From 2bdf019339ac84238fd9be69f208d9e7741094c3 Mon Sep 17 00:00:00 2001 From: Alexandre Montplaisir Date: Wed, 24 Sep 2014 17:23:30 -0400 Subject: tmf: Rename packages to org.eclipse.tracecompass.* Change-Id: I7072126d88e93cf44b0a1169c5090edb626b73c5 Signed-off-by: Alexandre Montplaisir --- .../linuxtools/lttng/alltests/RunAllCoreTests.java | 11 +- .../linuxtools/lttng/alltests/RunAllUITests.java | 4 +- .../lttng/alltests/perf/RunAllPerfTests.java | 4 +- .../lttng/alltests/swtbot/RunAllSWTBotTests.java | 6 +- .../btf/core/tests/trace/BtfTraceTest.java | 6 +- .../btf/core/tests/utils/BtfTestTrace.java | 4 +- .../btf/core/tests/utils/TestBtfTrace.java | 6 +- org.eclipse.tracecompass.btf.core/plugin.xml | 2 +- .../btf/core/analysis/BtfAnalysisModule.java | 8 +- .../btf/core/analysis/BtfStateProvider.java | 8 +- .../linuxtools/btf/core/event/BTFPayload.java | 2 +- .../linuxtools/btf/core/event/BtfEvent.java | 10 +- .../linuxtools/btf/core/event/BtfEventType.java | 6 +- .../btf/core/trace/BtfTimstampFormat.java | 4 +- .../linuxtools/btf/core/trace/BtfTrace.java | 38 +- .../linuxtools/btf/ui/BtfEventPropertySource.java | 6 +- .../linuxtools/btf/ui/BtfEventTableColumns.java | 8 +- .../ui/viewers/histogram/NewHistogramViewer.java | 10 +- .../ui/views/histogram/NewHistogramView.java | 2 +- .../gdbtrace/core/event/GdbTraceEvent.java | 6 +- .../gdbtrace/core/event/GdbTraceEventContent.java | 4 +- .../gdbtrace/core/trace/DsfGdbAdaptor.java | 14 +- .../internal/gdbtrace/core/trace/GdbTrace.java | 20 +- org.eclipse.tracecompass.gdbtrace.ui/plugin.xml | 2 +- .../gdbtrace/ui/views/GdbPerspectiveFactory.java | 2 +- .../ui/views/events/GdbEventTableColumns.java | 8 +- .../gdbtrace/ui/views/events/GdbEventsTable.java | 12 +- .../handlers/SelectTraceExecutableHandler.java | 2 +- .../ui/relayd/LttngRelaydConnectionManager.java | 14 +- .../control/ui/relayd/LttngRelaydConsumer.java | 8 +- .../control/ui/views/dialogs/ImportDialog.java | 4 +- .../ui/views/dialogs/OpenCommandScriptDialog.java | 2 +- .../control/ui/views/handlers/ImportHandler.java | 26 +- .../ui/views/property/BaseEventPropertySource.java | 2 +- .../property/KernelProviderPropertySource.java | 2 +- .../views/property/TargetNodePropertySource.java | 2 +- .../views/property/TraceChannelPropertySource.java | 2 +- .../views/property/TraceDomainPropertySource.java | 2 +- .../views/property/TraceEventPropertySource.java | 2 +- .../property/TraceProbeEventPropertySource.java | 2 +- .../views/property/TraceSessionPropertySource.java | 2 +- .../views/property/UstProviderPropertySource.java | 2 +- .../tests/perf/analysis/AnalysisBenchmark.java | 14 +- .../event/matching/EventMatchingBenchmark.java | 10 +- .../matching/TraceSynchronizationBenchmark.java | 12 +- .../tests/analysis/LttngKernelAnalysisTest.java | 12 +- .../event/matchandsync/ExperimentSyncTest.java | 16 +- .../tests/event/matchandsync/MatchAndSyncTest.java | 10 +- .../tests/stateprovider/GenerateTestValues.java | 8 +- .../LttngKernelStateProviderTest.java | 4 +- .../stateprovider/PartialStateSystemTest.java | 12 +- .../stateprovider/StateSystemFullHistoryTest.java | 12 +- .../stateprovider/StateSystemInMemoryTest.java | 10 +- .../core/tests/stateprovider/StateSystemTest.java | 2 +- .../plugin.xml | 2 +- .../internal/lttng2/kernel/core/Activator.java | 2 +- .../stateprovider/LttngKernelStateProvider.java | 8 +- .../core/analysis/LttngKernelAnalysisModule.java | 8 +- .../core/cpuusage/LttngKernelCpuStateProvider.java | 8 +- .../core/cpuusage/LttngKernelCpuUsageAnalysis.java | 6 +- .../core/event/matching/TcpEventMatching.java | 16 +- .../core/event/matching/TcpLttngEventMatching.java | 18 +- .../lttng2/kernel/core/trace/LttngKernelTrace.java | 4 +- .../swtbot/tests/ImportAndReadKernelSmokeTest.java | 20 +- .../ui/swtbot/tests/KernelPerspectiveChecker.java | 6 +- .../plugin.xml | 6 +- .../ui/viewers/events/LttngEventTableColumns.java | 6 +- .../lttng2/kernel/ui/views/PerspectiveFactory.java | 6 +- .../ui/views/controlflow/ControlFlowEntry.java | 4 +- .../ControlFlowPresentationProvider.java | 12 +- .../ui/views/controlflow/ControlFlowView.java | 26 +- .../ui/views/cpuusage/CpuUsageComposite.java | 16 +- .../kernel/ui/views/cpuusage/CpuUsageEntry.java | 2 +- .../kernel/ui/views/cpuusage/CpuUsageView.java | 6 +- .../kernel/ui/views/cpuusage/CpuUsageXYViewer.java | 2 +- .../kernel/ui/views/resources/ResourcesEntry.java | 6 +- .../resources/ResourcesPresentationProvider.java | 22 +- .../kernel/ui/views/resources/ResourcesView.java | 16 +- .../memory/UstMemoryAnalysisModuleTest.java | 2 +- .../trace/callstack/AbstractProviderTest.java | 14 +- .../LttngUstCallStackProviderFastTest.java | 2 +- .../callstack/LttngUstCallStackProviderTest.java | 2 +- .../plugin.xml | 2 +- .../core/memoryusage/MemoryUsageStateProvider.java | 10 +- .../trace/callstack/LttngUstCallStackProvider.java | 10 +- .../analysis/memory/UstMemoryAnalysisModule.java | 12 +- .../lttng2/ust/core/trace/LttngUstTrace.java | 4 +- org.eclipse.tracecompass.lttng2.ust.ui/plugin.xml | 2 +- .../ust/ui/views/memusage/MemoryUsageView.java | 2 +- .../ust/ui/views/memusage/MemoryUsageViewer.java | 6 +- .../callstack/LttngUstCallStackAnalysis.java | 8 +- .../rcp/ui/ApplicationWorkbenchWindowAdvisor.java | 8 +- .../META-INF/MANIFEST.MF | 6 +- .../xml/core/tests/common/TmfXmlTestFiles.java | 52 - .../xml/core/tests/common/TmfXmlTestFiles.java | 52 + .../pom.xml | 2 +- .../tmf/analysis/xml/core/tests/Activator.java | 58 - .../xml/core/tests/AllAnalysisXmlCoreTests.java | 29 - .../xml/core/tests/XmlAnalysisCorePluginTest.java | 51 - .../analysis/xml/core/tests/module/AllTests.java | 27 - .../xml/core/tests/module/XmlUtilsTest.java | 232 -- .../xml/core/tests/stateprovider/AllTests.java | 28 - .../stateprovider/StateProviderModuleTest.java | 130 - .../tests/stateprovider/StateProviderTest.java | 122 - .../tmf/analysis/xml/core/tests/Activator.java | 58 + .../xml/core/tests/AllAnalysisXmlCoreTests.java | 29 + .../xml/core/tests/XmlAnalysisCorePluginTest.java | 51 + .../analysis/xml/core/tests/module/AllTests.java | 27 + .../xml/core/tests/module/XmlUtilsTest.java | 232 ++ .../xml/core/tests/stateprovider/AllTests.java | 28 + .../stateprovider/StateProviderModuleTest.java | 130 + .../tests/stateprovider/StateProviderTest.java | 122 + .../META-INF/MANIFEST.MF | 14 +- .../internal/tmf/analysis/xml/core/Activator.java | 163 -- .../xml/core/model/ITmfXmlModelFactory.java | 112 - .../xml/core/model/ITmfXmlStateAttribute.java | 56 - .../analysis/xml/core/model/ITmfXmlStateValue.java | 78 - .../analysis/xml/core/model/TmfXmlCondition.java | 217 -- .../xml/core/model/TmfXmlEventHandler.java | 135 - .../analysis/xml/core/model/TmfXmlLocation.java | 125 - .../xml/core/model/TmfXmlStateAttribute.java | 327 --- .../analysis/xml/core/model/TmfXmlStateChange.java | 218 -- .../analysis/xml/core/model/TmfXmlStateValue.java | 495 ---- .../model/readonly/TmfXmlReadOnlyModelFactory.java | 88 - .../readonly/TmfXmlReadOnlyStateAttribute.java | 55 - .../model/readonly/TmfXmlReadOnlyStateValue.java | 69 - .../readwrite/TmfXmlReadWriteModelFactory.java | 87 - .../readwrite/TmfXmlReadWriteStateAttribute.java | 61 - .../model/readwrite/TmfXmlReadWriteStateValue.java | 375 --- .../xml/core/module/ITmfXmlTopLevelElement.java | 34 - .../xml/core/module/IXmlStateSystemContainer.java | 52 - .../tmf/analysis/xml/core/module/Messages.java | 41 - .../tmf/analysis/xml/core/module/XmlUtils.java | 252 -- .../analysis/xml/core/module/messages.properties | 15 - .../tmf/analysis/xml/core/module/xmlCommon.xsd | 44 - .../tmf/analysis/xml/core/module/xmlDefinition.xsd | 35 - .../analysis/xml/core/module/xmlStateProvider.xsd | 295 --- .../tmf/analysis/xml/core/module/xmlView.xsd | 178 -- .../xml/core/stateprovider/TmfXmlStrings.java | 96 - .../xml/core/stateprovider/XmlStateProvider.java | 185 -- .../core/stateprovider/XmlStateSystemModule.java | 85 - .../internal/tmf/analysis/xml/core/Activator.java | 163 ++ .../xml/core/model/ITmfXmlModelFactory.java | 112 + .../xml/core/model/ITmfXmlStateAttribute.java | 56 + .../analysis/xml/core/model/ITmfXmlStateValue.java | 78 + .../analysis/xml/core/model/TmfXmlCondition.java | 217 ++ .../xml/core/model/TmfXmlEventHandler.java | 135 + .../analysis/xml/core/model/TmfXmlLocation.java | 125 + .../xml/core/model/TmfXmlStateAttribute.java | 327 +++ .../analysis/xml/core/model/TmfXmlStateChange.java | 218 ++ .../analysis/xml/core/model/TmfXmlStateValue.java | 495 ++++ .../model/readonly/TmfXmlReadOnlyModelFactory.java | 88 + .../readonly/TmfXmlReadOnlyStateAttribute.java | 55 + .../model/readonly/TmfXmlReadOnlyStateValue.java | 69 + .../readwrite/TmfXmlReadWriteModelFactory.java | 87 + .../readwrite/TmfXmlReadWriteStateAttribute.java | 61 + .../model/readwrite/TmfXmlReadWriteStateValue.java | 375 +++ .../xml/core/module/ITmfXmlTopLevelElement.java | 34 + .../xml/core/module/IXmlStateSystemContainer.java | 52 + .../tmf/analysis/xml/core/module/Messages.java | 41 + .../tmf/analysis/xml/core/module/XmlUtils.java | 252 ++ .../analysis/xml/core/module/messages.properties | 15 + .../tmf/analysis/xml/core/module/xmlCommon.xsd | 44 + .../tmf/analysis/xml/core/module/xmlDefinition.xsd | 35 + .../analysis/xml/core/module/xmlStateProvider.xsd | 295 +++ .../tmf/analysis/xml/core/module/xmlView.xsd | 178 ++ .../xml/core/stateprovider/TmfXmlStrings.java | 96 + .../xml/core/stateprovider/XmlStateProvider.java | 185 ++ .../core/stateprovider/XmlStateSystemModule.java | 85 + .../META-INF/MANIFEST.MF | 4 +- .../pom.xml | 2 +- .../tmf/analysis/xml/ui/tests/Activator.java | 58 - .../xml/ui/tests/AllAnalysisXmlUiTests.java | 28 - .../xml/ui/tests/XmlAnalysisUiPluginTest.java | 53 - .../tmf/analysis/xml/ui/tests/module/AllTests.java | 27 - .../tests/module/XmlAnalysisModuleSourceTest.java | 134 - .../tmf/analysis/xml/ui/tests/Activator.java | 58 + .../xml/ui/tests/AllAnalysisXmlUiTests.java | 28 + .../xml/ui/tests/XmlAnalysisUiPluginTest.java | 53 + .../tmf/analysis/xml/ui/tests/module/AllTests.java | 27 + .../tests/module/XmlAnalysisModuleSourceTest.java | 134 + .../META-INF/MANIFEST.MF | 14 +- .../plugin.xml | 20 +- .../internal/tmf/analysis/xml/ui/Activator.java | 163 -- .../tmf/analysis/xml/ui/TmfXmlUiStrings.java | 46 - .../analysis/xml/ui/handler/ImportXmlHandler.java | 110 - .../tmf/analysis/xml/ui/views/XmlViewInfo.java | 159 -- .../analysis/xml/ui/views/xychart/Messages.java | 41 - .../analysis/xml/ui/views/xychart/XmlXYView.java | 105 - .../analysis/xml/ui/views/xychart/XmlXYViewer.java | 414 --- .../xml/ui/views/xychart/messages.properties | 4 - .../xml/ui/views/xychart/package-info.java | 14 - .../tmf/analysis/xml/ui/module/Messages.java | 35 - .../xml/ui/module/TmfAnalysisModuleHelperXml.java | 184 -- .../xml/ui/module/TmfXmlAnalysisOutputSource.java | 139 - .../analysis/xml/ui/module/TmfXmlViewOutput.java | 100 - .../xml/ui/module/XmlAnalysisModuleSource.java | 144 - .../tmf/analysis/xml/ui/module/messages.properties | 12 - .../analysis/xml/ui/views/timegraph/Messages.java | 49 - .../analysis/xml/ui/views/timegraph/XmlEntry.java | 272 -- .../views/timegraph/XmlPresentationProvider.java | 220 -- .../xml/ui/views/timegraph/XmlTimeGraphView.java | 512 ---- .../xml/ui/views/timegraph/messages.properties | 10 - .../internal/tmf/analysis/xml/ui/Activator.java | 163 ++ .../tmf/analysis/xml/ui/TmfXmlUiStrings.java | 46 + .../analysis/xml/ui/handler/ImportXmlHandler.java | 110 + .../tmf/analysis/xml/ui/views/XmlViewInfo.java | 159 ++ .../analysis/xml/ui/views/xychart/Messages.java | 41 + .../analysis/xml/ui/views/xychart/XmlXYView.java | 105 + .../analysis/xml/ui/views/xychart/XmlXYViewer.java | 414 +++ .../xml/ui/views/xychart/messages.properties | 4 + .../xml/ui/views/xychart/package-info.java | 14 + .../tmf/analysis/xml/ui/module/Messages.java | 35 + .../xml/ui/module/TmfAnalysisModuleHelperXml.java | 184 ++ .../xml/ui/module/TmfXmlAnalysisOutputSource.java | 139 + .../analysis/xml/ui/module/TmfXmlViewOutput.java | 100 + .../xml/ui/module/XmlAnalysisModuleSource.java | 144 + .../tmf/analysis/xml/ui/module/messages.properties | 12 + .../analysis/xml/ui/views/timegraph/Messages.java | 49 + .../analysis/xml/ui/views/timegraph/XmlEntry.java | 272 ++ .../views/timegraph/XmlPresentationProvider.java | 220 ++ .../xml/ui/views/timegraph/XmlTimeGraphView.java | 512 ++++ .../xml/ui/views/timegraph/messages.properties | 10 + .../META-INF/MANIFEST.MF | 11 +- .../tmf/core/tests/perf/AllPerfTests.java | 31 - .../tests/perf/synchronization/AllPerfTests.java | 29 - .../TimestampTransformBenchmark.java | 78 - .../tmf/core/tests/perf/AllPerfTests.java | 31 + .../tests/perf/synchronization/AllPerfTests.java | 29 + .../TimestampTransformBenchmark.java | 78 + org.eclipse.tracecompass.tmf.core.tests/plugin.xml | 42 +- org.eclipse.tracecompass.tmf.core.tests/pom.xml | 2 +- .../tmf/core/tests/shared/DebugListener.java | 44 - .../tmf/core/tests/shared/DebugSuite.java | 54 - .../tmf/core/tests/shared/TmfTestHelper.java | 63 - .../tmf/core/tests/shared/TmfTestTrace.java | 127 - .../tmf/core/tests/shared/DebugListener.java | 44 + .../tmf/core/tests/shared/DebugSuite.java | 54 + .../tmf/core/tests/shared/TmfTestHelper.java | 63 + .../tmf/core/tests/shared/TmfTestTrace.java | 127 + .../linuxtools/tmf/core/tests/AllTmfCoreTests.java | 46 - .../tmf/core/tests/TmfCorePluginTest.java | 54 - .../tmf/core/tests/TmfCoreTestPlugin.java | 84 - .../tmf/core/tests/analysis/AllTests.java | 32 - .../core/tests/analysis/AnalysisManagerTest.java | 130 - .../tests/analysis/AnalysisModuleHelperTest.java | 270 -- .../core/tests/analysis/AnalysisModuleTest.java | 257 -- .../analysis/AnalysisParameterProviderTest.java | 81 - .../analysis/AnalysisRequirementHelperTest.java | 182 -- .../tests/analysis/AnalysisRequirementTest.java | 243 -- .../tmf/core/tests/component/AllTests.java | 28 - .../core/tests/component/TmfEventProviderTest.java | 362 --- .../tests/component/TmfProviderManagerTest.java | 330 --- .../linuxtools/tmf/core/tests/event/AllTests.java | 40 - .../tmf/core/tests/event/TmfEventFieldTest.java | 365 --- .../tmf/core/tests/event/TmfEventTest.java | 417 --- .../core/tests/event/TmfEventTypeManagerTest.java | 242 -- .../tmf/core/tests/event/TmfEventTypeTest.java | 233 -- .../tmf/core/tests/event/TmfNanoTimestampTest.java | 293 -- .../core/tests/event/TmfSimpleTimestampTest.java | 293 -- .../core/tests/event/TmfTimePreferencesTest.java | 112 - .../tmf/core/tests/event/TmfTimeRangeTest.java | 373 --- .../core/tests/event/TmfTimestampDeltaTest.java | 131 - .../core/tests/event/TmfTimestampFormatTest.java | 386 --- .../tmf/core/tests/event/TmfTimestampTest.java | 670 ----- .../tmf/core/tests/event/lookup/AllTests.java | 28 - .../core/tests/event/lookup/TmfCallsiteTest.java | 179 -- .../linuxtools/tmf/core/tests/filter/AllTests.java | 27 - .../core/tests/filter/TmfCollapseFilterTest.java | 168 -- .../tmf/core/tests/request/AllTests.java | 29 - .../request/TmfCoalescedEventRequestTest.java | 594 ----- .../core/tests/request/TmfEventRequestTest.java | 313 --- .../linuxtools/tmf/core/tests/signal/AllTests.java | 28 - .../core/tests/signal/TmfSignalManagerTest.java | 558 ---- .../core/tests/signal/TmfSignalThrottlerTest.java | 224 -- .../tmf/core/tests/statesystem/AllTests.java | 28 - .../ExperimentStateSystemModuleTest.java | 119 - .../statesystem/StateSystemAnalysisModuleTest.java | 97 - .../core/tests/statesystem/mipmap/AllTests.java | 30 - .../mipmap/TmfMipmapStateProviderStub.java | 116 - .../mipmap/TmfMipmapStateProviderTest.java | 541 ---- .../mipmap/TmfMipmapStateProviderWeightedTest.java | 311 --- .../tmf/core/tests/synchronization/AllTests.java | 27 - .../tmf/core/tests/synchronization/SyncTest.java | 247 -- .../synchronization/TsTransformFactoryTest.java | 127 - .../tests/synchronization/TsTransformTest.java | 144 - .../linuxtools/tmf/core/tests/trace/AllTests.java | 30 - .../tmf/core/tests/trace/TmfContextTest.java | 255 -- .../tmf/core/tests/trace/TmfExperimentTest.java | 941 ------- .../tests/trace/TmfMultiTraceExperimentTest.java | 814 ------ .../tmf/core/tests/trace/TmfTraceTest.java | 1389 ---------- .../indexer/AbstractCheckpointCollectionTest.java | 374 --- .../tmf/core/tests/trace/indexer/AllBench.java | 251 -- .../tmf/core/tests/trace/indexer/AllTests.java | 31 - .../tmf/core/tests/trace/indexer/BTreeTest.java | 118 - .../core/tests/trace/indexer/FlatArrayTest.java | 87 - .../tests/trace/indexer/TmfMemoryIndexTest.java | 84 - .../indexer/checkpoint/AbstractIndexTest.java | 283 -- .../tests/trace/indexer/checkpoint/AllTests.java | 29 - .../indexer/checkpoint/TmfBTreeIndexTest.java | 69 - .../indexer/checkpoint/TmfCheckpointIndexTest.java | 23 - .../checkpoint/TmfCheckpointIndexTest2.java | 236 -- .../indexer/checkpoint/TmfCheckpointTest.java | 243 -- .../TmfExperimentCheckpointIndexTest.java | 192 -- .../tmf/core/tests/trace/location/AllTests.java | 27 - .../core/tests/trace/location/TmfLocationTest.java | 252 -- .../tmf/core/tests/trace/stub/AllTests.java | 27 - .../core/tests/trace/stub/XmlStubTraceTest.java | 191 -- .../tmf/core/tests/trace/text/AllTests.java | 27 - .../tests/trace/text/TextTraceContextTest.java | 238 -- .../trace/text/TextTraceEventContentTest.java | 232 -- .../tmf/core/tests/trace/text/TextTraceTest.java | 259 -- .../linuxtools/tmf/core/tests/uml2sd/AllTests.java | 28 - .../uml2sd/TmfAsyncSequenceDiagramEventTest.java | 125 - .../uml2sd/TmfSyncSequenceDiagramEventTest.java | 108 - .../linuxtools/tmf/core/tests/util/AllTests.java | 27 - .../linuxtools/tmf/core/tests/util/PairTest.java | 127 - .../tmf/core/tests/AllTmfCoreTests.java | 45 + .../tmf/core/tests/TmfCorePluginTest.java | 54 + .../tmf/core/tests/TmfCoreTestPlugin.java | 84 + .../tmf/core/tests/analysis/AllTests.java | 32 + .../core/tests/analysis/AnalysisManagerTest.java | 130 + .../tests/analysis/AnalysisModuleHelperTest.java | 270 ++ .../core/tests/analysis/AnalysisModuleTest.java | 257 ++ .../analysis/AnalysisParameterProviderTest.java | 81 + .../analysis/AnalysisRequirementHelperTest.java | 182 ++ .../tests/analysis/AnalysisRequirementTest.java | 243 ++ .../tmf/core/tests/component/AllTests.java | 28 + .../core/tests/component/TmfEventProviderTest.java | 362 +++ .../tests/component/TmfProviderManagerTest.java | 330 +++ .../tmf/core/tests/event/AllTests.java | 40 + .../tmf/core/tests/event/TmfEventFieldTest.java | 365 +++ .../tmf/core/tests/event/TmfEventTest.java | 417 +++ .../core/tests/event/TmfEventTypeManagerTest.java | 242 ++ .../tmf/core/tests/event/TmfEventTypeTest.java | 233 ++ .../tmf/core/tests/event/TmfNanoTimestampTest.java | 293 ++ .../core/tests/event/TmfSimpleTimestampTest.java | 293 ++ .../core/tests/event/TmfTimePreferencesTest.java | 112 + .../tmf/core/tests/event/TmfTimeRangeTest.java | 373 +++ .../core/tests/event/TmfTimestampDeltaTest.java | 131 + .../core/tests/event/TmfTimestampFormatTest.java | 386 +++ .../tmf/core/tests/event/TmfTimestampTest.java | 670 +++++ .../tmf/core/tests/event/lookup/AllTests.java | 28 + .../core/tests/event/lookup/TmfCallsiteTest.java | 179 ++ .../tmf/core/tests/filter/AllTests.java | 27 + .../core/tests/filter/TmfCollapseFilterTest.java | 168 ++ .../tmf/core/tests/request/AllTests.java | 29 + .../request/TmfCoalescedEventRequestTest.java | 594 +++++ .../core/tests/request/TmfEventRequestTest.java | 313 +++ .../tmf/core/tests/signal/AllTests.java | 28 + .../core/tests/signal/TmfSignalManagerTest.java | 558 ++++ .../core/tests/signal/TmfSignalThrottlerTest.java | 224 ++ .../tmf/core/tests/statesystem/AllTests.java | 28 + .../ExperimentStateSystemModuleTest.java | 119 + .../statesystem/StateSystemAnalysisModuleTest.java | 97 + .../core/tests/statesystem/mipmap/AllTests.java | 30 + .../mipmap/TmfMipmapStateProviderStub.java | 116 + .../mipmap/TmfMipmapStateProviderTest.java | 541 ++++ .../mipmap/TmfMipmapStateProviderWeightedTest.java | 311 +++ .../tmf/core/tests/synchronization/AllTests.java | 27 + .../tmf/core/tests/synchronization/SyncTest.java | 247 ++ .../synchronization/TsTransformFactoryTest.java | 127 + .../tests/synchronization/TsTransformTest.java | 144 + .../tmf/core/tests/trace/AllTests.java | 30 + .../tmf/core/tests/trace/TmfContextTest.java | 255 ++ .../tmf/core/tests/trace/TmfExperimentTest.java | 941 +++++++ .../tests/trace/TmfMultiTraceExperimentTest.java | 814 ++++++ .../tmf/core/tests/trace/TmfTraceTest.java | 1389 ++++++++++ .../indexer/AbstractCheckpointCollectionTest.java | 374 +++ .../tmf/core/tests/trace/indexer/AllBench.java | 251 ++ .../tmf/core/tests/trace/indexer/AllTests.java | 31 + .../tmf/core/tests/trace/indexer/BTreeTest.java | 118 + .../core/tests/trace/indexer/FlatArrayTest.java | 87 + .../tests/trace/indexer/TmfMemoryIndexTest.java | 84 + .../indexer/checkpoint/AbstractIndexTest.java | 283 ++ .../tests/trace/indexer/checkpoint/AllTests.java | 29 + .../indexer/checkpoint/TmfBTreeIndexTest.java | 69 + .../indexer/checkpoint/TmfCheckpointIndexTest.java | 23 + .../checkpoint/TmfCheckpointIndexTest2.java | 236 ++ .../indexer/checkpoint/TmfCheckpointTest.java | 243 ++ .../TmfExperimentCheckpointIndexTest.java | 192 ++ .../tmf/core/tests/trace/location/AllTests.java | 27 + .../core/tests/trace/location/TmfLocationTest.java | 252 ++ .../tmf/core/tests/trace/stub/AllTests.java | 27 + .../core/tests/trace/stub/XmlStubTraceTest.java | 191 ++ .../tmf/core/tests/trace/text/AllTests.java | 27 + .../tests/trace/text/TextTraceContextTest.java | 238 ++ .../trace/text/TextTraceEventContentTest.java | 232 ++ .../tmf/core/tests/trace/text/TextTraceTest.java | 259 ++ .../tmf/core/tests/uml2sd/AllTests.java | 28 + .../uml2sd/TmfAsyncSequenceDiagramEventTest.java | 124 + .../uml2sd/TmfSyncSequenceDiagramEventTest.java | 107 + .../tracecompass/tmf/core/tests/util/AllTests.java | 27 + .../tracecompass/tmf/core/tests/util/PairTest.java | 127 + .../tmf/tests/stubs/CreateTestFiles.java | 113 - .../stubs/analysis/AnalysisModuleSourceStub.java | 39 - .../stubs/analysis/AnalysisModuleTestHelper.java | 154 -- .../stubs/analysis/AnalysisRequirementFactory.java | 72 - .../tmf/tests/stubs/analysis/TestAnalysis.java | 91 - .../tmf/tests/stubs/analysis/TestAnalysis2.java | 41 - .../analysis/TestAnalysisParameterProvider.java | 59 - .../stubs/analysis/TestExperimentAnalysis.java | 93 - .../stubs/analysis/TestRequirementAnalysis.java | 81 - .../stubs/analysis/TestStateSystemModule.java | 37 - .../stubs/analysis/TestStateSystemProvider.java | 74 - .../tmf/tests/stubs/component/TmfClientStub.java | 44 - .../stubs/component/TmfEventProviderStub.java | 79 - .../component/TmfSyntheticEventProviderStub.java | 103 - .../tmf/tests/stubs/event/TmfEventTypeStub.java | 38 - .../tmf/tests/stubs/event/TmfSyncEventStub.java | 45 - .../tests/stubs/event/TmfSyntheticEventStub.java | 34 - .../tests/stubs/request/TmfEventRequestStub.java | 73 - .../tmf/tests/stubs/trace/TmfEmptyTraceStub.java | 71 - .../tmf/tests/stubs/trace/TmfEventParserStub.java | 125 - .../tmf/tests/stubs/trace/TmfExperimentStub.java | 52 - .../tmf/tests/stubs/trace/TmfIndexerStub.java | 36 - .../tmf/tests/stubs/trace/TmfTraceStub.java | 389 --- .../tmf/tests/stubs/trace/TmfTraceStub2.java | 55 - .../tmf/tests/stubs/trace/TmfTraceStub3.java | 29 - .../tmf/tests/stubs/trace/text/SyslogEvent.java | 127 - .../tests/stubs/trace/text/SyslogEventType.java | 51 - .../tmf/tests/stubs/trace/text/SyslogTrace.java | 116 - .../tmf/tests/stubs/trace/xml/Messages.java | 37 - .../stubs/trace/xml/TmfXmlDevelopmentTrace.xml | 38 - .../stubs/trace/xml/TmfXmlDevelopmentTrace.xsd | 47 - .../tmf/tests/stubs/trace/xml/TmfXmlTraceStub.java | 252 -- .../tmf/tests/stubs/trace/xml/messages.properties | 15 - .../tmf/tests/stubs/CreateTestFiles.java | 113 + .../stubs/analysis/AnalysisModuleSourceStub.java | 39 + .../stubs/analysis/AnalysisModuleTestHelper.java | 154 ++ .../stubs/analysis/AnalysisRequirementFactory.java | 72 + .../tmf/tests/stubs/analysis/TestAnalysis.java | 91 + .../tmf/tests/stubs/analysis/TestAnalysis2.java | 41 + .../analysis/TestAnalysisParameterProvider.java | 59 + .../stubs/analysis/TestExperimentAnalysis.java | 93 + .../stubs/analysis/TestRequirementAnalysis.java | 81 + .../stubs/analysis/TestStateSystemModule.java | 37 + .../stubs/analysis/TestStateSystemProvider.java | 74 + .../tmf/tests/stubs/component/TmfClientStub.java | 44 + .../stubs/component/TmfEventProviderStub.java | 79 + .../component/TmfSyntheticEventProviderStub.java | 103 + .../tmf/tests/stubs/event/TmfEventTypeStub.java | 38 + .../tmf/tests/stubs/event/TmfSyncEventStub.java | 45 + .../tests/stubs/event/TmfSyntheticEventStub.java | 34 + .../tests/stubs/request/TmfEventRequestStub.java | 73 + .../tmf/tests/stubs/trace/TmfEmptyTraceStub.java | 71 + .../tmf/tests/stubs/trace/TmfEventParserStub.java | 125 + .../tmf/tests/stubs/trace/TmfExperimentStub.java | 52 + .../tmf/tests/stubs/trace/TmfIndexerStub.java | 36 + .../tmf/tests/stubs/trace/TmfTraceStub.java | 389 +++ .../tmf/tests/stubs/trace/TmfTraceStub2.java | 55 + .../tmf/tests/stubs/trace/TmfTraceStub3.java | 29 + .../tmf/tests/stubs/trace/text/SyslogEvent.java | 127 + .../tests/stubs/trace/text/SyslogEventType.java | 51 + .../tmf/tests/stubs/trace/text/SyslogTrace.java | 116 + .../tmf/tests/stubs/trace/xml/Messages.java | 37 + .../stubs/trace/xml/TmfXmlDevelopmentTrace.xml | 38 + .../stubs/trace/xml/TmfXmlDevelopmentTrace.xsd | 47 + .../tmf/tests/stubs/trace/xml/TmfXmlTraceStub.java | 252 ++ .../tmf/tests/stubs/trace/xml/messages.properties | 15 + .../META-INF/MANIFEST.MF | 80 +- org.eclipse.tracecompass.tmf.core/plugin.xml | 12 +- .../linuxtools/internal/tmf/core/Activator.java | 196 -- .../linuxtools/internal/tmf/core/Messages.java | 31 - .../tmf/core/TmfCorePreferenceInitializer.java | 29 - .../internal/tmf/core/TmfCoreTracer.java | 239 -- .../TmfAnalysisModuleSourceConfigElement.java | 118 - .../core/analysis/TmfAnalysisModuleSources.java | 72 - .../tmf/core/component/TmfEventThread.java | 253 -- .../tmf/core/component/TmfProviderManager.java | 122 - .../tmf/core/filter/TmfCollapseFilter.java | 119 - .../internal/tmf/core/messages.properties | 14 - .../tmf/core/request/TmfCoalescedEventRequest.java | 321 --- .../tmf/core/request/TmfRequestExecutor.java | 308 --- .../backends/partial/PartialHistoryBackend.java | 365 --- .../backends/partial/PartialStateSystem.java | 162 -- .../mipmap/AbstractTmfMipmapStateProvider.java | 199 -- .../core/statesystem/mipmap/AvgMipmapFeature.java | 73 - .../core/statesystem/mipmap/ITmfMipmapFeature.java | 41 - .../core/statesystem/mipmap/MaxMipmapFeature.java | 69 - .../core/statesystem/mipmap/MinMipmapFeature.java | 69 - .../core/statesystem/mipmap/TmfMipmapFeature.java | 238 -- .../mipmap/TmfStateSystemOperations.java | 350 --- .../ITmfTimestampTransformInvertible.java | 33 - .../SyncAlgorithmFullyIncremental.java | 623 ----- .../core/synchronization/TmfConstantTransform.java | 116 - .../synchronization/TmfTimestampTransform.java | 82 - .../TmfTimestampTransformLinear.java | 150 -- .../tmf/core/synchronization/graph/Edge.java | 77 - .../tmf/core/synchronization/graph/SyncGraph.java | 179 -- .../synchronization/graph/SyncSpanningTree.java | 127 - .../tmf/core/trace/TmfExperimentCheckpoint.java | 95 - .../tmf/core/trace/TmfExperimentContext.java | 224 -- .../tmf/core/trace/TmfExperimentLocation.java | 120 - .../internal/tmf/core/trace/TmfLocationArray.java | 204 -- .../indexer/AbstractFileCheckpointCollection.java | 478 ---- .../internal/tmf/core/trace/indexer/BTree.java | 383 --- .../core/trace/indexer/BTreeCheckpointVisitor.java | 76 - .../internal/tmf/core/trace/indexer/BTreeNode.java | 204 -- .../tmf/core/trace/indexer/BTreeNodeCache.java | 146 - .../internal/tmf/core/trace/indexer/FlatArray.java | 142 - .../tmf/core/trace/indexer/IBTreeVisitor.java | 34 - .../core/trace/indexer/ICheckpointCollection.java | 99 - .../internal/tmf/core/trace/indexer/Messages.java | 67 - .../tmf/core/trace/indexer/TmfMemoryIndex.java | 103 - .../tmf/core/trace/indexer/messages.properties | 21 - .../org/eclipse/linuxtools/tmf/core/Messages.java | 39 - .../linuxtools/tmf/core/TmfCommonConstants.java | 59 - .../linuxtools/tmf/core/TmfProjectNature.java | 64 - .../tmf/core/analysis/IAnalysisModule.java | 249 -- .../tmf/core/analysis/IAnalysisModuleHelper.java | 138 - .../tmf/core/analysis/IAnalysisModuleSource.java | 37 - .../tmf/core/analysis/IAnalysisOutput.java | 54 - .../core/analysis/IAnalysisParameterProvider.java | 68 - .../analysis/IAnalysisRequirementProvider.java | 32 - .../analysis/ITmfNewAnalysisModuleListener.java | 31 - .../linuxtools/tmf/core/analysis/Messages.java | 70 - .../core/analysis/TmfAbstractAnalysisModule.java | 474 ---- .../analysis/TmfAbstractAnalysisParamProvider.java | 71 - .../tmf/core/analysis/TmfAnalysisManager.java | 230 -- .../TmfAnalysisModuleHelperConfigElement.java | 206 -- .../core/analysis/TmfAnalysisModuleOutputs.java | 95 - .../tmf/core/analysis/TmfAnalysisRequirement.java | 291 -- .../analysis/TmfAnalysisRequirementHelper.java | 128 - .../analysis/TmfNewAnalysisOutputListener.java | 58 - .../tmf/core/analysis/messages.properties | 24 - .../tmf/core/callstack/CallStackStateProvider.java | 198 -- .../linuxtools/tmf/core/callstack/Messages.java | 39 - .../tmf/core/callstack/messages.properties | 13 - .../tmf/core/component/ITmfComponent.java | 56 - .../tmf/core/component/ITmfEventProvider.java | 56 - .../tmf/core/component/TmfComponent.java | 119 - .../tmf/core/component/TmfEventProvider.java | 439 --- .../tmf/core/event/ITmfCustomAttributes.java | 43 - .../linuxtools/tmf/core/event/ITmfEvent.java | 113 - .../linuxtools/tmf/core/event/ITmfEventField.java | 96 - .../linuxtools/tmf/core/event/ITmfEventType.java | 69 - .../linuxtools/tmf/core/event/ITmfLostEvent.java | 53 - .../linuxtools/tmf/core/event/TmfEvent.java | 249 -- .../linuxtools/tmf/core/event/TmfEventField.java | 261 -- .../linuxtools/tmf/core/event/TmfEventType.java | 149 -- .../tmf/core/event/TmfEventTypeManager.java | 147 - .../linuxtools/tmf/core/event/TmfLostEvent.java | 136 - .../core/event/collapse/ITmfCollapsibleEvent.java | 35 - .../tmf/core/event/lookup/ITmfCallsite.java | 47 - .../tmf/core/event/lookup/ITmfModelLookup.java | 28 - .../tmf/core/event/lookup/ITmfSourceLookup.java | 28 - .../tmf/core/event/lookup/TmfCallsite.java | 150 -- .../core/event/matching/IMatchProcessingUnit.java | 58 - .../tmf/core/event/matching/ITmfEventMatching.java | 31 - .../event/matching/ITmfMatchEventDefinition.java | 56 - .../event/matching/ITmfNetworkMatchDefinition.java | 37 - .../core/event/matching/TmfEventDependency.java | 60 - .../tmf/core/event/matching/TmfEventMatches.java | 80 - .../tmf/core/event/matching/TmfEventMatching.java | 271 -- .../event/matching/TmfNetworkEventMatching.java | 212 -- .../tmf/core/exceptions/TmfAnalysisException.java | 47 - .../tmf/core/exceptions/TmfTraceException.java | 46 - .../linuxtools/tmf/core/filter/ITmfFilter.java | 33 - .../tmf/core/filter/model/ITmfFilterTreeNode.java | 127 - .../tmf/core/filter/model/TmfFilterAndNode.java | 116 - .../core/filter/model/TmfFilterCompareNode.java | 270 -- .../core/filter/model/TmfFilterContainsNode.java | 188 -- .../tmf/core/filter/model/TmfFilterEqualsNode.java | 188 -- .../core/filter/model/TmfFilterEventTypeNode.java | 171 -- .../core/filter/model/TmfFilterMatchesNode.java | 196 -- .../tmf/core/filter/model/TmfFilterNode.java | 137 - .../tmf/core/filter/model/TmfFilterOrNode.java | 114 - .../tmf/core/filter/model/TmfFilterRootNode.java | 62 - .../tmf/core/filter/model/TmfFilterTreeNode.java | 264 -- .../core/filter/xml/TmfFilterContentHandler.java | 179 -- .../tmf/core/filter/xml/TmfFilterXMLParser.java | 70 - .../tmf/core/filter/xml/TmfFilterXMLWriter.java | 162 -- .../tmf/core/io/BufferedRandomAccessFile.java | 229 -- .../linuxtools/tmf/core/messages.properties | 13 - .../tmf/core/parsers/custom/CustomEvent.java | 314 --- .../core/parsers/custom/CustomEventContent.java | 70 - .../tmf/core/parsers/custom/CustomEventType.java | 48 - .../core/parsers/custom/CustomTraceDefinition.java | 157 -- .../tmf/core/parsers/custom/CustomTxtEvent.java | 143 - .../core/parsers/custom/CustomTxtEventType.java | 33 - .../tmf/core/parsers/custom/CustomTxtTrace.java | 463 ---- .../core/parsers/custom/CustomTxtTraceContext.java | 103 - .../parsers/custom/CustomTxtTraceDefinition.java | 935 ------- .../tmf/core/parsers/custom/CustomXmlEvent.java | 127 - .../core/parsers/custom/CustomXmlEventType.java | 33 - .../tmf/core/parsers/custom/CustomXmlTrace.java | 585 ---- .../core/parsers/custom/CustomXmlTraceContext.java | 57 - .../parsers/custom/CustomXmlTraceDefinition.java | 858 ------ .../tmf/core/parsers/custom/Messages.java | 66 - .../tmf/core/parsers/custom/messages.properties | 44 - .../project/model/TmfTraceImportException.java | 45 - .../tmf/core/project/model/TmfTraceType.java | 691 ----- .../tmf/core/project/model/TraceTypeHelper.java | 167 -- .../core/project/model/TraceValidationHelper.java | 99 - .../tmf/core/request/ITmfEventRequest.java | 199 -- .../tmf/core/request/TmfEventRequest.java | 426 --- .../tmf/core/signal/TmfEndSynchSignal.java | 33 - .../core/signal/TmfEventFilterAppliedSignal.java | 68 - .../core/signal/TmfEventSearchAppliedSignal.java | 68 - .../tmf/core/signal/TmfEventSelectedSignal.java | 53 - .../tmf/core/signal/TmfRangeSynchSignal.java | 53 - .../linuxtools/tmf/core/signal/TmfSignal.java | 73 - .../tmf/core/signal/TmfSignalHandler.java | 30 - .../tmf/core/signal/TmfSignalManager.java | 231 -- .../tmf/core/signal/TmfSignalThrottler.java | 103 - .../tmf/core/signal/TmfSignalTracer.java | 48 - .../tmf/core/signal/TmfStartAnalysisSignal.java | 54 - .../tmf/core/signal/TmfStartSynchSignal.java | 34 - .../tmf/core/signal/TmfTimeSynchSignal.java | 95 - .../signal/TmfTimestampFormatUpdateSignal.java | 31 - .../tmf/core/signal/TmfTraceClosedSignal.java | 60 - .../tmf/core/signal/TmfTraceOpenedSignal.java | 72 - .../core/signal/TmfTraceRangeUpdatedSignal.java | 69 - .../tmf/core/signal/TmfTraceSelectedSignal.java | 54 - .../core/signal/TmfTraceSynchronizedSignal.java | 53 - .../tmf/core/signal/TmfTraceUpdatedSignal.java | 84 - .../core/statesystem/AbstractTmfStateProvider.java | 243 -- .../ITmfAnalysisModuleWithStateSystems.java | 48 - .../tmf/core/statesystem/ITmfStateProvider.java | 119 - .../statesystem/TmfStateSystemAnalysisModule.java | 501 ---- .../tmf/core/statistics/ITmfStatistics.java | 98 - .../tmf/core/statistics/TmfEventsStatistics.java | 285 -- .../tmf/core/statistics/TmfStateStatistics.java | 323 --- .../statistics/TmfStatisticsEventTypesModule.java | 161 -- .../tmf/core/statistics/TmfStatisticsModule.java | 188 -- .../core/statistics/TmfStatisticsTotalsModule.java | 130 - .../synchronization/ITmfTimestampTransform.java | 57 - .../tmf/core/synchronization/Messages.java | 53 - .../SyncAlgorithmFullyIncremental.java | 626 ----- .../synchronization/SynchronizationAlgorithm.java | 122 - .../SynchronizationAlgorithmFactory.java | 52 - .../synchronization/SynchronizationBackend.java | 196 -- .../synchronization/SynchronizationManager.java | 134 - .../synchronization/TimestampTransformFactory.java | 208 -- .../synchronization/TmfTimestampTransform.java | 82 - .../TmfTimestampTransformLinear.java | 149 -- .../tmf/core/synchronization/messages.properties | 32 - .../timestamp/ITmfTimePreferencesConstants.java | 58 - .../tmf/core/timestamp/ITmfTimestamp.java | 142 - .../tmf/core/timestamp/TmfNanoTimestamp.java | 110 - .../tmf/core/timestamp/TmfSimpleTimestamp.java | 112 - .../tmf/core/timestamp/TmfTimePreferences.java | 213 -- .../tmf/core/timestamp/TmfTimeRange.java | 226 -- .../tmf/core/timestamp/TmfTimestamp.java | 384 --- .../tmf/core/timestamp/TmfTimestampDelta.java | 105 - .../tmf/core/timestamp/TmfTimestampFormat.java | 802 ------ .../linuxtools/tmf/core/trace/ITmfContext.java | 88 - .../linuxtools/tmf/core/trace/ITmfEventParser.java | 38 - .../linuxtools/tmf/core/trace/ITmfTrace.java | 457 ---- .../tmf/core/trace/ITmfTraceCompleteness.java | 38 - .../tmf/core/trace/ITmfTraceProperties.java | 35 - .../core/trace/ITmfTraceWithPreDefinedEvents.java | 59 - .../linuxtools/tmf/core/trace/TmfContext.java | 178 -- .../core/trace/TmfEventTypeCollectionHelper.java | 48 - .../linuxtools/tmf/core/trace/TmfExperiment.java | 736 ----- .../linuxtools/tmf/core/trace/TmfTrace.java | 826 ------ .../linuxtools/tmf/core/trace/TmfTraceContext.java | 115 - .../linuxtools/tmf/core/trace/TmfTraceManager.java | 524 ---- .../tmf/core/trace/TraceValidationStatus.java | 49 - .../trace/indexer/ITmfPersistentlyIndexable.java | 47 - .../tmf/core/trace/indexer/ITmfTraceIndexer.java | 116 - .../tmf/core/trace/indexer/TmfBTreeTraceIndex.java | 139 - .../core/trace/indexer/TmfBTreeTraceIndexer.java | 43 - .../core/trace/indexer/TmfFlatArrayTraceIndex.java | 112 - .../trace/indexer/TmfFlatArrayTraceIndexer.java | 43 - .../trace/indexer/checkpoint/ITmfCheckpoint.java | 79 - .../indexer/checkpoint/ITmfCheckpointIndex.java | 118 - .../trace/indexer/checkpoint/TmfCheckpoint.java | 222 -- .../indexer/checkpoint/TmfCheckpointIndexer.java | 355 --- .../tmf/core/trace/location/ITmfLocation.java | 51 - .../tmf/core/trace/location/TmfLocation.java | 108 - .../tmf/core/trace/location/TmfLongLocation.java | 78 - .../core/trace/location/TmfTimestampLocation.java | 71 - .../linuxtools/tmf/core/trace/text/TextTrace.java | 382 --- .../tmf/core/trace/text/TextTraceContext.java | 100 - .../tmf/core/trace/text/TextTraceEvent.java | 76 - .../tmf/core/trace/text/TextTraceEventContent.java | 312 --- .../core/uml2sd/ITmfAsyncSequenceDiagramEvent.java | 32 - .../core/uml2sd/ITmfSyncSequenceDiagramEvent.java | 54 - .../core/uml2sd/TmfAsyncSequenceDiagramEvent.java | 67 - .../core/uml2sd/TmfSyncSequenceDiagramEvent.java | 102 - .../org/eclipse/linuxtools/tmf/core/util/Pair.java | 146 - .../tracecompass/internal/tmf/core/Activator.java | 196 ++ .../tracecompass/internal/tmf/core/Messages.java | 31 + .../tmf/core/TmfCorePreferenceInitializer.java | 29 + .../internal/tmf/core/TmfCoreTracer.java | 239 ++ .../TmfAnalysisModuleSourceConfigElement.java | 118 + .../core/analysis/TmfAnalysisModuleSources.java | 72 + .../tmf/core/component/TmfEventThread.java | 253 ++ .../tmf/core/component/TmfProviderManager.java | 122 + .../tmf/core/filter/TmfCollapseFilter.java | 119 + .../internal/tmf/core/messages.properties | 14 + .../tmf/core/request/TmfCoalescedEventRequest.java | 321 +++ .../tmf/core/request/TmfRequestExecutor.java | 308 +++ .../backends/partial/PartialHistoryBackend.java | 365 +++ .../backends/partial/PartialStateSystem.java | 162 ++ .../mipmap/AbstractTmfMipmapStateProvider.java | 199 ++ .../core/statesystem/mipmap/AvgMipmapFeature.java | 73 + .../core/statesystem/mipmap/ITmfMipmapFeature.java | 41 + .../core/statesystem/mipmap/MaxMipmapFeature.java | 69 + .../core/statesystem/mipmap/MinMipmapFeature.java | 69 + .../core/statesystem/mipmap/TmfMipmapFeature.java | 238 ++ .../mipmap/TmfStateSystemOperations.java | 350 +++ .../ITmfTimestampTransformInvertible.java | 33 + .../SyncAlgorithmFullyIncremental.java | 623 +++++ .../core/synchronization/TmfConstantTransform.java | 116 + .../synchronization/TmfTimestampTransform.java | 82 + .../TmfTimestampTransformLinear.java | 150 ++ .../tmf/core/synchronization/graph/Edge.java | 77 + .../tmf/core/synchronization/graph/SyncGraph.java | 179 ++ .../synchronization/graph/SyncSpanningTree.java | 127 + .../tmf/core/trace/TmfExperimentCheckpoint.java | 95 + .../tmf/core/trace/TmfExperimentContext.java | 224 ++ .../tmf/core/trace/TmfExperimentLocation.java | 120 + .../internal/tmf/core/trace/TmfLocationArray.java | 204 ++ .../indexer/AbstractFileCheckpointCollection.java | 478 ++++ .../internal/tmf/core/trace/indexer/BTree.java | 383 +++ .../core/trace/indexer/BTreeCheckpointVisitor.java | 76 + .../internal/tmf/core/trace/indexer/BTreeNode.java | 204 ++ .../tmf/core/trace/indexer/BTreeNodeCache.java | 146 + .../internal/tmf/core/trace/indexer/FlatArray.java | 142 + .../tmf/core/trace/indexer/IBTreeVisitor.java | 34 + .../core/trace/indexer/ICheckpointCollection.java | 99 + .../internal/tmf/core/trace/indexer/Messages.java | 67 + .../tmf/core/trace/indexer/TmfMemoryIndex.java | 103 + .../tmf/core/trace/indexer/messages.properties | 21 + .../eclipse/tracecompass/tmf/core/Messages.java | 39 + .../tracecompass/tmf/core/TmfCommonConstants.java | 59 + .../tracecompass/tmf/core/TmfProjectNature.java | 64 + .../tmf/core/analysis/IAnalysisModule.java | 249 ++ .../tmf/core/analysis/IAnalysisModuleHelper.java | 138 + .../tmf/core/analysis/IAnalysisModuleSource.java | 37 + .../tmf/core/analysis/IAnalysisOutput.java | 54 + .../core/analysis/IAnalysisParameterProvider.java | 68 + .../analysis/IAnalysisRequirementProvider.java | 32 + .../analysis/ITmfNewAnalysisModuleListener.java | 31 + .../tracecompass/tmf/core/analysis/Messages.java | 70 + .../core/analysis/TmfAbstractAnalysisModule.java | 474 ++++ .../analysis/TmfAbstractAnalysisParamProvider.java | 71 + .../tmf/core/analysis/TmfAnalysisManager.java | 230 ++ .../TmfAnalysisModuleHelperConfigElement.java | 206 ++ .../core/analysis/TmfAnalysisModuleOutputs.java | 95 + .../tmf/core/analysis/TmfAnalysisRequirement.java | 291 ++ .../analysis/TmfAnalysisRequirementHelper.java | 128 + .../analysis/TmfNewAnalysisOutputListener.java | 58 + .../tmf/core/analysis/messages.properties | 24 + .../tmf/core/callstack/CallStackStateProvider.java | 198 ++ .../tracecompass/tmf/core/callstack/Messages.java | 39 + .../tmf/core/callstack/messages.properties | 13 + .../tmf/core/component/ITmfComponent.java | 56 + .../tmf/core/component/ITmfEventProvider.java | 56 + .../tmf/core/component/TmfComponent.java | 119 + .../tmf/core/component/TmfEventProvider.java | 439 +++ .../tmf/core/event/ITmfCustomAttributes.java | 43 + .../tracecompass/tmf/core/event/ITmfEvent.java | 113 + .../tmf/core/event/ITmfEventField.java | 96 + .../tracecompass/tmf/core/event/ITmfEventType.java | 69 + .../tracecompass/tmf/core/event/ITmfLostEvent.java | 53 + .../tracecompass/tmf/core/event/TmfEvent.java | 249 ++ .../tracecompass/tmf/core/event/TmfEventField.java | 261 ++ .../tracecompass/tmf/core/event/TmfEventType.java | 149 ++ .../tmf/core/event/TmfEventTypeManager.java | 147 + .../tracecompass/tmf/core/event/TmfLostEvent.java | 136 + .../core/event/collapse/ITmfCollapsibleEvent.java | 35 + .../tmf/core/event/lookup/ITmfCallsite.java | 47 + .../tmf/core/event/lookup/ITmfModelLookup.java | 28 + .../tmf/core/event/lookup/ITmfSourceLookup.java | 28 + .../tmf/core/event/lookup/TmfCallsite.java | 150 ++ .../core/event/matching/IMatchProcessingUnit.java | 58 + .../tmf/core/event/matching/ITmfEventMatching.java | 31 + .../event/matching/ITmfMatchEventDefinition.java | 56 + .../event/matching/ITmfNetworkMatchDefinition.java | 37 + .../core/event/matching/TmfEventDependency.java | 60 + .../tmf/core/event/matching/TmfEventMatches.java | 80 + .../tmf/core/event/matching/TmfEventMatching.java | 271 ++ .../event/matching/TmfNetworkEventMatching.java | 212 ++ .../tmf/core/exceptions/TmfAnalysisException.java | 47 + .../tmf/core/exceptions/TmfTraceException.java | 46 + .../tracecompass/tmf/core/filter/ITmfFilter.java | 33 + .../tmf/core/filter/model/ITmfFilterTreeNode.java | 127 + .../tmf/core/filter/model/TmfFilterAndNode.java | 116 + .../core/filter/model/TmfFilterCompareNode.java | 270 ++ .../core/filter/model/TmfFilterContainsNode.java | 188 ++ .../tmf/core/filter/model/TmfFilterEqualsNode.java | 188 ++ .../core/filter/model/TmfFilterEventTypeNode.java | 171 ++ .../core/filter/model/TmfFilterMatchesNode.java | 196 ++ .../tmf/core/filter/model/TmfFilterNode.java | 137 + .../tmf/core/filter/model/TmfFilterOrNode.java | 114 + .../tmf/core/filter/model/TmfFilterRootNode.java | 62 + .../tmf/core/filter/model/TmfFilterTreeNode.java | 264 ++ .../core/filter/xml/TmfFilterContentHandler.java | 179 ++ .../tmf/core/filter/xml/TmfFilterXMLParser.java | 70 + .../tmf/core/filter/xml/TmfFilterXMLWriter.java | 162 ++ .../tmf/core/io/BufferedRandomAccessFile.java | 229 ++ .../tracecompass/tmf/core/messages.properties | 13 + .../tmf/core/parsers/custom/CustomEvent.java | 314 +++ .../core/parsers/custom/CustomEventContent.java | 70 + .../tmf/core/parsers/custom/CustomEventType.java | 48 + .../core/parsers/custom/CustomTraceDefinition.java | 157 ++ .../tmf/core/parsers/custom/CustomTxtEvent.java | 143 + .../core/parsers/custom/CustomTxtEventType.java | 33 + .../tmf/core/parsers/custom/CustomTxtTrace.java | 463 ++++ .../core/parsers/custom/CustomTxtTraceContext.java | 103 + .../parsers/custom/CustomTxtTraceDefinition.java | 935 +++++++ .../tmf/core/parsers/custom/CustomXmlEvent.java | 127 + .../core/parsers/custom/CustomXmlEventType.java | 33 + .../tmf/core/parsers/custom/CustomXmlTrace.java | 585 ++++ .../core/parsers/custom/CustomXmlTraceContext.java | 57 + .../parsers/custom/CustomXmlTraceDefinition.java | 858 ++++++ .../tmf/core/parsers/custom/Messages.java | 66 + .../tmf/core/parsers/custom/messages.properties | 44 + .../project/model/TmfTraceImportException.java | 45 + .../tmf/core/project/model/TmfTraceType.java | 691 +++++ .../tmf/core/project/model/TraceTypeHelper.java | 167 ++ .../core/project/model/TraceValidationHelper.java | 99 + .../tmf/core/request/ITmfEventRequest.java | 199 ++ .../tmf/core/request/TmfEventRequest.java | 426 +++ .../tmf/core/signal/TmfEndSynchSignal.java | 33 + .../core/signal/TmfEventFilterAppliedSignal.java | 68 + .../core/signal/TmfEventSearchAppliedSignal.java | 68 + .../tmf/core/signal/TmfEventSelectedSignal.java | 53 + .../tmf/core/signal/TmfRangeSynchSignal.java | 53 + .../tracecompass/tmf/core/signal/TmfSignal.java | 73 + .../tmf/core/signal/TmfSignalHandler.java | 30 + .../tmf/core/signal/TmfSignalManager.java | 231 ++ .../tmf/core/signal/TmfSignalThrottler.java | 103 + .../tmf/core/signal/TmfSignalTracer.java | 48 + .../tmf/core/signal/TmfStartAnalysisSignal.java | 54 + .../tmf/core/signal/TmfStartSynchSignal.java | 34 + .../tmf/core/signal/TmfTimeSynchSignal.java | 95 + .../signal/TmfTimestampFormatUpdateSignal.java | 31 + .../tmf/core/signal/TmfTraceClosedSignal.java | 60 + .../tmf/core/signal/TmfTraceOpenedSignal.java | 72 + .../core/signal/TmfTraceRangeUpdatedSignal.java | 69 + .../tmf/core/signal/TmfTraceSelectedSignal.java | 54 + .../core/signal/TmfTraceSynchronizedSignal.java | 53 + .../tmf/core/signal/TmfTraceUpdatedSignal.java | 84 + .../core/statesystem/AbstractTmfStateProvider.java | 243 ++ .../ITmfAnalysisModuleWithStateSystems.java | 48 + .../tmf/core/statesystem/ITmfStateProvider.java | 119 + .../statesystem/TmfStateSystemAnalysisModule.java | 501 ++++ .../tmf/core/statistics/ITmfStatistics.java | 98 + .../tmf/core/statistics/TmfEventsStatistics.java | 285 ++ .../tmf/core/statistics/TmfStateStatistics.java | 323 +++ .../statistics/TmfStatisticsEventTypesModule.java | 161 ++ .../tmf/core/statistics/TmfStatisticsModule.java | 188 ++ .../core/statistics/TmfStatisticsTotalsModule.java | 130 + .../synchronization/ITmfTimestampTransform.java | 57 + .../tmf/core/synchronization/Messages.java | 53 + .../SyncAlgorithmFullyIncremental.java | 626 +++++ .../synchronization/SynchronizationAlgorithm.java | 122 + .../SynchronizationAlgorithmFactory.java | 52 + .../synchronization/SynchronizationBackend.java | 196 ++ .../synchronization/SynchronizationManager.java | 134 + .../synchronization/TimestampTransformFactory.java | 208 ++ .../synchronization/TmfTimestampTransform.java | 82 + .../TmfTimestampTransformLinear.java | 149 ++ .../tmf/core/synchronization/messages.properties | 32 + .../timestamp/ITmfTimePreferencesConstants.java | 58 + .../tmf/core/timestamp/ITmfTimestamp.java | 142 + .../tmf/core/timestamp/TmfNanoTimestamp.java | 110 + .../tmf/core/timestamp/TmfSimpleTimestamp.java | 112 + .../tmf/core/timestamp/TmfTimePreferences.java | 213 ++ .../tmf/core/timestamp/TmfTimeRange.java | 226 ++ .../tmf/core/timestamp/TmfTimestamp.java | 384 +++ .../tmf/core/timestamp/TmfTimestampDelta.java | 105 + .../tmf/core/timestamp/TmfTimestampFormat.java | 802 ++++++ .../tracecompass/tmf/core/trace/ITmfContext.java | 88 + .../tmf/core/trace/ITmfEventParser.java | 38 + .../tracecompass/tmf/core/trace/ITmfTrace.java | 457 ++++ .../tmf/core/trace/ITmfTraceCompleteness.java | 38 + .../tmf/core/trace/ITmfTraceProperties.java | 35 + .../core/trace/ITmfTraceWithPreDefinedEvents.java | 59 + .../tracecompass/tmf/core/trace/TmfContext.java | 178 ++ .../core/trace/TmfEventTypeCollectionHelper.java | 48 + .../tracecompass/tmf/core/trace/TmfExperiment.java | 736 +++++ .../tracecompass/tmf/core/trace/TmfTrace.java | 826 ++++++ .../tmf/core/trace/TmfTraceContext.java | 115 + .../tmf/core/trace/TmfTraceManager.java | 524 ++++ .../tmf/core/trace/TraceValidationStatus.java | 49 + .../trace/indexer/ITmfPersistentlyIndexable.java | 47 + .../tmf/core/trace/indexer/ITmfTraceIndexer.java | 116 + .../tmf/core/trace/indexer/TmfBTreeTraceIndex.java | 139 + .../core/trace/indexer/TmfBTreeTraceIndexer.java | 43 + .../core/trace/indexer/TmfFlatArrayTraceIndex.java | 112 + .../trace/indexer/TmfFlatArrayTraceIndexer.java | 43 + .../trace/indexer/checkpoint/ITmfCheckpoint.java | 79 + .../indexer/checkpoint/ITmfCheckpointIndex.java | 118 + .../trace/indexer/checkpoint/TmfCheckpoint.java | 222 ++ .../indexer/checkpoint/TmfCheckpointIndexer.java | 355 +++ .../tmf/core/trace/location/ITmfLocation.java | 51 + .../tmf/core/trace/location/TmfLocation.java | 108 + .../tmf/core/trace/location/TmfLongLocation.java | 78 + .../core/trace/location/TmfTimestampLocation.java | 71 + .../tmf/core/trace/text/TextTrace.java | 382 +++ .../tmf/core/trace/text/TextTraceContext.java | 100 + .../tmf/core/trace/text/TextTraceEvent.java | 76 + .../tmf/core/trace/text/TextTraceEventContent.java | 312 +++ .../core/uml2sd/ITmfAsyncSequenceDiagramEvent.java | 32 + .../core/uml2sd/ITmfSyncSequenceDiagramEvent.java | 54 + .../core/uml2sd/TmfAsyncSequenceDiagramEvent.java | 67 + .../core/uml2sd/TmfSyncSequenceDiagramEvent.java | 102 + .../eclipse/tracecompass/tmf/core/util/Pair.java | 146 + .../META-INF/MANIFEST.MF | 18 +- .../tmf/ctf/core/tests/perf/AllPerfTests.java | 31 - .../core/tests/perf/experiment/AllPerfTests.java | 26 - .../tests/perf/experiment/ExperimentBenchmark.java | 163 -- .../tmf/ctf/core/tests/perf/AllPerfTests.java | 31 + .../core/tests/perf/experiment/AllPerfTests.java | 26 + .../tests/perf/experiment/ExperimentBenchmark.java | 163 ++ .../plugin.xml | 4 +- .../tmf/ctf/core/tests/shared/CtfTmfTestTrace.java | 123 - .../tmf/ctf/core/tests/shared/CtfTmfTestTrace.java | 123 + .../linuxtools/tmf/ctf/core/tests/AllTests.java | 48 - .../tmf/ctf/core/tests/CtfIteratorTest.java | 243 -- .../tmf/ctf/core/tests/CtfLocationDataTest.java | 99 - .../tmf/ctf/core/tests/CtfLocationTest.java | 105 - .../tmf/ctf/core/tests/CtfTmfContextTest.java | 126 - .../tmf/ctf/core/tests/CtfTmfEventFieldTest.java | 324 --- .../tmf/ctf/core/tests/CtfTmfEventTest.java | 227 -- .../tmf/ctf/core/tests/CtfTmfEventTypeTest.java | 61 - .../core/tests/CtfTmfLostEventStatisticsTest.java | 167 -- .../tmf/ctf/core/tests/CtfTmfLostEventsTest.java | 256 -- .../tmf/ctf/core/tests/CtfTmfTimestampTest.java | 53 - .../tmf/ctf/core/tests/CtfTmfTraceTest.java | 393 --- .../tmf/ctf/core/tests/EventContextTest.java | 241 -- .../tmf/ctf/core/tests/FunkyTraceTest.java | 212 -- .../tmf/ctf/core/tests/headless/Benchmark.java | 97 - .../ctf/core/tests/headless/RequestBenchmark.java | 130 - .../tmf/ctf/core/tests/request/AllTests.java | 25 - .../core/tests/request/TmfSchedulerBenchmark.java | 360 --- .../ctf/core/tests/request/TmfSchedulerTest.java | 451 ---- .../tmf/ctf/core/tests/statistics/AllTests.java | 26 - .../tests/statistics/TmfEventsStatisticsTest.java | 35 - .../tests/statistics/TmfStateStatisticsTest.java | 89 - .../core/tests/statistics/TmfStatisticsTest.java | 364 --- .../tmf/ctf/core/tests/tracemanager/AllTests.java | 25 - .../tests/tracemanager/TmfTraceManagerTest.java | 720 ----- .../tracecompass/tmf/ctf/core/tests/AllTests.java | 48 + .../tmf/ctf/core/tests/CtfIteratorTest.java | 243 ++ .../tmf/ctf/core/tests/CtfLocationDataTest.java | 99 + .../tmf/ctf/core/tests/CtfLocationTest.java | 105 + .../tmf/ctf/core/tests/CtfTmfContextTest.java | 126 + .../tmf/ctf/core/tests/CtfTmfEventFieldTest.java | 324 +++ .../tmf/ctf/core/tests/CtfTmfEventTest.java | 227 ++ .../tmf/ctf/core/tests/CtfTmfEventTypeTest.java | 61 + .../core/tests/CtfTmfLostEventStatisticsTest.java | 167 ++ .../tmf/ctf/core/tests/CtfTmfLostEventsTest.java | 256 ++ .../tmf/ctf/core/tests/CtfTmfTimestampTest.java | 53 + .../tmf/ctf/core/tests/CtfTmfTraceTest.java | 393 +++ .../tmf/ctf/core/tests/EventContextTest.java | 241 ++ .../tmf/ctf/core/tests/FunkyTraceTest.java | 212 ++ .../tmf/ctf/core/tests/headless/Benchmark.java | 97 + .../ctf/core/tests/headless/RequestBenchmark.java | 130 + .../tmf/ctf/core/tests/request/AllTests.java | 25 + .../core/tests/request/TmfSchedulerBenchmark.java | 360 +++ .../ctf/core/tests/request/TmfSchedulerTest.java | 451 ++++ .../tmf/ctf/core/tests/statistics/AllTests.java | 26 + .../tests/statistics/TmfEventsStatisticsTest.java | 35 + .../tests/statistics/TmfStateStatisticsTest.java | 89 + .../core/tests/statistics/TmfStatisticsTest.java | 364 +++ .../tmf/ctf/core/tests/tracemanager/AllTests.java | 25 + .../tests/tracemanager/TmfTraceManagerTest.java | 720 +++++ .../tmf/ctf/core/tests/stubs/CtfTmfTraceStub.java | 41 - .../tmf/ctf/core/tests/stubs/CtfTmfTraceStub.java | 41 + .../META-INF/MANIFEST.MF | 6 +- org.eclipse.tracecompass.tmf.ctf.core/plugin.xml | 4 +- .../internal/tmf/ctf/core/Activator.java | 137 - .../linuxtools/tmf/ctf/core/CtfConstants.java | 64 - .../linuxtools/tmf/ctf/core/CtfEnumPair.java | 59 - .../linuxtools/tmf/ctf/core/CtfIterator.java | 353 --- .../tmf/ctf/core/CtfIteratorManager.java | 229 -- .../linuxtools/tmf/ctf/core/CtfLocation.java | 147 - .../linuxtools/tmf/ctf/core/CtfLocationInfo.java | 137 - .../linuxtools/tmf/ctf/core/CtfTmfCallsite.java | 116 - .../linuxtools/tmf/ctf/core/CtfTmfContext.java | 202 -- .../linuxtools/tmf/ctf/core/CtfTmfEvent.java | 262 -- .../tmf/ctf/core/CtfTmfEventFactory.java | 121 - .../linuxtools/tmf/ctf/core/CtfTmfEventField.java | 472 ---- .../linuxtools/tmf/ctf/core/CtfTmfEventType.java | 84 - .../linuxtools/tmf/ctf/core/CtfTmfLostEvent.java | 79 - .../linuxtools/tmf/ctf/core/CtfTmfTimestamp.java | 37 - .../linuxtools/tmf/ctf/core/CtfTmfTrace.java | 518 ---- .../eclipse/linuxtools/tmf/ctf/core/Messages.java | 56 - .../linuxtools/tmf/ctf/core/messages.properties | 18 - .../internal/tmf/ctf/core/Activator.java | 137 + .../tracecompass/tmf/ctf/core/CtfConstants.java | 64 + .../tracecompass/tmf/ctf/core/CtfEnumPair.java | 59 + .../tracecompass/tmf/ctf/core/CtfIterator.java | 353 +++ .../tmf/ctf/core/CtfIteratorManager.java | 229 ++ .../tracecompass/tmf/ctf/core/CtfLocation.java | 147 + .../tracecompass/tmf/ctf/core/CtfLocationInfo.java | 137 + .../tracecompass/tmf/ctf/core/CtfTmfCallsite.java | 116 + .../tracecompass/tmf/ctf/core/CtfTmfContext.java | 202 ++ .../tracecompass/tmf/ctf/core/CtfTmfEvent.java | 262 ++ .../tmf/ctf/core/CtfTmfEventFactory.java | 121 + .../tmf/ctf/core/CtfTmfEventField.java | 472 ++++ .../tracecompass/tmf/ctf/core/CtfTmfEventType.java | 84 + .../tracecompass/tmf/ctf/core/CtfTmfLostEvent.java | 79 + .../tracecompass/tmf/ctf/core/CtfTmfTimestamp.java | 37 + .../tracecompass/tmf/ctf/core/CtfTmfTrace.java | 518 ++++ .../tracecompass/tmf/ctf/core/Messages.java | 56 + .../tracecompass/tmf/ctf/core/messages.properties | 18 + .../META-INF/MANIFEST.MF | 2 +- .../pom.xml | 2 +- .../tests/AbstractImportAndReadSmokeTest.java | 336 --- .../tmf/ctf/ui/swtbot/tests/AllTests.java | 29 - .../ui/swtbot/tests/ImportAndReadSmokeTest.java | 142 - .../tests/StandardImportAndReadSmokeTest.java | 315 --- .../tests/AbstractImportAndReadSmokeTest.java | 336 +++ .../tmf/ctf/ui/swtbot/tests/AllTests.java | 29 + .../ui/swtbot/tests/ImportAndReadSmokeTest.java | 142 + .../tests/StandardImportAndReadSmokeTest.java | 315 +++ .../META-INF/MANIFEST.MF | 12 +- .../pcap/core/tests/shared/PcapTmfTestTrace.java | 122 - .../pcap/core/tests/shared/PcapTmfTestTrace.java | 122 + .../tmf/pcap/core/tests/AllTmfPcapCoreTests.java | 32 - .../tmf/pcap/core/tests/analysis/AllTests.java | 27 - .../tests/analysis/StreamListAnalysisTest.java | 126 - .../tmf/pcap/core/tests/event/AllTests.java | 28 - .../pcap/core/tests/event/PcapEventFieldTest.java | 243 -- .../tmf/pcap/core/tests/event/PcapEventTest.java | 153 -- .../tmf/pcap/core/tests/trace/AllTests.java | 27 - .../tmf/pcap/core/tests/trace/PcapTraceTest.java | 307 --- .../tmf/pcap/core/tests/AllTmfPcapCoreTests.java | 32 + .../tmf/pcap/core/tests/analysis/AllTests.java | 27 + .../tests/analysis/StreamListAnalysisTest.java | 126 + .../tmf/pcap/core/tests/event/AllTests.java | 28 + .../pcap/core/tests/event/PcapEventFieldTest.java | 243 ++ .../tmf/pcap/core/tests/event/PcapEventTest.java | 153 ++ .../tmf/pcap/core/tests/trace/AllTests.java | 27 + .../tmf/pcap/core/tests/trace/PcapTraceTest.java | 307 +++ .../pcap/core/tests/stubs/PcapTmfTraceStub.java | 41 - .../pcap/core/tests/stubs/PcapTmfTraceStub.java | 41 + .../META-INF/MANIFEST.MF | 16 +- org.eclipse.tracecompass.tmf.pcap.core/plugin.xml | 8 +- .../internal/tmf/pcap/core/Activator.java | 212 -- .../tmf/pcap/core/analysis/StreamListAnalysis.java | 164 -- .../tmf/pcap/core/analysis/package-info.java | 14 - .../internal/tmf/pcap/core/event/Messages.java | 35 - .../internal/tmf/pcap/core/event/PcapEvent.java | 242 -- .../tmf/pcap/core/event/PcapEventField.java | 64 - .../tmf/pcap/core/event/PcapEventType.java | 75 - .../tmf/pcap/core/event/PcapRootEventField.java | 90 - .../tmf/pcap/core/event/TmfPacketStream.java | 175 -- .../pcap/core/event/TmfPacketStreamBuilder.java | 86 - .../tmf/pcap/core/event/messages.properties | 14 - .../internal/tmf/pcap/core/event/package-info.java | 14 - .../internal/tmf/pcap/core/package-info.java | 14 - .../tmf/pcap/core/protocol/TmfPcapProtocol.java | 109 - .../tmf/pcap/core/protocol/package-info.java | 14 - .../core/signal/TmfPacketStreamSelectedSignal.java | 54 - .../tmf/pcap/core/signal/package-info.java | 14 - .../internal/tmf/pcap/core/trace/Messages.java | 37 - .../internal/tmf/pcap/core/trace/PcapTrace.java | 251 -- .../tmf/pcap/core/trace/messages.properties | 18 - .../internal/tmf/pcap/core/trace/package-info.java | 14 - .../internal/tmf/pcap/core/util/Messages.java | 32 - .../tmf/pcap/core/util/PcapEventFactory.java | 133 - .../tmf/pcap/core/util/ProtocolConversion.java | 80 - .../tmf/pcap/core/util/messages.properties | 13 - .../internal/tmf/pcap/core/util/package-info.java | 14 - .../internal/tmf/pcap/core/Activator.java | 212 ++ .../tmf/pcap/core/analysis/StreamListAnalysis.java | 164 ++ .../tmf/pcap/core/analysis/package-info.java | 14 + .../internal/tmf/pcap/core/event/Messages.java | 35 + .../internal/tmf/pcap/core/event/PcapEvent.java | 242 ++ .../tmf/pcap/core/event/PcapEventField.java | 64 + .../tmf/pcap/core/event/PcapEventType.java | 75 + .../tmf/pcap/core/event/PcapRootEventField.java | 90 + .../tmf/pcap/core/event/TmfPacketStream.java | 175 ++ .../pcap/core/event/TmfPacketStreamBuilder.java | 86 + .../tmf/pcap/core/event/messages.properties | 14 + .../internal/tmf/pcap/core/event/package-info.java | 14 + .../internal/tmf/pcap/core/package-info.java | 14 + .../tmf/pcap/core/protocol/TmfPcapProtocol.java | 109 + .../tmf/pcap/core/protocol/package-info.java | 14 + .../core/signal/TmfPacketStreamSelectedSignal.java | 54 + .../tmf/pcap/core/signal/package-info.java | 14 + .../internal/tmf/pcap/core/trace/Messages.java | 37 + .../internal/tmf/pcap/core/trace/PcapTrace.java | 251 ++ .../tmf/pcap/core/trace/messages.properties | 18 + .../internal/tmf/pcap/core/trace/package-info.java | 14 + .../internal/tmf/pcap/core/util/Messages.java | 32 + .../tmf/pcap/core/util/PcapEventFactory.java | 133 + .../tmf/pcap/core/util/ProtocolConversion.java | 80 + .../tmf/pcap/core/util/messages.properties | 13 + .../internal/tmf/pcap/core/util/package-info.java | 14 + .../META-INF/MANIFEST.MF | 2 +- .../pom.xml | 2 +- .../tmf/pcap/ui/swtbot/tests/AllTests.java | 27 - .../ui/swtbot/tests/ImportAndReadPcapTest.java | 269 -- .../ui/swtbot/tests/NetworkPerspectiveChecker.java | 56 - .../tmf/pcap/ui/swtbot/tests/AllTests.java | 27 + .../ui/swtbot/tests/ImportAndReadPcapTest.java | 269 ++ .../ui/swtbot/tests/NetworkPerspectiveChecker.java | 56 + .../META-INF/MANIFEST.MF | 8 +- org.eclipse.tracecompass.tmf.pcap.ui/plugin.xml | 10 +- .../linuxtools/internal/tmf/pcap/ui/Activator.java | 212 -- .../tmf/pcap/ui/NetworkingPerspectiveFactory.java | 90 - .../internal/tmf/pcap/ui/editor/Messages.java | 37 - .../tmf/pcap/ui/editor/PcapEventTableColumns.java | 144 - .../tmf/pcap/ui/editor/messages.properties | 18 - .../internal/tmf/pcap/ui/editor/package-info.java | 14 - .../internal/tmf/pcap/ui/package-info.java | 14 - .../internal/tmf/pcap/ui/stream/Messages.java | 49 - .../tmf/pcap/ui/stream/StreamListView.java | 498 ---- .../tmf/pcap/ui/stream/messages.properties | 30 - .../internal/tmf/pcap/ui/stream/package-info.java | 14 - .../internal/tmf/pcap/ui/Activator.java | 212 ++ .../tmf/pcap/ui/NetworkingPerspectiveFactory.java | 90 + .../internal/tmf/pcap/ui/editor/Messages.java | 37 + .../tmf/pcap/ui/editor/PcapEventTableColumns.java | 144 + .../tmf/pcap/ui/editor/messages.properties | 18 + .../internal/tmf/pcap/ui/editor/package-info.java | 14 + .../internal/tmf/pcap/ui/package-info.java | 14 + .../internal/tmf/pcap/ui/stream/Messages.java | 49 + .../tmf/pcap/ui/stream/StreamListView.java | 498 ++++ .../tmf/pcap/ui/stream/messages.properties | 30 + .../internal/tmf/pcap/ui/stream/package-info.java | 14 + .../META-INF/MANIFEST.MF | 4 +- .../pom.xml | 2 +- .../swtbot/tests/AbstractCustomParserWizard.java | 96 - .../swtbot/tests/AbstractPerspectiveChecker.java | 111 - .../tmf/ui/swtbot/tests/AllTmfUISWTBotTests.java | 31 - .../linuxtools/tmf/ui/swtbot/tests/SWTBotUtil.java | 275 -- .../tmf/ui/swtbot/tests/TestCustomTxtWizard.java | 262 -- .../tmf/ui/swtbot/tests/TestCustomXmlWizard.java | 117 - .../ui/swtbot/tests/TracingPerspectiveChecker.java | 48 - .../swtbot/tests/conditions/ConditionHelpers.java | 107 - .../swtbot/tests/conditions/TableCellFilled.java | 56 - .../tests/conditions/TreeItemNodeAvailable.java | 52 - .../swtbot/tests/conditions/TreeNodeAvailable.java | 67 - .../tmf/ui/swtbot/tests/conditions/ViewClosed.java | 45 - .../ui/swtbot/tests/conditions/WizardOnPage.java | 57 - .../ui/swtbot/tests/conditions/WizardReady.java | 49 - .../tmf/ui/swtbot/tests/table/AllTests.java | 28 - .../tests/table/CollapseEventsInTableTest.java | 195 -- .../swtbot/tests/AbstractCustomParserWizard.java | 96 + .../swtbot/tests/AbstractPerspectiveChecker.java | 111 + .../tmf/ui/swtbot/tests/AllTmfUISWTBotTests.java | 31 + .../tmf/ui/swtbot/tests/SWTBotUtil.java | 275 ++ .../tmf/ui/swtbot/tests/TestCustomTxtWizard.java | 262 ++ .../tmf/ui/swtbot/tests/TestCustomXmlWizard.java | 117 + .../ui/swtbot/tests/TracingPerspectiveChecker.java | 48 + .../swtbot/tests/conditions/ConditionHelpers.java | 107 + .../swtbot/tests/conditions/TableCellFilled.java | 56 + .../tests/conditions/TreeItemNodeAvailable.java | 52 + .../swtbot/tests/conditions/TreeNodeAvailable.java | 67 + .../tmf/ui/swtbot/tests/conditions/ViewClosed.java | 45 + .../ui/swtbot/tests/conditions/WizardOnPage.java | 57 + .../ui/swtbot/tests/conditions/WizardReady.java | 49 + .../tmf/ui/swtbot/tests/table/AllTests.java | 28 + .../tests/table/CollapseEventsInTableTest.java | 195 ++ .../META-INF/MANIFEST.MF | 4 +- org.eclipse.tracecompass.tmf.ui.tests/plugin.xml | 24 +- org.eclipse.tracecompass.tmf.ui.tests/pom.xml | 2 +- .../tmf/ui/tests/shared/ProjectModelTestData.java | 265 -- .../tmf/ui/tests/shared/ProjectModelTestData.java | 265 ++ .../linuxtools/tmf/ui/tests/AllTmfUITests.java | 39 - .../linuxtools/tmf/ui/tests/TmfUITestPlugin.java | 84 - .../tmf/ui/tests/histogram/AllTests.java | 28 - .../ui/tests/histogram/HistogramDataModelTest.java | 703 ----- .../tmf/ui/tests/project/model/AllTests.java | 30 - .../project/model/ProjectModelAnalysisTest.java | 161 -- .../project/model/ProjectModelOutputTest.java | 171 -- .../tests/project/model/ProjectModelTraceTest.java | 110 - .../project/model/TraceAndExperimentTypeTest.java | 199 -- .../tmf/ui/tests/statistics/AllTests.java | 35 - .../statistics/TmfBaseColumnDataProviderTest.java | 173 -- .../ui/tests/statistics/TmfBaseColumnDataTest.java | 169 -- .../statistics/TmfBaseStatisticsDataTest.java | 238 -- .../tmf/ui/tests/statistics/TmfStatisticsTest.java | 94 - .../statistics/TmfStatisticsTreeManagerTest.java | 177 -- .../statistics/TmfStatisticsTreeNodeTest.java | 385 --- .../statistics/TmfTreeContentProviderTest.java | 187 -- .../tests/trace/AbstractCustomTraceIndexTest.java | 191 -- .../linuxtools/tmf/ui/tests/trace/AllTests.java | 32 - .../tmf/ui/tests/trace/CustomTxtIndexTest.java | 81 - .../tmf/ui/tests/trace/CustomXmlIndexTest.java | 83 - .../tests/trace/CustomXmlTraceBadlyFormedTest.java | 74 - .../ui/tests/trace/CustomXmlTraceInvalidTest.java | 75 - .../tmf/ui/tests/trace/CustomXmlTraceTest.java | 75 - .../ui/tests/trace/CustomXmlTraceValidTest.java | 75 - .../ui/tests/views/uml2sd/dialogs/AllTests.java | 28 - .../tests/views/uml2sd/dialogs/CriteriaTest.java | 304 --- .../tmf/ui/tests/views/uml2sd/load/AllTests.java | 28 - .../views/uml2sd/load/LoadersManagerTest.java | 157 -- .../tmf/ui/tests/views/uml2sd/loader/AllTests.java | 35 - .../views/uml2sd/loader/IUml2SDTestConstants.java | 77 - .../uml2sd/loader/IUml2SdSignalValidator.java | 103 - .../uml2sd/loader/TmfUml2SDSyncLoaderExpTest.java | 191 -- .../loader/TmfUml2SDSyncLoaderFilterTest.java | 213 -- .../uml2sd/loader/TmfUml2SDSyncLoaderFindTest.java | 338 --- .../loader/TmfUml2SDSyncLoaderPagesTest.java | 215 -- .../loader/TmfUml2SDSyncLoaderSignalTest.java | 134 - .../uml2sd/loader/TmfUml2SDSyncLoaderTimeTest.java | 311 --- .../views/uml2sd/loader/Uml2SDSignalValidator.java | 188 -- .../views/uml2sd/loader/Uml2SDTestFacility.java | 360 --- .../tests/views/uml2sd/loader/Uml2SDTestSetup.java | 40 - .../views/uml2sd/loader/Uml2SDTestTimestamp.java | 43 - .../tracecompass/tmf/ui/tests/AllTmfUITests.java | 39 + .../tracecompass/tmf/ui/tests/TmfUITestPlugin.java | 84 + .../tmf/ui/tests/histogram/AllTests.java | 28 + .../ui/tests/histogram/HistogramDataModelTest.java | 703 +++++ .../tmf/ui/tests/project/model/AllTests.java | 30 + .../project/model/ProjectModelAnalysisTest.java | 161 ++ .../project/model/ProjectModelOutputTest.java | 171 ++ .../tests/project/model/ProjectModelTraceTest.java | 110 + .../project/model/TraceAndExperimentTypeTest.java | 199 ++ .../tmf/ui/tests/statistics/AllTests.java | 35 + .../statistics/TmfBaseColumnDataProviderTest.java | 173 ++ .../ui/tests/statistics/TmfBaseColumnDataTest.java | 169 ++ .../statistics/TmfBaseStatisticsDataTest.java | 238 ++ .../tmf/ui/tests/statistics/TmfStatisticsTest.java | 94 + .../statistics/TmfStatisticsTreeManagerTest.java | 177 ++ .../statistics/TmfStatisticsTreeNodeTest.java | 385 +++ .../statistics/TmfTreeContentProviderTest.java | 187 ++ .../tests/trace/AbstractCustomTraceIndexTest.java | 191 ++ .../tracecompass/tmf/ui/tests/trace/AllTests.java | 32 + .../tmf/ui/tests/trace/CustomTxtIndexTest.java | 81 + .../tmf/ui/tests/trace/CustomXmlIndexTest.java | 83 + .../tests/trace/CustomXmlTraceBadlyFormedTest.java | 74 + .../ui/tests/trace/CustomXmlTraceInvalidTest.java | 75 + .../tmf/ui/tests/trace/CustomXmlTraceTest.java | 75 + .../ui/tests/trace/CustomXmlTraceValidTest.java | 75 + .../ui/tests/views/uml2sd/dialogs/AllTests.java | 28 + .../tests/views/uml2sd/dialogs/CriteriaTest.java | 304 +++ .../tmf/ui/tests/views/uml2sd/load/AllTests.java | 28 + .../views/uml2sd/load/LoadersManagerTest.java | 157 ++ .../tmf/ui/tests/views/uml2sd/loader/AllTests.java | 35 + .../views/uml2sd/loader/IUml2SDTestConstants.java | 77 + .../uml2sd/loader/IUml2SdSignalValidator.java | 103 + .../uml2sd/loader/TmfUml2SDSyncLoaderExpTest.java | 191 ++ .../loader/TmfUml2SDSyncLoaderFilterTest.java | 213 ++ .../uml2sd/loader/TmfUml2SDSyncLoaderFindTest.java | 338 +++ .../loader/TmfUml2SDSyncLoaderPagesTest.java | 215 ++ .../loader/TmfUml2SDSyncLoaderSignalTest.java | 134 + .../uml2sd/loader/TmfUml2SDSyncLoaderTimeTest.java | 311 +++ .../views/uml2sd/loader/Uml2SDSignalValidator.java | 188 ++ .../views/uml2sd/loader/Uml2SDTestFacility.java | 360 +++ .../tests/views/uml2sd/loader/Uml2SDTestSetup.java | 40 + .../views/uml2sd/loader/Uml2SDTestTimestamp.java | 43 + .../tests/experiment/type/TmfEventsEditorStub.java | 47 - .../ui/tests/stubs/analysis/TestAnalysisUi.java | 60 - .../tmf/ui/tests/uml2sd/load/TestLoaders.java | 483 ---- .../ui/tests/uml2sd/trace/TmfUml2SDTestTrace.java | 112 - .../test/stub/adaption/TsfImplProvider.java | 54 - .../timegraph/test/stub/model/EventImpl.java | 85 - .../timegraph/test/stub/model/TraceImpl.java | 118 - .../test/stub/model/TraceModelImplFactory.java | 232 -- .../test/stub/views/TsfTraceAnalysisView.java | 672 ----- .../tests/experiment/type/TmfEventsEditorStub.java | 47 + .../ui/tests/stubs/analysis/TestAnalysisUi.java | 60 + .../tmf/ui/tests/uml2sd/load/TestLoaders.java | 483 ++++ .../ui/tests/uml2sd/trace/TmfUml2SDTestTrace.java | 112 + .../test/stub/adaption/TsfImplProvider.java | 54 + .../timegraph/test/stub/model/EventImpl.java | 85 + .../timegraph/test/stub/model/TraceImpl.java | 118 + .../test/stub/model/TraceModelImplFactory.java | 232 ++ .../test/stub/views/TsfTraceAnalysisView.java | 672 +++++ .../.settings/.api_filters | 11 - .../META-INF/MANIFEST.MF | 124 +- org.eclipse.tracecompass.tmf.ui/plugin.xml | 266 +- .../linuxtools/internal/tmf/ui/Activator.java | 245 -- .../internal/tmf/ui/ITmfImageConstants.java | 63 - .../linuxtools/internal/tmf/ui/Messages.java | 306 --- .../linuxtools/internal/tmf/ui/TmfUiTracer.java | 245 -- .../ui/commands/ExportToTextCommandHandler.java | 81 - .../internal/tmf/ui/commands/ExportToTextJob.java | 135 - .../tmf/ui/commands/ExportToTextRequest.java | 103 - .../ManageCustomParsersCommandHandler.java | 35 - .../internal/tmf/ui/commands/Messages.java | 37 - .../internal/tmf/ui/commands/OpenFileHandler.java | 79 - .../internal/tmf/ui/commands/TmfHandlerUtil.java | 76 - .../internal/tmf/ui/commands/messages.properties | 14 - .../tmf/ui/dialogs/ManageCustomParsersDialog.java | 367 --- .../tmf/ui/dialogs/MultiLineInputDialog.java | 167 -- .../ui/editors/handlers/AddBookmarkHandler.java | 48 - .../linuxtools/internal/tmf/ui/messages.properties | 297 --- .../ui/parsers/custom/CustomEventTableColumns.java | 100 - .../wizards/CustomTxtParserInputWizardPage.java | 1681 ------------ .../wizards/CustomTxtParserOutputWizardPage.java | 340 --- .../ui/parsers/wizards/CustomTxtParserWizard.java | 82 - .../wizards/CustomXmlParserInputWizardPage.java | 1765 ------------ .../wizards/CustomXmlParserOutputWizardPage.java | 341 --- .../ui/parsers/wizards/CustomXmlParserWizard.java | 86 - .../ui/preferences/TmfTracingPreferencePage.java | 52 - .../internal/tmf/ui/project/dialogs/Messages.java | 38 - .../SelectSupplementaryResourcesDialog.java | 324 --- .../tmf/ui/project/dialogs/messages.properties | 16 - .../tmf/ui/project/dialogs/offset/Messages.java | 67 - .../ui/project/dialogs/offset/OffsetDialog.java | 578 ---- .../ui/project/dialogs/offset/messages.properties | 24 - .../project/handlers/BatchImportTraceHandler.java | 60 - .../project/handlers/ClearTraceOffsetHandler.java | 118 - .../ui/project/handlers/CopyExperimentHandler.java | 54 - .../tmf/ui/project/handlers/CopyTraceHandler.java | 54 - .../project/handlers/DeleteExperimentHandler.java | 113 - .../handlers/DeleteTraceFolderElementHandler.java | 349 --- .../DeleteTraceSupplementaryFilesHandler.java | 192 -- .../ui/project/handlers/DropAdapterAssistant.java | 669 ----- .../ui/project/handlers/ImportTraceHandler.java | 64 - .../internal/tmf/ui/project/handlers/Messages.java | 85 - .../ui/project/handlers/NewExperimentHandler.java | 74 - .../tmf/ui/project/handlers/NewFolderHandler.java | 63 - .../ui/project/handlers/OffsetTraceHandler.java | 132 - .../tmf/ui/project/handlers/OpenAction.java | 94 - .../project/handlers/OpenAnalysisHelpHandler.java | 114 - .../handlers/OpenAnalysisOutputHandler.java | 89 - .../ui/project/handlers/OpenExperimentHandler.java | 99 - .../tmf/ui/project/handlers/OpenTraceHandler.java | 104 - .../tmf/ui/project/handlers/RefreshHandler.java | 87 - .../project/handlers/RenameExperimentHandler.java | 96 - .../ui/project/handlers/RenameFolderHandler.java | 158 -- .../ui/project/handlers/RenameTraceHandler.java | 171 -- .../SelectElementTypeContributionItem.java | 269 -- .../project/handlers/SelectTraceTypeHandler.java | 203 -- .../ui/project/handlers/SelectTracesHandler.java | 107 - .../project/handlers/SynchronizeTracesHandler.java | 279 -- .../tmf/ui/project/handlers/TmfActionProvider.java | 81 - .../ui/project/handlers/TracePropertyTester.java | 118 - .../tmf/ui/project/handlers/messages.properties | 70 - .../tmf/ui/project/model/TmfEditorLinkHelper.java | 130 - .../tmf/ui/project/model/TmfImportHelper.java | 76 - .../operations/TmfWorkspaceModifyOperation.java | 114 - .../importtrace/AbstractImportTraceWizardPage.java | 154 -- .../importtrace/BatchImportTraceWizard.java | 699 ----- .../project/wizards/importtrace/FileAndName.java | 188 -- .../importtrace/ImportTraceContentProvider.java | 183 -- .../importtrace/ImportTraceLabelProvider.java | 41 - .../wizards/importtrace/ImportTraceWizard.java | 87 - .../wizards/importtrace/ImportTraceWizardPage.java | 2234 ---------------- .../importtrace/ImportTraceWizardPageOptions.java | 112 - .../importtrace/ImportTraceWizardScanPage.java | 566 ---- .../ImportTraceWizardSelectDirectoriesPage.java | 261 -- .../ImportTraceWizardSelectTraceTypePage.java | 184 -- .../ui/project/wizards/importtrace/Messages.java | 237 -- .../importtrace/ResourceTreeAndListGroup.java | 1203 --------- .../importtrace/TraceTypeContentProvider.java | 101 - .../wizards/importtrace/messages.properties | 81 - .../tracepkg/AbstractTracePackageOperation.java | 369 --- .../tracepkg/AbstractTracePackageWizardPage.java | 565 ---- .../wizards/tracepkg/ITracePackageConstants.java | 76 - .../tmf/ui/project/wizards/tracepkg/Messages.java | 84 - .../tracepkg/TracePackageBookmarkElement.java | 66 - .../tracepkg/TracePackageContentProvider.java | 58 - .../wizards/tracepkg/TracePackageElement.java | 179 -- .../wizards/tracepkg/TracePackageFilesElement.java | 107 - .../tracepkg/TracePackageLabelProvider.java | 69 - .../tracepkg/TracePackageSupplFileElement.java | 89 - .../tracepkg/TracePackageSupplFilesElement.java | 47 - .../wizards/tracepkg/TracePackageTraceElement.java | 149 -- .../importexport/ExportTracePackageHandler.java | 105 - .../ExportTracePackageSelectTraceWizardPage.java | 218 -- .../importexport/ExportTracePackageWizard.java | 84 - .../importexport/ExportTracePackageWizardPage.java | 453 ---- .../importexport/ImportTracePackageHandler.java | 53 - .../importexport/ImportTracePackageWizard.java | 63 - .../importexport/ImportTracePackageWizardPage.java | 417 --- .../tracepkg/importexport/ManifestReader.java | 191 -- .../wizards/tracepkg/importexport/Messages.java | 239 -- .../importexport/TracePackageExportOperation.java | 304 --- .../TracePackageExtractManifestOperation.java | 142 - .../importexport/TracePackageImportOperation.java | 487 ---- .../tracepkg/importexport/messages.properties | 53 - .../project/wizards/tracepkg/messages.properties | 22 - .../viewers/events/columns/TmfContentsColumn.java | 47 - .../viewers/events/columns/TmfReferenceColumn.java | 47 - .../ui/viewers/events/columns/TmfSourceColumn.java | 47 - .../viewers/events/columns/TmfTimestampColumn.java | 45 - .../ui/viewers/events/columns/TmfTypeColumn.java | 50 - .../linuxtools/tmf/ui/TmfUiRefreshHandler.java | 131 - .../tmf/ui/analysis/TmfAnalysisViewOutput.java | 133 - .../linuxtools/tmf/ui/editors/ITmfTraceEditor.java | 31 - .../linuxtools/tmf/ui/editors/TmfEditor.java | 71 - .../linuxtools/tmf/ui/editors/TmfEditorInput.java | 136 - .../linuxtools/tmf/ui/editors/TmfEventsEditor.java | 649 ----- .../tmf/ui/editors/TmfMultiPageEditorPart.java | 62 - .../tmf/ui/editors/UnsortedPropertySheetPage.java | 41 - .../ui/project/model/ITmfProjectModelElement.java | 87 - .../model/ITmfStyledProjectModelElement.java | 34 - .../linuxtools/tmf/ui/project/model/Messages.java | 146 - .../tmf/ui/project/model/TmfAnalysisElement.java | 254 -- .../ui/project/model/TmfAnalysisOutputElement.java | 86 - .../ui/project/model/TmfCommonProjectElement.java | 573 ---- .../tmf/ui/project/model/TmfExperimentElement.java | 478 ---- .../tmf/ui/project/model/TmfExperimentFolder.java | 196 -- .../project/model/TmfNavigatorContentProvider.java | 193 -- .../project/model/TmfNavigatorLabelProvider.java | 267 -- .../tmf/ui/project/model/TmfOpenTraceHelper.java | 464 ---- .../tmf/ui/project/model/TmfProjectElement.java | 146 - .../ui/project/model/TmfProjectModelElement.java | 271 -- .../tmf/ui/project/model/TmfProjectRegistry.java | 205 -- .../tmf/ui/project/model/TmfTraceElement.java | 700 ----- .../tmf/ui/project/model/TmfTraceFolder.java | 209 -- .../tmf/ui/project/model/TmfTraceTypeUIUtils.java | 494 ---- .../tmf/ui/project/model/TmfTracesFolder.java | 49 - .../tmf/ui/project/model/TmfViewerSorter.java | 42 - .../project/model/TraceFolderContentProvider.java | 55 - .../ui/project/model/TraceFolderLabelProvider.java | 37 - .../tmf/ui/project/model/TraceUtils.java | 99 - .../tmf/ui/project/model/messages.properties | 49 - .../ui/project/wizards/CopyExperimentDialog.java | 226 -- .../tmf/ui/project/wizards/CopyTraceDialog.java | 223 -- .../tmf/ui/project/wizards/Messages.java | 176 -- .../ui/project/wizards/NewExperimentDialog.java | 231 -- .../tmf/ui/project/wizards/NewFolderDialog.java | 192 -- .../wizards/NewTmfProjectMainWizardPage.java | 36 - .../ui/project/wizards/NewTmfProjectWizard.java | 152 -- .../ui/project/wizards/RenameExperimentDialog.java | 242 -- .../tmf/ui/project/wizards/RenameFolderDialog.java | 167 -- .../tmf/ui/project/wizards/RenameTraceDialog.java | 169 -- .../tmf/ui/project/wizards/SelectTracesWizard.java | 74 - .../ui/project/wizards/SelectTracesWizardPage.java | 477 ---- .../tmf/ui/project/wizards/messages.properties | 64 - .../linuxtools/tmf/ui/properties/Messages.java | 32 - .../properties/ReadOnlyTextPropertyDescriptor.java | 51 - .../tmf/ui/properties/TmfTimestampFormatPage.java | 391 --- .../tmf/ui/properties/messages.properties | 13 - .../tmf/ui/viewers/ArrayTreeContentProvider.java | 64 - .../tmf/ui/viewers/ITmfTimeProvider.java | 95 - .../linuxtools/tmf/ui/viewers/ITmfViewer.java | 41 - .../linuxtools/tmf/ui/viewers/TmfTimeViewer.java | 442 ---- .../linuxtools/tmf/ui/viewers/TmfViewer.java | 88 - .../ui/viewers/events/TmfEventAdapterFactory.java | 41 - .../ui/viewers/events/TmfEventPropertySource.java | 355 --- .../tmf/ui/viewers/events/TmfEventsCache.java | 489 ---- .../tmf/ui/viewers/events/TmfEventsTable.java | 2539 ------------------ .../events/columns/ITmfEventTableColumns.java | 44 - .../events/columns/TmfEventTableColumn.java | 159 -- .../events/columns/TmfEventTableFieldColumn.java | 114 - .../ui/viewers/events/text/TmfTextEventTable.java | 72 - .../tmf/ui/viewers/statistics/Messages.java | 39 - .../ui/viewers/statistics/TmfStatisticsViewer.java | 799 ------ .../tmf/ui/viewers/statistics/messages.properties | 13 - .../tmf/ui/viewers/statistics/model/Messages.java | 77 - .../statistics/model/TmfBaseColumnData.java | 178 -- .../model/TmfBaseColumnDataProvider.java | 289 -- .../statistics/model/TmfStatisticsFormatter.java | 84 - .../statistics/model/TmfStatisticsTree.java | 171 -- .../statistics/model/TmfStatisticsTreeManager.java | 118 - .../statistics/model/TmfStatisticsTreeNode.java | 252 -- .../statistics/model/TmfStatisticsValues.java | 90 - .../statistics/model/TmfTreeContentProvider.java | 55 - .../viewers/statistics/model/messages.properties | 20 - .../tmf/ui/viewers/tree/AbstractTmfTreeViewer.java | 508 ---- .../viewers/tree/ITmfTreeColumnDataProvider.java | 33 - .../tmf/ui/viewers/tree/ITmfTreeViewerEntry.java | 57 - .../tmf/ui/viewers/tree/TmfTreeColumnData.java | 266 -- .../tmf/ui/viewers/tree/TmfTreeViewerEntry.java | 107 - .../ui/viewers/xycharts/ITmfChartTimeProvider.java | 54 - .../tmf/ui/viewers/xycharts/TmfBaseProvider.java | 155 -- .../viewers/xycharts/TmfChartTimeStampFormat.java | 63 - .../ui/viewers/xycharts/TmfMouseDragProvider.java | 135 - .../viewers/xycharts/TmfMouseDragZoomProvider.java | 152 -- .../xycharts/TmfMouseSelectionProvider.java | 164 -- .../xycharts/TmfMouseWheelZoomProvider.java | 135 - .../viewers/xycharts/TmfSimpleTooltipProvider.java | 97 - .../tmf/ui/viewers/xycharts/TmfXYChartViewer.java | 373 --- .../xycharts/barcharts/TmfBarChartViewer.java | 220 -- .../barcharts/TmfHistogramTooltipProvider.java | 179 -- .../TmfCommonXLineChartTooltipProvider.java | 129 - .../linecharts/TmfCommonXLineChartViewer.java | 374 --- .../linuxtools/tmf/ui/views/PinTmfViewAction.java | 37 - .../linuxtools/tmf/ui/views/TmfChartView.java | 118 - .../eclipse/linuxtools/tmf/ui/views/TmfView.java | 149 -- .../tmf/ui/views/TracingPerspectiveFactory.java | 79 - .../views/callstack/AbstractCallStackAnalysis.java | 67 - .../tmf/ui/views/callstack/CallStackEntry.java | 192 -- .../tmf/ui/views/callstack/CallStackEvent.java | 40 - .../callstack/CallStackPresentationProvider.java | 153 -- .../tmf/ui/views/callstack/CallStackView.java | 1569 ----------- .../tmf/ui/views/callstack/FunctionNameMapper.java | 177 -- .../tmf/ui/views/colors/ColorSetting.java | 214 -- .../tmf/ui/views/colors/ColorSettingsManager.java | 153 -- .../tmf/ui/views/colors/ColorSettingsXML.java | 221 -- .../linuxtools/tmf/ui/views/colors/ColorsView.java | 588 ---- .../ui/views/colors/IColorSettingsListener.java | 30 - .../distribution/model/BaseDistributionData.java | 243 -- .../distribution/model/IBaseDistributionModel.java | 35 - .../tmf/ui/views/filter/CopyHandler.java | 79 - .../linuxtools/tmf/ui/views/filter/CutHandler.java | 43 - .../tmf/ui/views/filter/DeleteHandler.java | 75 - .../tmf/ui/views/filter/FilterDialog.java | 81 - .../ui/views/filter/FilterDragSourceAdapter.java | 70 - .../ui/views/filter/FilterDropTargetAdapter.java | 124 - .../tmf/ui/views/filter/FilterEditUtils.java | 48 - .../tmf/ui/views/filter/FilterManager.java | 78 - .../ui/views/filter/FilterTreeContentProvider.java | 71 - .../ui/views/filter/FilterTreeLabelProvider.java | 126 - .../linuxtools/tmf/ui/views/filter/FilterView.java | 309 --- .../tmf/ui/views/filter/FilterViewer.java | 1124 -------- .../tmf/ui/views/filter/PasteHandler.java | 89 - .../tmf/ui/views/histogram/FullTraceHistogram.java | 224 -- .../tmf/ui/views/histogram/Histogram.java | 1045 -------- .../tmf/ui/views/histogram/HistogramBucket.java | 175 -- .../histogram/HistogramCurrentTimeControl.java | 130 - .../tmf/ui/views/histogram/HistogramDataModel.java | 717 ----- .../tmf/ui/views/histogram/HistogramRequest.java | 115 - .../ui/views/histogram/HistogramScaledData.java | 210 -- .../histogram/HistogramSelectionEndControl.java | 43 - .../histogram/HistogramSelectionStartControl.java | 47 - .../ui/views/histogram/HistogramTextControl.java | 280 -- .../views/histogram/HistogramTimeRangeControl.java | 106 - .../tmf/ui/views/histogram/HistogramView.java | 887 ------- .../tmf/ui/views/histogram/HistogramZoom.java | 210 -- .../ui/views/histogram/IHistogramDataModel.java | 48 - .../views/histogram/IHistogramModelListener.java | 27 - .../tmf/ui/views/histogram/Messages.java | 95 - .../tmf/ui/views/histogram/TimeRangeHistogram.java | 217 -- .../tmf/ui/views/histogram/messages.properties | 21 - .../tmf/ui/views/statesystem/Messages.java | 86 - .../views/statesystem/TmfStateSystemExplorer.java | 107 - .../ui/views/statesystem/TmfStateSystemViewer.java | 463 ---- .../tmf/ui/views/statesystem/messages.properties | 28 - .../tmf/ui/views/statistics/Messages.java | 41 - .../tmf/ui/views/statistics/TmfStatisticsView.java | 230 -- .../tmf/ui/views/statistics/messages.properties | 13 - .../tmf/ui/views/synchronization/Messages.java | 33 - .../synchronization/TmfSynchronizationView.java | 156 -- .../ui/views/synchronization/messages.properties | 13 - .../ui/views/timechart/TimeChartAnalysisEntry.java | 277 -- .../views/timechart/TimeChartAnalysisProvider.java | 108 - .../timechart/TimeChartDecorationProvider.java | 141 - .../tmf/ui/views/timechart/TimeChartEvent.java | 375 --- .../tmf/ui/views/timechart/TimeChartView.java | 754 ------ .../ui/views/timegraph/AbstractTimeGraphView.java | 1271 --------- .../tmf/ui/views/timegraph/Messages.java | 38 - .../tmf/ui/views/timegraph/messages.properties | 16 - .../tmf/ui/views/uml2sd/DiagramToolTip.java | 131 - .../tmf/ui/views/uml2sd/DrawableToolTip.java | 305 --- .../ui/views/uml2sd/ITimeCompressionListener.java | 42 - .../linuxtools/tmf/ui/views/uml2sd/NGC.java | 988 ------- .../linuxtools/tmf/ui/views/uml2sd/SDView.java | 1181 --------- .../linuxtools/tmf/ui/views/uml2sd/SDWidget.java | 2066 --------------- .../ui/views/uml2sd/SDWidgetSelectionProvider.java | 88 - .../linuxtools/tmf/ui/views/uml2sd/ScrollView.java | 2067 --------------- .../tmf/ui/views/uml2sd/TimeCompressionBar.java | 1028 ------- .../tmf/ui/views/uml2sd/core/AsyncMessage.java | 469 ---- .../ui/views/uml2sd/core/AsyncMessageReturn.java | 112 - .../tmf/ui/views/uml2sd/core/BaseMessage.java | 724 ----- .../uml2sd/core/BasicExecutionOccurrence.java | 275 -- .../tmf/ui/views/uml2sd/core/BasicFrame.java | 633 ----- .../tmf/ui/views/uml2sd/core/EllipsisMessage.java | 141 - .../ui/views/uml2sd/core/ExecutionOccurrence.java | 267 -- .../linuxtools/tmf/ui/views/uml2sd/core/Frame.java | 1215 --------- .../tmf/ui/views/uml2sd/core/GraphNode.java | 906 ------- .../tmf/ui/views/uml2sd/core/HotSpot.java | 193 -- .../tmf/ui/views/uml2sd/core/ITimeRange.java | 46 - .../tmf/ui/views/uml2sd/core/Lifeline.java | 534 ---- .../ui/views/uml2sd/core/LifelineCategories.java | 81 - .../tmf/ui/views/uml2sd/core/Metrics.java | 332 --- .../tmf/ui/views/uml2sd/core/SDTimeEvent.java | 91 - .../linuxtools/tmf/ui/views/uml2sd/core/Stop.java | 167 -- .../tmf/ui/views/uml2sd/core/SyncMessage.java | 296 --- .../ui/views/uml2sd/core/SyncMessageReturn.java | 112 - .../tmf/ui/views/uml2sd/dialogs/Criteria.java | 415 --- .../ui/views/uml2sd/dialogs/FilterCriteria.java | 273 -- .../ui/views/uml2sd/dialogs/FilterListDialog.java | 518 ---- .../tmf/ui/views/uml2sd/dialogs/MinMaxDialog.java | 190 -- .../tmf/ui/views/uml2sd/dialogs/PagesDialog.java | 204 -- .../tmf/ui/views/uml2sd/dialogs/SDPrintDialog.java | 174 -- .../ui/views/uml2sd/dialogs/SDPrintDialogUI.java | 1424 ---------- .../views/uml2sd/dialogs/SearchFilterDialog.java | 451 ---- .../tmf/ui/views/uml2sd/dialogs/TabContents.java | 476 ---- .../tmf/ui/views/uml2sd/drawings/IColor.java | 36 - .../tmf/ui/views/uml2sd/drawings/IFont.java | 36 - .../tmf/ui/views/uml2sd/drawings/IGC.java | 375 --- .../tmf/ui/views/uml2sd/drawings/IImage.java | 37 - .../ui/views/uml2sd/drawings/impl/ColorImpl.java | 92 - .../ui/views/uml2sd/drawings/impl/FontImpl.java | 89 - .../ui/views/uml2sd/drawings/impl/ImageImpl.java | 105 - .../tmf/ui/views/uml2sd/handlers/BaseSDAction.java | 89 - .../ui/views/uml2sd/handlers/ConfigureMinMax.java | 46 - .../tmf/ui/views/uml2sd/handlers/FirstPage.java | 68 - .../views/uml2sd/handlers/KeyBindingsManager.java | 302 --- .../tmf/ui/views/uml2sd/handlers/LastPage.java | 68 - .../tmf/ui/views/uml2sd/handlers/MoveSDDown.java | 70 - .../tmf/ui/views/uml2sd/handlers/MoveSDLeft.java | 72 - .../tmf/ui/views/uml2sd/handlers/MoveSDRight.java | 73 - .../tmf/ui/views/uml2sd/handlers/MoveSDUp.java | 71 - .../ui/views/uml2sd/handlers/MoveToMessage.java | 113 - .../tmf/ui/views/uml2sd/handlers/NextPage.java | 68 - .../views/uml2sd/handlers/OpenSDFiltersDialog.java | 75 - .../ui/views/uml2sd/handlers/OpenSDFindDialog.java | 93 - .../views/uml2sd/handlers/OpenSDPagesDialog.java | 80 - .../tmf/ui/views/uml2sd/handlers/PrevPage.java | 70 - .../tmf/ui/views/uml2sd/handlers/Print.java | 60 - .../tmf/ui/views/uml2sd/handlers/ShowNodeEnd.java | 89 - .../ui/views/uml2sd/handlers/ShowNodeStart.java | 89 - .../tmf/ui/views/uml2sd/handlers/Zoom.java | 239 -- .../handlers/provider/IExtendedFilterProvider.java | 37 - .../handlers/provider/IExtendedFindProvider.java | 38 - .../provider/ISDAdvancedPagingProvider.java | 51 - .../handlers/provider/ISDCollapseProvider.java | 36 - .../provider/ISDExtendedActionBarProvider.java | 37 - .../handlers/provider/ISDFilterProvider.java | 43 - .../uml2sd/handlers/provider/ISDFindProvider.java | 46 - .../handlers/provider/ISDGraphNodeSupporter.java | 83 - .../handlers/provider/ISDPagingProvider.java | 61 - .../handlers/provider/ISDPropertiesProvider.java | 35 - .../tmf/ui/views/uml2sd/load/IUml2SDLoader.java | 46 - .../tmf/ui/views/uml2sd/load/LoadersManager.java | 397 --- .../tmf/ui/views/uml2sd/loader/Messages.java | 49 - .../ui/views/uml2sd/loader/TmfAsyncMessage.java | 68 - .../tmf/ui/views/uml2sd/loader/TmfSyncMessage.java | 68 - .../views/uml2sd/loader/TmfUml2SDSyncLoader.java | 1485 ----------- .../tmf/ui/views/uml2sd/loader/messages.properties | 22 - .../views/uml2sd/preferences/ISDPreferences.java | 147 - .../ui/views/uml2sd/preferences/SDViewPref.java | 527 ---- .../ui/views/uml2sd/preferences/SDViewerPage.java | 431 --- .../tmf/ui/views/uml2sd/util/Messages.java | 157 -- .../ui/views/uml2sd/util/SortAsyncForBackward.java | 96 - .../uml2sd/util/SortAsyncMessageComparator.java | 94 - .../uml2sd/util/SortSyncMessageComparator.java | 61 - .../ui/views/uml2sd/util/TimeEventComparator.java | 53 - .../tmf/ui/views/uml2sd/util/messages.properties | 132 - .../ui/widgets/rawviewer/TmfRawEventViewer.java | 1060 -------- .../tmf/ui/widgets/tabsview/TmfViewerFolder.java | 193 -- .../widgets/timegraph/ITimeGraphColorListener.java | 32 - .../timegraph/ITimeGraphContentProvider.java | 34 - .../timegraph/ITimeGraphPresentationProvider.java | 177 -- .../timegraph/ITimeGraphPresentationProvider2.java | 62 - .../widgets/timegraph/ITimeGraphRangeListener.java | 31 - .../timegraph/ITimeGraphSelectionListener.java | 31 - .../widgets/timegraph/ITimeGraphTimeListener.java | 31 - .../widgets/timegraph/ITimeGraphTreeListener.java | 36 - .../tmf/ui/widgets/timegraph/StateItem.java | 107 - .../tmf/ui/widgets/timegraph/TimeGraphCombo.java | 1134 -------- .../timegraph/TimeGraphPresentationProvider.java | 189 -- .../timegraph/TimeGraphRangeUpdateEvent.java | 71 - .../widgets/timegraph/TimeGraphSelectionEvent.java | 58 - .../ui/widgets/timegraph/TimeGraphTimeEvent.java | 74 - .../timegraph/TimeGraphTreeExpansionEvent.java | 57 - .../tmf/ui/widgets/timegraph/TimeGraphViewer.java | 1760 ------------ .../timegraph/dialogs/FilteredCheckboxTree.java | 193 -- .../timegraph/dialogs/TimeGraphFilterDialog.java | 569 ---- .../widgets/timegraph/dialogs/TimeGraphLegend.java | 191 -- .../timegraph/dialogs/TreePatternFilter.java | 61 - .../ui/widgets/timegraph/model/EventIterator.java | 157 -- .../tmf/ui/widgets/timegraph/model/ILinkEvent.java | 29 - .../tmf/ui/widgets/timegraph/model/ITimeEvent.java | 50 - .../ui/widgets/timegraph/model/ITimeEvent2.java | 35 - .../widgets/timegraph/model/ITimeGraphEntry.java | 102 - .../ui/widgets/timegraph/model/NullTimeEvent.java | 37 - .../tmf/ui/widgets/timegraph/model/TimeEvent.java | 138 - .../ui/widgets/timegraph/model/TimeGraphEntry.java | 304 --- .../ui/widgets/timegraph/model/TimeLinkEvent.java | 68 - .../timegraph/widgets/ITimeDataProvider.java | 175 -- .../widgets/ITimeDataProviderConverter.java | 31 - .../widgets/ITmfTimeGraphDrawingHelper.java | 44 - .../widgets/TimeDataProviderCyclesConverter.java | 178 -- .../timegraph/widgets/TimeGraphBaseControl.java | 115 - .../timegraph/widgets/TimeGraphColorScheme.java | 428 --- .../timegraph/widgets/TimeGraphControl.java | 2799 -------------------- .../widgets/timegraph/widgets/TimeGraphScale.java | 859 ------ .../timegraph/widgets/TimeGraphSelection.java | 97 - .../timegraph/widgets/TimeGraphTooltipHandler.java | 380 --- .../tmf/ui/widgets/timegraph/widgets/Utils.java | 826 ------ .../tmf/ui/widgets/virtualtable/ColumnData.java | 48 - .../widgets/virtualtable/IDoubleClickListener.java | 30 - .../ui/widgets/virtualtable/TmfVirtualTable.java | 1130 -------- .../ui/widgets/virtualtable/TooltipProvider.java | 29 - .../tracecompass/internal/tmf/ui/Activator.java | 245 ++ .../internal/tmf/ui/ITmfImageConstants.java | 63 + .../tracecompass/internal/tmf/ui/Messages.java | 306 +++ .../tracecompass/internal/tmf/ui/TmfUiTracer.java | 245 ++ .../ui/commands/ExportToTextCommandHandler.java | 81 + .../internal/tmf/ui/commands/ExportToTextJob.java | 135 + .../tmf/ui/commands/ExportToTextRequest.java | 103 + .../ManageCustomParsersCommandHandler.java | 35 + .../internal/tmf/ui/commands/Messages.java | 37 + .../internal/tmf/ui/commands/OpenFileHandler.java | 79 + .../internal/tmf/ui/commands/TmfHandlerUtil.java | 76 + .../internal/tmf/ui/commands/messages.properties | 14 + .../tmf/ui/dialogs/ManageCustomParsersDialog.java | 367 +++ .../tmf/ui/dialogs/MultiLineInputDialog.java | 167 ++ .../ui/editors/handlers/AddBookmarkHandler.java | 48 + .../internal/tmf/ui/messages.properties | 297 +++ .../ui/parsers/custom/CustomEventTableColumns.java | 100 + .../wizards/CustomTxtParserInputWizardPage.java | 1681 ++++++++++++ .../wizards/CustomTxtParserOutputWizardPage.java | 340 +++ .../ui/parsers/wizards/CustomTxtParserWizard.java | 82 + .../wizards/CustomXmlParserInputWizardPage.java | 1765 ++++++++++++ .../wizards/CustomXmlParserOutputWizardPage.java | 341 +++ .../ui/parsers/wizards/CustomXmlParserWizard.java | 86 + .../ui/preferences/TmfTracingPreferencePage.java | 52 + .../internal/tmf/ui/project/dialogs/Messages.java | 38 + .../SelectSupplementaryResourcesDialog.java | 324 +++ .../tmf/ui/project/dialogs/messages.properties | 16 + .../tmf/ui/project/dialogs/offset/Messages.java | 67 + .../ui/project/dialogs/offset/OffsetDialog.java | 578 ++++ .../ui/project/dialogs/offset/messages.properties | 24 + .../project/handlers/BatchImportTraceHandler.java | 60 + .../project/handlers/ClearTraceOffsetHandler.java | 118 + .../ui/project/handlers/CopyExperimentHandler.java | 54 + .../tmf/ui/project/handlers/CopyTraceHandler.java | 54 + .../project/handlers/DeleteExperimentHandler.java | 113 + .../handlers/DeleteTraceFolderElementHandler.java | 349 +++ .../DeleteTraceSupplementaryFilesHandler.java | 192 ++ .../ui/project/handlers/DropAdapterAssistant.java | 669 +++++ .../ui/project/handlers/ImportTraceHandler.java | 64 + .../internal/tmf/ui/project/handlers/Messages.java | 85 + .../ui/project/handlers/NewExperimentHandler.java | 74 + .../tmf/ui/project/handlers/NewFolderHandler.java | 63 + .../ui/project/handlers/OffsetTraceHandler.java | 132 + .../tmf/ui/project/handlers/OpenAction.java | 94 + .../project/handlers/OpenAnalysisHelpHandler.java | 114 + .../handlers/OpenAnalysisOutputHandler.java | 89 + .../ui/project/handlers/OpenExperimentHandler.java | 99 + .../tmf/ui/project/handlers/OpenTraceHandler.java | 104 + .../tmf/ui/project/handlers/RefreshHandler.java | 87 + .../project/handlers/RenameExperimentHandler.java | 96 + .../ui/project/handlers/RenameFolderHandler.java | 158 ++ .../ui/project/handlers/RenameTraceHandler.java | 171 ++ .../SelectElementTypeContributionItem.java | 269 ++ .../project/handlers/SelectTraceTypeHandler.java | 203 ++ .../ui/project/handlers/SelectTracesHandler.java | 107 + .../project/handlers/SynchronizeTracesHandler.java | 279 ++ .../tmf/ui/project/handlers/TmfActionProvider.java | 81 + .../ui/project/handlers/TracePropertyTester.java | 118 + .../tmf/ui/project/handlers/messages.properties | 70 + .../tmf/ui/project/model/TmfEditorLinkHelper.java | 130 + .../tmf/ui/project/model/TmfImportHelper.java | 76 + .../operations/TmfWorkspaceModifyOperation.java | 114 + .../importtrace/AbstractImportTraceWizardPage.java | 154 ++ .../importtrace/BatchImportTraceWizard.java | 699 +++++ .../project/wizards/importtrace/FileAndName.java | 188 ++ .../importtrace/ImportTraceContentProvider.java | 183 ++ .../importtrace/ImportTraceLabelProvider.java | 41 + .../wizards/importtrace/ImportTraceWizard.java | 87 + .../wizards/importtrace/ImportTraceWizardPage.java | 2234 ++++++++++++++++ .../importtrace/ImportTraceWizardPageOptions.java | 112 + .../importtrace/ImportTraceWizardScanPage.java | 566 ++++ .../ImportTraceWizardSelectDirectoriesPage.java | 261 ++ .../ImportTraceWizardSelectTraceTypePage.java | 184 ++ .../ui/project/wizards/importtrace/Messages.java | 237 ++ .../importtrace/ResourceTreeAndListGroup.java | 1203 +++++++++ .../importtrace/TraceTypeContentProvider.java | 101 + .../wizards/importtrace/messages.properties | 81 + .../tracepkg/AbstractTracePackageOperation.java | 369 +++ .../tracepkg/AbstractTracePackageWizardPage.java | 565 ++++ .../wizards/tracepkg/ITracePackageConstants.java | 76 + .../tmf/ui/project/wizards/tracepkg/Messages.java | 84 + .../tracepkg/TracePackageBookmarkElement.java | 66 + .../tracepkg/TracePackageContentProvider.java | 58 + .../wizards/tracepkg/TracePackageElement.java | 179 ++ .../wizards/tracepkg/TracePackageFilesElement.java | 107 + .../tracepkg/TracePackageLabelProvider.java | 69 + .../tracepkg/TracePackageSupplFileElement.java | 89 + .../tracepkg/TracePackageSupplFilesElement.java | 47 + .../wizards/tracepkg/TracePackageTraceElement.java | 149 ++ .../importexport/ExportTracePackageHandler.java | 105 + .../ExportTracePackageSelectTraceWizardPage.java | 218 ++ .../importexport/ExportTracePackageWizard.java | 84 + .../importexport/ExportTracePackageWizardPage.java | 453 ++++ .../importexport/ImportTracePackageHandler.java | 53 + .../importexport/ImportTracePackageWizard.java | 63 + .../importexport/ImportTracePackageWizardPage.java | 417 +++ .../tracepkg/importexport/ManifestReader.java | 191 ++ .../wizards/tracepkg/importexport/Messages.java | 239 ++ .../importexport/TracePackageExportOperation.java | 304 +++ .../TracePackageExtractManifestOperation.java | 142 + .../importexport/TracePackageImportOperation.java | 487 ++++ .../tracepkg/importexport/messages.properties | 53 + .../project/wizards/tracepkg/messages.properties | 22 + .../viewers/events/columns/TmfContentsColumn.java | 47 + .../viewers/events/columns/TmfReferenceColumn.java | 47 + .../ui/viewers/events/columns/TmfSourceColumn.java | 47 + .../viewers/events/columns/TmfTimestampColumn.java | 45 + .../ui/viewers/events/columns/TmfTypeColumn.java | 50 + .../tracecompass/tmf/ui/TmfUiRefreshHandler.java | 131 + .../tmf/ui/analysis/TmfAnalysisViewOutput.java | 133 + .../tmf/ui/editors/ITmfTraceEditor.java | 31 + .../tracecompass/tmf/ui/editors/TmfEditor.java | 71 + .../tmf/ui/editors/TmfEditorInput.java | 136 + .../tmf/ui/editors/TmfEventsEditor.java | 649 +++++ .../tmf/ui/editors/TmfMultiPageEditorPart.java | 62 + .../tmf/ui/editors/UnsortedPropertySheetPage.java | 41 + .../ui/project/model/ITmfProjectModelElement.java | 87 + .../model/ITmfStyledProjectModelElement.java | 34 + .../tmf/ui/project/model/Messages.java | 146 + .../tmf/ui/project/model/TmfAnalysisElement.java | 254 ++ .../ui/project/model/TmfAnalysisOutputElement.java | 86 + .../ui/project/model/TmfCommonProjectElement.java | 573 ++++ .../tmf/ui/project/model/TmfExperimentElement.java | 478 ++++ .../tmf/ui/project/model/TmfExperimentFolder.java | 196 ++ .../project/model/TmfNavigatorContentProvider.java | 193 ++ .../project/model/TmfNavigatorLabelProvider.java | 267 ++ .../tmf/ui/project/model/TmfOpenTraceHelper.java | 464 ++++ .../tmf/ui/project/model/TmfProjectElement.java | 146 + .../ui/project/model/TmfProjectModelElement.java | 271 ++ .../tmf/ui/project/model/TmfProjectRegistry.java | 205 ++ .../tmf/ui/project/model/TmfTraceElement.java | 700 +++++ .../tmf/ui/project/model/TmfTraceFolder.java | 209 ++ .../tmf/ui/project/model/TmfTraceTypeUIUtils.java | 494 ++++ .../tmf/ui/project/model/TmfTracesFolder.java | 49 + .../tmf/ui/project/model/TmfViewerSorter.java | 42 + .../project/model/TraceFolderContentProvider.java | 55 + .../ui/project/model/TraceFolderLabelProvider.java | 37 + .../tmf/ui/project/model/TraceUtils.java | 99 + .../tmf/ui/project/model/messages.properties | 49 + .../ui/project/wizards/CopyExperimentDialog.java | 226 ++ .../tmf/ui/project/wizards/CopyTraceDialog.java | 223 ++ .../tmf/ui/project/wizards/Messages.java | 176 ++ .../ui/project/wizards/NewExperimentDialog.java | 231 ++ .../tmf/ui/project/wizards/NewFolderDialog.java | 192 ++ .../wizards/NewTmfProjectMainWizardPage.java | 36 + .../ui/project/wizards/NewTmfProjectWizard.java | 152 ++ .../ui/project/wizards/RenameExperimentDialog.java | 242 ++ .../tmf/ui/project/wizards/RenameFolderDialog.java | 167 ++ .../tmf/ui/project/wizards/RenameTraceDialog.java | 169 ++ .../tmf/ui/project/wizards/SelectTracesWizard.java | 74 + .../ui/project/wizards/SelectTracesWizardPage.java | 477 ++++ .../tmf/ui/project/wizards/messages.properties | 64 + .../tracecompass/tmf/ui/properties/Messages.java | 32 + .../properties/ReadOnlyTextPropertyDescriptor.java | 51 + .../tmf/ui/properties/TmfTimestampFormatPage.java | 391 +++ .../tmf/ui/properties/messages.properties | 13 + .../tmf/ui/viewers/ArrayTreeContentProvider.java | 64 + .../tmf/ui/viewers/ITmfTimeProvider.java | 95 + .../tracecompass/tmf/ui/viewers/ITmfViewer.java | 41 + .../tracecompass/tmf/ui/viewers/TmfTimeViewer.java | 442 ++++ .../tracecompass/tmf/ui/viewers/TmfViewer.java | 88 + .../ui/viewers/events/TmfEventAdapterFactory.java | 41 + .../ui/viewers/events/TmfEventPropertySource.java | 355 +++ .../tmf/ui/viewers/events/TmfEventsCache.java | 489 ++++ .../tmf/ui/viewers/events/TmfEventsTable.java | 2539 ++++++++++++++++++ .../events/columns/ITmfEventTableColumns.java | 44 + .../events/columns/TmfEventTableColumn.java | 159 ++ .../events/columns/TmfEventTableFieldColumn.java | 114 + .../ui/viewers/events/text/TmfTextEventTable.java | 72 + .../tmf/ui/viewers/statistics/Messages.java | 39 + .../ui/viewers/statistics/TmfStatisticsViewer.java | 799 ++++++ .../tmf/ui/viewers/statistics/messages.properties | 13 + .../tmf/ui/viewers/statistics/model/Messages.java | 77 + .../statistics/model/TmfBaseColumnData.java | 178 ++ .../model/TmfBaseColumnDataProvider.java | 289 ++ .../statistics/model/TmfStatisticsFormatter.java | 84 + .../statistics/model/TmfStatisticsTree.java | 171 ++ .../statistics/model/TmfStatisticsTreeManager.java | 118 + .../statistics/model/TmfStatisticsTreeNode.java | 252 ++ .../statistics/model/TmfStatisticsValues.java | 90 + .../statistics/model/TmfTreeContentProvider.java | 55 + .../viewers/statistics/model/messages.properties | 20 + .../tmf/ui/viewers/tree/AbstractTmfTreeViewer.java | 508 ++++ .../viewers/tree/ITmfTreeColumnDataProvider.java | 33 + .../tmf/ui/viewers/tree/ITmfTreeViewerEntry.java | 57 + .../tmf/ui/viewers/tree/TmfTreeColumnData.java | 266 ++ .../tmf/ui/viewers/tree/TmfTreeViewerEntry.java | 107 + .../ui/viewers/xycharts/ITmfChartTimeProvider.java | 54 + .../tmf/ui/viewers/xycharts/TmfBaseProvider.java | 155 ++ .../viewers/xycharts/TmfChartTimeStampFormat.java | 63 + .../ui/viewers/xycharts/TmfMouseDragProvider.java | 135 + .../viewers/xycharts/TmfMouseDragZoomProvider.java | 152 ++ .../xycharts/TmfMouseSelectionProvider.java | 164 ++ .../xycharts/TmfMouseWheelZoomProvider.java | 135 + .../viewers/xycharts/TmfSimpleTooltipProvider.java | 97 + .../tmf/ui/viewers/xycharts/TmfXYChartViewer.java | 373 +++ .../xycharts/barcharts/TmfBarChartViewer.java | 220 ++ .../barcharts/TmfHistogramTooltipProvider.java | 179 ++ .../TmfCommonXLineChartTooltipProvider.java | 129 + .../linecharts/TmfCommonXLineChartViewer.java | 374 +++ .../tmf/ui/views/PinTmfViewAction.java | 37 + .../tracecompass/tmf/ui/views/TmfChartView.java | 118 + .../eclipse/tracecompass/tmf/ui/views/TmfView.java | 149 ++ .../tmf/ui/views/TracingPerspectiveFactory.java | 79 + .../views/callstack/AbstractCallStackAnalysis.java | 67 + .../tmf/ui/views/callstack/CallStackEntry.java | 192 ++ .../tmf/ui/views/callstack/CallStackEvent.java | 40 + .../callstack/CallStackPresentationProvider.java | 153 ++ .../tmf/ui/views/callstack/CallStackView.java | 1569 +++++++++++ .../tmf/ui/views/callstack/FunctionNameMapper.java | 177 ++ .../tmf/ui/views/colors/ColorSetting.java | 214 ++ .../tmf/ui/views/colors/ColorSettingsManager.java | 153 ++ .../tmf/ui/views/colors/ColorSettingsXML.java | 221 ++ .../tmf/ui/views/colors/ColorsView.java | 588 ++++ .../ui/views/colors/IColorSettingsListener.java | 30 + .../distribution/model/BaseDistributionData.java | 243 ++ .../distribution/model/IBaseDistributionModel.java | 35 + .../tmf/ui/views/filter/CopyHandler.java | 79 + .../tmf/ui/views/filter/CutHandler.java | 43 + .../tmf/ui/views/filter/DeleteHandler.java | 75 + .../tmf/ui/views/filter/FilterDialog.java | 81 + .../ui/views/filter/FilterDragSourceAdapter.java | 70 + .../ui/views/filter/FilterDropTargetAdapter.java | 124 + .../tmf/ui/views/filter/FilterEditUtils.java | 48 + .../tmf/ui/views/filter/FilterManager.java | 78 + .../ui/views/filter/FilterTreeContentProvider.java | 71 + .../ui/views/filter/FilterTreeLabelProvider.java | 126 + .../tmf/ui/views/filter/FilterView.java | 309 +++ .../tmf/ui/views/filter/FilterViewer.java | 1124 ++++++++ .../tmf/ui/views/filter/PasteHandler.java | 89 + .../tmf/ui/views/histogram/FullTraceHistogram.java | 224 ++ .../tmf/ui/views/histogram/Histogram.java | 1045 ++++++++ .../tmf/ui/views/histogram/HistogramBucket.java | 175 ++ .../histogram/HistogramCurrentTimeControl.java | 130 + .../tmf/ui/views/histogram/HistogramDataModel.java | 717 +++++ .../tmf/ui/views/histogram/HistogramRequest.java | 115 + .../ui/views/histogram/HistogramScaledData.java | 210 ++ .../histogram/HistogramSelectionEndControl.java | 43 + .../histogram/HistogramSelectionStartControl.java | 47 + .../ui/views/histogram/HistogramTextControl.java | 280 ++ .../views/histogram/HistogramTimeRangeControl.java | 106 + .../tmf/ui/views/histogram/HistogramView.java | 887 +++++++ .../tmf/ui/views/histogram/HistogramZoom.java | 210 ++ .../ui/views/histogram/IHistogramDataModel.java | 48 + .../views/histogram/IHistogramModelListener.java | 27 + .../tmf/ui/views/histogram/Messages.java | 95 + .../tmf/ui/views/histogram/TimeRangeHistogram.java | 217 ++ .../tmf/ui/views/histogram/messages.properties | 21 + .../tmf/ui/views/statesystem/Messages.java | 86 + .../views/statesystem/TmfStateSystemExplorer.java | 107 + .../ui/views/statesystem/TmfStateSystemViewer.java | 463 ++++ .../tmf/ui/views/statesystem/messages.properties | 28 + .../tmf/ui/views/statistics/Messages.java | 41 + .../tmf/ui/views/statistics/TmfStatisticsView.java | 230 ++ .../tmf/ui/views/statistics/messages.properties | 13 + .../tmf/ui/views/synchronization/Messages.java | 33 + .../synchronization/TmfSynchronizationView.java | 156 ++ .../ui/views/synchronization/messages.properties | 13 + .../ui/views/timechart/TimeChartAnalysisEntry.java | 277 ++ .../views/timechart/TimeChartAnalysisProvider.java | 108 + .../timechart/TimeChartDecorationProvider.java | 141 + .../tmf/ui/views/timechart/TimeChartEvent.java | 375 +++ .../tmf/ui/views/timechart/TimeChartView.java | 754 ++++++ .../ui/views/timegraph/AbstractTimeGraphView.java | 1271 +++++++++ .../tmf/ui/views/timegraph/Messages.java | 38 + .../tmf/ui/views/timegraph/messages.properties | 16 + .../tmf/ui/views/uml2sd/DiagramToolTip.java | 131 + .../tmf/ui/views/uml2sd/DrawableToolTip.java | 305 +++ .../ui/views/uml2sd/ITimeCompressionListener.java | 42 + .../tracecompass/tmf/ui/views/uml2sd/NGC.java | 988 +++++++ .../tracecompass/tmf/ui/views/uml2sd/SDView.java | 1181 +++++++++ .../tracecompass/tmf/ui/views/uml2sd/SDWidget.java | 2066 +++++++++++++++ .../ui/views/uml2sd/SDWidgetSelectionProvider.java | 88 + .../tmf/ui/views/uml2sd/ScrollView.java | 2067 +++++++++++++++ .../tmf/ui/views/uml2sd/TimeCompressionBar.java | 1028 +++++++ .../tmf/ui/views/uml2sd/core/AsyncMessage.java | 469 ++++ .../ui/views/uml2sd/core/AsyncMessageReturn.java | 112 + .../tmf/ui/views/uml2sd/core/BaseMessage.java | 724 +++++ .../uml2sd/core/BasicExecutionOccurrence.java | 275 ++ .../tmf/ui/views/uml2sd/core/BasicFrame.java | 633 +++++ .../tmf/ui/views/uml2sd/core/EllipsisMessage.java | 141 + .../ui/views/uml2sd/core/ExecutionOccurrence.java | 267 ++ .../tmf/ui/views/uml2sd/core/Frame.java | 1215 +++++++++ .../tmf/ui/views/uml2sd/core/GraphNode.java | 906 +++++++ .../tmf/ui/views/uml2sd/core/HotSpot.java | 193 ++ .../tmf/ui/views/uml2sd/core/ITimeRange.java | 46 + .../tmf/ui/views/uml2sd/core/Lifeline.java | 534 ++++ .../ui/views/uml2sd/core/LifelineCategories.java | 81 + .../tmf/ui/views/uml2sd/core/Metrics.java | 332 +++ .../tmf/ui/views/uml2sd/core/SDTimeEvent.java | 91 + .../tmf/ui/views/uml2sd/core/Stop.java | 167 ++ .../tmf/ui/views/uml2sd/core/SyncMessage.java | 296 +++ .../ui/views/uml2sd/core/SyncMessageReturn.java | 112 + .../tmf/ui/views/uml2sd/dialogs/Criteria.java | 415 +++ .../ui/views/uml2sd/dialogs/FilterCriteria.java | 273 ++ .../ui/views/uml2sd/dialogs/FilterListDialog.java | 518 ++++ .../tmf/ui/views/uml2sd/dialogs/MinMaxDialog.java | 190 ++ .../tmf/ui/views/uml2sd/dialogs/PagesDialog.java | 204 ++ .../tmf/ui/views/uml2sd/dialogs/SDPrintDialog.java | 174 ++ .../ui/views/uml2sd/dialogs/SDPrintDialogUI.java | 1424 ++++++++++ .../views/uml2sd/dialogs/SearchFilterDialog.java | 451 ++++ .../tmf/ui/views/uml2sd/dialogs/TabContents.java | 476 ++++ .../tmf/ui/views/uml2sd/drawings/IColor.java | 36 + .../tmf/ui/views/uml2sd/drawings/IFont.java | 36 + .../tmf/ui/views/uml2sd/drawings/IGC.java | 375 +++ .../tmf/ui/views/uml2sd/drawings/IImage.java | 37 + .../ui/views/uml2sd/drawings/impl/ColorImpl.java | 92 + .../ui/views/uml2sd/drawings/impl/FontImpl.java | 89 + .../ui/views/uml2sd/drawings/impl/ImageImpl.java | 105 + .../tmf/ui/views/uml2sd/handlers/BaseSDAction.java | 89 + .../ui/views/uml2sd/handlers/ConfigureMinMax.java | 46 + .../tmf/ui/views/uml2sd/handlers/FirstPage.java | 68 + .../views/uml2sd/handlers/KeyBindingsManager.java | 302 +++ .../tmf/ui/views/uml2sd/handlers/LastPage.java | 68 + .../tmf/ui/views/uml2sd/handlers/MoveSDDown.java | 70 + .../tmf/ui/views/uml2sd/handlers/MoveSDLeft.java | 72 + .../tmf/ui/views/uml2sd/handlers/MoveSDRight.java | 73 + .../tmf/ui/views/uml2sd/handlers/MoveSDUp.java | 71 + .../ui/views/uml2sd/handlers/MoveToMessage.java | 113 + .../tmf/ui/views/uml2sd/handlers/NextPage.java | 68 + .../views/uml2sd/handlers/OpenSDFiltersDialog.java | 75 + .../ui/views/uml2sd/handlers/OpenSDFindDialog.java | 93 + .../views/uml2sd/handlers/OpenSDPagesDialog.java | 80 + .../tmf/ui/views/uml2sd/handlers/PrevPage.java | 70 + .../tmf/ui/views/uml2sd/handlers/Print.java | 60 + .../tmf/ui/views/uml2sd/handlers/ShowNodeEnd.java | 89 + .../ui/views/uml2sd/handlers/ShowNodeStart.java | 89 + .../tmf/ui/views/uml2sd/handlers/Zoom.java | 239 ++ .../handlers/provider/IExtendedFilterProvider.java | 37 + .../handlers/provider/IExtendedFindProvider.java | 38 + .../provider/ISDAdvancedPagingProvider.java | 51 + .../handlers/provider/ISDCollapseProvider.java | 36 + .../provider/ISDExtendedActionBarProvider.java | 37 + .../handlers/provider/ISDFilterProvider.java | 43 + .../uml2sd/handlers/provider/ISDFindProvider.java | 46 + .../handlers/provider/ISDGraphNodeSupporter.java | 83 + .../handlers/provider/ISDPagingProvider.java | 61 + .../handlers/provider/ISDPropertiesProvider.java | 35 + .../tmf/ui/views/uml2sd/load/IUml2SDLoader.java | 46 + .../tmf/ui/views/uml2sd/load/LoadersManager.java | 397 +++ .../tmf/ui/views/uml2sd/loader/Messages.java | 49 + .../ui/views/uml2sd/loader/TmfAsyncMessage.java | 68 + .../tmf/ui/views/uml2sd/loader/TmfSyncMessage.java | 68 + .../views/uml2sd/loader/TmfUml2SDSyncLoader.java | 1485 +++++++++++ .../tmf/ui/views/uml2sd/loader/messages.properties | 22 + .../views/uml2sd/preferences/ISDPreferences.java | 147 + .../ui/views/uml2sd/preferences/SDViewPref.java | 527 ++++ .../ui/views/uml2sd/preferences/SDViewerPage.java | 431 +++ .../tmf/ui/views/uml2sd/util/Messages.java | 157 ++ .../ui/views/uml2sd/util/SortAsyncForBackward.java | 96 + .../uml2sd/util/SortAsyncMessageComparator.java | 94 + .../uml2sd/util/SortSyncMessageComparator.java | 61 + .../ui/views/uml2sd/util/TimeEventComparator.java | 53 + .../tmf/ui/views/uml2sd/util/messages.properties | 132 + .../ui/widgets/rawviewer/TmfRawEventViewer.java | 1060 ++++++++ .../tmf/ui/widgets/tabsview/TmfViewerFolder.java | 193 ++ .../widgets/timegraph/ITimeGraphColorListener.java | 32 + .../timegraph/ITimeGraphContentProvider.java | 34 + .../timegraph/ITimeGraphPresentationProvider.java | 177 ++ .../timegraph/ITimeGraphPresentationProvider2.java | 62 + .../widgets/timegraph/ITimeGraphRangeListener.java | 31 + .../timegraph/ITimeGraphSelectionListener.java | 31 + .../widgets/timegraph/ITimeGraphTimeListener.java | 31 + .../widgets/timegraph/ITimeGraphTreeListener.java | 36 + .../tmf/ui/widgets/timegraph/StateItem.java | 107 + .../tmf/ui/widgets/timegraph/TimeGraphCombo.java | 1134 ++++++++ .../timegraph/TimeGraphPresentationProvider.java | 189 ++ .../timegraph/TimeGraphRangeUpdateEvent.java | 71 + .../widgets/timegraph/TimeGraphSelectionEvent.java | 58 + .../ui/widgets/timegraph/TimeGraphTimeEvent.java | 74 + .../timegraph/TimeGraphTreeExpansionEvent.java | 57 + .../tmf/ui/widgets/timegraph/TimeGraphViewer.java | 1760 ++++++++++++ .../timegraph/dialogs/FilteredCheckboxTree.java | 193 ++ .../timegraph/dialogs/TimeGraphFilterDialog.java | 569 ++++ .../widgets/timegraph/dialogs/TimeGraphLegend.java | 191 ++ .../timegraph/dialogs/TreePatternFilter.java | 61 + .../ui/widgets/timegraph/model/EventIterator.java | 157 ++ .../tmf/ui/widgets/timegraph/model/ILinkEvent.java | 29 + .../tmf/ui/widgets/timegraph/model/ITimeEvent.java | 50 + .../ui/widgets/timegraph/model/ITimeEvent2.java | 35 + .../widgets/timegraph/model/ITimeGraphEntry.java | 102 + .../ui/widgets/timegraph/model/NullTimeEvent.java | 37 + .../tmf/ui/widgets/timegraph/model/TimeEvent.java | 138 + .../ui/widgets/timegraph/model/TimeGraphEntry.java | 304 +++ .../ui/widgets/timegraph/model/TimeLinkEvent.java | 68 + .../timegraph/widgets/ITimeDataProvider.java | 175 ++ .../widgets/ITimeDataProviderConverter.java | 31 + .../widgets/ITmfTimeGraphDrawingHelper.java | 44 + .../widgets/TimeDataProviderCyclesConverter.java | 178 ++ .../timegraph/widgets/TimeGraphBaseControl.java | 115 + .../timegraph/widgets/TimeGraphColorScheme.java | 428 +++ .../timegraph/widgets/TimeGraphControl.java | 2799 ++++++++++++++++++++ .../widgets/timegraph/widgets/TimeGraphScale.java | 859 ++++++ .../timegraph/widgets/TimeGraphSelection.java | 97 + .../timegraph/widgets/TimeGraphTooltipHandler.java | 380 +++ .../tmf/ui/widgets/timegraph/widgets/Utils.java | 826 ++++++ .../tmf/ui/widgets/virtualtable/ColumnData.java | 48 + .../widgets/virtualtable/IDoubleClickListener.java | 30 + .../ui/widgets/virtualtable/TmfVirtualTable.java | 1130 ++++++++ .../ui/widgets/virtualtable/TooltipProvider.java | 29 + 2065 files changed, 184410 insertions(+), 184422 deletions(-) delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core.tests/common/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/common/TmfXmlTestFiles.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core.tests/common/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/common/TmfXmlTestFiles.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/Activator.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/AllAnalysisXmlCoreTests.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/XmlAnalysisCorePluginTest.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/module/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/module/XmlUtilsTest.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/stateprovider/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/stateprovider/StateProviderModuleTest.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/stateprovider/StateProviderTest.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/Activator.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/AllAnalysisXmlCoreTests.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/XmlAnalysisCorePluginTest.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/module/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/module/XmlUtilsTest.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/stateprovider/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/stateprovider/StateProviderModuleTest.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/stateprovider/StateProviderTest.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/Activator.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlModelFactory.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlStateAttribute.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlStateValue.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlCondition.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlEventHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlLocation.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateAttribute.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateChange.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateValue.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyModelFactory.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyStateAttribute.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyStateValue.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteModelFactory.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteStateAttribute.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteStateValue.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/ITmfXmlTopLevelElement.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/IXmlStateSystemContainer.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/XmlUtils.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/xmlCommon.xsd delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/xmlDefinition.xsd delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/xmlStateProvider.xsd delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/xmlView.xsd delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/TmfXmlStrings.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/XmlStateProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/XmlStateSystemModule.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/Activator.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/ITmfXmlModelFactory.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/ITmfXmlStateAttribute.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/ITmfXmlStateValue.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlCondition.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlEventHandler.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlLocation.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlStateAttribute.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlStateChange.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlStateValue.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyModelFactory.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyStateAttribute.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyStateValue.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteModelFactory.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteStateAttribute.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteStateValue.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/ITmfXmlTopLevelElement.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/IXmlStateSystemContainer.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/XmlUtils.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/xmlCommon.xsd create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/xmlDefinition.xsd create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/xmlStateProvider.xsd create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/xmlView.xsd create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/stateprovider/TmfXmlStrings.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/stateprovider/XmlStateProvider.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/stateprovider/XmlStateSystemModule.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/Activator.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/AllAnalysisXmlUiTests.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/XmlAnalysisUiPluginTest.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/module/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/module/XmlAnalysisModuleSourceTest.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/Activator.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/AllAnalysisXmlUiTests.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/XmlAnalysisUiPluginTest.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/module/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/module/XmlAnalysisModuleSourceTest.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/Activator.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/TmfXmlUiStrings.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/handler/ImportXmlHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/XmlViewInfo.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/XmlXYView.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/XmlXYViewer.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/package-info.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/TmfAnalysisModuleHelperXml.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/TmfXmlAnalysisOutputSource.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/TmfXmlViewOutput.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/XmlAnalysisModuleSource.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/XmlEntry.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/XmlPresentationProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/XmlTimeGraphView.java delete mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/Activator.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/TmfXmlUiStrings.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/handler/ImportXmlHandler.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/XmlViewInfo.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/XmlXYView.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/XmlXYViewer.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/package-info.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/TmfAnalysisModuleHelperXml.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/TmfXmlAnalysisOutputSource.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/TmfXmlViewOutput.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/XmlAnalysisModuleSource.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlEntry.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlPresentationProvider.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlTimeGraphView.java create mode 100644 org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/linuxtools/tmf/core/tests/perf/AllPerfTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/linuxtools/tmf/core/tests/perf/synchronization/AllPerfTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/linuxtools/tmf/core/tests/perf/synchronization/TimestampTransformBenchmark.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/tracecompass/tmf/core/tests/perf/AllPerfTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/tracecompass/tmf/core/tests/perf/synchronization/AllPerfTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/tracecompass/tmf/core/tests/perf/synchronization/TimestampTransformBenchmark.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/DebugListener.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/DebugSuite.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/TmfTestHelper.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/TmfTestTrace.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/tracecompass/tmf/core/tests/shared/DebugListener.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/tracecompass/tmf/core/tests/shared/DebugSuite.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/tracecompass/tmf/core/tests/shared/TmfTestHelper.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/tracecompass/tmf/core/tests/shared/TmfTestTrace.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/AllTmfCoreTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/TmfCorePluginTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/TmfCoreTestPlugin.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisManagerTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisModuleHelperTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisModuleTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisParameterProviderTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisRequirementHelperTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisRequirementTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/component/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/component/TmfEventProviderTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/component/TmfProviderManagerTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfEventFieldTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfEventTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfEventTypeManagerTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfEventTypeTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfNanoTimestampTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfSimpleTimestampTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimePreferencesTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimeRangeTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimestampDeltaTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimestampFormatTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimestampTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/lookup/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/lookup/TmfCallsiteTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/filter/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/filter/TmfCollapseFilterTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/request/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/request/TmfCoalescedEventRequestTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/request/TmfEventRequestTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/signal/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/signal/TmfSignalManagerTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/signal/TmfSignalThrottlerTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/ExperimentStateSystemModuleTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/StateSystemAnalysisModuleTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/mipmap/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderStub.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderWeightedTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/SyncTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/TsTransformFactoryTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/TsTransformTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfContextTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfExperimentTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfMultiTraceExperimentTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfTraceTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/AbstractCheckpointCollectionTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/AllBench.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/BTreeTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/FlatArrayTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/TmfMemoryIndexTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/AbstractIndexTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfBTreeIndexTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointIndexTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointIndexTest2.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfExperimentCheckpointIndexTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/location/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/location/TmfLocationTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/stub/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/stub/XmlStubTraceTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/text/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/text/TextTraceContextTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/text/TextTraceEventContentTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/text/TextTraceTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/uml2sd/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/uml2sd/TmfAsyncSequenceDiagramEventTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/uml2sd/TmfSyncSequenceDiagramEventTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/util/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/util/PairTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/AllTmfCoreTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/TmfCorePluginTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/TmfCoreTestPlugin.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisManagerTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisModuleHelperTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisModuleTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisParameterProviderTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisRequirementHelperTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisRequirementTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/component/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/component/TmfEventProviderTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/component/TmfProviderManagerTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventFieldTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventTypeManagerTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventTypeTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfNanoTimestampTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfSimpleTimestampTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimePreferencesTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimeRangeTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimestampDeltaTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimestampFormatTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimestampTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/lookup/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/lookup/TmfCallsiteTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/filter/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/filter/TmfCollapseFilterTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/request/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/request/TmfCoalescedEventRequestTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/request/TmfEventRequestTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/signal/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/signal/TmfSignalManagerTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/signal/TmfSignalThrottlerTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/ExperimentStateSystemModuleTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/StateSystemAnalysisModuleTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/mipmap/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderStub.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderWeightedTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/synchronization/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/synchronization/SyncTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/synchronization/TsTransformFactoryTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/synchronization/TsTransformTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/TmfContextTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/TmfExperimentTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/TmfMultiTraceExperimentTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/TmfTraceTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/AbstractCheckpointCollectionTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/AllBench.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/BTreeTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/FlatArrayTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/TmfMemoryIndexTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/AbstractIndexTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfBTreeIndexTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointIndexTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointIndexTest2.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfExperimentCheckpointIndexTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/location/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/location/TmfLocationTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/stub/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/stub/XmlStubTraceTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/text/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/text/TextTraceContextTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/text/TextTraceEventContentTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/text/TextTraceTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/uml2sd/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/uml2sd/TmfAsyncSequenceDiagramEventTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/uml2sd/TmfSyncSequenceDiagramEventTest.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/util/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/util/PairTest.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/CreateTestFiles.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/AnalysisModuleSourceStub.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/AnalysisModuleTestHelper.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/AnalysisRequirementFactory.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestAnalysis.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestAnalysis2.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestAnalysisParameterProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestExperimentAnalysis.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestRequirementAnalysis.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestStateSystemModule.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestStateSystemProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/component/TmfClientStub.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/component/TmfEventProviderStub.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/component/TmfSyntheticEventProviderStub.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/event/TmfEventTypeStub.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/event/TmfSyncEventStub.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/event/TmfSyntheticEventStub.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/request/TmfEventRequestStub.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfEmptyTraceStub.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfEventParserStub.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfExperimentStub.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfIndexerStub.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfTraceStub.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfTraceStub2.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfTraceStub3.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/text/SyslogEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/text/SyslogEventType.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/text/SyslogTrace.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xml delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xsd delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlTraceStub.java delete mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/CreateTestFiles.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/AnalysisModuleSourceStub.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/AnalysisModuleTestHelper.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/AnalysisRequirementFactory.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestAnalysis.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestAnalysis2.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestAnalysisParameterProvider.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestExperimentAnalysis.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestRequirementAnalysis.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestStateSystemModule.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestStateSystemProvider.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/component/TmfClientStub.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/component/TmfEventProviderStub.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/component/TmfSyntheticEventProviderStub.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/event/TmfEventTypeStub.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/event/TmfSyncEventStub.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/event/TmfSyntheticEventStub.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/request/TmfEventRequestStub.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfEmptyTraceStub.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfEventParserStub.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfExperimentStub.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfIndexerStub.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfTraceStub.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfTraceStub2.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfTraceStub3.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/text/SyslogEvent.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/text/SyslogEventType.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/text/SyslogTrace.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xml create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xsd create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/TmfXmlTraceStub.java create mode 100644 org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/Activator.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/TmfCorePreferenceInitializer.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/TmfCoreTracer.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/analysis/TmfAnalysisModuleSourceConfigElement.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/analysis/TmfAnalysisModuleSources.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/component/TmfEventThread.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/component/TmfProviderManager.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/filter/TmfCollapseFilter.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/request/TmfCoalescedEventRequest.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/request/TmfRequestExecutor.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/backends/partial/PartialHistoryBackend.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/backends/partial/PartialStateSystem.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/AbstractTmfMipmapStateProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/AvgMipmapFeature.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/ITmfMipmapFeature.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/MaxMipmapFeature.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/MinMipmapFeature.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/TmfMipmapFeature.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/TmfStateSystemOperations.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/ITmfTimestampTransformInvertible.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/TmfConstantTransform.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/TmfTimestampTransform.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/TmfTimestampTransformLinear.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/graph/Edge.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/graph/SyncGraph.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/graph/SyncSpanningTree.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/TmfExperimentCheckpoint.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/TmfExperimentContext.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/TmfExperimentLocation.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/TmfLocationArray.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/AbstractFileCheckpointCollection.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/BTree.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/BTreeCheckpointVisitor.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/BTreeNode.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/BTreeNodeCache.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/FlatArray.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/IBTreeVisitor.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/ICheckpointCollection.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/TmfMemoryIndex.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/TmfCommonConstants.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/TmfProjectNature.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisModule.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisModuleHelper.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisModuleSource.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisOutput.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisParameterProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisRequirementProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/ITmfNewAnalysisModuleListener.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAbstractAnalysisModule.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAbstractAnalysisParamProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisManager.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisModuleHelperConfigElement.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisModuleOutputs.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisRequirement.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisRequirementHelper.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfNewAnalysisOutputListener.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/callstack/CallStackStateProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/callstack/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/callstack/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/ITmfComponent.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/ITmfEventProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/TmfComponent.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/TmfEventProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfCustomAttributes.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfEventField.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfEventType.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfLostEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfEventField.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfEventType.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfEventTypeManager.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfLostEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/collapse/ITmfCollapsibleEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/lookup/ITmfCallsite.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/lookup/ITmfModelLookup.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/lookup/ITmfSourceLookup.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/lookup/TmfCallsite.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/IMatchProcessingUnit.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfEventMatching.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfMatchEventDefinition.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfNetworkMatchDefinition.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventDependency.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventMatches.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventMatching.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfNetworkEventMatching.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/exceptions/TmfAnalysisException.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/exceptions/TmfTraceException.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/ITmfFilter.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/ITmfFilterTreeNode.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterAndNode.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterCompareNode.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterContainsNode.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterEqualsNode.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterEventTypeNode.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterMatchesNode.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterNode.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterOrNode.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterRootNode.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterTreeNode.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/xml/TmfFilterContentHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/xml/TmfFilterXMLParser.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/xml/TmfFilterXMLWriter.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/io/BufferedRandomAccessFile.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomEventContent.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomEventType.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTraceDefinition.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtEventType.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtTrace.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtTraceContext.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtTraceDefinition.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlEventType.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlTrace.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlTraceContext.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlTraceDefinition.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/project/model/TmfTraceImportException.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/project/model/TmfTraceType.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/project/model/TraceTypeHelper.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/project/model/TraceValidationHelper.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/request/ITmfEventRequest.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/request/TmfEventRequest.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfEndSynchSignal.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfEventFilterAppliedSignal.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfEventSearchAppliedSignal.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfEventSelectedSignal.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfRangeSynchSignal.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignal.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignalHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignalManager.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignalThrottler.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignalTracer.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfStartAnalysisSignal.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfStartSynchSignal.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTimeSynchSignal.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTimestampFormatUpdateSignal.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceClosedSignal.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceOpenedSignal.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceRangeUpdatedSignal.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceSelectedSignal.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceSynchronizedSignal.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceUpdatedSignal.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/AbstractTmfStateProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/ITmfAnalysisModuleWithStateSystems.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/ITmfStateProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/TmfStateSystemAnalysisModule.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/ITmfStatistics.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfEventsStatistics.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfStateStatistics.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfStatisticsEventTypesModule.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfStatisticsModule.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfStatisticsTotalsModule.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/ITmfTimestampTransform.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationAlgorithm.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationAlgorithmFactory.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationBackend.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationManager.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TimestampTransformFactory.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TmfTimestampTransform.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TmfTimestampTransformLinear.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/ITmfTimePreferencesConstants.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/ITmfTimestamp.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfNanoTimestamp.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfSimpleTimestamp.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimePreferences.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimeRange.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestamp.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestampDelta.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestampFormat.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfContext.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfEventParser.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTrace.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTraceCompleteness.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTraceProperties.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTraceWithPreDefinedEvents.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfContext.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfEventTypeCollectionHelper.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfExperiment.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTrace.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTraceContext.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTraceManager.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TraceValidationStatus.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/ITmfPersistentlyIndexable.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/ITmfTraceIndexer.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/TmfBTreeTraceIndex.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/TmfBTreeTraceIndexer.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/TmfFlatArrayTraceIndex.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/TmfFlatArrayTraceIndexer.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/checkpoint/ITmfCheckpoint.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/checkpoint/ITmfCheckpointIndex.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/checkpoint/TmfCheckpoint.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/checkpoint/TmfCheckpointIndexer.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/location/ITmfLocation.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/location/TmfLocation.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/location/TmfLongLocation.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/location/TmfTimestampLocation.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTrace.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTraceContext.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTraceEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTraceEventContent.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/uml2sd/ITmfAsyncSequenceDiagramEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/uml2sd/ITmfSyncSequenceDiagramEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/uml2sd/TmfAsyncSequenceDiagramEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/uml2sd/TmfSyncSequenceDiagramEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/util/Pair.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/Activator.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/TmfCorePreferenceInitializer.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/TmfCoreTracer.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/analysis/TmfAnalysisModuleSourceConfigElement.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/analysis/TmfAnalysisModuleSources.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/component/TmfEventThread.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/component/TmfProviderManager.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/filter/TmfCollapseFilter.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/request/TmfCoalescedEventRequest.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/request/TmfRequestExecutor.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/backends/partial/PartialHistoryBackend.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/backends/partial/PartialStateSystem.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/AbstractTmfMipmapStateProvider.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/AvgMipmapFeature.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/ITmfMipmapFeature.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/MaxMipmapFeature.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/MinMipmapFeature.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/TmfMipmapFeature.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/TmfStateSystemOperations.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/ITmfTimestampTransformInvertible.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/TmfConstantTransform.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/TmfTimestampTransform.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/TmfTimestampTransformLinear.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/graph/Edge.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/graph/SyncGraph.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/graph/SyncSpanningTree.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/TmfExperimentCheckpoint.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/TmfExperimentContext.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/TmfExperimentLocation.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/TmfLocationArray.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/AbstractFileCheckpointCollection.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/BTree.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/BTreeCheckpointVisitor.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/BTreeNode.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/BTreeNodeCache.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/FlatArray.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/IBTreeVisitor.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/ICheckpointCollection.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/TmfMemoryIndex.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/TmfCommonConstants.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/TmfProjectNature.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisModule.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisModuleHelper.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisModuleSource.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisOutput.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisParameterProvider.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisRequirementProvider.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/ITmfNewAnalysisModuleListener.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAbstractAnalysisModule.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAbstractAnalysisParamProvider.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisManager.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisModuleHelperConfigElement.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisModuleOutputs.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisRequirement.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisRequirementHelper.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfNewAnalysisOutputListener.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/callstack/CallStackStateProvider.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/callstack/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/callstack/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/ITmfComponent.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/ITmfEventProvider.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/TmfComponent.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/TmfEventProvider.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfCustomAttributes.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfEvent.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfEventField.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfEventType.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfLostEvent.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfEvent.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfEventField.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfEventType.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfEventTypeManager.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfLostEvent.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/collapse/ITmfCollapsibleEvent.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/lookup/ITmfCallsite.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/lookup/ITmfModelLookup.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/lookup/ITmfSourceLookup.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/lookup/TmfCallsite.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/IMatchProcessingUnit.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/ITmfEventMatching.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/ITmfMatchEventDefinition.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/ITmfNetworkMatchDefinition.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/TmfEventDependency.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/TmfEventMatches.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/TmfEventMatching.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/TmfNetworkEventMatching.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/exceptions/TmfAnalysisException.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/exceptions/TmfTraceException.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/ITmfFilter.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/ITmfFilterTreeNode.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterAndNode.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterCompareNode.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterContainsNode.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterEqualsNode.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterEventTypeNode.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterMatchesNode.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterNode.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterOrNode.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterRootNode.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterTreeNode.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/xml/TmfFilterContentHandler.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/xml/TmfFilterXMLParser.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/xml/TmfFilterXMLWriter.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/io/BufferedRandomAccessFile.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomEvent.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomEventContent.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomEventType.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTraceDefinition.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtEvent.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtEventType.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtTrace.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtTraceContext.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtTraceDefinition.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlEvent.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlEventType.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlTrace.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlTraceContext.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlTraceDefinition.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/project/model/TmfTraceImportException.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/project/model/TmfTraceType.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/project/model/TraceTypeHelper.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/project/model/TraceValidationHelper.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/request/ITmfEventRequest.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/request/TmfEventRequest.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfEndSynchSignal.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfEventFilterAppliedSignal.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfEventSearchAppliedSignal.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfEventSelectedSignal.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfRangeSynchSignal.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignal.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignalHandler.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignalManager.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignalThrottler.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignalTracer.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfStartAnalysisSignal.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfStartSynchSignal.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTimeSynchSignal.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTimestampFormatUpdateSignal.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceClosedSignal.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceOpenedSignal.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceRangeUpdatedSignal.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceSelectedSignal.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceSynchronizedSignal.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceUpdatedSignal.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statesystem/AbstractTmfStateProvider.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statesystem/ITmfAnalysisModuleWithStateSystems.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statesystem/ITmfStateProvider.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statesystem/TmfStateSystemAnalysisModule.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/ITmfStatistics.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfEventsStatistics.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStateStatistics.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStatisticsEventTypesModule.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStatisticsModule.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStatisticsTotalsModule.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/ITmfTimestampTransform.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SynchronizationAlgorithm.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SynchronizationAlgorithmFactory.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SynchronizationBackend.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SynchronizationManager.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/TimestampTransformFactory.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/TmfTimestampTransform.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/TmfTimestampTransformLinear.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/ITmfTimePreferencesConstants.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/ITmfTimestamp.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfNanoTimestamp.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfSimpleTimestamp.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimePreferences.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimeRange.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimestamp.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimestampDelta.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimestampFormat.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfContext.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfEventParser.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTrace.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTraceCompleteness.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTraceProperties.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTraceWithPreDefinedEvents.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfContext.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfEventTypeCollectionHelper.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfExperiment.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTrace.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTraceContext.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTraceManager.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TraceValidationStatus.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/ITmfPersistentlyIndexable.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/ITmfTraceIndexer.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/TmfBTreeTraceIndex.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/TmfBTreeTraceIndexer.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/TmfFlatArrayTraceIndex.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/TmfFlatArrayTraceIndexer.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/checkpoint/ITmfCheckpoint.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/checkpoint/ITmfCheckpointIndex.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/checkpoint/TmfCheckpoint.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/checkpoint/TmfCheckpointIndexer.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/location/ITmfLocation.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/location/TmfLocation.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/location/TmfLongLocation.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/location/TmfTimestampLocation.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/text/TextTrace.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/text/TextTraceContext.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/text/TextTraceEvent.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/text/TextTraceEventContent.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/uml2sd/ITmfAsyncSequenceDiagramEvent.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/uml2sd/ITmfSyncSequenceDiagramEvent.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/uml2sd/TmfAsyncSequenceDiagramEvent.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/uml2sd/TmfSyncSequenceDiagramEvent.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/util/Pair.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/linuxtools/tmf/ctf/core/tests/perf/AllPerfTests.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/linuxtools/tmf/ctf/core/tests/perf/experiment/AllPerfTests.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/linuxtools/tmf/ctf/core/tests/perf/experiment/ExperimentBenchmark.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/tracecompass/tmf/ctf/core/tests/perf/AllPerfTests.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/tracecompass/tmf/ctf/core/tests/perf/experiment/AllPerfTests.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/tracecompass/tmf/ctf/core/tests/perf/experiment/ExperimentBenchmark.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/shared/org/eclipse/linuxtools/tmf/ctf/core/tests/shared/CtfTmfTestTrace.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/shared/org/eclipse/tracecompass/tmf/ctf/core/tests/shared/CtfTmfTestTrace.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfIteratorTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfLocationDataTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfLocationTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfContextTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfEventFieldTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfEventTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfEventTypeTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfLostEventStatisticsTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfLostEventsTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfTimestampTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfTraceTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/EventContextTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/FunkyTraceTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/headless/Benchmark.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/headless/RequestBenchmark.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/request/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/request/TmfSchedulerBenchmark.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/request/TmfSchedulerTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/statistics/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/statistics/TmfEventsStatisticsTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/statistics/TmfStateStatisticsTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/statistics/TmfStatisticsTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/tracemanager/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/tracemanager/TmfTraceManagerTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfIteratorTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfLocationDataTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfLocationTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfContextTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfEventFieldTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfEventTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfEventTypeTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfLostEventStatisticsTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfLostEventsTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfTimestampTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfTraceTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/EventContextTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/FunkyTraceTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/headless/Benchmark.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/headless/RequestBenchmark.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/request/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/request/TmfSchedulerBenchmark.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/request/TmfSchedulerTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/statistics/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/statistics/TmfEventsStatisticsTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/statistics/TmfStateStatisticsTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/statistics/TmfStatisticsTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/tracemanager/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/tracemanager/TmfTraceManagerTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/stubs/org/eclipse/linuxtools/tmf/ctf/core/tests/stubs/CtfTmfTraceStub.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core.tests/stubs/org/eclipse/tracecompass/tmf/ctf/core/tests/stubs/CtfTmfTraceStub.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/internal/tmf/ctf/core/Activator.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfConstants.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfEnumPair.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfIterator.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfIteratorManager.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfLocation.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfLocationInfo.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfCallsite.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfContext.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfEventFactory.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfEventField.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfEventType.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfLostEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfTimestamp.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfTrace.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/internal/tmf/ctf/core/Activator.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfConstants.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfEnumPair.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfIterator.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfIteratorManager.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfLocation.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfLocationInfo.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfCallsite.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfContext.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfEvent.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfEventFactory.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfEventField.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfEventType.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfLostEvent.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfTimestamp.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfTrace.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ctf/ui/swtbot/tests/AbstractImportAndReadSmokeTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ctf/ui/swtbot/tests/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ctf/ui/swtbot/tests/ImportAndReadSmokeTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ctf/ui/swtbot/tests/StandardImportAndReadSmokeTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/AbstractImportAndReadSmokeTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/ImportAndReadSmokeTest.java create mode 100644 org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/StandardImportAndReadSmokeTest.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/shared/org/eclipse/linuxtools/tmf/pcap/core/tests/shared/PcapTmfTestTrace.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/shared/org/eclipse/tracecompass/tmf/pcap/core/tests/shared/PcapTmfTestTrace.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/AllTmfPcapCoreTests.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/analysis/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/analysis/StreamListAnalysisTest.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/event/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/event/PcapEventFieldTest.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/event/PcapEventTest.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/trace/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/trace/PcapTraceTest.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/AllTmfPcapCoreTests.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/analysis/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/analysis/StreamListAnalysisTest.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/event/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/event/PcapEventFieldTest.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/event/PcapEventTest.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/trace/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/trace/PcapTraceTest.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/stubs/org/eclipse/linuxtools/tmf/pcap/core/tests/stubs/PcapTmfTraceStub.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core.tests/stubs/org/eclipse/tracecompass/tmf/pcap/core/tests/stubs/PcapTmfTraceStub.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/Activator.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/analysis/StreamListAnalysis.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/analysis/package-info.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/PcapEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/PcapEventField.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/PcapEventType.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/PcapRootEventField.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/TmfPacketStream.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/TmfPacketStreamBuilder.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/package-info.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/package-info.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/protocol/TmfPcapProtocol.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/protocol/package-info.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/signal/TmfPacketStreamSelectedSignal.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/signal/package-info.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/trace/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/trace/PcapTrace.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/trace/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/trace/package-info.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/PcapEventFactory.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/ProtocolConversion.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/package-info.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/Activator.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/analysis/StreamListAnalysis.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/analysis/package-info.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/PcapEvent.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/PcapEventField.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/PcapEventType.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/PcapRootEventField.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/TmfPacketStream.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/TmfPacketStreamBuilder.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/package-info.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/package-info.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/protocol/TmfPcapProtocol.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/protocol/package-info.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/signal/TmfPacketStreamSelectedSignal.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/signal/package-info.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/trace/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/trace/PcapTrace.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/trace/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/trace/package-info.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/PcapEventFactory.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/ProtocolConversion.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/package-info.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/pcap/ui/swtbot/tests/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/pcap/ui/swtbot/tests/ImportAndReadPcapTest.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/pcap/ui/swtbot/tests/NetworkPerspectiveChecker.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/pcap/ui/swtbot/tests/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/pcap/ui/swtbot/tests/ImportAndReadPcapTest.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/pcap/ui/swtbot/tests/NetworkPerspectiveChecker.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/Activator.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/NetworkingPerspectiveFactory.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/editor/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/editor/PcapEventTableColumns.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/editor/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/editor/package-info.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/package-info.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/stream/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/stream/StreamListView.java delete mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/stream/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/stream/package-info.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/Activator.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/NetworkingPerspectiveFactory.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/PcapEventTableColumns.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/package-info.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/package-info.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/stream/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/stream/StreamListView.java create mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/stream/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/stream/package-info.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/AbstractCustomParserWizard.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/AbstractPerspectiveChecker.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/AllTmfUISWTBotTests.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/SWTBotUtil.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/TestCustomTxtWizard.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/TestCustomXmlWizard.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/TracingPerspectiveChecker.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/ConditionHelpers.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/TableCellFilled.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/TreeItemNodeAvailable.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/TreeNodeAvailable.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/ViewClosed.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/WizardOnPage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/WizardReady.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/table/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/table/CollapseEventsInTableTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/AbstractCustomParserWizard.java create mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/AbstractPerspectiveChecker.java create mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/AllTmfUISWTBotTests.java create mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/SWTBotUtil.java create mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/TestCustomTxtWizard.java create mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/TestCustomXmlWizard.java create mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/TracingPerspectiveChecker.java create mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/ConditionHelpers.java create mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/TableCellFilled.java create mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/TreeItemNodeAvailable.java create mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/TreeNodeAvailable.java create mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/ViewClosed.java create mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/WizardOnPage.java create mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/WizardReady.java create mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/table/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/table/CollapseEventsInTableTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/shared/org/eclipse/linuxtools/tmf/ui/tests/shared/ProjectModelTestData.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/shared/org/eclipse/tracecompass/tmf/ui/tests/shared/ProjectModelTestData.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/AllTmfUITests.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/TmfUITestPlugin.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/histogram/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/histogram/HistogramDataModelTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelAnalysisTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelOutputTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelTraceTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/TraceAndExperimentTypeTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfBaseColumnDataProviderTest.java delete mode 100755 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfBaseColumnDataTest.java delete mode 100755 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfBaseStatisticsDataTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfStatisticsTest.java delete mode 100755 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfStatisticsTreeManagerTest.java delete mode 100755 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfStatisticsTreeNodeTest.java delete mode 100755 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfTreeContentProviderTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/AbstractCustomTraceIndexTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomTxtIndexTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlIndexTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlTraceBadlyFormedTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlTraceInvalidTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlTraceTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlTraceValidTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/dialogs/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/dialogs/CriteriaTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/load/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/load/LoadersManagerTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/AllTests.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/IUml2SDTestConstants.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/IUml2SdSignalValidator.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderExpTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderFilterTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderFindTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderPagesTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderSignalTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderTimeTest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/Uml2SDSignalValidator.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestFacility.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestSetup.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestTimestamp.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/AllTmfUITests.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/TmfUITestPlugin.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/histogram/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/histogram/HistogramDataModelTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/ProjectModelAnalysisTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/ProjectModelOutputTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/ProjectModelTraceTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/TraceAndExperimentTypeTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfBaseColumnDataProviderTest.java create mode 100755 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfBaseColumnDataTest.java create mode 100755 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfBaseStatisticsDataTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfStatisticsTest.java create mode 100755 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfStatisticsTreeManagerTest.java create mode 100755 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfStatisticsTreeNodeTest.java create mode 100755 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfTreeContentProviderTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/AbstractCustomTraceIndexTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomTxtIndexTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlIndexTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlTraceBadlyFormedTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlTraceInvalidTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlTraceTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlTraceValidTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/dialogs/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/dialogs/CriteriaTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/load/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/load/LoadersManagerTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/AllTests.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/IUml2SDTestConstants.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/IUml2SdSignalValidator.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderExpTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderFilterTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderFindTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderPagesTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderSignalTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderTimeTest.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/Uml2SDSignalValidator.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestFacility.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestSetup.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestTimestamp.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/experiment/type/TmfEventsEditorStub.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/stubs/analysis/TestAnalysisUi.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/uml2sd/load/TestLoaders.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/uml2sd/trace/TmfUml2SDTestTrace.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/adaption/TsfImplProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/model/EventImpl.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/model/TraceImpl.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/model/TraceModelImplFactory.java delete mode 100644 org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/views/TsfTraceAnalysisView.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/tests/experiment/type/TmfEventsEditorStub.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/tests/stubs/analysis/TestAnalysisUi.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/tests/uml2sd/load/TestLoaders.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/tests/uml2sd/trace/TmfUml2SDTestTrace.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/adaption/TsfImplProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/model/EventImpl.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/model/TraceImpl.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/model/TraceModelImplFactory.java create mode 100644 org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/views/TsfTraceAnalysisView.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/.settings/.api_filters delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/Activator.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/ITmfImageConstants.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/TmfUiTracer.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/ExportToTextCommandHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/ExportToTextJob.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/ExportToTextRequest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/ManageCustomParsersCommandHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/OpenFileHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/TmfHandlerUtil.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/dialogs/ManageCustomParsersDialog.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/dialogs/MultiLineInputDialog.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/editors/handlers/AddBookmarkHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/custom/CustomEventTableColumns.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomTxtParserInputWizardPage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomTxtParserOutputWizardPage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomTxtParserWizard.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomXmlParserInputWizardPage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomXmlParserOutputWizardPage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomXmlParserWizard.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/preferences/TmfTracingPreferencePage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/SelectSupplementaryResourcesDialog.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/offset/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/offset/OffsetDialog.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/offset/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/BatchImportTraceHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/ClearTraceOffsetHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/CopyExperimentHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/CopyTraceHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/DeleteExperimentHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/DeleteTraceFolderElementHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/DeleteTraceSupplementaryFilesHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/DropAdapterAssistant.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/ImportTraceHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/NewExperimentHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/NewFolderHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OffsetTraceHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAction.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAnalysisHelpHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAnalysisOutputHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenExperimentHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenTraceHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/RefreshHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/RenameExperimentHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/RenameFolderHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/RenameTraceHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SelectElementTypeContributionItem.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SelectTraceTypeHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SelectTracesHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SynchronizeTracesHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/TmfActionProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/TracePropertyTester.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/model/TmfEditorLinkHelper.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/model/TmfImportHelper.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/operations/TmfWorkspaceModifyOperation.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/AbstractImportTraceWizardPage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/BatchImportTraceWizard.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/FileAndName.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceContentProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceLabelProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizard.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardPage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardPageOptions.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardScanPage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardSelectDirectoriesPage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardSelectTraceTypePage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ResourceTreeAndListGroup.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/TraceTypeContentProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/AbstractTracePackageOperation.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/AbstractTracePackageWizardPage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/ITracePackageConstants.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageBookmarkElement.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageContentProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageElement.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageFilesElement.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageLabelProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageSupplFileElement.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageSupplFilesElement.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageTraceElement.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageSelectTraceWizardPage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageWizard.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageWizardPage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageWizard.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageWizardPage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ManifestReader.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageExportOperation.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageExtractManifestOperation.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageImportOperation.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfContentsColumn.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfReferenceColumn.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfSourceColumn.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfTimestampColumn.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfTypeColumn.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/TmfUiRefreshHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/analysis/TmfAnalysisViewOutput.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/ITmfTraceEditor.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/TmfEditor.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/TmfEditorInput.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/TmfEventsEditor.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/TmfMultiPageEditorPart.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/UnsortedPropertySheetPage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/ITmfProjectModelElement.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/ITmfStyledProjectModelElement.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfAnalysisElement.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfAnalysisOutputElement.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfCommonProjectElement.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfExperimentElement.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfExperimentFolder.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfNavigatorContentProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfNavigatorLabelProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfOpenTraceHelper.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfProjectElement.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfProjectModelElement.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfProjectRegistry.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfTraceElement.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfTraceFolder.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfTraceTypeUIUtils.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfTracesFolder.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfViewerSorter.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TraceFolderContentProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TraceFolderLabelProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TraceUtils.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/CopyExperimentDialog.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/CopyTraceDialog.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/NewExperimentDialog.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/NewFolderDialog.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/NewTmfProjectMainWizardPage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/NewTmfProjectWizard.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/RenameExperimentDialog.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/RenameFolderDialog.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/RenameTraceDialog.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/SelectTracesWizard.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/SelectTracesWizardPage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/properties/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/properties/ReadOnlyTextPropertyDescriptor.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/properties/TmfTimestampFormatPage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/properties/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/ArrayTreeContentProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/ITmfTimeProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/ITmfViewer.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/TmfTimeViewer.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/TmfViewer.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventAdapterFactory.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventPropertySource.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventsCache.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventsTable.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/columns/ITmfEventTableColumns.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/columns/TmfEventTableColumn.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/columns/TmfEventTableFieldColumn.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/text/TmfTextEventTable.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/TmfStatisticsViewer.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/messages.properties delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/Messages.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfBaseColumnData.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfBaseColumnDataProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsFormatter.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsTree.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsTreeManager.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsTreeNode.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsValues.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfTreeContentProvider.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/AbstractTmfTreeViewer.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/ITmfTreeColumnDataProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/ITmfTreeViewerEntry.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/TmfTreeColumnData.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/TmfTreeViewerEntry.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/ITmfChartTimeProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfBaseProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfChartTimeStampFormat.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfMouseDragProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfMouseDragZoomProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfMouseSelectionProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfMouseWheelZoomProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfSimpleTooltipProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfXYChartViewer.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/barcharts/TmfBarChartViewer.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/barcharts/TmfHistogramTooltipProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/linecharts/TmfCommonXLineChartTooltipProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/linecharts/TmfCommonXLineChartViewer.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/PinTmfViewAction.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/TmfChartView.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/TmfView.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/TracingPerspectiveFactory.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/AbstractCallStackAnalysis.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackEntry.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackPresentationProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackView.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/FunctionNameMapper.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/ColorSetting.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/ColorSettingsManager.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/ColorSettingsXML.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/ColorsView.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/IColorSettingsListener.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/distribution/model/BaseDistributionData.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/distribution/model/IBaseDistributionModel.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/CopyHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/CutHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/DeleteHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterDialog.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterDragSourceAdapter.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterDropTargetAdapter.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterEditUtils.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterManager.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterTreeContentProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterTreeLabelProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterView.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterViewer.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/PasteHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/FullTraceHistogram.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/Histogram.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramBucket.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramCurrentTimeControl.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramDataModel.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramRequest.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramScaledData.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramSelectionEndControl.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramSelectionStartControl.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramTextControl.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramTimeRangeControl.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramView.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramZoom.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/IHistogramDataModel.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/IHistogramModelListener.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/TimeRangeHistogram.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statesystem/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statesystem/TmfStateSystemExplorer.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statesystem/TmfStateSystemViewer.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statesystem/messages.properties delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statistics/Messages.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statistics/TmfStatisticsView.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statistics/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/TmfSynchronizationView.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartAnalysisEntry.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartAnalysisProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartDecorationProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartView.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/AbstractTimeGraphView.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/messages.properties delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/DiagramToolTip.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/DrawableToolTip.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/ITimeCompressionListener.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/NGC.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/SDView.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/SDWidget.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/SDWidgetSelectionProvider.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/ScrollView.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/TimeCompressionBar.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/AsyncMessage.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/AsyncMessageReturn.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/BaseMessage.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/BasicExecutionOccurrence.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/BasicFrame.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/EllipsisMessage.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/ExecutionOccurrence.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/Frame.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/GraphNode.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/HotSpot.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/ITimeRange.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/Lifeline.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/LifelineCategories.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/Metrics.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/SDTimeEvent.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/Stop.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/SyncMessage.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/SyncMessageReturn.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/Criteria.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/FilterCriteria.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/FilterListDialog.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/MinMaxDialog.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/PagesDialog.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/SDPrintDialog.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/SDPrintDialogUI.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/SearchFilterDialog.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/TabContents.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/IColor.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/IFont.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/IGC.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/IImage.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/impl/ColorImpl.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/impl/FontImpl.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/impl/ImageImpl.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/BaseSDAction.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/ConfigureMinMax.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/FirstPage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/KeyBindingsManager.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/LastPage.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveSDDown.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveSDLeft.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveSDRight.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveSDUp.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveToMessage.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/NextPage.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/OpenSDFiltersDialog.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/OpenSDFindDialog.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/OpenSDPagesDialog.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/PrevPage.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/Print.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/ShowNodeEnd.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/ShowNodeStart.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/Zoom.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/IExtendedFilterProvider.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/IExtendedFindProvider.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDAdvancedPagingProvider.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDCollapseProvider.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDExtendedActionBarProvider.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDFilterProvider.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDFindProvider.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDGraphNodeSupporter.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDPagingProvider.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDPropertiesProvider.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/load/IUml2SDLoader.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/load/LoadersManager.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/Messages.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/TmfAsyncMessage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/TmfSyncMessage.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/TmfUml2SDSyncLoader.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/messages.properties delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/preferences/ISDPreferences.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/preferences/SDViewPref.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/preferences/SDViewerPage.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/Messages.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/SortAsyncForBackward.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/SortAsyncMessageComparator.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/SortSyncMessageComparator.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/TimeEventComparator.java delete mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/messages.properties delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/rawviewer/TmfRawEventViewer.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/tabsview/TmfViewerFolder.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphColorListener.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphContentProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider2.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphRangeListener.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphSelectionListener.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphTimeListener.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphTreeListener.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/StateItem.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphCombo.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphPresentationProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphRangeUpdateEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphSelectionEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphTimeEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphTreeExpansionEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphViewer.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/dialogs/FilteredCheckboxTree.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/dialogs/TimeGraphFilterDialog.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/dialogs/TimeGraphLegend.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/dialogs/TreePatternFilter.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/EventIterator.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ILinkEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ITimeEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ITimeEvent2.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ITimeGraphEntry.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/NullTimeEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeLinkEvent.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/ITimeDataProvider.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/ITimeDataProviderConverter.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/ITmfTimeGraphDrawingHelper.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeDataProviderCyclesConverter.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphBaseControl.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphColorScheme.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphScale.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphSelection.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphTooltipHandler.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/Utils.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/virtualtable/ColumnData.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/virtualtable/IDoubleClickListener.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/virtualtable/TmfVirtualTable.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/virtualtable/TooltipProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/Activator.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/ITmfImageConstants.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/TmfUiTracer.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/ExportToTextCommandHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/ExportToTextJob.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/ExportToTextRequest.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/ManageCustomParsersCommandHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/OpenFileHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/TmfHandlerUtil.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/dialogs/ManageCustomParsersDialog.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/dialogs/MultiLineInputDialog.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/editors/handlers/AddBookmarkHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/custom/CustomEventTableColumns.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomTxtParserInputWizardPage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomTxtParserOutputWizardPage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomTxtParserWizard.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomXmlParserInputWizardPage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomXmlParserOutputWizardPage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomXmlParserWizard.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/preferences/TmfTracingPreferencePage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/SelectSupplementaryResourcesDialog.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/offset/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/offset/OffsetDialog.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/offset/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/BatchImportTraceHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/ClearTraceOffsetHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/CopyExperimentHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/CopyTraceHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/DeleteExperimentHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/DeleteTraceFolderElementHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/DeleteTraceSupplementaryFilesHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/DropAdapterAssistant.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/ImportTraceHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/NewExperimentHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/NewFolderHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OffsetTraceHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenAction.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenAnalysisHelpHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenAnalysisOutputHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenExperimentHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenTraceHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/RefreshHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/RenameExperimentHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/RenameFolderHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/RenameTraceHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/SelectElementTypeContributionItem.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/SelectTraceTypeHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/SelectTracesHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/SynchronizeTracesHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/TmfActionProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/TracePropertyTester.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/model/TmfEditorLinkHelper.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/model/TmfImportHelper.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/operations/TmfWorkspaceModifyOperation.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/AbstractImportTraceWizardPage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/BatchImportTraceWizard.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/FileAndName.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceContentProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceLabelProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizard.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardPage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardPageOptions.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardScanPage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardSelectDirectoriesPage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardSelectTraceTypePage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ResourceTreeAndListGroup.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/TraceTypeContentProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/AbstractTracePackageOperation.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/AbstractTracePackageWizardPage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/ITracePackageConstants.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageBookmarkElement.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageContentProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageElement.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageFilesElement.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageLabelProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageSupplFileElement.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageSupplFilesElement.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageTraceElement.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageSelectTraceWizardPage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageWizard.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageWizardPage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageWizard.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageWizardPage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ManifestReader.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageExportOperation.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageExtractManifestOperation.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageImportOperation.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfContentsColumn.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfReferenceColumn.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfSourceColumn.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfTimestampColumn.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfTypeColumn.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/TmfUiRefreshHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/analysis/TmfAnalysisViewOutput.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/ITmfTraceEditor.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/TmfEditor.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/TmfEditorInput.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/TmfEventsEditor.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/TmfMultiPageEditorPart.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/UnsortedPropertySheetPage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/ITmfProjectModelElement.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/ITmfStyledProjectModelElement.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfAnalysisElement.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfAnalysisOutputElement.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfCommonProjectElement.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfExperimentElement.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfExperimentFolder.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfNavigatorContentProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfNavigatorLabelProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfOpenTraceHelper.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfProjectElement.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfProjectModelElement.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfProjectRegistry.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfTraceElement.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfTraceFolder.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfTraceTypeUIUtils.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfTracesFolder.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfViewerSorter.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TraceFolderContentProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TraceFolderLabelProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TraceUtils.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/CopyExperimentDialog.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/CopyTraceDialog.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/NewExperimentDialog.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/NewFolderDialog.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/NewTmfProjectMainWizardPage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/NewTmfProjectWizard.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/RenameExperimentDialog.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/RenameFolderDialog.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/RenameTraceDialog.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectTracesWizard.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectTracesWizardPage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/properties/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/properties/ReadOnlyTextPropertyDescriptor.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/properties/TmfTimestampFormatPage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/properties/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/ArrayTreeContentProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/ITmfTimeProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/ITmfViewer.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/TmfTimeViewer.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/TmfViewer.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventAdapterFactory.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventPropertySource.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventsCache.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventsTable.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/ITmfEventTableColumns.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/TmfEventTableColumn.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/TmfEventTableFieldColumn.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/text/TmfTextEventTable.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/TmfStatisticsViewer.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/messages.properties create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/Messages.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfBaseColumnData.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfBaseColumnDataProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsFormatter.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsTree.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsTreeManager.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsTreeNode.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsValues.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfTreeContentProvider.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/AbstractTmfTreeViewer.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/ITmfTreeColumnDataProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/ITmfTreeViewerEntry.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/TmfTreeColumnData.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/TmfTreeViewerEntry.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/ITmfChartTimeProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfBaseProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfChartTimeStampFormat.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfMouseDragProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfMouseDragZoomProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfMouseSelectionProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfMouseWheelZoomProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfSimpleTooltipProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfXYChartViewer.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/barcharts/TmfBarChartViewer.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/barcharts/TmfHistogramTooltipProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/linecharts/TmfCommonXLineChartTooltipProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/linecharts/TmfCommonXLineChartViewer.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/PinTmfViewAction.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/TmfChartView.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/TmfView.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/TracingPerspectiveFactory.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/AbstractCallStackAnalysis.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackEntry.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackEvent.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackPresentationProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackView.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/FunctionNameMapper.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/ColorSetting.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/ColorSettingsManager.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/ColorSettingsXML.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/ColorsView.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/IColorSettingsListener.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/distribution/model/BaseDistributionData.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/distribution/model/IBaseDistributionModel.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/CopyHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/CutHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/DeleteHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterDialog.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterDragSourceAdapter.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterDropTargetAdapter.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterEditUtils.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterManager.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterTreeContentProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterTreeLabelProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterView.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterViewer.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/PasteHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/FullTraceHistogram.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/Histogram.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramBucket.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramCurrentTimeControl.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramDataModel.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramRequest.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramScaledData.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramSelectionEndControl.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramSelectionStartControl.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramTextControl.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramTimeRangeControl.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramView.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramZoom.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/IHistogramDataModel.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/IHistogramModelListener.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/TimeRangeHistogram.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statesystem/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statesystem/TmfStateSystemExplorer.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statesystem/TmfStateSystemViewer.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statesystem/messages.properties create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statistics/Messages.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statistics/TmfStatisticsView.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statistics/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/synchronization/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/synchronization/TmfSynchronizationView.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/synchronization/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartAnalysisEntry.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartAnalysisProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartDecorationProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartEvent.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartView.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/AbstractTimeGraphView.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/messages.properties create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/DiagramToolTip.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/DrawableToolTip.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/ITimeCompressionListener.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/NGC.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/SDView.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/SDWidget.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/SDWidgetSelectionProvider.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/ScrollView.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/TimeCompressionBar.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/AsyncMessage.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/AsyncMessageReturn.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/BaseMessage.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/BasicExecutionOccurrence.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/BasicFrame.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/EllipsisMessage.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/ExecutionOccurrence.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/Frame.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/GraphNode.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/HotSpot.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/ITimeRange.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/Lifeline.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/LifelineCategories.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/Metrics.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/SDTimeEvent.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/Stop.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/SyncMessage.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/SyncMessageReturn.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/Criteria.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/FilterCriteria.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/FilterListDialog.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/MinMaxDialog.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/PagesDialog.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/SDPrintDialog.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/SDPrintDialogUI.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/SearchFilterDialog.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/TabContents.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/IColor.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/IFont.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/IGC.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/IImage.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/impl/ColorImpl.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/impl/FontImpl.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/impl/ImageImpl.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/BaseSDAction.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/ConfigureMinMax.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/FirstPage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/KeyBindingsManager.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/LastPage.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveSDDown.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveSDLeft.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveSDRight.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveSDUp.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveToMessage.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/NextPage.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/OpenSDFiltersDialog.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/OpenSDFindDialog.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/OpenSDPagesDialog.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/PrevPage.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/Print.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/ShowNodeEnd.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/ShowNodeStart.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/Zoom.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/IExtendedFilterProvider.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/IExtendedFindProvider.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDAdvancedPagingProvider.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDCollapseProvider.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDExtendedActionBarProvider.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDFilterProvider.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDFindProvider.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDGraphNodeSupporter.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDPagingProvider.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDPropertiesProvider.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/load/IUml2SDLoader.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/load/LoadersManager.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/TmfAsyncMessage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/TmfSyncMessage.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/TmfUml2SDSyncLoader.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/messages.properties create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/preferences/ISDPreferences.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/preferences/SDViewPref.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/preferences/SDViewerPage.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/Messages.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/SortAsyncForBackward.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/SortAsyncMessageComparator.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/SortSyncMessageComparator.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/TimeEventComparator.java create mode 100755 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/rawviewer/TmfRawEventViewer.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/tabsview/TmfViewerFolder.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphColorListener.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphContentProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider2.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphRangeListener.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphSelectionListener.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphTimeListener.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphTreeListener.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/StateItem.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphCombo.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphPresentationProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphRangeUpdateEvent.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphSelectionEvent.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphTimeEvent.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphTreeExpansionEvent.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphViewer.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/dialogs/FilteredCheckboxTree.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/dialogs/TimeGraphFilterDialog.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/dialogs/TimeGraphLegend.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/dialogs/TreePatternFilter.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/EventIterator.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/ILinkEvent.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/ITimeEvent.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/ITimeEvent2.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/ITimeGraphEntry.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/NullTimeEvent.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeEvent.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeLinkEvent.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/ITimeDataProvider.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/ITimeDataProviderConverter.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/ITmfTimeGraphDrawingHelper.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeDataProviderCyclesConverter.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphBaseControl.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphColorScheme.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphScale.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphSelection.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphTooltipHandler.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/Utils.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/virtualtable/ColumnData.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/virtualtable/IDoubleClickListener.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/virtualtable/TmfVirtualTable.java create mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/virtualtable/TooltipProvider.java diff --git a/org.eclipse.tracecompass.alltests/src/org/eclipse/linuxtools/lttng/alltests/RunAllCoreTests.java b/org.eclipse.tracecompass.alltests/src/org/eclipse/linuxtools/lttng/alltests/RunAllCoreTests.java index b35dc7e278..cae11abc33 100644 --- a/org.eclipse.tracecompass.alltests/src/org/eclipse/linuxtools/lttng/alltests/RunAllCoreTests.java +++ b/org.eclipse.tracecompass.alltests/src/org/eclipse/linuxtools/lttng/alltests/RunAllCoreTests.java @@ -29,10 +29,13 @@ import org.junit.runners.Suite; org.eclipse.linuxtools.lttng2.ust.core.tests.AllTests.class, org.eclipse.linuxtools.pcap.core.tests.AllPcapCoreTests.class, org.eclipse.linuxtools.statesystem.core.tests.AllTests.class, - org.eclipse.linuxtools.tmf.analysis.xml.core.tests.AllAnalysisXmlCoreTests.class, - org.eclipse.linuxtools.tmf.core.tests.AllTmfCoreTests.class, - org.eclipse.linuxtools.tmf.ctf.core.tests.AllTests.class, - org.eclipse.linuxtools.tmf.pcap.core.tests.AllTmfPcapCoreTests.class + org.eclipse.tracecompass.tmf.analysis.xml.core.tests.AllAnalysisXmlCoreTests.class, + org.eclipse.tracecompass.tmf.core.tests.AllTmfCoreTests.class, + org.eclipse.tracecompass.tmf.ctf.core.tests.AllTests.class, + org.eclipse.tracecompass.tmf.pcap.core.tests.AllTmfPcapCoreTests.class, + org.eclipse.tracecompass.tmf.analysis.xml.core.tests.AllAnalysisXmlCoreTests.class, + org.eclipse.tracecompass.tmf.ctf.core.tests.AllTests.class, + org.eclipse.tracecompass.tmf.pcap.core.tests.AllTmfPcapCoreTests.class }) public class RunAllCoreTests { diff --git a/org.eclipse.tracecompass.alltests/src/org/eclipse/linuxtools/lttng/alltests/RunAllUITests.java b/org.eclipse.tracecompass.alltests/src/org/eclipse/linuxtools/lttng/alltests/RunAllUITests.java index 56030d33ac..7b8b5386ae 100644 --- a/org.eclipse.tracecompass.alltests/src/org/eclipse/linuxtools/lttng/alltests/RunAllUITests.java +++ b/org.eclipse.tracecompass.alltests/src/org/eclipse/linuxtools/lttng/alltests/RunAllUITests.java @@ -24,8 +24,8 @@ import org.junit.runners.Suite; org.eclipse.linuxtools.lttng2.control.ui.tests.AllTests.class, org.eclipse.linuxtools.lttng2.kernel.ui.tests.AllTests.class, org.eclipse.linuxtools.lttng2.ust.ui.tests.AllTests.class, - org.eclipse.linuxtools.tmf.analysis.xml.ui.tests.AllAnalysisXmlUiTests.class, - org.eclipse.linuxtools.tmf.ui.tests.AllTmfUITests.class, + org.eclipse.tracecompass.tmf.analysis.xml.ui.tests.AllAnalysisXmlUiTests.class, + org.eclipse.tracecompass.tmf.ui.tests.AllTmfUITests.class, }) public class RunAllUITests { diff --git a/org.eclipse.tracecompass.alltests/src/org/eclipse/linuxtools/lttng/alltests/perf/RunAllPerfTests.java b/org.eclipse.tracecompass.alltests/src/org/eclipse/linuxtools/lttng/alltests/perf/RunAllPerfTests.java index 623005644a..56aa716508 100644 --- a/org.eclipse.tracecompass.alltests/src/org/eclipse/linuxtools/lttng/alltests/perf/RunAllPerfTests.java +++ b/org.eclipse.tracecompass.alltests/src/org/eclipse/linuxtools/lttng/alltests/perf/RunAllPerfTests.java @@ -23,8 +23,8 @@ import org.junit.runners.Suite; org.eclipse.linuxtools.ctf.core.tests.perf.AllPerfTests.class, org.eclipse.linuxtools.lttng2.kernel.core.tests.perf.AllPerfTests.class, org.eclipse.linuxtools.pcap.core.tests.perf.AllPerfTests.class, - org.eclipse.linuxtools.tmf.core.tests.perf.AllPerfTests.class, - org.eclipse.linuxtools.tmf.ctf.core.tests.perf.AllPerfTests.class + org.eclipse.tracecompass.tmf.core.tests.perf.AllPerfTests.class, + org.eclipse.tracecompass.tmf.ctf.core.tests.perf.AllPerfTests.class }) public class RunAllPerfTests { diff --git a/org.eclipse.tracecompass.alltests/src/org/eclipse/linuxtools/lttng/alltests/swtbot/RunAllSWTBotTests.java b/org.eclipse.tracecompass.alltests/src/org/eclipse/linuxtools/lttng/alltests/swtbot/RunAllSWTBotTests.java index b94cab57b8..20e3b5a3bb 100644 --- a/org.eclipse.tracecompass.alltests/src/org/eclipse/linuxtools/lttng/alltests/swtbot/RunAllSWTBotTests.java +++ b/org.eclipse.tracecompass.alltests/src/org/eclipse/linuxtools/lttng/alltests/swtbot/RunAllSWTBotTests.java @@ -23,9 +23,9 @@ import org.junit.runners.Suite; */ @RunWith(Suite.class) @Suite.SuiteClasses({ - org.eclipse.linuxtools.tmf.ui.swtbot.tests.AllTmfUISWTBotTests.class, - org.eclipse.linuxtools.tmf.ctf.ui.swtbot.tests.AllTests.class, - org.eclipse.linuxtools.tmf.pcap.ui.swtbot.tests.AllTests.class, + org.eclipse.tracecompass.tmf.ui.swtbot.tests.AllTmfUISWTBotTests.class, + org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests.AllTests.class, + org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests.AllTests.class, org.eclipse.linuxtools.lttng2.kernel.ui.swtbot.tests.AllTests.class }) public class RunAllSWTBotTests { diff --git a/org.eclipse.tracecompass.btf.core.tests/src/org/eclipse/linuxtools/btf/core/tests/trace/BtfTraceTest.java b/org.eclipse.tracecompass.btf.core.tests/src/org/eclipse/linuxtools/btf/core/tests/trace/BtfTraceTest.java index 053843102e..b3d62c9264 100644 --- a/org.eclipse.tracecompass.btf.core.tests/src/org/eclipse/linuxtools/btf/core/tests/trace/BtfTraceTest.java +++ b/org.eclipse.tracecompass.btf.core.tests/src/org/eclipse/linuxtools/btf/core/tests/trace/BtfTraceTest.java @@ -18,9 +18,9 @@ import java.util.Map; import org.eclipse.linuxtools.btf.core.tests.utils.BtfTestTrace; import org.eclipse.linuxtools.btf.core.trace.BtfTrace; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.TraceValidationStatus; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.TraceValidationStatus; import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/org.eclipse.tracecompass.btf.core.tests/src/org/eclipse/linuxtools/btf/core/tests/utils/BtfTestTrace.java b/org.eclipse.tracecompass.btf.core.tests/src/org/eclipse/linuxtools/btf/core/tests/utils/BtfTestTrace.java index c2eea5250b..364dc52fde 100644 --- a/org.eclipse.tracecompass.btf.core.tests/src/org/eclipse/linuxtools/btf/core/tests/utils/BtfTestTrace.java +++ b/org.eclipse.tracecompass.btf.core.tests/src/org/eclipse/linuxtools/btf/core/tests/utils/BtfTestTrace.java @@ -21,8 +21,8 @@ import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.Path; import org.eclipse.linuxtools.btf.core.tests.BtfTestPlugin; import org.eclipse.linuxtools.btf.core.trace.BtfTrace; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; import org.osgi.framework.Bundle; /** diff --git a/org.eclipse.tracecompass.btf.core.tests/src/org/eclipse/linuxtools/btf/core/tests/utils/TestBtfTrace.java b/org.eclipse.tracecompass.btf.core.tests/src/org/eclipse/linuxtools/btf/core/tests/utils/TestBtfTrace.java index e29c206150..f6a89adafc 100644 --- a/org.eclipse.tracecompass.btf.core.tests/src/org/eclipse/linuxtools/btf/core/tests/utils/TestBtfTrace.java +++ b/org.eclipse.tracecompass.btf.core.tests/src/org/eclipse/linuxtools/btf/core/tests/utils/TestBtfTrace.java @@ -15,9 +15,9 @@ package org.eclipse.linuxtools.btf.core.tests.utils; import java.io.IOException; import org.eclipse.linuxtools.btf.core.trace.BtfTrace; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; /** * Helpers for testing the btf trace. There is a main() top run the code without diff --git a/org.eclipse.tracecompass.btf.core/plugin.xml b/org.eclipse.tracecompass.btf.core/plugin.xml index e6d9fb7f24..8996cd5843 100644 --- a/org.eclipse.tracecompass.btf.core/plugin.xml +++ b/org.eclipse.tracecompass.btf.core/plugin.xml @@ -5,7 +5,7 @@ point="org.eclipse.linuxtools.tmf.core.tracetype"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement"> diff --git a/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/linuxtools/internal/gdbtrace/ui/views/GdbPerspectiveFactory.java b/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/linuxtools/internal/gdbtrace/ui/views/GdbPerspectiveFactory.java index 8bff0382d9..ce29ee0c91 100644 --- a/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/linuxtools/internal/gdbtrace/ui/views/GdbPerspectiveFactory.java +++ b/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/linuxtools/internal/gdbtrace/ui/views/GdbPerspectiveFactory.java @@ -15,7 +15,7 @@ package org.eclipse.linuxtools.internal.gdbtrace.ui.views; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.linuxtools.internal.gdbtrace.ui.GdbTraceUIPlugin; -import org.eclipse.linuxtools.tmf.ui.project.wizards.NewTmfProjectWizard; +import org.eclipse.tracecompass.tmf.ui.project.wizards.NewTmfProjectWizard; import org.eclipse.ui.IFolderLayout; import org.eclipse.ui.IPageLayout; import org.eclipse.ui.IPerspectiveFactory; diff --git a/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/linuxtools/internal/gdbtrace/ui/views/events/GdbEventTableColumns.java b/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/linuxtools/internal/gdbtrace/ui/views/events/GdbEventTableColumns.java index 781fc9a9d1..eaa0f86450 100644 --- a/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/linuxtools/internal/gdbtrace/ui/views/events/GdbEventTableColumns.java +++ b/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/linuxtools/internal/gdbtrace/ui/views/events/GdbEventTableColumns.java @@ -16,10 +16,10 @@ import java.util.Collection; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.linuxtools.internal.gdbtrace.core.event.GdbTraceEventContent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.ITmfEventTableColumns; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableFieldColumn; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.ITmfEventTableColumns; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableFieldColumn; import com.google.common.collect.ImmutableList; diff --git a/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/linuxtools/internal/gdbtrace/ui/views/events/GdbEventsTable.java b/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/linuxtools/internal/gdbtrace/ui/views/events/GdbEventsTable.java index 9b79b04779..c456feca85 100644 --- a/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/linuxtools/internal/gdbtrace/ui/views/events/GdbEventsTable.java +++ b/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/linuxtools/internal/gdbtrace/ui/views/events/GdbEventsTable.java @@ -21,15 +21,15 @@ import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.linuxtools.internal.gdbtrace.core.event.GdbTraceEvent; import org.eclipse.linuxtools.internal.gdbtrace.core.event.GdbTraceEventContent; import org.eclipse.linuxtools.internal.gdbtrace.core.trace.GdbTrace; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; -import org.eclipse.linuxtools.tmf.ui.viewers.events.TmfEventsTable; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.TableItem; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceUpdatedSignal; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; +import org.eclipse.tracecompass.tmf.ui.viewers.events.TmfEventsTable; /** * GDB Event Table diff --git a/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/linuxtools/internal/gdbtrace/ui/views/project/handlers/SelectTraceExecutableHandler.java b/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/linuxtools/internal/gdbtrace/ui/views/project/handlers/SelectTraceExecutableHandler.java index 51e63f1ab9..6030a0e008 100644 --- a/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/linuxtools/internal/gdbtrace/ui/views/project/handlers/SelectTraceExecutableHandler.java +++ b/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/linuxtools/internal/gdbtrace/ui/views/project/handlers/SelectTraceExecutableHandler.java @@ -24,9 +24,9 @@ import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.window.Window; import org.eclipse.linuxtools.internal.gdbtrace.core.trace.GdbTrace; import org.eclipse.linuxtools.internal.gdbtrace.ui.views.project.dialogs.SelectTraceExecutableDialog; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.handlers.HandlerUtil; diff --git a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/relayd/LttngRelaydConnectionManager.java b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/relayd/LttngRelaydConnectionManager.java index b71ffa7198..dedd4fa78f 100644 --- a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/relayd/LttngRelaydConnectionManager.java +++ b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/relayd/LttngRelaydConnectionManager.java @@ -21,13 +21,13 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.linuxtools.internal.lttng2.control.ui.Activator; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.CtfConstants; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.CtfConstants; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; import org.eclipse.ui.PlatformUI; /** diff --git a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/relayd/LttngRelaydConsumer.java b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/relayd/LttngRelaydConsumer.java index 47a8e2d8aa..c8427c4ac8 100644 --- a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/relayd/LttngRelaydConsumer.java +++ b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/relayd/LttngRelaydConsumer.java @@ -34,10 +34,10 @@ import org.eclipse.linuxtools.internal.lttng2.control.core.relayd.lttngviewerCom import org.eclipse.linuxtools.internal.lttng2.control.core.relayd.lttngviewerCommands.SessionResponse; import org.eclipse.linuxtools.internal.lttng2.control.core.relayd.lttngviewerCommands.StreamResponse; import org.eclipse.linuxtools.internal.lttng2.control.ui.Activator; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTimestamp; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceRangeUpdatedSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTimestamp; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; /** * Consumer of the relay d. diff --git a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/dialogs/ImportDialog.java b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/dialogs/ImportDialog.java index 70a9f3cc60..6a1fda18a8 100644 --- a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/dialogs/ImportDialog.java +++ b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/dialogs/ImportDialog.java @@ -32,8 +32,6 @@ import org.eclipse.linuxtools.internal.lttng2.control.ui.Activator; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.messages.Messages; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.model.impl.TraceSessionComponent; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.remote.IRemoteSystemProxy; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTracesFolder; -import org.eclipse.linuxtools.tmf.ui.project.model.TraceUtils; import org.eclipse.rse.core.subsystems.RemoteChildrenContentsType; import org.eclipse.rse.services.clientserver.messages.SystemMessageException; import org.eclipse.rse.subsystems.files.core.servicesubsystem.IFileServiceSubSystem; @@ -52,6 +50,8 @@ import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTracesFolder; +import org.eclipse.tracecompass.tmf.ui.project.model.TraceUtils; import org.eclipse.ui.model.WorkbenchContentProvider; import org.eclipse.ui.model.WorkbenchLabelProvider; diff --git a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/dialogs/OpenCommandScriptDialog.java b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/dialogs/OpenCommandScriptDialog.java index 7c1f422577..e775aab8b5 100644 --- a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/dialogs/OpenCommandScriptDialog.java +++ b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/dialogs/OpenCommandScriptDialog.java @@ -25,7 +25,6 @@ import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.linuxtools.internal.lttng2.control.ui.Activator; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.messages.Messages; -import org.eclipse.linuxtools.tmf.core.io.BufferedRandomAccessFile; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; @@ -41,6 +40,7 @@ import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.tmf.core.io.BufferedRandomAccessFile; import com.google.common.collect.ImmutableList; diff --git a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/handlers/ImportHandler.java b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/handlers/ImportHandler.java index 99ea37c732..5d97f2114e 100644 --- a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/handlers/ImportHandler.java +++ b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/handlers/ImportHandler.java @@ -52,24 +52,24 @@ import org.eclipse.linuxtools.internal.lttng2.control.ui.views.dialogs.ImportFil import org.eclipse.linuxtools.internal.lttng2.control.ui.views.dialogs.TraceControlDialogFactory; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.messages.Messages; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.model.impl.TraceSessionComponent; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace.ImportTraceWizard; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceImportException; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; -import org.eclipse.linuxtools.tmf.ctf.core.CtfConstants; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfOpenTraceHelper; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceTypeUIUtils; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTracesFolder; -import org.eclipse.linuxtools.tmf.ui.project.model.TraceUtils; import org.eclipse.rse.services.clientserver.messages.SystemMessageException; import org.eclipse.rse.services.files.IFileService; import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile; import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem; import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace.ImportTraceWizard; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceImportException; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; +import org.eclipse.tracecompass.tmf.ctf.core.CtfConstants; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfOpenTraceHelper; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceTypeUIUtils; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTracesFolder; +import org.eclipse.tracecompass.tmf.ui.project.model.TraceUtils; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; diff --git a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/BaseEventPropertySource.java b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/BaseEventPropertySource.java index 846bc0989b..48c962b546 100644 --- a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/BaseEventPropertySource.java +++ b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/BaseEventPropertySource.java @@ -18,7 +18,7 @@ import java.util.List; import org.eclipse.linuxtools.internal.lttng2.control.core.model.TraceLogLevel; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.messages.Messages; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.model.impl.BaseEventComponent; -import org.eclipse.linuxtools.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; +import org.eclipse.tracecompass.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; import org.eclipse.ui.views.properties.IPropertyDescriptor; /** diff --git a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/KernelProviderPropertySource.java b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/KernelProviderPropertySource.java index 00ae10c824..2ca3a3ee51 100644 --- a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/KernelProviderPropertySource.java +++ b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/KernelProviderPropertySource.java @@ -13,7 +13,7 @@ package org.eclipse.linuxtools.internal.lttng2.control.ui.views.property; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.messages.Messages; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.model.impl.KernelProviderComponent; -import org.eclipse.linuxtools.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; +import org.eclipse.tracecompass.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; import org.eclipse.ui.views.properties.IPropertyDescriptor; /** diff --git a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TargetNodePropertySource.java b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TargetNodePropertySource.java index e552bb919e..f20d676eb6 100644 --- a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TargetNodePropertySource.java +++ b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TargetNodePropertySource.java @@ -13,7 +13,7 @@ package org.eclipse.linuxtools.internal.lttng2.control.ui.views.property; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.messages.Messages; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.model.impl.TargetNodeComponent; -import org.eclipse.linuxtools.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; +import org.eclipse.tracecompass.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; import org.eclipse.ui.views.properties.IPropertyDescriptor; /** diff --git a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceChannelPropertySource.java b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceChannelPropertySource.java index 790a6dd01e..f3fb842045 100644 --- a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceChannelPropertySource.java +++ b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceChannelPropertySource.java @@ -13,7 +13,7 @@ package org.eclipse.linuxtools.internal.lttng2.control.ui.views.property; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.messages.Messages; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.model.impl.TraceChannelComponent; -import org.eclipse.linuxtools.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; +import org.eclipse.tracecompass.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; import org.eclipse.ui.views.properties.IPropertyDescriptor; /** diff --git a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceDomainPropertySource.java b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceDomainPropertySource.java index 630fe7f064..bff8c8351e 100644 --- a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceDomainPropertySource.java +++ b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceDomainPropertySource.java @@ -14,7 +14,7 @@ package org.eclipse.linuxtools.internal.lttng2.control.ui.views.property; import org.eclipse.linuxtools.internal.lttng2.control.core.model.impl.BufferType; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.messages.Messages; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.model.impl.TraceDomainComponent; -import org.eclipse.linuxtools.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; +import org.eclipse.tracecompass.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; import org.eclipse.ui.views.properties.IPropertyDescriptor; /** diff --git a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceEventPropertySource.java b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceEventPropertySource.java index e7cc8f5889..da36dc348c 100644 --- a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceEventPropertySource.java +++ b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceEventPropertySource.java @@ -19,7 +19,7 @@ import org.eclipse.linuxtools.internal.lttng2.control.core.model.LogLevelType; import org.eclipse.linuxtools.internal.lttng2.control.core.model.TraceLogLevel; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.messages.Messages; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.model.impl.TraceEventComponent; -import org.eclipse.linuxtools.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; +import org.eclipse.tracecompass.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; import org.eclipse.ui.views.properties.IPropertyDescriptor; /** diff --git a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceProbeEventPropertySource.java b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceProbeEventPropertySource.java index 759d43b7d2..b50c647a9f 100644 --- a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceProbeEventPropertySource.java +++ b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceProbeEventPropertySource.java @@ -18,7 +18,7 @@ import java.util.List; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.messages.Messages; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.model.impl.TraceEventComponent; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.model.impl.TraceProbeEventComponent; -import org.eclipse.linuxtools.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; +import org.eclipse.tracecompass.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; import org.eclipse.ui.views.properties.IPropertyDescriptor; /** diff --git a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceSessionPropertySource.java b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceSessionPropertySource.java index 0ccb10ec38..a0a64703b2 100644 --- a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceSessionPropertySource.java +++ b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/TraceSessionPropertySource.java @@ -16,7 +16,7 @@ import java.util.List; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.messages.Messages; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.model.impl.TraceSessionComponent; -import org.eclipse.linuxtools.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; +import org.eclipse.tracecompass.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; import org.eclipse.ui.views.properties.IPropertyDescriptor; /** diff --git a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/UstProviderPropertySource.java b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/UstProviderPropertySource.java index bd2ad61e27..e6aa305eab 100644 --- a/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/UstProviderPropertySource.java +++ b/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/linuxtools/internal/lttng2/control/ui/views/property/UstProviderPropertySource.java @@ -13,7 +13,7 @@ package org.eclipse.linuxtools.internal.lttng2.control.ui.views.property; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.messages.Messages; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.model.impl.UstProviderComponent; -import org.eclipse.linuxtools.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; +import org.eclipse.tracecompass.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; import org.eclipse.ui.views.properties.IPropertyDescriptor; /** diff --git a/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/linuxtools/lttng2/kernel/core/tests/perf/analysis/AnalysisBenchmark.java b/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/linuxtools/lttng2/kernel/core/tests/perf/analysis/AnalysisBenchmark.java index ae37bf0da1..cf80b6bc94 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/linuxtools/lttng2/kernel/core/tests/perf/analysis/AnalysisBenchmark.java +++ b/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/linuxtools/lttng2/kernel/core/tests/perf/analysis/AnalysisBenchmark.java @@ -20,16 +20,16 @@ import java.io.File; import org.eclipse.linuxtools.lttng2.kernel.core.analysis.LttngKernelAnalysisModule; import org.eclipse.linuxtools.lttng2.kernel.core.trace.LttngKernelTrace; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestHelper; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfEvent; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; import org.eclipse.test.performance.Dimension; import org.eclipse.test.performance.Performance; import org.eclipse.test.performance.PerformanceMeter; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestHelper; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfEvent; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; import org.junit.Test; /** diff --git a/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/linuxtools/lttng2/kernel/core/tests/perf/event/matching/EventMatchingBenchmark.java b/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/linuxtools/lttng2/kernel/core/tests/perf/event/matching/EventMatchingBenchmark.java index 8ccd66ff71..63eb31e140 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/linuxtools/lttng2/kernel/core/tests/perf/event/matching/EventMatchingBenchmark.java +++ b/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/linuxtools/lttng2/kernel/core/tests/perf/event/matching/EventMatchingBenchmark.java @@ -18,14 +18,14 @@ import java.util.Set; import org.eclipse.linuxtools.lttng2.kernel.core.event.matching.TcpEventMatching; import org.eclipse.linuxtools.lttng2.kernel.core.event.matching.TcpLttngEventMatching; -import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventMatching; -import org.eclipse.linuxtools.tmf.core.event.matching.TmfNetworkEventMatching; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; import org.eclipse.test.performance.Dimension; import org.eclipse.test.performance.Performance; import org.eclipse.test.performance.PerformanceMeter; +import org.eclipse.tracecompass.tmf.core.event.matching.TmfEventMatching; +import org.eclipse.tracecompass.tmf.core.event.matching.TmfNetworkEventMatching; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; import org.junit.BeforeClass; import org.junit.Test; diff --git a/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/linuxtools/lttng2/kernel/core/tests/perf/event/matching/TraceSynchronizationBenchmark.java b/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/linuxtools/lttng2/kernel/core/tests/perf/event/matching/TraceSynchronizationBenchmark.java index f4ab323eb6..48c3cd0317 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/linuxtools/lttng2/kernel/core/tests/perf/event/matching/TraceSynchronizationBenchmark.java +++ b/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/linuxtools/lttng2/kernel/core/tests/perf/event/matching/TraceSynchronizationBenchmark.java @@ -19,15 +19,15 @@ import java.util.Arrays; import org.eclipse.linuxtools.lttng2.kernel.core.event.matching.TcpEventMatching; import org.eclipse.linuxtools.lttng2.kernel.core.event.matching.TcpLttngEventMatching; -import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventMatching; -import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithm; -import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationManager; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; import org.eclipse.test.performance.Dimension; import org.eclipse.test.performance.Performance; import org.eclipse.test.performance.PerformanceMeter; +import org.eclipse.tracecompass.tmf.core.event.matching.TmfEventMatching; +import org.eclipse.tracecompass.tmf.core.synchronization.SynchronizationAlgorithm; +import org.eclipse.tracecompass.tmf.core.synchronization.SynchronizationManager; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; import org.junit.BeforeClass; import org.junit.Test; diff --git a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/analysis/LttngKernelAnalysisTest.java b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/analysis/LttngKernelAnalysisTest.java index e63a907da0..dd461e50df 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/analysis/LttngKernelAnalysisTest.java +++ b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/analysis/LttngKernelAnalysisTest.java @@ -27,12 +27,12 @@ import org.eclipse.linuxtools.internal.lttng2.kernel.core.LttngStrings; import org.eclipse.linuxtools.lttng2.control.core.session.SessionConfigStrings; import org.eclipse.linuxtools.lttng2.kernel.core.analysis.LttngKernelAnalysisModule; import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisRequirement; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestHelper; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestHelper; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; diff --git a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/ExperimentSyncTest.java b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/ExperimentSyncTest.java index 1e7b2447b7..459a0f380a 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/ExperimentSyncTest.java +++ b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/ExperimentSyncTest.java @@ -17,14 +17,14 @@ import static org.junit.Assume.assumeTrue; import org.eclipse.linuxtools.lttng2.kernel.core.event.matching.TcpEventMatching; import org.eclipse.linuxtools.lttng2.kernel.core.event.matching.TcpLttngEventMatching; -import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventMatching; -import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform; -import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithm; -import org.eclipse.linuxtools.tmf.core.synchronization.TimestampTransformFactory; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.eclipse.tracecompass.tmf.core.event.matching.TmfEventMatching; +import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform; +import org.eclipse.tracecompass.tmf.core.synchronization.SynchronizationAlgorithm; +import org.eclipse.tracecompass.tmf.core.synchronization.TimestampTransformFactory; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; import org.junit.BeforeClass; import org.junit.Test; diff --git a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/MatchAndSyncTest.java b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/MatchAndSyncTest.java index e8e7b514ab..d5ec5a781a 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/MatchAndSyncTest.java +++ b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/MatchAndSyncTest.java @@ -21,11 +21,11 @@ import java.util.List; import org.eclipse.linuxtools.lttng2.kernel.core.event.matching.TcpEventMatching; import org.eclipse.linuxtools.lttng2.kernel.core.event.matching.TcpLttngEventMatching; -import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventMatching; -import org.eclipse.linuxtools.tmf.core.event.matching.TmfNetworkEventMatching; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.eclipse.tracecompass.tmf.core.event.matching.TmfEventMatching; +import org.eclipse.tracecompass.tmf.core.event.matching.TmfNetworkEventMatching; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; import org.junit.Test; /** diff --git a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/GenerateTestValues.java b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/GenerateTestValues.java index dd85c0e477..02d722b4c9 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/GenerateTestValues.java +++ b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/GenerateTestValues.java @@ -21,10 +21,10 @@ import org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider.LttngKer import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; /** * Small program to regenerate the values used in "TestValues.java" from the diff --git a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/LttngKernelStateProviderTest.java b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/LttngKernelStateProviderTest.java index e6e8074ed0..f190653ff4 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/LttngKernelStateProviderTest.java +++ b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/LttngKernelStateProviderTest.java @@ -16,8 +16,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assume.assumeTrue; import org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider.LttngKernelStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateProvider; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; import org.junit.BeforeClass; import org.junit.Test; diff --git a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/PartialStateSystemTest.java b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/PartialStateSystemTest.java index 5e33dcdbd6..72fa8e4c08 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/PartialStateSystemTest.java +++ b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/PartialStateSystemTest.java @@ -23,12 +23,12 @@ import org.eclipse.jdt.annotation.Nullable; import org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider.LttngKernelStateProvider; import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; import org.junit.After; import org.junit.Test; diff --git a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullHistoryTest.java b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullHistoryTest.java index a8a0f62db7..7451460871 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullHistoryTest.java +++ b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullHistoryTest.java @@ -25,12 +25,12 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider.LttngKernelStateProvider; import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; import org.junit.After; import org.junit.Test; diff --git a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemInMemoryTest.java b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemInMemoryTest.java index 80cec1cbd7..6feea39d82 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemInMemoryTest.java +++ b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemInMemoryTest.java @@ -18,11 +18,11 @@ import static org.junit.Assert.fail; import org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider.LttngKernelStateProvider; import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; import org.junit.After; /** diff --git a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemTest.java b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemTest.java index 32e1ed23f7..b7d014e5d1 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemTest.java +++ b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemTest.java @@ -28,7 +28,7 @@ import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeExceptio import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; import org.junit.After; import org.junit.Before; import org.junit.Rule; diff --git a/org.eclipse.tracecompass.lttng2.kernel.core/plugin.xml b/org.eclipse.tracecompass.lttng2.kernel.core/plugin.xml index f74134c622..9e70f974b1 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.core/plugin.xml +++ b/org.eclipse.tracecompass.lttng2.kernel.core/plugin.xml @@ -5,7 +5,7 @@ point="org.eclipse.linuxtools.tmf.core.tracetype"> diff --git a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/viewers/events/LttngEventTableColumns.java b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/viewers/events/LttngEventTableColumns.java index da8b20f532..b902d1ec83 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/viewers/events/LttngEventTableColumns.java +++ b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/viewers/events/LttngEventTableColumns.java @@ -15,9 +15,9 @@ package org.eclipse.linuxtools.internal.lttng2.kernel.ui.viewers.events; import java.util.Collection; import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.ITmfEventTableColumns; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.ITmfEventTableColumns; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; import com.google.common.collect.ImmutableList; diff --git a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/PerspectiveFactory.java b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/PerspectiveFactory.java index 13bc181afb..799d919415 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/PerspectiveFactory.java +++ b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/PerspectiveFactory.java @@ -15,9 +15,9 @@ package org.eclipse.linuxtools.internal.lttng2.kernel.ui.views; import org.eclipse.linuxtools.internal.lttng2.control.ui.views.ControlView; import org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.controlflow.ControlFlowView; import org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.resources.ResourcesView; -import org.eclipse.linuxtools.tmf.ui.project.wizards.NewTmfProjectWizard; -import org.eclipse.linuxtools.tmf.ui.views.histogram.HistogramView; -import org.eclipse.linuxtools.tmf.ui.views.statistics.TmfStatisticsView; +import org.eclipse.tracecompass.tmf.ui.project.wizards.NewTmfProjectWizard; +import org.eclipse.tracecompass.tmf.ui.views.histogram.HistogramView; +import org.eclipse.tracecompass.tmf.ui.views.statistics.TmfStatisticsView; import org.eclipse.ui.IFolderLayout; import org.eclipse.ui.IPageLayout; import org.eclipse.ui.IPerspectiveFactory; diff --git a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowEntry.java b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowEntry.java index 01145fd372..14c86c8cb3 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowEntry.java +++ b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowEntry.java @@ -14,8 +14,8 @@ package org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.controlflow; import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry; /** * An entry in the Control Flow view diff --git a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowPresentationProvider.java b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowPresentationProvider.java index 22fa932dc0..2c84d8ae3b 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowPresentationProvider.java +++ b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowPresentationProvider.java @@ -29,16 +29,16 @@ import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeExceptio import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.StateItem; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.StateItem; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils; /** * Presentation provider for the control flow view diff --git a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java index 3627e80aa9..8613bd7433 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java +++ b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java @@ -35,19 +35,19 @@ import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeExceptio import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ui.views.timegraph.AbstractTimeGraphView; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeLinkEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.Resolution; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ui.views.timegraph.AbstractTimeGraphView; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeLinkEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.Resolution; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; /** * The Control Flow view main object diff --git a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageComposite.java b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageComposite.java index a56b3f3e83..b2a81acc42 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageComposite.java +++ b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageComposite.java @@ -30,16 +30,16 @@ import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundExcep import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.viewers.tree.AbstractTmfTreeViewer; -import org.eclipse.linuxtools.tmf.ui.viewers.tree.ITmfTreeColumnDataProvider; -import org.eclipse.linuxtools.tmf.ui.viewers.tree.ITmfTreeViewerEntry; -import org.eclipse.linuxtools.tmf.ui.viewers.tree.TmfTreeColumnData; -import org.eclipse.linuxtools.tmf.ui.viewers.tree.TmfTreeColumnData.ITmfColumnPercentageProvider; -import org.eclipse.linuxtools.tmf.ui.viewers.tree.TmfTreeViewerEntry; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Composite; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.viewers.tree.AbstractTmfTreeViewer; +import org.eclipse.tracecompass.tmf.ui.viewers.tree.ITmfTreeColumnDataProvider; +import org.eclipse.tracecompass.tmf.ui.viewers.tree.ITmfTreeViewerEntry; +import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfTreeColumnData; +import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfTreeViewerEntry; +import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfTreeColumnData.ITmfColumnPercentageProvider; /** * Tree viewer to display CPU usage information in a specified time range. It diff --git a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageEntry.java b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageEntry.java index 79bb0ce26e..537e05bf62 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageEntry.java +++ b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageEntry.java @@ -12,7 +12,7 @@ package org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.cpuusage; -import org.eclipse.linuxtools.tmf.ui.viewers.tree.TmfTreeViewerEntry; +import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfTreeViewerEntry; /** * Represents an entry in the tree viewer of the CPU usage view. An entry is a diff --git a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageView.java b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageView.java index d2d8a1ed23..470d909aa3 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageView.java +++ b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageView.java @@ -16,13 +16,13 @@ import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.views.TmfView; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.views.TmfView; /** * CPU usage view. It contains 2 viewers: one tree viewer showing all the diff --git a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageXYViewer.java b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageXYViewer.java index e2167ef594..4380be6789 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageXYViewer.java +++ b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageXYViewer.java @@ -23,8 +23,8 @@ import org.eclipse.linuxtools.internal.lttng2.kernel.ui.Activator; import org.eclipse.linuxtools.lttng2.kernel.core.cpuusage.LttngKernelCpuUsageAnalysis; import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.tmf.ui.viewers.xycharts.linecharts.TmfCommonXLineChartViewer; import org.eclipse.swt.widgets.Composite; +import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.linecharts.TmfCommonXLineChartViewer; /** * CPU usage viewer with XY line chart. It displays the total CPU usage and that diff --git a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesEntry.java b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesEntry.java index c67d0e6263..e3083e63f1 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesEntry.java +++ b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesEntry.java @@ -14,9 +14,9 @@ package org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.resources; import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry; /** * An entry, or row, in the resource view diff --git a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesPresentationProvider.java b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesPresentationProvider.java index fc326f501f..7e9bc64230 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesPresentationProvider.java +++ b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesPresentationProvider.java @@ -30,22 +30,22 @@ import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeExceptio import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.StateItem; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.NullTimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.ITmfTimeGraphDrawingHelper; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.Resolution; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.StateItem; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.NullTimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.ITmfTimeGraphDrawingHelper; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.Resolution; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; /** * Presentation provider for the Resource view, based on the generic TMF diff --git a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesView.java b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesView.java index 798a0e49c9..92169653e1 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesView.java +++ b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesView.java @@ -32,14 +32,14 @@ import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedExc import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.views.timegraph.AbstractTimeGraphView; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.NullTimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.views.timegraph.AbstractTimeGraphView; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.NullTimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry; /** * Main implementation for the LTTng 2.0 kernel Resource view diff --git a/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/analysis/memory/UstMemoryAnalysisModuleTest.java b/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/analysis/memory/UstMemoryAnalysisModuleTest.java index cbf456347a..4a10fad00d 100644 --- a/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/analysis/memory/UstMemoryAnalysisModuleTest.java +++ b/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/analysis/memory/UstMemoryAnalysisModuleTest.java @@ -21,7 +21,7 @@ import java.util.Set; import org.eclipse.linuxtools.internal.lttng2.ust.core.memoryusage.UstMemoryStrings; import org.eclipse.linuxtools.lttng2.control.core.session.SessionConfigStrings; import org.eclipse.linuxtools.lttng2.ust.core.analysis.memory.UstMemoryAnalysisModule; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisRequirement; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement; import org.junit.Before; import org.junit.Test; diff --git a/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/AbstractProviderTest.java b/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/AbstractProviderTest.java index 68841f0f16..d525c4b6cd 100644 --- a/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/AbstractProviderTest.java +++ b/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/AbstractProviderTest.java @@ -27,13 +27,13 @@ import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundExcep import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; import org.junit.After; import org.junit.Before; import org.junit.Rule; diff --git a/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/LttngUstCallStackProviderFastTest.java b/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/LttngUstCallStackProviderFastTest.java index fccfd93ec2..e2c29155e8 100644 --- a/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/LttngUstCallStackProviderFastTest.java +++ b/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/LttngUstCallStackProviderFastTest.java @@ -14,7 +14,7 @@ package org.eclipse.linuxtools.lttng2.ust.core.tests.trace.callstack; import static org.junit.Assume.assumeTrue; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; import org.junit.BeforeClass; /** diff --git a/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/LttngUstCallStackProviderTest.java b/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/LttngUstCallStackProviderTest.java index e27e7627b9..92ebe7be45 100644 --- a/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/LttngUstCallStackProviderTest.java +++ b/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/LttngUstCallStackProviderTest.java @@ -14,7 +14,7 @@ package org.eclipse.linuxtools.lttng2.ust.core.tests.trace.callstack; import static org.junit.Assume.assumeTrue; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; import org.junit.BeforeClass; /** diff --git a/org.eclipse.tracecompass.lttng2.ust.core/plugin.xml b/org.eclipse.tracecompass.lttng2.ust.core/plugin.xml index 8d536c340e..977ffc4282 100644 --- a/org.eclipse.tracecompass.lttng2.ust.core/plugin.xml +++ b/org.eclipse.tracecompass.lttng2.ust.core/plugin.xml @@ -5,7 +5,7 @@ point="org.eclipse.linuxtools.tmf.core.tracetype"> diff --git a/org.eclipse.tracecompass.lttng2.ust.ui/src/org/eclipse/linuxtools/internal/lttng2/ust/ui/views/memusage/MemoryUsageView.java b/org.eclipse.tracecompass.lttng2.ust.ui/src/org/eclipse/linuxtools/internal/lttng2/ust/ui/views/memusage/MemoryUsageView.java index aacb49aa37..b6827cc505 100644 --- a/org.eclipse.tracecompass.lttng2.ust.ui/src/org/eclipse/linuxtools/internal/lttng2/ust/ui/views/memusage/MemoryUsageView.java +++ b/org.eclipse.tracecompass.lttng2.ust.ui/src/org/eclipse/linuxtools/internal/lttng2/ust/ui/views/memusage/MemoryUsageView.java @@ -12,8 +12,8 @@ package org.eclipse.linuxtools.internal.lttng2.ust.ui.views.memusage; -import org.eclipse.linuxtools.tmf.ui.views.TmfChartView; import org.eclipse.swt.widgets.Composite; +import org.eclipse.tracecompass.tmf.ui.views.TmfChartView; /** * Memory Usage View diff --git a/org.eclipse.tracecompass.lttng2.ust.ui/src/org/eclipse/linuxtools/internal/lttng2/ust/ui/views/memusage/MemoryUsageViewer.java b/org.eclipse.tracecompass.lttng2.ust.ui/src/org/eclipse/linuxtools/internal/lttng2/ust/ui/views/memusage/MemoryUsageViewer.java index fcb2c06ed0..0e03dca1dd 100644 --- a/org.eclipse.tracecompass.lttng2.ust.ui/src/org/eclipse/linuxtools/internal/lttng2/ust/ui/views/memusage/MemoryUsageViewer.java +++ b/org.eclipse.tracecompass.lttng2.ust.ui/src/org/eclipse/linuxtools/internal/lttng2/ust/ui/views/memusage/MemoryUsageViewer.java @@ -19,7 +19,6 @@ import java.util.Map; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.linuxtools.internal.lttng2.ust.core.memoryusage.UstMemoryStrings; -import org.eclipse.linuxtools.internal.tmf.core.Activator; import org.eclipse.linuxtools.lttng2.ust.core.analysis.memory.UstMemoryAnalysisModule; import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; @@ -27,9 +26,10 @@ import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedExc import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.ui.viewers.xycharts.linecharts.TmfCommonXLineChartViewer; import org.eclipse.swt.widgets.Composite; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.linecharts.TmfCommonXLineChartViewer; /** * Memory usage view diff --git a/org.eclipse.tracecompass.lttng2.ust.ui/src/org/eclipse/linuxtools/lttng2/ust/ui/analysis/callstack/LttngUstCallStackAnalysis.java b/org.eclipse.tracecompass.lttng2.ust.ui/src/org/eclipse/linuxtools/lttng2/ust/ui/analysis/callstack/LttngUstCallStackAnalysis.java index f1b0ec08aa..d726faadf6 100644 --- a/org.eclipse.tracecompass.lttng2.ust.ui/src/org/eclipse/linuxtools/lttng2/ust/ui/analysis/callstack/LttngUstCallStackAnalysis.java +++ b/org.eclipse.tracecompass.lttng2.ust.ui/src/org/eclipse/linuxtools/lttng2/ust/ui/analysis/callstack/LttngUstCallStackAnalysis.java @@ -14,10 +14,10 @@ package org.eclipse.linuxtools.lttng2.ust.ui.analysis.callstack; import org.eclipse.linuxtools.internal.lttng2.ust.core.trace.callstack.LttngUstCallStackProvider; import org.eclipse.linuxtools.lttng2.ust.core.trace.LttngUstTrace; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateProvider; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.views.callstack.AbstractCallStackAnalysis; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.views.callstack.AbstractCallStackAnalysis; /** * Call-stack analysis to populate the TMF CallStack View from UST cyg-profile diff --git a/org.eclipse.tracecompass.rcp.ui/src/org/eclipse/linuxtools/internal/tracing/rcp/ui/ApplicationWorkbenchWindowAdvisor.java b/org.eclipse.tracecompass.rcp.ui/src/org/eclipse/linuxtools/internal/tracing/rcp/ui/ApplicationWorkbenchWindowAdvisor.java index 5e8f830446..1bc5b0d0d3 100644 --- a/org.eclipse.tracecompass.rcp.ui/src/org/eclipse/linuxtools/internal/tracing/rcp/ui/ApplicationWorkbenchWindowAdvisor.java +++ b/org.eclipse.tracecompass.rcp.ui/src/org/eclipse/linuxtools/internal/tracing/rcp/ui/ApplicationWorkbenchWindowAdvisor.java @@ -15,10 +15,10 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.linuxtools.internal.tracing.rcp.ui.cli.CliParser; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfOpenTraceHelper; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfOpenTraceHelper; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; import org.eclipse.ui.IPerspectiveDescriptor; import org.eclipse.ui.IPerspectiveListener; import org.eclipse.ui.IWorkbenchPage; diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/META-INF/MANIFEST.MF b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/META-INF/MANIFEST.MF index 05a3367361..1ee2b30405 100644 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.eclipse.tracecompass.tmf.analysis.xml.core.tests Bundle-Version: 1.1.0.qualifier -Bundle-Activator: org.eclipse.linuxtools.tmf.analysis.xml.core.tests.Activator +Bundle-Activator: org.eclipse.tracecompass.tmf.analysis.xml.core.tests.Activator Bundle-Vendor: %Bundle-Vendor Require-Bundle: org.junit, org.eclipse.core.runtime, @@ -16,5 +16,5 @@ Require-Bundle: org.junit, Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Bundle-ActivationPolicy: lazy Import-Package: org.junit.runners -Export-Package: org.eclipse.linuxtools.tmf.analysis.xml.core.tests, - org.eclipse.linuxtools.tmf.analysis.xml.core.tests.common;x-friends:="org.eclipse.tracecompass.tmf.analysis.xml.ui.tests" +Export-Package: org.eclipse.tracecompass.tmf.analysis.xml.core.tests, + org.eclipse.tracecompass.tmf.analysis.xml.core.tests.common;x-friends:="org.eclipse.tracecompass.tmf.analysis.xml.ui.tests" diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/common/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/common/TmfXmlTestFiles.java b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/common/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/common/TmfXmlTestFiles.java deleted file mode 100644 index 854d5d18b3..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/common/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/common/TmfXmlTestFiles.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.tests.common; - -import java.io.File; - -/** - * Provides some test XML files to use - * - * @author Geneviève Bastien - */ -public enum TmfXmlTestFiles { - /** A valid XML test file */ - VALID_FILE("../org.eclipse.linuxtools.tmf.analysis.xml.core.tests/test_xml_files/test_valid/test_valid.xml"), - /** An invalid test file */ - INVALID_FILE("../org.eclipse.linuxtools.tmf.analysis.xml.core.tests/test_xml_files/test_invalid/test_invalid.xml"); - - private final String fPath; - - private TmfXmlTestFiles(String file) { - fPath = file; - } - - /** - * Get the file name part of the file - * - * @return The path of this test file - */ - public String getPath() { - return fPath; - } - - /** - * Returns the file object corresponding to the test XML file - * - * @return The file object for this test file - */ - public File getFile() { - return new File(fPath); - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/common/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/common/TmfXmlTestFiles.java b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/common/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/common/TmfXmlTestFiles.java new file mode 100644 index 0000000000..598bedcfb5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/common/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/common/TmfXmlTestFiles.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.tests.common; + +import java.io.File; + +/** + * Provides some test XML files to use + * + * @author Geneviève Bastien + */ +public enum TmfXmlTestFiles { + /** A valid XML test file */ + VALID_FILE("../org.eclipse.tracecompass.tmf.analysis.xml.core.tests/test_xml_files/test_valid/test_valid.xml"), + /** An invalid test file */ + INVALID_FILE("../org.eclipse.tracecompass.tmf.analysis.xml.core.tests/test_xml_files/test_invalid/test_invalid.xml"); + + private final String fPath; + + private TmfXmlTestFiles(String file) { + fPath = file; + } + + /** + * Get the file name part of the file + * + * @return The path of this test file + */ + public String getPath() { + return fPath; + } + + /** + * Returns the file object corresponding to the test XML file + * + * @return The file object for this test file + */ + public File getFile() { + return new File(fPath); + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/pom.xml b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/pom.xml index 973d05b2ad..622a4b77ba 100644 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/pom.xml +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/pom.xml @@ -42,7 +42,7 @@ ${tycho-version} org.eclipse.tracecompass.tmf.analysis.xml.core.tests - org.eclipse.linuxtools.tmf.analysis.xml.core.tests.AllAnalysisXmlCoreTests + org.eclipse.tracecompass.tmf.analysis.xml.core.tests.AllAnalysisXmlCoreTests false false org.eclipse.sdk.ide diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/Activator.java b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/Activator.java deleted file mode 100644 index f5951595e4..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/Activator.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.tests; - -import org.eclipse.core.runtime.Plugin; -import org.osgi.framework.BundleContext; - -/** - * The activator class controls the plug-in life cycle - */ -public class Activator extends Plugin { - - /** - * The plug-in ID - */ - public static final String PLUGIN_ID = "org.eclipse.tracecompass.tmf.analysis.xml.core.tests"; //$NON-NLS-1$ - - // The shared instance - private static Activator plugin; - - /** - * The constructor - */ - public Activator() { - } - - @Override - public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - } - - @Override - 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; - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/AllAnalysisXmlCoreTests.java b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/AllAnalysisXmlCoreTests.java deleted file mode 100644 index 891b6d7c66..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/AllAnalysisXmlCoreTests.java +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.tests; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Master test suite for TMF XML Core Analysis plug-in. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - XmlAnalysisCorePluginTest.class, - org.eclipse.linuxtools.tmf.analysis.xml.core.tests.module.AllTests.class, - org.eclipse.linuxtools.tmf.analysis.xml.core.tests.stateprovider.AllTests.class -}) -public class AllAnalysisXmlCoreTests { - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/XmlAnalysisCorePluginTest.java b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/XmlAnalysisCorePluginTest.java deleted file mode 100644 index 993b11843a..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/XmlAnalysisCorePluginTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.tests; - -import static org.junit.Assert.assertEquals; - -import org.eclipse.linuxtools.internal.tmf.analysis.xml.core.Activator; -import org.junit.Test; - -/** - * Test the XML Analysis Core plug-in activator - */ -public class XmlAnalysisCorePluginTest { - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // Plug-in instantiation - static final Activator fPlugin = new Activator(); - - // ------------------------------------------------------------------------ - // Test cases - // ------------------------------------------------------------------------ - - /** - * Test the plugin ID. - */ - @Test - public void testTmfCorePluginId() { - assertEquals("Plugin ID", "org.eclipse.linuxtools.tmf.analysis.xml.core", Activator.PLUGIN_ID); - } - - /** - * Test the getDefault() static method. - */ - @Test - public void testGetDefault() { - Activator plugin = Activator.getDefault(); - assertEquals("getDefault()", plugin, fPlugin); - } -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/module/AllTests.java b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/module/AllTests.java deleted file mode 100644 index ca0aa281f5..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/module/AllTests.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.tests.module; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite for org.eclipse.linuxtools.tmf.analysis.xml.core.module package - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - XmlUtilsTest.class -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/module/XmlUtilsTest.java b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/module/XmlUtilsTest.java deleted file mode 100644 index e06b517512..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/module/XmlUtilsTest.java +++ /dev/null @@ -1,232 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.tests.module; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.util.List; - -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.analysis.xml.core.tests.Activator; -import org.eclipse.linuxtools.tmf.analysis.xml.core.tests.common.TmfXmlTestFiles; -import org.junit.After; -import org.junit.Test; -import org.w3c.dom.Element; - -/** - * Tests for the {@link XmlUtils} class - * - * @author Geneviève Bastien - */ -public class XmlUtilsTest { - - private static final Path PATH_INVALID = new Path("test_xml_files/test_invalid"); - private static final Path PATH_VALID = new Path("test_xml_files/test_valid"); - - private static IPath getAbsolutePath(Path relativePath) { - Activator plugin = Activator.getDefault(); - if (plugin == null) { - /* - * Shouldn't happen but at least throw something to get the test to - * fail early - */ - throw new IllegalStateException(); - } - URL location = FileLocator.find(plugin.getBundle(), relativePath, null); - try { - IPath path = new Path(FileLocator.toFileURL(location).getPath()); - return path; - } catch (IOException e) { - throw new IllegalStateException(); - } - } - - /** - * Empty the XML directory after the test - */ - @After - public void emptyXmlFolder() { - File fFolder = XmlUtils.getXmlFilesPath().toFile(); - if (!(fFolder.isDirectory() && fFolder.exists())) { - return; - } - for (File xmlFile : fFolder.listFiles()) { - xmlFile.delete(); - } - } - - /** - * Test the {@link XmlUtils#getXmlFilesPath()} method - */ - @Test - public void testXmlPath() { - IPath xmlPath = XmlUtils.getXmlFilesPath(); - - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - IPath workspacePath = workspace.getRoot().getRawLocation(); - workspacePath = workspacePath.addTrailingSeparator() - .append(".metadata").addTrailingSeparator().append(".plugins") - .addTrailingSeparator() - .append("org.eclipse.tracecompass.tmf.analysis.xml.core") - .addTrailingSeparator().append("xml_files"); - - assertEquals(xmlPath, workspacePath); - } - - /** - * test the {@link XmlUtils#xmlValidate(File)} method - */ - @Test - public void testXmlValidate() { - File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile(); - if ((testXmlFile == null) || !testXmlFile.exists()) { - fail("XML test file does not exist"); - } - IStatus status = XmlUtils.xmlValidate(testXmlFile); - if (!status.isOK()) { - fail(status.getMessage()); - } - - testXmlFile = TmfXmlTestFiles.INVALID_FILE.getFile(); - if ((testXmlFile == null) || !testXmlFile.exists()) { - fail("XML test file does not exist"); - } - assertFalse(XmlUtils.xmlValidate(testXmlFile).isOK()); - - } - - /** - * Test various invalid files and make sure they are invalid - */ - @Test - public void testXmlValidateInvalid() { - IPath path = getAbsolutePath(PATH_INVALID); - File file = path.toFile(); - - File[] invalidFiles = file.listFiles(); - assertTrue(invalidFiles.length > 0); - for (File f : invalidFiles) { - assertFalse("File " + f.getName(), XmlUtils.xmlValidate(f).isOK()); - } - } - - /** - * Test various valid files and make sure they are valid - */ - @Test - public void testXmlValidateValid() { - IPath path = getAbsolutePath(PATH_VALID); - File file = path.toFile(); - - File[] validFiles = file.listFiles(); - assertTrue(validFiles.length > 0); - for (File f : validFiles) { - assertTrue("File " + f.getName(), XmlUtils.xmlValidate(f).isOK()); - } - } - - /** - * test the {@link XmlUtils#addXmlFile(File)} method - */ - @Test - public void testXmlAddFile() { - /* Check the file does not exist */ - IPath xmlPath = XmlUtils.getXmlFilesPath().addTrailingSeparator().append("test_valid.xml"); - File destFile = xmlPath.toFile(); - assertFalse(destFile.exists()); - - /* Add test_valid.xml file */ - File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile(); - if ((testXmlFile == null) || !testXmlFile.exists()) { - fail("XML test file does not exist"); - } - - XmlUtils.addXmlFile(testXmlFile); - assertTrue(destFile.exists()); - } - - private static final @NonNull String ANALYSIS_ID = "kernel.linux.sp"; - - /** - * Test the {@link XmlUtils#getElementInFile(String, String, String)} method - */ - @Test - public void testGetElementInFile() { - File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile(); - if ((testXmlFile == null) || !testXmlFile.exists()) { - fail("XML test file does not exist"); - } - /* - * This sounds useless, but I get a potential null pointer warning - * otherwise - */ - if (testXmlFile == null) { - return; - } - - Element analysis = XmlUtils.getElementInFile(testXmlFile.getAbsolutePath(), TmfXmlStrings.STATE_PROVIDER, ANALYSIS_ID); - assertNotNull(analysis); - } - - /** - * Test the {@link XmlUtils#getChildElements(Element)} and - * {@link XmlUtils#getChildElements(Element, String)} methods - */ - @Test - public void testGetChildElements() { - File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile(); - if ((testXmlFile == null) || !testXmlFile.exists()) { - fail("XML test file does not exist"); - } - /* - * This sounds useless, but I get a potential null pointer warning - * otherwise - */ - if (testXmlFile == null) { - return; - } - - Element analysis = XmlUtils.getElementInFile(testXmlFile.getAbsolutePath(), TmfXmlStrings.STATE_PROVIDER, ANALYSIS_ID); - - List values = XmlUtils.getChildElements(analysis, TmfXmlStrings.LOCATION); - assertEquals(5, values.size()); - - Element aLocation = values.get(0); - List attributes = XmlUtils.getChildElements(aLocation, TmfXmlStrings.STATE_ATTRIBUTE); - assertEquals(2, attributes.size()); - - values = XmlUtils.getChildElements(analysis, TmfXmlStrings.HEAD); - assertEquals(1, values.size()); - - Element head = values.get(0); - values = XmlUtils.getChildElements(head); - assertEquals(2, values.size()); - - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/stateprovider/AllTests.java b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/stateprovider/AllTests.java deleted file mode 100644 index 05fbac267a..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/stateprovider/AllTests.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.tests.stateprovider; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite for org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider - * package - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - StateProviderTest.class, - StateProviderModuleTest.class }) -public class AllTests { - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/stateprovider/StateProviderModuleTest.java b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/stateprovider/StateProviderModuleTest.java deleted file mode 100644 index 018c2a933b..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/stateprovider/StateProviderModuleTest.java +++ /dev/null @@ -1,130 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.tests.stateprovider; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeTrue; - -import java.io.File; -import java.io.IOException; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Path; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.XmlStateSystemModule; -import org.eclipse.linuxtools.tmf.analysis.xml.core.tests.common.TmfXmlTestFiles; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; -import org.junit.Test; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -/** - * Test suite for the XmlStateSystemModule Test. It tests the reading of the - * file, the header and the module's proper functioning as a module, but not the - * state system building, which is covered by another test suite. - * - * @author Geneviève Bastien - */ -public class StateProviderModuleTest { - - private static String ANALYSIS_ID = "kernel.linux.sp"; - private static String ANALYSIS_NAME = "Xml kernel State System"; - - private XmlStateSystemModule fModule; - - private static Document getXmlDocumentFromFile(File file) { - /* Initialize the state provider module */ - try { - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - - Document doc = dBuilder.parse(file); - - doc.getDocumentElement().normalize(); - return doc; - } catch (ParserConfigurationException e) { - fail("Xml document parse exception"); - } catch (SAXException e) { - fail("Exception parsing xml file"); - } catch (IOException e) { - fail("File io exception"); - } - return null; - } - - /** - * Test the module construction - */ - @Test - public void testModuleConstruction() { - - Document doc = getXmlDocumentFromFile(TmfXmlTestFiles.VALID_FILE.getFile()); - assertNotNull(doc); - - /* get State Providers modules */ - NodeList stateproviderNodes = doc.getElementsByTagName(TmfXmlStrings.STATE_PROVIDER); - assertTrue(stateproviderNodes.getLength() > 0); - - Element node = (Element) stateproviderNodes.item(0); - fModule = new XmlStateSystemModule(); - String moduleId = node.getAttribute(TmfXmlStrings.ID); - fModule.setId(moduleId); - assertEquals(ANALYSIS_ID, fModule.getId()); - - fModule.setXmlFile(new Path(TmfXmlTestFiles.VALID_FILE.getFile().getAbsolutePath())); - - assertEquals(ANALYSIS_NAME, fModule.getName()); - } - - /** - * Test the module executes correctly - */ - @Test - public void testModuleExecution() { - assumeTrue(CtfTmfTestTrace.KERNEL.exists()); - - Document doc = getXmlDocumentFromFile(TmfXmlTestFiles.VALID_FILE.getFile()); - assertNotNull(doc); - - /* get State Providers modules */ - NodeList stateproviderNodes = doc.getElementsByTagName(TmfXmlStrings.STATE_PROVIDER); - - Element node = (Element) stateproviderNodes.item(0); - fModule = new XmlStateSystemModule(); - String moduleId = node.getAttribute(TmfXmlStrings.ID); - fModule.setId(moduleId); - - fModule.setXmlFile(new Path(TmfXmlTestFiles.VALID_FILE.getFile().getAbsolutePath())); - - try (CtfTmfTrace trace = CtfTmfTestTrace.KERNEL.getTrace();) { - fModule.setTrace(trace); - fModule.schedule(); - - assertTrue(fModule.waitForCompletion(new NullProgressMonitor())); - } catch (TmfAnalysisException e) { - fail("Cannot set trace " + e.getMessage()); - } - - } -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/stateprovider/StateProviderTest.java b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/stateprovider/StateProviderTest.java deleted file mode 100644 index 79bc3e290a..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/core/tests/stateprovider/StateProviderTest.java +++ /dev/null @@ -1,122 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.tests.stateprovider; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeTrue; - -import java.io.IOException; -import java.util.List; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Path; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.XmlStateSystemModule; -import org.eclipse.linuxtools.tmf.analysis.xml.core.tests.common.TmfXmlTestFiles; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -/** - * Test suite for the xml state providers - * - * TODO: instead of using one of the test traces, we should make a custom trace - * to make sure it covers the different possibilities of the state provider - * - * @author Geneviève Bastien - */ -public class StateProviderTest { - - private ITmfTrace fTrace; - private XmlStateSystemModule fModule; - - /** - * Setup the test fields - */ - @Before - public void setupTest() { - /* Initialize the trace */ - assumeTrue(CtfTmfTestTrace.KERNEL.exists()); - fTrace = CtfTmfTestTrace.KERNEL.getTrace(); - - /* Initialize the state provider module */ - Document doc = null; - try { - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - doc = dBuilder.parse(TmfXmlTestFiles.VALID_FILE.getFile()); - doc.getDocumentElement().normalize(); - } catch (ParserConfigurationException e) { - fail("Xml document parse exception"); - } catch (SAXException e) { - fail("Exception parsing xml file"); - } catch (IOException e) { - fail("File io exception"); - } - assertNotNull(doc); - - /* get State Providers modules */ - NodeList stateproviderNodes = doc.getElementsByTagName(TmfXmlStrings.STATE_PROVIDER); - - Element node = (Element) stateproviderNodes.item(0); - fModule = new XmlStateSystemModule(); - String moduleId = node.getAttribute(TmfXmlStrings.ID); - fModule.setId(moduleId); - - fModule.setXmlFile(new Path(TmfXmlTestFiles.VALID_FILE.getFile().getAbsolutePath())); - - try { - fModule.setTrace(fTrace); - fModule.schedule(); - } catch (TmfAnalysisException e) { - fail("Cannot set trace " + e.getMessage()); - } - } - - /** - * Cleanup after the test - */ - @After - public void cleanupTest() { - CtfTmfTestTrace.KERNEL.dispose(); - } - - /** - * Test the building of the state system - */ - @Test - public void testStateSystem() { - assertTrue(fModule.waitForCompletion(new NullProgressMonitor())); - ITmfStateSystem ss = fModule.getStateSystem(); - assertNotNull(ss); - - List quarks = ss.getQuarks("*"); - assertFalse(quarks.isEmpty()); - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/Activator.java b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/Activator.java new file mode 100644 index 0000000000..7c535cab24 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/Activator.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.tests; + +import org.eclipse.core.runtime.Plugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends Plugin { + + /** + * The plug-in ID + */ + public static final String PLUGIN_ID = "org.eclipse.tracecompass.tmf.analysis.xml.core.tests"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + @Override + 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; + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/AllAnalysisXmlCoreTests.java b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/AllAnalysisXmlCoreTests.java new file mode 100644 index 0000000000..4c90fdace1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/AllAnalysisXmlCoreTests.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.tests; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Master test suite for TMF XML Core Analysis plug-in. + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + XmlAnalysisCorePluginTest.class, + org.eclipse.tracecompass.tmf.analysis.xml.core.tests.module.AllTests.class, + org.eclipse.tracecompass.tmf.analysis.xml.core.tests.stateprovider.AllTests.class +}) +public class AllAnalysisXmlCoreTests { + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/XmlAnalysisCorePluginTest.java b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/XmlAnalysisCorePluginTest.java new file mode 100644 index 0000000000..b71a79c040 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/XmlAnalysisCorePluginTest.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.tests; + +import static org.junit.Assert.assertEquals; + +import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.Activator; +import org.junit.Test; + +/** + * Test the XML Analysis Core plug-in activator + */ +public class XmlAnalysisCorePluginTest { + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // Plug-in instantiation + static final Activator fPlugin = new Activator(); + + // ------------------------------------------------------------------------ + // Test cases + // ------------------------------------------------------------------------ + + /** + * Test the plugin ID. + */ + @Test + public void testTmfCorePluginId() { + assertEquals("Plugin ID", "org.eclipse.tracecompass.tmf.analysis.xml.core", Activator.PLUGIN_ID); + } + + /** + * Test the getDefault() static method. + */ + @Test + public void testGetDefault() { + Activator plugin = Activator.getDefault(); + assertEquals("getDefault()", plugin, fPlugin); + } +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/module/AllTests.java b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/module/AllTests.java new file mode 100644 index 0000000000..d8db862d07 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/module/AllTests.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.tests.module; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for org.eclipse.linuxtools.tmf.analysis.xml.core.module package + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + XmlUtilsTest.class +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/module/XmlUtilsTest.java b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/module/XmlUtilsTest.java new file mode 100644 index 0000000000..ae2a852749 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/module/XmlUtilsTest.java @@ -0,0 +1,232 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.tests.module; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.List; + +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.tracecompass.tmf.analysis.xml.core.tests.Activator; +import org.eclipse.tracecompass.tmf.analysis.xml.core.tests.common.TmfXmlTestFiles; +import org.junit.After; +import org.junit.Test; +import org.w3c.dom.Element; + +/** + * Tests for the {@link XmlUtils} class + * + * @author Geneviève Bastien + */ +public class XmlUtilsTest { + + private static final Path PATH_INVALID = new Path("test_xml_files/test_invalid"); + private static final Path PATH_VALID = new Path("test_xml_files/test_valid"); + + private static IPath getAbsolutePath(Path relativePath) { + Activator plugin = Activator.getDefault(); + if (plugin == null) { + /* + * Shouldn't happen but at least throw something to get the test to + * fail early + */ + throw new IllegalStateException(); + } + URL location = FileLocator.find(plugin.getBundle(), relativePath, null); + try { + IPath path = new Path(FileLocator.toFileURL(location).getPath()); + return path; + } catch (IOException e) { + throw new IllegalStateException(); + } + } + + /** + * Empty the XML directory after the test + */ + @After + public void emptyXmlFolder() { + File fFolder = XmlUtils.getXmlFilesPath().toFile(); + if (!(fFolder.isDirectory() && fFolder.exists())) { + return; + } + for (File xmlFile : fFolder.listFiles()) { + xmlFile.delete(); + } + } + + /** + * Test the {@link XmlUtils#getXmlFilesPath()} method + */ + @Test + public void testXmlPath() { + IPath xmlPath = XmlUtils.getXmlFilesPath(); + + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IPath workspacePath = workspace.getRoot().getRawLocation(); + workspacePath = workspacePath.addTrailingSeparator() + .append(".metadata").addTrailingSeparator().append(".plugins") + .addTrailingSeparator() + .append("org.eclipse.tracecompass.tmf.analysis.xml.core") + .addTrailingSeparator().append("xml_files"); + + assertEquals(xmlPath, workspacePath); + } + + /** + * test the {@link XmlUtils#xmlValidate(File)} method + */ + @Test + public void testXmlValidate() { + File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile(); + if ((testXmlFile == null) || !testXmlFile.exists()) { + fail("XML test file does not exist"); + } + IStatus status = XmlUtils.xmlValidate(testXmlFile); + if (!status.isOK()) { + fail(status.getMessage()); + } + + testXmlFile = TmfXmlTestFiles.INVALID_FILE.getFile(); + if ((testXmlFile == null) || !testXmlFile.exists()) { + fail("XML test file does not exist"); + } + assertFalse(XmlUtils.xmlValidate(testXmlFile).isOK()); + + } + + /** + * Test various invalid files and make sure they are invalid + */ + @Test + public void testXmlValidateInvalid() { + IPath path = getAbsolutePath(PATH_INVALID); + File file = path.toFile(); + + File[] invalidFiles = file.listFiles(); + assertTrue(invalidFiles.length > 0); + for (File f : invalidFiles) { + assertFalse("File " + f.getName(), XmlUtils.xmlValidate(f).isOK()); + } + } + + /** + * Test various valid files and make sure they are valid + */ + @Test + public void testXmlValidateValid() { + IPath path = getAbsolutePath(PATH_VALID); + File file = path.toFile(); + + File[] validFiles = file.listFiles(); + assertTrue(validFiles.length > 0); + for (File f : validFiles) { + assertTrue("File " + f.getName(), XmlUtils.xmlValidate(f).isOK()); + } + } + + /** + * test the {@link XmlUtils#addXmlFile(File)} method + */ + @Test + public void testXmlAddFile() { + /* Check the file does not exist */ + IPath xmlPath = XmlUtils.getXmlFilesPath().addTrailingSeparator().append("test_valid.xml"); + File destFile = xmlPath.toFile(); + assertFalse(destFile.exists()); + + /* Add test_valid.xml file */ + File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile(); + if ((testXmlFile == null) || !testXmlFile.exists()) { + fail("XML test file does not exist"); + } + + XmlUtils.addXmlFile(testXmlFile); + assertTrue(destFile.exists()); + } + + private static final @NonNull String ANALYSIS_ID = "kernel.linux.sp"; + + /** + * Test the {@link XmlUtils#getElementInFile(String, String, String)} method + */ + @Test + public void testGetElementInFile() { + File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile(); + if ((testXmlFile == null) || !testXmlFile.exists()) { + fail("XML test file does not exist"); + } + /* + * This sounds useless, but I get a potential null pointer warning + * otherwise + */ + if (testXmlFile == null) { + return; + } + + Element analysis = XmlUtils.getElementInFile(testXmlFile.getAbsolutePath(), TmfXmlStrings.STATE_PROVIDER, ANALYSIS_ID); + assertNotNull(analysis); + } + + /** + * Test the {@link XmlUtils#getChildElements(Element)} and + * {@link XmlUtils#getChildElements(Element, String)} methods + */ + @Test + public void testGetChildElements() { + File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile(); + if ((testXmlFile == null) || !testXmlFile.exists()) { + fail("XML test file does not exist"); + } + /* + * This sounds useless, but I get a potential null pointer warning + * otherwise + */ + if (testXmlFile == null) { + return; + } + + Element analysis = XmlUtils.getElementInFile(testXmlFile.getAbsolutePath(), TmfXmlStrings.STATE_PROVIDER, ANALYSIS_ID); + + List values = XmlUtils.getChildElements(analysis, TmfXmlStrings.LOCATION); + assertEquals(5, values.size()); + + Element aLocation = values.get(0); + List attributes = XmlUtils.getChildElements(aLocation, TmfXmlStrings.STATE_ATTRIBUTE); + assertEquals(2, attributes.size()); + + values = XmlUtils.getChildElements(analysis, TmfXmlStrings.HEAD); + assertEquals(1, values.size()); + + Element head = values.get(0); + values = XmlUtils.getChildElements(head); + assertEquals(2, values.size()); + + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/stateprovider/AllTests.java b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/stateprovider/AllTests.java new file mode 100644 index 0000000000..08f8938c99 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/stateprovider/AllTests.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.tests.stateprovider; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider + * package + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + StateProviderTest.class, + StateProviderModuleTest.class }) +public class AllTests { + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/stateprovider/StateProviderModuleTest.java b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/stateprovider/StateProviderModuleTest.java new file mode 100644 index 0000000000..72c76861db --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/stateprovider/StateProviderModuleTest.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.tests.stateprovider; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + +import java.io.File; +import java.io.IOException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.XmlStateSystemModule; +import org.eclipse.tracecompass.tmf.analysis.xml.core.tests.common.TmfXmlTestFiles; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.junit.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +/** + * Test suite for the XmlStateSystemModule Test. It tests the reading of the + * file, the header and the module's proper functioning as a module, but not the + * state system building, which is covered by another test suite. + * + * @author Geneviève Bastien + */ +public class StateProviderModuleTest { + + private static String ANALYSIS_ID = "kernel.linux.sp"; + private static String ANALYSIS_NAME = "Xml kernel State System"; + + private XmlStateSystemModule fModule; + + private static Document getXmlDocumentFromFile(File file) { + /* Initialize the state provider module */ + try { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + + Document doc = dBuilder.parse(file); + + doc.getDocumentElement().normalize(); + return doc; + } catch (ParserConfigurationException e) { + fail("Xml document parse exception"); + } catch (SAXException e) { + fail("Exception parsing xml file"); + } catch (IOException e) { + fail("File io exception"); + } + return null; + } + + /** + * Test the module construction + */ + @Test + public void testModuleConstruction() { + + Document doc = getXmlDocumentFromFile(TmfXmlTestFiles.VALID_FILE.getFile()); + assertNotNull(doc); + + /* get State Providers modules */ + NodeList stateproviderNodes = doc.getElementsByTagName(TmfXmlStrings.STATE_PROVIDER); + assertTrue(stateproviderNodes.getLength() > 0); + + Element node = (Element) stateproviderNodes.item(0); + fModule = new XmlStateSystemModule(); + String moduleId = node.getAttribute(TmfXmlStrings.ID); + fModule.setId(moduleId); + assertEquals(ANALYSIS_ID, fModule.getId()); + + fModule.setXmlFile(new Path(TmfXmlTestFiles.VALID_FILE.getFile().getAbsolutePath())); + + assertEquals(ANALYSIS_NAME, fModule.getName()); + } + + /** + * Test the module executes correctly + */ + @Test + public void testModuleExecution() { + assumeTrue(CtfTmfTestTrace.KERNEL.exists()); + + Document doc = getXmlDocumentFromFile(TmfXmlTestFiles.VALID_FILE.getFile()); + assertNotNull(doc); + + /* get State Providers modules */ + NodeList stateproviderNodes = doc.getElementsByTagName(TmfXmlStrings.STATE_PROVIDER); + + Element node = (Element) stateproviderNodes.item(0); + fModule = new XmlStateSystemModule(); + String moduleId = node.getAttribute(TmfXmlStrings.ID); + fModule.setId(moduleId); + + fModule.setXmlFile(new Path(TmfXmlTestFiles.VALID_FILE.getFile().getAbsolutePath())); + + try (CtfTmfTrace trace = CtfTmfTestTrace.KERNEL.getTrace();) { + fModule.setTrace(trace); + fModule.schedule(); + + assertTrue(fModule.waitForCompletion(new NullProgressMonitor())); + } catch (TmfAnalysisException e) { + fail("Cannot set trace " + e.getMessage()); + } + + } +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/stateprovider/StateProviderTest.java b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/stateprovider/StateProviderTest.java new file mode 100644 index 0000000000..9bee08de85 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/stateprovider/StateProviderTest.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.tests.stateprovider; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + +import java.io.IOException; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.XmlStateSystemModule; +import org.eclipse.tracecompass.tmf.analysis.xml.core.tests.common.TmfXmlTestFiles; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +/** + * Test suite for the xml state providers + * + * TODO: instead of using one of the test traces, we should make a custom trace + * to make sure it covers the different possibilities of the state provider + * + * @author Geneviève Bastien + */ +public class StateProviderTest { + + private ITmfTrace fTrace; + private XmlStateSystemModule fModule; + + /** + * Setup the test fields + */ + @Before + public void setupTest() { + /* Initialize the trace */ + assumeTrue(CtfTmfTestTrace.KERNEL.exists()); + fTrace = CtfTmfTestTrace.KERNEL.getTrace(); + + /* Initialize the state provider module */ + Document doc = null; + try { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + doc = dBuilder.parse(TmfXmlTestFiles.VALID_FILE.getFile()); + doc.getDocumentElement().normalize(); + } catch (ParserConfigurationException e) { + fail("Xml document parse exception"); + } catch (SAXException e) { + fail("Exception parsing xml file"); + } catch (IOException e) { + fail("File io exception"); + } + assertNotNull(doc); + + /* get State Providers modules */ + NodeList stateproviderNodes = doc.getElementsByTagName(TmfXmlStrings.STATE_PROVIDER); + + Element node = (Element) stateproviderNodes.item(0); + fModule = new XmlStateSystemModule(); + String moduleId = node.getAttribute(TmfXmlStrings.ID); + fModule.setId(moduleId); + + fModule.setXmlFile(new Path(TmfXmlTestFiles.VALID_FILE.getFile().getAbsolutePath())); + + try { + fModule.setTrace(fTrace); + fModule.schedule(); + } catch (TmfAnalysisException e) { + fail("Cannot set trace " + e.getMessage()); + } + } + + /** + * Cleanup after the test + */ + @After + public void cleanupTest() { + CtfTmfTestTrace.KERNEL.dispose(); + } + + /** + * Test the building of the state system + */ + @Test + public void testStateSystem() { + assertTrue(fModule.waitForCompletion(new NullProgressMonitor())); + ITmfStateSystem ss = fModule.getStateSystem(); + assertNotNull(ss); + + List quarks = ss.getQuarks("*"); + assertFalse(quarks.isEmpty()); + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/META-INF/MANIFEST.MF b/org.eclipse.tracecompass.tmf.analysis.xml.core/META-INF/MANIFEST.MF index 7eb9b3c812..317bab3917 100644 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/META-INF/MANIFEST.MF +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/META-INF/MANIFEST.MF @@ -5,14 +5,14 @@ Bundle-Vendor: %Bundle-Vendor Bundle-Version: 1.2.0.qualifier Bundle-Localization: plugin Bundle-SymbolicName: org.eclipse.tracecompass.tmf.analysis.xml.core;singleton:=true -Bundle-Activator: org.eclipse.linuxtools.internal.tmf.analysis.xml.core.Activator +Bundle-Activator: org.eclipse.tracecompass.internal.tmf.analysis.xml.core.Activator Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Bundle-ActivationPolicy: lazy Require-Bundle: org.eclipse.core.runtime, org.eclipse.tracecompass.tmf.core -Export-Package: org.eclipse.linuxtools.internal.tmf.analysis.xml.core;x-friends:="org.eclipse.tracecompass.tmf.analysis.xml.core.tests", - org.eclipse.linuxtools.tmf.analysis.xml.core.model, - org.eclipse.linuxtools.tmf.analysis.xml.core.model.readonly, - org.eclipse.linuxtools.tmf.analysis.xml.core.model.readwrite, - org.eclipse.linuxtools.tmf.analysis.xml.core.module, - org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider +Export-Package: org.eclipse.tracecompass.internal.tmf.analysis.xml.core;x-friends:="org.eclipse.tracecompass.tmf.analysis.xml.core.tests", + org.eclipse.tracecompass.tmf.analysis.xml.core.model, + org.eclipse.tracecompass.tmf.analysis.xml.core.model.readonly, + org.eclipse.tracecompass.tmf.analysis.xml.core.model.readwrite, + org.eclipse.tracecompass.tmf.analysis.xml.core.module, + org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/Activator.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/Activator.java deleted file mode 100644 index 5641c01392..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/Activator.java +++ /dev/null @@ -1,163 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.analysis.xml.core; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Plugin; -import org.eclipse.core.runtime.Status; -import org.osgi.framework.BundleContext; - -/** - * The activator class controls the plug-in life cycle - * - * @author Geneviève Bastien - */ -public class Activator extends Plugin { - - /** The plug-in ID */ - public static final String PLUGIN_ID = "org.eclipse.tracecompass.tmf.analysis.xml.core"; //$NON-NLS-1$ - - // The shared instance - private static Activator fPlugin; - - /** - * The constructor - */ - public Activator() { - setDefault(this); - } - - @Override - public void start(BundleContext context) throws Exception { - super.start(context); - setDefault(this); - } - - @Override - public void stop(BundleContext context) throws Exception { - setDefault(null); - super.stop(context); - } - - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static Activator getDefault() { - return fPlugin; - } - - // Sets plug-in instance - private static void setDefault(Activator plugin) { - fPlugin = plugin; - } - - // ------------------------------------------------------------------------ - // Log an IStatus - // ------------------------------------------------------------------------ - - /** - * Log an IStatus object directly - * - * @param status - * The status to log - */ - public static void log(IStatus status) { - fPlugin.getLog().log(status); - } - - // ------------------------------------------------------------------------ - // Log INFO - // ------------------------------------------------------------------------ - - /** - * Logs a message with severity INFO in the runtime log of the plug-in. - * - * @param message - * A message to log - */ - public static void logInfo(String message) { - fPlugin.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity INFO in the runtime log of the - * plug-in. - * - * @param message - * A message to log - * @param exception - * The corresponding exception - */ - public static void logInfo(String message, Throwable exception) { - fPlugin.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message, exception)); - } - - // ------------------------------------------------------------------------ - // Log WARNING - // ------------------------------------------------------------------------ - - /** - * Logs a message and exception with severity WARNING in the runtime log of - * the plug-in. - * - * @param message - * A message to log - */ - public static void logWarning(String message) { - fPlugin.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity WARNING in the runtime log of - * the plug-in. - * - * @param message - * A message to log - * @param exception - * The corresponding exception - */ - public static void logWarning(String message, Throwable exception) { - fPlugin.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message, exception)); - } - - // ------------------------------------------------------------------------ - // Log ERROR - // ------------------------------------------------------------------------ - - /** - * Logs a message and exception with severity ERROR in the runtime log of - * the plug-in. - * - * @param message - * A message to log - */ - public static void logError(String message) { - fPlugin.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity ERROR in the runtime log of - * the plug-in. - * - * @param message - * A message to log - * @param exception - * The corresponding exception - */ - public static void logError(String message, Throwable exception) { - fPlugin.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, exception)); - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlModelFactory.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlModelFactory.java deleted file mode 100644 index bf7bdde065..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlModelFactory.java +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.model; - -import java.util.List; - -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; -import org.w3c.dom.Element; - -/** - * Interface to create XML model elements in different contexts. This allows to - * reuse the same XML syntax and parsers, but use the elements differently - * depending on the what is intended to be done with them. - * - * @author Geneviève Bastien - */ -public interface ITmfXmlModelFactory { - - /** - * Create a new XML state attribute - * - * @param attribute - * XML element of the attribute - * @param container - * The state system container this state attribute belongs to - * @return The new state attribute - */ - ITmfXmlStateAttribute createStateAttribute(Element attribute, IXmlStateSystemContainer container); - - /** - * Create a new state value where the value corresponds to a path of - * {@link ITmfXmlStateAttribute} - * - * @param node - * The state value XML element - * @param container - * The state system container this state value belongs to - * @param attributes - * The attributes representing the path to this value - * @return The new state value - */ - ITmfXmlStateValue createStateValue(Element node, IXmlStateSystemContainer container, List attributes); - - /** - * Create a new state value where the value corresponds to a field in an - * event - * - * @param node - * The state value XML element - * @param container - * The state system container this state value belongs to - * @param eventField - * The event field where to get the value - * @return The new state value - */ - ITmfXmlStateValue createStateValue(Element node, IXmlStateSystemContainer container, String eventField); - - /** - * Create a new XML condition - * - * @param node - * The XML root of this condition - * @param container - * The state system container this condition belongs to - * @return The new XML condition - */ - TmfXmlCondition createCondition(Element node, IXmlStateSystemContainer container); - - /** - * Create a new XML event handler - * - * @param node - * The XML event handler element - * @param container - * The state system container this state value belongs to - * @return The new XML event handler - */ - TmfXmlEventHandler createEventHandler(Element node, IXmlStateSystemContainer container); - - /** - * Create a new XML state change - * - * @param node - * The XML state change element - * @param container - * The state system container this state change belongs to - * @return The new XML state change - */ - TmfXmlStateChange createStateChange(Element node, IXmlStateSystemContainer container); - - /** - * Create a new XML location - * - * @param node - * The XML location element - * @param container - * The state system container this location belongs to - * @return The new XML location - */ - TmfXmlLocation createLocation(Element node, IXmlStateSystemContainer container); - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlStateAttribute.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlStateAttribute.java deleted file mode 100644 index efb362b793..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlStateAttribute.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.model; - -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; - -/** - * Interface that describe a state attribute defined in an XML element - * - * @author Geneviève Bastien - */ -public interface ITmfXmlStateAttribute { - - /** - * This method gets the quark for this state attribute in the State System. - * - * Unless this attribute is a location, in which case the quark must exist, - * the quark will be added to the state system if the state system is in - * builder mode. - * - * @param startQuark - * root quark, use {@link IXmlStateSystemContainer#ROOT_QUARK} to search - * the full attribute tree - * @return the quark described by attribute or - * {@link IXmlStateSystemContainer#ERROR_QUARK} if quark cannot be found - */ - int getAttributeQuark(int startQuark); - - /** - * This method gets the quark for this state attribute in the State System. - * - * Unless this attribute is a location, in which case the quark must exist, - * the quark will be added to the state system if the state system is in - * builder mode. - * - * @param event - * The current event being handled - * @param startQuark - * root quark, use {@link IXmlStateSystemContainer#ROOT_QUARK} to search - * the full attribute tree - * @return the quark described by attribute or - * {@link IXmlStateSystemContainer#ERROR_QUARK} if quark cannot be found - */ - int getAttributeQuark(ITmfEvent event, int startQuark); -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlStateValue.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlStateValue.java deleted file mode 100644 index 623d1fa3d1..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlStateValue.java +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.model; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; - -/** - * Interface that describe operations on a state value described in an XML - * element - * - * @author Geneviève Bastien - */ -public interface ITmfXmlStateValue { - - /** - * Get the current {@link ITmfStateValue} of this state value for an event. - * It does not increment the value and does not any other processing of the - * value. - * - * @param event - * The current event or null if no event is - * available. - * @return the {@link ITmfStateValue} - * @throws AttributeNotFoundException - * May be thrown by the state system during the query - */ - ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException; - - /** - * Get the value of the event field that is the path of this state value - * - * @param event - * The current event - * @return the value of the event field - */ - ITmfStateValue getEventFieldValue(@NonNull ITmfEvent event); - - /** - * Get the list of state attributes, the path to the state value - * - * @return the list of Attribute to have the path in the State System - */ - List getAttributes(); - - /** - * Handles an event, by setting the value of the attribute described by the - * state attribute path in the state system. - * - * @param event - * The event to process - * @throws AttributeNotFoundException - * Pass through the exception it received - * @throws TimeRangeException - * Pass through the exception it received - * @throws StateValueTypeException - * Pass through the exception it received - */ - void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException; - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlCondition.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlCondition.java deleted file mode 100644 index 71679d2a4b..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlCondition.java +++ /dev/null @@ -1,217 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ecole Polytechnique de Montreal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Florian Wininger - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.model; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.w3c.dom.Element; - -/** - * This Class implement a condition tree in the XML-defined state system. - * - *
- * example:
- * 
- *   
- *       
- *       
- *       
- *   
- *   
- *   
- * 
- * 
- * - * @author Florian Wininger - */ -public class TmfXmlCondition { - - private final List fConditions = new ArrayList<>(); - private final ITmfXmlStateValue fStateValue; - private final ConditionOperator fOperator; - private final IXmlStateSystemContainer fContainer; - - private enum ConditionOperator { - NONE, - NOT, - AND, - OR, - } - - /** - * Constructor - * - * @param modelFactory - * The factory used to create XML model elements - * @param node - * The XML root of this condition - * @param container - * The state system container this condition belongs to - */ - public TmfXmlCondition(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container) { - fContainer = container; - - Element rootNode = node; - /* Process the conditions: in each case, only process Element nodes */ - List childElements = XmlUtils.getChildElements(rootNode); - - /* - * If the node is an if, take the child as the root condition - * - * FIXME: Maybe the caller should do this instead. - */ - if (node.getNodeName().equals(TmfXmlStrings.IF)) { - if (childElements.isEmpty()) { - throw new IllegalArgumentException("TmfXmlCondition constructor: IF node has no child element"); //$NON-NLS-1$ - } - rootNode = childElements.get(0); - childElements = XmlUtils.getChildElements(rootNode); - } - - switch (rootNode.getNodeName()) { - case TmfXmlStrings.CONDITION: - fOperator = ConditionOperator.NONE; - /* The last element is a state value node */ - Element stateValueElement = childElements.remove(childElements.size() - 1); - - /* - * A state value is either preceded by an eventField or a number of - * state attributes - */ - if (childElements.size() == 1 && childElements.get(0).getNodeName().equals(TmfXmlStrings.ELEMENT_FIELD)) { - fStateValue = modelFactory.createStateValue(stateValueElement, fContainer, childElements.get(0).getAttribute(TmfXmlStrings.NAME)); - } else { - List attributes = new ArrayList<>(); - for (Element element : childElements) { - if (!element.getNodeName().equals(TmfXmlStrings.STATE_ATTRIBUTE)) { - throw new IllegalArgumentException("TmfXmlCondition: a condition either has a eventField element or a number of TmfXmlStateAttribute elements before the state value"); //$NON-NLS-1$ - } - ITmfXmlStateAttribute attribute = modelFactory.createStateAttribute(element, fContainer); - attributes.add(attribute); - } - fStateValue = modelFactory.createStateValue(stateValueElement, fContainer, attributes); - } - break; - case TmfXmlStrings.NOT: - fOperator = ConditionOperator.NOT; - fStateValue = null; - fConditions.add(modelFactory.createCondition(childElements.get(0), fContainer)); - break; - case TmfXmlStrings.AND: - fOperator = ConditionOperator.AND; - fStateValue = null; - for (Element condition : childElements) { - fConditions.add(modelFactory.createCondition(condition, fContainer)); - } - break; - case TmfXmlStrings.OR: - fOperator = ConditionOperator.OR; - fStateValue = null; - for (Element condition : childElements) { - fConditions.add(modelFactory.createCondition(condition, fContainer)); - } - break; - default: - throw new IllegalArgumentException("TmfXmlCondition constructor: XML node is of the wrong type"); //$NON-NLS-1$ - } - } - - /** - * Test the result of the condition for an event - * - * @param event - * The event on which to test the condition - * @return Whether the condition is true or not - * @throws AttributeNotFoundException - * The state attribute was not found - */ - public boolean testForEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException { - ITmfStateSystem ss = fContainer.getStateSystem(); - /* - * The condition is either the equality check of a state value or a - * boolean operation on other conditions - */ - if (fStateValue != null) { - ITmfXmlStateValue filter = fStateValue; - int quark = IXmlStateSystemContainer.ROOT_QUARK; - for (ITmfXmlStateAttribute attribute : filter.getAttributes()) { - quark = attribute.getAttributeQuark(event, quark); - /* - * When verifying a condition, the state attribute must exist, - * if it does not, the query is not valid, we stop the condition - * check - */ - if (quark == IXmlStateSystemContainer.ERROR_QUARK) { - throw new AttributeNotFoundException(); - } - } - - /* Get the value to compare to from the XML file */ - ITmfStateValue valueXML; - valueXML = filter.getValue(event); - - /* - * The actual value: it can be either queried in the state system or - * found in the event - */ - ITmfStateValue valueState = (quark != IXmlStateSystemContainer.ROOT_QUARK) ? ss.queryOngoingState(quark) : - filter.getEventFieldValue(event); - - return valueXML.equals(valueState); - - } else if (!fConditions.isEmpty()) { - /* Verify a condition tree */ - switch (fOperator) { - case AND: - for (TmfXmlCondition childCondition : fConditions) { - if (!childCondition.testForEvent(event)) { - return false; - } - } - return true; - case NONE: - break; - case NOT: - return !fConditions.get(0).testForEvent(event); - case OR: - for (TmfXmlCondition childCondition : fConditions) { - if (childCondition.testForEvent(event)) { - return true; - } - } - return false; - default: - break; - - } - } else { - throw new IllegalStateException("TmfXmlCondition: the condition should be either a state value or be the result of a condition tree"); //$NON-NLS-1$ - } - return true; - } - - @Override - public String toString() { - return "TmfXmlCondition: " + fOperator + " on " + fConditions; //$NON-NLS-1$ //$NON-NLS-2$ - } - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlEventHandler.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlEventHandler.java deleted file mode 100644 index 4540fa57ee..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlEventHandler.java +++ /dev/null @@ -1,135 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ecole Polytechnique de Montreal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Florian Wininger - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.model; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.core.Activator; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; - -/** - * This Class implements an EventHandler in the XML-defined state system - * - *
- * example:
- * 
- *  
- *      ...
- *  
- *  
- *      ...
- *  
- * 
- * 
- * - * @author Florian Wininger - */ -public class TmfXmlEventHandler { - - /* list of states changes */ - private final List fStateChangeList = new ArrayList<>(); - private final String fName; - private final IXmlStateSystemContainer fParent; - - /** - * Constructor - * - * @param modelFactory - * The factory used to create XML model elements - * @param node - * XML event handler element - * @param parent - * The state system container this event handler belongs to - */ - public TmfXmlEventHandler(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer parent) { - fParent = parent; - fName = node.getAttribute(TmfXmlStrings.HANDLER_EVENT_NAME); - - NodeList nodesChanges = node.getElementsByTagName(TmfXmlStrings.STATE_CHANGE); - /* load state changes */ - for (int i = 0; i < nodesChanges.getLength(); i++) { - TmfXmlStateChange stateChange = modelFactory.createStateChange((Element) nodesChanges.item(i), fParent); - fStateChangeList.add(stateChange); - } - } - - private boolean appliesToEvent(ITmfEvent event) { - String eventName = event.getType().getName(); - - /* test for full name */ - if (eventName.equals(fName)) { - return true; - } - - /* test for the wildcard at the end */ - if ((fName.endsWith(TmfXmlStrings.WILDCARD) && eventName.startsWith(fName.replace(TmfXmlStrings.WILDCARD, TmfXmlStrings.NULL)))) { - return true; - } - return false; - } - - /** - * If the event handler can handle the event, it applies all state changes - * to modify the state system accordingly - * - * @param event - * The trace event to handle - */ - public void handleEvent(@NonNull ITmfEvent event) { - if (!appliesToEvent(event)) { - return; - } - - /* Process all state changes */ - for (TmfXmlStateChange stateChange : fStateChangeList) { - try { - stateChange.handleEvent(event); - } catch (AttributeNotFoundException ae) { - /* - * This would indicate a problem with the logic of the manager - * here, so it shouldn't happen. - */ - Activator.logError("Attribute not found", ae); //$NON-NLS-1$ - } catch (TimeRangeException tre) { - /* - * This would happen if the events in the trace aren't ordered - * chronologically, which should never be the case ... - */ - Activator.logError("TimeRangeException caught in the state system's event manager. Are the events in the trace correctly ordered?", tre); //$NON-NLS-1$ - } catch (StateValueTypeException sve) { - /* - * This would happen if we were trying to push/pop attributes - * not of type integer. Which, once again, should never happen. - */ - Activator.logError("State value type error", sve); //$NON-NLS-1$ - } - - } - - } - - @Override - public String toString() { - return "TmfXmlEventHandler: " + fName; //$NON-NLS-1$ - } - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlLocation.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlLocation.java deleted file mode 100644 index 817a3bed29..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlLocation.java +++ /dev/null @@ -1,125 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ecole Polytechnique de Montreal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Florian Wininger - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.model; - -import java.util.LinkedList; -import java.util.List; - -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.w3c.dom.Element; - -/** - * This Class implements a Location in the XML-defined state system, ie a named - * shortcut to reach a given attribute, used in state attributes - * - *
- * example:
- *  
- *    
- *    
- *    ...
- *  
- * 
- * - * @author Florian Wininger - */ -public class TmfXmlLocation { - - /** Path in the State System */ - private final List fPath = new LinkedList<>(); - - /** ID : name of the location */ - private final String fId; - private final IXmlStateSystemContainer fContainer; - - /** - * Constructor - * - * @param modelFactory - * The factory used to create XML model elements - * @param location - * XML node element - * @param container - * The state system container this location belongs to - */ - public TmfXmlLocation(ITmfXmlModelFactory modelFactory, Element location, IXmlStateSystemContainer container) { - fId = location.getAttribute(TmfXmlStrings.ID); - fContainer = container; - - List childElements = XmlUtils.getChildElements(location); - for (Element attribute : childElements) { - ITmfXmlStateAttribute xAttribute = modelFactory.createStateAttribute(attribute, fContainer); - fPath.add(xAttribute); - } - } - - /** - * Get the id of the location - * - * @return The id of a location - */ - public String getId() { - return fId; - } - - /** - * Get the quark for the path represented by this location - * - * @param event - * The event being handled - * @param startQuark - * The starting quark for relative search, use - * {@link IXmlStateSystemContainer#ROOT_QUARK} for the root of - * the attribute tree - * @return The quark at the leaf of the path - */ - public int getLocationQuark(ITmfEvent event, int startQuark) { - int quark = startQuark; - for (ITmfXmlStateAttribute attrib : fPath) { - quark = attrib.getAttributeQuark(event, quark); - if (quark == IXmlStateSystemContainer.ERROR_QUARK) { - break; - } - } - return quark; - } - - /** - * Get the quark for the path represented by this location - * - * @param startQuark - * The starting quark for relative search, use - * {@link IXmlStateSystemContainer#ROOT_QUARK} for the root of - * the attribute tree - * @return The quark at the leaf of the path - */ - public int getLocationQuark(int startQuark) { - int quark = startQuark; - for (ITmfXmlStateAttribute attrib : fPath) { - quark = attrib.getAttributeQuark(quark); - if (quark == IXmlStateSystemContainer.ERROR_QUARK) { - break; - } - } - return quark; - } - - @Override - public String toString() { - return "TmfXmlLocation " + fId + ": " + fPath; //$NON-NLS-1$ //$NON-NLS-2$ - } - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateAttribute.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateAttribute.java deleted file mode 100644 index 020b4311e0..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateAttribute.java +++ /dev/null @@ -1,327 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ecole Polytechnique de Montreal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Florian Wininger - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.model; - -import java.util.LinkedList; -import java.util.List; - -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.core.Activator; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.w3c.dom.Element; - -/** - * This Class implements a single attribute value in the XML-defined state - * system. - * - *
- * Examples:
- * 
- * 
- *      
- *      
- *      
- * 
- * 
- * - * @author Florian Wininger - */ -public abstract class TmfXmlStateAttribute implements ITmfXmlStateAttribute { - - private enum StateAttributeType { - NONE, - CONSTANT, - EVENTFIELD, - QUERY, - LOCATION, - SELF - } - - /** Type of attribute */ - private final StateAttributeType fType; - - /** Attribute's name */ - private final String fName; - - /** List of attributes for a query */ - private final List fQueryList = new LinkedList<>(); - - private final IXmlStateSystemContainer fContainer; - - /** - * Constructor - * - * @param modelFactory - * The factory used to create XML model elements - * @param attribute - * XML element of the attribute - * @param container - * The state system container this state attribute belongs to - */ - protected TmfXmlStateAttribute(ITmfXmlModelFactory modelFactory, Element attribute, IXmlStateSystemContainer container) { - fContainer = container; - - switch (attribute.getAttribute(TmfXmlStrings.TYPE)) { - case TmfXmlStrings.TYPE_CONSTANT: - fType = StateAttributeType.CONSTANT; - fName = fContainer.getAttributeValue(attribute.getAttribute(TmfXmlStrings.VALUE)); - break; - case TmfXmlStrings.EVENT_FIELD: - fType = StateAttributeType.EVENTFIELD; - fName = fContainer.getAttributeValue(attribute.getAttribute(TmfXmlStrings.VALUE)); - break; - case TmfXmlStrings.TYPE_LOCATION: - fType = StateAttributeType.LOCATION; - fName = fContainer.getAttributeValue(attribute.getAttribute(TmfXmlStrings.VALUE)); - break; - case TmfXmlStrings.TYPE_QUERY: - List childElements = XmlUtils.getChildElements(attribute); - for (Element subAttributeNode : childElements) { - ITmfXmlStateAttribute subAttribute = modelFactory.createStateAttribute(subAttributeNode, fContainer); - fQueryList.add(subAttribute); - } - fType = StateAttributeType.QUERY; - fName = null; - break; - case TmfXmlStrings.NULL: - fType = StateAttributeType.NONE; - fName = null; - break; - case TmfXmlStrings.TYPE_SELF: - fType = StateAttributeType.SELF; - fName = null; - break; - default: - throw new IllegalArgumentException("TmfXmlStateAttribute constructor: The XML element is not of the right type"); //$NON-NLS-1$ - } - } - - /** - * This method gets the quark for this state attribute in the State System. - * - * Unless this attribute is a location, in which case the quark must exist, - * the quark will be added to the state system if the state system is in - * builder mode. - * - * @param startQuark - * root quark, use {@link IXmlStateSystemContainer#ROOT_QUARK} to - * search the full attribute tree - * @return the quark described by attribute or - * {@link IXmlStateSystemContainer#ERROR_QUARK} if quark cannot be - * found - */ - @Override - public int getAttributeQuark(int startQuark) { - return getAttributeQuark(null, startQuark); - } - - /** - * Basic quark-retrieving method. Pass an attribute in parameter as an array - * of strings, the matching quark will be returned. If the attribute does - * not exist, it will add the quark to the state system if the context - * allows it. - * - * See {@link ITmfStateSystemBuilder#getQuarkAbsoluteAndAdd(String...)} - * - * @param path - * Full path to the attribute - * @return The quark for this attribute - * @throws AttributeNotFoundException - * The attribute does not exist and cannot be added - */ - protected abstract int getQuarkAbsoluteAndAdd(String... path) throws AttributeNotFoundException; - - /** - * Quark-retrieving method, but the attribute is queried starting from the - * startNodeQuark. If the attribute does not exist, it will add it to the - * state system if the context allows it. - * - * See {@link ITmfStateSystemBuilder#getQuarkRelativeAndAdd(int, String...)} - * - * @param startNodeQuark - * The quark of the attribute from which 'path' originates. - * @param path - * Relative path to the attribute - * @return The quark for this attribute - * @throws AttributeNotFoundException - * The attribute does not exist and cannot be added - */ - protected abstract int getQuarkRelativeAndAdd(int startNodeQuark, String... path) throws AttributeNotFoundException; - - /** - * Get the state system associated with this attribute's container - * - * @return The state system associated with this state attribute - */ - protected ITmfStateSystem getStateSystem() { - return fContainer.getStateSystem(); - } - - /** - * This method gets the quark for this state attribute in the State System. - * - * Unless this attribute is a location, in which case the quark must exist, - * the quark will be added to the state system if the state system is in - * builder mode. - * - * @param event - * The current event being handled, or null if no - * event available in the context - * @param startQuark - * root quark, use {@link IXmlStateSystemContainer#ROOT_QUARK} to - * search the full attribute tree - * @return the quark described by attribute or - * {@link IXmlStateSystemContainer#ERROR_QUARK} if quark cannot be - * found - */ - @Override - public int getAttributeQuark(@Nullable ITmfEvent event, int startQuark) { - ITmfStateSystem ss = getStateSystem(); - - try { - switch (fType) { - case CONSTANT: { - int quark; - if (startQuark == IXmlStateSystemContainer.ROOT_QUARK) { - quark = getQuarkAbsoluteAndAdd(fName); - } else { - quark = getQuarkRelativeAndAdd(startQuark, fName); - } - return quark; - } - case EVENTFIELD: { - int quark = IXmlStateSystemContainer.ERROR_QUARK; - if (event == null) { - Activator.logWarning("XML State attribute: looking for an event field, but event is null"); //$NON-NLS-1$ - return quark; - } - /* special case if field is CPU which is not in the field */ - if (fName.equals(TmfXmlStrings.CPU)) { - quark = getQuarkRelativeAndAdd(startQuark, event.getSource()); - } else { - final ITmfEventField content = event.getContent(); - /* stop if the event field doesn't exist */ - if (content.getField(fName) == null) { - return IXmlStateSystemContainer.ERROR_QUARK; - } - - Object field = content.getField(fName).getValue(); - - if (field instanceof String) { - String fieldString = (String) field; - quark = getQuarkRelativeAndAdd(startQuark, fieldString); - } else if (field instanceof Long) { - Long fieldLong = (Long) field; - quark = getQuarkRelativeAndAdd(startQuark, fieldLong.toString()); - } else if (field instanceof Integer) { - Integer fieldInterger = (Integer) field; - quark = getQuarkRelativeAndAdd(startQuark, fieldInterger.toString()); - } - } - return quark; - } - case QUERY: { - int quark; - ITmfStateValue value = TmfStateValue.nullValue(); - int quarkQuery = IXmlStateSystemContainer.ROOT_QUARK; - - for (ITmfXmlStateAttribute attrib : fQueryList) { - quarkQuery = attrib.getAttributeQuark(event, quarkQuery); - if (quarkQuery == IXmlStateSystemContainer.ERROR_QUARK) { - break; - } - } - - // the query may fail: for example CurrentThread if there - // has not been a sched_switch event - if (quarkQuery != IXmlStateSystemContainer.ERROR_QUARK) { - value = ss.queryOngoingState(quarkQuery); - } - - switch (value.getType()) { - case INTEGER: { - int result = value.unboxInt(); - quark = getQuarkRelativeAndAdd(startQuark, String.valueOf(result)); - break; - } - case LONG: { - long result = value.unboxLong(); - quark = getQuarkRelativeAndAdd(startQuark, String.valueOf(result)); - break; - } - case STRING: { - String result = value.unboxStr(); - quark = getQuarkRelativeAndAdd(startQuark, result); - break; - } - case DOUBLE: - case NULL: - default: - quark = IXmlStateSystemContainer.ERROR_QUARK; // error - break; - } - return quark; - } - case LOCATION: { - int quark = startQuark; - String idLocation = fName; - - /* TODO: Add a fContainer.getLocation(id) method */ - for (TmfXmlLocation location : fContainer.getLocations()) { - if (location.getId().equals(idLocation)) { - quark = location.getLocationQuark(event, quark); - if (quark == IXmlStateSystemContainer.ERROR_QUARK) { - break; - } - } - } - return quark; - } - case SELF: - return startQuark; - case NONE: - default: - return startQuark; - } - } catch (AttributeNotFoundException ae) { - /* - * This can be happen before the creation of the node for a query in - * the state system. Example : current thread before a sched_switch - */ - return IXmlStateSystemContainer.ERROR_QUARK; - } catch (StateValueTypeException e) { - /* - * This would happen if we were trying to push/pop attributes not of - * type integer. Which, once again, should never happen. - */ - Activator.logError("StateValueTypeException", e); //$NON-NLS-1$ - return IXmlStateSystemContainer.ERROR_QUARK; - } - } - - @Override - public String toString() { - return "TmfXmlStateAttribute " + fType + ": " + fName; //$NON-NLS-1$ //$NON-NLS-2$ - } - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateChange.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateChange.java deleted file mode 100644 index f21e322381..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateChange.java +++ /dev/null @@ -1,218 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ecole Polytechnique de Montreal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Florian Wininger - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.model; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -/** - * This Class implement a State Change in the XML-defined state system - * - *
- *  example 1: Simple state change
- *  
- *      
- *      
- *      
- *  
- *
- *  example 2: Conditional state change
- *  
- *     
- *      
- *        
- *        
- *        
- *      
- *     
- *    
- *      
- *      
- *      
- *    
- *    
- *      
- *      
- *      
- *    
- *  
- * 
- * - * @author Florian Wininger - */ -public class TmfXmlStateChange { - - private final IXmlStateChange fChange; - private final IXmlStateSystemContainer fContainer; - - /** - * Constructor - * - * @param modelFactory - * The factory used to create XML model elements - * @param statechange - * XML node root of this state change - * @param container - * The state system container this state change belongs to - */ - public TmfXmlStateChange(ITmfXmlModelFactory modelFactory, Element statechange, IXmlStateSystemContainer container) { - fContainer = container; - - /* - * child nodes is either a list of TmfXmlStateAttributes and - * TmfXmlStateValues, or an if-then-else series of nodes. - */ - Node ifNode = statechange.getElementsByTagName(TmfXmlStrings.IF).item(0); - if (ifNode != null) { - /* the state change has a condition */ - fChange = new XmlConditionalChange(modelFactory, statechange); - } else { - /* the state change does not have a condition */ - fChange = new XmlStateValueChange(modelFactory, statechange); - } - } - - /** - * Execute the state change for an event. If necessary, it validates the - * condition and executes the required change. - * - * @param event - * The event to process - * @throws AttributeNotFoundException - * Pass through the exception it received - * @throws TimeRangeException - * Pass through the exception it received - * @throws StateValueTypeException - * Pass through the exception it received - */ - public void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException { - fChange.handleEvent(event); - } - - @Override - public String toString() { - return "TmfXmlStateChange: " + fChange; //$NON-NLS-1$ - } - - /* Interface for both private classes to handle the event */ - private interface IXmlStateChange { - void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException; - } - - /** - * Conditional state change with a condition to verify - */ - private class XmlConditionalChange implements IXmlStateChange { - private final TmfXmlCondition fCondition; - private final TmfXmlStateChange fThenChange; - private final TmfXmlStateChange fElseChange; - - public XmlConditionalChange(ITmfXmlModelFactory modelFactory, Element statechange) { - /* - * The if node exists, it has been verified before calling this - */ - Node ifNode = statechange.getElementsByTagName(TmfXmlStrings.IF).item(0); - fCondition = modelFactory.createCondition((Element) ifNode, fContainer); - - Node thenNode = statechange.getElementsByTagName(TmfXmlStrings.THEN).item(0); - if (thenNode == null) { - throw new IllegalArgumentException("Conditional state change: there should be a then clause."); //$NON-NLS-1$ - } - fThenChange = modelFactory.createStateChange((Element) thenNode, fContainer); - - Node elseNode = statechange.getElementsByTagName(TmfXmlStrings.ELSE).item(0); - if (elseNode != null) { - fElseChange = modelFactory.createStateChange((Element) elseNode, fContainer); - } else { - fElseChange = null; - } - } - - @Override - public void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException { - TmfXmlStateChange toExecute = fThenChange; - try { - if (!fCondition.testForEvent(event)) { - toExecute = fElseChange; - } - } catch (AttributeNotFoundException e) { - /* - * An attribute in the condition did not exist (yet), return - * from the state change - */ - return; - } - - if (toExecute == null) { - return; - } - toExecute.handleEvent(event); - } - - @Override - public String toString() { - return "Condition: " + fCondition; //$NON-NLS-1$ - } - } - - /** - * State change with no condition - */ - private class XmlStateValueChange implements IXmlStateChange { - private final ITmfXmlStateValue fValue; - - public XmlStateValueChange(ITmfXmlModelFactory modelFactory, Element statechange) { - List childElements = XmlUtils.getChildElements(statechange); - - /* - * Last child element is the state value, the others are attributes - * to reach to value to set - */ - Element stateValueElement = childElements.remove(childElements.size() - 1); - List attributes = new ArrayList<>(); - for (Element element : childElements) { - if (!element.getNodeName().equals(TmfXmlStrings.STATE_ATTRIBUTE)) { - throw new IllegalArgumentException("TmfXmlStateChange: a state change must have only TmfXmlStateAttribute elements before the state value"); //$NON-NLS-1$ - } - ITmfXmlStateAttribute attribute = modelFactory.createStateAttribute(element, fContainer); - attributes.add(attribute); - } - if (attributes.isEmpty()) { - throw new IllegalArgumentException("TmfXmlStateChange: a state change must have at least one TmfXmlStateAttribute element before the state value"); //$NON-NLS-1$ - } - fValue = modelFactory.createStateValue(stateValueElement, fContainer, attributes); - } - - @Override - public void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException { - fValue.handleEvent(event); - } - - @Override - public String toString() { - return "Value: " + fValue; //$NON-NLS-1$ - } - } - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateValue.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateValue.java deleted file mode 100644 index 2b30ca9f06..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateValue.java +++ /dev/null @@ -1,495 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ecole Polytechnique de Montreal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Florian Wininger - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.model; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.w3c.dom.Element; - -/** - * This Class implements a State Value in the XML-defined state system, along - * with the path to get to the value (either a list of state attributes or an - * event field) - * - *
- * Example:
- *   
- *   
- *   
- * 
- * - * @author Florian Wininger - */ -public abstract class TmfXmlStateValue implements ITmfXmlStateValue { - - private final TmfXmlStateValueBase fStateValue; - - /* Path in the State System */ - private final List fPath; - /* Event field to match with this state value */ - private final String fEventField; - - /* Whether this state value is an increment of the previous value */ - private final boolean fIncrement; - /* Stack value */ - private final ValueTypeStack fStackType; - /* Forced value type */ - private final ITmfStateValue.Type fForcedType; - - private final IXmlStateSystemContainer fContainer; - - /** - * Different behaviors of an attribute that is to be stacked - */ - protected enum ValueTypeStack { - /** Not stacked */ - NULL, - /** Peek at the value at the top of the stack */ - PEEK, - /** Take the value at the top of the stack */ - POP, - /** Push the value on the stack */ - PUSH; - - /** - * Get the type stack value corresponding to a string - * - * @param input - * The string to match to a value - * @return The ValueTypeStack value - */ - public static ValueTypeStack getTypeFromString(String input) { - switch (input) { - case TmfXmlStrings.STACK_PUSH: - return PUSH; - case TmfXmlStrings.STACK_POP: - return POP; - case TmfXmlStrings.STACK_PEEK: - return PEEK; - default: - return NULL; - } - } - } - - /** - * Constructor - * - * @param modelFactory - * The factory used to create XML model elements - * @param node - * The state value XML element - * @param container - * The state system container this state value belongs to - * @param eventField - * The event field where to get the value - * @param attributes - * The attributes representing the path to this value - */ - protected TmfXmlStateValue(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container, List attributes, String eventField) { - fPath = attributes; - fContainer = container; - fEventField = eventField; - if (!node.getNodeName().equals(TmfXmlStrings.STATE_VALUE)) { - throw new IllegalArgumentException("TmfXmlStateValue constructor: Element is not a stateValue"); //$NON-NLS-1$ - } - - /* Check if there is an increment for the value */ - fIncrement = Boolean.parseBoolean(node.getAttribute(TmfXmlStrings.INCREMENT)); - - /* Process the XML Element state value */ - fStateValue = initializeStateValue(modelFactory, node); - - /* - * Forced type allows to convert the value to a certain type : For - * example, a process's TID in an event field may arrive with a LONG - * format but we want to store the data in an INT - */ - switch (node.getAttribute(TmfXmlStrings.FORCED_TYPE)) { - case TmfXmlStrings.TYPE_STRING: - fForcedType = ITmfStateValue.Type.STRING; - break; - case TmfXmlStrings.TYPE_INT: - fForcedType = ITmfStateValue.Type.INTEGER; - break; - case TmfXmlStrings.TYPE_LONG: - fForcedType = ITmfStateValue.Type.LONG; - break; - default: - fForcedType = ITmfStateValue.Type.NULL; - } - - /* - * Stack Actions : allow to define a stack with PUSH/POP/PEEK methods - */ - String stack = node.getAttribute(TmfXmlStrings.ATTRIBUTE_STACK); - fStackType = ValueTypeStack.getTypeFromString(stack); - } - - /** - * Initialize a {@link TmfXmlStateValueBase} object for the type and value - * - * @param modelFactory - * The factory used to create XML model elements - * @param node - * The state value XML element - * @return The internal state value type corresponding to this state value - */ - protected TmfXmlStateValueBase initializeStateValue(ITmfXmlModelFactory modelFactory, Element node) { - return new TmfXmlStateValueNull(); - } - - /** - * Return the state system container this class is attached to - * - * @return The state system container - */ - protected IXmlStateSystemContainer getSsContainer() { - return fContainer; - } - - /** - * Get the state system associated with this value's container - * - * @return The state system associated with the state system container - */ - protected ITmfStateSystem getStateSystem() { - return fContainer.getStateSystem(); - } - - /** - * Return whether this value is an increment of the previous value - * - * @return true if the value is an increment - */ - protected boolean isIncrement() { - return fIncrement; - } - - /** - * Get the stack type of this attribute. If the attribute is to be pushed or - * popped to a stack. The behavior of the stack attribute will depend on the - * implementation of the model. - * - * @return The stack type of the attribute - */ - protected ValueTypeStack getStackType() { - return fStackType; - } - - /** - * Get the forced type of the value. For example, if the value obtained from - * the attributes is not in this forced type, it will be converted to this. - * - * @return The desired type of the value - */ - protected ITmfStateValue.Type getForcedType() { - return fForcedType; - } - - /** - * Get the current {@link ITmfStateValue} of this state value for an event. - * It does not increment the value and does not any other processing of the - * value. - * - * @param event - * The current event, or null if no event available. - * @return the {@link ITmfStateValue} - * @throws AttributeNotFoundException - * May be thrown by the state system during the query - */ - @Override - public ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException { - return fStateValue.getValue(event); - } - - /** - * Get the value of the event field that is the path of this state value - * - * @param event - * The current event - * @return the value of the event field - */ - @Override - public ITmfStateValue getEventFieldValue(@NonNull ITmfEvent event) { - return getEventFieldValue(event, fEventField); - } - - /** - * Get the value of an event field - * - * @param event - * The current event - * @param fieldName - * The name of the field of which to get the value - * @return The value of the event field - */ - protected ITmfStateValue getEventFieldValue(@NonNull ITmfEvent event, String fieldName) { - - ITmfStateValue value = TmfStateValue.nullValue(); - - final ITmfEventField content = event.getContent(); - - /* Exception for "CPU", returns the source of this event */ - /* FIXME : Nameclash if a eventfield have "cpu" for name. */ - if (fieldName.equals(TmfXmlStrings.CPU)) { - return TmfStateValue.newValueInt(Integer.valueOf(event.getSource())); - } - /* Exception also for "TIMESTAMP", returns the timestamp of this event */ - if (fieldName.equals(TmfXmlStrings.TIMESTAMP)) { - return TmfStateValue.newValueLong(event.getTimestamp().getValue()); - } - if (content.getField(fieldName) == null) { - return value; - } - - Object field = content.getField(fieldName).getValue(); - - /* - * Try to find the right type. The type can be forced by - * "forcedType" argument. - */ - - if (field instanceof String) { - String fieldString = (String) field; - - switch (fForcedType) { - case INTEGER: - value = TmfStateValue.newValueInt(Integer.parseInt(fieldString)); - break; - case LONG: - value = TmfStateValue.newValueLong(Long.parseLong(fieldString)); - break; - case DOUBLE: - value = TmfStateValue.newValueDouble(Double.parseDouble(fieldString)); - break; - case NULL: - case STRING: - default: - value = TmfStateValue.newValueString(fieldString); - break; - } - } else if (field instanceof Long) { - Long fieldLong = (Long) field; - - switch (fForcedType) { - case INTEGER: - value = TmfStateValue.newValueInt(fieldLong.intValue()); - break; - case STRING: - value = TmfStateValue.newValueString(fieldLong.toString()); - break; - case DOUBLE: - value = TmfStateValue.newValueDouble(fieldLong.doubleValue()); - break; - case LONG: - case NULL: - default: - value = TmfStateValue.newValueLong(fieldLong); - break; - } - } else if (field instanceof Integer) { - Integer fieldInteger = (Integer) field; - - switch (fForcedType) { - case LONG: - value = TmfStateValue.newValueLong(fieldInteger.longValue()); - break; - case STRING: - value = TmfStateValue.newValueString(fieldInteger.toString()); - break; - case DOUBLE: - value = TmfStateValue.newValueDouble(fieldInteger.doubleValue()); - break; - case INTEGER: - case NULL: - default: - value = TmfStateValue.newValueInt(fieldInteger); - break; - } - } else if (field instanceof Double) { - Double fieldDouble = (Double) field; - - switch (fForcedType) { - case LONG: - value = TmfStateValue.newValueLong(fieldDouble.longValue()); - break; - case STRING: - value = TmfStateValue.newValueString(fieldDouble.toString()); - break; - case INTEGER: - value = TmfStateValue.newValueInt(fieldDouble.intValue()); - break; - case DOUBLE: - case NULL: - default: - value = TmfStateValue.newValueDouble(fieldDouble); - break; - } - } - return value; - } - - /** - * Get the list of state attributes, the path to the state value - * - * @return the list of Attribute to have the path in the State System - */ - @Override - public List getAttributes() { - return fPath; - } - - /** - * Handles an event, by setting the value of the attribute described by the - * state attribute path in the state system. - * - * @param event - * The event to process - * @throws AttributeNotFoundException - * Pass through the exception it received - * @throws TimeRangeException - * Pass through the exception it received - * @throws StateValueTypeException - * Pass through the exception it received - */ - @Override - public void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException { - int quark = IXmlStateSystemContainer.ROOT_QUARK; - - for (ITmfXmlStateAttribute attribute : fPath) { - quark = attribute.getAttributeQuark(event, quark); - /* the query is not valid, we stop the state change */ - if (quark == IXmlStateSystemContainer.ERROR_QUARK) { - throw new AttributeNotFoundException("Not found XML attribute " + attribute); //$NON-NLS-1$ - } - } - - long ts = event.getTimestamp().getValue(); - fStateValue.handleEvent(event, quark, ts); - } - - @Override - public String toString() { - return "TmfXmlStateValue: " + fStateValue; //$NON-NLS-1$ - } - - /** - * Base class for all state values. Contain default methods to handle event, - * process or increment the value - */ - protected abstract class TmfXmlStateValueBase { - - /** - * Get the value associated with this state value. - * - * @param event - * The event which can be used to retrieve the value if - * necessary. The event can be null if no event - * is required. - * @return The state value corresponding to this XML state value - * @throws AttributeNotFoundException - * Pass through the exception it received - */ - public abstract ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException; - - /** - * Do something with the state value, possibly using an event - * - * @param event - * The event being handled. If there is no event is - * available, use null. - * @param quark - * The quark for this value - * @param timestamp - * The timestamp of the event - * @throws StateValueTypeException - * Pass through the exception it received - * @throws TimeRangeException - * Pass through the exception it received - * @throws AttributeNotFoundException - * Pass through the exception it received - */ - public void handleEvent(@NonNull ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { - if (fIncrement) { - incrementValue(event, quark, timestamp); - } else { - ITmfStateValue value = getValue(event); - processValue(quark, timestamp, value); - } - } - - /** - * Set the value of a quark at a given timestamp. - * - * @param quark - * The quark for this value - * @param timestamp - * The timestamp - * @param value - * The value of this state value - * @throws TimeRangeException - * Pass through the exception it received - * @throws StateValueTypeException - * Pass through the exception it received - * @throws AttributeNotFoundException - * Pass through the exception it received - */ - @SuppressWarnings("unused") - protected void processValue(int quark, long timestamp, ITmfStateValue value) throws TimeRangeException, StateValueTypeException, AttributeNotFoundException { - } - - /** - * Increments the value of the parameter - * - * @param event - * The event being handled - * @param quark - * The quark for this value - * @param timestamp - * The timestamp of the event - * @throws StateValueTypeException - * Pass through the exception it received - * @throws TimeRangeException - * Pass through the exception it received - * @throws AttributeNotFoundException - * Pass through the exception it received - */ - @SuppressWarnings("unused") - protected void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { - } - } - - /* This state value uses a constant value, defined in the XML */ - private class TmfXmlStateValueNull extends TmfXmlStateValueBase { - - @Override - public ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException { - return TmfStateValue.nullValue(); - } - - } - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyModelFactory.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyModelFactory.java deleted file mode 100644 index df6be51284..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyModelFactory.java +++ /dev/null @@ -1,88 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.model.readonly; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlModelFactory; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlStateAttribute; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlStateValue; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlCondition; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlEventHandler; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlLocation; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlStateChange; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.readwrite.TmfXmlReadWriteModelFactory; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; -import org.w3c.dom.Element; - -/** - * Concrete factory for XML model elements in read only mode - * - * @author Geneviève Bastien - */ -public class TmfXmlReadOnlyModelFactory implements ITmfXmlModelFactory { - - private static ITmfXmlModelFactory fInstance = null; - - /** - * Get the instance of this model creator - * - * @return The {@link TmfXmlReadWriteModelFactory} instance - */ - @NonNull - public static synchronized ITmfXmlModelFactory getInstance() { - ITmfXmlModelFactory instance = fInstance; - if (instance == null) { - instance = new TmfXmlReadOnlyModelFactory(); - fInstance = instance; - } - return instance; - } - - @Override - public ITmfXmlStateAttribute createStateAttribute(Element attribute, IXmlStateSystemContainer container) { - return new TmfXmlReadOnlyStateAttribute(this, attribute, container); - } - - @Override - public ITmfXmlStateValue createStateValue(Element node, IXmlStateSystemContainer container, List attributes) { - return new TmfXmlReadOnlyStateValue(this, node, container, attributes); - } - - @Override - public ITmfXmlStateValue createStateValue(Element node, IXmlStateSystemContainer container, String eventField) { - return new TmfXmlReadOnlyStateValue(this, node, container, eventField); - } - - @Override - public TmfXmlCondition createCondition(Element node, IXmlStateSystemContainer container) { - return new TmfXmlCondition(this, node, container); - } - - @Override - public TmfXmlEventHandler createEventHandler(Element node, IXmlStateSystemContainer container) { - return new TmfXmlEventHandler(this, node, container); - } - - @Override - public TmfXmlStateChange createStateChange(Element node, IXmlStateSystemContainer container) { - return new TmfXmlStateChange(this, node, container); - } - - @Override - public TmfXmlLocation createLocation(Element node, IXmlStateSystemContainer container) { - return new TmfXmlLocation(this, node, container); - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyStateAttribute.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyStateAttribute.java deleted file mode 100644 index e3d53f39fb..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyStateAttribute.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.model.readonly; - -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlStateAttribute; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; -import org.w3c.dom.Element; - -/** - * Implements a state attribute in a read only mode. See - * {@link TmfXmlStateAttribute} for the syntax of this attribute. - * - * In read-only mode, attributes that are requested but do not exist in the - * state system will not be added. - * - * @author Geneviève Bastien - */ -public class TmfXmlReadOnlyStateAttribute extends TmfXmlStateAttribute { - - /** - * Constructor - * - * @param modelFactory - * The factory used to create XML model elements - * @param attribute - * The XML element corresponding to this attribute - * @param container - * The state system container this state value belongs to - */ - public TmfXmlReadOnlyStateAttribute(TmfXmlReadOnlyModelFactory modelFactory, Element attribute, IXmlStateSystemContainer container) { - super(modelFactory, attribute, container); - } - - @Override - protected int getQuarkAbsoluteAndAdd(String... path) throws AttributeNotFoundException { - return getStateSystem().getQuarkAbsolute(path); - } - - @Override - protected int getQuarkRelativeAndAdd(int startNodeQuark, String... path) throws AttributeNotFoundException { - return getStateSystem().getQuarkRelative(startNodeQuark, path); - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyStateValue.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyStateValue.java deleted file mode 100644 index 99f3f8d041..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyStateValue.java +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.model.readonly; - -import java.util.Collections; -import java.util.List; - -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlStateAttribute; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlStateValue; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; -import org.w3c.dom.Element; - -/** - * Implements a state value is a read only mode. See {@link TmfXmlStateValue} - * for the syntax of the state value. - * - * In read mode, a state value will typically be used to find a path to a value, - * so the value is known and there is a path of attributes that should lead to - * it. - * - * @author Geneviève Bastien - */ -public class TmfXmlReadOnlyStateValue extends TmfXmlStateValue { - - /** - * Constructor where the path to the value is a list of state attributes - * - * @param modelFactory - * The factory used to create XML model elements - * @param node - * The state value XML element - * @param container - * The state system container this state value belongs to - * @param attributes - * The attributes representing the path to this value - */ - public TmfXmlReadOnlyStateValue(TmfXmlReadOnlyModelFactory modelFactory, Element node, - IXmlStateSystemContainer container, List attributes) { - super(modelFactory, node, container, attributes, null); - } - - /** - * Constructor where the path to the value is an event field - * - * @param modelFactory - * The factory used to create XML model elements - * @param node - * The state value XML element - * @param container - * The state system container this state value belongs to - * @param eventField - * The event field where to get the value - */ - public TmfXmlReadOnlyStateValue(TmfXmlReadOnlyModelFactory modelFactory, Element node, - IXmlStateSystemContainer container, String eventField) { - super(modelFactory, node, container, Collections.EMPTY_LIST, eventField); - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteModelFactory.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteModelFactory.java deleted file mode 100644 index 1380bf08f2..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteModelFactory.java +++ /dev/null @@ -1,87 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.model.readwrite; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlModelFactory; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlStateAttribute; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlStateValue; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlCondition; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlEventHandler; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlLocation; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlStateChange; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; -import org.w3c.dom.Element; - -/** - * Concrete factory for XML model elements in read write mode - * - * @author Geneviève Bastien - */ -public class TmfXmlReadWriteModelFactory implements ITmfXmlModelFactory { - - private static ITmfXmlModelFactory fInstance = null; - - /** - * Get the instance of this model creator - * - * @return The {@link TmfXmlReadWriteModelFactory} instance - */ - @NonNull - public static synchronized ITmfXmlModelFactory getInstance() { - ITmfXmlModelFactory instance = fInstance; - if (instance == null) { - instance = new TmfXmlReadWriteModelFactory(); - fInstance = instance; - } - return instance; - } - - @Override - public ITmfXmlStateAttribute createStateAttribute(Element attribute, IXmlStateSystemContainer container) { - return new TmfXmlReadWriteStateAttribute(this, attribute, container); - } - - @Override - public ITmfXmlStateValue createStateValue(Element node, IXmlStateSystemContainer container, List attributes) { - return new TmfXmlReadWriteStateValue(this, node, container, attributes); - } - - @Override - public ITmfXmlStateValue createStateValue(Element node, IXmlStateSystemContainer container, String eventField) { - return new TmfXmlReadWriteStateValue(this, node, container, eventField); - } - - @Override - public TmfXmlCondition createCondition(Element node, IXmlStateSystemContainer container) { - return new TmfXmlCondition(this, node, container); - } - - @Override - public TmfXmlEventHandler createEventHandler(Element node, IXmlStateSystemContainer container) { - return new TmfXmlEventHandler(this, node, container); - } - - @Override - public TmfXmlStateChange createStateChange(Element node, IXmlStateSystemContainer container) { - return new TmfXmlStateChange(this, node, container); - } - - @Override - public TmfXmlLocation createLocation(Element node, IXmlStateSystemContainer container) { - return new TmfXmlLocation(this, node, container); - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteStateAttribute.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteStateAttribute.java deleted file mode 100644 index 4303f50c15..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteStateAttribute.java +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.model.readwrite; - -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlStateAttribute; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; -import org.w3c.dom.Element; - -/** - * Implements a state attribute in a read write mode. See - * {@link TmfXmlStateAttribute} for the syntax of this attribute. - * - * In read-write mode, attributes that are requested but do not exist are added - * to the state system. - * - * @author Geneviève Bastien - */ -public class TmfXmlReadWriteStateAttribute extends TmfXmlStateAttribute { - - /** - * Constructor - * - * @param modelFactory - * The factory used to create XML model elements - * @param attribute - * The XML element corresponding to this attribute - * @param container - * The state system container this state value belongs to - */ - public TmfXmlReadWriteStateAttribute(TmfXmlReadWriteModelFactory modelFactory, Element attribute, IXmlStateSystemContainer container) { - super(modelFactory, attribute, container); - } - - @Override - protected ITmfStateSystemBuilder getStateSystem() { - return (ITmfStateSystemBuilder) super.getStateSystem(); - } - - @Override - protected int getQuarkAbsoluteAndAdd(String... path) throws AttributeNotFoundException { - return getStateSystem().getQuarkAbsoluteAndAdd(path); - } - - @Override - protected int getQuarkRelativeAndAdd(int startNodeQuark, String... path) throws AttributeNotFoundException { - return getStateSystem().getQuarkRelativeAndAdd(startNodeQuark, path); - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteStateValue.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteStateValue.java deleted file mode 100644 index 18c8a58bbd..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteStateValue.java +++ /dev/null @@ -1,375 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.model.readwrite; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.linuxtools.internal.tmf.analysis.xml.core.Activator; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlModelFactory; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlStateAttribute; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlStateValue; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.w3c.dom.Element; - -/** - * Implements a state value in a read write mode. See {@link TmfXmlStateValue} - * for the syntax of the state value. - * - * In read/write mode, a state value can be considered as an assignation where - * the state value is assigned to the quark represented by the state attributes - * - * @author Geneviève Bastien - */ -public class TmfXmlReadWriteStateValue extends TmfXmlStateValue { - - /** - * Constructor where the path to the value is a list of state attributes - * - * @param modelFactory - * The factory used to create XML model elements - * @param node - * The state value XML element - * @param container - * The state system container this state value belongs to - * @param attributes - * The attributes representing the path to this value - */ - public TmfXmlReadWriteStateValue(TmfXmlReadWriteModelFactory modelFactory, Element node, IXmlStateSystemContainer container, List attributes) { - this(modelFactory, node, container, attributes, null); - } - - /** - * Constructor where the path to the value is an event field - * - * @param modelFactory - * The factory used to create XML model elements - * @param node - * The state value XML element - * @param container - * The state system container this state value belongs to - * @param eventField - * The event field where to get the value - */ - public TmfXmlReadWriteStateValue(TmfXmlReadWriteModelFactory modelFactory, Element node, IXmlStateSystemContainer container, String eventField) { - this(modelFactory, node, container, new ArrayList(), eventField); - } - - private TmfXmlReadWriteStateValue(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container, List attributes, String eventField) { - super(modelFactory, node, container, attributes, eventField); - } - - @Override - protected ITmfStateSystemBuilder getStateSystem() { - return (ITmfStateSystemBuilder) super.getStateSystem(); - } - - @Override - protected TmfXmlStateValueBase initializeStateValue(ITmfXmlModelFactory modelFactory, Element node) { - TmfXmlStateValueBase stateValueType = null; - /* Process the XML Element state value */ - String type = node.getAttribute(TmfXmlStrings.TYPE); - String value = getSsContainer().getAttributeValue(node.getAttribute(TmfXmlStrings.VALUE)); - - switch (type) { - case TmfXmlStrings.TYPE_INT: { - /* Integer value */ - ITmfStateValue stateValue = TmfStateValue.newValueInt(Integer.parseInt(value)); - stateValueType = new TmfXmlStateValueTmf(stateValue); - break; - } - case TmfXmlStrings.TYPE_LONG: { - /* Long value */ - ITmfStateValue stateValue = TmfStateValue.newValueLong(Long.parseLong(value)); - stateValueType = new TmfXmlStateValueTmf(stateValue); - break; - } - case TmfXmlStrings.TYPE_STRING: { - /* String value */ - ITmfStateValue stateValue = TmfStateValue.newValueString(value); - stateValueType = new TmfXmlStateValueTmf(stateValue); - break; - } - case TmfXmlStrings.TYPE_NULL: { - /* Null value */ - ITmfStateValue stateValue = TmfStateValue.nullValue(); - stateValueType = new TmfXmlStateValueTmf(stateValue); - break; - } - case TmfXmlStrings.EVENT_FIELD: - /* Event field */ - stateValueType = new TmfXmlStateValueEventField(value); - break; - case TmfXmlStrings.TYPE_EVENT_NAME: - /* The value is the event name */ - stateValueType = new TmfXmlStateValueEventName(); - break; - case TmfXmlStrings.TYPE_DELETE: - /* Deletes the value of an attribute */ - stateValueType = new TmfXmlStateValueDelete(); - break; - case TmfXmlStrings.TYPE_QUERY: - /* Value is the result of a query */ - List children = XmlUtils.getChildElements(node); - List childAttributes = new ArrayList<>(); - for (Element child : children) { - ITmfXmlStateAttribute queryAttribute = modelFactory.createStateAttribute(child, getSsContainer()); - childAttributes.add(queryAttribute); - } - stateValueType = new TmfXmlStateValueQuery(childAttributes); - break; - default: - throw new IllegalArgumentException(String.format("TmfXmlStateValue constructor: unexpected element %s for stateValue type", type)); //$NON-NLS-1$ - } - return stateValueType; - } - - // ---------------------------------------------------------- - // Internal state value classes for the different types - // ---------------------------------------------------------- - - /** - * Base class for all state value. Contain default methods to handle event, - * process or increment the value - */ - protected abstract class TmfXmlStateValueTypeReadWrite extends TmfXmlStateValueBase { - - @Override - public final void handleEvent(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { - if (isIncrement()) { - incrementValue(event, quark, timestamp); - } else { - ITmfStateValue value = getValue(event); - processValue(quark, timestamp, value); - } - } - - @Override - protected void processValue(int quark, long timestamp, ITmfStateValue value) throws AttributeNotFoundException, TimeRangeException, StateValueTypeException { - switch (getStackType()) { - case POP: - getStateSystem().popAttribute(timestamp, quark); - break; - case PUSH: - getStateSystem().pushAttribute(timestamp, value, quark); - break; - case NULL: - case PEEK: - default: - getStateSystem().modifyAttribute(timestamp, value, quark); - break; - } - } - - @Override - protected void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { - getStateSystem().incrementAttribute(timestamp, quark); - } - } - - /* This state value uses a constant value, defined in the XML */ - private class TmfXmlStateValueTmf extends TmfXmlStateValueTypeReadWrite { - - private final ITmfStateValue fValue; - - public TmfXmlStateValueTmf(ITmfStateValue value) { - fValue = value; - } - - @Override - public ITmfStateValue getValue(ITmfEvent event) { - return fValue; - } - - @Override - public void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { - ITmfStateSystem ss = getStateSystem(); - switch (fValue.getType()) { - case LONG: { - long incrementLong = fValue.unboxLong(); - long currentValue = ss.queryOngoingState(quark).unboxLong(); - ITmfStateValue value = TmfStateValue.newValueLong(incrementLong + currentValue); - processValue(quark, timestamp, value); - return; - } - case INTEGER: { - int increment = fValue.unboxInt(); - int currentValue = ss.queryOngoingState(quark).unboxInt(); - ITmfStateValue value = TmfStateValue.newValueInt(increment + currentValue); - processValue(quark, timestamp, value); - break; - } - case DOUBLE: - case NULL: - case STRING: - default: - Activator.logWarning("TmfXmlStateValue: The increment value is not a number type"); //$NON-NLS-1$ - break; - } - } - } - - /* The state value uses the value of an event field */ - private class TmfXmlStateValueEventField extends TmfXmlStateValueTypeReadWrite { - - private final String fFieldName; - - public TmfXmlStateValueEventField(String field) { - fFieldName = field; - } - - @Override - public ITmfStateValue getValue(ITmfEvent event) { - if (event == null) { - Activator.logWarning("XML State value: requested an event field, but event is null"); //$NON-NLS-1$ - return TmfStateValue.nullValue(); - } - return getEventFieldValue(event, fFieldName); - } - - @Override - public void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { - ITmfStateSystem ss = getSsContainer().getStateSystem(); - ITmfStateValue incrementValue = getValue(event); - switch (incrementValue.getType()) { - case INTEGER: { - int increment = incrementValue.unboxInt(); - int currentValue = ss.queryOngoingState(quark).unboxInt(); - ITmfStateValue value = TmfStateValue.newValueInt(increment + currentValue); - processValue(quark, timestamp, value); - break; - } - case LONG: { - long incrementLong = incrementValue.unboxLong(); - long currentValue = ss.queryOngoingState(quark).unboxLong(); - ITmfStateValue value = TmfStateValue.newValueLong(incrementLong + currentValue); - processValue(quark, timestamp, value); - break; - } - case DOUBLE: - case NULL: - case STRING: - default: - Activator.logWarning(String.format("TmfXmlStateValue: The event field increment %s is not a number type but a %s", fFieldName, incrementValue.getType())); //$NON-NLS-1$ - break; - } - } - } - - /* The state value is the event name */ - private class TmfXmlStateValueEventName extends TmfXmlStateValueTypeReadWrite { - - @Override - public ITmfStateValue getValue(ITmfEvent event) { - if (event == null) { - Activator.logWarning("XML State value: request event name, but event is null"); //$NON-NLS-1$ - return TmfStateValue.nullValue(); - } - return TmfStateValue.newValueString(event.getType().getName()); - } - - } - - /* The state value deletes an attribute */ - private class TmfXmlStateValueDelete extends TmfXmlStateValueTypeReadWrite { - - @Override - public ITmfStateValue getValue(ITmfEvent event) throws AttributeNotFoundException { - return TmfStateValue.nullValue(); - } - - @Override - protected void processValue(int quark, long timestamp, ITmfStateValue value) throws TimeRangeException, AttributeNotFoundException { - ITmfStateSystem ss = getStateSystem(); - if (!(ss instanceof ITmfStateSystemBuilder)) { - throw new IllegalStateException("incrementValue should never be called when not building the state system"); //$NON-NLS-1$ - } - ITmfStateSystemBuilder builder = (ITmfStateSystemBuilder) ss; - builder.removeAttribute(timestamp, quark); - } - - } - - /* The state value uses the result of a query */ - private class TmfXmlStateValueQuery extends TmfXmlStateValueTypeReadWrite { - - private final List fQueryValue; - - public TmfXmlStateValueQuery(List childAttributes) { - fQueryValue = childAttributes; - } - - @Override - public ITmfStateValue getValue(ITmfEvent event) throws AttributeNotFoundException { - /* Query the state system for the value */ - ITmfStateValue value = TmfStateValue.nullValue(); - int quarkQuery = IXmlStateSystemContainer.ROOT_QUARK; - ITmfStateSystem ss = getStateSystem(); - - for (ITmfXmlStateAttribute attribute : fQueryValue) { - quarkQuery = attribute.getAttributeQuark(event, quarkQuery); - if (quarkQuery == IXmlStateSystemContainer.ERROR_QUARK) { - /* the query is not valid, we stop the state change */ - break; - } - } - /* - * the query can fail : for example, if a value is requested but has - * not been set yet - */ - if (quarkQuery != IXmlStateSystemContainer.ERROR_QUARK) { - value = ss.queryOngoingState(quarkQuery); - } - return value; - } - - @Override - public void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { - ITmfStateSystem ss = getStateSystem(); - ITmfStateValue incrementValue = getValue(event); - switch (incrementValue.getType()) { - case INTEGER: { - int increment = incrementValue.unboxInt(); - int currentValue = ss.queryOngoingState(quark).unboxInt(); - ITmfStateValue value = TmfStateValue.newValueInt(increment + currentValue); - processValue(quark, timestamp, value); - break; - } - case LONG: { - long incrementLong = incrementValue.unboxLong(); - long currentValue = ss.queryOngoingState(quark).unboxLong(); - ITmfStateValue value = TmfStateValue.newValueLong(incrementLong + currentValue); - processValue(quark, timestamp, value); - break; - } - case DOUBLE: - case NULL: - case STRING: - default: - Activator.logWarning("TmfXmlStateValue: The query result increment is not a number type"); //$NON-NLS-1$ - break; - } - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/ITmfXmlTopLevelElement.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/ITmfXmlTopLevelElement.java deleted file mode 100644 index cfb59591c2..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/ITmfXmlTopLevelElement.java +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.module; - -/** - * Interface implemented by all classes representing XML top-level elements, for - * example state providers and views - * - * @author Geneviève Bastien - */ -public interface ITmfXmlTopLevelElement { - - /** - * Get the requested value for an attribute. If the value is a pre-defined - * value, we return the string corresponding in the defined values map in - * the top-level XML element. - * - * @param name - * the string to get - * @return the actual string value - */ - String getAttributeValue(String name); - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/IXmlStateSystemContainer.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/IXmlStateSystemContainer.java deleted file mode 100644 index 0803dbac88..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/IXmlStateSystemContainer.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.module; - -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlLocation; - -/** - * Interface that all XML defined objects who provide, use or contain state - * system must implement in order to use the state provider model elements in - * {@link org.eclipse.linuxtools.tmf.analysis.xml.core.model} package - * - * @author Geneviève Bastien - */ -public interface IXmlStateSystemContainer extends ITmfXmlTopLevelElement { - - /** Root quark, to get values at the root of the state system */ - static final int ROOT_QUARK = -1; - /** - * Error quark, value taken when a state system quark query is in error. - * - * FIXME: Originally in the code, the -1 was used for both root quark and - * return errors, so it has the same value as root quark, but maybe it can - * be changed to something else -2? A quark can never be negative - */ - static final int ERROR_QUARK = -1; - - /** - * Get the state system managed by this XML object - * - * @return The state system - */ - ITmfStateSystem getStateSystem(); - - /** - * Get the list of locations defined in this top level XML element - * - * @return The list of {@link TmfXmlLocation} - */ - Iterable getLocations(); - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/Messages.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/Messages.java deleted file mode 100644 index b8ac122f2f..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/Messages.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.module; - -import org.eclipse.osgi.util.NLS; - -/** - * Externalized messages for the XML analysis module package - * - * @author Geneviève Bastien - */ -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.analysis.xml.core.module.messages"; //$NON-NLS-1$ - - /** Error copying XML file to workspace folder */ - public static String XmlUtils_ErrorCopyingFile; - /** XML parse error */ - public static String XmlUtils_XmlParseError; - /** Error occurred while validating XML */ - public static String XmlUtils_XmlValidateError; - /** XML validation error */ - public static String XmlUtils_XmlValidationError; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/XmlUtils.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/XmlUtils.java deleted file mode 100644 index 475eb78ed9..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/XmlUtils.java +++ /dev/null @@ -1,252 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.module; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.URL; -import java.nio.channels.FileChannel; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.XMLConstants; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Source; -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; - -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.core.Activator; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.osgi.util.NLS; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -/** - * Class containing some utilities for the XML plug-in packages: for example, it - * manages the XML files and validates them - * - * @author Geneviève Bastien - */ -public class XmlUtils { - - /** Sub-directory of the plug-in where XML files are stored */ - private static final String XML_DIRECTORY = "xml_files"; //$NON-NLS-1$ - - /** Name of the XSD schema file */ - private static final String XSD = "xmlDefinition.xsd"; //$NON-NLS-1$ - - /** Make this class non-instantiable */ - private XmlUtils() { - - } - - /** - * Get the path where the XML files are stored. Create it if it does not - * exist - * - * @return path to XML files - */ - public static IPath getXmlFilesPath() { - IPath path = Activator.getDefault().getStateLocation(); - path = path.addTrailingSeparator().append(XML_DIRECTORY); - - /* Check if directory exists, otherwise create it */ - File dir = path.toFile(); - if (!dir.exists() || !dir.isDirectory()) { - dir.mkdirs(); - } - - return path; - } - - /** - * Validate the XML file input with the XSD schema - * - * @param xmlFile - * XML file to validate - * @return True if the XML validates - */ - public static IStatus xmlValidate(File xmlFile) { - URL url = XmlUtils.class.getResource(XSD); - SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - Source xmlSource = new StreamSource(xmlFile); - try { - Schema schema = schemaFactory.newSchema(url); - Validator validator = schema.newValidator(); - validator.validate(xmlSource); - } catch (SAXParseException e) { - String error = NLS.bind(Messages.XmlUtils_XmlParseError, e.getLineNumber(), e.getLocalizedMessage()); - Activator.logError(error); - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, error, e); - } catch (SAXException e) { - String error = NLS.bind(Messages.XmlUtils_XmlValidationError, e.getLocalizedMessage()); - Activator.logError(error); - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, error, e); - } catch (IOException e) { - String error = Messages.XmlUtils_XmlValidateError; - Activator.logError("IO exception occurred", e); //$NON-NLS-1$ - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, error, e); - } - return Status.OK_STATUS; - } - - /** - * Adds an XML file to the plugin's path. The XML file should have been - * validated using the {@link XmlUtils#xmlValidate(File)} method before - * calling this method. - * - * @param fromFile - * The XML file to add - * @return Whether the file was successfully added - */ - public static IStatus addXmlFile(File fromFile) { - - /* Copy file to path */ - File toFile = getXmlFilesPath().addTrailingSeparator().append(fromFile.getName()).toFile(); - - try { - if (!toFile.exists()) { - toFile.createNewFile(); - } - } catch (IOException e) { - String error = Messages.XmlUtils_ErrorCopyingFile; - Activator.logError(error, e); - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, error, e); - } - - try (FileInputStream fis = new FileInputStream(fromFile); - FileOutputStream fos = new FileOutputStream(toFile); - FileChannel source = fis.getChannel(); - FileChannel destination = fos.getChannel();) { - destination.transferFrom(source, 0, source.size()); - } catch (IOException e) { - String error = Messages.XmlUtils_ErrorCopyingFile; - Activator.logError(error, e); - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, error, e); - } - return Status.OK_STATUS; - } - - /** - * Get only the XML element children of an XML element. - * - * @param parent - * The parent element to get children from - * @return The list of children Element of the parent - */ - public static List getChildElements(Element parent) { - NodeList childNodes = parent.getChildNodes(); - List childElements = new ArrayList<>(); - for (int index = 0; index < childNodes.getLength(); index++) { - if (childNodes.item(index).getNodeType() == Node.ELEMENT_NODE) { - childElements.add((Element) childNodes.item(index)); - } - } - return childElements; - } - - /** - * Get the XML children element of an XML element, but only those of a - * certain type - * - * @param parent - * The parent element to get the children from - * @param elementTag - * The tag of the elements to return - * @return The list of children {@link Element} of the parent - */ - public static List getChildElements(Element parent, String elementTag) { - /* get the state providers and find the corresponding one */ - NodeList nodes = parent.getElementsByTagName(elementTag); - List childElements = new ArrayList<>(); - - for (int i = 0; i < nodes.getLength(); i++) { - Element node = (Element) nodes.item(i); - if (node.getParentNode().equals(parent)) { - childElements.add(node); - } - } - return childElements; - } - - /** - * Return the node element corresponding to the requested type in the file. - * - * TODO: Nothing prevents from having duplicate type -> id in a same file. - * That should not be allowed. If you want an element with the same ID as - * another one, it should be in a different file and we should check it at - * validation time. - * - * @param filePath - * The absolute path to the XML file - * @param elementType - * The type of top level element to search for - * @param elementId - * The ID of the desired element - * @return The XML element or null if not found - */ - public static Element getElementInFile(String filePath, @NonNull String elementType, @NonNull String elementId) { - - if (filePath == null) { - return null; - } - - IPath path = new Path(filePath); - File file = path.toFile(); - if (file == null || !file.exists() || !file.isFile() || !xmlValidate(file).isOK()) { - return null; - } - - try { - /* Load the XML File */ - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder; - - dBuilder = dbFactory.newDocumentBuilder(); - Document doc = dBuilder.parse(file); - doc.getDocumentElement().normalize(); - - /* get the state providers and find the corresponding one */ - NodeList nodes = doc.getElementsByTagName(elementType); - Element foundNode = null; - - for (int i = 0; i < nodes.getLength(); i++) { - Element node = (Element) nodes.item(i); - String id = node.getAttribute(TmfXmlStrings.ID); - if (id.equals(elementId)) { - foundNode = node; - } - } - return foundNode; - } catch (ParserConfigurationException | SAXException | IOException e) { - return null; - } - - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/messages.properties b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/messages.properties deleted file mode 100644 index 2f81a3d996..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/messages.properties +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -# Copyright (c) 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### -XmlUtils_ErrorCopyingFile=An error occurred while copying the XML file to the TMF directory. The file was not imported. -XmlUtils_XmlParseError=XML Parsing error at line {0}: {1} -XmlUtils_XmlValidateError=An error occurred while validating the XML file. -XmlUtils_XmlValidationError=Error validating XML file {0} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/xmlCommon.xsd b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/xmlCommon.xsd deleted file mode 100644 index 453a219155..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/xmlCommon.xsd +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - Maps a string (usually a human-readable value used by the XML elements) to another string (a value in the system, which can be converted to an integer, long by the a stateValue element or used as-is). - - - The human-readable string to identify this value. This is what will be manipulated by the XML and shown to the end-user (if applicable). - - - A system value the 'name' maps to. It will usually not be shown to the end user. - - - Optional color attribute to this mapping. This attribute is used in XML-defined views to represent this mapping. - - - - - Define a path in a state system, that can then be used as a shortcut in other XML elements. - - - - Define each element of the path represented by this location. For instance, if location "abc" has path "a/b/c", there would be a sequence of 3 stateAttribute elements of type constant. - - - - The identifier of this location, used inside the XML element in the scope of which it is defined. - - - - diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/xmlDefinition.xsd b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/xmlDefinition.xsd deleted file mode 100644 index f6e059f796..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/xmlDefinition.xsd +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - Define a new time graph view. - - - Define a new XY chart view. - - - Define a new state provider - - - - - diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/xmlStateProvider.xsd b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/xmlStateProvider.xsd deleted file mode 100644 index dcafbfd6b6..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/xmlStateProvider.xsd +++ /dev/null @@ -1,295 +0,0 @@ - - - - - - - Declares a data-driven state provider which defines how events change the state of attributes of the system. Each state provider defined in XML will become an analysis in TMF. - - - - Provide meta-information on this state provider, like labels and applicable trace types. - - - Define a value that maps a string used in the state provider to a numbered value. - - - Declare shortcuts to frequently used attribute/data locations. For instance, if a path to an often-used attribute is CPUs/{event.some_field}/Threads/Status, it may be a good idea to put this path in a location and then use the location name in the event handlers. - - - Define how a given event will modify the state system being built. For each event in the trace that causes a state change, a event handler should be defined. - - - - The unique ID of this state provider. It will be used to identify the analysis that will be built from this state provider. - - - The version ID of this state provider. Whenever the state provider changes so that the resulting state system is different from previous versions, this version number should be bumped. - - - - - Declares the meta-information that can be defined for an XML state provider. - - - - Indicate that the state provider applies to a given trace type. - - - - The ID of the trace type, as declared in a org.eclipse.linuxtools.tmf.core.tracetype extension point or a custom trace parser. For example: "org.eclipse.linuxtools.lttng2.kernel.tracetype" or "org.eclipse.linuxtools.lttng2.ust.tracetype" for respectively LTTng Kernel and LTTng UST traces. - - - - - Add a label to the state provider. If provided, this text will be the name of the analysis that the user will see in TMF. - - - - The text to name this state provider (and the analysis it will generate). - - - - - - - - Define how an event modifies the state of the system. There should be one event handler for each event causing a state change. - - - - Define how the state system is modified by the event. An event may cause more than one state change. - - - - Name of the event that causes a state change. - - - - - - Define a change of state in the state system being built. - - - - Describe a single attribute assignation. Simply put: a state change where path/to/attribute=value. - - - Explain how to reach an attribute in the state system. It describes the path/to/attribute. - - - Explain how to obtain the value of the state attribute to modify. - - - - Describe a conditional state change, where different path conditions may lead to different state changes. - - - Define the condition to verify. - - - Define the state change to use if the previous condition is true. - - - Optionally define the state change to use if the condition is false. - - - - - - - Define a conditional statement. Conditions may use values of the state system or from the event being handled. This element defines a statement in the form of "if (some_path == value)". - - - - - Compare the current value of an attribute of the state system. - - - Compare the value of an event field. - - - - Define the value to compare to. - - - - - - - Define a conditional statement with only one child. From this element, a condition may be composed of other conditional elements to create more complex conditional statements. - - - - Define a condition element, in the form "if (some_path == value)". - - - Negate the result of the following condition, allowing statements of the form "if (!cond)". - - - ANDs 2 conditional statements, allowing statements of the form "if (condA AND condB)" - - - ORs 2 conditional statements, allowing statements of the form "if (condA OR condB)" - - - - - - - Allows the composition of more than one conditional statements. - - - - Define a condition element, in the form "if (some_path == value)". - - - ORs 2 conditional statements, allowing statements of the form "if (condA OR condB)" - - - ANDs 2 conditional statements, allowing statements of the form "if (condA AND condB)" - - - Negate the result of the following condition, allowing statements of the form "if (!cond)". - - - - - - - Define a path to an attribute of the state system. - - - - If the type is a "query", those stateAttribute elements describe the elements of the query. - - - - The type of path to this attribute. The meaning of those paths type will depend on the context where the stateAttribute is being used. Not all types will make sense everywhere. - - - - - This type does not change the current attribute. Whatever attribute was the reference attribute at a given time, it will be returned as is. - - - This type identifies the state system attribute by a constant string. For instance, if the first level attribute of the state system is "Threads", then a constant type with "Threads" value should be used. - - - This type identifies the attribute by the value of an event field. Note that the event field corresponds to the attribute name, not its value. For example, if the event has a field called "current_cpu" with a value of "2", "2" would be the attribute name we want. - - - This type indicates that the path to the attribute is at the specified location. Location simply avoids having to write full path to an attribute each time it is being used, but the location itself is a sequence of stateAttribute elements. For example, if we previously defined a location named "CurrentThead" for path "CPUs/{current_cpu}/CurrentThread", we can use a stateAttribute of type location with "CurrentThread" value. - - - This type indicates that the path to the attribute is the result of a query. If this type is selected, a sequence of stateAttribute elements needs to be specified for this state attribute. The result of the query is the attribute name of the current element. For example, if the attribute we want is the PID of the current process on CPU 0, that PID can be found through the query "CPUs/0/CurrentThread". The value of this attribute would be, for example, 1234, the attribute we are looking for. - - - - - - The value of this state attribute. A value should be specified only if the type is "constant", "eventField" or "location". - - - - - Define a value, that can be assigned to an attribute of the state system. - - - For a "query" value type, a sequence of stateAttributes will define the query whose result is the value. - - - - - The type of this state value. It will describe how to obtain to value and/or what to do with it. - - - - - Indicate that the value is a null value. - - - The value is a constant of type integer. - - - The value is a constant of type long - - - The value is a constant of type string - - - The value is the content of an event field. The "value" attribute is the field name. To convert this field to a certain type, attribute "forcedType" may be used. - - - The value is the name of the event. - - - Indicate that the attribute the value is to be applied to should be deleted. - - - The value is the result of a query to the state system. If this type is selected, a sequence of stateAttributes must be defined in this stateValue element. - - - - - - Indicate that the current value will be added to any previously available value. - - - Indicate that a stack operation will be performed with the value - - - - - The value will be popped from the stack - - - The value will be pushed on a stack - - - The value will be peeked from the top of the stack, but it will stay there - - - - - - Indicate the desired type for the state value. If the value is not already of this type, a conversion will be attempted. The forcedType is used to convert values of event fields. - - - - - The value should be an integer - - - The value should be a long - - - The value should be a double - - - - - - Indicate what the value is. A value should be specified only if the type is int, long, string or event_field. See the documentation on types for information on what to put for value. - - - - - This element is used in conditions where the value of an event field is compared to something else. It is not the same as the stateAttribute's type eventField, where the eventField is used as the name for an attribute to the state system. - - - Indicate which field to use. - - - diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/xmlView.xsd b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/xmlView.xsd deleted file mode 100644 index 1931843ea7..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/xmlView.xsd +++ /dev/null @@ -1,178 +0,0 @@ - - - - - - - Declares a data-driven time graph view, which defines how the view will display the results of an analysis. For now, only state system analysis are supported by this view. - - - - Provider meta-information on this view, like labels and analysis it applies to. - - - Define a mapping between a human-readable text and the value used in the analysis. The "definedValue"'s optional "color" attribute is the color with which this value will be displayed. - - - Define how to determine the entries (lines) to show on the time graph view. An entry may have children entry elements defined as children, where children are sub-elements of this one (for example, child attributes in the state system). A parent/child relationship may be defined for entries of the same level. See the viewEntry element documentation for more details. - - - - The unique identifier of this view element. It will be used by the framework to identify this view. - - - - - Declares a data-driven XY chart view, which defines how the view will display the results of an analysis. For now, only state system analyses are supported by this view. - - - - Provider meta-information on this view, like labels and analyses it applies to. - - - Define how to determine the entries (series) to show on the XY view. See the xyViewEntry element documentation for more details. - - - - The unique identifier of this view element. It will be used by the framework to identify this view. - - - - - Declares the meta-information that can be defined for an XML time graph view. - - - - Indicate that the view applies to the analysis identified with the given ID. To have a view apply to an XML-defined state system analysis, you'd use the state provider ID in the "stateProvider" element. - - - - The ID of the analysis this view applies to. - - - The ID of the state system this view applies to. The attribute is used only if the analysis contains more than one state system. - - - - - Add a label to the time graph view. If provided, this text will be displayed to the user to identify this view, otherwise, the view's ID will be used. - - - - The text used as a name for this time graph view. - - - - - - - - Define a path to entries in the view. If this element is at the top level, the base path to reach the entry is the root of the state system. Otherwise, it will use the parent element's corresponding attribute as the base. Each view entry element corresponds to a time graph view entry that will actually be displayed. - - - - Indicate the attribute whose value will be displayed in the time graph (the value that changes over time). If this element is not specified, no entry will be created for this element, and all other elements will be ignored. - - - Specify which attribute to use as ID for this entry. This ID will be used in the ID column in the view, and will also be used to build the tree if a parent element is specified. If this element is not present, the display attribute's name will be used as ID. - - - Specify how to find the parent's ID of this entry. By default, the parent/child hierarchy is the same as defined in the timeGraphView element of the XML file. This element will add to this default parent/child relationship so that elements at the same XML-defined level can still have a relationship. - - - Specify how to find the name of this entry. Typically, the name will be human-readable. If not specified, the display attribute's name will be used as the name. - - - Define child entries for this entry. Child entries will be shown as children of this entry (with or without additional parent/child relationship defined through the viewEntry element's "parent" element). - - - - The path of the entry in the state system. Wildcards '*' may be used. For example, to display entries from all CPUs, the path could be "CPUs/*" and one entry will be created for each sub-attribute of the "CPUs" attribute. Each entry will be used as the base for all child elements, unless specified otherwise. - - - - - Define a path to entries in the view. If this element is at the top level, the base path to reach the entry is the root of the state system. Otherwise, it will use the parent element's corresponding attribute as the base. Each XY view entry element corresponds to a series in the resulting view. - - - - Indicate the attribute whose value will be displayed in the time graph (the value that changes over time). If this element is not specified, no entry will be created for this element, and all other elements will be ignored. - - - Specify how to find the name of this entry. Typically, the name will be human-readable. If not specified, the display attribute's name will be used as the name. - - - - The path of the entry in the state system. Wildcards '*' may be used. For example, to display entries from all CPUs, the path could be "CPUs/*" and one series will be created for each sub-attribute of the "CPUs" attribute. Each entry will be used as the base for all child elements, unless specified otherwise. - - - Indicate how to display the value, compared with preceding values. - - - - - The value is shown as is. - - - The value is the difference between the value at current timestamp and the value at the preceding timestamp. - - - - - - - - - - If the type is a "query", those stateAttribute elements describe the elements of the query. - - - - The type of path to this attribute. The value of the other attributes will depend on the selected type. - - - - - This type identifies the state system attribute by a constant string. For instance, if the state system attribute to display is "Status", it would be a constant type with value "Status". - - - This type indicates that the path to the attribute is at the specified location. A location avoids having to write the full path to an attribute every time it is being used. The location itself is a sequence of stateAttribute elements. For example, if we previously defined a location named "Procname" for path "Threads/tid/Procname", we can use a stateAttribute of type location with "Procname" value. - - - This type indicates that the path to the attribute is the result of a query. If this type is selected, a sequence of stateAttribute elements needs to be specified for this viewStateAttribute. The result of the query is the attribute name of the current element. For example, if the attribute we want is the PID of the current process on CPU 0, that PID can be found through the query "CPUs/0/CurrentThread". The value of this attribute would be for example 1234, which is the attribute we are looking for. - - - This type indicates that the requested attribute is the attribute itself. For this attribute, the reference is always relative (setting it to absolute will be ignored). - - - - - - The value of this state attribute. A value should be specified if the type is "constant" or "location". - - - Specify which state system attribute to use as the base to reach this path. It is either absolute or relative. By default, it is relative to the current entry. - - - - - The path will be calculated starting from the entry under which this viewStateAttribute element is defined. - - - The path will be calculated starting from the root of the state system. That means that if the entry itself is one of "CPUs/*", we could reach another attribute from the root of the state system, like "Threads/tid". - - - - - diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/TmfXmlStrings.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/TmfXmlStrings.java deleted file mode 100644 index a3f61ef8a7..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/TmfXmlStrings.java +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ecole Polytechnique - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Florian Wininger - Initial implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider; - -import org.eclipse.jdt.annotation.NonNullByDefault; - -/** - * This file defines all name in the XML Structure for the State Provider - * - * @author Florian Wininger - * @noimplement This interface only contains static defines - */ -@SuppressWarnings({ "javadoc", "nls" }) -@NonNullByDefault -public interface TmfXmlStrings { - - /* XML generic Element attribute names */ - static final String VALUE = "value"; - static final String NAME = "name"; - static final String VERSION = "version"; - static final String TYPE = "type"; - - /* XML header element */ - static final String HEAD = "head"; - static final String TRACETYPE = "traceType"; - static final String ID = "id"; - static final String LABEL = "label"; - static final String ANALYSIS = "analysis"; - - /* XML String */ - static final String NULL = ""; - static final String WILDCARD = "*"; - static final String VARIABLE_PREFIX = "$"; - static final String COLOR = "color"; - static final String COLOR_PREFIX = "#"; - - /* XML Element Name */ - static final String STATE_PROVIDER = "stateProvider"; - static final String DEFINED_VALUE = "definedValue"; - static final String LOCATION = "location"; - static final String EVENT_HANDLER = "eventHandler"; - static final String STATE_ATTRIBUTE = "stateAttribute"; - static final String STATE_VALUE = "stateValue"; - static final String STATE_CHANGE = "stateChange"; - static final String ELEMENT_FIELD = "field"; - - /* XML Condition strings */ - static final String IF = "if"; - static final String CONDITION = "condition"; - static final String THEN = "then"; - static final String ELSE = "else"; - - /* XML event handler strings */ - static final String HANDLER_EVENT_NAME = "eventName"; - - /* XML constant for Type of Attribute and Value */ - static final String TYPE_NULL = "null"; - static final String TYPE_CONSTANT = "constant"; - static final String EVENT_FIELD = "eventField"; - static final String TYPE_LOCATION = "location"; - static final String TYPE_QUERY = "query"; - static final String TYPE_SELF = "self"; - static final String TYPE_INT = "int"; - static final String TYPE_LONG = "long"; - static final String TYPE_STRING = "string"; - static final String TYPE_EVENT_NAME = "eventName"; - static final String TYPE_DELETE = "delete"; - static final String INCREMENT = "increment"; - static final String FORCED_TYPE = "forcedType"; - static final String ATTRIBUTE_STACK = "stack"; - static final String STACK_POP = "pop"; - static final String STACK_PUSH = "push"; - static final String STACK_PEEK = "peek"; - static final String CPU = "cpu"; - - /** - * @since 1.2 - */ - static final String TIMESTAMP = "timestamp"; - - /* Operator type */ - static final String NOT = "not"; - static final String AND = "and"; - static final String OR = "or"; - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/XmlStateProvider.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/XmlStateProvider.java deleted file mode 100644 index 29267fd1c1..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/XmlStateProvider.java +++ /dev/null @@ -1,185 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Florian Wininger - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider; - -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.eclipse.core.runtime.IPath; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlModelFactory; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlEventHandler; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlLocation; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.readwrite.TmfXmlReadWriteModelFactory; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.statesystem.AbstractTmfStateProvider; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; - -/** - * This is the state change input plug-in for TMF's state system which handles - * the XML Format - * - * @author Florian Wininger - */ -public class XmlStateProvider extends AbstractTmfStateProvider implements IXmlStateSystemContainer { - - private final IPath fFilePath; - @NonNull private final String fStateId; - - /** List of all Event Handlers */ - private final Set fEventHandlers = new HashSet<>(); - - /** List of all Locations */ - private final Set fLocations; - - /** Map for defined values */ - private final Map fDefinedValues = new HashMap<>(); - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Instantiate a new state provider plug-in. - * - * @param trace - * The trace - * @param stateid - * The state system id, corresponding to the analysis_id - * attribute of the state provider element of the XML file - * @param file - * Path to the XML file containing the state provider definition - */ - public XmlStateProvider(ITmfTrace trace, @NonNull String stateid, IPath file) { - super(trace, ITmfEvent.class, stateid); - fStateId = stateid; - fFilePath = file; - Element doc = XmlUtils.getElementInFile(fFilePath.makeAbsolute().toOSString(), TmfXmlStrings.STATE_PROVIDER, fStateId); - if (doc == null) { - fLocations = new HashSet<>(); - return; - } - - ITmfXmlModelFactory modelFactory = TmfXmlReadWriteModelFactory.getInstance(); - /* parser for defined Values */ - NodeList definedStateNodes = doc.getElementsByTagName(TmfXmlStrings.DEFINED_VALUE); - for (int i = 0; i < definedStateNodes.getLength(); i++) { - Element element = (Element) definedStateNodes.item(i); - fDefinedValues.put(element.getAttribute(TmfXmlStrings.NAME), element.getAttribute(TmfXmlStrings.VALUE)); - } - - /* parser for the locations */ - NodeList locationNodes = doc.getElementsByTagName(TmfXmlStrings.LOCATION); - Set locations = new HashSet<>(); - for (int i = 0; i < locationNodes.getLength(); i++) { - Element element = (Element) locationNodes.item(i); - TmfXmlLocation location = modelFactory.createLocation(element, this); - locations.add(location); - } - fLocations = Collections.unmodifiableSet(locations); - - /* parser for the event handlers */ - NodeList nodes = doc.getElementsByTagName(TmfXmlStrings.EVENT_HANDLER); - for (int i = 0; i < nodes.getLength(); i++) { - Element element = (Element) nodes.item(i); - TmfXmlEventHandler handler = modelFactory.createEventHandler(element, this); - fEventHandlers.add(handler); - } - } - - /** - * Get the state id of the state provider - * - * @return The state id of the state provider - */ - @NonNull - public String getStateId() { - return fStateId; - } - - // ------------------------------------------------------------------------ - // IStateChangeInput - // ------------------------------------------------------------------------ - - @Override - public int getVersion() { - Element ssNode = XmlUtils.getElementInFile(fFilePath.makeAbsolute().toOSString(), TmfXmlStrings.STATE_PROVIDER, fStateId); - if (ssNode != null) { - return Integer.parseInt(ssNode.getAttribute(TmfXmlStrings.VERSION)); - } - /* - * The version attribute is mandatory and XML files that don't validate - * with the XSD are ignored, so this should never happen - */ - throw new IllegalStateException("The state provider XML node should have a version attribute"); //$NON-NLS-1$ - } - - @Override - public XmlStateProvider getNewInstance() { - return new XmlStateProvider(this.getTrace(), getStateId(), fFilePath); - } - - @Override - protected void eventHandle(ITmfEvent event) { - if (event == null) { - return; - } - for (TmfXmlEventHandler eventHandler : fEventHandlers) { - eventHandler.handleEvent(event); - } - } - - @Override - public ITmfStateSystem getStateSystem() { - return ss; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Override - public Iterable getLocations() { - return fLocations; - } - - /** - * Get the defined value associated with a constant - * - * @param constant - * The constant defining this value - * @return The actual value corresponding to this constant - */ - public String getDefinedValue(String constant) { - return fDefinedValues.get(constant); - } - - @Override - public String getAttributeValue(String name) { - String attribute = name; - if (attribute.startsWith(TmfXmlStrings.VARIABLE_PREFIX)) { - /* search the attribute in the map without the fist character $ */ - attribute = getDefinedValue(attribute.substring(1)); - } - return attribute; - } - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/XmlStateSystemModule.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/XmlStateSystemModule.java deleted file mode 100644 index 66c8ee9a81..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/XmlStateSystemModule.java +++ /dev/null @@ -1,85 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider; - -import java.util.List; - -import org.eclipse.core.runtime.IPath; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.w3c.dom.Element; - -/** - * Analysis module for the data-driven state systems, defined in XML. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class XmlStateSystemModule extends TmfStateSystemAnalysisModule { - - private @Nullable IPath fXmlFile; - - @Override - protected StateSystemBackendType getBackendType() { - return StateSystemBackendType.FULL; - } - - @Override - @NonNull - protected ITmfStateProvider createStateProvider() { - return new XmlStateProvider(getTrace(), getId(), fXmlFile); - } - - @Override - public String getName() { - String name = getId(); - IPath xmlFile = fXmlFile; - if (xmlFile == null) { - return name; - } - Element doc = XmlUtils.getElementInFile(xmlFile.makeAbsolute().toString(), TmfXmlStrings.STATE_PROVIDER, getId()); - /* Label may be available in XML header */ - List head = XmlUtils.getChildElements(doc, TmfXmlStrings.HEAD); - if (head.size() == 1) { - List labels = XmlUtils.getChildElements(head.get(0), TmfXmlStrings.LABEL); - if (!labels.isEmpty()) { - name = labels.get(0).getAttribute(TmfXmlStrings.VALUE); - } - } - - return name; - } - - /** - * Sets the file path of the XML file containing the state provider - * - * @param file - * The full path to the XML file - */ - public void setXmlFile(IPath file) { - fXmlFile = file; - } - - /** - * Get the path to the XML file containing this state provider definition. - * - * @return XML file path - */ - public IPath getXmlFile() { - return fXmlFile; - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/Activator.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/Activator.java new file mode 100644 index 0000000000..11d24f328b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/Activator.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.analysis.xml.core; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + * + * @author Geneviève Bastien + */ +public class Activator extends Plugin { + + /** The plug-in ID */ + public static final String PLUGIN_ID = "org.eclipse.tracecompass.tmf.analysis.xml.core"; //$NON-NLS-1$ + + // The shared instance + private static Activator fPlugin; + + /** + * The constructor + */ + public Activator() { + setDefault(this); + } + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + setDefault(this); + } + + @Override + public void stop(BundleContext context) throws Exception { + setDefault(null); + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return fPlugin; + } + + // Sets plug-in instance + private static void setDefault(Activator plugin) { + fPlugin = plugin; + } + + // ------------------------------------------------------------------------ + // Log an IStatus + // ------------------------------------------------------------------------ + + /** + * Log an IStatus object directly + * + * @param status + * The status to log + */ + public static void log(IStatus status) { + fPlugin.getLog().log(status); + } + + // ------------------------------------------------------------------------ + // Log INFO + // ------------------------------------------------------------------------ + + /** + * Logs a message with severity INFO in the runtime log of the plug-in. + * + * @param message + * A message to log + */ + public static void logInfo(String message) { + fPlugin.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity INFO in the runtime log of the + * plug-in. + * + * @param message + * A message to log + * @param exception + * The corresponding exception + */ + public static void logInfo(String message, Throwable exception) { + fPlugin.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message, exception)); + } + + // ------------------------------------------------------------------------ + // Log WARNING + // ------------------------------------------------------------------------ + + /** + * Logs a message and exception with severity WARNING in the runtime log of + * the plug-in. + * + * @param message + * A message to log + */ + public static void logWarning(String message) { + fPlugin.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity WARNING in the runtime log of + * the plug-in. + * + * @param message + * A message to log + * @param exception + * The corresponding exception + */ + public static void logWarning(String message, Throwable exception) { + fPlugin.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message, exception)); + } + + // ------------------------------------------------------------------------ + // Log ERROR + // ------------------------------------------------------------------------ + + /** + * Logs a message and exception with severity ERROR in the runtime log of + * the plug-in. + * + * @param message + * A message to log + */ + public static void logError(String message) { + fPlugin.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity ERROR in the runtime log of + * the plug-in. + * + * @param message + * A message to log + * @param exception + * The corresponding exception + */ + public static void logError(String message, Throwable exception) { + fPlugin.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, exception)); + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/ITmfXmlModelFactory.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/ITmfXmlModelFactory.java new file mode 100644 index 0000000000..72d0ea68bd --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/ITmfXmlModelFactory.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.model; + +import java.util.List; + +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.w3c.dom.Element; + +/** + * Interface to create XML model elements in different contexts. This allows to + * reuse the same XML syntax and parsers, but use the elements differently + * depending on the what is intended to be done with them. + * + * @author Geneviève Bastien + */ +public interface ITmfXmlModelFactory { + + /** + * Create a new XML state attribute + * + * @param attribute + * XML element of the attribute + * @param container + * The state system container this state attribute belongs to + * @return The new state attribute + */ + ITmfXmlStateAttribute createStateAttribute(Element attribute, IXmlStateSystemContainer container); + + /** + * Create a new state value where the value corresponds to a path of + * {@link ITmfXmlStateAttribute} + * + * @param node + * The state value XML element + * @param container + * The state system container this state value belongs to + * @param attributes + * The attributes representing the path to this value + * @return The new state value + */ + ITmfXmlStateValue createStateValue(Element node, IXmlStateSystemContainer container, List attributes); + + /** + * Create a new state value where the value corresponds to a field in an + * event + * + * @param node + * The state value XML element + * @param container + * The state system container this state value belongs to + * @param eventField + * The event field where to get the value + * @return The new state value + */ + ITmfXmlStateValue createStateValue(Element node, IXmlStateSystemContainer container, String eventField); + + /** + * Create a new XML condition + * + * @param node + * The XML root of this condition + * @param container + * The state system container this condition belongs to + * @return The new XML condition + */ + TmfXmlCondition createCondition(Element node, IXmlStateSystemContainer container); + + /** + * Create a new XML event handler + * + * @param node + * The XML event handler element + * @param container + * The state system container this state value belongs to + * @return The new XML event handler + */ + TmfXmlEventHandler createEventHandler(Element node, IXmlStateSystemContainer container); + + /** + * Create a new XML state change + * + * @param node + * The XML state change element + * @param container + * The state system container this state change belongs to + * @return The new XML state change + */ + TmfXmlStateChange createStateChange(Element node, IXmlStateSystemContainer container); + + /** + * Create a new XML location + * + * @param node + * The XML location element + * @param container + * The state system container this location belongs to + * @return The new XML location + */ + TmfXmlLocation createLocation(Element node, IXmlStateSystemContainer container); + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/ITmfXmlStateAttribute.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/ITmfXmlStateAttribute.java new file mode 100644 index 0000000000..e0c96df5db --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/ITmfXmlStateAttribute.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.model; + +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * Interface that describe a state attribute defined in an XML element + * + * @author Geneviève Bastien + */ +public interface ITmfXmlStateAttribute { + + /** + * This method gets the quark for this state attribute in the State System. + * + * Unless this attribute is a location, in which case the quark must exist, + * the quark will be added to the state system if the state system is in + * builder mode. + * + * @param startQuark + * root quark, use {@link IXmlStateSystemContainer#ROOT_QUARK} to search + * the full attribute tree + * @return the quark described by attribute or + * {@link IXmlStateSystemContainer#ERROR_QUARK} if quark cannot be found + */ + int getAttributeQuark(int startQuark); + + /** + * This method gets the quark for this state attribute in the State System. + * + * Unless this attribute is a location, in which case the quark must exist, + * the quark will be added to the state system if the state system is in + * builder mode. + * + * @param event + * The current event being handled + * @param startQuark + * root quark, use {@link IXmlStateSystemContainer#ROOT_QUARK} to search + * the full attribute tree + * @return the quark described by attribute or + * {@link IXmlStateSystemContainer#ERROR_QUARK} if quark cannot be found + */ + int getAttributeQuark(ITmfEvent event, int startQuark); +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/ITmfXmlStateValue.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/ITmfXmlStateValue.java new file mode 100644 index 0000000000..d421e3f8a4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/ITmfXmlStateValue.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.model; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * Interface that describe operations on a state value described in an XML + * element + * + * @author Geneviève Bastien + */ +public interface ITmfXmlStateValue { + + /** + * Get the current {@link ITmfStateValue} of this state value for an event. + * It does not increment the value and does not any other processing of the + * value. + * + * @param event + * The current event or null if no event is + * available. + * @return the {@link ITmfStateValue} + * @throws AttributeNotFoundException + * May be thrown by the state system during the query + */ + ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException; + + /** + * Get the value of the event field that is the path of this state value + * + * @param event + * The current event + * @return the value of the event field + */ + ITmfStateValue getEventFieldValue(@NonNull ITmfEvent event); + + /** + * Get the list of state attributes, the path to the state value + * + * @return the list of Attribute to have the path in the State System + */ + List getAttributes(); + + /** + * Handles an event, by setting the value of the attribute described by the + * state attribute path in the state system. + * + * @param event + * The event to process + * @throws AttributeNotFoundException + * Pass through the exception it received + * @throws TimeRangeException + * Pass through the exception it received + * @throws StateValueTypeException + * Pass through the exception it received + */ + void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException; + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlCondition.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlCondition.java new file mode 100644 index 0000000000..ce243a0007 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlCondition.java @@ -0,0 +1,217 @@ +/******************************************************************************* + * Copyright (c) 2014 Ecole Polytechnique de Montreal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Florian Wininger - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.model; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.w3c.dom.Element; + +/** + * This Class implement a condition tree in the XML-defined state system. + * + *
+ * example:
+ * 
+ *   
+ *       
+ *       
+ *       
+ *   
+ *   
+ *   
+ * 
+ * 
+ * + * @author Florian Wininger + */ +public class TmfXmlCondition { + + private final List fConditions = new ArrayList<>(); + private final ITmfXmlStateValue fStateValue; + private final ConditionOperator fOperator; + private final IXmlStateSystemContainer fContainer; + + private enum ConditionOperator { + NONE, + NOT, + AND, + OR, + } + + /** + * Constructor + * + * @param modelFactory + * The factory used to create XML model elements + * @param node + * The XML root of this condition + * @param container + * The state system container this condition belongs to + */ + public TmfXmlCondition(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container) { + fContainer = container; + + Element rootNode = node; + /* Process the conditions: in each case, only process Element nodes */ + List childElements = XmlUtils.getChildElements(rootNode); + + /* + * If the node is an if, take the child as the root condition + * + * FIXME: Maybe the caller should do this instead. + */ + if (node.getNodeName().equals(TmfXmlStrings.IF)) { + if (childElements.isEmpty()) { + throw new IllegalArgumentException("TmfXmlCondition constructor: IF node has no child element"); //$NON-NLS-1$ + } + rootNode = childElements.get(0); + childElements = XmlUtils.getChildElements(rootNode); + } + + switch (rootNode.getNodeName()) { + case TmfXmlStrings.CONDITION: + fOperator = ConditionOperator.NONE; + /* The last element is a state value node */ + Element stateValueElement = childElements.remove(childElements.size() - 1); + + /* + * A state value is either preceded by an eventField or a number of + * state attributes + */ + if (childElements.size() == 1 && childElements.get(0).getNodeName().equals(TmfXmlStrings.ELEMENT_FIELD)) { + fStateValue = modelFactory.createStateValue(stateValueElement, fContainer, childElements.get(0).getAttribute(TmfXmlStrings.NAME)); + } else { + List attributes = new ArrayList<>(); + for (Element element : childElements) { + if (!element.getNodeName().equals(TmfXmlStrings.STATE_ATTRIBUTE)) { + throw new IllegalArgumentException("TmfXmlCondition: a condition either has a eventField element or a number of TmfXmlStateAttribute elements before the state value"); //$NON-NLS-1$ + } + ITmfXmlStateAttribute attribute = modelFactory.createStateAttribute(element, fContainer); + attributes.add(attribute); + } + fStateValue = modelFactory.createStateValue(stateValueElement, fContainer, attributes); + } + break; + case TmfXmlStrings.NOT: + fOperator = ConditionOperator.NOT; + fStateValue = null; + fConditions.add(modelFactory.createCondition(childElements.get(0), fContainer)); + break; + case TmfXmlStrings.AND: + fOperator = ConditionOperator.AND; + fStateValue = null; + for (Element condition : childElements) { + fConditions.add(modelFactory.createCondition(condition, fContainer)); + } + break; + case TmfXmlStrings.OR: + fOperator = ConditionOperator.OR; + fStateValue = null; + for (Element condition : childElements) { + fConditions.add(modelFactory.createCondition(condition, fContainer)); + } + break; + default: + throw new IllegalArgumentException("TmfXmlCondition constructor: XML node is of the wrong type"); //$NON-NLS-1$ + } + } + + /** + * Test the result of the condition for an event + * + * @param event + * The event on which to test the condition + * @return Whether the condition is true or not + * @throws AttributeNotFoundException + * The state attribute was not found + */ + public boolean testForEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException { + ITmfStateSystem ss = fContainer.getStateSystem(); + /* + * The condition is either the equality check of a state value or a + * boolean operation on other conditions + */ + if (fStateValue != null) { + ITmfXmlStateValue filter = fStateValue; + int quark = IXmlStateSystemContainer.ROOT_QUARK; + for (ITmfXmlStateAttribute attribute : filter.getAttributes()) { + quark = attribute.getAttributeQuark(event, quark); + /* + * When verifying a condition, the state attribute must exist, + * if it does not, the query is not valid, we stop the condition + * check + */ + if (quark == IXmlStateSystemContainer.ERROR_QUARK) { + throw new AttributeNotFoundException(); + } + } + + /* Get the value to compare to from the XML file */ + ITmfStateValue valueXML; + valueXML = filter.getValue(event); + + /* + * The actual value: it can be either queried in the state system or + * found in the event + */ + ITmfStateValue valueState = (quark != IXmlStateSystemContainer.ROOT_QUARK) ? ss.queryOngoingState(quark) : + filter.getEventFieldValue(event); + + return valueXML.equals(valueState); + + } else if (!fConditions.isEmpty()) { + /* Verify a condition tree */ + switch (fOperator) { + case AND: + for (TmfXmlCondition childCondition : fConditions) { + if (!childCondition.testForEvent(event)) { + return false; + } + } + return true; + case NONE: + break; + case NOT: + return !fConditions.get(0).testForEvent(event); + case OR: + for (TmfXmlCondition childCondition : fConditions) { + if (childCondition.testForEvent(event)) { + return true; + } + } + return false; + default: + break; + + } + } else { + throw new IllegalStateException("TmfXmlCondition: the condition should be either a state value or be the result of a condition tree"); //$NON-NLS-1$ + } + return true; + } + + @Override + public String toString() { + return "TmfXmlCondition: " + fOperator + " on " + fConditions; //$NON-NLS-1$ //$NON-NLS-2$ + } + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlEventHandler.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlEventHandler.java new file mode 100644 index 0000000000..ec8508866a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlEventHandler.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2014 Ecole Polytechnique de Montreal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Florian Wininger - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.model; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.Activator; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/** + * This Class implements an EventHandler in the XML-defined state system + * + *
+ * example:
+ * 
+ *  
+ *      ...
+ *  
+ *  
+ *      ...
+ *  
+ * 
+ * 
+ * + * @author Florian Wininger + */ +public class TmfXmlEventHandler { + + /* list of states changes */ + private final List fStateChangeList = new ArrayList<>(); + private final String fName; + private final IXmlStateSystemContainer fParent; + + /** + * Constructor + * + * @param modelFactory + * The factory used to create XML model elements + * @param node + * XML event handler element + * @param parent + * The state system container this event handler belongs to + */ + public TmfXmlEventHandler(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer parent) { + fParent = parent; + fName = node.getAttribute(TmfXmlStrings.HANDLER_EVENT_NAME); + + NodeList nodesChanges = node.getElementsByTagName(TmfXmlStrings.STATE_CHANGE); + /* load state changes */ + for (int i = 0; i < nodesChanges.getLength(); i++) { + TmfXmlStateChange stateChange = modelFactory.createStateChange((Element) nodesChanges.item(i), fParent); + fStateChangeList.add(stateChange); + } + } + + private boolean appliesToEvent(ITmfEvent event) { + String eventName = event.getType().getName(); + + /* test for full name */ + if (eventName.equals(fName)) { + return true; + } + + /* test for the wildcard at the end */ + if ((fName.endsWith(TmfXmlStrings.WILDCARD) && eventName.startsWith(fName.replace(TmfXmlStrings.WILDCARD, TmfXmlStrings.NULL)))) { + return true; + } + return false; + } + + /** + * If the event handler can handle the event, it applies all state changes + * to modify the state system accordingly + * + * @param event + * The trace event to handle + */ + public void handleEvent(@NonNull ITmfEvent event) { + if (!appliesToEvent(event)) { + return; + } + + /* Process all state changes */ + for (TmfXmlStateChange stateChange : fStateChangeList) { + try { + stateChange.handleEvent(event); + } catch (AttributeNotFoundException ae) { + /* + * This would indicate a problem with the logic of the manager + * here, so it shouldn't happen. + */ + Activator.logError("Attribute not found", ae); //$NON-NLS-1$ + } catch (TimeRangeException tre) { + /* + * This would happen if the events in the trace aren't ordered + * chronologically, which should never be the case ... + */ + Activator.logError("TimeRangeException caught in the state system's event manager. Are the events in the trace correctly ordered?", tre); //$NON-NLS-1$ + } catch (StateValueTypeException sve) { + /* + * This would happen if we were trying to push/pop attributes + * not of type integer. Which, once again, should never happen. + */ + Activator.logError("State value type error", sve); //$NON-NLS-1$ + } + + } + + } + + @Override + public String toString() { + return "TmfXmlEventHandler: " + fName; //$NON-NLS-1$ + } + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlLocation.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlLocation.java new file mode 100644 index 0000000000..e485d65b96 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlLocation.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (c) 2014 Ecole Polytechnique de Montreal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Florian Wininger - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.model; + +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.w3c.dom.Element; + +/** + * This Class implements a Location in the XML-defined state system, ie a named + * shortcut to reach a given attribute, used in state attributes + * + *
+ * example:
+ *  
+ *    
+ *    
+ *    ...
+ *  
+ * 
+ * + * @author Florian Wininger + */ +public class TmfXmlLocation { + + /** Path in the State System */ + private final List fPath = new LinkedList<>(); + + /** ID : name of the location */ + private final String fId; + private final IXmlStateSystemContainer fContainer; + + /** + * Constructor + * + * @param modelFactory + * The factory used to create XML model elements + * @param location + * XML node element + * @param container + * The state system container this location belongs to + */ + public TmfXmlLocation(ITmfXmlModelFactory modelFactory, Element location, IXmlStateSystemContainer container) { + fId = location.getAttribute(TmfXmlStrings.ID); + fContainer = container; + + List childElements = XmlUtils.getChildElements(location); + for (Element attribute : childElements) { + ITmfXmlStateAttribute xAttribute = modelFactory.createStateAttribute(attribute, fContainer); + fPath.add(xAttribute); + } + } + + /** + * Get the id of the location + * + * @return The id of a location + */ + public String getId() { + return fId; + } + + /** + * Get the quark for the path represented by this location + * + * @param event + * The event being handled + * @param startQuark + * The starting quark for relative search, use + * {@link IXmlStateSystemContainer#ROOT_QUARK} for the root of + * the attribute tree + * @return The quark at the leaf of the path + */ + public int getLocationQuark(ITmfEvent event, int startQuark) { + int quark = startQuark; + for (ITmfXmlStateAttribute attrib : fPath) { + quark = attrib.getAttributeQuark(event, quark); + if (quark == IXmlStateSystemContainer.ERROR_QUARK) { + break; + } + } + return quark; + } + + /** + * Get the quark for the path represented by this location + * + * @param startQuark + * The starting quark for relative search, use + * {@link IXmlStateSystemContainer#ROOT_QUARK} for the root of + * the attribute tree + * @return The quark at the leaf of the path + */ + public int getLocationQuark(int startQuark) { + int quark = startQuark; + for (ITmfXmlStateAttribute attrib : fPath) { + quark = attrib.getAttributeQuark(quark); + if (quark == IXmlStateSystemContainer.ERROR_QUARK) { + break; + } + } + return quark; + } + + @Override + public String toString() { + return "TmfXmlLocation " + fId + ": " + fPath; //$NON-NLS-1$ //$NON-NLS-2$ + } + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlStateAttribute.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlStateAttribute.java new file mode 100644 index 0000000000..7dacd92071 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlStateAttribute.java @@ -0,0 +1,327 @@ +/******************************************************************************* + * Copyright (c) 2014 Ecole Polytechnique de Montreal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Florian Wininger - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.model; + +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.Activator; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.w3c.dom.Element; + +/** + * This Class implements a single attribute value in the XML-defined state + * system. + * + *
+ * Examples:
+ * 
+ * 
+ *      
+ *      
+ *      
+ * 
+ * 
+ * + * @author Florian Wininger + */ +public abstract class TmfXmlStateAttribute implements ITmfXmlStateAttribute { + + private enum StateAttributeType { + NONE, + CONSTANT, + EVENTFIELD, + QUERY, + LOCATION, + SELF + } + + /** Type of attribute */ + private final StateAttributeType fType; + + /** Attribute's name */ + private final String fName; + + /** List of attributes for a query */ + private final List fQueryList = new LinkedList<>(); + + private final IXmlStateSystemContainer fContainer; + + /** + * Constructor + * + * @param modelFactory + * The factory used to create XML model elements + * @param attribute + * XML element of the attribute + * @param container + * The state system container this state attribute belongs to + */ + protected TmfXmlStateAttribute(ITmfXmlModelFactory modelFactory, Element attribute, IXmlStateSystemContainer container) { + fContainer = container; + + switch (attribute.getAttribute(TmfXmlStrings.TYPE)) { + case TmfXmlStrings.TYPE_CONSTANT: + fType = StateAttributeType.CONSTANT; + fName = fContainer.getAttributeValue(attribute.getAttribute(TmfXmlStrings.VALUE)); + break; + case TmfXmlStrings.EVENT_FIELD: + fType = StateAttributeType.EVENTFIELD; + fName = fContainer.getAttributeValue(attribute.getAttribute(TmfXmlStrings.VALUE)); + break; + case TmfXmlStrings.TYPE_LOCATION: + fType = StateAttributeType.LOCATION; + fName = fContainer.getAttributeValue(attribute.getAttribute(TmfXmlStrings.VALUE)); + break; + case TmfXmlStrings.TYPE_QUERY: + List childElements = XmlUtils.getChildElements(attribute); + for (Element subAttributeNode : childElements) { + ITmfXmlStateAttribute subAttribute = modelFactory.createStateAttribute(subAttributeNode, fContainer); + fQueryList.add(subAttribute); + } + fType = StateAttributeType.QUERY; + fName = null; + break; + case TmfXmlStrings.NULL: + fType = StateAttributeType.NONE; + fName = null; + break; + case TmfXmlStrings.TYPE_SELF: + fType = StateAttributeType.SELF; + fName = null; + break; + default: + throw new IllegalArgumentException("TmfXmlStateAttribute constructor: The XML element is not of the right type"); //$NON-NLS-1$ + } + } + + /** + * This method gets the quark for this state attribute in the State System. + * + * Unless this attribute is a location, in which case the quark must exist, + * the quark will be added to the state system if the state system is in + * builder mode. + * + * @param startQuark + * root quark, use {@link IXmlStateSystemContainer#ROOT_QUARK} to + * search the full attribute tree + * @return the quark described by attribute or + * {@link IXmlStateSystemContainer#ERROR_QUARK} if quark cannot be + * found + */ + @Override + public int getAttributeQuark(int startQuark) { + return getAttributeQuark(null, startQuark); + } + + /** + * Basic quark-retrieving method. Pass an attribute in parameter as an array + * of strings, the matching quark will be returned. If the attribute does + * not exist, it will add the quark to the state system if the context + * allows it. + * + * See {@link ITmfStateSystemBuilder#getQuarkAbsoluteAndAdd(String...)} + * + * @param path + * Full path to the attribute + * @return The quark for this attribute + * @throws AttributeNotFoundException + * The attribute does not exist and cannot be added + */ + protected abstract int getQuarkAbsoluteAndAdd(String... path) throws AttributeNotFoundException; + + /** + * Quark-retrieving method, but the attribute is queried starting from the + * startNodeQuark. If the attribute does not exist, it will add it to the + * state system if the context allows it. + * + * See {@link ITmfStateSystemBuilder#getQuarkRelativeAndAdd(int, String...)} + * + * @param startNodeQuark + * The quark of the attribute from which 'path' originates. + * @param path + * Relative path to the attribute + * @return The quark for this attribute + * @throws AttributeNotFoundException + * The attribute does not exist and cannot be added + */ + protected abstract int getQuarkRelativeAndAdd(int startNodeQuark, String... path) throws AttributeNotFoundException; + + /** + * Get the state system associated with this attribute's container + * + * @return The state system associated with this state attribute + */ + protected ITmfStateSystem getStateSystem() { + return fContainer.getStateSystem(); + } + + /** + * This method gets the quark for this state attribute in the State System. + * + * Unless this attribute is a location, in which case the quark must exist, + * the quark will be added to the state system if the state system is in + * builder mode. + * + * @param event + * The current event being handled, or null if no + * event available in the context + * @param startQuark + * root quark, use {@link IXmlStateSystemContainer#ROOT_QUARK} to + * search the full attribute tree + * @return the quark described by attribute or + * {@link IXmlStateSystemContainer#ERROR_QUARK} if quark cannot be + * found + */ + @Override + public int getAttributeQuark(@Nullable ITmfEvent event, int startQuark) { + ITmfStateSystem ss = getStateSystem(); + + try { + switch (fType) { + case CONSTANT: { + int quark; + if (startQuark == IXmlStateSystemContainer.ROOT_QUARK) { + quark = getQuarkAbsoluteAndAdd(fName); + } else { + quark = getQuarkRelativeAndAdd(startQuark, fName); + } + return quark; + } + case EVENTFIELD: { + int quark = IXmlStateSystemContainer.ERROR_QUARK; + if (event == null) { + Activator.logWarning("XML State attribute: looking for an event field, but event is null"); //$NON-NLS-1$ + return quark; + } + /* special case if field is CPU which is not in the field */ + if (fName.equals(TmfXmlStrings.CPU)) { + quark = getQuarkRelativeAndAdd(startQuark, event.getSource()); + } else { + final ITmfEventField content = event.getContent(); + /* stop if the event field doesn't exist */ + if (content.getField(fName) == null) { + return IXmlStateSystemContainer.ERROR_QUARK; + } + + Object field = content.getField(fName).getValue(); + + if (field instanceof String) { + String fieldString = (String) field; + quark = getQuarkRelativeAndAdd(startQuark, fieldString); + } else if (field instanceof Long) { + Long fieldLong = (Long) field; + quark = getQuarkRelativeAndAdd(startQuark, fieldLong.toString()); + } else if (field instanceof Integer) { + Integer fieldInterger = (Integer) field; + quark = getQuarkRelativeAndAdd(startQuark, fieldInterger.toString()); + } + } + return quark; + } + case QUERY: { + int quark; + ITmfStateValue value = TmfStateValue.nullValue(); + int quarkQuery = IXmlStateSystemContainer.ROOT_QUARK; + + for (ITmfXmlStateAttribute attrib : fQueryList) { + quarkQuery = attrib.getAttributeQuark(event, quarkQuery); + if (quarkQuery == IXmlStateSystemContainer.ERROR_QUARK) { + break; + } + } + + // the query may fail: for example CurrentThread if there + // has not been a sched_switch event + if (quarkQuery != IXmlStateSystemContainer.ERROR_QUARK) { + value = ss.queryOngoingState(quarkQuery); + } + + switch (value.getType()) { + case INTEGER: { + int result = value.unboxInt(); + quark = getQuarkRelativeAndAdd(startQuark, String.valueOf(result)); + break; + } + case LONG: { + long result = value.unboxLong(); + quark = getQuarkRelativeAndAdd(startQuark, String.valueOf(result)); + break; + } + case STRING: { + String result = value.unboxStr(); + quark = getQuarkRelativeAndAdd(startQuark, result); + break; + } + case DOUBLE: + case NULL: + default: + quark = IXmlStateSystemContainer.ERROR_QUARK; // error + break; + } + return quark; + } + case LOCATION: { + int quark = startQuark; + String idLocation = fName; + + /* TODO: Add a fContainer.getLocation(id) method */ + for (TmfXmlLocation location : fContainer.getLocations()) { + if (location.getId().equals(idLocation)) { + quark = location.getLocationQuark(event, quark); + if (quark == IXmlStateSystemContainer.ERROR_QUARK) { + break; + } + } + } + return quark; + } + case SELF: + return startQuark; + case NONE: + default: + return startQuark; + } + } catch (AttributeNotFoundException ae) { + /* + * This can be happen before the creation of the node for a query in + * the state system. Example : current thread before a sched_switch + */ + return IXmlStateSystemContainer.ERROR_QUARK; + } catch (StateValueTypeException e) { + /* + * This would happen if we were trying to push/pop attributes not of + * type integer. Which, once again, should never happen. + */ + Activator.logError("StateValueTypeException", e); //$NON-NLS-1$ + return IXmlStateSystemContainer.ERROR_QUARK; + } + } + + @Override + public String toString() { + return "TmfXmlStateAttribute " + fType + ": " + fName; //$NON-NLS-1$ //$NON-NLS-2$ + } + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlStateChange.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlStateChange.java new file mode 100644 index 0000000000..f6caa53018 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlStateChange.java @@ -0,0 +1,218 @@ +/******************************************************************************* + * Copyright (c) 2014 Ecole Polytechnique de Montreal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Florian Wininger - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.model; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * This Class implement a State Change in the XML-defined state system + * + *
+ *  example 1: Simple state change
+ *  
+ *      
+ *      
+ *      
+ *  
+ *
+ *  example 2: Conditional state change
+ *  
+ *     
+ *      
+ *        
+ *        
+ *        
+ *      
+ *     
+ *    
+ *      
+ *      
+ *      
+ *    
+ *    
+ *      
+ *      
+ *      
+ *    
+ *  
+ * 
+ * + * @author Florian Wininger + */ +public class TmfXmlStateChange { + + private final IXmlStateChange fChange; + private final IXmlStateSystemContainer fContainer; + + /** + * Constructor + * + * @param modelFactory + * The factory used to create XML model elements + * @param statechange + * XML node root of this state change + * @param container + * The state system container this state change belongs to + */ + public TmfXmlStateChange(ITmfXmlModelFactory modelFactory, Element statechange, IXmlStateSystemContainer container) { + fContainer = container; + + /* + * child nodes is either a list of TmfXmlStateAttributes and + * TmfXmlStateValues, or an if-then-else series of nodes. + */ + Node ifNode = statechange.getElementsByTagName(TmfXmlStrings.IF).item(0); + if (ifNode != null) { + /* the state change has a condition */ + fChange = new XmlConditionalChange(modelFactory, statechange); + } else { + /* the state change does not have a condition */ + fChange = new XmlStateValueChange(modelFactory, statechange); + } + } + + /** + * Execute the state change for an event. If necessary, it validates the + * condition and executes the required change. + * + * @param event + * The event to process + * @throws AttributeNotFoundException + * Pass through the exception it received + * @throws TimeRangeException + * Pass through the exception it received + * @throws StateValueTypeException + * Pass through the exception it received + */ + public void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException { + fChange.handleEvent(event); + } + + @Override + public String toString() { + return "TmfXmlStateChange: " + fChange; //$NON-NLS-1$ + } + + /* Interface for both private classes to handle the event */ + private interface IXmlStateChange { + void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException; + } + + /** + * Conditional state change with a condition to verify + */ + private class XmlConditionalChange implements IXmlStateChange { + private final TmfXmlCondition fCondition; + private final TmfXmlStateChange fThenChange; + private final TmfXmlStateChange fElseChange; + + public XmlConditionalChange(ITmfXmlModelFactory modelFactory, Element statechange) { + /* + * The if node exists, it has been verified before calling this + */ + Node ifNode = statechange.getElementsByTagName(TmfXmlStrings.IF).item(0); + fCondition = modelFactory.createCondition((Element) ifNode, fContainer); + + Node thenNode = statechange.getElementsByTagName(TmfXmlStrings.THEN).item(0); + if (thenNode == null) { + throw new IllegalArgumentException("Conditional state change: there should be a then clause."); //$NON-NLS-1$ + } + fThenChange = modelFactory.createStateChange((Element) thenNode, fContainer); + + Node elseNode = statechange.getElementsByTagName(TmfXmlStrings.ELSE).item(0); + if (elseNode != null) { + fElseChange = modelFactory.createStateChange((Element) elseNode, fContainer); + } else { + fElseChange = null; + } + } + + @Override + public void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException { + TmfXmlStateChange toExecute = fThenChange; + try { + if (!fCondition.testForEvent(event)) { + toExecute = fElseChange; + } + } catch (AttributeNotFoundException e) { + /* + * An attribute in the condition did not exist (yet), return + * from the state change + */ + return; + } + + if (toExecute == null) { + return; + } + toExecute.handleEvent(event); + } + + @Override + public String toString() { + return "Condition: " + fCondition; //$NON-NLS-1$ + } + } + + /** + * State change with no condition + */ + private class XmlStateValueChange implements IXmlStateChange { + private final ITmfXmlStateValue fValue; + + public XmlStateValueChange(ITmfXmlModelFactory modelFactory, Element statechange) { + List childElements = XmlUtils.getChildElements(statechange); + + /* + * Last child element is the state value, the others are attributes + * to reach to value to set + */ + Element stateValueElement = childElements.remove(childElements.size() - 1); + List attributes = new ArrayList<>(); + for (Element element : childElements) { + if (!element.getNodeName().equals(TmfXmlStrings.STATE_ATTRIBUTE)) { + throw new IllegalArgumentException("TmfXmlStateChange: a state change must have only TmfXmlStateAttribute elements before the state value"); //$NON-NLS-1$ + } + ITmfXmlStateAttribute attribute = modelFactory.createStateAttribute(element, fContainer); + attributes.add(attribute); + } + if (attributes.isEmpty()) { + throw new IllegalArgumentException("TmfXmlStateChange: a state change must have at least one TmfXmlStateAttribute element before the state value"); //$NON-NLS-1$ + } + fValue = modelFactory.createStateValue(stateValueElement, fContainer, attributes); + } + + @Override + public void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException { + fValue.handleEvent(event); + } + + @Override + public String toString() { + return "Value: " + fValue; //$NON-NLS-1$ + } + } + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlStateValue.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlStateValue.java new file mode 100644 index 0000000000..83c6548ac5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlStateValue.java @@ -0,0 +1,495 @@ +/******************************************************************************* + * Copyright (c) 2014 Ecole Polytechnique de Montreal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Florian Wininger - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.model; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.w3c.dom.Element; + +/** + * This Class implements a State Value in the XML-defined state system, along + * with the path to get to the value (either a list of state attributes or an + * event field) + * + *
+ * Example:
+ *   
+ *   
+ *   
+ * 
+ * + * @author Florian Wininger + */ +public abstract class TmfXmlStateValue implements ITmfXmlStateValue { + + private final TmfXmlStateValueBase fStateValue; + + /* Path in the State System */ + private final List fPath; + /* Event field to match with this state value */ + private final String fEventField; + + /* Whether this state value is an increment of the previous value */ + private final boolean fIncrement; + /* Stack value */ + private final ValueTypeStack fStackType; + /* Forced value type */ + private final ITmfStateValue.Type fForcedType; + + private final IXmlStateSystemContainer fContainer; + + /** + * Different behaviors of an attribute that is to be stacked + */ + protected enum ValueTypeStack { + /** Not stacked */ + NULL, + /** Peek at the value at the top of the stack */ + PEEK, + /** Take the value at the top of the stack */ + POP, + /** Push the value on the stack */ + PUSH; + + /** + * Get the type stack value corresponding to a string + * + * @param input + * The string to match to a value + * @return The ValueTypeStack value + */ + public static ValueTypeStack getTypeFromString(String input) { + switch (input) { + case TmfXmlStrings.STACK_PUSH: + return PUSH; + case TmfXmlStrings.STACK_POP: + return POP; + case TmfXmlStrings.STACK_PEEK: + return PEEK; + default: + return NULL; + } + } + } + + /** + * Constructor + * + * @param modelFactory + * The factory used to create XML model elements + * @param node + * The state value XML element + * @param container + * The state system container this state value belongs to + * @param eventField + * The event field where to get the value + * @param attributes + * The attributes representing the path to this value + */ + protected TmfXmlStateValue(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container, List attributes, String eventField) { + fPath = attributes; + fContainer = container; + fEventField = eventField; + if (!node.getNodeName().equals(TmfXmlStrings.STATE_VALUE)) { + throw new IllegalArgumentException("TmfXmlStateValue constructor: Element is not a stateValue"); //$NON-NLS-1$ + } + + /* Check if there is an increment for the value */ + fIncrement = Boolean.parseBoolean(node.getAttribute(TmfXmlStrings.INCREMENT)); + + /* Process the XML Element state value */ + fStateValue = initializeStateValue(modelFactory, node); + + /* + * Forced type allows to convert the value to a certain type : For + * example, a process's TID in an event field may arrive with a LONG + * format but we want to store the data in an INT + */ + switch (node.getAttribute(TmfXmlStrings.FORCED_TYPE)) { + case TmfXmlStrings.TYPE_STRING: + fForcedType = ITmfStateValue.Type.STRING; + break; + case TmfXmlStrings.TYPE_INT: + fForcedType = ITmfStateValue.Type.INTEGER; + break; + case TmfXmlStrings.TYPE_LONG: + fForcedType = ITmfStateValue.Type.LONG; + break; + default: + fForcedType = ITmfStateValue.Type.NULL; + } + + /* + * Stack Actions : allow to define a stack with PUSH/POP/PEEK methods + */ + String stack = node.getAttribute(TmfXmlStrings.ATTRIBUTE_STACK); + fStackType = ValueTypeStack.getTypeFromString(stack); + } + + /** + * Initialize a {@link TmfXmlStateValueBase} object for the type and value + * + * @param modelFactory + * The factory used to create XML model elements + * @param node + * The state value XML element + * @return The internal state value type corresponding to this state value + */ + protected TmfXmlStateValueBase initializeStateValue(ITmfXmlModelFactory modelFactory, Element node) { + return new TmfXmlStateValueNull(); + } + + /** + * Return the state system container this class is attached to + * + * @return The state system container + */ + protected IXmlStateSystemContainer getSsContainer() { + return fContainer; + } + + /** + * Get the state system associated with this value's container + * + * @return The state system associated with the state system container + */ + protected ITmfStateSystem getStateSystem() { + return fContainer.getStateSystem(); + } + + /** + * Return whether this value is an increment of the previous value + * + * @return true if the value is an increment + */ + protected boolean isIncrement() { + return fIncrement; + } + + /** + * Get the stack type of this attribute. If the attribute is to be pushed or + * popped to a stack. The behavior of the stack attribute will depend on the + * implementation of the model. + * + * @return The stack type of the attribute + */ + protected ValueTypeStack getStackType() { + return fStackType; + } + + /** + * Get the forced type of the value. For example, if the value obtained from + * the attributes is not in this forced type, it will be converted to this. + * + * @return The desired type of the value + */ + protected ITmfStateValue.Type getForcedType() { + return fForcedType; + } + + /** + * Get the current {@link ITmfStateValue} of this state value for an event. + * It does not increment the value and does not any other processing of the + * value. + * + * @param event + * The current event, or null if no event available. + * @return the {@link ITmfStateValue} + * @throws AttributeNotFoundException + * May be thrown by the state system during the query + */ + @Override + public ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException { + return fStateValue.getValue(event); + } + + /** + * Get the value of the event field that is the path of this state value + * + * @param event + * The current event + * @return the value of the event field + */ + @Override + public ITmfStateValue getEventFieldValue(@NonNull ITmfEvent event) { + return getEventFieldValue(event, fEventField); + } + + /** + * Get the value of an event field + * + * @param event + * The current event + * @param fieldName + * The name of the field of which to get the value + * @return The value of the event field + */ + protected ITmfStateValue getEventFieldValue(@NonNull ITmfEvent event, String fieldName) { + + ITmfStateValue value = TmfStateValue.nullValue(); + + final ITmfEventField content = event.getContent(); + + /* Exception for "CPU", returns the source of this event */ + /* FIXME : Nameclash if a eventfield have "cpu" for name. */ + if (fieldName.equals(TmfXmlStrings.CPU)) { + return TmfStateValue.newValueInt(Integer.valueOf(event.getSource())); + } + /* Exception also for "TIMESTAMP", returns the timestamp of this event */ + if (fieldName.equals(TmfXmlStrings.TIMESTAMP)) { + return TmfStateValue.newValueLong(event.getTimestamp().getValue()); + } + if (content.getField(fieldName) == null) { + return value; + } + + Object field = content.getField(fieldName).getValue(); + + /* + * Try to find the right type. The type can be forced by + * "forcedType" argument. + */ + + if (field instanceof String) { + String fieldString = (String) field; + + switch (fForcedType) { + case INTEGER: + value = TmfStateValue.newValueInt(Integer.parseInt(fieldString)); + break; + case LONG: + value = TmfStateValue.newValueLong(Long.parseLong(fieldString)); + break; + case DOUBLE: + value = TmfStateValue.newValueDouble(Double.parseDouble(fieldString)); + break; + case NULL: + case STRING: + default: + value = TmfStateValue.newValueString(fieldString); + break; + } + } else if (field instanceof Long) { + Long fieldLong = (Long) field; + + switch (fForcedType) { + case INTEGER: + value = TmfStateValue.newValueInt(fieldLong.intValue()); + break; + case STRING: + value = TmfStateValue.newValueString(fieldLong.toString()); + break; + case DOUBLE: + value = TmfStateValue.newValueDouble(fieldLong.doubleValue()); + break; + case LONG: + case NULL: + default: + value = TmfStateValue.newValueLong(fieldLong); + break; + } + } else if (field instanceof Integer) { + Integer fieldInteger = (Integer) field; + + switch (fForcedType) { + case LONG: + value = TmfStateValue.newValueLong(fieldInteger.longValue()); + break; + case STRING: + value = TmfStateValue.newValueString(fieldInteger.toString()); + break; + case DOUBLE: + value = TmfStateValue.newValueDouble(fieldInteger.doubleValue()); + break; + case INTEGER: + case NULL: + default: + value = TmfStateValue.newValueInt(fieldInteger); + break; + } + } else if (field instanceof Double) { + Double fieldDouble = (Double) field; + + switch (fForcedType) { + case LONG: + value = TmfStateValue.newValueLong(fieldDouble.longValue()); + break; + case STRING: + value = TmfStateValue.newValueString(fieldDouble.toString()); + break; + case INTEGER: + value = TmfStateValue.newValueInt(fieldDouble.intValue()); + break; + case DOUBLE: + case NULL: + default: + value = TmfStateValue.newValueDouble(fieldDouble); + break; + } + } + return value; + } + + /** + * Get the list of state attributes, the path to the state value + * + * @return the list of Attribute to have the path in the State System + */ + @Override + public List getAttributes() { + return fPath; + } + + /** + * Handles an event, by setting the value of the attribute described by the + * state attribute path in the state system. + * + * @param event + * The event to process + * @throws AttributeNotFoundException + * Pass through the exception it received + * @throws TimeRangeException + * Pass through the exception it received + * @throws StateValueTypeException + * Pass through the exception it received + */ + @Override + public void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException { + int quark = IXmlStateSystemContainer.ROOT_QUARK; + + for (ITmfXmlStateAttribute attribute : fPath) { + quark = attribute.getAttributeQuark(event, quark); + /* the query is not valid, we stop the state change */ + if (quark == IXmlStateSystemContainer.ERROR_QUARK) { + throw new AttributeNotFoundException("Not found XML attribute " + attribute); //$NON-NLS-1$ + } + } + + long ts = event.getTimestamp().getValue(); + fStateValue.handleEvent(event, quark, ts); + } + + @Override + public String toString() { + return "TmfXmlStateValue: " + fStateValue; //$NON-NLS-1$ + } + + /** + * Base class for all state values. Contain default methods to handle event, + * process or increment the value + */ + protected abstract class TmfXmlStateValueBase { + + /** + * Get the value associated with this state value. + * + * @param event + * The event which can be used to retrieve the value if + * necessary. The event can be null if no event + * is required. + * @return The state value corresponding to this XML state value + * @throws AttributeNotFoundException + * Pass through the exception it received + */ + public abstract ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException; + + /** + * Do something with the state value, possibly using an event + * + * @param event + * The event being handled. If there is no event is + * available, use null. + * @param quark + * The quark for this value + * @param timestamp + * The timestamp of the event + * @throws StateValueTypeException + * Pass through the exception it received + * @throws TimeRangeException + * Pass through the exception it received + * @throws AttributeNotFoundException + * Pass through the exception it received + */ + public void handleEvent(@NonNull ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { + if (fIncrement) { + incrementValue(event, quark, timestamp); + } else { + ITmfStateValue value = getValue(event); + processValue(quark, timestamp, value); + } + } + + /** + * Set the value of a quark at a given timestamp. + * + * @param quark + * The quark for this value + * @param timestamp + * The timestamp + * @param value + * The value of this state value + * @throws TimeRangeException + * Pass through the exception it received + * @throws StateValueTypeException + * Pass through the exception it received + * @throws AttributeNotFoundException + * Pass through the exception it received + */ + @SuppressWarnings("unused") + protected void processValue(int quark, long timestamp, ITmfStateValue value) throws TimeRangeException, StateValueTypeException, AttributeNotFoundException { + } + + /** + * Increments the value of the parameter + * + * @param event + * The event being handled + * @param quark + * The quark for this value + * @param timestamp + * The timestamp of the event + * @throws StateValueTypeException + * Pass through the exception it received + * @throws TimeRangeException + * Pass through the exception it received + * @throws AttributeNotFoundException + * Pass through the exception it received + */ + @SuppressWarnings("unused") + protected void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { + } + } + + /* This state value uses a constant value, defined in the XML */ + private class TmfXmlStateValueNull extends TmfXmlStateValueBase { + + @Override + public ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException { + return TmfStateValue.nullValue(); + } + + } + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyModelFactory.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyModelFactory.java new file mode 100644 index 0000000000..c844edae72 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyModelFactory.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.model.readonly; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.ITmfXmlModelFactory; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.ITmfXmlStateAttribute; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.ITmfXmlStateValue; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlCondition; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlEventHandler; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlLocation; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlStateChange; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.readwrite.TmfXmlReadWriteModelFactory; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.w3c.dom.Element; + +/** + * Concrete factory for XML model elements in read only mode + * + * @author Geneviève Bastien + */ +public class TmfXmlReadOnlyModelFactory implements ITmfXmlModelFactory { + + private static ITmfXmlModelFactory fInstance = null; + + /** + * Get the instance of this model creator + * + * @return The {@link TmfXmlReadWriteModelFactory} instance + */ + @NonNull + public static synchronized ITmfXmlModelFactory getInstance() { + ITmfXmlModelFactory instance = fInstance; + if (instance == null) { + instance = new TmfXmlReadOnlyModelFactory(); + fInstance = instance; + } + return instance; + } + + @Override + public ITmfXmlStateAttribute createStateAttribute(Element attribute, IXmlStateSystemContainer container) { + return new TmfXmlReadOnlyStateAttribute(this, attribute, container); + } + + @Override + public ITmfXmlStateValue createStateValue(Element node, IXmlStateSystemContainer container, List attributes) { + return new TmfXmlReadOnlyStateValue(this, node, container, attributes); + } + + @Override + public ITmfXmlStateValue createStateValue(Element node, IXmlStateSystemContainer container, String eventField) { + return new TmfXmlReadOnlyStateValue(this, node, container, eventField); + } + + @Override + public TmfXmlCondition createCondition(Element node, IXmlStateSystemContainer container) { + return new TmfXmlCondition(this, node, container); + } + + @Override + public TmfXmlEventHandler createEventHandler(Element node, IXmlStateSystemContainer container) { + return new TmfXmlEventHandler(this, node, container); + } + + @Override + public TmfXmlStateChange createStateChange(Element node, IXmlStateSystemContainer container) { + return new TmfXmlStateChange(this, node, container); + } + + @Override + public TmfXmlLocation createLocation(Element node, IXmlStateSystemContainer container) { + return new TmfXmlLocation(this, node, container); + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyStateAttribute.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyStateAttribute.java new file mode 100644 index 0000000000..4d62672bf8 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyStateAttribute.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.model.readonly; + +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlStateAttribute; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.w3c.dom.Element; + +/** + * Implements a state attribute in a read only mode. See + * {@link TmfXmlStateAttribute} for the syntax of this attribute. + * + * In read-only mode, attributes that are requested but do not exist in the + * state system will not be added. + * + * @author Geneviève Bastien + */ +public class TmfXmlReadOnlyStateAttribute extends TmfXmlStateAttribute { + + /** + * Constructor + * + * @param modelFactory + * The factory used to create XML model elements + * @param attribute + * The XML element corresponding to this attribute + * @param container + * The state system container this state value belongs to + */ + public TmfXmlReadOnlyStateAttribute(TmfXmlReadOnlyModelFactory modelFactory, Element attribute, IXmlStateSystemContainer container) { + super(modelFactory, attribute, container); + } + + @Override + protected int getQuarkAbsoluteAndAdd(String... path) throws AttributeNotFoundException { + return getStateSystem().getQuarkAbsolute(path); + } + + @Override + protected int getQuarkRelativeAndAdd(int startNodeQuark, String... path) throws AttributeNotFoundException { + return getStateSystem().getQuarkRelative(startNodeQuark, path); + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyStateValue.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyStateValue.java new file mode 100644 index 0000000000..cc0ad19df2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyStateValue.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.model.readonly; + +import java.util.Collections; +import java.util.List; + +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.ITmfXmlStateAttribute; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlStateValue; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.w3c.dom.Element; + +/** + * Implements a state value is a read only mode. See {@link TmfXmlStateValue} + * for the syntax of the state value. + * + * In read mode, a state value will typically be used to find a path to a value, + * so the value is known and there is a path of attributes that should lead to + * it. + * + * @author Geneviève Bastien + */ +public class TmfXmlReadOnlyStateValue extends TmfXmlStateValue { + + /** + * Constructor where the path to the value is a list of state attributes + * + * @param modelFactory + * The factory used to create XML model elements + * @param node + * The state value XML element + * @param container + * The state system container this state value belongs to + * @param attributes + * The attributes representing the path to this value + */ + public TmfXmlReadOnlyStateValue(TmfXmlReadOnlyModelFactory modelFactory, Element node, + IXmlStateSystemContainer container, List attributes) { + super(modelFactory, node, container, attributes, null); + } + + /** + * Constructor where the path to the value is an event field + * + * @param modelFactory + * The factory used to create XML model elements + * @param node + * The state value XML element + * @param container + * The state system container this state value belongs to + * @param eventField + * The event field where to get the value + */ + public TmfXmlReadOnlyStateValue(TmfXmlReadOnlyModelFactory modelFactory, Element node, + IXmlStateSystemContainer container, String eventField) { + super(modelFactory, node, container, Collections.EMPTY_LIST, eventField); + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteModelFactory.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteModelFactory.java new file mode 100644 index 0000000000..743d039e52 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteModelFactory.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.model.readwrite; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.ITmfXmlModelFactory; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.ITmfXmlStateAttribute; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.ITmfXmlStateValue; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlCondition; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlEventHandler; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlLocation; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlStateChange; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.w3c.dom.Element; + +/** + * Concrete factory for XML model elements in read write mode + * + * @author Geneviève Bastien + */ +public class TmfXmlReadWriteModelFactory implements ITmfXmlModelFactory { + + private static ITmfXmlModelFactory fInstance = null; + + /** + * Get the instance of this model creator + * + * @return The {@link TmfXmlReadWriteModelFactory} instance + */ + @NonNull + public static synchronized ITmfXmlModelFactory getInstance() { + ITmfXmlModelFactory instance = fInstance; + if (instance == null) { + instance = new TmfXmlReadWriteModelFactory(); + fInstance = instance; + } + return instance; + } + + @Override + public ITmfXmlStateAttribute createStateAttribute(Element attribute, IXmlStateSystemContainer container) { + return new TmfXmlReadWriteStateAttribute(this, attribute, container); + } + + @Override + public ITmfXmlStateValue createStateValue(Element node, IXmlStateSystemContainer container, List attributes) { + return new TmfXmlReadWriteStateValue(this, node, container, attributes); + } + + @Override + public ITmfXmlStateValue createStateValue(Element node, IXmlStateSystemContainer container, String eventField) { + return new TmfXmlReadWriteStateValue(this, node, container, eventField); + } + + @Override + public TmfXmlCondition createCondition(Element node, IXmlStateSystemContainer container) { + return new TmfXmlCondition(this, node, container); + } + + @Override + public TmfXmlEventHandler createEventHandler(Element node, IXmlStateSystemContainer container) { + return new TmfXmlEventHandler(this, node, container); + } + + @Override + public TmfXmlStateChange createStateChange(Element node, IXmlStateSystemContainer container) { + return new TmfXmlStateChange(this, node, container); + } + + @Override + public TmfXmlLocation createLocation(Element node, IXmlStateSystemContainer container) { + return new TmfXmlLocation(this, node, container); + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteStateAttribute.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteStateAttribute.java new file mode 100644 index 0000000000..dc39d29ade --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteStateAttribute.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.model.readwrite; + +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlStateAttribute; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.w3c.dom.Element; + +/** + * Implements a state attribute in a read write mode. See + * {@link TmfXmlStateAttribute} for the syntax of this attribute. + * + * In read-write mode, attributes that are requested but do not exist are added + * to the state system. + * + * @author Geneviève Bastien + */ +public class TmfXmlReadWriteStateAttribute extends TmfXmlStateAttribute { + + /** + * Constructor + * + * @param modelFactory + * The factory used to create XML model elements + * @param attribute + * The XML element corresponding to this attribute + * @param container + * The state system container this state value belongs to + */ + public TmfXmlReadWriteStateAttribute(TmfXmlReadWriteModelFactory modelFactory, Element attribute, IXmlStateSystemContainer container) { + super(modelFactory, attribute, container); + } + + @Override + protected ITmfStateSystemBuilder getStateSystem() { + return (ITmfStateSystemBuilder) super.getStateSystem(); + } + + @Override + protected int getQuarkAbsoluteAndAdd(String... path) throws AttributeNotFoundException { + return getStateSystem().getQuarkAbsoluteAndAdd(path); + } + + @Override + protected int getQuarkRelativeAndAdd(int startNodeQuark, String... path) throws AttributeNotFoundException { + return getStateSystem().getQuarkRelativeAndAdd(startNodeQuark, path); + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteStateValue.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteStateValue.java new file mode 100644 index 0000000000..7e2114784d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteStateValue.java @@ -0,0 +1,375 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.model.readwrite; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.Activator; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.ITmfXmlModelFactory; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.ITmfXmlStateAttribute; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlStateValue; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.w3c.dom.Element; + +/** + * Implements a state value in a read write mode. See {@link TmfXmlStateValue} + * for the syntax of the state value. + * + * In read/write mode, a state value can be considered as an assignation where + * the state value is assigned to the quark represented by the state attributes + * + * @author Geneviève Bastien + */ +public class TmfXmlReadWriteStateValue extends TmfXmlStateValue { + + /** + * Constructor where the path to the value is a list of state attributes + * + * @param modelFactory + * The factory used to create XML model elements + * @param node + * The state value XML element + * @param container + * The state system container this state value belongs to + * @param attributes + * The attributes representing the path to this value + */ + public TmfXmlReadWriteStateValue(TmfXmlReadWriteModelFactory modelFactory, Element node, IXmlStateSystemContainer container, List attributes) { + this(modelFactory, node, container, attributes, null); + } + + /** + * Constructor where the path to the value is an event field + * + * @param modelFactory + * The factory used to create XML model elements + * @param node + * The state value XML element + * @param container + * The state system container this state value belongs to + * @param eventField + * The event field where to get the value + */ + public TmfXmlReadWriteStateValue(TmfXmlReadWriteModelFactory modelFactory, Element node, IXmlStateSystemContainer container, String eventField) { + this(modelFactory, node, container, new ArrayList(), eventField); + } + + private TmfXmlReadWriteStateValue(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container, List attributes, String eventField) { + super(modelFactory, node, container, attributes, eventField); + } + + @Override + protected ITmfStateSystemBuilder getStateSystem() { + return (ITmfStateSystemBuilder) super.getStateSystem(); + } + + @Override + protected TmfXmlStateValueBase initializeStateValue(ITmfXmlModelFactory modelFactory, Element node) { + TmfXmlStateValueBase stateValueType = null; + /* Process the XML Element state value */ + String type = node.getAttribute(TmfXmlStrings.TYPE); + String value = getSsContainer().getAttributeValue(node.getAttribute(TmfXmlStrings.VALUE)); + + switch (type) { + case TmfXmlStrings.TYPE_INT: { + /* Integer value */ + ITmfStateValue stateValue = TmfStateValue.newValueInt(Integer.parseInt(value)); + stateValueType = new TmfXmlStateValueTmf(stateValue); + break; + } + case TmfXmlStrings.TYPE_LONG: { + /* Long value */ + ITmfStateValue stateValue = TmfStateValue.newValueLong(Long.parseLong(value)); + stateValueType = new TmfXmlStateValueTmf(stateValue); + break; + } + case TmfXmlStrings.TYPE_STRING: { + /* String value */ + ITmfStateValue stateValue = TmfStateValue.newValueString(value); + stateValueType = new TmfXmlStateValueTmf(stateValue); + break; + } + case TmfXmlStrings.TYPE_NULL: { + /* Null value */ + ITmfStateValue stateValue = TmfStateValue.nullValue(); + stateValueType = new TmfXmlStateValueTmf(stateValue); + break; + } + case TmfXmlStrings.EVENT_FIELD: + /* Event field */ + stateValueType = new TmfXmlStateValueEventField(value); + break; + case TmfXmlStrings.TYPE_EVENT_NAME: + /* The value is the event name */ + stateValueType = new TmfXmlStateValueEventName(); + break; + case TmfXmlStrings.TYPE_DELETE: + /* Deletes the value of an attribute */ + stateValueType = new TmfXmlStateValueDelete(); + break; + case TmfXmlStrings.TYPE_QUERY: + /* Value is the result of a query */ + List children = XmlUtils.getChildElements(node); + List childAttributes = new ArrayList<>(); + for (Element child : children) { + ITmfXmlStateAttribute queryAttribute = modelFactory.createStateAttribute(child, getSsContainer()); + childAttributes.add(queryAttribute); + } + stateValueType = new TmfXmlStateValueQuery(childAttributes); + break; + default: + throw new IllegalArgumentException(String.format("TmfXmlStateValue constructor: unexpected element %s for stateValue type", type)); //$NON-NLS-1$ + } + return stateValueType; + } + + // ---------------------------------------------------------- + // Internal state value classes for the different types + // ---------------------------------------------------------- + + /** + * Base class for all state value. Contain default methods to handle event, + * process or increment the value + */ + protected abstract class TmfXmlStateValueTypeReadWrite extends TmfXmlStateValueBase { + + @Override + public final void handleEvent(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { + if (isIncrement()) { + incrementValue(event, quark, timestamp); + } else { + ITmfStateValue value = getValue(event); + processValue(quark, timestamp, value); + } + } + + @Override + protected void processValue(int quark, long timestamp, ITmfStateValue value) throws AttributeNotFoundException, TimeRangeException, StateValueTypeException { + switch (getStackType()) { + case POP: + getStateSystem().popAttribute(timestamp, quark); + break; + case PUSH: + getStateSystem().pushAttribute(timestamp, value, quark); + break; + case NULL: + case PEEK: + default: + getStateSystem().modifyAttribute(timestamp, value, quark); + break; + } + } + + @Override + protected void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { + getStateSystem().incrementAttribute(timestamp, quark); + } + } + + /* This state value uses a constant value, defined in the XML */ + private class TmfXmlStateValueTmf extends TmfXmlStateValueTypeReadWrite { + + private final ITmfStateValue fValue; + + public TmfXmlStateValueTmf(ITmfStateValue value) { + fValue = value; + } + + @Override + public ITmfStateValue getValue(ITmfEvent event) { + return fValue; + } + + @Override + public void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { + ITmfStateSystem ss = getStateSystem(); + switch (fValue.getType()) { + case LONG: { + long incrementLong = fValue.unboxLong(); + long currentValue = ss.queryOngoingState(quark).unboxLong(); + ITmfStateValue value = TmfStateValue.newValueLong(incrementLong + currentValue); + processValue(quark, timestamp, value); + return; + } + case INTEGER: { + int increment = fValue.unboxInt(); + int currentValue = ss.queryOngoingState(quark).unboxInt(); + ITmfStateValue value = TmfStateValue.newValueInt(increment + currentValue); + processValue(quark, timestamp, value); + break; + } + case DOUBLE: + case NULL: + case STRING: + default: + Activator.logWarning("TmfXmlStateValue: The increment value is not a number type"); //$NON-NLS-1$ + break; + } + } + } + + /* The state value uses the value of an event field */ + private class TmfXmlStateValueEventField extends TmfXmlStateValueTypeReadWrite { + + private final String fFieldName; + + public TmfXmlStateValueEventField(String field) { + fFieldName = field; + } + + @Override + public ITmfStateValue getValue(ITmfEvent event) { + if (event == null) { + Activator.logWarning("XML State value: requested an event field, but event is null"); //$NON-NLS-1$ + return TmfStateValue.nullValue(); + } + return getEventFieldValue(event, fFieldName); + } + + @Override + public void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { + ITmfStateSystem ss = getSsContainer().getStateSystem(); + ITmfStateValue incrementValue = getValue(event); + switch (incrementValue.getType()) { + case INTEGER: { + int increment = incrementValue.unboxInt(); + int currentValue = ss.queryOngoingState(quark).unboxInt(); + ITmfStateValue value = TmfStateValue.newValueInt(increment + currentValue); + processValue(quark, timestamp, value); + break; + } + case LONG: { + long incrementLong = incrementValue.unboxLong(); + long currentValue = ss.queryOngoingState(quark).unboxLong(); + ITmfStateValue value = TmfStateValue.newValueLong(incrementLong + currentValue); + processValue(quark, timestamp, value); + break; + } + case DOUBLE: + case NULL: + case STRING: + default: + Activator.logWarning(String.format("TmfXmlStateValue: The event field increment %s is not a number type but a %s", fFieldName, incrementValue.getType())); //$NON-NLS-1$ + break; + } + } + } + + /* The state value is the event name */ + private class TmfXmlStateValueEventName extends TmfXmlStateValueTypeReadWrite { + + @Override + public ITmfStateValue getValue(ITmfEvent event) { + if (event == null) { + Activator.logWarning("XML State value: request event name, but event is null"); //$NON-NLS-1$ + return TmfStateValue.nullValue(); + } + return TmfStateValue.newValueString(event.getType().getName()); + } + + } + + /* The state value deletes an attribute */ + private class TmfXmlStateValueDelete extends TmfXmlStateValueTypeReadWrite { + + @Override + public ITmfStateValue getValue(ITmfEvent event) throws AttributeNotFoundException { + return TmfStateValue.nullValue(); + } + + @Override + protected void processValue(int quark, long timestamp, ITmfStateValue value) throws TimeRangeException, AttributeNotFoundException { + ITmfStateSystem ss = getStateSystem(); + if (!(ss instanceof ITmfStateSystemBuilder)) { + throw new IllegalStateException("incrementValue should never be called when not building the state system"); //$NON-NLS-1$ + } + ITmfStateSystemBuilder builder = (ITmfStateSystemBuilder) ss; + builder.removeAttribute(timestamp, quark); + } + + } + + /* The state value uses the result of a query */ + private class TmfXmlStateValueQuery extends TmfXmlStateValueTypeReadWrite { + + private final List fQueryValue; + + public TmfXmlStateValueQuery(List childAttributes) { + fQueryValue = childAttributes; + } + + @Override + public ITmfStateValue getValue(ITmfEvent event) throws AttributeNotFoundException { + /* Query the state system for the value */ + ITmfStateValue value = TmfStateValue.nullValue(); + int quarkQuery = IXmlStateSystemContainer.ROOT_QUARK; + ITmfStateSystem ss = getStateSystem(); + + for (ITmfXmlStateAttribute attribute : fQueryValue) { + quarkQuery = attribute.getAttributeQuark(event, quarkQuery); + if (quarkQuery == IXmlStateSystemContainer.ERROR_QUARK) { + /* the query is not valid, we stop the state change */ + break; + } + } + /* + * the query can fail : for example, if a value is requested but has + * not been set yet + */ + if (quarkQuery != IXmlStateSystemContainer.ERROR_QUARK) { + value = ss.queryOngoingState(quarkQuery); + } + return value; + } + + @Override + public void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { + ITmfStateSystem ss = getStateSystem(); + ITmfStateValue incrementValue = getValue(event); + switch (incrementValue.getType()) { + case INTEGER: { + int increment = incrementValue.unboxInt(); + int currentValue = ss.queryOngoingState(quark).unboxInt(); + ITmfStateValue value = TmfStateValue.newValueInt(increment + currentValue); + processValue(quark, timestamp, value); + break; + } + case LONG: { + long incrementLong = incrementValue.unboxLong(); + long currentValue = ss.queryOngoingState(quark).unboxLong(); + ITmfStateValue value = TmfStateValue.newValueLong(incrementLong + currentValue); + processValue(quark, timestamp, value); + break; + } + case DOUBLE: + case NULL: + case STRING: + default: + Activator.logWarning("TmfXmlStateValue: The query result increment is not a number type"); //$NON-NLS-1$ + break; + } + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/ITmfXmlTopLevelElement.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/ITmfXmlTopLevelElement.java new file mode 100644 index 0000000000..152c053120 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/ITmfXmlTopLevelElement.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.module; + +/** + * Interface implemented by all classes representing XML top-level elements, for + * example state providers and views + * + * @author Geneviève Bastien + */ +public interface ITmfXmlTopLevelElement { + + /** + * Get the requested value for an attribute. If the value is a pre-defined + * value, we return the string corresponding in the defined values map in + * the top-level XML element. + * + * @param name + * the string to get + * @return the actual string value + */ + String getAttributeValue(String name); + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/IXmlStateSystemContainer.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/IXmlStateSystemContainer.java new file mode 100644 index 0000000000..aa93620dc9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/IXmlStateSystemContainer.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.module; + +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlLocation; + +/** + * Interface that all XML defined objects who provide, use or contain state + * system must implement in order to use the state provider model elements in + * {@link org.eclipse.tracecompass.tmf.analysis.xml.core.model} package + * + * @author Geneviève Bastien + */ +public interface IXmlStateSystemContainer extends ITmfXmlTopLevelElement { + + /** Root quark, to get values at the root of the state system */ + static final int ROOT_QUARK = -1; + /** + * Error quark, value taken when a state system quark query is in error. + * + * FIXME: Originally in the code, the -1 was used for both root quark and + * return errors, so it has the same value as root quark, but maybe it can + * be changed to something else -2? A quark can never be negative + */ + static final int ERROR_QUARK = -1; + + /** + * Get the state system managed by this XML object + * + * @return The state system + */ + ITmfStateSystem getStateSystem(); + + /** + * Get the list of locations defined in this top level XML element + * + * @return The list of {@link TmfXmlLocation} + */ + Iterable getLocations(); + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/Messages.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/Messages.java new file mode 100644 index 0000000000..3c637ff17a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/Messages.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.module; + +import org.eclipse.osgi.util.NLS; + +/** + * Externalized messages for the XML analysis module package + * + * @author Geneviève Bastien + */ +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.analysis.xml.core.module.messages"; //$NON-NLS-1$ + + /** Error copying XML file to workspace folder */ + public static String XmlUtils_ErrorCopyingFile; + /** XML parse error */ + public static String XmlUtils_XmlParseError; + /** Error occurred while validating XML */ + public static String XmlUtils_XmlValidateError; + /** XML validation error */ + public static String XmlUtils_XmlValidationError; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/XmlUtils.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/XmlUtils.java new file mode 100644 index 0000000000..d8437fa982 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/XmlUtils.java @@ -0,0 +1,252 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.module; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; +import java.nio.channels.FileChannel; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.osgi.util.NLS; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.Activator; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +/** + * Class containing some utilities for the XML plug-in packages: for example, it + * manages the XML files and validates them + * + * @author Geneviève Bastien + */ +public class XmlUtils { + + /** Sub-directory of the plug-in where XML files are stored */ + private static final String XML_DIRECTORY = "xml_files"; //$NON-NLS-1$ + + /** Name of the XSD schema file */ + private static final String XSD = "xmlDefinition.xsd"; //$NON-NLS-1$ + + /** Make this class non-instantiable */ + private XmlUtils() { + + } + + /** + * Get the path where the XML files are stored. Create it if it does not + * exist + * + * @return path to XML files + */ + public static IPath getXmlFilesPath() { + IPath path = Activator.getDefault().getStateLocation(); + path = path.addTrailingSeparator().append(XML_DIRECTORY); + + /* Check if directory exists, otherwise create it */ + File dir = path.toFile(); + if (!dir.exists() || !dir.isDirectory()) { + dir.mkdirs(); + } + + return path; + } + + /** + * Validate the XML file input with the XSD schema + * + * @param xmlFile + * XML file to validate + * @return True if the XML validates + */ + public static IStatus xmlValidate(File xmlFile) { + URL url = XmlUtils.class.getResource(XSD); + SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Source xmlSource = new StreamSource(xmlFile); + try { + Schema schema = schemaFactory.newSchema(url); + Validator validator = schema.newValidator(); + validator.validate(xmlSource); + } catch (SAXParseException e) { + String error = NLS.bind(Messages.XmlUtils_XmlParseError, e.getLineNumber(), e.getLocalizedMessage()); + Activator.logError(error); + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, error, e); + } catch (SAXException e) { + String error = NLS.bind(Messages.XmlUtils_XmlValidationError, e.getLocalizedMessage()); + Activator.logError(error); + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, error, e); + } catch (IOException e) { + String error = Messages.XmlUtils_XmlValidateError; + Activator.logError("IO exception occurred", e); //$NON-NLS-1$ + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, error, e); + } + return Status.OK_STATUS; + } + + /** + * Adds an XML file to the plugin's path. The XML file should have been + * validated using the {@link XmlUtils#xmlValidate(File)} method before + * calling this method. + * + * @param fromFile + * The XML file to add + * @return Whether the file was successfully added + */ + public static IStatus addXmlFile(File fromFile) { + + /* Copy file to path */ + File toFile = getXmlFilesPath().addTrailingSeparator().append(fromFile.getName()).toFile(); + + try { + if (!toFile.exists()) { + toFile.createNewFile(); + } + } catch (IOException e) { + String error = Messages.XmlUtils_ErrorCopyingFile; + Activator.logError(error, e); + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, error, e); + } + + try (FileInputStream fis = new FileInputStream(fromFile); + FileOutputStream fos = new FileOutputStream(toFile); + FileChannel source = fis.getChannel(); + FileChannel destination = fos.getChannel();) { + destination.transferFrom(source, 0, source.size()); + } catch (IOException e) { + String error = Messages.XmlUtils_ErrorCopyingFile; + Activator.logError(error, e); + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, error, e); + } + return Status.OK_STATUS; + } + + /** + * Get only the XML element children of an XML element. + * + * @param parent + * The parent element to get children from + * @return The list of children Element of the parent + */ + public static List getChildElements(Element parent) { + NodeList childNodes = parent.getChildNodes(); + List childElements = new ArrayList<>(); + for (int index = 0; index < childNodes.getLength(); index++) { + if (childNodes.item(index).getNodeType() == Node.ELEMENT_NODE) { + childElements.add((Element) childNodes.item(index)); + } + } + return childElements; + } + + /** + * Get the XML children element of an XML element, but only those of a + * certain type + * + * @param parent + * The parent element to get the children from + * @param elementTag + * The tag of the elements to return + * @return The list of children {@link Element} of the parent + */ + public static List getChildElements(Element parent, String elementTag) { + /* get the state providers and find the corresponding one */ + NodeList nodes = parent.getElementsByTagName(elementTag); + List childElements = new ArrayList<>(); + + for (int i = 0; i < nodes.getLength(); i++) { + Element node = (Element) nodes.item(i); + if (node.getParentNode().equals(parent)) { + childElements.add(node); + } + } + return childElements; + } + + /** + * Return the node element corresponding to the requested type in the file. + * + * TODO: Nothing prevents from having duplicate type -> id in a same file. + * That should not be allowed. If you want an element with the same ID as + * another one, it should be in a different file and we should check it at + * validation time. + * + * @param filePath + * The absolute path to the XML file + * @param elementType + * The type of top level element to search for + * @param elementId + * The ID of the desired element + * @return The XML element or null if not found + */ + public static Element getElementInFile(String filePath, @NonNull String elementType, @NonNull String elementId) { + + if (filePath == null) { + return null; + } + + IPath path = new Path(filePath); + File file = path.toFile(); + if (file == null || !file.exists() || !file.isFile() || !xmlValidate(file).isOK()) { + return null; + } + + try { + /* Load the XML File */ + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder; + + dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(file); + doc.getDocumentElement().normalize(); + + /* get the state providers and find the corresponding one */ + NodeList nodes = doc.getElementsByTagName(elementType); + Element foundNode = null; + + for (int i = 0; i < nodes.getLength(); i++) { + Element node = (Element) nodes.item(i); + String id = node.getAttribute(TmfXmlStrings.ID); + if (id.equals(elementId)) { + foundNode = node; + } + } + return foundNode; + } catch (ParserConfigurationException | SAXException | IOException e) { + return null; + } + + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/messages.properties b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/messages.properties new file mode 100644 index 0000000000..2f81a3d996 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/messages.properties @@ -0,0 +1,15 @@ +############################################################################### +# Copyright (c) 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### +XmlUtils_ErrorCopyingFile=An error occurred while copying the XML file to the TMF directory. The file was not imported. +XmlUtils_XmlParseError=XML Parsing error at line {0}: {1} +XmlUtils_XmlValidateError=An error occurred while validating the XML file. +XmlUtils_XmlValidationError=Error validating XML file {0} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/xmlCommon.xsd b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/xmlCommon.xsd new file mode 100644 index 0000000000..453a219155 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/xmlCommon.xsd @@ -0,0 +1,44 @@ + + + + + + + Maps a string (usually a human-readable value used by the XML elements) to another string (a value in the system, which can be converted to an integer, long by the a stateValue element or used as-is). + + + The human-readable string to identify this value. This is what will be manipulated by the XML and shown to the end-user (if applicable). + + + A system value the 'name' maps to. It will usually not be shown to the end user. + + + Optional color attribute to this mapping. This attribute is used in XML-defined views to represent this mapping. + + + + + Define a path in a state system, that can then be used as a shortcut in other XML elements. + + + + Define each element of the path represented by this location. For instance, if location "abc" has path "a/b/c", there would be a sequence of 3 stateAttribute elements of type constant. + + + + The identifier of this location, used inside the XML element in the scope of which it is defined. + + + + diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/xmlDefinition.xsd b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/xmlDefinition.xsd new file mode 100644 index 0000000000..f6e059f796 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/xmlDefinition.xsd @@ -0,0 +1,35 @@ + + + + + + + + + + + + + Define a new time graph view. + + + Define a new XY chart view. + + + Define a new state provider + + + + + diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/xmlStateProvider.xsd b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/xmlStateProvider.xsd new file mode 100644 index 0000000000..dcafbfd6b6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/xmlStateProvider.xsd @@ -0,0 +1,295 @@ + + + + + + + Declares a data-driven state provider which defines how events change the state of attributes of the system. Each state provider defined in XML will become an analysis in TMF. + + + + Provide meta-information on this state provider, like labels and applicable trace types. + + + Define a value that maps a string used in the state provider to a numbered value. + + + Declare shortcuts to frequently used attribute/data locations. For instance, if a path to an often-used attribute is CPUs/{event.some_field}/Threads/Status, it may be a good idea to put this path in a location and then use the location name in the event handlers. + + + Define how a given event will modify the state system being built. For each event in the trace that causes a state change, a event handler should be defined. + + + + The unique ID of this state provider. It will be used to identify the analysis that will be built from this state provider. + + + The version ID of this state provider. Whenever the state provider changes so that the resulting state system is different from previous versions, this version number should be bumped. + + + + + Declares the meta-information that can be defined for an XML state provider. + + + + Indicate that the state provider applies to a given trace type. + + + + The ID of the trace type, as declared in a org.eclipse.linuxtools.tmf.core.tracetype extension point or a custom trace parser. For example: "org.eclipse.linuxtools.lttng2.kernel.tracetype" or "org.eclipse.linuxtools.lttng2.ust.tracetype" for respectively LTTng Kernel and LTTng UST traces. + + + + + Add a label to the state provider. If provided, this text will be the name of the analysis that the user will see in TMF. + + + + The text to name this state provider (and the analysis it will generate). + + + + + + + + Define how an event modifies the state of the system. There should be one event handler for each event causing a state change. + + + + Define how the state system is modified by the event. An event may cause more than one state change. + + + + Name of the event that causes a state change. + + + + + + Define a change of state in the state system being built. + + + + Describe a single attribute assignation. Simply put: a state change where path/to/attribute=value. + + + Explain how to reach an attribute in the state system. It describes the path/to/attribute. + + + Explain how to obtain the value of the state attribute to modify. + + + + Describe a conditional state change, where different path conditions may lead to different state changes. + + + Define the condition to verify. + + + Define the state change to use if the previous condition is true. + + + Optionally define the state change to use if the condition is false. + + + + + + + Define a conditional statement. Conditions may use values of the state system or from the event being handled. This element defines a statement in the form of "if (some_path == value)". + + + + + Compare the current value of an attribute of the state system. + + + Compare the value of an event field. + + + + Define the value to compare to. + + + + + + + Define a conditional statement with only one child. From this element, a condition may be composed of other conditional elements to create more complex conditional statements. + + + + Define a condition element, in the form "if (some_path == value)". + + + Negate the result of the following condition, allowing statements of the form "if (!cond)". + + + ANDs 2 conditional statements, allowing statements of the form "if (condA AND condB)" + + + ORs 2 conditional statements, allowing statements of the form "if (condA OR condB)" + + + + + + + Allows the composition of more than one conditional statements. + + + + Define a condition element, in the form "if (some_path == value)". + + + ORs 2 conditional statements, allowing statements of the form "if (condA OR condB)" + + + ANDs 2 conditional statements, allowing statements of the form "if (condA AND condB)" + + + Negate the result of the following condition, allowing statements of the form "if (!cond)". + + + + + + + Define a path to an attribute of the state system. + + + + If the type is a "query", those stateAttribute elements describe the elements of the query. + + + + The type of path to this attribute. The meaning of those paths type will depend on the context where the stateAttribute is being used. Not all types will make sense everywhere. + + + + + This type does not change the current attribute. Whatever attribute was the reference attribute at a given time, it will be returned as is. + + + This type identifies the state system attribute by a constant string. For instance, if the first level attribute of the state system is "Threads", then a constant type with "Threads" value should be used. + + + This type identifies the attribute by the value of an event field. Note that the event field corresponds to the attribute name, not its value. For example, if the event has a field called "current_cpu" with a value of "2", "2" would be the attribute name we want. + + + This type indicates that the path to the attribute is at the specified location. Location simply avoids having to write full path to an attribute each time it is being used, but the location itself is a sequence of stateAttribute elements. For example, if we previously defined a location named "CurrentThead" for path "CPUs/{current_cpu}/CurrentThread", we can use a stateAttribute of type location with "CurrentThread" value. + + + This type indicates that the path to the attribute is the result of a query. If this type is selected, a sequence of stateAttribute elements needs to be specified for this state attribute. The result of the query is the attribute name of the current element. For example, if the attribute we want is the PID of the current process on CPU 0, that PID can be found through the query "CPUs/0/CurrentThread". The value of this attribute would be, for example, 1234, the attribute we are looking for. + + + + + + The value of this state attribute. A value should be specified only if the type is "constant", "eventField" or "location". + + + + + Define a value, that can be assigned to an attribute of the state system. + + + For a "query" value type, a sequence of stateAttributes will define the query whose result is the value. + + + + + The type of this state value. It will describe how to obtain to value and/or what to do with it. + + + + + Indicate that the value is a null value. + + + The value is a constant of type integer. + + + The value is a constant of type long + + + The value is a constant of type string + + + The value is the content of an event field. The "value" attribute is the field name. To convert this field to a certain type, attribute "forcedType" may be used. + + + The value is the name of the event. + + + Indicate that the attribute the value is to be applied to should be deleted. + + + The value is the result of a query to the state system. If this type is selected, a sequence of stateAttributes must be defined in this stateValue element. + + + + + + Indicate that the current value will be added to any previously available value. + + + Indicate that a stack operation will be performed with the value + + + + + The value will be popped from the stack + + + The value will be pushed on a stack + + + The value will be peeked from the top of the stack, but it will stay there + + + + + + Indicate the desired type for the state value. If the value is not already of this type, a conversion will be attempted. The forcedType is used to convert values of event fields. + + + + + The value should be an integer + + + The value should be a long + + + The value should be a double + + + + + + Indicate what the value is. A value should be specified only if the type is int, long, string or event_field. See the documentation on types for information on what to put for value. + + + + + This element is used in conditions where the value of an event field is compared to something else. It is not the same as the stateAttribute's type eventField, where the eventField is used as the name for an attribute to the state system. + + + Indicate which field to use. + + + diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/xmlView.xsd b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/xmlView.xsd new file mode 100644 index 0000000000..1931843ea7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/xmlView.xsd @@ -0,0 +1,178 @@ + + + + + + + Declares a data-driven time graph view, which defines how the view will display the results of an analysis. For now, only state system analysis are supported by this view. + + + + Provider meta-information on this view, like labels and analysis it applies to. + + + Define a mapping between a human-readable text and the value used in the analysis. The "definedValue"'s optional "color" attribute is the color with which this value will be displayed. + + + Define how to determine the entries (lines) to show on the time graph view. An entry may have children entry elements defined as children, where children are sub-elements of this one (for example, child attributes in the state system). A parent/child relationship may be defined for entries of the same level. See the viewEntry element documentation for more details. + + + + The unique identifier of this view element. It will be used by the framework to identify this view. + + + + + Declares a data-driven XY chart view, which defines how the view will display the results of an analysis. For now, only state system analyses are supported by this view. + + + + Provider meta-information on this view, like labels and analyses it applies to. + + + Define how to determine the entries (series) to show on the XY view. See the xyViewEntry element documentation for more details. + + + + The unique identifier of this view element. It will be used by the framework to identify this view. + + + + + Declares the meta-information that can be defined for an XML time graph view. + + + + Indicate that the view applies to the analysis identified with the given ID. To have a view apply to an XML-defined state system analysis, you'd use the state provider ID in the "stateProvider" element. + + + + The ID of the analysis this view applies to. + + + The ID of the state system this view applies to. The attribute is used only if the analysis contains more than one state system. + + + + + Add a label to the time graph view. If provided, this text will be displayed to the user to identify this view, otherwise, the view's ID will be used. + + + + The text used as a name for this time graph view. + + + + + + + + Define a path to entries in the view. If this element is at the top level, the base path to reach the entry is the root of the state system. Otherwise, it will use the parent element's corresponding attribute as the base. Each view entry element corresponds to a time graph view entry that will actually be displayed. + + + + Indicate the attribute whose value will be displayed in the time graph (the value that changes over time). If this element is not specified, no entry will be created for this element, and all other elements will be ignored. + + + Specify which attribute to use as ID for this entry. This ID will be used in the ID column in the view, and will also be used to build the tree if a parent element is specified. If this element is not present, the display attribute's name will be used as ID. + + + Specify how to find the parent's ID of this entry. By default, the parent/child hierarchy is the same as defined in the timeGraphView element of the XML file. This element will add to this default parent/child relationship so that elements at the same XML-defined level can still have a relationship. + + + Specify how to find the name of this entry. Typically, the name will be human-readable. If not specified, the display attribute's name will be used as the name. + + + Define child entries for this entry. Child entries will be shown as children of this entry (with or without additional parent/child relationship defined through the viewEntry element's "parent" element). + + + + The path of the entry in the state system. Wildcards '*' may be used. For example, to display entries from all CPUs, the path could be "CPUs/*" and one entry will be created for each sub-attribute of the "CPUs" attribute. Each entry will be used as the base for all child elements, unless specified otherwise. + + + + + Define a path to entries in the view. If this element is at the top level, the base path to reach the entry is the root of the state system. Otherwise, it will use the parent element's corresponding attribute as the base. Each XY view entry element corresponds to a series in the resulting view. + + + + Indicate the attribute whose value will be displayed in the time graph (the value that changes over time). If this element is not specified, no entry will be created for this element, and all other elements will be ignored. + + + Specify how to find the name of this entry. Typically, the name will be human-readable. If not specified, the display attribute's name will be used as the name. + + + + The path of the entry in the state system. Wildcards '*' may be used. For example, to display entries from all CPUs, the path could be "CPUs/*" and one series will be created for each sub-attribute of the "CPUs" attribute. Each entry will be used as the base for all child elements, unless specified otherwise. + + + Indicate how to display the value, compared with preceding values. + + + + + The value is shown as is. + + + The value is the difference between the value at current timestamp and the value at the preceding timestamp. + + + + + + + + + + If the type is a "query", those stateAttribute elements describe the elements of the query. + + + + The type of path to this attribute. The value of the other attributes will depend on the selected type. + + + + + This type identifies the state system attribute by a constant string. For instance, if the state system attribute to display is "Status", it would be a constant type with value "Status". + + + This type indicates that the path to the attribute is at the specified location. A location avoids having to write the full path to an attribute every time it is being used. The location itself is a sequence of stateAttribute elements. For example, if we previously defined a location named "Procname" for path "Threads/tid/Procname", we can use a stateAttribute of type location with "Procname" value. + + + This type indicates that the path to the attribute is the result of a query. If this type is selected, a sequence of stateAttribute elements needs to be specified for this viewStateAttribute. The result of the query is the attribute name of the current element. For example, if the attribute we want is the PID of the current process on CPU 0, that PID can be found through the query "CPUs/0/CurrentThread". The value of this attribute would be for example 1234, which is the attribute we are looking for. + + + This type indicates that the requested attribute is the attribute itself. For this attribute, the reference is always relative (setting it to absolute will be ignored). + + + + + + The value of this state attribute. A value should be specified if the type is "constant" or "location". + + + Specify which state system attribute to use as the base to reach this path. It is either absolute or relative. By default, it is relative to the current entry. + + + + + The path will be calculated starting from the entry under which this viewStateAttribute element is defined. + + + The path will be calculated starting from the root of the state system. That means that if the entry itself is one of "CPUs/*", we could reach another attribute from the root of the state system, like "Threads/tid". + + + + + diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/stateprovider/TmfXmlStrings.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/stateprovider/TmfXmlStrings.java new file mode 100644 index 0000000000..0a51d30e74 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/stateprovider/TmfXmlStrings.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2014 Ecole Polytechnique + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Florian Wininger - Initial implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * This file defines all name in the XML Structure for the State Provider + * + * @author Florian Wininger + * @noimplement This interface only contains static defines + */ +@SuppressWarnings({ "javadoc", "nls" }) +@NonNullByDefault +public interface TmfXmlStrings { + + /* XML generic Element attribute names */ + static final String VALUE = "value"; + static final String NAME = "name"; + static final String VERSION = "version"; + static final String TYPE = "type"; + + /* XML header element */ + static final String HEAD = "head"; + static final String TRACETYPE = "traceType"; + static final String ID = "id"; + static final String LABEL = "label"; + static final String ANALYSIS = "analysis"; + + /* XML String */ + static final String NULL = ""; + static final String WILDCARD = "*"; + static final String VARIABLE_PREFIX = "$"; + static final String COLOR = "color"; + static final String COLOR_PREFIX = "#"; + + /* XML Element Name */ + static final String STATE_PROVIDER = "stateProvider"; + static final String DEFINED_VALUE = "definedValue"; + static final String LOCATION = "location"; + static final String EVENT_HANDLER = "eventHandler"; + static final String STATE_ATTRIBUTE = "stateAttribute"; + static final String STATE_VALUE = "stateValue"; + static final String STATE_CHANGE = "stateChange"; + static final String ELEMENT_FIELD = "field"; + + /* XML Condition strings */ + static final String IF = "if"; + static final String CONDITION = "condition"; + static final String THEN = "then"; + static final String ELSE = "else"; + + /* XML event handler strings */ + static final String HANDLER_EVENT_NAME = "eventName"; + + /* XML constant for Type of Attribute and Value */ + static final String TYPE_NULL = "null"; + static final String TYPE_CONSTANT = "constant"; + static final String EVENT_FIELD = "eventField"; + static final String TYPE_LOCATION = "location"; + static final String TYPE_QUERY = "query"; + static final String TYPE_SELF = "self"; + static final String TYPE_INT = "int"; + static final String TYPE_LONG = "long"; + static final String TYPE_STRING = "string"; + static final String TYPE_EVENT_NAME = "eventName"; + static final String TYPE_DELETE = "delete"; + static final String INCREMENT = "increment"; + static final String FORCED_TYPE = "forcedType"; + static final String ATTRIBUTE_STACK = "stack"; + static final String STACK_POP = "pop"; + static final String STACK_PUSH = "push"; + static final String STACK_PEEK = "peek"; + static final String CPU = "cpu"; + + /** + * @since 1.2 + */ + static final String TIMESTAMP = "timestamp"; + + /* Operator type */ + static final String NOT = "not"; + static final String AND = "and"; + static final String OR = "or"; + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/stateprovider/XmlStateProvider.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/stateprovider/XmlStateProvider.java new file mode 100644 index 0000000000..574a9e27ed --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/stateprovider/XmlStateProvider.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Florian Wininger - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.ITmfXmlModelFactory; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlEventHandler; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlLocation; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.readwrite.TmfXmlReadWriteModelFactory; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/** + * This is the state change input plug-in for TMF's state system which handles + * the XML Format + * + * @author Florian Wininger + */ +public class XmlStateProvider extends AbstractTmfStateProvider implements IXmlStateSystemContainer { + + private final IPath fFilePath; + @NonNull private final String fStateId; + + /** List of all Event Handlers */ + private final Set fEventHandlers = new HashSet<>(); + + /** List of all Locations */ + private final Set fLocations; + + /** Map for defined values */ + private final Map fDefinedValues = new HashMap<>(); + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Instantiate a new state provider plug-in. + * + * @param trace + * The trace + * @param stateid + * The state system id, corresponding to the analysis_id + * attribute of the state provider element of the XML file + * @param file + * Path to the XML file containing the state provider definition + */ + public XmlStateProvider(ITmfTrace trace, @NonNull String stateid, IPath file) { + super(trace, ITmfEvent.class, stateid); + fStateId = stateid; + fFilePath = file; + Element doc = XmlUtils.getElementInFile(fFilePath.makeAbsolute().toOSString(), TmfXmlStrings.STATE_PROVIDER, fStateId); + if (doc == null) { + fLocations = new HashSet<>(); + return; + } + + ITmfXmlModelFactory modelFactory = TmfXmlReadWriteModelFactory.getInstance(); + /* parser for defined Values */ + NodeList definedStateNodes = doc.getElementsByTagName(TmfXmlStrings.DEFINED_VALUE); + for (int i = 0; i < definedStateNodes.getLength(); i++) { + Element element = (Element) definedStateNodes.item(i); + fDefinedValues.put(element.getAttribute(TmfXmlStrings.NAME), element.getAttribute(TmfXmlStrings.VALUE)); + } + + /* parser for the locations */ + NodeList locationNodes = doc.getElementsByTagName(TmfXmlStrings.LOCATION); + Set locations = new HashSet<>(); + for (int i = 0; i < locationNodes.getLength(); i++) { + Element element = (Element) locationNodes.item(i); + TmfXmlLocation location = modelFactory.createLocation(element, this); + locations.add(location); + } + fLocations = Collections.unmodifiableSet(locations); + + /* parser for the event handlers */ + NodeList nodes = doc.getElementsByTagName(TmfXmlStrings.EVENT_HANDLER); + for (int i = 0; i < nodes.getLength(); i++) { + Element element = (Element) nodes.item(i); + TmfXmlEventHandler handler = modelFactory.createEventHandler(element, this); + fEventHandlers.add(handler); + } + } + + /** + * Get the state id of the state provider + * + * @return The state id of the state provider + */ + @NonNull + public String getStateId() { + return fStateId; + } + + // ------------------------------------------------------------------------ + // IStateChangeInput + // ------------------------------------------------------------------------ + + @Override + public int getVersion() { + Element ssNode = XmlUtils.getElementInFile(fFilePath.makeAbsolute().toOSString(), TmfXmlStrings.STATE_PROVIDER, fStateId); + if (ssNode != null) { + return Integer.parseInt(ssNode.getAttribute(TmfXmlStrings.VERSION)); + } + /* + * The version attribute is mandatory and XML files that don't validate + * with the XSD are ignored, so this should never happen + */ + throw new IllegalStateException("The state provider XML node should have a version attribute"); //$NON-NLS-1$ + } + + @Override + public XmlStateProvider getNewInstance() { + return new XmlStateProvider(this.getTrace(), getStateId(), fFilePath); + } + + @Override + protected void eventHandle(ITmfEvent event) { + if (event == null) { + return; + } + for (TmfXmlEventHandler eventHandler : fEventHandlers) { + eventHandler.handleEvent(event); + } + } + + @Override + public ITmfStateSystem getStateSystem() { + return ss; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Override + public Iterable getLocations() { + return fLocations; + } + + /** + * Get the defined value associated with a constant + * + * @param constant + * The constant defining this value + * @return The actual value corresponding to this constant + */ + public String getDefinedValue(String constant) { + return fDefinedValues.get(constant); + } + + @Override + public String getAttributeValue(String name) { + String attribute = name; + if (attribute.startsWith(TmfXmlStrings.VARIABLE_PREFIX)) { + /* search the attribute in the map without the fist character $ */ + attribute = getDefinedValue(attribute.substring(1)); + } + return attribute; + } + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/stateprovider/XmlStateSystemModule.java b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/stateprovider/XmlStateSystemModule.java new file mode 100644 index 0000000000..0a55f106ad --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/stateprovider/XmlStateSystemModule.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider; + +import java.util.List; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.w3c.dom.Element; + +/** + * Analysis module for the data-driven state systems, defined in XML. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class XmlStateSystemModule extends TmfStateSystemAnalysisModule { + + private @Nullable IPath fXmlFile; + + @Override + protected StateSystemBackendType getBackendType() { + return StateSystemBackendType.FULL; + } + + @Override + @NonNull + protected ITmfStateProvider createStateProvider() { + return new XmlStateProvider(getTrace(), getId(), fXmlFile); + } + + @Override + public String getName() { + String name = getId(); + IPath xmlFile = fXmlFile; + if (xmlFile == null) { + return name; + } + Element doc = XmlUtils.getElementInFile(xmlFile.makeAbsolute().toString(), TmfXmlStrings.STATE_PROVIDER, getId()); + /* Label may be available in XML header */ + List head = XmlUtils.getChildElements(doc, TmfXmlStrings.HEAD); + if (head.size() == 1) { + List labels = XmlUtils.getChildElements(head.get(0), TmfXmlStrings.LABEL); + if (!labels.isEmpty()) { + name = labels.get(0).getAttribute(TmfXmlStrings.VALUE); + } + } + + return name; + } + + /** + * Sets the file path of the XML file containing the state provider + * + * @param file + * The full path to the XML file + */ + public void setXmlFile(IPath file) { + fXmlFile = file; + } + + /** + * Get the path to the XML file containing this state provider definition. + * + * @return XML file path + */ + public IPath getXmlFile() { + return fXmlFile; + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/META-INF/MANIFEST.MF b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/META-INF/MANIFEST.MF index f4e27b4213..0b1e4b0ed7 100644 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.eclipse.tracecompass.tmf.analysis.xml.ui.tests;singleton:=true Bundle-Version: 1.1.0.qualifier -Bundle-Activator: org.eclipse.linuxtools.tmf.analysis.xml.ui.tests.Activator +Bundle-Activator: org.eclipse.tracecompass.tmf.analysis.xml.ui.tests.Activator Bundle-Vendor: %Bundle-Vendor Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime, @@ -18,4 +18,4 @@ Require-Bundle: org.eclipse.ui, Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Bundle-ActivationPolicy: lazy Import-Package: org.junit.runners -Export-Package: org.eclipse.linuxtools.tmf.analysis.xml.ui.tests +Export-Package: org.eclipse.tracecompass.tmf.analysis.xml.ui.tests diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/pom.xml b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/pom.xml index c497419065..9c8af9a391 100644 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/pom.xml +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/pom.xml @@ -42,7 +42,7 @@ ${tycho-version} org.eclipse.tracecompass.tmf.analysis.xml.ui.tests - org.eclipse.linuxtools.tmf.analysis.xml.ui.tests.AllAnalysisXmlUiTests + org.eclipse.tracecompass.tmf.analysis.xml.ui.tests.AllAnalysisXmlUiTests true true ${tycho.testArgLine} ${base.ui.test.vmargs} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/Activator.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/Activator.java deleted file mode 100644 index 8d5988172e..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/Activator.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.ui.tests; - -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.linuxtools.tmf.analysis.xml.ui.tests"; //$NON-NLS-1$ - - // The shared instance - private static Activator plugin; - - /** - * The constructor - */ - public Activator() { - } - - @Override - public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - } - - @Override - 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; - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/AllAnalysisXmlUiTests.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/AllAnalysisXmlUiTests.java deleted file mode 100644 index 61e085c0b3..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/AllAnalysisXmlUiTests.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.ui.tests; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Master test suite for TMF XML Analysis UI plug-in. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - XmlAnalysisUiPluginTest.class, - org.eclipse.linuxtools.tmf.analysis.xml.ui.tests.module.AllTests.class -}) -public class AllAnalysisXmlUiTests { - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/XmlAnalysisUiPluginTest.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/XmlAnalysisUiPluginTest.java deleted file mode 100644 index 4fdef05294..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/XmlAnalysisUiPluginTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.ui.tests; - -import static org.junit.Assert.assertEquals; - -import org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.Activator; -import org.junit.Test; - -/** - * Test the XML Analysis UI plug-in activator - * - * @author Geneviève Bastien - */ -public class XmlAnalysisUiPluginTest { - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // Plug-in instantiation - static final Activator fPlugin = new Activator(); - - // ------------------------------------------------------------------------ - // Test cases - // ------------------------------------------------------------------------ - - /** - * Test the plugin ID. - */ - @Test - public void testTmfCorePluginId() { - assertEquals("Plugin ID", "org.eclipse.linuxtools.tmf.analysis.xml.ui", Activator.PLUGIN_ID); - } - - /** - * Test the getDefault() static method. - */ - @Test - public void testGetDefault() { - Activator plugin = Activator.getDefault(); - assertEquals("getDefault()", plugin, fPlugin); - } -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/module/AllTests.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/module/AllTests.java deleted file mode 100644 index 865fd02ec8..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/module/AllTests.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.ui.tests.module; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite for org.eclipse.linuxtools.tmf.analysis.xml.ui.module package - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - XmlAnalysisModuleSourceTest.class -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/module/XmlAnalysisModuleSourceTest.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/module/XmlAnalysisModuleSourceTest.java deleted file mode 100644 index 697806f0d0..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/tests/module/XmlAnalysisModuleSourceTest.java +++ /dev/null @@ -1,134 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.ui.tests.module; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.File; -import java.util.Map; - -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.analysis.xml.core.tests.common.TmfXmlTestFiles; -import org.eclipse.linuxtools.tmf.analysis.xml.ui.module.XmlAnalysisModuleSource; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Test suite for the {@link XmlAnalysisModuleSource} class - * - * @author Geneviève Bastien - */ -public class XmlAnalysisModuleSourceTest { - - private static final String SS_MODULE = "kernel.linux.sp"; - private static final String BUILTIN_MODULE = "test.builtin.sp"; - - private static void emptyXmlFolder() { - File fFolder = XmlUtils.getXmlFilesPath().toFile(); - if (!(fFolder.isDirectory() && fFolder.exists())) { - return; - } - for (File xmlFile : fFolder.listFiles()) { - xmlFile.delete(); - } - XmlAnalysisModuleSource.notifyModuleChange(); - } - - /** - * Empty the XML directory before the test, just in case - */ - @Before - public void setUp() { - emptyXmlFolder(); - } - - /** - * Empty the XML directory after the test - */ - @After - public void cleanUp() { - emptyXmlFolder(); - } - - /** - * Test the {@link XmlAnalysisModuleSource#getAnalysisModules()} method - */ - @Test - public void testPopulateModules() { - XmlAnalysisModuleSource module = new XmlAnalysisModuleSource(); - - Iterable modules = module.getAnalysisModules(); - assertFalse(findModule(modules, SS_MODULE)); - - /* Test that the builtin module is present */ - assertTrue(findModule(modules, BUILTIN_MODULE)); - - /* use the valid XML test file */ - File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile(); - if ((testXmlFile == null) || !testXmlFile.exists()) { - fail("XML test file does not exist"); - } - - XmlUtils.addXmlFile(testXmlFile); - XmlAnalysisModuleSource.notifyModuleChange(); - modules = module.getAnalysisModules(); - - assertTrue(modules.iterator().hasNext()); - assertTrue(findModule(modules, SS_MODULE)); - assertTrue(findModule(modules, BUILTIN_MODULE)); - } - - private static boolean findModule(Iterable modules, String moduleName) { - for (IAnalysisModuleHelper helper : modules) { - if (moduleName.equals(helper.getId())) { - return true; - } - } - return false; - } - - /** - * Test that XML modules are available through the analysis manager - */ - @Test - public void testPopulateModulesWithAnalysisManager() { - - /* - * Make sure module sources are initialized. When run as unit test, the - * XML module source is sometimes missing - */ - TmfAnalysisManager.initialize(); - - Map modules = TmfAnalysisManager.getAnalysisModules(); - assertFalse(findModule(modules.values(), SS_MODULE)); - /* Test that the builtin module is present */ - assertTrue(findModule(modules.values(), BUILTIN_MODULE)); - - /* use the valid XML test file */ - File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile(); - if ((testXmlFile == null) || !testXmlFile.exists()) { - fail("XML test file does not exist"); - } - - XmlUtils.addXmlFile(testXmlFile); - XmlAnalysisModuleSource.notifyModuleChange(); - modules = TmfAnalysisManager.getAnalysisModules(); - assertTrue(findModule(modules.values(), SS_MODULE)); - assertTrue(findModule(modules.values(), BUILTIN_MODULE)); - } -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/Activator.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/Activator.java new file mode 100644 index 0000000000..50b0c48cf5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/Activator.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.ui.tests; + +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.linuxtools.tmf.analysis.xml.ui.tests"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + @Override + 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; + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/AllAnalysisXmlUiTests.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/AllAnalysisXmlUiTests.java new file mode 100644 index 0000000000..1637d173ee --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/AllAnalysisXmlUiTests.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.ui.tests; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Master test suite for TMF XML Analysis UI plug-in. + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + XmlAnalysisUiPluginTest.class, + org.eclipse.tracecompass.tmf.analysis.xml.ui.tests.module.AllTests.class +}) +public class AllAnalysisXmlUiTests { + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/XmlAnalysisUiPluginTest.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/XmlAnalysisUiPluginTest.java new file mode 100644 index 0000000000..5b38821db6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/XmlAnalysisUiPluginTest.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.ui.tests; + +import static org.junit.Assert.assertEquals; + +import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.Activator; +import org.junit.Test; + +/** + * Test the XML Analysis UI plug-in activator + * + * @author Geneviève Bastien + */ +public class XmlAnalysisUiPluginTest { + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // Plug-in instantiation + static final Activator fPlugin = new Activator(); + + // ------------------------------------------------------------------------ + // Test cases + // ------------------------------------------------------------------------ + + /** + * Test the plugin ID. + */ + @Test + public void testTmfCorePluginId() { + assertEquals("Plugin ID", "org.eclipse.linuxtools.tmf.analysis.xml.ui", Activator.PLUGIN_ID); + } + + /** + * Test the getDefault() static method. + */ + @Test + public void testGetDefault() { + Activator plugin = Activator.getDefault(); + assertEquals("getDefault()", plugin, fPlugin); + } +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/module/AllTests.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/module/AllTests.java new file mode 100644 index 0000000000..656e0878fd --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/module/AllTests.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.ui.tests.module; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for org.eclipse.linuxtools.tmf.analysis.xml.ui.module package + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + XmlAnalysisModuleSourceTest.class +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/module/XmlAnalysisModuleSourceTest.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/module/XmlAnalysisModuleSourceTest.java new file mode 100644 index 0000000000..45f7c0a09c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/tests/module/XmlAnalysisModuleSourceTest.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.ui.tests.module; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.util.Map; + +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.analysis.xml.core.tests.common.TmfXmlTestFiles; +import org.eclipse.tracecompass.tmf.analysis.xml.ui.module.XmlAnalysisModuleSource; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Test suite for the {@link XmlAnalysisModuleSource} class + * + * @author Geneviève Bastien + */ +public class XmlAnalysisModuleSourceTest { + + private static final String SS_MODULE = "kernel.linux.sp"; + private static final String BUILTIN_MODULE = "test.builtin.sp"; + + private static void emptyXmlFolder() { + File fFolder = XmlUtils.getXmlFilesPath().toFile(); + if (!(fFolder.isDirectory() && fFolder.exists())) { + return; + } + for (File xmlFile : fFolder.listFiles()) { + xmlFile.delete(); + } + XmlAnalysisModuleSource.notifyModuleChange(); + } + + /** + * Empty the XML directory before the test, just in case + */ + @Before + public void setUp() { + emptyXmlFolder(); + } + + /** + * Empty the XML directory after the test + */ + @After + public void cleanUp() { + emptyXmlFolder(); + } + + /** + * Test the {@link XmlAnalysisModuleSource#getAnalysisModules()} method + */ + @Test + public void testPopulateModules() { + XmlAnalysisModuleSource module = new XmlAnalysisModuleSource(); + + Iterable modules = module.getAnalysisModules(); + assertFalse(findModule(modules, SS_MODULE)); + + /* Test that the builtin module is present */ + assertTrue(findModule(modules, BUILTIN_MODULE)); + + /* use the valid XML test file */ + File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile(); + if ((testXmlFile == null) || !testXmlFile.exists()) { + fail("XML test file does not exist"); + } + + XmlUtils.addXmlFile(testXmlFile); + XmlAnalysisModuleSource.notifyModuleChange(); + modules = module.getAnalysisModules(); + + assertTrue(modules.iterator().hasNext()); + assertTrue(findModule(modules, SS_MODULE)); + assertTrue(findModule(modules, BUILTIN_MODULE)); + } + + private static boolean findModule(Iterable modules, String moduleName) { + for (IAnalysisModuleHelper helper : modules) { + if (moduleName.equals(helper.getId())) { + return true; + } + } + return false; + } + + /** + * Test that XML modules are available through the analysis manager + */ + @Test + public void testPopulateModulesWithAnalysisManager() { + + /* + * Make sure module sources are initialized. When run as unit test, the + * XML module source is sometimes missing + */ + TmfAnalysisManager.initialize(); + + Map modules = TmfAnalysisManager.getAnalysisModules(); + assertFalse(findModule(modules.values(), SS_MODULE)); + /* Test that the builtin module is present */ + assertTrue(findModule(modules.values(), BUILTIN_MODULE)); + + /* use the valid XML test file */ + File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile(); + if ((testXmlFile == null) || !testXmlFile.exists()) { + fail("XML test file does not exist"); + } + + XmlUtils.addXmlFile(testXmlFile); + XmlAnalysisModuleSource.notifyModuleChange(); + modules = TmfAnalysisManager.getAnalysisModules(); + assertTrue(findModule(modules.values(), SS_MODULE)); + assertTrue(findModule(modules.values(), BUILTIN_MODULE)); + } +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/META-INF/MANIFEST.MF b/org.eclipse.tracecompass.tmf.analysis.xml.ui/META-INF/MANIFEST.MF index acce650122..a7f791aa68 100644 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/META-INF/MANIFEST.MF @@ -5,7 +5,7 @@ Bundle-Vendor: %Bundle-Vendor Bundle-Version: 1.2.0.qualifier Bundle-Localization: plugin Bundle-SymbolicName: org.eclipse.tracecompass.tmf.analysis.xml.ui;singleton:=true -Bundle-Activator: org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.Activator +Bundle-Activator: org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.Activator Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Bundle-ActivationPolicy: lazy Require-Bundle: org.eclipse.ui, @@ -13,9 +13,9 @@ Require-Bundle: org.eclipse.ui, org.eclipse.tracecompass.tmf.core, org.eclipse.tracecompass.tmf.ui, org.eclipse.tracecompass.tmf.analysis.xml.core -Export-Package: org.eclipse.linuxtools.internal.tmf.analysis.xml.ui;x-friends:="org.eclipse.tracecompass.tmf.analysis.xml.ui.tests", - org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.handler;x-internal:=true, - org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.views;x-internal:=true, - org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.views.xychart;x-internal:=true, - org.eclipse.linuxtools.tmf.analysis.xml.ui.module, - org.eclipse.linuxtools.tmf.analysis.xml.ui.views.timegraph +Export-Package: org.eclipse.tracecompass.internal.tmf.analysis.xml.ui;x-friends:="org.eclipse.tracecompass.tmf.analysis.xml.ui.tests", + org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.handler;x-internal:=true, + org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views;x-internal:=true, + org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.xychart;x-internal:=true, + org.eclipse.tracecompass.tmf.analysis.xml.ui.module, + org.eclipse.tracecompass.tmf.analysis.xml.ui.views.timegraph diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/plugin.xml b/org.eclipse.tracecompass.tmf.analysis.xml.ui/plugin.xml index d8a56de6cc..c55e09c127 100644 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/plugin.xml +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/plugin.xml @@ -4,7 +4,7 @@ + class="org.eclipse.tracecompass.tmf.analysis.xml.ui.module.XmlAnalysisModuleSource"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement"> @@ -56,7 +56,7 @@ @@ -68,13 +68,13 @@ operator="and"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement"> @@ -87,7 +87,7 @@ @@ -95,7 +95,7 @@ diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/Activator.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/Activator.java deleted file mode 100644 index 261ab7e821..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/Activator.java +++ /dev/null @@ -1,163 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.analysis.xml.ui; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.ui.plugin.AbstractUIPlugin; -import org.osgi.framework.BundleContext; - -/** - * The activator class controls the plug-in life cycle - * - * @author Geneviève Bastien - */ -public class Activator extends AbstractUIPlugin { - - /** The plug-in ID */ - public static final String PLUGIN_ID = "org.eclipse.linuxtools.tmf.analysis.xml.ui"; //$NON-NLS-1$ - - // The shared instance - private static Activator fPlugin; - - /** - * The constructor - */ - public Activator() { - setDefault(this); - } - - @Override - public void start(BundleContext context) throws Exception { - super.start(context); - setDefault(this); - } - - @Override - public void stop(BundleContext context) throws Exception { - setDefault(null); - super.stop(context); - } - - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static Activator getDefault() { - return fPlugin; - } - - // Sets plug-in instance - private static void setDefault(Activator plugin) { - fPlugin = plugin; - } - - // ------------------------------------------------------------------------ - // Log an IStatus - // ------------------------------------------------------------------------ - - /** - * Log an IStatus object directly - * - * @param status - * The status to log - */ - public static void log(IStatus status) { - fPlugin.getLog().log(status); - } - - // ------------------------------------------------------------------------ - // Log INFO - // ------------------------------------------------------------------------ - - /** - * Logs a message with severity INFO in the runtime log of the plug-in. - * - * @param message - * A message to log - */ - public static void logInfo(String message) { - fPlugin.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity INFO in the runtime log of the - * plug-in. - * - * @param message - * A message to log - * @param exception - * The corresponding exception - */ - public static void logInfo(String message, Throwable exception) { - fPlugin.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message, exception)); - } - - // ------------------------------------------------------------------------ - // Log WARNING - // ------------------------------------------------------------------------ - - /** - * Logs a message and exception with severity WARNING in the runtime log of - * the plug-in. - * - * @param message - * A message to log - */ - public static void logWarning(String message) { - fPlugin.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity WARNING in the runtime log of - * the plug-in. - * - * @param message - * A message to log - * @param exception - * The corresponding exception - */ - public static void logWarning(String message, Throwable exception) { - fPlugin.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message, exception)); - } - - // ------------------------------------------------------------------------ - // Log ERROR - // ------------------------------------------------------------------------ - - /** - * Logs a message and exception with severity ERROR in the runtime log of - * the plug-in. - * - * @param message - * A message to log - */ - public static void logError(String message) { - fPlugin.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity ERROR in the runtime log of - * the plug-in. - * - * @param message - * A message to log - * @param exception - * The corresponding exception - */ - public static void logError(String message, Throwable exception) { - fPlugin.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, exception)); - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/TmfXmlUiStrings.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/TmfXmlUiStrings.java deleted file mode 100644 index 093c090e5e..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/TmfXmlUiStrings.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.analysis.xml.ui; - -import org.eclipse.jdt.annotation.NonNullByDefault; - -/** - * This file defines all names in the XML Structure for UI elements - * - * @author Geneviève Bastien - */ -@SuppressWarnings({ "javadoc", "nls" }) -@NonNullByDefault -public interface TmfXmlUiStrings { - - /* XML generic Element attribute names */ - static final String TIME_GRAPH_VIEW = "timeGraphView"; - static final String XY_VIEW = "xyView"; - - /* View elements and attributes */ - static final String ENTRY_ELEMENT = "entry"; - - /* Elements and attributes of view entries */ - static final String PATH = "path"; - static final String DISPLAY_ELEMENT = "display"; - static final String PARENT_ELEMENT = "parent"; - static final String NAME_ELEMENT = "name"; - static final String ID_ELEMENT = "id"; - static final String DISPLAY_TYPE = "displayType"; - static final String DISPLAY_TYPE_ABSOLUTE = "absolute"; - static final String DISPLAY_TYPE_DELTA = "delta"; - - /* Generic strings for the XML module */ - static final String XML_OUTPUT_DATA = "xmlOutputData"; - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/handler/ImportXmlHandler.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/handler/ImportXmlHandler.java deleted file mode 100644 index 8ea66a3251..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/handler/ImportXmlHandler.java +++ /dev/null @@ -1,110 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.handler; - -import java.io.File; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.analysis.xml.ui.module.Messages; -import org.eclipse.linuxtools.tmf.analysis.xml.ui.module.XmlAnalysisModuleSource; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectModelElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TraceUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -/** - * Imports and validates an XML file - * - * @author Geneviève Bastien - */ -public class ImportXmlHandler extends AbstractHandler { - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - FileDialog dlg = new FileDialog(new Shell(), SWT.OPEN); - dlg.setFilterNames(new String[] { Messages.ImportXmlHandler_ImportXmlFile + " (*.xml)" }); //$NON-NLS-1$ - dlg.setFilterExtensions(new String[] { "*.xml" }); //$NON-NLS-1$ - - String fn = dlg.open(); - if (fn != null) { - File file = new File(fn); - IStatus status = XmlUtils.xmlValidate(file); - if (status.isOK()) { - status = XmlUtils.addXmlFile(file); - if (status.isOK()) { - XmlAnalysisModuleSource.notifyModuleChange(); - /* - * FIXME: It refreshes the list of analysis under a trace, - * but since modules are instantiated when the trace opens, - * the changes won't apply to an opened trace, it needs to - * be closed then reopened - */ - refreshProject(); - } else { - TraceUtils.displayErrorMsg(Messages.ImportXmlHandler_ImportXmlFile, status.getMessage()); - } - } else { - TraceUtils.displayErrorMsg(Messages.ImportXmlHandler_ImportXmlFile, status.getMessage()); - } - } - - return null; - } - - /** - * Refresh the selected project with the new XML file import - */ - private static void refreshProject() { - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return; - } - - // Get the selection - IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - IWorkbenchPart part = page.getActivePart(); - if (part == null) { - return; - } - ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); - if (selectionProvider == null) { - return; - } - ISelection selection = selectionProvider.getSelection(); - - if (selection instanceof TreeSelection) { - TreeSelection sel = (TreeSelection) selection; - // There should be only one item selected as per the plugin.xml - Object element = sel.getFirstElement(); - if (element instanceof TmfProjectModelElement) { - ((TmfProjectModelElement) element).getProject().refresh(); - } - } - - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/XmlViewInfo.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/XmlViewInfo.java deleted file mode 100644 index aa8168e47d..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/XmlViewInfo.java +++ /dev/null @@ -1,159 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.views; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.Activator; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.analysis.xml.ui.module.TmfXmlAnalysisOutputSource; -import org.w3c.dom.Element; - -/** - * Class that manages information about a view: its title, the file, etc. - * - * @author Geneviève Bastien - */ -@NonNullByDefault -public class XmlViewInfo { - - private static final String XML_VIEW_ID_PROPERTY = "XmlViewId"; //$NON-NLS-1$ - private static final String XML_VIEW_FILE_PROPERTY = "XmlViewFile"; //$NON-NLS-1$ - - private final String fViewId; - private @Nullable String fId = null; - private @Nullable String fFilePath = null; - - /** - * Constructor - * - * @param viewId - * The ID of the view - */ - public XmlViewInfo(String viewId) { - fViewId = viewId; - - IDialogSettings settings = getPersistentPropertyStore(); - - fId = settings.get(XML_VIEW_ID_PROPERTY); - fFilePath = settings.get(XML_VIEW_FILE_PROPERTY); - } - - /** - * Set the data for this view and retrieves from it the view ID and the file - * path of the XML element this view uses. - * - * @param data - * A string of the form "XML view ID" + - * {@link TmfXmlAnalysisOutputSource#DATA_SEPARATOR} + - * "path of the file containing the XML element" - */ - public void setViewData(String data) { - String[] idFile = data.split(TmfXmlAnalysisOutputSource.DATA_SEPARATOR); - fId = (idFile.length > 0) ? idFile[0] : null; - fFilePath = (idFile.length > 1) ? idFile[1] : null; - savePersistentData(); - } - - private IDialogSettings getPersistentPropertyStore() { - IDialogSettings settings = Activator.getDefault().getDialogSettings(); - IDialogSettings section = settings.getSection(fViewId); - if (section == null) { - section = settings.addNewSection(fViewId); - if (section == null) { - throw new IllegalStateException(); - } - } - return section; - } - - private void savePersistentData() { - IDialogSettings settings = getPersistentPropertyStore(); - - settings.put(XML_VIEW_ID_PROPERTY, fId); - settings.put(XML_VIEW_FILE_PROPERTY, fFilePath); - } - - /** - * Retrieve the XML element corresponding to the view - * - * @param xmlTag - * The XML tag corresponding to the view element (the type of - * view) - * @return The view {@link Element} - */ - public @Nullable Element getViewElement(String xmlTag) { - String id = fId; - if (id == null) { - return null; - } - Element viewElement = XmlUtils.getElementInFile(fFilePath, xmlTag, id); - return viewElement; - } - - /** - * Get the view title from the header information of the XML view element. - * - * @param viewElement - * The XML view element from which to get the title - * @return The view title - */ - public @Nullable String getViewTitle(Element viewElement) { - List heads = XmlUtils.getChildElements(viewElement, TmfXmlStrings.HEAD); - - String title = null; - if (!heads.isEmpty()) { - Element head = heads.get(0); - /* Set the title of this view from the label in the header */ - List labels = XmlUtils.getChildElements(head, TmfXmlStrings.LABEL); - for (Element label : labels) { - if (!label.getAttribute(TmfXmlStrings.VALUE).isEmpty()) { - title = label.getAttribute(TmfXmlStrings.VALUE); - } - break; - } - } - return title; - } - - /** - * Get the list of analysis IDs this view is for, as listed in the header of - * the XML element - * - * @param viewElement - * The XML view element from which to get the analysis IDs - * @return The list of all analysis IDs this view is for - */ - public Set getViewAnalysisIds(Element viewElement) { - List heads = XmlUtils.getChildElements(viewElement, TmfXmlStrings.HEAD); - - Set analysisIds = new HashSet<>(); - if (!heads.isEmpty()) { - Element head = heads.get(0); - - /* Get the application analysis from the view's XML header */ - List applicableAnalysis = XmlUtils.getChildElements(head, TmfXmlStrings.ANALYSIS); - for (Element oneAnalysis : applicableAnalysis) { - analysisIds.add(oneAnalysis.getAttribute(TmfXmlStrings.ID)); - } - } - return analysisIds; - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/Messages.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/Messages.java deleted file mode 100644 index e548eec689..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/Messages.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.views.xychart; - -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.osgi.util.NLS; - -/** - * Externalized strings for the xml xy chart view package - * - * @author Geneviève Bastien - */ -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.views.xychart.messages"; //$NON-NLS-1$ - /** Default view title */ - public static @Nullable String XmlXYView_DefaultTitle; - - /** Default Viewer title */ - public static @Nullable String XmlXYViewer_DefaultViewerTitle; - /** Default X axix text */ - public static @Nullable String XmlXYViewer_DefaultXAxis; - /** Default Y axis text */ - public static @Nullable String XmlXYViewer_DefaultYAxis; - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/XmlXYView.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/XmlXYView.java deleted file mode 100644 index fca95f7146..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/XmlXYView.java +++ /dev/null @@ -1,105 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.views.xychart; - -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.TmfXmlUiStrings; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.views.XmlViewInfo; -import org.eclipse.linuxtools.tmf.ui.viewers.xycharts.TmfXYChartViewer; -import org.eclipse.linuxtools.tmf.ui.views.TmfChartView; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.w3c.dom.Element; - -/** - * This view displays state system data in an xy chart. It uses an XML - * {@link TmfXmlUiStrings#XY_VIEW} element from an XML file. This element - * defines which entries from the state system will be shown and also gives - * additional information on the presentation of the view. - * - * @author Geneviève Bastien - */ -public class XmlXYView extends TmfChartView { - - /** View ID. */ - public static final String ID = "org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.views.xyview"; //$NON-NLS-1$ - - private final XmlViewInfo fViewInfo = new XmlViewInfo(ID); - - /** - * Default constructor - */ - public XmlXYView() { - super(Messages.XmlXYView_DefaultTitle); - - this.addPartPropertyListener(new IPropertyChangeListener() { - @Override - public void propertyChange(@Nullable PropertyChangeEvent event) { - if (event == null) { - return; - } - if (event.getProperty().equals(TmfXmlUiStrings.XML_OUTPUT_DATA)) { - Object newValue = event.getNewValue(); - if (newValue instanceof String) { - fViewInfo.setViewData((String) newValue); - setViewTitle(); - TmfXYChartViewer viewer = getChartViewer(); - if (viewer instanceof XmlXYViewer) { - ((XmlXYViewer) viewer).viewInfoUpdated(); - } - - } - } - } - - }); - setViewTitle(); - } - - @Override - public void createPartControl(@Nullable Composite parent) { - setChartViewer(new XmlXYViewer(parent, fViewInfo)); - super.createPartControl(parent); - } - - @Override - public void setFocus() { - - } - - private void setViewTitle() { - /* - * Get the view element from the XML file. If the element can't be - * found, return. - */ - Element viewElement = fViewInfo.getViewElement(TmfXmlUiStrings.XY_VIEW); - if (viewElement == null) { - return; - } - - String title = fViewInfo.getViewTitle(viewElement); - if (title == null) { - title = Messages.XmlXYView_DefaultTitle; - } - final String viewTitle = title; - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - setPartName(viewTitle); - } - }); - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/XmlXYViewer.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/XmlXYViewer.java deleted file mode 100644 index e47ec07222..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/XmlXYViewer.java +++ /dev/null @@ -1,414 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.views.xychart; - -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.regex.Pattern; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.TmfXmlUiStrings; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.views.XmlViewInfo; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlModelFactory; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlStateAttribute; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlLocation; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.readonly.TmfXmlReadOnlyModelFactory; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfAnalysisModuleWithStateSystems; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.viewers.xycharts.linecharts.TmfCommonXLineChartViewer; -import org.eclipse.swt.widgets.Composite; -import org.w3c.dom.Element; - -/** - * Main viewer to display XML-defined xy charts. It uses an XML - * {@link TmfXmlUiStrings#XY_VIEW} element from an XML file. This element - * defines which entries from the state system will be shown and also gives - * additional information on the presentation of the view. - * - * @author Geneviève Bastien - */ -public class XmlXYViewer extends TmfCommonXLineChartViewer { - - private static final String SPLIT_STRING = "/"; //$NON-NLS-1$ - /** Timeout between updates in the updateData thread */ - private static final long BUILD_UPDATE_TIMEOUT = 500; - - @SuppressWarnings("null") - private static final @NonNull Pattern WILDCARD_PATTERN = Pattern.compile("\\*"); //$NON-NLS-1$ - - private final ITmfXmlModelFactory fFactory = TmfXmlReadOnlyModelFactory.getInstance(); - private final Map fSeriesData = new HashMap<>(); - - private final XmlViewInfo fViewInfo; - - /** XML Model elements to use to create the series */ - private @Nullable ITmfXmlStateAttribute fDisplay; - private @Nullable ITmfXmlStateAttribute fSeriesName; - private @Nullable XmlXYEntry fEntry; - - private enum DisplayType { - ABSOLUTE, - DELTA - } - - /** - * The information related to one series on the chart - */ - private class SeriesData { - - private final double[] fYValues; - private final @Nullable double[] fYAbsoluteValues; - private final Integer fDisplayQuark; - private final String fName; - private final DisplayType fType; - - public SeriesData(int length, int attributeQuark, String seriesName, DisplayType type) { - fYValues = new double[length]; - fDisplayQuark = attributeQuark; - fName = seriesName; - fType = type; - switch (fType) { - case DELTA: - fYAbsoluteValues = new double[length]; - break; - case ABSOLUTE: - default: - fYAbsoluteValues = null; - break; - } - - } - - public double[] getYValues() { - return fYValues; - } - - public Integer getDisplayQuark() { - return fDisplayQuark; - } - - public String getSeriesName() { - return fName; - } - - public void setYValue(int i, double yvalue) { - switch (fType) { - case DELTA: - double[] absoluteVals = fYAbsoluteValues; - if (absoluteVals == null) { - throw new IllegalStateException(); - } - absoluteVals[i] = yvalue; - /* - * At the first timestamp, the delta value should be 0 since we - * do not have the previous values - */ - double prevValue = yvalue; - if (i > 0) { - prevValue = absoluteVals[i - 1]; - } - fYValues[i] = yvalue - prevValue; - break; - case ABSOLUTE: - default: - fYValues[i] = yvalue; - break; - } - - } - } - - private static class XmlXYEntry implements IXmlStateSystemContainer { - - private final ITmfStateSystem fStateSystem; - private final String fPath; - private final DisplayType fType; - - public XmlXYEntry(ITmfStateSystem stateSystem, String path, Element entryElement) { - fStateSystem = stateSystem; - fPath = path; - switch (entryElement.getAttribute(TmfXmlUiStrings.DISPLAY_TYPE)) { - case TmfXmlUiStrings.DISPLAY_TYPE_DELTA: - fType = DisplayType.DELTA; - break; - case TmfXmlUiStrings.DISPLAY_TYPE_ABSOLUTE: - default: - fType = DisplayType.ABSOLUTE; - break; - } - } - - @Override - public @Nullable String getAttributeValue(@Nullable String name) { - return name; - } - - @Override - public ITmfStateSystem getStateSystem() { - return fStateSystem; - } - - @Override - public @Nullable Iterable getLocations() { - return Collections.EMPTY_SET; - } - - public DisplayType getType() { - return fType; - } - - public List getQuarks() { - /* Get the list of quarks to process with this path */ - String[] paths = fPath.split(SPLIT_STRING); - @SuppressWarnings("null") - @NonNull List quarks = Collections.singletonList(IXmlStateSystemContainer.ROOT_QUARK); - - try { - for (String path : paths) { - List subQuarks = new LinkedList<>(); - /* Replace * by .* to have a regex string */ - String name = WILDCARD_PATTERN.matcher(path).replaceAll(".*"); //$NON-NLS-1$ - for (int relativeQuark : quarks) { - subQuarks.addAll(fStateSystem.getSubAttributes(relativeQuark, false, name)); - } - quarks = subQuarks; - } - } catch (AttributeNotFoundException e) { - /* - * We get all attributes from the state system itself, this - * should not happen. - */ - throw new IllegalStateException(); - } - return quarks; - } - } - - /** - * Constructor - * - * @param parent - * parent view - * @param viewInfo - * The view info object - */ - public XmlXYViewer(@Nullable Composite parent, XmlViewInfo viewInfo) { - super(parent, Messages.XmlXYViewer_DefaultViewerTitle, Messages.XmlXYViewer_DefaultXAxis, Messages.XmlXYViewer_DefaultYAxis); - fViewInfo = viewInfo; - } - - @Override - protected void updateData(long start, long end, int nb, @Nullable IProgressMonitor monitor) { - - ITmfXmlStateAttribute display = fDisplay; - ITmfXmlStateAttribute seriesNameAttrib = fSeriesName; - XmlXYEntry entry = fEntry; - if (getTrace() == null || display == null || entry == null) { - return; - } - ITmfStateSystem ss = entry.getStateSystem(); - - double[] xvalues = getXAxis(start, end, nb); - setXAxis(xvalues); - - boolean complete = false; - long currentEnd = start; - - while (!complete && currentEnd < end) { - if (monitor != null && monitor.isCanceled()) { - return; - } - - complete = ss.waitUntilBuilt(BUILD_UPDATE_TIMEOUT); - currentEnd = ss.getCurrentEndTime(); - try { - List quarks = entry.getQuarks(); - long traceStart = getStartTime(); - long traceEnd = getEndTime(); - long offset = this.getTimeOffset(); - - /* Initialize quarks and series names */ - for (int quark : quarks) { - String seriesName = null; - if (seriesNameAttrib == null) { - seriesName = ss.getAttributeName(quark); - } else { - int seriesNameQuark = seriesNameAttrib.getAttributeQuark(quark); - try { - ITmfStateValue seriesNameValue = ss.querySingleState(start, seriesNameQuark).getStateValue(); - if (!seriesNameValue.isNull()) { - seriesName = seriesNameValue.toString(); - } - if (seriesName == null || seriesName.isEmpty()) { - seriesName = ss.getAttributeName(quark); - } - } catch (TimeRangeException e) { - /* - * The attribute did not exist at this point, simply - * use attribute name as series name - */ - seriesName = ss.getAttributeName(quark); - } - } - if (seriesName == null) { - throw new IllegalStateException(); - } - fSeriesData.put(quark, new SeriesData(xvalues.length, display.getAttributeQuark(quark), seriesName, entry.getType())); - } - double yvalue = 0.0; - for (int i = 0; i < xvalues.length; i++) { - if (monitor != null && monitor.isCanceled()) { - return; - } - double x = xvalues[i]; - long time = (long) x + offset; - // make sure that time is in the trace range after double to - // long conversion - time = time < traceStart ? traceStart : time; - time = time > traceEnd ? traceEnd : time; - - for (int quark : quarks) { - try { - yvalue = ss.querySingleState(time, fSeriesData.get(quark).getDisplayQuark()).getStateValue().unboxLong(); - fSeriesData.get(quark).setYValue(i, yvalue); - } catch (TimeRangeException e) { - fSeriesData.get(quark).setYValue(i, 0); - } - } - } - for (int quark : quarks) { - setSeries(fSeriesData.get(quark).getSeriesName(), fSeriesData.get(quark).getYValues()); - } - updateDisplay(); - } catch (AttributeNotFoundException | StateValueTypeException e) { - Activator.logError("Error updating the data of XML XY view", e); //$NON-NLS-1$ - } catch (StateSystemDisposedException e) { - return; - } - } - - } - - @Override - protected void initializeDataSource() { - super.initializeDataSource(); - - ITmfTrace trace = this.getTrace(); - if (trace == null) { - return; - } - - Element viewElement = fViewInfo.getViewElement(TmfXmlUiStrings.XY_VIEW); - if (viewElement == null) { - return; - } - - Iterable analysisIds = fViewInfo.getViewAnalysisIds(viewElement); - - List stateSystemModules = new LinkedList<>(); - if (!analysisIds.iterator().hasNext()) { - /* - * No analysis specified, take all state system analysis modules - */ - for (ITmfAnalysisModuleWithStateSystems module : trace.getAnalysisModulesOfClass(ITmfAnalysisModuleWithStateSystems.class)) { - stateSystemModules.add(module); - } - } else { - for (String moduleId : analysisIds) { - @SuppressWarnings("resource") - ITmfAnalysisModuleWithStateSystems module = trace.getAnalysisModuleOfClass(ITmfAnalysisModuleWithStateSystems.class, moduleId); - if (module != null) { - stateSystemModules.add(module); - } - } - } - - /** Initialize the data */ - fDisplay = null; - fSeriesName = null; - ITmfStateSystem ss = null; - fEntry = null; - - /* Schedule all state systems */ - for (ITmfAnalysisModuleWithStateSystems module : stateSystemModules) { - module.schedule(); - if (module instanceof TmfStateSystemAnalysisModule) { - ((TmfStateSystemAnalysisModule) module).waitForInitialization(); - } - for (ITmfStateSystem ssq : module.getStateSystems()) { - if (ssq != null) { - ss = ssq; - break; - } - } - } - if (ss == null) { - return; - } - - /* - * Initialize state attributes. There should be only one entry element - * for XY charts. - */ - List entries = XmlUtils.getChildElements(viewElement, TmfXmlUiStrings.ENTRY_ELEMENT); - Element entryElement = entries.get(0); - String path = entryElement.getAttribute(TmfXmlUiStrings.PATH); - if (path.isEmpty()) { - path = TmfXmlStrings.WILDCARD; - } - XmlXYEntry entry = new XmlXYEntry(ss, path, entryElement); - fEntry = entry; - - /* Get the display element to use */ - List displayElements = XmlUtils.getChildElements(entryElement, TmfXmlUiStrings.DISPLAY_ELEMENT); - if (displayElements.isEmpty()) { - Activator.logWarning(String.format("XML view: entry for %s should have a display element", path)); //$NON-NLS-1$ - return; - } - Element displayElement = displayElements.get(0); - fDisplay = fFactory.createStateAttribute(displayElement, entry); - - /* Get the series name element to use */ - List seriesNameElements = XmlUtils.getChildElements(entryElement, TmfXmlUiStrings.NAME_ELEMENT); - if (!seriesNameElements.isEmpty()) { - Element seriesNameElement = seriesNameElements.get(0); - fSeriesName = fFactory.createStateAttribute(seriesNameElement, entry); - } - - } - - /** - * Tells the viewer that the view info has been updated and the viewer needs - * to be reinitialized - */ - public void viewInfoUpdated() { - reinitialize(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/messages.properties b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/messages.properties deleted file mode 100644 index 77d3f62908..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/messages.properties +++ /dev/null @@ -1,4 +0,0 @@ -XmlXYView_DefaultTitle=Xml XY view -XmlXYViewer_DefaultViewerTitle=Xml XY Chart Viewer -XmlXYViewer_DefaultXAxis=Time -XmlXYViewer_DefaultYAxis=Unit diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/package-info.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/package-info.java deleted file mode 100644 index ff37508327..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/ui/views/xychart/package-info.java +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * École Polytechnique de Montréal - Initial API and implementation - *******************************************************************************/ - -@org.eclipse.jdt.annotation.NonNullByDefault -package org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.views.xychart; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/Messages.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/Messages.java deleted file mode 100644 index c720fa2db5..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/Messages.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.ui.module; - -import org.eclipse.osgi.util.NLS; - -/** - * Externalized messages for the XML analysis module package - * - * @author Geneviève Bastien - */ -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.analysis.xml.ui.module.messages"; //$NON-NLS-1$ - - /** Import XML file title */ - public static String ImportXmlHandler_ImportXmlFile; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/TmfAnalysisModuleHelperXml.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/TmfAnalysisModuleHelperXml.java deleted file mode 100644 index c98966ce33..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/TmfAnalysisModuleHelperXml.java +++ /dev/null @@ -1,184 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.ui.module; - -import java.io.File; -import java.util.Collections; -import java.util.List; - -import org.eclipse.core.runtime.Path; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.Activator; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.XmlStateSystemModule; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisRequirement; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.osgi.framework.Bundle; -import org.w3c.dom.Element; - -/** - * Analysis module helpers for modules provided by XML files - * - * @author Geneviève Bastien - */ -public class TmfAnalysisModuleHelperXml implements IAnalysisModuleHelper { - - /** - * The types of analysis that can be XML-defined - */ - public enum XmlAnalysisModuleType { - /** Analysis will be of type XmlStateSystemModule */ - STATE_SYSTEM - } - - private final File fSourceFile; - private final Element fSourceElement; - private final XmlAnalysisModuleType fType; - - /** - * Constructor - * - * @param xmlFile - * The XML file containing the details of this analysis - * @param node - * The XML node element - * @param type - * The type of analysis - */ - public TmfAnalysisModuleHelperXml(File xmlFile, Element node, XmlAnalysisModuleType type) { - fSourceFile = xmlFile; - fSourceElement = node; - fType = type; - } - - @Override - public String getId() { - return fSourceElement.getAttribute(TmfXmlStrings.ID); - } - - @Override - public String getName() { - String name = null; - /* Label may be available in XML header */ - List head = XmlUtils.getChildElements(fSourceElement, TmfXmlStrings.HEAD); - if (head.size() == 1) { - List labels = XmlUtils.getChildElements(head.get(0), TmfXmlStrings.LABEL); - if (!labels.isEmpty()) { - name = labels.get(0).getAttribute(TmfXmlStrings.VALUE); - } - } - - if (name == null) { - name = getId(); - } - return name; - } - - @Override - public boolean isAutomatic() { - return false; - } - - @Override - public String getHelpText() { - return new String(); - } - - @Override - public String getHelpText(@NonNull ITmfTrace trace) { - return ""; //$NON-NLS-1$ - } - - @Override - public String getIcon() { - return null; - } - - @Override - public Bundle getBundle() { - return Activator.getDefault().getBundle(); - } - - @Override - public boolean appliesToTraceType(Class traceClass) { - /* Trace types may be available in XML header */ - List head = XmlUtils.getChildElements(fSourceElement, TmfXmlStrings.HEAD); - if (head.size() != 1) { - return true; - } - /* - * TODO: Test with custom trace types - */ - List elements = XmlUtils.getChildElements(head.get(0), TmfXmlStrings.TRACETYPE); - if (elements.isEmpty()) { - return true; - } - - for (Element element : elements) { - String traceTypeId = element.getAttribute(TmfXmlStrings.ID); - TraceTypeHelper helper = TmfTraceType.getTraceType(traceTypeId); - if ((helper != null) && helper.getTrace().getClass().isAssignableFrom(traceClass)) { - return true; - } - } - return false; - } - - @Override - public Iterable> getValidTraceTypes() { - return Collections.EMPTY_SET; - } - - @Override - public Iterable getAnalysisRequirements() { - return Collections.EMPTY_SET; - } - - @Override - public IAnalysisModule newModule(ITmfTrace trace) throws TmfAnalysisException { - String analysisid = getId(); - IAnalysisModule module = null; - switch (fType) { - case STATE_SYSTEM: - module = new XmlStateSystemModule(); - XmlStateSystemModule ssModule = (XmlStateSystemModule) module; - module.setId(analysisid); - ssModule.setXmlFile(new Path(fSourceFile.getAbsolutePath())); - - /* - * FIXME: There is no way to know if a module is automatic, so we - * default to true - */ - ssModule.setAutomatic(true); - - break; - default: - break; - - } - if (module != null) { - module.setTrace(trace); - TmfAnalysisManager.analysisModuleCreated(module); - } - - return module; - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/TmfXmlAnalysisOutputSource.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/TmfXmlAnalysisOutputSource.java deleted file mode 100644 index 084097651c..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/TmfXmlAnalysisOutputSource.java +++ /dev/null @@ -1,139 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.ui.module; - -import java.io.File; -import java.io.IOException; -import java.util.List; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.eclipse.core.runtime.IPath; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.TmfXmlUiStrings; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.views.xychart.XmlXYView; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.analysis.xml.ui.views.timegraph.XmlTimeGraphView; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisOutput; -import org.eclipse.linuxtools.tmf.core.analysis.ITmfNewAnalysisModuleListener; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -/** - * This class searches all XML files to find outputs applicable to the newly - * created analysis - * - * @author Geneviève Bastien - */ -public class TmfXmlAnalysisOutputSource implements ITmfNewAnalysisModuleListener { - - /** String separating data elements for the output properties */ - public static final String DATA_SEPARATOR = ";;;"; //$NON-NLS-1$ - - /** - * Enum to match the name of a view's XML element to its view ID. - * @since 1.2 - */ - public static enum ViewType { - /** - * Time graph view element - */ - TIME_GRAPH_VIEW(TmfXmlUiStrings.TIME_GRAPH_VIEW, XmlTimeGraphView.ID), - /** - * XY chart view element - */ - XY_VIEW(TmfXmlUiStrings.XY_VIEW, XmlXYView.ID); - - private final @NonNull String fXmlElem; - private final String fViewId; - - private ViewType(@NonNull String xmlElem, String viewId) { - fXmlElem = xmlElem; - fViewId = viewId; - } - - /** - * Get the XML element corresponding to this view type - * - * @return The XML element corresponding to this type - */ - public @NonNull String getXmlElem() { - return fXmlElem; - } - - private String getViewId() { - return fViewId; - } - } - - - @Override - public void moduleCreated(IAnalysisModule module) { - IPath pathToFiles = XmlUtils.getXmlFilesPath(); - File fFolder = pathToFiles.toFile(); - if (!(fFolder.isDirectory() && fFolder.exists())) { - return; - } - for (File xmlFile : fFolder.listFiles()) { - if (!XmlUtils.xmlValidate(xmlFile).isOK()) { - continue; - } - - try { - /* Load the XML File */ - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - Document doc = dBuilder.parse(xmlFile); - doc.getDocumentElement().normalize(); - - /* get state provider views if the analysis has state systems */ - if (module instanceof TmfStateSystemAnalysisModule) { - for (ViewType viewType : ViewType.values()) { - NodeList ssViewNodes = doc.getElementsByTagName(viewType.getXmlElem()); - for (int i = 0; i < ssViewNodes.getLength(); i++) { - Element node = (Element) ssViewNodes.item(i); - - /* Check if analysis is the right one */ - List headNodes = XmlUtils.getChildElements(node, TmfXmlStrings.HEAD); - if (headNodes.size() != 1) { - continue; - } - - List analysisNodes = XmlUtils.getChildElements(headNodes.get(0), TmfXmlStrings.ANALYSIS); - for (Element analysis : analysisNodes) { - String analysisId = analysis.getAttribute(TmfXmlStrings.ID); - if (analysisId.equals(module.getId())) { - String viewId = viewType.getViewId(); - IAnalysisOutput output = new TmfXmlViewOutput(viewId, viewType); - output.setOutputProperty(TmfXmlUiStrings.XML_OUTPUT_DATA, node.getAttribute(TmfXmlStrings.ID) + DATA_SEPARATOR + xmlFile.getAbsolutePath(), false); - module.registerOutput(output); - } - } - } - } - } - } catch (ParserConfigurationException | SAXException | IOException e) { - Activator.logError("Error opening XML file", e); //$NON-NLS-1$ - } - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/TmfXmlViewOutput.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/TmfXmlViewOutput.java deleted file mode 100644 index 8fb18d619b..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/TmfXmlViewOutput.java +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.ui.module; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.TmfXmlUiStrings; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.analysis.xml.ui.module.TmfXmlAnalysisOutputSource.ViewType; -import org.eclipse.linuxtools.tmf.ui.analysis.TmfAnalysisViewOutput; -import org.w3c.dom.Element; - -/** - * Class overriding the default analysis view output for XML views. These views - * may have labels defined in the XML element and those label will be used as - * the name of the view - * - * @author Geneviève Bastien - * - * TODO: We shouldn't have to do a new class here, we should be able to - * set the name in the parent instead - */ -public class TmfXmlViewOutput extends TmfAnalysisViewOutput { - - private String fLabel = null; - private final @NonNull ViewType fViewType; - - /** - * Constructor - * - * @param viewid - * id of the view to display as output - */ - public TmfXmlViewOutput(String viewid) { - this(viewid, ViewType.TIME_GRAPH_VIEW); - } - - /** - * Constructor - * - * @param viewid - * id of the view to display as output - * @param viewType - * type of view this output is for - * @since 1.2 - */ - public TmfXmlViewOutput(String viewid, @NonNull ViewType viewType) { - super(viewid); - fViewType = viewType; - } - - @Override - public String getName() { - if (fLabel == null) { - return super.getName(); - } - return fLabel; - } - - @Override - public void setOutputProperty(@NonNull String key, String value, boolean immediate) { - super.setOutputProperty(key, value, immediate); - /* Find the label of the view */ - if (key.equals(TmfXmlUiStrings.XML_OUTPUT_DATA)) { - String[] idFile = value.split(TmfXmlAnalysisOutputSource.DATA_SEPARATOR); - String viewId = (idFile.length > 0) ? idFile[0] : null; - String filePath = (idFile.length > 1) ? idFile[1] : null; - if ((viewId == null) || (filePath == null)) { - return; - } - Element viewElement = XmlUtils.getElementInFile(filePath, fViewType.getXmlElem(), viewId); - if (viewElement == null) { - return; - } - List heads = XmlUtils.getChildElements(viewElement, TmfXmlStrings.HEAD); - if (heads.size() != 1) { - return; - } - Element headElement = heads.get(0); - List label = XmlUtils.getChildElements(headElement, TmfXmlStrings.LABEL); - if (label.isEmpty()) { - return; - } - Element labelElement = label.get(0); - fLabel = labelElement.getAttribute(TmfXmlStrings.VALUE); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/XmlAnalysisModuleSource.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/XmlAnalysisModuleSource.java deleted file mode 100644 index 05e5f6a974..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/XmlAnalysisModuleSource.java +++ /dev/null @@ -1,144 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.ui.module; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Platform; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.Activator; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.analysis.xml.ui.module.TmfAnalysisModuleHelperXml.XmlAnalysisModuleType; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleSource; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager; -import org.osgi.framework.Bundle; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -/** - * Analysis module source who creates helpers for the analysis modules described - * in the imported XML files - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class XmlAnalysisModuleSource implements IAnalysisModuleSource { - - /** Extension point ID */ - private static final String TMF_XML_BUILTIN_ID = "org.eclipse.linuxtools.tmf.analysis.xml.core.files"; //$NON-NLS-1$ - private static final String XML_FILE_ELEMENT = "xmlfile"; //$NON-NLS-1$ - - private static final String XML_FILE_ATTRIB = "file"; //$NON-NLS-1$ - - private static List fModules = null; - - /** - * Constructor. It adds the new module listener to the analysis manager. - */ - public XmlAnalysisModuleSource() { - TmfAnalysisManager.addNewModuleListener(new TmfXmlAnalysisOutputSource()); - } - - @Override - public synchronized Iterable getAnalysisModules() { - if (fModules == null) { - fModules = new ArrayList<>(); - populateBuiltinModules(); - populateAnalysisModules(); - } - return fModules; - } - - private static void processFile(File xmlFile) { - if (!XmlUtils.xmlValidate(xmlFile).isOK()) { - return; - } - - try { - /* Load the XML File */ - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - Document doc = dBuilder.parse(xmlFile); - doc.getDocumentElement().normalize(); - - /* get State Providers modules */ - NodeList stateproviderNodes = doc.getElementsByTagName(TmfXmlStrings.STATE_PROVIDER); - for (int i = 0; i < stateproviderNodes.getLength(); i++) { - Element node = (Element) stateproviderNodes.item(i); - - IAnalysisModuleHelper helper = new TmfAnalysisModuleHelperXml(xmlFile, node, XmlAnalysisModuleType.STATE_SYSTEM); - fModules.add(helper); - } - } catch (ParserConfigurationException | SAXException | IOException e) { - Activator.logError("Error opening XML file", e); //$NON-NLS-1$ - } - } - - private static void populateBuiltinModules() { - /* Get the XML files advertised through the extension point */ - IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_XML_BUILTIN_ID); - for (IConfigurationElement element : elements) { - if (element.getName().equals(XML_FILE_ELEMENT)) { - String filename = element.getAttribute(XML_FILE_ATTRIB); - String name = element.getContributor().getName(); - if (name != null) { - Bundle bundle = Platform.getBundle(name); - if (bundle != null) { - try { - URL xmlUrl = bundle.getResource(filename); - URL locatedURL = FileLocator.toFileURL(xmlUrl); - processFile(new File(locatedURL.getFile())); - } catch (IOException e) { - /* ignore */ - } - } - } - } - } - } - - private static void populateAnalysisModules() { - IPath pathToFiles = XmlUtils.getXmlFilesPath(); - File fFolder = pathToFiles.toFile(); - if (!(fFolder.isDirectory() && fFolder.exists())) { - return; - } - for (File xmlFile : fFolder.listFiles()) { - processFile(xmlFile); - } - } - - /** - * Notifies the main XML analysis module that the executable modules list - * may have changed and needs to be refreshed. - */ - public static void notifyModuleChange() { - fModules = null; - TmfAnalysisManager.refreshModules(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/messages.properties b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/messages.properties deleted file mode 100644 index 3059e008b1..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/module/messages.properties +++ /dev/null @@ -1,12 +0,0 @@ -############################################################################### -# Copyright (c) 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### -ImportXmlHandler_ImportXmlFile=Import XML analysis file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/Messages.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/Messages.java deleted file mode 100644 index 700937ce15..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/Messages.java +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.ui.views.timegraph; - -import org.eclipse.osgi.util.NLS; - -/** - * Message for the XML state system view - * - * @author Geneviève Bastien - */ -@SuppressWarnings("javadoc") -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.analysis.xml.ui.views.timegraph.messages"; //$NON-NLS-1$ - - public static String XmlPresentationProvider_MultipleStates; - - /* Default text messages */ - public static String XmlTimeGraphView_ColumnId; - public static String XmlTimeGraphView_ColumnName; - public static String XmlTimeGraphView_ColumnParentId; - public static String XmlTimeGraphView_DefaultTitle; - - /* Text and tooltips of the view */ - public static String XmlTimeGraphView_NextText; - public static String XmlTimeGraphView_NextTooltip; - public static String XmlTimeGraphView_PreviousInterval; - public static String XmlTimeGraphView_PreviousText; - - /* Errors and warnings messages */ - public static String XmlTimeGraphView_UselessEndPath; - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/XmlEntry.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/XmlEntry.java deleted file mode 100644 index 684b30627d..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/XmlEntry.java +++ /dev/null @@ -1,272 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Florian Wininger - Initial API and implementation - * Geneviève Bastien - Review of the initial implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.ui.views.timegraph; - -import java.util.Collections; -import java.util.List; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.TmfXmlUiStrings; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; -import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlModelFactory; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlStateAttribute; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlLocation; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.readonly.TmfXmlReadOnlyModelFactory; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry; -import org.w3c.dom.Element; - -/** - * An XML-defined entry, or row, to display in the XML state system view - * - * @author Florian Wininger - */ -public class XmlEntry extends TimeGraphEntry implements IXmlStateSystemContainer { - - private static final String EMPTY_STRING = ""; //$NON-NLS-1$ - - /** Type of resource */ - public static enum EntryDisplayType { - /** Entries without events to display (filler rows, etc.) */ - NULL, - /** Entries with time events */ - DISPLAY - } - - private final ITmfTrace fTrace; - private final EntryDisplayType fType; - private final int fBaseQuark; - private final int fDisplayQuark; - private final String fParentId; - private final String fId; - private final @NonNull ITmfStateSystem fSs; - private final Element fElement; - - /** - * Constructor - * - * @param baseQuark - * The quark matching this entry, or -1 if no quark - * @param displayQuark - * The quark containing the value to display. It was needed by - * the caller to get the start and end time of this entry, so we - * receive it as parameter from him. - * @param trace - * The trace on which we are working (FIXME: is this parameter - * useful?) - * @param name - * The name of this entry. It will be overridden if a "name" XML - * tag is specified in the entryElement. It will also be used as - * the ID of this entry if no "id" XML tag is specified. It - * typically is the attribute name corresponding the the base - * quark. - * @param startTime - * The start time of this entry lifetime - * @param endTime - * The end time of this entry - * @param type - * The display type of this entry - * @param ss - * The state system this entry belongs to - * @param entryElement - * The XML element describing this entry. This element will be - * used to determine, if available, the parent, ID, name and - * other display option of this entry - */ - public XmlEntry(int baseQuark, int displayQuark, ITmfTrace trace, String name, long startTime, long endTime, EntryDisplayType type, @NonNull ITmfStateSystem ss, Element entryElement) { - super(name, startTime, endTime); - fTrace = trace; - fType = type; - fBaseQuark = baseQuark; - fDisplayQuark = displayQuark; - fSs = ss; - fElement = entryElement; - - /* Get the parent if specified */ - List elements = XmlUtils.getChildElements(fElement, TmfXmlUiStrings.PARENT_ELEMENT); - if (elements.size() > 0) { - fParentId = getFirstValue(elements.get(0)); - } else { - fParentId = EMPTY_STRING; - } - - /* Get the name of this entry */ - elements = XmlUtils.getChildElements(fElement, TmfXmlUiStrings.NAME_ELEMENT); - if (elements.size() > 0) { - String nameFromSs = getFirstValue(elements.get(0)); - if (!nameFromSs.isEmpty()) { - setName(nameFromSs); - } - } - - /* Get the id of this entry */ - elements = XmlUtils.getChildElements(fElement, TmfXmlUiStrings.ID_ELEMENT); - if (elements.size() > 0) { - fId = getFirstValue(elements.get(0)); - } else { - fId = name; - } - - } - - /** - * Constructor - * - * @param baseQuark - * The quark matching this entry, or -1 if no quark - * @param trace - * The trace on which we are working - * @param name - * The exec_name of this entry - * @param ss - * The state system this entry belongs to - */ - public XmlEntry(int baseQuark, ITmfTrace trace, String name, @NonNull ITmfStateSystem ss) { - super(name, ss.getStartTime(), ss.getCurrentEndTime()); - fTrace = trace; - fType = EntryDisplayType.NULL; - fBaseQuark = baseQuark; - fDisplayQuark = baseQuark; - fSs = ss; - fElement = null; - fParentId = EMPTY_STRING; - fId = name; - } - - /** Return the state value of the first interval with a non-null value */ - private String getFirstValue(Element stateAttribute) { - ITmfXmlModelFactory factory = TmfXmlReadOnlyModelFactory.getInstance(); - ITmfXmlStateAttribute display = factory.createStateAttribute(stateAttribute, this); - int quark = display.getAttributeQuark(fBaseQuark); - if (quark != IXmlStateSystemContainer.ERROR_QUARK) { - try { - /* Find the first attribute with a parent */ - List execNameIntervals = fSs.queryHistoryRange(quark, getStartTime(), getEndTime()); - for (ITmfStateInterval execNameInterval : execNameIntervals) { - - if (!execNameInterval.getStateValue().isNull()) { - return execNameInterval.getStateValue().toString(); - } - } - } catch (AttributeNotFoundException | StateSystemDisposedException e) { - } - } - return EMPTY_STRING; - } - - /** - * Get the trace this entry was taken from - * - * @return the entry's trace - */ - public ITmfTrace getTrace() { - return fTrace; - } - - /** - * Get the entry Type of this entry. Uses the inner EntryDisplayType enum. - * - * @return The entry type - */ - public EntryDisplayType getType() { - return fType; - } - - /** - * Get the quark from which to get the time event intervals for this entry. - * - * @return The attribute quark containing the intervals to display - */ - public int getDisplayQuark() { - return fDisplayQuark; - } - - /** - * Get this entry's ID - * - * @return The id of the entry. - */ - public String getId() { - return fId; - } - - /** - * Return the entry's parent ID. It corresponds to another entry's ID - * received from the {@link #getId()} method. - * - * @return The parent ID of this entry - */ - public String getParentId() { - return fParentId; - } - - @Override - public boolean hasTimeEvents() { - if (fType == EntryDisplayType.NULL) { - return false; - } - return true; - } - - /** - * Add a child to this entry of type XmlEntry - * - * @param entry - * The entry to add - */ - public void addChild(XmlEntry entry) { - int index; - for (index = 0; index < getChildren().size(); index++) { - XmlEntry other = (XmlEntry) getChildren().get(index); - if (entry.getType().compareTo(other.getType()) < 0) { - break; - } else if (entry.getType().equals(other.getType())) { - if (entry.getName().compareTo(other.getName()) < 0) { - break; - } - } - } - - entry.setParent(this); - addChild(index, entry); - } - - /** - * Return the state system this entry is associated to - * - * @return The state system, or null if the state system can't - * be found. - */ - @Override - @NonNull - public ITmfStateSystem getStateSystem() { - return fSs; - } - - @Override - public String getAttributeValue(String name) { - return name; - } - - @Override - public Iterable getLocations() { - return Collections.EMPTY_SET; - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/XmlPresentationProvider.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/XmlPresentationProvider.java deleted file mode 100644 index 6d41049bf8..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/XmlPresentationProvider.java +++ /dev/null @@ -1,220 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Florian Wininger - Initial API and implementation - * Geneviève Bastien - Review of the initial implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.ui.views.timegraph; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.TmfXmlUiStrings; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.analysis.xml.ui.views.timegraph.XmlEntry.EntryDisplayType; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.StateItem; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeEvent; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Display; -import org.w3c.dom.Element; - -/** - * Presentation provider for the XML view, based on the generic TMF presentation - * provider. - * - * TODO: This should support colors/states defined for each entry element in the - * XML element. Also, event values may not be integers only (for instance, this - * wouldn't support yet the callstack view) - * - * @author Florian Wininger - */ -public class XmlPresentationProvider extends TimeGraphPresentationProvider { - - private List stateValues = new ArrayList<>(); - /* - * Maps the value of an event with the corresponding index in the - * stateValues list - */ - private Map stateIndex = new HashMap<>(); - - @Override - public int getStateTableIndex(ITimeEvent event) { - if (event instanceof TimeEvent && ((TimeEvent) event).hasValue()) { - TimeEvent tcEvent = (TimeEvent) event; - - XmlEntry entry = (XmlEntry) event.getEntry(); - int value = tcEvent.getValue(); - - if (entry.getType() == EntryDisplayType.DISPLAY) { - Integer index = stateIndex.get(value); - if (index == null) { - /* Colors won't be refreshed yet, return something known */ - index = TRANSPARENT; - stateIndex.put(value, stateValues.size()); - StateItem item = new StateItem(calcColor(stateValues.size()), String.valueOf(value)); - stateValues.add(item); - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - fireColorSettingsChanged(); - } - }); - } - return index; - } - } - - return INVISIBLE; - } - - @Override - public StateItem[] getStateTable() { - return stateValues.toArray(new StateItem[stateValues.size()]); - } - - @Override - public String getEventName(ITimeEvent event) { - if (event instanceof TimeEvent && ((TimeEvent) event).hasValue()) { - TimeEvent tcEvent = (TimeEvent) event; - - XmlEntry entry = (XmlEntry) event.getEntry(); - int value = tcEvent.getValue(); - - if (entry.getType() == EntryDisplayType.DISPLAY) { - Integer index = stateIndex.get(value); - String rgb = stateValues.get(index).getStateString(); - return rgb; - } - return null; - } - return Messages.XmlPresentationProvider_MultipleStates; - } - - @Override - public Map getEventHoverToolTipInfo(ITimeEvent event, long hoverTime) { - /* - * TODO: Add the XML elements to support adding extra information in the - * tooltips and implement this - */ - return Collections.EMPTY_MAP; - } - - @Override - public void postDrawEvent(ITimeEvent event, Rectangle bounds, GC gc) { - /* - * TODO Add the XML elements to support texts in intervals and implement - * this - */ - } - - @Override - public void postDrawEntry(ITimeGraphEntry entry, Rectangle bounds, GC gc) { - } - - /** - * Loads the states from a {@link TmfXmlUiStrings#TIME_GRAPH_VIEW} XML - * element - * - * @param viewElement - * The XML view element - */ - public void loadNewStates(@NonNull Element viewElement) { - stateValues.clear(); - stateIndex.clear(); - List states = XmlUtils.getChildElements(viewElement, TmfXmlStrings.DEFINED_VALUE); - - for (Element state : states) { - int value = Integer.parseInt(state.getAttribute(TmfXmlStrings.VALUE)); - String name = state.getAttribute(TmfXmlStrings.NAME); - String color = state.getAttribute(TmfXmlStrings.COLOR); - - // FIXME Allow this case - if (value < 0) { - return; - } - - RGB colorRGB = new RGB(255, 0, 0); - if (color.startsWith(TmfXmlStrings.COLOR_PREFIX)) { - Integer hex = Integer.parseInt(color.substring(1), 16); - int hex1 = hex.intValue() % 256; - int hex2 = (hex.intValue() / 256) % 256; - int hex3 = (hex.intValue() / (256 * 256)) % 256; - colorRGB = new RGB(hex3, hex2, hex1); - } else { - colorRGB = calcColor(value); - } - - StateItem item = new StateItem(colorRGB, name); - - Integer index = stateIndex.get(value); - if (index == null) { - /* Add the new state value */ - stateIndex.put(value, stateValues.size()); - stateValues.add(item); - } else { - /* Override a previous state value */ - stateValues.set(index, item); - } - } - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - fireColorSettingsChanged(); - } - }); - } - - private static RGB calcColor(int value) { - int x = (value * 97) % 1530; - int r = 0, g = 0, b = 0; - if (x >= 0 && x < 255) { - r = 255; - g = x; - b = 0; - } - if (x >= 255 && x < 510) { - r = 510 - x; - g = 255; - b = 0; - } - if (x >= 510 && x < 765) { - r = 0; - g = 255; - b = x - 510; - } - if (x >= 765 && x < 1020) { - r = 0; - g = 1020 - x; - b = 255; - } - if (x >= 1020 && x < 1275) { - r = x - 1020; - g = 0; - b = 255; - } - if (x >= 1275 && x <= 1530) { - r = 255; - g = 0; - b = 1530 - x; - } - return new RGB(r, g, b); - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/XmlTimeGraphView.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/XmlTimeGraphView.java deleted file mode 100644 index de83071fbd..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/XmlTimeGraphView.java +++ /dev/null @@ -1,512 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Florian Wininger - Initial API and implementation - * Geneviève Bastien - Review of the initial implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.analysis.xml.ui.views.timegraph; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.TmfXmlUiStrings; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.views.XmlViewInfo; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlModelFactory; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlStateAttribute; -import org.eclipse.linuxtools.tmf.analysis.xml.core.model.readonly.TmfXmlReadOnlyModelFactory; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.analysis.xml.ui.views.timegraph.XmlEntry.EntryDisplayType; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfAnalysisModuleWithStateSystems; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ui.views.timegraph.AbstractTimeGraphView; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider2; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.NullTimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry; -import org.eclipse.swt.widgets.Display; -import org.w3c.dom.Element; - -/** - * This view displays state system data in a time graph view. It uses an XML - * {@link TmfXmlUiStrings#TIME_GRAPH_VIEW} element from an XML file. This - * element defines which entries from the state system will be shown and also - * gives additional information on the presentation of the view (states, colors, - * etc) - * - * @author Florian Wininger - */ -public class XmlTimeGraphView extends AbstractTimeGraphView { - - /** View ID. */ - public static final @NonNull String ID = "org.eclipse.linuxtools.tmf.analysis.xml.ui.views.timegraph"; //$NON-NLS-1$ - - private static final String[] DEFAULT_COLUMN_NAMES = new String[] { - Messages.XmlTimeGraphView_ColumnName, - Messages.XmlTimeGraphView_ColumnId, - Messages.XmlTimeGraphView_ColumnParentId, - }; - - private static final String[] DEFAULT_FILTER_COLUMN_NAMES = new String[] { - Messages.XmlTimeGraphView_ColumnName, - Messages.XmlTimeGraphView_ColumnId - }; - - /** The relative weight of the sash */ - private static final int[] fWeight = { 1, 2 }; - - private static final String EMPTY_STRING = ""; //$NON-NLS-1$ - private static final String SPLIT_STRING = "/"; //$NON-NLS-1$ - - private final @NonNull XmlViewInfo fViewInfo = new XmlViewInfo(ID); - private final ITmfXmlModelFactory fFactory; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - public XmlTimeGraphView() { - super(ID, new XmlPresentationProvider()); - setWeight(fWeight); - setTreeColumns(DEFAULT_COLUMN_NAMES); - setTreeLabelProvider(new XmlTreeLabelProvider()); - setFilterColumns(DEFAULT_FILTER_COLUMN_NAMES); - setFilterLabelProvider(new XmlTreeLabelProvider()); - setEntryComparator(new XmlEntryComparator()); - this.addPartPropertyListener(new IPropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent event) { - if (event.getProperty().equals(TmfXmlUiStrings.XML_OUTPUT_DATA)) { - Object newValue = event.getNewValue(); - if (newValue instanceof String) { - String data = (String) newValue; - fViewInfo.setViewData(data); - loadNewXmlView(); - } - } - } - }); - - fFactory = TmfXmlReadOnlyModelFactory.getInstance(); - } - - private void loadNewXmlView() { - rebuild(); - } - - private void setViewTitle(final String title) { - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - setPartName(title); - } - }); - - } - - @Override - protected String getNextText() { - return Messages.XmlTimeGraphView_NextText; - } - - @Override - protected String getNextTooltip() { - return Messages.XmlTimeGraphView_NextTooltip; - } - - @Override - protected String getPrevText() { - return Messages.XmlTimeGraphView_PreviousText; - } - - @Override - protected String getPrevTooltip() { - return Messages.XmlTimeGraphView_PreviousInterval; - } - - /** - * Default label provider, it shows name, id and parent columns - * - * TODO: There should be a way to define columns in the XML - * */ - private static class XmlTreeLabelProvider extends TreeLabelProvider { - - @Override - public String getColumnText(Object element, int columnIndex) { - XmlEntry entry = (XmlEntry) element; - - if (DEFAULT_COLUMN_NAMES[columnIndex].equals(Messages.XmlTimeGraphView_ColumnName)) { - return entry.getName(); - } else if (DEFAULT_COLUMN_NAMES[columnIndex].equals(Messages.XmlTimeGraphView_ColumnId)) { - return entry.getId(); - } else if (DEFAULT_COLUMN_NAMES[columnIndex].equals(Messages.XmlTimeGraphView_ColumnParentId)) { - return entry.getParentId(); - } - return EMPTY_STRING; - } - - } - - private static class XmlEntryComparator implements Comparator { - - @Override - public int compare(ITimeGraphEntry o1, ITimeGraphEntry o2) { - - int result = 0; - - if ((o1 instanceof XmlEntry) && (o2 instanceof XmlEntry)) { - XmlEntry entry1 = (XmlEntry) o1; - XmlEntry entry2 = (XmlEntry) o2; - result = entry1.getTrace().getStartTime().compareTo(entry2.getTrace().getStartTime()); - if (result == 0) { - result = entry1.getTrace().getName().compareTo(entry2.getTrace().getName()); - } - if (result == 0) { - result = entry1.getName().compareTo(entry2.getName()); - } - } - - if (result == 0) { - result = o1.getStartTime() < o2.getStartTime() ? -1 : o1.getStartTime() > o2.getStartTime() ? 1 : 0; - } - - return result; - } - } - - // ------------------------------------------------------------------------ - // Internal - // ------------------------------------------------------------------------ - - @Override - protected void buildEventList(ITmfTrace trace, ITmfTrace parentTrace, IProgressMonitor monitor) { - - /* - * Get the view element from the XML file. If the element can't be - * found, return. - */ - Element viewElement = fViewInfo.getViewElement(TmfXmlUiStrings.TIME_GRAPH_VIEW); - if (viewElement == null) { - return; - } - ITimeGraphPresentationProvider2 pres = this.getPresentationProvider(); - if (pres instanceof XmlPresentationProvider) { - /* - * TODO: Each entry of a line could have their own states/color. - * That will require an update to the presentation provider - */ - ((XmlPresentationProvider) pres).loadNewStates(viewElement); - } - - String title = fViewInfo.getViewTitle(viewElement); - if (title == null) { - title = Messages.XmlTimeGraphView_DefaultTitle; - } - setViewTitle(title); - Set analysisIds = fViewInfo.getViewAnalysisIds(viewElement); - - List entries = XmlUtils.getChildElements(viewElement, TmfXmlUiStrings.ENTRY_ELEMENT); - Set entryList = new TreeSet<>(getEntryComparator()); - for (ITmfTrace aTrace : TmfTraceManager.getTraceSet(trace)) { - if (monitor.isCanceled()) { - return; - } - - List stateSystemModules = new LinkedList<>(); - if (analysisIds.isEmpty()) { - /* - * No analysis specified, take all state system analysis modules - */ - for (ITmfAnalysisModuleWithStateSystems module : aTrace.getAnalysisModulesOfClass(ITmfAnalysisModuleWithStateSystems.class)) { - stateSystemModules.add(module); - } - } else { - for (String moduleId : analysisIds) { - ITmfAnalysisModuleWithStateSystems module = aTrace.getAnalysisModuleOfClass(ITmfAnalysisModuleWithStateSystems.class, moduleId); - if (module != null) { - stateSystemModules.add(module); - } - } - } - - for (ITmfAnalysisModuleWithStateSystems module : stateSystemModules) { - module.schedule(); - if (module instanceof TmfStateSystemAnalysisModule) { - ((TmfStateSystemAnalysisModule) module).waitForInitialization(); - } - for (ITmfStateSystem ssq : module.getStateSystems()) { - if (ssq == null) { - return; - } - ssq.waitUntilBuilt(); - - long startTime = ssq.getStartTime(); - long endTime = ssq.getCurrentEndTime(); - XmlEntry groupEntry = new XmlEntry(-1, aTrace, aTrace.getName(), ssq); - entryList.add(groupEntry); - setStartTime(Math.min(getStartTime(), startTime)); - setEndTime(Math.max(getEndTime(), endTime)); - - /* Add children entry of this entry for each line */ - for (Element entry : entries) { - buildEntry(entry, groupEntry, -1); - } - } - } - } - putEntryList(trace, new ArrayList(entryList)); - - if (trace.equals(getTrace())) { - refresh(); - } - for (XmlEntry traceEntry : entryList) { - if (monitor.isCanceled()) { - return; - } - long startTime = traceEntry.getStateSystem().getStartTime(); - long endTime = traceEntry.getStateSystem().getCurrentEndTime() + 1; - buildStatusEvent(traceEntry, monitor, startTime, endTime); - } - } - - private void buildEntry(Element entryElement, XmlEntry parentEntry, int baseQuark) { - /* Get the attribute string to display */ - String path = entryElement.getAttribute(TmfXmlUiStrings.PATH); - if (path.isEmpty()) { - path = TmfXmlStrings.WILDCARD; - } - - /* - * Make sure the XML element has either a display attribute or entries, - * otherwise issue a warning - */ - - List displayElements = XmlUtils.getChildElements(entryElement, TmfXmlUiStrings.DISPLAY_ELEMENT); - List entryElements = XmlUtils.getChildElements(entryElement, TmfXmlUiStrings.ENTRY_ELEMENT); - - if (displayElements.isEmpty() && entryElements.isEmpty()) { - Activator.logWarning(String.format("XML view: entry for %s should have either a display element or entry elements", path)); //$NON-NLS-1$ - return; - } - - ITmfStateSystem ss = parentEntry.getStateSystem(); - - /* Get the list of quarks to process with this path */ - String[] paths = path.split(SPLIT_STRING); - int i = 0; - List quarks = Collections.singletonList(baseQuark); - - try { - while (i < paths.length) { - List subQuarks = new LinkedList<>(); - /* Replace * by .* to have a regex string */ - String name = paths[i].replaceAll("\\*", ".*"); //$NON-NLS-1$ //$NON-NLS-2$ - for (int relativeQuark : quarks) { - for (int quark : ss.getSubAttributes(relativeQuark, false, name)) { - subQuarks.add(quark); - } - } - quarks = subQuarks; - i++; - } - - /* Process each quark */ - XmlEntry currentEntry = parentEntry; - Element displayElement = null; - Map entryMap = new HashMap<>(); - if (!displayElements.isEmpty()) { - displayElement = displayElements.get(0); - } - for (int quark : quarks) { - currentEntry = parentEntry; - /* Process the current entry, if specified */ - if (displayElement != null) { - currentEntry = processEntry(entryElement, displayElement, parentEntry, quark, ss); - entryMap.put(currentEntry.getId(), currentEntry); - } - /* Process the children entry of this entry */ - for (Element subEntryEl : entryElements) { - buildEntry(subEntryEl, currentEntry, quark); - } - } - if (!entryMap.isEmpty()) { - buildTree(entryMap, parentEntry); - } - } catch (AttributeNotFoundException e) { - } - } - - private XmlEntry processEntry(@NonNull Element entryElement, @NonNull Element displayEl, - XmlEntry parentEntry, int quark, ITmfStateSystem ss) { - /* - * Get the start time and end time of this entry from the display - * attribute - */ - ITmfXmlStateAttribute display = fFactory.createStateAttribute(displayEl, parentEntry); - int displayQuark = display.getAttributeQuark(quark); - if (displayQuark == IXmlStateSystemContainer.ERROR_QUARK) { - return new XmlEntry(quark, parentEntry.getTrace(), - String.format("Unknown display quark for %s", ss.getAttributeName(quark)), ss); //$NON-NLS-1$ - } - - long entryStart = ss.getStartTime(); - long entryEnd = ss.getCurrentEndTime(); - - try { - - ITmfStateInterval oneInterval = ss.querySingleState(entryStart, displayQuark); - - /* The entry start is the first non-null interval */ - while (oneInterval.getStateValue().isNull()) { - long ts = oneInterval.getEndTime() + 1; - if (ts > ss.getCurrentEndTime()) { - break; - } - oneInterval = ss.querySingleState(ts, displayQuark); - } - entryStart = oneInterval.getStartTime(); - - /* The entry end is the last non-null interval */ - oneInterval = ss.querySingleState(entryEnd, displayQuark); - while (oneInterval.getStateValue().isNull()) { - long ts = oneInterval.getStartTime() - 1; - if (ts < ss.getStartTime()) { - break; - } - oneInterval = ss.querySingleState(ts, displayQuark); - } - entryEnd = oneInterval.getEndTime(); - - } catch (AttributeNotFoundException | StateSystemDisposedException e) { - } - - return new XmlEntry(quark, displayQuark, parentEntry.getTrace(), ss.getAttributeName(quark), - entryStart, entryEnd, EntryDisplayType.DISPLAY, ss, entryElement); - } - - private void buildStatusEvent(XmlEntry traceEntry, IProgressMonitor monitor, long start, long end) { - long resolution = (end - start) / getDisplayWidth(); - long startTime = Math.max(start, traceEntry.getStartTime()); - long endTime = Math.min(end + 1, traceEntry.getEndTime()); - List eventList = getEventList(traceEntry, startTime, endTime, resolution, monitor); - if (monitor.isCanceled()) { - return; - } - traceEntry.setEventList(eventList); - redraw(); - - for (ITimeGraphEntry entry : traceEntry.getChildren()) { - if (monitor.isCanceled()) { - return; - } - XmlEntry xmlEntry = (XmlEntry) entry; - buildStatusEvent(xmlEntry, monitor, start, end); - } - } - - /** Build a tree using getParentId() and getId() */ - private static void buildTree(Map entryMap, XmlEntry rootEntry) { - for (XmlEntry entry : entryMap.values()) { - boolean root = true; - if (!entry.getParentId().isEmpty()) { - XmlEntry parent = entryMap.get(entry.getParentId()); - if (parent != null && - entry.getStartTime() >= parent.getStartTime() && - entry.getStartTime() <= parent.getEndTime()) { - parent.addChild(entry); - root = false; - } - } - if (root) { - rootEntry.addChild(entry); - } - } - } - - @Override - protected List getEventList(TimeGraphEntry entry, long startTime, long endTime, long resolution, IProgressMonitor monitor) { - if (!(entry instanceof XmlEntry)) { - return Collections.EMPTY_LIST; - } - XmlEntry xmlEntry = (XmlEntry) entry; - ITmfStateSystem ssq = xmlEntry.getStateSystem(); - final long realStart = Math.max(startTime, entry.getStartTime()); - final long realEnd = Math.min(endTime, entry.getEndTime()); - if (realEnd <= realStart) { - return null; - } - List eventList = null; - int quark = xmlEntry.getDisplayQuark(); - - try { - if (xmlEntry.getType() == EntryDisplayType.DISPLAY) { - - List statusIntervals = ssq.queryHistoryRange(quark, realStart, realEnd - 1, resolution, monitor); - eventList = new ArrayList<>(statusIntervals.size()); - long lastEndTime = -1; - for (ITmfStateInterval statusInterval : statusIntervals) { - if (monitor.isCanceled()) { - return null; - } - int status = statusInterval.getStateValue().unboxInt(); - long time = statusInterval.getStartTime(); - long duration = statusInterval.getEndTime() - time + 1; - if (!statusInterval.getStateValue().isNull()) { - if (lastEndTime != time && lastEndTime != -1) { - eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime)); - } - eventList.add(new TimeEvent(entry, time, duration, status)); - } else if (lastEndTime == -1 || time + duration >= endTime) { - // add null event if it intersects the start or end time - eventList.add(new NullTimeEvent(entry, time, duration)); - } - lastEndTime = time + duration; - } - } - } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException | StateSystemDisposedException e) { - /* Ignored */ - } - return eventList; - } - - @Override - protected List getLinkList(long startTime, long endTime, long resolution, IProgressMonitor monitor) { - /* TODO: not implemented yet, need XML to go along */ - return Collections.EMPTY_LIST; - } - -} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/messages.properties b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/messages.properties deleted file mode 100644 index 73b9566d2d..0000000000 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/linuxtools/tmf/analysis/xml/ui/views/timegraph/messages.properties +++ /dev/null @@ -1,10 +0,0 @@ -XmlPresentationProvider_MultipleStates=(multiple) -XmlTimeGraphView_ColumnId=ID -XmlTimeGraphView_ColumnName=Name -XmlTimeGraphView_ColumnParentId=ParentID -XmlTimeGraphView_DefaultTitle=Xml State Provider -XmlTimeGraphView_NextText=Next Interval -XmlTimeGraphView_NextTooltip=Select next interval in time graph -XmlTimeGraphView_PreviousInterval=Select previous interval in time graph -XmlTimeGraphView_PreviousText=Previous Interval -XmlTimeGraphView_UselessEndPath=There should be an XML for path {0} in the view's XML otherwise the last level is useless diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/Activator.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/Activator.java new file mode 100644 index 0000000000..7c64e7db94 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/Activator.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.analysis.xml.ui; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + * + * @author Geneviève Bastien + */ +public class Activator extends AbstractUIPlugin { + + /** The plug-in ID */ + public static final String PLUGIN_ID = "org.eclipse.linuxtools.tmf.analysis.xml.ui"; //$NON-NLS-1$ + + // The shared instance + private static Activator fPlugin; + + /** + * The constructor + */ + public Activator() { + setDefault(this); + } + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + setDefault(this); + } + + @Override + public void stop(BundleContext context) throws Exception { + setDefault(null); + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return fPlugin; + } + + // Sets plug-in instance + private static void setDefault(Activator plugin) { + fPlugin = plugin; + } + + // ------------------------------------------------------------------------ + // Log an IStatus + // ------------------------------------------------------------------------ + + /** + * Log an IStatus object directly + * + * @param status + * The status to log + */ + public static void log(IStatus status) { + fPlugin.getLog().log(status); + } + + // ------------------------------------------------------------------------ + // Log INFO + // ------------------------------------------------------------------------ + + /** + * Logs a message with severity INFO in the runtime log of the plug-in. + * + * @param message + * A message to log + */ + public static void logInfo(String message) { + fPlugin.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity INFO in the runtime log of the + * plug-in. + * + * @param message + * A message to log + * @param exception + * The corresponding exception + */ + public static void logInfo(String message, Throwable exception) { + fPlugin.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message, exception)); + } + + // ------------------------------------------------------------------------ + // Log WARNING + // ------------------------------------------------------------------------ + + /** + * Logs a message and exception with severity WARNING in the runtime log of + * the plug-in. + * + * @param message + * A message to log + */ + public static void logWarning(String message) { + fPlugin.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity WARNING in the runtime log of + * the plug-in. + * + * @param message + * A message to log + * @param exception + * The corresponding exception + */ + public static void logWarning(String message, Throwable exception) { + fPlugin.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message, exception)); + } + + // ------------------------------------------------------------------------ + // Log ERROR + // ------------------------------------------------------------------------ + + /** + * Logs a message and exception with severity ERROR in the runtime log of + * the plug-in. + * + * @param message + * A message to log + */ + public static void logError(String message) { + fPlugin.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity ERROR in the runtime log of + * the plug-in. + * + * @param message + * A message to log + * @param exception + * The corresponding exception + */ + public static void logError(String message, Throwable exception) { + fPlugin.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, exception)); + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/TmfXmlUiStrings.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/TmfXmlUiStrings.java new file mode 100644 index 0000000000..4ead8262d1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/TmfXmlUiStrings.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.analysis.xml.ui; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * This file defines all names in the XML Structure for UI elements + * + * @author Geneviève Bastien + */ +@SuppressWarnings({ "javadoc", "nls" }) +@NonNullByDefault +public interface TmfXmlUiStrings { + + /* XML generic Element attribute names */ + static final String TIME_GRAPH_VIEW = "timeGraphView"; + static final String XY_VIEW = "xyView"; + + /* View elements and attributes */ + static final String ENTRY_ELEMENT = "entry"; + + /* Elements and attributes of view entries */ + static final String PATH = "path"; + static final String DISPLAY_ELEMENT = "display"; + static final String PARENT_ELEMENT = "parent"; + static final String NAME_ELEMENT = "name"; + static final String ID_ELEMENT = "id"; + static final String DISPLAY_TYPE = "displayType"; + static final String DISPLAY_TYPE_ABSOLUTE = "absolute"; + static final String DISPLAY_TYPE_DELTA = "delta"; + + /* Generic strings for the XML module */ + static final String XML_OUTPUT_DATA = "xmlOutputData"; + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/handler/ImportXmlHandler.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/handler/ImportXmlHandler.java new file mode 100644 index 0000000000..f49014c8af --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/handler/ImportXmlHandler.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.handler; + +import java.io.File; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.analysis.xml.ui.module.Messages; +import org.eclipse.tracecompass.tmf.analysis.xml.ui.module.XmlAnalysisModuleSource; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectModelElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TraceUtils; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * Imports and validates an XML file + * + * @author Geneviève Bastien + */ +public class ImportXmlHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + FileDialog dlg = new FileDialog(new Shell(), SWT.OPEN); + dlg.setFilterNames(new String[] { Messages.ImportXmlHandler_ImportXmlFile + " (*.xml)" }); //$NON-NLS-1$ + dlg.setFilterExtensions(new String[] { "*.xml" }); //$NON-NLS-1$ + + String fn = dlg.open(); + if (fn != null) { + File file = new File(fn); + IStatus status = XmlUtils.xmlValidate(file); + if (status.isOK()) { + status = XmlUtils.addXmlFile(file); + if (status.isOK()) { + XmlAnalysisModuleSource.notifyModuleChange(); + /* + * FIXME: It refreshes the list of analysis under a trace, + * but since modules are instantiated when the trace opens, + * the changes won't apply to an opened trace, it needs to + * be closed then reopened + */ + refreshProject(); + } else { + TraceUtils.displayErrorMsg(Messages.ImportXmlHandler_ImportXmlFile, status.getMessage()); + } + } else { + TraceUtils.displayErrorMsg(Messages.ImportXmlHandler_ImportXmlFile, status.getMessage()); + } + } + + return null; + } + + /** + * Refresh the selected project with the new XML file import + */ + private static void refreshProject() { + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return; + } + + // Get the selection + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + IWorkbenchPart part = page.getActivePart(); + if (part == null) { + return; + } + ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); + if (selectionProvider == null) { + return; + } + ISelection selection = selectionProvider.getSelection(); + + if (selection instanceof TreeSelection) { + TreeSelection sel = (TreeSelection) selection; + // There should be only one item selected as per the plugin.xml + Object element = sel.getFirstElement(); + if (element instanceof TmfProjectModelElement) { + ((TmfProjectModelElement) element).getProject().refresh(); + } + } + + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/XmlViewInfo.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/XmlViewInfo.java new file mode 100644 index 0000000000..393dac84b8 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/XmlViewInfo.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.Activator; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.tracecompass.tmf.analysis.xml.ui.module.TmfXmlAnalysisOutputSource; +import org.w3c.dom.Element; + +/** + * Class that manages information about a view: its title, the file, etc. + * + * @author Geneviève Bastien + */ +@NonNullByDefault +public class XmlViewInfo { + + private static final String XML_VIEW_ID_PROPERTY = "XmlViewId"; //$NON-NLS-1$ + private static final String XML_VIEW_FILE_PROPERTY = "XmlViewFile"; //$NON-NLS-1$ + + private final String fViewId; + private @Nullable String fId = null; + private @Nullable String fFilePath = null; + + /** + * Constructor + * + * @param viewId + * The ID of the view + */ + public XmlViewInfo(String viewId) { + fViewId = viewId; + + IDialogSettings settings = getPersistentPropertyStore(); + + fId = settings.get(XML_VIEW_ID_PROPERTY); + fFilePath = settings.get(XML_VIEW_FILE_PROPERTY); + } + + /** + * Set the data for this view and retrieves from it the view ID and the file + * path of the XML element this view uses. + * + * @param data + * A string of the form "XML view ID" + + * {@link TmfXmlAnalysisOutputSource#DATA_SEPARATOR} + + * "path of the file containing the XML element" + */ + public void setViewData(String data) { + String[] idFile = data.split(TmfXmlAnalysisOutputSource.DATA_SEPARATOR); + fId = (idFile.length > 0) ? idFile[0] : null; + fFilePath = (idFile.length > 1) ? idFile[1] : null; + savePersistentData(); + } + + private IDialogSettings getPersistentPropertyStore() { + IDialogSettings settings = Activator.getDefault().getDialogSettings(); + IDialogSettings section = settings.getSection(fViewId); + if (section == null) { + section = settings.addNewSection(fViewId); + if (section == null) { + throw new IllegalStateException(); + } + } + return section; + } + + private void savePersistentData() { + IDialogSettings settings = getPersistentPropertyStore(); + + settings.put(XML_VIEW_ID_PROPERTY, fId); + settings.put(XML_VIEW_FILE_PROPERTY, fFilePath); + } + + /** + * Retrieve the XML element corresponding to the view + * + * @param xmlTag + * The XML tag corresponding to the view element (the type of + * view) + * @return The view {@link Element} + */ + public @Nullable Element getViewElement(String xmlTag) { + String id = fId; + if (id == null) { + return null; + } + Element viewElement = XmlUtils.getElementInFile(fFilePath, xmlTag, id); + return viewElement; + } + + /** + * Get the view title from the header information of the XML view element. + * + * @param viewElement + * The XML view element from which to get the title + * @return The view title + */ + public @Nullable String getViewTitle(Element viewElement) { + List heads = XmlUtils.getChildElements(viewElement, TmfXmlStrings.HEAD); + + String title = null; + if (!heads.isEmpty()) { + Element head = heads.get(0); + /* Set the title of this view from the label in the header */ + List labels = XmlUtils.getChildElements(head, TmfXmlStrings.LABEL); + for (Element label : labels) { + if (!label.getAttribute(TmfXmlStrings.VALUE).isEmpty()) { + title = label.getAttribute(TmfXmlStrings.VALUE); + } + break; + } + } + return title; + } + + /** + * Get the list of analysis IDs this view is for, as listed in the header of + * the XML element + * + * @param viewElement + * The XML view element from which to get the analysis IDs + * @return The list of all analysis IDs this view is for + */ + public Set getViewAnalysisIds(Element viewElement) { + List heads = XmlUtils.getChildElements(viewElement, TmfXmlStrings.HEAD); + + Set analysisIds = new HashSet<>(); + if (!heads.isEmpty()) { + Element head = heads.get(0); + + /* Get the application analysis from the view's XML header */ + List applicableAnalysis = XmlUtils.getChildElements(head, TmfXmlStrings.ANALYSIS); + for (Element oneAnalysis : applicableAnalysis) { + analysisIds.add(oneAnalysis.getAttribute(TmfXmlStrings.ID)); + } + } + return analysisIds; + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/Messages.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/Messages.java new file mode 100644 index 0000000000..55abe491a7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/Messages.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.xychart; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.osgi.util.NLS; + +/** + * Externalized strings for the xml xy chart view package + * + * @author Geneviève Bastien + */ +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.xychart.messages"; //$NON-NLS-1$ + /** Default view title */ + public static @Nullable String XmlXYView_DefaultTitle; + + /** Default Viewer title */ + public static @Nullable String XmlXYViewer_DefaultViewerTitle; + /** Default X axix text */ + public static @Nullable String XmlXYViewer_DefaultXAxis; + /** Default Y axis text */ + public static @Nullable String XmlXYViewer_DefaultYAxis; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/XmlXYView.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/XmlXYView.java new file mode 100644 index 0000000000..cf780ebd1c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/XmlXYView.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.xychart; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.TmfXmlUiStrings; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.XmlViewInfo; +import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.TmfXYChartViewer; +import org.eclipse.tracecompass.tmf.ui.views.TmfChartView; +import org.w3c.dom.Element; + +/** + * This view displays state system data in an xy chart. It uses an XML + * {@link TmfXmlUiStrings#XY_VIEW} element from an XML file. This element + * defines which entries from the state system will be shown and also gives + * additional information on the presentation of the view. + * + * @author Geneviève Bastien + */ +public class XmlXYView extends TmfChartView { + + /** View ID. */ + public static final String ID = "org.eclipse.linuxtools.internal.tmf.analysis.xml.ui.views.xyview"; //$NON-NLS-1$ + + private final XmlViewInfo fViewInfo = new XmlViewInfo(ID); + + /** + * Default constructor + */ + public XmlXYView() { + super(Messages.XmlXYView_DefaultTitle); + + this.addPartPropertyListener(new IPropertyChangeListener() { + @Override + public void propertyChange(@Nullable PropertyChangeEvent event) { + if (event == null) { + return; + } + if (event.getProperty().equals(TmfXmlUiStrings.XML_OUTPUT_DATA)) { + Object newValue = event.getNewValue(); + if (newValue instanceof String) { + fViewInfo.setViewData((String) newValue); + setViewTitle(); + TmfXYChartViewer viewer = getChartViewer(); + if (viewer instanceof XmlXYViewer) { + ((XmlXYViewer) viewer).viewInfoUpdated(); + } + + } + } + } + + }); + setViewTitle(); + } + + @Override + public void createPartControl(@Nullable Composite parent) { + setChartViewer(new XmlXYViewer(parent, fViewInfo)); + super.createPartControl(parent); + } + + @Override + public void setFocus() { + + } + + private void setViewTitle() { + /* + * Get the view element from the XML file. If the element can't be + * found, return. + */ + Element viewElement = fViewInfo.getViewElement(TmfXmlUiStrings.XY_VIEW); + if (viewElement == null) { + return; + } + + String title = fViewInfo.getViewTitle(viewElement); + if (title == null) { + title = Messages.XmlXYView_DefaultTitle; + } + final String viewTitle = title; + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + setPartName(viewTitle); + } + }); + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/XmlXYViewer.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/XmlXYViewer.java new file mode 100644 index 0000000000..ac54b723a9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/XmlXYViewer.java @@ -0,0 +1,414 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.xychart; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.TmfXmlUiStrings; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.XmlViewInfo; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.ITmfXmlModelFactory; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.ITmfXmlStateAttribute; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlLocation; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.readonly.TmfXmlReadOnlyModelFactory; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfAnalysisModuleWithStateSystems; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.linecharts.TmfCommonXLineChartViewer; +import org.w3c.dom.Element; + +/** + * Main viewer to display XML-defined xy charts. It uses an XML + * {@link TmfXmlUiStrings#XY_VIEW} element from an XML file. This element + * defines which entries from the state system will be shown and also gives + * additional information on the presentation of the view. + * + * @author Geneviève Bastien + */ +public class XmlXYViewer extends TmfCommonXLineChartViewer { + + private static final String SPLIT_STRING = "/"; //$NON-NLS-1$ + /** Timeout between updates in the updateData thread */ + private static final long BUILD_UPDATE_TIMEOUT = 500; + + @SuppressWarnings("null") + private static final @NonNull Pattern WILDCARD_PATTERN = Pattern.compile("\\*"); //$NON-NLS-1$ + + private final ITmfXmlModelFactory fFactory = TmfXmlReadOnlyModelFactory.getInstance(); + private final Map fSeriesData = new HashMap<>(); + + private final XmlViewInfo fViewInfo; + + /** XML Model elements to use to create the series */ + private @Nullable ITmfXmlStateAttribute fDisplay; + private @Nullable ITmfXmlStateAttribute fSeriesName; + private @Nullable XmlXYEntry fEntry; + + private enum DisplayType { + ABSOLUTE, + DELTA + } + + /** + * The information related to one series on the chart + */ + private class SeriesData { + + private final double[] fYValues; + private final @Nullable double[] fYAbsoluteValues; + private final Integer fDisplayQuark; + private final String fName; + private final DisplayType fType; + + public SeriesData(int length, int attributeQuark, String seriesName, DisplayType type) { + fYValues = new double[length]; + fDisplayQuark = attributeQuark; + fName = seriesName; + fType = type; + switch (fType) { + case DELTA: + fYAbsoluteValues = new double[length]; + break; + case ABSOLUTE: + default: + fYAbsoluteValues = null; + break; + } + + } + + public double[] getYValues() { + return fYValues; + } + + public Integer getDisplayQuark() { + return fDisplayQuark; + } + + public String getSeriesName() { + return fName; + } + + public void setYValue(int i, double yvalue) { + switch (fType) { + case DELTA: + double[] absoluteVals = fYAbsoluteValues; + if (absoluteVals == null) { + throw new IllegalStateException(); + } + absoluteVals[i] = yvalue; + /* + * At the first timestamp, the delta value should be 0 since we + * do not have the previous values + */ + double prevValue = yvalue; + if (i > 0) { + prevValue = absoluteVals[i - 1]; + } + fYValues[i] = yvalue - prevValue; + break; + case ABSOLUTE: + default: + fYValues[i] = yvalue; + break; + } + + } + } + + private static class XmlXYEntry implements IXmlStateSystemContainer { + + private final ITmfStateSystem fStateSystem; + private final String fPath; + private final DisplayType fType; + + public XmlXYEntry(ITmfStateSystem stateSystem, String path, Element entryElement) { + fStateSystem = stateSystem; + fPath = path; + switch (entryElement.getAttribute(TmfXmlUiStrings.DISPLAY_TYPE)) { + case TmfXmlUiStrings.DISPLAY_TYPE_DELTA: + fType = DisplayType.DELTA; + break; + case TmfXmlUiStrings.DISPLAY_TYPE_ABSOLUTE: + default: + fType = DisplayType.ABSOLUTE; + break; + } + } + + @Override + public @Nullable String getAttributeValue(@Nullable String name) { + return name; + } + + @Override + public ITmfStateSystem getStateSystem() { + return fStateSystem; + } + + @Override + public @Nullable Iterable getLocations() { + return Collections.EMPTY_SET; + } + + public DisplayType getType() { + return fType; + } + + public List getQuarks() { + /* Get the list of quarks to process with this path */ + String[] paths = fPath.split(SPLIT_STRING); + @SuppressWarnings("null") + @NonNull List quarks = Collections.singletonList(IXmlStateSystemContainer.ROOT_QUARK); + + try { + for (String path : paths) { + List subQuarks = new LinkedList<>(); + /* Replace * by .* to have a regex string */ + String name = WILDCARD_PATTERN.matcher(path).replaceAll(".*"); //$NON-NLS-1$ + for (int relativeQuark : quarks) { + subQuarks.addAll(fStateSystem.getSubAttributes(relativeQuark, false, name)); + } + quarks = subQuarks; + } + } catch (AttributeNotFoundException e) { + /* + * We get all attributes from the state system itself, this + * should not happen. + */ + throw new IllegalStateException(); + } + return quarks; + } + } + + /** + * Constructor + * + * @param parent + * parent view + * @param viewInfo + * The view info object + */ + public XmlXYViewer(@Nullable Composite parent, XmlViewInfo viewInfo) { + super(parent, Messages.XmlXYViewer_DefaultViewerTitle, Messages.XmlXYViewer_DefaultXAxis, Messages.XmlXYViewer_DefaultYAxis); + fViewInfo = viewInfo; + } + + @Override + protected void updateData(long start, long end, int nb, @Nullable IProgressMonitor monitor) { + + ITmfXmlStateAttribute display = fDisplay; + ITmfXmlStateAttribute seriesNameAttrib = fSeriesName; + XmlXYEntry entry = fEntry; + if (getTrace() == null || display == null || entry == null) { + return; + } + ITmfStateSystem ss = entry.getStateSystem(); + + double[] xvalues = getXAxis(start, end, nb); + setXAxis(xvalues); + + boolean complete = false; + long currentEnd = start; + + while (!complete && currentEnd < end) { + if (monitor != null && monitor.isCanceled()) { + return; + } + + complete = ss.waitUntilBuilt(BUILD_UPDATE_TIMEOUT); + currentEnd = ss.getCurrentEndTime(); + try { + List quarks = entry.getQuarks(); + long traceStart = getStartTime(); + long traceEnd = getEndTime(); + long offset = this.getTimeOffset(); + + /* Initialize quarks and series names */ + for (int quark : quarks) { + String seriesName = null; + if (seriesNameAttrib == null) { + seriesName = ss.getAttributeName(quark); + } else { + int seriesNameQuark = seriesNameAttrib.getAttributeQuark(quark); + try { + ITmfStateValue seriesNameValue = ss.querySingleState(start, seriesNameQuark).getStateValue(); + if (!seriesNameValue.isNull()) { + seriesName = seriesNameValue.toString(); + } + if (seriesName == null || seriesName.isEmpty()) { + seriesName = ss.getAttributeName(quark); + } + } catch (TimeRangeException e) { + /* + * The attribute did not exist at this point, simply + * use attribute name as series name + */ + seriesName = ss.getAttributeName(quark); + } + } + if (seriesName == null) { + throw new IllegalStateException(); + } + fSeriesData.put(quark, new SeriesData(xvalues.length, display.getAttributeQuark(quark), seriesName, entry.getType())); + } + double yvalue = 0.0; + for (int i = 0; i < xvalues.length; i++) { + if (monitor != null && monitor.isCanceled()) { + return; + } + double x = xvalues[i]; + long time = (long) x + offset; + // make sure that time is in the trace range after double to + // long conversion + time = time < traceStart ? traceStart : time; + time = time > traceEnd ? traceEnd : time; + + for (int quark : quarks) { + try { + yvalue = ss.querySingleState(time, fSeriesData.get(quark).getDisplayQuark()).getStateValue().unboxLong(); + fSeriesData.get(quark).setYValue(i, yvalue); + } catch (TimeRangeException e) { + fSeriesData.get(quark).setYValue(i, 0); + } + } + } + for (int quark : quarks) { + setSeries(fSeriesData.get(quark).getSeriesName(), fSeriesData.get(quark).getYValues()); + } + updateDisplay(); + } catch (AttributeNotFoundException | StateValueTypeException e) { + Activator.logError("Error updating the data of XML XY view", e); //$NON-NLS-1$ + } catch (StateSystemDisposedException e) { + return; + } + } + + } + + @Override + protected void initializeDataSource() { + super.initializeDataSource(); + + ITmfTrace trace = this.getTrace(); + if (trace == null) { + return; + } + + Element viewElement = fViewInfo.getViewElement(TmfXmlUiStrings.XY_VIEW); + if (viewElement == null) { + return; + } + + Iterable analysisIds = fViewInfo.getViewAnalysisIds(viewElement); + + List stateSystemModules = new LinkedList<>(); + if (!analysisIds.iterator().hasNext()) { + /* + * No analysis specified, take all state system analysis modules + */ + for (ITmfAnalysisModuleWithStateSystems module : trace.getAnalysisModulesOfClass(ITmfAnalysisModuleWithStateSystems.class)) { + stateSystemModules.add(module); + } + } else { + for (String moduleId : analysisIds) { + @SuppressWarnings("resource") + ITmfAnalysisModuleWithStateSystems module = trace.getAnalysisModuleOfClass(ITmfAnalysisModuleWithStateSystems.class, moduleId); + if (module != null) { + stateSystemModules.add(module); + } + } + } + + /** Initialize the data */ + fDisplay = null; + fSeriesName = null; + ITmfStateSystem ss = null; + fEntry = null; + + /* Schedule all state systems */ + for (ITmfAnalysisModuleWithStateSystems module : stateSystemModules) { + module.schedule(); + if (module instanceof TmfStateSystemAnalysisModule) { + ((TmfStateSystemAnalysisModule) module).waitForInitialization(); + } + for (ITmfStateSystem ssq : module.getStateSystems()) { + if (ssq != null) { + ss = ssq; + break; + } + } + } + if (ss == null) { + return; + } + + /* + * Initialize state attributes. There should be only one entry element + * for XY charts. + */ + List entries = XmlUtils.getChildElements(viewElement, TmfXmlUiStrings.ENTRY_ELEMENT); + Element entryElement = entries.get(0); + String path = entryElement.getAttribute(TmfXmlUiStrings.PATH); + if (path.isEmpty()) { + path = TmfXmlStrings.WILDCARD; + } + XmlXYEntry entry = new XmlXYEntry(ss, path, entryElement); + fEntry = entry; + + /* Get the display element to use */ + List displayElements = XmlUtils.getChildElements(entryElement, TmfXmlUiStrings.DISPLAY_ELEMENT); + if (displayElements.isEmpty()) { + Activator.logWarning(String.format("XML view: entry for %s should have a display element", path)); //$NON-NLS-1$ + return; + } + Element displayElement = displayElements.get(0); + fDisplay = fFactory.createStateAttribute(displayElement, entry); + + /* Get the series name element to use */ + List seriesNameElements = XmlUtils.getChildElements(entryElement, TmfXmlUiStrings.NAME_ELEMENT); + if (!seriesNameElements.isEmpty()) { + Element seriesNameElement = seriesNameElements.get(0); + fSeriesName = fFactory.createStateAttribute(seriesNameElement, entry); + } + + } + + /** + * Tells the viewer that the view info has been updated and the viewer needs + * to be reinitialized + */ + public void viewInfoUpdated() { + reinitialize(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/messages.properties b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/messages.properties new file mode 100644 index 0000000000..77d3f62908 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/messages.properties @@ -0,0 +1,4 @@ +XmlXYView_DefaultTitle=Xml XY view +XmlXYViewer_DefaultViewerTitle=Xml XY Chart Viewer +XmlXYViewer_DefaultXAxis=Time +XmlXYViewer_DefaultYAxis=Unit diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/package-info.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/package-info.java new file mode 100644 index 0000000000..eada481e0a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/xychart/package-info.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * École Polytechnique de Montréal - Initial API and implementation + *******************************************************************************/ + +@org.eclipse.jdt.annotation.NonNullByDefault +package org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.xychart; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/Messages.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/Messages.java new file mode 100644 index 0000000000..fa9f9575ca --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/Messages.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.ui.module; + +import org.eclipse.osgi.util.NLS; + +/** + * Externalized messages for the XML analysis module package + * + * @author Geneviève Bastien + */ +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.analysis.xml.ui.module.messages"; //$NON-NLS-1$ + + /** Import XML file title */ + public static String ImportXmlHandler_ImportXmlFile; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/TmfAnalysisModuleHelperXml.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/TmfAnalysisModuleHelperXml.java new file mode 100644 index 0000000000..527c944613 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/TmfAnalysisModuleHelperXml.java @@ -0,0 +1,184 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.ui.module; + +import java.io.File; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.Path; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.Activator; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.XmlStateSystemModule; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.osgi.framework.Bundle; +import org.w3c.dom.Element; + +/** + * Analysis module helpers for modules provided by XML files + * + * @author Geneviève Bastien + */ +public class TmfAnalysisModuleHelperXml implements IAnalysisModuleHelper { + + /** + * The types of analysis that can be XML-defined + */ + public enum XmlAnalysisModuleType { + /** Analysis will be of type XmlStateSystemModule */ + STATE_SYSTEM + } + + private final File fSourceFile; + private final Element fSourceElement; + private final XmlAnalysisModuleType fType; + + /** + * Constructor + * + * @param xmlFile + * The XML file containing the details of this analysis + * @param node + * The XML node element + * @param type + * The type of analysis + */ + public TmfAnalysisModuleHelperXml(File xmlFile, Element node, XmlAnalysisModuleType type) { + fSourceFile = xmlFile; + fSourceElement = node; + fType = type; + } + + @Override + public String getId() { + return fSourceElement.getAttribute(TmfXmlStrings.ID); + } + + @Override + public String getName() { + String name = null; + /* Label may be available in XML header */ + List head = XmlUtils.getChildElements(fSourceElement, TmfXmlStrings.HEAD); + if (head.size() == 1) { + List labels = XmlUtils.getChildElements(head.get(0), TmfXmlStrings.LABEL); + if (!labels.isEmpty()) { + name = labels.get(0).getAttribute(TmfXmlStrings.VALUE); + } + } + + if (name == null) { + name = getId(); + } + return name; + } + + @Override + public boolean isAutomatic() { + return false; + } + + @Override + public String getHelpText() { + return new String(); + } + + @Override + public String getHelpText(@NonNull ITmfTrace trace) { + return ""; //$NON-NLS-1$ + } + + @Override + public String getIcon() { + return null; + } + + @Override + public Bundle getBundle() { + return Activator.getDefault().getBundle(); + } + + @Override + public boolean appliesToTraceType(Class traceClass) { + /* Trace types may be available in XML header */ + List head = XmlUtils.getChildElements(fSourceElement, TmfXmlStrings.HEAD); + if (head.size() != 1) { + return true; + } + /* + * TODO: Test with custom trace types + */ + List elements = XmlUtils.getChildElements(head.get(0), TmfXmlStrings.TRACETYPE); + if (elements.isEmpty()) { + return true; + } + + for (Element element : elements) { + String traceTypeId = element.getAttribute(TmfXmlStrings.ID); + TraceTypeHelper helper = TmfTraceType.getTraceType(traceTypeId); + if ((helper != null) && helper.getTrace().getClass().isAssignableFrom(traceClass)) { + return true; + } + } + return false; + } + + @Override + public Iterable> getValidTraceTypes() { + return Collections.EMPTY_SET; + } + + @Override + public Iterable getAnalysisRequirements() { + return Collections.EMPTY_SET; + } + + @Override + public IAnalysisModule newModule(ITmfTrace trace) throws TmfAnalysisException { + String analysisid = getId(); + IAnalysisModule module = null; + switch (fType) { + case STATE_SYSTEM: + module = new XmlStateSystemModule(); + XmlStateSystemModule ssModule = (XmlStateSystemModule) module; + module.setId(analysisid); + ssModule.setXmlFile(new Path(fSourceFile.getAbsolutePath())); + + /* + * FIXME: There is no way to know if a module is automatic, so we + * default to true + */ + ssModule.setAutomatic(true); + + break; + default: + break; + + } + if (module != null) { + module.setTrace(trace); + TmfAnalysisManager.analysisModuleCreated(module); + } + + return module; + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/TmfXmlAnalysisOutputSource.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/TmfXmlAnalysisOutputSource.java new file mode 100644 index 0000000000..44bd0c76ca --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/TmfXmlAnalysisOutputSource.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.ui.module; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.TmfXmlUiStrings; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.xychart.XmlXYView; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.tracecompass.tmf.analysis.xml.ui.views.timegraph.XmlTimeGraphView; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisOutput; +import org.eclipse.tracecompass.tmf.core.analysis.ITmfNewAnalysisModuleListener; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +/** + * This class searches all XML files to find outputs applicable to the newly + * created analysis + * + * @author Geneviève Bastien + */ +public class TmfXmlAnalysisOutputSource implements ITmfNewAnalysisModuleListener { + + /** String separating data elements for the output properties */ + public static final String DATA_SEPARATOR = ";;;"; //$NON-NLS-1$ + + /** + * Enum to match the name of a view's XML element to its view ID. + * @since 1.2 + */ + public static enum ViewType { + /** + * Time graph view element + */ + TIME_GRAPH_VIEW(TmfXmlUiStrings.TIME_GRAPH_VIEW, XmlTimeGraphView.ID), + /** + * XY chart view element + */ + XY_VIEW(TmfXmlUiStrings.XY_VIEW, XmlXYView.ID); + + private final @NonNull String fXmlElem; + private final String fViewId; + + private ViewType(@NonNull String xmlElem, String viewId) { + fXmlElem = xmlElem; + fViewId = viewId; + } + + /** + * Get the XML element corresponding to this view type + * + * @return The XML element corresponding to this type + */ + public @NonNull String getXmlElem() { + return fXmlElem; + } + + private String getViewId() { + return fViewId; + } + } + + + @Override + public void moduleCreated(IAnalysisModule module) { + IPath pathToFiles = XmlUtils.getXmlFilesPath(); + File fFolder = pathToFiles.toFile(); + if (!(fFolder.isDirectory() && fFolder.exists())) { + return; + } + for (File xmlFile : fFolder.listFiles()) { + if (!XmlUtils.xmlValidate(xmlFile).isOK()) { + continue; + } + + try { + /* Load the XML File */ + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(xmlFile); + doc.getDocumentElement().normalize(); + + /* get state provider views if the analysis has state systems */ + if (module instanceof TmfStateSystemAnalysisModule) { + for (ViewType viewType : ViewType.values()) { + NodeList ssViewNodes = doc.getElementsByTagName(viewType.getXmlElem()); + for (int i = 0; i < ssViewNodes.getLength(); i++) { + Element node = (Element) ssViewNodes.item(i); + + /* Check if analysis is the right one */ + List headNodes = XmlUtils.getChildElements(node, TmfXmlStrings.HEAD); + if (headNodes.size() != 1) { + continue; + } + + List analysisNodes = XmlUtils.getChildElements(headNodes.get(0), TmfXmlStrings.ANALYSIS); + for (Element analysis : analysisNodes) { + String analysisId = analysis.getAttribute(TmfXmlStrings.ID); + if (analysisId.equals(module.getId())) { + String viewId = viewType.getViewId(); + IAnalysisOutput output = new TmfXmlViewOutput(viewId, viewType); + output.setOutputProperty(TmfXmlUiStrings.XML_OUTPUT_DATA, node.getAttribute(TmfXmlStrings.ID) + DATA_SEPARATOR + xmlFile.getAbsolutePath(), false); + module.registerOutput(output); + } + } + } + } + } + } catch (ParserConfigurationException | SAXException | IOException e) { + Activator.logError("Error opening XML file", e); //$NON-NLS-1$ + } + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/TmfXmlViewOutput.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/TmfXmlViewOutput.java new file mode 100644 index 0000000000..86a57f35f1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/TmfXmlViewOutput.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.ui.module; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.TmfXmlUiStrings; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.tracecompass.tmf.analysis.xml.ui.module.TmfXmlAnalysisOutputSource.ViewType; +import org.eclipse.tracecompass.tmf.ui.analysis.TmfAnalysisViewOutput; +import org.w3c.dom.Element; + +/** + * Class overriding the default analysis view output for XML views. These views + * may have labels defined in the XML element and those label will be used as + * the name of the view + * + * @author Geneviève Bastien + * + * TODO: We shouldn't have to do a new class here, we should be able to + * set the name in the parent instead + */ +public class TmfXmlViewOutput extends TmfAnalysisViewOutput { + + private String fLabel = null; + private final @NonNull ViewType fViewType; + + /** + * Constructor + * + * @param viewid + * id of the view to display as output + */ + public TmfXmlViewOutput(String viewid) { + this(viewid, ViewType.TIME_GRAPH_VIEW); + } + + /** + * Constructor + * + * @param viewid + * id of the view to display as output + * @param viewType + * type of view this output is for + * @since 1.2 + */ + public TmfXmlViewOutput(String viewid, @NonNull ViewType viewType) { + super(viewid); + fViewType = viewType; + } + + @Override + public String getName() { + if (fLabel == null) { + return super.getName(); + } + return fLabel; + } + + @Override + public void setOutputProperty(@NonNull String key, String value, boolean immediate) { + super.setOutputProperty(key, value, immediate); + /* Find the label of the view */ + if (key.equals(TmfXmlUiStrings.XML_OUTPUT_DATA)) { + String[] idFile = value.split(TmfXmlAnalysisOutputSource.DATA_SEPARATOR); + String viewId = (idFile.length > 0) ? idFile[0] : null; + String filePath = (idFile.length > 1) ? idFile[1] : null; + if ((viewId == null) || (filePath == null)) { + return; + } + Element viewElement = XmlUtils.getElementInFile(filePath, fViewType.getXmlElem(), viewId); + if (viewElement == null) { + return; + } + List heads = XmlUtils.getChildElements(viewElement, TmfXmlStrings.HEAD); + if (heads.size() != 1) { + return; + } + Element headElement = heads.get(0); + List label = XmlUtils.getChildElements(headElement, TmfXmlStrings.LABEL); + if (label.isEmpty()) { + return; + } + Element labelElement = label.get(0); + fLabel = labelElement.getAttribute(TmfXmlStrings.VALUE); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/XmlAnalysisModuleSource.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/XmlAnalysisModuleSource.java new file mode 100644 index 0000000000..84065e7533 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/XmlAnalysisModuleSource.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.ui.module; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.Activator; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.tracecompass.tmf.analysis.xml.ui.module.TmfAnalysisModuleHelperXml.XmlAnalysisModuleType; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleSource; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager; +import org.osgi.framework.Bundle; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +/** + * Analysis module source who creates helpers for the analysis modules described + * in the imported XML files + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class XmlAnalysisModuleSource implements IAnalysisModuleSource { + + /** Extension point ID */ + private static final String TMF_XML_BUILTIN_ID = "org.eclipse.linuxtools.tmf.analysis.xml.core.files"; //$NON-NLS-1$ + private static final String XML_FILE_ELEMENT = "xmlfile"; //$NON-NLS-1$ + + private static final String XML_FILE_ATTRIB = "file"; //$NON-NLS-1$ + + private static List fModules = null; + + /** + * Constructor. It adds the new module listener to the analysis manager. + */ + public XmlAnalysisModuleSource() { + TmfAnalysisManager.addNewModuleListener(new TmfXmlAnalysisOutputSource()); + } + + @Override + public synchronized Iterable getAnalysisModules() { + if (fModules == null) { + fModules = new ArrayList<>(); + populateBuiltinModules(); + populateAnalysisModules(); + } + return fModules; + } + + private static void processFile(File xmlFile) { + if (!XmlUtils.xmlValidate(xmlFile).isOK()) { + return; + } + + try { + /* Load the XML File */ + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(xmlFile); + doc.getDocumentElement().normalize(); + + /* get State Providers modules */ + NodeList stateproviderNodes = doc.getElementsByTagName(TmfXmlStrings.STATE_PROVIDER); + for (int i = 0; i < stateproviderNodes.getLength(); i++) { + Element node = (Element) stateproviderNodes.item(i); + + IAnalysisModuleHelper helper = new TmfAnalysisModuleHelperXml(xmlFile, node, XmlAnalysisModuleType.STATE_SYSTEM); + fModules.add(helper); + } + } catch (ParserConfigurationException | SAXException | IOException e) { + Activator.logError("Error opening XML file", e); //$NON-NLS-1$ + } + } + + private static void populateBuiltinModules() { + /* Get the XML files advertised through the extension point */ + IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_XML_BUILTIN_ID); + for (IConfigurationElement element : elements) { + if (element.getName().equals(XML_FILE_ELEMENT)) { + String filename = element.getAttribute(XML_FILE_ATTRIB); + String name = element.getContributor().getName(); + if (name != null) { + Bundle bundle = Platform.getBundle(name); + if (bundle != null) { + try { + URL xmlUrl = bundle.getResource(filename); + URL locatedURL = FileLocator.toFileURL(xmlUrl); + processFile(new File(locatedURL.getFile())); + } catch (IOException e) { + /* ignore */ + } + } + } + } + } + } + + private static void populateAnalysisModules() { + IPath pathToFiles = XmlUtils.getXmlFilesPath(); + File fFolder = pathToFiles.toFile(); + if (!(fFolder.isDirectory() && fFolder.exists())) { + return; + } + for (File xmlFile : fFolder.listFiles()) { + processFile(xmlFile); + } + } + + /** + * Notifies the main XML analysis module that the executable modules list + * may have changed and needs to be refreshed. + */ + public static void notifyModuleChange() { + fModules = null; + TmfAnalysisManager.refreshModules(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/messages.properties b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/messages.properties new file mode 100644 index 0000000000..3059e008b1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/messages.properties @@ -0,0 +1,12 @@ +############################################################################### +# Copyright (c) 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### +ImportXmlHandler_ImportXmlFile=Import XML analysis file diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/Messages.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/Messages.java new file mode 100644 index 0000000000..f7e3bfde0d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/Messages.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.ui.views.timegraph; + +import org.eclipse.osgi.util.NLS; + +/** + * Message for the XML state system view + * + * @author Geneviève Bastien + */ +@SuppressWarnings("javadoc") +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.analysis.xml.ui.views.timegraph.messages"; //$NON-NLS-1$ + + public static String XmlPresentationProvider_MultipleStates; + + /* Default text messages */ + public static String XmlTimeGraphView_ColumnId; + public static String XmlTimeGraphView_ColumnName; + public static String XmlTimeGraphView_ColumnParentId; + public static String XmlTimeGraphView_DefaultTitle; + + /* Text and tooltips of the view */ + public static String XmlTimeGraphView_NextText; + public static String XmlTimeGraphView_NextTooltip; + public static String XmlTimeGraphView_PreviousInterval; + public static String XmlTimeGraphView_PreviousText; + + /* Errors and warnings messages */ + public static String XmlTimeGraphView_UselessEndPath; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlEntry.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlEntry.java new file mode 100644 index 0000000000..029ce8f315 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlEntry.java @@ -0,0 +1,272 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Florian Wininger - Initial API and implementation + * Geneviève Bastien - Review of the initial implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.ui.views.timegraph; + +import java.util.Collections; +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; +import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.TmfXmlUiStrings; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.ITmfXmlModelFactory; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.ITmfXmlStateAttribute; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlLocation; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.readonly.TmfXmlReadOnlyModelFactory; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry; +import org.w3c.dom.Element; + +/** + * An XML-defined entry, or row, to display in the XML state system view + * + * @author Florian Wininger + */ +public class XmlEntry extends TimeGraphEntry implements IXmlStateSystemContainer { + + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + + /** Type of resource */ + public static enum EntryDisplayType { + /** Entries without events to display (filler rows, etc.) */ + NULL, + /** Entries with time events */ + DISPLAY + } + + private final ITmfTrace fTrace; + private final EntryDisplayType fType; + private final int fBaseQuark; + private final int fDisplayQuark; + private final String fParentId; + private final String fId; + private final @NonNull ITmfStateSystem fSs; + private final Element fElement; + + /** + * Constructor + * + * @param baseQuark + * The quark matching this entry, or -1 if no quark + * @param displayQuark + * The quark containing the value to display. It was needed by + * the caller to get the start and end time of this entry, so we + * receive it as parameter from him. + * @param trace + * The trace on which we are working (FIXME: is this parameter + * useful?) + * @param name + * The name of this entry. It will be overridden if a "name" XML + * tag is specified in the entryElement. It will also be used as + * the ID of this entry if no "id" XML tag is specified. It + * typically is the attribute name corresponding the the base + * quark. + * @param startTime + * The start time of this entry lifetime + * @param endTime + * The end time of this entry + * @param type + * The display type of this entry + * @param ss + * The state system this entry belongs to + * @param entryElement + * The XML element describing this entry. This element will be + * used to determine, if available, the parent, ID, name and + * other display option of this entry + */ + public XmlEntry(int baseQuark, int displayQuark, ITmfTrace trace, String name, long startTime, long endTime, EntryDisplayType type, @NonNull ITmfStateSystem ss, Element entryElement) { + super(name, startTime, endTime); + fTrace = trace; + fType = type; + fBaseQuark = baseQuark; + fDisplayQuark = displayQuark; + fSs = ss; + fElement = entryElement; + + /* Get the parent if specified */ + List elements = XmlUtils.getChildElements(fElement, TmfXmlUiStrings.PARENT_ELEMENT); + if (elements.size() > 0) { + fParentId = getFirstValue(elements.get(0)); + } else { + fParentId = EMPTY_STRING; + } + + /* Get the name of this entry */ + elements = XmlUtils.getChildElements(fElement, TmfXmlUiStrings.NAME_ELEMENT); + if (elements.size() > 0) { + String nameFromSs = getFirstValue(elements.get(0)); + if (!nameFromSs.isEmpty()) { + setName(nameFromSs); + } + } + + /* Get the id of this entry */ + elements = XmlUtils.getChildElements(fElement, TmfXmlUiStrings.ID_ELEMENT); + if (elements.size() > 0) { + fId = getFirstValue(elements.get(0)); + } else { + fId = name; + } + + } + + /** + * Constructor + * + * @param baseQuark + * The quark matching this entry, or -1 if no quark + * @param trace + * The trace on which we are working + * @param name + * The exec_name of this entry + * @param ss + * The state system this entry belongs to + */ + public XmlEntry(int baseQuark, ITmfTrace trace, String name, @NonNull ITmfStateSystem ss) { + super(name, ss.getStartTime(), ss.getCurrentEndTime()); + fTrace = trace; + fType = EntryDisplayType.NULL; + fBaseQuark = baseQuark; + fDisplayQuark = baseQuark; + fSs = ss; + fElement = null; + fParentId = EMPTY_STRING; + fId = name; + } + + /** Return the state value of the first interval with a non-null value */ + private String getFirstValue(Element stateAttribute) { + ITmfXmlModelFactory factory = TmfXmlReadOnlyModelFactory.getInstance(); + ITmfXmlStateAttribute display = factory.createStateAttribute(stateAttribute, this); + int quark = display.getAttributeQuark(fBaseQuark); + if (quark != IXmlStateSystemContainer.ERROR_QUARK) { + try { + /* Find the first attribute with a parent */ + List execNameIntervals = fSs.queryHistoryRange(quark, getStartTime(), getEndTime()); + for (ITmfStateInterval execNameInterval : execNameIntervals) { + + if (!execNameInterval.getStateValue().isNull()) { + return execNameInterval.getStateValue().toString(); + } + } + } catch (AttributeNotFoundException | StateSystemDisposedException e) { + } + } + return EMPTY_STRING; + } + + /** + * Get the trace this entry was taken from + * + * @return the entry's trace + */ + public ITmfTrace getTrace() { + return fTrace; + } + + /** + * Get the entry Type of this entry. Uses the inner EntryDisplayType enum. + * + * @return The entry type + */ + public EntryDisplayType getType() { + return fType; + } + + /** + * Get the quark from which to get the time event intervals for this entry. + * + * @return The attribute quark containing the intervals to display + */ + public int getDisplayQuark() { + return fDisplayQuark; + } + + /** + * Get this entry's ID + * + * @return The id of the entry. + */ + public String getId() { + return fId; + } + + /** + * Return the entry's parent ID. It corresponds to another entry's ID + * received from the {@link #getId()} method. + * + * @return The parent ID of this entry + */ + public String getParentId() { + return fParentId; + } + + @Override + public boolean hasTimeEvents() { + if (fType == EntryDisplayType.NULL) { + return false; + } + return true; + } + + /** + * Add a child to this entry of type XmlEntry + * + * @param entry + * The entry to add + */ + public void addChild(XmlEntry entry) { + int index; + for (index = 0; index < getChildren().size(); index++) { + XmlEntry other = (XmlEntry) getChildren().get(index); + if (entry.getType().compareTo(other.getType()) < 0) { + break; + } else if (entry.getType().equals(other.getType())) { + if (entry.getName().compareTo(other.getName()) < 0) { + break; + } + } + } + + entry.setParent(this); + addChild(index, entry); + } + + /** + * Return the state system this entry is associated to + * + * @return The state system, or null if the state system can't + * be found. + */ + @Override + @NonNull + public ITmfStateSystem getStateSystem() { + return fSs; + } + + @Override + public String getAttributeValue(String name) { + return name; + } + + @Override + public Iterable getLocations() { + return Collections.EMPTY_SET; + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlPresentationProvider.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlPresentationProvider.java new file mode 100644 index 0000000000..61fef5385b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlPresentationProvider.java @@ -0,0 +1,220 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Florian Wininger - Initial API and implementation + * Geneviève Bastien - Review of the initial implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.ui.views.timegraph; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.TmfXmlUiStrings; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.tracecompass.tmf.analysis.xml.ui.views.timegraph.XmlEntry.EntryDisplayType; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.StateItem; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent; +import org.w3c.dom.Element; + +/** + * Presentation provider for the XML view, based on the generic TMF presentation + * provider. + * + * TODO: This should support colors/states defined for each entry element in the + * XML element. Also, event values may not be integers only (for instance, this + * wouldn't support yet the callstack view) + * + * @author Florian Wininger + */ +public class XmlPresentationProvider extends TimeGraphPresentationProvider { + + private List stateValues = new ArrayList<>(); + /* + * Maps the value of an event with the corresponding index in the + * stateValues list + */ + private Map stateIndex = new HashMap<>(); + + @Override + public int getStateTableIndex(ITimeEvent event) { + if (event instanceof TimeEvent && ((TimeEvent) event).hasValue()) { + TimeEvent tcEvent = (TimeEvent) event; + + XmlEntry entry = (XmlEntry) event.getEntry(); + int value = tcEvent.getValue(); + + if (entry.getType() == EntryDisplayType.DISPLAY) { + Integer index = stateIndex.get(value); + if (index == null) { + /* Colors won't be refreshed yet, return something known */ + index = TRANSPARENT; + stateIndex.put(value, stateValues.size()); + StateItem item = new StateItem(calcColor(stateValues.size()), String.valueOf(value)); + stateValues.add(item); + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + fireColorSettingsChanged(); + } + }); + } + return index; + } + } + + return INVISIBLE; + } + + @Override + public StateItem[] getStateTable() { + return stateValues.toArray(new StateItem[stateValues.size()]); + } + + @Override + public String getEventName(ITimeEvent event) { + if (event instanceof TimeEvent && ((TimeEvent) event).hasValue()) { + TimeEvent tcEvent = (TimeEvent) event; + + XmlEntry entry = (XmlEntry) event.getEntry(); + int value = tcEvent.getValue(); + + if (entry.getType() == EntryDisplayType.DISPLAY) { + Integer index = stateIndex.get(value); + String rgb = stateValues.get(index).getStateString(); + return rgb; + } + return null; + } + return Messages.XmlPresentationProvider_MultipleStates; + } + + @Override + public Map getEventHoverToolTipInfo(ITimeEvent event, long hoverTime) { + /* + * TODO: Add the XML elements to support adding extra information in the + * tooltips and implement this + */ + return Collections.EMPTY_MAP; + } + + @Override + public void postDrawEvent(ITimeEvent event, Rectangle bounds, GC gc) { + /* + * TODO Add the XML elements to support texts in intervals and implement + * this + */ + } + + @Override + public void postDrawEntry(ITimeGraphEntry entry, Rectangle bounds, GC gc) { + } + + /** + * Loads the states from a {@link TmfXmlUiStrings#TIME_GRAPH_VIEW} XML + * element + * + * @param viewElement + * The XML view element + */ + public void loadNewStates(@NonNull Element viewElement) { + stateValues.clear(); + stateIndex.clear(); + List states = XmlUtils.getChildElements(viewElement, TmfXmlStrings.DEFINED_VALUE); + + for (Element state : states) { + int value = Integer.parseInt(state.getAttribute(TmfXmlStrings.VALUE)); + String name = state.getAttribute(TmfXmlStrings.NAME); + String color = state.getAttribute(TmfXmlStrings.COLOR); + + // FIXME Allow this case + if (value < 0) { + return; + } + + RGB colorRGB = new RGB(255, 0, 0); + if (color.startsWith(TmfXmlStrings.COLOR_PREFIX)) { + Integer hex = Integer.parseInt(color.substring(1), 16); + int hex1 = hex.intValue() % 256; + int hex2 = (hex.intValue() / 256) % 256; + int hex3 = (hex.intValue() / (256 * 256)) % 256; + colorRGB = new RGB(hex3, hex2, hex1); + } else { + colorRGB = calcColor(value); + } + + StateItem item = new StateItem(colorRGB, name); + + Integer index = stateIndex.get(value); + if (index == null) { + /* Add the new state value */ + stateIndex.put(value, stateValues.size()); + stateValues.add(item); + } else { + /* Override a previous state value */ + stateValues.set(index, item); + } + } + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + fireColorSettingsChanged(); + } + }); + } + + private static RGB calcColor(int value) { + int x = (value * 97) % 1530; + int r = 0, g = 0, b = 0; + if (x >= 0 && x < 255) { + r = 255; + g = x; + b = 0; + } + if (x >= 255 && x < 510) { + r = 510 - x; + g = 255; + b = 0; + } + if (x >= 510 && x < 765) { + r = 0; + g = 255; + b = x - 510; + } + if (x >= 765 && x < 1020) { + r = 0; + g = 1020 - x; + b = 255; + } + if (x >= 1020 && x < 1275) { + r = x - 1020; + g = 0; + b = 255; + } + if (x >= 1275 && x <= 1530) { + r = 255; + g = 0; + b = 1530 - x; + } + return new RGB(r, g, b); + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlTimeGraphView.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlTimeGraphView.java new file mode 100644 index 0000000000..4721ebb634 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlTimeGraphView.java @@ -0,0 +1,512 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Florian Wininger - Initial API and implementation + * Geneviève Bastien - Review of the initial implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.analysis.xml.ui.views.timegraph; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.TmfXmlUiStrings; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.XmlViewInfo; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.ITmfXmlModelFactory; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.ITmfXmlStateAttribute; +import org.eclipse.tracecompass.tmf.analysis.xml.core.model.readonly.TmfXmlReadOnlyModelFactory; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.tracecompass.tmf.analysis.xml.ui.views.timegraph.XmlEntry.EntryDisplayType; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfAnalysisModuleWithStateSystems; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ui.views.timegraph.AbstractTimeGraphView; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider2; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.NullTimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry; +import org.w3c.dom.Element; + +/** + * This view displays state system data in a time graph view. It uses an XML + * {@link TmfXmlUiStrings#TIME_GRAPH_VIEW} element from an XML file. This + * element defines which entries from the state system will be shown and also + * gives additional information on the presentation of the view (states, colors, + * etc) + * + * @author Florian Wininger + */ +public class XmlTimeGraphView extends AbstractTimeGraphView { + + /** View ID. */ + public static final @NonNull String ID = "org.eclipse.linuxtools.tmf.analysis.xml.ui.views.timegraph"; //$NON-NLS-1$ + + private static final String[] DEFAULT_COLUMN_NAMES = new String[] { + Messages.XmlTimeGraphView_ColumnName, + Messages.XmlTimeGraphView_ColumnId, + Messages.XmlTimeGraphView_ColumnParentId, + }; + + private static final String[] DEFAULT_FILTER_COLUMN_NAMES = new String[] { + Messages.XmlTimeGraphView_ColumnName, + Messages.XmlTimeGraphView_ColumnId + }; + + /** The relative weight of the sash */ + private static final int[] fWeight = { 1, 2 }; + + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + private static final String SPLIT_STRING = "/"; //$NON-NLS-1$ + + private final @NonNull XmlViewInfo fViewInfo = new XmlViewInfo(ID); + private final ITmfXmlModelFactory fFactory; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + public XmlTimeGraphView() { + super(ID, new XmlPresentationProvider()); + setWeight(fWeight); + setTreeColumns(DEFAULT_COLUMN_NAMES); + setTreeLabelProvider(new XmlTreeLabelProvider()); + setFilterColumns(DEFAULT_FILTER_COLUMN_NAMES); + setFilterLabelProvider(new XmlTreeLabelProvider()); + setEntryComparator(new XmlEntryComparator()); + this.addPartPropertyListener(new IPropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent event) { + if (event.getProperty().equals(TmfXmlUiStrings.XML_OUTPUT_DATA)) { + Object newValue = event.getNewValue(); + if (newValue instanceof String) { + String data = (String) newValue; + fViewInfo.setViewData(data); + loadNewXmlView(); + } + } + } + }); + + fFactory = TmfXmlReadOnlyModelFactory.getInstance(); + } + + private void loadNewXmlView() { + rebuild(); + } + + private void setViewTitle(final String title) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + setPartName(title); + } + }); + + } + + @Override + protected String getNextText() { + return Messages.XmlTimeGraphView_NextText; + } + + @Override + protected String getNextTooltip() { + return Messages.XmlTimeGraphView_NextTooltip; + } + + @Override + protected String getPrevText() { + return Messages.XmlTimeGraphView_PreviousText; + } + + @Override + protected String getPrevTooltip() { + return Messages.XmlTimeGraphView_PreviousInterval; + } + + /** + * Default label provider, it shows name, id and parent columns + * + * TODO: There should be a way to define columns in the XML + * */ + private static class XmlTreeLabelProvider extends TreeLabelProvider { + + @Override + public String getColumnText(Object element, int columnIndex) { + XmlEntry entry = (XmlEntry) element; + + if (DEFAULT_COLUMN_NAMES[columnIndex].equals(Messages.XmlTimeGraphView_ColumnName)) { + return entry.getName(); + } else if (DEFAULT_COLUMN_NAMES[columnIndex].equals(Messages.XmlTimeGraphView_ColumnId)) { + return entry.getId(); + } else if (DEFAULT_COLUMN_NAMES[columnIndex].equals(Messages.XmlTimeGraphView_ColumnParentId)) { + return entry.getParentId(); + } + return EMPTY_STRING; + } + + } + + private static class XmlEntryComparator implements Comparator { + + @Override + public int compare(ITimeGraphEntry o1, ITimeGraphEntry o2) { + + int result = 0; + + if ((o1 instanceof XmlEntry) && (o2 instanceof XmlEntry)) { + XmlEntry entry1 = (XmlEntry) o1; + XmlEntry entry2 = (XmlEntry) o2; + result = entry1.getTrace().getStartTime().compareTo(entry2.getTrace().getStartTime()); + if (result == 0) { + result = entry1.getTrace().getName().compareTo(entry2.getTrace().getName()); + } + if (result == 0) { + result = entry1.getName().compareTo(entry2.getName()); + } + } + + if (result == 0) { + result = o1.getStartTime() < o2.getStartTime() ? -1 : o1.getStartTime() > o2.getStartTime() ? 1 : 0; + } + + return result; + } + } + + // ------------------------------------------------------------------------ + // Internal + // ------------------------------------------------------------------------ + + @Override + protected void buildEventList(ITmfTrace trace, ITmfTrace parentTrace, IProgressMonitor monitor) { + + /* + * Get the view element from the XML file. If the element can't be + * found, return. + */ + Element viewElement = fViewInfo.getViewElement(TmfXmlUiStrings.TIME_GRAPH_VIEW); + if (viewElement == null) { + return; + } + ITimeGraphPresentationProvider2 pres = this.getPresentationProvider(); + if (pres instanceof XmlPresentationProvider) { + /* + * TODO: Each entry of a line could have their own states/color. + * That will require an update to the presentation provider + */ + ((XmlPresentationProvider) pres).loadNewStates(viewElement); + } + + String title = fViewInfo.getViewTitle(viewElement); + if (title == null) { + title = Messages.XmlTimeGraphView_DefaultTitle; + } + setViewTitle(title); + Set analysisIds = fViewInfo.getViewAnalysisIds(viewElement); + + List entries = XmlUtils.getChildElements(viewElement, TmfXmlUiStrings.ENTRY_ELEMENT); + Set entryList = new TreeSet<>(getEntryComparator()); + for (ITmfTrace aTrace : TmfTraceManager.getTraceSet(trace)) { + if (monitor.isCanceled()) { + return; + } + + List stateSystemModules = new LinkedList<>(); + if (analysisIds.isEmpty()) { + /* + * No analysis specified, take all state system analysis modules + */ + for (ITmfAnalysisModuleWithStateSystems module : aTrace.getAnalysisModulesOfClass(ITmfAnalysisModuleWithStateSystems.class)) { + stateSystemModules.add(module); + } + } else { + for (String moduleId : analysisIds) { + ITmfAnalysisModuleWithStateSystems module = aTrace.getAnalysisModuleOfClass(ITmfAnalysisModuleWithStateSystems.class, moduleId); + if (module != null) { + stateSystemModules.add(module); + } + } + } + + for (ITmfAnalysisModuleWithStateSystems module : stateSystemModules) { + module.schedule(); + if (module instanceof TmfStateSystemAnalysisModule) { + ((TmfStateSystemAnalysisModule) module).waitForInitialization(); + } + for (ITmfStateSystem ssq : module.getStateSystems()) { + if (ssq == null) { + return; + } + ssq.waitUntilBuilt(); + + long startTime = ssq.getStartTime(); + long endTime = ssq.getCurrentEndTime(); + XmlEntry groupEntry = new XmlEntry(-1, aTrace, aTrace.getName(), ssq); + entryList.add(groupEntry); + setStartTime(Math.min(getStartTime(), startTime)); + setEndTime(Math.max(getEndTime(), endTime)); + + /* Add children entry of this entry for each line */ + for (Element entry : entries) { + buildEntry(entry, groupEntry, -1); + } + } + } + } + putEntryList(trace, new ArrayList(entryList)); + + if (trace.equals(getTrace())) { + refresh(); + } + for (XmlEntry traceEntry : entryList) { + if (monitor.isCanceled()) { + return; + } + long startTime = traceEntry.getStateSystem().getStartTime(); + long endTime = traceEntry.getStateSystem().getCurrentEndTime() + 1; + buildStatusEvent(traceEntry, monitor, startTime, endTime); + } + } + + private void buildEntry(Element entryElement, XmlEntry parentEntry, int baseQuark) { + /* Get the attribute string to display */ + String path = entryElement.getAttribute(TmfXmlUiStrings.PATH); + if (path.isEmpty()) { + path = TmfXmlStrings.WILDCARD; + } + + /* + * Make sure the XML element has either a display attribute or entries, + * otherwise issue a warning + */ + + List displayElements = XmlUtils.getChildElements(entryElement, TmfXmlUiStrings.DISPLAY_ELEMENT); + List entryElements = XmlUtils.getChildElements(entryElement, TmfXmlUiStrings.ENTRY_ELEMENT); + + if (displayElements.isEmpty() && entryElements.isEmpty()) { + Activator.logWarning(String.format("XML view: entry for %s should have either a display element or entry elements", path)); //$NON-NLS-1$ + return; + } + + ITmfStateSystem ss = parentEntry.getStateSystem(); + + /* Get the list of quarks to process with this path */ + String[] paths = path.split(SPLIT_STRING); + int i = 0; + List quarks = Collections.singletonList(baseQuark); + + try { + while (i < paths.length) { + List subQuarks = new LinkedList<>(); + /* Replace * by .* to have a regex string */ + String name = paths[i].replaceAll("\\*", ".*"); //$NON-NLS-1$ //$NON-NLS-2$ + for (int relativeQuark : quarks) { + for (int quark : ss.getSubAttributes(relativeQuark, false, name)) { + subQuarks.add(quark); + } + } + quarks = subQuarks; + i++; + } + + /* Process each quark */ + XmlEntry currentEntry = parentEntry; + Element displayElement = null; + Map entryMap = new HashMap<>(); + if (!displayElements.isEmpty()) { + displayElement = displayElements.get(0); + } + for (int quark : quarks) { + currentEntry = parentEntry; + /* Process the current entry, if specified */ + if (displayElement != null) { + currentEntry = processEntry(entryElement, displayElement, parentEntry, quark, ss); + entryMap.put(currentEntry.getId(), currentEntry); + } + /* Process the children entry of this entry */ + for (Element subEntryEl : entryElements) { + buildEntry(subEntryEl, currentEntry, quark); + } + } + if (!entryMap.isEmpty()) { + buildTree(entryMap, parentEntry); + } + } catch (AttributeNotFoundException e) { + } + } + + private XmlEntry processEntry(@NonNull Element entryElement, @NonNull Element displayEl, + XmlEntry parentEntry, int quark, ITmfStateSystem ss) { + /* + * Get the start time and end time of this entry from the display + * attribute + */ + ITmfXmlStateAttribute display = fFactory.createStateAttribute(displayEl, parentEntry); + int displayQuark = display.getAttributeQuark(quark); + if (displayQuark == IXmlStateSystemContainer.ERROR_QUARK) { + return new XmlEntry(quark, parentEntry.getTrace(), + String.format("Unknown display quark for %s", ss.getAttributeName(quark)), ss); //$NON-NLS-1$ + } + + long entryStart = ss.getStartTime(); + long entryEnd = ss.getCurrentEndTime(); + + try { + + ITmfStateInterval oneInterval = ss.querySingleState(entryStart, displayQuark); + + /* The entry start is the first non-null interval */ + while (oneInterval.getStateValue().isNull()) { + long ts = oneInterval.getEndTime() + 1; + if (ts > ss.getCurrentEndTime()) { + break; + } + oneInterval = ss.querySingleState(ts, displayQuark); + } + entryStart = oneInterval.getStartTime(); + + /* The entry end is the last non-null interval */ + oneInterval = ss.querySingleState(entryEnd, displayQuark); + while (oneInterval.getStateValue().isNull()) { + long ts = oneInterval.getStartTime() - 1; + if (ts < ss.getStartTime()) { + break; + } + oneInterval = ss.querySingleState(ts, displayQuark); + } + entryEnd = oneInterval.getEndTime(); + + } catch (AttributeNotFoundException | StateSystemDisposedException e) { + } + + return new XmlEntry(quark, displayQuark, parentEntry.getTrace(), ss.getAttributeName(quark), + entryStart, entryEnd, EntryDisplayType.DISPLAY, ss, entryElement); + } + + private void buildStatusEvent(XmlEntry traceEntry, IProgressMonitor monitor, long start, long end) { + long resolution = (end - start) / getDisplayWidth(); + long startTime = Math.max(start, traceEntry.getStartTime()); + long endTime = Math.min(end + 1, traceEntry.getEndTime()); + List eventList = getEventList(traceEntry, startTime, endTime, resolution, monitor); + if (monitor.isCanceled()) { + return; + } + traceEntry.setEventList(eventList); + redraw(); + + for (ITimeGraphEntry entry : traceEntry.getChildren()) { + if (monitor.isCanceled()) { + return; + } + XmlEntry xmlEntry = (XmlEntry) entry; + buildStatusEvent(xmlEntry, monitor, start, end); + } + } + + /** Build a tree using getParentId() and getId() */ + private static void buildTree(Map entryMap, XmlEntry rootEntry) { + for (XmlEntry entry : entryMap.values()) { + boolean root = true; + if (!entry.getParentId().isEmpty()) { + XmlEntry parent = entryMap.get(entry.getParentId()); + if (parent != null && + entry.getStartTime() >= parent.getStartTime() && + entry.getStartTime() <= parent.getEndTime()) { + parent.addChild(entry); + root = false; + } + } + if (root) { + rootEntry.addChild(entry); + } + } + } + + @Override + protected List getEventList(TimeGraphEntry entry, long startTime, long endTime, long resolution, IProgressMonitor monitor) { + if (!(entry instanceof XmlEntry)) { + return Collections.EMPTY_LIST; + } + XmlEntry xmlEntry = (XmlEntry) entry; + ITmfStateSystem ssq = xmlEntry.getStateSystem(); + final long realStart = Math.max(startTime, entry.getStartTime()); + final long realEnd = Math.min(endTime, entry.getEndTime()); + if (realEnd <= realStart) { + return null; + } + List eventList = null; + int quark = xmlEntry.getDisplayQuark(); + + try { + if (xmlEntry.getType() == EntryDisplayType.DISPLAY) { + + List statusIntervals = ssq.queryHistoryRange(quark, realStart, realEnd - 1, resolution, monitor); + eventList = new ArrayList<>(statusIntervals.size()); + long lastEndTime = -1; + for (ITmfStateInterval statusInterval : statusIntervals) { + if (monitor.isCanceled()) { + return null; + } + int status = statusInterval.getStateValue().unboxInt(); + long time = statusInterval.getStartTime(); + long duration = statusInterval.getEndTime() - time + 1; + if (!statusInterval.getStateValue().isNull()) { + if (lastEndTime != time && lastEndTime != -1) { + eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime)); + } + eventList.add(new TimeEvent(entry, time, duration, status)); + } else if (lastEndTime == -1 || time + duration >= endTime) { + // add null event if it intersects the start or end time + eventList.add(new NullTimeEvent(entry, time, duration)); + } + lastEndTime = time + duration; + } + } + } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException | StateSystemDisposedException e) { + /* Ignored */ + } + return eventList; + } + + @Override + protected List getLinkList(long startTime, long endTime, long resolution, IProgressMonitor monitor) { + /* TODO: not implemented yet, need XML to go along */ + return Collections.EMPTY_LIST; + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/messages.properties b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/messages.properties new file mode 100644 index 0000000000..73b9566d2d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/messages.properties @@ -0,0 +1,10 @@ +XmlPresentationProvider_MultipleStates=(multiple) +XmlTimeGraphView_ColumnId=ID +XmlTimeGraphView_ColumnName=Name +XmlTimeGraphView_ColumnParentId=ParentID +XmlTimeGraphView_DefaultTitle=Xml State Provider +XmlTimeGraphView_NextText=Next Interval +XmlTimeGraphView_NextTooltip=Select next interval in time graph +XmlTimeGraphView_PreviousInterval=Select previous interval in time graph +XmlTimeGraphView_PreviousText=Previous Interval +XmlTimeGraphView_UselessEndPath=There should be an XML for path {0} in the view's XML otherwise the last level is useless diff --git a/org.eclipse.tracecompass.tmf.core.tests/META-INF/MANIFEST.MF b/org.eclipse.tracecompass.tmf.core.tests/META-INF/MANIFEST.MF index ea767a3df5..0d58299039 100644 --- a/org.eclipse.tracecompass.tmf.core.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.tracecompass.tmf.core.tests/META-INF/MANIFEST.MF @@ -5,7 +5,7 @@ Bundle-Vendor: %Bundle-Vendor Bundle-Version: 3.1.0.qualifier Bundle-Localization: plugin Bundle-SymbolicName: org.eclipse.tracecompass.tmf.core.tests;singleton:=true -Bundle-Activator: org.eclipse.linuxtools.tmf.core.tests.TmfCoreTestPlugin +Bundle-Activator: org.eclipse.tracecompass.tmf.core.tests.TmfCoreTestPlugin Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Require-Bundle: org.junit;bundle-version="4.0.0", @@ -13,9 +13,8 @@ Require-Bundle: org.junit;bundle-version="4.0.0", org.eclipse.core.resources, org.eclipse.tracecompass.tmf.core;bundle-version="3.1.0", org.eclipse.test.performance -Export-Package: org.eclipse.linuxtools.tmf.core.tests, - org.eclipse.linuxtools.tmf.core.tests.perf, - org.eclipse.linuxtools.tmf.core.tests.shared, - org.eclipse.linuxtools.tmf.tests.stubs.trace, - org.eclipse.linuxtools.tmf.tests.stubs.trace.xml +Export-Package: org.eclipse.tracecompass.tmf.core.tests, + org.eclipse.tracecompass.tmf.core.tests.perf, + org.eclipse.tracecompass.tmf.core.tests.shared, + org.eclipse.tracecompass.tmf.tests.stubs.trace Import-Package: com.google.common.collect diff --git a/org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/linuxtools/tmf/core/tests/perf/AllPerfTests.java b/org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/linuxtools/tmf/core/tests/perf/AllPerfTests.java deleted file mode 100644 index f1d50f1389..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/linuxtools/tmf/core/tests/perf/AllPerfTests.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.perf; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * The class AllPerformanceTests builds a suite that can be used to - * run all of the performance tests within its package as well as within any - * subpackages of its package. - * - * @author Geneviève Bastien - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - org.eclipse.linuxtools.tmf.core.tests.perf.synchronization.AllPerfTests.class -}) -public class AllPerfTests { - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/linuxtools/tmf/core/tests/perf/synchronization/AllPerfTests.java b/org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/linuxtools/tmf/core/tests/perf/synchronization/AllPerfTests.java deleted file mode 100644 index 3d9971f6b6..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/linuxtools/tmf/core/tests/perf/synchronization/AllPerfTests.java +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.perf.synchronization; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Performance tests for the synchronization classes - * - * @author Geneviève Bastien - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TimestampTransformBenchmark.class -}) -public class AllPerfTests { - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/linuxtools/tmf/core/tests/perf/synchronization/TimestampTransformBenchmark.java b/org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/linuxtools/tmf/core/tests/perf/synchronization/TimestampTransformBenchmark.java deleted file mode 100644 index d3dc0677fe..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/linuxtools/tmf/core/tests/perf/synchronization/TimestampTransformBenchmark.java +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francis Giraldeau - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.perf.synchronization; - -import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform; -import org.eclipse.linuxtools.tmf.core.synchronization.TimestampTransformFactory; -import org.eclipse.test.performance.Dimension; -import org.eclipse.test.performance.Performance; -import org.eclipse.test.performance.PerformanceMeter; -import org.junit.Test; - -/** - * Test the performance of linear transforms classes - * - * @author Francis Giraldeau - */ -public class TimestampTransformBenchmark { - - private static final String TEST_ID = "org.eclipse.linuxtools#Trace synchronization#"; - private static final String TEST_SUMMARY = "Timestamp Transform: "; - - /** Number of transformations done for each transform: 50 millions */ - private static final long NB_TRANSFORMATIONS = 50000000L; - - /** - * Test the timestamp transform performances - */ - @Test - public void testTimestampTransformPerformance() { - ITmfTimestampTransform transform = TimestampTransformFactory.getDefaultTransform(); - doTimestampTransformRun("Identity transform", transform, 10); - - transform = TimestampTransformFactory.createWithOffset(123456789); - doTimestampTransformRun("Transform with offset", transform, 10); - - transform = TimestampTransformFactory.createLinear(Math.PI, 1234); - doTimestampTransformRun("Linear transform", transform, 5); - - transform = TimestampTransformFactory.createLinear(10000.1234545565635, -4312278758437L); - doTimestampTransformRun("Linear transform with larger slope and negative offset", transform, 5); - } - - private static void doTimestampTransformRun(String testName, ITmfTimestampTransform xform, long loopCount) { - Performance perf = Performance.getDefault(); - PerformanceMeter pm = perf.createPerformanceMeter(TEST_ID + testName); - perf.tagAsSummary(pm, TEST_SUMMARY + testName, Dimension.CPU_TIME); - - for (int x = 0; x < loopCount; x++) { - /** - * We use timestamps with values in the order of 10^18, which about - * corresponds to timestamps in nanoseconds since epoch - */ - long time = (long) Math.pow(10, 18); - pm.start(); - /** - * Apply the timestamp transform NB_TRANSFORMATIONS times, with - * timestamps incremented by 200 each time - */ - for (long i = 0; i < NB_TRANSFORMATIONS; i++) { - xform.transform(time); - time += 200; - } - pm.stop(); - } - pm.commit(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/tracecompass/tmf/core/tests/perf/AllPerfTests.java b/org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/tracecompass/tmf/core/tests/perf/AllPerfTests.java new file mode 100644 index 0000000000..62c8e57967 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/tracecompass/tmf/core/tests/perf/AllPerfTests.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.perf; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * The class AllPerformanceTests builds a suite that can be used to + * run all of the performance tests within its package as well as within any + * subpackages of its package. + * + * @author Geneviève Bastien + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + org.eclipse.tracecompass.tmf.core.tests.perf.synchronization.AllPerfTests.class +}) +public class AllPerfTests { + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/tracecompass/tmf/core/tests/perf/synchronization/AllPerfTests.java b/org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/tracecompass/tmf/core/tests/perf/synchronization/AllPerfTests.java new file mode 100644 index 0000000000..4532360872 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/tracecompass/tmf/core/tests/perf/synchronization/AllPerfTests.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.perf.synchronization; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Performance tests for the synchronization classes + * + * @author Geneviève Bastien + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TimestampTransformBenchmark.class +}) +public class AllPerfTests { + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/tracecompass/tmf/core/tests/perf/synchronization/TimestampTransformBenchmark.java b/org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/tracecompass/tmf/core/tests/perf/synchronization/TimestampTransformBenchmark.java new file mode 100644 index 0000000000..4f81e6447d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/perf/org/eclipse/tracecompass/tmf/core/tests/perf/synchronization/TimestampTransformBenchmark.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francis Giraldeau - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.perf.synchronization; + +import org.eclipse.test.performance.Dimension; +import org.eclipse.test.performance.Performance; +import org.eclipse.test.performance.PerformanceMeter; +import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform; +import org.eclipse.tracecompass.tmf.core.synchronization.TimestampTransformFactory; +import org.junit.Test; + +/** + * Test the performance of linear transforms classes + * + * @author Francis Giraldeau + */ +public class TimestampTransformBenchmark { + + private static final String TEST_ID = "org.eclipse.linuxtools#Trace synchronization#"; + private static final String TEST_SUMMARY = "Timestamp Transform: "; + + /** Number of transformations done for each transform: 50 millions */ + private static final long NB_TRANSFORMATIONS = 50000000L; + + /** + * Test the timestamp transform performances + */ + @Test + public void testTimestampTransformPerformance() { + ITmfTimestampTransform transform = TimestampTransformFactory.getDefaultTransform(); + doTimestampTransformRun("Identity transform", transform, 10); + + transform = TimestampTransformFactory.createWithOffset(123456789); + doTimestampTransformRun("Transform with offset", transform, 10); + + transform = TimestampTransformFactory.createLinear(Math.PI, 1234); + doTimestampTransformRun("Linear transform", transform, 5); + + transform = TimestampTransformFactory.createLinear(10000.1234545565635, -4312278758437L); + doTimestampTransformRun("Linear transform with larger slope and negative offset", transform, 5); + } + + private static void doTimestampTransformRun(String testName, ITmfTimestampTransform xform, long loopCount) { + Performance perf = Performance.getDefault(); + PerformanceMeter pm = perf.createPerformanceMeter(TEST_ID + testName); + perf.tagAsSummary(pm, TEST_SUMMARY + testName, Dimension.CPU_TIME); + + for (int x = 0; x < loopCount; x++) { + /** + * We use timestamps with values in the order of 10^18, which about + * corresponds to timestamps in nanoseconds since epoch + */ + long time = (long) Math.pow(10, 18); + pm.start(); + /** + * Apply the timestamp transform NB_TRANSFORMATIONS times, with + * timestamps incremented by 200 each time + */ + for (long i = 0; i < NB_TRANSFORMATIONS; i++) { + xform.transform(time); + time += 200; + } + pm.stop(); + } + pm.commit(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/plugin.xml b/org.eclipse.tracecompass.tmf.core.tests/plugin.xml index 74c3626fac..029ea81a94 100644 --- a/org.eclipse.tracecompass.tmf.core.tests/plugin.xml +++ b/org.eclipse.tracecompass.tmf.core.tests/plugin.xml @@ -6,69 +6,69 @@ + analysis_module="org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestAnalysis"> + class="org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub"> + class="org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub3"> + class="org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub"> + class="org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub3"> + class="org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub2"> + class="org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub"> + class="org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfExperimentStub"> + class="org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub"> @@ -80,30 +80,30 @@ + trace_type="org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub"> + trace_type="org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub2"> + trace_type="org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub3"> + experiment_type="org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfExperimentStub"> ${tycho-version} org.eclipse.tracecompass.tmf.core.tests - org.eclipse.linuxtools.tmf.core.tests.AllTmfCoreTests + org.eclipse.tracecompass.tmf.core.tests.AllTmfCoreTests false false org.eclipse.platform.ide diff --git a/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/DebugListener.java b/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/DebugListener.java deleted file mode 100644 index f53c6c4087..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/DebugListener.java +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.shared; - -import org.junit.runner.Description; -import org.junit.runner.notification.Failure; -import org.junit.runner.notification.RunListener; - -/** - * Debugging RunListener, which will print to stdout the name of the tests being - * run. - * - * @author Alexandre Montplaisir - */ -public class DebugListener extends RunListener { - - @Override - public void testStarted(Description description) { - System.out.println("Running " + getTestName(description)); - } - - @Override - public void testAssumptionFailure(Failure failure) { - System.out.println("SKIPPING TEST: " + getTestName(failure.getDescription())); - System.out.println(failure.getMessage()); - } - - /** - * Get the className#methodName from a Description. - */ - private static String getTestName(Description description) { - return description.getClassName() + '#' + description.getMethodName(); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/DebugSuite.java b/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/DebugSuite.java deleted file mode 100644 index 684aa60024..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/DebugSuite.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.shared; - -import org.junit.runner.notification.RunNotifier; -import org.junit.runners.Suite; -import org.junit.runners.model.InitializationError; - -/** - * Test suite that adds a {@link DebugListener} to unit tests, to help debug - * misbehaving tests. - * - * Use with @RunWith(DebugSuite) and DebugSuite.SuiteClasses({ }) - * - * @author Alexandre Montplaisir - */ -public class DebugSuite extends Suite { - - /** - * Constructor (required by JUnit) - * - * @param klass - * Root of the suite - * @throws InitializationError - * If an error happened when getting the test classes - */ - public DebugSuite(Class klass) throws InitializationError { - super(klass, getAnnotatedClasses(klass)); - } - - @Override - public void run(RunNotifier runNotifier) { - runNotifier.addListener(new DebugListener()); - super.run(runNotifier); - } - - private static Class[] getAnnotatedClasses(Class klass) throws InitializationError { - SuiteClasses annotation = klass.getAnnotation(SuiteClasses.class); - if (annotation == null) { - throw new InitializationError(String.format("class '%s' must have a SuiteClasses annotation", klass.getName())); - } - return annotation.value(); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/TmfTestHelper.java b/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/TmfTestHelper.java deleted file mode 100644 index b7cbc542ed..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/TmfTestHelper.java +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.shared; - -import static org.junit.Assert.fail; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAbstractAnalysisModule; - -/** - * This class contains code for some common use cases of things that would be - * illegal to do in normal code, but are useful if not necessary in unit tests, - * like executing protected methods, using reflection. - * - * It may also serve as example for developers who want to do similar things in - * less common use cases. - * - * @author Geneviève Bastien - */ -public class TmfTestHelper { - - /** - * Calls the {@link TmfAbstractAnalysisModule#executeAnalysis} method of an - * analysis module. This method does not return until the analysis is - * completed and it returns the result of the method. It allows to execute - * the analysis without requiring an Eclipse job and waiting for completion. - * - * @param module - * The analysis module to execute - * @return The return value of the - * {@link TmfAbstractAnalysisModule#executeAnalysis} method - */ - public static boolean executeAnalysis(IAnalysisModule module) { - if (module instanceof TmfAbstractAnalysisModule) { - try { - Class[] argTypes = new Class[] { IProgressMonitor.class }; - Method method = TmfAbstractAnalysisModule.class.getDeclaredMethod("executeAnalysis", argTypes); - method.setAccessible(true); - Object obj = method.invoke(module, new NullProgressMonitor()); - return (Boolean) obj; - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { - fail(e.toString()); - } - } - throw new RuntimeException("This analysis module does not have a protected method to execute. Maybe it can be executed differently? Or it is not supported yet in this method?"); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/TmfTestTrace.java b/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/TmfTestTrace.java deleted file mode 100644 index f689c841c3..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/TmfTestTrace.java +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.shared; - -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.tests.TmfCoreTestPlugin; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub2; - -/** - * Generic TMF test traces - * - * @author Geneviève Bastien - */ -public enum TmfTestTrace { - /** A test */ - A_TEST_10K("A-Test-10K"), - /** A second trace */ - A_TEST_10K2("A-Test-10K-2"), - /** A third trace */ - E_TEST_10K("E-Test-10K"), - /** A fourth trace */ - O_TEST_10K("O-Test-10K"), - /** And oh! a fifth trace */ - R_TEST_10K("R-Test-10K"); - - private final String fPath; - private final String fDirectory = "../org.eclipse.tracecompass.tmf.core.tests/testfiles"; - private ITmfTrace fTrace = null; - - private TmfTestTrace(String file) { - fPath = file; - } - - /** - * Get the path of the trace - * - * @return The path of this trace - */ - public String getPath() { - return fPath; - } - - /** - * Get the full path of the trace - * - * @return The full path of the trace - */ - public String getFullPath() { - return fDirectory + File.separator + fPath; - } - - /** - * Return a ITmfTrace object of this test trace. It will be already - * initTrace()'ed. This method will always return a new trace and dispose of - * the old one. - * - * After being used by unit tests, traces must be properly disposed of by - * calling the {@link TmfTestTrace#dispose()} method. - * - * @return A {@link ITmfTrace} reference to this trace - */ - public ITmfTrace getTrace() { - if (fTrace != null) { - fTrace.dispose(); - } - final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(fDirectory + File.separator + fPath), null); - try { - File test = new File(FileLocator.toFileURL(location).toURI()); - fTrace = new TmfTraceStub(test.toURI().getPath(), ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, false, null); - - } catch (URISyntaxException | IOException | TmfTraceException e) { - throw new IllegalStateException(e); - } - return fTrace; - } - - /** - * Return a ITmfTrace object that is of type {@link TmfTraceStub2}. It - * will be already initTrace()'ed. But the trace will be deregistered from - * signal managers and will need to be manually disposed of by the caller. - * - * @return a {@link ITmfTrace} reference to this trace - */ - public ITmfTrace getTraceAsStub2() { - ITmfTrace trace = null; - final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(fDirectory + File.separator + fPath), null); - try { - File test = new File(FileLocator.toFileURL(location).toURI()); - trace = new TmfTraceStub2(test.toURI().getPath(), ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, false, null); - TmfSignalManager.deregister(trace); - - } catch (URISyntaxException | IOException | TmfTraceException e) { - throw new IllegalStateException(e); - } - return trace; - } - - /** - * Dispose of the trace - */ - public void dispose() { - if (fTrace != null) { - fTrace.dispose(); - fTrace = null; - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/tracecompass/tmf/core/tests/shared/DebugListener.java b/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/tracecompass/tmf/core/tests/shared/DebugListener.java new file mode 100644 index 0000000000..b0bab47be8 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/tracecompass/tmf/core/tests/shared/DebugListener.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.shared; + +import org.junit.runner.Description; +import org.junit.runner.notification.Failure; +import org.junit.runner.notification.RunListener; + +/** + * Debugging RunListener, which will print to stdout the name of the tests being + * run. + * + * @author Alexandre Montplaisir + */ +public class DebugListener extends RunListener { + + @Override + public void testStarted(Description description) { + System.out.println("Running " + getTestName(description)); + } + + @Override + public void testAssumptionFailure(Failure failure) { + System.out.println("SKIPPING TEST: " + getTestName(failure.getDescription())); + System.out.println(failure.getMessage()); + } + + /** + * Get the className#methodName from a Description. + */ + private static String getTestName(Description description) { + return description.getClassName() + '#' + description.getMethodName(); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/tracecompass/tmf/core/tests/shared/DebugSuite.java b/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/tracecompass/tmf/core/tests/shared/DebugSuite.java new file mode 100644 index 0000000000..5686f8fdbe --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/tracecompass/tmf/core/tests/shared/DebugSuite.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.shared; + +import org.junit.runner.notification.RunNotifier; +import org.junit.runners.Suite; +import org.junit.runners.model.InitializationError; + +/** + * Test suite that adds a {@link DebugListener} to unit tests, to help debug + * misbehaving tests. + * + * Use with @RunWith(DebugSuite) and DebugSuite.SuiteClasses({ }) + * + * @author Alexandre Montplaisir + */ +public class DebugSuite extends Suite { + + /** + * Constructor (required by JUnit) + * + * @param klass + * Root of the suite + * @throws InitializationError + * If an error happened when getting the test classes + */ + public DebugSuite(Class klass) throws InitializationError { + super(klass, getAnnotatedClasses(klass)); + } + + @Override + public void run(RunNotifier runNotifier) { + runNotifier.addListener(new DebugListener()); + super.run(runNotifier); + } + + private static Class[] getAnnotatedClasses(Class klass) throws InitializationError { + SuiteClasses annotation = klass.getAnnotation(SuiteClasses.class); + if (annotation == null) { + throw new InitializationError(String.format("class '%s' must have a SuiteClasses annotation", klass.getName())); + } + return annotation.value(); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/tracecompass/tmf/core/tests/shared/TmfTestHelper.java b/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/tracecompass/tmf/core/tests/shared/TmfTestHelper.java new file mode 100644 index 0000000000..c9ede44f74 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/tracecompass/tmf/core/tests/shared/TmfTestHelper.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.shared; + +import static org.junit.Assert.fail; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule; + +/** + * This class contains code for some common use cases of things that would be + * illegal to do in normal code, but are useful if not necessary in unit tests, + * like executing protected methods, using reflection. + * + * It may also serve as example for developers who want to do similar things in + * less common use cases. + * + * @author Geneviève Bastien + */ +public class TmfTestHelper { + + /** + * Calls the {@link TmfAbstractAnalysisModule#executeAnalysis} method of an + * analysis module. This method does not return until the analysis is + * completed and it returns the result of the method. It allows to execute + * the analysis without requiring an Eclipse job and waiting for completion. + * + * @param module + * The analysis module to execute + * @return The return value of the + * {@link TmfAbstractAnalysisModule#executeAnalysis} method + */ + public static boolean executeAnalysis(IAnalysisModule module) { + if (module instanceof TmfAbstractAnalysisModule) { + try { + Class[] argTypes = new Class[] { IProgressMonitor.class }; + Method method = TmfAbstractAnalysisModule.class.getDeclaredMethod("executeAnalysis", argTypes); + method.setAccessible(true); + Object obj = method.invoke(module, new NullProgressMonitor()); + return (Boolean) obj; + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { + fail(e.toString()); + } + } + throw new RuntimeException("This analysis module does not have a protected method to execute. Maybe it can be executed differently? Or it is not supported yet in this method?"); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/tracecompass/tmf/core/tests/shared/TmfTestTrace.java b/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/tracecompass/tmf/core/tests/shared/TmfTestTrace.java new file mode 100644 index 0000000000..0b445e49a2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/shared/org/eclipse/tracecompass/tmf/core/tests/shared/TmfTestTrace.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.shared; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.tests.TmfCoreTestPlugin; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub2; + +/** + * Generic TMF test traces + * + * @author Geneviève Bastien + */ +public enum TmfTestTrace { + /** A test */ + A_TEST_10K("A-Test-10K"), + /** A second trace */ + A_TEST_10K2("A-Test-10K-2"), + /** A third trace */ + E_TEST_10K("E-Test-10K"), + /** A fourth trace */ + O_TEST_10K("O-Test-10K"), + /** And oh! a fifth trace */ + R_TEST_10K("R-Test-10K"); + + private final String fPath; + private final String fDirectory = "../org.eclipse.tracecompass.tmf.core.tests/testfiles"; + private ITmfTrace fTrace = null; + + private TmfTestTrace(String file) { + fPath = file; + } + + /** + * Get the path of the trace + * + * @return The path of this trace + */ + public String getPath() { + return fPath; + } + + /** + * Get the full path of the trace + * + * @return The full path of the trace + */ + public String getFullPath() { + return fDirectory + File.separator + fPath; + } + + /** + * Return a ITmfTrace object of this test trace. It will be already + * initTrace()'ed. This method will always return a new trace and dispose of + * the old one. + * + * After being used by unit tests, traces must be properly disposed of by + * calling the {@link TmfTestTrace#dispose()} method. + * + * @return A {@link ITmfTrace} reference to this trace + */ + public ITmfTrace getTrace() { + if (fTrace != null) { + fTrace.dispose(); + } + final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(fDirectory + File.separator + fPath), null); + try { + File test = new File(FileLocator.toFileURL(location).toURI()); + fTrace = new TmfTraceStub(test.toURI().getPath(), ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, false, null); + + } catch (URISyntaxException | IOException | TmfTraceException e) { + throw new IllegalStateException(e); + } + return fTrace; + } + + /** + * Return a ITmfTrace object that is of type {@link TmfTraceStub2}. It + * will be already initTrace()'ed. But the trace will be deregistered from + * signal managers and will need to be manually disposed of by the caller. + * + * @return a {@link ITmfTrace} reference to this trace + */ + public ITmfTrace getTraceAsStub2() { + ITmfTrace trace = null; + final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(fDirectory + File.separator + fPath), null); + try { + File test = new File(FileLocator.toFileURL(location).toURI()); + trace = new TmfTraceStub2(test.toURI().getPath(), ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, false, null); + TmfSignalManager.deregister(trace); + + } catch (URISyntaxException | IOException | TmfTraceException e) { + throw new IllegalStateException(e); + } + return trace; + } + + /** + * Dispose of the trace + */ + public void dispose() { + if (fTrace != null) { + fTrace.dispose(); + fTrace = null; + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/AllTmfCoreTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/AllTmfCoreTests.java deleted file mode 100644 index 691ac6022e..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/AllTmfCoreTests.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4, enable CTF and statistics tests - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Master test suite for TMF Core. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TmfCorePluginTest.class, - org.eclipse.linuxtools.tmf.core.tests.analysis.AllTests.class, - org.eclipse.linuxtools.tmf.core.tests.component.AllTests.class, - org.eclipse.linuxtools.tmf.core.tests.event.AllTests.class, - org.eclipse.linuxtools.tmf.core.tests.event.lookup.AllTests.class, - org.eclipse.linuxtools.tmf.core.tests.filter.AllTests.class, - org.eclipse.linuxtools.tmf.core.tests.request.AllTests.class, - org.eclipse.linuxtools.tmf.core.tests.signal.AllTests.class, - org.eclipse.linuxtools.tmf.core.tests.statesystem.AllTests.class, - org.eclipse.linuxtools.tmf.core.tests.statesystem.mipmap.AllTests.class, - org.eclipse.linuxtools.tmf.core.tests.synchronization.AllTests.class, - org.eclipse.linuxtools.tmf.core.tests.trace.AllTests.class, - org.eclipse.linuxtools.tmf.core.tests.trace.indexer.AllTests.class, - org.eclipse.linuxtools.tmf.core.tests.trace.indexer.checkpoint.AllTests.class, - org.eclipse.linuxtools.tmf.core.tests.trace.location.AllTests.class, - org.eclipse.linuxtools.tmf.core.tests.trace.stub.AllTests.class, - org.eclipse.linuxtools.tmf.core.tests.trace.text.AllTests.class, - org.eclipse.linuxtools.tmf.core.tests.uml2sd.AllTests.class, - org.eclipse.linuxtools.tmf.core.tests.util.AllTests.class -}) -public class AllTmfCoreTests { - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/TmfCorePluginTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/TmfCorePluginTest.java deleted file mode 100644 index 7dae1e770d..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/TmfCorePluginTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests; - -import static org.junit.Assert.assertEquals; - -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.junit.Test; - -/** - * Test the TMF core plug-in activator - */ -public class TmfCorePluginTest { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // Plug-in instantiation - static final Activator fPlugin = new Activator(); - - // ------------------------------------------------------------------------ - // Test cases - // ------------------------------------------------------------------------ - - /** - * Test the plugin ID. - */ - @Test - public void testTmfCorePluginId() { - assertEquals("Plugin ID", "org.eclipse.tracecompass.tmf.core", Activator.PLUGIN_ID); - } - - /** - * Test the getDefault() static method. - */ - @Test - public void testGetDefault() { - Activator plugin = Activator.getDefault(); - assertEquals("getDefault()", plugin, fPlugin); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/TmfCoreTestPlugin.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/TmfCoreTestPlugin.java deleted file mode 100644 index efe20ad184..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/TmfCoreTestPlugin.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests; - -import org.eclipse.core.runtime.Plugin; -import org.eclipse.linuxtools.internal.tmf.core.TmfCoreTracer; -import org.osgi.framework.BundleContext; - -/** - * TmfTestPlugin - *

- * The activator class controls the plug-in life cycle - */ -public class TmfCoreTestPlugin extends Plugin { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // The plug-in ID - @SuppressWarnings("javadoc") - public static final String PLUGIN_ID = "org.eclipse.tracecompass.tmf.tests"; - - // The shared instance - private static TmfCoreTestPlugin fPlugin; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * The constructor - */ - public TmfCoreTestPlugin() { - setDefault(this); - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * @return the shared instance - */ - public static TmfCoreTestPlugin getDefault() { - return fPlugin; - } - - /** - * @param plugin the shared instance - */ - private static void setDefault(TmfCoreTestPlugin plugin) { - fPlugin = plugin; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Override - public void start(BundleContext context) throws Exception { - super.start(context); - setDefault(this); - TmfCoreTracer.init(); - } - - @Override - public void stop(BundleContext context) throws Exception { - TmfCoreTracer.stop(); - setDefault(null); - super.stop(context); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AllTests.java deleted file mode 100644 index a97a023406..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AllTests.java +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.analysis; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Unit tests for the analysis package. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - AnalysisManagerTest.class, - AnalysisModuleTest.class, - AnalysisModuleHelperTest.class, - AnalysisParameterProviderTest.class, - AnalysisRequirementTest.class, - AnalysisRequirementHelperTest.class -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisManagerTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisManagerTest.java deleted file mode 100644 index da3af39495..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisManagerTest.java +++ /dev/null @@ -1,130 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.analysis; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.Map; - -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleSource; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.tests.stubs.analysis.AnalysisModuleSourceStub; -import org.eclipse.linuxtools.tmf.tests.stubs.analysis.AnalysisModuleTestHelper; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Test suite for the TmfAnalysisModule class - */ -public class AnalysisManagerTest { - - /** Id of analysis module with parameter */ - public static final String MODULE_PARAM = "org.eclipse.linuxtools.tmf.core.tests.analysis.test"; - /** ID of analysis module with parameter and default value */ - public static final String MODULE_PARAM_DEFAULT = "org.eclipse.linuxtools.tmf.core.tests.analysis.test2"; - /** ID of analysis module for trace 2 classes only */ - public static final String MODULE_SECOND = "org.eclipse.linuxtools.tmf.core.tests.analysis.testother"; - /** Id of analysis module with requirements */ - public static final String MODULE_REQ = "org.eclipse.linuxtools.tmf.core.tests.analysis.reqtest"; - - private ITmfTrace fTrace; - - /** - * Set up some trace code - */ - @Before - public void setupTraces() { - fTrace = TmfTestTrace.A_TEST_10K2.getTraceAsStub2(); - } - - /** - * Some tests use traces, let's clean them here - */ - @After - public void cleanupTraces() { - TmfTestTrace.A_TEST_10K.dispose(); - fTrace.dispose(); - } - - /** - * Test suite for the {@link TmfAnalysisManager#getAnalysisModules()} method - */ - @Test - public void testGetAnalysisModules() { - Map modules = TmfAnalysisManager.getAnalysisModules(); - /* At least 3 modules should be found */ - assertTrue(modules.size() >= 3); - - IAnalysisModuleHelper module = modules.get(MODULE_PARAM_DEFAULT); - assertTrue(module.isAutomatic()); - - module = modules.get(MODULE_PARAM); - assertFalse(module.isAutomatic()); - } - - /** - * Test suite for {@link TmfAnalysisManager#getAnalysisModules(Class)} Use - * the test TMF trace and test trace2 stubs as sample traces - */ - @Test - public void testListForTraces() { - /* Generic TmfTrace */ - ITmfTrace trace = TmfTestTrace.A_TEST_10K.getTrace(); - Map map = TmfAnalysisManager.getAnalysisModules(trace.getClass()); - - assertTrue(map.containsKey(MODULE_PARAM)); - assertTrue(map.containsKey(MODULE_PARAM_DEFAULT)); - assertFalse(map.containsKey(MODULE_SECOND)); - - /* TmfTraceStub2 class */ - map = TmfAnalysisManager.getAnalysisModules(fTrace.getClass()); - - assertTrue(map.containsKey(MODULE_PARAM)); - assertTrue(map.containsKey(MODULE_PARAM_DEFAULT)); - assertTrue(map.containsKey(MODULE_SECOND)); - } - - /** - * Test suite to test refresh of analysis module when adding a {@link IAnalysisModuleSource} - */ - @Test - public void testSources() { - /* Make sure that modules in the new source are not in the list already */ - /* Generic TmfTrace */ - ITmfTrace trace = TmfTestTrace.A_TEST_10K.getTrace(); - Map map = TmfAnalysisManager.getAnalysisModules(trace.getClass()); - - assertFalse(map.containsKey(AnalysisModuleTestHelper.moduleStubEnum.TEST.name())); - - /* TmfTraceStub2 class */ - map = TmfAnalysisManager.getAnalysisModules(fTrace.getClass()); - - assertFalse(map.containsKey(AnalysisModuleTestHelper.moduleStubEnum.TEST2.name())); - - /* Add new source */ - TmfAnalysisManager.registerModuleSource(new AnalysisModuleSourceStub()); - - /* Now make sure the modules are present */ - map = TmfAnalysisManager.getAnalysisModules(trace.getClass()); - assertTrue(map.containsKey(AnalysisModuleTestHelper.moduleStubEnum.TEST.name())); - - map = TmfAnalysisManager.getAnalysisModules(fTrace.getClass()); - assertTrue(map.containsKey(AnalysisModuleTestHelper.moduleStubEnum.TEST2.name())); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisModuleHelperTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisModuleHelperTest.java deleted file mode 100644 index 8af608e60a..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisModuleHelperTest.java +++ /dev/null @@ -1,270 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - * Mathieu Rail - Added tests for getting a module's requirements - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.analysis; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.eclipse.core.runtime.Platform; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper; -import org.eclipse.linuxtools.tmf.core.analysis.Messages; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisModuleHelperConfigElement; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisRequirement; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTrace; -import org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestAnalysis; -import org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestAnalysis2; -import org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestRequirementAnalysis; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub2; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub3; -import org.eclipse.osgi.util.NLS; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.osgi.framework.Bundle; - -import com.google.common.collect.ImmutableSet; - -/** - * Test suite for the {@link TmfAnalysisModuleHelperConfigElement} class - * - * @author Geneviève Bastien - */ -public class AnalysisModuleHelperTest { - - private IAnalysisModuleHelper fModule; - private IAnalysisModuleHelper fModuleOther; - private IAnalysisModuleHelper fReqModule; - private ITmfTrace fTrace; - - /** - * Gets the module helpers for 2 test modules - */ - @Before - public void getModules() { - fModule = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_PARAM); - assertNotNull(fModule); - assertTrue(fModule instanceof TmfAnalysisModuleHelperConfigElement); - fModuleOther = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_SECOND); - assertNotNull(fModuleOther); - assertTrue(fModuleOther instanceof TmfAnalysisModuleHelperConfigElement); - fReqModule = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_REQ); - assertNotNull(fReqModule); - assertTrue(fReqModule instanceof TmfAnalysisModuleHelperConfigElement); - fTrace = TmfTestTrace.A_TEST_10K2.getTraceAsStub2(); - } - - /** - * Some tests use traces, let's clean them here - */ - @After - public void cleanupTraces() { - TmfTestTrace.A_TEST_10K.dispose(); - fTrace.dispose(); - } - - /** - * Test the helper's getters and setters - */ - @Test - public void testHelperGetters() { - /* With first module */ - assertEquals(AnalysisManagerTest.MODULE_PARAM, fModule.getId()); - assertEquals("Test analysis", fModule.getName()); - assertFalse(fModule.isAutomatic()); - - Bundle helperbundle = fModule.getBundle(); - Bundle thisbundle = Platform.getBundle("org.eclipse.tracecompass.tmf.core.tests"); - assertNotNull(helperbundle); - assertEquals(thisbundle, helperbundle); - - /* With other module */ - assertEquals(AnalysisManagerTest.MODULE_SECOND, fModuleOther.getId()); - assertEquals("Test other analysis", fModuleOther.getName()); - assertTrue(fModuleOther.isAutomatic()); - } - - /** - * Test the - * {@link TmfAnalysisModuleHelperConfigElement#appliesToTraceType(Class)} - * method for the 2 modules - */ - @Test - public void testAppliesToTrace() { - /* stub module */ - assertFalse(fModule.appliesToTraceType(TmfTrace.class)); - assertTrue(fModule.appliesToTraceType(TmfTraceStub.class)); - assertTrue(fModule.appliesToTraceType(TmfTraceStub2.class)); - assertFalse(fModule.appliesToTraceType(TmfTraceStub3.class)); - - /* stub module 2 */ - assertFalse(fModuleOther.appliesToTraceType(TmfTrace.class)); - assertFalse(fModuleOther.appliesToTraceType(TmfTraceStub.class)); - assertTrue(fModuleOther.appliesToTraceType(TmfTraceStub2.class)); - assertTrue(fModuleOther.appliesToTraceType(TmfTraceStub3.class)); - } - - /** - * Test the - * {@link TmfAnalysisModuleHelperConfigElement#newModule(ITmfTrace)} method - * for the 2 modules - */ - @Test - public void testNewModule() { - /* Test analysis module with traceStub */ - Exception exception = null; - try (IAnalysisModule module = fModule.newModule(TmfTestTrace.A_TEST_10K.getTrace());) { - assertNotNull(module); - assertTrue(module instanceof TestAnalysis); - } catch (TmfAnalysisException e) { - exception = e; - } - assertNull(exception); - - /* TestAnalysis2 module with trace, should return an exception */ - try (IAnalysisModule module = fModuleOther.newModule(TmfTestTrace.A_TEST_10K.getTrace());) { - } catch (TmfAnalysisException e) { - exception = e; - } - assertNotNull(exception); - assertEquals(NLS.bind(Messages.TmfAnalysisModuleHelper_AnalysisDoesNotApply, fModuleOther.getName()), exception.getMessage()); - - /* TestAnalysis2 module with a TraceStub2 */ - exception = null; - try (IAnalysisModule module = fModuleOther.newModule(fTrace);) { - assertNotNull(module); - assertTrue(module instanceof TestAnalysis2); - } catch (TmfAnalysisException e) { - exception = e; - } - assertNull(exception); - } - - /** - * Test for the initialization of parameters from the extension points - */ - @Test - public void testParameters() { - ITmfTrace trace = TmfTestTrace.A_TEST_10K.getTrace(); - - /* - * This analysis has a parameter, but no default value. we should be - * able to set the parameter - */ - IAnalysisModuleHelper helper = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_PARAM); - try (IAnalysisModule module = helper.newModule(trace);) { - assertNull(module.getParameter(TestAnalysis.PARAM_TEST)); - module.setParameter(TestAnalysis.PARAM_TEST, 1); - assertEquals(1, module.getParameter(TestAnalysis.PARAM_TEST)); - - } catch (TmfAnalysisException e1) { - fail(e1.getMessage()); - return; - } - - /* This module has a parameter with default value */ - helper = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_PARAM_DEFAULT); - try (IAnalysisModule module = helper.newModule(trace);) { - assertEquals(3, module.getParameter(TestAnalysis.PARAM_TEST)); - module.setParameter(TestAnalysis.PARAM_TEST, 1); - assertEquals(1, module.getParameter(TestAnalysis.PARAM_TEST)); - - } catch (TmfAnalysisException e1) { - fail(e1.getMessage()); - return; - } - - /* - * This module does not have a parameter so setting it should throw an - * error - */ - helper = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_SECOND); - Exception exception = null; - try (IAnalysisModule module = helper.newModule(fTrace);) { - - assertNull(module.getParameter(TestAnalysis.PARAM_TEST)); - - try { - module.setParameter(TestAnalysis.PARAM_TEST, 1); - } catch (RuntimeException e) { - exception = e; - } - } catch (TmfAnalysisException e1) { - fail(e1.getMessage()); - return; - } - assertNotNull(exception); - } - - /** - * Test for the - * {@link TmfAnalysisModuleHelperConfigElement#getValidTraceTypes} method - */ - @Test - public void testGetValidTraceTypes() { - Set> expected = ImmutableSet.of((Class) TmfTraceStub.class, TmfTraceStub2.class, TmfTraceStub3.class); - Iterable> traceTypes = fReqModule.getValidTraceTypes(); - assertEquals(expected, traceTypes); - } - - /** - * Test for the - * {@link TmfAnalysisModuleHelperConfigElement#getAnalysisRequirements} - * method - */ - @Test - public void testGetRequirements() { - Iterable requirements = fReqModule.getAnalysisRequirements(); - assertNotNull(requirements); - - Map rMap = new HashMap<>(); - - for (TmfAnalysisRequirement req : requirements) { - assertFalse(rMap.containsKey(req.getType())); - rMap.put(req.getType(), req); - } - assertEquals(2, rMap.size()); - - /* Test if all types and values have been obtained */ - TmfAnalysisRequirement req = rMap.get(TestRequirementAnalysis.EVENT_TYPE); - assertNotNull(req); - - Set values = req.getValues(); - assertEquals(3, values.size()); - assertTrue(values.contains(TestRequirementAnalysis.EXIT_SYSCALL)); - assertTrue(values.contains(TestRequirementAnalysis.SCHED_SWITCH)); - assertTrue(values.contains(TestRequirementAnalysis.SCHED_WAKEUP)); - - req = rMap.get(TestRequirementAnalysis.FIELD_TYPE); - assertNotNull(req); - - values = req.getValues(); - assertEquals(2, values.size()); - assertTrue(values.contains(TestRequirementAnalysis.PID)); - assertTrue(values.contains(TestRequirementAnalysis.TID)); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisModuleTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisModuleTest.java deleted file mode 100644 index fbeac78c63..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisModuleTest.java +++ /dev/null @@ -1,257 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.analysis; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule; -import org.eclipse.linuxtools.tmf.core.analysis.Messages; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAbstractAnalysisModule; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestHelper; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestAnalysis; -import org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestAnalysis2; -import org.eclipse.osgi.util.NLS; -import org.junit.After; -import org.junit.Test; - -/** - * Test suite for the {@link TmfAbstractAnalysisModule} class - */ -public class AnalysisModuleTest { - - private static String MODULE_GENERIC_ID = "test.id"; - private static String MODULE_GENERIC_NAME = "Test analysis"; - - /** - * Some tests use traces, let's clean them here - */ - @After - public void cleanupTraces() { - TmfTestTrace.A_TEST_10K.dispose(); - } - - /** - * Test suite for analysis module getters and setters - */ - @Test - public void testGettersSetters() { - try (IAnalysisModule module = new TestAnalysis();) { - - module.setName(MODULE_GENERIC_NAME); - module.setId(MODULE_GENERIC_ID); - assertEquals(MODULE_GENERIC_ID, module.getId()); - assertEquals(MODULE_GENERIC_NAME, module.getName()); - - module.setAutomatic(false); - assertFalse(module.isAutomatic()); - module.setAutomatic(true); - assertTrue(module.isAutomatic()); - module.addParameter(TestAnalysis.PARAM_TEST); - assertNull(module.getParameter(TestAnalysis.PARAM_TEST)); - module.setParameter(TestAnalysis.PARAM_TEST, 1); - assertEquals(1, module.getParameter(TestAnalysis.PARAM_TEST)); - - /* Try to set and get wrong parameter */ - String wrongParam = "abc"; - Exception exception = null; - try { - module.setParameter(wrongParam, 1); - } catch (RuntimeException e) { - exception = e; - assertEquals(NLS.bind(Messages.TmfAbstractAnalysisModule_InvalidParameter, wrongParam, module.getName()), e.getMessage()); - } - assertNotNull(exception); - assertNull(module.getParameter(wrongParam)); - } - } - - private static TestAnalysis setUpAnalysis() { - TestAnalysis module = new TestAnalysis(); - - module.setName(MODULE_GENERIC_NAME); - module.setId(MODULE_GENERIC_ID); - module.addParameter(TestAnalysis.PARAM_TEST); - - return module; - } - - /** - * Test suite for analysis module - * {@link TmfAbstractAnalysisModule#waitForCompletion} with successful - * execution - */ - @Test - public void testWaitForCompletionSuccess() { - try (TestAnalysis module = setUpAnalysis();) { - - IStatus status = module.schedule(); - assertEquals(IStatus.ERROR, status.getSeverity()); - - /* Set a stub trace for analysis */ - try { - module.setTrace(TmfTestTrace.A_TEST_10K.getTrace()); - } catch (TmfAnalysisException e) { - fail(e.getMessage()); - } - - /* Default execution, with output 1 */ - module.setParameter(TestAnalysis.PARAM_TEST, 1); - status = module.schedule(); - assertEquals(Status.OK_STATUS, status); - boolean completed = module.waitForCompletion(); - - assertTrue(completed); - assertEquals(1, module.getAnalysisOutput()); - } - } - - /** - * Test suite for {@link TmfAbstractAnalysisModule#waitForCompletion} with cancellation - */ - @Test - public void testWaitForCompletionCancelled() { - try (TestAnalysis module = setUpAnalysis();) { - - /* Set a stub trace for analysis */ - ITmfTrace trace = TmfTestTrace.A_TEST_10K.getTrace(); - try { - module.setTrace(trace); - } catch (TmfAnalysisException e) { - fail(e.getMessage()); - } - - module.setParameter(TestAnalysis.PARAM_TEST, 0); - IStatus status = module.schedule(); - assertEquals(Status.OK_STATUS, status); - boolean completed = module.waitForCompletion(); - - assertFalse(completed); - assertEquals(0, module.getAnalysisOutput()); - } - } - - /** - * Test the {@link TmfAbstractAnalysisModule#setTrace(ITmfTrace)} method with wrong trace - */ - @Test - public void testSetWrongTrace() { - try (IAnalysisModule module = new TestAnalysis2();) { - - module.setName(MODULE_GENERIC_NAME); - module.setId(MODULE_GENERIC_ID); - assertEquals(MODULE_GENERIC_ID, module.getId()); - assertEquals(MODULE_GENERIC_NAME, module.getName()); - - Exception exception = null; - try { - module.setTrace(TmfTestTrace.A_TEST_10K.getTrace()); - } catch (TmfAnalysisException e) { - exception = e; - } - assertNotNull(exception); - assertEquals(NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisCannotExecute, module.getName()), exception.getMessage()); - } - } - - /** - * Test suite for the {@link TmfAbstractAnalysisModule#cancel()} method - */ - @Test - public void testCancel() { - try (TestAnalysis module = setUpAnalysis();) { - - module.setParameter(TestAnalysis.PARAM_TEST, 999); - try { - module.setTrace(TmfTestTrace.A_TEST_10K.getTrace()); - } catch (TmfAnalysisException e) { - fail(e.getMessage()); - } - - assertEquals(Status.OK_STATUS, module.schedule()); - - /* Give the job a chance to start */ - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - fail(e.getMessage()); - } - - module.cancel(); - assertFalse(module.waitForCompletion()); - assertEquals(-1, module.getAnalysisOutput()); - } - } - - /** - * Test suite for the {@link IAnalysisModule#notifyParameterChanged(String)} - * method - */ - @Test - public void testParameterChanged() { - try (TestAnalysis module = setUpAnalysis();) { - - try { - module.setTrace(TmfTestTrace.A_TEST_10K.getTrace()); - } catch (TmfAnalysisException e) { - fail(e.getMessage()); - } - - /* Check exception if no wrong parameter name */ - Exception exception = null; - try { - module.notifyParameterChanged("aaa"); - } catch (RuntimeException e) { - exception = e; - } - assertNotNull(exception); - - /* - * Cannot test anymore of this method, need a parameter provider to - * do this - */ - } - } - - /** - * Test the {@link TmfTestHelper#executeAnalysis(IAnalysisModule)} method - */ - @Test - public void testHelper() { - try (TestAnalysis module = setUpAnalysis();) { - - try { - module.setTrace(TmfTestTrace.A_TEST_10K.getTrace()); - } catch (TmfAnalysisException e) { - fail(e.getMessage()); - } - - module.setParameter(TestAnalysis.PARAM_TEST, 1); - boolean res = TmfTestHelper.executeAnalysis(module); - assertTrue(res); - - module.setParameter(TestAnalysis.PARAM_TEST, 0); - res = TmfTestHelper.executeAnalysis(module); - assertFalse(res); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisParameterProviderTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisParameterProviderTest.java deleted file mode 100644 index 51e6c15e49..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisParameterProviderTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.analysis; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisParameterProvider; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestAnalysis; -import org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestAnalysisParameterProvider; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Test the TmfAbstractParameterProvider class - * - * @author Geneviève Bastien - */ -public class AnalysisParameterProviderTest { - - /** - * Registers the parameter provider - */ - @Before - public void setup() { - TmfAnalysisManager.registerParameterProvider(AnalysisManagerTest.MODULE_PARAM, TestAnalysisParameterProvider.class); - } - - /** - * Cleanup the trace after testing - */ - @After - public void cleanupTrace() { - TmfTestTrace.A_TEST_10K.dispose(); - } - - /** - * Test that the provider's value is used - */ - @Test - public void testProviderTmfTrace() { - ITmfTrace trace = TmfTestTrace.A_TEST_10K.getTrace(); - /* Make sure the value is set to null */ - IAnalysisModuleHelper helper = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_PARAM); - try (IAnalysisModule module = helper.newModule(trace);) { - - assertEquals(10, module.getParameter(TestAnalysis.PARAM_TEST)); - - /* Change the value of the parameter in the provider */ - List providers = TmfAnalysisManager.getParameterProviders(module, trace); - assertEquals(1, providers.size()); - TestAnalysisParameterProvider provider = (TestAnalysisParameterProvider) providers.get(0); - provider.setValue(5); - assertEquals(5, module.getParameter(TestAnalysis.PARAM_TEST)); - - } catch (TmfAnalysisException e) { - fail(e.getMessage()); - return; - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisRequirementHelperTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisRequirementHelperTest.java deleted file mode 100644 index 65f1366113..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisRequirementHelperTest.java +++ /dev/null @@ -1,182 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Guilliano Molaire - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.analysis; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisRequirementProvider; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisRequirement.ValuePriorityLevel; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisRequirementHelper; -import org.eclipse.linuxtools.tmf.tests.stubs.analysis.AnalysisModuleTestHelper; -import org.eclipse.linuxtools.tmf.tests.stubs.analysis.AnalysisModuleTestHelper.moduleStubEnum; -import org.eclipse.linuxtools.tmf.tests.stubs.analysis.AnalysisRequirementFactory; -import org.junit.Before; -import org.junit.Test; - -import com.google.common.collect.Multimap; - -/** - * Test suite for the {@link TmfAnalysisRequirementHelper} class - */ -public class AnalysisRequirementHelperTest { - - private AnalysisModuleTestHelper fTestModuleHelper; - private AnalysisModuleTestHelper fTestModuleHelper2; - - /** - * Set up analysis modules - */ - @Before - public void setUpTest() { - fTestModuleHelper = new AnalysisModuleTestHelper(moduleStubEnum.TEST); - fTestModuleHelper2 = new AnalysisModuleTestHelper(moduleStubEnum.TEST2); - } - - /** - * Test suite for the - * {@link TmfAnalysisRequirementHelper#getRequirementValues(IAnalysisRequirementProvider, String)} - * method - */ - @Test - public void testGetRequirementValues() { - /* Test with a supported type */ - String type = AnalysisRequirementFactory.REQUIREMENT_TYPE_1; - Set values = TmfAnalysisRequirementHelper.getRequirementValues(fTestModuleHelper, type); - assertEquals(AnalysisRequirementFactory.REQUIREMENT_VALUES_1.size(), values.size()); - - /* Test with a type not supported */ - type = AnalysisRequirementFactory.REQUIREMENT_TYPE_2; - values = TmfAnalysisRequirementHelper.getRequirementValues(fTestModuleHelper, type); - assertTrue(values.isEmpty()); - } - - /** - * Test suite for the - * {@link TmfAnalysisRequirementHelper#getRequirementValues(IAnalysisRequirementProvider, String, ValuePriorityLevel)} - * method - */ - @Test - public void testGetRequirementValuesWithLevel() { - /* Test with a supported type */ - String type = AnalysisRequirementFactory.REQUIREMENT_TYPE_2; - Set values = TmfAnalysisRequirementHelper.getRequirementValues(fTestModuleHelper2, type, ValuePriorityLevel.MANDATORY); - assertEquals(3, values.size()); - - /* Test with another value level */ - values = TmfAnalysisRequirementHelper.getRequirementValues(fTestModuleHelper2, type, ValuePriorityLevel.OPTIONAL); - assertEquals(2, values.size()); - - /* Test with a type not supported */ - type = AnalysisRequirementFactory.REQUIREMENT_TYPE_1; - values = TmfAnalysisRequirementHelper.getRequirementValues(fTestModuleHelper2, type, ValuePriorityLevel.MANDATORY); - assertTrue(values.isEmpty()); - } - - /** - * Test suite for the - * {@link TmfAnalysisRequirementHelper#getRequirementValuesMap(Iterable)} - * method - */ - @Test - public void testGetRequirementValuesMap() { - Set providers = new HashSet<>(); - providers.add(fTestModuleHelper2); - providers.add(fTestModuleHelper); - - Multimap valuesByType = TmfAnalysisRequirementHelper.getRequirementValuesMap(providers); - assertFalse(valuesByType.isEmpty()); - - /* There should be 3 types */ - assertEquals(3, valuesByType.keySet().size()); - - Collection values = valuesByType.get(AnalysisRequirementFactory.REQUIREMENT_TYPE_1); - assertEquals(4, values.size()); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_1)); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_2)); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_3)); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_5)); - - values = valuesByType.get(AnalysisRequirementFactory.REQUIREMENT_TYPE_2); - assertEquals(5, values.size()); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_1)); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_2)); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_3)); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_4)); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_5)); - - values = valuesByType.get(AnalysisRequirementFactory.REQUIREMENT_TYPE_3); - assertEquals(3, values.size()); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_3)); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_4)); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_5)); - } - - /** - * Test suite for the - * {@link TmfAnalysisRequirementHelper#getRequirementValuesMap(Iterable, ValuePriorityLevel)} - * method - */ - @Test - public void testGetRequirementValuesMapWithLevel() { - Set providers = new HashSet<>(); - providers.add(fTestModuleHelper2); - providers.add(fTestModuleHelper); - - /* There should be 3 optional requirements types */ - Multimap valuesByType = TmfAnalysisRequirementHelper.getRequirementValuesMap(providers, ValuePriorityLevel.OPTIONAL); - assertTrue(!valuesByType.isEmpty()); - assertEquals(1, valuesByType.keySet().size()); - - Collection values = valuesByType.get(AnalysisRequirementFactory.REQUIREMENT_TYPE_1); - assertTrue(values.isEmpty()); - - values = valuesByType.get(AnalysisRequirementFactory.REQUIREMENT_TYPE_2); - assertEquals(2, values.size()); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_2)); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_4)); - - values = valuesByType.get(AnalysisRequirementFactory.REQUIREMENT_TYPE_3); - assertTrue(values.isEmpty()); - - /* And 3 types with mandatory requirements */ - valuesByType = TmfAnalysisRequirementHelper.getRequirementValuesMap(providers, ValuePriorityLevel.MANDATORY); - assertTrue(!valuesByType.isEmpty()); - assertEquals(3, valuesByType.keySet().size()); - - values = valuesByType.get(AnalysisRequirementFactory.REQUIREMENT_TYPE_1); - assertEquals(4, values.size()); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_1)); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_2)); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_3)); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_5)); - - values = valuesByType.get(AnalysisRequirementFactory.REQUIREMENT_TYPE_2); - assertEquals(3, values.size()); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_1)); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_3)); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_5)); - - values = valuesByType.get(AnalysisRequirementFactory.REQUIREMENT_TYPE_3); - assertEquals(3, values.size()); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_3)); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_4)); - assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_5)); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisRequirementTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisRequirementTest.java deleted file mode 100644 index 502d270105..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisRequirementTest.java +++ /dev/null @@ -1,243 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Guilliano Molaire - Initial API and implementation - * Mathieu Rail - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.analysis; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisRequirement; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisRequirement.ValuePriorityLevel; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -/** - * Test suite for the {@link TmfAnalysisRequirement} class. - * - * @author Guilliano Molaire - * @author Mathieu Rail - */ -public class AnalysisRequirementTest { - - /* Requirements used in the tests */ - private TmfAnalysisRequirement fRequirement; - private TmfAnalysisRequirement fSubRequirement; - - /* Types of requirement type strings */ - private static final String TYPE_A = "Test Type A"; - private static final String TYPE_B = "Test Type B"; - - /* Requirement value name strings */ - private static final String VALUE_A = "Test Value A"; - private static final String VALUE_B = "Test Value B"; - private static final String VALUE_C = "Test Value C"; - private static final String VALUE_D = "Test Value D"; - private static final String VALUE_E = "Test Value E"; - private static final String VALUE_F = "Test Value F"; - - /* Requirement information strings */ - private static final String INFO_A = "This is an information."; - private static final String INFO_B = "This is another information."; - private static final String INFO_C = "This is the last information."; - - /** - * Test suite for the {@link TmfAnalysisRequirement#addInformation} and the - * {@link TmfAnalysisRequirement#getInformation} methods. - */ - @Test - public void testAddAndGetInformation() { - fRequirement = new TmfAnalysisRequirement(TYPE_A); - - fRequirement.addInformation(INFO_A); - fRequirement.addInformation(INFO_B); - fRequirement.addInformation(INFO_B); - - Set information = fRequirement.getInformation(); - - assertEquals(2, information.size()); - - assertTrue(information.contains(INFO_A)); - assertTrue(information.contains(INFO_B)); - } - - /** - * Test suite for the {@link TmfAnalysisRequirement#addValues} and the - * {@link TmfAnalysisRequirement#addValue} methods. - */ - @Test - public void testAddValuesToRequirement() { - fRequirement = new TmfAnalysisRequirement(TYPE_A); - - assertEquals(0, fRequirement.getValues().size()); - - List values = new ArrayList<>(); - values.add(VALUE_A); - values.add(VALUE_B); - values.add(VALUE_C); - values.add(VALUE_C); - - /* - * Add values to the requirement with the same level, Value C should - * only exist once - */ - fRequirement.addValues(values, ValuePriorityLevel.MANDATORY); - assertEquals(3, fRequirement.getValues().size()); - - /* - * The new value should only exist once and its level should be - * mandatory - */ - fRequirement.addValue(VALUE_D, ValuePriorityLevel.OPTIONAL); - fRequirement.addValue(VALUE_D, ValuePriorityLevel.MANDATORY); - - assertEquals(4, fRequirement.getValues().size()); - assertEquals(ValuePriorityLevel.MANDATORY, fRequirement.getValueLevel(VALUE_D)); - } - - /** - * Test suite for the {@link TmfAnalysisRequirement#getValueLevel} method. - */ - @Test - public void testGetValueLevel() { - fRequirement = new TmfAnalysisRequirement(TYPE_A); - fRequirement.addValue(VALUE_A, ValuePriorityLevel.OPTIONAL); - - /* Try to get the level of a value */ - assertEquals(ValuePriorityLevel.OPTIONAL, fRequirement.getValueLevel(VALUE_A)); - - /* Try to get the level of a value that doesn't exist */ - assertNull(fRequirement.getValueLevel(VALUE_B)); - } - - /** - * Test suite for the {@link TmfAnalysisRequirement#merge} method with the - * parameter value MANDATORY. - */ - @Test - public void testMergeMandatory() { - initMergeRequirements(TYPE_A, TYPE_A); - - assertTrue(fRequirement.merge(fSubRequirement, ValuePriorityLevel.MANDATORY)); - - assertEquals(fRequirement.getValues().size(), 6); - - assertEquals(ValuePriorityLevel.MANDATORY, fRequirement.getValueLevel(VALUE_A)); - assertEquals(ValuePriorityLevel.MANDATORY, fRequirement.getValueLevel(VALUE_B)); - - assertEquals(ValuePriorityLevel.MANDATORY, fRequirement.getValueLevel(VALUE_C)); - assertEquals(ValuePriorityLevel.OPTIONAL, fRequirement.getValueLevel(VALUE_D)); - - assertEquals(ValuePriorityLevel.MANDATORY, fRequirement.getValueLevel(VALUE_E)); - assertEquals(ValuePriorityLevel.OPTIONAL, fRequirement.getValueLevel(VALUE_F)); - - Set information = fRequirement.getInformation(); - - assertEquals(3, information.size()); - - assertTrue(information.contains(INFO_A)); - assertTrue(information.contains(INFO_B)); - assertTrue(information.contains(INFO_C)); - } - - /** - * Test suite for the {@link TmfAnalysisRequirement#merge} method with the - * parameter value OPTIONAL. - */ - @Test - public void testMergeOptional() { - initMergeRequirements(TYPE_A, TYPE_A); - - assertTrue(fRequirement.merge(fSubRequirement, ValuePriorityLevel.OPTIONAL)); - - assertEquals(6, fRequirement.getValues().size()); - - assertEquals(ValuePriorityLevel.MANDATORY, fRequirement.getValueLevel(VALUE_A)); - assertEquals(ValuePriorityLevel.MANDATORY, fRequirement.getValueLevel(VALUE_B)); - - assertEquals(ValuePriorityLevel.OPTIONAL, fRequirement.getValueLevel(VALUE_C)); - assertEquals(ValuePriorityLevel.OPTIONAL, fRequirement.getValueLevel(VALUE_D)); - - assertEquals(ValuePriorityLevel.OPTIONAL, fRequirement.getValueLevel(VALUE_E)); - assertEquals(ValuePriorityLevel.OPTIONAL, fRequirement.getValueLevel(VALUE_F)); - - Set information = fRequirement.getInformation(); - - assertEquals(3, information.size()); - - assertTrue(information.contains(INFO_A)); - assertTrue(information.contains(INFO_B)); - assertTrue(information.contains(INFO_C)); - } - - /** - * Test suite for the {@link TmfAnalysisRequirement#merge} method with - * different requirement types. - */ - @Test - public void testMergeDifferentTypes() { - initMergeRequirements(TYPE_A, TYPE_B); - - assertFalse(fRequirement.merge(fSubRequirement, ValuePriorityLevel.OPTIONAL)); - } - - /** - * Test suite for the {@link TmfAnalysisRequirement#isSameType} method. - */ - @Test - public void testIsSameRequirementType() { - fRequirement = new TmfAnalysisRequirement(TYPE_A); - - assertTrue(fRequirement.isSameType(new TmfAnalysisRequirement(TYPE_A))); - assertFalse(fRequirement.isSameType(new TmfAnalysisRequirement(TYPE_B))); - } - - /** - * Initialize the requirement and sub-requirement for the merge tests. - * - * @param typeA - * The type of the first requirement - * @param typeB - * The type of the second requirement - */ - private void initMergeRequirements(String typeA, String typeB) { - fRequirement = new TmfAnalysisRequirement(typeA); - fRequirement.addValue(VALUE_A, ValuePriorityLevel.MANDATORY); - fRequirement.addValue(VALUE_B, ValuePriorityLevel.MANDATORY); - - fRequirement.addValue(VALUE_C, ValuePriorityLevel.OPTIONAL); - fRequirement.addValue(VALUE_D, ValuePriorityLevel.OPTIONAL); - - fRequirement.addInformation(INFO_A); - fRequirement.addInformation(INFO_B); - - /* This sub-requirement will be merged into requirement */ - fSubRequirement = new TmfAnalysisRequirement(typeB); - fSubRequirement.addValue(VALUE_A, ValuePriorityLevel.MANDATORY); - fSubRequirement.addValue(VALUE_B, ValuePriorityLevel.OPTIONAL); - - fSubRequirement.addValue(VALUE_C, ValuePriorityLevel.MANDATORY); - fSubRequirement.addValue(VALUE_D, ValuePriorityLevel.OPTIONAL); - - fSubRequirement.addValue(VALUE_E, ValuePriorityLevel.MANDATORY); - fSubRequirement.addValue(VALUE_F, ValuePriorityLevel.OPTIONAL); - - fSubRequirement.addInformation(INFO_B); - fSubRequirement.addInformation(INFO_C); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/component/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/component/AllTests.java deleted file mode 100644 index d8b309f66b..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/component/AllTests.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.component; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Unit tests for the component package. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TmfEventProviderTest.class, - TmfProviderManagerTest.class -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/component/TmfEventProviderTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/component/TmfEventProviderTest.java deleted file mode 100644 index 703888dfb4..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/component/TmfEventProviderTest.java +++ /dev/null @@ -1,362 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.component; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.IOException; -import java.util.Vector; - -import org.eclipse.linuxtools.internal.tmf.core.component.TmfProviderManager; -import org.eclipse.linuxtools.tmf.core.component.ITmfEventProvider; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest.ExecutionType; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.signal.TmfEndSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfStartSynchSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.tests.stubs.component.TmfEventProviderStub; -import org.eclipse.linuxtools.tmf.tests.stubs.component.TmfSyntheticEventProviderStub; -import org.eclipse.linuxtools.tmf.tests.stubs.event.TmfSyntheticEventStub; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Test suite for the TmfEventProvider class. - */ -public class TmfEventProviderTest { - - private TmfEventProviderStub fEventProvider; - private TmfSyntheticEventProviderStub fSyntheticEventProvider; - - /** - * Initialization - * - * @throws IOException - * If we can't find the test trace (they are committed in the - * tree, so it shouldn't happen). - */ - @Before - public void setUp() throws IOException { - fEventProvider = new TmfEventProviderStub(); - fSyntheticEventProvider = new TmfSyntheticEventProviderStub(); - } - - /** - * Clean-up - */ - @After - public void tearDown() { - fEventProvider.dispose(); - fSyntheticEventProvider.dispose(); - } - - // ------------------------------------------------------------------------ - // getProviders (more a sanity check than a test) - // ------------------------------------------------------------------------ - - /** - * Test getProviders - */ - @Test - public void testGetProviders() { - // There should be 2 TmfEvent providers: a TmfTraceStub and a - // TmfEventProviderStub - ITmfEventProvider[] eventProviders = TmfProviderManager.getProviders(ITmfEvent.class); - assertEquals("getProviders", 2, eventProviders.length); - - eventProviders = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); - assertEquals("getProviders", 1, eventProviders.length); - - eventProviders = TmfProviderManager.getProviders(ITmfEvent.class, TmfEventProviderStub.class); - assertEquals("getProviders", 1, eventProviders.length); - - // There should be 1 TmfSyntheticEventStub provider - eventProviders = TmfProviderManager.getProviders(TmfSyntheticEventStub.class); - assertEquals("getProviders", 1, eventProviders.length); - } - - // ------------------------------------------------------------------------ - // getSyntheticEvent - // ------------------------------------------------------------------------ - - /** - * Test getPlainEvents - */ - @Test - public void testGetPlainEvents() { - final int NB_EVENTS = 1000; - final Vector requestedEvents = new Vector<>(); - - // Get the TmfSyntheticEventStub provider - ITmfEventProvider[] eventProviders = TmfProviderManager.getProviders(ITmfEvent.class, - TmfEventProviderStub.class); - ITmfEventProvider provider = eventProviders[0]; - - TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, - range, 0, NB_EVENTS, ExecutionType.FOREGROUND) { - @Override - public void handleData(ITmfEvent event) { - super.handleData(event); - requestedEvents.add(event); - } - }; - - provider.sendRequest(request); - try { - request.waitForCompletion(); - assertEquals("nbEvents", NB_EVENTS, requestedEvents.size()); - assertTrue("isCompleted", request.isCompleted()); - assertFalse("isCancelled", request.isCancelled()); - - // Make that we have distinct events. - // Don't go overboard: we are not validating the stub! - for (int i = 0; i < NB_EVENTS; i++) { - assertEquals("Distinct events", i + 1, requestedEvents.get(i).getTimestamp().getValue()); - } - } catch (InterruptedException e) { - fail(); - } - } - - /** - * Test canceling requests. - */ - @Test - public void testCancelRequests() { - final int NB_EVENTS = 1000; - final int NUMBER_EVENTS_BEFORE_CANCEL_REQ1 = 10; - final int NUMBER_EVENTS_BEFORE_CANCEL_REQ2 = 800; - - final Vector requestedEventsReq1 = new Vector<>(); - final Vector requestedEventsReq2 = new Vector<>(); - - // Get the TmfSyntheticEventStub provider - ITmfEventProvider[] eventProviders = TmfProviderManager.getProviders(ITmfEvent.class, - TmfEventProviderStub.class); - ITmfEventProvider provider = eventProviders[0]; - - TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - - // Create first request - final TmfEventRequest request1 = new TmfEventRequest(ITmfEvent.class, - range, 0, NB_EVENTS, ExecutionType.FOREGROUND) { - @Override - public void handleData(ITmfEvent event) { - super.handleData(event); - requestedEventsReq1.add(event); - - // cancel sub request - if (getNbRead() == NUMBER_EVENTS_BEFORE_CANCEL_REQ1) { - cancel(); - } - } - }; - - // Synchronize requests - ((TmfEventProviderStub) provider).startSynch(new TmfStartSynchSignal(0)); - - // Additionally, notify provider for up-coming requests - provider.notifyPendingRequest(true); - - // Call sendRequest, which will create a coalescing request, but it - // doesn't send request1 yet - provider.sendRequest(request1); - - // Check if request1 is not running yet. - assertFalse("isRunning", request1.isRunning()); - - // Create second request - final TmfEventRequest request2 = new TmfEventRequest(ITmfEvent.class, - range, 0, NB_EVENTS, ExecutionType.FOREGROUND) { - @Override - public void handleData(ITmfEvent event) { - super.handleData(event); - requestedEventsReq2.add(event); - - // cancel sub request which will cancel also main request - if (getNbRead() == NUMBER_EVENTS_BEFORE_CANCEL_REQ2) { - cancel(); - } - } - }; - - // Call sendRequest, which will create a coalescing request, but it - // doesn't send request2 yet - provider.sendRequest(request2); - - // Check if request1/2 is not running yet. - assertFalse("isRunning", request1.isRunning()); - assertFalse("isRunning", request2.isRunning()); - - // Send end synch signal, however requests won't be sent - ((TmfEventProviderStub) provider).endSynch(new TmfEndSynchSignal(0)); - - // Check if request1/2 is not running yet. - assertFalse("isRunning", request1.isRunning()); - assertFalse("isRunning", request2.isRunning()); - - // Finally, trigger sending of requests - provider.notifyPendingRequest(false); - - try { - - // Wait until requests start - request1.waitForStart(); - request2.waitForStart(); - -// // Verify that the requests are running -// assertTrue("isRunning", request1.isRunning()); -// assertTrue("isRunning", request2.isRunning()); - - request1.waitForCompletion(); - -// // Check if request2 is still running -// assertTrue("isRunning", request2.isRunning()); - - // Verify result (request1) - assertEquals("nbEvents", NUMBER_EVENTS_BEFORE_CANCEL_REQ1, requestedEventsReq1.size()); - assertTrue("isCompleted", request1.isCompleted()); - assertTrue("isCancelled", request1.isCancelled()); - - request2.waitForCompletion(); - - // Verify result (request2) - assertEquals("nbEvents", NUMBER_EVENTS_BEFORE_CANCEL_REQ2, requestedEventsReq2.size()); - assertTrue("isCompleted", request2.isCompleted()); - assertTrue("isCancelled", request2.isCancelled()); - - } catch (InterruptedException e) { - fail(); - } - } - - private static void getSyntheticData(final TmfTimeRange range, - final int nbEvents) throws InterruptedException { - - final Vector requestedEvents = new Vector<>(); - - // Get the event provider - ITmfEventProvider[] eventProviders = TmfProviderManager - .getProviders(TmfSyntheticEventStub.class); - ITmfEventProvider provider = eventProviders[0]; - - final TmfEventRequest request = new TmfEventRequest(TmfSyntheticEventStub.class, range, - 0, nbEvents, ExecutionType.FOREGROUND) { - @Override - public void handleData(ITmfEvent event) { - super.handleData(event); - requestedEvents.add(event); - } - }; - provider.sendRequest(request); - - request.waitForCompletion(); - if (nbEvents != -1) { - assertEquals("nbEvents", nbEvents, requestedEvents.size()); - } - assertTrue("isCompleted", request.isCompleted()); - assertFalse("isCancelled", request.isCancelled()); - - // For each base event, the stub will queue 2 identical synthetic events - // Ensure that the events are queued properly. - // Don't go overboard: we are not validating the stub! - for (int i = 0; i < (nbEvents / 2); i++) { - assertEquals("Distinct events", i + 1, requestedEvents.get(2 * i + 0).getTimestamp().getValue()); - assertEquals("Distinct events", i + 1, requestedEvents.get(2 * i + 1).getTimestamp().getValue()); - } - } - - /** - * Test getSyntheticEvents for equal block sizes. - */ - @Test - public void testGetSyntheticEvents_EqualBlockSizes() { - TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - try { - getSyntheticData(range, 1000); - } catch (InterruptedException e) { - fail(); - } - } - - /** - * Test getSyntheticEvents - */ - @Test - public void testGetSyntheticEvents_TimeRange() { - TmfTimestamp start = new TmfTimestamp(1, (byte) -3, 0); - TmfTimestamp end = new TmfTimestamp(1000, (byte) -3, 0); - TmfTimeRange range = new TmfTimeRange(start, end); - try { - getSyntheticData(range, -1); - } catch (InterruptedException e) { - fail(); - } - } - -// public void testGetSyntheticEvents_WeirdTimeRange1() { -// TmfTimestamp start = TmfTimestamp.BigBang; -// TmfTimestamp end = TmfTimestamp.Zero; // new TmfTimestamp(0, (byte) -3, -// // 0); -// TmfTimeRange range = new TmfTimeRange(start, end); -// try { -// getSyntheticData(range, -1, TmfSyntheticEventProviderStub.BLOCK_SIZE); -// } catch (InterruptedException e) { -// fail(); -// } -// } - -// public void testGetSyntheticEvents_WeirdTimeRange2() { -// TmfTimestamp start = TmfTimestamp.Zero; // new TmfTimestamp(0, (byte) -// // -3, 0); -// TmfTimestamp end = TmfTimestamp.BigCrunch; -// TmfTimeRange range = new TmfTimeRange(start, end); -// try { -// getSyntheticData(range, -1, TmfSyntheticEventProviderStub.BLOCK_SIZE); -// } catch (InterruptedException e) { -// fail(); -// } -// } - - /** - * Test getProviders (more a sanity check than a test) - */ - @Test - public void testGetProviders2() { - - // There should be 2 TmfEvent providers: a TmfTraceStub and a - // TmfEventProviderStub - ITmfEventProvider[] eventProviders = TmfProviderManager.getProviders(ITmfEvent.class); - assertEquals("getProviders", 2, eventProviders.length); - - eventProviders = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); - assertEquals("getProviders", 1, eventProviders.length); - - eventProviders = TmfProviderManager.getProviders(ITmfEvent.class, TmfEventProviderStub.class); - assertEquals("getProviders", 1, eventProviders.length); - - // There should be 1 TmfSyntheticEventStub provider - eventProviders = TmfProviderManager.getProviders(TmfSyntheticEventStub.class); - assertEquals("getProviders", 1, eventProviders.length); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/component/TmfProviderManagerTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/component/TmfProviderManagerTest.java deleted file mode 100644 index b12ea0e1d3..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/component/TmfProviderManagerTest.java +++ /dev/null @@ -1,330 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.component; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.eclipse.linuxtools.internal.tmf.core.component.TmfProviderManager; -import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.junit.Test; - -/** - * Test suite for the TmfProviderManager class. - */ -public class TmfProviderManagerTest { - - // ------------------------------------------------------------------------ - // Dummy Providers - // ------------------------------------------------------------------------ - - private class TestProvider1 extends TmfEventProvider { - public TestProvider1(Class type) { - super("TestProvider1", type); - } - - @Override - public ITmfContext armRequest(ITmfEventRequest request) { - return null; - } - - @Override - public ITmfEvent getNext(ITmfContext context) { - return null; - } - - @Override - public boolean isCompleted(ITmfEventRequest request, ITmfEvent data, int nbRead) { - return false; - } - } - - private class TestProvider2 extends TmfEventProvider { - public TestProvider2(Class type) { - super("TestProvider2", type); - } - - @Override - public ITmfContext armRequest(ITmfEventRequest request) { - return null; - } - - @Override - public ITmfEvent getNext(ITmfContext context) { - return null; - } - - @Override - public boolean isCompleted(ITmfEventRequest request, ITmfEvent data, int nbRead) { - return false; - } - } - - private class TmfEvent3 extends TmfEvent { - } - - private class TestProvider3 extends TmfEventProvider { - public TestProvider3(Class type) { - super("TestProvider3", type); - } - - @Override - public ITmfContext armRequest(ITmfEventRequest request) { - return null; - } - - @Override - public TmfEvent3 getNext(ITmfContext context) { - return null; - } - - @Override - public boolean isCompleted(ITmfEventRequest request, ITmfEvent data, int nbRead) { - return false; - } - } - - // ------------------------------------------------------------------------ - // register/dispose - // ------------------------------------------------------------------------ - - /** - * Test registering - */ - @Test - public void testRegister_0() { - TmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class); - assertEquals("getProviders", 0, providers.length); - - providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); - assertEquals("getProviders", 0, providers.length); - } - - /** - * Test unregistering - */ - @Test - public void testRegister_Unregister_1() { - - // Register a single provider - TestProvider1 testProvider1 = new TestProvider1(ITmfEvent.class); - - TmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class); - assertEquals("getProviders", 1, providers.length); - assertEquals("getProviders", testProvider1, providers[0]); - - providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); - assertEquals("getProviders", 1, providers.length); - assertEquals("getProviders", testProvider1, providers[0]); - - // Unregister it - testProvider1.dispose(); - - providers = TmfProviderManager.getProviders(ITmfEvent.class); - assertEquals("getProviders", 0, providers.length); - - providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); - assertEquals("getProviders", 0, providers.length); - } - - /** - * Test unregistering - */ - @Test - public void testRegister_Unregister_2() { - - // Register 2 providers, same data type - TestProvider1 testProvider1 = new TestProvider1(ITmfEvent.class); - TestProvider2 testProvider2 = new TestProvider2(ITmfEvent.class); - - TmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class); - assertEquals("getProviders", 2, providers.length); - assertTrue(providers.length == 2); - if (providers[0] == testProvider1) { - assertEquals("getProviders", testProvider2, providers[1]); - } - else { - assertEquals("getProviders", testProvider2, providers[0]); - assertEquals("getProviders", testProvider1, providers[1]); - } - - providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); - assertEquals("getProviders", 1, providers.length); - assertEquals("getProviders", testProvider1, providers[0]); - - providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider2.class); - assertEquals("getProviders", 1, providers.length); - assertEquals("getProviders", testProvider2, providers[0]); - - // Remove one - testProvider1.dispose(); - - providers = TmfProviderManager.getProviders(ITmfEvent.class); - assertEquals("getProviders", 1, providers.length); - assertEquals("getProviders", testProvider2, providers[0]); - - providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); - assertEquals("getProviders", 0, providers.length); - - providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider2.class); - assertEquals("getProviders", 1, providers.length); - assertEquals("getProviders", testProvider2, providers[0]); - - // Remove the other - testProvider2.dispose(); - - providers = TmfProviderManager.getProviders(ITmfEvent.class); - assertEquals("getProviders", 0, providers.length); - - providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); - assertEquals("getProviders", 0, providers.length); - - providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider2.class); - assertEquals("getProviders", 0, providers.length); - } - - /** - * Test unregistering - */ - @Test - public void testRegister_Unregister_3() { - - // Register 3 providers, mixed data types - TestProvider1 testProvider1 = new TestProvider1(ITmfEvent.class); - TestProvider2 testProvider2 = new TestProvider2(ITmfEvent.class); - TestProvider3 testProvider3 = new TestProvider3(TmfEvent3.class); - - TmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class); - assertEquals("getProviders", 2, providers.length); - if (providers[0] == testProvider1) { - assertEquals("getProviders", testProvider2, providers[1]); - } - else { - assertEquals("getProviders", testProvider2, providers[0]); - assertEquals("getProviders", testProvider1, providers[1]); - } - - TmfEventProvider[] providers3 = TmfProviderManager.getProviders(TmfEvent3.class); - assertEquals("getProviders", 1, providers3.length); - assertEquals("getProviders", testProvider3, providers3[0]); - - providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); - assertEquals("getProviders", 1, providers.length); - assertEquals("getProviders", testProvider1, providers[0]); - - providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider2.class); - assertEquals("getProviders", 1, providers.length); - assertEquals("getProviders", testProvider2, providers[0]); - - providers3 = TmfProviderManager.getProviders(TmfEvent3.class, TestProvider3.class); - assertEquals("getProviders", 1, providers3.length); - assertEquals("getProviders", testProvider3, providers3[0]); - - // Remove one - testProvider1.dispose(); - - providers = TmfProviderManager.getProviders(ITmfEvent.class); - assertEquals("getProviders", 1, providers.length); - assertEquals("getProviders", testProvider2, providers[0]); - - providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); - assertEquals("getProviders", 0, providers.length); - - providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider2.class); - assertEquals("getProviders", 1, providers.length); - assertEquals("getProviders", testProvider2, providers[0]); - - providers3 = TmfProviderManager.getProviders(TmfEvent3.class); - assertEquals("getProviders", 1, providers3.length); - assertEquals("getProviders", testProvider3, providers3[0]); - - providers3 = TmfProviderManager.getProviders(TmfEvent3.class, TestProvider3.class); - assertEquals("getProviders", 1, providers3.length); - assertEquals("getProviders", testProvider3, providers3[0]); - - // Remove another one - testProvider2.dispose(); - - providers = TmfProviderManager.getProviders(ITmfEvent.class); - assertEquals("getProviders", 0, providers.length); - - providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); - assertEquals("getProviders", 0, providers.length); - - providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider2.class); - assertEquals("getProviders", 0, providers.length); - - providers3 = TmfProviderManager.getProviders(TmfEvent3.class); - assertTrue(providers3.length == 1); - assertTrue(providers3[0] == testProvider3); - - providers3 = TmfProviderManager.getProviders(TmfEvent3.class, TestProvider3.class); - assertEquals("getProviders", 1, providers3.length); - assertEquals("getProviders", testProvider3, providers3[0]); - - // Remove the last one - testProvider3.dispose(); - - providers = TmfProviderManager.getProviders(ITmfEvent.class); - assertEquals("getProviders", 0, providers.length); - - providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); - assertEquals("getProviders", 0, providers.length); - - providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider2.class); - assertEquals("getProviders", 0, providers.length); - - providers3 = TmfProviderManager.getProviders(TmfEvent3.class); - assertEquals("getProviders", 0, providers.length); - - providers3 = TmfProviderManager.getProviders(TmfEvent3.class, TestProvider3.class); - assertEquals("getProviders", 0, providers.length); - } - - /** - * Test getProviders method - */ - @Test - public void testGetProvider() { - - // Register 3 providers, mixed data types - TestProvider1 testProvider1 = new TestProvider1(ITmfEvent.class); - TestProvider2 testProvider2 = new TestProvider2(ITmfEvent.class); - TestProvider3 testProvider3 = new TestProvider3(TmfEvent3.class); - - TmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class, null); - assertEquals("getProviders", 2, providers.length); - if (providers[0] == testProvider1) { - assertEquals("getProviders", testProvider2, providers[1]); - } - else { - assertEquals("getProviders", testProvider2, providers[0]); - assertEquals("getProviders", testProvider1, providers[1]); - } - - providers = TmfProviderManager.getProviders(TmfEvent3.class, null); - assertEquals("getProviders", 1, providers.length); - assertEquals("getProviders", testProvider3, providers[0]); - - // Remove the providers - testProvider1.dispose(); - testProvider2.dispose(); - testProvider3.dispose(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/AllTests.java deleted file mode 100644 index bf91caf493..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/AllTests.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Adjusted for new Event Model - * Alexandre Montplaisir - Port to JUnit4 - * Patrick Tasse - Added TmfNanoTimestampTest - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.event; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite for org.eclipse.linuxtools.tmf.core.event - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TmfEventFieldTest.class, - TmfEventTest.class, - TmfEventTypeManagerTest.class, - TmfEventTypeTest.class, - TmfNanoTimestampTest.class, - TmfSimpleTimestampTest.class, - TmfTimePreferencesTest.class, - TmfTimeRangeTest.class, - TmfTimestampDeltaTest.class, - TmfTimestampTest.class, - TmfTimestampFormatTest.class, -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfEventFieldTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfEventFieldTest.java deleted file mode 100644 index e69f31e3c1..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfEventFieldTest.java +++ /dev/null @@ -1,365 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Adjusted for new Event Model - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.event; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.Collection; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.junit.Test; - -/** - * Test suite for the TmfEventField class. - */ -@SuppressWarnings("javadoc") -public class TmfEventFieldTest { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - private final String fFieldName1 = "Field-1"; - private final String fFieldName2 = "Field-2"; - - private final Object fValue1 = "Value"; - private final Object fValue2 = Integer.valueOf(10); - - private final TmfEventField fField1 = new TmfEventField(fFieldName1, fValue1, null); - private final TmfEventField fField2 = new TmfEventField(fFieldName2, fValue2, null); - private final TmfEventField fField3 = new TmfEventField(fFieldName1, fValue2, null); - - private final String fStructRootFieldName = "Root-S"; - private final String[] fStructFieldNames = new String[] { fFieldName1, fFieldName2 }; - private final TmfEventField fStructTerminalField1 = new TmfEventField(fFieldName1, null, null); - private final TmfEventField fStructTerminalField2 = new TmfEventField(fFieldName2, null, null); - private final TmfEventField fStructTerminalField3 = new TmfEventField(fFieldName1, null, null); - private final TmfEventField fStructRootField = new TmfEventField(fStructRootFieldName, null, - new ITmfEventField[] { fStructTerminalField1, fStructTerminalField2 }); - - private final String fRootFieldName = "Root"; - private final String[] fFieldNames = new String[] { fFieldName1, fFieldName2 }; - private final TmfEventField fRootField = new TmfEventField(fRootFieldName, null, - new ITmfEventField[] { fField1, fField2 }); - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - @Test - public void testTerminalStructConstructor() { - assertSame("getName", fFieldName1, fStructTerminalField1.getName()); - assertNull("getValue", fStructTerminalField1.getValue()); - assertEquals("getFields", 0, fStructTerminalField1.getFields().size()); - assertNull("getField(name)", fStructTerminalField1.getField(fFieldName1)); - assertEquals("getFieldNames", 0, fStructTerminalField1.getFieldNames().size()); - } - - @Test - public void testNonTerminalStructConstructor() { - assertSame("getName", fStructRootFieldName, fStructRootField.getName()); - assertNull("getValue", fStructRootField.getValue()); - assertEquals("getFields", 2, fStructRootField.getFields().size()); - assertSame("getField(name)", fStructTerminalField1, fStructRootField.getField(fFieldName1)); - assertSame("getField(name)", fStructTerminalField2, fStructRootField.getField(fFieldName2)); - - final Collection names = fStructRootField.getFieldNames(); - assertEquals("getFieldNames length", 2, names.size()); - assertArrayEquals(fStructFieldNames, names.toArray(new String[names.size()])); - } - - @Test - public void testTerminalConstructor() { - assertSame("getName", fFieldName1, fField1.getName()); - assertSame("getValue", fValue1, fField1.getValue()); - assertEquals("getFields", 0, fField1.getFields().size()); - assertNull("getField(name)", fField1.getField(fFieldName1)); - assertEquals("getFieldNames", 0, fField1.getFieldNames().size()); - - assertSame("getName", fFieldName2, fField2.getName()); - assertSame("getValue", fValue2, fField2.getValue()); - assertEquals("getFields", 0, fField2.getFields().size()); - assertNull("getField(name)", fField2.getField(fFieldName2)); - } - - @Test - public void testNonTerminalConstructor() { - assertSame("getName", fRootFieldName, fRootField.getName()); - assertNull("getValue", fRootField.getValue()); - assertEquals("getFields", 2, fRootField.getFields().size()); - assertSame("getField(name)", fField1, fRootField.getField(fFieldName1)); - assertSame("getField(name)", fField2, fRootField.getField(fFieldName2)); - - final Collection names = fRootField.getFieldNames(); - assertEquals("getFieldNames length", 2, names.size()); - assertArrayEquals(fFieldNames, names.toArray(new String[names.size()])); - } - - @Test - public void testConstructorBadArg() { - try { - new TmfEventField(null, fValue1, null); - fail("Invalid (null) field name"); - } catch (final IllegalArgumentException e) { - } - } - - @Test - public void testTerminalCopyConstructor() { - final TmfEventField copy = new TmfEventField(fField1); - assertSame("getName", fFieldName1, copy.getName()); - assertSame("getValue", fValue1, copy.getValue()); - assertEquals("getFields", 0, copy.getFields().size()); - assertNull("getField(name)", copy.getField(fFieldName1)); - assertEquals("getFieldNames", 0, copy.getFieldNames().size()); - } - - @Test - public void testNonTerminalCopyConstructor() { - assertSame("getName", fRootFieldName, fRootField.getName()); - assertNull("getValue", fRootField.getValue()); - assertEquals("getFields", 2, fRootField.getFields().size()); - assertSame("getField(name)", fField1, fRootField.getField(fFieldName1)); - assertSame("getField(name)", fField2, fRootField.getField(fFieldName2)); - - final Collection names = fRootField.getFieldNames(); - assertEquals("getFieldNames length", 2, names.size()); - assertArrayEquals(fFieldNames, names.toArray(new String[names.size()])); - } - - @Test - public void testCopyConstructorBadArg() { - try { - new TmfEventField(null); - fail("TmfEventField: null arguemnt"); - } catch (final IllegalArgumentException e) { - } - } - - /** - * Test that we correctly fail to create a field with subfields having the - * same name. - */ - @Test - public void testDuplicateFieldNames() { - ITmfEventField[] fields = { - new TmfEventField("samename", null, null), - new TmfEventField("samename", null, null) - }; - - try { - new TmfEventField("field", null, fields); - fail("TmfEventField: Duplicate field names"); - } catch (IllegalArgumentException e) { - /* Expected exception */ - } - } - - // ------------------------------------------------------------------------ - // hashCode - // ------------------------------------------------------------------------ - - @Test - public void testHashCode() { - TmfEventField copy = new TmfEventField(fField1); - assertTrue("hashCode", fField1.hashCode() == copy.hashCode()); - assertTrue("hashCode", fField1.hashCode() != fField2.hashCode()); - - copy = new TmfEventField(fStructTerminalField1); - assertTrue("hashCode", fStructTerminalField1.hashCode() == copy.hashCode()); - assertTrue("hashCode", fStructTerminalField1.hashCode() != fStructTerminalField2.hashCode()); - } - - // ------------------------------------------------------------------------ - // equals - // ------------------------------------------------------------------------ - - @Test - public void testEqualsReflexivity() { - assertTrue("equals", fField1.equals(fField1)); - assertTrue("equals", fField2.equals(fField2)); - - assertFalse("equals", fField1.equals(fField2)); - assertFalse("equals", fField2.equals(fField1)); - - assertTrue("equals", fStructTerminalField1.equals(fStructTerminalField1)); - assertTrue("equals", fStructTerminalField2.equals(fStructTerminalField2)); - - assertFalse("equals", fStructTerminalField1.equals(fStructTerminalField2)); - assertFalse("equals", fStructTerminalField2.equals(fStructTerminalField1)); - } - - @Test - public void testEqualsSymmetry() { - final TmfEventField copy0 = new TmfEventField(fField1); - assertTrue("equals", fField1.equals(copy0)); - assertTrue("equals", copy0.equals(fField1)); - - final TmfEventField copy3 = new TmfEventField(fField2); - assertTrue("equals", fField2.equals(copy3)); - assertTrue("equals", copy3.equals(fField2)); - } - - @Test - public void testEqualsTransivity() { - TmfEventField copy1 = new TmfEventField(fField1); - TmfEventField copy2 = new TmfEventField(copy1); - assertTrue("equals", fField1.equals(copy1)); - assertTrue("equals", copy1.equals(copy2)); - assertTrue("equals", fField1.equals(copy2)); - - copy1 = new TmfEventField(fField2); - copy2 = new TmfEventField(copy1); - assertTrue("equals", fField2.equals(copy1)); - assertTrue("equals", copy1.equals(copy2)); - assertTrue("equals", fField2.equals(copy2)); - } - - @Test - public void testEquals() { - assertTrue("equals", fStructTerminalField1.equals(fStructTerminalField3)); - assertTrue("equals", fStructTerminalField3.equals(fStructTerminalField1)); - - assertFalse("equals", fStructTerminalField1.equals(fField3)); - assertFalse("equals", fField3.equals(fStructTerminalField1)); - } - - @Test - public void testEqualsNull() { - assertFalse("equals", fField1.equals(null)); - assertFalse("equals", fField2.equals(null)); - } - - @Test - public void testNonEqualClasses() { - assertFalse("equals", fField1.equals(fStructTerminalField1)); - assertFalse("equals", fField1.equals(fValue1)); - } - - @Test - public void testNonEqualValues() { - final TmfEventField copy1 = new TmfEventField(fFieldName1, fValue1, null); - TmfEventField copy2 = new TmfEventField(fFieldName1, fValue1, null); - assertTrue("equals", copy1.equals(copy2)); - assertTrue("equals", copy2.equals(copy1)); - - copy2 = new TmfEventField(fFieldName1, fValue2, null); - assertFalse("equals", copy1.equals(copy2)); - assertFalse("equals", copy2.equals(copy1)); - - copy2 = new TmfEventField(fFieldName1, null, null); - assertFalse("equals", copy1.equals(copy2)); - assertFalse("equals", copy2.equals(copy1)); - } - - @Test - public void testNonEquals() { - assertFalse("equals", fField1.equals(fField2)); - assertFalse("equals", fField2.equals(fField1)); - - assertFalse("equals", fField1.equals(fStructTerminalField1)); - } - - /** - * Test with same fields, but different values (should not be equal) - */ - @Test - public void testNonEqualsValue() { - final String fieldName = "myfield"; - final Object value1 = new String("test-string"); - final Object value2 = new TmfEvent(); - final TmfEventField[] fields = { fField1, fField2 }; - - final TmfEventField field1 = new TmfEventField(fieldName, value1, fields); - final TmfEventField field2 = new TmfEventField(fieldName, value2, fields); - - assertNotEquals(field1, field2); - assertNotEquals(field2, field1); - } - - /** - * Test with same value, but different fields (should not be equal) - */ - @Test - public void testNonEqualsFields() { - final String fieldName = "myfield"; - final Object value = new String("test-string"); - final TmfEventField[] fields1 = { fField1, fField2 }; - final TmfEventField[] fields2 = { fField2, fField3 }; - - final TmfEventField field1 = new TmfEventField(fieldName, value, fields1); - final TmfEventField field2 = new TmfEventField(fieldName, value, fields2); - - assertNotEquals(field1, field2); - assertNotEquals(field2, field1); - } - - /** - * Test with same field and values (should be equals) - */ - @Test - public void testEqualsEverything() { - final String fieldName = "myfield"; - final Object value = new String("test-string"); - final TmfEventField[] fields = { fField1, fField2 }; - - final TmfEventField field1 = new TmfEventField(fieldName, value, fields); - final TmfEventField field2 = new TmfEventField(fieldName, value, fields); - - assertEquals(field1, field2); - assertEquals(field2, field1); - } - - // ------------------------------------------------------------------------ - // toString - // ------------------------------------------------------------------------ - - @Test - public void testToString() { - final String expected1 = fFieldName1 + "=" + fValue1.toString(); - TmfEventField field = new TmfEventField(fFieldName1, fValue1, null); - assertEquals("toString", expected1, field.toString()); - - final String expected2 = fFieldName1 + "=" + fValue2.toString(); - field = new TmfEventField(fFieldName1, fValue2, null); - assertEquals("toString", expected2, field.toString()); - } - - // ------------------------------------------------------------------------ - // makeRoot - // ------------------------------------------------------------------------ - - @Test - public void testMakeRoot() { - ITmfEventField root = TmfEventField.makeRoot(fStructFieldNames); - Collection names = root.getFieldNames(); - assertEquals("getFieldNames length", 2, names.size()); - assertArrayEquals(fStructFieldNames, names.toArray(new String[names.size()])); - - root = TmfEventField.makeRoot(fFieldNames); - names = root.getFieldNames(); - assertEquals("getFieldNames length", 2, names.size()); - assertArrayEquals(fFieldNames, names.toArray(new String[names.size()])); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfEventTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfEventTest.java deleted file mode 100644 index 40cefa1deb..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfEventTest.java +++ /dev/null @@ -1,417 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Adjusted for new Event Model - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.event; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.tests.TmfCoreTestPlugin; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; -import org.junit.Test; - -/** - * Test suite for the TmfEvent class. - */ -@SuppressWarnings("javadoc") -public class TmfEventTest { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - private final String fSource = "Source"; - - private final String fContext = ITmfEventType.DEFAULT_CONTEXT_ID; - private final String fTypeId = "TestType"; - private final String fLabel1 = "AString"; - private final String fLabel2 = "AnInteger"; - private final String[] fLabels = new String[] { fLabel1, fLabel2 }; - private final TmfEventType fType = new TmfEventType(fContext, fTypeId, TmfEventField.makeRoot(fLabels)); - - private final Object fValue1a = "Some string"; - private final Object fValue1b = Integer.valueOf(10); - private final ITmfEventField fField1a = new TmfEventField(fLabel1, fValue1a, null); - private final ITmfEventField fField1b = new TmfEventField(fLabel2, fValue1b, null); - private final ITmfEventField[] fFields1 = new ITmfEventField[] { fField1a, fField1b }; - private final String fRawContent1 = fField1a.toString() + fField1b.toString(); - private final ITmfEventField fContent1 = new TmfEventField(fRawContent1, null, fFields1); - private final TmfTimestamp fTimestamp1 = new TmfTimestamp(12345, 2, 5); - private final String fReference1 = "Some reference"; - private final ITmfEvent fEvent1 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - - private final Object fValue2a = "Another string"; - private final Object fValue2b = Integer.valueOf(-4); - private final ITmfEventField fField2a = new TmfEventField(fLabel1, fValue2a, null); - private final ITmfEventField fField2b = new TmfEventField(fLabel2, fValue2b, null); - private final ITmfEventField[] fFields2 = new ITmfEventField[] { fField2a, fField2b }; - private final String fRawContent2 = fField2a.toString() + fField2b.toString(); - private final ITmfEventField fContent2 = new TmfEventField(fRawContent2, null, fFields2); - private final TmfTimestamp fTimestamp2 = new TmfTimestamp(12350, 2, 5); - private final String fReference2 = "Some other reference"; - private final ITmfEvent fEvent2 = new TmfEvent(null, 1, fTimestamp2, fSource, fType, fContent2, fReference2); - - // ------------------------------------------------------------------------ - // Helper functions - // ------------------------------------------------------------------------ - - private static TmfTraceStub openTrace() { - TmfTraceStub trace = null; - try { - final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TmfTestTrace.A_TEST_10K.getFullPath()), null); - final File test = new File(FileLocator.toFileURL(location).toURI()); - trace = new TmfTraceStub(test.toURI().getPath(), 500, false, null); - } catch (final TmfTraceException e) { - e.printStackTrace(); - } catch (final URISyntaxException e) { - e.printStackTrace(); - } catch (final IOException e) { - e.printStackTrace(); - } - return trace; - } - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - @Test - public void testDefaultConstructor() { - final ITmfEvent event = new TmfEvent(); - assertNull("getTrace", event.getTrace()); - assertEquals("getRank", ITmfContext.UNKNOWN_RANK, event.getRank()); - assertNull("getTimestamp", event.getTimestamp()); - assertNull("getSource", event.getSource()); - assertNull("getType", event.getType()); - assertNull("getContent", event.getContent()); - assertNull("getReference", event.getReference()); - } - - @Test - public void testFullConstructor() { - assertNull("getTrace", fEvent1.getTrace()); - assertEquals("getRank", 0, fEvent1.getRank()); - assertEquals("getTimestamp", fTimestamp1, fEvent1.getTimestamp()); - assertEquals("getSource", fSource, fEvent1.getSource()); - assertEquals("getType", fType, fEvent1.getType()); - assertEquals("getContent", fContent1, fEvent1.getContent()); - assertEquals("getReference", fReference1, fEvent1.getReference()); - - assertNull("getTrace", fEvent2.getTrace()); - assertEquals("getRank", 1, fEvent2.getRank()); - assertEquals("getTimestamp", fTimestamp2, fEvent2.getTimestamp()); - assertEquals("getSource", fSource, fEvent2.getSource()); - assertEquals("getType", fType, fEvent2.getType()); - assertEquals("getContent", fContent2, fEvent2.getContent()); - assertEquals("getReference", fReference2, fEvent2.getReference()); - } - - @Test - public void testNoRankConstructor() { - final ITmfEvent event = new TmfEvent(null, fTimestamp1, fSource, fType, fContent1, fReference1); - assertNull("getTrace", event.getTrace()); - assertEquals("getRank", ITmfContext.UNKNOWN_RANK, event.getRank()); - assertEquals("getTimestamp", fTimestamp1, event.getTimestamp()); - assertEquals("getSource", fSource, event.getSource()); - assertEquals("getType", fType, event.getType()); - assertEquals("getContent", fContent1, event.getContent()); - assertEquals("getReference", fReference1, event.getReference()); - } - - @Test - public void testConstructorWithTrace() { - final ITmfTrace trace = openTrace(); - final ITmfEvent event = new TmfEvent(trace, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - assertNotNull("getTrace", event.getTrace()); - assertEquals("getRank", 0, event.getRank()); - assertEquals("getTimestamp", fTimestamp1, event.getTimestamp()); - assertEquals("getSource", fSource, event.getSource()); - assertEquals("getType", fType, event.getType()); - assertEquals("getContent", fContent1, event.getContent()); - assertEquals("getReference", fReference1, event.getReference()); - trace.dispose(); - } - - @Test - public void testTmfEventCopy() { - final ITmfEvent event = new TmfEvent(fEvent1); - assertNull("getTrace", event.getTrace()); - assertEquals("getRank", 0, event.getRank()); - assertEquals("getTimestamp", fTimestamp1, event.getTimestamp()); - assertEquals("getSource", fSource, event.getSource()); - assertEquals("getType", fType, event.getType()); - assertEquals("getContent", fContent1, event.getContent()); - assertEquals("getReference", fReference1, event.getReference()); - } - - @Test - public void testEventCopy2() { - try { - new TmfEvent(null); - fail("null copy"); - } catch (final IllegalArgumentException e) { - // Success - } - } - - // ------------------------------------------------------------------------ - // hashCode - // ------------------------------------------------------------------------ - - @Test - public void testHashCode() { - ITmfEvent event1 = new TmfEvent(); - ITmfEvent event2 = new TmfEvent(); - - assertTrue("hashCode", event1.hashCode() == event2.hashCode()); - - final ITmfTrace trace = openTrace(); - event1 = new TmfEvent(trace, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - event2 = new TmfEvent(trace, 1, fTimestamp2, fSource, fType, fContent2, fReference2); - final ITmfEvent event1b = new TmfEvent(event1); - final ITmfEvent event2b = new TmfEvent(event2); - - assertTrue("hashCode", event1.hashCode() == event1b.hashCode()); - assertTrue("hashCode", event2.hashCode() == event2b.hashCode()); - - assertTrue("hashCode", event1.hashCode() != event2.hashCode()); - assertTrue("hashCode", event2.hashCode() != event1.hashCode()); - - trace.dispose(); - } - - // ------------------------------------------------------------------------ - // equals - // ------------------------------------------------------------------------ - - @Test - public void testEqualsReflexivity() { - assertTrue("equals", fEvent1.equals(fEvent1)); - assertTrue("equals", fEvent2.equals(fEvent2)); - - assertFalse("equals", fEvent1.equals(fEvent2)); - assertFalse("equals", fEvent2.equals(fEvent1)); - } - - @Test - public void testEqualsSymmetry() { - final ITmfEvent event1 = new TmfEvent(fEvent1); - final ITmfEvent event2 = new TmfEvent(fEvent2); - - assertTrue("equals", event1.equals(fEvent1)); - assertTrue("equals", fEvent1.equals(event1)); - - assertTrue("equals", event2.equals(fEvent2)); - assertTrue("equals", fEvent2.equals(event2)); - } - - @Test - public void testEqualsTransivity() { - final ITmfEvent event1 = new TmfEvent(fEvent1); - final ITmfEvent event2 = new TmfEvent(fEvent1); - final ITmfEvent event3 = new TmfEvent(fEvent1); - - assertTrue("equals", event1.equals(event2)); - assertTrue("equals", event2.equals(event3)); - assertTrue("equals", event1.equals(event3)); - } - - @Test - public void testEqualsNull() { - assertFalse("equals", fEvent1.equals(null)); - assertFalse("equals", fEvent2.equals(null)); - } - - @Test - public void testNonEqualClasses() { - assertFalse("equals", fEvent1.equals(fEvent1.getType())); - assertFalse("equals", fEvent1.equals(null)); - } - - @Test - public void testNonEqualTraces() { - final ITmfTrace trace1 = openTrace(); - final ITmfTrace trace2 = openTrace(); - - final ITmfEvent event1 = new TmfEvent(trace1, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - ITmfEvent event2 = new TmfEvent(trace1, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - assertTrue("equals", event1.equals(event2)); - assertTrue("equals", event2.equals(event1)); - - event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - assertFalse("equals", event1.equals(event2)); - assertFalse("equals", event2.equals(event1)); - - event2 = new TmfEvent(trace2, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - assertFalse("equals", event1.equals(event2)); - assertFalse("equals", event2.equals(event1)); - - trace1.dispose(); - trace2.dispose(); - } - - @Test - public void testNonEqualRanks() { - final ITmfEvent event1 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - ITmfEvent event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - assertTrue("equals", event1.equals(event2)); - assertTrue("equals", event2.equals(event1)); - - event2 = new TmfEvent(null, 1, fTimestamp1, fSource, fType, fContent1, fReference1); - assertFalse("equals", event1.equals(event2)); - assertFalse("equals", event2.equals(event1)); - } - - @Test - public void testNonEqualTimestamps() { - final ITmfEvent event1 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - ITmfEvent event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - assertTrue("equals", event1.equals(event2)); - assertTrue("equals", event2.equals(event1)); - - event2 = new TmfEvent(null, 0, fTimestamp2, fSource, fType, fContent1, fReference1); - assertFalse("equals", event1.equals(event2)); - assertFalse("equals", event2.equals(event1)); - - event2 = new TmfEvent(null, 0, null, fSource, fType, fContent1, fReference1); - assertFalse("equals", event1.equals(event2)); - assertFalse("equals", event2.equals(event1)); - } - - @Test - public void testNonEqualSources() { - final ITmfEvent event1 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - ITmfEvent event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - assertTrue("equals", event1.equals(event2)); - assertTrue("equals", event2.equals(event1)); - - event2 = new TmfEvent(null, 0, fTimestamp1, fSource + "x", fType, fContent1, fReference1); - assertFalse("equals", event1.equals(event2)); - assertFalse("equals", event2.equals(event1)); - - event2 = new TmfEvent(null, 0, fTimestamp1, null, fType, fContent1, fReference1); - assertFalse("equals", event1.equals(event2)); - assertFalse("equals", event2.equals(event1)); - } - - @Test - public void testNonEqualTypes() { - final ITmfEvent event1 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - ITmfEvent event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - assertTrue("equals", event1.equals(event2)); - assertTrue("equals", event2.equals(event1)); - - final String typeId = "OtherTestType"; - final String[] labels = new String[] { fLabel2, fLabel1 }; - final TmfEventType newType = new TmfEventType(fContext, typeId, TmfEventField.makeRoot(labels)); - - event2 = new TmfEvent(null, 0, fTimestamp1, fSource, newType, fContent1, fReference1); - assertFalse("equals", event1.equals(event2)); - assertFalse("equals", event2.equals(event1)); - - event2 = new TmfEvent(null, 0, fTimestamp1, fSource, null, fContent1, fReference1); - assertFalse("equals", event1.equals(event2)); - assertFalse("equals", event2.equals(event1)); - } - - @Test - public void testNonEqualContents() { - final ITmfEvent event1 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - ITmfEvent event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - assertTrue("equals", event1.equals(event2)); - assertTrue("equals", event2.equals(event1)); - - event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent2, fReference1); - assertFalse("equals", event1.equals(event2)); - assertFalse("equals", event2.equals(event1)); - - event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, null, fReference1); - assertFalse("equals", event1.equals(event2)); - assertFalse("equals", event2.equals(event1)); - } - - @Test - public void testNonEqualReferences() { - final ITmfEvent event1 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - ITmfEvent event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); - assertTrue("equals", event1.equals(event2)); - assertTrue("equals", event2.equals(event1)); - - event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference2); - assertFalse("equals", event1.equals(event2)); - assertFalse("equals", event2.equals(event1)); - - event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, null); - assertFalse("equals", event1.equals(event2)); - assertFalse("equals", event2.equals(event1)); - } - - // ------------------------------------------------------------------------ - // toString - // ------------------------------------------------------------------------ - - @Test - public void testToString() { - final String expected1 = "TmfEvent [fTimestamp=" + fTimestamp1 + ", fTrace=null, fRank=0, fSource=" + fSource - + ", fType=" + fType + ", fContent=" + fContent1 + ", fReference=" + fReference1 + "]"; - assertEquals("toString", expected1, fEvent1.toString()); - - final String expected2 = "TmfEvent [fTimestamp=" + fTimestamp2 + ", fTrace=null, fRank=1, fSource=" + fSource - + ", fType=" + fType + ", fContent=" + fContent2 + ", fReference=" + fReference2 + "]"; - assertEquals("toString", expected2, fEvent2.toString()); - } - - /** - * Test the .toString() with extended classes. - * It should print the correct class name. - */ - @Test - public void testToStringExtended() { - class ExtendedEvent extends TmfEvent { - ExtendedEvent(ITmfEvent event) { - super(event); - } - } - ExtendedEvent event = new ExtendedEvent(fEvent1); - String expected = "ExtendedEvent [fTimestamp=" + fTimestamp1 - + ", fTrace=null, fRank=0, fSource=" + fSource - + ", fType=" + fType + ", fContent=" + fContent1 - + ", fReference=" + fReference1 + "]"; - - assertEquals(expected, event.toString()); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfEventTypeManagerTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfEventTypeManagerTest.java deleted file mode 100644 index 13bdc3c38f..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfEventTypeManagerTest.java +++ /dev/null @@ -1,242 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.event; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.Set; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.eclipse.linuxtools.tmf.core.event.TmfEventTypeManager; -import org.junit.Test; - -/** - * Test suite for the TmfEventTypeManager class. - */ -@SuppressWarnings("javadoc") -public class TmfEventTypeManagerTest { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - private static final TmfEventTypeManager fInstance = TmfEventTypeManager.getInstance(); - - private final String fContext1 = "JUnit context 1"; - private final String fContext2 = "JUnit context 2"; - - private final String fTypeId1 = "Some type"; - private final String fTypeId2 = "Some other type"; - private final String fTypeId3 = "Yet another type"; - private final String fTypeId4 = "A final type"; - - private final String fLabel0 = "label1"; - private final String fLabel1 = "label2"; - private final String fLabel2 = "label3"; - - private final String[] fLabels0 = new String[] { }; - private final String[] fLabels1 = new String[] { fLabel0, fLabel1 }; - private final String[] fLabels2 = new String[] { fLabel1, fLabel0, fLabel2 }; - - private final TmfEventType fType0 = new TmfEventType(fContext1, fTypeId1, TmfEventField.makeRoot(fLabels0)); - private final TmfEventType fType1 = new TmfEventType(fContext1, fTypeId2, TmfEventField.makeRoot(fLabels1)); - private final TmfEventType fType2 = new TmfEventType(fContext2, fTypeId3, TmfEventField.makeRoot(fLabels2)); - private final TmfEventType fType3 = new TmfEventType(fContext2, fTypeId4, TmfEventField.makeRoot(fLabels1)); - - // ------------------------------------------------------------------------ - // Getters - // ------------------------------------------------------------------------ - - @Test - public void testGetContexts() { - fInstance.clear(); - fInstance.add(fContext1, fType0); - fInstance.add(fContext1, fType1); - fInstance.add(fContext2, fType2); - fInstance.add(fContext2, fType3); - - final String[] contexts = fInstance.getContexts(); - Arrays.sort(contexts); - assertEquals("getContexts", 2, contexts.length); - assertEquals("getContexts", fContext1, contexts[0]); - assertEquals("getContexts", fContext2, contexts[1]); - } - - @Test - public void testGetTypes() { - fInstance.clear(); - fInstance.add(fContext1, fType0); - fInstance.add(fContext1, fType1); - fInstance.add(fContext2, fType2); - fInstance.add(fContext2, fType3); - - Set types = fInstance.getTypes(fContext1); - assertEquals("getTypes", 2, types.size()); - assertTrue(types.contains(fType1)); - assertTrue(types.contains(fType0)); - - types = fInstance.getTypes(fContext2); - assertEquals("getTypes", 2, types.size()); - assertTrue(types.contains(fType2)); - assertTrue(types.contains(fType3)); - } - - @Test - public void testGetType() { - fInstance.clear(); - fInstance.add(fContext1, fType0); - fInstance.add(fContext1, fType1); - fInstance.add(fContext2, fType2); - fInstance.add(fContext2, fType3); - - ITmfEventType type = fInstance.getType(fContext1, fType0.getName()); - assertSame("getType", fType0, type); - type = fInstance.getType(fContext1, fType1.getName()); - assertSame("getType", fType1, type); - type = fInstance.getType(fContext1, fType2.getName()); - assertNull("getType", type); - type = fInstance.getType(fContext1, fType3.getName()); - assertNull("getType", type); - - type = fInstance.getType(fContext2, fType2.getName()); - assertSame("getType", fType2, type); - type = fInstance.getType(fContext2, fType3.getName()); - assertSame("getType", fType3, type); - type = fInstance.getType(fContext2, fType0.getName()); - assertNull("getType", type); - type = fInstance.getType(fContext2, fType1.getName()); - assertNull("getType", type); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Test - public void testClear() { - fInstance.clear(); - assertEquals("clear", 0, fInstance.getContexts().length); - assertEquals("clear", 0, fInstance.getTypes(null).size()); - assertNull("clear", fInstance.getType(null, null)); - assertEquals("clear", "TmfEventTypeManager [fEventTypes={}]", fInstance.toString()); - } - - @Test - public void testClearContext() { - fInstance.clear(); - fInstance.add(fContext1, fType0); - fInstance.add(fContext1, fType1); - fInstance.add(fContext2, fType2); - fInstance.add(fContext2, fType3); - - fInstance.clear(fContext1); - - final String[] contexts = fInstance.getContexts(); - assertEquals("clear context", 1, contexts.length); - assertEquals("clear context", fContext2, contexts[0]); - - Set types = fInstance.getTypes(fContext1); - assertEquals("clear context", 0, types.size()); - - ITmfEventType type = fInstance.getType(fContext1, fType0.getName()); - assertNull("clear context", type); - type = fInstance.getType(fContext1, fType1.getName()); - assertNull("clear context", type); - - types = fInstance.getTypes(fContext2); - assertEquals("clear context", 2, types.size()); - assertTrue(types.contains(fType2)); - assertTrue(types.contains(fType3)); - } - - @Test - public void testBasicAdd() { - fInstance.clear(); - fInstance.add(fContext1, fType0); - - final String[] contexts = fInstance.getContexts(); - assertEquals("add", 1, contexts.length); - assertEquals("add", fContext1, contexts[0]); - - final Set types = fInstance.getTypes(contexts[0]); - assertEquals("add", 1, types.size()); - assertTrue(types.contains(fType0)); - - ITmfEventType type = fInstance.getType(contexts[0], fType0.getName()); - assertSame("add", fType0, type); - - type = fInstance.getType(contexts[0], fType1.getName()); - assertNotSame("add", fType0, type); - } - - @Test - public void testAdd() { - fInstance.clear(); - fInstance.add(fContext1, fType0); - fInstance.add(fContext1, fType1); - fInstance.add(fContext2, fType2); - fInstance.add(fContext2, fType3); - - final String[] contexts = fInstance.getContexts(); - Arrays.sort(contexts); - assertEquals("add", 2, contexts.length); - assertEquals("add", fContext1, contexts[0]); - assertEquals("add", fContext2, contexts[1]); - - Set types = fInstance.getTypes(fContext1); - assertEquals("add", 2, types.size()); - assertTrue(types.contains(fType0)); - assertTrue(types.contains(fType1)); - - types = fInstance.getTypes(fContext2); - assertEquals("add", 2, types.size()); - assertTrue(types.contains(fType2)); - assertTrue(types.contains(fType3)); - - ITmfEventType type = fInstance.getType(fContext1, fType0.getName()); - assertSame("add", fType0, type); - type = fInstance.getType(fContext1, fType1.getName()); - assertSame("add", fType1, type); - type = fInstance.getType(fContext2, fType2.getName()); - assertSame("add", fType2, type); - type = fInstance.getType(fContext2, fType3.getName()); - assertSame("add", fType3, type); - - type = fInstance.getType(fContext1, fType2.getName()); - assertNull("add", type); - type = fInstance.getType(fContext2, fType0.getName()); - assertNull("add", type); - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Test - public void testToString() { - fInstance.clear(); - assertEquals("toString", "TmfEventTypeManager [fEventTypes={}]", fInstance.toString()); - - fInstance.add(fContext1, fType0); - assertEquals("toString", "TmfEventTypeManager [fEventTypes={" + fContext1 + "={" + fTypeId1 + "=" + fType0 + "}}]", fInstance.toString()); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfEventTypeTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfEventTypeTest.java deleted file mode 100644 index 4dbbb8b1e9..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfEventTypeTest.java +++ /dev/null @@ -1,233 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Adjusted for new Event Model - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.event; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.Collection; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.junit.Test; - -/** - * Test suite for the TmfEventType class. - */ -@SuppressWarnings("javadoc") -public class TmfEventTypeTest { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - private final String fContext1 = "JUnit context 1"; - private final String fContext2 = "JUnit context 2"; - - private final String fTypeId1 = "Some type"; - private final String fTypeId2 = "Some other type"; - - private final String fLabel0 = "label1"; - private final String fLabel1 = "label2"; - private final String fLabel2 = "label3"; - - private final String[] fLabels0 = new String[] { }; - private final String[] fLabels1 = new String[] { fLabel0, fLabel1 }; - private final String[] fLabels2 = new String[] { fLabel1, fLabel0, fLabel2 }; - - private final ITmfEventType fType0 = new TmfEventType(fContext1, fTypeId1, TmfEventField.makeRoot(fLabels0)); - private final ITmfEventType fType1 = new TmfEventType(fContext1, fTypeId2, TmfEventField.makeRoot(fLabels1)); - private final ITmfEventType fType2 = new TmfEventType(fContext2, fTypeId1, TmfEventField.makeRoot(fLabels2)); - private final ITmfEventType fType3 = new TmfEventType(fContext2, fTypeId2, TmfEventField.makeRoot(fLabels1)); - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - @Test - public void testDefaultConstructor() { - final ITmfEventType type = new TmfEventType(); - assertEquals("getContext", ITmfEventType.DEFAULT_CONTEXT_ID, type.getContext()); - assertEquals("getName", ITmfEventType.DEFAULT_TYPE_ID, type.getName()); - assertNull("getRootField", type.getRootField()); - assertEquals("getFieldNames", 0, type.getFieldNames().size()); - } - - @Test - public void testFullConstructor() { - final ITmfEventType type0 = new TmfEventType(fContext1, fTypeId1, TmfEventField.makeRoot(fLabels0)); - assertEquals("getContext", fContext1, type0.getContext()); - assertEquals("getName", fTypeId1, type0.getName()); - assertEquals("getRootField", TmfEventField.makeRoot(fLabels0), type0.getRootField()); - final Collection labels0 = type0.getFieldNames(); - assertEquals("getFieldNames length", fLabels0.length, labels0.size()); - assertArrayEquals(fLabels0, labels0.toArray(new String[labels0.size()])); - - final ITmfEventType type1 = new TmfEventType(fContext1, fTypeId1, TmfEventField.makeRoot(fLabels1)); - assertEquals("getContext", fContext1, type1.getContext()); - assertEquals("getName", fTypeId1, type1.getName()); - assertEquals("getRootField", TmfEventField.makeRoot(fLabels1), type1.getRootField()); - final Collection labels1 = type1.getFieldNames(); - assertEquals("getFieldNames length", fLabels1.length, labels1.size()); - assertArrayEquals(fLabels1, labels1.toArray(new String[labels1.size()])); - - final ITmfEventType type2 = new TmfEventType(fContext2, fTypeId2, TmfEventField.makeRoot(fLabels2)); - assertEquals("getContext", fContext2, type2.getContext()); - assertEquals("getName", fTypeId2, type2.getName()); - assertEquals("getRootField", TmfEventField.makeRoot(fLabels2), type2.getRootField()); - final Collection labels2 = type2.getFieldNames(); - assertEquals("getFieldNames length", fLabels2.length, labels2.size()); - assertArrayEquals(fLabels2, labels2.toArray(new String[labels2.size()])); - } - - @Test - public void testConstructorCornerCases() { - try { - new TmfEventType(null, fTypeId1, null); - fail("TmfEventType: null context"); - } catch (final IllegalArgumentException e) { - } - - try { - new TmfEventType(fContext1, null, null); - fail("TmfEventType: null type"); - } catch (final IllegalArgumentException e) { - } - } - - @Test - public void testCopyConstructor() { - final TmfEventType original = new TmfEventType(fContext1, fTypeId1, TmfEventField.makeRoot(fLabels1)); - final TmfEventType copy = new TmfEventType(original); - - assertEquals("getContext", fContext1, copy.getContext()); - assertEquals("getName", fTypeId1, copy.getName()); - assertEquals("getRootField", TmfEventField.makeRoot(fLabels1), copy.getRootField()); - final Collection labels1 = copy.getFieldNames(); - assertEquals("getFieldNames length", fLabels1.length, labels1.size()); - assertArrayEquals(fLabels1, labels1.toArray(new String[labels1.size()])); - } - - @Test - public void testCopyConstructorCornerCases() { - try { - new TmfEventType(null); - fail("TmfEventType: null argument"); - } catch (final IllegalArgumentException e) { - } - } - - // ------------------------------------------------------------------------ - // hashCode - // ------------------------------------------------------------------------ - - @Test - public void testHashCode() { - final TmfEventType copy1 = new TmfEventType(fType0); - - assertTrue("hashCode", fType0.hashCode() == copy1.hashCode()); - assertTrue("hashCode", fType0.hashCode() != fType3.hashCode()); - } - - // ------------------------------------------------------------------------ - // equals - // ------------------------------------------------------------------------ - - @Test - public void testEqualsReflexivity() { - assertTrue("equals", fType0.equals(fType0)); - assertTrue("equals", fType3.equals(fType3)); - - assertFalse("equals", fType0.equals(fType3)); - assertFalse("equals", fType3.equals(fType0)); - } - - @Test - public void testEqualsSymmetry() { - final TmfEventType copy0 = new TmfEventType(fType0); - assertTrue("equals", fType0.equals(copy0)); - assertTrue("equals", copy0.equals(fType0)); - - final TmfEventType copy1 = new TmfEventType(fType1); - assertTrue("equals", fType1.equals(copy1)); - assertTrue("equals", copy1.equals(fType1)); - - final TmfEventType copy2 = new TmfEventType(fType2); - assertTrue("equals", fType2.equals(copy2)); - assertTrue("equals", copy2.equals(fType2)); - } - - @Test - public void testEqualsTransivity() { - TmfEventType copy1 = new TmfEventType(fType1); - TmfEventType copy2 = new TmfEventType(copy1); - assertTrue("equals", fType1.equals(copy1)); - assertTrue("equals", copy1.equals(copy2)); - assertTrue("equals", fType1.equals(copy2)); - - copy1 = new TmfEventType(fType2); - copy2 = new TmfEventType(copy1); - assertTrue("equals", fType2.equals(copy1)); - assertTrue("equals", copy1.equals(copy2)); - assertTrue("equals", fType2.equals(copy2)); - - copy1 = new TmfEventType(fType3); - copy2 = new TmfEventType(copy1); - assertTrue("equals", fType3.equals(copy1)); - assertTrue("equals", copy1.equals(copy2)); - assertTrue("equals", fType3.equals(copy2)); - } - - @Test - public void testEqualsNull() { - assertFalse("equals", fType0.equals(null)); - assertFalse("equals", fType3.equals(null)); - } - - @Test - public void testNonEquals() { - assertFalse("equals", fType0.equals(fType1)); - assertFalse("equals", fType1.equals(fType2)); - assertFalse("equals", fType2.equals(fType3)); - assertFalse("equals", fType3.equals(fType0)); - } - - @Test - public void testNonEqualsClasses() { - assertFalse("equals", fType1.equals(fLabels1)); - } - - // ------------------------------------------------------------------------ - // toString - // ------------------------------------------------------------------------ - - @Test - public void testToString() { - final String expected1 = "TmfEventType [fContext=" + ITmfEventType.DEFAULT_CONTEXT_ID + - ", fTypeId=" + ITmfEventType.DEFAULT_TYPE_ID + "]"; - final TmfEventType type1 = new TmfEventType(); - assertEquals("toString", expected1, type1.toString()); - - final String expected2 = "TmfEventType [fContext=" + fContext1 + ", fTypeId=" + fTypeId1 + "]"; - final TmfEventType type2 = new TmfEventType(fContext1, fTypeId1, TmfEventField.makeRoot(fLabels1)); - assertEquals("toString", expected2, type2.toString()); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfNanoTimestampTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfNanoTimestampTest.java deleted file mode 100644 index 55f040a9be..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfNanoTimestampTest.java +++ /dev/null @@ -1,293 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Modified from TmfSimpleTimestamp to use nanosecond scale - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.event; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.junit.Test; - -/** - * Test suite for the TmfNanoTimestampTest class. - */ -@SuppressWarnings("javadoc") -public class TmfNanoTimestampTest { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - private final ITmfTimestamp ts0 = new TmfNanoTimestamp(); - private final ITmfTimestamp ts1 = new TmfNanoTimestamp(12345); - private final ITmfTimestamp ts2 = new TmfNanoTimestamp(-1234); - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - @Test - public void testDefaultConstructor() { - assertEquals("getValue", 0, ts0.getValue()); - assertEquals("getscale", -9, ts0.getScale()); - assertEquals("getPrecision", 0, ts0.getPrecision()); - } - - @Test - public void testFullConstructor() { - assertEquals("getValue", 12345, ts1.getValue()); - assertEquals("getscale", -9, ts1.getScale()); - assertEquals("getPrecision", 0, ts1.getPrecision()); - } - - @Test - public void testCopyConstructor() { - final ITmfTimestamp copy = new TmfNanoTimestamp(ts1); - - assertEquals("getValue", ts1.getValue(), copy.getValue()); - assertEquals("getscale", ts1.getScale(), copy.getScale()); - assertEquals("getPrecision", ts1.getPrecision(), copy.getPrecision()); - - assertEquals("getValue", 12345, copy.getValue()); - assertEquals("getscale", -9, copy.getScale()); - assertEquals("getPrecision", 0, copy.getPrecision()); - } - - @Test - public void testCopyBadTimestamp() { - try { - new TmfNanoTimestamp(null); - fail("TmfNanoTimestamp: null argument"); - } catch (final NullPointerException e) { - } - } - - // ------------------------------------------------------------------------ - // equals - // ------------------------------------------------------------------------ - - @Test - public void testEqualsReflexivity() { - assertTrue("equals", ts0.equals(ts0)); - assertTrue("equals", ts1.equals(ts1)); - assertTrue("equals", ts2.equals(ts2)); - - assertTrue("equals", !ts0.equals(ts1)); - assertTrue("equals", !ts0.equals(ts2)); - - assertTrue("equals", !ts1.equals(ts0)); - assertTrue("equals", !ts1.equals(ts2)); - - assertTrue("equals", !ts2.equals(ts0)); - assertTrue("equals", !ts2.equals(ts1)); - } - - @Test - public void testEqualsSymmetry() { - final ITmfTimestamp ts0copy = new TmfNanoTimestamp(ts0); - assertTrue("equals", ts0.equals(ts0copy)); - assertTrue("equals", ts0copy.equals(ts0)); - - final ITmfTimestamp ts1copy = new TmfNanoTimestamp(ts1); - assertTrue("equals", ts1.equals(ts1copy)); - assertTrue("equals", ts1copy.equals(ts1)); - } - - @Test - public void testEqualsTransivity() { - final ITmfTimestamp ts0copy1 = new TmfNanoTimestamp(ts0); - final ITmfTimestamp ts0copy2 = new TmfNanoTimestamp(ts0copy1); - assertTrue("equals", ts0.equals(ts0copy1)); - assertTrue("equals", ts0copy1.equals(ts0copy2)); - assertTrue("equals", ts0.equals(ts0copy2)); - - final ITmfTimestamp ts1copy1 = new TmfNanoTimestamp(ts1); - final ITmfTimestamp ts1copy2 = new TmfNanoTimestamp(ts1copy1); - assertTrue("equals", ts1.equals(ts1copy1)); - assertTrue("equals", ts1copy1.equals(ts1copy2)); - assertTrue("equals", ts1.equals(ts1copy2)); - } - - @Test - public void testEqualsNull() { - assertTrue("equals", !ts0.equals(null)); - assertTrue("equals", !ts1.equals(null)); - assertTrue("equals", !ts2.equals(null)); - } - - @Test - public void testEqualsNonTimestamp() { - assertFalse("equals", ts0.equals(ts0.toString())); - } - - // ------------------------------------------------------------------------ - // toString - // ------------------------------------------------------------------------ - - @Test - public void testToString() { - DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS"); - Date d0 = new Date(ts0.getValue() / 1000000); - Date d1 = new Date(ts1.getValue() / 1000000); - Date d2 = new Date(ts2.getValue() / 1000000 - 1); - assertEquals("toString", df.format(d0) + " 000 000", ts0.toString()); - assertEquals("toString", df.format(d1) + " 012 345", ts1.toString()); - assertEquals("toString", df.format(d2) + " 998 766", ts2.toString()); - } - - // ------------------------------------------------------------------------ - // hashCode - // ------------------------------------------------------------------------ - - @Test - public void testHashCode() { - final ITmfTimestamp ts0copy = new TmfTimestamp(ts0); - final ITmfTimestamp ts1copy = new TmfTimestamp(ts1); - final ITmfTimestamp ts2copy = new TmfTimestamp(ts2); - - assertTrue("hashCode", ts0.hashCode() == ts0copy.hashCode()); - assertTrue("hashCode", ts1.hashCode() == ts1copy.hashCode()); - assertTrue("hashCode", ts2.hashCode() == ts2copy.hashCode()); - - assertTrue("hashCode", ts0.hashCode() != ts1.hashCode()); - } - - // ------------------------------------------------------------------------ - // normalize - // ------------------------------------------------------------------------ - - @Test - public void testNormalizeScale0() { - ITmfTimestamp ts = ts0.normalize(0, 0); - assertEquals("getValue", 0, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(12345, 0); - assertEquals("getValue", 12345, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(10, 0); - assertEquals("getValue", 10, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(-10, 0); - assertEquals("getValue", -10, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - } - - @Test - public void testNormalizeScaleNot0() { - ITmfTimestamp ts = ts0.normalize(0, 1); - assertEquals("getValue", 0, ts.getValue()); - assertEquals("getscale", 1, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(12345, 1); - assertEquals("getValue", 12345, ts.getValue()); - assertEquals("getscale", 1, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(10, 1); - assertEquals("getValue", 10, ts.getValue()); - assertEquals("getscale", 1, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(-10, 1); - assertEquals("getValue", -10, ts.getValue()); - assertEquals("getscale", 1, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - } - - // ------------------------------------------------------------------------ - // compareTo - // ------------------------------------------------------------------------ - - @Test - public void testBasicCompareTo() { - final ITmfTimestamp tstamp1 = new TmfNanoTimestamp(900); - final ITmfTimestamp tstamp2 = new TmfNanoTimestamp(1000); - final ITmfTimestamp tstamp3 = new TmfNanoTimestamp(1100); - - assertTrue(tstamp1.compareTo(tstamp1) == 0); - - assertTrue("CompareTo", tstamp1.compareTo(tstamp2) < 0); - assertTrue("CompareTo", tstamp1.compareTo(tstamp3) < 0); - - assertTrue("CompareTo", tstamp2.compareTo(tstamp1) > 0); - assertTrue("CompareTo", tstamp2.compareTo(tstamp3) < 0); - - assertTrue("CompareTo", tstamp3.compareTo(tstamp1) > 0); - assertTrue("CompareTo", tstamp3.compareTo(tstamp2) > 0); - } - - @Test - public void testCompareTo() { - final ITmfTimestamp ts0a = new TmfTimestamp(0, 2, 0); - final ITmfTimestamp ts1a = new TmfTimestamp(123450, -10); - final ITmfTimestamp ts2a = new TmfTimestamp(-12340, -10); - - assertTrue(ts1.compareTo(ts1) == 0); - - assertTrue("CompareTo", ts0.compareTo(ts0a) == 0); - assertTrue("CompareTo", ts1.compareTo(ts1a) == 0); - assertTrue("CompareTo", ts2.compareTo(ts2a) == 0); - } - - // ------------------------------------------------------------------------ - // getDelta - // ------------------------------------------------------------------------ - - @Test - public void testDelta() { - // Delta for same scale and precision (delta > 0) - TmfTimestamp tstamp0 = new TmfNanoTimestamp(10); - TmfTimestamp tstamp1 = new TmfNanoTimestamp(5); - TmfTimestamp expectd = new TmfNanoTimestamp(5); - - ITmfTimestamp delta = tstamp0.getDelta(tstamp1); - assertEquals("getDelta", 0, delta.compareTo(expectd, false)); - - // Delta for same scale and precision (delta < 0) - tstamp0 = new TmfTimestamp(5); - tstamp1 = new TmfTimestamp(10); - expectd = new TmfTimestamp(-5); - - delta = tstamp0.getDelta(tstamp1); - assertEquals("getDelta", 0, delta.compareTo(expectd, false)); - } - - @Test - public void testDelta2() { - // Delta for different scale and same precision (delta > 0) - final TmfTimestamp tstamp0 = new TmfNanoTimestamp(10); - final TmfTimestamp tstamp1 = new TmfTimestamp(1, -8); - final TmfTimestamp expectd = new TmfTimestamp(0, 0); - - final ITmfTimestamp delta = tstamp0.getDelta(tstamp1); - assertEquals("getDelta", 0, delta.compareTo(expectd, false)); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfSimpleTimestampTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfSimpleTimestampTest.java deleted file mode 100644 index a2f5604254..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfSimpleTimestampTest.java +++ /dev/null @@ -1,293 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.event; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfSimpleTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.junit.Test; - -/** - * Test suite for the TmfSimpleTimestampTest class. - */ -@SuppressWarnings("javadoc") -public class TmfSimpleTimestampTest { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - private final ITmfTimestamp ts0 = new TmfSimpleTimestamp(); - private final ITmfTimestamp ts1 = new TmfSimpleTimestamp(12345); - private final ITmfTimestamp ts2 = new TmfSimpleTimestamp(-1234); - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - @Test - public void testDefaultConstructor() { - assertEquals("getValue", 0, ts0.getValue()); - assertEquals("getscale", 0, ts0.getScale()); - assertEquals("getPrecision", 0, ts0.getPrecision()); - } - - @Test - public void testFullConstructor() { - assertEquals("getValue", 12345, ts1.getValue()); - assertEquals("getscale", 0, ts1.getScale()); - assertEquals("getPrecision", 0, ts1.getPrecision()); - } - - @Test - public void testCopyConstructor() { - final ITmfTimestamp copy = new TmfSimpleTimestamp(ts1); - - assertEquals("getValue", ts1.getValue(), copy.getValue()); - assertEquals("getscale", ts1.getScale(), copy.getScale()); - assertEquals("getPrecision", ts1.getPrecision(), copy.getPrecision()); - - assertEquals("getValue", 12345, copy.getValue()); - assertEquals("getscale", 0, copy.getScale()); - assertEquals("getPrecision", 0, copy.getPrecision()); - } - - @Test - public void testCopyBadTimestamp() { - try { - new TmfSimpleTimestamp(null); - fail("TmfSimpleTimestamp: null argument"); - } catch (final NullPointerException e) { - } - } - - // ------------------------------------------------------------------------ - // equals - // ------------------------------------------------------------------------ - - @Test - public void testEqualsReflexivity() { - assertTrue("equals", ts0.equals(ts0)); - assertTrue("equals", ts1.equals(ts1)); - assertTrue("equals", ts2.equals(ts2)); - - assertTrue("equals", !ts0.equals(ts1)); - assertTrue("equals", !ts0.equals(ts2)); - - assertTrue("equals", !ts1.equals(ts0)); - assertTrue("equals", !ts1.equals(ts2)); - - assertTrue("equals", !ts2.equals(ts0)); - assertTrue("equals", !ts2.equals(ts1)); - } - - @Test - public void testEqualsSymmetry() { - final ITmfTimestamp ts0copy = new TmfSimpleTimestamp(ts0); - assertTrue("equals", ts0.equals(ts0copy)); - assertTrue("equals", ts0copy.equals(ts0)); - - final ITmfTimestamp ts1copy = new TmfSimpleTimestamp(ts1); - assertTrue("equals", ts1.equals(ts1copy)); - assertTrue("equals", ts1copy.equals(ts1)); - } - - @Test - public void testEqualsTransivity() { - final ITmfTimestamp ts0copy1 = new TmfSimpleTimestamp(ts0); - final ITmfTimestamp ts0copy2 = new TmfSimpleTimestamp(ts0copy1); - assertTrue("equals", ts0.equals(ts0copy1)); - assertTrue("equals", ts0copy1.equals(ts0copy2)); - assertTrue("equals", ts0.equals(ts0copy2)); - - final ITmfTimestamp ts1copy1 = new TmfSimpleTimestamp(ts1); - final ITmfTimestamp ts1copy2 = new TmfSimpleTimestamp(ts1copy1); - assertTrue("equals", ts1.equals(ts1copy1)); - assertTrue("equals", ts1copy1.equals(ts1copy2)); - assertTrue("equals", ts1.equals(ts1copy2)); - } - - @Test - public void testEqualsNull() { - assertTrue("equals", !ts0.equals(null)); - assertTrue("equals", !ts1.equals(null)); - assertTrue("equals", !ts2.equals(null)); - } - - @Test - public void testEqualsNonTimestamp() { - assertFalse("equals", ts0.equals(ts0.toString())); - } - - // ------------------------------------------------------------------------ - // toString - // ------------------------------------------------------------------------ - - @Test - public void testToString() { - DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS"); - Date d0 = new Date(ts0.getValue()*1000); - Date d1 = new Date(ts1.getValue()*1000); - Date d2 = new Date(ts2.getValue()*1000); - assertEquals("toString", df.format(d0) + " 000 000", ts0.toString()); - assertEquals("toString", df.format(d1) + " 000 000", ts1.toString()); - assertEquals("toString", df.format(d2) + " 000 000", ts2.toString()); - } - - // ------------------------------------------------------------------------ - // hashCode - // ------------------------------------------------------------------------ - - @Test - public void testHashCode() { - final ITmfTimestamp ts0copy = new TmfTimestamp(ts0); - final ITmfTimestamp ts1copy = new TmfTimestamp(ts1); - final ITmfTimestamp ts2copy = new TmfTimestamp(ts2); - - assertTrue("hashCode", ts0.hashCode() == ts0copy.hashCode()); - assertTrue("hashCode", ts1.hashCode() == ts1copy.hashCode()); - assertTrue("hashCode", ts2.hashCode() == ts2copy.hashCode()); - - assertTrue("hashCode", ts0.hashCode() != ts1.hashCode()); - } - - // ------------------------------------------------------------------------ - // normalize - // ------------------------------------------------------------------------ - - @Test - public void testNormalizeScale0() { - ITmfTimestamp ts = ts0.normalize(0, 0); - assertEquals("getValue", 0, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(12345, 0); - assertEquals("getValue", 12345, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(10, 0); - assertEquals("getValue", 10, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(-10, 0); - assertEquals("getValue", -10, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - } - - @Test - public void testNormalizeScaleNot0() { - ITmfTimestamp ts = ts0.normalize(0, 1); - assertEquals("getValue", 0, ts.getValue()); - assertEquals("getscale", 1, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(12345, 1); - assertEquals("getValue", 12345, ts.getValue()); - assertEquals("getscale", 1, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(10, 1); - assertEquals("getValue", 10, ts.getValue()); - assertEquals("getscale", 1, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(-10, 1); - assertEquals("getValue", -10, ts.getValue()); - assertEquals("getscale", 1, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - } - - // ------------------------------------------------------------------------ - // compareTo - // ------------------------------------------------------------------------ - - @Test - public void testBasicCompareTo() { - final ITmfTimestamp tstamp1 = new TmfSimpleTimestamp(900); - final ITmfTimestamp tstamp2 = new TmfSimpleTimestamp(1000); - final ITmfTimestamp tstamp3 = new TmfSimpleTimestamp(1100); - - assertTrue(tstamp1.compareTo(tstamp1) == 0); - - assertTrue("CompareTo", tstamp1.compareTo(tstamp2) < 0); - assertTrue("CompareTo", tstamp1.compareTo(tstamp3) < 0); - - assertTrue("CompareTo", tstamp2.compareTo(tstamp1) > 0); - assertTrue("CompareTo", tstamp2.compareTo(tstamp3) < 0); - - assertTrue("CompareTo", tstamp3.compareTo(tstamp1) > 0); - assertTrue("CompareTo", tstamp3.compareTo(tstamp2) > 0); - } - - @Test - public void testCompareTo() { - final ITmfTimestamp ts0a = new TmfTimestamp(0, 2, 0); - final ITmfTimestamp ts1a = new TmfTimestamp(123450, -1); - final ITmfTimestamp ts2a = new TmfTimestamp(-12340, -1); - - assertTrue(ts1.compareTo(ts1) == 0); - - assertTrue("CompareTo", ts0.compareTo(ts0a) == 0); - assertTrue("CompareTo", ts1.compareTo(ts1a) == 0); - assertTrue("CompareTo", ts2.compareTo(ts2a) == 0); - } - - // ------------------------------------------------------------------------ - // getDelta - // ------------------------------------------------------------------------ - - @Test - public void testDelta() { - // Delta for same scale and precision (delta > 0) - TmfTimestamp tstamp0 = new TmfSimpleTimestamp(10); - TmfTimestamp tstamp1 = new TmfSimpleTimestamp(5); - TmfTimestamp expectd = new TmfSimpleTimestamp(5); - - ITmfTimestamp delta = tstamp0.getDelta(tstamp1); - assertEquals("getDelta", 0, delta.compareTo(expectd, false)); - - // Delta for same scale and precision (delta < 0) - tstamp0 = new TmfTimestamp(5); - tstamp1 = new TmfTimestamp(10); - expectd = new TmfTimestamp(-5); - - delta = tstamp0.getDelta(tstamp1); - assertEquals("getDelta", 0, delta.compareTo(expectd, false)); - } - - @Test - public void testDelta2() { - // Delta for different scale and same precision (delta > 0) - final TmfTimestamp tstamp0 = new TmfSimpleTimestamp(10); - final TmfTimestamp tstamp1 = new TmfTimestamp(1, 1); - final TmfTimestamp expectd = new TmfTimestamp(0, 0); - - final ITmfTimestamp delta = tstamp0.getDelta(tstamp1); - assertEquals("getDelta", 0, delta.compareTo(expectd, false)); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimePreferencesTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimePreferencesTest.java deleted file mode 100644 index 141bcf9951..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimePreferencesTest.java +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.event; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.util.Map; -import java.util.TimeZone; - -import org.eclipse.core.runtime.preferences.DefaultScope; -import org.eclipse.core.runtime.preferences.IEclipsePreferences; -import org.eclipse.core.runtime.preferences.InstanceScope; -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimePreferencesConstants; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimePreferences; -import org.junit.Test; -import org.osgi.service.prefs.BackingStoreException; - -/** - * Test suite for the TmfTimePreferences class. - */ -public class TmfTimePreferencesTest { - - private static final String TIME_PATTERN = "HH:mm:ss.SSS SSS SSS"; - private static final String INTERVAL_PATTERN = "TTT.SSS SSS SSS"; - - /** - * Test that the preferences get initialized to the default - */ - @Test - public void testInit() { - assertEquals(DefaultScope.INSTANCE.getNode(Activator.PLUGIN_ID).get(ITmfTimePreferencesConstants.DATIME, null), ITmfTimePreferencesConstants.TIME_HOUR_FMT); - } - - /** - * Test that getInstance returns an instance - */ - @Test - public void testGetInstance() { - assertNotNull(TmfTimePreferences.getInstance()); - } - - /** - * Test that getTimePattern returns the appropriate time pattern (from the default) - */ - @Test - public void testGetTimePattern() { - assertEquals(TIME_PATTERN, TmfTimePreferences.getInstance().getTimePattern()); - } - - /** - * Test that getIntervalPattern returns the appropriate interval pattern (from the default) - */ - @Test - public void testGetIntervalPattern() { - assertEquals(INTERVAL_PATTERN, TmfTimePreferences.getInstance().getIntervalPattern()); - } - - /** - * Test that getTimeZone returns the appropriate time zone (from the default) - */ - @Test - public void testGetTimeZone() { - assertEquals(TimeZone.getDefault(), TmfTimePreferences.getInstance().getTimeZone()); - } - - /** - * Test that getPreferenceMap returns the appropriate map even after preferences get modified - * and make sure it doesn't affect the defaults - */ - @Test - public void testGetPreferenceMap() { - Map defaultPreferenceMap = TmfTimePreferences.getInstance().getDefaultPreferenceMap(); - assertEquals(ITmfTimePreferencesConstants.TIME_HOUR_FMT, defaultPreferenceMap.get(ITmfTimePreferencesConstants.DATIME)); - - // Modify the preferences - String testValue = ITmfTimePreferencesConstants.TIME_HOUR_FMT + "foo"; - IEclipsePreferences node = InstanceScope.INSTANCE.getNode(Activator.PLUGIN_ID); - node.put(ITmfTimePreferencesConstants.DATIME, testValue); - try { - node.flush(); - } catch (BackingStoreException e) { - } - // Make sure the modification is in the map - Map preferenceMap = TmfTimePreferences.getInstance().getPreferenceMap(); - assertEquals(testValue, preferenceMap.get(ITmfTimePreferencesConstants.DATIME)); - - // Make sure the default is still the same - defaultPreferenceMap = TmfTimePreferences.getInstance().getDefaultPreferenceMap(); - assertEquals(ITmfTimePreferencesConstants.TIME_HOUR_FMT, defaultPreferenceMap.get(ITmfTimePreferencesConstants.DATIME)); - } - - /** - * Test that computeTimePattern computes the appropriate time pattern from a preference map (from the default) - */ - @Test - public void testComputeTimePattern() { - assertEquals(TIME_PATTERN, TmfTimePreferences.getInstance().computeTimePattern(TmfTimePreferences.getInstance().getPreferenceMap())); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimeRangeTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimeRangeTest.java deleted file mode 100644 index ba7a99db46..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimeRangeTest.java +++ /dev/null @@ -1,373 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Adjusted for new Event Model - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.event; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.junit.Test; - -/** - * Test suite for the TmfTimeRange class. - */ -@SuppressWarnings("javadoc") -public class TmfTimeRangeTest { - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - @Test - public void testConstructor() { - final ITmfTimestamp ts1 = new TmfTimestamp(12345); - final ITmfTimestamp ts2 = new TmfTimestamp(12350); - final TmfTimeRange range = new TmfTimeRange(ts1, ts2); - - assertEquals("startTime", ts1, range.getStartTime()); - assertEquals("endTime", ts2, range.getEndTime()); - } - - @Test - public void testBadConstructor() { - try { - new TmfTimeRange(TmfTimestamp.BIG_BANG, null); - fail("TmfTimeRange: bad end time"); - } catch (final IllegalArgumentException e) { - // Success - } - - try { - new TmfTimeRange(null, TmfTimestamp.BIG_CRUNCH); - fail("TmfTimeRange: bad start time"); - } catch (final IllegalArgumentException e) { - // Success - } - } - - @Test - public void testOpenRange1() { - final ITmfTimestamp ts2 = new TmfTimestamp(12350); - final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, ts2); - - assertEquals("startTime", TmfTimestamp.BIG_BANG, range.getStartTime()); - assertEquals("endTime", ts2, range.getEndTime()); - } - - @Test - public void testOpenRange2() { - final ITmfTimestamp ts1 = new TmfTimestamp(12345); - final TmfTimeRange range = new TmfTimeRange(ts1, TmfTimestamp.BIG_CRUNCH); - - assertEquals("startTime", ts1, range.getStartTime()); - assertEquals("endTime", TmfTimestamp.BIG_CRUNCH, range.getEndTime()); - } - - @Test - public void testOpenRange3() { - final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - - assertEquals("startTime", TmfTimestamp.BIG_BANG, range.getStartTime()); - assertEquals("endTime", TmfTimestamp.BIG_CRUNCH, range.getEndTime()); - } - - @Test - public void testCopyConstructor() { - final ITmfTimestamp ts1 = new TmfTimestamp(12345); - final ITmfTimestamp ts2 = new TmfTimestamp(12350); - final TmfTimeRange range0 = new TmfTimeRange(ts1, ts2); - final TmfTimeRange range1 = new TmfTimeRange(range0); - - assertEquals("startTime", ts1, range1.getStartTime()); - assertEquals("endTime", ts2, range1.getEndTime()); - - final TmfTimeRange range2 = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - final TmfTimeRange range3 = new TmfTimeRange(range2); - - assertEquals("startTime", TmfTimestamp.BIG_BANG, range3.getStartTime()); - assertEquals("endTime", TmfTimestamp.BIG_CRUNCH, range3.getEndTime()); - } - - @Test - public void testCopyConstructor2() { - try { - new TmfTimeRange(null); - fail("TmfTimeRange: null argument"); - } catch (final IllegalArgumentException e) { - // Success - } - } - - // ------------------------------------------------------------------------ - // hashCode - // ------------------------------------------------------------------------ - - @Test - public void testHashCode() { - final ITmfTimestamp ts1 = new TmfTimestamp(12345); - final ITmfTimestamp ts2 = new TmfTimestamp(12350); - final TmfTimeRange range1 = new TmfTimeRange(ts1, ts2); - final TmfTimeRange range1b = new TmfTimeRange(range1); - final TmfTimeRange range2 = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - final TmfTimeRange range2b = new TmfTimeRange(range2); - - assertTrue("hashCode", range1.hashCode() == range1b.hashCode()); - assertTrue("hashCode", range2.hashCode() == range2b.hashCode()); - - assertTrue("hashCode", range1.hashCode() != range2.hashCode()); - } - - // ------------------------------------------------------------------------ - // equals - // ------------------------------------------------------------------------ - - @Test - public void testEqualsReflexivity() { - final ITmfTimestamp ts1 = new TmfTimestamp(12345); - final ITmfTimestamp ts2 = new TmfTimestamp(12350); - final TmfTimeRange range1 = new TmfTimeRange(ts1, ts2); - final TmfTimeRange range2 = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - - assertTrue("equals", range1.equals(range1)); - assertTrue("equals", range2.equals(range2)); - - assertTrue("equals", !range1.equals(range2)); - assertTrue("equals", !range2.equals(range1)); - } - - @Test - public void testEqualsSymmetry() { - final ITmfTimestamp ts1 = new TmfTimestamp(12345); - final ITmfTimestamp ts2 = new TmfTimestamp(12350); - final TmfTimeRange range1a = new TmfTimeRange(ts1, ts2); - final TmfTimeRange range1b = new TmfTimeRange(ts1, ts2); - - final TmfTimeRange range2a = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - final TmfTimeRange range2b = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - - assertTrue("equals", range1a.equals(range1b)); - assertTrue("equals", range1b.equals(range1a)); - - assertTrue("equals", range2a.equals(range2b)); - assertTrue("equals", range2b.equals(range2a)); - } - - @Test - public void testEqualsTransivity() { - final ITmfTimestamp ts1 = new TmfTimestamp(12345); - final ITmfTimestamp ts2 = new TmfTimestamp(12350); - final TmfTimeRange range1a = new TmfTimeRange(ts1, ts2); - final TmfTimeRange range1b = new TmfTimeRange(ts1, ts2); - final TmfTimeRange range1c = new TmfTimeRange(ts1, ts2); - - assertTrue("equals", range1a.equals(range1b)); - assertTrue("equals", range1b.equals(range1c)); - assertTrue("equals", range1a.equals(range1c)); - } - - @Test - public void testEqualsNull() { - final ITmfTimestamp ts1 = new TmfTimestamp(12345); - final ITmfTimestamp ts2 = new TmfTimestamp(12350); - final TmfTimeRange range1 = new TmfTimeRange(ts1, ts2); - - assertTrue("equals", !range1.equals(null)); - } - - @Test - public void testEqualsBadType() { - final ITmfTimestamp ts1 = new TmfTimestamp(12345); - final ITmfTimestamp ts2 = new TmfTimestamp(12350); - final TmfTimeRange range1 = new TmfTimeRange(ts1, ts2); - - assertTrue("equals", !range1.equals(ts1)); - } - - @Test - public void testEqualStartTime() { - final ITmfTimestamp ts1 = new TmfTimestamp(12345); - final ITmfTimestamp ts2 = new TmfTimestamp(12350); - final ITmfTimestamp ts3 = new TmfTimestamp(12355); - - final TmfTimeRange range1 = new TmfTimeRange(ts1, ts3); - final TmfTimeRange range2 = new TmfTimeRange(ts2, ts3); - final TmfTimeRange range3 = new TmfTimeRange(ts1, ts2); - - assertTrue("equals", !range1.equals(range2)); - assertTrue("equals", !range1.equals(range3)); - } - - @Test - public void testEqualsEndTime() { - final ITmfTimestamp ts1 = new TmfTimestamp(12345); - final ITmfTimestamp ts2 = new TmfTimestamp(12350); - final ITmfTimestamp ts3 = new TmfTimestamp(12355); - - final TmfTimeRange range1 = new TmfTimeRange(ts1, ts2); - final TmfTimeRange range2 = new TmfTimeRange(ts1, ts3); - final TmfTimeRange range3 = new TmfTimeRange(ts2, ts3); - - assertTrue("equals", !range1.equals(range2)); - assertTrue("equals", !range1.equals(range3)); - } - - // ------------------------------------------------------------------------ - // toString - // ------------------------------------------------------------------------ - - @Test - public void testToString() { - final ITmfTimestamp ts1 = new TmfTimestamp(12345); - final ITmfTimestamp ts2 = new TmfTimestamp(12350); - final TmfTimeRange range = new TmfTimeRange(ts1, ts2); - - final String expected = "TmfTimeRange [fStartTime=" + ts1 + ", fEndTime=" + ts2 + "]"; - assertEquals("toString", expected, range.toString()); - } - - // ------------------------------------------------------------------------ - // contains - // ------------------------------------------------------------------------ - - @Test - public void testContainsTimestamp() { - final ITmfTimestamp ts1 = new TmfTimestamp(12345); - final ITmfTimestamp ts2 = new TmfTimestamp(12350); - final TmfTimeRange range = new TmfTimeRange(ts1, ts2); - - assertTrue("contains (lower bound)", range.contains(new TmfTimestamp(12345))); - assertTrue("contains (higher bound)", range.contains(new TmfTimestamp(12350))); - assertTrue("contains (within bounds)", range.contains(new TmfTimestamp(12346))); - - assertFalse("contains (low value)", range.contains(new TmfTimestamp(12340))); - assertFalse("contains (high value)", range.contains(new TmfTimestamp(12351))); - } - - @Test - public void testContainsRange() { - final ITmfTimestamp ts1 = new TmfTimestamp(10); - final ITmfTimestamp ts2 = new TmfTimestamp(20); - final ITmfTimestamp ts3 = new TmfTimestamp(30); - final ITmfTimestamp ts4 = new TmfTimestamp(40); - final ITmfTimestamp ts5 = new TmfTimestamp(50); - final ITmfTimestamp ts6 = new TmfTimestamp(60); - final ITmfTimestamp ts7 = new TmfTimestamp(70); - final ITmfTimestamp ts8 = new TmfTimestamp(80); - - // Reference range - final TmfTimeRange range0 = new TmfTimeRange(ts3, ts6); - - // Start time below range - final TmfTimeRange range1 = new TmfTimeRange(ts1, ts2); - final TmfTimeRange range2 = new TmfTimeRange(ts2, ts3); - final TmfTimeRange range3 = new TmfTimeRange(ts2, ts4); - final TmfTimeRange range4 = new TmfTimeRange(ts2, ts6); - final TmfTimeRange range5 = new TmfTimeRange(ts2, ts7); - - assertFalse("contains", range0.contains(range1)); - assertFalse("contains", range0.contains(range2)); - assertFalse("contains", range0.contains(range3)); - assertFalse("contains", range0.contains(range4)); - assertFalse("contains", range0.contains(range5)); - - // End time above range - final TmfTimeRange range6 = new TmfTimeRange(ts3, ts7); - final TmfTimeRange range7 = new TmfTimeRange(ts4, ts7); - final TmfTimeRange range8 = new TmfTimeRange(ts6, ts7); - final TmfTimeRange range9 = new TmfTimeRange(ts7, ts8); - - assertFalse("contains", range0.contains(range6)); - assertFalse("contains", range0.contains(range7)); - assertFalse("contains", range0.contains(range8)); - assertFalse("contains", range0.contains(range9)); - - // Within range - final TmfTimeRange range10 = new TmfTimeRange(ts3, ts4); - final TmfTimeRange range11 = new TmfTimeRange(ts3, ts6); - final TmfTimeRange range12 = new TmfTimeRange(ts4, ts5); - final TmfTimeRange range13 = new TmfTimeRange(ts4, ts6); - - assertTrue("contains", range0.contains(range10)); - assertTrue("contains", range0.contains(range11)); - assertTrue("contains", range0.contains(range12)); - assertTrue("contains", range0.contains(range13)); - } - - // ------------------------------------------------------------------------ - // getIntersection - // ------------------------------------------------------------------------ - - @Test - public void testGetIntersection() { - - final ITmfTimestamp ts1a = new TmfTimestamp(1000); - final ITmfTimestamp ts1b = new TmfTimestamp(2000); - final TmfTimeRange range1 = new TmfTimeRange(ts1a, ts1b); - - final ITmfTimestamp ts2a = new TmfTimestamp(2000); - final ITmfTimestamp ts2b = new TmfTimestamp(3000); - final TmfTimeRange range2 = new TmfTimeRange(ts2a, ts2b); - - final ITmfTimestamp ts3a = new TmfTimestamp(3000); - final ITmfTimestamp ts3b = new TmfTimestamp(4000); - final TmfTimeRange range3 = new TmfTimeRange(ts3a, ts3b); - - final ITmfTimestamp ts4a = new TmfTimestamp(1500); - final ITmfTimestamp ts4b = new TmfTimestamp(2500); - final TmfTimeRange range4 = new TmfTimeRange(ts4a, ts4b); - - final ITmfTimestamp ts5a = new TmfTimestamp(1500); - final ITmfTimestamp ts5b = new TmfTimestamp(2000); - final TmfTimeRange range5 = new TmfTimeRange(ts5a, ts5b); - - final ITmfTimestamp ts6a = new TmfTimestamp(2000); - final ITmfTimestamp ts6b = new TmfTimestamp(2500); - final TmfTimeRange range6 = new TmfTimeRange(ts6a, ts6b); - - final ITmfTimestamp ts7a = new TmfTimestamp(1500); - final ITmfTimestamp ts7b = new TmfTimestamp(3500); - final TmfTimeRange range7 = new TmfTimeRange(ts7a, ts7b); - - final ITmfTimestamp ts8a = new TmfTimestamp(2250); - final ITmfTimestamp ts8b = new TmfTimestamp(2750); - final TmfTimeRange range8 = new TmfTimeRange(ts8a, ts8b); - - assertEquals("getIntersection (below - not contiguous)", null, range1.getIntersection(range3)); - assertEquals("getIntersection (above - not contiguous)", null, range3.getIntersection(range1)); - - assertEquals("getIntersection (below - contiguous)", new TmfTimeRange(ts1b, ts1b), range1.getIntersection(range2)); - assertEquals("getIntersection (above - contiguous)", new TmfTimeRange(ts3a, ts3a), range3.getIntersection(range2)); - - assertEquals("getIntersection (below - overlap)", new TmfTimeRange(ts2a, ts4b), range2.getIntersection(range4)); - assertEquals("getIntersection (above - overlap)", new TmfTimeRange(ts2a, ts4b), range4.getIntersection(range2)); - - assertEquals("getIntersection (within - overlap1)", range6, range2.getIntersection(range6)); - assertEquals("getIntersection (within - overlap2)", range6, range6.getIntersection(range2)); - - assertEquals("getIntersection (within - overlap3)", range5, range1.getIntersection(range5)); - assertEquals("getIntersection (within - overlap4)", range5, range5.getIntersection(range1)); - - assertEquals("getIntersection (within - overlap5)", range8, range2.getIntersection(range8)); - assertEquals("getIntersection (within - overlap6)", range8, range8.getIntersection(range2)); - - assertEquals("getIntersection (accross1)", range2, range2.getIntersection(range7)); - assertEquals("getIntersection (accross2)", range2, range7.getIntersection(range2)); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimestampDeltaTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimestampDeltaTest.java deleted file mode 100644 index 1cc98df698..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimestampDeltaTest.java +++ /dev/null @@ -1,131 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.event; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampDelta; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampFormat; -import org.junit.Test; - -/** - * Test suite for the TmfTimestampDelta class. - */ -@SuppressWarnings("javadoc") -public class TmfTimestampDeltaTest { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - private final ITmfTimestamp ts0 = new TmfTimestampDelta(); - private final ITmfTimestamp ts1 = new TmfTimestampDelta(12345, 0); - private final ITmfTimestamp ts2 = new TmfTimestampDelta(12345, -1); - private final ITmfTimestamp ts3 = new TmfTimestampDelta(12345, 2, 5); - private final ITmfTimestamp ts4 = new TmfTimestampDelta(-12345, -5); - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - @Test - public void testDefaultConstructor() { - assertEquals("getValue", 0, ts0.getValue()); - assertEquals("getscale", 0, ts0.getScale()); - assertEquals("getPrecision", 0, ts0.getPrecision()); - } - - @Test - public void testValueConstructor() { - assertEquals("getValue", 12345, ts1.getValue()); - assertEquals("getscale", 0, ts1.getScale()); - assertEquals("getPrecision", 0, ts1.getPrecision()); - } - - @Test - public void testValueScaleConstructor() { - assertEquals("getValue", 12345, ts2.getValue()); - assertEquals("getscale", -1, ts2.getScale()); - assertEquals("getPrecision", 0, ts2.getPrecision()); - } - - @Test - public void testFullConstructor() { - assertEquals("getValue", 12345, ts3.getValue()); - assertEquals("getscale", 2, ts3.getScale()); - assertEquals("getPrecision", 5, ts3.getPrecision()); - - assertEquals("getValue", -12345, ts4.getValue()); - assertEquals("getscale", -5, ts4.getScale()); - assertEquals("getPrecision", 0, ts4.getPrecision()); - } - - @Test - public void testCopyConstructor() { - final ITmfTimestamp ts = new TmfTimestamp(12345, 2, 5); - final ITmfTimestamp copy = new TmfTimestamp(ts); - - assertEquals("getValue", ts.getValue(), copy.getValue()); - assertEquals("getscale", ts.getScale(), copy.getScale()); - assertEquals("getPrecision", ts.getPrecision(), copy.getPrecision()); - - assertEquals("getValue", 12345, copy.getValue()); - assertEquals("getscale", 2, copy.getScale()); - assertEquals("getPrecision", 5, copy.getPrecision()); - } - - @Test(expected=IllegalArgumentException.class) - public void testCopyNullConstructor() { - new TmfTimestamp((TmfTimestamp) null); - } - - // ------------------------------------------------------------------------ - // normalize - // ------------------------------------------------------------------------ - - @Test - public void testNormalizeOffset() { - ITmfTimestamp ts = ts0.normalize(12345, 0); - assertTrue("instance", ts instanceof TmfTimestampDelta); - assertEquals("getValue", 12345, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - } - - // ------------------------------------------------------------------------ - // toString - // ------------------------------------------------------------------------ - - @Test - public void testToStringDefault() { - assertEquals("toString", "000.000 000 000", ts0.toString()); - assertEquals("toString", "12345.000 000 000", ts1.toString()); - assertEquals("toString", "1234.500 000 000", ts2.toString()); - assertEquals("toString", "1234500.000 000 000", ts3.toString()); - assertEquals("toString", "-000.123 450 000", ts4.toString()); - } - - @Test - public void testToStringFormat() { - TmfTimestampFormat format = new TmfTimestampFormat("HH:mm:ss.SSS CCC NNN"); - assertEquals("toString", "00:00:00.000 000 000", ts0.toString(format)); - assertEquals("toString", "03:25:45.000 000 000", ts1.toString(format)); - assertEquals("toString", "00:20:34.500 000 000", ts2.toString(format)); - assertEquals("toString", "06:55:00.000 000 000", ts3.toString(format)); - assertEquals("toString", "-00:00:00.123 450 000", ts4.toString(format)); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimestampFormatTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimestampFormatTest.java deleted file mode 100644 index 925b7c5105..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimestampFormatTest.java +++ /dev/null @@ -1,386 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - * Matthew Khouzam - Added timestamp string tests - * Patrick Tasse - Updated for fraction of second - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.event; - -import static org.junit.Assert.assertEquals; - -import java.text.ParseException; -import java.util.Locale; -import java.util.TimeZone; - -import org.eclipse.core.runtime.preferences.IEclipsePreferences; -import org.eclipse.core.runtime.preferences.InstanceScope; -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimePreferencesConstants; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimePreferences; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampFormat; -import org.junit.Test; -import org.osgi.service.prefs.BackingStoreException; - -/** - * Test suite for the TmfTimestampFormat class. - */ -public class TmfTimestampFormatTest { - - private static final String TEST_PATTERN = "HH:mm:ss.SSS"; - private static final TimeZone TEST_TIME_ZONE = TimeZone.getTimeZone(TimeZone.getAvailableIDs(0)[0]); - private static final TimeZone GMT = TimeZone.getTimeZone("GMT"); - private static final Locale CA = Locale.CANADA; - - private static final TmfTimestampFormat tsf = new TmfTimestampFormat("yyyy-MM-dd HH:mm:ss.SSSSSSSSS", GMT, CA); - private static final TmfTimestampFormat tsf1 = new TmfTimestampFormat(TEST_PATTERN); - private static final TmfTimestampFormat tsf2 = new TmfTimestampFormat(TEST_PATTERN, TEST_TIME_ZONE); - - /** - * Test that the default value is loaded when using the default constructor - */ - @Test - public void testDefaultConstructor() { - TmfTimestampFormat ts0 = new TmfTimestampFormat(); - assertEquals("HH:mm:ss.SSS SSS SSS", ts0.toPattern()); - } - - /** - * Test that the value constructor properly assigns the value - */ - @Test - public void testValueConstructor() { - assertEquals(TEST_PATTERN, tsf1.toPattern()); - } - - /** - * Test that the value constructor using a time zone properly assigns the - * pattern and time zone - */ - @Test - public void testValueTimeZoneConstructor() { - assertEquals(TEST_PATTERN, tsf2.toPattern()); - assertEquals(TEST_TIME_ZONE, tsf2.getTimeZone()); - } - - /** - * Make sure that the default formats in TmfTimestampFormat get updated when - * updateDefaultFormats is called. - */ - @Test - public void testUpdateDefaultFormats() { - IEclipsePreferences node = InstanceScope.INSTANCE.getNode(Activator.PLUGIN_ID); - - String dateTimeTestValue = ITmfTimePreferencesConstants.TIME_HOUR_FMT + ":"; - node.put(ITmfTimePreferencesConstants.DATIME, dateTimeTestValue); - - String subSecTestValue = ITmfTimePreferencesConstants.SUBSEC_NANO_FMT + ":"; - node.put(ITmfTimePreferencesConstants.SUBSEC, subSecTestValue); - try { - node.flush(); - } catch (BackingStoreException e) { - } - TmfTimestampFormat.updateDefaultFormats(); - String expected = dateTimeTestValue + "." + subSecTestValue; - String expected2 = "TTT." + subSecTestValue; - assertEquals(expected, TmfTimestampFormat.getDefaulTimeFormat().toPattern()); - assertEquals(expected2, TmfTimestampFormat.getDefaulIntervalFormat().toPattern()); - // Revert preferences - node.put(ITmfTimePreferencesConstants.DATIME, ITmfTimePreferencesConstants.TIME_HOUR_FMT); - node.put(ITmfTimePreferencesConstants.SUBSEC, ITmfTimePreferencesConstants.SUBSEC_NANO_FMT); - try { - node.flush(); - } catch (BackingStoreException e) { - } - TmfTimestampFormat.updateDefaultFormats(); - } - - /** - * Test that getDefaulTimeFormat returns the appropriate value (from the - * default) - */ - @Test - public void testGetDefaulTimeFormat() { - assertEquals(TmfTimestampFormat.getDefaulTimeFormat().toPattern(), TmfTimePreferences.getInstance().getTimePattern()); - } - - /** - * Test that getDefaulIntervalFormat returns the appropriate value (from the - * default) - */ - @Test - public void testGetDefaulIntervalFormat() { - assertEquals(TmfTimestampFormat.getDefaulIntervalFormat().toPattern(), TmfTimePreferences.getInstance().getIntervalPattern()); - } - - /** - * Test parsing of seconds and sub-seconds - * - * @throws ParseException - * should not happen, if it does, the test is a failure - */ - @Test - public void testParseSeconds() throws ParseException { - assertEquals(7777777777123456789L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7777777777.123456789")); - assertEquals(7777777777123456789L, new TmfTimestampFormat("T.SSSSSSSSS").parseValue("7777777777.123456789")); - assertEquals(7123456789L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("0000000007.123456789")); - assertEquals(7123456789L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.123456789")); - assertEquals(7123456780L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.12345678")); - assertEquals(7123456700L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.1234567")); - assertEquals(7123456000L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.123456")); - assertEquals(7123450000L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.12345")); - assertEquals(7123400000L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.1234")); - assertEquals(7123000000L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.123")); - assertEquals(7120000000L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.12")); - assertEquals(7100000000L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.1")); - assertEquals(7000000000L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.")); - assertEquals(7000000000L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7")); - assertEquals(123456789L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue(".123456789")); - assertEquals(123456789L, new TmfTimestampFormat(".SSSSSSSSS").parseValue(".123456789")); - assertEquals(123456780L, new TmfTimestampFormat(".SSSSSSSS").parseValue(".123456789")); - assertEquals(123456700L, new TmfTimestampFormat(".SSSSSSS").parseValue(".123456789")); - assertEquals(123456000L, new TmfTimestampFormat(".SSSSSS").parseValue(".123456789")); - assertEquals(123450000L, new TmfTimestampFormat(".SSSSS").parseValue(".123456789")); - assertEquals(123400000L, new TmfTimestampFormat(".SSSS").parseValue(".123456789")); - assertEquals(123000000L, new TmfTimestampFormat(".SSS").parseValue(".123456789")); - assertEquals(120000000L, new TmfTimestampFormat(".SS").parseValue(".123456789")); - assertEquals(100000000L, new TmfTimestampFormat(".S").parseValue(".123456789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSSSSSSSS").parseValue("7.123456789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS SSS SSS").parseValue("7.123 456 789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS SSS SSS").parseValue("7.123456789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS.SSS.SSS").parseValue("7.123.456.789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS.SSS.SSS").parseValue("7.123456789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS,SSS,SSS").parseValue("7.123,456,789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS,SSS,SSS").parseValue("7.123456789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS-SSS-SSS").parseValue("7.123-456-789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS-SSS-SSS").parseValue("7.123456789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS_SSS_SSS").parseValue("7.123_456_789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS_SSS_SSS").parseValue("7.123456789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS:SSS:SSS").parseValue("7.123:456:789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS:SSS:SSS").parseValue("7.123456789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS;SSS;SSS").parseValue("7.123;456;789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS;SSS;SSS").parseValue("7.123456789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS/SSS/SSS").parseValue("7.123/456/789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS/SSS/SSS").parseValue("7.123456789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS''SSS''SSS").parseValue("7.123'456'789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS''SSS''SSS").parseValue("7.123456789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS\"SSS\"SSS").parseValue("7.123\"456\"789")); - assertEquals(7123456789L, new TmfTimestampFormat("T.SSS\"SSS\"SSS").parseValue("7.123456789")); - assertEquals(7000000000L, new TmfTimestampFormat("T. SSSSSSSSS").parseValue("7..123456789")); - assertEquals(7100000000L, new TmfTimestampFormat("T.S SSSSSSSS").parseValue("7.1,23456789")); - assertEquals(7120000000L, new TmfTimestampFormat("T.SS SSSSSSS").parseValue("7.12-3456789")); - assertEquals(7123000000L, new TmfTimestampFormat("T.SSS SSSSSS").parseValue("7.123_456789")); - assertEquals(7123400000L, new TmfTimestampFormat("T.SSSS SSSSS").parseValue("7.1234:56789")); - assertEquals(7123450000L, new TmfTimestampFormat("T.SSSSS SSSS").parseValue("7.12345;6789")); - assertEquals(7123456000L, new TmfTimestampFormat("T.SSSSSS SSS").parseValue("7.123456/789")); - assertEquals(7123456700L, new TmfTimestampFormat("T.SSSSSSS SS").parseValue("7.1234567'89")); - assertEquals(7123456780L, new TmfTimestampFormat("T.SSSSSSSS S").parseValue("7.12345678\"9")); - assertEquals(7123456789L, new TmfTimestampFormat("T 's'.SSS ms SSS us SSS ns").parseValue("7 s.123 ms 456 us 789 ns")); - assertEquals(7123456789L, new TmfTimestampFormat("T 'S'.SSS 'MS' SSS 'US' SSS 'NS'").parseValue("7 S.123 MS 456 US 789 NS")); - assertEquals(7123000000L, new TmfTimestampFormat("T.SSSSSSSSS").parseValue("7 s.123 ms 456 ns 789")); - assertEquals(0L, new TmfTimestampFormat("T.").parseValue("0.123456789")); - assertEquals(0L, new TmfTimestampFormat("T.S").parseValue(".")); - assertEquals(0L, new TmfTimestampFormat(".S").parseValue("7.")); - assertEquals(0L, new TmfTimestampFormat("T.S").parseValue("-.")); - assertEquals(0L, new TmfTimestampFormat("T.S").parseValue("-0")); - assertEquals(-100000000L, new TmfTimestampFormat("T.S").parseValue("-0.1")); - assertEquals(-100000000L, new TmfTimestampFormat("T.S").parseValue("-.1")); - assertEquals(-7000000000L, new TmfTimestampFormat("T.S").parseValue("-7")); - assertEquals(-7000000000L, new TmfTimestampFormat("T.S").parseValue("-7.")); - assertEquals(-7000000000L, new TmfTimestampFormat("T.S").parseValue("-7.0")); - assertEquals(-7100000000L, new TmfTimestampFormat("T.S").parseValue("-7.1")); - } - - /** - * Test parsing of date and time patterns - * - * @throws ParseException - * should not happen, if it does, the test is a failure - */ - @Test - public void testParseDateTime() throws ParseException { -// long ref = tsf.parseValue("2014-11-22 12:34:56.123456789"); // Saturday - long time; - - time = new TmfTimestampFormat("yyyy", GMT, CA).parseValue("2014"); - assertEquals("2014-01-01 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("YYYY", GMT, CA).parseValue("2014"); - assertEquals("2013-12-29 00:00:00.000000000", tsf.format(time)); // 1st day of week 1 - - time = new TmfTimestampFormat("MM", GMT, CA).parseValue("11"); - assertEquals("1970-11-01 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("ww", GMT, CA).parseValue("01"); - assertEquals("1969-12-28 00:00:00.000000000", tsf.format(time)); // Sunday of week 1 - - time = new TmfTimestampFormat("DDD", GMT, CA).parseValue("100"); - assertEquals("1970-04-10 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("F", GMT, CA).parseValue("2"); - assertEquals("1970-01-11 00:00:00.000000000", tsf.format(time)); // 2nd Sunday of month - - time = new TmfTimestampFormat("EEE", GMT, CA).parseValue("Mon"); - assertEquals("1970-01-05 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("u", GMT, CA).parseValue("1"); - assertEquals("1970-01-05 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("dd", GMT, CA).parseValue("22"); - assertEquals("1970-01-22 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("HH", GMT, CA).parseValue("12"); - assertEquals("1970-01-01 12:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("kk", GMT, CA).parseValue("24"); - assertEquals("1970-01-01 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("KK", GMT, CA).parseValue("12"); - assertEquals("1970-01-01 12:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("hh", GMT, CA).parseValue("12"); - assertEquals("1970-01-01 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("mm", GMT, CA).parseValue("34"); - assertEquals("1970-01-01 00:34:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("ss", GMT, CA).parseValue("56"); - assertEquals("1970-01-01 00:00:56.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy-MM", GMT, CA).parseValue("2014-11"); - assertEquals("2014-11-01 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy-MM-dd", GMT, CA).parseValue("2014-11-22"); - assertEquals("2014-11-22 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy-MM-dd HH", GMT, CA).parseValue("2014-11-22 12"); - assertEquals("2014-11-22 12:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy-MM-dd HH:mm", GMT, CA).parseValue("2014-11-22 12:34"); - assertEquals("2014-11-22 12:34:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy-MM-dd HH:mm:ss", GMT, CA).parseValue("2014-11-22 12:34:56"); - assertEquals("2014-11-22 12:34:56.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy-MM-dd HH:mm:ss.SSS", GMT, CA).parseValue("2014-11-22 12:34:56.123"); - assertEquals("2014-11-22 12:34:56.123000000", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy-ww", GMT, CA).parseValue("2014-01"); - assertEquals("2013-12-29 00:00:00.000000000", tsf.format(time)); // Sunday of week 1 - - time = new TmfTimestampFormat("yyyy-DDD", GMT, CA).parseValue("2014-100"); - assertEquals("2014-04-10 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy-MM-F", GMT, CA).parseValue("2014-11-2"); - assertEquals("2014-11-09 00:00:00.000000000", tsf.format(time)); // 2nd Sunday of month - - time = new TmfTimestampFormat("yyyy-MM-EEE", GMT, CA).parseValue("2014-11-Mon"); - assertEquals("2014-11-03 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy-MM-u", GMT, CA).parseValue("2014-11-1"); - assertEquals("2014-11-03 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy MM dd HH mm ss SSS SSS SSS", GMT, CA).parseValue("2014 11 22 12 34 56 123 456 789"); - assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy.MM.dd.HH.mm.ss.SSS.SSS.SSS", GMT, CA).parseValue("2014.11.22.12.34.56.123.456.789"); - assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy,MM,dd,HH,mm,ss,SSS,SSS,SSS", GMT, CA).parseValue("2014,11,22,12,34,56,123,456,789"); - assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy-MM-dd-HH-mm-ss-SSS-SSS-SSS", GMT, CA).parseValue("2014-11-22-12-34-56-123-456-789"); - assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy_MM_dd_HH_mm_ss_SSS_SSS_SSS", GMT, CA).parseValue("2014_11_22_12_34_56_123_456_789"); - assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy:MM:dd:HH:mm:ss:SSS:SSS:SSS", GMT, CA).parseValue("2014:11:22:12:34:56:123:456:789"); - assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy;MM;dd;HH;mm;ss;SSS;SSS;SSS", GMT, CA).parseValue("2014;11;22;12;34;56;123;456;789"); - assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy/MM/dd/HH/mm/ss/SSS/SSS/SSS", GMT, CA).parseValue("2014/11/22/12/34/56/123/456/789"); - assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy''MM''dd''HH''mm''ss''SSS''SSS''SSS", GMT, CA).parseValue("2014'11'22'12'34'56'123'456'789"); - assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); - - time = new TmfTimestampFormat("yyyy\"MM\"dd\"HH\"mm\"ss\"SSS\"SSS\"SSS", GMT, CA).parseValue("2014\"11\"22\"12\"34\"56\"123\"456\"789"); - assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); - } - - /** - * Test parsing of date and time patterns with reference time - * - * @throws ParseException - * should not happen, if it does, the test is a failure - */ - @Test - public void testParseDateTimeWithRef() throws ParseException { - long ref = tsf.parseValue("2014-11-22 12:34:56.123456789"); // Saturday - long time; - - time = new TmfTimestampFormat("yyyy", GMT, CA).parseValue("1970", ref); - assertEquals("1970-01-01 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("YYYY", GMT, CA).parseValue("1970", ref); - assertEquals("1969-12-28 00:00:00.000000000", tsf.format(time)); // 1st day of week 1 - - time = new TmfTimestampFormat("MM", GMT, CA).parseValue("01", ref); - assertEquals("2014-01-01 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("ww", GMT, CA).parseValue("01", ref); - assertEquals("2014-01-04 00:00:00.000000000", tsf.format(time)); // Saturday of week 1 - - time = new TmfTimestampFormat("DDD", GMT, CA).parseValue("1", ref); - assertEquals("2014-01-01 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("F", GMT, CA).parseValue("2", ref); - assertEquals("2014-11-08 00:00:00.000000000", tsf.format(time)); // 2nd Saturday of month - - time = new TmfTimestampFormat("EEE", GMT, CA).parseValue("Mon", ref); - assertEquals("2014-11-17 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("u", GMT, CA).parseValue("1", ref); - assertEquals("2014-11-17 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("dd", GMT, CA).parseValue("01", ref); - assertEquals("2014-11-01 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("HH", GMT, CA).parseValue("00", ref); - assertEquals("2014-11-22 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("kk", GMT, CA).parseValue("24", ref); - assertEquals("2014-11-22 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("KK", GMT, CA).parseValue("00", ref); - assertEquals("2014-11-22 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("hh", GMT, CA).parseValue("12", ref); - assertEquals("2014-11-22 00:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("mm", GMT, CA).parseValue("00", ref); - assertEquals("2014-11-22 12:00:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat("ss", GMT, CA).parseValue("00", ref); - assertEquals("2014-11-22 12:34:00.000000000", tsf.format(time)); - - time = new TmfTimestampFormat(".S", GMT, CA).parseValue(".9", ref); - assertEquals("2014-11-22 12:34:56.900000000", tsf.format(time)); - - time = new TmfTimestampFormat("T.S", GMT, CA).parseValue("8.9", ref); - assertEquals("1970-01-01 00:00:08.900000000", tsf.format(time)); - - time = new TmfTimestampFormat("T.S", GMT, CA).parseValue(".9", ref); - assertEquals("1970-01-01 00:00:00.900000000", tsf.format(time)); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimestampTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimestampTest.java deleted file mode 100644 index 7bf07186b2..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/TmfTimestampTest.java +++ /dev/null @@ -1,670 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Adjusted for new Event Model - * Alexandre Montplaisir - Port to JUnit4 - * Patrick Tasse - Updated for negative value formatting - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.event; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampFormat; -import org.junit.Test; - -/** - * Test suite for the TmfTimestamp class. - */ -@SuppressWarnings("javadoc") -public class TmfTimestampTest { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - private final ITmfTimestamp ts0 = new TmfTimestamp(); - private final ITmfTimestamp ts1 = new TmfTimestamp(12345, 0); - private final ITmfTimestamp ts2 = new TmfTimestamp(12345, -1); - private final ITmfTimestamp ts3 = new TmfTimestamp(12345, 2, 5); - private final ITmfTimestamp ts4 = new TmfTimestamp(12345, -3, 0); - private final ITmfTimestamp ts5 = new TmfTimestamp(12345, -6, 0); - private final ITmfTimestamp ts6 = new TmfTimestamp(12345, -9, 0); - private final ITmfTimestamp ts7 = new TmfTimestamp(-12345, -3, 0); - private final ITmfTimestamp ts8 = new TmfTimestamp(-12345, -6, 0); - private final ITmfTimestamp ts9 = new TmfTimestamp(-12345, -9, 0); - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - @Test - public void testDefaultConstructor() { - assertEquals("getValue", 0, ts0.getValue()); - assertEquals("getscale", 0, ts0.getScale()); - assertEquals("getPrecision", 0, ts0.getPrecision()); - } - - @Test - public void testValueConstructor() { - assertEquals("getValue", 12345, ts1.getValue()); - assertEquals("getscale", 0, ts1.getScale()); - assertEquals("getPrecision", 0, ts1.getPrecision()); - } - - @Test - public void testValueScaleConstructor() { - assertEquals("getValue", 12345, ts2.getValue()); - assertEquals("getscale", -1, ts2.getScale()); - assertEquals("getPrecision", 0, ts2.getPrecision()); - } - - @Test - public void testFullConstructor() { - assertEquals("getValue", 12345, ts3.getValue()); - assertEquals("getscale", 2, ts3.getScale()); - assertEquals("getPrecision", 5, ts3.getPrecision()); - } - - @Test - public void testCopyConstructor() { - final ITmfTimestamp ts = new TmfTimestamp(12345, 2, 5); - final ITmfTimestamp copy = new TmfTimestamp(ts); - - assertEquals("getValue", ts.getValue(), copy.getValue()); - assertEquals("getscale", ts.getScale(), copy.getScale()); - assertEquals("getPrecision", ts.getPrecision(), copy.getPrecision()); - - assertEquals("getValue", 12345, copy.getValue()); - assertEquals("getscale", 2, copy.getScale()); - assertEquals("getPrecision", 5, copy.getPrecision()); - } - - @Test(expected=IllegalArgumentException.class) - public void testCopyNullConstructor() { - new TmfTimestamp((TmfTimestamp) null); - } - - @Test - public void testCopyConstructorBigBang() { - final ITmfTimestamp ts = new TmfTimestamp(TmfTimestamp.BIG_BANG); - assertEquals("getValue", TmfTimestamp.BIG_BANG.getValue(), ts.getValue()); - assertEquals("getscale", TmfTimestamp.BIG_BANG.getScale(), ts.getScale()); - assertEquals("getPrecision", TmfTimestamp.BIG_BANG.getPrecision(), ts.getPrecision()); - } - - @Test - public void testCopyConstructorBigCrunch() { - final ITmfTimestamp ts = new TmfTimestamp(TmfTimestamp.BIG_CRUNCH); - assertEquals("getValue", TmfTimestamp.BIG_CRUNCH.getValue(), ts.getValue()); - assertEquals("getscale", TmfTimestamp.BIG_CRUNCH.getScale(), ts.getScale()); - assertEquals("getPrecision", TmfTimestamp.BIG_CRUNCH.getPrecision(), ts.getPrecision()); - } - - @Test - public void testCopyConstructorZero() { - final ITmfTimestamp ts = new TmfTimestamp(TmfTimestamp.ZERO); - assertEquals("getValue", TmfTimestamp.ZERO.getValue(), ts.getValue()); - assertEquals("getscale", TmfTimestamp.ZERO.getScale(), ts.getScale()); - assertEquals("getPrecision", TmfTimestamp.ZERO.getPrecision(), ts.getPrecision()); - } - - // ------------------------------------------------------------------------ - // hashCode - // ------------------------------------------------------------------------ - - @Test - public void testHashCode() { - final ITmfTimestamp ts0copy = new TmfTimestamp(ts0); - final ITmfTimestamp ts1copy = new TmfTimestamp(ts1); - final ITmfTimestamp ts2copy = new TmfTimestamp(ts2); - - assertTrue("hashCode", ts0.hashCode() == ts0copy.hashCode()); - assertTrue("hashCode", ts1.hashCode() == ts1copy.hashCode()); - assertTrue("hashCode", ts2.hashCode() == ts2copy.hashCode()); - - assertTrue("hashCode", ts0.hashCode() != ts1.hashCode()); - } - - // ------------------------------------------------------------------------ - // equals - // ------------------------------------------------------------------------ - - @Test - public void testEqualsReflexivity() { - assertTrue("equals", ts0.equals(ts0)); - assertTrue("equals", ts1.equals(ts1)); - - assertTrue("equals", !ts0.equals(ts1)); - assertTrue("equals", !ts1.equals(ts0)); - } - - @Test - public void testEqualsSymmetry() { - final ITmfTimestamp ts0copy = new TmfTimestamp(ts0); - assertTrue("equals", ts0.equals(ts0copy)); - assertTrue("equals", ts0copy.equals(ts0)); - - final ITmfTimestamp ts1copy = new TmfTimestamp(ts1); - assertTrue("equals", ts1.equals(ts1copy)); - assertTrue("equals", ts1copy.equals(ts1)); - - final ITmfTimestamp ts2copy = new TmfTimestamp(ts2); - assertTrue("equals", ts2.equals(ts2copy)); - assertTrue("equals", ts2copy.equals(ts2)); - } - - @Test - public void testEqualsTransivity() { - final ITmfTimestamp ts0copy1 = new TmfTimestamp(ts0); - final ITmfTimestamp ts0copy2 = new TmfTimestamp(ts0copy1); - assertTrue("equals", ts0.equals(ts0copy1)); - assertTrue("equals", ts0copy1.equals(ts0copy2)); - assertTrue("equals", ts0.equals(ts0copy2)); - - final ITmfTimestamp ts1copy1 = new TmfTimestamp(ts1); - final ITmfTimestamp ts1copy2 = new TmfTimestamp(ts1copy1); - assertTrue("equals", ts1.equals(ts1copy1)); - assertTrue("equals", ts1copy1.equals(ts1copy2)); - assertTrue("equals", ts1.equals(ts1copy2)); - - final ITmfTimestamp ts2copy1 = new TmfTimestamp(ts2); - final ITmfTimestamp ts2copy2 = new TmfTimestamp(ts2copy1); - assertTrue("equals", ts2.equals(ts2copy1)); - assertTrue("equals", ts2copy1.equals(ts2copy2)); - assertTrue("equals", ts2.equals(ts2copy2)); - } - - @Test - public void testEqualsNull() { - assertTrue("equals", !ts0.equals(null)); - assertTrue("equals", !ts1.equals(null)); - } - - @Test - public void testEqualsNonTimestamp() { - assertFalse("equals", ts0.equals(ts0.toString())); - } - - // ------------------------------------------------------------------------ - // toString - // ------------------------------------------------------------------------ - - @Test - public void testToStringDefault() { - DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS"); - Date d0 = new Date((long) (ts0.getValue() * Math.pow(10, ts0.getScale() + 3))); - Date d1 = new Date((long) (ts1.getValue() * Math.pow(10, ts1.getScale() + 3))); - Date d2 = new Date((long) (ts2.getValue() * Math.pow(10, ts2.getScale() + 3))); - Date d3 = new Date((long) (ts3.getValue() * Math.pow(10, ts3.getScale() + 3))); - Date d4 = new Date((long) (ts4.getValue() * Math.pow(10, ts4.getScale() + 3))); - Date d5 = new Date((long) (ts5.getValue() * Math.pow(10, ts5.getScale() + 3))); - Date d6 = new Date((long) (ts6.getValue() * Math.pow(10, ts6.getScale() + 3))); - Date d7 = new Date((long) (ts7.getValue() * Math.pow(10, ts7.getScale() + 3))); - Date d8 = new Date((long) (ts8.getValue() * Math.pow(10, ts8.getScale() + 3)) - 1); - Date d9 = new Date((long) (ts9.getValue() * Math.pow(10, ts9.getScale() + 3)) - 1); - assertEquals("toString", df.format(d0) + " 000 000", ts0.toString()); - assertEquals("toString", df.format(d1) + " 000 000", ts1.toString()); - assertEquals("toString", df.format(d2) + " 000 000", ts2.toString()); - assertEquals("toString", df.format(d3) + " 000 000", ts3.toString()); - assertEquals("toString", df.format(d4) + " 000 000", ts4.toString()); - assertEquals("toString", df.format(d5) + " 345 000", ts5.toString()); - assertEquals("toString", df.format(d6) + " 012 345", ts6.toString()); - assertEquals("toString", df.format(d7) + " 000 000", ts7.toString()); - assertEquals("toString", df.format(d8) + " 655 000", ts8.toString()); - assertEquals("toString", df.format(d9) + " 987 655", ts9.toString()); - } - - @Test - public void testToStringInterval() { - assertEquals("toString", "000.000 000 000", ts0.toString(TmfTimestampFormat.getDefaulIntervalFormat())); - assertEquals("toString", "12345.000 000 000", ts1.toString(TmfTimestampFormat.getDefaulIntervalFormat())); - assertEquals("toString", "1234.500 000 000", ts2.toString(TmfTimestampFormat.getDefaulIntervalFormat())); - assertEquals("toString", "1234500.000 000 000", ts3.toString(TmfTimestampFormat.getDefaulIntervalFormat())); - assertEquals("toString", "012.345 000 000", ts4.toString(TmfTimestampFormat.getDefaulIntervalFormat())); - assertEquals("toString", "000.012 345 000", ts5.toString(TmfTimestampFormat.getDefaulIntervalFormat())); - assertEquals("toString", "000.000 012 345", ts6.toString(TmfTimestampFormat.getDefaulIntervalFormat())); - assertEquals("toString", "-012.345 000 000", ts7.toString(TmfTimestampFormat.getDefaulIntervalFormat())); - assertEquals("toString", "-000.012 345 000", ts8.toString(TmfTimestampFormat.getDefaulIntervalFormat())); - assertEquals("toString", "-000.000 012 345", ts9.toString(TmfTimestampFormat.getDefaulIntervalFormat())); - } - - // ------------------------------------------------------------------------ - // normalize - // ------------------------------------------------------------------------ - - @Test - public void testNormalizeOffset() { - ITmfTimestamp ts = ts0.normalize(0, 0); - assertEquals("getValue", 0, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(12345, 0); - assertEquals("getValue", 12345, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(10, 0); - assertEquals("getValue", 10, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(-10, 0); - assertEquals("getValue", -10, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - } - - @Test - public void testNormalizeOffsetLowerLimits() { - final ITmfTimestamp ref = new TmfTimestamp(Long.MIN_VALUE + 5, 0); - - ITmfTimestamp ts = ref.normalize(-4, 0); - assertEquals("getValue", Long.MIN_VALUE + 1, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ref.normalize(-5, 0); - assertEquals("getValue", Long.MIN_VALUE, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ref.normalize(-6, 0); - assertEquals("getValue", Long.MIN_VALUE, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - } - - @Test - public void testNormalizeOffsetUpperLimits() { - final ITmfTimestamp ref = new TmfTimestamp(Long.MAX_VALUE - 5, 0); - - ITmfTimestamp ts = ref.normalize(4, 0); - assertEquals("getValue", Long.MAX_VALUE - 1, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ref.normalize(5, 0); - assertEquals("getValue", Long.MAX_VALUE, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ref.normalize(6, 0); - assertEquals("getValue", Long.MAX_VALUE, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - } - - @Test - public void testNormalizeScale() { - ITmfTimestamp ts = ts0.normalize(0, 10); - assertEquals("getValue", 0, ts.getValue()); - assertEquals("getscale", 10, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(0, -10); - assertEquals("getValue", 0, ts.getValue()); - assertEquals("getscale", -10, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - } - - @Test - public void testNormalizedScaleLimits() { - final int MAX_SCALE_DIFF = 19; - - // Test below limit - try { - ts1.normalize(0, +MAX_SCALE_DIFF - 1); - ts1.normalize(0, -MAX_SCALE_DIFF + 1); - } catch (final ArithmeticException e) { - fail("normalize: scale error"); - } - - // Test at limit - try { - ts1.normalize(0, +MAX_SCALE_DIFF); - fail("normalize: scale error"); - ts1.normalize(0, -MAX_SCALE_DIFF); - fail("normalize: scale error"); - } catch (final ArithmeticException e) { - } - - // Test over limit - try { - ts1.normalize(0, +MAX_SCALE_DIFF + 1); - fail("normalize: scale error"); - ts1.normalize(0, -MAX_SCALE_DIFF - 1); - fail("normalize: scale error"); - } catch (final ArithmeticException e) { - } - } - - @Test - public void testNormalizeOffsetAndScaleTrivial() { - final ITmfTimestamp ts = ts0.normalize(0, 0); - assertEquals("getValue", 0, ts.getValue()); - assertEquals("getscale", 0, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - } - - @Test - public void testNormalizeOffsetAndScale() { - final int SCALE = 12; - - ITmfTimestamp ts = ts0.normalize(0, SCALE); - assertEquals("getValue", 0, ts.getValue()); - assertEquals("getscale", SCALE, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(12345, SCALE); - assertEquals("getValue", 12345, ts.getValue()); - assertEquals("getscale", SCALE, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(10, SCALE); - assertEquals("getValue", 10, ts.getValue()); - assertEquals("getscale", SCALE, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts0.normalize(-10, SCALE); - assertEquals("getValue", -10, ts.getValue()); - assertEquals("getscale", SCALE, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - } - - @Test - public void testNormalizeOffsetAndScale2() { - int SCALE = 2; - ITmfTimestamp ts = ts1.normalize(0, SCALE); - assertEquals("getValue", 123, ts.getValue()); - assertEquals("getscale", SCALE, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts1.normalize(12345, SCALE); - assertEquals("getValue", 12468, ts.getValue()); - assertEquals("getscale", SCALE, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - SCALE = -2; - ts = ts1.normalize(0, SCALE); - assertEquals("getValue", 1234500, ts.getValue()); - assertEquals("getscale", SCALE, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - - ts = ts1.normalize(67, SCALE); - assertEquals("getValue", 1234567, ts.getValue()); - assertEquals("getscale", SCALE, ts.getScale()); - assertEquals("getPrecision", 0, ts.getPrecision()); - } - - // ------------------------------------------------------------------------ - // compareTo - // ------------------------------------------------------------------------ - - @Test - public void testBasicCompareTo() { - final ITmfTimestamp t1 = new TmfTimestamp(900, 0, 50); - final ITmfTimestamp t2 = new TmfTimestamp(1000, 0, 50); - final ITmfTimestamp t3 = new TmfTimestamp(1100, 0, 50); - final ITmfTimestamp t4 = new TmfTimestamp(1000, 0, 75); - - assertTrue(t1.compareTo(t1) == 0); - - assertTrue("CompareTo", t1.compareTo(t2) < 0); - assertTrue("CompareTo", t1.compareTo(t3) < 0); - assertTrue("CompareTo", t1.compareTo(t4) < 0); - - assertTrue("CompareTo", t2.compareTo(t1) > 0); - assertTrue("CompareTo", t2.compareTo(t3) < 0); - assertTrue("CompareTo", t2.compareTo(t4) == 0); - - assertTrue("CompareTo", t3.compareTo(t1) > 0); - assertTrue("CompareTo", t3.compareTo(t2) > 0); - assertTrue("CompareTo", t3.compareTo(t4) > 0); - } - - @Test - public void testCompareToCornerCases1() { - final ITmfTimestamp ts0a = new TmfTimestamp(ts0); - final ITmfTimestamp ts0b = new TmfTimestamp(ts0.getValue(), ts0.getScale() + 1); - final ITmfTimestamp ts0c = new TmfTimestamp(ts0.getValue() + 1, ts0.getScale()); - final ITmfTimestamp ts0d = new TmfTimestamp(ts0.getValue() + 1, ts0.getScale() + 1); - - assertTrue("compareTo", ts0.compareTo(ts0, false) == 0); - assertTrue("compareTo", ts0.compareTo(ts0a, false) == 0); - assertTrue("compareTo", ts0.compareTo(ts0b, false) == 0); - assertTrue("compareTo", ts0.compareTo(ts0c, false) == -1); - assertTrue("compareTo", ts0.compareTo(ts0d, false) == -1); - } - - @Test - public void testCompareToCornerCases2() { - final ITmfTimestamp ts0a = new TmfTimestamp(Long.MAX_VALUE, Integer.MAX_VALUE - 1); - final ITmfTimestamp ts0b = new TmfTimestamp(0, Integer.MAX_VALUE); - final ITmfTimestamp ts0c = new TmfTimestamp(Long.MAX_VALUE, Integer.MAX_VALUE); - - assertTrue("compareTo", ts0a.compareTo(ts0b, false) == 1); - assertTrue("compareTo", ts0a.compareTo(ts0c, false) == -1); - - assertTrue("compareTo", ts0b.compareTo(ts0a, false) == -1); - assertTrue("compareTo", ts0b.compareTo(ts0c, false) == -1); - - assertTrue("compareTo", ts0c.compareTo(ts0a, false) == 1); - assertTrue("compareTo", ts0c.compareTo(ts0b, false) == 1); - } - - @Test - public void testCompareToCornerCases3() { - final ITmfTimestamp ts0a = new TmfTimestamp(Long.MIN_VALUE, Integer.MAX_VALUE - 1); - final ITmfTimestamp ts0b = new TmfTimestamp(0, Integer.MAX_VALUE); - final ITmfTimestamp ts0c = new TmfTimestamp(Long.MIN_VALUE, Integer.MAX_VALUE); - - assertTrue("compareTo", ts0a.compareTo(ts0b, false) == -1); - assertTrue("compareTo", ts0a.compareTo(ts0c, false) == 1); - - assertTrue("compareTo", ts0b.compareTo(ts0a, false) == 1); - assertTrue("compareTo", ts0b.compareTo(ts0c, false) == 1); - - assertTrue("compareTo", ts0c.compareTo(ts0a, false) == -1); - assertTrue("compareTo", ts0c.compareTo(ts0b, false) == -1); - } - - @Test - public void testCompareToCornerCases4() { - assertTrue("compareTo", ts0.compareTo(null, false) == 1); - assertTrue("compareTo", ts0.compareTo(null, true) == 1); - } - - @Test - public void testCompareToSameScale() { - final ITmfTimestamp t1 = new TmfTimestamp(900, 0, 50); - final ITmfTimestamp t2 = new TmfTimestamp(1000, 0, 50); - final ITmfTimestamp t3 = new TmfTimestamp(1100, 0, 50); - final ITmfTimestamp t4 = new TmfTimestamp(1000, 0, 75); - - assertTrue(t1.compareTo(t1, false) == 0); - - assertTrue("CompareTo", t1.compareTo(t2, false) < 0); - assertTrue("CompareTo", t1.compareTo(t3, false) < 0); - assertTrue("CompareTo", t1.compareTo(t4, false) < 0); - - assertTrue("CompareTo", t2.compareTo(t1, false) > 0); - assertTrue("CompareTo", t2.compareTo(t3, false) < 0); - assertTrue("CompareTo", t2.compareTo(t4, false) == 0); - - assertTrue("CompareTo", t3.compareTo(t1, false) > 0); - assertTrue("CompareTo", t3.compareTo(t2, false) > 0); - assertTrue("CompareTo", t3.compareTo(t4, false) > 0); - } - - @Test - public void testCompareToDifferentScale() { - final ITmfTimestamp t1 = new TmfTimestamp(9000, -1, 50); - final ITmfTimestamp t2 = new TmfTimestamp(1000, 0, 50); - final ITmfTimestamp t3 = new TmfTimestamp(110, 1, 50); - final ITmfTimestamp t4 = new TmfTimestamp(1, 3, 75); - - assertTrue("CompareTo", t1.compareTo(t1, false) == 0); - - assertTrue("CompareTo", t1.compareTo(t2, false) < 0); - assertTrue("CompareTo", t1.compareTo(t3, false) < 0); - assertTrue("CompareTo", t1.compareTo(t4, false) < 0); - - assertTrue("CompareTo", t2.compareTo(t1, false) > 0); - assertTrue("CompareTo", t2.compareTo(t3, false) < 0); - assertTrue("CompareTo", t2.compareTo(t4, false) == 0); - - assertTrue("CompareTo", t3.compareTo(t1, false) > 0); - assertTrue("CompareTo", t3.compareTo(t2, false) > 0); - assertTrue("CompareTo", t3.compareTo(t4, false) > 0); - } - - @Test - public void testCompareToWithinPrecision() { - final ITmfTimestamp t1 = new TmfTimestamp(900, 0, 50); - final ITmfTimestamp t2 = new TmfTimestamp(1000, 0, 50); - final ITmfTimestamp t3 = new TmfTimestamp(1100, 0, 50); - final ITmfTimestamp t4 = new TmfTimestamp(1000, 0, 75); - - assertTrue("CompareTo", t1.compareTo(t1, true) == 0); - - assertTrue("CompareTo", t1.compareTo(t2, true) == 0); - assertTrue("CompareTo", t1.compareTo(t3, true) < 0); - assertTrue("CompareTo", t1.compareTo(t4, true) == 0); - - assertTrue("CompareTo", t2.compareTo(t1, true) == 0); - assertTrue("CompareTo", t2.compareTo(t3, true) == 0); - assertTrue("CompareTo", t2.compareTo(t4, true) == 0); - - assertTrue("CompareTo", t3.compareTo(t1, true) > 0); - assertTrue("CompareTo", t3.compareTo(t2, true) == 0); - assertTrue("CompareTo", t3.compareTo(t4, true) == 0); - } - - @Test - public void testCompareToLargeScale1() { - final ITmfTimestamp t1 = new TmfTimestamp(-1, 100); - final ITmfTimestamp t2 = new TmfTimestamp(-1000, -100); - final ITmfTimestamp t3 = new TmfTimestamp(1, 100); - final ITmfTimestamp t4 = new TmfTimestamp(1000, -100); - - assertTrue("CompareTo", t1.compareTo(t2, false) < 0); - assertTrue("CompareTo", t1.compareTo(t3, false) < 0); - assertTrue("CompareTo", t1.compareTo(t4, false) < 0); - - assertTrue("CompareTo", t2.compareTo(t1, false) > 0); - assertTrue("CompareTo", t2.compareTo(t3, false) < 0); - assertTrue("CompareTo", t2.compareTo(t4, false) < 0); - - assertTrue("CompareTo", t3.compareTo(t1, false) > 0); - assertTrue("CompareTo", t3.compareTo(t2, false) > 0); - assertTrue("CompareTo", t3.compareTo(t4, false) > 0); - - assertTrue("CompareTo", t4.compareTo(t1, false) > 0); - assertTrue("CompareTo", t4.compareTo(t2, false) > 0); - assertTrue("CompareTo", t4.compareTo(t3, false) < 0); - } - - @Test - public void testCompareToLargeScale2() { - final ITmfTimestamp ts0a = new TmfTimestamp(0, Integer.MAX_VALUE); - final ITmfTimestamp ts0b = new TmfTimestamp(1, Integer.MAX_VALUE); - - assertTrue("CompareTo", ts0a.compareTo(ts0, false) == 0); - assertTrue("CompareTo", ts0.compareTo(ts0a, false) == 0); - - assertTrue("CompareTo", ts0b.compareTo(ts0, false) == 1); - assertTrue("CompareTo", ts0.compareTo(ts0b, false) == -1); - } - - // ------------------------------------------------------------------------ - // getDelta - // ------------------------------------------------------------------------ - - @Test - public void testDelta() { - // Delta for same scale and precision (delta > 0) - ITmfTimestamp t0 = new TmfTimestamp(10, 9); - ITmfTimestamp t1 = new TmfTimestamp(5, 9); - ITmfTimestamp exp = new TmfTimestamp(5, 9); - - ITmfTimestamp delta = t0.getDelta(t1); - assertEquals("getDelta", 0, delta.compareTo(exp, false)); - - // Delta for same scale and precision (delta < 0) - t0 = new TmfTimestamp(5, 9); - t1 = new TmfTimestamp(10, 9); - exp = new TmfTimestamp(-5, 9); - - delta = t0.getDelta(t1); - assertEquals("getDelta", 0, delta.compareTo(exp, false)); - - // Delta for different scale and same precision (delta > 0) - t0 = new TmfTimestamp(5, 9); - t1 = new TmfTimestamp(10, 8); - exp = new TmfTimestamp(4, 9); - - delta = t0.getDelta(t1); - assertEquals("getDelta", 0, delta.compareTo(exp, false)); - - // Delta for different scale and same precision (delta > 0) - t0 = new TmfTimestamp(5, 9); - t1 = new TmfTimestamp(10, 7); - exp = new TmfTimestamp(5, 9); - - delta = t0.getDelta(t1); - assertEquals("getDelta", 0, delta.compareTo(exp, false)); - - // Delta for different scale and same precision - t0 = new TmfTimestamp(10, 9); - t1 = new TmfTimestamp(5, 8); - exp = new TmfTimestamp(10, 9); - - delta = t0.getDelta(t1); - assertEquals("getDelta", 0, delta.compareTo(exp, false)); - - // Delta for same scale and different precision - t0 = new TmfTimestamp(10, 9, 1); - t1 = new TmfTimestamp(5, 9, 2); - exp = new TmfTimestamp(5, 9, 3); - - delta = t0.getDelta(t1); - assertEquals("getDelta", 0, delta.compareTo(exp, true)); - assertEquals("precision", 3, delta.getPrecision()); - - // Delta for same scale and different precision - t0 = new TmfTimestamp(5, 9, 2); - t1 = new TmfTimestamp(10, 9, 1); - exp = new TmfTimestamp(-5, 9, 3); - - delta = t0.getDelta(t1); - assertEquals("getDelta", 0, delta.compareTo(exp, true)); - assertEquals("precision", 3, delta.getPrecision()); - - // Delta for different scale and different precision - t0 = new TmfTimestamp(5, 9, 2); - t1 = new TmfTimestamp(10, 8, 1); - exp = new TmfTimestamp(4, 9, 3); - delta = t0.getDelta(t1); - assertEquals("getDelta", 0, delta.compareTo(exp, true)); - assertEquals("precision", 2, delta.getPrecision()); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/lookup/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/lookup/AllTests.java deleted file mode 100644 index 2db2ab1c80..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/lookup/AllTests.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.event.lookup; - -import org.eclipse.linuxtools.tmf.core.tests.event.lookup.TmfCallsiteTest; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite for org.eclipse.linuxtools.tmf.core.event.lookup - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TmfCallsiteTest.class -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/lookup/TmfCallsiteTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/lookup/TmfCallsiteTest.java deleted file mode 100644 index 2839784745..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/event/lookup/TmfCallsiteTest.java +++ /dev/null @@ -1,179 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.event.lookup; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.eclipse.linuxtools.tmf.core.event.lookup.ITmfCallsite; -import org.eclipse.linuxtools.tmf.core.event.lookup.TmfCallsite; -import org.junit.Test; - -/** - * Test suite for the TmfCallsite class. - */ -@SuppressWarnings("javadoc") -public class TmfCallsiteTest { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - private final static String fFileName1 = "filename1"; - private final static String fFunctionName1 = "func1"; - private final static long fLine1 = 10; - - private final static String fFileName2 = "filename2"; - private final static String fFunctionName2 = "func2"; - private final static long fLine2 = 25; - - private final static String fFileName3 = "filename3"; - private final static String fFunctionName3 = null; - private final static long fLine3 = 123; - - private final static ITmfCallsite fCallsite1 = new TmfCallsite(fFileName1, fFunctionName1, fLine1); - private final static ITmfCallsite fCallsite2 = new TmfCallsite(fFileName2, fFunctionName2, fLine2); - private final static ITmfCallsite fCallsite3 = new TmfCallsite(fFileName3, fFunctionName3, fLine3); - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - @Test - public void testDefaultConstructor() { - assertEquals(fFileName1, fCallsite1.getFileName()); - assertEquals(fFunctionName1, fCallsite1.getFunctionName()); - assertEquals(fLine1, fCallsite1.getLineNumber()); - } - - @Test - public void testCallsiteCopy() { - TmfCallsite copy = new TmfCallsite(fCallsite1); - - assertEquals(fFileName1, copy.getFileName()); - assertEquals(fFunctionName1, copy.getFunctionName()); - assertEquals(fLine1, copy.getLineNumber()); - } - - @Test(expected=IllegalArgumentException.class) - public void testCallsiteCopy2() { - new TmfCallsite(null); - } - - @Test(expected=IllegalArgumentException.class) - public void testCallsiteCopy3() { - new TmfCallsite(new ITmfCallsite() { - @Override - public long getLineNumber() { - return 0; - } - - @Override - public String getFunctionName() { - return null; - } - - @Override - public String getFileName() { - return null; - } - }); - } - - @Test(expected=IllegalArgumentException.class) - public void testCallsiteFileNull() { - new TmfCallsite(null, fFunctionName1, fLine1); - } - - // ------------------------------------------------------------------------ - // hashCode - // ------------------------------------------------------------------------ - - @Test - public void testHashCode() { - final ITmfCallsite callsite1b = new TmfCallsite(fCallsite1); - final ITmfCallsite callsite2b = new TmfCallsite(fCallsite2); - - assertTrue("hashCode", fCallsite1.hashCode() == callsite1b.hashCode()); - assertTrue("hashCode", fCallsite2.hashCode() == callsite2b.hashCode()); - - assertTrue("hashCode", fCallsite1.hashCode() != fCallsite2.hashCode()); - assertTrue("hashCode", fCallsite2.hashCode() != fCallsite1.hashCode()); - } - - // ------------------------------------------------------------------------ - // equals - // ------------------------------------------------------------------------ - - @Test - public void testEqualsReflexivity() { - assertTrue("equals", fCallsite1.equals(fCallsite1)); - assertTrue("equals", fCallsite2.equals(fCallsite2)); - - assertFalse("equals", fCallsite1.equals(fCallsite2)); - assertFalse("equals", fCallsite2.equals(fCallsite1)); - } - - @Test - public void testEqualsSymmetry() { - final ITmfCallsite callsite1 = new TmfCallsite(fCallsite1); - final ITmfCallsite callsite2 = new TmfCallsite(fCallsite2); - - assertTrue("equals", callsite1.equals(fCallsite1)); - assertTrue("equals", fCallsite1.equals(callsite1)); - - assertTrue("equals", callsite2.equals(fCallsite2)); - assertTrue("equals", fCallsite2.equals(callsite2)); - } - - @Test - public void testEqualsTransivity() { - final ITmfCallsite callsite1 = new TmfCallsite(fCallsite1); - final ITmfCallsite callsite2 = new TmfCallsite(fCallsite1); - final ITmfCallsite callsite3 = new TmfCallsite(fCallsite1); - - assertTrue("equals", callsite1.equals(callsite2)); - assertTrue("equals", callsite2.equals(callsite3)); - assertTrue("equals", callsite1.equals(callsite3)); - } - - @Test - public void testEqualsNull() { - assertFalse("equals", fCallsite1.equals(null)); - assertFalse("equals", fCallsite2.equals(null)); - assertFalse("equals", fCallsite3.equals(null)); - } - - @Test - public void testNonEqualClasses() { - assertFalse("equals", fCallsite1.equals(fCallsite1.getFileName())); - } - - @Test - public void testNullElements() { - ITmfCallsite callsite = new TmfCallsite(fFileName1, null, fLine1); - assertFalse("equals", fCallsite1.equals(callsite)); - assertFalse("equals", callsite.equals(fCallsite1)); - } - - // ------------------------------------------------------------------------ - // toString - // ------------------------------------------------------------------------ - - @Test - public void testToString() { - assertEquals("toString", "filename1:10 func1()", fCallsite1.toString()); - assertEquals("toString", "filename2:25 func2()", fCallsite2.toString()); - assertEquals("toString", "filename3:123", fCallsite3.toString()); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/filter/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/filter/AllTests.java deleted file mode 100644 index 967226e8c3..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/filter/AllTests.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.filter; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Filter tests. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TmfCollapseFilterTest.class, -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/filter/TmfCollapseFilterTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/filter/TmfCollapseFilterTest.java deleted file mode 100644 index 4c58f80685..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/filter/TmfCollapseFilterTest.java +++ /dev/null @@ -1,168 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.filter; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import org.eclipse.linuxtools.internal.tmf.core.filter.TmfCollapseFilter; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.eclipse.linuxtools.tmf.core.event.collapse.ITmfCollapsibleEvent; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.junit.Test; - -/** - * Test suite for the {@link TmfCollpaseFilter} class. - * - * @author Bernd Hufmann - */ -@SuppressWarnings("javadoc") -public class TmfCollapseFilterTest { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - private CollapsibleEvent fCollapsibleEvent1 = new CollapsibleEvent(true); - private CollapsibleEvent fCollapsibleEvent2 = new CollapsibleEvent(true); - private CollapsibleEvent fCollapsibleEvent3 = new CollapsibleEvent(false); - private NonCollapsibleEvent fNonCollapsibleEvent1 = new NonCollapsibleEvent(); - private TmfCollapseFilter fFilter = new TmfCollapseFilter(); - - // ------------------------------------------------------------------------ - // matches - // ------------------------------------------------------------------------ - - @Test - public void testMatches() { - - TmfCollapseFilter filter = new TmfCollapseFilter(); - - assertTrue(filter.matches(fCollapsibleEvent1)); - assertFalse(filter.matches(fCollapsibleEvent2)); - assertFalse(filter.matches(fCollapsibleEvent1)); - assertFalse(filter.matches(fCollapsibleEvent2)); - assertTrue(filter.matches(fNonCollapsibleEvent1)); - assertTrue(filter.matches(fNonCollapsibleEvent1)); - assertTrue(filter.matches(fCollapsibleEvent1)); - assertFalse(filter.matches(fCollapsibleEvent2)); - assertTrue(filter.matches(fCollapsibleEvent3)); - } - - @Test - public void testInterfaces() { - assertNull("getParent()", fFilter.getParent()); - assertEquals("getName()", "Collapse", fFilter.getNodeName()); - assertEquals("hasChildren()", false, fFilter.hasChildren()); - assertEquals("getChildrenCount()", 0, fFilter.getChildrenCount()); - assertEquals("getChildren()", 0, fFilter.getChildren().length); - } - - @Test - public void testClone() { - assertNotEquals("clone()", fFilter, fFilter.clone()); - } - - @Test(expected=UnsupportedOperationException.class) - public void testGetChild() { - fFilter.getChild(0); - } - - @Test(expected=UnsupportedOperationException.class) - public void testRemove() { - fFilter.remove(); - } - - @Test(expected=UnsupportedOperationException.class) - public void testRemoveChild() { - fFilter.removeChild(null); - } - - @Test(expected=UnsupportedOperationException.class) - public void testAddChild() { - fFilter.addChild(null); - } - - @Test(expected=UnsupportedOperationException.class) - public void testReplaceChild() { - fFilter.replaceChild(0, null); - } - - @Test(expected=UnsupportedOperationException.class) - public void testGetValidChildren() { - fFilter.getValidChildren(); - } - - // ------------------------------------------------------------------------ - // Helper Classes - // ------------------------------------------------------------------------ - - private class CollapsibleEvent extends TmfEvent implements ITmfCollapsibleEvent { - - private final boolean fIsCollapsible; - CollapsibleEvent(boolean isCollapsible) { - super(); - fIsCollapsible = isCollapsible; - } - @Override - public boolean isCollapsibleWith(ITmfEvent otherEvent) { - return ((CollapsibleEvent)otherEvent).fIsCollapsible; - } - } - - private class NonCollapsibleEvent implements ITmfEvent { - - @Override - public Object getAdapter(Class adapter) { - return null; - } - @Override - public ITmfTrace getTrace() { - return null; - } - @Override - public long getRank() { - return 0; - } - @Override - public ITmfTimestamp getTimestamp() { - return new TmfNanoTimestamp(100); - } - @Override - public String getSource() { - return ""; - } - @Override - public ITmfEventType getType() { - return new TmfEventType(); - } - @Override - public ITmfEventField getContent() { - return new TmfEventField("testField", "test", null); - } - @Override - public String getReference() { - return "remote"; - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/request/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/request/AllTests.java deleted file mode 100644 index 59c5dbef42..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/request/AllTests.java +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.request; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Requests tests - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TmfCoalescedEventRequestTest.class, - TmfEventRequestTest.class, -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/request/TmfCoalescedEventRequestTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/request/TmfCoalescedEventRequestTest.java deleted file mode 100644 index ae5ce9c933..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/request/TmfCoalescedEventRequestTest.java +++ /dev/null @@ -1,594 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.request; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.Vector; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.linuxtools.internal.tmf.core.component.TmfProviderManager; -import org.eclipse.linuxtools.internal.tmf.core.request.TmfCoalescedEventRequest; -import org.eclipse.linuxtools.tmf.core.component.ITmfEventProvider; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest.ExecutionType; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.tests.TmfCoreTestPlugin; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.tests.stubs.request.TmfEventRequestStub; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; -import org.junit.Before; -import org.junit.Test; - -/** - * Test suite for the TmfCoalescedEventRequest class. - */ -@SuppressWarnings("javadoc") -public class TmfCoalescedEventRequestTest { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - private final TmfTimeRange range1 = new TmfTimeRange(TmfTimeRange.ETERNITY); - private final TmfTimeRange range2 = new TmfTimeRange(new TmfTimestamp(), TmfTimestamp.BIG_CRUNCH); - - private TmfCoalescedEventRequest fRequest1; - private TmfCoalescedEventRequest fRequest2; - private TmfCoalescedEventRequest fRequest3; - private TmfCoalescedEventRequest fRequest4; - - private TmfCoalescedEventRequest fRequest1b; - private TmfCoalescedEventRequest fRequest1c; - - private int fRequestCount; - - // ------------------------------------------------------------------------ - // Housekeeping - // ------------------------------------------------------------------------ - - @Before - public void setUp() { - TmfEventRequest.reset(); - fRequest1 = new TmfCoalescedEventRequest(ITmfEvent.class, range1, 0, 100, ExecutionType.FOREGROUND); - fRequest2 = new TmfCoalescedEventRequest(ITmfEvent.class, range2, 0, 100, ExecutionType.FOREGROUND); - fRequest3 = new TmfCoalescedEventRequest(ITmfEvent.class, range2, 0, 200, ExecutionType.FOREGROUND); - fRequest4 = new TmfCoalescedEventRequest(ITmfEvent.class, range2, 0, 200, ExecutionType.FOREGROUND); - - fRequest1b = new TmfCoalescedEventRequest(ITmfEvent.class, range1, 0, 100, ExecutionType.FOREGROUND); - fRequest1c = new TmfCoalescedEventRequest(ITmfEvent.class, range1, 0, 100, ExecutionType.FOREGROUND); - - fRequestCount = fRequest1c.getRequestId() + 1; - } - - private TmfCoalescedEventRequest setupTestRequest(final boolean[] flags) { - - TmfCoalescedEventRequest request = new TmfCoalescedEventRequest(ITmfEvent.class, range1, 0, 100, ExecutionType.FOREGROUND) { - @Override - public void handleCompleted() { - super.handleCompleted(); - flags[0] = true; - } - - @Override - public void handleSuccess() { - super.handleSuccess(); - flags[1] = true; - } - - @Override - public void handleFailure() { - super.handleFailure(); - flags[2] = true; - } - - @Override - public void handleCancel() { - super.handleCancel(); - flags[3] = true; - } - }; - return request; - } - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - @Test - public void testTmfCoalescedEventRequestIndexNbEventsBlocksize() { - TmfCoalescedEventRequest request = new TmfCoalescedEventRequest(ITmfEvent.class, range1, 0, 100, ExecutionType.FOREGROUND); - - assertEquals("getRequestId", fRequestCount++, request.getRequestId()); - assertEquals("getDataType", ITmfEvent.class, request.getDataType()); - - assertEquals("getRange", range1, request.getRange()); - assertEquals("getNbRequestedEvents", 100, request.getNbRequested()); - - assertFalse("isCompleted", request.isCompleted()); - assertFalse("isFailed", request.isFailed()); - assertFalse("isCancelled", request.isCancelled()); - - assertEquals("getNbRead", 0, request.getNbRead()); - } - - // ------------------------------------------------------------------------ - // equals - // ------------------------------------------------------------------------ - - @Test - public void testEqualsReflexivity() { - assertTrue("equals", fRequest1.equals(fRequest1)); - assertTrue("equals", fRequest2.equals(fRequest2)); - - assertFalse("equals", fRequest1.equals(fRequest2)); - assertFalse("equals", fRequest2.equals(fRequest1)); - } - - @Test - public void testEqualsSymmetry() { - assertTrue("equals", fRequest1.equals(fRequest1b)); - assertTrue("equals", fRequest1b.equals(fRequest1)); - - assertFalse("equals", fRequest1.equals(fRequest3)); - assertFalse("equals", fRequest2.equals(fRequest3)); - assertFalse("equals", fRequest3.equals(fRequest1)); - assertFalse("equals", fRequest3.equals(fRequest2)); - } - - @Test - public void testEqualsTransivity() { - assertTrue("equals", fRequest1.equals(fRequest1b)); - assertTrue("equals", fRequest1b.equals(fRequest1c)); - assertTrue("equals", fRequest1.equals(fRequest1c)); - } - - @Test - public void testEqualsNull() { - assertFalse("equals", fRequest1.equals(null)); - assertFalse("equals", fRequest2.equals(null)); - } - - // ------------------------------------------------------------------------ - // hashCode - // ------------------------------------------------------------------------ - - @Test - public void testHashCode() { - assertTrue("hashCode", fRequest1.hashCode() == fRequest1.hashCode()); - assertTrue("hashCode", fRequest2.hashCode() == fRequest2.hashCode()); - assertTrue("hashCode", fRequest1.hashCode() != fRequest2.hashCode()); - } - - // ------------------------------------------------------------------------ - // toString - // ------------------------------------------------------------------------ - - @Test - public void testToString() { - String expected1 = "[TmfCoalescedEventRequest(0,ITmfEvent,FOREGROUND," + range1 + ",0,100, [])]"; - String expected2 = "[TmfCoalescedEventRequest(1,ITmfEvent,FOREGROUND," + range2 + ",0,100, [])]"; - String expected3 = "[TmfCoalescedEventRequest(2,ITmfEvent,FOREGROUND," + range2 + ",0,200, [])]"; - String expected4 = "[TmfCoalescedEventRequest(3,ITmfEvent,FOREGROUND," + range2 + ",0,200, [])]"; - - assertEquals("toString", expected1, fRequest1.toString()); - assertEquals("toString", expected2, fRequest2.toString()); - assertEquals("toString", expected3, fRequest3.toString()); - assertEquals("toString", expected4, fRequest4.toString()); - } - - // ------------------------------------------------------------------------ - // isCompatible - // ------------------------------------------------------------------------ - - @Test - public void testIsCompatible() { - TmfCoalescedEventRequest coalescedRequest = new TmfCoalescedEventRequest(ITmfEvent.class, range1, 0, 100, ExecutionType.FOREGROUND); - TmfEventRequest req1 = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); - TmfEventRequest req2 = new TmfEventRequestStub(ITmfEvent.class, range2, 100, 200); - TmfEventRequest req3 = new TmfEventRequestStub(ITmfEvent.class, range1, 101, 200); - - assertTrue("isCompatible", coalescedRequest.isCompatible(req1)); - assertTrue("isCompatible", coalescedRequest.isCompatible(req2)); - assertTrue("isCompatible", coalescedRequest.isCompatible(req3)); - } - - // ------------------------------------------------------------------------ - // addEvent - // ------------------------------------------------------------------------ - - @Test - public void testAddEvent1() { - TmfCoalescedEventRequest coalescedRequest = new TmfCoalescedEventRequest(ITmfEvent.class, range1, 0, 2147483647, ExecutionType.FOREGROUND); - TmfEventRequest req1 = new TmfEventRequestStub(ITmfEvent.class, range1, 0, 2147483647, 200); - TmfEventRequest req2 = new TmfEventRequestStub(ITmfEvent.class, range1, 1, 2147483647, 200); - - assertTrue("isCompatible", coalescedRequest.isCompatible(req1)); - assertTrue("isCompatible", coalescedRequest.isCompatible(req2)); - - coalescedRequest.addRequest(req1); - coalescedRequest.addRequest(req2); - - assertEquals("addRequest", 0, coalescedRequest.getIndex()); - assertEquals("addRequest", 2147483647, coalescedRequest.getNbRequested()); - } - - @Test - public void testAddEvent2() { - TmfCoalescedEventRequest coalescedRequest = new TmfCoalescedEventRequest(ITmfEvent.class, range1, 1, 2147483647, ExecutionType.FOREGROUND); - TmfEventRequest req1 = new TmfEventRequestStub(ITmfEvent.class, range1, 1, 2147483647, 200); - TmfEventRequest req2 = new TmfEventRequestStub(ITmfEvent.class, range1, 0, 2147483647, 200); - - assertTrue("isCompatible", coalescedRequest.isCompatible(req1)); - assertTrue("isCompatible", coalescedRequest.isCompatible(req2)); - - coalescedRequest.addRequest(req1); - coalescedRequest.addRequest(req2); - - assertEquals("addRequest", 0, coalescedRequest.getIndex()); - assertEquals("addRequest", 2147483647, coalescedRequest.getNbRequested()); - } - - // ------------------------------------------------------------------------ - // done - // ------------------------------------------------------------------------ - - @Test - public void testDone() { - // Test request - final boolean[] crFlags = new boolean[4]; - TmfCoalescedEventRequest request = setupTestRequest(crFlags); - TmfEventRequest subRequest1 = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); - TmfEventRequest subRequest2 = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); - request.addRequest(subRequest1); - request.addRequest(subRequest2); - - request.done(); - - // Validate the coalescing request - assertTrue("isCompleted", request.isCompleted()); - assertFalse("isFailed", request.isFailed()); - assertFalse("isCancelled", request.isCancelled()); - - assertTrue("handleCompleted", crFlags[0]); - assertTrue("handleSuccess", crFlags[1]); - assertFalse("handleFailure", crFlags[2]); - assertFalse("handleCancel", crFlags[3]); - - // Validate the first coalesced request - assertTrue("isCompleted", subRequest1.isCompleted()); - assertFalse("isFailed", subRequest1.isFailed()); - assertFalse("isCancelled", subRequest1.isCancelled()); - - // Validate the second coalesced request - assertTrue("isCompleted", subRequest2.isCompleted()); - assertFalse("isFailed", subRequest2.isFailed()); - assertFalse("isCancelled", subRequest2.isCancelled()); - } - - // ------------------------------------------------------------------------ - // fail - // ------------------------------------------------------------------------ - - @Test - public void testFail() { - final boolean[] crFlags = new boolean[4]; - TmfCoalescedEventRequest request = setupTestRequest(crFlags); - TmfEventRequest subRequest1 = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); - TmfEventRequest subRequest2 = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); - request.addRequest(subRequest1); - request.addRequest(subRequest2); - - request.fail(); - - // Validate the coalescing request - assertTrue("isCompleted", request.isCompleted()); - assertTrue("isFailed", request.isFailed()); - assertFalse("isCancelled", request.isCancelled()); - - assertTrue("handleCompleted", crFlags[0]); - assertFalse("handleSuccess", crFlags[1]); - assertTrue("handleFailure", crFlags[2]); - assertFalse("handleCancel", crFlags[3]); - - // Validate the first coalesced request - assertTrue("isCompleted", subRequest1.isCompleted()); - assertTrue("isFailed", subRequest1.isFailed()); - assertFalse("isCancelled", subRequest1.isCancelled()); - - // Validate the second coalesced request - assertTrue("isCompleted", subRequest2.isCompleted()); - assertTrue("isFailed", subRequest2.isFailed()); - assertFalse("isCancelled", subRequest2.isCancelled()); - } - - // ------------------------------------------------------------------------ - // cancel - // ------------------------------------------------------------------------ - - @Test - public void testCancel() { - final boolean[] crFlags = new boolean[4]; - TmfCoalescedEventRequest request = setupTestRequest(crFlags); - TmfEventRequest subRequest1 = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); - TmfEventRequest subRequest2 = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); - request.addRequest(subRequest1); - request.addRequest(subRequest2); - - request.cancel(); - - // Validate the coalescing request - assertTrue("isCompleted", request.isCompleted()); - assertFalse("isFailed", request.isFailed()); - assertTrue("isCancelled", request.isCancelled()); - - assertTrue("handleCompleted", crFlags[0]); - assertFalse("handleSuccess", crFlags[1]); - assertFalse("handleFailure", crFlags[2]); - assertTrue("handleCancel", crFlags[3]); - - // Validate the first coalesced request - assertTrue("isCompleted", subRequest1.isCompleted()); - assertFalse("isFailed", subRequest1.isFailed()); - assertTrue("isCancelled", subRequest1.isCancelled()); - - // Validate the second coalesced request - assertTrue("isCompleted", subRequest2.isCompleted()); - assertFalse("isFailed", subRequest2.isFailed()); - assertTrue("isCancelled", subRequest2.isCancelled()); - } - - // ------------------------------------------------------------------------ - // Coalescing - // ------------------------------------------------------------------------ - - private static final TmfTestTrace TEST_TRACE = TmfTestTrace.A_TEST_10K; - private static final int NB_EVENTS = 5000; - - // Initialize the test trace - private TmfTraceStub fTrace = null; - - private synchronized TmfTraceStub setupTrace(String path) { - if (fTrace == null) { - try { - URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(path), null); - File test = new File(FileLocator.toFileURL(location).toURI()); - fTrace = new TmfTraceStub(test.getPath(), 500, false, null); - } catch (TmfTraceException e) { - e.printStackTrace(); - } catch (URISyntaxException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - return fTrace; - } - - Vector requestedEvents1; - Vector requestedEvents2; - Vector requestedEvents3; - - TmfEventRequest request1; - TmfEventRequest request2; - TmfEventRequest request3; - - ITmfEventProvider[] providers; - - private static class TmfTestTriggerSignal extends TmfSignal { - public final boolean forceCancel; - public final long fIndex; - - public TmfTestTriggerSignal(Object source, long index, boolean cancel) { - super(source); - forceCancel = cancel; - fIndex = index; - } - } - - private static class TmfTestTriggerSignal2 extends TmfSignal { - public TmfTestTriggerSignal2(Object source) { - super(source); - } - } - - @TmfSignalHandler - public void trigger(final TmfTestTriggerSignal signal) { - - TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - final long REQUEST_OFFSET = 1000; - - requestedEvents1 = new Vector<>(); - request1 = new TmfEventRequest(ITmfEvent.class, range, signal.fIndex, - NB_EVENTS, ExecutionType.FOREGROUND) { - @Override - public void handleData(ITmfEvent event) { - super.handleData(event); - if (!isCompleted()) { - requestedEvents1.add(event); - if (signal.forceCancel) { - cancel(); - } - } - } - }; - - requestedEvents2 = new Vector<>(); - request2 = new TmfEventRequest(ITmfEvent.class, range, - signal.fIndex + REQUEST_OFFSET, NB_EVENTS, ExecutionType.FOREGROUND) { - @Override - public void handleData(ITmfEvent event) { - super.handleData(event); - if (!isCompleted()) { - requestedEvents2.add(event); - } - } - }; - - requestedEvents3 = new Vector<>(); - request3 = new TmfEventRequest(ITmfEvent.class, range, - signal.fIndex + 2 * REQUEST_OFFSET, NB_EVENTS, ExecutionType.FOREGROUND) { - @Override - public void handleData(ITmfEvent event) { - super.handleData(event); - if (!isCompleted()) { - requestedEvents3.add(event); - } - } - }; - - providers = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); - providers[0].sendRequest(request1); - providers[0].sendRequest(request2); - providers[0].sendRequest(request3); - } - - /** - * @param signal - * the trigger signal - */ - @TmfSignalHandler - public void trigger(final TmfTestTriggerSignal2 signal) { - TmfTimeRange range = new TmfTimeRange(new TmfTimestamp(100, -3), TmfTimestamp.BIG_CRUNCH); - requestedEvents1 = new Vector<>(); - request1 = new TmfEventRequest(ITmfEvent.class, range, 0, 1, ExecutionType.FOREGROUND) { - @Override - public void handleData(ITmfEvent event) { - super.handleData(event); - if (!isCompleted()) { - requestedEvents1.add(event); - } - } - }; - providers = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); - providers[0].sendRequest(request1); - } - - public void runCoalescedRequest(long startIndex) throws InterruptedException { - - fTrace = setupTrace(TEST_TRACE.getFullPath()); - - TmfSignalManager.register(this); - TmfTestTriggerSignal signal = new TmfTestTriggerSignal(this, startIndex, false); - TmfSignalManager.dispatchSignal(signal); - - request1.waitForCompletion(); - request2.waitForCompletion(); - request3.waitForCompletion(); - - try { - assertEquals("Request1: nbEvents", NB_EVENTS, requestedEvents1.size()); - assertTrue("Request1: isCompleted", request1.isCompleted()); - assertFalse("Request1: isCancelled", request1.isCancelled()); - - assertEquals("Request2: nbEvents", NB_EVENTS, requestedEvents2.size()); - assertTrue("Request2: isCompleted", request2.isCompleted()); - assertFalse("Request2: isCancelled", request2.isCancelled()); - - assertEquals("Request3: nbEvents", NB_EVENTS, requestedEvents3.size()); - assertTrue("Request3: isCompleted", request3.isCompleted()); - assertFalse("Request3: isCancelled", request3.isCancelled()); - - // Ensure that we have distinct events. - // Don't go overboard: we are not validating the stub! - for (int i = 0; i < NB_EVENTS; i++) { - assertEquals("Distinct events", i + 1 + request1.getIndex(), requestedEvents1.get(i).getTimestamp().getValue()); - assertEquals("Distinct events", i + 1 + request2.getIndex(), requestedEvents2.get(i).getTimestamp().getValue()); - assertEquals("Distinct events", i + 1 + request3.getIndex(), requestedEvents3.get(i).getTimestamp().getValue()); - } - } finally { - TmfSignalManager.deregister(this); - fTrace.dispose(); - fTrace = null; - } - } - - @Test - public void testCoalescedRequest() throws InterruptedException { - runCoalescedRequest(0); - runCoalescedRequest(1); - runCoalescedRequest(5); - } - - @Test - public void testCancelCoalescedRequest() throws InterruptedException { - - fTrace = setupTrace(TEST_TRACE.getFullPath()); - - TmfSignalManager.register(this); - TmfTestTriggerSignal signal = new TmfTestTriggerSignal(this, 0, true); - TmfSignalManager.dispatchSignal(signal); - - request1.waitForCompletion(); - request2.waitForCompletion(); - request3.waitForCompletion(); - - assertTrue("Request1: isCompleted", request1.isCompleted()); - assertTrue("Request1: isCancelled", request1.isCancelled()); - - assertEquals("Request2: nbEvents", NB_EVENTS, requestedEvents2.size()); - assertTrue("Request2: isCompleted", request2.isCompleted()); - assertFalse("Request2: isCancelled", request2.isCancelled()); - - assertEquals("Request3: nbEvents", NB_EVENTS, requestedEvents3.size()); - assertTrue("Request3: isCompleted", request3.isCompleted()); - assertFalse("Request3: isCancelled", request3.isCancelled()); - - // Ensure that we have distinct events. - // Don't go overboard: we are not validating the stub! - for (int i = 0; i < NB_EVENTS; i++) { - assertEquals("Distinct events", i + 1 + request2.getIndex(), requestedEvents2.get(i).getTimestamp().getValue()); - assertEquals("Distinct events", i + 1 + request3.getIndex(), requestedEvents3.get(i).getTimestamp().getValue()); - } - - TmfSignalManager.deregister(this); - fTrace.dispose(); - fTrace = null; - } - - @Test - public void testSingleTimeRequest() throws InterruptedException { - - fTrace = setupTrace(TEST_TRACE.getFullPath()); - - TmfSignalManager.register(this); - TmfTestTriggerSignal2 signal = new TmfTestTriggerSignal2(this); - TmfSignalManager.dispatchSignal(signal); - - request1.waitForCompletion(); - - assertTrue("Request1: isCompleted", request1.isCompleted()); - - // We have to have one event processed - assertEquals("Request1: nbEvents", 1, requestedEvents1.size()); - - TmfSignalManager.deregister(this); - fTrace.dispose(); - fTrace = null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/request/TmfEventRequestTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/request/TmfEventRequestTest.java deleted file mode 100644 index 04c78ccc1f..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/request/TmfEventRequestTest.java +++ /dev/null @@ -1,313 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.request; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.tests.stubs.request.TmfEventRequestStub; -import org.junit.Before; -import org.junit.Test; - -/** - * Test suite for the TmfEventRequest class. - */ -@SuppressWarnings("javadoc") -public class TmfEventRequestTest { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - private static TmfTimeRange range1 = new TmfTimeRange(TmfTimeRange.ETERNITY); - private static TmfTimeRange range2 = new TmfTimeRange(new TmfTimestamp(), TmfTimestamp.BIG_CRUNCH); - - private static TmfEventRequest fRequest1; - private static TmfEventRequest fRequest1b; - private static TmfEventRequest fRequest1c; - private static TmfEventRequest fRequest2; - private static TmfEventRequest fRequest3; - private static TmfEventRequest fRequest4; - - private static int fRequestCount; - - // ------------------------------------------------------------------------ - // Housekeeping - // ------------------------------------------------------------------------ - - @Before - public void setUp() { - TmfEventRequest.reset(); - fRequest1 = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); - fRequest2 = new TmfEventRequestStub(ITmfEvent.class, range2, 100, 200); - fRequest3 = new TmfEventRequestStub(ITmfEvent.class, range2, 200, 200); - fRequest4 = new TmfEventRequestStub(ITmfEvent.class, range2, 200, 300); - fRequest1b = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); - fRequest1c = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); - fRequestCount = fRequest1c.getRequestId() + 1; - } - - private static TmfEventRequest setupTestRequest(final boolean[] flags) { - - TmfEventRequest request = new TmfEventRequestStub(ITmfEvent.class, new TmfTimeRange(TmfTimeRange.ETERNITY), 100, 200) { - @Override - public void handleCompleted() { - super.handleCompleted(); - flags[0] = true; - } - - @Override - public void handleSuccess() { - super.handleSuccess(); - flags[1] = true; - } - - @Override - public void handleFailure() { - super.handleFailure(); - flags[2] = true; - } - - @Override - public void handleCancel() { - super.handleCancel(); - flags[3] = true; - } - }; - return request; - } - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - @Test - public void testTmfEventRequest() { - TmfEventRequest request = new TmfEventRequestStub(ITmfEvent.class); - - assertEquals("getRequestId", fRequestCount++, request.getRequestId()); - assertEquals("getDataType", ITmfEvent.class, request.getDataType()); - - assertEquals("StartTime", TmfTimestamp.BIG_BANG, request.getRange().getStartTime()); - assertEquals("EndTime", TmfTimestamp.BIG_CRUNCH, request.getRange().getEndTime()); - - assertEquals("getRange", TmfTimeRange.ETERNITY, request.getRange()); - assertSame("getRange", TmfTimeRange.ETERNITY, request.getRange()); - - assertEquals("getIndex", 0, request.getIndex()); - assertEquals("getNbRequestedEvents", ITmfEventRequest.ALL_DATA, request.getNbRequested()); - - assertFalse("isCompleted", request.isCompleted()); - assertFalse("isFailed", request.isFailed()); - assertFalse("isCancelled", request.isCancelled()); - - assertEquals("getNbRead", 0, request.getNbRead()); - } - - @Test - public void testTmfEventRequestTimeRange() { - TmfTimeRange range = new TmfTimeRange(new TmfTimestamp(), TmfTimestamp.BIG_CRUNCH); - TmfEventRequest request = new TmfEventRequestStub(ITmfEvent.class, range); - - assertEquals("getRequestId", fRequestCount++, request.getRequestId()); - assertEquals("getDataType", ITmfEvent.class, request.getDataType()); - - assertEquals("StartTime", new TmfTimestamp(), request.getRange().getStartTime()); - assertEquals("EndTime", TmfTimestamp.BIG_CRUNCH, request.getRange().getEndTime()); - - assertEquals("getIndex", 0, request.getIndex()); - assertEquals("getNbRequestedEvents", ITmfEventRequest.ALL_DATA, request.getNbRequested()); - - assertFalse("isCompleted", request.isCompleted()); - assertFalse("isFailed", request.isFailed()); - assertFalse("isCancelled", request.isCancelled()); - - assertEquals("getNbRead", 0, request.getNbRead()); - } - - @Test - public void testTmfEventRequestTimeRangeNbRequested() { - TmfTimeRange range = new TmfTimeRange(new TmfTimestamp(), TmfTimestamp.BIG_CRUNCH); - TmfEventRequest request = new TmfEventRequestStub(ITmfEvent.class, range, 100); - - assertEquals("getRequestId", fRequestCount++, request.getRequestId()); - assertEquals("getDataType", ITmfEvent.class, request.getDataType()); - - assertEquals("StartTime", new TmfTimestamp(), request.getRange().getStartTime()); - assertEquals("EndTime", TmfTimestamp.BIG_CRUNCH, request.getRange().getEndTime()); - - assertEquals("getIndex", 0, request.getIndex()); - assertEquals("getNbRequestedEvents", 100, request.getNbRequested()); - - assertFalse("isCompleted", request.isCompleted()); - assertFalse("isFailed", request.isFailed()); - assertFalse("isCancelled", request.isCancelled()); - - assertEquals("getNbRead", 0, request.getNbRead()); - } - - @Test - public void testTmfEventRequestTimeRangeNbRequestedBlocksize() { - TmfTimeRange range = new TmfTimeRange(new TmfTimestamp(), TmfTimestamp.BIG_CRUNCH); - TmfEventRequest request = new TmfEventRequestStub(ITmfEvent.class, range, 100, 200); - - assertEquals("getRequestId", fRequestCount++, request.getRequestId()); - assertEquals("getDataType", ITmfEvent.class, request.getDataType()); - - assertEquals("StartTime", new TmfTimestamp(), request.getRange().getStartTime()); - assertEquals("EndTime", TmfTimestamp.BIG_CRUNCH, request.getRange().getEndTime()); - - assertEquals("getIndex", 0, request.getIndex()); - assertEquals("getNbRequestedEvents", 100, request.getNbRequested()); - - assertFalse("isCompleted", request.isCompleted()); - assertFalse("isFailed", request.isFailed()); - assertFalse("isCancelled", request.isCancelled()); - - assertEquals("getNbRead", 0, request.getNbRead()); - } - - // ------------------------------------------------------------------------ - // equals - // ------------------------------------------------------------------------ - - @Test - public void testEqualsReflexivity() { - assertTrue("equals", fRequest1.equals(fRequest1)); - assertTrue("equals", fRequest2.equals(fRequest2)); - - assertFalse("equals", fRequest1.equals(fRequest2)); - assertFalse("equals", fRequest2.equals(fRequest1)); - } - - @Test - public void testEqualsSymmetry() { - assertTrue("equals", fRequest1.equals(fRequest1b)); - assertTrue("equals", fRequest1b.equals(fRequest1)); - - assertFalse("equals", fRequest1.equals(fRequest3)); - assertFalse("equals", fRequest2.equals(fRequest3)); - assertFalse("equals", fRequest3.equals(fRequest1)); - assertFalse("equals", fRequest3.equals(fRequest2)); - } - - @Test - public void testEqualsTransivity() { - assertTrue("equals", fRequest1.equals(fRequest1b)); - assertTrue("equals", fRequest1b.equals(fRequest1c)); - assertTrue("equals", fRequest1.equals(fRequest1c)); - } - - @Test - public void testEqualsNull() { - assertFalse("equals", fRequest1.equals(null)); - assertFalse("equals", fRequest2.equals(null)); - } - - // ------------------------------------------------------------------------ - // hashCode - // ------------------------------------------------------------------------ - - @Test - public void testHashCode() { - assertTrue("hashCode", fRequest1.hashCode() == fRequest1.hashCode()); - assertTrue("hashCode", fRequest2.hashCode() == fRequest2.hashCode()); - assertTrue("hashCode", fRequest1.hashCode() != fRequest2.hashCode()); - } - - // ------------------------------------------------------------------------ - // toString - // ------------------------------------------------------------------------ - - @Test - public void testToString() { - String expected1 = "[TmfEventRequestStub(0,ITmfEvent,FOREGROUND," + range1 + ",0,100)]"; - String expected2 = "[TmfEventRequestStub(1,ITmfEvent,FOREGROUND," + range2 + ",0,100)]"; - String expected3 = "[TmfEventRequestStub(2,ITmfEvent,FOREGROUND," + range2 + ",0,200)]"; - String expected4 = "[TmfEventRequestStub(3,ITmfEvent,FOREGROUND," + range2 + ",0,200)]"; - - assertEquals("toString", expected1, fRequest1.toString()); - assertEquals("toString", expected2, fRequest2.toString()); - assertEquals("toString", expected3, fRequest3.toString()); - assertEquals("toString", expected4, fRequest4.toString()); - } - - // ------------------------------------------------------------------------ - // done - // ------------------------------------------------------------------------ - - @Test - public void testDone() { - final boolean[] flags = new boolean[4]; - TmfEventRequest request = setupTestRequest(flags); - request.done(); - - assertTrue("isCompleted", request.isCompleted()); - assertFalse("isFailed", request.isFailed()); - assertFalse("isCancelled", request.isCancelled()); - - assertTrue("handleCompleted", flags[0]); - assertTrue("handleSuccess", flags[1]); - assertFalse("handleFailure", flags[2]); - assertFalse("handleCancel", flags[3]); - } - - // ------------------------------------------------------------------------ - // fail - // ------------------------------------------------------------------------ - - @Test - public void testFail() { - final boolean[] flags = new boolean[4]; - TmfEventRequest request = setupTestRequest(flags); - request.fail(); - - assertTrue("isCompleted", request.isCompleted()); - assertTrue("isFailed", request.isFailed()); - assertFalse("isCancelled", request.isCancelled()); - - assertTrue("handleCompleted", flags[0]); - assertFalse("handleSuccess", flags[1]); - assertTrue("handleFailure", flags[2]); - assertFalse("handleCancel", flags[3]); - } - - // ------------------------------------------------------------------------ - // cancel - // ------------------------------------------------------------------------ - - @Test - public void testCancel() { - final boolean[] flags = new boolean[4]; - TmfEventRequest request = setupTestRequest(flags); - request.cancel(); - - assertTrue("isCompleted", request.isCompleted()); - assertFalse("isFailed", request.isFailed()); - assertTrue("isCancelled", request.isCancelled()); - - assertTrue("handleCompleted", flags[0]); - assertFalse("handleSuccess", flags[1]); - assertFalse("handleFailure", flags[2]); - assertTrue("handleCancel", flags[3]); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/signal/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/signal/AllTests.java deleted file mode 100644 index 804e4abd89..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/signal/AllTests.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.signal; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Signal tests - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TmfSignalManagerTest.class, - TmfSignalThrottlerTest.class -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/signal/TmfSignalManagerTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/signal/TmfSignalManagerTest.java deleted file mode 100644 index 2dfb57dbd8..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/signal/TmfSignalManagerTest.java +++ /dev/null @@ -1,558 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.signal; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CountDownLatch; - -import org.eclipse.linuxtools.tmf.core.component.TmfComponent; -import org.eclipse.linuxtools.tmf.core.signal.TmfEndSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfStartSynchSignal; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Test suite for {@link TmfSignalManager} - * - * @author Bernd Hufmann - */ -public class TmfSignalManagerTest { - - private TestSignalSender signalSender; - - /** - * Pre-test setup - */ - @Before - public void setUp() { - signalSender = new TestSignalSender(); - } - - /** - * After-test cleanup - */ - @After - public void tearDown() { - signalSender.dispose(); - } - - // ------------------------------------------------------------------------ - // Test cases - // ------------------------------------------------------------------------ - - /** - * Test send and receive including synch signals. - */ - @Test - public void testSendReceive() { - final int NB_HANDLERS = 10; - TestSignalHandler[] signalReceivers = new TestSignalHandler[NB_HANDLERS]; - for (int i = 0; i < NB_HANDLERS; i++) { - signalReceivers[i] = new TestSignalHandler(); - } - final TestSignal1 firstSignal = new TestSignal1(signalSender); - final TestSignal2 secondSignal = new TestSignal2(signalSender); - - final Class[] expectedOrder = new Class[] { - TmfStartSynchSignal.class, TestSignal1.class, TmfEndSynchSignal.class, - TmfStartSynchSignal.class, TestSignal2.class, TmfEndSynchSignal.class }; - - try { - signalSender.sendSignal(firstSignal); - signalSender.sendSignal(secondSignal); - - for (int i = 0; i < NB_HANDLERS; i++) { - assertEquals(expectedOrder.length, signalReceivers[i].receivedSignals.size()); - - for (int k = 0; k < expectedOrder.length; k++) { - assertEquals(signalReceivers[i].receivedSignals.get(k).getClass(), expectedOrder[k]); - } - - for (int k = 0; k < expectedOrder.length; k += 3) { - // Verify signal IDs - int startSyncId = signalReceivers[i].receivedSignals.get(k).getReference(); - int signalId = signalReceivers[i].receivedSignals.get(k + 1).getReference(); - int endSyncId = signalReceivers[i].receivedSignals.get(k + 2).getReference(); - - assertEquals(startSyncId, signalId); - assertEquals(startSyncId, endSyncId); - } - } - } finally { - // Make sure that handlers are disposed in any case (success or not success) - for (int i = 0; i < NB_HANDLERS; i++) { - signalReceivers[i].dispose(); - } - } - } - - /** - * Test nesting signals. Verify that they are handled in the same thread. - */ - @Test - public void testNestedSignals() { - TestSignalHandlerNested signalResender = new TestSignalHandlerNested(); - TestSignalHandler signalReceiver = new TestSignalHandler(); - - final TestSignal1 mainSignal = new TestSignal1(signalSender); - - final Class[] expectedOrder = new Class[] { - TmfStartSynchSignal.class, - TmfStartSynchSignal.class, - TestSignal2.class, - TmfEndSynchSignal.class, - TmfStartSynchSignal.class, - TmfStartSynchSignal.class, - TestSignal4.class, - TmfEndSynchSignal.class, - TestSignal3.class, - TmfEndSynchSignal.class, - TestSignal1.class, - TmfEndSynchSignal.class - }; - - /* - * Index of signals in array signalReceiver.receivedSignals which have - * to have the same signal ID. - */ - - final int[] sameSigNoIndex = new int[] { - 0, 10, 11, 1, 2, 3, 4, 8, 9, 5, 6, 7 - }; - - try { - signalSender.sendSignal(mainSignal); - - assertEquals(expectedOrder.length, signalReceiver.receivedSignals.size()); - - for (int i = 0; i < expectedOrder.length; i++) { - assertEquals(signalReceiver.receivedSignals.get(i).getClass(), expectedOrder[i]); - } - - for (int i = 0; i < sameSigNoIndex.length; i+=3) { - // Verify signal IDs - int startSyncId = signalReceiver.receivedSignals.get(sameSigNoIndex[i]).getReference(); - int signalId = signalReceiver.receivedSignals.get(sameSigNoIndex[i + 1]).getReference(); - int endSyncId = signalReceiver.receivedSignals.get(sameSigNoIndex[i + 2]).getReference(); - assertEquals(startSyncId, signalId); - assertEquals(startSyncId, endSyncId); - } - } finally { - // Make sure that handlers are disposed in any case (success or not success) - signalResender.dispose(); - signalReceiver.dispose(); - } - } - - /** - * Test concurrent signals. Verify that they are handled one after each - * other. - */ - @Test - public void testConcurrentSignals() { - - TestSignalHandlerNested signalResender = new TestSignalHandlerNested(); - TestSignalHandler signalReceiver = new TestSignalHandler(false, null); - - /* - * Test of synchronization of signal manager. - * - * The order of received signals is either set of signals triggered by - * thread1 before set of signals triggered by thread2 or the other way - * around. - * - * If both received sets were interleaved then the synchronization of - * the signal manager would be not working. - */ - - final Class[] expectedOrder1 = new Class[] { - TestSignal2.class, TestSignal4.class, TestSignal3.class, TestSignal1.class, // signals triggered by thread 1 - TestSignal4.class // signal triggered by thread2 - }; - - final Class[] expectedOrder2 = new Class[] { - TestSignal4.class, // signal triggered by thread2 - TestSignal2.class, TestSignal4.class, TestSignal3.class, TestSignal1.class // signals triggered by thread 1 - }; - - /* - * Run it multiple times so that both expected order are triggered - */ - try { - for (int k = 0; k < 10; k++) { - // Latch to ensure that both threads are started - final CountDownLatch startLatch = new CountDownLatch(2); - // Latch to ensure that signals are send roughly at the same time - final CountDownLatch sendLatch = new CountDownLatch(1); - // Latch to ensure that both treads are finished - final CountDownLatch endLatch = new CountDownLatch(2); - - signalReceiver.receivedSignals.clear(); - - Thread senderThread1 = new Thread() { - @Override - public void run() { - startLatch.countDown(); - try { - sendLatch.await(); - } catch (InterruptedException e) { - } - signalSender.sendSignal(new TestSignal1(signalSender)); - endLatch.countDown(); - } - }; - - Thread senderThread2 = new Thread() { - @Override - public void run() { - startLatch.countDown(); - try { - sendLatch.await(); - } catch (InterruptedException e) { - } - signalSender.sendSignal(new TestSignal4(signalSender)); - endLatch.countDown(); - } - }; - - senderThread1.start(); - senderThread2.start(); - try { - startLatch.await(); - } catch (InterruptedException e) { - } - sendLatch.countDown(); - - try { - endLatch.await(); - } catch (InterruptedException e) { - } - - assertEquals(expectedOrder1.length, signalReceiver.receivedSignals.size()); - boolean pass = true; - for (int i = 0; i < expectedOrder1.length; i++) { - if (!signalReceiver.receivedSignals.get(i).getClass().equals(expectedOrder1[i])) { - pass = false; - break; - } - } - - if (!pass) { - for (int i = 0; i < expectedOrder2.length; i++) { - if (!signalReceiver.receivedSignals.get(i).getClass().equals(expectedOrder2[i])) { - fail("Concurrent signal test failure!"); - } - } - } - } - } finally { - // Make sure that handlers are disposed in any case (success or not success) - signalResender.dispose(); - signalReceiver.dispose(); - } - } - - /** - * Test broadcastAsync() - */ - @Test - public void testBroadcastAsync() { - TestSignalHandlerNested signalResender = new TestSignalHandlerNested(false); - - final int NB_HANDLERS = 10; - final CountDownLatch latch = new CountDownLatch(NB_HANDLERS); - TestSignalHandler[] signalReceivers = new TestSignalHandler[NB_HANDLERS]; - for (int i = 0; i < NB_HANDLERS; i++) { - signalReceivers[i] = new TestSignalHandler(false, latch); - } - - final Class[] expectedOrder = new Class[] { - TestSignal1.class, TestSignal2.class, TestSignal3.class, TestSignal4.class - }; - - try { - final TestSignal1 mainSignal = new TestSignal1(signalSender); - signalSender.sendSignal(mainSignal); - - try { - latch.await(); - } catch (InterruptedException e) { - } - - for (int i = 0; i < NB_HANDLERS; i++) { - assertEquals(expectedOrder.length, signalReceivers[i].receivedSignals.size()); - for (int k = 0; k < expectedOrder.length; k++) { - assertEquals(signalReceivers[i].receivedSignals.get(k).getClass(), expectedOrder[k]); - } - } - } finally { - // Make sure that handlers are disposed in any case (success or not success) - for (int i = 0; i < NB_HANDLERS; i++) { - signalReceivers[i].dispose(); - } - signalResender.dispose(); - } - } - - // ------------------------------------------------------------------------ - // Helper classes - // ------------------------------------------------------------------------ - - /** - * Signal sender - */ - private class TestSignalSender extends TmfComponent { - - TestSignalSender() { - super("TestSignalSender"); - } - - /** - * Send a signal - * - * @param signal - * main signal to send - */ - public void sendSignal(TmfSignal signal) { - broadcast(signal); - } - } - - /** - * Signal handler implementation for testing nested signals. - * Needs to be public so TmfSignalManager can see it. - */ - public class TestSignalHandlerNested extends AbstractBaseSignalHandler { - - private boolean sync; - - /** - * Constructor - */ - private TestSignalHandlerNested() { - this(true); - } - - /** - * Constructor - * - * @param sync - * log sync signals - * - */ - private TestSignalHandlerNested(boolean sync) { - super("TestSignalHandlerNested", false); - this.sync = sync; - TmfSignalManager.deregister(this); - TmfSignalManager.registerVIP(this); - } - - /** - * Receive a signal of type TestSignal1. - * - * @param signal - * Signal received - */ - @TmfSignalHandler - public void receiveSignal1(final TestSignal1 signal) { - if (sync) { - broadcast(new TestSignal2(signal.getSource())); - broadcast(new TestSignal3(signal.getSource())); - } else { - broadcastAsync(new TestSignal2(signal.getSource())); - broadcastAsync(new TestSignal3(signal.getSource())); - } - } - - /** - * Receive a signal of type TestSignal3. - * - * @param signal - * Signal received - */ - @TmfSignalHandler - public void receiveSignal3(final TestSignal3 signal) { - if (sync) { - broadcast(new TestSignal4(signal.getSource())); - } else { - broadcastAsync(new TestSignal4(signal.getSource())); - } - } - } - - /** - * Signal handler implementation for testing of sending and receiving - * signals. - */ - public class TestSignalHandler extends AbstractBaseSignalHandler { - - private CountDownLatch latch; - - /** - * Constructor - * - */ - private TestSignalHandler() { - this(true, null); - } - - /** - * Constructor - * - * @param logSyncSigs - * log sync signals - * @param latch - * latch to count down when receiving last signal - * (TmfSingal4) - */ - private TestSignalHandler(boolean logSyncSigs, CountDownLatch latch) { - super("TestSignalHandler", logSyncSigs); - this.latch = latch; - } - - /** - * Receive a signal of type TestSignal1. - * - * @param signal - * Signal received - */ - @TmfSignalHandler - public void receiveSignal1(final TestSignal1 signal) { - receivedSignals.add(signal); - } - - /** - * Receive a signal of type TestSignal2. - * - * @param signal - * Signal received - */ - @TmfSignalHandler - public void receiveSignal2(final TestSignal2 signal) { - receivedSignals.add(signal); - } - - /** - * Receive a signal of type TestSignal3. - * - * @param signal - * Signal received - */ - @TmfSignalHandler - public void receiveSignal3(final TestSignal3 signal) { - receivedSignals.add(signal); - } - - /** - * Receive a signal of type TestSignal4. - * - * @param signal - * Signal received - */ - @TmfSignalHandler - public void receiveSignal4(final TestSignal4 signal) { - receivedSignals.add(signal); - if (latch != null) { - latch.countDown(); - } - } - } - - /** - * Base signal handler for start and end sync signals. - */ - public abstract class AbstractBaseSignalHandler extends TmfComponent { - List receivedSignals = new ArrayList<>(); - private boolean logSyncSigs; - - private AbstractBaseSignalHandler(String name, boolean logSyncSignal) { - super(name); - this.logSyncSigs = logSyncSignal; - } - - /** - * Receive a signal of type TmfStartSynchSignal. - * - * @param signal - * Signal received - */ - @TmfSignalHandler - public void receiveStartSynch(final TmfStartSynchSignal signal) { - if (logSyncSigs) { - receivedSignals.add(signal); - } - } - - /** - * Receive a signal of type TmfEndSynchSignal. - * - * @param signal - * Signal received - */ - @TmfSignalHandler - public void receiveEndSynch(final TmfEndSynchSignal signal) { - if (logSyncSigs) { - receivedSignals.add(signal); - } - } - } - - - /** - * Test Signal object - */ - private class TestSignal1 extends TmfSignal { - - public TestSignal1(Object source) { - super(source); - } - } - - /** - * Test Signal object - */ - private class TestSignal2 extends TmfSignal { - - public TestSignal2(Object source) { - super(source); - } - } - - /** - * Test Signal object - */ - private class TestSignal3 extends TmfSignal { - - public TestSignal3(Object source) { - super(source); - } - } - - /** - * Test Signal object - */ - private class TestSignal4 extends TmfSignal { - - public TestSignal4(Object source) { - super(source); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/signal/TmfSignalThrottlerTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/signal/TmfSignalThrottlerTest.java deleted file mode 100644 index 4f153f04b9..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/signal/TmfSignalThrottlerTest.java +++ /dev/null @@ -1,224 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.signal; - -import static org.junit.Assert.assertEquals; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.component.TmfComponent; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalThrottler; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Test suite for {@link TmfSignalThrottler} - * - * @author Alexandre Montplaisir - */ -public class TmfSignalThrottlerTest { - - private MySender sender; - private MyListener listener; - - /** - * Pre-test setup - */ - @Before - public void setUp() { - sender = new MySender(); - listener = new MyListener(); - } - - /** - * After-test cleanup - */ - @After - public void tearDown() { - sender.dispose(); - listener.dispose(); - } - - // ------------------------------------------------------------------------ - // Test cases - // ------------------------------------------------------------------------ - - /** - * Test using only one throttler. Only one signal should go through. - */ - @Test - public void testOneChannel() { - final MySignal sig1 = new MySignal(sender, 0); - final MySignal sig2 = new MySignal(sender, 0); - final MySignal sig3 = new MySignal(sender, 0); - - synchronized(this) { - sender.sendSignal(sig1); - sender.sendSignal(sig2); - sender.sendSignal(sig3); - } - - sleep(5000); - - assertEquals(1, listener.nbReceived[0]); - assertEquals(0, listener.nbReceived[1]); - assertEquals(0, listener.nbReceived[2]); - } - - /** - * Test using multiple throttlers in parrallel. Only one signal per - * throttler should go through. - */ - @Test - public void testMultipleChannels() { - List signals = new ArrayList<>(); - signals.add(new MySignal(sender, 0)); - signals.add(new MySignal(sender, 0)); - signals.add(new MySignal(sender, 0)); - - signals.add(new MySignal(sender, 1)); - signals.add(new MySignal(sender, 1)); - signals.add(new MySignal(sender, 1)); - - signals.add(new MySignal(sender, 2)); - signals.add(new MySignal(sender, 2)); - signals.add(new MySignal(sender, 2)); - - Collections.shuffle(signals); /* Every day */ - - synchronized(this) { - for (MySignal sig : signals) { - sender.sendSignal(sig); - } - } - - sleep(5000); - - for (int nb : listener.nbReceived) { - assertEquals(1, nb); - } - } - - /** - * Test with one throttler, sending signals slowly. All three signals should - * go through. - */ - @Test - public void testDelay() { - final MySignal sig1 = new MySignal(sender, 0); - final MySignal sig2 = new MySignal(sender, 0); - final MySignal sig3 = new MySignal(sender, 0); - - sender.sendSignal(sig1); - sleep(2000); - sender.sendSignal(sig2); - sleep(2000); - sender.sendSignal(sig3); - sleep(2000); - - assertEquals(3, listener.nbReceived[0]); - } - - // ------------------------------------------------------------------------ - // Helper methods - // ------------------------------------------------------------------------ - - private static void sleep(long millis) { - try { - Thread.sleep(millis); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - // ------------------------------------------------------------------------ - // Helper classes - // ------------------------------------------------------------------------ - - /** - * Signal sender - */ - private class MySender extends TmfComponent { - - private final TmfSignalThrottler[] throttlers; - - MySender() { - super("MySender"); - throttlers = new TmfSignalThrottler[] { - new TmfSignalThrottler(this, 200), - new TmfSignalThrottler(this, 500), - new TmfSignalThrottler(this, 1000), - }; - } - - void sendSignal(MySignal signal) { - throttlers[signal.getChannel()].queue(signal); - } - - @Override - public void dispose() { - super.dispose(); - for (TmfSignalThrottler elem : throttlers) { - elem.dispose(); - } - } - } - - /** - * Signal listener - */ - public class MyListener extends TmfComponent { - - int[] nbReceived = { 0, 0, 0 }; - - /** - * Constructor. Needs to be public so TmfSignalHandler can see it. - */ - public MyListener() { - super("MyListener"); - } - - /** - * Receive a signal. - * - * @param sig - * Signal received - */ - @TmfSignalHandler - public void receiveSignal(final MySignal sig) { - nbReceived[sig.getChannel()]++; - } - } - - /** - * Signal object - */ - private class MySignal extends TmfSignal { - - private final int channel; - - public MySignal(MySender source, int channel) { - super(source); - this.channel = channel; - } - - public int getChannel() { - return channel; - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/AllTests.java deleted file mode 100644 index b51108aa40..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/AllTests.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.statesystem; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite for org.eclipse.linuxtools.tmf.core.tests.statesystem - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - ExperimentStateSystemModuleTest.class, - StateSystemAnalysisModuleTest.class -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/ExperimentStateSystemModuleTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/ExperimentStateSystemModuleTest.java deleted file mode 100644 index 93fbf0beca..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/ExperimentStateSystemModuleTest.java +++ /dev/null @@ -1,119 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.statesystem; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; - -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; -import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; -import org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestExperimentAnalysis; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfExperimentStub; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; -import org.junit.rules.Timeout; - -/** - * Test the {@link TmfStateSystemAnalysisModule} class for an experiment - * - * @author Geneviève Bastien - */ -public class ExperimentStateSystemModuleTest { - - /** Time-out tests after some time */ - @Rule - public TestRule globalTimeout = new Timeout(60000); - - /** ID of the test state system analysis module */ - public static final String MODULE_SS = "org.eclipse.linuxtools.tmf.core.tests.experiment"; - - private TmfStateSystemAnalysisModule fModule; - private TmfExperiment fExperiment; - - /** - * Setup test trace - */ - @Before - public void setupTraces() { - ITmfTrace trace = TmfTestTrace.A_TEST_10K.getTrace(); - TmfSignalManager.deregister(trace); - ITmfTrace trace2 = TmfTestTrace.A_TEST_10K2.getTrace(); - TmfSignalManager.deregister(trace2); - ITmfTrace[] traces = { trace, trace2 }; - fExperiment = new TmfExperimentStub("Test", traces, 1000); - fExperiment.traceOpened(new TmfTraceOpenedSignal(this, fExperiment, null)); - - fModule = (TmfStateSystemAnalysisModule) fExperiment.getAnalysisModule(MODULE_SS); - assertNotNull(fModule); - } - - /** - * Some tests use traces, let's clean them here - */ - @After - public void cleanupTraces() { - fExperiment.dispose(); - } - - /** - * Test the state system module execution and result - */ - @Test - public void testSsModule() { - ITmfStateSystem ss = fModule.getStateSystem(); - assertNull(ss); - fModule.schedule(); - if (fModule.waitForCompletion()) { - ss = fModule.getStateSystem(); - assertNotNull(ss); - try { - int quark = ss.getQuarkAbsolute(TestExperimentAnalysis.TRACE_QUARK_NAME); - ITmfStateInterval interval = ss.querySingleState(ss.getCurrentEndTime(), quark); - assertEquals(2, interval.getStateValue().unboxInt()); - } catch (AttributeNotFoundException e) { - fail("The quark for number of traces does not exist"); - } catch (StateSystemDisposedException e) { - fail("Error: state system disposed"); - } - } else { - fail("Module did not complete properly"); - } - } - - /** - * Make sure that the state system is initialized after calling  - * {@link TmfStateSystemAnalysisModule#waitForInitialization()}. - */ - @Test - public void testInitialization() { - assertNull(fModule.getStateSystem()); - fModule.schedule(); - - fModule.waitForInitialization(); - assertNotNull(fModule.getStateSystem()); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/StateSystemAnalysisModuleTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/StateSystemAnalysisModuleTest.java deleted file mode 100644 index 08d588a595..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/StateSystemAnalysisModuleTest.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.statesystem; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; - -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; -import org.junit.rules.Timeout; - -/** - * Test the {@link TmfStateSystemAnalysisModule} class - * - * @author Geneviève Bastien - */ -public class StateSystemAnalysisModuleTest { - - /** Time-out tests after 20 seconds */ - @Rule - public TestRule globalTimeout= new Timeout(20000); - - /** ID of the test state system analysis module */ - public static final String MODULE_SS = "org.eclipse.linuxtools.tmf.core.tests.analysis.sstest"; - - private TmfStateSystemAnalysisModule module; - - /** - * Setup test trace - */ - @Before - public void setupTraces() { - TmfTraceStub trace = (TmfTraceStub) TmfTestTrace.A_TEST_10K.getTrace(); - TmfSignalManager.deregister(trace); - trace.traceOpened(new TmfTraceOpenedSignal(this, trace, null)); - - module = (TmfStateSystemAnalysisModule) trace.getAnalysisModule(MODULE_SS); - } - - /** - * Some tests use traces, let's clean them here - */ - @After - public void cleanupTraces() { - TmfTestTrace.A_TEST_10K.dispose(); - } - - /** - * Test the state system module execution and result - */ - @Test - public void testSsModule() { - ITmfStateSystem ss = module.getStateSystem(); - assertNull(ss); - module.schedule(); - if (module.waitForCompletion()) { - ss = module.getStateSystem(); - assertNotNull(ss); - } else { - fail("Module did not complete properly"); - } - } - - /** - * Make sure that the state system is initialized after calling  - * {@link TmfStateSystemAnalysisModule#waitForInitialization()}. - */ - @Test - public void testInitialization() { - assertNull(module.getStateSystem()); - module.schedule(); - - module.waitForInitialization(); - assertNotNull(module.getStateSystem()); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/mipmap/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/mipmap/AllTests.java deleted file mode 100644 index 9b93ccaa18..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/mipmap/AllTests.java +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Updates to mipmap feature - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.statesystem.mipmap; - -import org.eclipse.linuxtools.tmf.core.tests.statesystem.mipmap.TmfMipmapStateProviderTest; -import org.eclipse.linuxtools.tmf.core.tests.statesystem.mipmap.TmfMipmapStateProviderWeightedTest; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite for org.eclipse.linuxtools.tmf.core.tests.statesystem.mipmap - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TmfMipmapStateProviderTest.class, - TmfMipmapStateProviderWeightedTest.class, -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderStub.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderStub.java deleted file mode 100644 index 0a47e1ed39..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderStub.java +++ /dev/null @@ -1,116 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Jean-Christian Kouamé - Initial API and implementation - * Patrick Tasse - Updates to mipmap feature - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.statesystem.mipmap; - -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.internal.tmf.core.statesystem.mipmap.AbstractTmfMipmapStateProvider; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp; - -/** - * A mipmap state provider for test - * - * @author Jean-Christian Kouamé - * @since 3.0 - */ -class TmfMipmapStateProviderStub extends AbstractTmfMipmapStateProvider { - /** test attribute name */ - public final static String TEST_ATTRIBUTE_NAME = "test_attribute"; //$NON-NLS-1$ - - private int resolution; - private ITmfStateValue.Type type; - private final static String MIPMAP_ID = "MIPMAP_ID"; //$NON-NLS-1$ - - private final String ERROR_ATTRIBUTE_NOT_FOUND = "Error : Impossible to find the attribute"; //$NON-NLS-1$ - private final String ERROR_INVALID_STATE_VALUE = "Error : Invalid state value"; //$NON-NLS-1$ - private final String ERROR_INVALID_TIMESTAMP = "Error : Invalid timestamp"; //$NON-NLS-1$ - - /** - * Constructor - * - * @param resolution - * the mipmap resolution array (max, min, avg) - * @param type - * the type of value to use - */ - public TmfMipmapStateProviderStub(int resolution, ITmfStateValue.Type type) { - super(null, TmfEvent.class, MIPMAP_ID); - this.resolution = resolution; - this.type = type; - } - - @Override - protected void eventHandle(ITmfEvent ev) { - final long ts = ev.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - try { - int quark = ss.getQuarkAbsoluteAndAdd(TEST_ATTRIBUTE_NAME); - ITmfStateValue value = (ITmfStateValue) ev.getContent().getValue(); - modifyMipmapAttribute(ts, value, quark, MIN | MAX | AVG, resolution); - } catch (TimeRangeException e) { - Activator.logError(ERROR_INVALID_TIMESTAMP, e); - } catch (AttributeNotFoundException e) { - Activator.logError(ERROR_ATTRIBUTE_NOT_FOUND, e); - } catch (StateValueTypeException e) { - Activator.logError(ERROR_INVALID_STATE_VALUE, e); - } - } - - @Override - public int getVersion() { - return 0; - } - - @Override - public TmfMipmapStateProviderStub getNewInstance() { - return new TmfMipmapStateProviderStub(resolution, type); - } - - /** - * @param time - * The event type - * @param longVal - * The event value or null - * @return A new TmfEvent - */ - public ITmfEvent createEvent(long time, Long longVal) { - ITmfStateValue value; - if (longVal == null) { - value = TmfStateValue.nullValue(); - } else if (type == ITmfStateValue.Type.LONG) { - value = TmfStateValue.newValueLong(longVal); - } else if (type == ITmfStateValue.Type.INTEGER) { - value = TmfStateValue.newValueInt(longVal.intValue()); - } else if (type == ITmfStateValue.Type.DOUBLE) { - value = TmfStateValue.newValueDouble(longVal.doubleValue()); - } else { - value = TmfStateValue.nullValue(); - } - ITmfTimestamp timestamp = new TmfNanoTimestamp(time); - ITmfEventType eventType = new TmfEventType(ITmfEventType.DEFAULT_CONTEXT_ID, MIPMAP_ID, null); - ITmfEventField content = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, value, null); - ITmfEvent event = new TmfEvent(null, timestamp, null, eventType, content, null); - return event; - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderTest.java deleted file mode 100644 index 0e18d41d5c..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderTest.java +++ /dev/null @@ -1,541 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Jean-Christian Kouamé - Initial API and implementation - * Patrick Tasse - Updates to mipmap feature - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.statesystem.mipmap; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.List; -import java.util.Random; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.core.statesystem.mipmap.AbstractTmfMipmapStateProvider; -import org.eclipse.linuxtools.internal.tmf.core.statesystem.mipmap.TmfStateSystemOperations; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; -import org.eclipse.linuxtools.statesystem.core.StateSystemFactory; -import org.eclipse.linuxtools.statesystem.core.backend.IStateHistoryBackend; -import org.eclipse.linuxtools.statesystem.core.backend.InMemoryBackend; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * @author Jean-Christian Kouamé - * - */ -public class TmfMipmapStateProviderTest { - - @NonNull private static final String SSID = "mimap-test"; - private static final String TEST_ATTRIBUTE_NAME = TmfMipmapStateProviderStub.TEST_ATTRIBUTE_NAME; - private static final int NB_LEVELS = 4; - private static final long START_TIME = 1000L; - private static final long END_TIME = 100000000L; - private static final long INTERVAL = 1000L; - private static final int RESOLUTION = 16; - private static final double DELTA = 0.0001; - private static final long TEST_TIMESTAMP = 12345000L; - private static ITmfStateSystemBuilder ssq; - - /** - * Startup code, build a state system with n attributes always going up - * linearly - */ - @BeforeClass - public static void init() { - TmfMipmapStateProviderStub mmp = new TmfMipmapStateProviderStub(RESOLUTION, Type.LONG); - IStateHistoryBackend be = new InMemoryBackend(0); - ssq = StateSystemFactory.newStateSystem(SSID, be); - mmp.assignTargetStateSystem(ssq); - - for (long time = START_TIME; time <= END_TIME; time += INTERVAL) { - long value = time / INTERVAL; - ITmfEvent event = mmp.createEvent(time, value); - mmp.processEvent(event); - } - mmp.dispose(); - ssq.waitUntilBuilt(); - } - - /** - * Test a single query to the state system. - * - * Make sure the state system has data. - * - * Hint: the value read should always be t / 1000 - * - */ - @Test - public void testQuery() { - assertNotNull(ssq); - try { - Random rn = new Random(); - long time = Math.max(INTERVAL, rn.nextLong() % END_TIME); - List intervals = ssq.queryFullState(time); - int mipmapQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); - ITmfStateInterval interval = intervals.get(mipmapQuark); - long valueLong = interval.getStateValue().unboxLong(); - assertEquals(time / INTERVAL, valueLong); - - } catch (TimeRangeException e) { - fail(e.getMessage()); - } catch (StateSystemDisposedException e) { - fail(e.getMessage()); - } catch (AttributeNotFoundException e) { - fail(e.getMessage()); - } catch (StateValueTypeException e) { - fail(e.getMessage()); - } - assertTrue(true); - } - - /** - * Test a single query to the state system for the maxLevel. - * - * Make sure the state system has data. - * - */ - @Test - public void testMaxLevel() { - assertNotNull(ssq); - try { - Random rn = new Random(); - long time = Math.max(INTERVAL, rn.nextLong() % END_TIME); - List intervals = ssq.queryFullState(time); - - int maxMipmapQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME, AbstractTmfMipmapStateProvider.MAX_STRING); - int nbLevelMax = intervals.get(maxMipmapQuark).getStateValue().unboxInt(); - assertEquals(NB_LEVELS, nbLevelMax); - - int minMipmapQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME, AbstractTmfMipmapStateProvider.MIN_STRING); - int nbLevelMin = intervals.get(minMipmapQuark).getStateValue().unboxInt(); - assertEquals(NB_LEVELS, nbLevelMin); - - int avgMipmapQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME, AbstractTmfMipmapStateProvider.AVG_STRING); - int nbLevelAvg = intervals.get(avgMipmapQuark).getStateValue().unboxInt(); - assertEquals(NB_LEVELS, nbLevelAvg); - - } catch (TimeRangeException e) { - fail(e.getMessage()); - } catch (StateSystemDisposedException e) { - fail(e.getMessage()); - } catch (AttributeNotFoundException e) { - fail(e.getMessage()); - } catch (StateValueTypeException e) { - fail(e.getMessage()); - } - assertTrue(true); - - } - - /** - * Test a single query to the state system for a mip - * - * Make sure the state system has data. - * - */ - @Test - public void testQueryEventField() { - assertNotNull(ssq); - try { - List intervals = ssq.queryFullState(TEST_TIMESTAMP); - int eventFieldQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); - ITmfStateInterval interval = intervals.get(eventFieldQuark); - long valueLong = interval.getStateValue().unboxLong(); - assertEquals(TEST_TIMESTAMP / INTERVAL, valueLong); - } catch (TimeRangeException e) { - fail(e.getMessage()); - } catch (StateSystemDisposedException e) { - fail(e.getMessage()); - } catch (AttributeNotFoundException e) { - fail(e.getMessage()); - } catch (StateValueTypeException e) { - fail(e.getMessage()); - } - assertTrue(true); - } - - /** - * Test a single query to the state system for a max - * - * Make sure the state system has data. - * - * Hint: the value read should always be greater than(t / 1000) - * - */ - @Test - public void testQueryMipMax() { - assertNotNull(ssq); - try { - List intervals = ssq.queryFullState(TEST_TIMESTAMP); - int mipmapQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME, AbstractTmfMipmapStateProvider.MAX_STRING); - - assertEquals("max nblevels", NB_LEVELS, intervals.get(mipmapQuark).getStateValue().unboxInt()); - for (int level = 1; level < NB_LEVELS; level++) { - long width = (long) Math.pow(RESOLUTION, level); - int levelQuark = ssq.getQuarkRelative(mipmapQuark, String.valueOf(level)); - ITmfStateInterval interval = intervals.get(levelQuark); - long valueLong = interval.getStateValue().unboxLong(); - assertEquals("max value @ level " + level, width + (((TEST_TIMESTAMP - START_TIME) / INTERVAL) / width) * width, valueLong); - assertEquals("max start time @ level " + level, START_TIME + (((TEST_TIMESTAMP - START_TIME) / INTERVAL) / width) * width * INTERVAL, interval.getStartTime()); - assertEquals("max end time @ level " + level, START_TIME + (INTERVAL * width) + (((TEST_TIMESTAMP - START_TIME) / INTERVAL) / width) * width * INTERVAL, interval.getEndTime() + 1); - } - - } catch (TimeRangeException e) { - fail(e.getMessage()); - } catch (StateSystemDisposedException e) { - fail(e.getMessage()); - } catch (AttributeNotFoundException e) { - fail(e.getMessage()); - } catch (StateValueTypeException e) { - fail(e.getMessage()); - } - assertTrue(true); - } - - /** - * Test a single query to the state system for a min - * - * Make sure the state system has data. - * - * Hint: the value read should always be less than(t / 1000) - */ - @Test - public void testQueryMipMin() { - assertNotNull(ssq); - try { - List intervals = ssq.queryFullState(TEST_TIMESTAMP); - int mipmapQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME, AbstractTmfMipmapStateProvider.MIN_STRING); - - assertEquals("min nblevels", NB_LEVELS, intervals.get(mipmapQuark).getStateValue().unboxInt()); - for (int level = 1; level < NB_LEVELS; level++) { - long width = (long) Math.pow(RESOLUTION, level); - int levelQuark = ssq.getQuarkRelative(mipmapQuark, String.valueOf(level)); - ITmfStateInterval interval = intervals.get(levelQuark); - long valueLong = interval.getStateValue().unboxLong(); - assertEquals("min value @ level " + level, 1 + (((TEST_TIMESTAMP - START_TIME) / INTERVAL) / width) * width, valueLong); - assertEquals("min start time @ level " + level, START_TIME + (((TEST_TIMESTAMP - START_TIME) / INTERVAL) / width) * width * INTERVAL, interval.getStartTime()); - assertEquals("min end time @ level " + level, START_TIME + (INTERVAL * width) + (((TEST_TIMESTAMP - START_TIME) / INTERVAL) / width) * width * INTERVAL, interval.getEndTime() + 1); - } - - } catch (TimeRangeException e) { - fail(e.getMessage()); - } catch (StateSystemDisposedException e) { - fail(e.getMessage()); - } catch (AttributeNotFoundException e) { - fail(e.getMessage()); - } catch (StateValueTypeException e) { - fail(e.getMessage()); - } - assertTrue(true); - } - - /** - * Test a single query to the state system for an average - * - * Make sure the state system has data. - * - * Hint: the value read should always be more or less(t / 1000) - * - */ - @Test - public void testQueryMipAvg() { - assertNotNull(ssq); - try { - List intervals = ssq.queryFullState(TEST_TIMESTAMP); - int mipmapQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME, AbstractTmfMipmapStateProvider.AVG_STRING); - - assertEquals("avg nblevels", NB_LEVELS, intervals.get(mipmapQuark).getStateValue().unboxInt()); - for (int level = 1; level < NB_LEVELS; level++) { - long width = (long) Math.pow(RESOLUTION, level); - int levelQuark = ssq.getQuarkRelative(mipmapQuark, String.valueOf(level)); - ITmfStateInterval interval = intervals.get(levelQuark); - double valueDouble = interval.getStateValue().unboxDouble(); - assertEquals("avg value @ level " + level, 0.5 + (width / 2) + (((TEST_TIMESTAMP - START_TIME) / INTERVAL) / width) * width, valueDouble, DELTA); - assertEquals("avg start time @ level " + level, START_TIME + (((TEST_TIMESTAMP - START_TIME) / INTERVAL) / width) * width * INTERVAL, interval.getStartTime()); - assertEquals("avg end time @ level " + level, START_TIME + (INTERVAL * width) + (((TEST_TIMESTAMP - START_TIME) / INTERVAL) / width) * width * INTERVAL, interval.getEndTime() + 1); - } - - } catch (TimeRangeException e) { - fail(e.getMessage()); - } catch (StateSystemDisposedException e) { - fail(e.getMessage()); - } catch (AttributeNotFoundException e) { - fail(e.getMessage()); - } catch (StateValueTypeException e) { - fail(e.getMessage()); - } - assertTrue(true); - } - - /** - * Test a full query to the state system at the startTime - * - * Make sure the state system has data. - * - * Hint: the value read should always be more or less(t / 1000) - * - */ - @Test - public void testQueryValuesOnStart() { - assertNotNull(ssq); - try { - int quark; - - List intervals = ssq.queryFullState(START_TIME); - - int baseQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); - assertEquals(START_TIME / INTERVAL, intervals.get(baseQuark).getStateValue().unboxLong()); - - int maxMipmapQuark = ssq.getQuarkRelative(baseQuark, AbstractTmfMipmapStateProvider.MAX_STRING); - assertEquals("max nblevels", NB_LEVELS, intervals.get(maxMipmapQuark).getStateValue().unboxInt()); - quark = ssq.getQuarkRelative(maxMipmapQuark, String.valueOf(1)); - assertEquals("max value @ level 1", (long) Math.pow(RESOLUTION, 1), intervals.get(quark).getStateValue().unboxLong()); - quark = ssq.getQuarkRelative(maxMipmapQuark, String.valueOf(2)); - assertEquals("max value @ level 2", (long) Math.pow(RESOLUTION, 2), intervals.get(quark).getStateValue().unboxLong()); - quark = ssq.getQuarkRelative(maxMipmapQuark, String.valueOf(3)); - assertEquals("max value @ level 3", (long) Math.pow(RESOLUTION, 3), intervals.get(quark).getStateValue().unboxLong()); - quark = ssq.getQuarkRelative(maxMipmapQuark, String.valueOf(4)); - assertEquals("max value @ level 4", (long) Math.pow(RESOLUTION, 4), intervals.get(quark).getStateValue().unboxLong()); - - int minMipmapQuark = ssq.getQuarkRelative(baseQuark, AbstractTmfMipmapStateProvider.MIN_STRING); - assertEquals("min nblevels", NB_LEVELS, intervals.get(minMipmapQuark).getStateValue().unboxInt()); - quark = ssq.getQuarkRelative(minMipmapQuark, String.valueOf(1)); - assertEquals("min value @ level 1", START_TIME / INTERVAL, intervals.get(quark).getStateValue().unboxLong()); - quark = ssq.getQuarkRelative(minMipmapQuark, String.valueOf(2)); - assertEquals("min value @ level 2", START_TIME / INTERVAL, intervals.get(quark).getStateValue().unboxLong()); - quark = ssq.getQuarkRelative(minMipmapQuark, String.valueOf(3)); - assertEquals("min value @ level 3", START_TIME / INTERVAL, intervals.get(quark).getStateValue().unboxLong()); - quark = ssq.getQuarkRelative(minMipmapQuark, String.valueOf(4)); - assertEquals("min value @ level 4", START_TIME / INTERVAL, intervals.get(quark).getStateValue().unboxLong()); - - int avgMipmapQuark = ssq.getQuarkRelative(baseQuark, AbstractTmfMipmapStateProvider.AVG_STRING); - assertEquals("avg nblevels", NB_LEVELS, intervals.get(avgMipmapQuark).getStateValue().unboxInt()); - quark = ssq.getQuarkRelative(avgMipmapQuark, String.valueOf(1)); - assertEquals("avg value @ level 1", 0.5 + Math.pow(RESOLUTION, 1) / 2, intervals.get(quark).getStateValue().unboxDouble(), DELTA); - quark = ssq.getQuarkRelative(avgMipmapQuark, String.valueOf(2)); - assertEquals("avg value @ level 2", 0.5 + Math.pow(RESOLUTION, 2) / 2, intervals.get(quark).getStateValue().unboxDouble(), DELTA); - quark = ssq.getQuarkRelative(avgMipmapQuark, String.valueOf(3)); - assertEquals("avg value @ level 3", 0.5 + Math.pow(RESOLUTION, 3) / 2, intervals.get(quark).getStateValue().unboxDouble(), DELTA); - quark = ssq.getQuarkRelative(avgMipmapQuark, String.valueOf(4)); - assertEquals("avg value @ level 4", 0.5 + Math.pow(RESOLUTION, 4) / 2, intervals.get(quark).getStateValue().unboxDouble(), DELTA); - - } catch (TimeRangeException e) { - fail(e.getMessage()); - } catch (StateSystemDisposedException e) { - fail(e.getMessage()); - } catch (AttributeNotFoundException e) { - fail(e.getMessage()); - } catch (StateValueTypeException e) { - fail(e.getMessage()); - } - assertTrue(true); - } - - /** - * Test a full query to the state system when the end time - * - * Make sure the state system has data. - * - * Hint: the value read should always be more or less(t / 1000) - * - */ - @Test - public void testQueryValuesOnClose() { - assertNotNull(ssq); - try { - int quark; - - List intervals = ssq.queryFullState(END_TIME); - - int baseQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); - assertEquals(END_TIME / INTERVAL, intervals.get(baseQuark).getStateValue().unboxLong()); - - int maxMipmapQuark = ssq.getQuarkRelative(baseQuark, AbstractTmfMipmapStateProvider.MAX_STRING); - assertEquals("max nblevels", NB_LEVELS, intervals.get(maxMipmapQuark).getStateValue().unboxInt()); - quark = ssq.getQuarkRelative(maxMipmapQuark, String.valueOf(1)); - assertEquals("max value @ level 1", END_TIME / INTERVAL, intervals.get(quark).getStateValue().unboxLong()); - quark = ssq.getQuarkRelative(maxMipmapQuark, String.valueOf(2)); - assertEquals("max value @ level 2", END_TIME / INTERVAL, intervals.get(quark).getStateValue().unboxLong()); - quark = ssq.getQuarkRelative(maxMipmapQuark, String.valueOf(3)); - assertEquals("max value @ level 3", END_TIME / INTERVAL, intervals.get(quark).getStateValue().unboxLong()); - quark = ssq.getQuarkRelative(maxMipmapQuark, String.valueOf(4)); - assertEquals("max value @ level 4", END_TIME / INTERVAL, intervals.get(quark).getStateValue().unboxLong()); - - int minMipmapQuark = ssq.getQuarkRelative(baseQuark, AbstractTmfMipmapStateProvider.MIN_STRING); - assertEquals("min nblevels", NB_LEVELS, intervals.get(minMipmapQuark).getStateValue().unboxInt()); - quark = ssq.getQuarkRelative(minMipmapQuark, String.valueOf(1)); - assertEquals("min value @ level 1", END_TIME / INTERVAL - (END_TIME - START_TIME) / INTERVAL % (long) Math.pow(RESOLUTION, 1), intervals.get(quark).getStateValue().unboxLong()); - quark = ssq.getQuarkRelative(minMipmapQuark, String.valueOf(2)); - assertEquals("min value @ level 2", END_TIME / INTERVAL - (END_TIME - START_TIME) / INTERVAL % (long) Math.pow(RESOLUTION, 2), intervals.get(quark).getStateValue().unboxLong()); - quark = ssq.getQuarkRelative(minMipmapQuark, String.valueOf(3)); - assertEquals("min value @ level 3", END_TIME / INTERVAL - (END_TIME - START_TIME) / INTERVAL % (long) Math.pow(RESOLUTION, 3), intervals.get(quark).getStateValue().unboxLong()); - quark = ssq.getQuarkRelative(minMipmapQuark, String.valueOf(4)); - assertEquals("min value @ level 4", END_TIME / INTERVAL - (END_TIME - START_TIME) / INTERVAL % (long) Math.pow(RESOLUTION, 4), intervals.get(quark).getStateValue().unboxLong()); - - int avgMipmapQuark = ssq.getQuarkRelative(baseQuark, AbstractTmfMipmapStateProvider.AVG_STRING); - assertEquals("avg nblevels", NB_LEVELS, intervals.get(avgMipmapQuark).getStateValue().unboxInt()); - quark = ssq.getQuarkRelative(avgMipmapQuark, String.valueOf(1)); - assertEquals("avg value @ level 1", (long) (END_TIME / INTERVAL - (double) ((END_TIME - START_TIME) / INTERVAL % (long) Math.pow(RESOLUTION, 1)) / 2), intervals.get(quark).getStateValue().unboxDouble(), DELTA); - quark = ssq.getQuarkRelative(avgMipmapQuark, String.valueOf(2)); - assertEquals("avg value @ level 2", (long) (END_TIME / INTERVAL - (double) ((END_TIME - START_TIME) / INTERVAL % (long) Math.pow(RESOLUTION, 2)) / 2), intervals.get(quark).getStateValue().unboxDouble(), DELTA); - quark = ssq.getQuarkRelative(avgMipmapQuark, String.valueOf(3)); - assertEquals("avg value @ level 3", (long) (END_TIME / INTERVAL - (double) ((END_TIME - START_TIME) / INTERVAL % (long) Math.pow(RESOLUTION, 3)) / 2), intervals.get(quark).getStateValue().unboxDouble(), DELTA); - quark = ssq.getQuarkRelative(avgMipmapQuark, String.valueOf(4)); - assertEquals("avg value @ level 4", (long) (END_TIME / INTERVAL - (double) ((END_TIME - START_TIME) / INTERVAL % (long) Math.pow(RESOLUTION, 4)) / 2), intervals.get(quark).getStateValue().unboxDouble(), DELTA); - - } catch (TimeRangeException e) { - fail(e.getMessage()); - } catch (StateSystemDisposedException e) { - fail(e.getMessage()); - } catch (AttributeNotFoundException e) { - fail(e.getMessage()); - } catch (StateValueTypeException e) { - fail(e.getMessage()); - } - assertTrue(true); - } - - /** - * Test a query range to the state system to get the maximum value in the - * range - * - * Make sure the state system has data. - * - * - */ - @Test - public void testQueryMipmapRangeMax() { - assertNotNull(ssq); - try { - long max; - int quark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); - - max = TmfStateSystemOperations.queryRangeMax(ssq, 0, START_TIME, quark).unboxLong(); - assertEquals(START_TIME / INTERVAL, max); - - max = TmfStateSystemOperations.queryRangeMax(ssq, START_TIME, START_TIME, quark).unboxLong(); - assertEquals(START_TIME / INTERVAL, max); - - max = TmfStateSystemOperations.queryRangeMax(ssq, START_TIME, END_TIME / 2, quark).unboxLong(); - assertEquals((END_TIME / 2 / INTERVAL), max); - - max = TmfStateSystemOperations.queryRangeMax(ssq, 0, END_TIME, quark).unboxLong(); - assertEquals(END_TIME / INTERVAL, max); - - max = TmfStateSystemOperations.queryRangeMax(ssq, END_TIME / 2, END_TIME, quark).unboxLong(); - assertEquals(END_TIME / INTERVAL, max); - - max = TmfStateSystemOperations.queryRangeMax(ssq, START_TIME - INTERVAL / 2, END_TIME / 2 + INTERVAL / 2, quark).unboxLong(); - assertEquals(END_TIME / 2 / INTERVAL, max); - - } catch (AttributeNotFoundException e) { - fail(e.getMessage()); - } catch (StateValueTypeException e) { - fail(e.getMessage()); - } catch (TimeRangeException e) { - fail(e.getMessage()); - } - } - - /** - * Test a query range to the state system to get the minimum value in the - * range - * - * Make sure the state system has data. - * - * - */ - @Test - public void testQueryMipmapRangeMin() { - assertNotNull(ssq); - try { - long min; - int quark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); - - min = TmfStateSystemOperations.queryRangeMin(ssq, 0, START_TIME, quark).unboxLong(); - assertEquals(START_TIME / INTERVAL, min); - - min = TmfStateSystemOperations.queryRangeMin(ssq, START_TIME, START_TIME, quark).unboxLong(); - assertEquals(START_TIME / INTERVAL, min); - - min = TmfStateSystemOperations.queryRangeMin(ssq, START_TIME, END_TIME / 2, quark).unboxLong(); - assertEquals((START_TIME / INTERVAL), min); - - min = TmfStateSystemOperations.queryRangeMin(ssq, 0, END_TIME, quark).unboxLong(); - assertEquals(START_TIME / INTERVAL, min); - - min = TmfStateSystemOperations.queryRangeMin(ssq, END_TIME / 2, END_TIME, quark).unboxLong(); - assertEquals(END_TIME / 2 / INTERVAL, min); - - min = TmfStateSystemOperations.queryRangeMin(ssq, START_TIME - INTERVAL / 2, END_TIME / 2 + INTERVAL / 2, quark).unboxLong(); - assertEquals(START_TIME / INTERVAL, min); - - } catch (AttributeNotFoundException e) { - fail(e.getMessage()); - } catch (StateValueTypeException e) { - fail(e.getMessage()); - } catch (TimeRangeException e) { - fail(e.getMessage()); - } - } - - /** - * Test a query range to the state system to get the average value in the - * range - * - * Make sure the state system has data. - * - */ - @Test - public void testQueryMipmapRangeAvg() { - assertNotNull(ssq); - try { - double avg; - int quark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); - - avg = TmfStateSystemOperations.queryRangeAverage(ssq, 0, START_TIME, quark); - assertEquals((double) (START_TIME - INTERVAL) / INTERVAL, avg, DELTA); - - avg = TmfStateSystemOperations.queryRangeAverage(ssq, START_TIME, START_TIME, quark); - assertEquals((double) START_TIME / INTERVAL, avg, DELTA); - - avg = TmfStateSystemOperations.queryRangeAverage(ssq, START_TIME, END_TIME / 2, quark); - assertEquals((double) (START_TIME + (END_TIME / 2 - INTERVAL)) / 2 / INTERVAL, avg, DELTA); - - avg = TmfStateSystemOperations.queryRangeAverage(ssq, 0, END_TIME, quark); - assertEquals((double) (END_TIME - INTERVAL) / 2 / INTERVAL, avg, DELTA); - - avg = TmfStateSystemOperations.queryRangeAverage(ssq, END_TIME / 2, END_TIME, quark); - assertEquals((double) (END_TIME / 2 + (END_TIME - INTERVAL)) / 2 / INTERVAL, avg, DELTA); - - avg = TmfStateSystemOperations.queryRangeAverage(ssq, START_TIME - INTERVAL / 2, END_TIME / 2 + INTERVAL / 2, quark); - assertEquals((double) (START_TIME + (END_TIME / 2 - INTERVAL)) / 2 / INTERVAL, avg, DELTA); - - } catch (AttributeNotFoundException e) { - fail(e.getMessage()); - } catch (TimeRangeException e) { - fail(e.getMessage()); - } catch (StateValueTypeException e) { - fail(e.getMessage()); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderWeightedTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderWeightedTest.java deleted file mode 100644 index 45bc5165f6..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderWeightedTest.java +++ /dev/null @@ -1,311 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Updates to mipmap feature - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.statesystem.mipmap; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.core.statesystem.mipmap.TmfStateSystemOperations; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; -import org.eclipse.linuxtools.statesystem.core.StateSystemFactory; -import org.eclipse.linuxtools.statesystem.core.backend.IStateHistoryBackend; -import org.eclipse.linuxtools.statesystem.core.backend.InMemoryBackend; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type; -import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * @author Patrick Tasse - * - */ -public class TmfMipmapStateProviderWeightedTest { - - @NonNull private static final String SSID = "mipmap-test"; - private static final String TEST_ATTRIBUTE_NAME = TmfMipmapStateProviderStub.TEST_ATTRIBUTE_NAME; - private static final long END_TIME = 250000L; - private static final long INTERVAL = 1000L; - private static final int RESOLUTION = 2; - private static final double DELTA = 0.0001; - private static ITmfStateSystemBuilder ssqi; - private static ITmfStateSystemBuilder ssqd; - - /** - * Startup code, build a state system with uneven state durations - */ - @BeforeClass - public static void init() { - /* setup for INTEGER test */ - TmfMipmapStateProviderStub mmpi = new TmfMipmapStateProviderStub(RESOLUTION, Type.INTEGER); - IStateHistoryBackend bei = new InMemoryBackend(0); - ssqi = StateSystemFactory.newStateSystem(SSID, bei); - mmpi.assignTargetStateSystem(ssqi); - /* setup for DOUBLE test */ - TmfMipmapStateProviderStub mmpd = new TmfMipmapStateProviderStub(RESOLUTION, Type.DOUBLE); - IStateHistoryBackend bed = new InMemoryBackend(0); - ssqd = StateSystemFactory.newStateSystem(SSID, bed); - mmpd.assignTargetStateSystem(ssqd); - /* - * Every 10,000 ns chunk contains the following states: - * - * | null | 10 | null | 20 | null | 30 | null | - * 0 1000 2000 3000 4000 5000 6000 7000 8000 9000 10,000 - * - * The weighted average for a chunk is (1 x 10 + 2 x 20 + 3 x 30) / 10 = 14. - */ - for (int i = 0; i < END_TIME / INTERVAL / 10; i++) { - long time = i * 10 * INTERVAL; - /* update for INTEGER test */ - mmpi.processEvent(mmpi.createEvent(time, null)); - mmpi.processEvent(mmpi.createEvent(time + 1000, 10L)); - mmpi.processEvent(mmpi.createEvent(time + 2000, null)); - mmpi.processEvent(mmpi.createEvent(time + 3000, 20L)); - mmpi.processEvent(mmpi.createEvent(time + 5000, null)); - mmpi.processEvent(mmpi.createEvent(time + 6000, 30L)); - mmpi.processEvent(mmpi.createEvent(time + 9000, null)); - /* update for DOUBLE test */ - mmpd.processEvent(mmpd.createEvent(time, null)); - mmpd.processEvent(mmpd.createEvent(time + 1000, 10L)); - mmpd.processEvent(mmpd.createEvent(time + 2000, null)); - mmpd.processEvent(mmpd.createEvent(time + 3000, 20L)); - mmpd.processEvent(mmpd.createEvent(time + 5000, null)); - mmpd.processEvent(mmpd.createEvent(time + 6000, 30L)); - mmpd.processEvent(mmpd.createEvent(time + 9000, null)); - } - /* cleanup for INTEGER test */ - mmpi.processEvent(mmpi.createEvent(END_TIME, 0L)); - mmpi.dispose(); - ssqi.waitUntilBuilt(); - /* cleanup for DOUBLE test */ - mmpd.processEvent(mmpd.createEvent(END_TIME, 0L)); - mmpd.dispose(); - ssqd.waitUntilBuilt(); - } - - /** - * Test a query range to the state system to get the maximum value in the - * range. The test values are INTEGER. - */ - @Test - public void testQueryMipmapRangeMaxInteger() { - assertNotNull(ssqi); - try { - int quark = ssqi.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); - assertEquals(TmfStateValue.nullValue(), TmfStateSystemOperations.queryRangeMax(ssqi, 0, 0, quark)); - assertEquals(10, TmfStateSystemOperations.queryRangeMax(ssqi, 500, 1500, quark).unboxInt()); - assertEquals(20, TmfStateSystemOperations.queryRangeMax(ssqi, 1500, 5000, quark).unboxInt()); - assertEquals(30, TmfStateSystemOperations.queryRangeMax(ssqi, 5000, 10000, quark).unboxInt()); - assertEquals(30, TmfStateSystemOperations.queryRangeMax(ssqi, 0, 10000, quark).unboxInt()); - assertEquals(TmfStateValue.nullValue(), TmfStateSystemOperations.queryRangeMax(ssqi, 120000, 120000, quark)); - assertEquals(10, TmfStateSystemOperations.queryRangeMax(ssqi, 120500, 121500, quark).unboxInt()); - assertEquals(20, TmfStateSystemOperations.queryRangeMax(ssqi, 121500, 125000, quark).unboxInt()); - assertEquals(30, TmfStateSystemOperations.queryRangeMax(ssqi, 125000, 130000, quark).unboxInt()); - assertEquals(30, TmfStateSystemOperations.queryRangeMax(ssqi, 120000, 130000, quark).unboxInt()); - assertEquals(30, TmfStateSystemOperations.queryRangeMax(ssqi, 100000, 150000, quark).unboxInt()); - assertEquals(30, TmfStateSystemOperations.queryRangeMax(ssqi, 240000, 250000, quark).unboxInt()); - assertEquals(30, TmfStateSystemOperations.queryRangeMax(ssqi, 0, 250000, quark).unboxInt()); - assertEquals(00, TmfStateSystemOperations.queryRangeMax(ssqi, 250000, 250000, quark).unboxInt()); - - } catch (AttributeNotFoundException e) { - fail(e.getMessage()); - } catch (StateValueTypeException e) { - fail(e.getMessage()); - } catch (TimeRangeException e) { - fail(e.getMessage()); - } - } - - /** - * Test a query range to the state system to get the minimum value in the - * range. The test values are INTEGER. - */ - @Test - public void testQueryMipmapRangeMinInteger() { - assertNotNull(ssqi); - try { - int quark = ssqi.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); - assertEquals(TmfStateValue.nullValue(), TmfStateSystemOperations.queryRangeMin(ssqi, 0, 0, quark)); - assertEquals(10, TmfStateSystemOperations.queryRangeMin(ssqi, 500, 1500, quark).unboxInt()); - assertEquals(10, TmfStateSystemOperations.queryRangeMin(ssqi, 1500, 5000, quark).unboxInt()); - assertEquals(30, TmfStateSystemOperations.queryRangeMin(ssqi, 5000, 10000, quark).unboxInt()); - assertEquals(10, TmfStateSystemOperations.queryRangeMin(ssqi, 0, 10000, quark).unboxInt()); - assertEquals(TmfStateValue.nullValue(), TmfStateSystemOperations.queryRangeMin(ssqi, 120000, 120000, quark)); - assertEquals(10, TmfStateSystemOperations.queryRangeMin(ssqi, 120500, 121500, quark).unboxInt()); - assertEquals(10, TmfStateSystemOperations.queryRangeMin(ssqi, 121500, 125000, quark).unboxInt()); - assertEquals(30, TmfStateSystemOperations.queryRangeMin(ssqi, 125000, 130000, quark).unboxInt()); - assertEquals(10, TmfStateSystemOperations.queryRangeMin(ssqi, 120000, 130000, quark).unboxInt()); - assertEquals(10, TmfStateSystemOperations.queryRangeMin(ssqi, 100000, 150000, quark).unboxInt()); - assertEquals(00, TmfStateSystemOperations.queryRangeMin(ssqi, 240000, 250000, quark).unboxInt()); - assertEquals(00, TmfStateSystemOperations.queryRangeMin(ssqi, 0, 250000, quark).unboxInt()); - assertEquals(00, TmfStateSystemOperations.queryRangeMin(ssqi, 250000, 250000, quark).unboxInt()); - - } catch (AttributeNotFoundException e) { - fail(e.getMessage()); - } catch (StateValueTypeException e) { - fail(e.getMessage()); - } catch (TimeRangeException e) { - fail(e.getMessage()); - } - } - - /** - * Test a query range to the state system to get the average value in the - * range. The test values are INTEGER. - */ - @Test - public void testQueryMipmapRangeAvgInteger() { - assertNotNull(ssqi); - try { - int quark = ssqi.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); - assertEquals(0.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 0, 0, quark), DELTA); - assertEquals(5.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 500, 1500, quark), DELTA); - assertEquals(90.0 / 7, TmfStateSystemOperations.queryRangeAverage(ssqi, 1500, 5000, quark), DELTA); - assertEquals(90.0 / 5, TmfStateSystemOperations.queryRangeAverage(ssqi, 5000, 10000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 0, 10000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 0, 20000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 500, 20500, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 1000, 21000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 2000, 22000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 3000, 23000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 4000, 24000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 5000, 25000, quark), DELTA); - assertEquals(0.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 120000, 120000, quark), DELTA); - assertEquals(5.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 120500, 121500, quark), DELTA); - assertEquals(90.0 / 7, TmfStateSystemOperations.queryRangeAverage(ssqi, 121500, 125000, quark), DELTA); - assertEquals(90.0 / 5, TmfStateSystemOperations.queryRangeAverage(ssqi, 125000, 130000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 120000, 130000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 100000, 150000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 240000, 250000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 0, 250000, quark), DELTA); - assertEquals(0.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 250000, 250000, quark), DELTA); - - } catch (AttributeNotFoundException e) { - fail(e.getMessage()); - } catch (TimeRangeException e) { - fail(e.getMessage()); - } catch (StateValueTypeException e) { - fail(e.getMessage()); - } - } - - /** - * Test a query range to the state system to get the maximum value in the - * range. The test values are DOUBLE. - */ - @Test - public void testQueryMipmapRangeMaxDouble() { - assertNotNull(ssqd); - try { - int quark = ssqd.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); - assertEquals(TmfStateValue.nullValue(), TmfStateSystemOperations.queryRangeMax(ssqd, 0, 0, quark)); - assertEquals(10.0, TmfStateSystemOperations.queryRangeMax(ssqd, 500, 1500, quark).unboxDouble(), DELTA); - assertEquals(20.0, TmfStateSystemOperations.queryRangeMax(ssqd, 1500, 5000, quark).unboxDouble(), DELTA); - assertEquals(30.0, TmfStateSystemOperations.queryRangeMax(ssqd, 5000, 10000, quark).unboxDouble(), DELTA); - assertEquals(30.0, TmfStateSystemOperations.queryRangeMax(ssqd, 0, 10000, quark).unboxDouble(), DELTA); - assertEquals(TmfStateValue.nullValue(), TmfStateSystemOperations.queryRangeMax(ssqd, 120000, 120000, quark)); - assertEquals(10.0, TmfStateSystemOperations.queryRangeMax(ssqd, 120500, 121500, quark).unboxDouble(), DELTA); - assertEquals(20.0, TmfStateSystemOperations.queryRangeMax(ssqd, 121500, 125000, quark).unboxDouble(), DELTA); - assertEquals(30.0, TmfStateSystemOperations.queryRangeMax(ssqd, 125000, 130000, quark).unboxDouble(), DELTA); - assertEquals(30.0, TmfStateSystemOperations.queryRangeMax(ssqd, 120000, 130000, quark).unboxDouble(), DELTA); - assertEquals(30.0, TmfStateSystemOperations.queryRangeMax(ssqd, 100000, 150000, quark).unboxDouble(), DELTA); - assertEquals(30.0, TmfStateSystemOperations.queryRangeMax(ssqd, 240000, 250000, quark).unboxDouble(), DELTA); - assertEquals(30.0, TmfStateSystemOperations.queryRangeMax(ssqd, 0, 250000, quark).unboxDouble(), DELTA); - assertEquals(00.0, TmfStateSystemOperations.queryRangeMax(ssqd, 250000, 250000, quark).unboxDouble(), DELTA); - - } catch (AttributeNotFoundException e) { - fail(e.getMessage()); - } catch (StateValueTypeException e) { - fail(e.getMessage()); - } catch (TimeRangeException e) { - fail(e.getMessage()); - } - } - - /** - * Test a query range to the state system to get the minimum value in the - * range. The test values are DOUBLE. - */ - @Test - public void testQueryMipmapRangeMinDouble() { - assertNotNull(ssqd); - try { - int quark = ssqd.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); - assertEquals(TmfStateValue.nullValue(), TmfStateSystemOperations.queryRangeMin(ssqd, 0, 0, quark)); - assertEquals(10.0, TmfStateSystemOperations.queryRangeMin(ssqd, 500, 1500, quark).unboxDouble(), DELTA); - assertEquals(10.0, TmfStateSystemOperations.queryRangeMin(ssqd, 1500, 5000, quark).unboxDouble(), DELTA); - assertEquals(30.0, TmfStateSystemOperations.queryRangeMin(ssqd, 5000, 10000, quark).unboxDouble(), DELTA); - assertEquals(10.0, TmfStateSystemOperations.queryRangeMin(ssqd, 0, 10000, quark).unboxDouble(), DELTA); - assertEquals(TmfStateValue.nullValue(), TmfStateSystemOperations.queryRangeMin(ssqd, 120000, 120000, quark)); - assertEquals(10.0, TmfStateSystemOperations.queryRangeMin(ssqd, 120500, 121500, quark).unboxDouble(), DELTA); - assertEquals(10.0, TmfStateSystemOperations.queryRangeMin(ssqd, 121500, 125000, quark).unboxDouble(), DELTA); - assertEquals(30.0, TmfStateSystemOperations.queryRangeMin(ssqd, 125000, 130000, quark).unboxDouble(), DELTA); - assertEquals(10.0, TmfStateSystemOperations.queryRangeMin(ssqd, 120000, 130000, quark).unboxDouble(), DELTA); - assertEquals(10.0, TmfStateSystemOperations.queryRangeMin(ssqd, 100000, 150000, quark).unboxDouble(), DELTA); - assertEquals(00.0, TmfStateSystemOperations.queryRangeMin(ssqd, 240000, 250000, quark).unboxDouble(), DELTA); - assertEquals(00.0, TmfStateSystemOperations.queryRangeMin(ssqd, 0, 250000, quark).unboxDouble(), DELTA); - assertEquals(00.0, TmfStateSystemOperations.queryRangeMin(ssqd, 250000, 250000, quark).unboxDouble(), DELTA); - - } catch (AttributeNotFoundException e) { - fail(e.getMessage()); - } catch (StateValueTypeException e) { - fail(e.getMessage()); - } catch (TimeRangeException e) { - fail(e.getMessage()); - } - } - - /** - * Test a query range to the state system to get the average value in the - * range. The test values are DOUBLE. - */ - @Test - public void testQueryMipmapRangeAvgDouble() { - assertNotNull(ssqd); - try { - int quark = ssqd.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); - assertEquals(0.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 0, 0, quark), DELTA); - assertEquals(5.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 500, 1500, quark), DELTA); - assertEquals(90.0 / 7, TmfStateSystemOperations.queryRangeAverage(ssqd, 1500, 5000, quark), DELTA); - assertEquals(90.0 / 5, TmfStateSystemOperations.queryRangeAverage(ssqd, 5000, 10000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 0, 10000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 0, 20000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 500, 20500, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 1000, 21000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 2000, 22000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 3000, 23000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 4000, 24000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 5000, 25000, quark), DELTA); - assertEquals(0.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 120000, 120000, quark), DELTA); - assertEquals(5.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 120500, 121500, quark), DELTA); - assertEquals(90.0 / 7, TmfStateSystemOperations.queryRangeAverage(ssqd, 121500, 125000, quark), DELTA); - assertEquals(90.0 / 5, TmfStateSystemOperations.queryRangeAverage(ssqd, 125000, 130000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 120000, 130000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 100000, 150000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 240000, 250000, quark), DELTA); - assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 0, 250000, quark), DELTA); - assertEquals(0.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 250000, 250000, quark), DELTA); - - } catch (AttributeNotFoundException e) { - fail(e.getMessage()); - } catch (TimeRangeException e) { - fail(e.getMessage()); - } catch (StateValueTypeException e) { - fail(e.getMessage()); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/AllTests.java deleted file mode 100644 index 283a914677..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/AllTests.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.synchronization; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite for org.eclipse.linuxtools.tmf.core.synchronization - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ TsTransformTest.class, - SyncTest.class, - TsTransformFactoryTest.class }) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/SyncTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/SyncTest.java deleted file mode 100644 index 270df9f851..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/SyncTest.java +++ /dev/null @@ -1,247 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.synchronization; - -import static org.junit.Assert.assertEquals; - -import java.util.Collection; -import java.util.LinkedList; - -import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventDependency; -import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform; -import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithm; -import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithm.SyncQuality; -import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithmFactory; -import org.eclipse.linuxtools.tmf.core.synchronization.TimestampTransformFactory; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.tests.stubs.event.TmfSyncEventStub; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; -import org.junit.Before; -import org.junit.Test; - -/** - * Tests for {@link SynchronizationAlgorithm} and its descendants - * - * @author Geneviève Bastien - */ -@SuppressWarnings("nls") -public class SyncTest { - - private TmfTraceStub t1, t2; - private Collection fTraces; - - /** - * Initializing the traces - */ - @Before - public void init() { - t1 = new TmfTraceStub(); - t1.init("t1"); - t2 = new TmfTraceStub(); - t2.init("t2"); - - Collection traces = new LinkedList<>(); - traces.add(t1); - traces.add(t2); - fTraces = traces; - } - - /** - * Testing fully incremental algorithm with communication between the two - * traces - */ - @Test - public void testFullyIncremental() { - - SynchronizationAlgorithm syncAlgo = SynchronizationAlgorithmFactory.getFullyIncrementalAlgorithm(); - - syncAlgo.init(fTraces); - - assertEquals(SyncQuality.ABSENT, syncAlgo.getSynchronizationQuality(t1, t2)); - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(1)), - new TmfSyncEventStub(t1, new TmfTimestamp(1)) - )); - assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1 beta 0 ]]", syncAlgo.toString()); - assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); - - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(1)), - new TmfSyncEventStub(t2, new TmfTimestamp(3)) - )); - assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1 beta 0 ]]", syncAlgo.toString()); - assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); - - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(2)), - new TmfSyncEventStub(t1, new TmfTimestamp(3)) - )); - assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1 beta 0.5 ]]", syncAlgo.toString()); - assertEquals(SyncQuality.APPROXIMATE, syncAlgo.getSynchronizationQuality(t1, t2)); - - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(3)), - new TmfSyncEventStub(t2, new TmfTimestamp(5)) - )); - assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 0.75 beta 1.25 ]]", syncAlgo.toString()); - assertEquals(SyncQuality.ACCURATE, syncAlgo.getSynchronizationQuality(t1, t2)); - - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(4)), - new TmfSyncEventStub(t2, new TmfTimestamp(8)) - )); - assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 0.75 beta 1.25 ]]", syncAlgo.toString()); - assertEquals(SyncQuality.ACCURATE, syncAlgo.getSynchronizationQuality(t1, t2)); - - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(4)), - new TmfSyncEventStub(t1, new TmfTimestamp(5)) - )); - assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1.125 beta 0.875 ]]", syncAlgo.toString()); - assertEquals(SyncQuality.ACCURATE, syncAlgo.getSynchronizationQuality(t1, t2)); - - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(4)), - new TmfSyncEventStub(t1, new TmfTimestamp(6)) - )); - assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1.125 beta 0.875 ]]", syncAlgo.toString()); - assertEquals(SyncQuality.ACCURATE, syncAlgo.getSynchronizationQuality(t1, t2)); - - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(6)), - new TmfSyncEventStub(t2, new TmfTimestamp(7)) - )); - assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 0.725 beta 1.275 ]]", syncAlgo.toString()); - assertEquals(SyncQuality.ACCURATE, syncAlgo.getSynchronizationQuality(t1, t2)); - - ITmfTimestampTransform tt2 = syncAlgo.getTimestampTransform(t2); - ITmfTimestampTransform tt1 = syncAlgo.getTimestampTransform(t1); - - assertEquals(syncAlgo.getTimestampTransform(t1.getHostId()), tt1); - assertEquals(TimestampTransformFactory.getDefaultTransform(), tt1); - assertEquals(syncAlgo.getTimestampTransform(t2.getHostId()), tt2); - - /* Make the two hulls intersect */ - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(7)), - new TmfSyncEventStub(t2, new TmfTimestamp(4)) - )); - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(7)), - new TmfSyncEventStub(t1, new TmfTimestamp(3)) - )); - assertEquals(SyncQuality.FAIL, syncAlgo.getSynchronizationQuality(t1, t2)); - } - - /** - * Testing the fully incremental synchronization algorithm when - * communication goes in only one direction - */ - @Test - public void testOneHull() { - - SynchronizationAlgorithm syncAlgo = SynchronizationAlgorithmFactory.getFullyIncrementalAlgorithm(); - - syncAlgo.init(fTraces); - - assertEquals(SyncQuality.ABSENT, syncAlgo.getSynchronizationQuality(t1, t2)); - - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(1)), - new TmfSyncEventStub(t2, new TmfTimestamp(3))) - ); - assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); - - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(2)), - new TmfSyncEventStub(t2, new TmfTimestamp(5))) - ); - - assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); - - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(3)), - new TmfSyncEventStub(t2, new TmfTimestamp(5))) - ); - assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); - - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(4)), - new TmfSyncEventStub(t2, new TmfTimestamp(7))) - ); - assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); - assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1 beta 0 ]]", syncAlgo.toString()); - - } - - /** - * Testing the fully incremental synchronization algorithm when all - * communication from trace1 to trace2 happens before all communication from - * trace2 to trace1 - */ - @Test - public void testDisjoint() { - - SynchronizationAlgorithm syncAlgo = SynchronizationAlgorithmFactory.getFullyIncrementalAlgorithm(); - - syncAlgo.init(fTraces); - - assertEquals(SyncQuality.ABSENT, syncAlgo.getSynchronizationQuality(t1, t2)); - - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(1)), - new TmfSyncEventStub(t2, new TmfTimestamp(3))) - ); - assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); - - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(2)), - new TmfSyncEventStub(t2, new TmfTimestamp(5))) - ); - - assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); - - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(3)), - new TmfSyncEventStub(t2, new TmfTimestamp(5))) - ); - assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); - - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(4)), - new TmfSyncEventStub(t2, new TmfTimestamp(7))) - ); - assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); - assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1 beta 0 ]]", syncAlgo.toString()); - - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(7)), - new TmfSyncEventStub(t1, new TmfTimestamp(6))) - ); - assertEquals(SyncQuality.APPROXIMATE, syncAlgo.getSynchronizationQuality(t1, t2)); - - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(8)), - new TmfSyncEventStub(t1, new TmfTimestamp(6))) - ); - assertEquals(SyncQuality.APPROXIMATE, syncAlgo.getSynchronizationQuality(t1, t2)); - - syncAlgo.addMatch( - new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(10)), - new TmfSyncEventStub(t1, new TmfTimestamp(8))) - ); - assertEquals(SyncQuality.APPROXIMATE, syncAlgo.getSynchronizationQuality(t1, t2)); - assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1 beta 2.5 ]]", syncAlgo.toString()); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/TsTransformFactoryTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/TsTransformFactoryTest.java deleted file mode 100644 index 1ab11c3b7f..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/TsTransformFactoryTest.java +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.synchronization; - -import static org.junit.Assert.assertEquals; - -import java.math.BigDecimal; - -import org.eclipse.linuxtools.internal.tmf.core.synchronization.TmfConstantTransform; -import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform; -import org.eclipse.linuxtools.tmf.core.synchronization.TimestampTransformFactory; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.junit.Test; - -/** - * Timestamp transform tests - * - * @author Matthew Khouzam - * - */ -public class TsTransformFactoryTest { - private final ITmfTimestamp t0 = new TmfTimestamp(0); - private final ITmfTimestamp t100 = new TmfTimestamp(100); - private final ITmfTimestamp t1e2 = new TmfTimestamp(1, 2); - private final ITmfTimestamp t1e3 = new TmfTimestamp(1, 3); - private final ITmfTimestamp tn0 = new TmfNanoTimestamp(0); - private final ITmfTimestamp tn100 = new TmfNanoTimestamp(100); - private final ITmfTimestamp tn1 = new TmfNanoTimestamp(1); - private final ITmfTimestampTransform identity1 = TimestampTransformFactory.createLinear(1.0, new TmfNanoTimestamp(0)); - private final ITmfTimestampTransform offset1 = TimestampTransformFactory.createWithOffset(100); - private final ITmfTimestampTransform offset2 = TimestampTransformFactory.createLinear(BigDecimal.ONE, new BigDecimal(100)); - private final ITmfTimestampTransform offset3 = TimestampTransformFactory.createLinear(1.0, 100); - private final ITmfTimestampTransform offset4 = TimestampTransformFactory.createLinear(1.0, new TmfNanoTimestamp(100)); - - /** - * Test with identity - */ - @Test - public void transformIdenity() { - final ITmfTimestampTransform identity = TimestampTransformFactory.createWithOffset(0); - final ITmfTimestampTransform innefficientIdentity = new TmfConstantTransform(); - final ITmfTimestampTransform compositeInnefficientIdentity = identity.composeWith(innefficientIdentity); - final ITmfTimestampTransform compositeInnefficientIdentity2 = innefficientIdentity.composeWith(innefficientIdentity); - final ITmfTimestampTransform compositeInnefficientIdentity3 = innefficientIdentity.composeWith(identity); - assertEquals(t0, identity.transform(t0)); - assertEquals(tn0, identity.transform(tn0)); - assertEquals(t100, identity.transform(t100)); - assertEquals(t1e2, identity.transform(t100)); - assertEquals(t1e2, identity.transform(t1e2)); - assertEquals(t1e3, identity.transform(t1e3)); - assertEquals(tn100, identity.transform(tn100)); - assertEquals(t0, innefficientIdentity.transform(t0)); // bad practice - assertEquals(t0, compositeInnefficientIdentity.transform(t0)); // bad - // practice - assertEquals(t0, compositeInnefficientIdentity2.transform(t0)); // bad - // practice - assertEquals(t0, compositeInnefficientIdentity3.transform(t0)); // bad - // practice - } - - /** - * Test with an offset of 100 - */ - @Test - public void transformOffset() { - final ITmfTimestampTransform offset = offset1; - final ITmfTimestampTransform compositeTransform = offset.composeWith(TimestampTransformFactory.createWithOffset(new TmfNanoTimestamp(-100))); - assertEquals(tn100, offset.transform(t0)); - assertEquals(tn100, offset.transform(tn0)); - assertEquals(tn0, compositeTransform.transform(tn0)); - assertEquals(t0, compositeTransform.transform(t0)); - assertEquals(200, offset1.transform(100)); - assertEquals(200, offset2.transform(100)); - assertEquals(200, offset3.transform(100)); - assertEquals(200, offset4.transform(100)); - } - - /** - * Test with a slope - */ - @Test - public void transformSlope() { - final ITmfTimestampTransform slope = TimestampTransformFactory.createLinear(10, 0); - final ITmfTimestampTransform slope1 = TimestampTransformFactory.createLinear(10.0, new TmfNanoTimestamp(0)); - assertEquals(t1e3, slope.transform(t1e2)); - assertEquals(tn100, slope.transform(new TmfNanoTimestamp(10))); - assertEquals(tn100, slope.transform(slope.transform(tn1))); - assertEquals(tn100, slope.composeWith(slope).transform(tn1)); - assertEquals(tn100, slope1.transform(new TmfNanoTimestamp(10))); - } - - /** - * Test toStrings - */ - @Test - public void testToString() { - final String expectedLinear = "TmfTimestampLinear [ slope = 314.0, offset = 0.0 ]"; - final String expectedLinearBigDec = "TmfTimestampLinear [ slope = 314, offset = 0 ]"; - final String expectedOffset = "TmfConstantTransform [ offset = 314 ]"; - final String expectedIdentity = "TmfTimestampTransform [ IDENTITY ]"; - final String expectedOffset100 = "TmfConstantTransform [ offset = 100 ]"; - assertEquals(expectedLinear, TimestampTransformFactory.createLinear(314, 0).toString()); - assertEquals(expectedLinearBigDec, TimestampTransformFactory.createLinear(BigDecimal.valueOf(314), BigDecimal.ZERO).toString()); - assertEquals(expectedOffset, TimestampTransformFactory.createLinear(1, 314).toString()); - assertEquals(expectedOffset, TimestampTransformFactory.createWithOffset(314).toString()); - assertEquals(expectedOffset, TimestampTransformFactory.createWithOffset(14).composeWith(TimestampTransformFactory.createWithOffset(300)).toString()); - assertEquals(expectedIdentity, TimestampTransformFactory.createWithOffset(314).composeWith(TimestampTransformFactory.createWithOffset(-314)).toString()); - assertEquals(expectedIdentity, TimestampTransformFactory.createWithOffset(0).toString()); - assertEquals(expectedIdentity, identity1.toString()); - assertEquals(expectedOffset100, offset1.toString()); - assertEquals(expectedOffset100, offset2.toString()); - assertEquals(expectedOffset100, offset3.toString()); - assertEquals(expectedOffset100, offset4.toString()); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/TsTransformTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/TsTransformTest.java deleted file mode 100644 index 3d355ba147..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/TsTransformTest.java +++ /dev/null @@ -1,144 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.synchronization; - -import static org.junit.Assert.*; - -import java.math.BigDecimal; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.linuxtools.internal.tmf.core.synchronization.TmfTimestampTransform; -import org.eclipse.linuxtools.internal.tmf.core.synchronization.TmfTimestampTransformLinear; -import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.junit.Test; - -/** - * Tests for {@link TmfTimestampTransform} and its descendants - * - * @author Geneviève Bastien - */ -@SuppressWarnings("nls") -public class TsTransformTest { - - private long ts = 1361657893526374091L; - private ITmfTimestamp oTs = new TmfTimestamp(ts); - - /** - * Test the linear transform - */ - @Test - public void testLinearTransform() { - /* Default constructor */ - TmfTimestampTransformLinear ttl = new TmfTimestampTransformLinear(); - assertEquals(1361657893526374091L, ttl.transform(ts)); - assertEquals(1361657893526374091L, ttl.transform(oTs).getValue()); - - /* Just an offset */ - ttl = new TmfTimestampTransformLinear(BigDecimal.valueOf(1.0), BigDecimal.valueOf(3)); - assertEquals(1361657893526374094L, ttl.transform(ts)); - assertEquals(1361657893526374094L, ttl.transform(oTs).getValue()); - - /* Just a slope */ - ttl = new TmfTimestampTransformLinear(BigDecimal.valueOf(2.0), BigDecimal.valueOf(0)); - assertEquals(2723315787052748182L, ttl.transform(ts)); - assertEquals(2723315787052748182L, ttl.transform(oTs).getValue()); - - /* Offset and slope */ - ttl = new TmfTimestampTransformLinear(BigDecimal.valueOf(2.0), BigDecimal.valueOf(3)); - assertEquals(2723315787052748185L, ttl.transform(ts)); - assertEquals(2723315787052748185L, ttl.transform(oTs).getValue()); - - /* Offset and slope */ - ttl = new TmfTimestampTransformLinear(BigDecimal.valueOf(0.5), BigDecimal.valueOf(0)); - assertEquals(680828946763187045L, ttl.transform(ts)); - assertEquals(680828946763187045L, ttl.transform(oTs).getValue()); - } - - /** - * Test for the identity transform - */ - @Test - public void testIdentityTransform() { - ITmfTimestampTransform tt = TmfTimestampTransform.IDENTITY; - assertEquals(ts, tt.transform(ts)); - assertEquals(oTs, tt.transform(oTs)); - } - - /** - * Test hash and equals function - */ - @Test - public void testEquality() { - Map map = new HashMap<>(); - ITmfTimestampTransform ttl = new TmfTimestampTransformLinear(BigDecimal.valueOf(2.0), BigDecimal.valueOf(3)); - ITmfTimestampTransform ttl2 = new TmfTimestampTransformLinear(BigDecimal.valueOf(2.0), BigDecimal.valueOf(3)); - ITmfTimestampTransform ttl3 = new TmfTimestampTransformLinear(BigDecimal.valueOf(3), BigDecimal.valueOf(3)); - assertEquals(ttl, ttl2); - assertFalse(ttl.equals(ttl3)); - assertFalse(ttl2.equals(ttl3)); - - map.put(ttl, "a"); - assertTrue(map.containsKey(ttl2)); - assertEquals("a", map.get(ttl)); - - ITmfTimestampTransform ti = TmfTimestampTransform.IDENTITY; - assertEquals(TmfTimestampTransform.IDENTITY, ti); - assertFalse(TmfTimestampTransform.IDENTITY.equals(ttl)); - - map.put(ti, "b"); - assertTrue(map.containsKey(TmfTimestampTransform.IDENTITY)); - assertEquals("b", map.get(ti)); - - assertFalse(ti.equals(ttl)); - assertFalse(ttl.equals(ti)); - - } - - /** - * Test the transform composition function - */ - @Test - public void testComposition() { - long t = 100; - ITmfTimestampTransform ti = TmfTimestampTransform.IDENTITY; - ITmfTimestampTransform ttl = new TmfTimestampTransformLinear(BigDecimal.valueOf(2.0), BigDecimal.valueOf(3)); - ITmfTimestampTransform ttl2 = new TmfTimestampTransformLinear(BigDecimal.valueOf(1.5), BigDecimal.valueOf(8)); - - ITmfTimestampTransform tc1 = ti.composeWith(ttl); - /* Should be ttl */ - assertEquals(ttl, tc1); - assertEquals(203, tc1.transform(t)); - - tc1 = ttl.composeWith(ti); - /* Should be ttl also */ - assertEquals(ttl, tc1); - assertEquals(203, tc1.transform(t)); - - tc1 = ti.composeWith(ti); - /* Should be identity */ - assertEquals(tc1, TmfTimestampTransform.IDENTITY); - assertEquals(100, tc1.transform(t)); - - tc1 = ttl.composeWith(ttl2); - assertEquals(ttl.transform(ttl2.transform(t)), tc1.transform(t)); - assertEquals(319, tc1.transform(t)); - - tc1 = ttl2.composeWith(ttl); - assertEquals(ttl2.transform(ttl.transform(t)), tc1.transform(t)); - assertEquals(312, tc1.transform(t)); - - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/AllTests.java deleted file mode 100644 index 657ce1b761..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/AllTests.java +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Adjusted for new Trace Model - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite for org.eclipse.linuxtools.tmf.core.trace - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TmfContextTest.class, - TmfExperimentTest.class, - TmfMultiTraceExperimentTest.class, - TmfTraceTest.class -}) -public class AllTests {} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfContextTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfContextTest.java deleted file mode 100644 index e5f76dc206..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfContextTest.java +++ /dev/null @@ -1,255 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Adapted for TMF Trace Model 1.0 - * Alexandre Montplaisir - Port to JUnit4 - * Patrick Tasse - Updated for removal of context clone - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.TmfContext; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfTimestampLocation; -import org.junit.Test; - -/** - * Test suite for the TmfContext class. - */ -@SuppressWarnings("javadoc") -public class TmfContextTest { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - private final Long aLong = 12345L; - private final TmfTimestamp aTimestamp = new TmfTimestamp(); - - private final TmfLongLocation fLocation1 = new TmfLongLocation(aLong); - private final TmfTimestampLocation fLocation2 = new TmfTimestampLocation(aTimestamp); - - private final long fRank1 = 1; - private final long fRank2 = 2; - - private final TmfContext fContext1 = new TmfContext(fLocation1, fRank1); - private final TmfContext fContext2 = new TmfContext(fLocation2, fRank2); - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - @Test - public void testTmfContextDefault() { - final TmfContext context = new TmfContext(); - assertEquals("getLocation", null, context.getLocation()); - assertEquals("getRank", ITmfContext.UNKNOWN_RANK, context.getRank()); - } - - @Test - public void testTmfContextNoRank() { - final TmfContext context1 = new TmfContext(fLocation1); - final TmfContext context2 = new TmfContext(fLocation2); - - assertEquals("getLocation", fLocation1, context1.getLocation()); - assertEquals("getLocation", fLocation2, context2.getLocation()); - - assertEquals("getRank", ITmfContext.UNKNOWN_RANK, context1.getRank()); - assertEquals("getRank", ITmfContext.UNKNOWN_RANK, context2.getRank()); - } - - @Test - public void testTmfContext() { - assertEquals("getLocation", fLocation1, fContext1.getLocation()); - assertEquals("getLocation", fLocation2, fContext2.getLocation()); - - assertEquals("getRank", fRank1, fContext1.getRank()); - assertEquals("getRank", fRank2, fContext2.getRank()); - } - - @Test - public void testTmfContextCopy() { - final TmfContext context1 = new TmfContext(fContext1); - final TmfContext context2 = new TmfContext(fContext2); - - assertEquals("getLocation", fLocation1, context1.getLocation()); - assertEquals("getLocation", fLocation2, context2.getLocation()); - - assertEquals("getRank", fRank1, context1.getRank()); - assertEquals("getRank", fRank2, context2.getRank()); - } - - @Test - public void testTmfContextCopy2() { - try { - new TmfContext((TmfContext) null); - fail("Copy constructor: no exception"); - } - catch (final IllegalArgumentException e) { - // pass - } - catch (final Exception e) { - fail("Copy constructor: wrong exception"); - } - } - - // ------------------------------------------------------------------------ - // equals - // ------------------------------------------------------------------------ - - @Test - public void testEqualsReflexivity() { - assertTrue("equals", fContext1.equals(fContext1)); - assertTrue("equals", fContext2.equals(fContext2)); - - assertFalse("equals", fContext1.equals(fContext2)); - assertFalse("equals", fContext2.equals(fContext1)); - } - - @Test - public void testEqualsSymmetry() { - final TmfContext context1 = new TmfContext(fContext1); - final TmfContext context2 = new TmfContext(fContext2); - - assertTrue("equals", context1.equals(fContext1)); - assertTrue("equals", fContext1.equals(context1)); - - assertTrue("equals", context2.equals(fContext2)); - assertTrue("equals", fContext2.equals(context2)); - } - - @Test - public void testEqualsTransivity() { - final TmfContext context1 = new TmfContext(fContext1); - final TmfContext context2 = new TmfContext(context1); - final TmfContext context3 = new TmfContext(context2); - - assertTrue("equals", context1.equals(context2)); - assertTrue("equals", context2.equals(context3)); - assertTrue("equals", context1.equals(context3)); - } - - @Test - public void testEqualsNull() { - assertFalse("equals", fContext1.equals(null)); - assertFalse("equals", fContext2.equals(null)); - } - - private static class MyContext extends TmfContext { - } - - @Test - public void testNonEquals() { - - // Different classes - final MyContext myContext = new MyContext(); - assertFalse("equals", fContext1.equals(myContext)); - assertFalse("equals", myContext.equals(fContext1)); - - // Different locations - TmfContext context1 = new TmfContext(fContext1); - TmfContext context2 = new TmfContext(fContext1); - context1.setLocation(null); - context2.setLocation(null); - - assertFalse("equals", fContext1.equals(context1)); - assertFalse("equals", context1.equals(fContext1)); - assertTrue("equals", context1.equals(context2)); - - // Different ranks - context1 = new TmfContext(fContext1); - context2 = new TmfContext(fContext1); - context1.setRank(fContext1.getRank() + 1); - context2.setRank(fContext1.getRank() + 2); - - assertFalse("equals", fContext1.equals(context1)); - assertFalse("equals", context1.equals(fContext1)); - assertFalse("equals", context1.equals(context2)); - } - - // ------------------------------------------------------------------------ - // hashCode - // ------------------------------------------------------------------------ - - @Test - public void testHashCode() { - final TmfContext context1 = new TmfContext(fContext1); - final TmfContext context2 = new TmfContext(fContext2); - - assertEquals("hashCode", fContext1.hashCode(), context1.hashCode()); - assertEquals("hashCode", fContext2.hashCode(), context2.hashCode()); - - assertFalse("hashCode", fContext1.hashCode() == context2.hashCode()); - assertFalse("hashCode", fContext2.hashCode() == context1.hashCode()); - - final TmfContext nullContext1 = new TmfContext(); - final TmfContext nullContext2 = new TmfContext(nullContext1); - assertEquals("hashCode", nullContext1.hashCode(), nullContext2.hashCode()); - } - - // ------------------------------------------------------------------------ - // toString - // ------------------------------------------------------------------------ - - @Test - public void testToString() { - final String expected1 = "TmfContext [fLocation=" + fLocation1 + ", fRank=" + fRank1 + "]"; - final String expected2 = "TmfContext [fLocation=" + fLocation2 + ", fRank=" + fRank2 + "]"; - - assertEquals("toString", expected1, fContext1.toString()); - assertEquals("toString", expected2, fContext2.toString()); - } - - // ------------------------------------------------------------------------ - // setLocation, setRank, updateRank - // ------------------------------------------------------------------------ - - @Test - public void testSetLocation() { - final TmfContext context1 = new TmfContext(fContext1); - context1.setLocation(fContext2.getLocation()); - - assertEquals("getLocation", fLocation2, context1.getLocation()); - assertEquals("getRank", fRank1, context1.getRank()); - } - - @Test - public void testSetRank() { - final TmfContext context1 = new TmfContext(fContext1); - context1.setRank(fContext2.getRank()); - - assertEquals("getLocation", fLocation1, context1.getLocation()); - assertEquals("getRank", fRank2, context1.getRank()); - } - - @Test - public void testIncreaseRank() { - final TmfContext context1 = new TmfContext(fContext1); - - context1.increaseRank(); - assertEquals("getRank", fRank1 + 1, context1.getRank()); - context1.increaseRank(); - assertEquals("getRank", fRank1 + 2, context1.getRank()); - - context1.setRank(ITmfContext.UNKNOWN_RANK); - context1.increaseRank(); - assertEquals("getRank", ITmfContext.UNKNOWN_RANK, context1.getRank()); - context1.increaseRank(); - assertEquals("getRank", ITmfContext.UNKNOWN_RANK, context1.getRank()); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfExperimentTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfExperimentTest.java deleted file mode 100644 index a8635e6592..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfExperimentTest.java +++ /dev/null @@ -1,941 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Adjusted for new Trace Model - * Alexandre Montplaisir - Port to JUnit4 - * Patrick Tasse - Updated for rank in experiment location - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.Vector; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.linuxtools.internal.tmf.core.trace.TmfExperimentContext; -import org.eclipse.linuxtools.internal.tmf.core.trace.TmfExperimentLocation; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest.ExecutionType; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.tests.TmfCoreTestPlugin; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation; -import org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestExperimentAnalysis; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfExperimentStub; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; -import org.junit.Before; -import org.junit.Test; - -/** - * Test suite for the TmfExperiment class (single trace). - */ -@SuppressWarnings("javadoc") -public class TmfExperimentTest { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private static final String EXPERIMENT = "MyExperiment"; - private static int NB_EVENTS = 10000; - private static int BLOCK_SIZE = 1000; - - private static final double DELTA = 1e-15; - - private ITmfTrace[] fTestTraces; - private TmfExperimentStub fExperiment; - - private static byte SCALE = (byte) -3; - - // ------------------------------------------------------------------------ - // Housekeeping - // ------------------------------------------------------------------------ - - private synchronized ITmfTrace[] setupTrace(final String path) { - if (fTestTraces == null) { - fTestTraces = new ITmfTrace[1]; - try { - final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(path), null); - final File test = new File(FileLocator.toFileURL(location).toURI()); - final TmfTraceStub trace = new TmfTraceStub(test.getPath(), 0, true, null); - fTestTraces[0] = trace; - } catch (final TmfTraceException e) { - e.printStackTrace(); - } catch (final URISyntaxException e) { - e.printStackTrace(); - } catch (final IOException e) { - e.printStackTrace(); - } - } - return fTestTraces; - } - - private synchronized void setupExperiment() { - if (fExperiment == null) { - fExperiment = new TmfExperimentStub(EXPERIMENT, fTestTraces, BLOCK_SIZE); - fExperiment.getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, true); - } - } - - @Before - public void setUp() { - setupTrace(TmfTestTrace.A_TEST_10K.getFullPath()); - setupExperiment(); - } - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - @Test - public void testSimpleTmfExperimentConstructor() { - TmfExperiment experiment = new TmfExperiment(ITmfEvent.class, EXPERIMENT, fTestTraces); - assertEquals("GetId", EXPERIMENT, experiment.getName()); - assertEquals("GetCacheSize", TmfExperiment.DEFAULT_INDEX_PAGE_SIZE, experiment.getCacheSize()); - experiment.dispose(); - - experiment = new TmfExperiment(ITmfEvent.class, EXPERIMENT, null); - experiment.dispose(); - } - - @Test - public void testNormalTmfExperimentConstructor() { - assertEquals("GetId", EXPERIMENT, fExperiment.getName()); - assertEquals("GetNbEvents", NB_EVENTS, fExperiment.getNbEvents()); - - final long nbExperimentEvents = fExperiment.getNbEvents(); - assertEquals("GetNbEvents", NB_EVENTS, nbExperimentEvents); - - final long nbTraceEvents = fExperiment.getTraces()[0].getNbEvents(); - assertEquals("GetNbEvents", NB_EVENTS, nbTraceEvents); - - final TmfTimeRange timeRange = fExperiment.getTimeRange(); - assertEquals("getStartTime", 1, timeRange.getStartTime().getValue()); - assertEquals("getEndTime", NB_EVENTS, timeRange.getEndTime().getValue()); - } - - // ------------------------------------------------------------------------ - // Experiment setup - // ------------------------------------------------------------------------ - - @Test - public void testExperimentInitialization() { - /* - * Calling default constructor, then init should be equivalent to - * calling the full constructor - */ - - TmfExperimentStub experiment = new TmfExperimentStub(); - experiment.initExperiment(ITmfEvent.class, EXPERIMENT, fTestTraces, 5000, null); - experiment.getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, true); - - assertEquals("GetId", EXPERIMENT, fExperiment.getName()); - assertEquals("GetNbEvents", NB_EVENTS, fExperiment.getNbEvents()); - - final long nbExperimentEvents = fExperiment.getNbEvents(); - assertEquals("GetNbEvents", NB_EVENTS, nbExperimentEvents); - - final long nbTraceEvents = fExperiment.getTraces()[0].getNbEvents(); - assertEquals("GetNbEvents", NB_EVENTS, nbTraceEvents); - - final TmfTimeRange timeRange = fExperiment.getTimeRange(); - assertEquals("getStartTime", 1, timeRange.getStartTime().getValue()); - assertEquals("getEndTime", NB_EVENTS, timeRange.getEndTime().getValue()); - } - - // ------------------------------------------------------------------------ - // getTimestamp - // ------------------------------------------------------------------------ - - @Test - public void testGetTimestamp() { - assertEquals("getTimestamp", new TmfTimestamp( 1, (byte) -3), fExperiment.getTimestamp( 0)); - assertEquals("getTimestamp", new TmfTimestamp( 2, (byte) -3), fExperiment.getTimestamp( 1)); - assertEquals("getTimestamp", new TmfTimestamp( 11, (byte) -3), fExperiment.getTimestamp( 10)); - assertEquals("getTimestamp", new TmfTimestamp( 101, (byte) -3), fExperiment.getTimestamp( 100)); - assertEquals("getTimestamp", new TmfTimestamp( 1001, (byte) -3), fExperiment.getTimestamp(1000)); - assertEquals("getTimestamp", new TmfTimestamp( 2001, (byte) -3), fExperiment.getTimestamp(2000)); - assertEquals("getTimestamp", new TmfTimestamp( 2501, (byte) -3), fExperiment.getTimestamp(2500)); - assertEquals("getTimestamp", new TmfTimestamp(10000, (byte) -3), fExperiment.getTimestamp(9999)); - assertNull("getTimestamp", fExperiment.getTimestamp(10000)); - } - - // ------------------------------------------------------------------------ - // State system, statistics and modules methods - // ------------------------------------------------------------------------ - - @Test - public void testGetAnalysisModules() { - /* There should not be any modules at this point */ - Iterable modules = fExperiment.getAnalysisModules(); - assertFalse(modules.iterator().hasNext()); - - /* Open the experiment, the modules should be populated */ - fExperiment.traceOpened(new TmfTraceOpenedSignal(this, fExperiment, null)); - modules = fExperiment.getAnalysisModules(); - Iterable testModules = fExperiment.getAnalysisModulesOfClass(TestExperimentAnalysis.class); - assertTrue(modules.iterator().hasNext()); - assertTrue(testModules.iterator().hasNext()); - } - - // ------------------------------------------------------------------------ - // seekEvent by location - // ------------------------------------------------------------------------ - - @Test - public void testSeekBadLocation() { - ITmfContext context = fExperiment.seekEvent(new TmfLongLocation(0L)); - assertNull("seekEvent", context); - } - - @Test - public void testSeekNoTrace() { - TmfExperiment experiment = new TmfExperiment(ITmfEvent.class, EXPERIMENT, null); - ITmfContext context = experiment.seekEvent((TmfExperimentLocation) null); - assertNull("seekEvent", context); - experiment.dispose(); - } - - // ------------------------------------------------------------------------ - // seekEvent on ratio - // ------------------------------------------------------------------------ - - @Test - public void testSeekEventOnRatio() { - // First event - ITmfContext context = fExperiment.seekEvent(0.0); - assertEquals("Context rank", 0, context.getRank()); - ITmfEvent event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Context rank", 0, context.getRank()); - - // Middle event - int midTrace = NB_EVENTS / 2; - context = fExperiment.seekEvent(0.5); - assertEquals("Context rank", midTrace, context.getRank()); - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", midTrace + 1, event.getTimestamp().getValue()); - assertEquals("Context rank", midTrace, context.getRank()); - - // Last event - context = fExperiment.seekEvent(1.0); - assertEquals("Context rank", NB_EVENTS, context.getRank()); - event = fExperiment.parseEvent(context); - assertNull("Event timestamp", event); - assertEquals("Context rank", NB_EVENTS, context.getRank()); - - // Beyond last event - context = fExperiment.seekEvent(1.1); - assertEquals("Context rank", NB_EVENTS, context.getRank()); - event = fExperiment.parseEvent(context); - assertNull("Event timestamp", event); - assertEquals("Context rank", NB_EVENTS, context.getRank()); - - // Negative ratio - context = fExperiment.seekEvent(-0.5); - assertEquals("Context rank", 0, context.getRank()); - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Context rank", 0, context.getRank()); - } - - @Test - public void testGetLocationRatio() { - // First event - ITmfContext context = fExperiment.seekEvent((ITmfLocation) null); - double ratio = fExperiment.getLocationRatio(context.getLocation()); - assertEquals("getLocationRatio", 0.0, ratio, DELTA); - - // Middle event - context = fExperiment.seekEvent(NB_EVENTS / 2); - ratio = fExperiment.getLocationRatio(context.getLocation()); - assertEquals("getLocationRatio", (double) (NB_EVENTS / 2) / NB_EVENTS, ratio, DELTA); - - // Last event - context = fExperiment.seekEvent(NB_EVENTS - 1); - ratio = fExperiment.getLocationRatio(context.getLocation()); - assertEquals("getLocationRatio", (double) (NB_EVENTS - 1) / NB_EVENTS, ratio, DELTA); - } - -// @SuppressWarnings("rawtypes") -// public void testGetCurrentLocation() { -// ITmfContext context = fExperiment.seekEvent((ITmfLocation) null); -// ITmfLocation location = fExperiment.getCurrentLocation(); -// assertEquals("getCurrentLocation", location, context.getLocation()); -// } - - // ------------------------------------------------------------------------ - // seekEvent on rank - // ------------------------------------------------------------------------ - - @Test - public void testSeekRankOnCacheBoundary() { - long cacheSize = fExperiment.getCacheSize(); - - // On lower bound, returns the first event (TS = 1) - ITmfContext context = fExperiment.seekEvent(0); - assertEquals("Context rank", 0, context.getRank()); - - ITmfEvent event = fExperiment.getNext(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Context rank", 1, context.getRank()); - - // Position trace at event rank [cacheSize] - context = fExperiment.seekEvent(cacheSize); - assertEquals("Context rank", cacheSize, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); - assertEquals("Context rank", cacheSize + 1, context.getRank()); - - // Position trace at event rank [4 * cacheSize] - context = fExperiment.seekEvent(4 * cacheSize); - assertEquals("Context rank", 4 * cacheSize, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 4 * cacheSize + 1, event.getTimestamp().getValue()); - assertEquals("Context rank", 4 * cacheSize + 1, context.getRank()); - } - - @Test - public void testSeekRankNotOnCacheBoundary() { - long cacheSize = fExperiment.getCacheSize(); - - // Position trace at event rank 9 - ITmfContext context = fExperiment.seekEvent(9); - assertEquals("Context rank", 9, context.getRank()); - - ITmfEvent event = fExperiment.getNext(context); - assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); - assertEquals("Context rank", 10, context.getRank()); - - // Position trace at event rank [cacheSize - 1] - context = fExperiment.seekEvent(cacheSize - 1); - assertEquals("Context rank", cacheSize - 1, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", cacheSize, event.getTimestamp().getValue()); - assertEquals("Context rank", cacheSize, context.getRank()); - - // Position trace at event rank [cacheSize + 1] - context = fExperiment.seekEvent(cacheSize + 1); - assertEquals("Context rank", cacheSize + 1, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", cacheSize + 2, event.getTimestamp().getValue()); - assertEquals("Context rank", cacheSize + 2, context.getRank()); - - // Position trace at event rank 4500 - context = fExperiment.seekEvent(4500); - assertEquals("Context rank", 4500, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); - assertEquals("Context rank", 4501, context.getRank()); - } - - @Test - public void testSeekRankOutOfScope() { - // Position trace at beginning - ITmfContext context = fExperiment.seekEvent(-1); - assertEquals("Event rank", 0, context.getRank()); - - ITmfEvent event = fExperiment.getNext(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Context rank", 1, context.getRank()); - - // Position trace at event passed the end - context = fExperiment.seekEvent(NB_EVENTS); - assertEquals("Context rank", NB_EVENTS, context.getRank()); - - event = fExperiment.getNext(context); - assertNull("Event", event); - assertEquals("Context rank", NB_EVENTS, context.getRank()); - } - - // ------------------------------------------------------------------------ - // seekEvent on timestamp - // ------------------------------------------------------------------------ - - @Test - public void testSeekTimestampOnCacheBoundary() { - long cacheSize = fExperiment.getCacheSize(); - - // Position trace at event rank 0 - ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(1, SCALE, 0)); - assertEquals("Context rank", 0, context.getRank()); - - ITmfEvent event = fExperiment.getNext(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Context rank", 1, context.getRank()); - - // Position trace at event rank [cacheSize] - context = fExperiment.seekEvent(new TmfTimestamp(cacheSize + 1, SCALE, 0)); - assertEquals("Event rank", cacheSize, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); - assertEquals("Context rank", cacheSize + 1, context.getRank()); - - // Position trace at event rank [4 * cacheSize] - context = fExperiment.seekEvent(new TmfTimestamp(4 * cacheSize + 1, SCALE, 0)); - assertEquals("Context rank", 4 * cacheSize, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 4 * cacheSize + 1, event.getTimestamp().getValue()); - assertEquals("Context rank", 4 * cacheSize + 1, context.getRank()); - } - - @Test - public void testSeekTimestampNotOnCacheBoundary() { - // Position trace at event rank 1 (TS = 2) - ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(2, SCALE, 0)); - assertEquals("Context rank", 1, context.getRank()); - - ITmfEvent event = fExperiment.getNext(context); - assertEquals("Event timestamp", 2, event.getTimestamp().getValue()); - assertEquals("Context rank", 2, context.getRank()); - - // Position trace at event rank 9 (TS = 10) - context = fExperiment.seekEvent(new TmfTimestamp(10, SCALE, 0)); - assertEquals("Context rank", 9, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); - assertEquals("Context rank", 10, context.getRank()); - - // Position trace at event rank 999 (TS = 1000) - context = fExperiment.seekEvent(new TmfTimestamp(1000, SCALE, 0)); - assertEquals("Context rank", 999, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 1000, event.getTimestamp().getValue()); - assertEquals("Context rank", 1000, context.getRank()); - - // Position trace at event rank 1001 (TS = 1002) - context = fExperiment.seekEvent(new TmfTimestamp(1002, SCALE, 0)); - assertEquals("Context rank", 1001, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 1002, event.getTimestamp().getValue()); - assertEquals("Context rank", 1002, context.getRank()); - - // Position trace at event rank 4500 (TS = 4501) - context = fExperiment.seekEvent(new TmfTimestamp(4501, SCALE, 0)); - assertEquals("Context rank", 4500, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); - assertEquals("Context rank", 4501, context.getRank()); - } - - @Test - public void testSeekTimestampOutOfScope() { - // Position trace at beginning - ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(-1, SCALE, 0)); - assertEquals("Event rank", 0, context.getRank()); - - ITmfEvent event = fExperiment.getNext(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", 1, context.getRank()); - - // Position trace at event passed the end - context = fExperiment.seekEvent(new TmfTimestamp(NB_EVENTS + 1, SCALE, 0)); - event = fExperiment.getNext(context); - assertNull("Event location", event); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - } - - // ------------------------------------------------------------------------ - // seekEvent by location (context rank is undefined) - // ------------------------------------------------------------------------ - - @Test - public void testSeekLocationOnCacheBoundary() { - long cacheSize = fExperiment.getCacheSize(); - - // Position trace at event rank 0 - ITmfContext tmpContext = fExperiment.seekEvent(0); - ITmfContext context = fExperiment.seekEvent(tmpContext.getLocation()); - - ITmfEvent event = fExperiment.getNext(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 2, event.getTimestamp().getValue()); - - // Position trace at event rank 'cacheSize' - tmpContext = fExperiment.seekEvent(cacheSize); - context = fExperiment.seekEvent(tmpContext.getLocation()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", cacheSize + 2, event.getTimestamp().getValue()); - - // Position trace at event rank 4 * 'cacheSize' - tmpContext = fExperiment.seekEvent(4 * cacheSize); - context = fExperiment.seekEvent(tmpContext.getLocation()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 4 * cacheSize + 1, event.getTimestamp().getValue()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 4 * cacheSize + 2, event.getTimestamp().getValue()); - } - - @Test - public void testSeekLocationNotOnCacheBoundary() { - long cacheSize = fExperiment.getCacheSize(); - - // Position trace at event 'cacheSize' - 1 - ITmfContext tmpContext = fExperiment.seekEvent(cacheSize - 1); - ITmfContext context = fExperiment.seekEvent(tmpContext.getLocation()); - - ITmfEvent event = fExperiment.getNext(context); - assertEquals("Event timestamp", cacheSize, event.getTimestamp().getValue()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); - - // Position trace at event rank 2 * 'cacheSize' - 1 - tmpContext = fExperiment.seekEvent(2 * cacheSize - 1); - context = fExperiment.seekEvent(tmpContext.getLocation()); - context = fExperiment.seekEvent(2 * cacheSize - 1); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 2 * cacheSize, event.getTimestamp().getValue()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 2 * cacheSize + 1, event.getTimestamp().getValue()); - - // Position trace at event rank 4500 - tmpContext = fExperiment.seekEvent(4500); - context = fExperiment.seekEvent(tmpContext.getLocation()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 4502, event.getTimestamp().getValue()); - } - - @Test - public void testSeekLocationOutOfScope() { - // Position trace at beginning - ITmfContext context = fExperiment.seekEvent((ITmfLocation) null); - - ITmfEvent event = fExperiment.getNext(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - } - - // ------------------------------------------------------------------------ - // getNext - updates the context - // ------------------------------------------------------------------------ - - private static void validateContextRanks(ITmfContext context) { - assertTrue("Experiment context type", context instanceof TmfExperimentContext); - TmfExperimentContext ctx = (TmfExperimentContext) context; - - int nbTraces = ctx.getNbTraces(); - - // expRank = sum(trace ranks) - nbTraces + 1 (if lastTraceRead != NO_TRACE) - long expRank = -nbTraces + ((ctx.getLastTrace() != TmfExperimentContext.NO_TRACE) ? 1 : 0); - for (int i = 0; i < nbTraces; i++) { - ITmfContext subContext = ctx.getContext(i); - assertNotNull(subContext); - long rank = subContext.getRank(); - if (rank == -1) { - expRank = -1; - break; - } - expRank += rank; - } - assertEquals("Experiment context rank", expRank, ctx.getRank()); - } - - @Test - public void testGetNextAfteSeekingOnTS_1() { - - final long INITIAL_TS = 1; - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 1) - final ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(INITIAL_TS, SCALE, 0)); - - validateContextRanks(context); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fExperiment.getNext(context); - assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + i, context.getRank()); - } - - // Make sure we stay positioned - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); - - validateContextRanks(context); - } - - @Test - public void testGetNextAfteSeekingOnTS_2() { - final long INITIAL_TS = 2; - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 2) - final ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(INITIAL_TS, SCALE, 0)); - - validateContextRanks(context); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fExperiment.getNext(context); - assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + i, context.getRank()); - } - - // Make sure we stay positioned - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); - - validateContextRanks(context); - } - - @Test - public void testGetNextAfteSeekingOnTS_3() { - - final long INITIAL_TS = 500; - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 500) - final ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(INITIAL_TS, SCALE, 0)); - - validateContextRanks(context); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fExperiment.getNext(context); - assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + i, context.getRank()); - } - - // Make sure we stay positioned - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); - - validateContextRanks(context); - } - - @Test - public void testGetNextAfterSeekingOnRank_1() { - final long INITIAL_RANK = 0L; - final int NB_READS = 20; - - // On lower bound, returns the first event (rank = 0) - final ITmfContext context = fExperiment.seekEvent(INITIAL_RANK); - - validateContextRanks(context); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fExperiment.getNext(context); - assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); - } - - // Make sure we stay positioned - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); - - validateContextRanks(context); - } - - @Test - public void testGetNextAfterSeekingOnRank_2() { - final long INITIAL_RANK = 1L; - final int NB_READS = 20; - - // On lower bound, returns the first event (rank = 0) - final ITmfContext context = fExperiment.seekEvent(INITIAL_RANK); - - validateContextRanks(context); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fExperiment.getNext(context); - assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); - } - - // Make sure we stay positioned - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); - - validateContextRanks(context); - } - - @Test - public void testGetNextAfterSeekingOnRank_3() { - final long INITIAL_RANK = 500L; - final int NB_READS = 20; - - // On lower bound, returns the first event (rank = 0) - final ITmfContext context = fExperiment.seekEvent(INITIAL_RANK); - - validateContextRanks(context); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fExperiment.getNext(context); - assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); - } - - // Make sure we stay positioned - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); - - validateContextRanks(context); - } - - @Test - public void testGetNextAfterSeekingOnLocation_1() { - final ITmfLocation INITIAL_LOC = null; - final long INITIAL_TS = 1; - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 1) - final ITmfContext context = fExperiment.seekEvent(INITIAL_LOC); - - validateContextRanks(context); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fExperiment.getNext(context); - assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + i, context.getRank()); - } - - // Make sure we stay positioned - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); - - validateContextRanks(context); - } - - @Test - public void testGetNextAfterSeekingOnLocation_2() { - final ITmfLocation INITIAL_LOC = fExperiment.seekEvent(1L).getLocation(); - final long INITIAL_TS = 2; - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 2) - final ITmfContext context = fExperiment.seekEvent(INITIAL_LOC); - - validateContextRanks(context); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fExperiment.getNext(context); - assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); - } - - // Make sure we stay positioned - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); - - validateContextRanks(context); - } - - @Test - public void testGetNextAfterSeekingOnLocation_3() { - final ITmfLocation INITIAL_LOC = fExperiment.seekEvent(500L).getLocation(); - final long INITIAL_TS = 501; - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 501) - final ITmfContext context = fExperiment.seekEvent(INITIAL_LOC); - - validateContextRanks(context); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fExperiment.getNext(context); - assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); - } - - // Make sure we stay positioned - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); - - validateContextRanks(context); - } - - @Test - public void testGetNextLocation() { - ITmfContext context1 = fExperiment.seekEvent(0); - fExperiment.getNext(context1); - ITmfLocation location = context1.getLocation(); - ITmfEvent event1 = fExperiment.getNext(context1); - ITmfContext context2 = fExperiment.seekEvent(location); - ITmfEvent event2 = fExperiment.getNext(context2); - assertEquals("Event timestamp", event1.getTimestamp().getValue(), event2.getTimestamp().getValue()); - } - - @Test - public void testGetNextEndLocation() { - ITmfContext context1 = fExperiment.seekEvent(fExperiment.getNbEvents() - 1); - fExperiment.getNext(context1); - ITmfLocation location = context1.getLocation(); - ITmfContext context2 = fExperiment.seekEvent(location); - ITmfEvent event = fExperiment.getNext(context2); - assertNull("Event", event); - } - - // ------------------------------------------------------------------------ - // processRequest - // ------------------------------------------------------------------------ - - @Test - public void testProcessRequestForNbEvents() throws InterruptedException { - final int nbEvents = 1000; - final Vector requestedEvents = new Vector<>(); - - final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, - range, 0, nbEvents, ExecutionType.FOREGROUND) { - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - requestedEvents.add(event); - } - }; - fExperiment.sendRequest(request); - request.waitForCompletion(); - - assertEquals("nbEvents", nbEvents, requestedEvents.size()); - assertTrue("isCompleted", request.isCompleted()); - assertFalse("isCancelled", request.isCancelled()); - - // Ensure that we have distinct events. - // Don't go overboard: we are not validating the stub! - for (int i = 0; i < nbEvents; i++) { - assertEquals("Distinct events", i+1, requestedEvents.get(i).getTimestamp().getValue()); - } - } - - @Test - public void testProcessRequestForAllEvents() throws InterruptedException { - final int nbEvents = ITmfEventRequest.ALL_DATA; - final Vector requestedEvents = new Vector<>(); - final long nbExpectedEvents = NB_EVENTS; - - final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, - range, 0, nbEvents, ExecutionType.FOREGROUND) { - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - requestedEvents.add(event); - } - }; - fExperiment.sendRequest(request); - request.waitForCompletion(); - - assertEquals("nbEvents", nbExpectedEvents, requestedEvents.size()); - assertTrue("isCompleted", request.isCompleted()); - assertFalse("isCancelled", request.isCancelled()); - - // Ensure that we have distinct events. - // Don't go overboard: we are not validating the stub! - for (int i = 0; i < nbExpectedEvents; i++) { - assertEquals("Distinct events", i+1, requestedEvents.get(i).getTimestamp().getValue()); - } - } - - // ------------------------------------------------------------------------ - // cancel - // ------------------------------------------------------------------------ - - @Test - public void testCancel() throws InterruptedException { - final int nbEvents = NB_EVENTS; - final int limit = BLOCK_SIZE; - final Vector requestedEvents = new Vector<>(); - - final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, - range, 0, nbEvents, ExecutionType.FOREGROUND) { - int nbRead = 0; - - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - requestedEvents.add(event); - if (++nbRead == limit) { - cancel(); - } - } - - @Override - public void handleCancel() { - if (requestedEvents.size() < limit) { - System.out.println("aie"); - } - } - }; - fExperiment.sendRequest(request); - request.waitForCompletion(); - - assertEquals("nbEvents", limit, requestedEvents.size()); - assertTrue("isCompleted", request.isCompleted()); - assertTrue("isCancelled", request.isCancelled()); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfMultiTraceExperimentTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfMultiTraceExperimentTest.java deleted file mode 100644 index f4731c0eba..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfMultiTraceExperimentTest.java +++ /dev/null @@ -1,814 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Adjusted for new Trace Model - * Alexandre Montplaisir - Port to JUnit4 - * Patrick Tasse - Fix for concurrency - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.Vector; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.linuxtools.internal.tmf.core.trace.TmfExperimentContext; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest.ExecutionType; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.tests.TmfCoreTestPlugin; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfExperimentStub; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Test suite for the TmfExperiment class (multiple traces). - */ -@SuppressWarnings("javadoc") -public class TmfMultiTraceExperimentTest { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private static final long DEFAULT_INITIAL_OFFSET_VALUE = (1L * 100 * 1000 * 1000); // .1sec - private static final String EXPERIMENT = "MyExperiment"; - private static int NB_EVENTS = 20000; - private static int BLOCK_SIZE = 1000; - - private static TmfExperimentStub fExperiment; - - private static byte SCALE = (byte) -3; - - // ------------------------------------------------------------------------ - // Housekeeping - // ------------------------------------------------------------------------ - - @BeforeClass - public static void setUp() { - ITmfTrace[] traces = setupTraces(); - fExperiment = new TmfExperimentStub(EXPERIMENT, traces, BLOCK_SIZE); - fExperiment.getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, true); - } - - @AfterClass - public static void tearDown() { - fExperiment.dispose(); - } - - private static ITmfTrace[] setupTraces() { - try { - ITmfTrace[] traces = new ITmfTrace[2]; - - URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TmfTestTrace.O_TEST_10K.getFullPath()), null); - File test = new File(FileLocator.toFileURL(location).toURI()); - final TmfTraceStub trace1 = new TmfTraceStub(test.getPath(), 0, true, null); - traces[0] = trace1; - - location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TmfTestTrace.E_TEST_10K.getFullPath()), null); - test = new File(FileLocator.toFileURL(location).toURI()); - final TmfTraceStub trace2 = new TmfTraceStub(test.getPath(), 0, true, null); - traces[1] = trace2; - - return traces; - } catch (final TmfTraceException e) { - e.printStackTrace(); - } catch (final URISyntaxException e) { - e.printStackTrace(); - } catch (final IOException e) { - e.printStackTrace(); - } - return new ITmfTrace[0]; - } - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - @Test - public void testBasicTmfExperimentConstructor() { - assertEquals("GetId", EXPERIMENT, fExperiment.getName()); - assertEquals("GetNbEvents", NB_EVENTS, fExperiment.getNbEvents()); - - final TmfTimeRange timeRange = fExperiment.getTimeRange(); - assertEquals("getStartTime", 1, timeRange.getStartTime().getValue()); - assertEquals("getEndTime", NB_EVENTS, timeRange.getEndTime().getValue()); - - TmfTimestamp initRange = new TmfTimestamp(DEFAULT_INITIAL_OFFSET_VALUE, ITmfTimestamp.NANOSECOND_SCALE); - assertEquals("getInitialRangeOffset", initRange, fExperiment.getInitialRangeOffset()); - } - - // ------------------------------------------------------------------------ - // seekEvent on rank - // ------------------------------------------------------------------------ - - @Test - public void testSeekRankOnCacheBoundary() { - long cacheSize = fExperiment.getCacheSize(); - - // On lower bound, returns the first event (TS = 1) - ITmfContext context = fExperiment.seekEvent(0); - assertEquals("Context rank", 0, context.getRank()); - - ITmfEvent event = fExperiment.getNext(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Context rank", 1, context.getRank()); - - // Position trace at event rank [cacheSize] - context = fExperiment.seekEvent(cacheSize); - assertEquals("Context rank", cacheSize, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); - assertEquals("Context rank", cacheSize + 1, context.getRank()); - - // Position trace at event rank [4 * cacheSize] - context = fExperiment.seekEvent(4 * cacheSize); - assertEquals("Context rank", 4 * cacheSize, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 4 * cacheSize + 1, event.getTimestamp().getValue()); - assertEquals("Context rank", 4 * cacheSize + 1, context.getRank()); - } - - @Test - public void testSeekRankNotOnCacheBoundary() { - long cacheSize = fExperiment.getCacheSize(); - - // Position trace at event rank 9 - ITmfContext context = fExperiment.seekEvent(9); - assertEquals("Context rank", 9, context.getRank()); - - ITmfEvent event = fExperiment.getNext(context); - assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); - assertEquals("Context rank", 10, context.getRank()); - - // Position trace at event rank [cacheSize - 1] - context = fExperiment.seekEvent(cacheSize - 1); - assertEquals("Context rank", cacheSize - 1, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", cacheSize, event.getTimestamp().getValue()); - assertEquals("Context rank", cacheSize, context.getRank()); - - // Position trace at event rank [cacheSize + 1] - context = fExperiment.seekEvent(cacheSize + 1); - assertEquals("Context rank", cacheSize + 1, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", cacheSize + 2, event.getTimestamp().getValue()); - assertEquals("Context rank", cacheSize + 2, context.getRank()); - - // Position trace at event rank 4500 - context = fExperiment.seekEvent(4500); - assertEquals("Context rank", 4500, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); - assertEquals("Context rank", 4501, context.getRank()); - } - - @Test - public void testSeekRankOutOfScope() { - // Position trace at beginning - ITmfContext context = fExperiment.seekEvent(-1); - assertEquals("Event rank", 0, context.getRank()); - - ITmfEvent event = fExperiment.getNext(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Context rank", 1, context.getRank()); - - // Position trace at event passed the end - context = fExperiment.seekEvent(NB_EVENTS); - assertEquals("Context rank", NB_EVENTS, context.getRank()); - - event = fExperiment.getNext(context); - assertNull("Event", event); - assertEquals("Context rank", NB_EVENTS, context.getRank()); - } - - // ------------------------------------------------------------------------ - // seekEvent on timestamp - // ------------------------------------------------------------------------ - - @Test - public void testSeekTimestampOnCacheBoundary() { - long cacheSize = fExperiment.getCacheSize(); - - // Position trace at event rank 0 - ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(1, SCALE, 0)); - assertEquals("Context rank", 0, context.getRank()); - - ITmfEvent event = fExperiment.getNext(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Context rank", 1, context.getRank()); - - // Position trace at event rank [cacheSize] - context = fExperiment.seekEvent(new TmfTimestamp(cacheSize + 1, SCALE, 0)); - assertEquals("Event rank", cacheSize, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); - assertEquals("Context rank", cacheSize + 1, context.getRank()); - - // Position trace at event rank [4 * cacheSize] - context = fExperiment.seekEvent(new TmfTimestamp(4 * cacheSize + 1, SCALE, 0)); - assertEquals("Context rank", 4 * cacheSize, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 4 * cacheSize + 1, event.getTimestamp().getValue()); - assertEquals("Context rank", 4 * cacheSize + 1, context.getRank()); - } - - @Test - public void testSeekTimestampNotOnCacheBoundary() { - // Position trace at event rank 1 (TS = 2) - ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(2, SCALE, 0)); - assertEquals("Context rank", 1, context.getRank()); - - ITmfEvent event = fExperiment.getNext(context); - assertEquals("Event timestamp", 2, event.getTimestamp().getValue()); - assertEquals("Context rank", 2, context.getRank()); - - // Position trace at event rank 9 (TS = 10) - context = fExperiment.seekEvent(new TmfTimestamp(10, SCALE, 0)); - assertEquals("Context rank", 9, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); - assertEquals("Context rank", 10, context.getRank()); - - // Position trace at event rank 999 (TS = 1000) - context = fExperiment.seekEvent(new TmfTimestamp(1000, SCALE, 0)); - assertEquals("Context rank", 999, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 1000, event.getTimestamp().getValue()); - assertEquals("Context rank", 1000, context.getRank()); - - // Position trace at event rank 1001 (TS = 1002) - context = fExperiment.seekEvent(new TmfTimestamp(1002, SCALE, 0)); - assertEquals("Context rank", 1001, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 1002, event.getTimestamp().getValue()); - assertEquals("Context rank", 1002, context.getRank()); - - // Position trace at event rank 4500 (TS = 4501) - context = fExperiment.seekEvent(new TmfTimestamp(4501, SCALE, 0)); - assertEquals("Context rank", 4500, context.getRank()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); - assertEquals("Context rank", 4501, context.getRank()); - } - - @Test - public void testSeekTimestampOutOfScope() { - // Position trace at beginning - ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(-1, SCALE, 0)); - assertEquals("Event rank", 0, context.getRank()); - - ITmfEvent event = fExperiment.getNext(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", 1, context.getRank()); - - // Position trace at event passed the end - context = fExperiment.seekEvent(new TmfTimestamp(NB_EVENTS + 1, SCALE, 0)); - event = fExperiment.getNext(context); - assertNull("Event location", event); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - } - - // ------------------------------------------------------------------------ - // seekEvent by location (context rank is undefined) - // ------------------------------------------------------------------------ - - @Test - public void testSeekLocationOnCacheBoundary() { - long cacheSize = fExperiment.getCacheSize(); - - // Position trace at event rank 0 - ITmfContext tmpContext = fExperiment.seekEvent(0); - ITmfContext context = fExperiment.seekEvent(tmpContext.getLocation()); - - ITmfEvent event = fExperiment.getNext(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 2, event.getTimestamp().getValue()); - - // Position trace at event rank 'cacheSize' - tmpContext = fExperiment.seekEvent(cacheSize); - context = fExperiment.seekEvent(tmpContext.getLocation()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", cacheSize + 2, event.getTimestamp().getValue()); - - // Position trace at event rank 4 * 'cacheSize' - tmpContext = fExperiment.seekEvent(4 * cacheSize); - context = fExperiment.seekEvent(tmpContext.getLocation()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 4 * cacheSize + 1, event.getTimestamp().getValue()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 4 * cacheSize + 2, event.getTimestamp().getValue()); - } - - @Test - public void testSeekLocationNotOnCacheBoundary() { - long cacheSize = fExperiment.getCacheSize(); - - // Position trace at event 'cacheSize' - 1 - ITmfContext tmpContext = fExperiment.seekEvent(cacheSize - 1); - ITmfContext context = fExperiment.seekEvent(tmpContext.getLocation()); - - ITmfEvent event = fExperiment.getNext(context); - assertEquals("Event timestamp", cacheSize, event.getTimestamp().getValue()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); - - // Position trace at event rank 2 * 'cacheSize' - 1 - tmpContext = fExperiment.seekEvent(2 * cacheSize - 1); - context = fExperiment.seekEvent(tmpContext.getLocation()); - context = fExperiment.seekEvent(2 * cacheSize - 1); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 2 * cacheSize, event.getTimestamp().getValue()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 2 * cacheSize + 1, event.getTimestamp().getValue()); - - // Position trace at event rank 4500 - tmpContext = fExperiment.seekEvent(4500); - context = fExperiment.seekEvent(tmpContext.getLocation()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); - - event = fExperiment.getNext(context); - assertEquals("Event timestamp", 4502, event.getTimestamp().getValue()); - } - - @Test - public void testSeekLocationOutOfScope() { - // Position trace at beginning - ITmfContext context = fExperiment.seekEvent((ITmfLocation) null); - - ITmfEvent event = fExperiment.getNext(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - } - - // ------------------------------------------------------------------------ - // getNext - updates the context - // ------------------------------------------------------------------------ - - private static void validateContextRanks(ITmfContext context) { - assertTrue("Experiment context type", context instanceof TmfExperimentContext); - TmfExperimentContext ctx = (TmfExperimentContext) context; - - int nbTraces = ctx.getNbTraces(); - - // expRank = sum(trace ranks) - nbTraces + 1 (if lastTraceRead != NO_TRACE) - long expRank = -nbTraces + ((ctx.getLastTrace() != TmfExperimentContext.NO_TRACE) ? 1 : 0); - for (int i = 0; i < nbTraces; i++) { - ITmfContext subContext = ctx.getContext(i); - assertNotNull(subContext); - long rank = subContext.getRank(); - if (rank == -1) { - expRank = -1; - break; - } - expRank += rank; - } - assertEquals("Experiment context rank", expRank, ctx.getRank()); - } - - @Test - public void testGetNextAfteSeekingOnTS_1() { - final long INITIAL_TS = 1; - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 1) - final ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(INITIAL_TS, SCALE, 0)); - - validateContextRanks(context); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fExperiment.getNext(context); - assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + i, context.getRank()); - } - - // Make sure we stay positioned - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); - - validateContextRanks(context); - } - - @Test - public void testGetNextAfteSeekingOnTS_2() { - final long INITIAL_TS = 2; - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 2) - final ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(INITIAL_TS, SCALE, 0)); - - validateContextRanks(context); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fExperiment.getNext(context); - assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + i, context.getRank()); - } - - // Make sure we stay positioned - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); - - validateContextRanks(context); - } - - @Test - public void testGetNextAfteSeekingOnTS_3() { - final long INITIAL_TS = 500; - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 500) - final ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(INITIAL_TS, SCALE, 0)); - - validateContextRanks(context); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fExperiment.getNext(context); - assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + i, context.getRank()); - } - - // Make sure we stay positioned - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); - - validateContextRanks(context); - } - - @Test - public void testGetNextAfterSeekingOnRank_1() { - final long INITIAL_RANK = 0L; - final int NB_READS = 20; - - // On lower bound, returns the first event (rank = 0) - final ITmfContext context = fExperiment.seekEvent(INITIAL_RANK); - - validateContextRanks(context); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fExperiment.getNext(context); - assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); - } - - // Make sure we stay positioned - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); - - validateContextRanks(context); - } - - @Test - public void testGetNextAfterSeekingOnRank_2() { - final long INITIAL_RANK = 1L; - final int NB_READS = 20; - - // On lower bound, returns the first event (rank = 0) - final ITmfContext context = fExperiment.seekEvent(INITIAL_RANK); - - validateContextRanks(context); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fExperiment.getNext(context); - assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); - } - - // Make sure we stay positioned - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); - - validateContextRanks(context); - } - - @Test - public void testGetNextAfterSeekingOnRank_3() { - final long INITIAL_RANK = 500L; - final int NB_READS = 20; - - // On lower bound, returns the first event (rank = 0) - final ITmfContext context = fExperiment.seekEvent(INITIAL_RANK); - - validateContextRanks(context); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fExperiment.getNext(context); - assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); - } - - // Make sure we stay positioned - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); - - validateContextRanks(context); - } - - @Test - public void testGetNextAfterSeekingOnLocation_1() { - final ITmfLocation INITIAL_LOC = null; - final long INITIAL_TS = 1; - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 1) - final ITmfContext context = fExperiment.seekEvent(INITIAL_LOC); - - validateContextRanks(context); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fExperiment.getNext(context); - assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + i, context.getRank()); - } - - // Make sure we stay positioned - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); - - validateContextRanks(context); - } - - @Test - public void testGetNextAfterSeekingOnLocation_2() { - final ITmfLocation INITIAL_LOC = fExperiment.seekEvent(1L).getLocation(); - final long INITIAL_TS = 2; - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 2) - final ITmfContext context = fExperiment.seekEvent(INITIAL_LOC); - - validateContextRanks(context); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fExperiment.getNext(context); - assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); - } - - // Make sure we stay positioned - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); - - validateContextRanks(context); - } - - @Test - public void testGetNextAfterSeekingOnLocation_3() { - final ITmfLocation INITIAL_LOC = fExperiment.seekEvent(500L).getLocation(); - final long INITIAL_TS = 501; - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 501) - final ITmfContext context = fExperiment.seekEvent(INITIAL_LOC); - - validateContextRanks(context); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fExperiment.getNext(context); - assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); - } - - // Make sure we stay positioned - event = fExperiment.parseEvent(context); - assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); - - validateContextRanks(context); - } - - @Test - public void testGetNextLocation() { - ITmfContext context1 = fExperiment.seekEvent(0); - fExperiment.getNext(context1); - ITmfLocation location = context1.getLocation(); - ITmfEvent event1 = fExperiment.getNext(context1); - ITmfContext context2 = fExperiment.seekEvent(location); - ITmfEvent event2 = fExperiment.getNext(context2); - assertEquals("Event timestamp", event1.getTimestamp().getValue(), event2.getTimestamp().getValue()); - } - - @Test - public void testGetNextEndLocation() { - ITmfContext context1 = fExperiment.seekEvent(fExperiment.getNbEvents() - 1); - fExperiment.getNext(context1); - ITmfLocation location = context1.getLocation(); - ITmfContext context2 = fExperiment.seekEvent(location); - ITmfEvent event = fExperiment.getNext(context2); - assertNull("Event", event); - } - - // ------------------------------------------------------------------------ - // processRequest - // ------------------------------------------------------------------------ - - @Test - public void testProcessRequestForNbEvents() throws InterruptedException { - final int nbEvents = 1000; - final Vector requestedEvents = new Vector<>(); - - final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, - range, 0, nbEvents, ExecutionType.FOREGROUND) { - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - requestedEvents.add(event); - } - }; - fExperiment.sendRequest(request); - request.waitForCompletion(); - - assertEquals("nbEvents", nbEvents, requestedEvents.size()); - assertTrue("isCompleted", request.isCompleted()); - assertFalse("isCancelled", request.isCancelled()); - - // Ensure that we have distinct events. - // Don't go overboard: we are not validating the stub! - for (int i = 0; i < nbEvents; i++) { - assertEquals("Distinct events", i+1, requestedEvents.get(i).getTimestamp().getValue()); - } - } - - @Test - public void testProcessRequestForAllEvents() throws InterruptedException { - final int nbEvents = ITmfEventRequest.ALL_DATA; - final Vector requestedEvents = new Vector<>(); - final long nbExpectedEvents = NB_EVENTS; - - final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, - range, 0, nbEvents, ExecutionType.FOREGROUND) { - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - requestedEvents.add(event); - } - }; - fExperiment.sendRequest(request); - request.waitForCompletion(); - - assertEquals("nbEvents", nbExpectedEvents, requestedEvents.size()); - assertTrue("isCompleted", request.isCompleted()); - assertFalse("isCancelled", request.isCancelled()); - - // Ensure that we have distinct events. - // Don't go overboard: we are not validating the stub! - for (int i = 0; i < nbExpectedEvents; i++) { - assertEquals("Distinct events", i+1, requestedEvents.get(i).getTimestamp().getValue()); - } - } - - // ------------------------------------------------------------------------ - // cancel - // ------------------------------------------------------------------------ - - @Test - public void testCancel() throws InterruptedException { - final int nbEvents = NB_EVENTS; - final int limit = BLOCK_SIZE; - final Vector requestedEvents = new Vector<>(); - - final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, - range, 0, nbEvents, ExecutionType.FOREGROUND) { - int nbRead = 0; - - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - requestedEvents.add(event); - if (++nbRead == limit) { - cancel(); - } - } - }; - fExperiment.sendRequest(request); - request.waitForCompletion(); - - assertEquals("nbEvents", limit, requestedEvents.size()); - assertTrue("isCompleted", request.isCompleted()); - assertTrue("isCancelled", request.isCancelled()); - } - - // ------------------------------------------------------------------------ - // getTimestamp - // ------------------------------------------------------------------------ - - @Test - public void testGetTimestamp() { - assertEquals("getTimestamp", new TmfTimestamp( 1, (byte) -3), fExperiment.getTimestamp( 0)); - assertEquals("getTimestamp", new TmfTimestamp( 2, (byte) -3), fExperiment.getTimestamp( 1)); - assertEquals("getTimestamp", new TmfTimestamp( 11, (byte) -3), fExperiment.getTimestamp( 10)); - assertEquals("getTimestamp", new TmfTimestamp( 101, (byte) -3), fExperiment.getTimestamp( 100)); - assertEquals("getTimestamp", new TmfTimestamp( 1001, (byte) -3), fExperiment.getTimestamp( 1000)); - assertEquals("getTimestamp", new TmfTimestamp( 2001, (byte) -3), fExperiment.getTimestamp( 2000)); - assertEquals("getTimestamp", new TmfTimestamp( 2501, (byte) -3), fExperiment.getTimestamp( 2500)); - assertEquals("getTimestamp", new TmfTimestamp(10000, (byte) -3), fExperiment.getTimestamp( 9999)); - assertEquals("getTimestamp", new TmfTimestamp(20000, (byte) -3), fExperiment.getTimestamp(19999)); - assertNull("getTimestamp", fExperiment.getTimestamp(20000)); - } - - // ------------------------------------------------------------------------ - // getInitialRangeOffset, getCurrentRange, getCurrentTime - // ------------------------------------------------------------------------ - - @Test - public void testDefaultCurrentTimeValues() { - ITmfTrace[] traces = setupTraces(); - TmfExperimentStub exp = new TmfExperimentStub(EXPERIMENT, traces, BLOCK_SIZE); - - // verify initial values - TmfTimestamp initRange = new TmfTimestamp(DEFAULT_INITIAL_OFFSET_VALUE, ITmfTimestamp.NANOSECOND_SCALE); - assertEquals("getInitialRangeOffset", initRange, exp.getInitialRangeOffset()); - - exp.dispose(); - } - - @Test - public void testInitialRangeOffset() { - ITmfTrace[] traces = setupTraces(); - ((TmfTraceStub) traces[0]).setInitialRangeOffset(new TmfTimestamp(5, ITmfTimestamp.MILLISECOND_SCALE)); - ((TmfTraceStub) traces[1]).setInitialRangeOffset(new TmfTimestamp(2, ITmfTimestamp.MILLISECOND_SCALE)); - TmfExperimentStub exp = new TmfExperimentStub(EXPERIMENT, traces, BLOCK_SIZE); - - TmfTimestamp initRange = new TmfTimestamp(2, ITmfTimestamp.MILLISECOND_SCALE); - assertEquals("getInitialRangeOffset", initRange, exp.getInitialRangeOffset()); - - exp.dispose(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfTraceTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfTraceTest.java deleted file mode 100644 index fa46b548a8..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfTraceTest.java +++ /dev/null @@ -1,1389 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Adapted for TMF Trace Model 1.0 - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.Vector; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.linuxtools.internal.tmf.core.component.TmfProviderManager; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule; -import org.eclipse.linuxtools.tmf.core.component.ITmfEventProvider; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest.ExecutionType; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.tests.TmfCoreTestPlugin; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfContext; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; -import org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestAnalysis; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; -import org.junit.rules.Timeout; - -/** - * Test suite for the TmfTrace class. - */ -@SuppressWarnings("javadoc") -public class TmfTraceTest { - - /** Time-out tests after 20 seconds */ - @Rule - public TestRule globalTimeout= new Timeout(20000); - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - private static final TmfTestTrace TEST_TRACE = TmfTestTrace.A_TEST_10K; - private static final long DEFAULT_INITIAL_OFFSET_VALUE = (1L * 100 * 1000 * 1000); // .1sec - private static final int NB_EVENTS = 10000; - private TmfTraceStub fTrace = null; - - private static int SCALE = -3; - - // ------------------------------------------------------------------------ - // Housekeeping - // ------------------------------------------------------------------------ - - @Before - public void setUp() { - try { - final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE.getFullPath()), null); - final File test = new File(FileLocator.toFileURL(location).toURI()); - fTrace = new TmfTraceStub(test.toURI().getPath(), ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, false, null); - TmfSignalManager.deregister(fTrace); - fTrace.indexTrace(true); - } catch (final TmfTraceException e) { - e.printStackTrace(); - } catch (final URISyntaxException e) { - e.printStackTrace(); - } catch (final IOException e) { - e.printStackTrace(); - } - } - - @After - public void tearDown() { - fTrace.dispose(); - fTrace = null; - } - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - @Test - public void testFullConstructor() throws TmfTraceException { - try { - final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE.getFullPath()), null); - File testfile = new File(FileLocator.toFileURL(location).toURI()); - TmfTraceStub trace = new TmfTraceStub(testfile.toURI().getPath(), ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, false, null); - trace.indexTrace(true); - - assertEquals("getType", ITmfEvent.class, trace.getType()); - assertNull("getResource", trace.getResource()); - assertEquals("getPath", testfile.toURI().getPath(), trace.getPath()); - assertEquals("getCacheSize", ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, trace.getCacheSize()); - assertEquals("getStreamingInterval", 0, trace.getStreamingInterval()); - assertEquals("getName", TEST_TRACE.getPath(), trace.getName()); - - assertEquals("getNbEvents", NB_EVENTS, trace.getNbEvents()); - assertEquals("getRange-start", 1, trace.getTimeRange().getStartTime().getValue()); - assertEquals("getRange-end", NB_EVENTS, trace.getTimeRange().getEndTime().getValue()); - assertEquals("getStartTime", 1, trace.getStartTime().getValue()); - assertEquals("getEndTime", NB_EVENTS, trace.getEndTime().getValue()); - - } catch (final URISyntaxException e) { - fail("URISyntaxException"); - } catch (final IOException e) { - fail("IOException"); - } - } - - @Test - public void testLiveTraceConstructor() throws TmfTraceException { - final long interval = 100; - try { - final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE.getFullPath()), null); - File testfile = new File(FileLocator.toFileURL(location).toURI()); - TmfTraceStub trace = new TmfTraceStub(testfile.toURI().getPath(), ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, interval); - trace.indexTrace(true); - - assertEquals("getType", ITmfEvent.class, trace.getType()); - assertNull("getResource", trace.getResource()); - assertEquals("getPath", testfile.toURI().getPath(), trace.getPath()); - assertEquals("getCacheSize", ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, trace.getCacheSize()); - assertEquals("getStreamingInterval", interval, trace.getStreamingInterval()); - assertEquals("getName", TEST_TRACE.getPath(), trace.getName()); - - assertEquals("getNbEvents", NB_EVENTS, trace.getNbEvents()); - assertEquals("getRange-start", 1, trace.getTimeRange().getStartTime().getValue()); - assertEquals("getRange-end", NB_EVENTS, trace.getTimeRange().getEndTime().getValue()); - assertEquals("getStartTime", 1, trace.getStartTime().getValue()); - assertEquals("getEndTime", NB_EVENTS, trace.getEndTime().getValue()); - - } catch (final URISyntaxException e) { - fail("URISyntaxException"); - } catch (final IOException e) { - fail("IOException"); - } - } - - @Test - public void testCopyConstructor() throws TmfTraceException { - try { - final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE.getFullPath()), null); - File testfile = new File(FileLocator.toFileURL(location).toURI()); - TmfTraceStub original = new TmfTraceStub(testfile.toURI().getPath(), ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, false, null); - TmfTraceStub trace = new TmfTraceStub(original); - trace.indexTrace(true); - - assertEquals("getType", ITmfEvent.class, trace.getType()); - assertNull("getResource", trace.getResource()); - assertEquals("getPath", testfile.toURI().getPath(), trace.getPath()); - assertEquals("getCacheSize", ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, trace.getCacheSize()); - assertEquals("getStreamingInterval", 0, trace.getStreamingInterval()); - assertEquals("getName", TEST_TRACE.getPath(), trace.getName()); - - assertEquals("getNbEvents", NB_EVENTS, trace.getNbEvents()); - assertEquals("getRange-start", 1, trace.getTimeRange().getStartTime().getValue()); - assertEquals("getRange-end", NB_EVENTS, trace.getTimeRange().getEndTime().getValue()); - assertEquals("getStartTime", 1, trace.getStartTime().getValue()); - assertEquals("getEndTime", NB_EVENTS, trace.getEndTime().getValue()); - - } catch (final URISyntaxException e) { - fail("URISyntaxException"); - } catch (final IOException e) { - fail("IOException"); - } - - // Test the copy of a null trace - try { - new TmfTraceStub((TmfTraceStub) null); - fail("Missing exception"); - } catch (final IllegalArgumentException e) { - // test passed - } catch (final Exception e) { - fail("Unexpected exception"); - } - } - - // ------------------------------------------------------------------------ - // Trace initialization - // ------------------------------------------------------------------------ - - @Test - public void testInitializeNullPath() { - // Instantiate an "empty" trace - final TmfTraceStub trace = new TmfTraceStub(); - - try { - trace.initialize(null, null, ITmfEvent.class); - fail("TmfTrace.initialize() - no exception thrown"); - } catch (TmfTraceException e) { - // Success - } catch (Exception e) { - fail("TmfTrace.initialize() - wrong exception thrown"); - } - } - - @Test - public void testInitializeSimplePath() { - // Instantiate an "empty" trace - final TmfTraceStub trace = new TmfTraceStub(); - - // Path == trace name - String path = "TraceName"; - try { - trace.initialize(null, path, ITmfEvent.class); - } catch (Exception e) { - fail("TmfTrace.initialize() - Exception thrown"); - } - - assertEquals("getType", ITmfEvent.class, trace.getType()); - assertNull ("getResource", trace.getResource()); - assertEquals("getPath", path, trace.getPath()); - assertEquals("getCacheSize", ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, trace.getCacheSize()); - assertEquals("getStreamingInterval", 0, trace.getStreamingInterval()); - assertEquals("getName", path, trace.getName()); - - assertEquals("getNbEvents", 0, trace.getNbEvents()); - assertEquals("getRange-start", Long.MIN_VALUE, trace.getTimeRange().getStartTime().getValue()); - assertEquals("getRange-end", Long.MIN_VALUE, trace.getTimeRange().getEndTime().getValue()); - assertEquals("getStartTime", Long.MIN_VALUE, trace.getStartTime().getValue()); - assertEquals("getEndTime", Long.MIN_VALUE, trace.getEndTime().getValue()); - } - - @Test - public void testInitializeNormalPath() { - // Instantiate an "empty" trace - final TmfTraceStub trace = new TmfTraceStub(); - - // Path == trace name - String name = "TraceName"; - String path = "/my/trace/path/" + name; - try { - trace.initialize(null, path, ITmfEvent.class); - } catch (Exception e) { - fail("TmfTrace.initialize() - Exception thrown"); - } - - assertEquals("getType", ITmfEvent.class, trace.getType()); - assertNull ("getResource", trace.getResource()); - assertEquals("getPath", path, trace.getPath()); - assertEquals("getCacheSize", ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, trace.getCacheSize()); - assertEquals("getStreamingInterval", 0, trace.getStreamingInterval()); - assertEquals("getName", name, trace.getName()); - - assertEquals("getNbEvents", 0, trace.getNbEvents()); - assertEquals("getRange-start", Long.MIN_VALUE, trace.getTimeRange().getStartTime().getValue()); - assertEquals("getRange-end", Long.MIN_VALUE, trace.getTimeRange().getEndTime().getValue()); - assertEquals("getStartTime", Long.MIN_VALUE, trace.getStartTime().getValue()); - assertEquals("getEndTime", Long.MIN_VALUE, trace.getEndTime().getValue()); - } - - @Test - public void testInitTrace() throws URISyntaxException, IOException, TmfTraceException, InterruptedException { - // Instantiate an "empty" trace - final TmfTraceStub trace = new TmfTraceStub(); - - assertNull ("getType", trace.getType()); - assertNull ("getResource", trace.getResource()); - assertEquals("getCacheSize", ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, trace.getCacheSize()); - assertEquals("getStreamingInterval", 0, trace.getStreamingInterval()); - assertEquals("getName", "", trace.getName()); - - assertEquals("getNbEvents", 0, trace.getNbEvents()); - assertEquals("getRange-start", Long.MIN_VALUE, trace.getTimeRange().getStartTime().getValue()); - assertEquals("getRange-end", Long.MIN_VALUE, trace.getTimeRange().getEndTime().getValue()); - assertEquals("getStartTime", Long.MIN_VALUE, trace.getStartTime().getValue()); - assertEquals("getEndTime", Long.MIN_VALUE, trace.getEndTime().getValue()); - - // Validate - final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE.getFullPath()), null); - final File testfile = new File(FileLocator.toFileURL(location).toURI()); - assertTrue("validate", trace.validate(null, testfile.getPath()).isOK()); - - // InitTrace and wait for indexing completion... - trace.initTrace(null, testfile.toURI().getPath(), ITmfEvent.class); - trace.indexTrace(true); - int nbSecs = 0; - while (trace.getNbEvents() < NB_EVENTS && nbSecs < 10) { - Thread.sleep(1000); - nbSecs++; - } - if (trace.getNbEvents() < NB_EVENTS) { - fail("indexing"); - } - - assertEquals("getType", ITmfEvent.class, trace.getType()); - assertNull ("getResource", trace.getResource()); - assertEquals("getCacheSize", ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, trace.getCacheSize()); - assertEquals("getStreamingInterval", 0, trace.getStreamingInterval()); - assertEquals("getName", TEST_TRACE.getPath(), trace.getName()); - - assertEquals("getNbEvents", NB_EVENTS, trace.getNbEvents()); - assertEquals("getRange-start", 1, trace.getTimeRange().getStartTime().getValue()); - assertEquals("getRange-end", NB_EVENTS, trace.getTimeRange().getEndTime().getValue()); - assertEquals("getStartTime", 1, trace.getStartTime().getValue()); - assertEquals("getEndTime", NB_EVENTS, trace.getEndTime().getValue()); - } - - // ------------------------------------------------------------------------ - // Set/Get streaming interval - // ------------------------------------------------------------------------ - - @Test - public void testSetStreamingInterval() throws TmfTraceException { - final TmfTraceStub trace = new TmfTraceStub(fTrace); - - long interval = 0; - assertEquals("getStreamingInterval", interval, trace.getStreamingInterval()); - - interval = 100; - trace.setStreamingInterval(interval); - assertEquals("getStreamingInterval", interval, trace.getStreamingInterval()); - - interval = -1; - trace.setStreamingInterval(interval); - assertEquals("getStreamingInterval", 0, trace.getStreamingInterval()); - - interval = 0; - trace.setStreamingInterval(interval); - assertEquals("getStreamingInterval", interval, trace.getStreamingInterval()); - - trace.dispose(); - } - - // ------------------------------------------------------------------------ - // Set/Get time range - // ------------------------------------------------------------------------ - - @Test - public void testSetTimeRange() throws TmfTraceException { - final TmfTraceStub trace = new TmfTraceStub(fTrace); - trace.indexTrace(true); - - assertEquals("getRange-start", 1, trace.getTimeRange().getStartTime().getValue()); - assertEquals("getRange-end", NB_EVENTS, trace.getTimeRange().getEndTime().getValue()); - assertEquals("getStartTime", 1, trace.getStartTime().getValue()); - assertEquals("getEndTime", NB_EVENTS, trace.getEndTime().getValue()); - - trace.setTimeRange(new TmfTimeRange(new TmfTimestamp(100), new TmfTimestamp(200))); - assertEquals("setTimeRange", 100, trace.getTimeRange().getStartTime().getValue()); - assertEquals("setTimeRange", 200, trace.getTimeRange().getEndTime().getValue()); - assertEquals("setTimeRange", 100, trace.getStartTime().getValue()); - assertEquals("setTimeRange", 200, trace.getEndTime().getValue()); - - trace.dispose(); - } - - @Test - public void testSetStartTime() throws TmfTraceException { - final TmfTraceStub trace = new TmfTraceStub(fTrace); - trace.indexTrace(true); - - assertEquals("getRange-start", 1, trace.getTimeRange().getStartTime().getValue()); - assertEquals("getRange-end", NB_EVENTS, trace.getTimeRange().getEndTime().getValue()); - assertEquals("getStartTime", 1, trace.getStartTime().getValue()); - assertEquals("getEndTime", NB_EVENTS, trace.getEndTime().getValue()); - - trace.setStartTime(new TmfTimestamp(100)); - assertEquals("setStartTime", 100, trace.getTimeRange().getStartTime().getValue()); - assertEquals("setStartTime", NB_EVENTS, trace.getTimeRange().getEndTime().getValue()); - assertEquals("setStartTime", 100, trace.getStartTime().getValue()); - assertEquals("setStartTime", NB_EVENTS, trace.getEndTime().getValue()); - - trace.dispose(); - } - - @Test - public void testSetEndTime() throws TmfTraceException { - final TmfTraceStub trace = new TmfTraceStub(fTrace); - trace.indexTrace(true); - - assertEquals("getRange-start", 1, trace.getTimeRange().getStartTime().getValue()); - assertEquals("getRange-end", NB_EVENTS, trace.getTimeRange().getEndTime().getValue()); - assertEquals("getStartTime", 1, trace.getStartTime().getValue()); - assertEquals("getEndTime", NB_EVENTS, trace.getEndTime().getValue()); - - trace.setEndTime(new TmfTimestamp(100)); - assertEquals("setEndTime", 1, trace.getTimeRange().getStartTime().getValue()); - assertEquals("setEndTime", 100, trace.getTimeRange().getEndTime().getValue()); - assertEquals("setEndTime", 1, trace.getStartTime().getValue()); - assertEquals("setEndTime", 100, trace.getEndTime().getValue()); - - trace.dispose(); - } - - @Test - public void testSetNbEvents() throws TmfTraceException { - final TmfTraceStub trace = new TmfTraceStub(fTrace); - trace.indexTrace(true); - - assertEquals("getNbEvents", NB_EVENTS, trace.getNbEvents()); - - trace.setNbEvents(0); - assertEquals("getNbEvents", 0, trace.getNbEvents()); - - trace.setNbEvents(-1); - assertEquals("getNbEvents", 0, trace.getNbEvents()); - - trace.setNbEvents(NB_EVENTS + 1); - assertEquals("getNbEvents", NB_EVENTS + 1, trace.getNbEvents()); - - trace.setNbEvents(NB_EVENTS); - assertEquals("getNbEvents", NB_EVENTS, trace.getNbEvents()); - - trace.dispose(); - } - - // ------------------------------------------------------------------------ - // State system, statistics and modules methods - // ------------------------------------------------------------------------ - - @Test - public void testGetModulesByClass() { - /* There should not be any modules at this point */ - Iterable modules = fTrace.getAnalysisModules(); - assertFalse(modules.iterator().hasNext()); - - /* Open the trace, the modules should be populated */ - fTrace.traceOpened(new TmfTraceOpenedSignal(this, fTrace, null)); - - modules = fTrace.getAnalysisModules(); - Iterable testModules = fTrace.getAnalysisModulesOfClass(TestAnalysis.class); - assertTrue(modules.iterator().hasNext()); - assertTrue(testModules.iterator().hasNext()); - - /* - * Make sure all modules of type TestAnalysis are returned in the second - * call - */ - for (IAnalysisModule module : modules) { - if (module instanceof TestAnalysis) { - IAnalysisModule otherModule = fTrace.getAnalysisModule(module.getId()); - assertNotNull(otherModule); - assertTrue(otherModule.equals(module)); - } - } - - } - - // ------------------------------------------------------------------------ - // seekEvent on location (note: does not reliably set the rank) - // ------------------------------------------------------------------------ - - @Test - public void testSeekEventOnCacheBoundary() { - // Position trace at event rank 0 - ITmfContext context = fTrace.seekEvent(0); - ITmfEvent event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", 0, context.getRank()); - - context = fTrace.seekEvent(context.getLocation()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - // Position trace at event rank 1000 - ITmfContext tmpContext = fTrace.seekEvent(new TmfTimestamp(1001, SCALE, 0)); - context = fTrace.seekEvent(tmpContext.getLocation()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1001, event.getTimestamp().getValue()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 1001, event.getTimestamp().getValue()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - // Position trace at event rank 4000 - tmpContext = fTrace.seekEvent(new TmfTimestamp(4001, SCALE, 0)); - context = fTrace.seekEvent(tmpContext.getLocation()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 4001, event.getTimestamp().getValue()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 4001, event.getTimestamp().getValue()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - } - - @Test - public void testSeekEventNotOnCacheBoundary() { - // Position trace at event rank 9 - ITmfContext tmpContext = fTrace.seekEvent(new TmfTimestamp(10, SCALE, 0)); - TmfContext context = fTrace.seekEvent(tmpContext.getLocation()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - ITmfEvent event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - // Position trace at event rank 999 - tmpContext = fTrace.seekEvent(new TmfTimestamp(1000, SCALE, 0)); - context = fTrace.seekEvent(tmpContext.getLocation()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1000, event.getTimestamp().getValue()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 1000, event.getTimestamp().getValue()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - // Position trace at event rank 1001 - tmpContext = fTrace.seekEvent(new TmfTimestamp(1002, SCALE, 0)); - context = fTrace.seekEvent(tmpContext.getLocation()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1002, event.getTimestamp().getValue()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 1002, event.getTimestamp().getValue()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - // Position trace at event rank 4500 - tmpContext = fTrace.seekEvent(new TmfTimestamp(4501, SCALE, 0)); - context = fTrace.seekEvent(tmpContext.getLocation()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - } - - @Test - public void testSeekEventOutOfScope() { - // Position trace at beginning - ITmfContext tmpContext = fTrace.seekEvent(0); - ITmfContext context = fTrace.seekEvent(tmpContext.getLocation()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - ITmfEvent event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - // Position trace at event passed the end - context = fTrace.seekEvent(new TmfTimestamp(NB_EVENTS + 1, SCALE, 0)); - assertNull("Event timestamp", context.getLocation()); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - event = fTrace.getNext(context); - assertNull("Event", event); - } - - // ------------------------------------------------------------------------ - // seekEvent on timestamp (note: does not reliably set the rank) - // ------------------------------------------------------------------------ - - @Test - public void testSeekEventOnNullTimestamp() { - // Position trace at event rank 0 - ITmfContext context = fTrace.seekEvent((ITmfTimestamp) null); - assertEquals("Event rank", 0, context.getRank()); - - ITmfEvent event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", 0, context.getRank()); - } - - @Test - public void testSeekEventOnTimestampOnCacheBoundary() { - // Position trace at event rank 0 - ITmfContext context = fTrace.seekEvent(new TmfTimestamp(1, SCALE, 0)); - assertEquals("Event rank", 0, context.getRank()); - - ITmfEvent event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", 0, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", 1, context.getRank()); - - // Position trace at event rank 1000 - context = fTrace.seekEvent(new TmfTimestamp(1001, SCALE, 0)); - assertEquals("Event rank", 1000, context.getRank()); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1001, event.getTimestamp().getValue()); - assertEquals("Event rank", 1000, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 1001, event.getTimestamp().getValue()); - assertEquals("Event rank", 1001, context.getRank()); - - // Position trace at event rank 4000 - context = fTrace.seekEvent(new TmfTimestamp(4001, SCALE, 0)); - assertEquals("Event rank", 4000, context.getRank()); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 4001, event.getTimestamp().getValue()); - assertEquals("Event rank", 4000, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 4001, event.getTimestamp().getValue()); - assertEquals("Event rank", 4001, context.getRank()); - } - - @Test - public void testSeekEventOnTimestampNotOnCacheBoundary() { - // Position trace at event rank 1 - ITmfContext context = fTrace.seekEvent(new TmfTimestamp(2, SCALE, 0)); - assertEquals("Event rank", 1, context.getRank()); - - ITmfEvent event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 2, event.getTimestamp().getValue()); - assertEquals("Event rank", 1, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 2, event.getTimestamp().getValue()); - assertEquals("Event rank", 2, context.getRank()); - - // Position trace at event rank 9 - context = fTrace.seekEvent(new TmfTimestamp(10, SCALE, 0)); - assertEquals("Event rank", 9, context.getRank()); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); - assertEquals("Event rank", 9, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); - assertEquals("Event rank", 10, context.getRank()); - - // Position trace at event rank 999 - context = fTrace.seekEvent(new TmfTimestamp(1000, SCALE, 0)); - assertEquals("Event rank", 999, context.getRank()); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1000, event.getTimestamp().getValue()); - assertEquals("Event rank", 999, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 1000, event.getTimestamp().getValue()); - assertEquals("Event rank", 1000, context.getRank()); - - // Position trace at event rank 1001 - context = fTrace.seekEvent(new TmfTimestamp(1002, SCALE, 0)); - assertEquals("Event rank", 1001, context.getRank()); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1002, event.getTimestamp().getValue()); - assertEquals("Event rank", 1001, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 1002, event.getTimestamp().getValue()); - assertEquals("Event rank", 1002, context.getRank()); - - // Position trace at event rank 4500 - context = fTrace.seekEvent(new TmfTimestamp(4501, SCALE, 0)); - assertEquals("Event rank", 4500, context.getRank()); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); - assertEquals("Event rank", 4500, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); - assertEquals("Event rank", 4501, context.getRank()); - } - - @Test - public void testSeekEventOnTimestampOutOfScope() { - // Position trace at beginning - ITmfContext context = fTrace.seekEvent(new TmfTimestamp(-1, SCALE, 0)); - assertEquals("Event rank", 0, context.getRank()); - - ITmfEvent event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", 0, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", 1, context.getRank()); - - // Position trace at event passed the end - context = fTrace.seekEvent(new TmfTimestamp(NB_EVENTS + 1, SCALE, 0)); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", null, event); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", null, event); - assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); - } - - // ------------------------------------------------------------------------ - // seekEvent on rank - // ------------------------------------------------------------------------ - - @Test - public void testSeekEventOnNegativeRank() { - // Position trace at event rank 0 - ITmfContext context = fTrace.seekEvent(-1); - assertEquals("Event rank", 0, context.getRank()); - - ITmfEvent event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", 0, context.getRank()); - } - - @Test - public void testSeekOnRankOnCacheBoundary() { - // On lower bound, returns the first event (ts = 1) - ITmfContext context = fTrace.seekEvent(0); - assertEquals("Event rank", 0, context.getRank()); - - ITmfEvent event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", 0, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", 1, context.getRank()); - - // Position trace at event rank 1000 - context = fTrace.seekEvent(1000); - assertEquals("Event rank", 1000, context.getRank()); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1001, event.getTimestamp().getValue()); - assertEquals("Event rank", 1000, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 1001, event.getTimestamp().getValue()); - assertEquals("Event rank", 1001, context.getRank()); - - // Position trace at event rank 4000 - context = fTrace.seekEvent(4000); - assertEquals("Event rank", 4000, context.getRank()); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 4001, event.getTimestamp().getValue()); - assertEquals("Event rank", 4000, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 4001, event.getTimestamp().getValue()); - assertEquals("Event rank", 4001, context.getRank()); - } - - @Test - public void testSeekOnRankNotOnCacheBoundary() { - // Position trace at event rank 9 - ITmfContext context = fTrace.seekEvent(9); - assertEquals("Event rank", 9, context.getRank()); - - ITmfEvent event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); - assertEquals("Event rank", 9, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); - assertEquals("Event rank", 10, context.getRank()); - - // Position trace at event rank 999 - context = fTrace.seekEvent(999); - assertEquals("Event rank", 999, context.getRank()); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1000, event.getTimestamp().getValue()); - assertEquals("Event rank", 999, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 1000, event.getTimestamp().getValue()); - assertEquals("Event rank", 1000, context.getRank()); - - // Position trace at event rank 1001 - context = fTrace.seekEvent(1001); - assertEquals("Event rank", 1001, context.getRank()); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1002, event.getTimestamp().getValue()); - assertEquals("Event rank", 1001, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 1002, event.getTimestamp().getValue()); - assertEquals("Event rank", 1002, context.getRank()); - - // Position trace at event rank 4500 - context = fTrace.seekEvent(4500); - assertEquals("Event rank", 4500, context.getRank()); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); - assertEquals("Event rank", 4500, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); - assertEquals("Event rank", 4501, context.getRank()); - } - - @Test - public void testSeekEventOnRankOutOfScope() { - // Position trace at beginning - ITmfContext context = fTrace.seekEvent(-1); - assertEquals("Event rank", 0, context.getRank()); - - ITmfEvent event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", 0, context.getRank()); - - event = fTrace.getNext(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", 1, context.getRank()); - - // Position trace at event passed the end - context = fTrace.seekEvent(NB_EVENTS); - assertEquals("Event rank", NB_EVENTS, context.getRank()); - - event = fTrace.parseEvent(context); - assertNull("Event", event); - assertEquals("Event rank", NB_EVENTS, context.getRank()); - - event = fTrace.getNext(context); - assertNull("Event", event); - assertEquals("Event rank", NB_EVENTS, context.getRank()); - } - - // ------------------------------------------------------------------------ - // parseEvent - make sure parseEvent doesn't update the context - // ------------------------------------------------------------------------ - - @Test - public void testParseEvent() { - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 0) - final TmfContext context = (TmfContext) fTrace.seekEvent(new TmfTimestamp(0, SCALE, 0)); - TmfContext svContext = new TmfContext(context); - - ITmfEvent event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", 0, context.getRank()); - assertTrue("parseEvent", context.equals(svContext)); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", 0, context.getRank()); - assertTrue("parseEvent", context.equals(svContext)); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); - assertEquals("Event rank", 0, context.getRank()); - assertTrue("parseEvent", context.equals(svContext)); - - // Position the trace at event NB_READS - for (int i = 1; i < NB_READS; i++) { - event = fTrace.getNext(context); - assertEquals("Event timestamp", i, event.getTimestamp().getValue()); - } - - svContext = new TmfContext(context); - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", NB_READS, event.getTimestamp().getValue()); - assertEquals("Event rank", NB_READS -1 , context.getRank()); - assertTrue("parseEvent", context.equals(svContext)); - - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", NB_READS, event.getTimestamp().getValue()); - assertEquals("Event rank", NB_READS - 1, context.getRank()); - assertTrue("parseEvent", context.equals(svContext)); - } - - // ------------------------------------------------------------------------ - // getNext - updates the context - // ------------------------------------------------------------------------ - - @Test - public void testGetNextAfteSeekingOnTS_1() { - final long INITIAL_TS = 1; - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 1) - final ITmfContext context = fTrace.seekEvent(new TmfTimestamp(INITIAL_TS, SCALE, 0)); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fTrace.getNext(context); - assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + i, context.getRank()); - } - - // Make sure we stay positioned - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); - } - - @Test - public void testGetNextAfteSeekingOnTS_2() { - final long INITIAL_TS = 2; - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 500) - final ITmfContext context = fTrace.seekEvent(new TmfTimestamp(INITIAL_TS, SCALE, 0)); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fTrace.getNext(context); - assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + i, context.getRank()); - } - - // Make sure we stay positioned - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); - } - - @Test - public void testGetNextAfteSeekingOnTS_3() { - final long INITIAL_TS = 500; - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 500) - final ITmfContext context = fTrace.seekEvent(new TmfTimestamp(INITIAL_TS, SCALE, 0)); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fTrace.getNext(context); - assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + i, context.getRank()); - } - - // Make sure we stay positioned - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); - } - - @Test - public void testGetNextAfterSeekingOnRank_1() { - final long INITIAL_RANK = 0L; - final int NB_READS = 20; - - // On lower bound, returns the first event (rank = 0) - final ITmfContext context = fTrace.seekEvent(INITIAL_RANK); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fTrace.getNext(context); - assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); - } - - // Make sure we stay positioned - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); - } - - @Test - public void testGetNextAfterSeekingOnRank_2() { - final long INITIAL_RANK = 1L; - final int NB_READS = 20; - - // On lower bound, returns the first event (rank = 0) - final ITmfContext context = fTrace.seekEvent(INITIAL_RANK); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fTrace.getNext(context); - assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); - } - - // Make sure we stay positioned - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); - } - - @Test - public void testGetNextAfterSeekingOnRank_3() { - final long INITIAL_RANK = 500L; - final int NB_READS = 20; - - // On lower bound, returns the first event (rank = 0) - final ITmfContext context = fTrace.seekEvent(INITIAL_RANK); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fTrace.getNext(context); - assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); - } - - // Make sure we stay positioned - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); - } - - @Test - public void testGetNextAfterSeekingOnLocation_1() { - final ITmfLocation INITIAL_LOC = null; - final long INITIAL_TS = 1; - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 1) - final ITmfContext context = fTrace.seekEvent(INITIAL_LOC); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fTrace.getNext(context); - assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + i, context.getRank()); - } - - // Make sure we stay positioned - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); - assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); - } - - @Test - public void testGetNextAfterSeekingOnLocation_2() { - final ITmfLocation INITIAL_LOC = fTrace.seekEvent(1L).getLocation(); - final long INITIAL_TS = 2; - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 501) - final ITmfContext context = fTrace.seekEvent(INITIAL_LOC); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fTrace.getNext(context); - assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); - } - - // Make sure we stay positioned - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); - } - - @Test - public void testGetNextAfterSeekingOnLocation_3() { - final ITmfLocation INITIAL_LOC = fTrace.seekEvent(500L).getLocation(); - final long INITIAL_TS = 501; - final int NB_READS = 20; - - // On lower bound, returns the first event (ts = 501) - final ITmfContext context = fTrace.seekEvent(INITIAL_LOC); - - // Read NB_EVENTS - ITmfEvent event; - for (int i = 0; i < NB_READS; i++) { - event = fTrace.getNext(context); - assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); - } - - // Make sure we stay positioned - event = fTrace.parseEvent(context); - assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); - } - - @Test - public void testGetNextLocation() { - ITmfContext context1 = fTrace.seekEvent(0); - fTrace.getNext(context1); - ITmfLocation location = context1.getLocation(); - ITmfEvent event1 = fTrace.getNext(context1); - ITmfContext context2 = fTrace.seekEvent(location); - ITmfEvent event2 = fTrace.getNext(context2); - assertEquals("Event timestamp", event1.getTimestamp().getValue(), event2.getTimestamp().getValue()); - } - - @Test - public void testGetNextEndLocation() { - ITmfContext context1 = fTrace.seekEvent(fTrace.getNbEvents() - 1); - fTrace.getNext(context1); - ITmfLocation location = context1.getLocation(); - ITmfContext context2 = fTrace.seekEvent(location); - ITmfEvent event = fTrace.getNext(context2); - assertNull("Event", event); - } - - // ------------------------------------------------------------------------ - // processRequest - // ------------------------------------------------------------------------ - - @Test - public void testProcessEventRequestForAllEvents() throws InterruptedException { - final Vector requestedEvents = new Vector<>(); - - final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, - range, 0, NB_EVENTS, ExecutionType.FOREGROUND) { - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - requestedEvents.add(event); - } - }; - final ITmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); - providers[0].sendRequest(request); - request.waitForCompletion(); - - assertEquals("nbEvents", NB_EVENTS, requestedEvents.size()); - assertTrue("isCompleted", request.isCompleted()); - assertFalse("isCancelled", request.isCancelled()); - - // Ensure that we have distinct events. - // Don't go overboard: we are not validating the stub! - for (int i = 0; i < NB_EVENTS; i++) { - assertEquals("Distinct events", i + 1, requestedEvents.get(i).getTimestamp().getValue()); - } - } - - @Test - public void testProcessEventRequestForNbEvents() throws InterruptedException { - final int nbEvents = 1000; - final Vector requestedEvents = new Vector<>(); - - final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, - range, 0, nbEvents, ExecutionType.FOREGROUND) { - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - requestedEvents.add(event); - } - }; - final ITmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); - providers[0].sendRequest(request); - request.waitForCompletion(); - - assertEquals("nbEvents", nbEvents, requestedEvents.size()); - assertTrue("isCompleted", request.isCompleted()); - assertFalse("isCancelled", request.isCancelled()); - - // Ensure that we have distinct events. - // Don't go overboard: we are not validating the stub! - for (int i = 0; i < nbEvents; i++) { - assertEquals("Distinct events", i + 1, requestedEvents.get(i).getTimestamp().getValue()); - } - } - - @Test - public void testProcessEventRequestForSomeEvents() throws InterruptedException { - final long startTime = 100; - final int nbEvents = 1000; - final Vector requestedEvents = new Vector<>(); - - final TmfTimeRange range = new TmfTimeRange(new TmfTimestamp(startTime, SCALE), TmfTimestamp.BIG_CRUNCH); - final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, - range, 0, nbEvents, ExecutionType.FOREGROUND) { - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - requestedEvents.add(event); - } - }; - final ITmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); - providers[0].sendRequest(request); - request.waitForCompletion(); - - assertEquals("nbEvents", nbEvents, requestedEvents.size()); - assertTrue("isCompleted", request.isCompleted()); - assertFalse("isCancelled", request.isCancelled()); - - // Ensure that we have distinct events. - // Don't go overboard: we are not validating the stub! - for (int i = 0; i < nbEvents; i++) { - assertEquals("Distinct events", startTime + i, requestedEvents.get(i).getTimestamp().getValue()); - } - } - - @Test - public void testProcessEventRequestForOtherEvents() throws InterruptedException { - final int startIndex = 99; - final long startTime = 100; - final int nbEvents = 1000; - final Vector requestedEvents = new Vector<>(); - - final TmfTimeRange range = new TmfTimeRange(new TmfTimestamp(startTime, SCALE), TmfTimestamp.BIG_CRUNCH); - final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, - range, startIndex, nbEvents, ExecutionType.FOREGROUND) { - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - requestedEvents.add(event); - } - }; - final ITmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); - providers[0].sendRequest(request); - request.waitForCompletion(); - - assertEquals("nbEvents", nbEvents, requestedEvents.size()); - assertTrue("isCompleted", request.isCompleted()); - assertFalse("isCancelled", request.isCancelled()); - - // Ensure that we have distinct events. - // Don't go overboard: we are not validating the stub! - for (int i = 0; i < nbEvents; i++) { - assertEquals("Distinct events", startTime + i, requestedEvents.get(i).getTimestamp().getValue()); - } - } - - @Test - public void testProcessDataRequestForSomeEvents() throws InterruptedException { - final int startIndex = 100; - final int nbEvents = 1000; - final Vector requestedEvents = new Vector<>(); - - final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, - TmfTimeRange.ETERNITY, - startIndex, - nbEvents, - TmfEventRequest.ExecutionType.FOREGROUND) { - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - requestedEvents.add(event); - } - }; - final ITmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); - providers[0].sendRequest(request); - request.waitForCompletion(); - - assertEquals("nbEvents", nbEvents, requestedEvents.size()); - assertTrue("isCompleted", request.isCompleted()); - assertFalse("isCancelled", request.isCancelled()); - - // Ensure that we have distinct events. - // Don't go overboard: we are not validating the stub! - for (int i = 0; i < nbEvents; i++) { - assertEquals("Distinct events", startIndex + 1 + i, requestedEvents.get(i).getTimestamp().getValue()); - } - } - - // ------------------------------------------------------------------------ - // cancel - // ------------------------------------------------------------------------ - - @Test - public void testCancel() throws InterruptedException { - final int limit = 500; - final Vector requestedEvents = new Vector<>(); - - final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, - range, 0, NB_EVENTS, ExecutionType.FOREGROUND) { - int nbRead = 0; - - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - requestedEvents.add(event); - if (++nbRead == limit) { - cancel(); - } - } - }; - final ITmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); - providers[0].sendRequest(request); - request.waitForCompletion(); - - assertEquals("nbEvents", limit, requestedEvents.size()); - assertTrue("isCompleted", request.isCompleted()); - assertTrue("isCancelled", request.isCancelled()); - } - - // ------------------------------------------------------------------------ - // toString - // ------------------------------------------------------------------------ - - @Test - public void testDefaultTmfTraceStub() { - assertFalse ("Open trace", fTrace == null); - assertEquals("getType", ITmfEvent.class, fTrace.getType()); - assertNull ("getResource", fTrace.getResource()); - assertEquals("getStreamingInterval", 0, fTrace.getStreamingInterval()); - assertEquals("getName", TEST_TRACE.getPath(), fTrace.getName()); - - assertEquals("getNbEvents", NB_EVENTS, fTrace.getNbEvents()); - assertEquals("getRange-start", 1, fTrace.getTimeRange().getStartTime().getValue()); - assertEquals("getRange-end", NB_EVENTS, fTrace.getTimeRange().getEndTime().getValue()); - assertEquals("getStartTime", 1, fTrace.getStartTime().getValue()); - assertEquals("getEndTime", NB_EVENTS, fTrace.getEndTime().getValue()); - - String expected = "TmfTrace [fPath=" + fTrace.getPath() + ", fCacheSize=" + fTrace.getCacheSize() + - ", fNbEvents=" + fTrace.getNbEvents() + ", fStartTime=" + fTrace.getStartTime() + - ", fEndTime=" + fTrace.getEndTime() + ", fStreamingInterval=" + fTrace.getStreamingInterval() + - "]"; - assertEquals("toString", expected, fTrace.toString()); - } - - // ------------------------------------------------------------------------ - // getInitialRangeOffset, getCurrentRange, getCurrentTime - // ------------------------------------------------------------------------ - - @Test - public void testCurrentTimeValues() throws TmfTraceException { - - TmfTraceStub trace = null; - File testfile = null; - try { - final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE.getFullPath()), null); - testfile = new File(FileLocator.toFileURL(location).toURI()); - trace = new TmfTraceStub(testfile.toURI().getPath(), ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, false, null); - // verify initial values - TmfTimestamp defaultInitRange = new TmfTimestamp(DEFAULT_INITIAL_OFFSET_VALUE, ITmfTimestamp.NANOSECOND_SCALE); - assertEquals("getInitialRangeOffset", defaultInitRange, trace.getInitialRangeOffset()); - trace.setInitialRangeOffset(new TmfTimestamp(5, ITmfTimestamp.MILLISECOND_SCALE)); - trace.indexTrace(true); - - TmfTimestamp initRange = new TmfTimestamp(5, ITmfTimestamp.MILLISECOND_SCALE); - assertEquals("getInitialRangeOffset", initRange, trace.getInitialRangeOffset()); - - } catch (final URISyntaxException e) { - fail("URISyntaxException"); - } catch (final IOException e) { - fail("IOException"); - } - } - - /** - * Run the String getHostId() method test - */ - @Test - public void testTraceHostId() { - String a = fTrace.getHostId(); - assertEquals("A-Test-10K", a); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/AbstractCheckpointCollectionTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/AbstractCheckpointCollectionTest.java deleted file mode 100644 index 0d386a8849..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/AbstractCheckpointCollectionTest.java +++ /dev/null @@ -1,374 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.indexer; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.util.ArrayList; -import java.util.Random; - -import org.eclipse.linuxtools.internal.tmf.core.trace.indexer.ICheckpointCollection; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Common code for ICheckpointCollection test classes - * - * @author Marc-Andre Laperle - */ -public abstract class AbstractCheckpointCollectionTest { - - private static final String INDEX_FILE_NAME = "checkpoint.idx"; //$NON-NLS-1$ - - /** - * The number of checkpoints to be inserted in insert tests - */ - protected static final int CHECKPOINTS_INSERT_NUM = 50000; - /** - * The collection being tested - */ - protected ICheckpointCollection fCheckpointCollection = null; - - private TmfTraceStub fTrace; - private File fFile = new File(INDEX_FILE_NAME); - - /** - * Setup the test. Make sure the index is deleted. - */ - @Before - public void setUp() { - fTrace = new TmfTraceStub(); - if (fFile.exists()) { - fFile.delete(); - } - fCheckpointCollection = createCollection(); - } - - /** - * Tear down the test. Make sure the index is deleted. - */ - @After - public void tearDown() { - fTrace.dispose(); - fTrace = null; - if (fCheckpointCollection != null) { - fCheckpointCollection.dispose(); - } - if (fFile.exists()) { - fFile.delete(); - } - } - - /** - * Get the trace being tested. - * - * @return the trace being tested. - */ - public ITmfTrace getTrace() { - return fTrace; - } - - /** - * Returns whether or not the collection is persisted to disk - * - * @return true if the collection is persisted to disk, false otherwise - */ - public boolean isPersistableCollection() { - return false; - } - - /** - * Get the file used for the index being tested. - * - * @return the file used for the index being tested. - */ - public File getFile() { - return fFile; - } - - /** - * Test constructing a new checkpoint collection - */ - @Test - public void testConstructor() { - if (isPersistableCollection()) { - assertTrue(fFile.exists()); - } - assertTrue(fCheckpointCollection.isCreatedFromScratch()); - } - - /** - * Test constructing a new checkpoint collection, existing file - */ - @Test - public void testConstructorExistingFile() { - if (isPersistableCollection()) { - assertTrue(fFile.exists()); - fCheckpointCollection.setIndexComplete(); - fCheckpointCollection.dispose(); - - fCheckpointCollection = createCollection(); - assertFalse(fCheckpointCollection.isCreatedFromScratch()); - } - } - - /** - * Test that a new checkpoint collection is considered created from scratch - * and vice versa - */ - @Test - public void testIsCreatedFromScratch() { - assertTrue(fCheckpointCollection.isCreatedFromScratch()); - fCheckpointCollection.setIndexComplete(); - - if (isPersistableCollection()) { - fCheckpointCollection.dispose(); - fCheckpointCollection = createCollection(); - assertFalse(fCheckpointCollection.isCreatedFromScratch()); - } - } - - /** - * Test setTimeRange, getTimeRange - */ - @Test - public void testSetGetTimeRange() { - if (isPersistableCollection()) { - TmfTimeRange timeRange = new TmfTimeRange(new TmfTimestamp(0), new TmfTimestamp(100)); - fCheckpointCollection.setTimeRange(timeRange); - assertEquals(timeRange, fCheckpointCollection.getTimeRange()); - } - } - - /** - * Create a collection for the test - * - * @return the collection - */ - abstract protected ICheckpointCollection createCollection(); - - /** - * Test setNbEvents, getNbEvents - */ - @Test - public void testSetGetNbEvents() { - if (isPersistableCollection()) { - int expected = 12345; - fCheckpointCollection.setNbEvents(expected); - assertEquals(expected, fCheckpointCollection.getNbEvents()); - } - } - - /** - * Test setSize, size - */ - @Test - public void testSetGetSize() { - assertEquals(0, fCheckpointCollection.size()); - int expected = CHECKPOINTS_INSERT_NUM; - for (int i = 0; i < expected; ++i) { - fCheckpointCollection.insert(new TmfCheckpoint(new TmfTimestamp(0), new TmfLongLocation(0L), 0)); - } - assertEquals(expected, fCheckpointCollection.size()); - } - - /** - * Test delete - */ - @Test - public void testDelete() { - if (isPersistableCollection()) { - assertTrue(fFile.exists()); - fCheckpointCollection.delete(); - assertFalse(fFile.exists()); - } - } - - /** - * Test version change - * - * @throws IOException - * can throw this - */ - @Test - public void testVersionChange() throws IOException { - fCheckpointCollection.setIndexComplete(); - fCheckpointCollection.dispose(); - try (RandomAccessFile f = new RandomAccessFile(fFile, "rw");) { - f.writeInt(-1); - } - - fCheckpointCollection = createCollection(); - assertTrue(fCheckpointCollection.isCreatedFromScratch()); - } - - /** - * Test a single insertion - */ - @Test - public void testInsert() { - TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345), new TmfLongLocation(123456L), 0); - fCheckpointCollection.insert(checkpoint); - - long found = fCheckpointCollection.binarySearch(checkpoint); - assertEquals(0, found); - } - - /** - * Generate many checkpoints and insert them in the collection - * - * @return the list of generated checkpoints - */ - protected ArrayList insertAlot() { - for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { - TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345 + i), new TmfLongLocation(123456L + i), i); - fCheckpointCollection.insert(checkpoint); - } - - fCheckpointCollection.setIndexComplete(); - if (isPersistableCollection()) { - fCheckpointCollection.dispose(); - } - - boolean random = true; - ArrayList list = new ArrayList<>(); - for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { - if (random) { - Random rand = new Random(); - list.add(rand.nextInt(CHECKPOINTS_INSERT_NUM)); - } else { - list.add(i); - } - } - return list; - } - - /** - * Test many checkpoint insertions. Make sure they can be found after - * re-opening the file - */ - @Test - public void testInsertAlot() { - ArrayList list = insertAlot(); - - if (isPersistableCollection()) { - fCheckpointCollection = createCollection(); - } - - for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { - Integer randomCheckpoint = list.get(i); - TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345 + randomCheckpoint), new TmfLongLocation(123456L + randomCheckpoint), 0); - long found = fCheckpointCollection.binarySearch(checkpoint); - assertEquals(randomCheckpoint.intValue(), found); - } - } - - /** - * Test many checkpoint insertions using the same timestamp. Make sure they - * can be found after re-opening the file - */ - @Test - public void testInsertSameTimestamp() { - for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { - TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345), new TmfLongLocation(123456L + i), i); - fCheckpointCollection.insert(checkpoint); - } - - fCheckpointCollection.setIndexComplete(); - if (isPersistableCollection()) { - fCheckpointCollection.dispose(); - } - - boolean random = true; - ArrayList list = new ArrayList<>(); - for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { - if (random) { - Random rand = new Random(); - list.add(rand.nextInt(CHECKPOINTS_INSERT_NUM)); - } else { - list.add(i); - } - } - - if (isPersistableCollection()) { - fCheckpointCollection = createCollection(); - } - - for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { - Integer randomCheckpoint = list.get(i); - TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345), new TmfLongLocation(123456L + randomCheckpoint), 0); - long found = fCheckpointCollection.binarySearch(checkpoint); - assertEquals(randomCheckpoint.intValue(), found); - } - } - - /** - * Tests that binarySearch find the correct checkpoint when the time stamp - * is between checkpoints - */ - @Test - public void testBinarySearchFindInBetween() { - for (long i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { - TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(2 * i), new TmfLongLocation(2 * i), i); - fCheckpointCollection.insert(checkpoint); - } - - TmfCheckpoint searchedCheckpoint = new TmfCheckpoint(new TmfTimestamp(123), new TmfLongLocation(123L), 123); - int expectedInsertionPoint = 61; - int expectedRank = -(expectedInsertionPoint + 2); - - long rank = fCheckpointCollection.binarySearch(searchedCheckpoint); - assertEquals(expectedRank, rank); - } - - - /** - * Tests that binarySearch finds the correct checkpoint when searching for a - * checkpoint with a null location. It should return the previous checkpoint - * from the first checkpoint that matches the timestamp. - */ - @Test - public void testBinarySearchInBetweenSameTimestamp() { - int checkpointNum = 0; - for (; checkpointNum < 100; checkpointNum++) { - TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(0), new TmfLongLocation(checkpointNum), checkpointNum); - fCheckpointCollection.insert(checkpoint); - } - - for (; checkpointNum < 200; checkpointNum++) { - TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(1), new TmfLongLocation(checkpointNum), checkpointNum); - fCheckpointCollection.insert(checkpoint); - } - - final TmfCheckpoint searchedCheckpoint = new TmfCheckpoint(new TmfTimestamp(1), null, 0); - - long found = fCheckpointCollection.binarySearch(searchedCheckpoint); - - int expectedInsertionPoint = 99; - int expectedRank = -(expectedInsertionPoint + 2); - - assertEquals(expectedRank, found); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/AllBench.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/AllBench.java deleted file mode 100644 index d05abe293e..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/AllBench.java +++ /dev/null @@ -1,251 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.indexer; - -import static org.junit.Assert.assertEquals; - -import java.io.File; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.util.ArrayList; -import java.util.Random; - -import org.eclipse.linuxtools.internal.tmf.core.trace.indexer.BTree; -import org.eclipse.linuxtools.internal.tmf.core.trace.indexer.BTreeCheckpointVisitor; -import org.eclipse.linuxtools.internal.tmf.core.trace.indexer.FlatArray; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; - -/** - * A class to benchmark different algoritms for storing the - * checkpoint index on disk - * - * @author Marc-Andre Laperle - */ -public class AllBench { - - private static final boolean reportProgress = true; - private static ArrayList> nums; - private TmfTraceStub fTrace; - private File file = new File("index.idx"); - - static int BTREE_DEGREE = 10; - - private void setUp() { - fTrace = new TmfTraceStub(); - if (file.exists()) { - file.delete(); - } - } - - private void tearDown() { - fTrace.dispose(); - fTrace = null; - if (file.exists()) { - file.delete(); - } - } - - private static void generateDataFile(ArrayList list, int checkpointsNums) throws IOException { - File randomDataFile = new File("data" + checkpointsNums); - try (RandomAccessFile f = new RandomAccessFile(randomDataFile, "rw");) { - if (randomDataFile.exists()) { - for (int i = 0; i < checkpointsNums; i++) { - Random rand = new Random(); - int nextInt = rand.nextInt(checkpointsNums); - list.add(nextInt); - f.writeInt(nextInt); - } - } else { - for (int i = 0; i < checkpointsNums; i++) { - list.add(f.readInt()); - } - } - } - } - - @SuppressWarnings("javadoc") - public static void main(String[] args) throws IOException { - int checkpointsNums [] = new int [] { 5000, 50000, 500000, 1000000 }; - nums = new ArrayList<>(checkpointsNums.length); - - System.out.println("DEGREE: " + BTREE_DEGREE); - - AllBench b = new AllBench(); - b.setUp(); - for (int i = 0; i < checkpointsNums.length; i++) { - ArrayList list = new ArrayList<>(); - generateDataFile(list, checkpointsNums[i]); - nums.add(list); - - System.out.println("*** " + checkpointsNums[i] + " checkpoints ***\n"); - - b.benchIt(list); - } - b.tearDown(); - } - - private void benchIt(ArrayList list) { - - System.out.println("Testing BTree\n"); - - testInsertAlot(list); - - System.out.println("Testing Array\n"); - - testInsertAlotArray(list); - } - - private void testInsertAlot(ArrayList list2) { - int checkpointsNum = list2.size(); - - writeCheckpoints(checkpointsNum); - - ArrayList list = new ArrayList<>(); - for (int i = 0; i < checkpointsNum; i++) { - list.add(i); - } - - readCheckpoints(checkpointsNum, list, false); - readCheckpoints(checkpointsNum, list2, true); - - file.delete(); - - System.out.println(); - } - - private void testInsertAlotArray(ArrayList list2) { - int checkpointsNum = list2.size(); - - writeCheckpointsArray(checkpointsNum); - - ArrayList list = new ArrayList<>(); - for (int i = 0; i < checkpointsNum; i++) { - list.add(i); - } - - readCheckpointsArray(checkpointsNum, list, false); - readCheckpointsArray(checkpointsNum, list2, true); - - file.delete(); - - System.out.println(); - } - - private void writeCheckpoints(int checkpointsNum) { - BTree bTree; - int REPEAT = 10; - long time = 0; - for (int j = 0; j < REPEAT; j++) { - long old = System.currentTimeMillis(); - bTree = new BTree(BTREE_DEGREE, file, fTrace); - for (int i = 0; i < checkpointsNum; i++) { - TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345 + i), new TmfLongLocation(123456L + i), i); - bTree.insert(checkpoint); - } - - time += (System.currentTimeMillis() - old); - bTree.setIndexComplete(); - bTree.dispose(); - if (j != REPEAT - 1) { - file.delete(); - } - if (reportProgress) { - System.out.print("."); - } - } - - System.out.println("Write time average: " + (float) time / REPEAT); - } - - private void writeCheckpointsArray(int checkpointsNum) { - FlatArray array; - int REPEAT = 10; - long time = 0; - for (int j = 0; j < REPEAT; j++) { - long old = System.currentTimeMillis(); - array = new FlatArray(file, fTrace); - for (int i = 0; i < checkpointsNum; i++) { - TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345 + i), new TmfLongLocation(123456L + i), i); - array.insert(checkpoint); - } - - time += (System.currentTimeMillis() - old); - array.setIndexComplete(); - array.dispose(); - if (j != REPEAT - 1) { - file.delete(); - } - if (reportProgress) { - System.out.print("."); - } - } - - System.out.println("Write time average: " + (float) time / REPEAT); - } - - - private void readCheckpoints(int checkpointsNum, ArrayList list, boolean random) { - BTree bTree; - int REPEAT = 10; - long time = 0; - long cacheMisses = 0; - for (int j = 0; j < REPEAT; j++) { - long old = System.currentTimeMillis(); - bTree = new BTree(BTREE_DEGREE, file, fTrace); - for (int i = 0; i < checkpointsNum; i++) { - Integer randomCheckpoint = list.get(i); - TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345 + randomCheckpoint), new TmfLongLocation(123456L + randomCheckpoint), 0); - BTreeCheckpointVisitor treeVisitor = new BTreeCheckpointVisitor(checkpoint); - bTree.accept(treeVisitor); - assertEquals(randomCheckpoint.intValue(), treeVisitor.getCheckpoint().getCheckpointRank()); - } - time += (System.currentTimeMillis() - old); - cacheMisses = bTree.getCacheMisses(); - bTree.dispose(); - if (reportProgress) { - System.out.print("."); - } - } - - System.out.println("Read " + (random ? "(random)" : "(linear)") + "time average: " + (float) time / REPEAT + " (cache miss: " + cacheMisses + ")"); - } - - private void readCheckpointsArray(int checkpointsNum, ArrayList list, boolean random) { - FlatArray array; - int REPEAT = 10; - long time = 0; - long cacheMisses = 0; - for (int j = 0; j < REPEAT; j++) { - long old = System.currentTimeMillis(); - array = new FlatArray(file, fTrace); - for (int i = 0; i < checkpointsNum; i++) { - Integer randomCheckpoint = list.get(i); - TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345 + randomCheckpoint), new TmfLongLocation(123456L + randomCheckpoint), 0); - long found = array.binarySearch(checkpoint); - assertEquals(randomCheckpoint.intValue(), found); - } - time += (System.currentTimeMillis() - old); - cacheMisses = array.getCacheMisses(); - array.dispose(); - if (reportProgress) { - System.out.print("."); - } - } - - System.out.println("Read " + (random ? "(random)" : "(linear)") + "time average: " + (float) time / REPEAT + " (cache miss: " + cacheMisses + ")"); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/AllTests.java deleted file mode 100644 index 0cc9a11dcd..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/AllTests.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.indexer; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite indexer classes - * - * @author Marc-Andre Laperle - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - BTreeTest.class, - FlatArrayTest.class, - TmfMemoryIndexTest.class -}) -public class AllTests { - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/BTreeTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/BTreeTest.java deleted file mode 100644 index 2ea65819c9..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/BTreeTest.java +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.indexer; - -import static org.junit.Assert.assertEquals; - -import java.util.ArrayList; - -import org.eclipse.linuxtools.internal.tmf.core.trace.indexer.BTree; -import org.eclipse.linuxtools.internal.tmf.core.trace.indexer.BTreeCheckpointVisitor; -import org.eclipse.linuxtools.internal.tmf.core.trace.indexer.IBTreeVisitor; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfPersistentlyIndexable; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation; -import org.junit.Test; - -/** - * Tests for the BTree class - * - * @author Marc-Andre Laperle - */ -public class BTreeTest extends AbstractCheckpointCollectionTest { - - private final int DEGREE = 15; - private BTree fBTree; - - @Override - protected BTree createCollection() { - fCheckpointCollection = fBTree = new BTree(DEGREE, getFile(), (ITmfPersistentlyIndexable) getTrace()); - return fBTree; - } - - @Override - public boolean isPersistableCollection() { - return true; - } - - /** - * Tests that accepts find the correct checkpoint and ends with a perfect - * match - */ - @Test - public void testAccept() { - for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { - TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(i), new TmfLongLocation(i), 0); - fBTree.insert(checkpoint); - } - - final TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(123), new TmfLongLocation(123L), 0); - - class TestVisitor implements IBTreeVisitor { - public int fLastCompare = 0; - ITmfCheckpoint fFoundCheckpoint; - - @Override - public int compare(ITmfCheckpoint checkRec) { - fLastCompare = checkRec.compareTo(checkpoint); - if (fLastCompare == 0) { - fFoundCheckpoint = checkRec; - } - return fLastCompare; - } - } - final TestVisitor t = new TestVisitor(); - - fBTree.accept(t); - - assertEquals(checkpoint, t.fFoundCheckpoint); - assertEquals(0, t.fLastCompare); - } - - /** - * Test many checkpoint insertions. Make sure they can be found after - * re-opening the file - */ - @Test - public void testInsertAlotCheckEquals() { - ArrayList list = insertAlot(); - - fBTree = createCollection(); - - for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { - Integer checkpointIndex = list.get(i); - TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345 + checkpointIndex), new TmfLongLocation(123456L + checkpointIndex), 0); - BTreeCheckpointVisitor treeVisitor = new BTreeCheckpointVisitor(checkpoint); - fBTree.accept(treeVisitor); - assertEquals(checkpoint, treeVisitor.getCheckpoint()); - } - } - - /** - * Test setSize, size - */ - @Override - @Test - public void testSetGetSize() { - assertEquals(0, fBTree.size()); - int expected = CHECKPOINTS_INSERT_NUM; - for (int i = 0; i < expected; ++i) { - fBTree.insert(new TmfCheckpoint(new TmfTimestamp(0), new TmfLongLocation(0L), 0)); - fBTree.setSize(fBTree.size() + 1); - } - assertEquals(expected, fBTree.size()); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/FlatArrayTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/FlatArrayTest.java deleted file mode 100644 index 215a5d1903..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/FlatArrayTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.indexer; - -import static org.junit.Assert.assertEquals; - -import java.util.ArrayList; - -import org.eclipse.linuxtools.internal.tmf.core.trace.indexer.FlatArray; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfPersistentlyIndexable; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation; -import org.junit.Test; - -/** - * Tests for the FlatArray class - * - * @author Marc-Andre Laperle - */ -public class FlatArrayTest extends AbstractCheckpointCollectionTest { - - private FlatArray fFlatArray; - - @Override - protected FlatArray createCollection() { - fCheckpointCollection = fFlatArray = new FlatArray(getFile(), (ITmfPersistentlyIndexable) getTrace()); - return fFlatArray; - } - - @Override - public boolean isPersistableCollection() { - return true; - } - - /** - * Tests that binarySearch find the correct checkpoint and ends with a - * perfect match - */ - @Test - public void testBinarySearch() { - for (long i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { - TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(i), new TmfLongLocation(i), 0); - fFlatArray.insert(checkpoint); - } - - TmfCheckpoint expectedCheckpoint = new TmfCheckpoint(new TmfTimestamp(122), new TmfLongLocation(122L), 0); - int expectedRank = 122; - - long rank = fFlatArray.binarySearch(expectedCheckpoint); - ITmfCheckpoint found = fFlatArray.get(rank); - - assertEquals(expectedRank, rank); - assertEquals(found, expectedCheckpoint); - } - - /** - * Test many checkpoint insertions. Make sure they can be found after - * re-opening the file - */ - @Test - public void testInsertAlotCheckEquals() { - ArrayList list = insertAlot(); - - fFlatArray = createCollection(); - - for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { - int checkpointIndex = list.get(i); - TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345 + checkpointIndex), - new TmfLongLocation(123456L + checkpointIndex), checkpointIndex); - ITmfCheckpoint found = fFlatArray.get(checkpointIndex); - assertEquals(checkpoint, found); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/TmfMemoryIndexTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/TmfMemoryIndexTest.java deleted file mode 100644 index 33ebec31c4..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/TmfMemoryIndexTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.indexer; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.eclipse.linuxtools.internal.tmf.core.trace.indexer.TmfMemoryIndex; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation; -import org.junit.Test; - -/** - * Test for the TmfMemoryIndex class - * - * @author Marc-Andre Laperle - */ -public class TmfMemoryIndexTest extends AbstractCheckpointCollectionTest { - - private TmfMemoryIndex fMemoryIndex; - - @Override - protected TmfMemoryIndex createCollection() { - fCheckpointCollection = fMemoryIndex = new TmfMemoryIndex(getTrace()); - return fMemoryIndex; - } - - /** - * Test a single insertion - */ - @Override - @Test - public void testInsert() { - TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345), new TmfLongLocation(123456L), 0); - fMemoryIndex.insert(checkpoint); - - ITmfCheckpoint indexCheckpoint = fMemoryIndex.get(0); - assertEquals(checkpoint, indexCheckpoint); - - long found = fMemoryIndex.binarySearch(checkpoint); - assertEquals(0, found); - } - - /** - * Tests that binarySearch find the correct checkpoint and ends with a perfect match - */ - @Test - public void testBinarySearch() { - for (long i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { - TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(i), new TmfLongLocation(i), 0); - fMemoryIndex.insert(checkpoint); - } - - TmfCheckpoint expectedCheckpoint = new TmfCheckpoint(new TmfTimestamp(122), new TmfLongLocation(122L), 0); - int expectedRank = 122; - - long rank = fMemoryIndex.binarySearch(expectedCheckpoint); - ITmfCheckpoint found = fMemoryIndex.get(rank); - - assertEquals(expectedRank, rank); - assertEquals(found, expectedCheckpoint); - } - - /** - * Test dispose - */ - @Test - public void testDispose() { - fMemoryIndex.dispose(); - assertTrue(fMemoryIndex.isEmpty()); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/AbstractIndexTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/AbstractIndexTest.java deleted file mode 100644 index 7f964a22fe..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/AbstractIndexTest.java +++ /dev/null @@ -1,283 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Adapted for TMF Trace Model 1.0 - * Alexandre Montplaisir - Port to JUnit4 - * Marc-Andre Laperle - Extracted to a common class from TmfCheckpointIndexTest - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.indexer.checkpoint; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.tests.TmfCoreTestPlugin; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfContext; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfEmptyTraceStub; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Common code for index testing - * - * @author Marc-Andre Laperle - */ -public abstract class AbstractIndexTest { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - /** - * - */ - protected static final int BLOCK_SIZE = 100; - private static final int NB_EVENTS = 10000; - /** - * The trace being tested - */ - protected static TestTrace fTrace = null; - private static EmptyTestTrace fEmptyTrace = null; - - // ------------------------------------------------------------------------ - // Housekeeping - // ------------------------------------------------------------------------ - - /** - * Setup the test - */ - @Before - public void setUp() { - setupTrace(getTracePath()); - } - - /** - * Get the trace path - * - * @return the trace path - */ - protected String getTracePath() { - return TmfTestTrace.A_TEST_10K.getFullPath(); - } - - /** - * Tear down the test - */ - @After - public void tearDown() { - fTrace.dispose(); - fTrace = null; - fEmptyTrace.dispose(); - fEmptyTrace = null; - } - - interface TestIndexerInterface extends ITmfTraceIndexer { - ITmfCheckpointIndex getCheckpoints(); - } - - // ------------------------------------------------------------------------ - // Helper classes - // ------------------------------------------------------------------------ - - /** - * A test indexer - */ - protected static class TestIndexer extends TmfCheckpointIndexer implements TestIndexerInterface { - /** - * Constructs the test indexer for a normal test trace - * - * @param testTrace - * the test trace - */ - public TestIndexer(ITmfTrace testTrace) { - super(testTrace, BLOCK_SIZE); - } - - @Override - public ITmfCheckpointIndex getCheckpoints() { - return getTraceIndex(); - } - } - - /** - * Create the indexer for testing - * - * @param trace - * the trace - * @return the indexer for testing - */ - protected TestIndexerInterface createTestIndexer(TestTrace trace) { - return new TestIndexer(trace); - } - - /** - * A test trace - */ - protected class TestTrace extends TmfTraceStub { - /** - * - * @param path - * the path - * @param blockSize - * the block size - * @throws TmfTraceException - * when error occurs - */ - public TestTrace(String path, int blockSize) throws TmfTraceException { - super(path, blockSize, false, null); - } - - @Override - protected ITmfTraceIndexer createIndexer(int interval) { - return createTestIndexer(this); - } - - @Override - public TestIndexerInterface getIndexer() { - return (TestIndexerInterface) super.getIndexer(); - } - } - - private class EmptyTestTrace extends TmfEmptyTraceStub { - public EmptyTestTrace() { - super(); - init(getClass().getSimpleName(), TmfEvent.class); - } - - @Override - protected ITmfTraceIndexer createIndexer(int interval) { - return new TestIndexer(this); - } - - @Override - public TestIndexer getIndexer() { - return (TestIndexer) super.getIndexer(); - } - } - - // ------------------------------------------------------------------------ - // Helper functions - // ------------------------------------------------------------------------ - - /** - * Creates the trace for the specified path - * - * @param path - * the path - * @return the created trace - * @throws URISyntaxException - * when error occurs - * @throws IOException - * when error occurs - * @throws TmfTraceException - * when error occurs - */ - protected TestTrace createTrace(final String path) throws URISyntaxException, IOException, TmfTraceException { - final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(path), null); - final File test = new File(FileLocator.toFileURL(location).toURI()); - TestTrace trace = new TestTrace(test.toURI().getPath(), BLOCK_SIZE); - trace.indexTrace(true); - return trace; - } - - private synchronized void setupTrace(final String path) { - if (fTrace == null) { - try { - fTrace = createTrace(path); - } catch (final TmfTraceException e) { - fail(e.getMessage()); - } catch (final URISyntaxException e) { - fail(e.getMessage()); - } catch (final IOException e) { - fail(e.getMessage()); - } - } - - if (fEmptyTrace == null) { - fEmptyTrace = new EmptyTestTrace(); - fEmptyTrace.indexTrace(true); - } - } - - // ------------------------------------------------------------------------ - // Verify checkpoints - // ------------------------------------------------------------------------ - - /** - * Test the content of the index after building the full index - */ - @Test - public void testTmfTraceIndexing() { - verifyIndexContent(); - } - - /** - * Verify the content of the index - */ - protected static void verifyIndexContent() { - assertEquals(BLOCK_SIZE, fTrace.getCacheSize()); - assertEquals(NB_EVENTS, fTrace.getNbEvents()); - assertEquals(1, fTrace.getTimeRange().getStartTime().getValue()); - assertEquals(NB_EVENTS, fTrace.getTimeRange().getEndTime().getValue()); - assertEquals(1, fTrace.getStartTime().getValue()); - assertEquals(NB_EVENTS, fTrace.getEndTime().getValue()); - - ITmfCheckpointIndex checkpoints = fTrace.getIndexer().getCheckpoints(); - int pageSize = fTrace.getCacheSize(); - assertTrue(checkpoints != null); - assertEquals(NB_EVENTS / BLOCK_SIZE, checkpoints.size()); - - // Validate that each checkpoint points to the right event - for (int i = 0; i < checkpoints.size(); i++) { - ITmfCheckpoint checkpoint = checkpoints.get(i); - TmfContext context = new TmfContext(checkpoint.getLocation(), i * pageSize); - ITmfEvent event = fTrace.parseEvent(context); - assertEquals(context.getRank(), i * pageSize); - assertTrue((checkpoint.getTimestamp().compareTo(event.getTimestamp(), false) == 0)); - } - } - - /** - * Test that a empty trace has the correct content - */ - @Test - public void testEmptyTmfTraceIndexing() { - assertEquals(ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, fEmptyTrace.getCacheSize()); - assertEquals(0, fEmptyTrace.getNbEvents()); - assertEquals(TmfTimestamp.BIG_BANG, fEmptyTrace.getTimeRange().getStartTime()); - assertEquals(TmfTimestamp.BIG_BANG, fEmptyTrace.getTimeRange().getEndTime()); - assertEquals(TmfTimestamp.BIG_BANG, fEmptyTrace.getStartTime()); - assertEquals(TmfTimestamp.BIG_BANG, fEmptyTrace.getEndTime()); - - ITmfCheckpointIndex checkpoints = fEmptyTrace.getIndexer().getCheckpoints(); - assertTrue(checkpoints != null); - assertEquals(0, checkpoints.size()); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/AllTests.java deleted file mode 100644 index 43ab0a43ea..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/AllTests.java +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.indexer.checkpoint; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite for org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TmfBTreeIndexTest.class, - TmfCheckpointIndexTest.class, - TmfCheckpointIndexTest2.class, - TmfCheckpointTest.class, - TmfExperimentCheckpointIndexTest.class, -}) -public class AllTests {} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfBTreeIndexTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfBTreeIndexTest.java deleted file mode 100644 index f522a95f56..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfBTreeIndexTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Adapted for TMF Trace Model 1.0 - * Alexandre Montplaisir - Port to JUnit4 - * Marc-Andre Laperle - Adapted to BTree indexer from TmfCheckpointIndexTest - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.indexer.checkpoint; - -import static org.junit.Assert.assertFalse; - -import org.eclipse.linuxtools.tmf.core.trace.indexer.TmfBTreeTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; -import org.junit.Test; - -/** - * Test suite for the TmfBTreeTraceIndexer class. - * - * @author Marc-Andre Laperle - */ -public class TmfBTreeIndexTest extends AbstractIndexTest { - - /** - * Create the indexer for testing - * - * @param trace - * the trace - * @return the indexer for testing - */ - @Override - protected TestIndexerInterface createTestIndexer(TestTrace trace) { - return new TestBTreeIndexer(trace); - } - - private static class TestBTreeIndexer extends TmfBTreeTraceIndexer implements TestIndexerInterface { - public TestBTreeIndexer(TestTrace testTrace) { - super(testTrace, BLOCK_SIZE); - } - - @Override - public ITmfCheckpointIndex getCheckpoints() { - return getTraceIndex(); - } - } - - /** - * Test that a fully built index has the same content when reloaded from disk - * - * @throws Exception when error occurs - */ - @Test - public void testReopenIndex() throws Exception { - fTrace.dispose(); - fTrace = createTrace(getTracePath()); - assertFalse(fTrace.getIndexer().getCheckpoints().isCreatedFromScratch()); - fTrace.indexTrace(true); - - verifyIndexContent(); - } - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointIndexTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointIndexTest.java deleted file mode 100644 index 6eba8a3c3c..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointIndexTest.java +++ /dev/null @@ -1,23 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Adapted for TMF Trace Model 1.0 - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.indexer.checkpoint; - - -/** - * Test suite for the TmfCheckpointIndexTest class. - */ -public class TmfCheckpointIndexTest extends AbstractIndexTest { - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointIndexTest2.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointIndexTest2.java deleted file mode 100644 index b7049cb63b..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointIndexTest2.java +++ /dev/null @@ -1,236 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.indexer.checkpoint; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.tests.TmfCoreTestPlugin; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfEmptyTraceStub; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Test suite for the TmfCheckpointIndexer class (events with same - * timestamp around checkpoint). - */ -@SuppressWarnings("javadoc") -public class TmfCheckpointIndexTest2 { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - private static final int BLOCK_SIZE = 100; - private static final int NB_EVENTS = 702; - private static TestTrace fTrace = null; - private static EmptyTestTrace fEmptyTrace = null; - - // ------------------------------------------------------------------------ - // Housekeeping - // ------------------------------------------------------------------------ - - @Before - public void setUp() { - // Trace has 3 events at t=101 at rank 99, 100, 101 - // Trace has events with same timestamp (ts=102) for ranks 102..702 -> 2 checkpoints with same timestamp are created - setupTrace(TmfTestTrace.A_TEST_10K2.getFullPath()); - } - - @After - public void tearDown() { - fTrace.dispose(); - fTrace = null; - fEmptyTrace.dispose(); - fEmptyTrace = null; - } - - // ------------------------------------------------------------------------ - // Helper classes - // ------------------------------------------------------------------------ - - private static class TestIndexer extends TmfCheckpointIndexer { - @SuppressWarnings({ }) - public TestIndexer(TestTrace testTrace) { - super(testTrace, BLOCK_SIZE); - } - @SuppressWarnings({ }) - public TestIndexer(EmptyTestTrace testTrace) { - super(testTrace, BLOCK_SIZE); - } - public ITmfCheckpointIndex getCheckpoints() { - return getTraceIndex(); - } - } - - private class TestTrace extends TmfTraceStub { - public TestTrace(String path, int blockSize) throws TmfTraceException { - super(path, blockSize, false, null); - } - - @Override - protected ITmfTraceIndexer createIndexer(int interval) { - return new TestIndexer(this); - } - - @Override - public TestIndexer getIndexer() { - return (TestIndexer) super.getIndexer(); - } - } - - private class EmptyTestTrace extends TmfEmptyTraceStub { - - public EmptyTestTrace() { - super(); - init(getClass().getSimpleName(), TmfEvent.class); - } - - @Override - protected ITmfTraceIndexer createIndexer(int interval) { - return new TestIndexer(this); - } - - @Override - public TestIndexer getIndexer() { - return (TestIndexer) super.getIndexer(); - } - } - - // ------------------------------------------------------------------------ - // Helper functions - // ------------------------------------------------------------------------ - - private synchronized void setupTrace(final String path) { - if (fTrace == null) { - try { - final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(path), null); - final File test = new File(FileLocator.toFileURL(location).toURI()); - fTrace = new TestTrace(test.toURI().getPath(), BLOCK_SIZE); - fTrace.indexTrace(true); - } catch (final TmfTraceException e) { - e.printStackTrace(); - } catch (final URISyntaxException e) { - e.printStackTrace(); - } catch (final IOException e) { - e.printStackTrace(); - } - } - - if (fEmptyTrace == null) { - fEmptyTrace = new EmptyTestTrace(); - fEmptyTrace.indexTrace(true); - } - } - - // ------------------------------------------------------------------------ - // Verify checkpoints - // ------------------------------------------------------------------------ - - @Test - public void testTmfTraceMultiTimestamps() { - assertEquals("getCacheSize", BLOCK_SIZE, fTrace.getCacheSize()); - assertEquals("getTraceSize", NB_EVENTS, fTrace.getNbEvents()); - assertEquals("getRange-start", 1, fTrace.getTimeRange().getStartTime().getValue()); - assertEquals("getRange-end", 102, fTrace.getTimeRange().getEndTime().getValue()); - assertEquals("getStartTime", 1, fTrace.getStartTime().getValue()); - assertEquals("getEndTime", 102, fTrace.getEndTime().getValue()); - - ITmfCheckpointIndex checkpoints = fTrace.getIndexer().getCheckpoints(); - assertTrue("Checkpoints exist", checkpoints != null); - assertEquals("Checkpoints size", NB_EVENTS / BLOCK_SIZE + 1, checkpoints.size()); - - // Trace has 3 events with same timestamp (ts=101) at rank 99, 100, 101 - - // Verify that the event at rank=99 is returned when seeking to ts=101 (first event with this timestamp) - // and not the event at checkpoint boundary - TmfTimestamp seekTs = new TmfTimestamp(101, -3, 0); - ITmfContext ctx = fTrace.seekEvent(seekTs); - ITmfEvent event = fTrace.getNext(ctx); - - assertEquals(99, ctx.getRank()); - assertEquals(0, seekTs.compareTo(event.getTimestamp(), false)); - - event = fTrace.getNext(ctx); - - assertEquals(100, ctx.getRank()); - assertEquals(0, seekTs.compareTo(event.getTimestamp(), false)); - - event = fTrace.getNext(ctx); - - assertEquals(101, ctx.getRank()); - assertEquals(0, seekTs.compareTo(event.getTimestamp(), false)); - - // Trace has events with same timestamp (ts=102) for ranks 102..702 -> 2 checkpoints with same timestamp are created - // Verify that the event at rank=102 is returned when seeking to ts=102 (first event with this timestamp) - // and not the event at checkpoint boundary - seekTs = new TmfTimestamp(102, -3, 0); - ctx = fTrace.seekEvent(seekTs); - event = fTrace.getNext(ctx); - - assertEquals(102, ctx.getRank()); - assertEquals(0, seekTs.compareTo(event.getTimestamp(), false)); - - // Verify seek to first checkpoint - seekTs = new TmfTimestamp(1, -3, 0); - ctx = fTrace.seekEvent(seekTs); - event = fTrace.getNext(ctx); - - assertEquals(1, ctx.getRank()); - assertEquals(0, seekTs.compareTo(event.getTimestamp(), false)); - - // Verify seek to timestamp before first event - seekTs = new TmfTimestamp(0, -3, 0); - ctx = fTrace.seekEvent(seekTs); - event = fTrace.getNext(ctx); - - assertEquals(1, ctx.getRank()); - assertEquals(0, new TmfTimestamp(1, -3, 0).compareTo(event.getTimestamp(), false)); - - // Verify seek to timestamp between first and second checkpoint - seekTs = new TmfTimestamp(50, -3, 0); - ctx = fTrace.seekEvent(seekTs); - event = fTrace.getNext(ctx); - - assertEquals(50, ctx.getRank()); - assertEquals(0, seekTs.compareTo(event.getTimestamp(), false)); - - // Verify seek to timestamp after last event in trace - seekTs = new TmfTimestamp(103, -3, 0); - ctx = fTrace.seekEvent(seekTs); - event = fTrace.getNext(ctx); - - assertEquals(-1, ctx.getRank()); - assertNull(event); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointTest.java deleted file mode 100644 index c4e202a250..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointTest.java +++ /dev/null @@ -1,243 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Adapted for TMF Trace Model 1.0 - * Alexandre Montplaisir - Port to JUnit4 - * Patrick Tasse - Updated for location in checkpoint - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.indexer.checkpoint; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation; -import org.junit.Test; - -/** - * Test suite for the TmfCheckpoint class. - */ -@SuppressWarnings("javadoc") -public class TmfCheckpointTest { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - private ITmfTimestamp fTimestamp1 = new TmfTimestamp(); - private ITmfTimestamp fTimestamp2 = TmfTimestamp.BIG_BANG; - private ITmfTimestamp fTimestamp3 = TmfTimestamp.BIG_CRUNCH; - - private long aLong1 = 12345L; - private long aLong2 = 23456L; - private long aLong3 = 34567L; - private long RANK1 = 1L; - private long RANK2 = 2L; - private long RANK3 = 3L; - - private ITmfLocation fLocation1 = new TmfLongLocation(aLong1); - private ITmfLocation fLocation2 = new TmfLongLocation(aLong2); - private ITmfLocation fLocation3 = new TmfLongLocation(aLong3); - - private TmfCheckpoint fCheckpoint1 = new TmfCheckpoint(fTimestamp1, fLocation1, RANK1); - private TmfCheckpoint fCheckpoint2 = new TmfCheckpoint(fTimestamp2, fLocation2, RANK2); - private TmfCheckpoint fCheckpoint3 = new TmfCheckpoint(fTimestamp3, fLocation3, RANK3); - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - @Test - public void testTmfCheckpoint() { - assertEquals("TmfCheckpoint", fTimestamp1, fCheckpoint1.getTimestamp()); - assertEquals("TmfCheckpoint", fLocation1, fCheckpoint1.getLocation()); - } - - public void testTmfLocationCopy() { - final TmfCheckpoint checkpoint = new TmfCheckpoint(fCheckpoint1); - - assertEquals("TmfCheckpoint", fTimestamp1, checkpoint.getTimestamp()); - assertEquals("TmfCheckpoint", fLocation1, checkpoint.getLocation()); - } - - @Test - public void testTmfLocationCopy2() { - try { - new TmfCheckpoint(null); - fail("null copy"); - } - catch (final IllegalArgumentException e) { - // Success - } - catch (final Exception e) { - fail("wrong exception"); - } - } - - // ------------------------------------------------------------------------ - // compareTo - // ------------------------------------------------------------------------ - - @Test - public void testCompareTo() { - assertEquals("compareTo", 0, fCheckpoint1.compareTo(fCheckpoint1)); - assertEquals("compareTo", 1, fCheckpoint1.compareTo(fCheckpoint2)); - assertEquals("compareTo", -1, fCheckpoint1.compareTo(fCheckpoint3)); - - assertEquals("compareTo", -1, fCheckpoint2.compareTo(fCheckpoint1)); - assertEquals("compareTo", 0, fCheckpoint2.compareTo(fCheckpoint2)); - assertEquals("compareTo", -1, fCheckpoint2.compareTo(fCheckpoint3)); - - assertEquals("compareTo", 1, fCheckpoint3.compareTo(fCheckpoint1)); - assertEquals("compareTo", 1, fCheckpoint3.compareTo(fCheckpoint2)); - assertEquals("compareTo", 0, fCheckpoint3.compareTo(fCheckpoint3)); - } - - @Test - public void testCompareToNull() { - final TmfCheckpoint checkpoint1 = new TmfCheckpoint(null, fLocation1, RANK1); - final TmfCheckpoint checkpoint2 = new TmfCheckpoint(null, fLocation2, RANK2); - final TmfCheckpoint checkpoint3 = new TmfCheckpoint(null, fLocation3, RANK3); - final TmfCheckpoint checkpoint4 = new TmfCheckpoint(null, fLocation1, RANK1); - - // Test the various 'null' vs. '!null' combinations - assertEquals("compareTo", 0, checkpoint1.compareTo(fCheckpoint1)); - assertEquals("compareTo", 0, fCheckpoint1.compareTo(checkpoint1)); - assertEquals("compareTo", -1, checkpoint1.compareTo(fCheckpoint2)); - assertEquals("compareTo", 1, fCheckpoint2.compareTo(checkpoint1)); - assertEquals("compareTo", -1, checkpoint1.compareTo(fCheckpoint3)); - assertEquals("compareTo", 1, fCheckpoint3.compareTo(checkpoint1)); - - // Test the 'null' vs. 'null' combinations - assertEquals("compareTo", 0, checkpoint1.compareTo(checkpoint4)); - assertEquals("compareTo", 0, checkpoint4.compareTo(checkpoint1)); - assertEquals("compareTo", -1, checkpoint1.compareTo(checkpoint2)); - assertEquals("compareTo", 1, checkpoint2.compareTo(checkpoint1)); - assertEquals("compareTo", -1, checkpoint1.compareTo(checkpoint3)); - assertEquals("compareTo", 1, checkpoint3.compareTo(checkpoint1)); - } - - // ------------------------------------------------------------------------ - // hashCode - // ------------------------------------------------------------------------ - - @Test - public void testHashCode() { - final TmfCheckpoint checkpoint1 = new TmfCheckpoint(fCheckpoint1); - final TmfCheckpoint checkpoint2 = new TmfCheckpoint(fCheckpoint2); - - assertTrue("hashCode", fCheckpoint1.hashCode() == checkpoint1.hashCode()); - assertTrue("hashCode", fCheckpoint2.hashCode() == checkpoint2.hashCode()); - - assertTrue("hashCode", fCheckpoint1.hashCode() != checkpoint2.hashCode()); - assertTrue("hashCode", fCheckpoint2.hashCode() != checkpoint1.hashCode()); - } - - @Test - public void testHashCodeNull() { - final TmfCheckpoint checkpoint1 = new TmfCheckpoint(null, fLocation1, RANK1); - final TmfCheckpoint checkpoint2 = new TmfCheckpoint(fTimestamp1, null, RANK1); - final TmfCheckpoint checkpoint3 = new TmfCheckpoint(checkpoint1); - final TmfCheckpoint checkpoint4 = new TmfCheckpoint(checkpoint2); - - assertTrue("hashCode", fCheckpoint1.hashCode() != checkpoint1.hashCode()); - assertTrue("hashCode", fCheckpoint1.hashCode() != checkpoint2.hashCode()); - - assertTrue("hashCode", checkpoint1.hashCode() == checkpoint3.hashCode()); - assertTrue("hashCode", checkpoint2.hashCode() == checkpoint4.hashCode()); - } - - // ------------------------------------------------------------------------ - // equals - // ------------------------------------------------------------------------ - - @Test - public void testEqualsReflexivity() { - assertTrue("equals", fCheckpoint1.equals(fCheckpoint1)); - assertTrue("equals", fCheckpoint2.equals(fCheckpoint2)); - - assertTrue("equals", !fCheckpoint1.equals(fCheckpoint2)); - assertTrue("equals", !fCheckpoint2.equals(fCheckpoint1)); - } - - @Test - public void testEqualsSymmetry() { - final TmfCheckpoint checkpoint1 = new TmfCheckpoint(fCheckpoint1); - final TmfCheckpoint checkpoint2 = new TmfCheckpoint(fCheckpoint2); - - assertTrue("equals", checkpoint1.equals(fCheckpoint1)); - assertTrue("equals", fCheckpoint1.equals(checkpoint1)); - - assertTrue("equals", checkpoint2.equals(fCheckpoint2)); - assertTrue("equals", fCheckpoint2.equals(checkpoint2)); - } - - @Test - public void testEqualsTransivity() { - final TmfCheckpoint checkpoint1 = new TmfCheckpoint(fCheckpoint1); - final TmfCheckpoint checkpoint2 = new TmfCheckpoint(checkpoint1); - final TmfCheckpoint checkpoint3 = new TmfCheckpoint(checkpoint2); - - assertTrue("equals", checkpoint1.equals(checkpoint2)); - assertTrue("equals", checkpoint2.equals(checkpoint3)); - assertTrue("equals", checkpoint1.equals(checkpoint3)); - } - - @Test - public void testNotEqual() { - // Various checkpoints - final TmfCheckpoint checkpoint1 = new TmfCheckpoint(fTimestamp1, fLocation1, RANK1); - final TmfCheckpoint checkpoint2 = new TmfCheckpoint(fTimestamp2, fLocation1, RANK1); - final TmfCheckpoint checkpoint3 = new TmfCheckpoint(fTimestamp1, fLocation2, RANK2); - final TmfCheckpoint checkpoint4 = new TmfCheckpoint(fTimestamp1, null, RANK1); - final TmfCheckpoint checkpoint5 = new TmfCheckpoint(null, fLocation1, RANK1); - - // Null check - assertFalse("equals", checkpoint1.equals(null)); - - // Different types - assertFalse("equals", checkpoint1.equals(new TmfTimestamp())); - - // Null locations/location - assertFalse("equals", checkpoint1.equals(checkpoint4)); - assertFalse("equals", checkpoint1.equals(checkpoint5)); - assertFalse("equals", checkpoint4.equals(checkpoint1)); - assertFalse("equals", checkpoint5.equals(checkpoint1)); - - // Different locations/location - assertFalse("equals", checkpoint1.equals(checkpoint2)); - assertFalse("equals", checkpoint1.equals(checkpoint3)); - } - - // ------------------------------------------------------------------------ - // toString - // ------------------------------------------------------------------------ - - @Test - public void testToString() { - final String expected1 = "TmfCheckpoint [fLocation=" + fCheckpoint1.getLocation() + - ", fTimestamp=" + fCheckpoint1.getTimestamp() + ", fCheckpointRank=" + fCheckpoint1.getCheckpointRank() + "]"; - final String expected2 = "TmfCheckpoint [fLocation=" + fCheckpoint2.getLocation() + - ", fTimestamp=" + fCheckpoint2.getTimestamp() + ", fCheckpointRank=" + fCheckpoint2.getCheckpointRank() + "]"; - final String expected3 = "TmfCheckpoint [fLocation=" + fCheckpoint3.getLocation() + - ", fTimestamp=" + fCheckpoint3.getTimestamp() + ", fCheckpointRank=" + fCheckpoint3.getCheckpointRank() + "]"; - - assertEquals("toString", expected1, fCheckpoint1.toString()); - assertEquals("toString", expected2, fCheckpoint2.toString()); - assertEquals("toString", expected3, fCheckpoint3.toString()); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfExperimentCheckpointIndexTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfExperimentCheckpointIndexTest.java deleted file mode 100644 index 1aa81bf3c1..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/indexer/checkpoint/TmfExperimentCheckpointIndexTest.java +++ /dev/null @@ -1,192 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - * Patrick Tasse - Updated for ranks in experiment location - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.indexer.checkpoint; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.tests.TmfCoreTestPlugin; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfExperimentStub; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Test suite for the TmfCheckpointIndexTest class. - */ -@SuppressWarnings("javadoc") -public class TmfExperimentCheckpointIndexTest { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private static final String EXPERIMENT = "MyExperiment"; - private static final TmfTestTrace TEST_TRACE1 = TmfTestTrace.O_TEST_10K; - private static final TmfTestTrace TEST_TRACE2 = TmfTestTrace.E_TEST_10K; - private static int NB_EVENTS = 20000; - private static int BLOCK_SIZE = 1000; - - private static ITmfTrace[] fTestTraces; - private static TmfExperimentStub fExperiment; - - // ------------------------------------------------------------------------ - // Housekeeping - // ------------------------------------------------------------------------ - - @Before - public void setUp() { - setupTraces(); - fExperiment = new TmfExperimentStub(EXPERIMENT, fTestTraces, BLOCK_SIZE); - fExperiment.getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, true); - } - - @After - public void tearDown() { - fExperiment.dispose(); - fExperiment = null; - for (ITmfTrace trace : fTestTraces) { - trace.dispose(); - } - fTestTraces = null; - } - - private static void setupTraces() { - - fTestTraces = new ITmfTrace[2]; - try { - URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE1.getFullPath()), null); - File test = new File(FileLocator.toFileURL(location).toURI()); - final TmfTraceStub trace1 = new TmfTraceStub(test.getPath(), 0, true, null); - fTestTraces[0] = trace1; - location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE2.getFullPath()), null); - test = new File(FileLocator.toFileURL(location).toURI()); - final TmfTraceStub trace2 = new TmfTraceStub(test.getPath(), 0, true, null); - fTestTraces[1] = trace2; - } catch (final TmfTraceException e) { - e.printStackTrace(); - } catch (final URISyntaxException e) { - e.printStackTrace(); - } catch (final IOException e) { - e.printStackTrace(); - } - } - - // ------------------------------------------------------------------------ - // Verify checkpoints - // ------------------------------------------------------------------------ - - @Test - public void testTmfTraceIndexing() { - assertEquals("getCacheSize", BLOCK_SIZE, fExperiment.getCacheSize()); - assertEquals("getTraceSize", NB_EVENTS, fExperiment.getNbEvents()); - assertEquals("getRange-start", 1, fExperiment.getTimeRange().getStartTime().getValue()); - assertEquals("getRange-end", NB_EVENTS, fExperiment.getTimeRange().getEndTime().getValue()); - assertEquals("getStartTime", 1, fExperiment.getStartTime().getValue()); - assertEquals("getEndTime", NB_EVENTS, fExperiment.getEndTime().getValue()); - - ITmfCheckpointIndex checkpoints = fExperiment.getIndexer().getCheckpoints(); - int pageSize = fExperiment.getCacheSize(); - assertTrue("Checkpoints exist", checkpoints != null); - assertEquals("Checkpoints size", NB_EVENTS / BLOCK_SIZE, checkpoints.size()); - - // Validate that each checkpoint points to the right event - for (int i = 0; i < checkpoints.size(); i++) { - ITmfCheckpoint checkpoint = checkpoints.get(i); - ITmfLocation location = checkpoint.getLocation(); - ITmfContext context = fExperiment.seekEvent(location); - ITmfEvent event = fExperiment.parseEvent(context); - assertTrue(context.getRank() == i * pageSize); - assertTrue((checkpoint.getTimestamp().compareTo(event.getTimestamp(), false) == 0)); - } - } - - // ------------------------------------------------------------------------ - // Streaming - // ------------------------------------------------------------------------ - - @Test - public void testGrowingIndex() { - ITmfTrace[] testTraces = new TmfTraceStub[2]; - try { - URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE1.getFullPath()), null); - File test = new File(FileLocator.toFileURL(location).toURI()); - final TmfTraceStub trace1 = new TmfTraceStub(test.getPath(), 0, false, null); - testTraces[0] = trace1; - location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE2.getFullPath()), null); - test = new File(FileLocator.toFileURL(location).toURI()); - final TmfTraceStub trace2 = new TmfTraceStub(test.getPath(), 0, false, null); - testTraces[1] = trace2; - } catch (final TmfTraceException e) { - e.printStackTrace(); - } catch (final URISyntaxException e) { - e.printStackTrace(); - } catch (final IOException e) { - e.printStackTrace(); - } - - TmfExperimentStub experiment = new TmfExperimentStub(EXPERIMENT, testTraces, BLOCK_SIZE); - int pageSize = experiment.getCacheSize(); - - // Build the first half of the index - TmfTimeRange range = new TmfTimeRange(new TmfTimestamp(1, -3), new TmfTimestamp(NB_EVENTS / 2 - 1, -3)); - experiment.getIndexer().buildIndex(0, range, true); - - // Validate that each checkpoint points to the right event - ITmfCheckpointIndex checkpoints = experiment.getIndexer().getCheckpoints(); - assertTrue("Checkpoints exist", checkpoints != null); - assertEquals("Checkpoints size", NB_EVENTS / BLOCK_SIZE / 2, checkpoints.size()); - - // Build the second half of the index - experiment.getIndexer().buildIndex(NB_EVENTS / 2, TmfTimeRange.ETERNITY, true); - - // Validate that each checkpoint points to the right event - assertEquals("Checkpoints size", NB_EVENTS / BLOCK_SIZE, checkpoints.size()); - for (int i = 0; i < checkpoints.size(); i++) { - ITmfCheckpoint checkpoint = checkpoints.get(i); - ITmfLocation location = checkpoint.getLocation(); - ITmfContext context = experiment.seekEvent(location); - ITmfEvent event = experiment.parseEvent(context); - assertTrue(context.getRank() == i * pageSize); - assertTrue((checkpoint.getTimestamp().compareTo(event.getTimestamp(), false) == 0)); - assertEquals("Checkpoint value", i * pageSize + 1, checkpoint.getTimestamp().getValue()); - } - - /* Clean up (since we didn't use the class-specific fixtures) */ - experiment.dispose(); - for (ITmfTrace trace : testTraces) { - trace.dispose(); - } - } - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/location/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/location/AllTests.java deleted file mode 100644 index 3593f4caaa..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/location/AllTests.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Adjusted for new Trace Model - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.location; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite for org.eclipse.linuxtools.tmf.core.trace.location - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TmfLocationTest.class, -}) -public class AllTests {} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/location/TmfLocationTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/location/TmfLocationTest.java deleted file mode 100644 index fdbc6a4b1b..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/location/TmfLocationTest.java +++ /dev/null @@ -1,252 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - * Patrick Tasse - Add tests for TmfExperimentLocation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.location; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.nio.ByteBuffer; - -import org.eclipse.linuxtools.internal.tmf.core.trace.TmfExperimentLocation; -import org.eclipse.linuxtools.internal.tmf.core.trace.TmfLocationArray; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLocation; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfTimestampLocation; -import org.junit.Before; -import org.junit.Test; - -/** - * Test suite for the TmfLocation class. - */ -@SuppressWarnings("javadoc") -public class TmfLocationTest { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - private Long aLong = 12345L; - private TmfTimestamp aTimestamp = new TmfTimestamp(); - private TmfLocationArray aLocationArray; - - private TmfLongLocation fLocation1; - private TmfLongLocation fLocation2; - private TmfTimestampLocation fLocation3; - private TmfExperimentLocation fExpLocation; - - // ------------------------------------------------------------------------ - // Housekeeping - // ------------------------------------------------------------------------ - - @Before - public void setUp() { - fLocation1 = new TmfLongLocation((Long) null); - fLocation2 = new TmfLongLocation(aLong); - fLocation3 = new TmfTimestampLocation(aTimestamp); - aLocationArray = new TmfLocationArray( - new ITmfLocation[] { fLocation1, fLocation2, fLocation3 }, - new long[] { 1, 2, 3 } - ); - fExpLocation = new TmfExperimentLocation(aLocationArray); - } - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - @Test - public void testTmfLocation() { - assertNull("TmfLocation", fLocation1.getLocationInfo()); - assertEquals("TmfLocation", aLong, fLocation2.getLocationInfo()); - assertEquals("TmfLocation", aTimestamp, fLocation3.getLocationInfo()); - assertEquals("TmfLocation", aLocationArray, fExpLocation.getLocationInfo()); - } - - @Test - public void testTmfLocationCopy() { - TmfLongLocation location1 = new TmfLongLocation(fLocation1); - TmfLongLocation location2 = new TmfLongLocation(fLocation2); - TmfTimestampLocation location3 = new TmfTimestampLocation(fLocation3); - TmfExperimentLocation expLocation = new TmfExperimentLocation(fExpLocation); - - assertNull("TmfLocation", location1.getLocationInfo()); - assertEquals("TmfLocation", aLong, location2.getLocationInfo()); - assertEquals("TmfLocation", aTimestamp, location3.getLocationInfo()); - assertEquals("TmfLocation", aLocationArray, expLocation.getLocationInfo()); - } - - // ------------------------------------------------------------------------ - // hashCode - // ------------------------------------------------------------------------ - - @Test - public void testHashCode() { - TmfLongLocation location1 = new TmfLongLocation((Long) null); - TmfLongLocation location2 = new TmfLongLocation(aLong); - TmfTimestampLocation location3 = new TmfTimestampLocation(aTimestamp); - TmfExperimentLocation expLocation = new TmfExperimentLocation(fExpLocation); - TmfLocationArray locationArray1 = new TmfLocationArray(aLocationArray, 2, fLocation3, 5); - TmfExperimentLocation expLocation1 = new TmfExperimentLocation(locationArray1); - TmfLocationArray locationArray2 = new TmfLocationArray(aLocationArray, 2, fLocation2, 4); - TmfExperimentLocation expLocation2 = new TmfExperimentLocation(locationArray2); - TmfLocationArray locationArray3 = new TmfLocationArray( - new ITmfLocation[] { fLocation1, fLocation2 }, - new long[] { 1, 2 } - ); - TmfExperimentLocation expLocation3 = new TmfExperimentLocation(locationArray3); - - assertTrue("hashCode", fLocation1.hashCode() == location1.hashCode()); - assertTrue("hashCode", fLocation2.hashCode() == location2.hashCode()); - assertTrue("hashCode", fLocation3.hashCode() == location3.hashCode()); - assertTrue("hashCode", fExpLocation.hashCode() == expLocation.hashCode()); - - assertTrue("hashCode", fLocation2.hashCode() != location3.hashCode()); - assertTrue("hashCode", fLocation3.hashCode() != location2.hashCode()); - assertTrue("hashCode", fExpLocation.hashCode() != expLocation1.hashCode()); - assertTrue("hashCode", fExpLocation.hashCode() != expLocation2.hashCode()); - assertTrue("hashCode", fExpLocation.hashCode() != expLocation3.hashCode()); - } - - // ------------------------------------------------------------------------ - // toEquals - // ------------------------------------------------------------------------ - - private static class TmfTestLongLocation extends TmfLocation { - public TmfTestLongLocation(Long location) { - super(location); - } - - @Override - public void serialize(ByteBuffer bufferOut) {} - } - - private static class TmfTestLongLocation2 extends TmfTestLongLocation { - public TmfTestLongLocation2(Long location) { - super(location); - } - } - - @Test - public void testEqualsWrongTypes() { - ITmfLocation location1 = new TmfTestLongLocation(aLong); - TmfTestLongLocation location2 = new TmfTestLongLocation2(aLong); - - assertFalse("equals", location1.equals(location2)); - assertFalse("equals", location2.equals(location1)); - } - - @Test - public void testEqualsWithNulls() { - ITmfLocation location1 = new TmfLongLocation(aLong); - ITmfLocation location2 = new TmfLongLocation((Long) null); - - assertFalse("equals", location1.equals(location2)); - assertFalse("equals", location2.equals(location1)); - } - - @Test - public void testEqualsReflexivity() { - assertTrue("equals", fLocation1.equals(fLocation1)); - assertTrue("equals", fLocation2.equals(fLocation2)); - assertTrue("equals", fLocation3.equals(fLocation3)); - assertTrue("equals", fExpLocation.equals(fExpLocation)); - - assertTrue("equals", !fLocation2.equals(fLocation3)); - assertTrue("equals", !fLocation3.equals(fLocation2)); - TmfLocationArray locationArray1 = new TmfLocationArray(aLocationArray, 2, fLocation3, 5); - TmfExperimentLocation expLocation1 = new TmfExperimentLocation(locationArray1); - TmfLocationArray locationArray2 = new TmfLocationArray(aLocationArray, 2, fLocation2, 4); - TmfExperimentLocation expLocation2 = new TmfExperimentLocation(locationArray2); - TmfLocationArray locationArray3 = new TmfLocationArray( - new ITmfLocation[] { fLocation1, fLocation2, fLocation3 }, - new long[] { 1, 2 } - ); - TmfExperimentLocation expLocation3 = new TmfExperimentLocation(locationArray3); - assertTrue("equals", !fExpLocation.equals(expLocation1)); - assertTrue("equals", !expLocation1.equals(fExpLocation)); - assertTrue("equals", !fExpLocation.equals(expLocation2)); - assertTrue("equals", !expLocation2.equals(fExpLocation)); - assertTrue("equals", !fExpLocation.equals(expLocation3)); - assertTrue("equals", !expLocation3.equals(fExpLocation)); - } - - @Test - public void testEqualsSymmetry() { - TmfLongLocation location2 = new TmfLongLocation(aLong); - TmfTimestampLocation location3 = new TmfTimestampLocation(aTimestamp); - TmfExperimentLocation expLocation = new TmfExperimentLocation(fExpLocation); - - assertTrue("equals", location2.equals(fLocation2)); - assertTrue("equals", fLocation2.equals(location2)); - - assertTrue("equals", location3.equals(fLocation3)); - assertTrue("equals", fLocation3.equals(location3)); - - assertTrue("equals", expLocation.equals(fExpLocation)); - assertTrue("equals", fExpLocation.equals(expLocation)); - } - - @Test - public void testEqualsTransivity() { - TmfLongLocation location1 = new TmfLongLocation(aLong); - TmfLongLocation location2 = new TmfLongLocation(aLong); - TmfLongLocation location3 = new TmfLongLocation(aLong); - - TmfExperimentLocation expLocation1 = new TmfExperimentLocation(aLocationArray); - TmfExperimentLocation expLocation2 = new TmfExperimentLocation(aLocationArray); - TmfExperimentLocation expLocation3 = new TmfExperimentLocation(aLocationArray); - - assertTrue("equals", location1.equals(location2)); - assertTrue("equals", location2.equals(location3)); - assertTrue("equals", location3.equals(location1)); - assertTrue("equals", expLocation1.equals(expLocation2)); - assertTrue("equals", expLocation2.equals(expLocation3)); - assertTrue("equals", expLocation3.equals(expLocation1)); - } - - @Test - public void testEqualsNull() { - assertTrue("equals", !fLocation1.equals(null)); - assertTrue("equals", !fLocation2.equals(null)); - assertTrue("equals", !fLocation3.equals(null)); - assertTrue("equals", !fExpLocation.equals(null)); - } - - // ------------------------------------------------------------------------ - // toString - // ------------------------------------------------------------------------ - - @Test - public void testToString() { - TmfTimestamp ts = new TmfTimestamp(); - - TmfLongLocation location1 = new TmfLongLocation(aLong); - TmfTimestampLocation location2 = new TmfTimestampLocation(ts); - TmfExperimentLocation expLocation = new TmfExperimentLocation(aLocationArray); - - String expected1 = "TmfLongLocation [fLocationInfo=" + aLong + "]"; - String expected2 = "TmfTimestampLocation [fLocationInfo=" + ts + "]"; - String expected3 = "TmfExperimentLocation [" + aLocationArray + "]"; - - assertEquals("toString", expected1, location1.toString()); - assertEquals("toString", expected2, location2.toString()); - assertEquals("toString", expected3, expLocation.toString()); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/stub/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/stub/AllTests.java deleted file mode 100644 index 4ed2c6ed23..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/stub/AllTests.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.stub; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Unit tests for the development trace package. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - XmlStubTraceTest.class -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/stub/XmlStubTraceTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/stub/XmlStubTraceTest.java deleted file mode 100644 index 5705e938a9..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/stub/XmlStubTraceTest.java +++ /dev/null @@ -1,191 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.stub; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.File; -import java.io.IOException; -import java.net.URL; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Plugin; -import org.eclipse.core.runtime.Status; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.tests.TmfCoreTestPlugin; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.xml.TmfXmlTraceStub; -import org.junit.Test; - -/** - * Test suite for the {@link TmfXmlTraceStub} class - * - * @author Geneviève Bastien - */ -public class XmlStubTraceTest { - - private static final Path VALID_FILE = new Path("testfiles/stub_xml_traces/valid/test.xml"); - private static final Path VALID_PATH = new Path("testfiles/stub_xml_traces/valid"); - private static final Path INVALID_PATH = new Path("testfiles/stub_xml_traces/invalid"); - - private static final String EVENT_A = "A"; - private static final String EVENT_B = "B"; - private static final String FIELD_A = "b"; - private static final String FIELD_B = "f"; - - private static IPath getAbsolutePath(Path relativePath) { - Plugin plugin = TmfCoreTestPlugin.getDefault(); - if (plugin == null) { - /* - * Shouldn't happen but at least throw something to get the test to - * fail early - */ - throw new IllegalStateException(); - } - URL location = FileLocator.find(plugin.getBundle(), relativePath, null); - try { - IPath path = new Path(FileLocator.toFileURL(location).getPath()); - return path; - } catch (IOException e) { - throw new IllegalStateException(); - } - } - - /** - * Test the - * {@link TmfXmlTraceStub#validate(org.eclipse.core.resources.IProject, String)} - * method - */ - @Test - public void testValidate() { - TmfXmlTraceStub trace = new TmfXmlTraceStub(); - File[] invalidFiles = getAbsolutePath(INVALID_PATH).toFile().listFiles(); - assertTrue(invalidFiles.length > 0); - for (File f : invalidFiles) { - assertTrue(!trace.validate(null, f.getAbsolutePath()).isOK()); - } - - File[] validFiles = getAbsolutePath(VALID_PATH).toFile().listFiles(); - assertTrue(validFiles.length > 0); - for (File f : validFiles) { - assertTrue(trace.validate(null, f.getAbsolutePath()).isOK()); - } - } - - /** - * Test the reading and querying the XML trace and make sure fields are - * present - */ - @Test - public void testDevelopmentTrace() { - TmfXmlTraceStub trace = new TmfXmlTraceStub(); - IStatus status = trace.validate(null, getAbsolutePath(VALID_FILE).toOSString()); - if (!status.isOK()) { - fail(status.getException().getMessage()); - } - - try { - trace.initTrace(null, getAbsolutePath(VALID_FILE).toOSString(), TmfEvent.class); - } catch (TmfTraceException e1) { - fail(e1.getMessage()); - } - - CustomEventRequest req = new CustomEventRequest(trace); - trace.sendRequest(req); - try { - req.waitForCompletion(); - if (req.isCancelled()) { - fail(req.getStatus().getMessage()); - } - } catch (InterruptedException e) { - fail(e.getMessage()); - } - assertEquals(4, req.getCount()); - } - - private static IStatus testEvent(ITmfEvent event) { - switch (event.getType().getName()) { - case EVENT_A: { - ITmfEventField content = event.getContent(); - if (!event.getSource().equals("1")) { - return new Status(IStatus.ERROR, TmfCoreTestPlugin.PLUGIN_ID, "Events of type A should have source 1 but was " + event.getSource()); - } - if (content.getField(FIELD_A) == null) { - return new Status(IStatus.ERROR, TmfCoreTestPlugin.PLUGIN_ID, String.format("Field %s does not exist in event %s", FIELD_A, EVENT_A)); - } - break; - } - case EVENT_B: { - ITmfEventField content = event.getContent(); - if (!event.getSource().equals("2")) { - return new Status(IStatus.ERROR, TmfCoreTestPlugin.PLUGIN_ID, "Events of type B should have source 2 but was " + event.getSource()); - } - if (content.getField(FIELD_B) == null) { - return new Status(IStatus.ERROR, TmfCoreTestPlugin.PLUGIN_ID, String.format("Field %s does not exist in event %s", FIELD_B, EVENT_B)); - } - break; - } - default: - return new Status(IStatus.ERROR, TmfCoreTestPlugin.PLUGIN_ID, "Unexpected event " + event.getType().getName()); - } - return Status.OK_STATUS; - } - - private class CustomEventRequest extends TmfEventRequest { - private final ITmfTrace fTrace; - private IStatus fResult = Status.OK_STATUS; - private int fCount = 0; - - public CustomEventRequest(ITmfTrace trace) { - super(trace.getEventType(), - TmfTimeRange.ETERNITY, - 0, - ITmfEventRequest.ALL_DATA, - ITmfEventRequest.ExecutionType.BACKGROUND); - this.fTrace = trace; - } - - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - if (event.getTrace() == fTrace) { - fCount++; - IStatus result = testEvent(event); - if (!result.isOK()) { - fResult = result; - this.cancel(); - } - } - } - - public IStatus getStatus() { - return fResult; - } - - public int getCount() { - return fCount; - } - - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/text/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/text/AllTests.java deleted file mode 100644 index 77274652b1..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/text/AllTests.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.text; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite for org.eclipse.linuxtools.tmf.core.trace.location - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TextTraceContextTest.class, - TextTraceEventContentTest.class, - TextTraceTest.class, -}) -public class AllTests {} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/text/TextTraceContextTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/text/TextTraceContextTest.java deleted file mode 100644 index c514c5bcdb..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/text/TextTraceContextTest.java +++ /dev/null @@ -1,238 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.text; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.util.regex.Pattern; - -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.TmfContext; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation; -import org.eclipse.linuxtools.tmf.core.trace.text.TextTraceContext; -import org.junit.Test; - -/** - * Test suite for the {@link TextTraceContext} class. - */ -@SuppressWarnings("javadoc") -public class TextTraceContextTest { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - private final Long aLong1 = 12345L; - private final Long aLong2 = 12346L; - private final Long aLong3 = 12347L; - - private final TmfLongLocation fLocation1 = new TmfLongLocation(aLong1); - private final TmfLongLocation fLocation2 = new TmfLongLocation(aLong2); - - private final long fRank1 = 1; - private final long fRank2 = 2; - - private final TextTraceContext fContext1 = new TextTraceContext(fLocation1, fRank1); - private final TextTraceContext fContext2 = new TextTraceContext(fLocation1, fRank1); - - private final Pattern pattern1 = Pattern.compile("\\s*.*"); - private final Pattern pattern2 = Pattern.compile("\\s*.*"); - - private final String line1 = "line1"; - private final String line2 = "line2"; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - public TextTraceContextTest () { - fContext1.firstLine = line1; - fContext1.firstLineMatcher = pattern1.matcher(line1); - fContext1.nextLineLocation = aLong2; - - fContext2.firstLine = line2; - fContext2.firstLineMatcher = pattern2.matcher(line2); - fContext2.nextLineLocation = aLong3; - } - - @Test - public void testTmfContextDefault() { - final TextTraceContext context = new TextTraceContext(fLocation1, fRank1); - assertEquals("getLocation", fLocation1, context.getLocation()); - assertEquals("getRank", fRank1, context.getRank()); - assertNull(context.firstLine); - assertNull(context.firstLineMatcher); - assertEquals(0, context.nextLineLocation); - } - - // ------------------------------------------------------------------------ - // equals - // ------------------------------------------------------------------------ - - @Test - public void testEqualsReflexivity() { - assertTrue("equals", fContext1.equals(fContext1)); - assertTrue("equals", fContext2.equals(fContext2)); - - assertFalse("equals", fContext1.equals(fContext2)); - assertFalse("equals", fContext2.equals(fContext1)); - } - - @Test - public void testEqualsSymmetry() { - final TextTraceContext context1 = new TextTraceContext(fContext1); - final TextTraceContext context2 = new TextTraceContext(fContext2); - - assertTrue("equals", context1.equals(fContext1)); - assertTrue("equals", fContext1.equals(context1)); - - assertTrue("equals", context2.equals(fContext2)); - assertTrue("equals", fContext2.equals(context2)); - } - - @Test - public void testEqualsTransivity() { - - final TextTraceContext context1 = new TextTraceContext(fContext1); - final TextTraceContext context2 = new TextTraceContext(fContext1); - final TextTraceContext context3 = new TextTraceContext(fContext1); - - assertTrue("equals", context1.equals(context2)); - assertTrue("equals", context2.equals(context3)); - assertTrue("equals", context1.equals(context3)); - } - - @Test - public void testEqualsNull() { - assertFalse("equals", fContext1.equals(null)); - assertFalse("equals", fContext2.equals(null)); - } - - private static class MyContext extends TextTraceContext { - - public MyContext(ITmfLocation location, long rank) { - super(location, rank); - } - } - - @Test - public void testNonEquals() { - - // Different classes - final MyContext myContext = new MyContext(fLocation1, fRank1); - assertFalse("equals", fContext1.equals(myContext)); - assertFalse("equals", myContext.equals(fContext1)); - - // Different locations - TextTraceContext context1 = new TextTraceContext(fLocation1, fRank1); - TextTraceContext context2 = new TextTraceContext(fLocation2, fRank1); - assertFalse("equals", context1.equals(context2)); - - // Different ranks - context1 = new TextTraceContext(fLocation1, fRank1); - context2 = new TextTraceContext(fLocation1, fRank2); - assertFalse("equals", context1.equals(context2)); - - // Different firstLine - context1 = new TextTraceContext(fLocation1, fRank1); - context1.firstLine = line1; - context2 = new TextTraceContext(fLocation1, fRank1); - context2.firstLine = line2; - assertFalse("equals", context1.equals(context2)); - - // Different firstLineMatcher - context1 = new TextTraceContext(fLocation1, fRank1); - context1.firstLine = line1; - context1.firstLineMatcher = fContext1.firstLineMatcher; - context2 = new TextTraceContext(fLocation1, fRank1); - context2.firstLine = line1; - context2.firstLineMatcher = fContext2.firstLineMatcher; - assertFalse("equals", context1.equals(context2)); - - // Different nextLineLocation - context1 = new TextTraceContext(fLocation1, fRank1); - context1.firstLine = line1; - context1.firstLineMatcher = fContext1.firstLineMatcher; - context1.nextLineLocation = aLong2; - context2 = new TextTraceContext(fLocation1, fRank1); - context2.firstLine = line1; - context2.firstLineMatcher = fContext1.firstLineMatcher; - context2.nextLineLocation = aLong3; - assertFalse("equals", context1.equals(context2)); - - } - - // ------------------------------------------------------------------------ - // hashCode - // ------------------------------------------------------------------------ - - @Test - public void testHashCode() { - final TextTraceContext context1 = new TextTraceContext(fContext1); - final TextTraceContext context2 = new TextTraceContext(fContext2); - - assertEquals("hashCode", fContext1.hashCode(), context1.hashCode()); - assertEquals("hashCode", fContext2.hashCode(), context2.hashCode()); - - assertFalse("hashCode", fContext1.hashCode() == context2.hashCode()); - assertFalse("hashCode", fContext2.hashCode() == context1.hashCode()); - - final TmfContext nullContext1 = new TmfContext(); - final TmfContext nullContext2 = new TmfContext(nullContext1); - assertEquals("hashCode", nullContext1.hashCode(), nullContext2.hashCode()); - } - - // ------------------------------------------------------------------------ - // setLocation, setRank, updateRank - // ------------------------------------------------------------------------ - - @Test - public void testSetLocation() { - final TextTraceContext context1 = new TextTraceContext(fLocation1, fRank1); - context1.setLocation(fLocation2); - - assertEquals("getLocation", fLocation2, context1.getLocation()); - assertEquals("getRank", fRank1, context1.getRank()); - } - - @Test - public void testSetRank() { - final TextTraceContext context1 = new TextTraceContext(fContext1); - context1.setRank(fContext2.getRank()); - - assertEquals("getLocation", fContext1.getLocation(), context1.getLocation()); - assertEquals("getRank", fContext2.getRank(), context1.getRank()); - } - - @Test - public void testIncreaseRank() { - final TextTraceContext context1 = new TextTraceContext(fLocation1, fRank1); - - context1.increaseRank(); - assertEquals("getRank", fRank1 + 1, context1.getRank()); - context1.increaseRank(); - assertEquals("getRank", fRank1 + 2, context1.getRank()); - - context1.setRank(ITmfContext.UNKNOWN_RANK); - context1.increaseRank(); - assertEquals("getRank", ITmfContext.UNKNOWN_RANK, context1.getRank()); - context1.increaseRank(); - assertEquals("getRank", ITmfContext.UNKNOWN_RANK, context1.getRank()); - } - -} - diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/text/TextTraceEventContentTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/text/TextTraceEventContentTest.java deleted file mode 100644 index 8930792c9e..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/text/TextTraceEventContentTest.java +++ /dev/null @@ -1,232 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.core.tests.trace.text; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.trace.text.TextTraceEventContent; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.text.SyslogEventType; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.text.SyslogEventType.Index; -import org.junit.Test; - -/** - * Test suite for the {@link TextTraceEventContent} class. - */ -@SuppressWarnings({ "javadoc", "nls" }) -public class TextTraceEventContentTest { - - // ------------------------------------------------------------------------ - // Members - // ------------------------------------------------------------------------ - - private TextTraceEventContent fEventContent1; - private TextTraceEventContent fEventContent1Clone; - private TextTraceEventContent fEventContent2; - private TextTraceEventContent fEventContent2Clone; - - public TextTraceEventContentTest () { - fEventContent1 = new TextTraceEventContent(SyslogEventType.LABELS); - fEventContent1.setValue("CONTENT"); - fEventContent1.setFieldValue(Index.TIMESTAMP, "Jan 1 01:01:01"); - fEventContent1.setFieldValue(Index.HOST, "HostA"); - fEventContent1.setFieldValue(Index.LOGGER, "LoggerA"); - fEventContent1.setFieldValue(Index.MESSAGE, "MessageA"); - - fEventContent1Clone = new TextTraceEventContent(SyslogEventType.LABELS); - fEventContent1Clone.setValue("CONTENT"); - fEventContent1Clone.setFieldValue(Index.TIMESTAMP, "Jan 1 01:01:01"); - fEventContent1Clone.setFieldValue(Index.HOST, "HostA"); - fEventContent1Clone.setFieldValue(Index.LOGGER, "LoggerA"); - fEventContent1Clone.setFieldValue(Index.MESSAGE, "MessageA"); - - fEventContent2 = new TextTraceEventContent(SyslogEventType.LABELS); - fEventContent2.setFieldValue(SyslogEventType.LABELS[0], "Jan 1 02:02:02"); - fEventContent2.setFieldValue(SyslogEventType.LABELS[1], "HostB"); - fEventContent2.setFieldValue(SyslogEventType.LABELS[2], "LoggerB"); - StringBuffer buffer = new StringBuffer(); - buffer.append("Message B"); - fEventContent2.setFieldValue(SyslogEventType.LABELS[3], buffer); - - fEventContent2Clone = new TextTraceEventContent(SyslogEventType.LABELS); - fEventContent2Clone.setFieldValue(SyslogEventType.LABELS[0], "Jan 1 02:02:02"); - fEventContent2Clone.setFieldValue(SyslogEventType.LABELS[1], "HostB"); - fEventContent2Clone.setFieldValue(SyslogEventType.LABELS[2], "LoggerB"); - buffer = new StringBuffer(); - buffer.append("Message B"); - fEventContent2Clone.setFieldValue(SyslogEventType.LABELS[3], buffer); - } - - public void testConstructorConstructor() { - assertEquals("getField:TIMESTAMP", "Jan 1 01:01:01", fEventContent1.getFieldValue(Index.TIMESTAMP)); - assertEquals("getField:HOST", "HostA", fEventContent1.getFieldValue(Index.HOST)); - assertEquals("getField:LOGGER", "LoggerA", fEventContent1.getFieldValue(Index.LOGGER)); - assertEquals("getField:MESSAGE", "MessageA", fEventContent1.getFieldValue(Index.MESSAGE).toString()); - } - - // ------------------------------------------------------------------------ - // Event Type - // ------------------------------------------------------------------------ - - @Test - public void testEventTypeInstance() { - SyslogEventType eventType = SyslogEventType.INSTANCE; - assertEquals("getTypeId", "Syslog", eventType.getName()); - assertNotNull ("instance", eventType); - assertTrue (eventType.getFieldNames().contains("Timestamp")); - assertTrue (eventType.getFieldNames().contains("Host")); - assertTrue (eventType.getFieldNames().contains("Logger")); - assertTrue (eventType.getFieldNames().contains("Message")); - } - - // ------------------------------------------------------------------------ - // equals - // ------------------------------------------------------------------------ - - @Test - public void testEquals() { - assertEquals("equals", fEventContent1, fEventContent1); - assertEquals("equals", fEventContent2, fEventContent2); - - assertTrue("equals", !fEventContent1.equals(fEventContent2)); - assertTrue("equals", !fEventContent2.equals(fEventContent1)); - - assertEquals("equals", fEventContent1, fEventContent1Clone); - assertEquals("equals", fEventContent2, fEventContent2Clone); - } - - @Test - public void testEqualsNull() { - assertTrue("equals", !fEventContent1.equals(null)); - assertTrue("equals", !fEventContent2.equals(null)); - } - - // ------------------------------------------------------------------------ - // hashCode - // ------------------------------------------------------------------------ - - @Test - public void testHashCode() { - - assertEquals("hashCode", fEventContent1.hashCode(), fEventContent1Clone.hashCode()); - assertEquals("hashCode", fEventContent2.hashCode(), fEventContent2Clone.hashCode()); - - assertNotEquals("hashCode", fEventContent1.hashCode(), fEventContent2.hashCode()); - assertNotEquals("hashCode", fEventContent2.hashCode(), fEventContent1.hashCode()); - } - - // ------------------------------------------------------------------------ - // Event Content - // ------------------------------------------------------------------------ - - @Test - public void testGetFieldValueWithIndex() { - assertEquals("getFieldValue:TIMESTAMP", "Jan 1 01:01:01", fEventContent1.getFieldValue(Index.TIMESTAMP)); - assertEquals("getFieldValue:HOST", "HostA", fEventContent1.getFieldValue(Index.HOST)); - assertEquals("getFieldValue:LOGGER", "LoggerA", fEventContent1.getFieldValue(Index.LOGGER)); - assertEquals("getFieldValue:MESSAGE", "MessageA", fEventContent1.getFieldValue(Index.MESSAGE)); - assertNull(fEventContent1.getFieldValue(4)); - } - - @Test - public void testGetFieldValueWithName() { - assertEquals("getFieldValue:TIMESTAMP", "Jan 1 01:01:01", fEventContent1.getFieldValue("Timestamp")); - assertEquals("getFieldValue:HOST", "HostA", fEventContent1.getFieldValue("Host")); - assertEquals("getFieldValue:LOGGER", "LoggerA", fEventContent1.getFieldValue("Logger")); - assertEquals("getFieldValue:MESSAGE", "MessageA", fEventContent1.getFieldValue("Message")); - assertNull(fEventContent1.getFieldValue("BlaBla")); - } - - @Test - public void testGetFieldNameWithIndex() { - - assertEquals("getFieldName:TIMESTAMP", SyslogEventType.LABELS[0], fEventContent1.getFieldName(Index.TIMESTAMP)); - assertEquals("getFieldName:HOST", SyslogEventType.LABELS[1], fEventContent1.getFieldName(Index.HOST)); - assertEquals("getFieldName:LOGGER", SyslogEventType.LABELS[2], fEventContent1.getFieldName(Index.LOGGER)); - assertEquals("getFieldName:MESSAGE", SyslogEventType.LABELS[3], fEventContent1.getFieldName(Index.MESSAGE)); - assertNull(fEventContent1.getFieldValue(4)); - } - - @Test - public void testGetFields() { - List fields = fEventContent1.getFields(); - assertEquals(4, fields.size()); - assertEquals("getFields:TIMESTAMP", SyslogEventType.LABELS[0], fields.get(Index.TIMESTAMP).getName()); - assertEquals("getFields:TIMESTAMP", "Jan 1 01:01:01", fields.get(Index.TIMESTAMP).getValue()); - assertEquals("getFields:HOST", SyslogEventType.LABELS[1], fields.get(Index.HOST).getName()); - assertEquals("getFields:HOST", "HostA", fields.get(Index.HOST).getValue()); - assertEquals("getFields:LOGGER", SyslogEventType.LABELS[2], fields.get(Index.LOGGER).getName()); - assertEquals("getFields:LOGGER", "LoggerA", fields.get(Index.LOGGER).getValue()); - assertEquals("getFields:MESSAGE", SyslogEventType.LABELS[3], fields.get(Index.MESSAGE).getName()); - assertEquals("getFields:MESSAGE", "MessageA", fields.get(Index.MESSAGE).getValue()); - } - - @Test - public void testGetFieldWithName() { - ITmfEventField field = fEventContent1.getField("Timestamp"); - assertEquals("getFieldName:TIMESTAMP", SyslogEventType.LABELS[0], field.getName()); - assertEquals("getFieldName:TIMESTAMP", "Jan 1 01:01:01", field.getValue()); - - field = fEventContent1.getField(SyslogEventType.LABELS[1]); - assertEquals("getFieldName:HOST", SyslogEventType.LABELS[1], field.getName()); - assertEquals("getFieldName:HOST", "HostA", field.getValue()); - - field = fEventContent1.getField(SyslogEventType.LABELS[2]); - assertEquals("getFieldName:LOGGER", SyslogEventType.LABELS[2], field.getName()); - assertEquals("getFieldName:LOGGER", "LoggerA", field.getValue()); - - field = fEventContent1.getField(SyslogEventType.LABELS[3]); - assertEquals("getFieldName:Message", SyslogEventType.LABELS[3], field.getName()); - assertEquals("getgetFieldName:Message", "MessageA", field.getValue()); - - field = fEventContent1.getField("BlaBla"); - assertNull(field); - } - - @Test - public void testGetFormattedValue() { - assertEquals("CONTENT", fEventContent1.getFormattedValue()); - } - - @Test - public void testToString() { - assertEquals("Timestamp=Jan 1 01:01:01, Host=HostA, Logger=LoggerA, Message=MessageA", fEventContent1.toString()); - } - - @Test - public void testGetSubField() { - String[] names = { "Timestamp"}; - - ITmfEventField field = fEventContent1.getSubField(names); - assertEquals("getSubField:TIMESTAMP", SyslogEventType.LABELS[0], field.getName()); - assertEquals("getSubField:TIMESTAMP", "Jan 1 01:01:01", field.getValue()); - - String[] names2 = { "Timestamp", "subField" }; - field = fEventContent1.getSubField(names2); - assertNull(field); - } - - @Test - public void testGetFieldNames() { - String[] labels = {"Timestamp", "Host", "Logger", "Message"}; - List names = fEventContent1.getFieldNames(); - assertArrayEquals(labels, names.toArray(new String[names.size()])); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/text/TextTraceTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/text/TextTraceTest.java deleted file mode 100644 index a8df8d27a8..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/text/TextTraceTest.java +++ /dev/null @@ -1,259 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.trace.text; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.Locale; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.preferences.IEclipsePreferences; -import org.eclipse.core.runtime.preferences.InstanceScope; -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest.ExecutionType; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.tests.TmfCoreTestPlugin; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimePreferencesConstants; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampFormat; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.TraceValidationStatus; -import org.eclipse.linuxtools.tmf.core.trace.text.TextTraceEventContent; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.text.SyslogEvent; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.text.SyslogEventType.Index; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.text.SyslogTrace; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -@SuppressWarnings({ "nls", "javadoc"}) -public class TextTraceTest { - - // ------------------------------------------------------------------------ - // Variables - // ------------------------------------------------------------------------ - - private static final String NAME = "syslog"; - private static final String PATH = "testfiles/" + NAME; - - private static final String OTHER_PATH = "testfiles/" + "A-Test-10K"; - - private static SyslogTrace fTrace = null; - private static File fTestFile = null; - - // ------------------------------------------------------------------------ - // Housekeeping - // ------------------------------------------------------------------------ - - @BeforeClass - public static void setUp() throws Exception { - IEclipsePreferences defaultPreferences = InstanceScope.INSTANCE.getNode(Activator.PLUGIN_ID); - defaultPreferences.put(ITmfTimePreferencesConstants.DATIME, "MMM d HH:mm:ss"); - defaultPreferences.put(ITmfTimePreferencesConstants.SUBSEC, ITmfTimePreferencesConstants.SUBSEC_NO_FMT); - defaultPreferences.put(ITmfTimePreferencesConstants.LOCALE, Locale.CANADA.toLanguageTag()); - TmfTimestampFormat.updateDefaultFormats(); - - if (fTrace == null) { - try { - URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(PATH), null); - URI uri = FileLocator.toFileURL(location).toURI(); - fTestFile = new File(uri); - - fTrace = new SyslogTrace(); - IResource resource = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(PATH)); - fTrace.initTrace(resource, uri.getPath(), SyslogEvent.class); - // Dummy request to force the trace indexing - TmfEventRequest request = new TmfEventRequest( - SyslogEvent.class, - TmfTimeRange.ETERNITY, - 0, - ITmfEventRequest.ALL_DATA, - ExecutionType.FOREGROUND) { - }; - fTrace.sendRequest(request); - request.waitForCompletion(); - } catch (URISyntaxException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - @AfterClass - public static void tearDown() { - fTrace.dispose(); - fTrace = null; - IEclipsePreferences defaultPreferences = InstanceScope.INSTANCE.getNode(Activator.PLUGIN_ID); - defaultPreferences.put(ITmfTimePreferencesConstants.DATIME, ITmfTimePreferencesConstants.TIME_HOUR_FMT); - defaultPreferences.put(ITmfTimePreferencesConstants.SUBSEC, ITmfTimePreferencesConstants.SUBSEC_NANO_FMT); - defaultPreferences.put(ITmfTimePreferencesConstants.LOCALE, Locale.getDefault().toLanguageTag()); - TmfTimestampFormat.updateDefaultFormats(); - } - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - @Test - public void testEmptyConstructor() { - SyslogTrace trace = new SyslogTrace(); - assertEquals("getType", null, trace.getType()); - assertEquals("getPath", null, trace.getPath()); - assertEquals("getName", "", trace.getName()); - assertEquals("getCacheSize", 100, trace.getCacheSize()); - - TmfTimestamp initRange = new TmfTimestamp(60, ITmfTimestamp.SECOND_SCALE); - assertEquals("getInitialRangeOffset", initRange, trace.getInitialRangeOffset()); - } - - @Test - public void testValidation() throws URISyntaxException, IOException { - SyslogTrace trace = new SyslogTrace(); - String validTracePath = fTestFile.getAbsolutePath(); - IStatus status = trace.validate(null, validTracePath); - assertTrue(status.isOK()); - assertTrue(status instanceof TraceValidationStatus); - assertEquals(180, ((TraceValidationStatus) status).getConfidence()); - - URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(OTHER_PATH), null); - URI uri = FileLocator.toFileURL(location).toURI(); - File otherFile = new File(uri); - - String validNoConfidenceTrace = otherFile.getAbsolutePath(); - status = trace.validate(null, validNoConfidenceTrace); - assertTrue(status instanceof TraceValidationStatus); - assertEquals(0, ((TraceValidationStatus) status).getConfidence()); - assertTrue(status.isOK()); - - String invalidTrace = fTestFile.getParentFile().getAbsolutePath(); - status = trace.validate(null, invalidTrace); - assertFalse(status.isOK()); - } - - @Test - public void testInitTrace() throws Exception { - URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(PATH), null); - String path = FileLocator.toFileURL(location).toURI().getPath(); - SyslogTrace trace = new SyslogTrace(); - IResource resource = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(PATH)); - trace.initTrace(resource, path, SyslogEvent.class); - assertEquals("getType", SyslogEvent.class, trace.getType()); - assertEquals("getPath", fTestFile.toURI().getPath(), trace.getPath()); - assertEquals("getName", NAME, trace.getName()); - assertEquals("getCacheSize", 100, trace.getCacheSize()); - } - - // ------------------------------------------------------------------------ - // Indexing - // ------------------------------------------------------------------------ - - @Test - public void testTraceIndexing() { - assertEquals("getNbEvents", 6, fTrace.getNbEvents()); - - TmfTimestamp initRange = new TmfTimestamp(60, ITmfTimestamp.SECOND_SCALE); - assertEquals("getInitialRangeOffset", initRange, fTrace.getInitialRangeOffset()); - } - - // ------------------------------------------------------------------------ - // Parsing - // ------------------------------------------------------------------------ - - @Test - public void testTraceParsing() { - ITmfContext context = fTrace.seekEvent(0); - SyslogEvent event = fTrace.getNext(context); - TextTraceEventContent content = event.getContent(); - assertEquals("getTimestamp", "Jan 1 01:01:01", event.getTimestamp().toString()); - assertEquals("getField:TIMESTAMP", "Jan 1 01:01:01", content.getFieldValue(Index.TIMESTAMP)); - assertEquals("getField:HOST", "HostA", content.getFieldValue(Index.HOST)); - assertEquals("getField:LOGGER", "LoggerA", content.getFieldValue(Index.LOGGER)); - assertEquals("getField:MESSAGE", "Message A", content.getFieldValue(Index.MESSAGE).toString()); - event = fTrace.getNext(context); - content = event.getContent(); - assertEquals("getTimestamp", "Jan 1 02:02:02", event.getTimestamp().toString()); - assertEquals("getField:TIMESTAMP", "Jan 1 02:02:02", content.getFieldValue(Index.TIMESTAMP)); - assertEquals("getField:HOST", "HostB", content.getFieldValue(Index.HOST)); - assertEquals("getField:LOGGER", "LoggerB", content.getFieldValue(Index.LOGGER)); - assertEquals("getField:MESSAGE", "Message B", content.getFieldValue(Index.MESSAGE).toString()); - event = fTrace.getNext(context); - content = event.getContent(); - assertEquals("getTimestamp", "Jan 1 03:03:03", event.getTimestamp().toString()); - assertEquals("getField:TIMESTAMP", "Jan 1 03:03:03", content.getFieldValue(Index.TIMESTAMP)); - assertEquals("getField:HOST", "HostC", content.getFieldValue(Index.HOST)); - assertEquals("getField:LOGGER", "LoggerC", content.getFieldValue(Index.LOGGER)); - assertEquals("getField:MESSAGE", "Message C", content.getFieldValue(Index.MESSAGE).toString()); - event = fTrace.getNext(context); - content = event.getContent(); - assertEquals("getTimestamp", "Jan 1 04:04:04", event.getTimestamp().toString()); - assertEquals("getField:TIMESTAMP", "Jan 1 04:04:04", content.getFieldValue(Index.TIMESTAMP)); - assertEquals("getField:HOST", "HostD", content.getFieldValue(Index.HOST)); - assertEquals("getField:LOGGER", "LoggerD", content.getFieldValue(Index.LOGGER)); - assertEquals("getField:MESSAGE", "Message D", content.getFieldValue(Index.MESSAGE).toString()); - event = fTrace.getNext(context); - content = event.getContent(); - assertEquals("getTimestamp", "Jan 1 05:05:05", event.getTimestamp().toString()); - assertEquals("getField:TIMESTAMP", "Jan 1 05:05:05", content.getFieldValue(Index.TIMESTAMP)); - assertEquals("getField:HOST", "HostE", content.getFieldValue(Index.HOST)); - assertEquals("getField:LOGGER", "LoggerE", content.getFieldValue(Index.LOGGER)); - assertEquals("getField:MESSAGE", "", content.getFieldValue(Index.MESSAGE).toString()); - event = fTrace.getNext(context); - content = event.getContent(); - assertEquals("getTimestamp", "Jan 1 06:06:06", event.getTimestamp().toString()); - assertEquals("getField:TIMESTAMP", "Jan 1 06:06:06", content.getFieldValue(Index.TIMESTAMP)); - assertEquals("getField:HOST", "HostF", content.getFieldValue(Index.HOST)); - assertEquals("getField:LOGGER", "LoggerF", content.getFieldValue(Index.LOGGER)); - assertEquals("getField:MESSAGE", "Message F", content.getFieldValue(Index.MESSAGE).toString()); - event = fTrace.getNext(context); - assertEquals("event", null, event); - context.dispose(); - } - - @Test - public void testLocationRatio() { - ITmfContext context = fTrace.seekEvent(3); - double ratio = fTrace.getLocationRatio(context.getLocation()); - SyslogEvent event = fTrace.getNext(context); - TextTraceEventContent content = event.getContent(); - Object logger = content.getFieldValue(Index.LOGGER); - context.dispose(); - context = fTrace.seekEvent(ratio); - event = fTrace.getNext(context); - content = event.getContent(); - assertEquals("getField:LOGGER", logger.toString(), content.getFieldValue(Index.LOGGER).toString()); - context.dispose(); - context = fTrace.seekEvent(0.0); - event = fTrace.getNext(context); - content = event.getContent(); - assertEquals("getField:LOGGER", "LoggerA", content.getFieldValue(Index.LOGGER)); - context.dispose(); - context = fTrace.seekEvent(1.0); - event = fTrace.getNext(context); - assertEquals("event", null, event); - context.dispose(); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/uml2sd/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/uml2sd/AllTests.java deleted file mode 100644 index 0fb01f8e78..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/uml2sd/AllTests.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.uml2sd; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Unit tests for tmf.core.uml2sd - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TmfAsyncSequenceDiagramEventTest.class, - TmfSyncSequenceDiagramEventTest.class -}) -public class AllTests { - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/uml2sd/TmfAsyncSequenceDiagramEventTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/uml2sd/TmfAsyncSequenceDiagramEventTest.java deleted file mode 100644 index 8c0d54c6d7..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/uml2sd/TmfAsyncSequenceDiagramEventTest.java +++ /dev/null @@ -1,125 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.uml2sd; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.uml2sd.TmfAsyncSequenceDiagramEvent; - -import org.junit.Test; - -/** - * TmfAsyncSequenceDiagramEventTest - */ -public class TmfAsyncSequenceDiagramEventTest { - - private final String fContext = ITmfEventType.DEFAULT_CONTEXT_ID; - private final String fTypeId = "Some type"; - private final String fLabel0 = "label1"; - private final String fLabel1 = "label2"; - private final String[] fLabels = new String[] { fLabel0, fLabel1 }; - - private final TmfTimestamp fTimestamp1 = new TmfTimestamp(12345, (byte) 2, 5); - private final TmfTimestamp fTimestamp2 = new TmfTimestamp(12350, (byte) 2, 5); - private final String fSource = "Source"; - private final TmfEventType fType = new TmfEventType(fContext, fTypeId, TmfEventField.makeRoot(fLabels)); - private final String fReference = "Some reference"; - - private final ITmfEvent fEvent1; - private final ITmfEvent fEvent2; - private final TmfEventField fContent1; - private final TmfEventField fContent2; - - /** - * Constructor for the test case - */ - public TmfAsyncSequenceDiagramEventTest() { - fContent1 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some content", null); - fEvent1 = new TmfEvent(null, fTimestamp1, fSource, fType, fContent1, fReference); - - fContent2 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some other content", null); - fEvent2 = new TmfEvent(null, fTimestamp2, fSource, fType, fContent2, fReference); - } - - /** - * Main test - */ - @Test - public void testTmfAsyncSequenceDiagramEvent() { - TmfAsyncSequenceDiagramEvent event = null; - - // Check for illegal arguments (i.e. null for the parameters) - try { - event = new TmfAsyncSequenceDiagramEvent(null, null, null, null, null); - fail(); - } catch (IllegalArgumentException e) { - // success - assertTrue("TmfAsyncSequenceDiagramEvent", e.getMessage().contains("startEvent=null")); - } - - try { - event = new TmfAsyncSequenceDiagramEvent(fEvent1, fEvent2, null, null, null); - fail(); - } catch (IllegalArgumentException e) { - // success - assertTrue("TmfAsyncSequenceDiagramEvent", e.getMessage().contains("sender=null")); - } - - try { - event = new TmfAsyncSequenceDiagramEvent(fEvent1, fEvent2, null, null, null); - fail(); - } catch (IllegalArgumentException e) { - // success - assertTrue("TmfAsyncSequenceDiagramEvent", e.getMessage().contains("receiver=null")); - } - - try { - event = new TmfAsyncSequenceDiagramEvent(fEvent1, fEvent2, "sender", null, null); - fail(); - } catch (IllegalArgumentException e) { - // success - assertTrue("TmfAsyncSequenceDiagramEvent", e.getMessage().contains("name=null")); - } - - try { - event = new TmfAsyncSequenceDiagramEvent(fEvent1, null, "sender", "receiver", "signal"); - fail(); - } catch (IllegalArgumentException e) { - // success - assertTrue("TmfAsyncSequenceDiagramEvent", e.getMessage().contains("endEvent=null")); - } - - try { - event = new TmfAsyncSequenceDiagramEvent(fEvent1, fEvent2, "sender", "receiver", "signal"); - // success - assertEquals("testTmfAsyncSequenceDiagramEvent", 0, event.getStartTime().compareTo(fTimestamp1, true)); - assertEquals("testTmfAsyncSequenceDiagramEvent", 0, event.getEndTime().compareTo(fTimestamp2, true)); - assertEquals("testTmfAsyncSequenceDiagramEvent", "sender", event.getSender()); - assertEquals("testTmfAsyncSequenceDiagramEvent", "receiver", event.getReceiver()); - assertEquals("testTmfAsyncSequenceDiagramEvent", "signal", event.getName()); - - } catch (IllegalArgumentException e) { - fail(); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/uml2sd/TmfSyncSequenceDiagramEventTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/uml2sd/TmfSyncSequenceDiagramEventTest.java deleted file mode 100644 index b8a6b157d4..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/uml2sd/TmfSyncSequenceDiagramEventTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.uml2sd; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.uml2sd.TmfSyncSequenceDiagramEvent; - -import org.junit.Test; - -/** - * TmfSyncSequenceDiagramEventTest - */ -public class TmfSyncSequenceDiagramEventTest { - - private final String fContext = ITmfEventType.DEFAULT_CONTEXT_ID; - private final String fTypeId = "Some type"; - private final String fLabel0 = "label1"; - private final String fLabel1 = "label2"; - private final String[] fLabels = new String[] { fLabel0, fLabel1 }; - - private final TmfTimestamp fTimestamp1 = new TmfTimestamp(12345, (byte) 2, 5); - private final String fSource = "Source"; - private final TmfEventType fType = new TmfEventType(fContext, fTypeId, TmfEventField.makeRoot(fLabels)); - private final String fReference = "Some reference"; - - private final ITmfEvent fEvent1; - private final TmfEventField fContent1; - - /** - * Constructor for the test case - */ - public TmfSyncSequenceDiagramEventTest() { - fContent1 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some content", null); - fEvent1 = new TmfEvent(null, fTimestamp1, fSource, fType, fContent1, fReference); - } - - /** - * Main test - */ - @Test - public void testTmfSyncSequenceDiagramEvent() { - TmfSyncSequenceDiagramEvent event = null; - try { - event = new TmfSyncSequenceDiagramEvent(null, null, null, null); - fail(); - } catch (IllegalArgumentException e) { - // success - assertTrue("testTmfSyncSequenceDiagramEvent", e.getMessage().contains("startEvent=null")); - } - - try { - event = new TmfSyncSequenceDiagramEvent(fEvent1, null, null, null); - fail(); - } catch (IllegalArgumentException e) { - // success - assertTrue("testTmfSyncSequenceDiagramEvent", e.getMessage().contains("sender=null")); - } - - try { - event = new TmfSyncSequenceDiagramEvent(fEvent1, "sender", null, null); - fail(); - } catch (IllegalArgumentException e) { - // success - assertTrue("testTmfSyncSequenceDiagramEvent", e.getMessage().contains("receiver=null")); - } - - try { - event = new TmfSyncSequenceDiagramEvent(fEvent1, "sender", "receiver", null); - fail(); - } catch (IllegalArgumentException e) { - // success - assertTrue("testTmfSyncSequenceDiagramEvent", e.getMessage().contains("name=null")); - } - - try { - event = new TmfSyncSequenceDiagramEvent(fEvent1, "sender", "receiver", "signal"); - // success - assertEquals("testTmfSyncSequenceDiagramEvent", 0, event.getStartTime().compareTo(fTimestamp1, true)); - assertEquals("testTmfSyncSequenceDiagramEvent", "sender", event.getSender()); - assertEquals("testTmfSyncSequenceDiagramEvent", "receiver", event.getReceiver()); - assertEquals("testTmfSyncSequenceDiagramEvent", "signal", event.getName()); - - } catch (IllegalArgumentException e) { - fail(); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/util/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/util/AllTests.java deleted file mode 100644 index 172d2b44a1..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/util/AllTests.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.util; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Unit tests for tmf.core.util - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - PairTest.class -}) -public class AllTests { - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/util/PairTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/util/PairTest.java deleted file mode 100644 index 9230525f63..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/util/PairTest.java +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial design and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.tests.util; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.eclipse.linuxtools.tmf.core.util.Pair; -import org.junit.Test; - -/** - * Test case for Pair class. - * - * @author Bernd Hufmann - */ -@SuppressWarnings("javadoc") -public class PairTest { - - // ------------------------------------------------------------------------ - // Field(s) - // ------------------------------------------------------------------------ - - Pair fPair1 = new Pair<>("String 1", 1L); - Pair fPair2 = new Pair<>("String 2", 2L); - - // ------------------------------------------------------------------------ - // to String - // ------------------------------------------------------------------------ - - @Test - public void testToString() { - String result = fPair1.toString(); - assertEquals("(String 1, 1)", result); - } - - // ------------------------------------------------------------------------ - // Setters/Getters - // ------------------------------------------------------------------------ - - @Test - public void testAccessors() { - Pair myPair = new Pair<>("String 1", 1L); - assertEquals("String 1", myPair.getFirst()); - assertEquals(Long.valueOf(1L), myPair.getSecond()); - - myPair.setFirst("Hello"); - assertEquals("Hello", myPair.getFirst()); - - myPair.setSecond(123L); - assertEquals(Long.valueOf(123L), myPair.getSecond()); - } - - // ------------------------------------------------------------------------ - // equals - // ------------------------------------------------------------------------ - - @Test - public void testEqualsReflexivity() { - assertTrue("equals", fPair1.equals(fPair1)); - assertTrue("equals", fPair2.equals(fPair2)); - - assertTrue("equals", !fPair1.equals(fPair2)); - assertTrue("equals", !fPair2.equals(fPair1)); - } - - @Test - public void testEqualsSymmetry() { - Pair info1 = new Pair<>(fPair1.getFirst(), fPair1.getSecond().longValue()); - Pair info2 = new Pair<>(fPair2.getFirst(), fPair2.getSecond().longValue()); - - assertTrue("equals", info1.equals(fPair1)); - assertTrue("equals", fPair1.equals(info1)); - - assertTrue("equals", info2.equals(fPair2)); - assertTrue("equals", fPair2.equals(info2)); - } - - @Test - public void testEqualsTransivity() { - Pair info1 = new Pair<>(fPair1.getFirst(), fPair1.getSecond().longValue()); - Pair info2 = new Pair<>(fPair1.getFirst(), fPair1.getSecond().longValue()); - Pair info3 = new Pair<>(fPair1.getFirst(), fPair1.getSecond().longValue()); - - assertTrue("equals", info1.equals(info2)); - assertTrue("equals", info2.equals(info3)); - assertTrue("equals", info1.equals(info3)); - } - - @Test - public void testEqualsNull() { - assertTrue("equals", !fPair1.equals(null)); - assertTrue("equals", !fPair2.equals(null)); - } - - @Test - public void testEqualsDifferentObj() { - Pair info = new Pair<>(1L, "String1"); - assertTrue("equals", !fPair1.equals(info)); - } - - // ------------------------------------------------------------------------ - // hashCode - // ------------------------------------------------------------------------ - - @Test - public void testHashCode() { - Pair info1 = new Pair<>(fPair1.getFirst(), fPair1.getSecond().longValue()); - Pair info2 = new Pair<>(fPair2.getFirst(), fPair2.getSecond().longValue()); - - assertTrue("hashCode", fPair1.hashCode() == info1.hashCode()); - assertTrue("hashCode", fPair2.hashCode() == info2.hashCode()); - - assertTrue("hashCode", fPair1.hashCode() != info2.hashCode()); - assertTrue("hashCode", fPair2.hashCode() != info1.hashCode()); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/AllTmfCoreTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/AllTmfCoreTests.java new file mode 100644 index 0000000000..f6fee1b1cc --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/AllTmfCoreTests.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4, enable CTF and statistics tests + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Master test suite for TMF Core. + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TmfCorePluginTest.class, + org.eclipse.tracecompass.tmf.core.tests.analysis.AllTests.class, + org.eclipse.tracecompass.tmf.core.tests.component.AllTests.class, + org.eclipse.tracecompass.tmf.core.tests.event.AllTests.class, + org.eclipse.tracecompass.tmf.core.tests.event.lookup.AllTests.class, + org.eclipse.tracecompass.tmf.core.tests.filter.AllTests.class, + org.eclipse.tracecompass.tmf.core.tests.request.AllTests.class, + org.eclipse.tracecompass.tmf.core.tests.signal.AllTests.class, + org.eclipse.tracecompass.tmf.core.tests.statesystem.AllTests.class, + org.eclipse.tracecompass.tmf.core.tests.statesystem.mipmap.AllTests.class, + org.eclipse.tracecompass.tmf.core.tests.synchronization.AllTests.class, + org.eclipse.tracecompass.tmf.core.tests.trace.AllTests.class, + org.eclipse.tracecompass.tmf.core.tests.trace.indexer.AllTests.class, + org.eclipse.tracecompass.tmf.core.tests.trace.indexer.checkpoint.AllTests.class, + org.eclipse.tracecompass.tmf.core.tests.trace.location.AllTests.class, + org.eclipse.tracecompass.tmf.core.tests.trace.text.AllTests.class, + org.eclipse.tracecompass.tmf.core.tests.uml2sd.AllTests.class, + org.eclipse.tracecompass.tmf.core.tests.util.AllTests.class +}) +public class AllTmfCoreTests { + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/TmfCorePluginTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/TmfCorePluginTest.java new file mode 100644 index 0000000000..0bf03d72e5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/TmfCorePluginTest.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests; + +import static org.junit.Assert.assertEquals; + +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.junit.Test; + +/** + * Test the TMF core plug-in activator + */ +public class TmfCorePluginTest { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // Plug-in instantiation + static final Activator fPlugin = new Activator(); + + // ------------------------------------------------------------------------ + // Test cases + // ------------------------------------------------------------------------ + + /** + * Test the plugin ID. + */ + @Test + public void testTmfCorePluginId() { + assertEquals("Plugin ID", "org.eclipse.tracecompass.tmf.core", Activator.PLUGIN_ID); + } + + /** + * Test the getDefault() static method. + */ + @Test + public void testGetDefault() { + Activator plugin = Activator.getDefault(); + assertEquals("getDefault()", plugin, fPlugin); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/TmfCoreTestPlugin.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/TmfCoreTestPlugin.java new file mode 100644 index 0000000000..b2c4b14479 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/TmfCoreTestPlugin.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests; + +import org.eclipse.core.runtime.Plugin; +import org.eclipse.tracecompass.internal.tmf.core.TmfCoreTracer; +import org.osgi.framework.BundleContext; + +/** + * TmfTestPlugin + *

+ * The activator class controls the plug-in life cycle + */ +public class TmfCoreTestPlugin extends Plugin { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // The plug-in ID + @SuppressWarnings("javadoc") + public static final String PLUGIN_ID = "org.eclipse.tracecompass.tmf.tests"; + + // The shared instance + private static TmfCoreTestPlugin fPlugin; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * The constructor + */ + public TmfCoreTestPlugin() { + setDefault(this); + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * @return the shared instance + */ + public static TmfCoreTestPlugin getDefault() { + return fPlugin; + } + + /** + * @param plugin the shared instance + */ + private static void setDefault(TmfCoreTestPlugin plugin) { + fPlugin = plugin; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + setDefault(this); + TmfCoreTracer.init(); + } + + @Override + public void stop(BundleContext context) throws Exception { + TmfCoreTracer.stop(); + setDefault(null); + super.stop(context); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AllTests.java new file mode 100644 index 0000000000..ee0fc525bc --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AllTests.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.analysis; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Unit tests for the analysis package. + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + AnalysisManagerTest.class, + AnalysisModuleTest.class, + AnalysisModuleHelperTest.class, + AnalysisParameterProviderTest.class, + AnalysisRequirementTest.class, + AnalysisRequirementHelperTest.class +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisManagerTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisManagerTest.java new file mode 100644 index 0000000000..cf7fec7a0d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisManagerTest.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.analysis; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Map; + +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleSource; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.tests.stubs.analysis.AnalysisModuleSourceStub; +import org.eclipse.tracecompass.tmf.tests.stubs.analysis.AnalysisModuleTestHelper; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Test suite for the TmfAnalysisModule class + */ +public class AnalysisManagerTest { + + /** Id of analysis module with parameter */ + public static final String MODULE_PARAM = "org.eclipse.linuxtools.tmf.core.tests.analysis.test"; + /** ID of analysis module with parameter and default value */ + public static final String MODULE_PARAM_DEFAULT = "org.eclipse.linuxtools.tmf.core.tests.analysis.test2"; + /** ID of analysis module for trace 2 classes only */ + public static final String MODULE_SECOND = "org.eclipse.linuxtools.tmf.core.tests.analysis.testother"; + /** Id of analysis module with requirements */ + public static final String MODULE_REQ = "org.eclipse.linuxtools.tmf.core.tests.analysis.reqtest"; + + private ITmfTrace fTrace; + + /** + * Set up some trace code + */ + @Before + public void setupTraces() { + fTrace = TmfTestTrace.A_TEST_10K2.getTraceAsStub2(); + } + + /** + * Some tests use traces, let's clean them here + */ + @After + public void cleanupTraces() { + TmfTestTrace.A_TEST_10K.dispose(); + fTrace.dispose(); + } + + /** + * Test suite for the {@link TmfAnalysisManager#getAnalysisModules()} method + */ + @Test + public void testGetAnalysisModules() { + Map modules = TmfAnalysisManager.getAnalysisModules(); + /* At least 3 modules should be found */ + assertTrue(modules.size() >= 3); + + IAnalysisModuleHelper module = modules.get(MODULE_PARAM_DEFAULT); + assertTrue(module.isAutomatic()); + + module = modules.get(MODULE_PARAM); + assertFalse(module.isAutomatic()); + } + + /** + * Test suite for {@link TmfAnalysisManager#getAnalysisModules(Class)} Use + * the test TMF trace and test trace2 stubs as sample traces + */ + @Test + public void testListForTraces() { + /* Generic TmfTrace */ + ITmfTrace trace = TmfTestTrace.A_TEST_10K.getTrace(); + Map map = TmfAnalysisManager.getAnalysisModules(trace.getClass()); + + assertTrue(map.containsKey(MODULE_PARAM)); + assertTrue(map.containsKey(MODULE_PARAM_DEFAULT)); + assertFalse(map.containsKey(MODULE_SECOND)); + + /* TmfTraceStub2 class */ + map = TmfAnalysisManager.getAnalysisModules(fTrace.getClass()); + + assertTrue(map.containsKey(MODULE_PARAM)); + assertTrue(map.containsKey(MODULE_PARAM_DEFAULT)); + assertTrue(map.containsKey(MODULE_SECOND)); + } + + /** + * Test suite to test refresh of analysis module when adding a {@link IAnalysisModuleSource} + */ + @Test + public void testSources() { + /* Make sure that modules in the new source are not in the list already */ + /* Generic TmfTrace */ + ITmfTrace trace = TmfTestTrace.A_TEST_10K.getTrace(); + Map map = TmfAnalysisManager.getAnalysisModules(trace.getClass()); + + assertFalse(map.containsKey(AnalysisModuleTestHelper.moduleStubEnum.TEST.name())); + + /* TmfTraceStub2 class */ + map = TmfAnalysisManager.getAnalysisModules(fTrace.getClass()); + + assertFalse(map.containsKey(AnalysisModuleTestHelper.moduleStubEnum.TEST2.name())); + + /* Add new source */ + TmfAnalysisManager.registerModuleSource(new AnalysisModuleSourceStub()); + + /* Now make sure the modules are present */ + map = TmfAnalysisManager.getAnalysisModules(trace.getClass()); + assertTrue(map.containsKey(AnalysisModuleTestHelper.moduleStubEnum.TEST.name())); + + map = TmfAnalysisManager.getAnalysisModules(fTrace.getClass()); + assertTrue(map.containsKey(AnalysisModuleTestHelper.moduleStubEnum.TEST2.name())); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisModuleHelperTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisModuleHelperTest.java new file mode 100644 index 0000000000..8774a09123 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisModuleHelperTest.java @@ -0,0 +1,270 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + * Mathieu Rail - Added tests for getting a module's requirements + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.analysis; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.osgi.util.NLS; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper; +import org.eclipse.tracecompass.tmf.core.analysis.Messages; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisModuleHelperConfigElement; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTrace; +import org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestAnalysis; +import org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestAnalysis2; +import org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestRequirementAnalysis; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub2; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub3; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.osgi.framework.Bundle; + +import com.google.common.collect.ImmutableSet; + +/** + * Test suite for the {@link TmfAnalysisModuleHelperConfigElement} class + * + * @author Geneviève Bastien + */ +public class AnalysisModuleHelperTest { + + private IAnalysisModuleHelper fModule; + private IAnalysisModuleHelper fModuleOther; + private IAnalysisModuleHelper fReqModule; + private ITmfTrace fTrace; + + /** + * Gets the module helpers for 2 test modules + */ + @Before + public void getModules() { + fModule = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_PARAM); + assertNotNull(fModule); + assertTrue(fModule instanceof TmfAnalysisModuleHelperConfigElement); + fModuleOther = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_SECOND); + assertNotNull(fModuleOther); + assertTrue(fModuleOther instanceof TmfAnalysisModuleHelperConfigElement); + fReqModule = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_REQ); + assertNotNull(fReqModule); + assertTrue(fReqModule instanceof TmfAnalysisModuleHelperConfigElement); + fTrace = TmfTestTrace.A_TEST_10K2.getTraceAsStub2(); + } + + /** + * Some tests use traces, let's clean them here + */ + @After + public void cleanupTraces() { + TmfTestTrace.A_TEST_10K.dispose(); + fTrace.dispose(); + } + + /** + * Test the helper's getters and setters + */ + @Test + public void testHelperGetters() { + /* With first module */ + assertEquals(AnalysisManagerTest.MODULE_PARAM, fModule.getId()); + assertEquals("Test analysis", fModule.getName()); + assertFalse(fModule.isAutomatic()); + + Bundle helperbundle = fModule.getBundle(); + Bundle thisbundle = Platform.getBundle("org.eclipse.tracecompass.tmf.core.tests"); + assertNotNull(helperbundle); + assertEquals(thisbundle, helperbundle); + + /* With other module */ + assertEquals(AnalysisManagerTest.MODULE_SECOND, fModuleOther.getId()); + assertEquals("Test other analysis", fModuleOther.getName()); + assertTrue(fModuleOther.isAutomatic()); + } + + /** + * Test the + * {@link TmfAnalysisModuleHelperConfigElement#appliesToTraceType(Class)} + * method for the 2 modules + */ + @Test + public void testAppliesToTrace() { + /* stub module */ + assertFalse(fModule.appliesToTraceType(TmfTrace.class)); + assertTrue(fModule.appliesToTraceType(TmfTraceStub.class)); + assertTrue(fModule.appliesToTraceType(TmfTraceStub2.class)); + assertFalse(fModule.appliesToTraceType(TmfTraceStub3.class)); + + /* stub module 2 */ + assertFalse(fModuleOther.appliesToTraceType(TmfTrace.class)); + assertFalse(fModuleOther.appliesToTraceType(TmfTraceStub.class)); + assertTrue(fModuleOther.appliesToTraceType(TmfTraceStub2.class)); + assertTrue(fModuleOther.appliesToTraceType(TmfTraceStub3.class)); + } + + /** + * Test the + * {@link TmfAnalysisModuleHelperConfigElement#newModule(ITmfTrace)} method + * for the 2 modules + */ + @Test + public void testNewModule() { + /* Test analysis module with traceStub */ + Exception exception = null; + try (IAnalysisModule module = fModule.newModule(TmfTestTrace.A_TEST_10K.getTrace());) { + assertNotNull(module); + assertTrue(module instanceof TestAnalysis); + } catch (TmfAnalysisException e) { + exception = e; + } + assertNull(exception); + + /* TestAnalysis2 module with trace, should return an exception */ + try (IAnalysisModule module = fModuleOther.newModule(TmfTestTrace.A_TEST_10K.getTrace());) { + } catch (TmfAnalysisException e) { + exception = e; + } + assertNotNull(exception); + assertEquals(NLS.bind(Messages.TmfAnalysisModuleHelper_AnalysisDoesNotApply, fModuleOther.getName()), exception.getMessage()); + + /* TestAnalysis2 module with a TraceStub2 */ + exception = null; + try (IAnalysisModule module = fModuleOther.newModule(fTrace);) { + assertNotNull(module); + assertTrue(module instanceof TestAnalysis2); + } catch (TmfAnalysisException e) { + exception = e; + } + assertNull(exception); + } + + /** + * Test for the initialization of parameters from the extension points + */ + @Test + public void testParameters() { + ITmfTrace trace = TmfTestTrace.A_TEST_10K.getTrace(); + + /* + * This analysis has a parameter, but no default value. we should be + * able to set the parameter + */ + IAnalysisModuleHelper helper = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_PARAM); + try (IAnalysisModule module = helper.newModule(trace);) { + assertNull(module.getParameter(TestAnalysis.PARAM_TEST)); + module.setParameter(TestAnalysis.PARAM_TEST, 1); + assertEquals(1, module.getParameter(TestAnalysis.PARAM_TEST)); + + } catch (TmfAnalysisException e1) { + fail(e1.getMessage()); + return; + } + + /* This module has a parameter with default value */ + helper = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_PARAM_DEFAULT); + try (IAnalysisModule module = helper.newModule(trace);) { + assertEquals(3, module.getParameter(TestAnalysis.PARAM_TEST)); + module.setParameter(TestAnalysis.PARAM_TEST, 1); + assertEquals(1, module.getParameter(TestAnalysis.PARAM_TEST)); + + } catch (TmfAnalysisException e1) { + fail(e1.getMessage()); + return; + } + + /* + * This module does not have a parameter so setting it should throw an + * error + */ + helper = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_SECOND); + Exception exception = null; + try (IAnalysisModule module = helper.newModule(fTrace);) { + + assertNull(module.getParameter(TestAnalysis.PARAM_TEST)); + + try { + module.setParameter(TestAnalysis.PARAM_TEST, 1); + } catch (RuntimeException e) { + exception = e; + } + } catch (TmfAnalysisException e1) { + fail(e1.getMessage()); + return; + } + assertNotNull(exception); + } + + /** + * Test for the + * {@link TmfAnalysisModuleHelperConfigElement#getValidTraceTypes} method + */ + @Test + public void testGetValidTraceTypes() { + Set> expected = ImmutableSet.of((Class) TmfTraceStub.class, TmfTraceStub2.class, TmfTraceStub3.class); + Iterable> traceTypes = fReqModule.getValidTraceTypes(); + assertEquals(expected, traceTypes); + } + + /** + * Test for the + * {@link TmfAnalysisModuleHelperConfigElement#getAnalysisRequirements} + * method + */ + @Test + public void testGetRequirements() { + Iterable requirements = fReqModule.getAnalysisRequirements(); + assertNotNull(requirements); + + Map rMap = new HashMap<>(); + + for (TmfAnalysisRequirement req : requirements) { + assertFalse(rMap.containsKey(req.getType())); + rMap.put(req.getType(), req); + } + assertEquals(2, rMap.size()); + + /* Test if all types and values have been obtained */ + TmfAnalysisRequirement req = rMap.get(TestRequirementAnalysis.EVENT_TYPE); + assertNotNull(req); + + Set values = req.getValues(); + assertEquals(3, values.size()); + assertTrue(values.contains(TestRequirementAnalysis.EXIT_SYSCALL)); + assertTrue(values.contains(TestRequirementAnalysis.SCHED_SWITCH)); + assertTrue(values.contains(TestRequirementAnalysis.SCHED_WAKEUP)); + + req = rMap.get(TestRequirementAnalysis.FIELD_TYPE); + assertNotNull(req); + + values = req.getValues(); + assertEquals(2, values.size()); + assertTrue(values.contains(TestRequirementAnalysis.PID)); + assertTrue(values.contains(TestRequirementAnalysis.TID)); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisModuleTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisModuleTest.java new file mode 100644 index 0000000000..7ba522a4cb --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisModuleTest.java @@ -0,0 +1,257 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.analysis; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.osgi.util.NLS; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; +import org.eclipse.tracecompass.tmf.core.analysis.Messages; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestHelper; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestAnalysis; +import org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestAnalysis2; +import org.junit.After; +import org.junit.Test; + +/** + * Test suite for the {@link TmfAbstractAnalysisModule} class + */ +public class AnalysisModuleTest { + + private static String MODULE_GENERIC_ID = "test.id"; + private static String MODULE_GENERIC_NAME = "Test analysis"; + + /** + * Some tests use traces, let's clean them here + */ + @After + public void cleanupTraces() { + TmfTestTrace.A_TEST_10K.dispose(); + } + + /** + * Test suite for analysis module getters and setters + */ + @Test + public void testGettersSetters() { + try (IAnalysisModule module = new TestAnalysis();) { + + module.setName(MODULE_GENERIC_NAME); + module.setId(MODULE_GENERIC_ID); + assertEquals(MODULE_GENERIC_ID, module.getId()); + assertEquals(MODULE_GENERIC_NAME, module.getName()); + + module.setAutomatic(false); + assertFalse(module.isAutomatic()); + module.setAutomatic(true); + assertTrue(module.isAutomatic()); + module.addParameter(TestAnalysis.PARAM_TEST); + assertNull(module.getParameter(TestAnalysis.PARAM_TEST)); + module.setParameter(TestAnalysis.PARAM_TEST, 1); + assertEquals(1, module.getParameter(TestAnalysis.PARAM_TEST)); + + /* Try to set and get wrong parameter */ + String wrongParam = "abc"; + Exception exception = null; + try { + module.setParameter(wrongParam, 1); + } catch (RuntimeException e) { + exception = e; + assertEquals(NLS.bind(Messages.TmfAbstractAnalysisModule_InvalidParameter, wrongParam, module.getName()), e.getMessage()); + } + assertNotNull(exception); + assertNull(module.getParameter(wrongParam)); + } + } + + private static TestAnalysis setUpAnalysis() { + TestAnalysis module = new TestAnalysis(); + + module.setName(MODULE_GENERIC_NAME); + module.setId(MODULE_GENERIC_ID); + module.addParameter(TestAnalysis.PARAM_TEST); + + return module; + } + + /** + * Test suite for analysis module + * {@link TmfAbstractAnalysisModule#waitForCompletion} with successful + * execution + */ + @Test + public void testWaitForCompletionSuccess() { + try (TestAnalysis module = setUpAnalysis();) { + + IStatus status = module.schedule(); + assertEquals(IStatus.ERROR, status.getSeverity()); + + /* Set a stub trace for analysis */ + try { + module.setTrace(TmfTestTrace.A_TEST_10K.getTrace()); + } catch (TmfAnalysisException e) { + fail(e.getMessage()); + } + + /* Default execution, with output 1 */ + module.setParameter(TestAnalysis.PARAM_TEST, 1); + status = module.schedule(); + assertEquals(Status.OK_STATUS, status); + boolean completed = module.waitForCompletion(); + + assertTrue(completed); + assertEquals(1, module.getAnalysisOutput()); + } + } + + /** + * Test suite for {@link TmfAbstractAnalysisModule#waitForCompletion} with cancellation + */ + @Test + public void testWaitForCompletionCancelled() { + try (TestAnalysis module = setUpAnalysis();) { + + /* Set a stub trace for analysis */ + ITmfTrace trace = TmfTestTrace.A_TEST_10K.getTrace(); + try { + module.setTrace(trace); + } catch (TmfAnalysisException e) { + fail(e.getMessage()); + } + + module.setParameter(TestAnalysis.PARAM_TEST, 0); + IStatus status = module.schedule(); + assertEquals(Status.OK_STATUS, status); + boolean completed = module.waitForCompletion(); + + assertFalse(completed); + assertEquals(0, module.getAnalysisOutput()); + } + } + + /** + * Test the {@link TmfAbstractAnalysisModule#setTrace(ITmfTrace)} method with wrong trace + */ + @Test + public void testSetWrongTrace() { + try (IAnalysisModule module = new TestAnalysis2();) { + + module.setName(MODULE_GENERIC_NAME); + module.setId(MODULE_GENERIC_ID); + assertEquals(MODULE_GENERIC_ID, module.getId()); + assertEquals(MODULE_GENERIC_NAME, module.getName()); + + Exception exception = null; + try { + module.setTrace(TmfTestTrace.A_TEST_10K.getTrace()); + } catch (TmfAnalysisException e) { + exception = e; + } + assertNotNull(exception); + assertEquals(NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisCannotExecute, module.getName()), exception.getMessage()); + } + } + + /** + * Test suite for the {@link TmfAbstractAnalysisModule#cancel()} method + */ + @Test + public void testCancel() { + try (TestAnalysis module = setUpAnalysis();) { + + module.setParameter(TestAnalysis.PARAM_TEST, 999); + try { + module.setTrace(TmfTestTrace.A_TEST_10K.getTrace()); + } catch (TmfAnalysisException e) { + fail(e.getMessage()); + } + + assertEquals(Status.OK_STATUS, module.schedule()); + + /* Give the job a chance to start */ + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + fail(e.getMessage()); + } + + module.cancel(); + assertFalse(module.waitForCompletion()); + assertEquals(-1, module.getAnalysisOutput()); + } + } + + /** + * Test suite for the {@link IAnalysisModule#notifyParameterChanged(String)} + * method + */ + @Test + public void testParameterChanged() { + try (TestAnalysis module = setUpAnalysis();) { + + try { + module.setTrace(TmfTestTrace.A_TEST_10K.getTrace()); + } catch (TmfAnalysisException e) { + fail(e.getMessage()); + } + + /* Check exception if no wrong parameter name */ + Exception exception = null; + try { + module.notifyParameterChanged("aaa"); + } catch (RuntimeException e) { + exception = e; + } + assertNotNull(exception); + + /* + * Cannot test anymore of this method, need a parameter provider to + * do this + */ + } + } + + /** + * Test the {@link TmfTestHelper#executeAnalysis(IAnalysisModule)} method + */ + @Test + public void testHelper() { + try (TestAnalysis module = setUpAnalysis();) { + + try { + module.setTrace(TmfTestTrace.A_TEST_10K.getTrace()); + } catch (TmfAnalysisException e) { + fail(e.getMessage()); + } + + module.setParameter(TestAnalysis.PARAM_TEST, 1); + boolean res = TmfTestHelper.executeAnalysis(module); + assertTrue(res); + + module.setParameter(TestAnalysis.PARAM_TEST, 0); + res = TmfTestHelper.executeAnalysis(module); + assertFalse(res); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisParameterProviderTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisParameterProviderTest.java new file mode 100644 index 0000000000..9c0840878d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisParameterProviderTest.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.analysis; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisParameterProvider; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestAnalysis; +import org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestAnalysisParameterProvider; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Test the TmfAbstractParameterProvider class + * + * @author Geneviève Bastien + */ +public class AnalysisParameterProviderTest { + + /** + * Registers the parameter provider + */ + @Before + public void setup() { + TmfAnalysisManager.registerParameterProvider(AnalysisManagerTest.MODULE_PARAM, TestAnalysisParameterProvider.class); + } + + /** + * Cleanup the trace after testing + */ + @After + public void cleanupTrace() { + TmfTestTrace.A_TEST_10K.dispose(); + } + + /** + * Test that the provider's value is used + */ + @Test + public void testProviderTmfTrace() { + ITmfTrace trace = TmfTestTrace.A_TEST_10K.getTrace(); + /* Make sure the value is set to null */ + IAnalysisModuleHelper helper = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_PARAM); + try (IAnalysisModule module = helper.newModule(trace);) { + + assertEquals(10, module.getParameter(TestAnalysis.PARAM_TEST)); + + /* Change the value of the parameter in the provider */ + List providers = TmfAnalysisManager.getParameterProviders(module, trace); + assertEquals(1, providers.size()); + TestAnalysisParameterProvider provider = (TestAnalysisParameterProvider) providers.get(0); + provider.setValue(5); + assertEquals(5, module.getParameter(TestAnalysis.PARAM_TEST)); + + } catch (TmfAnalysisException e) { + fail(e.getMessage()); + return; + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisRequirementHelperTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisRequirementHelperTest.java new file mode 100644 index 0000000000..4a14eff57f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisRequirementHelperTest.java @@ -0,0 +1,182 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Guilliano Molaire - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.analysis; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisRequirementProvider; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirementHelper; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement.ValuePriorityLevel; +import org.eclipse.tracecompass.tmf.tests.stubs.analysis.AnalysisModuleTestHelper; +import org.eclipse.tracecompass.tmf.tests.stubs.analysis.AnalysisRequirementFactory; +import org.eclipse.tracecompass.tmf.tests.stubs.analysis.AnalysisModuleTestHelper.moduleStubEnum; +import org.junit.Before; +import org.junit.Test; + +import com.google.common.collect.Multimap; + +/** + * Test suite for the {@link TmfAnalysisRequirementHelper} class + */ +public class AnalysisRequirementHelperTest { + + private AnalysisModuleTestHelper fTestModuleHelper; + private AnalysisModuleTestHelper fTestModuleHelper2; + + /** + * Set up analysis modules + */ + @Before + public void setUpTest() { + fTestModuleHelper = new AnalysisModuleTestHelper(moduleStubEnum.TEST); + fTestModuleHelper2 = new AnalysisModuleTestHelper(moduleStubEnum.TEST2); + } + + /** + * Test suite for the + * {@link TmfAnalysisRequirementHelper#getRequirementValues(IAnalysisRequirementProvider, String)} + * method + */ + @Test + public void testGetRequirementValues() { + /* Test with a supported type */ + String type = AnalysisRequirementFactory.REQUIREMENT_TYPE_1; + Set values = TmfAnalysisRequirementHelper.getRequirementValues(fTestModuleHelper, type); + assertEquals(AnalysisRequirementFactory.REQUIREMENT_VALUES_1.size(), values.size()); + + /* Test with a type not supported */ + type = AnalysisRequirementFactory.REQUIREMENT_TYPE_2; + values = TmfAnalysisRequirementHelper.getRequirementValues(fTestModuleHelper, type); + assertTrue(values.isEmpty()); + } + + /** + * Test suite for the + * {@link TmfAnalysisRequirementHelper#getRequirementValues(IAnalysisRequirementProvider, String, ValuePriorityLevel)} + * method + */ + @Test + public void testGetRequirementValuesWithLevel() { + /* Test with a supported type */ + String type = AnalysisRequirementFactory.REQUIREMENT_TYPE_2; + Set values = TmfAnalysisRequirementHelper.getRequirementValues(fTestModuleHelper2, type, ValuePriorityLevel.MANDATORY); + assertEquals(3, values.size()); + + /* Test with another value level */ + values = TmfAnalysisRequirementHelper.getRequirementValues(fTestModuleHelper2, type, ValuePriorityLevel.OPTIONAL); + assertEquals(2, values.size()); + + /* Test with a type not supported */ + type = AnalysisRequirementFactory.REQUIREMENT_TYPE_1; + values = TmfAnalysisRequirementHelper.getRequirementValues(fTestModuleHelper2, type, ValuePriorityLevel.MANDATORY); + assertTrue(values.isEmpty()); + } + + /** + * Test suite for the + * {@link TmfAnalysisRequirementHelper#getRequirementValuesMap(Iterable)} + * method + */ + @Test + public void testGetRequirementValuesMap() { + Set providers = new HashSet<>(); + providers.add(fTestModuleHelper2); + providers.add(fTestModuleHelper); + + Multimap valuesByType = TmfAnalysisRequirementHelper.getRequirementValuesMap(providers); + assertFalse(valuesByType.isEmpty()); + + /* There should be 3 types */ + assertEquals(3, valuesByType.keySet().size()); + + Collection values = valuesByType.get(AnalysisRequirementFactory.REQUIREMENT_TYPE_1); + assertEquals(4, values.size()); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_1)); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_2)); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_3)); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_5)); + + values = valuesByType.get(AnalysisRequirementFactory.REQUIREMENT_TYPE_2); + assertEquals(5, values.size()); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_1)); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_2)); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_3)); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_4)); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_5)); + + values = valuesByType.get(AnalysisRequirementFactory.REQUIREMENT_TYPE_3); + assertEquals(3, values.size()); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_3)); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_4)); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_5)); + } + + /** + * Test suite for the + * {@link TmfAnalysisRequirementHelper#getRequirementValuesMap(Iterable, ValuePriorityLevel)} + * method + */ + @Test + public void testGetRequirementValuesMapWithLevel() { + Set providers = new HashSet<>(); + providers.add(fTestModuleHelper2); + providers.add(fTestModuleHelper); + + /* There should be 3 optional requirements types */ + Multimap valuesByType = TmfAnalysisRequirementHelper.getRequirementValuesMap(providers, ValuePriorityLevel.OPTIONAL); + assertTrue(!valuesByType.isEmpty()); + assertEquals(1, valuesByType.keySet().size()); + + Collection values = valuesByType.get(AnalysisRequirementFactory.REQUIREMENT_TYPE_1); + assertTrue(values.isEmpty()); + + values = valuesByType.get(AnalysisRequirementFactory.REQUIREMENT_TYPE_2); + assertEquals(2, values.size()); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_2)); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_4)); + + values = valuesByType.get(AnalysisRequirementFactory.REQUIREMENT_TYPE_3); + assertTrue(values.isEmpty()); + + /* And 3 types with mandatory requirements */ + valuesByType = TmfAnalysisRequirementHelper.getRequirementValuesMap(providers, ValuePriorityLevel.MANDATORY); + assertTrue(!valuesByType.isEmpty()); + assertEquals(3, valuesByType.keySet().size()); + + values = valuesByType.get(AnalysisRequirementFactory.REQUIREMENT_TYPE_1); + assertEquals(4, values.size()); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_1)); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_2)); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_3)); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_5)); + + values = valuesByType.get(AnalysisRequirementFactory.REQUIREMENT_TYPE_2); + assertEquals(3, values.size()); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_1)); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_3)); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_5)); + + values = valuesByType.get(AnalysisRequirementFactory.REQUIREMENT_TYPE_3); + assertEquals(3, values.size()); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_3)); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_4)); + assertTrue(values.contains(AnalysisRequirementFactory.REQUIREMENT_VALUE_5)); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisRequirementTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisRequirementTest.java new file mode 100644 index 0000000000..5f7be2e40c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisRequirementTest.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Guilliano Molaire - Initial API and implementation + * Mathieu Rail - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.analysis; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement.ValuePriorityLevel; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * Test suite for the {@link TmfAnalysisRequirement} class. + * + * @author Guilliano Molaire + * @author Mathieu Rail + */ +public class AnalysisRequirementTest { + + /* Requirements used in the tests */ + private TmfAnalysisRequirement fRequirement; + private TmfAnalysisRequirement fSubRequirement; + + /* Types of requirement type strings */ + private static final String TYPE_A = "Test Type A"; + private static final String TYPE_B = "Test Type B"; + + /* Requirement value name strings */ + private static final String VALUE_A = "Test Value A"; + private static final String VALUE_B = "Test Value B"; + private static final String VALUE_C = "Test Value C"; + private static final String VALUE_D = "Test Value D"; + private static final String VALUE_E = "Test Value E"; + private static final String VALUE_F = "Test Value F"; + + /* Requirement information strings */ + private static final String INFO_A = "This is an information."; + private static final String INFO_B = "This is another information."; + private static final String INFO_C = "This is the last information."; + + /** + * Test suite for the {@link TmfAnalysisRequirement#addInformation} and the + * {@link TmfAnalysisRequirement#getInformation} methods. + */ + @Test + public void testAddAndGetInformation() { + fRequirement = new TmfAnalysisRequirement(TYPE_A); + + fRequirement.addInformation(INFO_A); + fRequirement.addInformation(INFO_B); + fRequirement.addInformation(INFO_B); + + Set information = fRequirement.getInformation(); + + assertEquals(2, information.size()); + + assertTrue(information.contains(INFO_A)); + assertTrue(information.contains(INFO_B)); + } + + /** + * Test suite for the {@link TmfAnalysisRequirement#addValues} and the + * {@link TmfAnalysisRequirement#addValue} methods. + */ + @Test + public void testAddValuesToRequirement() { + fRequirement = new TmfAnalysisRequirement(TYPE_A); + + assertEquals(0, fRequirement.getValues().size()); + + List values = new ArrayList<>(); + values.add(VALUE_A); + values.add(VALUE_B); + values.add(VALUE_C); + values.add(VALUE_C); + + /* + * Add values to the requirement with the same level, Value C should + * only exist once + */ + fRequirement.addValues(values, ValuePriorityLevel.MANDATORY); + assertEquals(3, fRequirement.getValues().size()); + + /* + * The new value should only exist once and its level should be + * mandatory + */ + fRequirement.addValue(VALUE_D, ValuePriorityLevel.OPTIONAL); + fRequirement.addValue(VALUE_D, ValuePriorityLevel.MANDATORY); + + assertEquals(4, fRequirement.getValues().size()); + assertEquals(ValuePriorityLevel.MANDATORY, fRequirement.getValueLevel(VALUE_D)); + } + + /** + * Test suite for the {@link TmfAnalysisRequirement#getValueLevel} method. + */ + @Test + public void testGetValueLevel() { + fRequirement = new TmfAnalysisRequirement(TYPE_A); + fRequirement.addValue(VALUE_A, ValuePriorityLevel.OPTIONAL); + + /* Try to get the level of a value */ + assertEquals(ValuePriorityLevel.OPTIONAL, fRequirement.getValueLevel(VALUE_A)); + + /* Try to get the level of a value that doesn't exist */ + assertNull(fRequirement.getValueLevel(VALUE_B)); + } + + /** + * Test suite for the {@link TmfAnalysisRequirement#merge} method with the + * parameter value MANDATORY. + */ + @Test + public void testMergeMandatory() { + initMergeRequirements(TYPE_A, TYPE_A); + + assertTrue(fRequirement.merge(fSubRequirement, ValuePriorityLevel.MANDATORY)); + + assertEquals(fRequirement.getValues().size(), 6); + + assertEquals(ValuePriorityLevel.MANDATORY, fRequirement.getValueLevel(VALUE_A)); + assertEquals(ValuePriorityLevel.MANDATORY, fRequirement.getValueLevel(VALUE_B)); + + assertEquals(ValuePriorityLevel.MANDATORY, fRequirement.getValueLevel(VALUE_C)); + assertEquals(ValuePriorityLevel.OPTIONAL, fRequirement.getValueLevel(VALUE_D)); + + assertEquals(ValuePriorityLevel.MANDATORY, fRequirement.getValueLevel(VALUE_E)); + assertEquals(ValuePriorityLevel.OPTIONAL, fRequirement.getValueLevel(VALUE_F)); + + Set information = fRequirement.getInformation(); + + assertEquals(3, information.size()); + + assertTrue(information.contains(INFO_A)); + assertTrue(information.contains(INFO_B)); + assertTrue(information.contains(INFO_C)); + } + + /** + * Test suite for the {@link TmfAnalysisRequirement#merge} method with the + * parameter value OPTIONAL. + */ + @Test + public void testMergeOptional() { + initMergeRequirements(TYPE_A, TYPE_A); + + assertTrue(fRequirement.merge(fSubRequirement, ValuePriorityLevel.OPTIONAL)); + + assertEquals(6, fRequirement.getValues().size()); + + assertEquals(ValuePriorityLevel.MANDATORY, fRequirement.getValueLevel(VALUE_A)); + assertEquals(ValuePriorityLevel.MANDATORY, fRequirement.getValueLevel(VALUE_B)); + + assertEquals(ValuePriorityLevel.OPTIONAL, fRequirement.getValueLevel(VALUE_C)); + assertEquals(ValuePriorityLevel.OPTIONAL, fRequirement.getValueLevel(VALUE_D)); + + assertEquals(ValuePriorityLevel.OPTIONAL, fRequirement.getValueLevel(VALUE_E)); + assertEquals(ValuePriorityLevel.OPTIONAL, fRequirement.getValueLevel(VALUE_F)); + + Set information = fRequirement.getInformation(); + + assertEquals(3, information.size()); + + assertTrue(information.contains(INFO_A)); + assertTrue(information.contains(INFO_B)); + assertTrue(information.contains(INFO_C)); + } + + /** + * Test suite for the {@link TmfAnalysisRequirement#merge} method with + * different requirement types. + */ + @Test + public void testMergeDifferentTypes() { + initMergeRequirements(TYPE_A, TYPE_B); + + assertFalse(fRequirement.merge(fSubRequirement, ValuePriorityLevel.OPTIONAL)); + } + + /** + * Test suite for the {@link TmfAnalysisRequirement#isSameType} method. + */ + @Test + public void testIsSameRequirementType() { + fRequirement = new TmfAnalysisRequirement(TYPE_A); + + assertTrue(fRequirement.isSameType(new TmfAnalysisRequirement(TYPE_A))); + assertFalse(fRequirement.isSameType(new TmfAnalysisRequirement(TYPE_B))); + } + + /** + * Initialize the requirement and sub-requirement for the merge tests. + * + * @param typeA + * The type of the first requirement + * @param typeB + * The type of the second requirement + */ + private void initMergeRequirements(String typeA, String typeB) { + fRequirement = new TmfAnalysisRequirement(typeA); + fRequirement.addValue(VALUE_A, ValuePriorityLevel.MANDATORY); + fRequirement.addValue(VALUE_B, ValuePriorityLevel.MANDATORY); + + fRequirement.addValue(VALUE_C, ValuePriorityLevel.OPTIONAL); + fRequirement.addValue(VALUE_D, ValuePriorityLevel.OPTIONAL); + + fRequirement.addInformation(INFO_A); + fRequirement.addInformation(INFO_B); + + /* This sub-requirement will be merged into requirement */ + fSubRequirement = new TmfAnalysisRequirement(typeB); + fSubRequirement.addValue(VALUE_A, ValuePriorityLevel.MANDATORY); + fSubRequirement.addValue(VALUE_B, ValuePriorityLevel.OPTIONAL); + + fSubRequirement.addValue(VALUE_C, ValuePriorityLevel.MANDATORY); + fSubRequirement.addValue(VALUE_D, ValuePriorityLevel.OPTIONAL); + + fSubRequirement.addValue(VALUE_E, ValuePriorityLevel.MANDATORY); + fSubRequirement.addValue(VALUE_F, ValuePriorityLevel.OPTIONAL); + + fSubRequirement.addInformation(INFO_B); + fSubRequirement.addInformation(INFO_C); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/component/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/component/AllTests.java new file mode 100644 index 0000000000..b163bfce7d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/component/AllTests.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.component; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Unit tests for the component package. + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TmfEventProviderTest.class, + TmfProviderManagerTest.class +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/component/TmfEventProviderTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/component/TmfEventProviderTest.java new file mode 100644 index 0000000000..78d158aa4f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/component/TmfEventProviderTest.java @@ -0,0 +1,362 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.component; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.util.Vector; + +import org.eclipse.tracecompass.internal.tmf.core.component.TmfProviderManager; +import org.eclipse.tracecompass.tmf.core.component.ITmfEventProvider; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType; +import org.eclipse.tracecompass.tmf.core.signal.TmfEndSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfStartSynchSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.tests.stubs.component.TmfEventProviderStub; +import org.eclipse.tracecompass.tmf.tests.stubs.component.TmfSyntheticEventProviderStub; +import org.eclipse.tracecompass.tmf.tests.stubs.event.TmfSyntheticEventStub; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Test suite for the TmfEventProvider class. + */ +public class TmfEventProviderTest { + + private TmfEventProviderStub fEventProvider; + private TmfSyntheticEventProviderStub fSyntheticEventProvider; + + /** + * Initialization + * + * @throws IOException + * If we can't find the test trace (they are committed in the + * tree, so it shouldn't happen). + */ + @Before + public void setUp() throws IOException { + fEventProvider = new TmfEventProviderStub(); + fSyntheticEventProvider = new TmfSyntheticEventProviderStub(); + } + + /** + * Clean-up + */ + @After + public void tearDown() { + fEventProvider.dispose(); + fSyntheticEventProvider.dispose(); + } + + // ------------------------------------------------------------------------ + // getProviders (more a sanity check than a test) + // ------------------------------------------------------------------------ + + /** + * Test getProviders + */ + @Test + public void testGetProviders() { + // There should be 2 TmfEvent providers: a TmfTraceStub and a + // TmfEventProviderStub + ITmfEventProvider[] eventProviders = TmfProviderManager.getProviders(ITmfEvent.class); + assertEquals("getProviders", 2, eventProviders.length); + + eventProviders = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); + assertEquals("getProviders", 1, eventProviders.length); + + eventProviders = TmfProviderManager.getProviders(ITmfEvent.class, TmfEventProviderStub.class); + assertEquals("getProviders", 1, eventProviders.length); + + // There should be 1 TmfSyntheticEventStub provider + eventProviders = TmfProviderManager.getProviders(TmfSyntheticEventStub.class); + assertEquals("getProviders", 1, eventProviders.length); + } + + // ------------------------------------------------------------------------ + // getSyntheticEvent + // ------------------------------------------------------------------------ + + /** + * Test getPlainEvents + */ + @Test + public void testGetPlainEvents() { + final int NB_EVENTS = 1000; + final Vector requestedEvents = new Vector<>(); + + // Get the TmfSyntheticEventStub provider + ITmfEventProvider[] eventProviders = TmfProviderManager.getProviders(ITmfEvent.class, + TmfEventProviderStub.class); + ITmfEventProvider provider = eventProviders[0]; + + TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, + range, 0, NB_EVENTS, ExecutionType.FOREGROUND) { + @Override + public void handleData(ITmfEvent event) { + super.handleData(event); + requestedEvents.add(event); + } + }; + + provider.sendRequest(request); + try { + request.waitForCompletion(); + assertEquals("nbEvents", NB_EVENTS, requestedEvents.size()); + assertTrue("isCompleted", request.isCompleted()); + assertFalse("isCancelled", request.isCancelled()); + + // Make that we have distinct events. + // Don't go overboard: we are not validating the stub! + for (int i = 0; i < NB_EVENTS; i++) { + assertEquals("Distinct events", i + 1, requestedEvents.get(i).getTimestamp().getValue()); + } + } catch (InterruptedException e) { + fail(); + } + } + + /** + * Test canceling requests. + */ + @Test + public void testCancelRequests() { + final int NB_EVENTS = 1000; + final int NUMBER_EVENTS_BEFORE_CANCEL_REQ1 = 10; + final int NUMBER_EVENTS_BEFORE_CANCEL_REQ2 = 800; + + final Vector requestedEventsReq1 = new Vector<>(); + final Vector requestedEventsReq2 = new Vector<>(); + + // Get the TmfSyntheticEventStub provider + ITmfEventProvider[] eventProviders = TmfProviderManager.getProviders(ITmfEvent.class, + TmfEventProviderStub.class); + ITmfEventProvider provider = eventProviders[0]; + + TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + + // Create first request + final TmfEventRequest request1 = new TmfEventRequest(ITmfEvent.class, + range, 0, NB_EVENTS, ExecutionType.FOREGROUND) { + @Override + public void handleData(ITmfEvent event) { + super.handleData(event); + requestedEventsReq1.add(event); + + // cancel sub request + if (getNbRead() == NUMBER_EVENTS_BEFORE_CANCEL_REQ1) { + cancel(); + } + } + }; + + // Synchronize requests + ((TmfEventProviderStub) provider).startSynch(new TmfStartSynchSignal(0)); + + // Additionally, notify provider for up-coming requests + provider.notifyPendingRequest(true); + + // Call sendRequest, which will create a coalescing request, but it + // doesn't send request1 yet + provider.sendRequest(request1); + + // Check if request1 is not running yet. + assertFalse("isRunning", request1.isRunning()); + + // Create second request + final TmfEventRequest request2 = new TmfEventRequest(ITmfEvent.class, + range, 0, NB_EVENTS, ExecutionType.FOREGROUND) { + @Override + public void handleData(ITmfEvent event) { + super.handleData(event); + requestedEventsReq2.add(event); + + // cancel sub request which will cancel also main request + if (getNbRead() == NUMBER_EVENTS_BEFORE_CANCEL_REQ2) { + cancel(); + } + } + }; + + // Call sendRequest, which will create a coalescing request, but it + // doesn't send request2 yet + provider.sendRequest(request2); + + // Check if request1/2 is not running yet. + assertFalse("isRunning", request1.isRunning()); + assertFalse("isRunning", request2.isRunning()); + + // Send end synch signal, however requests won't be sent + ((TmfEventProviderStub) provider).endSynch(new TmfEndSynchSignal(0)); + + // Check if request1/2 is not running yet. + assertFalse("isRunning", request1.isRunning()); + assertFalse("isRunning", request2.isRunning()); + + // Finally, trigger sending of requests + provider.notifyPendingRequest(false); + + try { + + // Wait until requests start + request1.waitForStart(); + request2.waitForStart(); + +// // Verify that the requests are running +// assertTrue("isRunning", request1.isRunning()); +// assertTrue("isRunning", request2.isRunning()); + + request1.waitForCompletion(); + +// // Check if request2 is still running +// assertTrue("isRunning", request2.isRunning()); + + // Verify result (request1) + assertEquals("nbEvents", NUMBER_EVENTS_BEFORE_CANCEL_REQ1, requestedEventsReq1.size()); + assertTrue("isCompleted", request1.isCompleted()); + assertTrue("isCancelled", request1.isCancelled()); + + request2.waitForCompletion(); + + // Verify result (request2) + assertEquals("nbEvents", NUMBER_EVENTS_BEFORE_CANCEL_REQ2, requestedEventsReq2.size()); + assertTrue("isCompleted", request2.isCompleted()); + assertTrue("isCancelled", request2.isCancelled()); + + } catch (InterruptedException e) { + fail(); + } + } + + private static void getSyntheticData(final TmfTimeRange range, + final int nbEvents) throws InterruptedException { + + final Vector requestedEvents = new Vector<>(); + + // Get the event provider + ITmfEventProvider[] eventProviders = TmfProviderManager + .getProviders(TmfSyntheticEventStub.class); + ITmfEventProvider provider = eventProviders[0]; + + final TmfEventRequest request = new TmfEventRequest(TmfSyntheticEventStub.class, range, + 0, nbEvents, ExecutionType.FOREGROUND) { + @Override + public void handleData(ITmfEvent event) { + super.handleData(event); + requestedEvents.add(event); + } + }; + provider.sendRequest(request); + + request.waitForCompletion(); + if (nbEvents != -1) { + assertEquals("nbEvents", nbEvents, requestedEvents.size()); + } + assertTrue("isCompleted", request.isCompleted()); + assertFalse("isCancelled", request.isCancelled()); + + // For each base event, the stub will queue 2 identical synthetic events + // Ensure that the events are queued properly. + // Don't go overboard: we are not validating the stub! + for (int i = 0; i < (nbEvents / 2); i++) { + assertEquals("Distinct events", i + 1, requestedEvents.get(2 * i + 0).getTimestamp().getValue()); + assertEquals("Distinct events", i + 1, requestedEvents.get(2 * i + 1).getTimestamp().getValue()); + } + } + + /** + * Test getSyntheticEvents for equal block sizes. + */ + @Test + public void testGetSyntheticEvents_EqualBlockSizes() { + TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + try { + getSyntheticData(range, 1000); + } catch (InterruptedException e) { + fail(); + } + } + + /** + * Test getSyntheticEvents + */ + @Test + public void testGetSyntheticEvents_TimeRange() { + TmfTimestamp start = new TmfTimestamp(1, (byte) -3, 0); + TmfTimestamp end = new TmfTimestamp(1000, (byte) -3, 0); + TmfTimeRange range = new TmfTimeRange(start, end); + try { + getSyntheticData(range, -1); + } catch (InterruptedException e) { + fail(); + } + } + +// public void testGetSyntheticEvents_WeirdTimeRange1() { +// TmfTimestamp start = TmfTimestamp.BigBang; +// TmfTimestamp end = TmfTimestamp.Zero; // new TmfTimestamp(0, (byte) -3, +// // 0); +// TmfTimeRange range = new TmfTimeRange(start, end); +// try { +// getSyntheticData(range, -1, TmfSyntheticEventProviderStub.BLOCK_SIZE); +// } catch (InterruptedException e) { +// fail(); +// } +// } + +// public void testGetSyntheticEvents_WeirdTimeRange2() { +// TmfTimestamp start = TmfTimestamp.Zero; // new TmfTimestamp(0, (byte) +// // -3, 0); +// TmfTimestamp end = TmfTimestamp.BigCrunch; +// TmfTimeRange range = new TmfTimeRange(start, end); +// try { +// getSyntheticData(range, -1, TmfSyntheticEventProviderStub.BLOCK_SIZE); +// } catch (InterruptedException e) { +// fail(); +// } +// } + + /** + * Test getProviders (more a sanity check than a test) + */ + @Test + public void testGetProviders2() { + + // There should be 2 TmfEvent providers: a TmfTraceStub and a + // TmfEventProviderStub + ITmfEventProvider[] eventProviders = TmfProviderManager.getProviders(ITmfEvent.class); + assertEquals("getProviders", 2, eventProviders.length); + + eventProviders = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); + assertEquals("getProviders", 1, eventProviders.length); + + eventProviders = TmfProviderManager.getProviders(ITmfEvent.class, TmfEventProviderStub.class); + assertEquals("getProviders", 1, eventProviders.length); + + // There should be 1 TmfSyntheticEventStub provider + eventProviders = TmfProviderManager.getProviders(TmfSyntheticEventStub.class); + assertEquals("getProviders", 1, eventProviders.length); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/component/TmfProviderManagerTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/component/TmfProviderManagerTest.java new file mode 100644 index 0000000000..475db7dc05 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/component/TmfProviderManagerTest.java @@ -0,0 +1,330 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.component; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.eclipse.tracecompass.internal.tmf.core.component.TmfProviderManager; +import org.eclipse.tracecompass.tmf.core.component.TmfEventProvider; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.junit.Test; + +/** + * Test suite for the TmfProviderManager class. + */ +public class TmfProviderManagerTest { + + // ------------------------------------------------------------------------ + // Dummy Providers + // ------------------------------------------------------------------------ + + private class TestProvider1 extends TmfEventProvider { + public TestProvider1(Class type) { + super("TestProvider1", type); + } + + @Override + public ITmfContext armRequest(ITmfEventRequest request) { + return null; + } + + @Override + public ITmfEvent getNext(ITmfContext context) { + return null; + } + + @Override + public boolean isCompleted(ITmfEventRequest request, ITmfEvent data, int nbRead) { + return false; + } + } + + private class TestProvider2 extends TmfEventProvider { + public TestProvider2(Class type) { + super("TestProvider2", type); + } + + @Override + public ITmfContext armRequest(ITmfEventRequest request) { + return null; + } + + @Override + public ITmfEvent getNext(ITmfContext context) { + return null; + } + + @Override + public boolean isCompleted(ITmfEventRequest request, ITmfEvent data, int nbRead) { + return false; + } + } + + private class TmfEvent3 extends TmfEvent { + } + + private class TestProvider3 extends TmfEventProvider { + public TestProvider3(Class type) { + super("TestProvider3", type); + } + + @Override + public ITmfContext armRequest(ITmfEventRequest request) { + return null; + } + + @Override + public TmfEvent3 getNext(ITmfContext context) { + return null; + } + + @Override + public boolean isCompleted(ITmfEventRequest request, ITmfEvent data, int nbRead) { + return false; + } + } + + // ------------------------------------------------------------------------ + // register/dispose + // ------------------------------------------------------------------------ + + /** + * Test registering + */ + @Test + public void testRegister_0() { + TmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class); + assertEquals("getProviders", 0, providers.length); + + providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); + assertEquals("getProviders", 0, providers.length); + } + + /** + * Test unregistering + */ + @Test + public void testRegister_Unregister_1() { + + // Register a single provider + TestProvider1 testProvider1 = new TestProvider1(ITmfEvent.class); + + TmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class); + assertEquals("getProviders", 1, providers.length); + assertEquals("getProviders", testProvider1, providers[0]); + + providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); + assertEquals("getProviders", 1, providers.length); + assertEquals("getProviders", testProvider1, providers[0]); + + // Unregister it + testProvider1.dispose(); + + providers = TmfProviderManager.getProviders(ITmfEvent.class); + assertEquals("getProviders", 0, providers.length); + + providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); + assertEquals("getProviders", 0, providers.length); + } + + /** + * Test unregistering + */ + @Test + public void testRegister_Unregister_2() { + + // Register 2 providers, same data type + TestProvider1 testProvider1 = new TestProvider1(ITmfEvent.class); + TestProvider2 testProvider2 = new TestProvider2(ITmfEvent.class); + + TmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class); + assertEquals("getProviders", 2, providers.length); + assertTrue(providers.length == 2); + if (providers[0] == testProvider1) { + assertEquals("getProviders", testProvider2, providers[1]); + } + else { + assertEquals("getProviders", testProvider2, providers[0]); + assertEquals("getProviders", testProvider1, providers[1]); + } + + providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); + assertEquals("getProviders", 1, providers.length); + assertEquals("getProviders", testProvider1, providers[0]); + + providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider2.class); + assertEquals("getProviders", 1, providers.length); + assertEquals("getProviders", testProvider2, providers[0]); + + // Remove one + testProvider1.dispose(); + + providers = TmfProviderManager.getProviders(ITmfEvent.class); + assertEquals("getProviders", 1, providers.length); + assertEquals("getProviders", testProvider2, providers[0]); + + providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); + assertEquals("getProviders", 0, providers.length); + + providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider2.class); + assertEquals("getProviders", 1, providers.length); + assertEquals("getProviders", testProvider2, providers[0]); + + // Remove the other + testProvider2.dispose(); + + providers = TmfProviderManager.getProviders(ITmfEvent.class); + assertEquals("getProviders", 0, providers.length); + + providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); + assertEquals("getProviders", 0, providers.length); + + providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider2.class); + assertEquals("getProviders", 0, providers.length); + } + + /** + * Test unregistering + */ + @Test + public void testRegister_Unregister_3() { + + // Register 3 providers, mixed data types + TestProvider1 testProvider1 = new TestProvider1(ITmfEvent.class); + TestProvider2 testProvider2 = new TestProvider2(ITmfEvent.class); + TestProvider3 testProvider3 = new TestProvider3(TmfEvent3.class); + + TmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class); + assertEquals("getProviders", 2, providers.length); + if (providers[0] == testProvider1) { + assertEquals("getProviders", testProvider2, providers[1]); + } + else { + assertEquals("getProviders", testProvider2, providers[0]); + assertEquals("getProviders", testProvider1, providers[1]); + } + + TmfEventProvider[] providers3 = TmfProviderManager.getProviders(TmfEvent3.class); + assertEquals("getProviders", 1, providers3.length); + assertEquals("getProviders", testProvider3, providers3[0]); + + providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); + assertEquals("getProviders", 1, providers.length); + assertEquals("getProviders", testProvider1, providers[0]); + + providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider2.class); + assertEquals("getProviders", 1, providers.length); + assertEquals("getProviders", testProvider2, providers[0]); + + providers3 = TmfProviderManager.getProviders(TmfEvent3.class, TestProvider3.class); + assertEquals("getProviders", 1, providers3.length); + assertEquals("getProviders", testProvider3, providers3[0]); + + // Remove one + testProvider1.dispose(); + + providers = TmfProviderManager.getProviders(ITmfEvent.class); + assertEquals("getProviders", 1, providers.length); + assertEquals("getProviders", testProvider2, providers[0]); + + providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); + assertEquals("getProviders", 0, providers.length); + + providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider2.class); + assertEquals("getProviders", 1, providers.length); + assertEquals("getProviders", testProvider2, providers[0]); + + providers3 = TmfProviderManager.getProviders(TmfEvent3.class); + assertEquals("getProviders", 1, providers3.length); + assertEquals("getProviders", testProvider3, providers3[0]); + + providers3 = TmfProviderManager.getProviders(TmfEvent3.class, TestProvider3.class); + assertEquals("getProviders", 1, providers3.length); + assertEquals("getProviders", testProvider3, providers3[0]); + + // Remove another one + testProvider2.dispose(); + + providers = TmfProviderManager.getProviders(ITmfEvent.class); + assertEquals("getProviders", 0, providers.length); + + providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); + assertEquals("getProviders", 0, providers.length); + + providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider2.class); + assertEquals("getProviders", 0, providers.length); + + providers3 = TmfProviderManager.getProviders(TmfEvent3.class); + assertTrue(providers3.length == 1); + assertTrue(providers3[0] == testProvider3); + + providers3 = TmfProviderManager.getProviders(TmfEvent3.class, TestProvider3.class); + assertEquals("getProviders", 1, providers3.length); + assertEquals("getProviders", testProvider3, providers3[0]); + + // Remove the last one + testProvider3.dispose(); + + providers = TmfProviderManager.getProviders(ITmfEvent.class); + assertEquals("getProviders", 0, providers.length); + + providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider1.class); + assertEquals("getProviders", 0, providers.length); + + providers = TmfProviderManager.getProviders(ITmfEvent.class, TestProvider2.class); + assertEquals("getProviders", 0, providers.length); + + providers3 = TmfProviderManager.getProviders(TmfEvent3.class); + assertEquals("getProviders", 0, providers.length); + + providers3 = TmfProviderManager.getProviders(TmfEvent3.class, TestProvider3.class); + assertEquals("getProviders", 0, providers.length); + } + + /** + * Test getProviders method + */ + @Test + public void testGetProvider() { + + // Register 3 providers, mixed data types + TestProvider1 testProvider1 = new TestProvider1(ITmfEvent.class); + TestProvider2 testProvider2 = new TestProvider2(ITmfEvent.class); + TestProvider3 testProvider3 = new TestProvider3(TmfEvent3.class); + + TmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class, null); + assertEquals("getProviders", 2, providers.length); + if (providers[0] == testProvider1) { + assertEquals("getProviders", testProvider2, providers[1]); + } + else { + assertEquals("getProviders", testProvider2, providers[0]); + assertEquals("getProviders", testProvider1, providers[1]); + } + + providers = TmfProviderManager.getProviders(TmfEvent3.class, null); + assertEquals("getProviders", 1, providers.length); + assertEquals("getProviders", testProvider3, providers[0]); + + // Remove the providers + testProvider1.dispose(); + testProvider2.dispose(); + testProvider3.dispose(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/AllTests.java new file mode 100644 index 0000000000..19f74e8912 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/AllTests.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Adjusted for new Event Model + * Alexandre Montplaisir - Port to JUnit4 + * Patrick Tasse - Added TmfNanoTimestampTest + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.event; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for org.eclipse.linuxtools.tmf.core.event + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TmfEventFieldTest.class, + TmfEventTest.class, + TmfEventTypeManagerTest.class, + TmfEventTypeTest.class, + TmfNanoTimestampTest.class, + TmfSimpleTimestampTest.class, + TmfTimePreferencesTest.class, + TmfTimeRangeTest.class, + TmfTimestampDeltaTest.class, + TmfTimestampTest.class, + TmfTimestampFormatTest.class, +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventFieldTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventFieldTest.java new file mode 100644 index 0000000000..380ed1ad14 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventFieldTest.java @@ -0,0 +1,365 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Adjusted for new Event Model + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.event; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Collection; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.junit.Test; + +/** + * Test suite for the TmfEventField class. + */ +@SuppressWarnings("javadoc") +public class TmfEventFieldTest { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + private final String fFieldName1 = "Field-1"; + private final String fFieldName2 = "Field-2"; + + private final Object fValue1 = "Value"; + private final Object fValue2 = Integer.valueOf(10); + + private final TmfEventField fField1 = new TmfEventField(fFieldName1, fValue1, null); + private final TmfEventField fField2 = new TmfEventField(fFieldName2, fValue2, null); + private final TmfEventField fField3 = new TmfEventField(fFieldName1, fValue2, null); + + private final String fStructRootFieldName = "Root-S"; + private final String[] fStructFieldNames = new String[] { fFieldName1, fFieldName2 }; + private final TmfEventField fStructTerminalField1 = new TmfEventField(fFieldName1, null, null); + private final TmfEventField fStructTerminalField2 = new TmfEventField(fFieldName2, null, null); + private final TmfEventField fStructTerminalField3 = new TmfEventField(fFieldName1, null, null); + private final TmfEventField fStructRootField = new TmfEventField(fStructRootFieldName, null, + new ITmfEventField[] { fStructTerminalField1, fStructTerminalField2 }); + + private final String fRootFieldName = "Root"; + private final String[] fFieldNames = new String[] { fFieldName1, fFieldName2 }; + private final TmfEventField fRootField = new TmfEventField(fRootFieldName, null, + new ITmfEventField[] { fField1, fField2 }); + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + @Test + public void testTerminalStructConstructor() { + assertSame("getName", fFieldName1, fStructTerminalField1.getName()); + assertNull("getValue", fStructTerminalField1.getValue()); + assertEquals("getFields", 0, fStructTerminalField1.getFields().size()); + assertNull("getField(name)", fStructTerminalField1.getField(fFieldName1)); + assertEquals("getFieldNames", 0, fStructTerminalField1.getFieldNames().size()); + } + + @Test + public void testNonTerminalStructConstructor() { + assertSame("getName", fStructRootFieldName, fStructRootField.getName()); + assertNull("getValue", fStructRootField.getValue()); + assertEquals("getFields", 2, fStructRootField.getFields().size()); + assertSame("getField(name)", fStructTerminalField1, fStructRootField.getField(fFieldName1)); + assertSame("getField(name)", fStructTerminalField2, fStructRootField.getField(fFieldName2)); + + final Collection names = fStructRootField.getFieldNames(); + assertEquals("getFieldNames length", 2, names.size()); + assertArrayEquals(fStructFieldNames, names.toArray(new String[names.size()])); + } + + @Test + public void testTerminalConstructor() { + assertSame("getName", fFieldName1, fField1.getName()); + assertSame("getValue", fValue1, fField1.getValue()); + assertEquals("getFields", 0, fField1.getFields().size()); + assertNull("getField(name)", fField1.getField(fFieldName1)); + assertEquals("getFieldNames", 0, fField1.getFieldNames().size()); + + assertSame("getName", fFieldName2, fField2.getName()); + assertSame("getValue", fValue2, fField2.getValue()); + assertEquals("getFields", 0, fField2.getFields().size()); + assertNull("getField(name)", fField2.getField(fFieldName2)); + } + + @Test + public void testNonTerminalConstructor() { + assertSame("getName", fRootFieldName, fRootField.getName()); + assertNull("getValue", fRootField.getValue()); + assertEquals("getFields", 2, fRootField.getFields().size()); + assertSame("getField(name)", fField1, fRootField.getField(fFieldName1)); + assertSame("getField(name)", fField2, fRootField.getField(fFieldName2)); + + final Collection names = fRootField.getFieldNames(); + assertEquals("getFieldNames length", 2, names.size()); + assertArrayEquals(fFieldNames, names.toArray(new String[names.size()])); + } + + @Test + public void testConstructorBadArg() { + try { + new TmfEventField(null, fValue1, null); + fail("Invalid (null) field name"); + } catch (final IllegalArgumentException e) { + } + } + + @Test + public void testTerminalCopyConstructor() { + final TmfEventField copy = new TmfEventField(fField1); + assertSame("getName", fFieldName1, copy.getName()); + assertSame("getValue", fValue1, copy.getValue()); + assertEquals("getFields", 0, copy.getFields().size()); + assertNull("getField(name)", copy.getField(fFieldName1)); + assertEquals("getFieldNames", 0, copy.getFieldNames().size()); + } + + @Test + public void testNonTerminalCopyConstructor() { + assertSame("getName", fRootFieldName, fRootField.getName()); + assertNull("getValue", fRootField.getValue()); + assertEquals("getFields", 2, fRootField.getFields().size()); + assertSame("getField(name)", fField1, fRootField.getField(fFieldName1)); + assertSame("getField(name)", fField2, fRootField.getField(fFieldName2)); + + final Collection names = fRootField.getFieldNames(); + assertEquals("getFieldNames length", 2, names.size()); + assertArrayEquals(fFieldNames, names.toArray(new String[names.size()])); + } + + @Test + public void testCopyConstructorBadArg() { + try { + new TmfEventField(null); + fail("TmfEventField: null arguemnt"); + } catch (final IllegalArgumentException e) { + } + } + + /** + * Test that we correctly fail to create a field with subfields having the + * same name. + */ + @Test + public void testDuplicateFieldNames() { + ITmfEventField[] fields = { + new TmfEventField("samename", null, null), + new TmfEventField("samename", null, null) + }; + + try { + new TmfEventField("field", null, fields); + fail("TmfEventField: Duplicate field names"); + } catch (IllegalArgumentException e) { + /* Expected exception */ + } + } + + // ------------------------------------------------------------------------ + // hashCode + // ------------------------------------------------------------------------ + + @Test + public void testHashCode() { + TmfEventField copy = new TmfEventField(fField1); + assertTrue("hashCode", fField1.hashCode() == copy.hashCode()); + assertTrue("hashCode", fField1.hashCode() != fField2.hashCode()); + + copy = new TmfEventField(fStructTerminalField1); + assertTrue("hashCode", fStructTerminalField1.hashCode() == copy.hashCode()); + assertTrue("hashCode", fStructTerminalField1.hashCode() != fStructTerminalField2.hashCode()); + } + + // ------------------------------------------------------------------------ + // equals + // ------------------------------------------------------------------------ + + @Test + public void testEqualsReflexivity() { + assertTrue("equals", fField1.equals(fField1)); + assertTrue("equals", fField2.equals(fField2)); + + assertFalse("equals", fField1.equals(fField2)); + assertFalse("equals", fField2.equals(fField1)); + + assertTrue("equals", fStructTerminalField1.equals(fStructTerminalField1)); + assertTrue("equals", fStructTerminalField2.equals(fStructTerminalField2)); + + assertFalse("equals", fStructTerminalField1.equals(fStructTerminalField2)); + assertFalse("equals", fStructTerminalField2.equals(fStructTerminalField1)); + } + + @Test + public void testEqualsSymmetry() { + final TmfEventField copy0 = new TmfEventField(fField1); + assertTrue("equals", fField1.equals(copy0)); + assertTrue("equals", copy0.equals(fField1)); + + final TmfEventField copy3 = new TmfEventField(fField2); + assertTrue("equals", fField2.equals(copy3)); + assertTrue("equals", copy3.equals(fField2)); + } + + @Test + public void testEqualsTransivity() { + TmfEventField copy1 = new TmfEventField(fField1); + TmfEventField copy2 = new TmfEventField(copy1); + assertTrue("equals", fField1.equals(copy1)); + assertTrue("equals", copy1.equals(copy2)); + assertTrue("equals", fField1.equals(copy2)); + + copy1 = new TmfEventField(fField2); + copy2 = new TmfEventField(copy1); + assertTrue("equals", fField2.equals(copy1)); + assertTrue("equals", copy1.equals(copy2)); + assertTrue("equals", fField2.equals(copy2)); + } + + @Test + public void testEquals() { + assertTrue("equals", fStructTerminalField1.equals(fStructTerminalField3)); + assertTrue("equals", fStructTerminalField3.equals(fStructTerminalField1)); + + assertFalse("equals", fStructTerminalField1.equals(fField3)); + assertFalse("equals", fField3.equals(fStructTerminalField1)); + } + + @Test + public void testEqualsNull() { + assertFalse("equals", fField1.equals(null)); + assertFalse("equals", fField2.equals(null)); + } + + @Test + public void testNonEqualClasses() { + assertFalse("equals", fField1.equals(fStructTerminalField1)); + assertFalse("equals", fField1.equals(fValue1)); + } + + @Test + public void testNonEqualValues() { + final TmfEventField copy1 = new TmfEventField(fFieldName1, fValue1, null); + TmfEventField copy2 = new TmfEventField(fFieldName1, fValue1, null); + assertTrue("equals", copy1.equals(copy2)); + assertTrue("equals", copy2.equals(copy1)); + + copy2 = new TmfEventField(fFieldName1, fValue2, null); + assertFalse("equals", copy1.equals(copy2)); + assertFalse("equals", copy2.equals(copy1)); + + copy2 = new TmfEventField(fFieldName1, null, null); + assertFalse("equals", copy1.equals(copy2)); + assertFalse("equals", copy2.equals(copy1)); + } + + @Test + public void testNonEquals() { + assertFalse("equals", fField1.equals(fField2)); + assertFalse("equals", fField2.equals(fField1)); + + assertFalse("equals", fField1.equals(fStructTerminalField1)); + } + + /** + * Test with same fields, but different values (should not be equal) + */ + @Test + public void testNonEqualsValue() { + final String fieldName = "myfield"; + final Object value1 = new String("test-string"); + final Object value2 = new TmfEvent(); + final TmfEventField[] fields = { fField1, fField2 }; + + final TmfEventField field1 = new TmfEventField(fieldName, value1, fields); + final TmfEventField field2 = new TmfEventField(fieldName, value2, fields); + + assertNotEquals(field1, field2); + assertNotEquals(field2, field1); + } + + /** + * Test with same value, but different fields (should not be equal) + */ + @Test + public void testNonEqualsFields() { + final String fieldName = "myfield"; + final Object value = new String("test-string"); + final TmfEventField[] fields1 = { fField1, fField2 }; + final TmfEventField[] fields2 = { fField2, fField3 }; + + final TmfEventField field1 = new TmfEventField(fieldName, value, fields1); + final TmfEventField field2 = new TmfEventField(fieldName, value, fields2); + + assertNotEquals(field1, field2); + assertNotEquals(field2, field1); + } + + /** + * Test with same field and values (should be equals) + */ + @Test + public void testEqualsEverything() { + final String fieldName = "myfield"; + final Object value = new String("test-string"); + final TmfEventField[] fields = { fField1, fField2 }; + + final TmfEventField field1 = new TmfEventField(fieldName, value, fields); + final TmfEventField field2 = new TmfEventField(fieldName, value, fields); + + assertEquals(field1, field2); + assertEquals(field2, field1); + } + + // ------------------------------------------------------------------------ + // toString + // ------------------------------------------------------------------------ + + @Test + public void testToString() { + final String expected1 = fFieldName1 + "=" + fValue1.toString(); + TmfEventField field = new TmfEventField(fFieldName1, fValue1, null); + assertEquals("toString", expected1, field.toString()); + + final String expected2 = fFieldName1 + "=" + fValue2.toString(); + field = new TmfEventField(fFieldName1, fValue2, null); + assertEquals("toString", expected2, field.toString()); + } + + // ------------------------------------------------------------------------ + // makeRoot + // ------------------------------------------------------------------------ + + @Test + public void testMakeRoot() { + ITmfEventField root = TmfEventField.makeRoot(fStructFieldNames); + Collection names = root.getFieldNames(); + assertEquals("getFieldNames length", 2, names.size()); + assertArrayEquals(fStructFieldNames, names.toArray(new String[names.size()])); + + root = TmfEventField.makeRoot(fFieldNames); + names = root.getFieldNames(); + assertEquals("getFieldNames length", 2, names.size()); + assertArrayEquals(fFieldNames, names.toArray(new String[names.size()])); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventTest.java new file mode 100644 index 0000000000..625a973b69 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventTest.java @@ -0,0 +1,417 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Adjusted for new Event Model + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.event; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.tests.TmfCoreTestPlugin; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; +import org.junit.Test; + +/** + * Test suite for the TmfEvent class. + */ +@SuppressWarnings("javadoc") +public class TmfEventTest { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + private final String fSource = "Source"; + + private final String fContext = ITmfEventType.DEFAULT_CONTEXT_ID; + private final String fTypeId = "TestType"; + private final String fLabel1 = "AString"; + private final String fLabel2 = "AnInteger"; + private final String[] fLabels = new String[] { fLabel1, fLabel2 }; + private final TmfEventType fType = new TmfEventType(fContext, fTypeId, TmfEventField.makeRoot(fLabels)); + + private final Object fValue1a = "Some string"; + private final Object fValue1b = Integer.valueOf(10); + private final ITmfEventField fField1a = new TmfEventField(fLabel1, fValue1a, null); + private final ITmfEventField fField1b = new TmfEventField(fLabel2, fValue1b, null); + private final ITmfEventField[] fFields1 = new ITmfEventField[] { fField1a, fField1b }; + private final String fRawContent1 = fField1a.toString() + fField1b.toString(); + private final ITmfEventField fContent1 = new TmfEventField(fRawContent1, null, fFields1); + private final TmfTimestamp fTimestamp1 = new TmfTimestamp(12345, 2, 5); + private final String fReference1 = "Some reference"; + private final ITmfEvent fEvent1 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + + private final Object fValue2a = "Another string"; + private final Object fValue2b = Integer.valueOf(-4); + private final ITmfEventField fField2a = new TmfEventField(fLabel1, fValue2a, null); + private final ITmfEventField fField2b = new TmfEventField(fLabel2, fValue2b, null); + private final ITmfEventField[] fFields2 = new ITmfEventField[] { fField2a, fField2b }; + private final String fRawContent2 = fField2a.toString() + fField2b.toString(); + private final ITmfEventField fContent2 = new TmfEventField(fRawContent2, null, fFields2); + private final TmfTimestamp fTimestamp2 = new TmfTimestamp(12350, 2, 5); + private final String fReference2 = "Some other reference"; + private final ITmfEvent fEvent2 = new TmfEvent(null, 1, fTimestamp2, fSource, fType, fContent2, fReference2); + + // ------------------------------------------------------------------------ + // Helper functions + // ------------------------------------------------------------------------ + + private static TmfTraceStub openTrace() { + TmfTraceStub trace = null; + try { + final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TmfTestTrace.A_TEST_10K.getFullPath()), null); + final File test = new File(FileLocator.toFileURL(location).toURI()); + trace = new TmfTraceStub(test.toURI().getPath(), 500, false, null); + } catch (final TmfTraceException e) { + e.printStackTrace(); + } catch (final URISyntaxException e) { + e.printStackTrace(); + } catch (final IOException e) { + e.printStackTrace(); + } + return trace; + } + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + @Test + public void testDefaultConstructor() { + final ITmfEvent event = new TmfEvent(); + assertNull("getTrace", event.getTrace()); + assertEquals("getRank", ITmfContext.UNKNOWN_RANK, event.getRank()); + assertNull("getTimestamp", event.getTimestamp()); + assertNull("getSource", event.getSource()); + assertNull("getType", event.getType()); + assertNull("getContent", event.getContent()); + assertNull("getReference", event.getReference()); + } + + @Test + public void testFullConstructor() { + assertNull("getTrace", fEvent1.getTrace()); + assertEquals("getRank", 0, fEvent1.getRank()); + assertEquals("getTimestamp", fTimestamp1, fEvent1.getTimestamp()); + assertEquals("getSource", fSource, fEvent1.getSource()); + assertEquals("getType", fType, fEvent1.getType()); + assertEquals("getContent", fContent1, fEvent1.getContent()); + assertEquals("getReference", fReference1, fEvent1.getReference()); + + assertNull("getTrace", fEvent2.getTrace()); + assertEquals("getRank", 1, fEvent2.getRank()); + assertEquals("getTimestamp", fTimestamp2, fEvent2.getTimestamp()); + assertEquals("getSource", fSource, fEvent2.getSource()); + assertEquals("getType", fType, fEvent2.getType()); + assertEquals("getContent", fContent2, fEvent2.getContent()); + assertEquals("getReference", fReference2, fEvent2.getReference()); + } + + @Test + public void testNoRankConstructor() { + final ITmfEvent event = new TmfEvent(null, fTimestamp1, fSource, fType, fContent1, fReference1); + assertNull("getTrace", event.getTrace()); + assertEquals("getRank", ITmfContext.UNKNOWN_RANK, event.getRank()); + assertEquals("getTimestamp", fTimestamp1, event.getTimestamp()); + assertEquals("getSource", fSource, event.getSource()); + assertEquals("getType", fType, event.getType()); + assertEquals("getContent", fContent1, event.getContent()); + assertEquals("getReference", fReference1, event.getReference()); + } + + @Test + public void testConstructorWithTrace() { + final ITmfTrace trace = openTrace(); + final ITmfEvent event = new TmfEvent(trace, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + assertNotNull("getTrace", event.getTrace()); + assertEquals("getRank", 0, event.getRank()); + assertEquals("getTimestamp", fTimestamp1, event.getTimestamp()); + assertEquals("getSource", fSource, event.getSource()); + assertEquals("getType", fType, event.getType()); + assertEquals("getContent", fContent1, event.getContent()); + assertEquals("getReference", fReference1, event.getReference()); + trace.dispose(); + } + + @Test + public void testTmfEventCopy() { + final ITmfEvent event = new TmfEvent(fEvent1); + assertNull("getTrace", event.getTrace()); + assertEquals("getRank", 0, event.getRank()); + assertEquals("getTimestamp", fTimestamp1, event.getTimestamp()); + assertEquals("getSource", fSource, event.getSource()); + assertEquals("getType", fType, event.getType()); + assertEquals("getContent", fContent1, event.getContent()); + assertEquals("getReference", fReference1, event.getReference()); + } + + @Test + public void testEventCopy2() { + try { + new TmfEvent(null); + fail("null copy"); + } catch (final IllegalArgumentException e) { + // Success + } + } + + // ------------------------------------------------------------------------ + // hashCode + // ------------------------------------------------------------------------ + + @Test + public void testHashCode() { + ITmfEvent event1 = new TmfEvent(); + ITmfEvent event2 = new TmfEvent(); + + assertTrue("hashCode", event1.hashCode() == event2.hashCode()); + + final ITmfTrace trace = openTrace(); + event1 = new TmfEvent(trace, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + event2 = new TmfEvent(trace, 1, fTimestamp2, fSource, fType, fContent2, fReference2); + final ITmfEvent event1b = new TmfEvent(event1); + final ITmfEvent event2b = new TmfEvent(event2); + + assertTrue("hashCode", event1.hashCode() == event1b.hashCode()); + assertTrue("hashCode", event2.hashCode() == event2b.hashCode()); + + assertTrue("hashCode", event1.hashCode() != event2.hashCode()); + assertTrue("hashCode", event2.hashCode() != event1.hashCode()); + + trace.dispose(); + } + + // ------------------------------------------------------------------------ + // equals + // ------------------------------------------------------------------------ + + @Test + public void testEqualsReflexivity() { + assertTrue("equals", fEvent1.equals(fEvent1)); + assertTrue("equals", fEvent2.equals(fEvent2)); + + assertFalse("equals", fEvent1.equals(fEvent2)); + assertFalse("equals", fEvent2.equals(fEvent1)); + } + + @Test + public void testEqualsSymmetry() { + final ITmfEvent event1 = new TmfEvent(fEvent1); + final ITmfEvent event2 = new TmfEvent(fEvent2); + + assertTrue("equals", event1.equals(fEvent1)); + assertTrue("equals", fEvent1.equals(event1)); + + assertTrue("equals", event2.equals(fEvent2)); + assertTrue("equals", fEvent2.equals(event2)); + } + + @Test + public void testEqualsTransivity() { + final ITmfEvent event1 = new TmfEvent(fEvent1); + final ITmfEvent event2 = new TmfEvent(fEvent1); + final ITmfEvent event3 = new TmfEvent(fEvent1); + + assertTrue("equals", event1.equals(event2)); + assertTrue("equals", event2.equals(event3)); + assertTrue("equals", event1.equals(event3)); + } + + @Test + public void testEqualsNull() { + assertFalse("equals", fEvent1.equals(null)); + assertFalse("equals", fEvent2.equals(null)); + } + + @Test + public void testNonEqualClasses() { + assertFalse("equals", fEvent1.equals(fEvent1.getType())); + assertFalse("equals", fEvent1.equals(null)); + } + + @Test + public void testNonEqualTraces() { + final ITmfTrace trace1 = openTrace(); + final ITmfTrace trace2 = openTrace(); + + final ITmfEvent event1 = new TmfEvent(trace1, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + ITmfEvent event2 = new TmfEvent(trace1, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + assertTrue("equals", event1.equals(event2)); + assertTrue("equals", event2.equals(event1)); + + event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + assertFalse("equals", event1.equals(event2)); + assertFalse("equals", event2.equals(event1)); + + event2 = new TmfEvent(trace2, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + assertFalse("equals", event1.equals(event2)); + assertFalse("equals", event2.equals(event1)); + + trace1.dispose(); + trace2.dispose(); + } + + @Test + public void testNonEqualRanks() { + final ITmfEvent event1 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + ITmfEvent event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + assertTrue("equals", event1.equals(event2)); + assertTrue("equals", event2.equals(event1)); + + event2 = new TmfEvent(null, 1, fTimestamp1, fSource, fType, fContent1, fReference1); + assertFalse("equals", event1.equals(event2)); + assertFalse("equals", event2.equals(event1)); + } + + @Test + public void testNonEqualTimestamps() { + final ITmfEvent event1 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + ITmfEvent event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + assertTrue("equals", event1.equals(event2)); + assertTrue("equals", event2.equals(event1)); + + event2 = new TmfEvent(null, 0, fTimestamp2, fSource, fType, fContent1, fReference1); + assertFalse("equals", event1.equals(event2)); + assertFalse("equals", event2.equals(event1)); + + event2 = new TmfEvent(null, 0, null, fSource, fType, fContent1, fReference1); + assertFalse("equals", event1.equals(event2)); + assertFalse("equals", event2.equals(event1)); + } + + @Test + public void testNonEqualSources() { + final ITmfEvent event1 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + ITmfEvent event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + assertTrue("equals", event1.equals(event2)); + assertTrue("equals", event2.equals(event1)); + + event2 = new TmfEvent(null, 0, fTimestamp1, fSource + "x", fType, fContent1, fReference1); + assertFalse("equals", event1.equals(event2)); + assertFalse("equals", event2.equals(event1)); + + event2 = new TmfEvent(null, 0, fTimestamp1, null, fType, fContent1, fReference1); + assertFalse("equals", event1.equals(event2)); + assertFalse("equals", event2.equals(event1)); + } + + @Test + public void testNonEqualTypes() { + final ITmfEvent event1 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + ITmfEvent event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + assertTrue("equals", event1.equals(event2)); + assertTrue("equals", event2.equals(event1)); + + final String typeId = "OtherTestType"; + final String[] labels = new String[] { fLabel2, fLabel1 }; + final TmfEventType newType = new TmfEventType(fContext, typeId, TmfEventField.makeRoot(labels)); + + event2 = new TmfEvent(null, 0, fTimestamp1, fSource, newType, fContent1, fReference1); + assertFalse("equals", event1.equals(event2)); + assertFalse("equals", event2.equals(event1)); + + event2 = new TmfEvent(null, 0, fTimestamp1, fSource, null, fContent1, fReference1); + assertFalse("equals", event1.equals(event2)); + assertFalse("equals", event2.equals(event1)); + } + + @Test + public void testNonEqualContents() { + final ITmfEvent event1 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + ITmfEvent event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + assertTrue("equals", event1.equals(event2)); + assertTrue("equals", event2.equals(event1)); + + event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent2, fReference1); + assertFalse("equals", event1.equals(event2)); + assertFalse("equals", event2.equals(event1)); + + event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, null, fReference1); + assertFalse("equals", event1.equals(event2)); + assertFalse("equals", event2.equals(event1)); + } + + @Test + public void testNonEqualReferences() { + final ITmfEvent event1 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + ITmfEvent event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference1); + assertTrue("equals", event1.equals(event2)); + assertTrue("equals", event2.equals(event1)); + + event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, fReference2); + assertFalse("equals", event1.equals(event2)); + assertFalse("equals", event2.equals(event1)); + + event2 = new TmfEvent(null, 0, fTimestamp1, fSource, fType, fContent1, null); + assertFalse("equals", event1.equals(event2)); + assertFalse("equals", event2.equals(event1)); + } + + // ------------------------------------------------------------------------ + // toString + // ------------------------------------------------------------------------ + + @Test + public void testToString() { + final String expected1 = "TmfEvent [fTimestamp=" + fTimestamp1 + ", fTrace=null, fRank=0, fSource=" + fSource + + ", fType=" + fType + ", fContent=" + fContent1 + ", fReference=" + fReference1 + "]"; + assertEquals("toString", expected1, fEvent1.toString()); + + final String expected2 = "TmfEvent [fTimestamp=" + fTimestamp2 + ", fTrace=null, fRank=1, fSource=" + fSource + + ", fType=" + fType + ", fContent=" + fContent2 + ", fReference=" + fReference2 + "]"; + assertEquals("toString", expected2, fEvent2.toString()); + } + + /** + * Test the .toString() with extended classes. + * It should print the correct class name. + */ + @Test + public void testToStringExtended() { + class ExtendedEvent extends TmfEvent { + ExtendedEvent(ITmfEvent event) { + super(event); + } + } + ExtendedEvent event = new ExtendedEvent(fEvent1); + String expected = "ExtendedEvent [fTimestamp=" + fTimestamp1 + + ", fTrace=null, fRank=0, fSource=" + fSource + + ", fType=" + fType + ", fContent=" + fContent1 + + ", fReference=" + fReference1 + "]"; + + assertEquals(expected, event.toString()); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventTypeManagerTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventTypeManagerTest.java new file mode 100644 index 0000000000..fe2b6ba51b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventTypeManagerTest.java @@ -0,0 +1,242 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.event; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Set; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.eclipse.tracecompass.tmf.core.event.TmfEventTypeManager; +import org.junit.Test; + +/** + * Test suite for the TmfEventTypeManager class. + */ +@SuppressWarnings("javadoc") +public class TmfEventTypeManagerTest { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + private static final TmfEventTypeManager fInstance = TmfEventTypeManager.getInstance(); + + private final String fContext1 = "JUnit context 1"; + private final String fContext2 = "JUnit context 2"; + + private final String fTypeId1 = "Some type"; + private final String fTypeId2 = "Some other type"; + private final String fTypeId3 = "Yet another type"; + private final String fTypeId4 = "A final type"; + + private final String fLabel0 = "label1"; + private final String fLabel1 = "label2"; + private final String fLabel2 = "label3"; + + private final String[] fLabels0 = new String[] { }; + private final String[] fLabels1 = new String[] { fLabel0, fLabel1 }; + private final String[] fLabels2 = new String[] { fLabel1, fLabel0, fLabel2 }; + + private final TmfEventType fType0 = new TmfEventType(fContext1, fTypeId1, TmfEventField.makeRoot(fLabels0)); + private final TmfEventType fType1 = new TmfEventType(fContext1, fTypeId2, TmfEventField.makeRoot(fLabels1)); + private final TmfEventType fType2 = new TmfEventType(fContext2, fTypeId3, TmfEventField.makeRoot(fLabels2)); + private final TmfEventType fType3 = new TmfEventType(fContext2, fTypeId4, TmfEventField.makeRoot(fLabels1)); + + // ------------------------------------------------------------------------ + // Getters + // ------------------------------------------------------------------------ + + @Test + public void testGetContexts() { + fInstance.clear(); + fInstance.add(fContext1, fType0); + fInstance.add(fContext1, fType1); + fInstance.add(fContext2, fType2); + fInstance.add(fContext2, fType3); + + final String[] contexts = fInstance.getContexts(); + Arrays.sort(contexts); + assertEquals("getContexts", 2, contexts.length); + assertEquals("getContexts", fContext1, contexts[0]); + assertEquals("getContexts", fContext2, contexts[1]); + } + + @Test + public void testGetTypes() { + fInstance.clear(); + fInstance.add(fContext1, fType0); + fInstance.add(fContext1, fType1); + fInstance.add(fContext2, fType2); + fInstance.add(fContext2, fType3); + + Set types = fInstance.getTypes(fContext1); + assertEquals("getTypes", 2, types.size()); + assertTrue(types.contains(fType1)); + assertTrue(types.contains(fType0)); + + types = fInstance.getTypes(fContext2); + assertEquals("getTypes", 2, types.size()); + assertTrue(types.contains(fType2)); + assertTrue(types.contains(fType3)); + } + + @Test + public void testGetType() { + fInstance.clear(); + fInstance.add(fContext1, fType0); + fInstance.add(fContext1, fType1); + fInstance.add(fContext2, fType2); + fInstance.add(fContext2, fType3); + + ITmfEventType type = fInstance.getType(fContext1, fType0.getName()); + assertSame("getType", fType0, type); + type = fInstance.getType(fContext1, fType1.getName()); + assertSame("getType", fType1, type); + type = fInstance.getType(fContext1, fType2.getName()); + assertNull("getType", type); + type = fInstance.getType(fContext1, fType3.getName()); + assertNull("getType", type); + + type = fInstance.getType(fContext2, fType2.getName()); + assertSame("getType", fType2, type); + type = fInstance.getType(fContext2, fType3.getName()); + assertSame("getType", fType3, type); + type = fInstance.getType(fContext2, fType0.getName()); + assertNull("getType", type); + type = fInstance.getType(fContext2, fType1.getName()); + assertNull("getType", type); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Test + public void testClear() { + fInstance.clear(); + assertEquals("clear", 0, fInstance.getContexts().length); + assertEquals("clear", 0, fInstance.getTypes(null).size()); + assertNull("clear", fInstance.getType(null, null)); + assertEquals("clear", "TmfEventTypeManager [fEventTypes={}]", fInstance.toString()); + } + + @Test + public void testClearContext() { + fInstance.clear(); + fInstance.add(fContext1, fType0); + fInstance.add(fContext1, fType1); + fInstance.add(fContext2, fType2); + fInstance.add(fContext2, fType3); + + fInstance.clear(fContext1); + + final String[] contexts = fInstance.getContexts(); + assertEquals("clear context", 1, contexts.length); + assertEquals("clear context", fContext2, contexts[0]); + + Set types = fInstance.getTypes(fContext1); + assertEquals("clear context", 0, types.size()); + + ITmfEventType type = fInstance.getType(fContext1, fType0.getName()); + assertNull("clear context", type); + type = fInstance.getType(fContext1, fType1.getName()); + assertNull("clear context", type); + + types = fInstance.getTypes(fContext2); + assertEquals("clear context", 2, types.size()); + assertTrue(types.contains(fType2)); + assertTrue(types.contains(fType3)); + } + + @Test + public void testBasicAdd() { + fInstance.clear(); + fInstance.add(fContext1, fType0); + + final String[] contexts = fInstance.getContexts(); + assertEquals("add", 1, contexts.length); + assertEquals("add", fContext1, contexts[0]); + + final Set types = fInstance.getTypes(contexts[0]); + assertEquals("add", 1, types.size()); + assertTrue(types.contains(fType0)); + + ITmfEventType type = fInstance.getType(contexts[0], fType0.getName()); + assertSame("add", fType0, type); + + type = fInstance.getType(contexts[0], fType1.getName()); + assertNotSame("add", fType0, type); + } + + @Test + public void testAdd() { + fInstance.clear(); + fInstance.add(fContext1, fType0); + fInstance.add(fContext1, fType1); + fInstance.add(fContext2, fType2); + fInstance.add(fContext2, fType3); + + final String[] contexts = fInstance.getContexts(); + Arrays.sort(contexts); + assertEquals("add", 2, contexts.length); + assertEquals("add", fContext1, contexts[0]); + assertEquals("add", fContext2, contexts[1]); + + Set types = fInstance.getTypes(fContext1); + assertEquals("add", 2, types.size()); + assertTrue(types.contains(fType0)); + assertTrue(types.contains(fType1)); + + types = fInstance.getTypes(fContext2); + assertEquals("add", 2, types.size()); + assertTrue(types.contains(fType2)); + assertTrue(types.contains(fType3)); + + ITmfEventType type = fInstance.getType(fContext1, fType0.getName()); + assertSame("add", fType0, type); + type = fInstance.getType(fContext1, fType1.getName()); + assertSame("add", fType1, type); + type = fInstance.getType(fContext2, fType2.getName()); + assertSame("add", fType2, type); + type = fInstance.getType(fContext2, fType3.getName()); + assertSame("add", fType3, type); + + type = fInstance.getType(fContext1, fType2.getName()); + assertNull("add", type); + type = fInstance.getType(fContext2, fType0.getName()); + assertNull("add", type); + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Test + public void testToString() { + fInstance.clear(); + assertEquals("toString", "TmfEventTypeManager [fEventTypes={}]", fInstance.toString()); + + fInstance.add(fContext1, fType0); + assertEquals("toString", "TmfEventTypeManager [fEventTypes={" + fContext1 + "={" + fTypeId1 + "=" + fType0 + "}}]", fInstance.toString()); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventTypeTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventTypeTest.java new file mode 100644 index 0000000000..4a81181d79 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventTypeTest.java @@ -0,0 +1,233 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Adjusted for new Event Model + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.event; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Collection; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.junit.Test; + +/** + * Test suite for the TmfEventType class. + */ +@SuppressWarnings("javadoc") +public class TmfEventTypeTest { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + private final String fContext1 = "JUnit context 1"; + private final String fContext2 = "JUnit context 2"; + + private final String fTypeId1 = "Some type"; + private final String fTypeId2 = "Some other type"; + + private final String fLabel0 = "label1"; + private final String fLabel1 = "label2"; + private final String fLabel2 = "label3"; + + private final String[] fLabels0 = new String[] { }; + private final String[] fLabels1 = new String[] { fLabel0, fLabel1 }; + private final String[] fLabels2 = new String[] { fLabel1, fLabel0, fLabel2 }; + + private final ITmfEventType fType0 = new TmfEventType(fContext1, fTypeId1, TmfEventField.makeRoot(fLabels0)); + private final ITmfEventType fType1 = new TmfEventType(fContext1, fTypeId2, TmfEventField.makeRoot(fLabels1)); + private final ITmfEventType fType2 = new TmfEventType(fContext2, fTypeId1, TmfEventField.makeRoot(fLabels2)); + private final ITmfEventType fType3 = new TmfEventType(fContext2, fTypeId2, TmfEventField.makeRoot(fLabels1)); + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + @Test + public void testDefaultConstructor() { + final ITmfEventType type = new TmfEventType(); + assertEquals("getContext", ITmfEventType.DEFAULT_CONTEXT_ID, type.getContext()); + assertEquals("getName", ITmfEventType.DEFAULT_TYPE_ID, type.getName()); + assertNull("getRootField", type.getRootField()); + assertEquals("getFieldNames", 0, type.getFieldNames().size()); + } + + @Test + public void testFullConstructor() { + final ITmfEventType type0 = new TmfEventType(fContext1, fTypeId1, TmfEventField.makeRoot(fLabels0)); + assertEquals("getContext", fContext1, type0.getContext()); + assertEquals("getName", fTypeId1, type0.getName()); + assertEquals("getRootField", TmfEventField.makeRoot(fLabels0), type0.getRootField()); + final Collection labels0 = type0.getFieldNames(); + assertEquals("getFieldNames length", fLabels0.length, labels0.size()); + assertArrayEquals(fLabels0, labels0.toArray(new String[labels0.size()])); + + final ITmfEventType type1 = new TmfEventType(fContext1, fTypeId1, TmfEventField.makeRoot(fLabels1)); + assertEquals("getContext", fContext1, type1.getContext()); + assertEquals("getName", fTypeId1, type1.getName()); + assertEquals("getRootField", TmfEventField.makeRoot(fLabels1), type1.getRootField()); + final Collection labels1 = type1.getFieldNames(); + assertEquals("getFieldNames length", fLabels1.length, labels1.size()); + assertArrayEquals(fLabels1, labels1.toArray(new String[labels1.size()])); + + final ITmfEventType type2 = new TmfEventType(fContext2, fTypeId2, TmfEventField.makeRoot(fLabels2)); + assertEquals("getContext", fContext2, type2.getContext()); + assertEquals("getName", fTypeId2, type2.getName()); + assertEquals("getRootField", TmfEventField.makeRoot(fLabels2), type2.getRootField()); + final Collection labels2 = type2.getFieldNames(); + assertEquals("getFieldNames length", fLabels2.length, labels2.size()); + assertArrayEquals(fLabels2, labels2.toArray(new String[labels2.size()])); + } + + @Test + public void testConstructorCornerCases() { + try { + new TmfEventType(null, fTypeId1, null); + fail("TmfEventType: null context"); + } catch (final IllegalArgumentException e) { + } + + try { + new TmfEventType(fContext1, null, null); + fail("TmfEventType: null type"); + } catch (final IllegalArgumentException e) { + } + } + + @Test + public void testCopyConstructor() { + final TmfEventType original = new TmfEventType(fContext1, fTypeId1, TmfEventField.makeRoot(fLabels1)); + final TmfEventType copy = new TmfEventType(original); + + assertEquals("getContext", fContext1, copy.getContext()); + assertEquals("getName", fTypeId1, copy.getName()); + assertEquals("getRootField", TmfEventField.makeRoot(fLabels1), copy.getRootField()); + final Collection labels1 = copy.getFieldNames(); + assertEquals("getFieldNames length", fLabels1.length, labels1.size()); + assertArrayEquals(fLabels1, labels1.toArray(new String[labels1.size()])); + } + + @Test + public void testCopyConstructorCornerCases() { + try { + new TmfEventType(null); + fail("TmfEventType: null argument"); + } catch (final IllegalArgumentException e) { + } + } + + // ------------------------------------------------------------------------ + // hashCode + // ------------------------------------------------------------------------ + + @Test + public void testHashCode() { + final TmfEventType copy1 = new TmfEventType(fType0); + + assertTrue("hashCode", fType0.hashCode() == copy1.hashCode()); + assertTrue("hashCode", fType0.hashCode() != fType3.hashCode()); + } + + // ------------------------------------------------------------------------ + // equals + // ------------------------------------------------------------------------ + + @Test + public void testEqualsReflexivity() { + assertTrue("equals", fType0.equals(fType0)); + assertTrue("equals", fType3.equals(fType3)); + + assertFalse("equals", fType0.equals(fType3)); + assertFalse("equals", fType3.equals(fType0)); + } + + @Test + public void testEqualsSymmetry() { + final TmfEventType copy0 = new TmfEventType(fType0); + assertTrue("equals", fType0.equals(copy0)); + assertTrue("equals", copy0.equals(fType0)); + + final TmfEventType copy1 = new TmfEventType(fType1); + assertTrue("equals", fType1.equals(copy1)); + assertTrue("equals", copy1.equals(fType1)); + + final TmfEventType copy2 = new TmfEventType(fType2); + assertTrue("equals", fType2.equals(copy2)); + assertTrue("equals", copy2.equals(fType2)); + } + + @Test + public void testEqualsTransivity() { + TmfEventType copy1 = new TmfEventType(fType1); + TmfEventType copy2 = new TmfEventType(copy1); + assertTrue("equals", fType1.equals(copy1)); + assertTrue("equals", copy1.equals(copy2)); + assertTrue("equals", fType1.equals(copy2)); + + copy1 = new TmfEventType(fType2); + copy2 = new TmfEventType(copy1); + assertTrue("equals", fType2.equals(copy1)); + assertTrue("equals", copy1.equals(copy2)); + assertTrue("equals", fType2.equals(copy2)); + + copy1 = new TmfEventType(fType3); + copy2 = new TmfEventType(copy1); + assertTrue("equals", fType3.equals(copy1)); + assertTrue("equals", copy1.equals(copy2)); + assertTrue("equals", fType3.equals(copy2)); + } + + @Test + public void testEqualsNull() { + assertFalse("equals", fType0.equals(null)); + assertFalse("equals", fType3.equals(null)); + } + + @Test + public void testNonEquals() { + assertFalse("equals", fType0.equals(fType1)); + assertFalse("equals", fType1.equals(fType2)); + assertFalse("equals", fType2.equals(fType3)); + assertFalse("equals", fType3.equals(fType0)); + } + + @Test + public void testNonEqualsClasses() { + assertFalse("equals", fType1.equals(fLabels1)); + } + + // ------------------------------------------------------------------------ + // toString + // ------------------------------------------------------------------------ + + @Test + public void testToString() { + final String expected1 = "TmfEventType [fContext=" + ITmfEventType.DEFAULT_CONTEXT_ID + + ", fTypeId=" + ITmfEventType.DEFAULT_TYPE_ID + "]"; + final TmfEventType type1 = new TmfEventType(); + assertEquals("toString", expected1, type1.toString()); + + final String expected2 = "TmfEventType [fContext=" + fContext1 + ", fTypeId=" + fTypeId1 + "]"; + final TmfEventType type2 = new TmfEventType(fContext1, fTypeId1, TmfEventField.makeRoot(fLabels1)); + assertEquals("toString", expected2, type2.toString()); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfNanoTimestampTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfNanoTimestampTest.java new file mode 100644 index 0000000000..6f2964d822 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfNanoTimestampTest.java @@ -0,0 +1,293 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Modified from TmfSimpleTimestamp to use nanosecond scale + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.event; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.junit.Test; + +/** + * Test suite for the TmfNanoTimestampTest class. + */ +@SuppressWarnings("javadoc") +public class TmfNanoTimestampTest { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + private final ITmfTimestamp ts0 = new TmfNanoTimestamp(); + private final ITmfTimestamp ts1 = new TmfNanoTimestamp(12345); + private final ITmfTimestamp ts2 = new TmfNanoTimestamp(-1234); + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + @Test + public void testDefaultConstructor() { + assertEquals("getValue", 0, ts0.getValue()); + assertEquals("getscale", -9, ts0.getScale()); + assertEquals("getPrecision", 0, ts0.getPrecision()); + } + + @Test + public void testFullConstructor() { + assertEquals("getValue", 12345, ts1.getValue()); + assertEquals("getscale", -9, ts1.getScale()); + assertEquals("getPrecision", 0, ts1.getPrecision()); + } + + @Test + public void testCopyConstructor() { + final ITmfTimestamp copy = new TmfNanoTimestamp(ts1); + + assertEquals("getValue", ts1.getValue(), copy.getValue()); + assertEquals("getscale", ts1.getScale(), copy.getScale()); + assertEquals("getPrecision", ts1.getPrecision(), copy.getPrecision()); + + assertEquals("getValue", 12345, copy.getValue()); + assertEquals("getscale", -9, copy.getScale()); + assertEquals("getPrecision", 0, copy.getPrecision()); + } + + @Test + public void testCopyBadTimestamp() { + try { + new TmfNanoTimestamp(null); + fail("TmfNanoTimestamp: null argument"); + } catch (final NullPointerException e) { + } + } + + // ------------------------------------------------------------------------ + // equals + // ------------------------------------------------------------------------ + + @Test + public void testEqualsReflexivity() { + assertTrue("equals", ts0.equals(ts0)); + assertTrue("equals", ts1.equals(ts1)); + assertTrue("equals", ts2.equals(ts2)); + + assertTrue("equals", !ts0.equals(ts1)); + assertTrue("equals", !ts0.equals(ts2)); + + assertTrue("equals", !ts1.equals(ts0)); + assertTrue("equals", !ts1.equals(ts2)); + + assertTrue("equals", !ts2.equals(ts0)); + assertTrue("equals", !ts2.equals(ts1)); + } + + @Test + public void testEqualsSymmetry() { + final ITmfTimestamp ts0copy = new TmfNanoTimestamp(ts0); + assertTrue("equals", ts0.equals(ts0copy)); + assertTrue("equals", ts0copy.equals(ts0)); + + final ITmfTimestamp ts1copy = new TmfNanoTimestamp(ts1); + assertTrue("equals", ts1.equals(ts1copy)); + assertTrue("equals", ts1copy.equals(ts1)); + } + + @Test + public void testEqualsTransivity() { + final ITmfTimestamp ts0copy1 = new TmfNanoTimestamp(ts0); + final ITmfTimestamp ts0copy2 = new TmfNanoTimestamp(ts0copy1); + assertTrue("equals", ts0.equals(ts0copy1)); + assertTrue("equals", ts0copy1.equals(ts0copy2)); + assertTrue("equals", ts0.equals(ts0copy2)); + + final ITmfTimestamp ts1copy1 = new TmfNanoTimestamp(ts1); + final ITmfTimestamp ts1copy2 = new TmfNanoTimestamp(ts1copy1); + assertTrue("equals", ts1.equals(ts1copy1)); + assertTrue("equals", ts1copy1.equals(ts1copy2)); + assertTrue("equals", ts1.equals(ts1copy2)); + } + + @Test + public void testEqualsNull() { + assertTrue("equals", !ts0.equals(null)); + assertTrue("equals", !ts1.equals(null)); + assertTrue("equals", !ts2.equals(null)); + } + + @Test + public void testEqualsNonTimestamp() { + assertFalse("equals", ts0.equals(ts0.toString())); + } + + // ------------------------------------------------------------------------ + // toString + // ------------------------------------------------------------------------ + + @Test + public void testToString() { + DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS"); + Date d0 = new Date(ts0.getValue() / 1000000); + Date d1 = new Date(ts1.getValue() / 1000000); + Date d2 = new Date(ts2.getValue() / 1000000 - 1); + assertEquals("toString", df.format(d0) + " 000 000", ts0.toString()); + assertEquals("toString", df.format(d1) + " 012 345", ts1.toString()); + assertEquals("toString", df.format(d2) + " 998 766", ts2.toString()); + } + + // ------------------------------------------------------------------------ + // hashCode + // ------------------------------------------------------------------------ + + @Test + public void testHashCode() { + final ITmfTimestamp ts0copy = new TmfTimestamp(ts0); + final ITmfTimestamp ts1copy = new TmfTimestamp(ts1); + final ITmfTimestamp ts2copy = new TmfTimestamp(ts2); + + assertTrue("hashCode", ts0.hashCode() == ts0copy.hashCode()); + assertTrue("hashCode", ts1.hashCode() == ts1copy.hashCode()); + assertTrue("hashCode", ts2.hashCode() == ts2copy.hashCode()); + + assertTrue("hashCode", ts0.hashCode() != ts1.hashCode()); + } + + // ------------------------------------------------------------------------ + // normalize + // ------------------------------------------------------------------------ + + @Test + public void testNormalizeScale0() { + ITmfTimestamp ts = ts0.normalize(0, 0); + assertEquals("getValue", 0, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(12345, 0); + assertEquals("getValue", 12345, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(10, 0); + assertEquals("getValue", 10, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(-10, 0); + assertEquals("getValue", -10, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + } + + @Test + public void testNormalizeScaleNot0() { + ITmfTimestamp ts = ts0.normalize(0, 1); + assertEquals("getValue", 0, ts.getValue()); + assertEquals("getscale", 1, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(12345, 1); + assertEquals("getValue", 12345, ts.getValue()); + assertEquals("getscale", 1, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(10, 1); + assertEquals("getValue", 10, ts.getValue()); + assertEquals("getscale", 1, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(-10, 1); + assertEquals("getValue", -10, ts.getValue()); + assertEquals("getscale", 1, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + } + + // ------------------------------------------------------------------------ + // compareTo + // ------------------------------------------------------------------------ + + @Test + public void testBasicCompareTo() { + final ITmfTimestamp tstamp1 = new TmfNanoTimestamp(900); + final ITmfTimestamp tstamp2 = new TmfNanoTimestamp(1000); + final ITmfTimestamp tstamp3 = new TmfNanoTimestamp(1100); + + assertTrue(tstamp1.compareTo(tstamp1) == 0); + + assertTrue("CompareTo", tstamp1.compareTo(tstamp2) < 0); + assertTrue("CompareTo", tstamp1.compareTo(tstamp3) < 0); + + assertTrue("CompareTo", tstamp2.compareTo(tstamp1) > 0); + assertTrue("CompareTo", tstamp2.compareTo(tstamp3) < 0); + + assertTrue("CompareTo", tstamp3.compareTo(tstamp1) > 0); + assertTrue("CompareTo", tstamp3.compareTo(tstamp2) > 0); + } + + @Test + public void testCompareTo() { + final ITmfTimestamp ts0a = new TmfTimestamp(0, 2, 0); + final ITmfTimestamp ts1a = new TmfTimestamp(123450, -10); + final ITmfTimestamp ts2a = new TmfTimestamp(-12340, -10); + + assertTrue(ts1.compareTo(ts1) == 0); + + assertTrue("CompareTo", ts0.compareTo(ts0a) == 0); + assertTrue("CompareTo", ts1.compareTo(ts1a) == 0); + assertTrue("CompareTo", ts2.compareTo(ts2a) == 0); + } + + // ------------------------------------------------------------------------ + // getDelta + // ------------------------------------------------------------------------ + + @Test + public void testDelta() { + // Delta for same scale and precision (delta > 0) + TmfTimestamp tstamp0 = new TmfNanoTimestamp(10); + TmfTimestamp tstamp1 = new TmfNanoTimestamp(5); + TmfTimestamp expectd = new TmfNanoTimestamp(5); + + ITmfTimestamp delta = tstamp0.getDelta(tstamp1); + assertEquals("getDelta", 0, delta.compareTo(expectd, false)); + + // Delta for same scale and precision (delta < 0) + tstamp0 = new TmfTimestamp(5); + tstamp1 = new TmfTimestamp(10); + expectd = new TmfTimestamp(-5); + + delta = tstamp0.getDelta(tstamp1); + assertEquals("getDelta", 0, delta.compareTo(expectd, false)); + } + + @Test + public void testDelta2() { + // Delta for different scale and same precision (delta > 0) + final TmfTimestamp tstamp0 = new TmfNanoTimestamp(10); + final TmfTimestamp tstamp1 = new TmfTimestamp(1, -8); + final TmfTimestamp expectd = new TmfTimestamp(0, 0); + + final ITmfTimestamp delta = tstamp0.getDelta(tstamp1); + assertEquals("getDelta", 0, delta.compareTo(expectd, false)); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfSimpleTimestampTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfSimpleTimestampTest.java new file mode 100644 index 0000000000..35fa48c6d5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfSimpleTimestampTest.java @@ -0,0 +1,293 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.event; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfSimpleTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.junit.Test; + +/** + * Test suite for the TmfSimpleTimestampTest class. + */ +@SuppressWarnings("javadoc") +public class TmfSimpleTimestampTest { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + private final ITmfTimestamp ts0 = new TmfSimpleTimestamp(); + private final ITmfTimestamp ts1 = new TmfSimpleTimestamp(12345); + private final ITmfTimestamp ts2 = new TmfSimpleTimestamp(-1234); + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + @Test + public void testDefaultConstructor() { + assertEquals("getValue", 0, ts0.getValue()); + assertEquals("getscale", 0, ts0.getScale()); + assertEquals("getPrecision", 0, ts0.getPrecision()); + } + + @Test + public void testFullConstructor() { + assertEquals("getValue", 12345, ts1.getValue()); + assertEquals("getscale", 0, ts1.getScale()); + assertEquals("getPrecision", 0, ts1.getPrecision()); + } + + @Test + public void testCopyConstructor() { + final ITmfTimestamp copy = new TmfSimpleTimestamp(ts1); + + assertEquals("getValue", ts1.getValue(), copy.getValue()); + assertEquals("getscale", ts1.getScale(), copy.getScale()); + assertEquals("getPrecision", ts1.getPrecision(), copy.getPrecision()); + + assertEquals("getValue", 12345, copy.getValue()); + assertEquals("getscale", 0, copy.getScale()); + assertEquals("getPrecision", 0, copy.getPrecision()); + } + + @Test + public void testCopyBadTimestamp() { + try { + new TmfSimpleTimestamp(null); + fail("TmfSimpleTimestamp: null argument"); + } catch (final NullPointerException e) { + } + } + + // ------------------------------------------------------------------------ + // equals + // ------------------------------------------------------------------------ + + @Test + public void testEqualsReflexivity() { + assertTrue("equals", ts0.equals(ts0)); + assertTrue("equals", ts1.equals(ts1)); + assertTrue("equals", ts2.equals(ts2)); + + assertTrue("equals", !ts0.equals(ts1)); + assertTrue("equals", !ts0.equals(ts2)); + + assertTrue("equals", !ts1.equals(ts0)); + assertTrue("equals", !ts1.equals(ts2)); + + assertTrue("equals", !ts2.equals(ts0)); + assertTrue("equals", !ts2.equals(ts1)); + } + + @Test + public void testEqualsSymmetry() { + final ITmfTimestamp ts0copy = new TmfSimpleTimestamp(ts0); + assertTrue("equals", ts0.equals(ts0copy)); + assertTrue("equals", ts0copy.equals(ts0)); + + final ITmfTimestamp ts1copy = new TmfSimpleTimestamp(ts1); + assertTrue("equals", ts1.equals(ts1copy)); + assertTrue("equals", ts1copy.equals(ts1)); + } + + @Test + public void testEqualsTransivity() { + final ITmfTimestamp ts0copy1 = new TmfSimpleTimestamp(ts0); + final ITmfTimestamp ts0copy2 = new TmfSimpleTimestamp(ts0copy1); + assertTrue("equals", ts0.equals(ts0copy1)); + assertTrue("equals", ts0copy1.equals(ts0copy2)); + assertTrue("equals", ts0.equals(ts0copy2)); + + final ITmfTimestamp ts1copy1 = new TmfSimpleTimestamp(ts1); + final ITmfTimestamp ts1copy2 = new TmfSimpleTimestamp(ts1copy1); + assertTrue("equals", ts1.equals(ts1copy1)); + assertTrue("equals", ts1copy1.equals(ts1copy2)); + assertTrue("equals", ts1.equals(ts1copy2)); + } + + @Test + public void testEqualsNull() { + assertTrue("equals", !ts0.equals(null)); + assertTrue("equals", !ts1.equals(null)); + assertTrue("equals", !ts2.equals(null)); + } + + @Test + public void testEqualsNonTimestamp() { + assertFalse("equals", ts0.equals(ts0.toString())); + } + + // ------------------------------------------------------------------------ + // toString + // ------------------------------------------------------------------------ + + @Test + public void testToString() { + DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS"); + Date d0 = new Date(ts0.getValue()*1000); + Date d1 = new Date(ts1.getValue()*1000); + Date d2 = new Date(ts2.getValue()*1000); + assertEquals("toString", df.format(d0) + " 000 000", ts0.toString()); + assertEquals("toString", df.format(d1) + " 000 000", ts1.toString()); + assertEquals("toString", df.format(d2) + " 000 000", ts2.toString()); + } + + // ------------------------------------------------------------------------ + // hashCode + // ------------------------------------------------------------------------ + + @Test + public void testHashCode() { + final ITmfTimestamp ts0copy = new TmfTimestamp(ts0); + final ITmfTimestamp ts1copy = new TmfTimestamp(ts1); + final ITmfTimestamp ts2copy = new TmfTimestamp(ts2); + + assertTrue("hashCode", ts0.hashCode() == ts0copy.hashCode()); + assertTrue("hashCode", ts1.hashCode() == ts1copy.hashCode()); + assertTrue("hashCode", ts2.hashCode() == ts2copy.hashCode()); + + assertTrue("hashCode", ts0.hashCode() != ts1.hashCode()); + } + + // ------------------------------------------------------------------------ + // normalize + // ------------------------------------------------------------------------ + + @Test + public void testNormalizeScale0() { + ITmfTimestamp ts = ts0.normalize(0, 0); + assertEquals("getValue", 0, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(12345, 0); + assertEquals("getValue", 12345, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(10, 0); + assertEquals("getValue", 10, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(-10, 0); + assertEquals("getValue", -10, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + } + + @Test + public void testNormalizeScaleNot0() { + ITmfTimestamp ts = ts0.normalize(0, 1); + assertEquals("getValue", 0, ts.getValue()); + assertEquals("getscale", 1, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(12345, 1); + assertEquals("getValue", 12345, ts.getValue()); + assertEquals("getscale", 1, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(10, 1); + assertEquals("getValue", 10, ts.getValue()); + assertEquals("getscale", 1, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(-10, 1); + assertEquals("getValue", -10, ts.getValue()); + assertEquals("getscale", 1, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + } + + // ------------------------------------------------------------------------ + // compareTo + // ------------------------------------------------------------------------ + + @Test + public void testBasicCompareTo() { + final ITmfTimestamp tstamp1 = new TmfSimpleTimestamp(900); + final ITmfTimestamp tstamp2 = new TmfSimpleTimestamp(1000); + final ITmfTimestamp tstamp3 = new TmfSimpleTimestamp(1100); + + assertTrue(tstamp1.compareTo(tstamp1) == 0); + + assertTrue("CompareTo", tstamp1.compareTo(tstamp2) < 0); + assertTrue("CompareTo", tstamp1.compareTo(tstamp3) < 0); + + assertTrue("CompareTo", tstamp2.compareTo(tstamp1) > 0); + assertTrue("CompareTo", tstamp2.compareTo(tstamp3) < 0); + + assertTrue("CompareTo", tstamp3.compareTo(tstamp1) > 0); + assertTrue("CompareTo", tstamp3.compareTo(tstamp2) > 0); + } + + @Test + public void testCompareTo() { + final ITmfTimestamp ts0a = new TmfTimestamp(0, 2, 0); + final ITmfTimestamp ts1a = new TmfTimestamp(123450, -1); + final ITmfTimestamp ts2a = new TmfTimestamp(-12340, -1); + + assertTrue(ts1.compareTo(ts1) == 0); + + assertTrue("CompareTo", ts0.compareTo(ts0a) == 0); + assertTrue("CompareTo", ts1.compareTo(ts1a) == 0); + assertTrue("CompareTo", ts2.compareTo(ts2a) == 0); + } + + // ------------------------------------------------------------------------ + // getDelta + // ------------------------------------------------------------------------ + + @Test + public void testDelta() { + // Delta for same scale and precision (delta > 0) + TmfTimestamp tstamp0 = new TmfSimpleTimestamp(10); + TmfTimestamp tstamp1 = new TmfSimpleTimestamp(5); + TmfTimestamp expectd = new TmfSimpleTimestamp(5); + + ITmfTimestamp delta = tstamp0.getDelta(tstamp1); + assertEquals("getDelta", 0, delta.compareTo(expectd, false)); + + // Delta for same scale and precision (delta < 0) + tstamp0 = new TmfTimestamp(5); + tstamp1 = new TmfTimestamp(10); + expectd = new TmfTimestamp(-5); + + delta = tstamp0.getDelta(tstamp1); + assertEquals("getDelta", 0, delta.compareTo(expectd, false)); + } + + @Test + public void testDelta2() { + // Delta for different scale and same precision (delta > 0) + final TmfTimestamp tstamp0 = new TmfSimpleTimestamp(10); + final TmfTimestamp tstamp1 = new TmfTimestamp(1, 1); + final TmfTimestamp expectd = new TmfTimestamp(0, 0); + + final ITmfTimestamp delta = tstamp0.getDelta(tstamp1); + assertEquals("getDelta", 0, delta.compareTo(expectd, false)); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimePreferencesTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimePreferencesTest.java new file mode 100644 index 0000000000..36d88595ac --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimePreferencesTest.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.event; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.Map; +import java.util.TimeZone; + +import org.eclipse.core.runtime.preferences.DefaultScope; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimePreferencesConstants; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimePreferences; +import org.junit.Test; +import org.osgi.service.prefs.BackingStoreException; + +/** + * Test suite for the TmfTimePreferences class. + */ +public class TmfTimePreferencesTest { + + private static final String TIME_PATTERN = "HH:mm:ss.SSS SSS SSS"; + private static final String INTERVAL_PATTERN = "TTT.SSS SSS SSS"; + + /** + * Test that the preferences get initialized to the default + */ + @Test + public void testInit() { + assertEquals(DefaultScope.INSTANCE.getNode(Activator.PLUGIN_ID).get(ITmfTimePreferencesConstants.DATIME, null), ITmfTimePreferencesConstants.TIME_HOUR_FMT); + } + + /** + * Test that getInstance returns an instance + */ + @Test + public void testGetInstance() { + assertNotNull(TmfTimePreferences.getInstance()); + } + + /** + * Test that getTimePattern returns the appropriate time pattern (from the default) + */ + @Test + public void testGetTimePattern() { + assertEquals(TIME_PATTERN, TmfTimePreferences.getInstance().getTimePattern()); + } + + /** + * Test that getIntervalPattern returns the appropriate interval pattern (from the default) + */ + @Test + public void testGetIntervalPattern() { + assertEquals(INTERVAL_PATTERN, TmfTimePreferences.getInstance().getIntervalPattern()); + } + + /** + * Test that getTimeZone returns the appropriate time zone (from the default) + */ + @Test + public void testGetTimeZone() { + assertEquals(TimeZone.getDefault(), TmfTimePreferences.getInstance().getTimeZone()); + } + + /** + * Test that getPreferenceMap returns the appropriate map even after preferences get modified + * and make sure it doesn't affect the defaults + */ + @Test + public void testGetPreferenceMap() { + Map defaultPreferenceMap = TmfTimePreferences.getInstance().getDefaultPreferenceMap(); + assertEquals(ITmfTimePreferencesConstants.TIME_HOUR_FMT, defaultPreferenceMap.get(ITmfTimePreferencesConstants.DATIME)); + + // Modify the preferences + String testValue = ITmfTimePreferencesConstants.TIME_HOUR_FMT + "foo"; + IEclipsePreferences node = InstanceScope.INSTANCE.getNode(Activator.PLUGIN_ID); + node.put(ITmfTimePreferencesConstants.DATIME, testValue); + try { + node.flush(); + } catch (BackingStoreException e) { + } + // Make sure the modification is in the map + Map preferenceMap = TmfTimePreferences.getInstance().getPreferenceMap(); + assertEquals(testValue, preferenceMap.get(ITmfTimePreferencesConstants.DATIME)); + + // Make sure the default is still the same + defaultPreferenceMap = TmfTimePreferences.getInstance().getDefaultPreferenceMap(); + assertEquals(ITmfTimePreferencesConstants.TIME_HOUR_FMT, defaultPreferenceMap.get(ITmfTimePreferencesConstants.DATIME)); + } + + /** + * Test that computeTimePattern computes the appropriate time pattern from a preference map (from the default) + */ + @Test + public void testComputeTimePattern() { + assertEquals(TIME_PATTERN, TmfTimePreferences.getInstance().computeTimePattern(TmfTimePreferences.getInstance().getPreferenceMap())); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimeRangeTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimeRangeTest.java new file mode 100644 index 0000000000..50ba63a9f3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimeRangeTest.java @@ -0,0 +1,373 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Adjusted for new Event Model + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.event; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.junit.Test; + +/** + * Test suite for the TmfTimeRange class. + */ +@SuppressWarnings("javadoc") +public class TmfTimeRangeTest { + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + @Test + public void testConstructor() { + final ITmfTimestamp ts1 = new TmfTimestamp(12345); + final ITmfTimestamp ts2 = new TmfTimestamp(12350); + final TmfTimeRange range = new TmfTimeRange(ts1, ts2); + + assertEquals("startTime", ts1, range.getStartTime()); + assertEquals("endTime", ts2, range.getEndTime()); + } + + @Test + public void testBadConstructor() { + try { + new TmfTimeRange(TmfTimestamp.BIG_BANG, null); + fail("TmfTimeRange: bad end time"); + } catch (final IllegalArgumentException e) { + // Success + } + + try { + new TmfTimeRange(null, TmfTimestamp.BIG_CRUNCH); + fail("TmfTimeRange: bad start time"); + } catch (final IllegalArgumentException e) { + // Success + } + } + + @Test + public void testOpenRange1() { + final ITmfTimestamp ts2 = new TmfTimestamp(12350); + final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, ts2); + + assertEquals("startTime", TmfTimestamp.BIG_BANG, range.getStartTime()); + assertEquals("endTime", ts2, range.getEndTime()); + } + + @Test + public void testOpenRange2() { + final ITmfTimestamp ts1 = new TmfTimestamp(12345); + final TmfTimeRange range = new TmfTimeRange(ts1, TmfTimestamp.BIG_CRUNCH); + + assertEquals("startTime", ts1, range.getStartTime()); + assertEquals("endTime", TmfTimestamp.BIG_CRUNCH, range.getEndTime()); + } + + @Test + public void testOpenRange3() { + final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + + assertEquals("startTime", TmfTimestamp.BIG_BANG, range.getStartTime()); + assertEquals("endTime", TmfTimestamp.BIG_CRUNCH, range.getEndTime()); + } + + @Test + public void testCopyConstructor() { + final ITmfTimestamp ts1 = new TmfTimestamp(12345); + final ITmfTimestamp ts2 = new TmfTimestamp(12350); + final TmfTimeRange range0 = new TmfTimeRange(ts1, ts2); + final TmfTimeRange range1 = new TmfTimeRange(range0); + + assertEquals("startTime", ts1, range1.getStartTime()); + assertEquals("endTime", ts2, range1.getEndTime()); + + final TmfTimeRange range2 = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + final TmfTimeRange range3 = new TmfTimeRange(range2); + + assertEquals("startTime", TmfTimestamp.BIG_BANG, range3.getStartTime()); + assertEquals("endTime", TmfTimestamp.BIG_CRUNCH, range3.getEndTime()); + } + + @Test + public void testCopyConstructor2() { + try { + new TmfTimeRange(null); + fail("TmfTimeRange: null argument"); + } catch (final IllegalArgumentException e) { + // Success + } + } + + // ------------------------------------------------------------------------ + // hashCode + // ------------------------------------------------------------------------ + + @Test + public void testHashCode() { + final ITmfTimestamp ts1 = new TmfTimestamp(12345); + final ITmfTimestamp ts2 = new TmfTimestamp(12350); + final TmfTimeRange range1 = new TmfTimeRange(ts1, ts2); + final TmfTimeRange range1b = new TmfTimeRange(range1); + final TmfTimeRange range2 = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + final TmfTimeRange range2b = new TmfTimeRange(range2); + + assertTrue("hashCode", range1.hashCode() == range1b.hashCode()); + assertTrue("hashCode", range2.hashCode() == range2b.hashCode()); + + assertTrue("hashCode", range1.hashCode() != range2.hashCode()); + } + + // ------------------------------------------------------------------------ + // equals + // ------------------------------------------------------------------------ + + @Test + public void testEqualsReflexivity() { + final ITmfTimestamp ts1 = new TmfTimestamp(12345); + final ITmfTimestamp ts2 = new TmfTimestamp(12350); + final TmfTimeRange range1 = new TmfTimeRange(ts1, ts2); + final TmfTimeRange range2 = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + + assertTrue("equals", range1.equals(range1)); + assertTrue("equals", range2.equals(range2)); + + assertTrue("equals", !range1.equals(range2)); + assertTrue("equals", !range2.equals(range1)); + } + + @Test + public void testEqualsSymmetry() { + final ITmfTimestamp ts1 = new TmfTimestamp(12345); + final ITmfTimestamp ts2 = new TmfTimestamp(12350); + final TmfTimeRange range1a = new TmfTimeRange(ts1, ts2); + final TmfTimeRange range1b = new TmfTimeRange(ts1, ts2); + + final TmfTimeRange range2a = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + final TmfTimeRange range2b = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + + assertTrue("equals", range1a.equals(range1b)); + assertTrue("equals", range1b.equals(range1a)); + + assertTrue("equals", range2a.equals(range2b)); + assertTrue("equals", range2b.equals(range2a)); + } + + @Test + public void testEqualsTransivity() { + final ITmfTimestamp ts1 = new TmfTimestamp(12345); + final ITmfTimestamp ts2 = new TmfTimestamp(12350); + final TmfTimeRange range1a = new TmfTimeRange(ts1, ts2); + final TmfTimeRange range1b = new TmfTimeRange(ts1, ts2); + final TmfTimeRange range1c = new TmfTimeRange(ts1, ts2); + + assertTrue("equals", range1a.equals(range1b)); + assertTrue("equals", range1b.equals(range1c)); + assertTrue("equals", range1a.equals(range1c)); + } + + @Test + public void testEqualsNull() { + final ITmfTimestamp ts1 = new TmfTimestamp(12345); + final ITmfTimestamp ts2 = new TmfTimestamp(12350); + final TmfTimeRange range1 = new TmfTimeRange(ts1, ts2); + + assertTrue("equals", !range1.equals(null)); + } + + @Test + public void testEqualsBadType() { + final ITmfTimestamp ts1 = new TmfTimestamp(12345); + final ITmfTimestamp ts2 = new TmfTimestamp(12350); + final TmfTimeRange range1 = new TmfTimeRange(ts1, ts2); + + assertTrue("equals", !range1.equals(ts1)); + } + + @Test + public void testEqualStartTime() { + final ITmfTimestamp ts1 = new TmfTimestamp(12345); + final ITmfTimestamp ts2 = new TmfTimestamp(12350); + final ITmfTimestamp ts3 = new TmfTimestamp(12355); + + final TmfTimeRange range1 = new TmfTimeRange(ts1, ts3); + final TmfTimeRange range2 = new TmfTimeRange(ts2, ts3); + final TmfTimeRange range3 = new TmfTimeRange(ts1, ts2); + + assertTrue("equals", !range1.equals(range2)); + assertTrue("equals", !range1.equals(range3)); + } + + @Test + public void testEqualsEndTime() { + final ITmfTimestamp ts1 = new TmfTimestamp(12345); + final ITmfTimestamp ts2 = new TmfTimestamp(12350); + final ITmfTimestamp ts3 = new TmfTimestamp(12355); + + final TmfTimeRange range1 = new TmfTimeRange(ts1, ts2); + final TmfTimeRange range2 = new TmfTimeRange(ts1, ts3); + final TmfTimeRange range3 = new TmfTimeRange(ts2, ts3); + + assertTrue("equals", !range1.equals(range2)); + assertTrue("equals", !range1.equals(range3)); + } + + // ------------------------------------------------------------------------ + // toString + // ------------------------------------------------------------------------ + + @Test + public void testToString() { + final ITmfTimestamp ts1 = new TmfTimestamp(12345); + final ITmfTimestamp ts2 = new TmfTimestamp(12350); + final TmfTimeRange range = new TmfTimeRange(ts1, ts2); + + final String expected = "TmfTimeRange [fStartTime=" + ts1 + ", fEndTime=" + ts2 + "]"; + assertEquals("toString", expected, range.toString()); + } + + // ------------------------------------------------------------------------ + // contains + // ------------------------------------------------------------------------ + + @Test + public void testContainsTimestamp() { + final ITmfTimestamp ts1 = new TmfTimestamp(12345); + final ITmfTimestamp ts2 = new TmfTimestamp(12350); + final TmfTimeRange range = new TmfTimeRange(ts1, ts2); + + assertTrue("contains (lower bound)", range.contains(new TmfTimestamp(12345))); + assertTrue("contains (higher bound)", range.contains(new TmfTimestamp(12350))); + assertTrue("contains (within bounds)", range.contains(new TmfTimestamp(12346))); + + assertFalse("contains (low value)", range.contains(new TmfTimestamp(12340))); + assertFalse("contains (high value)", range.contains(new TmfTimestamp(12351))); + } + + @Test + public void testContainsRange() { + final ITmfTimestamp ts1 = new TmfTimestamp(10); + final ITmfTimestamp ts2 = new TmfTimestamp(20); + final ITmfTimestamp ts3 = new TmfTimestamp(30); + final ITmfTimestamp ts4 = new TmfTimestamp(40); + final ITmfTimestamp ts5 = new TmfTimestamp(50); + final ITmfTimestamp ts6 = new TmfTimestamp(60); + final ITmfTimestamp ts7 = new TmfTimestamp(70); + final ITmfTimestamp ts8 = new TmfTimestamp(80); + + // Reference range + final TmfTimeRange range0 = new TmfTimeRange(ts3, ts6); + + // Start time below range + final TmfTimeRange range1 = new TmfTimeRange(ts1, ts2); + final TmfTimeRange range2 = new TmfTimeRange(ts2, ts3); + final TmfTimeRange range3 = new TmfTimeRange(ts2, ts4); + final TmfTimeRange range4 = new TmfTimeRange(ts2, ts6); + final TmfTimeRange range5 = new TmfTimeRange(ts2, ts7); + + assertFalse("contains", range0.contains(range1)); + assertFalse("contains", range0.contains(range2)); + assertFalse("contains", range0.contains(range3)); + assertFalse("contains", range0.contains(range4)); + assertFalse("contains", range0.contains(range5)); + + // End time above range + final TmfTimeRange range6 = new TmfTimeRange(ts3, ts7); + final TmfTimeRange range7 = new TmfTimeRange(ts4, ts7); + final TmfTimeRange range8 = new TmfTimeRange(ts6, ts7); + final TmfTimeRange range9 = new TmfTimeRange(ts7, ts8); + + assertFalse("contains", range0.contains(range6)); + assertFalse("contains", range0.contains(range7)); + assertFalse("contains", range0.contains(range8)); + assertFalse("contains", range0.contains(range9)); + + // Within range + final TmfTimeRange range10 = new TmfTimeRange(ts3, ts4); + final TmfTimeRange range11 = new TmfTimeRange(ts3, ts6); + final TmfTimeRange range12 = new TmfTimeRange(ts4, ts5); + final TmfTimeRange range13 = new TmfTimeRange(ts4, ts6); + + assertTrue("contains", range0.contains(range10)); + assertTrue("contains", range0.contains(range11)); + assertTrue("contains", range0.contains(range12)); + assertTrue("contains", range0.contains(range13)); + } + + // ------------------------------------------------------------------------ + // getIntersection + // ------------------------------------------------------------------------ + + @Test + public void testGetIntersection() { + + final ITmfTimestamp ts1a = new TmfTimestamp(1000); + final ITmfTimestamp ts1b = new TmfTimestamp(2000); + final TmfTimeRange range1 = new TmfTimeRange(ts1a, ts1b); + + final ITmfTimestamp ts2a = new TmfTimestamp(2000); + final ITmfTimestamp ts2b = new TmfTimestamp(3000); + final TmfTimeRange range2 = new TmfTimeRange(ts2a, ts2b); + + final ITmfTimestamp ts3a = new TmfTimestamp(3000); + final ITmfTimestamp ts3b = new TmfTimestamp(4000); + final TmfTimeRange range3 = new TmfTimeRange(ts3a, ts3b); + + final ITmfTimestamp ts4a = new TmfTimestamp(1500); + final ITmfTimestamp ts4b = new TmfTimestamp(2500); + final TmfTimeRange range4 = new TmfTimeRange(ts4a, ts4b); + + final ITmfTimestamp ts5a = new TmfTimestamp(1500); + final ITmfTimestamp ts5b = new TmfTimestamp(2000); + final TmfTimeRange range5 = new TmfTimeRange(ts5a, ts5b); + + final ITmfTimestamp ts6a = new TmfTimestamp(2000); + final ITmfTimestamp ts6b = new TmfTimestamp(2500); + final TmfTimeRange range6 = new TmfTimeRange(ts6a, ts6b); + + final ITmfTimestamp ts7a = new TmfTimestamp(1500); + final ITmfTimestamp ts7b = new TmfTimestamp(3500); + final TmfTimeRange range7 = new TmfTimeRange(ts7a, ts7b); + + final ITmfTimestamp ts8a = new TmfTimestamp(2250); + final ITmfTimestamp ts8b = new TmfTimestamp(2750); + final TmfTimeRange range8 = new TmfTimeRange(ts8a, ts8b); + + assertEquals("getIntersection (below - not contiguous)", null, range1.getIntersection(range3)); + assertEquals("getIntersection (above - not contiguous)", null, range3.getIntersection(range1)); + + assertEquals("getIntersection (below - contiguous)", new TmfTimeRange(ts1b, ts1b), range1.getIntersection(range2)); + assertEquals("getIntersection (above - contiguous)", new TmfTimeRange(ts3a, ts3a), range3.getIntersection(range2)); + + assertEquals("getIntersection (below - overlap)", new TmfTimeRange(ts2a, ts4b), range2.getIntersection(range4)); + assertEquals("getIntersection (above - overlap)", new TmfTimeRange(ts2a, ts4b), range4.getIntersection(range2)); + + assertEquals("getIntersection (within - overlap1)", range6, range2.getIntersection(range6)); + assertEquals("getIntersection (within - overlap2)", range6, range6.getIntersection(range2)); + + assertEquals("getIntersection (within - overlap3)", range5, range1.getIntersection(range5)); + assertEquals("getIntersection (within - overlap4)", range5, range5.getIntersection(range1)); + + assertEquals("getIntersection (within - overlap5)", range8, range2.getIntersection(range8)); + assertEquals("getIntersection (within - overlap6)", range8, range8.getIntersection(range2)); + + assertEquals("getIntersection (accross1)", range2, range2.getIntersection(range7)); + assertEquals("getIntersection (accross2)", range2, range7.getIntersection(range2)); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimestampDeltaTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimestampDeltaTest.java new file mode 100644 index 0000000000..02d94fc3a3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimestampDeltaTest.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.event; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampDelta; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; +import org.junit.Test; + +/** + * Test suite for the TmfTimestampDelta class. + */ +@SuppressWarnings("javadoc") +public class TmfTimestampDeltaTest { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + private final ITmfTimestamp ts0 = new TmfTimestampDelta(); + private final ITmfTimestamp ts1 = new TmfTimestampDelta(12345, 0); + private final ITmfTimestamp ts2 = new TmfTimestampDelta(12345, -1); + private final ITmfTimestamp ts3 = new TmfTimestampDelta(12345, 2, 5); + private final ITmfTimestamp ts4 = new TmfTimestampDelta(-12345, -5); + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + @Test + public void testDefaultConstructor() { + assertEquals("getValue", 0, ts0.getValue()); + assertEquals("getscale", 0, ts0.getScale()); + assertEquals("getPrecision", 0, ts0.getPrecision()); + } + + @Test + public void testValueConstructor() { + assertEquals("getValue", 12345, ts1.getValue()); + assertEquals("getscale", 0, ts1.getScale()); + assertEquals("getPrecision", 0, ts1.getPrecision()); + } + + @Test + public void testValueScaleConstructor() { + assertEquals("getValue", 12345, ts2.getValue()); + assertEquals("getscale", -1, ts2.getScale()); + assertEquals("getPrecision", 0, ts2.getPrecision()); + } + + @Test + public void testFullConstructor() { + assertEquals("getValue", 12345, ts3.getValue()); + assertEquals("getscale", 2, ts3.getScale()); + assertEquals("getPrecision", 5, ts3.getPrecision()); + + assertEquals("getValue", -12345, ts4.getValue()); + assertEquals("getscale", -5, ts4.getScale()); + assertEquals("getPrecision", 0, ts4.getPrecision()); + } + + @Test + public void testCopyConstructor() { + final ITmfTimestamp ts = new TmfTimestamp(12345, 2, 5); + final ITmfTimestamp copy = new TmfTimestamp(ts); + + assertEquals("getValue", ts.getValue(), copy.getValue()); + assertEquals("getscale", ts.getScale(), copy.getScale()); + assertEquals("getPrecision", ts.getPrecision(), copy.getPrecision()); + + assertEquals("getValue", 12345, copy.getValue()); + assertEquals("getscale", 2, copy.getScale()); + assertEquals("getPrecision", 5, copy.getPrecision()); + } + + @Test(expected=IllegalArgumentException.class) + public void testCopyNullConstructor() { + new TmfTimestamp((TmfTimestamp) null); + } + + // ------------------------------------------------------------------------ + // normalize + // ------------------------------------------------------------------------ + + @Test + public void testNormalizeOffset() { + ITmfTimestamp ts = ts0.normalize(12345, 0); + assertTrue("instance", ts instanceof TmfTimestampDelta); + assertEquals("getValue", 12345, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + } + + // ------------------------------------------------------------------------ + // toString + // ------------------------------------------------------------------------ + + @Test + public void testToStringDefault() { + assertEquals("toString", "000.000 000 000", ts0.toString()); + assertEquals("toString", "12345.000 000 000", ts1.toString()); + assertEquals("toString", "1234.500 000 000", ts2.toString()); + assertEquals("toString", "1234500.000 000 000", ts3.toString()); + assertEquals("toString", "-000.123 450 000", ts4.toString()); + } + + @Test + public void testToStringFormat() { + TmfTimestampFormat format = new TmfTimestampFormat("HH:mm:ss.SSS CCC NNN"); + assertEquals("toString", "00:00:00.000 000 000", ts0.toString(format)); + assertEquals("toString", "03:25:45.000 000 000", ts1.toString(format)); + assertEquals("toString", "00:20:34.500 000 000", ts2.toString(format)); + assertEquals("toString", "06:55:00.000 000 000", ts3.toString(format)); + assertEquals("toString", "-00:00:00.123 450 000", ts4.toString(format)); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimestampFormatTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimestampFormatTest.java new file mode 100644 index 0000000000..fa95d83fd2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimestampFormatTest.java @@ -0,0 +1,386 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + * Matthew Khouzam - Added timestamp string tests + * Patrick Tasse - Updated for fraction of second + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.event; + +import static org.junit.Assert.assertEquals; + +import java.text.ParseException; +import java.util.Locale; +import java.util.TimeZone; + +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimePreferencesConstants; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimePreferences; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; +import org.junit.Test; +import org.osgi.service.prefs.BackingStoreException; + +/** + * Test suite for the TmfTimestampFormat class. + */ +public class TmfTimestampFormatTest { + + private static final String TEST_PATTERN = "HH:mm:ss.SSS"; + private static final TimeZone TEST_TIME_ZONE = TimeZone.getTimeZone(TimeZone.getAvailableIDs(0)[0]); + private static final TimeZone GMT = TimeZone.getTimeZone("GMT"); + private static final Locale CA = Locale.CANADA; + + private static final TmfTimestampFormat tsf = new TmfTimestampFormat("yyyy-MM-dd HH:mm:ss.SSSSSSSSS", GMT, CA); + private static final TmfTimestampFormat tsf1 = new TmfTimestampFormat(TEST_PATTERN); + private static final TmfTimestampFormat tsf2 = new TmfTimestampFormat(TEST_PATTERN, TEST_TIME_ZONE); + + /** + * Test that the default value is loaded when using the default constructor + */ + @Test + public void testDefaultConstructor() { + TmfTimestampFormat ts0 = new TmfTimestampFormat(); + assertEquals("HH:mm:ss.SSS SSS SSS", ts0.toPattern()); + } + + /** + * Test that the value constructor properly assigns the value + */ + @Test + public void testValueConstructor() { + assertEquals(TEST_PATTERN, tsf1.toPattern()); + } + + /** + * Test that the value constructor using a time zone properly assigns the + * pattern and time zone + */ + @Test + public void testValueTimeZoneConstructor() { + assertEquals(TEST_PATTERN, tsf2.toPattern()); + assertEquals(TEST_TIME_ZONE, tsf2.getTimeZone()); + } + + /** + * Make sure that the default formats in TmfTimestampFormat get updated when + * updateDefaultFormats is called. + */ + @Test + public void testUpdateDefaultFormats() { + IEclipsePreferences node = InstanceScope.INSTANCE.getNode(Activator.PLUGIN_ID); + + String dateTimeTestValue = ITmfTimePreferencesConstants.TIME_HOUR_FMT + ":"; + node.put(ITmfTimePreferencesConstants.DATIME, dateTimeTestValue); + + String subSecTestValue = ITmfTimePreferencesConstants.SUBSEC_NANO_FMT + ":"; + node.put(ITmfTimePreferencesConstants.SUBSEC, subSecTestValue); + try { + node.flush(); + } catch (BackingStoreException e) { + } + TmfTimestampFormat.updateDefaultFormats(); + String expected = dateTimeTestValue + "." + subSecTestValue; + String expected2 = "TTT." + subSecTestValue; + assertEquals(expected, TmfTimestampFormat.getDefaulTimeFormat().toPattern()); + assertEquals(expected2, TmfTimestampFormat.getDefaulIntervalFormat().toPattern()); + // Revert preferences + node.put(ITmfTimePreferencesConstants.DATIME, ITmfTimePreferencesConstants.TIME_HOUR_FMT); + node.put(ITmfTimePreferencesConstants.SUBSEC, ITmfTimePreferencesConstants.SUBSEC_NANO_FMT); + try { + node.flush(); + } catch (BackingStoreException e) { + } + TmfTimestampFormat.updateDefaultFormats(); + } + + /** + * Test that getDefaulTimeFormat returns the appropriate value (from the + * default) + */ + @Test + public void testGetDefaulTimeFormat() { + assertEquals(TmfTimestampFormat.getDefaulTimeFormat().toPattern(), TmfTimePreferences.getInstance().getTimePattern()); + } + + /** + * Test that getDefaulIntervalFormat returns the appropriate value (from the + * default) + */ + @Test + public void testGetDefaulIntervalFormat() { + assertEquals(TmfTimestampFormat.getDefaulIntervalFormat().toPattern(), TmfTimePreferences.getInstance().getIntervalPattern()); + } + + /** + * Test parsing of seconds and sub-seconds + * + * @throws ParseException + * should not happen, if it does, the test is a failure + */ + @Test + public void testParseSeconds() throws ParseException { + assertEquals(7777777777123456789L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7777777777.123456789")); + assertEquals(7777777777123456789L, new TmfTimestampFormat("T.SSSSSSSSS").parseValue("7777777777.123456789")); + assertEquals(7123456789L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("0000000007.123456789")); + assertEquals(7123456789L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.123456789")); + assertEquals(7123456780L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.12345678")); + assertEquals(7123456700L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.1234567")); + assertEquals(7123456000L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.123456")); + assertEquals(7123450000L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.12345")); + assertEquals(7123400000L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.1234")); + assertEquals(7123000000L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.123")); + assertEquals(7120000000L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.12")); + assertEquals(7100000000L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.1")); + assertEquals(7000000000L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7.")); + assertEquals(7000000000L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue("7")); + assertEquals(123456789L, new TmfTimestampFormat("TTTTTTTTTT.SSSSSSSSS").parseValue(".123456789")); + assertEquals(123456789L, new TmfTimestampFormat(".SSSSSSSSS").parseValue(".123456789")); + assertEquals(123456780L, new TmfTimestampFormat(".SSSSSSSS").parseValue(".123456789")); + assertEquals(123456700L, new TmfTimestampFormat(".SSSSSSS").parseValue(".123456789")); + assertEquals(123456000L, new TmfTimestampFormat(".SSSSSS").parseValue(".123456789")); + assertEquals(123450000L, new TmfTimestampFormat(".SSSSS").parseValue(".123456789")); + assertEquals(123400000L, new TmfTimestampFormat(".SSSS").parseValue(".123456789")); + assertEquals(123000000L, new TmfTimestampFormat(".SSS").parseValue(".123456789")); + assertEquals(120000000L, new TmfTimestampFormat(".SS").parseValue(".123456789")); + assertEquals(100000000L, new TmfTimestampFormat(".S").parseValue(".123456789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSSSSSSSS").parseValue("7.123456789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS SSS SSS").parseValue("7.123 456 789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS SSS SSS").parseValue("7.123456789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS.SSS.SSS").parseValue("7.123.456.789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS.SSS.SSS").parseValue("7.123456789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS,SSS,SSS").parseValue("7.123,456,789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS,SSS,SSS").parseValue("7.123456789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS-SSS-SSS").parseValue("7.123-456-789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS-SSS-SSS").parseValue("7.123456789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS_SSS_SSS").parseValue("7.123_456_789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS_SSS_SSS").parseValue("7.123456789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS:SSS:SSS").parseValue("7.123:456:789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS:SSS:SSS").parseValue("7.123456789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS;SSS;SSS").parseValue("7.123;456;789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS;SSS;SSS").parseValue("7.123456789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS/SSS/SSS").parseValue("7.123/456/789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS/SSS/SSS").parseValue("7.123456789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS''SSS''SSS").parseValue("7.123'456'789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS''SSS''SSS").parseValue("7.123456789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS\"SSS\"SSS").parseValue("7.123\"456\"789")); + assertEquals(7123456789L, new TmfTimestampFormat("T.SSS\"SSS\"SSS").parseValue("7.123456789")); + assertEquals(7000000000L, new TmfTimestampFormat("T. SSSSSSSSS").parseValue("7..123456789")); + assertEquals(7100000000L, new TmfTimestampFormat("T.S SSSSSSSS").parseValue("7.1,23456789")); + assertEquals(7120000000L, new TmfTimestampFormat("T.SS SSSSSSS").parseValue("7.12-3456789")); + assertEquals(7123000000L, new TmfTimestampFormat("T.SSS SSSSSS").parseValue("7.123_456789")); + assertEquals(7123400000L, new TmfTimestampFormat("T.SSSS SSSSS").parseValue("7.1234:56789")); + assertEquals(7123450000L, new TmfTimestampFormat("T.SSSSS SSSS").parseValue("7.12345;6789")); + assertEquals(7123456000L, new TmfTimestampFormat("T.SSSSSS SSS").parseValue("7.123456/789")); + assertEquals(7123456700L, new TmfTimestampFormat("T.SSSSSSS SS").parseValue("7.1234567'89")); + assertEquals(7123456780L, new TmfTimestampFormat("T.SSSSSSSS S").parseValue("7.12345678\"9")); + assertEquals(7123456789L, new TmfTimestampFormat("T 's'.SSS ms SSS us SSS ns").parseValue("7 s.123 ms 456 us 789 ns")); + assertEquals(7123456789L, new TmfTimestampFormat("T 'S'.SSS 'MS' SSS 'US' SSS 'NS'").parseValue("7 S.123 MS 456 US 789 NS")); + assertEquals(7123000000L, new TmfTimestampFormat("T.SSSSSSSSS").parseValue("7 s.123 ms 456 ns 789")); + assertEquals(0L, new TmfTimestampFormat("T.").parseValue("0.123456789")); + assertEquals(0L, new TmfTimestampFormat("T.S").parseValue(".")); + assertEquals(0L, new TmfTimestampFormat(".S").parseValue("7.")); + assertEquals(0L, new TmfTimestampFormat("T.S").parseValue("-.")); + assertEquals(0L, new TmfTimestampFormat("T.S").parseValue("-0")); + assertEquals(-100000000L, new TmfTimestampFormat("T.S").parseValue("-0.1")); + assertEquals(-100000000L, new TmfTimestampFormat("T.S").parseValue("-.1")); + assertEquals(-7000000000L, new TmfTimestampFormat("T.S").parseValue("-7")); + assertEquals(-7000000000L, new TmfTimestampFormat("T.S").parseValue("-7.")); + assertEquals(-7000000000L, new TmfTimestampFormat("T.S").parseValue("-7.0")); + assertEquals(-7100000000L, new TmfTimestampFormat("T.S").parseValue("-7.1")); + } + + /** + * Test parsing of date and time patterns + * + * @throws ParseException + * should not happen, if it does, the test is a failure + */ + @Test + public void testParseDateTime() throws ParseException { +// long ref = tsf.parseValue("2014-11-22 12:34:56.123456789"); // Saturday + long time; + + time = new TmfTimestampFormat("yyyy", GMT, CA).parseValue("2014"); + assertEquals("2014-01-01 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("YYYY", GMT, CA).parseValue("2014"); + assertEquals("2013-12-29 00:00:00.000000000", tsf.format(time)); // 1st day of week 1 + + time = new TmfTimestampFormat("MM", GMT, CA).parseValue("11"); + assertEquals("1970-11-01 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("ww", GMT, CA).parseValue("01"); + assertEquals("1969-12-28 00:00:00.000000000", tsf.format(time)); // Sunday of week 1 + + time = new TmfTimestampFormat("DDD", GMT, CA).parseValue("100"); + assertEquals("1970-04-10 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("F", GMT, CA).parseValue("2"); + assertEquals("1970-01-11 00:00:00.000000000", tsf.format(time)); // 2nd Sunday of month + + time = new TmfTimestampFormat("EEE", GMT, CA).parseValue("Mon"); + assertEquals("1970-01-05 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("u", GMT, CA).parseValue("1"); + assertEquals("1970-01-05 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("dd", GMT, CA).parseValue("22"); + assertEquals("1970-01-22 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("HH", GMT, CA).parseValue("12"); + assertEquals("1970-01-01 12:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("kk", GMT, CA).parseValue("24"); + assertEquals("1970-01-01 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("KK", GMT, CA).parseValue("12"); + assertEquals("1970-01-01 12:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("hh", GMT, CA).parseValue("12"); + assertEquals("1970-01-01 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("mm", GMT, CA).parseValue("34"); + assertEquals("1970-01-01 00:34:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("ss", GMT, CA).parseValue("56"); + assertEquals("1970-01-01 00:00:56.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy-MM", GMT, CA).parseValue("2014-11"); + assertEquals("2014-11-01 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy-MM-dd", GMT, CA).parseValue("2014-11-22"); + assertEquals("2014-11-22 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy-MM-dd HH", GMT, CA).parseValue("2014-11-22 12"); + assertEquals("2014-11-22 12:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy-MM-dd HH:mm", GMT, CA).parseValue("2014-11-22 12:34"); + assertEquals("2014-11-22 12:34:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy-MM-dd HH:mm:ss", GMT, CA).parseValue("2014-11-22 12:34:56"); + assertEquals("2014-11-22 12:34:56.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy-MM-dd HH:mm:ss.SSS", GMT, CA).parseValue("2014-11-22 12:34:56.123"); + assertEquals("2014-11-22 12:34:56.123000000", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy-ww", GMT, CA).parseValue("2014-01"); + assertEquals("2013-12-29 00:00:00.000000000", tsf.format(time)); // Sunday of week 1 + + time = new TmfTimestampFormat("yyyy-DDD", GMT, CA).parseValue("2014-100"); + assertEquals("2014-04-10 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy-MM-F", GMT, CA).parseValue("2014-11-2"); + assertEquals("2014-11-09 00:00:00.000000000", tsf.format(time)); // 2nd Sunday of month + + time = new TmfTimestampFormat("yyyy-MM-EEE", GMT, CA).parseValue("2014-11-Mon"); + assertEquals("2014-11-03 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy-MM-u", GMT, CA).parseValue("2014-11-1"); + assertEquals("2014-11-03 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy MM dd HH mm ss SSS SSS SSS", GMT, CA).parseValue("2014 11 22 12 34 56 123 456 789"); + assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy.MM.dd.HH.mm.ss.SSS.SSS.SSS", GMT, CA).parseValue("2014.11.22.12.34.56.123.456.789"); + assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy,MM,dd,HH,mm,ss,SSS,SSS,SSS", GMT, CA).parseValue("2014,11,22,12,34,56,123,456,789"); + assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy-MM-dd-HH-mm-ss-SSS-SSS-SSS", GMT, CA).parseValue("2014-11-22-12-34-56-123-456-789"); + assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy_MM_dd_HH_mm_ss_SSS_SSS_SSS", GMT, CA).parseValue("2014_11_22_12_34_56_123_456_789"); + assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy:MM:dd:HH:mm:ss:SSS:SSS:SSS", GMT, CA).parseValue("2014:11:22:12:34:56:123:456:789"); + assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy;MM;dd;HH;mm;ss;SSS;SSS;SSS", GMT, CA).parseValue("2014;11;22;12;34;56;123;456;789"); + assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy/MM/dd/HH/mm/ss/SSS/SSS/SSS", GMT, CA).parseValue("2014/11/22/12/34/56/123/456/789"); + assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy''MM''dd''HH''mm''ss''SSS''SSS''SSS", GMT, CA).parseValue("2014'11'22'12'34'56'123'456'789"); + assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); + + time = new TmfTimestampFormat("yyyy\"MM\"dd\"HH\"mm\"ss\"SSS\"SSS\"SSS", GMT, CA).parseValue("2014\"11\"22\"12\"34\"56\"123\"456\"789"); + assertEquals("2014-11-22 12:34:56.123456789", tsf.format(time)); + } + + /** + * Test parsing of date and time patterns with reference time + * + * @throws ParseException + * should not happen, if it does, the test is a failure + */ + @Test + public void testParseDateTimeWithRef() throws ParseException { + long ref = tsf.parseValue("2014-11-22 12:34:56.123456789"); // Saturday + long time; + + time = new TmfTimestampFormat("yyyy", GMT, CA).parseValue("1970", ref); + assertEquals("1970-01-01 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("YYYY", GMT, CA).parseValue("1970", ref); + assertEquals("1969-12-28 00:00:00.000000000", tsf.format(time)); // 1st day of week 1 + + time = new TmfTimestampFormat("MM", GMT, CA).parseValue("01", ref); + assertEquals("2014-01-01 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("ww", GMT, CA).parseValue("01", ref); + assertEquals("2014-01-04 00:00:00.000000000", tsf.format(time)); // Saturday of week 1 + + time = new TmfTimestampFormat("DDD", GMT, CA).parseValue("1", ref); + assertEquals("2014-01-01 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("F", GMT, CA).parseValue("2", ref); + assertEquals("2014-11-08 00:00:00.000000000", tsf.format(time)); // 2nd Saturday of month + + time = new TmfTimestampFormat("EEE", GMT, CA).parseValue("Mon", ref); + assertEquals("2014-11-17 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("u", GMT, CA).parseValue("1", ref); + assertEquals("2014-11-17 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("dd", GMT, CA).parseValue("01", ref); + assertEquals("2014-11-01 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("HH", GMT, CA).parseValue("00", ref); + assertEquals("2014-11-22 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("kk", GMT, CA).parseValue("24", ref); + assertEquals("2014-11-22 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("KK", GMT, CA).parseValue("00", ref); + assertEquals("2014-11-22 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("hh", GMT, CA).parseValue("12", ref); + assertEquals("2014-11-22 00:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("mm", GMT, CA).parseValue("00", ref); + assertEquals("2014-11-22 12:00:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat("ss", GMT, CA).parseValue("00", ref); + assertEquals("2014-11-22 12:34:00.000000000", tsf.format(time)); + + time = new TmfTimestampFormat(".S", GMT, CA).parseValue(".9", ref); + assertEquals("2014-11-22 12:34:56.900000000", tsf.format(time)); + + time = new TmfTimestampFormat("T.S", GMT, CA).parseValue("8.9", ref); + assertEquals("1970-01-01 00:00:08.900000000", tsf.format(time)); + + time = new TmfTimestampFormat("T.S", GMT, CA).parseValue(".9", ref); + assertEquals("1970-01-01 00:00:00.900000000", tsf.format(time)); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimestampTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimestampTest.java new file mode 100644 index 0000000000..78cf284deb --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfTimestampTest.java @@ -0,0 +1,670 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Adjusted for new Event Model + * Alexandre Montplaisir - Port to JUnit4 + * Patrick Tasse - Updated for negative value formatting + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.event; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; +import org.junit.Test; + +/** + * Test suite for the TmfTimestamp class. + */ +@SuppressWarnings("javadoc") +public class TmfTimestampTest { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + private final ITmfTimestamp ts0 = new TmfTimestamp(); + private final ITmfTimestamp ts1 = new TmfTimestamp(12345, 0); + private final ITmfTimestamp ts2 = new TmfTimestamp(12345, -1); + private final ITmfTimestamp ts3 = new TmfTimestamp(12345, 2, 5); + private final ITmfTimestamp ts4 = new TmfTimestamp(12345, -3, 0); + private final ITmfTimestamp ts5 = new TmfTimestamp(12345, -6, 0); + private final ITmfTimestamp ts6 = new TmfTimestamp(12345, -9, 0); + private final ITmfTimestamp ts7 = new TmfTimestamp(-12345, -3, 0); + private final ITmfTimestamp ts8 = new TmfTimestamp(-12345, -6, 0); + private final ITmfTimestamp ts9 = new TmfTimestamp(-12345, -9, 0); + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + @Test + public void testDefaultConstructor() { + assertEquals("getValue", 0, ts0.getValue()); + assertEquals("getscale", 0, ts0.getScale()); + assertEquals("getPrecision", 0, ts0.getPrecision()); + } + + @Test + public void testValueConstructor() { + assertEquals("getValue", 12345, ts1.getValue()); + assertEquals("getscale", 0, ts1.getScale()); + assertEquals("getPrecision", 0, ts1.getPrecision()); + } + + @Test + public void testValueScaleConstructor() { + assertEquals("getValue", 12345, ts2.getValue()); + assertEquals("getscale", -1, ts2.getScale()); + assertEquals("getPrecision", 0, ts2.getPrecision()); + } + + @Test + public void testFullConstructor() { + assertEquals("getValue", 12345, ts3.getValue()); + assertEquals("getscale", 2, ts3.getScale()); + assertEquals("getPrecision", 5, ts3.getPrecision()); + } + + @Test + public void testCopyConstructor() { + final ITmfTimestamp ts = new TmfTimestamp(12345, 2, 5); + final ITmfTimestamp copy = new TmfTimestamp(ts); + + assertEquals("getValue", ts.getValue(), copy.getValue()); + assertEquals("getscale", ts.getScale(), copy.getScale()); + assertEquals("getPrecision", ts.getPrecision(), copy.getPrecision()); + + assertEquals("getValue", 12345, copy.getValue()); + assertEquals("getscale", 2, copy.getScale()); + assertEquals("getPrecision", 5, copy.getPrecision()); + } + + @Test(expected=IllegalArgumentException.class) + public void testCopyNullConstructor() { + new TmfTimestamp((TmfTimestamp) null); + } + + @Test + public void testCopyConstructorBigBang() { + final ITmfTimestamp ts = new TmfTimestamp(TmfTimestamp.BIG_BANG); + assertEquals("getValue", TmfTimestamp.BIG_BANG.getValue(), ts.getValue()); + assertEquals("getscale", TmfTimestamp.BIG_BANG.getScale(), ts.getScale()); + assertEquals("getPrecision", TmfTimestamp.BIG_BANG.getPrecision(), ts.getPrecision()); + } + + @Test + public void testCopyConstructorBigCrunch() { + final ITmfTimestamp ts = new TmfTimestamp(TmfTimestamp.BIG_CRUNCH); + assertEquals("getValue", TmfTimestamp.BIG_CRUNCH.getValue(), ts.getValue()); + assertEquals("getscale", TmfTimestamp.BIG_CRUNCH.getScale(), ts.getScale()); + assertEquals("getPrecision", TmfTimestamp.BIG_CRUNCH.getPrecision(), ts.getPrecision()); + } + + @Test + public void testCopyConstructorZero() { + final ITmfTimestamp ts = new TmfTimestamp(TmfTimestamp.ZERO); + assertEquals("getValue", TmfTimestamp.ZERO.getValue(), ts.getValue()); + assertEquals("getscale", TmfTimestamp.ZERO.getScale(), ts.getScale()); + assertEquals("getPrecision", TmfTimestamp.ZERO.getPrecision(), ts.getPrecision()); + } + + // ------------------------------------------------------------------------ + // hashCode + // ------------------------------------------------------------------------ + + @Test + public void testHashCode() { + final ITmfTimestamp ts0copy = new TmfTimestamp(ts0); + final ITmfTimestamp ts1copy = new TmfTimestamp(ts1); + final ITmfTimestamp ts2copy = new TmfTimestamp(ts2); + + assertTrue("hashCode", ts0.hashCode() == ts0copy.hashCode()); + assertTrue("hashCode", ts1.hashCode() == ts1copy.hashCode()); + assertTrue("hashCode", ts2.hashCode() == ts2copy.hashCode()); + + assertTrue("hashCode", ts0.hashCode() != ts1.hashCode()); + } + + // ------------------------------------------------------------------------ + // equals + // ------------------------------------------------------------------------ + + @Test + public void testEqualsReflexivity() { + assertTrue("equals", ts0.equals(ts0)); + assertTrue("equals", ts1.equals(ts1)); + + assertTrue("equals", !ts0.equals(ts1)); + assertTrue("equals", !ts1.equals(ts0)); + } + + @Test + public void testEqualsSymmetry() { + final ITmfTimestamp ts0copy = new TmfTimestamp(ts0); + assertTrue("equals", ts0.equals(ts0copy)); + assertTrue("equals", ts0copy.equals(ts0)); + + final ITmfTimestamp ts1copy = new TmfTimestamp(ts1); + assertTrue("equals", ts1.equals(ts1copy)); + assertTrue("equals", ts1copy.equals(ts1)); + + final ITmfTimestamp ts2copy = new TmfTimestamp(ts2); + assertTrue("equals", ts2.equals(ts2copy)); + assertTrue("equals", ts2copy.equals(ts2)); + } + + @Test + public void testEqualsTransivity() { + final ITmfTimestamp ts0copy1 = new TmfTimestamp(ts0); + final ITmfTimestamp ts0copy2 = new TmfTimestamp(ts0copy1); + assertTrue("equals", ts0.equals(ts0copy1)); + assertTrue("equals", ts0copy1.equals(ts0copy2)); + assertTrue("equals", ts0.equals(ts0copy2)); + + final ITmfTimestamp ts1copy1 = new TmfTimestamp(ts1); + final ITmfTimestamp ts1copy2 = new TmfTimestamp(ts1copy1); + assertTrue("equals", ts1.equals(ts1copy1)); + assertTrue("equals", ts1copy1.equals(ts1copy2)); + assertTrue("equals", ts1.equals(ts1copy2)); + + final ITmfTimestamp ts2copy1 = new TmfTimestamp(ts2); + final ITmfTimestamp ts2copy2 = new TmfTimestamp(ts2copy1); + assertTrue("equals", ts2.equals(ts2copy1)); + assertTrue("equals", ts2copy1.equals(ts2copy2)); + assertTrue("equals", ts2.equals(ts2copy2)); + } + + @Test + public void testEqualsNull() { + assertTrue("equals", !ts0.equals(null)); + assertTrue("equals", !ts1.equals(null)); + } + + @Test + public void testEqualsNonTimestamp() { + assertFalse("equals", ts0.equals(ts0.toString())); + } + + // ------------------------------------------------------------------------ + // toString + // ------------------------------------------------------------------------ + + @Test + public void testToStringDefault() { + DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS"); + Date d0 = new Date((long) (ts0.getValue() * Math.pow(10, ts0.getScale() + 3))); + Date d1 = new Date((long) (ts1.getValue() * Math.pow(10, ts1.getScale() + 3))); + Date d2 = new Date((long) (ts2.getValue() * Math.pow(10, ts2.getScale() + 3))); + Date d3 = new Date((long) (ts3.getValue() * Math.pow(10, ts3.getScale() + 3))); + Date d4 = new Date((long) (ts4.getValue() * Math.pow(10, ts4.getScale() + 3))); + Date d5 = new Date((long) (ts5.getValue() * Math.pow(10, ts5.getScale() + 3))); + Date d6 = new Date((long) (ts6.getValue() * Math.pow(10, ts6.getScale() + 3))); + Date d7 = new Date((long) (ts7.getValue() * Math.pow(10, ts7.getScale() + 3))); + Date d8 = new Date((long) (ts8.getValue() * Math.pow(10, ts8.getScale() + 3)) - 1); + Date d9 = new Date((long) (ts9.getValue() * Math.pow(10, ts9.getScale() + 3)) - 1); + assertEquals("toString", df.format(d0) + " 000 000", ts0.toString()); + assertEquals("toString", df.format(d1) + " 000 000", ts1.toString()); + assertEquals("toString", df.format(d2) + " 000 000", ts2.toString()); + assertEquals("toString", df.format(d3) + " 000 000", ts3.toString()); + assertEquals("toString", df.format(d4) + " 000 000", ts4.toString()); + assertEquals("toString", df.format(d5) + " 345 000", ts5.toString()); + assertEquals("toString", df.format(d6) + " 012 345", ts6.toString()); + assertEquals("toString", df.format(d7) + " 000 000", ts7.toString()); + assertEquals("toString", df.format(d8) + " 655 000", ts8.toString()); + assertEquals("toString", df.format(d9) + " 987 655", ts9.toString()); + } + + @Test + public void testToStringInterval() { + assertEquals("toString", "000.000 000 000", ts0.toString(TmfTimestampFormat.getDefaulIntervalFormat())); + assertEquals("toString", "12345.000 000 000", ts1.toString(TmfTimestampFormat.getDefaulIntervalFormat())); + assertEquals("toString", "1234.500 000 000", ts2.toString(TmfTimestampFormat.getDefaulIntervalFormat())); + assertEquals("toString", "1234500.000 000 000", ts3.toString(TmfTimestampFormat.getDefaulIntervalFormat())); + assertEquals("toString", "012.345 000 000", ts4.toString(TmfTimestampFormat.getDefaulIntervalFormat())); + assertEquals("toString", "000.012 345 000", ts5.toString(TmfTimestampFormat.getDefaulIntervalFormat())); + assertEquals("toString", "000.000 012 345", ts6.toString(TmfTimestampFormat.getDefaulIntervalFormat())); + assertEquals("toString", "-012.345 000 000", ts7.toString(TmfTimestampFormat.getDefaulIntervalFormat())); + assertEquals("toString", "-000.012 345 000", ts8.toString(TmfTimestampFormat.getDefaulIntervalFormat())); + assertEquals("toString", "-000.000 012 345", ts9.toString(TmfTimestampFormat.getDefaulIntervalFormat())); + } + + // ------------------------------------------------------------------------ + // normalize + // ------------------------------------------------------------------------ + + @Test + public void testNormalizeOffset() { + ITmfTimestamp ts = ts0.normalize(0, 0); + assertEquals("getValue", 0, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(12345, 0); + assertEquals("getValue", 12345, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(10, 0); + assertEquals("getValue", 10, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(-10, 0); + assertEquals("getValue", -10, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + } + + @Test + public void testNormalizeOffsetLowerLimits() { + final ITmfTimestamp ref = new TmfTimestamp(Long.MIN_VALUE + 5, 0); + + ITmfTimestamp ts = ref.normalize(-4, 0); + assertEquals("getValue", Long.MIN_VALUE + 1, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ref.normalize(-5, 0); + assertEquals("getValue", Long.MIN_VALUE, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ref.normalize(-6, 0); + assertEquals("getValue", Long.MIN_VALUE, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + } + + @Test + public void testNormalizeOffsetUpperLimits() { + final ITmfTimestamp ref = new TmfTimestamp(Long.MAX_VALUE - 5, 0); + + ITmfTimestamp ts = ref.normalize(4, 0); + assertEquals("getValue", Long.MAX_VALUE - 1, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ref.normalize(5, 0); + assertEquals("getValue", Long.MAX_VALUE, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ref.normalize(6, 0); + assertEquals("getValue", Long.MAX_VALUE, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + } + + @Test + public void testNormalizeScale() { + ITmfTimestamp ts = ts0.normalize(0, 10); + assertEquals("getValue", 0, ts.getValue()); + assertEquals("getscale", 10, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(0, -10); + assertEquals("getValue", 0, ts.getValue()); + assertEquals("getscale", -10, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + } + + @Test + public void testNormalizedScaleLimits() { + final int MAX_SCALE_DIFF = 19; + + // Test below limit + try { + ts1.normalize(0, +MAX_SCALE_DIFF - 1); + ts1.normalize(0, -MAX_SCALE_DIFF + 1); + } catch (final ArithmeticException e) { + fail("normalize: scale error"); + } + + // Test at limit + try { + ts1.normalize(0, +MAX_SCALE_DIFF); + fail("normalize: scale error"); + ts1.normalize(0, -MAX_SCALE_DIFF); + fail("normalize: scale error"); + } catch (final ArithmeticException e) { + } + + // Test over limit + try { + ts1.normalize(0, +MAX_SCALE_DIFF + 1); + fail("normalize: scale error"); + ts1.normalize(0, -MAX_SCALE_DIFF - 1); + fail("normalize: scale error"); + } catch (final ArithmeticException e) { + } + } + + @Test + public void testNormalizeOffsetAndScaleTrivial() { + final ITmfTimestamp ts = ts0.normalize(0, 0); + assertEquals("getValue", 0, ts.getValue()); + assertEquals("getscale", 0, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + } + + @Test + public void testNormalizeOffsetAndScale() { + final int SCALE = 12; + + ITmfTimestamp ts = ts0.normalize(0, SCALE); + assertEquals("getValue", 0, ts.getValue()); + assertEquals("getscale", SCALE, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(12345, SCALE); + assertEquals("getValue", 12345, ts.getValue()); + assertEquals("getscale", SCALE, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(10, SCALE); + assertEquals("getValue", 10, ts.getValue()); + assertEquals("getscale", SCALE, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts0.normalize(-10, SCALE); + assertEquals("getValue", -10, ts.getValue()); + assertEquals("getscale", SCALE, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + } + + @Test + public void testNormalizeOffsetAndScale2() { + int SCALE = 2; + ITmfTimestamp ts = ts1.normalize(0, SCALE); + assertEquals("getValue", 123, ts.getValue()); + assertEquals("getscale", SCALE, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts1.normalize(12345, SCALE); + assertEquals("getValue", 12468, ts.getValue()); + assertEquals("getscale", SCALE, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + SCALE = -2; + ts = ts1.normalize(0, SCALE); + assertEquals("getValue", 1234500, ts.getValue()); + assertEquals("getscale", SCALE, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + + ts = ts1.normalize(67, SCALE); + assertEquals("getValue", 1234567, ts.getValue()); + assertEquals("getscale", SCALE, ts.getScale()); + assertEquals("getPrecision", 0, ts.getPrecision()); + } + + // ------------------------------------------------------------------------ + // compareTo + // ------------------------------------------------------------------------ + + @Test + public void testBasicCompareTo() { + final ITmfTimestamp t1 = new TmfTimestamp(900, 0, 50); + final ITmfTimestamp t2 = new TmfTimestamp(1000, 0, 50); + final ITmfTimestamp t3 = new TmfTimestamp(1100, 0, 50); + final ITmfTimestamp t4 = new TmfTimestamp(1000, 0, 75); + + assertTrue(t1.compareTo(t1) == 0); + + assertTrue("CompareTo", t1.compareTo(t2) < 0); + assertTrue("CompareTo", t1.compareTo(t3) < 0); + assertTrue("CompareTo", t1.compareTo(t4) < 0); + + assertTrue("CompareTo", t2.compareTo(t1) > 0); + assertTrue("CompareTo", t2.compareTo(t3) < 0); + assertTrue("CompareTo", t2.compareTo(t4) == 0); + + assertTrue("CompareTo", t3.compareTo(t1) > 0); + assertTrue("CompareTo", t3.compareTo(t2) > 0); + assertTrue("CompareTo", t3.compareTo(t4) > 0); + } + + @Test + public void testCompareToCornerCases1() { + final ITmfTimestamp ts0a = new TmfTimestamp(ts0); + final ITmfTimestamp ts0b = new TmfTimestamp(ts0.getValue(), ts0.getScale() + 1); + final ITmfTimestamp ts0c = new TmfTimestamp(ts0.getValue() + 1, ts0.getScale()); + final ITmfTimestamp ts0d = new TmfTimestamp(ts0.getValue() + 1, ts0.getScale() + 1); + + assertTrue("compareTo", ts0.compareTo(ts0, false) == 0); + assertTrue("compareTo", ts0.compareTo(ts0a, false) == 0); + assertTrue("compareTo", ts0.compareTo(ts0b, false) == 0); + assertTrue("compareTo", ts0.compareTo(ts0c, false) == -1); + assertTrue("compareTo", ts0.compareTo(ts0d, false) == -1); + } + + @Test + public void testCompareToCornerCases2() { + final ITmfTimestamp ts0a = new TmfTimestamp(Long.MAX_VALUE, Integer.MAX_VALUE - 1); + final ITmfTimestamp ts0b = new TmfTimestamp(0, Integer.MAX_VALUE); + final ITmfTimestamp ts0c = new TmfTimestamp(Long.MAX_VALUE, Integer.MAX_VALUE); + + assertTrue("compareTo", ts0a.compareTo(ts0b, false) == 1); + assertTrue("compareTo", ts0a.compareTo(ts0c, false) == -1); + + assertTrue("compareTo", ts0b.compareTo(ts0a, false) == -1); + assertTrue("compareTo", ts0b.compareTo(ts0c, false) == -1); + + assertTrue("compareTo", ts0c.compareTo(ts0a, false) == 1); + assertTrue("compareTo", ts0c.compareTo(ts0b, false) == 1); + } + + @Test + public void testCompareToCornerCases3() { + final ITmfTimestamp ts0a = new TmfTimestamp(Long.MIN_VALUE, Integer.MAX_VALUE - 1); + final ITmfTimestamp ts0b = new TmfTimestamp(0, Integer.MAX_VALUE); + final ITmfTimestamp ts0c = new TmfTimestamp(Long.MIN_VALUE, Integer.MAX_VALUE); + + assertTrue("compareTo", ts0a.compareTo(ts0b, false) == -1); + assertTrue("compareTo", ts0a.compareTo(ts0c, false) == 1); + + assertTrue("compareTo", ts0b.compareTo(ts0a, false) == 1); + assertTrue("compareTo", ts0b.compareTo(ts0c, false) == 1); + + assertTrue("compareTo", ts0c.compareTo(ts0a, false) == -1); + assertTrue("compareTo", ts0c.compareTo(ts0b, false) == -1); + } + + @Test + public void testCompareToCornerCases4() { + assertTrue("compareTo", ts0.compareTo(null, false) == 1); + assertTrue("compareTo", ts0.compareTo(null, true) == 1); + } + + @Test + public void testCompareToSameScale() { + final ITmfTimestamp t1 = new TmfTimestamp(900, 0, 50); + final ITmfTimestamp t2 = new TmfTimestamp(1000, 0, 50); + final ITmfTimestamp t3 = new TmfTimestamp(1100, 0, 50); + final ITmfTimestamp t4 = new TmfTimestamp(1000, 0, 75); + + assertTrue(t1.compareTo(t1, false) == 0); + + assertTrue("CompareTo", t1.compareTo(t2, false) < 0); + assertTrue("CompareTo", t1.compareTo(t3, false) < 0); + assertTrue("CompareTo", t1.compareTo(t4, false) < 0); + + assertTrue("CompareTo", t2.compareTo(t1, false) > 0); + assertTrue("CompareTo", t2.compareTo(t3, false) < 0); + assertTrue("CompareTo", t2.compareTo(t4, false) == 0); + + assertTrue("CompareTo", t3.compareTo(t1, false) > 0); + assertTrue("CompareTo", t3.compareTo(t2, false) > 0); + assertTrue("CompareTo", t3.compareTo(t4, false) > 0); + } + + @Test + public void testCompareToDifferentScale() { + final ITmfTimestamp t1 = new TmfTimestamp(9000, -1, 50); + final ITmfTimestamp t2 = new TmfTimestamp(1000, 0, 50); + final ITmfTimestamp t3 = new TmfTimestamp(110, 1, 50); + final ITmfTimestamp t4 = new TmfTimestamp(1, 3, 75); + + assertTrue("CompareTo", t1.compareTo(t1, false) == 0); + + assertTrue("CompareTo", t1.compareTo(t2, false) < 0); + assertTrue("CompareTo", t1.compareTo(t3, false) < 0); + assertTrue("CompareTo", t1.compareTo(t4, false) < 0); + + assertTrue("CompareTo", t2.compareTo(t1, false) > 0); + assertTrue("CompareTo", t2.compareTo(t3, false) < 0); + assertTrue("CompareTo", t2.compareTo(t4, false) == 0); + + assertTrue("CompareTo", t3.compareTo(t1, false) > 0); + assertTrue("CompareTo", t3.compareTo(t2, false) > 0); + assertTrue("CompareTo", t3.compareTo(t4, false) > 0); + } + + @Test + public void testCompareToWithinPrecision() { + final ITmfTimestamp t1 = new TmfTimestamp(900, 0, 50); + final ITmfTimestamp t2 = new TmfTimestamp(1000, 0, 50); + final ITmfTimestamp t3 = new TmfTimestamp(1100, 0, 50); + final ITmfTimestamp t4 = new TmfTimestamp(1000, 0, 75); + + assertTrue("CompareTo", t1.compareTo(t1, true) == 0); + + assertTrue("CompareTo", t1.compareTo(t2, true) == 0); + assertTrue("CompareTo", t1.compareTo(t3, true) < 0); + assertTrue("CompareTo", t1.compareTo(t4, true) == 0); + + assertTrue("CompareTo", t2.compareTo(t1, true) == 0); + assertTrue("CompareTo", t2.compareTo(t3, true) == 0); + assertTrue("CompareTo", t2.compareTo(t4, true) == 0); + + assertTrue("CompareTo", t3.compareTo(t1, true) > 0); + assertTrue("CompareTo", t3.compareTo(t2, true) == 0); + assertTrue("CompareTo", t3.compareTo(t4, true) == 0); + } + + @Test + public void testCompareToLargeScale1() { + final ITmfTimestamp t1 = new TmfTimestamp(-1, 100); + final ITmfTimestamp t2 = new TmfTimestamp(-1000, -100); + final ITmfTimestamp t3 = new TmfTimestamp(1, 100); + final ITmfTimestamp t4 = new TmfTimestamp(1000, -100); + + assertTrue("CompareTo", t1.compareTo(t2, false) < 0); + assertTrue("CompareTo", t1.compareTo(t3, false) < 0); + assertTrue("CompareTo", t1.compareTo(t4, false) < 0); + + assertTrue("CompareTo", t2.compareTo(t1, false) > 0); + assertTrue("CompareTo", t2.compareTo(t3, false) < 0); + assertTrue("CompareTo", t2.compareTo(t4, false) < 0); + + assertTrue("CompareTo", t3.compareTo(t1, false) > 0); + assertTrue("CompareTo", t3.compareTo(t2, false) > 0); + assertTrue("CompareTo", t3.compareTo(t4, false) > 0); + + assertTrue("CompareTo", t4.compareTo(t1, false) > 0); + assertTrue("CompareTo", t4.compareTo(t2, false) > 0); + assertTrue("CompareTo", t4.compareTo(t3, false) < 0); + } + + @Test + public void testCompareToLargeScale2() { + final ITmfTimestamp ts0a = new TmfTimestamp(0, Integer.MAX_VALUE); + final ITmfTimestamp ts0b = new TmfTimestamp(1, Integer.MAX_VALUE); + + assertTrue("CompareTo", ts0a.compareTo(ts0, false) == 0); + assertTrue("CompareTo", ts0.compareTo(ts0a, false) == 0); + + assertTrue("CompareTo", ts0b.compareTo(ts0, false) == 1); + assertTrue("CompareTo", ts0.compareTo(ts0b, false) == -1); + } + + // ------------------------------------------------------------------------ + // getDelta + // ------------------------------------------------------------------------ + + @Test + public void testDelta() { + // Delta for same scale and precision (delta > 0) + ITmfTimestamp t0 = new TmfTimestamp(10, 9); + ITmfTimestamp t1 = new TmfTimestamp(5, 9); + ITmfTimestamp exp = new TmfTimestamp(5, 9); + + ITmfTimestamp delta = t0.getDelta(t1); + assertEquals("getDelta", 0, delta.compareTo(exp, false)); + + // Delta for same scale and precision (delta < 0) + t0 = new TmfTimestamp(5, 9); + t1 = new TmfTimestamp(10, 9); + exp = new TmfTimestamp(-5, 9); + + delta = t0.getDelta(t1); + assertEquals("getDelta", 0, delta.compareTo(exp, false)); + + // Delta for different scale and same precision (delta > 0) + t0 = new TmfTimestamp(5, 9); + t1 = new TmfTimestamp(10, 8); + exp = new TmfTimestamp(4, 9); + + delta = t0.getDelta(t1); + assertEquals("getDelta", 0, delta.compareTo(exp, false)); + + // Delta for different scale and same precision (delta > 0) + t0 = new TmfTimestamp(5, 9); + t1 = new TmfTimestamp(10, 7); + exp = new TmfTimestamp(5, 9); + + delta = t0.getDelta(t1); + assertEquals("getDelta", 0, delta.compareTo(exp, false)); + + // Delta for different scale and same precision + t0 = new TmfTimestamp(10, 9); + t1 = new TmfTimestamp(5, 8); + exp = new TmfTimestamp(10, 9); + + delta = t0.getDelta(t1); + assertEquals("getDelta", 0, delta.compareTo(exp, false)); + + // Delta for same scale and different precision + t0 = new TmfTimestamp(10, 9, 1); + t1 = new TmfTimestamp(5, 9, 2); + exp = new TmfTimestamp(5, 9, 3); + + delta = t0.getDelta(t1); + assertEquals("getDelta", 0, delta.compareTo(exp, true)); + assertEquals("precision", 3, delta.getPrecision()); + + // Delta for same scale and different precision + t0 = new TmfTimestamp(5, 9, 2); + t1 = new TmfTimestamp(10, 9, 1); + exp = new TmfTimestamp(-5, 9, 3); + + delta = t0.getDelta(t1); + assertEquals("getDelta", 0, delta.compareTo(exp, true)); + assertEquals("precision", 3, delta.getPrecision()); + + // Delta for different scale and different precision + t0 = new TmfTimestamp(5, 9, 2); + t1 = new TmfTimestamp(10, 8, 1); + exp = new TmfTimestamp(4, 9, 3); + delta = t0.getDelta(t1); + assertEquals("getDelta", 0, delta.compareTo(exp, true)); + assertEquals("precision", 2, delta.getPrecision()); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/lookup/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/lookup/AllTests.java new file mode 100644 index 0000000000..e08ce79e59 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/lookup/AllTests.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.event.lookup; + +import org.eclipse.tracecompass.tmf.core.tests.event.lookup.TmfCallsiteTest; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for org.eclipse.linuxtools.tmf.core.event.lookup + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TmfCallsiteTest.class +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/lookup/TmfCallsiteTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/lookup/TmfCallsiteTest.java new file mode 100644 index 0000000000..ef00099db6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/lookup/TmfCallsiteTest.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.event.lookup; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfCallsite; +import org.eclipse.tracecompass.tmf.core.event.lookup.TmfCallsite; +import org.junit.Test; + +/** + * Test suite for the TmfCallsite class. + */ +@SuppressWarnings("javadoc") +public class TmfCallsiteTest { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + private final static String fFileName1 = "filename1"; + private final static String fFunctionName1 = "func1"; + private final static long fLine1 = 10; + + private final static String fFileName2 = "filename2"; + private final static String fFunctionName2 = "func2"; + private final static long fLine2 = 25; + + private final static String fFileName3 = "filename3"; + private final static String fFunctionName3 = null; + private final static long fLine3 = 123; + + private final static ITmfCallsite fCallsite1 = new TmfCallsite(fFileName1, fFunctionName1, fLine1); + private final static ITmfCallsite fCallsite2 = new TmfCallsite(fFileName2, fFunctionName2, fLine2); + private final static ITmfCallsite fCallsite3 = new TmfCallsite(fFileName3, fFunctionName3, fLine3); + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + @Test + public void testDefaultConstructor() { + assertEquals(fFileName1, fCallsite1.getFileName()); + assertEquals(fFunctionName1, fCallsite1.getFunctionName()); + assertEquals(fLine1, fCallsite1.getLineNumber()); + } + + @Test + public void testCallsiteCopy() { + TmfCallsite copy = new TmfCallsite(fCallsite1); + + assertEquals(fFileName1, copy.getFileName()); + assertEquals(fFunctionName1, copy.getFunctionName()); + assertEquals(fLine1, copy.getLineNumber()); + } + + @Test(expected=IllegalArgumentException.class) + public void testCallsiteCopy2() { + new TmfCallsite(null); + } + + @Test(expected=IllegalArgumentException.class) + public void testCallsiteCopy3() { + new TmfCallsite(new ITmfCallsite() { + @Override + public long getLineNumber() { + return 0; + } + + @Override + public String getFunctionName() { + return null; + } + + @Override + public String getFileName() { + return null; + } + }); + } + + @Test(expected=IllegalArgumentException.class) + public void testCallsiteFileNull() { + new TmfCallsite(null, fFunctionName1, fLine1); + } + + // ------------------------------------------------------------------------ + // hashCode + // ------------------------------------------------------------------------ + + @Test + public void testHashCode() { + final ITmfCallsite callsite1b = new TmfCallsite(fCallsite1); + final ITmfCallsite callsite2b = new TmfCallsite(fCallsite2); + + assertTrue("hashCode", fCallsite1.hashCode() == callsite1b.hashCode()); + assertTrue("hashCode", fCallsite2.hashCode() == callsite2b.hashCode()); + + assertTrue("hashCode", fCallsite1.hashCode() != fCallsite2.hashCode()); + assertTrue("hashCode", fCallsite2.hashCode() != fCallsite1.hashCode()); + } + + // ------------------------------------------------------------------------ + // equals + // ------------------------------------------------------------------------ + + @Test + public void testEqualsReflexivity() { + assertTrue("equals", fCallsite1.equals(fCallsite1)); + assertTrue("equals", fCallsite2.equals(fCallsite2)); + + assertFalse("equals", fCallsite1.equals(fCallsite2)); + assertFalse("equals", fCallsite2.equals(fCallsite1)); + } + + @Test + public void testEqualsSymmetry() { + final ITmfCallsite callsite1 = new TmfCallsite(fCallsite1); + final ITmfCallsite callsite2 = new TmfCallsite(fCallsite2); + + assertTrue("equals", callsite1.equals(fCallsite1)); + assertTrue("equals", fCallsite1.equals(callsite1)); + + assertTrue("equals", callsite2.equals(fCallsite2)); + assertTrue("equals", fCallsite2.equals(callsite2)); + } + + @Test + public void testEqualsTransivity() { + final ITmfCallsite callsite1 = new TmfCallsite(fCallsite1); + final ITmfCallsite callsite2 = new TmfCallsite(fCallsite1); + final ITmfCallsite callsite3 = new TmfCallsite(fCallsite1); + + assertTrue("equals", callsite1.equals(callsite2)); + assertTrue("equals", callsite2.equals(callsite3)); + assertTrue("equals", callsite1.equals(callsite3)); + } + + @Test + public void testEqualsNull() { + assertFalse("equals", fCallsite1.equals(null)); + assertFalse("equals", fCallsite2.equals(null)); + assertFalse("equals", fCallsite3.equals(null)); + } + + @Test + public void testNonEqualClasses() { + assertFalse("equals", fCallsite1.equals(fCallsite1.getFileName())); + } + + @Test + public void testNullElements() { + ITmfCallsite callsite = new TmfCallsite(fFileName1, null, fLine1); + assertFalse("equals", fCallsite1.equals(callsite)); + assertFalse("equals", callsite.equals(fCallsite1)); + } + + // ------------------------------------------------------------------------ + // toString + // ------------------------------------------------------------------------ + + @Test + public void testToString() { + assertEquals("toString", "filename1:10 func1()", fCallsite1.toString()); + assertEquals("toString", "filename2:25 func2()", fCallsite2.toString()); + assertEquals("toString", "filename3:123", fCallsite3.toString()); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/filter/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/filter/AllTests.java new file mode 100644 index 0000000000..d63bb2d71e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/filter/AllTests.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.filter; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Filter tests. + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TmfCollapseFilterTest.class, +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/filter/TmfCollapseFilterTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/filter/TmfCollapseFilterTest.java new file mode 100644 index 0000000000..2e66c525f9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/filter/TmfCollapseFilterTest.java @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.filter; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.eclipse.tracecompass.internal.tmf.core.filter.TmfCollapseFilter; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.eclipse.tracecompass.tmf.core.event.collapse.ITmfCollapsibleEvent; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.junit.Test; + +/** + * Test suite for the {@link TmfCollpaseFilter} class. + * + * @author Bernd Hufmann + */ +@SuppressWarnings("javadoc") +public class TmfCollapseFilterTest { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + private CollapsibleEvent fCollapsibleEvent1 = new CollapsibleEvent(true); + private CollapsibleEvent fCollapsibleEvent2 = new CollapsibleEvent(true); + private CollapsibleEvent fCollapsibleEvent3 = new CollapsibleEvent(false); + private NonCollapsibleEvent fNonCollapsibleEvent1 = new NonCollapsibleEvent(); + private TmfCollapseFilter fFilter = new TmfCollapseFilter(); + + // ------------------------------------------------------------------------ + // matches + // ------------------------------------------------------------------------ + + @Test + public void testMatches() { + + TmfCollapseFilter filter = new TmfCollapseFilter(); + + assertTrue(filter.matches(fCollapsibleEvent1)); + assertFalse(filter.matches(fCollapsibleEvent2)); + assertFalse(filter.matches(fCollapsibleEvent1)); + assertFalse(filter.matches(fCollapsibleEvent2)); + assertTrue(filter.matches(fNonCollapsibleEvent1)); + assertTrue(filter.matches(fNonCollapsibleEvent1)); + assertTrue(filter.matches(fCollapsibleEvent1)); + assertFalse(filter.matches(fCollapsibleEvent2)); + assertTrue(filter.matches(fCollapsibleEvent3)); + } + + @Test + public void testInterfaces() { + assertNull("getParent()", fFilter.getParent()); + assertEquals("getName()", "Collapse", fFilter.getNodeName()); + assertEquals("hasChildren()", false, fFilter.hasChildren()); + assertEquals("getChildrenCount()", 0, fFilter.getChildrenCount()); + assertEquals("getChildren()", 0, fFilter.getChildren().length); + } + + @Test + public void testClone() { + assertNotEquals("clone()", fFilter, fFilter.clone()); + } + + @Test(expected=UnsupportedOperationException.class) + public void testGetChild() { + fFilter.getChild(0); + } + + @Test(expected=UnsupportedOperationException.class) + public void testRemove() { + fFilter.remove(); + } + + @Test(expected=UnsupportedOperationException.class) + public void testRemoveChild() { + fFilter.removeChild(null); + } + + @Test(expected=UnsupportedOperationException.class) + public void testAddChild() { + fFilter.addChild(null); + } + + @Test(expected=UnsupportedOperationException.class) + public void testReplaceChild() { + fFilter.replaceChild(0, null); + } + + @Test(expected=UnsupportedOperationException.class) + public void testGetValidChildren() { + fFilter.getValidChildren(); + } + + // ------------------------------------------------------------------------ + // Helper Classes + // ------------------------------------------------------------------------ + + private class CollapsibleEvent extends TmfEvent implements ITmfCollapsibleEvent { + + private final boolean fIsCollapsible; + CollapsibleEvent(boolean isCollapsible) { + super(); + fIsCollapsible = isCollapsible; + } + @Override + public boolean isCollapsibleWith(ITmfEvent otherEvent) { + return ((CollapsibleEvent)otherEvent).fIsCollapsible; + } + } + + private class NonCollapsibleEvent implements ITmfEvent { + + @Override + public Object getAdapter(Class adapter) { + return null; + } + @Override + public ITmfTrace getTrace() { + return null; + } + @Override + public long getRank() { + return 0; + } + @Override + public ITmfTimestamp getTimestamp() { + return new TmfNanoTimestamp(100); + } + @Override + public String getSource() { + return ""; + } + @Override + public ITmfEventType getType() { + return new TmfEventType(); + } + @Override + public ITmfEventField getContent() { + return new TmfEventField("testField", "test", null); + } + @Override + public String getReference() { + return "remote"; + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/request/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/request/AllTests.java new file mode 100644 index 0000000000..8ca764e356 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/request/AllTests.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.request; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Requests tests + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TmfCoalescedEventRequestTest.class, + TmfEventRequestTest.class, +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/request/TmfCoalescedEventRequestTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/request/TmfCoalescedEventRequestTest.java new file mode 100644 index 0000000000..e7411d3472 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/request/TmfCoalescedEventRequestTest.java @@ -0,0 +1,594 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.request; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Vector; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.tracecompass.internal.tmf.core.component.TmfProviderManager; +import org.eclipse.tracecompass.internal.tmf.core.request.TmfCoalescedEventRequest; +import org.eclipse.tracecompass.tmf.core.component.ITmfEventProvider; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.tests.TmfCoreTestPlugin; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.tests.stubs.request.TmfEventRequestStub; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; +import org.junit.Before; +import org.junit.Test; + +/** + * Test suite for the TmfCoalescedEventRequest class. + */ +@SuppressWarnings("javadoc") +public class TmfCoalescedEventRequestTest { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + private final TmfTimeRange range1 = new TmfTimeRange(TmfTimeRange.ETERNITY); + private final TmfTimeRange range2 = new TmfTimeRange(new TmfTimestamp(), TmfTimestamp.BIG_CRUNCH); + + private TmfCoalescedEventRequest fRequest1; + private TmfCoalescedEventRequest fRequest2; + private TmfCoalescedEventRequest fRequest3; + private TmfCoalescedEventRequest fRequest4; + + private TmfCoalescedEventRequest fRequest1b; + private TmfCoalescedEventRequest fRequest1c; + + private int fRequestCount; + + // ------------------------------------------------------------------------ + // Housekeeping + // ------------------------------------------------------------------------ + + @Before + public void setUp() { + TmfEventRequest.reset(); + fRequest1 = new TmfCoalescedEventRequest(ITmfEvent.class, range1, 0, 100, ExecutionType.FOREGROUND); + fRequest2 = new TmfCoalescedEventRequest(ITmfEvent.class, range2, 0, 100, ExecutionType.FOREGROUND); + fRequest3 = new TmfCoalescedEventRequest(ITmfEvent.class, range2, 0, 200, ExecutionType.FOREGROUND); + fRequest4 = new TmfCoalescedEventRequest(ITmfEvent.class, range2, 0, 200, ExecutionType.FOREGROUND); + + fRequest1b = new TmfCoalescedEventRequest(ITmfEvent.class, range1, 0, 100, ExecutionType.FOREGROUND); + fRequest1c = new TmfCoalescedEventRequest(ITmfEvent.class, range1, 0, 100, ExecutionType.FOREGROUND); + + fRequestCount = fRequest1c.getRequestId() + 1; + } + + private TmfCoalescedEventRequest setupTestRequest(final boolean[] flags) { + + TmfCoalescedEventRequest request = new TmfCoalescedEventRequest(ITmfEvent.class, range1, 0, 100, ExecutionType.FOREGROUND) { + @Override + public void handleCompleted() { + super.handleCompleted(); + flags[0] = true; + } + + @Override + public void handleSuccess() { + super.handleSuccess(); + flags[1] = true; + } + + @Override + public void handleFailure() { + super.handleFailure(); + flags[2] = true; + } + + @Override + public void handleCancel() { + super.handleCancel(); + flags[3] = true; + } + }; + return request; + } + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + @Test + public void testTmfCoalescedEventRequestIndexNbEventsBlocksize() { + TmfCoalescedEventRequest request = new TmfCoalescedEventRequest(ITmfEvent.class, range1, 0, 100, ExecutionType.FOREGROUND); + + assertEquals("getRequestId", fRequestCount++, request.getRequestId()); + assertEquals("getDataType", ITmfEvent.class, request.getDataType()); + + assertEquals("getRange", range1, request.getRange()); + assertEquals("getNbRequestedEvents", 100, request.getNbRequested()); + + assertFalse("isCompleted", request.isCompleted()); + assertFalse("isFailed", request.isFailed()); + assertFalse("isCancelled", request.isCancelled()); + + assertEquals("getNbRead", 0, request.getNbRead()); + } + + // ------------------------------------------------------------------------ + // equals + // ------------------------------------------------------------------------ + + @Test + public void testEqualsReflexivity() { + assertTrue("equals", fRequest1.equals(fRequest1)); + assertTrue("equals", fRequest2.equals(fRequest2)); + + assertFalse("equals", fRequest1.equals(fRequest2)); + assertFalse("equals", fRequest2.equals(fRequest1)); + } + + @Test + public void testEqualsSymmetry() { + assertTrue("equals", fRequest1.equals(fRequest1b)); + assertTrue("equals", fRequest1b.equals(fRequest1)); + + assertFalse("equals", fRequest1.equals(fRequest3)); + assertFalse("equals", fRequest2.equals(fRequest3)); + assertFalse("equals", fRequest3.equals(fRequest1)); + assertFalse("equals", fRequest3.equals(fRequest2)); + } + + @Test + public void testEqualsTransivity() { + assertTrue("equals", fRequest1.equals(fRequest1b)); + assertTrue("equals", fRequest1b.equals(fRequest1c)); + assertTrue("equals", fRequest1.equals(fRequest1c)); + } + + @Test + public void testEqualsNull() { + assertFalse("equals", fRequest1.equals(null)); + assertFalse("equals", fRequest2.equals(null)); + } + + // ------------------------------------------------------------------------ + // hashCode + // ------------------------------------------------------------------------ + + @Test + public void testHashCode() { + assertTrue("hashCode", fRequest1.hashCode() == fRequest1.hashCode()); + assertTrue("hashCode", fRequest2.hashCode() == fRequest2.hashCode()); + assertTrue("hashCode", fRequest1.hashCode() != fRequest2.hashCode()); + } + + // ------------------------------------------------------------------------ + // toString + // ------------------------------------------------------------------------ + + @Test + public void testToString() { + String expected1 = "[TmfCoalescedEventRequest(0,ITmfEvent,FOREGROUND," + range1 + ",0,100, [])]"; + String expected2 = "[TmfCoalescedEventRequest(1,ITmfEvent,FOREGROUND," + range2 + ",0,100, [])]"; + String expected3 = "[TmfCoalescedEventRequest(2,ITmfEvent,FOREGROUND," + range2 + ",0,200, [])]"; + String expected4 = "[TmfCoalescedEventRequest(3,ITmfEvent,FOREGROUND," + range2 + ",0,200, [])]"; + + assertEquals("toString", expected1, fRequest1.toString()); + assertEquals("toString", expected2, fRequest2.toString()); + assertEquals("toString", expected3, fRequest3.toString()); + assertEquals("toString", expected4, fRequest4.toString()); + } + + // ------------------------------------------------------------------------ + // isCompatible + // ------------------------------------------------------------------------ + + @Test + public void testIsCompatible() { + TmfCoalescedEventRequest coalescedRequest = new TmfCoalescedEventRequest(ITmfEvent.class, range1, 0, 100, ExecutionType.FOREGROUND); + TmfEventRequest req1 = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); + TmfEventRequest req2 = new TmfEventRequestStub(ITmfEvent.class, range2, 100, 200); + TmfEventRequest req3 = new TmfEventRequestStub(ITmfEvent.class, range1, 101, 200); + + assertTrue("isCompatible", coalescedRequest.isCompatible(req1)); + assertTrue("isCompatible", coalescedRequest.isCompatible(req2)); + assertTrue("isCompatible", coalescedRequest.isCompatible(req3)); + } + + // ------------------------------------------------------------------------ + // addEvent + // ------------------------------------------------------------------------ + + @Test + public void testAddEvent1() { + TmfCoalescedEventRequest coalescedRequest = new TmfCoalescedEventRequest(ITmfEvent.class, range1, 0, 2147483647, ExecutionType.FOREGROUND); + TmfEventRequest req1 = new TmfEventRequestStub(ITmfEvent.class, range1, 0, 2147483647, 200); + TmfEventRequest req2 = new TmfEventRequestStub(ITmfEvent.class, range1, 1, 2147483647, 200); + + assertTrue("isCompatible", coalescedRequest.isCompatible(req1)); + assertTrue("isCompatible", coalescedRequest.isCompatible(req2)); + + coalescedRequest.addRequest(req1); + coalescedRequest.addRequest(req2); + + assertEquals("addRequest", 0, coalescedRequest.getIndex()); + assertEquals("addRequest", 2147483647, coalescedRequest.getNbRequested()); + } + + @Test + public void testAddEvent2() { + TmfCoalescedEventRequest coalescedRequest = new TmfCoalescedEventRequest(ITmfEvent.class, range1, 1, 2147483647, ExecutionType.FOREGROUND); + TmfEventRequest req1 = new TmfEventRequestStub(ITmfEvent.class, range1, 1, 2147483647, 200); + TmfEventRequest req2 = new TmfEventRequestStub(ITmfEvent.class, range1, 0, 2147483647, 200); + + assertTrue("isCompatible", coalescedRequest.isCompatible(req1)); + assertTrue("isCompatible", coalescedRequest.isCompatible(req2)); + + coalescedRequest.addRequest(req1); + coalescedRequest.addRequest(req2); + + assertEquals("addRequest", 0, coalescedRequest.getIndex()); + assertEquals("addRequest", 2147483647, coalescedRequest.getNbRequested()); + } + + // ------------------------------------------------------------------------ + // done + // ------------------------------------------------------------------------ + + @Test + public void testDone() { + // Test request + final boolean[] crFlags = new boolean[4]; + TmfCoalescedEventRequest request = setupTestRequest(crFlags); + TmfEventRequest subRequest1 = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); + TmfEventRequest subRequest2 = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); + request.addRequest(subRequest1); + request.addRequest(subRequest2); + + request.done(); + + // Validate the coalescing request + assertTrue("isCompleted", request.isCompleted()); + assertFalse("isFailed", request.isFailed()); + assertFalse("isCancelled", request.isCancelled()); + + assertTrue("handleCompleted", crFlags[0]); + assertTrue("handleSuccess", crFlags[1]); + assertFalse("handleFailure", crFlags[2]); + assertFalse("handleCancel", crFlags[3]); + + // Validate the first coalesced request + assertTrue("isCompleted", subRequest1.isCompleted()); + assertFalse("isFailed", subRequest1.isFailed()); + assertFalse("isCancelled", subRequest1.isCancelled()); + + // Validate the second coalesced request + assertTrue("isCompleted", subRequest2.isCompleted()); + assertFalse("isFailed", subRequest2.isFailed()); + assertFalse("isCancelled", subRequest2.isCancelled()); + } + + // ------------------------------------------------------------------------ + // fail + // ------------------------------------------------------------------------ + + @Test + public void testFail() { + final boolean[] crFlags = new boolean[4]; + TmfCoalescedEventRequest request = setupTestRequest(crFlags); + TmfEventRequest subRequest1 = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); + TmfEventRequest subRequest2 = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); + request.addRequest(subRequest1); + request.addRequest(subRequest2); + + request.fail(); + + // Validate the coalescing request + assertTrue("isCompleted", request.isCompleted()); + assertTrue("isFailed", request.isFailed()); + assertFalse("isCancelled", request.isCancelled()); + + assertTrue("handleCompleted", crFlags[0]); + assertFalse("handleSuccess", crFlags[1]); + assertTrue("handleFailure", crFlags[2]); + assertFalse("handleCancel", crFlags[3]); + + // Validate the first coalesced request + assertTrue("isCompleted", subRequest1.isCompleted()); + assertTrue("isFailed", subRequest1.isFailed()); + assertFalse("isCancelled", subRequest1.isCancelled()); + + // Validate the second coalesced request + assertTrue("isCompleted", subRequest2.isCompleted()); + assertTrue("isFailed", subRequest2.isFailed()); + assertFalse("isCancelled", subRequest2.isCancelled()); + } + + // ------------------------------------------------------------------------ + // cancel + // ------------------------------------------------------------------------ + + @Test + public void testCancel() { + final boolean[] crFlags = new boolean[4]; + TmfCoalescedEventRequest request = setupTestRequest(crFlags); + TmfEventRequest subRequest1 = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); + TmfEventRequest subRequest2 = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); + request.addRequest(subRequest1); + request.addRequest(subRequest2); + + request.cancel(); + + // Validate the coalescing request + assertTrue("isCompleted", request.isCompleted()); + assertFalse("isFailed", request.isFailed()); + assertTrue("isCancelled", request.isCancelled()); + + assertTrue("handleCompleted", crFlags[0]); + assertFalse("handleSuccess", crFlags[1]); + assertFalse("handleFailure", crFlags[2]); + assertTrue("handleCancel", crFlags[3]); + + // Validate the first coalesced request + assertTrue("isCompleted", subRequest1.isCompleted()); + assertFalse("isFailed", subRequest1.isFailed()); + assertTrue("isCancelled", subRequest1.isCancelled()); + + // Validate the second coalesced request + assertTrue("isCompleted", subRequest2.isCompleted()); + assertFalse("isFailed", subRequest2.isFailed()); + assertTrue("isCancelled", subRequest2.isCancelled()); + } + + // ------------------------------------------------------------------------ + // Coalescing + // ------------------------------------------------------------------------ + + private static final TmfTestTrace TEST_TRACE = TmfTestTrace.A_TEST_10K; + private static final int NB_EVENTS = 5000; + + // Initialize the test trace + private TmfTraceStub fTrace = null; + + private synchronized TmfTraceStub setupTrace(String path) { + if (fTrace == null) { + try { + URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(path), null); + File test = new File(FileLocator.toFileURL(location).toURI()); + fTrace = new TmfTraceStub(test.getPath(), 500, false, null); + } catch (TmfTraceException e) { + e.printStackTrace(); + } catch (URISyntaxException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return fTrace; + } + + Vector requestedEvents1; + Vector requestedEvents2; + Vector requestedEvents3; + + TmfEventRequest request1; + TmfEventRequest request2; + TmfEventRequest request3; + + ITmfEventProvider[] providers; + + private static class TmfTestTriggerSignal extends TmfSignal { + public final boolean forceCancel; + public final long fIndex; + + public TmfTestTriggerSignal(Object source, long index, boolean cancel) { + super(source); + forceCancel = cancel; + fIndex = index; + } + } + + private static class TmfTestTriggerSignal2 extends TmfSignal { + public TmfTestTriggerSignal2(Object source) { + super(source); + } + } + + @TmfSignalHandler + public void trigger(final TmfTestTriggerSignal signal) { + + TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + final long REQUEST_OFFSET = 1000; + + requestedEvents1 = new Vector<>(); + request1 = new TmfEventRequest(ITmfEvent.class, range, signal.fIndex, + NB_EVENTS, ExecutionType.FOREGROUND) { + @Override + public void handleData(ITmfEvent event) { + super.handleData(event); + if (!isCompleted()) { + requestedEvents1.add(event); + if (signal.forceCancel) { + cancel(); + } + } + } + }; + + requestedEvents2 = new Vector<>(); + request2 = new TmfEventRequest(ITmfEvent.class, range, + signal.fIndex + REQUEST_OFFSET, NB_EVENTS, ExecutionType.FOREGROUND) { + @Override + public void handleData(ITmfEvent event) { + super.handleData(event); + if (!isCompleted()) { + requestedEvents2.add(event); + } + } + }; + + requestedEvents3 = new Vector<>(); + request3 = new TmfEventRequest(ITmfEvent.class, range, + signal.fIndex + 2 * REQUEST_OFFSET, NB_EVENTS, ExecutionType.FOREGROUND) { + @Override + public void handleData(ITmfEvent event) { + super.handleData(event); + if (!isCompleted()) { + requestedEvents3.add(event); + } + } + }; + + providers = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); + providers[0].sendRequest(request1); + providers[0].sendRequest(request2); + providers[0].sendRequest(request3); + } + + /** + * @param signal + * the trigger signal + */ + @TmfSignalHandler + public void trigger(final TmfTestTriggerSignal2 signal) { + TmfTimeRange range = new TmfTimeRange(new TmfTimestamp(100, -3), TmfTimestamp.BIG_CRUNCH); + requestedEvents1 = new Vector<>(); + request1 = new TmfEventRequest(ITmfEvent.class, range, 0, 1, ExecutionType.FOREGROUND) { + @Override + public void handleData(ITmfEvent event) { + super.handleData(event); + if (!isCompleted()) { + requestedEvents1.add(event); + } + } + }; + providers = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); + providers[0].sendRequest(request1); + } + + public void runCoalescedRequest(long startIndex) throws InterruptedException { + + fTrace = setupTrace(TEST_TRACE.getFullPath()); + + TmfSignalManager.register(this); + TmfTestTriggerSignal signal = new TmfTestTriggerSignal(this, startIndex, false); + TmfSignalManager.dispatchSignal(signal); + + request1.waitForCompletion(); + request2.waitForCompletion(); + request3.waitForCompletion(); + + try { + assertEquals("Request1: nbEvents", NB_EVENTS, requestedEvents1.size()); + assertTrue("Request1: isCompleted", request1.isCompleted()); + assertFalse("Request1: isCancelled", request1.isCancelled()); + + assertEquals("Request2: nbEvents", NB_EVENTS, requestedEvents2.size()); + assertTrue("Request2: isCompleted", request2.isCompleted()); + assertFalse("Request2: isCancelled", request2.isCancelled()); + + assertEquals("Request3: nbEvents", NB_EVENTS, requestedEvents3.size()); + assertTrue("Request3: isCompleted", request3.isCompleted()); + assertFalse("Request3: isCancelled", request3.isCancelled()); + + // Ensure that we have distinct events. + // Don't go overboard: we are not validating the stub! + for (int i = 0; i < NB_EVENTS; i++) { + assertEquals("Distinct events", i + 1 + request1.getIndex(), requestedEvents1.get(i).getTimestamp().getValue()); + assertEquals("Distinct events", i + 1 + request2.getIndex(), requestedEvents2.get(i).getTimestamp().getValue()); + assertEquals("Distinct events", i + 1 + request3.getIndex(), requestedEvents3.get(i).getTimestamp().getValue()); + } + } finally { + TmfSignalManager.deregister(this); + fTrace.dispose(); + fTrace = null; + } + } + + @Test + public void testCoalescedRequest() throws InterruptedException { + runCoalescedRequest(0); + runCoalescedRequest(1); + runCoalescedRequest(5); + } + + @Test + public void testCancelCoalescedRequest() throws InterruptedException { + + fTrace = setupTrace(TEST_TRACE.getFullPath()); + + TmfSignalManager.register(this); + TmfTestTriggerSignal signal = new TmfTestTriggerSignal(this, 0, true); + TmfSignalManager.dispatchSignal(signal); + + request1.waitForCompletion(); + request2.waitForCompletion(); + request3.waitForCompletion(); + + assertTrue("Request1: isCompleted", request1.isCompleted()); + assertTrue("Request1: isCancelled", request1.isCancelled()); + + assertEquals("Request2: nbEvents", NB_EVENTS, requestedEvents2.size()); + assertTrue("Request2: isCompleted", request2.isCompleted()); + assertFalse("Request2: isCancelled", request2.isCancelled()); + + assertEquals("Request3: nbEvents", NB_EVENTS, requestedEvents3.size()); + assertTrue("Request3: isCompleted", request3.isCompleted()); + assertFalse("Request3: isCancelled", request3.isCancelled()); + + // Ensure that we have distinct events. + // Don't go overboard: we are not validating the stub! + for (int i = 0; i < NB_EVENTS; i++) { + assertEquals("Distinct events", i + 1 + request2.getIndex(), requestedEvents2.get(i).getTimestamp().getValue()); + assertEquals("Distinct events", i + 1 + request3.getIndex(), requestedEvents3.get(i).getTimestamp().getValue()); + } + + TmfSignalManager.deregister(this); + fTrace.dispose(); + fTrace = null; + } + + @Test + public void testSingleTimeRequest() throws InterruptedException { + + fTrace = setupTrace(TEST_TRACE.getFullPath()); + + TmfSignalManager.register(this); + TmfTestTriggerSignal2 signal = new TmfTestTriggerSignal2(this); + TmfSignalManager.dispatchSignal(signal); + + request1.waitForCompletion(); + + assertTrue("Request1: isCompleted", request1.isCompleted()); + + // We have to have one event processed + assertEquals("Request1: nbEvents", 1, requestedEvents1.size()); + + TmfSignalManager.deregister(this); + fTrace.dispose(); + fTrace = null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/request/TmfEventRequestTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/request/TmfEventRequestTest.java new file mode 100644 index 0000000000..c1df4c2c4d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/request/TmfEventRequestTest.java @@ -0,0 +1,313 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.request; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.tests.stubs.request.TmfEventRequestStub; +import org.junit.Before; +import org.junit.Test; + +/** + * Test suite for the TmfEventRequest class. + */ +@SuppressWarnings("javadoc") +public class TmfEventRequestTest { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + private static TmfTimeRange range1 = new TmfTimeRange(TmfTimeRange.ETERNITY); + private static TmfTimeRange range2 = new TmfTimeRange(new TmfTimestamp(), TmfTimestamp.BIG_CRUNCH); + + private static TmfEventRequest fRequest1; + private static TmfEventRequest fRequest1b; + private static TmfEventRequest fRequest1c; + private static TmfEventRequest fRequest2; + private static TmfEventRequest fRequest3; + private static TmfEventRequest fRequest4; + + private static int fRequestCount; + + // ------------------------------------------------------------------------ + // Housekeeping + // ------------------------------------------------------------------------ + + @Before + public void setUp() { + TmfEventRequest.reset(); + fRequest1 = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); + fRequest2 = new TmfEventRequestStub(ITmfEvent.class, range2, 100, 200); + fRequest3 = new TmfEventRequestStub(ITmfEvent.class, range2, 200, 200); + fRequest4 = new TmfEventRequestStub(ITmfEvent.class, range2, 200, 300); + fRequest1b = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); + fRequest1c = new TmfEventRequestStub(ITmfEvent.class, range1, 100, 200); + fRequestCount = fRequest1c.getRequestId() + 1; + } + + private static TmfEventRequest setupTestRequest(final boolean[] flags) { + + TmfEventRequest request = new TmfEventRequestStub(ITmfEvent.class, new TmfTimeRange(TmfTimeRange.ETERNITY), 100, 200) { + @Override + public void handleCompleted() { + super.handleCompleted(); + flags[0] = true; + } + + @Override + public void handleSuccess() { + super.handleSuccess(); + flags[1] = true; + } + + @Override + public void handleFailure() { + super.handleFailure(); + flags[2] = true; + } + + @Override + public void handleCancel() { + super.handleCancel(); + flags[3] = true; + } + }; + return request; + } + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + @Test + public void testTmfEventRequest() { + TmfEventRequest request = new TmfEventRequestStub(ITmfEvent.class); + + assertEquals("getRequestId", fRequestCount++, request.getRequestId()); + assertEquals("getDataType", ITmfEvent.class, request.getDataType()); + + assertEquals("StartTime", TmfTimestamp.BIG_BANG, request.getRange().getStartTime()); + assertEquals("EndTime", TmfTimestamp.BIG_CRUNCH, request.getRange().getEndTime()); + + assertEquals("getRange", TmfTimeRange.ETERNITY, request.getRange()); + assertSame("getRange", TmfTimeRange.ETERNITY, request.getRange()); + + assertEquals("getIndex", 0, request.getIndex()); + assertEquals("getNbRequestedEvents", ITmfEventRequest.ALL_DATA, request.getNbRequested()); + + assertFalse("isCompleted", request.isCompleted()); + assertFalse("isFailed", request.isFailed()); + assertFalse("isCancelled", request.isCancelled()); + + assertEquals("getNbRead", 0, request.getNbRead()); + } + + @Test + public void testTmfEventRequestTimeRange() { + TmfTimeRange range = new TmfTimeRange(new TmfTimestamp(), TmfTimestamp.BIG_CRUNCH); + TmfEventRequest request = new TmfEventRequestStub(ITmfEvent.class, range); + + assertEquals("getRequestId", fRequestCount++, request.getRequestId()); + assertEquals("getDataType", ITmfEvent.class, request.getDataType()); + + assertEquals("StartTime", new TmfTimestamp(), request.getRange().getStartTime()); + assertEquals("EndTime", TmfTimestamp.BIG_CRUNCH, request.getRange().getEndTime()); + + assertEquals("getIndex", 0, request.getIndex()); + assertEquals("getNbRequestedEvents", ITmfEventRequest.ALL_DATA, request.getNbRequested()); + + assertFalse("isCompleted", request.isCompleted()); + assertFalse("isFailed", request.isFailed()); + assertFalse("isCancelled", request.isCancelled()); + + assertEquals("getNbRead", 0, request.getNbRead()); + } + + @Test + public void testTmfEventRequestTimeRangeNbRequested() { + TmfTimeRange range = new TmfTimeRange(new TmfTimestamp(), TmfTimestamp.BIG_CRUNCH); + TmfEventRequest request = new TmfEventRequestStub(ITmfEvent.class, range, 100); + + assertEquals("getRequestId", fRequestCount++, request.getRequestId()); + assertEquals("getDataType", ITmfEvent.class, request.getDataType()); + + assertEquals("StartTime", new TmfTimestamp(), request.getRange().getStartTime()); + assertEquals("EndTime", TmfTimestamp.BIG_CRUNCH, request.getRange().getEndTime()); + + assertEquals("getIndex", 0, request.getIndex()); + assertEquals("getNbRequestedEvents", 100, request.getNbRequested()); + + assertFalse("isCompleted", request.isCompleted()); + assertFalse("isFailed", request.isFailed()); + assertFalse("isCancelled", request.isCancelled()); + + assertEquals("getNbRead", 0, request.getNbRead()); + } + + @Test + public void testTmfEventRequestTimeRangeNbRequestedBlocksize() { + TmfTimeRange range = new TmfTimeRange(new TmfTimestamp(), TmfTimestamp.BIG_CRUNCH); + TmfEventRequest request = new TmfEventRequestStub(ITmfEvent.class, range, 100, 200); + + assertEquals("getRequestId", fRequestCount++, request.getRequestId()); + assertEquals("getDataType", ITmfEvent.class, request.getDataType()); + + assertEquals("StartTime", new TmfTimestamp(), request.getRange().getStartTime()); + assertEquals("EndTime", TmfTimestamp.BIG_CRUNCH, request.getRange().getEndTime()); + + assertEquals("getIndex", 0, request.getIndex()); + assertEquals("getNbRequestedEvents", 100, request.getNbRequested()); + + assertFalse("isCompleted", request.isCompleted()); + assertFalse("isFailed", request.isFailed()); + assertFalse("isCancelled", request.isCancelled()); + + assertEquals("getNbRead", 0, request.getNbRead()); + } + + // ------------------------------------------------------------------------ + // equals + // ------------------------------------------------------------------------ + + @Test + public void testEqualsReflexivity() { + assertTrue("equals", fRequest1.equals(fRequest1)); + assertTrue("equals", fRequest2.equals(fRequest2)); + + assertFalse("equals", fRequest1.equals(fRequest2)); + assertFalse("equals", fRequest2.equals(fRequest1)); + } + + @Test + public void testEqualsSymmetry() { + assertTrue("equals", fRequest1.equals(fRequest1b)); + assertTrue("equals", fRequest1b.equals(fRequest1)); + + assertFalse("equals", fRequest1.equals(fRequest3)); + assertFalse("equals", fRequest2.equals(fRequest3)); + assertFalse("equals", fRequest3.equals(fRequest1)); + assertFalse("equals", fRequest3.equals(fRequest2)); + } + + @Test + public void testEqualsTransivity() { + assertTrue("equals", fRequest1.equals(fRequest1b)); + assertTrue("equals", fRequest1b.equals(fRequest1c)); + assertTrue("equals", fRequest1.equals(fRequest1c)); + } + + @Test + public void testEqualsNull() { + assertFalse("equals", fRequest1.equals(null)); + assertFalse("equals", fRequest2.equals(null)); + } + + // ------------------------------------------------------------------------ + // hashCode + // ------------------------------------------------------------------------ + + @Test + public void testHashCode() { + assertTrue("hashCode", fRequest1.hashCode() == fRequest1.hashCode()); + assertTrue("hashCode", fRequest2.hashCode() == fRequest2.hashCode()); + assertTrue("hashCode", fRequest1.hashCode() != fRequest2.hashCode()); + } + + // ------------------------------------------------------------------------ + // toString + // ------------------------------------------------------------------------ + + @Test + public void testToString() { + String expected1 = "[TmfEventRequestStub(0,ITmfEvent,FOREGROUND," + range1 + ",0,100)]"; + String expected2 = "[TmfEventRequestStub(1,ITmfEvent,FOREGROUND," + range2 + ",0,100)]"; + String expected3 = "[TmfEventRequestStub(2,ITmfEvent,FOREGROUND," + range2 + ",0,200)]"; + String expected4 = "[TmfEventRequestStub(3,ITmfEvent,FOREGROUND," + range2 + ",0,200)]"; + + assertEquals("toString", expected1, fRequest1.toString()); + assertEquals("toString", expected2, fRequest2.toString()); + assertEquals("toString", expected3, fRequest3.toString()); + assertEquals("toString", expected4, fRequest4.toString()); + } + + // ------------------------------------------------------------------------ + // done + // ------------------------------------------------------------------------ + + @Test + public void testDone() { + final boolean[] flags = new boolean[4]; + TmfEventRequest request = setupTestRequest(flags); + request.done(); + + assertTrue("isCompleted", request.isCompleted()); + assertFalse("isFailed", request.isFailed()); + assertFalse("isCancelled", request.isCancelled()); + + assertTrue("handleCompleted", flags[0]); + assertTrue("handleSuccess", flags[1]); + assertFalse("handleFailure", flags[2]); + assertFalse("handleCancel", flags[3]); + } + + // ------------------------------------------------------------------------ + // fail + // ------------------------------------------------------------------------ + + @Test + public void testFail() { + final boolean[] flags = new boolean[4]; + TmfEventRequest request = setupTestRequest(flags); + request.fail(); + + assertTrue("isCompleted", request.isCompleted()); + assertTrue("isFailed", request.isFailed()); + assertFalse("isCancelled", request.isCancelled()); + + assertTrue("handleCompleted", flags[0]); + assertFalse("handleSuccess", flags[1]); + assertTrue("handleFailure", flags[2]); + assertFalse("handleCancel", flags[3]); + } + + // ------------------------------------------------------------------------ + // cancel + // ------------------------------------------------------------------------ + + @Test + public void testCancel() { + final boolean[] flags = new boolean[4]; + TmfEventRequest request = setupTestRequest(flags); + request.cancel(); + + assertTrue("isCompleted", request.isCompleted()); + assertFalse("isFailed", request.isFailed()); + assertTrue("isCancelled", request.isCancelled()); + + assertTrue("handleCompleted", flags[0]); + assertFalse("handleSuccess", flags[1]); + assertFalse("handleFailure", flags[2]); + assertTrue("handleCancel", flags[3]); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/signal/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/signal/AllTests.java new file mode 100644 index 0000000000..6c4f6adcd2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/signal/AllTests.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.signal; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Signal tests + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TmfSignalManagerTest.class, + TmfSignalThrottlerTest.class +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/signal/TmfSignalManagerTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/signal/TmfSignalManagerTest.java new file mode 100644 index 0000000000..ac31c46b4f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/signal/TmfSignalManagerTest.java @@ -0,0 +1,558 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.signal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CountDownLatch; + +import org.eclipse.tracecompass.tmf.core.component.TmfComponent; +import org.eclipse.tracecompass.tmf.core.signal.TmfEndSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfStartSynchSignal; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Test suite for {@link TmfSignalManager} + * + * @author Bernd Hufmann + */ +public class TmfSignalManagerTest { + + private TestSignalSender signalSender; + + /** + * Pre-test setup + */ + @Before + public void setUp() { + signalSender = new TestSignalSender(); + } + + /** + * After-test cleanup + */ + @After + public void tearDown() { + signalSender.dispose(); + } + + // ------------------------------------------------------------------------ + // Test cases + // ------------------------------------------------------------------------ + + /** + * Test send and receive including synch signals. + */ + @Test + public void testSendReceive() { + final int NB_HANDLERS = 10; + TestSignalHandler[] signalReceivers = new TestSignalHandler[NB_HANDLERS]; + for (int i = 0; i < NB_HANDLERS; i++) { + signalReceivers[i] = new TestSignalHandler(); + } + final TestSignal1 firstSignal = new TestSignal1(signalSender); + final TestSignal2 secondSignal = new TestSignal2(signalSender); + + final Class[] expectedOrder = new Class[] { + TmfStartSynchSignal.class, TestSignal1.class, TmfEndSynchSignal.class, + TmfStartSynchSignal.class, TestSignal2.class, TmfEndSynchSignal.class }; + + try { + signalSender.sendSignal(firstSignal); + signalSender.sendSignal(secondSignal); + + for (int i = 0; i < NB_HANDLERS; i++) { + assertEquals(expectedOrder.length, signalReceivers[i].receivedSignals.size()); + + for (int k = 0; k < expectedOrder.length; k++) { + assertEquals(signalReceivers[i].receivedSignals.get(k).getClass(), expectedOrder[k]); + } + + for (int k = 0; k < expectedOrder.length; k += 3) { + // Verify signal IDs + int startSyncId = signalReceivers[i].receivedSignals.get(k).getReference(); + int signalId = signalReceivers[i].receivedSignals.get(k + 1).getReference(); + int endSyncId = signalReceivers[i].receivedSignals.get(k + 2).getReference(); + + assertEquals(startSyncId, signalId); + assertEquals(startSyncId, endSyncId); + } + } + } finally { + // Make sure that handlers are disposed in any case (success or not success) + for (int i = 0; i < NB_HANDLERS; i++) { + signalReceivers[i].dispose(); + } + } + } + + /** + * Test nesting signals. Verify that they are handled in the same thread. + */ + @Test + public void testNestedSignals() { + TestSignalHandlerNested signalResender = new TestSignalHandlerNested(); + TestSignalHandler signalReceiver = new TestSignalHandler(); + + final TestSignal1 mainSignal = new TestSignal1(signalSender); + + final Class[] expectedOrder = new Class[] { + TmfStartSynchSignal.class, + TmfStartSynchSignal.class, + TestSignal2.class, + TmfEndSynchSignal.class, + TmfStartSynchSignal.class, + TmfStartSynchSignal.class, + TestSignal4.class, + TmfEndSynchSignal.class, + TestSignal3.class, + TmfEndSynchSignal.class, + TestSignal1.class, + TmfEndSynchSignal.class + }; + + /* + * Index of signals in array signalReceiver.receivedSignals which have + * to have the same signal ID. + */ + + final int[] sameSigNoIndex = new int[] { + 0, 10, 11, 1, 2, 3, 4, 8, 9, 5, 6, 7 + }; + + try { + signalSender.sendSignal(mainSignal); + + assertEquals(expectedOrder.length, signalReceiver.receivedSignals.size()); + + for (int i = 0; i < expectedOrder.length; i++) { + assertEquals(signalReceiver.receivedSignals.get(i).getClass(), expectedOrder[i]); + } + + for (int i = 0; i < sameSigNoIndex.length; i+=3) { + // Verify signal IDs + int startSyncId = signalReceiver.receivedSignals.get(sameSigNoIndex[i]).getReference(); + int signalId = signalReceiver.receivedSignals.get(sameSigNoIndex[i + 1]).getReference(); + int endSyncId = signalReceiver.receivedSignals.get(sameSigNoIndex[i + 2]).getReference(); + assertEquals(startSyncId, signalId); + assertEquals(startSyncId, endSyncId); + } + } finally { + // Make sure that handlers are disposed in any case (success or not success) + signalResender.dispose(); + signalReceiver.dispose(); + } + } + + /** + * Test concurrent signals. Verify that they are handled one after each + * other. + */ + @Test + public void testConcurrentSignals() { + + TestSignalHandlerNested signalResender = new TestSignalHandlerNested(); + TestSignalHandler signalReceiver = new TestSignalHandler(false, null); + + /* + * Test of synchronization of signal manager. + * + * The order of received signals is either set of signals triggered by + * thread1 before set of signals triggered by thread2 or the other way + * around. + * + * If both received sets were interleaved then the synchronization of + * the signal manager would be not working. + */ + + final Class[] expectedOrder1 = new Class[] { + TestSignal2.class, TestSignal4.class, TestSignal3.class, TestSignal1.class, // signals triggered by thread 1 + TestSignal4.class // signal triggered by thread2 + }; + + final Class[] expectedOrder2 = new Class[] { + TestSignal4.class, // signal triggered by thread2 + TestSignal2.class, TestSignal4.class, TestSignal3.class, TestSignal1.class // signals triggered by thread 1 + }; + + /* + * Run it multiple times so that both expected order are triggered + */ + try { + for (int k = 0; k < 10; k++) { + // Latch to ensure that both threads are started + final CountDownLatch startLatch = new CountDownLatch(2); + // Latch to ensure that signals are send roughly at the same time + final CountDownLatch sendLatch = new CountDownLatch(1); + // Latch to ensure that both treads are finished + final CountDownLatch endLatch = new CountDownLatch(2); + + signalReceiver.receivedSignals.clear(); + + Thread senderThread1 = new Thread() { + @Override + public void run() { + startLatch.countDown(); + try { + sendLatch.await(); + } catch (InterruptedException e) { + } + signalSender.sendSignal(new TestSignal1(signalSender)); + endLatch.countDown(); + } + }; + + Thread senderThread2 = new Thread() { + @Override + public void run() { + startLatch.countDown(); + try { + sendLatch.await(); + } catch (InterruptedException e) { + } + signalSender.sendSignal(new TestSignal4(signalSender)); + endLatch.countDown(); + } + }; + + senderThread1.start(); + senderThread2.start(); + try { + startLatch.await(); + } catch (InterruptedException e) { + } + sendLatch.countDown(); + + try { + endLatch.await(); + } catch (InterruptedException e) { + } + + assertEquals(expectedOrder1.length, signalReceiver.receivedSignals.size()); + boolean pass = true; + for (int i = 0; i < expectedOrder1.length; i++) { + if (!signalReceiver.receivedSignals.get(i).getClass().equals(expectedOrder1[i])) { + pass = false; + break; + } + } + + if (!pass) { + for (int i = 0; i < expectedOrder2.length; i++) { + if (!signalReceiver.receivedSignals.get(i).getClass().equals(expectedOrder2[i])) { + fail("Concurrent signal test failure!"); + } + } + } + } + } finally { + // Make sure that handlers are disposed in any case (success or not success) + signalResender.dispose(); + signalReceiver.dispose(); + } + } + + /** + * Test broadcastAsync() + */ + @Test + public void testBroadcastAsync() { + TestSignalHandlerNested signalResender = new TestSignalHandlerNested(false); + + final int NB_HANDLERS = 10; + final CountDownLatch latch = new CountDownLatch(NB_HANDLERS); + TestSignalHandler[] signalReceivers = new TestSignalHandler[NB_HANDLERS]; + for (int i = 0; i < NB_HANDLERS; i++) { + signalReceivers[i] = new TestSignalHandler(false, latch); + } + + final Class[] expectedOrder = new Class[] { + TestSignal1.class, TestSignal2.class, TestSignal3.class, TestSignal4.class + }; + + try { + final TestSignal1 mainSignal = new TestSignal1(signalSender); + signalSender.sendSignal(mainSignal); + + try { + latch.await(); + } catch (InterruptedException e) { + } + + for (int i = 0; i < NB_HANDLERS; i++) { + assertEquals(expectedOrder.length, signalReceivers[i].receivedSignals.size()); + for (int k = 0; k < expectedOrder.length; k++) { + assertEquals(signalReceivers[i].receivedSignals.get(k).getClass(), expectedOrder[k]); + } + } + } finally { + // Make sure that handlers are disposed in any case (success or not success) + for (int i = 0; i < NB_HANDLERS; i++) { + signalReceivers[i].dispose(); + } + signalResender.dispose(); + } + } + + // ------------------------------------------------------------------------ + // Helper classes + // ------------------------------------------------------------------------ + + /** + * Signal sender + */ + private class TestSignalSender extends TmfComponent { + + TestSignalSender() { + super("TestSignalSender"); + } + + /** + * Send a signal + * + * @param signal + * main signal to send + */ + public void sendSignal(TmfSignal signal) { + broadcast(signal); + } + } + + /** + * Signal handler implementation for testing nested signals. + * Needs to be public so TmfSignalManager can see it. + */ + public class TestSignalHandlerNested extends AbstractBaseSignalHandler { + + private boolean sync; + + /** + * Constructor + */ + private TestSignalHandlerNested() { + this(true); + } + + /** + * Constructor + * + * @param sync + * log sync signals + * + */ + private TestSignalHandlerNested(boolean sync) { + super("TestSignalHandlerNested", false); + this.sync = sync; + TmfSignalManager.deregister(this); + TmfSignalManager.registerVIP(this); + } + + /** + * Receive a signal of type TestSignal1. + * + * @param signal + * Signal received + */ + @TmfSignalHandler + public void receiveSignal1(final TestSignal1 signal) { + if (sync) { + broadcast(new TestSignal2(signal.getSource())); + broadcast(new TestSignal3(signal.getSource())); + } else { + broadcastAsync(new TestSignal2(signal.getSource())); + broadcastAsync(new TestSignal3(signal.getSource())); + } + } + + /** + * Receive a signal of type TestSignal3. + * + * @param signal + * Signal received + */ + @TmfSignalHandler + public void receiveSignal3(final TestSignal3 signal) { + if (sync) { + broadcast(new TestSignal4(signal.getSource())); + } else { + broadcastAsync(new TestSignal4(signal.getSource())); + } + } + } + + /** + * Signal handler implementation for testing of sending and receiving + * signals. + */ + public class TestSignalHandler extends AbstractBaseSignalHandler { + + private CountDownLatch latch; + + /** + * Constructor + * + */ + private TestSignalHandler() { + this(true, null); + } + + /** + * Constructor + * + * @param logSyncSigs + * log sync signals + * @param latch + * latch to count down when receiving last signal + * (TmfSingal4) + */ + private TestSignalHandler(boolean logSyncSigs, CountDownLatch latch) { + super("TestSignalHandler", logSyncSigs); + this.latch = latch; + } + + /** + * Receive a signal of type TestSignal1. + * + * @param signal + * Signal received + */ + @TmfSignalHandler + public void receiveSignal1(final TestSignal1 signal) { + receivedSignals.add(signal); + } + + /** + * Receive a signal of type TestSignal2. + * + * @param signal + * Signal received + */ + @TmfSignalHandler + public void receiveSignal2(final TestSignal2 signal) { + receivedSignals.add(signal); + } + + /** + * Receive a signal of type TestSignal3. + * + * @param signal + * Signal received + */ + @TmfSignalHandler + public void receiveSignal3(final TestSignal3 signal) { + receivedSignals.add(signal); + } + + /** + * Receive a signal of type TestSignal4. + * + * @param signal + * Signal received + */ + @TmfSignalHandler + public void receiveSignal4(final TestSignal4 signal) { + receivedSignals.add(signal); + if (latch != null) { + latch.countDown(); + } + } + } + + /** + * Base signal handler for start and end sync signals. + */ + public abstract class AbstractBaseSignalHandler extends TmfComponent { + List receivedSignals = new ArrayList<>(); + private boolean logSyncSigs; + + private AbstractBaseSignalHandler(String name, boolean logSyncSignal) { + super(name); + this.logSyncSigs = logSyncSignal; + } + + /** + * Receive a signal of type TmfStartSynchSignal. + * + * @param signal + * Signal received + */ + @TmfSignalHandler + public void receiveStartSynch(final TmfStartSynchSignal signal) { + if (logSyncSigs) { + receivedSignals.add(signal); + } + } + + /** + * Receive a signal of type TmfEndSynchSignal. + * + * @param signal + * Signal received + */ + @TmfSignalHandler + public void receiveEndSynch(final TmfEndSynchSignal signal) { + if (logSyncSigs) { + receivedSignals.add(signal); + } + } + } + + + /** + * Test Signal object + */ + private class TestSignal1 extends TmfSignal { + + public TestSignal1(Object source) { + super(source); + } + } + + /** + * Test Signal object + */ + private class TestSignal2 extends TmfSignal { + + public TestSignal2(Object source) { + super(source); + } + } + + /** + * Test Signal object + */ + private class TestSignal3 extends TmfSignal { + + public TestSignal3(Object source) { + super(source); + } + } + + /** + * Test Signal object + */ + private class TestSignal4 extends TmfSignal { + + public TestSignal4(Object source) { + super(source); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/signal/TmfSignalThrottlerTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/signal/TmfSignalThrottlerTest.java new file mode 100644 index 0000000000..c933dd69d5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/signal/TmfSignalThrottlerTest.java @@ -0,0 +1,224 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.signal; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.component.TmfComponent; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalThrottler; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Test suite for {@link TmfSignalThrottler} + * + * @author Alexandre Montplaisir + */ +public class TmfSignalThrottlerTest { + + private MySender sender; + private MyListener listener; + + /** + * Pre-test setup + */ + @Before + public void setUp() { + sender = new MySender(); + listener = new MyListener(); + } + + /** + * After-test cleanup + */ + @After + public void tearDown() { + sender.dispose(); + listener.dispose(); + } + + // ------------------------------------------------------------------------ + // Test cases + // ------------------------------------------------------------------------ + + /** + * Test using only one throttler. Only one signal should go through. + */ + @Test + public void testOneChannel() { + final MySignal sig1 = new MySignal(sender, 0); + final MySignal sig2 = new MySignal(sender, 0); + final MySignal sig3 = new MySignal(sender, 0); + + synchronized(this) { + sender.sendSignal(sig1); + sender.sendSignal(sig2); + sender.sendSignal(sig3); + } + + sleep(5000); + + assertEquals(1, listener.nbReceived[0]); + assertEquals(0, listener.nbReceived[1]); + assertEquals(0, listener.nbReceived[2]); + } + + /** + * Test using multiple throttlers in parrallel. Only one signal per + * throttler should go through. + */ + @Test + public void testMultipleChannels() { + List signals = new ArrayList<>(); + signals.add(new MySignal(sender, 0)); + signals.add(new MySignal(sender, 0)); + signals.add(new MySignal(sender, 0)); + + signals.add(new MySignal(sender, 1)); + signals.add(new MySignal(sender, 1)); + signals.add(new MySignal(sender, 1)); + + signals.add(new MySignal(sender, 2)); + signals.add(new MySignal(sender, 2)); + signals.add(new MySignal(sender, 2)); + + Collections.shuffle(signals); /* Every day */ + + synchronized(this) { + for (MySignal sig : signals) { + sender.sendSignal(sig); + } + } + + sleep(5000); + + for (int nb : listener.nbReceived) { + assertEquals(1, nb); + } + } + + /** + * Test with one throttler, sending signals slowly. All three signals should + * go through. + */ + @Test + public void testDelay() { + final MySignal sig1 = new MySignal(sender, 0); + final MySignal sig2 = new MySignal(sender, 0); + final MySignal sig3 = new MySignal(sender, 0); + + sender.sendSignal(sig1); + sleep(2000); + sender.sendSignal(sig2); + sleep(2000); + sender.sendSignal(sig3); + sleep(2000); + + assertEquals(3, listener.nbReceived[0]); + } + + // ------------------------------------------------------------------------ + // Helper methods + // ------------------------------------------------------------------------ + + private static void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + // ------------------------------------------------------------------------ + // Helper classes + // ------------------------------------------------------------------------ + + /** + * Signal sender + */ + private class MySender extends TmfComponent { + + private final TmfSignalThrottler[] throttlers; + + MySender() { + super("MySender"); + throttlers = new TmfSignalThrottler[] { + new TmfSignalThrottler(this, 200), + new TmfSignalThrottler(this, 500), + new TmfSignalThrottler(this, 1000), + }; + } + + void sendSignal(MySignal signal) { + throttlers[signal.getChannel()].queue(signal); + } + + @Override + public void dispose() { + super.dispose(); + for (TmfSignalThrottler elem : throttlers) { + elem.dispose(); + } + } + } + + /** + * Signal listener + */ + public class MyListener extends TmfComponent { + + int[] nbReceived = { 0, 0, 0 }; + + /** + * Constructor. Needs to be public so TmfSignalHandler can see it. + */ + public MyListener() { + super("MyListener"); + } + + /** + * Receive a signal. + * + * @param sig + * Signal received + */ + @TmfSignalHandler + public void receiveSignal(final MySignal sig) { + nbReceived[sig.getChannel()]++; + } + } + + /** + * Signal object + */ + private class MySignal extends TmfSignal { + + private final int channel; + + public MySignal(MySender source, int channel) { + super(source); + this.channel = channel; + } + + public int getChannel() { + return channel; + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/AllTests.java new file mode 100644 index 0000000000..009eb62b37 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/AllTests.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.statesystem; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for org.eclipse.linuxtools.tmf.core.tests.statesystem + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + ExperimentStateSystemModuleTest.class, + StateSystemAnalysisModuleTest.class +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/ExperimentStateSystemModuleTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/ExperimentStateSystemModuleTest.java new file mode 100644 index 0000000000..10768c82e1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/ExperimentStateSystemModuleTest.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.statesystem; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; +import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; +import org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestExperimentAnalysis; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfExperimentStub; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.rules.Timeout; + +/** + * Test the {@link TmfStateSystemAnalysisModule} class for an experiment + * + * @author Geneviève Bastien + */ +public class ExperimentStateSystemModuleTest { + + /** Time-out tests after some time */ + @Rule + public TestRule globalTimeout = new Timeout(60000); + + /** ID of the test state system analysis module */ + public static final String MODULE_SS = "org.eclipse.linuxtools.tmf.core.tests.experiment"; + + private TmfStateSystemAnalysisModule fModule; + private TmfExperiment fExperiment; + + /** + * Setup test trace + */ + @Before + public void setupTraces() { + ITmfTrace trace = TmfTestTrace.A_TEST_10K.getTrace(); + TmfSignalManager.deregister(trace); + ITmfTrace trace2 = TmfTestTrace.A_TEST_10K2.getTrace(); + TmfSignalManager.deregister(trace2); + ITmfTrace[] traces = { trace, trace2 }; + fExperiment = new TmfExperimentStub("Test", traces, 1000); + fExperiment.traceOpened(new TmfTraceOpenedSignal(this, fExperiment, null)); + + fModule = (TmfStateSystemAnalysisModule) fExperiment.getAnalysisModule(MODULE_SS); + assertNotNull(fModule); + } + + /** + * Some tests use traces, let's clean them here + */ + @After + public void cleanupTraces() { + fExperiment.dispose(); + } + + /** + * Test the state system module execution and result + */ + @Test + public void testSsModule() { + ITmfStateSystem ss = fModule.getStateSystem(); + assertNull(ss); + fModule.schedule(); + if (fModule.waitForCompletion()) { + ss = fModule.getStateSystem(); + assertNotNull(ss); + try { + int quark = ss.getQuarkAbsolute(TestExperimentAnalysis.TRACE_QUARK_NAME); + ITmfStateInterval interval = ss.querySingleState(ss.getCurrentEndTime(), quark); + assertEquals(2, interval.getStateValue().unboxInt()); + } catch (AttributeNotFoundException e) { + fail("The quark for number of traces does not exist"); + } catch (StateSystemDisposedException e) { + fail("Error: state system disposed"); + } + } else { + fail("Module did not complete properly"); + } + } + + /** + * Make sure that the state system is initialized after calling  + * {@link TmfStateSystemAnalysisModule#waitForInitialization()}. + */ + @Test + public void testInitialization() { + assertNull(fModule.getStateSystem()); + fModule.schedule(); + + fModule.waitForInitialization(); + assertNotNull(fModule.getStateSystem()); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/StateSystemAnalysisModuleTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/StateSystemAnalysisModuleTest.java new file mode 100644 index 0000000000..2c3dc00baa --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/StateSystemAnalysisModuleTest.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.statesystem; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.rules.Timeout; + +/** + * Test the {@link TmfStateSystemAnalysisModule} class + * + * @author Geneviève Bastien + */ +public class StateSystemAnalysisModuleTest { + + /** Time-out tests after 20 seconds */ + @Rule + public TestRule globalTimeout= new Timeout(20000); + + /** ID of the test state system analysis module */ + public static final String MODULE_SS = "org.eclipse.linuxtools.tmf.core.tests.analysis.sstest"; + + private TmfStateSystemAnalysisModule module; + + /** + * Setup test trace + */ + @Before + public void setupTraces() { + TmfTraceStub trace = (TmfTraceStub) TmfTestTrace.A_TEST_10K.getTrace(); + TmfSignalManager.deregister(trace); + trace.traceOpened(new TmfTraceOpenedSignal(this, trace, null)); + + module = (TmfStateSystemAnalysisModule) trace.getAnalysisModule(MODULE_SS); + } + + /** + * Some tests use traces, let's clean them here + */ + @After + public void cleanupTraces() { + TmfTestTrace.A_TEST_10K.dispose(); + } + + /** + * Test the state system module execution and result + */ + @Test + public void testSsModule() { + ITmfStateSystem ss = module.getStateSystem(); + assertNull(ss); + module.schedule(); + if (module.waitForCompletion()) { + ss = module.getStateSystem(); + assertNotNull(ss); + } else { + fail("Module did not complete properly"); + } + } + + /** + * Make sure that the state system is initialized after calling  + * {@link TmfStateSystemAnalysisModule#waitForInitialization()}. + */ + @Test + public void testInitialization() { + assertNull(module.getStateSystem()); + module.schedule(); + + module.waitForInitialization(); + assertNotNull(module.getStateSystem()); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/mipmap/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/mipmap/AllTests.java new file mode 100644 index 0000000000..36e7e053e9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/mipmap/AllTests.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Updates to mipmap feature + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.statesystem.mipmap; + +import org.eclipse.tracecompass.tmf.core.tests.statesystem.mipmap.TmfMipmapStateProviderTest; +import org.eclipse.tracecompass.tmf.core.tests.statesystem.mipmap.TmfMipmapStateProviderWeightedTest; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for org.eclipse.linuxtools.tmf.core.tests.statesystem.mipmap + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TmfMipmapStateProviderTest.class, + TmfMipmapStateProviderWeightedTest.class, +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderStub.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderStub.java new file mode 100644 index 0000000000..c4b6daf3ec --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderStub.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jean-Christian Kouamé - Initial API and implementation + * Patrick Tasse - Updates to mipmap feature + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.statesystem.mipmap; + +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.internal.tmf.core.statesystem.mipmap.AbstractTmfMipmapStateProvider; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp; + +/** + * A mipmap state provider for test + * + * @author Jean-Christian Kouamé + * @since 3.0 + */ +class TmfMipmapStateProviderStub extends AbstractTmfMipmapStateProvider { + /** test attribute name */ + public final static String TEST_ATTRIBUTE_NAME = "test_attribute"; //$NON-NLS-1$ + + private int resolution; + private ITmfStateValue.Type type; + private final static String MIPMAP_ID = "MIPMAP_ID"; //$NON-NLS-1$ + + private final String ERROR_ATTRIBUTE_NOT_FOUND = "Error : Impossible to find the attribute"; //$NON-NLS-1$ + private final String ERROR_INVALID_STATE_VALUE = "Error : Invalid state value"; //$NON-NLS-1$ + private final String ERROR_INVALID_TIMESTAMP = "Error : Invalid timestamp"; //$NON-NLS-1$ + + /** + * Constructor + * + * @param resolution + * the mipmap resolution array (max, min, avg) + * @param type + * the type of value to use + */ + public TmfMipmapStateProviderStub(int resolution, ITmfStateValue.Type type) { + super(null, TmfEvent.class, MIPMAP_ID); + this.resolution = resolution; + this.type = type; + } + + @Override + protected void eventHandle(ITmfEvent ev) { + final long ts = ev.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + try { + int quark = ss.getQuarkAbsoluteAndAdd(TEST_ATTRIBUTE_NAME); + ITmfStateValue value = (ITmfStateValue) ev.getContent().getValue(); + modifyMipmapAttribute(ts, value, quark, MIN | MAX | AVG, resolution); + } catch (TimeRangeException e) { + Activator.logError(ERROR_INVALID_TIMESTAMP, e); + } catch (AttributeNotFoundException e) { + Activator.logError(ERROR_ATTRIBUTE_NOT_FOUND, e); + } catch (StateValueTypeException e) { + Activator.logError(ERROR_INVALID_STATE_VALUE, e); + } + } + + @Override + public int getVersion() { + return 0; + } + + @Override + public TmfMipmapStateProviderStub getNewInstance() { + return new TmfMipmapStateProviderStub(resolution, type); + } + + /** + * @param time + * The event type + * @param longVal + * The event value or null + * @return A new TmfEvent + */ + public ITmfEvent createEvent(long time, Long longVal) { + ITmfStateValue value; + if (longVal == null) { + value = TmfStateValue.nullValue(); + } else if (type == ITmfStateValue.Type.LONG) { + value = TmfStateValue.newValueLong(longVal); + } else if (type == ITmfStateValue.Type.INTEGER) { + value = TmfStateValue.newValueInt(longVal.intValue()); + } else if (type == ITmfStateValue.Type.DOUBLE) { + value = TmfStateValue.newValueDouble(longVal.doubleValue()); + } else { + value = TmfStateValue.nullValue(); + } + ITmfTimestamp timestamp = new TmfNanoTimestamp(time); + ITmfEventType eventType = new TmfEventType(ITmfEventType.DEFAULT_CONTEXT_ID, MIPMAP_ID, null); + ITmfEventField content = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, value, null); + ITmfEvent event = new TmfEvent(null, timestamp, null, eventType, content, null); + return event; + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderTest.java new file mode 100644 index 0000000000..52c45f7eef --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderTest.java @@ -0,0 +1,541 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jean-Christian Kouamé - Initial API and implementation + * Patrick Tasse - Updates to mipmap feature + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.statesystem.mipmap; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.List; +import java.util.Random; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; +import org.eclipse.linuxtools.statesystem.core.StateSystemFactory; +import org.eclipse.linuxtools.statesystem.core.backend.IStateHistoryBackend; +import org.eclipse.linuxtools.statesystem.core.backend.InMemoryBackend; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type; +import org.eclipse.tracecompass.internal.tmf.core.statesystem.mipmap.AbstractTmfMipmapStateProvider; +import org.eclipse.tracecompass.internal.tmf.core.statesystem.mipmap.TmfStateSystemOperations; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * @author Jean-Christian Kouamé + * + */ +public class TmfMipmapStateProviderTest { + + @NonNull private static final String SSID = "mimap-test"; + private static final String TEST_ATTRIBUTE_NAME = TmfMipmapStateProviderStub.TEST_ATTRIBUTE_NAME; + private static final int NB_LEVELS = 4; + private static final long START_TIME = 1000L; + private static final long END_TIME = 100000000L; + private static final long INTERVAL = 1000L; + private static final int RESOLUTION = 16; + private static final double DELTA = 0.0001; + private static final long TEST_TIMESTAMP = 12345000L; + private static ITmfStateSystemBuilder ssq; + + /** + * Startup code, build a state system with n attributes always going up + * linearly + */ + @BeforeClass + public static void init() { + TmfMipmapStateProviderStub mmp = new TmfMipmapStateProviderStub(RESOLUTION, Type.LONG); + IStateHistoryBackend be = new InMemoryBackend(0); + ssq = StateSystemFactory.newStateSystem(SSID, be); + mmp.assignTargetStateSystem(ssq); + + for (long time = START_TIME; time <= END_TIME; time += INTERVAL) { + long value = time / INTERVAL; + ITmfEvent event = mmp.createEvent(time, value); + mmp.processEvent(event); + } + mmp.dispose(); + ssq.waitUntilBuilt(); + } + + /** + * Test a single query to the state system. + * + * Make sure the state system has data. + * + * Hint: the value read should always be t / 1000 + * + */ + @Test + public void testQuery() { + assertNotNull(ssq); + try { + Random rn = new Random(); + long time = Math.max(INTERVAL, rn.nextLong() % END_TIME); + List intervals = ssq.queryFullState(time); + int mipmapQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); + ITmfStateInterval interval = intervals.get(mipmapQuark); + long valueLong = interval.getStateValue().unboxLong(); + assertEquals(time / INTERVAL, valueLong); + + } catch (TimeRangeException e) { + fail(e.getMessage()); + } catch (StateSystemDisposedException e) { + fail(e.getMessage()); + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } catch (StateValueTypeException e) { + fail(e.getMessage()); + } + assertTrue(true); + } + + /** + * Test a single query to the state system for the maxLevel. + * + * Make sure the state system has data. + * + */ + @Test + public void testMaxLevel() { + assertNotNull(ssq); + try { + Random rn = new Random(); + long time = Math.max(INTERVAL, rn.nextLong() % END_TIME); + List intervals = ssq.queryFullState(time); + + int maxMipmapQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME, AbstractTmfMipmapStateProvider.MAX_STRING); + int nbLevelMax = intervals.get(maxMipmapQuark).getStateValue().unboxInt(); + assertEquals(NB_LEVELS, nbLevelMax); + + int minMipmapQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME, AbstractTmfMipmapStateProvider.MIN_STRING); + int nbLevelMin = intervals.get(minMipmapQuark).getStateValue().unboxInt(); + assertEquals(NB_LEVELS, nbLevelMin); + + int avgMipmapQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME, AbstractTmfMipmapStateProvider.AVG_STRING); + int nbLevelAvg = intervals.get(avgMipmapQuark).getStateValue().unboxInt(); + assertEquals(NB_LEVELS, nbLevelAvg); + + } catch (TimeRangeException e) { + fail(e.getMessage()); + } catch (StateSystemDisposedException e) { + fail(e.getMessage()); + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } catch (StateValueTypeException e) { + fail(e.getMessage()); + } + assertTrue(true); + + } + + /** + * Test a single query to the state system for a mip + * + * Make sure the state system has data. + * + */ + @Test + public void testQueryEventField() { + assertNotNull(ssq); + try { + List intervals = ssq.queryFullState(TEST_TIMESTAMP); + int eventFieldQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); + ITmfStateInterval interval = intervals.get(eventFieldQuark); + long valueLong = interval.getStateValue().unboxLong(); + assertEquals(TEST_TIMESTAMP / INTERVAL, valueLong); + } catch (TimeRangeException e) { + fail(e.getMessage()); + } catch (StateSystemDisposedException e) { + fail(e.getMessage()); + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } catch (StateValueTypeException e) { + fail(e.getMessage()); + } + assertTrue(true); + } + + /** + * Test a single query to the state system for a max + * + * Make sure the state system has data. + * + * Hint: the value read should always be greater than(t / 1000) + * + */ + @Test + public void testQueryMipMax() { + assertNotNull(ssq); + try { + List intervals = ssq.queryFullState(TEST_TIMESTAMP); + int mipmapQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME, AbstractTmfMipmapStateProvider.MAX_STRING); + + assertEquals("max nblevels", NB_LEVELS, intervals.get(mipmapQuark).getStateValue().unboxInt()); + for (int level = 1; level < NB_LEVELS; level++) { + long width = (long) Math.pow(RESOLUTION, level); + int levelQuark = ssq.getQuarkRelative(mipmapQuark, String.valueOf(level)); + ITmfStateInterval interval = intervals.get(levelQuark); + long valueLong = interval.getStateValue().unboxLong(); + assertEquals("max value @ level " + level, width + (((TEST_TIMESTAMP - START_TIME) / INTERVAL) / width) * width, valueLong); + assertEquals("max start time @ level " + level, START_TIME + (((TEST_TIMESTAMP - START_TIME) / INTERVAL) / width) * width * INTERVAL, interval.getStartTime()); + assertEquals("max end time @ level " + level, START_TIME + (INTERVAL * width) + (((TEST_TIMESTAMP - START_TIME) / INTERVAL) / width) * width * INTERVAL, interval.getEndTime() + 1); + } + + } catch (TimeRangeException e) { + fail(e.getMessage()); + } catch (StateSystemDisposedException e) { + fail(e.getMessage()); + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } catch (StateValueTypeException e) { + fail(e.getMessage()); + } + assertTrue(true); + } + + /** + * Test a single query to the state system for a min + * + * Make sure the state system has data. + * + * Hint: the value read should always be less than(t / 1000) + */ + @Test + public void testQueryMipMin() { + assertNotNull(ssq); + try { + List intervals = ssq.queryFullState(TEST_TIMESTAMP); + int mipmapQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME, AbstractTmfMipmapStateProvider.MIN_STRING); + + assertEquals("min nblevels", NB_LEVELS, intervals.get(mipmapQuark).getStateValue().unboxInt()); + for (int level = 1; level < NB_LEVELS; level++) { + long width = (long) Math.pow(RESOLUTION, level); + int levelQuark = ssq.getQuarkRelative(mipmapQuark, String.valueOf(level)); + ITmfStateInterval interval = intervals.get(levelQuark); + long valueLong = interval.getStateValue().unboxLong(); + assertEquals("min value @ level " + level, 1 + (((TEST_TIMESTAMP - START_TIME) / INTERVAL) / width) * width, valueLong); + assertEquals("min start time @ level " + level, START_TIME + (((TEST_TIMESTAMP - START_TIME) / INTERVAL) / width) * width * INTERVAL, interval.getStartTime()); + assertEquals("min end time @ level " + level, START_TIME + (INTERVAL * width) + (((TEST_TIMESTAMP - START_TIME) / INTERVAL) / width) * width * INTERVAL, interval.getEndTime() + 1); + } + + } catch (TimeRangeException e) { + fail(e.getMessage()); + } catch (StateSystemDisposedException e) { + fail(e.getMessage()); + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } catch (StateValueTypeException e) { + fail(e.getMessage()); + } + assertTrue(true); + } + + /** + * Test a single query to the state system for an average + * + * Make sure the state system has data. + * + * Hint: the value read should always be more or less(t / 1000) + * + */ + @Test + public void testQueryMipAvg() { + assertNotNull(ssq); + try { + List intervals = ssq.queryFullState(TEST_TIMESTAMP); + int mipmapQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME, AbstractTmfMipmapStateProvider.AVG_STRING); + + assertEquals("avg nblevels", NB_LEVELS, intervals.get(mipmapQuark).getStateValue().unboxInt()); + for (int level = 1; level < NB_LEVELS; level++) { + long width = (long) Math.pow(RESOLUTION, level); + int levelQuark = ssq.getQuarkRelative(mipmapQuark, String.valueOf(level)); + ITmfStateInterval interval = intervals.get(levelQuark); + double valueDouble = interval.getStateValue().unboxDouble(); + assertEquals("avg value @ level " + level, 0.5 + (width / 2) + (((TEST_TIMESTAMP - START_TIME) / INTERVAL) / width) * width, valueDouble, DELTA); + assertEquals("avg start time @ level " + level, START_TIME + (((TEST_TIMESTAMP - START_TIME) / INTERVAL) / width) * width * INTERVAL, interval.getStartTime()); + assertEquals("avg end time @ level " + level, START_TIME + (INTERVAL * width) + (((TEST_TIMESTAMP - START_TIME) / INTERVAL) / width) * width * INTERVAL, interval.getEndTime() + 1); + } + + } catch (TimeRangeException e) { + fail(e.getMessage()); + } catch (StateSystemDisposedException e) { + fail(e.getMessage()); + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } catch (StateValueTypeException e) { + fail(e.getMessage()); + } + assertTrue(true); + } + + /** + * Test a full query to the state system at the startTime + * + * Make sure the state system has data. + * + * Hint: the value read should always be more or less(t / 1000) + * + */ + @Test + public void testQueryValuesOnStart() { + assertNotNull(ssq); + try { + int quark; + + List intervals = ssq.queryFullState(START_TIME); + + int baseQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); + assertEquals(START_TIME / INTERVAL, intervals.get(baseQuark).getStateValue().unboxLong()); + + int maxMipmapQuark = ssq.getQuarkRelative(baseQuark, AbstractTmfMipmapStateProvider.MAX_STRING); + assertEquals("max nblevels", NB_LEVELS, intervals.get(maxMipmapQuark).getStateValue().unboxInt()); + quark = ssq.getQuarkRelative(maxMipmapQuark, String.valueOf(1)); + assertEquals("max value @ level 1", (long) Math.pow(RESOLUTION, 1), intervals.get(quark).getStateValue().unboxLong()); + quark = ssq.getQuarkRelative(maxMipmapQuark, String.valueOf(2)); + assertEquals("max value @ level 2", (long) Math.pow(RESOLUTION, 2), intervals.get(quark).getStateValue().unboxLong()); + quark = ssq.getQuarkRelative(maxMipmapQuark, String.valueOf(3)); + assertEquals("max value @ level 3", (long) Math.pow(RESOLUTION, 3), intervals.get(quark).getStateValue().unboxLong()); + quark = ssq.getQuarkRelative(maxMipmapQuark, String.valueOf(4)); + assertEquals("max value @ level 4", (long) Math.pow(RESOLUTION, 4), intervals.get(quark).getStateValue().unboxLong()); + + int minMipmapQuark = ssq.getQuarkRelative(baseQuark, AbstractTmfMipmapStateProvider.MIN_STRING); + assertEquals("min nblevels", NB_LEVELS, intervals.get(minMipmapQuark).getStateValue().unboxInt()); + quark = ssq.getQuarkRelative(minMipmapQuark, String.valueOf(1)); + assertEquals("min value @ level 1", START_TIME / INTERVAL, intervals.get(quark).getStateValue().unboxLong()); + quark = ssq.getQuarkRelative(minMipmapQuark, String.valueOf(2)); + assertEquals("min value @ level 2", START_TIME / INTERVAL, intervals.get(quark).getStateValue().unboxLong()); + quark = ssq.getQuarkRelative(minMipmapQuark, String.valueOf(3)); + assertEquals("min value @ level 3", START_TIME / INTERVAL, intervals.get(quark).getStateValue().unboxLong()); + quark = ssq.getQuarkRelative(minMipmapQuark, String.valueOf(4)); + assertEquals("min value @ level 4", START_TIME / INTERVAL, intervals.get(quark).getStateValue().unboxLong()); + + int avgMipmapQuark = ssq.getQuarkRelative(baseQuark, AbstractTmfMipmapStateProvider.AVG_STRING); + assertEquals("avg nblevels", NB_LEVELS, intervals.get(avgMipmapQuark).getStateValue().unboxInt()); + quark = ssq.getQuarkRelative(avgMipmapQuark, String.valueOf(1)); + assertEquals("avg value @ level 1", 0.5 + Math.pow(RESOLUTION, 1) / 2, intervals.get(quark).getStateValue().unboxDouble(), DELTA); + quark = ssq.getQuarkRelative(avgMipmapQuark, String.valueOf(2)); + assertEquals("avg value @ level 2", 0.5 + Math.pow(RESOLUTION, 2) / 2, intervals.get(quark).getStateValue().unboxDouble(), DELTA); + quark = ssq.getQuarkRelative(avgMipmapQuark, String.valueOf(3)); + assertEquals("avg value @ level 3", 0.5 + Math.pow(RESOLUTION, 3) / 2, intervals.get(quark).getStateValue().unboxDouble(), DELTA); + quark = ssq.getQuarkRelative(avgMipmapQuark, String.valueOf(4)); + assertEquals("avg value @ level 4", 0.5 + Math.pow(RESOLUTION, 4) / 2, intervals.get(quark).getStateValue().unboxDouble(), DELTA); + + } catch (TimeRangeException e) { + fail(e.getMessage()); + } catch (StateSystemDisposedException e) { + fail(e.getMessage()); + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } catch (StateValueTypeException e) { + fail(e.getMessage()); + } + assertTrue(true); + } + + /** + * Test a full query to the state system when the end time + * + * Make sure the state system has data. + * + * Hint: the value read should always be more or less(t / 1000) + * + */ + @Test + public void testQueryValuesOnClose() { + assertNotNull(ssq); + try { + int quark; + + List intervals = ssq.queryFullState(END_TIME); + + int baseQuark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); + assertEquals(END_TIME / INTERVAL, intervals.get(baseQuark).getStateValue().unboxLong()); + + int maxMipmapQuark = ssq.getQuarkRelative(baseQuark, AbstractTmfMipmapStateProvider.MAX_STRING); + assertEquals("max nblevels", NB_LEVELS, intervals.get(maxMipmapQuark).getStateValue().unboxInt()); + quark = ssq.getQuarkRelative(maxMipmapQuark, String.valueOf(1)); + assertEquals("max value @ level 1", END_TIME / INTERVAL, intervals.get(quark).getStateValue().unboxLong()); + quark = ssq.getQuarkRelative(maxMipmapQuark, String.valueOf(2)); + assertEquals("max value @ level 2", END_TIME / INTERVAL, intervals.get(quark).getStateValue().unboxLong()); + quark = ssq.getQuarkRelative(maxMipmapQuark, String.valueOf(3)); + assertEquals("max value @ level 3", END_TIME / INTERVAL, intervals.get(quark).getStateValue().unboxLong()); + quark = ssq.getQuarkRelative(maxMipmapQuark, String.valueOf(4)); + assertEquals("max value @ level 4", END_TIME / INTERVAL, intervals.get(quark).getStateValue().unboxLong()); + + int minMipmapQuark = ssq.getQuarkRelative(baseQuark, AbstractTmfMipmapStateProvider.MIN_STRING); + assertEquals("min nblevels", NB_LEVELS, intervals.get(minMipmapQuark).getStateValue().unboxInt()); + quark = ssq.getQuarkRelative(minMipmapQuark, String.valueOf(1)); + assertEquals("min value @ level 1", END_TIME / INTERVAL - (END_TIME - START_TIME) / INTERVAL % (long) Math.pow(RESOLUTION, 1), intervals.get(quark).getStateValue().unboxLong()); + quark = ssq.getQuarkRelative(minMipmapQuark, String.valueOf(2)); + assertEquals("min value @ level 2", END_TIME / INTERVAL - (END_TIME - START_TIME) / INTERVAL % (long) Math.pow(RESOLUTION, 2), intervals.get(quark).getStateValue().unboxLong()); + quark = ssq.getQuarkRelative(minMipmapQuark, String.valueOf(3)); + assertEquals("min value @ level 3", END_TIME / INTERVAL - (END_TIME - START_TIME) / INTERVAL % (long) Math.pow(RESOLUTION, 3), intervals.get(quark).getStateValue().unboxLong()); + quark = ssq.getQuarkRelative(minMipmapQuark, String.valueOf(4)); + assertEquals("min value @ level 4", END_TIME / INTERVAL - (END_TIME - START_TIME) / INTERVAL % (long) Math.pow(RESOLUTION, 4), intervals.get(quark).getStateValue().unboxLong()); + + int avgMipmapQuark = ssq.getQuarkRelative(baseQuark, AbstractTmfMipmapStateProvider.AVG_STRING); + assertEquals("avg nblevels", NB_LEVELS, intervals.get(avgMipmapQuark).getStateValue().unboxInt()); + quark = ssq.getQuarkRelative(avgMipmapQuark, String.valueOf(1)); + assertEquals("avg value @ level 1", (long) (END_TIME / INTERVAL - (double) ((END_TIME - START_TIME) / INTERVAL % (long) Math.pow(RESOLUTION, 1)) / 2), intervals.get(quark).getStateValue().unboxDouble(), DELTA); + quark = ssq.getQuarkRelative(avgMipmapQuark, String.valueOf(2)); + assertEquals("avg value @ level 2", (long) (END_TIME / INTERVAL - (double) ((END_TIME - START_TIME) / INTERVAL % (long) Math.pow(RESOLUTION, 2)) / 2), intervals.get(quark).getStateValue().unboxDouble(), DELTA); + quark = ssq.getQuarkRelative(avgMipmapQuark, String.valueOf(3)); + assertEquals("avg value @ level 3", (long) (END_TIME / INTERVAL - (double) ((END_TIME - START_TIME) / INTERVAL % (long) Math.pow(RESOLUTION, 3)) / 2), intervals.get(quark).getStateValue().unboxDouble(), DELTA); + quark = ssq.getQuarkRelative(avgMipmapQuark, String.valueOf(4)); + assertEquals("avg value @ level 4", (long) (END_TIME / INTERVAL - (double) ((END_TIME - START_TIME) / INTERVAL % (long) Math.pow(RESOLUTION, 4)) / 2), intervals.get(quark).getStateValue().unboxDouble(), DELTA); + + } catch (TimeRangeException e) { + fail(e.getMessage()); + } catch (StateSystemDisposedException e) { + fail(e.getMessage()); + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } catch (StateValueTypeException e) { + fail(e.getMessage()); + } + assertTrue(true); + } + + /** + * Test a query range to the state system to get the maximum value in the + * range + * + * Make sure the state system has data. + * + * + */ + @Test + public void testQueryMipmapRangeMax() { + assertNotNull(ssq); + try { + long max; + int quark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); + + max = TmfStateSystemOperations.queryRangeMax(ssq, 0, START_TIME, quark).unboxLong(); + assertEquals(START_TIME / INTERVAL, max); + + max = TmfStateSystemOperations.queryRangeMax(ssq, START_TIME, START_TIME, quark).unboxLong(); + assertEquals(START_TIME / INTERVAL, max); + + max = TmfStateSystemOperations.queryRangeMax(ssq, START_TIME, END_TIME / 2, quark).unboxLong(); + assertEquals((END_TIME / 2 / INTERVAL), max); + + max = TmfStateSystemOperations.queryRangeMax(ssq, 0, END_TIME, quark).unboxLong(); + assertEquals(END_TIME / INTERVAL, max); + + max = TmfStateSystemOperations.queryRangeMax(ssq, END_TIME / 2, END_TIME, quark).unboxLong(); + assertEquals(END_TIME / INTERVAL, max); + + max = TmfStateSystemOperations.queryRangeMax(ssq, START_TIME - INTERVAL / 2, END_TIME / 2 + INTERVAL / 2, quark).unboxLong(); + assertEquals(END_TIME / 2 / INTERVAL, max); + + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } catch (StateValueTypeException e) { + fail(e.getMessage()); + } catch (TimeRangeException e) { + fail(e.getMessage()); + } + } + + /** + * Test a query range to the state system to get the minimum value in the + * range + * + * Make sure the state system has data. + * + * + */ + @Test + public void testQueryMipmapRangeMin() { + assertNotNull(ssq); + try { + long min; + int quark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); + + min = TmfStateSystemOperations.queryRangeMin(ssq, 0, START_TIME, quark).unboxLong(); + assertEquals(START_TIME / INTERVAL, min); + + min = TmfStateSystemOperations.queryRangeMin(ssq, START_TIME, START_TIME, quark).unboxLong(); + assertEquals(START_TIME / INTERVAL, min); + + min = TmfStateSystemOperations.queryRangeMin(ssq, START_TIME, END_TIME / 2, quark).unboxLong(); + assertEquals((START_TIME / INTERVAL), min); + + min = TmfStateSystemOperations.queryRangeMin(ssq, 0, END_TIME, quark).unboxLong(); + assertEquals(START_TIME / INTERVAL, min); + + min = TmfStateSystemOperations.queryRangeMin(ssq, END_TIME / 2, END_TIME, quark).unboxLong(); + assertEquals(END_TIME / 2 / INTERVAL, min); + + min = TmfStateSystemOperations.queryRangeMin(ssq, START_TIME - INTERVAL / 2, END_TIME / 2 + INTERVAL / 2, quark).unboxLong(); + assertEquals(START_TIME / INTERVAL, min); + + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } catch (StateValueTypeException e) { + fail(e.getMessage()); + } catch (TimeRangeException e) { + fail(e.getMessage()); + } + } + + /** + * Test a query range to the state system to get the average value in the + * range + * + * Make sure the state system has data. + * + */ + @Test + public void testQueryMipmapRangeAvg() { + assertNotNull(ssq); + try { + double avg; + int quark = ssq.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); + + avg = TmfStateSystemOperations.queryRangeAverage(ssq, 0, START_TIME, quark); + assertEquals((double) (START_TIME - INTERVAL) / INTERVAL, avg, DELTA); + + avg = TmfStateSystemOperations.queryRangeAverage(ssq, START_TIME, START_TIME, quark); + assertEquals((double) START_TIME / INTERVAL, avg, DELTA); + + avg = TmfStateSystemOperations.queryRangeAverage(ssq, START_TIME, END_TIME / 2, quark); + assertEquals((double) (START_TIME + (END_TIME / 2 - INTERVAL)) / 2 / INTERVAL, avg, DELTA); + + avg = TmfStateSystemOperations.queryRangeAverage(ssq, 0, END_TIME, quark); + assertEquals((double) (END_TIME - INTERVAL) / 2 / INTERVAL, avg, DELTA); + + avg = TmfStateSystemOperations.queryRangeAverage(ssq, END_TIME / 2, END_TIME, quark); + assertEquals((double) (END_TIME / 2 + (END_TIME - INTERVAL)) / 2 / INTERVAL, avg, DELTA); + + avg = TmfStateSystemOperations.queryRangeAverage(ssq, START_TIME - INTERVAL / 2, END_TIME / 2 + INTERVAL / 2, quark); + assertEquals((double) (START_TIME + (END_TIME / 2 - INTERVAL)) / 2 / INTERVAL, avg, DELTA); + + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } catch (TimeRangeException e) { + fail(e.getMessage()); + } catch (StateValueTypeException e) { + fail(e.getMessage()); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderWeightedTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderWeightedTest.java new file mode 100644 index 0000000000..9f0d819809 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/statesystem/mipmap/TmfMipmapStateProviderWeightedTest.java @@ -0,0 +1,311 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Updates to mipmap feature + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.statesystem.mipmap; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; +import org.eclipse.linuxtools.statesystem.core.StateSystemFactory; +import org.eclipse.linuxtools.statesystem.core.backend.IStateHistoryBackend; +import org.eclipse.linuxtools.statesystem.core.backend.InMemoryBackend; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type; +import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; +import org.eclipse.tracecompass.internal.tmf.core.statesystem.mipmap.TmfStateSystemOperations; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * @author Patrick Tasse + * + */ +public class TmfMipmapStateProviderWeightedTest { + + @NonNull private static final String SSID = "mipmap-test"; + private static final String TEST_ATTRIBUTE_NAME = TmfMipmapStateProviderStub.TEST_ATTRIBUTE_NAME; + private static final long END_TIME = 250000L; + private static final long INTERVAL = 1000L; + private static final int RESOLUTION = 2; + private static final double DELTA = 0.0001; + private static ITmfStateSystemBuilder ssqi; + private static ITmfStateSystemBuilder ssqd; + + /** + * Startup code, build a state system with uneven state durations + */ + @BeforeClass + public static void init() { + /* setup for INTEGER test */ + TmfMipmapStateProviderStub mmpi = new TmfMipmapStateProviderStub(RESOLUTION, Type.INTEGER); + IStateHistoryBackend bei = new InMemoryBackend(0); + ssqi = StateSystemFactory.newStateSystem(SSID, bei); + mmpi.assignTargetStateSystem(ssqi); + /* setup for DOUBLE test */ + TmfMipmapStateProviderStub mmpd = new TmfMipmapStateProviderStub(RESOLUTION, Type.DOUBLE); + IStateHistoryBackend bed = new InMemoryBackend(0); + ssqd = StateSystemFactory.newStateSystem(SSID, bed); + mmpd.assignTargetStateSystem(ssqd); + /* + * Every 10,000 ns chunk contains the following states: + * + * | null | 10 | null | 20 | null | 30 | null | + * 0 1000 2000 3000 4000 5000 6000 7000 8000 9000 10,000 + * + * The weighted average for a chunk is (1 x 10 + 2 x 20 + 3 x 30) / 10 = 14. + */ + for (int i = 0; i < END_TIME / INTERVAL / 10; i++) { + long time = i * 10 * INTERVAL; + /* update for INTEGER test */ + mmpi.processEvent(mmpi.createEvent(time, null)); + mmpi.processEvent(mmpi.createEvent(time + 1000, 10L)); + mmpi.processEvent(mmpi.createEvent(time + 2000, null)); + mmpi.processEvent(mmpi.createEvent(time + 3000, 20L)); + mmpi.processEvent(mmpi.createEvent(time + 5000, null)); + mmpi.processEvent(mmpi.createEvent(time + 6000, 30L)); + mmpi.processEvent(mmpi.createEvent(time + 9000, null)); + /* update for DOUBLE test */ + mmpd.processEvent(mmpd.createEvent(time, null)); + mmpd.processEvent(mmpd.createEvent(time + 1000, 10L)); + mmpd.processEvent(mmpd.createEvent(time + 2000, null)); + mmpd.processEvent(mmpd.createEvent(time + 3000, 20L)); + mmpd.processEvent(mmpd.createEvent(time + 5000, null)); + mmpd.processEvent(mmpd.createEvent(time + 6000, 30L)); + mmpd.processEvent(mmpd.createEvent(time + 9000, null)); + } + /* cleanup for INTEGER test */ + mmpi.processEvent(mmpi.createEvent(END_TIME, 0L)); + mmpi.dispose(); + ssqi.waitUntilBuilt(); + /* cleanup for DOUBLE test */ + mmpd.processEvent(mmpd.createEvent(END_TIME, 0L)); + mmpd.dispose(); + ssqd.waitUntilBuilt(); + } + + /** + * Test a query range to the state system to get the maximum value in the + * range. The test values are INTEGER. + */ + @Test + public void testQueryMipmapRangeMaxInteger() { + assertNotNull(ssqi); + try { + int quark = ssqi.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); + assertEquals(TmfStateValue.nullValue(), TmfStateSystemOperations.queryRangeMax(ssqi, 0, 0, quark)); + assertEquals(10, TmfStateSystemOperations.queryRangeMax(ssqi, 500, 1500, quark).unboxInt()); + assertEquals(20, TmfStateSystemOperations.queryRangeMax(ssqi, 1500, 5000, quark).unboxInt()); + assertEquals(30, TmfStateSystemOperations.queryRangeMax(ssqi, 5000, 10000, quark).unboxInt()); + assertEquals(30, TmfStateSystemOperations.queryRangeMax(ssqi, 0, 10000, quark).unboxInt()); + assertEquals(TmfStateValue.nullValue(), TmfStateSystemOperations.queryRangeMax(ssqi, 120000, 120000, quark)); + assertEquals(10, TmfStateSystemOperations.queryRangeMax(ssqi, 120500, 121500, quark).unboxInt()); + assertEquals(20, TmfStateSystemOperations.queryRangeMax(ssqi, 121500, 125000, quark).unboxInt()); + assertEquals(30, TmfStateSystemOperations.queryRangeMax(ssqi, 125000, 130000, quark).unboxInt()); + assertEquals(30, TmfStateSystemOperations.queryRangeMax(ssqi, 120000, 130000, quark).unboxInt()); + assertEquals(30, TmfStateSystemOperations.queryRangeMax(ssqi, 100000, 150000, quark).unboxInt()); + assertEquals(30, TmfStateSystemOperations.queryRangeMax(ssqi, 240000, 250000, quark).unboxInt()); + assertEquals(30, TmfStateSystemOperations.queryRangeMax(ssqi, 0, 250000, quark).unboxInt()); + assertEquals(00, TmfStateSystemOperations.queryRangeMax(ssqi, 250000, 250000, quark).unboxInt()); + + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } catch (StateValueTypeException e) { + fail(e.getMessage()); + } catch (TimeRangeException e) { + fail(e.getMessage()); + } + } + + /** + * Test a query range to the state system to get the minimum value in the + * range. The test values are INTEGER. + */ + @Test + public void testQueryMipmapRangeMinInteger() { + assertNotNull(ssqi); + try { + int quark = ssqi.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); + assertEquals(TmfStateValue.nullValue(), TmfStateSystemOperations.queryRangeMin(ssqi, 0, 0, quark)); + assertEquals(10, TmfStateSystemOperations.queryRangeMin(ssqi, 500, 1500, quark).unboxInt()); + assertEquals(10, TmfStateSystemOperations.queryRangeMin(ssqi, 1500, 5000, quark).unboxInt()); + assertEquals(30, TmfStateSystemOperations.queryRangeMin(ssqi, 5000, 10000, quark).unboxInt()); + assertEquals(10, TmfStateSystemOperations.queryRangeMin(ssqi, 0, 10000, quark).unboxInt()); + assertEquals(TmfStateValue.nullValue(), TmfStateSystemOperations.queryRangeMin(ssqi, 120000, 120000, quark)); + assertEquals(10, TmfStateSystemOperations.queryRangeMin(ssqi, 120500, 121500, quark).unboxInt()); + assertEquals(10, TmfStateSystemOperations.queryRangeMin(ssqi, 121500, 125000, quark).unboxInt()); + assertEquals(30, TmfStateSystemOperations.queryRangeMin(ssqi, 125000, 130000, quark).unboxInt()); + assertEquals(10, TmfStateSystemOperations.queryRangeMin(ssqi, 120000, 130000, quark).unboxInt()); + assertEquals(10, TmfStateSystemOperations.queryRangeMin(ssqi, 100000, 150000, quark).unboxInt()); + assertEquals(00, TmfStateSystemOperations.queryRangeMin(ssqi, 240000, 250000, quark).unboxInt()); + assertEquals(00, TmfStateSystemOperations.queryRangeMin(ssqi, 0, 250000, quark).unboxInt()); + assertEquals(00, TmfStateSystemOperations.queryRangeMin(ssqi, 250000, 250000, quark).unboxInt()); + + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } catch (StateValueTypeException e) { + fail(e.getMessage()); + } catch (TimeRangeException e) { + fail(e.getMessage()); + } + } + + /** + * Test a query range to the state system to get the average value in the + * range. The test values are INTEGER. + */ + @Test + public void testQueryMipmapRangeAvgInteger() { + assertNotNull(ssqi); + try { + int quark = ssqi.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); + assertEquals(0.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 0, 0, quark), DELTA); + assertEquals(5.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 500, 1500, quark), DELTA); + assertEquals(90.0 / 7, TmfStateSystemOperations.queryRangeAverage(ssqi, 1500, 5000, quark), DELTA); + assertEquals(90.0 / 5, TmfStateSystemOperations.queryRangeAverage(ssqi, 5000, 10000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 0, 10000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 0, 20000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 500, 20500, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 1000, 21000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 2000, 22000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 3000, 23000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 4000, 24000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 5000, 25000, quark), DELTA); + assertEquals(0.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 120000, 120000, quark), DELTA); + assertEquals(5.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 120500, 121500, quark), DELTA); + assertEquals(90.0 / 7, TmfStateSystemOperations.queryRangeAverage(ssqi, 121500, 125000, quark), DELTA); + assertEquals(90.0 / 5, TmfStateSystemOperations.queryRangeAverage(ssqi, 125000, 130000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 120000, 130000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 100000, 150000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 240000, 250000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 0, 250000, quark), DELTA); + assertEquals(0.0, TmfStateSystemOperations.queryRangeAverage(ssqi, 250000, 250000, quark), DELTA); + + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } catch (TimeRangeException e) { + fail(e.getMessage()); + } catch (StateValueTypeException e) { + fail(e.getMessage()); + } + } + + /** + * Test a query range to the state system to get the maximum value in the + * range. The test values are DOUBLE. + */ + @Test + public void testQueryMipmapRangeMaxDouble() { + assertNotNull(ssqd); + try { + int quark = ssqd.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); + assertEquals(TmfStateValue.nullValue(), TmfStateSystemOperations.queryRangeMax(ssqd, 0, 0, quark)); + assertEquals(10.0, TmfStateSystemOperations.queryRangeMax(ssqd, 500, 1500, quark).unboxDouble(), DELTA); + assertEquals(20.0, TmfStateSystemOperations.queryRangeMax(ssqd, 1500, 5000, quark).unboxDouble(), DELTA); + assertEquals(30.0, TmfStateSystemOperations.queryRangeMax(ssqd, 5000, 10000, quark).unboxDouble(), DELTA); + assertEquals(30.0, TmfStateSystemOperations.queryRangeMax(ssqd, 0, 10000, quark).unboxDouble(), DELTA); + assertEquals(TmfStateValue.nullValue(), TmfStateSystemOperations.queryRangeMax(ssqd, 120000, 120000, quark)); + assertEquals(10.0, TmfStateSystemOperations.queryRangeMax(ssqd, 120500, 121500, quark).unboxDouble(), DELTA); + assertEquals(20.0, TmfStateSystemOperations.queryRangeMax(ssqd, 121500, 125000, quark).unboxDouble(), DELTA); + assertEquals(30.0, TmfStateSystemOperations.queryRangeMax(ssqd, 125000, 130000, quark).unboxDouble(), DELTA); + assertEquals(30.0, TmfStateSystemOperations.queryRangeMax(ssqd, 120000, 130000, quark).unboxDouble(), DELTA); + assertEquals(30.0, TmfStateSystemOperations.queryRangeMax(ssqd, 100000, 150000, quark).unboxDouble(), DELTA); + assertEquals(30.0, TmfStateSystemOperations.queryRangeMax(ssqd, 240000, 250000, quark).unboxDouble(), DELTA); + assertEquals(30.0, TmfStateSystemOperations.queryRangeMax(ssqd, 0, 250000, quark).unboxDouble(), DELTA); + assertEquals(00.0, TmfStateSystemOperations.queryRangeMax(ssqd, 250000, 250000, quark).unboxDouble(), DELTA); + + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } catch (StateValueTypeException e) { + fail(e.getMessage()); + } catch (TimeRangeException e) { + fail(e.getMessage()); + } + } + + /** + * Test a query range to the state system to get the minimum value in the + * range. The test values are DOUBLE. + */ + @Test + public void testQueryMipmapRangeMinDouble() { + assertNotNull(ssqd); + try { + int quark = ssqd.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); + assertEquals(TmfStateValue.nullValue(), TmfStateSystemOperations.queryRangeMin(ssqd, 0, 0, quark)); + assertEquals(10.0, TmfStateSystemOperations.queryRangeMin(ssqd, 500, 1500, quark).unboxDouble(), DELTA); + assertEquals(10.0, TmfStateSystemOperations.queryRangeMin(ssqd, 1500, 5000, quark).unboxDouble(), DELTA); + assertEquals(30.0, TmfStateSystemOperations.queryRangeMin(ssqd, 5000, 10000, quark).unboxDouble(), DELTA); + assertEquals(10.0, TmfStateSystemOperations.queryRangeMin(ssqd, 0, 10000, quark).unboxDouble(), DELTA); + assertEquals(TmfStateValue.nullValue(), TmfStateSystemOperations.queryRangeMin(ssqd, 120000, 120000, quark)); + assertEquals(10.0, TmfStateSystemOperations.queryRangeMin(ssqd, 120500, 121500, quark).unboxDouble(), DELTA); + assertEquals(10.0, TmfStateSystemOperations.queryRangeMin(ssqd, 121500, 125000, quark).unboxDouble(), DELTA); + assertEquals(30.0, TmfStateSystemOperations.queryRangeMin(ssqd, 125000, 130000, quark).unboxDouble(), DELTA); + assertEquals(10.0, TmfStateSystemOperations.queryRangeMin(ssqd, 120000, 130000, quark).unboxDouble(), DELTA); + assertEquals(10.0, TmfStateSystemOperations.queryRangeMin(ssqd, 100000, 150000, quark).unboxDouble(), DELTA); + assertEquals(00.0, TmfStateSystemOperations.queryRangeMin(ssqd, 240000, 250000, quark).unboxDouble(), DELTA); + assertEquals(00.0, TmfStateSystemOperations.queryRangeMin(ssqd, 0, 250000, quark).unboxDouble(), DELTA); + assertEquals(00.0, TmfStateSystemOperations.queryRangeMin(ssqd, 250000, 250000, quark).unboxDouble(), DELTA); + + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } catch (StateValueTypeException e) { + fail(e.getMessage()); + } catch (TimeRangeException e) { + fail(e.getMessage()); + } + } + + /** + * Test a query range to the state system to get the average value in the + * range. The test values are DOUBLE. + */ + @Test + public void testQueryMipmapRangeAvgDouble() { + assertNotNull(ssqd); + try { + int quark = ssqd.getQuarkAbsolute(TEST_ATTRIBUTE_NAME); + assertEquals(0.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 0, 0, quark), DELTA); + assertEquals(5.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 500, 1500, quark), DELTA); + assertEquals(90.0 / 7, TmfStateSystemOperations.queryRangeAverage(ssqd, 1500, 5000, quark), DELTA); + assertEquals(90.0 / 5, TmfStateSystemOperations.queryRangeAverage(ssqd, 5000, 10000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 0, 10000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 0, 20000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 500, 20500, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 1000, 21000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 2000, 22000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 3000, 23000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 4000, 24000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 5000, 25000, quark), DELTA); + assertEquals(0.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 120000, 120000, quark), DELTA); + assertEquals(5.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 120500, 121500, quark), DELTA); + assertEquals(90.0 / 7, TmfStateSystemOperations.queryRangeAverage(ssqd, 121500, 125000, quark), DELTA); + assertEquals(90.0 / 5, TmfStateSystemOperations.queryRangeAverage(ssqd, 125000, 130000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 120000, 130000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 100000, 150000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 240000, 250000, quark), DELTA); + assertEquals(14.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 0, 250000, quark), DELTA); + assertEquals(0.0, TmfStateSystemOperations.queryRangeAverage(ssqd, 250000, 250000, quark), DELTA); + + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } catch (TimeRangeException e) { + fail(e.getMessage()); + } catch (StateValueTypeException e) { + fail(e.getMessage()); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/synchronization/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/synchronization/AllTests.java new file mode 100644 index 0000000000..a5577ed738 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/synchronization/AllTests.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.synchronization; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for org.eclipse.linuxtools.tmf.core.synchronization + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ TsTransformTest.class, + SyncTest.class, + TsTransformFactoryTest.class }) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/synchronization/SyncTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/synchronization/SyncTest.java new file mode 100644 index 0000000000..5b77a911aa --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/synchronization/SyncTest.java @@ -0,0 +1,247 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.synchronization; + +import static org.junit.Assert.assertEquals; + +import java.util.Collection; +import java.util.LinkedList; + +import org.eclipse.tracecompass.tmf.core.event.matching.TmfEventDependency; +import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform; +import org.eclipse.tracecompass.tmf.core.synchronization.SynchronizationAlgorithm; +import org.eclipse.tracecompass.tmf.core.synchronization.SynchronizationAlgorithmFactory; +import org.eclipse.tracecompass.tmf.core.synchronization.TimestampTransformFactory; +import org.eclipse.tracecompass.tmf.core.synchronization.SynchronizationAlgorithm.SyncQuality; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.tests.stubs.event.TmfSyncEventStub; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests for {@link SynchronizationAlgorithm} and its descendants + * + * @author Geneviève Bastien + */ +@SuppressWarnings("nls") +public class SyncTest { + + private TmfTraceStub t1, t2; + private Collection fTraces; + + /** + * Initializing the traces + */ + @Before + public void init() { + t1 = new TmfTraceStub(); + t1.init("t1"); + t2 = new TmfTraceStub(); + t2.init("t2"); + + Collection traces = new LinkedList<>(); + traces.add(t1); + traces.add(t2); + fTraces = traces; + } + + /** + * Testing fully incremental algorithm with communication between the two + * traces + */ + @Test + public void testFullyIncremental() { + + SynchronizationAlgorithm syncAlgo = SynchronizationAlgorithmFactory.getFullyIncrementalAlgorithm(); + + syncAlgo.init(fTraces); + + assertEquals(SyncQuality.ABSENT, syncAlgo.getSynchronizationQuality(t1, t2)); + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(1)), + new TmfSyncEventStub(t1, new TmfTimestamp(1)) + )); + assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1 beta 0 ]]", syncAlgo.toString()); + assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); + + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(1)), + new TmfSyncEventStub(t2, new TmfTimestamp(3)) + )); + assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1 beta 0 ]]", syncAlgo.toString()); + assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); + + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(2)), + new TmfSyncEventStub(t1, new TmfTimestamp(3)) + )); + assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1 beta 0.5 ]]", syncAlgo.toString()); + assertEquals(SyncQuality.APPROXIMATE, syncAlgo.getSynchronizationQuality(t1, t2)); + + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(3)), + new TmfSyncEventStub(t2, new TmfTimestamp(5)) + )); + assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 0.75 beta 1.25 ]]", syncAlgo.toString()); + assertEquals(SyncQuality.ACCURATE, syncAlgo.getSynchronizationQuality(t1, t2)); + + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(4)), + new TmfSyncEventStub(t2, new TmfTimestamp(8)) + )); + assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 0.75 beta 1.25 ]]", syncAlgo.toString()); + assertEquals(SyncQuality.ACCURATE, syncAlgo.getSynchronizationQuality(t1, t2)); + + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(4)), + new TmfSyncEventStub(t1, new TmfTimestamp(5)) + )); + assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1.125 beta 0.875 ]]", syncAlgo.toString()); + assertEquals(SyncQuality.ACCURATE, syncAlgo.getSynchronizationQuality(t1, t2)); + + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(4)), + new TmfSyncEventStub(t1, new TmfTimestamp(6)) + )); + assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1.125 beta 0.875 ]]", syncAlgo.toString()); + assertEquals(SyncQuality.ACCURATE, syncAlgo.getSynchronizationQuality(t1, t2)); + + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(6)), + new TmfSyncEventStub(t2, new TmfTimestamp(7)) + )); + assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 0.725 beta 1.275 ]]", syncAlgo.toString()); + assertEquals(SyncQuality.ACCURATE, syncAlgo.getSynchronizationQuality(t1, t2)); + + ITmfTimestampTransform tt2 = syncAlgo.getTimestampTransform(t2); + ITmfTimestampTransform tt1 = syncAlgo.getTimestampTransform(t1); + + assertEquals(syncAlgo.getTimestampTransform(t1.getHostId()), tt1); + assertEquals(TimestampTransformFactory.getDefaultTransform(), tt1); + assertEquals(syncAlgo.getTimestampTransform(t2.getHostId()), tt2); + + /* Make the two hulls intersect */ + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(7)), + new TmfSyncEventStub(t2, new TmfTimestamp(4)) + )); + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(7)), + new TmfSyncEventStub(t1, new TmfTimestamp(3)) + )); + assertEquals(SyncQuality.FAIL, syncAlgo.getSynchronizationQuality(t1, t2)); + } + + /** + * Testing the fully incremental synchronization algorithm when + * communication goes in only one direction + */ + @Test + public void testOneHull() { + + SynchronizationAlgorithm syncAlgo = SynchronizationAlgorithmFactory.getFullyIncrementalAlgorithm(); + + syncAlgo.init(fTraces); + + assertEquals(SyncQuality.ABSENT, syncAlgo.getSynchronizationQuality(t1, t2)); + + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(1)), + new TmfSyncEventStub(t2, new TmfTimestamp(3))) + ); + assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); + + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(2)), + new TmfSyncEventStub(t2, new TmfTimestamp(5))) + ); + + assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); + + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(3)), + new TmfSyncEventStub(t2, new TmfTimestamp(5))) + ); + assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); + + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(4)), + new TmfSyncEventStub(t2, new TmfTimestamp(7))) + ); + assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); + assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1 beta 0 ]]", syncAlgo.toString()); + + } + + /** + * Testing the fully incremental synchronization algorithm when all + * communication from trace1 to trace2 happens before all communication from + * trace2 to trace1 + */ + @Test + public void testDisjoint() { + + SynchronizationAlgorithm syncAlgo = SynchronizationAlgorithmFactory.getFullyIncrementalAlgorithm(); + + syncAlgo.init(fTraces); + + assertEquals(SyncQuality.ABSENT, syncAlgo.getSynchronizationQuality(t1, t2)); + + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(1)), + new TmfSyncEventStub(t2, new TmfTimestamp(3))) + ); + assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); + + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(2)), + new TmfSyncEventStub(t2, new TmfTimestamp(5))) + ); + + assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); + + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(3)), + new TmfSyncEventStub(t2, new TmfTimestamp(5))) + ); + assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); + + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(4)), + new TmfSyncEventStub(t2, new TmfTimestamp(7))) + ); + assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2)); + assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1 beta 0 ]]", syncAlgo.toString()); + + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(7)), + new TmfSyncEventStub(t1, new TmfTimestamp(6))) + ); + assertEquals(SyncQuality.APPROXIMATE, syncAlgo.getSynchronizationQuality(t1, t2)); + + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(8)), + new TmfSyncEventStub(t1, new TmfTimestamp(6))) + ); + assertEquals(SyncQuality.APPROXIMATE, syncAlgo.getSynchronizationQuality(t1, t2)); + + syncAlgo.addMatch( + new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(10)), + new TmfSyncEventStub(t1, new TmfTimestamp(8))) + ); + assertEquals(SyncQuality.APPROXIMATE, syncAlgo.getSynchronizationQuality(t1, t2)); + assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1 beta 2.5 ]]", syncAlgo.toString()); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/synchronization/TsTransformFactoryTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/synchronization/TsTransformFactoryTest.java new file mode 100644 index 0000000000..183903461e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/synchronization/TsTransformFactoryTest.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.synchronization; + +import static org.junit.Assert.assertEquals; + +import java.math.BigDecimal; + +import org.eclipse.tracecompass.internal.tmf.core.synchronization.TmfConstantTransform; +import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform; +import org.eclipse.tracecompass.tmf.core.synchronization.TimestampTransformFactory; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.junit.Test; + +/** + * Timestamp transform tests + * + * @author Matthew Khouzam + * + */ +public class TsTransformFactoryTest { + private final ITmfTimestamp t0 = new TmfTimestamp(0); + private final ITmfTimestamp t100 = new TmfTimestamp(100); + private final ITmfTimestamp t1e2 = new TmfTimestamp(1, 2); + private final ITmfTimestamp t1e3 = new TmfTimestamp(1, 3); + private final ITmfTimestamp tn0 = new TmfNanoTimestamp(0); + private final ITmfTimestamp tn100 = new TmfNanoTimestamp(100); + private final ITmfTimestamp tn1 = new TmfNanoTimestamp(1); + private final ITmfTimestampTransform identity1 = TimestampTransformFactory.createLinear(1.0, new TmfNanoTimestamp(0)); + private final ITmfTimestampTransform offset1 = TimestampTransformFactory.createWithOffset(100); + private final ITmfTimestampTransform offset2 = TimestampTransformFactory.createLinear(BigDecimal.ONE, new BigDecimal(100)); + private final ITmfTimestampTransform offset3 = TimestampTransformFactory.createLinear(1.0, 100); + private final ITmfTimestampTransform offset4 = TimestampTransformFactory.createLinear(1.0, new TmfNanoTimestamp(100)); + + /** + * Test with identity + */ + @Test + public void transformIdenity() { + final ITmfTimestampTransform identity = TimestampTransformFactory.createWithOffset(0); + final ITmfTimestampTransform innefficientIdentity = new TmfConstantTransform(); + final ITmfTimestampTransform compositeInnefficientIdentity = identity.composeWith(innefficientIdentity); + final ITmfTimestampTransform compositeInnefficientIdentity2 = innefficientIdentity.composeWith(innefficientIdentity); + final ITmfTimestampTransform compositeInnefficientIdentity3 = innefficientIdentity.composeWith(identity); + assertEquals(t0, identity.transform(t0)); + assertEquals(tn0, identity.transform(tn0)); + assertEquals(t100, identity.transform(t100)); + assertEquals(t1e2, identity.transform(t100)); + assertEquals(t1e2, identity.transform(t1e2)); + assertEquals(t1e3, identity.transform(t1e3)); + assertEquals(tn100, identity.transform(tn100)); + assertEquals(t0, innefficientIdentity.transform(t0)); // bad practice + assertEquals(t0, compositeInnefficientIdentity.transform(t0)); // bad + // practice + assertEquals(t0, compositeInnefficientIdentity2.transform(t0)); // bad + // practice + assertEquals(t0, compositeInnefficientIdentity3.transform(t0)); // bad + // practice + } + + /** + * Test with an offset of 100 + */ + @Test + public void transformOffset() { + final ITmfTimestampTransform offset = offset1; + final ITmfTimestampTransform compositeTransform = offset.composeWith(TimestampTransformFactory.createWithOffset(new TmfNanoTimestamp(-100))); + assertEquals(tn100, offset.transform(t0)); + assertEquals(tn100, offset.transform(tn0)); + assertEquals(tn0, compositeTransform.transform(tn0)); + assertEquals(t0, compositeTransform.transform(t0)); + assertEquals(200, offset1.transform(100)); + assertEquals(200, offset2.transform(100)); + assertEquals(200, offset3.transform(100)); + assertEquals(200, offset4.transform(100)); + } + + /** + * Test with a slope + */ + @Test + public void transformSlope() { + final ITmfTimestampTransform slope = TimestampTransformFactory.createLinear(10, 0); + final ITmfTimestampTransform slope1 = TimestampTransformFactory.createLinear(10.0, new TmfNanoTimestamp(0)); + assertEquals(t1e3, slope.transform(t1e2)); + assertEquals(tn100, slope.transform(new TmfNanoTimestamp(10))); + assertEquals(tn100, slope.transform(slope.transform(tn1))); + assertEquals(tn100, slope.composeWith(slope).transform(tn1)); + assertEquals(tn100, slope1.transform(new TmfNanoTimestamp(10))); + } + + /** + * Test toStrings + */ + @Test + public void testToString() { + final String expectedLinear = "TmfTimestampLinear [ slope = 314.0, offset = 0.0 ]"; + final String expectedLinearBigDec = "TmfTimestampLinear [ slope = 314, offset = 0 ]"; + final String expectedOffset = "TmfConstantTransform [ offset = 314 ]"; + final String expectedIdentity = "TmfTimestampTransform [ IDENTITY ]"; + final String expectedOffset100 = "TmfConstantTransform [ offset = 100 ]"; + assertEquals(expectedLinear, TimestampTransformFactory.createLinear(314, 0).toString()); + assertEquals(expectedLinearBigDec, TimestampTransformFactory.createLinear(BigDecimal.valueOf(314), BigDecimal.ZERO).toString()); + assertEquals(expectedOffset, TimestampTransformFactory.createLinear(1, 314).toString()); + assertEquals(expectedOffset, TimestampTransformFactory.createWithOffset(314).toString()); + assertEquals(expectedOffset, TimestampTransformFactory.createWithOffset(14).composeWith(TimestampTransformFactory.createWithOffset(300)).toString()); + assertEquals(expectedIdentity, TimestampTransformFactory.createWithOffset(314).composeWith(TimestampTransformFactory.createWithOffset(-314)).toString()); + assertEquals(expectedIdentity, TimestampTransformFactory.createWithOffset(0).toString()); + assertEquals(expectedIdentity, identity1.toString()); + assertEquals(expectedOffset100, offset1.toString()); + assertEquals(expectedOffset100, offset2.toString()); + assertEquals(expectedOffset100, offset3.toString()); + assertEquals(expectedOffset100, offset4.toString()); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/synchronization/TsTransformTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/synchronization/TsTransformTest.java new file mode 100644 index 0000000000..5bb800112d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/synchronization/TsTransformTest.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.synchronization; + +import static org.junit.Assert.*; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.tracecompass.internal.tmf.core.synchronization.TmfTimestampTransform; +import org.eclipse.tracecompass.internal.tmf.core.synchronization.TmfTimestampTransformLinear; +import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.junit.Test; + +/** + * Tests for {@link TmfTimestampTransform} and its descendants + * + * @author Geneviève Bastien + */ +@SuppressWarnings("nls") +public class TsTransformTest { + + private long ts = 1361657893526374091L; + private ITmfTimestamp oTs = new TmfTimestamp(ts); + + /** + * Test the linear transform + */ + @Test + public void testLinearTransform() { + /* Default constructor */ + TmfTimestampTransformLinear ttl = new TmfTimestampTransformLinear(); + assertEquals(1361657893526374091L, ttl.transform(ts)); + assertEquals(1361657893526374091L, ttl.transform(oTs).getValue()); + + /* Just an offset */ + ttl = new TmfTimestampTransformLinear(BigDecimal.valueOf(1.0), BigDecimal.valueOf(3)); + assertEquals(1361657893526374094L, ttl.transform(ts)); + assertEquals(1361657893526374094L, ttl.transform(oTs).getValue()); + + /* Just a slope */ + ttl = new TmfTimestampTransformLinear(BigDecimal.valueOf(2.0), BigDecimal.valueOf(0)); + assertEquals(2723315787052748182L, ttl.transform(ts)); + assertEquals(2723315787052748182L, ttl.transform(oTs).getValue()); + + /* Offset and slope */ + ttl = new TmfTimestampTransformLinear(BigDecimal.valueOf(2.0), BigDecimal.valueOf(3)); + assertEquals(2723315787052748185L, ttl.transform(ts)); + assertEquals(2723315787052748185L, ttl.transform(oTs).getValue()); + + /* Offset and slope */ + ttl = new TmfTimestampTransformLinear(BigDecimal.valueOf(0.5), BigDecimal.valueOf(0)); + assertEquals(680828946763187045L, ttl.transform(ts)); + assertEquals(680828946763187045L, ttl.transform(oTs).getValue()); + } + + /** + * Test for the identity transform + */ + @Test + public void testIdentityTransform() { + ITmfTimestampTransform tt = TmfTimestampTransform.IDENTITY; + assertEquals(ts, tt.transform(ts)); + assertEquals(oTs, tt.transform(oTs)); + } + + /** + * Test hash and equals function + */ + @Test + public void testEquality() { + Map map = new HashMap<>(); + ITmfTimestampTransform ttl = new TmfTimestampTransformLinear(BigDecimal.valueOf(2.0), BigDecimal.valueOf(3)); + ITmfTimestampTransform ttl2 = new TmfTimestampTransformLinear(BigDecimal.valueOf(2.0), BigDecimal.valueOf(3)); + ITmfTimestampTransform ttl3 = new TmfTimestampTransformLinear(BigDecimal.valueOf(3), BigDecimal.valueOf(3)); + assertEquals(ttl, ttl2); + assertFalse(ttl.equals(ttl3)); + assertFalse(ttl2.equals(ttl3)); + + map.put(ttl, "a"); + assertTrue(map.containsKey(ttl2)); + assertEquals("a", map.get(ttl)); + + ITmfTimestampTransform ti = TmfTimestampTransform.IDENTITY; + assertEquals(TmfTimestampTransform.IDENTITY, ti); + assertFalse(TmfTimestampTransform.IDENTITY.equals(ttl)); + + map.put(ti, "b"); + assertTrue(map.containsKey(TmfTimestampTransform.IDENTITY)); + assertEquals("b", map.get(ti)); + + assertFalse(ti.equals(ttl)); + assertFalse(ttl.equals(ti)); + + } + + /** + * Test the transform composition function + */ + @Test + public void testComposition() { + long t = 100; + ITmfTimestampTransform ti = TmfTimestampTransform.IDENTITY; + ITmfTimestampTransform ttl = new TmfTimestampTransformLinear(BigDecimal.valueOf(2.0), BigDecimal.valueOf(3)); + ITmfTimestampTransform ttl2 = new TmfTimestampTransformLinear(BigDecimal.valueOf(1.5), BigDecimal.valueOf(8)); + + ITmfTimestampTransform tc1 = ti.composeWith(ttl); + /* Should be ttl */ + assertEquals(ttl, tc1); + assertEquals(203, tc1.transform(t)); + + tc1 = ttl.composeWith(ti); + /* Should be ttl also */ + assertEquals(ttl, tc1); + assertEquals(203, tc1.transform(t)); + + tc1 = ti.composeWith(ti); + /* Should be identity */ + assertEquals(tc1, TmfTimestampTransform.IDENTITY); + assertEquals(100, tc1.transform(t)); + + tc1 = ttl.composeWith(ttl2); + assertEquals(ttl.transform(ttl2.transform(t)), tc1.transform(t)); + assertEquals(319, tc1.transform(t)); + + tc1 = ttl2.composeWith(ttl); + assertEquals(ttl2.transform(ttl.transform(t)), tc1.transform(t)); + assertEquals(312, tc1.transform(t)); + + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/AllTests.java new file mode 100644 index 0000000000..0036e07ffe --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/AllTests.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Adjusted for new Trace Model + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for org.eclipse.linuxtools.tmf.core.trace + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TmfContextTest.class, + TmfExperimentTest.class, + TmfMultiTraceExperimentTest.class, + TmfTraceTest.class +}) +public class AllTests {} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/TmfContextTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/TmfContextTest.java new file mode 100644 index 0000000000..939552da3d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/TmfContextTest.java @@ -0,0 +1,255 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Adapted for TMF Trace Model 1.0 + * Alexandre Montplaisir - Port to JUnit4 + * Patrick Tasse - Updated for removal of context clone + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.TmfContext; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfTimestampLocation; +import org.junit.Test; + +/** + * Test suite for the TmfContext class. + */ +@SuppressWarnings("javadoc") +public class TmfContextTest { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + private final Long aLong = 12345L; + private final TmfTimestamp aTimestamp = new TmfTimestamp(); + + private final TmfLongLocation fLocation1 = new TmfLongLocation(aLong); + private final TmfTimestampLocation fLocation2 = new TmfTimestampLocation(aTimestamp); + + private final long fRank1 = 1; + private final long fRank2 = 2; + + private final TmfContext fContext1 = new TmfContext(fLocation1, fRank1); + private final TmfContext fContext2 = new TmfContext(fLocation2, fRank2); + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + @Test + public void testTmfContextDefault() { + final TmfContext context = new TmfContext(); + assertEquals("getLocation", null, context.getLocation()); + assertEquals("getRank", ITmfContext.UNKNOWN_RANK, context.getRank()); + } + + @Test + public void testTmfContextNoRank() { + final TmfContext context1 = new TmfContext(fLocation1); + final TmfContext context2 = new TmfContext(fLocation2); + + assertEquals("getLocation", fLocation1, context1.getLocation()); + assertEquals("getLocation", fLocation2, context2.getLocation()); + + assertEquals("getRank", ITmfContext.UNKNOWN_RANK, context1.getRank()); + assertEquals("getRank", ITmfContext.UNKNOWN_RANK, context2.getRank()); + } + + @Test + public void testTmfContext() { + assertEquals("getLocation", fLocation1, fContext1.getLocation()); + assertEquals("getLocation", fLocation2, fContext2.getLocation()); + + assertEquals("getRank", fRank1, fContext1.getRank()); + assertEquals("getRank", fRank2, fContext2.getRank()); + } + + @Test + public void testTmfContextCopy() { + final TmfContext context1 = new TmfContext(fContext1); + final TmfContext context2 = new TmfContext(fContext2); + + assertEquals("getLocation", fLocation1, context1.getLocation()); + assertEquals("getLocation", fLocation2, context2.getLocation()); + + assertEquals("getRank", fRank1, context1.getRank()); + assertEquals("getRank", fRank2, context2.getRank()); + } + + @Test + public void testTmfContextCopy2() { + try { + new TmfContext((TmfContext) null); + fail("Copy constructor: no exception"); + } + catch (final IllegalArgumentException e) { + // pass + } + catch (final Exception e) { + fail("Copy constructor: wrong exception"); + } + } + + // ------------------------------------------------------------------------ + // equals + // ------------------------------------------------------------------------ + + @Test + public void testEqualsReflexivity() { + assertTrue("equals", fContext1.equals(fContext1)); + assertTrue("equals", fContext2.equals(fContext2)); + + assertFalse("equals", fContext1.equals(fContext2)); + assertFalse("equals", fContext2.equals(fContext1)); + } + + @Test + public void testEqualsSymmetry() { + final TmfContext context1 = new TmfContext(fContext1); + final TmfContext context2 = new TmfContext(fContext2); + + assertTrue("equals", context1.equals(fContext1)); + assertTrue("equals", fContext1.equals(context1)); + + assertTrue("equals", context2.equals(fContext2)); + assertTrue("equals", fContext2.equals(context2)); + } + + @Test + public void testEqualsTransivity() { + final TmfContext context1 = new TmfContext(fContext1); + final TmfContext context2 = new TmfContext(context1); + final TmfContext context3 = new TmfContext(context2); + + assertTrue("equals", context1.equals(context2)); + assertTrue("equals", context2.equals(context3)); + assertTrue("equals", context1.equals(context3)); + } + + @Test + public void testEqualsNull() { + assertFalse("equals", fContext1.equals(null)); + assertFalse("equals", fContext2.equals(null)); + } + + private static class MyContext extends TmfContext { + } + + @Test + public void testNonEquals() { + + // Different classes + final MyContext myContext = new MyContext(); + assertFalse("equals", fContext1.equals(myContext)); + assertFalse("equals", myContext.equals(fContext1)); + + // Different locations + TmfContext context1 = new TmfContext(fContext1); + TmfContext context2 = new TmfContext(fContext1); + context1.setLocation(null); + context2.setLocation(null); + + assertFalse("equals", fContext1.equals(context1)); + assertFalse("equals", context1.equals(fContext1)); + assertTrue("equals", context1.equals(context2)); + + // Different ranks + context1 = new TmfContext(fContext1); + context2 = new TmfContext(fContext1); + context1.setRank(fContext1.getRank() + 1); + context2.setRank(fContext1.getRank() + 2); + + assertFalse("equals", fContext1.equals(context1)); + assertFalse("equals", context1.equals(fContext1)); + assertFalse("equals", context1.equals(context2)); + } + + // ------------------------------------------------------------------------ + // hashCode + // ------------------------------------------------------------------------ + + @Test + public void testHashCode() { + final TmfContext context1 = new TmfContext(fContext1); + final TmfContext context2 = new TmfContext(fContext2); + + assertEquals("hashCode", fContext1.hashCode(), context1.hashCode()); + assertEquals("hashCode", fContext2.hashCode(), context2.hashCode()); + + assertFalse("hashCode", fContext1.hashCode() == context2.hashCode()); + assertFalse("hashCode", fContext2.hashCode() == context1.hashCode()); + + final TmfContext nullContext1 = new TmfContext(); + final TmfContext nullContext2 = new TmfContext(nullContext1); + assertEquals("hashCode", nullContext1.hashCode(), nullContext2.hashCode()); + } + + // ------------------------------------------------------------------------ + // toString + // ------------------------------------------------------------------------ + + @Test + public void testToString() { + final String expected1 = "TmfContext [fLocation=" + fLocation1 + ", fRank=" + fRank1 + "]"; + final String expected2 = "TmfContext [fLocation=" + fLocation2 + ", fRank=" + fRank2 + "]"; + + assertEquals("toString", expected1, fContext1.toString()); + assertEquals("toString", expected2, fContext2.toString()); + } + + // ------------------------------------------------------------------------ + // setLocation, setRank, updateRank + // ------------------------------------------------------------------------ + + @Test + public void testSetLocation() { + final TmfContext context1 = new TmfContext(fContext1); + context1.setLocation(fContext2.getLocation()); + + assertEquals("getLocation", fLocation2, context1.getLocation()); + assertEquals("getRank", fRank1, context1.getRank()); + } + + @Test + public void testSetRank() { + final TmfContext context1 = new TmfContext(fContext1); + context1.setRank(fContext2.getRank()); + + assertEquals("getLocation", fLocation1, context1.getLocation()); + assertEquals("getRank", fRank2, context1.getRank()); + } + + @Test + public void testIncreaseRank() { + final TmfContext context1 = new TmfContext(fContext1); + + context1.increaseRank(); + assertEquals("getRank", fRank1 + 1, context1.getRank()); + context1.increaseRank(); + assertEquals("getRank", fRank1 + 2, context1.getRank()); + + context1.setRank(ITmfContext.UNKNOWN_RANK); + context1.increaseRank(); + assertEquals("getRank", ITmfContext.UNKNOWN_RANK, context1.getRank()); + context1.increaseRank(); + assertEquals("getRank", ITmfContext.UNKNOWN_RANK, context1.getRank()); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/TmfExperimentTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/TmfExperimentTest.java new file mode 100644 index 0000000000..9a39eb0419 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/TmfExperimentTest.java @@ -0,0 +1,941 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Adjusted for new Trace Model + * Alexandre Montplaisir - Port to JUnit4 + * Patrick Tasse - Updated for rank in experiment location + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Vector; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.tracecompass.internal.tmf.core.trace.TmfExperimentContext; +import org.eclipse.tracecompass.internal.tmf.core.trace.TmfExperimentLocation; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.tests.TmfCoreTestPlugin; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; +import org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestExperimentAnalysis; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfExperimentStub; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; +import org.junit.Before; +import org.junit.Test; + +/** + * Test suite for the TmfExperiment class (single trace). + */ +@SuppressWarnings("javadoc") +public class TmfExperimentTest { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private static final String EXPERIMENT = "MyExperiment"; + private static int NB_EVENTS = 10000; + private static int BLOCK_SIZE = 1000; + + private static final double DELTA = 1e-15; + + private ITmfTrace[] fTestTraces; + private TmfExperimentStub fExperiment; + + private static byte SCALE = (byte) -3; + + // ------------------------------------------------------------------------ + // Housekeeping + // ------------------------------------------------------------------------ + + private synchronized ITmfTrace[] setupTrace(final String path) { + if (fTestTraces == null) { + fTestTraces = new ITmfTrace[1]; + try { + final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(path), null); + final File test = new File(FileLocator.toFileURL(location).toURI()); + final TmfTraceStub trace = new TmfTraceStub(test.getPath(), 0, true, null); + fTestTraces[0] = trace; + } catch (final TmfTraceException e) { + e.printStackTrace(); + } catch (final URISyntaxException e) { + e.printStackTrace(); + } catch (final IOException e) { + e.printStackTrace(); + } + } + return fTestTraces; + } + + private synchronized void setupExperiment() { + if (fExperiment == null) { + fExperiment = new TmfExperimentStub(EXPERIMENT, fTestTraces, BLOCK_SIZE); + fExperiment.getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, true); + } + } + + @Before + public void setUp() { + setupTrace(TmfTestTrace.A_TEST_10K.getFullPath()); + setupExperiment(); + } + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + @Test + public void testSimpleTmfExperimentConstructor() { + TmfExperiment experiment = new TmfExperiment(ITmfEvent.class, EXPERIMENT, fTestTraces); + assertEquals("GetId", EXPERIMENT, experiment.getName()); + assertEquals("GetCacheSize", TmfExperiment.DEFAULT_INDEX_PAGE_SIZE, experiment.getCacheSize()); + experiment.dispose(); + + experiment = new TmfExperiment(ITmfEvent.class, EXPERIMENT, null); + experiment.dispose(); + } + + @Test + public void testNormalTmfExperimentConstructor() { + assertEquals("GetId", EXPERIMENT, fExperiment.getName()); + assertEquals("GetNbEvents", NB_EVENTS, fExperiment.getNbEvents()); + + final long nbExperimentEvents = fExperiment.getNbEvents(); + assertEquals("GetNbEvents", NB_EVENTS, nbExperimentEvents); + + final long nbTraceEvents = fExperiment.getTraces()[0].getNbEvents(); + assertEquals("GetNbEvents", NB_EVENTS, nbTraceEvents); + + final TmfTimeRange timeRange = fExperiment.getTimeRange(); + assertEquals("getStartTime", 1, timeRange.getStartTime().getValue()); + assertEquals("getEndTime", NB_EVENTS, timeRange.getEndTime().getValue()); + } + + // ------------------------------------------------------------------------ + // Experiment setup + // ------------------------------------------------------------------------ + + @Test + public void testExperimentInitialization() { + /* + * Calling default constructor, then init should be equivalent to + * calling the full constructor + */ + + TmfExperimentStub experiment = new TmfExperimentStub(); + experiment.initExperiment(ITmfEvent.class, EXPERIMENT, fTestTraces, 5000, null); + experiment.getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, true); + + assertEquals("GetId", EXPERIMENT, fExperiment.getName()); + assertEquals("GetNbEvents", NB_EVENTS, fExperiment.getNbEvents()); + + final long nbExperimentEvents = fExperiment.getNbEvents(); + assertEquals("GetNbEvents", NB_EVENTS, nbExperimentEvents); + + final long nbTraceEvents = fExperiment.getTraces()[0].getNbEvents(); + assertEquals("GetNbEvents", NB_EVENTS, nbTraceEvents); + + final TmfTimeRange timeRange = fExperiment.getTimeRange(); + assertEquals("getStartTime", 1, timeRange.getStartTime().getValue()); + assertEquals("getEndTime", NB_EVENTS, timeRange.getEndTime().getValue()); + } + + // ------------------------------------------------------------------------ + // getTimestamp + // ------------------------------------------------------------------------ + + @Test + public void testGetTimestamp() { + assertEquals("getTimestamp", new TmfTimestamp( 1, (byte) -3), fExperiment.getTimestamp( 0)); + assertEquals("getTimestamp", new TmfTimestamp( 2, (byte) -3), fExperiment.getTimestamp( 1)); + assertEquals("getTimestamp", new TmfTimestamp( 11, (byte) -3), fExperiment.getTimestamp( 10)); + assertEquals("getTimestamp", new TmfTimestamp( 101, (byte) -3), fExperiment.getTimestamp( 100)); + assertEquals("getTimestamp", new TmfTimestamp( 1001, (byte) -3), fExperiment.getTimestamp(1000)); + assertEquals("getTimestamp", new TmfTimestamp( 2001, (byte) -3), fExperiment.getTimestamp(2000)); + assertEquals("getTimestamp", new TmfTimestamp( 2501, (byte) -3), fExperiment.getTimestamp(2500)); + assertEquals("getTimestamp", new TmfTimestamp(10000, (byte) -3), fExperiment.getTimestamp(9999)); + assertNull("getTimestamp", fExperiment.getTimestamp(10000)); + } + + // ------------------------------------------------------------------------ + // State system, statistics and modules methods + // ------------------------------------------------------------------------ + + @Test + public void testGetAnalysisModules() { + /* There should not be any modules at this point */ + Iterable modules = fExperiment.getAnalysisModules(); + assertFalse(modules.iterator().hasNext()); + + /* Open the experiment, the modules should be populated */ + fExperiment.traceOpened(new TmfTraceOpenedSignal(this, fExperiment, null)); + modules = fExperiment.getAnalysisModules(); + Iterable testModules = fExperiment.getAnalysisModulesOfClass(TestExperimentAnalysis.class); + assertTrue(modules.iterator().hasNext()); + assertTrue(testModules.iterator().hasNext()); + } + + // ------------------------------------------------------------------------ + // seekEvent by location + // ------------------------------------------------------------------------ + + @Test + public void testSeekBadLocation() { + ITmfContext context = fExperiment.seekEvent(new TmfLongLocation(0L)); + assertNull("seekEvent", context); + } + + @Test + public void testSeekNoTrace() { + TmfExperiment experiment = new TmfExperiment(ITmfEvent.class, EXPERIMENT, null); + ITmfContext context = experiment.seekEvent((TmfExperimentLocation) null); + assertNull("seekEvent", context); + experiment.dispose(); + } + + // ------------------------------------------------------------------------ + // seekEvent on ratio + // ------------------------------------------------------------------------ + + @Test + public void testSeekEventOnRatio() { + // First event + ITmfContext context = fExperiment.seekEvent(0.0); + assertEquals("Context rank", 0, context.getRank()); + ITmfEvent event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Context rank", 0, context.getRank()); + + // Middle event + int midTrace = NB_EVENTS / 2; + context = fExperiment.seekEvent(0.5); + assertEquals("Context rank", midTrace, context.getRank()); + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", midTrace + 1, event.getTimestamp().getValue()); + assertEquals("Context rank", midTrace, context.getRank()); + + // Last event + context = fExperiment.seekEvent(1.0); + assertEquals("Context rank", NB_EVENTS, context.getRank()); + event = fExperiment.parseEvent(context); + assertNull("Event timestamp", event); + assertEquals("Context rank", NB_EVENTS, context.getRank()); + + // Beyond last event + context = fExperiment.seekEvent(1.1); + assertEquals("Context rank", NB_EVENTS, context.getRank()); + event = fExperiment.parseEvent(context); + assertNull("Event timestamp", event); + assertEquals("Context rank", NB_EVENTS, context.getRank()); + + // Negative ratio + context = fExperiment.seekEvent(-0.5); + assertEquals("Context rank", 0, context.getRank()); + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Context rank", 0, context.getRank()); + } + + @Test + public void testGetLocationRatio() { + // First event + ITmfContext context = fExperiment.seekEvent((ITmfLocation) null); + double ratio = fExperiment.getLocationRatio(context.getLocation()); + assertEquals("getLocationRatio", 0.0, ratio, DELTA); + + // Middle event + context = fExperiment.seekEvent(NB_EVENTS / 2); + ratio = fExperiment.getLocationRatio(context.getLocation()); + assertEquals("getLocationRatio", (double) (NB_EVENTS / 2) / NB_EVENTS, ratio, DELTA); + + // Last event + context = fExperiment.seekEvent(NB_EVENTS - 1); + ratio = fExperiment.getLocationRatio(context.getLocation()); + assertEquals("getLocationRatio", (double) (NB_EVENTS - 1) / NB_EVENTS, ratio, DELTA); + } + +// @SuppressWarnings("rawtypes") +// public void testGetCurrentLocation() { +// ITmfContext context = fExperiment.seekEvent((ITmfLocation) null); +// ITmfLocation location = fExperiment.getCurrentLocation(); +// assertEquals("getCurrentLocation", location, context.getLocation()); +// } + + // ------------------------------------------------------------------------ + // seekEvent on rank + // ------------------------------------------------------------------------ + + @Test + public void testSeekRankOnCacheBoundary() { + long cacheSize = fExperiment.getCacheSize(); + + // On lower bound, returns the first event (TS = 1) + ITmfContext context = fExperiment.seekEvent(0); + assertEquals("Context rank", 0, context.getRank()); + + ITmfEvent event = fExperiment.getNext(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Context rank", 1, context.getRank()); + + // Position trace at event rank [cacheSize] + context = fExperiment.seekEvent(cacheSize); + assertEquals("Context rank", cacheSize, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); + assertEquals("Context rank", cacheSize + 1, context.getRank()); + + // Position trace at event rank [4 * cacheSize] + context = fExperiment.seekEvent(4 * cacheSize); + assertEquals("Context rank", 4 * cacheSize, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 4 * cacheSize + 1, event.getTimestamp().getValue()); + assertEquals("Context rank", 4 * cacheSize + 1, context.getRank()); + } + + @Test + public void testSeekRankNotOnCacheBoundary() { + long cacheSize = fExperiment.getCacheSize(); + + // Position trace at event rank 9 + ITmfContext context = fExperiment.seekEvent(9); + assertEquals("Context rank", 9, context.getRank()); + + ITmfEvent event = fExperiment.getNext(context); + assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); + assertEquals("Context rank", 10, context.getRank()); + + // Position trace at event rank [cacheSize - 1] + context = fExperiment.seekEvent(cacheSize - 1); + assertEquals("Context rank", cacheSize - 1, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", cacheSize, event.getTimestamp().getValue()); + assertEquals("Context rank", cacheSize, context.getRank()); + + // Position trace at event rank [cacheSize + 1] + context = fExperiment.seekEvent(cacheSize + 1); + assertEquals("Context rank", cacheSize + 1, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", cacheSize + 2, event.getTimestamp().getValue()); + assertEquals("Context rank", cacheSize + 2, context.getRank()); + + // Position trace at event rank 4500 + context = fExperiment.seekEvent(4500); + assertEquals("Context rank", 4500, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); + assertEquals("Context rank", 4501, context.getRank()); + } + + @Test + public void testSeekRankOutOfScope() { + // Position trace at beginning + ITmfContext context = fExperiment.seekEvent(-1); + assertEquals("Event rank", 0, context.getRank()); + + ITmfEvent event = fExperiment.getNext(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Context rank", 1, context.getRank()); + + // Position trace at event passed the end + context = fExperiment.seekEvent(NB_EVENTS); + assertEquals("Context rank", NB_EVENTS, context.getRank()); + + event = fExperiment.getNext(context); + assertNull("Event", event); + assertEquals("Context rank", NB_EVENTS, context.getRank()); + } + + // ------------------------------------------------------------------------ + // seekEvent on timestamp + // ------------------------------------------------------------------------ + + @Test + public void testSeekTimestampOnCacheBoundary() { + long cacheSize = fExperiment.getCacheSize(); + + // Position trace at event rank 0 + ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(1, SCALE, 0)); + assertEquals("Context rank", 0, context.getRank()); + + ITmfEvent event = fExperiment.getNext(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Context rank", 1, context.getRank()); + + // Position trace at event rank [cacheSize] + context = fExperiment.seekEvent(new TmfTimestamp(cacheSize + 1, SCALE, 0)); + assertEquals("Event rank", cacheSize, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); + assertEquals("Context rank", cacheSize + 1, context.getRank()); + + // Position trace at event rank [4 * cacheSize] + context = fExperiment.seekEvent(new TmfTimestamp(4 * cacheSize + 1, SCALE, 0)); + assertEquals("Context rank", 4 * cacheSize, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 4 * cacheSize + 1, event.getTimestamp().getValue()); + assertEquals("Context rank", 4 * cacheSize + 1, context.getRank()); + } + + @Test + public void testSeekTimestampNotOnCacheBoundary() { + // Position trace at event rank 1 (TS = 2) + ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(2, SCALE, 0)); + assertEquals("Context rank", 1, context.getRank()); + + ITmfEvent event = fExperiment.getNext(context); + assertEquals("Event timestamp", 2, event.getTimestamp().getValue()); + assertEquals("Context rank", 2, context.getRank()); + + // Position trace at event rank 9 (TS = 10) + context = fExperiment.seekEvent(new TmfTimestamp(10, SCALE, 0)); + assertEquals("Context rank", 9, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); + assertEquals("Context rank", 10, context.getRank()); + + // Position trace at event rank 999 (TS = 1000) + context = fExperiment.seekEvent(new TmfTimestamp(1000, SCALE, 0)); + assertEquals("Context rank", 999, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 1000, event.getTimestamp().getValue()); + assertEquals("Context rank", 1000, context.getRank()); + + // Position trace at event rank 1001 (TS = 1002) + context = fExperiment.seekEvent(new TmfTimestamp(1002, SCALE, 0)); + assertEquals("Context rank", 1001, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 1002, event.getTimestamp().getValue()); + assertEquals("Context rank", 1002, context.getRank()); + + // Position trace at event rank 4500 (TS = 4501) + context = fExperiment.seekEvent(new TmfTimestamp(4501, SCALE, 0)); + assertEquals("Context rank", 4500, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); + assertEquals("Context rank", 4501, context.getRank()); + } + + @Test + public void testSeekTimestampOutOfScope() { + // Position trace at beginning + ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(-1, SCALE, 0)); + assertEquals("Event rank", 0, context.getRank()); + + ITmfEvent event = fExperiment.getNext(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", 1, context.getRank()); + + // Position trace at event passed the end + context = fExperiment.seekEvent(new TmfTimestamp(NB_EVENTS + 1, SCALE, 0)); + event = fExperiment.getNext(context); + assertNull("Event location", event); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + } + + // ------------------------------------------------------------------------ + // seekEvent by location (context rank is undefined) + // ------------------------------------------------------------------------ + + @Test + public void testSeekLocationOnCacheBoundary() { + long cacheSize = fExperiment.getCacheSize(); + + // Position trace at event rank 0 + ITmfContext tmpContext = fExperiment.seekEvent(0); + ITmfContext context = fExperiment.seekEvent(tmpContext.getLocation()); + + ITmfEvent event = fExperiment.getNext(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 2, event.getTimestamp().getValue()); + + // Position trace at event rank 'cacheSize' + tmpContext = fExperiment.seekEvent(cacheSize); + context = fExperiment.seekEvent(tmpContext.getLocation()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", cacheSize + 2, event.getTimestamp().getValue()); + + // Position trace at event rank 4 * 'cacheSize' + tmpContext = fExperiment.seekEvent(4 * cacheSize); + context = fExperiment.seekEvent(tmpContext.getLocation()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 4 * cacheSize + 1, event.getTimestamp().getValue()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 4 * cacheSize + 2, event.getTimestamp().getValue()); + } + + @Test + public void testSeekLocationNotOnCacheBoundary() { + long cacheSize = fExperiment.getCacheSize(); + + // Position trace at event 'cacheSize' - 1 + ITmfContext tmpContext = fExperiment.seekEvent(cacheSize - 1); + ITmfContext context = fExperiment.seekEvent(tmpContext.getLocation()); + + ITmfEvent event = fExperiment.getNext(context); + assertEquals("Event timestamp", cacheSize, event.getTimestamp().getValue()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); + + // Position trace at event rank 2 * 'cacheSize' - 1 + tmpContext = fExperiment.seekEvent(2 * cacheSize - 1); + context = fExperiment.seekEvent(tmpContext.getLocation()); + context = fExperiment.seekEvent(2 * cacheSize - 1); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 2 * cacheSize, event.getTimestamp().getValue()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 2 * cacheSize + 1, event.getTimestamp().getValue()); + + // Position trace at event rank 4500 + tmpContext = fExperiment.seekEvent(4500); + context = fExperiment.seekEvent(tmpContext.getLocation()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 4502, event.getTimestamp().getValue()); + } + + @Test + public void testSeekLocationOutOfScope() { + // Position trace at beginning + ITmfContext context = fExperiment.seekEvent((ITmfLocation) null); + + ITmfEvent event = fExperiment.getNext(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + } + + // ------------------------------------------------------------------------ + // getNext - updates the context + // ------------------------------------------------------------------------ + + private static void validateContextRanks(ITmfContext context) { + assertTrue("Experiment context type", context instanceof TmfExperimentContext); + TmfExperimentContext ctx = (TmfExperimentContext) context; + + int nbTraces = ctx.getNbTraces(); + + // expRank = sum(trace ranks) - nbTraces + 1 (if lastTraceRead != NO_TRACE) + long expRank = -nbTraces + ((ctx.getLastTrace() != TmfExperimentContext.NO_TRACE) ? 1 : 0); + for (int i = 0; i < nbTraces; i++) { + ITmfContext subContext = ctx.getContext(i); + assertNotNull(subContext); + long rank = subContext.getRank(); + if (rank == -1) { + expRank = -1; + break; + } + expRank += rank; + } + assertEquals("Experiment context rank", expRank, ctx.getRank()); + } + + @Test + public void testGetNextAfteSeekingOnTS_1() { + + final long INITIAL_TS = 1; + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 1) + final ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(INITIAL_TS, SCALE, 0)); + + validateContextRanks(context); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fExperiment.getNext(context); + assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + i, context.getRank()); + } + + // Make sure we stay positioned + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); + + validateContextRanks(context); + } + + @Test + public void testGetNextAfteSeekingOnTS_2() { + final long INITIAL_TS = 2; + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 2) + final ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(INITIAL_TS, SCALE, 0)); + + validateContextRanks(context); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fExperiment.getNext(context); + assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + i, context.getRank()); + } + + // Make sure we stay positioned + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); + + validateContextRanks(context); + } + + @Test + public void testGetNextAfteSeekingOnTS_3() { + + final long INITIAL_TS = 500; + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 500) + final ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(INITIAL_TS, SCALE, 0)); + + validateContextRanks(context); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fExperiment.getNext(context); + assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + i, context.getRank()); + } + + // Make sure we stay positioned + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); + + validateContextRanks(context); + } + + @Test + public void testGetNextAfterSeekingOnRank_1() { + final long INITIAL_RANK = 0L; + final int NB_READS = 20; + + // On lower bound, returns the first event (rank = 0) + final ITmfContext context = fExperiment.seekEvent(INITIAL_RANK); + + validateContextRanks(context); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fExperiment.getNext(context); + assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); + } + + // Make sure we stay positioned + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); + + validateContextRanks(context); + } + + @Test + public void testGetNextAfterSeekingOnRank_2() { + final long INITIAL_RANK = 1L; + final int NB_READS = 20; + + // On lower bound, returns the first event (rank = 0) + final ITmfContext context = fExperiment.seekEvent(INITIAL_RANK); + + validateContextRanks(context); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fExperiment.getNext(context); + assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); + } + + // Make sure we stay positioned + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); + + validateContextRanks(context); + } + + @Test + public void testGetNextAfterSeekingOnRank_3() { + final long INITIAL_RANK = 500L; + final int NB_READS = 20; + + // On lower bound, returns the first event (rank = 0) + final ITmfContext context = fExperiment.seekEvent(INITIAL_RANK); + + validateContextRanks(context); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fExperiment.getNext(context); + assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); + } + + // Make sure we stay positioned + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); + + validateContextRanks(context); + } + + @Test + public void testGetNextAfterSeekingOnLocation_1() { + final ITmfLocation INITIAL_LOC = null; + final long INITIAL_TS = 1; + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 1) + final ITmfContext context = fExperiment.seekEvent(INITIAL_LOC); + + validateContextRanks(context); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fExperiment.getNext(context); + assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + i, context.getRank()); + } + + // Make sure we stay positioned + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); + + validateContextRanks(context); + } + + @Test + public void testGetNextAfterSeekingOnLocation_2() { + final ITmfLocation INITIAL_LOC = fExperiment.seekEvent(1L).getLocation(); + final long INITIAL_TS = 2; + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 2) + final ITmfContext context = fExperiment.seekEvent(INITIAL_LOC); + + validateContextRanks(context); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fExperiment.getNext(context); + assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); + } + + // Make sure we stay positioned + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); + + validateContextRanks(context); + } + + @Test + public void testGetNextAfterSeekingOnLocation_3() { + final ITmfLocation INITIAL_LOC = fExperiment.seekEvent(500L).getLocation(); + final long INITIAL_TS = 501; + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 501) + final ITmfContext context = fExperiment.seekEvent(INITIAL_LOC); + + validateContextRanks(context); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fExperiment.getNext(context); + assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); + } + + // Make sure we stay positioned + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); + + validateContextRanks(context); + } + + @Test + public void testGetNextLocation() { + ITmfContext context1 = fExperiment.seekEvent(0); + fExperiment.getNext(context1); + ITmfLocation location = context1.getLocation(); + ITmfEvent event1 = fExperiment.getNext(context1); + ITmfContext context2 = fExperiment.seekEvent(location); + ITmfEvent event2 = fExperiment.getNext(context2); + assertEquals("Event timestamp", event1.getTimestamp().getValue(), event2.getTimestamp().getValue()); + } + + @Test + public void testGetNextEndLocation() { + ITmfContext context1 = fExperiment.seekEvent(fExperiment.getNbEvents() - 1); + fExperiment.getNext(context1); + ITmfLocation location = context1.getLocation(); + ITmfContext context2 = fExperiment.seekEvent(location); + ITmfEvent event = fExperiment.getNext(context2); + assertNull("Event", event); + } + + // ------------------------------------------------------------------------ + // processRequest + // ------------------------------------------------------------------------ + + @Test + public void testProcessRequestForNbEvents() throws InterruptedException { + final int nbEvents = 1000; + final Vector requestedEvents = new Vector<>(); + + final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, + range, 0, nbEvents, ExecutionType.FOREGROUND) { + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + requestedEvents.add(event); + } + }; + fExperiment.sendRequest(request); + request.waitForCompletion(); + + assertEquals("nbEvents", nbEvents, requestedEvents.size()); + assertTrue("isCompleted", request.isCompleted()); + assertFalse("isCancelled", request.isCancelled()); + + // Ensure that we have distinct events. + // Don't go overboard: we are not validating the stub! + for (int i = 0; i < nbEvents; i++) { + assertEquals("Distinct events", i+1, requestedEvents.get(i).getTimestamp().getValue()); + } + } + + @Test + public void testProcessRequestForAllEvents() throws InterruptedException { + final int nbEvents = ITmfEventRequest.ALL_DATA; + final Vector requestedEvents = new Vector<>(); + final long nbExpectedEvents = NB_EVENTS; + + final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, + range, 0, nbEvents, ExecutionType.FOREGROUND) { + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + requestedEvents.add(event); + } + }; + fExperiment.sendRequest(request); + request.waitForCompletion(); + + assertEquals("nbEvents", nbExpectedEvents, requestedEvents.size()); + assertTrue("isCompleted", request.isCompleted()); + assertFalse("isCancelled", request.isCancelled()); + + // Ensure that we have distinct events. + // Don't go overboard: we are not validating the stub! + for (int i = 0; i < nbExpectedEvents; i++) { + assertEquals("Distinct events", i+1, requestedEvents.get(i).getTimestamp().getValue()); + } + } + + // ------------------------------------------------------------------------ + // cancel + // ------------------------------------------------------------------------ + + @Test + public void testCancel() throws InterruptedException { + final int nbEvents = NB_EVENTS; + final int limit = BLOCK_SIZE; + final Vector requestedEvents = new Vector<>(); + + final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, + range, 0, nbEvents, ExecutionType.FOREGROUND) { + int nbRead = 0; + + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + requestedEvents.add(event); + if (++nbRead == limit) { + cancel(); + } + } + + @Override + public void handleCancel() { + if (requestedEvents.size() < limit) { + System.out.println("aie"); + } + } + }; + fExperiment.sendRequest(request); + request.waitForCompletion(); + + assertEquals("nbEvents", limit, requestedEvents.size()); + assertTrue("isCompleted", request.isCompleted()); + assertTrue("isCancelled", request.isCancelled()); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/TmfMultiTraceExperimentTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/TmfMultiTraceExperimentTest.java new file mode 100644 index 0000000000..b56c75832a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/TmfMultiTraceExperimentTest.java @@ -0,0 +1,814 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Adjusted for new Trace Model + * Alexandre Montplaisir - Port to JUnit4 + * Patrick Tasse - Fix for concurrency + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Vector; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.tracecompass.internal.tmf.core.trace.TmfExperimentContext; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType; +import org.eclipse.tracecompass.tmf.core.tests.TmfCoreTestPlugin; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfExperimentStub; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Test suite for the TmfExperiment class (multiple traces). + */ +@SuppressWarnings("javadoc") +public class TmfMultiTraceExperimentTest { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private static final long DEFAULT_INITIAL_OFFSET_VALUE = (1L * 100 * 1000 * 1000); // .1sec + private static final String EXPERIMENT = "MyExperiment"; + private static int NB_EVENTS = 20000; + private static int BLOCK_SIZE = 1000; + + private static TmfExperimentStub fExperiment; + + private static byte SCALE = (byte) -3; + + // ------------------------------------------------------------------------ + // Housekeeping + // ------------------------------------------------------------------------ + + @BeforeClass + public static void setUp() { + ITmfTrace[] traces = setupTraces(); + fExperiment = new TmfExperimentStub(EXPERIMENT, traces, BLOCK_SIZE); + fExperiment.getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, true); + } + + @AfterClass + public static void tearDown() { + fExperiment.dispose(); + } + + private static ITmfTrace[] setupTraces() { + try { + ITmfTrace[] traces = new ITmfTrace[2]; + + URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TmfTestTrace.O_TEST_10K.getFullPath()), null); + File test = new File(FileLocator.toFileURL(location).toURI()); + final TmfTraceStub trace1 = new TmfTraceStub(test.getPath(), 0, true, null); + traces[0] = trace1; + + location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TmfTestTrace.E_TEST_10K.getFullPath()), null); + test = new File(FileLocator.toFileURL(location).toURI()); + final TmfTraceStub trace2 = new TmfTraceStub(test.getPath(), 0, true, null); + traces[1] = trace2; + + return traces; + } catch (final TmfTraceException e) { + e.printStackTrace(); + } catch (final URISyntaxException e) { + e.printStackTrace(); + } catch (final IOException e) { + e.printStackTrace(); + } + return new ITmfTrace[0]; + } + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + @Test + public void testBasicTmfExperimentConstructor() { + assertEquals("GetId", EXPERIMENT, fExperiment.getName()); + assertEquals("GetNbEvents", NB_EVENTS, fExperiment.getNbEvents()); + + final TmfTimeRange timeRange = fExperiment.getTimeRange(); + assertEquals("getStartTime", 1, timeRange.getStartTime().getValue()); + assertEquals("getEndTime", NB_EVENTS, timeRange.getEndTime().getValue()); + + TmfTimestamp initRange = new TmfTimestamp(DEFAULT_INITIAL_OFFSET_VALUE, ITmfTimestamp.NANOSECOND_SCALE); + assertEquals("getInitialRangeOffset", initRange, fExperiment.getInitialRangeOffset()); + } + + // ------------------------------------------------------------------------ + // seekEvent on rank + // ------------------------------------------------------------------------ + + @Test + public void testSeekRankOnCacheBoundary() { + long cacheSize = fExperiment.getCacheSize(); + + // On lower bound, returns the first event (TS = 1) + ITmfContext context = fExperiment.seekEvent(0); + assertEquals("Context rank", 0, context.getRank()); + + ITmfEvent event = fExperiment.getNext(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Context rank", 1, context.getRank()); + + // Position trace at event rank [cacheSize] + context = fExperiment.seekEvent(cacheSize); + assertEquals("Context rank", cacheSize, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); + assertEquals("Context rank", cacheSize + 1, context.getRank()); + + // Position trace at event rank [4 * cacheSize] + context = fExperiment.seekEvent(4 * cacheSize); + assertEquals("Context rank", 4 * cacheSize, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 4 * cacheSize + 1, event.getTimestamp().getValue()); + assertEquals("Context rank", 4 * cacheSize + 1, context.getRank()); + } + + @Test + public void testSeekRankNotOnCacheBoundary() { + long cacheSize = fExperiment.getCacheSize(); + + // Position trace at event rank 9 + ITmfContext context = fExperiment.seekEvent(9); + assertEquals("Context rank", 9, context.getRank()); + + ITmfEvent event = fExperiment.getNext(context); + assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); + assertEquals("Context rank", 10, context.getRank()); + + // Position trace at event rank [cacheSize - 1] + context = fExperiment.seekEvent(cacheSize - 1); + assertEquals("Context rank", cacheSize - 1, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", cacheSize, event.getTimestamp().getValue()); + assertEquals("Context rank", cacheSize, context.getRank()); + + // Position trace at event rank [cacheSize + 1] + context = fExperiment.seekEvent(cacheSize + 1); + assertEquals("Context rank", cacheSize + 1, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", cacheSize + 2, event.getTimestamp().getValue()); + assertEquals("Context rank", cacheSize + 2, context.getRank()); + + // Position trace at event rank 4500 + context = fExperiment.seekEvent(4500); + assertEquals("Context rank", 4500, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); + assertEquals("Context rank", 4501, context.getRank()); + } + + @Test + public void testSeekRankOutOfScope() { + // Position trace at beginning + ITmfContext context = fExperiment.seekEvent(-1); + assertEquals("Event rank", 0, context.getRank()); + + ITmfEvent event = fExperiment.getNext(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Context rank", 1, context.getRank()); + + // Position trace at event passed the end + context = fExperiment.seekEvent(NB_EVENTS); + assertEquals("Context rank", NB_EVENTS, context.getRank()); + + event = fExperiment.getNext(context); + assertNull("Event", event); + assertEquals("Context rank", NB_EVENTS, context.getRank()); + } + + // ------------------------------------------------------------------------ + // seekEvent on timestamp + // ------------------------------------------------------------------------ + + @Test + public void testSeekTimestampOnCacheBoundary() { + long cacheSize = fExperiment.getCacheSize(); + + // Position trace at event rank 0 + ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(1, SCALE, 0)); + assertEquals("Context rank", 0, context.getRank()); + + ITmfEvent event = fExperiment.getNext(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Context rank", 1, context.getRank()); + + // Position trace at event rank [cacheSize] + context = fExperiment.seekEvent(new TmfTimestamp(cacheSize + 1, SCALE, 0)); + assertEquals("Event rank", cacheSize, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); + assertEquals("Context rank", cacheSize + 1, context.getRank()); + + // Position trace at event rank [4 * cacheSize] + context = fExperiment.seekEvent(new TmfTimestamp(4 * cacheSize + 1, SCALE, 0)); + assertEquals("Context rank", 4 * cacheSize, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 4 * cacheSize + 1, event.getTimestamp().getValue()); + assertEquals("Context rank", 4 * cacheSize + 1, context.getRank()); + } + + @Test + public void testSeekTimestampNotOnCacheBoundary() { + // Position trace at event rank 1 (TS = 2) + ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(2, SCALE, 0)); + assertEquals("Context rank", 1, context.getRank()); + + ITmfEvent event = fExperiment.getNext(context); + assertEquals("Event timestamp", 2, event.getTimestamp().getValue()); + assertEquals("Context rank", 2, context.getRank()); + + // Position trace at event rank 9 (TS = 10) + context = fExperiment.seekEvent(new TmfTimestamp(10, SCALE, 0)); + assertEquals("Context rank", 9, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); + assertEquals("Context rank", 10, context.getRank()); + + // Position trace at event rank 999 (TS = 1000) + context = fExperiment.seekEvent(new TmfTimestamp(1000, SCALE, 0)); + assertEquals("Context rank", 999, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 1000, event.getTimestamp().getValue()); + assertEquals("Context rank", 1000, context.getRank()); + + // Position trace at event rank 1001 (TS = 1002) + context = fExperiment.seekEvent(new TmfTimestamp(1002, SCALE, 0)); + assertEquals("Context rank", 1001, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 1002, event.getTimestamp().getValue()); + assertEquals("Context rank", 1002, context.getRank()); + + // Position trace at event rank 4500 (TS = 4501) + context = fExperiment.seekEvent(new TmfTimestamp(4501, SCALE, 0)); + assertEquals("Context rank", 4500, context.getRank()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); + assertEquals("Context rank", 4501, context.getRank()); + } + + @Test + public void testSeekTimestampOutOfScope() { + // Position trace at beginning + ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(-1, SCALE, 0)); + assertEquals("Event rank", 0, context.getRank()); + + ITmfEvent event = fExperiment.getNext(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", 1, context.getRank()); + + // Position trace at event passed the end + context = fExperiment.seekEvent(new TmfTimestamp(NB_EVENTS + 1, SCALE, 0)); + event = fExperiment.getNext(context); + assertNull("Event location", event); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + } + + // ------------------------------------------------------------------------ + // seekEvent by location (context rank is undefined) + // ------------------------------------------------------------------------ + + @Test + public void testSeekLocationOnCacheBoundary() { + long cacheSize = fExperiment.getCacheSize(); + + // Position trace at event rank 0 + ITmfContext tmpContext = fExperiment.seekEvent(0); + ITmfContext context = fExperiment.seekEvent(tmpContext.getLocation()); + + ITmfEvent event = fExperiment.getNext(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 2, event.getTimestamp().getValue()); + + // Position trace at event rank 'cacheSize' + tmpContext = fExperiment.seekEvent(cacheSize); + context = fExperiment.seekEvent(tmpContext.getLocation()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", cacheSize + 2, event.getTimestamp().getValue()); + + // Position trace at event rank 4 * 'cacheSize' + tmpContext = fExperiment.seekEvent(4 * cacheSize); + context = fExperiment.seekEvent(tmpContext.getLocation()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 4 * cacheSize + 1, event.getTimestamp().getValue()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 4 * cacheSize + 2, event.getTimestamp().getValue()); + } + + @Test + public void testSeekLocationNotOnCacheBoundary() { + long cacheSize = fExperiment.getCacheSize(); + + // Position trace at event 'cacheSize' - 1 + ITmfContext tmpContext = fExperiment.seekEvent(cacheSize - 1); + ITmfContext context = fExperiment.seekEvent(tmpContext.getLocation()); + + ITmfEvent event = fExperiment.getNext(context); + assertEquals("Event timestamp", cacheSize, event.getTimestamp().getValue()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); + + // Position trace at event rank 2 * 'cacheSize' - 1 + tmpContext = fExperiment.seekEvent(2 * cacheSize - 1); + context = fExperiment.seekEvent(tmpContext.getLocation()); + context = fExperiment.seekEvent(2 * cacheSize - 1); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 2 * cacheSize, event.getTimestamp().getValue()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 2 * cacheSize + 1, event.getTimestamp().getValue()); + + // Position trace at event rank 4500 + tmpContext = fExperiment.seekEvent(4500); + context = fExperiment.seekEvent(tmpContext.getLocation()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); + + event = fExperiment.getNext(context); + assertEquals("Event timestamp", 4502, event.getTimestamp().getValue()); + } + + @Test + public void testSeekLocationOutOfScope() { + // Position trace at beginning + ITmfContext context = fExperiment.seekEvent((ITmfLocation) null); + + ITmfEvent event = fExperiment.getNext(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + } + + // ------------------------------------------------------------------------ + // getNext - updates the context + // ------------------------------------------------------------------------ + + private static void validateContextRanks(ITmfContext context) { + assertTrue("Experiment context type", context instanceof TmfExperimentContext); + TmfExperimentContext ctx = (TmfExperimentContext) context; + + int nbTraces = ctx.getNbTraces(); + + // expRank = sum(trace ranks) - nbTraces + 1 (if lastTraceRead != NO_TRACE) + long expRank = -nbTraces + ((ctx.getLastTrace() != TmfExperimentContext.NO_TRACE) ? 1 : 0); + for (int i = 0; i < nbTraces; i++) { + ITmfContext subContext = ctx.getContext(i); + assertNotNull(subContext); + long rank = subContext.getRank(); + if (rank == -1) { + expRank = -1; + break; + } + expRank += rank; + } + assertEquals("Experiment context rank", expRank, ctx.getRank()); + } + + @Test + public void testGetNextAfteSeekingOnTS_1() { + final long INITIAL_TS = 1; + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 1) + final ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(INITIAL_TS, SCALE, 0)); + + validateContextRanks(context); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fExperiment.getNext(context); + assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + i, context.getRank()); + } + + // Make sure we stay positioned + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); + + validateContextRanks(context); + } + + @Test + public void testGetNextAfteSeekingOnTS_2() { + final long INITIAL_TS = 2; + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 2) + final ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(INITIAL_TS, SCALE, 0)); + + validateContextRanks(context); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fExperiment.getNext(context); + assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + i, context.getRank()); + } + + // Make sure we stay positioned + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); + + validateContextRanks(context); + } + + @Test + public void testGetNextAfteSeekingOnTS_3() { + final long INITIAL_TS = 500; + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 500) + final ITmfContext context = fExperiment.seekEvent(new TmfTimestamp(INITIAL_TS, SCALE, 0)); + + validateContextRanks(context); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fExperiment.getNext(context); + assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + i, context.getRank()); + } + + // Make sure we stay positioned + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); + + validateContextRanks(context); + } + + @Test + public void testGetNextAfterSeekingOnRank_1() { + final long INITIAL_RANK = 0L; + final int NB_READS = 20; + + // On lower bound, returns the first event (rank = 0) + final ITmfContext context = fExperiment.seekEvent(INITIAL_RANK); + + validateContextRanks(context); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fExperiment.getNext(context); + assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); + } + + // Make sure we stay positioned + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); + + validateContextRanks(context); + } + + @Test + public void testGetNextAfterSeekingOnRank_2() { + final long INITIAL_RANK = 1L; + final int NB_READS = 20; + + // On lower bound, returns the first event (rank = 0) + final ITmfContext context = fExperiment.seekEvent(INITIAL_RANK); + + validateContextRanks(context); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fExperiment.getNext(context); + assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); + } + + // Make sure we stay positioned + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); + + validateContextRanks(context); + } + + @Test + public void testGetNextAfterSeekingOnRank_3() { + final long INITIAL_RANK = 500L; + final int NB_READS = 20; + + // On lower bound, returns the first event (rank = 0) + final ITmfContext context = fExperiment.seekEvent(INITIAL_RANK); + + validateContextRanks(context); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fExperiment.getNext(context); + assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); + } + + // Make sure we stay positioned + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); + + validateContextRanks(context); + } + + @Test + public void testGetNextAfterSeekingOnLocation_1() { + final ITmfLocation INITIAL_LOC = null; + final long INITIAL_TS = 1; + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 1) + final ITmfContext context = fExperiment.seekEvent(INITIAL_LOC); + + validateContextRanks(context); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fExperiment.getNext(context); + assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + i, context.getRank()); + } + + // Make sure we stay positioned + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); + + validateContextRanks(context); + } + + @Test + public void testGetNextAfterSeekingOnLocation_2() { + final ITmfLocation INITIAL_LOC = fExperiment.seekEvent(1L).getLocation(); + final long INITIAL_TS = 2; + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 2) + final ITmfContext context = fExperiment.seekEvent(INITIAL_LOC); + + validateContextRanks(context); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fExperiment.getNext(context); + assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); + } + + // Make sure we stay positioned + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); + + validateContextRanks(context); + } + + @Test + public void testGetNextAfterSeekingOnLocation_3() { + final ITmfLocation INITIAL_LOC = fExperiment.seekEvent(500L).getLocation(); + final long INITIAL_TS = 501; + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 501) + final ITmfContext context = fExperiment.seekEvent(INITIAL_LOC); + + validateContextRanks(context); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fExperiment.getNext(context); + assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); + } + + // Make sure we stay positioned + event = fExperiment.parseEvent(context); + assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); + + validateContextRanks(context); + } + + @Test + public void testGetNextLocation() { + ITmfContext context1 = fExperiment.seekEvent(0); + fExperiment.getNext(context1); + ITmfLocation location = context1.getLocation(); + ITmfEvent event1 = fExperiment.getNext(context1); + ITmfContext context2 = fExperiment.seekEvent(location); + ITmfEvent event2 = fExperiment.getNext(context2); + assertEquals("Event timestamp", event1.getTimestamp().getValue(), event2.getTimestamp().getValue()); + } + + @Test + public void testGetNextEndLocation() { + ITmfContext context1 = fExperiment.seekEvent(fExperiment.getNbEvents() - 1); + fExperiment.getNext(context1); + ITmfLocation location = context1.getLocation(); + ITmfContext context2 = fExperiment.seekEvent(location); + ITmfEvent event = fExperiment.getNext(context2); + assertNull("Event", event); + } + + // ------------------------------------------------------------------------ + // processRequest + // ------------------------------------------------------------------------ + + @Test + public void testProcessRequestForNbEvents() throws InterruptedException { + final int nbEvents = 1000; + final Vector requestedEvents = new Vector<>(); + + final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, + range, 0, nbEvents, ExecutionType.FOREGROUND) { + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + requestedEvents.add(event); + } + }; + fExperiment.sendRequest(request); + request.waitForCompletion(); + + assertEquals("nbEvents", nbEvents, requestedEvents.size()); + assertTrue("isCompleted", request.isCompleted()); + assertFalse("isCancelled", request.isCancelled()); + + // Ensure that we have distinct events. + // Don't go overboard: we are not validating the stub! + for (int i = 0; i < nbEvents; i++) { + assertEquals("Distinct events", i+1, requestedEvents.get(i).getTimestamp().getValue()); + } + } + + @Test + public void testProcessRequestForAllEvents() throws InterruptedException { + final int nbEvents = ITmfEventRequest.ALL_DATA; + final Vector requestedEvents = new Vector<>(); + final long nbExpectedEvents = NB_EVENTS; + + final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, + range, 0, nbEvents, ExecutionType.FOREGROUND) { + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + requestedEvents.add(event); + } + }; + fExperiment.sendRequest(request); + request.waitForCompletion(); + + assertEquals("nbEvents", nbExpectedEvents, requestedEvents.size()); + assertTrue("isCompleted", request.isCompleted()); + assertFalse("isCancelled", request.isCancelled()); + + // Ensure that we have distinct events. + // Don't go overboard: we are not validating the stub! + for (int i = 0; i < nbExpectedEvents; i++) { + assertEquals("Distinct events", i+1, requestedEvents.get(i).getTimestamp().getValue()); + } + } + + // ------------------------------------------------------------------------ + // cancel + // ------------------------------------------------------------------------ + + @Test + public void testCancel() throws InterruptedException { + final int nbEvents = NB_EVENTS; + final int limit = BLOCK_SIZE; + final Vector requestedEvents = new Vector<>(); + + final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, + range, 0, nbEvents, ExecutionType.FOREGROUND) { + int nbRead = 0; + + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + requestedEvents.add(event); + if (++nbRead == limit) { + cancel(); + } + } + }; + fExperiment.sendRequest(request); + request.waitForCompletion(); + + assertEquals("nbEvents", limit, requestedEvents.size()); + assertTrue("isCompleted", request.isCompleted()); + assertTrue("isCancelled", request.isCancelled()); + } + + // ------------------------------------------------------------------------ + // getTimestamp + // ------------------------------------------------------------------------ + + @Test + public void testGetTimestamp() { + assertEquals("getTimestamp", new TmfTimestamp( 1, (byte) -3), fExperiment.getTimestamp( 0)); + assertEquals("getTimestamp", new TmfTimestamp( 2, (byte) -3), fExperiment.getTimestamp( 1)); + assertEquals("getTimestamp", new TmfTimestamp( 11, (byte) -3), fExperiment.getTimestamp( 10)); + assertEquals("getTimestamp", new TmfTimestamp( 101, (byte) -3), fExperiment.getTimestamp( 100)); + assertEquals("getTimestamp", new TmfTimestamp( 1001, (byte) -3), fExperiment.getTimestamp( 1000)); + assertEquals("getTimestamp", new TmfTimestamp( 2001, (byte) -3), fExperiment.getTimestamp( 2000)); + assertEquals("getTimestamp", new TmfTimestamp( 2501, (byte) -3), fExperiment.getTimestamp( 2500)); + assertEquals("getTimestamp", new TmfTimestamp(10000, (byte) -3), fExperiment.getTimestamp( 9999)); + assertEquals("getTimestamp", new TmfTimestamp(20000, (byte) -3), fExperiment.getTimestamp(19999)); + assertNull("getTimestamp", fExperiment.getTimestamp(20000)); + } + + // ------------------------------------------------------------------------ + // getInitialRangeOffset, getCurrentRange, getCurrentTime + // ------------------------------------------------------------------------ + + @Test + public void testDefaultCurrentTimeValues() { + ITmfTrace[] traces = setupTraces(); + TmfExperimentStub exp = new TmfExperimentStub(EXPERIMENT, traces, BLOCK_SIZE); + + // verify initial values + TmfTimestamp initRange = new TmfTimestamp(DEFAULT_INITIAL_OFFSET_VALUE, ITmfTimestamp.NANOSECOND_SCALE); + assertEquals("getInitialRangeOffset", initRange, exp.getInitialRangeOffset()); + + exp.dispose(); + } + + @Test + public void testInitialRangeOffset() { + ITmfTrace[] traces = setupTraces(); + ((TmfTraceStub) traces[0]).setInitialRangeOffset(new TmfTimestamp(5, ITmfTimestamp.MILLISECOND_SCALE)); + ((TmfTraceStub) traces[1]).setInitialRangeOffset(new TmfTimestamp(2, ITmfTimestamp.MILLISECOND_SCALE)); + TmfExperimentStub exp = new TmfExperimentStub(EXPERIMENT, traces, BLOCK_SIZE); + + TmfTimestamp initRange = new TmfTimestamp(2, ITmfTimestamp.MILLISECOND_SCALE); + assertEquals("getInitialRangeOffset", initRange, exp.getInitialRangeOffset()); + + exp.dispose(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/TmfTraceTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/TmfTraceTest.java new file mode 100644 index 0000000000..500c3edb45 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/TmfTraceTest.java @@ -0,0 +1,1389 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Adapted for TMF Trace Model 1.0 + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Vector; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.tracecompass.internal.tmf.core.component.TmfProviderManager; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; +import org.eclipse.tracecompass.tmf.core.component.ITmfEventProvider; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.tests.TmfCoreTestPlugin; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfContext; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; +import org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestAnalysis; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.rules.Timeout; + +/** + * Test suite for the TmfTrace class. + */ +@SuppressWarnings("javadoc") +public class TmfTraceTest { + + /** Time-out tests after 20 seconds */ + @Rule + public TestRule globalTimeout= new Timeout(20000); + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + private static final TmfTestTrace TEST_TRACE = TmfTestTrace.A_TEST_10K; + private static final long DEFAULT_INITIAL_OFFSET_VALUE = (1L * 100 * 1000 * 1000); // .1sec + private static final int NB_EVENTS = 10000; + private TmfTraceStub fTrace = null; + + private static int SCALE = -3; + + // ------------------------------------------------------------------------ + // Housekeeping + // ------------------------------------------------------------------------ + + @Before + public void setUp() { + try { + final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE.getFullPath()), null); + final File test = new File(FileLocator.toFileURL(location).toURI()); + fTrace = new TmfTraceStub(test.toURI().getPath(), ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, false, null); + TmfSignalManager.deregister(fTrace); + fTrace.indexTrace(true); + } catch (final TmfTraceException e) { + e.printStackTrace(); + } catch (final URISyntaxException e) { + e.printStackTrace(); + } catch (final IOException e) { + e.printStackTrace(); + } + } + + @After + public void tearDown() { + fTrace.dispose(); + fTrace = null; + } + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + @Test + public void testFullConstructor() throws TmfTraceException { + try { + final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE.getFullPath()), null); + File testfile = new File(FileLocator.toFileURL(location).toURI()); + TmfTraceStub trace = new TmfTraceStub(testfile.toURI().getPath(), ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, false, null); + trace.indexTrace(true); + + assertEquals("getType", ITmfEvent.class, trace.getType()); + assertNull("getResource", trace.getResource()); + assertEquals("getPath", testfile.toURI().getPath(), trace.getPath()); + assertEquals("getCacheSize", ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, trace.getCacheSize()); + assertEquals("getStreamingInterval", 0, trace.getStreamingInterval()); + assertEquals("getName", TEST_TRACE.getPath(), trace.getName()); + + assertEquals("getNbEvents", NB_EVENTS, trace.getNbEvents()); + assertEquals("getRange-start", 1, trace.getTimeRange().getStartTime().getValue()); + assertEquals("getRange-end", NB_EVENTS, trace.getTimeRange().getEndTime().getValue()); + assertEquals("getStartTime", 1, trace.getStartTime().getValue()); + assertEquals("getEndTime", NB_EVENTS, trace.getEndTime().getValue()); + + } catch (final URISyntaxException e) { + fail("URISyntaxException"); + } catch (final IOException e) { + fail("IOException"); + } + } + + @Test + public void testLiveTraceConstructor() throws TmfTraceException { + final long interval = 100; + try { + final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE.getFullPath()), null); + File testfile = new File(FileLocator.toFileURL(location).toURI()); + TmfTraceStub trace = new TmfTraceStub(testfile.toURI().getPath(), ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, interval); + trace.indexTrace(true); + + assertEquals("getType", ITmfEvent.class, trace.getType()); + assertNull("getResource", trace.getResource()); + assertEquals("getPath", testfile.toURI().getPath(), trace.getPath()); + assertEquals("getCacheSize", ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, trace.getCacheSize()); + assertEquals("getStreamingInterval", interval, trace.getStreamingInterval()); + assertEquals("getName", TEST_TRACE.getPath(), trace.getName()); + + assertEquals("getNbEvents", NB_EVENTS, trace.getNbEvents()); + assertEquals("getRange-start", 1, trace.getTimeRange().getStartTime().getValue()); + assertEquals("getRange-end", NB_EVENTS, trace.getTimeRange().getEndTime().getValue()); + assertEquals("getStartTime", 1, trace.getStartTime().getValue()); + assertEquals("getEndTime", NB_EVENTS, trace.getEndTime().getValue()); + + } catch (final URISyntaxException e) { + fail("URISyntaxException"); + } catch (final IOException e) { + fail("IOException"); + } + } + + @Test + public void testCopyConstructor() throws TmfTraceException { + try { + final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE.getFullPath()), null); + File testfile = new File(FileLocator.toFileURL(location).toURI()); + TmfTraceStub original = new TmfTraceStub(testfile.toURI().getPath(), ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, false, null); + TmfTraceStub trace = new TmfTraceStub(original); + trace.indexTrace(true); + + assertEquals("getType", ITmfEvent.class, trace.getType()); + assertNull("getResource", trace.getResource()); + assertEquals("getPath", testfile.toURI().getPath(), trace.getPath()); + assertEquals("getCacheSize", ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, trace.getCacheSize()); + assertEquals("getStreamingInterval", 0, trace.getStreamingInterval()); + assertEquals("getName", TEST_TRACE.getPath(), trace.getName()); + + assertEquals("getNbEvents", NB_EVENTS, trace.getNbEvents()); + assertEquals("getRange-start", 1, trace.getTimeRange().getStartTime().getValue()); + assertEquals("getRange-end", NB_EVENTS, trace.getTimeRange().getEndTime().getValue()); + assertEquals("getStartTime", 1, trace.getStartTime().getValue()); + assertEquals("getEndTime", NB_EVENTS, trace.getEndTime().getValue()); + + } catch (final URISyntaxException e) { + fail("URISyntaxException"); + } catch (final IOException e) { + fail("IOException"); + } + + // Test the copy of a null trace + try { + new TmfTraceStub((TmfTraceStub) null); + fail("Missing exception"); + } catch (final IllegalArgumentException e) { + // test passed + } catch (final Exception e) { + fail("Unexpected exception"); + } + } + + // ------------------------------------------------------------------------ + // Trace initialization + // ------------------------------------------------------------------------ + + @Test + public void testInitializeNullPath() { + // Instantiate an "empty" trace + final TmfTraceStub trace = new TmfTraceStub(); + + try { + trace.initialize(null, null, ITmfEvent.class); + fail("TmfTrace.initialize() - no exception thrown"); + } catch (TmfTraceException e) { + // Success + } catch (Exception e) { + fail("TmfTrace.initialize() - wrong exception thrown"); + } + } + + @Test + public void testInitializeSimplePath() { + // Instantiate an "empty" trace + final TmfTraceStub trace = new TmfTraceStub(); + + // Path == trace name + String path = "TraceName"; + try { + trace.initialize(null, path, ITmfEvent.class); + } catch (Exception e) { + fail("TmfTrace.initialize() - Exception thrown"); + } + + assertEquals("getType", ITmfEvent.class, trace.getType()); + assertNull ("getResource", trace.getResource()); + assertEquals("getPath", path, trace.getPath()); + assertEquals("getCacheSize", ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, trace.getCacheSize()); + assertEquals("getStreamingInterval", 0, trace.getStreamingInterval()); + assertEquals("getName", path, trace.getName()); + + assertEquals("getNbEvents", 0, trace.getNbEvents()); + assertEquals("getRange-start", Long.MIN_VALUE, trace.getTimeRange().getStartTime().getValue()); + assertEquals("getRange-end", Long.MIN_VALUE, trace.getTimeRange().getEndTime().getValue()); + assertEquals("getStartTime", Long.MIN_VALUE, trace.getStartTime().getValue()); + assertEquals("getEndTime", Long.MIN_VALUE, trace.getEndTime().getValue()); + } + + @Test + public void testInitializeNormalPath() { + // Instantiate an "empty" trace + final TmfTraceStub trace = new TmfTraceStub(); + + // Path == trace name + String name = "TraceName"; + String path = "/my/trace/path/" + name; + try { + trace.initialize(null, path, ITmfEvent.class); + } catch (Exception e) { + fail("TmfTrace.initialize() - Exception thrown"); + } + + assertEquals("getType", ITmfEvent.class, trace.getType()); + assertNull ("getResource", trace.getResource()); + assertEquals("getPath", path, trace.getPath()); + assertEquals("getCacheSize", ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, trace.getCacheSize()); + assertEquals("getStreamingInterval", 0, trace.getStreamingInterval()); + assertEquals("getName", name, trace.getName()); + + assertEquals("getNbEvents", 0, trace.getNbEvents()); + assertEquals("getRange-start", Long.MIN_VALUE, trace.getTimeRange().getStartTime().getValue()); + assertEquals("getRange-end", Long.MIN_VALUE, trace.getTimeRange().getEndTime().getValue()); + assertEquals("getStartTime", Long.MIN_VALUE, trace.getStartTime().getValue()); + assertEquals("getEndTime", Long.MIN_VALUE, trace.getEndTime().getValue()); + } + + @Test + public void testInitTrace() throws URISyntaxException, IOException, TmfTraceException, InterruptedException { + // Instantiate an "empty" trace + final TmfTraceStub trace = new TmfTraceStub(); + + assertNull ("getType", trace.getType()); + assertNull ("getResource", trace.getResource()); + assertEquals("getCacheSize", ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, trace.getCacheSize()); + assertEquals("getStreamingInterval", 0, trace.getStreamingInterval()); + assertEquals("getName", "", trace.getName()); + + assertEquals("getNbEvents", 0, trace.getNbEvents()); + assertEquals("getRange-start", Long.MIN_VALUE, trace.getTimeRange().getStartTime().getValue()); + assertEquals("getRange-end", Long.MIN_VALUE, trace.getTimeRange().getEndTime().getValue()); + assertEquals("getStartTime", Long.MIN_VALUE, trace.getStartTime().getValue()); + assertEquals("getEndTime", Long.MIN_VALUE, trace.getEndTime().getValue()); + + // Validate + final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE.getFullPath()), null); + final File testfile = new File(FileLocator.toFileURL(location).toURI()); + assertTrue("validate", trace.validate(null, testfile.getPath()).isOK()); + + // InitTrace and wait for indexing completion... + trace.initTrace(null, testfile.toURI().getPath(), ITmfEvent.class); + trace.indexTrace(true); + int nbSecs = 0; + while (trace.getNbEvents() < NB_EVENTS && nbSecs < 10) { + Thread.sleep(1000); + nbSecs++; + } + if (trace.getNbEvents() < NB_EVENTS) { + fail("indexing"); + } + + assertEquals("getType", ITmfEvent.class, trace.getType()); + assertNull ("getResource", trace.getResource()); + assertEquals("getCacheSize", ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, trace.getCacheSize()); + assertEquals("getStreamingInterval", 0, trace.getStreamingInterval()); + assertEquals("getName", TEST_TRACE.getPath(), trace.getName()); + + assertEquals("getNbEvents", NB_EVENTS, trace.getNbEvents()); + assertEquals("getRange-start", 1, trace.getTimeRange().getStartTime().getValue()); + assertEquals("getRange-end", NB_EVENTS, trace.getTimeRange().getEndTime().getValue()); + assertEquals("getStartTime", 1, trace.getStartTime().getValue()); + assertEquals("getEndTime", NB_EVENTS, trace.getEndTime().getValue()); + } + + // ------------------------------------------------------------------------ + // Set/Get streaming interval + // ------------------------------------------------------------------------ + + @Test + public void testSetStreamingInterval() throws TmfTraceException { + final TmfTraceStub trace = new TmfTraceStub(fTrace); + + long interval = 0; + assertEquals("getStreamingInterval", interval, trace.getStreamingInterval()); + + interval = 100; + trace.setStreamingInterval(interval); + assertEquals("getStreamingInterval", interval, trace.getStreamingInterval()); + + interval = -1; + trace.setStreamingInterval(interval); + assertEquals("getStreamingInterval", 0, trace.getStreamingInterval()); + + interval = 0; + trace.setStreamingInterval(interval); + assertEquals("getStreamingInterval", interval, trace.getStreamingInterval()); + + trace.dispose(); + } + + // ------------------------------------------------------------------------ + // Set/Get time range + // ------------------------------------------------------------------------ + + @Test + public void testSetTimeRange() throws TmfTraceException { + final TmfTraceStub trace = new TmfTraceStub(fTrace); + trace.indexTrace(true); + + assertEquals("getRange-start", 1, trace.getTimeRange().getStartTime().getValue()); + assertEquals("getRange-end", NB_EVENTS, trace.getTimeRange().getEndTime().getValue()); + assertEquals("getStartTime", 1, trace.getStartTime().getValue()); + assertEquals("getEndTime", NB_EVENTS, trace.getEndTime().getValue()); + + trace.setTimeRange(new TmfTimeRange(new TmfTimestamp(100), new TmfTimestamp(200))); + assertEquals("setTimeRange", 100, trace.getTimeRange().getStartTime().getValue()); + assertEquals("setTimeRange", 200, trace.getTimeRange().getEndTime().getValue()); + assertEquals("setTimeRange", 100, trace.getStartTime().getValue()); + assertEquals("setTimeRange", 200, trace.getEndTime().getValue()); + + trace.dispose(); + } + + @Test + public void testSetStartTime() throws TmfTraceException { + final TmfTraceStub trace = new TmfTraceStub(fTrace); + trace.indexTrace(true); + + assertEquals("getRange-start", 1, trace.getTimeRange().getStartTime().getValue()); + assertEquals("getRange-end", NB_EVENTS, trace.getTimeRange().getEndTime().getValue()); + assertEquals("getStartTime", 1, trace.getStartTime().getValue()); + assertEquals("getEndTime", NB_EVENTS, trace.getEndTime().getValue()); + + trace.setStartTime(new TmfTimestamp(100)); + assertEquals("setStartTime", 100, trace.getTimeRange().getStartTime().getValue()); + assertEquals("setStartTime", NB_EVENTS, trace.getTimeRange().getEndTime().getValue()); + assertEquals("setStartTime", 100, trace.getStartTime().getValue()); + assertEquals("setStartTime", NB_EVENTS, trace.getEndTime().getValue()); + + trace.dispose(); + } + + @Test + public void testSetEndTime() throws TmfTraceException { + final TmfTraceStub trace = new TmfTraceStub(fTrace); + trace.indexTrace(true); + + assertEquals("getRange-start", 1, trace.getTimeRange().getStartTime().getValue()); + assertEquals("getRange-end", NB_EVENTS, trace.getTimeRange().getEndTime().getValue()); + assertEquals("getStartTime", 1, trace.getStartTime().getValue()); + assertEquals("getEndTime", NB_EVENTS, trace.getEndTime().getValue()); + + trace.setEndTime(new TmfTimestamp(100)); + assertEquals("setEndTime", 1, trace.getTimeRange().getStartTime().getValue()); + assertEquals("setEndTime", 100, trace.getTimeRange().getEndTime().getValue()); + assertEquals("setEndTime", 1, trace.getStartTime().getValue()); + assertEquals("setEndTime", 100, trace.getEndTime().getValue()); + + trace.dispose(); + } + + @Test + public void testSetNbEvents() throws TmfTraceException { + final TmfTraceStub trace = new TmfTraceStub(fTrace); + trace.indexTrace(true); + + assertEquals("getNbEvents", NB_EVENTS, trace.getNbEvents()); + + trace.setNbEvents(0); + assertEquals("getNbEvents", 0, trace.getNbEvents()); + + trace.setNbEvents(-1); + assertEquals("getNbEvents", 0, trace.getNbEvents()); + + trace.setNbEvents(NB_EVENTS + 1); + assertEquals("getNbEvents", NB_EVENTS + 1, trace.getNbEvents()); + + trace.setNbEvents(NB_EVENTS); + assertEquals("getNbEvents", NB_EVENTS, trace.getNbEvents()); + + trace.dispose(); + } + + // ------------------------------------------------------------------------ + // State system, statistics and modules methods + // ------------------------------------------------------------------------ + + @Test + public void testGetModulesByClass() { + /* There should not be any modules at this point */ + Iterable modules = fTrace.getAnalysisModules(); + assertFalse(modules.iterator().hasNext()); + + /* Open the trace, the modules should be populated */ + fTrace.traceOpened(new TmfTraceOpenedSignal(this, fTrace, null)); + + modules = fTrace.getAnalysisModules(); + Iterable testModules = fTrace.getAnalysisModulesOfClass(TestAnalysis.class); + assertTrue(modules.iterator().hasNext()); + assertTrue(testModules.iterator().hasNext()); + + /* + * Make sure all modules of type TestAnalysis are returned in the second + * call + */ + for (IAnalysisModule module : modules) { + if (module instanceof TestAnalysis) { + IAnalysisModule otherModule = fTrace.getAnalysisModule(module.getId()); + assertNotNull(otherModule); + assertTrue(otherModule.equals(module)); + } + } + + } + + // ------------------------------------------------------------------------ + // seekEvent on location (note: does not reliably set the rank) + // ------------------------------------------------------------------------ + + @Test + public void testSeekEventOnCacheBoundary() { + // Position trace at event rank 0 + ITmfContext context = fTrace.seekEvent(0); + ITmfEvent event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", 0, context.getRank()); + + context = fTrace.seekEvent(context.getLocation()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + // Position trace at event rank 1000 + ITmfContext tmpContext = fTrace.seekEvent(new TmfTimestamp(1001, SCALE, 0)); + context = fTrace.seekEvent(tmpContext.getLocation()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1001, event.getTimestamp().getValue()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 1001, event.getTimestamp().getValue()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + // Position trace at event rank 4000 + tmpContext = fTrace.seekEvent(new TmfTimestamp(4001, SCALE, 0)); + context = fTrace.seekEvent(tmpContext.getLocation()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 4001, event.getTimestamp().getValue()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 4001, event.getTimestamp().getValue()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + } + + @Test + public void testSeekEventNotOnCacheBoundary() { + // Position trace at event rank 9 + ITmfContext tmpContext = fTrace.seekEvent(new TmfTimestamp(10, SCALE, 0)); + TmfContext context = fTrace.seekEvent(tmpContext.getLocation()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + ITmfEvent event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + // Position trace at event rank 999 + tmpContext = fTrace.seekEvent(new TmfTimestamp(1000, SCALE, 0)); + context = fTrace.seekEvent(tmpContext.getLocation()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1000, event.getTimestamp().getValue()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 1000, event.getTimestamp().getValue()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + // Position trace at event rank 1001 + tmpContext = fTrace.seekEvent(new TmfTimestamp(1002, SCALE, 0)); + context = fTrace.seekEvent(tmpContext.getLocation()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1002, event.getTimestamp().getValue()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 1002, event.getTimestamp().getValue()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + // Position trace at event rank 4500 + tmpContext = fTrace.seekEvent(new TmfTimestamp(4501, SCALE, 0)); + context = fTrace.seekEvent(tmpContext.getLocation()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + } + + @Test + public void testSeekEventOutOfScope() { + // Position trace at beginning + ITmfContext tmpContext = fTrace.seekEvent(0); + ITmfContext context = fTrace.seekEvent(tmpContext.getLocation()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + ITmfEvent event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + // Position trace at event passed the end + context = fTrace.seekEvent(new TmfTimestamp(NB_EVENTS + 1, SCALE, 0)); + assertNull("Event timestamp", context.getLocation()); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + event = fTrace.getNext(context); + assertNull("Event", event); + } + + // ------------------------------------------------------------------------ + // seekEvent on timestamp (note: does not reliably set the rank) + // ------------------------------------------------------------------------ + + @Test + public void testSeekEventOnNullTimestamp() { + // Position trace at event rank 0 + ITmfContext context = fTrace.seekEvent((ITmfTimestamp) null); + assertEquals("Event rank", 0, context.getRank()); + + ITmfEvent event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", 0, context.getRank()); + } + + @Test + public void testSeekEventOnTimestampOnCacheBoundary() { + // Position trace at event rank 0 + ITmfContext context = fTrace.seekEvent(new TmfTimestamp(1, SCALE, 0)); + assertEquals("Event rank", 0, context.getRank()); + + ITmfEvent event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", 0, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", 1, context.getRank()); + + // Position trace at event rank 1000 + context = fTrace.seekEvent(new TmfTimestamp(1001, SCALE, 0)); + assertEquals("Event rank", 1000, context.getRank()); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1001, event.getTimestamp().getValue()); + assertEquals("Event rank", 1000, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 1001, event.getTimestamp().getValue()); + assertEquals("Event rank", 1001, context.getRank()); + + // Position trace at event rank 4000 + context = fTrace.seekEvent(new TmfTimestamp(4001, SCALE, 0)); + assertEquals("Event rank", 4000, context.getRank()); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 4001, event.getTimestamp().getValue()); + assertEquals("Event rank", 4000, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 4001, event.getTimestamp().getValue()); + assertEquals("Event rank", 4001, context.getRank()); + } + + @Test + public void testSeekEventOnTimestampNotOnCacheBoundary() { + // Position trace at event rank 1 + ITmfContext context = fTrace.seekEvent(new TmfTimestamp(2, SCALE, 0)); + assertEquals("Event rank", 1, context.getRank()); + + ITmfEvent event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 2, event.getTimestamp().getValue()); + assertEquals("Event rank", 1, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 2, event.getTimestamp().getValue()); + assertEquals("Event rank", 2, context.getRank()); + + // Position trace at event rank 9 + context = fTrace.seekEvent(new TmfTimestamp(10, SCALE, 0)); + assertEquals("Event rank", 9, context.getRank()); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); + assertEquals("Event rank", 9, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); + assertEquals("Event rank", 10, context.getRank()); + + // Position trace at event rank 999 + context = fTrace.seekEvent(new TmfTimestamp(1000, SCALE, 0)); + assertEquals("Event rank", 999, context.getRank()); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1000, event.getTimestamp().getValue()); + assertEquals("Event rank", 999, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 1000, event.getTimestamp().getValue()); + assertEquals("Event rank", 1000, context.getRank()); + + // Position trace at event rank 1001 + context = fTrace.seekEvent(new TmfTimestamp(1002, SCALE, 0)); + assertEquals("Event rank", 1001, context.getRank()); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1002, event.getTimestamp().getValue()); + assertEquals("Event rank", 1001, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 1002, event.getTimestamp().getValue()); + assertEquals("Event rank", 1002, context.getRank()); + + // Position trace at event rank 4500 + context = fTrace.seekEvent(new TmfTimestamp(4501, SCALE, 0)); + assertEquals("Event rank", 4500, context.getRank()); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); + assertEquals("Event rank", 4500, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); + assertEquals("Event rank", 4501, context.getRank()); + } + + @Test + public void testSeekEventOnTimestampOutOfScope() { + // Position trace at beginning + ITmfContext context = fTrace.seekEvent(new TmfTimestamp(-1, SCALE, 0)); + assertEquals("Event rank", 0, context.getRank()); + + ITmfEvent event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", 0, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", 1, context.getRank()); + + // Position trace at event passed the end + context = fTrace.seekEvent(new TmfTimestamp(NB_EVENTS + 1, SCALE, 0)); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", null, event); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", null, event); + assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); + } + + // ------------------------------------------------------------------------ + // seekEvent on rank + // ------------------------------------------------------------------------ + + @Test + public void testSeekEventOnNegativeRank() { + // Position trace at event rank 0 + ITmfContext context = fTrace.seekEvent(-1); + assertEquals("Event rank", 0, context.getRank()); + + ITmfEvent event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", 0, context.getRank()); + } + + @Test + public void testSeekOnRankOnCacheBoundary() { + // On lower bound, returns the first event (ts = 1) + ITmfContext context = fTrace.seekEvent(0); + assertEquals("Event rank", 0, context.getRank()); + + ITmfEvent event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", 0, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", 1, context.getRank()); + + // Position trace at event rank 1000 + context = fTrace.seekEvent(1000); + assertEquals("Event rank", 1000, context.getRank()); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1001, event.getTimestamp().getValue()); + assertEquals("Event rank", 1000, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 1001, event.getTimestamp().getValue()); + assertEquals("Event rank", 1001, context.getRank()); + + // Position trace at event rank 4000 + context = fTrace.seekEvent(4000); + assertEquals("Event rank", 4000, context.getRank()); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 4001, event.getTimestamp().getValue()); + assertEquals("Event rank", 4000, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 4001, event.getTimestamp().getValue()); + assertEquals("Event rank", 4001, context.getRank()); + } + + @Test + public void testSeekOnRankNotOnCacheBoundary() { + // Position trace at event rank 9 + ITmfContext context = fTrace.seekEvent(9); + assertEquals("Event rank", 9, context.getRank()); + + ITmfEvent event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); + assertEquals("Event rank", 9, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); + assertEquals("Event rank", 10, context.getRank()); + + // Position trace at event rank 999 + context = fTrace.seekEvent(999); + assertEquals("Event rank", 999, context.getRank()); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1000, event.getTimestamp().getValue()); + assertEquals("Event rank", 999, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 1000, event.getTimestamp().getValue()); + assertEquals("Event rank", 1000, context.getRank()); + + // Position trace at event rank 1001 + context = fTrace.seekEvent(1001); + assertEquals("Event rank", 1001, context.getRank()); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1002, event.getTimestamp().getValue()); + assertEquals("Event rank", 1001, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 1002, event.getTimestamp().getValue()); + assertEquals("Event rank", 1002, context.getRank()); + + // Position trace at event rank 4500 + context = fTrace.seekEvent(4500); + assertEquals("Event rank", 4500, context.getRank()); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); + assertEquals("Event rank", 4500, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); + assertEquals("Event rank", 4501, context.getRank()); + } + + @Test + public void testSeekEventOnRankOutOfScope() { + // Position trace at beginning + ITmfContext context = fTrace.seekEvent(-1); + assertEquals("Event rank", 0, context.getRank()); + + ITmfEvent event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", 0, context.getRank()); + + event = fTrace.getNext(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", 1, context.getRank()); + + // Position trace at event passed the end + context = fTrace.seekEvent(NB_EVENTS); + assertEquals("Event rank", NB_EVENTS, context.getRank()); + + event = fTrace.parseEvent(context); + assertNull("Event", event); + assertEquals("Event rank", NB_EVENTS, context.getRank()); + + event = fTrace.getNext(context); + assertNull("Event", event); + assertEquals("Event rank", NB_EVENTS, context.getRank()); + } + + // ------------------------------------------------------------------------ + // parseEvent - make sure parseEvent doesn't update the context + // ------------------------------------------------------------------------ + + @Test + public void testParseEvent() { + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 0) + final TmfContext context = (TmfContext) fTrace.seekEvent(new TmfTimestamp(0, SCALE, 0)); + TmfContext svContext = new TmfContext(context); + + ITmfEvent event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", 0, context.getRank()); + assertTrue("parseEvent", context.equals(svContext)); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", 0, context.getRank()); + assertTrue("parseEvent", context.equals(svContext)); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); + assertEquals("Event rank", 0, context.getRank()); + assertTrue("parseEvent", context.equals(svContext)); + + // Position the trace at event NB_READS + for (int i = 1; i < NB_READS; i++) { + event = fTrace.getNext(context); + assertEquals("Event timestamp", i, event.getTimestamp().getValue()); + } + + svContext = new TmfContext(context); + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", NB_READS, event.getTimestamp().getValue()); + assertEquals("Event rank", NB_READS -1 , context.getRank()); + assertTrue("parseEvent", context.equals(svContext)); + + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", NB_READS, event.getTimestamp().getValue()); + assertEquals("Event rank", NB_READS - 1, context.getRank()); + assertTrue("parseEvent", context.equals(svContext)); + } + + // ------------------------------------------------------------------------ + // getNext - updates the context + // ------------------------------------------------------------------------ + + @Test + public void testGetNextAfteSeekingOnTS_1() { + final long INITIAL_TS = 1; + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 1) + final ITmfContext context = fTrace.seekEvent(new TmfTimestamp(INITIAL_TS, SCALE, 0)); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fTrace.getNext(context); + assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + i, context.getRank()); + } + + // Make sure we stay positioned + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); + } + + @Test + public void testGetNextAfteSeekingOnTS_2() { + final long INITIAL_TS = 2; + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 500) + final ITmfContext context = fTrace.seekEvent(new TmfTimestamp(INITIAL_TS, SCALE, 0)); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fTrace.getNext(context); + assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + i, context.getRank()); + } + + // Make sure we stay positioned + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); + } + + @Test + public void testGetNextAfteSeekingOnTS_3() { + final long INITIAL_TS = 500; + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 500) + final ITmfContext context = fTrace.seekEvent(new TmfTimestamp(INITIAL_TS, SCALE, 0)); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fTrace.getNext(context); + assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + i, context.getRank()); + } + + // Make sure we stay positioned + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); + } + + @Test + public void testGetNextAfterSeekingOnRank_1() { + final long INITIAL_RANK = 0L; + final int NB_READS = 20; + + // On lower bound, returns the first event (rank = 0) + final ITmfContext context = fTrace.seekEvent(INITIAL_RANK); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fTrace.getNext(context); + assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); + } + + // Make sure we stay positioned + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); + } + + @Test + public void testGetNextAfterSeekingOnRank_2() { + final long INITIAL_RANK = 1L; + final int NB_READS = 20; + + // On lower bound, returns the first event (rank = 0) + final ITmfContext context = fTrace.seekEvent(INITIAL_RANK); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fTrace.getNext(context); + assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); + } + + // Make sure we stay positioned + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); + } + + @Test + public void testGetNextAfterSeekingOnRank_3() { + final long INITIAL_RANK = 500L; + final int NB_READS = 20; + + // On lower bound, returns the first event (rank = 0) + final ITmfContext context = fTrace.seekEvent(INITIAL_RANK); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fTrace.getNext(context); + assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); + } + + // Make sure we stay positioned + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); + } + + @Test + public void testGetNextAfterSeekingOnLocation_1() { + final ITmfLocation INITIAL_LOC = null; + final long INITIAL_TS = 1; + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 1) + final ITmfContext context = fTrace.seekEvent(INITIAL_LOC); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fTrace.getNext(context); + assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + i, context.getRank()); + } + + // Make sure we stay positioned + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); + assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); + } + + @Test + public void testGetNextAfterSeekingOnLocation_2() { + final ITmfLocation INITIAL_LOC = fTrace.seekEvent(1L).getLocation(); + final long INITIAL_TS = 2; + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 501) + final ITmfContext context = fTrace.seekEvent(INITIAL_LOC); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fTrace.getNext(context); + assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); + } + + // Make sure we stay positioned + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); + } + + @Test + public void testGetNextAfterSeekingOnLocation_3() { + final ITmfLocation INITIAL_LOC = fTrace.seekEvent(500L).getLocation(); + final long INITIAL_TS = 501; + final int NB_READS = 20; + + // On lower bound, returns the first event (ts = 501) + final ITmfContext context = fTrace.seekEvent(INITIAL_LOC); + + // Read NB_EVENTS + ITmfEvent event; + for (int i = 0; i < NB_READS; i++) { + event = fTrace.getNext(context); + assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); + } + + // Make sure we stay positioned + event = fTrace.parseEvent(context); + assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); + } + + @Test + public void testGetNextLocation() { + ITmfContext context1 = fTrace.seekEvent(0); + fTrace.getNext(context1); + ITmfLocation location = context1.getLocation(); + ITmfEvent event1 = fTrace.getNext(context1); + ITmfContext context2 = fTrace.seekEvent(location); + ITmfEvent event2 = fTrace.getNext(context2); + assertEquals("Event timestamp", event1.getTimestamp().getValue(), event2.getTimestamp().getValue()); + } + + @Test + public void testGetNextEndLocation() { + ITmfContext context1 = fTrace.seekEvent(fTrace.getNbEvents() - 1); + fTrace.getNext(context1); + ITmfLocation location = context1.getLocation(); + ITmfContext context2 = fTrace.seekEvent(location); + ITmfEvent event = fTrace.getNext(context2); + assertNull("Event", event); + } + + // ------------------------------------------------------------------------ + // processRequest + // ------------------------------------------------------------------------ + + @Test + public void testProcessEventRequestForAllEvents() throws InterruptedException { + final Vector requestedEvents = new Vector<>(); + + final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, + range, 0, NB_EVENTS, ExecutionType.FOREGROUND) { + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + requestedEvents.add(event); + } + }; + final ITmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); + providers[0].sendRequest(request); + request.waitForCompletion(); + + assertEquals("nbEvents", NB_EVENTS, requestedEvents.size()); + assertTrue("isCompleted", request.isCompleted()); + assertFalse("isCancelled", request.isCancelled()); + + // Ensure that we have distinct events. + // Don't go overboard: we are not validating the stub! + for (int i = 0; i < NB_EVENTS; i++) { + assertEquals("Distinct events", i + 1, requestedEvents.get(i).getTimestamp().getValue()); + } + } + + @Test + public void testProcessEventRequestForNbEvents() throws InterruptedException { + final int nbEvents = 1000; + final Vector requestedEvents = new Vector<>(); + + final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, + range, 0, nbEvents, ExecutionType.FOREGROUND) { + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + requestedEvents.add(event); + } + }; + final ITmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); + providers[0].sendRequest(request); + request.waitForCompletion(); + + assertEquals("nbEvents", nbEvents, requestedEvents.size()); + assertTrue("isCompleted", request.isCompleted()); + assertFalse("isCancelled", request.isCancelled()); + + // Ensure that we have distinct events. + // Don't go overboard: we are not validating the stub! + for (int i = 0; i < nbEvents; i++) { + assertEquals("Distinct events", i + 1, requestedEvents.get(i).getTimestamp().getValue()); + } + } + + @Test + public void testProcessEventRequestForSomeEvents() throws InterruptedException { + final long startTime = 100; + final int nbEvents = 1000; + final Vector requestedEvents = new Vector<>(); + + final TmfTimeRange range = new TmfTimeRange(new TmfTimestamp(startTime, SCALE), TmfTimestamp.BIG_CRUNCH); + final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, + range, 0, nbEvents, ExecutionType.FOREGROUND) { + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + requestedEvents.add(event); + } + }; + final ITmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); + providers[0].sendRequest(request); + request.waitForCompletion(); + + assertEquals("nbEvents", nbEvents, requestedEvents.size()); + assertTrue("isCompleted", request.isCompleted()); + assertFalse("isCancelled", request.isCancelled()); + + // Ensure that we have distinct events. + // Don't go overboard: we are not validating the stub! + for (int i = 0; i < nbEvents; i++) { + assertEquals("Distinct events", startTime + i, requestedEvents.get(i).getTimestamp().getValue()); + } + } + + @Test + public void testProcessEventRequestForOtherEvents() throws InterruptedException { + final int startIndex = 99; + final long startTime = 100; + final int nbEvents = 1000; + final Vector requestedEvents = new Vector<>(); + + final TmfTimeRange range = new TmfTimeRange(new TmfTimestamp(startTime, SCALE), TmfTimestamp.BIG_CRUNCH); + final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, + range, startIndex, nbEvents, ExecutionType.FOREGROUND) { + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + requestedEvents.add(event); + } + }; + final ITmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); + providers[0].sendRequest(request); + request.waitForCompletion(); + + assertEquals("nbEvents", nbEvents, requestedEvents.size()); + assertTrue("isCompleted", request.isCompleted()); + assertFalse("isCancelled", request.isCancelled()); + + // Ensure that we have distinct events. + // Don't go overboard: we are not validating the stub! + for (int i = 0; i < nbEvents; i++) { + assertEquals("Distinct events", startTime + i, requestedEvents.get(i).getTimestamp().getValue()); + } + } + + @Test + public void testProcessDataRequestForSomeEvents() throws InterruptedException { + final int startIndex = 100; + final int nbEvents = 1000; + final Vector requestedEvents = new Vector<>(); + + final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, + TmfTimeRange.ETERNITY, + startIndex, + nbEvents, + TmfEventRequest.ExecutionType.FOREGROUND) { + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + requestedEvents.add(event); + } + }; + final ITmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); + providers[0].sendRequest(request); + request.waitForCompletion(); + + assertEquals("nbEvents", nbEvents, requestedEvents.size()); + assertTrue("isCompleted", request.isCompleted()); + assertFalse("isCancelled", request.isCancelled()); + + // Ensure that we have distinct events. + // Don't go overboard: we are not validating the stub! + for (int i = 0; i < nbEvents; i++) { + assertEquals("Distinct events", startIndex + 1 + i, requestedEvents.get(i).getTimestamp().getValue()); + } + } + + // ------------------------------------------------------------------------ + // cancel + // ------------------------------------------------------------------------ + + @Test + public void testCancel() throws InterruptedException { + final int limit = 500; + final Vector requestedEvents = new Vector<>(); + + final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, + range, 0, NB_EVENTS, ExecutionType.FOREGROUND) { + int nbRead = 0; + + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + requestedEvents.add(event); + if (++nbRead == limit) { + cancel(); + } + } + }; + final ITmfEventProvider[] providers = TmfProviderManager.getProviders(ITmfEvent.class, TmfTraceStub.class); + providers[0].sendRequest(request); + request.waitForCompletion(); + + assertEquals("nbEvents", limit, requestedEvents.size()); + assertTrue("isCompleted", request.isCompleted()); + assertTrue("isCancelled", request.isCancelled()); + } + + // ------------------------------------------------------------------------ + // toString + // ------------------------------------------------------------------------ + + @Test + public void testDefaultTmfTraceStub() { + assertFalse ("Open trace", fTrace == null); + assertEquals("getType", ITmfEvent.class, fTrace.getType()); + assertNull ("getResource", fTrace.getResource()); + assertEquals("getStreamingInterval", 0, fTrace.getStreamingInterval()); + assertEquals("getName", TEST_TRACE.getPath(), fTrace.getName()); + + assertEquals("getNbEvents", NB_EVENTS, fTrace.getNbEvents()); + assertEquals("getRange-start", 1, fTrace.getTimeRange().getStartTime().getValue()); + assertEquals("getRange-end", NB_EVENTS, fTrace.getTimeRange().getEndTime().getValue()); + assertEquals("getStartTime", 1, fTrace.getStartTime().getValue()); + assertEquals("getEndTime", NB_EVENTS, fTrace.getEndTime().getValue()); + + String expected = "TmfTrace [fPath=" + fTrace.getPath() + ", fCacheSize=" + fTrace.getCacheSize() + + ", fNbEvents=" + fTrace.getNbEvents() + ", fStartTime=" + fTrace.getStartTime() + + ", fEndTime=" + fTrace.getEndTime() + ", fStreamingInterval=" + fTrace.getStreamingInterval() + + "]"; + assertEquals("toString", expected, fTrace.toString()); + } + + // ------------------------------------------------------------------------ + // getInitialRangeOffset, getCurrentRange, getCurrentTime + // ------------------------------------------------------------------------ + + @Test + public void testCurrentTimeValues() throws TmfTraceException { + + TmfTraceStub trace = null; + File testfile = null; + try { + final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE.getFullPath()), null); + testfile = new File(FileLocator.toFileURL(location).toURI()); + trace = new TmfTraceStub(testfile.toURI().getPath(), ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, false, null); + // verify initial values + TmfTimestamp defaultInitRange = new TmfTimestamp(DEFAULT_INITIAL_OFFSET_VALUE, ITmfTimestamp.NANOSECOND_SCALE); + assertEquals("getInitialRangeOffset", defaultInitRange, trace.getInitialRangeOffset()); + trace.setInitialRangeOffset(new TmfTimestamp(5, ITmfTimestamp.MILLISECOND_SCALE)); + trace.indexTrace(true); + + TmfTimestamp initRange = new TmfTimestamp(5, ITmfTimestamp.MILLISECOND_SCALE); + assertEquals("getInitialRangeOffset", initRange, trace.getInitialRangeOffset()); + + } catch (final URISyntaxException e) { + fail("URISyntaxException"); + } catch (final IOException e) { + fail("IOException"); + } + } + + /** + * Run the String getHostId() method test + */ + @Test + public void testTraceHostId() { + String a = fTrace.getHostId(); + assertEquals("A-Test-10K", a); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/AbstractCheckpointCollectionTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/AbstractCheckpointCollectionTest.java new file mode 100644 index 0000000000..22fff26e15 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/AbstractCheckpointCollectionTest.java @@ -0,0 +1,374 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.indexer; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.ArrayList; +import java.util.Random; + +import org.eclipse.tracecompass.internal.tmf.core.trace.indexer.ICheckpointCollection; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Common code for ICheckpointCollection test classes + * + * @author Marc-Andre Laperle + */ +public abstract class AbstractCheckpointCollectionTest { + + private static final String INDEX_FILE_NAME = "checkpoint.idx"; //$NON-NLS-1$ + + /** + * The number of checkpoints to be inserted in insert tests + */ + protected static final int CHECKPOINTS_INSERT_NUM = 50000; + /** + * The collection being tested + */ + protected ICheckpointCollection fCheckpointCollection = null; + + private TmfTraceStub fTrace; + private File fFile = new File(INDEX_FILE_NAME); + + /** + * Setup the test. Make sure the index is deleted. + */ + @Before + public void setUp() { + fTrace = new TmfTraceStub(); + if (fFile.exists()) { + fFile.delete(); + } + fCheckpointCollection = createCollection(); + } + + /** + * Tear down the test. Make sure the index is deleted. + */ + @After + public void tearDown() { + fTrace.dispose(); + fTrace = null; + if (fCheckpointCollection != null) { + fCheckpointCollection.dispose(); + } + if (fFile.exists()) { + fFile.delete(); + } + } + + /** + * Get the trace being tested. + * + * @return the trace being tested. + */ + public ITmfTrace getTrace() { + return fTrace; + } + + /** + * Returns whether or not the collection is persisted to disk + * + * @return true if the collection is persisted to disk, false otherwise + */ + public boolean isPersistableCollection() { + return false; + } + + /** + * Get the file used for the index being tested. + * + * @return the file used for the index being tested. + */ + public File getFile() { + return fFile; + } + + /** + * Test constructing a new checkpoint collection + */ + @Test + public void testConstructor() { + if (isPersistableCollection()) { + assertTrue(fFile.exists()); + } + assertTrue(fCheckpointCollection.isCreatedFromScratch()); + } + + /** + * Test constructing a new checkpoint collection, existing file + */ + @Test + public void testConstructorExistingFile() { + if (isPersistableCollection()) { + assertTrue(fFile.exists()); + fCheckpointCollection.setIndexComplete(); + fCheckpointCollection.dispose(); + + fCheckpointCollection = createCollection(); + assertFalse(fCheckpointCollection.isCreatedFromScratch()); + } + } + + /** + * Test that a new checkpoint collection is considered created from scratch + * and vice versa + */ + @Test + public void testIsCreatedFromScratch() { + assertTrue(fCheckpointCollection.isCreatedFromScratch()); + fCheckpointCollection.setIndexComplete(); + + if (isPersistableCollection()) { + fCheckpointCollection.dispose(); + fCheckpointCollection = createCollection(); + assertFalse(fCheckpointCollection.isCreatedFromScratch()); + } + } + + /** + * Test setTimeRange, getTimeRange + */ + @Test + public void testSetGetTimeRange() { + if (isPersistableCollection()) { + TmfTimeRange timeRange = new TmfTimeRange(new TmfTimestamp(0), new TmfTimestamp(100)); + fCheckpointCollection.setTimeRange(timeRange); + assertEquals(timeRange, fCheckpointCollection.getTimeRange()); + } + } + + /** + * Create a collection for the test + * + * @return the collection + */ + abstract protected ICheckpointCollection createCollection(); + + /** + * Test setNbEvents, getNbEvents + */ + @Test + public void testSetGetNbEvents() { + if (isPersistableCollection()) { + int expected = 12345; + fCheckpointCollection.setNbEvents(expected); + assertEquals(expected, fCheckpointCollection.getNbEvents()); + } + } + + /** + * Test setSize, size + */ + @Test + public void testSetGetSize() { + assertEquals(0, fCheckpointCollection.size()); + int expected = CHECKPOINTS_INSERT_NUM; + for (int i = 0; i < expected; ++i) { + fCheckpointCollection.insert(new TmfCheckpoint(new TmfTimestamp(0), new TmfLongLocation(0L), 0)); + } + assertEquals(expected, fCheckpointCollection.size()); + } + + /** + * Test delete + */ + @Test + public void testDelete() { + if (isPersistableCollection()) { + assertTrue(fFile.exists()); + fCheckpointCollection.delete(); + assertFalse(fFile.exists()); + } + } + + /** + * Test version change + * + * @throws IOException + * can throw this + */ + @Test + public void testVersionChange() throws IOException { + fCheckpointCollection.setIndexComplete(); + fCheckpointCollection.dispose(); + try (RandomAccessFile f = new RandomAccessFile(fFile, "rw");) { + f.writeInt(-1); + } + + fCheckpointCollection = createCollection(); + assertTrue(fCheckpointCollection.isCreatedFromScratch()); + } + + /** + * Test a single insertion + */ + @Test + public void testInsert() { + TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345), new TmfLongLocation(123456L), 0); + fCheckpointCollection.insert(checkpoint); + + long found = fCheckpointCollection.binarySearch(checkpoint); + assertEquals(0, found); + } + + /** + * Generate many checkpoints and insert them in the collection + * + * @return the list of generated checkpoints + */ + protected ArrayList insertAlot() { + for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { + TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345 + i), new TmfLongLocation(123456L + i), i); + fCheckpointCollection.insert(checkpoint); + } + + fCheckpointCollection.setIndexComplete(); + if (isPersistableCollection()) { + fCheckpointCollection.dispose(); + } + + boolean random = true; + ArrayList list = new ArrayList<>(); + for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { + if (random) { + Random rand = new Random(); + list.add(rand.nextInt(CHECKPOINTS_INSERT_NUM)); + } else { + list.add(i); + } + } + return list; + } + + /** + * Test many checkpoint insertions. Make sure they can be found after + * re-opening the file + */ + @Test + public void testInsertAlot() { + ArrayList list = insertAlot(); + + if (isPersistableCollection()) { + fCheckpointCollection = createCollection(); + } + + for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { + Integer randomCheckpoint = list.get(i); + TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345 + randomCheckpoint), new TmfLongLocation(123456L + randomCheckpoint), 0); + long found = fCheckpointCollection.binarySearch(checkpoint); + assertEquals(randomCheckpoint.intValue(), found); + } + } + + /** + * Test many checkpoint insertions using the same timestamp. Make sure they + * can be found after re-opening the file + */ + @Test + public void testInsertSameTimestamp() { + for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { + TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345), new TmfLongLocation(123456L + i), i); + fCheckpointCollection.insert(checkpoint); + } + + fCheckpointCollection.setIndexComplete(); + if (isPersistableCollection()) { + fCheckpointCollection.dispose(); + } + + boolean random = true; + ArrayList list = new ArrayList<>(); + for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { + if (random) { + Random rand = new Random(); + list.add(rand.nextInt(CHECKPOINTS_INSERT_NUM)); + } else { + list.add(i); + } + } + + if (isPersistableCollection()) { + fCheckpointCollection = createCollection(); + } + + for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { + Integer randomCheckpoint = list.get(i); + TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345), new TmfLongLocation(123456L + randomCheckpoint), 0); + long found = fCheckpointCollection.binarySearch(checkpoint); + assertEquals(randomCheckpoint.intValue(), found); + } + } + + /** + * Tests that binarySearch find the correct checkpoint when the time stamp + * is between checkpoints + */ + @Test + public void testBinarySearchFindInBetween() { + for (long i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { + TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(2 * i), new TmfLongLocation(2 * i), i); + fCheckpointCollection.insert(checkpoint); + } + + TmfCheckpoint searchedCheckpoint = new TmfCheckpoint(new TmfTimestamp(123), new TmfLongLocation(123L), 123); + int expectedInsertionPoint = 61; + int expectedRank = -(expectedInsertionPoint + 2); + + long rank = fCheckpointCollection.binarySearch(searchedCheckpoint); + assertEquals(expectedRank, rank); + } + + + /** + * Tests that binarySearch finds the correct checkpoint when searching for a + * checkpoint with a null location. It should return the previous checkpoint + * from the first checkpoint that matches the timestamp. + */ + @Test + public void testBinarySearchInBetweenSameTimestamp() { + int checkpointNum = 0; + for (; checkpointNum < 100; checkpointNum++) { + TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(0), new TmfLongLocation(checkpointNum), checkpointNum); + fCheckpointCollection.insert(checkpoint); + } + + for (; checkpointNum < 200; checkpointNum++) { + TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(1), new TmfLongLocation(checkpointNum), checkpointNum); + fCheckpointCollection.insert(checkpoint); + } + + final TmfCheckpoint searchedCheckpoint = new TmfCheckpoint(new TmfTimestamp(1), null, 0); + + long found = fCheckpointCollection.binarySearch(searchedCheckpoint); + + int expectedInsertionPoint = 99; + int expectedRank = -(expectedInsertionPoint + 2); + + assertEquals(expectedRank, found); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/AllBench.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/AllBench.java new file mode 100644 index 0000000000..7c6e587293 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/AllBench.java @@ -0,0 +1,251 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.indexer; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.ArrayList; +import java.util.Random; + +import org.eclipse.tracecompass.internal.tmf.core.trace.indexer.BTree; +import org.eclipse.tracecompass.internal.tmf.core.trace.indexer.BTreeCheckpointVisitor; +import org.eclipse.tracecompass.internal.tmf.core.trace.indexer.FlatArray; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; + +/** + * A class to benchmark different algoritms for storing the + * checkpoint index on disk + * + * @author Marc-Andre Laperle + */ +public class AllBench { + + private static final boolean reportProgress = true; + private static ArrayList> nums; + private TmfTraceStub fTrace; + private File file = new File("index.idx"); + + static int BTREE_DEGREE = 10; + + private void setUp() { + fTrace = new TmfTraceStub(); + if (file.exists()) { + file.delete(); + } + } + + private void tearDown() { + fTrace.dispose(); + fTrace = null; + if (file.exists()) { + file.delete(); + } + } + + private static void generateDataFile(ArrayList list, int checkpointsNums) throws IOException { + File randomDataFile = new File("data" + checkpointsNums); + try (RandomAccessFile f = new RandomAccessFile(randomDataFile, "rw");) { + if (randomDataFile.exists()) { + for (int i = 0; i < checkpointsNums; i++) { + Random rand = new Random(); + int nextInt = rand.nextInt(checkpointsNums); + list.add(nextInt); + f.writeInt(nextInt); + } + } else { + for (int i = 0; i < checkpointsNums; i++) { + list.add(f.readInt()); + } + } + } + } + + @SuppressWarnings("javadoc") + public static void main(String[] args) throws IOException { + int checkpointsNums [] = new int [] { 5000, 50000, 500000, 1000000 }; + nums = new ArrayList<>(checkpointsNums.length); + + System.out.println("DEGREE: " + BTREE_DEGREE); + + AllBench b = new AllBench(); + b.setUp(); + for (int i = 0; i < checkpointsNums.length; i++) { + ArrayList list = new ArrayList<>(); + generateDataFile(list, checkpointsNums[i]); + nums.add(list); + + System.out.println("*** " + checkpointsNums[i] + " checkpoints ***\n"); + + b.benchIt(list); + } + b.tearDown(); + } + + private void benchIt(ArrayList list) { + + System.out.println("Testing BTree\n"); + + testInsertAlot(list); + + System.out.println("Testing Array\n"); + + testInsertAlotArray(list); + } + + private void testInsertAlot(ArrayList list2) { + int checkpointsNum = list2.size(); + + writeCheckpoints(checkpointsNum); + + ArrayList list = new ArrayList<>(); + for (int i = 0; i < checkpointsNum; i++) { + list.add(i); + } + + readCheckpoints(checkpointsNum, list, false); + readCheckpoints(checkpointsNum, list2, true); + + file.delete(); + + System.out.println(); + } + + private void testInsertAlotArray(ArrayList list2) { + int checkpointsNum = list2.size(); + + writeCheckpointsArray(checkpointsNum); + + ArrayList list = new ArrayList<>(); + for (int i = 0; i < checkpointsNum; i++) { + list.add(i); + } + + readCheckpointsArray(checkpointsNum, list, false); + readCheckpointsArray(checkpointsNum, list2, true); + + file.delete(); + + System.out.println(); + } + + private void writeCheckpoints(int checkpointsNum) { + BTree bTree; + int REPEAT = 10; + long time = 0; + for (int j = 0; j < REPEAT; j++) { + long old = System.currentTimeMillis(); + bTree = new BTree(BTREE_DEGREE, file, fTrace); + for (int i = 0; i < checkpointsNum; i++) { + TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345 + i), new TmfLongLocation(123456L + i), i); + bTree.insert(checkpoint); + } + + time += (System.currentTimeMillis() - old); + bTree.setIndexComplete(); + bTree.dispose(); + if (j != REPEAT - 1) { + file.delete(); + } + if (reportProgress) { + System.out.print("."); + } + } + + System.out.println("Write time average: " + (float) time / REPEAT); + } + + private void writeCheckpointsArray(int checkpointsNum) { + FlatArray array; + int REPEAT = 10; + long time = 0; + for (int j = 0; j < REPEAT; j++) { + long old = System.currentTimeMillis(); + array = new FlatArray(file, fTrace); + for (int i = 0; i < checkpointsNum; i++) { + TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345 + i), new TmfLongLocation(123456L + i), i); + array.insert(checkpoint); + } + + time += (System.currentTimeMillis() - old); + array.setIndexComplete(); + array.dispose(); + if (j != REPEAT - 1) { + file.delete(); + } + if (reportProgress) { + System.out.print("."); + } + } + + System.out.println("Write time average: " + (float) time / REPEAT); + } + + + private void readCheckpoints(int checkpointsNum, ArrayList list, boolean random) { + BTree bTree; + int REPEAT = 10; + long time = 0; + long cacheMisses = 0; + for (int j = 0; j < REPEAT; j++) { + long old = System.currentTimeMillis(); + bTree = new BTree(BTREE_DEGREE, file, fTrace); + for (int i = 0; i < checkpointsNum; i++) { + Integer randomCheckpoint = list.get(i); + TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345 + randomCheckpoint), new TmfLongLocation(123456L + randomCheckpoint), 0); + BTreeCheckpointVisitor treeVisitor = new BTreeCheckpointVisitor(checkpoint); + bTree.accept(treeVisitor); + assertEquals(randomCheckpoint.intValue(), treeVisitor.getCheckpoint().getCheckpointRank()); + } + time += (System.currentTimeMillis() - old); + cacheMisses = bTree.getCacheMisses(); + bTree.dispose(); + if (reportProgress) { + System.out.print("."); + } + } + + System.out.println("Read " + (random ? "(random)" : "(linear)") + "time average: " + (float) time / REPEAT + " (cache miss: " + cacheMisses + ")"); + } + + private void readCheckpointsArray(int checkpointsNum, ArrayList list, boolean random) { + FlatArray array; + int REPEAT = 10; + long time = 0; + long cacheMisses = 0; + for (int j = 0; j < REPEAT; j++) { + long old = System.currentTimeMillis(); + array = new FlatArray(file, fTrace); + for (int i = 0; i < checkpointsNum; i++) { + Integer randomCheckpoint = list.get(i); + TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345 + randomCheckpoint), new TmfLongLocation(123456L + randomCheckpoint), 0); + long found = array.binarySearch(checkpoint); + assertEquals(randomCheckpoint.intValue(), found); + } + time += (System.currentTimeMillis() - old); + cacheMisses = array.getCacheMisses(); + array.dispose(); + if (reportProgress) { + System.out.print("."); + } + } + + System.out.println("Read " + (random ? "(random)" : "(linear)") + "time average: " + (float) time / REPEAT + " (cache miss: " + cacheMisses + ")"); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/AllTests.java new file mode 100644 index 0000000000..8652898ba5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/AllTests.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.indexer; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite indexer classes + * + * @author Marc-Andre Laperle + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + BTreeTest.class, + FlatArrayTest.class, + TmfMemoryIndexTest.class +}) +public class AllTests { + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/BTreeTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/BTreeTest.java new file mode 100644 index 0000000000..7763c480c0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/BTreeTest.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.indexer; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; + +import org.eclipse.tracecompass.internal.tmf.core.trace.indexer.BTree; +import org.eclipse.tracecompass.internal.tmf.core.trace.indexer.BTreeCheckpointVisitor; +import org.eclipse.tracecompass.internal.tmf.core.trace.indexer.IBTreeVisitor; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfPersistentlyIndexable; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; +import org.junit.Test; + +/** + * Tests for the BTree class + * + * @author Marc-Andre Laperle + */ +public class BTreeTest extends AbstractCheckpointCollectionTest { + + private final int DEGREE = 15; + private BTree fBTree; + + @Override + protected BTree createCollection() { + fCheckpointCollection = fBTree = new BTree(DEGREE, getFile(), (ITmfPersistentlyIndexable) getTrace()); + return fBTree; + } + + @Override + public boolean isPersistableCollection() { + return true; + } + + /** + * Tests that accepts find the correct checkpoint and ends with a perfect + * match + */ + @Test + public void testAccept() { + for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { + TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(i), new TmfLongLocation(i), 0); + fBTree.insert(checkpoint); + } + + final TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(123), new TmfLongLocation(123L), 0); + + class TestVisitor implements IBTreeVisitor { + public int fLastCompare = 0; + ITmfCheckpoint fFoundCheckpoint; + + @Override + public int compare(ITmfCheckpoint checkRec) { + fLastCompare = checkRec.compareTo(checkpoint); + if (fLastCompare == 0) { + fFoundCheckpoint = checkRec; + } + return fLastCompare; + } + } + final TestVisitor t = new TestVisitor(); + + fBTree.accept(t); + + assertEquals(checkpoint, t.fFoundCheckpoint); + assertEquals(0, t.fLastCompare); + } + + /** + * Test many checkpoint insertions. Make sure they can be found after + * re-opening the file + */ + @Test + public void testInsertAlotCheckEquals() { + ArrayList list = insertAlot(); + + fBTree = createCollection(); + + for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { + Integer checkpointIndex = list.get(i); + TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345 + checkpointIndex), new TmfLongLocation(123456L + checkpointIndex), 0); + BTreeCheckpointVisitor treeVisitor = new BTreeCheckpointVisitor(checkpoint); + fBTree.accept(treeVisitor); + assertEquals(checkpoint, treeVisitor.getCheckpoint()); + } + } + + /** + * Test setSize, size + */ + @Override + @Test + public void testSetGetSize() { + assertEquals(0, fBTree.size()); + int expected = CHECKPOINTS_INSERT_NUM; + for (int i = 0; i < expected; ++i) { + fBTree.insert(new TmfCheckpoint(new TmfTimestamp(0), new TmfLongLocation(0L), 0)); + fBTree.setSize(fBTree.size() + 1); + } + assertEquals(expected, fBTree.size()); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/FlatArrayTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/FlatArrayTest.java new file mode 100644 index 0000000000..4774586182 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/FlatArrayTest.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.indexer; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; + +import org.eclipse.tracecompass.internal.tmf.core.trace.indexer.FlatArray; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfPersistentlyIndexable; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; +import org.junit.Test; + +/** + * Tests for the FlatArray class + * + * @author Marc-Andre Laperle + */ +public class FlatArrayTest extends AbstractCheckpointCollectionTest { + + private FlatArray fFlatArray; + + @Override + protected FlatArray createCollection() { + fCheckpointCollection = fFlatArray = new FlatArray(getFile(), (ITmfPersistentlyIndexable) getTrace()); + return fFlatArray; + } + + @Override + public boolean isPersistableCollection() { + return true; + } + + /** + * Tests that binarySearch find the correct checkpoint and ends with a + * perfect match + */ + @Test + public void testBinarySearch() { + for (long i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { + TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(i), new TmfLongLocation(i), 0); + fFlatArray.insert(checkpoint); + } + + TmfCheckpoint expectedCheckpoint = new TmfCheckpoint(new TmfTimestamp(122), new TmfLongLocation(122L), 0); + int expectedRank = 122; + + long rank = fFlatArray.binarySearch(expectedCheckpoint); + ITmfCheckpoint found = fFlatArray.get(rank); + + assertEquals(expectedRank, rank); + assertEquals(found, expectedCheckpoint); + } + + /** + * Test many checkpoint insertions. Make sure they can be found after + * re-opening the file + */ + @Test + public void testInsertAlotCheckEquals() { + ArrayList list = insertAlot(); + + fFlatArray = createCollection(); + + for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { + int checkpointIndex = list.get(i); + TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345 + checkpointIndex), + new TmfLongLocation(123456L + checkpointIndex), checkpointIndex); + ITmfCheckpoint found = fFlatArray.get(checkpointIndex); + assertEquals(checkpoint, found); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/TmfMemoryIndexTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/TmfMemoryIndexTest.java new file mode 100644 index 0000000000..698085dfc6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/TmfMemoryIndexTest.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.indexer; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.eclipse.tracecompass.internal.tmf.core.trace.indexer.TmfMemoryIndex; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; +import org.junit.Test; + +/** + * Test for the TmfMemoryIndex class + * + * @author Marc-Andre Laperle + */ +public class TmfMemoryIndexTest extends AbstractCheckpointCollectionTest { + + private TmfMemoryIndex fMemoryIndex; + + @Override + protected TmfMemoryIndex createCollection() { + fCheckpointCollection = fMemoryIndex = new TmfMemoryIndex(getTrace()); + return fMemoryIndex; + } + + /** + * Test a single insertion + */ + @Override + @Test + public void testInsert() { + TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345), new TmfLongLocation(123456L), 0); + fMemoryIndex.insert(checkpoint); + + ITmfCheckpoint indexCheckpoint = fMemoryIndex.get(0); + assertEquals(checkpoint, indexCheckpoint); + + long found = fMemoryIndex.binarySearch(checkpoint); + assertEquals(0, found); + } + + /** + * Tests that binarySearch find the correct checkpoint and ends with a perfect match + */ + @Test + public void testBinarySearch() { + for (long i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { + TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(i), new TmfLongLocation(i), 0); + fMemoryIndex.insert(checkpoint); + } + + TmfCheckpoint expectedCheckpoint = new TmfCheckpoint(new TmfTimestamp(122), new TmfLongLocation(122L), 0); + int expectedRank = 122; + + long rank = fMemoryIndex.binarySearch(expectedCheckpoint); + ITmfCheckpoint found = fMemoryIndex.get(rank); + + assertEquals(expectedRank, rank); + assertEquals(found, expectedCheckpoint); + } + + /** + * Test dispose + */ + @Test + public void testDispose() { + fMemoryIndex.dispose(); + assertTrue(fMemoryIndex.isEmpty()); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/AbstractIndexTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/AbstractIndexTest.java new file mode 100644 index 0000000000..90a14e82e4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/AbstractIndexTest.java @@ -0,0 +1,283 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Adapted for TMF Trace Model 1.0 + * Alexandre Montplaisir - Port to JUnit4 + * Marc-Andre Laperle - Extracted to a common class from TmfCheckpointIndexTest + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.indexer.checkpoint; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.tests.TmfCoreTestPlugin; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfContext; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfEmptyTraceStub; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Common code for index testing + * + * @author Marc-Andre Laperle + */ +public abstract class AbstractIndexTest { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + /** + * + */ + protected static final int BLOCK_SIZE = 100; + private static final int NB_EVENTS = 10000; + /** + * The trace being tested + */ + protected static TestTrace fTrace = null; + private static EmptyTestTrace fEmptyTrace = null; + + // ------------------------------------------------------------------------ + // Housekeeping + // ------------------------------------------------------------------------ + + /** + * Setup the test + */ + @Before + public void setUp() { + setupTrace(getTracePath()); + } + + /** + * Get the trace path + * + * @return the trace path + */ + protected String getTracePath() { + return TmfTestTrace.A_TEST_10K.getFullPath(); + } + + /** + * Tear down the test + */ + @After + public void tearDown() { + fTrace.dispose(); + fTrace = null; + fEmptyTrace.dispose(); + fEmptyTrace = null; + } + + interface TestIndexerInterface extends ITmfTraceIndexer { + ITmfCheckpointIndex getCheckpoints(); + } + + // ------------------------------------------------------------------------ + // Helper classes + // ------------------------------------------------------------------------ + + /** + * A test indexer + */ + protected static class TestIndexer extends TmfCheckpointIndexer implements TestIndexerInterface { + /** + * Constructs the test indexer for a normal test trace + * + * @param testTrace + * the test trace + */ + public TestIndexer(ITmfTrace testTrace) { + super(testTrace, BLOCK_SIZE); + } + + @Override + public ITmfCheckpointIndex getCheckpoints() { + return getTraceIndex(); + } + } + + /** + * Create the indexer for testing + * + * @param trace + * the trace + * @return the indexer for testing + */ + protected TestIndexerInterface createTestIndexer(TestTrace trace) { + return new TestIndexer(trace); + } + + /** + * A test trace + */ + protected class TestTrace extends TmfTraceStub { + /** + * + * @param path + * the path + * @param blockSize + * the block size + * @throws TmfTraceException + * when error occurs + */ + public TestTrace(String path, int blockSize) throws TmfTraceException { + super(path, blockSize, false, null); + } + + @Override + protected ITmfTraceIndexer createIndexer(int interval) { + return createTestIndexer(this); + } + + @Override + public TestIndexerInterface getIndexer() { + return (TestIndexerInterface) super.getIndexer(); + } + } + + private class EmptyTestTrace extends TmfEmptyTraceStub { + public EmptyTestTrace() { + super(); + init(getClass().getSimpleName(), TmfEvent.class); + } + + @Override + protected ITmfTraceIndexer createIndexer(int interval) { + return new TestIndexer(this); + } + + @Override + public TestIndexer getIndexer() { + return (TestIndexer) super.getIndexer(); + } + } + + // ------------------------------------------------------------------------ + // Helper functions + // ------------------------------------------------------------------------ + + /** + * Creates the trace for the specified path + * + * @param path + * the path + * @return the created trace + * @throws URISyntaxException + * when error occurs + * @throws IOException + * when error occurs + * @throws TmfTraceException + * when error occurs + */ + protected TestTrace createTrace(final String path) throws URISyntaxException, IOException, TmfTraceException { + final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(path), null); + final File test = new File(FileLocator.toFileURL(location).toURI()); + TestTrace trace = new TestTrace(test.toURI().getPath(), BLOCK_SIZE); + trace.indexTrace(true); + return trace; + } + + private synchronized void setupTrace(final String path) { + if (fTrace == null) { + try { + fTrace = createTrace(path); + } catch (final TmfTraceException e) { + fail(e.getMessage()); + } catch (final URISyntaxException e) { + fail(e.getMessage()); + } catch (final IOException e) { + fail(e.getMessage()); + } + } + + if (fEmptyTrace == null) { + fEmptyTrace = new EmptyTestTrace(); + fEmptyTrace.indexTrace(true); + } + } + + // ------------------------------------------------------------------------ + // Verify checkpoints + // ------------------------------------------------------------------------ + + /** + * Test the content of the index after building the full index + */ + @Test + public void testTmfTraceIndexing() { + verifyIndexContent(); + } + + /** + * Verify the content of the index + */ + protected static void verifyIndexContent() { + assertEquals(BLOCK_SIZE, fTrace.getCacheSize()); + assertEquals(NB_EVENTS, fTrace.getNbEvents()); + assertEquals(1, fTrace.getTimeRange().getStartTime().getValue()); + assertEquals(NB_EVENTS, fTrace.getTimeRange().getEndTime().getValue()); + assertEquals(1, fTrace.getStartTime().getValue()); + assertEquals(NB_EVENTS, fTrace.getEndTime().getValue()); + + ITmfCheckpointIndex checkpoints = fTrace.getIndexer().getCheckpoints(); + int pageSize = fTrace.getCacheSize(); + assertTrue(checkpoints != null); + assertEquals(NB_EVENTS / BLOCK_SIZE, checkpoints.size()); + + // Validate that each checkpoint points to the right event + for (int i = 0; i < checkpoints.size(); i++) { + ITmfCheckpoint checkpoint = checkpoints.get(i); + TmfContext context = new TmfContext(checkpoint.getLocation(), i * pageSize); + ITmfEvent event = fTrace.parseEvent(context); + assertEquals(context.getRank(), i * pageSize); + assertTrue((checkpoint.getTimestamp().compareTo(event.getTimestamp(), false) == 0)); + } + } + + /** + * Test that a empty trace has the correct content + */ + @Test + public void testEmptyTmfTraceIndexing() { + assertEquals(ITmfTrace.DEFAULT_TRACE_CACHE_SIZE, fEmptyTrace.getCacheSize()); + assertEquals(0, fEmptyTrace.getNbEvents()); + assertEquals(TmfTimestamp.BIG_BANG, fEmptyTrace.getTimeRange().getStartTime()); + assertEquals(TmfTimestamp.BIG_BANG, fEmptyTrace.getTimeRange().getEndTime()); + assertEquals(TmfTimestamp.BIG_BANG, fEmptyTrace.getStartTime()); + assertEquals(TmfTimestamp.BIG_BANG, fEmptyTrace.getEndTime()); + + ITmfCheckpointIndex checkpoints = fEmptyTrace.getIndexer().getCheckpoints(); + assertTrue(checkpoints != null); + assertEquals(0, checkpoints.size()); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/AllTests.java new file mode 100644 index 0000000000..1bc820d9b4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/AllTests.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.indexer.checkpoint; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TmfBTreeIndexTest.class, + TmfCheckpointIndexTest.class, + TmfCheckpointIndexTest2.class, + TmfCheckpointTest.class, + TmfExperimentCheckpointIndexTest.class, +}) +public class AllTests {} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfBTreeIndexTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfBTreeIndexTest.java new file mode 100644 index 0000000000..9b71726d31 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfBTreeIndexTest.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Adapted for TMF Trace Model 1.0 + * Alexandre Montplaisir - Port to JUnit4 + * Marc-Andre Laperle - Adapted to BTree indexer from TmfCheckpointIndexTest + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.indexer.checkpoint; + +import static org.junit.Assert.assertFalse; + +import org.eclipse.tracecompass.tmf.core.trace.indexer.TmfBTreeTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; +import org.junit.Test; + +/** + * Test suite for the TmfBTreeTraceIndexer class. + * + * @author Marc-Andre Laperle + */ +public class TmfBTreeIndexTest extends AbstractIndexTest { + + /** + * Create the indexer for testing + * + * @param trace + * the trace + * @return the indexer for testing + */ + @Override + protected TestIndexerInterface createTestIndexer(TestTrace trace) { + return new TestBTreeIndexer(trace); + } + + private static class TestBTreeIndexer extends TmfBTreeTraceIndexer implements TestIndexerInterface { + public TestBTreeIndexer(TestTrace testTrace) { + super(testTrace, BLOCK_SIZE); + } + + @Override + public ITmfCheckpointIndex getCheckpoints() { + return getTraceIndex(); + } + } + + /** + * Test that a fully built index has the same content when reloaded from disk + * + * @throws Exception when error occurs + */ + @Test + public void testReopenIndex() throws Exception { + fTrace.dispose(); + fTrace = createTrace(getTracePath()); + assertFalse(fTrace.getIndexer().getCheckpoints().isCreatedFromScratch()); + fTrace.indexTrace(true); + + verifyIndexContent(); + } + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointIndexTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointIndexTest.java new file mode 100644 index 0000000000..afa0d857c9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointIndexTest.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Adapted for TMF Trace Model 1.0 + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.indexer.checkpoint; + + +/** + * Test suite for the TmfCheckpointIndexTest class. + */ +public class TmfCheckpointIndexTest extends AbstractIndexTest { + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointIndexTest2.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointIndexTest2.java new file mode 100644 index 0000000000..895c644705 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointIndexTest2.java @@ -0,0 +1,236 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.indexer.checkpoint; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.tests.TmfCoreTestPlugin; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfEmptyTraceStub; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Test suite for the TmfCheckpointIndexer class (events with same + * timestamp around checkpoint). + */ +@SuppressWarnings("javadoc") +public class TmfCheckpointIndexTest2 { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + private static final int BLOCK_SIZE = 100; + private static final int NB_EVENTS = 702; + private static TestTrace fTrace = null; + private static EmptyTestTrace fEmptyTrace = null; + + // ------------------------------------------------------------------------ + // Housekeeping + // ------------------------------------------------------------------------ + + @Before + public void setUp() { + // Trace has 3 events at t=101 at rank 99, 100, 101 + // Trace has events with same timestamp (ts=102) for ranks 102..702 -> 2 checkpoints with same timestamp are created + setupTrace(TmfTestTrace.A_TEST_10K2.getFullPath()); + } + + @After + public void tearDown() { + fTrace.dispose(); + fTrace = null; + fEmptyTrace.dispose(); + fEmptyTrace = null; + } + + // ------------------------------------------------------------------------ + // Helper classes + // ------------------------------------------------------------------------ + + private static class TestIndexer extends TmfCheckpointIndexer { + @SuppressWarnings({ }) + public TestIndexer(TestTrace testTrace) { + super(testTrace, BLOCK_SIZE); + } + @SuppressWarnings({ }) + public TestIndexer(EmptyTestTrace testTrace) { + super(testTrace, BLOCK_SIZE); + } + public ITmfCheckpointIndex getCheckpoints() { + return getTraceIndex(); + } + } + + private class TestTrace extends TmfTraceStub { + public TestTrace(String path, int blockSize) throws TmfTraceException { + super(path, blockSize, false, null); + } + + @Override + protected ITmfTraceIndexer createIndexer(int interval) { + return new TestIndexer(this); + } + + @Override + public TestIndexer getIndexer() { + return (TestIndexer) super.getIndexer(); + } + } + + private class EmptyTestTrace extends TmfEmptyTraceStub { + + public EmptyTestTrace() { + super(); + init(getClass().getSimpleName(), TmfEvent.class); + } + + @Override + protected ITmfTraceIndexer createIndexer(int interval) { + return new TestIndexer(this); + } + + @Override + public TestIndexer getIndexer() { + return (TestIndexer) super.getIndexer(); + } + } + + // ------------------------------------------------------------------------ + // Helper functions + // ------------------------------------------------------------------------ + + private synchronized void setupTrace(final String path) { + if (fTrace == null) { + try { + final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(path), null); + final File test = new File(FileLocator.toFileURL(location).toURI()); + fTrace = new TestTrace(test.toURI().getPath(), BLOCK_SIZE); + fTrace.indexTrace(true); + } catch (final TmfTraceException e) { + e.printStackTrace(); + } catch (final URISyntaxException e) { + e.printStackTrace(); + } catch (final IOException e) { + e.printStackTrace(); + } + } + + if (fEmptyTrace == null) { + fEmptyTrace = new EmptyTestTrace(); + fEmptyTrace.indexTrace(true); + } + } + + // ------------------------------------------------------------------------ + // Verify checkpoints + // ------------------------------------------------------------------------ + + @Test + public void testTmfTraceMultiTimestamps() { + assertEquals("getCacheSize", BLOCK_SIZE, fTrace.getCacheSize()); + assertEquals("getTraceSize", NB_EVENTS, fTrace.getNbEvents()); + assertEquals("getRange-start", 1, fTrace.getTimeRange().getStartTime().getValue()); + assertEquals("getRange-end", 102, fTrace.getTimeRange().getEndTime().getValue()); + assertEquals("getStartTime", 1, fTrace.getStartTime().getValue()); + assertEquals("getEndTime", 102, fTrace.getEndTime().getValue()); + + ITmfCheckpointIndex checkpoints = fTrace.getIndexer().getCheckpoints(); + assertTrue("Checkpoints exist", checkpoints != null); + assertEquals("Checkpoints size", NB_EVENTS / BLOCK_SIZE + 1, checkpoints.size()); + + // Trace has 3 events with same timestamp (ts=101) at rank 99, 100, 101 + + // Verify that the event at rank=99 is returned when seeking to ts=101 (first event with this timestamp) + // and not the event at checkpoint boundary + TmfTimestamp seekTs = new TmfTimestamp(101, -3, 0); + ITmfContext ctx = fTrace.seekEvent(seekTs); + ITmfEvent event = fTrace.getNext(ctx); + + assertEquals(99, ctx.getRank()); + assertEquals(0, seekTs.compareTo(event.getTimestamp(), false)); + + event = fTrace.getNext(ctx); + + assertEquals(100, ctx.getRank()); + assertEquals(0, seekTs.compareTo(event.getTimestamp(), false)); + + event = fTrace.getNext(ctx); + + assertEquals(101, ctx.getRank()); + assertEquals(0, seekTs.compareTo(event.getTimestamp(), false)); + + // Trace has events with same timestamp (ts=102) for ranks 102..702 -> 2 checkpoints with same timestamp are created + // Verify that the event at rank=102 is returned when seeking to ts=102 (first event with this timestamp) + // and not the event at checkpoint boundary + seekTs = new TmfTimestamp(102, -3, 0); + ctx = fTrace.seekEvent(seekTs); + event = fTrace.getNext(ctx); + + assertEquals(102, ctx.getRank()); + assertEquals(0, seekTs.compareTo(event.getTimestamp(), false)); + + // Verify seek to first checkpoint + seekTs = new TmfTimestamp(1, -3, 0); + ctx = fTrace.seekEvent(seekTs); + event = fTrace.getNext(ctx); + + assertEquals(1, ctx.getRank()); + assertEquals(0, seekTs.compareTo(event.getTimestamp(), false)); + + // Verify seek to timestamp before first event + seekTs = new TmfTimestamp(0, -3, 0); + ctx = fTrace.seekEvent(seekTs); + event = fTrace.getNext(ctx); + + assertEquals(1, ctx.getRank()); + assertEquals(0, new TmfTimestamp(1, -3, 0).compareTo(event.getTimestamp(), false)); + + // Verify seek to timestamp between first and second checkpoint + seekTs = new TmfTimestamp(50, -3, 0); + ctx = fTrace.seekEvent(seekTs); + event = fTrace.getNext(ctx); + + assertEquals(50, ctx.getRank()); + assertEquals(0, seekTs.compareTo(event.getTimestamp(), false)); + + // Verify seek to timestamp after last event in trace + seekTs = new TmfTimestamp(103, -3, 0); + ctx = fTrace.seekEvent(seekTs); + event = fTrace.getNext(ctx); + + assertEquals(-1, ctx.getRank()); + assertNull(event); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointTest.java new file mode 100644 index 0000000000..f4c128619d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfCheckpointTest.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Adapted for TMF Trace Model 1.0 + * Alexandre Montplaisir - Port to JUnit4 + * Patrick Tasse - Updated for location in checkpoint + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.indexer.checkpoint; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; +import org.junit.Test; + +/** + * Test suite for the TmfCheckpoint class. + */ +@SuppressWarnings("javadoc") +public class TmfCheckpointTest { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + private ITmfTimestamp fTimestamp1 = new TmfTimestamp(); + private ITmfTimestamp fTimestamp2 = TmfTimestamp.BIG_BANG; + private ITmfTimestamp fTimestamp3 = TmfTimestamp.BIG_CRUNCH; + + private long aLong1 = 12345L; + private long aLong2 = 23456L; + private long aLong3 = 34567L; + private long RANK1 = 1L; + private long RANK2 = 2L; + private long RANK3 = 3L; + + private ITmfLocation fLocation1 = new TmfLongLocation(aLong1); + private ITmfLocation fLocation2 = new TmfLongLocation(aLong2); + private ITmfLocation fLocation3 = new TmfLongLocation(aLong3); + + private TmfCheckpoint fCheckpoint1 = new TmfCheckpoint(fTimestamp1, fLocation1, RANK1); + private TmfCheckpoint fCheckpoint2 = new TmfCheckpoint(fTimestamp2, fLocation2, RANK2); + private TmfCheckpoint fCheckpoint3 = new TmfCheckpoint(fTimestamp3, fLocation3, RANK3); + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + @Test + public void testTmfCheckpoint() { + assertEquals("TmfCheckpoint", fTimestamp1, fCheckpoint1.getTimestamp()); + assertEquals("TmfCheckpoint", fLocation1, fCheckpoint1.getLocation()); + } + + public void testTmfLocationCopy() { + final TmfCheckpoint checkpoint = new TmfCheckpoint(fCheckpoint1); + + assertEquals("TmfCheckpoint", fTimestamp1, checkpoint.getTimestamp()); + assertEquals("TmfCheckpoint", fLocation1, checkpoint.getLocation()); + } + + @Test + public void testTmfLocationCopy2() { + try { + new TmfCheckpoint(null); + fail("null copy"); + } + catch (final IllegalArgumentException e) { + // Success + } + catch (final Exception e) { + fail("wrong exception"); + } + } + + // ------------------------------------------------------------------------ + // compareTo + // ------------------------------------------------------------------------ + + @Test + public void testCompareTo() { + assertEquals("compareTo", 0, fCheckpoint1.compareTo(fCheckpoint1)); + assertEquals("compareTo", 1, fCheckpoint1.compareTo(fCheckpoint2)); + assertEquals("compareTo", -1, fCheckpoint1.compareTo(fCheckpoint3)); + + assertEquals("compareTo", -1, fCheckpoint2.compareTo(fCheckpoint1)); + assertEquals("compareTo", 0, fCheckpoint2.compareTo(fCheckpoint2)); + assertEquals("compareTo", -1, fCheckpoint2.compareTo(fCheckpoint3)); + + assertEquals("compareTo", 1, fCheckpoint3.compareTo(fCheckpoint1)); + assertEquals("compareTo", 1, fCheckpoint3.compareTo(fCheckpoint2)); + assertEquals("compareTo", 0, fCheckpoint3.compareTo(fCheckpoint3)); + } + + @Test + public void testCompareToNull() { + final TmfCheckpoint checkpoint1 = new TmfCheckpoint(null, fLocation1, RANK1); + final TmfCheckpoint checkpoint2 = new TmfCheckpoint(null, fLocation2, RANK2); + final TmfCheckpoint checkpoint3 = new TmfCheckpoint(null, fLocation3, RANK3); + final TmfCheckpoint checkpoint4 = new TmfCheckpoint(null, fLocation1, RANK1); + + // Test the various 'null' vs. '!null' combinations + assertEquals("compareTo", 0, checkpoint1.compareTo(fCheckpoint1)); + assertEquals("compareTo", 0, fCheckpoint1.compareTo(checkpoint1)); + assertEquals("compareTo", -1, checkpoint1.compareTo(fCheckpoint2)); + assertEquals("compareTo", 1, fCheckpoint2.compareTo(checkpoint1)); + assertEquals("compareTo", -1, checkpoint1.compareTo(fCheckpoint3)); + assertEquals("compareTo", 1, fCheckpoint3.compareTo(checkpoint1)); + + // Test the 'null' vs. 'null' combinations + assertEquals("compareTo", 0, checkpoint1.compareTo(checkpoint4)); + assertEquals("compareTo", 0, checkpoint4.compareTo(checkpoint1)); + assertEquals("compareTo", -1, checkpoint1.compareTo(checkpoint2)); + assertEquals("compareTo", 1, checkpoint2.compareTo(checkpoint1)); + assertEquals("compareTo", -1, checkpoint1.compareTo(checkpoint3)); + assertEquals("compareTo", 1, checkpoint3.compareTo(checkpoint1)); + } + + // ------------------------------------------------------------------------ + // hashCode + // ------------------------------------------------------------------------ + + @Test + public void testHashCode() { + final TmfCheckpoint checkpoint1 = new TmfCheckpoint(fCheckpoint1); + final TmfCheckpoint checkpoint2 = new TmfCheckpoint(fCheckpoint2); + + assertTrue("hashCode", fCheckpoint1.hashCode() == checkpoint1.hashCode()); + assertTrue("hashCode", fCheckpoint2.hashCode() == checkpoint2.hashCode()); + + assertTrue("hashCode", fCheckpoint1.hashCode() != checkpoint2.hashCode()); + assertTrue("hashCode", fCheckpoint2.hashCode() != checkpoint1.hashCode()); + } + + @Test + public void testHashCodeNull() { + final TmfCheckpoint checkpoint1 = new TmfCheckpoint(null, fLocation1, RANK1); + final TmfCheckpoint checkpoint2 = new TmfCheckpoint(fTimestamp1, null, RANK1); + final TmfCheckpoint checkpoint3 = new TmfCheckpoint(checkpoint1); + final TmfCheckpoint checkpoint4 = new TmfCheckpoint(checkpoint2); + + assertTrue("hashCode", fCheckpoint1.hashCode() != checkpoint1.hashCode()); + assertTrue("hashCode", fCheckpoint1.hashCode() != checkpoint2.hashCode()); + + assertTrue("hashCode", checkpoint1.hashCode() == checkpoint3.hashCode()); + assertTrue("hashCode", checkpoint2.hashCode() == checkpoint4.hashCode()); + } + + // ------------------------------------------------------------------------ + // equals + // ------------------------------------------------------------------------ + + @Test + public void testEqualsReflexivity() { + assertTrue("equals", fCheckpoint1.equals(fCheckpoint1)); + assertTrue("equals", fCheckpoint2.equals(fCheckpoint2)); + + assertTrue("equals", !fCheckpoint1.equals(fCheckpoint2)); + assertTrue("equals", !fCheckpoint2.equals(fCheckpoint1)); + } + + @Test + public void testEqualsSymmetry() { + final TmfCheckpoint checkpoint1 = new TmfCheckpoint(fCheckpoint1); + final TmfCheckpoint checkpoint2 = new TmfCheckpoint(fCheckpoint2); + + assertTrue("equals", checkpoint1.equals(fCheckpoint1)); + assertTrue("equals", fCheckpoint1.equals(checkpoint1)); + + assertTrue("equals", checkpoint2.equals(fCheckpoint2)); + assertTrue("equals", fCheckpoint2.equals(checkpoint2)); + } + + @Test + public void testEqualsTransivity() { + final TmfCheckpoint checkpoint1 = new TmfCheckpoint(fCheckpoint1); + final TmfCheckpoint checkpoint2 = new TmfCheckpoint(checkpoint1); + final TmfCheckpoint checkpoint3 = new TmfCheckpoint(checkpoint2); + + assertTrue("equals", checkpoint1.equals(checkpoint2)); + assertTrue("equals", checkpoint2.equals(checkpoint3)); + assertTrue("equals", checkpoint1.equals(checkpoint3)); + } + + @Test + public void testNotEqual() { + // Various checkpoints + final TmfCheckpoint checkpoint1 = new TmfCheckpoint(fTimestamp1, fLocation1, RANK1); + final TmfCheckpoint checkpoint2 = new TmfCheckpoint(fTimestamp2, fLocation1, RANK1); + final TmfCheckpoint checkpoint3 = new TmfCheckpoint(fTimestamp1, fLocation2, RANK2); + final TmfCheckpoint checkpoint4 = new TmfCheckpoint(fTimestamp1, null, RANK1); + final TmfCheckpoint checkpoint5 = new TmfCheckpoint(null, fLocation1, RANK1); + + // Null check + assertFalse("equals", checkpoint1.equals(null)); + + // Different types + assertFalse("equals", checkpoint1.equals(new TmfTimestamp())); + + // Null locations/location + assertFalse("equals", checkpoint1.equals(checkpoint4)); + assertFalse("equals", checkpoint1.equals(checkpoint5)); + assertFalse("equals", checkpoint4.equals(checkpoint1)); + assertFalse("equals", checkpoint5.equals(checkpoint1)); + + // Different locations/location + assertFalse("equals", checkpoint1.equals(checkpoint2)); + assertFalse("equals", checkpoint1.equals(checkpoint3)); + } + + // ------------------------------------------------------------------------ + // toString + // ------------------------------------------------------------------------ + + @Test + public void testToString() { + final String expected1 = "TmfCheckpoint [fLocation=" + fCheckpoint1.getLocation() + + ", fTimestamp=" + fCheckpoint1.getTimestamp() + ", fCheckpointRank=" + fCheckpoint1.getCheckpointRank() + "]"; + final String expected2 = "TmfCheckpoint [fLocation=" + fCheckpoint2.getLocation() + + ", fTimestamp=" + fCheckpoint2.getTimestamp() + ", fCheckpointRank=" + fCheckpoint2.getCheckpointRank() + "]"; + final String expected3 = "TmfCheckpoint [fLocation=" + fCheckpoint3.getLocation() + + ", fTimestamp=" + fCheckpoint3.getTimestamp() + ", fCheckpointRank=" + fCheckpoint3.getCheckpointRank() + "]"; + + assertEquals("toString", expected1, fCheckpoint1.toString()); + assertEquals("toString", expected2, fCheckpoint2.toString()); + assertEquals("toString", expected3, fCheckpoint3.toString()); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfExperimentCheckpointIndexTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfExperimentCheckpointIndexTest.java new file mode 100644 index 0000000000..1761ddd072 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfExperimentCheckpointIndexTest.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + * Patrick Tasse - Updated for ranks in experiment location + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.indexer.checkpoint; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.tests.TmfCoreTestPlugin; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfExperimentStub; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Test suite for the TmfCheckpointIndexTest class. + */ +@SuppressWarnings("javadoc") +public class TmfExperimentCheckpointIndexTest { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private static final String EXPERIMENT = "MyExperiment"; + private static final TmfTestTrace TEST_TRACE1 = TmfTestTrace.O_TEST_10K; + private static final TmfTestTrace TEST_TRACE2 = TmfTestTrace.E_TEST_10K; + private static int NB_EVENTS = 20000; + private static int BLOCK_SIZE = 1000; + + private static ITmfTrace[] fTestTraces; + private static TmfExperimentStub fExperiment; + + // ------------------------------------------------------------------------ + // Housekeeping + // ------------------------------------------------------------------------ + + @Before + public void setUp() { + setupTraces(); + fExperiment = new TmfExperimentStub(EXPERIMENT, fTestTraces, BLOCK_SIZE); + fExperiment.getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, true); + } + + @After + public void tearDown() { + fExperiment.dispose(); + fExperiment = null; + for (ITmfTrace trace : fTestTraces) { + trace.dispose(); + } + fTestTraces = null; + } + + private static void setupTraces() { + + fTestTraces = new ITmfTrace[2]; + try { + URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE1.getFullPath()), null); + File test = new File(FileLocator.toFileURL(location).toURI()); + final TmfTraceStub trace1 = new TmfTraceStub(test.getPath(), 0, true, null); + fTestTraces[0] = trace1; + location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE2.getFullPath()), null); + test = new File(FileLocator.toFileURL(location).toURI()); + final TmfTraceStub trace2 = new TmfTraceStub(test.getPath(), 0, true, null); + fTestTraces[1] = trace2; + } catch (final TmfTraceException e) { + e.printStackTrace(); + } catch (final URISyntaxException e) { + e.printStackTrace(); + } catch (final IOException e) { + e.printStackTrace(); + } + } + + // ------------------------------------------------------------------------ + // Verify checkpoints + // ------------------------------------------------------------------------ + + @Test + public void testTmfTraceIndexing() { + assertEquals("getCacheSize", BLOCK_SIZE, fExperiment.getCacheSize()); + assertEquals("getTraceSize", NB_EVENTS, fExperiment.getNbEvents()); + assertEquals("getRange-start", 1, fExperiment.getTimeRange().getStartTime().getValue()); + assertEquals("getRange-end", NB_EVENTS, fExperiment.getTimeRange().getEndTime().getValue()); + assertEquals("getStartTime", 1, fExperiment.getStartTime().getValue()); + assertEquals("getEndTime", NB_EVENTS, fExperiment.getEndTime().getValue()); + + ITmfCheckpointIndex checkpoints = fExperiment.getIndexer().getCheckpoints(); + int pageSize = fExperiment.getCacheSize(); + assertTrue("Checkpoints exist", checkpoints != null); + assertEquals("Checkpoints size", NB_EVENTS / BLOCK_SIZE, checkpoints.size()); + + // Validate that each checkpoint points to the right event + for (int i = 0; i < checkpoints.size(); i++) { + ITmfCheckpoint checkpoint = checkpoints.get(i); + ITmfLocation location = checkpoint.getLocation(); + ITmfContext context = fExperiment.seekEvent(location); + ITmfEvent event = fExperiment.parseEvent(context); + assertTrue(context.getRank() == i * pageSize); + assertTrue((checkpoint.getTimestamp().compareTo(event.getTimestamp(), false) == 0)); + } + } + + // ------------------------------------------------------------------------ + // Streaming + // ------------------------------------------------------------------------ + + @Test + public void testGrowingIndex() { + ITmfTrace[] testTraces = new TmfTraceStub[2]; + try { + URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE1.getFullPath()), null); + File test = new File(FileLocator.toFileURL(location).toURI()); + final TmfTraceStub trace1 = new TmfTraceStub(test.getPath(), 0, false, null); + testTraces[0] = trace1; + location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TEST_TRACE2.getFullPath()), null); + test = new File(FileLocator.toFileURL(location).toURI()); + final TmfTraceStub trace2 = new TmfTraceStub(test.getPath(), 0, false, null); + testTraces[1] = trace2; + } catch (final TmfTraceException e) { + e.printStackTrace(); + } catch (final URISyntaxException e) { + e.printStackTrace(); + } catch (final IOException e) { + e.printStackTrace(); + } + + TmfExperimentStub experiment = new TmfExperimentStub(EXPERIMENT, testTraces, BLOCK_SIZE); + int pageSize = experiment.getCacheSize(); + + // Build the first half of the index + TmfTimeRange range = new TmfTimeRange(new TmfTimestamp(1, -3), new TmfTimestamp(NB_EVENTS / 2 - 1, -3)); + experiment.getIndexer().buildIndex(0, range, true); + + // Validate that each checkpoint points to the right event + ITmfCheckpointIndex checkpoints = experiment.getIndexer().getCheckpoints(); + assertTrue("Checkpoints exist", checkpoints != null); + assertEquals("Checkpoints size", NB_EVENTS / BLOCK_SIZE / 2, checkpoints.size()); + + // Build the second half of the index + experiment.getIndexer().buildIndex(NB_EVENTS / 2, TmfTimeRange.ETERNITY, true); + + // Validate that each checkpoint points to the right event + assertEquals("Checkpoints size", NB_EVENTS / BLOCK_SIZE, checkpoints.size()); + for (int i = 0; i < checkpoints.size(); i++) { + ITmfCheckpoint checkpoint = checkpoints.get(i); + ITmfLocation location = checkpoint.getLocation(); + ITmfContext context = experiment.seekEvent(location); + ITmfEvent event = experiment.parseEvent(context); + assertTrue(context.getRank() == i * pageSize); + assertTrue((checkpoint.getTimestamp().compareTo(event.getTimestamp(), false) == 0)); + assertEquals("Checkpoint value", i * pageSize + 1, checkpoint.getTimestamp().getValue()); + } + + /* Clean up (since we didn't use the class-specific fixtures) */ + experiment.dispose(); + for (ITmfTrace trace : testTraces) { + trace.dispose(); + } + } + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/location/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/location/AllTests.java new file mode 100644 index 0000000000..5b4b99d3e7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/location/AllTests.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Adjusted for new Trace Model + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.location; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for org.eclipse.linuxtools.tmf.core.trace.location + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TmfLocationTest.class, +}) +public class AllTests {} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/location/TmfLocationTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/location/TmfLocationTest.java new file mode 100644 index 0000000000..28ba7ea900 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/location/TmfLocationTest.java @@ -0,0 +1,252 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + * Patrick Tasse - Add tests for TmfExperimentLocation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.location; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.nio.ByteBuffer; + +import org.eclipse.tracecompass.internal.tmf.core.trace.TmfExperimentLocation; +import org.eclipse.tracecompass.internal.tmf.core.trace.TmfLocationArray; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLocation; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfTimestampLocation; +import org.junit.Before; +import org.junit.Test; + +/** + * Test suite for the TmfLocation class. + */ +@SuppressWarnings("javadoc") +public class TmfLocationTest { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + private Long aLong = 12345L; + private TmfTimestamp aTimestamp = new TmfTimestamp(); + private TmfLocationArray aLocationArray; + + private TmfLongLocation fLocation1; + private TmfLongLocation fLocation2; + private TmfTimestampLocation fLocation3; + private TmfExperimentLocation fExpLocation; + + // ------------------------------------------------------------------------ + // Housekeeping + // ------------------------------------------------------------------------ + + @Before + public void setUp() { + fLocation1 = new TmfLongLocation((Long) null); + fLocation2 = new TmfLongLocation(aLong); + fLocation3 = new TmfTimestampLocation(aTimestamp); + aLocationArray = new TmfLocationArray( + new ITmfLocation[] { fLocation1, fLocation2, fLocation3 }, + new long[] { 1, 2, 3 } + ); + fExpLocation = new TmfExperimentLocation(aLocationArray); + } + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + @Test + public void testTmfLocation() { + assertNull("TmfLocation", fLocation1.getLocationInfo()); + assertEquals("TmfLocation", aLong, fLocation2.getLocationInfo()); + assertEquals("TmfLocation", aTimestamp, fLocation3.getLocationInfo()); + assertEquals("TmfLocation", aLocationArray, fExpLocation.getLocationInfo()); + } + + @Test + public void testTmfLocationCopy() { + TmfLongLocation location1 = new TmfLongLocation(fLocation1); + TmfLongLocation location2 = new TmfLongLocation(fLocation2); + TmfTimestampLocation location3 = new TmfTimestampLocation(fLocation3); + TmfExperimentLocation expLocation = new TmfExperimentLocation(fExpLocation); + + assertNull("TmfLocation", location1.getLocationInfo()); + assertEquals("TmfLocation", aLong, location2.getLocationInfo()); + assertEquals("TmfLocation", aTimestamp, location3.getLocationInfo()); + assertEquals("TmfLocation", aLocationArray, expLocation.getLocationInfo()); + } + + // ------------------------------------------------------------------------ + // hashCode + // ------------------------------------------------------------------------ + + @Test + public void testHashCode() { + TmfLongLocation location1 = new TmfLongLocation((Long) null); + TmfLongLocation location2 = new TmfLongLocation(aLong); + TmfTimestampLocation location3 = new TmfTimestampLocation(aTimestamp); + TmfExperimentLocation expLocation = new TmfExperimentLocation(fExpLocation); + TmfLocationArray locationArray1 = new TmfLocationArray(aLocationArray, 2, fLocation3, 5); + TmfExperimentLocation expLocation1 = new TmfExperimentLocation(locationArray1); + TmfLocationArray locationArray2 = new TmfLocationArray(aLocationArray, 2, fLocation2, 4); + TmfExperimentLocation expLocation2 = new TmfExperimentLocation(locationArray2); + TmfLocationArray locationArray3 = new TmfLocationArray( + new ITmfLocation[] { fLocation1, fLocation2 }, + new long[] { 1, 2 } + ); + TmfExperimentLocation expLocation3 = new TmfExperimentLocation(locationArray3); + + assertTrue("hashCode", fLocation1.hashCode() == location1.hashCode()); + assertTrue("hashCode", fLocation2.hashCode() == location2.hashCode()); + assertTrue("hashCode", fLocation3.hashCode() == location3.hashCode()); + assertTrue("hashCode", fExpLocation.hashCode() == expLocation.hashCode()); + + assertTrue("hashCode", fLocation2.hashCode() != location3.hashCode()); + assertTrue("hashCode", fLocation3.hashCode() != location2.hashCode()); + assertTrue("hashCode", fExpLocation.hashCode() != expLocation1.hashCode()); + assertTrue("hashCode", fExpLocation.hashCode() != expLocation2.hashCode()); + assertTrue("hashCode", fExpLocation.hashCode() != expLocation3.hashCode()); + } + + // ------------------------------------------------------------------------ + // toEquals + // ------------------------------------------------------------------------ + + private static class TmfTestLongLocation extends TmfLocation { + public TmfTestLongLocation(Long location) { + super(location); + } + + @Override + public void serialize(ByteBuffer bufferOut) {} + } + + private static class TmfTestLongLocation2 extends TmfTestLongLocation { + public TmfTestLongLocation2(Long location) { + super(location); + } + } + + @Test + public void testEqualsWrongTypes() { + ITmfLocation location1 = new TmfTestLongLocation(aLong); + TmfTestLongLocation location2 = new TmfTestLongLocation2(aLong); + + assertFalse("equals", location1.equals(location2)); + assertFalse("equals", location2.equals(location1)); + } + + @Test + public void testEqualsWithNulls() { + ITmfLocation location1 = new TmfLongLocation(aLong); + ITmfLocation location2 = new TmfLongLocation((Long) null); + + assertFalse("equals", location1.equals(location2)); + assertFalse("equals", location2.equals(location1)); + } + + @Test + public void testEqualsReflexivity() { + assertTrue("equals", fLocation1.equals(fLocation1)); + assertTrue("equals", fLocation2.equals(fLocation2)); + assertTrue("equals", fLocation3.equals(fLocation3)); + assertTrue("equals", fExpLocation.equals(fExpLocation)); + + assertTrue("equals", !fLocation2.equals(fLocation3)); + assertTrue("equals", !fLocation3.equals(fLocation2)); + TmfLocationArray locationArray1 = new TmfLocationArray(aLocationArray, 2, fLocation3, 5); + TmfExperimentLocation expLocation1 = new TmfExperimentLocation(locationArray1); + TmfLocationArray locationArray2 = new TmfLocationArray(aLocationArray, 2, fLocation2, 4); + TmfExperimentLocation expLocation2 = new TmfExperimentLocation(locationArray2); + TmfLocationArray locationArray3 = new TmfLocationArray( + new ITmfLocation[] { fLocation1, fLocation2, fLocation3 }, + new long[] { 1, 2 } + ); + TmfExperimentLocation expLocation3 = new TmfExperimentLocation(locationArray3); + assertTrue("equals", !fExpLocation.equals(expLocation1)); + assertTrue("equals", !expLocation1.equals(fExpLocation)); + assertTrue("equals", !fExpLocation.equals(expLocation2)); + assertTrue("equals", !expLocation2.equals(fExpLocation)); + assertTrue("equals", !fExpLocation.equals(expLocation3)); + assertTrue("equals", !expLocation3.equals(fExpLocation)); + } + + @Test + public void testEqualsSymmetry() { + TmfLongLocation location2 = new TmfLongLocation(aLong); + TmfTimestampLocation location3 = new TmfTimestampLocation(aTimestamp); + TmfExperimentLocation expLocation = new TmfExperimentLocation(fExpLocation); + + assertTrue("equals", location2.equals(fLocation2)); + assertTrue("equals", fLocation2.equals(location2)); + + assertTrue("equals", location3.equals(fLocation3)); + assertTrue("equals", fLocation3.equals(location3)); + + assertTrue("equals", expLocation.equals(fExpLocation)); + assertTrue("equals", fExpLocation.equals(expLocation)); + } + + @Test + public void testEqualsTransivity() { + TmfLongLocation location1 = new TmfLongLocation(aLong); + TmfLongLocation location2 = new TmfLongLocation(aLong); + TmfLongLocation location3 = new TmfLongLocation(aLong); + + TmfExperimentLocation expLocation1 = new TmfExperimentLocation(aLocationArray); + TmfExperimentLocation expLocation2 = new TmfExperimentLocation(aLocationArray); + TmfExperimentLocation expLocation3 = new TmfExperimentLocation(aLocationArray); + + assertTrue("equals", location1.equals(location2)); + assertTrue("equals", location2.equals(location3)); + assertTrue("equals", location3.equals(location1)); + assertTrue("equals", expLocation1.equals(expLocation2)); + assertTrue("equals", expLocation2.equals(expLocation3)); + assertTrue("equals", expLocation3.equals(expLocation1)); + } + + @Test + public void testEqualsNull() { + assertTrue("equals", !fLocation1.equals(null)); + assertTrue("equals", !fLocation2.equals(null)); + assertTrue("equals", !fLocation3.equals(null)); + assertTrue("equals", !fExpLocation.equals(null)); + } + + // ------------------------------------------------------------------------ + // toString + // ------------------------------------------------------------------------ + + @Test + public void testToString() { + TmfTimestamp ts = new TmfTimestamp(); + + TmfLongLocation location1 = new TmfLongLocation(aLong); + TmfTimestampLocation location2 = new TmfTimestampLocation(ts); + TmfExperimentLocation expLocation = new TmfExperimentLocation(aLocationArray); + + String expected1 = "TmfLongLocation [fLocationInfo=" + aLong + "]"; + String expected2 = "TmfTimestampLocation [fLocationInfo=" + ts + "]"; + String expected3 = "TmfExperimentLocation [" + aLocationArray + "]"; + + assertEquals("toString", expected1, location1.toString()); + assertEquals("toString", expected2, location2.toString()); + assertEquals("toString", expected3, expLocation.toString()); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/stub/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/stub/AllTests.java new file mode 100644 index 0000000000..fc5d8ace08 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/stub/AllTests.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.stub; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Unit tests for the development trace package. + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + XmlStubTraceTest.class +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/stub/XmlStubTraceTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/stub/XmlStubTraceTest.java new file mode 100644 index 0000000000..e4a20ff57d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/stub/XmlStubTraceTest.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.stub; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; +import java.net.URL; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.tests.TmfCoreTestPlugin; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.TmfXmlTraceStub; +import org.junit.Test; + +/** + * Test suite for the {@link TmfXmlTraceStub} class + * + * @author Geneviève Bastien + */ +public class XmlStubTraceTest { + + private static final Path VALID_FILE = new Path("testfiles/stub_xml_traces/valid/test.xml"); + private static final Path VALID_PATH = new Path("testfiles/stub_xml_traces/valid"); + private static final Path INVALID_PATH = new Path("testfiles/stub_xml_traces/invalid"); + + private static final String EVENT_A = "A"; + private static final String EVENT_B = "B"; + private static final String FIELD_A = "b"; + private static final String FIELD_B = "f"; + + private static IPath getAbsolutePath(Path relativePath) { + Plugin plugin = TmfCoreTestPlugin.getDefault(); + if (plugin == null) { + /* + * Shouldn't happen but at least throw something to get the test to + * fail early + */ + throw new IllegalStateException(); + } + URL location = FileLocator.find(plugin.getBundle(), relativePath, null); + try { + IPath path = new Path(FileLocator.toFileURL(location).getPath()); + return path; + } catch (IOException e) { + throw new IllegalStateException(); + } + } + + /** + * Test the + * {@link TmfXmlTraceStub#validate(org.eclipse.core.resources.IProject, String)} + * method + */ + @Test + public void testValidate() { + TmfXmlTraceStub trace = new TmfXmlTraceStub(); + File[] invalidFiles = getAbsolutePath(INVALID_PATH).toFile().listFiles(); + assertTrue(invalidFiles.length > 0); + for (File f : invalidFiles) { + assertTrue(!trace.validate(null, f.getAbsolutePath()).isOK()); + } + + File[] validFiles = getAbsolutePath(VALID_PATH).toFile().listFiles(); + assertTrue(validFiles.length > 0); + for (File f : validFiles) { + assertTrue(trace.validate(null, f.getAbsolutePath()).isOK()); + } + } + + /** + * Test the reading and querying the XML trace and make sure fields are + * present + */ + @Test + public void testDevelopmentTrace() { + TmfXmlTraceStub trace = new TmfXmlTraceStub(); + IStatus status = trace.validate(null, getAbsolutePath(VALID_FILE).toOSString()); + if (!status.isOK()) { + fail(status.getException().getMessage()); + } + + try { + trace.initTrace(null, getAbsolutePath(VALID_FILE).toOSString(), TmfEvent.class); + } catch (TmfTraceException e1) { + fail(e1.getMessage()); + } + + CustomEventRequest req = new CustomEventRequest(trace); + trace.sendRequest(req); + try { + req.waitForCompletion(); + if (req.isCancelled()) { + fail(req.getStatus().getMessage()); + } + } catch (InterruptedException e) { + fail(e.getMessage()); + } + assertEquals(4, req.getCount()); + } + + private static IStatus testEvent(ITmfEvent event) { + switch (event.getType().getName()) { + case EVENT_A: { + ITmfEventField content = event.getContent(); + if (!event.getSource().equals("1")) { + return new Status(IStatus.ERROR, TmfCoreTestPlugin.PLUGIN_ID, "Events of type A should have source 1 but was " + event.getSource()); + } + if (content.getField(FIELD_A) == null) { + return new Status(IStatus.ERROR, TmfCoreTestPlugin.PLUGIN_ID, String.format("Field %s does not exist in event %s", FIELD_A, EVENT_A)); + } + break; + } + case EVENT_B: { + ITmfEventField content = event.getContent(); + if (!event.getSource().equals("2")) { + return new Status(IStatus.ERROR, TmfCoreTestPlugin.PLUGIN_ID, "Events of type B should have source 2 but was " + event.getSource()); + } + if (content.getField(FIELD_B) == null) { + return new Status(IStatus.ERROR, TmfCoreTestPlugin.PLUGIN_ID, String.format("Field %s does not exist in event %s", FIELD_B, EVENT_B)); + } + break; + } + default: + return new Status(IStatus.ERROR, TmfCoreTestPlugin.PLUGIN_ID, "Unexpected event " + event.getType().getName()); + } + return Status.OK_STATUS; + } + + private class CustomEventRequest extends TmfEventRequest { + private final ITmfTrace fTrace; + private IStatus fResult = Status.OK_STATUS; + private int fCount = 0; + + public CustomEventRequest(ITmfTrace trace) { + super(trace.getEventType(), + TmfTimeRange.ETERNITY, + 0, + ITmfEventRequest.ALL_DATA, + ITmfEventRequest.ExecutionType.BACKGROUND); + this.fTrace = trace; + } + + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + if (event.getTrace() == fTrace) { + fCount++; + IStatus result = testEvent(event); + if (!result.isOK()) { + fResult = result; + this.cancel(); + } + } + } + + public IStatus getStatus() { + return fResult; + } + + public int getCount() { + return fCount; + } + + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/text/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/text/AllTests.java new file mode 100644 index 0000000000..c5a0876ece --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/text/AllTests.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.text; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for org.eclipse.linuxtools.tmf.core.trace.location + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TextTraceContextTest.class, + TextTraceEventContentTest.class, + TextTraceTest.class, +}) +public class AllTests {} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/text/TextTraceContextTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/text/TextTraceContextTest.java new file mode 100644 index 0000000000..34fb4e26d8 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/text/TextTraceContextTest.java @@ -0,0 +1,238 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.text; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.regex.Pattern; + +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.TmfContext; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; +import org.eclipse.tracecompass.tmf.core.trace.text.TextTraceContext; +import org.junit.Test; + +/** + * Test suite for the {@link TextTraceContext} class. + */ +@SuppressWarnings("javadoc") +public class TextTraceContextTest { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + private final Long aLong1 = 12345L; + private final Long aLong2 = 12346L; + private final Long aLong3 = 12347L; + + private final TmfLongLocation fLocation1 = new TmfLongLocation(aLong1); + private final TmfLongLocation fLocation2 = new TmfLongLocation(aLong2); + + private final long fRank1 = 1; + private final long fRank2 = 2; + + private final TextTraceContext fContext1 = new TextTraceContext(fLocation1, fRank1); + private final TextTraceContext fContext2 = new TextTraceContext(fLocation1, fRank1); + + private final Pattern pattern1 = Pattern.compile("\\s*.*"); + private final Pattern pattern2 = Pattern.compile("\\s*.*"); + + private final String line1 = "line1"; + private final String line2 = "line2"; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + public TextTraceContextTest () { + fContext1.firstLine = line1; + fContext1.firstLineMatcher = pattern1.matcher(line1); + fContext1.nextLineLocation = aLong2; + + fContext2.firstLine = line2; + fContext2.firstLineMatcher = pattern2.matcher(line2); + fContext2.nextLineLocation = aLong3; + } + + @Test + public void testTmfContextDefault() { + final TextTraceContext context = new TextTraceContext(fLocation1, fRank1); + assertEquals("getLocation", fLocation1, context.getLocation()); + assertEquals("getRank", fRank1, context.getRank()); + assertNull(context.firstLine); + assertNull(context.firstLineMatcher); + assertEquals(0, context.nextLineLocation); + } + + // ------------------------------------------------------------------------ + // equals + // ------------------------------------------------------------------------ + + @Test + public void testEqualsReflexivity() { + assertTrue("equals", fContext1.equals(fContext1)); + assertTrue("equals", fContext2.equals(fContext2)); + + assertFalse("equals", fContext1.equals(fContext2)); + assertFalse("equals", fContext2.equals(fContext1)); + } + + @Test + public void testEqualsSymmetry() { + final TextTraceContext context1 = new TextTraceContext(fContext1); + final TextTraceContext context2 = new TextTraceContext(fContext2); + + assertTrue("equals", context1.equals(fContext1)); + assertTrue("equals", fContext1.equals(context1)); + + assertTrue("equals", context2.equals(fContext2)); + assertTrue("equals", fContext2.equals(context2)); + } + + @Test + public void testEqualsTransivity() { + + final TextTraceContext context1 = new TextTraceContext(fContext1); + final TextTraceContext context2 = new TextTraceContext(fContext1); + final TextTraceContext context3 = new TextTraceContext(fContext1); + + assertTrue("equals", context1.equals(context2)); + assertTrue("equals", context2.equals(context3)); + assertTrue("equals", context1.equals(context3)); + } + + @Test + public void testEqualsNull() { + assertFalse("equals", fContext1.equals(null)); + assertFalse("equals", fContext2.equals(null)); + } + + private static class MyContext extends TextTraceContext { + + public MyContext(ITmfLocation location, long rank) { + super(location, rank); + } + } + + @Test + public void testNonEquals() { + + // Different classes + final MyContext myContext = new MyContext(fLocation1, fRank1); + assertFalse("equals", fContext1.equals(myContext)); + assertFalse("equals", myContext.equals(fContext1)); + + // Different locations + TextTraceContext context1 = new TextTraceContext(fLocation1, fRank1); + TextTraceContext context2 = new TextTraceContext(fLocation2, fRank1); + assertFalse("equals", context1.equals(context2)); + + // Different ranks + context1 = new TextTraceContext(fLocation1, fRank1); + context2 = new TextTraceContext(fLocation1, fRank2); + assertFalse("equals", context1.equals(context2)); + + // Different firstLine + context1 = new TextTraceContext(fLocation1, fRank1); + context1.firstLine = line1; + context2 = new TextTraceContext(fLocation1, fRank1); + context2.firstLine = line2; + assertFalse("equals", context1.equals(context2)); + + // Different firstLineMatcher + context1 = new TextTraceContext(fLocation1, fRank1); + context1.firstLine = line1; + context1.firstLineMatcher = fContext1.firstLineMatcher; + context2 = new TextTraceContext(fLocation1, fRank1); + context2.firstLine = line1; + context2.firstLineMatcher = fContext2.firstLineMatcher; + assertFalse("equals", context1.equals(context2)); + + // Different nextLineLocation + context1 = new TextTraceContext(fLocation1, fRank1); + context1.firstLine = line1; + context1.firstLineMatcher = fContext1.firstLineMatcher; + context1.nextLineLocation = aLong2; + context2 = new TextTraceContext(fLocation1, fRank1); + context2.firstLine = line1; + context2.firstLineMatcher = fContext1.firstLineMatcher; + context2.nextLineLocation = aLong3; + assertFalse("equals", context1.equals(context2)); + + } + + // ------------------------------------------------------------------------ + // hashCode + // ------------------------------------------------------------------------ + + @Test + public void testHashCode() { + final TextTraceContext context1 = new TextTraceContext(fContext1); + final TextTraceContext context2 = new TextTraceContext(fContext2); + + assertEquals("hashCode", fContext1.hashCode(), context1.hashCode()); + assertEquals("hashCode", fContext2.hashCode(), context2.hashCode()); + + assertFalse("hashCode", fContext1.hashCode() == context2.hashCode()); + assertFalse("hashCode", fContext2.hashCode() == context1.hashCode()); + + final TmfContext nullContext1 = new TmfContext(); + final TmfContext nullContext2 = new TmfContext(nullContext1); + assertEquals("hashCode", nullContext1.hashCode(), nullContext2.hashCode()); + } + + // ------------------------------------------------------------------------ + // setLocation, setRank, updateRank + // ------------------------------------------------------------------------ + + @Test + public void testSetLocation() { + final TextTraceContext context1 = new TextTraceContext(fLocation1, fRank1); + context1.setLocation(fLocation2); + + assertEquals("getLocation", fLocation2, context1.getLocation()); + assertEquals("getRank", fRank1, context1.getRank()); + } + + @Test + public void testSetRank() { + final TextTraceContext context1 = new TextTraceContext(fContext1); + context1.setRank(fContext2.getRank()); + + assertEquals("getLocation", fContext1.getLocation(), context1.getLocation()); + assertEquals("getRank", fContext2.getRank(), context1.getRank()); + } + + @Test + public void testIncreaseRank() { + final TextTraceContext context1 = new TextTraceContext(fLocation1, fRank1); + + context1.increaseRank(); + assertEquals("getRank", fRank1 + 1, context1.getRank()); + context1.increaseRank(); + assertEquals("getRank", fRank1 + 2, context1.getRank()); + + context1.setRank(ITmfContext.UNKNOWN_RANK); + context1.increaseRank(); + assertEquals("getRank", ITmfContext.UNKNOWN_RANK, context1.getRank()); + context1.increaseRank(); + assertEquals("getRank", ITmfContext.UNKNOWN_RANK, context1.getRank()); + } + +} + diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/text/TextTraceEventContentTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/text/TextTraceEventContentTest.java new file mode 100644 index 0000000000..acbda3f5a5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/text/TextTraceEventContentTest.java @@ -0,0 +1,232 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.core.tests.trace.text; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.trace.text.TextTraceEventContent; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.text.SyslogEventType; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.text.SyslogEventType.Index; +import org.junit.Test; + +/** + * Test suite for the {@link TextTraceEventContent} class. + */ +@SuppressWarnings({ "javadoc", "nls" }) +public class TextTraceEventContentTest { + + // ------------------------------------------------------------------------ + // Members + // ------------------------------------------------------------------------ + + private TextTraceEventContent fEventContent1; + private TextTraceEventContent fEventContent1Clone; + private TextTraceEventContent fEventContent2; + private TextTraceEventContent fEventContent2Clone; + + public TextTraceEventContentTest () { + fEventContent1 = new TextTraceEventContent(SyslogEventType.LABELS); + fEventContent1.setValue("CONTENT"); + fEventContent1.setFieldValue(Index.TIMESTAMP, "Jan 1 01:01:01"); + fEventContent1.setFieldValue(Index.HOST, "HostA"); + fEventContent1.setFieldValue(Index.LOGGER, "LoggerA"); + fEventContent1.setFieldValue(Index.MESSAGE, "MessageA"); + + fEventContent1Clone = new TextTraceEventContent(SyslogEventType.LABELS); + fEventContent1Clone.setValue("CONTENT"); + fEventContent1Clone.setFieldValue(Index.TIMESTAMP, "Jan 1 01:01:01"); + fEventContent1Clone.setFieldValue(Index.HOST, "HostA"); + fEventContent1Clone.setFieldValue(Index.LOGGER, "LoggerA"); + fEventContent1Clone.setFieldValue(Index.MESSAGE, "MessageA"); + + fEventContent2 = new TextTraceEventContent(SyslogEventType.LABELS); + fEventContent2.setFieldValue(SyslogEventType.LABELS[0], "Jan 1 02:02:02"); + fEventContent2.setFieldValue(SyslogEventType.LABELS[1], "HostB"); + fEventContent2.setFieldValue(SyslogEventType.LABELS[2], "LoggerB"); + StringBuffer buffer = new StringBuffer(); + buffer.append("Message B"); + fEventContent2.setFieldValue(SyslogEventType.LABELS[3], buffer); + + fEventContent2Clone = new TextTraceEventContent(SyslogEventType.LABELS); + fEventContent2Clone.setFieldValue(SyslogEventType.LABELS[0], "Jan 1 02:02:02"); + fEventContent2Clone.setFieldValue(SyslogEventType.LABELS[1], "HostB"); + fEventContent2Clone.setFieldValue(SyslogEventType.LABELS[2], "LoggerB"); + buffer = new StringBuffer(); + buffer.append("Message B"); + fEventContent2Clone.setFieldValue(SyslogEventType.LABELS[3], buffer); + } + + public void testConstructorConstructor() { + assertEquals("getField:TIMESTAMP", "Jan 1 01:01:01", fEventContent1.getFieldValue(Index.TIMESTAMP)); + assertEquals("getField:HOST", "HostA", fEventContent1.getFieldValue(Index.HOST)); + assertEquals("getField:LOGGER", "LoggerA", fEventContent1.getFieldValue(Index.LOGGER)); + assertEquals("getField:MESSAGE", "MessageA", fEventContent1.getFieldValue(Index.MESSAGE).toString()); + } + + // ------------------------------------------------------------------------ + // Event Type + // ------------------------------------------------------------------------ + + @Test + public void testEventTypeInstance() { + SyslogEventType eventType = SyslogEventType.INSTANCE; + assertEquals("getTypeId", "Syslog", eventType.getName()); + assertNotNull ("instance", eventType); + assertTrue (eventType.getFieldNames().contains("Timestamp")); + assertTrue (eventType.getFieldNames().contains("Host")); + assertTrue (eventType.getFieldNames().contains("Logger")); + assertTrue (eventType.getFieldNames().contains("Message")); + } + + // ------------------------------------------------------------------------ + // equals + // ------------------------------------------------------------------------ + + @Test + public void testEquals() { + assertEquals("equals", fEventContent1, fEventContent1); + assertEquals("equals", fEventContent2, fEventContent2); + + assertTrue("equals", !fEventContent1.equals(fEventContent2)); + assertTrue("equals", !fEventContent2.equals(fEventContent1)); + + assertEquals("equals", fEventContent1, fEventContent1Clone); + assertEquals("equals", fEventContent2, fEventContent2Clone); + } + + @Test + public void testEqualsNull() { + assertTrue("equals", !fEventContent1.equals(null)); + assertTrue("equals", !fEventContent2.equals(null)); + } + + // ------------------------------------------------------------------------ + // hashCode + // ------------------------------------------------------------------------ + + @Test + public void testHashCode() { + + assertEquals("hashCode", fEventContent1.hashCode(), fEventContent1Clone.hashCode()); + assertEquals("hashCode", fEventContent2.hashCode(), fEventContent2Clone.hashCode()); + + assertNotEquals("hashCode", fEventContent1.hashCode(), fEventContent2.hashCode()); + assertNotEquals("hashCode", fEventContent2.hashCode(), fEventContent1.hashCode()); + } + + // ------------------------------------------------------------------------ + // Event Content + // ------------------------------------------------------------------------ + + @Test + public void testGetFieldValueWithIndex() { + assertEquals("getFieldValue:TIMESTAMP", "Jan 1 01:01:01", fEventContent1.getFieldValue(Index.TIMESTAMP)); + assertEquals("getFieldValue:HOST", "HostA", fEventContent1.getFieldValue(Index.HOST)); + assertEquals("getFieldValue:LOGGER", "LoggerA", fEventContent1.getFieldValue(Index.LOGGER)); + assertEquals("getFieldValue:MESSAGE", "MessageA", fEventContent1.getFieldValue(Index.MESSAGE)); + assertNull(fEventContent1.getFieldValue(4)); + } + + @Test + public void testGetFieldValueWithName() { + assertEquals("getFieldValue:TIMESTAMP", "Jan 1 01:01:01", fEventContent1.getFieldValue("Timestamp")); + assertEquals("getFieldValue:HOST", "HostA", fEventContent1.getFieldValue("Host")); + assertEquals("getFieldValue:LOGGER", "LoggerA", fEventContent1.getFieldValue("Logger")); + assertEquals("getFieldValue:MESSAGE", "MessageA", fEventContent1.getFieldValue("Message")); + assertNull(fEventContent1.getFieldValue("BlaBla")); + } + + @Test + public void testGetFieldNameWithIndex() { + + assertEquals("getFieldName:TIMESTAMP", SyslogEventType.LABELS[0], fEventContent1.getFieldName(Index.TIMESTAMP)); + assertEquals("getFieldName:HOST", SyslogEventType.LABELS[1], fEventContent1.getFieldName(Index.HOST)); + assertEquals("getFieldName:LOGGER", SyslogEventType.LABELS[2], fEventContent1.getFieldName(Index.LOGGER)); + assertEquals("getFieldName:MESSAGE", SyslogEventType.LABELS[3], fEventContent1.getFieldName(Index.MESSAGE)); + assertNull(fEventContent1.getFieldValue(4)); + } + + @Test + public void testGetFields() { + List fields = fEventContent1.getFields(); + assertEquals(4, fields.size()); + assertEquals("getFields:TIMESTAMP", SyslogEventType.LABELS[0], fields.get(Index.TIMESTAMP).getName()); + assertEquals("getFields:TIMESTAMP", "Jan 1 01:01:01", fields.get(Index.TIMESTAMP).getValue()); + assertEquals("getFields:HOST", SyslogEventType.LABELS[1], fields.get(Index.HOST).getName()); + assertEquals("getFields:HOST", "HostA", fields.get(Index.HOST).getValue()); + assertEquals("getFields:LOGGER", SyslogEventType.LABELS[2], fields.get(Index.LOGGER).getName()); + assertEquals("getFields:LOGGER", "LoggerA", fields.get(Index.LOGGER).getValue()); + assertEquals("getFields:MESSAGE", SyslogEventType.LABELS[3], fields.get(Index.MESSAGE).getName()); + assertEquals("getFields:MESSAGE", "MessageA", fields.get(Index.MESSAGE).getValue()); + } + + @Test + public void testGetFieldWithName() { + ITmfEventField field = fEventContent1.getField("Timestamp"); + assertEquals("getFieldName:TIMESTAMP", SyslogEventType.LABELS[0], field.getName()); + assertEquals("getFieldName:TIMESTAMP", "Jan 1 01:01:01", field.getValue()); + + field = fEventContent1.getField(SyslogEventType.LABELS[1]); + assertEquals("getFieldName:HOST", SyslogEventType.LABELS[1], field.getName()); + assertEquals("getFieldName:HOST", "HostA", field.getValue()); + + field = fEventContent1.getField(SyslogEventType.LABELS[2]); + assertEquals("getFieldName:LOGGER", SyslogEventType.LABELS[2], field.getName()); + assertEquals("getFieldName:LOGGER", "LoggerA", field.getValue()); + + field = fEventContent1.getField(SyslogEventType.LABELS[3]); + assertEquals("getFieldName:Message", SyslogEventType.LABELS[3], field.getName()); + assertEquals("getgetFieldName:Message", "MessageA", field.getValue()); + + field = fEventContent1.getField("BlaBla"); + assertNull(field); + } + + @Test + public void testGetFormattedValue() { + assertEquals("CONTENT", fEventContent1.getFormattedValue()); + } + + @Test + public void testToString() { + assertEquals("Timestamp=Jan 1 01:01:01, Host=HostA, Logger=LoggerA, Message=MessageA", fEventContent1.toString()); + } + + @Test + public void testGetSubField() { + String[] names = { "Timestamp"}; + + ITmfEventField field = fEventContent1.getSubField(names); + assertEquals("getSubField:TIMESTAMP", SyslogEventType.LABELS[0], field.getName()); + assertEquals("getSubField:TIMESTAMP", "Jan 1 01:01:01", field.getValue()); + + String[] names2 = { "Timestamp", "subField" }; + field = fEventContent1.getSubField(names2); + assertNull(field); + } + + @Test + public void testGetFieldNames() { + String[] labels = {"Timestamp", "Host", "Logger", "Message"}; + List names = fEventContent1.getFieldNames(); + assertArrayEquals(labels, names.toArray(new String[names.size()])); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/text/TextTraceTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/text/TextTraceTest.java new file mode 100644 index 0000000000..669d0521ba --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/text/TextTraceTest.java @@ -0,0 +1,259 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.trace.text; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Locale; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType; +import org.eclipse.tracecompass.tmf.core.tests.TmfCoreTestPlugin; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimePreferencesConstants; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.TraceValidationStatus; +import org.eclipse.tracecompass.tmf.core.trace.text.TextTraceEventContent; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.text.SyslogEvent; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.text.SyslogTrace; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.text.SyslogEventType.Index; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +@SuppressWarnings({ "nls", "javadoc"}) +public class TextTraceTest { + + // ------------------------------------------------------------------------ + // Variables + // ------------------------------------------------------------------------ + + private static final String NAME = "syslog"; + private static final String PATH = "testfiles/" + NAME; + + private static final String OTHER_PATH = "testfiles/" + "A-Test-10K"; + + private static SyslogTrace fTrace = null; + private static File fTestFile = null; + + // ------------------------------------------------------------------------ + // Housekeeping + // ------------------------------------------------------------------------ + + @BeforeClass + public static void setUp() throws Exception { + IEclipsePreferences defaultPreferences = InstanceScope.INSTANCE.getNode(Activator.PLUGIN_ID); + defaultPreferences.put(ITmfTimePreferencesConstants.DATIME, "MMM d HH:mm:ss"); + defaultPreferences.put(ITmfTimePreferencesConstants.SUBSEC, ITmfTimePreferencesConstants.SUBSEC_NO_FMT); + defaultPreferences.put(ITmfTimePreferencesConstants.LOCALE, Locale.CANADA.toLanguageTag()); + TmfTimestampFormat.updateDefaultFormats(); + + if (fTrace == null) { + try { + URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(PATH), null); + URI uri = FileLocator.toFileURL(location).toURI(); + fTestFile = new File(uri); + + fTrace = new SyslogTrace(); + IResource resource = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(PATH)); + fTrace.initTrace(resource, uri.getPath(), SyslogEvent.class); + // Dummy request to force the trace indexing + TmfEventRequest request = new TmfEventRequest( + SyslogEvent.class, + TmfTimeRange.ETERNITY, + 0, + ITmfEventRequest.ALL_DATA, + ExecutionType.FOREGROUND) { + }; + fTrace.sendRequest(request); + request.waitForCompletion(); + } catch (URISyntaxException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + @AfterClass + public static void tearDown() { + fTrace.dispose(); + fTrace = null; + IEclipsePreferences defaultPreferences = InstanceScope.INSTANCE.getNode(Activator.PLUGIN_ID); + defaultPreferences.put(ITmfTimePreferencesConstants.DATIME, ITmfTimePreferencesConstants.TIME_HOUR_FMT); + defaultPreferences.put(ITmfTimePreferencesConstants.SUBSEC, ITmfTimePreferencesConstants.SUBSEC_NANO_FMT); + defaultPreferences.put(ITmfTimePreferencesConstants.LOCALE, Locale.getDefault().toLanguageTag()); + TmfTimestampFormat.updateDefaultFormats(); + } + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + @Test + public void testEmptyConstructor() { + SyslogTrace trace = new SyslogTrace(); + assertEquals("getType", null, trace.getType()); + assertEquals("getPath", null, trace.getPath()); + assertEquals("getName", "", trace.getName()); + assertEquals("getCacheSize", 100, trace.getCacheSize()); + + TmfTimestamp initRange = new TmfTimestamp(60, ITmfTimestamp.SECOND_SCALE); + assertEquals("getInitialRangeOffset", initRange, trace.getInitialRangeOffset()); + } + + @Test + public void testValidation() throws URISyntaxException, IOException { + SyslogTrace trace = new SyslogTrace(); + String validTracePath = fTestFile.getAbsolutePath(); + IStatus status = trace.validate(null, validTracePath); + assertTrue(status.isOK()); + assertTrue(status instanceof TraceValidationStatus); + assertEquals(180, ((TraceValidationStatus) status).getConfidence()); + + URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(OTHER_PATH), null); + URI uri = FileLocator.toFileURL(location).toURI(); + File otherFile = new File(uri); + + String validNoConfidenceTrace = otherFile.getAbsolutePath(); + status = trace.validate(null, validNoConfidenceTrace); + assertTrue(status instanceof TraceValidationStatus); + assertEquals(0, ((TraceValidationStatus) status).getConfidence()); + assertTrue(status.isOK()); + + String invalidTrace = fTestFile.getParentFile().getAbsolutePath(); + status = trace.validate(null, invalidTrace); + assertFalse(status.isOK()); + } + + @Test + public void testInitTrace() throws Exception { + URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(PATH), null); + String path = FileLocator.toFileURL(location).toURI().getPath(); + SyslogTrace trace = new SyslogTrace(); + IResource resource = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(PATH)); + trace.initTrace(resource, path, SyslogEvent.class); + assertEquals("getType", SyslogEvent.class, trace.getType()); + assertEquals("getPath", fTestFile.toURI().getPath(), trace.getPath()); + assertEquals("getName", NAME, trace.getName()); + assertEquals("getCacheSize", 100, trace.getCacheSize()); + } + + // ------------------------------------------------------------------------ + // Indexing + // ------------------------------------------------------------------------ + + @Test + public void testTraceIndexing() { + assertEquals("getNbEvents", 6, fTrace.getNbEvents()); + + TmfTimestamp initRange = new TmfTimestamp(60, ITmfTimestamp.SECOND_SCALE); + assertEquals("getInitialRangeOffset", initRange, fTrace.getInitialRangeOffset()); + } + + // ------------------------------------------------------------------------ + // Parsing + // ------------------------------------------------------------------------ + + @Test + public void testTraceParsing() { + ITmfContext context = fTrace.seekEvent(0); + SyslogEvent event = fTrace.getNext(context); + TextTraceEventContent content = event.getContent(); + assertEquals("getTimestamp", "Jan 1 01:01:01", event.getTimestamp().toString()); + assertEquals("getField:TIMESTAMP", "Jan 1 01:01:01", content.getFieldValue(Index.TIMESTAMP)); + assertEquals("getField:HOST", "HostA", content.getFieldValue(Index.HOST)); + assertEquals("getField:LOGGER", "LoggerA", content.getFieldValue(Index.LOGGER)); + assertEquals("getField:MESSAGE", "Message A", content.getFieldValue(Index.MESSAGE).toString()); + event = fTrace.getNext(context); + content = event.getContent(); + assertEquals("getTimestamp", "Jan 1 02:02:02", event.getTimestamp().toString()); + assertEquals("getField:TIMESTAMP", "Jan 1 02:02:02", content.getFieldValue(Index.TIMESTAMP)); + assertEquals("getField:HOST", "HostB", content.getFieldValue(Index.HOST)); + assertEquals("getField:LOGGER", "LoggerB", content.getFieldValue(Index.LOGGER)); + assertEquals("getField:MESSAGE", "Message B", content.getFieldValue(Index.MESSAGE).toString()); + event = fTrace.getNext(context); + content = event.getContent(); + assertEquals("getTimestamp", "Jan 1 03:03:03", event.getTimestamp().toString()); + assertEquals("getField:TIMESTAMP", "Jan 1 03:03:03", content.getFieldValue(Index.TIMESTAMP)); + assertEquals("getField:HOST", "HostC", content.getFieldValue(Index.HOST)); + assertEquals("getField:LOGGER", "LoggerC", content.getFieldValue(Index.LOGGER)); + assertEquals("getField:MESSAGE", "Message C", content.getFieldValue(Index.MESSAGE).toString()); + event = fTrace.getNext(context); + content = event.getContent(); + assertEquals("getTimestamp", "Jan 1 04:04:04", event.getTimestamp().toString()); + assertEquals("getField:TIMESTAMP", "Jan 1 04:04:04", content.getFieldValue(Index.TIMESTAMP)); + assertEquals("getField:HOST", "HostD", content.getFieldValue(Index.HOST)); + assertEquals("getField:LOGGER", "LoggerD", content.getFieldValue(Index.LOGGER)); + assertEquals("getField:MESSAGE", "Message D", content.getFieldValue(Index.MESSAGE).toString()); + event = fTrace.getNext(context); + content = event.getContent(); + assertEquals("getTimestamp", "Jan 1 05:05:05", event.getTimestamp().toString()); + assertEquals("getField:TIMESTAMP", "Jan 1 05:05:05", content.getFieldValue(Index.TIMESTAMP)); + assertEquals("getField:HOST", "HostE", content.getFieldValue(Index.HOST)); + assertEquals("getField:LOGGER", "LoggerE", content.getFieldValue(Index.LOGGER)); + assertEquals("getField:MESSAGE", "", content.getFieldValue(Index.MESSAGE).toString()); + event = fTrace.getNext(context); + content = event.getContent(); + assertEquals("getTimestamp", "Jan 1 06:06:06", event.getTimestamp().toString()); + assertEquals("getField:TIMESTAMP", "Jan 1 06:06:06", content.getFieldValue(Index.TIMESTAMP)); + assertEquals("getField:HOST", "HostF", content.getFieldValue(Index.HOST)); + assertEquals("getField:LOGGER", "LoggerF", content.getFieldValue(Index.LOGGER)); + assertEquals("getField:MESSAGE", "Message F", content.getFieldValue(Index.MESSAGE).toString()); + event = fTrace.getNext(context); + assertEquals("event", null, event); + context.dispose(); + } + + @Test + public void testLocationRatio() { + ITmfContext context = fTrace.seekEvent(3); + double ratio = fTrace.getLocationRatio(context.getLocation()); + SyslogEvent event = fTrace.getNext(context); + TextTraceEventContent content = event.getContent(); + Object logger = content.getFieldValue(Index.LOGGER); + context.dispose(); + context = fTrace.seekEvent(ratio); + event = fTrace.getNext(context); + content = event.getContent(); + assertEquals("getField:LOGGER", logger.toString(), content.getFieldValue(Index.LOGGER).toString()); + context.dispose(); + context = fTrace.seekEvent(0.0); + event = fTrace.getNext(context); + content = event.getContent(); + assertEquals("getField:LOGGER", "LoggerA", content.getFieldValue(Index.LOGGER)); + context.dispose(); + context = fTrace.seekEvent(1.0); + event = fTrace.getNext(context); + assertEquals("event", null, event); + context.dispose(); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/uml2sd/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/uml2sd/AllTests.java new file mode 100644 index 0000000000..b1509a2081 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/uml2sd/AllTests.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.uml2sd; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Unit tests for tmf.core.uml2sd + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TmfAsyncSequenceDiagramEventTest.class, + TmfSyncSequenceDiagramEventTest.class +}) +public class AllTests { + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/uml2sd/TmfAsyncSequenceDiagramEventTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/uml2sd/TmfAsyncSequenceDiagramEventTest.java new file mode 100644 index 0000000000..fe093ca3c5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/uml2sd/TmfAsyncSequenceDiagramEventTest.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.uml2sd; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.uml2sd.TmfAsyncSequenceDiagramEvent; +import org.junit.Test; + +/** + * TmfAsyncSequenceDiagramEventTest + */ +public class TmfAsyncSequenceDiagramEventTest { + + private final String fContext = ITmfEventType.DEFAULT_CONTEXT_ID; + private final String fTypeId = "Some type"; + private final String fLabel0 = "label1"; + private final String fLabel1 = "label2"; + private final String[] fLabels = new String[] { fLabel0, fLabel1 }; + + private final TmfTimestamp fTimestamp1 = new TmfTimestamp(12345, (byte) 2, 5); + private final TmfTimestamp fTimestamp2 = new TmfTimestamp(12350, (byte) 2, 5); + private final String fSource = "Source"; + private final TmfEventType fType = new TmfEventType(fContext, fTypeId, TmfEventField.makeRoot(fLabels)); + private final String fReference = "Some reference"; + + private final ITmfEvent fEvent1; + private final ITmfEvent fEvent2; + private final TmfEventField fContent1; + private final TmfEventField fContent2; + + /** + * Constructor for the test case + */ + public TmfAsyncSequenceDiagramEventTest() { + fContent1 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some content", null); + fEvent1 = new TmfEvent(null, fTimestamp1, fSource, fType, fContent1, fReference); + + fContent2 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some other content", null); + fEvent2 = new TmfEvent(null, fTimestamp2, fSource, fType, fContent2, fReference); + } + + /** + * Main test + */ + @Test + public void testTmfAsyncSequenceDiagramEvent() { + TmfAsyncSequenceDiagramEvent event = null; + + // Check for illegal arguments (i.e. null for the parameters) + try { + event = new TmfAsyncSequenceDiagramEvent(null, null, null, null, null); + fail(); + } catch (IllegalArgumentException e) { + // success + assertTrue("TmfAsyncSequenceDiagramEvent", e.getMessage().contains("startEvent=null")); + } + + try { + event = new TmfAsyncSequenceDiagramEvent(fEvent1, fEvent2, null, null, null); + fail(); + } catch (IllegalArgumentException e) { + // success + assertTrue("TmfAsyncSequenceDiagramEvent", e.getMessage().contains("sender=null")); + } + + try { + event = new TmfAsyncSequenceDiagramEvent(fEvent1, fEvent2, null, null, null); + fail(); + } catch (IllegalArgumentException e) { + // success + assertTrue("TmfAsyncSequenceDiagramEvent", e.getMessage().contains("receiver=null")); + } + + try { + event = new TmfAsyncSequenceDiagramEvent(fEvent1, fEvent2, "sender", null, null); + fail(); + } catch (IllegalArgumentException e) { + // success + assertTrue("TmfAsyncSequenceDiagramEvent", e.getMessage().contains("name=null")); + } + + try { + event = new TmfAsyncSequenceDiagramEvent(fEvent1, null, "sender", "receiver", "signal"); + fail(); + } catch (IllegalArgumentException e) { + // success + assertTrue("TmfAsyncSequenceDiagramEvent", e.getMessage().contains("endEvent=null")); + } + + try { + event = new TmfAsyncSequenceDiagramEvent(fEvent1, fEvent2, "sender", "receiver", "signal"); + // success + assertEquals("testTmfAsyncSequenceDiagramEvent", 0, event.getStartTime().compareTo(fTimestamp1, true)); + assertEquals("testTmfAsyncSequenceDiagramEvent", 0, event.getEndTime().compareTo(fTimestamp2, true)); + assertEquals("testTmfAsyncSequenceDiagramEvent", "sender", event.getSender()); + assertEquals("testTmfAsyncSequenceDiagramEvent", "receiver", event.getReceiver()); + assertEquals("testTmfAsyncSequenceDiagramEvent", "signal", event.getName()); + + } catch (IllegalArgumentException e) { + fail(); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/uml2sd/TmfSyncSequenceDiagramEventTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/uml2sd/TmfSyncSequenceDiagramEventTest.java new file mode 100644 index 0000000000..e0f1b29546 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/uml2sd/TmfSyncSequenceDiagramEventTest.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.uml2sd; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.uml2sd.TmfSyncSequenceDiagramEvent; +import org.junit.Test; + +/** + * TmfSyncSequenceDiagramEventTest + */ +public class TmfSyncSequenceDiagramEventTest { + + private final String fContext = ITmfEventType.DEFAULT_CONTEXT_ID; + private final String fTypeId = "Some type"; + private final String fLabel0 = "label1"; + private final String fLabel1 = "label2"; + private final String[] fLabels = new String[] { fLabel0, fLabel1 }; + + private final TmfTimestamp fTimestamp1 = new TmfTimestamp(12345, (byte) 2, 5); + private final String fSource = "Source"; + private final TmfEventType fType = new TmfEventType(fContext, fTypeId, TmfEventField.makeRoot(fLabels)); + private final String fReference = "Some reference"; + + private final ITmfEvent fEvent1; + private final TmfEventField fContent1; + + /** + * Constructor for the test case + */ + public TmfSyncSequenceDiagramEventTest() { + fContent1 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some content", null); + fEvent1 = new TmfEvent(null, fTimestamp1, fSource, fType, fContent1, fReference); + } + + /** + * Main test + */ + @Test + public void testTmfSyncSequenceDiagramEvent() { + TmfSyncSequenceDiagramEvent event = null; + try { + event = new TmfSyncSequenceDiagramEvent(null, null, null, null); + fail(); + } catch (IllegalArgumentException e) { + // success + assertTrue("testTmfSyncSequenceDiagramEvent", e.getMessage().contains("startEvent=null")); + } + + try { + event = new TmfSyncSequenceDiagramEvent(fEvent1, null, null, null); + fail(); + } catch (IllegalArgumentException e) { + // success + assertTrue("testTmfSyncSequenceDiagramEvent", e.getMessage().contains("sender=null")); + } + + try { + event = new TmfSyncSequenceDiagramEvent(fEvent1, "sender", null, null); + fail(); + } catch (IllegalArgumentException e) { + // success + assertTrue("testTmfSyncSequenceDiagramEvent", e.getMessage().contains("receiver=null")); + } + + try { + event = new TmfSyncSequenceDiagramEvent(fEvent1, "sender", "receiver", null); + fail(); + } catch (IllegalArgumentException e) { + // success + assertTrue("testTmfSyncSequenceDiagramEvent", e.getMessage().contains("name=null")); + } + + try { + event = new TmfSyncSequenceDiagramEvent(fEvent1, "sender", "receiver", "signal"); + // success + assertEquals("testTmfSyncSequenceDiagramEvent", 0, event.getStartTime().compareTo(fTimestamp1, true)); + assertEquals("testTmfSyncSequenceDiagramEvent", "sender", event.getSender()); + assertEquals("testTmfSyncSequenceDiagramEvent", "receiver", event.getReceiver()); + assertEquals("testTmfSyncSequenceDiagramEvent", "signal", event.getName()); + + } catch (IllegalArgumentException e) { + fail(); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/util/AllTests.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/util/AllTests.java new file mode 100644 index 0000000000..7fbfa4b611 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/util/AllTests.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.util; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Unit tests for tmf.core.util + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + PairTest.class +}) +public class AllTests { + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/util/PairTest.java b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/util/PairTest.java new file mode 100644 index 0000000000..871b7ba20d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/util/PairTest.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial design and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.eclipse.tracecompass.tmf.core.util.Pair; +import org.junit.Test; + +/** + * Test case for Pair class. + * + * @author Bernd Hufmann + */ +@SuppressWarnings("javadoc") +public class PairTest { + + // ------------------------------------------------------------------------ + // Field(s) + // ------------------------------------------------------------------------ + + Pair fPair1 = new Pair<>("String 1", 1L); + Pair fPair2 = new Pair<>("String 2", 2L); + + // ------------------------------------------------------------------------ + // to String + // ------------------------------------------------------------------------ + + @Test + public void testToString() { + String result = fPair1.toString(); + assertEquals("(String 1, 1)", result); + } + + // ------------------------------------------------------------------------ + // Setters/Getters + // ------------------------------------------------------------------------ + + @Test + public void testAccessors() { + Pair myPair = new Pair<>("String 1", 1L); + assertEquals("String 1", myPair.getFirst()); + assertEquals(Long.valueOf(1L), myPair.getSecond()); + + myPair.setFirst("Hello"); + assertEquals("Hello", myPair.getFirst()); + + myPair.setSecond(123L); + assertEquals(Long.valueOf(123L), myPair.getSecond()); + } + + // ------------------------------------------------------------------------ + // equals + // ------------------------------------------------------------------------ + + @Test + public void testEqualsReflexivity() { + assertTrue("equals", fPair1.equals(fPair1)); + assertTrue("equals", fPair2.equals(fPair2)); + + assertTrue("equals", !fPair1.equals(fPair2)); + assertTrue("equals", !fPair2.equals(fPair1)); + } + + @Test + public void testEqualsSymmetry() { + Pair info1 = new Pair<>(fPair1.getFirst(), fPair1.getSecond().longValue()); + Pair info2 = new Pair<>(fPair2.getFirst(), fPair2.getSecond().longValue()); + + assertTrue("equals", info1.equals(fPair1)); + assertTrue("equals", fPair1.equals(info1)); + + assertTrue("equals", info2.equals(fPair2)); + assertTrue("equals", fPair2.equals(info2)); + } + + @Test + public void testEqualsTransivity() { + Pair info1 = new Pair<>(fPair1.getFirst(), fPair1.getSecond().longValue()); + Pair info2 = new Pair<>(fPair1.getFirst(), fPair1.getSecond().longValue()); + Pair info3 = new Pair<>(fPair1.getFirst(), fPair1.getSecond().longValue()); + + assertTrue("equals", info1.equals(info2)); + assertTrue("equals", info2.equals(info3)); + assertTrue("equals", info1.equals(info3)); + } + + @Test + public void testEqualsNull() { + assertTrue("equals", !fPair1.equals(null)); + assertTrue("equals", !fPair2.equals(null)); + } + + @Test + public void testEqualsDifferentObj() { + Pair info = new Pair<>(1L, "String1"); + assertTrue("equals", !fPair1.equals(info)); + } + + // ------------------------------------------------------------------------ + // hashCode + // ------------------------------------------------------------------------ + + @Test + public void testHashCode() { + Pair info1 = new Pair<>(fPair1.getFirst(), fPair1.getSecond().longValue()); + Pair info2 = new Pair<>(fPair2.getFirst(), fPair2.getSecond().longValue()); + + assertTrue("hashCode", fPair1.hashCode() == info1.hashCode()); + assertTrue("hashCode", fPair2.hashCode() == info2.hashCode()); + + assertTrue("hashCode", fPair1.hashCode() != info2.hashCode()); + assertTrue("hashCode", fPair2.hashCode() != info1.hashCode()); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/CreateTestFiles.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/CreateTestFiles.java deleted file mode 100644 index 4ce1eb5db0..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/CreateTestFiles.java +++ /dev/null @@ -1,113 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs; - -import java.io.BufferedOutputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Random; - -/** - * CreateTestFiles - *

- * Create a number of event test files of various lengths. - *

- * Events have the following format: - *

    - *
  • [timestamp] [source] [type] [ref] [field]* - *
  • There are NB_SOURCES sources and NB_TYPES types. - *
  • The number of fields (0 .. NB_TYPES-1) depends on the event type. - *
- */ -public class CreateTestFiles { - - // ======================================================================== - // Constants - // ======================================================================== - - private static final String DIRECTORY = "testfiles"; - // private static final String FILE_NAMES[] = { "Test-10", "Test-1K", "Test-10K", "Test-100K" }; - // private static final int FILE_SIZES[] = { 10 , 1000 , 10000 , 100000 }; - private static final String FILE_NAMES[] = { "Test-10K" }; - private static final int FILE_SIZES[] = { 10000 }; - - private static final int NB_SOURCES = 15; - private static final int NB_TYPES = 7; - - // ======================================================================== - // Constructors - // ======================================================================== - - /** - * @param args unused - */ - public static void main(final String[] args) { - - try { - System.out.println("Creating test files in directory: " + new File(".").getCanonicalPath() + File.separator + DIRECTORY); - } catch (final IOException e) { - e.printStackTrace(); - } - - for (int i = 0; i < FILE_SIZES.length; i++) { - try { - createTestFile("testfiles" + File.separator + "O-" + FILE_NAMES[i], FILE_SIZES[i], true, true); - createTestFile("testfiles" + File.separator + "E-" + FILE_NAMES[i], FILE_SIZES[i], true, false); - createTestFile("testfiles" + File.separator + "R-" + FILE_NAMES[i], FILE_SIZES[i], false, false); - } catch (final FileNotFoundException e) { - } catch (final IOException e) { - } - } - - System.out.println("Done."); - } - - // ======================================================================== - // Operators - // ======================================================================== - - /** - * @param file - * @param size - * @param monotonic - * @throws FileNotFoundException - * @throws IOException - */ - private static void createTestFile(final String file, final int size, - final boolean monotonic, final boolean odd) - throws IOException { - System.out.println("Creating " + file); - try (DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));) { - - final Random generator = new Random(19580427 + size); - long ts = (monotonic && odd) ? -1 : 0; - for (int i = 0; i < size; i++) { - ts += monotonic ? 2 : generator.nextInt(10); - final int sourceIndex = i % NB_SOURCES; - final int typeIndex = i % NB_TYPES; - out.writeLong(ts); // Timestamp - out.writeUTF("Source-" + sourceIndex); // Source - out.writeUTF("Type-" + typeIndex); // Type - out.writeInt(i + 1); // Reference (event #) - for (int j = 0; j < typeIndex; j++) { - out.writeUTF("Field-" + sourceIndex + "-" + j); - } - } - out.flush(); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/AnalysisModuleSourceStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/AnalysisModuleSourceStub.java deleted file mode 100644 index 4e3faa5c2d..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/AnalysisModuleSourceStub.java +++ /dev/null @@ -1,39 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.analysis; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleSource; -import org.eclipse.linuxtools.tmf.tests.stubs.analysis.AnalysisModuleTestHelper.moduleStubEnum; - -/** - * Stub class for analysis module source - * - * @author Geneviève Bastien - */ -public class AnalysisModuleSourceStub implements IAnalysisModuleSource { - - @Override - public Iterable getAnalysisModules() { - List list = new ArrayList<>(); - IAnalysisModuleHelper helper = new AnalysisModuleTestHelper(moduleStubEnum.TEST); - list.add(helper); - helper = new AnalysisModuleTestHelper(moduleStubEnum.TEST2); - list.add(helper); - return list; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/AnalysisModuleTestHelper.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/AnalysisModuleTestHelper.java deleted file mode 100644 index b53246213c..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/AnalysisModuleTestHelper.java +++ /dev/null @@ -1,154 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - * Guilliano Molaire - Implementation of requirements and valid trace types getters - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.analysis; - -import java.util.Collections; - -import org.eclipse.core.runtime.Platform; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisRequirement; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub2; -import org.osgi.framework.Bundle; - -import com.google.common.collect.ImmutableList; - -/** - * Analysis Module Helper for the stub analysis source - * - * @author Geneviève Bastien - */ -public class AnalysisModuleTestHelper implements IAnalysisModuleHelper { - - /** - * Enum to select an analysis module for this stub - */ - public enum moduleStubEnum { - /** Test analysis */ - TEST, - /** Test analysis 2 */ - TEST2 - } - - private moduleStubEnum fModule; - - /** - * Constructor - * - * @param module - * The type identifying the module for this helper - */ - public AnalysisModuleTestHelper(moduleStubEnum module) { - fModule = module; - } - - @Override - public String getId() { - return fModule.name(); - } - - @Override - public String getName() { - return fModule.name(); - } - - @Override - public boolean isAutomatic() { - return false; - } - - @Override - public String getHelpText() { - return ""; - } - - @Override - public String getHelpText(@NonNull ITmfTrace trace) { - return ""; - } - - @Override - public String getIcon() { - return ""; - } - - @Override - public Bundle getBundle() { - return Platform.getBundle("org.eclipse.linuxtools.tmf.core.tests"); - } - - @Override - public boolean appliesToTraceType(Class traceclass) { - switch (fModule) { - case TEST: - return TmfTraceStub.class.isAssignableFrom(traceclass); - case TEST2: - return TmfTraceStub2.class.isAssignableFrom(traceclass); - default: - return false; - } - } - - @Override - public IAnalysisModule newModule(ITmfTrace trace) throws TmfAnalysisException { - IAnalysisModule module = null; - switch (fModule) { - case TEST: - module = new TestAnalysis(); - module.setName(getName()); - module.setId(getId()); - module.setAutomatic(isAutomatic()); - module.setTrace(trace); - break; - case TEST2: - module = new TestAnalysis2(); - module.setName(getName()); - module.setId(getId()); - module.setAutomatic(isAutomatic()); - module.setTrace(trace); - break; - default: - break; - - } - return module; - } - - @Override - public Iterable> getValidTraceTypes() { - return ImmutableList.> of( - TmfTraceStub.class, - TmfTraceStub2.class); - } - - @Override - public Iterable getAnalysisRequirements() { - switch (fModule) { - case TEST: - return ImmutableList.of( - AnalysisRequirementFactory.REQUIREMENT_1, - AnalysisRequirementFactory.REQUIREMENT_3); - case TEST2: - return ImmutableList.of( - AnalysisRequirementFactory.REQUIREMENT_2, - AnalysisRequirementFactory.REQUIREMENT_3); - default: - return Collections.EMPTY_SET; - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/AnalysisRequirementFactory.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/AnalysisRequirementFactory.java deleted file mode 100644 index 21f5b98e12..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/AnalysisRequirementFactory.java +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Guilliano Molaire - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.analysis; - -import java.util.Set; - -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisRequirement; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisRequirement.ValuePriorityLevel; - -import com.google.common.collect.ImmutableSet; - -/** - * Factory class to facilitate requirement usage across test case - */ -@SuppressWarnings("javadoc") -public final class AnalysisRequirementFactory { - - private AnalysisRequirementFactory() {} - - public static final String REQUIREMENT_TYPE_1 = "car"; - public static final String REQUIREMENT_TYPE_2 = "factory"; - public static final String REQUIREMENT_TYPE_3 = "code"; - - public static final String REQUIREMENT_VALUE_1 = "value1"; - public static final String REQUIREMENT_VALUE_2 = "value2"; - public static final String REQUIREMENT_VALUE_3 = "value3"; - public static final String REQUIREMENT_VALUE_4 = "value4"; - public static final String REQUIREMENT_VALUE_5 = "value5"; - - public static final Set REQUIREMENT_VALUES_1 = ImmutableSet.of( - REQUIREMENT_VALUE_1, - REQUIREMENT_VALUE_2, - REQUIREMENT_VALUE_3, - REQUIREMENT_VALUE_5 - ); - - public static final Set REQUIREMENT_VALUES_2 = ImmutableSet.of( - REQUIREMENT_VALUE_2, - REQUIREMENT_VALUE_3 - ); - - public static final Set REQUIREMENT_VALUES_3 = ImmutableSet.of( - REQUIREMENT_VALUE_3, - REQUIREMENT_VALUE_4, - REQUIREMENT_VALUE_5 - ); - - public static final TmfAnalysisRequirement REQUIREMENT_1 = - new TmfAnalysisRequirement(REQUIREMENT_TYPE_1, REQUIREMENT_VALUES_1, ValuePriorityLevel.MANDATORY); - public static final TmfAnalysisRequirement REQUIREMENT_2 = - new TmfAnalysisRequirement(REQUIREMENT_TYPE_2); - public static final TmfAnalysisRequirement REQUIREMENT_3 = - new TmfAnalysisRequirement(REQUIREMENT_TYPE_3, REQUIREMENT_VALUES_3, ValuePriorityLevel.MANDATORY); - - static { - REQUIREMENT_2.addValue(REQUIREMENT_VALUE_1, ValuePriorityLevel.MANDATORY); - REQUIREMENT_2.addValue(REQUIREMENT_VALUE_2, ValuePriorityLevel.OPTIONAL); - REQUIREMENT_2.addValue(REQUIREMENT_VALUE_3, ValuePriorityLevel.MANDATORY); - REQUIREMENT_2.addValue(REQUIREMENT_VALUE_4, ValuePriorityLevel.OPTIONAL); - REQUIREMENT_2.addValue(REQUIREMENT_VALUE_5, ValuePriorityLevel.MANDATORY); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestAnalysis.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestAnalysis.java deleted file mode 100644 index bc00b59fde..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestAnalysis.java +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.analysis; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAbstractAnalysisModule; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Simple analysis type for test - */ -public class TestAnalysis extends TmfAbstractAnalysisModule { - - private int output = 0; - - /** - * Test parameter. If set, simulate cancellation - */ - public static final String PARAM_TEST = "test"; - - /** - * Constructor - */ - public TestAnalysis() { - super(); - } - - @Override - public boolean canExecute(ITmfTrace trace) { - return true; - } - - @Override - protected boolean executeAnalysis(final IProgressMonitor monitor) { - if (getParameter(PARAM_TEST) == null) { - throw new RuntimeException("The parameter should be set"); - } - /* If PARAM_TEST is set to 0, simulate cancellation */ - if ((Integer) getParameter(PARAM_TEST) == 0) { - output = 0; - return false; - } else if ((Integer) getParameter(PARAM_TEST) == 999) { - /* just stay in an infinite loop until cancellation */ - while (!monitor.isCanceled()) { - - } - return !monitor.isCanceled(); - } - output = (Integer) getParameter(PARAM_TEST); - return true; - } - - @Override - protected void canceling() { - output = -1; - } - - @Override - public Object getParameter(String name) { - Object value = super.getParameter(name); - if ((value != null) && name.equals(PARAM_TEST) && (value instanceof String)) { - return Integer.decode((String) value); - } - return value; - } - - @Override - protected void parameterChanged(String name) { - schedule(); - } - - /** - * Get the analysis output value - * - * @return The analysis output - */ - public int getAnalysisOutput() { - return output; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestAnalysis2.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestAnalysis2.java deleted file mode 100644 index 6fe7fd3e20..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestAnalysis2.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.analysis; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAbstractAnalysisModule; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub2; - -/** - * Simple analysis type for test - */ -public class TestAnalysis2 extends TmfAbstractAnalysisModule { - - @Override - public boolean canExecute(ITmfTrace trace) { - /* This just makes sure the trace is a trace stub 2 */ - return (TmfTraceStub2.class.isAssignableFrom(trace.getClass())); - } - - @Override - protected void canceling() { - - } - - @Override - protected boolean executeAnalysis(final IProgressMonitor monitor) { - return false; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestAnalysisParameterProvider.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestAnalysisParameterProvider.java deleted file mode 100644 index b5614e8487..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestAnalysisParameterProvider.java +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.analysis; - -import org.eclipse.linuxtools.tmf.core.analysis.TmfAbstractAnalysisParamProvider; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; - -/** - * Test parameter provider for the PARAM_TEST that would apply only to - * CtfTmfTrace (though it is associated with an analysis that supports all trace - * types) - * - * @author Geneviève Bastien - */ -public class TestAnalysisParameterProvider extends TmfAbstractAnalysisParamProvider { - - private int fValue = 10; - - @Override - public String getName() { - return "test parameter provider"; - } - - @Override - public Object getParameter(String name) { - if (name.equals(TestAnalysis.PARAM_TEST)) { - return fValue; - } - return null; - } - - @Override - public boolean appliesToTrace(ITmfTrace trace) { - return (trace instanceof TmfTraceStub); - } - - /** - * Sets a new value for the parameter - * - * @param value - * new parameter value - */ - public void setValue(int value) { - fValue = value; - notifyParameterChanged(TestAnalysis.PARAM_TEST); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestExperimentAnalysis.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestExperimentAnalysis.java deleted file mode 100644 index dad0024376..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestExperimentAnalysis.java +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.analysis; - -import java.util.HashSet; -import java.util.Set; - -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.statesystem.AbstractTmfStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Stubs for experiment analysis. This analysis is a state system analysis that - * simply counts the number of traces for which events were received. The number - * of traces is the value of attribute - * {@link TestExperimentAnalysis#TRACE_QUARK_NAME}. - * - * @author Geneviève Bastien - */ -public class TestExperimentAnalysis extends TmfStateSystemAnalysisModule { - - /** - * The quark counting the number of traces - */ - public static final String TRACE_QUARK_NAME = "Traces"; - - @Override - protected ITmfStateProvider createStateProvider() { - return new TestExpStateSystemProvider(getTrace()); - } - - @Override - protected StateSystemBackendType getBackendType() { - return StateSystemBackendType.INMEM; - } - - private class TestExpStateSystemProvider extends AbstractTmfStateProvider { - - private static final int VERSION = 1; - private final Set fTraces = new HashSet<>(); - private int fCount = 0; - - /** - * Constructor - * - * @param trace - * The LTTng 2.0 kernel trace directory - */ - public TestExpStateSystemProvider(ITmfTrace trace) { - super(trace, TmfEvent.class, "Stub State System for Experiment"); - } - - @Override - public int getVersion() { - return VERSION; - } - - @Override - public ITmfStateProvider getNewInstance() { - return new TestExpStateSystemProvider(this.getTrace()); - } - - @Override - protected void eventHandle(ITmfEvent event) { - if (!fTraces.contains(event.getTrace())) { - try { - int quarkId = ss.getQuarkAbsoluteAndAdd(TRACE_QUARK_NAME); - ss.modifyAttribute(event.getTimestamp().getValue(), TmfStateValue.newValueInt(++fCount), quarkId); - fTraces.add(event.getTrace()); - } catch (TimeRangeException | AttributeNotFoundException | StateValueTypeException e) { - - } - } - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestRequirementAnalysis.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestRequirementAnalysis.java deleted file mode 100644 index 08f2e6822d..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestRequirementAnalysis.java +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Rail - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.analysis; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAbstractAnalysisModule; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisRequirement; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisRequirement.ValuePriorityLevel; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; - -/** - * Analysis type to test requirements acquisition - */ -@SuppressWarnings({ "javadoc", "nls" }) -public class TestRequirementAnalysis extends TmfAbstractAnalysisModule { - /* Test requirement types */ - public static final String EVENT_TYPE = "event"; - public static final String FIELD_TYPE = "field"; - - /* A few event names */ - public static final String EXIT_SYSCALL = "exit_syscall"; - public static final String SCHED_SWITCH = "sched_switch"; - public static final String SCHED_WAKEUP = "sched_wakeup"; - - /* A few fields */ - public static final String PID = "pid"; - public static final String TID = "tid"; - - @Override - public boolean canExecute(ITmfTrace trace) { - /* This just makes sure the trace is a ctf stub trace */ - return (TmfTraceStub.class.isAssignableFrom(trace.getClass())); - } - - @Override - protected void canceling() { - - } - - @Override - protected boolean executeAnalysis(final IProgressMonitor monitor) { - return true; - } - - @Override - public void setTrace(ITmfTrace trace) throws TmfAnalysisException { - } - - @Override - public Iterable getAnalysisRequirements() { - Map requirements = new HashMap<>(); - - /* Event type requirement and values */ - requirements.put(EVENT_TYPE, new TmfAnalysisRequirement(EVENT_TYPE)); - requirements.get(EVENT_TYPE).addValue(EXIT_SYSCALL, ValuePriorityLevel.MANDATORY); - requirements.get(EVENT_TYPE).addValue(SCHED_SWITCH, ValuePriorityLevel.MANDATORY); - requirements.get(EVENT_TYPE).addValue(SCHED_WAKEUP, ValuePriorityLevel.MANDATORY); - - /* Field type requirement and values */ - requirements.put(FIELD_TYPE, new TmfAnalysisRequirement(FIELD_TYPE)); - requirements.get(FIELD_TYPE).addValue(PID, ValuePriorityLevel.MANDATORY); - requirements.get(FIELD_TYPE).addValue(TID, ValuePriorityLevel.MANDATORY); - - return requirements.values(); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestStateSystemModule.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestStateSystemModule.java deleted file mode 100644 index 0c392b01eb..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestStateSystemModule.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.analysis; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; - -/** - * Test State System module - * - * @author Geneviève Bastien - */ -@NonNullByDefault -public class TestStateSystemModule extends TmfStateSystemAnalysisModule { - - @Override - protected ITmfStateProvider createStateProvider() { - return new TestStateSystemProvider(getTrace()); - } - - @Override - protected StateSystemBackendType getBackendType() { - return StateSystemBackendType.INMEM; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestStateSystemProvider.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestStateSystemProvider.java deleted file mode 100644 index 1f08e47464..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestStateSystemProvider.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.analysis; - -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.statesystem.AbstractTmfStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateProvider; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Stub test provider for test state system analysis module - * - * @author Geneviève Bastien - */ -public class TestStateSystemProvider extends AbstractTmfStateProvider { - - private static final int VERSION = 1; - private final String fString = "[]"; - private int fCount = 0; - - /** - * Constructor - * - * @param trace - * The LTTng 2.0 kernel trace directory - */ - public TestStateSystemProvider(ITmfTrace trace) { - super(trace, TmfEvent.class, "Stub State System"); - } - - @Override - public int getVersion() { - return VERSION; - } - - @Override - public ITmfStateProvider getNewInstance() { - return new TestStateSystemProvider(this.getTrace()); - } - - @Override - protected void eventHandle(ITmfEvent event) { - /* Just need something to fill the state system */ - if (fString.equals(event.getContent().getValue())) { - try { - int quarkId = ss.getQuarkAbsoluteAndAdd("String"); - int quark = ss.getQuarkRelativeAndAdd(quarkId, fString); - ss.modifyAttribute(event.getTimestamp().getValue(), TmfStateValue.newValueInt(fCount++), quark); - } catch (TimeRangeException e) { - - } catch (AttributeNotFoundException e) { - - } catch (StateValueTypeException e) { - - } - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/component/TmfClientStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/component/TmfClientStub.java deleted file mode 100644 index d75fb51430..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/component/TmfClientStub.java +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.component; - -import org.eclipse.linuxtools.internal.tmf.core.component.TmfProviderManager; -import org.eclipse.linuxtools.tmf.core.component.TmfComponent; -import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider; -import org.eclipse.linuxtools.tmf.tests.stubs.event.TmfSyntheticEventStub; - -/** - * TmfClientStub - *

- * TODO: Implement me. Please. - */ -@SuppressWarnings("javadoc") -public class TmfClientStub extends TmfComponent { - - private TmfEventProvider[] fProviders; - - public TmfClientStub() { - super("TmfClientStub"); - } - - public void findProvider() { - fProviders = TmfProviderManager.getProviders(TmfSyntheticEventStub.class, TmfSyntheticEventProviderStub.class); - // TmfEventRequest request; - System.out.println(fProviders.length); - } - - public void triggeRequest() { - // TmfEventRequest request; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/component/TmfEventProviderStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/component/TmfEventProviderStub.java deleted file mode 100644 index 84397c7dcb..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/component/TmfEventProviderStub.java +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.component; - -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.tests.TmfCoreTestPlugin; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; - -/** - * TmfEventProviderStub - *

- * TODO: Implement me. Please. - */ -@SuppressWarnings("javadoc") -public class TmfEventProviderStub extends TmfEventProvider { - - private TmfTraceStub fTrace; - - public TmfEventProviderStub(final String path) throws IOException { - super(path, ITmfEvent.class); - final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(path), null); - try { - final File test = new File(FileLocator.toFileURL(location).toURI()); - fTrace = new TmfTraceStub(test.getPath(), 0, true, null); - } catch (final TmfTraceException e) { - e.printStackTrace(); - } catch (final URISyntaxException e) { - e.printStackTrace(); - } - } - - public TmfEventProviderStub() throws IOException { - this(TmfTestTrace.A_TEST_10K.getFullPath()); - } - - @Override - public void dispose() { - fTrace.dispose(); - super.dispose(); - } - - // ------------------------------------------------------------------------ - // TmfEventProvider - // ------------------------------------------------------------------------ - - @Override - public ITmfContext armRequest(final ITmfEventRequest request) { - final ITmfContext context = fTrace.seekEvent(request.getRange().getStartTime()); - return context; - } - - @Override - public ITmfEvent getNext(final ITmfContext context) { - return fTrace.getNext(context); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/component/TmfSyntheticEventProviderStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/component/TmfSyntheticEventProviderStub.java deleted file mode 100644 index 46c3d196f3..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/component/TmfSyntheticEventProviderStub.java +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.component; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; - -import org.eclipse.linuxtools.internal.tmf.core.component.TmfProviderManager; -import org.eclipse.linuxtools.tmf.core.component.ITmfEventProvider; -import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest.ExecutionType; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.TmfContext; -import org.eclipse.linuxtools.tmf.tests.stubs.event.TmfSyntheticEventStub; - -/** - * TmfSyntheticEventProviderStub - *

- * TODO: Implement me. Please. - */ -@SuppressWarnings("javadoc") -public class TmfSyntheticEventProviderStub extends TmfEventProvider { - - public static final int NB_EVENTS = 1000; - - private final BlockingQueue fDataQueue = new LinkedBlockingQueue<>(1000); - - public TmfSyntheticEventProviderStub() { - super("TmfSyntheticEventProviderStub", TmfSyntheticEventStub.class); - } - - @Override - public ITmfContext armRequest(final ITmfEventRequest request) { - - // Get the TmfSyntheticEventStub provider - final ITmfEventProvider[] eventProviders = TmfProviderManager.getProviders(ITmfEvent.class, TmfEventProviderStub.class); - final ITmfEventProvider provider = eventProviders[0]; - - final TmfTimeRange range = request.getRange(); - final TmfEventRequest subRequest = - new TmfEventRequest(ITmfEvent.class, range, 0, NB_EVENTS, ExecutionType.FOREGROUND) { - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - handleIncomingData(event); - } - }; - provider.sendRequest(subRequest); - - // Return a dummy context - return new TmfContext(); - } - - // Queue 2 synthetic events per base event - private void handleIncomingData(final ITmfEvent e) { - queueResult(new TmfSyntheticEventStub(e)); - queueResult(new TmfSyntheticEventStub(e)); - } - - private static final int TIMEOUT = 10000; - - @Override - public TmfSyntheticEventStub getNext(final ITmfContext context) { - TmfSyntheticEventStub data = null; - try { - data = (TmfSyntheticEventStub) fDataQueue.poll(TIMEOUT, TimeUnit.MILLISECONDS); - if (data == null) { - throw new InterruptedException(); - } - } - catch (final InterruptedException e) { - } - return data; - } - - public void queueResult(final TmfSyntheticEventStub data) { - boolean ok = false; - try { - ok = fDataQueue.offer(data, TIMEOUT, TimeUnit.MILLISECONDS); - if (!ok) { - throw new InterruptedException(); - } - } - catch (final InterruptedException e) { - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/event/TmfEventTypeStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/event/TmfEventTypeStub.java deleted file mode 100644 index 2ad3868199..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/event/TmfEventTypeStub.java +++ /dev/null @@ -1,38 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.event; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; - -/** - * TmfEventTypeStub - */ -@SuppressWarnings("javadoc") -public class TmfEventTypeStub extends TmfEventType { - - private static final ITmfEventField FIELD_1 = new TmfEventField("Field1", null, null); - private static final ITmfEventField FIELD_2 = new TmfEventField("Field2", null, null); - private static final ITmfEventField FIELD_3 = new TmfEventField("Field3", null, null); - private static final ITmfEventField FIELD_4 = new TmfEventField("Field4", null, null); - private static final ITmfEventField FIELD_5 = new TmfEventField("Field5", null, null); - - private static final ITmfEventField[] FIELDS = new ITmfEventField[] { - FIELD_1, FIELD_2, FIELD_3, FIELD_4, FIELD_5 }; - - private static ITmfEventField ROOT = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, null, FIELDS); - - public TmfEventTypeStub() { - super("UnitTest", "TmfEventTypeStub", ROOT); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/event/TmfSyncEventStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/event/TmfSyncEventStub.java deleted file mode 100644 index b8a0166ba1..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/event/TmfSyncEventStub.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.event; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Event stub used by the synchronization tests - * - * @author Geneviève Bastien - */ -public class TmfSyncEventStub extends TmfEvent { - - private static final String stub = "stub"; //$NON-NLS-1$ - - /** - * Constructor - * - * @param trace - * The trace of this event - * @param timestamp - * The timestamp - */ - public TmfSyncEventStub(final ITmfTrace trace, final ITmfTimestamp timestamp) { - super(trace, - timestamp, - stub, - new TmfEventTypeStub(), - new TmfEventField(stub, stub, null), - stub); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/event/TmfSyntheticEventStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/event/TmfSyntheticEventStub.java deleted file mode 100644 index 2b1dc92c8c..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/event/TmfSyntheticEventStub.java +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.event; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; - -/** - * TmfSyntheticEventStub - *

- * TODO: Implement me. Please. - */ -@SuppressWarnings("javadoc") -public class TmfSyntheticEventStub extends TmfEvent { - - - public TmfSyntheticEventStub(final ITmfEvent event) { - super(event); - } - public TmfSyntheticEventStub(final TmfSyntheticEventStub other) { - super(other); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/request/TmfEventRequestStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/request/TmfEventRequestStub.java deleted file mode 100644 index eb1d741f3e..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/request/TmfEventRequestStub.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.request; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; - -/** - * TmfEventRequestStub - */ -public class TmfEventRequestStub extends TmfEventRequest { - - /** - * @param dataType the event type - */ - public TmfEventRequestStub(final Class dataType) { - super(dataType, TmfTimeRange.ETERNITY, 0, ALL_DATA, ExecutionType.FOREGROUND); - } - - /** - * @param dataType the event type - * @param range the requested time range - */ - public TmfEventRequestStub(final Class dataType, final TmfTimeRange range) { - super(dataType, range, 0, ALL_DATA, ExecutionType.FOREGROUND); - } - - /** - * @param dataType the event type - * @param range the requested time range - * @param nbRequested the number of events requested - */ - public TmfEventRequestStub(final Class dataType, final TmfTimeRange range, final int nbRequested) { - super(dataType, range, 0, nbRequested, ExecutionType.FOREGROUND); - } - - /** - * @param dataType the event type - * @param range the requested time range - * @param nbRequested the number of events requested - * @param blockSize the event block size - */ - public TmfEventRequestStub(final Class dataType, final TmfTimeRange range, final int nbRequested, final int blockSize) { - super(dataType, range, 0, nbRequested, ExecutionType.FOREGROUND); - } - - /** - * @param dataType the event type - * @param range the requested time range - * @param index the initial event index - * @param nbRequested the number of events requested - * @param blockSize the event block size - */ - public TmfEventRequestStub(final Class dataType, final TmfTimeRange range, final long index, final int nbRequested, final int blockSize) { - super(dataType, range, index, nbRequested, ExecutionType.FOREGROUND); - } - - @Override - public void handleData(final ITmfEvent data) { - super.handleData(data); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfEmptyTraceStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfEmptyTraceStub.java deleted file mode 100644 index 3a5df51e06..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfEmptyTraceStub.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.trace; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.TmfContext; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - -/** - * TmfEmptyTraceStub - *

- * Dummy test trace. Use in conjunction with TmfEventParserStub. - */ -public class TmfEmptyTraceStub extends TmfTraceStub { - - /** - * - */ - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * - */ - public TmfEmptyTraceStub() { - super(); - setParser(new TmfEventParserStub(this)); - } - - // ------------------------------------------------------------------------ - // Operators - // ------------------------------------------------------------------------ - - @Override - public TmfContext seekEvent(final ITmfLocation location) { - return new TmfContext(); - } - - @Override - public TmfContext seekEvent(final double ratio) { - return new TmfContext(); - } - - @Override - public double getLocationRatio(ITmfLocation location) { - return 0; - } - - @Override - public ITmfLocation getCurrentLocation() { - return null; - } - - @Override - public ITmfEvent parseEvent(final ITmfContext context) { - return null; - } - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfEventParserStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfEventParserStub.java deleted file mode 100644 index 86def21e4f..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfEventParserStub.java +++ /dev/null @@ -1,125 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.trace; - -import java.io.EOFException; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.util.Vector; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * TmfEventParserStub - *

- * TODO: Implement me. Please. - */ -@SuppressWarnings("javadoc") -public class TmfEventParserStub implements ITmfEventParser { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private static final int NB_TYPES = 10; - private final TmfEventType[] fTypes; - private final ITmfTrace fEventStream; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - public TmfEventParserStub(final ITmfTrace eventStream) { - fEventStream = eventStream; - fTypes = new TmfEventType[NB_TYPES]; - for (int i = 0; i < NB_TYPES; i++) { - final Vector fields = new Vector<>(); - for (int j = 1; j <= i; j++) { - final String field = "Fmt-" + i + "-Fld-" + j; - fields.add(field); - } - final String[] fieldArray = new String[i]; - final ITmfEventField rootField = TmfEventField.makeRoot(fields.toArray(fieldArray)); - fTypes[i] = new TmfEventType("UnitTest", "Type-" + i, rootField); - } - } - - // ------------------------------------------------------------------------ - // Operators - // ------------------------------------------------------------------------ - - static final String typePrefix = "Type-"; - @Override - public ITmfEvent parseEvent(final ITmfContext context) { - - if (! (fEventStream instanceof TmfTraceStub)) { - return null; - } - - // Highly inefficient... - final RandomAccessFile stream = ((TmfTraceStub) fEventStream).getStream(); - if (stream == null) { - return null; - } - - // String name = eventStream.getName(); - // name = name.substring(name.lastIndexOf('/') + 1); - - // no need to use synchronized since it's already cover by the calling method - - long location = 0; - if (context != null && context.getLocation() != null) { - location = (Long) context.getLocation().getLocationInfo(); - try { - stream.seek(location); - - final long ts = stream.readLong(); - final String source = stream.readUTF(); - final String type = stream.readUTF(); - final int reference = stream.readInt(); - final int typeIndex = Integer.parseInt(type.substring(typePrefix.length())); - final String[] fields = new String[typeIndex]; - for (int i = 0; i < typeIndex; i++) { - fields[i] = stream.readUTF(); - } - - final StringBuffer content = new StringBuffer("["); - if (typeIndex > 0) { - content.append(fields[0]); - } - for (int i = 1; i < typeIndex; i++) { - content.append(", ").append(fields[i]); - } - content.append("]"); - - final TmfEventField root = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, content.toString(), null); - final ITmfEvent event = new TmfEvent(fEventStream, - new TmfTimestamp(ts, -3, 0), // millisecs - source, fTypes[typeIndex], root, String.valueOf(reference)); - return event; - } catch (final EOFException e) { - } catch (final IOException e) { - } - } - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfExperimentStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfExperimentStub.java deleted file mode 100644 index c2b88bf013..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfExperimentStub.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.trace; - -import org.eclipse.core.resources.IResource; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer; - -/** - * TmfExperimentStub - *

- * Implement me. Please. - *

- */ -@SuppressWarnings("javadoc") -public class TmfExperimentStub extends TmfExperiment { - - public TmfExperimentStub() { - super(); - } - - public TmfExperimentStub(String name, ITmfTrace[] traces, int blockSize) { - super(ITmfEvent.class, name, traces, blockSize); - } - - @Override - protected ITmfTraceIndexer createIndexer(int interval) { - return new TmfIndexerStub(this, interval); - } - - @Override - public TmfIndexerStub getIndexer() { - return (TmfIndexerStub) super.getIndexer(); - } - - @Override - public void initExperiment(final Class type, final String path, final ITmfTrace[] traces, final int indexPageSize, IResource resource) { - super.initExperiment(type, path, traces, indexPageSize, resource); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfIndexerStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfIndexerStub.java deleted file mode 100644 index 4338385b54..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfIndexerStub.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.trace; - -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer; - -/** - * TmfIndexerStub - *

- * Implement me. Please. - *

- */ -@SuppressWarnings("javadoc") -public class TmfIndexerStub extends TmfCheckpointIndexer { - - public TmfIndexerStub(ITmfTrace trace, int blockSize) { - super(trace, blockSize); - } - - public ITmfCheckpointIndex getCheckpoints() { - return getTraceIndex(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfTraceStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfTraceStub.java deleted file mode 100644 index 12845edca0..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfTraceStub.java +++ /dev/null @@ -1,389 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Updated for removal of context clone - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.trace; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; -import java.util.concurrent.locks.ReentrantLock; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser; -import org.eclipse.linuxtools.tmf.core.trace.TmfContext; -import org.eclipse.linuxtools.tmf.core.trace.TmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfPersistentlyIndexable; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation; - -/** - * TmfTraceStub - *

- * Dummy test trace. Use in conjunction with TmfEventParserStub. - */ -public class TmfTraceStub extends TmfTrace implements ITmfEventParser, ITmfPersistentlyIndexable { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // The actual stream - private RandomAccessFile fTrace; - -// // The associated event parser -// private ITmfEventParser fParser; - - // The synchronization lock - private final ReentrantLock fLock = new ReentrantLock(); - - private ITmfTimestamp fInitialRangeOffset = null; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - public TmfTraceStub() { - super(); - setParser(new TmfEventParserStub(this)); - } - - /** - * Constructor with which you can specify a custom streaming interval. The - * parser and indexer won't be specified. - * - * @param path - * The path to the trace file - * @param cacheSize - * The cache size - * @param interval - * The trace streaming interval - * @throws TmfTraceException - * If an error occurred opening the trace - */ - public TmfTraceStub(final String path, - final int cacheSize, - final long interval) throws TmfTraceException { - super(null, ITmfEvent.class, path, cacheSize, interval, null); - setupTrace(path); - setParser(new TmfEventParserStub(this)); - } - - /** - * Constructor to specify the parser and indexer. The streaming interval - * will be 0. - * - * @param path - * The path to the trace file - * @param cacheSize - * The cache size - * @param waitForCompletion - * Do we block the caller until the trace is indexed, or not. - * @param parser - * The trace parser. If left 'null', it will use a - * {@link TmfEventParserStub}. - * @throws TmfTraceException - * If an error occurred opening the trace - */ - public TmfTraceStub(final String path, - final int cacheSize, - final boolean waitForCompletion, - final ITmfEventParser parser) throws TmfTraceException { - super(null, ITmfEvent.class, path, cacheSize, 0, null); - setupTrace(path); - setParser((parser != null) ? parser : new TmfEventParserStub(this)); - if (waitForCompletion) { - indexTrace(true); - } - } - - /** - * Copy constructor - * - * @param trace - * The trace to copy - * @throws TmfTraceException - * If an error occurred opening the trace - */ - public TmfTraceStub(final TmfTraceStub trace) throws TmfTraceException { - super(trace); - setupTrace(getPath()); // fPath will be set by the super-constructor - setParser(new TmfEventParserStub(this)); - } - - - private void setupTrace(String path) throws TmfTraceException { - try { - fTrace = new RandomAccessFile(path, "r"); //$NON-NLS-1$ - } catch (FileNotFoundException e) { - throw new TmfTraceException(e.getMessage()); - } - } - - // ------------------------------------------------------------------------ - // Initializers - // ------------------------------------------------------------------------ - - @Override - public void initTrace(final IResource resource, final String path, final Class type) throws TmfTraceException { - try { - fTrace = new RandomAccessFile(path, "r"); //$NON-NLS-1$ - } catch (FileNotFoundException e) { - throw new TmfTraceException(e.getMessage()); - } - setParser(new TmfEventParserStub(this)); - super.initTrace(resource, path, type); - } - - @Override - public void initialize(final IResource resource, final String path, final Class type) throws TmfTraceException { - super.initialize(resource, path, type); - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * @return The file stream to the trace - */ - public RandomAccessFile getStream() { - return fTrace; - } - - /** - * Set the initial range offset. - * - * @param initOffset - * The new initial range offset - */ - public void setInitialRangeOffset(ITmfTimestamp initOffset) { - fInitialRangeOffset = initOffset; - } - - @Override - public ITmfTimestamp getInitialRangeOffset() { - if (fInitialRangeOffset != null) { - return fInitialRangeOffset; - } - return super.getInitialRangeOffset(); - } - - // ------------------------------------------------------------------------ - // Operators - // ------------------------------------------------------------------------ - - @Override - public TmfContext seekEvent(final ITmfLocation location) { - try { - fLock.lock(); - try { - if (fTrace != null) { - // Position the trace at the requested location and - // returns the corresponding context - long loc = 0; - long rank = 0; - if (location != null) { - loc = (Long) location.getLocationInfo(); - rank = ITmfContext.UNKNOWN_RANK; - } - if (loc != fTrace.getFilePointer()) { - fTrace.seek(loc); - } - final TmfContext context = new TmfContext(getCurrentLocation(), rank); - return context; - } - } catch (final IOException e) { - e.printStackTrace(); - } catch (final NullPointerException e) { - e.printStackTrace(); - } - finally{ - fLock.unlock(); - } - } catch (final NullPointerException e) { - e.printStackTrace(); - } - return null; - } - - - @Override - public TmfContext seekEvent(final double ratio) { - fLock.lock(); - try { - if (fTrace != null) { - final ITmfLocation location = new TmfLongLocation(Long.valueOf(Math.round(ratio * fTrace.length()))); - final TmfContext context = seekEvent(location); - context.setRank(ITmfContext.UNKNOWN_RANK); - return context; - } - } catch (final IOException e) { - e.printStackTrace(); - } finally { - fLock.unlock(); - } - - return null; - } - - @Override - public double getLocationRatio(ITmfLocation location) { - fLock.lock(); - try { - if (fTrace != null) { - if (location.getLocationInfo() instanceof Long) { - return ((Long) location.getLocationInfo()).doubleValue() / fTrace.length(); - } - } - } catch (final IOException e) { - e.printStackTrace(); - } finally { - fLock.unlock(); - } - return 0; - } - - @Override - public ITmfLocation getCurrentLocation() { - fLock.lock(); - try { - if (fTrace != null) { - return new TmfLongLocation(fTrace.getFilePointer()); - } - } catch (final IOException e) { - e.printStackTrace(); - } finally { - fLock.unlock(); - } - return null; - } - - @Override - public ITmfEvent parseEvent(final ITmfContext context) { - fLock.lock(); - try { - // parseNextEvent will update the context - if (fTrace != null && getParser() != null && context != null) { - final ITmfEvent event = getParser().parseEvent(context); - return event; - } - } finally { - fLock.unlock(); - } - return null; - } - - @Override - public synchronized void setNbEvents(final long nbEvents) { - super.setNbEvents(nbEvents); - } - - @Override - public void setTimeRange(final TmfTimeRange range) { - super.setTimeRange(range); - } - - @Override - public void setStartTime(final ITmfTimestamp startTime) { - super.setStartTime(startTime); - } - - @Override - public void setEndTime(final ITmfTimestamp endTime) { - super.setEndTime(endTime); - } - - @Override - public void setStreamingInterval(final long interval) { - super.setStreamingInterval(interval); - } - - @Override - public synchronized void dispose() { - fLock.lock(); - try { - if (fTrace != null) { - fTrace.close(); - fTrace = null; - } - } catch (final IOException e) { - // Ignore - } finally { - fLock.unlock(); - } - super.dispose(); - } - - @Override - public IStatus validate(IProject project, String path) { - if (fileExists(path)) { - return Status.OK_STATUS; - } - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "File does not exist: " + path); - } - - private static int fCheckpointSize = -1; - - @Override - public synchronized int getCheckpointSize() { - if (fCheckpointSize == -1) { - TmfCheckpoint c = new TmfCheckpoint(new TmfTimestamp(0L), new TmfLongLocation(0L), 0); - ByteBuffer b = ByteBuffer.allocate(ITmfCheckpoint.MAX_SERIALIZE_SIZE); - b.clear(); - c.serialize(b); - fCheckpointSize = b.position(); - } - - return fCheckpointSize; - } - - @Override - public ITmfLocation restoreLocation(ByteBuffer bufferIn) { - return new TmfLongLocation(bufferIn); - } - - /** - * Simulate trace opening, to be called by tests who need an actively opened - * trace - */ - public void openTrace() { - TmfSignalManager.dispatchSignal(new TmfTraceOpenedSignal(this, this, null)); - selectTrace(); - } - - /** - * Simulate selecting the trace - */ - public void selectTrace() { - TmfSignalManager.dispatchSignal(new TmfTraceSelectedSignal(this, this)); - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfTraceStub2.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfTraceStub2.java deleted file mode 100644 index 30b19c5727..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfTraceStub2.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.trace; - -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser; - -/** - * Another stub trace class for unit tests who need more than one stub class. - * - * @author Geneviève Bastien - */ -public class TmfTraceStub2 extends TmfTraceStub { - - /** - * Default constructor - */ - public TmfTraceStub2() { - super(); - } - - /** - * Constructor to specify the parser and indexer. The streaming interval - * will be 0. - * - * @param path - * The path to the trace file - * @param cacheSize - * The cache size - * @param waitForCompletion - * Do we block the caller until the trace is indexed, or not. - * @param parser - * The trace parser. If left 'null', it will use a - * {@link TmfEventParserStub}. - * @throws TmfTraceException - * If an error occurred opening the trace - */ - public TmfTraceStub2(final String path, - final int cacheSize, - final boolean waitForCompletion, - final ITmfEventParser parser) throws TmfTraceException { - super(path, cacheSize, waitForCompletion, parser); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfTraceStub3.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfTraceStub3.java deleted file mode 100644 index c619eec29b..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/TmfTraceStub3.java +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.trace; - -/** - * Another stub trace class for unit tests who need more than one stub class. - * - * @author Geneviève Bastien - */ -public class TmfTraceStub3 extends TmfTraceStub { - - /** - * Default constructor - */ - public TmfTraceStub3() { - super(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/text/SyslogEvent.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/text/SyslogEvent.java deleted file mode 100644 index 8146adc101..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/text/SyslogEvent.java +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.trace.text; - -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.core.event.collapse.ITmfCollapsibleEvent; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.text.TextTraceEvent; -import org.eclipse.linuxtools.tmf.core.trace.text.TextTraceEventContent; - -/** - * System log trace implementation of TmfEvent. - */ -public class SyslogEvent extends TextTraceEvent implements ITmfCollapsibleEvent { - - /** - * Default constructor - */ - public SyslogEvent() { - super(null, null, null, new SyslogEventType(), null, null); - } - - /** - * Copy constructor - * - * @param other - * the event to copy - * - */ - public SyslogEvent(final SyslogEvent other) { - super(other); - } - - /** - * Full Constructor - * - * @param parentTrace - * the parent trace - * @param timestamp - * the event timestamp - * @param source - * the event source - * @param type - * the event type - * @param content - * the event content (payload) - * @param reference - * the event reference - */ - public SyslogEvent(SyslogTrace parentTrace, final ITmfTimestamp timestamp, final String source, - final ITmfEventType type, final TextTraceEventContent content, final String reference) { - super(parentTrace, timestamp, source, type, content, reference); - } - - @Override - public boolean isCollapsibleWith(ITmfEvent otherEvent) { - if (this == otherEvent) { - return true; - } - - if (!(otherEvent instanceof SyslogEvent)) { - return false; - } - - final SyslogEvent other = (SyslogEvent) otherEvent; - - if (getTrace() == null) { - if (other.getTrace() != null) { - return false; - } - } else if (!getTrace().equals(other.getTrace())) { - return false; - } - - if (getType() == null) { - if (other.getType() != null) { - return false; - } - } else if (!getType().equals(other.getType())) { - return false; - } - - TextTraceEventContent content = this.getContent(); - TextTraceEventContent otherContent = other.getContent(); - - if (content == null) { - if (otherContent != null) { - return false; - } - return true; - } - - if (otherContent == null) { - return false; - } - - List fields = content.getFields(); - List otherFields = otherContent.getFields(); - int size = fields.size(); - - if (size != otherFields.size()) { - return false; - } - - // At i = 0 the timestamp is stored and needs to be bypassed - for (int i = 1; i < size; i++) { - if (!fields.get(i).equals(otherFields.get(i))) { - return false; - } - } - return true; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/text/SyslogEventType.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/text/SyslogEventType.java deleted file mode 100644 index 539faddc27..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/text/SyslogEventType.java +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.trace.text; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; - -/** - * The system log extension of the TMF event type. - */ -public class SyslogEventType extends TmfEventType { - - /** The event type id string. */ - public static final String TYPE_ID = "Syslog"; //$NON-NLS-1$ - /** The labels (field names) used for SA system log events. */ - @SuppressWarnings("nls") - public static final String[] LABELS = {"Timestamp", "Host", "Logger", "Message"}; - /** A default instance of this class */ - public static final SyslogEventType INSTANCE = new SyslogEventType(); - - /** Index numbers in the array of event field names and values. */ - public interface Index { - /** Index for time stamp */ - int TIMESTAMP = 0; - /** Index for the host name */ - int HOST = 1; - /** Index for the logger name */ - int LOGGER = 2; - /** Index for the event message */ - int MESSAGE = 3; - } - - /** - * Default Constructor - */ - public SyslogEventType() { - super(ITmfEventType.DEFAULT_CONTEXT_ID, TYPE_ID, TmfEventField.makeRoot(LABELS)); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/text/SyslogTrace.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/text/SyslogTrace.java deleted file mode 100644 index f0b90656fd..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/text/SyslogTrace.java +++ /dev/null @@ -1,116 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.trace.text; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimePreferences; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampFormat; -import org.eclipse.linuxtools.tmf.core.trace.text.TextTrace; -import org.eclipse.linuxtools.tmf.core.trace.text.TextTraceEventContent; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.text.SyslogEventType.Index; - -/** - * Extension of TmfTrace for handling of system logs. - */ -public class SyslogTrace extends TextTrace { - - /** The cache size for system log traces. */ - private static final int CACHE_SIZE = 100; - /** The time stamp format of the trace type. */ - public static final String TIMESTAMP_FORMAT = "MMM dd HH:mm:ss"; //$NON-NLS-1$ - /** The corresponding date format of the time stamp. */ - public static final SimpleDateFormat TIMESTAMP_SIMPLEDATEFORMAT = new SimpleDateFormat( - TIMESTAMP_FORMAT, TmfTimePreferences.getInstance().getLocale()); - /** The regular expression pattern of the first line of an event. */ - public static final Pattern LINE1_PATTERN = Pattern.compile( - "\\s*(\\S\\S\\S \\d\\d? \\d\\d:\\d\\d:\\d\\d)\\s*(\\S*)\\s*(\\S*):+\\s*(.*\\S)?"); //$NON-NLS-1$ - - /* The current calendar to use */ - private static final Calendar CURRENT = Calendar.getInstance(); - - /** - * Constructor - */ - public SyslogTrace() { - setCacheSize(CACHE_SIZE); - } - - @Override - protected Pattern getFirstLinePattern() { - return LINE1_PATTERN; - } - - @Override - protected SyslogEvent parseFirstLine(Matcher matcher, String line) { - - ITmfTimestamp timestamp = null; - - try { - synchronized (TIMESTAMP_SIMPLEDATEFORMAT) { - TIMESTAMP_SIMPLEDATEFORMAT.setTimeZone(TmfTimestampFormat.getDefaulTimeFormat().getTimeZone()); - Date date = TIMESTAMP_SIMPLEDATEFORMAT.parse(matcher.group(1)); - GregorianCalendar calendar = new GregorianCalendar(); - calendar.setTime(date); - calendar.set(Calendar.YEAR, CURRENT.get(Calendar.YEAR)); - if (calendar.after(CURRENT)) { - calendar.set(Calendar.YEAR, CURRENT.get(Calendar.YEAR) - 1); - } - long ns = calendar.getTimeInMillis() * 1000000; - timestamp = createTimestamp(ns); - } - } catch (ParseException e) { - timestamp = new TmfTimestamp(); - } - - TextTraceEventContent content = new TextTraceEventContent(SyslogEventType.LABELS); - content.setValue(new StringBuffer(line)); - content.setFieldValue(Index.TIMESTAMP, matcher.group(1)); - content.setFieldValue(Index.HOST, matcher.group(2)); - content.setFieldValue(Index.LOGGER, matcher.group(3)); - content.setFieldValue(Index.MESSAGE, new StringBuffer(matcher.group(4) != null ? matcher.group(4) : "")); //$NON-NLS-1$ - - SyslogEvent event = new SyslogEvent( - this, - timestamp, - "", //$NON-NLS-1$ - SyslogEventType.INSTANCE, - content, - ""); //$NON-NLS-1$ - - return event; - } - - @Override - protected void parseNextLine(SyslogEvent event, String line) { - TextTraceEventContent content = event.getContent(); - ((StringBuffer) content.getValue()).append("\n").append(line); //$NON-NLS-1$ - if (line.trim().length() > 0) { - ((StringBuffer) content.getFieldValue(Index.MESSAGE)).append(SEPARATOR + line.trim()); - } - } - - @Override - public ITmfTimestamp getInitialRangeOffset() { - return new TmfTimestamp(60, ITmfTimestamp.SECOND_SCALE); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/Messages.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/Messages.java deleted file mode 100644 index f0dba7e393..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/Messages.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.trace.xml; - -import org.eclipse.osgi.util.NLS; - -/** - * Externalized messages for the - * {@link org.eclipse.linuxtools.tmf.tests.stubs.trace.xml} package - * - * @author Geneviève Bastien - */ -@SuppressWarnings("javadoc") -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.tests.stubs.trace.xml.messages"; //$NON-NLS-1$ - - public static String TmfDevelopmentTrace_FileNotFound; - public static String TmfDevelopmentTrace_IoError; - public static String TmfDevelopmentTrace_ValidationError; - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xml b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xml deleted file mode 100644 index 96ec2b9b5d..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - -T - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xsd b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xsd deleted file mode 100644 index fe8abdfd9e..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xsd +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlTraceStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlTraceStub.java deleted file mode 100644 index 47e7e89330..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlTraceStub.java +++ /dev/null @@ -1,252 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.tests.stubs.trace.xml; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; - -import javax.xml.XMLConstants; -import javax.xml.transform.Source; -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomEventContent; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlEvent; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTrace; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.TmfContext; -import org.eclipse.linuxtools.tmf.core.trace.TmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; -import org.eclipse.osgi.util.NLS; -import org.xml.sax.SAXException; - -/** - * An XML development trace using a custom XML trace definition and schema. - * - * This class will typically be used to build custom traces to unit test more - * complex functionalities like analyzes or to develop and test data-driven - * analyzes. - * - * This class wraps a custom XML trace and rewrites the returned events in the - * getNext() method so that event's fields are the ones defined in - * elements instead of those defined in the custom XML parser. This way, each - * event can have a different set of fields. This class can, for example, mimic - * a CTF trace. - * - * @author Geneviève Bastien - */ -public class TmfXmlTraceStub extends TmfTrace { - - private static final String DEVELOPMENT_TRACE_PARSER_PATH = "TmfXmlDevelopmentTrace.xml"; //$NON-NLS-1$ - private static final String DEVELOPMENT_TRACE_XSD = "TmfXmlDevelopmentTrace.xsd"; //$NON-NLS-1$ - private static final String EMPTY = ""; //$NON-NLS-1$ - - /* XML elements and attributes names */ - private static final String EVENT_NAME_FIELD = "Message"; //$NON-NLS-1$ - private static final String FIELD_NAMES_FIELD = "fields"; //$NON-NLS-1$ - private static final String SOURCE_FIELD = "source"; //$NON-NLS-1$ - private static final String VALUES_FIELD = "values"; //$NON-NLS-1$ - private static final String TYPES_FIELD = "type"; //$NON-NLS-1$ - private static final String VALUES_SEPARATOR = " \\| "; //$NON-NLS-1$ - private static final String TYPE_INTEGER = "int"; //$NON-NLS-1$ - private static final String TYPE_LONG = "long"; //$NON-NLS-1$ - - private final CustomXmlTrace fTrace; - - /** - * Constructor. Constructs the custom XML trace with the appropriate - * definition. - */ - public TmfXmlTraceStub() { - - /* Load custom XML definition */ - try (InputStream in = TmfXmlTraceStub.class.getResourceAsStream(DEVELOPMENT_TRACE_PARSER_PATH);) { - CustomXmlTraceDefinition[] definitions = CustomXmlTraceDefinition.loadAll(in); - if (definitions.length == 0) { - throw new IllegalStateException("The custom trace definition does not exist"); //$NON-NLS-1$ - } - fTrace = new CustomXmlTrace(definitions[0]); - /* Deregister the custom XML trace */ - TmfSignalManager.deregister(fTrace); - this.setParser(fTrace); - } catch (IOException e) { - throw new IllegalStateException("Cannot open the trace parser for development traces"); //$NON-NLS-1$ - } - - } - - @Override - public void initTrace(IResource resource, String path, Class type) throws TmfTraceException { - super.initTrace(resource, path, type); - fTrace.initTrace(resource, path, type); - ITmfContext ctx; - /* Set the start and (current) end times for this trace */ - ctx = seekEvent(0L); - ITmfEvent event = getNext(ctx); - if (event != null) { - final ITmfTimestamp curTime = event.getTimestamp(); - this.setStartTime(curTime); - this.setEndTime(curTime); - } - } - - @Override - public ITmfLocation getCurrentLocation() { - return fTrace.getCurrentLocation(); - } - - @Override - public double getLocationRatio(ITmfLocation location) { - return fTrace.getLocationRatio(location); - } - - @Override - public ITmfContext seekEvent(ITmfLocation location) { - return fTrace.seekEvent(location); - } - - @Override - public ITmfContext seekEvent(double ratio) { - return fTrace.seekEvent(ratio); - } - - @Override - public IStatus validate(IProject project, String path) { - File xmlFile = new File(path); - if (!xmlFile.exists() || !xmlFile.isFile() || !xmlFile.canRead()) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(org.eclipse.linuxtools.tmf.tests.stubs.trace.xml.Messages.TmfDevelopmentTrace_FileNotFound, path)); - } - /* Does the XML file validate with the XSD */ - SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - Source xmlSource = new StreamSource(xmlFile); - - try { - URL url = TmfXmlTraceStub.class.getResource(DEVELOPMENT_TRACE_XSD); - Schema schema = schemaFactory.newSchema(url); - - Validator validator = schema.newValidator(); - validator.validate(xmlSource); - } catch (SAXException e) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(org.eclipse.linuxtools.tmf.tests.stubs.trace.xml.Messages.TmfDevelopmentTrace_ValidationError, path), e); - } catch (IOException e) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(org.eclipse.linuxtools.tmf.tests.stubs.trace.xml.Messages.TmfDevelopmentTrace_IoError, path), e); - } - return Status.OK_STATUS; - } - - private static String getStringValue(@NonNull ITmfEventField content, String fieldName) { - ITmfEventField field = content.getField(fieldName); - if (field == null) { - return EMPTY; - } - Object val = field.getValue(); - if (!(val instanceof String)) { - return EMPTY; - } - return (String) val; - } - - @Override - public synchronized ITmfEvent getNext(ITmfContext context) { - final ITmfContext savedContext = new TmfContext(context.getLocation(), context.getRank()); - CustomXmlEvent event = fTrace.getNext(context); - if (event == null) { - return null; - } - - /* Translate the content of the event */ - /* The "fields" field contains a | separated list of field names */ - /* The "values" field contains a | separated list of field values */ - /* the "type" field contains a | separated list of field types */ - ITmfEventField content = event.getContent(); - if (content == null) { - return null; - } - String fieldString = getStringValue(content, FIELD_NAMES_FIELD); - String valueString = getStringValue(content, VALUES_FIELD); - String typeString = getStringValue(content, TYPES_FIELD); - - String[] fields = fieldString.split(VALUES_SEPARATOR); - String[] values = valueString.split(VALUES_SEPARATOR); - String[] types = typeString.split(VALUES_SEPARATOR); - ITmfEventField[] fieldsArray = new TmfEventField[fields.length]; - - for (int i = 0; i < fields.length; i++) { - String value = EMPTY; - if (values.length > i) { - value = values[i]; - } - String type = null; - if (types.length > i) { - type = types[i]; - } - Object val = value; - if (type != null) { - switch (type) { - case TYPE_INTEGER: { - try { - val = Integer.valueOf(value); - } catch (NumberFormatException e) { - Activator.logError(String.format("Get next XML event: cannot cast value %s to integer", value), e); //$NON-NLS-1$ - val = 0; - } - break; - } - case TYPE_LONG: { - try { - val = Long.valueOf(value); - } catch (NumberFormatException e) { - Activator.logError(String.format("Get next XML event: cannot cast value %s to long", value), e); //$NON-NLS-1$ - val = 0L; - } - break; - } - default: - break; - } - } - fieldsArray[i] = new TmfEventField(fields[i], val, null); - } - - /* Create a new event with new fields and name */ - ITmfEventType customEventType = event.getType(); - TmfEventType eventType = new TmfEventType(customEventType.getContext(), getStringValue(content, EVENT_NAME_FIELD), customEventType.getRootField()); - ITmfEventField eventFields = new CustomEventContent(content.getName(), content.getValue(), fieldsArray); - TmfEvent newEvent = new TmfEvent(this, event.getTimestamp(), getStringValue(content, SOURCE_FIELD), eventType, eventFields, event.getReference()); - updateAttributes(savedContext, event.getTimestamp()); - context.increaseRank(); - - return newEvent; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/messages.properties b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/messages.properties deleted file mode 100644 index 005b58eba4..0000000000 --- a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/messages.properties +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -# Copyright (c) 2014 École Polytechnique de Montréal -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# École Polytechnique de Montréal - Initial API and implementation -############################################################################### - -TmfDevelopmentTrace_FileNotFound=File not found: {0} -TmfDevelopmentTrace_IoError=IOException validating file: {0} -TmfDevelopmentTrace_ValidationError=Trace file does not validate: {0} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/CreateTestFiles.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/CreateTestFiles.java new file mode 100644 index 0000000000..cb6403167a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/CreateTestFiles.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs; + +import java.io.BufferedOutputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Random; + +/** + * CreateTestFiles + *

+ * Create a number of event test files of various lengths. + *

+ * Events have the following format: + *

    + *
  • [timestamp] [source] [type] [ref] [field]* + *
  • There are NB_SOURCES sources and NB_TYPES types. + *
  • The number of fields (0 .. NB_TYPES-1) depends on the event type. + *
+ */ +public class CreateTestFiles { + + // ======================================================================== + // Constants + // ======================================================================== + + private static final String DIRECTORY = "testfiles"; + // private static final String FILE_NAMES[] = { "Test-10", "Test-1K", "Test-10K", "Test-100K" }; + // private static final int FILE_SIZES[] = { 10 , 1000 , 10000 , 100000 }; + private static final String FILE_NAMES[] = { "Test-10K" }; + private static final int FILE_SIZES[] = { 10000 }; + + private static final int NB_SOURCES = 15; + private static final int NB_TYPES = 7; + + // ======================================================================== + // Constructors + // ======================================================================== + + /** + * @param args unused + */ + public static void main(final String[] args) { + + try { + System.out.println("Creating test files in directory: " + new File(".").getCanonicalPath() + File.separator + DIRECTORY); + } catch (final IOException e) { + e.printStackTrace(); + } + + for (int i = 0; i < FILE_SIZES.length; i++) { + try { + createTestFile("testfiles" + File.separator + "O-" + FILE_NAMES[i], FILE_SIZES[i], true, true); + createTestFile("testfiles" + File.separator + "E-" + FILE_NAMES[i], FILE_SIZES[i], true, false); + createTestFile("testfiles" + File.separator + "R-" + FILE_NAMES[i], FILE_SIZES[i], false, false); + } catch (final FileNotFoundException e) { + } catch (final IOException e) { + } + } + + System.out.println("Done."); + } + + // ======================================================================== + // Operators + // ======================================================================== + + /** + * @param file + * @param size + * @param monotonic + * @throws FileNotFoundException + * @throws IOException + */ + private static void createTestFile(final String file, final int size, + final boolean monotonic, final boolean odd) + throws IOException { + System.out.println("Creating " + file); + try (DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));) { + + final Random generator = new Random(19580427 + size); + long ts = (monotonic && odd) ? -1 : 0; + for (int i = 0; i < size; i++) { + ts += monotonic ? 2 : generator.nextInt(10); + final int sourceIndex = i % NB_SOURCES; + final int typeIndex = i % NB_TYPES; + out.writeLong(ts); // Timestamp + out.writeUTF("Source-" + sourceIndex); // Source + out.writeUTF("Type-" + typeIndex); // Type + out.writeInt(i + 1); // Reference (event #) + for (int j = 0; j < typeIndex; j++) { + out.writeUTF("Field-" + sourceIndex + "-" + j); + } + } + out.flush(); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/AnalysisModuleSourceStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/AnalysisModuleSourceStub.java new file mode 100644 index 0000000000..0eec97d6fc --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/AnalysisModuleSourceStub.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.analysis; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleSource; +import org.eclipse.tracecompass.tmf.tests.stubs.analysis.AnalysisModuleTestHelper.moduleStubEnum; + +/** + * Stub class for analysis module source + * + * @author Geneviève Bastien + */ +public class AnalysisModuleSourceStub implements IAnalysisModuleSource { + + @Override + public Iterable getAnalysisModules() { + List list = new ArrayList<>(); + IAnalysisModuleHelper helper = new AnalysisModuleTestHelper(moduleStubEnum.TEST); + list.add(helper); + helper = new AnalysisModuleTestHelper(moduleStubEnum.TEST2); + list.add(helper); + return list; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/AnalysisModuleTestHelper.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/AnalysisModuleTestHelper.java new file mode 100644 index 0000000000..68d09884cc --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/AnalysisModuleTestHelper.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + * Guilliano Molaire - Implementation of requirements and valid trace types getters + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.analysis; + +import java.util.Collections; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub2; +import org.osgi.framework.Bundle; + +import com.google.common.collect.ImmutableList; + +/** + * Analysis Module Helper for the stub analysis source + * + * @author Geneviève Bastien + */ +public class AnalysisModuleTestHelper implements IAnalysisModuleHelper { + + /** + * Enum to select an analysis module for this stub + */ + public enum moduleStubEnum { + /** Test analysis */ + TEST, + /** Test analysis 2 */ + TEST2 + } + + private moduleStubEnum fModule; + + /** + * Constructor + * + * @param module + * The type identifying the module for this helper + */ + public AnalysisModuleTestHelper(moduleStubEnum module) { + fModule = module; + } + + @Override + public String getId() { + return fModule.name(); + } + + @Override + public String getName() { + return fModule.name(); + } + + @Override + public boolean isAutomatic() { + return false; + } + + @Override + public String getHelpText() { + return ""; + } + + @Override + public String getHelpText(@NonNull ITmfTrace trace) { + return ""; + } + + @Override + public String getIcon() { + return ""; + } + + @Override + public Bundle getBundle() { + return Platform.getBundle("org.eclipse.linuxtools.tmf.core.tests"); + } + + @Override + public boolean appliesToTraceType(Class traceclass) { + switch (fModule) { + case TEST: + return TmfTraceStub.class.isAssignableFrom(traceclass); + case TEST2: + return TmfTraceStub2.class.isAssignableFrom(traceclass); + default: + return false; + } + } + + @Override + public IAnalysisModule newModule(ITmfTrace trace) throws TmfAnalysisException { + IAnalysisModule module = null; + switch (fModule) { + case TEST: + module = new TestAnalysis(); + module.setName(getName()); + module.setId(getId()); + module.setAutomatic(isAutomatic()); + module.setTrace(trace); + break; + case TEST2: + module = new TestAnalysis2(); + module.setName(getName()); + module.setId(getId()); + module.setAutomatic(isAutomatic()); + module.setTrace(trace); + break; + default: + break; + + } + return module; + } + + @Override + public Iterable> getValidTraceTypes() { + return ImmutableList.> of( + TmfTraceStub.class, + TmfTraceStub2.class); + } + + @Override + public Iterable getAnalysisRequirements() { + switch (fModule) { + case TEST: + return ImmutableList.of( + AnalysisRequirementFactory.REQUIREMENT_1, + AnalysisRequirementFactory.REQUIREMENT_3); + case TEST2: + return ImmutableList.of( + AnalysisRequirementFactory.REQUIREMENT_2, + AnalysisRequirementFactory.REQUIREMENT_3); + default: + return Collections.EMPTY_SET; + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/AnalysisRequirementFactory.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/AnalysisRequirementFactory.java new file mode 100644 index 0000000000..c37015eab4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/AnalysisRequirementFactory.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Guilliano Molaire - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.analysis; + +import java.util.Set; + +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement.ValuePriorityLevel; + +import com.google.common.collect.ImmutableSet; + +/** + * Factory class to facilitate requirement usage across test case + */ +@SuppressWarnings("javadoc") +public final class AnalysisRequirementFactory { + + private AnalysisRequirementFactory() {} + + public static final String REQUIREMENT_TYPE_1 = "car"; + public static final String REQUIREMENT_TYPE_2 = "factory"; + public static final String REQUIREMENT_TYPE_3 = "code"; + + public static final String REQUIREMENT_VALUE_1 = "value1"; + public static final String REQUIREMENT_VALUE_2 = "value2"; + public static final String REQUIREMENT_VALUE_3 = "value3"; + public static final String REQUIREMENT_VALUE_4 = "value4"; + public static final String REQUIREMENT_VALUE_5 = "value5"; + + public static final Set REQUIREMENT_VALUES_1 = ImmutableSet.of( + REQUIREMENT_VALUE_1, + REQUIREMENT_VALUE_2, + REQUIREMENT_VALUE_3, + REQUIREMENT_VALUE_5 + ); + + public static final Set REQUIREMENT_VALUES_2 = ImmutableSet.of( + REQUIREMENT_VALUE_2, + REQUIREMENT_VALUE_3 + ); + + public static final Set REQUIREMENT_VALUES_3 = ImmutableSet.of( + REQUIREMENT_VALUE_3, + REQUIREMENT_VALUE_4, + REQUIREMENT_VALUE_5 + ); + + public static final TmfAnalysisRequirement REQUIREMENT_1 = + new TmfAnalysisRequirement(REQUIREMENT_TYPE_1, REQUIREMENT_VALUES_1, ValuePriorityLevel.MANDATORY); + public static final TmfAnalysisRequirement REQUIREMENT_2 = + new TmfAnalysisRequirement(REQUIREMENT_TYPE_2); + public static final TmfAnalysisRequirement REQUIREMENT_3 = + new TmfAnalysisRequirement(REQUIREMENT_TYPE_3, REQUIREMENT_VALUES_3, ValuePriorityLevel.MANDATORY); + + static { + REQUIREMENT_2.addValue(REQUIREMENT_VALUE_1, ValuePriorityLevel.MANDATORY); + REQUIREMENT_2.addValue(REQUIREMENT_VALUE_2, ValuePriorityLevel.OPTIONAL); + REQUIREMENT_2.addValue(REQUIREMENT_VALUE_3, ValuePriorityLevel.MANDATORY); + REQUIREMENT_2.addValue(REQUIREMENT_VALUE_4, ValuePriorityLevel.OPTIONAL); + REQUIREMENT_2.addValue(REQUIREMENT_VALUE_5, ValuePriorityLevel.MANDATORY); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestAnalysis.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestAnalysis.java new file mode 100644 index 0000000000..00fa5b5afe --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestAnalysis.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.analysis; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Simple analysis type for test + */ +public class TestAnalysis extends TmfAbstractAnalysisModule { + + private int output = 0; + + /** + * Test parameter. If set, simulate cancellation + */ + public static final String PARAM_TEST = "test"; + + /** + * Constructor + */ + public TestAnalysis() { + super(); + } + + @Override + public boolean canExecute(ITmfTrace trace) { + return true; + } + + @Override + protected boolean executeAnalysis(final IProgressMonitor monitor) { + if (getParameter(PARAM_TEST) == null) { + throw new RuntimeException("The parameter should be set"); + } + /* If PARAM_TEST is set to 0, simulate cancellation */ + if ((Integer) getParameter(PARAM_TEST) == 0) { + output = 0; + return false; + } else if ((Integer) getParameter(PARAM_TEST) == 999) { + /* just stay in an infinite loop until cancellation */ + while (!monitor.isCanceled()) { + + } + return !monitor.isCanceled(); + } + output = (Integer) getParameter(PARAM_TEST); + return true; + } + + @Override + protected void canceling() { + output = -1; + } + + @Override + public Object getParameter(String name) { + Object value = super.getParameter(name); + if ((value != null) && name.equals(PARAM_TEST) && (value instanceof String)) { + return Integer.decode((String) value); + } + return value; + } + + @Override + protected void parameterChanged(String name) { + schedule(); + } + + /** + * Get the analysis output value + * + * @return The analysis output + */ + public int getAnalysisOutput() { + return output; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestAnalysis2.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestAnalysis2.java new file mode 100644 index 0000000000..01708d8d02 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestAnalysis2.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.analysis; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub2; + +/** + * Simple analysis type for test + */ +public class TestAnalysis2 extends TmfAbstractAnalysisModule { + + @Override + public boolean canExecute(ITmfTrace trace) { + /* This just makes sure the trace is a trace stub 2 */ + return (TmfTraceStub2.class.isAssignableFrom(trace.getClass())); + } + + @Override + protected void canceling() { + + } + + @Override + protected boolean executeAnalysis(final IProgressMonitor monitor) { + return false; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestAnalysisParameterProvider.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestAnalysisParameterProvider.java new file mode 100644 index 0000000000..78e237396b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestAnalysisParameterProvider.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.analysis; + +import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisParamProvider; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; + +/** + * Test parameter provider for the PARAM_TEST that would apply only to + * CtfTmfTrace (though it is associated with an analysis that supports all trace + * types) + * + * @author Geneviève Bastien + */ +public class TestAnalysisParameterProvider extends TmfAbstractAnalysisParamProvider { + + private int fValue = 10; + + @Override + public String getName() { + return "test parameter provider"; + } + + @Override + public Object getParameter(String name) { + if (name.equals(TestAnalysis.PARAM_TEST)) { + return fValue; + } + return null; + } + + @Override + public boolean appliesToTrace(ITmfTrace trace) { + return (trace instanceof TmfTraceStub); + } + + /** + * Sets a new value for the parameter + * + * @param value + * new parameter value + */ + public void setValue(int value) { + fValue = value; + notifyParameterChanged(TestAnalysis.PARAM_TEST); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestExperimentAnalysis.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestExperimentAnalysis.java new file mode 100644 index 0000000000..46c4beed1d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestExperimentAnalysis.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.analysis; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Stubs for experiment analysis. This analysis is a state system analysis that + * simply counts the number of traces for which events were received. The number + * of traces is the value of attribute + * {@link TestExperimentAnalysis#TRACE_QUARK_NAME}. + * + * @author Geneviève Bastien + */ +public class TestExperimentAnalysis extends TmfStateSystemAnalysisModule { + + /** + * The quark counting the number of traces + */ + public static final String TRACE_QUARK_NAME = "Traces"; + + @Override + protected ITmfStateProvider createStateProvider() { + return new TestExpStateSystemProvider(getTrace()); + } + + @Override + protected StateSystemBackendType getBackendType() { + return StateSystemBackendType.INMEM; + } + + private class TestExpStateSystemProvider extends AbstractTmfStateProvider { + + private static final int VERSION = 1; + private final Set fTraces = new HashSet<>(); + private int fCount = 0; + + /** + * Constructor + * + * @param trace + * The LTTng 2.0 kernel trace directory + */ + public TestExpStateSystemProvider(ITmfTrace trace) { + super(trace, TmfEvent.class, "Stub State System for Experiment"); + } + + @Override + public int getVersion() { + return VERSION; + } + + @Override + public ITmfStateProvider getNewInstance() { + return new TestExpStateSystemProvider(this.getTrace()); + } + + @Override + protected void eventHandle(ITmfEvent event) { + if (!fTraces.contains(event.getTrace())) { + try { + int quarkId = ss.getQuarkAbsoluteAndAdd(TRACE_QUARK_NAME); + ss.modifyAttribute(event.getTimestamp().getValue(), TmfStateValue.newValueInt(++fCount), quarkId); + fTraces.add(event.getTrace()); + } catch (TimeRangeException | AttributeNotFoundException | StateValueTypeException e) { + + } + } + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestRequirementAnalysis.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestRequirementAnalysis.java new file mode 100644 index 0000000000..d0343bce4e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestRequirementAnalysis.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Rail - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.analysis; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement.ValuePriorityLevel; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; + +/** + * Analysis type to test requirements acquisition + */ +@SuppressWarnings({ "javadoc", "nls" }) +public class TestRequirementAnalysis extends TmfAbstractAnalysisModule { + /* Test requirement types */ + public static final String EVENT_TYPE = "event"; + public static final String FIELD_TYPE = "field"; + + /* A few event names */ + public static final String EXIT_SYSCALL = "exit_syscall"; + public static final String SCHED_SWITCH = "sched_switch"; + public static final String SCHED_WAKEUP = "sched_wakeup"; + + /* A few fields */ + public static final String PID = "pid"; + public static final String TID = "tid"; + + @Override + public boolean canExecute(ITmfTrace trace) { + /* This just makes sure the trace is a ctf stub trace */ + return (TmfTraceStub.class.isAssignableFrom(trace.getClass())); + } + + @Override + protected void canceling() { + + } + + @Override + protected boolean executeAnalysis(final IProgressMonitor monitor) { + return true; + } + + @Override + public void setTrace(ITmfTrace trace) throws TmfAnalysisException { + } + + @Override + public Iterable getAnalysisRequirements() { + Map requirements = new HashMap<>(); + + /* Event type requirement and values */ + requirements.put(EVENT_TYPE, new TmfAnalysisRequirement(EVENT_TYPE)); + requirements.get(EVENT_TYPE).addValue(EXIT_SYSCALL, ValuePriorityLevel.MANDATORY); + requirements.get(EVENT_TYPE).addValue(SCHED_SWITCH, ValuePriorityLevel.MANDATORY); + requirements.get(EVENT_TYPE).addValue(SCHED_WAKEUP, ValuePriorityLevel.MANDATORY); + + /* Field type requirement and values */ + requirements.put(FIELD_TYPE, new TmfAnalysisRequirement(FIELD_TYPE)); + requirements.get(FIELD_TYPE).addValue(PID, ValuePriorityLevel.MANDATORY); + requirements.get(FIELD_TYPE).addValue(TID, ValuePriorityLevel.MANDATORY); + + return requirements.values(); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestStateSystemModule.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestStateSystemModule.java new file mode 100644 index 0000000000..7174b1f027 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestStateSystemModule.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.analysis; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; + +/** + * Test State System module + * + * @author Geneviève Bastien + */ +@NonNullByDefault +public class TestStateSystemModule extends TmfStateSystemAnalysisModule { + + @Override + protected ITmfStateProvider createStateProvider() { + return new TestStateSystemProvider(getTrace()); + } + + @Override + protected StateSystemBackendType getBackendType() { + return StateSystemBackendType.INMEM; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestStateSystemProvider.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestStateSystemProvider.java new file mode 100644 index 0000000000..eab33c63e2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestStateSystemProvider.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.analysis; + +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Stub test provider for test state system analysis module + * + * @author Geneviève Bastien + */ +public class TestStateSystemProvider extends AbstractTmfStateProvider { + + private static final int VERSION = 1; + private final String fString = "[]"; + private int fCount = 0; + + /** + * Constructor + * + * @param trace + * The LTTng 2.0 kernel trace directory + */ + public TestStateSystemProvider(ITmfTrace trace) { + super(trace, TmfEvent.class, "Stub State System"); + } + + @Override + public int getVersion() { + return VERSION; + } + + @Override + public ITmfStateProvider getNewInstance() { + return new TestStateSystemProvider(this.getTrace()); + } + + @Override + protected void eventHandle(ITmfEvent event) { + /* Just need something to fill the state system */ + if (fString.equals(event.getContent().getValue())) { + try { + int quarkId = ss.getQuarkAbsoluteAndAdd("String"); + int quark = ss.getQuarkRelativeAndAdd(quarkId, fString); + ss.modifyAttribute(event.getTimestamp().getValue(), TmfStateValue.newValueInt(fCount++), quark); + } catch (TimeRangeException e) { + + } catch (AttributeNotFoundException e) { + + } catch (StateValueTypeException e) { + + } + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/component/TmfClientStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/component/TmfClientStub.java new file mode 100644 index 0000000000..f5bfa84900 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/component/TmfClientStub.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.component; + +import org.eclipse.tracecompass.internal.tmf.core.component.TmfProviderManager; +import org.eclipse.tracecompass.tmf.core.component.TmfComponent; +import org.eclipse.tracecompass.tmf.core.component.TmfEventProvider; +import org.eclipse.tracecompass.tmf.tests.stubs.event.TmfSyntheticEventStub; + +/** + * TmfClientStub + *

+ * TODO: Implement me. Please. + */ +@SuppressWarnings("javadoc") +public class TmfClientStub extends TmfComponent { + + private TmfEventProvider[] fProviders; + + public TmfClientStub() { + super("TmfClientStub"); + } + + public void findProvider() { + fProviders = TmfProviderManager.getProviders(TmfSyntheticEventStub.class, TmfSyntheticEventProviderStub.class); + // TmfEventRequest request; + System.out.println(fProviders.length); + } + + public void triggeRequest() { + // TmfEventRequest request; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/component/TmfEventProviderStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/component/TmfEventProviderStub.java new file mode 100644 index 0000000000..1be4e0b1ca --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/component/TmfEventProviderStub.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.component; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.tracecompass.tmf.core.component.TmfEventProvider; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.tests.TmfCoreTestPlugin; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; + +/** + * TmfEventProviderStub + *

+ * TODO: Implement me. Please. + */ +@SuppressWarnings("javadoc") +public class TmfEventProviderStub extends TmfEventProvider { + + private TmfTraceStub fTrace; + + public TmfEventProviderStub(final String path) throws IOException { + super(path, ITmfEvent.class); + final URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(path), null); + try { + final File test = new File(FileLocator.toFileURL(location).toURI()); + fTrace = new TmfTraceStub(test.getPath(), 0, true, null); + } catch (final TmfTraceException e) { + e.printStackTrace(); + } catch (final URISyntaxException e) { + e.printStackTrace(); + } + } + + public TmfEventProviderStub() throws IOException { + this(TmfTestTrace.A_TEST_10K.getFullPath()); + } + + @Override + public void dispose() { + fTrace.dispose(); + super.dispose(); + } + + // ------------------------------------------------------------------------ + // TmfEventProvider + // ------------------------------------------------------------------------ + + @Override + public ITmfContext armRequest(final ITmfEventRequest request) { + final ITmfContext context = fTrace.seekEvent(request.getRange().getStartTime()); + return context; + } + + @Override + public ITmfEvent getNext(final ITmfContext context) { + return fTrace.getNext(context); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/component/TmfSyntheticEventProviderStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/component/TmfSyntheticEventProviderStub.java new file mode 100644 index 0000000000..cd18880ba6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/component/TmfSyntheticEventProviderStub.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.component; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import org.eclipse.tracecompass.internal.tmf.core.component.TmfProviderManager; +import org.eclipse.tracecompass.tmf.core.component.ITmfEventProvider; +import org.eclipse.tracecompass.tmf.core.component.TmfEventProvider; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.TmfContext; +import org.eclipse.tracecompass.tmf.tests.stubs.event.TmfSyntheticEventStub; + +/** + * TmfSyntheticEventProviderStub + *

+ * TODO: Implement me. Please. + */ +@SuppressWarnings("javadoc") +public class TmfSyntheticEventProviderStub extends TmfEventProvider { + + public static final int NB_EVENTS = 1000; + + private final BlockingQueue fDataQueue = new LinkedBlockingQueue<>(1000); + + public TmfSyntheticEventProviderStub() { + super("TmfSyntheticEventProviderStub", TmfSyntheticEventStub.class); + } + + @Override + public ITmfContext armRequest(final ITmfEventRequest request) { + + // Get the TmfSyntheticEventStub provider + final ITmfEventProvider[] eventProviders = TmfProviderManager.getProviders(ITmfEvent.class, TmfEventProviderStub.class); + final ITmfEventProvider provider = eventProviders[0]; + + final TmfTimeRange range = request.getRange(); + final TmfEventRequest subRequest = + new TmfEventRequest(ITmfEvent.class, range, 0, NB_EVENTS, ExecutionType.FOREGROUND) { + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + handleIncomingData(event); + } + }; + provider.sendRequest(subRequest); + + // Return a dummy context + return new TmfContext(); + } + + // Queue 2 synthetic events per base event + private void handleIncomingData(final ITmfEvent e) { + queueResult(new TmfSyntheticEventStub(e)); + queueResult(new TmfSyntheticEventStub(e)); + } + + private static final int TIMEOUT = 10000; + + @Override + public TmfSyntheticEventStub getNext(final ITmfContext context) { + TmfSyntheticEventStub data = null; + try { + data = (TmfSyntheticEventStub) fDataQueue.poll(TIMEOUT, TimeUnit.MILLISECONDS); + if (data == null) { + throw new InterruptedException(); + } + } + catch (final InterruptedException e) { + } + return data; + } + + public void queueResult(final TmfSyntheticEventStub data) { + boolean ok = false; + try { + ok = fDataQueue.offer(data, TIMEOUT, TimeUnit.MILLISECONDS); + if (!ok) { + throw new InterruptedException(); + } + } + catch (final InterruptedException e) { + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/event/TmfEventTypeStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/event/TmfEventTypeStub.java new file mode 100644 index 0000000000..d280069ae0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/event/TmfEventTypeStub.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.event; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; + +/** + * TmfEventTypeStub + */ +@SuppressWarnings("javadoc") +public class TmfEventTypeStub extends TmfEventType { + + private static final ITmfEventField FIELD_1 = new TmfEventField("Field1", null, null); + private static final ITmfEventField FIELD_2 = new TmfEventField("Field2", null, null); + private static final ITmfEventField FIELD_3 = new TmfEventField("Field3", null, null); + private static final ITmfEventField FIELD_4 = new TmfEventField("Field4", null, null); + private static final ITmfEventField FIELD_5 = new TmfEventField("Field5", null, null); + + private static final ITmfEventField[] FIELDS = new ITmfEventField[] { + FIELD_1, FIELD_2, FIELD_3, FIELD_4, FIELD_5 }; + + private static ITmfEventField ROOT = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, null, FIELDS); + + public TmfEventTypeStub() { + super("UnitTest", "TmfEventTypeStub", ROOT); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/event/TmfSyncEventStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/event/TmfSyncEventStub.java new file mode 100644 index 0000000000..3cb6fe48c8 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/event/TmfSyncEventStub.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.event; + +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Event stub used by the synchronization tests + * + * @author Geneviève Bastien + */ +public class TmfSyncEventStub extends TmfEvent { + + private static final String stub = "stub"; //$NON-NLS-1$ + + /** + * Constructor + * + * @param trace + * The trace of this event + * @param timestamp + * The timestamp + */ + public TmfSyncEventStub(final ITmfTrace trace, final ITmfTimestamp timestamp) { + super(trace, + timestamp, + stub, + new TmfEventTypeStub(), + new TmfEventField(stub, stub, null), + stub); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/event/TmfSyntheticEventStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/event/TmfSyntheticEventStub.java new file mode 100644 index 0000000000..b34a340585 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/event/TmfSyntheticEventStub.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2009, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.event; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; + +/** + * TmfSyntheticEventStub + *

+ * TODO: Implement me. Please. + */ +@SuppressWarnings("javadoc") +public class TmfSyntheticEventStub extends TmfEvent { + + + public TmfSyntheticEventStub(final ITmfEvent event) { + super(event); + } + public TmfSyntheticEventStub(final TmfSyntheticEventStub other) { + super(other); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/request/TmfEventRequestStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/request/TmfEventRequestStub.java new file mode 100644 index 0000000000..1a5bb3b7d4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/request/TmfEventRequestStub.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.request; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; + +/** + * TmfEventRequestStub + */ +public class TmfEventRequestStub extends TmfEventRequest { + + /** + * @param dataType the event type + */ + public TmfEventRequestStub(final Class dataType) { + super(dataType, TmfTimeRange.ETERNITY, 0, ALL_DATA, ExecutionType.FOREGROUND); + } + + /** + * @param dataType the event type + * @param range the requested time range + */ + public TmfEventRequestStub(final Class dataType, final TmfTimeRange range) { + super(dataType, range, 0, ALL_DATA, ExecutionType.FOREGROUND); + } + + /** + * @param dataType the event type + * @param range the requested time range + * @param nbRequested the number of events requested + */ + public TmfEventRequestStub(final Class dataType, final TmfTimeRange range, final int nbRequested) { + super(dataType, range, 0, nbRequested, ExecutionType.FOREGROUND); + } + + /** + * @param dataType the event type + * @param range the requested time range + * @param nbRequested the number of events requested + * @param blockSize the event block size + */ + public TmfEventRequestStub(final Class dataType, final TmfTimeRange range, final int nbRequested, final int blockSize) { + super(dataType, range, 0, nbRequested, ExecutionType.FOREGROUND); + } + + /** + * @param dataType the event type + * @param range the requested time range + * @param index the initial event index + * @param nbRequested the number of events requested + * @param blockSize the event block size + */ + public TmfEventRequestStub(final Class dataType, final TmfTimeRange range, final long index, final int nbRequested, final int blockSize) { + super(dataType, range, index, nbRequested, ExecutionType.FOREGROUND); + } + + @Override + public void handleData(final ITmfEvent data) { + super.handleData(data); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfEmptyTraceStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfEmptyTraceStub.java new file mode 100644 index 0000000000..21cdb1bb85 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfEmptyTraceStub.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.trace; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.TmfContext; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +/** + * TmfEmptyTraceStub + *

+ * Dummy test trace. Use in conjunction with TmfEventParserStub. + */ +public class TmfEmptyTraceStub extends TmfTraceStub { + + /** + * + */ + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * + */ + public TmfEmptyTraceStub() { + super(); + setParser(new TmfEventParserStub(this)); + } + + // ------------------------------------------------------------------------ + // Operators + // ------------------------------------------------------------------------ + + @Override + public TmfContext seekEvent(final ITmfLocation location) { + return new TmfContext(); + } + + @Override + public TmfContext seekEvent(final double ratio) { + return new TmfContext(); + } + + @Override + public double getLocationRatio(ITmfLocation location) { + return 0; + } + + @Override + public ITmfLocation getCurrentLocation() { + return null; + } + + @Override + public ITmfEvent parseEvent(final ITmfContext context) { + return null; + } + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfEventParserStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfEventParserStub.java new file mode 100644 index 0000000000..52ffb46cc8 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfEventParserStub.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.trace; + +import java.io.EOFException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.Vector; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfEventParser; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * TmfEventParserStub + *

+ * TODO: Implement me. Please. + */ +@SuppressWarnings("javadoc") +public class TmfEventParserStub implements ITmfEventParser { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private static final int NB_TYPES = 10; + private final TmfEventType[] fTypes; + private final ITmfTrace fEventStream; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + public TmfEventParserStub(final ITmfTrace eventStream) { + fEventStream = eventStream; + fTypes = new TmfEventType[NB_TYPES]; + for (int i = 0; i < NB_TYPES; i++) { + final Vector fields = new Vector<>(); + for (int j = 1; j <= i; j++) { + final String field = "Fmt-" + i + "-Fld-" + j; + fields.add(field); + } + final String[] fieldArray = new String[i]; + final ITmfEventField rootField = TmfEventField.makeRoot(fields.toArray(fieldArray)); + fTypes[i] = new TmfEventType("UnitTest", "Type-" + i, rootField); + } + } + + // ------------------------------------------------------------------------ + // Operators + // ------------------------------------------------------------------------ + + static final String typePrefix = "Type-"; + @Override + public ITmfEvent parseEvent(final ITmfContext context) { + + if (! (fEventStream instanceof TmfTraceStub)) { + return null; + } + + // Highly inefficient... + final RandomAccessFile stream = ((TmfTraceStub) fEventStream).getStream(); + if (stream == null) { + return null; + } + + // String name = eventStream.getName(); + // name = name.substring(name.lastIndexOf('/') + 1); + + // no need to use synchronized since it's already cover by the calling method + + long location = 0; + if (context != null && context.getLocation() != null) { + location = (Long) context.getLocation().getLocationInfo(); + try { + stream.seek(location); + + final long ts = stream.readLong(); + final String source = stream.readUTF(); + final String type = stream.readUTF(); + final int reference = stream.readInt(); + final int typeIndex = Integer.parseInt(type.substring(typePrefix.length())); + final String[] fields = new String[typeIndex]; + for (int i = 0; i < typeIndex; i++) { + fields[i] = stream.readUTF(); + } + + final StringBuffer content = new StringBuffer("["); + if (typeIndex > 0) { + content.append(fields[0]); + } + for (int i = 1; i < typeIndex; i++) { + content.append(", ").append(fields[i]); + } + content.append("]"); + + final TmfEventField root = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, content.toString(), null); + final ITmfEvent event = new TmfEvent(fEventStream, + new TmfTimestamp(ts, -3, 0), // millisecs + source, fTypes[typeIndex], root, String.valueOf(reference)); + return event; + } catch (final EOFException e) { + } catch (final IOException e) { + } + } + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfExperimentStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfExperimentStub.java new file mode 100644 index 0000000000..2c279572b0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfExperimentStub.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.trace; + +import org.eclipse.core.resources.IResource; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer; + +/** + * TmfExperimentStub + *

+ * Implement me. Please. + *

+ */ +@SuppressWarnings("javadoc") +public class TmfExperimentStub extends TmfExperiment { + + public TmfExperimentStub() { + super(); + } + + public TmfExperimentStub(String name, ITmfTrace[] traces, int blockSize) { + super(ITmfEvent.class, name, traces, blockSize); + } + + @Override + protected ITmfTraceIndexer createIndexer(int interval) { + return new TmfIndexerStub(this, interval); + } + + @Override + public TmfIndexerStub getIndexer() { + return (TmfIndexerStub) super.getIndexer(); + } + + @Override + public void initExperiment(final Class type, final String path, final ITmfTrace[] traces, final int indexPageSize, IResource resource) { + super.initExperiment(type, path, traces, indexPageSize, resource); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfIndexerStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfIndexerStub.java new file mode 100644 index 0000000000..f28f80a6e4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfIndexerStub.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.trace; + +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer; + +/** + * TmfIndexerStub + *

+ * Implement me. Please. + *

+ */ +@SuppressWarnings("javadoc") +public class TmfIndexerStub extends TmfCheckpointIndexer { + + public TmfIndexerStub(ITmfTrace trace, int blockSize) { + super(trace, blockSize); + } + + public ITmfCheckpointIndex getCheckpoints() { + return getTraceIndex(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfTraceStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfTraceStub.java new file mode 100644 index 0000000000..1e0daf2a2c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfTraceStub.java @@ -0,0 +1,389 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Updated for removal of context clone + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.trace; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.util.concurrent.locks.ReentrantLock; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfEventParser; +import org.eclipse.tracecompass.tmf.core.trace.TmfContext; +import org.eclipse.tracecompass.tmf.core.trace.TmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfPersistentlyIndexable; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; + +/** + * TmfTraceStub + *

+ * Dummy test trace. Use in conjunction with TmfEventParserStub. + */ +public class TmfTraceStub extends TmfTrace implements ITmfEventParser, ITmfPersistentlyIndexable { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // The actual stream + private RandomAccessFile fTrace; + +// // The associated event parser +// private ITmfEventParser fParser; + + // The synchronization lock + private final ReentrantLock fLock = new ReentrantLock(); + + private ITmfTimestamp fInitialRangeOffset = null; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + public TmfTraceStub() { + super(); + setParser(new TmfEventParserStub(this)); + } + + /** + * Constructor with which you can specify a custom streaming interval. The + * parser and indexer won't be specified. + * + * @param path + * The path to the trace file + * @param cacheSize + * The cache size + * @param interval + * The trace streaming interval + * @throws TmfTraceException + * If an error occurred opening the trace + */ + public TmfTraceStub(final String path, + final int cacheSize, + final long interval) throws TmfTraceException { + super(null, ITmfEvent.class, path, cacheSize, interval, null); + setupTrace(path); + setParser(new TmfEventParserStub(this)); + } + + /** + * Constructor to specify the parser and indexer. The streaming interval + * will be 0. + * + * @param path + * The path to the trace file + * @param cacheSize + * The cache size + * @param waitForCompletion + * Do we block the caller until the trace is indexed, or not. + * @param parser + * The trace parser. If left 'null', it will use a + * {@link TmfEventParserStub}. + * @throws TmfTraceException + * If an error occurred opening the trace + */ + public TmfTraceStub(final String path, + final int cacheSize, + final boolean waitForCompletion, + final ITmfEventParser parser) throws TmfTraceException { + super(null, ITmfEvent.class, path, cacheSize, 0, null); + setupTrace(path); + setParser((parser != null) ? parser : new TmfEventParserStub(this)); + if (waitForCompletion) { + indexTrace(true); + } + } + + /** + * Copy constructor + * + * @param trace + * The trace to copy + * @throws TmfTraceException + * If an error occurred opening the trace + */ + public TmfTraceStub(final TmfTraceStub trace) throws TmfTraceException { + super(trace); + setupTrace(getPath()); // fPath will be set by the super-constructor + setParser(new TmfEventParserStub(this)); + } + + + private void setupTrace(String path) throws TmfTraceException { + try { + fTrace = new RandomAccessFile(path, "r"); //$NON-NLS-1$ + } catch (FileNotFoundException e) { + throw new TmfTraceException(e.getMessage()); + } + } + + // ------------------------------------------------------------------------ + // Initializers + // ------------------------------------------------------------------------ + + @Override + public void initTrace(final IResource resource, final String path, final Class type) throws TmfTraceException { + try { + fTrace = new RandomAccessFile(path, "r"); //$NON-NLS-1$ + } catch (FileNotFoundException e) { + throw new TmfTraceException(e.getMessage()); + } + setParser(new TmfEventParserStub(this)); + super.initTrace(resource, path, type); + } + + @Override + public void initialize(final IResource resource, final String path, final Class type) throws TmfTraceException { + super.initialize(resource, path, type); + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * @return The file stream to the trace + */ + public RandomAccessFile getStream() { + return fTrace; + } + + /** + * Set the initial range offset. + * + * @param initOffset + * The new initial range offset + */ + public void setInitialRangeOffset(ITmfTimestamp initOffset) { + fInitialRangeOffset = initOffset; + } + + @Override + public ITmfTimestamp getInitialRangeOffset() { + if (fInitialRangeOffset != null) { + return fInitialRangeOffset; + } + return super.getInitialRangeOffset(); + } + + // ------------------------------------------------------------------------ + // Operators + // ------------------------------------------------------------------------ + + @Override + public TmfContext seekEvent(final ITmfLocation location) { + try { + fLock.lock(); + try { + if (fTrace != null) { + // Position the trace at the requested location and + // returns the corresponding context + long loc = 0; + long rank = 0; + if (location != null) { + loc = (Long) location.getLocationInfo(); + rank = ITmfContext.UNKNOWN_RANK; + } + if (loc != fTrace.getFilePointer()) { + fTrace.seek(loc); + } + final TmfContext context = new TmfContext(getCurrentLocation(), rank); + return context; + } + } catch (final IOException e) { + e.printStackTrace(); + } catch (final NullPointerException e) { + e.printStackTrace(); + } + finally{ + fLock.unlock(); + } + } catch (final NullPointerException e) { + e.printStackTrace(); + } + return null; + } + + + @Override + public TmfContext seekEvent(final double ratio) { + fLock.lock(); + try { + if (fTrace != null) { + final ITmfLocation location = new TmfLongLocation(Long.valueOf(Math.round(ratio * fTrace.length()))); + final TmfContext context = seekEvent(location); + context.setRank(ITmfContext.UNKNOWN_RANK); + return context; + } + } catch (final IOException e) { + e.printStackTrace(); + } finally { + fLock.unlock(); + } + + return null; + } + + @Override + public double getLocationRatio(ITmfLocation location) { + fLock.lock(); + try { + if (fTrace != null) { + if (location.getLocationInfo() instanceof Long) { + return ((Long) location.getLocationInfo()).doubleValue() / fTrace.length(); + } + } + } catch (final IOException e) { + e.printStackTrace(); + } finally { + fLock.unlock(); + } + return 0; + } + + @Override + public ITmfLocation getCurrentLocation() { + fLock.lock(); + try { + if (fTrace != null) { + return new TmfLongLocation(fTrace.getFilePointer()); + } + } catch (final IOException e) { + e.printStackTrace(); + } finally { + fLock.unlock(); + } + return null; + } + + @Override + public ITmfEvent parseEvent(final ITmfContext context) { + fLock.lock(); + try { + // parseNextEvent will update the context + if (fTrace != null && getParser() != null && context != null) { + final ITmfEvent event = getParser().parseEvent(context); + return event; + } + } finally { + fLock.unlock(); + } + return null; + } + + @Override + public synchronized void setNbEvents(final long nbEvents) { + super.setNbEvents(nbEvents); + } + + @Override + public void setTimeRange(final TmfTimeRange range) { + super.setTimeRange(range); + } + + @Override + public void setStartTime(final ITmfTimestamp startTime) { + super.setStartTime(startTime); + } + + @Override + public void setEndTime(final ITmfTimestamp endTime) { + super.setEndTime(endTime); + } + + @Override + public void setStreamingInterval(final long interval) { + super.setStreamingInterval(interval); + } + + @Override + public synchronized void dispose() { + fLock.lock(); + try { + if (fTrace != null) { + fTrace.close(); + fTrace = null; + } + } catch (final IOException e) { + // Ignore + } finally { + fLock.unlock(); + } + super.dispose(); + } + + @Override + public IStatus validate(IProject project, String path) { + if (fileExists(path)) { + return Status.OK_STATUS; + } + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "File does not exist: " + path); + } + + private static int fCheckpointSize = -1; + + @Override + public synchronized int getCheckpointSize() { + if (fCheckpointSize == -1) { + TmfCheckpoint c = new TmfCheckpoint(new TmfTimestamp(0L), new TmfLongLocation(0L), 0); + ByteBuffer b = ByteBuffer.allocate(ITmfCheckpoint.MAX_SERIALIZE_SIZE); + b.clear(); + c.serialize(b); + fCheckpointSize = b.position(); + } + + return fCheckpointSize; + } + + @Override + public ITmfLocation restoreLocation(ByteBuffer bufferIn) { + return new TmfLongLocation(bufferIn); + } + + /** + * Simulate trace opening, to be called by tests who need an actively opened + * trace + */ + public void openTrace() { + TmfSignalManager.dispatchSignal(new TmfTraceOpenedSignal(this, this, null)); + selectTrace(); + } + + /** + * Simulate selecting the trace + */ + public void selectTrace() { + TmfSignalManager.dispatchSignal(new TmfTraceSelectedSignal(this, this)); + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfTraceStub2.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfTraceStub2.java new file mode 100644 index 0000000000..6aad924e42 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfTraceStub2.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.trace; + +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.trace.ITmfEventParser; + +/** + * Another stub trace class for unit tests who need more than one stub class. + * + * @author Geneviève Bastien + */ +public class TmfTraceStub2 extends TmfTraceStub { + + /** + * Default constructor + */ + public TmfTraceStub2() { + super(); + } + + /** + * Constructor to specify the parser and indexer. The streaming interval + * will be 0. + * + * @param path + * The path to the trace file + * @param cacheSize + * The cache size + * @param waitForCompletion + * Do we block the caller until the trace is indexed, or not. + * @param parser + * The trace parser. If left 'null', it will use a + * {@link TmfEventParserStub}. + * @throws TmfTraceException + * If an error occurred opening the trace + */ + public TmfTraceStub2(final String path, + final int cacheSize, + final boolean waitForCompletion, + final ITmfEventParser parser) throws TmfTraceException { + super(path, cacheSize, waitForCompletion, parser); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfTraceStub3.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfTraceStub3.java new file mode 100644 index 0000000000..1a1f584eb3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/TmfTraceStub3.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.trace; + +/** + * Another stub trace class for unit tests who need more than one stub class. + * + * @author Geneviève Bastien + */ +public class TmfTraceStub3 extends TmfTraceStub { + + /** + * Default constructor + */ + public TmfTraceStub3() { + super(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/text/SyslogEvent.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/text/SyslogEvent.java new file mode 100644 index 0000000000..f8e8bf62cc --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/text/SyslogEvent.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.trace.text; + +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.core.event.collapse.ITmfCollapsibleEvent; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.text.TextTraceEvent; +import org.eclipse.tracecompass.tmf.core.trace.text.TextTraceEventContent; + +/** + * System log trace implementation of TmfEvent. + */ +public class SyslogEvent extends TextTraceEvent implements ITmfCollapsibleEvent { + + /** + * Default constructor + */ + public SyslogEvent() { + super(null, null, null, new SyslogEventType(), null, null); + } + + /** + * Copy constructor + * + * @param other + * the event to copy + * + */ + public SyslogEvent(final SyslogEvent other) { + super(other); + } + + /** + * Full Constructor + * + * @param parentTrace + * the parent trace + * @param timestamp + * the event timestamp + * @param source + * the event source + * @param type + * the event type + * @param content + * the event content (payload) + * @param reference + * the event reference + */ + public SyslogEvent(SyslogTrace parentTrace, final ITmfTimestamp timestamp, final String source, + final ITmfEventType type, final TextTraceEventContent content, final String reference) { + super(parentTrace, timestamp, source, type, content, reference); + } + + @Override + public boolean isCollapsibleWith(ITmfEvent otherEvent) { + if (this == otherEvent) { + return true; + } + + if (!(otherEvent instanceof SyslogEvent)) { + return false; + } + + final SyslogEvent other = (SyslogEvent) otherEvent; + + if (getTrace() == null) { + if (other.getTrace() != null) { + return false; + } + } else if (!getTrace().equals(other.getTrace())) { + return false; + } + + if (getType() == null) { + if (other.getType() != null) { + return false; + } + } else if (!getType().equals(other.getType())) { + return false; + } + + TextTraceEventContent content = this.getContent(); + TextTraceEventContent otherContent = other.getContent(); + + if (content == null) { + if (otherContent != null) { + return false; + } + return true; + } + + if (otherContent == null) { + return false; + } + + List fields = content.getFields(); + List otherFields = otherContent.getFields(); + int size = fields.size(); + + if (size != otherFields.size()) { + return false; + } + + // At i = 0 the timestamp is stored and needs to be bypassed + for (int i = 1; i < size; i++) { + if (!fields.get(i).equals(otherFields.get(i))) { + return false; + } + } + return true; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/text/SyslogEventType.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/text/SyslogEventType.java new file mode 100644 index 0000000000..66768a24d5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/text/SyslogEventType.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.trace.text; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; + +/** + * The system log extension of the TMF event type. + */ +public class SyslogEventType extends TmfEventType { + + /** The event type id string. */ + public static final String TYPE_ID = "Syslog"; //$NON-NLS-1$ + /** The labels (field names) used for SA system log events. */ + @SuppressWarnings("nls") + public static final String[] LABELS = {"Timestamp", "Host", "Logger", "Message"}; + /** A default instance of this class */ + public static final SyslogEventType INSTANCE = new SyslogEventType(); + + /** Index numbers in the array of event field names and values. */ + public interface Index { + /** Index for time stamp */ + int TIMESTAMP = 0; + /** Index for the host name */ + int HOST = 1; + /** Index for the logger name */ + int LOGGER = 2; + /** Index for the event message */ + int MESSAGE = 3; + } + + /** + * Default Constructor + */ + public SyslogEventType() { + super(ITmfEventType.DEFAULT_CONTEXT_ID, TYPE_ID, TmfEventField.makeRoot(LABELS)); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/text/SyslogTrace.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/text/SyslogTrace.java new file mode 100644 index 0000000000..8f3cd46608 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/text/SyslogTrace.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.trace.text; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimePreferences; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; +import org.eclipse.tracecompass.tmf.core.trace.text.TextTrace; +import org.eclipse.tracecompass.tmf.core.trace.text.TextTraceEventContent; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.text.SyslogEventType.Index; + +/** + * Extension of TmfTrace for handling of system logs. + */ +public class SyslogTrace extends TextTrace { + + /** The cache size for system log traces. */ + private static final int CACHE_SIZE = 100; + /** The time stamp format of the trace type. */ + public static final String TIMESTAMP_FORMAT = "MMM dd HH:mm:ss"; //$NON-NLS-1$ + /** The corresponding date format of the time stamp. */ + public static final SimpleDateFormat TIMESTAMP_SIMPLEDATEFORMAT = new SimpleDateFormat( + TIMESTAMP_FORMAT, TmfTimePreferences.getInstance().getLocale()); + /** The regular expression pattern of the first line of an event. */ + public static final Pattern LINE1_PATTERN = Pattern.compile( + "\\s*(\\S\\S\\S \\d\\d? \\d\\d:\\d\\d:\\d\\d)\\s*(\\S*)\\s*(\\S*):+\\s*(.*\\S)?"); //$NON-NLS-1$ + + /* The current calendar to use */ + private static final Calendar CURRENT = Calendar.getInstance(); + + /** + * Constructor + */ + public SyslogTrace() { + setCacheSize(CACHE_SIZE); + } + + @Override + protected Pattern getFirstLinePattern() { + return LINE1_PATTERN; + } + + @Override + protected SyslogEvent parseFirstLine(Matcher matcher, String line) { + + ITmfTimestamp timestamp = null; + + try { + synchronized (TIMESTAMP_SIMPLEDATEFORMAT) { + TIMESTAMP_SIMPLEDATEFORMAT.setTimeZone(TmfTimestampFormat.getDefaulTimeFormat().getTimeZone()); + Date date = TIMESTAMP_SIMPLEDATEFORMAT.parse(matcher.group(1)); + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTime(date); + calendar.set(Calendar.YEAR, CURRENT.get(Calendar.YEAR)); + if (calendar.after(CURRENT)) { + calendar.set(Calendar.YEAR, CURRENT.get(Calendar.YEAR) - 1); + } + long ns = calendar.getTimeInMillis() * 1000000; + timestamp = createTimestamp(ns); + } + } catch (ParseException e) { + timestamp = new TmfTimestamp(); + } + + TextTraceEventContent content = new TextTraceEventContent(SyslogEventType.LABELS); + content.setValue(new StringBuffer(line)); + content.setFieldValue(Index.TIMESTAMP, matcher.group(1)); + content.setFieldValue(Index.HOST, matcher.group(2)); + content.setFieldValue(Index.LOGGER, matcher.group(3)); + content.setFieldValue(Index.MESSAGE, new StringBuffer(matcher.group(4) != null ? matcher.group(4) : "")); //$NON-NLS-1$ + + SyslogEvent event = new SyslogEvent( + this, + timestamp, + "", //$NON-NLS-1$ + SyslogEventType.INSTANCE, + content, + ""); //$NON-NLS-1$ + + return event; + } + + @Override + protected void parseNextLine(SyslogEvent event, String line) { + TextTraceEventContent content = event.getContent(); + ((StringBuffer) content.getValue()).append("\n").append(line); //$NON-NLS-1$ + if (line.trim().length() > 0) { + ((StringBuffer) content.getFieldValue(Index.MESSAGE)).append(SEPARATOR + line.trim()); + } + } + + @Override + public ITmfTimestamp getInitialRangeOffset() { + return new TmfTimestamp(60, ITmfTimestamp.SECOND_SCALE); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/Messages.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/Messages.java new file mode 100644 index 0000000000..30b12bd310 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/Messages.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.trace.xml; + +import org.eclipse.osgi.util.NLS; + +/** + * Externalized messages for the + * {@link org.eclipse.tracecompass.tmf.tests.stubs.trace.xml} package + * + * @author Geneviève Bastien + */ +@SuppressWarnings("javadoc") +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.messages"; //$NON-NLS-1$ + + public static String TmfDevelopmentTrace_FileNotFound; + public static String TmfDevelopmentTrace_IoError; + public static String TmfDevelopmentTrace_ValidationError; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xml b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xml new file mode 100644 index 0000000000..96ec2b9b5d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xml @@ -0,0 +1,38 @@ + + + +T + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xsd b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xsd new file mode 100644 index 0000000000..fe8abdfd9e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xsd @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/TmfXmlTraceStub.java b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/TmfXmlTraceStub.java new file mode 100644 index 0000000000..d612b7b91f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/TmfXmlTraceStub.java @@ -0,0 +1,252 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.tests.stubs.trace.xml; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import javax.xml.XMLConstants; +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.osgi.util.NLS; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomEventContent; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlEvent; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTrace; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.TmfContext; +import org.eclipse.tracecompass.tmf.core.trace.TmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; +import org.xml.sax.SAXException; + +/** + * An XML development trace using a custom XML trace definition and schema. + * + * This class will typically be used to build custom traces to unit test more + * complex functionalities like analyzes or to develop and test data-driven + * analyzes. + * + * This class wraps a custom XML trace and rewrites the returned events in the + * getNext() method so that event's fields are the ones defined in + * elements instead of those defined in the custom XML parser. This way, each + * event can have a different set of fields. This class can, for example, mimic + * a CTF trace. + * + * @author Geneviève Bastien + */ +public class TmfXmlTraceStub extends TmfTrace { + + private static final String DEVELOPMENT_TRACE_PARSER_PATH = "TmfXmlDevelopmentTrace.xml"; //$NON-NLS-1$ + private static final String DEVELOPMENT_TRACE_XSD = "TmfXmlDevelopmentTrace.xsd"; //$NON-NLS-1$ + private static final String EMPTY = ""; //$NON-NLS-1$ + + /* XML elements and attributes names */ + private static final String EVENT_NAME_FIELD = "Message"; //$NON-NLS-1$ + private static final String FIELD_NAMES_FIELD = "fields"; //$NON-NLS-1$ + private static final String SOURCE_FIELD = "source"; //$NON-NLS-1$ + private static final String VALUES_FIELD = "values"; //$NON-NLS-1$ + private static final String TYPES_FIELD = "type"; //$NON-NLS-1$ + private static final String VALUES_SEPARATOR = " \\| "; //$NON-NLS-1$ + private static final String TYPE_INTEGER = "int"; //$NON-NLS-1$ + private static final String TYPE_LONG = "long"; //$NON-NLS-1$ + + private final CustomXmlTrace fTrace; + + /** + * Constructor. Constructs the custom XML trace with the appropriate + * definition. + */ + public TmfXmlTraceStub() { + + /* Load custom XML definition */ + try (InputStream in = TmfXmlTraceStub.class.getResourceAsStream(DEVELOPMENT_TRACE_PARSER_PATH);) { + CustomXmlTraceDefinition[] definitions = CustomXmlTraceDefinition.loadAll(in); + if (definitions.length == 0) { + throw new IllegalStateException("The custom trace definition does not exist"); //$NON-NLS-1$ + } + fTrace = new CustomXmlTrace(definitions[0]); + /* Deregister the custom XML trace */ + TmfSignalManager.deregister(fTrace); + this.setParser(fTrace); + } catch (IOException e) { + throw new IllegalStateException("Cannot open the trace parser for development traces"); //$NON-NLS-1$ + } + + } + + @Override + public void initTrace(IResource resource, String path, Class type) throws TmfTraceException { + super.initTrace(resource, path, type); + fTrace.initTrace(resource, path, type); + ITmfContext ctx; + /* Set the start and (current) end times for this trace */ + ctx = seekEvent(0L); + ITmfEvent event = getNext(ctx); + if (event != null) { + final ITmfTimestamp curTime = event.getTimestamp(); + this.setStartTime(curTime); + this.setEndTime(curTime); + } + } + + @Override + public ITmfLocation getCurrentLocation() { + return fTrace.getCurrentLocation(); + } + + @Override + public double getLocationRatio(ITmfLocation location) { + return fTrace.getLocationRatio(location); + } + + @Override + public ITmfContext seekEvent(ITmfLocation location) { + return fTrace.seekEvent(location); + } + + @Override + public ITmfContext seekEvent(double ratio) { + return fTrace.seekEvent(ratio); + } + + @Override + public IStatus validate(IProject project, String path) { + File xmlFile = new File(path); + if (!xmlFile.exists() || !xmlFile.isFile() || !xmlFile.canRead()) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.Messages.TmfDevelopmentTrace_FileNotFound, path)); + } + /* Does the XML file validate with the XSD */ + SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Source xmlSource = new StreamSource(xmlFile); + + try { + URL url = TmfXmlTraceStub.class.getResource(DEVELOPMENT_TRACE_XSD); + Schema schema = schemaFactory.newSchema(url); + + Validator validator = schema.newValidator(); + validator.validate(xmlSource); + } catch (SAXException e) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.Messages.TmfDevelopmentTrace_ValidationError, path), e); + } catch (IOException e) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.Messages.TmfDevelopmentTrace_IoError, path), e); + } + return Status.OK_STATUS; + } + + private static String getStringValue(@NonNull ITmfEventField content, String fieldName) { + ITmfEventField field = content.getField(fieldName); + if (field == null) { + return EMPTY; + } + Object val = field.getValue(); + if (!(val instanceof String)) { + return EMPTY; + } + return (String) val; + } + + @Override + public synchronized ITmfEvent getNext(ITmfContext context) { + final ITmfContext savedContext = new TmfContext(context.getLocation(), context.getRank()); + CustomXmlEvent event = fTrace.getNext(context); + if (event == null) { + return null; + } + + /* Translate the content of the event */ + /* The "fields" field contains a | separated list of field names */ + /* The "values" field contains a | separated list of field values */ + /* the "type" field contains a | separated list of field types */ + ITmfEventField content = event.getContent(); + if (content == null) { + return null; + } + String fieldString = getStringValue(content, FIELD_NAMES_FIELD); + String valueString = getStringValue(content, VALUES_FIELD); + String typeString = getStringValue(content, TYPES_FIELD); + + String[] fields = fieldString.split(VALUES_SEPARATOR); + String[] values = valueString.split(VALUES_SEPARATOR); + String[] types = typeString.split(VALUES_SEPARATOR); + ITmfEventField[] fieldsArray = new TmfEventField[fields.length]; + + for (int i = 0; i < fields.length; i++) { + String value = EMPTY; + if (values.length > i) { + value = values[i]; + } + String type = null; + if (types.length > i) { + type = types[i]; + } + Object val = value; + if (type != null) { + switch (type) { + case TYPE_INTEGER: { + try { + val = Integer.valueOf(value); + } catch (NumberFormatException e) { + Activator.logError(String.format("Get next XML event: cannot cast value %s to integer", value), e); //$NON-NLS-1$ + val = 0; + } + break; + } + case TYPE_LONG: { + try { + val = Long.valueOf(value); + } catch (NumberFormatException e) { + Activator.logError(String.format("Get next XML event: cannot cast value %s to long", value), e); //$NON-NLS-1$ + val = 0L; + } + break; + } + default: + break; + } + } + fieldsArray[i] = new TmfEventField(fields[i], val, null); + } + + /* Create a new event with new fields and name */ + ITmfEventType customEventType = event.getType(); + TmfEventType eventType = new TmfEventType(customEventType.getContext(), getStringValue(content, EVENT_NAME_FIELD), customEventType.getRootField()); + ITmfEventField eventFields = new CustomEventContent(content.getName(), content.getValue(), fieldsArray); + TmfEvent newEvent = new TmfEvent(this, event.getTimestamp(), getStringValue(content, SOURCE_FIELD), eventType, eventFields, event.getReference()); + updateAttributes(savedContext, event.getTimestamp()); + context.increaseRank(); + + return newEvent; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/messages.properties b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/messages.properties new file mode 100644 index 0000000000..005b58eba4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/messages.properties @@ -0,0 +1,15 @@ +############################################################################### +# Copyright (c) 2014 École Polytechnique de Montréal +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# École Polytechnique de Montréal - Initial API and implementation +############################################################################### + +TmfDevelopmentTrace_FileNotFound=File not found: {0} +TmfDevelopmentTrace_IoError=IOException validating file: {0} +TmfDevelopmentTrace_ValidationError=Trace file does not validate: {0} diff --git a/org.eclipse.tracecompass.tmf.core/META-INF/MANIFEST.MF b/org.eclipse.tracecompass.tmf.core/META-INF/MANIFEST.MF index 671cecfe35..27a844c283 100644 --- a/org.eclipse.tracecompass.tmf.core/META-INF/MANIFEST.MF +++ b/org.eclipse.tracecompass.tmf.core/META-INF/MANIFEST.MF @@ -5,50 +5,50 @@ Bundle-Vendor: %Bundle-Vendor Bundle-Version: 3.2.0.qualifier Bundle-Localization: plugin Bundle-SymbolicName: org.eclipse.tracecompass.tmf.core;singleton:=true -Bundle-Activator: org.eclipse.linuxtools.internal.tmf.core.Activator +Bundle-Activator: org.eclipse.tracecompass.internal.tmf.core.Activator Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.resources, org.eclipse.tracecompass.statesystem.core;visibility:=reexport -Export-Package: org.eclipse.linuxtools.internal.tmf.core;x-friends:="org.eclipse.tracecompass.tmf.core.tests,org.eclipse.tracecompass.tmf.ui.swtbot.tests", - org.eclipse.linuxtools.internal.tmf.core.analysis;x-friends:="org.eclipse.tracecompass.tmf.core.tests", - org.eclipse.linuxtools.internal.tmf.core.component;x-friends:="org.eclipse.tracecompass.tmf.core.tests", - org.eclipse.linuxtools.internal.tmf.core.filter;x-friends:="org.eclipse.tracecompass.tmf.core.tests,org.eclipse.tracecompass.tmf.ui", - org.eclipse.linuxtools.internal.tmf.core.request;x-friends:="org.eclipse.tracecompass.tmf.core.tests", - org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.partial;x-friends:="org.eclipse.tracecompass.statesystem.core.tests", - org.eclipse.linuxtools.internal.tmf.core.statesystem.mipmap;x-friends:="org.eclipse.tracecompass.tmf.core.tests", - org.eclipse.linuxtools.internal.tmf.core.synchronization;x-friends:="org.eclipse.tracecompass.tmf.core.tests", - org.eclipse.linuxtools.internal.tmf.core.synchronization.graph;x-friends:="org.eclipse.tracecompass.tmf.core.tests", - org.eclipse.linuxtools.internal.tmf.core.trace;x-friends:="org.eclipse.tracecompass.tmf.core.tests", - org.eclipse.linuxtools.internal.tmf.core.trace.indexer;x-friends:="org.eclipse.tracecompass.tmf.core.tests", - org.eclipse.linuxtools.tmf.core, - org.eclipse.linuxtools.tmf.core.analysis, - org.eclipse.linuxtools.tmf.core.callstack, - org.eclipse.linuxtools.tmf.core.component, - org.eclipse.linuxtools.tmf.core.event, - org.eclipse.linuxtools.tmf.core.event.collapse, - org.eclipse.linuxtools.tmf.core.event.lookup, - org.eclipse.linuxtools.tmf.core.event.matching, - org.eclipse.linuxtools.tmf.core.exceptions, - org.eclipse.linuxtools.tmf.core.filter, - org.eclipse.linuxtools.tmf.core.filter.model, - org.eclipse.linuxtools.tmf.core.filter.xml, - org.eclipse.linuxtools.tmf.core.io, - org.eclipse.linuxtools.tmf.core.parsers.custom, - org.eclipse.linuxtools.tmf.core.project.model, - org.eclipse.linuxtools.tmf.core.request, - org.eclipse.linuxtools.tmf.core.signal, - org.eclipse.linuxtools.tmf.core.statesystem, - org.eclipse.linuxtools.tmf.core.statistics, - org.eclipse.linuxtools.tmf.core.synchronization, - org.eclipse.linuxtools.tmf.core.timestamp, - org.eclipse.linuxtools.tmf.core.trace, - org.eclipse.linuxtools.tmf.core.trace.indexer, - org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint, - org.eclipse.linuxtools.tmf.core.trace.location, - org.eclipse.linuxtools.tmf.core.trace.text, - org.eclipse.linuxtools.tmf.core.uml2sd, - org.eclipse.linuxtools.tmf.core.util +Export-Package: org.eclipse.tracecompass.internal.tmf.core;x-friends:="org.eclipse.tracecompass.tmf.core.tests,org.eclipse.tracecompass.tmf.ui.swtbot.tests", + org.eclipse.tracecompass.internal.tmf.core.analysis;x-friends:="org.eclipse.tracecompass.tmf.core.tests", + org.eclipse.tracecompass.internal.tmf.core.component;x-friends:="org.eclipse.tracecompass.tmf.core.tests", + org.eclipse.tracecompass.internal.tmf.core.filter;x-friends:="org.eclipse.tracecompass.tmf.core.tests,org.eclipse.tracecompass.tmf.ui", + org.eclipse.tracecompass.internal.tmf.core.request;x-friends:="org.eclipse.tracecompass.tmf.core.tests", + org.eclipse.tracecompass.internal.tmf.core.statesystem.backends.partial;x-friends:="org.eclipse.tracecompass.statesystem.core.tests", + org.eclipse.tracecompass.internal.tmf.core.statesystem.mipmap;x-friends:="org.eclipse.tracecompass.tmf.core.tests", + org.eclipse.tracecompass.internal.tmf.core.synchronization;x-friends:="org.eclipse.tracecompass.tmf.core.tests", + org.eclipse.tracecompass.internal.tmf.core.synchronization.graph;x-friends:="org.eclipse.tracecompass.tmf.core.tests", + org.eclipse.tracecompass.internal.tmf.core.trace;x-friends:="org.eclipse.tracecompass.tmf.core.tests", + org.eclipse.tracecompass.internal.tmf.core.trace.indexer;x-friends:="org.eclipse.tracecompass.tmf.core.tests", + org.eclipse.tracecompass.tmf.core, + org.eclipse.tracecompass.tmf.core.analysis, + org.eclipse.tracecompass.tmf.core.callstack, + org.eclipse.tracecompass.tmf.core.component, + org.eclipse.tracecompass.tmf.core.event, + org.eclipse.tracecompass.tmf.core.event.collapse, + org.eclipse.tracecompass.tmf.core.event.lookup, + org.eclipse.tracecompass.tmf.core.event.matching, + org.eclipse.tracecompass.tmf.core.exceptions, + org.eclipse.tracecompass.tmf.core.filter, + org.eclipse.tracecompass.tmf.core.filter.model, + org.eclipse.tracecompass.tmf.core.filter.xml, + org.eclipse.tracecompass.tmf.core.io, + org.eclipse.tracecompass.tmf.core.parsers.custom, + org.eclipse.tracecompass.tmf.core.project.model, + org.eclipse.tracecompass.tmf.core.request, + org.eclipse.tracecompass.tmf.core.signal, + org.eclipse.tracecompass.tmf.core.statesystem, + org.eclipse.tracecompass.tmf.core.statistics, + org.eclipse.tracecompass.tmf.core.synchronization, + org.eclipse.tracecompass.tmf.core.timestamp, + org.eclipse.tracecompass.tmf.core.trace, + org.eclipse.tracecompass.tmf.core.trace.indexer, + org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint, + org.eclipse.tracecompass.tmf.core.trace.location, + org.eclipse.tracecompass.tmf.core.trace.text, + org.eclipse.tracecompass.tmf.core.uml2sd, + org.eclipse.tracecompass.tmf.core.util Import-Package: com.google.common.base, com.google.common.collect diff --git a/org.eclipse.tracecompass.tmf.core/plugin.xml b/org.eclipse.tracecompass.tmf.core/plugin.xml index 45eaf88b1d..309a162773 100644 --- a/org.eclipse.tracecompass.tmf.core/plugin.xml +++ b/org.eclipse.tracecompass.tmf.core/plugin.xml @@ -7,26 +7,26 @@ + class="org.eclipse.tracecompass.internal.tmf.core.TmfCorePreferenceInitializer"> + class="org.eclipse.tracecompass.internal.tmf.core.analysis.TmfAnalysisModuleSourceConfigElement"> + class="org.eclipse.tracecompass.tmf.core.trace.TmfTrace"> + class="org.eclipse.tracecompass.tmf.core.trace.TmfExperiment"> @@ -35,7 +35,7 @@ + experiment_type="org.eclipse.tracecompass.tmf.core.trace.TmfExperiment"> diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/Activator.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/Activator.java deleted file mode 100644 index 84db09ef2a..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/Activator.java +++ /dev/null @@ -1,196 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Add signal manager disposal - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Plugin; -import org.eclipse.core.runtime.Status; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.osgi.framework.BundleContext; - -/** - * The activator class controls the plug-in life cycle. No more than one such - * plug-in can exist at any time. - *

- * It also provides the plug-in's general logging facility and manages the - * internal tracer. - */ -public class Activator extends Plugin { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The plug-in ID - */ - public static final String PLUGIN_ID = "org.eclipse.tracecompass.tmf.core"; //$NON-NLS-1$ - - /** - * The shared instance - */ - private static Activator fPlugin; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructor - */ - public Activator() { - setDefault(this); - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Returns the TMF Core plug-in instance. - * - * @return the TMF Core plug-in instance. - */ - public static Activator getDefault() { - return fPlugin; - } - - // Sets plug-in instance - private static void setDefault(Activator plugin) { - fPlugin = plugin; - } - - // ------------------------------------------------------------------------ - // Plugin - // ------------------------------------------------------------------------ - - @Override - public void start(BundleContext context) throws Exception { - super.start(context); - setDefault(this); - TmfCoreTracer.init(); - /* Initialize the trace manager */ - TmfTraceManager.getInstance(); - /* Initialize the analysis manager */ - TmfAnalysisManager.initialize(); - } - - @Override - public void stop(BundleContext context) throws Exception { - TmfCoreTracer.stop(); - TmfSignalManager.dispose(); - setDefault(null); - super.stop(context); - } - - - // ------------------------------------------------------------------------ - // Log an IStatus - // ------------------------------------------------------------------------ - - /** - * Log an IStatus object directly - * - * @param status - * The status to log - */ - public static void log(IStatus status) { - fPlugin.getLog().log(status); - } - - // ------------------------------------------------------------------------ - // Log INFO - // ------------------------------------------------------------------------ - - /** - * Logs a message with severity INFO in the runtime log of the plug-in. - * - * @param message - * A message to log - */ - public static void logInfo(String message) { - fPlugin.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity INFO in the runtime log of the - * plug-in. - * - * @param message - * A message to log - * @param exception - * The corresponding exception - */ - public static void logInfo(String message, Throwable exception) { - fPlugin.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message, exception)); - } - - // ------------------------------------------------------------------------ - // Log WARNING - // ------------------------------------------------------------------------ - - /** - * Logs a message and exception with severity WARNING in the runtime log of - * the plug-in. - * - * @param message - * A message to log - */ - public static void logWarning(String message) { - fPlugin.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity WARNING in the runtime log of - * the plug-in. - * - * @param message - * A message to log - * @param exception - * The corresponding exception - */ - public static void logWarning(String message, Throwable exception) { - fPlugin.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message, exception)); - } - - // ------------------------------------------------------------------------ - // Log ERROR - // ------------------------------------------------------------------------ - - /** - * Logs a message and exception with severity ERROR in the runtime log of - * the plug-in. - * - * @param message - * A message to log - */ - public static void logError(String message) { - fPlugin.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity ERROR in the runtime log of - * the plug-in. - * - * @param message - * A message to log - * @param exception - * The corresponding exception - */ - public static void logError(String message, Throwable exception) { - fPlugin.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, exception)); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/Messages.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/Messages.java deleted file mode 100644 index 70b4ee8e45..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/Messages.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core; - -import org.eclipse.osgi.util.NLS; - -/** - * TMF Core message bundle - * @since 2.0 - */ -@SuppressWarnings("javadoc") -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.tmf.core.messages"; //$NON-NLS-1$ - public static String TmfCheckpointIndexer_EventsPerSecond; - public static String TmfCheckpointIndexer_Indexing; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/TmfCorePreferenceInitializer.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/TmfCorePreferenceInitializer.java deleted file mode 100644 index 5103f44bfb..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/TmfCorePreferenceInitializer.java +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core; - -import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimePreferences; - -/** - * Preference initializer for tmf.core - * - */ -public class TmfCorePreferenceInitializer extends AbstractPreferenceInitializer { - - @Override - public void initializeDefaultPreferences() { - TmfTimePreferences.init(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/TmfCoreTracer.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/TmfCoreTracer.java deleted file mode 100644 index 3a36d41ed6..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/TmfCoreTracer.java +++ /dev/null @@ -1,239 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core; - -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; - -import org.eclipse.core.runtime.Platform; -import org.eclipse.linuxtools.tmf.core.component.ITmfComponent; -import org.eclipse.linuxtools.tmf.core.component.ITmfEventProvider; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignal; - -/** - * The TMF Core tracer, used to trace TMF internal components. - *

- * The tracing classes are independently controlled (i.e no implicit inclusion) - * from the launch configuration's Tracing. The resulting trace is stored in a - * distinct file (TmfTrace.log) in a format that can later be analyzed by TMF. - *

- * The tracing classes are: - *

    - *
  • Component: TMF components life-cycle - *
  • Request: TMF requests life-cycle - *
  • Signal: TMF signals triggering and distribution - *
  • Event: TMF trace events - *
- * - * @version 1.0 - * @author Francois Chouinard - */ -@SuppressWarnings("nls") -public class TmfCoreTracer { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - private static final String PLUGIN_ID = Activator.PLUGIN_ID; - - // Tracing keys (in .options) - private static final String COMPONENT_TRACE_KEY = PLUGIN_ID + "/component"; - private static final String REQUEST_TRACE_KEY = PLUGIN_ID + "/request"; - private static final String SIGNAL_TRACE_KEY = PLUGIN_ID + "/signal"; - private static final String EVENT_TRACE_KEY = PLUGIN_ID + "/event"; - - private static final String TRACE_FILE_NAME = "TmfTrace.log"; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // Classes tracing flags - static boolean COMPONENT_CLASS_ENABLED = false; - static boolean REQUEST_CLASS_ENABLED = false; - static boolean SIGNAL_CLASS_ENABLED = false; - static boolean EVENT_CLASS_ENABLED = false; - - // Trace log file - private static BufferedWriter fTraceFile; - - // ------------------------------------------------------------------------ - // Start/stop tracing - controlled by the plug-in - // ------------------------------------------------------------------------ - - /** - * Set the tracing flags according to the launch configuration - */ - public static void init() { - - String traceKey; - boolean isTracing = false; - - traceKey = Platform.getDebugOption(COMPONENT_TRACE_KEY); - if (traceKey != null) { - COMPONENT_CLASS_ENABLED = (Boolean.valueOf(traceKey)).booleanValue(); - isTracing |= COMPONENT_CLASS_ENABLED; - } - - traceKey = Platform.getDebugOption(REQUEST_TRACE_KEY); - if (traceKey != null) { - REQUEST_CLASS_ENABLED = (Boolean.valueOf(traceKey)).booleanValue(); - isTracing |= REQUEST_CLASS_ENABLED; - } - - traceKey = Platform.getDebugOption(SIGNAL_TRACE_KEY); - if (traceKey != null) { - SIGNAL_CLASS_ENABLED = (Boolean.valueOf(traceKey)).booleanValue(); - isTracing |= SIGNAL_CLASS_ENABLED; - } - - traceKey = Platform.getDebugOption(EVENT_TRACE_KEY); - if (traceKey != null) { - EVENT_CLASS_ENABLED = (Boolean.valueOf(traceKey)).booleanValue(); - isTracing |= EVENT_CLASS_ENABLED; - } - - // Create trace log file if any of the flags was set - if (isTracing) { - try { - fTraceFile = new BufferedWriter(new FileWriter(TRACE_FILE_NAME)); - } catch (IOException e) { - Activator.logError("Error opening log file " + TRACE_FILE_NAME, e); - fTraceFile = null; - } - } - } - - /** - * Close the trace log file - */ - public static void stop() { - if (fTraceFile != null) { - try { - fTraceFile.close(); - fTraceFile = null; - } catch (IOException e) { - Activator.logError("Error closing log file", e); - } - } - } - - // ------------------------------------------------------------------------ - // Predicates - // ------------------------------------------------------------------------ - - @SuppressWarnings("javadoc") - public static boolean isComponentTraced() { - return COMPONENT_CLASS_ENABLED; - } - - @SuppressWarnings("javadoc") - public static boolean isRequestTraced() { - return REQUEST_CLASS_ENABLED; - } - - @SuppressWarnings("javadoc") - public static boolean isSignalTraced() { - return SIGNAL_CLASS_ENABLED; - } - - @SuppressWarnings("javadoc") - public static boolean isEventTraced() { - return EVENT_CLASS_ENABLED; - } - - // ------------------------------------------------------------------------ - // Tracing methods - // ------------------------------------------------------------------------ - - /** - * The central tracing method. Prepends the timestamp and the thread id - * to the trace message. - * - * @param msg the trace message to log - */ - public static synchronized void trace(String msg) { - // Leave when there is no place to write the message. - if (fTraceFile == null) { - return; - } - - // Set the timestamp (ms resolution) - long currentTime = System.currentTimeMillis(); - StringBuilder message = new StringBuilder("["); - message.append(currentTime / 1000); - message.append("."); - message.append(String.format("%1$03d", currentTime % 1000)); - message.append("] "); - - // Set the thread id - message.append("[TID="); - message.append(String.format("%1$03d", Thread.currentThread().getId())); - message.append("] "); - - // Append the trace message - message.append(msg); - - // Write to file - try { - fTraceFile.write(message.toString()); - fTraceFile.newLine(); - fTraceFile.flush(); - } catch (IOException e) { - Activator.logError("Error writing to log file", e); - } - } - - // ------------------------------------------------------------------------ - // TMF Core specific trace formatters - // ------------------------------------------------------------------------ - - @SuppressWarnings("javadoc") - public static void traceComponent(ITmfComponent component, String msg) { - if (COMPONENT_CLASS_ENABLED) { - String message = ("[CMP] Cmp=" + component.getName() + " " + msg); - trace(message); - } - } - - @SuppressWarnings("javadoc") - public static void traceRequest(ITmfEventRequest request, String msg) { - if (REQUEST_CLASS_ENABLED) { - String message = ("[REQ] Req=" + request.getRequestId() + " " + msg); - trace(message); - } - } - - @SuppressWarnings("javadoc") - public static void traceSignal(TmfSignal signal, String msg) { - if (SIGNAL_CLASS_ENABLED) { - String message = ("[SIG] Sig=" + signal.getClass().getSimpleName() - + " Target=" + msg); - trace(message); - } - } - - @SuppressWarnings("javadoc") - public static void traceEvent(ITmfEventProvider provider, ITmfEventRequest request, ITmfEvent event) { - if (EVENT_CLASS_ENABLED) { - String message = ("[EVT] Provider=" + provider.toString() - + ", Req=" + request.getRequestId() + ", Event=" + event.getTimestamp()); - trace(message); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/analysis/TmfAnalysisModuleSourceConfigElement.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/analysis/TmfAnalysisModuleSourceConfigElement.java deleted file mode 100644 index fd0b17c5ba..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/analysis/TmfAnalysisModuleSourceConfigElement.java +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.analysis; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; - -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.Platform; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleSource; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisModuleHelperConfigElement; - -/** - * Utility class for accessing TMF analysis module extensions from the - * platform's extensions registry. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public final class TmfAnalysisModuleSourceConfigElement implements IAnalysisModuleSource { - - /** Extension point ID */ - public static final String TMF_ANALYSIS_TYPE_ID = "org.eclipse.linuxtools.tmf.core.analysis"; //$NON-NLS-1$ - - /** Extension point element 'module' */ - public static final String MODULE_ELEM = "module"; //$NON-NLS-1$ - - /** Extension point element 'parameter' */ - public static final String PARAMETER_ELEM = "parameter"; //$NON-NLS-1$ - - /** Extension point attribute 'ID' */ - public static final String ID_ATTR = "id"; //$NON-NLS-1$ - - /** Extension point attribute 'name' */ - public static final String NAME_ATTR = "name"; //$NON-NLS-1$ - - /** Extension point attribute 'analysis_module' */ - public static final String ANALYSIS_MODULE_ATTR = "analysis_module"; //$NON-NLS-1$ - - /** Extension point attribute 'automatic' */ - public static final String AUTOMATIC_ATTR = "automatic"; //$NON-NLS-1$ - - /** Extension point attribute 'icon' */ - public static final String ICON_ATTR = "icon"; //$NON-NLS-1$ - - /** Extension point attribute 'default_value' */ - public static final String DEFAULT_VALUE_ATTR = "default_value"; //$NON-NLS-1$ - - /** Extension point element 'tracetype' */ - public static final String TRACETYPE_ELEM = "tracetype"; //$NON-NLS-1$ - - /** Extension point attribute 'class' */ - public static final String CLASS_ATTR = "class"; //$NON-NLS-1$ - - /** Extension point attribute 'applies' */ - public static final String APPLIES_ATTR = "applies"; //$NON-NLS-1$ - - /** - * The mapping of available analysis ID to their corresponding helper - */ - private final List fAnalysisHelpers = new ArrayList<>(); - - /** - * Retrieves all configuration elements from the platform extension registry - * for the analysis module extension. - * - * @return an array of analysis module configuration elements - */ - public static IConfigurationElement[] getTypeElements() { - IConfigurationElement[] elements = - Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_ANALYSIS_TYPE_ID); - List typeElements = new LinkedList<>(); - for (IConfigurationElement element : elements) { - if (element.getName().equals(MODULE_ELEM)) { - typeElements.add(element); - } - } - return typeElements.toArray(new IConfigurationElement[typeElements.size()]); - } - - /** - * Constructor - */ - public TmfAnalysisModuleSourceConfigElement() { - populateAnalysisList(); - } - - @Override - public Iterable getAnalysisModules() { - return fAnalysisHelpers; - } - - private void populateAnalysisList() { - if (fAnalysisHelpers.isEmpty()) { - // Populate the analysis module list - IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_ANALYSIS_TYPE_ID); - for (IConfigurationElement ce : config) { - String elementName = ce.getName(); - if (elementName.equals(TmfAnalysisModuleSourceConfigElement.MODULE_ELEM)) { - fAnalysisHelpers.add(new TmfAnalysisModuleHelperConfigElement(ce)); - } - } - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/analysis/TmfAnalysisModuleSources.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/analysis/TmfAnalysisModuleSources.java deleted file mode 100644 index 90f01c8b84..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/analysis/TmfAnalysisModuleSources.java +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.analysis; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.InvalidRegistryObjectException; -import org.eclipse.core.runtime.Platform; -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleSource; - -/** - * Utility class for accessing TMF analysis module extensions from the - * platform's extensions registry and returning the module sources. - * - * @author Geneviève Bastien - */ -public final class TmfAnalysisModuleSources { - - /** Extension point ID */ - public static final String TMF_ANALYSIS_TYPE_ID = "org.eclipse.linuxtools.tmf.core.analysis"; //$NON-NLS-1$ - - /** Extension point element 'module' */ - public static final String SOURCE_ELEM = "source"; //$NON-NLS-1$ - - /** Extension point attribute 'class' */ - public static final String CLASS_ATTR = "class"; //$NON-NLS-1$ - - private TmfAnalysisModuleSources() { - - } - - /** - * Return the analysis module sources advertised in the extension - * point, in iterable format. - * - * @return List of {@link IAnalysisModuleSource} - */ - public static Iterable getSources() { - List sources = new ArrayList<>(); - // Get the sources element from the extension point - IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_ANALYSIS_TYPE_ID); - for (IConfigurationElement ce : config) { - String elementName = ce.getName(); - if (elementName.equals(SOURCE_ELEM)) { - try { - IAnalysisModuleSource source = (IAnalysisModuleSource) ce.createExecutableExtension(CLASS_ATTR); - sources.add(source); - } catch (InvalidRegistryObjectException e) { - Activator.logError("Error creating module source", e); //$NON-NLS-1$ - } catch (CoreException e) { - Activator.logError("Error creating module source", e); //$NON-NLS-1$ - } - - } - } - return sources; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/component/TmfEventThread.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/component/TmfEventThread.java deleted file mode 100644 index f15ebed8a8..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/component/TmfEventThread.java +++ /dev/null @@ -1,253 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Update handling of suspend and resume - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.component; - -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.internal.tmf.core.TmfCoreTracer; -import org.eclipse.linuxtools.tmf.core.component.ITmfEventProvider; -import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest.ExecutionType; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; - -/** - * Provides the core event request processor. It also has support for suspending - * and resuming a request in a thread-safe manner. - * - * @author Francois Chouinard - * @version 1.0 - */ -public class TmfEventThread implements Runnable { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The event provider - */ - private final TmfEventProvider fProvider; - - /** - * The wrapped event request - */ - private final ITmfEventRequest fRequest; - - /** - * The request execution priority - */ - private final ExecutionType fExecType; - - /** - * The wrapped thread (if applicable) - */ - private final TmfEventThread fThread; - - /** - * The thread execution state - */ - private volatile boolean isCompleted = false; - - /** The synchronization object */ - private final Object fSynchObject = new Object(); - - /** The flag for suspending a thread */ - private volatile boolean fIsPaused = false; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Basic constructor - * - * @param provider the event provider - * @param request the request to process - */ - public TmfEventThread(TmfEventProvider provider, ITmfEventRequest request) { - assert provider != null; - assert request != null; - fProvider = provider; - fRequest = request; - fExecType = request.getExecType(); - fThread = null; - } - - /** - * Wrapper constructor - * - * @param thread the thread to wrap - */ - public TmfEventThread(TmfEventThread thread) { - fProvider = thread.fProvider; - fRequest = thread.fRequest; - fExecType = thread.fExecType; - fThread = thread; - } - - // ------------------------------------------------------------------------ - // Getters - // ------------------------------------------------------------------------ - - /** - * @return The wrapped thread - */ - public TmfEventThread getThread() { - return fThread; - } - - /** - * @return The event provider - */ - public ITmfEventProvider getProvider() { - return fProvider; - } - - /** - * @return The event request - */ - public ITmfEventRequest getRequest() { - return fRequest; - } - - /** - * @return The request execution priority - */ - public ExecutionType getExecType() { - return fExecType; - } - - /** - * @return The request execution state - */ - public boolean isRunning() { - return fRequest.isRunning() && !isPaused(); - } - - /** - * @return The request execution state - */ - public boolean isPaused() { - return fIsPaused; - } - - /** - * @return The request execution state - */ - public boolean isCompleted() { - return isCompleted; - } - - // ------------------------------------------------------------------------ - // Runnable - // ------------------------------------------------------------------------ - - @Override - public void run() { - - TmfCoreTracer.traceRequest(fRequest, "is being serviced by " + fProvider.getName()); //$NON-NLS-1$ - - // Extract the generic information - fRequest.start(); - int nbRequested = fRequest.getNbRequested(); - int nbRead = 0; - isCompleted = false; - - // Initialize the execution - ITmfContext context = fProvider.armRequest(fRequest); - if (context == null) { - fRequest.cancel(); - return; - } - - try { - // Get the ordered events - ITmfEvent event = fProvider.getNext(context); - TmfCoreTracer.traceRequest(fRequest, "read first event"); //$NON-NLS-1$ - - while (event != null && !fProvider.isCompleted(fRequest, event, nbRead)) { - - TmfCoreTracer.traceEvent(fProvider, fRequest, event); - if (fRequest.getDataType().isInstance(event)) { - fRequest.handleData(event); - } - - // Pause execution if requested - - while (fIsPaused) { - synchronized (fSynchObject) { - try { - fSynchObject.wait(); - } catch (InterruptedException e) { - // continue - } - } - } - - // To avoid an unnecessary read passed the last event requested - if (++nbRead < nbRequested) { - event = fProvider.getNext(context); - } - } - - isCompleted = true; - - if (fRequest.isCancelled()) { - fRequest.cancel(); - } else { - fRequest.done(); - } - - } catch (Exception e) { - Activator.logError("Error in " + fProvider.getName() + " handling " + fRequest, e); //$NON-NLS-1$ //$NON-NLS-2$ - fRequest.fail(); - } - - // Cleanup - context.dispose(); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Suspend the thread - */ - public void suspend() { - fIsPaused = true; - TmfCoreTracer.traceRequest(fRequest, "SUSPENDED"); //$NON-NLS-1$ - } - - /** - * Resume the thread - */ - public void resume() { - fIsPaused = false; - synchronized (fSynchObject) { - fSynchObject.notifyAll(); - } - TmfCoreTracer.traceRequest(fRequest, "RESUMED"); //$NON-NLS-1$ - } - - /** - * Cancel the request - */ - public void cancel() { - if (!fRequest.isCompleted()) { - fRequest.cancel(); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/component/TmfProviderManager.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/component/TmfProviderManager.java deleted file mode 100644 index aeee0352cb..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/component/TmfProviderManager.java +++ /dev/null @@ -1,122 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.component; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; - -/** - * Singleton that keeps track of the event providers. - * - * @version 1.0 - * @author Francois Chouinard - */ -public class TmfProviderManager { - - // ------------------------------------------------------------------------ - // No constructor - // ------------------------------------------------------------------------ - - private TmfProviderManager() { - } - - // ------------------------------------------------------------------------ - // Keeps track of the providers for each event type - // ------------------------------------------------------------------------ - - private static Map, List> fProviders = - new HashMap<>(); - - /** - * Registers [provider] as a provider of [eventType] - * - * @param eventType - * The event type - * @param provider - * The data provider - */ - public static void register(Class eventType, TmfEventProvider provider) { - if (fProviders.get(eventType) == null) { - fProviders.put(eventType, new ArrayList()); - } - fProviders.get(eventType).add(provider); - } - - /** - * Re-registers [provider] as a provider of [eventType] - * - * @param eventType - * The event type - * @param provider - * The data provider - */ - public static void deregister(Class eventType, TmfEventProvider provider) { - List list = fProviders.get(eventType); - if (list != null) { - list.remove(provider); - if (list.size() == 0) { - fProviders.remove(eventType); - } - } - } - - /** - * Returns the list of components that provide [eventType] - * - * @param eventType - * The event type - * @return the list of components that provide [eventType] - */ - public static TmfEventProvider[] getProviders(Class eventType) { - List list = fProviders.get(eventType); - if (list == null) { - list = new ArrayList<>(); - } - TmfEventProvider[] result = new TmfEventProvider[list.size()]; - return list.toArray(result); - } - - /** - * Returns the list of components of type [providerType] that provide - * [eventType] - * - * @param eventType - * The event type - * @param providerType - * The data provider - * @return the list of components of type [providerType] that provide - * [eventType] - */ - public static TmfEventProvider[] getProviders(Class eventType, Class providerType) { - if (providerType == null) { - return getProviders(eventType); - } - TmfEventProvider[] list = getProviders(eventType); - List result = new ArrayList<>(); - if (list != null) { - for (TmfEventProvider provider : list) { - if (provider.getClass() == providerType) { - result.add(provider); - } - } - } - TmfEventProvider[] array = new TmfEventProvider[result.size()]; - return result.toArray(array); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/filter/TmfCollapseFilter.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/filter/TmfCollapseFilter.java deleted file mode 100644 index 66dbae0254..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/filter/TmfCollapseFilter.java +++ /dev/null @@ -1,119 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.internal.tmf.core.filter; - -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.collapse.ITmfCollapsibleEvent; -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; - -/** - * Stateful filter that compares consecutive events for collapsing feature. - * - * Usage of this class in conjunction with other {@link ITmfFilterTreeNode} - * filters is not supported. Will throw {@link UnsupportedOperationException} - * in that case. - * - * @author Bernd Hufmann - */ -public class TmfCollapseFilter implements ITmfFilterTreeNode { - - private static final String COLLAPSE_NODE_NAME = "Collapse"; //$NON-NLS-1$ - - private ITmfCollapsibleEvent fPrevEvent = null; - - @Override - public boolean matches(ITmfEvent event) { - - if (fPrevEvent != null) { - if (event instanceof ITmfCollapsibleEvent) { - boolean isCollapsible = fPrevEvent.isCollapsibleWith(event); - fPrevEvent = (ITmfCollapsibleEvent) event; - if (isCollapsible) { - return false; - } - } else { - fPrevEvent = null; - } - } else { - if (event instanceof ITmfCollapsibleEvent) { - fPrevEvent = (ITmfCollapsibleEvent) event; - } - } - return true; - } - - @Override - public ITmfFilterTreeNode getParent() { - return null; - } - - @Override - public String getNodeName() { - return COLLAPSE_NODE_NAME; - } - - @Override - public boolean hasChildren() { - return false; - } - - @Override - public int getChildrenCount() { - return 0; - } - - @Override - public ITmfFilterTreeNode[] getChildren() { - return new ITmfFilterTreeNode[0]; - } - - @Override - public ITmfFilterTreeNode getChild(int index) { - throw new UnsupportedOperationException(); - } - - @Override - public ITmfFilterTreeNode remove() { - throw new UnsupportedOperationException(); - } - - @Override - public ITmfFilterTreeNode removeChild(ITmfFilterTreeNode node) { - throw new UnsupportedOperationException(); - } - - @Override - public int addChild(ITmfFilterTreeNode node) { - throw new UnsupportedOperationException(); - } - - @Override - public ITmfFilterTreeNode replaceChild(int index, ITmfFilterTreeNode node) { - throw new UnsupportedOperationException(); - } - - @Override - public void setParent(ITmfFilterTreeNode parent) { - } - - @Override - public List getValidChildren() { - throw new UnsupportedOperationException(); - } - - @Override - public ITmfFilterTreeNode clone() { - return new TmfCollapseFilter(); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/messages.properties b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/messages.properties deleted file mode 100644 index ef096a387b..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/messages.properties +++ /dev/null @@ -1,14 +0,0 @@ -############################################################################### -# Copyright (c) 2013 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### - -TmfCheckpointIndexer_EventsPerSecond=events/s -TmfCheckpointIndexer_Indexing=Indexing diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/request/TmfCoalescedEventRequest.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/request/TmfCoalescedEventRequest.java deleted file mode 100644 index 33d54cd7de..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/request/TmfCoalescedEventRequest.java +++ /dev/null @@ -1,321 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Alexandre Montplaisir - Merge with TmfCoalescedDataRequest - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.request; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.linuxtools.internal.tmf.core.TmfCoreTracer; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; - -/** - * The TMF coalesced event request - * - * @author Francois Chouinard - * @since 3.0 - */ -public class TmfCoalescedEventRequest extends TmfEventRequest { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** The list of coalesced requests */ - private final List fRequests = new ArrayList<>(); - - /** - * We do not use super.fRange, because in the case of coalesced requests, - * the global range can be modified as sub-request are added. - */ - private TmfTimeRange fRange; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Request 'n' events of a given type for the given time range (given - * priority). Events are returned in blocks of the given size. - * - * @param dataType - * The requested data type - * @param range - * The range of the request. You can use - * {@link TmfTimeRange#ETERNITY} to request all events. - * @param index - * The index of the first event to retrieve. Use '0' to start at - * the beginning. - * @param nbRequested - * The number of events requested. You can use - * {@link TmfEventRequest#ALL_DATA} to request all events. - * @param priority - * The requested execution priority - */ - public TmfCoalescedEventRequest(Class dataType, - TmfTimeRange range, - long index, - int nbRequested, - ExecutionType priority) { - super(ITmfEvent.class, null, index, nbRequested, priority); - fRange = range; - - if (TmfCoreTracer.isRequestTraced()) { - String type = getClass().getName(); - type = type.substring(type.lastIndexOf('.') + 1); - @SuppressWarnings("nls") - String message = "CREATED " - + (getExecType() == ITmfEventRequest.ExecutionType.BACKGROUND ? "(BG)" : "(FG)") - + " Type=" + type + " Index=" + getIndex() + " NbReq=" + getNbRequested() - + " Range=" + getRange() - + " DataType=" + getDataType().getSimpleName(); - TmfCoreTracer.traceRequest(this, message); - } - } - - @Override - public TmfTimeRange getRange() { - return fRange; - } - - // ------------------------------------------------------------------------ - // Management - // ------------------------------------------------------------------------ - - /** - * Add a request to this one. - * - * @param request - * The request to add - */ - public void addRequest(ITmfEventRequest request) { - fRequests.add(request); - merge(request); - } - - /** - * Check if a request is compatible with the current coalesced one - * - * @param request - * The request to verify - * @return If the request is compatible, true or false - */ - public boolean isCompatible(ITmfEventRequest request) { - if (request.getExecType() == getExecType() && - ranksOverlap(request) && - timeRangesOverlap(request)) { - return true; - } - return false; - } - - private boolean ranksOverlap(ITmfEventRequest request) { - long start = request.getIndex(); - long end = start + request.getNbRequested(); - - // Return true if either the start or end index falls within - // the coalesced request boundaries - return (start <= (fIndex + fNbRequested + 1) && (end >= fIndex - 1)); - } - - private boolean timeRangesOverlap(ITmfEventRequest request) { - ITmfTimestamp startTime = request.getRange().getStartTime(); - ITmfTimestamp endTime = request.getRange().getEndTime(); - return (startTime.compareTo(endTime) <= 0) && - (fRange.getStartTime().compareTo(fRange.getEndTime()) <= 0); - } - - private void merge(ITmfEventRequest request) { - long start = request.getIndex(); - long end = Math.min(start + request.getNbRequested(), ITmfEventRequest.ALL_DATA); - - if (start < fIndex) { - if (fNbRequested != ITmfEventRequest.ALL_DATA) { - fNbRequested += (fIndex - start); - } - fIndex = start; - } - if ((request.getNbRequested() == ITmfEventRequest.ALL_DATA) || - (fNbRequested == ITmfEventRequest.ALL_DATA)) { - fNbRequested = ITmfEventRequest.ALL_DATA; - } else { - fNbRequested = (int) Math.max(end - fIndex, fNbRequested); - } - - ITmfTimestamp startTime = request.getRange().getStartTime(); - ITmfTimestamp endTime = request.getRange().getEndTime(); - if (!fRange.contains(startTime) && fRange.getStartTime().compareTo(startTime) > 0) { - fRange = new TmfTimeRange(startTime, fRange.getEndTime()); - } - if (!fRange.contains(endTime) && fRange.getEndTime().compareTo(endTime) < 0) { - fRange = new TmfTimeRange(fRange.getStartTime(), endTime); - } - } - - /** - * @return The list of IDs of the sub-requests - */ - @SuppressWarnings("nls") - public String getSubRequestIds() { - StringBuffer result = new StringBuffer("["); - for (int i = 0; i < fRequests.size(); i++) { - if (i != 0) { - result.append(", "); - } - result.append(fRequests.get(i).getRequestId()); - } - result.append("]"); - return result.toString(); - } - - // ------------------------------------------------------------------------ - // ITmfEventRequest - // ------------------------------------------------------------------------ - - @Override - public void handleData(ITmfEvent data) { - super.handleData(data); - long index = getIndex() + getNbRead() - 1; - for (ITmfEventRequest request : fRequests) { - long start = request.getIndex(); - if (!request.isCompleted() && index >= start && request.getNbRead() < request.getNbRequested()) { - ITmfTimestamp ts = data.getTimestamp(); - if (request.getRange().contains(ts)) { - if (request.getDataType().isInstance(data)) { - request.handleData(data); - } - } - } - } - } - - @Override - public void start() { - for (ITmfEventRequest request : fRequests) { - if (!request.isCompleted()) { - request.start(); - } - } - super.start(); - } - - @Override - public void done() { - for (ITmfEventRequest request : fRequests) { - if (!request.isCompleted()) { - request.done(); - } - } - super.done(); - } - - @Override - public void fail() { - for (ITmfEventRequest request : fRequests) { - request.fail(); - } - super.fail(); - } - - @Override - public void cancel() { - for (ITmfEventRequest request : fRequests) { - if (!request.isCompleted()) { - request.cancel(); - } - } - super.cancel(); - } - - @Override - public synchronized boolean isCompleted() { - // Firstly, check if coalescing request is completed - if (super.isCompleted()) { - return true; - } - - // Secondly, check if all sub-requests are finished - if (fRequests.size() > 0) { - // If all sub requests are completed the coalesced request is - // treated as completed, too. - for (ITmfEventRequest request : fRequests) { - if (!request.isCompleted()) { - return false; - } - } - return true; - } - - // Coalescing request is not finished if there are no sub-requests - return false; - } - - @Override - public synchronized boolean isCancelled() { - // Firstly, check if coalescing request is canceled - if (super.isCancelled()) { - return true; - } - - // Secondly, check if all sub-requests are canceled - if (fRequests.size() > 0) { - // If all sub requests are canceled the coalesced request is - // treated as completed, too. - for (ITmfEventRequest request : fRequests) { - if (!request.isCancelled()) { - return false; - } - } - return true; - } - - // Coalescing request is not canceled if there are no sub-requests - return false; - - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - // All requests have a unique id - public int hashCode() { - return super.hashCode(); - } - - @Override - public boolean equals(Object other) { - if (other instanceof TmfCoalescedEventRequest) { - TmfCoalescedEventRequest request = (TmfCoalescedEventRequest) other; - return (request.getDataType() == getDataType()) && - (request.getIndex() == getIndex()) && - (request.getNbRequested() == getNbRequested()) && - (request.getRange().equals(fRange)); - } - return false; - } - - @Override - @SuppressWarnings("nls") - public String toString() { - return "[TmfCoalescedEventRequest(" + getRequestId() + "," + getDataType().getSimpleName() - + "," + getExecType() + "," + getRange() + "," + getIndex() + "," + getNbRequested() - + ", " + fRequests.toString() + ")]"; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/request/TmfRequestExecutor.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/request/TmfRequestExecutor.java deleted file mode 100644 index a232cabcb2..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/request/TmfRequestExecutor.java +++ /dev/null @@ -1,308 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Added support for pre-emption - * Simon Delisle - Added scheduler for requests - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.request; - -import java.util.Queue; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.Executor; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import org.eclipse.linuxtools.internal.tmf.core.TmfCoreTracer; -import org.eclipse.linuxtools.internal.tmf.core.component.TmfEventThread; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest.ExecutionType; - -/** - * The request scheduler works with 5 slots with a specific time. It has 4 slots - * for foreground requests and 1 slot for background requests, and it passes - * through all the slots (foreground first and background after). - * - * Example: if we have one foreground and one background request, the foreground - * request will be executed four times more often than the background request. - * - * @author Francois Chouinard - * @author Simon Delisle - * @version 1.1 - */ -public class TmfRequestExecutor implements Executor { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - private static final long REQUEST_TIME = 100; - private static final int FOREGROUND_SLOT = 4; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // The request executor - private final ExecutorService fExecutor = Executors.newCachedThreadPool(); - private final String fExecutorName; - - // The request queues - private final Queue fForegroundTasks = new ArrayBlockingQueue<>(10); - private final Queue fBackgroundTasks = new ArrayBlockingQueue<>(10); - - // The tasks - private TmfEventThread fActiveTask; - - private Timer fTimer; - private TimerTask fTimerTask; - - private int fForegroundCycle = 0; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - public TmfRequestExecutor() { - String canonicalName = fExecutor.getClass().getCanonicalName(); - fExecutorName = canonicalName.substring(canonicalName.lastIndexOf('.') + 1); - if (TmfCoreTracer.isComponentTraced()) { - TmfCoreTracer.trace(fExecutor + " created"); //$NON-NLS-1$ - } - } - - // ------------------------------------------------------------------------ - // Getters - // ------------------------------------------------------------------------ - - /** - * @return the shutdown state (i.e. if it is accepting new requests) - */ - public boolean isShutdown() { - return fExecutor.isShutdown(); - } - - /** - * @return the termination state - */ - public boolean isTerminated() { - return fExecutor.isTerminated(); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Initialize the executor - */ - public void init() { - if (fTimer != null) { - return; - } - // Initialize the timer for the schedSwitch - fTimerTask = new SchedSwitch(); - fTimer = new Timer(true); - fTimer.schedule(fTimerTask, 0, REQUEST_TIME); - } - - @Override - public synchronized void execute(final Runnable command) { - - // We are expecting MyEventThread:s - if (!(command instanceof TmfEventThread)) { - // TODO: Log an error - return; - } - - // Wrap the thread in a MyThread - TmfEventThread thread = (TmfEventThread) command; - TmfEventThread wrapper = new TmfEventThread(thread) { - @Override - public void run() { - try { - command.run(); - } finally { - scheduleNext(); - } - } - }; - - // Add the thread to the appropriate queue - ExecutionType priority = thread.getExecType(); - - if (priority == ExecutionType.FOREGROUND) { - if (!fForegroundTasks.offer(wrapper)) { - wrapper.cancel(); - } - } else { - if (!fBackgroundTasks.offer(wrapper)) { - wrapper.cancel(); - } - } - } - - /** - * Timer task to trigger scheduleNext() - */ - private class SchedSwitch extends TimerTask { - - SchedSwitch() { - } - - @Override - public void run() { - scheduleNext(); - } - } - - /** - * Executes the next pending request, if applicable. - */ - protected synchronized void scheduleNext() { - if (!isShutdown()) { - if (fActiveTask == null) { - schedule(); - } else if (fActiveTask.getExecType() == ExecutionType.FOREGROUND) { - if (fActiveTask.getThread().isCompleted()) { - fActiveTask = null; - schedule(); - } else { - if (hasTasks()) { - fActiveTask.getThread().suspend(); - if (!fForegroundTasks.offer(fActiveTask)) { - fActiveTask.cancel(); - fActiveTask = null; - } - schedule(); - } - } - - } else if (fActiveTask.getExecType() == ExecutionType.BACKGROUND) { - if (fActiveTask.getThread().isCompleted()) { - fActiveTask = null; - schedule(); - } else { - if (hasTasks()) { - fActiveTask.getThread().suspend(); - if (!fBackgroundTasks.offer(fActiveTask)) { - fActiveTask.cancel(); - fActiveTask = null; - } - schedule(); - } - } - } - } - } - - /** - * Stops the executor - */ - public synchronized void stop() { - if (fTimerTask != null) { - fTimerTask.cancel(); - } - - if (fTimer != null) { - fTimer.cancel(); - } - - if (fActiveTask != null) { - fActiveTask.cancel(); - } - - while ((fActiveTask = fForegroundTasks.poll()) != null) { - fActiveTask.cancel(); - } - while ((fActiveTask = fBackgroundTasks.poll()) != null) { - fActiveTask.cancel(); - } - - fExecutor.shutdown(); - if (TmfCoreTracer.isComponentTraced()) { - TmfCoreTracer.trace(fExecutor + " terminated"); //$NON-NLS-1$ - } - } - - // ------------------------------------------------------------------------ - // Helper methods - // ------------------------------------------------------------------------ - - /** - * Determine which type of request (foreground or background) we schedule - * next - */ - private void schedule() { - if (!fForegroundTasks.isEmpty()) { - scheduleNextForeground(); - } else { - scheduleNextBackground(); - } - } - - /** - * Schedule the next foreground request - */ - private void scheduleNextForeground() { - if (fForegroundCycle < FOREGROUND_SLOT || fBackgroundTasks.isEmpty()) { - ++fForegroundCycle; - fActiveTask = fForegroundTasks.poll(); - executefActiveTask(); - } else { - fActiveTask = null; - scheduleNextBackground(); - } - } - - /** - * Schedule the next background request - */ - private void scheduleNextBackground() { - fForegroundCycle = 0; - if (!fBackgroundTasks.isEmpty()) { - fActiveTask = fBackgroundTasks.poll(); - executefActiveTask(); - } - } - - /** - * Execute or resume the active task - */ - private void executefActiveTask() { - if (fActiveTask.getThread().isPaused()) { - fActiveTask.getThread().resume(); - } else { - fExecutor.execute(fActiveTask); - } - } - - /** - * Check if the scheduler has tasks - */ - private boolean hasTasks() { - return !(fForegroundTasks.isEmpty() && fBackgroundTasks.isEmpty()); - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - @SuppressWarnings("nls") - public String toString() { - return "[TmfRequestExecutor(" + fExecutorName + ")]"; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/backends/partial/PartialHistoryBackend.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/backends/partial/PartialHistoryBackend.java deleted file mode 100644 index f225edeb52..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/backends/partial/PartialHistoryBackend.java +++ /dev/null @@ -1,365 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.partial; - -import java.io.File; -import java.io.FileInputStream; -import java.io.PrintWriter; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import java.util.concurrent.CountDownLatch; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.statesystem.core.backend.IStateHistoryBackend; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; -import org.eclipse.linuxtools.statesystem.core.interval.TmfStateInterval; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.statesystem.AbstractTmfStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateProvider; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Partial state history back-end. - * - * This is a shim inserted between the real state system and a "real" history - * back-end. It will keep checkpoints, every n trace events (where n is called - * the granularity) and will only forward to the real state history the state - * intervals that crosses at least one checkpoint. Every other interval will - * be discarded. - * - * This would mean that it can only answer queries exactly at the checkpoints. - * For any other timestamps (ie, most of the time), it will load the closest - * earlier checkpoint, and will re-feed the state-change-input with events from - * the trace, to restore the real state at the time that was requested. - * - * @author Alexandre Montplaisir - */ -public class PartialHistoryBackend implements IStateHistoryBackend { - - /** - * A partial history needs the state input plugin to re-generate state - * between checkpoints. - */ - private final @NonNull ITmfStateProvider partialInput; - - /** - * Fake state system that is used for partially rebuilding the states (when - * going from a checkpoint to a target query timestamp). - */ - private final @NonNull PartialStateSystem partialSS; - - /** Reference to the "real" state history that is used for storage */ - private final @NonNull IStateHistoryBackend innerHistory; - - /** Checkpoints map, */ - private final @NonNull TreeMap checkpoints = new TreeMap<>(); - - /** Latch tracking if the initial checkpoint registration is done */ - private final @NonNull CountDownLatch checkpointsReady = new CountDownLatch(1); - - private final long granularity; - - private long latestTime; - - /** - * Constructor - * - * @param partialInput - * The state change input object that was used to build the - * upstream state system. This partial history will make its own - * copy (since they have different targets). - * @param pss - * The partial history's inner state system. It should already be - * assigned to partialInput. - * @param realBackend - * The real state history back-end to use. It's supposed to be - * modular, so it should be able to be of any type. - * @param granularity - * Configuration parameter indicating how many trace events there - * should be between each checkpoint - */ - public PartialHistoryBackend(ITmfStateProvider partialInput, PartialStateSystem pss, - IStateHistoryBackend realBackend, long granularity) { - if (granularity <= 0 || partialInput == null || pss == null || - partialInput.getAssignedStateSystem() != pss) { - throw new IllegalArgumentException(); - } - - final long startTime = realBackend.getStartTime(); - - this.partialInput = partialInput; - this.partialSS = pss; - - this.innerHistory = realBackend; - this.granularity = granularity; - - latestTime = startTime; - - registerCheckpoints(); - } - - private void registerCheckpoints() { - ITmfEventRequest request = new CheckpointsRequest(partialInput, checkpoints); - partialInput.getTrace().sendRequest(request); - /* The request will countDown the checkpoints latch once it's finished */ - } - - @Override - public long getStartTime() { - return innerHistory.getStartTime(); - } - - @Override - public long getEndTime() { - return latestTime; - } - - @Override - public void insertPastState(long stateStartTime, long stateEndTime, - int quark, ITmfStateValue value) throws TimeRangeException { - waitForCheckpoints(); - - /* Update the latest time */ - if (stateEndTime > latestTime) { - latestTime = stateEndTime; - } - - /* - * Check if the interval intersects the previous checkpoint. If so, - * insert it in the real history back-end. - * - * FIXME since intervals are inserted in order of rank, we could avoid - * doing a map lookup every time here (just compare with the known - * previous one). - */ - if (stateStartTime <= checkpoints.floorKey(stateEndTime)) { - innerHistory.insertPastState(stateStartTime, stateEndTime, quark, value); - } - } - - @Override - public void finishedBuilding(long endTime) throws TimeRangeException { - innerHistory.finishedBuilding(endTime); - } - - @Override - public FileInputStream supplyAttributeTreeReader() { - return innerHistory.supplyAttributeTreeReader(); - } - - @Override - public File supplyAttributeTreeWriterFile() { - return innerHistory.supplyAttributeTreeWriterFile(); - } - - @Override - public long supplyAttributeTreeWriterFilePosition() { - return innerHistory.supplyAttributeTreeWriterFilePosition(); - } - - @Override - public void removeFiles() { - innerHistory.removeFiles(); - } - - @Override - public void dispose() { - partialInput.dispose(); - partialSS.dispose(); - innerHistory.dispose(); - } - - @Override - public void doQuery(List currentStateInfo, long t) - throws TimeRangeException, StateSystemDisposedException { - /* Wait for required steps to be done */ - waitForCheckpoints(); - partialSS.getUpstreamSS().waitUntilBuilt(); - - if (!checkValidTime(t)) { - throw new TimeRangeException(); - } - - /* Reload the previous checkpoint */ - long checkpointTime = checkpoints.floorKey(t); - innerHistory.doQuery(currentStateInfo, checkpointTime); - - /* - * Set the initial contents of the partial state system (which is the - * contents of the query at the checkpoint). - */ - partialSS.takeQueryLock(); - partialSS.replaceOngoingState(currentStateInfo); - - /* Send an event request to update the state system to the target time. */ - TmfTimeRange range = new TmfTimeRange( - /* - * The state at the checkpoint already includes any state change - * caused by the event(s) happening exactly at 'checkpointTime', - * if any. We must not include those events in the query. - */ - new TmfTimestamp(checkpointTime + 1, ITmfTimestamp.NANOSECOND_SCALE), - new TmfTimestamp(t, ITmfTimestamp.NANOSECOND_SCALE)); - ITmfEventRequest request = new PartialStateSystemRequest(partialInput, range); - partialInput.getTrace().sendRequest(request); - - try { - request.waitForCompletion(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - /* - * Now the partial state system should have the ongoing time we are - * looking for. However, the method expects a List of *state intervals*, - * not state values, so we'll create intervals with a dummy end time. - */ - try { - for (int i = 0; i < currentStateInfo.size(); i++) { - long start = 0; - ITmfStateValue val = null; - start = ((ITmfStateSystem) partialSS).getOngoingStartTime(i); - val = ((ITmfStateSystem) partialSS).queryOngoingState(i); - - ITmfStateInterval interval = new TmfStateInterval(start, t, i, val); - currentStateInfo.set(i, interval); - } - } catch (AttributeNotFoundException e) { - /* Should not happen, we iterate over existing values. */ - e.printStackTrace(); - } - - partialSS.releaseQueryLock(); - } - - /** - * Single queries are not supported in partial histories. To get the same - * result you can do a full query, then call fullState.get(attribute). - */ - @Override - public ITmfStateInterval doSingularQuery(long t, int attributeQuark) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean checkValidTime(long t) { - return (t >= getStartTime() && t <= getEndTime()); - } - - @Override - public void debugPrint(PrintWriter writer) { - // TODO Auto-generated method stub - } - - private void waitForCheckpoints() { - try { - checkpointsReady.await(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - // ------------------------------------------------------------------------ - // Event requests types - // ------------------------------------------------------------------------ - - private class CheckpointsRequest extends TmfEventRequest { - private final ITmfTrace trace; - private final Map checkpts; - private long eventCount; - private long lastCheckpointAt; - - public CheckpointsRequest(ITmfStateProvider input, Map checkpoints) { - super(input.getExpectedEventType(), - TmfTimeRange.ETERNITY, - 0, - ITmfEventRequest.ALL_DATA, - ITmfEventRequest.ExecutionType.FOREGROUND); - checkpoints.clear(); - this.trace = input.getTrace(); - this.checkpts = checkpoints; - eventCount = 0; - lastCheckpointAt = 0; - - /* Insert a checkpoint at the start of the trace */ - checkpoints.put(input.getStartTime(), 0L); - } - - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - if (event.getTrace() == trace) { - eventCount++; - - /* Check if we need to register a new checkpoint */ - if (eventCount >= lastCheckpointAt + granularity) { - checkpts.put(event.getTimestamp().getValue(), eventCount); - lastCheckpointAt = eventCount; - } - } - } - - @Override - public void handleCompleted() { - super.handleCompleted(); - checkpointsReady.countDown(); - } - } - - private class PartialStateSystemRequest extends TmfEventRequest { - private final ITmfStateProvider sci; - private final ITmfTrace trace; - - PartialStateSystemRequest(ITmfStateProvider sci, TmfTimeRange range) { - super(sci.getExpectedEventType(), - range, - 0, - ITmfEventRequest.ALL_DATA, - ITmfEventRequest.ExecutionType.BACKGROUND); - this.sci = sci; - this.trace = sci.getTrace(); - } - - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - if (event.getTrace() == trace) { - sci.processEvent(event); - } - } - - @Override - public void handleCompleted() { - /* - * If we're using a threaded state provider, we need to make sure - * all events have been handled by the state system before doing - * queries on it. - */ - if (partialInput instanceof AbstractTmfStateProvider) { - ((AbstractTmfStateProvider) partialInput).waitForEmptyQueue(); - } - super.handleCompleted(); - } - - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/backends/partial/PartialStateSystem.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/backends/partial/PartialStateSystem.java deleted file mode 100644 index 1a7ede3f9a..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/backends/partial/PartialStateSystem.java +++ /dev/null @@ -1,162 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.partial; - -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import org.eclipse.linuxtools.internal.statesystem.core.AttributeTree; -import org.eclipse.linuxtools.internal.statesystem.core.StateSystem; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.statesystem.core.backend.NullBackend; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; - -/** - * State system interface-like extension to use with partial state histories. - * - * It mainly exposes the {@link #replaceOngoingState} method, which allows - * seeking the state system to a different point by updating its "ongoing" state - * values. - * - * @author Alexandre Montplaisir - */ -@SuppressWarnings("restriction") /* We're using AttributeTree directly */ -public class PartialStateSystem extends StateSystem { - - private static final String ERR_MSG = "Partial state system should not modify the attribute tree!"; //$NON-NLS-1$ - - private final CountDownLatch ssAssignedLatch = new CountDownLatch(1); - private final Lock queryLock = new ReentrantLock(); - - /** - * Reference to the real upstream state system. This is used so we can read - * its attribute tree. - */ - private StateSystem realStateSystem = null; - - /** - * Constructor - */ - public PartialStateSystem() { - /* - * We use a Null back end here : we only use this state system for its - * "ongoing" values, so no need to save the changes that are inserted. - */ - super("partial", new NullBackend()); //$NON-NLS-1$ - } - - /** - * Assign the upstream state system to this one. - * - * @param ss - * The real state system - */ - public void assignUpstream(StateSystem ss) { - realStateSystem = ss; - ssAssignedLatch.countDown(); - } - - ITmfStateSystem getUpstreamSS() { - return realStateSystem; - } - - // ------------------------------------------------------------------------ - // Publicized non-API methods - // ------------------------------------------------------------------------ - - @Override - public void replaceOngoingState(List ongoingIntervals) { - super.replaceOngoingState(ongoingIntervals); - } - - @Override - public synchronized void dispose() { - super.dispose(); - } - - // ------------------------------------------------------------------------ - // Methods regarding the query lock - // ------------------------------------------------------------------------ - - /** - * Take this inner state system's lock before doing a query. - * - * When doing queries, you should take the lock, then run - * {@link #replaceOngoingState}, then send events to its state provider - * input to cause state changes, and then call {@link #queryOngoingState} to - * get the states at the new "current time". - * - * Only after all that it would be safe to release the lock. - */ - public void takeQueryLock() { - try { - queryLock.lockInterruptibly(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - /** - * Release the query lock, when you are done with your query. - */ - public void releaseQueryLock() { - queryLock.unlock(); - } - - @Override - public AttributeTree getAttributeTree() { - waitUntilReady(); - return realStateSystem.getAttributeTree(); - } - - /* - * Override these methods to make sure we don't try to overwrite the - * "real" upstream attribute tree. - */ - - @Override - public void addEmptyAttribute() { - throw new RuntimeException(ERR_MSG); - } - - @Override - public int getQuarkAbsoluteAndAdd(String... attribute) { - waitUntilReady(); - try { - return realStateSystem.getQuarkAbsolute(attribute); - } catch (AttributeNotFoundException e) { - throw new RuntimeException(ERR_MSG); - } - } - - @Override - public int getQuarkRelativeAndAdd(int startingNodeQuark, String... subPath) { - waitUntilReady(); - try { - return realStateSystem.getQuarkRelative(startingNodeQuark, subPath); - } catch (AttributeNotFoundException e) { - throw new RuntimeException(ERR_MSG); - } - } - - private void waitUntilReady() { - try { - ssAssignedLatch.await(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/AbstractTmfMipmapStateProvider.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/AbstractTmfMipmapStateProvider.java deleted file mode 100644 index 2baaae8c9c..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/AbstractTmfMipmapStateProvider.java +++ /dev/null @@ -1,199 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Jean-Christian Kouamé - Initial API and implementation - * Patrick Tasse - Updates to mipmap feature - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.statesystem.mipmap; - -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.statesystem.AbstractTmfStateProvider; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * This is an abstract state provider that allows attributes to be mipmapped - * for one or more of the supported mipmap features (min, max, average). - * - * Extend this class for a specific implementation - */ -public abstract class AbstractTmfMipmapStateProvider extends AbstractTmfStateProvider { - - /** - * Feature bit for the maximum mipmap feature (value is 1<<1). - */ - public static final int MAX = 1 << 1; - - /** - * Feature bit for the minimum mipmap feature (value is 1<<2). - */ - public static final int MIN = 1 << 2; - - /** - * Feature bit for the average mipmap feature (value is 1<<3). - */ - public static final int AVG = 1 << 3; - - /** - * The string for maximum mipmap feature sub-attribute. - * This attribute value is the mipmap number of levels. - * It has sub-attributes for every level ("1", "2", etc.) - */ - public static final String MAX_STRING = "max"; //$NON-NLS-1$ - - /** - * The string for minimum mipmap feature sub-attribute. - * This attribute value is the mipmap number of levels. - * It has sub-attributes for every level ("1", "2", etc.) - */ - public static final String MIN_STRING = "min"; //$NON-NLS-1$ - - /** - * The string for average mipmap feature sub-attribute. - * This attribute value is the mipmap number of levels. - * It has sub-attributes for every level ("1", "2", etc.) - */ - public static final String AVG_STRING = "avg"; //$NON-NLS-1$ - - /** - * Map of mipmap features per attribute. The map's key is the base attribute quark. - */ - private Map> featureMap = new HashMap<>(); - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructor - * - * @param trace - * The trace directory - * @param eventType - * The specific class for the event type - * @param id - * The name given to this state change input. Only used - * internally. - */ - public AbstractTmfMipmapStateProvider(ITmfTrace trace, Class eventType, String id) { - super(trace, eventType, id); - } - - // ------------------------------------------------------------------------ - // Public methods - // ------------------------------------------------------------------------ - - @Override - public void dispose() { - waitForEmptyQueue(); - for (Set features : featureMap.values()) { - for (ITmfMipmapFeature feature : features) { - feature.updateAndCloseMipmap(); - } - } - super.dispose(); - } - - /** - * Modify a mipmap attribute. The base attribute is modified and the mipmap - * attributes for the feature(s) specified in the mipmap feature bitmap are - * created and/or updated.
- * Note: The mipmapFeatureBits and resolution are only used on the first - * call of this method for a particular attribute, and the mipmap features - * for this attribute are then activated until the end of the trace.
- * Note: The base attribute should only be modified by calling this method. - * - * @param ts - * The timestamp of the event - * @param value - * The value of the base attribute - * @param baseQuark - * The quark of the base attribute - * @param mipmapFeatureBits - * The mipmap feature bit(s) - * @param resolution - * The mipmap resolution (must be greater than 1) - * @throws TimeRangeException - * If the requested time is outside of the trace's range - * @throws AttributeNotFoundException - * If the requested attribute quark is invalid - * @throws StateValueTypeException - * If the inserted state value's type does not match what is - * already assigned to this attribute. - * @see #MAX - * @see #MIN - * @see #AVG - */ - public void modifyMipmapAttribute(long ts, ITmfStateValue value, int baseQuark, int mipmapFeatureBits, int resolution) - throws TimeRangeException, AttributeNotFoundException, StateValueTypeException { - ss.modifyAttribute(ts, value, baseQuark); - if (value.getType() == Type.LONG || value.getType() == Type.INTEGER || value.getType() == Type.DOUBLE || value.isNull()) { - Set features = getFeatureSet(baseQuark, ts, value, mipmapFeatureBits, resolution); - for (ITmfMipmapFeature mf : features) { - mf.updateMipmap(value, ts); - } - } - } - - // ------------------------------------------------------------------------ - // Private methods - // ------------------------------------------------------------------------ - - private Set getFeatureSet(int baseQuark, long ts, ITmfStateValue value, int mipmapFeatureBits, int resolution) { - Set features = featureMap.get(baseQuark); - if (features != null) { - return features; - } - features = new LinkedHashSet<>(); - if (value.isNull()) { - return features; - } - featureMap.put(baseQuark, features); - if (resolution > 1) { - try { - if ((mipmapFeatureBits & MAX) != 0) { - int featureQuark = ss.getQuarkRelativeAndAdd(baseQuark, MAX_STRING); - ss.modifyAttribute(ts, TmfStateValue.newValueInt(0), featureQuark); - MaxMipmapFeature mf = new MaxMipmapFeature(baseQuark, featureQuark, resolution, ss); - features.add(mf); - } - if ((mipmapFeatureBits & MIN) != 0) { - int featureQuark = ss.getQuarkRelativeAndAdd(baseQuark, MIN_STRING); - ss.modifyAttribute(ts, TmfStateValue.newValueInt(0), featureQuark); - MinMipmapFeature mf = new MinMipmapFeature(baseQuark, featureQuark, resolution, ss); - features.add(mf); - } - if ((mipmapFeatureBits & AVG) != 0) { - int featureQuark = ss.getQuarkRelativeAndAdd(baseQuark, AVG_STRING); - ss.modifyAttribute(ts, TmfStateValue.newValueInt(0), featureQuark); - AvgMipmapFeature mf = new AvgMipmapFeature(baseQuark, featureQuark, resolution, ss); - features.add(mf); - } - } catch (TimeRangeException e) { - e.printStackTrace(); - } catch (AttributeNotFoundException e) { - e.printStackTrace(); - } catch (StateValueTypeException e) { - e.printStackTrace(); - } - } - return features; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/AvgMipmapFeature.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/AvgMipmapFeature.java deleted file mode 100644 index d86b42eb73..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/AvgMipmapFeature.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Jean-Christian Kouamé - Initial API and implementation - * Patrick Tasse - Updates to mipmap feature - *******************************************************************************/ -package org.eclipse.linuxtools.internal.tmf.core.statesystem.mipmap; - -import java.util.List; - -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type; - -/** - * The average mipmap feature. - * - * Each mipmap state value is the weighted average by time duration of all the - * lower-level state values it covers. Null state values count as zero in the - * weighted average. The state value is a Double. - */ -public class AvgMipmapFeature extends TmfMipmapFeature { - - /** - * Constructor - * - * @param baseQuark - * The quark for the attribute we want to mipmap - * @param mipmapQuark - * The quark of the mipmap feature attribute - * @param mipmapResolution - * The resolution that will be use in the mipmap - * @param ss - * The state system in which to insert the state changes - */ - public AvgMipmapFeature(final int baseQuark, final int mipmapQuark, final int mipmapResolution, final ITmfStateSystemBuilder ss) { - super(baseQuark, mipmapQuark, mipmapResolution, ss); - } - - @Override - protected ITmfStateValue computeMipmapValue(List lowerIntervals, long startTime, long endTime) { - long range = endTime - startTime; - if (range <= 0) { - return TmfStateValue.newValueDouble(0.0); - } - double sum = 0.0; - try { - for (ITmfStateInterval interval : lowerIntervals) { - ITmfStateValue value = interval.getStateValue(); - long duration = interval.getEndTime() - interval.getStartTime(); - if (value.getType() == Type.DOUBLE) { - sum += value.unboxDouble() * duration; - } else { - sum += (double) value.unboxLong() * duration; - } - } - } catch (StateValueTypeException e) { - e.printStackTrace(); - } - double average = sum / range; - ITmfStateValue avgValue = TmfStateValue.newValueDouble(average); - return avgValue; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/ITmfMipmapFeature.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/ITmfMipmapFeature.java deleted file mode 100644 index 7589c80a91..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/ITmfMipmapFeature.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Jean-Christian Kouamé - Initial API and implementation - * Patrick Tasse - Updates to mipmap feature - *******************************************************************************/ -package org.eclipse.linuxtools.internal.tmf.core.statesystem.mipmap; - -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; - -/** - * Interface to allow additional types of mipmaps to be added. Two functions - * need to be implemented: {@link ITmfMipmapFeature#updateMipmap} and - * {@link ITmfMipmapFeature#updateAndCloseMipmap}. - * - * @author Jean-Christian Kouamé - * - */ -public interface ITmfMipmapFeature { - - /** - * Update the mipmap with a new state value. - * - * @param value - * The new state value - * @param ts - * The timestamp of the event - */ - public void updateMipmap(ITmfStateValue value, long ts); - - /** - * Update the mipmap values at all levels before closing. - */ - public void updateAndCloseMipmap(); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/MaxMipmapFeature.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/MaxMipmapFeature.java deleted file mode 100644 index 013da7c768..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/MaxMipmapFeature.java +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Jean-Christian Kouamé - Initial API and implementation - * Patrick Tasse - Updates to mipmap feature - *******************************************************************************/ -package org.eclipse.linuxtools.internal.tmf.core.statesystem.mipmap; - -import java.util.List; - -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type; - -/** - * The maximum mipmap feature. - * - * Each mipmap state value is the maximum numerical value of all the non-null - * lower-level state values it covers. The state value is of the same type as - * the base attribute. - */ -public class MaxMipmapFeature extends TmfMipmapFeature { - - /** - * Constructor - * - * @param baseQuark - * The quark for the attribute we want to mipmap - * @param mipmapQuark - * The quark of the mipmap feature attribute - * @param mipmapResolution - * The resolution that will be use in the mipmap - * @param ss - * The state system in which to insert the state changes - */ - public MaxMipmapFeature(final int baseQuark, final int mipmapQuark, final int mipmapResolution, final ITmfStateSystemBuilder ss) { - super(baseQuark, mipmapQuark, mipmapResolution, ss); - } - - @Override - protected ITmfStateValue computeMipmapValue(List lowerIntervals, long startTime, long endTime) { - ITmfStateValue maxValue = null; - try { - for (ITmfStateInterval interval : lowerIntervals) { - ITmfStateValue value = interval.getStateValue(); - if (value.getType() == Type.DOUBLE) { - if (maxValue == null || value.unboxDouble() > maxValue.unboxDouble()) { - maxValue = value; - } - } else { - if (maxValue == null || value.unboxLong() > maxValue.unboxLong()) { - maxValue = value; - } - } - } - } catch (StateValueTypeException e) { - e.printStackTrace(); - } - return maxValue; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/MinMipmapFeature.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/MinMipmapFeature.java deleted file mode 100644 index 4422f8ca28..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/MinMipmapFeature.java +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Jean-Christian Kouamé - Initial API and implementation - * Patrick Tasse - Updates to mipmap feature - *******************************************************************************/ -package org.eclipse.linuxtools.internal.tmf.core.statesystem.mipmap; - -import java.util.List; - -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type; - -/** - * The minimum mipmap feature. - * - * Each mipmap state value is the minimum numerical value of all the non-null - * lower-level state values it covers. The state value is of the same type as - * the base attribute. - */ -public class MinMipmapFeature extends TmfMipmapFeature { - - /** - * Constructor - * - * @param baseQuark - * The quark for the attribute we want to mipmap - * @param mipmapQuark - * The quark of the mipmap feature attribute - * @param mipmapResolution - * The resolution that will be use in the mipmap - * @param ss - * The state system in which to insert the state changes - */ - public MinMipmapFeature(final int baseQuark, final int mipmapQuark, final int mipmapResolution, final ITmfStateSystemBuilder ss) { - super(baseQuark, mipmapQuark, mipmapResolution, ss); - } - - @Override - protected ITmfStateValue computeMipmapValue(List lowerIntervals, long startTime, long endTime) { - ITmfStateValue minValue = null; - try { - for (ITmfStateInterval interval : lowerIntervals) { - ITmfStateValue value = interval.getStateValue(); - if (value.getType() == Type.DOUBLE) { - if (minValue == null || value.unboxDouble() < minValue.unboxDouble()) { - minValue = value; - } - } else { - if (minValue == null || value.unboxLong() < minValue.unboxLong()) { - minValue = value; - } - } - } - } catch (StateValueTypeException e) { - e.printStackTrace(); - } - return minValue; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/TmfMipmapFeature.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/TmfMipmapFeature.java deleted file mode 100644 index dfc5fee930..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/TmfMipmapFeature.java +++ /dev/null @@ -1,238 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Jean-Christian Kouamé - Initial API and implementation - * Patrick Tasse - Updates to mipmap feature - *******************************************************************************/ -package org.eclipse.linuxtools.internal.tmf.core.statesystem.mipmap; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; -import org.eclipse.linuxtools.statesystem.core.interval.TmfStateInterval; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; - -/** - * The mipmap feature base implementation. - * - * @author Jean-Christian Kouamé - * @author Patrick Tasse - * - */ -public abstract class TmfMipmapFeature implements ITmfMipmapFeature { - - /** The current state value */ - protected ITmfStateValue currentValue = TmfStateValue.nullValue(); - /** The current start time for the state value */ - protected long currentStartTime; - /** The list of ongoing state intervals per mipmap level */ - protected List> intervals = new ArrayList<>(); - /** The state system used to store the mipmap attributes */ - protected ITmfStateSystemBuilder ss; - - private int mipmapResolution; - private int mipmapQuark; - private List levelQuarks = new ArrayList<>(); - - /** - * Constructor - * - * @param baseQuark - * The quark of the attribute we want to mipmap - * @param mipmapQuark - * The quark of the mipmap feature attribute - * @param mipmapResolution - * The resolution that will be used for the mipmap - * @param ss - * The state system in which to insert the state changes - */ - public TmfMipmapFeature(int baseQuark, int mipmapQuark, int mipmapResolution, ITmfStateSystemBuilder ss) { - this.mipmapQuark = mipmapQuark; - this.mipmapResolution = mipmapResolution; - this.ss = ss; - - /* store the base attribute quark at level 0 */ - this.levelQuarks.add(baseQuark); - - /* create the level 0 list */ - intervals.add(new ArrayList(mipmapResolution)); - } - - @Override - public void updateMipmap(ITmfStateValue value, long ts) { - /* if the value did not change, ignore it */ - if (currentValue.equals(value)) { - return; - } - - /* if the ongoing state value is not null, create and store a state interval */ - if (!currentValue.isNull()) { - ITmfStateInterval interval = new TmfStateInterval(currentStartTime, ts, getLevelQuark(0), currentValue); - intervals.get(0).add(interval); - } - - /* if the new value is not null, update the mipmap levels that are full */ - if (!value.isNull()) { - int level = 0; - while (intervals.get(level).size() == getMipmapResolution()) { - updateMipmapLevel(++level, ts); - } - } - - /* store the new value as the ongoing state value */ - currentValue = value; - currentStartTime = ts; - } - - @Override - public void updateAndCloseMipmap() { - if (!currentValue.isNull()) { - ITmfStateInterval interval = new TmfStateInterval(currentStartTime, currentStartTime, getLevelQuark(0), currentValue); - intervals.get(0).add(interval); - } - for (int level = 1; level <= getNbLevels(); level++) { - updateMipmapLevel(level, currentStartTime); - } - } - - /** - * Compute and update the mipmap level attribute from the lower-level - * state interval list - * - * @param level - * The mipmap level to update - * @param endTime - * The end timestamp to use for the mipmap interval - */ - protected void updateMipmapLevel(int level, long endTime) { - try { - /* get the lower-level interval list */ - List lowerIntervals = intervals.get(level - 1); - if (lowerIntervals.size() == 0) { - return; - } - - /* get the start time from the first interval in the lower-level list */ - long startTime = lowerIntervals.get(0).getStartTime(); - - /* compute the mipmap value */ - ITmfStateValue value = computeMipmapValue(lowerIntervals, startTime, endTime); - - /* clear the lower-level list */ - lowerIntervals.clear(); - - /* get or create the current-level quark */ - int levelQuark = ss.getQuarkRelativeAndAdd(mipmapQuark, String.valueOf(level)); - if (!checkLevelExists(level)) { - addLevelQuark(levelQuark); - ss.updateOngoingState(TmfStateValue.newValueInt(level), mipmapQuark); - intervals.add(new ArrayList(getMipmapResolution())); - } - - /* add new interval to current-level list */ - ITmfStateInterval interval = new TmfStateInterval(startTime, endTime, levelQuark, value); - intervals.get(level).add(interval); - - /* update the current-level attribute */ - ss.modifyAttribute(startTime, value, levelQuark); - } catch (StateValueTypeException e) { - e.printStackTrace(); - } catch (AttributeNotFoundException e) { - e.printStackTrace(); - } catch (TimeRangeException e) { - e.printStackTrace(); - } - } - - /** - * Compute the mipmap value from a list of lower-level state intervals - * - * @param lowerIntervals - * The list of lower-level state intervals - * @param startTime - * The start time of the mipmap interval - * @param endTime - * The end time of the mipmap interval - * @return A state value to be stored in the mipmap level attribute - */ - protected abstract ITmfStateValue computeMipmapValue(List lowerIntervals, long startTime, long endTime); - - /** - * Get the mipmap resolution - * - * @return The mipmap resolution for this feature - */ - protected int getMipmapResolution() { - return mipmapResolution; - } - - /** - * Get the mipmap feature quark. The state value - * of this attribute is the mipmap number of levels. - * This is the parent attribute of the mipmap level quarks. - * - * @return The attribute quark for this mipmap feature - */ - protected int getMipmapQuark() { - return mipmapQuark; - } - - /** - * Get the mipmap quark for the specified level. - * For level 0 the base attribute quark is returned. - * - * @param level - * The mipmap level (0 for the base attribute) - * @return The attribute quark for this mipmap level - */ - protected int getLevelQuark(int level) { - return levelQuarks.get(level); - } - - /** - * Add a new mipmap level quark. - * - * @param quark - * The attribute quark for the new mipmap level - */ - protected void addLevelQuark(int quark) { - levelQuarks.add(quark); - } - - /** - * Get the mipmap number of levels. - * - * @return The current number of mipmap levels for this feature - * (excluding the base attribute) - */ - protected int getNbLevels() { - return levelQuarks.size() - 1; - } - - /** - * Checks if a mipmap level exists. - * - * @param level - * The mipmap level to check - * @return true if this level exists, false otherwise - */ - protected boolean checkLevelExists(int level) { - if (level >= levelQuarks.size() || level < 0) { - return false; - } - return true; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/TmfStateSystemOperations.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/TmfStateSystemOperations.java deleted file mode 100644 index 4db30a2990..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/mipmap/TmfStateSystemOperations.java +++ /dev/null @@ -1,350 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Jean-Christian Kouamé - Initial API and implementation - * Patrick Tasse - Updates to mipmap feature - ******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.statesystem.mipmap; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type; - -/** - * This class implements additional statistical operations that can be - * performed on attributes of the state system. - * - * @author Patrick Tassé - * @since 3.0 - */ -public final class TmfStateSystemOperations { - - private TmfStateSystemOperations() {} - - /** - * Return the maximum value of an attribute over a time range - * - * @param ss - * The state system to query - * @param t1 - * The start time of the range - * @param t2 - * The end time of the range - * @param quark - * The quark of the attribute - * @return The maximum value of the attribute in this range - * @throws TimeRangeException - * If an invalid time range is specified - * @throws AttributeNotFoundException - * If the specified quark doesn't match an attribute - * @throws StateValueTypeException - * If the state value type of the attribute does not support the - * "Max" operation - */ - public static ITmfStateValue queryRangeMax(ITmfStateSystem ss, long t1, long t2, int quark) - throws AttributeNotFoundException, TimeRangeException, StateValueTypeException { - ITmfStateValue max = TmfStateValue.nullValue(); - - List intervals = queryAttributeRange(ss, t1, t2, quark, AbstractTmfMipmapStateProvider.MAX_STRING); - if (intervals.size() == 0) { - return TmfStateValue.nullValue(); - } - for (ITmfStateInterval si : intervals) { - ITmfStateValue value = si.getStateValue(); - - switch (value.getType()) { - case DOUBLE: - if (max.isNull() || si.getStateValue().unboxDouble() > max.unboxDouble()) { - max = si.getStateValue(); - } - break; - - case INTEGER: - case LONG: - if (max.isNull() || si.getStateValue().unboxLong() > max.unboxLong()) { - max = si.getStateValue(); - } - break; - - case NULL: - case STRING: - default: - throw new StateValueTypeException(); - } - } - return max; - } - - /** - * Return the minimum value of an attribute over a time range - * - * @param ss - * The state system to query - * @param t1 - * The start time of the range - * @param t2 - * The end time of the range - * @param quark - * The quark of the attribute - * @return The minimum value of the attribute in this range - * @throws TimeRangeException - * If an invalid time range is specified - * @throws AttributeNotFoundException - * If the specified quark doesn't match an attribute - * @throws StateValueTypeException - * If the state value type of the attribute does not support the - * "Min" operation - */ - public static ITmfStateValue queryRangeMin(ITmfStateSystem ss, - long t1, long t2, int quark) - throws AttributeNotFoundException, TimeRangeException, StateValueTypeException { - ITmfStateValue min = TmfStateValue.nullValue(); - - List intervals = queryAttributeRange(ss, t1, t2, quark, AbstractTmfMipmapStateProvider.MIN_STRING); - if (intervals.size() == 0) { - return TmfStateValue.nullValue(); - } - for (ITmfStateInterval si : intervals) { - ITmfStateValue value = si.getStateValue(); - - switch (value.getType()) { - case DOUBLE: - if (min.isNull() || si.getStateValue().unboxDouble() < min.unboxDouble()) { - min = si.getStateValue(); - } - break; - - case INTEGER: - case LONG: - if (min.isNull() || si.getStateValue().unboxLong() < min.unboxLong()) { - min = si.getStateValue(); - } - break; - - case NULL: - case STRING: - default: - throw new StateValueTypeException(); - } - } - return min; - } - - /** - * Return the weighted average value of an attribute over a time range - * - * @param ss - * The state system to query - * @param t1 - * The start time of the range - * @param t2 - * The end time of the range - * @param quark - * The quark of the attribute - * @return The weighted average value of the attribute in this range - * @throws TimeRangeException - * If an invalid time range is specified - * @throws AttributeNotFoundException - * If the specified quark doesn't match an attribute - * @throws StateValueTypeException - * If the state value type of the attribute does not support the - * "Average" operation - */ - public static double queryRangeAverage(ITmfStateSystem ss, long t1, long t2, int quark) - throws AttributeNotFoundException, TimeRangeException, StateValueTypeException { - double avg = 0.0; - List intervals = queryAttributeRange(ss, t1, t2, quark, AbstractTmfMipmapStateProvider.AVG_STRING); - if (intervals.size() == 0) { - return 0; - } else if (t1 == t2) { - ITmfStateValue value = intervals.get(0).getStateValue(); - if (value.getType() == Type.DOUBLE) { - return value.unboxDouble(); - } - return value.unboxLong(); - } - for (ITmfStateInterval si : intervals) { - long startTime = Math.max(t1, si.getStartTime()); - long endTime = Math.min(t2, si.getEndTime() + 1); - long delta = endTime - startTime; - if (delta > 0) { - ITmfStateValue value = si.getStateValue(); - if (value.getType() == Type.DOUBLE) { - avg += si.getStateValue().unboxDouble() * ((double) delta / (double) (t2 - t1)); - } else { - avg += si.getStateValue().unboxLong() * ((double) delta / (double) (t2 - t1)); - } - } - } - return avg; - } - - private static List queryAttributeRange(ITmfStateSystem ss, - long t1, long t2, int baseQuark, String featureString) - throws AttributeNotFoundException, TimeRangeException, StateValueTypeException { - TimeRange timeRange = new TimeRange(t1, t2); - int mipmapQuark = -1; - List intervals = new ArrayList<>(); - try { - try { - mipmapQuark = ss.getQuarkRelative(baseQuark, featureString); - } catch (AttributeNotFoundException e) { - /* Not a mipmap attribute, query the base attribute */ - if (t1 == t2) { - ITmfStateInterval interval = ss.querySingleState(t1, baseQuark); - if (!interval.getStateValue().isNull()) { - intervals.add(interval); - } - } else { - for (ITmfStateInterval interval : ss.queryHistoryRange(baseQuark, t1, t2)) { - if (!interval.getStateValue().isNull()) { - intervals.add(interval); - } - } - } - return intervals; - } - ITmfStateInterval maxLevelInterval = ss.querySingleState(timeRange.getSecond(), mipmapQuark); - int levelMax = maxLevelInterval.getStateValue().unboxInt(); - queryMipmapAttributeRange(ss, 0, levelMax, baseQuark, mipmapQuark, timeRange, intervals); - return intervals; - - } catch (StateValueTypeException e) { - /* This is a special case, so we'll add a message to the exception */ - throw new StateValueTypeException("State system advertises mipmaps," + //$NON-NLS-1$ - " but doesn't actually have them.", e); //$NON-NLS-1$ - } catch (StateSystemDisposedException e) { - /* We are shutting down, ignore the operation */ - } - return intervals; - } - - private static void queryMipmapAttributeRange(ITmfStateSystem ss, - int currentLevel, int levelMax, int baseQuark, int mipmapQuark, - TimeRange timeRange, List intervals) - throws AttributeNotFoundException, TimeRangeException { - int level = currentLevel; - TimeRange range = timeRange; - ITmfStateInterval currentLevelInterval = null, nextLevelInterval = null; - if (range == null || range.getFirst() > range.getSecond()) { - return; - } - if (level > levelMax || level < 0) { - return; - } - try { - if (range.getFirst() == range.getSecond()) { - level = 0; - currentLevelInterval = ss.querySingleState(range.getFirst(), baseQuark); - if (!currentLevelInterval.getStateValue().isNull()) { - intervals.add(currentLevelInterval); - } - return; - } - if (level < levelMax) { - int levelQuark = ss.getQuarkRelative(mipmapQuark, String.valueOf(level + 1)); - nextLevelInterval = ss.querySingleState(range.getFirst(), levelQuark); - } - - if (nextLevelInterval != null && isFullyOverlapped(range, nextLevelInterval)) { - if (nextLevelInterval.getStateValue().isNull()) { - range = updateTimeRange(range, nextLevelInterval); - } else { - level++; - } - queryMipmapAttributeRange(ss, level, levelMax, baseQuark, mipmapQuark, range, intervals); - return; - } - - if (level == 0) { - currentLevelInterval = ss.querySingleState(range.getFirst(), baseQuark); - } else { - int levelQuark = ss.getQuarkRelative(mipmapQuark, String.valueOf(level)); - currentLevelInterval = ss.querySingleState(range.getFirst(), levelQuark); - } - - if (currentLevelInterval != null && isFullyOverlapped(range, currentLevelInterval)) { - if (!currentLevelInterval.getStateValue().isNull()) { - intervals.add(currentLevelInterval); - } - range = updateTimeRange(range, currentLevelInterval); - } else { - if (level == 0) { - if (currentLevelInterval == null) { - return; - } - if (!currentLevelInterval.getStateValue().isNull()) { - intervals.add(currentLevelInterval); - } - range = updateTimeRange(range, currentLevelInterval); - } else { - level--; - } - } - - queryMipmapAttributeRange(ss, level, levelMax, baseQuark, - mipmapQuark, range, intervals); - - } catch (StateSystemDisposedException e) { - /* We are shutting down, ignore the operation */ - } - } - - private static TimeRange updateTimeRange(TimeRange timeRange, - ITmfStateInterval currentLevelInterval) { - if (currentLevelInterval.getEndTime() >= timeRange.getSecond()) { - return null; - } - long startTime = Math.max(timeRange.getFirst(), - Math.min(currentLevelInterval.getEndTime() + 1, timeRange.getSecond())); - return new TimeRange(startTime, timeRange.getSecond()); - } - - private static boolean isFullyOverlapped(TimeRange range, - ITmfStateInterval interval) { - if (range.getFirst() >= range.getSecond() || - interval.getStartTime() >= interval.getEndTime()) { - return false; - } - if (range.getFirst() <= interval.getStartTime() && - range.getSecond() >= interval.getEndTime()) { - return true; - } - return false; - } -} - -class TimeRange { - - private final long a; - private final long b; - - public TimeRange(long first, long second) { - a = first; - b = second; - } - - public long getFirst() { - return a; - } - - public long getSecond() { - return b; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/ITmfTimestampTransformInvertible.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/ITmfTimestampTransformInvertible.java deleted file mode 100644 index 62895237d5..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/ITmfTimestampTransformInvertible.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.synchronization; - -import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform; - -/** - * Interface for timestamp transform who also provide an inverse transform. - * - * @author Geneviève Bastien - */ -public interface ITmfTimestampTransformInvertible extends ITmfTimestampTransform { - - /** - * Returns the inverse of this transform. The transform composed with its - * inverse yields the identity (or as close to it as mathematical - * approximations in the formulae allow). - * - * @return The inverse transform - */ - ITmfTimestampTransform inverse(); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java deleted file mode 100644 index 540d57d2b7..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java +++ /dev/null @@ -1,623 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - * Francis Giraldeau - Transform computation using synchronization graph - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.synchronization; - -import java.io.IOException; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.math.BigDecimal; -import java.math.MathContext; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.eclipse.linuxtools.internal.tmf.core.synchronization.graph.SyncSpanningTree; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventDependency; -import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform; -import org.eclipse.linuxtools.tmf.core.synchronization.Messages; -import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithm; -import org.eclipse.linuxtools.tmf.core.synchronization.TimestampTransformFactory; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Class implementing fully incremental trace synchronization approach as - * described in - * - * Masoume Jabbarifar, Michel Dagenais and Alireza Shameli-Sendi, - * "Streaming Mode Incremental Clock Synchronization" - * - * Since the algorithm itself applies to two traces, it is implemented in a - * private class, while this public class manages the synchronization between - * all traces. - * - * @author Geneviève Bastien - */ -public class SyncAlgorithmFullyIncremental extends SynchronizationAlgorithm { - - /** - * Auto-generated serial UID - */ - private static final long serialVersionUID = -1782788842774838830L; - - private static final MathContext fMc = MathContext.DECIMAL128; - - /** @Serial */ - private final List fSyncs; - - private SyncSpanningTree fTree = null; - - /** - * Initialization of the attributes - */ - public SyncAlgorithmFullyIncremental() { - fSyncs = new LinkedList<>(); - } - - /** - * Function called after all matching has been done, to do any post-match - * treatment. For this class, it calculates stats, while the data is - * available - */ - @Override - public void matchingEnded() { - getStats(); - } - - @Override - public void init(Collection traces) { - ITmfTrace[] traceArr = traces.toArray(new ITmfTrace[traces.size()]); - fSyncs.clear(); - /* Create a convex hull for all trace pairs */ - // FIXME: is it necessary to make ConvexHull for every pairs up-front? - // The ConvexHull seems to be created on the fly in processMatch(). - for (int i = 0; i < traceArr.length; i++) { - for (int j = i + 1; j < traceArr.length; j++) { - if (!traceArr[i].getHostId().equals(traceArr[j].getHostId())) { - ConvexHull algo = new ConvexHull(traceArr[i].getHostId(), traceArr[j].getHostId()); - fSyncs.add(algo); - } - } - } - } - - @Override - protected void processMatch(TmfEventDependency match) { - String host1 = match.getSourceEvent().getTrace().getHostId(); - String host2 = match.getDestinationEvent().getTrace().getHostId(); - - /* Process only if source and destination are different */ - if (host1.equals(host2)) { - return; - } - - /* Check if a convex hull algorithm already exists for these 2 hosts */ - ConvexHull algo = null; - for (ConvexHull traceSync : fSyncs) { - if (traceSync.isForHosts(host1, host2)) { - algo = traceSync; - } - } - if (algo == null) { - algo = new ConvexHull(host1, host2); - fSyncs.add(algo); - } - algo.processMatch(match); - invalidateSyncGraph(); - } - - private void invalidateSyncGraph() { - fTree = null; - } - - @Override - public ITmfTimestampTransform getTimestampTransform(ITmfTrace trace) { - return getTimestampTransform(trace.getHostId()); - } - - @Override - public ITmfTimestampTransform getTimestampTransform(String hostId) { - SyncSpanningTree tree = getSyncTree(); - return tree.getTimestampTransform(hostId); - } - - /** - * Each convex hull computes the synchronization between 2 given hosts. A - * synchronization can be done on multiple hosts that may not all - * communicate with each other. We must use another algorithm to determine - * which host will be the reference node and what synchronization formula - * will be used between each host and this reference node. - * - * For example, take traces a, b and c where a and c talk to b but do not - * know each other ({@literal a <-> b <-> c}). The convex hulls will contain - * the formulae between their 2 traces, but if a is the reference node, then - * the resulting formula of c would be the composition of {@literal a <-> b} - * and {@literal b <-> c} - * - * @return The synchronization spanning tree for this synchronization - */ - private SyncSpanningTree getSyncTree() { - if (fTree == null) { - fTree = new SyncSpanningTree(); - for (ConvexHull traceSync : fSyncs) { - SyncQuality q = traceSync.getQuality(); - if (q == SyncQuality.ACCURATE || q == SyncQuality.APPROXIMATE) { - String from = traceSync.getReferenceHost(); - String to = traceSync.getOtherHost(); - fTree.addSynchronization(from, to, traceSync.getTimestampTransform(to), traceSync.getAccuracy()); - } - } - } - return fTree; - } - - @Override - public SyncQuality getSynchronizationQuality(ITmfTrace trace1, ITmfTrace trace2) { - for (ConvexHull traceSync : fSyncs) { - if (traceSync.isForHosts(trace1.getHostId(), trace2.getHostId())) { - return traceSync.getQuality(); - } - } - return SyncQuality.ABSENT; - } - - @Override - public boolean isTraceSynced(String hostId) { - ITmfTimestampTransform t = getTimestampTransform(hostId); - return !t.equals(TimestampTransformFactory.getDefaultTransform()); - } - - @Override - public Map> getStats() { - /* - * TODO: Stats, while still accurate, may be misleading now that the - * sync tree changes synchronization formula. The stats should use the - * tree instead - */ - Map> statmap = new LinkedHashMap<>(); - for (ConvexHull traceSync : fSyncs) { - statmap.put(traceSync.getReferenceHost() + " <==> " + traceSync.getOtherHost(), traceSync.getStats()); //$NON-NLS-1$ - } - return statmap; - } - - @Override - public String toString() { - StringBuilder b = new StringBuilder(); - b.append(getClass().getSimpleName() + " "); //$NON-NLS-1$ - b.append(fSyncs); - return b.toString(); - } - - /** - * This is the actual synchronization algorithm between two traces using - * convex hull - */ - private class ConvexHull implements Serializable { - - private static final long serialVersionUID = 8309351175030935291L; - - /** - * The list of meaningful points on the upper hull (received by the - * reference trace, below in a graph) - */ - private final LinkedList fUpperBoundList = new LinkedList<>(); - - /** - * The list of meaninful points on the lower hull (sent by the reference - * trace, above in a graph) - */ - private final LinkedList fLowerBoundList = new LinkedList<>(); - - /** Points forming the line with maximum slope */ - private final SyncPoint[] fLmax; - - /** Points forming the line with minimum slope */ - private final SyncPoint[] fLmin; - - /** - * Slopes and ordinate at origin of respectively fLmin, fLmax and the - * bisector - */ - private BigDecimal fAlphamin, fBetamax, fAlphamax, fBetamin, fAlpha, fBeta; - - private int fNbMatches, fNbAccurateMatches; - private String fReferenceHost = "", fOtherHost = ""; //$NON-NLS-1$//$NON-NLS-2$ - private SyncQuality fQuality; - - private Map fStats = new LinkedHashMap<>(); - - /** - * Initialization of the attributes - * - * @param host1 - * ID of the first host - * @param host2 - * ID of the second host - */ - public ConvexHull(String host1, String host2) { - if (host1.compareTo(host2) > 0) { - fReferenceHost = host2; - fOtherHost = host1; - } else { - fReferenceHost = host1; - fOtherHost = host2; - } - fLmax = new SyncPoint[2]; - fLmin = new SyncPoint[2]; - fAlpha = BigDecimal.ONE; - fAlphamax = BigDecimal.ONE; - fAlphamin = BigDecimal.ONE; - fBeta = BigDecimal.ZERO; - fBetamax = BigDecimal.ZERO; - fBetamin = BigDecimal.ZERO; - fNbMatches = 0; - fNbAccurateMatches = 0; - fQuality = SyncQuality.ABSENT; // default quality - } - - protected void processMatch(TmfEventDependency match) { - - LinkedList boundList, otherBoundList; - - SyncPoint[] line, otherLine; - SyncPoint p; - int inversionFactor = 1; - boolean qualify = false; - fNbMatches++; - - /* Initialize data depending on the which hull the match is part of */ - if (match.getSourceEvent().getTrace().getHostId().compareTo(match.getDestinationEvent().getTrace().getHostId()) > 0) { - boundList = fUpperBoundList; - otherBoundList = fLowerBoundList; - line = fLmin; - otherLine = fLmax; - p = new SyncPoint(match.getDestinationEvent(), match.getSourceEvent()); - inversionFactor = 1; - } else { - boundList = fLowerBoundList; - otherBoundList = fUpperBoundList; - line = fLmax; - otherLine = fLmin; - p = new SyncPoint(match.getSourceEvent(), match.getDestinationEvent()); - inversionFactor = -1; - } - - /* - * Does the message qualify for the hull, or is in on the wrong side - * of the reference line - */ - if ((line[0] == null) || (line[1] == null) || (p.crossProduct(line[0], line[1]) * inversionFactor > 0)) { - /* - * If message qualifies, verify if points need to be removed - * from the hull and add the new point as the maximum reference - * point for the line. Also clear the stats that are not good - * anymore - */ - fNbAccurateMatches++; - qualify = true; - removeUselessPoints(p, boundList, inversionFactor); - line[1] = p; - fStats.clear(); - } - - /* - * Adjust the boundary of the reference line and if one of the - * reference point of the other line was removed from the hull, also - * adjust the other line - */ - adjustBound(line, otherBoundList, inversionFactor); - if ((otherLine[1] != null) && !boundList.contains(otherLine[0])) { - adjustBound(otherLine, boundList, inversionFactor * -1); - } - - if (qualify) { - approximateSync(); - } - - } - - /** - * Calculates slopes and ordinate at origin of fLmax and fLmin to obtain - * and approximation of the synchronization at this time - */ - private void approximateSync() { - - /** - * Line slopes functions - * - * Lmax = alpha_max T + beta_min - * - * Lmin = alpha_min T + beta_max - */ - if ((fLmax[0] != null) || (fLmin[0] != null)) { - /** - * Do not recalculate synchronization after it is failed. We - * keep the last not failed result. - */ - if (getQuality() != SyncQuality.FAIL) { - BigDecimal alphamax = fLmax[1].getAlpha(fLmax[0]); - BigDecimal alphamin = fLmin[1].getAlpha(fLmin[0]); - SyncQuality quality = null; - - if ((fLmax[0] == null) || (fLmin[0] == null)) { - quality = SyncQuality.APPROXIMATE; - } - else if (alphamax.compareTo(alphamin) > 0) { - quality = SyncQuality.ACCURATE; - } else { - /* Lines intersect, not good */ - quality = SyncQuality.FAIL; - } - /* - * Only calculate sync if this match does not cause failure - * of synchronization - */ - if (quality != SyncQuality.FAIL) { - fAlphamax = alphamax; - fBetamin = fLmax[1].getBeta(fAlphamax); - fAlphamin = alphamin; - fBetamax = fLmin[1].getBeta(fAlphamin); - fAlpha = fAlphamax.add(fAlphamin).divide(BigDecimal.valueOf(2), fMc); - fBeta = fBetamin.add(fBetamax).divide(BigDecimal.valueOf(2), fMc); - } - setQuality(quality); - } - } else if (((fLmax[0] == null) && (fLmin[1] == null)) - || ((fLmax[1] == null) && (fLmin[0] == null))) { - /* Either there is no upper hull point or no lower hull */ - setQuality(SyncQuality.INCOMPLETE); - } - } - - /* - * Verify if the line should be adjusted to be more accurate give the - * hull - */ - private void adjustBound(SyncPoint[] line, LinkedList otherBoundList, int inversionFactor) { - SyncPoint minPoint = null, nextPoint; - boolean finishedSearch = false; - - /* - * Find in the other bound, the origin point of the line, start from - * the beginning if the point was lost - */ - int i = Math.max(0, otherBoundList.indexOf(line[0])); - - while ((i < otherBoundList.size() - 1) && !finishedSearch) { - minPoint = otherBoundList.get(i); - nextPoint = otherBoundList.get(i + 1); - - /* - * If the rotation (cross-product) is not optimal, move to next - * point as reference for the line (if available) - * - * Otherwise, the current minPoint is the minPoint of the line - */ - if (minPoint.crossProduct(nextPoint, line[1]) * inversionFactor > 0) { - if (nextPoint.getTimeX() < line[1].getTimeX()) { - i++; - } else { - line[0] = null; - finishedSearch = true; - } - } else { - line[0] = minPoint; - finishedSearch = true; - } - } - - if (line[0] == null) { - line[0] = minPoint; - } - - /* Make sure point 0 is before point 1 */ - if ((line[0] != null) && (line[0].getTimeX() > line[1].getTimeX())) { - line[0] = null; - } - } - - /* - * When a point qualifies to be in a hull, we verify if any of the - * existing points need to be removed from the hull - */ - private void removeUselessPoints(final SyncPoint p, final LinkedList boundList, final int inversionFactor) { - - boolean checkRemove = true; - - while (checkRemove && boundList.size() >= 2) { - if (p.crossProduct(boundList.get(boundList.size() - 2), boundList.getLast()) * inversionFactor > 0) { - boundList.removeLast(); - } else { - checkRemove = false; - } - } - boundList.addLast(p); - } - - public ITmfTimestampTransform getTimestampTransform(String hostId) { - if (hostId.equals(fOtherHost) && (getQuality() == SyncQuality.ACCURATE || getQuality() == SyncQuality.APPROXIMATE || getQuality() == SyncQuality.FAIL)) { - /* alpha: beta => 1 / fAlpha, -1 * fBeta / fAlpha); */ - return TimestampTransformFactory.createLinear(BigDecimal.ONE.divide(fAlpha, fMc), BigDecimal.valueOf(-1).multiply(fBeta).divide(fAlpha, fMc)); - } - return TimestampTransformFactory.getDefaultTransform(); - } - - public SyncQuality getQuality() { - return fQuality; - } - - public BigDecimal getAccuracy() { - return fAlphamax.subtract(fAlphamin); - } - - public Map getStats() { - if (fStats.size() == 0) { - String syncQuality; - switch (getQuality()) { - case ABSENT: - syncQuality = Messages.SyncAlgorithmFullyIncremental_absent; - break; - case ACCURATE: - syncQuality = Messages.SyncAlgorithmFullyIncremental_accurate; - break; - case APPROXIMATE: - syncQuality = Messages.SyncAlgorithmFullyIncremental_approx; - break; - case INCOMPLETE: - syncQuality = Messages.SyncAlgorithmFullyIncremental_incomplete; - break; - case FAIL: - default: - syncQuality = Messages.SyncAlgorithmFullyIncremental_fail; - break; - } - - fStats.put(Messages.SyncAlgorithmFullyIncremental_refhost, fReferenceHost); - fStats.put(Messages.SyncAlgorithmFullyIncremental_otherhost, fOtherHost); - fStats.put(Messages.SyncAlgorithmFullyIncremental_quality, syncQuality); - fStats.put(Messages.SyncAlgorithmFullyIncremental_alpha, fAlpha); - fStats.put(Messages.SyncAlgorithmFullyIncremental_beta, fBeta); - fStats.put(Messages.SyncAlgorithmFullyIncremental_ub, (fUpperBoundList.size() == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fUpperBoundList.size()); - fStats.put(Messages.SyncAlgorithmFullyIncremental_lb, (fLowerBoundList.size() == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fLowerBoundList.size()); - fStats.put(Messages.SyncAlgorithmFullyIncremental_accuracy, getAccuracy().doubleValue()); - fStats.put(Messages.SyncAlgorithmFullyIncremental_nbmatch, (fNbMatches == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fNbMatches); - fStats.put(Messages.SyncAlgorithmFullyIncremental_nbacc, (fNbAccurateMatches == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fNbAccurateMatches); - fStats.put(Messages.SyncAlgorithmFullyIncremental_refformula, Messages.SyncAlgorithmFullyIncremental_T_ + fReferenceHost); - fStats.put(Messages.SyncAlgorithmFullyIncremental_otherformula, fAlpha + Messages.SyncAlgorithmFullyIncremental_mult + Messages.SyncAlgorithmFullyIncremental_T_ + fReferenceHost + Messages.SyncAlgorithmFullyIncremental_add + fBeta); - } - return fStats; - - } - - public String getReferenceHost() { - return fReferenceHost; - } - - public String getOtherHost() { - return fOtherHost; - } - - public boolean isForHosts(String hostId1, String hostId2) { - return ((fReferenceHost.equals(hostId1) && fOtherHost.equals(hostId2)) || (fReferenceHost.equals(hostId2) && fOtherHost.equals(hostId1))); - } - - private void writeObject(ObjectOutputStream s) - throws IOException { - /* - * Remove calculation data because most of it is not serializable. - * We have the statistics anyway - */ - fUpperBoundList.clear(); - fLowerBoundList.clear(); - fLmin[0] = null; - fLmin[1] = null; - fLmax[0] = null; - fLmax[1] = null; - s.defaultWriteObject(); - } - - @SuppressWarnings("nls") - @Override - public String toString() { - StringBuilder b = new StringBuilder(); - b.append("Between " + fReferenceHost + " and " + fOtherHost + " ["); - b.append(" alpha " + fAlpha + " beta " + fBeta + " ]"); - return b.toString(); - } - - private void setQuality(SyncQuality fQuality) { - this.fQuality = fQuality; - } - - } - - /** - * Private class representing a point to synchronize on a graph. The x axis - * is the timestamp of the event from the reference trace while the y axis - * is the timestamp of the event on the other trace - */ - private class SyncPoint { - private final ITmfTimestamp x, y; - - public SyncPoint(ITmfEvent ex, ITmfEvent ey) { - x = ex.getTimestamp(); - y = ey.getTimestamp(); - } - - public long getTimeX() { - return x.getValue(); - } - - /** - * Calculate a cross product of 3 points: - * - * If the cross-product < 0, then p, pa, pb are clockwise - * - * If the cross-product > 0, then p, pa, pb are counter-clockwise - * - * If cross-product == 0, then they are in a line - * - * @param pa - * First point - * @param pb - * Second point - * @return The cross product - */ - public long crossProduct(SyncPoint pa, SyncPoint pb) { - long cp = ((pa.x.getValue() - x.getValue()) * (pb.y.getValue() - y.getValue()) - (pa.y.getValue() - y.getValue()) * (pb.x.getValue() - x.getValue())); - return cp; - } - - /* - * Gets the alpha (slope) between two points - */ - public BigDecimal getAlpha(SyncPoint p1) { - if (p1 == null) { - return BigDecimal.ONE; - } - BigDecimal deltay = BigDecimal.valueOf(y.getValue() - p1.y.getValue()); - BigDecimal deltax = BigDecimal.valueOf(x.getValue() - p1.x.getValue()); - if (deltax.equals(BigDecimal.ZERO)) { - return BigDecimal.ONE; - } - return deltay.divide(deltax, fMc); - } - - /* - * Get the beta value (when x = 0) of the line given alpha - */ - public BigDecimal getBeta(BigDecimal alpha) { - return BigDecimal.valueOf(y.getValue()).subtract(alpha.multiply(BigDecimal.valueOf(x.getValue()), fMc)); - } - - @Override - public String toString() { - return String.format("%s (%s, %s)", this.getClass().getCanonicalName(), x, y); //$NON-NLS-1$ - } - } - - private void writeObject(ObjectOutputStream s) - throws IOException { - /* - * Remove the tree because it is not serializable - */ - fTree = null; - s.defaultWriteObject(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/TmfConstantTransform.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/TmfConstantTransform.java deleted file mode 100644 index fe5f73aeea..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/TmfConstantTransform.java +++ /dev/null @@ -1,116 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.synchronization; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform; -import org.eclipse.linuxtools.tmf.core.synchronization.TimestampTransformFactory; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp; - -/** - * Constant transform, just offset your timestamp with another. - * - * @author Matthew Khouzam - */ -public class TmfConstantTransform implements ITmfTimestampTransformInvertible { - - /** - * Serial ID - */ - private static final long serialVersionUID = 417299521984404532L; - private final long fOffset; - - /** - * Default constructor - */ - public TmfConstantTransform() { - // we really should be using an identity transform here. - fOffset = 0; - } - - /** - * Constructor with offset - * - * @param offset - * The offset of the linear transform in nanoseconds - */ - public TmfConstantTransform(long offset) { - fOffset = offset; - } - - /** - * Constructor with offset timestamp - * - * @param offset - * The offset of the linear transform - */ - public TmfConstantTransform(@NonNull ITmfTimestamp offset) { - this(new TmfNanoTimestamp(offset).getValue()); - } - - @Override - public ITmfTimestamp transform(ITmfTimestamp timestamp) { - return timestamp.normalize(fOffset, ITmfTimestamp.NANOSECOND_SCALE); - } - - /** - * {@inheritDoc} - * - * @param timestamp - * the timestamp in nanoseconds - * @return the timestamp in nanoseconds - */ - @Override - public long transform(long timestamp) { - return fOffset + timestamp; - } - - @Override - public ITmfTimestampTransform composeWith(ITmfTimestampTransform composeWith) { - if (composeWith.equals(TmfTimestampTransform.IDENTITY)) { - /* If composing with identity, just return this */ - return this; - } else if (composeWith instanceof TmfConstantTransform) { - TmfConstantTransform tct = (TmfConstantTransform) composeWith; - final long offset = fOffset + tct.fOffset; - if (offset == 0) { - return TmfTimestampTransform.IDENTITY; - } - return new TmfConstantTransform(offset); - } else if (composeWith instanceof TmfTimestampTransformLinear) { - throw new UnsupportedOperationException("Cannot compose a constant and linear transform yet"); //$NON-NLS-1$ - } else { - /* - * We do not know what to do with this kind of transform, just - * return this - */ - return this; - } - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("TmfConstantTransform [ offset = "); //$NON-NLS-1$ - builder.append(fOffset); - builder.append(" ]"); //$NON-NLS-1$ - return builder.toString(); - } - - @Override - public ITmfTimestampTransform inverse() { - return TimestampTransformFactory.createWithOffset(-1 * fOffset); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/TmfTimestampTransform.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/TmfTimestampTransform.java deleted file mode 100644 index 75784e5a68..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/TmfTimestampTransform.java +++ /dev/null @@ -1,82 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.synchronization; - -import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; - -/** - * A default simple, identity timestamp transform. It is a singleton class and - * returns the timestamp itself - * - * @author Geneviève Bastien - */ -public final class TmfTimestampTransform implements ITmfTimestampTransformInvertible { - - /** - * Generated serial UID - */ - private static final long serialVersionUID = -1480581417493073304L; - - /** - * The unique instance of this transform, since it is always the same - */ - public static final TmfTimestampTransform IDENTITY = new TmfTimestampTransform(); - - /** - * Default constructor - */ - private TmfTimestampTransform() { - - } - - @Override - public ITmfTimestamp transform(ITmfTimestamp timestamp) { - return timestamp; - } - - @Override - public long transform(long timestamp) { - return timestamp; - } - - @Override - public ITmfTimestampTransform composeWith(ITmfTimestampTransform composeWith) { - /* Since this transform will not modify anything, return the other */ - return composeWith; - } - - @Override - public boolean equals(Object other) { - return other.getClass().equals(TmfTimestampTransform.class); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + TmfTimestampTransform.class.hashCode(); - return result; - } - - @Override - public String toString() { - return "TmfTimestampTransform [ IDENTITY ]"; //$NON-NLS-1$ - } - - @Override - public ITmfTimestampTransform inverse() { - return IDENTITY; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/TmfTimestampTransformLinear.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/TmfTimestampTransformLinear.java deleted file mode 100644 index 7deb551831..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/TmfTimestampTransformLinear.java +++ /dev/null @@ -1,150 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.synchronization; - -import java.math.BigDecimal; -import java.math.MathContext; - -import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform; -import org.eclipse.linuxtools.tmf.core.synchronization.TimestampTransformFactory; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; - -/** - * Class implementing a linear timestamp transform, with a slope and/or offset - * - * f(t) = alpha*t + beta - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfTimestampTransformLinear implements ITmfTimestampTransformInvertible { - - /** - * Generated serial UID - */ - private static final long serialVersionUID = -4756608071358979461L; - - /** - * Respectively the slope and offset and this linear equation. - */ - private final BigDecimal fAlpha; - private final BigDecimal fBeta; - - private static final MathContext fMc = MathContext.DECIMAL128; - - /** - * Default constructor - */ - public TmfTimestampTransformLinear() { - fAlpha = BigDecimal.ONE; - fBeta = BigDecimal.ZERO; - } - - /** - * Constructor with alpha and beta - * - * @param alpha - * The slope of the linear transform - * @param beta - * The initial offset of the linear transform - */ - public TmfTimestampTransformLinear(final double alpha, final double beta) { - fAlpha = BigDecimal.valueOf(alpha); - fBeta = BigDecimal.valueOf(beta); - } - - /** - * Constructor with alpha and beta in big decimal - * - * @param fAlpha2 - * The slope of the linear transform - * @param fBeta2 - * The initial offset of the linear transform - */ - public TmfTimestampTransformLinear(final BigDecimal fAlpha2, final BigDecimal fBeta2) { - if (fAlpha2 != null) { - fAlpha = fAlpha2; - } else { - fAlpha = BigDecimal.ONE; - } - if (fBeta2 != null) { - fBeta = fBeta2; - } else { - fBeta = BigDecimal.ZERO; - } - } - - @Override - public ITmfTimestamp transform(ITmfTimestamp timestamp) { - BigDecimal newvalue = BigDecimal.valueOf(timestamp.getValue()).multiply(fAlpha, fMc).add(fBeta); - return new TmfTimestamp(timestamp, newvalue.longValue()); - } - - @Override - public long transform(long timestamp) { - BigDecimal t = BigDecimal.valueOf(timestamp).multiply(fAlpha, fMc).add(fBeta); - return t.longValue(); - } - - @Override - public ITmfTimestampTransform composeWith(ITmfTimestampTransform composeWith) { - if (composeWith.equals(TmfTimestampTransform.IDENTITY)) { - /* If composing with identity, just return this */ - return this; - } else if (composeWith instanceof TmfTimestampTransformLinear) { - /* If composeWith is a linear transform, add the two together */ - TmfTimestampTransformLinear ttl = (TmfTimestampTransformLinear) composeWith; - BigDecimal newAlpha = fAlpha.multiply(ttl.fAlpha, fMc); - BigDecimal newBeta = fAlpha.multiply(ttl.fBeta, fMc).add(fBeta); - return TimestampTransformFactory.createLinear(newAlpha, newBeta); - } else { - /* - * We do not know what to do with this kind of transform, just - * return this - */ - return this; - } - } - - @Override - public boolean equals(Object other) { - boolean result = false; - if (other instanceof TmfTimestampTransformLinear) { - TmfTimestampTransformLinear that = (TmfTimestampTransformLinear) other; - result = ((that.fAlpha.equals(fAlpha)) && (that.fBeta.equals(fBeta))); - } - return result; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + (fBeta.multiply(fAlpha).intValue()); - return result; - } - - @Override - public String toString() { - return "TmfTimestampLinear [ slope = " + fAlpha.toString() + //$NON-NLS-1$ - ", offset = " + fBeta.toString() + //$NON-NLS-1$ - " ]"; //$NON-NLS-1$ - } - - @Override - public ITmfTimestampTransform inverse() { - return TimestampTransformFactory.createLinear(BigDecimal.ONE.divide(fAlpha, fMc), BigDecimal.valueOf(-1).multiply(fBeta).divide(fAlpha, fMc)); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/graph/Edge.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/graph/Edge.java deleted file mode 100644 index f2afb7babb..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/graph/Edge.java +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francis Giraldeau - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.synchronization.graph; - -/** - * An edge in the {@link SyncGraph} - * - * @author Francis Giraldeau - * @param - * The vertices type - * @param - * The edge annotation type - */ -public class Edge { - - private final V fFrom; - private final V fTo; - private final E fLabel; - - /** - * An edge constructor - * - * @param from - * The origin vertex - * @param to - * The destination vertex - * @param label - * The edge annotation label - */ - public Edge(V from, V to, E label) { - fFrom = from; - fTo = to; - fLabel = label; - } - - /** - * Get the vertex from - * - * @return The origin vertex - */ - public V getFrom() { - return fFrom; - } - - /** - * Get the vertex to - * - * @return The destination vertex - */ - public V getTo() { - return fTo; - } - - /** - * Get the edge label - * - * @return The edge label - */ - public E getLabel() { - return fLabel; - } - - @Override - public String toString() { - return String.format("(%s, %s, %s)", fFrom, fTo, fLabel); //$NON-NLS-1$ - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/graph/SyncGraph.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/graph/SyncGraph.java deleted file mode 100644 index 2fc5c88ee9..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/graph/SyncGraph.java +++ /dev/null @@ -1,179 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francis Giraldeau - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.synchronization.graph; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; -import java.util.Set; -import java.util.Stack; - -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Multimap; - -/** - * Minimal graph implementation to compute timestamps transforms of a trace from - * a given synchronized set of traces. The graph is implemented as an adjacency - * list and is directed. To create undirected graph, add the edge in both - * directions. - * - * @author Francis Giraldeau - * @param - * The vertices type - * @param - * The edge annotation type - */ -public class SyncGraph { - - private Multimap> fAdjacentEdges; - private Set fVertices; - - /** - * Construct empty graph - */ - public SyncGraph() { - fAdjacentEdges = ArrayListMultimap.create(); - fVertices = new HashSet<>(); - } - - /** - * Add edge from v to w and annotation label - * - * @param from - * from vertex - * @param to - * to vertex - * @param label - * the edge label - */ - public void addEdge(V from, V to, E label) { - fAdjacentEdges.put(from, new Edge<>(from, to, label)); - fVertices.add(from); - fVertices.add(to); - } - - /** - * Get the number of edges - * - * @return number of edges - */ - public int getNbEdges() { - return fAdjacentEdges.entries().size(); - } - - /** - * Get the number of vertices - * - * @return number of vertices - */ - public int getNbVertices() { - return fVertices.size(); - } - - /** - * Returns the adjacent edges of the given vertex - * - * @param v - * the vertex - * @return the adjacent vertices - */ - public Collection> getAdjacentEdges(V v) { - return fAdjacentEdges.get(v); - } - - /** - * Returns a path between start and end vertices. - * - * @param start - * vertex - * @param end - * vertex - * @return the list of edges between start and end vertices - */ - public List> path(V start, V end) { - ArrayList> path = new ArrayList<>(); - HashMap> hist = new HashMap<>(); - HashSet visited = new HashSet<>(); - Queue queue = new LinkedList<>(); - queue.offer(start); - /** - * Build the map of nodes reachable from the start node, by recursively - * visiting all accessible nodes. It is a breadth-first search, so the - * edges kept for each node will be the shortest path to that node. - */ - while (!queue.isEmpty()) { - V node = queue.poll(); - visited.add(node); - for (Edge e : getAdjacentEdges(node)) { - V to = e.getTo(); - if (!visited.contains(to)) { - queue.offer(e.getTo()); - if (!hist.containsKey(e.getTo())) { - hist.put(e.getTo(), e); - } - } - } - } - /* - * Find path from start to end by traversing the edges backward, from - * the end node - */ - V node = end; - Edge edge = hist.get(node); - while (edge != null && node != start) { - path.add(edge); - node = edge.getFrom(); - edge = hist.get(node); - } - Collections.reverse(path); - return path; - } - - /** - * Check if this graph is connected, ie there are no partitions, all - * vertices are reachable from every other one. It is a depth-first visit of - * all vertices reachable from the first vertex of the graph. - * - * @return true if the graph is connected, false otherwise - */ - public boolean isConnected() { - HashSet visited = new HashSet<>(); - Stack stack = new Stack<>(); - stack.push(fVertices.iterator().next()); - while (!stack.isEmpty()) { - V node = stack.pop(); - visited.add(node); - for (Edge edge : getAdjacentEdges(node)) { - if (!visited.contains(edge.getTo())) { - stack.push(edge.getTo()); - } - } - } - return visited.size() == fVertices.size(); - } - - @Override - public String toString() { - StringBuilder str = new StringBuilder(); - for (V key : fAdjacentEdges.keySet()) { - str.append(key + ": " + fAdjacentEdges.get(key) + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ - } - return str.toString(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/graph/SyncSpanningTree.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/graph/SyncSpanningTree.java deleted file mode 100644 index 8013c96e4d..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/synchronization/graph/SyncSpanningTree.java +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.synchronization.graph; - -import java.math.BigDecimal; -import java.util.List; -import java.util.SortedSet; -import java.util.TreeSet; - -import org.eclipse.linuxtools.internal.tmf.core.synchronization.ITmfTimestampTransformInvertible; -import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform; -import org.eclipse.linuxtools.tmf.core.synchronization.TimestampTransformFactory; - -/** - * Implements a tree to calculate the synchronization between hosts - * - * TODO: This minimal implementation does not take into account the accuracy of - * the synchronization or the number of hops between 2 traces. A great - * improvement would be to implement Masoume Jabbarifar's minimal spanning tree - * algorithm to select reference trace(s) and optimal path to each node of the - * tree. - * - * @author Geneviève Bastien - */ -public class SyncSpanningTree { - - private final SyncGraph fSyncGraph; - - /* - * Using a TreeSet here to make sure the order of the hosts, and thus the - * reference node, is predictable, mostly for unit tests. - */ - private SortedSet fHosts = new TreeSet<>(); - - /** - * Default constructor - */ - public SyncSpanningTree() { - fSyncGraph = new SyncGraph<>(); - } - - /** - * Add a synchronization formula between hostFrom and hostTo with a given - * accuracy - * - * @param hostFrom - * Host from which the transform applies - * @param hostTo - * Host to which the transform applies - * @param transform - * The timestamp transform - * @param accuracy - * The accuracy of the synchronization between hostFrom and - * hostTo - */ - public void addSynchronization(String hostFrom, String hostTo, ITmfTimestampTransform transform, BigDecimal accuracy) { - fHosts.add(hostFrom); - fHosts.add(hostTo); - fSyncGraph.addEdge(hostFrom, hostTo, transform); - if (transform instanceof ITmfTimestampTransformInvertible) { - fSyncGraph.addEdge(hostTo, hostFrom, ((ITmfTimestampTransformInvertible) transform).inverse()); - } - } - - /** - * Get the timestamp transform to a host - * - * FIXME: This might not work in situations where we have disjoint graphs - * since we only calculate 1 root node and each tree has its own root. When - * implementing the algorithm with minimal spanning tree, we will solve this - * problem. - * - * @param host - * The host to reach - * @return The timestamp transform to host - */ - public ITmfTimestampTransform getTimestampTransform(String host) { - ITmfTimestampTransform result = TimestampTransformFactory.getDefaultTransform(); - String rootNode = getRootNode(); - /* - * Compute the path from reference node to the given host id - */ - if (rootNode != null) { - List> path = fSyncGraph.path(rootNode, host); - /* - * Compute the resulting transform by chaining each transforms on - * the path. - */ - for (Edge edge : path) { - result = result.composeWith(edge.getLabel()); - } - } - return result; - } - - private String getRootNode() { - /** - * Get the root node from which all other paths will be calculated. For - * now, we take the first node alphabetically. - */ - if (fHosts.size() == 0) { - return null; - } - return fHosts.first(); - } - - /** - * Check if this multi-host synchronization tree is connected, ie all nodes - * have a synchronization path to a reference node. - * - * @return true if the tree is connected, false otherwise - */ - public boolean isConnected() { - return fSyncGraph.isConnected(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/TmfExperimentCheckpoint.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/TmfExperimentCheckpoint.java deleted file mode 100644 index faa88d1e47..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/TmfExperimentCheckpoint.java +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.trace; - -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.TmfContext; - -/** - * TmfExperimentCheckpoint - *

- * TODO: Implement me. Please. - */ -public class TmfExperimentCheckpoint implements Comparable { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final TmfTimestamp fTimestamp; - private final long[] fRanks; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * @param ts the checkpoint timestamp - * @param contexts the corresponding set of trace contexts - */ - public TmfExperimentCheckpoint(final TmfTimestamp ts, final TmfContext[] contexts) { - fTimestamp = ts; - fRanks = new long[contexts.length]; - for (int i = 0; i < fRanks.length; i++) { - fRanks[i] = contexts[i].getRank(); - } - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * @return the checkpoint event timestamp - */ - public TmfTimestamp getTimestamp() { - return fTimestamp; - } - - /** - * @return the checkpoint event rank - */ - public long[] getRanks() { - return fRanks; - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - int result = 37; - result = 17 * result + fTimestamp.hashCode(); - return result; - } - - @Override - public boolean equals(final Object other) { - if (!(other instanceof TmfExperimentCheckpoint)) { - return false; - } - final TmfExperimentCheckpoint o = (TmfExperimentCheckpoint) other; - return fTimestamp.equals(o.fTimestamp); - } - - // ------------------------------------------------------------------------ - // Comparable - // ------------------------------------------------------------------------ - - @Override - public int compareTo(final TmfExperimentCheckpoint other) { - return fTimestamp.compareTo(other.fTimestamp, false); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/TmfExperimentContext.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/TmfExperimentContext.java deleted file mode 100644 index bfeafba49f..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/TmfExperimentContext.java +++ /dev/null @@ -1,224 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Put in shape for 1.0 - * Patrick Tasse - Updated for removal of context clone - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.trace; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.TmfContext; - -/** - * The experiment context in TMF. - *

- * The experiment keeps track of the next event from each of its traces so it - * can pick the next one in chronological order. - *

- * This implies that the "next" event from each trace has already been - * read and that we at least know its timestamp. - *

- * The last trace refers to the trace from which the last event was "consumed" - * at the experiment level. - */ -public final class TmfExperimentContext extends TmfContext { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * No last trace read indicator - */ - public static final int NO_TRACE = -1; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final List fContexts; - private final List fEvents; - private int fLastTraceRead; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Standard constructor - * - * @param nbTraces - * The number of traces in the experiment - */ - public TmfExperimentContext(final int nbTraces) { - super(); - fLastTraceRead = NO_TRACE; - fContexts = new ArrayList<>(nbTraces); - fEvents = new ArrayList<>(nbTraces); - - - /* Initialize the arrays to the requested size */ - for (int i = 0; i < nbTraces; i++) { - fContexts.add(null); - fEvents.add(null); - } - } - - @Override - public void dispose() { - for (ITmfContext context : fContexts) { - context.dispose(); - } - super.dispose(); - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Return how many traces this experiment context tracks the contexts of - * (a.k.a., the number of traces in the experiment). - * - * @return The number of traces in the experiment - */ - public int getNbTraces() { - return fContexts.size(); - } - - /** - * Get the current context of a specific trace - * - * @param traceIndex - * The index of the trace in the experiment - * @return The matching context object for that trace - */ - @Nullable - public ITmfContext getContext(int traceIndex) { - return fContexts.get(traceIndex); - } - - /** - * Set the context of a trace - * - * @param traceIndex - * The index of the trace in the experiment - * @param ctx - * The new context object for that trace - */ - public void setContext(int traceIndex, ITmfContext ctx) { - fContexts.set(traceIndex, ctx); - } - - /** - * Get the current event for a specific trace in the experiment. - * - * @param traceIndex - * The index of the trace in the experiment - * @return The event matching the trace/context - * - */ - @Nullable - public ITmfEvent getEvent(int traceIndex) { - return fEvents.get(traceIndex); - } - - /** - * Set the context's event for a specific trace - * - * @param traceIndex - * The index of the trace in the experiment - * @param event - * The event at the context in the trace - */ - public void setEvent(int traceIndex, ITmfEvent event) { - fEvents.set(traceIndex, event); - } - - /** - * Get the index of the trace that was last read (so the trace whose - * current context will match this experiment's). - * - * @return The index of the trace - */ - public int getLastTrace() { - return fLastTraceRead; - } - - /** - * Set the last trace read index - * - * @param newIndex - * The new value to assign - */ - public void setLastTrace(final int newIndex) { - fLastTraceRead = newIndex; - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - int result = 17; - for (int i = 0; i < fContexts.size(); i++) { - result = 37 * result + fContexts.get(i).hashCode(); - } - return result; - } - - @Override - public boolean equals(final Object other) { - if (this == other) { - return true; - } - if (!super.equals(other)) { - return false; - } - if (!(other instanceof TmfExperimentContext)) { - return false; - } - final TmfExperimentContext o = (TmfExperimentContext) other; - boolean isEqual = true; - int i = 0; - while (isEqual && (i < fContexts.size())) { - isEqual &= fContexts.get(i).equals(o.fContexts.get(i)); - i++; - } - return isEqual; - } - - @Override - @SuppressWarnings("nls") - public String toString() { - StringBuilder sb = new StringBuilder("TmfExperimentContext [\n"); - sb.append("\tfLocation=" + getLocation() + ", fRank=" + getRank() + "\n"); - sb.append("\tfContexts=["); - for (int i = 0; i < fContexts.size(); i++) { - sb.append("(" + fContexts.get(i).getLocation() + "," + fContexts.get(i).getRank() + ((i < fContexts.size() - 1) ? ")," : ")]\n")); - } - sb.append("\tfEvents=["); - for (int i = 0; i < fEvents.size(); i++) { - ITmfEvent event = fEvents.get(i); - sb.append(((event != null) ? fEvents.get(i).getTimestamp() : "(null)") + ((i < fEvents.size() - 1) ? "," : "]\n")); - } - sb.append("\tfLastTraceRead=" + fLastTraceRead + "\n"); - sb.append("]"); - return sb.toString(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/TmfExperimentLocation.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/TmfExperimentLocation.java deleted file mode 100644 index 4f6edec3c4..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/TmfExperimentLocation.java +++ /dev/null @@ -1,120 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Updated as per TMF Trace Model 1.0 - * Patrick Tasse - Updated for ranks in experiment location - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.trace; - -import java.nio.ByteBuffer; - -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - - -/** - * The experiment location in TMF. - *

- * An experiment location is actually the set of locations of the traces it - * contains. By setting the individual traces to their corresponding locations, - * the experiment can be positioned to read the next chronological event. - *

- * It is the responsibility of the user the individual trace locations are valid - * and that they are matched to the correct trace. - * - * @version 1.0 - * @author Francois Chouinard - * - * @see TmfLocationArray - */ -public final class TmfExperimentLocation implements ITmfLocation { - - private final TmfLocationArray fLocation; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * The standard constructor - * - * @param locations the set of trace locations - */ - public TmfExperimentLocation(TmfLocationArray locations) { - fLocation = locations; - } - - /** - * The copy constructor - * - * @param location the other experiment location - */ - public TmfExperimentLocation(TmfExperimentLocation location) { - this(location.getLocationInfo()); - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - @SuppressWarnings("nls") - public String toString() { - StringBuilder result = new StringBuilder("TmfExperimentLocation ["); - result.append(fLocation.toString()); - result.append("]"); - return result.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((fLocation != null) ? fLocation.hashCode() : 0); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final TmfExperimentLocation other = (TmfExperimentLocation) obj; - if (fLocation == null) { - if (other.fLocation != null) { - return false; - } - } else if (!fLocation.equals(other.fLocation)) { - return false; - } - return true; - } - - @Override - public TmfLocationArray getLocationInfo() { - return fLocation; - } - - @Override - public void serialize(ByteBuffer bufferOut) { - ITmfLocation[] locations = fLocation.getLocations(); - long[] ranks = fLocation.getRanks(); - for (int i = 0; i < locations.length; ++i) { - locations[i].serialize(bufferOut); - bufferOut.putLong(ranks[i]); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/TmfLocationArray.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/TmfLocationArray.java deleted file mode 100644 index a9abc076dc..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/TmfLocationArray.java +++ /dev/null @@ -1,204 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Francois Chouinard - Put in shape for 1.0 - * Patrick Tasse - Updated for ranks in experiment location - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.trace; - -import java.util.Arrays; - -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - - -/** - * A convenience class to store trace location arrays. The main purpose is to - * provide an immutable and Comparable implementation for TmfExperimentLocation. - * - * @version 1.0 - * @author Patrick Tasse - */ -public final class TmfLocationArray implements Comparable { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final ITmfLocation[] fLocations; - private final long [] fRanks; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * The standard constructor. - * - * @param locations the locations - * @param ranks the ranks - */ - public TmfLocationArray(ITmfLocation[] locations, long[] ranks) { - fLocations = Arrays.copyOf(locations, locations.length); - fRanks = Arrays.copyOf(ranks, ranks.length); - } - - /** - * The update constructor. Copies the arrays and updates a single entry. - * - * @param locationArray the location array - * @param index the updated index - * @param location the updated location - * @param rank the updated rank - */ - public TmfLocationArray(TmfLocationArray locationArray, int index, ITmfLocation location, long rank) { - fLocations = Arrays.copyOf(locationArray.fLocations, locationArray.fLocations.length); - fLocations[index] = location; - fRanks = Arrays.copyOf(locationArray.fRanks, locationArray.fRanks.length); - fRanks[index] = rank; - } - - /** - * The empty constructor. - * - * @param size the number of elements in the array - */ - public TmfLocationArray(int size) { - fLocations = new ITmfLocation[size]; - fRanks = new long[size]; - } - - // ------------------------------------------------------------------------ - // Getters - // ------------------------------------------------------------------------ - - /** - * Returns the number of elements in this array. - * - * @return the number of elements in this array - */ - public int size() { - return fLocations.length; - } - - /** - * Get the locations inside this array. - * - * @return a copy of the locations array - */ - public ITmfLocation[] getLocations() { - return Arrays.copyOf(fLocations, fLocations.length); - } - - /** - * Get a specific location - * - * @param index the location element - * - * @return the specific location (possibly null) - */ - public ITmfLocation getLocation(int index) { - if (index >= 0 && index < fLocations.length) { - return fLocations[index]; - } - return null; - } - - /** - * Get the ranks inside this array. - * - * @return a copy of the ranks array - */ - public long[] getRanks() { - return Arrays.copyOf(fRanks, fRanks.length); - } - - /** - * Get a specific rank - * - * @param index the rank element - * - * @return the specific rank - */ - public long getRank(int index) { - if (index >= 0 && index < fRanks.length) { - return fRanks[index]; - } - return 0; - } - - // ------------------------------------------------------------------------ - // Comparable - // ------------------------------------------------------------------------ - - @Override - public int compareTo(TmfLocationArray o) { - for (int i = 0; i < fRanks.length; i++) { - long rank1 = fRanks[i]; - long rank2 = o.fRanks[i]; - if (rank1 < rank2) { - return -1; - } else if (rank1 > rank2) { - return 1; - } - } - return 0; - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + Arrays.hashCode(fLocations); - result = prime * result + Arrays.hashCode(fRanks); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TmfLocationArray other = (TmfLocationArray) obj; - if (!Arrays.equals(fLocations, other.fLocations)) { - return false; - } - if (!Arrays.equals(fRanks, other.fRanks)) { - return false; - } - return true; - } - - @Override - @SuppressWarnings("nls") - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(getClass().getSimpleName() + " ["); - for (int i = 0; i < fLocations.length; i++) { - if (i > 0) { - sb.append(", "); - } - sb.append("[location=" + fLocations[i] + ",rank=" + fRanks[i] + "]"); - } - sb.append("]"); - return sb.toString(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/AbstractFileCheckpointCollection.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/AbstractFileCheckpointCollection.java deleted file mode 100644 index 77832f1174..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/AbstractFileCheckpointCollection.java +++ /dev/null @@ -1,478 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.trace.indexer; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; -import java.text.MessageFormat; - -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfPersistentlyIndexable; - -/** - * Common implementation of file-based checkpoint collection - * - * @author Marc-Andre Laperle - */ -public abstract class AbstractFileCheckpointCollection implements ICheckpointCollection { - - private static final int VERSION = 1; - private static final int SUB_VERSION_NONE = -1; - - /** - * The base file header, can be extended - */ - protected class CheckpointCollectionFileHeader { - private final static int SIZE = INT_SIZE + - INT_SIZE + - LONG_SIZE + - LONG_SIZE; - - /** - * Get the size of the header in bytes. This should be overridden if the - * header is augmented with more data - * - * @return the size of the header in bytes - */ - public int getSize() { - return SIZE; - } - - /** - * Get the sub version of this header - * - * @return the sub version - */ - public int getSubVersion() { - return SUB_VERSION_NONE; - } - - /** - * Constructs a new file header for an existing file - * - * @param randomAccessFile - * the existing file - * @throws IOException - * if an I/O error occurs reading from the file - */ - public CheckpointCollectionFileHeader(RandomAccessFile randomAccessFile) throws IOException { - fVersion = randomAccessFile.readInt(); - fSize = randomAccessFile.readInt(); - fNbEvents = randomAccessFile.readLong(); - fTimeRangeOffset = randomAccessFile.readLong(); - } - - /** - * Constructs a new file header for the given version - * - * @param version - * the version - */ - public CheckpointCollectionFileHeader(int version) { - fVersion = version; - } - - /** - * Serialize the header to a file - * - * @param randomAccessFile - * the existing file - * @throws IOException - * if an I/O error occurs writing to the file - */ - public void serialize(RandomAccessFile randomAccessFile) throws IOException { - randomAccessFile.seek(0); - randomAccessFile.writeInt(getVersion()); - randomAccessFile.writeInt(fSize); - randomAccessFile.writeLong(fNbEvents); - randomAccessFile.writeLong(fTimeRangeOffset); - } - - /** - * The version of the collection. Should be incremented if a binary - * incompatible change occurs. - */ - protected final int fVersion; - /** - * The size of the collection expressed in a number of checkpoints. - */ - protected int fSize = 0; - /** - * Offset in bytes where the time range is store - */ - protected long fTimeRangeOffset; - /** - * The total number of events in the trace - */ - protected long fNbEvents; - } - - /** - * The size of an int in bytes - */ - protected static final int INT_SIZE = 4; - /** - * The size of a long in bytes - */ - protected static final int LONG_SIZE = 8; - - /** - * The maximum size of the serialize buffer when writing the time range - */ - protected static final int MAX_TIME_RANGE_SERIALIZE_SIZE = 1024; - - /** - * The originating trace - */ - private ITmfPersistentlyIndexable fTrace; - - private long fCacheMisses = 0; - private boolean fCreatedFromScratch; - - /** - * File handle for the file being read/written - */ - private RandomAccessFile fRandomAccessFile; - /** - * File handle for the file being read/written - */ - private File fFile; - - /** - * The base file header - */ - private final CheckpointCollectionFileHeader fHeader; - - // Cached values - private FileChannel fFileChannel; - private TmfTimeRange fTimeRange; - - /** - * Constructs a checkpoint collection for a given trace from scratch or from - * an existing file. When the checkpoint collection is created from scratch, - * it is populated by subsequent calls to {@link #insert}. - * - * @param file - * the file to use as the persistent storage - * @param trace - * the trace - */ - public AbstractFileCheckpointCollection(File file, ITmfPersistentlyIndexable trace) { - fTrace = trace; - fFile = file; - setCreatedFromScratch(!fFile.exists()); - - CheckpointCollectionFileHeader header = null; - - if (!isCreatedFromScratch()) { - header = tryRestore(); - if (header == null) { - fFile.delete(); - dispose(); - } - } - - if (isCreatedFromScratch()) { - header = initialize(); - } - - fHeader = header; - } - - /** - * Creates a new basic file header with the version field initialized. This - * should be overridden if the file header is extended - * - * @return the created file header - */ - protected CheckpointCollectionFileHeader createHeader() { - return new CheckpointCollectionFileHeader(VERSION); - } - - /** - * Creates a new basic file header for an existing file. This should be - * overridden if the file header is extended - * - * @param randomAccessFile - * the existing file - * @return the created file header - * @throws IOException - * if an I/O error occurs reading from the file - */ - protected CheckpointCollectionFileHeader createHeader(RandomAccessFile randomAccessFile) throws IOException { - return new CheckpointCollectionFileHeader(randomAccessFile); - } - - /** - * Get the version of the collection. - * - * @return the version of the collection. - */ - protected int getVersion() { - return VERSION; - } - - /** - * Get the sub version of the collection. - * - * @return the sub version of the collection. - */ - protected int getSubVersion() { - return SUB_VERSION_NONE; - } - - private CheckpointCollectionFileHeader initialize() { - CheckpointCollectionFileHeader header = null; - try { - fRandomAccessFile = new RandomAccessFile(fFile, "rw"); //$NON-NLS-1$ - fFileChannel = fRandomAccessFile.getChannel(); - header = createHeader(); - - // Reserve space for header - fRandomAccessFile.setLength(header.getSize()); - - fTimeRange = new TmfTimeRange(new TmfTimestamp(0), new TmfTimestamp(0)); - } catch (IOException e) { - Activator.logError(MessageFormat.format(Messages.ErrorOpeningIndex, fFile), e); - return null; - } - - return header; - } - - /** - * Try to restore the index from disk. Try to open the file and check the - * version. Returns the loaded header or null if it could not be loaded. - * - * @return the loaded header or null if it could not be loaded. - */ - private CheckpointCollectionFileHeader tryRestore() { - CheckpointCollectionFileHeader header = null; - - try { - fRandomAccessFile = new RandomAccessFile(fFile, "r"); //$NON-NLS-1$ - fFileChannel = fRandomAccessFile.getChannel(); - } catch (FileNotFoundException e) { - Activator.logError(MessageFormat.format(Messages.ErrorOpeningIndex, fFile), e); - return null; - } - - try { - header = createHeader(fRandomAccessFile); - if (header.fVersion != VERSION || header.getSubVersion() != getSubVersion()) { - return null; - } - serializeInTimeRange(header); - } catch (IOException e) { - Activator.logError(MessageFormat.format(Messages.IOErrorReadingHeader, fFile), e); - return null; - } - - return header; - } - - private void serializeInTimeRange(CheckpointCollectionFileHeader header) throws IOException { - ByteBuffer b = ByteBuffer.allocate(MAX_TIME_RANGE_SERIALIZE_SIZE); - b.clear(); - fFileChannel.read(b, header.fTimeRangeOffset); - b.flip(); - fTimeRange = new TmfTimeRange(new TmfTimestamp(b), new TmfTimestamp(b)); - } - - private void serializeOutTimeRange() throws IOException { - fHeader.fTimeRangeOffset = fRandomAccessFile.length(); - ByteBuffer b = ByteBuffer.allocate(MAX_TIME_RANGE_SERIALIZE_SIZE); - b.clear(); - new TmfTimestamp(fTimeRange.getStartTime()).serialize(b); - new TmfTimestamp(fTimeRange.getEndTime()).serialize(b); - b.flip(); - fFileChannel.write(b, fHeader.fTimeRangeOffset); - } - - /** - * Set the index as complete. No more checkpoints will be inserted. - */ - @Override - public void setIndexComplete() { - try { - serializeOutTimeRange(); - - fHeader.serialize(fRandomAccessFile); - } catch (IOException e) { - Activator.logError(MessageFormat.format(Messages.IOErrorWritingHeader, fFile), e); - } - } - - /** - * - * @return true if the checkpoint collection was created from scratch, false - * otherwise - */ - @Override - public boolean isCreatedFromScratch() { - return fCreatedFromScratch; - } - - /** - * Set whether or not the collection is created from scratch - * - * @param isCreatedFromScratch - * whether or not the collection is created from scratch - */ - protected void setCreatedFromScratch(boolean isCreatedFromScratch) { - fCreatedFromScratch = isCreatedFromScratch; - } - - /** - * @return the number of cache misses. - */ - public long getCacheMisses() { - return fCacheMisses; - } - - /** - * Increment the number of cache misses. - */ - protected void incCacheMisses() { - ++fCacheMisses; - } - - /** - * Returns the size of the checkpoint collection expressed as a number of - * checkpoints. - * - * @return the size of the checkpoint collection - */ - @Override - public int size() { - return fHeader.fSize; - } - - /** - * Set the trace time range - * - * @param timeRange - * the trace time range - */ - @Override - public void setTimeRange(TmfTimeRange timeRange) { - fTimeRange = timeRange; - } - - /** - * Get the trace time range - * - * @return the trace time range - */ - @Override - public TmfTimeRange getTimeRange() { - return fTimeRange; - } - - /** - * Set the number of events in the trace - * - * @param nbEvents - * the number of events in the trace - */ - @Override - public void setNbEvents(long nbEvents) { - fHeader.fNbEvents = nbEvents; - } - - /** - * Get the number of events in the trace - * - * @return the number of events in the trace - */ - @Override - public long getNbEvents() { - return fHeader.fNbEvents; - } - - /** - * Get the trace - * - * @return the trace - */ - protected ITmfPersistentlyIndexable getTrace() { - return fTrace; - } - - /** - * Get the random access file currently opened - * - * @return the file - */ - protected RandomAccessFile getRandomAccessFile() { - return fRandomAccessFile; - } - - /** - * Get the file channel currently used for the index - * - * @return the file channel - */ - protected FileChannel getFileChannel() { - return fRandomAccessFile.getChannel(); - } - - /** - * Get the file handle for the index - * - * @return the file - */ - protected File getFile() { - return fFile; - } - - /** - * Get the header for this collection - * - * @return the header - */ - public CheckpointCollectionFileHeader getHeader() { - return fHeader; - }/** - * Dispose and delete the checkpoint collection - */ - @Override - public void delete() { - dispose(); - if (fFile.exists()) { - fFile.delete(); - } - } - - /** - * Dispose the collection and its resources - */ - @Override - public void dispose() { - try { - if (fRandomAccessFile != null) { - fRandomAccessFile.close(); - } - setCreatedFromScratch(true); - fRandomAccessFile = null; - } catch (IOException e) { - Activator.logError(MessageFormat.format(Messages.IOErrorClosingIndex, fFile), e); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/BTree.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/BTree.java deleted file mode 100644 index d5d524207d..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/BTree.java +++ /dev/null @@ -1,383 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.trace.indexer; - -import java.io.File; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; -import java.text.MessageFormat; - -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfPersistentlyIndexable; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; - -/** - * A BTree made of BTreeNodes representing a series of ITmfCheckpoints ordered - * by time stamps. {@link BTreeNodeCache } is used to improve performance by - * caching some nodes in memory and the other nodes are kept on disk. - * - * @author Marc-Andre Laperle - */ -public class BTree extends AbstractFileCheckpointCollection { - - /** - * Typical BTree file name - */ - public static final String INDEX_FILE_NAME = "checkpoint_btree.idx"; //$NON-NLS-1$ - private static final int SUB_VERSION = 4; - private static final boolean ALWAYS_CACHE_ROOT = true; - - private final int fMaxNumEntries; - private final int fMaxNumChildren; - private final int fMedianEntry; - - private BTreeHeader fBTreeHeader; - - // Cached values - private int nodeSize = -1; - private final ByteBuffer fNodeByteBuffer; - private final BTreeNodeCache fNodeCache; - - private class BTreeHeader extends CheckpointCollectionFileHeader { - private static final int SIZE = LONG_SIZE + INT_SIZE; - private long fRoot; - private final int fSubVersion; - - private BTreeHeader(int version, int subVersion) { - super(version); - fSubVersion = subVersion; - } - - private BTreeHeader(RandomAccessFile randomAccessFile) throws IOException { - super(randomAccessFile); - - fRoot = randomAccessFile.readLong(); - fSubVersion = randomAccessFile.readInt(); - } - - @Override - public int getSubVersion() { - return fSubVersion; - } - - @Override - public int getSize() { - return SIZE + super.getSize(); - } - - @Override - public void serialize(RandomAccessFile randomAccessFile) throws IOException { - super.serialize(randomAccessFile); - - randomAccessFile.writeLong(fRoot); - randomAccessFile.writeInt(fSubVersion); - } - } - - @Override - protected CheckpointCollectionFileHeader createHeader() { - fBTreeHeader = new BTreeHeader(getVersion(), SUB_VERSION); - return fBTreeHeader; - } - - @Override - protected CheckpointCollectionFileHeader createHeader(RandomAccessFile randomAccessFile) throws IOException { - fBTreeHeader = new BTreeHeader(randomAccessFile); - return fBTreeHeader; - } - - @Override - protected int getSubVersion() { - return SUB_VERSION; - } - - /** - * Constructs a BTree for a given trace from scratch or from an existing - * file. The degree is used to calibrate the number of entries in each node - * which can affect performance. When the BTree is created from scratch, it - * is populated by subsequent calls to {@link #insert}. - * - * @param degree - * the degree to use in the tree - * @param file - * the file to use as the persistent storage - * @param trace - * the trace - */ - public BTree(int degree, File file, ITmfPersistentlyIndexable trace) { - super(file, trace); - - fMaxNumEntries = 2 * degree - 1; - fMaxNumChildren = 2 * degree; - fMedianEntry = degree - 1; - - fNodeByteBuffer = ByteBuffer.allocate(getNodeSize()); - fNodeByteBuffer.clear(); - fNodeCache = new BTreeNodeCache(this); - BTreeNode rootNode = isCreatedFromScratch() ? allocateNode() : fNodeCache.getNode(fBTreeHeader.fRoot); - setRootNode(rootNode); - } - - /** - * Insert a checkpoint into the file-backed BTree - * - * @param checkpoint - * the checkpoint to insert - */ - @Override - public void insert(ITmfCheckpoint checkpoint) { - insert(checkpoint, fBTreeHeader.fRoot, null, 0); - } - - private void setRootNode(BTreeNode newRootNode) { - fBTreeHeader.fRoot = newRootNode.getOffset(); - if (ALWAYS_CACHE_ROOT) { - fNodeCache.setRootNode(newRootNode); - } else { - fNodeCache.addNode(newRootNode); - } - } - - private void insert(ITmfCheckpoint checkpoint, long nodeOffset, BTreeNode pParent, int iParent) { - BTreeNode parent = pParent; - BTreeNode node = fNodeCache.getNode(nodeOffset); - - // If this node is full (last entry isn't null), split it - if (node.getEntry(fMaxNumEntries - 1) != null) { - - ITmfCheckpoint median = node.getEntry(fMedianEntry); - if (median.compareTo(checkpoint) == 0) { - // Found it - return; - } - - // Split it. - // Create the new node and move the larger entries over. - BTreeNode newnode = allocateNode(); - fNodeCache.addNode(newnode); - long newNodeOffset = newnode.getOffset(); - for (int i = 0; i < fMedianEntry; ++i) { - newnode.setEntry(i, node.getEntry(fMedianEntry + 1 + i)); - node.setEntry(fMedianEntry + 1 + i, null); - newnode.setChild(i, node.getChild(fMedianEntry + 1 + i)); - node.setChild(fMedianEntry + 1 + i, BTreeNode.NULL_CHILD); - } - newnode.setChild(fMedianEntry, node.getChild(fMaxNumEntries)); - node.setChild(fMaxNumEntries, BTreeNode.NULL_CHILD); - - if (parent == null) { - parent = allocateNode(); - setRootNode(parent); - parent.setChild(0, nodeOffset); - } else { - // Insert the median into the parent. - for (int i = fMaxNumEntries - 2; i >= iParent; --i) { - ITmfCheckpoint r = parent.getEntry(i); - if (r != null) { - parent.setEntry(i + 1, r); - parent.setChild(i + 2, parent.getChild(i + 1)); - } - } - } - - fNodeCache.getNode(parent.getOffset()); - - parent.setEntry(iParent, median); - parent.setChild(iParent + 1, newNodeOffset); - - node.setEntry(fMedianEntry, null); - - // Set the node to the correct one to follow. - if (checkpoint.compareTo(median) > 0) { - node = newnode; - } - } - - // Binary search to find the insert point. - int lower = 0; - int upper = fMaxNumEntries - 1; - while (lower < upper && node.getEntry(upper - 1) == null) { - upper--; - } - - while (lower < upper) { - int middle = (lower + upper) / 2; - ITmfCheckpoint check = node.getEntry(middle); - if (check == null) { - upper = middle; - } else { - int compare = check.compareTo(checkpoint); - if (compare > 0) { - upper = middle; - } else if (compare < 0) { - lower = middle + 1; - } else { - // Found it, no insert - return; - } - } - } - final int i = lower; - long child = node.getChild(i); - if (child != BTreeNode.NULL_CHILD) { - // Visit the children. - insert(checkpoint, child, node, i); - } else { - // We are at the leaf, add us in. - // First copy everything after over one. - for (int j = fMaxNumEntries - 2; j >= i; --j) { - ITmfCheckpoint r = node.getEntry(j); - if (r != null) { - node.setEntry(j + 1, r); - } - } - node.setEntry(i, checkpoint); - return; - } - } - - int getNodeSize() { - if (nodeSize == -1) { - nodeSize = INT_SIZE; // num entries - nodeSize += getTrace().getCheckpointSize() * fMaxNumEntries; - nodeSize += LONG_SIZE * fMaxNumChildren; - } - - return nodeSize; - } - - private BTreeNode allocateNode() { - try { - long offset = getRandomAccessFile().length(); - getRandomAccessFile().setLength(offset + getNodeSize()); - BTreeNode node = new BTreeNode(this, offset); - return node; - } catch (IOException e) { - Activator.logError(MessageFormat.format(Messages.BTree_IOErrorAllocatingNode, getFile()), e); - } - return null; - } - - @Override - public long binarySearch(ITmfCheckpoint checkpoint) { - BTreeCheckpointVisitor v = new BTreeCheckpointVisitor(checkpoint); - accept(v); - return v.getCheckpointRank(); - } - - /** - * Accept a visitor. This visitor is used to search through the whole tree. - * - * @param treeVisitor - * the visitor to accept - */ - public void accept(IBTreeVisitor treeVisitor) { - accept(fBTreeHeader.fRoot, treeVisitor); - } - - private void accept(long nodeOffset, IBTreeVisitor visitor) { - - if (nodeOffset == BTreeNode.NULL_CHILD) { - return; - } - - BTreeNode node = fNodeCache.getNode(nodeOffset); - - // Binary search to find first entry greater or equal. - int lower = 0; - int upper = fMaxNumEntries - 1; - while (lower < upper && node.getEntry(upper - 1) == null) { - upper--; - } - while (lower < upper) { - int middle = (lower + upper) / 2; - ITmfCheckpoint middleCheckpoint = node.getEntry(middle); - if (middleCheckpoint == null) { - upper = middle; - } else { - int compare = visitor.compare(middleCheckpoint); - if (compare == 0) { - return; - } else if (compare > 0) { - upper = middle; - } else { - lower = middle + 1; - } - } - } - - // Start with first record greater or equal, reuse comparison - // results. - int i = lower; - for (; i < fMaxNumEntries; ++i) { - ITmfCheckpoint record = node.getEntry(i); - if (record == null) { - break; - } - - int compare = visitor.compare(record); - if (compare > 0) { - // Start point is to the left. - accept(node.getChild(i), visitor); - return; - } else if (compare == 0) { - return; - } - } - accept(node.getChild(i), visitor); - return; - } - - /** - * Set the index as complete. No more checkpoints will be inserted. - */ - @Override - public void setIndexComplete() { - super.setIndexComplete(); - - fNodeCache.serialize(); - } - - /** - * Get the maximum number of entries in a node - * - * @return the maximum number of entries in a node - */ - int getMaxNumEntries() { - return fMaxNumEntries; - } - - /** - * Set the size of the BTree, expressed as a number of checkpoints - * - * @param size - * the size of the BTree - */ - public void setSize(int size) { - fBTreeHeader.fSize = size; - } - - /** - * Get the maximum number of children in a node - * - * @return the maximum number of children in a node - */ - int getMaxNumChildren() { - return fMaxNumChildren; - } - - ByteBuffer getNodeByteBuffer() { - return fNodeByteBuffer; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/BTreeCheckpointVisitor.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/BTreeCheckpointVisitor.java deleted file mode 100644 index 20e10e2790..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/BTreeCheckpointVisitor.java +++ /dev/null @@ -1,76 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.trace.indexer; - -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; - -/** - * A visitor that searches for a specific checkpoint - * - * @author Marc-Andre Laperle - */ -public class BTreeCheckpointVisitor implements IBTreeVisitor { - - private long rank = -1; - private ITmfCheckpoint found; - private ITmfCheckpoint search; - private boolean exactFound = false; - - /** - * Constructs the checkpoint visitor - * - * @param search - * the checkpoint to search for - */ - public BTreeCheckpointVisitor(ITmfCheckpoint search) { - this.search = search; - } - - @Override - public int compare(ITmfCheckpoint currentCheckpoint) { - int compareTo = currentCheckpoint.compareTo(search); - if (compareTo <= 0 && !exactFound) { - rank = currentCheckpoint.getCheckpointRank(); - found = currentCheckpoint; - if (compareTo == 0) { - exactFound = true; - } - } - return compareTo; - } - - /** - * Return the found checkpoint - * - * @return the found checkpoint - */ - public ITmfCheckpoint getCheckpoint() { - return found; - } - - /** - * Returns the checkpoint rank of the searched checkpoint, if it is - * contained in the index; otherwise, (-(insertion point) - 1). - * - * @return the checkpoint rank of the searched checkpoint, if it is - * contained in the index; otherwise, (-(insertion point) - 1). - */ - public long getCheckpointRank() { - if (!exactFound) { - long insertionPoint = rank + 1; - return -insertionPoint - 1; - } - - return rank; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/BTreeNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/BTreeNode.java deleted file mode 100644 index 2a37b90b4d..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/BTreeNode.java +++ /dev/null @@ -1,204 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.trace.indexer; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.text.MessageFormat; -import java.util.Arrays; - -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - -/** - * A node in the BTree. A node contains entries and pointers to other nodes. - * The layout can be illustrated like this: - * - * | - * ___________Node__________ - * | e | e | e | e | - * p p p p p - * | - * | - * Node ... - * - * Where e is an entry, p is a pointer to another node. - * - * A pointer on the left side of an entry points to a node containing entries - * that are of lesser value than the entry and a pointer on the right side of - * an entry points to a node containing entries that are of greater value - * than the entry. In this implementation, entries are ITmfCheckpoints and - * pointers are file offsets (long). - * - * @author Marc-Andre Laperle - */ -class BTreeNode { - - /** - * Integer to represent a null child - */ - static final int NULL_CHILD = -1; - - private final ITmfCheckpoint fEntries[]; - private final long fChildrenFileOffsets[]; - private final long fFileOffset; - private final BTree fTree; - - private int fNumEntries = 0; - private boolean fIsDirty = false; - - /** - * Construct a node for the specified tree for the specified file offset - * - * @param tree - * the BTree - * @param offset - * the file offset - */ - BTreeNode(BTree tree, long offset) { - fTree = tree; - fFileOffset = offset; - fEntries = new ITmfCheckpoint[fTree.getMaxNumEntries()]; - fChildrenFileOffsets = new long[fTree.getMaxNumChildren()]; - Arrays.fill(fChildrenFileOffsets, NULL_CHILD); - } - - /** - * Get the file offset for this node - * - * @return the file offset - */ - long getOffset() { - return fFileOffset; - } - - /** - * Read the node data from disk - */ - void serializeIn() { - try { - fTree.getRandomAccessFile().seek(fFileOffset); - - ByteBuffer bb; - bb = fTree.getNodeByteBuffer(); - bb.clear(); - fTree.getRandomAccessFile().read(bb.array()); - - for (int i = 0; i < fTree.getMaxNumChildren(); ++i) { - fChildrenFileOffsets[i] = bb.getLong(); - } - fNumEntries = bb.getInt(); - - for (int i = 0; i < fNumEntries; ++i) { - - ITmfLocation location = fTree.getTrace().restoreLocation(bb); - ITmfTimestamp timeStamp = new TmfTimestamp(bb); - TmfCheckpoint c = new TmfCheckpoint(timeStamp, location, bb); - fEntries[i] = c; - } - - } catch (IOException e) { - Activator.logError(MessageFormat.format(Messages.BTreeNode_IOErrorLoading, fFileOffset, fTree.getRandomAccessFile()), e); - } - } - - /** - * Write the node data to disk - */ - void serializeOut() { - try { - fTree.getRandomAccessFile().seek(fFileOffset); - - ByteBuffer bb = fTree.getNodeByteBuffer(); - bb.clear(); - - for (int i = 0; i < fTree.getMaxNumChildren(); ++i) { - bb.putLong(fChildrenFileOffsets[i]); - } - bb.putInt(fNumEntries); - - for (int i = 0; i < fNumEntries; ++i) { - ITmfCheckpoint key = fEntries[i]; - key.serialize(bb); - } - - fTree.getRandomAccessFile().write(bb.array()); - - fIsDirty = false; - } catch (IOException e) { - Activator.logError(MessageFormat.format(Messages.BTreeNode_IOErrorWriting, fFileOffset, fTree.getRandomAccessFile()), e); - } - } - - /** - * Get the entry at the given index - * - * @param index - * the index where to get the entry - * @return the entry at the index - */ - ITmfCheckpoint getEntry(int index) { - return fEntries[index]; - } - - long getChild(int index) { - return fChildrenFileOffsets[index]; - } - - /** - * Set the checkpoint entry at the given index - * - * @param index - * the index where to set the entry - * @param checkpoint - * the checkpoint to set at the index - */ - void setEntry(int index, ITmfCheckpoint checkpoint) { - fIsDirty = true; - // Update number of entries - if (fEntries[index] == null && checkpoint != null) { - ++fNumEntries; - } else if (fEntries[index] != null && checkpoint == null) { - fNumEntries = Math.max(0, fNumEntries - 1); - } - - fEntries[index] = checkpoint; - } - - /** - * Set the child file offset at the given index - * - * @param index - * the index where to set the child offset - * @param offset - * the child offset - */ - void setChild(int index, long offset) { - fIsDirty = true; - fChildrenFileOffsets[index] = offset; - } - - /** - * Returns whether or not the node is dirty, that is, if the node has been - * modified since it first has been loaded into memory - * - * @return true if the node is dirty, false otherwise - */ - boolean isDirty() { - return fIsDirty; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/BTreeNodeCache.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/BTreeNodeCache.java deleted file mode 100644 index a0b8488564..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/BTreeNodeCache.java +++ /dev/null @@ -1,146 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.trace.indexer; - -import java.util.ArrayDeque; -import java.util.Deque; - -/** - * A simple LRU node cache. The BTree request a node from the cache and the - * cache load it from disk if it's not already in memory. - * - * This cache could be improved considerably by allowing bigger caches. - * - * @author Marc-Andre Laperle - */ -public class BTreeNodeCache { - - /** - * Cache size obtained by experimentation. An improved cache could set this - * dynamically or using a user preference. - */ - private static final int CACHE_SIZE = 15; - - private final BTree fTree; - /** - * The root node is always kept in memory when {@link - * BTree#ALWAYS_CACHE_ROOT} is set to true - */ - private BTreeNode fRootNode = null; - /** - * The collection keeping the nodes in memory. The most recently used is - * kept at the front of the double-ended queue and the least recently used - * node is kept at the back. - */ - private final Deque fCachedNodes = new ArrayDeque<>(CACHE_SIZE); - - private int fCcheMisses = 0; - - /** - * Construct a new node cache for the given BTree - * - * @param tree - * the BTree that will use the cache - */ - BTreeNodeCache(BTree tree) { - fTree = tree; - } - - /** - * Get the node at the offset from the cache. If the node is not found in - * memory, it is loaded from disk. - * - * @param offset - * @return - */ - BTreeNode getNode(long offset) { - if (fRootNode != null && fRootNode.getOffset() == offset) { - return fRootNode; - } - - for (BTreeNode nodeSearch : fCachedNodes) { - if (nodeSearch.getOffset() == offset) { - // This node is now the most recently used - fCachedNodes.remove(nodeSearch); - fCachedNodes.push(nodeSearch); - - return nodeSearch; - } - } - - ++fCcheMisses; - - BTreeNode node = new BTreeNode(fTree, offset); - node.serializeIn(); - addNode(node); - - return node; - } - - /** - * Write all in-memory nodes to disk if they are dirty - */ - void serialize() { - if (fRootNode != null && fRootNode.isDirty()) { - fRootNode.serializeOut(); - } - for (BTreeNode nodeSearch : fCachedNodes) { - if (nodeSearch.isDirty()) { - nodeSearch.serializeOut(); - } - } - } - - /** - * Add a node to the cache. If the cache has reached the size specified with - * {@link #CACHE_SIZE}, the least recently used node is removed from memory. - * - * @param node - * the node to add to the cache - */ - void addNode(BTreeNode node) { - if (fCachedNodes.size() >= CACHE_SIZE) { - BTreeNode removed = fCachedNodes.removeLast(); - if (removed.isDirty()) { - removed.serializeOut(); - } - } - fCachedNodes.push(node); - } - - /** - * Set the root node. See {@link #fRootNode} - * - * @param newRootNode - * the new root node - */ - void setRootNode(BTreeNode newRootNode) { - BTreeNode oldRootNode = fRootNode; - fRootNode = newRootNode; - if (oldRootNode != null) { - addNode(oldRootNode); - } - return; - } - - /** - * Useful for benchmarks. Get the number of cache misses for the whole BTree - * instance lifetime. Cache misses occur when a node is requested and it's - * not in memory therefore it has to be read from disk. - * - * @return the number of cache misses. - */ - int getCacheMisses() { - return fCcheMisses; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/FlatArray.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/FlatArray.java deleted file mode 100644 index de9d906888..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/FlatArray.java +++ /dev/null @@ -1,142 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.trace.indexer; - -import java.io.File; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.text.MessageFormat; - -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfPersistentlyIndexable; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - -/** - * An array of checkpoints stored on disk. It is very efficient for searching - * checkpoints by rank (O(1)) - * - * @author Marc-Andre Laperle - */ -public class FlatArray extends AbstractFileCheckpointCollection { - /** - * Typical FlatArray file name - */ - public static final String INDEX_FILE_NAME = "checkpoint_flatarray.idx"; //$NON-NLS-1$ - - // Cached values - private int fCheckpointSize = 0; - private ByteBuffer fByteBuffer; - - /** - * Constructs a FlatArray for a given trace from scratch or from an existing - * file. When the FlatArray is created from scratch, it is populated by - * subsequent calls to {@link #insert}. - * - * @param file - * the file to use as the persistent storage - * @param trace - * the trace - */ - public FlatArray(File file, ITmfPersistentlyIndexable trace) { - super(file, trace); - - fCheckpointSize = getTrace().getCheckpointSize(); - fByteBuffer = ByteBuffer.allocate(fCheckpointSize); - fByteBuffer.clear(); - } - - /** - * Insert a checkpoint into the file-backed array - * - * @param checkpoint - * the checkpoint to insert - */ - @Override - public void insert(ITmfCheckpoint checkpoint) { - try { - CheckpointCollectionFileHeader header = getHeader(); - ++header.fSize; - getRandomAccessFile().seek(getRandomAccessFile().length()); - fByteBuffer.clear(); - checkpoint.serialize(fByteBuffer); - getRandomAccessFile().write(fByteBuffer.array()); - } catch (IOException e) { - Activator.logError(MessageFormat.format(Messages.FlatArray_IOErrorWriting, getFile()), e); - } - } - - /** - * Get a checkpoint from a rank - * - * @param rank - * the rank to search - * @return the checkpoint that has been found or null if not found - */ - public ITmfCheckpoint get(long rank) { - ITmfCheckpoint checkpoint = null; - try { - long pos = getHeader().getSize() + fCheckpointSize * rank; - getRandomAccessFile().seek(pos); - fByteBuffer.clear(); - getRandomAccessFile().read(fByteBuffer.array()); - ITmfLocation location = getTrace().restoreLocation(fByteBuffer); - ITmfTimestamp timeStamp = new TmfTimestamp(fByteBuffer); - checkpoint = new TmfCheckpoint(timeStamp, location, fByteBuffer); - } catch (IOException e) { - Activator.logError(MessageFormat.format(Messages.FlatArray_IOErrorReading, getFile()), e); - } - return checkpoint; - } - - /** - * Search for a checkpoint and return the rank. - * - * @param checkpoint - * the checkpoint to search - * @return the checkpoint rank of the searched checkpoint, if it is - * contained in the index; otherwise, (-(insertion point) - 1). - */ - @Override - public long binarySearch(ITmfCheckpoint checkpoint) { - if (getHeader().fSize == 1) { - return 0; - } - - long lower = 0; - long upper = getHeader().fSize - 1; - long lastMiddle = -1; - long middle = 0; - while (lower <= upper && lastMiddle != middle) { - lastMiddle = middle; - middle = (lower + upper) / 2; - ITmfCheckpoint found = get(middle); - incCacheMisses(); - int compare = checkpoint.compareTo(found); - if (compare == 0) { - return middle; - } - - if (compare < 0) { - upper = middle; - } else { - lower = middle + 1; - } - } - long insertionPoint = lower; - return -(insertionPoint) - 1; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/IBTreeVisitor.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/IBTreeVisitor.java deleted file mode 100644 index 4f4e560dca..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/IBTreeVisitor.java +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.trace.indexer; - -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; - -/** - * A BTree visitor goes through the tree using a comparator for - * optimal searches. - * - * @author Marc-Andre Laperle - */ -public interface IBTreeVisitor { - - /** - * The current checkpoint being compared against an internally held key. - * - * @param checkpoint - * the current checkpoint - * @return -1 if checkpoint < key, 0 if checkpoint == key, 1 if checkpoint > - * key - */ - int compare(ITmfCheckpoint checkpoint); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/ICheckpointCollection.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/ICheckpointCollection.java deleted file mode 100644 index ea75482e7b..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/ICheckpointCollection.java +++ /dev/null @@ -1,99 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.trace.indexer; - -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; - -/** - * A common interface for collections containing checkpoints - * - * @author Marc-Andre Laperle - */ -public interface ICheckpointCollection { - - /** - * Insert a checkpoint into the collection - * - * @param checkpoint - * the checkpoint to insert - */ - void insert(ITmfCheckpoint checkpoint); - - /** - * Search for a checkpoint and return the rank. - * - * @param checkpoint - * the checkpoint to search - * @return the checkpoint rank of the searched checkpoint, if it is - * contained in the index; otherwise, (-(insertion point) - 1). - */ - long binarySearch(ITmfCheckpoint checkpoint); - - /** - * @return true if the collection was created from scratch, false otherwise - */ - boolean isCreatedFromScratch(); - - /** - * Returns the size of the collection expressed as a number of checkpoints. - * - * @return the size of the collection - */ - int size(); - - /** - * Set the trace time range - * - * @param timeRange - * the trace time range - */ - void setTimeRange(TmfTimeRange timeRange); - - /** - * Get the trace time range - * - * @return the trace time range - */ - TmfTimeRange getTimeRange(); - - /** - * Set the number of events in the trace - * - * @param nbEvents - * the number of events in the trace - */ - void setNbEvents(long nbEvents); - - /** - * Get the number of events in the trace - * - * @return the number of events in the trace - */ - long getNbEvents(); - - /** - * Set the index as complete. No more checkpoints will be inserted. - */ - void setIndexComplete(); - - /** - * Dispose the collection and delete persistent data (file) - */ - void delete(); - - /** - * Dispose the structure and its resources - */ - void dispose(); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/Messages.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/Messages.java deleted file mode 100644 index f7c8631050..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/Messages.java +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.trace.indexer; - -import org.eclipse.osgi.util.NLS; - -/** - * Message bundle for tmf.core.trace.index - * - * @author Marc-Andre Laperle - */ -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.tmf.core.trace.indexer.messages"; //$NON-NLS-1$ - /** - * Error opening index - */ - public static String ErrorOpeningIndex; - /** - * I/O Error allocating a node - */ - public static String BTree_IOErrorAllocatingNode; - /** - * I/O Error closing the index - */ - public static String IOErrorClosingIndex; - /** - * I/O Error reading header from disk - */ - public static String IOErrorReadingHeader; - /** - * I/O Error writing header from disk - */ - public static String IOErrorWritingHeader; - /** - * I/O Error reading node from disk - */ - public static String BTreeNode_IOErrorLoading; - /** - * I/O Error writing node to disk - */ - public static String BTreeNode_IOErrorWriting; - /** - * I/O Error reading from disk - */ - public static String FlatArray_IOErrorReading; - /** - * I/O Error writing to disk - */ - public static String FlatArray_IOErrorWriting; - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/TmfMemoryIndex.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/TmfMemoryIndex.java deleted file mode 100644 index 62ad4ff762..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/TmfMemoryIndex.java +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.core.trace.indexer; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; - -/** - * A checkpoint index that store all checkpoints in memory. - * - * @since 3.0 - * @author Marc-Andre Laperle - */ -public class TmfMemoryIndex implements ITmfCheckpointIndex, ICheckpointCollection { - - private final List fCheckpoints; - - /** - * Creates an index for the given trace - * - * @param trace the trace - */ - public TmfMemoryIndex(ITmfTrace trace) { - fCheckpoints = new ArrayList<>(); - } - - @Override - public void dispose() { - fCheckpoints.clear(); - } - - @Override - public void insert(ITmfCheckpoint checkpoint) { - fCheckpoints.add(checkpoint); - } - - @Override - public ITmfCheckpoint get(long checkpoint) { - return fCheckpoints.get((int)checkpoint); - } - - @Override - public long binarySearch(ITmfCheckpoint checkpoint) { - return Collections.binarySearch(fCheckpoints, checkpoint); - } - - @Override - public boolean isEmpty() { - return fCheckpoints.isEmpty(); - } - - @Override - public int size() { - return fCheckpoints.size(); - } - - @Override - public boolean isCreatedFromScratch() { - return true; - } - - @Override - public void setTimeRange(TmfTimeRange timeRange) { - } - - @Override - public void setNbEvents(long nbEvents) { - } - - @Override - public TmfTimeRange getTimeRange() { - return null; - } - - @Override - public long getNbEvents() { - return 0; - } - - @Override - public void setIndexComplete() { - } - - @Override - public void delete() { - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/messages.properties b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/messages.properties deleted file mode 100644 index 6528587289..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/trace/indexer/messages.properties +++ /dev/null @@ -1,21 +0,0 @@ -############################################################################### -# Copyright (c) 2013 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### - -ErrorOpeningIndex=Error opening index. File: {0} -BTree_IOErrorAllocatingNode=I/O error allocating index node. File: {0} -IOErrorClosingIndex=Error closing index. File: {0} -IOErrorReadingHeader=Error reading index header. File: {0} -IOErrorWritingHeader=Error writing index header. File: {0} -BTreeNode_IOErrorLoading=I/O error loading index node. Offset: {0} file: {1} -BTreeNode_IOErrorWriting=I/O error writing index node. Offset: {0} file: {1} -FlatArray_IOErrorReading=I/O error reading index checkpoint. File: {0} -FlatArray_IOErrorWriting=I/O error writing index checkpoint. File: {0} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/Messages.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/Messages.java deleted file mode 100644 index 4474752cfc..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/Messages.java +++ /dev/null @@ -1,39 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core; - -import org.eclipse.osgi.util.NLS; - -/** - * Message strings for TMF model handling. - * - * @author Marc-Andre Laperle - * @since 2.2 - */ -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.core.messages"; //$NON-NLS-1$ - - /** - * The name of the default project - */ - public static String DefaultTraceProjectName; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/TmfCommonConstants.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/TmfCommonConstants.java deleted file mode 100644 index 2d90110e01..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/TmfCommonConstants.java +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Patrick Tasse - Add support for source location - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.core; - -import org.eclipse.core.runtime.QualifiedName; - -/** - * This class provides a common container for TMF constants. - * - * @version 1.0 - * @author Bernd Hufmann - */ -public class TmfCommonConstants { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The trace type ID persistent property of a trace resource. - */ - public static final QualifiedName TRACETYPE = new QualifiedName("org.eclipse.linuxtools.tmf", "tracetype.id"); //$NON-NLS-1$//$NON-NLS-2$ - - /** - * The source location persistent property of a trace resource. - * @since 3.0 - */ - public static final QualifiedName SOURCE_LOCATION = new QualifiedName("org.eclipse.linuxtools.tmf", "source.location"); //$NON-NLS-1$//$NON-NLS-2$ - - /** - * The supplementary folder name persistent property of a trace resource. - */ - public static final QualifiedName TRACE_SUPPLEMENTARY_FOLDER = new QualifiedName("org.eclipse.linuxtools.tmf", "trace.suppl.folder"); //$NON-NLS-1$//$NON-NLS-2$ - - /** - * The name of the parent folder for storing trace specific supplementary data. Each trace will have a sub-directory underneath with folder name equal to the trace name. - * @since 3.0 - */ - public static final String TRACE_SUPPLEMENTARY_FOLDER_NAME = ".tracing"; //$NON-NLS-1$ - - /** - * The name of the default project that can be created under various - * conditions when there is no tracing project in the workspace. - * - * @since 2.2 - */ - public static final String DEFAULT_TRACE_PROJECT_NAME = Messages.DefaultTraceProjectName; - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/TmfProjectNature.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/TmfProjectNature.java deleted file mode 100644 index c100335eb0..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/TmfProjectNature.java +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IProjectNature; -import org.eclipse.core.runtime.CoreException; - -/** - * The TMF basic tracing project nature. - * - * @version 1.0 - * @author Francois Chouinard - */ -public class TmfProjectNature implements IProjectNature { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The nature ID - */ - public static final String ID = "org.eclipse.linuxtools.tmf.project.nature"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private IProject fProject; - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Override - public void configure() throws CoreException { - } - - @Override - public void deconfigure() throws CoreException { - } - - @Override - public IProject getProject() { - return fProject; - } - - @Override - public void setProject(IProject project) { - fProject = project; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisModule.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisModule.java deleted file mode 100644 index 3e30dc9f71..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisModule.java +++ /dev/null @@ -1,249 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.analysis; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.tmf.core.component.ITmfComponent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Interface that hooks analysis modules to the rest of TMF. Analysis modules - * are a set of operations to be run on a trace (or experiment). They will - * typically either provide outputs to the end user, or feed other analysis. - * - * An analysis module must tell what trace type it applies to and if it can be - * executed on a given trace of the right type. - * - * Implementations of this interface must define how an analysis will be - * executed once scheduled and provide help texts to describe how to use the - * analysis. - * - * Analysis can also take parameters, manually set, through default values or - * using an {@link IAnalysisParameterProvider}. {@link IAnalysisOutput} can also - * be registered to an analysis modules to display the results of the analysis. - * - * This interface just allows to hook the analysis to the TMF framework, but the - * developer is free to implement the internals of its operations the way he - * wishes. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public interface IAnalysisModule extends ITmfComponent, IAnalysisRequirementProvider, AutoCloseable { - - // -------------------------------------------------------- - // Getters and setters - // -------------------------------------------------------- - - /** - * Sets the name of the analysis module - * - * @param name - * name of the module - */ - void setName(String name); - - /** - * Sets the id of the module - * - * @param id - * id of the module - */ - void setId(String id); - - /** - * Gets the id of the analysis module - * - * @return The id of the module - */ - @NonNull - String getId(); - - /** - * Sets whether this analysis should be run automatically at trace opening - * - * @param auto - * True if analysis should be run automatically for a trace - */ - void setAutomatic(boolean auto); - - /** - * Gets whether the analysis should be run automatically at trace opening - * - * @return true if analysis is to be run automatically - */ - boolean isAutomatic(); - - /** - * Sets the trace on which to run the analysis - * - * Note: The trace cannot be final since most modules are instantiated in a - * way that does not know about the trace, but it shouldn't be set more than - * once since an instance of a module belongs to a trace. It is up to each - * implementation to make sure the trace is set only once. - * - * @param trace - * The trace to run the analysis on - * @throws TmfAnalysisException - */ - void setTrace(ITmfTrace trace) throws TmfAnalysisException; - - /** - * Add a parameter to this module - * - * @param name - * Name of the parameter - */ - void addParameter(String name); - - /** - * Sets the value of a parameter - * - * @param name - * The name of the parameter - * @param value - * The value (subclasses may type-check it) - * @throws RuntimeException - */ - void setParameter(String name, Object value); - - /** - * Gets the value of a parameter - * - * @param name - * Name of the parameter - * @return The value of a parameter - */ - Object getParameter(String name); - - // ----------------------------------------------------- - // Functionalities - // ----------------------------------------------------- - - /** - * Can an analysis be executed on a given trace (otherwise, it is shown - * grayed out and a help message is available to see why it is not - * applicable) - * - * @param trace - * The trace to analyze - * @return Whether the analysis can be executed - */ - boolean canExecute(@NonNull ITmfTrace trace); - - /** - * Schedule the execution of the analysis. If the trace has been set and is - * opened, the analysis will be executed right away, otherwise it should - * scheduled for execution once all pre-conditions are satisfied. - * - * @return An IStatus indicating if the execution of the analysis could be - * scheduled successfully or not. - */ - IStatus schedule(); - - /** - * Gets a list of outputs - * - * @return The list of {@link IAnalysisOutput} - */ - Iterable getOutputs(); - - /** - * Registers an output for this analysis - * - * @param output - * The {@link IAnalysisOutput} object - */ - void registerOutput(IAnalysisOutput output); - - /** - * Block the calling thread until this analysis has completed (or has been - * cancelled). - * - * @return True if the analysis finished successfully, false if it was - * cancelled. - */ - boolean waitForCompletion(); - - /** - * Typically the output of an analysis will be available only after it is - * completed. This method allows to wait until an analysis has been - * completed or the analysis has been cancelled - * - * To avoid UI freezes, it should not be called from the main thread of the - * application - * - * @param monitor - * The progress monitor to check for cancellation - * @return If the analysis was successfully completed. If false is returned, - * this either means there was a problem during the analysis, or it - * got cancelled before it could finished or it has not been - * scheduled to run at all. In all cases, the quality or - * availability of the output(s) and results is not guaranteed. - */ - boolean waitForCompletion(IProgressMonitor monitor); - - /** - * Cancels the current analysis - */ - void cancel(); - - // ----------------------------------------------------- - // Utilities - // ----------------------------------------------------- - - /** - * Gets a generic help message/documentation for this analysis module - * - * This help text will be displayed to the user and may contain information - * on what the module does, how to use it and how to correctly generate the - * trace to make it available - * - * TODO: Help texts could be quite long. They should reside in their own - * file and be accessed either with text, for a command line man page, or - * through the eclipse help context. - * - * @return The generic help text - */ - String getHelpText(); - - /** - * Gets a help text specific for a given trace - * - * For instance, it may explain why the analysis module cannot be executed - * on a trace and how to correct this - * - * @param trace - * The trace to analyze - * @return A help text with information on a specific trace - */ - String getHelpText(ITmfTrace trace); - - /** - * Notify the module that the value of a parameter has changed - * - * @param name - * The of the parameter that changed - */ - void notifyParameterChanged(String name); - - // ----------------------------------------------------- - // AutoCloseable (remove the thrown exception) - // ----------------------------------------------------- - - @Override - void close(); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisModuleHelper.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisModuleHelper.java deleted file mode 100644 index 4469e9798f..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisModuleHelper.java +++ /dev/null @@ -1,138 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.analysis; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.osgi.framework.Bundle; - -/** - * Interface for modules helpers that provide basic module information and - * creates module from a source when requested. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public interface IAnalysisModuleHelper extends IAnalysisRequirementProvider { - - // ------------------------------------ - // Getters - // ------------------------------------ - - /** - * Gets the id of the analysis module - * - * @return The id of the module - */ - String getId(); - - /** - * Gets the name of the analysis module - * - * @return The id of the module - */ - String getName(); - - /** - * Gets whether the analysis should be run automatically at trace opening - * - * @return true if analysis is to be run automatically - */ - boolean isAutomatic(); - - /** - * Gets a generic help message/documentation for this analysis module - * - * This help text will be displayed to the user and may contain information - * on what the module does, how to use it and how to correctly generate the - * trace to make it available - * - * TODO: Help texts could be quite long. They should reside in their own - * file and be accessed either with text, for a command line man page, or - * through the eclipse help context. There should be a custom way to make it - * available through the helper, without instantiating the analysis, though - * help text after analysis instantiation may be richer. - * - * @return The generic help text - */ - String getHelpText(); - - /** - * Gets a specific help message/documentation for this analysis module - * applied on the given trace. This help message can add information on the - * status of this analysis for a given trace, whether it can be executed or - * not and why. - * - * This help text will be displayed to the user and may contain information - * on what the module does, how to use it and how to correctly generate the - * trace to make it available - * - * @param trace - * A trace for which to get specific help message - * @return The generic help text - */ - String getHelpText(@NonNull ITmfTrace trace); - - /** - * Gets the icon for this module - * - * @return The icon path - */ - String getIcon(); - - /** - * Gets the bundle this analysis module is part of - * - * @return The bundle - */ - Bundle getBundle(); - - /** - * Does an analysis apply to a given trace type (otherwise, it is not shown) - * - * @param traceclass - * The trace to analyze - * @return whether the analysis applies - */ - boolean appliesToTraceType(Class traceclass); - - /** - * Gets the list of valid trace types that the analysis can operate on. - * - * @return List of the trace type - */ - Iterable> getValidTraceTypes(); - - // --------------------------------------- - // Functionalities - // --------------------------------------- - - /** - * Creates a new instance of the {@link IAnalysisModule} represented by this - * helper and initializes it with the trace. - * - * After the module is fully created, this method should call - * {@link TmfAnalysisManager#analysisModuleCreated(IAnalysisModule)} in - * order for the new module listeners to be executed on this module. - * - * @param trace - * The trace to be linked to the module - * @return A new {@link IAnalysisModule} instance initialized with the - * trace. - * @throws TmfAnalysisException - * Exceptions that occurred when setting trace - */ - IAnalysisModule newModule(ITmfTrace trace) throws TmfAnalysisException; - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisModuleSource.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisModuleSource.java deleted file mode 100644 index c5720ee1e6..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisModuleSource.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.analysis; - - -/** - * Interface that module sources must implement. A module source provides a list - * of analysis modules. For example, one module source would be the plugin's - * configuration element through the analysis extension point. - * - * Typically, for each module source, there would be an - * {@link IAnalysisModuleHelper} implementation to create modules from this - * source. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public interface IAnalysisModuleSource { - - /** - * Get the list of modules helpers provided by this source - * - * @return The analysis module helpers in iterable format - */ - Iterable getAnalysisModules(); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisOutput.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisOutput.java deleted file mode 100644 index 5c072947dc..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisOutput.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.analysis; - -import org.eclipse.jdt.annotation.NonNull; - -/** - * Interface for all output types of analysis - * - * @author Geneviève Bastien - * @since 3.0 - */ -public interface IAnalysisOutput { - - /** - * Gets the name of the output - * - * @return Name of the output - */ - String getName(); - - /** - * Requests the output for an analysis module. This function does not - * necessarily output the analysis, it just specifies that the user wants - * this output. - */ - void requestOutput(); - - /** - * Sets an arbitrary property on the output. The key must not be null, a - * null value removes the property. - * - * @param key - * The arbitrary property. Must not be null. - * @param value - * The value of the property. - * @param immediate - * If true, the property will be applied immediately - * if the output is active. Otherwise, it is only applied when the - * output is explicitly requested by the user. - */ - void setOutputProperty(@NonNull String key, String value, boolean immediate); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisParameterProvider.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisParameterProvider.java deleted file mode 100644 index 2689f203a7..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisParameterProvider.java +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.analysis; - -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Interface for classes that can provide parameters to analysis when they are - * not set manually - * - * @author Geneviève Bastien - * @since 3.0 - */ -public interface IAnalysisParameterProvider { - - // -------------------------------------------------------- - // Getters and setters - // -------------------------------------------------------- - - /** - * Gets the name of the parameter provider - * - * @return Name of the parameter provider - */ - String getName(); - - /** - * Gets the value of a parameter - * - * @param name - * Name of the parameter - * @return The value of a parameter - */ - Object getParameter(String name); - - // -------------------------------------------------------- - // Functionalities - // -------------------------------------------------------- - - /** - * Does this parameter provider apply to a given trace - * - * @param trace - * The trace to analyse - * @return whether the parameter provider applies - */ - boolean appliesToTrace(ITmfTrace trace); - - /** - * Register an analysis module to be notified when a parameter value is - * changed - * - * @param module - * The listening analysis module - */ - void registerModule(IAnalysisModule module); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisRequirementProvider.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisRequirementProvider.java deleted file mode 100644 index f1744baa18..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisRequirementProvider.java +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Guilliano Molaire - Initial API and implementation - * Mathieu Rail - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.analysis; - -/** - * Interface that provides the necessary methods for an analysis to define its - * requirements. - * - * @author Guilliano Molaire - * @author Mathieu Rail - * @since 3.0 - */ -public interface IAnalysisRequirementProvider { - - /** - * Gets the requirements associated with this analysis. - * - * @return List of requirement - */ - Iterable getAnalysisRequirements(); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/ITmfNewAnalysisModuleListener.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/ITmfNewAnalysisModuleListener.java deleted file mode 100644 index 8ec84ae9f3..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/ITmfNewAnalysisModuleListener.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.analysis; - -/** - * This is the interface class must implement to listen to new analysis module - * objects being instantiated. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public interface ITmfNewAnalysisModuleListener { - - /** - * Method called when an analysis module has just been instantiated. - * - * @param module - * The newly instantiated analysis module - */ - public void moduleCreated(IAnalysisModule module); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/Messages.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/Messages.java deleted file mode 100644 index 3919bf3270..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/Messages.java +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.analysis; - -import org.eclipse.osgi.util.NLS; - -/** - * Message bundle for org.eclipse.linuxtools.tmf.core.analysis - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.core.analysis.messages"; //$NON-NLS-1$ - - /** Trace was set more than once for this module */ - public static String TmfAbstractAnalysisModule_TraceSetMoreThanOnce; - - /** Analysis Module cannot execute on trace */ - public static String TmfAbstractAnalysisModule_AnalysisCannotExecute; - - /** Analysis Module does not apply to trace */ - public static String TmfAnalysisModuleHelper_AnalysisDoesNotApply; - - /** Analysis Module for trace */ - public static String TmfAbstractAnalysisModule_AnalysisForTrace; - - /** Analysis Module presentation */ - public static String TmfAbstractAnalysisModule_AnalysisModule; - - /** Parameter is invalid */ - public static String TmfAbstractAnalysisModule_InvalidParameter; - - /** The trace to set was null */ - public static String TmfAbstractAnalysisModule_NullTrace; - - /** Additional information on a requirement */ - public static String TmfAnalysis_RequirementInformation; - - /** Mandatory values of a requirement */ - public static String TmfAnalysis_RequirementMandatoryValues; - - /** A requirement is not fulfilled */ - public static String TmfAnalysis_RequirementNotFulfilled; - - /** Running analysis */ - public static String TmfAbstractAnalysisModule_RunningAnalysis; - - /** Error instantiating parameter provider */ - public static String TmfAnalysisManager_ErrorParameterProvider; - - /** Impossible to instantiate module from helper */ - public static String TmfAnalysisModuleHelper_ImpossibleToCreateModule; - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAbstractAnalysisModule.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAbstractAnalysisModule.java deleted file mode 100644 index ad65810ab3..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAbstractAnalysisModule.java +++ /dev/null @@ -1,474 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.analysis; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisRequirement.ValuePriorityLevel; -import org.eclipse.linuxtools.tmf.core.component.TmfComponent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfStartAnalysisSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.osgi.util.NLS; - -/** - * Base class that analysis modules main class may extend. It provides default - * behavior to some methods of the analysis module - * - * @author Geneviève Bastien - * @since 3.0 - */ -public abstract class TmfAbstractAnalysisModule extends TmfComponent implements IAnalysisModule { - - private String fName, fId; - private boolean fAutomatic = false, fStarted = false; - private ITmfTrace fTrace; - private final Map fParameters = new HashMap<>(); - private final List fParameterNames = new ArrayList<>(); - private final List fOutputs = new ArrayList<>(); - private List fParameterProviders = new ArrayList<>(); - private Job fJob = null; - - private final Object syncObj = new Object(); - - /* Latch tracking if the analysis is completed or not */ - private CountDownLatch fFinishedLatch = new CountDownLatch(0); - - private boolean fAnalysisCancelled = false; - - @Override - public boolean isAutomatic() { - return fAutomatic; - } - - @Override - public String getName() { - return fName; - } - - @Override - public void setName(String name) { - fName = name; - } - - @Override - public void setId(String id) { - fId = id; - } - - @Override - @NonNull - public String getId() { - String id = fId; - if (id == null) { - id = new String(this.getClass().getCanonicalName()); - fId = id; - } - return id; - } - - @Override - public void setAutomatic(boolean auto) { - fAutomatic = auto; - } - - @Override - public void setTrace(ITmfTrace trace) throws TmfAnalysisException { - if (trace == null) { - throw new TmfAnalysisException(Messages.TmfAbstractAnalysisModule_NullTrace); - } - if (fTrace != null) { - throw new TmfAnalysisException(NLS.bind(Messages.TmfAbstractAnalysisModule_TraceSetMoreThanOnce, getName())); - } - - /* Check that analysis can be executed */ - if (!canExecute(trace)) { - throw new TmfAnalysisException(NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisCannotExecute, getName())); - } - - fTrace = trace; - /* Get the parameter providers for this trace */ - fParameterProviders = TmfAnalysisManager.getParameterProviders(this, fTrace); - for (IAnalysisParameterProvider provider : fParameterProviders) { - provider.registerModule(this); - } - resetAnalysis(); - fStarted = false; - } - - /** - * Gets the trace - * - * @return The trace - */ - protected ITmfTrace getTrace() { - return fTrace; - } - - @Override - public void addParameter(String name) { - fParameterNames.add(name); - } - - @Override - public synchronized void setParameter(String name, Object value) { - if (!fParameterNames.contains(name)) { - throw new RuntimeException(NLS.bind(Messages.TmfAbstractAnalysisModule_InvalidParameter, name, getName())); - } - Object oldValue = fParameters.get(name); - fParameters.put(name, value); - if ((value != null) && !(value.equals(oldValue))) { - parameterChanged(name); - } - } - - @Override - public synchronized void notifyParameterChanged(String name) { - if (!fParameterNames.contains(name)) { - throw new RuntimeException(NLS.bind(Messages.TmfAbstractAnalysisModule_InvalidParameter, name, getName())); - } - Object oldValue = fParameters.get(name); - Object value = getParameter(name); - if ((value != null) && !(value.equals(oldValue))) { - parameterChanged(name); - } - } - - /** - * Used to indicate that a parameter value has been changed - * - * @param name - * The name of the modified parameter - */ - protected void parameterChanged(String name) { - - } - - @Override - public Object getParameter(String name) { - Object paramValue = fParameters.get(name); - /* The parameter is not set, maybe it can be provided by someone else */ - if ((paramValue == null) && (fTrace != null)) { - for (IAnalysisParameterProvider provider : fParameterProviders) { - paramValue = provider.getParameter(name); - if (paramValue != null) { - break; - } - } - } - return paramValue; - } - - @Override - public boolean canExecute(@NonNull ITmfTrace trace) { - for (TmfAnalysisRequirement requirement : getAnalysisRequirements()) { - if (!requirement.isFulfilled(trace)) { - return false; - } - } - return true; - } - - /** - * Set the countdown latch back to 1 so the analysis can be executed again - */ - protected void resetAnalysis() { - fFinishedLatch.countDown(); - fFinishedLatch = new CountDownLatch(1); - } - - /** - * Actually executes the analysis itself - * - * @param monitor - * Progress monitor - * @return Whether the analysis was completed successfully or not - * @throws TmfAnalysisException - * Method may throw an analysis exception - */ - protected abstract boolean executeAnalysis(final IProgressMonitor monitor) throws TmfAnalysisException; - - /** - * Indicate the analysis has been canceled. It is abstract to force - * implementing class to cleanup what they are running. This is called by - * the job's canceling. It does not need to be called directly. - */ - protected abstract void canceling(); - - /** - * To be called when the analysis is completed, whether normally or because - * it was cancelled or for any other reason. - * - * It has to be called inside a synchronized block - */ - private void setAnalysisCompleted() { - fStarted = false; - fJob = null; - fFinishedLatch.countDown(); - } - - /** - * Cancels the analysis if it is executing - */ - @Override - public final void cancel() { - synchronized (syncObj) { - if (fJob != null) { - if (fJob.cancel()) { - fAnalysisCancelled = true; - setAnalysisCompleted(); - } - } - fStarted = false; - } - } - - @Override - public void close() { - dispose(); - } - - @Override - public void dispose() { - super.dispose(); - cancel(); - } - - private void execute(@NonNull final ITmfTrace trace) { - - /* - * TODO: The analysis in a job should be done at the analysis manager - * level instead of depending on this abstract class implementation, - * otherwise another analysis implementation may block the main thread - */ - - /* Do not execute if analysis has already run */ - if (fFinishedLatch.getCount() == 0) { - return; - } - - /* Do not execute if analysis already running */ - synchronized (syncObj) { - if (fStarted) { - return; - } - fStarted = true; - } - - /* - * Actual analysis will be run on a separate thread - */ - fJob = new Job(NLS.bind(Messages.TmfAbstractAnalysisModule_RunningAnalysis, getName())) { - @Override - protected IStatus run(final IProgressMonitor monitor) { - try { - monitor.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$ - broadcast(new TmfStartAnalysisSignal(TmfAbstractAnalysisModule.this, TmfAbstractAnalysisModule.this)); - fAnalysisCancelled = !executeAnalysis(monitor); - } catch (TmfAnalysisException e) { - Activator.logError("Error executing analysis with trace " + getTrace().getName(), e); //$NON-NLS-1$ - } finally { - synchronized (syncObj) { - monitor.done(); - setAnalysisCompleted(); - } - TmfTraceManager.refreshSupplementaryFiles(trace); - } - if (!fAnalysisCancelled) { - return Status.OK_STATUS; - } - // Reset analysis so that it can be executed again. - resetAnalysis(); - return Status.CANCEL_STATUS; - } - - @Override - protected void canceling() { - TmfAbstractAnalysisModule.this.canceling(); - } - - }; - fJob.schedule(); - } - - @Override - public IStatus schedule() { - final ITmfTrace trace = fTrace; - if (trace == null) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, String.format("No trace specified for analysis %s", getName())); //$NON-NLS-1$ - } - execute(trace); - - return Status.OK_STATUS; - } - - @Override - public Iterable getOutputs() { - return fOutputs; - } - - @Override - public void registerOutput(IAnalysisOutput output) { - if (!fOutputs.contains(output)) { - fOutputs.add(output); - } - } - - @Override - public boolean waitForCompletion() { - try { - fFinishedLatch.await(); - } catch (InterruptedException e) { - Activator.logError("Error while waiting for module completion", e); //$NON-NLS-1$ - } - return !fAnalysisCancelled; - } - - @Override - public boolean waitForCompletion(IProgressMonitor monitor) { - try { - while (!fFinishedLatch.await(500, TimeUnit.MILLISECONDS)) { - if (fAnalysisCancelled || monitor.isCanceled()) { - fAnalysisCancelled = true; - return false; - } - } - } catch (InterruptedException e) { - Activator.logError("Error while waiting for module completion", e); //$NON-NLS-1$ - } - return !fAnalysisCancelled; - } - - /** - * Signal handler for trace closing - * - * @param signal - * Trace closed signal - */ - @TmfSignalHandler - public void traceClosed(TmfTraceClosedSignal signal) { - /* Is the closing trace the one that was requested? */ - if (signal.getTrace() == fTrace) { - cancel(); - fTrace = null; - } - } - - /** - * Signal handler for when the trace becomes active - * - * @param signal - * Trace selected signal - * @since 3.1 - */ - @TmfSignalHandler - public void traceSelected(TmfTraceSelectedSignal signal) { - /* - * Since some parameter providers may handle many traces, we need to - * register the current trace to it - */ - if (signal.getTrace() == fTrace) { - for (IAnalysisParameterProvider provider : fParameterProviders) { - provider.registerModule(this); - } - } - } - - /** - * Returns a full help text to display - * - * @return Full help text for the module - */ - protected String getFullHelpText() { - return NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisModule, getName()); - } - - /** - * Gets a short help text, to display as header to other help text - * - * @param trace - * The trace to show help for - * - * @return Short help text describing the module - */ - protected String getShortHelpText(ITmfTrace trace) { - return NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisForTrace, getName(), trace.getName()); - } - - /** - * Gets the help text specific for a trace who does not have required - * characteristics for module to execute. The default implementation uses - * the analysis requirements. - * - * @param trace - * The trace to apply the analysis to - * @return Help text - */ - protected String getTraceCannotExecuteHelpText(@NonNull ITmfTrace trace) { - StringBuilder builder = new StringBuilder(); - builder.append(NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisCannotExecute, getName())); - for (TmfAnalysisRequirement requirement : getAnalysisRequirements()) { - if (!requirement.isFulfilled(trace)) { - builder.append("\n\n"); //$NON-NLS-1$ - builder.append(NLS.bind(Messages.TmfAnalysis_RequirementNotFulfilled, requirement.getType())); - builder.append("\n"); //$NON-NLS-1$ - builder.append(NLS.bind(Messages.TmfAnalysis_RequirementMandatoryValues, requirement.getValues(ValuePriorityLevel.MANDATORY))); - Set information = requirement.getInformation(); - if (!information.isEmpty()) { - builder.append("\n"); //$NON-NLS-1$ - builder.append(NLS.bind(Messages.TmfAnalysis_RequirementInformation, information)); - } - } - } - return builder.toString(); - } - - @Override - public String getHelpText() { - return getFullHelpText(); - } - - @Override - public String getHelpText(ITmfTrace trace) { - if (trace == null) { - return getHelpText(); - } - String text = getShortHelpText(trace); - if (!canExecute(trace)) { - text = text + "\n\n" + getTraceCannotExecuteHelpText(trace); //$NON-NLS-1$ - } - return text; - } - - @Override - public Iterable getAnalysisRequirements() { - return Collections.EMPTY_SET; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAbstractAnalysisParamProvider.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAbstractAnalysisParamProvider.java deleted file mode 100644 index 7f56b5d221..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAbstractAnalysisParamProvider.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.analysis; - -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; - -/** - * Abstract class for parameter providers, implements methods and - * functionalities to warn the analysis module of parameter changed - * - * @author Geneviève Bastien - * @since 3.0 - */ -public abstract class TmfAbstractAnalysisParamProvider implements IAnalysisParameterProvider { - - /** - * The module registered with this provider - */ - private IAnalysisModule fModule; - - @Override - public void registerModule(IAnalysisModule module) { - if (module == null) { - throw new IllegalArgumentException(); - } - ITmfTrace selectedTrace = TmfTraceManager.getInstance().getActiveTrace(); - /* If no trace is active, just register the module */ - if (selectedTrace == null) { - fModule = module; - return; - } - IAnalysisModule selectedModule = selectedTrace.getAnalysisModule(module.getId()); - /* register only if the module is for the currently selected trace */ - if (selectedModule == module) { - fModule = module; - } - } - - /** - * Gets the analysis module - * - * @return the {@link IAnalysisModule} associated with this provider - */ - protected IAnalysisModule getModule() { - return fModule; - } - - /** - * Notify the registered module that the said parameter has a new value. The - * analysis module will decide what to do with this information - * - * @param name - * Name of the modified parameter - */ - protected void notifyParameterChanged(String name) { - if (fModule != null) { - fModule.notifyParameterChanged(name); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisManager.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisManager.java deleted file mode 100644 index 3bf69efe67..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisManager.java +++ /dev/null @@ -1,230 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.analysis; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.internal.tmf.core.analysis.TmfAnalysisModuleSources; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Manages the available analysis helpers from different sources and their - * parameter providers. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfAnalysisManager { - - private static final Map fAnalysisModules = new HashMap<>(); - private static final Map>> fParameterProviders = new HashMap<>(); - private static final Map, IAnalysisParameterProvider> fParamProviderInstances = new HashMap<>(); - private static final List fSources = new ArrayList<>(); - private static final List fListeners = new ArrayList<>(); - - /** - * Constructor, not to be used - * TODO This class is not meant to be instantiated, put me private in next major release - * @deprecated It was never meant to be public - */ - @Deprecated - public TmfAnalysisManager() { - - } - - /** - * Registers a new source of modules - * - * @param source - * A {@link IAnalysisModuleSource} instance - */ - public static synchronized void registerModuleSource(IAnalysisModuleSource source) { - fSources.add(source); - refreshModules(); - } - - /** - * Initializes sources and new module listeners from the extension point - */ - public static synchronized void initialize() { - fSources.clear(); - fListeners.clear(); - initializeModuleSources(); - initializeNewModuleListeners(); - } - - /** - * Cleans the module sources list and initialize it from the extension point - */ - private static synchronized void initializeModuleSources() { - for (IAnalysisModuleSource source : TmfAnalysisModuleSources.getSources()) { - fSources.add(source); - } - } - - /** - * Cleans the new module listeners list and initialize it from the extension - * point - */ - private static synchronized void initializeNewModuleListeners() { - for (ITmfNewAnalysisModuleListener output : TmfAnalysisModuleOutputs.getOutputListeners()) { - fListeners.add(output); - } - } - - /** - * Add a new module listener to the list of listeners - * - * @param listener - * The new module listener - */ - public static synchronized void addNewModuleListener(ITmfNewAnalysisModuleListener listener) { - fListeners.add(listener); - } - - /** - * Gets all available analysis module helpers - * - * This map is read-only - * - * @return The map of available {@link IAnalysisModuleHelper} - */ - public static synchronized Map getAnalysisModules() { - if (fAnalysisModules.isEmpty()) { - for (IAnalysisModuleSource source : fSources) { - for (IAnalysisModuleHelper helper : source.getAnalysisModules()) { - fAnalysisModules.put(helper.getId(), helper); - } - } - } - return Collections.unmodifiableMap(fAnalysisModules); - } - - /** - * Gets all analysis module helpers that apply to a given trace type - * - * This map is read-only - * - * @param traceclass - * The trace class to get modules for - * @return The map of available {@link IAnalysisModuleHelper} - */ - public static Map getAnalysisModules(Class traceclass) { - Map allModules = getAnalysisModules(); - Map map = new HashMap<>(); - for (IAnalysisModuleHelper module : allModules.values()) { - if (module.appliesToTraceType(traceclass)) { - map.put(module.getId(), module); - } - } - return Collections.unmodifiableMap(map); - } - - /** - * Gets an analysis module helper identified by an id - * - * @param id - * Id of the analysis module to get - * @return The {@link IAnalysisModuleHelper} - */ - public static IAnalysisModuleHelper getAnalysisModule(String id) { - Map map = getAnalysisModules(); - return map.get(id); - } - - /** - * Register a new parameter provider for an analysis - * - * @param analysisId - * The id of the analysis - * @param paramProvider - * The class of the parameter provider - */ - public static void registerParameterProvider(String analysisId, Class paramProvider) { - synchronized (fParameterProviders) { - if (!fParameterProviders.containsKey(analysisId)) { - fParameterProviders.put(analysisId, new ArrayList>()); - } - fParameterProviders.get(analysisId).add(paramProvider); - } - } - - /** - * Get a parameter provider that applies to the requested trace - * - * @param module - * Analysis module - * @param trace - * The trace - * @return A parameter provider if one applies to the trace, null otherwise - */ - public static List getParameterProviders(IAnalysisModule module, ITmfTrace trace) { - List providerList = new ArrayList<>(); - synchronized (fParameterProviders) { - if (!fParameterProviders.containsKey(module.getId())) { - return providerList; - } - for (Class providerClass : fParameterProviders.get(module.getId())) { - try { - IAnalysisParameterProvider provider = fParamProviderInstances.get(providerClass); - if (provider == null) { - provider = providerClass.newInstance(); - fParamProviderInstances.put(providerClass, provider); - } - if (provider != null) { - if (provider.appliesToTrace(trace)) { - providerList.add(provider); - } - } - } catch (IllegalArgumentException e) { - Activator.logError(Messages.TmfAnalysisManager_ErrorParameterProvider, e); - } catch (SecurityException e) { - Activator.logError(Messages.TmfAnalysisManager_ErrorParameterProvider, e); - } catch (InstantiationException e) { - Activator.logError(Messages.TmfAnalysisManager_ErrorParameterProvider, e); - } catch (IllegalAccessException e) { - Activator.logError(Messages.TmfAnalysisManager_ErrorParameterProvider, e); - } - } - } - return providerList; - } - - /** - * Clear the list of modules so that next time, it is computed again from - * sources - */ - public static synchronized void refreshModules() { - fAnalysisModules.clear(); - } - - /** - * This method should be called when new analysis modules have been created - * by module helpers to that the {@link ITmfNewAnalysisModuleListener} can - * be executed on the module instance. - * - * @param module - * The newly created analysis module - */ - public static synchronized void analysisModuleCreated(IAnalysisModule module) { - for (ITmfNewAnalysisModuleListener listener : fListeners) { - listener.moduleCreated(module); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisModuleHelperConfigElement.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisModuleHelperConfigElement.java deleted file mode 100644 index 4b73977b35..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisModuleHelperConfigElement.java +++ /dev/null @@ -1,206 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - * Mathieu Rail - Added functionality for getting a module's requirements - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.analysis; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -import org.eclipse.core.runtime.ContributorFactoryOSGi; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.InvalidRegistryObjectException; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.internal.tmf.core.analysis.TmfAnalysisModuleSourceConfigElement; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.osgi.util.NLS; -import org.osgi.framework.Bundle; - -/** - * Analysis module helper for modules provided by a plugin's configuration - * elements. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfAnalysisModuleHelperConfigElement implements IAnalysisModuleHelper { - - private final IConfigurationElement fCe; - - /** - * Constructor - * - * @param ce - * The source {@link IConfigurationElement} of this module helper - */ - public TmfAnalysisModuleHelperConfigElement(IConfigurationElement ce) { - fCe = ce; - } - - // ---------------------------------------- - // Wrappers to {@link IAnalysisModule} methods - // ---------------------------------------- - - @Override - public String getId() { - return fCe.getAttribute(TmfAnalysisModuleSourceConfigElement.ID_ATTR); - } - - @Override - public String getName() { - return fCe.getAttribute(TmfAnalysisModuleSourceConfigElement.NAME_ATTR); - } - - @Override - public boolean isAutomatic() { - return Boolean.parseBoolean(fCe.getAttribute(TmfAnalysisModuleSourceConfigElement.AUTOMATIC_ATTR)); - } - - @Override - public String getHelpText() { - /* - * FIXME: No need to externalize this. A better solution will be found - * soon and this string is just temporary - */ - return new String("The trace must be opened to get the help message"); //$NON-NLS-1$ - } - - @Override - public String getIcon() { - return fCe.getAttribute(TmfAnalysisModuleSourceConfigElement.ICON_ATTR); - } - - @Override - public Bundle getBundle() { - return ContributorFactoryOSGi.resolve(fCe.getContributor()); - } - - @Override - public boolean appliesToTraceType(Class traceclass) { - boolean applies = false; - - /* Get the module's applying tracetypes */ - final IConfigurationElement[] tracetypeCE = fCe.getChildren(TmfAnalysisModuleSourceConfigElement.TRACETYPE_ELEM); - for (IConfigurationElement element : tracetypeCE) { - Class applyclass; - try { - applyclass = getBundle().loadClass(element.getAttribute(TmfAnalysisModuleSourceConfigElement.CLASS_ATTR)); - String classAppliesVal = element.getAttribute(TmfAnalysisModuleSourceConfigElement.APPLIES_ATTR); - boolean classApplies = true; - if (classAppliesVal != null) { - classApplies = Boolean.parseBoolean(classAppliesVal); - } - if (classApplies) { - applies |= applyclass.isAssignableFrom(traceclass); - } else { - /* If the trace type does not apply, reset the applies variable to false */ - if (applyclass.isAssignableFrom(traceclass)) { - applies = false; - } - } - } catch (ClassNotFoundException e) { - Activator.logError("Error in applies to trace", e); //$NON-NLS-1$ - } catch (InvalidRegistryObjectException e) { - Activator.logError("Error in applies to trace", e); //$NON-NLS-1$ - } - } - return applies; - } - - @Override - public Iterable> getValidTraceTypes() { - Set> traceTypes = new HashSet<>(); - - for (TraceTypeHelper tth : TmfTraceType.getTraceTypeHelpers()) { - if (appliesToTraceType(tth.getTraceClass())) { - traceTypes.add(tth.getTraceClass()); - } - } - - return traceTypes; - } - - @Override - public Iterable getAnalysisRequirements() { - IAnalysisModule module = createModule(); - if (module != null) { - return module.getAnalysisRequirements(); - } - return Collections.EMPTY_SET; - - } - - // --------------------------------------- - // Functionalities - // --------------------------------------- - - private IAnalysisModule createModule() { - IAnalysisModule module = null; - try { - module = (IAnalysisModule) fCe.createExecutableExtension(TmfAnalysisModuleSourceConfigElement.ANALYSIS_MODULE_ATTR); - module.setName(getName()); - module.setId(getId()); - } catch (CoreException e) { - Activator.logError("Error getting analysis modules from configuration files", e); //$NON-NLS-1$ - } - return module; - } - - @Override - public IAnalysisModule newModule(ITmfTrace trace) throws TmfAnalysisException { - - /* Check that analysis can be executed */ - if (!appliesToTraceType(trace.getClass())) { - throw new TmfAnalysisException(NLS.bind(Messages.TmfAnalysisModuleHelper_AnalysisDoesNotApply, getName())); - } - - IAnalysisModule module = createModule(); - if (module == null) { - return null; - } - - module.setAutomatic(isAutomatic()); - - /* Get the module's parameters */ - final IConfigurationElement[] parametersCE = fCe.getChildren(TmfAnalysisModuleSourceConfigElement.PARAMETER_ELEM); - for (IConfigurationElement element : parametersCE) { - module.addParameter(element.getAttribute(TmfAnalysisModuleSourceConfigElement.NAME_ATTR)); - String defaultValue = element.getAttribute(TmfAnalysisModuleSourceConfigElement.DEFAULT_VALUE_ATTR); - if (defaultValue != null) { - module.setParameter(element.getAttribute(TmfAnalysisModuleSourceConfigElement.NAME_ATTR), defaultValue); - } - } - module.setTrace(trace); - TmfAnalysisManager.analysisModuleCreated(module); - - return module; - - } - - @Override - public String getHelpText(@NonNull ITmfTrace trace) { - IAnalysisModule module = createModule(); - if (module != null) { - String ret = module.getHelpText(trace); - module.dispose(); - return ret; - } - return getHelpText(); - - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisModuleOutputs.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisModuleOutputs.java deleted file mode 100644 index bc32aad6df..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisModuleOutputs.java +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.analysis; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.InvalidRegistryObjectException; -import org.eclipse.core.runtime.Platform; -import org.eclipse.linuxtools.internal.tmf.core.Activator; - -/** - * Utility class for accessing TMF analysis module extensions from the - * platform's extensions registry and returning the modules' outputs, wrapped as - * new module listeners. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfAnalysisModuleOutputs { - - /** Extension point ID */ - public static final String TMF_ANALYSIS_TYPE_ID = "org.eclipse.linuxtools.tmf.core.analysis"; //$NON-NLS-1$ - - /** Extension point element 'output' */ - public static final String OUTPUT_ELEM = "output"; //$NON-NLS-1$ - - /** Extension point attribute 'outputClass' */ - public static final String CLASS_ATTR = "class"; //$NON-NLS-1$ - - /** Extension point attribute 'id' */ - public static final String ID_ATTR = "id"; //$NON-NLS-1$ - - /** - * Extension point element 'analysisId' to associate the output to a single - * analysis - */ - public static final String ANALYSIS_ID_ELEM = "analysisId"; //$NON-NLS-1$ - - /** - * Extension point element 'analysisModuleClass' to associate the output - * with an analysis module class - */ - public static final String MODULE_CLASS_ELEM = "analysisModuleClass"; //$NON-NLS-1$ - - private TmfAnalysisModuleOutputs() { - - } - - /** - * Return the analysis module outputs, wrapped as new module listeners, - * advertised in the extension point, in iterable format. - * - * @return List of {@link ITmfNewAnalysisModuleListener} - */ - public static Iterable getOutputListeners() { - List newModuleListeners = new ArrayList<>(); - // Get the sources element from the extension point - IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_ANALYSIS_TYPE_ID); - for (IConfigurationElement ce : config) { - String elementName = ce.getName(); - if (elementName.equals(OUTPUT_ELEM)) { - try { - IAnalysisOutput output = (IAnalysisOutput) ce.createExecutableExtension(CLASS_ATTR); - ITmfNewAnalysisModuleListener listener = null; - for (IConfigurationElement childCe : ce.getChildren()) { - if (childCe.getName().equals(ANALYSIS_ID_ELEM)) { - listener = new TmfNewAnalysisOutputListener(output, childCe.getAttribute(ID_ATTR), null); - } else if (childCe.getName().equals(MODULE_CLASS_ELEM)) { - listener = new TmfNewAnalysisOutputListener(output, null, childCe.createExecutableExtension(CLASS_ATTR).getClass().asSubclass(IAnalysisModule.class)); - } - } - if (listener != null) { - newModuleListeners.add(listener); - } - } catch (InvalidRegistryObjectException | CoreException e) { - Activator.logError("Error creating module output listener", e); //$NON-NLS-1$ - } - } - } - return newModuleListeners; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisRequirement.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisRequirement.java deleted file mode 100644 index 9397b2469d..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisRequirement.java +++ /dev/null @@ -1,291 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Rail - Initial API and implementation - * Guilliano Molaire - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.analysis; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTraceWithPreDefinedEvents; -import org.eclipse.linuxtools.tmf.core.trace.TmfEventTypeCollectionHelper; - -/** - * Class that contains all the values associated with a type needed by an - * analysis in order to execute. Each value is peered with a level that - * determines the importance of that specific value for the requirement. - * - * The type gives an indication about the kind of value the requirement - * contains. The value should depend on the type. For instance, a requirement - * type could be "event" and all the values that would be added in the - * requirement object could indicate the possible events handled by the - * analysis. - * - * For these values, a level will be assigned indicating how important the value - * is based on two possibilities: Mandatory or optional. - * - * Moreover, useful information that can not be leveled with a priority but are - * important for the proper execution of an analysis can be added. - * - * @author Guilliano Molaire - * @author Mathieu Rail - * @since 3.0 - */ -public class TmfAnalysisRequirement { - - /** - * String for requirement type 'event', that can be used by analysis - */ - public static final String TYPE_EVENT = "event"; //$NON-NLS-1$ - - private final String fType; - private final Map fValues = new HashMap<>(); - private final Set fInformation = new HashSet<>(); - - /** - * The possible level for each value. They must be listed in ascending order - * of priority. - */ - public enum ValuePriorityLevel { - /** The value could be absent and the analysis would still work */ - OPTIONAL, - /** The value must be present at runtime (for the analysis) */ - MANDATORY - } - - /** - * Constructor - * - * @param type - * The type of the requirement - */ - public TmfAnalysisRequirement(String type) { - fType = type; - } - - /** - * Constructor. Instantiate a requirement object with a list of values of - * the same level - * - * @param type - * The type of the requirement - * @param values - * All the values associated with that type - * @param level - * A level associated with all the values - */ - public TmfAnalysisRequirement(String type, Iterable values, ValuePriorityLevel level) { - fType = type; - addValues(values, level); - } - - /** - * Merges the values of the specified requirement with those of this - * requirement. All new values will retain their priority value level. If a - * value was already inside the current requirement, the current priority - * level will be overridden if the new priority level is higher. - * - * @param subRequirement - * The requirement to be merged into the current one - * @param maxSubRequirementValueLevel - * The level associated with all the new values or currently - * lower priority ones - * @return True if the merge was successful - */ - public Boolean merge(TmfAnalysisRequirement subRequirement, ValuePriorityLevel maxSubRequirementValueLevel) { - /* Two requirements can't be merged if their types are different */ - if (!isSameType(subRequirement)) { - return false; - } - - Set values = subRequirement.getValues(); - for (String value : values) { - /* - * Sub-requirement value levels are limited to - * maxSubRequirementValueLevel, so the level associated with the - * values in the merge is the minimum value between - * maxSubRequirementValueLevel and its true level. - */ - int minLevel = Math.min(subRequirement.getValueLevel(value).ordinal(), maxSubRequirementValueLevel.ordinal()); - ValuePriorityLevel subRequirementValueLevel = ValuePriorityLevel.values()[minLevel]; - - if (fValues.containsKey(value)) { - /* - * If a value is already in a requirement, we update the level - * by the highest value between the current level in the - * requirement and the level of the value in the - * sub-requirement. - */ - ValuePriorityLevel requirementValueLevel = getValueLevel(value); - - int newValueLevel = Math.max(requirementValueLevel.ordinal(), subRequirementValueLevel.ordinal()); - ValuePriorityLevel highestLevel = ValuePriorityLevel.values()[newValueLevel]; - addValue(value, highestLevel); - } - else { - addValue(value, subRequirementValueLevel); - } - } - - /* Merge the information */ - fInformation.addAll(subRequirement.getInformation()); - - return true; - } - - /** - * Adds a list of value inside the requirement with the same level. - * - * @param values - * A list of value - * @param level - * The level associated with all the values - */ - public void addValues(Iterable values, ValuePriorityLevel level) { - for (String value : values) { - addValue(value, level); - } - } - - /** - * Adds a value with his associated level into the requirement. If the value - * is already contained in the requirement the method modifies its existing - * value level. - * - * @param value - * The value - * @param level - * The level - */ - public void addValue(String value, ValuePriorityLevel level) { - synchronized (fValues) { - fValues.put(value, level); - } - } - - /** - * Adds an information about the requirement. - * - * @param information - * The information to be added - */ - public void addInformation(String information) { - fInformation.add(information); - } - - /** - * Determines if the analysis requirement has the same type of another - * requirement. - * - * @param requirement - * Requirement whose type is to be compared to this requirement's - * type. - * @return True if the two requirements have the same type; otherwise false - */ - public Boolean isSameType(TmfAnalysisRequirement requirement) { - return fType.equals(requirement.getType()); - } - - /** - * Gets the requirement type. The type is read only. - * - * @return The type of this requirement - */ - public String getType() { - return fType; - } - - /** - * Gets all the values associated with the requirement. - * - * @return Set containing the values - */ - public Set getValues() { - synchronized (fValues) { - return fValues.keySet(); - } - } - - /** - * Gets all the values associated with the requirement with a given priority - * level. - * - * @param level - * The desired level - * @return Set containing the values with the given priority level - */ - public Set getValues(ValuePriorityLevel level) { - synchronized (fValues) { - Set values = new HashSet<>(); - for (Entry entry : fValues.entrySet()) { - if (entry.getValue() == level) { - values.add(entry.getKey()); - } - } - return values; - } - } - - /** - * Gets information about the requirement. - * - * @return The set of all the information - */ - public Set getInformation() { - return fInformation; - } - - /** - * Gets the level associated with a particular type - * - * @param value - * The value - * @return The level or null if the value does not exist - */ - public ValuePriorityLevel getValueLevel(String value) { - synchronized (fValues) { - return fValues.get(value); - } - } - - /** - * Verifies whether a trace fulfills this requirement - * - * @param trace - * The trace on which to check for this requirement - * @return True if the trace has all mandatory values of this requirement - */ - public boolean isFulfilled(@NonNull ITmfTrace trace) { - switch (fType) { - case TYPE_EVENT: - if (trace instanceof ITmfTraceWithPreDefinedEvents) { - Set traceEvents = TmfEventTypeCollectionHelper.getEventNames(((ITmfTraceWithPreDefinedEvents) trace).getContainedEventTypes()); - Set mandatoryValues = getValues(ValuePriorityLevel.MANDATORY); - return traceEvents.containsAll(mandatoryValues); - } - break; - default: - return true; - } - return true; - } - - @Override - public String toString() { - return fType + ": " + fValues; //$NON-NLS-1$ - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisRequirementHelper.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisRequirementHelper.java deleted file mode 100644 index 4377cede63..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisRequirementHelper.java +++ /dev/null @@ -1,128 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Guilliano Molaire - Initial API and implementation - * Mathieu Rail - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.analysis; - -import java.util.HashSet; -import java.util.Set; - -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisRequirement.ValuePriorityLevel; - -import com.google.common.collect.HashMultimap; -import com.google.common.collect.SetMultimap; - -/** - * Helper class to simplify analysis requirement management. - * - * @author Guilliano Molaire - * @since 3.0 - */ -public final class TmfAnalysisRequirementHelper { - - /** - * Private constructor. The class should not be instantiated. - */ - private TmfAnalysisRequirementHelper() { - } - - /** - * Gets the requirement values of a given type from an analysis requirement - * provider. Only values linked to the type will be returned. - * - * @param provider - * The analysis requirement provider - * @param type - * The type of the requirement values we need - * @return The list of values for the specified type - */ - public static Set getRequirementValues(IAnalysisRequirementProvider provider, String type) { - Set values = new HashSet<>(); - for (TmfAnalysisRequirement requirement : provider.getAnalysisRequirements()) { - if (requirement.getType().equalsIgnoreCase(type)) { - values.addAll(requirement.getValues()); - } - } - return values; - } - - /** - * Gets the requirement values of a given type from an analysis requirement - * provider, with the specified level. Only values associated with that type - * and level will be returned. - * - * @param provider - * The analysis requirement provider - * @param type - * The type of the requirement values we need - * @param level - * The priority level of the values to be returned - * @return The list of values for the specified type - */ - public static Set getRequirementValues(IAnalysisRequirementProvider provider, String type, ValuePriorityLevel level) { - Set values = new HashSet<>(); - for (TmfAnalysisRequirement requirement : provider.getAnalysisRequirements()) { - if (requirement.getType().equalsIgnoreCase(type)) { - for (String value : requirement.getValues()) { - if (requirement.getValueLevel(value) == level) { - values.add(value); - } - } - } - } - return values; - } - - /** - * Gets a map in which the keys are the types of different requirements and - * the values represent a set of requirement values linked to that type. - * - * @param providers - * The set of analysis requirement provider - * @return A map with the values keyed by type - */ - public static SetMultimap getRequirementValuesMap(Iterable providers) { - SetMultimap valuesByType = HashMultimap.create(); - for (IAnalysisRequirementProvider provider : providers) { - for (TmfAnalysisRequirement requirement : provider.getAnalysisRequirements()) { - valuesByType.putAll(requirement.getType(), requirement.getValues()); - } - } - return valuesByType; - } - - /** - * Gets a map in which the keys are the types of different requirements and - * the values represents a list of requirement values linked to that type. - * We only take values with the same priority level as the argument. - * - * @param providers - * The set of analysis requirement provider - * @param level - * The priority level of the values to be returned - * @return A map with the values keyed by type - */ - public static SetMultimap getRequirementValuesMap(Iterable providers, ValuePriorityLevel level) { - SetMultimap valuesByType = HashMultimap.create(); - for (IAnalysisRequirementProvider provider : providers) { - for (TmfAnalysisRequirement requirement : provider.getAnalysisRequirements()) { - /* Since it's a set, there will be no duplicate */ - for (String value : requirement.getValues()) { - if (requirement.getValueLevel(value) == level) { - valuesByType.put(requirement.getType(), value); - } - } - } - } - return valuesByType; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfNewAnalysisOutputListener.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfNewAnalysisOutputListener.java deleted file mode 100644 index 2412f1bb6f..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfNewAnalysisOutputListener.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.analysis; - -/** - * This class listens when new analysis modules are created and registers an - * output if the module corresponds to the output specifications - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfNewAnalysisOutputListener implements ITmfNewAnalysisModuleListener { - - private final String fAnalysisId; - private final Class fAnalysisModuleClass; - private final IAnalysisOutput fOutput; - - /** - * Constructor - * - * @param output - * The analysis output to add if the analysis corresponds to the - * ID or class - * @param analysisId - * The analysis ID of the single analysis to match - * @param moduleClass - * The module class this output applies to - */ - public TmfNewAnalysisOutputListener(IAnalysisOutput output, String analysisId, Class moduleClass) { - fOutput = output; - fAnalysisId = analysisId; - fAnalysisModuleClass = moduleClass; - } - - @Override - public void moduleCreated(IAnalysisModule module) { - if (fAnalysisId != null) { - if (module.getId().equals(fAnalysisId)) { - module.registerOutput(fOutput); - } - } else if (fAnalysisModuleClass != null) { - if (fAnalysisModuleClass.isAssignableFrom(module.getClass())) { - module.registerOutput(fOutput); - } - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/messages.properties b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/messages.properties deleted file mode 100644 index 1cd4123a28..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/messages.properties +++ /dev/null @@ -1,24 +0,0 @@ -############################################################################### -# Copyright (c) 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### -TmfAbstractAnalysisModule_TraceSetMoreThanOnce=Trace was set more than once for analysis "{0}" -TmfAbstractAnalysisModule_AnalysisCannotExecute=Cannot perform analysis "{0}" on this trace because the trace does not have the required characteristics -TmfAnalysisModuleHelper_AnalysisDoesNotApply=Cannot perform analysis "{0}" on this trace because the trace is of the wrong type. -TmfAbstractAnalysisModule_AnalysisForTrace=Analysis module: {0} for trace {1} -TmfAbstractAnalysisModule_AnalysisModule=Analysis module: {0} -TmfAbstractAnalysisModule_InvalidParameter=Parameter {0} is not valid for analysis module {1} -TmfAbstractAnalysisModule_NullTrace=Setting a null trace to analysis module -TmfAnalysis_RequirementInformation=Additional information: {0} -TmfAnalysis_RequirementMandatoryValues=Mandatory values: {0} -TmfAnalysis_RequirementNotFulfilled=Requirement not fulfilled: {0} -TmfAbstractAnalysisModule_RunningAnalysis=Running analysis {0} -TmfAnalysisManager_ErrorParameterProvider=Error instantiating parameter provider -TmfAnalysisModuleHelper_ImpossibleToCreateModule=Could not instantiate module "{0}" diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/callstack/CallStackStateProvider.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/callstack/CallStackStateProvider.java deleted file mode 100644 index 54f02e3eac..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/callstack/CallStackStateProvider.java +++ /dev/null @@ -1,198 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.callstack; - -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.statesystem.AbstractTmfStateProvider; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.osgi.util.NLS; - -/** - * The state provider for traces that support the Call Stack view. - * - * The attribute tree should have the following structure: - *

- * (root)
- *   \-- Threads
- *        |-- (Thread 1)
- *        |    \-- CallStack (stack-attribute)
- *        |         |-- 1
- *        |         |-- 2
- *        |        ...
- *        |         \-- n
- *        |-- (Thread 2)
- *        |    \-- CallStack (stack-attribute)
- *        |         |-- 1
- *        |         |-- 2
- *        |        ...
- *        |         \-- n
- *       ...
- *        \-- (Thread n)
- *             \-- CallStack (stack-attribute)
- *                  |-- 1
- *                  |-- 2
- *                 ...
- *                  \-- n
- *
- * where: - *
- * (Thread n) is an attribute whose name is the display name of the thread. - * Optionally, its value is a long representing the thread id, used for sorting. - *
- * CallStack is a stack-attribute whose pushed values are either a string, - * int or long representing the function name or address in the call stack. - * The type of value used must be constant for a particular CallStack. - * - * @author Patrick Tasse - * @since 2.0 - */ -public abstract class CallStackStateProvider extends AbstractTmfStateProvider { - - /** Thread attribute */ - public static final String THREADS = "Threads"; //$NON-NLS-1$ - /** CallStack stack-attribute */ - public static final String CALL_STACK = "CallStack"; //$NON-NLS-1$ - /** Undefined function exit name */ - public static final String UNDEFINED = "UNDEFINED"; //$NON-NLS-1$ - - /** CallStack state system ID */ - private static final String ID = "org.eclipse.linuxtools.tmf.callstack"; //$NON-NLS-1$ - /** Dummy function name for when no function is expected */ - private static final String NO_FUNCTION = "no function"; //$NON-NLS-1$ - - /** - * Default constructor - * - * @param trace - * The trace for which we build this state system - */ - public CallStackStateProvider(ITmfTrace trace) { - super(trace, ITmfEvent.class, ID); - } - - @Override - protected void eventHandle(ITmfEvent event) { - if (!considerEvent(event)) { - return; - } - try { - /* Check if the event is a function entry */ - String functionEntryName = functionEntry(event); - if (functionEntryName != null) { - long timestamp = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - String thread = getThreadName(event); - int threadQuark = ss.getQuarkAbsoluteAndAdd(THREADS, thread); - Long threadId = getThreadId(event); - if (threadId != null) { - ss.updateOngoingState(TmfStateValue.newValueLong(threadId), threadQuark); - } - int callStackQuark = ss.getQuarkRelativeAndAdd(threadQuark, CALL_STACK); - ITmfStateValue value = TmfStateValue.newValueString(functionEntryName); - ss.pushAttribute(timestamp, value, callStackQuark); - return; - } - - /* Check if the event is a function exit */ - String functionExitName = functionExit(event); - if (functionExitName != null) { - long timestamp = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - String thread = getThreadName(event); - int quark = ss.getQuarkAbsoluteAndAdd(THREADS, thread, CALL_STACK); - ITmfStateValue poppedValue = ss.popAttribute(timestamp, quark); - String poppedName = (poppedValue == null ? NO_FUNCTION : poppedValue.unboxStr()); - - /* - * Verify that the value we are popping matches the one in the - * event field, unless the latter is undefined. - */ - if (!functionExitName.equals(UNDEFINED) && - !functionExitName.equals(poppedName)) { - Activator.logWarning(NLS.bind( - Messages.CallStackStateProvider_UnmatchedPoppedValue, - functionExitName, - poppedName)); - } - } - - } catch (TimeRangeException e) { - e.printStackTrace(); - } catch (AttributeNotFoundException e) { - e.printStackTrace(); - } catch (StateValueTypeException e) { - e.printStackTrace(); - } - } - - /** - * Check if this event should be considered at all for function entry/exit - * analysis. This check is only run once per event, before - * {@link #functionEntry} and {@link #functionExit} (to avoid repeating - * checks in those methods). - * - * @param event - * The event to check - * @return If false, the event will be ignored by the state provider. If - * true processing will continue. - * @since 3.0 - */ - protected abstract boolean considerEvent(ITmfEvent event); - - /** - * Check an event if it indicates a function entry. - * - * @param event - * An event to check for function entry - * @return The function name of the function entry, or null if not a - * function entry. - */ - protected abstract String functionEntry(ITmfEvent event); - - /** - * Check an event if it indicates a function exit. - * - * @param event - * An event to check for function exit - * @return The function name, or UNDEFINED, for a function exit, or null if - * not a function exit. - */ - protected abstract String functionExit(ITmfEvent event); - - /** - * Return the thread name of a function entry or exit event. - * - * @param event - * The event - * @return The thread name (as will be shown in the view) - * @since 3.0 - */ - protected abstract String getThreadName(ITmfEvent event); - - /** - * Return the thread id of a function entry event. - * - * @param event - * The event - * @return The thread id, or null if undefined - * @since 3.1 - */ - protected Long getThreadId(ITmfEvent event) { - return null; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/callstack/Messages.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/callstack/Messages.java deleted file mode 100644 index eaf0f7c394..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/callstack/Messages.java +++ /dev/null @@ -1,39 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.callstack; - -import org.eclipse.osgi.util.NLS; - -/** - * Message bundle for the call stack state provider. - * - * @since 3.0 - */ -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.core.callstack.messages"; //$NON-NLS-1$ - - /** - * The value popped from a 'func_exit' event doesn't match the current - * function name. - */ - public static String CallStackStateProvider_UnmatchedPoppedValue; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/callstack/messages.properties b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/callstack/messages.properties deleted file mode 100644 index 4603be0526..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/callstack/messages.properties +++ /dev/null @@ -1,13 +0,0 @@ -############################################################################### -# Copyright (c) 2013 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Alexandre Montplaisir - Initial API and implementation -############################################################################### - -CallStackStateProvider_UnmatchedPoppedValue=Function exit name in event ({0}) different from the expected one ({1}). You may have lost events in your trace. diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/ITmfComponent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/ITmfComponent.java deleted file mode 100644 index c5aeafa739..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/ITmfComponent.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Add interface for broadcasting signals asynchronously - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.component; - -import org.eclipse.linuxtools.tmf.core.signal.TmfSignal; - -/** - * This is the basic interface of all the TMF components. - *

- * Currently, it only addresses the inter-component signalling. - * - * @version 1.0 - * @author Francois Chouinard - * - * @see TmfComponent - */ -public interface ITmfComponent { - - /** - * @return the component ID (display name) - */ - String getName(); - - /** - * Dispose of the component - */ - void dispose(); - - /** - * Propagate a signal to all the interested listeners in - * the same thread of execution. - * - * @param signal the signal to broadcast - */ - void broadcast(TmfSignal signal); - - /** - * Propagate a signal to all the interested listeners - * in a separate thread. - * - * @param signal the signal to broadcast - * @since 3.0 - */ - void broadcastAsync(TmfSignal signal); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/ITmfEventProvider.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/ITmfEventProvider.java deleted file mode 100644 index e26e717f54..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/ITmfEventProvider.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.component; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; - -/** - * This is the interface of the data providers in TMF. Data providers have the - * capability of handling data requests. - * - * @author Francois Chouinard - * - * @see TmfEventProvider - * @since 3.0 - */ -public interface ITmfEventProvider extends ITmfComponent { - - /** - * Queue the request for processing. - * - * @param request The request to process - */ - void sendRequest(ITmfEventRequest request); - - /** - * Increments/decrements the pending requests counters and fires the request - * if necessary (counter == 0). Used for coalescing requests across multiple - * TmfDataProvider's. - * - * @param isIncrement - * Should we increment (true) or decrement (false) the pending - * counter - */ - void notifyPendingRequest(boolean isIncrement); - - /** - * Return the next event based on the context supplied. The context - * will be updated for the subsequent read. - * - * @param context the trace read context (updated) - * @return the event referred to by context - */ - ITmfEvent getNext(ITmfContext context); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/TmfComponent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/TmfComponent.java deleted file mode 100644 index 25692eea89..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/TmfComponent.java +++ /dev/null @@ -1,119 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Add interface for broadcasting signals asynchronously - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.component; - -import org.eclipse.linuxtools.internal.tmf.core.TmfCoreTracer; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; - -/** - * This is the base class of the TMF components. - *

- * Currently, it only addresses the inter-component signaling. - * - * @version 1.0 - * @author Francois Chouinard - */ -public abstract class TmfComponent implements ITmfComponent { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private String fName; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Default constructor. To be used in conjunction with init() - */ - public TmfComponent() { - this(""); //$NON-NLS-1$ - } - - /** - * Perform component initialization and register it as a signal listener. - * Need to be called when the default constructor was used. - * - * @param name - * the component name - */ - public void init(String name) { - TmfCoreTracer.traceComponent(this, "created"); //$NON-NLS-1$ - fName = name; - TmfSignalManager.register(this); - } - - /** - * The standard constructor - * - * @param name - * the component name - */ - public TmfComponent(String name) { - init(name); - } - - /** - * The copy constructor - * - * @param other - * the other component - */ - public TmfComponent(TmfComponent other) { - init(other.fName); - } - - // ------------------------------------------------------------------------ - // Getters/setters - // ------------------------------------------------------------------------ - - @Override - public String getName() { - return fName; - } - - /** - * @param name - * the new component name - */ - protected void setName(String name) { - fName = name; - } - - // ------------------------------------------------------------------------ - // ITmfComponent - // ------------------------------------------------------------------------ - - @Override - public void dispose() { - TmfSignalManager.deregister(this); - TmfCoreTracer.traceComponent(this, "disposed"); //$NON-NLS-1$ - } - - @Override - public void broadcast(TmfSignal signal) { - TmfSignalManager.dispatchSignal(signal); - } - - /** - * @since 3.0 - */ - @Override - public void broadcastAsync(TmfSignal signal) { - TmfSignalManager.dispatchSignalAsync(signal); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/TmfEventProvider.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/TmfEventProvider.java deleted file mode 100644 index 83a318c289..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/TmfEventProvider.java +++ /dev/null @@ -1,439 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation, replace background - * requests by preemptable requests - * Alexandre Montplaisir - Merge with TmfDataProvider - * Bernd Hufmann - Add timer based coalescing for background requests - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.component; - -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; - -import org.eclipse.linuxtools.internal.tmf.core.TmfCoreTracer; -import org.eclipse.linuxtools.internal.tmf.core.component.TmfEventThread; -import org.eclipse.linuxtools.internal.tmf.core.component.TmfProviderManager; -import org.eclipse.linuxtools.internal.tmf.core.request.TmfCoalescedEventRequest; -import org.eclipse.linuxtools.internal.tmf.core.request.TmfRequestExecutor; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest.ExecutionType; -import org.eclipse.linuxtools.tmf.core.signal.TmfEndSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfStartSynchSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; - -/** - * An abstract base class that implements ITmfEventProvider. - *

- * This abstract class implements the housekeeping methods to register/ - * de-register the event provider and to handle generically the event requests. - *

- * - * @author Francois Chouinard - * @since 3.0 - */ -public abstract class TmfEventProvider extends TmfComponent implements ITmfEventProvider { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** Default amount of events per request "chunk" - * @since 3.0 */ - public static final int DEFAULT_BLOCK_SIZE = 50000; - - /** Delay for coalescing background requests (in milli-seconds) */ - private static final long DELAY = 1000; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** List of coalesced requests */ - private final List fPendingCoalescedRequests = new LinkedList<>(); - - /** The type of event handled by this provider */ - private Class fType; - - private final TmfRequestExecutor fExecutor; - - private final Object fLock = new Object(); - - private int fSignalDepth = 0; - - private int fRequestPendingCounter = 0; - - private Timer fTimer; - - private boolean fIsTimeout = false; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - public TmfEventProvider() { - super(); - fExecutor = new TmfRequestExecutor(); - } - - /** - * Standard constructor. Instantiate and initialize at the same time. - * - * @param name - * Name of the provider - * @param type - * The type of events that will be handled - */ - public TmfEventProvider(String name, Class type) { - this(); - init(name, type); - } - - /** - * Initialize this data provider - * - * @param name - * Name of the provider - * @param type - * The type of events that will be handled - */ - public void init(String name, Class type) { - super.init(name); - fType = type; - fExecutor.init(); - - fSignalDepth = 0; - - synchronized (fLock) { - fTimer = new Timer(); - } - - TmfProviderManager.register(fType, this); - } - - @Override - public void dispose() { - TmfProviderManager.deregister(fType, this); - fExecutor.stop(); - synchronized (fLock) { - if (fTimer != null) { - fTimer.cancel(); - } - fTimer = null; - } - super.dispose(); - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Get the event type this provider handles - * - * @return The type of ITmfEvent - */ - public Class getType() { - return fType; - } - - // ------------------------------------------------------------------------ - // ITmfRequestHandler - // ------------------------------------------------------------------------ - - /** - * @since 3.0 - */ - @Override - public void sendRequest(final ITmfEventRequest request) { - synchronized (fLock) { - if (request.getExecType() == ExecutionType.FOREGROUND) { - if ((fSignalDepth > 0) || (fRequestPendingCounter > 0)) { - coalesceEventRequest(request); - } else { - queueRequest(request); - } - return; - } - - /* - * Dispatch request in case timer is not running. - */ - if (fTimer == null) { - queueRequest(request); - return; - } - - /* - * For the first background request in the request pending queue - * a timer will be started to allow other background requests to - * coalesce. - */ - boolean startTimer = (getNbPendingBackgroundRequests() == 0); - coalesceEventRequest(request); - if (startTimer) { - TimerTask task = new TimerTask() { - @Override - public void run() { - synchronized (fLock) { - fIsTimeout = true; - fireRequest(); - } - } - }; - fTimer.schedule(task, DELAY); - } - } - } - - private void fireRequest() { - synchronized (fLock) { - if (fRequestPendingCounter > 0) { - return; - } - - if (fPendingCoalescedRequests.size() > 0) { - Iterator iter = fPendingCoalescedRequests.iterator(); - while (iter.hasNext()) { - ExecutionType type = (fIsTimeout ? ExecutionType.BACKGROUND : ExecutionType.FOREGROUND); - ITmfEventRequest request = iter.next(); - if (type == request.getExecType()) { - queueRequest(request); - iter.remove(); - } - } - } - } - } - - /** - * Increments/decrements the pending requests counters and fires the request - * if necessary (counter == 0). Used for coalescing requests across multiple - * TmfDataProvider's. - * - * @param isIncrement - * Should we increment (true) or decrement (false) the pending - * counter - */ - @Override - public void notifyPendingRequest(boolean isIncrement) { - synchronized (fLock) { - if (isIncrement) { - fRequestPendingCounter++; - } else { - if (fRequestPendingCounter > 0) { - fRequestPendingCounter--; - } - - // fire request if all pending requests are received - if (fRequestPendingCounter == 0) { - fireRequest(); - } - } - } - } - - // ------------------------------------------------------------------------ - // Coalescing - // ------------------------------------------------------------------------ - - /** - * Create a new request from an existing one, and add it to the coalesced - * requests - * - * @param request - * The request to copy - * @since 3.0 - */ - protected void newCoalescedEventRequest(ITmfEventRequest request) { - synchronized (fLock) { - TmfCoalescedEventRequest coalescedRequest = new TmfCoalescedEventRequest( - request.getDataType(), - request.getRange(), - request.getIndex(), - request.getNbRequested(), - request.getExecType()); - coalescedRequest.addRequest(request); - if (TmfCoreTracer.isRequestTraced()) { - TmfCoreTracer.traceRequest(request, "COALESCED with " + coalescedRequest.getRequestId()); //$NON-NLS-1$ - TmfCoreTracer.traceRequest(coalescedRequest, "now contains " + coalescedRequest.getSubRequestIds()); //$NON-NLS-1$ - } - fPendingCoalescedRequests.add(coalescedRequest); - } - } - - /** - * Add an existing requests to the list of coalesced ones - * - * @param request - * The request to add to the list - * @since 3.0 - */ - protected void coalesceEventRequest(ITmfEventRequest request) { - synchronized (fLock) { - for (TmfCoalescedEventRequest coalescedRequest : fPendingCoalescedRequests) { - if (coalescedRequest.isCompatible(request)) { - coalescedRequest.addRequest(request); - if (TmfCoreTracer.isRequestTraced()) { - TmfCoreTracer.traceRequest(request, "COALESCED with " + coalescedRequest.getRequestId()); //$NON-NLS-1$ - TmfCoreTracer.traceRequest(coalescedRequest, "now contains " + coalescedRequest.getSubRequestIds()); //$NON-NLS-1$ - } - return; - } - } - newCoalescedEventRequest(request); - } - } - - /** - * Gets the number of background requests in pending queue. - * - * @return the number of background requests in pending queue - */ - private int getNbPendingBackgroundRequests() { - int nbBackgroundRequests = 0; - synchronized (fLock) { - for (ITmfEventRequest request : fPendingCoalescedRequests) { - if (request.getExecType() == ExecutionType.BACKGROUND) { - nbBackgroundRequests++; - } - } - } - return nbBackgroundRequests; - } - - // ------------------------------------------------------------------------ - // Request processing - // ------------------------------------------------------------------------ - - /** - * Queue a request. - * - * @param request - * The data request - * @since 3.0 - */ - protected void queueRequest(final ITmfEventRequest request) { - - if (fExecutor.isShutdown()) { - request.cancel(); - return; - } - - TmfEventThread thread = new TmfEventThread(this, request); - - if (TmfCoreTracer.isRequestTraced()) { - TmfCoreTracer.traceRequest(request, "QUEUED"); //$NON-NLS-1$ - } - - fExecutor.execute(thread); - } - - /** - * Initialize the provider based on the request. The context is provider - * specific and will be updated by getNext(). - * - * @param request - * The request - * @return An application specific context; null if request can't be - * serviced - * @since 3.0 - */ - public abstract ITmfContext armRequest(ITmfEventRequest request); - - /** - * Checks if the data meets the request completion criteria. - * - * @param request - * The request - * @param event - * The data to verify - * @param nbRead - * The number of events read so far - * @return true if completion criteria is met - * @since 3.0 - */ - public boolean isCompleted(ITmfEventRequest request, ITmfEvent event, int nbRead) { - boolean requestCompleted = isCompleted2(request, nbRead); - if (!requestCompleted) { - ITmfTimestamp endTime = request.getRange().getEndTime(); - return event.getTimestamp().compareTo(endTime, false) > 0; - } - return requestCompleted; - } - - private static boolean isCompleted2(ITmfEventRequest request,int nbRead) { - return request.isCompleted() || nbRead >= request.getNbRequested(); - } - - // ------------------------------------------------------------------------ - // Pass-through's to the request executor - // ------------------------------------------------------------------------ - - /** - * @return the shutdown state (i.e. if it is accepting new requests) - * @since 2.0 - */ - protected boolean executorIsShutdown() { - return fExecutor.isShutdown(); - } - - /** - * @return the termination state - * @since 2.0 - */ - protected boolean executorIsTerminated() { - return fExecutor.isTerminated(); - } - - // ------------------------------------------------------------------------ - // Signal handlers - // ------------------------------------------------------------------------ - - /** - * Handler for the start synch signal - * - * @param signal - * Incoming signal - */ - @TmfSignalHandler - public void startSynch(TmfStartSynchSignal signal) { - synchronized (fLock) { - fSignalDepth++; - } - } - - /** - * Handler for the end synch signal - * - * @param signal - * Incoming signal - */ - @TmfSignalHandler - public void endSynch(TmfEndSynchSignal signal) { - synchronized (fLock) { - fSignalDepth--; - if (fSignalDepth == 0) { - fIsTimeout = false; - fireRequest(); - } - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfCustomAttributes.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfCustomAttributes.java deleted file mode 100644 index 923c5ca459..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfCustomAttributes.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Simon Delisle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event; - -import java.util.Set; - -/** - * Interface for events to implement to provide information about custom - * attributes. - * - * @author Simon Delisle - * @since 2.0 - */ -public interface ITmfCustomAttributes { - - /** - * List the custom attributes of this event. - * - * @return The list of custom attribute names. Should not be null, but could - * be empty. - */ - Set listCustomAttributes(); - - /** - * Get the value of a custom attribute. - * - * @param name - * Name of the the custom attribute - * @return Value of this attribute, or null if there is no attribute with - * that name - */ - String getCustomAttribute(String name); -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfEvent.java deleted file mode 100644 index 807552e565..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfEvent.java +++ /dev/null @@ -1,113 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event; - -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * The generic event structure in TMF. In its canonical form, an event has: - *
    - *
  • a parent trace - *
  • a rank (order within the trace) - *
  • a timestamp - *
  • a source (reporting component) - *
  • a type - *
  • a content (payload) - *
- * For convenience, a free-form reference field is also provided. It could be - * used as e.g. a location marker (filename:lineno) to indicate where the event - * was generated. - * - * @version 1.0 - * @author Francois Chouinard - * - * @see ITmfTimestamp - * @see ITmfEventType - * @see ITmfEventField - * @see TmfEvent - */ -public interface ITmfEvent extends IAdaptable { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * Pre-defined event timestamp attribute (for searching &filtering purposes) - */ - public static final @NonNull String EVENT_FIELD_TIMESTAMP = ":timestamp:"; //$NON-NLS-1$ - - /** - * Pre-defined event source attribute (for searching &filtering purposes) - */ - public static final @NonNull String EVENT_FIELD_SOURCE = ":source:"; //$NON-NLS-1$ - - /** - * Pre-defined event type attribute (for searching &filtering purposes) - */ - public static final @NonNull String EVENT_FIELD_TYPE = ":type:"; //$NON-NLS-1$ - - /** - * Pre-defined event content attribute (for searching &filtering purposes) - */ - public static final @NonNull String EVENT_FIELD_CONTENT = ":content:"; //$NON-NLS-1$ - - /** - * Pre-defined event reference attribute (for searching &filtering purposes) - */ - public static final @NonNull String EVENT_FIELD_REFERENCE = ":reference:"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Getters - // ------------------------------------------------------------------------ - - /** - * @return the trace that 'owns' the event - */ - ITmfTrace getTrace(); - - /** - * @return the event rank within the parent trace - */ - long getRank(); - - /** - * @return the event timestamp - * @since 2.0 - */ - ITmfTimestamp getTimestamp(); - - /** - * @return the event source - */ - String getSource(); - - /** - * @return the event type - */ - ITmfEventType getType(); - - /** - * @return the event content - */ - ITmfEventField getContent(); - - /** - * @return the event reference - */ - String getReference(); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfEventField.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfEventField.java deleted file mode 100644 index 72f250f6d1..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfEventField.java +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Alexandre Montplaisir - Removed arrays from the API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event; - -import java.util.Collection; - -import org.eclipse.jdt.annotation.NonNull; - -/** - * The generic event payload in TMF. Each field can be either a terminal or - * further decomposed into subfields. - * - * @version 1.0 - * @author Francois Chouinard - * - * @see ITmfEvent - * @see ITmfEventType - */ -public interface ITmfEventField { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The root field id (the main container) - */ - public static final @NonNull String ROOT_FIELD_ID = ":root:"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Getters - // ------------------------------------------------------------------------ - - /** - * @return the field name - */ - String getName(); - - /** - * @return the field value - */ - Object getValue(); - - /** - * @return the value formatted as string - * @since 2.0 - */ - String getFormattedValue(); - - /** - * Return the subfield names. The iteration order is the same as - * {@link #getFields()}. The returned Collection is immutable. - * - * @return The subfield names (empty Collection if none) - * @since 3.0 - */ - Collection getFieldNames(); - - /** - * Return the subfield. The iteration order is the same as - * {@link #getFieldNames()}. The returned Collection is immutable. - * - * @return The subfields (empty Collection if none) - * @since 3.0 - */ - Collection getFields(); - - /** - * @param name The name of the field - * @return a specific subfield by name (null if absent or inexistent) - */ - ITmfEventField getField(String name); - - /** - * Gets the a sub-field of this field, which may be multiple levels down. - * - * @param path - * Array of field names to recursively go through - * @return The field at the end, or null if a field in the path cannot be - * found - * @since 3.0 - */ - ITmfEventField getSubField(String... path); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfEventType.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfEventType.java deleted file mode 100644 index 07dd4b3e5e..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfEventType.java +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event; - -import java.util.Collection; - -/** - * The generic event type in TMF. It contains a reference to the full field structure - * for that event type. - *

- * Types are unique within their context space. - * - * @version 1.0 - * @author Francois Chouinard - * - * @see ITmfEvent - * @see ITmfEventField - */ -public interface ITmfEventType { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The default event type content - */ - public static final String DEFAULT_CONTEXT_ID = "TmfContext"; //$NON-NLS-1$ - - /** - * The default event type name - */ - public static final String DEFAULT_TYPE_ID = "TmfType"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Getters - // ------------------------------------------------------------------------ - - /** - * @return the event type context - */ - String getContext(); - - /** - * @return the event type ID - */ - String getName(); - - /** - * @return the event type root field - */ - ITmfEventField getRootField(); - - /** - * @return the event field names (labels) - * @since 3.0 - */ - Collection getFieldNames(); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfLostEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfLostEvent.java deleted file mode 100644 index 8408e3caba..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/ITmfLostEvent.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event; - -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; - -/** - * The generic lost event structure in TMF. - * - * In some demanding situations, tracers can be overwhelmed and have a hard time - * keeping up with the flow of events to record. Usually, even if a tracer can't - * keep up, it can at least record the number of events that it lost. - * - * This interface provides the different components (e.g. views) with a mean to - * identify and highlight such events. - * - * This interface extends ITmfEvent by adding the number of lost events for a - * 'problematic' time range. - * - * @see TmfLostEvent - * - * @author Francois Chouinard - * @version 1.0 - * @since 1.2 - */ -public interface ITmfLostEvent extends ITmfEvent { - - // ------------------------------------------------------------------------ - // Getters - // ------------------------------------------------------------------------ - - /** - * @return the 'problem' time range - * @since 2.0 - */ - TmfTimeRange getTimeRange(); - - /** - * @return the number of lost events in the time range - */ - long getNbLostEvents(); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfEvent.java deleted file mode 100644 index 0a1763a864..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfEvent.java +++ /dev/null @@ -1,249 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Updated as per TMF Event Model 1.0 - * Alexandre Montplaisir - Made immutable - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event; - -import org.eclipse.core.runtime.PlatformObject; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * A basic implementation of ITmfEvent. - * - * @version 1.0 - * @author Francois Chouinard - * - * @see ITmfTimestamp - * @see ITmfEventType - * @see ITmfEventField - * @see ITmfTrace - */ -public class TmfEvent extends PlatformObject implements ITmfEvent { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final ITmfTrace fTrace; - private final long fRank; - private final ITmfTimestamp fTimestamp; - private final String fSource; - private final ITmfEventType fType; - private final ITmfEventField fContent; - private final String fReference; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor. All fields have their default value (null) and the - * event rank is set to TmfContext.UNKNOWN_RANK. - */ - public TmfEvent() { - this(null, ITmfContext.UNKNOWN_RANK, null, null, null, null, null); - } - - /** - * Standard constructor. The event rank will be set to TmfContext.UNKNOWN_RANK. - * - * @param trace the parent trace - * @param timestamp the event timestamp - * @param source the event source - * @param type the event type - * @param content the event content (payload) - * @param reference the event reference - * @since 2.0 - - */ - public TmfEvent(final ITmfTrace trace, final ITmfTimestamp timestamp, final String source, - final ITmfEventType type, final ITmfEventField content, final String reference) - { - this(trace, ITmfContext.UNKNOWN_RANK, timestamp, source, type, content, reference); - } - - /** - * Full constructor - * - * @param trace the parent trace - * @param rank the event rank (in the trace) - * @param timestamp the event timestamp - * @param source the event source - * @param type the event type - * @param content the event content (payload) - * @param reference the event reference - * @since 2.0 - */ - public TmfEvent(final ITmfTrace trace, final long rank, final ITmfTimestamp timestamp, final String source, - final ITmfEventType type, final ITmfEventField content, final String reference) - { - fTrace = trace; - fRank = rank; - fTimestamp = timestamp; - fSource = source; - fType = type; - fContent = content; - fReference = reference; - } - - /** - * Copy constructor - * - * @param event the original event - */ - public TmfEvent(final ITmfEvent event) { - if (event == null) { - throw new IllegalArgumentException(); - } - fTrace = event.getTrace(); - fRank = event.getRank(); - fTimestamp = event.getTimestamp(); - fSource = event.getSource(); - fType = event.getType(); - fContent = event.getContent(); - fReference = event.getReference(); - } - - // ------------------------------------------------------------------------ - // ITmfEvent - // ------------------------------------------------------------------------ - - @Override - public ITmfTrace getTrace() { - return fTrace; - } - - @Override - public long getRank() { - return fRank; - } - - /** - * @since 2.0 - */ - @Override - public ITmfTimestamp getTimestamp() { - return fTimestamp; - } - - @Override - public String getSource() { - return fSource; - } - - @Override - public ITmfEventType getType() { - return fType; - } - - @Override - public ITmfEventField getContent() { - return fContent; - } - - @Override - public String getReference() { - return fReference; - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((fTrace == null) ? 0 : fTrace.hashCode()); - result = prime * result + (int) (fRank ^ (fRank >>> 32)); - result = prime * result + ((fTimestamp == null) ? 0 : fTimestamp.hashCode()); - result = prime * result + ((fSource == null) ? 0 : fSource.hashCode()); - result = prime * result + ((fType == null) ? 0 : fType.hashCode()); - result = prime * result + ((fContent == null) ? 0 : fContent.hashCode()); - result = prime * result + ((fReference == null) ? 0 : fReference.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof TmfEvent)) { - return false; - } - final TmfEvent other = (TmfEvent) obj; - if (fTrace == null) { - if (other.fTrace != null) { - return false; - } - } else if (!fTrace.equals(other.fTrace)) { - return false; - } - if (fRank != other.fRank) { - return false; - } - if (fTimestamp == null) { - if (other.fTimestamp != null) { - return false; - } - } else if (!fTimestamp.equals(other.fTimestamp)) { - return false; - } - if (fSource == null) { - if (other.fSource != null) { - return false; - } - } else if (!fSource.equals(other.fSource)) { - return false; - } - if (fType == null) { - if (other.fType != null) { - return false; - } - } else if (!fType.equals(other.fType)) { - return false; - } - if (fContent == null) { - if (other.fContent != null) { - return false; - } - } else if (!fContent.equals(other.fContent)) { - return false; - } - if (fReference == null) { - if (other.fReference != null) { - return false; - } - } else if (!fReference.equals(other.fReference)) { - return false; - } - return true; - } - - @Override - @SuppressWarnings("nls") - public String toString() { - return getClass().getSimpleName() + " [fTimestamp=" + getTimestamp() - + ", fTrace=" + getTrace() + ", fRank=" + getRank() - + ", fSource=" + getSource() + ", fType=" + getType() - + ", fContent=" + getContent() + ", fReference=" + getReference() - + "]"; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfEventField.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfEventField.java deleted file mode 100644 index f98221b8c7..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfEventField.java +++ /dev/null @@ -1,261 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Updated as per TMF Event Model 1.0 - * Alexandre Montplaisir - Removed Cloneable, made immutable - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event; - -import java.util.Collection; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableMap; - -/** - * A basic implementation of ITmfEventField. - *

- * Non-value fields are structural (i.e. used to represent the event structure - * including optional fields) while the valued fields are actual event fields. - * - * @version 1.0 - * @author Francois Chouinard - * - * @see ITmfEvent - * @see ITmfEventType - */ -public class TmfEventField implements ITmfEventField { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final @NonNull String fName; - private final @Nullable Object fValue; - private final @NonNull ImmutableMap fFields; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Full constructor - * - * @param name - * the event field id - * @param value - * the event field value - * @param fields - * the list of subfields - * @throws IllegalArgumentException - * If 'name' is null, or if 'fields' has duplicate field names. - */ - @SuppressWarnings("null") /* ImmutableMap methods do not return @NonNull */ - public TmfEventField(String name, @Nullable Object value, @Nullable ITmfEventField[] fields) { - if (name == null) { - throw new IllegalArgumentException(); - } - fName = name; - fValue = value; - - if (fields == null) { - fFields = ImmutableMap.of(); - } else { - /* Java 8 streams will make this even more simple! */ - ImmutableMap.Builder mapBuilder = new ImmutableMap.Builder<>(); - for (ITmfEventField field : fields) { - final String curName = field.getName(); - mapBuilder.put(curName, field); - } - fFields = mapBuilder.build(); - } - } - - /** - * Copy constructor - * - * @param field the other event field - */ - public TmfEventField(final TmfEventField field) { - if (field == null) { - throw new IllegalArgumentException(); - } - fName = field.fName; - fValue = field.fValue; - fFields = field.fFields; - } - - // ------------------------------------------------------------------------ - // ITmfEventField - // ------------------------------------------------------------------------ - - @Override - public String getName() { - return fName; - } - - @Override - public Object getValue() { - return fValue; - } - - /** - * @since 3.0 - */ - @Override - public Collection getFieldNames() { - return fFields.keySet(); - } - - /** - * @since 3.0 - */ - @Override - public Collection getFields() { - return fFields.values(); - } - - @Override - public ITmfEventField getField(final String name) { - return fFields.get(name); - } - - /** - * @since 3.0 - */ - @Override - public ITmfEventField getSubField(final String... names) { - ITmfEventField field = this; - for (String name : names) { - field = field.getField(name); - if (field == null) { - return null; - } - } - return field; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Create a root field from a list of labels. - * - * @param labels the list of labels - * @return the (flat) root list - */ - public final static ITmfEventField makeRoot(final String[] labels) { - final ITmfEventField[] fields = new ITmfEventField[labels.length]; - for (int i = 0; i < labels.length; i++) { - fields[i] = new TmfEventField(labels[i], null, null); - } - // Return a new root field; - return new TmfEventField(ITmfEventField.ROOT_FIELD_ID, null, fields); - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - Object value = fValue; - final int prime = 31; - int result = 1; - result = prime * result + fName.hashCode(); - result = prime * result + ((value == null) ? 0 : value.hashCode()); - result = prime * result + fFields.hashCode(); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof TmfEventField)) { - return false; - } - - final TmfEventField other = (TmfEventField) obj; - - /* Check that 'fName' is the same */ - if (!fName.equals(other.fName)) { - return false; - } - - /* Check that 'fValue' is the same */ - Object value = this.fValue; - if (value == null) { - if (other.fValue != null) { - return false; - } - } else if (!value.equals(other.fValue)) { - return false; - } - - /* Check that 'fFields' are the same */ - if (!fFields.equals(other.fFields)) { - return false; - } - - return true; - } - - @Override - public String toString() { - StringBuilder ret = new StringBuilder(); - if (fName.equals(ITmfEventField.ROOT_FIELD_ID)) { - /* - * If this field is a top-level "field container", we will print its - * sub-fields directly. - */ - appendSubFields(ret); - - } else { - /* The field has its own values */ - ret.append(fName); - ret.append('='); - ret.append(fValue); - - if (!fFields.isEmpty()) { - /* - * In addition to its own name/value, this field also has - * sub-fields. - */ - ret.append(" ["); //$NON-NLS-1$ - appendSubFields(ret); - ret.append(']'); - } - } - return ret.toString(); - } - - private void appendSubFields(StringBuilder sb) { - Joiner joiner = Joiner.on(", ").skipNulls(); //$NON-NLS-1$ - sb.append(joiner.join(getFields())); - } - - /** - * @since 2.0 - */ - @Override - public String getFormattedValue() { - return getValue().toString(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfEventType.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfEventType.java deleted file mode 100644 index da6a08ab62..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfEventType.java +++ /dev/null @@ -1,149 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Updated as per TMF Event Model 1.0 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event; - -import java.util.Collection; -import java.util.Collections; - -/** - * A basic implementation of ITmfEventType. - * - * @version 1.0 - * @author Francois Chouinard - * - * @see ITmfEvent - * @see ITmfEventField - */ -public class TmfEventType implements ITmfEventType { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final String fContext; - private final String fTypeId; - private final ITmfEventField fRootField; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - public TmfEventType() { - this(DEFAULT_CONTEXT_ID, DEFAULT_TYPE_ID, null); - } - - /** - * Full constructor - * - * @param context the type context - * @param typeId the type name - * @param root the root field - */ - public TmfEventType(final String context, final String typeId, final ITmfEventField root) { - if (context == null || typeId == null) { - throw new IllegalArgumentException(); - } - fContext = context; - fTypeId = typeId; - fRootField = root; - - // Register to the event type manager - TmfEventTypeManager.getInstance().add(context, this); - } - - /** - * Copy constructor - * - * @param type the other type - */ - public TmfEventType(final ITmfEventType type) { - if (type == null) { - throw new IllegalArgumentException(); - } - fContext = type.getContext(); - fTypeId = type.getName(); - fRootField = type.getRootField(); - } - - // ------------------------------------------------------------------------ - // ITmfEventType - // ------------------------------------------------------------------------ - - @Override - public String getContext() { - return fContext; - } - - @Override - public String getName() { - return fTypeId; - } - - @Override - public ITmfEventField getRootField() { - return fRootField; - } - - /** - * @since 3.0 - */ - @Override - public Collection getFieldNames() { - return (fRootField != null) ? fRootField.getFieldNames() : Collections.EMPTY_SET; - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + fContext.hashCode(); - result = prime * result + fTypeId.hashCode(); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof TmfEventType)) { - return false; - } - final TmfEventType other = (TmfEventType) obj; - if (!fContext.equals(other.fContext)) { - return false; - } - if (!fTypeId.equals(other.fTypeId)) { - return false; - } - return true; - } - - @Override - @SuppressWarnings("nls") - public String toString() { - return "TmfEventType [fContext=" + fContext + ", fTypeId=" + fTypeId + "]"; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfEventTypeManager.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfEventTypeManager.java deleted file mode 100644 index 4a6a5bc215..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfEventTypeManager.java +++ /dev/null @@ -1,147 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import com.google.common.collect.ImmutableSet; - -/** - * A central repository for the available event types. Types are managed by - * context space. - * - * @version 1.0 - * @author Francois Chouinard - * - * @see ITmfEventType - */ -public final class TmfEventTypeManager { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // The event type manager singleton - private static TmfEventTypeManager fEventTypeManager = null; - - // The available types, per context - private final Map> fEventTypes; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * The singleton constructor - */ - private TmfEventTypeManager() { - fEventTypes = new HashMap<>(); - } - - /** - * @return the TmfEventTypeManager singleton - */ - public static synchronized TmfEventTypeManager getInstance() { - if (fEventTypeManager == null) { - fEventTypeManager = new TmfEventTypeManager(); - } - return fEventTypeManager; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Add a context:type pair to the available types - * - * @param context the target context - * @param type the type to add - */ - public synchronized void add(final String context, final ITmfEventType type) { - HashMap types = fEventTypes.get(context); - if (types == null) { - types = new HashMap<>(); - } - types.put(type.getName(), type); - fEventTypes.put(context, types); - } - - /** - * Return the list of currently defined contexts - * - * @return the list of contexts - */ - public synchronized String[] getContexts() { - return fEventTypes.keySet().toArray(new String[fEventTypes.size()]); - } - - /** - * Return the list of types defined for a given context - * - * @param context the context to look into - * @return the list of types defined for that context - * @since 3.0 - */ - public synchronized Set getTypes(final String context) { - final HashMap types = fEventTypes.get(context); - if (types != null) { - return ImmutableSet.copyOf(types.values()); - } - return ImmutableSet.of(); - } - - /** - * Return an event type - * - * @param context the context to look into - * @param typeId the type ID - * @return the corresponding type - */ - public synchronized ITmfEventType getType(final String context, final String typeId) { - final HashMap types = fEventTypes.get(context); - if (types != null) { - return types.get(typeId); - } - return null; - } - - /** - * Remove the types associated to a context - * - * @param context the context to remove - */ - public synchronized void clear(final String context) { - fEventTypes.remove(context); - } - - /** - * Remove all contexts and types - */ - public synchronized void clear() { - fEventTypes.clear(); - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - @SuppressWarnings("nls") - public String toString() { - return "TmfEventTypeManager [fEventTypes=" + fEventTypes + "]"; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfLostEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfLostEvent.java deleted file mode 100644 index 04d13ecea0..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/TmfLostEvent.java +++ /dev/null @@ -1,136 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Alexandre Montplaisir - Made immutable - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * A basic implementation of ITmfLostEvent. - * - * @author Francois Chouinard - * @version 1.0 - * @since 1.2 -*/ -public class TmfLostEvent extends TmfEvent implements ITmfLostEvent { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final TmfTimeRange fTimeRange; - private final long fNbLostEvents; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Full constructor - * - * @param trace - * the parent trace - * @param rank - * the event rank (in the trace) - * @param timestamp - * the event timestamp - * @param source - * the event source - * @param type - * the event type - * @param reference - * the event reference - * @param timeRange - * the 'problematic' time range - * @param nbLostEvents - * the number of lost events in the time range - * @since 2.0 - */ - public TmfLostEvent(final ITmfTrace trace, - final long rank, - final ITmfTimestamp timestamp, - final String source, - final ITmfEventType type, - final String reference, - final TmfTimeRange timeRange, - final long nbLostEvents) { - super(trace, rank, timestamp, source, type, null, reference); - fTimeRange = timeRange; - fNbLostEvents = nbLostEvents; - } - - // ------------------------------------------------------------------------ - // ITmfLostEvent - // ------------------------------------------------------------------------ - - /** - * @since 2.0 - */ - @Override - public TmfTimeRange getTimeRange() { - return fTimeRange; - } - - @Override - public long getNbLostEvents() { - return fNbLostEvents; - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + (int) (fNbLostEvents ^ (fNbLostEvents >>> 32)); - result = prime * result + ((fTimeRange == null) ? 0 : fTimeRange.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof TmfLostEvent)) { - return false; - } - TmfLostEvent other = (TmfLostEvent) obj; - if (fNbLostEvents != other.fNbLostEvents) { - return false; - } - if (fTimeRange == null) { - if (other.fTimeRange != null) { - return false; - } - } else if (!fTimeRange.equals(other.fTimeRange)) { - return false; - } - return true; - } - - @Override - @SuppressWarnings("nls") - public String toString() { - return getClass().getSimpleName() + " [Event=" + super.toString() + - ", fTimeRange=" + fTimeRange + ", fNbLostEvents=" + fNbLostEvents + "]"; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/collapse/ITmfCollapsibleEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/collapse/ITmfCollapsibleEvent.java deleted file mode 100644 index 273ba20269..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/collapse/ITmfCollapsibleEvent.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.core.event.collapse; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; - -/** - * Interface for deciding whether an event can be collapsed with another event. - * - * @author Bernd Hufmann - * @since 3.2 - */ -public interface ITmfCollapsibleEvent { - - /** - * Verifies if an event is similar to a given event and can be collapsed - * into one event. For example, an event can be seen as similar if all data - * of the events but the timestamp is equal. - * - * @param otherEvent - * an event to compare - * @return true if a given event is similar to another event - * else false - */ - boolean isCollapsibleWith(ITmfEvent otherEvent); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/lookup/ITmfCallsite.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/lookup/ITmfCallsite.java deleted file mode 100644 index 95ef5ff6a9..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/lookup/ITmfCallsite.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event.lookup; - - -/** - * The generic call site structure in TMF. A call site has: - *

    - *
  • a file name - *
  • a function name (optional) - *
  • a line number - *
- * - * @author Bernd Hufmann - * @since 2.0 - * - * @see TmfCallsite - */ -public interface ITmfCallsite { - /** - * Returns the file name of the call site. - * @return the file name - */ - public String getFileName(); - - /** - * Returns the function name of the call site. - * @return the function name or null - */ - public String getFunctionName(); - - /** - * Returns the line number of the call site. - * @return the line number - */ - public long getLineNumber(); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/lookup/ITmfModelLookup.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/lookup/ITmfModelLookup.java deleted file mode 100644 index b5dbf08583..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/lookup/ITmfModelLookup.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.core.event.lookup; - - -/** - * Interface for events to implement to provide information for model element lookup. - * - * @author Bernd Hufmann - * @since 2.0 - */ -public interface ITmfModelLookup { - /** - * Returns a model URI string. - * - * @return a model URI string. - */ - public String getModelUri(); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/lookup/ITmfSourceLookup.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/lookup/ITmfSourceLookup.java deleted file mode 100644 index c3daac9a46..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/lookup/ITmfSourceLookup.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.core.event.lookup; - - -/** - * Interface for events to implement to provide information for source lookup. - * - * @author Bernd Hufmann - * @since 2.0 - */ -public interface ITmfSourceLookup { - /** - * Returns a call site instance. - * - * @return a call site instance. - */ - public ITmfCallsite getCallsite(); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/lookup/TmfCallsite.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/lookup/TmfCallsite.java deleted file mode 100644 index ca02084663..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/lookup/TmfCallsite.java +++ /dev/null @@ -1,150 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event.lookup; - - -/** - * TMF call site information for source code lookup. - * - * @since 2.0 - * @author Bernd Hufmann - */ -public class TmfCallsite implements ITmfCallsite { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** The file name string. */ - final private String fFileName; - - /** The function name. */ - final private String fFunctionName; - - /** The line number. */ - final private long fLineNumber; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor. - * - * @param fileName - * - a file name - * @param functionName - * - a function name - * @param lineNumber - * - a line number - */ - public TmfCallsite(String fileName, String functionName, long lineNumber) { - if (fileName == null) { - throw new IllegalArgumentException(); - } - fFileName = fileName; - fFunctionName = functionName; - fLineNumber = lineNumber; - } - - /** - * Copy Constructor. - * - * @param other - * - An other call site implementation - */ - public TmfCallsite(ITmfCallsite other) { - if ((other == null) || (other.getFileName() == null)) { - throw new IllegalArgumentException(); - } - fFileName = other.getFileName(); - fFunctionName = other.getFunctionName(); - fLineNumber = other.getLineNumber(); - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - @Override - public String getFileName() { - return fFileName; - } - - @Override - public String getFunctionName() { - return fFunctionName; - } - - @Override - public long getLineNumber() { - return fLineNumber; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + fFileName.hashCode(); // fFileName cannot be null - result = prime * result + ((fFunctionName == null) ? 0 : fFunctionName.hashCode()); - result = prime * result + (int) (fLineNumber ^ (fLineNumber >>> 32)); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TmfCallsite other = (TmfCallsite) obj; - - // fFileName cannot be null! - if (!fFileName.equals(other.fFileName)) { - return false; - } - - if (fFunctionName == null) { - if (other.fFunctionName != null) { - return false; - } - } else if (!fFunctionName.equals(other.fFunctionName)) { - return false; - } - if (fLineNumber != other.fLineNumber) { - return false; - } - return true; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append(fFileName).append(':'); - builder.append(Long.toString(fLineNumber)); - if (fFunctionName != null) { - builder.append(' '); - builder.append(fFunctionName).append("()"); //$NON-NLS-1$ - } - return builder.toString(); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/IMatchProcessingUnit.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/IMatchProcessingUnit.java deleted file mode 100644 index 4fc90cc843..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/IMatchProcessingUnit.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event.matching; - -import java.util.Collection; - -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * This class represent an action to be done when event matches are found. This - * interface needs to be implemented by all classes that want to be warned when - * new event matches are found. They need to register to an instance of - * TmfEventMatches class in order to be informed of matches. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public interface IMatchProcessingUnit { - - /** - * Once the traces are known, hook function to initialize some things - * - * @param fTraces the set of traces that will be synchronized - */ - void init(Collection fTraces); - - /** - * Function called when a match is found - * - * @param match - * The event match - */ - void addMatch(TmfEventDependency match); - - /** - * Function called after all matching has been done, to do any post-match - * treatment - */ - void matchingEnded(); - - /** - * Counts the matches - * - * @return the number of matches - */ - int countMatches(); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfEventMatching.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfEventMatching.java deleted file mode 100644 index 1714ca8510..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfEventMatching.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event.matching; - - -/** - * Interface for matching trace events - * - * @author Geneviève Bastien - * @since 3.0 - */ -public interface ITmfEventMatching { - - /** - * Method that start the process of matching events - * - * @return Whether the match was completed correctly or not - */ - boolean matchEvents(); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfMatchEventDefinition.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfMatchEventDefinition.java deleted file mode 100644 index caba63508e..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfMatchEventDefinition.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event.matching; - -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventMatching.MatchingType; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * This interface describe a concrete method to match events. Typically it - * manages for a given matching type what events/fields are used to match events - * - * @author Geneviève Bastien - * @since 3.0 - */ -public interface ITmfMatchEventDefinition { - - /** - * Returns a list of values for an event that uniquely identifies this event - * - * @param event - * The event for which to compute the key - * @return the unique key for this event - */ - List getUniqueField(ITmfEvent event); - - /** - * Verifies whether a trace has all required events to match using this - * class - * - * @param trace - * The trace - * @return Whether the trace has all required information - */ - boolean canMatchTrace(ITmfTrace trace); - - /** - * Return all matching types this definition covers - * - * @return an array of matching types - */ - MatchingType[] getApplicableMatchingTypes(); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfNetworkMatchDefinition.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfNetworkMatchDefinition.java deleted file mode 100644 index b6cf2b8119..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfNetworkMatchDefinition.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event.matching; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.matching.TmfNetworkEventMatching.Direction; - -/** - * Interface for all network match definitions, ie traces with send and receive - * events - * - * @author Geneviève Bastien - * @since 3.0 - */ -public interface ITmfNetworkMatchDefinition extends ITmfMatchEventDefinition { - - /** - * Returns the direction of this event, whether 'send', 'receive' or null if - * event is neither - * - * @param event - * The event to check - * @return The direction of this event, null if uninteresting event - */ - Direction getDirection(ITmfEvent event); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventDependency.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventDependency.java deleted file mode 100644 index 13502507b5..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventDependency.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event.matching; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; - -/** - * Represents a dependency (match) between two events, where source event leads - * to destination event - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfEventDependency { - - private final ITmfEvent fSourceEvent; - private final ITmfEvent fDestEvent; - - /** - * Constructor - * - * @param source - * The source event of this dependency - * @param destination - * The destination event of this dependency - */ - public TmfEventDependency(final ITmfEvent source, final ITmfEvent destination) { - fSourceEvent = source; - fDestEvent = destination; - } - - /** - * Getter for fSourceEvent - * - * @return The source event - */ - public ITmfEvent getSourceEvent() { - return fSourceEvent; - } - - /** - * Getter for fDestEvent - * - * @return the Destination event - */ - public ITmfEvent getDestinationEvent() { - return fDestEvent; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventMatches.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventMatches.java deleted file mode 100644 index c247d0c8a4..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventMatches.java +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event.matching; - -import java.util.Collection; - -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Class that does something with a match. - * - * This default implementation of the class just counts the matches - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfEventMatches implements IMatchProcessingUnit { - - private int fMatchCount; - - /** - * Constructor - */ - public TmfEventMatches() { - fMatchCount = 0; - } - - /** - * IMatchProcessingUnit overrides - */ - - @Override - public void init(Collection fTraces) { - fMatchCount = 0; - } - - @Override - public void addMatch(TmfEventDependency match) { - fMatchCount++; - } - - @Override - public void matchingEnded() { - - } - - @Override - public int countMatches() { - return fMatchCount; - } - - /** - * Returns the match at the specified index - * - * @param index - * The index of the match to get - * @return The match at index or null or not present - * @deprecated Matches are not kept anymore, they use up memory for no real reason - */ - @Deprecated - public TmfEventDependency getMatch(int index) { - return null; - } - - @Override - public String toString() { - return getClass().getSimpleName() + " [ Number of matches found: " + fMatchCount + " ]"; //$NON-NLS-1$ //$NON-NLS-2$ - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventMatching.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventMatching.java deleted file mode 100644 index 169a0eae41..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventMatching.java +++ /dev/null @@ -1,271 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event.matching; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Abstract class to extend to match certain type of events in a trace - * - * @author Geneviève Bastien - * @since 3.0 - */ -public abstract class TmfEventMatching implements ITmfEventMatching { - - /** - * The matching type - * - * FIXME Not the best place to put this. Have an array of match types as a - * parameter of each trace? - */ - public enum MatchingType { - /** - * NETWORK, match network events - */ - NETWORK - } - - /** - * The array of traces to match - */ - private final Collection fTraces; - - /** - * The class to call once a match is found - */ - private final IMatchProcessingUnit fMatches; - - private static final Map> fMatchDefinitions = new HashMap<>(); - - private final Map fMatchMap = new HashMap<>(); - - /** - * Constructor with multiple traces and a match processing object - * - * @param traces - * The set of traces for which to match events - * @param tmfEventMatches - * The match processing class - */ - public TmfEventMatching(Collection traces, IMatchProcessingUnit tmfEventMatches) { - if (tmfEventMatches == null) { - throw new IllegalArgumentException(); - } - fTraces = traces; - fMatches = tmfEventMatches; - } - - /** - * Returns the traces to process - * - * @return The traces - */ - protected Collection getTraces() { - return fTraces; - } - - /** - * Returns the match processing unit - * - * @return The match processing unit - */ - protected IMatchProcessingUnit getProcessingUnit() { - return fMatches; - } - - /** - * Returns the match event definition corresponding to the trace - * - * @param trace - * The trace - * @return The match event definition object - */ - protected ITmfMatchEventDefinition getEventDefinition(ITmfTrace trace) { - return fMatchMap.get(trace); - } - - /** - * Method that initializes any data structure for the event matching. It - * also assigns to each trace an event matching definition instance that - * applies to the trace - */ - protected void initMatching() { - fMatches.init(fTraces); - List deflist = fMatchDefinitions.get(getMatchingType()); - if (deflist == null) { - return; - } - for (ITmfTrace trace : fTraces) { - for (ITmfMatchEventDefinition def : deflist) { - if (def.canMatchTrace(trace)) { - fMatchMap.put(trace, def); - break; - } - } - } - } - - /** - * Calls any post matching methods of the processing class - */ - protected void finalizeMatching() { - fMatches.matchingEnded(); - } - - /** - * Prints stats from the matching - * - * @return string of statistics - */ - @SuppressWarnings("nls") - @Override - public String toString() { - return getClass().getSimpleName() + " [ " + fMatches + " ]"; - } - - /** - * Matches one event - * - * @param event - * The event to match - * @param trace - * The trace to which this event belongs - */ - protected abstract void matchEvent(ITmfEvent event, ITmfTrace trace); - - /** - * Returns the matching type this class implements - * - * @return A matching type - */ - protected abstract MatchingType getMatchingType(); - - /** - * Method that start the process of matching events - * - * @return Whether the match was completed correctly or not - */ - @Override - public boolean matchEvents() { - - /* Are there traces to match? If no, return false */ - if (!(fTraces.size() > 0)) { - return false; - } - - // TODO Start a new thread here? - initMatching(); - - /** - * For each trace, get the events and for each event, call the - * MatchEvent method - * - * FIXME This would use a lot of memory if the traces are big, because - * all involved events from first trace will have to be kept before a - * first match is possible with second trace. - * - *
-         * Other possible matching strategy:
-         * Incremental:
-         * Sliding window:
-         * Other strategy: start with the shortest trace, take a few events
-         * at the beginning and at the end
-         * Experiment strategy: have the experiment do the request, then events will
-         * come from both traces chronologically, but then instead of ITmfTrace[], it
-         * would be preferable to have experiment
-         * 
- */ - for (ITmfTrace trace : fTraces) { - EventMatchingBuildRequest request = new EventMatchingBuildRequest(this, trace); - - /* - * Send the request to the trace here, since there is probably no - * experiment. - */ - trace.sendRequest(request); - try { - request.waitForCompletion(); - } catch (InterruptedException e) { - Activator.logInfo(e.getMessage()); - } - } - - finalizeMatching(); - - return true; - } - - /** - * Registers an event match definition to be used for a certain match type - * - * @param match - * The event matching definition - */ - public static void registerMatchObject(ITmfMatchEventDefinition match) { - for (MatchingType type : match.getApplicableMatchingTypes()) { - if (!fMatchDefinitions.containsKey(type)) { - fMatchDefinitions.put(type, new ArrayList()); - } - fMatchDefinitions.get(type).add(match); - } - } - -} - -class EventMatchingBuildRequest extends TmfEventRequest { - - private final TmfEventMatching matching; - private final ITmfTrace trace; - - EventMatchingBuildRequest(TmfEventMatching matching, ITmfTrace trace) { - super(ITmfEvent.class, - TmfTimeRange.ETERNITY, - 0, - ITmfEventRequest.ALL_DATA, - ITmfEventRequest.ExecutionType.FOREGROUND); - this.matching = matching; - this.trace = trace; - } - - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - matching.matchEvent(event, trace); - } - - @Override - public void handleSuccess() { - super.handleSuccess(); - } - - @Override - public void handleCancel() { - super.handleCancel(); - } - - @Override - public void handleFailure() { - super.handleFailure(); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfNetworkEventMatching.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfNetworkEventMatching.java deleted file mode 100644 index 384f4634aa..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfNetworkEventMatching.java +++ /dev/null @@ -1,212 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.event.matching; - -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * This class matches events typically network-style, ie. where some events are - * 'send' events and the other 'receive' events or out/in events - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfNetworkEventMatching extends TmfEventMatching { - - /** - * Hashtables for unmatches incoming events - */ - private final Map, ITmfEvent>> fUnmatchedIn = new LinkedHashMap<>(); - - /** - * Hashtables for unmatches outgoing events - */ - private final Map, ITmfEvent>> fUnmatchedOut = new LinkedHashMap<>(); - - /** - * Enum for in and out types - */ - public enum Direction { - /** - * The event is a 'receive' type of event - */ - IN, - /** - * The event is a 'send' type of event - */ - OUT, - } - - /** - * Constructor with multiple traces and match processing object - * - * @param traces - * The set of traces for which to match events - */ - public TmfNetworkEventMatching(Collection traces) { - this(traces, new TmfEventMatches()); - } - - /** - * Constructor with multiple traces and match processing object - * - * @param traces - * The set of traces for which to match events - * @param tmfEventMatches - * The match processing class - */ - public TmfNetworkEventMatching(Collection traces, IMatchProcessingUnit tmfEventMatches) { - super(traces, tmfEventMatches); - } - - /** - * Method that initializes any data structure for the event matching - */ - @Override - public void initMatching() { - // Initialize the matching infrastructure (unmatched event lists) - fUnmatchedIn.clear(); - fUnmatchedOut.clear(); - for (ITmfTrace trace : getTraces()) { - fUnmatchedIn.put(trace, new HashMap, ITmfEvent>()); - fUnmatchedOut.put(trace, new HashMap, ITmfEvent>()); - } - super.initMatching(); - } - - /** - * Function that counts the events in a hashtable. - * - * @param tbl - * The table to count events for - * @return The number of events - */ - protected int countEvents(Map, ITmfEvent> tbl) { - return tbl.size(); - } - - @Override - protected MatchingType getMatchingType() { - return MatchingType.NETWORK; - } - - @Override - public void matchEvent(ITmfEvent event, ITmfTrace trace) { - if (!(getEventDefinition(event.getTrace()) instanceof ITmfNetworkMatchDefinition)) { - return; - } - ITmfNetworkMatchDefinition def = (ITmfNetworkMatchDefinition) getEventDefinition(event.getTrace()); - - Direction evType = def.getDirection(event); - if (evType == null) { - return; - } - - /* Get the event's unique fields */ - List eventKey = def.getUniqueField(event); - Map, ITmfEvent>> unmatchedTbl, companionTbl; - - /* Point to the appropriate table */ - switch (evType) { - case IN: - unmatchedTbl = fUnmatchedIn; - companionTbl = fUnmatchedOut; - break; - case OUT: - unmatchedTbl = fUnmatchedOut; - companionTbl = fUnmatchedIn; - break; - default: - return; - } - - boolean found = false; - TmfEventDependency dep = null; - /* Search for the event in the companion table */ - for (Map, ITmfEvent> map : companionTbl.values()) { - if (map.containsKey(eventKey)) { - found = true; - ITmfEvent companionEvent = map.get(eventKey); - - /* Remove the element from the companion table */ - map.remove(eventKey); - - /* Create the dependency object */ - switch (evType) { - case IN: - dep = new TmfEventDependency(companionEvent, event); - break; - case OUT: - dep = new TmfEventDependency(event, companionEvent); - break; - default: - break; - - } - } - } - - /* - * If no companion was found, add the event to the appropriate unMatched - * lists - */ - if (found) { - getProcessingUnit().addMatch(dep); - } else { - /* - * If an event is already associated with this key, do not add it - * again, we keep the first event chronologically, so if its match - * is eventually found, it is associated with the first send or - * receive event. At best, it is a good guess, at worst, the match - * will be too far off to be accurate. Too bad! - * - * TODO: maybe instead of just one event, we could have a list of - * events as value for the unmatched table. Not necessary right now - * though - */ - if (!unmatchedTbl.get(trace).containsKey(eventKey)) { - unmatchedTbl.get(trace).put(eventKey, event); - } - } - - } - - /** - * Prints stats from the matching - * - * @return string of statistics - */ - @SuppressWarnings("nls") - @Override - public String toString() { - final String cr = System.getProperty("line.separator"); - StringBuilder b = new StringBuilder(); - b.append(getProcessingUnit()); - int i = 0; - for (ITmfTrace trace : getTraces()) { - b.append("Trace " + i++ + ":" + cr + - " " + countEvents(fUnmatchedIn.get(trace)) + " unmatched incoming events" + cr + - " " + countEvents(fUnmatchedOut.get(trace)) + " unmatched outgoing events" + cr); - } - - return b.toString(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/exceptions/TmfAnalysisException.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/exceptions/TmfAnalysisException.java deleted file mode 100644 index 8957d02380..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/exceptions/TmfAnalysisException.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.exceptions; - -/** - * Generic exception for an error or issue occurs in analysis setup and - * execution. - * - * For instance, to perform an analysis, a trace must be of the right type and - * have some characteristics. If trying to do an analysis on a trace that does - * not match, this exception is thrown. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfAnalysisException extends Exception { - - private static final long serialVersionUID = -4567750551324478401L; - - /** - * Default constructor - */ - public TmfAnalysisException() { - super(); - } - - /** - * Constructor with a message - * - * @param message - * Message to attach to this exception - */ - public TmfAnalysisException(String message) { - super(message); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/exceptions/TmfTraceException.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/exceptions/TmfTraceException.java deleted file mode 100644 index 90e5a8fc82..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/exceptions/TmfTraceException.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.exceptions; - -/** - * TMF trace related exception - * - * @version 1.0 - * @author Francois Chouinard - */ -public class TmfTraceException extends Exception { - - /** - * The exception version ID - */ - private static final long serialVersionUID = -6829650938285722133L; - - /** - * Constructor - * - * @param errMsg the error message - */ - public TmfTraceException(String errMsg) { - super(errMsg); - } - - /** - * Constructor - * - * @param errMsg the error message - * @param cause the error cause (null is permitted which means no cause is available) - */ - public TmfTraceException(String errMsg, Throwable cause) { - super(errMsg, cause); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/ITmfFilter.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/ITmfFilter.java deleted file mode 100644 index b73399c783..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/ITmfFilter.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.filter; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; - -/** - * The TMF filter interface. - * - * @version 1.0 - * @author Patrick Tasse - */ -public interface ITmfFilter { - - /** - * Verify the filter conditions on an event - * - * @param event The event to verify. - * @return True if the event matches the filter conditions. - */ - boolean matches(ITmfEvent event); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/ITmfFilterTreeNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/ITmfFilterTreeNode.java deleted file mode 100644 index 174f970a20..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/ITmfFilterTreeNode.java +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Godin (copelnug@gmail.com) - Initial API - * Yuriy Vashchuk (yvashchuk@gmail.com) - Initial implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.filter.model; - -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.filter.ITmfFilter; - - -/** - *

This is Node Interface in the Filter Tree

- */ -public interface ITmfFilterTreeNode extends ITmfFilter { - - /** - *

Get the parent node of current node

- * - * @return The parent node (null when the node has no parent). - */ - public ITmfFilterTreeNode getParent(); - - /** - *

Get the current node name

- * - * @return The name of the current node. - */ - public String getNodeName(); - - /** - *

Tell if the node has children

- * - * @return True if the node has children. - */ - public boolean hasChildren(); - - /** - *

Return the number of children

- * - * @return The number of children. - */ - public int getChildrenCount(); - - /** - *

Get the array of children

- * - * @return The array (possibly empty) of children nodes. - */ - public ITmfFilterTreeNode[] getChildren(); - - /** - *

Get the node by index

- * - * @param index The index of node to return. - * @return The desired node (null if the node is not exists). - */ - public ITmfFilterTreeNode getChild(int index); - - /** - *

Remove the node from its parent

- * - *

Shifts all nodes after the removed one to prevent having an empty spot. - * See {@link #replaceChild(int, ITmfFilterTreeNode)} to replace a node.

- * - * @return The removed node. - */ - public ITmfFilterTreeNode remove(); - - /** - *

Remove the child from the current node

- * - *

Shifts all nodes after the removed one to prevent having an empty spot. - * See {@link #replaceChild(int, ITmfFilterTreeNode)} to replace a node.

- * - * @param node the parent node - * - * @return The removed node. - */ - public ITmfFilterTreeNode removeChild(ITmfFilterTreeNode node); - - /** - *

Append a node to the current children

- * - * @param node Node to append. - * @return Index of added node (-1 if the node cannot be added). - */ - public int addChild(ITmfFilterTreeNode node); - - /** - *

Replace a child node

- * - * @param index Index of the node to replace. - * @param node Node who will replace. - * @return Node replaced. - */ - public ITmfFilterTreeNode replaceChild(int index, ITmfFilterTreeNode node); - - /** - *

Sets the parent of current node

- * - * @param parent The parent of current node. - */ - public void setParent(ITmfFilterTreeNode parent); - - /** - *

Gets the list of valid children node names that could be added to the node

- * - * @return The list of valid children node names. - */ - public List getValidChildren(); - - /** - * @return a clone of the node - */ - public ITmfFilterTreeNode clone(); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterAndNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterAndNode.java deleted file mode 100644 index 6aaef336d4..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterAndNode.java +++ /dev/null @@ -1,116 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.filter.model; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; - - -/** - * Filter node for the 'and' operation - * - * @version 1.0 - * @author Patrick Tasse - */ -@SuppressWarnings("javadoc") -public class TmfFilterAndNode extends TmfFilterTreeNode { - - public static final String NODE_NAME = "AND"; //$NON-NLS-1$ - public static final String NOT_ATTR = "not"; //$NON-NLS-1$ - - private boolean fNot = false; - - /** - * @param parent the parent node - */ - public TmfFilterAndNode(ITmfFilterTreeNode parent) { - super(parent); - } - - /** - * @return the NOT state - */ - public boolean isNot() { - return fNot; - } - - /** - * @param not the NOT state - */ - public void setNot(boolean not) { - this.fNot = not; - } - - @Override - public String getNodeName() { - return NODE_NAME; - } - - @Override - public boolean matches(ITmfEvent event) { - for (ITmfFilterTreeNode node : getChildren()) { - if (! node.matches(event)) { - return false ^ fNot; - } - } - return true ^ fNot; - } - - @Override - public String toString() { - StringBuffer buf = new StringBuffer(); - if (fNot) { - buf.append("not "); //$NON-NLS-1$ - } - if (getParent() != null && !(getParent() instanceof TmfFilterRootNode) && !(getParent() instanceof TmfFilterNode)) { - buf.append("( "); //$NON-NLS-1$ - } - for (int i = 0; i < getChildrenCount(); i++) { - ITmfFilterTreeNode node = getChildren()[i]; - buf.append(node.toString()); - if (i < getChildrenCount() - 1) { - buf.append(" and "); //$NON-NLS-1$ - } - } - if (getParent() != null && !(getParent() instanceof TmfFilterRootNode) && !(getParent() instanceof TmfFilterNode)) { - buf.append(" )"); //$NON-NLS-1$ - } - return buf.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + (fNot ? 1231 : 1237); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TmfFilterAndNode other = (TmfFilterAndNode) obj; - if (fNot != other.fNot) { - return false; - } - return true; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterCompareNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterCompareNode.java deleted file mode 100644 index 0037532e93..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterCompareNode.java +++ /dev/null @@ -1,270 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.filter.model; - -import java.text.NumberFormat; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; - - -/** - * Filter node for the comparison operation - * - * @version 1.0 - * @author Patrick Tasse - */ -@SuppressWarnings("javadoc") -public class TmfFilterCompareNode extends TmfFilterTreeNode { - - public static final String NODE_NAME = "COMPARE"; //$NON-NLS-1$ - public static final String NOT_ATTR = "not"; //$NON-NLS-1$ - public static final String FIELD_ATTR = "field"; //$NON-NLS-1$ - public static final String RESULT_ATTR = "result"; //$NON-NLS-1$ - public static final String TYPE_ATTR = "type"; //$NON-NLS-1$ - public static final String VALUE_ATTR = "value"; //$NON-NLS-1$ - - /** - * Supported comparison types - */ - public static enum Type { - NUM, - ALPHA, - TIMESTAMP - } - - private boolean fNot = false; - private String fField; - private int fResult; - private Type fType = Type.NUM; - private String fValue; - private transient Number fValueNumber; - private transient TmfTimestamp fValueTimestamp; - - /** - * @param parent the parent node - */ - public TmfFilterCompareNode(ITmfFilterTreeNode parent) { - super(parent); - } - - /** - * @return the NOT state - */ - public boolean isNot() { - return fNot; - } - - /** - * @param not the NOT state - */ - public void setNot(boolean not) { - this.fNot = not; - } - - /** - * @return the field name - */ - public String getField() { - return fField; - } - - /** - * @param field the field name - */ - public void setField(String field) { - this.fField = field; - } - - /** - * @return the compare result - */ - public int getResult() { - return fResult; - } - - /** - * @param result the compare result - */ - public void setResult(int result) { - this.fResult = result; - } - - /** - * @return the comparison type - */ - public Type getType() { - return fType; - } - - /** - * @param type the comparison type - */ - public void setType(Type type) { - this.fType = type; - setValue(fValue); - } - - /** - * @return the comparison value - */ - public String getValue() { - return fValue; - } - - /** - * @param value the comparison value - */ - public void setValue(String value) { - this.fValue = value; - fValueNumber = null; - fValueTimestamp = null; - if (value == null) { - return; - } - if (fType == Type.NUM) { - try { - fValueNumber = NumberFormat.getInstance().parse(value).doubleValue(); - } catch (ParseException e) { - } - } else if (fType == Type.TIMESTAMP) { - try { - fValueTimestamp = new TmfTimestamp((long) (1E9 * NumberFormat.getInstance().parse(value.toString()).doubleValue())); - } catch (ParseException e) { - } - } - } - - @Override - public String getNodeName() { - return NODE_NAME; - } - - @Override - public boolean matches(ITmfEvent event) { - Object value = getFieldValue(event, fField); - if (value == null) { - return false ^ fNot; - } - if (fType == Type.NUM) { - if (fValueNumber != null) { - if (value instanceof Number) { - double valueDouble = ((Number) value).doubleValue(); - return (Double.compare(valueDouble, fValueNumber.doubleValue()) == fResult) ^ fNot; - } - try { - double valueDouble = NumberFormat.getInstance().parse(value.toString()).doubleValue(); - return (Double.compare(valueDouble, fValueNumber.doubleValue()) == fResult) ^ fNot; - } catch (ParseException e) { - } - } - } else if (fType == Type.ALPHA) { - String valueString = value.toString(); - int comp = valueString.compareTo(fValue.toString()); - if (comp < -1) { - comp = -1; - } else if (comp > 1) { - comp = 1; - } - return (comp == fResult) ^ fNot; - } else if (fType == Type.TIMESTAMP) { - if (fValueTimestamp != null) { - if (value instanceof TmfTimestamp) { - TmfTimestamp valueTimestamp = (TmfTimestamp) value; - return (valueTimestamp.compareTo(fValueTimestamp, false) == fResult) ^ fNot; - } - try { - TmfTimestamp valueTimestamp = new TmfTimestamp((long) (1E9 * NumberFormat - .getInstance().parse(value.toString()).doubleValue())); - return (valueTimestamp.compareTo(fValueTimestamp, false) == fResult) ^ fNot; - } catch (ParseException e) { - } - } - } - return false ^ fNot; - } - - @Override - public List getValidChildren() { - return new ArrayList<>(0); - } - - @Override - public String toString() { - String result = (fResult == 0 ? "= " : fResult < 0 ? "< " : "> "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - String open = (fType == Type.NUM ? "" : fType == Type.ALPHA ? "\"" : "["); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - String close = (fType == Type.NUM ? "" : fType == Type.ALPHA ? "\"" : "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - return fField + (fNot ? " not " : " ") + result + open + fValue + close; //$NON-NLS-1$ //$NON-NLS-2$ - } - - @Override - public ITmfFilterTreeNode clone() { - TmfFilterCompareNode clone = (TmfFilterCompareNode) super.clone(); - clone.fField = fField; - clone.setValue(fValue); - return clone; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((fField == null) ? 0 : fField.hashCode()); - result = prime * result + (fNot ? 1231 : 1237); - result = prime * result + fResult; - result = prime * result + ((fType == null) ? 0 : fType.hashCode()); - result = prime * result + ((fValue == null) ? 0 : fValue.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TmfFilterCompareNode other = (TmfFilterCompareNode) obj; - if (fField == null) { - if (other.fField != null) { - return false; - } - } else if (!fField.equals(other.fField)) { - return false; - } - if (fNot != other.fNot) { - return false; - } - if (fResult != other.fResult) { - return false; - } - if (fType != other.fType) { - return false; - } - if (fValue == null) { - if (other.fValue != null) { - return false; - } - } else if (!fValue.equals(other.fValue)) { - return false; - } - return true; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterContainsNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterContainsNode.java deleted file mode 100644 index 798787d623..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterContainsNode.java +++ /dev/null @@ -1,188 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.filter.model; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; - -/** - * Filter node for the 'contains' operation - * - * @version 1.0 - * @author Patrick Tasse - */ -@SuppressWarnings("javadoc") -public class TmfFilterContainsNode extends TmfFilterTreeNode { - - public static final String NODE_NAME = "CONTAINS"; //$NON-NLS-1$ - public static final String NOT_ATTR = "not"; //$NON-NLS-1$ - public static final String FIELD_ATTR = "field"; //$NON-NLS-1$ - public static final String VALUE_ATTR = "value"; //$NON-NLS-1$ - public static final String IGNORECASE_ATTR = "ignorecase"; //$NON-NLS-1$ - - private boolean fNot = false; - private String fField; - private String fValue; - private transient String fValueUpperCase; - private boolean fIgnoreCase = false; - - /** - * @param parent the parent node - */ - public TmfFilterContainsNode(ITmfFilterTreeNode parent) { - super(parent); - } - - /** - * @return the NOT state - */ - public boolean isNot() { - return fNot; - } - - /** - * @param not the NOT state - */ - public void setNot(boolean not) { - this.fNot = not; - } - - /** - * @return the field name - */ - public String getField() { - return fField; - } - - /** - * @param field the field name - */ - public void setField(String field) { - this.fField = field; - } - - /** - * @return the contains value - */ - public String getValue() { - return fValue; - } - - /** - * @param value the contains value - */ - public void setValue(String value) { - this.fValue = value; - if (value != null) { - fValueUpperCase = value.toUpperCase(); - } - } - - /** - * @return the ignoreCase state - */ - public boolean isIgnoreCase() { - return fIgnoreCase; - } - - /** - * @param ignoreCase the ignoreCase state - */ - public void setIgnoreCase(boolean ignoreCase) { - this.fIgnoreCase = ignoreCase; - } - - @Override - public String getNodeName() { - return NODE_NAME; - } - - @Override - public boolean matches(ITmfEvent event) { - Object value = getFieldValue(event, fField); - if (value == null) { - return false ^ fNot; - } - String valueString = value.toString(); - if (fIgnoreCase) { - return valueString.toUpperCase().contains(fValueUpperCase) ^ fNot; - } - return valueString.contains(fValue) ^ fNot; - } - - @Override - public List getValidChildren() { - return new ArrayList<>(0); - } - - @Override - public String toString() { - return fField + (fNot ? " not" : "") + " contains \"" + fValue + "\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - - @Override - public ITmfFilterTreeNode clone() { - TmfFilterContainsNode clone = (TmfFilterContainsNode) super.clone(); - clone.fField = fField; - clone.setValue(fValue); - return clone; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((fField == null) ? 0 : fField.hashCode()); - result = prime * result + (fIgnoreCase ? 1231 : 1237); - result = prime * result + (fNot ? 1231 : 1237); - result = prime * result + ((fValue == null) ? 0 : fValue.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TmfFilterContainsNode other = (TmfFilterContainsNode) obj; - if (fField == null) { - if (other.fField != null) { - return false; - } - } else if (!fField.equals(other.fField)) { - return false; - } - if (fIgnoreCase != other.fIgnoreCase) { - return false; - } - if (fNot != other.fNot) { - return false; - } - if (fValue == null) { - if (other.fValue != null) { - return false; - } - } else if (!fValue.equals(other.fValue)) { - return false; - } - return true; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterEqualsNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterEqualsNode.java deleted file mode 100644 index a85a43a598..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterEqualsNode.java +++ /dev/null @@ -1,188 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.filter.model; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; - - -/** - * Filter node for the '==' operation - * - * @version 1.0 - * @author Patrick Tasse - */ -@SuppressWarnings("javadoc") -public class TmfFilterEqualsNode extends TmfFilterTreeNode { - - public static final String NODE_NAME = "EQUALS"; //$NON-NLS-1$ - public static final String NOT_ATTR = "not"; //$NON-NLS-1$ - public static final String FIELD_ATTR = "field"; //$NON-NLS-1$ - public static final String VALUE_ATTR = "value"; //$NON-NLS-1$ - public static final String IGNORECASE_ATTR = "ignorecase"; //$NON-NLS-1$ - - private boolean fNot = false; - private String fField; - private String fValue; - private boolean fIgnoreCase = false; - - /** - * @param parent the aprent node - */ - public TmfFilterEqualsNode(ITmfFilterTreeNode parent) { - super(parent); - } - - /** - * @return the NOT state - */ - public boolean isNot() { - return fNot; - } - - /** - * @param not the NOT state - */ - public void setNot(boolean not) { - this.fNot = not; - } - - /** - * @return the field name - */ - public String getField() { - return fField; - } - - /** - * @param field the field name - */ - public void setField(String field) { - this.fField = field; - } - - /** - * @return the equals value - */ - public String getValue() { - return fValue; - } - - /** - * @param value the equals value - */ - public void setValue(String value) { - this.fValue = value; - } - - /** - * @return the ignoreCase state - */ - public boolean isIgnoreCase() { - return fIgnoreCase; - } - - /** - * @param ignoreCase the ignoreCase state - */ - public void setIgnoreCase(boolean ignoreCase) { - this.fIgnoreCase = ignoreCase; - } - - @Override - public String getNodeName() { - return NODE_NAME; - } - - @Override - public boolean matches(ITmfEvent event) { - Object value = getFieldValue(event, fField); - if (value == null) { - return false ^ fNot; - } - String valueString = value.toString(); - if (valueString == null) { - return false ^ fNot; - } - if (fIgnoreCase) { - return valueString.equalsIgnoreCase(fValue) ^ fNot; - } - return valueString.equals(fValue) ^ fNot; - } - - @Override - public List getValidChildren() { - return new ArrayList<>(0); - } - - @Override - public String toString() { - return fField + (fNot ? " not" : "") + " equals \"" + fValue + "\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - - @Override - public ITmfFilterTreeNode clone() { - TmfFilterEqualsNode clone = (TmfFilterEqualsNode) super.clone(); - clone.fField = fField; - clone.fValue = fValue; - return clone; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((fField == null) ? 0 : fField.hashCode()); - result = prime * result + (fIgnoreCase ? 1231 : 1237); - result = prime * result + (fNot ? 1231 : 1237); - result = prime * result + ((fValue == null) ? 0 : fValue.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TmfFilterEqualsNode other = (TmfFilterEqualsNode) obj; - if (fField == null) { - if (other.fField != null) { - return false; - } - } else if (!fField.equals(other.fField)) { - return false; - } - if (fIgnoreCase != other.fIgnoreCase) { - return false; - } - if (fNot != other.fNot) { - return false; - } - if (fValue == null) { - if (other.fValue != null) { - return false; - } - } else if (!fValue.equals(other.fValue)) { - return false; - } - return true; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterEventTypeNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterEventTypeNode.java deleted file mode 100644 index 55bead9a1b..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterEventTypeNode.java +++ /dev/null @@ -1,171 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.filter.model; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; - -/** - * Filter node for an event - * - * @version 1.0 - * @author Patrick Tasse - */ -@SuppressWarnings("javadoc") -public class TmfFilterEventTypeNode extends TmfFilterTreeNode { - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((fName == null) ? 0 : fName.hashCode()); - result = prime * result + ((fType == null) ? 0 : fType.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TmfFilterEventTypeNode other = (TmfFilterEventTypeNode) obj; - if (fName == null) { - if (other.fName != null) { - return false; - } - } else if (!fName.equals(other.fName)) { - return false; - } - if (fType == null) { - if (other.fType != null) { - return false; - } - } else if (!fType.equals(other.fType)) { - return false; - } - return true; - } - - public static final String NODE_NAME = "EVENTTYPE"; //$NON-NLS-1$ - public static final String TYPE_ATTR = "type"; //$NON-NLS-1$ - public static final String NAME_ATTR = "name"; //$NON-NLS-1$ - - private String fType; - private String fName; - - /** - * @param parent the parent node - */ - public TmfFilterEventTypeNode(ITmfFilterTreeNode parent) { - super(parent); - } - - @Override - public String getNodeName() { - return NODE_NAME; - } - - /** - * @return the event type - */ - public String getEventType() { - return fType; - } - - /** - * @param type the event type - */ - public void setEventType(String type) { - this.fType = type; - } - - /** - * @return the category and trace type name - */ - public String getName() { - return fName; - } - - /** - * @param name the category and trace type name - */ - public void setName(String name) { - this.fName = name; - } - - @Override - public boolean matches(ITmfEvent event) { - boolean match = false; - if (fType.contains(":")) { //$NON-NLS-1$ - // special case for custom parsers - if (fType.startsWith(event.getClass().getCanonicalName())) { - if (fType.endsWith(event.getType().getName())) { - match = true; - } - } - } else { - if (event.getClass().getCanonicalName().equals(fType)) { - match = true; - } - } - if (match) { - // There should be at most one child - for (ITmfFilterTreeNode node : getChildren()) { - if (! node.matches(event)) { - return false; - } - } - return true; - } - return false; - } - - @Override - public List getValidChildren() { - if (getChildrenCount() == 0) { - return super.getValidChildren(); - } - return new ArrayList<>(0); // only one child allowed - } - - @Override - public String toString() { - StringBuffer buf = new StringBuffer(); - buf.append("EventType is " + fName); //$NON-NLS-1$ - if (getChildrenCount() > 0) { - buf.append(" and "); //$NON-NLS-1$ - } - if (getChildrenCount() > 1) { - buf.append("( "); //$NON-NLS-1$ - } - for (int i = 0; i < getChildrenCount(); i++) { - ITmfFilterTreeNode node = getChildren()[i]; - buf.append(node.toString()); - if (i < getChildrenCount() - 1) { - buf.append(" and "); //$NON-NLS-1$ - } - } - if (getChildrenCount() > 1) { - buf.append(" )"); //$NON-NLS-1$ - } - return buf.toString(); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterMatchesNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterMatchesNode.java deleted file mode 100644 index d32115762d..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterMatchesNode.java +++ /dev/null @@ -1,196 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.filter.model; - -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; - -/** - * Filter node for the regex match - * - * @version 1.0 - * @author Patrick Tasse - */ -@SuppressWarnings("javadoc") -public class TmfFilterMatchesNode extends TmfFilterTreeNode { - - public static final String NODE_NAME = "MATCHES"; //$NON-NLS-1$ - public static final String NOT_ATTR = "not"; //$NON-NLS-1$ - public static final String FIELD_ATTR = "field"; //$NON-NLS-1$ - public static final String REGEX_ATTR = "regex"; //$NON-NLS-1$ - - private boolean fNot = false; - private String fField; - private String fRegex; - private transient Pattern fPattern; - - /** - * @param parent - * the parent node - */ - public TmfFilterMatchesNode(ITmfFilterTreeNode parent) { - super(parent); - } - - /** - * @return the NOT state - */ - public boolean isNot() { - return fNot; - } - - /** - * @param not - * the NOT state - */ - public void setNot(boolean not) { - this.fNot = not; - } - - /** - * @return the field name - */ - public String getField() { - return fField; - } - - /** - * @param field - * the field name - */ - public void setField(String field) { - this.fField = field; - } - - /** - * @return the regular expression - */ - public String getRegex() { - return fRegex; - } - - /** - * @param regex - * the regular expression - */ - public void setRegex(String regex) { - this.fRegex = regex; - if (regex != null) { - try { - this.fPattern = Pattern.compile(regex, Pattern.DOTALL); - } catch (PatternSyntaxException e) { - this.fPattern = null; - } - } - } - - @Override - public String getNodeName() { - return NODE_NAME; - } - - @Override - public boolean matches(ITmfEvent event) { - if (fPattern == null) { - return false ^ fNot; - } - - Object value = getFieldValue(event, fField); - if (value == null) { - return false ^ fNot; - } - String valueString = value.toString(); - - return fPattern.matcher(valueString).matches() ^ fNot; - } - - @Override - public List getValidChildren() { - return new ArrayList<>(0); - } - - @Override - public String toString() { - return fField + (fNot ? " not" : "") + " matches \"" + fRegex + "\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - - @Override - public ITmfFilterTreeNode clone() { - TmfFilterMatchesNode clone = (TmfFilterMatchesNode) super.clone(); - clone.fField = fField; - clone.setRegex(fRegex); - return clone; - } - - /** - * @param pattern - * the rough regex pattern - * @return the compliant regex - */ - public static String regexFix(String pattern) { - String ret = pattern; - // if the pattern does not contain one of the expressions .* !^ - // (at the beginning) $ (at the end), then a .* is added at the - // beginning and at the end of the pattern - if (!(ret.indexOf(".*") >= 0 || ret.charAt(0) == '^' || ret.charAt(ret.length() - 1) == '$')) { //$NON-NLS-1$ - ret = ".*" + ret + ".*"; //$NON-NLS-1$ //$NON-NLS-2$ - } - return ret; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((fField == null) ? 0 : fField.hashCode()); - result = prime * result + (fNot ? 1231 : 1237); - result = prime * result + ((fRegex == null) ? 0 : fRegex.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TmfFilterMatchesNode other = (TmfFilterMatchesNode) obj; - if (fField == null) { - if (other.fField != null) { - return false; - } - } else if (!fField.equals(other.fField)) { - return false; - } - if (fNot != other.fNot) { - return false; - } - if (fRegex == null) { - if (other.fRegex != null) { - return false; - } - } else if (!fRegex.equals(other.fRegex)) { - return false; - } - return true; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterNode.java deleted file mode 100644 index 59ae9c2728..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterNode.java +++ /dev/null @@ -1,137 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.filter.model; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; - -/** - * Filter node for the event match operation - * - * @version 1.0 - * @author Patrick Tasse - */ -@SuppressWarnings("javadoc") -public class TmfFilterNode extends TmfFilterTreeNode { - - public static final String NODE_NAME = "FILTER"; //$NON-NLS-1$ - public static final String NAME_ATTR = "name"; //$NON-NLS-1$ - - String fFilterName; - - /** - * @param filterName the filter name - */ - public TmfFilterNode(String filterName) { - super(null); - fFilterName = filterName; - } - - /** - * @param parent the parent node - * @param filterName the filter name - */ - public TmfFilterNode(ITmfFilterTreeNode parent, String filterName) { - super(parent); - fFilterName = filterName; - } - - /** - * @return the filer name - */ - public String getFilterName() { - return fFilterName; - } - - /** - * @param filterName the filer name - */ - public void setFilterName(String filterName) { - fFilterName = filterName; - } - - @Override - public String getNodeName() { - return NODE_NAME; - } - - @Override - public boolean matches(ITmfEvent event) { - // There should be at most one child - for (ITmfFilterTreeNode node : getChildren()) { - if (node.matches(event)) { - return true; - } - } - return false; - } - - @Override - public List getValidChildren() { - if (getChildrenCount() == 0) { - return super.getValidChildren(); - } - return new ArrayList<>(0); // only one child allowed - } - - @Override - public String toString() { - StringBuffer buf = new StringBuffer(); - if (getChildrenCount() > 1) { - buf.append("( "); //$NON-NLS-1$ - } - for (int i = 0; i < getChildrenCount(); i++) { - ITmfFilterTreeNode node = getChildren()[i]; - buf.append(node.toString()); - if (i < (getChildrenCount() - 1)) { - buf.append(" and "); //$NON-NLS-1$ - } - } - if (getChildrenCount() > 1) { - buf.append(" )"); //$NON-NLS-1$ - } - return buf.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((fFilterName == null) ? 0 : fFilterName.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TmfFilterNode other = (TmfFilterNode) obj; - if (fFilterName == null) { - if (other.fFilterName != null) { - return false; - } - } else if (!fFilterName.equals(other.fFilterName)) { - return false; - } - return true; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterOrNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterOrNode.java deleted file mode 100644 index a8579e6e8d..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterOrNode.java +++ /dev/null @@ -1,114 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.filter.model; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; - -/** - * Filter node for the 'or' operation - * - * @version 1.0 - * @author Patrick Tasse - */ -@SuppressWarnings("javadoc") -public class TmfFilterOrNode extends TmfFilterTreeNode { - - public static final String NODE_NAME = "OR"; //$NON-NLS-1$ - public static final String NOT_ATTR = "not"; //$NON-NLS-1$ - - private boolean fNot = false; - - /** - * @param parent the parent node - */ - public TmfFilterOrNode(ITmfFilterTreeNode parent) { - super(parent); - } - - @Override - public String getNodeName() { - return NODE_NAME; - } - - /** - * @return the NOT state - */ - public boolean isNot() { - return fNot; - } - - /** - * @param not the NOT state - */ - public void setNot(boolean not) { - this.fNot = not; - } - - @Override - public boolean matches(ITmfEvent event) { - for (ITmfFilterTreeNode node : getChildren()) { - if (node.matches(event)) { - return true ^ fNot; - } - } - return false & fNot; - } - - @Override - public String toString() { - StringBuffer buf = new StringBuffer(); - if (fNot) { - buf.append("not "); //$NON-NLS-1$ - } - if (getParent() != null && !(getParent() instanceof TmfFilterRootNode) && !(getParent() instanceof TmfFilterNode)) { - buf.append("( "); //$NON-NLS-1$ - } - for (int i = 0; i < getChildrenCount(); i++) { - ITmfFilterTreeNode node = getChildren()[i]; - buf.append(node.toString()); - if (i < getChildrenCount() - 1) { - buf.append(" or "); //$NON-NLS-1$ - } - } - if (getParent() != null && !(getParent() instanceof TmfFilterRootNode) && !(getParent() instanceof TmfFilterNode)) { - buf.append(" )"); //$NON-NLS-1$ - } - return buf.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + (fNot ? 1231 : 1237); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TmfFilterOrNode other = (TmfFilterOrNode) obj; - if (fNot != other.fNot) { - return false; - } - return true; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterRootNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterRootNode.java deleted file mode 100644 index 9c754604d8..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterRootNode.java +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.filter.model; - -import java.util.Arrays; -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; - -/** - * The Filter tree root node - * - * @version 1.0 - * @author Patrick Tasse - */ -public class TmfFilterRootNode extends TmfFilterTreeNode { - - @SuppressWarnings("javadoc") - public static final String NODE_NAME = "ROOT"; //$NON-NLS-1$ - - private static final String[] VALID_CHILDREN = { - TmfFilterNode.NODE_NAME - }; - - /** - * Default constructor - */ - public TmfFilterRootNode() { - super(null); - } - - @Override - public String getNodeName() { - return NODE_NAME; - } - - @Override - public boolean matches(ITmfEvent event) { - for (ITmfFilterTreeNode node : getChildren()) { - if (! node.matches(event)) { - return false; - } - } - return true; - } - - @Override - public List getValidChildren() { - return Arrays.asList(VALID_CHILDREN); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterTreeNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterTreeNode.java deleted file mode 100644 index 6bf7f5f1df..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterTreeNode.java +++ /dev/null @@ -1,264 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Yuriy Vashchuk (yvashchuk@gmail.com) - Initial API and implementation - * Patrick Tasse - Refactoring - * Vincent Perot - Add subfield filtering - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.filter.model; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; - -/** - * The base class for the Filter tree nodes - * - * @version 1.0 - * @author Yuriy Vashchuk - * @author Patrick Tasse - */ -public abstract class TmfFilterTreeNode implements ITmfFilterTreeNode, Cloneable { - - private static final char SLASH = '/'; - private static final char BACKSLASH = '\\'; - - private static final String[] VALID_CHILDREN = { - TmfFilterEventTypeNode.NODE_NAME, - TmfFilterAndNode.NODE_NAME, - TmfFilterOrNode.NODE_NAME, - TmfFilterContainsNode.NODE_NAME, - TmfFilterEqualsNode.NODE_NAME, - TmfFilterMatchesNode.NODE_NAME, - TmfFilterCompareNode.NODE_NAME - }; - - private ITmfFilterTreeNode parent = null; - private ArrayList children = new ArrayList<>(); - - private String fPathAsString = null; - private String[] fPathAsArray = null; - - /** - * @param parent - * the parent node - */ - public TmfFilterTreeNode(final ITmfFilterTreeNode parent) { - if (parent != null) { - parent.addChild(this); - } - } - - @Override - public ITmfFilterTreeNode getParent() { - return parent; - } - - @Override - public abstract String getNodeName(); - - @Override - public boolean hasChildren() { - return (children.size() > 0); - } - - @Override - public int getChildrenCount() { - return children.size(); - } - - @Override - public ITmfFilterTreeNode[] getChildren() { - return children.toArray(new ITmfFilterTreeNode[0]); - } - - @Override - public ITmfFilterTreeNode getChild(final int index) throws IndexOutOfBoundsException { - return children.get(index); - } - - @Override - public ITmfFilterTreeNode remove() { - if (getParent() != null) { - getParent().removeChild(this); - } - return this; - } - - @Override - public ITmfFilterTreeNode removeChild(ITmfFilterTreeNode node) { - children.remove(node); - node.setParent(null); - return node; - } - - @Override - public int addChild(final ITmfFilterTreeNode node) { - node.setParent(this); - if (children.add(node)) { - return (children.size() - 1); - } - return -1; - } - - @Override - public ITmfFilterTreeNode replaceChild(final int index, final ITmfFilterTreeNode node) throws IndexOutOfBoundsException { - node.setParent(this); - return children.set(index, node); - } - - @Override - public void setParent(final ITmfFilterTreeNode parent) { - this.parent = parent; - } - - @Override - public abstract boolean matches(ITmfEvent event); - - /** - * @param event - * the event - * @param field - * the field id - * @return the field value - */ - protected Object getFieldValue(ITmfEvent event, String field) { - Object value = null; - if (ITmfEvent.EVENT_FIELD_CONTENT.equals(field)) { - value = event.getContent().toString(); - } - else if (ITmfEvent.EVENT_FIELD_TYPE.equals(field)) { - value = event.getType().getName(); - } - else if (ITmfEvent.EVENT_FIELD_TIMESTAMP.equals(field)) { - value = event.getTimestamp().toString(); - } - else if (ITmfEvent.EVENT_FIELD_SOURCE.equals(field)) { - value = event.getSource(); - } - else if (ITmfEvent.EVENT_FIELD_REFERENCE.equals(field)) { - value = event.getReference(); - } - else { - if (field == null) { - return null; - } - ITmfEventField eventField; - if (field.isEmpty() || field.charAt(0) != SLASH) { - eventField = event.getContent().getField(field); - } else { - String[] array = getPathArray(field); - eventField = event.getContent().getSubField(array); - } - - if (eventField != null) { - value = eventField.getValue(); - } - } - return value; - } - - private String[] getPathArray(String field) { - - // Check if last request was not the same string. - if (field.equals(fPathAsString)) { - return fPathAsArray; - } - - // Generate the new path array - StringBuilder sb = new StringBuilder(); - List list = new ArrayList<>(); - - // We start at 1 since the first character is a slash that we want to - // ignore. - for (int i = 1; i < field.length(); i++) { - char charAt = field.charAt(i); - if (charAt == SLASH) { - // char is slash. Cut here. - list.add(sb.toString()); - sb = new StringBuilder(); - } else if (charAt == BACKSLASH && i < field.length() - 1 && field.charAt(i + 1) == SLASH) { - // Uninterpreted slash. Add it. - sb.append(SLASH); - i++; - } else { - // Any other character. Add. - sb.append(charAt); - } - } - - // Last block. Add it to list. - list.add(sb.toString()); - - // Transform to array - String[] array = new String[list.size()]; - list.toArray(array); - - // Save new values. - // Array first for solving concurrency issues - fPathAsArray = array; - fPathAsString = field; - - return array; - } - - @Override - public List getValidChildren() { - return Arrays.asList(VALID_CHILDREN); - } - - @Override - public ITmfFilterTreeNode clone() { - try { - TmfFilterTreeNode clone = (TmfFilterTreeNode) super.clone(); - clone.parent = null; - clone.children = new ArrayList<>(children.size()); - for (ITmfFilterTreeNode child : getChildren()) { - clone.addChild(child.clone()); - } - return clone; - } catch (CloneNotSupportedException e) { - return null; - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((children == null) ? 0 : children.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TmfFilterTreeNode other = (TmfFilterTreeNode) obj; - if (children == null) { - if (other.children != null) { - return false; - } - } else if (!children.equals(other.children)) { - return false; - } - return true; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/xml/TmfFilterContentHandler.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/xml/TmfFilterContentHandler.java deleted file mode 100644 index 87f9576fb3..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/xml/TmfFilterContentHandler.java +++ /dev/null @@ -1,179 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Yuriy Vashchuk (yvashchuk@gmail.com) - Initial API and implementation - * based on http://smeric.developpez.com/java/cours/xml/sax/ - * Patrick Tasse - Refactoring - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.filter.xml; - -import java.util.Stack; - -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterAndNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterCompareNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterContainsNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterEqualsNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterEventTypeNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterMatchesNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterOrNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterRootNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterTreeNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterCompareNode.Type; -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -/** - * The SAX Content Handler - * - * @version 1.0 - * @author Yuriy Vashchuk - * @author Patrick Tasse - */ -public class TmfFilterContentHandler extends DefaultHandler { - - private ITmfFilterTreeNode fRoot = null; - private Stack fFilterTreeStack = null; - - /** - * The default constructor - */ - public TmfFilterContentHandler() { - super(); - fFilterTreeStack = new Stack<>(); - } - - /** - * Getter of tree - * - * @return The builded tree - */ - public ITmfFilterTreeNode getTree() { - return fRoot; - } - - - @Override - public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { - ITmfFilterTreeNode node = null; - - if (localName.equalsIgnoreCase(TmfFilterRootNode.NODE_NAME)) { - - node = new TmfFilterRootNode(); - - } else if (localName.equals(TmfFilterNode.NODE_NAME)) { - - node = new TmfFilterNode(atts.getValue(TmfFilterNode.NAME_ATTR)); - - } else if (localName.equals(TmfFilterEventTypeNode.NODE_NAME)) { - - node = new TmfFilterEventTypeNode(null); - ((TmfFilterEventTypeNode) node).setEventType(atts.getValue(TmfFilterEventTypeNode.TYPE_ATTR)); - ((TmfFilterEventTypeNode) node).setName(atts.getValue(TmfFilterEventTypeNode.NAME_ATTR)); - - } else if (localName.equals(TmfFilterAndNode.NODE_NAME)) { - - node = new TmfFilterAndNode(null); - String value = atts.getValue(TmfFilterAndNode.NOT_ATTR); - if (value != null && value.equalsIgnoreCase(Boolean.TRUE.toString())) { - ((TmfFilterAndNode) node).setNot(true); - } - - } else if (localName.equals(TmfFilterOrNode.NODE_NAME)) { - - node = new TmfFilterOrNode(null); - String value = atts.getValue(TmfFilterOrNode.NOT_ATTR); - if (value != null && value.equalsIgnoreCase(Boolean.TRUE.toString())) { - ((TmfFilterOrNode) node).setNot(true); - } - - } else if (localName.equals(TmfFilterContainsNode.NODE_NAME)) { - - node = new TmfFilterContainsNode(null); - String value = atts.getValue(TmfFilterContainsNode.NOT_ATTR); - if (value != null && value.equalsIgnoreCase(Boolean.TRUE.toString())) { - ((TmfFilterContainsNode) node).setNot(true); - } - ((TmfFilterContainsNode) node).setField(atts.getValue(TmfFilterContainsNode.FIELD_ATTR)); - ((TmfFilterContainsNode) node).setValue(atts.getValue(TmfFilterContainsNode.VALUE_ATTR)); - value = atts.getValue(TmfFilterContainsNode.IGNORECASE_ATTR); - if (value != null && value.equalsIgnoreCase(Boolean.TRUE.toString())) { - ((TmfFilterContainsNode) node).setIgnoreCase(true); - } - - } else if (localName.equals(TmfFilterEqualsNode.NODE_NAME)) { - - node = new TmfFilterEqualsNode(null); - String value = atts.getValue(TmfFilterEqualsNode.NOT_ATTR); - if (value != null && value.equalsIgnoreCase(Boolean.TRUE.toString())) { - ((TmfFilterEqualsNode) node).setNot(true); - } - ((TmfFilterEqualsNode) node).setField(atts.getValue(TmfFilterEqualsNode.FIELD_ATTR)); - ((TmfFilterEqualsNode) node).setValue(atts.getValue(TmfFilterEqualsNode.VALUE_ATTR)); - value = atts.getValue(TmfFilterEqualsNode.IGNORECASE_ATTR); - if (value != null && value.equalsIgnoreCase(Boolean.TRUE.toString())) { - ((TmfFilterEqualsNode) node).setIgnoreCase(true); - } - - } else if (localName.equals(TmfFilterMatchesNode.NODE_NAME)) { - - node = new TmfFilterMatchesNode(null); - String value = atts.getValue(TmfFilterMatchesNode.NOT_ATTR); - if (value != null && value.equalsIgnoreCase(Boolean.TRUE.toString())) { - ((TmfFilterMatchesNode) node).setNot(true); - } - ((TmfFilterMatchesNode) node).setField(atts.getValue(TmfFilterMatchesNode.FIELD_ATTR)); - ((TmfFilterMatchesNode) node).setRegex(atts.getValue(TmfFilterMatchesNode.REGEX_ATTR)); - - } else if (localName.equals(TmfFilterCompareNode.NODE_NAME)) { - - node = new TmfFilterCompareNode(null); - String value = atts.getValue(TmfFilterCompareNode.NOT_ATTR); - if (value != null && value.equalsIgnoreCase(Boolean.TRUE.toString())) { - ((TmfFilterCompareNode) node).setNot(true); - } - ((TmfFilterCompareNode) node).setField(atts.getValue(TmfFilterCompareNode.FIELD_ATTR)); - value = atts.getValue(TmfFilterCompareNode.TYPE_ATTR); - if (value != null) { - ((TmfFilterCompareNode) node).setType(Type.valueOf(value)); - } - value = atts.getValue(TmfFilterCompareNode.RESULT_ATTR); - if (value != null) { - if (value.equals(Integer.toString(-1))) { - ((TmfFilterCompareNode) node).setResult(-1); - } else if (value.equals(Integer.toString(1))) { - ((TmfFilterCompareNode) node).setResult(1); - } else { - ((TmfFilterCompareNode) node).setResult(0); - } - } - ((TmfFilterCompareNode) node).setValue(atts.getValue(TmfFilterCompareNode.VALUE_ATTR)); - - } - - fFilterTreeStack.push(node); - } - - @Override - public void endElement(String uri, String localName, String qName) throws SAXException { - ITmfFilterTreeNode node = fFilterTreeStack.pop(); - - if (fFilterTreeStack.isEmpty()) { - fRoot = node; - } else if (fFilterTreeStack.lastElement() instanceof TmfFilterTreeNode && - node instanceof TmfFilterTreeNode) { - fFilterTreeStack.lastElement().addChild(node); - } - - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/xml/TmfFilterXMLParser.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/xml/TmfFilterXMLParser.java deleted file mode 100644 index 7ddbd54b4e..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/xml/TmfFilterXMLParser.java +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Yuriy Vashchuk (yvashchuk@gmail.com) - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.filter.xml; - -import java.io.IOException; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParserFactory; - -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; - -/** - * The SAX based XML parser - * - * @version 1.0 - * @author Yuriy Vashchuk - * @author Patrick Tasse - */ -public class TmfFilterXMLParser { - - private static ITmfFilterTreeNode fRoot = null; - - /** - * The XMLParser constructor - * - * @param uri The XML file to parse - * @throws SAXException SAX exception - * @throws IOException IO exception - */ - public TmfFilterXMLParser(final String uri) throws SAXException, IOException { - - SAXParserFactory m_parserFactory = null; - m_parserFactory = SAXParserFactory.newInstance(); - m_parserFactory.setNamespaceAware(true); - - XMLReader saxReader = null; - try { - - saxReader = m_parserFactory.newSAXParser().getXMLReader(); - saxReader.setContentHandler(new TmfFilterContentHandler()); - saxReader.parse(uri); - - fRoot = ((TmfFilterContentHandler) saxReader.getContentHandler()).getTree(); - - } catch (ParserConfigurationException e) { - e.printStackTrace(); - } - } - - /** - * Getter of tree - * - * @return The builded tree - */ - public ITmfFilterTreeNode getTree() { - return fRoot; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/xml/TmfFilterXMLWriter.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/xml/TmfFilterXMLWriter.java deleted file mode 100644 index e642733e8e..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/xml/TmfFilterXMLWriter.java +++ /dev/null @@ -1,162 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Yuriy Vashchuk (yvashchuk@gmail.com) - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.filter.xml; - -import java.io.File; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterAndNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterCompareNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterContainsNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterEqualsNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterEventTypeNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterMatchesNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterOrNode; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -/** - * The SAX based XML writer - * - * @version 1.0 - * @author Yuriy Vashchuk - * @author Patrick Tasse - */ -public class TmfFilterXMLWriter { - - private Document document = null; - - /** - * The XMLParser constructor - * - * @param root The tree root - * @throws ParserConfigurationException if a DocumentBuilder - * cannot be created which satisfies the configuration requested. - */ - public TmfFilterXMLWriter(final ITmfFilterTreeNode root) throws ParserConfigurationException { - DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); - document = documentBuilder.newDocument(); - - Element rootElement = document.createElement(root.getNodeName()); - document.appendChild(rootElement); - - for (ITmfFilterTreeNode node : root.getChildren()) { - buildXMLTree(document, node, rootElement); - } - } - - /** - * The Tree to XML parser - * - * @param document The XML document - * @param treenode The node to write - * @param parentElement The XML element of the parent - */ - public static void buildXMLTree(final Document document, final ITmfFilterTreeNode treenode, Element parentElement) { - Element element = document.createElement(treenode.getNodeName()); - - if (treenode instanceof TmfFilterNode) { - - TmfFilterNode node = (TmfFilterNode) treenode; - element.setAttribute(TmfFilterNode.NAME_ATTR, node.getFilterName()); - - } else if (treenode instanceof TmfFilterEventTypeNode) { - - TmfFilterEventTypeNode node = (TmfFilterEventTypeNode) treenode; - element.setAttribute(TmfFilterEventTypeNode.TYPE_ATTR, node.getEventType()); - element.setAttribute(TmfFilterEventTypeNode.NAME_ATTR, node.getName()); - - } else if (treenode instanceof TmfFilterAndNode) { - - TmfFilterAndNode node = (TmfFilterAndNode) treenode; - element.setAttribute(TmfFilterAndNode.NOT_ATTR, Boolean.toString(node.isNot())); - - } else if (treenode instanceof TmfFilterOrNode) { - - TmfFilterOrNode node = (TmfFilterOrNode) treenode; - element.setAttribute(TmfFilterOrNode.NOT_ATTR, Boolean.toString(node.isNot())); - - } else if (treenode instanceof TmfFilterContainsNode) { - - TmfFilterContainsNode node = (TmfFilterContainsNode) treenode; - element.setAttribute(TmfFilterContainsNode.NOT_ATTR, Boolean.toString(node.isNot())); - element.setAttribute(TmfFilterContainsNode.FIELD_ATTR, node.getField()); - element.setAttribute(TmfFilterContainsNode.VALUE_ATTR, node.getValue()); - element.setAttribute(TmfFilterContainsNode.IGNORECASE_ATTR, Boolean.toString(node.isIgnoreCase())); - - } else if (treenode instanceof TmfFilterEqualsNode) { - - TmfFilterEqualsNode node = (TmfFilterEqualsNode) treenode; - element.setAttribute(TmfFilterEqualsNode.NOT_ATTR, Boolean.toString(node.isNot())); - element.setAttribute(TmfFilterEqualsNode.FIELD_ATTR, node.getField()); - element.setAttribute(TmfFilterEqualsNode.VALUE_ATTR, node.getValue()); - element.setAttribute(TmfFilterEqualsNode.IGNORECASE_ATTR, Boolean.toString(node.isIgnoreCase())); - - } else if (treenode instanceof TmfFilterMatchesNode) { - - TmfFilterMatchesNode node = (TmfFilterMatchesNode) treenode; - element.setAttribute(TmfFilterMatchesNode.NOT_ATTR, Boolean.toString(node.isNot())); - element.setAttribute(TmfFilterMatchesNode.FIELD_ATTR, node.getField()); - element.setAttribute(TmfFilterMatchesNode.REGEX_ATTR, node.getRegex()); - - } else if (treenode instanceof TmfFilterCompareNode) { - - TmfFilterCompareNode node = (TmfFilterCompareNode) treenode; - element.setAttribute(TmfFilterCompareNode.NOT_ATTR, Boolean.toString(node.isNot())); - element.setAttribute(TmfFilterCompareNode.FIELD_ATTR, node.getField()); - element.setAttribute(TmfFilterCompareNode.RESULT_ATTR, Integer.toString(node.getResult())); - element.setAttribute(TmfFilterCompareNode.TYPE_ATTR, node.getType().toString()); - element.setAttribute(TmfFilterCompareNode.VALUE_ATTR, node.getValue()); - - } - - parentElement.appendChild(element); - - for (int i = 0; i < treenode.getChildrenCount(); i++) { - buildXMLTree(document, treenode.getChild(i), element); - } - } - - /** - * Save the tree - * - * @param uri The new Filter XML path - */ - public void saveTree(final String uri) { - TransformerFactory transformerFactory = TransformerFactory.newInstance(); - - try { - Transformer transformer = transformerFactory.newTransformer(); - DOMSource source = new DOMSource(document); - StreamResult result = new StreamResult(new File(uri)); - transformer.transform(source, result); - } catch (TransformerConfigurationException e) { - e.printStackTrace(); - } catch (TransformerException e) { - e.printStackTrace(); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/io/BufferedRandomAccessFile.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/io/BufferedRandomAccessFile.java deleted file mode 100644 index 8c0b9c3ed3..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/io/BufferedRandomAccessFile.java +++ /dev/null @@ -1,229 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation, based on article by Nick Zhang - * (http://www.javaworld.com/javatips/jw-javatip26.html) - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.io; - -import java.io.File; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.charset.Charset; - -/** - * A class to mitigate the Java I/O inefficiency of RandomAccessFile. - * - * @version 1.0 - * @author Patrick Tasse - */ -public class BufferedRandomAccessFile extends RandomAccessFile { - - private static final int DEFAULT_BUF_SIZE = 8192; - private static final Charset CHARSET_UTF8 = Charset.forName("UTF-8"); //$NON-NLS-1$ - - private final int BUF_SIZE; - private final byte buffer[]; - private int buf_end = 0; - private int buf_pos = 0; - private long real_pos = 0; - private final StringBuilder sb = new StringBuilder(); - - /** - * Constructor using the default buffer size - * - * @param name - * File path. This is passed as-is to the RandomAccessFile's - * constructor. - * @param mode - * File open mode ("r", "rw", etc.). This is passed as-is to - * RandomAccessFile's constructor. - * @throws IOException - * If the file was not found or couldn't be opened with the - * request permissions - */ - public BufferedRandomAccessFile(String name, String mode) throws IOException { - this(name, mode, DEFAULT_BUF_SIZE); - } - - /** - * Constructor using the default buffer size - * - * @param file - * File object. This is passed as-is to the RandomAccessFile's - * constructor. - * @param mode - * File open mode ("r", "rw", etc.). This is passed as-is to - * RandomAccessFile's constructor. - * @throws IOException - * If the file was not found or couldn't be opened with the - * request permissions - */ - public BufferedRandomAccessFile(File file, String mode) throws IOException { - this(file, mode, DEFAULT_BUF_SIZE); - } - - /** - * Standard constructor. - * - * @param name - * File path. This is passed as-is to the RandomAccessFile's - * constructor. - * @param mode - * File open mode ("r", "rw", etc.). This is passed as-is to - * RandomAccessFile's constructor. - * @param bufsize - * Buffer size to use, in bytes - * @throws IOException - * If the file was not found or couldn't be opened with the - * request permissions - */ - public BufferedRandomAccessFile(String name, String mode, int bufsize) throws IOException { - super(name, mode); - invalidate(); - BUF_SIZE = bufsize; - buffer = new byte[BUF_SIZE]; - } - - /** - * Standard constructor. - * - * @param file - * File object. This is passed as-is to the RandomAccessFile's - * constructor. - * @param mode - * File open mode ("r", "rw", etc.). This is passed as-is to - * RandomAccessFile's constructor. - * @param bufsize - * Buffer size to use, in bytes - * @throws IOException - * If the file was not found or couldn't be opened with the - * request permissions - */ - public BufferedRandomAccessFile(File file, String mode, int bufsize) throws IOException { - super(file, mode); - invalidate(); - BUF_SIZE = bufsize; - buffer = new byte[BUF_SIZE]; - } - - @Override - public final int read() throws IOException { - if (buf_pos >= buf_end) { - if (fillBuffer() < 0) { - return -1; - } - } - if (buf_end == 0) { - return -1; - } - return (buffer[buf_pos++] & 0xff); - } - - @Override - public int read(byte b[], int off, int len) throws IOException { - int leftover = buf_end - buf_pos; - if (len <= leftover) { - System.arraycopy(buffer, buf_pos, b, off, len); - buf_pos += len; - return len; - } - for (int i = 0; i < len; i++) { - int c = this.read(); - if (c != -1) { - b[off + i] = (byte) c; - } else { - if (i == 0) { - return -1; - } - return i; - } - } - return len; - } - - @Override - public long getFilePointer() throws IOException { - long l = real_pos; - return (l - buf_end + buf_pos); - } - - @Override - public void seek(long pos) throws IOException { - int n = (int) (real_pos - pos); - if (n >= 0 && n <= buf_end) { - buf_pos = buf_end - n; - } else { - super.seek(pos); - invalidate(); - } - } - - /** - * Read the next line from the buffer (ie, until the next '\n'). The bytes - * are interpreted as UTF-8 characters. - * - * @return The String that was read - * @throws IOException - * If we failed reading the file - */ - public final String getNextLine() throws IOException { - String str = null; - if (buf_end - buf_pos <= 0) { - if (fillBuffer() < 0) { - return null; - } - } - int lineend = -1; - for (int i = buf_pos; i < buf_end; i++) { - if (buffer[i] == '\n') { - lineend = i; - break; - } - } - if (lineend < 0) { - sb.delete(0, sb.length()); - int c; - while (((c = read()) != -1) && (c != '\n')) { - sb.append((char) c); - } - if ((c == -1) && (sb.length() == 0)) { - return null; - } - if (sb.charAt(sb.length() - 1) == '\r') { - sb.deleteCharAt(sb.length() - 1); - } - return sb.toString(); - } - if (lineend > 0 && buffer[lineend - 1] == '\r' && lineend > buf_pos) { - str = new String(buffer, buf_pos, lineend - buf_pos - 1, CHARSET_UTF8); - } else { - str = new String(buffer, buf_pos, lineend - buf_pos, CHARSET_UTF8); - } - buf_pos = lineend + 1; - return str; - } - - private int fillBuffer() throws IOException { - int n = super.read(buffer, 0, BUF_SIZE); - if (n >= 0) { - real_pos += n; - buf_end = n; - buf_pos = 0; - } - return n; - } - - private void invalidate() throws IOException { - buf_end = 0; - buf_pos = 0; - real_pos = super.getFilePointer(); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/messages.properties b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/messages.properties deleted file mode 100644 index 501a62717c..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/messages.properties +++ /dev/null @@ -1,13 +0,0 @@ -############################################################################### -# Copyright (c) 2013 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Marc-Andre Laperle - Initial API and implementation -############################################################################### - -DefaultTraceProjectName=Tracing \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomEvent.java deleted file mode 100644 index e8508c4295..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomEvent.java +++ /dev/null @@ -1,314 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.parsers.custom; - -import java.text.ParseException; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTraceDefinition.OutputColumn; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampFormat; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Base event for custom text parsers. - * - * @author Patrick Tassé - * @since 3.0 - */ -public class CustomEvent extends TmfEvent { - - /** Input format key */ - protected static final String TIMESTAMP_INPUT_FORMAT_KEY = "CE_TS_I_F"; //$NON-NLS-1$ - - /** Empty message */ - protected static final String NO_MESSAGE = ""; //$NON-NLS-1$ - - /** Replacement for the super-class' timestamp field */ - private ITmfTimestamp customEventTimestamp; - - /** Replacement for the super-class' content field */ - private ITmfEventField customEventContent; - - /** Replacement for the super-class' type field */ - private ITmfEventType customEventType; - - /** The trace to which this event belongs */ - protected CustomTraceDefinition fDefinition; - - /** The payload data of this event, */ - protected Map fData; - - private TmfEventField[] fColumnData; - - /** - * Basic constructor. - * - * @param definition - * The trace definition to which this event belongs - */ - public CustomEvent(CustomTraceDefinition definition) { - fDefinition = definition; - fData = new HashMap<>(); - } - - /** - * Build a new CustomEvent from an existing TmfEvent. - * - * @param definition - * The trace definition to which this event belongs - * @param other - * The TmfEvent to copy - */ - public CustomEvent(CustomTraceDefinition definition, TmfEvent other) { - super(other); - fDefinition = definition; - fData = new HashMap<>(); - - /* Set our overridden fields */ - customEventTimestamp = other.getTimestamp(); - customEventContent = other.getContent(); - customEventType = other.getType(); - } - - /** - * Full constructor - * - * @param definition - * Trace definition of this event - * @param parentTrace - * Parent trace object - * @param timestamp - * Timestamp of this event - * @param source - * Source of the event - * @param type - * Event type - * @param reference - * Event reference - */ - public CustomEvent(CustomTraceDefinition definition, ITmfTrace parentTrace, - ITmfTimestamp timestamp, String source, TmfEventType type, - String reference) { - /* Do not use upstream's fields for stuff we override */ - super(parentTrace, null, source, null, null, reference); - fDefinition = definition; - fData = new HashMap<>(); - - /* Set our overridden fields */ - customEventTimestamp = timestamp; - customEventContent = null; - customEventType = type; - } - - // ------------------------------------------------------------------------ - // Overridden getters - // ------------------------------------------------------------------------ - - @Override - public ITmfTimestamp getTimestamp() { - if (fData != null) { - processData(); - } - return customEventTimestamp; - } - - @Override - public ITmfEventField getContent() { - return customEventContent; - } - - @Override - public ITmfEventType getType() { - return customEventType; - } - - // ------------------------------------------------------------------------ - // Setters - // ------------------------------------------------------------------------ - - /** - * Set this event's timestamp - * - * @param timestamp - * The new timestamp - */ - protected void setTimestamp(ITmfTimestamp timestamp) { - customEventTimestamp = timestamp; - } - - /** - * Set this event's content - * - * @param content - * The new content - */ - protected void setContent(ITmfEventField content) { - customEventContent = content; - } - - /** - * Set this event's type - * - * @param type - * The new type - */ - protected void setType(ITmfEventType type) { - customEventType = type; - } - - // ------------------------------------------------------------------------ - // Other operations - // ------------------------------------------------------------------------ - - /** - * Get the contents of an event table cell for this event's row. - * - * @param index - * The ID/index of the field to display. This corresponds to the - * index in the event content. - * @return The String to display in the cell - * @since 3.1 - */ - public String getEventString(int index) { - if (fData != null) { - processData(); - } - if (index < 0 || index >= fColumnData.length) { - return ""; //$NON-NLS-1$ - } - - return fColumnData[index].getValue().toString(); - } - - /** - * Get the contents of the row in the events table corresponding to this - * event. The order of the elements corresponds to the order of the columns. - * - * @return The event row entries - * @deprecated This should not be used, since this isn't related to the - * order of columns in the view anymore. You should use - * {@link #getEventString(int)} - */ - @Deprecated - public String[] getEventStrings() { - if (fData != null) { - processData(); - } - String[] entries = new String[fColumnData.length]; - for (int i = 0; i < fColumnData.length; i++) { - entries[i] = fColumnData[i].getValue().toString(); - } - return entries; - } - - private void processData() { - String timestampString = fData.get(CustomTraceDefinition.TAG_TIMESTAMP); - String timestampInputFormat = fData.get(TIMESTAMP_INPUT_FORMAT_KEY); - TmfTimestamp timestamp = null; - if (timestampInputFormat != null && timestampString != null) { - TmfTimestampFormat timestampFormat = new TmfTimestampFormat(timestampInputFormat); - try { - long time = timestampFormat.parseValue(timestampString); - timestamp = new TmfNanoTimestamp(getTrace().getTimestampTransform().transform(time)); - setTimestamp(timestamp); - } catch (ParseException e) { - setTimestamp(TmfTimestamp.ZERO); - } - } else { - setTimestamp(TmfTimestamp.ZERO); - } - - int i = 0; - fColumnData = new TmfEventField[fDefinition.outputs.size()]; - for (OutputColumn outputColumn : fDefinition.outputs) { - String value = fData.get(outputColumn.name); - if (outputColumn.name.equals(CustomTraceDefinition.TAG_TIMESTAMP) && timestamp != null) { - TmfTimestampFormat timestampFormat = new TmfTimestampFormat(fDefinition.timeStampOutputFormat); - fColumnData[i++] = new TmfEventField(outputColumn.name, timestampFormat.format(timestamp.getValue()), null); - } else { - fColumnData[i++] = new TmfEventField(outputColumn.name, (value != null ? value : ""), null); //$NON-NLS-1$ - } - } - CustomEventContent curContent = (CustomEventContent) getContent(); - setContent(new CustomEventContent(curContent.getName(), curContent.getValue(), fColumnData)); - fData = null; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((fDefinition == null) ? 0 : fDefinition.hashCode()); - result = prime * result + ((customEventTimestamp == null) ? 0 : customEventTimestamp.hashCode()); - result = prime * result + ((customEventContent == null) ? 0 : customEventContent.hashCode()); - result = prime * result + ((customEventType == null) ? 0 : customEventType.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof CustomEvent)) { - return false; - } - CustomEvent other = (CustomEvent) obj; - if (fDefinition == null) { - if (other.fDefinition != null) { - return false; - } - } else if (!fDefinition.equals(other.fDefinition)) { - return false; - } - - if (customEventTimestamp == null) { - if (other.customEventTimestamp != null) { - return false; - } - } else if (!customEventTimestamp.equals(other.customEventTimestamp)) { - return false; - } - - if (customEventContent == null) { - if (other.customEventContent != null) { - return false; - } - } else if (!customEventContent.equals(other.customEventContent)) { - return false; - } - - if (customEventType == null) { - if (other.customEventType != null) { - return false; - } - } else if (!customEventType.equals(other.customEventType)) { - return false; - } - - return true; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomEventContent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomEventContent.java deleted file mode 100644 index 69684a8957..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomEventContent.java +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tassé - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.parsers.custom; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; - -/** - * Event content for custom text parsers - * - * @author Patrick Tassé - * @since 3.0 - */ -public class CustomEventContent extends TmfEventField { - - /** - * Constructor. - * - * @param parent - * Parent event - * @param content - * Event content - */ - public CustomEventContent(CustomEvent parent, StringBuffer content) { - super(ITmfEventField.ROOT_FIELD_ID, content, null); - } - - /** - * Create a new event field with sub-fields. - * - * @param name - * Field name - * @param content - * Event content - * @param fields - * The array of sub-fields - */ - public CustomEventContent(String name, Object content, ITmfEventField[] fields) { - super(name, content, fields); - } - - @Override - public int hashCode() { - return super.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof CustomEventContent)) { - return false; - } - return true; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomEventType.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomEventType.java deleted file mode 100644 index 2dc5c785c7..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomEventType.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tassé - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.parsers.custom; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; - -/** - * Event type for custom text parsers. - * - * @author Patrick Tassé - * @since 3.0 - */ -public abstract class CustomEventType extends TmfEventType { - - private static String CONTEXT_ID = "CustomEventType"; //$NON-NLS-1$ - - /** - * Constructor - * - * @param definition - * Trace definition - */ - public CustomEventType(CustomTraceDefinition definition) { - super(CONTEXT_ID, definition.definitionName, getRootField(definition)); - } - - private static ITmfEventField getRootField(CustomTraceDefinition definition) { - ITmfEventField[] fields = new ITmfEventField[definition.outputs.size()]; - for (int i = 0; i < fields.length; i++) { - fields[i] = new TmfEventField(definition.outputs.get(i).name, null, null); - } - ITmfEventField rootField = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, null, fields); - return rootField; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTraceDefinition.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTraceDefinition.java deleted file mode 100644 index d38ddd92f8..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTraceDefinition.java +++ /dev/null @@ -1,157 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.parsers.custom; - -import java.io.ByteArrayInputStream; -import java.text.SimpleDateFormat; -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.xml.sax.EntityResolver; -import org.xml.sax.ErrorHandler; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -/** - * Base class for custom trace definitions. - * - * @author Patrick Tassé - * @since 3.0 - */ -public abstract class CustomTraceDefinition { - - /** "set" action */ - public static final int ACTION_SET = 0; - - /** "append" action */ - public static final int ACTION_APPEND = 1; - - /** "append with separator" action */ - public static final int ACTION_APPEND_WITH_SEPARATOR = 2; - - /** Timestamp tag */ - public static final String TAG_TIMESTAMP = Messages.CustomTraceDefinition_timestampTag; - - /** Message tag */ - public static final String TAG_MESSAGE = Messages.CustomTraceDefinition_messageTag; - - /** "Other" tag */ - public static final String TAG_OTHER = Messages.CustomTraceDefinition_otherTag; - - /** Category of this trace definition - * @since 3.2 */ - public String categoryName; - - /** Name of this trace definition */ - public String definitionName; - - /** List of output columns */ - public List outputs; - - /** Timestamp format */ - public String timeStampOutputFormat; - - /** - * Definition of an output column - */ - public static class OutputColumn { - - /** Name of this column */ - public String name; - - /** - * Default constructor (empty) - */ - public OutputColumn() {} - - /** - * Constructor - * - * @param name Name of this output column - */ - public OutputColumn(String name) { - this.name = name; - } - - @Override - public String toString() { - return name; - } - } - - /** - * Format a timestamp in this trace's current time stamp format. - * - * @param timestamp - * The timestamp to format - * @return The same timestamp as a formatted string - */ - public String formatTimeStamp(TmfTimestamp timestamp) { - SimpleDateFormat simpleDateFormat = new SimpleDateFormat(timeStampOutputFormat); - return simpleDateFormat.format(timestamp.getValue()); - } - - /** - * Save this custom trace in the default path. - */ - public abstract void save(); - - /** - * Save this custom trace in the supplied path. - * - * @param path - * The path to save to - */ - public abstract void save(String path); - - /** - * Creates a new empty entity resolver - * - * @return a new entity resolver - * @since 3.1 - */ - protected static EntityResolver createEmptyEntityResolver() { - return new EntityResolver() { - @Override - public InputSource resolveEntity(String publicId, String systemId) { - String empty = ""; //$NON-NLS-1$ - ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); - return new InputSource(bais); - } - }; - } - - /** - * Creates an error handler for parse exceptions - * - * @return a new error handler - * @since 3.1 - */ - protected static ErrorHandler createErrorHandler() { - return new ErrorHandler() { - @Override - public void error(SAXParseException saxparseexception) throws SAXException { - } - - @Override - public void warning(SAXParseException saxparseexception) throws SAXException { - } - - @Override - public void fatalError(SAXParseException saxparseexception) throws SAXException { - throw saxparseexception; - } - }; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtEvent.java deleted file mode 100644 index b8d11f2927..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtEvent.java +++ /dev/null @@ -1,143 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.parsers.custom; - -import java.util.regex.Matcher; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTraceDefinition.InputData; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTraceDefinition.InputLine; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Trace event for custom text parsers. - * - * @author Patrick Tassé - * @since 3.0 - */ -public class CustomTxtEvent extends CustomEvent { - - /** - * Constructor - * - * @param definition - * Trace definition - */ - public CustomTxtEvent(CustomTxtTraceDefinition definition) { - super(definition); - setType(new CustomTxtEventType(definition)); - } - - /** - * Construct a custom text event from an existing TmfEvent. - * - * @param definition - * Trace definition - * @param other - * The TmfEvent object to copy - */ - public CustomTxtEvent(CustomTxtTraceDefinition definition, TmfEvent other) { - super(definition, other); - } - - /** - * Full constructor. - * - * @param definition - * Trace definition - * @param parentTrace - * Parent trace object - * @param timestamp - * Timestamp of this event - * @param source - * Source of this event - * @param type - * Event type - * @param reference - * Reference if this event - */ - public CustomTxtEvent(CustomTxtTraceDefinition definition, - ITmfTrace parentTrace, ITmfTimestamp timestamp, String source, - TmfEventType type, String reference) { - super(definition, parentTrace, timestamp, source, type, reference); - } - - @Override - public void setContent(ITmfEventField content) { - super.setContent(content); - } - - /** - * Process an entry in the trace file - * - * @param input - * The input line to read - * @param matcher - * The regex matcher to use - */ - public void processGroups(InputLine input, Matcher matcher) { - if (input.columns == null) { - return; - } - for (int i = 0; i < input.columns.size(); i++) { - InputData column = input.columns.get(i); - if (i < matcher.groupCount() && matcher.group(i + 1) != null) { - String value = matcher.group(i + 1).trim(); - if (value.length() == 0) { - continue; - } - String name = column.name; - if (column.action == CustomTraceDefinition.ACTION_SET) { - fData.put(name, value); - if (name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - fData.put(TIMESTAMP_INPUT_FORMAT_KEY, column.format); - } - } else if (column.action == CustomTraceDefinition.ACTION_APPEND) { - String s = fData.get(name); - if (s != null) { - fData.put(name, s + value); - } else { - fData.put(name, value); - } - if (name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - String timeStampInputFormat = fData.get(TIMESTAMP_INPUT_FORMAT_KEY); - if (timeStampInputFormat != null) { - fData.put(TIMESTAMP_INPUT_FORMAT_KEY, timeStampInputFormat + column.format); - } else { - fData.put(TIMESTAMP_INPUT_FORMAT_KEY, column.format); - } - } - } else if (column.action == CustomTraceDefinition.ACTION_APPEND_WITH_SEPARATOR) { - String s = fData.get(name); - if (s != null) { - fData.put(name, s + " | " + value); //$NON-NLS-1$ - } else { - fData.put(name, value); - } - if (name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - String timeStampInputFormat = fData.get(TIMESTAMP_INPUT_FORMAT_KEY); - if (timeStampInputFormat != null) { - fData.put(TIMESTAMP_INPUT_FORMAT_KEY, timeStampInputFormat + " | " + column.format); //$NON-NLS-1$ - } else { - fData.put(TIMESTAMP_INPUT_FORMAT_KEY, column.format); - } - } - } - } - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtEventType.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtEventType.java deleted file mode 100644 index 5bf681e4db..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtEventType.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.parsers.custom; - -/** - * Event type for custom text traces. - * - * @author Patrick Tassé - * @since 3.0 - */ -public class CustomTxtEventType extends CustomEventType { - - /** - * Constructor - * - * @param definition - * Custom text trace definition - */ - public CustomTxtEventType(CustomTxtTraceDefinition definition) { - super(definition); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtTrace.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtTrace.java deleted file mode 100644 index 5d45ce359b..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtTrace.java +++ /dev/null @@ -1,463 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.parsers.custom; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map.Entry; -import java.util.regex.Matcher; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.io.BufferedRandomAccessFile; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTraceDefinition.InputLine; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser; -import org.eclipse.linuxtools.tmf.core.trace.TmfContext; -import org.eclipse.linuxtools.tmf.core.trace.TmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TraceValidationStatus; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfPersistentlyIndexable; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.indexer.TmfBTreeTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation; - -/** - * Base class for custom plain text traces. - * - * @author Patrick Tassé - * @since 3.0 - */ -public class CustomTxtTrace extends TmfTrace implements ITmfEventParser, ITmfPersistentlyIndexable { - - private static final TmfLongLocation NULL_LOCATION = new TmfLongLocation(-1L); - private static final int DEFAULT_CACHE_SIZE = 100; - private static final int MAX_LINES = 100; - private static final int MAX_CONFIDENCE = 100; - - private final CustomTxtTraceDefinition fDefinition; - private final CustomTxtEventType fEventType; - private BufferedRandomAccessFile fFile; - - /** - * Basic constructor. - * - * @param definition - * Text trace definition - */ - public CustomTxtTrace(final CustomTxtTraceDefinition definition) { - fDefinition = definition; - fEventType = new CustomTxtEventType(fDefinition); - setCacheSize(DEFAULT_CACHE_SIZE); - } - - /** - * Full constructor. - * - * @param resource - * Trace's resource. - * @param definition - * Text trace definition - * @param path - * Path to the trace file - * @param cacheSize - * Cache size to use - * @throws TmfTraceException - * If we couldn't open the trace at 'path' - */ - public CustomTxtTrace(final IResource resource, - final CustomTxtTraceDefinition definition, final String path, - final int cacheSize) throws TmfTraceException { - this(definition); - setCacheSize((cacheSize > 0) ? cacheSize : DEFAULT_CACHE_SIZE); - initTrace(resource, path, CustomTxtEvent.class); - } - - @Override - public void initTrace(final IResource resource, final String path, final Class eventType) throws TmfTraceException { - super.initTrace(resource, path, eventType); - try { - fFile = new BufferedRandomAccessFile(getPath(), "r"); //$NON-NLS-1$ - } catch (IOException e) { - throw new TmfTraceException(e.getMessage(), e); - } - } - - @Override - public synchronized void dispose() { - super.dispose(); - if (fFile != null) { - try { - fFile.close(); - } catch (IOException e) { - } finally { - fFile = null; - } - } - } - - @Override - public ITmfTraceIndexer getIndexer() { - return super.getIndexer(); - } - - @Override - public synchronized TmfContext seekEvent(final ITmfLocation location) { - final CustomTxtTraceContext context = new CustomTxtTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK); - if (NULL_LOCATION.equals(location) || fFile == null) { - return context; - } - try { - if (location == null) { - fFile.seek(0); - } else if (location.getLocationInfo() instanceof Long) { - fFile.seek((Long) location.getLocationInfo()); - } - long rawPos = fFile.getFilePointer(); - String line = fFile.getNextLine(); - while (line != null) { - for (final InputLine input : getFirstLines()) { - final Matcher matcher = input.getPattern().matcher(line); - if (matcher.matches()) { - context.setLocation(new TmfLongLocation(rawPos)); - context.firstLineMatcher = matcher; - context.firstLine = line; - context.nextLineLocation = fFile.getFilePointer(); - context.inputLine = input; - return context; - } - } - rawPos = fFile.getFilePointer(); - line = fFile.getNextLine(); - } - return context; - } catch (final FileNotFoundException e) { - Activator.logError("Error seeking event. File not found: " + getPath(), e); //$NON-NLS-1$ - return context; - } catch (final IOException e) { - Activator.logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$ - return context; - } - - } - - @Override - public synchronized TmfContext seekEvent(final double ratio) { - if (fFile == null) { - return new CustomTxtTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK); - } - try { - long pos = Math.round(ratio * fFile.length()); - while (pos > 0) { - fFile.seek(pos - 1); - if (fFile.read() == '\n') { - break; - } - pos--; - } - final ITmfLocation location = new TmfLongLocation(pos); - final TmfContext context = seekEvent(location); - context.setRank(ITmfContext.UNKNOWN_RANK); - return context; - } catch (final IOException e) { - Activator.logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$ - return new CustomTxtTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK); - } - } - - @Override - public synchronized double getLocationRatio(final ITmfLocation location) { - if (fFile == null) { - return 0; - } - try { - if (location.getLocationInfo() instanceof Long) { - return ((Long) location.getLocationInfo()).doubleValue() / fFile.length(); - } - } catch (final IOException e) { - Activator.logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$ - } - return 0; - } - - @Override - public ITmfLocation getCurrentLocation() { - // TODO Auto-generated method stub - return null; - } - - @Override - public synchronized CustomTxtEvent parseEvent(final ITmfContext tmfContext) { - ITmfContext context = seekEvent(tmfContext.getLocation()); - return parse(context); - } - - @Override - public synchronized CustomTxtEvent getNext(final ITmfContext context) { - final ITmfContext savedContext = new TmfContext(context.getLocation(), context.getRank()); - final CustomTxtEvent event = parse(context); - if (event != null) { - updateAttributes(savedContext, event.getTimestamp()); - context.increaseRank(); - } - return event; - } - - private synchronized CustomTxtEvent parse(final ITmfContext tmfContext) { - if (fFile == null) { - return null; - } - if (!(tmfContext instanceof CustomTxtTraceContext)) { - return null; - } - - final CustomTxtTraceContext context = (CustomTxtTraceContext) tmfContext; - if (context.getLocation() == null || !(context.getLocation().getLocationInfo() instanceof Long) || NULL_LOCATION.equals(context.getLocation())) { - return null; - } - - CustomTxtEvent event = parseFirstLine(context); - - final HashMap countMap = new HashMap<>(); - InputLine currentInput = null; - if (context.inputLine.childrenInputs != null && context.inputLine.childrenInputs.size() > 0) { - currentInput = context.inputLine.childrenInputs.get(0); - countMap.put(currentInput, 0); - } - - try { - if (fFile.getFilePointer() != context.nextLineLocation) { - fFile.seek(context.nextLineLocation); - } - long rawPos = fFile.getFilePointer(); - String line = fFile.getNextLine(); - while (line != null) { - boolean processed = false; - if (currentInput == null) { - for (final InputLine input : getFirstLines()) { - final Matcher matcher = input.getPattern().matcher(line); - if (matcher.matches()) { - context.setLocation(new TmfLongLocation(rawPos)); - context.firstLineMatcher = matcher; - context.firstLine = line; - context.nextLineLocation = fFile.getFilePointer(); - context.inputLine = input; - return event; - } - } - } else { - if (countMap.get(currentInput) >= currentInput.getMinCount()) { - final List nextInputs = currentInput.getNextInputs(countMap); - if (nextInputs.size() == 0 || nextInputs.get(nextInputs.size() - 1).getMinCount() == 0) { - for (final InputLine input : getFirstLines()) { - final Matcher matcher = input.getPattern().matcher(line); - if (matcher.matches()) { - context.setLocation(new TmfLongLocation(rawPos)); - context.firstLineMatcher = matcher; - context.firstLine = line; - context.nextLineLocation = fFile.getFilePointer(); - context.inputLine = input; - return event; - } - } - } - for (final InputLine input : nextInputs) { - final Matcher matcher = input.getPattern().matcher(line); - if (matcher.matches()) { - event.processGroups(input, matcher); - currentInput = input; - if (countMap.get(currentInput) == null) { - countMap.put(currentInput, 1); - } else { - countMap.put(currentInput, countMap.get(currentInput) + 1); - } - Iterator iter = countMap.keySet().iterator(); - while (iter.hasNext()) { - final InputLine inputLine = iter.next(); - if (inputLine.level > currentInput.level) { - iter.remove(); - } - } - if (currentInput.childrenInputs != null && currentInput.childrenInputs.size() > 0) { - currentInput = currentInput.childrenInputs.get(0); - countMap.put(currentInput, 0); - } else if (countMap.get(currentInput) >= currentInput.getMaxCount()) { - if (currentInput.getNextInputs(countMap).size() > 0) { - currentInput = currentInput.getNextInputs(countMap).get(0); - if (countMap.get(currentInput) == null) { - countMap.put(currentInput, 0); - } - iter = countMap.keySet().iterator(); - while (iter.hasNext()) { - final InputLine inputLine = iter.next(); - if (inputLine.level > currentInput.level) { - iter.remove(); - } - } - } else { - currentInput = null; - } - } - processed = true; - break; - } - } - } - if (!processed && currentInput != null) { - final Matcher matcher = currentInput.getPattern().matcher(line); - if (matcher.matches()) { - event.processGroups(currentInput, matcher); - countMap.put(currentInput, countMap.get(currentInput) + 1); - if (currentInput.childrenInputs != null && currentInput.childrenInputs.size() > 0) { - currentInput = currentInput.childrenInputs.get(0); - countMap.put(currentInput, 0); - } else if (countMap.get(currentInput) >= currentInput.getMaxCount()) { - if (currentInput.getNextInputs(countMap).size() > 0) { - currentInput = currentInput.getNextInputs(countMap).get(0); - if (countMap.get(currentInput) == null) { - countMap.put(currentInput, 0); - } - final Iterator iter = countMap.keySet().iterator(); - while (iter.hasNext()) { - final InputLine inputLine = iter.next(); - if (inputLine.level > currentInput.level) { - iter.remove(); - } - } - } else { - currentInput = null; - } - } - } - ((StringBuffer) event.getContent().getValue()).append("\n").append(line); //$NON-NLS-1$ - } - } - rawPos = fFile.getFilePointer(); - line = fFile.getNextLine(); - } - } catch (final IOException e) { - Activator.logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$ - } - for (final Entry entry : countMap.entrySet()) { - if (entry.getValue() < entry.getKey().getMinCount()) { - event = null; - } - } - context.setLocation(NULL_LOCATION); - return event; - } - - /** - * @return The first few lines of the text file - */ - public List getFirstLines() { - return fDefinition.inputs; - } - - /** - * Parse the first line of the trace (to recognize the type). - * - * @param context - * Trace context - * @return The first event - */ - public CustomTxtEvent parseFirstLine(final CustomTxtTraceContext context) { - final CustomTxtEvent event = new CustomTxtEvent(fDefinition, this, TmfTimestamp.ZERO, "", fEventType, ""); //$NON-NLS-1$ //$NON-NLS-2$ - event.processGroups(context.inputLine, context.firstLineMatcher); - event.setContent(new CustomEventContent(event, new StringBuffer(context.firstLine))); - return event; - } - - /** - * Get the trace definition. - * - * @return The trace definition - */ - public CustomTraceDefinition getDefinition() { - return fDefinition; - } - - /** - * {@inheritDoc} - *

- * The default implementation computes the confidence as the percentage of - * lines in the first 100 lines of the file which match any of the root - * input line patterns. - */ - @Override - public IStatus validate(IProject project, String path) { - File file = new File(path); - if (!file.exists() || !file.isFile() || !file.canRead()) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CustomTrace_FileNotFound + ": " + path); //$NON-NLS-1$ - } - int confidence = 0; - try (BufferedRandomAccessFile rafile = new BufferedRandomAccessFile(path, "r")) { //$NON-NLS-1$ - int lineCount = 0; - double matches = 0.0; - String line = rafile.getNextLine(); - while ((line != null) && (lineCount++ < MAX_LINES)) { - for (InputLine inputLine : fDefinition.inputs) { - Matcher matcher = inputLine.getPattern().matcher(line); - if (matcher.matches()) { - int groupCount = matcher.groupCount(); - matches += (1.0 + groupCount / ((double) groupCount + 1)); - break; - } - } - confidence = (int) (MAX_CONFIDENCE * matches / lineCount); - line = rafile.getNextLine(); - } - } catch (IOException e) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "IOException validating file: " + path, e); //$NON-NLS-1$ - } - return new TraceValidationStatus(confidence, Activator.PLUGIN_ID); - } - - private static int fCheckpointSize = -1; - - @Override - public synchronized int getCheckpointSize() { - if (fCheckpointSize == -1) { - TmfCheckpoint c = new TmfCheckpoint(TmfTimestamp.ZERO, new TmfLongLocation(0L), 0); - ByteBuffer b = ByteBuffer.allocate(ITmfCheckpoint.MAX_SERIALIZE_SIZE); - b.clear(); - c.serialize(b); - fCheckpointSize = b.position(); - } - - return fCheckpointSize; - } - - @Override - public ITmfLocation restoreLocation(ByteBuffer bufferIn) { - return new TmfLongLocation(bufferIn); - } - - @Override - protected ITmfTraceIndexer createIndexer(int interval) { - return new TmfBTreeTraceIndexer(this, interval); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtTraceContext.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtTraceContext.java deleted file mode 100644 index ca01f22a8b..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtTraceContext.java +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.parsers.custom; - -import java.util.regex.Matcher; - -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTraceDefinition.InputLine; -import org.eclipse.linuxtools.tmf.core.trace.TmfContext; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - -/** - * Trace context for custom text traces. - * - * @author Patrick Tassé - * @since 3.0 - */ -public class CustomTxtTraceContext extends TmfContext { - - /** Regex matcher for the first line of the trace */ - public Matcher firstLineMatcher; - - /** First line of the text file */ - public String firstLine; - - /** Position in the file where the 'current' next line is */ - public long nextLineLocation; - - /** InputLine object for the currently read line */ - public InputLine inputLine; - - /** - * Constructor. - * - * @param location - * Location in the trace - * @param rank - * Rank of the event at this location - */ - public CustomTxtTraceContext(ITmfLocation location, long rank) { - super(location, rank); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((firstLine == null) ? 0 : firstLine.hashCode()); - result = prime * result + ((firstLineMatcher == null) ? 0 : firstLineMatcher.hashCode()); - result = prime * result + ((inputLine == null) ? 0 : inputLine.hashCode()); - result = prime * result + (int) (nextLineLocation ^ (nextLineLocation >>> 32)); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof CustomTxtTraceContext)) { - return false; - } - CustomTxtTraceContext other = (CustomTxtTraceContext) obj; - if (firstLine == null) { - if (other.firstLine != null) { - return false; - } - } else if (!firstLine.equals(other.firstLine)) { - return false; - } - if (firstLineMatcher == null) { - if (other.firstLineMatcher != null) { - return false; - } - } else if (!firstLineMatcher.equals(other.firstLineMatcher)) { - return false; - } - if (inputLine == null) { - if (other.inputLine != null) { - return false; - } - } else if (!inputLine.equals(other.inputLine)) { - return false; - } - if (nextLineLocation != other.nextLineLocation) { - return false; - } - return true; - } - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtTraceDefinition.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtTraceDefinition.java deleted file mode 100644 index 02e8911ad6..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomTxtTraceDefinition.java +++ /dev/null @@ -1,935 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Matthew Khouzam - Add support for default parsers - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.parsers.custom; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.eclipse.core.runtime.Platform; -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -/** - * Trace definition for custom text traces. - * - * @author Patrick Tassé - * @since 3.0 - */ -public class CustomTxtTraceDefinition extends CustomTraceDefinition { - - /** Input lines */ - public List inputs; - - /** File name of the default definition file */ - protected static final String CUSTOM_TXT_TRACE_DEFINITIONS_DEFAULT_FILE_NAME = "custom_txt_default_parsers.xml"; //$NON-NLS-1$ - /** File name of the definition file */ - protected static final String CUSTOM_TXT_TRACE_DEFINITIONS_FILE_NAME = "custom_txt_parsers.xml"; //$NON-NLS-1$ - - /** Path of the definition file */ - protected static final String CUSTOM_TXT_TRACE_DEFINITIONS_DEFAULT_PATH_NAME = - Platform.getInstallLocation().getURL().getPath() + "templates/org.eclipse.linuxtools.tmf.core/" + //$NON-NLS-1$ - CUSTOM_TXT_TRACE_DEFINITIONS_DEFAULT_FILE_NAME; - /** Path of the definition file */ - protected static final String CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME = - Activator.getDefault().getStateLocation().addTrailingSeparator().append(CUSTOM_TXT_TRACE_DEFINITIONS_FILE_NAME).toString(); - - /** - * Legacy path to the XML definitions file (in the UI plug-in) TODO Remove - * once we feel the transition phase is over. - */ - private static final String CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME_LEGACY = - Activator.getDefault().getStateLocation().removeLastSegments(1).addTrailingSeparator() - .append("org.eclipse.linuxtools.tmf.ui") //$NON-NLS-1$ - .append(CUSTOM_TXT_TRACE_DEFINITIONS_FILE_NAME).toString(); - - private static final String CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT = Messages.CustomTxtTraceDefinition_definitionRootElement; - private static final String DEFINITION_ELEMENT = Messages.CustomTxtTraceDefinition_definition; - private static final String CATEGORY_ATTRIBUTE = Messages.CustomTxtTraceDefinition_category; - private static final String NAME_ATTRIBUTE = Messages.CustomTxtTraceDefinition_name; - private static final String TIME_STAMP_OUTPUT_FORMAT_ELEMENT = Messages.CustomTxtTraceDefinition_timestampOutputFormat; - private static final String INPUT_LINE_ELEMENT = Messages.CustomTxtTraceDefinition_inputLine; - private static final String CARDINALITY_ELEMENT = Messages.CustomTxtTraceDefinition_cardinality; - private static final String MIN_ATTRIBUTE = Messages.CustomTxtTraceDefinition_min; - private static final String MAX_ATTRIBUTE = Messages.CustomTxtTraceDefinition_max; - private static final String REGEX_ELEMENT = Messages.CustomTxtTraceDefinition_regEx; - private static final String INPUT_DATA_ELEMENT = Messages.CustomTxtTraceDefinition_inputData; - private static final String ACTION_ATTRIBUTE = Messages.CustomTxtTraceDefinition_action; - private static final String FORMAT_ATTRIBUTE = Messages.CustomTxtTraceDefinition_format; - private static final String OUTPUT_COLUMN_ELEMENT = Messages.CustomTxtTraceDefinition_outputColumn; - - /** - * Default constructor. - */ - public CustomTxtTraceDefinition() { - this(TmfTraceType.CUSTOM_TXT_CATEGORY, "", new ArrayList(0), new ArrayList(0), ""); //$NON-NLS-1$ //$NON-NLS-2$ - } - - /** - * Full constructor. - * - * @param traceType - * Name of the trace type - * @param inputs - * List of inputs - * @param outputs - * List of output columns - * @param timeStampOutputFormat - * The timestamp format to use - * @deprecated Use {@link #CustomTxtTraceDefinition(String, String, List, List, String)} - */ - @Deprecated - public CustomTxtTraceDefinition(String traceType, List inputs, - List outputs, String timeStampOutputFormat) { - this.definitionName = traceType; - this.inputs = inputs; - this.outputs = outputs; - this.timeStampOutputFormat = timeStampOutputFormat; - } - - /** - * Full constructor. - * - * @param category - * Category of the trace type - * @param traceType - * Name of the trace type - * @param inputs - * List of inputs - * @param outputs - * List of output columns - * @param timeStampOutputFormat - * The timestamp format to use - * @since 3.2 - */ - public CustomTxtTraceDefinition(String category, String traceType, List inputs, - List outputs, String timeStampOutputFormat) { - this.categoryName = category; - this.definitionName = traceType; - this.inputs = inputs; - this.outputs = outputs; - this.timeStampOutputFormat = timeStampOutputFormat; - } - - /** - * Wrapper to store a line of the log file - */ - public static class InputLine { - - /** Data columns of this line */ - public List columns; - - /** Cardinality of this line (see {@link Cardinality}) */ - public Cardinality cardinality; - - /** Parent line */ - public InputLine parentInput; - - /** Level of this line */ - public int level; - - /** Next input line in the file */ - public InputLine nextInput; - - /** Children of this line (if one "event" spans many lines) */ - public List childrenInputs; - - private String regex; - private Pattern pattern; - - /** - * Default (empty) constructor. - */ - public InputLine() { - } - - /** - * Constructor. - * - * @param cardinality - * Cardinality of this line. - * @param regex - * Regex - * @param columns - * Columns to use - */ - public InputLine(Cardinality cardinality, String regex, List columns) { - this.cardinality = cardinality; - this.regex = regex; - this.columns = columns; - } - - /** - * Set the regex of this input line - * - * @param regex - * Regex to set - */ - public void setRegex(String regex) { - this.regex = regex; - this.pattern = null; - } - - /** - * Get the current regex - * - * @return The current regex - */ - public String getRegex() { - return regex; - } - - /** - * Get the Pattern object of this line's regex - * - * @return The Pattern - * @throws PatternSyntaxException - * If the regex does not parse correctly - */ - public Pattern getPattern() throws PatternSyntaxException { - if (pattern == null) { - pattern = Pattern.compile(regex); - } - return pattern; - } - - /** - * Add a child line to this line. - * - * @param input - * The child input line - */ - public void addChild(InputLine input) { - if (childrenInputs == null) { - childrenInputs = new ArrayList<>(1); - } else if (childrenInputs.size() > 0) { - InputLine last = childrenInputs.get(childrenInputs.size() - 1); - last.nextInput = input; - } - childrenInputs.add(input); - input.parentInput = this; - input.level = this.level + 1; - } - - /** - * Set the next input line. - * - * @param input - * The next input line - */ - public void addNext(InputLine input) { - if (parentInput != null) { - int index = parentInput.childrenInputs.indexOf(this); - parentInput.childrenInputs.add(index + 1, input); - InputLine next = nextInput; - nextInput = input; - input.nextInput = next; - } - input.parentInput = this.parentInput; - input.level = this.level; - } - - /** - * Move this line up in its parent's children. - */ - public void moveUp() { - if (parentInput != null) { - int index = parentInput.childrenInputs.indexOf(this); - if (index > 0) { - parentInput.childrenInputs.add(index - 1, parentInput.childrenInputs.remove(index)); - parentInput.childrenInputs.get(index).nextInput = nextInput; - nextInput = parentInput.childrenInputs.get(index); - } - } - } - - /** - * Move this line down in its parent's children. - */ - public void moveDown() { - if (parentInput != null) { - int index = parentInput.childrenInputs.indexOf(this); - if (index < parentInput.childrenInputs.size() - 1) { - parentInput.childrenInputs.add(index + 1, parentInput.childrenInputs.remove(index)); - nextInput = parentInput.childrenInputs.get(index).nextInput; - parentInput.childrenInputs.get(index).nextInput = this; - } - } - } - - /** - * Add a data column to this line - * - * @param column - * The column to add - */ - public void addColumn(InputData column) { - if (columns == null) { - columns = new ArrayList<>(1); - } - columns.add(column); - } - - /** - * Get the next input lines. - * - * @param countMap - * The map of line "sets". - * @return The next list of lines. - */ - public List getNextInputs(Map countMap) { - List nextInputs = new ArrayList<>(); - InputLine next = nextInput; - while (next != null) { - nextInputs.add(next); - if (next.cardinality.min > 0) { - return nextInputs; - } - next = next.nextInput; - } - if (parentInput != null && parentInput.level > 0) { - int parentCount = countMap.get(parentInput); - if (parentCount < parentInput.getMaxCount()) { - nextInputs.add(parentInput); - } - if (parentCount < parentInput.getMinCount()) { - return nextInputs; - } - nextInputs.addAll(parentInput.getNextInputs(countMap)); - } - return nextInputs; - } - - /** - * Get the minimum possible amount of entries. - * - * @return The minimum - */ - public int getMinCount() { - return cardinality.min; - } - - /** - * Get the maximum possible amount of entries. - * - * @return The maximum - */ - public int getMaxCount() { - return cardinality.max; - } - - @Override - public String toString() { - return regex + " " + cardinality; //$NON-NLS-1$ - } - } - - /** - * Data column for input lines. - */ - public static class InputData { - - /** Name of this column */ - public String name; - - /** Action id */ - public int action; - - /** Format */ - public String format; - - /** - * Default (empty) constructor - */ - public InputData() { - } - - /** - * Full constructor - * - * @param name - * Name - * @param action - * Action - * @param format - * Format - */ - public InputData(String name, int action, String format) { - this.name = name; - this.action = action; - this.format = format; - } - - /** - * Constructor with default format - * - * @param name - * Name - * @param action - * Action - */ - public InputData(String name, int action) { - this.name = name; - this.action = action; - } - } - - /** - * Input line cardinality - */ - public static class Cardinality { - - /** Representation of infinity */ - public final static int INF = Integer.MAX_VALUE; - - /** Preset for [1, 1] */ - public final static Cardinality ONE = new Cardinality(1, 1); - - /** Preset for [1, inf] */ - public final static Cardinality ONE_OR_MORE = new Cardinality(1, INF); - - /** Preset for [0, 1] */ - public final static Cardinality ZERO_OR_ONE = new Cardinality(0, 1); - - /** Preset for [0, inf] */ - public final static Cardinality ZERO_OR_MORE = new Cardinality(0, INF); - - private final int min; - private final int max; - - /** - * Constructor. - * - * @param min - * Minimum - * @param max - * Maximum - */ - public Cardinality(int min, int max) { - this.min = min; - this.max = max; - } - - @Override - public String toString() { - return "(" + (min >= 0 ? min : "?") + ',' + (max == INF ? "\u221E" : (max >= 0 ? max : "?")) + ')'; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + max; - result = prime * result + min; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof Cardinality)) { - return false; - } - Cardinality other = (Cardinality) obj; - return (this.min == other.min && this.max == other.max); - } - } - - @Override - public void save() { - save(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME); - } - - @Override - public void save(String path) { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - - // The following allows xml parsing without access to the dtd - db.setEntityResolver(createEmptyEntityResolver()); - - // The following catches xml parsing exceptions - db.setErrorHandler(createErrorHandler()); - - Document doc = null; - File file = new File(path); - if (file.canRead()) { - doc = db.parse(file); - if (!doc.getDocumentElement().getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT)) { - return; - } - } else { - doc = db.newDocument(); - Node node = doc.createElement(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT); - doc.appendChild(node); - } - - Element root = doc.getDocumentElement(); - - Element oldDefinitionElement = findDefinitionElement(root, categoryName, definitionName); - if (oldDefinitionElement != null) { - root.removeChild(oldDefinitionElement); - } - Element definitionElement = doc.createElement(DEFINITION_ELEMENT); - root.appendChild(definitionElement); - definitionElement.setAttribute(CATEGORY_ATTRIBUTE, categoryName); - definitionElement.setAttribute(NAME_ATTRIBUTE, definitionName); - - Element formatElement = doc.createElement(TIME_STAMP_OUTPUT_FORMAT_ELEMENT); - definitionElement.appendChild(formatElement); - formatElement.appendChild(doc.createTextNode(timeStampOutputFormat)); - - if (inputs != null) { - for (InputLine inputLine : inputs) { - definitionElement.appendChild(createInputLineElement(inputLine, doc)); - } - } - - if (outputs != null) { - for (OutputColumn output : outputs) { - Element outputColumnElement = doc.createElement(OUTPUT_COLUMN_ELEMENT); - definitionElement.appendChild(outputColumnElement); - outputColumnElement.setAttribute(NAME_ATTRIBUTE, output.name); - } - } - - Transformer transformer = TransformerFactory.newInstance().newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ - - // initialize StreamResult with File object to save to file - StreamResult result = new StreamResult(new StringWriter()); - DOMSource source = new DOMSource(doc); - transformer.transform(source, result); - String xmlString = result.getWriter().toString(); - - try (FileWriter writer = new FileWriter(file);) { - writer.write(xmlString); - } - - TmfTraceType.addCustomTraceType(CustomTxtTrace.class, categoryName, definitionName); - - } catch (ParserConfigurationException e) { - Activator.logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ - } catch (TransformerConfigurationException e) { - Activator.logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ - } catch (TransformerFactoryConfigurationError e) { - Activator.logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ - } catch (TransformerException e) { - Activator.logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ - } catch (IOException e) { - Activator.logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ - } catch (SAXException e) { - Activator.logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ - } - } - - private Element createInputLineElement(InputLine inputLine, Document doc) { - Element inputLineElement = doc.createElement(INPUT_LINE_ELEMENT); - - Element cardinalityElement = doc.createElement(CARDINALITY_ELEMENT); - inputLineElement.appendChild(cardinalityElement); - cardinalityElement.setAttribute(MIN_ATTRIBUTE, Integer.toString(inputLine.cardinality.min)); - cardinalityElement.setAttribute(MAX_ATTRIBUTE, Integer.toString(inputLine.cardinality.max)); - - Element regexElement = doc.createElement(REGEX_ELEMENT); - inputLineElement.appendChild(regexElement); - regexElement.appendChild(doc.createTextNode(inputLine.regex)); - - if (inputLine.columns != null) { - for (InputData inputData : inputLine.columns) { - Element inputDataElement = doc.createElement(INPUT_DATA_ELEMENT); - inputLineElement.appendChild(inputDataElement); - inputDataElement.setAttribute(NAME_ATTRIBUTE, inputData.name); - inputDataElement.setAttribute(ACTION_ATTRIBUTE, Integer.toString(inputData.action)); - if (inputData.format != null) { - inputDataElement.setAttribute(FORMAT_ATTRIBUTE, inputData.format); - } - } - } - - if (inputLine.childrenInputs != null) { - for (InputLine childInputLine : inputLine.childrenInputs) { - inputLineElement.appendChild(createInputLineElement(childInputLine, doc)); - } - } - - return inputLineElement; - } - - /** - * Load all custom text trace definitions, including the user-defined and - * default (built-in) parsers. - * - * @return The loaded trace definitions - */ - public static CustomTxtTraceDefinition[] loadAll() { - return loadAll(true); - } - - /** - * Load all custom text trace definitions, including the user-defined and, - * optionally, the default (built-in) parsers. - * - * @param includeDefaults - * if true, the default (built-in) parsers are included - * - * @return The loaded trace definitions - * @since 3.2 - */ - public static CustomTxtTraceDefinition[] loadAll(boolean includeDefaults) { - File defaultFile = new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME); - File legacyFile = new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME_LEGACY); - - /* - * If there is no file at the expected location, check the legacy - * location instead. - */ - if (!defaultFile.exists() && legacyFile.exists()) { - CustomTxtTraceDefinition[] oldDefs = loadAll(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME_LEGACY); - for (CustomTxtTraceDefinition def : oldDefs) { - /* Save in the new location */ - def.save(); - } - } - - Set defs = new TreeSet<>(new Comparator() { - @Override - public int compare(CustomTxtTraceDefinition o1, CustomTxtTraceDefinition o2) { - int result = o1.categoryName.compareTo(o2.categoryName); - if (result != 0) { - return result; - } - return o1.definitionName.compareTo(o2.definitionName); - } - }); - defs.addAll(Arrays.asList(loadAll(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME))); - if (includeDefaults) { - defs.addAll(Arrays.asList(loadAll(CUSTOM_TXT_TRACE_DEFINITIONS_DEFAULT_PATH_NAME))); - } - return defs.toArray(new CustomTxtTraceDefinition[0]); - - } - - /** - * Load a specific text trace definition file. - * - * @param path - * The path to the file to load - * @return The loaded trace definitions - */ - public static CustomTxtTraceDefinition[] loadAll(String path) { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - - // The following allows xml parsing without access to the dtd - db.setEntityResolver(createEmptyEntityResolver()); - - // The following catches xml parsing exceptions - db.setErrorHandler(createErrorHandler()); - - File file = new File(path); - if (!file.canRead()) { - return new CustomTxtTraceDefinition[0]; - } - Document doc = db.parse(file); - - Element root = doc.getDocumentElement(); - if (!root.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT)) { - return new CustomTxtTraceDefinition[0]; - } - - ArrayList defList = new ArrayList<>(); - NodeList nodeList = root.getChildNodes(); - for (int i = 0; i < nodeList.getLength(); i++) { - Node node = nodeList.item(i); - if (node instanceof Element && node.getNodeName().equals(DEFINITION_ELEMENT)) { - CustomTxtTraceDefinition def = extractDefinition((Element) node); - if (def != null) { - defList.add(def); - } - } - } - return defList.toArray(new CustomTxtTraceDefinition[0]); - } catch (ParserConfigurationException e) { - Activator.logError("Error loading all in CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ - } catch (SAXException e) { - Activator.logError("Error loading all in CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ - } catch (IOException e) { - Activator.logError("Error loading all in CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ - } - return new CustomTxtTraceDefinition[0]; - } - - /** - * Load a single definition. - * - * @param definitionName - * Name of the definition to load - * @return The loaded trace definition - * @deprecated Use {@link #load(String, String)} - */ - @Deprecated - public static CustomTxtTraceDefinition load(String definitionName) { - return load(TmfTraceType.CUSTOM_TXT_CATEGORY, definitionName); - } - - /** - * Load a single definition. - * - * @param categoryName - * Category of the definition to load - * @param definitionName - * Name of the definition to load - * @return The loaded trace definition - * @since 3.2 - */ - public static CustomTxtTraceDefinition load(String categoryName, String definitionName) { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - - // The following allows xml parsing without access to the dtd - db.setEntityResolver(createEmptyEntityResolver()); - - // The following catches xml parsing exceptions - db.setErrorHandler(createErrorHandler()); - - CustomTxtTraceDefinition value = lookupDefinition(categoryName, definitionName, db, CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME); - if (value == null) { - return lookupDefinition(categoryName, definitionName, db, CUSTOM_TXT_TRACE_DEFINITIONS_DEFAULT_PATH_NAME); - } - return value; - } catch (ParserConfigurationException | SAXException | IOException e) { - Activator.logError("Error loading CustomTxtTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ - } - return null; - } - - private static CustomTxtTraceDefinition lookupDefinition(String categoryName, String definitionName, DocumentBuilder db, String source) throws SAXException, IOException { - File file = new File(source); - if (!file.exists()) { - return null; - } - Document doc = db.parse(file); - - Element root = doc.getDocumentElement(); - if (!root.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT)) { - return null; - } - - Element definitionElement = findDefinitionElement(root, categoryName, definitionName); - if (definitionElement != null) { - return extractDefinition(definitionElement); - } - return null; - } - - private static Element findDefinitionElement(Element root, String categoryName, String definitionName) { - NodeList nodeList = root.getChildNodes(); - for (int i = 0; i < nodeList.getLength(); i++) { - Node node = nodeList.item(i); - if (node instanceof Element && node.getNodeName().equals(DEFINITION_ELEMENT)) { - Element element = (Element) node; - String categoryAttribute = element.getAttribute(CATEGORY_ATTRIBUTE); - if (categoryAttribute.isEmpty()) { - categoryAttribute = TmfTraceType.CUSTOM_TXT_CATEGORY; - } - String nameAttribute = element.getAttribute(NAME_ATTRIBUTE); - if (categoryName.equals(categoryAttribute) && - definitionName.equals(nameAttribute)) { - return element; - } - } - } - return null; - } - - /** - * Get the definition from a definition element. - * - * @param definitionElement - * The Element to extract from - * @return The loaded trace definition - */ - public static CustomTxtTraceDefinition extractDefinition(Element definitionElement) { - CustomTxtTraceDefinition def = new CustomTxtTraceDefinition(); - - def.categoryName = definitionElement.getAttribute(CATEGORY_ATTRIBUTE); - if (def.categoryName.isEmpty()) { - def.categoryName = TmfTraceType.CUSTOM_TXT_CATEGORY; - } - def.definitionName = definitionElement.getAttribute(NAME_ATTRIBUTE); - if (def.definitionName.isEmpty()) { - return null; - } - - NodeList nodeList = definitionElement.getChildNodes(); - for (int i = 0; i < nodeList.getLength(); i++) { - Node node = nodeList.item(i); - String nodeName = node.getNodeName(); - if (nodeName.equals(TIME_STAMP_OUTPUT_FORMAT_ELEMENT)) { - Element formatElement = (Element) node; - def.timeStampOutputFormat = formatElement.getTextContent(); - } else if (nodeName.equals(INPUT_LINE_ELEMENT)) { - InputLine inputLine = extractInputLine((Element) node); - if (inputLine != null) { - def.inputs.add(inputLine); - } - } else if (nodeName.equals(OUTPUT_COLUMN_ELEMENT)) { - Element outputColumnElement = (Element) node; - OutputColumn outputColumn = new OutputColumn(); - outputColumn.name = outputColumnElement.getAttribute(NAME_ATTRIBUTE); - def.outputs.add(outputColumn); - } - } - return def; - } - - private static InputLine extractInputLine(Element inputLineElement) { - InputLine inputLine = new InputLine(); - NodeList nodeList = inputLineElement.getChildNodes(); - for (int i = 0; i < nodeList.getLength(); i++) { - Node node = nodeList.item(i); - String nodeName = node.getNodeName(); - if (nodeName.equals(CARDINALITY_ELEMENT)) { - Element cardinalityElement = (Element) node; - try { - int min = Integer.parseInt(cardinalityElement.getAttribute(MIN_ATTRIBUTE)); - int max = Integer.parseInt(cardinalityElement.getAttribute(MAX_ATTRIBUTE)); - inputLine.cardinality = new Cardinality(min, max); - } catch (NumberFormatException e) { - return null; - } - } else if (nodeName.equals(REGEX_ELEMENT)) { - Element regexElement = (Element) node; - inputLine.regex = regexElement.getTextContent(); - } else if (nodeName.equals(INPUT_DATA_ELEMENT)) { - Element inputDataElement = (Element) node; - InputData inputData = new InputData(); - inputData.name = inputDataElement.getAttribute(NAME_ATTRIBUTE); - inputData.action = Integer.parseInt(inputDataElement.getAttribute(ACTION_ATTRIBUTE)); - inputData.format = inputDataElement.getAttribute(FORMAT_ATTRIBUTE); - inputLine.addColumn(inputData); - } else if (nodeName.equals(INPUT_LINE_ELEMENT)) { - Element childInputLineElement = (Element) node; - InputLine childInputLine = extractInputLine(childInputLineElement); - if (childInputLine != null) { - inputLine.addChild(childInputLine); - } - } - } - return inputLine; - } - - /** - * Delete a definition from the currently loaded ones. - * - * @param definitionName - * The name of the definition to delete - * @deprecated Use {@link #delete(String, String)} - */ - @Deprecated - public static void delete(String definitionName) { - delete(TmfTraceType.CUSTOM_TXT_CATEGORY, definitionName); - } - - /** - * Delete a definition from the currently loaded ones. - * - * @param categoryName - * The category of the definition to delete - * @param definitionName - * The name of the definition to delete - * @since 3.2 - */ - public static void delete(String categoryName, String definitionName) { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - - // The following allows xml parsing without access to the dtd - db.setEntityResolver(createEmptyEntityResolver()); - - // The following catches xml parsing exceptions - db.setErrorHandler(createErrorHandler()); - - File file = new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME); - Document doc = db.parse(file); - - Element root = doc.getDocumentElement(); - if (!root.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT)) { - return; - } - - Element definitionElement = findDefinitionElement(root, categoryName, definitionName); - if (definitionElement != null) { - root.removeChild(definitionElement); - } - - Transformer transformer = TransformerFactory.newInstance().newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ - - // initialize StreamResult with File object to save to file - StreamResult result = new StreamResult(new StringWriter()); - DOMSource source = new DOMSource(doc); - transformer.transform(source, result); - String xmlString = result.getWriter().toString(); - - try (FileWriter writer = new FileWriter(file);) { - writer.write(xmlString); - } - - TmfTraceType.removeCustomTraceType(CustomTxtTrace.class, categoryName, definitionName); - // Check if default definition needs to be reloaded - TmfTraceType.addCustomTraceType(CustomTxtTrace.class, categoryName, definitionName); - - } catch (ParserConfigurationException | SAXException | IOException | TransformerFactoryConfigurationError | TransformerException e) { - Activator.logError("Error deleting CustomTxtTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlEvent.java deleted file mode 100644 index 0a23b3766d..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlEvent.java +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.parsers.custom; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Trace event for custom XML traces. - * - * @author Patrick Tassé - * @since 3.0 - */ -public class CustomXmlEvent extends CustomEvent { - - /** - * Constructor defining only the trace definition - * - * @param definition - * Trace definition - */ - public CustomXmlEvent(CustomXmlTraceDefinition definition) { - super(definition); - setType(new CustomXmlEventType(definition)); - } - - /** - * Build a custom trace event from an existing TmfEvent. - * - * @param definition - * Trace definition - * @param other - * Other TmfEvent to copy - */ - public CustomXmlEvent(CustomXmlTraceDefinition definition, TmfEvent other) { - super(definition, other); - } - - /** - * Full constructor - * - * @param definition - * Trace definition - * @param parentTrace - * Parent trace object - * @param timestamp - * Timestamp of the event - * @param source - * Source of the event - * @param type - * Event type - * @param reference - * Reference of the event - */ - public CustomXmlEvent(CustomXmlTraceDefinition definition, ITmfTrace parentTrace, ITmfTimestamp timestamp, String source, TmfEventType type, String reference) { - super(definition, parentTrace, timestamp, source, type, reference); - } - - @Override - public void setContent(ITmfEventField content) { - super.setContent(content); - } - - /** - * Parse an entry. - * - * @param value Value - * @param name Name - * @param inputAction Input action - * @param inputFormat Input format - */ - public void parseInput(String value, String name, int inputAction, String inputFormat) { - if (value.length() == 0) { - return; - } - if (inputAction == CustomTraceDefinition.ACTION_SET) { - fData.put(name, value); - if (name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - fData.put(TIMESTAMP_INPUT_FORMAT_KEY, inputFormat); - } - } else if (inputAction == CustomTraceDefinition.ACTION_APPEND) { - String s = fData.get(name); - if (s != null) { - fData.put(name, s + value); - } else { - fData.put(name, value); - } - if (name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - String timeStampInputFormat = fData.get(TIMESTAMP_INPUT_FORMAT_KEY); - if (timeStampInputFormat != null) { - fData.put(TIMESTAMP_INPUT_FORMAT_KEY, timeStampInputFormat + inputFormat); - } else { - fData.put(TIMESTAMP_INPUT_FORMAT_KEY, inputFormat); - } - } - } else if (inputAction == CustomTraceDefinition.ACTION_APPEND_WITH_SEPARATOR) { - String s = fData.get(name); - if (s != null) { - fData.put(name, s + " | " + value); //$NON-NLS-1$ - } else { - fData.put(name, value); - } - if (name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - String timeStampInputFormat = fData.get(TIMESTAMP_INPUT_FORMAT_KEY); - if (timeStampInputFormat != null) { - fData.put(TIMESTAMP_INPUT_FORMAT_KEY, timeStampInputFormat + " | " + inputFormat); //$NON-NLS-1$ - } else { - fData.put(TIMESTAMP_INPUT_FORMAT_KEY, inputFormat); - } - } - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlEventType.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlEventType.java deleted file mode 100644 index 3757b62283..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlEventType.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.parsers.custom; - -/** - * Event type class for custom XML traces. - * - * @author Patrick Tassé - * @since 3.0 - */ -public class CustomXmlEventType extends CustomEventType { - - /** - * Constructor - * - * @param definition - * Trace definition - */ - public CustomXmlEventType(CustomXmlTraceDefinition definition) { - super(definition); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlTrace.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlTrace.java deleted file mode 100644 index c6a333de18..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlTrace.java +++ /dev/null @@ -1,585 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.parsers.custom; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.io.BufferedRandomAccessFile; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition.InputAttribute; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition.InputElement; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser; -import org.eclipse.linuxtools.tmf.core.trace.TmfContext; -import org.eclipse.linuxtools.tmf.core.trace.TmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TraceValidationStatus; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfPersistentlyIndexable; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.indexer.TmfBTreeTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.EntityResolver; -import org.xml.sax.ErrorHandler; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -/** - * Trace object for custom XML trace parsers. - * - * @author Patrick Tassé - * @since 3.0 - */ -public class CustomXmlTrace extends TmfTrace implements ITmfEventParser, ITmfPersistentlyIndexable { - - private static final TmfLongLocation NULL_LOCATION = new TmfLongLocation(-1L); - private static final int DEFAULT_CACHE_SIZE = 100; - private static final int MAX_LINES = 100; - private static final int CONFIDENCE = 100; - - private final CustomXmlTraceDefinition fDefinition; - private final CustomXmlEventType fEventType; - private final InputElement fRecordInputElement; - private BufferedRandomAccessFile fFile; - - /** - * Basic constructor - * - * @param definition - * Trace definition - */ - public CustomXmlTrace(final CustomXmlTraceDefinition definition) { - fDefinition = definition; - fEventType = new CustomXmlEventType(fDefinition); - fRecordInputElement = getRecordInputElement(fDefinition.rootInputElement); - setCacheSize(DEFAULT_CACHE_SIZE); - } - - /** - * Full constructor - * - * @param resource - * Trace resource - * @param definition - * Trace definition - * @param path - * Path to the trace/log file - * @param pageSize - * Page size to use - * @throws TmfTraceException - * If the trace/log couldn't be opened - */ - public CustomXmlTrace(final IResource resource, - final CustomXmlTraceDefinition definition, final String path, - final int pageSize) throws TmfTraceException { - this(definition); - setCacheSize((pageSize > 0) ? pageSize : DEFAULT_CACHE_SIZE); - initTrace(resource, path, CustomXmlEvent.class); - } - - @Override - public void initTrace(final IResource resource, final String path, final Class eventType) throws TmfTraceException { - super.initTrace(resource, path, eventType); - try { - fFile = new BufferedRandomAccessFile(getPath(), "r"); //$NON-NLS-1$ - } catch (IOException e) { - throw new TmfTraceException(e.getMessage(), e); - } - } - - @Override - public synchronized void dispose() { - super.dispose(); - if (fFile != null) { - try { - fFile.close(); - } catch (IOException e) { - } finally { - fFile = null; - } - } - } - - @Override - public ITmfTraceIndexer getIndexer() { - return super.getIndexer(); - } - - @Override - public synchronized TmfContext seekEvent(final ITmfLocation location) { - final CustomXmlTraceContext context = new CustomXmlTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK); - if (NULL_LOCATION.equals(location) || fFile == null) { - return context; - } - try { - if (location == null) { - fFile.seek(0); - } else if (location.getLocationInfo() instanceof Long) { - fFile.seek((Long) location.getLocationInfo()); - } - long rawPos = fFile.getFilePointer(); - String line = fFile.getNextLine(); - while (line != null) { - final int idx = indexOfElement(fRecordInputElement.elementName, line, 0); - if (idx != -1) { - context.setLocation(new TmfLongLocation(rawPos + idx)); - return context; - } - rawPos = fFile.getFilePointer(); - line = fFile.getNextLine(); - } - return context; - } catch (final IOException e) { - Activator.logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$ - return context; - } - - } - - @Override - public synchronized TmfContext seekEvent(final double ratio) { - if (fFile == null) { - return new CustomTxtTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK); - } - try { - long pos = Math.round(ratio * fFile.length()); - while (pos > 0) { - fFile.seek(pos - 1); - if (fFile.read() == '\n') { - break; - } - pos--; - } - final ITmfLocation location = new TmfLongLocation(pos); - final TmfContext context = seekEvent(location); - context.setRank(ITmfContext.UNKNOWN_RANK); - return context; - } catch (final IOException e) { - Activator.logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$ - return new CustomXmlTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK); - } - } - - @Override - public synchronized double getLocationRatio(final ITmfLocation location) { - if (fFile == null) { - return 0; - } - try { - if (location.getLocationInfo() instanceof Long) { - return ((Long) location.getLocationInfo()).doubleValue() / fFile.length(); - } - } catch (final IOException e) { - Activator.logError("Error getting location ration. File: " + getPath(), e); //$NON-NLS-1$ - } - return 0; - } - - @Override - public ITmfLocation getCurrentLocation() { - // TODO Auto-generated method stub - return null; - } - - @Override - public synchronized CustomXmlEvent parseEvent(final ITmfContext tmfContext) { - ITmfContext context = seekEvent(tmfContext.getLocation()); - return parse(context); - } - - @Override - public synchronized CustomXmlEvent getNext(final ITmfContext context) { - final ITmfContext savedContext = new TmfContext(context.getLocation(), context.getRank()); - final CustomXmlEvent event = parse(context); - if (event != null) { - updateAttributes(savedContext, event.getTimestamp()); - context.increaseRank(); - } - return event; - } - - private synchronized CustomXmlEvent parse(final ITmfContext tmfContext) { - if (fFile == null) { - return null; - } - if (!(tmfContext instanceof CustomXmlTraceContext)) { - return null; - } - - final CustomXmlTraceContext context = (CustomXmlTraceContext) tmfContext; - if (context.getLocation() == null || !(context.getLocation().getLocationInfo() instanceof Long) || NULL_LOCATION.equals(context.getLocation())) { - return null; - } - - CustomXmlEvent event = null; - try { - if (fFile.getFilePointer() != (Long) context.getLocation().getLocationInfo() + 1) - { - fFile.seek((Long) context.getLocation().getLocationInfo() + 1); // +1 is for the < - } - final StringBuffer elementBuffer = new StringBuffer("<"); //$NON-NLS-1$ - readElement(elementBuffer, fFile); - final Element element = parseElementBuffer(elementBuffer); - - event = extractEvent(element, fRecordInputElement); - ((StringBuffer) event.getContent().getValue()).append(elementBuffer); - - long rawPos = fFile.getFilePointer(); - String line = fFile.getNextLine(); - while (line != null) { - final int idx = indexOfElement(fRecordInputElement.elementName, line, 0); - if (idx != -1) { - context.setLocation(new TmfLongLocation(rawPos + idx)); - return event; - } - rawPos = fFile.getFilePointer(); - line = fFile.getNextLine(); - } - } catch (final IOException e) { - Activator.logError("Error parsing event. File: " + getPath(), e); //$NON-NLS-1$ - - } - context.setLocation(NULL_LOCATION); - return event; - } - - private Element parseElementBuffer(final StringBuffer elementBuffer) { - try { - final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - final DocumentBuilder db = dbf.newDocumentBuilder(); - - // The following allows xml parsing without access to the dtd - final EntityResolver resolver = new EntityResolver() { - @Override - public InputSource resolveEntity(final String publicId, final String systemId) { - final String empty = ""; //$NON-NLS-1$ - final ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); - return new InputSource(bais); - } - }; - db.setEntityResolver(resolver); - - // The following catches xml parsing exceptions - db.setErrorHandler(new ErrorHandler() { - @Override - public void error(final SAXParseException saxparseexception) throws SAXException {} - - @Override - public void warning(final SAXParseException saxparseexception) throws SAXException {} - - @Override - public void fatalError(final SAXParseException saxparseexception) throws SAXException { - throw saxparseexception; - } - }); - - final Document doc = db.parse(new ByteArrayInputStream(elementBuffer.toString().getBytes())); - return doc.getDocumentElement(); - } catch (final ParserConfigurationException e) { - Activator.logError("Error parsing element buffer. File:" + getPath(), e); //$NON-NLS-1$ - } catch (final SAXException e) { - Activator.logError("Error parsing element buffer. File:" + getPath(), e); //$NON-NLS-1$ - } catch (final IOException e) { - Activator.logError("Error parsing element buffer. File: " + getPath(), e); //$NON-NLS-1$ - } - return null; - } - - private static int indexOfElement(String elementName, String line, int fromIndex) { - final String recordElementStart = '<' + elementName; - int index = line.indexOf(recordElementStart, fromIndex); - if (index == -1) { - return index; - } - int nextCharIndex = index + recordElementStart.length(); - if (nextCharIndex < line.length()) { - char c = line.charAt(nextCharIndex); - // Check that the match is not just a substring of another element - if (Character.isLetterOrDigit(c)) { - return indexOfElement(elementName, line, nextCharIndex); - } - } - return index; - } - - private void readElement(final StringBuffer buffer, final RandomAccessFile raFile) { - try { - int numRead = 0; - boolean startTagClosed = false; - int i; - while ((i = raFile.read()) != -1) { - numRead++; - final char c = (char) i; - buffer.append(c); - if (c == '"') { - readQuote(buffer, raFile, '"'); - } else if (c == '\'') { - readQuote(buffer, raFile, '\''); - } else if (c == '<') { - readElement(buffer, raFile); - } else if (c == '/' && numRead == 1) { - break; // found "') { - if (buffer.charAt(buffer.length() - 2) == '/') { - break; // found "/>" - } else if (startTagClosed) { - break; // found "<...>..." - } - else { - startTagClosed = true; // found "<...>" - } - } - } - return; - } catch (final IOException e) { - return; - } - } - - private static void readQuote(final StringBuffer buffer, - final RandomAccessFile raFile, final char eq) { - try { - int i; - while ((i = raFile.read()) != -1) { - final char c = (char) i; - buffer.append(c); - if (c == eq) - { - break; // found matching end-quote - } - } - return; - } catch (final IOException e) { - return; - } - } - - private static void readComment(final StringBuffer buffer, - final RandomAccessFile raFile) { - try { - int numRead = 0; - int i; - while ((i = raFile.read()) != -1) { - numRead++; - final char c = (char) i; - buffer.append(c); - if (c == '>' && numRead >= 2 && buffer.substring(buffer.length() - 3, buffer.length() - 1).equals("--")) //$NON-NLS-1$ - { - break; // found "-->" - } - } - return; - } catch (final IOException e) { - return; - } - } - - /** - * Parse an XML element. - * - * @param parentElement - * The parent element - * @param buffer - * The contents to parse - * @return The parsed content - */ - public static StringBuffer parseElement(final Element parentElement, final StringBuffer buffer) { - final NodeList nodeList = parentElement.getChildNodes(); - String separator = null; - for (int i = 0; i < nodeList.getLength(); i++) { - final Node node = nodeList.item(i); - if (node.getNodeType() == Node.ELEMENT_NODE) { - if (separator == null) { - separator = " | "; //$NON-NLS-1$ - } else { - buffer.append(separator); - } - final Element element = (Element) node; - if (!element.hasChildNodes()) { - buffer.append(element.getNodeName()); - } else if (element.getChildNodes().getLength() == 1 && element.getFirstChild().getNodeType() == Node.TEXT_NODE) { - buffer.append(element.getNodeName() + ":" + element.getFirstChild().getNodeValue().trim()); //$NON-NLS-1$ - } else { - buffer.append(element.getNodeName()); - buffer.append(" [ "); //$NON-NLS-1$ - parseElement(element, buffer); - buffer.append(" ]"); //$NON-NLS-1$ - } - } else if (node.getNodeType() == Node.TEXT_NODE) { - if (node.getNodeValue().trim().length() != 0) { - buffer.append(node.getNodeValue().trim()); - } - } - } - return buffer; - } - - /** - * Get an input element if it is a valid record input. If not, we will look - * into its children for valid inputs. - * - * @param inputElement - * The main element to check for. - * @return The record element - */ - public InputElement getRecordInputElement(final InputElement inputElement) { - if (inputElement.logEntry) { - return inputElement; - } else if (inputElement.childElements != null) { - for (final InputElement childInputElement : inputElement.childElements) { - final InputElement recordInputElement = getRecordInputElement(childInputElement); - if (recordInputElement != null) { - return recordInputElement; - } - } - } - return null; - } - - /** - * Extract a trace event from an XML element. - * - * @param element - * The element - * @param inputElement - * The input element - * @return The extracted event - */ - public CustomXmlEvent extractEvent(final Element element, final InputElement inputElement) { - final CustomXmlEvent event = new CustomXmlEvent(fDefinition, this, TmfTimestamp.ZERO, "", fEventType, ""); //$NON-NLS-1$ //$NON-NLS-2$ - event.setContent(new CustomEventContent(event, new StringBuffer())); - parseElement(element, event, inputElement); - return event; - } - - private void parseElement(final Element element, final CustomXmlEvent event, final InputElement inputElement) { - if (inputElement.inputName != null && !inputElement.inputName.equals(CustomXmlTraceDefinition.TAG_IGNORE)) { - event.parseInput(parseElement(element, new StringBuffer()).toString(), inputElement.inputName, inputElement.inputAction, inputElement.inputFormat); - } - if (inputElement.attributes != null) { - for (final InputAttribute attribute : inputElement.attributes) { - event.parseInput(element.getAttribute(attribute.attributeName), attribute.inputName, attribute.inputAction, attribute.inputFormat); - } - } - final NodeList childNodes = element.getChildNodes(); - if (inputElement.childElements != null) { - for (int i = 0; i < childNodes.getLength(); i++) { - final Node node = childNodes.item(i); - if (node instanceof Element) { - for (final InputElement child : inputElement.childElements) { - if (node.getNodeName().equals(child.elementName)) { - parseElement((Element) node, event, child); - break; - } - } - } - } - } - return; - } - - /** - * Retrieve the trace definition. - * - * @return The trace definition - */ - public CustomTraceDefinition getDefinition() { - return fDefinition; - } - - /** - * {@inheritDoc} - *

- * The default implementation sets the confidence to 100 if any of the first - * 100 lines of the file contains a valid record input element, and 0 - * otherwise. - */ - @Override - public IStatus validate(IProject project, String path) { - File file = new File(path); - if (!file.exists() || !file.isFile() || !file.canRead()) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CustomTrace_FileNotFound + ": " + path); //$NON-NLS-1$ - } - try (BufferedRandomAccessFile rafile = new BufferedRandomAccessFile(path, "r")) { //$NON-NLS-1$ - int lineCount = 0; - long rawPos = 0; - String line = rafile.getNextLine(); - while ((line != null) && (lineCount++ < MAX_LINES)) { - final int idx = indexOfElement(fRecordInputElement.elementName, line, 0); - if (idx != -1) { - rafile.seek(rawPos + idx + 1); // +1 is for the < - final StringBuffer elementBuffer = new StringBuffer("<"); //$NON-NLS-1$ - readElement(elementBuffer, rafile); - final Element element = parseElementBuffer(elementBuffer); - if (element != null) { - rafile.close(); - return new TraceValidationStatus(CONFIDENCE, Activator.PLUGIN_ID); - } - } - rawPos = rafile.getFilePointer(); - line = rafile.getNextLine(); - } - } catch (IOException e) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "IOException validating file: " + path, e); //$NON-NLS-1$ - } - return new TraceValidationStatus(0, Activator.PLUGIN_ID); - } - - private static int fCheckpointSize = -1; - - @Override - public synchronized int getCheckpointSize() { - if (fCheckpointSize == -1) { - TmfCheckpoint c = new TmfCheckpoint(TmfTimestamp.ZERO, new TmfLongLocation(0L), 0); - ByteBuffer b = ByteBuffer.allocate(ITmfCheckpoint.MAX_SERIALIZE_SIZE); - b.clear(); - c.serialize(b); - fCheckpointSize = b.position(); - } - - return fCheckpointSize; - } - - @Override - public ITmfLocation restoreLocation(ByteBuffer bufferIn) { - return new TmfLongLocation(bufferIn); - } - - @Override - protected ITmfTraceIndexer createIndexer(int interval) { - return new TmfBTreeTraceIndexer(this, interval); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlTraceContext.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlTraceContext.java deleted file mode 100644 index ec86422ab3..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlTraceContext.java +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.parsers.custom; - -import org.eclipse.linuxtools.tmf.core.trace.TmfContext; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - -/** - * Trace context for custom XML traces. - * - * @author Patrick Tassé - * @since 3.0 - */ -public class CustomXmlTraceContext extends TmfContext { - - /** - * Constructor - * - * @param location - * The location (in the file) of this context - * @param rank - * The rank of the event pointed by this context - */ - public CustomXmlTraceContext(ITmfLocation location, long rank) { - super(location, rank); - } - - @Override - public int hashCode() { - return super.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof CustomXmlTraceContext)) { - return false; - } - return true; - } - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlTraceDefinition.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlTraceDefinition.java deleted file mode 100644 index d2df6bf590..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlTraceDefinition.java +++ /dev/null @@ -1,858 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Matthew Khouzam - Add support for default xml parsers - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.parsers.custom; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.eclipse.core.runtime.Platform; -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.EntityResolver; -import org.xml.sax.ErrorHandler; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -/** - * Trace definition for custom XML traces. - * - * @author Patrick Tassé - * @since 3.0 - */ -public class CustomXmlTraceDefinition extends CustomTraceDefinition { - - /** "ignore" tag */ - public static final String TAG_IGNORE = Messages.CustomXmlTraceDefinition_ignoreTag; - - /** Name of the default XML definitions file */ - protected static final String CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_FILE_NAME = "custom_xml_default_parsers.xml"; //$NON-NLS-1$ - - /** Name of the XML definitions file */ - protected static final String CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME = "custom_xml_parsers.xml"; //$NON-NLS-1$ - - /** Path to the XML definitions file */ - protected static final String CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME = - Platform.getInstallLocation().getURL().getPath() + "templates/org.eclipse.linuxtools.tmf.core/" + //$NON-NLS-1$ - CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_FILE_NAME; - - /** Path to the XML definitions file */ - protected static final String CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME = - Activator.getDefault().getStateLocation().addTrailingSeparator().append(CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME).toString(); - - /** - * Legacy path to the XML definitions file (in the UI plug-in) TODO Remove - * once we feel the transition phase is over. - */ - private static final String CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY = - Activator.getDefault().getStateLocation().removeLastSegments(1).addTrailingSeparator() - .append("org.eclipse.linuxtools.tmf.ui") //$NON-NLS-1$ - .append(CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME).toString(); - - // TODO: These strings should not be externalized - private static final String CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT = Messages.CustomXmlTraceDefinition_definitionRootElement; - private static final String DEFINITION_ELEMENT = Messages.CustomXmlTraceDefinition_definition; - private static final String CATEGORY_ATTRIBUTE = Messages.CustomXmlTraceDefinition_category; - private static final String NAME_ATTRIBUTE = Messages.CustomXmlTraceDefinition_name; - private static final String LOG_ENTRY_ATTRIBUTE = Messages.CustomXmlTraceDefinition_logEntry; - private static final String TIME_STAMP_OUTPUT_FORMAT_ELEMENT = Messages.CustomXmlTraceDefinition_timestampOutputFormat; - private static final String INPUT_ELEMENT_ELEMENT = Messages.CustomXmlTraceDefinition_inputElement; - private static final String ATTRIBUTE_ELEMENT = Messages.CustomXmlTraceDefinition_attribute; - private static final String INPUT_DATA_ELEMENT = Messages.CustomXmlTraceDefinition_inputData; - private static final String ACTION_ATTRIBUTE = Messages.CustomXmlTraceDefinition_action; - private static final String FORMAT_ATTRIBUTE = Messages.CustomXmlTraceDefinition_format; - private static final String OUTPUT_COLUMN_ELEMENT = Messages.CustomXmlTraceDefinition_outputColumn; - - /** Top-level input element */ - public InputElement rootInputElement; - - /** - * Default constructor - */ - public CustomXmlTraceDefinition() { - this(TmfTraceType.CUSTOM_XML_CATEGORY, "", null, new ArrayList(), ""); //$NON-NLS-1$ //$NON-NLS-2$ - } - - /** - * Full constructor - * - * @param traceType - * Name of the trace type - * @param rootElement - * The top-level XML element - * @param outputs - * The list of output columns - * @param timeStampOutputFormat - * The timestamp format to use - * @deprecated Use {@link #CustomXmlTraceDefinition(String, String, InputElement, List, String)} - */ - @Deprecated - public CustomXmlTraceDefinition(String traceType, InputElement rootElement, - List outputs, String timeStampOutputFormat) { - this.definitionName = traceType; - this.rootInputElement = rootElement; - this.outputs = outputs; - this.timeStampOutputFormat = timeStampOutputFormat; - } - - /** - * Full constructor - * - * @param category - * Category of the trace type - * @param traceType - * Name of the trace type - * @param rootElement - * The top-level XML element - * @param outputs - * The list of output columns - * @param timeStampOutputFormat - * The timestamp format to use - * @since 3.2 - */ - public CustomXmlTraceDefinition(String category, String traceType, InputElement rootElement, - List outputs, String timeStampOutputFormat) { - this.categoryName = category; - this.definitionName = traceType; - this.rootInputElement = rootElement; - this.outputs = outputs; - this.timeStampOutputFormat = timeStampOutputFormat; - } - - /** - * Wrapper for input XML elements - */ - public static class InputElement { - - /** Name of the element */ - public String elementName; - - /** Indicates if this is a log entry */ - public boolean logEntry; - - /** Name of the input element */ - public String inputName; - - /** Input action */ - public int inputAction; - - /** Input format */ - public String inputFormat; - - /** XML attributes of this element */ - public List attributes; - - /** Parent element */ - public InputElement parentElement; - - /** Following element in the file */ - public InputElement nextElement; - - /** Child elements */ - public List childElements; - - /** - * Default (empty) constructor - */ - public InputElement() { - } - - /** - * Constructor - * - * @param elementName - * Element name - * @param logEntry - * If this element is a log entry - * @param inputName - * Name of the the input - * @param inputAction - * Input action - * @param inputFormat - * Input format - * @param attributes - * XML attributes of this element - */ - public InputElement(String elementName, boolean logEntry, - String inputName, int inputAction, String inputFormat, - List attributes) { - this.elementName = elementName; - this.logEntry = logEntry; - this.inputName = inputName; - this.inputAction = inputAction; - this.inputFormat = inputFormat; - this.attributes = attributes; - } - - /** - * Add a XML attribute to the element - * - * @param attribute - * The attribute to add - */ - public void addAttribute(InputAttribute attribute) { - if (attributes == null) { - attributes = new ArrayList<>(1); - } - attributes.add(attribute); - } - - /** - * Add a child element to this one. - * - * @param input - * The input element to add as child - */ - public void addChild(InputElement input) { - if (childElements == null) { - childElements = new ArrayList<>(1); - } else if (childElements.size() > 0) { - InputElement last = childElements.get(childElements.size() - 1); - last.nextElement = input; - } - childElements.add(input); - input.parentElement = this; - } - - /** - * Set the following input element. - * - * @param input - * The input element to add as next element - */ - public void addNext(InputElement input) { - if (parentElement != null) { - int index = parentElement.childElements.indexOf(this); - parentElement.childElements.add(index + 1, input); - InputElement next = nextElement; - nextElement = input; - input.nextElement = next; - } - input.parentElement = this.parentElement; - } - - /** - * Move this element up in its parent's list of children. - */ - public void moveUp() { - if (parentElement != null) { - int index = parentElement.childElements.indexOf(this); - if (index > 0) { - parentElement.childElements.add(index - 1, parentElement.childElements.remove(index)); - parentElement.childElements.get(index).nextElement = nextElement; - nextElement = parentElement.childElements.get(index); - } - } - } - - /** - * Move this element down in its parent's list of children. - */ - public void moveDown() { - if (parentElement != null) { - int index = parentElement.childElements.indexOf(this); - if (index < parentElement.childElements.size() - 1) { - parentElement.childElements.add(index + 1, parentElement.childElements.remove(index)); - nextElement = parentElement.childElements.get(index).nextElement; - parentElement.childElements.get(index).nextElement = this; - } - } - } - - } - - /** - * Wrapper for XML element attributes - */ - public static class InputAttribute { - - /** Name of the XML attribute */ - public String attributeName; - - /** Input name */ - public String inputName; - - /** Input action */ - public int inputAction; - - /** Input format */ - public String inputFormat; - - /** - * Default (empty) constructor - */ - public InputAttribute() { - } - - /** - * Constructor - * - * @param attributeName - * Name of the XML attribute - * @param inputName - * Input name - * @param inputAction - * Input action - * @param inputFormat - * Input format - */ - public InputAttribute(String attributeName, String inputName, - int inputAction, String inputFormat) { - this.attributeName = attributeName; - this.inputName = inputName; - this.inputAction = inputAction; - this.inputFormat = inputFormat; - } - } - - @Override - public void save() { - save(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME); - } - - @Override - public void save(String path) { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - - // The following allows xml parsing without access to the dtd - db.setEntityResolver(createEmptyEntityResolver()); - - // The following catches xml parsing exceptions - db.setErrorHandler(createErrorHandler()); - - Document doc = null; - File file = new File(path); - if (file.canRead()) { - doc = db.parse(file); - if (!doc.getDocumentElement().getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) { - return; - } - } else { - doc = db.newDocument(); - Node node = doc.createElement(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT); - doc.appendChild(node); - } - - Element root = doc.getDocumentElement(); - - Element oldDefinitionElement = findDefinitionElement(root, categoryName, definitionName); - if (oldDefinitionElement != null) { - root.removeChild(oldDefinitionElement); - } - Element definitionElement = doc.createElement(DEFINITION_ELEMENT); - root.appendChild(definitionElement); - definitionElement.setAttribute(CATEGORY_ATTRIBUTE, categoryName); - definitionElement.setAttribute(NAME_ATTRIBUTE, definitionName); - - Element formatElement = doc.createElement(TIME_STAMP_OUTPUT_FORMAT_ELEMENT); - definitionElement.appendChild(formatElement); - formatElement.appendChild(doc.createTextNode(timeStampOutputFormat)); - - if (rootInputElement != null) { - definitionElement.appendChild(createInputElementElement(rootInputElement, doc)); - } - - if (outputs != null) { - for (OutputColumn output : outputs) { - Element outputColumnElement = doc.createElement(OUTPUT_COLUMN_ELEMENT); - definitionElement.appendChild(outputColumnElement); - outputColumnElement.setAttribute(NAME_ATTRIBUTE, output.name); - } - } - - Transformer transformer = TransformerFactory.newInstance().newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ - - // initialize StreamResult with File object to save to file - StreamResult result = new StreamResult(new StringWriter()); - DOMSource source = new DOMSource(doc); - transformer.transform(source, result); - String xmlString = result.getWriter().toString(); - - try (FileWriter writer = new FileWriter(file);) { - writer.write(xmlString); - } - - TmfTraceType.addCustomTraceType(CustomXmlTrace.class, categoryName, definitionName); - - } catch (ParserConfigurationException | TransformerFactoryConfigurationError | TransformerException | IOException | SAXException e) { - Activator.logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$ - } - } - - private Element createInputElementElement(InputElement inputElement, Document doc) { - Element inputElementElement = doc.createElement(INPUT_ELEMENT_ELEMENT); - inputElementElement.setAttribute(NAME_ATTRIBUTE, inputElement.elementName); - - if (inputElement.logEntry) { - inputElementElement.setAttribute(LOG_ENTRY_ATTRIBUTE, Boolean.toString(inputElement.logEntry)); - } - - if (inputElement.parentElement != null) { - Element inputDataElement = doc.createElement(INPUT_DATA_ELEMENT); - inputElementElement.appendChild(inputDataElement); - inputDataElement.setAttribute(NAME_ATTRIBUTE, inputElement.inputName); - inputDataElement.setAttribute(ACTION_ATTRIBUTE, Integer.toString(inputElement.inputAction)); - if (inputElement.inputFormat != null) { - inputDataElement.setAttribute(FORMAT_ATTRIBUTE, inputElement.inputFormat); - } - } - - if (inputElement.attributes != null) { - for (InputAttribute attribute : inputElement.attributes) { - Element inputAttributeElement = doc.createElement(ATTRIBUTE_ELEMENT); - inputElementElement.appendChild(inputAttributeElement); - inputAttributeElement.setAttribute(NAME_ATTRIBUTE, attribute.attributeName); - Element inputDataElement = doc.createElement(INPUT_DATA_ELEMENT); - inputAttributeElement.appendChild(inputDataElement); - inputDataElement.setAttribute(NAME_ATTRIBUTE, attribute.inputName); - inputDataElement.setAttribute(ACTION_ATTRIBUTE, Integer.toString(attribute.inputAction)); - if (attribute.inputFormat != null) { - inputDataElement.setAttribute(FORMAT_ATTRIBUTE, attribute.inputFormat); - } - } - } - - if (inputElement.childElements != null) { - for (InputElement childInputElement : inputElement.childElements) { - inputElementElement.appendChild(createInputElementElement(childInputElement, doc)); - } - } - - return inputElementElement; - } - - /** - * Load all custom XML trace definitions, including the user-defined and - * default (built-in) parsers. - * - * @return The loaded trace definitions - */ - public static CustomXmlTraceDefinition[] loadAll() { - return loadAll(true); - } - - /** - * Load all custom XML trace definitions, including the user-defined and, - * optionally, the default (built-in) parsers. - * - * @param includeDefaults - * if true, the default (built-in) parsers are included - * - * @return The loaded trace definitions - * @since 3.2 - */ - public static CustomXmlTraceDefinition[] loadAll(boolean includeDefaults) { - File defaultFile = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME); - File legacyFile = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY); - - /* - * If there is no file at the expected location, check the legacy - * location instead. - */ - if (!defaultFile.exists() && legacyFile.exists()) { - CustomXmlTraceDefinition[] oldDefs = loadAll(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY); - for (CustomXmlTraceDefinition def : oldDefs) { - /* Save in the new location */ - def.save(); - } - } - - Set defs = new TreeSet<>(new Comparator() { - @Override - public int compare(CustomXmlTraceDefinition o1, CustomXmlTraceDefinition o2) { - int result = o1.categoryName.compareTo(o2.categoryName); - if (result != 0) { - return result; - } - return o1.definitionName.compareTo(o2.definitionName); - } - }); - defs.addAll(Arrays.asList(loadAll(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME))); - if (includeDefaults) { - defs.addAll(Arrays.asList(loadAll(CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME))); - } - return defs.toArray(new CustomXmlTraceDefinition[0]); - } - - /** - * Load all the XML trace definitions in the given definitions file. - * - * @param path - * Path to the definitions file to load - * @return The loaded trace definitions - */ - public static CustomXmlTraceDefinition[] loadAll(String path) { - File file = new File(path); - if (!file.canRead()) { - return new CustomXmlTraceDefinition[0]; - } - try (FileInputStream fis = new FileInputStream(file);) { - return loadAll(fis); - } catch (IOException e) { - Activator.logError("Error loading all in CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$ - } - return new CustomXmlTraceDefinition[0]; - } - - /** - * Load all the XML trace definitions from the given stream - * - * @param stream - * An input stream from which to read the definitions - * @return The loaded trace definitions - * @since 3.2 - */ - public static CustomXmlTraceDefinition[] loadAll(InputStream stream) { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - - // The following allows xml parsing without access to the dtd - db.setEntityResolver(createEmptyEntityResolver()); - - // The following catches xml parsing exceptions - db.setErrorHandler(createErrorHandler()); - - Document doc = db.parse(stream); - Element root = doc.getDocumentElement(); - if (!root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) { - return new CustomXmlTraceDefinition[0]; - } - - ArrayList defList = new ArrayList<>(); - NodeList nodeList = root.getChildNodes(); - for (int i = 0; i < nodeList.getLength(); i++) { - Node node = nodeList.item(i); - if (node instanceof Element && node.getNodeName().equals(DEFINITION_ELEMENT)) { - CustomXmlTraceDefinition def = extractDefinition((Element) node); - if (def != null) { - defList.add(def); - } - } - } - return defList.toArray(new CustomXmlTraceDefinition[0]); - } catch (ParserConfigurationException | SAXException | IOException e) { - Activator.logError("Error loading all in CustomXmlTraceDefinition: path=" + stream, e); //$NON-NLS-1$ - } - return new CustomXmlTraceDefinition[0]; - } - - /** - * Load the given trace definition. - * - * @param definitionName - * Name of the XML trace definition to load - * @return The loaded trace definition - * @deprecated Use {@link #load(String, String)} - */ - @Deprecated - public static CustomXmlTraceDefinition load(String definitionName) { - return load(TmfTraceType.CUSTOM_XML_CATEGORY, definitionName); - } - - /** - * Load the given trace definition. - * - * @param categoryName - * Category of the definition to load - * @param definitionName - * Name of the XML trace definition to load - * @return The loaded trace definition - * @since 3.2 - */ - public static CustomXmlTraceDefinition load(String categoryName, String definitionName) { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - - // The following allows xml parsing without access to the dtd - EntityResolver resolver = new EntityResolver() { - @Override - public InputSource resolveEntity(String publicId, String systemId) { - String empty = ""; //$NON-NLS-1$ - ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); - return new InputSource(bais); - } - }; - db.setEntityResolver(resolver); - - // The following catches xml parsing exceptions - db.setErrorHandler(new ErrorHandler() { - @Override - public void error(SAXParseException saxparseexception) throws SAXException { - } - - @Override - public void warning(SAXParseException saxparseexception) throws SAXException { - } - - @Override - public void fatalError(SAXParseException saxparseexception) throws SAXException { - throw saxparseexception; - } - }); - - CustomXmlTraceDefinition value = lookupXmlDefinition(categoryName, definitionName, db, CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME); - if (value == null) { - value = lookupXmlDefinition(categoryName, definitionName, db, CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME); - } - return value; - } catch (ParserConfigurationException | SAXException | IOException e) { - Activator.logError("Error loading CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ - } - return null; - } - - private static CustomXmlTraceDefinition lookupXmlDefinition(String categoryName, String definitionName, DocumentBuilder db, String source) throws SAXException, IOException { - File file = new File(source); - if (!file.exists()) { - return null; - } - - Document doc = db.parse(file); - - Element root = doc.getDocumentElement(); - if (!root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) { - return null; - } - - Element definitionElement = findDefinitionElement(root, categoryName, definitionName); - if (definitionElement != null) { - return extractDefinition(definitionElement); - } - return null; - } - - private static Element findDefinitionElement(Element root, String categoryName, String definitionName) { - NodeList nodeList = root.getChildNodes(); - for (int i = 0; i < nodeList.getLength(); i++) { - Node node = nodeList.item(i); - if (node instanceof Element && node.getNodeName().equals(DEFINITION_ELEMENT)) { - Element element = (Element) node; - String categoryAttribute = element.getAttribute(CATEGORY_ATTRIBUTE); - if (categoryAttribute.isEmpty()) { - categoryAttribute = TmfTraceType.CUSTOM_XML_CATEGORY; - } - String nameAttribute = element.getAttribute(NAME_ATTRIBUTE); - if (categoryName.equals(categoryAttribute) && - definitionName.equals(nameAttribute)) { - return element; - } - } - } - return null; - } - - /** - * Extract a trace definition from an XML element. - * - * @param definitionElement - * Definition element - * @return The extracted trace definition - */ - public static CustomXmlTraceDefinition extractDefinition(Element definitionElement) { - CustomXmlTraceDefinition def = new CustomXmlTraceDefinition(); - - def.categoryName = definitionElement.getAttribute(CATEGORY_ATTRIBUTE); - if (def.categoryName.isEmpty()) { - def.categoryName = TmfTraceType.CUSTOM_XML_CATEGORY; - } - def.definitionName = definitionElement.getAttribute(NAME_ATTRIBUTE); - if (def.definitionName.isEmpty()) { - return null; - } - - NodeList nodeList = definitionElement.getChildNodes(); - for (int i = 0; i < nodeList.getLength(); i++) { - Node node = nodeList.item(i); - String nodeName = node.getNodeName(); - if (nodeName.equals(TIME_STAMP_OUTPUT_FORMAT_ELEMENT)) { - Element formatElement = (Element) node; - def.timeStampOutputFormat = formatElement.getTextContent(); - } else if (nodeName.equals(INPUT_ELEMENT_ELEMENT)) { - InputElement inputElement = extractInputElement((Element) node); - if (inputElement != null) { - if (def.rootInputElement == null) { - def.rootInputElement = inputElement; - } else { - return null; - } - } - } else if (nodeName.equals(OUTPUT_COLUMN_ELEMENT)) { - Element outputColumnElement = (Element) node; - OutputColumn outputColumn = new OutputColumn(); - outputColumn.name = outputColumnElement.getAttribute(NAME_ATTRIBUTE); - def.outputs.add(outputColumn); - } - } - return def; - } - - private static InputElement extractInputElement(Element inputElementElement) { - InputElement inputElement = new InputElement(); - inputElement.elementName = inputElementElement.getAttribute(NAME_ATTRIBUTE); - inputElement.logEntry = (Boolean.toString(true).equals(inputElementElement.getAttribute(LOG_ENTRY_ATTRIBUTE))) ? true : false; - NodeList nodeList = inputElementElement.getChildNodes(); - for (int i = 0; i < nodeList.getLength(); i++) { - Node node = nodeList.item(i); - String nodeName = node.getNodeName(); - if (nodeName.equals(INPUT_DATA_ELEMENT)) { - Element inputDataElement = (Element) node; - inputElement.inputName = inputDataElement.getAttribute(NAME_ATTRIBUTE); - inputElement.inputAction = Integer.parseInt(inputDataElement.getAttribute(ACTION_ATTRIBUTE)); - inputElement.inputFormat = inputDataElement.getAttribute(FORMAT_ATTRIBUTE); - } else if (nodeName.equals(ATTRIBUTE_ELEMENT)) { - Element attributeElement = (Element) node; - InputAttribute attribute = new InputAttribute(); - attribute.attributeName = attributeElement.getAttribute(NAME_ATTRIBUTE); - NodeList attributeNodeList = attributeElement.getChildNodes(); - for (int j = 0; j < attributeNodeList.getLength(); j++) { - Node attributeNode = attributeNodeList.item(j); - String attributeNodeName = attributeNode.getNodeName(); - if (attributeNodeName.equals(INPUT_DATA_ELEMENT)) { - Element inputDataElement = (Element) attributeNode; - attribute.inputName = inputDataElement.getAttribute(NAME_ATTRIBUTE); - attribute.inputAction = Integer.parseInt(inputDataElement.getAttribute(ACTION_ATTRIBUTE)); - attribute.inputFormat = inputDataElement.getAttribute(FORMAT_ATTRIBUTE); - } - } - inputElement.addAttribute(attribute); - } else if (nodeName.equals(INPUT_ELEMENT_ELEMENT)) { - Element childInputElementElement = (Element) node; - InputElement childInputElement = extractInputElement(childInputElementElement); - if (childInputElement != null) { - inputElement.addChild(childInputElement); - } - } - } - return inputElement; - } - - /** - * Delete a definition from the currently loaded ones. - * - * @param definitionName - * The name of the definition to delete - * @deprecated Use {@link #delete(String, String)} - */ - @Deprecated - public static void delete(String definitionName) { - delete(TmfTraceType.CUSTOM_XML_CATEGORY, definitionName); - } - - /** - * Delete a definition from the currently loaded ones. - * - * @param categoryName - * The category of the definition to delete - * @param definitionName - * The name of the definition to delete - * @since 3.2 - */ - public static void delete(String categoryName, String definitionName) { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - - // The following allows xml parsing without access to the dtd - EntityResolver resolver = new EntityResolver() { - @Override - public InputSource resolveEntity(String publicId, String systemId) { - String empty = ""; //$NON-NLS-1$ - ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); - return new InputSource(bais); - } - }; - db.setEntityResolver(resolver); - - // The following catches xml parsing exceptions - db.setErrorHandler(new ErrorHandler() { - @Override - public void error(SAXParseException saxparseexception) throws SAXException { - } - - @Override - public void warning(SAXParseException saxparseexception) throws SAXException { - } - - @Override - public void fatalError(SAXParseException saxparseexception) throws SAXException { - throw saxparseexception; - } - }); - - File file = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME); - Document doc = db.parse(file); - - Element root = doc.getDocumentElement(); - if (!root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) { - return; - } - - Element definitionElement = findDefinitionElement(root, categoryName, definitionName); - if (definitionElement != null) { - root.removeChild(definitionElement); - } - - Transformer transformer = TransformerFactory.newInstance().newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ - - // initialize StreamResult with File object to save to file - StreamResult result = new StreamResult(new StringWriter()); - DOMSource source = new DOMSource(doc); - transformer.transform(source, result); - String xmlString = result.getWriter().toString(); - - try (FileWriter writer = new FileWriter(file);) { - writer.write(xmlString); - } - - TmfTraceType.removeCustomTraceType(CustomXmlTrace.class, categoryName, definitionName); - // Check if default definition needs to be reloaded - TmfTraceType.addCustomTraceType(CustomXmlTrace.class, categoryName, definitionName); - - } catch (ParserConfigurationException | SAXException | IOException | TransformerFactoryConfigurationError | TransformerException e) { - Activator.logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/Messages.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/Messages.java deleted file mode 100644 index 40d4a85262..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/Messages.java +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.parsers.custom; - -import org.eclipse.osgi.util.NLS; - -/** - * @since 3.0 - */ -@SuppressWarnings("javadoc") -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.core.parsers.custom.messages"; //$NON-NLS-1$ - - public static String CustomTrace_FileNotFound; - - // TODO: These strings should not be externalized - public static String CustomTraceDefinition_messageTag; - public static String CustomTraceDefinition_otherTag; - public static String CustomTraceDefinition_timestampTag; - public static String CustomTxtTraceDefinition_action; - public static String CustomTxtTraceDefinition_cardinality; - /** @since 3.2*/ - public static String CustomTxtTraceDefinition_category; - public static String CustomTxtTraceDefinition_definition; - public static String CustomTxtTraceDefinition_definitionRootElement; - public static String CustomTxtTraceDefinition_format; - public static String CustomTxtTraceDefinition_inputData; - public static String CustomTxtTraceDefinition_inputLine; - public static String CustomTxtTraceDefinition_max; - public static String CustomTxtTraceDefinition_min; - public static String CustomTxtTraceDefinition_name; - public static String CustomTxtTraceDefinition_outputColumn; - public static String CustomTxtTraceDefinition_regEx; - public static String CustomTxtTraceDefinition_timestampOutputFormat; - public static String CustomXmlTraceDefinition_action; - public static String CustomXmlTraceDefinition_attribute; - /** @since 3.2*/ - public static String CustomXmlTraceDefinition_category; - public static String CustomXmlTraceDefinition_definition; - public static String CustomXmlTraceDefinition_definitionRootElement; - public static String CustomXmlTraceDefinition_format; - public static String CustomXmlTraceDefinition_ignoreTag; - public static String CustomXmlTraceDefinition_inputData; - public static String CustomXmlTraceDefinition_inputElement; - public static String CustomXmlTraceDefinition_logEntry; - public static String CustomXmlTraceDefinition_name; - public static String CustomXmlTraceDefinition_outputColumn; - public static String CustomXmlTraceDefinition_timestampOutputFormat; - - static { - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/messages.properties b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/messages.properties deleted file mode 100644 index 5f12afdde8..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/messages.properties +++ /dev/null @@ -1,44 +0,0 @@ -############################################################################### -# Copyright (c) 2013, 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### - -CustomTrace_FileNotFound=File not found - -CustomTraceDefinition_messageTag=Message -CustomTraceDefinition_otherTag=Other -CustomTraceDefinition_timestampTag=Time Stamp -CustomTxtTraceDefinition_action=action -CustomTxtTraceDefinition_cardinality=Cardinality -CustomTxtTraceDefinition_category=category -CustomTxtTraceDefinition_definition=Definition -CustomTxtTraceDefinition_definitionRootElement=CustomTxtTraceDefinitionList -CustomTxtTraceDefinition_format=format -CustomTxtTraceDefinition_inputData=InputData -CustomTxtTraceDefinition_inputLine=InputLine -CustomTxtTraceDefinition_max=max -CustomTxtTraceDefinition_min=min -CustomTxtTraceDefinition_name=name -CustomTxtTraceDefinition_outputColumn=OutputColumn -CustomTxtTraceDefinition_regEx=RegEx -CustomTxtTraceDefinition_timestampOutputFormat=TimeStampOutputFormat -CustomXmlTraceDefinition_action=action -CustomXmlTraceDefinition_attribute=Attribute -CustomXmlTraceDefinition_category=category -CustomXmlTraceDefinition_definition=Definition -CustomXmlTraceDefinition_definitionRootElement=CustomXMLTraceDefinitionList -CustomXmlTraceDefinition_format=format -CustomXmlTraceDefinition_ignoreTag=Ignore -CustomXmlTraceDefinition_inputData=InputData -CustomXmlTraceDefinition_inputElement=InputElement -CustomXmlTraceDefinition_logEntry=logentry -CustomXmlTraceDefinition_name=name -CustomXmlTraceDefinition_outputColumn=OutputColumn -CustomXmlTraceDefinition_timestampOutputFormat=TimeStampOutputFormat diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/project/model/TmfTraceImportException.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/project/model/TmfTraceImportException.java deleted file mode 100644 index 115353c715..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/project/model/TmfTraceImportException.java +++ /dev/null @@ -1,45 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.core.project.model; - -/** - * Tmf trace import exception - * - * @author Matthew Khouzam - * @since 3.0 - */ -public class TmfTraceImportException extends Exception { - - private static final long serialVersionUID = -6902068313782751330L; - - /** - * Constructs a new TmfTraceImportException with null as its - * detail message. The cause is not initialized, and may subsequently be - * initialized by a call to {@link #initCause}. - */ - public TmfTraceImportException() { - } - - /** - * Constructs a new exception with the specified detail message. The cause - * is not initialized, and may subsequently be initialized by a call to - * {@link #initCause}. - * - * @param message - * the detail message. The detail message is saved for later - * retrieval by the {@link #getMessage()} method. - */ - public TmfTraceImportException(String message) { - super(message); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/project/model/TmfTraceType.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/project/model/TmfTraceType.java deleted file mode 100644 index 447d0f786c..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/project/model/TmfTraceType.java +++ /dev/null @@ -1,691 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Matthew Khouzam - Added import functionalities - * Geneviève Bastien - Added support for experiment types - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.project.model; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.Platform; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTrace; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTraceDefinition; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTrace; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Utility class for accessing TMF trace type extensions from the platform's - * extensions registry. - * - * @version 1.0 - * @author Patrick Tasse - * @author Matthew Khouzam - * @since 3.0 - */ -public final class TmfTraceType { - - // ------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------ - - private static final char SEPARATOR = ':'; - - /** Extension point ID */ - public static final String TMF_TRACE_TYPE_ID = "org.eclipse.linuxtools.tmf.core.tracetype"; //$NON-NLS-1$ - - /** Extension point element 'Category' */ - public static final String CATEGORY_ELEM = "category"; //$NON-NLS-1$ - - /** Extension point element 'Type' */ - public static final String TYPE_ELEM = "type"; //$NON-NLS-1$ - - /** Extension point element 'Experiment' */ - public static final String EXPERIMENT_ELEM = "experiment"; //$NON-NLS-1$ - - /** Extension point attribute 'ID' */ - public static final String ID_ATTR = "id"; //$NON-NLS-1$ - - /** Extension point attribute 'name' */ - public static final String NAME_ATTR = "name"; //$NON-NLS-1$ - - /** Extension point attribute 'category' */ - public static final String CATEGORY_ATTR = "category"; //$NON-NLS-1$ - - /** Extension point attribute 'trace_type' */ - public static final String TRACE_TYPE_ATTR = "trace_type"; //$NON-NLS-1$ - - /** Extension point attribute 'event_type' */ - public static final String EVENT_TYPE_ATTR = "event_type"; //$NON-NLS-1$ - - /** Extension point attribute 'experiment_type' */ - public static final String EXPERIMENT_TYPE_ATTR = "experiment_type"; //$NON-NLS-1$ - - /** Extension point attribute 'isDirectory' */ - public static final String IS_DIR_ATTR = "isDirectory"; //$NON-NLS-1$ - - /** - * Custom text label used internally and therefore should not be - * externalized - */ - public static final String CUSTOM_TXT_CATEGORY = "Custom Text"; //$NON-NLS-1$ - - /** - * Custom XML label used internally and therefore should not be externalized - */ - public static final String CUSTOM_XML_CATEGORY = "Custom XML"; //$NON-NLS-1$ - - /** Default experiment type */ - public static final String DEFAULT_EXPERIMENT_TYPE = "org.eclipse.linuxtools.tmf.core.experiment.generic"; //$NON-NLS-1$ - - // The mapping of available trace type IDs to their corresponding - // configuration element - private static final Map TRACE_TYPE_ATTRIBUTES = new HashMap<>(); - private static final Map TRACE_CATEGORIES = new HashMap<>(); - private static final Map TRACE_TYPES = new LinkedHashMap<>(); - - static { - populateCategoriesAndTraceTypes(); - populateCustomTraceTypes(); - } - - /** - * Enum to say whether a type applies to a trace or experiment - * - * @author Geneviève Bastien - */ - public enum TraceElementType { - /** Trace type applies to trace */ - TRACE, - /** Trace type applies to experiment */ - EXPERIMENT, - } - - // ------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------ - - private TmfTraceType() { - } - - // ------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------ - - /** - * Retrieves the category name from the platform extension registry based on - * the category ID - * - * @param categoryId - * The category ID - * @return the category name or empty string if not found - */ - public static String getCategoryName(String categoryId) { - IConfigurationElement[] elements = Platform.getExtensionRegistry() - .getConfigurationElementsFor(TMF_TRACE_TYPE_ID); - for (IConfigurationElement element : elements) { - if (element.getName().equals(CATEGORY_ELEM) && element.getAttribute(ID_ATTR).equals(categoryId)) { - return element.getAttribute(NAME_ATTR); - } - } - return ""; //$NON-NLS-1$ - } - - /** - * Retrieves all configuration elements from the platform extension registry - * for the trace type extension that apply to traces and not experiments. - * - * @return an array of trace type configuration elements - */ - public static IConfigurationElement[] getTypeElements() { - IConfigurationElement[] elements = Platform.getExtensionRegistry() - .getConfigurationElementsFor(TMF_TRACE_TYPE_ID); - List typeElements = new LinkedList<>(); - for (IConfigurationElement element : elements) { - if (element.getName().equals(TYPE_ELEM)) { - typeElements.add(element); - } - } - return typeElements.toArray(new IConfigurationElement[typeElements.size()]); - } - - /** - * Retrieve the TraceTypeHelper for a given trace type ID - * - * @param id - * The trace type ID - * @return The corresponding TraceTypeHelper, or null if there is none for - * the specified ID - * @deprecated Use {@link #getTraceType(String)} - */ - @Deprecated - public static TraceTypeHelper getTraceTypeHelper(String id) { - return TRACE_TYPES.get(id); - } - - /** - * Get an iterable view of the existing trace type IDs. - * - * @return The currently registered trace type IDs - */ - public static Iterable getTraceTypeIDs() { - return TRACE_TYPES.keySet(); - } - - /** - * Get an iterable view of the existing trace type helpers. - * - * @return The currently registered trace type helpers - */ - public static Iterable getTraceTypeHelpers() { - return TRACE_TYPES.values(); - } - - /** - * Returns a list of "category:tracetype , ..." - * - * Returns only trace types, not experiment types - * - * @return returns a list of "category:tracetype , ..." - */ - public static String[] getAvailableTraceTypes() { - return getAvailableTraceTypes(null); - } - - /** - * Returns a list of "category:tracetype , ..." sorted by given comparator. - * - * Returns only trace types, not experiment types - * - * @param comparator - * Comparator class (type String) or null for alphabetical order. - * @return sorted list according to the given comparator - */ - public static String[] getAvailableTraceTypes(Comparator comparator) { - - // Generate the list of Category:TraceType to populate the ComboBox - List traceTypes = new ArrayList<>(); - - for (String key : TRACE_TYPES.keySet()) { - TraceTypeHelper tt = TRACE_TYPES.get(key); - if (!tt.isExperimentType()) { - traceTypes.add(tt.getCategoryName() + SEPARATOR + tt.getName()); - } - } - - if (comparator == null) { - Collections.sort(traceTypes); - } else { - Collections.sort(traceTypes, comparator); - } - - // Format result - return traceTypes.toArray(new String[traceTypes.size()]); - } - - /** - * Gets the custom trace types (custom text and friends) - * - * @param type - * the type to get (Text, xml or other...) - * @return the list of custom trace types - */ - public static List getCustomTraceTypes(String type) { - List traceTypes = new ArrayList<>(); - if (type.equals(CUSTOM_TXT_CATEGORY)) { - for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) { - String traceTypeName = def.definitionName; - traceTypes.add(traceTypeName); - } - } - if (type.equals(CUSTOM_XML_CATEGORY)) { - for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { - String traceTypeName = def.definitionName; - traceTypes.add(traceTypeName); - } - } - return traceTypes; - } - - /** - * Gets all the custom trace types - * - * @return the list of custom trace types - */ - public static List getCustomTraceTypes() { - - List traceTypes = new ArrayList<>(); - for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) { - String traceTypeName = def.definitionName; - traceTypes.add(traceTypeName); - } - for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { - String traceTypeName = def.definitionName; - traceTypes.add(traceTypeName); - } - return traceTypes; - } - - private static void populateCustomTraceTypes() { - // add the custom trace types - for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) { - String traceTypeId = CustomTxtTrace.class.getCanonicalName() + SEPARATOR + def.categoryName + SEPARATOR + def.definitionName; - ITmfTrace trace = new CustomTxtTrace(def); - TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, def.categoryName, def.definitionName, trace, false, TraceElementType.TRACE); - TRACE_TYPES.put(traceTypeId, tt); - // Deregister trace as signal handler because it is only used for validation - TmfSignalManager.deregister(trace); - } - for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { - String traceTypeId = CustomXmlTrace.class.getCanonicalName() + SEPARATOR + def.categoryName + SEPARATOR + def.definitionName; - ITmfTrace trace = new CustomXmlTrace(def); - TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, def.categoryName, def.definitionName, trace, false, TraceElementType.TRACE); - TRACE_TYPES.put(traceTypeId, tt); - // Deregister trace as signal handler because it is only used for validation - TmfSignalManager.deregister(trace); - } - } - - /** - * Add or replace a custom trace type - * - * @param category - * The custom parser category - * @param definitionName - * The custom parser definition name to add or replace - * @deprecated Use {@link #addCustomTraceType(Class, String, String)} - */ - @Deprecated - public static void addCustomTraceType(String category, String definitionName) { - if (category.equals(CUSTOM_TXT_CATEGORY)) { - addCustomTraceType(CustomTxtTrace.class, category, definitionName); - } else if (category.equals(CUSTOM_XML_CATEGORY)) { - addCustomTraceType(CustomXmlTrace.class, category, definitionName); - } - } - - /** - * Add or replace a custom trace type - * - * @param traceClass - * The custom trace class, either {@link CustomTxtTrace} or - * {@link CustomXmlTrace} - * @param category - * The custom parser category - * @param definitionName - * The custom parser definition name to add or replace - */ - public static void addCustomTraceType(Class traceClass, String category, String definitionName) { - String traceTypeId = null; - ITmfTrace trace = null; - - if (traceClass.equals(CustomTxtTrace.class)) { - traceTypeId = CustomTxtTrace.class.getCanonicalName() + SEPARATOR + category + SEPARATOR + definitionName; - CustomTxtTraceDefinition def = CustomTxtTraceDefinition.load(category, definitionName); - if (def != null) { - trace = new CustomTxtTrace(def); - } - } else if (traceClass.equals(CustomXmlTrace.class)) { - traceTypeId = CustomXmlTrace.class.getCanonicalName() + SEPARATOR + category + SEPARATOR + definitionName; - CustomXmlTraceDefinition def = CustomXmlTraceDefinition.load(category, definitionName); - if (def != null) { - trace = new CustomXmlTrace(def); - } - } - - if (traceTypeId != null && trace != null) { - TraceTypeHelper helper = TRACE_TYPES.get(traceTypeId); - if (helper != null) { - helper.getTrace().dispose(); - } - TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, category, definitionName, trace, false, TraceElementType.TRACE); - TRACE_TYPES.put(traceTypeId, tt); - // Deregister trace as signal handler because it is only used for validation - TmfSignalManager.deregister(trace); - } - } - - /** - * Remove a custom trace type - * - * @param category - * The custom parser category - * @param definitionName - * The custom parser definition name to add or replace - * @deprecated Use {@link #removeCustomTraceType(Class, String, String)} - */ - @Deprecated - public static void removeCustomTraceType(String category, String definitionName) { - if (category.equals(CUSTOM_TXT_CATEGORY)) { - removeCustomTraceType(CustomTxtTrace.class, category, definitionName); - } else if (category.equals(CUSTOM_XML_CATEGORY)) { - removeCustomTraceType(CustomXmlTrace.class, category, definitionName); - } - } - - /** - * Remove a custom trace type - * - * @param traceClass - * The custom trace class, either {@link CustomTxtTrace} or - * {@link CustomXmlTrace} - * @param category - * The custom parser category - * @param definitionName - * The custom parser definition name to add or replace - */ - public static void removeCustomTraceType(Class traceClass, String category, String definitionName) { - String traceTypeId = traceClass.getCanonicalName() + SEPARATOR + category + SEPARATOR + definitionName; - TraceTypeHelper helper = TRACE_TYPES.remove(traceTypeId); - if (helper != null) { - helper.getTrace().dispose(); - } - } - - /** - * Gets a trace type for a given canonical id - * - * @param id - * the ID of the trace - * @return the return type - */ - public static TraceTypeHelper getTraceType(String id) { - return TRACE_TYPES.get(id); - } - - private static void populateCategoriesAndTraceTypes() { - if (TRACE_TYPES.isEmpty()) { - // Populate the Categories and Trace Types - IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType.TMF_TRACE_TYPE_ID); - for (IConfigurationElement ce : config) { - String elementName = ce.getName(); - if (elementName.equals(TmfTraceType.TYPE_ELEM)) { - String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR); - TRACE_TYPE_ATTRIBUTES.put(traceTypeId, ce); - } else if (elementName.equals(TmfTraceType.CATEGORY_ELEM)) { - String categoryId = ce.getAttribute(TmfTraceType.ID_ATTR); - TRACE_CATEGORIES.put(categoryId, ce); - } else if (elementName.equals(TmfTraceType.EXPERIMENT_ELEM)) { - String experimentTypeId = ce.getAttribute(TmfTraceType.ID_ATTR); - TRACE_TYPE_ATTRIBUTES.put(experimentTypeId, ce); - } - } - // create the trace types - for (String typeId : TRACE_TYPE_ATTRIBUTES.keySet()) { - IConfigurationElement ce = TRACE_TYPE_ATTRIBUTES.get(typeId); - final String category = getCategory(ce); - final String attribute = ce.getAttribute(TmfTraceType.NAME_ATTR); - ITmfTrace trace = null; - TraceElementType elementType = TraceElementType.TRACE; - try { - if (ce.getName().equals(TmfTraceType.TYPE_ELEM)) { - trace = (ITmfTrace) ce.createExecutableExtension(TmfTraceType.TRACE_TYPE_ATTR); - } else if (ce.getName().equals(TmfTraceType.EXPERIMENT_ELEM)) { - trace = (ITmfTrace) ce.createExecutableExtension(TmfTraceType.EXPERIMENT_TYPE_ATTR); - elementType = TraceElementType.EXPERIMENT; - } - if (trace == null) { - break; - } - // Deregister trace as signal handler because it is only - // used for validation - TmfSignalManager.deregister(trace); - - final String dirString = ce.getAttribute(TmfTraceType.IS_DIR_ATTR); - boolean isDir = Boolean.parseBoolean(dirString); - - TraceTypeHelper tt = new TraceTypeHelper(typeId, category, attribute, trace, isDir, elementType); - TRACE_TYPES.put(typeId, tt); - } catch (CoreException e) { - } - - } - } - } - - private static String getCategory(IConfigurationElement ce) { - final String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR); - if (categoryId != null) { - IConfigurationElement category = TRACE_CATEGORIES.get(categoryId); - if (category != null && !category.getName().equals("")) { //$NON-NLS-1$ - return category.getAttribute(TmfTraceType.NAME_ATTR); - } - } - return "[no category]"; //$NON-NLS-1$ - } - - /** - * Returns the list of trace categories - * - * @return the list of trace categories - */ - public static List getTraceCategories() { - List categoryNames = new ArrayList<>(); - for (String key : TRACE_TYPES.keySet()) { - final String categoryName = TRACE_TYPES.get(key).getCategoryName(); - if (!categoryNames.contains(categoryName)) { - categoryNames.add(categoryName); - } - } - return categoryNames; - } - - /** - * Get the trace type helper classes from category name. Return only the - * trace types, not the experiment types - * - * @param categoryName - * the categoryName to lookup - * @return a list of trace type helper classes {@link TraceTypeHelper} - */ - public static List getTraceTypes(String categoryName) { - List traceNames = new ArrayList<>(); - for (String key : TRACE_TYPES.keySet()) { - if (!TRACE_TYPES.get(key).isExperimentType()) { - final String storedCategoryName = TRACE_TYPES.get(key).getCategoryName(); - if (storedCategoryName.equals(categoryName)) { - traceNames.add(TRACE_TYPES.get(key)); - } - } - } - return traceNames; - } - - /** - * Validate a trace type - * - * @param traceTypeName - * the trace category (canonical name) - * @param fileName - * the file name (and path) - * @return true if the trace is of a valid type - */ - public static boolean validate(String traceTypeName, String fileName) { - if (traceTypeName != null && !traceTypeName.isEmpty()) { - final TraceTypeHelper traceTypeHelper = TRACE_TYPES.get(traceTypeName); - if (traceTypeHelper == null || !traceTypeHelper.validate(fileName).isOK()) { - return false; - } - } - return true; - } - - /** - * Validate a trace - * - * @param traceToValidate - * the trace category (canonical name) - * @return true if the trace is of a valid type - */ - public static boolean validate(TraceValidationHelper traceToValidate) { - return validate(traceToValidate.getTraceType(), traceToValidate.getTraceToScan()); - } - - /** - * Validate a list of files with a tracetype - * - * @param traceTypeName - * the trace category (canonical name) - * @param traces - * the list of files to check if they are trace - * @return true if all the traces are valid - */ - public static boolean validateTraceFiles(String traceTypeName, List traces) { - if (traceTypeName != null && !"".equals(traceTypeName) && //$NON-NLS-1$ - !traceTypeName.startsWith(TmfTraceType.CUSTOM_TXT_CATEGORY) && !traceTypeName.startsWith(TmfTraceType.CUSTOM_XML_CATEGORY)) { - for (File trace : traces) { - if (!validate(traceTypeName, trace.getAbsolutePath())) { - return false; - } - } - } - return true; - } - - /** - * Get a configuration element for a given name - * - * @param traceType - * the name canonical - * @return the configuration element, can be null - */ - public static IConfigurationElement getTraceAttributes(String traceType) { - return TRACE_TYPE_ATTRIBUTES.get(traceType); - } - - /** - * Find the id of a trace type by its parameters - * - * @param category - * like "ctf" or "custom text" - * @param traceType - * like "kernel" - * @return an id like "org.eclipse.linuxtools.blabla... - */ - public static String getTraceTypeId(String category, String traceType) { - for (String key : TRACE_TYPES.keySet()) { - if (TRACE_TYPES.get(key).getCategoryName().equals(category.trim()) && TRACE_TYPES.get(key).getName().equals(traceType.trim())) { - return key; - } - } - return null; - } - - /** - * Gets the custom trace type ID from the custom trace name - * - * @param traceType - * The trace type in human form (category:name) - * @return the trace type ID or null if the trace is not a custom one - * @deprecated Use {@link #getTraceTypeId(String, String)} - */ - @Deprecated - public static String getCustomTraceTypeId(String traceType) { - String traceTypeToken[] = traceType.split(":", 2); //$NON-NLS-1$ - if (traceTypeToken.length == 2) { - return getTraceTypeId(traceTypeToken[0], traceTypeToken[1]); - } - return null; - } - - /** - * Is the trace a custom (user-defined) trace type. These are the traces - * like : text and xml defined by the custom trace wizard. - * - * @param traceType - * the trace type in human form (category:name) - * @return true if the trace is a custom type - * @deprecated Use {@link #getTraceTypeId(String, String)} and check prefix - */ - @Deprecated - public static boolean isCustomTrace(String traceType) { - String traceTypeId = getCustomTraceTypeId(traceType); - if (traceTypeId != null) { - return traceTypeId.startsWith(CustomTxtTrace.class.getCanonicalName() + SEPARATOR) || - traceTypeId.startsWith(CustomXmlTrace.class.getCanonicalName() + SEPARATOR); - } - return false; - } - - /** - * Checks if a trace is a valid directory trace - * @param path - * the file name (and path) - * @return true if the trace is a valid directory trace else false - */ - public static boolean isDirectoryTrace(String path) { - final Iterable traceTypeHelpers = getTraceTypeHelpers(); - for (TraceTypeHelper traceTypeHelper : traceTypeHelpers) { - if (traceTypeHelper.isDirectoryTraceType() && - traceTypeHelper.validate(path).isOK()) { - return true; - } - } - return false; - } - - /** - * @param traceType - * the trace type - * @return true it is a directory trace type else else false - */ - public static boolean isDirectoryTraceType(String traceType) { - if (traceType != null) { - TraceTypeHelper traceTypeHelper = getTraceType(traceType); - if (traceTypeHelper != null) { - return traceTypeHelper.isDirectoryTraceType(); - } - } - throw new IllegalArgumentException("Invalid trace type string: " + traceType); //$NON-NLS-1$ - } - - /** - * Get the trace type id for a resource - * - * @param resource - * the resource - * @return the trace type id or null if it is not set - * @throws CoreException - * if the trace type id cannot be accessed - * @since 3.2 - */ - public static String getTraceTypeId(IResource resource) throws CoreException { - String traceTypeId = resource.getPersistentProperties().get(TmfCommonConstants.TRACETYPE); - // Fix custom trace type id with old class name or without category name for backward compatibility - if (traceTypeId != null) { - int index = traceTypeId.lastIndexOf(':'); - if (index != -1) { - if (traceTypeId.contains(CustomTxtTrace.class.getSimpleName() + ':') && traceTypeId.indexOf(':') == index) { - traceTypeId = CustomTxtTrace.class.getCanonicalName() + ':' + - TmfTraceType.CUSTOM_TXT_CATEGORY + traceTypeId.substring(index); - } else if (traceTypeId.contains(CustomXmlTrace.class.getSimpleName() + ':') && traceTypeId.indexOf(':') == index) { - traceTypeId = CustomXmlTrace.class.getCanonicalName() + ':' + - TmfTraceType.CUSTOM_XML_CATEGORY + traceTypeId.substring(index); - } - } - } - return traceTypeId; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/project/model/TraceTypeHelper.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/project/model/TraceTypeHelper.java deleted file mode 100644 index b647038809..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/project/model/TraceTypeHelper.java +++ /dev/null @@ -1,167 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Bernd Hufmann - Handling of directory traces types - * Geneviève Bastien - Added support of experiment types - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.project.model; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType.TraceElementType; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TraceValidationStatus; - -/** - * TraceTypeHelper, a helper that can link a few names to a configuration element - * and a trace - * - * @author Matthew Khouzam - * @since 3.0 - */ -public class TraceTypeHelper { - - private final String fName; - private final String fCategoryName; - private final String fCanonicalName; - private final TraceElementType fElementType; - @NonNull - private final ITmfTrace fTrace; - private final boolean fIsDirectory; - - /** - * Constructor for a trace type helper. It is a link between a canonical - * (hard to read) name, a category name, a name and a trace object. It is - * used for trace validation. - * - * @param canonicalName - * The "path" of the tracetype - * @param categoryName - * the category of the trace type - * @param name - * the name of the trace - * @param trace - * an object of the trace type - * @param isDir - * flag indicating whether the trace type is for a directory or file trace - * @param elementType - * True if this helper is for an experiment type - */ - public TraceTypeHelper(String canonicalName, String categoryName, String name, @NonNull ITmfTrace trace, boolean isDir, TraceElementType elementType) { - fName = name; - fCategoryName = categoryName; - fCanonicalName = canonicalName; - fTrace = trace; - fIsDirectory = isDir; - fElementType = elementType; - } - - /** - * Get the name - * - * @return the name - */ - public String getName() { - return fName; - } - - /** - * Get the category name - * - * @return the category name - */ - public String getCategoryName() { - return fCategoryName; - } - - /** - * Get the canonical name - * - * @return the canonical Name - */ - public String getCanonicalName() { - return fCanonicalName; - } - - /** - * Is the trace of this type? - * - * @param path - * the trace to validate - * @return whether it passes the validation - */ - public IStatus validate(String path) { - return fTrace.validate(null, path); - } - - /** - * Validate a trace against this trace type with confidence level - * - * @param path - * the trace to validate - * @return the confidence level (0 is lowest) or -1 if validation fails - * @since 3.0 - */ - public int validateWithConfidence(String path) { - int result = -1; - IStatus status = fTrace.validate(null, path); - if (status.isOK()) { - result = 0; - if (status instanceof TraceValidationStatus) { - result = ((TraceValidationStatus) status).getConfidence(); - } - } - return result; - } - - /** - * Get an object of the trace type - * @return an object of the trace type - * @since 2.1 - */ - public ITmfTrace getTrace() { - return fTrace; - } - - /** - * Return whether this helper applies to a trace type or experiment type - * - * @return True if experiment type, false otherwise - */ - public boolean isExperimentType() { - return fElementType == TraceElementType.EXPERIMENT; - } - - /** - * Get the class associated with this trace type - * - * @return The trace class - * @since 3.0 - */ - public Class getTraceClass() { - return fTrace.getClass(); - } - - /** - * Returns whether trace type is for a directory trace or a single file trace - * @return true if trace type is for a directory trace else false - */ - public boolean isDirectoryTraceType() { - return fIsDirectory; - } - - - @Override - public String toString() { - return fName; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/project/model/TraceValidationHelper.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/project/model/TraceValidationHelper.java deleted file mode 100644 index b95ddadb43..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/project/model/TraceValidationHelper.java +++ /dev/null @@ -1,99 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.project.model; - -/** - * Trace import helper class - * - * @author Matthew Khouzam - * @since 3.0 - */ -public class TraceValidationHelper implements Comparable { - - private final String fTraceToScan; - private final String fTraceType; - - /** - * Trace To validate constructor - * - * @param traceToScan - * the path of the trace - * @param traceType - * the trace type of the trace to add (canonical name) - */ - public TraceValidationHelper(String traceToScan, String traceType) { - this.fTraceToScan = traceToScan; - this.fTraceType = traceType; - } - - /** - * @return the trace filename - */ - public String getTraceToScan() { - return fTraceToScan; - } - - /** - * @return the trace type canonical name - */ - public String getTraceType() { - return fTraceType; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((fTraceToScan == null) ? 0 : fTraceToScan.hashCode()); - result = prime * result + ((fTraceType == null) ? 0 : fTraceType.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof TraceValidationHelper)) { - return false; - } - TraceValidationHelper other = (TraceValidationHelper) obj; - if (fTraceToScan == null) { - if (other.fTraceToScan != null) { - return false; - } - } else if (!fTraceToScan.equals(other.fTraceToScan)) { - return false; - } - if (fTraceType == null) { - if (other.fTraceType != null) { - return false; - } - } else if (!fTraceType.equals(other.fTraceType)) { - return false; - } - return true; - } - - @Override - public int compareTo(TraceValidationHelper o) { - int retVal = fTraceToScan.compareTo(o.getTraceToScan()); - if (retVal == 0) { - retVal = fTraceType.compareTo(o.fTraceType); - } - return retVal; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/request/ITmfEventRequest.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/request/ITmfEventRequest.java deleted file mode 100644 index 8f0aca9b4b..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/request/ITmfEventRequest.java +++ /dev/null @@ -1,199 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Alexandre Montplaisir - Merge with ITmfDataRequest - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.request; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; - -/** - * The TMF event request - * - * @author Francois Chouinard - */ -public interface ITmfEventRequest { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** The request count for all the events - * @since 3.0*/ - static final int ALL_DATA = Integer.MAX_VALUE; - - /** The request execution type/priority - * @since 3.0*/ - enum ExecutionType { - /** - * Backgroung, long-running, lower priority request - */ - BACKGROUND, - /** - * Foreground, short-running, high priority request - */ - FOREGROUND - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * @return request data type (T) - */ - Class getDataType(); - - /** - * @return request ID - */ - int getRequestId(); - - /** - * @return request ID - * @since 3.0 - */ - ExecutionType getExecType(); - - /** - * @return the index of the first event requested - */ - long getIndex(); - - /** - * @return the number of requested events - */ - int getNbRequested(); - - /** - * @return the number of events read so far - */ - int getNbRead(); - - /** - * @return the requested time range - */ - TmfTimeRange getRange(); - - // ------------------------------------------------------------------------ - // Request state predicates - // ------------------------------------------------------------------------ - - /** - * @return true if the request is still active - */ - boolean isRunning(); - - /** - * @return true if the request is completed - */ - boolean isCompleted(); - - /** - * @return true if the request has failed - */ - boolean isFailed(); - - /** - * @return true if the request was cancelled - */ - boolean isCancelled(); - - // ------------------------------------------------------------------------ - // Data handling - // ------------------------------------------------------------------------ - - /** - * Process the piece of data - * - * @param event - * The trace event to process - */ - void handleData(@NonNull ITmfEvent event); - - // ------------------------------------------------------------------------ - // Request notifications - // ------------------------------------------------------------------------ - - /** - * Request processing start notification - */ - void handleStarted(); - - /** - * Request processing completion notification - */ - void handleCompleted(); - - /** - * Request successful completion notification - */ - void handleSuccess(); - - /** - * Request failure notification - */ - void handleFailure(); - - /** - * Request cancellation notification - */ - void handleCancel(); - - /** - * To suspend the client thread until the request completes (or is - * cancelled). - * - * @throws InterruptedException - * thrown if the request was cancelled - */ - void waitForCompletion() throws InterruptedException; - - // ------------------------------------------------------------------------ - // Request state modifiers - // ------------------------------------------------------------------------ - - /** - * Put the request in the running state - */ - void start(); - - /** - * Put the request in the completed state - */ - void done(); - - /** - * Put the request in the failed completed state - */ - void fail(); - - /** - * Put the request in the cancelled completed state - */ - void cancel(); - - // ------------------------------------------------------------------------ - // Others - // ------------------------------------------------------------------------ - - /** - * This method is called by the event provider to set the index - * corresponding to the time range start time - * - * @param index - * The start time index - */ - void setStartIndex(int index); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/request/TmfEventRequest.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/request/TmfEventRequest.java deleted file mode 100644 index c37bb1173a..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/request/TmfEventRequest.java +++ /dev/null @@ -1,426 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Alexandre Montplaisir - Consolidate constructors, merge with TmfDataRequest - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.request; - -import java.util.concurrent.CountDownLatch; - -import org.eclipse.linuxtools.internal.tmf.core.TmfCoreTracer; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; - -/** - * TmfEventRequest's are used to obtain series of events from an event provider. - * Open ranges can be used, especially for continuous streaming. - *

- * The request is processed asynchronously by a TmfEventProvider and, as events - * become available, handleData() is invoked synchronously for each one. - *

- * The TmfEventProvider indicates that the request is completed by calling - * done(). The request can be cancelled at any time with cancel(). - *

- * Typical usage: - * - *


- * TmfEventRequest request = new TmfEventRequest(DataType.class, range, startIndex, nbEvents, priority) {
- *
- *     public void handleData(ITmfEvent event) {
- *         // do something with the event
- *     }
- *
- *     public void handleSuccess() {
- *         // callback for when the request completes successfully
- *     }
- *
- *     public void handleFailure() {
- *         // callback for when the request fails due to an error
- *     }
- *
- *     public void handleCancel() {
- *         // callback for when the request is cancelled via .cancel()
- *     }
- *
- * };
- *
- * eventProvider.sendRequest(request);
- * 
- * - * - * TODO: Implement request failures (codes, etc...) - * - * @author Francois Chouinard - * @since 3.0 - */ -public abstract class TmfEventRequest implements ITmfEventRequest { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - private static int fRequestNumber = 0; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final Class fDataType; - private final ExecutionType fExecType; - - /** A unique request ID */ - private final int fRequestId; - - /** The requested events time range */ - private final TmfTimeRange fRange; - - /** The index (rank) of the requested event - * @since 3.0*/ - protected long fIndex; - - /** The number of requested events (ALL_DATA for all) - * @since 3.0*/ - protected int fNbRequested; - - /** The number of reads so far */ - private int fNbRead; - - private final CountDownLatch startedLatch = new CountDownLatch(1); - private final CountDownLatch completedLatch = new CountDownLatch(1); - - private boolean fRequestRunning; - private boolean fRequestCompleted; - private boolean fRequestFailed; - private boolean fRequestCanceled; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Request 'n' events of a given type, for the *whole* trace, at the given - * priority. - * - * @param dataType - * The requested data type. - * @param index - * The index of the first event to retrieve. You can use '0' to - * start at the beginning of the trace. - * @param nbRequested - * The number of events requested. You can use - * {@link TmfEventRequest#ALL_DATA} to indicate you want all - * events in the trace. - * @param priority - * The requested execution priority. - */ - public TmfEventRequest(Class dataType, - long index, - int nbRequested, - ExecutionType priority) { - this(dataType, TmfTimeRange.ETERNITY, index, nbRequested, priority); - } - - /** - * Request 'n' events of a given type, for the given time range, at the - * given priority. - * - * @param dataType - * The requested data type. - * @param range - * The time range of the requested events. You can use - * {@link TmfTimeRange#ETERNITY} to indicate you want to cover - * the whole trace. - * @param index - * The index of the first event to retrieve. You can use '0' to - * start at the beginning of the trace. - * @param nbRequested - * The number of events requested. You can use - * {@link TmfEventRequest#ALL_DATA} to indicate you want all - * events in the time range. - * @param priority - * The requested execution priority. - */ - public TmfEventRequest(Class dataType, - TmfTimeRange range, - long index, - int nbRequested, - ExecutionType priority) { - - fRequestId = fRequestNumber++; - fDataType = dataType; - fIndex = index; - fNbRequested = nbRequested; - fExecType = priority; - fRange = range; - fNbRead = 0; - - fRequestRunning = false; - fRequestCompleted = false; - fRequestFailed = false; - fRequestCanceled = false; - - /* Setup the request tracing if it's enabled */ - if (TmfCoreTracer.isRequestTraced()) { - String type = getClass().getName(); - type = type.substring(type.lastIndexOf('.') + 1); - @SuppressWarnings("nls") - String message = "CREATED " - + (getExecType() == ExecutionType.BACKGROUND ? "(BG)" : "(FG)") - + " Type=" + type + " Index=" + getIndex() + " NbReq=" + getNbRequested() - + " Range=" + getRange() - + " DataType=" + getDataType().getSimpleName(); - TmfCoreTracer.traceRequest(this, message); - } - } - - /** - * Resets the request counter (used for testing) - */ - public static void reset() { - fRequestNumber = 0; - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - @Override - public int getRequestId() { - return fRequestId; - } - - @Override - public long getIndex() { - return fIndex; - } - - /** - * @since 3.0 - */ - @Override - public ExecutionType getExecType() { - return fExecType; - } - - @Override - public int getNbRequested() { - return fNbRequested; - } - - @Override - public synchronized int getNbRead() { - return fNbRead; - } - - @Override - public synchronized boolean isRunning() { - return fRequestRunning; - } - - @Override - public synchronized boolean isCompleted() { - return fRequestCompleted; - } - - @Override - public synchronized boolean isFailed() { - return fRequestFailed; - } - - @Override - public synchronized boolean isCancelled() { - return fRequestCanceled; - } - - @Override - public Class getDataType() { - return fDataType; - } - - @Override - public TmfTimeRange getRange() { - return fRange; - } - - // ------------------------------------------------------------------------ - // Setters - // ------------------------------------------------------------------------ - - /** - * This method is called by the event provider to set the index - * corresponding to the time range start time - * - * @param index - * The start time index - */ - protected void setIndex(int index) { - fIndex = index; - } - - @Override - public void setStartIndex(int index) { - setIndex(index); - } - - // ------------------------------------------------------------------------ - // Operators - // ------------------------------------------------------------------------ - - @Override - public void handleData(ITmfEvent event) { - fNbRead++; - } - - @Override - public void handleStarted() { - if (TmfCoreTracer.isRequestTraced()) { - TmfCoreTracer.traceRequest(this, "STARTED"); //$NON-NLS-1$ - } - } - - @Override - public void handleCompleted() { - boolean requestFailed = false; - boolean requestCanceled = false; - synchronized (this) { - requestFailed = fRequestFailed; - requestCanceled = fRequestCanceled; - } - - if (requestFailed) { - handleFailure(); - } else if (requestCanceled) { - handleCancel(); - } else { - handleSuccess(); - } - if (TmfCoreTracer.isRequestTraced()) { - TmfCoreTracer.traceRequest(this, "COMPLETED (" + fNbRead + " events read)"); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - @Override - public void handleSuccess() { - if (TmfCoreTracer.isRequestTraced()) { - TmfCoreTracer.traceRequest(this, "SUCCEEDED"); //$NON-NLS-1$ - } - } - - @Override - public void handleFailure() { - if (TmfCoreTracer.isRequestTraced()) { - TmfCoreTracer.traceRequest(this, "FAILED"); //$NON-NLS-1$ - } - } - - @Override - public void handleCancel() { - if (TmfCoreTracer.isRequestTraced()) { - TmfCoreTracer.traceRequest(this, "CANCELLED"); //$NON-NLS-1$ - } - } - - /** - * To suspend the client thread until the request starts (or is canceled). - * - * @throws InterruptedException - * If the thread was interrupted while waiting - */ - public void waitForStart() throws InterruptedException { - while (!fRequestRunning) { - startedLatch.await(); - } - } - - @Override - public void waitForCompletion() throws InterruptedException { - while (!fRequestCompleted) { - completedLatch.await(); - } - } - - @Override - public void start() { - synchronized (this) { - fRequestRunning = true; - } - handleStarted(); - startedLatch.countDown(); - } - - @Override - public void done() { - synchronized (this) { - if (!fRequestCompleted) { - fRequestRunning = false; - fRequestCompleted = true; - } else { - return; - } - } - try { - handleCompleted(); - } finally { - completedLatch.countDown(); - } - } - - @Override - public void fail() { - synchronized (this) { - fRequestFailed = true; - } - done(); - } - - @Override - public void cancel() { - synchronized (this) { - fRequestCanceled = true; - } - done(); - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - // All requests have a unique id - public int hashCode() { - return getRequestId(); - } - - @Override - public boolean equals(Object other) { - if (other instanceof TmfEventRequest) { - TmfEventRequest request = (TmfEventRequest) other; - return request.fDataType == fDataType - && request.fIndex == fIndex - && request.fNbRequested == fNbRequested - && request.fRange.equals(fRange); - } - return false; - } - - @Override - public String toString() { - String name = getClass().getName(); - int dot = name.lastIndexOf('.'); - if (dot >= 0) { - name = name.substring(dot + 1); - } - return '[' + name + '(' + getRequestId() + ',' + getDataType().getSimpleName() + - ',' + getExecType() + ',' + getRange() + ',' + getIndex() + - ',' + getNbRequested() + ")]"; //$NON-NLS-1$ - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfEndSynchSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfEndSynchSignal.java deleted file mode 100644 index f4a0f4203b..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfEndSynchSignal.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -/** - * End of signal synchronization - * - * @version 1.0 - * @author Francois Chouinard - */ -public class TmfEndSynchSignal extends TmfSignal { - - /** - * Constructor - * - * @param synchId - * The ID assigned to this signal - */ - public TmfEndSynchSignal(int synchId) { - super(null, synchId); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfEventFilterAppliedSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfEventFilterAppliedSignal.java deleted file mode 100644 index bff7197651..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfEventFilterAppliedSignal.java +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -import org.eclipse.linuxtools.tmf.core.filter.ITmfFilter; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Signal indicating an event filter has been applied. - * - * @version 1.0 - * @author Patrick Tasse - * @since 2.0 - */ -public class TmfEventFilterAppliedSignal extends TmfSignal { - - private final ITmfTrace fTrace; - private final ITmfFilter fEventFilter; - - /** - * Constructor for a new signal. - * - * @param source - * The object sending this signal - * @param trace - * The trace to which filter is applied - * @param filter - * The applied event filter or null - */ - public TmfEventFilterAppliedSignal(Object source, ITmfTrace trace, ITmfFilter filter) { - super(source); - fTrace = trace; - fEventFilter = filter; - } - - /** - * Get the trace object concerning this signal - * - * @return The trace - */ - public ITmfTrace getTrace() { - return fTrace; - } - - /** - * Get the event filter being applied - * - * @return The filter - */ - public ITmfFilter getEventFilter() { - return fEventFilter; - } - - @Override - public String toString() { - return "[TmfEventFilterAppliedSignal (" + fTrace.getName() + " : " + fEventFilter + ")]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfEventSearchAppliedSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfEventSearchAppliedSignal.java deleted file mode 100644 index ab13c334d4..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfEventSearchAppliedSignal.java +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -import org.eclipse.linuxtools.tmf.core.filter.ITmfFilter; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Signal indicating an event search has been applied. - * - * @version 1.0 - * @author Patrick Tasse - * @since 2.0 - */ -public class TmfEventSearchAppliedSignal extends TmfSignal { - - private final ITmfTrace fTrace; - private final ITmfFilter fSearchFilter; - - /** - * Constructor for a new signal. - * - * @param source - * The object sending this signal - * @param trace - * The trace to which search is applied - * @param filter - * The applied search filter or null - */ - public TmfEventSearchAppliedSignal(Object source, ITmfTrace trace, ITmfFilter filter) { - super(source); - fTrace = trace; - fSearchFilter = filter; - } - - /** - * Get the trace object concerning this signal - * - * @return The trace - */ - public ITmfTrace getTrace() { - return fTrace; - } - - /** - * Get the search filter being applied - * - * @return The search filter - */ - public ITmfFilter getSearchFilter() { - return fSearchFilter; - } - - @Override - public String toString() { - return "[TmfSearchFilterAppliedSignal (" + fTrace.getName() + " : " + fSearchFilter + ")]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfEventSelectedSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfEventSelectedSignal.java deleted file mode 100644 index 53b5e0d54e..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfEventSelectedSignal.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; - -/** - * Signal indicating a trace event has been selected. - * - * The specified event has been selected. - * - * @author Patrick Tasse - * @since 3.2 - */ -public class TmfEventSelectedSignal extends TmfSignal { - - private final ITmfEvent fEvent; - - /** - * Constructor - * - * @param source - * Object sending this signal - * @param event - * The event that was selected - */ - public TmfEventSelectedSignal(Object source, ITmfEvent event) { - super(source); - fEvent = event; - } - - /** - * @return The event referred to by this signal - */ - public ITmfEvent getEvent() { - return fEvent; - } - - @Override - public String toString() { - return "[TmfEventSelectedSignal (" + fEvent.toString() + ")]"; //$NON-NLS-1$ //$NON-NLS-2$ - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfRangeSynchSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfRangeSynchSignal.java deleted file mode 100644 index 7d2e00ad68..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfRangeSynchSignal.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Deprecate current time - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; - -/** - * A new time range has been selected. - * - * This is the visible (zoom) time range. To synchronize on the selection range, - * use {@link TmfTimeSynchSignal}. - * - * @version 1.0 - * @author Francois Chouinard - */ -public class TmfRangeSynchSignal extends TmfSignal { - - private final TmfTimeRange fCurrentRange; - - /** - * Constructor - * - * @param source - * Object sending this signal - * @param range - * The new time range - * @since 2.1 - */ - public TmfRangeSynchSignal(Object source, TmfTimeRange range) { - super(source); - fCurrentRange = range; - } - - /** - * @return This signal's time range - * @since 2.0 - */ - public TmfTimeRange getCurrentRange() { - return fCurrentRange; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignal.java deleted file mode 100644 index 3304828c18..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignal.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -/** - * Base class for TMF signals - * - * @version 1.0 - * @author Francois Chouinard - */ -public abstract class TmfSignal { - - private final Object fSource; - private int fReference; - - /** - * Basic constructor, which uses a default of "0" for the reference index - * - * @param source - * Object sending this signal - */ - public TmfSignal(Object source) { - this(source, 0); - } - - /** - * Standard constructor - * - * @param source - * Object sending this signal - * @param reference - * Reference index to assign to this signal - */ - public TmfSignal(Object source, int reference) { - fSource = source; - fReference = reference; - } - - /** - * @return The source object of this signal - */ - public Object getSource() { - return fSource; - } - - /** - * Change this signal's reference index - * - * @param reference - * The new reference to use - */ - public void setReference(int reference) { - fReference = reference; - } - - /** - * @return This signal's reference index - */ - public int getReference() { - return fReference; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignalHandler.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignalHandler.java deleted file mode 100644 index caff3db90a..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignalHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marker for TMF signal handlers. - * - * @version 1.0 - * @author Francois Chouinard - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface TmfSignalHandler { - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignalManager.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignalManager.java deleted file mode 100644 index 90e34ed704..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignalManager.java +++ /dev/null @@ -1,231 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Update register methods - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.internal.tmf.core.TmfCoreTracer; - -/** - * This class manages the set of signal listeners and the signals they are - * interested in. When a signal is broadcasted, the appropriate listeners - * signal handlers are invoked. - * - * @version 1.0 - * @author Francois Chouinard - */ -public class TmfSignalManager { - - // The set of event listeners and their corresponding handler methods. - // Note: listeners could be restricted to ITmfComponents but there is no - // harm in letting anyone use this since it is not tied to anything but - // the signal data type. - private static Map fListeners = new HashMap<>(); - private static Map fVIPListeners = new HashMap<>(); - - // The signal executor for asynchronous signals - private static final ExecutorService fExecutor = Executors.newSingleThreadExecutor(); - - // If requested, add universal signal tracer - // TODO: Temporary solution: should be enabled/disabled dynamically - private static boolean fTraceIsActive = false; - private static TmfSignalTracer fSignalTracer; - - static { - if (fTraceIsActive) { - fSignalTracer = TmfSignalTracer.getInstance(); - register(fSignalTracer); - } - } - - /** - * Register an object to the signal manager. This object can then implement - * handler methods, marked with @TmfSignalHandler and with the expected - * signal type as parameter. - * - * @param listener - * The object that will be notified of new signals - */ - public static synchronized void register(Object listener) { - deregister(listener); // make sure that listener is only registered once - Method[] methods = getSignalHandlerMethods(listener); - if (methods.length > 0) { - fListeners.put(listener, methods); - } - } - - /** - * Register an object to the signal manager as a "VIP" listener. All VIP - * listeners will all receive the signal before the manager moves on to the - * lowly, non-VIP listeners. - * - * @param listener - * The object that will be notified of new signals - */ - public static synchronized void registerVIP(Object listener) { - deregister(listener); // make sure that listener is only registered once - Method[] methods = getSignalHandlerMethods(listener); - if (methods.length > 0) { - fVIPListeners.put(listener, methods); - } - } - - /** - * De-register a listener object from the signal manager. This means that - * its @TmfSignalHandler methods will no longer be called. - * - * @param listener - * The object to de-register - */ - public static synchronized void deregister(Object listener) { - fVIPListeners.remove(listener); - fListeners.remove(listener); - } - - /** - * Returns the list of signal handlers in the listener. Signal handler name - * is irrelevant; only the annotation (@TmfSignalHandler) is important. - * - * @param listener - * @return - */ - private static Method[] getSignalHandlerMethods(Object listener) { - List handlers = new ArrayList<>(); - Method[] methods = listener.getClass().getMethods(); - for (Method method : methods) { - if (method.isAnnotationPresent(TmfSignalHandler.class)) { - handlers.add(method); - } - } - return handlers.toArray(new Method[handlers.size()]); - } - - static int fSignalId = 0; - - /** - * Invokes the handling methods that listens to signals of a given type in - * the current thread. - * - * The list of handlers is built on-the-fly to allow for the dynamic - * creation/deletion of signal handlers. Since the number of signal handlers - * shouldn't be too high, this is not a big performance issue to pay for the - * flexibility. - * - * For synchronization purposes, the signal is bracketed by two synch - * signals. - * - * @param signal - * the signal to dispatch - */ - public static synchronized void dispatchSignal(TmfSignal signal) { - int signalId = fSignalId++; - sendSignal(new TmfStartSynchSignal(signalId)); - signal.setReference(signalId); - sendSignal(signal); - sendSignal(new TmfEndSynchSignal(signalId)); - } - - /** - * Invokes the handling methods that listens to signals of a given type - * in a separate thread which will call - * {@link TmfSignalManager#dispatchSignal(TmfSignal)}. - * - * If a signal is already processed the signal will be queued and - * dispatched after the ongoing signal finishes. - * - * @param signal - * the signal to dispatch - * @since 3.0 - */ - public static void dispatchSignalAsync(final TmfSignal signal) { - if (!fExecutor.isShutdown()) { - fExecutor.execute(new Runnable() { - @Override - public void run() { - dispatchSignal(signal); - } - }); - } - } - - /** - * Disposes the signal manager - * @since 3.0 - */ - public static void dispose() { - fExecutor.shutdown(); - } - - private static void sendSignal(TmfSignal signal) { - sendSignal(fVIPListeners, signal); - sendSignal(fListeners, signal); - } - - private static void sendSignal(Map listeners, TmfSignal signal) { - - if (TmfCoreTracer.isSignalTraced()) { - TmfCoreTracer.traceSignal(signal, "(start)"); //$NON-NLS-1$ - } - - // Build the list of listener methods that are registered for this signal - Class signalClass = signal.getClass(); - Map> targets = new HashMap<>(); - targets.clear(); - for (Map.Entry entry : listeners.entrySet()) { - List matchingMethods = new ArrayList<>(); - for (Method method : entry.getValue()) { - if (method.getParameterTypes()[0].isAssignableFrom(signalClass)) { - matchingMethods.add(method); - } - } - if (!matchingMethods.isEmpty()) { - targets.put(entry.getKey(), matchingMethods); - } - } - - // Call the signal handlers - for (Map.Entry> entry : targets.entrySet()) { - for (Method method : entry.getValue()) { - try { - method.invoke(entry.getKey(), new Object[] { signal }); - if (TmfCoreTracer.isSignalTraced()) { - Object key = entry.getKey(); - String hash = String.format("%1$08X", entry.getKey().hashCode()); //$NON-NLS-1$ - String target = "[" + hash + "] " + key.getClass().getSimpleName() + ":" + method.getName(); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ - TmfCoreTracer.traceSignal(signal, target); - } - } catch (IllegalArgumentException e) { - Activator.logError("Exception handling signal " + signal + " in method " + method, e); //$NON-NLS-1$ //$NON-NLS-2$ - } catch (IllegalAccessException e) { - Activator.logError("Exception handling signal " + signal + " in method " + method, e); //$NON-NLS-1$ //$NON-NLS-2$ - } catch (InvocationTargetException e) { - Activator.logError("Exception handling signal " + signal + " in method " + method, e); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - } - - if (TmfCoreTracer.isSignalTraced()) { - TmfCoreTracer.traceSignal(signal, "(end)"); //$NON-NLS-1$ - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignalThrottler.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignalThrottler.java deleted file mode 100644 index c5c79ec5e2..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignalThrottler.java +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -import java.util.Timer; -import java.util.TimerTask; - -import org.eclipse.linuxtools.tmf.core.component.ITmfComponent; -import org.eclipse.linuxtools.tmf.core.component.TmfComponent; - -/** - * "Buffer" between a TmfComponent and the signal manager. You can use this if - * you want to throttle the amount of signals your component will send. - * - * It works by specifying a delay, then calling {@link #queue}. The signals will - * only be really sent if no other call to {@link #queue} happens within $delay - * milliseconds afterwards. This guarantees that only the *last* signal is - * actually broadcasted. - * - * Note that this class does not discriminate for signal types, sources, or - * whatever. If you want to throttle different signals in different ways, you - * can use multiple signal throttlers in your component and call them - * accordingly. - * - * @author Alexandre Montplaisir - * @since 2.0 - */ -public class TmfSignalThrottler { - - private final ITmfComponent fComponent; - private final long fDelay; - private final Timer fTimer; - private TimerTask fCurrentTask; - - /** - * Constructor - * - * @param component - * The source component of the signals - * @param delay - * Time to wait before actually sending signals (in ms) - */ - public TmfSignalThrottler(ITmfComponent component, long delay) { - this.fComponent = component; - this.fDelay = delay; - this.fTimer = new Timer(); - - /* - * Initialize currentTask to something, so we don't have to do a null - * check every time - */ - fCurrentTask = new TimerTask() { @Override public void run() {} }; - } - - /** - * Queue a signal for sending. It will only be forward to the centralized - * signal handler if 'delay' elapses without another signal being sent - * through this method. - * - * You call this instead of calling {@link TmfComponent#broadcast}. - * - * @param signal - * The signal to queue for broadcasting - */ - public synchronized void queue(TmfSignal signal) { - fCurrentTask.cancel(); - fCurrentTask = new BroadcastRequest(signal); - fTimer.schedule(fCurrentTask, fDelay); - } - - /** - * Dispose method. Will prevent any pending signal from being sent, and this - * throttler from be used again. - */ - public synchronized void dispose() { - fTimer.cancel(); - fTimer.purge(); - } - - private class BroadcastRequest extends TimerTask { - - private final TmfSignal signal; - - BroadcastRequest(TmfSignal signal) { - this.signal = signal; - } - - @Override - public void run() { - fComponent.broadcast(signal); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignalTracer.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignalTracer.java deleted file mode 100644 index 66106920c6..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfSignalTracer.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -/** - * This object (singleton) traces all TmfSignals in the application. - * - * @version 1.0 - * @author Francois Chouinard - */ -public class TmfSignalTracer { - - static TmfSignalTracer fInstance; - - /** - * @return The single instance of the signal tracer object - */ - static public TmfSignalTracer getInstance() { - if (fInstance == null) { - fInstance = new TmfSignalTracer(); - } - return fInstance; - } - - private TmfSignalTracer() { - } - - /** - * Handler for all TMF signal types - * - * @param signal - * Incoming signal - */ - @TmfSignalHandler - public void traceSignal(TmfSignal signal) { - System.out.println(signal.getSource().toString() + ": " + signal.toString()); //$NON-NLS-1$ - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfStartAnalysisSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfStartAnalysisSignal.java deleted file mode 100644 index 5542a2cbf6..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfStartAnalysisSignal.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule; - -/** - * Signal indicating an analysis has started. Views and outputs may use it to - * update themselves with the results. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfStartAnalysisSignal extends TmfSignal { - - private final IAnalysisModule fModule; - - /** - * Constructor for a new signal. - * - * @param source - * The object sending this signal - * @param module - * The analysis module - */ - public TmfStartAnalysisSignal(Object source, IAnalysisModule module) { - super(source); - fModule = module; - } - - /** - * Get the trace object concerning this signal - * - * @return The trace - */ - public IAnalysisModule getAnalysisModule() { - return fModule; - } - - @Override - public String toString() { - return "[" + this.getClass().getSimpleName() + " (" + fModule.getName() + ")]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfStartSynchSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfStartSynchSignal.java deleted file mode 100644 index 5dd85a331c..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfStartSynchSignal.java +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -/** - * Start of signal synchronization - * - * @version 1.0 - * @author Francois Chouinard - */ -public class TmfStartSynchSignal extends TmfSignal { - - - /** - * Constructor - * - * @param synchId - * The synch ID of this signal - */ - public TmfStartSynchSignal(int synchId) { - super(null, synchId); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTimeSynchSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTimeSynchSignal.java deleted file mode 100644 index 02fd8886a6..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTimeSynchSignal.java +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Support selection range - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; - -/** - * A new time or time range selection has been made. - * - * This is the selected time or time range. To synchronize on the visible - * (zoom) range, use {@link TmfRangeSynchSignal}. - * - * @version 1.0 - * @author Francois Chouinard -*/ -public class TmfTimeSynchSignal extends TmfSignal { - - private final ITmfTimestamp fBeginTime; - private final ITmfTimestamp fEndTime; - - /** - * Constructor - * - * @param source - * Object sending this signal - * @param ts - * Timestamp of selection - * @since 2.0 - */ - public TmfTimeSynchSignal(Object source, ITmfTimestamp ts) { - super(source); - fBeginTime = ts; - fEndTime = ts; - } - - /** - * Constructor - * - * @param source - * Object sending this signal - * @param begin - * Timestamp of begin of selection range - * @param end - * Timestamp of end of selection range - * @since 2.1 - */ - public TmfTimeSynchSignal(Object source, ITmfTimestamp begin, ITmfTimestamp end) { - super(source); - fBeginTime = begin; - fEndTime = end; - } - - /** - * @return The begin timestamp of selection - * @since 2.1 - */ - public ITmfTimestamp getBeginTime() { - return fBeginTime; - } - - /** - * @return The end timestamp of selection - * @since 2.1 - */ - public ITmfTimestamp getEndTime() { - return fEndTime; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("[TmfTimeSynchSignal ("); //$NON-NLS-1$ - if (fBeginTime != null) { - sb.append(fBeginTime.toString()); - if (!fBeginTime.equals(fEndTime) && fEndTime != null) { - sb.append('-'); - sb.append(fEndTime.toString()); - } - } - sb.append(")]"); //$NON-NLS-1$ - return sb.toString(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTimestampFormatUpdateSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTimestampFormatUpdateSignal.java deleted file mode 100644 index 2b25fd0aab..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTimestampFormatUpdateSignal.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -/** - * The default timestamp/interval format was modified - * - * @author Francois Chouinard - * @version 1.0 - * @since 2.0 - */ -public class TmfTimestampFormatUpdateSignal extends TmfSignal { - - /** - * @param source the signal source - */ - public TmfTimestampFormatUpdateSignal(Object source) { - super(source); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceClosedSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceClosedSignal.java deleted file mode 100644 index 9f9f2fa5ee..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceClosedSignal.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Signal indicating a trace is being closed. - * - * Receivers should cancel any jobs, threads or requests for the specified trace - * and clear any user interface component related to it as soon as possible. - * The trace will be disposed after the signal has been processed. - * - * @version 1.0 - * @author Patrick Tasse - * @since 2.0 - */ -@NonNullByDefault -public class TmfTraceClosedSignal extends TmfSignal { - - private final ITmfTrace fTrace; - - /** - * Constructor for a new signal - * - * @param source - * The object sending this signal - * @param trace - * The trace being closed - */ - public TmfTraceClosedSignal(Object source, ITmfTrace trace) { - super(source); - fTrace = trace; - } - - /** - * Get a reference to the trace being closed - * - * @return The trace object - */ - public ITmfTrace getTrace() { - return fTrace; - } - - @Override - public String toString() { - return "[TmfTraceClosedSignal (" + fTrace.getName() + ")]"; //$NON-NLS-1$ //$NON-NLS-2$ - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceOpenedSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceOpenedSignal.java deleted file mode 100644 index 962b9af6b9..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceOpenedSignal.java +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -import org.eclipse.core.resources.IFile; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Signal indicating a trace has been opened. - * - * Receivers can get ready to receive TmfTraceRangeUpdatedSignal for coalescing - * and can expect TmfTraceSelectedSignal to follow. - * - * @version 1.0 - * @author Patrick Tasse - * @since 2.0 - */ -public class TmfTraceOpenedSignal extends TmfSignal { - - private final ITmfTrace fTrace; - private final IFile fEditorFile; - - /** - * Constructor for a new signal. - * - * @param source - * The object sending this signal - * @param trace - * The trace that has been opened - * @param editorFile - * Pointer to the editor file - */ - public TmfTraceOpenedSignal(Object source, ITmfTrace trace, IFile editorFile) { - super(source); - fTrace = trace; - fEditorFile = editorFile; - } - - /** - * Get the trace object concerning this signal - * - * @return The trace - */ - public ITmfTrace getTrace() { - return fTrace; - } - - /** - * Get a pointer to the editor file for this trace - * - * @return The IFile object - * @since 3.0 - */ - public IFile getEditorFile() { - return fEditorFile; - } - - @Override - public String toString() { - return "[TmfTraceOpenedSignal (" + fTrace.getName() + ")]"; //$NON-NLS-1$ //$NON-NLS-2$ - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceRangeUpdatedSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceRangeUpdatedSignal.java deleted file mode 100644 index 57e259801b..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceRangeUpdatedSignal.java +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Signal indicating a trace range has been updated. - * - * Receivers can safely perform event requests for the specified time range. - * The signal acts as a trigger for coalescing such requests. - * - * @version 1.0 - * @author Patrick Tasse - * @since 2.0 - */ -public class TmfTraceRangeUpdatedSignal extends TmfSignal { - - private final ITmfTrace fTrace; - private final TmfTimeRange fTimeRange; - - /** - * Constructor - * - * @param source - * Object sending this signal - * @param trace - * Trace whose range was updated - * @param range - * The new time range of the trace - */ - public TmfTraceRangeUpdatedSignal(Object source, ITmfTrace trace, TmfTimeRange range) { - super(source); - fTrace = trace; - fTimeRange = range; - } - - /** - * @return The trace - */ - public ITmfTrace getTrace() { - return fTrace; - } - - /** - * @return The time range - */ - public TmfTimeRange getRange() { - return fTimeRange; - } - - @Override - @SuppressWarnings("nls") - public String toString() { - return "[TmfTraceRangeUpdatedSignal (" + fTrace.getName() + ", " + fTimeRange.toString() + ")]"; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceSelectedSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceSelectedSignal.java deleted file mode 100644 index 8292888e45..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceSelectedSignal.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Signal indicating a trace has been selected. - * - * The specified trace is the active trace and has been brought to top - * or the signal is used as a trigger to bring it to top. - * - * @version 1.0 - * @author Patrick Tasse - */ -public class TmfTraceSelectedSignal extends TmfSignal { - - private final ITmfTrace fTrace; - - /** - * Constructor - * - * @param source - * Object sending this signal - * @param trace - * The trace that was selected - */ - public TmfTraceSelectedSignal(Object source, ITmfTrace trace) { - super(source); - fTrace = trace; - } - - /** - * @return The trace referred to by this signal - */ - public ITmfTrace getTrace() { - return fTrace; - } - - @Override - public String toString() { - return "[TmfTraceSelectedSignal (" + fTrace.getName() + ")]"; //$NON-NLS-1$ //$NON-NLS-2$ - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceSynchronizedSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceSynchronizedSignal.java deleted file mode 100644 index fa24bbf702..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceSynchronizedSignal.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithm; - -/** - * Signal indicating a trace synchronization has been done - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfTraceSynchronizedSignal extends TmfSignal { - - private final SynchronizationAlgorithm fAlgoSync; - - /** - * Constructor - * - * @param source - * Object sending this signal - * @param algoSync - * The synchronization algorithm used - */ - public TmfTraceSynchronizedSignal(Object source, SynchronizationAlgorithm algoSync) { - super(source); - fAlgoSync = algoSync; - } - - /** - * Synchronization algorithm getter - * - * @return The algorithm object - */ - public SynchronizationAlgorithm getSyncAlgo() { - return fAlgoSync; - } - - @Override - public String toString() { - return "[" + getClass().getSimpleName() + " (" + fAlgoSync.toString() + ")]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceUpdatedSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceUpdatedSignal.java deleted file mode 100644 index 73ecbfbe5d..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceUpdatedSignal.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.signal; - -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Signal indicating a trace has been updated. - * - * The trace has been indexed up to the specified range. - * - * @version 1.0 - * @author Francois Chouinard - */ -public class TmfTraceUpdatedSignal extends TmfSignal { - - private final ITmfTrace fTrace; - private final TmfTimeRange fTimeRange; - private final long fNbEvents; - - /** - * Constructor - * - * @param source - * Object sending this signal - * @param trace - * The trace that was updated - * @param range - * The new time range of the trace - * @param nbEvents - * The number of events in the trace - * @since 3.0 - */ - public TmfTraceUpdatedSignal(Object source, ITmfTrace trace, TmfTimeRange range, long nbEvents) { - super(source); - fTrace = trace; - fTimeRange = range; - fNbEvents = nbEvents; - } - - /** - * @return The trace referred to by this signal - */ - public ITmfTrace getTrace() { - return fTrace; - } - - /** - * @return The time range indicated by this signal - * @since 2.0 - */ - public TmfTimeRange getRange() { - return fTimeRange; - } - - /** - * Returns the number of events indicated by this signal - * - * @return the number of events indicated by this signal - * @since 3.0 - */ - public long getNbEvents() { - return fNbEvents; - } - - @Override - @SuppressWarnings("nls") - public String toString() { - return "[TmfTraceUpdatedSignal (" + fTrace.toString() + ", " - + fTimeRange.toString() + ")]"; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/AbstractTmfStateProvider.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/AbstractTmfStateProvider.java deleted file mode 100644 index 54209c808c..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/AbstractTmfStateProvider.java +++ /dev/null @@ -1,243 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.statesystem; - -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; - -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Instead of using IStateChangeInput directly, one can extend this class, which - * defines a lot of the common functions of the state change input plugin. - * - * It will handle the state-system-processing in a separate thread, which is - * normally not a bad idea for traces of some size. - * - * processEvent() is replaced with eventHandle(), so that all the multi-thread - * logic is abstracted away. - * - * @author Alexandre Montplaisir - * @since 2.0 - */ -public abstract class AbstractTmfStateProvider implements ITmfStateProvider { - - private static final int DEFAULT_EVENTS_QUEUE_SIZE = 10000; - - private final ITmfTrace trace; - private final Class eventType; - private final BlockingQueue eventsQueue; - private final Thread eventHandlerThread; - - private boolean ssAssigned; - - /** State system in which to insert the state changes */ - protected ITmfStateSystemBuilder ss = null; - - /** - * Instantiate a new state provider plugin. - * - * @param trace - * The LTTng 2.0 kernel trace directory - * @param eventType - * The specific class for the event type that will be used within - * the subclass - * @param id - * Name given to this state change input. Only used internally. - */ - public AbstractTmfStateProvider(ITmfTrace trace, - Class eventType, String id) { - this.trace = trace; - this.eventType = eventType; - eventsQueue = new ArrayBlockingQueue<>(DEFAULT_EVENTS_QUEUE_SIZE); - ssAssigned = false; - - String id2 = (id == null ? "Unamed" : id); //$NON-NLS-1$ - eventHandlerThread = new Thread(new EventProcessor(), id2 + " Event Handler"); //$NON-NLS-1$ - } - - @Override - public ITmfTrace getTrace() { - return trace; - } - - /** - * @since 3.0 - */ - @Override - public long getStartTime() { - return trace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - } - - /** - * @since 3.0 - */ - @Override - public void assignTargetStateSystem(ITmfStateSystemBuilder ssb) { - ss = ssb; - ssAssigned = true; - eventHandlerThread.start(); - } - - /** - * @since 3.0 - */ - @Override - public ITmfStateSystem getAssignedStateSystem() { - return ss; - } - - @Override - public void dispose() { - /* Insert a null event in the queue to stop the event handler's thread. */ - try { - eventsQueue.put(END_EVENT); - eventHandlerThread.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - ssAssigned = false; - ss = null; - } - - @Override - public final Class getExpectedEventType() { - return eventType; - } - - @Override - public final void processEvent(ITmfEvent event) { - /* Make sure the target state system has been assigned */ - if (!ssAssigned) { - System.err.println("Cannot process event without a target state system"); //$NON-NLS-1$ - return; - } - - /* Insert the event we're received into the events queue */ - ITmfEvent curEvent = event; - try { - eventsQueue.put(curEvent); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - /** - * Block the caller until the events queue is empty. - */ - public void waitForEmptyQueue() { - /* - * We will first insert a dummy event that is guaranteed to not modify - * the state. That way, when that event leaves the queue, we will know - * for sure that the state system processed the preceding real event. - */ - try { - eventsQueue.put(EMPTY_QUEUE_EVENT); - while (!eventsQueue.isEmpty()) { - Thread.sleep(100); - } - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - // ------------------------------------------------------------------------ - // Special event types - // ------------------------------------------------------------------------ - - /** Fake event indicating the build is over, and the provider should close */ - private static class EndEvent extends TmfEvent {} - /** Fake event indicating we want to clear the current queue */ - private static class EmptyQueueEvent extends TmfEvent {} - - private static final EndEvent END_EVENT = new EndEvent(); - private static final EmptyQueueEvent EMPTY_QUEUE_EVENT = new EmptyQueueEvent(); - - // ------------------------------------------------------------------------ - // Inner classes - // ------------------------------------------------------------------------ - - /** - * This is the runner class for the second thread, which will take the - * events from the queue and pass them through the state system. - */ - private class EventProcessor implements Runnable { - - private ITmfEvent currentEvent; - - @Override - public void run() { - if (ss == null) { - System.err.println("Cannot run event manager without assigning a target state system first!"); //$NON-NLS-1$ - return; - } - ITmfEvent event; - - try { - event = eventsQueue.take(); - /* This is a singleton, we want to do != instead of !x.equals */ - while (event != END_EVENT) { - if (event == EMPTY_QUEUE_EVENT) { - /* Synchronization event, should be ignored */ - event = eventsQueue.take(); - continue; - } - - currentEvent = event; - - /* Make sure this is an event the sub-class can process */ - if (eventType.isInstance(event) && event.getType() != null) { - eventHandle(event); - } - event = eventsQueue.take(); - } - /* We've received the last event, clean up */ - closeStateSystem(); - } catch (InterruptedException e) { - /* We've been interrupted abnormally */ - System.out.println("Event handler interrupted!"); //$NON-NLS-1$ - e.printStackTrace(); - } - } - - private void closeStateSystem() { - final long endTime = (currentEvent == null) ? 0 : - currentEvent.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - ss.closeHistory(endTime); - } - } - - // ------------------------------------------------------------------------ - // Abstract methods - // ------------------------------------------------------------------------ - - /** - * Handle the given event and send the appropriate state transitions into - * the the state system. - * - * This is basically the same thing as IStateChangeInput.processEvent(), - * except here processEvent() and eventHandle() are run in two different - * threads (and the AbstractStateChangeInput takes care of processEvent() - * already). - * - * @param event - * The event to process. If you need a specific event type, you - * should check for its instance right at the beginning. - */ - protected abstract void eventHandle(ITmfEvent event); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/ITmfAnalysisModuleWithStateSystems.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/ITmfAnalysisModuleWithStateSystems.java deleted file mode 100644 index 4d982d121a..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/ITmfAnalysisModuleWithStateSystems.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.statesystem; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule; - -/** - * Interface for analysis modules providing state systems. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public interface ITmfAnalysisModuleWithStateSystems extends IAnalysisModule { - - /** - * Return a specific state system provided by this analysis. - * - * @param id - * The ID of the state system - * @return The state system corresponding to the given ID, null if there is - * no match. - */ - @Nullable - ITmfStateSystem getStateSystem(@NonNull String id); - - /** - * Return all the state systems provided by this analysis module, in - * Iterable format. - * - * @return The state systems - */ - @NonNull - Iterable getStateSystems(); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/ITmfStateProvider.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/ITmfStateProvider.java deleted file mode 100644 index 379fa4dc3c..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/ITmfStateProvider.java +++ /dev/null @@ -1,119 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * Copyright (c) 2010, 2011 École Polytechnique de Montréal - * Copyright (c) 2010, 2011 Alexandre Montplaisir - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.statesystem; - -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * This is the interface used to define the "state change input", which is the - * main type of input that goes in the state system. - * - * Usually a state change input, also called "state provider" is the piece of - * the pipeline which converts trace events to state changes. - * - * @author Alexandre Montplaisir - * @since 2.0 - */ -public interface ITmfStateProvider { - - /** - * Event handler plugins should provide a version number. This is used to - * determine if a potential existing file can be re-opened later (if the - * versions in the file and in the viewer match), or if the file should be - * rebuilt from scratch (if the versions don't match). - * - * @return The version number of the input plugin - * @since 2.0 - */ - int getVersion(); - - /** - * Get the trace with which this state input plugin is associated. - * - * @return The associated trace - */ - ITmfTrace getTrace(); - - /** - * Return the start time of this "state change input", which is normally the - * start time of the originating trace (or it can be the time of the first - * state-changing event). - * - * @return The start time - */ - long getStartTime(); - - /** - * Method for the input plugin to specify which type of events it expects. - * This will guarantee that all events it receives via processEvent() are - * indeed of the given type, so it should be safe to cast to that type. - * - * @return The expected Class of the event. Only events of this class (and - * valid subclasses) will be handled. - * @since 2.0 - */ - Class getExpectedEventType(); - - /** - * Assign the target state system where this SCI will insert its state - * changes. Because of dependencies issues, this can normally not be done at - * the constructor. - * - * This needs to be called before .run()! - * - * @param ssb - * Target state system for the state changes generated by this - * input plugin - * @since 3.0 - */ - void assignTargetStateSystem(ITmfStateSystemBuilder ssb); - - /** - * Return the currently assigned target state system. - * - * @return Reference to the currently assigned state system, or null if no - * SS is assigned yet - * @since 3.0 - */ - ITmfStateSystem getAssignedStateSystem(); - - /** - * Send an event to this input plugin for processing. The implementation - * should check the contents, and call the state-modifying methods of its - * IStateSystemBuilder object accordingly. - * - * @param event - * The event (which should be safe to cast to the - * expectedEventType) that has to be processed. - */ - void processEvent(ITmfEvent event); - - /** - * Provide a non-initialized copy of this state input plugin. You will need - * to call {@link #assignTargetStateSystem} on it to assign its target. - * - * @return A new state change input object, of the same type, but without an - * assigned target state system - * @since 2.0 - */ - ITmfStateProvider getNewInstance(); - - /** - * Indicate to the state history building process that we are done (for now), - * and that it should close its current history. - */ - void dispose(); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/TmfStateSystemAnalysisModule.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/TmfStateSystemAnalysisModule.java deleted file mode 100644 index 17f8fa57b6..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/TmfStateSystemAnalysisModule.java +++ /dev/null @@ -1,501 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - * Bernd Hufmann - Integrated history builder functionality - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.statesystem; - -import java.io.File; -import java.io.IOException; -import java.util.Collections; -import java.util.concurrent.CountDownLatch; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.partial.PartialHistoryBackend; -import org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.partial.PartialStateSystem; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; -import org.eclipse.linuxtools.statesystem.core.StateSystemFactory; -import org.eclipse.linuxtools.statesystem.core.backend.IStateHistoryBackend; -import org.eclipse.linuxtools.statesystem.core.backend.InMemoryBackend; -import org.eclipse.linuxtools.statesystem.core.backend.NullBackend; -import org.eclipse.linuxtools.statesystem.core.backend.historytree.HistoryTreeBackend; -import org.eclipse.linuxtools.statesystem.core.backend.historytree.ThreadedHistoryTreeBackend; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAbstractAnalysisModule; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; - -/** - * Abstract analysis module to generate a state system. It is a base class that - * can be used as a shortcut by analysis who just need to build a single state - * system with a state provider. - * - * Analysis implementing this class should only need to provide a state system - * and optionally a backend (default to NULL) and, if required, a filename - * (defaults to the analysis'ID) - * - * @author Geneviève Bastien - * @since 3.0 - */ -@NonNullByDefault -public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisModule - implements ITmfAnalysisModuleWithStateSystems { - - private static final String EXTENSION = ".ht"; //$NON-NLS-1$ - - private final CountDownLatch fInitialized = new CountDownLatch(1); - - @Nullable private ITmfStateSystemBuilder fStateSystem; - @Nullable private ITmfStateProvider fStateProvider; - @Nullable private IStateHistoryBackend fHtBackend; - @Nullable private ITmfEventRequest fRequest; - - /** - * State system backend types - * - * @author Geneviève Bastien - */ - protected enum StateSystemBackendType { - /** Full history in file */ - FULL, - /** In memory state system */ - INMEM, - /** Null history */ - NULL, - /** State system backed with partial history */ - PARTIAL - } - - - /** - * Retrieve a state system belonging to trace, by passing the ID of the - * relevant analysis module. - * - * This will start the execution of the analysis module, and start the - * construction of the state system, if needed. - * - * @param trace - * The trace for which you want the state system - * @param moduleId - * The ID of the state system analysis module - * @return The state system, or null if there was no match - * @since 3.1 - */ - public static @Nullable ITmfStateSystem getStateSystem(ITmfTrace trace, String moduleId) { - TmfStateSystemAnalysisModule module = - trace.getAnalysisModuleOfClass(TmfStateSystemAnalysisModule.class, moduleId); - if (module != null) { - module.schedule(); - module.waitForInitialization(); - /* - * FIXME If we keep a reference to "module", the compiler expects us to - * close it. The Analysis Module's API should be reworked to not expose - * these objects directly (utility classes instead?) - */ - return module.getStateSystem(); - } - return null; - } - - /** - * Get the state provider for this analysis module - * - * @return the state provider - */ - protected abstract ITmfStateProvider createStateProvider(); - - /** - * Get the state system backend type used by this module - * - * @return The {@link StateSystemBackendType} - */ - protected StateSystemBackendType getBackendType() { - /* Using full history by default, sub-classes can override */ - return StateSystemBackendType.FULL; - } - - /** - * Get the supplementary file name where to save this state system. The - * default is the ID of the analysis followed by the extension. - * - * @return The supplementary file name - */ - protected String getSsFileName() { - return getId() + EXTENSION; - } - - /** - * Get the state system generated by this analysis, or null if it is not yet - * created. - * - * @return The state system - */ - @Nullable - public ITmfStateSystem getStateSystem() { - return fStateSystem; - } - - /** - * Block the calling thread until the analysis module has been initialized. - * After this method returns, {@link #getStateSystem()} should not return - * null anymore. - */ - public void waitForInitialization() { - try { - fInitialized.await(); - } catch (InterruptedException e) {} - } - - // ------------------------------------------------------------------------ - // TmfAbstractAnalysisModule - // ------------------------------------------------------------------------ - - @Override - protected boolean executeAnalysis(@Nullable final IProgressMonitor monitor) { - IProgressMonitor mon = (monitor == null ? new NullProgressMonitor() : monitor); - final ITmfStateProvider provider = createStateProvider(); - - String id = getId(); - - /* FIXME: State systems should make use of the monitor, to be cancelled */ - try { - /* Get the state system according to backend */ - StateSystemBackendType backend = getBackendType(); - String directory; - File htFile; - switch (backend) { - case FULL: - directory = TmfTraceManager.getSupplementaryFileDir(getTrace()); - htFile = new File(directory + getSsFileName()); - createFullHistory(id, provider, htFile); - break; - case PARTIAL: - directory = TmfTraceManager.getSupplementaryFileDir(getTrace()); - htFile = new File(directory + getSsFileName()); - createPartialHistory(id, provider, htFile); - break; - case INMEM: - createInMemoryHistory(id, provider); - break; - case NULL: - createNullHistory(id, provider); - break; - default: - break; - } - } catch (TmfTraceException e) { - return false; - } - return !mon.isCanceled(); - } - - @Override - protected void canceling() { - ITmfEventRequest req = fRequest; - if ((req != null) && (!req.isCompleted())) { - req.cancel(); - } - } - - @Override - public void dispose() { - super.dispose(); - if (fStateSystem != null) { - fStateSystem.dispose(); - } - } - - // ------------------------------------------------------------------------ - // History creation methods - // ------------------------------------------------------------------------ - - /* - * Load the history file matching the target trace. If the file already - * exists, it will be opened directly. If not, it will be created from - * scratch. - */ - private void createFullHistory(String id, ITmfStateProvider provider, File htFile) throws TmfTraceException { - - /* If the target file already exists, do not rebuild it uselessly */ - // TODO for now we assume it's complete. Might be a good idea to check - // at least if its range matches the trace's range. - - if (htFile.exists()) { - /* Load an existing history */ - final int version = provider.getVersion(); - try { - IStateHistoryBackend backend = new HistoryTreeBackend(htFile, version); - fHtBackend = backend; - fStateSystem = StateSystemFactory.newStateSystem(id, backend, false); - fInitialized.countDown(); - return; - } catch (IOException e) { - /* - * There was an error opening the existing file. Perhaps it was - * corrupted, perhaps it's an old version? We'll just - * fall-through and try to build a new one from scratch instead. - */ - } - } - - /* Size of the blocking queue to use when building a state history */ - final int QUEUE_SIZE = 10000; - - try { - IStateHistoryBackend backend = new ThreadedHistoryTreeBackend(htFile, - provider.getStartTime(), provider.getVersion(), QUEUE_SIZE); - fHtBackend = backend; - fStateSystem = StateSystemFactory.newStateSystem(id, backend); - provider.assignTargetStateSystem(fStateSystem); - build(provider); - } catch (IOException e) { - /* - * If it fails here however, it means there was a problem writing to - * the disk, so throw a real exception this time. - */ - throw new TmfTraceException(e.toString(), e); - } - } - - /* - * Create a new state system backed with a partial history. A partial - * history is similar to a "full" one (which you get with - * {@link #newFullHistory}), except that the file on disk is much smaller, - * but queries are a bit slower. - * - * Also note that single-queries are implemented using a full-query - * underneath, (which are much slower), so this might not be a good fit for - * a use case where you have to do lots of single queries. - */ - private void createPartialHistory(String id, ITmfStateProvider provider, File htPartialFile) - throws TmfTraceException { - /* - * The order of initializations is very tricky (but very important!) - * here. We need to follow this pattern: - * (1 is done before the call to this method) - * - * 1- Instantiate realStateProvider - * 2- Instantiate realBackend - * 3- Instantiate partialBackend, with prereqs: - * 3a- Instantiate partialProvider, via realProvider.getNew() - * 3b- Instantiate nullBackend (partialSS's backend) - * 3c- Instantiate partialSS - * 3d- partialProvider.assignSS(partialSS) - * 4- Instantiate realSS - * 5- partialSS.assignUpstream(realSS) - * 6- realProvider.assignSS(realSS) - * 7- Call HistoryBuilder(realProvider, realSS, partialBackend) to build the thing. - */ - - /* Size of the blocking queue to use when building a state history */ - final int QUEUE_SIZE = 10000; - - final long granularity = 50000; - - /* 2 */ - IStateHistoryBackend realBackend = null; - try { - realBackend = new ThreadedHistoryTreeBackend(htPartialFile, - provider.getStartTime(), provider.getVersion(), QUEUE_SIZE); - } catch (IOException e) { - throw new TmfTraceException(e.toString(), e); - } - - /* 3a */ - ITmfStateProvider partialProvider = provider.getNewInstance(); - - /* 3b-3c, constructor automatically uses a NullBackend */ - PartialStateSystem pss = new PartialStateSystem(); - - /* 3d */ - partialProvider.assignTargetStateSystem(pss); - - /* 3 */ - IStateHistoryBackend partialBackend = - new PartialHistoryBackend(partialProvider, pss, realBackend, granularity); - - /* 4 */ - @SuppressWarnings("restriction") - org.eclipse.linuxtools.internal.statesystem.core.StateSystem realSS = - (org.eclipse.linuxtools.internal.statesystem.core.StateSystem) StateSystemFactory.newStateSystem(id, partialBackend); - - /* 5 */ - pss.assignUpstream(realSS); - - /* 6 */ - provider.assignTargetStateSystem(realSS); - - /* 7 */ - fHtBackend = partialBackend; - fStateSystem = realSS; - - build(provider); - } - - /* - * Create a new state system using a null history back-end. This means that - * no history intervals will be saved anywhere, and as such only - * {@link ITmfStateSystem#queryOngoingState} will be available. - */ - private void createNullHistory(String id, ITmfStateProvider provider) { - IStateHistoryBackend backend = new NullBackend(); - fHtBackend = backend; - fStateSystem = StateSystemFactory.newStateSystem(id, backend); - provider.assignTargetStateSystem(fStateSystem); - build(provider); - } - - /* - * Create a new state system using in-memory interval storage. This should - * only be done for very small state system, and will be naturally limited - * to 2^31 intervals. - */ - private void createInMemoryHistory(String id, ITmfStateProvider provider) { - IStateHistoryBackend backend = new InMemoryBackend(provider.getStartTime()); - fHtBackend = backend; - fStateSystem = StateSystemFactory.newStateSystem(id, backend); - provider.assignTargetStateSystem(fStateSystem); - build(provider); - } - - private void disposeProvider(boolean deleteFiles) { - ITmfStateProvider provider = fStateProvider; - if (provider != null) { - provider.dispose(); - } - if (deleteFiles && (fHtBackend != null)) { - fHtBackend.removeFiles(); - } - } - - private void build(ITmfStateProvider provider) { - if ((fStateSystem == null) || (fHtBackend == null)) { - throw new IllegalArgumentException(); - } - - ITmfEventRequest request = fRequest; - if ((request != null) && (!request.isCompleted())) { - request.cancel(); - } - - request = new StateSystemEventRequest(provider); - provider.getTrace().sendRequest(request); - - /* - * Only now that we've actually started the build, we'll update the - * class fields, so that they become visible for other callers. - */ - fStateProvider = provider; - fRequest = request; - - /* - * The state system object is now created, we can consider this module - * "initialized" (components can retrieve it and start doing queries). - */ - fInitialized.countDown(); - - /* - * Block the executeAnalysis() construction is complete (so that the - * progress monitor displays that it is running). - */ - try { - request.waitForCompletion(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - private class StateSystemEventRequest extends TmfEventRequest { - private final ITmfStateProvider sci; - private final ITmfTrace trace; - - public StateSystemEventRequest(ITmfStateProvider sp) { - super(sp.getExpectedEventType(), - TmfTimeRange.ETERNITY, - 0, - ITmfEventRequest.ALL_DATA, - ITmfEventRequest.ExecutionType.BACKGROUND); - this.sci = sp; - - // sci.getTrace() will eventually return a @NonNull - @SuppressWarnings("null") - @NonNull ITmfTrace tr = sci.getTrace(); - trace = tr; - - } - - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - if (event.getTrace() == trace) { - sci.processEvent(event); - } else if (trace instanceof TmfExperiment) { - /* - * If the request is for an experiment, check if the event is - * from one of the child trace - */ - for (ITmfTrace childTrace : ((TmfExperiment) trace).getTraces()) { - if (childTrace == event.getTrace()) { - sci.processEvent(event); - } - } - } - } - - @Override - public void handleSuccess() { - super.handleSuccess(); - disposeProvider(false); - } - - @Override - public void handleCancel() { - super.handleCancel(); - disposeProvider(true); - } - - @Override - public void handleFailure() { - super.handleFailure(); - disposeProvider(true); - } - } - - // ------------------------------------------------------------------------ - // ITmfAnalysisModuleWithStateSystems - // ------------------------------------------------------------------------ - - @Override - @Nullable - public ITmfStateSystem getStateSystem(String id) { - if (id.equals(getId())) { - return fStateSystem; - } - return null; - } - - @Override - public Iterable getStateSystems() { - @SuppressWarnings("null") - @NonNull Iterable ret = Collections.singleton((ITmfStateSystem) fStateSystem); - return ret; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/ITmfStatistics.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/ITmfStatistics.java deleted file mode 100644 index 467b1c49a0..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/ITmfStatistics.java +++ /dev/null @@ -1,98 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.statistics; - -import java.util.List; -import java.util.Map; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; - -/** - * Provider for statistics, which is assigned to a trace. This can be used to - * populate views like the Statistics View or the Histogram. - * - * As a guideline, since any trace type can use this interface, all timestamps - * should be normalized to nanoseconds when using these methods - * ({@link ITmfTimestamp#NANOSECOND_SCALE}). - * - * @author Alexandre Montplaisir - * @since 2.0 - */ -public interface ITmfStatistics { - - /** - * Run a histogram query on the statistics back-end. This means, return the - * total number of events in a series of 'nb' equal-sized ranges between - * 'start' and 'end'. As its name implies, this is typically used to fill - * the histogram data (where each range represents one pixel on the - * histogram). - * - * This method will block the caller until the results are returned, so it - * should not be called from a signal handler or from the UI thread. - * - * @param start - * Start time of the query - * @param end - * End time of the query - * @param nb - * The number of ranges to separate the complete time range into. - * It will be the size() of the returned array. - * @return The array representing the number of events found in each - * sub-range. - */ - List histogramQuery(long start, long end, int nb); - - /** - * Return the total number of events in the trace. - * - * @return The total number of events - */ - long getEventsTotal(); - - /** - * Return a Map of the total events in the trace, per event type. The event - * type should come from ITmfEvent.getType().getName(). - * - * @return The map of , for the whole trace - */ - Map getEventTypesTotal(); - - /** - * Retrieve the number of events in the trace in a given time interval. - * - * @param start - * Start time of the time range - * @param end - * End time of the time range - * @return The number of events found - */ - long getEventsInRange(long start, long end); - - /** - * Retrieve the number of events in the trace, per event type, in a given - * time interval. - * - * @param start - * Start time of the time range - * @param end - * End time of the time range - * @return The map of , for the given time range - */ - Map getEventTypesInRange(long start, long end); - - /** - * Notify the statistics back-end that the trace is being closed, so it - * should dispose itself as appropriate (release file descriptors, etc.) - */ - void dispose(); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfEventsStatistics.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfEventsStatistics.java deleted file mode 100644 index e3d53bcd94..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfEventsStatistics.java +++ /dev/null @@ -1,285 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.statistics; - -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfLostEvent; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Implementation of ITmfStatistics which uses event requests to the trace to - * retrieve its information. - * - * There is almost no setup time, but queries themselves are longer than with a - * TmfStateStatistics. Queries are O(n * m), where n is the size of the trace, - * and m is the portion of the trace covered by the selected interval. - * - * @author Alexandre Montplaisir - * @since 2.0 - */ -public class TmfEventsStatistics implements ITmfStatistics { - - /* All timestamps should be stored in nanoseconds in the statistics backend */ - private static final int SCALE = ITmfTimestamp.NANOSECOND_SCALE; - - private final ITmfTrace trace; - - /* Event request objects for the time-range request. */ - private StatsTotalRequest totalRequest = null; - private StatsPerTypeRequest perTypeRequest = null; - - /** - * Constructor - * - * @param trace - * The trace for which we are building the statistics - */ - public TmfEventsStatistics(ITmfTrace trace) { - this.trace = trace; - } - - @Override - public void dispose() { - cancelOngoingRequests(); - } - - @Override - public List histogramQuery(long start, long end, int nb) { - final long[] borders = new long[nb]; - final long increment = (end - start) / nb; - - long curTime = start; - for (int i = 0; i < nb; i++) { - borders[i] = curTime; - curTime += increment; - } - - HistogramQueryRequest req = new HistogramQueryRequest(borders, end); - sendAndWait(req); - - List results = new LinkedList<>(req.getResults()); - return results; - - } - - private synchronized void cancelOngoingRequests() { - if (totalRequest != null && totalRequest.isRunning()) { - totalRequest.cancel(); - } - if (perTypeRequest != null && perTypeRequest.isRunning()) { - perTypeRequest.cancel(); - } - } - - @Override - public long getEventsTotal() { - StatsTotalRequest request = new StatsTotalRequest(trace, TmfTimeRange.ETERNITY); - sendAndWait(request); - - long total = request.getResult(); - return total; - } - - @Override - public Map getEventTypesTotal() { - StatsPerTypeRequest request = new StatsPerTypeRequest(trace, TmfTimeRange.ETERNITY); - sendAndWait(request); - - Map stats = request.getResults(); - return stats; - } - - @Override - public long getEventsInRange(long start, long end) { - ITmfTimestamp startTS = new TmfTimestamp(start, SCALE); - ITmfTimestamp endTS = new TmfTimestamp(end, SCALE); - TmfTimeRange range = new TmfTimeRange(startTS, endTS); - - StatsTotalRequest request = new StatsTotalRequest(trace, range); - sendAndWait(request); - - long total = request.getResult(); - return total; - } - - @Override - public Map getEventTypesInRange(long start, long end) { - ITmfTimestamp startTS = new TmfTimestamp(start, SCALE); - ITmfTimestamp endTS = new TmfTimestamp(end, SCALE); - TmfTimeRange range = new TmfTimeRange(startTS, endTS); - - StatsPerTypeRequest request = new StatsPerTypeRequest(trace, range); - sendAndWait(request); - - Map stats = request.getResults(); - return stats; - } - - private void sendAndWait(TmfEventRequest request) { - trace.sendRequest(request); - try { - request.waitForCompletion(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - - /** - * Event request to get the total number of events - */ - private class StatsTotalRequest extends TmfEventRequest { - - /* Total number of events the request has found */ - private long total; - - public StatsTotalRequest(ITmfTrace trace, TmfTimeRange range) { - super(trace.getEventType(), range, 0, ITmfEventRequest.ALL_DATA, - ITmfEventRequest.ExecutionType.BACKGROUND); - total = 0; - } - - public long getResult() { - return total; - } - - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - if (!(event instanceof ITmfLostEvent) && event.getTrace() == trace) { - total += 1; - } - } - } - - - /** - * Event request to get the counts per event type - */ - private class StatsPerTypeRequest extends TmfEventRequest { - - /* Map in which the results are saved */ - private final Map stats; - - public StatsPerTypeRequest(ITmfTrace trace, TmfTimeRange range) { - super(trace.getEventType(), range, 0, ITmfEventRequest.ALL_DATA, - ITmfEventRequest.ExecutionType.BACKGROUND); - this.stats = new HashMap<>(); - } - - public Map getResults() { - return stats; - } - - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - if (event.getTrace() == trace) { - String eventType = event.getType().getName(); - /* - * Special handling for lost events: instead of counting just - * one, we will count how many actual events it represents. - */ - if (event instanceof ITmfLostEvent) { - ITmfLostEvent le = (ITmfLostEvent) event; - incrementStats(eventType, le.getNbLostEvents()); - return; - } - - /* For standard event types, just increment by one */ - incrementStats(eventType, 1L); - } - } - - private void incrementStats(String key, long count) { - if (stats.containsKey(key)) { - long curValue = stats.get(key); - stats.put(key, curValue + count); - } else { - stats.put(key, count); - } - } - } - - /** - * Event request for histogram queries. It is much faster to do one event - * request then set the results accordingly than doing thousands of them one - * by one. - */ - private class HistogramQueryRequest extends TmfEventRequest { - - /** Map of */ - private final TreeMap results; - - /** - * New histogram request - * - * @param borders - * The array of borders (not including the end time). The - * first element should be the start time of the queries. - * @param endTime - * The end time of the query. Not used in the results map, - * but we need to know when to stop the event request. - */ - public HistogramQueryRequest(long[] borders, long endTime) { - super(trace.getEventType(), - new TmfTimeRange( - new TmfTimestamp(borders[0], SCALE), - new TmfTimestamp(endTime, SCALE)), - 0, - ITmfEventRequest.ALL_DATA, - ITmfEventRequest.ExecutionType.BACKGROUND); - - /* Prepare the results map, with all counts at 0 */ - results = new TreeMap<>(); - for (long border : borders) { - results.put(border, 0L); - } - } - - public Collection getResults() { - return results.values(); - } - - @Override - public void handleData(ITmfEvent event) { - super.handleData(event); - if (event.getTrace() == trace) { - long ts = event.getTimestamp().normalize(0, SCALE).getValue(); - Long key = results.floorKey(ts); - if (key != null) { - incrementValue(key); - } - } - } - - private void incrementValue(Long key) { - long value = results.get(key); - value++; - results.put(key, value); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfStateStatistics.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfStateStatistics.java deleted file mode 100644 index 125fbdb8ef..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfStateStatistics.java +++ /dev/null @@ -1,323 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - * Patrick Tasse - Fix TimeRangeException - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.statistics; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; -import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; - -/** - * Implementation of ITmfStatistics which uses a state history for storing its - * information. In reality, it uses two state histories, one for "event totals" - * information (which should ideally use a fast backend), and another one for - * the rest (per event type, per CPU, etc.). - * - * Compared to the event-request-based statistics calculations, it adds the - * building the history first, but gives much faster response times once built : - * Queries are O(log n) wrt the size of the trace, and O(1) wrt to the size of - * the time interval selected. - * - * @author Alexandre Montplaisir - * @since 2.0 - */ -public class TmfStateStatistics implements ITmfStatistics { - - // ------------------------------------------------------------------------ - // Fields - // ------------------------------------------------------------------------ - - /** The event totals state system */ - private final ITmfStateSystem totalsStats; - - /** The state system for event types */ - private final ITmfStateSystem typesStats; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructor - * - * @param totals - * The state system containing the "totals" information - * @param eventTypes - * The state system containing the "event types" information - * @since 3.0 - */ - public TmfStateStatistics(@NonNull ITmfStateSystem totals, @NonNull ITmfStateSystem eventTypes) { - this.totalsStats = totals; - this.typesStats = eventTypes; - } - - /** - * Return the state system containing the "totals" values - * - * @return The "totals" state system - * @since 3.0 - */ - public ITmfStateSystem getTotalsSS() { - return totalsStats; - } - - /** - * Return the state system containing the "event types" values - * - * @return The "event types" state system - * @since 3.0 - */ - public ITmfStateSystem getEventTypesSS() { - return typesStats; - } - - // ------------------------------------------------------------------------ - // ITmfStatistics - // ------------------------------------------------------------------------ - - @Override - public void dispose() { - totalsStats.dispose(); - typesStats.dispose(); - } - - @Override - public List histogramQuery(final long start, final long end, final int nb) { - final List list = new LinkedList<>(); - final long increment = (end - start) / nb; - - if (totalsStats.isCancelled()) { - return list; - } - - /* - * We will do one state system query per "border", and save the - * differences between each border. - */ - long prevTotal = (start == totalsStats.getStartTime()) ? 0 : getEventCountAt(start); - long curTime = start + increment; - - long curTotal, count; - for (int i = 0; i < nb - 1; i++) { - curTotal = getEventCountAt(curTime); - count = curTotal - prevTotal; - list.add(count); - - curTime += increment; - prevTotal = curTotal; - } - - /* - * For the last bucket, we'll stretch its end time to the end time of - * the requested range, in case it got truncated down. - */ - curTotal = getEventCountAt(end); - count = curTotal - prevTotal; - list.add(count); - - return list; - } - - @Override - public long getEventsTotal() { - long endTime = totalsStats.getCurrentEndTime(); - int count = 0; - - try { - final int quark = totalsStats.getQuarkAbsolute(Attributes.TOTAL); - count= totalsStats.querySingleState(endTime, quark).getStateValue().unboxInt(); - - } catch (StateSystemDisposedException e) { - /* Assume there is no events for that range */ - return 0; - } catch (AttributeNotFoundException e) { - e.printStackTrace(); - } - - return count; - } - - @Override - public Map getEventTypesTotal() { - final Map map = new HashMap<>(); - long endTime = typesStats.getCurrentEndTime(); - - try { - /* Get the list of quarks, one for each even type in the database */ - int quark = typesStats.getQuarkAbsolute(Attributes.EVENT_TYPES); - List quarks = typesStats.getSubAttributes(quark, false); - - /* Since we want the total we can look only at the end */ - List endState = typesStats.queryFullState(endTime); - - String curEventName; - long eventCount; - for (int typeQuark : quarks) { - curEventName = typesStats.getAttributeName(typeQuark); - eventCount = endState.get(typeQuark).getStateValue().unboxInt(); - map.put(curEventName, eventCount); - } - - } catch (StateSystemDisposedException e) { - /* Assume there is no events, nothing will be put in the map. */ - } catch (AttributeNotFoundException e) { - e.printStackTrace(); - } - return map; - } - - @Override - public long getEventsInRange(long start, long end) { - long startCount; - if (start == totalsStats.getStartTime()) { - startCount = 0; - } else { - /* - * We want the events happening at "start" to be included, so we'll - * need to query one unit before that point. - */ - startCount = getEventCountAt(start - 1); - } - long endCount = getEventCountAt(end); - - return endCount - startCount; - } - - @Override - public Map getEventTypesInRange(long start, long end) { - final Map map = new HashMap<>(); - List quarks; - - /* Make sure the start/end times are within the state history, so we - * don't get TimeRange exceptions. - */ - long startTime = checkStartTime(start, typesStats); - long endTime = checkEndTime(end, typesStats); - if (endTime < startTime) { - /* The start/end times do not intersect this state system range. - * Return the empty map. */ - return map; - } - - try { - /* Get the list of quarks, one for each even type in the database */ - int quark = typesStats.getQuarkAbsolute(Attributes.EVENT_TYPES); - quarks = typesStats.getSubAttributes(quark, false); - } catch (AttributeNotFoundException e) { - /* - * The state system does not (yet?) have the needed attributes, it - * probably means there are no events counted yet. Return the empty - * map. - */ - return map; - } - - try { - List endState = typesStats.queryFullState(endTime); - - if (startTime == typesStats.getStartTime()) { - /* Only use the values picked up at the end time */ - for (int typeQuark : quarks) { - String curEventName = typesStats.getAttributeName(typeQuark); - long eventCount = endState.get(typeQuark).getStateValue().unboxInt(); - if (eventCount == -1) { - eventCount = 0; - } - map.put(curEventName, eventCount); - } - } else { - /* - * Query the start time at -1, so the beginning of the interval - * is inclusive. - */ - List startState = typesStats.queryFullState(startTime - 1); - for (int typeQuark : quarks) { - String curEventName = typesStats.getAttributeName(typeQuark); - long countAtStart = startState.get(typeQuark).getStateValue().unboxInt(); - long countAtEnd = endState.get(typeQuark).getStateValue().unboxInt(); - - if (countAtStart == -1) { - countAtStart = 0; - } - if (countAtEnd == -1) { - countAtEnd = 0; - } - long eventCount = countAtEnd - countAtStart; - map.put(curEventName, eventCount); - } - } - - } catch (StateSystemDisposedException e) { - /* Assume there is no (more) events, nothing will be put in the map. */ - } - return map; - } - - // ------------------------------------------------------------------------ - // Helper methods - // ------------------------------------------------------------------------ - - private long getEventCountAt(long timestamp) { - /* Make sure the target time is within the range of the history */ - long ts = checkStartTime(timestamp, totalsStats); - ts = checkEndTime(ts, totalsStats); - - try { - final int quark = totalsStats.getQuarkAbsolute(Attributes.TOTAL); - long count = totalsStats.querySingleState(ts, quark).getStateValue().unboxInt(); - return count; - - } catch (StateSystemDisposedException e) { - /* Assume there is no (more) events, nothing will be put in the map. */ - } catch (AttributeNotFoundException e) { - e.printStackTrace(); - } - - return 0; - } - - private static long checkStartTime(long initialStart, ITmfStateSystem ss) { - long start = initialStart; - if (start < ss.getStartTime()) { - return ss.getStartTime(); - } - return start; - } - - private static long checkEndTime(long initialEnd, ITmfStateSystem ss) { - long end = initialEnd; - if (end > ss.getCurrentEndTime()) { - return ss.getCurrentEndTime(); - } - return end; - } - - /** - * The attribute names that are used in the state provider - */ - public static class Attributes { - - /** Total nb of events */ - public static final String TOTAL = "total"; //$NON-NLS-1$ - - /** event_types */ - public static final String EVENT_TYPES = "event_types"; //$NON-NLS-1$< - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfStatisticsEventTypesModule.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfStatisticsEventTypesModule.java deleted file mode 100644 index fec4665b60..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfStatisticsEventTypesModule.java +++ /dev/null @@ -1,161 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.statistics; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfLostEvent; -import org.eclipse.linuxtools.tmf.core.statesystem.AbstractTmfStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.core.statistics.TmfStateStatistics.Attributes; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * The analysis module building the "event types" statistics state system. - * - * It is not in the extension point (and as such, not registered in the - * TmfAnalysisManager), as it is being handled by the TmfStatisticsModule. - * - * @author Alexandre Montplaisir - * @since 3.0 - */ -public class TmfStatisticsEventTypesModule extends TmfStateSystemAnalysisModule { - - /** - * The ID of this analysis module (which is also the ID of the state system) - */ - @NonNull - public static final String ID = "org.eclipse.linuxtools.tmf.statistics.types"; //$NON-NLS-1$ - - private static final String NAME = "TMF Statistics, events per type"; //$NON-NLS-1$ - - /** - * Constructor - */ - public TmfStatisticsEventTypesModule() { - super(); - setId(ID); - setName(NAME); - } - - @Override - protected ITmfStateProvider createStateProvider() { - return new StatsProviderEventTypes(getTrace()); - } - - @Override - protected String getSsFileName() { - return "statistics-types.ht"; //$NON-NLS-1$ - } - - - /** - * The state provider for traces statistics that use TmfStateStatistics. It - * should work with any trace type for which we can use the state system. - * - * It will store number of events seen, per event types. The resulting attribute - * tree will look like this: - * - *
-     * (root)
-     *   \-- event_types
-     *        |-- (event name 1)
-     *        |-- (event name 2)
-     *        |-- (event name 3)
-     *       ...
-     * 
- * - * And each (event name)'s value will be an integer, representing how many times - * this particular event type has been seen in the trace so far. - * - * @author Alexandre Montplaisir - * @version 1.0 - */ - class StatsProviderEventTypes extends AbstractTmfStateProvider { - - /** - * Version number of this input handler. Please bump this if you modify the - * contents of the generated state history in some way. - */ - private static final int VERSION = 2; - - /** - * Constructor - * - * @param trace - * The trace for which we build this state system - */ - public StatsProviderEventTypes(ITmfTrace trace) { - super(trace, ITmfEvent.class ,"TMF Statistics, events per type"); //$NON-NLS-1$ - } - - @Override - public int getVersion() { - return VERSION; - } - - @Override - public StatsProviderEventTypes getNewInstance() { - return new StatsProviderEventTypes(this.getTrace()); - } - - @Override - protected void eventHandle(ITmfEvent event) { - int quark; - - /* Since this can be used for any trace types, normalize all the - * timestamp values to nanoseconds. */ - final long ts = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - - final String eventName = event.getType().getName(); - - try { - /* Special handling for lost events */ - if (event instanceof ITmfLostEvent) { - ITmfLostEvent le = (ITmfLostEvent) event; - quark = ss.getQuarkAbsoluteAndAdd(Attributes.EVENT_TYPES, eventName); - - int curVal = ss.queryOngoingState(quark).unboxInt(); - if (curVal == -1) { - curVal = 0; - } - - TmfStateValue value = TmfStateValue.newValueInt((int) (curVal + le.getNbLostEvents())); - ss.modifyAttribute(ts, value, quark); - return; - } - - /* Number of events of each type, globally */ - quark = ss.getQuarkAbsoluteAndAdd(Attributes.EVENT_TYPES, eventName); - ss.incrementAttribute(ts, quark); - -// /* Number of events per CPU */ -// quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATISTICS, Attributes.EVENT_TYPES, eventName); -// ss.incrementAttribute(ts, quark); - // -// /* Number of events per process */ -// quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATISTICS, Attributes.EVENT_TYPES, eventName); -// ss.incrementAttribute(ts, quark); - - } catch (StateValueTypeException | TimeRangeException | AttributeNotFoundException e) { - e.printStackTrace(); - } - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfStatisticsModule.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfStatisticsModule.java deleted file mode 100644 index 26e822de89..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfStatisticsModule.java +++ /dev/null @@ -1,188 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.statistics; - -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.CountDownLatch; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAbstractAnalysisModule; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfAnalysisModuleWithStateSystems; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Analysis module to compute the statistics of a trace. - * - * @author Alexandre Montplaisir - * @since 3.0 - */ -public class TmfStatisticsModule extends TmfAbstractAnalysisModule - implements ITmfAnalysisModuleWithStateSystems { - - /** ID of this analysis module */ - public static final String ID = "org.eclipse.linuxtools.tmf.core.statistics.analysis"; //$NON-NLS-1$ - - /** The trace's statistics */ - private ITmfStatistics fStatistics = null; - - private final TmfStateSystemAnalysisModule totalsModule = new TmfStatisticsTotalsModule(); - private final TmfStateSystemAnalysisModule eventTypesModule = new TmfStatisticsEventTypesModule(); - - private final CountDownLatch fInitialized = new CountDownLatch(1); - - /** - * Constructor - */ - public TmfStatisticsModule() { - super(); - } - - /** - * Get the statistics object built by this analysis - * - * @return The ITmfStatistics object - */ - @Nullable - public ITmfStatistics getStatistics() { - return fStatistics; - } - - /** - * Wait until the analyses/state systems underneath are ready to be queried. - */ - public void waitForInitialization() { - try { - fInitialized.await(); - } catch (InterruptedException e) {} - } - - // ------------------------------------------------------------------------ - // TmfAbstractAnalysisModule - // ------------------------------------------------------------------------ - - @Override - public void dispose() { - /* - * The sub-analyses are not registered to the trace directly, so we need - * to tell them when the trace is disposed. - */ - super.dispose(); - totalsModule.dispose(); - eventTypesModule.dispose(); - } - - @Override - public void setTrace(ITmfTrace trace) throws TmfAnalysisException { - super.setTrace(trace); - - /* - * Since these sub-analyzes are not built from an extension point, we - * have to assign the trace ourselves. Very important to do so before - * calling schedule()! - */ - totalsModule.setTrace(trace); - eventTypesModule.setTrace(trace); - } - - @Override - protected boolean executeAnalysis(IProgressMonitor monitor) throws TmfAnalysisException { - ITmfTrace trace = getTrace(); - if (trace == null) { - /* This analysis's trace should not be null when this is called */ - throw new IllegalStateException(); - } - - IStatus status1 = totalsModule.schedule(); - IStatus status2 = eventTypesModule.schedule(); - if (!(status1.isOK() && status2.isOK())) { - cancelSubAnalyses(); - return false; - } - - /* Wait until the two modules are initialized */ - totalsModule.waitForInitialization(); - eventTypesModule.waitForInitialization(); - - ITmfStateSystem totalsSS = totalsModule.getStateSystem(); - ITmfStateSystem eventTypesSS = eventTypesModule.getStateSystem(); - - if (totalsSS == null || eventTypesSS == null) { - /* Better safe than sorry... */ - throw new IllegalStateException(); - } - - fStatistics = new TmfStateStatistics(totalsSS, eventTypesSS); - - /* fStatistics is now set, consider this module initialized */ - fInitialized.countDown(); - - /* - * The rest of this "execute" will encompass the "execute" of the two - * sub-analyzes. - */ - if (!(totalsModule.waitForCompletion(monitor) && - eventTypesModule.waitForCompletion(monitor))) { - return false; - } - return true; - } - - @Override - protected void canceling() { - /* - * FIXME The "right" way to cancel state system construction is not - * available yet... - */ - cancelSubAnalyses(); - - ITmfStatistics stats = fStatistics; - if (stats != null) { - stats.dispose(); - } - } - - private void cancelSubAnalyses() { - totalsModule.cancel(); - eventTypesModule.cancel(); - } - - // ------------------------------------------------------------------------ - // ITmfStateSystemAnalysisModule - // ------------------------------------------------------------------------ - - @Override - public ITmfStateSystem getStateSystem(String id) { - switch (id) { - case TmfStatisticsTotalsModule.ID: - return totalsModule.getStateSystem(); - case TmfStatisticsEventTypesModule.ID: - return eventTypesModule.getStateSystem(); - default: - return null; - } - } - - @Override - public Iterable getStateSystems() { - List list = new LinkedList<>(); - list.add(totalsModule.getStateSystem()); - list.add(eventTypesModule.getStateSystem()); - return list; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfStatisticsTotalsModule.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfStatisticsTotalsModule.java deleted file mode 100644 index 513f7deeb2..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfStatisticsTotalsModule.java +++ /dev/null @@ -1,130 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.statistics; - -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfLostEvent; -import org.eclipse.linuxtools.tmf.core.statesystem.AbstractTmfStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.core.statistics.TmfStateStatistics.Attributes; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * The analysis module building the "totals" statistics state system. - * - * It is not in the extension point (and as such, not registered in the - * TmfAnalysisManager), as it is being handled by the TmfStatisticsModule. - * - * @author Alexandre Montplaisir - * @since 3.0 - */ -public class TmfStatisticsTotalsModule extends TmfStateSystemAnalysisModule { - - /** - * The ID of this analysis module (which is also the ID of the state system) - */ - public static final String ID = "org.eclipse.linuxtools.tmf.statistics.totals"; //$NON-NLS-1$ - - private static final String NAME = "TMF Statistics, event totals"; //$NON-NLS-1$ - - /** - * Constructor - */ - public TmfStatisticsTotalsModule() { - super(); - setId(ID); - setName(NAME); - } - - @Override - protected ITmfStateProvider createStateProvider() { - return new StatsProviderTotals(getTrace()); - } - - @Override - protected String getSsFileName() { - return "statistics-totals.ht"; //$NON-NLS-1$ - } - - - /** - * The state provider for traces statistics that use TmfStateStatistics. It - * should work with any trace type for which we can use the state system. - * - * Only one attribute will be stored, containing the total of events seen so - * far. The resulting attribute tree will look like this: - * - *
-     * (root)
-     *   \-- total
-     * 
- * - * @author Alexandre Montplaisir - * @version 1.0 - */ - class StatsProviderTotals extends AbstractTmfStateProvider { - - /** - * Version number of this input handler. Please bump this if you modify the - * contents of the generated state history in some way. - */ - private static final int VERSION = 2; - - /** - * Constructor - * - * @param trace - * The trace for which we build this state system - */ - public StatsProviderTotals(ITmfTrace trace) { - super(trace, ITmfEvent.class , NAME); - } - - @Override - public int getVersion() { - return VERSION; - } - - @Override - public StatsProviderTotals getNewInstance() { - return new StatsProviderTotals(this.getTrace()); - } - - @Override - protected void eventHandle(ITmfEvent event) { - /* Do not count lost events in the total */ - if (event instanceof ITmfLostEvent) { - return; - } - - /* Since this can be used for any trace types, normalize all the - * timestamp values to nanoseconds. */ - final long ts = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - - try { - /* Total number of events */ - int quark = ss.getQuarkAbsoluteAndAdd(Attributes.TOTAL); - ss.incrementAttribute(ts, quark); - - } catch (StateValueTypeException | TimeRangeException | AttributeNotFoundException e) { - e.printStackTrace(); - } - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/ITmfTimestampTransform.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/ITmfTimestampTransform.java deleted file mode 100644 index 9e24bb86cb..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/ITmfTimestampTransform.java +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.synchronization; - -import java.io.Serializable; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; - -/** - * This class contains a formula to transform the value of a timestamp, for - * example after trace synchronization - * - * @author Geneviève Bastien - * @since 3.0 - */ -public interface ITmfTimestampTransform extends Serializable { - - /** - * Transforms a timestamp - * - * @param timestamp - * The timestamp to transform - * @return the transformed timestamp - */ - ITmfTimestamp transform(ITmfTimestamp timestamp); - - /** - * Transforms a timestamp value - * - * @param timestamp - * The timestamp to transform in nanoseconds - * @return the transformed value - */ - long transform(long timestamp); - - /** - * Returns a timestamp transform that is the composition of two timestamp - * transforms. - * - * @param composeWith - * The transform to first apply on the timestamp before applying - * the current object - * @return A new timestamp transform object with the resulting composition. - */ - ITmfTimestampTransform composeWith(ITmfTimestampTransform composeWith); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/Messages.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/Messages.java deleted file mode 100644 index 757cbccec1..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/Messages.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.synchronization; - -import org.eclipse.osgi.util.NLS; - -/** - * Messages class - * - * @since 3.0 - */ -@SuppressWarnings("javadoc") -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.core.synchronization.messages"; //$NON-NLS-1$ - public static String SyncAlgorithmFullyIncremental_absent; - public static String SyncAlgorithmFullyIncremental_alpha; - public static String SyncAlgorithmFullyIncremental_beta; - public static String SyncAlgorithmFullyIncremental_T_; - public static String SyncAlgorithmFullyIncremental_otherformula; - public static String SyncAlgorithmFullyIncremental_mult; - public static String SyncAlgorithmFullyIncremental_add; - public static String SyncAlgorithmFullyIncremental_ub; - public static String SyncAlgorithmFullyIncremental_lb; - public static String SyncAlgorithmFullyIncremental_accuracy; - public static String SyncAlgorithmFullyIncremental_accurate; - public static String SyncAlgorithmFullyIncremental_approx; - public static String SyncAlgorithmFullyIncremental_fail; - public static String SyncAlgorithmFullyIncremental_incomplete; - public static String SyncAlgorithmFullyIncremental_nbmatch; - public static String SyncAlgorithmFullyIncremental_nbacc; - public static String SyncAlgorithmFullyIncremental_refhost; - public static String SyncAlgorithmFullyIncremental_otherhost; - public static String SyncAlgorithmFullyIncremental_refformula; - public static String SyncAlgorithmFullyIncremental_NA; - public static String SyncAlgorithmFullyIncremental_quality; - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java deleted file mode 100644 index 25208fb56a..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java +++ /dev/null @@ -1,626 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - * Francis Giraldeau - Transform computation using synchronization graph - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.synchronization; - -import java.io.IOException; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.math.BigDecimal; -import java.math.MathContext; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.eclipse.linuxtools.internal.tmf.core.synchronization.graph.SyncSpanningTree; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventDependency; -import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform; -import org.eclipse.linuxtools.tmf.core.synchronization.Messages; -import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithm; -import org.eclipse.linuxtools.tmf.core.synchronization.TimestampTransformFactory; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Class implementing fully incremental trace synchronization approach as - * described in - * - * Masoume Jabbarifar, Michel Dagenais and Alireza Shameli-Sendi, - * "Streaming Mode Incremental Clock Synchronization" - * - * Since the algorithm itself applies to two traces, it is implemented in a - * private class, while this public class manages the synchronization between - * all traces. - * - * @author Geneviève Bastien - * @since 3.0 - * @deprecated This class has been moved to internal. Use one of - * {@link SynchronizationAlgorithmFactory#getFullyIncrementalAlgorithm()} - * method to get this algorithm. - */ -@Deprecated -public class SyncAlgorithmFullyIncremental extends SynchronizationAlgorithm { - - /** - * Auto-generated serial UID - */ - private static final long serialVersionUID = -1782788842774838830L; - - private static final MathContext fMc = MathContext.DECIMAL128; - - /** @serial */ - private final List fSyncs; - - private SyncSpanningTree fTree = null; - - /** - * Initialization of the attributes - */ - public SyncAlgorithmFullyIncremental() { - fSyncs = new LinkedList<>(); - } - - /** - * Function called after all matching has been done, to do any post-match - * treatment. For this class, it calculates stats, while the data is - * available - */ - @Override - public void matchingEnded() { - getStats(); - } - - @Override - public void init(Collection traces) { - ITmfTrace[] traceArr = traces.toArray(new ITmfTrace[traces.size()]); - fSyncs.clear(); - /* Create a convex hull for all trace pairs */ - // FIXME: is it necessary to make ConvexHull for every pairs up-front? - // The ConvexHull seems to be created on the fly in processMatch(). - for (int i = 0; i < traceArr.length; i++) { - for (int j = i + 1; j < traceArr.length; j++) { - ConvexHull algo = new ConvexHull(traceArr[i].getHostId(), traceArr[j].getHostId()); - fSyncs.add(algo); - } - } - } - - @Override - protected void processMatch(TmfEventDependency match) { - String host1 = match.getSourceEvent().getTrace().getHostId(); - String host2 = match.getDestinationEvent().getTrace().getHostId(); - - /* Process only if source and destination are different */ - if (host1.equals(host2)) { - return; - } - - /* Check if a convex hull algorithm already exists for these 2 hosts */ - ConvexHull algo = null; - for (ConvexHull traceSync : fSyncs) { - if (traceSync.isForHosts(host1, host2)) { - algo = traceSync; - } - } - if (algo == null) { - algo = new ConvexHull(host1, host2); - fSyncs.add(algo); - } - algo.processMatch(match); - invalidateSyncGraph(); - } - - private void invalidateSyncGraph() { - fTree = null; - } - - @Override - public ITmfTimestampTransform getTimestampTransform(ITmfTrace trace) { - return getTimestampTransform(trace.getHostId()); - } - - @Override - public ITmfTimestampTransform getTimestampTransform(String hostId) { - SyncSpanningTree tree = getSyncTree(); - return tree.getTimestampTransform(hostId); - } - - /** - * Each convex hull computes the synchronization between 2 given hosts. A - * synchronization can be done on multiple hosts that may not all - * communicate with each other. We must use another algorithm to determine - * which host will be the reference node and what synchronization formula - * will be used between each host and this reference node. - * - * For example, take traces a, b and c where a and c talk to b but do not - * know each other ({@literal a <-> b <-> c}). The convex hulls will contain - * the formulae between their 2 traces, but if a is the reference node, then - * the resulting formula of c would be the composition of {@literal a <-> b} - * and {@literal b <-> c} - * - * @return The synchronization spanning tree for this synchronization - */ - private SyncSpanningTree getSyncTree() { - if (fTree == null) { - fTree = new SyncSpanningTree(); - for (ConvexHull traceSync : fSyncs) { - SyncQuality q = traceSync.getQuality(); - if (q == SyncQuality.ACCURATE || q == SyncQuality.APPROXIMATE) { - String from = traceSync.getReferenceHost(); - String to = traceSync.getOtherHost(); - fTree.addSynchronization(from, to, traceSync.getTimestampTransform(to), traceSync.getAccuracy()); - } - } - } - return fTree; - } - - @Override - public SyncQuality getSynchronizationQuality(ITmfTrace trace1, ITmfTrace trace2) { - for (ConvexHull traceSync : fSyncs) { - if (traceSync.isForHosts(trace1.getHostId(), trace2.getHostId())) { - return traceSync.getQuality(); - } - } - return SyncQuality.ABSENT; - } - - @Override - public boolean isTraceSynced(String hostId) { - ITmfTimestampTransform t = getTimestampTransform(hostId); - return !t.equals(TimestampTransformFactory.getDefaultTransform()); - } - - @Override - public Map> getStats() { - /* - * TODO: Stats, while still accurate, may be misleading now that the - * sync tree changes synchronization formula. The stats should use the - * tree instead - */ - Map> statmap = new LinkedHashMap<>(); - for (ConvexHull traceSync : fSyncs) { - statmap.put(traceSync.getReferenceHost() + " <==> " + traceSync.getOtherHost(), traceSync.getStats()); //$NON-NLS-1$ - } - return statmap; - } - - @Override - public String toString() { - StringBuilder b = new StringBuilder(); - b.append(getClass().getSimpleName() + " "); //$NON-NLS-1$ - b.append(fSyncs); - return b.toString(); - } - - /** - * This is the actual synchronization algorithm between two traces using - * convex hull - */ - private class ConvexHull implements Serializable { - - private static final long serialVersionUID = 8309351175030935291L; - - /** - * The list of meaningful points on the upper hull (received by the - * reference trace, below in a graph) - */ - private final LinkedList fUpperBoundList = new LinkedList<>(); - - /** - * The list of meaninful points on the lower hull (sent by the reference - * trace, above in a graph) - */ - private final LinkedList fLowerBoundList = new LinkedList<>(); - - /** Points forming the line with maximum slope */ - private final SyncPoint[] fLmax; - - /** Points forming the line with minimum slope */ - private final SyncPoint[] fLmin; - - /** - * Slopes and ordinate at origin of respectively fLmin, fLmax and the - * bisector - */ - private BigDecimal fAlphamin, fBetamax, fAlphamax, fBetamin, fAlpha, fBeta; - - private int fNbMatches, fNbAccurateMatches; - private String fReferenceHost = "", fOtherHost = ""; //$NON-NLS-1$//$NON-NLS-2$ - private SyncQuality fQuality; - - private Map fStats = new LinkedHashMap<>(); - - /** - * Initialization of the attributes - * - * @param host1 - * ID of the first host - * @param host2 - * ID of the second host - */ - public ConvexHull(String host1, String host2) { - if (host1.compareTo(host2) > 0) { - fReferenceHost = host2; - fOtherHost = host1; - } else { - fReferenceHost = host1; - fOtherHost = host2; - } - fLmax = new SyncPoint[2]; - fLmin = new SyncPoint[2]; - fAlpha = BigDecimal.ONE; - fAlphamax = BigDecimal.ONE; - fAlphamin = BigDecimal.ONE; - fBeta = BigDecimal.ZERO; - fBetamax = BigDecimal.ZERO; - fBetamin = BigDecimal.ZERO; - fNbMatches = 0; - fNbAccurateMatches = 0; - fQuality = SyncQuality.ABSENT; // default quality - } - - protected void processMatch(TmfEventDependency match) { - - LinkedList boundList, otherBoundList; - - SyncPoint[] line, otherLine; - SyncPoint p; - int inversionFactor = 1; - boolean qualify = false; - fNbMatches++; - - /* Initialize data depending on the which hull the match is part of */ - if (match.getSourceEvent().getTrace().getHostId().compareTo(match.getDestinationEvent().getTrace().getHostId()) > 0) { - boundList = fUpperBoundList; - otherBoundList = fLowerBoundList; - line = fLmin; - otherLine = fLmax; - p = new SyncPoint(match.getDestinationEvent(), match.getSourceEvent()); - inversionFactor = 1; - } else { - boundList = fLowerBoundList; - otherBoundList = fUpperBoundList; - line = fLmax; - otherLine = fLmin; - p = new SyncPoint(match.getSourceEvent(), match.getDestinationEvent()); - inversionFactor = -1; - } - - /* - * Does the message qualify for the hull, or is in on the wrong side - * of the reference line - */ - if ((line[0] == null) || (line[1] == null) || (p.crossProduct(line[0], line[1]) * inversionFactor > 0)) { - /* - * If message qualifies, verify if points need to be removed - * from the hull and add the new point as the maximum reference - * point for the line. Also clear the stats that are not good - * anymore - */ - fNbAccurateMatches++; - qualify = true; - removeUselessPoints(p, boundList, inversionFactor); - line[1] = p; - fStats.clear(); - } - - /* - * Adjust the boundary of the reference line and if one of the - * reference point of the other line was removed from the hull, also - * adjust the other line - */ - adjustBound(line, otherBoundList, inversionFactor); - if ((otherLine[1] != null) && !boundList.contains(otherLine[0])) { - adjustBound(otherLine, boundList, inversionFactor * -1); - } - - if (qualify) { - approximateSync(); - } - - } - - /** - * Calculates slopes and ordinate at origin of fLmax and fLmin to obtain - * and approximation of the synchronization at this time - */ - private void approximateSync() { - - /** - * Line slopes functions - * - * Lmax = alpha_max T + beta_min - * - * Lmin = alpha_min T + beta_max - */ - if ((fLmax[0] != null) || (fLmin[0] != null)) { - /** - * Do not recalculate synchronization after it is failed. We - * keep the last not failed result. - */ - if (getQuality() != SyncQuality.FAIL) { - BigDecimal alphamax = fLmax[1].getAlpha(fLmax[0]); - BigDecimal alphamin = fLmin[1].getAlpha(fLmin[0]); - SyncQuality quality = null; - - if ((fLmax[0] == null) || (fLmin[0] == null)) { - quality = SyncQuality.APPROXIMATE; - } - else if (alphamax.compareTo(alphamin) > 0) { - quality = SyncQuality.ACCURATE; - } else { - /* Lines intersect, not good */ - quality = SyncQuality.FAIL; - } - /* - * Only calculate sync if this match does not cause failure - * of synchronization - */ - if (quality != SyncQuality.FAIL) { - fAlphamax = alphamax; - fBetamin = fLmax[1].getBeta(fAlphamax); - fAlphamin = alphamin; - fBetamax = fLmin[1].getBeta(fAlphamin); - fAlpha = fAlphamax.add(fAlphamin).divide(BigDecimal.valueOf(2), fMc); - fBeta = fBetamin.add(fBetamax).divide(BigDecimal.valueOf(2), fMc); - } - setQuality(quality); - } - } else if (((fLmax[0] == null) && (fLmin[1] == null)) - || ((fLmax[1] == null) && (fLmin[0] == null))) { - /* Either there is no upper hull point or no lower hull */ - setQuality(SyncQuality.INCOMPLETE); - } - } - - /* - * Verify if the line should be adjusted to be more accurate give the - * hull - */ - private void adjustBound(SyncPoint[] line, LinkedList otherBoundList, int inversionFactor) { - SyncPoint minPoint = null, nextPoint; - boolean finishedSearch = false; - - /* - * Find in the other bound, the origin point of the line, start from - * the beginning if the point was lost - */ - int i = Math.max(0, otherBoundList.indexOf(line[0])); - - while ((i < otherBoundList.size() - 1) && !finishedSearch) { - minPoint = otherBoundList.get(i); - nextPoint = otherBoundList.get(i + 1); - - /* - * If the rotation (cross-product) is not optimal, move to next - * point as reference for the line (if available) - * - * Otherwise, the current minPoint is the minPoint of the line - */ - if (minPoint.crossProduct(nextPoint, line[1]) * inversionFactor > 0) { - if (nextPoint.getTimeX() < line[1].getTimeX()) { - i++; - } else { - line[0] = null; - finishedSearch = true; - } - } else { - line[0] = minPoint; - finishedSearch = true; - } - } - - if (line[0] == null) { - line[0] = minPoint; - } - - /* Make sure point 0 is before point 1 */ - if ((line[0] != null) && (line[0].getTimeX() > line[1].getTimeX())) { - line[0] = null; - } - } - - /* - * When a point qualifies to be in a hull, we verify if any of the - * existing points need to be removed from the hull - */ - private void removeUselessPoints(final SyncPoint p, final LinkedList boundList, final int inversionFactor) { - - boolean checkRemove = true; - - while (checkRemove && boundList.size() >= 2) { - if (p.crossProduct(boundList.get(boundList.size() - 2), boundList.getLast()) * inversionFactor > 0) { - boundList.removeLast(); - } else { - checkRemove = false; - } - } - boundList.addLast(p); - } - - public ITmfTimestampTransform getTimestampTransform(String hostId) { - if (hostId.equals(fOtherHost) && (getQuality() == SyncQuality.ACCURATE || getQuality() == SyncQuality.APPROXIMATE || getQuality() == SyncQuality.FAIL)) { - /* alpha: beta => 1 / fAlpha, -1 * fBeta / fAlpha); */ - return TimestampTransformFactory.createLinear(BigDecimal.ONE.divide(fAlpha, fMc), BigDecimal.valueOf(-1).multiply(fBeta).divide(fAlpha, fMc)); - } - return TimestampTransformFactory.getDefaultTransform(); - } - - public SyncQuality getQuality() { - return fQuality; - } - - public BigDecimal getAccuracy() { - return fAlphamax.subtract(fAlphamin); - } - - public Map getStats() { - if (fStats.size() == 0) { - String syncQuality; - switch (getQuality()) { - case ABSENT: - syncQuality = Messages.SyncAlgorithmFullyIncremental_absent; - break; - case ACCURATE: - syncQuality = Messages.SyncAlgorithmFullyIncremental_accurate; - break; - case APPROXIMATE: - syncQuality = Messages.SyncAlgorithmFullyIncremental_approx; - break; - case INCOMPLETE: - syncQuality = Messages.SyncAlgorithmFullyIncremental_incomplete; - break; - case FAIL: - default: - syncQuality = Messages.SyncAlgorithmFullyIncremental_fail; - break; - } - - fStats.put(Messages.SyncAlgorithmFullyIncremental_refhost, fReferenceHost); - fStats.put(Messages.SyncAlgorithmFullyIncremental_otherhost, fOtherHost); - fStats.put(Messages.SyncAlgorithmFullyIncremental_quality, syncQuality); - fStats.put(Messages.SyncAlgorithmFullyIncremental_alpha, fAlpha); - fStats.put(Messages.SyncAlgorithmFullyIncremental_beta, fBeta); - fStats.put(Messages.SyncAlgorithmFullyIncremental_ub, (fUpperBoundList.size() == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fUpperBoundList.size()); - fStats.put(Messages.SyncAlgorithmFullyIncremental_lb, (fLowerBoundList.size() == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fLowerBoundList.size()); - fStats.put(Messages.SyncAlgorithmFullyIncremental_accuracy, getAccuracy().doubleValue()); - fStats.put(Messages.SyncAlgorithmFullyIncremental_nbmatch, (fNbMatches == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fNbMatches); - fStats.put(Messages.SyncAlgorithmFullyIncremental_nbacc, (fNbAccurateMatches == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fNbAccurateMatches); - fStats.put(Messages.SyncAlgorithmFullyIncremental_refformula, Messages.SyncAlgorithmFullyIncremental_T_ + fReferenceHost); - fStats.put(Messages.SyncAlgorithmFullyIncremental_otherformula, fAlpha + Messages.SyncAlgorithmFullyIncremental_mult + Messages.SyncAlgorithmFullyIncremental_T_ + fReferenceHost + Messages.SyncAlgorithmFullyIncremental_add + fBeta); - } - return fStats; - - } - - public String getReferenceHost() { - return fReferenceHost; - } - - public String getOtherHost() { - return fOtherHost; - } - - public boolean isForHosts(String hostId1, String hostId2) { - return ((fReferenceHost.equals(hostId1) && fOtherHost.equals(hostId2)) || (fReferenceHost.equals(hostId2) && fOtherHost.equals(hostId1))); - } - - private void writeObject(ObjectOutputStream s) - throws IOException { - /* - * Remove calculation data because most of it is not serializable. - * We have the statistics anyway - */ - fUpperBoundList.clear(); - fLowerBoundList.clear(); - fLmin[0] = null; - fLmin[1] = null; - fLmax[0] = null; - fLmax[1] = null; - s.defaultWriteObject(); - } - - @SuppressWarnings("nls") - @Override - public String toString() { - StringBuilder b = new StringBuilder(); - b.append("Between " + fReferenceHost + " and " + fOtherHost + " ["); - b.append(" alpha " + fAlpha + " beta " + fBeta + " ]"); - return b.toString(); - } - - private void setQuality(SyncQuality fQuality) { - this.fQuality = fQuality; - } - - } - - /** - * Private class representing a point to synchronize on a graph. The x axis - * is the timestamp of the event from the reference trace while the y axis - * is the timestamp of the event on the other trace - */ - private class SyncPoint { - private final ITmfTimestamp x, y; - - public SyncPoint(ITmfEvent ex, ITmfEvent ey) { - x = ex.getTimestamp(); - y = ey.getTimestamp(); - } - - public long getTimeX() { - return x.getValue(); - } - - /** - * Calculate a cross product of 3 points: - * - * If the cross-product < 0, then p, pa, pb are clockwise - * - * If the cross-product > 0, then p, pa, pb are counter-clockwise - * - * If cross-product == 0, then they are in a line - * - * @param pa - * First point - * @param pb - * Second point - * @return The cross product - */ - public long crossProduct(SyncPoint pa, SyncPoint pb) { - long cp = ((pa.x.getValue() - x.getValue()) * (pb.y.getValue() - y.getValue()) - (pa.y.getValue() - y.getValue()) * (pb.x.getValue() - x.getValue())); - return cp; - } - - /* - * Gets the alpha (slope) between two points - */ - public BigDecimal getAlpha(SyncPoint p1) { - if (p1 == null) { - return BigDecimal.ONE; - } - BigDecimal deltay = BigDecimal.valueOf(y.getValue() - p1.y.getValue()); - BigDecimal deltax = BigDecimal.valueOf(x.getValue() - p1.x.getValue()); - if (deltax.equals(BigDecimal.ZERO)) { - return BigDecimal.ONE; - } - return deltay.divide(deltax, fMc); - } - - /* - * Get the beta value (when x = 0) of the line given alpha - */ - public BigDecimal getBeta(BigDecimal alpha) { - return BigDecimal.valueOf(y.getValue()).subtract(alpha.multiply(BigDecimal.valueOf(x.getValue()), fMc)); - } - - @Override - public String toString() { - return String.format("%s (%s, %s)", this.getClass().getCanonicalName(), x, y); //$NON-NLS-1$ - } - } - - private void writeObject(ObjectOutputStream s) - throws IOException { - /* - * Remove the tree because it is not serializable - */ - fTree = null; - s.defaultWriteObject(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationAlgorithm.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationAlgorithm.java deleted file mode 100644 index ce6e12c207..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationAlgorithm.java +++ /dev/null @@ -1,122 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.synchronization; - -import java.io.Serializable; -import java.util.Map; - -import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventDependency; -import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventMatches; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Abstract class for synchronization algorithm - * - * @author Geneviève Bastien - * @since 3.0 - */ -public abstract class SynchronizationAlgorithm extends TmfEventMatches implements Serializable { - - private static final long serialVersionUID = -3083906749528872196L; - - /** - * Quality of the result obtained by the synchronization algorithm - */ - public enum SyncQuality { - /** - * Algorithm returned a result satisfying all hypothesis for the - * algorithm - */ - ACCURATE, - /** - * Best effort of the algorithm - */ - APPROXIMATE, - /** - * There is communication only in one direction - */ - INCOMPLETE, - /** - * No communication between two traces - */ - ABSENT, - /** - * Hypothesis of the algorithm are not satisfied for some reason - */ - FAIL - } - - @Override - public void addMatch(TmfEventDependency match) { - super.addMatch(match); - processMatch(match); - } - - /** - * Function for synchronization algorithm to do something with the received - * match - * - * @param match - * The match of events - */ - protected abstract void processMatch(TmfEventDependency match); - - /** - * Returns a map of staticstics relating to this algorithm. Those stats - * could be used to be displayed in a view for example. - * - * @return A map of statistics for this algorithm - */ - public abstract Map> getStats(); - - /** - * Returns a timestamp transformation algorithm - * - * @param trace - * The trace to get the transform for - * @return The timestamp transformation formula - */ - public abstract ITmfTimestampTransform getTimestampTransform(ITmfTrace trace); - - /** - * Returns a timestamp transformation algorithm - * - * @param hostId - * The host ID of the trace to get the transform for - * @return The timestamp transformation formula - */ - public abstract ITmfTimestampTransform getTimestampTransform(String hostId); - - /** - * Gets the quality of the synchronization between two given traces - * - * @param trace1 - * First trace - * @param trace2 - * Second trace - * @return The synchronization quality - */ - public abstract SyncQuality getSynchronizationQuality(ITmfTrace trace1, ITmfTrace trace2); - - /** - * Returns whether a given trace has a synchronization formula that is not - * identity. This function returns true if the synchronization algorithm has - * failed for some reason - * - * @param hostId - * The host ID of the trace - * @return true if trace has formula - */ - public abstract boolean isTraceSynced(String hostId); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationAlgorithmFactory.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationAlgorithmFactory.java deleted file mode 100644 index bd30e7c73f..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationAlgorithmFactory.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.synchronization; - -import org.eclipse.linuxtools.internal.tmf.core.synchronization.SyncAlgorithmFullyIncremental; - -/** - * A factory to generate synchronization algorithm to synchronize traces - * - * @author Geneviève Bastien - * @since 3.2 - */ -public final class SynchronizationAlgorithmFactory { - - private SynchronizationAlgorithmFactory() { - - } - - /** - * Returns the system's default trace synchronization algorithm, ie the - * fully incremental convex hull synchronization algorithm. - * - * @return The default trace synchronization algorithm - */ - public static SynchronizationAlgorithm getDefaultAlgorithm() { - return new SyncAlgorithmFullyIncremental(); - } - - /** - * Returns the class implementing the fully incremental convex hull trace - * synchronization approach as described in - * - * Masoume Jabbarifar, Michel Dagenais and Alireza Shameli-Sendi, - * "Streaming Mode Incremental Clock Synchronization" - * - * @return The {@link SynchronizationAlgorithm} implementing the fully - * incremental convex hull synchronization algorithm - */ - public static SynchronizationAlgorithm getFullyIncrementalAlgorithm() { - return new SyncAlgorithmFullyIncremental(); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationBackend.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationBackend.java deleted file mode 100644 index 534410a779..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationBackend.java +++ /dev/null @@ -1,196 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.synchronization; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; - -import org.eclipse.linuxtools.internal.tmf.core.Activator; - -/** - * Class to fetch and save synchronization information between traces - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class SynchronizationBackend { - - private static final int SYNC_FILE_MAGIC_NUMBER = 0x0DECAF00; - - private static final int FILE_VERSION = 1; - - private static final int HEADER_SIZE = 20; - - private final File fSyncFile; - - /** - * Constructor - * - * @param syncFile - * The file containing synchronization information - * @throws IOException - * If the file couldn't be opened for some reason - */ - public SynchronizationBackend(File syncFile) throws IOException { - this(syncFile, true); - } - - /** - * Constructor with possibility to tell whether to throw errors on exception - * or not - * - * @param syncFile - * The file containing synchronization information - * @param throwErrors - * Whether to throw exceptions or not - * @throws IOException - * If the file couldn't be opened for some reason - */ - public SynchronizationBackend(File syncFile, boolean throwErrors) throws IOException { - /* - * Open the file ourselves, get the header information we need, then - * pass on the descriptor. - */ - int res; - - fSyncFile = syncFile; - - if (syncFile == null) { - return; - } - - if (!syncFile.exists()) { - if (throwErrors) { - throw new IOException("Selected synchronization file does not exist"); //$NON-NLS-1$ - } - return; - } - if (syncFile.length() <= 0) { - if (throwErrors) { - throw new IOException("Invalid synchronization file selected, " + //$NON-NLS-1$ - "target file is empty"); //$NON-NLS-1$ - } - return; - } - - try (FileInputStream fis = new FileInputStream(syncFile); - FileChannel fc = fis.getChannel();) { - ByteBuffer buffer = ByteBuffer.allocate(HEADER_SIZE); - buffer.clear(); - fc.read(buffer); - buffer.flip(); - - /* - * Check the magic number,to make sure we're opening the right type - * of file - */ - res = buffer.getInt(); - if (res != SYNC_FILE_MAGIC_NUMBER) { - throw new IOException("Selected file does not" + //$NON-NLS-1$ - "look like a synchronization file"); //$NON-NLS-1$ - } - - res = buffer.getInt(); /* Major version number */ - if (res != FILE_VERSION) { - throw new IOException("Select synchronization file is of an older " //$NON-NLS-1$ - + "format. Synchronization will have to be computed again."); //$NON-NLS-1$ - } - - res = buffer.getInt(); /* Minor version number */ - } - } - - /** - * Opens an existing synchronization file - * - * @return The synchronization algorithm contained in the file - * @throws IOException - * Exception returned file functions - */ - public SynchronizationAlgorithm openExistingSync() throws IOException { - - if (fSyncFile == null) { - return null; - } - - try (/* Set the position after the header */ - FileInputStream fis = new FileInputStream(fSyncFile); - FileChannel fc = fis.getChannel().position(HEADER_SIZE); - /* Read the input stream */ - ObjectInputStream ois = new ObjectInputStream(fis);) { - - return (SynchronizationAlgorithm) ois.readObject(); - } catch (ClassNotFoundException e) { - return null; - } - - - } - - /** - * Saves the synchronization algorithm object to file - * - * @param syncAlgo - * The algorithm to save - * @throws FileNotFoundException - * propagate callee's exceptions - */ - public void saveSync(SynchronizationAlgorithm syncAlgo) throws FileNotFoundException { - - if (fSyncFile == null) { - return; - } - - /* Save the header of the file */ - try (FileOutputStream fos = new FileOutputStream(fSyncFile, false); - FileChannel fc = fos.getChannel();) { - - ByteBuffer buffer = ByteBuffer.allocate(HEADER_SIZE); - buffer.clear(); - - fc.position(0); - - buffer.putInt(SYNC_FILE_MAGIC_NUMBER); - - buffer.putInt(FILE_VERSION); - - buffer.flip(); - int res = fc.write(buffer); - assert (res <= HEADER_SIZE); - /* done writing the file header */ - - fc.position(HEADER_SIZE); - - try (ObjectOutputStream oos = new ObjectOutputStream(fos);) { - oos.writeObject(syncAlgo); - } - - } catch (FileNotFoundException e) { - /* Send this upwards */ - throw e; - } catch (IOException e) { - /* Handle other cases of IOException's */ - Activator.logError("Error saving trace synchronization data", e); //$NON-NLS-1$ - } - return; - - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationManager.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationManager.java deleted file mode 100644 index bb489d9cdc..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationManager.java +++ /dev/null @@ -1,134 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.synchronization; - -import java.io.File; -import java.io.IOException; -import java.util.Collection; - -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.component.TmfComponent; -import org.eclipse.linuxtools.tmf.core.event.matching.ITmfEventMatching; -import org.eclipse.linuxtools.tmf.core.event.matching.TmfNetworkEventMatching; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * This abstract manager class handles loading trace synchronization data or - * otherwise their calculation. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public abstract class SynchronizationManager extends TmfComponent { - - /** - * Function called to synchronize traces using the fully incremental - * synchronization algorithm - * - * @param syncFile - * The target name of the synchronization file. If it exists, it - * will be opened, otherwise it will be created and data from - * this synchro run will be saved there - * @param traces - * The list of traces to synchronize - * @param doSync - * Whether to actually synchronize or just try opening a sync - * file - * @return The synchronization object - */ - public static SynchronizationAlgorithm synchronizeTraces(final File syncFile, final Collection traces, boolean doSync) { - - SynchronizationAlgorithm syncAlgo; - if (doSync) { - syncAlgo = synchronize(syncFile, traces, SynchronizationAlgorithmFactory.getDefaultAlgorithm()); - } else { - syncAlgo = openExisting(syncFile); - if (syncAlgo == null) { - syncAlgo = SynchronizationAlgorithmFactory.getDefaultAlgorithm(); - } - } - return syncAlgo; - } - - /** - * Function called to synchronize traces with a specific synchronization - * algorithm. If a synchronization already exists, but is not the requested - * algorithm, the synchronization is done again using the new algorithm - * - * @param syncFile - * The target name of the synchronization file. If it exists, it - * will be opened, otherwise it will be created and data from - * this synchro run will be saved there - * @param traces - * The list of traces to synchronize - * @param algo - * A synchronization algorithm object to determine the algorithm - * used to synchronization. - * @param doSync - * Whether to actually synchronize or just try opening a sync - * file - * @return The synchronization object - */ - public static SynchronizationAlgorithm synchronizeTraces(final File syncFile, final Collection traces, SynchronizationAlgorithm algo, boolean doSync) { - - SynchronizationAlgorithm syncAlgo; - if (doSync) { - syncAlgo = synchronize(syncFile, traces, algo); - } else { - syncAlgo = openExisting(syncFile); - if (syncAlgo == null || (syncAlgo.getClass() != algo.getClass())) { - if (algo != null) { - syncAlgo = algo; - } else { - syncAlgo = SynchronizationAlgorithmFactory.getDefaultAlgorithm(); - } - } - } - - return syncAlgo; - } - - private static SynchronizationAlgorithm openExisting(final File syncFile) { - if ((syncFile != null) && syncFile.exists()) { - /* Load an existing history */ - try { - SynchronizationBackend syncBackend = new SynchronizationBackend(syncFile); - SynchronizationAlgorithm algo = syncBackend.openExistingSync(); - return algo; - } catch (IOException e) { - /* - * There was an error opening the existing file. Perhaps it was - * corrupted, perhaps it's an old version? We'll just - * fall-through and try to build a new one from scratch instead. - */ - Activator.logInfo("Problem opening existing trace synchronization file", e); //$NON-NLS-1$ - } - } - return null; - } - - private static SynchronizationAlgorithm synchronize(final File syncFile, final Collection traces, SynchronizationAlgorithm syncAlgo) { - ITmfEventMatching matching = new TmfNetworkEventMatching(traces, syncAlgo); - matching.matchEvents(); - - SynchronizationBackend syncBackend; - try { - syncBackend = new SynchronizationBackend(syncFile, false); - syncBackend.saveSync(syncAlgo); - } catch (IOException e) { - Activator.logError("Error while saving trace synchronization file", e); //$NON-NLS-1$ - } - return syncAlgo; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TimestampTransformFactory.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TimestampTransformFactory.java deleted file mode 100644 index f74deb02de..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TimestampTransformFactory.java +++ /dev/null @@ -1,208 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial implementation and API - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.core.synchronization; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.math.BigDecimal; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.internal.tmf.core.synchronization.TmfConstantTransform; -import org.eclipse.linuxtools.internal.tmf.core.synchronization.TmfTimestampTransform; -import org.eclipse.linuxtools.internal.tmf.core.synchronization.TmfTimestampTransformLinear; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; - -/** - * A factory to generate timestamp tranforms - * - * @author Matthew Khouzam - * @since 3.1 - */ -public final class TimestampTransformFactory { - - private static final String SYNCHRONIZATION_FORMULA_FILE = "sync_formula"; //$NON-NLS-1$ - - private TimestampTransformFactory() { - } - - /** - * Creates the identity timestamp transform - * - * @return The identity timestamp transform - */ - public static ITmfTimestampTransform getDefaultTransform() { - return TmfTimestampTransform.IDENTITY; - } - - /** - * Create an offsetted transform - * - * @param offset - * the offset in long format, nanosecond scale - * @return the offsetted transform - */ - public static ITmfTimestampTransform createWithOffset(long offset) { - if (offset == 0) { - return TmfTimestampTransform.IDENTITY; - } - return new TmfConstantTransform(offset); - } - - /** - * Create an offsetted transform - * - * @param offset - * the offset in a timestamp with scale - * @return the offsetted transform - */ - public static ITmfTimestampTransform createWithOffset(ITmfTimestamp offset) { - if (offset.getValue() == 0) { - return TmfTimestampTransform.IDENTITY; - } - return new TmfConstantTransform(offset); - } - - /** - * Create a timestamp transform corresponding to a linear equation, with - * slope and offset. The expected timestamp transform is such that f(t) = - * m*x + b, where m is the slope and b the offset. - * - * @param factor - * the slope - * @param offset - * the offset - * @return the transform - */ - public static ITmfTimestampTransform createLinear(double factor, ITmfTimestamp offset) { - if (factor == 1.0) { - return createWithOffset(offset); - } - return new TmfTimestampTransformLinear(factor, offset.normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue()); - } - - /** - * Create a timestamp transform corresponding to a linear equation, with - * slope and offset. The expected timestamp transform is such that f(t) = - * m*x + b, where m is the slope and b the offset. - * - * @param factor - * the slope - * @param offset - * the offset in nanoseconds - * @return the transform - */ - public static ITmfTimestampTransform createLinear(double factor, long offset) { - if (factor == 1.0) { - return createWithOffset(offset); - } - return new TmfTimestampTransformLinear(factor, offset); - } - - /** - * Create a timestamp transform corresponding to a linear equation, with - * slope and offset expressed in BigDecimal. The expected timestamp - * transform is such that f(t) = m*x + b, where m is the slope and b the - * offset. - * - * @param factor - * the slope - * @param offset - * the offset in nanoseconds - * @return the transform - */ - public static ITmfTimestampTransform createLinear(BigDecimal factor, BigDecimal offset) { - if (factor.equals(BigDecimal.ONE)) { - return createWithOffset(offset.longValueExact()); - } - return new TmfTimestampTransformLinear(factor, offset); - } - - /** - * Returns the file resource used to store synchronization formula. The file - * may not exist. - * - * @param resource - * the trace resource - * @return the synchronization file - */ - private static File getSyncFormulaFile(IResource resource) { - if (resource == null) { - return null; - } - try { - String supplDirectory = resource.getPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER); - return new File(supplDirectory + File.separator + SYNCHRONIZATION_FORMULA_FILE); - } catch (CoreException e) { - /* Ignored */ - } - return null; - } - - /** - * Returns the timestamp transform for a trace resource - * - * @param resource - * the trace resource - * @return the timestamp transform - * @since 3.2 - */ - public static ITmfTimestampTransform getTimestampTransform(IResource resource) { - File syncFile = getSyncFormulaFile(resource); - if (syncFile != null && syncFile.exists()) { - /* Read the serialized object from file */ - try (FileInputStream fis = new FileInputStream(syncFile); - ObjectInputStream ois = new ObjectInputStream(fis);) { - return (ITmfTimestampTransform) ois.readObject(); - } catch (ClassNotFoundException | IOException e) { - } - } - return TimestampTransformFactory.getDefaultTransform(); - } - - /** - * Sets the trace resource's timestamp transform - * - * @param resource - * the trace resource - * @param tt - * The timestamp transform for all timestamps of this trace, or - * null to clear it - * @since 3.2 - */ - public static void setTimestampTransform(IResource resource, ITmfTimestampTransform tt) { - /* Save the timestamp transform to a file */ - File syncFile = getSyncFormulaFile(resource); - if (syncFile != null) { - if (syncFile.exists()) { - syncFile.delete(); - } - if (tt == null) { - return; - } - /* Write the serialized object to file */ - try (FileOutputStream fos = new FileOutputStream(syncFile, false); - ObjectOutputStream oos = new ObjectOutputStream(fos);) { - oos.writeObject(tt); - } catch (IOException e1) { - Activator.logError("Error writing timestamp transform for trace", e1); //$NON-NLS-1$ - } - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TmfTimestampTransform.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TmfTimestampTransform.java deleted file mode 100644 index a229658814..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TmfTimestampTransform.java +++ /dev/null @@ -1,82 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.synchronization; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; - -/** - * A default simple, identity timestamp transform. It is a singleton class and - * returns the timestamp itself - * - * @author Geneviève Bastien - * @since 3.0 - * @deprecated This class has been moved to internal. Use one of - * {@link TimestampTransformFactory} methods to create the timestamp - * transform. For the identity, use - * {@link TimestampTransformFactory#getDefaultTransform()} - */ -@Deprecated -public class TmfTimestampTransform implements ITmfTimestampTransform { - - /** - * Generated serial UID - */ - private static final long serialVersionUID = -1480581417493073304L; - - /** - * The unique instance of this transform, since it is always the same - */ - public static final TmfTimestampTransform IDENTITY = new TmfTimestampTransform(); - - /** - * Default constructor - */ - protected TmfTimestampTransform() { - - } - - @Override - public ITmfTimestamp transform(ITmfTimestamp timestamp) { - return timestamp; - } - - @Override - public long transform(long timestamp) { - return timestamp; - } - - @Override - public ITmfTimestampTransform composeWith(ITmfTimestampTransform composeWith) { - /* Since this transform will not modify anything, return the other */ - return composeWith; - } - - @Override - public boolean equals(Object other) { - return other.getClass().equals(TmfTimestampTransform.class); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + TmfTimestampTransform.class.hashCode(); - return result; - } - - @Override - public String toString() { - return "TmfTimestampTransform [ IDENTITY ]"; //$NON-NLS-1$ - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TmfTimestampTransformLinear.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TmfTimestampTransformLinear.java deleted file mode 100644 index 52c4c9cf24..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TmfTimestampTransformLinear.java +++ /dev/null @@ -1,149 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.synchronization; - -import java.math.BigDecimal; -import java.math.MathContext; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; - -/** - * Class implementing a linear timestamp transform, with a slope and/or offset - * - * f(t) = alpha*t + beta - * - * @author Geneviève Bastien - * @since 3.0 - * @deprecated This class has been moved to internal. Use one of - * {@link TimestampTransformFactory} methods to create the timestamp - * transform. It will return an optimized transform for the - * parameters given. To have a linear transform, use methods - * createLinear from the factory. - */ -@Deprecated -public class TmfTimestampTransformLinear implements ITmfTimestampTransform { - - /** - * Generated serial UID - */ - private static final long serialVersionUID = -4756608071358979461L; - - /** - * Respectively the slope and offset and this linear equation. - */ - private final BigDecimal fAlpha; - private final BigDecimal fBeta; - - private static final MathContext fMc = MathContext.DECIMAL128; - - /** - * Default constructor - */ - public TmfTimestampTransformLinear() { - fAlpha = BigDecimal.ONE; - fBeta = BigDecimal.ZERO; - } - - /** - * Constructor with alpha and beta - * - * @param alpha - * The slope of the linear transform - * @param beta - * The initial offset of the linear transform - */ - public TmfTimestampTransformLinear(final double alpha, final double beta) { - fAlpha = BigDecimal.valueOf(alpha); - fBeta = BigDecimal.valueOf(beta); - } - - /** - * Constructor with alpha and beta in big decimal - * - * @param fAlpha2 - * The slope of the linear transform - * @param fBeta2 - * The initial offset of the linear transform - */ - public TmfTimestampTransformLinear(final BigDecimal fAlpha2, final BigDecimal fBeta2) { - if (fAlpha2 != null) { - fAlpha = fAlpha2; - } else { - fAlpha = BigDecimal.ONE; - } - if (fBeta2 != null) { - fBeta = fBeta2; - } else { - fBeta = BigDecimal.ZERO; - } - } - - @Override - public ITmfTimestamp transform(ITmfTimestamp timestamp) { - BigDecimal newvalue = BigDecimal.valueOf(timestamp.getValue()).multiply(fAlpha, fMc).add(fBeta); - return new TmfTimestamp(timestamp, newvalue.longValue()); - } - - @Override - public long transform(long timestamp) { - BigDecimal t = BigDecimal.valueOf(timestamp).multiply(fAlpha, fMc).add(fBeta); - return t.longValue(); - } - - @Override - public ITmfTimestampTransform composeWith(ITmfTimestampTransform composeWith) { - if (composeWith.equals(TmfTimestampTransform.IDENTITY)) { - /* If composing with identity, just return this */ - return this; - } else if (composeWith instanceof TmfTimestampTransformLinear) { - /* If composeWith is a linear transform, add the two together */ - TmfTimestampTransformLinear ttl = (TmfTimestampTransformLinear) composeWith; - BigDecimal newAlpha = fAlpha.multiply(ttl.fAlpha, fMc); - BigDecimal newBeta = fAlpha.multiply(ttl.fBeta, fMc).add(fBeta); - return new TmfTimestampTransformLinear(newAlpha, newBeta); - } else { - /* - * We do not know what to do with this kind of transform, just - * return this - */ - return this; - } - } - - @Override - public boolean equals(Object other) { - boolean result = false; - if (other instanceof TmfTimestampTransformLinear) { - TmfTimestampTransformLinear that = (TmfTimestampTransformLinear) other; - result = ((that.fAlpha.equals(fAlpha)) && (that.fBeta.equals(fBeta))); - } - return result; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + (fBeta.multiply(fAlpha).intValue()); - return result; - } - - @Override - public String toString() { - return "TmfTimestampLinear [ alpha = " + fAlpha.toString() + //$NON-NLS-1$ - ", beta = " + fBeta.toString() + //$NON-NLS-1$ - " ]"; //$NON-NLS-1$ - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/messages.properties b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/messages.properties deleted file mode 100644 index 328fe23af4..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/messages.properties +++ /dev/null @@ -1,32 +0,0 @@ -############################################################################### -# Copyright (c) 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### -SyncAlgorithmFullyIncremental_absent=Absent -SyncAlgorithmFullyIncremental_alpha=Alpha -SyncAlgorithmFullyIncremental_beta=Beta -SyncAlgorithmFullyIncremental_T_=T_ -SyncAlgorithmFullyIncremental_otherformula=C_T1(t) -SyncAlgorithmFullyIncremental_mult=* -SyncAlgorithmFullyIncremental_add=\ + -SyncAlgorithmFullyIncremental_ub=Number of points in upper hull -SyncAlgorithmFullyIncremental_lb=Number of points in lower hull -SyncAlgorithmFullyIncremental_accuracy=Accuracy -SyncAlgorithmFullyIncremental_accurate=Accurate -SyncAlgorithmFullyIncremental_approx=Approximate -SyncAlgorithmFullyIncremental_fail=Fail -SyncAlgorithmFullyIncremental_incomplete=Incomplete -SyncAlgorithmFullyIncremental_nbmatch=Number of matching packets received -SyncAlgorithmFullyIncremental_nbacc=Number of accurate packets -SyncAlgorithmFullyIncremental_refhost=T0 -SyncAlgorithmFullyIncremental_otherhost=T1 -SyncAlgorithmFullyIncremental_refformula=C_T0(t) -SyncAlgorithmFullyIncremental_NA=N/A -SyncAlgorithmFullyIncremental_quality=Quality \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/ITmfTimePreferencesConstants.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/ITmfTimePreferencesConstants.java deleted file mode 100644 index 7ce220c3a3..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/ITmfTimePreferencesConstants.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.timestamp; - -/** - * @since 2.1 - * @noimplement This interface is not intended to be implemented by clients. - */ -@SuppressWarnings({ "javadoc", "nls" }) -public interface ITmfTimePreferencesConstants { - public static final String TIME_FORMAT_PREF = "org.eclipse.linuxtools.tmf.core.prefs.time.format"; - public static final String DEFAULT_TIME_PATTERN = "HH:mm:ss.SSS SSS SSS"; - public static final String DATIME = TIME_FORMAT_PREF + ".datime"; - public static final String SUBSEC = TIME_FORMAT_PREF + ".subsec"; - public static final String TIME_ZONE = TIME_FORMAT_PREF + ".timezone"; - public static final String DATE_DELIMITER = TIME_FORMAT_PREF + ".date.delimiter"; - public static final String TIME_DELIMITER = TIME_FORMAT_PREF + ".time.delimiter"; - public static final String SSEC_DELIMITER = TIME_FORMAT_PREF + ".ssec.delimiter"; - public static final String DATE_YEAR_FMT = "yyyy-MM-dd HH:mm:ss"; - public static final String DATE_YEAR2_FMT = "yy-MM-dd HH:mm:ss"; - public static final String DATE_MONTH_FMT = "MM-dd HH:mm:ss"; - public static final String DATE_DAY_FMT = "dd HH:mm:ss"; - public static final String DATE_JDAY_FMT = "DDD HH:mm:ss"; - public static final String DATE_NO_FMT = "HH:mm:ss"; - public static final String TIME_HOUR_FMT = "HH:mm:ss"; - public static final String TIME_MINUTE_FMT = "mm:ss"; - public static final String TIME_SECOND_FMT = "ss"; - public static final String TIME_ELAPSED_FMT = "TTT"; - public static final String TIME_NO_FMT = ""; - public static final String SUBSEC_MILLI_FMT = "SSS"; - public static final String SUBSEC_MICRO_FMT = "SSS SSS"; - public static final String SUBSEC_NANO_FMT = "SSS SSS SSS"; - public static final String SUBSEC_NO_FMT = ""; - public static final String DELIMITER_NONE = ""; - public static final String DELIMITER_SPACE = " "; - public static final String DELIMITER_PERIOD = "."; - public static final String DELIMITER_COMMA = ","; - public static final String DELIMITER_DASH = "-"; - public static final String DELIMITER_UNDERLINE = "_"; - public static final String DELIMITER_COLON = ":"; - public static final String DELIMITER_SEMICOLON = ";"; - public static final String DELIMITER_SLASH = "/"; - public static final String DELIMITER_DQUOT = "\""; - /** @since 3.0 */ - public static final String DELIMITER_QUOTE = "''"; - /** @since 3.2*/ - public static final String LOCALE = TIME_FORMAT_PREF + ".locale"; -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/ITmfTimestamp.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/ITmfTimestamp.java deleted file mode 100644 index 5f4bf5fc59..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/ITmfTimestamp.java +++ /dev/null @@ -1,142 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.timestamp; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; - -/** - * The fundamental time reference in the TMF. - *

- * It defines a generic timestamp interface in its most basic form: - *

    - *
  • timestamp = [value] * 10**[scale] +/- [precision] - *
- * Where: - *
    - *
  • [value] is an unstructured integer value - *
  • [scale] is the magnitude of the value wrt some application-specific - * base unit (e.g. the second) - *
  • [precision] indicates the error on the value (useful for comparing - * timestamps in different scales). Default: 0. - *
- * - * @author Francois Chouinard - * @version 2.0 - * @since 2.0 - * - * @see ITmfEvent - * @see TmfTimeRange - */ -public interface ITmfTimestamp extends Comparable { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The millisecond scale factor (10e0) - */ - public static final int SECOND_SCALE = 0; - - /** - * The millisecond scale factor (10e-3) - */ - public static final int MILLISECOND_SCALE = -3; - - /** - * The microsecond scale factor (10e-6) - */ - public static final int MICROSECOND_SCALE = -6; - - /** - * The nanosecond scale factor (10e-9) - */ - public static final int NANOSECOND_SCALE = -9; - - // ------------------------------------------------------------------------ - // Getters - // ------------------------------------------------------------------------ - - /** - * @return the timestamp value (magnitude) - */ - long getValue(); - - /** - * @return the timestamp scale (exponent) - */ - int getScale(); - - /** - * @return the timestamp precision (measurement tolerance) - */ - int getPrecision(); - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Normalize (adjust scale and offset) of the timestamp - * - * @param offset the offset to apply to the timestamp value (after scaling) - * @param scale the new timestamp scale - * @return a new 'adjusted' ITmfTimestamp - */ - ITmfTimestamp normalize(long offset, int scale); - - /** - * Compares [this] and [ts] within timestamp precision - * - * @param ts the other timestamp - * @param withinPrecision consider the precision when testing for equality - * @return -1, 0 or 1 (less than, equals, greater than) - */ - int compareTo(ITmfTimestamp ts, boolean withinPrecision); - - /** - * Returns the difference between [this] and [ts] as a timestamp - * - * @param ts the other timestamp - * @return the time difference (this - other) as an ITmfTimestamp - */ - ITmfTimestamp getDelta(ITmfTimestamp ts); - - /** - * Returns if this timestamp intersects the given time range. Borders are - * inclusive (for more fine-grained behavior, you can use - * {@link #compareTo(ITmfTimestamp)}. - * - * @param range - * The time range to compare to - * @return True if this timestamp is part of the time range, false if not - */ - boolean intersects(TmfTimeRange range); - - // ------------------------------------------------------------------------ - // Comparable - // ------------------------------------------------------------------------ - - @Override - int compareTo(ITmfTimestamp ts); - - /** - * Format the timestamp as per the format provided - * - * @param format the timestamp formatter - * @return the formatted timestamp - * @since 2.0 - */ - String toString(final TmfTimestampFormat format); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfNanoTimestamp.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfNanoTimestamp.java deleted file mode 100644 index 64d7982579..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfNanoTimestamp.java +++ /dev/null @@ -1,110 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Modified from TmfSimpleTimestamp to use nanosecond scale - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.timestamp; - -/** - * A simplified timestamp where scale is nanoseconds and precision is set to 0. - * - * @since 2.1 - */ -public class TmfNanoTimestamp extends TmfTimestamp { - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor (value = 0) - */ - public TmfNanoTimestamp() { - this(0); - } - - /** - * Full constructor - * - * @param value the timestamp value - */ - public TmfNanoTimestamp(final long value) { - super(value, ITmfTimestamp.NANOSECOND_SCALE, 0); - } - - /** - * Copy constructor. - * - * If the parameter is not a TmfNanoTimestamp, the timestamp will be - * scaled to nanoseconds, and the precision will be discarded. - * - * @param timestamp - * The timestamp to copy - */ - public TmfNanoTimestamp(final ITmfTimestamp timestamp) { - super(timestamp.normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(), ITmfTimestamp.NANOSECOND_SCALE, 0); - } - - // ------------------------------------------------------------------------ - // ITmfTimestamp - // ------------------------------------------------------------------------ - - @Override - public ITmfTimestamp normalize(final long offset, final int scale) { - if (scale == ITmfTimestamp.NANOSECOND_SCALE) { - return new TmfNanoTimestamp(getValue() + offset); - } - return super.normalize(offset, scale); - } - - @Override - public int compareTo(final ITmfTimestamp ts, final boolean withinPrecision) { - if (ts instanceof TmfNanoTimestamp) { - final long delta = getValue() - ts.getValue(); - return (delta == 0) ? 0 : (delta > 0) ? 1 : -1; - } - return super.compareTo(ts, withinPrecision); - } - - @Override - public ITmfTimestamp getDelta(final ITmfTimestamp ts) { - if (ts instanceof TmfNanoTimestamp) { - return new TmfTimestampDelta(getValue() - ts.getValue(), ITmfTimestamp.NANOSECOND_SCALE); - } - return super.getDelta(ts); - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - return super.hashCode(); - } - - @Override - public boolean equals(final Object other) { - if (this == other) { - return true; - } - if (other == null) { - return false; - } - if (!(other instanceof TmfNanoTimestamp)) { - return super.equals(other); - } - final TmfNanoTimestamp ts = (TmfNanoTimestamp) other; - - return compareTo(ts, false) == 0; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfSimpleTimestamp.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfSimpleTimestamp.java deleted file mode 100644 index 94fccfb051..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfSimpleTimestamp.java +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Standardize on the default toString() - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.timestamp; - -/** - * A simplified timestamp where scale and precision are set to 0. - * - * @author Francois Chouinard - * @version 1.1 - * @since 2.0 - */ -public class TmfSimpleTimestamp extends TmfTimestamp { - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor (value = 0) - */ - public TmfSimpleTimestamp() { - this(0); - } - - /** - * Full constructor - * - * @param value the timestamp value - */ - public TmfSimpleTimestamp(final long value) { - super(value, 0, 0); - } - - /** - * Copy constructor. - * - * If the parameter is not a TmfSimpleTimestamp, the timestamp will be - * scaled to seconds, and the precision will be discarded. - * - * @param timestamp - * The timestamp to copy - */ - public TmfSimpleTimestamp(final ITmfTimestamp timestamp) { - super(timestamp.normalize(0, ITmfTimestamp.SECOND_SCALE).getValue(), 0, 0); - } - - // ------------------------------------------------------------------------ - // ITmfTimestamp - // ------------------------------------------------------------------------ - - @Override - public ITmfTimestamp normalize(final long offset, final int scale) { - if (scale == 0) { - return new TmfSimpleTimestamp(getValue() + offset); - } - return super.normalize(offset, scale); - } - - @Override - public int compareTo(final ITmfTimestamp ts, final boolean withinPrecision) { - if (ts instanceof TmfSimpleTimestamp) { - final long delta = getValue() - ts.getValue(); - return (delta == 0) ? 0 : (delta > 0) ? 1 : -1; - } - return super.compareTo(ts, withinPrecision); - } - - @Override - public ITmfTimestamp getDelta(final ITmfTimestamp ts) { - if (ts instanceof TmfSimpleTimestamp) { - return new TmfTimestampDelta(getValue() - ts.getValue()); - } - return super.getDelta(ts); - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - return super.hashCode(); - } - - @Override - public boolean equals(final Object other) { - if (this == other) { - return true; - } - if (other == null) { - return false; - } - if (!(other instanceof TmfSimpleTimestamp)) { - return super.equals(other); - } - final TmfSimpleTimestamp ts = (TmfSimpleTimestamp) other; - - return compareTo(ts, false) == 0; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimePreferences.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimePreferences.java deleted file mode 100644 index f7abb872fd..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimePreferences.java +++ /dev/null @@ -1,213 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Marc-Andre Laperle - Add time zone preference - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.timestamp; - -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.TimeZone; - -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.preferences.DefaultScope; -import org.eclipse.core.runtime.preferences.IEclipsePreferences; -import org.eclipse.core.runtime.preferences.InstanceScope; -import org.eclipse.linuxtools.internal.tmf.core.Activator; - -/** - * TMF Time format preferences - * - * @author Francois Chouinard - * @version 1.0 - * @since 2.1 - */ -public class TmfTimePreferences { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - private static final String DATIME_DEFAULT = ITmfTimePreferencesConstants.TIME_HOUR_FMT; - private static final String SUBSEC_DEFAULT = ITmfTimePreferencesConstants.SUBSEC_NANO_FMT; - private static final String DATE_DELIMITER_DEFAULT = ITmfTimePreferencesConstants.DELIMITER_DASH; - private static final String TIME_DELIMITER_DEFAULT = ITmfTimePreferencesConstants.DELIMITER_COLON; - private static final String SSEC_DELIMITER_DEFAULT = ITmfTimePreferencesConstants.DELIMITER_SPACE; - private static final String TIME_ZONE_DEFAULT = TimeZone.getDefault().getID(); - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private static TmfTimePreferences fPreferences; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Initialize the default preferences and the singleton - */ - public static void init() { - IEclipsePreferences defaultPreferences = DefaultScope.INSTANCE.getNode(Activator.PLUGIN_ID); - defaultPreferences.put(ITmfTimePreferencesConstants.DATIME, DATIME_DEFAULT); - defaultPreferences.put(ITmfTimePreferencesConstants.SUBSEC, SUBSEC_DEFAULT); - defaultPreferences.put(ITmfTimePreferencesConstants.DATE_DELIMITER, DATE_DELIMITER_DEFAULT); - defaultPreferences.put(ITmfTimePreferencesConstants.TIME_DELIMITER, TIME_DELIMITER_DEFAULT); - defaultPreferences.put(ITmfTimePreferencesConstants.SSEC_DELIMITER, SSEC_DELIMITER_DEFAULT); - defaultPreferences.put(ITmfTimePreferencesConstants.TIME_ZONE, TIME_ZONE_DEFAULT); - - // Create the singleton and update default formats - getInstance(); - } - - /** - * Get the TmfTimePreferences singleton - * - * @return The TmfTimePreferences instance - */ - public static synchronized TmfTimePreferences getInstance() { - if (fPreferences == null) { - fPreferences = new TmfTimePreferences(); - TmfTimestampFormat.updateDefaultFormats(); - } - return fPreferences; - } - - /** - * Local constructor - */ - private TmfTimePreferences() { - } - - // ------------------------------------------------------------------------ - // Getters/Setters - // ------------------------------------------------------------------------ - - /** - * Return the timestamp pattern - * - * @return the timestamp pattern - */ - public String getTimePattern() { - return computeTimePattern(getPreferenceMap(false)); - } - - /** - * Return the interval pattern - * - * @return the interval pattern - */ - public String getIntervalPattern() { - return computeIntervalPattern(getPreferenceMap(false)); - } - - /** - * Get the time zone - * - * @return the time zone - */ - public TimeZone getTimeZone() { - return TimeZone.getTimeZone(Platform.getPreferencesService().getString(Activator.PLUGIN_ID, ITmfTimePreferencesConstants.TIME_ZONE, TimeZone.getDefault().getID(), null)); - } - - /** - * Get the locale - * - * @return the locale - * @since 3.2 - */ - public Locale getLocale() { - return Locale.forLanguageTag(Platform.getPreferencesService().getString(Activator.PLUGIN_ID, ITmfTimePreferencesConstants.LOCALE, Locale.getDefault().toLanguageTag(), null)); - } - - /** - * Get the default preferences map - * - * @return a collection containing the default preferences - */ - public Map getDefaultPreferenceMap() { - return getPreferenceMap(true); - } - - /** - * Get the current preferences map - * - * @return a collection containing the current preferences - */ - public Map getPreferenceMap() { - return getPreferenceMap(false); - } - - private static Map getPreferenceMap(boolean defaultValues) { - Map prefsMap = new HashMap<>(); - IEclipsePreferences prefs = defaultValues ? DefaultScope.INSTANCE.getNode(Activator.PLUGIN_ID) : InstanceScope.INSTANCE.getNode(Activator.PLUGIN_ID); - prefToMap(prefs, prefsMap, ITmfTimePreferencesConstants.SUBSEC, SUBSEC_DEFAULT); - prefToMap(prefs, prefsMap, ITmfTimePreferencesConstants.TIME_DELIMITER, TIME_DELIMITER_DEFAULT); - prefToMap(prefs, prefsMap, ITmfTimePreferencesConstants.SSEC_DELIMITER, SSEC_DELIMITER_DEFAULT); - prefToMap(prefs, prefsMap, ITmfTimePreferencesConstants.DATIME, DATIME_DEFAULT); - prefToMap(prefs, prefsMap, ITmfTimePreferencesConstants.DATE_DELIMITER, DATE_DELIMITER_DEFAULT); - return prefsMap; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - private static String computeIntervalPattern(Map prefsMap) { - String ssecFmt = computeSubSecFormat(prefsMap); - return ITmfTimePreferencesConstants.TIME_ELAPSED_FMT + "." + ssecFmt; //$NON-NLS-1$ - } - - private static String computeSubSecFormat(Map prefsMap) { - String sSecFormat = prefsMap.get(ITmfTimePreferencesConstants.SUBSEC); - String sSecFieldSep = prefsMap.get(ITmfTimePreferencesConstants.SSEC_DELIMITER); - String ssecFmt = sSecFormat.replaceAll(" ", sSecFieldSep); //$NON-NLS-1$ - return ssecFmt; - } - - private static void prefToMap(IEclipsePreferences node, Map prefsMap, String key, String defaultValue) { - prefsMap.put(key, node.get(key, defaultValue)); - } - - /** - * Compute the time pattern with the collection of preferences - * - * @param prefsMap the preferences to apply when computing the time pattern - * @return the time pattern resulting in applying the preferences - */ - public String computeTimePattern(Map prefsMap) { - String dateTimeFormat = prefsMap.get(ITmfTimePreferencesConstants.DATIME); - if (dateTimeFormat == null) { - dateTimeFormat = ITmfTimePreferencesConstants.DEFAULT_TIME_PATTERN; - } - - String dateFormat; - String timeFormat; - int index = dateTimeFormat.indexOf(' '); - if (index != -1) { - dateFormat = dateTimeFormat.substring(0, dateTimeFormat.indexOf(' ') + 1); - timeFormat = dateTimeFormat.substring(dateFormat.length()); - } else { - dateFormat = ""; //$NON-NLS-1$ - timeFormat = dateTimeFormat; - } - - String dateFieldSep = prefsMap.get(ITmfTimePreferencesConstants.DATE_DELIMITER); - String timeFieldSep = prefsMap.get(ITmfTimePreferencesConstants.TIME_DELIMITER); - String dateFmt = dateFormat.replaceAll("-", dateFieldSep); //$NON-NLS-1$ - String timeFmt = timeFormat.replaceAll(":", timeFieldSep); //$NON-NLS-1$ - - String ssecFmt = computeSubSecFormat(prefsMap); - return dateFmt + timeFmt + (ssecFmt.equals(ITmfTimePreferencesConstants.SUBSEC_NO_FMT) ? "" : '.' + ssecFmt); //$NON-NLS-1$; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimeRange.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimeRange.java deleted file mode 100644 index 2f373fcb51..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimeRange.java +++ /dev/null @@ -1,226 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Updated as per TMF Event Model 1.0 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.timestamp; - -import org.eclipse.jdt.annotation.NonNull; - -/** - * A utility class to define and manage time ranges. - * - * @author Francois Chouinard - * @version 1.0 - * @since 2.0 - * - * @see ITmfTimestamp - */ -public class TmfTimeRange { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The full possible time range - */ - public static final @NonNull TmfTimeRange ETERNITY = new EternityTimeRange(); - - /** - * The null time range - */ - public static final @NonNull TmfTimeRange NULL_RANGE = new TmfTimeRange(); - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final ITmfTimestamp fStartTime; - private final ITmfTimestamp fEndTime; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - private TmfTimeRange() { - fStartTime = TmfTimestamp.BIG_BANG; - fEndTime = TmfTimestamp.BIG_BANG; - } - - /** - * Full constructor - * - * @param startTime start of the time range - * @param endTime end of the time range - */ - public TmfTimeRange(final ITmfTimestamp startTime, final ITmfTimestamp endTime) { - if (startTime == null || endTime == null) { - throw new IllegalArgumentException(); - } - fStartTime = startTime; - fEndTime = endTime; - } - - /** - * Copy constructor - * - * @param range the other time range - */ - public TmfTimeRange(final TmfTimeRange range) { - if (range == null) { - throw new IllegalArgumentException(); - } - fStartTime = range.getStartTime(); - fEndTime = range.getEndTime(); - } - - // ------------------------------------------------------------------------ - // Getters - // ------------------------------------------------------------------------ - - /** - * @return the time range start time - */ - public ITmfTimestamp getStartTime() { - return fStartTime; - } - - /** - * @return the time range end time - */ - public ITmfTimestamp getEndTime() { - return fEndTime; - } - - // ------------------------------------------------------------------------ - // Predicates - // ------------------------------------------------------------------------ - - /** - * Check if the timestamp is within the time range - * - * @param ts - * The timestamp to check - * @return True if [startTime] <= [ts] <= [endTime] - */ - public boolean contains(final ITmfTimestamp ts) { - return (fStartTime.compareTo(ts, true) <= 0) && (fEndTime.compareTo(ts, true) >= 0); - } - - /** - * Check if the time range is within the time range - * - * @param range - * The other time range - * @return True if [range] is fully contained - */ - public boolean contains(final TmfTimeRange range) { - final ITmfTimestamp startTime = range.getStartTime(); - final ITmfTimestamp endTime = range.getEndTime(); - return (fStartTime.compareTo(startTime, true) <= 0) && (fEndTime.compareTo(endTime, true) >= 0); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Get intersection of two time ranges - * - * @param range the other time range - * @return the intersection time range, or null if no intersection exists - */ - public TmfTimeRange getIntersection(final TmfTimeRange range) { - if (fStartTime.compareTo(range.fEndTime, true) > 0 || fEndTime.compareTo(range.fStartTime, true) < 0) { - return null; // no intersection - } - - return new TmfTimeRange(fStartTime.compareTo(range.fStartTime, true) < 0 - ? range.fStartTime - : fStartTime, fEndTime.compareTo(range.fEndTime, true) > 0 - ? range.fEndTime - : fEndTime); - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + fEndTime.hashCode(); - result = prime * result + fStartTime.hashCode(); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof TmfTimeRange)) { - return false; - } - final TmfTimeRange other = (TmfTimeRange) obj; - if (!fEndTime.equals(other.fEndTime)) { - return false; - } - if (!fStartTime.equals(other.fStartTime)) { - return false; - } - return true; - } - - @Override - @SuppressWarnings("nls") - public String toString() { - return "TmfTimeRange [fStartTime=" + fStartTime + ", fEndTime=" + fEndTime + "]"; - } - - // ------------------------------------------------------------------------ - // Inner classes - // ------------------------------------------------------------------------ - - /** - * "Eternity" time range, representing the largest time range possible, - * which includes any other time range or timestamp. - */ - private static final class EternityTimeRange extends TmfTimeRange { - - public EternityTimeRange() { - super(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); - } - - @Override - public boolean contains(ITmfTimestamp ts) { - return true; - } - - @Override - public boolean contains(TmfTimeRange range) { - return true; - } - - @Override - public TmfTimeRange getIntersection(TmfTimeRange range) { - return range; - } - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestamp.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestamp.java deleted file mode 100644 index 95648c55cc..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestamp.java +++ /dev/null @@ -1,384 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Thomas Gatterweh - Updated scaling / synchronization - * Francois Chouinard - Refactoring to align with TMF Event Model 1.0 - * Francois Chouinard - Implement augmented interface - * Geneviève Bastien - Added copy constructor with new value - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.timestamp; - -import java.nio.ByteBuffer; - -/** - * A generic timestamp implementation. The timestamp is represented by the - * tuple { value, scale, precision }. By default, timestamps are scaled in - * seconds. - * - * @author Francois Chouinard - * @version 1.1 - * @since 2.0 - */ -public class TmfTimestamp implements ITmfTimestamp { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The beginning of time - */ - public static final ITmfTimestamp BIG_BANG = - new TmfTimestamp(Long.MIN_VALUE, Integer.MAX_VALUE, 0); - - /** - * The end of time - */ - public static final ITmfTimestamp BIG_CRUNCH = - new TmfTimestamp(Long.MAX_VALUE, Integer.MAX_VALUE, 0); - - /** - * A more practical definition of "beginning of time" - */ - public static final ITmfTimestamp PROJECT_IS_FUNDED = BIG_BANG; - - /** - * A more practical definition of "end of time" - */ - public static final ITmfTimestamp PROJECT_IS_CANNED = BIG_CRUNCH; - - /** - * Zero - */ - public static final ITmfTimestamp ZERO = - new TmfTimestamp(0, 0, 0); - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The timestamp raw value (mantissa) - */ - private final long fValue; - - /** - * The timestamp scale (magnitude) - */ - private final int fScale; - - /** - * The value precision (tolerance) - */ - private final int fPrecision; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - public TmfTimestamp() { - this(0, ITmfTimestamp.SECOND_SCALE, 0); - } - - /** - * Simple constructor (scale = precision = 0) - * - * @param value the timestamp value - */ - public TmfTimestamp(final long value) { - this(value, ITmfTimestamp.SECOND_SCALE, 0); - } - - /** - * Simple constructor (precision = 0) - * - * @param value the timestamp value - * @param scale the timestamp scale - */ - public TmfTimestamp(final long value, final int scale) { - this(value, scale, 0); - } - - /** - * Full constructor - * - * @param value the timestamp value - * @param scale the timestamp scale - * @param precision the timestamp precision - */ - public TmfTimestamp(final long value, final int scale, final int precision) { - fValue = value; - fScale = scale; - fPrecision = Math.abs(precision); - } - - /** - * Copy constructor - * - * @param timestamp the timestamp to copy - */ - public TmfTimestamp(final ITmfTimestamp timestamp) { - if (timestamp == null) { - throw new IllegalArgumentException(); - } - fValue = timestamp.getValue(); - fScale = timestamp.getScale(); - fPrecision = timestamp.getPrecision(); - } - - /** - * Copies a timestamp but with a new time value - * - * @param timestamp - * The timestamp to copy - * @param newvalue - * The value the new timestamp will have - * @since 3.0 - */ - public TmfTimestamp(ITmfTimestamp timestamp, long newvalue) { - if (timestamp == null) { - throw new IllegalArgumentException(); - } - fValue = newvalue; - fScale = timestamp.getScale(); - fPrecision = timestamp.getPrecision(); - } - - // ------------------------------------------------------------------------ - // ITmfTimestamp - // ------------------------------------------------------------------------ - - /** - * Construct the timestamp from the ByteBuffer. - * - * @param bufferIn - * the buffer to read from - * - * @since 3.0 - */ - public TmfTimestamp(ByteBuffer bufferIn) { - this(bufferIn.getLong(), bufferIn.getInt(), bufferIn.getInt()); - } - - @Override - public long getValue() { - return fValue; - } - - @Override - public int getScale() { - return fScale; - } - - @Override - public int getPrecision() { - return fPrecision; - } - - private static final long scalingFactors[] = new long[] { - 1L, - 10L, - 100L, - 1000L, - 10000L, - 100000L, - 1000000L, - 10000000L, - 100000000L, - 1000000000L, - 10000000000L, - 100000000000L, - 1000000000000L, - 10000000000000L, - 100000000000000L, - 1000000000000000L, - 10000000000000000L, - 100000000000000000L, - 1000000000000000000L, - }; - - @Override - public ITmfTimestamp normalize(final long offset, final int scale) { - - long value = fValue; - int precision = fPrecision; - - // Handle the trivial case - if (fScale == scale && offset == 0) { - return this; - } - - // In case of big bang and big crunch just return this (no need to normalize) - if (this.equals(BIG_BANG) || this.equals(BIG_CRUNCH)) { - return this; - } - - // First, scale the timestamp - if (fScale != scale) { - final int scaleDiff = Math.abs(fScale - scale); - if (scaleDiff >= scalingFactors.length) { - throw new ArithmeticException("Scaling exception"); //$NON-NLS-1$ - } - - final long scalingFactor = scalingFactors[scaleDiff]; - if (scale < fScale) { - value *= scalingFactor; - precision *= scalingFactor; - } else { - value /= scalingFactor; - precision /= scalingFactor; - } - } - - // Then, apply the offset - if (offset < 0) { - value = (value < Long.MIN_VALUE - offset) ? Long.MIN_VALUE : value + offset; - } else { - value = (value > Long.MAX_VALUE - offset) ? Long.MAX_VALUE : value + offset; - } - - return new TmfTimestamp(value, scale, precision); - } - - @Override - public int compareTo(final ITmfTimestamp ts, final boolean withinPrecision) { - - // Check the corner cases (we can't use equals() because it uses compareTo()...) - if (ts == null) { - return 1; - } - if (this == ts || (fValue == ts.getValue() && fScale == ts.getScale())) { - return 0; - } - if ((fValue == BIG_BANG.getValue() && fScale == BIG_BANG.getScale()) || (ts.getValue() == BIG_CRUNCH.getValue() && ts.getScale() == BIG_CRUNCH.getScale())) { - return -1; - } - if ((fValue == BIG_CRUNCH.getValue() && fScale == BIG_CRUNCH.getScale()) || (ts.getValue() == BIG_BANG.getValue() && ts.getScale() == BIG_BANG.getScale())) { - return 1; - } - - try { - final ITmfTimestamp nts = ts.normalize(0, fScale); - final long delta = fValue - nts.getValue(); - if ((delta == 0) || (withinPrecision && (Math.abs(delta) <= (fPrecision + nts.getPrecision())))) { - return 0; - } - return (delta > 0) ? 1 : -1; - } - catch (final ArithmeticException e) { - // Scaling error. We can figure it out nonetheless. - - // First, look at the sign of the mantissa - final long value = ts.getValue(); - if (fValue == 0 && value == 0) { - return 0; - } - if (fValue < 0 && value >= 0) { - return -1; - } - if (fValue >= 0 && value < 0) { - return 1; - } - - // Otherwise, just compare the scales - final int scale = ts.getScale(); - return (fScale > scale) ? (fValue >= 0) ? 1 : -1 : (fValue >= 0) ? -1 : 1; - } - } - - @Override - public ITmfTimestamp getDelta(final ITmfTimestamp ts) { - final ITmfTimestamp nts = ts.normalize(0, fScale); - final long value = fValue - nts.getValue(); - return new TmfTimestampDelta(value, fScale, fPrecision + nts.getPrecision()); - } - - @Override - public boolean intersects(TmfTimeRange range) { - if (this.compareTo(range.getStartTime()) >= 0 && - this.compareTo(range.getEndTime()) <= 0) { - return true; - } - return false; - } - - // ------------------------------------------------------------------------ - // Comparable - // ------------------------------------------------------------------------ - - @Override - public int compareTo(final ITmfTimestamp ts) { - return compareTo(ts, false); - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + (int) (fValue ^ (fValue >>> 32)); - result = prime * result + fScale; - result = prime * result + fPrecision; - return result; - } - - @Override - public boolean equals(final Object other) { - if (this == other) { - return true; - } - if (other == null) { - return false; - } - if (!(other instanceof TmfTimestamp)) { - return false; - } - final TmfTimestamp ts = (TmfTimestamp) other; - return compareTo(ts, false) == 0; - } - - @Override - public String toString() { - return toString(TmfTimestampFormat.getDefaulTimeFormat()); - } - - /** - * @since 2.0 - */ - @Override - public String toString(final TmfTimestampFormat format) { - try { - ITmfTimestamp ts = normalize(0, ITmfTimestamp.NANOSECOND_SCALE); - return format.format(ts.getValue()); - } - catch (ArithmeticException e) { - return format.format(0); - } - } - - /** - * Write the time stamp to the ByteBuffer so that it can be saved to disk. - * @param bufferOut the buffer to write to - * - * @since 3.0 - */ - public void serialize(ByteBuffer bufferOut) { - bufferOut.putLong(fValue); - bufferOut.putInt(fScale); - bufferOut.putInt(fPrecision); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestampDelta.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestampDelta.java deleted file mode 100644 index ea0775f993..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestampDelta.java +++ /dev/null @@ -1,105 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.core.timestamp; - -import java.util.TimeZone; - -/** - * A generic timestamp implementation for delta between timestamps. - * The toString() method takes negative values into consideration. - * - * @author Bernd Hufmann - * @since 2.0 - */ -public class TmfTimestampDelta extends TmfTimestamp { - - // ------------------------------------------------------------------------ - // Members - // ------------------------------------------------------------------------ - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor - */ - public TmfTimestampDelta() { - super(); - } - - /** - * Simple constructor (scale = precision = 0) - * - * @param value the timestamp value - */ - - public TmfTimestampDelta(long value) { - super(value); - } - - /** - * Simple constructor (precision = 0) - * - * @param value the timestamp value - * @param scale the timestamp scale - */ - public TmfTimestampDelta(long value, int scale) { - super(value, scale); - } - - - /** - * Copy constructor - * - * @param timestamp the timestamp to copy - */ - public TmfTimestampDelta(ITmfTimestamp timestamp) { - super(timestamp); - } - - /** - * Full constructor - * - * @param value the timestamp value - * @param scale the timestamp scale - * @param precision the timestamp precision - */ - public TmfTimestampDelta(long value, int scale, int precision) { - super(value, scale, precision); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Override - public ITmfTimestamp normalize(final long offset, final int scale) { - ITmfTimestamp nts = super.normalize(offset, scale); - return new TmfTimestampDelta(nts.getValue(), nts.getScale(), nts.getPrecision()); - } - - @Override - public String toString() { - return toString(TmfTimestampFormat.getDefaulIntervalFormat()); - } - - @Override - public String toString(TmfTimestampFormat format) { - if (getValue() < 0) { - TmfTimestampDelta tmpTs = new TmfTimestampDelta(-getValue(), getScale(), getPrecision()); - return "-" + tmpTs.toString(format); //$NON-NLS-1$ - } - TmfTimestampFormat deltaFormat = new TmfTimestampFormat(format.toPattern()); - deltaFormat.setTimeZone(TimeZone.getTimeZone("UTC")); //$NON-NLS-1$ - return super.toString(deltaFormat); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestampFormat.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestampFormat.java deleted file mode 100644 index e682409a26..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestampFormat.java +++ /dev/null @@ -1,802 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Marc-Andre Laperle - Add time zone preference - * Patrick Tasse - Updated for negative value formatting and fraction of sec - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.timestamp; - -import java.text.DecimalFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.List; -import java.util.Locale; -import java.util.TimeZone; - -/** - * A formatting and parsing facility that can handle timestamps that span the - * epoch with a precision down to the nanosecond. It can be understood as an - * extension of SimpleDateFormat that supports seconds since the epoch (Jan 1, - * 1970, 00:00:00 GMT), additional sub-second patterns and optional delimiters. - *

- * The timestamp representation is broken down into a number of optional - * components that can be assembled into a fairly simple way. - * - *

Date and Time Patterns

- * All date and time pattern letters defined in {@link SimpleDateFormat} are - * supported with the following exceptions: - *
- * - * - * - * - * - *
Format - * Description - * Value Range - * Example - *
T - * The seconds since the epoch - * 0-9223372036 - * 1332170682 - *
S - * Millisecond - * N/A - * Not supported - *
W - * Week in month - * N/A - * Not supported - *
- *
- *

- * Note: When parsing, if "T" is used, no other Date and Time - * pattern letter will be interpreted and the entire pre-delimiter input string - * will be parsed as a number. Also, "T" should be used for time intervals. - *

- * Note: The decimal separator between the Date and Time - * pattern and the Sub-Seconds pattern is mandatory (if there is a fractional - * part) and must be one of the sub-second delimiters. Date and Time pattern - * letters are not interpreted after the decimal separator. - *

- *

Sub-Seconds Patterns

- *
- * - * - * - * - * - *
Format - * Description - * Value Range - * Example - *
S - * Fraction of second - * 0-999999999 - * 123456789 - *
C - * Microseconds in ms - * 0-999 - * 456 - *
N - * Nanoseconds in µs - * 0-999 - * 789 - *
- *
- * Note: The fraction of second pattern can be split, in which - * case parsing and formatting continues at the next digit. Digits beyond the - * total number of pattern letters are ignored when parsing and truncated when - * formatting. - *

- * Note: When parsing, "S", "C" and "N" are interchangeable - * and are all handled as fraction of second ("S"). The use of "C" and "N" is - * discouraged but is supported for backward compatibility. - *

- * - * The recognized sub-second delimiters are: - *

    - *
  • Space (" ") - *
  • Period (".") - *
  • Comma (",") - *
  • Dash ("-") - *
  • Underline ("_") - *
  • Colon (":") - *
  • Semicolon (";") - *
  • Slash ("/") - *
  • Single-quote ("''") - *
  • Double-quote (""") - *
- *

- * Note: When parsing, sub-second delimiters are optional if - * unquoted. However, an extra delimiter or any other unexpected character in - * the input string ends the parsing of digits. All other quoted or unquoted - * characters in the sub-second pattern are matched against the input string. - * - *

Examples

- * The following examples show how timestamp patterns are interpreted in - * the U.S. locale. The given timestamp is 1332170682539677389L, the number - * of nanoseconds since 1970/01/01. - * - *
- * - * - * - * - * - * - * - * - *
Date and Time Pattern - * Result - *
"yyyy-MM-dd HH:mm:ss.SSS.SSS.SSS" - * 2012-03-19 11:24:42.539.677.389 - *
"yyyy-MM-dd HH:mm:ss.SSS.SSS" - * 2012-03-19 11:24:42.539.677 - *
"yyyy-D HH:mm:ss.SSS.SSS" - * 2012-79 11:24:42.539.677 - *
"ss,SSSS" - * 42,5397 - *
"T.SSS SSS SSS" - * 1332170682.539 677 389 - *
"T" - * 1332170682 - *
- *
- *

- * @version 1.0 - * @since 2.0 - * @author Francois Chouinard - */ -public class TmfTimestampFormat extends SimpleDateFormat { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * This class' serialization ID - */ - private static final long serialVersionUID = 2835829763122454020L; - - /** - * The default timestamp pattern - */ - public static final String DEFAULT_TIME_PATTERN = "HH:mm:ss.SSS SSS SSS"; //$NON-NLS-1$ - - /** - * The default interval pattern - */ - public static final String DEFAULT_INTERVAL_PATTERN = "TTT.SSS SSS SSS"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // The default timestamp pattern - private static TmfTimestampFormat fDefaultTimeFormat = null; - - // The default time interval format - private static TmfTimestampFormat fDefaultIntervalFormat = null; - - // The timestamp pattern - private String fPattern; - - // The index of the decimal separator in the pattern - private int fPatternDecimalSeparatorIndex; - - // The decimal separator - private char fDecimalSeparator = '\0'; - - // The date and time pattern unquoted characters - private String fDateTimePattern; - - // The sub-seconds pattern - private String fSubSecPattern; - - // The list of supplementary patterns - private List fSupplPatterns = new ArrayList<>(); - - // The locale - private final Locale fLocale; - - /** - * The supplementary pattern letters. Can be redefined by sub-classes - * to either override existing letters or augment the letter set. - * If so, the format() method must provide the (re-)implementation of the - * pattern. - */ - protected String fSupplPatternLetters = "TSCN"; //$NON-NLS-1$ - /** - * The sub-second pattern letters. - * @since 3.0 - */ - protected String fSubSecPatternChars = "SCN"; //$NON-NLS-1$ - /** - * The optional sub-second delimiter characters. - * @since 3.0 - */ - protected String fDelimiterChars = " .,-_:;/'\""; //$NON-NLS-1$ - - /* - * The bracketing symbols used to mitigate the risk of a format string - * that contains escaped sequences that would conflict with our format - * extension. - */ - /** The open bracket symbol */ - protected String fOpenBracket = "[&"; //$NON-NLS-1$ - - /** The closing bracket symbol */ - protected String fCloseBracket = "&]"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * The default constructor (uses the default pattern) - */ - public TmfTimestampFormat() { - this(TmfTimePreferences.getInstance().getTimePattern()); - } - - /** - * The normal constructor - * - * @param pattern the format pattern - */ - public TmfTimestampFormat(String pattern) { - fLocale = Locale.getDefault(); - applyPattern(pattern); - } - - /** - * The full constructor - * - * @param pattern the format pattern - * @param timeZone the time zone - * @since 2.1 - */ - public TmfTimestampFormat(String pattern, TimeZone timeZone) { - fLocale = Locale.getDefault(); - setTimeZone(timeZone); - applyPattern(pattern); - } - - /** - * The fuller constructor - * - * @param pattern the format pattern - * @param timeZone the time zone - * @param locale the locale - * @since 3.2 - */ - public TmfTimestampFormat(String pattern, TimeZone timeZone, Locale locale) { - super("", locale); //$NON-NLS-1$ - fLocale = locale; - setTimeZone(timeZone); - setCalendar(Calendar.getInstance(timeZone, locale)); - applyPattern(pattern); - } - - /** - * The copy constructor - * - * @param other the other format pattern - */ - public TmfTimestampFormat(TmfTimestampFormat other) { - this(other.fPattern, other.getTimeZone(), other.fLocale); - } - - // ------------------------------------------------------------------------ - // Getters/setters - // ------------------------------------------------------------------------ - - /** - * @since 2.1 - */ - public static void updateDefaultFormats() { - fDefaultTimeFormat = new TmfTimestampFormat( - TmfTimePreferences.getInstance().getTimePattern(), - TmfTimePreferences.getInstance().getTimeZone(), - TmfTimePreferences.getInstance().getLocale()); - fDefaultIntervalFormat = new TmfTimestampFormat(TmfTimePreferences.getInstance().getIntervalPattern()); - } - - /** - * @return the default time format pattern - */ - public static TmfTimestampFormat getDefaulTimeFormat() { - if (fDefaultTimeFormat == null) { - fDefaultTimeFormat = new TmfTimestampFormat( - TmfTimePreferences.getInstance().getTimePattern(), - TmfTimePreferences.getInstance().getTimeZone(), - TmfTimePreferences.getInstance().getLocale()); - } - return fDefaultTimeFormat; - } - - /** - * @return the default interval format pattern - */ - public static TmfTimestampFormat getDefaulIntervalFormat() { - if (fDefaultIntervalFormat == null) { - fDefaultIntervalFormat = new TmfTimestampFormat(TmfTimePreferences.getInstance().getIntervalPattern()); - } - return fDefaultIntervalFormat; - } - - @Override - public void applyPattern(String pattern) { - fPattern = pattern; - fPatternDecimalSeparatorIndex = indexOfPatternDecimalSeparator(pattern); - fDateTimePattern = unquotePattern(pattern.substring(0, fPatternDecimalSeparatorIndex)); - // Check that 'S' is not present in the date and time pattern - if (fDateTimePattern.indexOf('S') != -1) { - throw new IllegalArgumentException("Illegal pattern character 'S'"); //$NON-NLS-1$ - } - // Check that 'W' is not present in the date and time pattern - if (fDateTimePattern.indexOf('W') != -1) { - throw new IllegalArgumentException("Illegal pattern character 'W'"); //$NON-NLS-1$ - } - // The super pattern is the date/time pattern, quoted and bracketed - super.applyPattern(quoteSpecificTags(pattern.substring(0, fPatternDecimalSeparatorIndex), true)); - // The sub-seconds pattern is bracketed (but not quoted) - fSubSecPattern = quoteSpecificTags(pattern.substring(fPatternDecimalSeparatorIndex), false); - } - - @Override - public String toPattern() { - return fPattern; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Format the timestamp according to its pattern. - * - * @param value the timestamp value to format (in ns) - * @return the formatted timestamp - */ - public synchronized String format(long value) { - - // Split the timestamp value into its sub-components - long date = value / 1000000; // milliseconds since January 1, 1970, 00:00:00 GMT - long sec = value / 1000000000; // seconds since January 1, 1970, 00:00:00 GMT - long ms = Math.abs((value % 1000000000) / 1000000); // milliseconds - long cs = Math.abs((value % 1000000) / 1000); // microseconds - long ns = Math.abs(value % 1000); // nanoseconds - - // Adjust for negative value when formatted as a date - if (value < 0 && ms + cs + ns > 0 && !super.toPattern().contains(fOpenBracket + "T")) { //$NON-NLS-1$ - date -= 1; - long nanosec = 1000000000 - (1000000 * ms + 1000 * cs + ns); - ms = nanosec / 1000000; - cs = (nanosec % 1000000) / 1000; - ns = nanosec % 1000; - } - - // Let the base class format the date/time pattern - StringBuffer result = new StringBuffer(super.format(date)); - // Append the sub-second pattern - result.append(fSubSecPattern); - - int fractionDigitsPrinted = 0; - // Fill in our extensions - for (String pattern : fSupplPatterns) { - int length = pattern.length(); - long val = 0; - int bufLength = 0; - - // Format the proper value as per the pattern - switch (pattern.charAt(0)) { - case 'T': - if (value < 0 && sec == 0) { - result.insert(0, '-'); - } - val = sec; - bufLength = Math.min(length, 10); - break; - case 'S': - val = 1000000 * ms + 1000 * cs + ns; - bufLength = 9; - break; - case 'C': - val = cs; - bufLength = Math.min(length, 3); - break; - case 'N': - val = ns; - bufLength = Math.min(length, 3); - break; - default: - break; - } - - // Prepare the format buffer - StringBuffer fmt = new StringBuffer(); - for (int i = 0; i < bufLength; i++) { - fmt.append("0"); //$NON-NLS-1$ - } - DecimalFormat dfmt = new DecimalFormat(fmt.toString()); - String fmtVal = dfmt.format(val); - if (pattern.charAt(0) == 'S') { - fmtVal = fmtVal.substring(fractionDigitsPrinted, Math.min(bufLength, fractionDigitsPrinted + length)); - fractionDigitsPrinted += fmtVal.length(); - } - - // Substitute the placeholder pattern with the formatted value - String ph = new StringBuffer(fOpenBracket + pattern + fCloseBracket).toString(); - int loc = result.indexOf(ph); - result.replace(loc, loc + length + fOpenBracket.length() + fCloseBracket.length(), fmtVal); - } - - return result.toString(); - } - - /** - * Parse a string according to the format pattern - * - * @param source the source string - * @param ref the reference (base) time (in ns) - * @return the parsed value (in ns) - * @throws ParseException if the string has an invalid format - */ - public synchronized long parseValue(final String source, final long ref) throws ParseException { - - // Trivial case - if (source == null || source.length() == 0) { - return 0; - } - - long seconds = 0; - boolean isNegative = source.charAt(0) == '-'; - boolean isDateTimeFormat = true; - - int index = indexOfSourceDecimalSeparator(source); - - // Check for seconds in epoch pattern - for (String pattern : fSupplPatterns) { - if (pattern.charAt(0) == 'T') { - isDateTimeFormat = false; - // Remove everything up to the first "." and compute the - // number of seconds since the epoch. If there is no period, - // assume an integer value and return immediately - if (index == 0 || (isNegative && index <= 1)) { - seconds = 0; - } else if (index == source.length()) { - return new DecimalFormat("0").parse(source).longValue() * 1000000000; //$NON-NLS-1$ - } else { - seconds = new DecimalFormat("0").parse(source.substring(0, index)).longValue(); //$NON-NLS-1$ - } - break; - } - } - - // If there was no "T" (thus not an interval), parse as a date - if (isDateTimeFormat && super.toPattern().length() > 0) { - Date baseDate = super.parse(source.substring(0, index)); - getCalendar(); - - if (ref != Long.MIN_VALUE) { - Calendar baseTime = Calendar.getInstance(getTimeZone(), fLocale); - baseTime.setTimeInMillis(baseDate.getTime()); - Calendar newTime = Calendar.getInstance(getTimeZone(), fLocale); - newTime.setTimeInMillis(ref / 1000000); - boolean setRemainingFields = false; - if (dateTimePatternContains("yY")) { //$NON-NLS-1$ - newTime.set(Calendar.YEAR, baseTime.get(Calendar.YEAR)); - setRemainingFields = true; - } - if (setRemainingFields || dateTimePatternContains("M")) { //$NON-NLS-1$ - newTime.set(Calendar.MONTH, baseTime.get(Calendar.MONTH)); - setRemainingFields = true; - } - if (setRemainingFields || dateTimePatternContains("d")) { //$NON-NLS-1$ - newTime.set(Calendar.DATE, baseTime.get(Calendar.DATE)); - setRemainingFields = true; - } else if (dateTimePatternContains("D")) { //$NON-NLS-1$ - newTime.set(Calendar.DAY_OF_YEAR, baseTime.get(Calendar.DAY_OF_YEAR)); - setRemainingFields = true; - } else if (dateTimePatternContains("w")) { //$NON-NLS-1$ - newTime.set(Calendar.WEEK_OF_YEAR, baseTime.get(Calendar.WEEK_OF_YEAR)); - setRemainingFields = true; - } - if (dateTimePatternContains("F")) { //$NON-NLS-1$ - newTime.set(Calendar.DAY_OF_WEEK_IN_MONTH, baseTime.get(Calendar.DAY_OF_WEEK_IN_MONTH)); - setRemainingFields = true; - } - if (dateTimePatternContains("Eu")) { //$NON-NLS-1$ - newTime.set(Calendar.DAY_OF_WEEK, baseTime.get(Calendar.DAY_OF_WEEK)); - setRemainingFields = true; - } - if (setRemainingFields || dateTimePatternContains("aHkKh")) { //$NON-NLS-1$ - newTime.set(Calendar.HOUR_OF_DAY, baseTime.get(Calendar.HOUR_OF_DAY)); - setRemainingFields = true; - } - if (setRemainingFields || dateTimePatternContains("m")) { //$NON-NLS-1$ - newTime.set(Calendar.MINUTE, baseTime.get(Calendar.MINUTE)); - setRemainingFields = true; - } - if (setRemainingFields || dateTimePatternContains("s")) { //$NON-NLS-1$ - newTime.set(Calendar.SECOND, baseTime.get(Calendar.SECOND)); - } - newTime.set(Calendar.MILLISECOND, 0); - seconds = newTime.getTimeInMillis() / 1000; - } else { - seconds = baseDate.getTime() / 1000; - } - } else if (isDateTimeFormat && ref != Long.MIN_VALUE) { - // If the date and time pattern is empty, adjust for reference - seconds = ref / 1000000000; - } - - long nanos = parseSubSeconds(source.substring(index)); - if (isNegative && !isDateTimeFormat) { - nanos = -nanos; - } - // Compute the value in ns - return seconds * 1000000000 + nanos; - } - - /** - * Parse a string according to the format pattern - * - * @param source the source string - * @return the parsed value (in ns) - * @throws ParseException if the string has an invalid format - */ - public long parseValue(final String source) throws ParseException { - long result = parseValue(source, Long.MIN_VALUE); - return result; - - } - - // ------------------------------------------------------------------------ - // Helper functions - // ------------------------------------------------------------------------ - - /** - * Finds the index of the decimal separator in the pattern string, which is - * the last delimiter found before the first sub-second pattern character. - * Returns the pattern string length if decimal separator is not found. - */ - private int indexOfPatternDecimalSeparator(String pattern) { - int lastDelimiterIndex = pattern.length(); - boolean inQuote = false; - int index = 0; - while (index < pattern.length()) { - char ch = pattern.charAt(index); - if (ch == '\'') { - if (index + 1 < pattern.length()) { - index++; - ch = pattern.charAt(index); - if (ch != '\'') { - inQuote = !inQuote; - } - } - } - if (!inQuote) { - if (fSubSecPatternChars.indexOf(ch) != -1) { - if (lastDelimiterIndex < pattern.length()) { - fDecimalSeparator = pattern.charAt(lastDelimiterIndex); - } - return lastDelimiterIndex; - } - if (fDelimiterChars.indexOf(ch) != -1) { - lastDelimiterIndex = index; - if (ch == '\'') { - lastDelimiterIndex--; - } - } - } - index++; - } - return pattern.length(); - } - - /** - * Finds the first index of a decimal separator in the source string. - * Skips the number of decimal separators in the format pattern. - * Returns the source string length if decimal separator is not found. - */ - private int indexOfSourceDecimalSeparator(String source) { - String pattern = fPattern.substring(0, fPatternDecimalSeparatorIndex); - String separator = fDecimalSeparator == '\'' ? "''" : String.valueOf(fDecimalSeparator); //$NON-NLS-1$ - int sourcePos = source.indexOf(fDecimalSeparator); - int patternPos = pattern.indexOf(separator); - while (patternPos != -1 && sourcePos != -1) { - sourcePos = source.indexOf(fDecimalSeparator, sourcePos + 1); - patternPos = pattern.indexOf(separator, patternPos + separator.length()); - } - if (sourcePos == -1) { - sourcePos = source.length(); - } - return sourcePos; - } - - /** - * Parse the sub-second digits in the input. Handle delimiters as optional - * characters. Match any non-pattern and non-delimiter pattern characters - * against the input. Returns the number of nanoseconds. - */ - private long parseSubSeconds(String input) throws ParseException { - StringBuilder digits = new StringBuilder("000000000"); //$NON-NLS-1$ - String pattern = fPattern.substring(fPatternDecimalSeparatorIndex); - boolean inQuote = false; - int digitIndex = 0; - int inputIndex = 0; - int patternIndex = 0; - while (patternIndex < pattern.length()) { - char ch = pattern.charAt(patternIndex); - if (ch == '\'') { - patternIndex++; - if (patternIndex < pattern.length()) { - ch = pattern.charAt(patternIndex); - if (ch != '\'') { - inQuote = !inQuote; - } - } else if (inQuote) { - // final end quote - break; - } - } - if (fDelimiterChars.indexOf(ch) != -1 && !inQuote) { - // delimiter is optional if not in quote - if (inputIndex < input.length() && input.charAt(inputIndex) == ch) { - inputIndex++; - } - patternIndex++; - continue; - } else if (fSubSecPatternChars.indexOf(ch) != -1 && !inQuote) { - // read digit if not in quote - if (inputIndex < input.length() && Character.isDigit(input.charAt(inputIndex))) { - if (digitIndex < digits.length()) { - digits.setCharAt(digitIndex, input.charAt(inputIndex)); - digitIndex++; - } - inputIndex++; - } else { - // not a digit, stop parsing digits - digitIndex = digits.length(); - } - patternIndex++; - continue; - } - if (inputIndex >= input.length() || input.charAt(inputIndex) != ch) { - throw new ParseException("Unparseable sub-seconds: \"" + input + '\"', inputIndex); //$NON-NLS-1$ - } - patternIndex++; - inputIndex++; - } - return Long.parseLong(digits.toString()); - } - - /** - * Copy the pattern but quote (bracket with "[&" and "&]") the - * TmfTimestampFormat specific tags. Optionally surround tags with single - * quotes so these fields are treated as comments by the base class. - * - * It also keeps track of the corresponding quoted fields so they can be - * properly populated later on (by format()). - * - * @param pattern - * the 'extended' pattern - * @param includeQuotes - * true to include quotes from pattern and add single quotes - * around tags - * @return the quoted and bracketed pattern - */ - private String quoteSpecificTags(final String pattern, boolean includeQuotes) { - - StringBuffer result = new StringBuffer(); - - int length = pattern.length(); - boolean inQuote = false; - - for (int i = 0; i < length; i++) { - char c = pattern.charAt(i); - if (c != '\'' || includeQuotes) { - result.append(c); - } - if (c == '\'') { - // '' is treated as a single quote regardless of being - // in a quoted section. - if ((i + 1) < length) { - c = pattern.charAt(i + 1); - if (c == '\'') { - i++; - result.append(c); - continue; - } - } - inQuote = !inQuote; - continue; - } - if (!inQuote && (fSupplPatternLetters.indexOf(c) != -1)) { - if (pattern.charAt(0) == fDecimalSeparator) { - if (fSubSecPatternChars.indexOf(c) == -1) { - // do not quote non-sub-second pattern letters in sub-second pattern - continue; - } - } else { - if (fSubSecPatternChars.indexOf(c) != -1) { - // do not quote sub-second pattern letters in date and time pattern - continue; - } - } - StringBuilder pat = new StringBuilder(); - pat.append(c); - if (includeQuotes) { - result.insert(result.length() - 1, "'"); //$NON-NLS-1$ - } - result.insert(result.length() - 1, fOpenBracket); - while ((i + 1) < length && pattern.charAt(i + 1) == c) { - result.append(c); - pat.append(c); - i++; - } - result.append(fCloseBracket); - if (includeQuotes) { - result.append("'"); //$NON-NLS-1$ - } - fSupplPatterns.add(pat.toString()); - } - } - return result.toString(); - } - - /** - * Returns the unquoted characters in this pattern. - */ - private static String unquotePattern(String pattern) { - boolean inQuote = false; - int index = 0; - StringBuilder result = new StringBuilder(); - while (index < pattern.length()) { - char ch = pattern.charAt(index); - if (ch == '\'') { - if (index + 1 < pattern.length()) { - index++; - ch = pattern.charAt(index); - if (ch != '\'') { - inQuote = !inQuote; - } - } - } - if (!inQuote) { - result.append(ch); - } - index++; - } - return result.toString(); - } - - /** - * Returns true if the date and time pattern contains any of these chars. - */ - private boolean dateTimePatternContains(String chars) { - int index = 0; - while (index < chars.length()) { - char ch = chars.charAt(index); - if (fDateTimePattern.indexOf(ch) != -1) { - return true; - } - index++; - } - return false; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfContext.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfContext.java deleted file mode 100644 index f3b526e117..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfContext.java +++ /dev/null @@ -1,88 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Updated as per TMF Trace Model 1.0 - * Patrick Tasse - Updated for removal of context clone - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace; - -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - -/** - * The basic trace context structure in TMF. The purpose of the context is to - * associate a trace location to an event at a specific rank (order). - *

- * The context should be sufficient to allow the trace to position itself so - * that performing a trace read operation will yield the corresponding 'nth' - * event. - * - * @version 1.0 - * @author Francois Chouinard - * - * @see ITmfLocation - */ -public interface ITmfContext { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The unknown event rank - */ - public long UNKNOWN_RANK = -1L; - - // ------------------------------------------------------------------------ - // Getters - // ------------------------------------------------------------------------ - - /** - * @return the rank of the event at the context location - */ - long getRank(); - - /** - * @return the location of the event at the context rank - * @since 3.0 - */ - ITmfLocation getLocation(); - - /** - * @return indicates if the context rank is valid (!= UNKNOWN_RANK) - */ - boolean hasValidRank(); - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * @param location the new location - * @since 3.0 - */ - void setLocation(ITmfLocation location); - - /** - * @param rank the new rank - */ - void setRank(long rank); - - /** - * Increment the context rank - */ - void increaseRank(); - - /** - * Cleanup hook - */ - void dispose(); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfEventParser.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfEventParser.java deleted file mode 100644 index d855f8b267..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfEventParser.java +++ /dev/null @@ -1,38 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Updated as per TMF Trace Model 1.0 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; - -/** - * The generic trace parser in TMF. - * - * @version 1.0 - * @author Francois Chouinard - * - * @see ITmfEvent - * @see ITmfContext - */ -public interface ITmfEventParser { - - /** - * Parses the trace event referenced by the context. - * The context should *not* be altered. - * - * @param context the trace context - * @return a parsed event (null if none) - */ - ITmfEvent parseEvent(ITmfContext context); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTrace.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTrace.java deleted file mode 100644 index 4c2cf3f0a4..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTrace.java +++ /dev/null @@ -1,457 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Updated as per TMF Trace Model 1.0 - * Geneviève Bastien - Added timestamp transforms and timestamp - * creation functions - * Patrick Tasse - Add support for folder elements - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule; -import org.eclipse.linuxtools.tmf.core.component.ITmfEventProvider; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - -/** - * The event stream structure in TMF. In its basic form, a trace has: - *

    - *
  • an associated Eclipse resource - *
  • a path to its location on the file system - *
  • the type of the events it contains - *
  • the number of events it contains - *
  • the time range (span) of the events it contains - *
- * Concrete ITmfTrace classes have to provide a parameter-less constructor and - * an initialization method (initTrace) if they are to be opened from the - * Project View. Also, a validation method (validate) has to be provided - * to ensure that the trace is of the correct type. - *

- * A trace can be accessed simultaneously from multiple threads by various - * application components. To avoid obvious multi-threading issues, the trace - * uses an ITmfContext as a synchronization aid for its read operations. - *

- * A proper ITmfContext can be obtained by performing a seek operation on the - * trace. Seek operations can be performed for a particular event (by rank or - * timestamp) or for a plain trace location. - *

- * Example 1: Process a whole trace - *

- * ITmfContext context = trace.seekEvent(0);
- * ITmfEvent event = trace.getNext(context);
- * while (event != null) {
- *     processEvent(event);
- *     event = trace.getNext(context);
- * }
- * 
- * Example 2: Process 50 events starting from the 1000th event - *
- * int nbEventsRead = 0;
- * ITmfContext context = trace.seekEvent(1000);
- * ITmfEvent event = trace.getNext(context);
- * while (event != null && nbEventsRead < 50) {
- *     nbEventsRead++;
- *     processEvent(event);
- *     event = trace.getNext(context);
- * }
- * 
- * Example 3: Process the events between 2 timestamps (inclusive) - *
- * ITmfTimestamp startTime = ...;
- * ITmfTimestamp endTime = ...;
- * ITmfContext context = trace.seekEvent(startTime);
- * ITmfEvent event = trace.getNext(context);
- * while (event != null && event.getTimestamp().compareTo(endTime) <= 0) {
- *     processEvent(event);
- *     event = trace.getNext(context);
- * }
- * 
- * - * A trace is also an event provider so it can process event requests - * asynchronously (and coalesce compatible, concurrent requests). - *

- * - * Example 4: Process a whole trace (see ITmfEventRequest for - * variants) - *

- * ITmfRequest request = new TmfEventRequest<MyEventType>(MyEventType.class) {
- *     @Override
- *     public void handleData(MyEventType event) {
- *         super.handleData(event);
- *         processEvent(event);
- *     }
- *
- *     @Override
- *     public void handleCompleted() {
- *         finish();
- *         super.handleCompleted();
- *     }
- * };
- *
- * fTrace.handleRequest(request);
- * if (youWant) {
- *     request.waitForCompletion();
- * }
- * 
- * - * @version 1.0 - * @author Francois Chouinard - * - * @see ITmfContext - * @see ITmfEvent - * @see ITmfTraceIndexer - * @see ITmfEventParser - */ -public interface ITmfTrace extends ITmfEventProvider { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The default trace cache size - */ - public static final int DEFAULT_TRACE_CACHE_SIZE = 1000; - - // ------------------------------------------------------------------------ - // Initializers - // ------------------------------------------------------------------------ - - /** - * Initialize a newly instantiated "empty" trace object. This is used to - * properly parameterize an ITmfTrace instantiated with its parameterless - * constructor. - *

- * Typically, the parameterless constructor will provide the block size and - * its associated parser and indexer. - * - * @param resource - * the trace resource - * @param path - * the trace path. The path should suitable for passing to - * java.io.File(String) and should use the - * platform-dependent path separator. - * @param type - * the trace event type - * @throws TmfTraceException - * If we couldn't open the trace - */ - void initTrace(IResource resource, String path, Class type) throws TmfTraceException; - - /** - * Initialize a newly instantiated "empty" trace object. This is used to - * properly parameterize an ITmfTrace instantiated with its parameterless - * constructor. - *

- * Typically, the parameterless constructor will provide the block size and - * its associated parser and indexer. - * - * @param resource - * the trace resource - * @param path - * the trace path - * @param type - * the trace event type - * @param name - * the trace name - * @throws TmfTraceException - * If we couldn't open the trace - */ - void initTrace(IResource resource, String path, Class type, String name) throws TmfTraceException; - - /** - * Validate that the trace is of the correct type. The implementation should - * return a TraceValidationStatus to indicate success with a certain level - * of confidence. - * - * @param project - * the eclipse project - * @param path - * the trace path. The path should suitable for passing to - * java.io.File(String) and should use the - * platform-dependent path separator. - * - * @return an IStatus object with validation result. Use severity OK to - * indicate success. - * @see TraceValidationStatus - * @since 2.0 - */ - IStatus validate(IProject project, String path); - - // ------------------------------------------------------------------------ - // Basic getters - // ------------------------------------------------------------------------ - - /** - * @return the trace event type - */ - Class getEventType(); - - /** - * @return the associated trace resource - */ - IResource getResource(); - - /** - * @return the trace path - */ - String getPath(); - - /** - * @return the trace cache size - */ - int getCacheSize(); - - /** - * Index the trace. Depending on the trace type, this could be done at the - * constructor or initTrace phase too, so this could be implemented as a - * no-op. - * - * @param waitForCompletion - * Should we block the caller until indexing is finished, or not. - * @since 2.0 - */ - void indexTrace(boolean waitForCompletion); - - // ------------------------------------------------------------------------ - // Analysis getters - // ------------------------------------------------------------------------ - - /** - * Returns an analysis module with the given ID. - * - * @param id - * The analysis module ID - * @return The {@link IAnalysisModule} object, or null if an analysis with - * the given ID does no exist. - * @since 3.0 - */ - @Nullable - IAnalysisModule getAnalysisModule(String id); - - /** - * Get a list of all analysis modules currently available for this trace. - * - * @return An iterable view of the analysis modules - * @since 3.0 - */ - @NonNull - Iterable getAnalysisModules(); - - /** - * Get an analysis module belonging to this trace, with the specified ID and - * class. - * - * @param moduleClass - * Returned modules must extend this class - * @param id - * The ID of the analysis module - * @return The analysis module with specified class and ID, or null if no - * such module exists. - * @since 3.0 - */ - @Nullable - T getAnalysisModuleOfClass(Class moduleClass, String id); - - /** - * Return the analysis modules that are of a given class. Module are already - * casted to the requested class. - * - * @param moduleClass - * Returned modules must extend this class - * @return List of modules of class moduleClass - * @since 3.0 - */ - @NonNull - Iterable getAnalysisModulesOfClass(Class moduleClass); - - // ------------------------------------------------------------------------ - // Trace characteristics getters - // ------------------------------------------------------------------------ - - /** - * @return the number of events in the trace - */ - long getNbEvents(); - - /** - * @return the trace time range - * @since 2.0 - */ - TmfTimeRange getTimeRange(); - - /** - * @return the timestamp of the first trace event - * @since 2.0 - */ - ITmfTimestamp getStartTime(); - - /** - * @return the timestamp of the last trace event - * @since 2.0 - */ - ITmfTimestamp getEndTime(); - - /** - * @return the streaming interval in ms (0 if not a streaming trace) - */ - long getStreamingInterval(); - - // ------------------------------------------------------------------------ - // Trace positioning getters - // ------------------------------------------------------------------------ - - /** - * @return the current trace location - * @since 3.0 - */ - ITmfLocation getCurrentLocation(); - - /** - * Returns the ratio (proportion) corresponding to the specified location. - * - * @param location - * a trace specific location - * @return a floating-point number between 0.0 (beginning) and 1.0 (end) - * @since 3.0 - */ - double getLocationRatio(ITmfLocation location); - - // ------------------------------------------------------------------------ - // SeekEvent operations (returning a trace context) - // ------------------------------------------------------------------------ - - /** - * Position the trace at the specified (trace specific) location. - *

- * A null location is interpreted as seeking for the first event of the - * trace. - *

- * If not null, the location requested must be valid otherwise the returned - * context is undefined (up to the implementation to recover if possible). - *

- * - * @param location - * the trace specific location - * @return a context which can later be used to read the corresponding event - * @since 3.0 - */ - ITmfContext seekEvent(ITmfLocation location); - - /** - * Position the trace at the 'rank'th event in the trace. - *

- * A rank <= 0 is interpreted as seeking for the first event of the trace. - *

- * If the requested rank is beyond the last trace event, the context - * returned will yield a null event if used in a subsequent read. - * - * @param rank - * the event rank - * @return a context which can later be used to read the corresponding event - */ - ITmfContext seekEvent(long rank); - - /** - * Position the trace at the first event with the specified timestamp. If - * there is no event with the requested timestamp, a context pointing to the - * next chronological event is returned. - *

- * A null timestamp is interpreted as seeking for the first event of the - * trace. - *

- * If the requested timestamp is beyond the last trace event, the context - * returned will yield a null event if used in a subsequent read. - * - * @param timestamp - * the timestamp of desired event - * @return a context which can later be used to read the corresponding event - * @since 2.0 - */ - ITmfContext seekEvent(ITmfTimestamp timestamp); - - /** - * Position the trace at the event located at the specified ratio in the - * trace file. - *

- * The notion of ratio (0.0 <= r <= 1.0) is trace specific and left - * voluntarily vague. Typically, it would refer to the event proportional - * rank (arguably more intuitive) or timestamp in the trace file. - * - * @param ratio - * the proportional 'rank' in the trace - * @return a context which can later be used to read the corresponding event - */ - ITmfContext seekEvent(double ratio); - - /** - * Returns the initial range offset - * - * @return the initial range offset - * @since 2.0 - */ - ITmfTimestamp getInitialRangeOffset(); - - /** - * Returns the ID of the host this trace is from. The host ID is not - * necessarily the hostname, but should be a unique identifier for the - * machine on which the trace was taken. It can be used to determine if two - * traces were taken on the exact same machine (timestamp are already - * synchronized, resources with same id are the same if taken at the same - * time, etc). - * - * @return The host id of this trace - * @since 3.0 - */ - String getHostId(); - - // ------------------------------------------------------------------------ - // Timestamp transformation functions - // ------------------------------------------------------------------------ - - /** - * Returns the timestamp transformation for this trace - * - * @return the timestamp transform - * @since 3.0 - */ - ITmfTimestampTransform getTimestampTransform(); - - /** - * Sets the trace's timestamp transform - * - * @param tt - * The timestamp transform for all timestamps of this trace - * @since 3.0 - */ - void setTimestampTransform(final ITmfTimestampTransform tt); - - /** - * Creates a timestamp for this trace, using the transformation formula - * - * @param ts - * The time in nanoseconds with which to create the timestamp - * @return The new timestamp - * @since 3.0 - */ - ITmfTimestamp createTimestamp(long ts); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTraceCompleteness.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTraceCompleteness.java deleted file mode 100644 index 67a31eb414..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTraceCompleteness.java +++ /dev/null @@ -1,38 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial implementation - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace; - -/** - * An interface that provides information about the completeness of a trace. A - * trace is considered complete when it is known that no more data will be added - * to it. - * - * @since 3.1 - */ -public interface ITmfTraceCompleteness { - - /** - * Returns whether or not a trace is complete. - * - * @return true if a trace is complete, false otherwise - */ - boolean isComplete(); - - /** - * Set the completeness of a trace. - * - * @param isComplete - * whether the trace should be considered complete or not - */ - void setComplete(boolean isComplete); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTraceProperties.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTraceProperties.java deleted file mode 100644 index 6838b38a2f..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTraceProperties.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace; - -import java.util.Map; - -/** - * Interface for trace types to implement when they can provide additional - * trace-wide properties. - * - * This information will be displayed in the trace's Properties View, among - * other things. - * - * @author Alexandre Montplaisir - * @since 2.0 - */ -public interface ITmfTraceProperties { - - /** - * Get the properties related to this trace. - * - * @return The map of properties, - */ - public Map getTraceProperties(); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTraceWithPreDefinedEvents.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTraceWithPreDefinedEvents.java deleted file mode 100644 index 093ccfffdc..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTraceWithPreDefinedEvents.java +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal, Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace; - -import java.util.Set; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; - -/** - * This interface should be implemented by all trace classes who have a way to - * know in advance what events it may contain. It allows analyses and other - * external components to ask the list of events for the trace might contain. - * - * The methods from this interface will typically be called to determine whether - * or not it is worth reading a trace. If we can know in advance that a trace - * does not contain the events required by an analysis, then the analysis will - * not be run. So the response should not involve having to actually read the - * trace. - * - * @author Geneviève Bastien - * @author Matthew Khouzam - * @since 3.0 - */ -public interface ITmfTraceWithPreDefinedEvents { - - /** - * Return a set of event types declared in the trace, without actually - * reading the trace. This method can be called before reading a trace but - * after it is initialized, in order to compare this set with a set of - * events that a request handles, to determine whether or not it is worth - * reading the trace. - * - * Some trace types have ways to determine the events that were traced - * without having to read the whole trace and this is what this method will - * query. The presence of an event in the returned set does not guarantee - * that an event with this name actually happened during this trace, only - * that it can be there. - * - * The set should be immutable. Destructive set operations should be - * performed on a copy of this set.A helper class - * {@link TmfEventTypeCollectionHelper} will provide ways of working with - * this data structure. - * - * @return The set of events that might be present in the trace - */ - Set getContainedEventTypes(); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfContext.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfContext.java deleted file mode 100644 index 3b55ebe1ec..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfContext.java +++ /dev/null @@ -1,178 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Updated as per TMF Trace Model 1.0 - * Patrick Tasse - Updated for removal of context clone - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace; - -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - -/** - * A basic implementation of ITmfContext. - *

- * It ties a trace location to an event rank. The context should be enough to - * restore the trace state so the corresponding event can be read. - * - * @version 1.0 - * @author Francois Chouinard - * - * @see ITmfLocation - */ -public class TmfContext implements ITmfContext { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // The trace location - private ITmfLocation fLocation; - - // The event rank - private long fRank; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - public TmfContext() { - this(null, UNKNOWN_RANK); - } - - /** - * Simple constructor (unknown rank) - * - * @param location the event location - * @since 3.0 - */ - public TmfContext(final ITmfLocation location) { - this(location, UNKNOWN_RANK); - } - - /** - * Full constructor - * - * @param location the event location - * @param rank the event rank - * @since 3.0 - */ - public TmfContext(final ITmfLocation location, final long rank) { - fLocation = location; - fRank = rank; - } - - /** - * Copy constructor - * - * @param context the other context - */ - public TmfContext(final TmfContext context) { - if (context == null) { - throw new IllegalArgumentException(); - } - fLocation = context.fLocation; - fRank = context.fRank; - } - - // ------------------------------------------------------------------------ - // ITmfContext - // ------------------------------------------------------------------------ - - /** - * @since 3.0 - */ - @Override - public ITmfLocation getLocation() { - return fLocation; - } - - /** - * @since 3.0 - */ - @Override - public void setLocation(final ITmfLocation location) { - fLocation = location; - } - - @Override - public long getRank() { - return fRank; - } - - @Override - public void setRank(final long rank) { - fRank = rank; - } - - @Override - public void increaseRank() { - if (hasValidRank()) { - fRank++; - } - } - - @Override - public boolean hasValidRank() { - return fRank != UNKNOWN_RANK; - } - - @Override - public void dispose() { - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((fLocation == null) ? 0 : fLocation.hashCode()); - result = prime * result + (int) (fRank ^ (fRank >>> 32)); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final TmfContext other = (TmfContext) obj; - if (fLocation == null) { - if (other.fLocation != null) { - return false; - } - } else if (!fLocation.equals(other.fLocation)) { - return false; - } - if (fRank != other.fRank) { - return false; - } - return true; - } - - @Override - @SuppressWarnings("nls") - public String toString() { - return "TmfContext [fLocation=" + fLocation + ", fRank=" + fRank + "]"; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfEventTypeCollectionHelper.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfEventTypeCollectionHelper.java deleted file mode 100644 index 72bfe18574..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfEventTypeCollectionHelper.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace; - -import java.util.HashSet; -import java.util.Set; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; - -/** - * Set Helper for sets of ITmfTraceType - * - * TODO Remove once Java 8 is used (replace with Streams) - * - * @author Matthew Khouzam - * @since 3.0 - */ -public final class TmfEventTypeCollectionHelper { - - private TmfEventTypeCollectionHelper() { - } - - /** - * Gets the event names from a collection of event types - * - * @param eventTypes - * an iterable collection of ITmfEventTypes - * @return a set of the names of these events, if some names are clashing - * they will only appear once - */ - public static Set getEventNames(Iterable eventTypes) { - Set retSet = new HashSet<>(); - for (ITmfEventType eventType : eventTypes) { - retSet.add(eventType.getName()); - } - return retSet; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfExperiment.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfExperiment.java deleted file mode 100644 index 3eeee30c34..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfExperiment.java +++ /dev/null @@ -1,736 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Updated as per TMF Trace Model 1.0 - * Patrick Tasse - Updated for removal of context clone - * Patrick Tasse - Updated for ranks in experiment location - * Geneviève Bastien - Added support of experiment synchronization - * Added the initExperiment method and default constructor - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace; - -import java.io.File; -import java.nio.ByteBuffer; -import java.util.Arrays; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.internal.tmf.core.trace.TmfExperimentContext; -import org.eclipse.linuxtools.internal.tmf.core.trace.TmfExperimentLocation; -import org.eclipse.linuxtools.internal.tmf.core.trace.TmfLocationArray; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSynchronizedSignal; -import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithm; -import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationManager; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfPersistentlyIndexable; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.indexer.TmfBTreeTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - -/** - * TmfExperiment presents a time-ordered, unified view of a set of ITmfTrace:s - * that are part of a tracing experiment. - * - * @version 1.0 - * @author Francois Chouinard - */ -public class TmfExperiment extends TmfTrace implements ITmfEventParser, ITmfPersistentlyIndexable { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The file name of the Synchronization - * - * @since 3.0 - * @deprecated This file name shouldn't be used directly anymore. All - * synchronization files have been moved to a folder and you - * should use the {@link #getSynchronizationFolder(boolean)} - * method to return the path to this folder. - */ - @Deprecated - public static final String SYNCHRONIZATION_FILE_NAME = "synchronization.bin"; //$NON-NLS-1$ - - /** - * The name of the directory containing trace synchronization data. This - * directory typically will be preserved when traces are synchronized. - * Analysis involved in synchronization can put their supplementary files in - * there so they are not deleted when synchronized traces are copied. - */ - private static final String SYNCHRONIZATION_DIRECTORY = "sync_data"; //$NON-NLS-1$ - - /** - * The default index page size - */ - public static final int DEFAULT_INDEX_PAGE_SIZE = 5000; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The set of traces that constitute the experiment - */ - protected ITmfTrace[] fTraces; - - /** - * The set of traces that constitute the experiment - */ - private boolean fInitialized = false; - - // ------------------------------------------------------------------------ - // Construction - // ------------------------------------------------------------------------ - - /** - * Default constructor - * - * @since 3.0 - */ - public TmfExperiment() { - super(); - } - - /** - * Constructor with parameters - * - * @param type - * the event type - * @param id - * the experiment id - * @param traces - * the experiment set of traces - */ - public TmfExperiment(final Class type, final String id, final ITmfTrace[] traces) { - this(type, id, traces, DEFAULT_INDEX_PAGE_SIZE, null); - } - - /** - * Constructor of experiment taking type, path, traces and resource - * - * @param type - * the event type - * @param id - * the experiment id - * @param traces - * the experiment set of traces - * @param resource - * the resource associated to the experiment - */ - public TmfExperiment(final Class type, final String id, final ITmfTrace[] traces, IResource resource) { - this(type, id, traces, DEFAULT_INDEX_PAGE_SIZE, resource); - } - - /** - * @param type - * the event type - * @param path - * the experiment path - * @param traces - * the experiment set of traces - * @param indexPageSize - * the experiment index page size - */ - public TmfExperiment(final Class type, final String path, final ITmfTrace[] traces, final int indexPageSize) { - this(type, path, traces, indexPageSize, null); - } - - /** - * Full constructor of an experiment, taking the type, path, traces, - * indexPageSize and resource - * - * @param type - * the event type - * @param path - * the experiment path - * @param traces - * the experiment set of traces - * @param indexPageSize - * the experiment index page size - * @param resource - * the resource associated to the experiment - */ - public TmfExperiment(final Class type, final String path, final ITmfTrace[] traces, final int indexPageSize, IResource resource) { - initExperiment(type, path, traces, indexPageSize, resource); - } - - @Override - protected ITmfTraceIndexer createIndexer(int interval) { - if (getCheckpointSize() > 0) { - return new TmfBTreeTraceIndexer(this, interval); - } - return super.createIndexer(interval); - } - - /** - * Clears the experiment - */ - @Override - public synchronized void dispose() { - - // Clean up the index if applicable - if (getIndexer() != null) { - getIndexer().dispose(); - } - - if (fTraces != null) { - for (final ITmfTrace trace : fTraces) { - trace.dispose(); - } - fTraces = null; - } - super.dispose(); - } - - // ------------------------------------------------------------------------ - // ITmfTrace - Initializers - // ------------------------------------------------------------------------ - - @Override - public void initTrace(final IResource resource, final String path, final Class type) { - } - - /** - * Initialization of an experiment, taking the type, path, traces, - * indexPageSize and resource - * - * @param type - * the event type - * @param path - * the experiment path - * @param traces - * the experiment set of traces - * @param indexPageSize - * the experiment index page size - * @param resource - * the resource associated to the experiment - * @since 3.0 - */ - public void initExperiment(final Class type, final String path, final ITmfTrace[] traces, final int indexPageSize, IResource resource) { - setCacheSize(indexPageSize); - setStreamingInterval(0); - setParser(this); - // traces have to be set before super.initialize() - fTraces = traces; - try { - super.initialize(resource, path, type); - } catch (TmfTraceException e) { - Activator.logError("Error initializing experiment", e); //$NON-NLS-1$ - } - - if (resource != null) { - this.synchronizeTraces(); - } - } - - /** - * @since 2.0 - */ - @Override - public IStatus validate(final IProject project, final String path) { - return Status.OK_STATUS; - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Get the traces contained in this experiment. - * - * @return The array of contained traces - */ - public ITmfTrace[] getTraces() { - return fTraces; - } - - /** - * Returns the timestamp of the event at the requested index. If none, - * returns null. - * - * @param index - * the event index (rank) - * @return the corresponding event timestamp - * @since 2.0 - */ - public ITmfTimestamp getTimestamp(final int index) { - final ITmfContext context = seekEvent(index); - final ITmfEvent event = getNext(context); - context.dispose(); - return (event != null) ? event.getTimestamp() : null; - } - - // ------------------------------------------------------------------------ - // Request management - // ------------------------------------------------------------------------ - - /** - * @since 2.0 - */ - @Override - public synchronized ITmfContext armRequest(final ITmfEventRequest request) { - - // Make sure we have something to read from - if (fTraces == null) { - return null; - } - - if (!TmfTimestamp.BIG_BANG.equals(request.getRange().getStartTime()) - && request.getIndex() == 0) { - final ITmfContext context = seekEvent(request.getRange().getStartTime()); - request.setStartIndex((int) context.getRank()); - return context; - - } - - return seekEvent(request.getIndex()); - } - - // ------------------------------------------------------------------------ - // ITmfTrace trace positioning - // ------------------------------------------------------------------------ - - /** - * @since 3.0 - */ - @Override - public synchronized ITmfContext seekEvent(final ITmfLocation location) { - // Validate the location - if (location != null && !(location instanceof TmfExperimentLocation)) { - return null; // Throw an exception? - } - // Make sure we have something to read from - if (fTraces == null) { - return null; - } - - // Initialize the location array if necessary - TmfLocationArray locationArray = ((location == null) ? - new TmfLocationArray(fTraces.length) : - ((TmfExperimentLocation) location).getLocationInfo()); - - ITmfLocation[] locations = locationArray.getLocations(); - long[] ranks = locationArray.getRanks(); - - // Create and populate the context's traces contexts - final TmfExperimentContext context = new TmfExperimentContext(fTraces.length); - - // Position the traces - long rank = 0; - for (int i = 0; i < fTraces.length; i++) { - // Get the relevant trace attributes - final ITmfContext traceContext = fTraces[i].seekEvent(locations[i]); - context.setContext(i, traceContext); - traceContext.setRank(ranks[i]); - // update location after seek - locations[i] = traceContext.getLocation(); - context.setEvent(i, fTraces[i].getNext(traceContext)); - rank += ranks[i]; - } - - // Finalize context - context.setLocation(new TmfExperimentLocation(new TmfLocationArray(locations, ranks))); - context.setLastTrace(TmfExperimentContext.NO_TRACE); - context.setRank(rank); - - return context; - } - - // ------------------------------------------------------------------------ - // ITmfTrace - SeekEvent operations (returning a trace context) - // ------------------------------------------------------------------------ - - @Override - public ITmfContext seekEvent(final double ratio) { - final ITmfContext context = seekEvent(Math.round(ratio * getNbEvents())); - return context; - } - - /** - * @since 3.0 - */ - @Override - public double getLocationRatio(final ITmfLocation location) { - if (location instanceof TmfExperimentLocation) { - long rank = 0; - TmfLocationArray locationArray = ((TmfExperimentLocation) location).getLocationInfo(); - for (int i = 0; i < locationArray.size(); i++) { - rank += locationArray.getRank(i); - } - return (double) rank / getNbEvents(); - } - return 0.0; - } - - /** - * @since 3.0 - */ - @Override - public ITmfLocation getCurrentLocation() { - // never used - return null; - } - - // ------------------------------------------------------------------------ - // ITmfTrace trace positioning - // ------------------------------------------------------------------------ - - @Override - public synchronized ITmfEvent parseEvent(final ITmfContext context) { - final ITmfContext tmpContext = seekEvent(context.getLocation()); - final ITmfEvent event = getNext(tmpContext); - return event; - } - - @Override - public synchronized ITmfEvent getNext(ITmfContext context) { - - // Validate the context - if (!(context instanceof TmfExperimentContext)) { - return null; // Throw an exception? - } - - // Make sure that we have something to read from - if (fTraces == null) { - return null; - } - - TmfExperimentContext expContext = (TmfExperimentContext) context; - - // If an event was consumed previously, first get the next one from that - // trace - final int lastTrace = expContext.getLastTrace(); - if (lastTrace != TmfExperimentContext.NO_TRACE) { - final ITmfContext traceContext = expContext.getContext(lastTrace); - expContext.setEvent(lastTrace, fTraces[lastTrace].getNext(traceContext)); - expContext.setLastTrace(TmfExperimentContext.NO_TRACE); - } - - // Scan the candidate events and identify the "next" trace to read from - int trace = TmfExperimentContext.NO_TRACE; - ITmfTimestamp timestamp = TmfTimestamp.BIG_CRUNCH; - for (int i = 0; i < fTraces.length; i++) { - final ITmfEvent event = expContext.getEvent(i); - if (event != null && event.getTimestamp() != null) { - final ITmfTimestamp otherTS = event.getTimestamp(); - if (otherTS.compareTo(timestamp, true) < 0) { - trace = i; - timestamp = otherTS; - } - } - } - - ITmfEvent event = null; - if (trace != TmfExperimentContext.NO_TRACE) { - event = expContext.getEvent(trace); - if (event != null) { - updateAttributes(expContext, event.getTimestamp()); - expContext.increaseRank(); - expContext.setLastTrace(trace); - final ITmfContext traceContext = expContext.getContext(trace); - if (traceContext == null) { - throw new IllegalStateException(); - } - - // Update the experiment location - TmfLocationArray locationArray = new TmfLocationArray( - ((TmfExperimentLocation) expContext.getLocation()).getLocationInfo(), - trace, traceContext.getLocation(), traceContext.getRank()); - expContext.setLocation(new TmfExperimentLocation(locationArray)); - - processEvent(event); - } - } - - return event; - } - - /** - * @since 2.0 - */ - @Override - public ITmfTimestamp getInitialRangeOffset() { - if ((fTraces == null) || (fTraces.length == 0)) { - return super.getInitialRangeOffset(); - } - - ITmfTimestamp initTs = TmfTimestamp.BIG_CRUNCH; - for (int i = 0; i < fTraces.length; i++) { - ITmfTimestamp ts = fTraces[i].getInitialRangeOffset(); - if (ts.compareTo(initTs) < 0) { - initTs = ts; - } - } - return initTs; - } - - /** - * Get the path to the folder in the supplementary file where - * synchronization-related data can be kept so they are not deleted when the - * experiment is synchronized. Analysis involved in synchronization can put - * their supplementary files in there so they are preserved after - * synchronization. - * - * If the directory does not exist, it will be created. A return value of - * null means either the trace resource does not exist or - * supplementary resources cannot be kept. - * - * @param absolute - * If true, it returns the absolute path in the file - * system, including the supplementary file path. Otherwise, it - * returns only the directory name. - * @return The path to the folder where synchronization-related - * supplementary files can be kept or null if not - * available. - * @since 3.2 - */ - public String getSynchronizationFolder(boolean absolute) { - /* Set up the path to the synchronization file we'll use */ - IResource resource = this.getResource(); - String syncDirectory = null; - - try { - /* get the directory where the file will be stored. */ - if (resource != null) { - String fullDirectory = resource.getPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER); - /* Create the synchronization data directory if not present */ - if (fullDirectory != null) { - fullDirectory = fullDirectory + File.separator + SYNCHRONIZATION_DIRECTORY; - File syncDir = new File(fullDirectory); - syncDir.mkdirs(); - } - if (absolute) { - syncDirectory = fullDirectory; - } else { - syncDirectory = SYNCHRONIZATION_DIRECTORY; - } - } - } catch (CoreException e) { - return null; - } - - return syncDirectory; - } - - /** - * Synchronizes the traces of an experiment. By default it only tries to - * read a synchronization file if it exists - * - * @return The synchronization object - * @since 3.0 - */ - public synchronized SynchronizationAlgorithm synchronizeTraces() { - return synchronizeTraces(false); - } - - /** - * Synchronizes the traces of an experiment. - * - * @param doSync - * Whether to actually synchronize or just try opening a sync - * file - * @return The synchronization object - * @since 3.0 - */ - public synchronized SynchronizationAlgorithm synchronizeTraces(boolean doSync) { - - String syncDirectory = getSynchronizationFolder(true); - - final File syncFile = (syncDirectory != null) ? new File(syncDirectory + File.separator + SYNCHRONIZATION_FILE_NAME) : null; - - final SynchronizationAlgorithm syncAlgo = SynchronizationManager.synchronizeTraces(syncFile, Arrays.asList(fTraces), doSync); - - final TmfTraceSynchronizedSignal signal = new TmfTraceSynchronizedSignal(this, syncAlgo); - - /* Broadcast in separate thread to prevent deadlock */ - new Thread() { - @Override - public void run() { - broadcast(signal); - } - }.start(); - - return syncAlgo; - } - - @Override - @SuppressWarnings("nls") - public synchronized String toString() { - return "[TmfExperiment (" + getName() + ")]"; - } - - // ------------------------------------------------------------------------ - // Streaming support - // ------------------------------------------------------------------------ - - private synchronized void initializeStreamingMonitor() { - - if (fInitialized) { - return; - } - fInitialized = true; - - if (getStreamingInterval() == 0) { - final ITmfContext context = seekEvent(0); - final ITmfEvent event = getNext(context); - context.dispose(); - if (event == null) { - return; - } - final TmfTimeRange timeRange = new TmfTimeRange(event.getTimestamp(), TmfTimestamp.BIG_CRUNCH); - final TmfTraceRangeUpdatedSignal signal = new TmfTraceRangeUpdatedSignal(this, this, timeRange); - - // Broadcast in separate thread to prevent deadlock - new Thread() { - @Override - public void run() { - broadcast(signal); - } - }.start(); - return; - } - - final Thread thread = new Thread("Streaming Monitor for experiment " + getName()) { //$NON-NLS-1$ - private ITmfTimestamp safeTimestamp = null; - private ITmfTimestamp lastSafeTimestamp = null; - private TmfTimeRange timeRange = null; - - @Override - public void run() { - while (!executorIsShutdown()) { - if (!getIndexer().isIndexing()) { - ITmfTimestamp startTimestamp = TmfTimestamp.BIG_CRUNCH; - ITmfTimestamp endTimestamp = TmfTimestamp.BIG_BANG; - for (final ITmfTrace trace : fTraces) { - if (trace.getStartTime().compareTo(startTimestamp) < 0) { - startTimestamp = trace.getStartTime(); - } - if (trace.getStreamingInterval() != 0 && trace.getEndTime().compareTo(endTimestamp) > 0) { - endTimestamp = trace.getEndTime(); - } - } - if (safeTimestamp != null && (lastSafeTimestamp == null || safeTimestamp.compareTo(lastSafeTimestamp, false) > 0)) { - timeRange = new TmfTimeRange(startTimestamp, safeTimestamp); - lastSafeTimestamp = safeTimestamp; - } else { - timeRange = null; - } - safeTimestamp = endTimestamp; - if (timeRange != null) { - final TmfTraceRangeUpdatedSignal signal = - new TmfTraceRangeUpdatedSignal(TmfExperiment.this, TmfExperiment.this, timeRange); - broadcast(signal); - } - } - try { - Thread.sleep(getStreamingInterval()); - } catch (final InterruptedException e) { - e.printStackTrace(); - } - } - } - }; - thread.start(); - } - - @Override - public long getStreamingInterval() { - long interval = 0; - for (final ITmfTrace trace : fTraces) { - interval = Math.max(interval, trace.getStreamingInterval()); - } - return interval; - } - - // ------------------------------------------------------------------------ - // Signal handlers - // ------------------------------------------------------------------------ - - @Override - @TmfSignalHandler - public void traceOpened(TmfTraceOpenedSignal signal) { - if (signal.getTrace() == this) { - initializeStreamingMonitor(); - - /* Initialize the analysis */ - MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, null, null); - status.add(executeAnalysis()); - if (!status.isOK()) { - Activator.log(status); - } - TmfTraceManager.refreshSupplementaryFiles(this); - } - } - - /** - * @since 3.0 - */ - @Override - public synchronized int getCheckpointSize() { - int totalCheckpointSize = 0; - try { - if (fTraces != null) { - for (final ITmfTrace trace : fTraces) { - if (!(trace instanceof ITmfPersistentlyIndexable)) { - return 0; - } - - ITmfPersistentlyIndexable persistableIndexTrace = (ITmfPersistentlyIndexable) trace; - int currentTraceCheckpointSize = persistableIndexTrace.getCheckpointSize(); - if (currentTraceCheckpointSize <= 0) { - return 0; - } - totalCheckpointSize += currentTraceCheckpointSize; - // each entry in the TmfLocationArray has a rank in addition - // of the location - totalCheckpointSize += 8; - } - } - } catch (UnsupportedOperationException e) { - return 0; - } - - return totalCheckpointSize; - } - - /** - * @since 3.0 - */ - @Override - public ITmfLocation restoreLocation(ByteBuffer bufferIn) { - ITmfLocation[] locations = new ITmfLocation[fTraces.length]; - long[] ranks = new long[fTraces.length]; - for (int i = 0; i < fTraces.length; ++i) { - final ITmfTrace trace = fTraces[i]; - locations[i] = ((ITmfPersistentlyIndexable) trace).restoreLocation(bufferIn); - ranks[i] = bufferIn.getLong(); - } - TmfLocationArray arr = new TmfLocationArray(locations, ranks); - TmfExperimentLocation l = new TmfExperimentLocation(arr); - return l; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTrace.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTrace.java deleted file mode 100644 index 167800c755..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTrace.java +++ /dev/null @@ -1,826 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Updated as per TMF Trace Model 1.0 - * Patrick Tasse - Updated for removal of context clone - * Geneviève Bastien - Added timestamp transforms, its saving to file and - * timestamp creation functions - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace; - -import java.io.File; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager; -import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal; -import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform; -import org.eclipse.linuxtools.tmf.core.synchronization.TimestampTransformFactory; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - -/** - * Abstract implementation of ITmfTrace. - *

- * Since the concept of 'location' is trace specific, the concrete classes have - * to provide the related methods, namely: - *

    - *
  • public ITmfLocation getCurrentLocation() - *
  • public double getLocationRatio(ITmfLocation location) - *
  • public ITmfContext seekEvent(ITmfLocation location) - *
  • public ITmfContext seekEvent(double ratio) - *
  • public IStatus validate(IProject project, String path) - *
- * A concrete trace must provide its corresponding parser. A common way to - * accomplish this is by making the concrete class extend TmfTrace and - * implement ITmfEventParser. - *

- * When constructing an event, the concrete trace should use the trace's - * timestamp transform to create the timestamp, by either transforming the - * parsed time value directly or by using the method createTimestamp(). - *

- * The concrete class can either specify its own indexer or use the provided - * TmfCheckpointIndexer (default). In this case, the trace cache size will be - * used as checkpoint interval. - * - * @version 1.0 - * @author Francois Chouinard - * - * @see ITmfEvent - * @see ITmfTraceIndexer - * @see ITmfEventParser - */ -public abstract class TmfTrace extends TmfEventProvider implements ITmfTrace, ITmfTraceCompleteness { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // The resource used for persistent properties for this trace - private IResource fResource; - - // The trace path - private String fPath; - - // The trace cache page size - private int fCacheSize = ITmfTrace.DEFAULT_TRACE_CACHE_SIZE; - - // The number of events collected (so far) - private volatile long fNbEvents = 0; - - // The time span of the event stream - private ITmfTimestamp fStartTime = TmfTimestamp.BIG_BANG; - private ITmfTimestamp fEndTime = TmfTimestamp.BIG_BANG; - - // The trace streaming interval (0 = no streaming) - private long fStreamingInterval = 0; - - // The trace indexer - private ITmfTraceIndexer fIndexer; - - // The trace parser - private ITmfEventParser fParser; - - private ITmfTimestampTransform fTsTransform; - - private final Map fAnalysisModules = - Collections.synchronizedMap(new LinkedHashMap()); - - // ------------------------------------------------------------------------ - // Construction - // ------------------------------------------------------------------------ - - /** - * The default, parameterless, constructor - */ - public TmfTrace() { - super(); - fIndexer = createIndexer(DEFAULT_BLOCK_SIZE); - } - - /** - * Full constructor. - * - * @param resource - * The resource associated to the trace - * @param type - * The type of events that will be read from this trace - * @param path - * The path to the trace on the filesystem - * @param cacheSize - * The trace cache size. Pass '-1' to use the default specified - * in {@link ITmfTrace#DEFAULT_TRACE_CACHE_SIZE} - * @param interval - * The trace streaming interval. You can use '0' for post-mortem - * traces. - * @param parser - * The trace event parser. Use 'null' if (and only if) the trace - * object itself is also the ITmfEventParser to be used. - * @throws TmfTraceException - * If something failed during the opening - */ - protected TmfTrace(final IResource resource, - final Class type, - final String path, - final int cacheSize, - final long interval, - final ITmfEventParser parser) - throws TmfTraceException { - super(); - fCacheSize = (cacheSize > 0) ? cacheSize : ITmfTrace.DEFAULT_TRACE_CACHE_SIZE; - fStreamingInterval = interval; - fParser = parser; - initialize(resource, path, type); - } - - /** - * Copy constructor - * - * @param trace the original trace - * @throws TmfTraceException Should not happen usually - */ - public TmfTrace(final TmfTrace trace) throws TmfTraceException { - super(); - if (trace == null) { - throw new IllegalArgumentException(); - } - fCacheSize = trace.getCacheSize(); - fStreamingInterval = trace.getStreamingInterval(); - fParser = trace.fParser; - initialize(trace.getResource(), trace.getPath(), trace.getEventType()); - } - - /** - * Creates the indexer instance. Classes extending this class can override - * this to provide a different indexer implementation. - * - * @param interval the checkpoints interval - * - * @return the indexer - * @since 3.0 - */ - protected ITmfTraceIndexer createIndexer(int interval) { - return new TmfCheckpointIndexer(this, interval); - } - - // ------------------------------------------------------------------------ - // ITmfTrace - Initializers - // ------------------------------------------------------------------------ - - @Override - public void initTrace(final IResource resource, final String path, final Class type, String name) throws TmfTraceException { - setName(name); - initTrace(resource, path, type); - } - - @Override - public void initTrace(final IResource resource, final String path, final Class type) throws TmfTraceException { - initialize(resource, path, type); - } - - /** - * Initialize the trace common attributes and the base component. - * - * @param resource the Eclipse resource (trace) - * @param path the trace path - * @param type the trace event type - * - * @throws TmfTraceException If something failed during the initialization - */ - protected void initialize(final IResource resource, - final String path, - final Class type) - throws TmfTraceException { - if (path == null) { - throw new TmfTraceException("Invalid trace path"); //$NON-NLS-1$ - } - fPath = path; - fResource = resource; - String traceName = getName(); - if (traceName == null || traceName.isEmpty()) { - traceName = (resource != null) ? resource.getName() : new Path(path).lastSegment(); - } - if (fParser == null) { - if (this instanceof ITmfEventParser) { - fParser = (ITmfEventParser) this; - } else { - throw new TmfTraceException("Invalid trace parser"); //$NON-NLS-1$ - } - } - super.init(traceName, type); - // register as VIP after super.init() because TmfComponent registers to signal manager there - TmfSignalManager.registerVIP(this); - if (fIndexer != null) { - fIndexer.dispose(); - } - fIndexer = createIndexer(fCacheSize); - } - - /** - * Indicates if the path points to an existing file/directory - * - * @param path the path to test - * @return true if the file/directory exists - */ - protected boolean fileExists(final String path) { - final File file = new File(path); - return file.exists(); - } - - /** - * @since 2.0 - */ - @Override - public void indexTrace(boolean waitForCompletion) { - getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, waitForCompletion); - } - - /** - * Instantiate the applicable analysis modules and executes the analysis - * modules that are meant to be automatically executed - * - * @return An IStatus indicating whether the analysis could be run - * successfully or not - * @since 3.0 - */ - protected IStatus executeAnalysis() { - MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, null, null); - Map modules = TmfAnalysisManager.getAnalysisModules(this.getClass()); - for (IAnalysisModuleHelper helper : modules.values()) { - try { - IAnalysisModule module = helper.newModule(this); - fAnalysisModules.put(module.getId(), module); - if (module.isAutomatic()) { - status.add(module.schedule()); - } - } catch (TmfAnalysisException e) { - status.add(new Status(IStatus.WARNING, Activator.PLUGIN_ID, e.getMessage())); - } - } - return status; - } - - /** - * @since 3.0 - */ - @Override - public IAnalysisModule getAnalysisModule(String analysisId) { - return fAnalysisModules.get(analysisId); - } - - - /** - * @since 3.0 - */ - @Override - public Iterable getAnalysisModules() { - synchronized (fAnalysisModules) { - Set modules = new HashSet<>(fAnalysisModules.values()); - return modules; - } - } - - /** - * @since 3.0 - */ - @Override - public T getAnalysisModuleOfClass(Class moduleClass, String id) { - Iterable modules = getAnalysisModulesOfClass(moduleClass); - for (T module : modules) { - if (id.equals(module.getId())) { - return module; - } - } - return null; - } - - /** - * @since 3.0 - */ - @Override - public Iterable getAnalysisModulesOfClass(Class moduleClass) { - Set modules = new HashSet<>(); - synchronized (fAnalysisModules) { - for (Entry entry : fAnalysisModules.entrySet()) { - if (moduleClass.isAssignableFrom(entry.getValue().getClass())) { - modules.add(moduleClass.cast(entry.getValue())); - } - } - } - return modules; - } - - /** - * Clears the trace - */ - @Override - public synchronized void dispose() { - /* Clean up the index if applicable */ - if (getIndexer() != null) { - getIndexer().dispose(); - } - - /* Clean up the analysis modules */ - synchronized (fAnalysisModules) { - for (IAnalysisModule module : fAnalysisModules.values()) { - module.dispose(); - } - fAnalysisModules.clear(); - } - - super.dispose(); - } - - // ------------------------------------------------------------------------ - // ITmfTrace - Basic getters - // ------------------------------------------------------------------------ - - @Override - public Class getEventType() { - return super.getType(); - } - - @Override - public IResource getResource() { - return fResource; - } - - @Override - public String getPath() { - return fPath; - } - - @Override - public int getCacheSize() { - return fCacheSize; - } - - @Override - public long getStreamingInterval() { - return fStreamingInterval; - } - - /** - * @return the trace indexer - * @since 3.0 - */ - protected ITmfTraceIndexer getIndexer() { - return fIndexer; - } - - /** - * @return the trace parser - */ - protected ITmfEventParser getParser() { - return fParser; - } - - // ------------------------------------------------------------------------ - // ITmfTrace - Trace characteristics getters - // ------------------------------------------------------------------------ - - @Override - public long getNbEvents() { - return fNbEvents; - } - - /** - * @since 2.0 - */ - @Override - public TmfTimeRange getTimeRange() { - return new TmfTimeRange(fStartTime, fEndTime); - } - - /** - * @since 2.0 - */ - @Override - public ITmfTimestamp getStartTime() { - return fStartTime; - } - - /** - * @since 2.0 - */ - @Override - public ITmfTimestamp getEndTime() { - return fEndTime; - } - - /** - * @since 2.0 - */ - @Override - public ITmfTimestamp getInitialRangeOffset() { - final long DEFAULT_INITIAL_OFFSET_VALUE = (1L * 100 * 1000 * 1000); // .1sec - return new TmfTimestamp(DEFAULT_INITIAL_OFFSET_VALUE, ITmfTimestamp.NANOSECOND_SCALE); - } - - /** - * @since 3.0 - */ - @Override - public String getHostId() { - return this.getName(); - } - - // ------------------------------------------------------------------------ - // Convenience setters - // ------------------------------------------------------------------------ - - /** - * Set the trace cache size. Must be done at initialization time. - * - * @param cacheSize The trace cache size - */ - protected void setCacheSize(final int cacheSize) { - fCacheSize = cacheSize; - } - - /** - * Set the trace known number of events. This can be quite dynamic - * during indexing or for live traces. - * - * @param nbEvents The number of events - */ - protected synchronized void setNbEvents(final long nbEvents) { - fNbEvents = (nbEvents > 0) ? nbEvents : 0; - } - - /** - * Update the trace events time range - * - * @param range the new time range - * @since 2.0 - */ - protected void setTimeRange(final TmfTimeRange range) { - fStartTime = range.getStartTime(); - fEndTime = range.getEndTime(); - } - - /** - * Update the trace chronologically first event timestamp - * - * @param startTime the new first event timestamp - * @since 2.0 - */ - protected void setStartTime(final ITmfTimestamp startTime) { - fStartTime = startTime; - } - - /** - * Update the trace chronologically last event timestamp - * - * @param endTime the new last event timestamp - * @since 2.0 - */ - protected void setEndTime(final ITmfTimestamp endTime) { - fEndTime = endTime; - } - - /** - * Set the polling interval for live traces (default = 0 = no streaming). - * - * @param interval the new trace streaming interval - */ - protected void setStreamingInterval(final long interval) { - fStreamingInterval = (interval > 0) ? interval : 0; - } - - /** - * Set the trace parser. Must be done at initialization time. - * - * @param parser the new trace parser - */ - protected void setParser(final ITmfEventParser parser) { - fParser = parser; - } - - // ------------------------------------------------------------------------ - // ITmfTrace - SeekEvent operations (returning a trace context) - // ------------------------------------------------------------------------ - - @Override - public synchronized ITmfContext seekEvent(final long rank) { - - // A rank <= 0 indicates to seek the first event - if (rank <= 0) { - ITmfContext context = seekEvent((ITmfLocation) null); - context.setRank(0); - return context; - } - - // Position the trace at the checkpoint - final ITmfContext context = fIndexer.seekIndex(rank); - - // And locate the requested event context - long pos = context.getRank(); - if (pos < rank) { - ITmfEvent event = getNext(context); - while ((event != null) && (++pos < rank)) { - event = getNext(context); - } - } - return context; - } - - /** - * @since 2.0 - */ - @Override - public synchronized ITmfContext seekEvent(final ITmfTimestamp timestamp) { - - // A null timestamp indicates to seek the first event - if (timestamp == null) { - ITmfContext context = seekEvent((ITmfLocation) null); - context.setRank(0); - return context; - } - - // Position the trace at the checkpoint - ITmfContext context = fIndexer.seekIndex(timestamp); - - // And locate the requested event context - ITmfLocation previousLocation = context.getLocation(); - long previousRank = context.getRank(); - ITmfEvent event = getNext(context); - while (event != null && event.getTimestamp().compareTo(timestamp, false) < 0) { - previousLocation = context.getLocation(); - previousRank = context.getRank(); - event = getNext(context); - } - if (event == null) { - context.setLocation(null); - context.setRank(ITmfContext.UNKNOWN_RANK); - } else { - context.dispose(); - context = seekEvent(previousLocation); - context.setRank(previousRank); - } - return context; - } - - // ------------------------------------------------------------------------ - // ITmfTrace - Read operations (returning an actual event) - // ------------------------------------------------------------------------ - - @Override - public synchronized ITmfEvent getNext(final ITmfContext context) { - // parseEvent() does not update the context - final ITmfEvent event = fParser.parseEvent(context); - if (event != null) { - updateAttributes(context, event.getTimestamp()); - context.setLocation(getCurrentLocation()); - context.increaseRank(); - processEvent(event); - } - return event; - } - - /** - * Hook for special event processing by the concrete class - * (called by TmfTrace.getEvent()) - * - * @param event the event - */ - protected void processEvent(final ITmfEvent event) { - // Do nothing - } - - /** - * Update the trace attributes - * - * @param context the current trace context - * @param timestamp the corresponding timestamp - * @since 2.0 - */ - protected synchronized void updateAttributes(final ITmfContext context, final ITmfTimestamp timestamp) { - if (fStartTime.equals(TmfTimestamp.BIG_BANG) || (fStartTime.compareTo(timestamp, false) > 0)) { - fStartTime = timestamp; - } - if (fEndTime.equals(TmfTimestamp.BIG_CRUNCH) || (fEndTime.compareTo(timestamp, false) < 0)) { - fEndTime = timestamp; - } - if (context.hasValidRank()) { - long rank = context.getRank(); - if (fNbEvents <= rank) { - fNbEvents = rank + 1; - } - if (fIndexer != null) { - fIndexer.updateIndex(context, timestamp); - } - } - } - - // ------------------------------------------------------------------------ - // TmfDataProvider - // ------------------------------------------------------------------------ - - /** - * @since 2.0 - */ - @Override - public synchronized ITmfContext armRequest(final ITmfEventRequest request) { - if (executorIsShutdown()) { - return null; - } - if (!TmfTimestamp.BIG_BANG.equals(request.getRange().getStartTime()) - && (request.getIndex() == 0)) { - final ITmfContext context = seekEvent(request.getRange().getStartTime()); - request.setStartIndex((int) context.getRank()); - return context; - - } - return seekEvent(request.getIndex()); - } - - // ------------------------------------------------------------------------ - // Signal handlers - // ------------------------------------------------------------------------ - - /** - * Handler for the Trace Opened signal - * - * @param signal - * The incoming signal - * @since 2.0 - */ - @TmfSignalHandler - public void traceOpened(TmfTraceOpenedSignal signal) { - boolean signalIsForUs = false; - for (ITmfTrace trace : TmfTraceManager.getTraceSet(signal.getTrace())) { - if (trace == this) { - signalIsForUs = true; - break; - } - } - - if (!signalIsForUs) { - return; - } - - /* - * The signal is either for this trace, or for an experiment containing - * this trace. - */ - IStatus status = executeAnalysis(); - if (!status.isOK()) { - Activator.log(status); - } - - TmfTraceManager.refreshSupplementaryFiles(this); - - if (signal.getTrace() == this) { - /* Additionally, the signal is directly for this trace. */ - if (getNbEvents() == 0) { - return; - } - - /* For a streaming trace, the range updated signal should be sent - * by the subclass when a new safe time is determined. - */ - if (getStreamingInterval() > 0) { - return; - } - - if (isComplete()) { - final TmfTimeRange timeRange = new TmfTimeRange(getStartTime(), TmfTimestamp.BIG_CRUNCH); - final TmfTraceRangeUpdatedSignal rangeUpdatedsignal = new TmfTraceRangeUpdatedSignal(this, this, timeRange); - - // Broadcast in separate thread to prevent deadlock - broadcastAsync(rangeUpdatedsignal); - } - return; - } - } - - /** - * Signal handler for the TmfTraceRangeUpdatedSignal signal - * - * @param signal The incoming signal - * @since 2.0 - */ - @TmfSignalHandler - public void traceRangeUpdated(final TmfTraceRangeUpdatedSignal signal) { - if (signal.getTrace() == this) { - getIndexer().buildIndex(getNbEvents(), signal.getRange(), false); - } - } - - /** - * Signal handler for the TmfTraceUpdatedSignal signal - * - * @param signal The incoming signal - * @since 3.0 - */ - @TmfSignalHandler - public void traceUpdated(final TmfTraceUpdatedSignal signal) { - if (signal.getSource() == getIndexer()) { - fNbEvents = signal.getNbEvents(); - fStartTime = signal.getRange().getStartTime(); - fEndTime = signal.getRange().getEndTime(); - } - } - - // ------------------------------------------------------------------------ - // Timestamp transformation functions - // ------------------------------------------------------------------------ - - /** - * @since 3.0 - */ - @Override - public ITmfTimestampTransform getTimestampTransform() { - if (fTsTransform == null) { - fTsTransform = TimestampTransformFactory.getTimestampTransform(getResource()); - } - return fTsTransform; - } - - /** - * @since 3.0 - */ - @Override - public void setTimestampTransform(final ITmfTimestampTransform tt) { - fTsTransform = tt; - TimestampTransformFactory.setTimestampTransform(getResource(), tt); - } - - /** - * @since 3.0 - */ - @Override - public ITmfTimestamp createTimestamp(long ts) { - return new TmfNanoTimestamp(getTimestampTransform().transform(ts)); - } - - // ------------------------------------------------------------------------ - // toString - // ------------------------------------------------------------------------ - - @Override - @SuppressWarnings("nls") - public synchronized String toString() { - return "TmfTrace [fPath=" + fPath + ", fCacheSize=" + fCacheSize - + ", fNbEvents=" + fNbEvents + ", fStartTime=" + fStartTime - + ", fEndTime=" + fEndTime + ", fStreamingInterval=" + fStreamingInterval + "]"; - } - - /** - * @since 3.1 - */ - @Override - public boolean isComplete() { - /* - * Be default, all traces are "complete" which means no more data will - * be added later - */ - return true; - } - - /** - * @since 3.1 - */ - @Override - public void setComplete(boolean isComplete) { - /* - * This should be overridden by trace classes that can support live - * reading (traces in an incomplete state) - */ - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTraceContext.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTraceContext.java deleted file mode 100644 index b2a3e689f2..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTraceContext.java +++ /dev/null @@ -1,115 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - * Patrick Tasse - Support selection range - * Xavier Raynaud - Support filters tracking - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace; - -import org.eclipse.core.resources.IFile; -import org.eclipse.linuxtools.tmf.core.filter.ITmfFilter; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; - -/** - * Context of a trace, which is the representation of the "view" the user - * currently has on this trace (window time range, selected time or time range). - * - * TODO could be extended to support the notion of current location too. - * - * @author Alexandre Montplaisir - * @since 2.0 - */ -final class TmfTraceContext { - - static final TmfTraceContext NULL_CONTEXT = - new TmfTraceContext(TmfTimestamp.BIG_CRUNCH, TmfTimestamp.BIG_CRUNCH, TmfTimeRange.NULL_RANGE, null); - - private final TmfTimeRange fSelection; - private final TmfTimeRange fWindowRange; - private final IFile fEditorFile; - private final ITmfFilter fFilter; - - public TmfTraceContext(ITmfTimestamp beginTs, ITmfTimestamp endTs, TmfTimeRange tr, IFile editorFile) { - fSelection = new TmfTimeRange(beginTs, endTs); - fWindowRange = tr; - fEditorFile = editorFile; - fFilter = null; - } - - public TmfTraceContext(TmfTraceContext prevCtx, ITmfTimestamp beginTs, ITmfTimestamp endTs) { - fSelection = new TmfTimeRange(beginTs, endTs); - fWindowRange = prevCtx.fWindowRange; - fEditorFile = prevCtx.fEditorFile; - fFilter = prevCtx.fFilter; - } - - public TmfTraceContext(TmfTraceContext prevCtx, TmfTimeRange tr) { - fSelection = prevCtx.fSelection; - fWindowRange = tr; - fEditorFile = prevCtx.fEditorFile; - fFilter = prevCtx.fFilter; - } - - /** - * @param prevCtx - * The previous context - * @param filter - * The applied filter - * @since 2.2 - */ - public TmfTraceContext(TmfTraceContext prevCtx, ITmfFilter filter) { - fSelection = prevCtx.fSelection; - fWindowRange = prevCtx.fWindowRange; - fEditorFile = prevCtx.fEditorFile; - fFilter = filter; - } - - public ITmfTimestamp getSelectionBegin() { - return fSelection.getStartTime(); - } - - public ITmfTimestamp getSelectionEnd() { - return fSelection.getEndTime(); - } - - public TmfTimeRange getWindowRange() { - return fWindowRange; - } - - public IFile getEditorFile() { - return fEditorFile; - } - - /** - * @return the current filter applied to the trace - * @since 2.2 - */ - public ITmfFilter getFilter() { - return fFilter; - } - - public boolean isValid() { - if (fSelection.getStartTime().compareTo(TmfTimestamp.ZERO) <= 0 || - fSelection.getEndTime().compareTo(TmfTimestamp.ZERO) <= 0 || - fWindowRange.getEndTime().compareTo(fWindowRange.getStartTime()) <= 0) { - return false; - } - return true; - } - - @Override - public String toString() { - return getClass().getSimpleName() + "[fSelection=" + fSelection + //$NON-NLS-1$ - ", fWindowRange=" + fWindowRange + ']'; //$NON-NLS-1$ - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTraceManager.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTraceManager.java deleted file mode 100644 index e0ab3e8a23..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTraceManager.java +++ /dev/null @@ -1,524 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - * Patrick Tasse - Support selection range - * Xavier Raynaud - Support filters tracking - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace; - -import java.io.File; -import java.net.URISyntaxException; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.URIUtil; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.filter.ITmfFilter; -import org.eclipse.linuxtools.tmf.core.signal.TmfEventFilterAppliedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; - -/** - * Central trace manager for TMF. It tracks the currently opened traces and - * experiment, as well as the currently-selected time or time range and the - * current window time range for each one of those. It also tracks filters - * applied for each trace. - * - * It's a singleton class, so only one instance should exist (available via - * {@link #getInstance()}). - * - * @author Alexandre Montplaisir - * @since 2.0 - */ -public final class TmfTraceManager { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final Map fTraces; - - /** The currently-selected trace. Should always be part of the trace map */ - private ITmfTrace fCurrentTrace = null; - - private static final String TEMP_DIR_NAME = ".temp"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - private TmfTraceManager() { - fTraces = new LinkedHashMap<>(); - TmfSignalManager.registerVIP(this); - } - - /** Singleton instance */ - private static TmfTraceManager tm = null; - - /** - * Get an instance of the trace manager. - * - * @return The trace manager - */ - public static synchronized TmfTraceManager getInstance() { - if (tm == null) { - tm = new TmfTraceManager(); - } - return tm; - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * @return The begin timestamp of selection - * @since 2.1 - */ - public ITmfTimestamp getSelectionBeginTime() { - return getCurrentTraceContext().getSelectionBegin(); - } - - /** - * @return The end timestamp of selection - * @since 2.1 - */ - public ITmfTimestamp getSelectionEndTime() { - return getCurrentTraceContext().getSelectionEnd(); - } - - /** - * Return the current window time range. - * - * @return the current window time range - */ - public synchronized TmfTimeRange getCurrentRange() { - return getCurrentTraceContext().getWindowRange(); - } - - /** - * Gets the filter applied to the current trace - * - * @return - * a filter, or null - * @since 2.2 - */ - public synchronized ITmfFilter getCurrentFilter() { - return getCurrentTraceContext().getFilter(); - } - - /** - * Get the currently selected trace (normally, the focused editor). - * - * @return The active trace - */ - public synchronized ITmfTrace getActiveTrace() { - return fCurrentTrace; - } - - /** - * Get the trace set of the currently active trace. - * - * @return The active trace set - * @see #getTraceSet(ITmfTrace) - */ - public synchronized ITmfTrace[] getActiveTraceSet() { - final ITmfTrace trace = fCurrentTrace; - return getTraceSet(trace); - } - - /** - * Get the currently-opened traces, as an unmodifiable set. - * - * @return A set containing the opened traces - */ - public synchronized Set getOpenedTraces() { - return Collections.unmodifiableSet(fTraces.keySet()); - } - - /** - * Get the editor file for an opened trace. - * - * @param trace - * the trace - * @return the editor file or null if the trace is not opened - * @since 3.0 - */ - public synchronized IFile getTraceEditorFile(ITmfTrace trace) { - TmfTraceContext ctx = fTraces.get(trace); - if (ctx != null) { - return ctx.getEditorFile(); - } - return null; - } - - private TmfTraceContext getCurrentTraceContext() { - TmfTraceContext curCtx = fTraces.get(fCurrentTrace); - if (curCtx == null) { - /* There are no traces opened at the moment. */ - return TmfTraceContext.NULL_CONTEXT; - } - return curCtx; - } - - // ------------------------------------------------------------------------ - // Public utility methods - // ------------------------------------------------------------------------ - - /** - * Get the trace set of a given trace. For a standard trace, this is simply - * an array with only that trace in it. For experiments, this is an array of - * all the traces contained in this experiment. - * - * @param trace - * The trace or experiment - * @return The corresponding trace set - */ - public static ITmfTrace[] getTraceSet(ITmfTrace trace) { - if (trace == null) { - return null; - } - if (trace instanceof TmfExperiment) { - TmfExperiment exp = (TmfExperiment) trace; - return exp.getTraces(); - } - return new ITmfTrace[] { trace }; - } - - /** - * Get the trace set of a given trace or experiment, including the - * experiment. For a standard trace, this is simply a set containing only - * that trace. For experiments, it is the set of all the traces contained in - * this experiment, along with the experiment. - * - * @param trace - * The trace or experiment - * @return The corresponding trace set, including the experiment - * @since 3.1 - */ - public static @NonNull Set getTraceSetWithExperiment(ITmfTrace trace) { - if (trace == null) { - @SuppressWarnings("null") - @NonNull Set emptySet = Collections.EMPTY_SET; - return emptySet; - } - if (trace instanceof TmfExperiment) { - TmfExperiment exp = (TmfExperiment) trace; - ITmfTrace[] traces = exp.getTraces(); - Set alltraces = new LinkedHashSet<>(Arrays.asList(traces)); - alltraces.add(exp); - return alltraces; - } - @SuppressWarnings("null") - @NonNull Set singleton = Collections.singleton(trace); - return singleton; - } - - /** - * Return the path (as a string) to the directory for supplementary files to - * use with a given trace. If no supplementary file directory has been - * configured, a temporary directory based on the trace's name will be - * provided. - * - * @param trace - * The trace - * @return The path to the supplementary file directory (trailing slash is - * INCLUDED!) - */ - public static String getSupplementaryFileDir(ITmfTrace trace) { - IResource resource = trace.getResource(); - if (resource == null) { - return getTemporaryDir(trace); - } - - String supplDir = null; - try { - supplDir = resource.getPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER); - } catch (CoreException e) { - return getTemporaryDir(trace); - } - return supplDir + File.separator; - } - - /** - * Refresh the supplementary files resources for a trace, so it can pick up - * new files that got created. - * - * @param trace - * The trace for which to refresh the supplementary files - * @since 3.0 - */ - public static void refreshSupplementaryFiles(ITmfTrace trace) { - IResource resource = trace.getResource(); - if (resource != null && resource.exists()) { - String supplFolderPath = getSupplementaryFileDir(trace); - IProject project = resource.getProject(); - /* Remove the project's path from the supplementary path dir */ - if (!supplFolderPath.startsWith(project.getLocationURI().getPath())) { - Activator.logWarning(String.format("Supplementary files folder for trace %s is not within the project.", trace.getName())); //$NON-NLS-1$ - return; - } - IFolder supplFolder = project.getFolder(supplFolderPath.substring(project.getLocationURI().getPath().length())); - if (supplFolder.exists()) { - try { - supplFolder.refreshLocal(IResource.DEPTH_INFINITE, null); - } catch (CoreException e) { - Activator.logError("Error refreshing resources", e); //$NON-NLS-1$ - } - } - } - } - - // ------------------------------------------------------------------------ - // Signal handlers - // ------------------------------------------------------------------------ - - /** - * Signal handler for the traceOpened signal. - * - * @param signal - * The incoming signal - */ - @TmfSignalHandler - public synchronized void traceOpened(final TmfTraceOpenedSignal signal) { - final ITmfTrace trace = signal.getTrace(); - final IFile editorFile = signal.getEditorFile(); - final ITmfTimestamp startTs = trace.getStartTime(); - - /* Calculate the initial time range */ - final int SCALE = ITmfTimestamp.NANOSECOND_SCALE; - long offset = trace.getInitialRangeOffset().normalize(0, SCALE).getValue(); - long endTime = startTs.normalize(0, SCALE).getValue() + offset; - final TmfTimeRange startTr = new TmfTimeRange(startTs, new TmfTimestamp(endTime, SCALE)); - - final TmfTraceContext startCtx = new TmfTraceContext(startTs, startTs, startTr, editorFile); - - fTraces.put(trace, startCtx); - - /* We also want to set the newly-opened trace as the active trace */ - fCurrentTrace = trace; - } - - - /** - * Handler for the TmfTraceSelectedSignal. - * - * @param signal - * The incoming signal - */ - @TmfSignalHandler - public synchronized void traceSelected(final TmfTraceSelectedSignal signal) { - final ITmfTrace newTrace = signal.getTrace(); - if (!fTraces.containsKey(newTrace)) { - throw new RuntimeException(); - } - fCurrentTrace = newTrace; - } - - /** - * Signal handler for the filterApplied signal. - * - * @param signal - * The incoming signal - * @since 2.2 - */ - @TmfSignalHandler - public synchronized void filterApplied(TmfEventFilterAppliedSignal signal) { - final ITmfTrace newTrace = signal.getTrace(); - TmfTraceContext context = fTraces.get(newTrace); - if (context == null) { - throw new RuntimeException(); - } - fTraces.put(newTrace, new TmfTraceContext(context, signal.getEventFilter())); - } - - /** - * Signal handler for the traceClosed signal. - * - * @param signal - * The incoming signal - */ - @TmfSignalHandler - public synchronized void traceClosed(final TmfTraceClosedSignal signal) { - fTraces.remove(signal.getTrace()); - if (fTraces.size() == 0) { - fCurrentTrace = null; - /* - * In other cases, we should receive a traceSelected signal that - * will indicate which trace is the new one. - */ - } - } - - /** - * Signal handler for the TmfTimeSynchSignal signal. - * - * The current time of *all* traces whose range contains the requested new - * selection time range will be updated. - * - * @param signal - * The incoming signal - */ - @TmfSignalHandler - public synchronized void timeUpdated(final TmfTimeSynchSignal signal) { - final ITmfTimestamp beginTs = signal.getBeginTime(); - final ITmfTimestamp endTs = signal.getEndTime(); - - for (Map.Entry entry : fTraces.entrySet()) { - final ITmfTrace trace = entry.getKey(); - if (beginTs.intersects(getValidTimeRange(trace)) || endTs.intersects(getValidTimeRange(trace))) { - TmfTraceContext prevCtx = entry.getValue(); - TmfTraceContext newCtx = new TmfTraceContext(prevCtx, beginTs, endTs); - entry.setValue(newCtx); - } - } - } - - /** - * Signal handler for the TmfRangeSynchSignal signal. - * - * The current window time range of *all* valid traces will be updated - * to the new requested times. - * - * @param signal - * The incoming signal - */ - @TmfSignalHandler - public synchronized void timeRangeUpdated(final TmfRangeSynchSignal signal) { - for (Map.Entry entry : fTraces.entrySet()) { - final ITmfTrace trace = entry.getKey(); - final TmfTraceContext curCtx = entry.getValue(); - - final TmfTimeRange validTr = getValidTimeRange(trace); - - /* Determine the new time range */ - TmfTimeRange targetTr = signal.getCurrentRange().getIntersection(validTr); - TmfTimeRange newTr = (targetTr == null ? curCtx.getWindowRange() : targetTr); - - /* Update the values */ - TmfTraceContext newCtx = new TmfTraceContext(curCtx, newTr); - entry.setValue(newCtx); - } - } - - // ------------------------------------------------------------------------ - // Private utility methods - // ------------------------------------------------------------------------ - - /** - * Return the valid time range of a trace (not the current window time - * range, but the range of all possible valid timestamps). - * - * For a real trace this is the whole range of the trace. For an experiment, - * it goes from the start time of the earliest trace to the end time of the - * latest one. - * - * @param trace - * The trace to check for - * @return The valid time span, or 'null' if the trace is not valid - */ - private TmfTimeRange getValidTimeRange(ITmfTrace trace) { - if (!fTraces.containsKey(trace)) { - /* Trace is not part of the currently opened traces */ - return null; - } - if (!(trace instanceof TmfExperiment)) { - /* "trace" is a single trace, return its time range directly */ - return trace.getTimeRange(); - } - final ITmfTrace[] traces = ((TmfExperiment) trace).getTraces(); - if (traces.length == 0) { - /* We are being trolled */ - return null; - } - if (traces.length == 1) { - /* Trace is an experiment with only 1 trace */ - return traces[0].getTimeRange(); - } - /* - * Trace is an experiment with 2+ traces, so get the earliest start and - * the latest end. - */ - ITmfTimestamp start = traces[0].getStartTime(); - ITmfTimestamp end = traces[0].getEndTime(); - for (int i = 1; i < traces.length; i++) { - ITmfTrace curTrace = traces[i]; - if (curTrace.getStartTime().compareTo(start) < 0) { - start = curTrace.getStartTime(); - } - if (curTrace.getEndTime().compareTo(end) > 0) { - end = curTrace.getEndTime(); - } - } - return new TmfTimeRange(start, end); - } - - /** - * Get the temporary directory path. If there is an instance of Eclipse - * running, the temporary directory will reside under the workspace. - * - * @return the temporary directory path suitable to be passed to the - * java.io.File constructor without a trailing separator - * @since 3.2 - */ - public static String getTemporaryDirPath() { - // Get the workspace path from the properties - String property = System.getProperty("osgi.instance.area"); //$NON-NLS-1$ - if (property != null) { - try { - File dir = URIUtil.toFile(URIUtil.fromString(property)); - dir = new File(dir.getAbsolutePath() + File.separator + TEMP_DIR_NAME); - if (!dir.exists()) { - dir.mkdirs(); - } - return dir.getAbsolutePath(); - } catch (URISyntaxException e) { - Activator.logError(e.getLocalizedMessage(), e); - } - } - return System.getProperty("java.io.tmpdir"); //$NON-NLS-1$ - } - - /** - * Get a temporary directory based on a trace's name. We will create the - * directory if it doesn't exist, so that it's ready to be used. - */ - private static String getTemporaryDir(ITmfTrace trace) { - String pathName = getTemporaryDirPath() + - File.separator + - trace.getName() + - File.separator; - File dir = new File(pathName); - if (!dir.exists()) { - dir.mkdirs(); - } - return pathName; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TraceValidationStatus.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TraceValidationStatus.java deleted file mode 100644 index 70ee92a7ed..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TraceValidationStatus.java +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace; - -import org.eclipse.core.runtime.Status; - -/** - * A class representing the validation status of a trace against a particular - * trace type. - * - * @since 3.0 - */ -public class TraceValidationStatus extends Status { - - private int fConfidence; - - /** - * Construct a successful validation status with a confidence level - * - * @param confidence the confidence level, 0 is lowest - * @param pluginId the unique identifier of the relevant plug-in - */ - public TraceValidationStatus(int confidence, String pluginId) { - super(OK, pluginId, OK_STATUS.getMessage()); - if (confidence < 0) { - throw new IllegalArgumentException(); - } - fConfidence = confidence; - } - - /** - * Gets the confidence level - * - * @return the confidence level, 0 is lowest - */ - public int getConfidence() { - return fConfidence; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/ITmfPersistentlyIndexable.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/ITmfPersistentlyIndexable.java deleted file mode 100644 index 1011008174..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/ITmfPersistentlyIndexable.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace.indexer; - -import java.nio.ByteBuffer; - -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - -/** - * A trace implementing this interface can be indexed and its index can be - * persisted to disk. - * - * @author Marc-Andre Laperle - * @since 3.0 - */ -public interface ITmfPersistentlyIndexable { - - /** - * Instantiate a ITmfLocation from a ByteBuffer, typically from disk. - * - * @param bufferIn - * the buffer to read from - * @return the instantiated location - * - * @since 3.0 - */ - ITmfLocation restoreLocation(ByteBuffer bufferIn); - - /** - * Get the checkpoint size for this trace - * - * @return the checkpoint size - * - * @since 3.0 - */ - public int getCheckpointSize(); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/ITmfTraceIndexer.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/ITmfTraceIndexer.java deleted file mode 100644 index 3f279480e6..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/ITmfTraceIndexer.java +++ /dev/null @@ -1,116 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace.indexer; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * The generic trace indexer in TMF with support for incremental indexing. - * - * @see ITmfTrace - * @see ITmfEvent - * - * @author Francois Chouinard - * @since 3.0 - */ -public interface ITmfTraceIndexer { - - /** - * Start an asynchronous index building job and waits for the job completion - * if required. Typically, the indexing job sends notifications at regular - * intervals to indicate its progress. - *

- * Example 1: Index a whole trace asynchronously - * - *

-     * trace.getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, false);
-     * 
- * - * Example 2: Index a whole trace synchronously - * - *
-     * trace.getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, true);
-     * 
- * - * Example 3: Index a trace asynchronously, starting at rank 100 - * - *
-     * trace.getIndexer().buildIndex(100, TmfTimeRange.ETERNITY, false);
-     * 
- * - * Example 4: Index a trace asynchronously, starting at rank 100 for - * events between T1 and T2 (inclusive). This is used for incremental - * indexing. - * - *
-     * TmfTimeRange range = new TmfTimeRange(T1, T2);
-     * trace.getIndexer().buildIndex(100, range, false);
-     * 
- * - * @param offset - * The offset of the first event to consider - * @param range - * The time range to consider - * @param waitForCompletion - * Should we block the calling thread until the build is - * complete? - * @since 2.0 - */ - void buildIndex(long offset, TmfTimeRange range, boolean waitForCompletion); - - /** - * Indicates that the indexer is busy indexing the trace. - * Will always return false if the indexing is done synchronously. - * - * @return the state of the indexer (indexing or not) - */ - boolean isIndexing(); - - /** - * Adds an entry to the trace index. - * - * @param context The trace context to save - * @param timestamp The timestamp matching this context - * @since 2.0 - */ - void updateIndex(ITmfContext context, ITmfTimestamp timestamp); - - /** - * Returns the context of the checkpoint immediately preceding the requested - * timestamp (or at the timestamp if it coincides with a checkpoint). - * - * @param timestamp the requested timestamp - * @return the checkpoint context - * @since 2.0 - */ - ITmfContext seekIndex(ITmfTimestamp timestamp); - - /** - * Returns the context of the checkpoint immediately preceding the requested - * rank (or at rank if it coincides with a checkpoint). - * - * @param rank the requested event rank - * @return the checkpoint context - */ - ITmfContext seekIndex(long rank); - - /** - * Perform cleanup when the indexer is no longer required. - */ - void dispose(); - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/TmfBTreeTraceIndex.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/TmfBTreeTraceIndex.java deleted file mode 100644 index 39f2bf47e3..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/TmfBTreeTraceIndex.java +++ /dev/null @@ -1,139 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace.indexer; - -import java.io.File; - -import org.eclipse.linuxtools.internal.tmf.core.trace.indexer.BTree; -import org.eclipse.linuxtools.internal.tmf.core.trace.indexer.FlatArray; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; - -/** - * A checkpoint index that uses a BTree to store and search checkpoints by time stamps. - * It's possible to have the checkpoints time stamps in a different order than their checkpoint ranks. - * Because of that, we use a separate structure FlatArray that is better suited for searching - * by checkpoint rank (O(1)). - * - * @since 3.0 - * @author Marc-Andre Laperle - */ -public class TmfBTreeTraceIndex implements ITmfCheckpointIndex { - - private final BTree fCheckpoints; - private final FlatArray fCheckpointRanks; - - private static final int BTREE_DEGREE = 15; - - /** - * Creates an index for the given trace - * - * @param trace the trace - */ - public TmfBTreeTraceIndex(ITmfTrace trace) { - BTree bTree = createBTree(trace); - FlatArray flatArray = createFlatArray(trace); - - // If one of the files is created from scratch, make sure we rebuild the other one too - if (bTree.isCreatedFromScratch() != flatArray.isCreatedFromScratch()) { - bTree.delete(); - flatArray.delete(); - bTree = createBTree(trace); - flatArray = createFlatArray(trace); - } - - fCheckpoints = bTree; - fCheckpointRanks = flatArray; - } - - private static FlatArray createFlatArray(ITmfTrace trace) { - return new FlatArray(getIndexFile(trace, FlatArray.INDEX_FILE_NAME), (ITmfPersistentlyIndexable)trace); - } - - private static BTree createBTree(ITmfTrace trace) { - return new BTree(BTREE_DEGREE, getIndexFile(trace, BTree.INDEX_FILE_NAME), (ITmfPersistentlyIndexable)trace); - } - - private static File getIndexFile(ITmfTrace trace, String fileName) { - String directory = TmfTraceManager.getSupplementaryFileDir(trace); - return new File(directory + fileName); - } - - @Override - public void dispose() { - fCheckpoints.dispose(); - fCheckpointRanks.dispose(); - } - - @Override - public void insert(ITmfCheckpoint checkpoint) { - fCheckpoints.insert(checkpoint); - fCheckpointRanks.insert(checkpoint); - fCheckpoints.setSize(fCheckpoints.size() + 1); - } - - @Override - public ITmfCheckpoint get(long checkpoint) { - return fCheckpointRanks.get(checkpoint); - } - - @Override - public long binarySearch(ITmfCheckpoint checkpoint) { - return fCheckpoints.binarySearch(checkpoint); - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - @Override - public int size() { - return fCheckpoints.size(); - } - - @Override - public boolean isCreatedFromScratch() { - return fCheckpoints.isCreatedFromScratch(); - } - - @Override - public void setTimeRange(TmfTimeRange timeRange) { - fCheckpoints.setTimeRange(timeRange); - } - - @Override - public void setNbEvents(long nbEvents) { - fCheckpoints.setNbEvents(nbEvents); - } - - @Override - public TmfTimeRange getTimeRange() { - return fCheckpoints.getTimeRange(); - } - - @Override - public long getNbEvents() { - return fCheckpoints.getNbEvents(); - } - - @Override - public void setIndexComplete() { - fCheckpoints.setIndexComplete(); - fCheckpointRanks.setIndexComplete(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/TmfBTreeTraceIndexer.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/TmfBTreeTraceIndexer.java deleted file mode 100644 index a4d76b2144..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/TmfBTreeTraceIndexer.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace.indexer; - -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer; - -/** - * An indexer that uses a Btree index to store checkpoints - * - * @since 3.0 - * @author Marc-Andre Laperle - */ -public class TmfBTreeTraceIndexer extends TmfCheckpointIndexer { - - /** - * Full trace indexer - * - * @param trace - * the trace to index - * @param interval - * the checkpoints interval - */ - public TmfBTreeTraceIndexer(ITmfTrace trace, int interval) { - super(trace, interval); - } - - @Override - protected ITmfCheckpointIndex createIndex(ITmfTrace trace) { - return new TmfBTreeTraceIndex(trace); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/TmfFlatArrayTraceIndex.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/TmfFlatArrayTraceIndex.java deleted file mode 100644 index c1fd940e5a..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/TmfFlatArrayTraceIndex.java +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace.indexer; - -import java.io.File; - -import org.eclipse.linuxtools.internal.tmf.core.trace.indexer.FlatArray; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; - -/** - *

A checkpoint index that uses a FlatArray to store and search checkpoints by - * time stamps and by checkpoint rank.

- * - *

Note: This index alone will not work for - * traces that have events with time stamps that are out of order.

- * - * @since 3.0 - * @author Marc-Andre Laperle - */ -public class TmfFlatArrayTraceIndex implements ITmfCheckpointIndex { - - private final FlatArray fCheckpoints; - - /** - * Creates an index for the given trace - * - * @param trace the trace - */ - public TmfFlatArrayTraceIndex(ITmfTrace trace) { - fCheckpoints = new FlatArray(getIndexFile(trace, FlatArray.INDEX_FILE_NAME), (ITmfPersistentlyIndexable)trace); - } - - private static File getIndexFile(ITmfTrace trace, String fileName) { - String directory = TmfTraceManager.getSupplementaryFileDir(trace); - return new File(directory + fileName); - } - - @Override - public void dispose() { - fCheckpoints.dispose(); - } - - @Override - public void insert(ITmfCheckpoint checkpoint) { - fCheckpoints.insert(checkpoint); - } - - @Override - public ITmfCheckpoint get(long checkpoint) { - return fCheckpoints.get(checkpoint); - } - - @Override - public long binarySearch(ITmfCheckpoint checkpoint) { - return fCheckpoints.binarySearch(checkpoint); - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - @Override - public int size() { - return fCheckpoints.size(); - } - - @Override - public boolean isCreatedFromScratch() { - return fCheckpoints.isCreatedFromScratch(); - } - - @Override - public void setTimeRange(TmfTimeRange timeRange) { - fCheckpoints.setTimeRange(timeRange); - } - - @Override - public void setNbEvents(long nbEvents) { - fCheckpoints.setNbEvents(nbEvents); - } - - @Override - public TmfTimeRange getTimeRange() { - return fCheckpoints.getTimeRange(); - } - - @Override - public long getNbEvents() { - return fCheckpoints.getNbEvents(); - } - - @Override - public void setIndexComplete() { - fCheckpoints.setIndexComplete(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/TmfFlatArrayTraceIndexer.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/TmfFlatArrayTraceIndexer.java deleted file mode 100644 index 7ae1cef6b1..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/TmfFlatArrayTraceIndexer.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace.indexer; - -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer; - -/** - * An indexer that uses a FlatArray index to store checkpoints - * - * @since 3.0 - * @author Marc-Andre Laperle - */ -public class TmfFlatArrayTraceIndexer extends TmfCheckpointIndexer { - - /** - * Full trace indexer - * - * @param trace - * the trace to index - * @param interval - * the checkpoints interval - */ - public TmfFlatArrayTraceIndexer(ITmfTrace trace, int interval) { - super(trace, interval); - } - - @Override - protected ITmfCheckpointIndex createIndex(ITmfTrace trace) { - return new TmfFlatArrayTraceIndex(trace); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/checkpoint/ITmfCheckpoint.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/checkpoint/ITmfCheckpoint.java deleted file mode 100644 index e847fc2d85..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/checkpoint/ITmfCheckpoint.java +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Updated for location in checkpoint - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint; - -import java.nio.ByteBuffer; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - -/** - * The basic trace checkpoint structure in TMF. The purpose of the checkpoint is - * to associate a trace location to an event timestamp. - * * - * @see ITmfTimestamp - * @see ITmfLocation - * - * @author Francois Chouinard - * @since 3.0 - */ -public interface ITmfCheckpoint extends Comparable { - - // ------------------------------------------------------------------------ - // Getters - // ------------------------------------------------------------------------ - - /** - * The maximum size of the serialize buffer when determining the checkpoint - * size - */ - static final int MAX_SERIALIZE_SIZE = 1024; - - /** - * @return the timestamp of the event referred to by the context - * @since 2.0 - */ - ITmfTimestamp getTimestamp(); - - /** - * @return the location of the event referred to by the checkpoint - */ - ITmfLocation getLocation(); - - // ------------------------------------------------------------------------ - // Comparable - // ------------------------------------------------------------------------ - - @Override - int compareTo(ITmfCheckpoint checkpoint); - - /** - * Returns the checkpoint rank for this checkpoint. The checkpoint rank can - * be seen as the index of the checkpoint in the order it was added. - * - * @return the checkpoint rank for this checkpoint - * @since 3.0 - */ - long getCheckpointRank(); - - /** - * Write the checkpoint to the ByteBuffer so that it can be saved to disk. - * - * @param bufferOut - * the buffer to write to - * - * @since 3.0 - */ - void serialize(ByteBuffer bufferOut); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/checkpoint/ITmfCheckpointIndex.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/checkpoint/ITmfCheckpointIndex.java deleted file mode 100644 index 264e3604d2..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/checkpoint/ITmfCheckpointIndex.java +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint; - -import java.util.Collections; - -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; - -/** - * A trace index contains the data (checkpoints) needed by the indexer so that it can perform - * its operations. Implementors can store checkpoints in various ways and - * optionally restore them later, see ({@link #isCreatedFromScratch}) - * - * @since 3.0 - * @author Marc-Andre Laperle - */ -public interface ITmfCheckpointIndex { - - /** - * Add a checkpoint to the index - * - * @param checkpoint - * the checkpoint to add - */ - void insert(ITmfCheckpoint checkpoint); - - /** - * Get a checkpoint by checkpoint rank - * - * @param checkpointRank - * the checkpoint rank to search for - * @return the checkpoint found for the given checkpoint rank - */ - ITmfCheckpoint get(long checkpointRank); - - /** - * Find the checkpoint rank of a checkpoint. Implementors must respect the - * contract of {@link Collections#binarySearch} - * - * @param checkpoint - * the checkpoint to search for - * @return the checkpoint rank of the searched checkpoint, if it is - * contained in the index; otherwise, (-(insertion point) - 1). - */ - long binarySearch(ITmfCheckpoint checkpoint); - - /** - * Returns whether or not the index is empty - * - * @return true if empty false otherwise - */ - boolean isEmpty(); - - /** - * Returns the number of checkpoints in the index - * - * @return the number of checkpoints - */ - int size(); - - /** - * Dispose the index and its resources - */ - void dispose(); - - /** - * Returns whether or not the index was created from scratch. An index not - * created from scratch was typically loaded from disk. - * - * @return true if the index was created from scratch, false otherwise - */ - boolean isCreatedFromScratch(); - - /** - * Set trace time range to be stored in the index - * - * @param timeRange - * the time range to be stored in the index - */ - void setTimeRange(TmfTimeRange timeRange); - - /** - * Set the total number of events in the trace to be stored in the index - * - * @param nbEvents - * the total number of events - */ - void setNbEvents(long nbEvents); - - /** - * Get the trace time range stored in the index - * - * @return the trace time range - */ - TmfTimeRange getTimeRange(); - - /** - * Get the total number of events in the trace stored in the index - * - * @return the total number of events - */ - long getNbEvents(); - - /** - * Set the index as complete. No more checkpoints will be inserted. - */ - void setIndexComplete(); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/checkpoint/TmfCheckpoint.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/checkpoint/TmfCheckpoint.java deleted file mode 100644 index b3c74722f3..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/checkpoint/TmfCheckpoint.java +++ /dev/null @@ -1,222 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Updated as per TMF Trace Model 1.0 - * Patrick Tasse - Updated for location in checkpoint - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint; - -import java.nio.ByteBuffer; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - -/** - * A basic implementation of ITmfCheckpoint. It simply maps an event timestamp - * to a generic location. - * - * @see ITmfLocation - * @see ITmfTimestamp - * - * @author Francois Chouinard - * @since 3.0 - */ -public class TmfCheckpoint implements ITmfCheckpoint { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // The checkpoint location - private final ITmfLocation fLocation; - - // The checkpoint timestamp - private final ITmfTimestamp fTimestamp; - - private final long fCheckpointRank; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Full constructor - * - * @param timestamp - * the checkpoint timestamp - * @param location - * the corresponding trace location - * @param checkpointRank - * the rank of the checkpoint - * @since 3.0 - */ - public TmfCheckpoint(final ITmfTimestamp timestamp, final ITmfLocation location, long checkpointRank) { - fTimestamp = timestamp; - fLocation = location; - fCheckpointRank = checkpointRank; - } - - /** - * Constructs a checkpoint using also a byte buffer to read the rank from - * disk. - * - * @param timestamp - * the checkpoint timestamp - * @param location - * the corresponding trace location - * @param bufferIn - * the byte buffer to read from - * - * @since 3.0 - */ - public TmfCheckpoint(final ITmfTimestamp timestamp, final ITmfLocation location, ByteBuffer bufferIn) { - fTimestamp = timestamp; - fLocation = location; - fCheckpointRank = bufferIn.getLong(); - } - - /** - * Copy constructor - * - * @param other the other checkpoint - */ - public TmfCheckpoint(final TmfCheckpoint other) { - if (other == null) { - throw new IllegalArgumentException(); - } - fTimestamp = other.fTimestamp; - fLocation = other.fLocation; - fCheckpointRank = other.fCheckpointRank; - } - - // ------------------------------------------------------------------------ - // ITmfCheckpoint - // ------------------------------------------------------------------------ - - /** - * @since 2.0 - */ - @Override - public ITmfTimestamp getTimestamp() { - return fTimestamp; - } - - @Override - public ITmfLocation getLocation() { - return fLocation; - } - - // ------------------------------------------------------------------------ - // Comparable - // ------------------------------------------------------------------------ - - @Override - @SuppressWarnings({ "unchecked", "rawtypes" }) - public int compareTo(final ITmfCheckpoint other) { - int comp = 0; - if ((fTimestamp != null) && (other.getTimestamp() != null)) { - comp = fTimestamp.compareTo(other.getTimestamp(), false); - if (comp != 0) { - return comp; - } - // compare locations if timestamps are the same - } - - if ((fLocation == null) && (other.getLocation() == null)) { - return 0; - } - - // treat location of other as null location which is before any location - if ((fLocation != null) && (other.getLocation() == null)) { - return 1; - } - - // treat this as null location which is before any other locations - if ((fLocation == null) && (other.getLocation() != null)) { - return -1; - } - - // compare location - final Comparable location1 = getLocation().getLocationInfo(); - final Comparable location2 = other.getLocation().getLocationInfo(); - return location1.compareTo(location2); - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((fLocation == null) ? 0 : fLocation.hashCode()); - result = prime * result + ((fTimestamp == null) ? 0 : fTimestamp.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof TmfCheckpoint)) { - return false; - } - final TmfCheckpoint other = (TmfCheckpoint) obj; - if (fLocation == null) { - if (other.fLocation != null) { - return false; - } - } else if (!fLocation.equals(other.fLocation)) { - return false; - } - if (fTimestamp == null) { - if (other.fTimestamp != null) { - return false; - } - } else if (!fTimestamp.equals(other.fTimestamp)) { - return false; - } - return true; - } - - @Override - @SuppressWarnings("nls") - public String toString() { - return getClass().getSimpleName() + " [fLocation=" + fLocation + ", fTimestamp=" + fTimestamp + ", fCheckpointRank=" + fCheckpointRank + "]"; - } - - /** - * @since 3.0 - */ - @Override - public void serialize(ByteBuffer bufferOut) { - fLocation.serialize(bufferOut); - // Always serialize as base TmfTimestamp, this should be sufficient for indexing. - // If not, we can add API for the test to restore the time stamp, similarly to the location. - TmfTimestamp t = new TmfTimestamp(fTimestamp); - t.serialize(bufferOut); - bufferOut.putLong(fCheckpointRank); - } - - /** - * @since 3.0 - */ - @Override - public long getCheckpointRank() { - return fCheckpointRank; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/checkpoint/TmfCheckpointIndexer.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/checkpoint/TmfCheckpointIndexer.java deleted file mode 100644 index eacdd0ef24..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/indexer/checkpoint/TmfCheckpointIndexer.java +++ /dev/null @@ -1,355 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Update way of broadcasting of TmfTraceUpdatedSignal - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.linuxtools.internal.tmf.core.Messages; -import org.eclipse.linuxtools.internal.tmf.core.trace.indexer.TmfMemoryIndex; -import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTraceCompleteness; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - -/** - * A simple indexer that manages the trace index as an array of trace - * checkpoints. Checkpoints are stored in memory at fixed intervals (event rank) in - * ascending timestamp order. - *

- * The goal being to access a random trace event reasonably fast from the user's - * standpoint, picking the right interval value becomes a trade-off between speed - * and memory usage (a shorter inter-event interval is faster but requires more - * checkpoints). - *

- * Locating a specific checkpoint is trivial for both rank (rank % interval) and - * timestamp (bsearch in the array). - * * - * @see ITmfTrace - * @see ITmfEvent - * - * @author Francois Chouinard - * @since 3.0 - */ -public class TmfCheckpointIndexer implements ITmfTraceIndexer { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** The event trace to index */ - protected final ITmfTrace fTrace; - - /** The interval between checkpoints */ - private final int fCheckpointInterval; - - /** The event trace to index */ - private boolean fIsIndexing; - - /** - * The trace index. It is composed of checkpoints taken at intervals of - * fCheckpointInterval events. - */ - protected final ITmfCheckpointIndex fTraceIndex; - - /** - * The indexing request - */ - private ITmfEventRequest fIndexingRequest = null; - - // ------------------------------------------------------------------------ - // Construction - // ------------------------------------------------------------------------ - - /** - * Basic constructor that uses the default trace block size as checkpoints - * intervals - * - * @param trace the trace to index - */ - public TmfCheckpointIndexer(final ITmfTrace trace) { - this(trace, TmfEventProvider.DEFAULT_BLOCK_SIZE); - } - - /** - * Full trace indexer - * - * @param trace the trace to index - * @param interval the checkpoints interval - */ - public TmfCheckpointIndexer(final ITmfTrace trace, final int interval) { - fTrace = trace; - fCheckpointInterval = interval; - fTraceIndex = createIndex(trace); - fIsIndexing = false; - } - - /** - * Creates the index instance. Classes extending this class - * can override this to provide a different index implementation. - * - * @param trace the trace to index - * @return the index - * @since 3.0 - */ - protected ITmfCheckpointIndex createIndex(final ITmfTrace trace) { - return new TmfMemoryIndex(trace); - } - - @Override - public void dispose() { - if ((fIndexingRequest != null) && !fIndexingRequest.isCompleted()) { - fIndexingRequest.cancel(); - } - - fTraceIndex.dispose(); - } - - // ------------------------------------------------------------------------ - // ITmfTraceIndexer - isIndexing - // ------------------------------------------------------------------------ - - @Override - public boolean isIndexing() { - return fIsIndexing; - } - - // ------------------------------------------------------------------------ - // ITmfTraceIndexer - buildIndex - // ------------------------------------------------------------------------ - - /** - * @since 2.0 - */ - @Override - public void buildIndex(final long offset, final TmfTimeRange range, final boolean waitForCompletion) { - - // Don't do anything if we are already indexing - synchronized (fTraceIndex) { - if (fIsIndexing) { - return; - } - fIsIndexing = true; - } - - // No need to build the index, it has been restored - if (!fTraceIndex.isCreatedFromScratch()) { - // Set some trace attributes that depends on indexing - TmfTraceUpdatedSignal signal = new TmfTraceUpdatedSignal(this, fTrace, new TmfTimeRange(fTraceIndex.getTimeRange().getStartTime(), fTraceIndex.getTimeRange().getEndTime()), fTraceIndex.getNbEvents()); - if (waitForCompletion) { - fTrace.broadcast(signal); - } else { - fTrace.broadcastAsync(signal); - } - fIsIndexing = false; - return; - } - - // The monitoring job - final Job job = new Job("Indexing " + fTrace.getName() + "...") { //$NON-NLS-1$ //$NON-NLS-2$ - @Override - protected IStatus run(final IProgressMonitor monitor) { - monitor.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$ - while (!monitor.isCanceled()) { - try { - long prevNbEvents = fTrace.getNbEvents(); - Thread.sleep(250); - long nbEvents = fTrace.getNbEvents(); - setName(Messages.TmfCheckpointIndexer_Indexing + ' ' + fTrace.getName() + " (" + nbEvents + ")"); //$NON-NLS-1$ //$NON-NLS-2$ - // setName doesn't refresh the UI, setTaskName does - long rate = (nbEvents - prevNbEvents) * 4; - monitor.setTaskName(rate + " " + Messages.TmfCheckpointIndexer_EventsPerSecond); //$NON-NLS-1$ - } catch (final InterruptedException e) { - return Status.OK_STATUS; - } - } - monitor.done(); - return Status.OK_STATUS; - } - }; - job.setSystem(!isCompleteTrace(fTrace)); - job.schedule(); - - // Build a background request for all the trace data. The index is - // updated as we go by readNextEvent(). - fIndexingRequest = new TmfEventRequest(ITmfEvent.class, - range, offset, ITmfEventRequest.ALL_DATA, - ITmfEventRequest.ExecutionType.BACKGROUND) { - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - // Update the trace status at regular intervals - if ((getNbRead() % fCheckpointInterval) == 0) { - updateTraceStatus(); - } - } - - @Override - public void handleSuccess() { - fTraceIndex.setTimeRange(fTrace.getTimeRange()); - fTraceIndex.setNbEvents(fTrace.getNbEvents()); - if (isCompleteTrace(fTrace)) { - fTraceIndex.setIndexComplete(); - } - updateTraceStatus(); - } - - @Override - public void handleCompleted() { - job.cancel(); - super.handleCompleted(); - fIsIndexing = false; - } - - private void updateTraceStatus() { - if (fTrace.getNbEvents() > 0) { - signalNewTimeRange(fTrace.getStartTime(), fTrace.getEndTime()); - } - } - }; - - // Submit the request and wait for completion if required - fTrace.sendRequest(fIndexingRequest); - if (waitForCompletion) { - try { - fIndexingRequest.waitForCompletion(); - } catch (final InterruptedException e) { - } - } - } - - /** - * Notify the interested parties that the trace time range has changed - * - * @param startTime the new start time - * @param endTime the new end time - */ - private void signalNewTimeRange(final ITmfTimestamp startTime, final ITmfTimestamp endTime) { - fTrace.broadcast(new TmfTraceUpdatedSignal(fTrace, fTrace, new TmfTimeRange(startTime, endTime), fTrace.getNbEvents())); - } - - // ------------------------------------------------------------------------ - // ITmfTraceIndexer - updateIndex - // ------------------------------------------------------------------------ - - /** - * @since 2.0 - */ - @Override - public synchronized void updateIndex(final ITmfContext context, final ITmfTimestamp timestamp) { - if ((context.getRank() % fCheckpointInterval) == 0) { - // Determine the table position - final long position = context.getRank() / fCheckpointInterval; - // Add new entry at proper location (if empty) - if (fTraceIndex.size() == position) { - fTraceIndex.insert(new TmfCheckpoint(timestamp, context.getLocation(), position)); - } - } - } - - // ------------------------------------------------------------------------ - // ITmfTraceIndexer - seekIndex - // ------------------------------------------------------------------------ - - /** - * @since 2.0 - */ - @Override - public synchronized ITmfContext seekIndex(final ITmfTimestamp timestamp) { - - // A null timestamp indicates to seek the first event - if (timestamp == null) { - return fTrace.seekEvent(0); - } - - // Find the checkpoint at or before the requested timestamp. - // In the very likely event that the timestamp is not at a checkpoint - // boundary, bsearch will return index = (- (insertion point + 1)). - // It is then trivial to compute the index of the previous checkpoint. - long index = fTraceIndex.binarySearch(new TmfCheckpoint(timestamp, null, 0)); - if (index < 0) { - index = Math.max(0, -(index + 2)); - } else { - // If timestamp was in the list, use previous index to be able to find the - // first event with the same timestamp before the checkpoint - index = Math.max(0, index - 1); - } - - // Position the trace at the checkpoint - return restoreCheckpoint(index); - } - - @Override - public ITmfContext seekIndex(final long rank) { - - // A rank < 0 indicates to seek the first event - if (rank < 0) { - return fTrace.seekEvent(0); - } - - // Find the checkpoint at or before the requested rank. - final int index = (int) rank / fCheckpointInterval; - - // Position the trace at the checkpoint - return restoreCheckpoint(index); - } - - /** - * Position the trace at the given checkpoint - * - * @param checkpoint the checkpoint index - * @return the corresponding context - */ - private ITmfContext restoreCheckpoint(final long checkpoint) { - ITmfLocation location = null; - long index = 0; - synchronized (fTraceIndex) { - if (!fTraceIndex.isEmpty()) { - index = checkpoint; - if (index >= fTraceIndex.size()) { - index = fTraceIndex.size() - 1; - } - location = fTraceIndex.get(index).getLocation(); - } - } - final ITmfContext context = fTrace.seekEvent(location); - context.setRank(index * fCheckpointInterval); - return context; - } - - // ------------------------------------------------------------------------ - // Getters - // ------------------------------------------------------------------------ - - /** - * @return the trace index - * @since 3.0 - */ - protected ITmfCheckpointIndex getTraceIndex() { - return fTraceIndex; - } - - private static boolean isCompleteTrace(ITmfTrace trace) { - return !(trace instanceof ITmfTraceCompleteness) || ((ITmfTraceCompleteness)trace).isComplete(); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/location/ITmfLocation.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/location/ITmfLocation.java deleted file mode 100644 index 50819485a8..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/location/ITmfLocation.java +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Updated as per TMF Trace Model 1.0 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace.location; - -import java.nio.ByteBuffer; - -/** - * The generic trace location in TMF. - *

- * An ITmfLocation is the equivalent of a random-access file position, holding - * enough information to allow the positioning of the trace 'pointer' to read an - * arbitrary event. - *

- * This location is trace-specific, must be comparable and immutable. - * - * @author Francois Chouinard - * @since 3.0 - */ -public interface ITmfLocation { - - // ------------------------------------------------------------------------ - // Getters - // ------------------------------------------------------------------------ - - /** - * Returns the concrete trace location information - * - * @return the location information - * @since 2.0 - */ - Comparable getLocationInfo(); - - /** - * Write the location to the ByteBuffer so that it can be saved to disk. - * @param bufferOut the buffer to write to - * - * @since 3.0 - */ - void serialize(ByteBuffer bufferOut); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/location/TmfLocation.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/location/TmfLocation.java deleted file mode 100644 index 133f002886..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/location/TmfLocation.java +++ /dev/null @@ -1,108 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Updated as per TMF Trace Model 1.0 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace.location; - - -/** - * A abstract implementation of ITmfLocation. The concrete classes must provide - * comparable location information. - * - * @author Francois Chouinard - * @since 3.0 - */ -public abstract class TmfLocation implements ITmfLocation { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final Comparable fLocationInfo; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Standard constructor. - * - * @param locationInfo - * The concrete trace location - */ - public TmfLocation(final Comparable locationInfo) { - fLocationInfo = locationInfo; - } - - /** - * Copy constructor - * - * @param location - * The original trace location - */ - public TmfLocation(final TmfLocation location) { - fLocationInfo = location.fLocationInfo; - } - - // ------------------------------------------------------------------------ - // Getters - // ------------------------------------------------------------------------ - - /** - * @since 2.0 - */ - @Override - public Comparable getLocationInfo() { - return fLocationInfo; - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((fLocationInfo != null) ? fLocationInfo.hashCode() : 0); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final TmfLocation other = (TmfLocation) obj; - if (fLocationInfo == null) { - if (other.fLocationInfo != null) { - return false; - } - } else if (!fLocationInfo.equals(other.fLocationInfo)) { - return false; - } - return true; - } - - @Override - @SuppressWarnings("nls") - public String toString() { - return getClass().getSimpleName() + " [fLocationInfo=" + fLocationInfo + "]"; - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/location/TmfLongLocation.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/location/TmfLongLocation.java deleted file mode 100644 index fdb249f10a..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/location/TmfLongLocation.java +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace.location; - -import java.nio.ByteBuffer; - -/** - * A concrete implementation of TmfLocation based on Long:s - * - * @author Francois Chouinard - * @since 3.0 - */ -public final class TmfLongLocation extends TmfLocation { - - /** - * Constructor - * - * @param locationInfo - * The concrete location - */ - public TmfLongLocation(long locationInfo) { - super(Long.valueOf(locationInfo)); - } - - /** - * The normal constructor - * - * @param locationInfo the concrete location - */ - public TmfLongLocation(final Long locationInfo) { - super(locationInfo); - } - - /** - * The copy constructor - * - * @param other the other location - */ - public TmfLongLocation(final TmfLongLocation other) { - super(other.getLocationInfo()); - } - - /** - * Construct the location from the ByteBuffer. - * - * @param bufferIn - * the buffer to read from - * - * @since 3.0 - */ - public TmfLongLocation(ByteBuffer bufferIn) { - this(bufferIn.getLong()); - } - - @Override - public Long getLocationInfo() { - return (Long) super.getLocationInfo(); - } - - /** - * @since 3.0 - */ - @Override - public void serialize(ByteBuffer bufferOut) { - bufferOut.putLong(getLocationInfo().longValue()); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/location/TmfTimestampLocation.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/location/TmfTimestampLocation.java deleted file mode 100644 index 4e76217cfe..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/location/TmfTimestampLocation.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace.location; - -import java.nio.ByteBuffer; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; - -/** - * A concrete implementation of TmfLocation based on ITmfTimestamp:s - * - * @author Francois Chouinard - * @since 3.0 - */ -public final class TmfTimestampLocation extends TmfLocation { - - /** - * The normal constructor - * - * @param locationInfo the concrete location - */ - public TmfTimestampLocation(final ITmfTimestamp locationInfo) { - super(locationInfo); - } - - /** - * The copy constructor - * - * @param other the other location - */ - public TmfTimestampLocation(final TmfTimestampLocation other) { - super(other.getLocationInfo()); - } - - /** - * Construct the location from the ByteBuffer. - * - * @param bufferIn - * the buffer to read from - * - * @since 3.0 - */ - public TmfTimestampLocation(ByteBuffer bufferIn) { - super(new TmfTimestamp(bufferIn)); - } - - @Override - public ITmfTimestamp getLocationInfo() { - return (ITmfTimestamp) super.getLocationInfo(); - } - - /** - * @since 3.0 - */ - @Override - public void serialize(ByteBuffer bufferOut) { - TmfTimestamp t = new TmfTimestamp(getLocationInfo()); - t.serialize(bufferOut); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTrace.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTrace.java deleted file mode 100644 index cd48427d6c..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTrace.java +++ /dev/null @@ -1,382 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Marc-Andre Laperle - Add persistent index support - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace.text; - -import java.io.File; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.Collections; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.io.BufferedRandomAccessFile; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser; -import org.eclipse.linuxtools.tmf.core.trace.TmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TraceValidationStatus; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfPersistentlyIndexable; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.indexer.TmfBTreeTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation; - -/** - * Extension of TmfTrace for handling of line-based text traces parsed using - * regular expressions. Each line that matches the first line pattern indicates - * the start of a new event. The subsequent lines can contain additional - * information that is added to the current event. - * - * @param - * TmfEvent class returned by this trace - * - * @since 3.0 - */ -public abstract class TextTrace extends TmfTrace implements ITmfEventParser, ITmfPersistentlyIndexable { - - private static final TmfLongLocation NULL_LOCATION = new TmfLongLocation(-1L); - private static final int MAX_LINES = 100; - private static final int MAX_CONFIDENCE = 100; - - /** The default separator used for multi-line fields */ - protected static final String SEPARATOR = " | "; //$NON-NLS-1$ - - /** The text file */ - protected BufferedRandomAccessFile fFile; - - /** - * Constructor - */ - public TextTrace() { - } - - /** - * {@inheritDoc} - *

- * The default implementation computes the confidence as the sum of weighted - * values of the first 100 lines of the file which match any of the provided - * validation patterns. For each matching line a weighted value between 1.5 - * and 2.0 is assigned based on the group count of the matching patterns. - * The higher the group count, the closer the weighted value will be to 2.0. - */ - @Override - public IStatus validate(IProject project, String path) { - File file = new File(path); - if (!file.exists()) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "File not found: " + path); //$NON-NLS-1$ - } - if (!file.isFile()) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Not a file. It's a directory: " + path); //$NON-NLS-1$ - } - int confidence = 0; - try (BufferedRandomAccessFile rafile = new BufferedRandomAccessFile(path, "r")) { //$NON-NLS-1$ - int lineCount = 0; - double matches = 0.0; - String line = rafile.getNextLine(); - List validationPatterns = getValidationPatterns(); - while ((line != null) && (lineCount++ < MAX_LINES)) { - for(Pattern pattern : validationPatterns) { - Matcher matcher = pattern.matcher(line); - if (matcher.matches()) { - int groupCount = matcher.groupCount(); - matches += (1.0 + groupCount / ((double) groupCount + 1)); - } - } - confidence = (int) (MAX_CONFIDENCE * matches / lineCount); - line = rafile.getNextLine(); - } - } catch (IOException e) { - Activator.logError("Error validating file: " + path, e); //$NON-NLS-1$ - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "IOException validating file: " + path, e); //$NON-NLS-1$ - } - - return new TraceValidationStatus(confidence, Activator.PLUGIN_ID); - - } - @Override - public void initTrace(IResource resource, String path, Class type) throws TmfTraceException { - super.initTrace(resource, path, type); - try { - fFile = new BufferedRandomAccessFile(getPath(), "r"); //$NON-NLS-1$ - } catch (IOException e) { - throw new TmfTraceException(e.getMessage(), e); - } - } - - @Override - public synchronized void dispose() { - super.dispose(); - if (fFile != null) { - try { - fFile.close(); - } catch (IOException e) { - } finally { - fFile = null; - } - } - } - - @Override - public synchronized TextTraceContext seekEvent(ITmfLocation location) { - TextTraceContext context = new TextTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK); - if (NULL_LOCATION.equals(location) || fFile == null) { - return context; - } - try { - if (location == null) { - fFile.seek(0); - } else if (location.getLocationInfo() instanceof Long) { - fFile.seek((Long) location.getLocationInfo()); - } - long rawPos = fFile.getFilePointer(); - String line = fFile.getNextLine(); - while (line != null) { - Matcher matcher = getFirstLinePattern().matcher(line); - if (matcher.matches()) { - setupContext(context, rawPos, line, matcher); - return context; - } - rawPos = fFile.getFilePointer(); - line = fFile.getNextLine(); - } - return context; - } catch (IOException e) { - Activator.logError("Error seeking file: " + getPath(), e); //$NON-NLS-1$ - return context; - } - } - - private void setupContext(TextTraceContext context, long rawPos, String line, Matcher matcher) throws IOException { - context.setLocation(new TmfLongLocation(rawPos)); - context.firstLineMatcher = matcher; - context.firstLine = line; - context.nextLineLocation = fFile.getFilePointer(); - } - - @Override - public synchronized TextTraceContext seekEvent(double ratio) { - if (fFile == null) { - return new TextTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK); - } - try { - long pos = (long) (ratio * fFile.length()); - while (pos > 0) { - fFile.seek(pos - 1); - if (fFile.read() == '\n') { - break; - } - pos--; - } - ITmfLocation location = new TmfLongLocation(Long.valueOf(pos)); - TextTraceContext context = seekEvent(location); - context.setRank(ITmfContext.UNKNOWN_RANK); - return context; - } catch (IOException e) { - Activator.logError("Error seeking file: " + getPath(), e); //$NON-NLS-1$ - return new TextTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK); - } - } - - @Override - public double getLocationRatio(ITmfLocation location) { - if (fFile == null) { - return 0; - } - try { - long length = fFile.length(); - if (length == 0) { - return 0; - } - if (location.getLocationInfo() instanceof Long) { - return (double) ((Long) location.getLocationInfo()) / length; - } - } catch (IOException e) { - Activator.logError("Error reading file: " + getPath(), e); //$NON-NLS-1$ - } - return 0; - } - - @Override - public ITmfLocation getCurrentLocation() { - return null; - } - - @Override - public TextTraceEvent parseEvent(ITmfContext tmfContext) { - TextTraceContext context = seekEvent(tmfContext.getLocation()); - return parse(context); - } - - @Override - public synchronized T getNext(ITmfContext context) { - if (!(context instanceof TextTraceContext)) { - throw new IllegalArgumentException(); - } - TextTraceContext savedContext = new TextTraceContext(context.getLocation(), context.getRank()); - T event = parse((TextTraceContext) context); - if (event != null) { - updateAttributes(savedContext, event.getTimestamp()); - context.increaseRank(); - } - return event; - } - - /** - * Parse the next event. The context is advanced. - * - * @param tmfContext - * the context - * @return the next event or null - */ - protected synchronized T parse(TextTraceContext tmfContext) { - if (fFile == null) { - return null; - } - TextTraceContext context = tmfContext; - if (context.getLocation() == null || !(context.getLocation().getLocationInfo() instanceof Long) || NULL_LOCATION.equals(context.getLocation())) { - return null; - } - - T event = parseFirstLine(context.firstLineMatcher, context.firstLine); - - try { - if (fFile.getFilePointer() != context.nextLineLocation) { - fFile.seek(context.nextLineLocation); - } - long rawPos = fFile.getFilePointer(); - String line = fFile.getNextLine(); - while (line != null) { - Matcher matcher = getFirstLinePattern().matcher(line); - if (matcher.matches()) { - setupContext(context, rawPos, line, matcher); - return event; - } - parseNextLine(event, line); - rawPos = fFile.getFilePointer(); - line = fFile.getNextLine(); - } - } catch (IOException e) { - Activator.logError("Error reading file: " + getPath(), e); //$NON-NLS-1$ - } - - context.setLocation(NULL_LOCATION); - return event; - } - - /** - * Gets the first line pattern. - * - * @return The first line pattern - */ - protected abstract Pattern getFirstLinePattern(); - - /** - * Parses the first line data and returns a new event. When constructing the - * event, the concrete trace should use the trace's timestamp transform to - * create the timestamp, by either transforming the parsed time value - * directly or by using the method {@link #createTimestamp(long)}. - * - * @param matcher - * The matcher - * @param line - * The line to parse - * @return The parsed event - */ - protected abstract T parseFirstLine(Matcher matcher, String line); - - /** - * Parses the next line data for the current event. - * - * @param event - * The current event being parsed - * @param line - * The line to parse - */ - protected abstract void parseNextLine(T event, String line); - - /** - * Returns a ordered list of validation patterns that will be used in - * the default {@link #validate(IProject, String)} method to match - * the first 100 to compute the confidence level - * - * @return collection of patterns to validate against - * @since 3.2 - */ - protected List getValidationPatterns() { - return Collections.singletonList(getFirstLinePattern()); - } - - // ------------------------------------------------------------------------ - // Helper methods - // ------------------------------------------------------------------------ - - /** - * Strip quotes surrounding a string - * - * @param input - * The input string - * @return The string without quotes - */ - protected static String replaceQuotes(String input) { - String out = input.replaceAll("^\"|(\"\\s*)$", ""); //$NON-NLS-1$//$NON-NLS-2$ - return out; - } - - /** - * Strip brackets surrounding a string - * - * @param input - * The input string - * @return The string without brackets - */ - protected static String replaceBrackets(String input) { - String out = input.replaceAll("^\\{|(\\}\\s*)$", ""); //$NON-NLS-1$//$NON-NLS-2$ - return out; - } - - private static int fCheckpointSize = -1; - - @Override - public synchronized int getCheckpointSize() { - if (fCheckpointSize == -1) { - TmfCheckpoint c = new TmfCheckpoint(TmfTimestamp.ZERO, new TmfLongLocation(0L), 0); - ByteBuffer b = ByteBuffer.allocate(ITmfCheckpoint.MAX_SERIALIZE_SIZE); - b.clear(); - c.serialize(b); - fCheckpointSize = b.position(); - } - - return fCheckpointSize; - } - - @Override - protected ITmfTraceIndexer createIndexer(int interval) { - return new TmfBTreeTraceIndexer(this, interval); - } - - @Override - public ITmfLocation restoreLocation(ByteBuffer bufferIn) { - return new TmfLongLocation(bufferIn); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTraceContext.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTraceContext.java deleted file mode 100644 index 2b7a7a7175..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTraceContext.java +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace.text; - -import java.util.regex.Matcher; - -import org.eclipse.linuxtools.tmf.core.trace.TmfContext; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - -/** - * Implementation of a TmfContext for text traces. - * - * @since 3.0 - */ -public class TextTraceContext extends TmfContext { - - /** The Matcher object for the first line. */ - public Matcher firstLineMatcher; - /** The first line string */ - public String firstLine; - /** The location of the next line */ - public long nextLineLocation; - - /** - * Constructor - * - * @param location - * Trace location - * @param rank - * Event rank - */ - public TextTraceContext(final ITmfLocation location, final long rank) { - super(location, rank); - } - - /** - * Copy Constructor - * - * @param other - * the other TextTraceContext - */ - public TextTraceContext(TextTraceContext other) { - this(other.getLocation(), other.getRank()); - firstLine = other.firstLine; - firstLineMatcher = other.firstLineMatcher; - nextLineLocation = other.nextLineLocation; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((firstLine == null) ? 0 : firstLine.hashCode()); - result = prime * result + ((firstLineMatcher == null) ? 0 : firstLineMatcher.hashCode()); - result = prime * result + (int) (nextLineLocation ^ (nextLineLocation >>> 32)); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TextTraceContext other = (TextTraceContext) obj; - if (firstLine == null) { - if (other.firstLine != null) { - return false; - } - } else if (!firstLine.equals(other.firstLine)) { - return false; - } - if (firstLineMatcher == null) { - if (other.firstLineMatcher != null) { - return false; - } - } else if (!firstLineMatcher.equals(other.firstLineMatcher)) { - return false; - } - if (nextLineLocation != other.nextLineLocation) { - return false; - } - return true; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTraceEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTraceEvent.java deleted file mode 100644 index 5853f33923..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTraceEvent.java +++ /dev/null @@ -1,76 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace.text; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; - -/** - * Class to store the common functionality of text trace events. - * - * @author Alexandre Montplaisir - * @since 3.0 - */ -public abstract class TextTraceEvent extends TmfEvent { - - /** - * Full Constructor. - * - * Compared to {@link TmfEvent}'s constructor, 'content' is restricted to a - * {@link TextTraceEventContent}. - * - * @param parentTrace - * The parent trace - * @param timestamp - * The event timestamp - * @param source - * The event source - * @param type - * The event type - * @param content - * The event content (payload) - * @param reference - * The event reference - */ - public TextTraceEvent(TextTrace parentTrace, - final ITmfTimestamp timestamp, - final String source, - final ITmfEventType type, - final TextTraceEventContent content, - final String reference) { - super(parentTrace, timestamp, source, type, content, reference); - } - - /** - * Copy constructor - * - * @param other - * The event to copy - */ - public TextTraceEvent(final TextTraceEvent other) { - super(other); - } - - @Override - public TextTrace getTrace() { - /* Cast should be safe, type is restricted by the constructor */ - return (TextTrace) super.getTrace(); - } - - @Override - public TextTraceEventContent getContent() { - /* Cast should be safe, type is restricted by the constructor */ - return (TextTraceEventContent) super.getContent(); - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTraceEventContent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTraceEventContent.java deleted file mode 100644 index b239b7b0a1..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTraceEventContent.java +++ /dev/null @@ -1,312 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Bernd Hufmann - Updated equals, clone and hashCode to consider StringBuffer values - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.core.trace.text; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; - -/** - * Implementation of ITmfEventField for Text Traces. - * - * @since 3.0 - */ -public class TextTraceEventContent implements ITmfEventField { - - private final @NonNull String fName; - private final @NonNull List fFields; - - private @Nullable Object fValue; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructor for a root event content - * - * @param fieldNames - * the array of field names - */ - public TextTraceEventContent(String[] fieldNames) { - fName = ITmfEventField.ROOT_FIELD_ID; - fValue = null; - fFields = new ArrayList<>(fieldNames.length); - for (String fieldName : fieldNames) { - if (fieldName == null) { - throw new IllegalArgumentException("Null field name not allowed"); //$NON-NLS-1$ - } - fFields.add(new TextTraceEventContent(fieldName)); - } - } - - /** - * Constructor for a subfield - * - * @param fieldNames - * the array of field names - */ - private TextTraceEventContent(@NonNull String fieldName) { - fName = fieldName; - fValue = null; - @SuppressWarnings("null") - @NonNull List fields = Collections.EMPTY_LIST; - fFields = fields; - } - - // ------------------------------------------------------------------------ - // ITmfEventField - // ------------------------------------------------------------------------ - - @Override - public String getName() { - return fName; - } - - @Override - public Object getValue() { - return fValue; - } - - @Override - public List getFieldNames() { - List fieldNames = new ArrayList<>(fFields.size()); - for (TextTraceEventContent field : fFields) { - fieldNames.add(field.getName()); - } - return fieldNames; - } - - @Override - public List getFields() { - return new ArrayList<>(fFields); - } - - @Override - public ITmfEventField getField(String name) { - for (TextTraceEventContent field : fFields) { - if (field.getName().equals(name)) { - return field; - } - } - return null; - } - - @Override - public String getFormattedValue() { - Object value = fValue; - if (value == null) { - return null; - } - return value.toString(); - } - - @Override - public ITmfEventField getSubField(String... names) { - // There are no sub fields - if (names.length == 1) { - return getField(names[0]); - } - return null; - } - - // ------------------------------------------------------------------------ - // Convenience getters and setters - // ------------------------------------------------------------------------ - - /** - * Get a field name by index - * - * @param index - * The index of the field - * @return The name of the field at that index - */ - public String getFieldName(int index) { - if (index >= 0 && index < fFields.size()) { - return fFields.get(index).getName(); - } - return null; - } - - /** - * Get a field by index - * - * @param index - * The index of the field - * @return The field object at the requested index - */ - public ITmfEventField getField(int index) { - if (index >= 0 && index < fFields.size()) { - return fFields.get(index); - } - return null; - } - - /** - * Get a subfield value by name - * - * @param name - * a subfield name - * @return field value object - */ - public Object getFieldValue(String name) { - for (int i = 0; i < fFields.size(); i++) { - if (fFields.get(i).getName().equals(name)) { - return fFields.get(i).getValue(); - } - } - return null; - } - - /** - * Get a subfield value by index - * - * @param index - * a subfield index - * @return field value object - */ - public Object getFieldValue(int index) { - if (index >= 0 && index < fFields.size()) { - return fFields.get(index).getValue(); - } - return null; - } - - /** - * Set the content value - * - * @param value - * the content value - */ - public void setValue(Object value) { - fValue = value; - } - - /** - * Set a subfield value by name - * - * @param name - * a subfield name - * @param value - * the subfield value - */ - public void setFieldValue(String name, Object value) { - for (int i = 0; i < fFields.size(); i++) { - if (fFields.get(i).getName().equals(name)) { - fFields.get(i).fValue = value; - } - } - } - - /** - * Set a subfield value by index - * - * @param index - * a subfield index - * @param value - * the subfield value - */ - public void setFieldValue(int index, Object value) { - if (index >= 0 && index < fFields.size()) { - fFields.get(index).fValue = value; - } - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + fFields.hashCode(); - result = prime * result + fName.hashCode(); - int tmpHash = 0; // initialize for fValue equals null; - Object value = fValue; - if (value != null) { - if (value instanceof StringBuffer) { - tmpHash = value.toString().hashCode(); - } else { - tmpHash = value.hashCode(); - } - } - result = prime * result + tmpHash; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TextTraceEventContent other = (TextTraceEventContent) obj; - if (!fFields.equals(other.fFields)) { - return false; - } - if (!fName.equals(other.fName)) { - return false; - } - - Object value = fValue; - if (value == null) { - if (other.fValue != null) { - return false; - } - } else { - if ((value instanceof StringBuffer) && (other.fValue instanceof StringBuffer)) { - Object otherValue = other.getValue(); - if (otherValue == null) { - return false; - } - if (!value.toString().equals(otherValue.toString())) { - return false; - } - } else if (!value.equals(other.fValue)) { - return false; - } - } - return true; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - if (fName == ITmfEventField.ROOT_FIELD_ID) { - for (int i = 0; i < getFields().size(); i++) { - ITmfEventField field = getFields().get(i); - if (i != 0) { - sb.append(", "); //$NON-NLS-1$ - } - sb.append(field.toString()); - } - } else { - sb.append(fName); - sb.append('='); - sb.append(fValue); - } - return sb.toString(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/uml2sd/ITmfAsyncSequenceDiagramEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/uml2sd/ITmfAsyncSequenceDiagramEvent.java deleted file mode 100644 index 3201560e5e..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/uml2sd/ITmfAsyncSequenceDiagramEvent.java +++ /dev/null @@ -1,32 +0,0 @@ -/********************************************************************** - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ -package org.eclipse.linuxtools.tmf.core.uml2sd; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; - -/** - *

- * Interface for asynchronous sequence diagram events. - *

- * - * @version 1.0 - * @author Bernd Hufmann - */ -public interface ITmfAsyncSequenceDiagramEvent extends ITmfSyncSequenceDiagramEvent { - /** - * Returns end timestamp of message (i.e. receive time) - * - * @return end timestamp of message (i.e. receive time) - * @since 2.0 - */ - ITmfTimestamp getEndTime(); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/uml2sd/ITmfSyncSequenceDiagramEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/uml2sd/ITmfSyncSequenceDiagramEvent.java deleted file mode 100644 index bfcb520d50..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/uml2sd/ITmfSyncSequenceDiagramEvent.java +++ /dev/null @@ -1,54 +0,0 @@ -/********************************************************************** - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ -package org.eclipse.linuxtools.tmf.core.uml2sd; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; - -/** - *

- * Interface for synchronous sequence diagram events. - *

- * - * @version 1.0 - * @author Bernd Hufmann - */ -public interface ITmfSyncSequenceDiagramEvent { - - /** - * Returns Name of message. - * - * @return Name of message - */ - String getName(); - - /** - * Returns name of sender of message. - * - * @return name of sender of message - */ - String getSender(); - - /** - * Returns Name of receiver of message. - * - * @return Name of receiver of message - */ - String getReceiver(); - - /** - * Returns Start time of message (i.e. send time). - * - * @return Start timestamp of message (i.e. send time) - * @since 2.0 - */ - ITmfTimestamp getStartTime(); -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/uml2sd/TmfAsyncSequenceDiagramEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/uml2sd/TmfAsyncSequenceDiagramEvent.java deleted file mode 100644 index ad0e07e8fb..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/uml2sd/TmfAsyncSequenceDiagramEvent.java +++ /dev/null @@ -1,67 +0,0 @@ -/********************************************************************** - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ -package org.eclipse.linuxtools.tmf.core.uml2sd; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; - -/** - *

- * A basic implementation of ITmfAsyncSequenceDiagramEvent. - *

- * - * @version 1.0 - * @author Bernd Hufmann - */ -public class TmfAsyncSequenceDiagramEvent extends TmfSyncSequenceDiagramEvent implements ITmfAsyncSequenceDiagramEvent { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The end time of the sequence diagram event (i.e. time when signal was received). - */ - private final ITmfTimestamp fEndTime; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Constructor - * - * @param startEvent The start event (on sender side). - * @param endEvent The end event (receiver side). - * @param sender The name of sender of signal. - * @param receiver The Name of receiver of signal. - * @param name - The signal name - */ - public TmfAsyncSequenceDiagramEvent(ITmfEvent startEvent, ITmfEvent endEvent, String sender, String receiver, String name) { - super(startEvent, sender, receiver, name); - - if (endEvent == null) { - throw new IllegalArgumentException("TmfAsyncSequenceDiagramEvent constructor: endEvent=null"); //$NON-NLS-1$ - } - fEndTime = endEvent.getTimestamp(); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * @since 2.0 - */ - @Override - public ITmfTimestamp getEndTime() { - return fEndTime; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/uml2sd/TmfSyncSequenceDiagramEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/uml2sd/TmfSyncSequenceDiagramEvent.java deleted file mode 100644 index aff49d792f..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/uml2sd/TmfSyncSequenceDiagramEvent.java +++ /dev/null @@ -1,102 +0,0 @@ -/********************************************************************** - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ -package org.eclipse.linuxtools.tmf.core.uml2sd; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; - -/** - *

- * A basic implementation of ITmfSyncSequenceDiagramEvent. - *

- * - * @version 1.0 - * @author Bernd Hufmann - */ -public class TmfSyncSequenceDiagramEvent implements ITmfSyncSequenceDiagramEvent { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The start time of the sequence diagram event (i.e. time when signal was sent). - */ - private final ITmfTimestamp fStartTime; - /** - * The name of the sender of the signal. - */ - private final String fSender; - /** - * The name of the receiver of the signal. - */ - private final String fReceiver; - /** - * The name of the signal - */ - private final String fName; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Constructor - * - * @param startEvent The start event (on sender side). - * @param sender The name of sender of signal. - * @param receiver The Name of receiver of signal. - * @param name - The signal name - */ - public TmfSyncSequenceDiagramEvent(ITmfEvent startEvent, String sender, String receiver, String name) { - - if ((startEvent == null) || (sender == null) || (receiver == null) || (name == null)) { - throw new IllegalArgumentException("TmfSyncSequenceDiagramEvent constructor: " + //$NON-NLS-1$ - (startEvent == null ? ", startEvent=null" : "") + //$NON-NLS-1$ //$NON-NLS-2$ - (sender == null ? ", sender=null" : "") + //$NON-NLS-1$ //$NON-NLS-2$ - (receiver == null ? ", receiver=null" : "") + //$NON-NLS-1$ //$NON-NLS-2$ - (name == null ? ", name=null" : "")); //$NON-NLS-1$ //$NON-NLS-2$ - } - - fStartTime = startEvent.getTimestamp(); - - fSender = sender; - fReceiver = receiver; - - fName = name; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Override - public String getSender() { - return fSender; - } - - @Override - public String getReceiver() { - return fReceiver; - } - - @Override - public String getName() { - return fName; - } - - /** - * @since 2.0 - */ - @Override - public ITmfTimestamp getStartTime() { - return fStartTime; - } -} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/util/Pair.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/util/Pair.java deleted file mode 100644 index 6bde87908d..0000000000 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/linuxtools/tmf/core/util/Pair.java +++ /dev/null @@ -1,146 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Philippe Sawicki (INF4990.A2010@gmail.com) - Initial API and implementation - * Mathieu Denis (mathieu.denis55@gmail.com) - Refactored code - * Bernd Hufmann - Integrated to TMF, fixed hashCode() and equals() methods - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.core.util; - -/** - * Pair utility class, encapsulates a pair of objects. - * - * @param - * The type of the first object. - * @param - * The type of the second object. - * - * @author Philippe Sawicki - * @since 2.0 - */ -public class Pair { - - /** - * A reference to the first object. - */ - protected A fFirst; - /** - * A reference to the second object. - */ - protected B fSecond; - - /** - * Constructor. - * @param first - * The pair's first object. - * @param second - * The pair's second object. - */ - public Pair(A first, B second) { - fFirst = first; - fSecond = second; - } - - /** - * Constructor. - */ - public Pair() { - this(null, null); - } - - /** - * Pair hash code. - */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((fFirst == null) ? 0 : fFirst.hashCode()); - result = prime * result + ((fSecond == null) ? 0 : fSecond.hashCode()); - return result; - } - - /** - * Object comparison. - */ - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - - if (obj == null) { - return false; - } - - if (getClass() != obj.getClass()) { - return false; - } - - Pair other = (Pair) obj; - - if (fFirst == null) { - if (other.fFirst != null) { - return false; - } - } else if (!fFirst.equals(other.fFirst)) { - return false; - } - if (fSecond == null) { - if (other.fSecond != null) { - return false; - } - } else if (!fSecond.equals(other.fSecond)) { - return false; - } - return true; - } - - /** - * Object to string. - */ - @Override - public String toString() { - return "(" + fFirst + ", " + fSecond + ")"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ - } - - /** - * Returns a reference to the pair's first object. - * @return A reference to the pair's first object. - */ - public A getFirst() { - return fFirst; - } - - /** - * Sets the pair's first object. - * @param first - * The pair's first object. - */ - public void setFirst(A first) { - fFirst = first; - } - - /** - * Returns a reference to the pair's second object. - * @return A reference to the pair's second object. - */ - public B getSecond() { - return fSecond; - } - - /** - * Sets the pair's second object. - * @param second - * The pair's second object. - */ - public void setSecond(B second) { - fSecond = second; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/Activator.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/Activator.java new file mode 100644 index 0000000000..55444baf2f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/Activator.java @@ -0,0 +1,196 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Add signal manager disposal + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle. No more than one such + * plug-in can exist at any time. + *

+ * It also provides the plug-in's general logging facility and manages the + * internal tracer. + */ +public class Activator extends Plugin { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The plug-in ID + */ + public static final String PLUGIN_ID = "org.eclipse.tracecompass.tmf.core"; //$NON-NLS-1$ + + /** + * The shared instance + */ + private static Activator fPlugin; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructor + */ + public Activator() { + setDefault(this); + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * Returns the TMF Core plug-in instance. + * + * @return the TMF Core plug-in instance. + */ + public static Activator getDefault() { + return fPlugin; + } + + // Sets plug-in instance + private static void setDefault(Activator plugin) { + fPlugin = plugin; + } + + // ------------------------------------------------------------------------ + // Plugin + // ------------------------------------------------------------------------ + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + setDefault(this); + TmfCoreTracer.init(); + /* Initialize the trace manager */ + TmfTraceManager.getInstance(); + /* Initialize the analysis manager */ + TmfAnalysisManager.initialize(); + } + + @Override + public void stop(BundleContext context) throws Exception { + TmfCoreTracer.stop(); + TmfSignalManager.dispose(); + setDefault(null); + super.stop(context); + } + + + // ------------------------------------------------------------------------ + // Log an IStatus + // ------------------------------------------------------------------------ + + /** + * Log an IStatus object directly + * + * @param status + * The status to log + */ + public static void log(IStatus status) { + fPlugin.getLog().log(status); + } + + // ------------------------------------------------------------------------ + // Log INFO + // ------------------------------------------------------------------------ + + /** + * Logs a message with severity INFO in the runtime log of the plug-in. + * + * @param message + * A message to log + */ + public static void logInfo(String message) { + fPlugin.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity INFO in the runtime log of the + * plug-in. + * + * @param message + * A message to log + * @param exception + * The corresponding exception + */ + public static void logInfo(String message, Throwable exception) { + fPlugin.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message, exception)); + } + + // ------------------------------------------------------------------------ + // Log WARNING + // ------------------------------------------------------------------------ + + /** + * Logs a message and exception with severity WARNING in the runtime log of + * the plug-in. + * + * @param message + * A message to log + */ + public static void logWarning(String message) { + fPlugin.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity WARNING in the runtime log of + * the plug-in. + * + * @param message + * A message to log + * @param exception + * The corresponding exception + */ + public static void logWarning(String message, Throwable exception) { + fPlugin.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message, exception)); + } + + // ------------------------------------------------------------------------ + // Log ERROR + // ------------------------------------------------------------------------ + + /** + * Logs a message and exception with severity ERROR in the runtime log of + * the plug-in. + * + * @param message + * A message to log + */ + public static void logError(String message) { + fPlugin.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity ERROR in the runtime log of + * the plug-in. + * + * @param message + * A message to log + * @param exception + * The corresponding exception + */ + public static void logError(String message, Throwable exception) { + fPlugin.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, exception)); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/Messages.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/Messages.java new file mode 100644 index 0000000000..e4f9cd49ec --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/Messages.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core; + +import org.eclipse.osgi.util.NLS; + +/** + * TMF Core message bundle + * @since 2.0 + */ +@SuppressWarnings("javadoc") +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.tmf.core.messages"; //$NON-NLS-1$ + public static String TmfCheckpointIndexer_EventsPerSecond; + public static String TmfCheckpointIndexer_Indexing; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/TmfCorePreferenceInitializer.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/TmfCorePreferenceInitializer.java new file mode 100644 index 0000000000..dd08c2b67f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/TmfCorePreferenceInitializer.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core; + +import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimePreferences; + +/** + * Preference initializer for tmf.core + * + */ +public class TmfCorePreferenceInitializer extends AbstractPreferenceInitializer { + + @Override + public void initializeDefaultPreferences() { + TmfTimePreferences.init(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/TmfCoreTracer.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/TmfCoreTracer.java new file mode 100644 index 0000000000..92ff7ab396 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/TmfCoreTracer.java @@ -0,0 +1,239 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.tracecompass.tmf.core.component.ITmfComponent; +import org.eclipse.tracecompass.tmf.core.component.ITmfEventProvider; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignal; + +/** + * The TMF Core tracer, used to trace TMF internal components. + *

+ * The tracing classes are independently controlled (i.e no implicit inclusion) + * from the launch configuration's Tracing. The resulting trace is stored in a + * distinct file (TmfTrace.log) in a format that can later be analyzed by TMF. + *

+ * The tracing classes are: + *

    + *
  • Component: TMF components life-cycle + *
  • Request: TMF requests life-cycle + *
  • Signal: TMF signals triggering and distribution + *
  • Event: TMF trace events + *
+ * + * @version 1.0 + * @author Francois Chouinard + */ +@SuppressWarnings("nls") +public class TmfCoreTracer { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + private static final String PLUGIN_ID = Activator.PLUGIN_ID; + + // Tracing keys (in .options) + private static final String COMPONENT_TRACE_KEY = PLUGIN_ID + "/component"; + private static final String REQUEST_TRACE_KEY = PLUGIN_ID + "/request"; + private static final String SIGNAL_TRACE_KEY = PLUGIN_ID + "/signal"; + private static final String EVENT_TRACE_KEY = PLUGIN_ID + "/event"; + + private static final String TRACE_FILE_NAME = "TmfTrace.log"; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // Classes tracing flags + static boolean COMPONENT_CLASS_ENABLED = false; + static boolean REQUEST_CLASS_ENABLED = false; + static boolean SIGNAL_CLASS_ENABLED = false; + static boolean EVENT_CLASS_ENABLED = false; + + // Trace log file + private static BufferedWriter fTraceFile; + + // ------------------------------------------------------------------------ + // Start/stop tracing - controlled by the plug-in + // ------------------------------------------------------------------------ + + /** + * Set the tracing flags according to the launch configuration + */ + public static void init() { + + String traceKey; + boolean isTracing = false; + + traceKey = Platform.getDebugOption(COMPONENT_TRACE_KEY); + if (traceKey != null) { + COMPONENT_CLASS_ENABLED = (Boolean.valueOf(traceKey)).booleanValue(); + isTracing |= COMPONENT_CLASS_ENABLED; + } + + traceKey = Platform.getDebugOption(REQUEST_TRACE_KEY); + if (traceKey != null) { + REQUEST_CLASS_ENABLED = (Boolean.valueOf(traceKey)).booleanValue(); + isTracing |= REQUEST_CLASS_ENABLED; + } + + traceKey = Platform.getDebugOption(SIGNAL_TRACE_KEY); + if (traceKey != null) { + SIGNAL_CLASS_ENABLED = (Boolean.valueOf(traceKey)).booleanValue(); + isTracing |= SIGNAL_CLASS_ENABLED; + } + + traceKey = Platform.getDebugOption(EVENT_TRACE_KEY); + if (traceKey != null) { + EVENT_CLASS_ENABLED = (Boolean.valueOf(traceKey)).booleanValue(); + isTracing |= EVENT_CLASS_ENABLED; + } + + // Create trace log file if any of the flags was set + if (isTracing) { + try { + fTraceFile = new BufferedWriter(new FileWriter(TRACE_FILE_NAME)); + } catch (IOException e) { + Activator.logError("Error opening log file " + TRACE_FILE_NAME, e); + fTraceFile = null; + } + } + } + + /** + * Close the trace log file + */ + public static void stop() { + if (fTraceFile != null) { + try { + fTraceFile.close(); + fTraceFile = null; + } catch (IOException e) { + Activator.logError("Error closing log file", e); + } + } + } + + // ------------------------------------------------------------------------ + // Predicates + // ------------------------------------------------------------------------ + + @SuppressWarnings("javadoc") + public static boolean isComponentTraced() { + return COMPONENT_CLASS_ENABLED; + } + + @SuppressWarnings("javadoc") + public static boolean isRequestTraced() { + return REQUEST_CLASS_ENABLED; + } + + @SuppressWarnings("javadoc") + public static boolean isSignalTraced() { + return SIGNAL_CLASS_ENABLED; + } + + @SuppressWarnings("javadoc") + public static boolean isEventTraced() { + return EVENT_CLASS_ENABLED; + } + + // ------------------------------------------------------------------------ + // Tracing methods + // ------------------------------------------------------------------------ + + /** + * The central tracing method. Prepends the timestamp and the thread id + * to the trace message. + * + * @param msg the trace message to log + */ + public static synchronized void trace(String msg) { + // Leave when there is no place to write the message. + if (fTraceFile == null) { + return; + } + + // Set the timestamp (ms resolution) + long currentTime = System.currentTimeMillis(); + StringBuilder message = new StringBuilder("["); + message.append(currentTime / 1000); + message.append("."); + message.append(String.format("%1$03d", currentTime % 1000)); + message.append("] "); + + // Set the thread id + message.append("[TID="); + message.append(String.format("%1$03d", Thread.currentThread().getId())); + message.append("] "); + + // Append the trace message + message.append(msg); + + // Write to file + try { + fTraceFile.write(message.toString()); + fTraceFile.newLine(); + fTraceFile.flush(); + } catch (IOException e) { + Activator.logError("Error writing to log file", e); + } + } + + // ------------------------------------------------------------------------ + // TMF Core specific trace formatters + // ------------------------------------------------------------------------ + + @SuppressWarnings("javadoc") + public static void traceComponent(ITmfComponent component, String msg) { + if (COMPONENT_CLASS_ENABLED) { + String message = ("[CMP] Cmp=" + component.getName() + " " + msg); + trace(message); + } + } + + @SuppressWarnings("javadoc") + public static void traceRequest(ITmfEventRequest request, String msg) { + if (REQUEST_CLASS_ENABLED) { + String message = ("[REQ] Req=" + request.getRequestId() + " " + msg); + trace(message); + } + } + + @SuppressWarnings("javadoc") + public static void traceSignal(TmfSignal signal, String msg) { + if (SIGNAL_CLASS_ENABLED) { + String message = ("[SIG] Sig=" + signal.getClass().getSimpleName() + + " Target=" + msg); + trace(message); + } + } + + @SuppressWarnings("javadoc") + public static void traceEvent(ITmfEventProvider provider, ITmfEventRequest request, ITmfEvent event) { + if (EVENT_CLASS_ENABLED) { + String message = ("[EVT] Provider=" + provider.toString() + + ", Req=" + request.getRequestId() + ", Event=" + event.getTimestamp()); + trace(message); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/analysis/TmfAnalysisModuleSourceConfigElement.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/analysis/TmfAnalysisModuleSourceConfigElement.java new file mode 100644 index 0000000000..1978b6acf4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/analysis/TmfAnalysisModuleSourceConfigElement.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.analysis; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.Platform; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleSource; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisModuleHelperConfigElement; + +/** + * Utility class for accessing TMF analysis module extensions from the + * platform's extensions registry. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public final class TmfAnalysisModuleSourceConfigElement implements IAnalysisModuleSource { + + /** Extension point ID */ + public static final String TMF_ANALYSIS_TYPE_ID = "org.eclipse.linuxtools.tmf.core.analysis"; //$NON-NLS-1$ + + /** Extension point element 'module' */ + public static final String MODULE_ELEM = "module"; //$NON-NLS-1$ + + /** Extension point element 'parameter' */ + public static final String PARAMETER_ELEM = "parameter"; //$NON-NLS-1$ + + /** Extension point attribute 'ID' */ + public static final String ID_ATTR = "id"; //$NON-NLS-1$ + + /** Extension point attribute 'name' */ + public static final String NAME_ATTR = "name"; //$NON-NLS-1$ + + /** Extension point attribute 'analysis_module' */ + public static final String ANALYSIS_MODULE_ATTR = "analysis_module"; //$NON-NLS-1$ + + /** Extension point attribute 'automatic' */ + public static final String AUTOMATIC_ATTR = "automatic"; //$NON-NLS-1$ + + /** Extension point attribute 'icon' */ + public static final String ICON_ATTR = "icon"; //$NON-NLS-1$ + + /** Extension point attribute 'default_value' */ + public static final String DEFAULT_VALUE_ATTR = "default_value"; //$NON-NLS-1$ + + /** Extension point element 'tracetype' */ + public static final String TRACETYPE_ELEM = "tracetype"; //$NON-NLS-1$ + + /** Extension point attribute 'class' */ + public static final String CLASS_ATTR = "class"; //$NON-NLS-1$ + + /** Extension point attribute 'applies' */ + public static final String APPLIES_ATTR = "applies"; //$NON-NLS-1$ + + /** + * The mapping of available analysis ID to their corresponding helper + */ + private final List fAnalysisHelpers = new ArrayList<>(); + + /** + * Retrieves all configuration elements from the platform extension registry + * for the analysis module extension. + * + * @return an array of analysis module configuration elements + */ + public static IConfigurationElement[] getTypeElements() { + IConfigurationElement[] elements = + Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_ANALYSIS_TYPE_ID); + List typeElements = new LinkedList<>(); + for (IConfigurationElement element : elements) { + if (element.getName().equals(MODULE_ELEM)) { + typeElements.add(element); + } + } + return typeElements.toArray(new IConfigurationElement[typeElements.size()]); + } + + /** + * Constructor + */ + public TmfAnalysisModuleSourceConfigElement() { + populateAnalysisList(); + } + + @Override + public Iterable getAnalysisModules() { + return fAnalysisHelpers; + } + + private void populateAnalysisList() { + if (fAnalysisHelpers.isEmpty()) { + // Populate the analysis module list + IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_ANALYSIS_TYPE_ID); + for (IConfigurationElement ce : config) { + String elementName = ce.getName(); + if (elementName.equals(TmfAnalysisModuleSourceConfigElement.MODULE_ELEM)) { + fAnalysisHelpers.add(new TmfAnalysisModuleHelperConfigElement(ce)); + } + } + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/analysis/TmfAnalysisModuleSources.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/analysis/TmfAnalysisModuleSources.java new file mode 100644 index 0000000000..81868854e4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/analysis/TmfAnalysisModuleSources.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.analysis; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.InvalidRegistryObjectException; +import org.eclipse.core.runtime.Platform; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleSource; + +/** + * Utility class for accessing TMF analysis module extensions from the + * platform's extensions registry and returning the module sources. + * + * @author Geneviève Bastien + */ +public final class TmfAnalysisModuleSources { + + /** Extension point ID */ + public static final String TMF_ANALYSIS_TYPE_ID = "org.eclipse.linuxtools.tmf.core.analysis"; //$NON-NLS-1$ + + /** Extension point element 'module' */ + public static final String SOURCE_ELEM = "source"; //$NON-NLS-1$ + + /** Extension point attribute 'class' */ + public static final String CLASS_ATTR = "class"; //$NON-NLS-1$ + + private TmfAnalysisModuleSources() { + + } + + /** + * Return the analysis module sources advertised in the extension + * point, in iterable format. + * + * @return List of {@link IAnalysisModuleSource} + */ + public static Iterable getSources() { + List sources = new ArrayList<>(); + // Get the sources element from the extension point + IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_ANALYSIS_TYPE_ID); + for (IConfigurationElement ce : config) { + String elementName = ce.getName(); + if (elementName.equals(SOURCE_ELEM)) { + try { + IAnalysisModuleSource source = (IAnalysisModuleSource) ce.createExecutableExtension(CLASS_ATTR); + sources.add(source); + } catch (InvalidRegistryObjectException e) { + Activator.logError("Error creating module source", e); //$NON-NLS-1$ + } catch (CoreException e) { + Activator.logError("Error creating module source", e); //$NON-NLS-1$ + } + + } + } + return sources; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/component/TmfEventThread.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/component/TmfEventThread.java new file mode 100644 index 0000000000..923b00607d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/component/TmfEventThread.java @@ -0,0 +1,253 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Update handling of suspend and resume + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.component; + +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.internal.tmf.core.TmfCoreTracer; +import org.eclipse.tracecompass.tmf.core.component.ITmfEventProvider; +import org.eclipse.tracecompass.tmf.core.component.TmfEventProvider; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; + +/** + * Provides the core event request processor. It also has support for suspending + * and resuming a request in a thread-safe manner. + * + * @author Francois Chouinard + * @version 1.0 + */ +public class TmfEventThread implements Runnable { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The event provider + */ + private final TmfEventProvider fProvider; + + /** + * The wrapped event request + */ + private final ITmfEventRequest fRequest; + + /** + * The request execution priority + */ + private final ExecutionType fExecType; + + /** + * The wrapped thread (if applicable) + */ + private final TmfEventThread fThread; + + /** + * The thread execution state + */ + private volatile boolean isCompleted = false; + + /** The synchronization object */ + private final Object fSynchObject = new Object(); + + /** The flag for suspending a thread */ + private volatile boolean fIsPaused = false; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Basic constructor + * + * @param provider the event provider + * @param request the request to process + */ + public TmfEventThread(TmfEventProvider provider, ITmfEventRequest request) { + assert provider != null; + assert request != null; + fProvider = provider; + fRequest = request; + fExecType = request.getExecType(); + fThread = null; + } + + /** + * Wrapper constructor + * + * @param thread the thread to wrap + */ + public TmfEventThread(TmfEventThread thread) { + fProvider = thread.fProvider; + fRequest = thread.fRequest; + fExecType = thread.fExecType; + fThread = thread; + } + + // ------------------------------------------------------------------------ + // Getters + // ------------------------------------------------------------------------ + + /** + * @return The wrapped thread + */ + public TmfEventThread getThread() { + return fThread; + } + + /** + * @return The event provider + */ + public ITmfEventProvider getProvider() { + return fProvider; + } + + /** + * @return The event request + */ + public ITmfEventRequest getRequest() { + return fRequest; + } + + /** + * @return The request execution priority + */ + public ExecutionType getExecType() { + return fExecType; + } + + /** + * @return The request execution state + */ + public boolean isRunning() { + return fRequest.isRunning() && !isPaused(); + } + + /** + * @return The request execution state + */ + public boolean isPaused() { + return fIsPaused; + } + + /** + * @return The request execution state + */ + public boolean isCompleted() { + return isCompleted; + } + + // ------------------------------------------------------------------------ + // Runnable + // ------------------------------------------------------------------------ + + @Override + public void run() { + + TmfCoreTracer.traceRequest(fRequest, "is being serviced by " + fProvider.getName()); //$NON-NLS-1$ + + // Extract the generic information + fRequest.start(); + int nbRequested = fRequest.getNbRequested(); + int nbRead = 0; + isCompleted = false; + + // Initialize the execution + ITmfContext context = fProvider.armRequest(fRequest); + if (context == null) { + fRequest.cancel(); + return; + } + + try { + // Get the ordered events + ITmfEvent event = fProvider.getNext(context); + TmfCoreTracer.traceRequest(fRequest, "read first event"); //$NON-NLS-1$ + + while (event != null && !fProvider.isCompleted(fRequest, event, nbRead)) { + + TmfCoreTracer.traceEvent(fProvider, fRequest, event); + if (fRequest.getDataType().isInstance(event)) { + fRequest.handleData(event); + } + + // Pause execution if requested + + while (fIsPaused) { + synchronized (fSynchObject) { + try { + fSynchObject.wait(); + } catch (InterruptedException e) { + // continue + } + } + } + + // To avoid an unnecessary read passed the last event requested + if (++nbRead < nbRequested) { + event = fProvider.getNext(context); + } + } + + isCompleted = true; + + if (fRequest.isCancelled()) { + fRequest.cancel(); + } else { + fRequest.done(); + } + + } catch (Exception e) { + Activator.logError("Error in " + fProvider.getName() + " handling " + fRequest, e); //$NON-NLS-1$ //$NON-NLS-2$ + fRequest.fail(); + } + + // Cleanup + context.dispose(); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Suspend the thread + */ + public void suspend() { + fIsPaused = true; + TmfCoreTracer.traceRequest(fRequest, "SUSPENDED"); //$NON-NLS-1$ + } + + /** + * Resume the thread + */ + public void resume() { + fIsPaused = false; + synchronized (fSynchObject) { + fSynchObject.notifyAll(); + } + TmfCoreTracer.traceRequest(fRequest, "RESUMED"); //$NON-NLS-1$ + } + + /** + * Cancel the request + */ + public void cancel() { + if (!fRequest.isCompleted()) { + fRequest.cancel(); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/component/TmfProviderManager.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/component/TmfProviderManager.java new file mode 100644 index 0000000000..36f72edb93 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/component/TmfProviderManager.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.tracecompass.tmf.core.component.TmfEventProvider; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * Singleton that keeps track of the event providers. + * + * @version 1.0 + * @author Francois Chouinard + */ +public class TmfProviderManager { + + // ------------------------------------------------------------------------ + // No constructor + // ------------------------------------------------------------------------ + + private TmfProviderManager() { + } + + // ------------------------------------------------------------------------ + // Keeps track of the providers for each event type + // ------------------------------------------------------------------------ + + private static Map, List> fProviders = + new HashMap<>(); + + /** + * Registers [provider] as a provider of [eventType] + * + * @param eventType + * The event type + * @param provider + * The data provider + */ + public static void register(Class eventType, TmfEventProvider provider) { + if (fProviders.get(eventType) == null) { + fProviders.put(eventType, new ArrayList()); + } + fProviders.get(eventType).add(provider); + } + + /** + * Re-registers [provider] as a provider of [eventType] + * + * @param eventType + * The event type + * @param provider + * The data provider + */ + public static void deregister(Class eventType, TmfEventProvider provider) { + List list = fProviders.get(eventType); + if (list != null) { + list.remove(provider); + if (list.size() == 0) { + fProviders.remove(eventType); + } + } + } + + /** + * Returns the list of components that provide [eventType] + * + * @param eventType + * The event type + * @return the list of components that provide [eventType] + */ + public static TmfEventProvider[] getProviders(Class eventType) { + List list = fProviders.get(eventType); + if (list == null) { + list = new ArrayList<>(); + } + TmfEventProvider[] result = new TmfEventProvider[list.size()]; + return list.toArray(result); + } + + /** + * Returns the list of components of type [providerType] that provide + * [eventType] + * + * @param eventType + * The event type + * @param providerType + * The data provider + * @return the list of components of type [providerType] that provide + * [eventType] + */ + public static TmfEventProvider[] getProviders(Class eventType, Class providerType) { + if (providerType == null) { + return getProviders(eventType); + } + TmfEventProvider[] list = getProviders(eventType); + List result = new ArrayList<>(); + if (list != null) { + for (TmfEventProvider provider : list) { + if (provider.getClass() == providerType) { + result.add(provider); + } + } + } + TmfEventProvider[] array = new TmfEventProvider[result.size()]; + return result.toArray(array); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/filter/TmfCollapseFilter.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/filter/TmfCollapseFilter.java new file mode 100644 index 0000000000..f6870ee349 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/filter/TmfCollapseFilter.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.internal.tmf.core.filter; + +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.collapse.ITmfCollapsibleEvent; +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; + +/** + * Stateful filter that compares consecutive events for collapsing feature. + * + * Usage of this class in conjunction with other {@link ITmfFilterTreeNode} + * filters is not supported. Will throw {@link UnsupportedOperationException} + * in that case. + * + * @author Bernd Hufmann + */ +public class TmfCollapseFilter implements ITmfFilterTreeNode { + + private static final String COLLAPSE_NODE_NAME = "Collapse"; //$NON-NLS-1$ + + private ITmfCollapsibleEvent fPrevEvent = null; + + @Override + public boolean matches(ITmfEvent event) { + + if (fPrevEvent != null) { + if (event instanceof ITmfCollapsibleEvent) { + boolean isCollapsible = fPrevEvent.isCollapsibleWith(event); + fPrevEvent = (ITmfCollapsibleEvent) event; + if (isCollapsible) { + return false; + } + } else { + fPrevEvent = null; + } + } else { + if (event instanceof ITmfCollapsibleEvent) { + fPrevEvent = (ITmfCollapsibleEvent) event; + } + } + return true; + } + + @Override + public ITmfFilterTreeNode getParent() { + return null; + } + + @Override + public String getNodeName() { + return COLLAPSE_NODE_NAME; + } + + @Override + public boolean hasChildren() { + return false; + } + + @Override + public int getChildrenCount() { + return 0; + } + + @Override + public ITmfFilterTreeNode[] getChildren() { + return new ITmfFilterTreeNode[0]; + } + + @Override + public ITmfFilterTreeNode getChild(int index) { + throw new UnsupportedOperationException(); + } + + @Override + public ITmfFilterTreeNode remove() { + throw new UnsupportedOperationException(); + } + + @Override + public ITmfFilterTreeNode removeChild(ITmfFilterTreeNode node) { + throw new UnsupportedOperationException(); + } + + @Override + public int addChild(ITmfFilterTreeNode node) { + throw new UnsupportedOperationException(); + } + + @Override + public ITmfFilterTreeNode replaceChild(int index, ITmfFilterTreeNode node) { + throw new UnsupportedOperationException(); + } + + @Override + public void setParent(ITmfFilterTreeNode parent) { + } + + @Override + public List getValidChildren() { + throw new UnsupportedOperationException(); + } + + @Override + public ITmfFilterTreeNode clone() { + return new TmfCollapseFilter(); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/messages.properties b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/messages.properties new file mode 100644 index 0000000000..ef096a387b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/messages.properties @@ -0,0 +1,14 @@ +############################################################################### +# Copyright (c) 2013 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### + +TmfCheckpointIndexer_EventsPerSecond=events/s +TmfCheckpointIndexer_Indexing=Indexing diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/request/TmfCoalescedEventRequest.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/request/TmfCoalescedEventRequest.java new file mode 100644 index 0000000000..958cd56dfa --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/request/TmfCoalescedEventRequest.java @@ -0,0 +1,321 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Alexandre Montplaisir - Merge with TmfCoalescedDataRequest + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.request; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.tracecompass.internal.tmf.core.TmfCoreTracer; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; + +/** + * The TMF coalesced event request + * + * @author Francois Chouinard + * @since 3.0 + */ +public class TmfCoalescedEventRequest extends TmfEventRequest { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** The list of coalesced requests */ + private final List fRequests = new ArrayList<>(); + + /** + * We do not use super.fRange, because in the case of coalesced requests, + * the global range can be modified as sub-request are added. + */ + private TmfTimeRange fRange; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Request 'n' events of a given type for the given time range (given + * priority). Events are returned in blocks of the given size. + * + * @param dataType + * The requested data type + * @param range + * The range of the request. You can use + * {@link TmfTimeRange#ETERNITY} to request all events. + * @param index + * The index of the first event to retrieve. Use '0' to start at + * the beginning. + * @param nbRequested + * The number of events requested. You can use + * {@link TmfEventRequest#ALL_DATA} to request all events. + * @param priority + * The requested execution priority + */ + public TmfCoalescedEventRequest(Class dataType, + TmfTimeRange range, + long index, + int nbRequested, + ExecutionType priority) { + super(ITmfEvent.class, null, index, nbRequested, priority); + fRange = range; + + if (TmfCoreTracer.isRequestTraced()) { + String type = getClass().getName(); + type = type.substring(type.lastIndexOf('.') + 1); + @SuppressWarnings("nls") + String message = "CREATED " + + (getExecType() == ITmfEventRequest.ExecutionType.BACKGROUND ? "(BG)" : "(FG)") + + " Type=" + type + " Index=" + getIndex() + " NbReq=" + getNbRequested() + + " Range=" + getRange() + + " DataType=" + getDataType().getSimpleName(); + TmfCoreTracer.traceRequest(this, message); + } + } + + @Override + public TmfTimeRange getRange() { + return fRange; + } + + // ------------------------------------------------------------------------ + // Management + // ------------------------------------------------------------------------ + + /** + * Add a request to this one. + * + * @param request + * The request to add + */ + public void addRequest(ITmfEventRequest request) { + fRequests.add(request); + merge(request); + } + + /** + * Check if a request is compatible with the current coalesced one + * + * @param request + * The request to verify + * @return If the request is compatible, true or false + */ + public boolean isCompatible(ITmfEventRequest request) { + if (request.getExecType() == getExecType() && + ranksOverlap(request) && + timeRangesOverlap(request)) { + return true; + } + return false; + } + + private boolean ranksOverlap(ITmfEventRequest request) { + long start = request.getIndex(); + long end = start + request.getNbRequested(); + + // Return true if either the start or end index falls within + // the coalesced request boundaries + return (start <= (fIndex + fNbRequested + 1) && (end >= fIndex - 1)); + } + + private boolean timeRangesOverlap(ITmfEventRequest request) { + ITmfTimestamp startTime = request.getRange().getStartTime(); + ITmfTimestamp endTime = request.getRange().getEndTime(); + return (startTime.compareTo(endTime) <= 0) && + (fRange.getStartTime().compareTo(fRange.getEndTime()) <= 0); + } + + private void merge(ITmfEventRequest request) { + long start = request.getIndex(); + long end = Math.min(start + request.getNbRequested(), ITmfEventRequest.ALL_DATA); + + if (start < fIndex) { + if (fNbRequested != ITmfEventRequest.ALL_DATA) { + fNbRequested += (fIndex - start); + } + fIndex = start; + } + if ((request.getNbRequested() == ITmfEventRequest.ALL_DATA) || + (fNbRequested == ITmfEventRequest.ALL_DATA)) { + fNbRequested = ITmfEventRequest.ALL_DATA; + } else { + fNbRequested = (int) Math.max(end - fIndex, fNbRequested); + } + + ITmfTimestamp startTime = request.getRange().getStartTime(); + ITmfTimestamp endTime = request.getRange().getEndTime(); + if (!fRange.contains(startTime) && fRange.getStartTime().compareTo(startTime) > 0) { + fRange = new TmfTimeRange(startTime, fRange.getEndTime()); + } + if (!fRange.contains(endTime) && fRange.getEndTime().compareTo(endTime) < 0) { + fRange = new TmfTimeRange(fRange.getStartTime(), endTime); + } + } + + /** + * @return The list of IDs of the sub-requests + */ + @SuppressWarnings("nls") + public String getSubRequestIds() { + StringBuffer result = new StringBuffer("["); + for (int i = 0; i < fRequests.size(); i++) { + if (i != 0) { + result.append(", "); + } + result.append(fRequests.get(i).getRequestId()); + } + result.append("]"); + return result.toString(); + } + + // ------------------------------------------------------------------------ + // ITmfEventRequest + // ------------------------------------------------------------------------ + + @Override + public void handleData(ITmfEvent data) { + super.handleData(data); + long index = getIndex() + getNbRead() - 1; + for (ITmfEventRequest request : fRequests) { + long start = request.getIndex(); + if (!request.isCompleted() && index >= start && request.getNbRead() < request.getNbRequested()) { + ITmfTimestamp ts = data.getTimestamp(); + if (request.getRange().contains(ts)) { + if (request.getDataType().isInstance(data)) { + request.handleData(data); + } + } + } + } + } + + @Override + public void start() { + for (ITmfEventRequest request : fRequests) { + if (!request.isCompleted()) { + request.start(); + } + } + super.start(); + } + + @Override + public void done() { + for (ITmfEventRequest request : fRequests) { + if (!request.isCompleted()) { + request.done(); + } + } + super.done(); + } + + @Override + public void fail() { + for (ITmfEventRequest request : fRequests) { + request.fail(); + } + super.fail(); + } + + @Override + public void cancel() { + for (ITmfEventRequest request : fRequests) { + if (!request.isCompleted()) { + request.cancel(); + } + } + super.cancel(); + } + + @Override + public synchronized boolean isCompleted() { + // Firstly, check if coalescing request is completed + if (super.isCompleted()) { + return true; + } + + // Secondly, check if all sub-requests are finished + if (fRequests.size() > 0) { + // If all sub requests are completed the coalesced request is + // treated as completed, too. + for (ITmfEventRequest request : fRequests) { + if (!request.isCompleted()) { + return false; + } + } + return true; + } + + // Coalescing request is not finished if there are no sub-requests + return false; + } + + @Override + public synchronized boolean isCancelled() { + // Firstly, check if coalescing request is canceled + if (super.isCancelled()) { + return true; + } + + // Secondly, check if all sub-requests are canceled + if (fRequests.size() > 0) { + // If all sub requests are canceled the coalesced request is + // treated as completed, too. + for (ITmfEventRequest request : fRequests) { + if (!request.isCancelled()) { + return false; + } + } + return true; + } + + // Coalescing request is not canceled if there are no sub-requests + return false; + + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + // All requests have a unique id + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object other) { + if (other instanceof TmfCoalescedEventRequest) { + TmfCoalescedEventRequest request = (TmfCoalescedEventRequest) other; + return (request.getDataType() == getDataType()) && + (request.getIndex() == getIndex()) && + (request.getNbRequested() == getNbRequested()) && + (request.getRange().equals(fRange)); + } + return false; + } + + @Override + @SuppressWarnings("nls") + public String toString() { + return "[TmfCoalescedEventRequest(" + getRequestId() + "," + getDataType().getSimpleName() + + "," + getExecType() + "," + getRange() + "," + getIndex() + "," + getNbRequested() + + ", " + fRequests.toString() + ")]"; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/request/TmfRequestExecutor.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/request/TmfRequestExecutor.java new file mode 100644 index 0000000000..cba3cae696 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/request/TmfRequestExecutor.java @@ -0,0 +1,308 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Added support for pre-emption + * Simon Delisle - Added scheduler for requests + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.request; + +import java.util.Queue; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import org.eclipse.tracecompass.internal.tmf.core.TmfCoreTracer; +import org.eclipse.tracecompass.internal.tmf.core.component.TmfEventThread; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType; + +/** + * The request scheduler works with 5 slots with a specific time. It has 4 slots + * for foreground requests and 1 slot for background requests, and it passes + * through all the slots (foreground first and background after). + * + * Example: if we have one foreground and one background request, the foreground + * request will be executed four times more often than the background request. + * + * @author Francois Chouinard + * @author Simon Delisle + * @version 1.1 + */ +public class TmfRequestExecutor implements Executor { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + private static final long REQUEST_TIME = 100; + private static final int FOREGROUND_SLOT = 4; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // The request executor + private final ExecutorService fExecutor = Executors.newCachedThreadPool(); + private final String fExecutorName; + + // The request queues + private final Queue fForegroundTasks = new ArrayBlockingQueue<>(10); + private final Queue fBackgroundTasks = new ArrayBlockingQueue<>(10); + + // The tasks + private TmfEventThread fActiveTask; + + private Timer fTimer; + private TimerTask fTimerTask; + + private int fForegroundCycle = 0; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + public TmfRequestExecutor() { + String canonicalName = fExecutor.getClass().getCanonicalName(); + fExecutorName = canonicalName.substring(canonicalName.lastIndexOf('.') + 1); + if (TmfCoreTracer.isComponentTraced()) { + TmfCoreTracer.trace(fExecutor + " created"); //$NON-NLS-1$ + } + } + + // ------------------------------------------------------------------------ + // Getters + // ------------------------------------------------------------------------ + + /** + * @return the shutdown state (i.e. if it is accepting new requests) + */ + public boolean isShutdown() { + return fExecutor.isShutdown(); + } + + /** + * @return the termination state + */ + public boolean isTerminated() { + return fExecutor.isTerminated(); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Initialize the executor + */ + public void init() { + if (fTimer != null) { + return; + } + // Initialize the timer for the schedSwitch + fTimerTask = new SchedSwitch(); + fTimer = new Timer(true); + fTimer.schedule(fTimerTask, 0, REQUEST_TIME); + } + + @Override + public synchronized void execute(final Runnable command) { + + // We are expecting MyEventThread:s + if (!(command instanceof TmfEventThread)) { + // TODO: Log an error + return; + } + + // Wrap the thread in a MyThread + TmfEventThread thread = (TmfEventThread) command; + TmfEventThread wrapper = new TmfEventThread(thread) { + @Override + public void run() { + try { + command.run(); + } finally { + scheduleNext(); + } + } + }; + + // Add the thread to the appropriate queue + ExecutionType priority = thread.getExecType(); + + if (priority == ExecutionType.FOREGROUND) { + if (!fForegroundTasks.offer(wrapper)) { + wrapper.cancel(); + } + } else { + if (!fBackgroundTasks.offer(wrapper)) { + wrapper.cancel(); + } + } + } + + /** + * Timer task to trigger scheduleNext() + */ + private class SchedSwitch extends TimerTask { + + SchedSwitch() { + } + + @Override + public void run() { + scheduleNext(); + } + } + + /** + * Executes the next pending request, if applicable. + */ + protected synchronized void scheduleNext() { + if (!isShutdown()) { + if (fActiveTask == null) { + schedule(); + } else if (fActiveTask.getExecType() == ExecutionType.FOREGROUND) { + if (fActiveTask.getThread().isCompleted()) { + fActiveTask = null; + schedule(); + } else { + if (hasTasks()) { + fActiveTask.getThread().suspend(); + if (!fForegroundTasks.offer(fActiveTask)) { + fActiveTask.cancel(); + fActiveTask = null; + } + schedule(); + } + } + + } else if (fActiveTask.getExecType() == ExecutionType.BACKGROUND) { + if (fActiveTask.getThread().isCompleted()) { + fActiveTask = null; + schedule(); + } else { + if (hasTasks()) { + fActiveTask.getThread().suspend(); + if (!fBackgroundTasks.offer(fActiveTask)) { + fActiveTask.cancel(); + fActiveTask = null; + } + schedule(); + } + } + } + } + } + + /** + * Stops the executor + */ + public synchronized void stop() { + if (fTimerTask != null) { + fTimerTask.cancel(); + } + + if (fTimer != null) { + fTimer.cancel(); + } + + if (fActiveTask != null) { + fActiveTask.cancel(); + } + + while ((fActiveTask = fForegroundTasks.poll()) != null) { + fActiveTask.cancel(); + } + while ((fActiveTask = fBackgroundTasks.poll()) != null) { + fActiveTask.cancel(); + } + + fExecutor.shutdown(); + if (TmfCoreTracer.isComponentTraced()) { + TmfCoreTracer.trace(fExecutor + " terminated"); //$NON-NLS-1$ + } + } + + // ------------------------------------------------------------------------ + // Helper methods + // ------------------------------------------------------------------------ + + /** + * Determine which type of request (foreground or background) we schedule + * next + */ + private void schedule() { + if (!fForegroundTasks.isEmpty()) { + scheduleNextForeground(); + } else { + scheduleNextBackground(); + } + } + + /** + * Schedule the next foreground request + */ + private void scheduleNextForeground() { + if (fForegroundCycle < FOREGROUND_SLOT || fBackgroundTasks.isEmpty()) { + ++fForegroundCycle; + fActiveTask = fForegroundTasks.poll(); + executefActiveTask(); + } else { + fActiveTask = null; + scheduleNextBackground(); + } + } + + /** + * Schedule the next background request + */ + private void scheduleNextBackground() { + fForegroundCycle = 0; + if (!fBackgroundTasks.isEmpty()) { + fActiveTask = fBackgroundTasks.poll(); + executefActiveTask(); + } + } + + /** + * Execute or resume the active task + */ + private void executefActiveTask() { + if (fActiveTask.getThread().isPaused()) { + fActiveTask.getThread().resume(); + } else { + fExecutor.execute(fActiveTask); + } + } + + /** + * Check if the scheduler has tasks + */ + private boolean hasTasks() { + return !(fForegroundTasks.isEmpty() && fBackgroundTasks.isEmpty()); + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + @SuppressWarnings("nls") + public String toString() { + return "[TmfRequestExecutor(" + fExecutorName + ")]"; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/backends/partial/PartialHistoryBackend.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/backends/partial/PartialHistoryBackend.java new file mode 100644 index 0000000000..48d3cd0dad --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/backends/partial/PartialHistoryBackend.java @@ -0,0 +1,365 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.statesystem.backends.partial; + +import java.io.File; +import java.io.FileInputStream; +import java.io.PrintWriter; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.concurrent.CountDownLatch; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.backend.IStateHistoryBackend; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; +import org.eclipse.linuxtools.statesystem.core.interval.TmfStateInterval; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Partial state history back-end. + * + * This is a shim inserted between the real state system and a "real" history + * back-end. It will keep checkpoints, every n trace events (where n is called + * the granularity) and will only forward to the real state history the state + * intervals that crosses at least one checkpoint. Every other interval will + * be discarded. + * + * This would mean that it can only answer queries exactly at the checkpoints. + * For any other timestamps (ie, most of the time), it will load the closest + * earlier checkpoint, and will re-feed the state-change-input with events from + * the trace, to restore the real state at the time that was requested. + * + * @author Alexandre Montplaisir + */ +public class PartialHistoryBackend implements IStateHistoryBackend { + + /** + * A partial history needs the state input plugin to re-generate state + * between checkpoints. + */ + private final @NonNull ITmfStateProvider partialInput; + + /** + * Fake state system that is used for partially rebuilding the states (when + * going from a checkpoint to a target query timestamp). + */ + private final @NonNull PartialStateSystem partialSS; + + /** Reference to the "real" state history that is used for storage */ + private final @NonNull IStateHistoryBackend innerHistory; + + /** Checkpoints map, */ + private final @NonNull TreeMap checkpoints = new TreeMap<>(); + + /** Latch tracking if the initial checkpoint registration is done */ + private final @NonNull CountDownLatch checkpointsReady = new CountDownLatch(1); + + private final long granularity; + + private long latestTime; + + /** + * Constructor + * + * @param partialInput + * The state change input object that was used to build the + * upstream state system. This partial history will make its own + * copy (since they have different targets). + * @param pss + * The partial history's inner state system. It should already be + * assigned to partialInput. + * @param realBackend + * The real state history back-end to use. It's supposed to be + * modular, so it should be able to be of any type. + * @param granularity + * Configuration parameter indicating how many trace events there + * should be between each checkpoint + */ + public PartialHistoryBackend(ITmfStateProvider partialInput, PartialStateSystem pss, + IStateHistoryBackend realBackend, long granularity) { + if (granularity <= 0 || partialInput == null || pss == null || + partialInput.getAssignedStateSystem() != pss) { + throw new IllegalArgumentException(); + } + + final long startTime = realBackend.getStartTime(); + + this.partialInput = partialInput; + this.partialSS = pss; + + this.innerHistory = realBackend; + this.granularity = granularity; + + latestTime = startTime; + + registerCheckpoints(); + } + + private void registerCheckpoints() { + ITmfEventRequest request = new CheckpointsRequest(partialInput, checkpoints); + partialInput.getTrace().sendRequest(request); + /* The request will countDown the checkpoints latch once it's finished */ + } + + @Override + public long getStartTime() { + return innerHistory.getStartTime(); + } + + @Override + public long getEndTime() { + return latestTime; + } + + @Override + public void insertPastState(long stateStartTime, long stateEndTime, + int quark, ITmfStateValue value) throws TimeRangeException { + waitForCheckpoints(); + + /* Update the latest time */ + if (stateEndTime > latestTime) { + latestTime = stateEndTime; + } + + /* + * Check if the interval intersects the previous checkpoint. If so, + * insert it in the real history back-end. + * + * FIXME since intervals are inserted in order of rank, we could avoid + * doing a map lookup every time here (just compare with the known + * previous one). + */ + if (stateStartTime <= checkpoints.floorKey(stateEndTime)) { + innerHistory.insertPastState(stateStartTime, stateEndTime, quark, value); + } + } + + @Override + public void finishedBuilding(long endTime) throws TimeRangeException { + innerHistory.finishedBuilding(endTime); + } + + @Override + public FileInputStream supplyAttributeTreeReader() { + return innerHistory.supplyAttributeTreeReader(); + } + + @Override + public File supplyAttributeTreeWriterFile() { + return innerHistory.supplyAttributeTreeWriterFile(); + } + + @Override + public long supplyAttributeTreeWriterFilePosition() { + return innerHistory.supplyAttributeTreeWriterFilePosition(); + } + + @Override + public void removeFiles() { + innerHistory.removeFiles(); + } + + @Override + public void dispose() { + partialInput.dispose(); + partialSS.dispose(); + innerHistory.dispose(); + } + + @Override + public void doQuery(List currentStateInfo, long t) + throws TimeRangeException, StateSystemDisposedException { + /* Wait for required steps to be done */ + waitForCheckpoints(); + partialSS.getUpstreamSS().waitUntilBuilt(); + + if (!checkValidTime(t)) { + throw new TimeRangeException(); + } + + /* Reload the previous checkpoint */ + long checkpointTime = checkpoints.floorKey(t); + innerHistory.doQuery(currentStateInfo, checkpointTime); + + /* + * Set the initial contents of the partial state system (which is the + * contents of the query at the checkpoint). + */ + partialSS.takeQueryLock(); + partialSS.replaceOngoingState(currentStateInfo); + + /* Send an event request to update the state system to the target time. */ + TmfTimeRange range = new TmfTimeRange( + /* + * The state at the checkpoint already includes any state change + * caused by the event(s) happening exactly at 'checkpointTime', + * if any. We must not include those events in the query. + */ + new TmfTimestamp(checkpointTime + 1, ITmfTimestamp.NANOSECOND_SCALE), + new TmfTimestamp(t, ITmfTimestamp.NANOSECOND_SCALE)); + ITmfEventRequest request = new PartialStateSystemRequest(partialInput, range); + partialInput.getTrace().sendRequest(request); + + try { + request.waitForCompletion(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + /* + * Now the partial state system should have the ongoing time we are + * looking for. However, the method expects a List of *state intervals*, + * not state values, so we'll create intervals with a dummy end time. + */ + try { + for (int i = 0; i < currentStateInfo.size(); i++) { + long start = 0; + ITmfStateValue val = null; + start = ((ITmfStateSystem) partialSS).getOngoingStartTime(i); + val = ((ITmfStateSystem) partialSS).queryOngoingState(i); + + ITmfStateInterval interval = new TmfStateInterval(start, t, i, val); + currentStateInfo.set(i, interval); + } + } catch (AttributeNotFoundException e) { + /* Should not happen, we iterate over existing values. */ + e.printStackTrace(); + } + + partialSS.releaseQueryLock(); + } + + /** + * Single queries are not supported in partial histories. To get the same + * result you can do a full query, then call fullState.get(attribute). + */ + @Override + public ITmfStateInterval doSingularQuery(long t, int attributeQuark) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean checkValidTime(long t) { + return (t >= getStartTime() && t <= getEndTime()); + } + + @Override + public void debugPrint(PrintWriter writer) { + // TODO Auto-generated method stub + } + + private void waitForCheckpoints() { + try { + checkpointsReady.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + // ------------------------------------------------------------------------ + // Event requests types + // ------------------------------------------------------------------------ + + private class CheckpointsRequest extends TmfEventRequest { + private final ITmfTrace trace; + private final Map checkpts; + private long eventCount; + private long lastCheckpointAt; + + public CheckpointsRequest(ITmfStateProvider input, Map checkpoints) { + super(input.getExpectedEventType(), + TmfTimeRange.ETERNITY, + 0, + ITmfEventRequest.ALL_DATA, + ITmfEventRequest.ExecutionType.FOREGROUND); + checkpoints.clear(); + this.trace = input.getTrace(); + this.checkpts = checkpoints; + eventCount = 0; + lastCheckpointAt = 0; + + /* Insert a checkpoint at the start of the trace */ + checkpoints.put(input.getStartTime(), 0L); + } + + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + if (event.getTrace() == trace) { + eventCount++; + + /* Check if we need to register a new checkpoint */ + if (eventCount >= lastCheckpointAt + granularity) { + checkpts.put(event.getTimestamp().getValue(), eventCount); + lastCheckpointAt = eventCount; + } + } + } + + @Override + public void handleCompleted() { + super.handleCompleted(); + checkpointsReady.countDown(); + } + } + + private class PartialStateSystemRequest extends TmfEventRequest { + private final ITmfStateProvider sci; + private final ITmfTrace trace; + + PartialStateSystemRequest(ITmfStateProvider sci, TmfTimeRange range) { + super(sci.getExpectedEventType(), + range, + 0, + ITmfEventRequest.ALL_DATA, + ITmfEventRequest.ExecutionType.BACKGROUND); + this.sci = sci; + this.trace = sci.getTrace(); + } + + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + if (event.getTrace() == trace) { + sci.processEvent(event); + } + } + + @Override + public void handleCompleted() { + /* + * If we're using a threaded state provider, we need to make sure + * all events have been handled by the state system before doing + * queries on it. + */ + if (partialInput instanceof AbstractTmfStateProvider) { + ((AbstractTmfStateProvider) partialInput).waitForEmptyQueue(); + } + super.handleCompleted(); + } + + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/backends/partial/PartialStateSystem.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/backends/partial/PartialStateSystem.java new file mode 100644 index 0000000000..9760464940 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/backends/partial/PartialStateSystem.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.statesystem.backends.partial; + +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.eclipse.linuxtools.internal.statesystem.core.AttributeTree; +import org.eclipse.linuxtools.internal.statesystem.core.StateSystem; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.backend.NullBackend; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; + +/** + * State system interface-like extension to use with partial state histories. + * + * It mainly exposes the {@link #replaceOngoingState} method, which allows + * seeking the state system to a different point by updating its "ongoing" state + * values. + * + * @author Alexandre Montplaisir + */ +@SuppressWarnings("restriction") /* We're using AttributeTree directly */ +public class PartialStateSystem extends StateSystem { + + private static final String ERR_MSG = "Partial state system should not modify the attribute tree!"; //$NON-NLS-1$ + + private final CountDownLatch ssAssignedLatch = new CountDownLatch(1); + private final Lock queryLock = new ReentrantLock(); + + /** + * Reference to the real upstream state system. This is used so we can read + * its attribute tree. + */ + private StateSystem realStateSystem = null; + + /** + * Constructor + */ + public PartialStateSystem() { + /* + * We use a Null back end here : we only use this state system for its + * "ongoing" values, so no need to save the changes that are inserted. + */ + super("partial", new NullBackend()); //$NON-NLS-1$ + } + + /** + * Assign the upstream state system to this one. + * + * @param ss + * The real state system + */ + public void assignUpstream(StateSystem ss) { + realStateSystem = ss; + ssAssignedLatch.countDown(); + } + + ITmfStateSystem getUpstreamSS() { + return realStateSystem; + } + + // ------------------------------------------------------------------------ + // Publicized non-API methods + // ------------------------------------------------------------------------ + + @Override + public void replaceOngoingState(List ongoingIntervals) { + super.replaceOngoingState(ongoingIntervals); + } + + @Override + public synchronized void dispose() { + super.dispose(); + } + + // ------------------------------------------------------------------------ + // Methods regarding the query lock + // ------------------------------------------------------------------------ + + /** + * Take this inner state system's lock before doing a query. + * + * When doing queries, you should take the lock, then run + * {@link #replaceOngoingState}, then send events to its state provider + * input to cause state changes, and then call {@link #queryOngoingState} to + * get the states at the new "current time". + * + * Only after all that it would be safe to release the lock. + */ + public void takeQueryLock() { + try { + queryLock.lockInterruptibly(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * Release the query lock, when you are done with your query. + */ + public void releaseQueryLock() { + queryLock.unlock(); + } + + @Override + public AttributeTree getAttributeTree() { + waitUntilReady(); + return realStateSystem.getAttributeTree(); + } + + /* + * Override these methods to make sure we don't try to overwrite the + * "real" upstream attribute tree. + */ + + @Override + public void addEmptyAttribute() { + throw new RuntimeException(ERR_MSG); + } + + @Override + public int getQuarkAbsoluteAndAdd(String... attribute) { + waitUntilReady(); + try { + return realStateSystem.getQuarkAbsolute(attribute); + } catch (AttributeNotFoundException e) { + throw new RuntimeException(ERR_MSG); + } + } + + @Override + public int getQuarkRelativeAndAdd(int startingNodeQuark, String... subPath) { + waitUntilReady(); + try { + return realStateSystem.getQuarkRelative(startingNodeQuark, subPath); + } catch (AttributeNotFoundException e) { + throw new RuntimeException(ERR_MSG); + } + } + + private void waitUntilReady() { + try { + ssAssignedLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/AbstractTmfMipmapStateProvider.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/AbstractTmfMipmapStateProvider.java new file mode 100644 index 0000000000..881f528ec9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/AbstractTmfMipmapStateProvider.java @@ -0,0 +1,199 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jean-Christian Kouamé - Initial API and implementation + * Patrick Tasse - Updates to mipmap feature + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.statesystem.mipmap; + +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * This is an abstract state provider that allows attributes to be mipmapped + * for one or more of the supported mipmap features (min, max, average). + * + * Extend this class for a specific implementation + */ +public abstract class AbstractTmfMipmapStateProvider extends AbstractTmfStateProvider { + + /** + * Feature bit for the maximum mipmap feature (value is 1<<1). + */ + public static final int MAX = 1 << 1; + + /** + * Feature bit for the minimum mipmap feature (value is 1<<2). + */ + public static final int MIN = 1 << 2; + + /** + * Feature bit for the average mipmap feature (value is 1<<3). + */ + public static final int AVG = 1 << 3; + + /** + * The string for maximum mipmap feature sub-attribute. + * This attribute value is the mipmap number of levels. + * It has sub-attributes for every level ("1", "2", etc.) + */ + public static final String MAX_STRING = "max"; //$NON-NLS-1$ + + /** + * The string for minimum mipmap feature sub-attribute. + * This attribute value is the mipmap number of levels. + * It has sub-attributes for every level ("1", "2", etc.) + */ + public static final String MIN_STRING = "min"; //$NON-NLS-1$ + + /** + * The string for average mipmap feature sub-attribute. + * This attribute value is the mipmap number of levels. + * It has sub-attributes for every level ("1", "2", etc.) + */ + public static final String AVG_STRING = "avg"; //$NON-NLS-1$ + + /** + * Map of mipmap features per attribute. The map's key is the base attribute quark. + */ + private Map> featureMap = new HashMap<>(); + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Constructor + * + * @param trace + * The trace directory + * @param eventType + * The specific class for the event type + * @param id + * The name given to this state change input. Only used + * internally. + */ + public AbstractTmfMipmapStateProvider(ITmfTrace trace, Class eventType, String id) { + super(trace, eventType, id); + } + + // ------------------------------------------------------------------------ + // Public methods + // ------------------------------------------------------------------------ + + @Override + public void dispose() { + waitForEmptyQueue(); + for (Set features : featureMap.values()) { + for (ITmfMipmapFeature feature : features) { + feature.updateAndCloseMipmap(); + } + } + super.dispose(); + } + + /** + * Modify a mipmap attribute. The base attribute is modified and the mipmap + * attributes for the feature(s) specified in the mipmap feature bitmap are + * created and/or updated.
+ * Note: The mipmapFeatureBits and resolution are only used on the first + * call of this method for a particular attribute, and the mipmap features + * for this attribute are then activated until the end of the trace.
+ * Note: The base attribute should only be modified by calling this method. + * + * @param ts + * The timestamp of the event + * @param value + * The value of the base attribute + * @param baseQuark + * The quark of the base attribute + * @param mipmapFeatureBits + * The mipmap feature bit(s) + * @param resolution + * The mipmap resolution (must be greater than 1) + * @throws TimeRangeException + * If the requested time is outside of the trace's range + * @throws AttributeNotFoundException + * If the requested attribute quark is invalid + * @throws StateValueTypeException + * If the inserted state value's type does not match what is + * already assigned to this attribute. + * @see #MAX + * @see #MIN + * @see #AVG + */ + public void modifyMipmapAttribute(long ts, ITmfStateValue value, int baseQuark, int mipmapFeatureBits, int resolution) + throws TimeRangeException, AttributeNotFoundException, StateValueTypeException { + ss.modifyAttribute(ts, value, baseQuark); + if (value.getType() == Type.LONG || value.getType() == Type.INTEGER || value.getType() == Type.DOUBLE || value.isNull()) { + Set features = getFeatureSet(baseQuark, ts, value, mipmapFeatureBits, resolution); + for (ITmfMipmapFeature mf : features) { + mf.updateMipmap(value, ts); + } + } + } + + // ------------------------------------------------------------------------ + // Private methods + // ------------------------------------------------------------------------ + + private Set getFeatureSet(int baseQuark, long ts, ITmfStateValue value, int mipmapFeatureBits, int resolution) { + Set features = featureMap.get(baseQuark); + if (features != null) { + return features; + } + features = new LinkedHashSet<>(); + if (value.isNull()) { + return features; + } + featureMap.put(baseQuark, features); + if (resolution > 1) { + try { + if ((mipmapFeatureBits & MAX) != 0) { + int featureQuark = ss.getQuarkRelativeAndAdd(baseQuark, MAX_STRING); + ss.modifyAttribute(ts, TmfStateValue.newValueInt(0), featureQuark); + MaxMipmapFeature mf = new MaxMipmapFeature(baseQuark, featureQuark, resolution, ss); + features.add(mf); + } + if ((mipmapFeatureBits & MIN) != 0) { + int featureQuark = ss.getQuarkRelativeAndAdd(baseQuark, MIN_STRING); + ss.modifyAttribute(ts, TmfStateValue.newValueInt(0), featureQuark); + MinMipmapFeature mf = new MinMipmapFeature(baseQuark, featureQuark, resolution, ss); + features.add(mf); + } + if ((mipmapFeatureBits & AVG) != 0) { + int featureQuark = ss.getQuarkRelativeAndAdd(baseQuark, AVG_STRING); + ss.modifyAttribute(ts, TmfStateValue.newValueInt(0), featureQuark); + AvgMipmapFeature mf = new AvgMipmapFeature(baseQuark, featureQuark, resolution, ss); + features.add(mf); + } + } catch (TimeRangeException e) { + e.printStackTrace(); + } catch (AttributeNotFoundException e) { + e.printStackTrace(); + } catch (StateValueTypeException e) { + e.printStackTrace(); + } + } + return features; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/AvgMipmapFeature.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/AvgMipmapFeature.java new file mode 100644 index 0000000000..113835a571 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/AvgMipmapFeature.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jean-Christian Kouamé - Initial API and implementation + * Patrick Tasse - Updates to mipmap feature + *******************************************************************************/ +package org.eclipse.tracecompass.internal.tmf.core.statesystem.mipmap; + +import java.util.List; + +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type; + +/** + * The average mipmap feature. + * + * Each mipmap state value is the weighted average by time duration of all the + * lower-level state values it covers. Null state values count as zero in the + * weighted average. The state value is a Double. + */ +public class AvgMipmapFeature extends TmfMipmapFeature { + + /** + * Constructor + * + * @param baseQuark + * The quark for the attribute we want to mipmap + * @param mipmapQuark + * The quark of the mipmap feature attribute + * @param mipmapResolution + * The resolution that will be use in the mipmap + * @param ss + * The state system in which to insert the state changes + */ + public AvgMipmapFeature(final int baseQuark, final int mipmapQuark, final int mipmapResolution, final ITmfStateSystemBuilder ss) { + super(baseQuark, mipmapQuark, mipmapResolution, ss); + } + + @Override + protected ITmfStateValue computeMipmapValue(List lowerIntervals, long startTime, long endTime) { + long range = endTime - startTime; + if (range <= 0) { + return TmfStateValue.newValueDouble(0.0); + } + double sum = 0.0; + try { + for (ITmfStateInterval interval : lowerIntervals) { + ITmfStateValue value = interval.getStateValue(); + long duration = interval.getEndTime() - interval.getStartTime(); + if (value.getType() == Type.DOUBLE) { + sum += value.unboxDouble() * duration; + } else { + sum += (double) value.unboxLong() * duration; + } + } + } catch (StateValueTypeException e) { + e.printStackTrace(); + } + double average = sum / range; + ITmfStateValue avgValue = TmfStateValue.newValueDouble(average); + return avgValue; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/ITmfMipmapFeature.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/ITmfMipmapFeature.java new file mode 100644 index 0000000000..03cfe532a3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/ITmfMipmapFeature.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jean-Christian Kouamé - Initial API and implementation + * Patrick Tasse - Updates to mipmap feature + *******************************************************************************/ +package org.eclipse.tracecompass.internal.tmf.core.statesystem.mipmap; + +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; + +/** + * Interface to allow additional types of mipmaps to be added. Two functions + * need to be implemented: {@link ITmfMipmapFeature#updateMipmap} and + * {@link ITmfMipmapFeature#updateAndCloseMipmap}. + * + * @author Jean-Christian Kouamé + * + */ +public interface ITmfMipmapFeature { + + /** + * Update the mipmap with a new state value. + * + * @param value + * The new state value + * @param ts + * The timestamp of the event + */ + public void updateMipmap(ITmfStateValue value, long ts); + + /** + * Update the mipmap values at all levels before closing. + */ + public void updateAndCloseMipmap(); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/MaxMipmapFeature.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/MaxMipmapFeature.java new file mode 100644 index 0000000000..06d70c440a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/MaxMipmapFeature.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jean-Christian Kouamé - Initial API and implementation + * Patrick Tasse - Updates to mipmap feature + *******************************************************************************/ +package org.eclipse.tracecompass.internal.tmf.core.statesystem.mipmap; + +import java.util.List; + +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type; + +/** + * The maximum mipmap feature. + * + * Each mipmap state value is the maximum numerical value of all the non-null + * lower-level state values it covers. The state value is of the same type as + * the base attribute. + */ +public class MaxMipmapFeature extends TmfMipmapFeature { + + /** + * Constructor + * + * @param baseQuark + * The quark for the attribute we want to mipmap + * @param mipmapQuark + * The quark of the mipmap feature attribute + * @param mipmapResolution + * The resolution that will be use in the mipmap + * @param ss + * The state system in which to insert the state changes + */ + public MaxMipmapFeature(final int baseQuark, final int mipmapQuark, final int mipmapResolution, final ITmfStateSystemBuilder ss) { + super(baseQuark, mipmapQuark, mipmapResolution, ss); + } + + @Override + protected ITmfStateValue computeMipmapValue(List lowerIntervals, long startTime, long endTime) { + ITmfStateValue maxValue = null; + try { + for (ITmfStateInterval interval : lowerIntervals) { + ITmfStateValue value = interval.getStateValue(); + if (value.getType() == Type.DOUBLE) { + if (maxValue == null || value.unboxDouble() > maxValue.unboxDouble()) { + maxValue = value; + } + } else { + if (maxValue == null || value.unboxLong() > maxValue.unboxLong()) { + maxValue = value; + } + } + } + } catch (StateValueTypeException e) { + e.printStackTrace(); + } + return maxValue; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/MinMipmapFeature.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/MinMipmapFeature.java new file mode 100644 index 0000000000..fdc676349a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/MinMipmapFeature.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jean-Christian Kouamé - Initial API and implementation + * Patrick Tasse - Updates to mipmap feature + *******************************************************************************/ +package org.eclipse.tracecompass.internal.tmf.core.statesystem.mipmap; + +import java.util.List; + +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type; + +/** + * The minimum mipmap feature. + * + * Each mipmap state value is the minimum numerical value of all the non-null + * lower-level state values it covers. The state value is of the same type as + * the base attribute. + */ +public class MinMipmapFeature extends TmfMipmapFeature { + + /** + * Constructor + * + * @param baseQuark + * The quark for the attribute we want to mipmap + * @param mipmapQuark + * The quark of the mipmap feature attribute + * @param mipmapResolution + * The resolution that will be use in the mipmap + * @param ss + * The state system in which to insert the state changes + */ + public MinMipmapFeature(final int baseQuark, final int mipmapQuark, final int mipmapResolution, final ITmfStateSystemBuilder ss) { + super(baseQuark, mipmapQuark, mipmapResolution, ss); + } + + @Override + protected ITmfStateValue computeMipmapValue(List lowerIntervals, long startTime, long endTime) { + ITmfStateValue minValue = null; + try { + for (ITmfStateInterval interval : lowerIntervals) { + ITmfStateValue value = interval.getStateValue(); + if (value.getType() == Type.DOUBLE) { + if (minValue == null || value.unboxDouble() < minValue.unboxDouble()) { + minValue = value; + } + } else { + if (minValue == null || value.unboxLong() < minValue.unboxLong()) { + minValue = value; + } + } + } + } catch (StateValueTypeException e) { + e.printStackTrace(); + } + return minValue; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/TmfMipmapFeature.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/TmfMipmapFeature.java new file mode 100644 index 0000000000..b66aa8f27c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/TmfMipmapFeature.java @@ -0,0 +1,238 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jean-Christian Kouamé - Initial API and implementation + * Patrick Tasse - Updates to mipmap feature + *******************************************************************************/ +package org.eclipse.tracecompass.internal.tmf.core.statesystem.mipmap; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; +import org.eclipse.linuxtools.statesystem.core.interval.TmfStateInterval; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; + +/** + * The mipmap feature base implementation. + * + * @author Jean-Christian Kouamé + * @author Patrick Tasse + * + */ +public abstract class TmfMipmapFeature implements ITmfMipmapFeature { + + /** The current state value */ + protected ITmfStateValue currentValue = TmfStateValue.nullValue(); + /** The current start time for the state value */ + protected long currentStartTime; + /** The list of ongoing state intervals per mipmap level */ + protected List> intervals = new ArrayList<>(); + /** The state system used to store the mipmap attributes */ + protected ITmfStateSystemBuilder ss; + + private int mipmapResolution; + private int mipmapQuark; + private List levelQuarks = new ArrayList<>(); + + /** + * Constructor + * + * @param baseQuark + * The quark of the attribute we want to mipmap + * @param mipmapQuark + * The quark of the mipmap feature attribute + * @param mipmapResolution + * The resolution that will be used for the mipmap + * @param ss + * The state system in which to insert the state changes + */ + public TmfMipmapFeature(int baseQuark, int mipmapQuark, int mipmapResolution, ITmfStateSystemBuilder ss) { + this.mipmapQuark = mipmapQuark; + this.mipmapResolution = mipmapResolution; + this.ss = ss; + + /* store the base attribute quark at level 0 */ + this.levelQuarks.add(baseQuark); + + /* create the level 0 list */ + intervals.add(new ArrayList(mipmapResolution)); + } + + @Override + public void updateMipmap(ITmfStateValue value, long ts) { + /* if the value did not change, ignore it */ + if (currentValue.equals(value)) { + return; + } + + /* if the ongoing state value is not null, create and store a state interval */ + if (!currentValue.isNull()) { + ITmfStateInterval interval = new TmfStateInterval(currentStartTime, ts, getLevelQuark(0), currentValue); + intervals.get(0).add(interval); + } + + /* if the new value is not null, update the mipmap levels that are full */ + if (!value.isNull()) { + int level = 0; + while (intervals.get(level).size() == getMipmapResolution()) { + updateMipmapLevel(++level, ts); + } + } + + /* store the new value as the ongoing state value */ + currentValue = value; + currentStartTime = ts; + } + + @Override + public void updateAndCloseMipmap() { + if (!currentValue.isNull()) { + ITmfStateInterval interval = new TmfStateInterval(currentStartTime, currentStartTime, getLevelQuark(0), currentValue); + intervals.get(0).add(interval); + } + for (int level = 1; level <= getNbLevels(); level++) { + updateMipmapLevel(level, currentStartTime); + } + } + + /** + * Compute and update the mipmap level attribute from the lower-level + * state interval list + * + * @param level + * The mipmap level to update + * @param endTime + * The end timestamp to use for the mipmap interval + */ + protected void updateMipmapLevel(int level, long endTime) { + try { + /* get the lower-level interval list */ + List lowerIntervals = intervals.get(level - 1); + if (lowerIntervals.size() == 0) { + return; + } + + /* get the start time from the first interval in the lower-level list */ + long startTime = lowerIntervals.get(0).getStartTime(); + + /* compute the mipmap value */ + ITmfStateValue value = computeMipmapValue(lowerIntervals, startTime, endTime); + + /* clear the lower-level list */ + lowerIntervals.clear(); + + /* get or create the current-level quark */ + int levelQuark = ss.getQuarkRelativeAndAdd(mipmapQuark, String.valueOf(level)); + if (!checkLevelExists(level)) { + addLevelQuark(levelQuark); + ss.updateOngoingState(TmfStateValue.newValueInt(level), mipmapQuark); + intervals.add(new ArrayList(getMipmapResolution())); + } + + /* add new interval to current-level list */ + ITmfStateInterval interval = new TmfStateInterval(startTime, endTime, levelQuark, value); + intervals.get(level).add(interval); + + /* update the current-level attribute */ + ss.modifyAttribute(startTime, value, levelQuark); + } catch (StateValueTypeException e) { + e.printStackTrace(); + } catch (AttributeNotFoundException e) { + e.printStackTrace(); + } catch (TimeRangeException e) { + e.printStackTrace(); + } + } + + /** + * Compute the mipmap value from a list of lower-level state intervals + * + * @param lowerIntervals + * The list of lower-level state intervals + * @param startTime + * The start time of the mipmap interval + * @param endTime + * The end time of the mipmap interval + * @return A state value to be stored in the mipmap level attribute + */ + protected abstract ITmfStateValue computeMipmapValue(List lowerIntervals, long startTime, long endTime); + + /** + * Get the mipmap resolution + * + * @return The mipmap resolution for this feature + */ + protected int getMipmapResolution() { + return mipmapResolution; + } + + /** + * Get the mipmap feature quark. The state value + * of this attribute is the mipmap number of levels. + * This is the parent attribute of the mipmap level quarks. + * + * @return The attribute quark for this mipmap feature + */ + protected int getMipmapQuark() { + return mipmapQuark; + } + + /** + * Get the mipmap quark for the specified level. + * For level 0 the base attribute quark is returned. + * + * @param level + * The mipmap level (0 for the base attribute) + * @return The attribute quark for this mipmap level + */ + protected int getLevelQuark(int level) { + return levelQuarks.get(level); + } + + /** + * Add a new mipmap level quark. + * + * @param quark + * The attribute quark for the new mipmap level + */ + protected void addLevelQuark(int quark) { + levelQuarks.add(quark); + } + + /** + * Get the mipmap number of levels. + * + * @return The current number of mipmap levels for this feature + * (excluding the base attribute) + */ + protected int getNbLevels() { + return levelQuarks.size() - 1; + } + + /** + * Checks if a mipmap level exists. + * + * @param level + * The mipmap level to check + * @return true if this level exists, false otherwise + */ + protected boolean checkLevelExists(int level) { + if (level >= levelQuarks.size() || level < 0) { + return false; + } + return true; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/TmfStateSystemOperations.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/TmfStateSystemOperations.java new file mode 100644 index 0000000000..fd0f506a68 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/TmfStateSystemOperations.java @@ -0,0 +1,350 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jean-Christian Kouamé - Initial API and implementation + * Patrick Tasse - Updates to mipmap feature + ******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.statesystem.mipmap; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type; + +/** + * This class implements additional statistical operations that can be + * performed on attributes of the state system. + * + * @author Patrick Tassé + * @since 3.0 + */ +public final class TmfStateSystemOperations { + + private TmfStateSystemOperations() {} + + /** + * Return the maximum value of an attribute over a time range + * + * @param ss + * The state system to query + * @param t1 + * The start time of the range + * @param t2 + * The end time of the range + * @param quark + * The quark of the attribute + * @return The maximum value of the attribute in this range + * @throws TimeRangeException + * If an invalid time range is specified + * @throws AttributeNotFoundException + * If the specified quark doesn't match an attribute + * @throws StateValueTypeException + * If the state value type of the attribute does not support the + * "Max" operation + */ + public static ITmfStateValue queryRangeMax(ITmfStateSystem ss, long t1, long t2, int quark) + throws AttributeNotFoundException, TimeRangeException, StateValueTypeException { + ITmfStateValue max = TmfStateValue.nullValue(); + + List intervals = queryAttributeRange(ss, t1, t2, quark, AbstractTmfMipmapStateProvider.MAX_STRING); + if (intervals.size() == 0) { + return TmfStateValue.nullValue(); + } + for (ITmfStateInterval si : intervals) { + ITmfStateValue value = si.getStateValue(); + + switch (value.getType()) { + case DOUBLE: + if (max.isNull() || si.getStateValue().unboxDouble() > max.unboxDouble()) { + max = si.getStateValue(); + } + break; + + case INTEGER: + case LONG: + if (max.isNull() || si.getStateValue().unboxLong() > max.unboxLong()) { + max = si.getStateValue(); + } + break; + + case NULL: + case STRING: + default: + throw new StateValueTypeException(); + } + } + return max; + } + + /** + * Return the minimum value of an attribute over a time range + * + * @param ss + * The state system to query + * @param t1 + * The start time of the range + * @param t2 + * The end time of the range + * @param quark + * The quark of the attribute + * @return The minimum value of the attribute in this range + * @throws TimeRangeException + * If an invalid time range is specified + * @throws AttributeNotFoundException + * If the specified quark doesn't match an attribute + * @throws StateValueTypeException + * If the state value type of the attribute does not support the + * "Min" operation + */ + public static ITmfStateValue queryRangeMin(ITmfStateSystem ss, + long t1, long t2, int quark) + throws AttributeNotFoundException, TimeRangeException, StateValueTypeException { + ITmfStateValue min = TmfStateValue.nullValue(); + + List intervals = queryAttributeRange(ss, t1, t2, quark, AbstractTmfMipmapStateProvider.MIN_STRING); + if (intervals.size() == 0) { + return TmfStateValue.nullValue(); + } + for (ITmfStateInterval si : intervals) { + ITmfStateValue value = si.getStateValue(); + + switch (value.getType()) { + case DOUBLE: + if (min.isNull() || si.getStateValue().unboxDouble() < min.unboxDouble()) { + min = si.getStateValue(); + } + break; + + case INTEGER: + case LONG: + if (min.isNull() || si.getStateValue().unboxLong() < min.unboxLong()) { + min = si.getStateValue(); + } + break; + + case NULL: + case STRING: + default: + throw new StateValueTypeException(); + } + } + return min; + } + + /** + * Return the weighted average value of an attribute over a time range + * + * @param ss + * The state system to query + * @param t1 + * The start time of the range + * @param t2 + * The end time of the range + * @param quark + * The quark of the attribute + * @return The weighted average value of the attribute in this range + * @throws TimeRangeException + * If an invalid time range is specified + * @throws AttributeNotFoundException + * If the specified quark doesn't match an attribute + * @throws StateValueTypeException + * If the state value type of the attribute does not support the + * "Average" operation + */ + public static double queryRangeAverage(ITmfStateSystem ss, long t1, long t2, int quark) + throws AttributeNotFoundException, TimeRangeException, StateValueTypeException { + double avg = 0.0; + List intervals = queryAttributeRange(ss, t1, t2, quark, AbstractTmfMipmapStateProvider.AVG_STRING); + if (intervals.size() == 0) { + return 0; + } else if (t1 == t2) { + ITmfStateValue value = intervals.get(0).getStateValue(); + if (value.getType() == Type.DOUBLE) { + return value.unboxDouble(); + } + return value.unboxLong(); + } + for (ITmfStateInterval si : intervals) { + long startTime = Math.max(t1, si.getStartTime()); + long endTime = Math.min(t2, si.getEndTime() + 1); + long delta = endTime - startTime; + if (delta > 0) { + ITmfStateValue value = si.getStateValue(); + if (value.getType() == Type.DOUBLE) { + avg += si.getStateValue().unboxDouble() * ((double) delta / (double) (t2 - t1)); + } else { + avg += si.getStateValue().unboxLong() * ((double) delta / (double) (t2 - t1)); + } + } + } + return avg; + } + + private static List queryAttributeRange(ITmfStateSystem ss, + long t1, long t2, int baseQuark, String featureString) + throws AttributeNotFoundException, TimeRangeException, StateValueTypeException { + TimeRange timeRange = new TimeRange(t1, t2); + int mipmapQuark = -1; + List intervals = new ArrayList<>(); + try { + try { + mipmapQuark = ss.getQuarkRelative(baseQuark, featureString); + } catch (AttributeNotFoundException e) { + /* Not a mipmap attribute, query the base attribute */ + if (t1 == t2) { + ITmfStateInterval interval = ss.querySingleState(t1, baseQuark); + if (!interval.getStateValue().isNull()) { + intervals.add(interval); + } + } else { + for (ITmfStateInterval interval : ss.queryHistoryRange(baseQuark, t1, t2)) { + if (!interval.getStateValue().isNull()) { + intervals.add(interval); + } + } + } + return intervals; + } + ITmfStateInterval maxLevelInterval = ss.querySingleState(timeRange.getSecond(), mipmapQuark); + int levelMax = maxLevelInterval.getStateValue().unboxInt(); + queryMipmapAttributeRange(ss, 0, levelMax, baseQuark, mipmapQuark, timeRange, intervals); + return intervals; + + } catch (StateValueTypeException e) { + /* This is a special case, so we'll add a message to the exception */ + throw new StateValueTypeException("State system advertises mipmaps," + //$NON-NLS-1$ + " but doesn't actually have them.", e); //$NON-NLS-1$ + } catch (StateSystemDisposedException e) { + /* We are shutting down, ignore the operation */ + } + return intervals; + } + + private static void queryMipmapAttributeRange(ITmfStateSystem ss, + int currentLevel, int levelMax, int baseQuark, int mipmapQuark, + TimeRange timeRange, List intervals) + throws AttributeNotFoundException, TimeRangeException { + int level = currentLevel; + TimeRange range = timeRange; + ITmfStateInterval currentLevelInterval = null, nextLevelInterval = null; + if (range == null || range.getFirst() > range.getSecond()) { + return; + } + if (level > levelMax || level < 0) { + return; + } + try { + if (range.getFirst() == range.getSecond()) { + level = 0; + currentLevelInterval = ss.querySingleState(range.getFirst(), baseQuark); + if (!currentLevelInterval.getStateValue().isNull()) { + intervals.add(currentLevelInterval); + } + return; + } + if (level < levelMax) { + int levelQuark = ss.getQuarkRelative(mipmapQuark, String.valueOf(level + 1)); + nextLevelInterval = ss.querySingleState(range.getFirst(), levelQuark); + } + + if (nextLevelInterval != null && isFullyOverlapped(range, nextLevelInterval)) { + if (nextLevelInterval.getStateValue().isNull()) { + range = updateTimeRange(range, nextLevelInterval); + } else { + level++; + } + queryMipmapAttributeRange(ss, level, levelMax, baseQuark, mipmapQuark, range, intervals); + return; + } + + if (level == 0) { + currentLevelInterval = ss.querySingleState(range.getFirst(), baseQuark); + } else { + int levelQuark = ss.getQuarkRelative(mipmapQuark, String.valueOf(level)); + currentLevelInterval = ss.querySingleState(range.getFirst(), levelQuark); + } + + if (currentLevelInterval != null && isFullyOverlapped(range, currentLevelInterval)) { + if (!currentLevelInterval.getStateValue().isNull()) { + intervals.add(currentLevelInterval); + } + range = updateTimeRange(range, currentLevelInterval); + } else { + if (level == 0) { + if (currentLevelInterval == null) { + return; + } + if (!currentLevelInterval.getStateValue().isNull()) { + intervals.add(currentLevelInterval); + } + range = updateTimeRange(range, currentLevelInterval); + } else { + level--; + } + } + + queryMipmapAttributeRange(ss, level, levelMax, baseQuark, + mipmapQuark, range, intervals); + + } catch (StateSystemDisposedException e) { + /* We are shutting down, ignore the operation */ + } + } + + private static TimeRange updateTimeRange(TimeRange timeRange, + ITmfStateInterval currentLevelInterval) { + if (currentLevelInterval.getEndTime() >= timeRange.getSecond()) { + return null; + } + long startTime = Math.max(timeRange.getFirst(), + Math.min(currentLevelInterval.getEndTime() + 1, timeRange.getSecond())); + return new TimeRange(startTime, timeRange.getSecond()); + } + + private static boolean isFullyOverlapped(TimeRange range, + ITmfStateInterval interval) { + if (range.getFirst() >= range.getSecond() || + interval.getStartTime() >= interval.getEndTime()) { + return false; + } + if (range.getFirst() <= interval.getStartTime() && + range.getSecond() >= interval.getEndTime()) { + return true; + } + return false; + } +} + +class TimeRange { + + private final long a; + private final long b; + + public TimeRange(long first, long second) { + a = first; + b = second; + } + + public long getFirst() { + return a; + } + + public long getSecond() { + return b; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/ITmfTimestampTransformInvertible.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/ITmfTimestampTransformInvertible.java new file mode 100644 index 0000000000..49b6651dc2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/ITmfTimestampTransformInvertible.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.synchronization; + +import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform; + +/** + * Interface for timestamp transform who also provide an inverse transform. + * + * @author Geneviève Bastien + */ +public interface ITmfTimestampTransformInvertible extends ITmfTimestampTransform { + + /** + * Returns the inverse of this transform. The transform composed with its + * inverse yields the identity (or as close to it as mathematical + * approximations in the formulae allow). + * + * @return The inverse transform + */ + ITmfTimestampTransform inverse(); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java new file mode 100644 index 0000000000..654740352f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java @@ -0,0 +1,623 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + * Francis Giraldeau - Transform computation using synchronization graph + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.synchronization; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.math.BigDecimal; +import java.math.MathContext; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.eclipse.tracecompass.internal.tmf.core.synchronization.graph.SyncSpanningTree; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.matching.TmfEventDependency; +import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform; +import org.eclipse.tracecompass.tmf.core.synchronization.Messages; +import org.eclipse.tracecompass.tmf.core.synchronization.SynchronizationAlgorithm; +import org.eclipse.tracecompass.tmf.core.synchronization.TimestampTransformFactory; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Class implementing fully incremental trace synchronization approach as + * described in + * + * Masoume Jabbarifar, Michel Dagenais and Alireza Shameli-Sendi, + * "Streaming Mode Incremental Clock Synchronization" + * + * Since the algorithm itself applies to two traces, it is implemented in a + * private class, while this public class manages the synchronization between + * all traces. + * + * @author Geneviève Bastien + */ +public class SyncAlgorithmFullyIncremental extends SynchronizationAlgorithm { + + /** + * Auto-generated serial UID + */ + private static final long serialVersionUID = -1782788842774838830L; + + private static final MathContext fMc = MathContext.DECIMAL128; + + /** @Serial */ + private final List fSyncs; + + private SyncSpanningTree fTree = null; + + /** + * Initialization of the attributes + */ + public SyncAlgorithmFullyIncremental() { + fSyncs = new LinkedList<>(); + } + + /** + * Function called after all matching has been done, to do any post-match + * treatment. For this class, it calculates stats, while the data is + * available + */ + @Override + public void matchingEnded() { + getStats(); + } + + @Override + public void init(Collection traces) { + ITmfTrace[] traceArr = traces.toArray(new ITmfTrace[traces.size()]); + fSyncs.clear(); + /* Create a convex hull for all trace pairs */ + // FIXME: is it necessary to make ConvexHull for every pairs up-front? + // The ConvexHull seems to be created on the fly in processMatch(). + for (int i = 0; i < traceArr.length; i++) { + for (int j = i + 1; j < traceArr.length; j++) { + if (!traceArr[i].getHostId().equals(traceArr[j].getHostId())) { + ConvexHull algo = new ConvexHull(traceArr[i].getHostId(), traceArr[j].getHostId()); + fSyncs.add(algo); + } + } + } + } + + @Override + protected void processMatch(TmfEventDependency match) { + String host1 = match.getSourceEvent().getTrace().getHostId(); + String host2 = match.getDestinationEvent().getTrace().getHostId(); + + /* Process only if source and destination are different */ + if (host1.equals(host2)) { + return; + } + + /* Check if a convex hull algorithm already exists for these 2 hosts */ + ConvexHull algo = null; + for (ConvexHull traceSync : fSyncs) { + if (traceSync.isForHosts(host1, host2)) { + algo = traceSync; + } + } + if (algo == null) { + algo = new ConvexHull(host1, host2); + fSyncs.add(algo); + } + algo.processMatch(match); + invalidateSyncGraph(); + } + + private void invalidateSyncGraph() { + fTree = null; + } + + @Override + public ITmfTimestampTransform getTimestampTransform(ITmfTrace trace) { + return getTimestampTransform(trace.getHostId()); + } + + @Override + public ITmfTimestampTransform getTimestampTransform(String hostId) { + SyncSpanningTree tree = getSyncTree(); + return tree.getTimestampTransform(hostId); + } + + /** + * Each convex hull computes the synchronization between 2 given hosts. A + * synchronization can be done on multiple hosts that may not all + * communicate with each other. We must use another algorithm to determine + * which host will be the reference node and what synchronization formula + * will be used between each host and this reference node. + * + * For example, take traces a, b and c where a and c talk to b but do not + * know each other ({@literal a <-> b <-> c}). The convex hulls will contain + * the formulae between their 2 traces, but if a is the reference node, then + * the resulting formula of c would be the composition of {@literal a <-> b} + * and {@literal b <-> c} + * + * @return The synchronization spanning tree for this synchronization + */ + private SyncSpanningTree getSyncTree() { + if (fTree == null) { + fTree = new SyncSpanningTree(); + for (ConvexHull traceSync : fSyncs) { + SyncQuality q = traceSync.getQuality(); + if (q == SyncQuality.ACCURATE || q == SyncQuality.APPROXIMATE) { + String from = traceSync.getReferenceHost(); + String to = traceSync.getOtherHost(); + fTree.addSynchronization(from, to, traceSync.getTimestampTransform(to), traceSync.getAccuracy()); + } + } + } + return fTree; + } + + @Override + public SyncQuality getSynchronizationQuality(ITmfTrace trace1, ITmfTrace trace2) { + for (ConvexHull traceSync : fSyncs) { + if (traceSync.isForHosts(trace1.getHostId(), trace2.getHostId())) { + return traceSync.getQuality(); + } + } + return SyncQuality.ABSENT; + } + + @Override + public boolean isTraceSynced(String hostId) { + ITmfTimestampTransform t = getTimestampTransform(hostId); + return !t.equals(TimestampTransformFactory.getDefaultTransform()); + } + + @Override + public Map> getStats() { + /* + * TODO: Stats, while still accurate, may be misleading now that the + * sync tree changes synchronization formula. The stats should use the + * tree instead + */ + Map> statmap = new LinkedHashMap<>(); + for (ConvexHull traceSync : fSyncs) { + statmap.put(traceSync.getReferenceHost() + " <==> " + traceSync.getOtherHost(), traceSync.getStats()); //$NON-NLS-1$ + } + return statmap; + } + + @Override + public String toString() { + StringBuilder b = new StringBuilder(); + b.append(getClass().getSimpleName() + " "); //$NON-NLS-1$ + b.append(fSyncs); + return b.toString(); + } + + /** + * This is the actual synchronization algorithm between two traces using + * convex hull + */ + private class ConvexHull implements Serializable { + + private static final long serialVersionUID = 8309351175030935291L; + + /** + * The list of meaningful points on the upper hull (received by the + * reference trace, below in a graph) + */ + private final LinkedList fUpperBoundList = new LinkedList<>(); + + /** + * The list of meaninful points on the lower hull (sent by the reference + * trace, above in a graph) + */ + private final LinkedList fLowerBoundList = new LinkedList<>(); + + /** Points forming the line with maximum slope */ + private final SyncPoint[] fLmax; + + /** Points forming the line with minimum slope */ + private final SyncPoint[] fLmin; + + /** + * Slopes and ordinate at origin of respectively fLmin, fLmax and the + * bisector + */ + private BigDecimal fAlphamin, fBetamax, fAlphamax, fBetamin, fAlpha, fBeta; + + private int fNbMatches, fNbAccurateMatches; + private String fReferenceHost = "", fOtherHost = ""; //$NON-NLS-1$//$NON-NLS-2$ + private SyncQuality fQuality; + + private Map fStats = new LinkedHashMap<>(); + + /** + * Initialization of the attributes + * + * @param host1 + * ID of the first host + * @param host2 + * ID of the second host + */ + public ConvexHull(String host1, String host2) { + if (host1.compareTo(host2) > 0) { + fReferenceHost = host2; + fOtherHost = host1; + } else { + fReferenceHost = host1; + fOtherHost = host2; + } + fLmax = new SyncPoint[2]; + fLmin = new SyncPoint[2]; + fAlpha = BigDecimal.ONE; + fAlphamax = BigDecimal.ONE; + fAlphamin = BigDecimal.ONE; + fBeta = BigDecimal.ZERO; + fBetamax = BigDecimal.ZERO; + fBetamin = BigDecimal.ZERO; + fNbMatches = 0; + fNbAccurateMatches = 0; + fQuality = SyncQuality.ABSENT; // default quality + } + + protected void processMatch(TmfEventDependency match) { + + LinkedList boundList, otherBoundList; + + SyncPoint[] line, otherLine; + SyncPoint p; + int inversionFactor = 1; + boolean qualify = false; + fNbMatches++; + + /* Initialize data depending on the which hull the match is part of */ + if (match.getSourceEvent().getTrace().getHostId().compareTo(match.getDestinationEvent().getTrace().getHostId()) > 0) { + boundList = fUpperBoundList; + otherBoundList = fLowerBoundList; + line = fLmin; + otherLine = fLmax; + p = new SyncPoint(match.getDestinationEvent(), match.getSourceEvent()); + inversionFactor = 1; + } else { + boundList = fLowerBoundList; + otherBoundList = fUpperBoundList; + line = fLmax; + otherLine = fLmin; + p = new SyncPoint(match.getSourceEvent(), match.getDestinationEvent()); + inversionFactor = -1; + } + + /* + * Does the message qualify for the hull, or is in on the wrong side + * of the reference line + */ + if ((line[0] == null) || (line[1] == null) || (p.crossProduct(line[0], line[1]) * inversionFactor > 0)) { + /* + * If message qualifies, verify if points need to be removed + * from the hull and add the new point as the maximum reference + * point for the line. Also clear the stats that are not good + * anymore + */ + fNbAccurateMatches++; + qualify = true; + removeUselessPoints(p, boundList, inversionFactor); + line[1] = p; + fStats.clear(); + } + + /* + * Adjust the boundary of the reference line and if one of the + * reference point of the other line was removed from the hull, also + * adjust the other line + */ + adjustBound(line, otherBoundList, inversionFactor); + if ((otherLine[1] != null) && !boundList.contains(otherLine[0])) { + adjustBound(otherLine, boundList, inversionFactor * -1); + } + + if (qualify) { + approximateSync(); + } + + } + + /** + * Calculates slopes and ordinate at origin of fLmax and fLmin to obtain + * and approximation of the synchronization at this time + */ + private void approximateSync() { + + /** + * Line slopes functions + * + * Lmax = alpha_max T + beta_min + * + * Lmin = alpha_min T + beta_max + */ + if ((fLmax[0] != null) || (fLmin[0] != null)) { + /** + * Do not recalculate synchronization after it is failed. We + * keep the last not failed result. + */ + if (getQuality() != SyncQuality.FAIL) { + BigDecimal alphamax = fLmax[1].getAlpha(fLmax[0]); + BigDecimal alphamin = fLmin[1].getAlpha(fLmin[0]); + SyncQuality quality = null; + + if ((fLmax[0] == null) || (fLmin[0] == null)) { + quality = SyncQuality.APPROXIMATE; + } + else if (alphamax.compareTo(alphamin) > 0) { + quality = SyncQuality.ACCURATE; + } else { + /* Lines intersect, not good */ + quality = SyncQuality.FAIL; + } + /* + * Only calculate sync if this match does not cause failure + * of synchronization + */ + if (quality != SyncQuality.FAIL) { + fAlphamax = alphamax; + fBetamin = fLmax[1].getBeta(fAlphamax); + fAlphamin = alphamin; + fBetamax = fLmin[1].getBeta(fAlphamin); + fAlpha = fAlphamax.add(fAlphamin).divide(BigDecimal.valueOf(2), fMc); + fBeta = fBetamin.add(fBetamax).divide(BigDecimal.valueOf(2), fMc); + } + setQuality(quality); + } + } else if (((fLmax[0] == null) && (fLmin[1] == null)) + || ((fLmax[1] == null) && (fLmin[0] == null))) { + /* Either there is no upper hull point or no lower hull */ + setQuality(SyncQuality.INCOMPLETE); + } + } + + /* + * Verify if the line should be adjusted to be more accurate give the + * hull + */ + private void adjustBound(SyncPoint[] line, LinkedList otherBoundList, int inversionFactor) { + SyncPoint minPoint = null, nextPoint; + boolean finishedSearch = false; + + /* + * Find in the other bound, the origin point of the line, start from + * the beginning if the point was lost + */ + int i = Math.max(0, otherBoundList.indexOf(line[0])); + + while ((i < otherBoundList.size() - 1) && !finishedSearch) { + minPoint = otherBoundList.get(i); + nextPoint = otherBoundList.get(i + 1); + + /* + * If the rotation (cross-product) is not optimal, move to next + * point as reference for the line (if available) + * + * Otherwise, the current minPoint is the minPoint of the line + */ + if (minPoint.crossProduct(nextPoint, line[1]) * inversionFactor > 0) { + if (nextPoint.getTimeX() < line[1].getTimeX()) { + i++; + } else { + line[0] = null; + finishedSearch = true; + } + } else { + line[0] = minPoint; + finishedSearch = true; + } + } + + if (line[0] == null) { + line[0] = minPoint; + } + + /* Make sure point 0 is before point 1 */ + if ((line[0] != null) && (line[0].getTimeX() > line[1].getTimeX())) { + line[0] = null; + } + } + + /* + * When a point qualifies to be in a hull, we verify if any of the + * existing points need to be removed from the hull + */ + private void removeUselessPoints(final SyncPoint p, final LinkedList boundList, final int inversionFactor) { + + boolean checkRemove = true; + + while (checkRemove && boundList.size() >= 2) { + if (p.crossProduct(boundList.get(boundList.size() - 2), boundList.getLast()) * inversionFactor > 0) { + boundList.removeLast(); + } else { + checkRemove = false; + } + } + boundList.addLast(p); + } + + public ITmfTimestampTransform getTimestampTransform(String hostId) { + if (hostId.equals(fOtherHost) && (getQuality() == SyncQuality.ACCURATE || getQuality() == SyncQuality.APPROXIMATE || getQuality() == SyncQuality.FAIL)) { + /* alpha: beta => 1 / fAlpha, -1 * fBeta / fAlpha); */ + return TimestampTransformFactory.createLinear(BigDecimal.ONE.divide(fAlpha, fMc), BigDecimal.valueOf(-1).multiply(fBeta).divide(fAlpha, fMc)); + } + return TimestampTransformFactory.getDefaultTransform(); + } + + public SyncQuality getQuality() { + return fQuality; + } + + public BigDecimal getAccuracy() { + return fAlphamax.subtract(fAlphamin); + } + + public Map getStats() { + if (fStats.size() == 0) { + String syncQuality; + switch (getQuality()) { + case ABSENT: + syncQuality = Messages.SyncAlgorithmFullyIncremental_absent; + break; + case ACCURATE: + syncQuality = Messages.SyncAlgorithmFullyIncremental_accurate; + break; + case APPROXIMATE: + syncQuality = Messages.SyncAlgorithmFullyIncremental_approx; + break; + case INCOMPLETE: + syncQuality = Messages.SyncAlgorithmFullyIncremental_incomplete; + break; + case FAIL: + default: + syncQuality = Messages.SyncAlgorithmFullyIncremental_fail; + break; + } + + fStats.put(Messages.SyncAlgorithmFullyIncremental_refhost, fReferenceHost); + fStats.put(Messages.SyncAlgorithmFullyIncremental_otherhost, fOtherHost); + fStats.put(Messages.SyncAlgorithmFullyIncremental_quality, syncQuality); + fStats.put(Messages.SyncAlgorithmFullyIncremental_alpha, fAlpha); + fStats.put(Messages.SyncAlgorithmFullyIncremental_beta, fBeta); + fStats.put(Messages.SyncAlgorithmFullyIncremental_ub, (fUpperBoundList.size() == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fUpperBoundList.size()); + fStats.put(Messages.SyncAlgorithmFullyIncremental_lb, (fLowerBoundList.size() == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fLowerBoundList.size()); + fStats.put(Messages.SyncAlgorithmFullyIncremental_accuracy, getAccuracy().doubleValue()); + fStats.put(Messages.SyncAlgorithmFullyIncremental_nbmatch, (fNbMatches == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fNbMatches); + fStats.put(Messages.SyncAlgorithmFullyIncremental_nbacc, (fNbAccurateMatches == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fNbAccurateMatches); + fStats.put(Messages.SyncAlgorithmFullyIncremental_refformula, Messages.SyncAlgorithmFullyIncremental_T_ + fReferenceHost); + fStats.put(Messages.SyncAlgorithmFullyIncremental_otherformula, fAlpha + Messages.SyncAlgorithmFullyIncremental_mult + Messages.SyncAlgorithmFullyIncremental_T_ + fReferenceHost + Messages.SyncAlgorithmFullyIncremental_add + fBeta); + } + return fStats; + + } + + public String getReferenceHost() { + return fReferenceHost; + } + + public String getOtherHost() { + return fOtherHost; + } + + public boolean isForHosts(String hostId1, String hostId2) { + return ((fReferenceHost.equals(hostId1) && fOtherHost.equals(hostId2)) || (fReferenceHost.equals(hostId2) && fOtherHost.equals(hostId1))); + } + + private void writeObject(ObjectOutputStream s) + throws IOException { + /* + * Remove calculation data because most of it is not serializable. + * We have the statistics anyway + */ + fUpperBoundList.clear(); + fLowerBoundList.clear(); + fLmin[0] = null; + fLmin[1] = null; + fLmax[0] = null; + fLmax[1] = null; + s.defaultWriteObject(); + } + + @SuppressWarnings("nls") + @Override + public String toString() { + StringBuilder b = new StringBuilder(); + b.append("Between " + fReferenceHost + " and " + fOtherHost + " ["); + b.append(" alpha " + fAlpha + " beta " + fBeta + " ]"); + return b.toString(); + } + + private void setQuality(SyncQuality fQuality) { + this.fQuality = fQuality; + } + + } + + /** + * Private class representing a point to synchronize on a graph. The x axis + * is the timestamp of the event from the reference trace while the y axis + * is the timestamp of the event on the other trace + */ + private class SyncPoint { + private final ITmfTimestamp x, y; + + public SyncPoint(ITmfEvent ex, ITmfEvent ey) { + x = ex.getTimestamp(); + y = ey.getTimestamp(); + } + + public long getTimeX() { + return x.getValue(); + } + + /** + * Calculate a cross product of 3 points: + * + * If the cross-product < 0, then p, pa, pb are clockwise + * + * If the cross-product > 0, then p, pa, pb are counter-clockwise + * + * If cross-product == 0, then they are in a line + * + * @param pa + * First point + * @param pb + * Second point + * @return The cross product + */ + public long crossProduct(SyncPoint pa, SyncPoint pb) { + long cp = ((pa.x.getValue() - x.getValue()) * (pb.y.getValue() - y.getValue()) - (pa.y.getValue() - y.getValue()) * (pb.x.getValue() - x.getValue())); + return cp; + } + + /* + * Gets the alpha (slope) between two points + */ + public BigDecimal getAlpha(SyncPoint p1) { + if (p1 == null) { + return BigDecimal.ONE; + } + BigDecimal deltay = BigDecimal.valueOf(y.getValue() - p1.y.getValue()); + BigDecimal deltax = BigDecimal.valueOf(x.getValue() - p1.x.getValue()); + if (deltax.equals(BigDecimal.ZERO)) { + return BigDecimal.ONE; + } + return deltay.divide(deltax, fMc); + } + + /* + * Get the beta value (when x = 0) of the line given alpha + */ + public BigDecimal getBeta(BigDecimal alpha) { + return BigDecimal.valueOf(y.getValue()).subtract(alpha.multiply(BigDecimal.valueOf(x.getValue()), fMc)); + } + + @Override + public String toString() { + return String.format("%s (%s, %s)", this.getClass().getCanonicalName(), x, y); //$NON-NLS-1$ + } + } + + private void writeObject(ObjectOutputStream s) + throws IOException { + /* + * Remove the tree because it is not serializable + */ + fTree = null; + s.defaultWriteObject(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/TmfConstantTransform.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/TmfConstantTransform.java new file mode 100644 index 0000000000..da979b5517 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/TmfConstantTransform.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.synchronization; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform; +import org.eclipse.tracecompass.tmf.core.synchronization.TimestampTransformFactory; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp; + +/** + * Constant transform, just offset your timestamp with another. + * + * @author Matthew Khouzam + */ +public class TmfConstantTransform implements ITmfTimestampTransformInvertible { + + /** + * Serial ID + */ + private static final long serialVersionUID = 417299521984404532L; + private final long fOffset; + + /** + * Default constructor + */ + public TmfConstantTransform() { + // we really should be using an identity transform here. + fOffset = 0; + } + + /** + * Constructor with offset + * + * @param offset + * The offset of the linear transform in nanoseconds + */ + public TmfConstantTransform(long offset) { + fOffset = offset; + } + + /** + * Constructor with offset timestamp + * + * @param offset + * The offset of the linear transform + */ + public TmfConstantTransform(@NonNull ITmfTimestamp offset) { + this(new TmfNanoTimestamp(offset).getValue()); + } + + @Override + public ITmfTimestamp transform(ITmfTimestamp timestamp) { + return timestamp.normalize(fOffset, ITmfTimestamp.NANOSECOND_SCALE); + } + + /** + * {@inheritDoc} + * + * @param timestamp + * the timestamp in nanoseconds + * @return the timestamp in nanoseconds + */ + @Override + public long transform(long timestamp) { + return fOffset + timestamp; + } + + @Override + public ITmfTimestampTransform composeWith(ITmfTimestampTransform composeWith) { + if (composeWith.equals(TmfTimestampTransform.IDENTITY)) { + /* If composing with identity, just return this */ + return this; + } else if (composeWith instanceof TmfConstantTransform) { + TmfConstantTransform tct = (TmfConstantTransform) composeWith; + final long offset = fOffset + tct.fOffset; + if (offset == 0) { + return TmfTimestampTransform.IDENTITY; + } + return new TmfConstantTransform(offset); + } else if (composeWith instanceof TmfTimestampTransformLinear) { + throw new UnsupportedOperationException("Cannot compose a constant and linear transform yet"); //$NON-NLS-1$ + } else { + /* + * We do not know what to do with this kind of transform, just + * return this + */ + return this; + } + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("TmfConstantTransform [ offset = "); //$NON-NLS-1$ + builder.append(fOffset); + builder.append(" ]"); //$NON-NLS-1$ + return builder.toString(); + } + + @Override + public ITmfTimestampTransform inverse() { + return TimestampTransformFactory.createWithOffset(-1 * fOffset); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/TmfTimestampTransform.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/TmfTimestampTransform.java new file mode 100644 index 0000000000..655d88225a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/TmfTimestampTransform.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.synchronization; + +import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; + +/** + * A default simple, identity timestamp transform. It is a singleton class and + * returns the timestamp itself + * + * @author Geneviève Bastien + */ +public final class TmfTimestampTransform implements ITmfTimestampTransformInvertible { + + /** + * Generated serial UID + */ + private static final long serialVersionUID = -1480581417493073304L; + + /** + * The unique instance of this transform, since it is always the same + */ + public static final TmfTimestampTransform IDENTITY = new TmfTimestampTransform(); + + /** + * Default constructor + */ + private TmfTimestampTransform() { + + } + + @Override + public ITmfTimestamp transform(ITmfTimestamp timestamp) { + return timestamp; + } + + @Override + public long transform(long timestamp) { + return timestamp; + } + + @Override + public ITmfTimestampTransform composeWith(ITmfTimestampTransform composeWith) { + /* Since this transform will not modify anything, return the other */ + return composeWith; + } + + @Override + public boolean equals(Object other) { + return other.getClass().equals(TmfTimestampTransform.class); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = (prime * result) + TmfTimestampTransform.class.hashCode(); + return result; + } + + @Override + public String toString() { + return "TmfTimestampTransform [ IDENTITY ]"; //$NON-NLS-1$ + } + + @Override + public ITmfTimestampTransform inverse() { + return IDENTITY; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/TmfTimestampTransformLinear.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/TmfTimestampTransformLinear.java new file mode 100644 index 0000000000..8c88c29856 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/TmfTimestampTransformLinear.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.synchronization; + +import java.math.BigDecimal; +import java.math.MathContext; + +import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform; +import org.eclipse.tracecompass.tmf.core.synchronization.TimestampTransformFactory; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; + +/** + * Class implementing a linear timestamp transform, with a slope and/or offset + * + * f(t) = alpha*t + beta + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfTimestampTransformLinear implements ITmfTimestampTransformInvertible { + + /** + * Generated serial UID + */ + private static final long serialVersionUID = -4756608071358979461L; + + /** + * Respectively the slope and offset and this linear equation. + */ + private final BigDecimal fAlpha; + private final BigDecimal fBeta; + + private static final MathContext fMc = MathContext.DECIMAL128; + + /** + * Default constructor + */ + public TmfTimestampTransformLinear() { + fAlpha = BigDecimal.ONE; + fBeta = BigDecimal.ZERO; + } + + /** + * Constructor with alpha and beta + * + * @param alpha + * The slope of the linear transform + * @param beta + * The initial offset of the linear transform + */ + public TmfTimestampTransformLinear(final double alpha, final double beta) { + fAlpha = BigDecimal.valueOf(alpha); + fBeta = BigDecimal.valueOf(beta); + } + + /** + * Constructor with alpha and beta in big decimal + * + * @param fAlpha2 + * The slope of the linear transform + * @param fBeta2 + * The initial offset of the linear transform + */ + public TmfTimestampTransformLinear(final BigDecimal fAlpha2, final BigDecimal fBeta2) { + if (fAlpha2 != null) { + fAlpha = fAlpha2; + } else { + fAlpha = BigDecimal.ONE; + } + if (fBeta2 != null) { + fBeta = fBeta2; + } else { + fBeta = BigDecimal.ZERO; + } + } + + @Override + public ITmfTimestamp transform(ITmfTimestamp timestamp) { + BigDecimal newvalue = BigDecimal.valueOf(timestamp.getValue()).multiply(fAlpha, fMc).add(fBeta); + return new TmfTimestamp(timestamp, newvalue.longValue()); + } + + @Override + public long transform(long timestamp) { + BigDecimal t = BigDecimal.valueOf(timestamp).multiply(fAlpha, fMc).add(fBeta); + return t.longValue(); + } + + @Override + public ITmfTimestampTransform composeWith(ITmfTimestampTransform composeWith) { + if (composeWith.equals(TmfTimestampTransform.IDENTITY)) { + /* If composing with identity, just return this */ + return this; + } else if (composeWith instanceof TmfTimestampTransformLinear) { + /* If composeWith is a linear transform, add the two together */ + TmfTimestampTransformLinear ttl = (TmfTimestampTransformLinear) composeWith; + BigDecimal newAlpha = fAlpha.multiply(ttl.fAlpha, fMc); + BigDecimal newBeta = fAlpha.multiply(ttl.fBeta, fMc).add(fBeta); + return TimestampTransformFactory.createLinear(newAlpha, newBeta); + } else { + /* + * We do not know what to do with this kind of transform, just + * return this + */ + return this; + } + } + + @Override + public boolean equals(Object other) { + boolean result = false; + if (other instanceof TmfTimestampTransformLinear) { + TmfTimestampTransformLinear that = (TmfTimestampTransformLinear) other; + result = ((that.fAlpha.equals(fAlpha)) && (that.fBeta.equals(fBeta))); + } + return result; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = (prime * result) + (fBeta.multiply(fAlpha).intValue()); + return result; + } + + @Override + public String toString() { + return "TmfTimestampLinear [ slope = " + fAlpha.toString() + //$NON-NLS-1$ + ", offset = " + fBeta.toString() + //$NON-NLS-1$ + " ]"; //$NON-NLS-1$ + } + + @Override + public ITmfTimestampTransform inverse() { + return TimestampTransformFactory.createLinear(BigDecimal.ONE.divide(fAlpha, fMc), BigDecimal.valueOf(-1).multiply(fBeta).divide(fAlpha, fMc)); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/graph/Edge.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/graph/Edge.java new file mode 100644 index 0000000000..bc857b109a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/graph/Edge.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francis Giraldeau - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.synchronization.graph; + +/** + * An edge in the {@link SyncGraph} + * + * @author Francis Giraldeau + * @param + * The vertices type + * @param + * The edge annotation type + */ +public class Edge { + + private final V fFrom; + private final V fTo; + private final E fLabel; + + /** + * An edge constructor + * + * @param from + * The origin vertex + * @param to + * The destination vertex + * @param label + * The edge annotation label + */ + public Edge(V from, V to, E label) { + fFrom = from; + fTo = to; + fLabel = label; + } + + /** + * Get the vertex from + * + * @return The origin vertex + */ + public V getFrom() { + return fFrom; + } + + /** + * Get the vertex to + * + * @return The destination vertex + */ + public V getTo() { + return fTo; + } + + /** + * Get the edge label + * + * @return The edge label + */ + public E getLabel() { + return fLabel; + } + + @Override + public String toString() { + return String.format("(%s, %s, %s)", fFrom, fTo, fLabel); //$NON-NLS-1$ + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/graph/SyncGraph.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/graph/SyncGraph.java new file mode 100644 index 0000000000..2fb162ebf9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/graph/SyncGraph.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francis Giraldeau - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.synchronization.graph; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.Set; +import java.util.Stack; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; + +/** + * Minimal graph implementation to compute timestamps transforms of a trace from + * a given synchronized set of traces. The graph is implemented as an adjacency + * list and is directed. To create undirected graph, add the edge in both + * directions. + * + * @author Francis Giraldeau + * @param + * The vertices type + * @param + * The edge annotation type + */ +public class SyncGraph { + + private Multimap> fAdjacentEdges; + private Set fVertices; + + /** + * Construct empty graph + */ + public SyncGraph() { + fAdjacentEdges = ArrayListMultimap.create(); + fVertices = new HashSet<>(); + } + + /** + * Add edge from v to w and annotation label + * + * @param from + * from vertex + * @param to + * to vertex + * @param label + * the edge label + */ + public void addEdge(V from, V to, E label) { + fAdjacentEdges.put(from, new Edge<>(from, to, label)); + fVertices.add(from); + fVertices.add(to); + } + + /** + * Get the number of edges + * + * @return number of edges + */ + public int getNbEdges() { + return fAdjacentEdges.entries().size(); + } + + /** + * Get the number of vertices + * + * @return number of vertices + */ + public int getNbVertices() { + return fVertices.size(); + } + + /** + * Returns the adjacent edges of the given vertex + * + * @param v + * the vertex + * @return the adjacent vertices + */ + public Collection> getAdjacentEdges(V v) { + return fAdjacentEdges.get(v); + } + + /** + * Returns a path between start and end vertices. + * + * @param start + * vertex + * @param end + * vertex + * @return the list of edges between start and end vertices + */ + public List> path(V start, V end) { + ArrayList> path = new ArrayList<>(); + HashMap> hist = new HashMap<>(); + HashSet visited = new HashSet<>(); + Queue queue = new LinkedList<>(); + queue.offer(start); + /** + * Build the map of nodes reachable from the start node, by recursively + * visiting all accessible nodes. It is a breadth-first search, so the + * edges kept for each node will be the shortest path to that node. + */ + while (!queue.isEmpty()) { + V node = queue.poll(); + visited.add(node); + for (Edge e : getAdjacentEdges(node)) { + V to = e.getTo(); + if (!visited.contains(to)) { + queue.offer(e.getTo()); + if (!hist.containsKey(e.getTo())) { + hist.put(e.getTo(), e); + } + } + } + } + /* + * Find path from start to end by traversing the edges backward, from + * the end node + */ + V node = end; + Edge edge = hist.get(node); + while (edge != null && node != start) { + path.add(edge); + node = edge.getFrom(); + edge = hist.get(node); + } + Collections.reverse(path); + return path; + } + + /** + * Check if this graph is connected, ie there are no partitions, all + * vertices are reachable from every other one. It is a depth-first visit of + * all vertices reachable from the first vertex of the graph. + * + * @return true if the graph is connected, false otherwise + */ + public boolean isConnected() { + HashSet visited = new HashSet<>(); + Stack stack = new Stack<>(); + stack.push(fVertices.iterator().next()); + while (!stack.isEmpty()) { + V node = stack.pop(); + visited.add(node); + for (Edge edge : getAdjacentEdges(node)) { + if (!visited.contains(edge.getTo())) { + stack.push(edge.getTo()); + } + } + } + return visited.size() == fVertices.size(); + } + + @Override + public String toString() { + StringBuilder str = new StringBuilder(); + for (V key : fAdjacentEdges.keySet()) { + str.append(key + ": " + fAdjacentEdges.get(key) + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + } + return str.toString(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/graph/SyncSpanningTree.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/graph/SyncSpanningTree.java new file mode 100644 index 0000000000..e108e6caf8 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/synchronization/graph/SyncSpanningTree.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.synchronization.graph; + +import java.math.BigDecimal; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.eclipse.tracecompass.internal.tmf.core.synchronization.ITmfTimestampTransformInvertible; +import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform; +import org.eclipse.tracecompass.tmf.core.synchronization.TimestampTransformFactory; + +/** + * Implements a tree to calculate the synchronization between hosts + * + * TODO: This minimal implementation does not take into account the accuracy of + * the synchronization or the number of hops between 2 traces. A great + * improvement would be to implement Masoume Jabbarifar's minimal spanning tree + * algorithm to select reference trace(s) and optimal path to each node of the + * tree. + * + * @author Geneviève Bastien + */ +public class SyncSpanningTree { + + private final SyncGraph fSyncGraph; + + /* + * Using a TreeSet here to make sure the order of the hosts, and thus the + * reference node, is predictable, mostly for unit tests. + */ + private SortedSet fHosts = new TreeSet<>(); + + /** + * Default constructor + */ + public SyncSpanningTree() { + fSyncGraph = new SyncGraph<>(); + } + + /** + * Add a synchronization formula between hostFrom and hostTo with a given + * accuracy + * + * @param hostFrom + * Host from which the transform applies + * @param hostTo + * Host to which the transform applies + * @param transform + * The timestamp transform + * @param accuracy + * The accuracy of the synchronization between hostFrom and + * hostTo + */ + public void addSynchronization(String hostFrom, String hostTo, ITmfTimestampTransform transform, BigDecimal accuracy) { + fHosts.add(hostFrom); + fHosts.add(hostTo); + fSyncGraph.addEdge(hostFrom, hostTo, transform); + if (transform instanceof ITmfTimestampTransformInvertible) { + fSyncGraph.addEdge(hostTo, hostFrom, ((ITmfTimestampTransformInvertible) transform).inverse()); + } + } + + /** + * Get the timestamp transform to a host + * + * FIXME: This might not work in situations where we have disjoint graphs + * since we only calculate 1 root node and each tree has its own root. When + * implementing the algorithm with minimal spanning tree, we will solve this + * problem. + * + * @param host + * The host to reach + * @return The timestamp transform to host + */ + public ITmfTimestampTransform getTimestampTransform(String host) { + ITmfTimestampTransform result = TimestampTransformFactory.getDefaultTransform(); + String rootNode = getRootNode(); + /* + * Compute the path from reference node to the given host id + */ + if (rootNode != null) { + List> path = fSyncGraph.path(rootNode, host); + /* + * Compute the resulting transform by chaining each transforms on + * the path. + */ + for (Edge edge : path) { + result = result.composeWith(edge.getLabel()); + } + } + return result; + } + + private String getRootNode() { + /** + * Get the root node from which all other paths will be calculated. For + * now, we take the first node alphabetically. + */ + if (fHosts.size() == 0) { + return null; + } + return fHosts.first(); + } + + /** + * Check if this multi-host synchronization tree is connected, ie all nodes + * have a synchronization path to a reference node. + * + * @return true if the tree is connected, false otherwise + */ + public boolean isConnected() { + return fSyncGraph.isConnected(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/TmfExperimentCheckpoint.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/TmfExperimentCheckpoint.java new file mode 100644 index 0000000000..4c54d5e1ba --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/TmfExperimentCheckpoint.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.trace; + +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.TmfContext; + +/** + * TmfExperimentCheckpoint + *

+ * TODO: Implement me. Please. + */ +public class TmfExperimentCheckpoint implements Comparable { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final TmfTimestamp fTimestamp; + private final long[] fRanks; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * @param ts the checkpoint timestamp + * @param contexts the corresponding set of trace contexts + */ + public TmfExperimentCheckpoint(final TmfTimestamp ts, final TmfContext[] contexts) { + fTimestamp = ts; + fRanks = new long[contexts.length]; + for (int i = 0; i < fRanks.length; i++) { + fRanks[i] = contexts[i].getRank(); + } + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * @return the checkpoint event timestamp + */ + public TmfTimestamp getTimestamp() { + return fTimestamp; + } + + /** + * @return the checkpoint event rank + */ + public long[] getRanks() { + return fRanks; + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + int result = 37; + result = 17 * result + fTimestamp.hashCode(); + return result; + } + + @Override + public boolean equals(final Object other) { + if (!(other instanceof TmfExperimentCheckpoint)) { + return false; + } + final TmfExperimentCheckpoint o = (TmfExperimentCheckpoint) other; + return fTimestamp.equals(o.fTimestamp); + } + + // ------------------------------------------------------------------------ + // Comparable + // ------------------------------------------------------------------------ + + @Override + public int compareTo(final TmfExperimentCheckpoint other) { + return fTimestamp.compareTo(other.fTimestamp, false); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/TmfExperimentContext.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/TmfExperimentContext.java new file mode 100644 index 0000000000..f86e75f358 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/TmfExperimentContext.java @@ -0,0 +1,224 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Put in shape for 1.0 + * Patrick Tasse - Updated for removal of context clone + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.trace; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.TmfContext; + +/** + * The experiment context in TMF. + *

+ * The experiment keeps track of the next event from each of its traces so it + * can pick the next one in chronological order. + *

+ * This implies that the "next" event from each trace has already been + * read and that we at least know its timestamp. + *

+ * The last trace refers to the trace from which the last event was "consumed" + * at the experiment level. + */ +public final class TmfExperimentContext extends TmfContext { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * No last trace read indicator + */ + public static final int NO_TRACE = -1; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final List fContexts; + private final List fEvents; + private int fLastTraceRead; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Standard constructor + * + * @param nbTraces + * The number of traces in the experiment + */ + public TmfExperimentContext(final int nbTraces) { + super(); + fLastTraceRead = NO_TRACE; + fContexts = new ArrayList<>(nbTraces); + fEvents = new ArrayList<>(nbTraces); + + + /* Initialize the arrays to the requested size */ + for (int i = 0; i < nbTraces; i++) { + fContexts.add(null); + fEvents.add(null); + } + } + + @Override + public void dispose() { + for (ITmfContext context : fContexts) { + context.dispose(); + } + super.dispose(); + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * Return how many traces this experiment context tracks the contexts of + * (a.k.a., the number of traces in the experiment). + * + * @return The number of traces in the experiment + */ + public int getNbTraces() { + return fContexts.size(); + } + + /** + * Get the current context of a specific trace + * + * @param traceIndex + * The index of the trace in the experiment + * @return The matching context object for that trace + */ + @Nullable + public ITmfContext getContext(int traceIndex) { + return fContexts.get(traceIndex); + } + + /** + * Set the context of a trace + * + * @param traceIndex + * The index of the trace in the experiment + * @param ctx + * The new context object for that trace + */ + public void setContext(int traceIndex, ITmfContext ctx) { + fContexts.set(traceIndex, ctx); + } + + /** + * Get the current event for a specific trace in the experiment. + * + * @param traceIndex + * The index of the trace in the experiment + * @return The event matching the trace/context + * + */ + @Nullable + public ITmfEvent getEvent(int traceIndex) { + return fEvents.get(traceIndex); + } + + /** + * Set the context's event for a specific trace + * + * @param traceIndex + * The index of the trace in the experiment + * @param event + * The event at the context in the trace + */ + public void setEvent(int traceIndex, ITmfEvent event) { + fEvents.set(traceIndex, event); + } + + /** + * Get the index of the trace that was last read (so the trace whose + * current context will match this experiment's). + * + * @return The index of the trace + */ + public int getLastTrace() { + return fLastTraceRead; + } + + /** + * Set the last trace read index + * + * @param newIndex + * The new value to assign + */ + public void setLastTrace(final int newIndex) { + fLastTraceRead = newIndex; + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + int result = 17; + for (int i = 0; i < fContexts.size(); i++) { + result = 37 * result + fContexts.get(i).hashCode(); + } + return result; + } + + @Override + public boolean equals(final Object other) { + if (this == other) { + return true; + } + if (!super.equals(other)) { + return false; + } + if (!(other instanceof TmfExperimentContext)) { + return false; + } + final TmfExperimentContext o = (TmfExperimentContext) other; + boolean isEqual = true; + int i = 0; + while (isEqual && (i < fContexts.size())) { + isEqual &= fContexts.get(i).equals(o.fContexts.get(i)); + i++; + } + return isEqual; + } + + @Override + @SuppressWarnings("nls") + public String toString() { + StringBuilder sb = new StringBuilder("TmfExperimentContext [\n"); + sb.append("\tfLocation=" + getLocation() + ", fRank=" + getRank() + "\n"); + sb.append("\tfContexts=["); + for (int i = 0; i < fContexts.size(); i++) { + sb.append("(" + fContexts.get(i).getLocation() + "," + fContexts.get(i).getRank() + ((i < fContexts.size() - 1) ? ")," : ")]\n")); + } + sb.append("\tfEvents=["); + for (int i = 0; i < fEvents.size(); i++) { + ITmfEvent event = fEvents.get(i); + sb.append(((event != null) ? fEvents.get(i).getTimestamp() : "(null)") + ((i < fEvents.size() - 1) ? "," : "]\n")); + } + sb.append("\tfLastTraceRead=" + fLastTraceRead + "\n"); + sb.append("]"); + return sb.toString(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/TmfExperimentLocation.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/TmfExperimentLocation.java new file mode 100644 index 0000000000..1eb150b12d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/TmfExperimentLocation.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Updated as per TMF Trace Model 1.0 + * Patrick Tasse - Updated for ranks in experiment location + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.trace; + +import java.nio.ByteBuffer; + +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + + +/** + * The experiment location in TMF. + *

+ * An experiment location is actually the set of locations of the traces it + * contains. By setting the individual traces to their corresponding locations, + * the experiment can be positioned to read the next chronological event. + *

+ * It is the responsibility of the user the individual trace locations are valid + * and that they are matched to the correct trace. + * + * @version 1.0 + * @author Francois Chouinard + * + * @see TmfLocationArray + */ +public final class TmfExperimentLocation implements ITmfLocation { + + private final TmfLocationArray fLocation; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * The standard constructor + * + * @param locations the set of trace locations + */ + public TmfExperimentLocation(TmfLocationArray locations) { + fLocation = locations; + } + + /** + * The copy constructor + * + * @param location the other experiment location + */ + public TmfExperimentLocation(TmfExperimentLocation location) { + this(location.getLocationInfo()); + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + @SuppressWarnings("nls") + public String toString() { + StringBuilder result = new StringBuilder("TmfExperimentLocation ["); + result.append(fLocation.toString()); + result.append("]"); + return result.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((fLocation != null) ? fLocation.hashCode() : 0); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final TmfExperimentLocation other = (TmfExperimentLocation) obj; + if (fLocation == null) { + if (other.fLocation != null) { + return false; + } + } else if (!fLocation.equals(other.fLocation)) { + return false; + } + return true; + } + + @Override + public TmfLocationArray getLocationInfo() { + return fLocation; + } + + @Override + public void serialize(ByteBuffer bufferOut) { + ITmfLocation[] locations = fLocation.getLocations(); + long[] ranks = fLocation.getRanks(); + for (int i = 0; i < locations.length; ++i) { + locations[i].serialize(bufferOut); + bufferOut.putLong(ranks[i]); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/TmfLocationArray.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/TmfLocationArray.java new file mode 100644 index 0000000000..f67ea9ec8c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/TmfLocationArray.java @@ -0,0 +1,204 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Francois Chouinard - Put in shape for 1.0 + * Patrick Tasse - Updated for ranks in experiment location + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.trace; + +import java.util.Arrays; + +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + + +/** + * A convenience class to store trace location arrays. The main purpose is to + * provide an immutable and Comparable implementation for TmfExperimentLocation. + * + * @version 1.0 + * @author Patrick Tasse + */ +public final class TmfLocationArray implements Comparable { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final ITmfLocation[] fLocations; + private final long [] fRanks; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * The standard constructor. + * + * @param locations the locations + * @param ranks the ranks + */ + public TmfLocationArray(ITmfLocation[] locations, long[] ranks) { + fLocations = Arrays.copyOf(locations, locations.length); + fRanks = Arrays.copyOf(ranks, ranks.length); + } + + /** + * The update constructor. Copies the arrays and updates a single entry. + * + * @param locationArray the location array + * @param index the updated index + * @param location the updated location + * @param rank the updated rank + */ + public TmfLocationArray(TmfLocationArray locationArray, int index, ITmfLocation location, long rank) { + fLocations = Arrays.copyOf(locationArray.fLocations, locationArray.fLocations.length); + fLocations[index] = location; + fRanks = Arrays.copyOf(locationArray.fRanks, locationArray.fRanks.length); + fRanks[index] = rank; + } + + /** + * The empty constructor. + * + * @param size the number of elements in the array + */ + public TmfLocationArray(int size) { + fLocations = new ITmfLocation[size]; + fRanks = new long[size]; + } + + // ------------------------------------------------------------------------ + // Getters + // ------------------------------------------------------------------------ + + /** + * Returns the number of elements in this array. + * + * @return the number of elements in this array + */ + public int size() { + return fLocations.length; + } + + /** + * Get the locations inside this array. + * + * @return a copy of the locations array + */ + public ITmfLocation[] getLocations() { + return Arrays.copyOf(fLocations, fLocations.length); + } + + /** + * Get a specific location + * + * @param index the location element + * + * @return the specific location (possibly null) + */ + public ITmfLocation getLocation(int index) { + if (index >= 0 && index < fLocations.length) { + return fLocations[index]; + } + return null; + } + + /** + * Get the ranks inside this array. + * + * @return a copy of the ranks array + */ + public long[] getRanks() { + return Arrays.copyOf(fRanks, fRanks.length); + } + + /** + * Get a specific rank + * + * @param index the rank element + * + * @return the specific rank + */ + public long getRank(int index) { + if (index >= 0 && index < fRanks.length) { + return fRanks[index]; + } + return 0; + } + + // ------------------------------------------------------------------------ + // Comparable + // ------------------------------------------------------------------------ + + @Override + public int compareTo(TmfLocationArray o) { + for (int i = 0; i < fRanks.length; i++) { + long rank1 = fRanks[i]; + long rank2 = o.fRanks[i]; + if (rank1 < rank2) { + return -1; + } else if (rank1 > rank2) { + return 1; + } + } + return 0; + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(fLocations); + result = prime * result + Arrays.hashCode(fRanks); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TmfLocationArray other = (TmfLocationArray) obj; + if (!Arrays.equals(fLocations, other.fLocations)) { + return false; + } + if (!Arrays.equals(fRanks, other.fRanks)) { + return false; + } + return true; + } + + @Override + @SuppressWarnings("nls") + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getSimpleName() + " ["); + for (int i = 0; i < fLocations.length; i++) { + if (i > 0) { + sb.append(", "); + } + sb.append("[location=" + fLocations[i] + ",rank=" + fRanks[i] + "]"); + } + sb.append("]"); + return sb.toString(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/AbstractFileCheckpointCollection.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/AbstractFileCheckpointCollection.java new file mode 100644 index 0000000000..c21a433960 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/AbstractFileCheckpointCollection.java @@ -0,0 +1,478 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.trace.indexer; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.text.MessageFormat; + +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfPersistentlyIndexable; + +/** + * Common implementation of file-based checkpoint collection + * + * @author Marc-Andre Laperle + */ +public abstract class AbstractFileCheckpointCollection implements ICheckpointCollection { + + private static final int VERSION = 1; + private static final int SUB_VERSION_NONE = -1; + + /** + * The base file header, can be extended + */ + protected class CheckpointCollectionFileHeader { + private final static int SIZE = INT_SIZE + + INT_SIZE + + LONG_SIZE + + LONG_SIZE; + + /** + * Get the size of the header in bytes. This should be overridden if the + * header is augmented with more data + * + * @return the size of the header in bytes + */ + public int getSize() { + return SIZE; + } + + /** + * Get the sub version of this header + * + * @return the sub version + */ + public int getSubVersion() { + return SUB_VERSION_NONE; + } + + /** + * Constructs a new file header for an existing file + * + * @param randomAccessFile + * the existing file + * @throws IOException + * if an I/O error occurs reading from the file + */ + public CheckpointCollectionFileHeader(RandomAccessFile randomAccessFile) throws IOException { + fVersion = randomAccessFile.readInt(); + fSize = randomAccessFile.readInt(); + fNbEvents = randomAccessFile.readLong(); + fTimeRangeOffset = randomAccessFile.readLong(); + } + + /** + * Constructs a new file header for the given version + * + * @param version + * the version + */ + public CheckpointCollectionFileHeader(int version) { + fVersion = version; + } + + /** + * Serialize the header to a file + * + * @param randomAccessFile + * the existing file + * @throws IOException + * if an I/O error occurs writing to the file + */ + public void serialize(RandomAccessFile randomAccessFile) throws IOException { + randomAccessFile.seek(0); + randomAccessFile.writeInt(getVersion()); + randomAccessFile.writeInt(fSize); + randomAccessFile.writeLong(fNbEvents); + randomAccessFile.writeLong(fTimeRangeOffset); + } + + /** + * The version of the collection. Should be incremented if a binary + * incompatible change occurs. + */ + protected final int fVersion; + /** + * The size of the collection expressed in a number of checkpoints. + */ + protected int fSize = 0; + /** + * Offset in bytes where the time range is store + */ + protected long fTimeRangeOffset; + /** + * The total number of events in the trace + */ + protected long fNbEvents; + } + + /** + * The size of an int in bytes + */ + protected static final int INT_SIZE = 4; + /** + * The size of a long in bytes + */ + protected static final int LONG_SIZE = 8; + + /** + * The maximum size of the serialize buffer when writing the time range + */ + protected static final int MAX_TIME_RANGE_SERIALIZE_SIZE = 1024; + + /** + * The originating trace + */ + private ITmfPersistentlyIndexable fTrace; + + private long fCacheMisses = 0; + private boolean fCreatedFromScratch; + + /** + * File handle for the file being read/written + */ + private RandomAccessFile fRandomAccessFile; + /** + * File handle for the file being read/written + */ + private File fFile; + + /** + * The base file header + */ + private final CheckpointCollectionFileHeader fHeader; + + // Cached values + private FileChannel fFileChannel; + private TmfTimeRange fTimeRange; + + /** + * Constructs a checkpoint collection for a given trace from scratch or from + * an existing file. When the checkpoint collection is created from scratch, + * it is populated by subsequent calls to {@link #insert}. + * + * @param file + * the file to use as the persistent storage + * @param trace + * the trace + */ + public AbstractFileCheckpointCollection(File file, ITmfPersistentlyIndexable trace) { + fTrace = trace; + fFile = file; + setCreatedFromScratch(!fFile.exists()); + + CheckpointCollectionFileHeader header = null; + + if (!isCreatedFromScratch()) { + header = tryRestore(); + if (header == null) { + fFile.delete(); + dispose(); + } + } + + if (isCreatedFromScratch()) { + header = initialize(); + } + + fHeader = header; + } + + /** + * Creates a new basic file header with the version field initialized. This + * should be overridden if the file header is extended + * + * @return the created file header + */ + protected CheckpointCollectionFileHeader createHeader() { + return new CheckpointCollectionFileHeader(VERSION); + } + + /** + * Creates a new basic file header for an existing file. This should be + * overridden if the file header is extended + * + * @param randomAccessFile + * the existing file + * @return the created file header + * @throws IOException + * if an I/O error occurs reading from the file + */ + protected CheckpointCollectionFileHeader createHeader(RandomAccessFile randomAccessFile) throws IOException { + return new CheckpointCollectionFileHeader(randomAccessFile); + } + + /** + * Get the version of the collection. + * + * @return the version of the collection. + */ + protected int getVersion() { + return VERSION; + } + + /** + * Get the sub version of the collection. + * + * @return the sub version of the collection. + */ + protected int getSubVersion() { + return SUB_VERSION_NONE; + } + + private CheckpointCollectionFileHeader initialize() { + CheckpointCollectionFileHeader header = null; + try { + fRandomAccessFile = new RandomAccessFile(fFile, "rw"); //$NON-NLS-1$ + fFileChannel = fRandomAccessFile.getChannel(); + header = createHeader(); + + // Reserve space for header + fRandomAccessFile.setLength(header.getSize()); + + fTimeRange = new TmfTimeRange(new TmfTimestamp(0), new TmfTimestamp(0)); + } catch (IOException e) { + Activator.logError(MessageFormat.format(Messages.ErrorOpeningIndex, fFile), e); + return null; + } + + return header; + } + + /** + * Try to restore the index from disk. Try to open the file and check the + * version. Returns the loaded header or null if it could not be loaded. + * + * @return the loaded header or null if it could not be loaded. + */ + private CheckpointCollectionFileHeader tryRestore() { + CheckpointCollectionFileHeader header = null; + + try { + fRandomAccessFile = new RandomAccessFile(fFile, "r"); //$NON-NLS-1$ + fFileChannel = fRandomAccessFile.getChannel(); + } catch (FileNotFoundException e) { + Activator.logError(MessageFormat.format(Messages.ErrorOpeningIndex, fFile), e); + return null; + } + + try { + header = createHeader(fRandomAccessFile); + if (header.fVersion != VERSION || header.getSubVersion() != getSubVersion()) { + return null; + } + serializeInTimeRange(header); + } catch (IOException e) { + Activator.logError(MessageFormat.format(Messages.IOErrorReadingHeader, fFile), e); + return null; + } + + return header; + } + + private void serializeInTimeRange(CheckpointCollectionFileHeader header) throws IOException { + ByteBuffer b = ByteBuffer.allocate(MAX_TIME_RANGE_SERIALIZE_SIZE); + b.clear(); + fFileChannel.read(b, header.fTimeRangeOffset); + b.flip(); + fTimeRange = new TmfTimeRange(new TmfTimestamp(b), new TmfTimestamp(b)); + } + + private void serializeOutTimeRange() throws IOException { + fHeader.fTimeRangeOffset = fRandomAccessFile.length(); + ByteBuffer b = ByteBuffer.allocate(MAX_TIME_RANGE_SERIALIZE_SIZE); + b.clear(); + new TmfTimestamp(fTimeRange.getStartTime()).serialize(b); + new TmfTimestamp(fTimeRange.getEndTime()).serialize(b); + b.flip(); + fFileChannel.write(b, fHeader.fTimeRangeOffset); + } + + /** + * Set the index as complete. No more checkpoints will be inserted. + */ + @Override + public void setIndexComplete() { + try { + serializeOutTimeRange(); + + fHeader.serialize(fRandomAccessFile); + } catch (IOException e) { + Activator.logError(MessageFormat.format(Messages.IOErrorWritingHeader, fFile), e); + } + } + + /** + * + * @return true if the checkpoint collection was created from scratch, false + * otherwise + */ + @Override + public boolean isCreatedFromScratch() { + return fCreatedFromScratch; + } + + /** + * Set whether or not the collection is created from scratch + * + * @param isCreatedFromScratch + * whether or not the collection is created from scratch + */ + protected void setCreatedFromScratch(boolean isCreatedFromScratch) { + fCreatedFromScratch = isCreatedFromScratch; + } + + /** + * @return the number of cache misses. + */ + public long getCacheMisses() { + return fCacheMisses; + } + + /** + * Increment the number of cache misses. + */ + protected void incCacheMisses() { + ++fCacheMisses; + } + + /** + * Returns the size of the checkpoint collection expressed as a number of + * checkpoints. + * + * @return the size of the checkpoint collection + */ + @Override + public int size() { + return fHeader.fSize; + } + + /** + * Set the trace time range + * + * @param timeRange + * the trace time range + */ + @Override + public void setTimeRange(TmfTimeRange timeRange) { + fTimeRange = timeRange; + } + + /** + * Get the trace time range + * + * @return the trace time range + */ + @Override + public TmfTimeRange getTimeRange() { + return fTimeRange; + } + + /** + * Set the number of events in the trace + * + * @param nbEvents + * the number of events in the trace + */ + @Override + public void setNbEvents(long nbEvents) { + fHeader.fNbEvents = nbEvents; + } + + /** + * Get the number of events in the trace + * + * @return the number of events in the trace + */ + @Override + public long getNbEvents() { + return fHeader.fNbEvents; + } + + /** + * Get the trace + * + * @return the trace + */ + protected ITmfPersistentlyIndexable getTrace() { + return fTrace; + } + + /** + * Get the random access file currently opened + * + * @return the file + */ + protected RandomAccessFile getRandomAccessFile() { + return fRandomAccessFile; + } + + /** + * Get the file channel currently used for the index + * + * @return the file channel + */ + protected FileChannel getFileChannel() { + return fRandomAccessFile.getChannel(); + } + + /** + * Get the file handle for the index + * + * @return the file + */ + protected File getFile() { + return fFile; + } + + /** + * Get the header for this collection + * + * @return the header + */ + public CheckpointCollectionFileHeader getHeader() { + return fHeader; + }/** + * Dispose and delete the checkpoint collection + */ + @Override + public void delete() { + dispose(); + if (fFile.exists()) { + fFile.delete(); + } + } + + /** + * Dispose the collection and its resources + */ + @Override + public void dispose() { + try { + if (fRandomAccessFile != null) { + fRandomAccessFile.close(); + } + setCreatedFromScratch(true); + fRandomAccessFile = null; + } catch (IOException e) { + Activator.logError(MessageFormat.format(Messages.IOErrorClosingIndex, fFile), e); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/BTree.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/BTree.java new file mode 100644 index 0000000000..fc21025377 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/BTree.java @@ -0,0 +1,383 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.trace.indexer; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.text.MessageFormat; + +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfPersistentlyIndexable; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; + +/** + * A BTree made of BTreeNodes representing a series of ITmfCheckpoints ordered + * by time stamps. {@link BTreeNodeCache } is used to improve performance by + * caching some nodes in memory and the other nodes are kept on disk. + * + * @author Marc-Andre Laperle + */ +public class BTree extends AbstractFileCheckpointCollection { + + /** + * Typical BTree file name + */ + public static final String INDEX_FILE_NAME = "checkpoint_btree.idx"; //$NON-NLS-1$ + private static final int SUB_VERSION = 4; + private static final boolean ALWAYS_CACHE_ROOT = true; + + private final int fMaxNumEntries; + private final int fMaxNumChildren; + private final int fMedianEntry; + + private BTreeHeader fBTreeHeader; + + // Cached values + private int nodeSize = -1; + private final ByteBuffer fNodeByteBuffer; + private final BTreeNodeCache fNodeCache; + + private class BTreeHeader extends CheckpointCollectionFileHeader { + private static final int SIZE = LONG_SIZE + INT_SIZE; + private long fRoot; + private final int fSubVersion; + + private BTreeHeader(int version, int subVersion) { + super(version); + fSubVersion = subVersion; + } + + private BTreeHeader(RandomAccessFile randomAccessFile) throws IOException { + super(randomAccessFile); + + fRoot = randomAccessFile.readLong(); + fSubVersion = randomAccessFile.readInt(); + } + + @Override + public int getSubVersion() { + return fSubVersion; + } + + @Override + public int getSize() { + return SIZE + super.getSize(); + } + + @Override + public void serialize(RandomAccessFile randomAccessFile) throws IOException { + super.serialize(randomAccessFile); + + randomAccessFile.writeLong(fRoot); + randomAccessFile.writeInt(fSubVersion); + } + } + + @Override + protected CheckpointCollectionFileHeader createHeader() { + fBTreeHeader = new BTreeHeader(getVersion(), SUB_VERSION); + return fBTreeHeader; + } + + @Override + protected CheckpointCollectionFileHeader createHeader(RandomAccessFile randomAccessFile) throws IOException { + fBTreeHeader = new BTreeHeader(randomAccessFile); + return fBTreeHeader; + } + + @Override + protected int getSubVersion() { + return SUB_VERSION; + } + + /** + * Constructs a BTree for a given trace from scratch or from an existing + * file. The degree is used to calibrate the number of entries in each node + * which can affect performance. When the BTree is created from scratch, it + * is populated by subsequent calls to {@link #insert}. + * + * @param degree + * the degree to use in the tree + * @param file + * the file to use as the persistent storage + * @param trace + * the trace + */ + public BTree(int degree, File file, ITmfPersistentlyIndexable trace) { + super(file, trace); + + fMaxNumEntries = 2 * degree - 1; + fMaxNumChildren = 2 * degree; + fMedianEntry = degree - 1; + + fNodeByteBuffer = ByteBuffer.allocate(getNodeSize()); + fNodeByteBuffer.clear(); + fNodeCache = new BTreeNodeCache(this); + BTreeNode rootNode = isCreatedFromScratch() ? allocateNode() : fNodeCache.getNode(fBTreeHeader.fRoot); + setRootNode(rootNode); + } + + /** + * Insert a checkpoint into the file-backed BTree + * + * @param checkpoint + * the checkpoint to insert + */ + @Override + public void insert(ITmfCheckpoint checkpoint) { + insert(checkpoint, fBTreeHeader.fRoot, null, 0); + } + + private void setRootNode(BTreeNode newRootNode) { + fBTreeHeader.fRoot = newRootNode.getOffset(); + if (ALWAYS_CACHE_ROOT) { + fNodeCache.setRootNode(newRootNode); + } else { + fNodeCache.addNode(newRootNode); + } + } + + private void insert(ITmfCheckpoint checkpoint, long nodeOffset, BTreeNode pParent, int iParent) { + BTreeNode parent = pParent; + BTreeNode node = fNodeCache.getNode(nodeOffset); + + // If this node is full (last entry isn't null), split it + if (node.getEntry(fMaxNumEntries - 1) != null) { + + ITmfCheckpoint median = node.getEntry(fMedianEntry); + if (median.compareTo(checkpoint) == 0) { + // Found it + return; + } + + // Split it. + // Create the new node and move the larger entries over. + BTreeNode newnode = allocateNode(); + fNodeCache.addNode(newnode); + long newNodeOffset = newnode.getOffset(); + for (int i = 0; i < fMedianEntry; ++i) { + newnode.setEntry(i, node.getEntry(fMedianEntry + 1 + i)); + node.setEntry(fMedianEntry + 1 + i, null); + newnode.setChild(i, node.getChild(fMedianEntry + 1 + i)); + node.setChild(fMedianEntry + 1 + i, BTreeNode.NULL_CHILD); + } + newnode.setChild(fMedianEntry, node.getChild(fMaxNumEntries)); + node.setChild(fMaxNumEntries, BTreeNode.NULL_CHILD); + + if (parent == null) { + parent = allocateNode(); + setRootNode(parent); + parent.setChild(0, nodeOffset); + } else { + // Insert the median into the parent. + for (int i = fMaxNumEntries - 2; i >= iParent; --i) { + ITmfCheckpoint r = parent.getEntry(i); + if (r != null) { + parent.setEntry(i + 1, r); + parent.setChild(i + 2, parent.getChild(i + 1)); + } + } + } + + fNodeCache.getNode(parent.getOffset()); + + parent.setEntry(iParent, median); + parent.setChild(iParent + 1, newNodeOffset); + + node.setEntry(fMedianEntry, null); + + // Set the node to the correct one to follow. + if (checkpoint.compareTo(median) > 0) { + node = newnode; + } + } + + // Binary search to find the insert point. + int lower = 0; + int upper = fMaxNumEntries - 1; + while (lower < upper && node.getEntry(upper - 1) == null) { + upper--; + } + + while (lower < upper) { + int middle = (lower + upper) / 2; + ITmfCheckpoint check = node.getEntry(middle); + if (check == null) { + upper = middle; + } else { + int compare = check.compareTo(checkpoint); + if (compare > 0) { + upper = middle; + } else if (compare < 0) { + lower = middle + 1; + } else { + // Found it, no insert + return; + } + } + } + final int i = lower; + long child = node.getChild(i); + if (child != BTreeNode.NULL_CHILD) { + // Visit the children. + insert(checkpoint, child, node, i); + } else { + // We are at the leaf, add us in. + // First copy everything after over one. + for (int j = fMaxNumEntries - 2; j >= i; --j) { + ITmfCheckpoint r = node.getEntry(j); + if (r != null) { + node.setEntry(j + 1, r); + } + } + node.setEntry(i, checkpoint); + return; + } + } + + int getNodeSize() { + if (nodeSize == -1) { + nodeSize = INT_SIZE; // num entries + nodeSize += getTrace().getCheckpointSize() * fMaxNumEntries; + nodeSize += LONG_SIZE * fMaxNumChildren; + } + + return nodeSize; + } + + private BTreeNode allocateNode() { + try { + long offset = getRandomAccessFile().length(); + getRandomAccessFile().setLength(offset + getNodeSize()); + BTreeNode node = new BTreeNode(this, offset); + return node; + } catch (IOException e) { + Activator.logError(MessageFormat.format(Messages.BTree_IOErrorAllocatingNode, getFile()), e); + } + return null; + } + + @Override + public long binarySearch(ITmfCheckpoint checkpoint) { + BTreeCheckpointVisitor v = new BTreeCheckpointVisitor(checkpoint); + accept(v); + return v.getCheckpointRank(); + } + + /** + * Accept a visitor. This visitor is used to search through the whole tree. + * + * @param treeVisitor + * the visitor to accept + */ + public void accept(IBTreeVisitor treeVisitor) { + accept(fBTreeHeader.fRoot, treeVisitor); + } + + private void accept(long nodeOffset, IBTreeVisitor visitor) { + + if (nodeOffset == BTreeNode.NULL_CHILD) { + return; + } + + BTreeNode node = fNodeCache.getNode(nodeOffset); + + // Binary search to find first entry greater or equal. + int lower = 0; + int upper = fMaxNumEntries - 1; + while (lower < upper && node.getEntry(upper - 1) == null) { + upper--; + } + while (lower < upper) { + int middle = (lower + upper) / 2; + ITmfCheckpoint middleCheckpoint = node.getEntry(middle); + if (middleCheckpoint == null) { + upper = middle; + } else { + int compare = visitor.compare(middleCheckpoint); + if (compare == 0) { + return; + } else if (compare > 0) { + upper = middle; + } else { + lower = middle + 1; + } + } + } + + // Start with first record greater or equal, reuse comparison + // results. + int i = lower; + for (; i < fMaxNumEntries; ++i) { + ITmfCheckpoint record = node.getEntry(i); + if (record == null) { + break; + } + + int compare = visitor.compare(record); + if (compare > 0) { + // Start point is to the left. + accept(node.getChild(i), visitor); + return; + } else if (compare == 0) { + return; + } + } + accept(node.getChild(i), visitor); + return; + } + + /** + * Set the index as complete. No more checkpoints will be inserted. + */ + @Override + public void setIndexComplete() { + super.setIndexComplete(); + + fNodeCache.serialize(); + } + + /** + * Get the maximum number of entries in a node + * + * @return the maximum number of entries in a node + */ + int getMaxNumEntries() { + return fMaxNumEntries; + } + + /** + * Set the size of the BTree, expressed as a number of checkpoints + * + * @param size + * the size of the BTree + */ + public void setSize(int size) { + fBTreeHeader.fSize = size; + } + + /** + * Get the maximum number of children in a node + * + * @return the maximum number of children in a node + */ + int getMaxNumChildren() { + return fMaxNumChildren; + } + + ByteBuffer getNodeByteBuffer() { + return fNodeByteBuffer; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/BTreeCheckpointVisitor.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/BTreeCheckpointVisitor.java new file mode 100644 index 0000000000..e8b06f0c63 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/BTreeCheckpointVisitor.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.trace.indexer; + +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; + +/** + * A visitor that searches for a specific checkpoint + * + * @author Marc-Andre Laperle + */ +public class BTreeCheckpointVisitor implements IBTreeVisitor { + + private long rank = -1; + private ITmfCheckpoint found; + private ITmfCheckpoint search; + private boolean exactFound = false; + + /** + * Constructs the checkpoint visitor + * + * @param search + * the checkpoint to search for + */ + public BTreeCheckpointVisitor(ITmfCheckpoint search) { + this.search = search; + } + + @Override + public int compare(ITmfCheckpoint currentCheckpoint) { + int compareTo = currentCheckpoint.compareTo(search); + if (compareTo <= 0 && !exactFound) { + rank = currentCheckpoint.getCheckpointRank(); + found = currentCheckpoint; + if (compareTo == 0) { + exactFound = true; + } + } + return compareTo; + } + + /** + * Return the found checkpoint + * + * @return the found checkpoint + */ + public ITmfCheckpoint getCheckpoint() { + return found; + } + + /** + * Returns the checkpoint rank of the searched checkpoint, if it is + * contained in the index; otherwise, (-(insertion point) - 1). + * + * @return the checkpoint rank of the searched checkpoint, if it is + * contained in the index; otherwise, (-(insertion point) - 1). + */ + public long getCheckpointRank() { + if (!exactFound) { + long insertionPoint = rank + 1; + return -insertionPoint - 1; + } + + return rank; + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/BTreeNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/BTreeNode.java new file mode 100644 index 0000000000..8cdb2f0661 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/BTreeNode.java @@ -0,0 +1,204 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.trace.indexer; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.text.MessageFormat; +import java.util.Arrays; + +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +/** + * A node in the BTree. A node contains entries and pointers to other nodes. + * The layout can be illustrated like this: + * + * | + * ___________Node__________ + * | e | e | e | e | + * p p p p p + * | + * | + * Node ... + * + * Where e is an entry, p is a pointer to another node. + * + * A pointer on the left side of an entry points to a node containing entries + * that are of lesser value than the entry and a pointer on the right side of + * an entry points to a node containing entries that are of greater value + * than the entry. In this implementation, entries are ITmfCheckpoints and + * pointers are file offsets (long). + * + * @author Marc-Andre Laperle + */ +class BTreeNode { + + /** + * Integer to represent a null child + */ + static final int NULL_CHILD = -1; + + private final ITmfCheckpoint fEntries[]; + private final long fChildrenFileOffsets[]; + private final long fFileOffset; + private final BTree fTree; + + private int fNumEntries = 0; + private boolean fIsDirty = false; + + /** + * Construct a node for the specified tree for the specified file offset + * + * @param tree + * the BTree + * @param offset + * the file offset + */ + BTreeNode(BTree tree, long offset) { + fTree = tree; + fFileOffset = offset; + fEntries = new ITmfCheckpoint[fTree.getMaxNumEntries()]; + fChildrenFileOffsets = new long[fTree.getMaxNumChildren()]; + Arrays.fill(fChildrenFileOffsets, NULL_CHILD); + } + + /** + * Get the file offset for this node + * + * @return the file offset + */ + long getOffset() { + return fFileOffset; + } + + /** + * Read the node data from disk + */ + void serializeIn() { + try { + fTree.getRandomAccessFile().seek(fFileOffset); + + ByteBuffer bb; + bb = fTree.getNodeByteBuffer(); + bb.clear(); + fTree.getRandomAccessFile().read(bb.array()); + + for (int i = 0; i < fTree.getMaxNumChildren(); ++i) { + fChildrenFileOffsets[i] = bb.getLong(); + } + fNumEntries = bb.getInt(); + + for (int i = 0; i < fNumEntries; ++i) { + + ITmfLocation location = fTree.getTrace().restoreLocation(bb); + ITmfTimestamp timeStamp = new TmfTimestamp(bb); + TmfCheckpoint c = new TmfCheckpoint(timeStamp, location, bb); + fEntries[i] = c; + } + + } catch (IOException e) { + Activator.logError(MessageFormat.format(Messages.BTreeNode_IOErrorLoading, fFileOffset, fTree.getRandomAccessFile()), e); + } + } + + /** + * Write the node data to disk + */ + void serializeOut() { + try { + fTree.getRandomAccessFile().seek(fFileOffset); + + ByteBuffer bb = fTree.getNodeByteBuffer(); + bb.clear(); + + for (int i = 0; i < fTree.getMaxNumChildren(); ++i) { + bb.putLong(fChildrenFileOffsets[i]); + } + bb.putInt(fNumEntries); + + for (int i = 0; i < fNumEntries; ++i) { + ITmfCheckpoint key = fEntries[i]; + key.serialize(bb); + } + + fTree.getRandomAccessFile().write(bb.array()); + + fIsDirty = false; + } catch (IOException e) { + Activator.logError(MessageFormat.format(Messages.BTreeNode_IOErrorWriting, fFileOffset, fTree.getRandomAccessFile()), e); + } + } + + /** + * Get the entry at the given index + * + * @param index + * the index where to get the entry + * @return the entry at the index + */ + ITmfCheckpoint getEntry(int index) { + return fEntries[index]; + } + + long getChild(int index) { + return fChildrenFileOffsets[index]; + } + + /** + * Set the checkpoint entry at the given index + * + * @param index + * the index where to set the entry + * @param checkpoint + * the checkpoint to set at the index + */ + void setEntry(int index, ITmfCheckpoint checkpoint) { + fIsDirty = true; + // Update number of entries + if (fEntries[index] == null && checkpoint != null) { + ++fNumEntries; + } else if (fEntries[index] != null && checkpoint == null) { + fNumEntries = Math.max(0, fNumEntries - 1); + } + + fEntries[index] = checkpoint; + } + + /** + * Set the child file offset at the given index + * + * @param index + * the index where to set the child offset + * @param offset + * the child offset + */ + void setChild(int index, long offset) { + fIsDirty = true; + fChildrenFileOffsets[index] = offset; + } + + /** + * Returns whether or not the node is dirty, that is, if the node has been + * modified since it first has been loaded into memory + * + * @return true if the node is dirty, false otherwise + */ + boolean isDirty() { + return fIsDirty; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/BTreeNodeCache.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/BTreeNodeCache.java new file mode 100644 index 0000000000..3a9adbb531 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/BTreeNodeCache.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.trace.indexer; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * A simple LRU node cache. The BTree request a node from the cache and the + * cache load it from disk if it's not already in memory. + * + * This cache could be improved considerably by allowing bigger caches. + * + * @author Marc-Andre Laperle + */ +public class BTreeNodeCache { + + /** + * Cache size obtained by experimentation. An improved cache could set this + * dynamically or using a user preference. + */ + private static final int CACHE_SIZE = 15; + + private final BTree fTree; + /** + * The root node is always kept in memory when {@link + * BTree#ALWAYS_CACHE_ROOT} is set to true + */ + private BTreeNode fRootNode = null; + /** + * The collection keeping the nodes in memory. The most recently used is + * kept at the front of the double-ended queue and the least recently used + * node is kept at the back. + */ + private final Deque fCachedNodes = new ArrayDeque<>(CACHE_SIZE); + + private int fCcheMisses = 0; + + /** + * Construct a new node cache for the given BTree + * + * @param tree + * the BTree that will use the cache + */ + BTreeNodeCache(BTree tree) { + fTree = tree; + } + + /** + * Get the node at the offset from the cache. If the node is not found in + * memory, it is loaded from disk. + * + * @param offset + * @return + */ + BTreeNode getNode(long offset) { + if (fRootNode != null && fRootNode.getOffset() == offset) { + return fRootNode; + } + + for (BTreeNode nodeSearch : fCachedNodes) { + if (nodeSearch.getOffset() == offset) { + // This node is now the most recently used + fCachedNodes.remove(nodeSearch); + fCachedNodes.push(nodeSearch); + + return nodeSearch; + } + } + + ++fCcheMisses; + + BTreeNode node = new BTreeNode(fTree, offset); + node.serializeIn(); + addNode(node); + + return node; + } + + /** + * Write all in-memory nodes to disk if they are dirty + */ + void serialize() { + if (fRootNode != null && fRootNode.isDirty()) { + fRootNode.serializeOut(); + } + for (BTreeNode nodeSearch : fCachedNodes) { + if (nodeSearch.isDirty()) { + nodeSearch.serializeOut(); + } + } + } + + /** + * Add a node to the cache. If the cache has reached the size specified with + * {@link #CACHE_SIZE}, the least recently used node is removed from memory. + * + * @param node + * the node to add to the cache + */ + void addNode(BTreeNode node) { + if (fCachedNodes.size() >= CACHE_SIZE) { + BTreeNode removed = fCachedNodes.removeLast(); + if (removed.isDirty()) { + removed.serializeOut(); + } + } + fCachedNodes.push(node); + } + + /** + * Set the root node. See {@link #fRootNode} + * + * @param newRootNode + * the new root node + */ + void setRootNode(BTreeNode newRootNode) { + BTreeNode oldRootNode = fRootNode; + fRootNode = newRootNode; + if (oldRootNode != null) { + addNode(oldRootNode); + } + return; + } + + /** + * Useful for benchmarks. Get the number of cache misses for the whole BTree + * instance lifetime. Cache misses occur when a node is requested and it's + * not in memory therefore it has to be read from disk. + * + * @return the number of cache misses. + */ + int getCacheMisses() { + return fCcheMisses; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/FlatArray.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/FlatArray.java new file mode 100644 index 0000000000..19009847c5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/FlatArray.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.trace.indexer; + +import java.io.File; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.text.MessageFormat; + +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfPersistentlyIndexable; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +/** + * An array of checkpoints stored on disk. It is very efficient for searching + * checkpoints by rank (O(1)) + * + * @author Marc-Andre Laperle + */ +public class FlatArray extends AbstractFileCheckpointCollection { + /** + * Typical FlatArray file name + */ + public static final String INDEX_FILE_NAME = "checkpoint_flatarray.idx"; //$NON-NLS-1$ + + // Cached values + private int fCheckpointSize = 0; + private ByteBuffer fByteBuffer; + + /** + * Constructs a FlatArray for a given trace from scratch or from an existing + * file. When the FlatArray is created from scratch, it is populated by + * subsequent calls to {@link #insert}. + * + * @param file + * the file to use as the persistent storage + * @param trace + * the trace + */ + public FlatArray(File file, ITmfPersistentlyIndexable trace) { + super(file, trace); + + fCheckpointSize = getTrace().getCheckpointSize(); + fByteBuffer = ByteBuffer.allocate(fCheckpointSize); + fByteBuffer.clear(); + } + + /** + * Insert a checkpoint into the file-backed array + * + * @param checkpoint + * the checkpoint to insert + */ + @Override + public void insert(ITmfCheckpoint checkpoint) { + try { + CheckpointCollectionFileHeader header = getHeader(); + ++header.fSize; + getRandomAccessFile().seek(getRandomAccessFile().length()); + fByteBuffer.clear(); + checkpoint.serialize(fByteBuffer); + getRandomAccessFile().write(fByteBuffer.array()); + } catch (IOException e) { + Activator.logError(MessageFormat.format(Messages.FlatArray_IOErrorWriting, getFile()), e); + } + } + + /** + * Get a checkpoint from a rank + * + * @param rank + * the rank to search + * @return the checkpoint that has been found or null if not found + */ + public ITmfCheckpoint get(long rank) { + ITmfCheckpoint checkpoint = null; + try { + long pos = getHeader().getSize() + fCheckpointSize * rank; + getRandomAccessFile().seek(pos); + fByteBuffer.clear(); + getRandomAccessFile().read(fByteBuffer.array()); + ITmfLocation location = getTrace().restoreLocation(fByteBuffer); + ITmfTimestamp timeStamp = new TmfTimestamp(fByteBuffer); + checkpoint = new TmfCheckpoint(timeStamp, location, fByteBuffer); + } catch (IOException e) { + Activator.logError(MessageFormat.format(Messages.FlatArray_IOErrorReading, getFile()), e); + } + return checkpoint; + } + + /** + * Search for a checkpoint and return the rank. + * + * @param checkpoint + * the checkpoint to search + * @return the checkpoint rank of the searched checkpoint, if it is + * contained in the index; otherwise, (-(insertion point) - 1). + */ + @Override + public long binarySearch(ITmfCheckpoint checkpoint) { + if (getHeader().fSize == 1) { + return 0; + } + + long lower = 0; + long upper = getHeader().fSize - 1; + long lastMiddle = -1; + long middle = 0; + while (lower <= upper && lastMiddle != middle) { + lastMiddle = middle; + middle = (lower + upper) / 2; + ITmfCheckpoint found = get(middle); + incCacheMisses(); + int compare = checkpoint.compareTo(found); + if (compare == 0) { + return middle; + } + + if (compare < 0) { + upper = middle; + } else { + lower = middle + 1; + } + } + long insertionPoint = lower; + return -(insertionPoint) - 1; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/IBTreeVisitor.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/IBTreeVisitor.java new file mode 100644 index 0000000000..6ad14adc4a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/IBTreeVisitor.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.trace.indexer; + +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; + +/** + * A BTree visitor goes through the tree using a comparator for + * optimal searches. + * + * @author Marc-Andre Laperle + */ +public interface IBTreeVisitor { + + /** + * The current checkpoint being compared against an internally held key. + * + * @param checkpoint + * the current checkpoint + * @return -1 if checkpoint < key, 0 if checkpoint == key, 1 if checkpoint > + * key + */ + int compare(ITmfCheckpoint checkpoint); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/ICheckpointCollection.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/ICheckpointCollection.java new file mode 100644 index 0000000000..ac06f4ed04 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/ICheckpointCollection.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.trace.indexer; + +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; + +/** + * A common interface for collections containing checkpoints + * + * @author Marc-Andre Laperle + */ +public interface ICheckpointCollection { + + /** + * Insert a checkpoint into the collection + * + * @param checkpoint + * the checkpoint to insert + */ + void insert(ITmfCheckpoint checkpoint); + + /** + * Search for a checkpoint and return the rank. + * + * @param checkpoint + * the checkpoint to search + * @return the checkpoint rank of the searched checkpoint, if it is + * contained in the index; otherwise, (-(insertion point) - 1). + */ + long binarySearch(ITmfCheckpoint checkpoint); + + /** + * @return true if the collection was created from scratch, false otherwise + */ + boolean isCreatedFromScratch(); + + /** + * Returns the size of the collection expressed as a number of checkpoints. + * + * @return the size of the collection + */ + int size(); + + /** + * Set the trace time range + * + * @param timeRange + * the trace time range + */ + void setTimeRange(TmfTimeRange timeRange); + + /** + * Get the trace time range + * + * @return the trace time range + */ + TmfTimeRange getTimeRange(); + + /** + * Set the number of events in the trace + * + * @param nbEvents + * the number of events in the trace + */ + void setNbEvents(long nbEvents); + + /** + * Get the number of events in the trace + * + * @return the number of events in the trace + */ + long getNbEvents(); + + /** + * Set the index as complete. No more checkpoints will be inserted. + */ + void setIndexComplete(); + + /** + * Dispose the collection and delete persistent data (file) + */ + void delete(); + + /** + * Dispose the structure and its resources + */ + void dispose(); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/Messages.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/Messages.java new file mode 100644 index 0000000000..1f16181849 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/Messages.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.trace.indexer; + +import org.eclipse.osgi.util.NLS; + +/** + * Message bundle for tmf.core.trace.index + * + * @author Marc-Andre Laperle + */ +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.tmf.core.trace.indexer.messages"; //$NON-NLS-1$ + /** + * Error opening index + */ + public static String ErrorOpeningIndex; + /** + * I/O Error allocating a node + */ + public static String BTree_IOErrorAllocatingNode; + /** + * I/O Error closing the index + */ + public static String IOErrorClosingIndex; + /** + * I/O Error reading header from disk + */ + public static String IOErrorReadingHeader; + /** + * I/O Error writing header from disk + */ + public static String IOErrorWritingHeader; + /** + * I/O Error reading node from disk + */ + public static String BTreeNode_IOErrorLoading; + /** + * I/O Error writing node to disk + */ + public static String BTreeNode_IOErrorWriting; + /** + * I/O Error reading from disk + */ + public static String FlatArray_IOErrorReading; + /** + * I/O Error writing to disk + */ + public static String FlatArray_IOErrorWriting; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/TmfMemoryIndex.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/TmfMemoryIndex.java new file mode 100644 index 0000000000..1841661662 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/TmfMemoryIndex.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.core.trace.indexer; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; + +/** + * A checkpoint index that store all checkpoints in memory. + * + * @since 3.0 + * @author Marc-Andre Laperle + */ +public class TmfMemoryIndex implements ITmfCheckpointIndex, ICheckpointCollection { + + private final List fCheckpoints; + + /** + * Creates an index for the given trace + * + * @param trace the trace + */ + public TmfMemoryIndex(ITmfTrace trace) { + fCheckpoints = new ArrayList<>(); + } + + @Override + public void dispose() { + fCheckpoints.clear(); + } + + @Override + public void insert(ITmfCheckpoint checkpoint) { + fCheckpoints.add(checkpoint); + } + + @Override + public ITmfCheckpoint get(long checkpoint) { + return fCheckpoints.get((int)checkpoint); + } + + @Override + public long binarySearch(ITmfCheckpoint checkpoint) { + return Collections.binarySearch(fCheckpoints, checkpoint); + } + + @Override + public boolean isEmpty() { + return fCheckpoints.isEmpty(); + } + + @Override + public int size() { + return fCheckpoints.size(); + } + + @Override + public boolean isCreatedFromScratch() { + return true; + } + + @Override + public void setTimeRange(TmfTimeRange timeRange) { + } + + @Override + public void setNbEvents(long nbEvents) { + } + + @Override + public TmfTimeRange getTimeRange() { + return null; + } + + @Override + public long getNbEvents() { + return 0; + } + + @Override + public void setIndexComplete() { + } + + @Override + public void delete() { + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/messages.properties b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/messages.properties new file mode 100644 index 0000000000..6528587289 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/messages.properties @@ -0,0 +1,21 @@ +############################################################################### +# Copyright (c) 2013 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### + +ErrorOpeningIndex=Error opening index. File: {0} +BTree_IOErrorAllocatingNode=I/O error allocating index node. File: {0} +IOErrorClosingIndex=Error closing index. File: {0} +IOErrorReadingHeader=Error reading index header. File: {0} +IOErrorWritingHeader=Error writing index header. File: {0} +BTreeNode_IOErrorLoading=I/O error loading index node. Offset: {0} file: {1} +BTreeNode_IOErrorWriting=I/O error writing index node. Offset: {0} file: {1} +FlatArray_IOErrorReading=I/O error reading index checkpoint. File: {0} +FlatArray_IOErrorWriting=I/O error writing index checkpoint. File: {0} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/Messages.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/Messages.java new file mode 100644 index 0000000000..bc106f6003 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/Messages.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core; + +import org.eclipse.osgi.util.NLS; + +/** + * Message strings for TMF model handling. + * + * @author Marc-Andre Laperle + * @since 2.2 + */ +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.core.messages"; //$NON-NLS-1$ + + /** + * The name of the default project + */ + public static String DefaultTraceProjectName; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/TmfCommonConstants.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/TmfCommonConstants.java new file mode 100644 index 0000000000..d1aa3b28c0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/TmfCommonConstants.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Patrick Tasse - Add support for source location + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.core; + +import org.eclipse.core.runtime.QualifiedName; + +/** + * This class provides a common container for TMF constants. + * + * @version 1.0 + * @author Bernd Hufmann + */ +public class TmfCommonConstants { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The trace type ID persistent property of a trace resource. + */ + public static final QualifiedName TRACETYPE = new QualifiedName("org.eclipse.linuxtools.tmf", "tracetype.id"); //$NON-NLS-1$//$NON-NLS-2$ + + /** + * The source location persistent property of a trace resource. + * @since 3.0 + */ + public static final QualifiedName SOURCE_LOCATION = new QualifiedName("org.eclipse.linuxtools.tmf", "source.location"); //$NON-NLS-1$//$NON-NLS-2$ + + /** + * The supplementary folder name persistent property of a trace resource. + */ + public static final QualifiedName TRACE_SUPPLEMENTARY_FOLDER = new QualifiedName("org.eclipse.linuxtools.tmf", "trace.suppl.folder"); //$NON-NLS-1$//$NON-NLS-2$ + + /** + * The name of the parent folder for storing trace specific supplementary data. Each trace will have a sub-directory underneath with folder name equal to the trace name. + * @since 3.0 + */ + public static final String TRACE_SUPPLEMENTARY_FOLDER_NAME = ".tracing"; //$NON-NLS-1$ + + /** + * The name of the default project that can be created under various + * conditions when there is no tracing project in the workspace. + * + * @since 2.2 + */ + public static final String DEFAULT_TRACE_PROJECT_NAME = Messages.DefaultTraceProjectName; + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/TmfProjectNature.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/TmfProjectNature.java new file mode 100644 index 0000000000..dad673aee0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/TmfProjectNature.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectNature; +import org.eclipse.core.runtime.CoreException; + +/** + * The TMF basic tracing project nature. + * + * @version 1.0 + * @author Francois Chouinard + */ +public class TmfProjectNature implements IProjectNature { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The nature ID + */ + public static final String ID = "org.eclipse.linuxtools.tmf.project.nature"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private IProject fProject; + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Override + public void configure() throws CoreException { + } + + @Override + public void deconfigure() throws CoreException { + } + + @Override + public IProject getProject() { + return fProject; + } + + @Override + public void setProject(IProject project) { + fProject = project; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisModule.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisModule.java new file mode 100644 index 0000000000..6f23104f9b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisModule.java @@ -0,0 +1,249 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.analysis; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.tmf.core.component.ITmfComponent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Interface that hooks analysis modules to the rest of TMF. Analysis modules + * are a set of operations to be run on a trace (or experiment). They will + * typically either provide outputs to the end user, or feed other analysis. + * + * An analysis module must tell what trace type it applies to and if it can be + * executed on a given trace of the right type. + * + * Implementations of this interface must define how an analysis will be + * executed once scheduled and provide help texts to describe how to use the + * analysis. + * + * Analysis can also take parameters, manually set, through default values or + * using an {@link IAnalysisParameterProvider}. {@link IAnalysisOutput} can also + * be registered to an analysis modules to display the results of the analysis. + * + * This interface just allows to hook the analysis to the TMF framework, but the + * developer is free to implement the internals of its operations the way he + * wishes. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public interface IAnalysisModule extends ITmfComponent, IAnalysisRequirementProvider, AutoCloseable { + + // -------------------------------------------------------- + // Getters and setters + // -------------------------------------------------------- + + /** + * Sets the name of the analysis module + * + * @param name + * name of the module + */ + void setName(String name); + + /** + * Sets the id of the module + * + * @param id + * id of the module + */ + void setId(String id); + + /** + * Gets the id of the analysis module + * + * @return The id of the module + */ + @NonNull + String getId(); + + /** + * Sets whether this analysis should be run automatically at trace opening + * + * @param auto + * True if analysis should be run automatically for a trace + */ + void setAutomatic(boolean auto); + + /** + * Gets whether the analysis should be run automatically at trace opening + * + * @return true if analysis is to be run automatically + */ + boolean isAutomatic(); + + /** + * Sets the trace on which to run the analysis + * + * Note: The trace cannot be final since most modules are instantiated in a + * way that does not know about the trace, but it shouldn't be set more than + * once since an instance of a module belongs to a trace. It is up to each + * implementation to make sure the trace is set only once. + * + * @param trace + * The trace to run the analysis on + * @throws TmfAnalysisException + */ + void setTrace(ITmfTrace trace) throws TmfAnalysisException; + + /** + * Add a parameter to this module + * + * @param name + * Name of the parameter + */ + void addParameter(String name); + + /** + * Sets the value of a parameter + * + * @param name + * The name of the parameter + * @param value + * The value (subclasses may type-check it) + * @throws RuntimeException + */ + void setParameter(String name, Object value); + + /** + * Gets the value of a parameter + * + * @param name + * Name of the parameter + * @return The value of a parameter + */ + Object getParameter(String name); + + // ----------------------------------------------------- + // Functionalities + // ----------------------------------------------------- + + /** + * Can an analysis be executed on a given trace (otherwise, it is shown + * grayed out and a help message is available to see why it is not + * applicable) + * + * @param trace + * The trace to analyze + * @return Whether the analysis can be executed + */ + boolean canExecute(@NonNull ITmfTrace trace); + + /** + * Schedule the execution of the analysis. If the trace has been set and is + * opened, the analysis will be executed right away, otherwise it should + * scheduled for execution once all pre-conditions are satisfied. + * + * @return An IStatus indicating if the execution of the analysis could be + * scheduled successfully or not. + */ + IStatus schedule(); + + /** + * Gets a list of outputs + * + * @return The list of {@link IAnalysisOutput} + */ + Iterable getOutputs(); + + /** + * Registers an output for this analysis + * + * @param output + * The {@link IAnalysisOutput} object + */ + void registerOutput(IAnalysisOutput output); + + /** + * Block the calling thread until this analysis has completed (or has been + * cancelled). + * + * @return True if the analysis finished successfully, false if it was + * cancelled. + */ + boolean waitForCompletion(); + + /** + * Typically the output of an analysis will be available only after it is + * completed. This method allows to wait until an analysis has been + * completed or the analysis has been cancelled + * + * To avoid UI freezes, it should not be called from the main thread of the + * application + * + * @param monitor + * The progress monitor to check for cancellation + * @return If the analysis was successfully completed. If false is returned, + * this either means there was a problem during the analysis, or it + * got cancelled before it could finished or it has not been + * scheduled to run at all. In all cases, the quality or + * availability of the output(s) and results is not guaranteed. + */ + boolean waitForCompletion(IProgressMonitor monitor); + + /** + * Cancels the current analysis + */ + void cancel(); + + // ----------------------------------------------------- + // Utilities + // ----------------------------------------------------- + + /** + * Gets a generic help message/documentation for this analysis module + * + * This help text will be displayed to the user and may contain information + * on what the module does, how to use it and how to correctly generate the + * trace to make it available + * + * TODO: Help texts could be quite long. They should reside in their own + * file and be accessed either with text, for a command line man page, or + * through the eclipse help context. + * + * @return The generic help text + */ + String getHelpText(); + + /** + * Gets a help text specific for a given trace + * + * For instance, it may explain why the analysis module cannot be executed + * on a trace and how to correct this + * + * @param trace + * The trace to analyze + * @return A help text with information on a specific trace + */ + String getHelpText(ITmfTrace trace); + + /** + * Notify the module that the value of a parameter has changed + * + * @param name + * The of the parameter that changed + */ + void notifyParameterChanged(String name); + + // ----------------------------------------------------- + // AutoCloseable (remove the thrown exception) + // ----------------------------------------------------- + + @Override + void close(); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisModuleHelper.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisModuleHelper.java new file mode 100644 index 0000000000..8122c9ff18 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisModuleHelper.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.analysis; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.osgi.framework.Bundle; + +/** + * Interface for modules helpers that provide basic module information and + * creates module from a source when requested. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public interface IAnalysisModuleHelper extends IAnalysisRequirementProvider { + + // ------------------------------------ + // Getters + // ------------------------------------ + + /** + * Gets the id of the analysis module + * + * @return The id of the module + */ + String getId(); + + /** + * Gets the name of the analysis module + * + * @return The id of the module + */ + String getName(); + + /** + * Gets whether the analysis should be run automatically at trace opening + * + * @return true if analysis is to be run automatically + */ + boolean isAutomatic(); + + /** + * Gets a generic help message/documentation for this analysis module + * + * This help text will be displayed to the user and may contain information + * on what the module does, how to use it and how to correctly generate the + * trace to make it available + * + * TODO: Help texts could be quite long. They should reside in their own + * file and be accessed either with text, for a command line man page, or + * through the eclipse help context. There should be a custom way to make it + * available through the helper, without instantiating the analysis, though + * help text after analysis instantiation may be richer. + * + * @return The generic help text + */ + String getHelpText(); + + /** + * Gets a specific help message/documentation for this analysis module + * applied on the given trace. This help message can add information on the + * status of this analysis for a given trace, whether it can be executed or + * not and why. + * + * This help text will be displayed to the user and may contain information + * on what the module does, how to use it and how to correctly generate the + * trace to make it available + * + * @param trace + * A trace for which to get specific help message + * @return The generic help text + */ + String getHelpText(@NonNull ITmfTrace trace); + + /** + * Gets the icon for this module + * + * @return The icon path + */ + String getIcon(); + + /** + * Gets the bundle this analysis module is part of + * + * @return The bundle + */ + Bundle getBundle(); + + /** + * Does an analysis apply to a given trace type (otherwise, it is not shown) + * + * @param traceclass + * The trace to analyze + * @return whether the analysis applies + */ + boolean appliesToTraceType(Class traceclass); + + /** + * Gets the list of valid trace types that the analysis can operate on. + * + * @return List of the trace type + */ + Iterable> getValidTraceTypes(); + + // --------------------------------------- + // Functionalities + // --------------------------------------- + + /** + * Creates a new instance of the {@link IAnalysisModule} represented by this + * helper and initializes it with the trace. + * + * After the module is fully created, this method should call + * {@link TmfAnalysisManager#analysisModuleCreated(IAnalysisModule)} in + * order for the new module listeners to be executed on this module. + * + * @param trace + * The trace to be linked to the module + * @return A new {@link IAnalysisModule} instance initialized with the + * trace. + * @throws TmfAnalysisException + * Exceptions that occurred when setting trace + */ + IAnalysisModule newModule(ITmfTrace trace) throws TmfAnalysisException; + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisModuleSource.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisModuleSource.java new file mode 100644 index 0000000000..ee40999e38 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisModuleSource.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.analysis; + + +/** + * Interface that module sources must implement. A module source provides a list + * of analysis modules. For example, one module source would be the plugin's + * configuration element through the analysis extension point. + * + * Typically, for each module source, there would be an + * {@link IAnalysisModuleHelper} implementation to create modules from this + * source. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public interface IAnalysisModuleSource { + + /** + * Get the list of modules helpers provided by this source + * + * @return The analysis module helpers in iterable format + */ + Iterable getAnalysisModules(); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisOutput.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisOutput.java new file mode 100644 index 0000000000..0768024601 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisOutput.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.analysis; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * Interface for all output types of analysis + * + * @author Geneviève Bastien + * @since 3.0 + */ +public interface IAnalysisOutput { + + /** + * Gets the name of the output + * + * @return Name of the output + */ + String getName(); + + /** + * Requests the output for an analysis module. This function does not + * necessarily output the analysis, it just specifies that the user wants + * this output. + */ + void requestOutput(); + + /** + * Sets an arbitrary property on the output. The key must not be null, a + * null value removes the property. + * + * @param key + * The arbitrary property. Must not be null. + * @param value + * The value of the property. + * @param immediate + * If true, the property will be applied immediately + * if the output is active. Otherwise, it is only applied when the + * output is explicitly requested by the user. + */ + void setOutputProperty(@NonNull String key, String value, boolean immediate); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisParameterProvider.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisParameterProvider.java new file mode 100644 index 0000000000..59bc1fc46d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisParameterProvider.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.analysis; + +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Interface for classes that can provide parameters to analysis when they are + * not set manually + * + * @author Geneviève Bastien + * @since 3.0 + */ +public interface IAnalysisParameterProvider { + + // -------------------------------------------------------- + // Getters and setters + // -------------------------------------------------------- + + /** + * Gets the name of the parameter provider + * + * @return Name of the parameter provider + */ + String getName(); + + /** + * Gets the value of a parameter + * + * @param name + * Name of the parameter + * @return The value of a parameter + */ + Object getParameter(String name); + + // -------------------------------------------------------- + // Functionalities + // -------------------------------------------------------- + + /** + * Does this parameter provider apply to a given trace + * + * @param trace + * The trace to analyse + * @return whether the parameter provider applies + */ + boolean appliesToTrace(ITmfTrace trace); + + /** + * Register an analysis module to be notified when a parameter value is + * changed + * + * @param module + * The listening analysis module + */ + void registerModule(IAnalysisModule module); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisRequirementProvider.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisRequirementProvider.java new file mode 100644 index 0000000000..96011a7958 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisRequirementProvider.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Guilliano Molaire - Initial API and implementation + * Mathieu Rail - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.analysis; + +/** + * Interface that provides the necessary methods for an analysis to define its + * requirements. + * + * @author Guilliano Molaire + * @author Mathieu Rail + * @since 3.0 + */ +public interface IAnalysisRequirementProvider { + + /** + * Gets the requirements associated with this analysis. + * + * @return List of requirement + */ + Iterable getAnalysisRequirements(); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/ITmfNewAnalysisModuleListener.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/ITmfNewAnalysisModuleListener.java new file mode 100644 index 0000000000..8175cd6720 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/ITmfNewAnalysisModuleListener.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.analysis; + +/** + * This is the interface class must implement to listen to new analysis module + * objects being instantiated. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public interface ITmfNewAnalysisModuleListener { + + /** + * Method called when an analysis module has just been instantiated. + * + * @param module + * The newly instantiated analysis module + */ + public void moduleCreated(IAnalysisModule module); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/Messages.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/Messages.java new file mode 100644 index 0000000000..daf470efe1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/Messages.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.analysis; + +import org.eclipse.osgi.util.NLS; + +/** + * Message bundle for org.eclipse.linuxtools.tmf.core.analysis + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.core.analysis.messages"; //$NON-NLS-1$ + + /** Trace was set more than once for this module */ + public static String TmfAbstractAnalysisModule_TraceSetMoreThanOnce; + + /** Analysis Module cannot execute on trace */ + public static String TmfAbstractAnalysisModule_AnalysisCannotExecute; + + /** Analysis Module does not apply to trace */ + public static String TmfAnalysisModuleHelper_AnalysisDoesNotApply; + + /** Analysis Module for trace */ + public static String TmfAbstractAnalysisModule_AnalysisForTrace; + + /** Analysis Module presentation */ + public static String TmfAbstractAnalysisModule_AnalysisModule; + + /** Parameter is invalid */ + public static String TmfAbstractAnalysisModule_InvalidParameter; + + /** The trace to set was null */ + public static String TmfAbstractAnalysisModule_NullTrace; + + /** Additional information on a requirement */ + public static String TmfAnalysis_RequirementInformation; + + /** Mandatory values of a requirement */ + public static String TmfAnalysis_RequirementMandatoryValues; + + /** A requirement is not fulfilled */ + public static String TmfAnalysis_RequirementNotFulfilled; + + /** Running analysis */ + public static String TmfAbstractAnalysisModule_RunningAnalysis; + + /** Error instantiating parameter provider */ + public static String TmfAnalysisManager_ErrorParameterProvider; + + /** Impossible to instantiate module from helper */ + public static String TmfAnalysisModuleHelper_ImpossibleToCreateModule; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAbstractAnalysisModule.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAbstractAnalysisModule.java new file mode 100644 index 0000000000..ffc6c881c2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAbstractAnalysisModule.java @@ -0,0 +1,474 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.analysis; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.osgi.util.NLS; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement.ValuePriorityLevel; +import org.eclipse.tracecompass.tmf.core.component.TmfComponent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfStartAnalysisSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; + +/** + * Base class that analysis modules main class may extend. It provides default + * behavior to some methods of the analysis module + * + * @author Geneviève Bastien + * @since 3.0 + */ +public abstract class TmfAbstractAnalysisModule extends TmfComponent implements IAnalysisModule { + + private String fName, fId; + private boolean fAutomatic = false, fStarted = false; + private ITmfTrace fTrace; + private final Map fParameters = new HashMap<>(); + private final List fParameterNames = new ArrayList<>(); + private final List fOutputs = new ArrayList<>(); + private List fParameterProviders = new ArrayList<>(); + private Job fJob = null; + + private final Object syncObj = new Object(); + + /* Latch tracking if the analysis is completed or not */ + private CountDownLatch fFinishedLatch = new CountDownLatch(0); + + private boolean fAnalysisCancelled = false; + + @Override + public boolean isAutomatic() { + return fAutomatic; + } + + @Override + public String getName() { + return fName; + } + + @Override + public void setName(String name) { + fName = name; + } + + @Override + public void setId(String id) { + fId = id; + } + + @Override + @NonNull + public String getId() { + String id = fId; + if (id == null) { + id = new String(this.getClass().getCanonicalName()); + fId = id; + } + return id; + } + + @Override + public void setAutomatic(boolean auto) { + fAutomatic = auto; + } + + @Override + public void setTrace(ITmfTrace trace) throws TmfAnalysisException { + if (trace == null) { + throw new TmfAnalysisException(Messages.TmfAbstractAnalysisModule_NullTrace); + } + if (fTrace != null) { + throw new TmfAnalysisException(NLS.bind(Messages.TmfAbstractAnalysisModule_TraceSetMoreThanOnce, getName())); + } + + /* Check that analysis can be executed */ + if (!canExecute(trace)) { + throw new TmfAnalysisException(NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisCannotExecute, getName())); + } + + fTrace = trace; + /* Get the parameter providers for this trace */ + fParameterProviders = TmfAnalysisManager.getParameterProviders(this, fTrace); + for (IAnalysisParameterProvider provider : fParameterProviders) { + provider.registerModule(this); + } + resetAnalysis(); + fStarted = false; + } + + /** + * Gets the trace + * + * @return The trace + */ + protected ITmfTrace getTrace() { + return fTrace; + } + + @Override + public void addParameter(String name) { + fParameterNames.add(name); + } + + @Override + public synchronized void setParameter(String name, Object value) { + if (!fParameterNames.contains(name)) { + throw new RuntimeException(NLS.bind(Messages.TmfAbstractAnalysisModule_InvalidParameter, name, getName())); + } + Object oldValue = fParameters.get(name); + fParameters.put(name, value); + if ((value != null) && !(value.equals(oldValue))) { + parameterChanged(name); + } + } + + @Override + public synchronized void notifyParameterChanged(String name) { + if (!fParameterNames.contains(name)) { + throw new RuntimeException(NLS.bind(Messages.TmfAbstractAnalysisModule_InvalidParameter, name, getName())); + } + Object oldValue = fParameters.get(name); + Object value = getParameter(name); + if ((value != null) && !(value.equals(oldValue))) { + parameterChanged(name); + } + } + + /** + * Used to indicate that a parameter value has been changed + * + * @param name + * The name of the modified parameter + */ + protected void parameterChanged(String name) { + + } + + @Override + public Object getParameter(String name) { + Object paramValue = fParameters.get(name); + /* The parameter is not set, maybe it can be provided by someone else */ + if ((paramValue == null) && (fTrace != null)) { + for (IAnalysisParameterProvider provider : fParameterProviders) { + paramValue = provider.getParameter(name); + if (paramValue != null) { + break; + } + } + } + return paramValue; + } + + @Override + public boolean canExecute(@NonNull ITmfTrace trace) { + for (TmfAnalysisRequirement requirement : getAnalysisRequirements()) { + if (!requirement.isFulfilled(trace)) { + return false; + } + } + return true; + } + + /** + * Set the countdown latch back to 1 so the analysis can be executed again + */ + protected void resetAnalysis() { + fFinishedLatch.countDown(); + fFinishedLatch = new CountDownLatch(1); + } + + /** + * Actually executes the analysis itself + * + * @param monitor + * Progress monitor + * @return Whether the analysis was completed successfully or not + * @throws TmfAnalysisException + * Method may throw an analysis exception + */ + protected abstract boolean executeAnalysis(final IProgressMonitor monitor) throws TmfAnalysisException; + + /** + * Indicate the analysis has been canceled. It is abstract to force + * implementing class to cleanup what they are running. This is called by + * the job's canceling. It does not need to be called directly. + */ + protected abstract void canceling(); + + /** + * To be called when the analysis is completed, whether normally or because + * it was cancelled or for any other reason. + * + * It has to be called inside a synchronized block + */ + private void setAnalysisCompleted() { + fStarted = false; + fJob = null; + fFinishedLatch.countDown(); + } + + /** + * Cancels the analysis if it is executing + */ + @Override + public final void cancel() { + synchronized (syncObj) { + if (fJob != null) { + if (fJob.cancel()) { + fAnalysisCancelled = true; + setAnalysisCompleted(); + } + } + fStarted = false; + } + } + + @Override + public void close() { + dispose(); + } + + @Override + public void dispose() { + super.dispose(); + cancel(); + } + + private void execute(@NonNull final ITmfTrace trace) { + + /* + * TODO: The analysis in a job should be done at the analysis manager + * level instead of depending on this abstract class implementation, + * otherwise another analysis implementation may block the main thread + */ + + /* Do not execute if analysis has already run */ + if (fFinishedLatch.getCount() == 0) { + return; + } + + /* Do not execute if analysis already running */ + synchronized (syncObj) { + if (fStarted) { + return; + } + fStarted = true; + } + + /* + * Actual analysis will be run on a separate thread + */ + fJob = new Job(NLS.bind(Messages.TmfAbstractAnalysisModule_RunningAnalysis, getName())) { + @Override + protected IStatus run(final IProgressMonitor monitor) { + try { + monitor.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$ + broadcast(new TmfStartAnalysisSignal(TmfAbstractAnalysisModule.this, TmfAbstractAnalysisModule.this)); + fAnalysisCancelled = !executeAnalysis(monitor); + } catch (TmfAnalysisException e) { + Activator.logError("Error executing analysis with trace " + getTrace().getName(), e); //$NON-NLS-1$ + } finally { + synchronized (syncObj) { + monitor.done(); + setAnalysisCompleted(); + } + TmfTraceManager.refreshSupplementaryFiles(trace); + } + if (!fAnalysisCancelled) { + return Status.OK_STATUS; + } + // Reset analysis so that it can be executed again. + resetAnalysis(); + return Status.CANCEL_STATUS; + } + + @Override + protected void canceling() { + TmfAbstractAnalysisModule.this.canceling(); + } + + }; + fJob.schedule(); + } + + @Override + public IStatus schedule() { + final ITmfTrace trace = fTrace; + if (trace == null) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, String.format("No trace specified for analysis %s", getName())); //$NON-NLS-1$ + } + execute(trace); + + return Status.OK_STATUS; + } + + @Override + public Iterable getOutputs() { + return fOutputs; + } + + @Override + public void registerOutput(IAnalysisOutput output) { + if (!fOutputs.contains(output)) { + fOutputs.add(output); + } + } + + @Override + public boolean waitForCompletion() { + try { + fFinishedLatch.await(); + } catch (InterruptedException e) { + Activator.logError("Error while waiting for module completion", e); //$NON-NLS-1$ + } + return !fAnalysisCancelled; + } + + @Override + public boolean waitForCompletion(IProgressMonitor monitor) { + try { + while (!fFinishedLatch.await(500, TimeUnit.MILLISECONDS)) { + if (fAnalysisCancelled || monitor.isCanceled()) { + fAnalysisCancelled = true; + return false; + } + } + } catch (InterruptedException e) { + Activator.logError("Error while waiting for module completion", e); //$NON-NLS-1$ + } + return !fAnalysisCancelled; + } + + /** + * Signal handler for trace closing + * + * @param signal + * Trace closed signal + */ + @TmfSignalHandler + public void traceClosed(TmfTraceClosedSignal signal) { + /* Is the closing trace the one that was requested? */ + if (signal.getTrace() == fTrace) { + cancel(); + fTrace = null; + } + } + + /** + * Signal handler for when the trace becomes active + * + * @param signal + * Trace selected signal + * @since 3.1 + */ + @TmfSignalHandler + public void traceSelected(TmfTraceSelectedSignal signal) { + /* + * Since some parameter providers may handle many traces, we need to + * register the current trace to it + */ + if (signal.getTrace() == fTrace) { + for (IAnalysisParameterProvider provider : fParameterProviders) { + provider.registerModule(this); + } + } + } + + /** + * Returns a full help text to display + * + * @return Full help text for the module + */ + protected String getFullHelpText() { + return NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisModule, getName()); + } + + /** + * Gets a short help text, to display as header to other help text + * + * @param trace + * The trace to show help for + * + * @return Short help text describing the module + */ + protected String getShortHelpText(ITmfTrace trace) { + return NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisForTrace, getName(), trace.getName()); + } + + /** + * Gets the help text specific for a trace who does not have required + * characteristics for module to execute. The default implementation uses + * the analysis requirements. + * + * @param trace + * The trace to apply the analysis to + * @return Help text + */ + protected String getTraceCannotExecuteHelpText(@NonNull ITmfTrace trace) { + StringBuilder builder = new StringBuilder(); + builder.append(NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisCannotExecute, getName())); + for (TmfAnalysisRequirement requirement : getAnalysisRequirements()) { + if (!requirement.isFulfilled(trace)) { + builder.append("\n\n"); //$NON-NLS-1$ + builder.append(NLS.bind(Messages.TmfAnalysis_RequirementNotFulfilled, requirement.getType())); + builder.append("\n"); //$NON-NLS-1$ + builder.append(NLS.bind(Messages.TmfAnalysis_RequirementMandatoryValues, requirement.getValues(ValuePriorityLevel.MANDATORY))); + Set information = requirement.getInformation(); + if (!information.isEmpty()) { + builder.append("\n"); //$NON-NLS-1$ + builder.append(NLS.bind(Messages.TmfAnalysis_RequirementInformation, information)); + } + } + } + return builder.toString(); + } + + @Override + public String getHelpText() { + return getFullHelpText(); + } + + @Override + public String getHelpText(ITmfTrace trace) { + if (trace == null) { + return getHelpText(); + } + String text = getShortHelpText(trace); + if (!canExecute(trace)) { + text = text + "\n\n" + getTraceCannotExecuteHelpText(trace); //$NON-NLS-1$ + } + return text; + } + + @Override + public Iterable getAnalysisRequirements() { + return Collections.EMPTY_SET; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAbstractAnalysisParamProvider.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAbstractAnalysisParamProvider.java new file mode 100644 index 0000000000..368df83989 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAbstractAnalysisParamProvider.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.analysis; + +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; + +/** + * Abstract class for parameter providers, implements methods and + * functionalities to warn the analysis module of parameter changed + * + * @author Geneviève Bastien + * @since 3.0 + */ +public abstract class TmfAbstractAnalysisParamProvider implements IAnalysisParameterProvider { + + /** + * The module registered with this provider + */ + private IAnalysisModule fModule; + + @Override + public void registerModule(IAnalysisModule module) { + if (module == null) { + throw new IllegalArgumentException(); + } + ITmfTrace selectedTrace = TmfTraceManager.getInstance().getActiveTrace(); + /* If no trace is active, just register the module */ + if (selectedTrace == null) { + fModule = module; + return; + } + IAnalysisModule selectedModule = selectedTrace.getAnalysisModule(module.getId()); + /* register only if the module is for the currently selected trace */ + if (selectedModule == module) { + fModule = module; + } + } + + /** + * Gets the analysis module + * + * @return the {@link IAnalysisModule} associated with this provider + */ + protected IAnalysisModule getModule() { + return fModule; + } + + /** + * Notify the registered module that the said parameter has a new value. The + * analysis module will decide what to do with this information + * + * @param name + * Name of the modified parameter + */ + protected void notifyParameterChanged(String name) { + if (fModule != null) { + fModule.notifyParameterChanged(name); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisManager.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisManager.java new file mode 100644 index 0000000000..9fce5d5c1b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisManager.java @@ -0,0 +1,230 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.analysis; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.internal.tmf.core.analysis.TmfAnalysisModuleSources; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Manages the available analysis helpers from different sources and their + * parameter providers. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfAnalysisManager { + + private static final Map fAnalysisModules = new HashMap<>(); + private static final Map>> fParameterProviders = new HashMap<>(); + private static final Map, IAnalysisParameterProvider> fParamProviderInstances = new HashMap<>(); + private static final List fSources = new ArrayList<>(); + private static final List fListeners = new ArrayList<>(); + + /** + * Constructor, not to be used + * TODO This class is not meant to be instantiated, put me private in next major release + * @deprecated It was never meant to be public + */ + @Deprecated + public TmfAnalysisManager() { + + } + + /** + * Registers a new source of modules + * + * @param source + * A {@link IAnalysisModuleSource} instance + */ + public static synchronized void registerModuleSource(IAnalysisModuleSource source) { + fSources.add(source); + refreshModules(); + } + + /** + * Initializes sources and new module listeners from the extension point + */ + public static synchronized void initialize() { + fSources.clear(); + fListeners.clear(); + initializeModuleSources(); + initializeNewModuleListeners(); + } + + /** + * Cleans the module sources list and initialize it from the extension point + */ + private static synchronized void initializeModuleSources() { + for (IAnalysisModuleSource source : TmfAnalysisModuleSources.getSources()) { + fSources.add(source); + } + } + + /** + * Cleans the new module listeners list and initialize it from the extension + * point + */ + private static synchronized void initializeNewModuleListeners() { + for (ITmfNewAnalysisModuleListener output : TmfAnalysisModuleOutputs.getOutputListeners()) { + fListeners.add(output); + } + } + + /** + * Add a new module listener to the list of listeners + * + * @param listener + * The new module listener + */ + public static synchronized void addNewModuleListener(ITmfNewAnalysisModuleListener listener) { + fListeners.add(listener); + } + + /** + * Gets all available analysis module helpers + * + * This map is read-only + * + * @return The map of available {@link IAnalysisModuleHelper} + */ + public static synchronized Map getAnalysisModules() { + if (fAnalysisModules.isEmpty()) { + for (IAnalysisModuleSource source : fSources) { + for (IAnalysisModuleHelper helper : source.getAnalysisModules()) { + fAnalysisModules.put(helper.getId(), helper); + } + } + } + return Collections.unmodifiableMap(fAnalysisModules); + } + + /** + * Gets all analysis module helpers that apply to a given trace type + * + * This map is read-only + * + * @param traceclass + * The trace class to get modules for + * @return The map of available {@link IAnalysisModuleHelper} + */ + public static Map getAnalysisModules(Class traceclass) { + Map allModules = getAnalysisModules(); + Map map = new HashMap<>(); + for (IAnalysisModuleHelper module : allModules.values()) { + if (module.appliesToTraceType(traceclass)) { + map.put(module.getId(), module); + } + } + return Collections.unmodifiableMap(map); + } + + /** + * Gets an analysis module helper identified by an id + * + * @param id + * Id of the analysis module to get + * @return The {@link IAnalysisModuleHelper} + */ + public static IAnalysisModuleHelper getAnalysisModule(String id) { + Map map = getAnalysisModules(); + return map.get(id); + } + + /** + * Register a new parameter provider for an analysis + * + * @param analysisId + * The id of the analysis + * @param paramProvider + * The class of the parameter provider + */ + public static void registerParameterProvider(String analysisId, Class paramProvider) { + synchronized (fParameterProviders) { + if (!fParameterProviders.containsKey(analysisId)) { + fParameterProviders.put(analysisId, new ArrayList>()); + } + fParameterProviders.get(analysisId).add(paramProvider); + } + } + + /** + * Get a parameter provider that applies to the requested trace + * + * @param module + * Analysis module + * @param trace + * The trace + * @return A parameter provider if one applies to the trace, null otherwise + */ + public static List getParameterProviders(IAnalysisModule module, ITmfTrace trace) { + List providerList = new ArrayList<>(); + synchronized (fParameterProviders) { + if (!fParameterProviders.containsKey(module.getId())) { + return providerList; + } + for (Class providerClass : fParameterProviders.get(module.getId())) { + try { + IAnalysisParameterProvider provider = fParamProviderInstances.get(providerClass); + if (provider == null) { + provider = providerClass.newInstance(); + fParamProviderInstances.put(providerClass, provider); + } + if (provider != null) { + if (provider.appliesToTrace(trace)) { + providerList.add(provider); + } + } + } catch (IllegalArgumentException e) { + Activator.logError(Messages.TmfAnalysisManager_ErrorParameterProvider, e); + } catch (SecurityException e) { + Activator.logError(Messages.TmfAnalysisManager_ErrorParameterProvider, e); + } catch (InstantiationException e) { + Activator.logError(Messages.TmfAnalysisManager_ErrorParameterProvider, e); + } catch (IllegalAccessException e) { + Activator.logError(Messages.TmfAnalysisManager_ErrorParameterProvider, e); + } + } + } + return providerList; + } + + /** + * Clear the list of modules so that next time, it is computed again from + * sources + */ + public static synchronized void refreshModules() { + fAnalysisModules.clear(); + } + + /** + * This method should be called when new analysis modules have been created + * by module helpers to that the {@link ITmfNewAnalysisModuleListener} can + * be executed on the module instance. + * + * @param module + * The newly created analysis module + */ + public static synchronized void analysisModuleCreated(IAnalysisModule module) { + for (ITmfNewAnalysisModuleListener listener : fListeners) { + listener.moduleCreated(module); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisModuleHelperConfigElement.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisModuleHelperConfigElement.java new file mode 100644 index 0000000000..880a4ab4a6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisModuleHelperConfigElement.java @@ -0,0 +1,206 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + * Mathieu Rail - Added functionality for getting a module's requirements + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.analysis; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.runtime.ContributorFactoryOSGi; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.InvalidRegistryObjectException; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.osgi.util.NLS; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.internal.tmf.core.analysis.TmfAnalysisModuleSourceConfigElement; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.osgi.framework.Bundle; + +/** + * Analysis module helper for modules provided by a plugin's configuration + * elements. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfAnalysisModuleHelperConfigElement implements IAnalysisModuleHelper { + + private final IConfigurationElement fCe; + + /** + * Constructor + * + * @param ce + * The source {@link IConfigurationElement} of this module helper + */ + public TmfAnalysisModuleHelperConfigElement(IConfigurationElement ce) { + fCe = ce; + } + + // ---------------------------------------- + // Wrappers to {@link IAnalysisModule} methods + // ---------------------------------------- + + @Override + public String getId() { + return fCe.getAttribute(TmfAnalysisModuleSourceConfigElement.ID_ATTR); + } + + @Override + public String getName() { + return fCe.getAttribute(TmfAnalysisModuleSourceConfigElement.NAME_ATTR); + } + + @Override + public boolean isAutomatic() { + return Boolean.parseBoolean(fCe.getAttribute(TmfAnalysisModuleSourceConfigElement.AUTOMATIC_ATTR)); + } + + @Override + public String getHelpText() { + /* + * FIXME: No need to externalize this. A better solution will be found + * soon and this string is just temporary + */ + return new String("The trace must be opened to get the help message"); //$NON-NLS-1$ + } + + @Override + public String getIcon() { + return fCe.getAttribute(TmfAnalysisModuleSourceConfigElement.ICON_ATTR); + } + + @Override + public Bundle getBundle() { + return ContributorFactoryOSGi.resolve(fCe.getContributor()); + } + + @Override + public boolean appliesToTraceType(Class traceclass) { + boolean applies = false; + + /* Get the module's applying tracetypes */ + final IConfigurationElement[] tracetypeCE = fCe.getChildren(TmfAnalysisModuleSourceConfigElement.TRACETYPE_ELEM); + for (IConfigurationElement element : tracetypeCE) { + Class applyclass; + try { + applyclass = getBundle().loadClass(element.getAttribute(TmfAnalysisModuleSourceConfigElement.CLASS_ATTR)); + String classAppliesVal = element.getAttribute(TmfAnalysisModuleSourceConfigElement.APPLIES_ATTR); + boolean classApplies = true; + if (classAppliesVal != null) { + classApplies = Boolean.parseBoolean(classAppliesVal); + } + if (classApplies) { + applies |= applyclass.isAssignableFrom(traceclass); + } else { + /* If the trace type does not apply, reset the applies variable to false */ + if (applyclass.isAssignableFrom(traceclass)) { + applies = false; + } + } + } catch (ClassNotFoundException e) { + Activator.logError("Error in applies to trace", e); //$NON-NLS-1$ + } catch (InvalidRegistryObjectException e) { + Activator.logError("Error in applies to trace", e); //$NON-NLS-1$ + } + } + return applies; + } + + @Override + public Iterable> getValidTraceTypes() { + Set> traceTypes = new HashSet<>(); + + for (TraceTypeHelper tth : TmfTraceType.getTraceTypeHelpers()) { + if (appliesToTraceType(tth.getTraceClass())) { + traceTypes.add(tth.getTraceClass()); + } + } + + return traceTypes; + } + + @Override + public Iterable getAnalysisRequirements() { + IAnalysisModule module = createModule(); + if (module != null) { + return module.getAnalysisRequirements(); + } + return Collections.EMPTY_SET; + + } + + // --------------------------------------- + // Functionalities + // --------------------------------------- + + private IAnalysisModule createModule() { + IAnalysisModule module = null; + try { + module = (IAnalysisModule) fCe.createExecutableExtension(TmfAnalysisModuleSourceConfigElement.ANALYSIS_MODULE_ATTR); + module.setName(getName()); + module.setId(getId()); + } catch (CoreException e) { + Activator.logError("Error getting analysis modules from configuration files", e); //$NON-NLS-1$ + } + return module; + } + + @Override + public IAnalysisModule newModule(ITmfTrace trace) throws TmfAnalysisException { + + /* Check that analysis can be executed */ + if (!appliesToTraceType(trace.getClass())) { + throw new TmfAnalysisException(NLS.bind(Messages.TmfAnalysisModuleHelper_AnalysisDoesNotApply, getName())); + } + + IAnalysisModule module = createModule(); + if (module == null) { + return null; + } + + module.setAutomatic(isAutomatic()); + + /* Get the module's parameters */ + final IConfigurationElement[] parametersCE = fCe.getChildren(TmfAnalysisModuleSourceConfigElement.PARAMETER_ELEM); + for (IConfigurationElement element : parametersCE) { + module.addParameter(element.getAttribute(TmfAnalysisModuleSourceConfigElement.NAME_ATTR)); + String defaultValue = element.getAttribute(TmfAnalysisModuleSourceConfigElement.DEFAULT_VALUE_ATTR); + if (defaultValue != null) { + module.setParameter(element.getAttribute(TmfAnalysisModuleSourceConfigElement.NAME_ATTR), defaultValue); + } + } + module.setTrace(trace); + TmfAnalysisManager.analysisModuleCreated(module); + + return module; + + } + + @Override + public String getHelpText(@NonNull ITmfTrace trace) { + IAnalysisModule module = createModule(); + if (module != null) { + String ret = module.getHelpText(trace); + module.dispose(); + return ret; + } + return getHelpText(); + + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisModuleOutputs.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisModuleOutputs.java new file mode 100644 index 0000000000..7436e7e079 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisModuleOutputs.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.analysis; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.InvalidRegistryObjectException; +import org.eclipse.core.runtime.Platform; +import org.eclipse.tracecompass.internal.tmf.core.Activator; + +/** + * Utility class for accessing TMF analysis module extensions from the + * platform's extensions registry and returning the modules' outputs, wrapped as + * new module listeners. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfAnalysisModuleOutputs { + + /** Extension point ID */ + public static final String TMF_ANALYSIS_TYPE_ID = "org.eclipse.linuxtools.tmf.core.analysis"; //$NON-NLS-1$ + + /** Extension point element 'output' */ + public static final String OUTPUT_ELEM = "output"; //$NON-NLS-1$ + + /** Extension point attribute 'outputClass' */ + public static final String CLASS_ATTR = "class"; //$NON-NLS-1$ + + /** Extension point attribute 'id' */ + public static final String ID_ATTR = "id"; //$NON-NLS-1$ + + /** + * Extension point element 'analysisId' to associate the output to a single + * analysis + */ + public static final String ANALYSIS_ID_ELEM = "analysisId"; //$NON-NLS-1$ + + /** + * Extension point element 'analysisModuleClass' to associate the output + * with an analysis module class + */ + public static final String MODULE_CLASS_ELEM = "analysisModuleClass"; //$NON-NLS-1$ + + private TmfAnalysisModuleOutputs() { + + } + + /** + * Return the analysis module outputs, wrapped as new module listeners, + * advertised in the extension point, in iterable format. + * + * @return List of {@link ITmfNewAnalysisModuleListener} + */ + public static Iterable getOutputListeners() { + List newModuleListeners = new ArrayList<>(); + // Get the sources element from the extension point + IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_ANALYSIS_TYPE_ID); + for (IConfigurationElement ce : config) { + String elementName = ce.getName(); + if (elementName.equals(OUTPUT_ELEM)) { + try { + IAnalysisOutput output = (IAnalysisOutput) ce.createExecutableExtension(CLASS_ATTR); + ITmfNewAnalysisModuleListener listener = null; + for (IConfigurationElement childCe : ce.getChildren()) { + if (childCe.getName().equals(ANALYSIS_ID_ELEM)) { + listener = new TmfNewAnalysisOutputListener(output, childCe.getAttribute(ID_ATTR), null); + } else if (childCe.getName().equals(MODULE_CLASS_ELEM)) { + listener = new TmfNewAnalysisOutputListener(output, null, childCe.createExecutableExtension(CLASS_ATTR).getClass().asSubclass(IAnalysisModule.class)); + } + } + if (listener != null) { + newModuleListeners.add(listener); + } + } catch (InvalidRegistryObjectException | CoreException e) { + Activator.logError("Error creating module output listener", e); //$NON-NLS-1$ + } + } + } + return newModuleListeners; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisRequirement.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisRequirement.java new file mode 100644 index 0000000000..2eeb89169e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisRequirement.java @@ -0,0 +1,291 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Rail - Initial API and implementation + * Guilliano Molaire - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.analysis; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceWithPreDefinedEvents; +import org.eclipse.tracecompass.tmf.core.trace.TmfEventTypeCollectionHelper; + +/** + * Class that contains all the values associated with a type needed by an + * analysis in order to execute. Each value is peered with a level that + * determines the importance of that specific value for the requirement. + * + * The type gives an indication about the kind of value the requirement + * contains. The value should depend on the type. For instance, a requirement + * type could be "event" and all the values that would be added in the + * requirement object could indicate the possible events handled by the + * analysis. + * + * For these values, a level will be assigned indicating how important the value + * is based on two possibilities: Mandatory or optional. + * + * Moreover, useful information that can not be leveled with a priority but are + * important for the proper execution of an analysis can be added. + * + * @author Guilliano Molaire + * @author Mathieu Rail + * @since 3.0 + */ +public class TmfAnalysisRequirement { + + /** + * String for requirement type 'event', that can be used by analysis + */ + public static final String TYPE_EVENT = "event"; //$NON-NLS-1$ + + private final String fType; + private final Map fValues = new HashMap<>(); + private final Set fInformation = new HashSet<>(); + + /** + * The possible level for each value. They must be listed in ascending order + * of priority. + */ + public enum ValuePriorityLevel { + /** The value could be absent and the analysis would still work */ + OPTIONAL, + /** The value must be present at runtime (for the analysis) */ + MANDATORY + } + + /** + * Constructor + * + * @param type + * The type of the requirement + */ + public TmfAnalysisRequirement(String type) { + fType = type; + } + + /** + * Constructor. Instantiate a requirement object with a list of values of + * the same level + * + * @param type + * The type of the requirement + * @param values + * All the values associated with that type + * @param level + * A level associated with all the values + */ + public TmfAnalysisRequirement(String type, Iterable values, ValuePriorityLevel level) { + fType = type; + addValues(values, level); + } + + /** + * Merges the values of the specified requirement with those of this + * requirement. All new values will retain their priority value level. If a + * value was already inside the current requirement, the current priority + * level will be overridden if the new priority level is higher. + * + * @param subRequirement + * The requirement to be merged into the current one + * @param maxSubRequirementValueLevel + * The level associated with all the new values or currently + * lower priority ones + * @return True if the merge was successful + */ + public Boolean merge(TmfAnalysisRequirement subRequirement, ValuePriorityLevel maxSubRequirementValueLevel) { + /* Two requirements can't be merged if their types are different */ + if (!isSameType(subRequirement)) { + return false; + } + + Set values = subRequirement.getValues(); + for (String value : values) { + /* + * Sub-requirement value levels are limited to + * maxSubRequirementValueLevel, so the level associated with the + * values in the merge is the minimum value between + * maxSubRequirementValueLevel and its true level. + */ + int minLevel = Math.min(subRequirement.getValueLevel(value).ordinal(), maxSubRequirementValueLevel.ordinal()); + ValuePriorityLevel subRequirementValueLevel = ValuePriorityLevel.values()[minLevel]; + + if (fValues.containsKey(value)) { + /* + * If a value is already in a requirement, we update the level + * by the highest value between the current level in the + * requirement and the level of the value in the + * sub-requirement. + */ + ValuePriorityLevel requirementValueLevel = getValueLevel(value); + + int newValueLevel = Math.max(requirementValueLevel.ordinal(), subRequirementValueLevel.ordinal()); + ValuePriorityLevel highestLevel = ValuePriorityLevel.values()[newValueLevel]; + addValue(value, highestLevel); + } + else { + addValue(value, subRequirementValueLevel); + } + } + + /* Merge the information */ + fInformation.addAll(subRequirement.getInformation()); + + return true; + } + + /** + * Adds a list of value inside the requirement with the same level. + * + * @param values + * A list of value + * @param level + * The level associated with all the values + */ + public void addValues(Iterable values, ValuePriorityLevel level) { + for (String value : values) { + addValue(value, level); + } + } + + /** + * Adds a value with his associated level into the requirement. If the value + * is already contained in the requirement the method modifies its existing + * value level. + * + * @param value + * The value + * @param level + * The level + */ + public void addValue(String value, ValuePriorityLevel level) { + synchronized (fValues) { + fValues.put(value, level); + } + } + + /** + * Adds an information about the requirement. + * + * @param information + * The information to be added + */ + public void addInformation(String information) { + fInformation.add(information); + } + + /** + * Determines if the analysis requirement has the same type of another + * requirement. + * + * @param requirement + * Requirement whose type is to be compared to this requirement's + * type. + * @return True if the two requirements have the same type; otherwise false + */ + public Boolean isSameType(TmfAnalysisRequirement requirement) { + return fType.equals(requirement.getType()); + } + + /** + * Gets the requirement type. The type is read only. + * + * @return The type of this requirement + */ + public String getType() { + return fType; + } + + /** + * Gets all the values associated with the requirement. + * + * @return Set containing the values + */ + public Set getValues() { + synchronized (fValues) { + return fValues.keySet(); + } + } + + /** + * Gets all the values associated with the requirement with a given priority + * level. + * + * @param level + * The desired level + * @return Set containing the values with the given priority level + */ + public Set getValues(ValuePriorityLevel level) { + synchronized (fValues) { + Set values = new HashSet<>(); + for (Entry entry : fValues.entrySet()) { + if (entry.getValue() == level) { + values.add(entry.getKey()); + } + } + return values; + } + } + + /** + * Gets information about the requirement. + * + * @return The set of all the information + */ + public Set getInformation() { + return fInformation; + } + + /** + * Gets the level associated with a particular type + * + * @param value + * The value + * @return The level or null if the value does not exist + */ + public ValuePriorityLevel getValueLevel(String value) { + synchronized (fValues) { + return fValues.get(value); + } + } + + /** + * Verifies whether a trace fulfills this requirement + * + * @param trace + * The trace on which to check for this requirement + * @return True if the trace has all mandatory values of this requirement + */ + public boolean isFulfilled(@NonNull ITmfTrace trace) { + switch (fType) { + case TYPE_EVENT: + if (trace instanceof ITmfTraceWithPreDefinedEvents) { + Set traceEvents = TmfEventTypeCollectionHelper.getEventNames(((ITmfTraceWithPreDefinedEvents) trace).getContainedEventTypes()); + Set mandatoryValues = getValues(ValuePriorityLevel.MANDATORY); + return traceEvents.containsAll(mandatoryValues); + } + break; + default: + return true; + } + return true; + } + + @Override + public String toString() { + return fType + ": " + fValues; //$NON-NLS-1$ + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisRequirementHelper.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisRequirementHelper.java new file mode 100644 index 0000000000..7840962f89 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisRequirementHelper.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Guilliano Molaire - Initial API and implementation + * Mathieu Rail - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.analysis; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement.ValuePriorityLevel; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.SetMultimap; + +/** + * Helper class to simplify analysis requirement management. + * + * @author Guilliano Molaire + * @since 3.0 + */ +public final class TmfAnalysisRequirementHelper { + + /** + * Private constructor. The class should not be instantiated. + */ + private TmfAnalysisRequirementHelper() { + } + + /** + * Gets the requirement values of a given type from an analysis requirement + * provider. Only values linked to the type will be returned. + * + * @param provider + * The analysis requirement provider + * @param type + * The type of the requirement values we need + * @return The list of values for the specified type + */ + public static Set getRequirementValues(IAnalysisRequirementProvider provider, String type) { + Set values = new HashSet<>(); + for (TmfAnalysisRequirement requirement : provider.getAnalysisRequirements()) { + if (requirement.getType().equalsIgnoreCase(type)) { + values.addAll(requirement.getValues()); + } + } + return values; + } + + /** + * Gets the requirement values of a given type from an analysis requirement + * provider, with the specified level. Only values associated with that type + * and level will be returned. + * + * @param provider + * The analysis requirement provider + * @param type + * The type of the requirement values we need + * @param level + * The priority level of the values to be returned + * @return The list of values for the specified type + */ + public static Set getRequirementValues(IAnalysisRequirementProvider provider, String type, ValuePriorityLevel level) { + Set values = new HashSet<>(); + for (TmfAnalysisRequirement requirement : provider.getAnalysisRequirements()) { + if (requirement.getType().equalsIgnoreCase(type)) { + for (String value : requirement.getValues()) { + if (requirement.getValueLevel(value) == level) { + values.add(value); + } + } + } + } + return values; + } + + /** + * Gets a map in which the keys are the types of different requirements and + * the values represent a set of requirement values linked to that type. + * + * @param providers + * The set of analysis requirement provider + * @return A map with the values keyed by type + */ + public static SetMultimap getRequirementValuesMap(Iterable providers) { + SetMultimap valuesByType = HashMultimap.create(); + for (IAnalysisRequirementProvider provider : providers) { + for (TmfAnalysisRequirement requirement : provider.getAnalysisRequirements()) { + valuesByType.putAll(requirement.getType(), requirement.getValues()); + } + } + return valuesByType; + } + + /** + * Gets a map in which the keys are the types of different requirements and + * the values represents a list of requirement values linked to that type. + * We only take values with the same priority level as the argument. + * + * @param providers + * The set of analysis requirement provider + * @param level + * The priority level of the values to be returned + * @return A map with the values keyed by type + */ + public static SetMultimap getRequirementValuesMap(Iterable providers, ValuePriorityLevel level) { + SetMultimap valuesByType = HashMultimap.create(); + for (IAnalysisRequirementProvider provider : providers) { + for (TmfAnalysisRequirement requirement : provider.getAnalysisRequirements()) { + /* Since it's a set, there will be no duplicate */ + for (String value : requirement.getValues()) { + if (requirement.getValueLevel(value) == level) { + valuesByType.put(requirement.getType(), value); + } + } + } + } + return valuesByType; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfNewAnalysisOutputListener.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfNewAnalysisOutputListener.java new file mode 100644 index 0000000000..b32fc7ad29 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfNewAnalysisOutputListener.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.analysis; + +/** + * This class listens when new analysis modules are created and registers an + * output if the module corresponds to the output specifications + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfNewAnalysisOutputListener implements ITmfNewAnalysisModuleListener { + + private final String fAnalysisId; + private final Class fAnalysisModuleClass; + private final IAnalysisOutput fOutput; + + /** + * Constructor + * + * @param output + * The analysis output to add if the analysis corresponds to the + * ID or class + * @param analysisId + * The analysis ID of the single analysis to match + * @param moduleClass + * The module class this output applies to + */ + public TmfNewAnalysisOutputListener(IAnalysisOutput output, String analysisId, Class moduleClass) { + fOutput = output; + fAnalysisId = analysisId; + fAnalysisModuleClass = moduleClass; + } + + @Override + public void moduleCreated(IAnalysisModule module) { + if (fAnalysisId != null) { + if (module.getId().equals(fAnalysisId)) { + module.registerOutput(fOutput); + } + } else if (fAnalysisModuleClass != null) { + if (fAnalysisModuleClass.isAssignableFrom(module.getClass())) { + module.registerOutput(fOutput); + } + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/messages.properties b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/messages.properties new file mode 100644 index 0000000000..1cd4123a28 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/messages.properties @@ -0,0 +1,24 @@ +############################################################################### +# Copyright (c) 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### +TmfAbstractAnalysisModule_TraceSetMoreThanOnce=Trace was set more than once for analysis "{0}" +TmfAbstractAnalysisModule_AnalysisCannotExecute=Cannot perform analysis "{0}" on this trace because the trace does not have the required characteristics +TmfAnalysisModuleHelper_AnalysisDoesNotApply=Cannot perform analysis "{0}" on this trace because the trace is of the wrong type. +TmfAbstractAnalysisModule_AnalysisForTrace=Analysis module: {0} for trace {1} +TmfAbstractAnalysisModule_AnalysisModule=Analysis module: {0} +TmfAbstractAnalysisModule_InvalidParameter=Parameter {0} is not valid for analysis module {1} +TmfAbstractAnalysisModule_NullTrace=Setting a null trace to analysis module +TmfAnalysis_RequirementInformation=Additional information: {0} +TmfAnalysis_RequirementMandatoryValues=Mandatory values: {0} +TmfAnalysis_RequirementNotFulfilled=Requirement not fulfilled: {0} +TmfAbstractAnalysisModule_RunningAnalysis=Running analysis {0} +TmfAnalysisManager_ErrorParameterProvider=Error instantiating parameter provider +TmfAnalysisModuleHelper_ImpossibleToCreateModule=Could not instantiate module "{0}" diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/callstack/CallStackStateProvider.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/callstack/CallStackStateProvider.java new file mode 100644 index 0000000000..23f24fab88 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/callstack/CallStackStateProvider.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.callstack; + +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; +import org.eclipse.osgi.util.NLS; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * The state provider for traces that support the Call Stack view. + * + * The attribute tree should have the following structure: + *

+ * (root)
+ *   \-- Threads
+ *        |-- (Thread 1)
+ *        |    \-- CallStack (stack-attribute)
+ *        |         |-- 1
+ *        |         |-- 2
+ *        |        ...
+ *        |         \-- n
+ *        |-- (Thread 2)
+ *        |    \-- CallStack (stack-attribute)
+ *        |         |-- 1
+ *        |         |-- 2
+ *        |        ...
+ *        |         \-- n
+ *       ...
+ *        \-- (Thread n)
+ *             \-- CallStack (stack-attribute)
+ *                  |-- 1
+ *                  |-- 2
+ *                 ...
+ *                  \-- n
+ *
+ * where: + *
+ * (Thread n) is an attribute whose name is the display name of the thread. + * Optionally, its value is a long representing the thread id, used for sorting. + *
+ * CallStack is a stack-attribute whose pushed values are either a string, + * int or long representing the function name or address in the call stack. + * The type of value used must be constant for a particular CallStack. + * + * @author Patrick Tasse + * @since 2.0 + */ +public abstract class CallStackStateProvider extends AbstractTmfStateProvider { + + /** Thread attribute */ + public static final String THREADS = "Threads"; //$NON-NLS-1$ + /** CallStack stack-attribute */ + public static final String CALL_STACK = "CallStack"; //$NON-NLS-1$ + /** Undefined function exit name */ + public static final String UNDEFINED = "UNDEFINED"; //$NON-NLS-1$ + + /** CallStack state system ID */ + private static final String ID = "org.eclipse.linuxtools.tmf.callstack"; //$NON-NLS-1$ + /** Dummy function name for when no function is expected */ + private static final String NO_FUNCTION = "no function"; //$NON-NLS-1$ + + /** + * Default constructor + * + * @param trace + * The trace for which we build this state system + */ + public CallStackStateProvider(ITmfTrace trace) { + super(trace, ITmfEvent.class, ID); + } + + @Override + protected void eventHandle(ITmfEvent event) { + if (!considerEvent(event)) { + return; + } + try { + /* Check if the event is a function entry */ + String functionEntryName = functionEntry(event); + if (functionEntryName != null) { + long timestamp = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + String thread = getThreadName(event); + int threadQuark = ss.getQuarkAbsoluteAndAdd(THREADS, thread); + Long threadId = getThreadId(event); + if (threadId != null) { + ss.updateOngoingState(TmfStateValue.newValueLong(threadId), threadQuark); + } + int callStackQuark = ss.getQuarkRelativeAndAdd(threadQuark, CALL_STACK); + ITmfStateValue value = TmfStateValue.newValueString(functionEntryName); + ss.pushAttribute(timestamp, value, callStackQuark); + return; + } + + /* Check if the event is a function exit */ + String functionExitName = functionExit(event); + if (functionExitName != null) { + long timestamp = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + String thread = getThreadName(event); + int quark = ss.getQuarkAbsoluteAndAdd(THREADS, thread, CALL_STACK); + ITmfStateValue poppedValue = ss.popAttribute(timestamp, quark); + String poppedName = (poppedValue == null ? NO_FUNCTION : poppedValue.unboxStr()); + + /* + * Verify that the value we are popping matches the one in the + * event field, unless the latter is undefined. + */ + if (!functionExitName.equals(UNDEFINED) && + !functionExitName.equals(poppedName)) { + Activator.logWarning(NLS.bind( + Messages.CallStackStateProvider_UnmatchedPoppedValue, + functionExitName, + poppedName)); + } + } + + } catch (TimeRangeException e) { + e.printStackTrace(); + } catch (AttributeNotFoundException e) { + e.printStackTrace(); + } catch (StateValueTypeException e) { + e.printStackTrace(); + } + } + + /** + * Check if this event should be considered at all for function entry/exit + * analysis. This check is only run once per event, before + * {@link #functionEntry} and {@link #functionExit} (to avoid repeating + * checks in those methods). + * + * @param event + * The event to check + * @return If false, the event will be ignored by the state provider. If + * true processing will continue. + * @since 3.0 + */ + protected abstract boolean considerEvent(ITmfEvent event); + + /** + * Check an event if it indicates a function entry. + * + * @param event + * An event to check for function entry + * @return The function name of the function entry, or null if not a + * function entry. + */ + protected abstract String functionEntry(ITmfEvent event); + + /** + * Check an event if it indicates a function exit. + * + * @param event + * An event to check for function exit + * @return The function name, or UNDEFINED, for a function exit, or null if + * not a function exit. + */ + protected abstract String functionExit(ITmfEvent event); + + /** + * Return the thread name of a function entry or exit event. + * + * @param event + * The event + * @return The thread name (as will be shown in the view) + * @since 3.0 + */ + protected abstract String getThreadName(ITmfEvent event); + + /** + * Return the thread id of a function entry event. + * + * @param event + * The event + * @return The thread id, or null if undefined + * @since 3.1 + */ + protected Long getThreadId(ITmfEvent event) { + return null; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/callstack/Messages.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/callstack/Messages.java new file mode 100644 index 0000000000..7c59eb3cfa --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/callstack/Messages.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.callstack; + +import org.eclipse.osgi.util.NLS; + +/** + * Message bundle for the call stack state provider. + * + * @since 3.0 + */ +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.core.callstack.messages"; //$NON-NLS-1$ + + /** + * The value popped from a 'func_exit' event doesn't match the current + * function name. + */ + public static String CallStackStateProvider_UnmatchedPoppedValue; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/callstack/messages.properties b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/callstack/messages.properties new file mode 100644 index 0000000000..4603be0526 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/callstack/messages.properties @@ -0,0 +1,13 @@ +############################################################################### +# Copyright (c) 2013 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Alexandre Montplaisir - Initial API and implementation +############################################################################### + +CallStackStateProvider_UnmatchedPoppedValue=Function exit name in event ({0}) different from the expected one ({1}). You may have lost events in your trace. diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/ITmfComponent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/ITmfComponent.java new file mode 100644 index 0000000000..f379320411 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/ITmfComponent.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Add interface for broadcasting signals asynchronously + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.component; + +import org.eclipse.tracecompass.tmf.core.signal.TmfSignal; + +/** + * This is the basic interface of all the TMF components. + *

+ * Currently, it only addresses the inter-component signalling. + * + * @version 1.0 + * @author Francois Chouinard + * + * @see TmfComponent + */ +public interface ITmfComponent { + + /** + * @return the component ID (display name) + */ + String getName(); + + /** + * Dispose of the component + */ + void dispose(); + + /** + * Propagate a signal to all the interested listeners in + * the same thread of execution. + * + * @param signal the signal to broadcast + */ + void broadcast(TmfSignal signal); + + /** + * Propagate a signal to all the interested listeners + * in a separate thread. + * + * @param signal the signal to broadcast + * @since 3.0 + */ + void broadcastAsync(TmfSignal signal); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/ITmfEventProvider.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/ITmfEventProvider.java new file mode 100644 index 0000000000..a5567289e9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/ITmfEventProvider.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.component; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; + +/** + * This is the interface of the data providers in TMF. Data providers have the + * capability of handling data requests. + * + * @author Francois Chouinard + * + * @see TmfEventProvider + * @since 3.0 + */ +public interface ITmfEventProvider extends ITmfComponent { + + /** + * Queue the request for processing. + * + * @param request The request to process + */ + void sendRequest(ITmfEventRequest request); + + /** + * Increments/decrements the pending requests counters and fires the request + * if necessary (counter == 0). Used for coalescing requests across multiple + * TmfDataProvider's. + * + * @param isIncrement + * Should we increment (true) or decrement (false) the pending + * counter + */ + void notifyPendingRequest(boolean isIncrement); + + /** + * Return the next event based on the context supplied. The context + * will be updated for the subsequent read. + * + * @param context the trace read context (updated) + * @return the event referred to by context + */ + ITmfEvent getNext(ITmfContext context); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/TmfComponent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/TmfComponent.java new file mode 100644 index 0000000000..77bfcadcb9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/TmfComponent.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Add interface for broadcasting signals asynchronously + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.component; + +import org.eclipse.tracecompass.internal.tmf.core.TmfCoreTracer; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; + +/** + * This is the base class of the TMF components. + *

+ * Currently, it only addresses the inter-component signaling. + * + * @version 1.0 + * @author Francois Chouinard + */ +public abstract class TmfComponent implements ITmfComponent { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private String fName; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Default constructor. To be used in conjunction with init() + */ + public TmfComponent() { + this(""); //$NON-NLS-1$ + } + + /** + * Perform component initialization and register it as a signal listener. + * Need to be called when the default constructor was used. + * + * @param name + * the component name + */ + public void init(String name) { + TmfCoreTracer.traceComponent(this, "created"); //$NON-NLS-1$ + fName = name; + TmfSignalManager.register(this); + } + + /** + * The standard constructor + * + * @param name + * the component name + */ + public TmfComponent(String name) { + init(name); + } + + /** + * The copy constructor + * + * @param other + * the other component + */ + public TmfComponent(TmfComponent other) { + init(other.fName); + } + + // ------------------------------------------------------------------------ + // Getters/setters + // ------------------------------------------------------------------------ + + @Override + public String getName() { + return fName; + } + + /** + * @param name + * the new component name + */ + protected void setName(String name) { + fName = name; + } + + // ------------------------------------------------------------------------ + // ITmfComponent + // ------------------------------------------------------------------------ + + @Override + public void dispose() { + TmfSignalManager.deregister(this); + TmfCoreTracer.traceComponent(this, "disposed"); //$NON-NLS-1$ + } + + @Override + public void broadcast(TmfSignal signal) { + TmfSignalManager.dispatchSignal(signal); + } + + /** + * @since 3.0 + */ + @Override + public void broadcastAsync(TmfSignal signal) { + TmfSignalManager.dispatchSignalAsync(signal); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/TmfEventProvider.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/TmfEventProvider.java new file mode 100644 index 0000000000..5c43e53884 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/TmfEventProvider.java @@ -0,0 +1,439 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation, replace background + * requests by preemptable requests + * Alexandre Montplaisir - Merge with TmfDataProvider + * Bernd Hufmann - Add timer based coalescing for background requests + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.component; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; + +import org.eclipse.tracecompass.internal.tmf.core.TmfCoreTracer; +import org.eclipse.tracecompass.internal.tmf.core.component.TmfEventThread; +import org.eclipse.tracecompass.internal.tmf.core.component.TmfProviderManager; +import org.eclipse.tracecompass.internal.tmf.core.request.TmfCoalescedEventRequest; +import org.eclipse.tracecompass.internal.tmf.core.request.TmfRequestExecutor; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType; +import org.eclipse.tracecompass.tmf.core.signal.TmfEndSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfStartSynchSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; + +/** + * An abstract base class that implements ITmfEventProvider. + *

+ * This abstract class implements the housekeeping methods to register/ + * de-register the event provider and to handle generically the event requests. + *

+ * + * @author Francois Chouinard + * @since 3.0 + */ +public abstract class TmfEventProvider extends TmfComponent implements ITmfEventProvider { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** Default amount of events per request "chunk" + * @since 3.0 */ + public static final int DEFAULT_BLOCK_SIZE = 50000; + + /** Delay for coalescing background requests (in milli-seconds) */ + private static final long DELAY = 1000; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** List of coalesced requests */ + private final List fPendingCoalescedRequests = new LinkedList<>(); + + /** The type of event handled by this provider */ + private Class fType; + + private final TmfRequestExecutor fExecutor; + + private final Object fLock = new Object(); + + private int fSignalDepth = 0; + + private int fRequestPendingCounter = 0; + + private Timer fTimer; + + private boolean fIsTimeout = false; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + public TmfEventProvider() { + super(); + fExecutor = new TmfRequestExecutor(); + } + + /** + * Standard constructor. Instantiate and initialize at the same time. + * + * @param name + * Name of the provider + * @param type + * The type of events that will be handled + */ + public TmfEventProvider(String name, Class type) { + this(); + init(name, type); + } + + /** + * Initialize this data provider + * + * @param name + * Name of the provider + * @param type + * The type of events that will be handled + */ + public void init(String name, Class type) { + super.init(name); + fType = type; + fExecutor.init(); + + fSignalDepth = 0; + + synchronized (fLock) { + fTimer = new Timer(); + } + + TmfProviderManager.register(fType, this); + } + + @Override + public void dispose() { + TmfProviderManager.deregister(fType, this); + fExecutor.stop(); + synchronized (fLock) { + if (fTimer != null) { + fTimer.cancel(); + } + fTimer = null; + } + super.dispose(); + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * Get the event type this provider handles + * + * @return The type of ITmfEvent + */ + public Class getType() { + return fType; + } + + // ------------------------------------------------------------------------ + // ITmfRequestHandler + // ------------------------------------------------------------------------ + + /** + * @since 3.0 + */ + @Override + public void sendRequest(final ITmfEventRequest request) { + synchronized (fLock) { + if (request.getExecType() == ExecutionType.FOREGROUND) { + if ((fSignalDepth > 0) || (fRequestPendingCounter > 0)) { + coalesceEventRequest(request); + } else { + queueRequest(request); + } + return; + } + + /* + * Dispatch request in case timer is not running. + */ + if (fTimer == null) { + queueRequest(request); + return; + } + + /* + * For the first background request in the request pending queue + * a timer will be started to allow other background requests to + * coalesce. + */ + boolean startTimer = (getNbPendingBackgroundRequests() == 0); + coalesceEventRequest(request); + if (startTimer) { + TimerTask task = new TimerTask() { + @Override + public void run() { + synchronized (fLock) { + fIsTimeout = true; + fireRequest(); + } + } + }; + fTimer.schedule(task, DELAY); + } + } + } + + private void fireRequest() { + synchronized (fLock) { + if (fRequestPendingCounter > 0) { + return; + } + + if (fPendingCoalescedRequests.size() > 0) { + Iterator iter = fPendingCoalescedRequests.iterator(); + while (iter.hasNext()) { + ExecutionType type = (fIsTimeout ? ExecutionType.BACKGROUND : ExecutionType.FOREGROUND); + ITmfEventRequest request = iter.next(); + if (type == request.getExecType()) { + queueRequest(request); + iter.remove(); + } + } + } + } + } + + /** + * Increments/decrements the pending requests counters and fires the request + * if necessary (counter == 0). Used for coalescing requests across multiple + * TmfDataProvider's. + * + * @param isIncrement + * Should we increment (true) or decrement (false) the pending + * counter + */ + @Override + public void notifyPendingRequest(boolean isIncrement) { + synchronized (fLock) { + if (isIncrement) { + fRequestPendingCounter++; + } else { + if (fRequestPendingCounter > 0) { + fRequestPendingCounter--; + } + + // fire request if all pending requests are received + if (fRequestPendingCounter == 0) { + fireRequest(); + } + } + } + } + + // ------------------------------------------------------------------------ + // Coalescing + // ------------------------------------------------------------------------ + + /** + * Create a new request from an existing one, and add it to the coalesced + * requests + * + * @param request + * The request to copy + * @since 3.0 + */ + protected void newCoalescedEventRequest(ITmfEventRequest request) { + synchronized (fLock) { + TmfCoalescedEventRequest coalescedRequest = new TmfCoalescedEventRequest( + request.getDataType(), + request.getRange(), + request.getIndex(), + request.getNbRequested(), + request.getExecType()); + coalescedRequest.addRequest(request); + if (TmfCoreTracer.isRequestTraced()) { + TmfCoreTracer.traceRequest(request, "COALESCED with " + coalescedRequest.getRequestId()); //$NON-NLS-1$ + TmfCoreTracer.traceRequest(coalescedRequest, "now contains " + coalescedRequest.getSubRequestIds()); //$NON-NLS-1$ + } + fPendingCoalescedRequests.add(coalescedRequest); + } + } + + /** + * Add an existing requests to the list of coalesced ones + * + * @param request + * The request to add to the list + * @since 3.0 + */ + protected void coalesceEventRequest(ITmfEventRequest request) { + synchronized (fLock) { + for (TmfCoalescedEventRequest coalescedRequest : fPendingCoalescedRequests) { + if (coalescedRequest.isCompatible(request)) { + coalescedRequest.addRequest(request); + if (TmfCoreTracer.isRequestTraced()) { + TmfCoreTracer.traceRequest(request, "COALESCED with " + coalescedRequest.getRequestId()); //$NON-NLS-1$ + TmfCoreTracer.traceRequest(coalescedRequest, "now contains " + coalescedRequest.getSubRequestIds()); //$NON-NLS-1$ + } + return; + } + } + newCoalescedEventRequest(request); + } + } + + /** + * Gets the number of background requests in pending queue. + * + * @return the number of background requests in pending queue + */ + private int getNbPendingBackgroundRequests() { + int nbBackgroundRequests = 0; + synchronized (fLock) { + for (ITmfEventRequest request : fPendingCoalescedRequests) { + if (request.getExecType() == ExecutionType.BACKGROUND) { + nbBackgroundRequests++; + } + } + } + return nbBackgroundRequests; + } + + // ------------------------------------------------------------------------ + // Request processing + // ------------------------------------------------------------------------ + + /** + * Queue a request. + * + * @param request + * The data request + * @since 3.0 + */ + protected void queueRequest(final ITmfEventRequest request) { + + if (fExecutor.isShutdown()) { + request.cancel(); + return; + } + + TmfEventThread thread = new TmfEventThread(this, request); + + if (TmfCoreTracer.isRequestTraced()) { + TmfCoreTracer.traceRequest(request, "QUEUED"); //$NON-NLS-1$ + } + + fExecutor.execute(thread); + } + + /** + * Initialize the provider based on the request. The context is provider + * specific and will be updated by getNext(). + * + * @param request + * The request + * @return An application specific context; null if request can't be + * serviced + * @since 3.0 + */ + public abstract ITmfContext armRequest(ITmfEventRequest request); + + /** + * Checks if the data meets the request completion criteria. + * + * @param request + * The request + * @param event + * The data to verify + * @param nbRead + * The number of events read so far + * @return true if completion criteria is met + * @since 3.0 + */ + public boolean isCompleted(ITmfEventRequest request, ITmfEvent event, int nbRead) { + boolean requestCompleted = isCompleted2(request, nbRead); + if (!requestCompleted) { + ITmfTimestamp endTime = request.getRange().getEndTime(); + return event.getTimestamp().compareTo(endTime, false) > 0; + } + return requestCompleted; + } + + private static boolean isCompleted2(ITmfEventRequest request,int nbRead) { + return request.isCompleted() || nbRead >= request.getNbRequested(); + } + + // ------------------------------------------------------------------------ + // Pass-through's to the request executor + // ------------------------------------------------------------------------ + + /** + * @return the shutdown state (i.e. if it is accepting new requests) + * @since 2.0 + */ + protected boolean executorIsShutdown() { + return fExecutor.isShutdown(); + } + + /** + * @return the termination state + * @since 2.0 + */ + protected boolean executorIsTerminated() { + return fExecutor.isTerminated(); + } + + // ------------------------------------------------------------------------ + // Signal handlers + // ------------------------------------------------------------------------ + + /** + * Handler for the start synch signal + * + * @param signal + * Incoming signal + */ + @TmfSignalHandler + public void startSynch(TmfStartSynchSignal signal) { + synchronized (fLock) { + fSignalDepth++; + } + } + + /** + * Handler for the end synch signal + * + * @param signal + * Incoming signal + */ + @TmfSignalHandler + public void endSynch(TmfEndSynchSignal signal) { + synchronized (fLock) { + fSignalDepth--; + if (fSignalDepth == 0) { + fIsTimeout = false; + fireRequest(); + } + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfCustomAttributes.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfCustomAttributes.java new file mode 100644 index 0000000000..d9f985ec36 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfCustomAttributes.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Simon Delisle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event; + +import java.util.Set; + +/** + * Interface for events to implement to provide information about custom + * attributes. + * + * @author Simon Delisle + * @since 2.0 + */ +public interface ITmfCustomAttributes { + + /** + * List the custom attributes of this event. + * + * @return The list of custom attribute names. Should not be null, but could + * be empty. + */ + Set listCustomAttributes(); + + /** + * Get the value of a custom attribute. + * + * @param name + * Name of the the custom attribute + * @return Value of this attribute, or null if there is no attribute with + * that name + */ + String getCustomAttribute(String name); +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfEvent.java new file mode 100644 index 0000000000..6c2d6ace25 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfEvent.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * The generic event structure in TMF. In its canonical form, an event has: + *
    + *
  • a parent trace + *
  • a rank (order within the trace) + *
  • a timestamp + *
  • a source (reporting component) + *
  • a type + *
  • a content (payload) + *
+ * For convenience, a free-form reference field is also provided. It could be + * used as e.g. a location marker (filename:lineno) to indicate where the event + * was generated. + * + * @version 1.0 + * @author Francois Chouinard + * + * @see ITmfTimestamp + * @see ITmfEventType + * @see ITmfEventField + * @see TmfEvent + */ +public interface ITmfEvent extends IAdaptable { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * Pre-defined event timestamp attribute (for searching &filtering purposes) + */ + public static final @NonNull String EVENT_FIELD_TIMESTAMP = ":timestamp:"; //$NON-NLS-1$ + + /** + * Pre-defined event source attribute (for searching &filtering purposes) + */ + public static final @NonNull String EVENT_FIELD_SOURCE = ":source:"; //$NON-NLS-1$ + + /** + * Pre-defined event type attribute (for searching &filtering purposes) + */ + public static final @NonNull String EVENT_FIELD_TYPE = ":type:"; //$NON-NLS-1$ + + /** + * Pre-defined event content attribute (for searching &filtering purposes) + */ + public static final @NonNull String EVENT_FIELD_CONTENT = ":content:"; //$NON-NLS-1$ + + /** + * Pre-defined event reference attribute (for searching &filtering purposes) + */ + public static final @NonNull String EVENT_FIELD_REFERENCE = ":reference:"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Getters + // ------------------------------------------------------------------------ + + /** + * @return the trace that 'owns' the event + */ + ITmfTrace getTrace(); + + /** + * @return the event rank within the parent trace + */ + long getRank(); + + /** + * @return the event timestamp + * @since 2.0 + */ + ITmfTimestamp getTimestamp(); + + /** + * @return the event source + */ + String getSource(); + + /** + * @return the event type + */ + ITmfEventType getType(); + + /** + * @return the event content + */ + ITmfEventField getContent(); + + /** + * @return the event reference + */ + String getReference(); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfEventField.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfEventField.java new file mode 100644 index 0000000000..b94a10ea5c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfEventField.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Alexandre Montplaisir - Removed arrays from the API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event; + +import java.util.Collection; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The generic event payload in TMF. Each field can be either a terminal or + * further decomposed into subfields. + * + * @version 1.0 + * @author Francois Chouinard + * + * @see ITmfEvent + * @see ITmfEventType + */ +public interface ITmfEventField { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The root field id (the main container) + */ + public static final @NonNull String ROOT_FIELD_ID = ":root:"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Getters + // ------------------------------------------------------------------------ + + /** + * @return the field name + */ + String getName(); + + /** + * @return the field value + */ + Object getValue(); + + /** + * @return the value formatted as string + * @since 2.0 + */ + String getFormattedValue(); + + /** + * Return the subfield names. The iteration order is the same as + * {@link #getFields()}. The returned Collection is immutable. + * + * @return The subfield names (empty Collection if none) + * @since 3.0 + */ + Collection getFieldNames(); + + /** + * Return the subfield. The iteration order is the same as + * {@link #getFieldNames()}. The returned Collection is immutable. + * + * @return The subfields (empty Collection if none) + * @since 3.0 + */ + Collection getFields(); + + /** + * @param name The name of the field + * @return a specific subfield by name (null if absent or inexistent) + */ + ITmfEventField getField(String name); + + /** + * Gets the a sub-field of this field, which may be multiple levels down. + * + * @param path + * Array of field names to recursively go through + * @return The field at the end, or null if a field in the path cannot be + * found + * @since 3.0 + */ + ITmfEventField getSubField(String... path); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfEventType.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfEventType.java new file mode 100644 index 0000000000..4a3a107d83 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfEventType.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event; + +import java.util.Collection; + +/** + * The generic event type in TMF. It contains a reference to the full field structure + * for that event type. + *

+ * Types are unique within their context space. + * + * @version 1.0 + * @author Francois Chouinard + * + * @see ITmfEvent + * @see ITmfEventField + */ +public interface ITmfEventType { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The default event type content + */ + public static final String DEFAULT_CONTEXT_ID = "TmfContext"; //$NON-NLS-1$ + + /** + * The default event type name + */ + public static final String DEFAULT_TYPE_ID = "TmfType"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Getters + // ------------------------------------------------------------------------ + + /** + * @return the event type context + */ + String getContext(); + + /** + * @return the event type ID + */ + String getName(); + + /** + * @return the event type root field + */ + ITmfEventField getRootField(); + + /** + * @return the event field names (labels) + * @since 3.0 + */ + Collection getFieldNames(); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfLostEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfLostEvent.java new file mode 100644 index 0000000000..093a487283 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/ITmfLostEvent.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event; + +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; + +/** + * The generic lost event structure in TMF. + * + * In some demanding situations, tracers can be overwhelmed and have a hard time + * keeping up with the flow of events to record. Usually, even if a tracer can't + * keep up, it can at least record the number of events that it lost. + * + * This interface provides the different components (e.g. views) with a mean to + * identify and highlight such events. + * + * This interface extends ITmfEvent by adding the number of lost events for a + * 'problematic' time range. + * + * @see TmfLostEvent + * + * @author Francois Chouinard + * @version 1.0 + * @since 1.2 + */ +public interface ITmfLostEvent extends ITmfEvent { + + // ------------------------------------------------------------------------ + // Getters + // ------------------------------------------------------------------------ + + /** + * @return the 'problem' time range + * @since 2.0 + */ + TmfTimeRange getTimeRange(); + + /** + * @return the number of lost events in the time range + */ + long getNbLostEvents(); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfEvent.java new file mode 100644 index 0000000000..c81f5e451b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfEvent.java @@ -0,0 +1,249 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Updated as per TMF Event Model 1.0 + * Alexandre Montplaisir - Made immutable + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event; + +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * A basic implementation of ITmfEvent. + * + * @version 1.0 + * @author Francois Chouinard + * + * @see ITmfTimestamp + * @see ITmfEventType + * @see ITmfEventField + * @see ITmfTrace + */ +public class TmfEvent extends PlatformObject implements ITmfEvent { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final ITmfTrace fTrace; + private final long fRank; + private final ITmfTimestamp fTimestamp; + private final String fSource; + private final ITmfEventType fType; + private final ITmfEventField fContent; + private final String fReference; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor. All fields have their default value (null) and the + * event rank is set to TmfContext.UNKNOWN_RANK. + */ + public TmfEvent() { + this(null, ITmfContext.UNKNOWN_RANK, null, null, null, null, null); + } + + /** + * Standard constructor. The event rank will be set to TmfContext.UNKNOWN_RANK. + * + * @param trace the parent trace + * @param timestamp the event timestamp + * @param source the event source + * @param type the event type + * @param content the event content (payload) + * @param reference the event reference + * @since 2.0 + + */ + public TmfEvent(final ITmfTrace trace, final ITmfTimestamp timestamp, final String source, + final ITmfEventType type, final ITmfEventField content, final String reference) + { + this(trace, ITmfContext.UNKNOWN_RANK, timestamp, source, type, content, reference); + } + + /** + * Full constructor + * + * @param trace the parent trace + * @param rank the event rank (in the trace) + * @param timestamp the event timestamp + * @param source the event source + * @param type the event type + * @param content the event content (payload) + * @param reference the event reference + * @since 2.0 + */ + public TmfEvent(final ITmfTrace trace, final long rank, final ITmfTimestamp timestamp, final String source, + final ITmfEventType type, final ITmfEventField content, final String reference) + { + fTrace = trace; + fRank = rank; + fTimestamp = timestamp; + fSource = source; + fType = type; + fContent = content; + fReference = reference; + } + + /** + * Copy constructor + * + * @param event the original event + */ + public TmfEvent(final ITmfEvent event) { + if (event == null) { + throw new IllegalArgumentException(); + } + fTrace = event.getTrace(); + fRank = event.getRank(); + fTimestamp = event.getTimestamp(); + fSource = event.getSource(); + fType = event.getType(); + fContent = event.getContent(); + fReference = event.getReference(); + } + + // ------------------------------------------------------------------------ + // ITmfEvent + // ------------------------------------------------------------------------ + + @Override + public ITmfTrace getTrace() { + return fTrace; + } + + @Override + public long getRank() { + return fRank; + } + + /** + * @since 2.0 + */ + @Override + public ITmfTimestamp getTimestamp() { + return fTimestamp; + } + + @Override + public String getSource() { + return fSource; + } + + @Override + public ITmfEventType getType() { + return fType; + } + + @Override + public ITmfEventField getContent() { + return fContent; + } + + @Override + public String getReference() { + return fReference; + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((fTrace == null) ? 0 : fTrace.hashCode()); + result = prime * result + (int) (fRank ^ (fRank >>> 32)); + result = prime * result + ((fTimestamp == null) ? 0 : fTimestamp.hashCode()); + result = prime * result + ((fSource == null) ? 0 : fSource.hashCode()); + result = prime * result + ((fType == null) ? 0 : fType.hashCode()); + result = prime * result + ((fContent == null) ? 0 : fContent.hashCode()); + result = prime * result + ((fReference == null) ? 0 : fReference.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof TmfEvent)) { + return false; + } + final TmfEvent other = (TmfEvent) obj; + if (fTrace == null) { + if (other.fTrace != null) { + return false; + } + } else if (!fTrace.equals(other.fTrace)) { + return false; + } + if (fRank != other.fRank) { + return false; + } + if (fTimestamp == null) { + if (other.fTimestamp != null) { + return false; + } + } else if (!fTimestamp.equals(other.fTimestamp)) { + return false; + } + if (fSource == null) { + if (other.fSource != null) { + return false; + } + } else if (!fSource.equals(other.fSource)) { + return false; + } + if (fType == null) { + if (other.fType != null) { + return false; + } + } else if (!fType.equals(other.fType)) { + return false; + } + if (fContent == null) { + if (other.fContent != null) { + return false; + } + } else if (!fContent.equals(other.fContent)) { + return false; + } + if (fReference == null) { + if (other.fReference != null) { + return false; + } + } else if (!fReference.equals(other.fReference)) { + return false; + } + return true; + } + + @Override + @SuppressWarnings("nls") + public String toString() { + return getClass().getSimpleName() + " [fTimestamp=" + getTimestamp() + + ", fTrace=" + getTrace() + ", fRank=" + getRank() + + ", fSource=" + getSource() + ", fType=" + getType() + + ", fContent=" + getContent() + ", fReference=" + getReference() + + "]"; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfEventField.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfEventField.java new file mode 100644 index 0000000000..6c197db633 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfEventField.java @@ -0,0 +1,261 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Updated as per TMF Event Model 1.0 + * Alexandre Montplaisir - Removed Cloneable, made immutable + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event; + +import java.util.Collection; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; + +import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableMap; + +/** + * A basic implementation of ITmfEventField. + *

+ * Non-value fields are structural (i.e. used to represent the event structure + * including optional fields) while the valued fields are actual event fields. + * + * @version 1.0 + * @author Francois Chouinard + * + * @see ITmfEvent + * @see ITmfEventType + */ +public class TmfEventField implements ITmfEventField { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final @NonNull String fName; + private final @Nullable Object fValue; + private final @NonNull ImmutableMap fFields; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Full constructor + * + * @param name + * the event field id + * @param value + * the event field value + * @param fields + * the list of subfields + * @throws IllegalArgumentException + * If 'name' is null, or if 'fields' has duplicate field names. + */ + @SuppressWarnings("null") /* ImmutableMap methods do not return @NonNull */ + public TmfEventField(String name, @Nullable Object value, @Nullable ITmfEventField[] fields) { + if (name == null) { + throw new IllegalArgumentException(); + } + fName = name; + fValue = value; + + if (fields == null) { + fFields = ImmutableMap.of(); + } else { + /* Java 8 streams will make this even more simple! */ + ImmutableMap.Builder mapBuilder = new ImmutableMap.Builder<>(); + for (ITmfEventField field : fields) { + final String curName = field.getName(); + mapBuilder.put(curName, field); + } + fFields = mapBuilder.build(); + } + } + + /** + * Copy constructor + * + * @param field the other event field + */ + public TmfEventField(final TmfEventField field) { + if (field == null) { + throw new IllegalArgumentException(); + } + fName = field.fName; + fValue = field.fValue; + fFields = field.fFields; + } + + // ------------------------------------------------------------------------ + // ITmfEventField + // ------------------------------------------------------------------------ + + @Override + public String getName() { + return fName; + } + + @Override + public Object getValue() { + return fValue; + } + + /** + * @since 3.0 + */ + @Override + public Collection getFieldNames() { + return fFields.keySet(); + } + + /** + * @since 3.0 + */ + @Override + public Collection getFields() { + return fFields.values(); + } + + @Override + public ITmfEventField getField(final String name) { + return fFields.get(name); + } + + /** + * @since 3.0 + */ + @Override + public ITmfEventField getSubField(final String... names) { + ITmfEventField field = this; + for (String name : names) { + field = field.getField(name); + if (field == null) { + return null; + } + } + return field; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Create a root field from a list of labels. + * + * @param labels the list of labels + * @return the (flat) root list + */ + public final static ITmfEventField makeRoot(final String[] labels) { + final ITmfEventField[] fields = new ITmfEventField[labels.length]; + for (int i = 0; i < labels.length; i++) { + fields[i] = new TmfEventField(labels[i], null, null); + } + // Return a new root field; + return new TmfEventField(ITmfEventField.ROOT_FIELD_ID, null, fields); + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + Object value = fValue; + final int prime = 31; + int result = 1; + result = prime * result + fName.hashCode(); + result = prime * result + ((value == null) ? 0 : value.hashCode()); + result = prime * result + fFields.hashCode(); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof TmfEventField)) { + return false; + } + + final TmfEventField other = (TmfEventField) obj; + + /* Check that 'fName' is the same */ + if (!fName.equals(other.fName)) { + return false; + } + + /* Check that 'fValue' is the same */ + Object value = this.fValue; + if (value == null) { + if (other.fValue != null) { + return false; + } + } else if (!value.equals(other.fValue)) { + return false; + } + + /* Check that 'fFields' are the same */ + if (!fFields.equals(other.fFields)) { + return false; + } + + return true; + } + + @Override + public String toString() { + StringBuilder ret = new StringBuilder(); + if (fName.equals(ITmfEventField.ROOT_FIELD_ID)) { + /* + * If this field is a top-level "field container", we will print its + * sub-fields directly. + */ + appendSubFields(ret); + + } else { + /* The field has its own values */ + ret.append(fName); + ret.append('='); + ret.append(fValue); + + if (!fFields.isEmpty()) { + /* + * In addition to its own name/value, this field also has + * sub-fields. + */ + ret.append(" ["); //$NON-NLS-1$ + appendSubFields(ret); + ret.append(']'); + } + } + return ret.toString(); + } + + private void appendSubFields(StringBuilder sb) { + Joiner joiner = Joiner.on(", ").skipNulls(); //$NON-NLS-1$ + sb.append(joiner.join(getFields())); + } + + /** + * @since 2.0 + */ + @Override + public String getFormattedValue() { + return getValue().toString(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfEventType.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfEventType.java new file mode 100644 index 0000000000..342503cf48 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfEventType.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Updated as per TMF Event Model 1.0 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event; + +import java.util.Collection; +import java.util.Collections; + +/** + * A basic implementation of ITmfEventType. + * + * @version 1.0 + * @author Francois Chouinard + * + * @see ITmfEvent + * @see ITmfEventField + */ +public class TmfEventType implements ITmfEventType { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final String fContext; + private final String fTypeId; + private final ITmfEventField fRootField; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + public TmfEventType() { + this(DEFAULT_CONTEXT_ID, DEFAULT_TYPE_ID, null); + } + + /** + * Full constructor + * + * @param context the type context + * @param typeId the type name + * @param root the root field + */ + public TmfEventType(final String context, final String typeId, final ITmfEventField root) { + if (context == null || typeId == null) { + throw new IllegalArgumentException(); + } + fContext = context; + fTypeId = typeId; + fRootField = root; + + // Register to the event type manager + TmfEventTypeManager.getInstance().add(context, this); + } + + /** + * Copy constructor + * + * @param type the other type + */ + public TmfEventType(final ITmfEventType type) { + if (type == null) { + throw new IllegalArgumentException(); + } + fContext = type.getContext(); + fTypeId = type.getName(); + fRootField = type.getRootField(); + } + + // ------------------------------------------------------------------------ + // ITmfEventType + // ------------------------------------------------------------------------ + + @Override + public String getContext() { + return fContext; + } + + @Override + public String getName() { + return fTypeId; + } + + @Override + public ITmfEventField getRootField() { + return fRootField; + } + + /** + * @since 3.0 + */ + @Override + public Collection getFieldNames() { + return (fRootField != null) ? fRootField.getFieldNames() : Collections.EMPTY_SET; + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + fContext.hashCode(); + result = prime * result + fTypeId.hashCode(); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof TmfEventType)) { + return false; + } + final TmfEventType other = (TmfEventType) obj; + if (!fContext.equals(other.fContext)) { + return false; + } + if (!fTypeId.equals(other.fTypeId)) { + return false; + } + return true; + } + + @Override + @SuppressWarnings("nls") + public String toString() { + return "TmfEventType [fContext=" + fContext + ", fTypeId=" + fTypeId + "]"; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfEventTypeManager.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfEventTypeManager.java new file mode 100644 index 0000000000..596dbfb6d3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfEventTypeManager.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import com.google.common.collect.ImmutableSet; + +/** + * A central repository for the available event types. Types are managed by + * context space. + * + * @version 1.0 + * @author Francois Chouinard + * + * @see ITmfEventType + */ +public final class TmfEventTypeManager { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // The event type manager singleton + private static TmfEventTypeManager fEventTypeManager = null; + + // The available types, per context + private final Map> fEventTypes; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * The singleton constructor + */ + private TmfEventTypeManager() { + fEventTypes = new HashMap<>(); + } + + /** + * @return the TmfEventTypeManager singleton + */ + public static synchronized TmfEventTypeManager getInstance() { + if (fEventTypeManager == null) { + fEventTypeManager = new TmfEventTypeManager(); + } + return fEventTypeManager; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Add a context:type pair to the available types + * + * @param context the target context + * @param type the type to add + */ + public synchronized void add(final String context, final ITmfEventType type) { + HashMap types = fEventTypes.get(context); + if (types == null) { + types = new HashMap<>(); + } + types.put(type.getName(), type); + fEventTypes.put(context, types); + } + + /** + * Return the list of currently defined contexts + * + * @return the list of contexts + */ + public synchronized String[] getContexts() { + return fEventTypes.keySet().toArray(new String[fEventTypes.size()]); + } + + /** + * Return the list of types defined for a given context + * + * @param context the context to look into + * @return the list of types defined for that context + * @since 3.0 + */ + public synchronized Set getTypes(final String context) { + final HashMap types = fEventTypes.get(context); + if (types != null) { + return ImmutableSet.copyOf(types.values()); + } + return ImmutableSet.of(); + } + + /** + * Return an event type + * + * @param context the context to look into + * @param typeId the type ID + * @return the corresponding type + */ + public synchronized ITmfEventType getType(final String context, final String typeId) { + final HashMap types = fEventTypes.get(context); + if (types != null) { + return types.get(typeId); + } + return null; + } + + /** + * Remove the types associated to a context + * + * @param context the context to remove + */ + public synchronized void clear(final String context) { + fEventTypes.remove(context); + } + + /** + * Remove all contexts and types + */ + public synchronized void clear() { + fEventTypes.clear(); + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + @SuppressWarnings("nls") + public String toString() { + return "TmfEventTypeManager [fEventTypes=" + fEventTypes + "]"; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfLostEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfLostEvent.java new file mode 100644 index 0000000000..e9aea22517 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/TmfLostEvent.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Alexandre Montplaisir - Made immutable + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * A basic implementation of ITmfLostEvent. + * + * @author Francois Chouinard + * @version 1.0 + * @since 1.2 +*/ +public class TmfLostEvent extends TmfEvent implements ITmfLostEvent { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final TmfTimeRange fTimeRange; + private final long fNbLostEvents; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Full constructor + * + * @param trace + * the parent trace + * @param rank + * the event rank (in the trace) + * @param timestamp + * the event timestamp + * @param source + * the event source + * @param type + * the event type + * @param reference + * the event reference + * @param timeRange + * the 'problematic' time range + * @param nbLostEvents + * the number of lost events in the time range + * @since 2.0 + */ + public TmfLostEvent(final ITmfTrace trace, + final long rank, + final ITmfTimestamp timestamp, + final String source, + final ITmfEventType type, + final String reference, + final TmfTimeRange timeRange, + final long nbLostEvents) { + super(trace, rank, timestamp, source, type, null, reference); + fTimeRange = timeRange; + fNbLostEvents = nbLostEvents; + } + + // ------------------------------------------------------------------------ + // ITmfLostEvent + // ------------------------------------------------------------------------ + + /** + * @since 2.0 + */ + @Override + public TmfTimeRange getTimeRange() { + return fTimeRange; + } + + @Override + public long getNbLostEvents() { + return fNbLostEvents; + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + (int) (fNbLostEvents ^ (fNbLostEvents >>> 32)); + result = prime * result + ((fTimeRange == null) ? 0 : fTimeRange.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof TmfLostEvent)) { + return false; + } + TmfLostEvent other = (TmfLostEvent) obj; + if (fNbLostEvents != other.fNbLostEvents) { + return false; + } + if (fTimeRange == null) { + if (other.fTimeRange != null) { + return false; + } + } else if (!fTimeRange.equals(other.fTimeRange)) { + return false; + } + return true; + } + + @Override + @SuppressWarnings("nls") + public String toString() { + return getClass().getSimpleName() + " [Event=" + super.toString() + + ", fTimeRange=" + fTimeRange + ", fNbLostEvents=" + fNbLostEvents + "]"; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/collapse/ITmfCollapsibleEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/collapse/ITmfCollapsibleEvent.java new file mode 100644 index 0000000000..5609f3703e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/collapse/ITmfCollapsibleEvent.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.core.event.collapse; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * Interface for deciding whether an event can be collapsed with another event. + * + * @author Bernd Hufmann + * @since 3.2 + */ +public interface ITmfCollapsibleEvent { + + /** + * Verifies if an event is similar to a given event and can be collapsed + * into one event. For example, an event can be seen as similar if all data + * of the events but the timestamp is equal. + * + * @param otherEvent + * an event to compare + * @return true if a given event is similar to another event + * else false + */ + boolean isCollapsibleWith(ITmfEvent otherEvent); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/lookup/ITmfCallsite.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/lookup/ITmfCallsite.java new file mode 100644 index 0000000000..dd6843e328 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/lookup/ITmfCallsite.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event.lookup; + + +/** + * The generic call site structure in TMF. A call site has: + *

    + *
  • a file name + *
  • a function name (optional) + *
  • a line number + *
+ * + * @author Bernd Hufmann + * @since 2.0 + * + * @see TmfCallsite + */ +public interface ITmfCallsite { + /** + * Returns the file name of the call site. + * @return the file name + */ + public String getFileName(); + + /** + * Returns the function name of the call site. + * @return the function name or null + */ + public String getFunctionName(); + + /** + * Returns the line number of the call site. + * @return the line number + */ + public long getLineNumber(); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/lookup/ITmfModelLookup.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/lookup/ITmfModelLookup.java new file mode 100644 index 0000000000..434a041300 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/lookup/ITmfModelLookup.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.core.event.lookup; + + +/** + * Interface for events to implement to provide information for model element lookup. + * + * @author Bernd Hufmann + * @since 2.0 + */ +public interface ITmfModelLookup { + /** + * Returns a model URI string. + * + * @return a model URI string. + */ + public String getModelUri(); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/lookup/ITmfSourceLookup.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/lookup/ITmfSourceLookup.java new file mode 100644 index 0000000000..975dd66d3d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/lookup/ITmfSourceLookup.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.core.event.lookup; + + +/** + * Interface for events to implement to provide information for source lookup. + * + * @author Bernd Hufmann + * @since 2.0 + */ +public interface ITmfSourceLookup { + /** + * Returns a call site instance. + * + * @return a call site instance. + */ + public ITmfCallsite getCallsite(); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/lookup/TmfCallsite.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/lookup/TmfCallsite.java new file mode 100644 index 0000000000..574fbbbbc2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/lookup/TmfCallsite.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event.lookup; + + +/** + * TMF call site information for source code lookup. + * + * @since 2.0 + * @author Bernd Hufmann + */ +public class TmfCallsite implements ITmfCallsite { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** The file name string. */ + final private String fFileName; + + /** The function name. */ + final private String fFunctionName; + + /** The line number. */ + final private long fLineNumber; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor. + * + * @param fileName + * - a file name + * @param functionName + * - a function name + * @param lineNumber + * - a line number + */ + public TmfCallsite(String fileName, String functionName, long lineNumber) { + if (fileName == null) { + throw new IllegalArgumentException(); + } + fFileName = fileName; + fFunctionName = functionName; + fLineNumber = lineNumber; + } + + /** + * Copy Constructor. + * + * @param other + * - An other call site implementation + */ + public TmfCallsite(ITmfCallsite other) { + if ((other == null) || (other.getFileName() == null)) { + throw new IllegalArgumentException(); + } + fFileName = other.getFileName(); + fFunctionName = other.getFunctionName(); + fLineNumber = other.getLineNumber(); + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + @Override + public String getFileName() { + return fFileName; + } + + @Override + public String getFunctionName() { + return fFunctionName; + } + + @Override + public long getLineNumber() { + return fLineNumber; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + fFileName.hashCode(); // fFileName cannot be null + result = prime * result + ((fFunctionName == null) ? 0 : fFunctionName.hashCode()); + result = prime * result + (int) (fLineNumber ^ (fLineNumber >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TmfCallsite other = (TmfCallsite) obj; + + // fFileName cannot be null! + if (!fFileName.equals(other.fFileName)) { + return false; + } + + if (fFunctionName == null) { + if (other.fFunctionName != null) { + return false; + } + } else if (!fFunctionName.equals(other.fFunctionName)) { + return false; + } + if (fLineNumber != other.fLineNumber) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(fFileName).append(':'); + builder.append(Long.toString(fLineNumber)); + if (fFunctionName != null) { + builder.append(' '); + builder.append(fFunctionName).append("()"); //$NON-NLS-1$ + } + return builder.toString(); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/IMatchProcessingUnit.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/IMatchProcessingUnit.java new file mode 100644 index 0000000000..34ae78b595 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/IMatchProcessingUnit.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event.matching; + +import java.util.Collection; + +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * This class represent an action to be done when event matches are found. This + * interface needs to be implemented by all classes that want to be warned when + * new event matches are found. They need to register to an instance of + * TmfEventMatches class in order to be informed of matches. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public interface IMatchProcessingUnit { + + /** + * Once the traces are known, hook function to initialize some things + * + * @param fTraces the set of traces that will be synchronized + */ + void init(Collection fTraces); + + /** + * Function called when a match is found + * + * @param match + * The event match + */ + void addMatch(TmfEventDependency match); + + /** + * Function called after all matching has been done, to do any post-match + * treatment + */ + void matchingEnded(); + + /** + * Counts the matches + * + * @return the number of matches + */ + int countMatches(); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/ITmfEventMatching.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/ITmfEventMatching.java new file mode 100644 index 0000000000..fa91fe038e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/ITmfEventMatching.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event.matching; + + +/** + * Interface for matching trace events + * + * @author Geneviève Bastien + * @since 3.0 + */ +public interface ITmfEventMatching { + + /** + * Method that start the process of matching events + * + * @return Whether the match was completed correctly or not + */ + boolean matchEvents(); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/ITmfMatchEventDefinition.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/ITmfMatchEventDefinition.java new file mode 100644 index 0000000000..0115f8cb6b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/ITmfMatchEventDefinition.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event.matching; + +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.matching.TmfEventMatching.MatchingType; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * This interface describe a concrete method to match events. Typically it + * manages for a given matching type what events/fields are used to match events + * + * @author Geneviève Bastien + * @since 3.0 + */ +public interface ITmfMatchEventDefinition { + + /** + * Returns a list of values for an event that uniquely identifies this event + * + * @param event + * The event for which to compute the key + * @return the unique key for this event + */ + List getUniqueField(ITmfEvent event); + + /** + * Verifies whether a trace has all required events to match using this + * class + * + * @param trace + * The trace + * @return Whether the trace has all required information + */ + boolean canMatchTrace(ITmfTrace trace); + + /** + * Return all matching types this definition covers + * + * @return an array of matching types + */ + MatchingType[] getApplicableMatchingTypes(); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/ITmfNetworkMatchDefinition.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/ITmfNetworkMatchDefinition.java new file mode 100644 index 0000000000..58c78b312d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/ITmfNetworkMatchDefinition.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event.matching; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.matching.TmfNetworkEventMatching.Direction; + +/** + * Interface for all network match definitions, ie traces with send and receive + * events + * + * @author Geneviève Bastien + * @since 3.0 + */ +public interface ITmfNetworkMatchDefinition extends ITmfMatchEventDefinition { + + /** + * Returns the direction of this event, whether 'send', 'receive' or null if + * event is neither + * + * @param event + * The event to check + * @return The direction of this event, null if uninteresting event + */ + Direction getDirection(ITmfEvent event); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/TmfEventDependency.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/TmfEventDependency.java new file mode 100644 index 0000000000..3ab0c11513 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/TmfEventDependency.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event.matching; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * Represents a dependency (match) between two events, where source event leads + * to destination event + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfEventDependency { + + private final ITmfEvent fSourceEvent; + private final ITmfEvent fDestEvent; + + /** + * Constructor + * + * @param source + * The source event of this dependency + * @param destination + * The destination event of this dependency + */ + public TmfEventDependency(final ITmfEvent source, final ITmfEvent destination) { + fSourceEvent = source; + fDestEvent = destination; + } + + /** + * Getter for fSourceEvent + * + * @return The source event + */ + public ITmfEvent getSourceEvent() { + return fSourceEvent; + } + + /** + * Getter for fDestEvent + * + * @return the Destination event + */ + public ITmfEvent getDestinationEvent() { + return fDestEvent; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/TmfEventMatches.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/TmfEventMatches.java new file mode 100644 index 0000000000..c512ee26bb --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/TmfEventMatches.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event.matching; + +import java.util.Collection; + +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Class that does something with a match. + * + * This default implementation of the class just counts the matches + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfEventMatches implements IMatchProcessingUnit { + + private int fMatchCount; + + /** + * Constructor + */ + public TmfEventMatches() { + fMatchCount = 0; + } + + /** + * IMatchProcessingUnit overrides + */ + + @Override + public void init(Collection fTraces) { + fMatchCount = 0; + } + + @Override + public void addMatch(TmfEventDependency match) { + fMatchCount++; + } + + @Override + public void matchingEnded() { + + } + + @Override + public int countMatches() { + return fMatchCount; + } + + /** + * Returns the match at the specified index + * + * @param index + * The index of the match to get + * @return The match at index or null or not present + * @deprecated Matches are not kept anymore, they use up memory for no real reason + */ + @Deprecated + public TmfEventDependency getMatch(int index) { + return null; + } + + @Override + public String toString() { + return getClass().getSimpleName() + " [ Number of matches found: " + fMatchCount + " ]"; //$NON-NLS-1$ //$NON-NLS-2$ + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/TmfEventMatching.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/TmfEventMatching.java new file mode 100644 index 0000000000..951193db60 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/TmfEventMatching.java @@ -0,0 +1,271 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event.matching; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Abstract class to extend to match certain type of events in a trace + * + * @author Geneviève Bastien + * @since 3.0 + */ +public abstract class TmfEventMatching implements ITmfEventMatching { + + /** + * The matching type + * + * FIXME Not the best place to put this. Have an array of match types as a + * parameter of each trace? + */ + public enum MatchingType { + /** + * NETWORK, match network events + */ + NETWORK + } + + /** + * The array of traces to match + */ + private final Collection fTraces; + + /** + * The class to call once a match is found + */ + private final IMatchProcessingUnit fMatches; + + private static final Map> fMatchDefinitions = new HashMap<>(); + + private final Map fMatchMap = new HashMap<>(); + + /** + * Constructor with multiple traces and a match processing object + * + * @param traces + * The set of traces for which to match events + * @param tmfEventMatches + * The match processing class + */ + public TmfEventMatching(Collection traces, IMatchProcessingUnit tmfEventMatches) { + if (tmfEventMatches == null) { + throw new IllegalArgumentException(); + } + fTraces = traces; + fMatches = tmfEventMatches; + } + + /** + * Returns the traces to process + * + * @return The traces + */ + protected Collection getTraces() { + return fTraces; + } + + /** + * Returns the match processing unit + * + * @return The match processing unit + */ + protected IMatchProcessingUnit getProcessingUnit() { + return fMatches; + } + + /** + * Returns the match event definition corresponding to the trace + * + * @param trace + * The trace + * @return The match event definition object + */ + protected ITmfMatchEventDefinition getEventDefinition(ITmfTrace trace) { + return fMatchMap.get(trace); + } + + /** + * Method that initializes any data structure for the event matching. It + * also assigns to each trace an event matching definition instance that + * applies to the trace + */ + protected void initMatching() { + fMatches.init(fTraces); + List deflist = fMatchDefinitions.get(getMatchingType()); + if (deflist == null) { + return; + } + for (ITmfTrace trace : fTraces) { + for (ITmfMatchEventDefinition def : deflist) { + if (def.canMatchTrace(trace)) { + fMatchMap.put(trace, def); + break; + } + } + } + } + + /** + * Calls any post matching methods of the processing class + */ + protected void finalizeMatching() { + fMatches.matchingEnded(); + } + + /** + * Prints stats from the matching + * + * @return string of statistics + */ + @SuppressWarnings("nls") + @Override + public String toString() { + return getClass().getSimpleName() + " [ " + fMatches + " ]"; + } + + /** + * Matches one event + * + * @param event + * The event to match + * @param trace + * The trace to which this event belongs + */ + protected abstract void matchEvent(ITmfEvent event, ITmfTrace trace); + + /** + * Returns the matching type this class implements + * + * @return A matching type + */ + protected abstract MatchingType getMatchingType(); + + /** + * Method that start the process of matching events + * + * @return Whether the match was completed correctly or not + */ + @Override + public boolean matchEvents() { + + /* Are there traces to match? If no, return false */ + if (!(fTraces.size() > 0)) { + return false; + } + + // TODO Start a new thread here? + initMatching(); + + /** + * For each trace, get the events and for each event, call the + * MatchEvent method + * + * FIXME This would use a lot of memory if the traces are big, because + * all involved events from first trace will have to be kept before a + * first match is possible with second trace. + * + *
+         * Other possible matching strategy:
+         * Incremental:
+         * Sliding window:
+         * Other strategy: start with the shortest trace, take a few events
+         * at the beginning and at the end
+         * Experiment strategy: have the experiment do the request, then events will
+         * come from both traces chronologically, but then instead of ITmfTrace[], it
+         * would be preferable to have experiment
+         * 
+ */ + for (ITmfTrace trace : fTraces) { + EventMatchingBuildRequest request = new EventMatchingBuildRequest(this, trace); + + /* + * Send the request to the trace here, since there is probably no + * experiment. + */ + trace.sendRequest(request); + try { + request.waitForCompletion(); + } catch (InterruptedException e) { + Activator.logInfo(e.getMessage()); + } + } + + finalizeMatching(); + + return true; + } + + /** + * Registers an event match definition to be used for a certain match type + * + * @param match + * The event matching definition + */ + public static void registerMatchObject(ITmfMatchEventDefinition match) { + for (MatchingType type : match.getApplicableMatchingTypes()) { + if (!fMatchDefinitions.containsKey(type)) { + fMatchDefinitions.put(type, new ArrayList()); + } + fMatchDefinitions.get(type).add(match); + } + } + +} + +class EventMatchingBuildRequest extends TmfEventRequest { + + private final TmfEventMatching matching; + private final ITmfTrace trace; + + EventMatchingBuildRequest(TmfEventMatching matching, ITmfTrace trace) { + super(ITmfEvent.class, + TmfTimeRange.ETERNITY, + 0, + ITmfEventRequest.ALL_DATA, + ITmfEventRequest.ExecutionType.FOREGROUND); + this.matching = matching; + this.trace = trace; + } + + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + matching.matchEvent(event, trace); + } + + @Override + public void handleSuccess() { + super.handleSuccess(); + } + + @Override + public void handleCancel() { + super.handleCancel(); + } + + @Override + public void handleFailure() { + super.handleFailure(); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/TmfNetworkEventMatching.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/TmfNetworkEventMatching.java new file mode 100644 index 0000000000..7321cfcb9d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/matching/TmfNetworkEventMatching.java @@ -0,0 +1,212 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event.matching; + +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * This class matches events typically network-style, ie. where some events are + * 'send' events and the other 'receive' events or out/in events + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfNetworkEventMatching extends TmfEventMatching { + + /** + * Hashtables for unmatches incoming events + */ + private final Map, ITmfEvent>> fUnmatchedIn = new LinkedHashMap<>(); + + /** + * Hashtables for unmatches outgoing events + */ + private final Map, ITmfEvent>> fUnmatchedOut = new LinkedHashMap<>(); + + /** + * Enum for in and out types + */ + public enum Direction { + /** + * The event is a 'receive' type of event + */ + IN, + /** + * The event is a 'send' type of event + */ + OUT, + } + + /** + * Constructor with multiple traces and match processing object + * + * @param traces + * The set of traces for which to match events + */ + public TmfNetworkEventMatching(Collection traces) { + this(traces, new TmfEventMatches()); + } + + /** + * Constructor with multiple traces and match processing object + * + * @param traces + * The set of traces for which to match events + * @param tmfEventMatches + * The match processing class + */ + public TmfNetworkEventMatching(Collection traces, IMatchProcessingUnit tmfEventMatches) { + super(traces, tmfEventMatches); + } + + /** + * Method that initializes any data structure for the event matching + */ + @Override + public void initMatching() { + // Initialize the matching infrastructure (unmatched event lists) + fUnmatchedIn.clear(); + fUnmatchedOut.clear(); + for (ITmfTrace trace : getTraces()) { + fUnmatchedIn.put(trace, new HashMap, ITmfEvent>()); + fUnmatchedOut.put(trace, new HashMap, ITmfEvent>()); + } + super.initMatching(); + } + + /** + * Function that counts the events in a hashtable. + * + * @param tbl + * The table to count events for + * @return The number of events + */ + protected int countEvents(Map, ITmfEvent> tbl) { + return tbl.size(); + } + + @Override + protected MatchingType getMatchingType() { + return MatchingType.NETWORK; + } + + @Override + public void matchEvent(ITmfEvent event, ITmfTrace trace) { + if (!(getEventDefinition(event.getTrace()) instanceof ITmfNetworkMatchDefinition)) { + return; + } + ITmfNetworkMatchDefinition def = (ITmfNetworkMatchDefinition) getEventDefinition(event.getTrace()); + + Direction evType = def.getDirection(event); + if (evType == null) { + return; + } + + /* Get the event's unique fields */ + List eventKey = def.getUniqueField(event); + Map, ITmfEvent>> unmatchedTbl, companionTbl; + + /* Point to the appropriate table */ + switch (evType) { + case IN: + unmatchedTbl = fUnmatchedIn; + companionTbl = fUnmatchedOut; + break; + case OUT: + unmatchedTbl = fUnmatchedOut; + companionTbl = fUnmatchedIn; + break; + default: + return; + } + + boolean found = false; + TmfEventDependency dep = null; + /* Search for the event in the companion table */ + for (Map, ITmfEvent> map : companionTbl.values()) { + if (map.containsKey(eventKey)) { + found = true; + ITmfEvent companionEvent = map.get(eventKey); + + /* Remove the element from the companion table */ + map.remove(eventKey); + + /* Create the dependency object */ + switch (evType) { + case IN: + dep = new TmfEventDependency(companionEvent, event); + break; + case OUT: + dep = new TmfEventDependency(event, companionEvent); + break; + default: + break; + + } + } + } + + /* + * If no companion was found, add the event to the appropriate unMatched + * lists + */ + if (found) { + getProcessingUnit().addMatch(dep); + } else { + /* + * If an event is already associated with this key, do not add it + * again, we keep the first event chronologically, so if its match + * is eventually found, it is associated with the first send or + * receive event. At best, it is a good guess, at worst, the match + * will be too far off to be accurate. Too bad! + * + * TODO: maybe instead of just one event, we could have a list of + * events as value for the unmatched table. Not necessary right now + * though + */ + if (!unmatchedTbl.get(trace).containsKey(eventKey)) { + unmatchedTbl.get(trace).put(eventKey, event); + } + } + + } + + /** + * Prints stats from the matching + * + * @return string of statistics + */ + @SuppressWarnings("nls") + @Override + public String toString() { + final String cr = System.getProperty("line.separator"); + StringBuilder b = new StringBuilder(); + b.append(getProcessingUnit()); + int i = 0; + for (ITmfTrace trace : getTraces()) { + b.append("Trace " + i++ + ":" + cr + + " " + countEvents(fUnmatchedIn.get(trace)) + " unmatched incoming events" + cr + + " " + countEvents(fUnmatchedOut.get(trace)) + " unmatched outgoing events" + cr); + } + + return b.toString(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/exceptions/TmfAnalysisException.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/exceptions/TmfAnalysisException.java new file mode 100644 index 0000000000..de9f7e6a9e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/exceptions/TmfAnalysisException.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.exceptions; + +/** + * Generic exception for an error or issue occurs in analysis setup and + * execution. + * + * For instance, to perform an analysis, a trace must be of the right type and + * have some characteristics. If trying to do an analysis on a trace that does + * not match, this exception is thrown. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfAnalysisException extends Exception { + + private static final long serialVersionUID = -4567750551324478401L; + + /** + * Default constructor + */ + public TmfAnalysisException() { + super(); + } + + /** + * Constructor with a message + * + * @param message + * Message to attach to this exception + */ + public TmfAnalysisException(String message) { + super(message); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/exceptions/TmfTraceException.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/exceptions/TmfTraceException.java new file mode 100644 index 0000000000..d02b5f8b13 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/exceptions/TmfTraceException.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.exceptions; + +/** + * TMF trace related exception + * + * @version 1.0 + * @author Francois Chouinard + */ +public class TmfTraceException extends Exception { + + /** + * The exception version ID + */ + private static final long serialVersionUID = -6829650938285722133L; + + /** + * Constructor + * + * @param errMsg the error message + */ + public TmfTraceException(String errMsg) { + super(errMsg); + } + + /** + * Constructor + * + * @param errMsg the error message + * @param cause the error cause (null is permitted which means no cause is available) + */ + public TmfTraceException(String errMsg, Throwable cause) { + super(errMsg, cause); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/ITmfFilter.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/ITmfFilter.java new file mode 100644 index 0000000000..a70af6c5ac --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/ITmfFilter.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.filter; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * The TMF filter interface. + * + * @version 1.0 + * @author Patrick Tasse + */ +public interface ITmfFilter { + + /** + * Verify the filter conditions on an event + * + * @param event The event to verify. + * @return True if the event matches the filter conditions. + */ + boolean matches(ITmfEvent event); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/ITmfFilterTreeNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/ITmfFilterTreeNode.java new file mode 100644 index 0000000000..5ee8781658 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/ITmfFilterTreeNode.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Godin (copelnug@gmail.com) - Initial API + * Yuriy Vashchuk (yvashchuk@gmail.com) - Initial implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.filter.model; + +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.filter.ITmfFilter; + + +/** + *

This is Node Interface in the Filter Tree

+ */ +public interface ITmfFilterTreeNode extends ITmfFilter { + + /** + *

Get the parent node of current node

+ * + * @return The parent node (null when the node has no parent). + */ + public ITmfFilterTreeNode getParent(); + + /** + *

Get the current node name

+ * + * @return The name of the current node. + */ + public String getNodeName(); + + /** + *

Tell if the node has children

+ * + * @return True if the node has children. + */ + public boolean hasChildren(); + + /** + *

Return the number of children

+ * + * @return The number of children. + */ + public int getChildrenCount(); + + /** + *

Get the array of children

+ * + * @return The array (possibly empty) of children nodes. + */ + public ITmfFilterTreeNode[] getChildren(); + + /** + *

Get the node by index

+ * + * @param index The index of node to return. + * @return The desired node (null if the node is not exists). + */ + public ITmfFilterTreeNode getChild(int index); + + /** + *

Remove the node from its parent

+ * + *

Shifts all nodes after the removed one to prevent having an empty spot. + * See {@link #replaceChild(int, ITmfFilterTreeNode)} to replace a node.

+ * + * @return The removed node. + */ + public ITmfFilterTreeNode remove(); + + /** + *

Remove the child from the current node

+ * + *

Shifts all nodes after the removed one to prevent having an empty spot. + * See {@link #replaceChild(int, ITmfFilterTreeNode)} to replace a node.

+ * + * @param node the parent node + * + * @return The removed node. + */ + public ITmfFilterTreeNode removeChild(ITmfFilterTreeNode node); + + /** + *

Append a node to the current children

+ * + * @param node Node to append. + * @return Index of added node (-1 if the node cannot be added). + */ + public int addChild(ITmfFilterTreeNode node); + + /** + *

Replace a child node

+ * + * @param index Index of the node to replace. + * @param node Node who will replace. + * @return Node replaced. + */ + public ITmfFilterTreeNode replaceChild(int index, ITmfFilterTreeNode node); + + /** + *

Sets the parent of current node

+ * + * @param parent The parent of current node. + */ + public void setParent(ITmfFilterTreeNode parent); + + /** + *

Gets the list of valid children node names that could be added to the node

+ * + * @return The list of valid children node names. + */ + public List getValidChildren(); + + /** + * @return a clone of the node + */ + public ITmfFilterTreeNode clone(); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterAndNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterAndNode.java new file mode 100644 index 0000000000..f9e475d861 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterAndNode.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.filter.model; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + + +/** + * Filter node for the 'and' operation + * + * @version 1.0 + * @author Patrick Tasse + */ +@SuppressWarnings("javadoc") +public class TmfFilterAndNode extends TmfFilterTreeNode { + + public static final String NODE_NAME = "AND"; //$NON-NLS-1$ + public static final String NOT_ATTR = "not"; //$NON-NLS-1$ + + private boolean fNot = false; + + /** + * @param parent the parent node + */ + public TmfFilterAndNode(ITmfFilterTreeNode parent) { + super(parent); + } + + /** + * @return the NOT state + */ + public boolean isNot() { + return fNot; + } + + /** + * @param not the NOT state + */ + public void setNot(boolean not) { + this.fNot = not; + } + + @Override + public String getNodeName() { + return NODE_NAME; + } + + @Override + public boolean matches(ITmfEvent event) { + for (ITmfFilterTreeNode node : getChildren()) { + if (! node.matches(event)) { + return false ^ fNot; + } + } + return true ^ fNot; + } + + @Override + public String toString() { + StringBuffer buf = new StringBuffer(); + if (fNot) { + buf.append("not "); //$NON-NLS-1$ + } + if (getParent() != null && !(getParent() instanceof TmfFilterRootNode) && !(getParent() instanceof TmfFilterNode)) { + buf.append("( "); //$NON-NLS-1$ + } + for (int i = 0; i < getChildrenCount(); i++) { + ITmfFilterTreeNode node = getChildren()[i]; + buf.append(node.toString()); + if (i < getChildrenCount() - 1) { + buf.append(" and "); //$NON-NLS-1$ + } + } + if (getParent() != null && !(getParent() instanceof TmfFilterRootNode) && !(getParent() instanceof TmfFilterNode)) { + buf.append(" )"); //$NON-NLS-1$ + } + return buf.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + (fNot ? 1231 : 1237); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TmfFilterAndNode other = (TmfFilterAndNode) obj; + if (fNot != other.fNot) { + return false; + } + return true; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterCompareNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterCompareNode.java new file mode 100644 index 0000000000..4a45cd3a46 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterCompareNode.java @@ -0,0 +1,270 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.filter.model; + +import java.text.NumberFormat; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; + + +/** + * Filter node for the comparison operation + * + * @version 1.0 + * @author Patrick Tasse + */ +@SuppressWarnings("javadoc") +public class TmfFilterCompareNode extends TmfFilterTreeNode { + + public static final String NODE_NAME = "COMPARE"; //$NON-NLS-1$ + public static final String NOT_ATTR = "not"; //$NON-NLS-1$ + public static final String FIELD_ATTR = "field"; //$NON-NLS-1$ + public static final String RESULT_ATTR = "result"; //$NON-NLS-1$ + public static final String TYPE_ATTR = "type"; //$NON-NLS-1$ + public static final String VALUE_ATTR = "value"; //$NON-NLS-1$ + + /** + * Supported comparison types + */ + public static enum Type { + NUM, + ALPHA, + TIMESTAMP + } + + private boolean fNot = false; + private String fField; + private int fResult; + private Type fType = Type.NUM; + private String fValue; + private transient Number fValueNumber; + private transient TmfTimestamp fValueTimestamp; + + /** + * @param parent the parent node + */ + public TmfFilterCompareNode(ITmfFilterTreeNode parent) { + super(parent); + } + + /** + * @return the NOT state + */ + public boolean isNot() { + return fNot; + } + + /** + * @param not the NOT state + */ + public void setNot(boolean not) { + this.fNot = not; + } + + /** + * @return the field name + */ + public String getField() { + return fField; + } + + /** + * @param field the field name + */ + public void setField(String field) { + this.fField = field; + } + + /** + * @return the compare result + */ + public int getResult() { + return fResult; + } + + /** + * @param result the compare result + */ + public void setResult(int result) { + this.fResult = result; + } + + /** + * @return the comparison type + */ + public Type getType() { + return fType; + } + + /** + * @param type the comparison type + */ + public void setType(Type type) { + this.fType = type; + setValue(fValue); + } + + /** + * @return the comparison value + */ + public String getValue() { + return fValue; + } + + /** + * @param value the comparison value + */ + public void setValue(String value) { + this.fValue = value; + fValueNumber = null; + fValueTimestamp = null; + if (value == null) { + return; + } + if (fType == Type.NUM) { + try { + fValueNumber = NumberFormat.getInstance().parse(value).doubleValue(); + } catch (ParseException e) { + } + } else if (fType == Type.TIMESTAMP) { + try { + fValueTimestamp = new TmfTimestamp((long) (1E9 * NumberFormat.getInstance().parse(value.toString()).doubleValue())); + } catch (ParseException e) { + } + } + } + + @Override + public String getNodeName() { + return NODE_NAME; + } + + @Override + public boolean matches(ITmfEvent event) { + Object value = getFieldValue(event, fField); + if (value == null) { + return false ^ fNot; + } + if (fType == Type.NUM) { + if (fValueNumber != null) { + if (value instanceof Number) { + double valueDouble = ((Number) value).doubleValue(); + return (Double.compare(valueDouble, fValueNumber.doubleValue()) == fResult) ^ fNot; + } + try { + double valueDouble = NumberFormat.getInstance().parse(value.toString()).doubleValue(); + return (Double.compare(valueDouble, fValueNumber.doubleValue()) == fResult) ^ fNot; + } catch (ParseException e) { + } + } + } else if (fType == Type.ALPHA) { + String valueString = value.toString(); + int comp = valueString.compareTo(fValue.toString()); + if (comp < -1) { + comp = -1; + } else if (comp > 1) { + comp = 1; + } + return (comp == fResult) ^ fNot; + } else if (fType == Type.TIMESTAMP) { + if (fValueTimestamp != null) { + if (value instanceof TmfTimestamp) { + TmfTimestamp valueTimestamp = (TmfTimestamp) value; + return (valueTimestamp.compareTo(fValueTimestamp, false) == fResult) ^ fNot; + } + try { + TmfTimestamp valueTimestamp = new TmfTimestamp((long) (1E9 * NumberFormat + .getInstance().parse(value.toString()).doubleValue())); + return (valueTimestamp.compareTo(fValueTimestamp, false) == fResult) ^ fNot; + } catch (ParseException e) { + } + } + } + return false ^ fNot; + } + + @Override + public List getValidChildren() { + return new ArrayList<>(0); + } + + @Override + public String toString() { + String result = (fResult == 0 ? "= " : fResult < 0 ? "< " : "> "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + String open = (fType == Type.NUM ? "" : fType == Type.ALPHA ? "\"" : "["); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + String close = (fType == Type.NUM ? "" : fType == Type.ALPHA ? "\"" : "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + return fField + (fNot ? " not " : " ") + result + open + fValue + close; //$NON-NLS-1$ //$NON-NLS-2$ + } + + @Override + public ITmfFilterTreeNode clone() { + TmfFilterCompareNode clone = (TmfFilterCompareNode) super.clone(); + clone.fField = fField; + clone.setValue(fValue); + return clone; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((fField == null) ? 0 : fField.hashCode()); + result = prime * result + (fNot ? 1231 : 1237); + result = prime * result + fResult; + result = prime * result + ((fType == null) ? 0 : fType.hashCode()); + result = prime * result + ((fValue == null) ? 0 : fValue.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TmfFilterCompareNode other = (TmfFilterCompareNode) obj; + if (fField == null) { + if (other.fField != null) { + return false; + } + } else if (!fField.equals(other.fField)) { + return false; + } + if (fNot != other.fNot) { + return false; + } + if (fResult != other.fResult) { + return false; + } + if (fType != other.fType) { + return false; + } + if (fValue == null) { + if (other.fValue != null) { + return false; + } + } else if (!fValue.equals(other.fValue)) { + return false; + } + return true; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterContainsNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterContainsNode.java new file mode 100644 index 0000000000..8e9d1dcad9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterContainsNode.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.filter.model; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * Filter node for the 'contains' operation + * + * @version 1.0 + * @author Patrick Tasse + */ +@SuppressWarnings("javadoc") +public class TmfFilterContainsNode extends TmfFilterTreeNode { + + public static final String NODE_NAME = "CONTAINS"; //$NON-NLS-1$ + public static final String NOT_ATTR = "not"; //$NON-NLS-1$ + public static final String FIELD_ATTR = "field"; //$NON-NLS-1$ + public static final String VALUE_ATTR = "value"; //$NON-NLS-1$ + public static final String IGNORECASE_ATTR = "ignorecase"; //$NON-NLS-1$ + + private boolean fNot = false; + private String fField; + private String fValue; + private transient String fValueUpperCase; + private boolean fIgnoreCase = false; + + /** + * @param parent the parent node + */ + public TmfFilterContainsNode(ITmfFilterTreeNode parent) { + super(parent); + } + + /** + * @return the NOT state + */ + public boolean isNot() { + return fNot; + } + + /** + * @param not the NOT state + */ + public void setNot(boolean not) { + this.fNot = not; + } + + /** + * @return the field name + */ + public String getField() { + return fField; + } + + /** + * @param field the field name + */ + public void setField(String field) { + this.fField = field; + } + + /** + * @return the contains value + */ + public String getValue() { + return fValue; + } + + /** + * @param value the contains value + */ + public void setValue(String value) { + this.fValue = value; + if (value != null) { + fValueUpperCase = value.toUpperCase(); + } + } + + /** + * @return the ignoreCase state + */ + public boolean isIgnoreCase() { + return fIgnoreCase; + } + + /** + * @param ignoreCase the ignoreCase state + */ + public void setIgnoreCase(boolean ignoreCase) { + this.fIgnoreCase = ignoreCase; + } + + @Override + public String getNodeName() { + return NODE_NAME; + } + + @Override + public boolean matches(ITmfEvent event) { + Object value = getFieldValue(event, fField); + if (value == null) { + return false ^ fNot; + } + String valueString = value.toString(); + if (fIgnoreCase) { + return valueString.toUpperCase().contains(fValueUpperCase) ^ fNot; + } + return valueString.contains(fValue) ^ fNot; + } + + @Override + public List getValidChildren() { + return new ArrayList<>(0); + } + + @Override + public String toString() { + return fField + (fNot ? " not" : "") + " contains \"" + fValue + "\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + + @Override + public ITmfFilterTreeNode clone() { + TmfFilterContainsNode clone = (TmfFilterContainsNode) super.clone(); + clone.fField = fField; + clone.setValue(fValue); + return clone; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((fField == null) ? 0 : fField.hashCode()); + result = prime * result + (fIgnoreCase ? 1231 : 1237); + result = prime * result + (fNot ? 1231 : 1237); + result = prime * result + ((fValue == null) ? 0 : fValue.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TmfFilterContainsNode other = (TmfFilterContainsNode) obj; + if (fField == null) { + if (other.fField != null) { + return false; + } + } else if (!fField.equals(other.fField)) { + return false; + } + if (fIgnoreCase != other.fIgnoreCase) { + return false; + } + if (fNot != other.fNot) { + return false; + } + if (fValue == null) { + if (other.fValue != null) { + return false; + } + } else if (!fValue.equals(other.fValue)) { + return false; + } + return true; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterEqualsNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterEqualsNode.java new file mode 100644 index 0000000000..832d53a73b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterEqualsNode.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.filter.model; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + + +/** + * Filter node for the '==' operation + * + * @version 1.0 + * @author Patrick Tasse + */ +@SuppressWarnings("javadoc") +public class TmfFilterEqualsNode extends TmfFilterTreeNode { + + public static final String NODE_NAME = "EQUALS"; //$NON-NLS-1$ + public static final String NOT_ATTR = "not"; //$NON-NLS-1$ + public static final String FIELD_ATTR = "field"; //$NON-NLS-1$ + public static final String VALUE_ATTR = "value"; //$NON-NLS-1$ + public static final String IGNORECASE_ATTR = "ignorecase"; //$NON-NLS-1$ + + private boolean fNot = false; + private String fField; + private String fValue; + private boolean fIgnoreCase = false; + + /** + * @param parent the aprent node + */ + public TmfFilterEqualsNode(ITmfFilterTreeNode parent) { + super(parent); + } + + /** + * @return the NOT state + */ + public boolean isNot() { + return fNot; + } + + /** + * @param not the NOT state + */ + public void setNot(boolean not) { + this.fNot = not; + } + + /** + * @return the field name + */ + public String getField() { + return fField; + } + + /** + * @param field the field name + */ + public void setField(String field) { + this.fField = field; + } + + /** + * @return the equals value + */ + public String getValue() { + return fValue; + } + + /** + * @param value the equals value + */ + public void setValue(String value) { + this.fValue = value; + } + + /** + * @return the ignoreCase state + */ + public boolean isIgnoreCase() { + return fIgnoreCase; + } + + /** + * @param ignoreCase the ignoreCase state + */ + public void setIgnoreCase(boolean ignoreCase) { + this.fIgnoreCase = ignoreCase; + } + + @Override + public String getNodeName() { + return NODE_NAME; + } + + @Override + public boolean matches(ITmfEvent event) { + Object value = getFieldValue(event, fField); + if (value == null) { + return false ^ fNot; + } + String valueString = value.toString(); + if (valueString == null) { + return false ^ fNot; + } + if (fIgnoreCase) { + return valueString.equalsIgnoreCase(fValue) ^ fNot; + } + return valueString.equals(fValue) ^ fNot; + } + + @Override + public List getValidChildren() { + return new ArrayList<>(0); + } + + @Override + public String toString() { + return fField + (fNot ? " not" : "") + " equals \"" + fValue + "\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + + @Override + public ITmfFilterTreeNode clone() { + TmfFilterEqualsNode clone = (TmfFilterEqualsNode) super.clone(); + clone.fField = fField; + clone.fValue = fValue; + return clone; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((fField == null) ? 0 : fField.hashCode()); + result = prime * result + (fIgnoreCase ? 1231 : 1237); + result = prime * result + (fNot ? 1231 : 1237); + result = prime * result + ((fValue == null) ? 0 : fValue.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TmfFilterEqualsNode other = (TmfFilterEqualsNode) obj; + if (fField == null) { + if (other.fField != null) { + return false; + } + } else if (!fField.equals(other.fField)) { + return false; + } + if (fIgnoreCase != other.fIgnoreCase) { + return false; + } + if (fNot != other.fNot) { + return false; + } + if (fValue == null) { + if (other.fValue != null) { + return false; + } + } else if (!fValue.equals(other.fValue)) { + return false; + } + return true; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterEventTypeNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterEventTypeNode.java new file mode 100644 index 0000000000..bfcacf092d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterEventTypeNode.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.filter.model; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * Filter node for an event + * + * @version 1.0 + * @author Patrick Tasse + */ +@SuppressWarnings("javadoc") +public class TmfFilterEventTypeNode extends TmfFilterTreeNode { + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((fName == null) ? 0 : fName.hashCode()); + result = prime * result + ((fType == null) ? 0 : fType.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TmfFilterEventTypeNode other = (TmfFilterEventTypeNode) obj; + if (fName == null) { + if (other.fName != null) { + return false; + } + } else if (!fName.equals(other.fName)) { + return false; + } + if (fType == null) { + if (other.fType != null) { + return false; + } + } else if (!fType.equals(other.fType)) { + return false; + } + return true; + } + + public static final String NODE_NAME = "EVENTTYPE"; //$NON-NLS-1$ + public static final String TYPE_ATTR = "type"; //$NON-NLS-1$ + public static final String NAME_ATTR = "name"; //$NON-NLS-1$ + + private String fType; + private String fName; + + /** + * @param parent the parent node + */ + public TmfFilterEventTypeNode(ITmfFilterTreeNode parent) { + super(parent); + } + + @Override + public String getNodeName() { + return NODE_NAME; + } + + /** + * @return the event type + */ + public String getEventType() { + return fType; + } + + /** + * @param type the event type + */ + public void setEventType(String type) { + this.fType = type; + } + + /** + * @return the category and trace type name + */ + public String getName() { + return fName; + } + + /** + * @param name the category and trace type name + */ + public void setName(String name) { + this.fName = name; + } + + @Override + public boolean matches(ITmfEvent event) { + boolean match = false; + if (fType.contains(":")) { //$NON-NLS-1$ + // special case for custom parsers + if (fType.startsWith(event.getClass().getCanonicalName())) { + if (fType.endsWith(event.getType().getName())) { + match = true; + } + } + } else { + if (event.getClass().getCanonicalName().equals(fType)) { + match = true; + } + } + if (match) { + // There should be at most one child + for (ITmfFilterTreeNode node : getChildren()) { + if (! node.matches(event)) { + return false; + } + } + return true; + } + return false; + } + + @Override + public List getValidChildren() { + if (getChildrenCount() == 0) { + return super.getValidChildren(); + } + return new ArrayList<>(0); // only one child allowed + } + + @Override + public String toString() { + StringBuffer buf = new StringBuffer(); + buf.append("EventType is " + fName); //$NON-NLS-1$ + if (getChildrenCount() > 0) { + buf.append(" and "); //$NON-NLS-1$ + } + if (getChildrenCount() > 1) { + buf.append("( "); //$NON-NLS-1$ + } + for (int i = 0; i < getChildrenCount(); i++) { + ITmfFilterTreeNode node = getChildren()[i]; + buf.append(node.toString()); + if (i < getChildrenCount() - 1) { + buf.append(" and "); //$NON-NLS-1$ + } + } + if (getChildrenCount() > 1) { + buf.append(" )"); //$NON-NLS-1$ + } + return buf.toString(); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterMatchesNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterMatchesNode.java new file mode 100644 index 0000000000..1d928eadb1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterMatchesNode.java @@ -0,0 +1,196 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.filter.model; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * Filter node for the regex match + * + * @version 1.0 + * @author Patrick Tasse + */ +@SuppressWarnings("javadoc") +public class TmfFilterMatchesNode extends TmfFilterTreeNode { + + public static final String NODE_NAME = "MATCHES"; //$NON-NLS-1$ + public static final String NOT_ATTR = "not"; //$NON-NLS-1$ + public static final String FIELD_ATTR = "field"; //$NON-NLS-1$ + public static final String REGEX_ATTR = "regex"; //$NON-NLS-1$ + + private boolean fNot = false; + private String fField; + private String fRegex; + private transient Pattern fPattern; + + /** + * @param parent + * the parent node + */ + public TmfFilterMatchesNode(ITmfFilterTreeNode parent) { + super(parent); + } + + /** + * @return the NOT state + */ + public boolean isNot() { + return fNot; + } + + /** + * @param not + * the NOT state + */ + public void setNot(boolean not) { + this.fNot = not; + } + + /** + * @return the field name + */ + public String getField() { + return fField; + } + + /** + * @param field + * the field name + */ + public void setField(String field) { + this.fField = field; + } + + /** + * @return the regular expression + */ + public String getRegex() { + return fRegex; + } + + /** + * @param regex + * the regular expression + */ + public void setRegex(String regex) { + this.fRegex = regex; + if (regex != null) { + try { + this.fPattern = Pattern.compile(regex, Pattern.DOTALL); + } catch (PatternSyntaxException e) { + this.fPattern = null; + } + } + } + + @Override + public String getNodeName() { + return NODE_NAME; + } + + @Override + public boolean matches(ITmfEvent event) { + if (fPattern == null) { + return false ^ fNot; + } + + Object value = getFieldValue(event, fField); + if (value == null) { + return false ^ fNot; + } + String valueString = value.toString(); + + return fPattern.matcher(valueString).matches() ^ fNot; + } + + @Override + public List getValidChildren() { + return new ArrayList<>(0); + } + + @Override + public String toString() { + return fField + (fNot ? " not" : "") + " matches \"" + fRegex + "\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + + @Override + public ITmfFilterTreeNode clone() { + TmfFilterMatchesNode clone = (TmfFilterMatchesNode) super.clone(); + clone.fField = fField; + clone.setRegex(fRegex); + return clone; + } + + /** + * @param pattern + * the rough regex pattern + * @return the compliant regex + */ + public static String regexFix(String pattern) { + String ret = pattern; + // if the pattern does not contain one of the expressions .* !^ + // (at the beginning) $ (at the end), then a .* is added at the + // beginning and at the end of the pattern + if (!(ret.indexOf(".*") >= 0 || ret.charAt(0) == '^' || ret.charAt(ret.length() - 1) == '$')) { //$NON-NLS-1$ + ret = ".*" + ret + ".*"; //$NON-NLS-1$ //$NON-NLS-2$ + } + return ret; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((fField == null) ? 0 : fField.hashCode()); + result = prime * result + (fNot ? 1231 : 1237); + result = prime * result + ((fRegex == null) ? 0 : fRegex.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TmfFilterMatchesNode other = (TmfFilterMatchesNode) obj; + if (fField == null) { + if (other.fField != null) { + return false; + } + } else if (!fField.equals(other.fField)) { + return false; + } + if (fNot != other.fNot) { + return false; + } + if (fRegex == null) { + if (other.fRegex != null) { + return false; + } + } else if (!fRegex.equals(other.fRegex)) { + return false; + } + return true; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterNode.java new file mode 100644 index 0000000000..a63719f088 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterNode.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.filter.model; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * Filter node for the event match operation + * + * @version 1.0 + * @author Patrick Tasse + */ +@SuppressWarnings("javadoc") +public class TmfFilterNode extends TmfFilterTreeNode { + + public static final String NODE_NAME = "FILTER"; //$NON-NLS-1$ + public static final String NAME_ATTR = "name"; //$NON-NLS-1$ + + String fFilterName; + + /** + * @param filterName the filter name + */ + public TmfFilterNode(String filterName) { + super(null); + fFilterName = filterName; + } + + /** + * @param parent the parent node + * @param filterName the filter name + */ + public TmfFilterNode(ITmfFilterTreeNode parent, String filterName) { + super(parent); + fFilterName = filterName; + } + + /** + * @return the filer name + */ + public String getFilterName() { + return fFilterName; + } + + /** + * @param filterName the filer name + */ + public void setFilterName(String filterName) { + fFilterName = filterName; + } + + @Override + public String getNodeName() { + return NODE_NAME; + } + + @Override + public boolean matches(ITmfEvent event) { + // There should be at most one child + for (ITmfFilterTreeNode node : getChildren()) { + if (node.matches(event)) { + return true; + } + } + return false; + } + + @Override + public List getValidChildren() { + if (getChildrenCount() == 0) { + return super.getValidChildren(); + } + return new ArrayList<>(0); // only one child allowed + } + + @Override + public String toString() { + StringBuffer buf = new StringBuffer(); + if (getChildrenCount() > 1) { + buf.append("( "); //$NON-NLS-1$ + } + for (int i = 0; i < getChildrenCount(); i++) { + ITmfFilterTreeNode node = getChildren()[i]; + buf.append(node.toString()); + if (i < (getChildrenCount() - 1)) { + buf.append(" and "); //$NON-NLS-1$ + } + } + if (getChildrenCount() > 1) { + buf.append(" )"); //$NON-NLS-1$ + } + return buf.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((fFilterName == null) ? 0 : fFilterName.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TmfFilterNode other = (TmfFilterNode) obj; + if (fFilterName == null) { + if (other.fFilterName != null) { + return false; + } + } else if (!fFilterName.equals(other.fFilterName)) { + return false; + } + return true; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterOrNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterOrNode.java new file mode 100644 index 0000000000..138d052d5f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterOrNode.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.filter.model; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * Filter node for the 'or' operation + * + * @version 1.0 + * @author Patrick Tasse + */ +@SuppressWarnings("javadoc") +public class TmfFilterOrNode extends TmfFilterTreeNode { + + public static final String NODE_NAME = "OR"; //$NON-NLS-1$ + public static final String NOT_ATTR = "not"; //$NON-NLS-1$ + + private boolean fNot = false; + + /** + * @param parent the parent node + */ + public TmfFilterOrNode(ITmfFilterTreeNode parent) { + super(parent); + } + + @Override + public String getNodeName() { + return NODE_NAME; + } + + /** + * @return the NOT state + */ + public boolean isNot() { + return fNot; + } + + /** + * @param not the NOT state + */ + public void setNot(boolean not) { + this.fNot = not; + } + + @Override + public boolean matches(ITmfEvent event) { + for (ITmfFilterTreeNode node : getChildren()) { + if (node.matches(event)) { + return true ^ fNot; + } + } + return false & fNot; + } + + @Override + public String toString() { + StringBuffer buf = new StringBuffer(); + if (fNot) { + buf.append("not "); //$NON-NLS-1$ + } + if (getParent() != null && !(getParent() instanceof TmfFilterRootNode) && !(getParent() instanceof TmfFilterNode)) { + buf.append("( "); //$NON-NLS-1$ + } + for (int i = 0; i < getChildrenCount(); i++) { + ITmfFilterTreeNode node = getChildren()[i]; + buf.append(node.toString()); + if (i < getChildrenCount() - 1) { + buf.append(" or "); //$NON-NLS-1$ + } + } + if (getParent() != null && !(getParent() instanceof TmfFilterRootNode) && !(getParent() instanceof TmfFilterNode)) { + buf.append(" )"); //$NON-NLS-1$ + } + return buf.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + (fNot ? 1231 : 1237); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TmfFilterOrNode other = (TmfFilterOrNode) obj; + if (fNot != other.fNot) { + return false; + } + return true; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterRootNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterRootNode.java new file mode 100644 index 0000000000..194ec712b1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterRootNode.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.filter.model; + +import java.util.Arrays; +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * The Filter tree root node + * + * @version 1.0 + * @author Patrick Tasse + */ +public class TmfFilterRootNode extends TmfFilterTreeNode { + + @SuppressWarnings("javadoc") + public static final String NODE_NAME = "ROOT"; //$NON-NLS-1$ + + private static final String[] VALID_CHILDREN = { + TmfFilterNode.NODE_NAME + }; + + /** + * Default constructor + */ + public TmfFilterRootNode() { + super(null); + } + + @Override + public String getNodeName() { + return NODE_NAME; + } + + @Override + public boolean matches(ITmfEvent event) { + for (ITmfFilterTreeNode node : getChildren()) { + if (! node.matches(event)) { + return false; + } + } + return true; + } + + @Override + public List getValidChildren() { + return Arrays.asList(VALID_CHILDREN); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterTreeNode.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterTreeNode.java new file mode 100644 index 0000000000..ca21892006 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/model/TmfFilterTreeNode.java @@ -0,0 +1,264 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Yuriy Vashchuk (yvashchuk@gmail.com) - Initial API and implementation + * Patrick Tasse - Refactoring + * Vincent Perot - Add subfield filtering + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.filter.model; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; + +/** + * The base class for the Filter tree nodes + * + * @version 1.0 + * @author Yuriy Vashchuk + * @author Patrick Tasse + */ +public abstract class TmfFilterTreeNode implements ITmfFilterTreeNode, Cloneable { + + private static final char SLASH = '/'; + private static final char BACKSLASH = '\\'; + + private static final String[] VALID_CHILDREN = { + TmfFilterEventTypeNode.NODE_NAME, + TmfFilterAndNode.NODE_NAME, + TmfFilterOrNode.NODE_NAME, + TmfFilterContainsNode.NODE_NAME, + TmfFilterEqualsNode.NODE_NAME, + TmfFilterMatchesNode.NODE_NAME, + TmfFilterCompareNode.NODE_NAME + }; + + private ITmfFilterTreeNode parent = null; + private ArrayList children = new ArrayList<>(); + + private String fPathAsString = null; + private String[] fPathAsArray = null; + + /** + * @param parent + * the parent node + */ + public TmfFilterTreeNode(final ITmfFilterTreeNode parent) { + if (parent != null) { + parent.addChild(this); + } + } + + @Override + public ITmfFilterTreeNode getParent() { + return parent; + } + + @Override + public abstract String getNodeName(); + + @Override + public boolean hasChildren() { + return (children.size() > 0); + } + + @Override + public int getChildrenCount() { + return children.size(); + } + + @Override + public ITmfFilterTreeNode[] getChildren() { + return children.toArray(new ITmfFilterTreeNode[0]); + } + + @Override + public ITmfFilterTreeNode getChild(final int index) throws IndexOutOfBoundsException { + return children.get(index); + } + + @Override + public ITmfFilterTreeNode remove() { + if (getParent() != null) { + getParent().removeChild(this); + } + return this; + } + + @Override + public ITmfFilterTreeNode removeChild(ITmfFilterTreeNode node) { + children.remove(node); + node.setParent(null); + return node; + } + + @Override + public int addChild(final ITmfFilterTreeNode node) { + node.setParent(this); + if (children.add(node)) { + return (children.size() - 1); + } + return -1; + } + + @Override + public ITmfFilterTreeNode replaceChild(final int index, final ITmfFilterTreeNode node) throws IndexOutOfBoundsException { + node.setParent(this); + return children.set(index, node); + } + + @Override + public void setParent(final ITmfFilterTreeNode parent) { + this.parent = parent; + } + + @Override + public abstract boolean matches(ITmfEvent event); + + /** + * @param event + * the event + * @param field + * the field id + * @return the field value + */ + protected Object getFieldValue(ITmfEvent event, String field) { + Object value = null; + if (ITmfEvent.EVENT_FIELD_CONTENT.equals(field)) { + value = event.getContent().toString(); + } + else if (ITmfEvent.EVENT_FIELD_TYPE.equals(field)) { + value = event.getType().getName(); + } + else if (ITmfEvent.EVENT_FIELD_TIMESTAMP.equals(field)) { + value = event.getTimestamp().toString(); + } + else if (ITmfEvent.EVENT_FIELD_SOURCE.equals(field)) { + value = event.getSource(); + } + else if (ITmfEvent.EVENT_FIELD_REFERENCE.equals(field)) { + value = event.getReference(); + } + else { + if (field == null) { + return null; + } + ITmfEventField eventField; + if (field.isEmpty() || field.charAt(0) != SLASH) { + eventField = event.getContent().getField(field); + } else { + String[] array = getPathArray(field); + eventField = event.getContent().getSubField(array); + } + + if (eventField != null) { + value = eventField.getValue(); + } + } + return value; + } + + private String[] getPathArray(String field) { + + // Check if last request was not the same string. + if (field.equals(fPathAsString)) { + return fPathAsArray; + } + + // Generate the new path array + StringBuilder sb = new StringBuilder(); + List list = new ArrayList<>(); + + // We start at 1 since the first character is a slash that we want to + // ignore. + for (int i = 1; i < field.length(); i++) { + char charAt = field.charAt(i); + if (charAt == SLASH) { + // char is slash. Cut here. + list.add(sb.toString()); + sb = new StringBuilder(); + } else if (charAt == BACKSLASH && i < field.length() - 1 && field.charAt(i + 1) == SLASH) { + // Uninterpreted slash. Add it. + sb.append(SLASH); + i++; + } else { + // Any other character. Add. + sb.append(charAt); + } + } + + // Last block. Add it to list. + list.add(sb.toString()); + + // Transform to array + String[] array = new String[list.size()]; + list.toArray(array); + + // Save new values. + // Array first for solving concurrency issues + fPathAsArray = array; + fPathAsString = field; + + return array; + } + + @Override + public List getValidChildren() { + return Arrays.asList(VALID_CHILDREN); + } + + @Override + public ITmfFilterTreeNode clone() { + try { + TmfFilterTreeNode clone = (TmfFilterTreeNode) super.clone(); + clone.parent = null; + clone.children = new ArrayList<>(children.size()); + for (ITmfFilterTreeNode child : getChildren()) { + clone.addChild(child.clone()); + } + return clone; + } catch (CloneNotSupportedException e) { + return null; + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((children == null) ? 0 : children.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TmfFilterTreeNode other = (TmfFilterTreeNode) obj; + if (children == null) { + if (other.children != null) { + return false; + } + } else if (!children.equals(other.children)) { + return false; + } + return true; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/xml/TmfFilterContentHandler.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/xml/TmfFilterContentHandler.java new file mode 100644 index 0000000000..7d209cd82c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/xml/TmfFilterContentHandler.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Yuriy Vashchuk (yvashchuk@gmail.com) - Initial API and implementation + * based on http://smeric.developpez.com/java/cours/xml/sax/ + * Patrick Tasse - Refactoring + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.filter.xml; + +import java.util.Stack; + +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterAndNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterCompareNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterContainsNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterEqualsNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterEventTypeNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterMatchesNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterOrNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterRootNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterTreeNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterCompareNode.Type; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * The SAX Content Handler + * + * @version 1.0 + * @author Yuriy Vashchuk + * @author Patrick Tasse + */ +public class TmfFilterContentHandler extends DefaultHandler { + + private ITmfFilterTreeNode fRoot = null; + private Stack fFilterTreeStack = null; + + /** + * The default constructor + */ + public TmfFilterContentHandler() { + super(); + fFilterTreeStack = new Stack<>(); + } + + /** + * Getter of tree + * + * @return The builded tree + */ + public ITmfFilterTreeNode getTree() { + return fRoot; + } + + + @Override + public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { + ITmfFilterTreeNode node = null; + + if (localName.equalsIgnoreCase(TmfFilterRootNode.NODE_NAME)) { + + node = new TmfFilterRootNode(); + + } else if (localName.equals(TmfFilterNode.NODE_NAME)) { + + node = new TmfFilterNode(atts.getValue(TmfFilterNode.NAME_ATTR)); + + } else if (localName.equals(TmfFilterEventTypeNode.NODE_NAME)) { + + node = new TmfFilterEventTypeNode(null); + ((TmfFilterEventTypeNode) node).setEventType(atts.getValue(TmfFilterEventTypeNode.TYPE_ATTR)); + ((TmfFilterEventTypeNode) node).setName(atts.getValue(TmfFilterEventTypeNode.NAME_ATTR)); + + } else if (localName.equals(TmfFilterAndNode.NODE_NAME)) { + + node = new TmfFilterAndNode(null); + String value = atts.getValue(TmfFilterAndNode.NOT_ATTR); + if (value != null && value.equalsIgnoreCase(Boolean.TRUE.toString())) { + ((TmfFilterAndNode) node).setNot(true); + } + + } else if (localName.equals(TmfFilterOrNode.NODE_NAME)) { + + node = new TmfFilterOrNode(null); + String value = atts.getValue(TmfFilterOrNode.NOT_ATTR); + if (value != null && value.equalsIgnoreCase(Boolean.TRUE.toString())) { + ((TmfFilterOrNode) node).setNot(true); + } + + } else if (localName.equals(TmfFilterContainsNode.NODE_NAME)) { + + node = new TmfFilterContainsNode(null); + String value = atts.getValue(TmfFilterContainsNode.NOT_ATTR); + if (value != null && value.equalsIgnoreCase(Boolean.TRUE.toString())) { + ((TmfFilterContainsNode) node).setNot(true); + } + ((TmfFilterContainsNode) node).setField(atts.getValue(TmfFilterContainsNode.FIELD_ATTR)); + ((TmfFilterContainsNode) node).setValue(atts.getValue(TmfFilterContainsNode.VALUE_ATTR)); + value = atts.getValue(TmfFilterContainsNode.IGNORECASE_ATTR); + if (value != null && value.equalsIgnoreCase(Boolean.TRUE.toString())) { + ((TmfFilterContainsNode) node).setIgnoreCase(true); + } + + } else if (localName.equals(TmfFilterEqualsNode.NODE_NAME)) { + + node = new TmfFilterEqualsNode(null); + String value = atts.getValue(TmfFilterEqualsNode.NOT_ATTR); + if (value != null && value.equalsIgnoreCase(Boolean.TRUE.toString())) { + ((TmfFilterEqualsNode) node).setNot(true); + } + ((TmfFilterEqualsNode) node).setField(atts.getValue(TmfFilterEqualsNode.FIELD_ATTR)); + ((TmfFilterEqualsNode) node).setValue(atts.getValue(TmfFilterEqualsNode.VALUE_ATTR)); + value = atts.getValue(TmfFilterEqualsNode.IGNORECASE_ATTR); + if (value != null && value.equalsIgnoreCase(Boolean.TRUE.toString())) { + ((TmfFilterEqualsNode) node).setIgnoreCase(true); + } + + } else if (localName.equals(TmfFilterMatchesNode.NODE_NAME)) { + + node = new TmfFilterMatchesNode(null); + String value = atts.getValue(TmfFilterMatchesNode.NOT_ATTR); + if (value != null && value.equalsIgnoreCase(Boolean.TRUE.toString())) { + ((TmfFilterMatchesNode) node).setNot(true); + } + ((TmfFilterMatchesNode) node).setField(atts.getValue(TmfFilterMatchesNode.FIELD_ATTR)); + ((TmfFilterMatchesNode) node).setRegex(atts.getValue(TmfFilterMatchesNode.REGEX_ATTR)); + + } else if (localName.equals(TmfFilterCompareNode.NODE_NAME)) { + + node = new TmfFilterCompareNode(null); + String value = atts.getValue(TmfFilterCompareNode.NOT_ATTR); + if (value != null && value.equalsIgnoreCase(Boolean.TRUE.toString())) { + ((TmfFilterCompareNode) node).setNot(true); + } + ((TmfFilterCompareNode) node).setField(atts.getValue(TmfFilterCompareNode.FIELD_ATTR)); + value = atts.getValue(TmfFilterCompareNode.TYPE_ATTR); + if (value != null) { + ((TmfFilterCompareNode) node).setType(Type.valueOf(value)); + } + value = atts.getValue(TmfFilterCompareNode.RESULT_ATTR); + if (value != null) { + if (value.equals(Integer.toString(-1))) { + ((TmfFilterCompareNode) node).setResult(-1); + } else if (value.equals(Integer.toString(1))) { + ((TmfFilterCompareNode) node).setResult(1); + } else { + ((TmfFilterCompareNode) node).setResult(0); + } + } + ((TmfFilterCompareNode) node).setValue(atts.getValue(TmfFilterCompareNode.VALUE_ATTR)); + + } + + fFilterTreeStack.push(node); + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + ITmfFilterTreeNode node = fFilterTreeStack.pop(); + + if (fFilterTreeStack.isEmpty()) { + fRoot = node; + } else if (fFilterTreeStack.lastElement() instanceof TmfFilterTreeNode && + node instanceof TmfFilterTreeNode) { + fFilterTreeStack.lastElement().addChild(node); + } + + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/xml/TmfFilterXMLParser.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/xml/TmfFilterXMLParser.java new file mode 100644 index 0000000000..8f910b8dd6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/xml/TmfFilterXMLParser.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Yuriy Vashchuk (yvashchuk@gmail.com) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.filter.xml; + +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; + +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +/** + * The SAX based XML parser + * + * @version 1.0 + * @author Yuriy Vashchuk + * @author Patrick Tasse + */ +public class TmfFilterXMLParser { + + private static ITmfFilterTreeNode fRoot = null; + + /** + * The XMLParser constructor + * + * @param uri The XML file to parse + * @throws SAXException SAX exception + * @throws IOException IO exception + */ + public TmfFilterXMLParser(final String uri) throws SAXException, IOException { + + SAXParserFactory m_parserFactory = null; + m_parserFactory = SAXParserFactory.newInstance(); + m_parserFactory.setNamespaceAware(true); + + XMLReader saxReader = null; + try { + + saxReader = m_parserFactory.newSAXParser().getXMLReader(); + saxReader.setContentHandler(new TmfFilterContentHandler()); + saxReader.parse(uri); + + fRoot = ((TmfFilterContentHandler) saxReader.getContentHandler()).getTree(); + + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } + } + + /** + * Getter of tree + * + * @return The builded tree + */ + public ITmfFilterTreeNode getTree() { + return fRoot; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/xml/TmfFilterXMLWriter.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/xml/TmfFilterXMLWriter.java new file mode 100644 index 0000000000..6935565ba4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/filter/xml/TmfFilterXMLWriter.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Yuriy Vashchuk (yvashchuk@gmail.com) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.filter.xml; + +import java.io.File; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterAndNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterCompareNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterContainsNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterEqualsNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterEventTypeNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterMatchesNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterOrNode; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * The SAX based XML writer + * + * @version 1.0 + * @author Yuriy Vashchuk + * @author Patrick Tasse + */ +public class TmfFilterXMLWriter { + + private Document document = null; + + /** + * The XMLParser constructor + * + * @param root The tree root + * @throws ParserConfigurationException if a DocumentBuilder + * cannot be created which satisfies the configuration requested. + */ + public TmfFilterXMLWriter(final ITmfFilterTreeNode root) throws ParserConfigurationException { + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + document = documentBuilder.newDocument(); + + Element rootElement = document.createElement(root.getNodeName()); + document.appendChild(rootElement); + + for (ITmfFilterTreeNode node : root.getChildren()) { + buildXMLTree(document, node, rootElement); + } + } + + /** + * The Tree to XML parser + * + * @param document The XML document + * @param treenode The node to write + * @param parentElement The XML element of the parent + */ + public static void buildXMLTree(final Document document, final ITmfFilterTreeNode treenode, Element parentElement) { + Element element = document.createElement(treenode.getNodeName()); + + if (treenode instanceof TmfFilterNode) { + + TmfFilterNode node = (TmfFilterNode) treenode; + element.setAttribute(TmfFilterNode.NAME_ATTR, node.getFilterName()); + + } else if (treenode instanceof TmfFilterEventTypeNode) { + + TmfFilterEventTypeNode node = (TmfFilterEventTypeNode) treenode; + element.setAttribute(TmfFilterEventTypeNode.TYPE_ATTR, node.getEventType()); + element.setAttribute(TmfFilterEventTypeNode.NAME_ATTR, node.getName()); + + } else if (treenode instanceof TmfFilterAndNode) { + + TmfFilterAndNode node = (TmfFilterAndNode) treenode; + element.setAttribute(TmfFilterAndNode.NOT_ATTR, Boolean.toString(node.isNot())); + + } else if (treenode instanceof TmfFilterOrNode) { + + TmfFilterOrNode node = (TmfFilterOrNode) treenode; + element.setAttribute(TmfFilterOrNode.NOT_ATTR, Boolean.toString(node.isNot())); + + } else if (treenode instanceof TmfFilterContainsNode) { + + TmfFilterContainsNode node = (TmfFilterContainsNode) treenode; + element.setAttribute(TmfFilterContainsNode.NOT_ATTR, Boolean.toString(node.isNot())); + element.setAttribute(TmfFilterContainsNode.FIELD_ATTR, node.getField()); + element.setAttribute(TmfFilterContainsNode.VALUE_ATTR, node.getValue()); + element.setAttribute(TmfFilterContainsNode.IGNORECASE_ATTR, Boolean.toString(node.isIgnoreCase())); + + } else if (treenode instanceof TmfFilterEqualsNode) { + + TmfFilterEqualsNode node = (TmfFilterEqualsNode) treenode; + element.setAttribute(TmfFilterEqualsNode.NOT_ATTR, Boolean.toString(node.isNot())); + element.setAttribute(TmfFilterEqualsNode.FIELD_ATTR, node.getField()); + element.setAttribute(TmfFilterEqualsNode.VALUE_ATTR, node.getValue()); + element.setAttribute(TmfFilterEqualsNode.IGNORECASE_ATTR, Boolean.toString(node.isIgnoreCase())); + + } else if (treenode instanceof TmfFilterMatchesNode) { + + TmfFilterMatchesNode node = (TmfFilterMatchesNode) treenode; + element.setAttribute(TmfFilterMatchesNode.NOT_ATTR, Boolean.toString(node.isNot())); + element.setAttribute(TmfFilterMatchesNode.FIELD_ATTR, node.getField()); + element.setAttribute(TmfFilterMatchesNode.REGEX_ATTR, node.getRegex()); + + } else if (treenode instanceof TmfFilterCompareNode) { + + TmfFilterCompareNode node = (TmfFilterCompareNode) treenode; + element.setAttribute(TmfFilterCompareNode.NOT_ATTR, Boolean.toString(node.isNot())); + element.setAttribute(TmfFilterCompareNode.FIELD_ATTR, node.getField()); + element.setAttribute(TmfFilterCompareNode.RESULT_ATTR, Integer.toString(node.getResult())); + element.setAttribute(TmfFilterCompareNode.TYPE_ATTR, node.getType().toString()); + element.setAttribute(TmfFilterCompareNode.VALUE_ATTR, node.getValue()); + + } + + parentElement.appendChild(element); + + for (int i = 0; i < treenode.getChildrenCount(); i++) { + buildXMLTree(document, treenode.getChild(i), element); + } + } + + /** + * Save the tree + * + * @param uri The new Filter XML path + */ + public void saveTree(final String uri) { + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + + try { + Transformer transformer = transformerFactory.newTransformer(); + DOMSource source = new DOMSource(document); + StreamResult result = new StreamResult(new File(uri)); + transformer.transform(source, result); + } catch (TransformerConfigurationException e) { + e.printStackTrace(); + } catch (TransformerException e) { + e.printStackTrace(); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/io/BufferedRandomAccessFile.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/io/BufferedRandomAccessFile.java new file mode 100644 index 0000000000..4974c4d13e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/io/BufferedRandomAccessFile.java @@ -0,0 +1,229 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation, based on article by Nick Zhang + * (http://www.javaworld.com/javatips/jw-javatip26.html) + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.io; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.charset.Charset; + +/** + * A class to mitigate the Java I/O inefficiency of RandomAccessFile. + * + * @version 1.0 + * @author Patrick Tasse + */ +public class BufferedRandomAccessFile extends RandomAccessFile { + + private static final int DEFAULT_BUF_SIZE = 8192; + private static final Charset CHARSET_UTF8 = Charset.forName("UTF-8"); //$NON-NLS-1$ + + private final int BUF_SIZE; + private final byte buffer[]; + private int buf_end = 0; + private int buf_pos = 0; + private long real_pos = 0; + private final StringBuilder sb = new StringBuilder(); + + /** + * Constructor using the default buffer size + * + * @param name + * File path. This is passed as-is to the RandomAccessFile's + * constructor. + * @param mode + * File open mode ("r", "rw", etc.). This is passed as-is to + * RandomAccessFile's constructor. + * @throws IOException + * If the file was not found or couldn't be opened with the + * request permissions + */ + public BufferedRandomAccessFile(String name, String mode) throws IOException { + this(name, mode, DEFAULT_BUF_SIZE); + } + + /** + * Constructor using the default buffer size + * + * @param file + * File object. This is passed as-is to the RandomAccessFile's + * constructor. + * @param mode + * File open mode ("r", "rw", etc.). This is passed as-is to + * RandomAccessFile's constructor. + * @throws IOException + * If the file was not found or couldn't be opened with the + * request permissions + */ + public BufferedRandomAccessFile(File file, String mode) throws IOException { + this(file, mode, DEFAULT_BUF_SIZE); + } + + /** + * Standard constructor. + * + * @param name + * File path. This is passed as-is to the RandomAccessFile's + * constructor. + * @param mode + * File open mode ("r", "rw", etc.). This is passed as-is to + * RandomAccessFile's constructor. + * @param bufsize + * Buffer size to use, in bytes + * @throws IOException + * If the file was not found or couldn't be opened with the + * request permissions + */ + public BufferedRandomAccessFile(String name, String mode, int bufsize) throws IOException { + super(name, mode); + invalidate(); + BUF_SIZE = bufsize; + buffer = new byte[BUF_SIZE]; + } + + /** + * Standard constructor. + * + * @param file + * File object. This is passed as-is to the RandomAccessFile's + * constructor. + * @param mode + * File open mode ("r", "rw", etc.). This is passed as-is to + * RandomAccessFile's constructor. + * @param bufsize + * Buffer size to use, in bytes + * @throws IOException + * If the file was not found or couldn't be opened with the + * request permissions + */ + public BufferedRandomAccessFile(File file, String mode, int bufsize) throws IOException { + super(file, mode); + invalidate(); + BUF_SIZE = bufsize; + buffer = new byte[BUF_SIZE]; + } + + @Override + public final int read() throws IOException { + if (buf_pos >= buf_end) { + if (fillBuffer() < 0) { + return -1; + } + } + if (buf_end == 0) { + return -1; + } + return (buffer[buf_pos++] & 0xff); + } + + @Override + public int read(byte b[], int off, int len) throws IOException { + int leftover = buf_end - buf_pos; + if (len <= leftover) { + System.arraycopy(buffer, buf_pos, b, off, len); + buf_pos += len; + return len; + } + for (int i = 0; i < len; i++) { + int c = this.read(); + if (c != -1) { + b[off + i] = (byte) c; + } else { + if (i == 0) { + return -1; + } + return i; + } + } + return len; + } + + @Override + public long getFilePointer() throws IOException { + long l = real_pos; + return (l - buf_end + buf_pos); + } + + @Override + public void seek(long pos) throws IOException { + int n = (int) (real_pos - pos); + if (n >= 0 && n <= buf_end) { + buf_pos = buf_end - n; + } else { + super.seek(pos); + invalidate(); + } + } + + /** + * Read the next line from the buffer (ie, until the next '\n'). The bytes + * are interpreted as UTF-8 characters. + * + * @return The String that was read + * @throws IOException + * If we failed reading the file + */ + public final String getNextLine() throws IOException { + String str = null; + if (buf_end - buf_pos <= 0) { + if (fillBuffer() < 0) { + return null; + } + } + int lineend = -1; + for (int i = buf_pos; i < buf_end; i++) { + if (buffer[i] == '\n') { + lineend = i; + break; + } + } + if (lineend < 0) { + sb.delete(0, sb.length()); + int c; + while (((c = read()) != -1) && (c != '\n')) { + sb.append((char) c); + } + if ((c == -1) && (sb.length() == 0)) { + return null; + } + if (sb.charAt(sb.length() - 1) == '\r') { + sb.deleteCharAt(sb.length() - 1); + } + return sb.toString(); + } + if (lineend > 0 && buffer[lineend - 1] == '\r' && lineend > buf_pos) { + str = new String(buffer, buf_pos, lineend - buf_pos - 1, CHARSET_UTF8); + } else { + str = new String(buffer, buf_pos, lineend - buf_pos, CHARSET_UTF8); + } + buf_pos = lineend + 1; + return str; + } + + private int fillBuffer() throws IOException { + int n = super.read(buffer, 0, BUF_SIZE); + if (n >= 0) { + real_pos += n; + buf_end = n; + buf_pos = 0; + } + return n; + } + + private void invalidate() throws IOException { + buf_end = 0; + buf_pos = 0; + real_pos = super.getFilePointer(); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/messages.properties b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/messages.properties new file mode 100644 index 0000000000..501a62717c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/messages.properties @@ -0,0 +1,13 @@ +############################################################################### +# Copyright (c) 2013 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Marc-Andre Laperle - Initial API and implementation +############################################################################### + +DefaultTraceProjectName=Tracing \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomEvent.java new file mode 100644 index 0000000000..26ac66a81c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomEvent.java @@ -0,0 +1,314 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.parsers.custom; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition.OutputColumn; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Base event for custom text parsers. + * + * @author Patrick Tassé + * @since 3.0 + */ +public class CustomEvent extends TmfEvent { + + /** Input format key */ + protected static final String TIMESTAMP_INPUT_FORMAT_KEY = "CE_TS_I_F"; //$NON-NLS-1$ + + /** Empty message */ + protected static final String NO_MESSAGE = ""; //$NON-NLS-1$ + + /** Replacement for the super-class' timestamp field */ + private ITmfTimestamp customEventTimestamp; + + /** Replacement for the super-class' content field */ + private ITmfEventField customEventContent; + + /** Replacement for the super-class' type field */ + private ITmfEventType customEventType; + + /** The trace to which this event belongs */ + protected CustomTraceDefinition fDefinition; + + /** The payload data of this event, */ + protected Map fData; + + private TmfEventField[] fColumnData; + + /** + * Basic constructor. + * + * @param definition + * The trace definition to which this event belongs + */ + public CustomEvent(CustomTraceDefinition definition) { + fDefinition = definition; + fData = new HashMap<>(); + } + + /** + * Build a new CustomEvent from an existing TmfEvent. + * + * @param definition + * The trace definition to which this event belongs + * @param other + * The TmfEvent to copy + */ + public CustomEvent(CustomTraceDefinition definition, TmfEvent other) { + super(other); + fDefinition = definition; + fData = new HashMap<>(); + + /* Set our overridden fields */ + customEventTimestamp = other.getTimestamp(); + customEventContent = other.getContent(); + customEventType = other.getType(); + } + + /** + * Full constructor + * + * @param definition + * Trace definition of this event + * @param parentTrace + * Parent trace object + * @param timestamp + * Timestamp of this event + * @param source + * Source of the event + * @param type + * Event type + * @param reference + * Event reference + */ + public CustomEvent(CustomTraceDefinition definition, ITmfTrace parentTrace, + ITmfTimestamp timestamp, String source, TmfEventType type, + String reference) { + /* Do not use upstream's fields for stuff we override */ + super(parentTrace, null, source, null, null, reference); + fDefinition = definition; + fData = new HashMap<>(); + + /* Set our overridden fields */ + customEventTimestamp = timestamp; + customEventContent = null; + customEventType = type; + } + + // ------------------------------------------------------------------------ + // Overridden getters + // ------------------------------------------------------------------------ + + @Override + public ITmfTimestamp getTimestamp() { + if (fData != null) { + processData(); + } + return customEventTimestamp; + } + + @Override + public ITmfEventField getContent() { + return customEventContent; + } + + @Override + public ITmfEventType getType() { + return customEventType; + } + + // ------------------------------------------------------------------------ + // Setters + // ------------------------------------------------------------------------ + + /** + * Set this event's timestamp + * + * @param timestamp + * The new timestamp + */ + protected void setTimestamp(ITmfTimestamp timestamp) { + customEventTimestamp = timestamp; + } + + /** + * Set this event's content + * + * @param content + * The new content + */ + protected void setContent(ITmfEventField content) { + customEventContent = content; + } + + /** + * Set this event's type + * + * @param type + * The new type + */ + protected void setType(ITmfEventType type) { + customEventType = type; + } + + // ------------------------------------------------------------------------ + // Other operations + // ------------------------------------------------------------------------ + + /** + * Get the contents of an event table cell for this event's row. + * + * @param index + * The ID/index of the field to display. This corresponds to the + * index in the event content. + * @return The String to display in the cell + * @since 3.1 + */ + public String getEventString(int index) { + if (fData != null) { + processData(); + } + if (index < 0 || index >= fColumnData.length) { + return ""; //$NON-NLS-1$ + } + + return fColumnData[index].getValue().toString(); + } + + /** + * Get the contents of the row in the events table corresponding to this + * event. The order of the elements corresponds to the order of the columns. + * + * @return The event row entries + * @deprecated This should not be used, since this isn't related to the + * order of columns in the view anymore. You should use + * {@link #getEventString(int)} + */ + @Deprecated + public String[] getEventStrings() { + if (fData != null) { + processData(); + } + String[] entries = new String[fColumnData.length]; + for (int i = 0; i < fColumnData.length; i++) { + entries[i] = fColumnData[i].getValue().toString(); + } + return entries; + } + + private void processData() { + String timestampString = fData.get(CustomTraceDefinition.TAG_TIMESTAMP); + String timestampInputFormat = fData.get(TIMESTAMP_INPUT_FORMAT_KEY); + TmfTimestamp timestamp = null; + if (timestampInputFormat != null && timestampString != null) { + TmfTimestampFormat timestampFormat = new TmfTimestampFormat(timestampInputFormat); + try { + long time = timestampFormat.parseValue(timestampString); + timestamp = new TmfNanoTimestamp(getTrace().getTimestampTransform().transform(time)); + setTimestamp(timestamp); + } catch (ParseException e) { + setTimestamp(TmfTimestamp.ZERO); + } + } else { + setTimestamp(TmfTimestamp.ZERO); + } + + int i = 0; + fColumnData = new TmfEventField[fDefinition.outputs.size()]; + for (OutputColumn outputColumn : fDefinition.outputs) { + String value = fData.get(outputColumn.name); + if (outputColumn.name.equals(CustomTraceDefinition.TAG_TIMESTAMP) && timestamp != null) { + TmfTimestampFormat timestampFormat = new TmfTimestampFormat(fDefinition.timeStampOutputFormat); + fColumnData[i++] = new TmfEventField(outputColumn.name, timestampFormat.format(timestamp.getValue()), null); + } else { + fColumnData[i++] = new TmfEventField(outputColumn.name, (value != null ? value : ""), null); //$NON-NLS-1$ + } + } + CustomEventContent curContent = (CustomEventContent) getContent(); + setContent(new CustomEventContent(curContent.getName(), curContent.getValue(), fColumnData)); + fData = null; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((fDefinition == null) ? 0 : fDefinition.hashCode()); + result = prime * result + ((customEventTimestamp == null) ? 0 : customEventTimestamp.hashCode()); + result = prime * result + ((customEventContent == null) ? 0 : customEventContent.hashCode()); + result = prime * result + ((customEventType == null) ? 0 : customEventType.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof CustomEvent)) { + return false; + } + CustomEvent other = (CustomEvent) obj; + if (fDefinition == null) { + if (other.fDefinition != null) { + return false; + } + } else if (!fDefinition.equals(other.fDefinition)) { + return false; + } + + if (customEventTimestamp == null) { + if (other.customEventTimestamp != null) { + return false; + } + } else if (!customEventTimestamp.equals(other.customEventTimestamp)) { + return false; + } + + if (customEventContent == null) { + if (other.customEventContent != null) { + return false; + } + } else if (!customEventContent.equals(other.customEventContent)) { + return false; + } + + if (customEventType == null) { + if (other.customEventType != null) { + return false; + } + } else if (!customEventType.equals(other.customEventType)) { + return false; + } + + return true; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomEventContent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomEventContent.java new file mode 100644 index 0000000000..7241a8eda2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomEventContent.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tassé - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.parsers.custom; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; + +/** + * Event content for custom text parsers + * + * @author Patrick Tassé + * @since 3.0 + */ +public class CustomEventContent extends TmfEventField { + + /** + * Constructor. + * + * @param parent + * Parent event + * @param content + * Event content + */ + public CustomEventContent(CustomEvent parent, StringBuffer content) { + super(ITmfEventField.ROOT_FIELD_ID, content, null); + } + + /** + * Create a new event field with sub-fields. + * + * @param name + * Field name + * @param content + * Event content + * @param fields + * The array of sub-fields + */ + public CustomEventContent(String name, Object content, ITmfEventField[] fields) { + super(name, content, fields); + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof CustomEventContent)) { + return false; + } + return true; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomEventType.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomEventType.java new file mode 100644 index 0000000000..3416dad98f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomEventType.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tassé - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.parsers.custom; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; + +/** + * Event type for custom text parsers. + * + * @author Patrick Tassé + * @since 3.0 + */ +public abstract class CustomEventType extends TmfEventType { + + private static String CONTEXT_ID = "CustomEventType"; //$NON-NLS-1$ + + /** + * Constructor + * + * @param definition + * Trace definition + */ + public CustomEventType(CustomTraceDefinition definition) { + super(CONTEXT_ID, definition.definitionName, getRootField(definition)); + } + + private static ITmfEventField getRootField(CustomTraceDefinition definition) { + ITmfEventField[] fields = new ITmfEventField[definition.outputs.size()]; + for (int i = 0; i < fields.length; i++) { + fields[i] = new TmfEventField(definition.outputs.get(i).name, null, null); + } + ITmfEventField rootField = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, null, fields); + return rootField; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTraceDefinition.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTraceDefinition.java new file mode 100644 index 0000000000..8e31a77cc4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTraceDefinition.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.parsers.custom; + +import java.io.ByteArrayInputStream; +import java.text.SimpleDateFormat; +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.xml.sax.EntityResolver; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +/** + * Base class for custom trace definitions. + * + * @author Patrick Tassé + * @since 3.0 + */ +public abstract class CustomTraceDefinition { + + /** "set" action */ + public static final int ACTION_SET = 0; + + /** "append" action */ + public static final int ACTION_APPEND = 1; + + /** "append with separator" action */ + public static final int ACTION_APPEND_WITH_SEPARATOR = 2; + + /** Timestamp tag */ + public static final String TAG_TIMESTAMP = Messages.CustomTraceDefinition_timestampTag; + + /** Message tag */ + public static final String TAG_MESSAGE = Messages.CustomTraceDefinition_messageTag; + + /** "Other" tag */ + public static final String TAG_OTHER = Messages.CustomTraceDefinition_otherTag; + + /** Category of this trace definition + * @since 3.2 */ + public String categoryName; + + /** Name of this trace definition */ + public String definitionName; + + /** List of output columns */ + public List outputs; + + /** Timestamp format */ + public String timeStampOutputFormat; + + /** + * Definition of an output column + */ + public static class OutputColumn { + + /** Name of this column */ + public String name; + + /** + * Default constructor (empty) + */ + public OutputColumn() {} + + /** + * Constructor + * + * @param name Name of this output column + */ + public OutputColumn(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } + } + + /** + * Format a timestamp in this trace's current time stamp format. + * + * @param timestamp + * The timestamp to format + * @return The same timestamp as a formatted string + */ + public String formatTimeStamp(TmfTimestamp timestamp) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(timeStampOutputFormat); + return simpleDateFormat.format(timestamp.getValue()); + } + + /** + * Save this custom trace in the default path. + */ + public abstract void save(); + + /** + * Save this custom trace in the supplied path. + * + * @param path + * The path to save to + */ + public abstract void save(String path); + + /** + * Creates a new empty entity resolver + * + * @return a new entity resolver + * @since 3.1 + */ + protected static EntityResolver createEmptyEntityResolver() { + return new EntityResolver() { + @Override + public InputSource resolveEntity(String publicId, String systemId) { + String empty = ""; //$NON-NLS-1$ + ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); + return new InputSource(bais); + } + }; + } + + /** + * Creates an error handler for parse exceptions + * + * @return a new error handler + * @since 3.1 + */ + protected static ErrorHandler createErrorHandler() { + return new ErrorHandler() { + @Override + public void error(SAXParseException saxparseexception) throws SAXException { + } + + @Override + public void warning(SAXParseException saxparseexception) throws SAXException { + } + + @Override + public void fatalError(SAXParseException saxparseexception) throws SAXException { + throw saxparseexception; + } + }; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtEvent.java new file mode 100644 index 0000000000..b58e7d51b6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtEvent.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.parsers.custom; + +import java.util.regex.Matcher; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition.InputData; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition.InputLine; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Trace event for custom text parsers. + * + * @author Patrick Tassé + * @since 3.0 + */ +public class CustomTxtEvent extends CustomEvent { + + /** + * Constructor + * + * @param definition + * Trace definition + */ + public CustomTxtEvent(CustomTxtTraceDefinition definition) { + super(definition); + setType(new CustomTxtEventType(definition)); + } + + /** + * Construct a custom text event from an existing TmfEvent. + * + * @param definition + * Trace definition + * @param other + * The TmfEvent object to copy + */ + public CustomTxtEvent(CustomTxtTraceDefinition definition, TmfEvent other) { + super(definition, other); + } + + /** + * Full constructor. + * + * @param definition + * Trace definition + * @param parentTrace + * Parent trace object + * @param timestamp + * Timestamp of this event + * @param source + * Source of this event + * @param type + * Event type + * @param reference + * Reference if this event + */ + public CustomTxtEvent(CustomTxtTraceDefinition definition, + ITmfTrace parentTrace, ITmfTimestamp timestamp, String source, + TmfEventType type, String reference) { + super(definition, parentTrace, timestamp, source, type, reference); + } + + @Override + public void setContent(ITmfEventField content) { + super.setContent(content); + } + + /** + * Process an entry in the trace file + * + * @param input + * The input line to read + * @param matcher + * The regex matcher to use + */ + public void processGroups(InputLine input, Matcher matcher) { + if (input.columns == null) { + return; + } + for (int i = 0; i < input.columns.size(); i++) { + InputData column = input.columns.get(i); + if (i < matcher.groupCount() && matcher.group(i + 1) != null) { + String value = matcher.group(i + 1).trim(); + if (value.length() == 0) { + continue; + } + String name = column.name; + if (column.action == CustomTraceDefinition.ACTION_SET) { + fData.put(name, value); + if (name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + fData.put(TIMESTAMP_INPUT_FORMAT_KEY, column.format); + } + } else if (column.action == CustomTraceDefinition.ACTION_APPEND) { + String s = fData.get(name); + if (s != null) { + fData.put(name, s + value); + } else { + fData.put(name, value); + } + if (name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + String timeStampInputFormat = fData.get(TIMESTAMP_INPUT_FORMAT_KEY); + if (timeStampInputFormat != null) { + fData.put(TIMESTAMP_INPUT_FORMAT_KEY, timeStampInputFormat + column.format); + } else { + fData.put(TIMESTAMP_INPUT_FORMAT_KEY, column.format); + } + } + } else if (column.action == CustomTraceDefinition.ACTION_APPEND_WITH_SEPARATOR) { + String s = fData.get(name); + if (s != null) { + fData.put(name, s + " | " + value); //$NON-NLS-1$ + } else { + fData.put(name, value); + } + if (name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + String timeStampInputFormat = fData.get(TIMESTAMP_INPUT_FORMAT_KEY); + if (timeStampInputFormat != null) { + fData.put(TIMESTAMP_INPUT_FORMAT_KEY, timeStampInputFormat + " | " + column.format); //$NON-NLS-1$ + } else { + fData.put(TIMESTAMP_INPUT_FORMAT_KEY, column.format); + } + } + } + } + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtEventType.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtEventType.java new file mode 100644 index 0000000000..aebcac7a30 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtEventType.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.parsers.custom; + +/** + * Event type for custom text traces. + * + * @author Patrick Tassé + * @since 3.0 + */ +public class CustomTxtEventType extends CustomEventType { + + /** + * Constructor + * + * @param definition + * Custom text trace definition + */ + public CustomTxtEventType(CustomTxtTraceDefinition definition) { + super(definition); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtTrace.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtTrace.java new file mode 100644 index 0000000000..b31ec1d8e1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtTrace.java @@ -0,0 +1,463 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.parsers.custom; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; +import java.util.regex.Matcher; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.io.BufferedRandomAccessFile; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition.InputLine; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfEventParser; +import org.eclipse.tracecompass.tmf.core.trace.TmfContext; +import org.eclipse.tracecompass.tmf.core.trace.TmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TraceValidationStatus; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfPersistentlyIndexable; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.indexer.TmfBTreeTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; + +/** + * Base class for custom plain text traces. + * + * @author Patrick Tassé + * @since 3.0 + */ +public class CustomTxtTrace extends TmfTrace implements ITmfEventParser, ITmfPersistentlyIndexable { + + private static final TmfLongLocation NULL_LOCATION = new TmfLongLocation(-1L); + private static final int DEFAULT_CACHE_SIZE = 100; + private static final int MAX_LINES = 100; + private static final int MAX_CONFIDENCE = 100; + + private final CustomTxtTraceDefinition fDefinition; + private final CustomTxtEventType fEventType; + private BufferedRandomAccessFile fFile; + + /** + * Basic constructor. + * + * @param definition + * Text trace definition + */ + public CustomTxtTrace(final CustomTxtTraceDefinition definition) { + fDefinition = definition; + fEventType = new CustomTxtEventType(fDefinition); + setCacheSize(DEFAULT_CACHE_SIZE); + } + + /** + * Full constructor. + * + * @param resource + * Trace's resource. + * @param definition + * Text trace definition + * @param path + * Path to the trace file + * @param cacheSize + * Cache size to use + * @throws TmfTraceException + * If we couldn't open the trace at 'path' + */ + public CustomTxtTrace(final IResource resource, + final CustomTxtTraceDefinition definition, final String path, + final int cacheSize) throws TmfTraceException { + this(definition); + setCacheSize((cacheSize > 0) ? cacheSize : DEFAULT_CACHE_SIZE); + initTrace(resource, path, CustomTxtEvent.class); + } + + @Override + public void initTrace(final IResource resource, final String path, final Class eventType) throws TmfTraceException { + super.initTrace(resource, path, eventType); + try { + fFile = new BufferedRandomAccessFile(getPath(), "r"); //$NON-NLS-1$ + } catch (IOException e) { + throw new TmfTraceException(e.getMessage(), e); + } + } + + @Override + public synchronized void dispose() { + super.dispose(); + if (fFile != null) { + try { + fFile.close(); + } catch (IOException e) { + } finally { + fFile = null; + } + } + } + + @Override + public ITmfTraceIndexer getIndexer() { + return super.getIndexer(); + } + + @Override + public synchronized TmfContext seekEvent(final ITmfLocation location) { + final CustomTxtTraceContext context = new CustomTxtTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK); + if (NULL_LOCATION.equals(location) || fFile == null) { + return context; + } + try { + if (location == null) { + fFile.seek(0); + } else if (location.getLocationInfo() instanceof Long) { + fFile.seek((Long) location.getLocationInfo()); + } + long rawPos = fFile.getFilePointer(); + String line = fFile.getNextLine(); + while (line != null) { + for (final InputLine input : getFirstLines()) { + final Matcher matcher = input.getPattern().matcher(line); + if (matcher.matches()) { + context.setLocation(new TmfLongLocation(rawPos)); + context.firstLineMatcher = matcher; + context.firstLine = line; + context.nextLineLocation = fFile.getFilePointer(); + context.inputLine = input; + return context; + } + } + rawPos = fFile.getFilePointer(); + line = fFile.getNextLine(); + } + return context; + } catch (final FileNotFoundException e) { + Activator.logError("Error seeking event. File not found: " + getPath(), e); //$NON-NLS-1$ + return context; + } catch (final IOException e) { + Activator.logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$ + return context; + } + + } + + @Override + public synchronized TmfContext seekEvent(final double ratio) { + if (fFile == null) { + return new CustomTxtTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK); + } + try { + long pos = Math.round(ratio * fFile.length()); + while (pos > 0) { + fFile.seek(pos - 1); + if (fFile.read() == '\n') { + break; + } + pos--; + } + final ITmfLocation location = new TmfLongLocation(pos); + final TmfContext context = seekEvent(location); + context.setRank(ITmfContext.UNKNOWN_RANK); + return context; + } catch (final IOException e) { + Activator.logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$ + return new CustomTxtTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK); + } + } + + @Override + public synchronized double getLocationRatio(final ITmfLocation location) { + if (fFile == null) { + return 0; + } + try { + if (location.getLocationInfo() instanceof Long) { + return ((Long) location.getLocationInfo()).doubleValue() / fFile.length(); + } + } catch (final IOException e) { + Activator.logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$ + } + return 0; + } + + @Override + public ITmfLocation getCurrentLocation() { + // TODO Auto-generated method stub + return null; + } + + @Override + public synchronized CustomTxtEvent parseEvent(final ITmfContext tmfContext) { + ITmfContext context = seekEvent(tmfContext.getLocation()); + return parse(context); + } + + @Override + public synchronized CustomTxtEvent getNext(final ITmfContext context) { + final ITmfContext savedContext = new TmfContext(context.getLocation(), context.getRank()); + final CustomTxtEvent event = parse(context); + if (event != null) { + updateAttributes(savedContext, event.getTimestamp()); + context.increaseRank(); + } + return event; + } + + private synchronized CustomTxtEvent parse(final ITmfContext tmfContext) { + if (fFile == null) { + return null; + } + if (!(tmfContext instanceof CustomTxtTraceContext)) { + return null; + } + + final CustomTxtTraceContext context = (CustomTxtTraceContext) tmfContext; + if (context.getLocation() == null || !(context.getLocation().getLocationInfo() instanceof Long) || NULL_LOCATION.equals(context.getLocation())) { + return null; + } + + CustomTxtEvent event = parseFirstLine(context); + + final HashMap countMap = new HashMap<>(); + InputLine currentInput = null; + if (context.inputLine.childrenInputs != null && context.inputLine.childrenInputs.size() > 0) { + currentInput = context.inputLine.childrenInputs.get(0); + countMap.put(currentInput, 0); + } + + try { + if (fFile.getFilePointer() != context.nextLineLocation) { + fFile.seek(context.nextLineLocation); + } + long rawPos = fFile.getFilePointer(); + String line = fFile.getNextLine(); + while (line != null) { + boolean processed = false; + if (currentInput == null) { + for (final InputLine input : getFirstLines()) { + final Matcher matcher = input.getPattern().matcher(line); + if (matcher.matches()) { + context.setLocation(new TmfLongLocation(rawPos)); + context.firstLineMatcher = matcher; + context.firstLine = line; + context.nextLineLocation = fFile.getFilePointer(); + context.inputLine = input; + return event; + } + } + } else { + if (countMap.get(currentInput) >= currentInput.getMinCount()) { + final List nextInputs = currentInput.getNextInputs(countMap); + if (nextInputs.size() == 0 || nextInputs.get(nextInputs.size() - 1).getMinCount() == 0) { + for (final InputLine input : getFirstLines()) { + final Matcher matcher = input.getPattern().matcher(line); + if (matcher.matches()) { + context.setLocation(new TmfLongLocation(rawPos)); + context.firstLineMatcher = matcher; + context.firstLine = line; + context.nextLineLocation = fFile.getFilePointer(); + context.inputLine = input; + return event; + } + } + } + for (final InputLine input : nextInputs) { + final Matcher matcher = input.getPattern().matcher(line); + if (matcher.matches()) { + event.processGroups(input, matcher); + currentInput = input; + if (countMap.get(currentInput) == null) { + countMap.put(currentInput, 1); + } else { + countMap.put(currentInput, countMap.get(currentInput) + 1); + } + Iterator iter = countMap.keySet().iterator(); + while (iter.hasNext()) { + final InputLine inputLine = iter.next(); + if (inputLine.level > currentInput.level) { + iter.remove(); + } + } + if (currentInput.childrenInputs != null && currentInput.childrenInputs.size() > 0) { + currentInput = currentInput.childrenInputs.get(0); + countMap.put(currentInput, 0); + } else if (countMap.get(currentInput) >= currentInput.getMaxCount()) { + if (currentInput.getNextInputs(countMap).size() > 0) { + currentInput = currentInput.getNextInputs(countMap).get(0); + if (countMap.get(currentInput) == null) { + countMap.put(currentInput, 0); + } + iter = countMap.keySet().iterator(); + while (iter.hasNext()) { + final InputLine inputLine = iter.next(); + if (inputLine.level > currentInput.level) { + iter.remove(); + } + } + } else { + currentInput = null; + } + } + processed = true; + break; + } + } + } + if (!processed && currentInput != null) { + final Matcher matcher = currentInput.getPattern().matcher(line); + if (matcher.matches()) { + event.processGroups(currentInput, matcher); + countMap.put(currentInput, countMap.get(currentInput) + 1); + if (currentInput.childrenInputs != null && currentInput.childrenInputs.size() > 0) { + currentInput = currentInput.childrenInputs.get(0); + countMap.put(currentInput, 0); + } else if (countMap.get(currentInput) >= currentInput.getMaxCount()) { + if (currentInput.getNextInputs(countMap).size() > 0) { + currentInput = currentInput.getNextInputs(countMap).get(0); + if (countMap.get(currentInput) == null) { + countMap.put(currentInput, 0); + } + final Iterator iter = countMap.keySet().iterator(); + while (iter.hasNext()) { + final InputLine inputLine = iter.next(); + if (inputLine.level > currentInput.level) { + iter.remove(); + } + } + } else { + currentInput = null; + } + } + } + ((StringBuffer) event.getContent().getValue()).append("\n").append(line); //$NON-NLS-1$ + } + } + rawPos = fFile.getFilePointer(); + line = fFile.getNextLine(); + } + } catch (final IOException e) { + Activator.logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$ + } + for (final Entry entry : countMap.entrySet()) { + if (entry.getValue() < entry.getKey().getMinCount()) { + event = null; + } + } + context.setLocation(NULL_LOCATION); + return event; + } + + /** + * @return The first few lines of the text file + */ + public List getFirstLines() { + return fDefinition.inputs; + } + + /** + * Parse the first line of the trace (to recognize the type). + * + * @param context + * Trace context + * @return The first event + */ + public CustomTxtEvent parseFirstLine(final CustomTxtTraceContext context) { + final CustomTxtEvent event = new CustomTxtEvent(fDefinition, this, TmfTimestamp.ZERO, "", fEventType, ""); //$NON-NLS-1$ //$NON-NLS-2$ + event.processGroups(context.inputLine, context.firstLineMatcher); + event.setContent(new CustomEventContent(event, new StringBuffer(context.firstLine))); + return event; + } + + /** + * Get the trace definition. + * + * @return The trace definition + */ + public CustomTraceDefinition getDefinition() { + return fDefinition; + } + + /** + * {@inheritDoc} + *

+ * The default implementation computes the confidence as the percentage of + * lines in the first 100 lines of the file which match any of the root + * input line patterns. + */ + @Override + public IStatus validate(IProject project, String path) { + File file = new File(path); + if (!file.exists() || !file.isFile() || !file.canRead()) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CustomTrace_FileNotFound + ": " + path); //$NON-NLS-1$ + } + int confidence = 0; + try (BufferedRandomAccessFile rafile = new BufferedRandomAccessFile(path, "r")) { //$NON-NLS-1$ + int lineCount = 0; + double matches = 0.0; + String line = rafile.getNextLine(); + while ((line != null) && (lineCount++ < MAX_LINES)) { + for (InputLine inputLine : fDefinition.inputs) { + Matcher matcher = inputLine.getPattern().matcher(line); + if (matcher.matches()) { + int groupCount = matcher.groupCount(); + matches += (1.0 + groupCount / ((double) groupCount + 1)); + break; + } + } + confidence = (int) (MAX_CONFIDENCE * matches / lineCount); + line = rafile.getNextLine(); + } + } catch (IOException e) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "IOException validating file: " + path, e); //$NON-NLS-1$ + } + return new TraceValidationStatus(confidence, Activator.PLUGIN_ID); + } + + private static int fCheckpointSize = -1; + + @Override + public synchronized int getCheckpointSize() { + if (fCheckpointSize == -1) { + TmfCheckpoint c = new TmfCheckpoint(TmfTimestamp.ZERO, new TmfLongLocation(0L), 0); + ByteBuffer b = ByteBuffer.allocate(ITmfCheckpoint.MAX_SERIALIZE_SIZE); + b.clear(); + c.serialize(b); + fCheckpointSize = b.position(); + } + + return fCheckpointSize; + } + + @Override + public ITmfLocation restoreLocation(ByteBuffer bufferIn) { + return new TmfLongLocation(bufferIn); + } + + @Override + protected ITmfTraceIndexer createIndexer(int interval) { + return new TmfBTreeTraceIndexer(this, interval); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtTraceContext.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtTraceContext.java new file mode 100644 index 0000000000..e4170ba226 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtTraceContext.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.parsers.custom; + +import java.util.regex.Matcher; + +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition.InputLine; +import org.eclipse.tracecompass.tmf.core.trace.TmfContext; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +/** + * Trace context for custom text traces. + * + * @author Patrick Tassé + * @since 3.0 + */ +public class CustomTxtTraceContext extends TmfContext { + + /** Regex matcher for the first line of the trace */ + public Matcher firstLineMatcher; + + /** First line of the text file */ + public String firstLine; + + /** Position in the file where the 'current' next line is */ + public long nextLineLocation; + + /** InputLine object for the currently read line */ + public InputLine inputLine; + + /** + * Constructor. + * + * @param location + * Location in the trace + * @param rank + * Rank of the event at this location + */ + public CustomTxtTraceContext(ITmfLocation location, long rank) { + super(location, rank); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((firstLine == null) ? 0 : firstLine.hashCode()); + result = prime * result + ((firstLineMatcher == null) ? 0 : firstLineMatcher.hashCode()); + result = prime * result + ((inputLine == null) ? 0 : inputLine.hashCode()); + result = prime * result + (int) (nextLineLocation ^ (nextLineLocation >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof CustomTxtTraceContext)) { + return false; + } + CustomTxtTraceContext other = (CustomTxtTraceContext) obj; + if (firstLine == null) { + if (other.firstLine != null) { + return false; + } + } else if (!firstLine.equals(other.firstLine)) { + return false; + } + if (firstLineMatcher == null) { + if (other.firstLineMatcher != null) { + return false; + } + } else if (!firstLineMatcher.equals(other.firstLineMatcher)) { + return false; + } + if (inputLine == null) { + if (other.inputLine != null) { + return false; + } + } else if (!inputLine.equals(other.inputLine)) { + return false; + } + if (nextLineLocation != other.nextLineLocation) { + return false; + } + return true; + } + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtTraceDefinition.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtTraceDefinition.java new file mode 100644 index 0000000000..1ee3ab17b0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomTxtTraceDefinition.java @@ -0,0 +1,935 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Matthew Khouzam - Add support for default parsers + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.parsers.custom; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +/** + * Trace definition for custom text traces. + * + * @author Patrick Tassé + * @since 3.0 + */ +public class CustomTxtTraceDefinition extends CustomTraceDefinition { + + /** Input lines */ + public List inputs; + + /** File name of the default definition file */ + protected static final String CUSTOM_TXT_TRACE_DEFINITIONS_DEFAULT_FILE_NAME = "custom_txt_default_parsers.xml"; //$NON-NLS-1$ + /** File name of the definition file */ + protected static final String CUSTOM_TXT_TRACE_DEFINITIONS_FILE_NAME = "custom_txt_parsers.xml"; //$NON-NLS-1$ + + /** Path of the definition file */ + protected static final String CUSTOM_TXT_TRACE_DEFINITIONS_DEFAULT_PATH_NAME = + Platform.getInstallLocation().getURL().getPath() + "templates/org.eclipse.linuxtools.tmf.core/" + //$NON-NLS-1$ + CUSTOM_TXT_TRACE_DEFINITIONS_DEFAULT_FILE_NAME; + /** Path of the definition file */ + protected static final String CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME = + Activator.getDefault().getStateLocation().addTrailingSeparator().append(CUSTOM_TXT_TRACE_DEFINITIONS_FILE_NAME).toString(); + + /** + * Legacy path to the XML definitions file (in the UI plug-in) TODO Remove + * once we feel the transition phase is over. + */ + private static final String CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME_LEGACY = + Activator.getDefault().getStateLocation().removeLastSegments(1).addTrailingSeparator() + .append("org.eclipse.linuxtools.tmf.ui") //$NON-NLS-1$ + .append(CUSTOM_TXT_TRACE_DEFINITIONS_FILE_NAME).toString(); + + private static final String CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT = Messages.CustomTxtTraceDefinition_definitionRootElement; + private static final String DEFINITION_ELEMENT = Messages.CustomTxtTraceDefinition_definition; + private static final String CATEGORY_ATTRIBUTE = Messages.CustomTxtTraceDefinition_category; + private static final String NAME_ATTRIBUTE = Messages.CustomTxtTraceDefinition_name; + private static final String TIME_STAMP_OUTPUT_FORMAT_ELEMENT = Messages.CustomTxtTraceDefinition_timestampOutputFormat; + private static final String INPUT_LINE_ELEMENT = Messages.CustomTxtTraceDefinition_inputLine; + private static final String CARDINALITY_ELEMENT = Messages.CustomTxtTraceDefinition_cardinality; + private static final String MIN_ATTRIBUTE = Messages.CustomTxtTraceDefinition_min; + private static final String MAX_ATTRIBUTE = Messages.CustomTxtTraceDefinition_max; + private static final String REGEX_ELEMENT = Messages.CustomTxtTraceDefinition_regEx; + private static final String INPUT_DATA_ELEMENT = Messages.CustomTxtTraceDefinition_inputData; + private static final String ACTION_ATTRIBUTE = Messages.CustomTxtTraceDefinition_action; + private static final String FORMAT_ATTRIBUTE = Messages.CustomTxtTraceDefinition_format; + private static final String OUTPUT_COLUMN_ELEMENT = Messages.CustomTxtTraceDefinition_outputColumn; + + /** + * Default constructor. + */ + public CustomTxtTraceDefinition() { + this(TmfTraceType.CUSTOM_TXT_CATEGORY, "", new ArrayList(0), new ArrayList(0), ""); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * Full constructor. + * + * @param traceType + * Name of the trace type + * @param inputs + * List of inputs + * @param outputs + * List of output columns + * @param timeStampOutputFormat + * The timestamp format to use + * @deprecated Use {@link #CustomTxtTraceDefinition(String, String, List, List, String)} + */ + @Deprecated + public CustomTxtTraceDefinition(String traceType, List inputs, + List outputs, String timeStampOutputFormat) { + this.definitionName = traceType; + this.inputs = inputs; + this.outputs = outputs; + this.timeStampOutputFormat = timeStampOutputFormat; + } + + /** + * Full constructor. + * + * @param category + * Category of the trace type + * @param traceType + * Name of the trace type + * @param inputs + * List of inputs + * @param outputs + * List of output columns + * @param timeStampOutputFormat + * The timestamp format to use + * @since 3.2 + */ + public CustomTxtTraceDefinition(String category, String traceType, List inputs, + List outputs, String timeStampOutputFormat) { + this.categoryName = category; + this.definitionName = traceType; + this.inputs = inputs; + this.outputs = outputs; + this.timeStampOutputFormat = timeStampOutputFormat; + } + + /** + * Wrapper to store a line of the log file + */ + public static class InputLine { + + /** Data columns of this line */ + public List columns; + + /** Cardinality of this line (see {@link Cardinality}) */ + public Cardinality cardinality; + + /** Parent line */ + public InputLine parentInput; + + /** Level of this line */ + public int level; + + /** Next input line in the file */ + public InputLine nextInput; + + /** Children of this line (if one "event" spans many lines) */ + public List childrenInputs; + + private String regex; + private Pattern pattern; + + /** + * Default (empty) constructor. + */ + public InputLine() { + } + + /** + * Constructor. + * + * @param cardinality + * Cardinality of this line. + * @param regex + * Regex + * @param columns + * Columns to use + */ + public InputLine(Cardinality cardinality, String regex, List columns) { + this.cardinality = cardinality; + this.regex = regex; + this.columns = columns; + } + + /** + * Set the regex of this input line + * + * @param regex + * Regex to set + */ + public void setRegex(String regex) { + this.regex = regex; + this.pattern = null; + } + + /** + * Get the current regex + * + * @return The current regex + */ + public String getRegex() { + return regex; + } + + /** + * Get the Pattern object of this line's regex + * + * @return The Pattern + * @throws PatternSyntaxException + * If the regex does not parse correctly + */ + public Pattern getPattern() throws PatternSyntaxException { + if (pattern == null) { + pattern = Pattern.compile(regex); + } + return pattern; + } + + /** + * Add a child line to this line. + * + * @param input + * The child input line + */ + public void addChild(InputLine input) { + if (childrenInputs == null) { + childrenInputs = new ArrayList<>(1); + } else if (childrenInputs.size() > 0) { + InputLine last = childrenInputs.get(childrenInputs.size() - 1); + last.nextInput = input; + } + childrenInputs.add(input); + input.parentInput = this; + input.level = this.level + 1; + } + + /** + * Set the next input line. + * + * @param input + * The next input line + */ + public void addNext(InputLine input) { + if (parentInput != null) { + int index = parentInput.childrenInputs.indexOf(this); + parentInput.childrenInputs.add(index + 1, input); + InputLine next = nextInput; + nextInput = input; + input.nextInput = next; + } + input.parentInput = this.parentInput; + input.level = this.level; + } + + /** + * Move this line up in its parent's children. + */ + public void moveUp() { + if (parentInput != null) { + int index = parentInput.childrenInputs.indexOf(this); + if (index > 0) { + parentInput.childrenInputs.add(index - 1, parentInput.childrenInputs.remove(index)); + parentInput.childrenInputs.get(index).nextInput = nextInput; + nextInput = parentInput.childrenInputs.get(index); + } + } + } + + /** + * Move this line down in its parent's children. + */ + public void moveDown() { + if (parentInput != null) { + int index = parentInput.childrenInputs.indexOf(this); + if (index < parentInput.childrenInputs.size() - 1) { + parentInput.childrenInputs.add(index + 1, parentInput.childrenInputs.remove(index)); + nextInput = parentInput.childrenInputs.get(index).nextInput; + parentInput.childrenInputs.get(index).nextInput = this; + } + } + } + + /** + * Add a data column to this line + * + * @param column + * The column to add + */ + public void addColumn(InputData column) { + if (columns == null) { + columns = new ArrayList<>(1); + } + columns.add(column); + } + + /** + * Get the next input lines. + * + * @param countMap + * The map of line "sets". + * @return The next list of lines. + */ + public List getNextInputs(Map countMap) { + List nextInputs = new ArrayList<>(); + InputLine next = nextInput; + while (next != null) { + nextInputs.add(next); + if (next.cardinality.min > 0) { + return nextInputs; + } + next = next.nextInput; + } + if (parentInput != null && parentInput.level > 0) { + int parentCount = countMap.get(parentInput); + if (parentCount < parentInput.getMaxCount()) { + nextInputs.add(parentInput); + } + if (parentCount < parentInput.getMinCount()) { + return nextInputs; + } + nextInputs.addAll(parentInput.getNextInputs(countMap)); + } + return nextInputs; + } + + /** + * Get the minimum possible amount of entries. + * + * @return The minimum + */ + public int getMinCount() { + return cardinality.min; + } + + /** + * Get the maximum possible amount of entries. + * + * @return The maximum + */ + public int getMaxCount() { + return cardinality.max; + } + + @Override + public String toString() { + return regex + " " + cardinality; //$NON-NLS-1$ + } + } + + /** + * Data column for input lines. + */ + public static class InputData { + + /** Name of this column */ + public String name; + + /** Action id */ + public int action; + + /** Format */ + public String format; + + /** + * Default (empty) constructor + */ + public InputData() { + } + + /** + * Full constructor + * + * @param name + * Name + * @param action + * Action + * @param format + * Format + */ + public InputData(String name, int action, String format) { + this.name = name; + this.action = action; + this.format = format; + } + + /** + * Constructor with default format + * + * @param name + * Name + * @param action + * Action + */ + public InputData(String name, int action) { + this.name = name; + this.action = action; + } + } + + /** + * Input line cardinality + */ + public static class Cardinality { + + /** Representation of infinity */ + public final static int INF = Integer.MAX_VALUE; + + /** Preset for [1, 1] */ + public final static Cardinality ONE = new Cardinality(1, 1); + + /** Preset for [1, inf] */ + public final static Cardinality ONE_OR_MORE = new Cardinality(1, INF); + + /** Preset for [0, 1] */ + public final static Cardinality ZERO_OR_ONE = new Cardinality(0, 1); + + /** Preset for [0, inf] */ + public final static Cardinality ZERO_OR_MORE = new Cardinality(0, INF); + + private final int min; + private final int max; + + /** + * Constructor. + * + * @param min + * Minimum + * @param max + * Maximum + */ + public Cardinality(int min, int max) { + this.min = min; + this.max = max; + } + + @Override + public String toString() { + return "(" + (min >= 0 ? min : "?") + ',' + (max == INF ? "\u221E" : (max >= 0 ? max : "?")) + ')'; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + max; + result = prime * result + min; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof Cardinality)) { + return false; + } + Cardinality other = (Cardinality) obj; + return (this.min == other.min && this.max == other.max); + } + } + + @Override + public void save() { + save(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME); + } + + @Override + public void save(String path) { + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + + // The following allows xml parsing without access to the dtd + db.setEntityResolver(createEmptyEntityResolver()); + + // The following catches xml parsing exceptions + db.setErrorHandler(createErrorHandler()); + + Document doc = null; + File file = new File(path); + if (file.canRead()) { + doc = db.parse(file); + if (!doc.getDocumentElement().getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT)) { + return; + } + } else { + doc = db.newDocument(); + Node node = doc.createElement(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT); + doc.appendChild(node); + } + + Element root = doc.getDocumentElement(); + + Element oldDefinitionElement = findDefinitionElement(root, categoryName, definitionName); + if (oldDefinitionElement != null) { + root.removeChild(oldDefinitionElement); + } + Element definitionElement = doc.createElement(DEFINITION_ELEMENT); + root.appendChild(definitionElement); + definitionElement.setAttribute(CATEGORY_ATTRIBUTE, categoryName); + definitionElement.setAttribute(NAME_ATTRIBUTE, definitionName); + + Element formatElement = doc.createElement(TIME_STAMP_OUTPUT_FORMAT_ELEMENT); + definitionElement.appendChild(formatElement); + formatElement.appendChild(doc.createTextNode(timeStampOutputFormat)); + + if (inputs != null) { + for (InputLine inputLine : inputs) { + definitionElement.appendChild(createInputLineElement(inputLine, doc)); + } + } + + if (outputs != null) { + for (OutputColumn output : outputs) { + Element outputColumnElement = doc.createElement(OUTPUT_COLUMN_ELEMENT); + definitionElement.appendChild(outputColumnElement); + outputColumnElement.setAttribute(NAME_ATTRIBUTE, output.name); + } + } + + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ + + // initialize StreamResult with File object to save to file + StreamResult result = new StreamResult(new StringWriter()); + DOMSource source = new DOMSource(doc); + transformer.transform(source, result); + String xmlString = result.getWriter().toString(); + + try (FileWriter writer = new FileWriter(file);) { + writer.write(xmlString); + } + + TmfTraceType.addCustomTraceType(CustomTxtTrace.class, categoryName, definitionName); + + } catch (ParserConfigurationException e) { + Activator.logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ + } catch (TransformerConfigurationException e) { + Activator.logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ + } catch (TransformerFactoryConfigurationError e) { + Activator.logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ + } catch (TransformerException e) { + Activator.logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ + } catch (IOException e) { + Activator.logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ + } catch (SAXException e) { + Activator.logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ + } + } + + private Element createInputLineElement(InputLine inputLine, Document doc) { + Element inputLineElement = doc.createElement(INPUT_LINE_ELEMENT); + + Element cardinalityElement = doc.createElement(CARDINALITY_ELEMENT); + inputLineElement.appendChild(cardinalityElement); + cardinalityElement.setAttribute(MIN_ATTRIBUTE, Integer.toString(inputLine.cardinality.min)); + cardinalityElement.setAttribute(MAX_ATTRIBUTE, Integer.toString(inputLine.cardinality.max)); + + Element regexElement = doc.createElement(REGEX_ELEMENT); + inputLineElement.appendChild(regexElement); + regexElement.appendChild(doc.createTextNode(inputLine.regex)); + + if (inputLine.columns != null) { + for (InputData inputData : inputLine.columns) { + Element inputDataElement = doc.createElement(INPUT_DATA_ELEMENT); + inputLineElement.appendChild(inputDataElement); + inputDataElement.setAttribute(NAME_ATTRIBUTE, inputData.name); + inputDataElement.setAttribute(ACTION_ATTRIBUTE, Integer.toString(inputData.action)); + if (inputData.format != null) { + inputDataElement.setAttribute(FORMAT_ATTRIBUTE, inputData.format); + } + } + } + + if (inputLine.childrenInputs != null) { + for (InputLine childInputLine : inputLine.childrenInputs) { + inputLineElement.appendChild(createInputLineElement(childInputLine, doc)); + } + } + + return inputLineElement; + } + + /** + * Load all custom text trace definitions, including the user-defined and + * default (built-in) parsers. + * + * @return The loaded trace definitions + */ + public static CustomTxtTraceDefinition[] loadAll() { + return loadAll(true); + } + + /** + * Load all custom text trace definitions, including the user-defined and, + * optionally, the default (built-in) parsers. + * + * @param includeDefaults + * if true, the default (built-in) parsers are included + * + * @return The loaded trace definitions + * @since 3.2 + */ + public static CustomTxtTraceDefinition[] loadAll(boolean includeDefaults) { + File defaultFile = new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME); + File legacyFile = new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME_LEGACY); + + /* + * If there is no file at the expected location, check the legacy + * location instead. + */ + if (!defaultFile.exists() && legacyFile.exists()) { + CustomTxtTraceDefinition[] oldDefs = loadAll(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME_LEGACY); + for (CustomTxtTraceDefinition def : oldDefs) { + /* Save in the new location */ + def.save(); + } + } + + Set defs = new TreeSet<>(new Comparator() { + @Override + public int compare(CustomTxtTraceDefinition o1, CustomTxtTraceDefinition o2) { + int result = o1.categoryName.compareTo(o2.categoryName); + if (result != 0) { + return result; + } + return o1.definitionName.compareTo(o2.definitionName); + } + }); + defs.addAll(Arrays.asList(loadAll(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME))); + if (includeDefaults) { + defs.addAll(Arrays.asList(loadAll(CUSTOM_TXT_TRACE_DEFINITIONS_DEFAULT_PATH_NAME))); + } + return defs.toArray(new CustomTxtTraceDefinition[0]); + + } + + /** + * Load a specific text trace definition file. + * + * @param path + * The path to the file to load + * @return The loaded trace definitions + */ + public static CustomTxtTraceDefinition[] loadAll(String path) { + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + + // The following allows xml parsing without access to the dtd + db.setEntityResolver(createEmptyEntityResolver()); + + // The following catches xml parsing exceptions + db.setErrorHandler(createErrorHandler()); + + File file = new File(path); + if (!file.canRead()) { + return new CustomTxtTraceDefinition[0]; + } + Document doc = db.parse(file); + + Element root = doc.getDocumentElement(); + if (!root.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT)) { + return new CustomTxtTraceDefinition[0]; + } + + ArrayList defList = new ArrayList<>(); + NodeList nodeList = root.getChildNodes(); + for (int i = 0; i < nodeList.getLength(); i++) { + Node node = nodeList.item(i); + if (node instanceof Element && node.getNodeName().equals(DEFINITION_ELEMENT)) { + CustomTxtTraceDefinition def = extractDefinition((Element) node); + if (def != null) { + defList.add(def); + } + } + } + return defList.toArray(new CustomTxtTraceDefinition[0]); + } catch (ParserConfigurationException e) { + Activator.logError("Error loading all in CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ + } catch (SAXException e) { + Activator.logError("Error loading all in CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ + } catch (IOException e) { + Activator.logError("Error loading all in CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$ + } + return new CustomTxtTraceDefinition[0]; + } + + /** + * Load a single definition. + * + * @param definitionName + * Name of the definition to load + * @return The loaded trace definition + * @deprecated Use {@link #load(String, String)} + */ + @Deprecated + public static CustomTxtTraceDefinition load(String definitionName) { + return load(TmfTraceType.CUSTOM_TXT_CATEGORY, definitionName); + } + + /** + * Load a single definition. + * + * @param categoryName + * Category of the definition to load + * @param definitionName + * Name of the definition to load + * @return The loaded trace definition + * @since 3.2 + */ + public static CustomTxtTraceDefinition load(String categoryName, String definitionName) { + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + + // The following allows xml parsing without access to the dtd + db.setEntityResolver(createEmptyEntityResolver()); + + // The following catches xml parsing exceptions + db.setErrorHandler(createErrorHandler()); + + CustomTxtTraceDefinition value = lookupDefinition(categoryName, definitionName, db, CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME); + if (value == null) { + return lookupDefinition(categoryName, definitionName, db, CUSTOM_TXT_TRACE_DEFINITIONS_DEFAULT_PATH_NAME); + } + return value; + } catch (ParserConfigurationException | SAXException | IOException e) { + Activator.logError("Error loading CustomTxtTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ + } + return null; + } + + private static CustomTxtTraceDefinition lookupDefinition(String categoryName, String definitionName, DocumentBuilder db, String source) throws SAXException, IOException { + File file = new File(source); + if (!file.exists()) { + return null; + } + Document doc = db.parse(file); + + Element root = doc.getDocumentElement(); + if (!root.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT)) { + return null; + } + + Element definitionElement = findDefinitionElement(root, categoryName, definitionName); + if (definitionElement != null) { + return extractDefinition(definitionElement); + } + return null; + } + + private static Element findDefinitionElement(Element root, String categoryName, String definitionName) { + NodeList nodeList = root.getChildNodes(); + for (int i = 0; i < nodeList.getLength(); i++) { + Node node = nodeList.item(i); + if (node instanceof Element && node.getNodeName().equals(DEFINITION_ELEMENT)) { + Element element = (Element) node; + String categoryAttribute = element.getAttribute(CATEGORY_ATTRIBUTE); + if (categoryAttribute.isEmpty()) { + categoryAttribute = TmfTraceType.CUSTOM_TXT_CATEGORY; + } + String nameAttribute = element.getAttribute(NAME_ATTRIBUTE); + if (categoryName.equals(categoryAttribute) && + definitionName.equals(nameAttribute)) { + return element; + } + } + } + return null; + } + + /** + * Get the definition from a definition element. + * + * @param definitionElement + * The Element to extract from + * @return The loaded trace definition + */ + public static CustomTxtTraceDefinition extractDefinition(Element definitionElement) { + CustomTxtTraceDefinition def = new CustomTxtTraceDefinition(); + + def.categoryName = definitionElement.getAttribute(CATEGORY_ATTRIBUTE); + if (def.categoryName.isEmpty()) { + def.categoryName = TmfTraceType.CUSTOM_TXT_CATEGORY; + } + def.definitionName = definitionElement.getAttribute(NAME_ATTRIBUTE); + if (def.definitionName.isEmpty()) { + return null; + } + + NodeList nodeList = definitionElement.getChildNodes(); + for (int i = 0; i < nodeList.getLength(); i++) { + Node node = nodeList.item(i); + String nodeName = node.getNodeName(); + if (nodeName.equals(TIME_STAMP_OUTPUT_FORMAT_ELEMENT)) { + Element formatElement = (Element) node; + def.timeStampOutputFormat = formatElement.getTextContent(); + } else if (nodeName.equals(INPUT_LINE_ELEMENT)) { + InputLine inputLine = extractInputLine((Element) node); + if (inputLine != null) { + def.inputs.add(inputLine); + } + } else if (nodeName.equals(OUTPUT_COLUMN_ELEMENT)) { + Element outputColumnElement = (Element) node; + OutputColumn outputColumn = new OutputColumn(); + outputColumn.name = outputColumnElement.getAttribute(NAME_ATTRIBUTE); + def.outputs.add(outputColumn); + } + } + return def; + } + + private static InputLine extractInputLine(Element inputLineElement) { + InputLine inputLine = new InputLine(); + NodeList nodeList = inputLineElement.getChildNodes(); + for (int i = 0; i < nodeList.getLength(); i++) { + Node node = nodeList.item(i); + String nodeName = node.getNodeName(); + if (nodeName.equals(CARDINALITY_ELEMENT)) { + Element cardinalityElement = (Element) node; + try { + int min = Integer.parseInt(cardinalityElement.getAttribute(MIN_ATTRIBUTE)); + int max = Integer.parseInt(cardinalityElement.getAttribute(MAX_ATTRIBUTE)); + inputLine.cardinality = new Cardinality(min, max); + } catch (NumberFormatException e) { + return null; + } + } else if (nodeName.equals(REGEX_ELEMENT)) { + Element regexElement = (Element) node; + inputLine.regex = regexElement.getTextContent(); + } else if (nodeName.equals(INPUT_DATA_ELEMENT)) { + Element inputDataElement = (Element) node; + InputData inputData = new InputData(); + inputData.name = inputDataElement.getAttribute(NAME_ATTRIBUTE); + inputData.action = Integer.parseInt(inputDataElement.getAttribute(ACTION_ATTRIBUTE)); + inputData.format = inputDataElement.getAttribute(FORMAT_ATTRIBUTE); + inputLine.addColumn(inputData); + } else if (nodeName.equals(INPUT_LINE_ELEMENT)) { + Element childInputLineElement = (Element) node; + InputLine childInputLine = extractInputLine(childInputLineElement); + if (childInputLine != null) { + inputLine.addChild(childInputLine); + } + } + } + return inputLine; + } + + /** + * Delete a definition from the currently loaded ones. + * + * @param definitionName + * The name of the definition to delete + * @deprecated Use {@link #delete(String, String)} + */ + @Deprecated + public static void delete(String definitionName) { + delete(TmfTraceType.CUSTOM_TXT_CATEGORY, definitionName); + } + + /** + * Delete a definition from the currently loaded ones. + * + * @param categoryName + * The category of the definition to delete + * @param definitionName + * The name of the definition to delete + * @since 3.2 + */ + public static void delete(String categoryName, String definitionName) { + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + + // The following allows xml parsing without access to the dtd + db.setEntityResolver(createEmptyEntityResolver()); + + // The following catches xml parsing exceptions + db.setErrorHandler(createErrorHandler()); + + File file = new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME); + Document doc = db.parse(file); + + Element root = doc.getDocumentElement(); + if (!root.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT)) { + return; + } + + Element definitionElement = findDefinitionElement(root, categoryName, definitionName); + if (definitionElement != null) { + root.removeChild(definitionElement); + } + + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ + + // initialize StreamResult with File object to save to file + StreamResult result = new StreamResult(new StringWriter()); + DOMSource source = new DOMSource(doc); + transformer.transform(source, result); + String xmlString = result.getWriter().toString(); + + try (FileWriter writer = new FileWriter(file);) { + writer.write(xmlString); + } + + TmfTraceType.removeCustomTraceType(CustomTxtTrace.class, categoryName, definitionName); + // Check if default definition needs to be reloaded + TmfTraceType.addCustomTraceType(CustomTxtTrace.class, categoryName, definitionName); + + } catch (ParserConfigurationException | SAXException | IOException | TransformerFactoryConfigurationError | TransformerException e) { + Activator.logError("Error deleting CustomTxtTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlEvent.java new file mode 100644 index 0000000000..92faa7f498 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlEvent.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.parsers.custom; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Trace event for custom XML traces. + * + * @author Patrick Tassé + * @since 3.0 + */ +public class CustomXmlEvent extends CustomEvent { + + /** + * Constructor defining only the trace definition + * + * @param definition + * Trace definition + */ + public CustomXmlEvent(CustomXmlTraceDefinition definition) { + super(definition); + setType(new CustomXmlEventType(definition)); + } + + /** + * Build a custom trace event from an existing TmfEvent. + * + * @param definition + * Trace definition + * @param other + * Other TmfEvent to copy + */ + public CustomXmlEvent(CustomXmlTraceDefinition definition, TmfEvent other) { + super(definition, other); + } + + /** + * Full constructor + * + * @param definition + * Trace definition + * @param parentTrace + * Parent trace object + * @param timestamp + * Timestamp of the event + * @param source + * Source of the event + * @param type + * Event type + * @param reference + * Reference of the event + */ + public CustomXmlEvent(CustomXmlTraceDefinition definition, ITmfTrace parentTrace, ITmfTimestamp timestamp, String source, TmfEventType type, String reference) { + super(definition, parentTrace, timestamp, source, type, reference); + } + + @Override + public void setContent(ITmfEventField content) { + super.setContent(content); + } + + /** + * Parse an entry. + * + * @param value Value + * @param name Name + * @param inputAction Input action + * @param inputFormat Input format + */ + public void parseInput(String value, String name, int inputAction, String inputFormat) { + if (value.length() == 0) { + return; + } + if (inputAction == CustomTraceDefinition.ACTION_SET) { + fData.put(name, value); + if (name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + fData.put(TIMESTAMP_INPUT_FORMAT_KEY, inputFormat); + } + } else if (inputAction == CustomTraceDefinition.ACTION_APPEND) { + String s = fData.get(name); + if (s != null) { + fData.put(name, s + value); + } else { + fData.put(name, value); + } + if (name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + String timeStampInputFormat = fData.get(TIMESTAMP_INPUT_FORMAT_KEY); + if (timeStampInputFormat != null) { + fData.put(TIMESTAMP_INPUT_FORMAT_KEY, timeStampInputFormat + inputFormat); + } else { + fData.put(TIMESTAMP_INPUT_FORMAT_KEY, inputFormat); + } + } + } else if (inputAction == CustomTraceDefinition.ACTION_APPEND_WITH_SEPARATOR) { + String s = fData.get(name); + if (s != null) { + fData.put(name, s + " | " + value); //$NON-NLS-1$ + } else { + fData.put(name, value); + } + if (name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + String timeStampInputFormat = fData.get(TIMESTAMP_INPUT_FORMAT_KEY); + if (timeStampInputFormat != null) { + fData.put(TIMESTAMP_INPUT_FORMAT_KEY, timeStampInputFormat + " | " + inputFormat); //$NON-NLS-1$ + } else { + fData.put(TIMESTAMP_INPUT_FORMAT_KEY, inputFormat); + } + } + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlEventType.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlEventType.java new file mode 100644 index 0000000000..4aea345c99 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlEventType.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.parsers.custom; + +/** + * Event type class for custom XML traces. + * + * @author Patrick Tassé + * @since 3.0 + */ +public class CustomXmlEventType extends CustomEventType { + + /** + * Constructor + * + * @param definition + * Trace definition + */ + public CustomXmlEventType(CustomXmlTraceDefinition definition) { + super(definition); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlTrace.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlTrace.java new file mode 100644 index 0000000000..fba0bfb4ed --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlTrace.java @@ -0,0 +1,585 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.parsers.custom; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.io.BufferedRandomAccessFile; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition.InputAttribute; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition.InputElement; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfEventParser; +import org.eclipse.tracecompass.tmf.core.trace.TmfContext; +import org.eclipse.tracecompass.tmf.core.trace.TmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TraceValidationStatus; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfPersistentlyIndexable; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.indexer.TmfBTreeTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.EntityResolver; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +/** + * Trace object for custom XML trace parsers. + * + * @author Patrick Tassé + * @since 3.0 + */ +public class CustomXmlTrace extends TmfTrace implements ITmfEventParser, ITmfPersistentlyIndexable { + + private static final TmfLongLocation NULL_LOCATION = new TmfLongLocation(-1L); + private static final int DEFAULT_CACHE_SIZE = 100; + private static final int MAX_LINES = 100; + private static final int CONFIDENCE = 100; + + private final CustomXmlTraceDefinition fDefinition; + private final CustomXmlEventType fEventType; + private final InputElement fRecordInputElement; + private BufferedRandomAccessFile fFile; + + /** + * Basic constructor + * + * @param definition + * Trace definition + */ + public CustomXmlTrace(final CustomXmlTraceDefinition definition) { + fDefinition = definition; + fEventType = new CustomXmlEventType(fDefinition); + fRecordInputElement = getRecordInputElement(fDefinition.rootInputElement); + setCacheSize(DEFAULT_CACHE_SIZE); + } + + /** + * Full constructor + * + * @param resource + * Trace resource + * @param definition + * Trace definition + * @param path + * Path to the trace/log file + * @param pageSize + * Page size to use + * @throws TmfTraceException + * If the trace/log couldn't be opened + */ + public CustomXmlTrace(final IResource resource, + final CustomXmlTraceDefinition definition, final String path, + final int pageSize) throws TmfTraceException { + this(definition); + setCacheSize((pageSize > 0) ? pageSize : DEFAULT_CACHE_SIZE); + initTrace(resource, path, CustomXmlEvent.class); + } + + @Override + public void initTrace(final IResource resource, final String path, final Class eventType) throws TmfTraceException { + super.initTrace(resource, path, eventType); + try { + fFile = new BufferedRandomAccessFile(getPath(), "r"); //$NON-NLS-1$ + } catch (IOException e) { + throw new TmfTraceException(e.getMessage(), e); + } + } + + @Override + public synchronized void dispose() { + super.dispose(); + if (fFile != null) { + try { + fFile.close(); + } catch (IOException e) { + } finally { + fFile = null; + } + } + } + + @Override + public ITmfTraceIndexer getIndexer() { + return super.getIndexer(); + } + + @Override + public synchronized TmfContext seekEvent(final ITmfLocation location) { + final CustomXmlTraceContext context = new CustomXmlTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK); + if (NULL_LOCATION.equals(location) || fFile == null) { + return context; + } + try { + if (location == null) { + fFile.seek(0); + } else if (location.getLocationInfo() instanceof Long) { + fFile.seek((Long) location.getLocationInfo()); + } + long rawPos = fFile.getFilePointer(); + String line = fFile.getNextLine(); + while (line != null) { + final int idx = indexOfElement(fRecordInputElement.elementName, line, 0); + if (idx != -1) { + context.setLocation(new TmfLongLocation(rawPos + idx)); + return context; + } + rawPos = fFile.getFilePointer(); + line = fFile.getNextLine(); + } + return context; + } catch (final IOException e) { + Activator.logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$ + return context; + } + + } + + @Override + public synchronized TmfContext seekEvent(final double ratio) { + if (fFile == null) { + return new CustomTxtTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK); + } + try { + long pos = Math.round(ratio * fFile.length()); + while (pos > 0) { + fFile.seek(pos - 1); + if (fFile.read() == '\n') { + break; + } + pos--; + } + final ITmfLocation location = new TmfLongLocation(pos); + final TmfContext context = seekEvent(location); + context.setRank(ITmfContext.UNKNOWN_RANK); + return context; + } catch (final IOException e) { + Activator.logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$ + return new CustomXmlTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK); + } + } + + @Override + public synchronized double getLocationRatio(final ITmfLocation location) { + if (fFile == null) { + return 0; + } + try { + if (location.getLocationInfo() instanceof Long) { + return ((Long) location.getLocationInfo()).doubleValue() / fFile.length(); + } + } catch (final IOException e) { + Activator.logError("Error getting location ration. File: " + getPath(), e); //$NON-NLS-1$ + } + return 0; + } + + @Override + public ITmfLocation getCurrentLocation() { + // TODO Auto-generated method stub + return null; + } + + @Override + public synchronized CustomXmlEvent parseEvent(final ITmfContext tmfContext) { + ITmfContext context = seekEvent(tmfContext.getLocation()); + return parse(context); + } + + @Override + public synchronized CustomXmlEvent getNext(final ITmfContext context) { + final ITmfContext savedContext = new TmfContext(context.getLocation(), context.getRank()); + final CustomXmlEvent event = parse(context); + if (event != null) { + updateAttributes(savedContext, event.getTimestamp()); + context.increaseRank(); + } + return event; + } + + private synchronized CustomXmlEvent parse(final ITmfContext tmfContext) { + if (fFile == null) { + return null; + } + if (!(tmfContext instanceof CustomXmlTraceContext)) { + return null; + } + + final CustomXmlTraceContext context = (CustomXmlTraceContext) tmfContext; + if (context.getLocation() == null || !(context.getLocation().getLocationInfo() instanceof Long) || NULL_LOCATION.equals(context.getLocation())) { + return null; + } + + CustomXmlEvent event = null; + try { + if (fFile.getFilePointer() != (Long) context.getLocation().getLocationInfo() + 1) + { + fFile.seek((Long) context.getLocation().getLocationInfo() + 1); // +1 is for the < + } + final StringBuffer elementBuffer = new StringBuffer("<"); //$NON-NLS-1$ + readElement(elementBuffer, fFile); + final Element element = parseElementBuffer(elementBuffer); + + event = extractEvent(element, fRecordInputElement); + ((StringBuffer) event.getContent().getValue()).append(elementBuffer); + + long rawPos = fFile.getFilePointer(); + String line = fFile.getNextLine(); + while (line != null) { + final int idx = indexOfElement(fRecordInputElement.elementName, line, 0); + if (idx != -1) { + context.setLocation(new TmfLongLocation(rawPos + idx)); + return event; + } + rawPos = fFile.getFilePointer(); + line = fFile.getNextLine(); + } + } catch (final IOException e) { + Activator.logError("Error parsing event. File: " + getPath(), e); //$NON-NLS-1$ + + } + context.setLocation(NULL_LOCATION); + return event; + } + + private Element parseElementBuffer(final StringBuffer elementBuffer) { + try { + final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + final DocumentBuilder db = dbf.newDocumentBuilder(); + + // The following allows xml parsing without access to the dtd + final EntityResolver resolver = new EntityResolver() { + @Override + public InputSource resolveEntity(final String publicId, final String systemId) { + final String empty = ""; //$NON-NLS-1$ + final ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); + return new InputSource(bais); + } + }; + db.setEntityResolver(resolver); + + // The following catches xml parsing exceptions + db.setErrorHandler(new ErrorHandler() { + @Override + public void error(final SAXParseException saxparseexception) throws SAXException {} + + @Override + public void warning(final SAXParseException saxparseexception) throws SAXException {} + + @Override + public void fatalError(final SAXParseException saxparseexception) throws SAXException { + throw saxparseexception; + } + }); + + final Document doc = db.parse(new ByteArrayInputStream(elementBuffer.toString().getBytes())); + return doc.getDocumentElement(); + } catch (final ParserConfigurationException e) { + Activator.logError("Error parsing element buffer. File:" + getPath(), e); //$NON-NLS-1$ + } catch (final SAXException e) { + Activator.logError("Error parsing element buffer. File:" + getPath(), e); //$NON-NLS-1$ + } catch (final IOException e) { + Activator.logError("Error parsing element buffer. File: " + getPath(), e); //$NON-NLS-1$ + } + return null; + } + + private static int indexOfElement(String elementName, String line, int fromIndex) { + final String recordElementStart = '<' + elementName; + int index = line.indexOf(recordElementStart, fromIndex); + if (index == -1) { + return index; + } + int nextCharIndex = index + recordElementStart.length(); + if (nextCharIndex < line.length()) { + char c = line.charAt(nextCharIndex); + // Check that the match is not just a substring of another element + if (Character.isLetterOrDigit(c)) { + return indexOfElement(elementName, line, nextCharIndex); + } + } + return index; + } + + private void readElement(final StringBuffer buffer, final RandomAccessFile raFile) { + try { + int numRead = 0; + boolean startTagClosed = false; + int i; + while ((i = raFile.read()) != -1) { + numRead++; + final char c = (char) i; + buffer.append(c); + if (c == '"') { + readQuote(buffer, raFile, '"'); + } else if (c == '\'') { + readQuote(buffer, raFile, '\''); + } else if (c == '<') { + readElement(buffer, raFile); + } else if (c == '/' && numRead == 1) { + break; // found "') { + if (buffer.charAt(buffer.length() - 2) == '/') { + break; // found "/>" + } else if (startTagClosed) { + break; // found "<...>..." + } + else { + startTagClosed = true; // found "<...>" + } + } + } + return; + } catch (final IOException e) { + return; + } + } + + private static void readQuote(final StringBuffer buffer, + final RandomAccessFile raFile, final char eq) { + try { + int i; + while ((i = raFile.read()) != -1) { + final char c = (char) i; + buffer.append(c); + if (c == eq) + { + break; // found matching end-quote + } + } + return; + } catch (final IOException e) { + return; + } + } + + private static void readComment(final StringBuffer buffer, + final RandomAccessFile raFile) { + try { + int numRead = 0; + int i; + while ((i = raFile.read()) != -1) { + numRead++; + final char c = (char) i; + buffer.append(c); + if (c == '>' && numRead >= 2 && buffer.substring(buffer.length() - 3, buffer.length() - 1).equals("--")) //$NON-NLS-1$ + { + break; // found "-->" + } + } + return; + } catch (final IOException e) { + return; + } + } + + /** + * Parse an XML element. + * + * @param parentElement + * The parent element + * @param buffer + * The contents to parse + * @return The parsed content + */ + public static StringBuffer parseElement(final Element parentElement, final StringBuffer buffer) { + final NodeList nodeList = parentElement.getChildNodes(); + String separator = null; + for (int i = 0; i < nodeList.getLength(); i++) { + final Node node = nodeList.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) { + if (separator == null) { + separator = " | "; //$NON-NLS-1$ + } else { + buffer.append(separator); + } + final Element element = (Element) node; + if (!element.hasChildNodes()) { + buffer.append(element.getNodeName()); + } else if (element.getChildNodes().getLength() == 1 && element.getFirstChild().getNodeType() == Node.TEXT_NODE) { + buffer.append(element.getNodeName() + ":" + element.getFirstChild().getNodeValue().trim()); //$NON-NLS-1$ + } else { + buffer.append(element.getNodeName()); + buffer.append(" [ "); //$NON-NLS-1$ + parseElement(element, buffer); + buffer.append(" ]"); //$NON-NLS-1$ + } + } else if (node.getNodeType() == Node.TEXT_NODE) { + if (node.getNodeValue().trim().length() != 0) { + buffer.append(node.getNodeValue().trim()); + } + } + } + return buffer; + } + + /** + * Get an input element if it is a valid record input. If not, we will look + * into its children for valid inputs. + * + * @param inputElement + * The main element to check for. + * @return The record element + */ + public InputElement getRecordInputElement(final InputElement inputElement) { + if (inputElement.logEntry) { + return inputElement; + } else if (inputElement.childElements != null) { + for (final InputElement childInputElement : inputElement.childElements) { + final InputElement recordInputElement = getRecordInputElement(childInputElement); + if (recordInputElement != null) { + return recordInputElement; + } + } + } + return null; + } + + /** + * Extract a trace event from an XML element. + * + * @param element + * The element + * @param inputElement + * The input element + * @return The extracted event + */ + public CustomXmlEvent extractEvent(final Element element, final InputElement inputElement) { + final CustomXmlEvent event = new CustomXmlEvent(fDefinition, this, TmfTimestamp.ZERO, "", fEventType, ""); //$NON-NLS-1$ //$NON-NLS-2$ + event.setContent(new CustomEventContent(event, new StringBuffer())); + parseElement(element, event, inputElement); + return event; + } + + private void parseElement(final Element element, final CustomXmlEvent event, final InputElement inputElement) { + if (inputElement.inputName != null && !inputElement.inputName.equals(CustomXmlTraceDefinition.TAG_IGNORE)) { + event.parseInput(parseElement(element, new StringBuffer()).toString(), inputElement.inputName, inputElement.inputAction, inputElement.inputFormat); + } + if (inputElement.attributes != null) { + for (final InputAttribute attribute : inputElement.attributes) { + event.parseInput(element.getAttribute(attribute.attributeName), attribute.inputName, attribute.inputAction, attribute.inputFormat); + } + } + final NodeList childNodes = element.getChildNodes(); + if (inputElement.childElements != null) { + for (int i = 0; i < childNodes.getLength(); i++) { + final Node node = childNodes.item(i); + if (node instanceof Element) { + for (final InputElement child : inputElement.childElements) { + if (node.getNodeName().equals(child.elementName)) { + parseElement((Element) node, event, child); + break; + } + } + } + } + } + return; + } + + /** + * Retrieve the trace definition. + * + * @return The trace definition + */ + public CustomTraceDefinition getDefinition() { + return fDefinition; + } + + /** + * {@inheritDoc} + *

+ * The default implementation sets the confidence to 100 if any of the first + * 100 lines of the file contains a valid record input element, and 0 + * otherwise. + */ + @Override + public IStatus validate(IProject project, String path) { + File file = new File(path); + if (!file.exists() || !file.isFile() || !file.canRead()) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CustomTrace_FileNotFound + ": " + path); //$NON-NLS-1$ + } + try (BufferedRandomAccessFile rafile = new BufferedRandomAccessFile(path, "r")) { //$NON-NLS-1$ + int lineCount = 0; + long rawPos = 0; + String line = rafile.getNextLine(); + while ((line != null) && (lineCount++ < MAX_LINES)) { + final int idx = indexOfElement(fRecordInputElement.elementName, line, 0); + if (idx != -1) { + rafile.seek(rawPos + idx + 1); // +1 is for the < + final StringBuffer elementBuffer = new StringBuffer("<"); //$NON-NLS-1$ + readElement(elementBuffer, rafile); + final Element element = parseElementBuffer(elementBuffer); + if (element != null) { + rafile.close(); + return new TraceValidationStatus(CONFIDENCE, Activator.PLUGIN_ID); + } + } + rawPos = rafile.getFilePointer(); + line = rafile.getNextLine(); + } + } catch (IOException e) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "IOException validating file: " + path, e); //$NON-NLS-1$ + } + return new TraceValidationStatus(0, Activator.PLUGIN_ID); + } + + private static int fCheckpointSize = -1; + + @Override + public synchronized int getCheckpointSize() { + if (fCheckpointSize == -1) { + TmfCheckpoint c = new TmfCheckpoint(TmfTimestamp.ZERO, new TmfLongLocation(0L), 0); + ByteBuffer b = ByteBuffer.allocate(ITmfCheckpoint.MAX_SERIALIZE_SIZE); + b.clear(); + c.serialize(b); + fCheckpointSize = b.position(); + } + + return fCheckpointSize; + } + + @Override + public ITmfLocation restoreLocation(ByteBuffer bufferIn) { + return new TmfLongLocation(bufferIn); + } + + @Override + protected ITmfTraceIndexer createIndexer(int interval) { + return new TmfBTreeTraceIndexer(this, interval); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlTraceContext.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlTraceContext.java new file mode 100644 index 0000000000..0cdefe59eb --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlTraceContext.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.parsers.custom; + +import org.eclipse.tracecompass.tmf.core.trace.TmfContext; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +/** + * Trace context for custom XML traces. + * + * @author Patrick Tassé + * @since 3.0 + */ +public class CustomXmlTraceContext extends TmfContext { + + /** + * Constructor + * + * @param location + * The location (in the file) of this context + * @param rank + * The rank of the event pointed by this context + */ + public CustomXmlTraceContext(ITmfLocation location, long rank) { + super(location, rank); + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof CustomXmlTraceContext)) { + return false; + } + return true; + } + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlTraceDefinition.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlTraceDefinition.java new file mode 100644 index 0000000000..2efd8e491f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/CustomXmlTraceDefinition.java @@ -0,0 +1,858 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Matthew Khouzam - Add support for default xml parsers + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.parsers.custom; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.EntityResolver; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +/** + * Trace definition for custom XML traces. + * + * @author Patrick Tassé + * @since 3.0 + */ +public class CustomXmlTraceDefinition extends CustomTraceDefinition { + + /** "ignore" tag */ + public static final String TAG_IGNORE = Messages.CustomXmlTraceDefinition_ignoreTag; + + /** Name of the default XML definitions file */ + protected static final String CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_FILE_NAME = "custom_xml_default_parsers.xml"; //$NON-NLS-1$ + + /** Name of the XML definitions file */ + protected static final String CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME = "custom_xml_parsers.xml"; //$NON-NLS-1$ + + /** Path to the XML definitions file */ + protected static final String CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME = + Platform.getInstallLocation().getURL().getPath() + "templates/org.eclipse.linuxtools.tmf.core/" + //$NON-NLS-1$ + CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_FILE_NAME; + + /** Path to the XML definitions file */ + protected static final String CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME = + Activator.getDefault().getStateLocation().addTrailingSeparator().append(CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME).toString(); + + /** + * Legacy path to the XML definitions file (in the UI plug-in) TODO Remove + * once we feel the transition phase is over. + */ + private static final String CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY = + Activator.getDefault().getStateLocation().removeLastSegments(1).addTrailingSeparator() + .append("org.eclipse.linuxtools.tmf.ui") //$NON-NLS-1$ + .append(CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME).toString(); + + // TODO: These strings should not be externalized + private static final String CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT = Messages.CustomXmlTraceDefinition_definitionRootElement; + private static final String DEFINITION_ELEMENT = Messages.CustomXmlTraceDefinition_definition; + private static final String CATEGORY_ATTRIBUTE = Messages.CustomXmlTraceDefinition_category; + private static final String NAME_ATTRIBUTE = Messages.CustomXmlTraceDefinition_name; + private static final String LOG_ENTRY_ATTRIBUTE = Messages.CustomXmlTraceDefinition_logEntry; + private static final String TIME_STAMP_OUTPUT_FORMAT_ELEMENT = Messages.CustomXmlTraceDefinition_timestampOutputFormat; + private static final String INPUT_ELEMENT_ELEMENT = Messages.CustomXmlTraceDefinition_inputElement; + private static final String ATTRIBUTE_ELEMENT = Messages.CustomXmlTraceDefinition_attribute; + private static final String INPUT_DATA_ELEMENT = Messages.CustomXmlTraceDefinition_inputData; + private static final String ACTION_ATTRIBUTE = Messages.CustomXmlTraceDefinition_action; + private static final String FORMAT_ATTRIBUTE = Messages.CustomXmlTraceDefinition_format; + private static final String OUTPUT_COLUMN_ELEMENT = Messages.CustomXmlTraceDefinition_outputColumn; + + /** Top-level input element */ + public InputElement rootInputElement; + + /** + * Default constructor + */ + public CustomXmlTraceDefinition() { + this(TmfTraceType.CUSTOM_XML_CATEGORY, "", null, new ArrayList(), ""); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * Full constructor + * + * @param traceType + * Name of the trace type + * @param rootElement + * The top-level XML element + * @param outputs + * The list of output columns + * @param timeStampOutputFormat + * The timestamp format to use + * @deprecated Use {@link #CustomXmlTraceDefinition(String, String, InputElement, List, String)} + */ + @Deprecated + public CustomXmlTraceDefinition(String traceType, InputElement rootElement, + List outputs, String timeStampOutputFormat) { + this.definitionName = traceType; + this.rootInputElement = rootElement; + this.outputs = outputs; + this.timeStampOutputFormat = timeStampOutputFormat; + } + + /** + * Full constructor + * + * @param category + * Category of the trace type + * @param traceType + * Name of the trace type + * @param rootElement + * The top-level XML element + * @param outputs + * The list of output columns + * @param timeStampOutputFormat + * The timestamp format to use + * @since 3.2 + */ + public CustomXmlTraceDefinition(String category, String traceType, InputElement rootElement, + List outputs, String timeStampOutputFormat) { + this.categoryName = category; + this.definitionName = traceType; + this.rootInputElement = rootElement; + this.outputs = outputs; + this.timeStampOutputFormat = timeStampOutputFormat; + } + + /** + * Wrapper for input XML elements + */ + public static class InputElement { + + /** Name of the element */ + public String elementName; + + /** Indicates if this is a log entry */ + public boolean logEntry; + + /** Name of the input element */ + public String inputName; + + /** Input action */ + public int inputAction; + + /** Input format */ + public String inputFormat; + + /** XML attributes of this element */ + public List attributes; + + /** Parent element */ + public InputElement parentElement; + + /** Following element in the file */ + public InputElement nextElement; + + /** Child elements */ + public List childElements; + + /** + * Default (empty) constructor + */ + public InputElement() { + } + + /** + * Constructor + * + * @param elementName + * Element name + * @param logEntry + * If this element is a log entry + * @param inputName + * Name of the the input + * @param inputAction + * Input action + * @param inputFormat + * Input format + * @param attributes + * XML attributes of this element + */ + public InputElement(String elementName, boolean logEntry, + String inputName, int inputAction, String inputFormat, + List attributes) { + this.elementName = elementName; + this.logEntry = logEntry; + this.inputName = inputName; + this.inputAction = inputAction; + this.inputFormat = inputFormat; + this.attributes = attributes; + } + + /** + * Add a XML attribute to the element + * + * @param attribute + * The attribute to add + */ + public void addAttribute(InputAttribute attribute) { + if (attributes == null) { + attributes = new ArrayList<>(1); + } + attributes.add(attribute); + } + + /** + * Add a child element to this one. + * + * @param input + * The input element to add as child + */ + public void addChild(InputElement input) { + if (childElements == null) { + childElements = new ArrayList<>(1); + } else if (childElements.size() > 0) { + InputElement last = childElements.get(childElements.size() - 1); + last.nextElement = input; + } + childElements.add(input); + input.parentElement = this; + } + + /** + * Set the following input element. + * + * @param input + * The input element to add as next element + */ + public void addNext(InputElement input) { + if (parentElement != null) { + int index = parentElement.childElements.indexOf(this); + parentElement.childElements.add(index + 1, input); + InputElement next = nextElement; + nextElement = input; + input.nextElement = next; + } + input.parentElement = this.parentElement; + } + + /** + * Move this element up in its parent's list of children. + */ + public void moveUp() { + if (parentElement != null) { + int index = parentElement.childElements.indexOf(this); + if (index > 0) { + parentElement.childElements.add(index - 1, parentElement.childElements.remove(index)); + parentElement.childElements.get(index).nextElement = nextElement; + nextElement = parentElement.childElements.get(index); + } + } + } + + /** + * Move this element down in its parent's list of children. + */ + public void moveDown() { + if (parentElement != null) { + int index = parentElement.childElements.indexOf(this); + if (index < parentElement.childElements.size() - 1) { + parentElement.childElements.add(index + 1, parentElement.childElements.remove(index)); + nextElement = parentElement.childElements.get(index).nextElement; + parentElement.childElements.get(index).nextElement = this; + } + } + } + + } + + /** + * Wrapper for XML element attributes + */ + public static class InputAttribute { + + /** Name of the XML attribute */ + public String attributeName; + + /** Input name */ + public String inputName; + + /** Input action */ + public int inputAction; + + /** Input format */ + public String inputFormat; + + /** + * Default (empty) constructor + */ + public InputAttribute() { + } + + /** + * Constructor + * + * @param attributeName + * Name of the XML attribute + * @param inputName + * Input name + * @param inputAction + * Input action + * @param inputFormat + * Input format + */ + public InputAttribute(String attributeName, String inputName, + int inputAction, String inputFormat) { + this.attributeName = attributeName; + this.inputName = inputName; + this.inputAction = inputAction; + this.inputFormat = inputFormat; + } + } + + @Override + public void save() { + save(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME); + } + + @Override + public void save(String path) { + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + + // The following allows xml parsing without access to the dtd + db.setEntityResolver(createEmptyEntityResolver()); + + // The following catches xml parsing exceptions + db.setErrorHandler(createErrorHandler()); + + Document doc = null; + File file = new File(path); + if (file.canRead()) { + doc = db.parse(file); + if (!doc.getDocumentElement().getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) { + return; + } + } else { + doc = db.newDocument(); + Node node = doc.createElement(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT); + doc.appendChild(node); + } + + Element root = doc.getDocumentElement(); + + Element oldDefinitionElement = findDefinitionElement(root, categoryName, definitionName); + if (oldDefinitionElement != null) { + root.removeChild(oldDefinitionElement); + } + Element definitionElement = doc.createElement(DEFINITION_ELEMENT); + root.appendChild(definitionElement); + definitionElement.setAttribute(CATEGORY_ATTRIBUTE, categoryName); + definitionElement.setAttribute(NAME_ATTRIBUTE, definitionName); + + Element formatElement = doc.createElement(TIME_STAMP_OUTPUT_FORMAT_ELEMENT); + definitionElement.appendChild(formatElement); + formatElement.appendChild(doc.createTextNode(timeStampOutputFormat)); + + if (rootInputElement != null) { + definitionElement.appendChild(createInputElementElement(rootInputElement, doc)); + } + + if (outputs != null) { + for (OutputColumn output : outputs) { + Element outputColumnElement = doc.createElement(OUTPUT_COLUMN_ELEMENT); + definitionElement.appendChild(outputColumnElement); + outputColumnElement.setAttribute(NAME_ATTRIBUTE, output.name); + } + } + + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ + + // initialize StreamResult with File object to save to file + StreamResult result = new StreamResult(new StringWriter()); + DOMSource source = new DOMSource(doc); + transformer.transform(source, result); + String xmlString = result.getWriter().toString(); + + try (FileWriter writer = new FileWriter(file);) { + writer.write(xmlString); + } + + TmfTraceType.addCustomTraceType(CustomXmlTrace.class, categoryName, definitionName); + + } catch (ParserConfigurationException | TransformerFactoryConfigurationError | TransformerException | IOException | SAXException e) { + Activator.logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$ + } + } + + private Element createInputElementElement(InputElement inputElement, Document doc) { + Element inputElementElement = doc.createElement(INPUT_ELEMENT_ELEMENT); + inputElementElement.setAttribute(NAME_ATTRIBUTE, inputElement.elementName); + + if (inputElement.logEntry) { + inputElementElement.setAttribute(LOG_ENTRY_ATTRIBUTE, Boolean.toString(inputElement.logEntry)); + } + + if (inputElement.parentElement != null) { + Element inputDataElement = doc.createElement(INPUT_DATA_ELEMENT); + inputElementElement.appendChild(inputDataElement); + inputDataElement.setAttribute(NAME_ATTRIBUTE, inputElement.inputName); + inputDataElement.setAttribute(ACTION_ATTRIBUTE, Integer.toString(inputElement.inputAction)); + if (inputElement.inputFormat != null) { + inputDataElement.setAttribute(FORMAT_ATTRIBUTE, inputElement.inputFormat); + } + } + + if (inputElement.attributes != null) { + for (InputAttribute attribute : inputElement.attributes) { + Element inputAttributeElement = doc.createElement(ATTRIBUTE_ELEMENT); + inputElementElement.appendChild(inputAttributeElement); + inputAttributeElement.setAttribute(NAME_ATTRIBUTE, attribute.attributeName); + Element inputDataElement = doc.createElement(INPUT_DATA_ELEMENT); + inputAttributeElement.appendChild(inputDataElement); + inputDataElement.setAttribute(NAME_ATTRIBUTE, attribute.inputName); + inputDataElement.setAttribute(ACTION_ATTRIBUTE, Integer.toString(attribute.inputAction)); + if (attribute.inputFormat != null) { + inputDataElement.setAttribute(FORMAT_ATTRIBUTE, attribute.inputFormat); + } + } + } + + if (inputElement.childElements != null) { + for (InputElement childInputElement : inputElement.childElements) { + inputElementElement.appendChild(createInputElementElement(childInputElement, doc)); + } + } + + return inputElementElement; + } + + /** + * Load all custom XML trace definitions, including the user-defined and + * default (built-in) parsers. + * + * @return The loaded trace definitions + */ + public static CustomXmlTraceDefinition[] loadAll() { + return loadAll(true); + } + + /** + * Load all custom XML trace definitions, including the user-defined and, + * optionally, the default (built-in) parsers. + * + * @param includeDefaults + * if true, the default (built-in) parsers are included + * + * @return The loaded trace definitions + * @since 3.2 + */ + public static CustomXmlTraceDefinition[] loadAll(boolean includeDefaults) { + File defaultFile = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME); + File legacyFile = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY); + + /* + * If there is no file at the expected location, check the legacy + * location instead. + */ + if (!defaultFile.exists() && legacyFile.exists()) { + CustomXmlTraceDefinition[] oldDefs = loadAll(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY); + for (CustomXmlTraceDefinition def : oldDefs) { + /* Save in the new location */ + def.save(); + } + } + + Set defs = new TreeSet<>(new Comparator() { + @Override + public int compare(CustomXmlTraceDefinition o1, CustomXmlTraceDefinition o2) { + int result = o1.categoryName.compareTo(o2.categoryName); + if (result != 0) { + return result; + } + return o1.definitionName.compareTo(o2.definitionName); + } + }); + defs.addAll(Arrays.asList(loadAll(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME))); + if (includeDefaults) { + defs.addAll(Arrays.asList(loadAll(CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME))); + } + return defs.toArray(new CustomXmlTraceDefinition[0]); + } + + /** + * Load all the XML trace definitions in the given definitions file. + * + * @param path + * Path to the definitions file to load + * @return The loaded trace definitions + */ + public static CustomXmlTraceDefinition[] loadAll(String path) { + File file = new File(path); + if (!file.canRead()) { + return new CustomXmlTraceDefinition[0]; + } + try (FileInputStream fis = new FileInputStream(file);) { + return loadAll(fis); + } catch (IOException e) { + Activator.logError("Error loading all in CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$ + } + return new CustomXmlTraceDefinition[0]; + } + + /** + * Load all the XML trace definitions from the given stream + * + * @param stream + * An input stream from which to read the definitions + * @return The loaded trace definitions + * @since 3.2 + */ + public static CustomXmlTraceDefinition[] loadAll(InputStream stream) { + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + + // The following allows xml parsing without access to the dtd + db.setEntityResolver(createEmptyEntityResolver()); + + // The following catches xml parsing exceptions + db.setErrorHandler(createErrorHandler()); + + Document doc = db.parse(stream); + Element root = doc.getDocumentElement(); + if (!root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) { + return new CustomXmlTraceDefinition[0]; + } + + ArrayList defList = new ArrayList<>(); + NodeList nodeList = root.getChildNodes(); + for (int i = 0; i < nodeList.getLength(); i++) { + Node node = nodeList.item(i); + if (node instanceof Element && node.getNodeName().equals(DEFINITION_ELEMENT)) { + CustomXmlTraceDefinition def = extractDefinition((Element) node); + if (def != null) { + defList.add(def); + } + } + } + return defList.toArray(new CustomXmlTraceDefinition[0]); + } catch (ParserConfigurationException | SAXException | IOException e) { + Activator.logError("Error loading all in CustomXmlTraceDefinition: path=" + stream, e); //$NON-NLS-1$ + } + return new CustomXmlTraceDefinition[0]; + } + + /** + * Load the given trace definition. + * + * @param definitionName + * Name of the XML trace definition to load + * @return The loaded trace definition + * @deprecated Use {@link #load(String, String)} + */ + @Deprecated + public static CustomXmlTraceDefinition load(String definitionName) { + return load(TmfTraceType.CUSTOM_XML_CATEGORY, definitionName); + } + + /** + * Load the given trace definition. + * + * @param categoryName + * Category of the definition to load + * @param definitionName + * Name of the XML trace definition to load + * @return The loaded trace definition + * @since 3.2 + */ + public static CustomXmlTraceDefinition load(String categoryName, String definitionName) { + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + + // The following allows xml parsing without access to the dtd + EntityResolver resolver = new EntityResolver() { + @Override + public InputSource resolveEntity(String publicId, String systemId) { + String empty = ""; //$NON-NLS-1$ + ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); + return new InputSource(bais); + } + }; + db.setEntityResolver(resolver); + + // The following catches xml parsing exceptions + db.setErrorHandler(new ErrorHandler() { + @Override + public void error(SAXParseException saxparseexception) throws SAXException { + } + + @Override + public void warning(SAXParseException saxparseexception) throws SAXException { + } + + @Override + public void fatalError(SAXParseException saxparseexception) throws SAXException { + throw saxparseexception; + } + }); + + CustomXmlTraceDefinition value = lookupXmlDefinition(categoryName, definitionName, db, CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME); + if (value == null) { + value = lookupXmlDefinition(categoryName, definitionName, db, CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME); + } + return value; + } catch (ParserConfigurationException | SAXException | IOException e) { + Activator.logError("Error loading CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ + } + return null; + } + + private static CustomXmlTraceDefinition lookupXmlDefinition(String categoryName, String definitionName, DocumentBuilder db, String source) throws SAXException, IOException { + File file = new File(source); + if (!file.exists()) { + return null; + } + + Document doc = db.parse(file); + + Element root = doc.getDocumentElement(); + if (!root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) { + return null; + } + + Element definitionElement = findDefinitionElement(root, categoryName, definitionName); + if (definitionElement != null) { + return extractDefinition(definitionElement); + } + return null; + } + + private static Element findDefinitionElement(Element root, String categoryName, String definitionName) { + NodeList nodeList = root.getChildNodes(); + for (int i = 0; i < nodeList.getLength(); i++) { + Node node = nodeList.item(i); + if (node instanceof Element && node.getNodeName().equals(DEFINITION_ELEMENT)) { + Element element = (Element) node; + String categoryAttribute = element.getAttribute(CATEGORY_ATTRIBUTE); + if (categoryAttribute.isEmpty()) { + categoryAttribute = TmfTraceType.CUSTOM_XML_CATEGORY; + } + String nameAttribute = element.getAttribute(NAME_ATTRIBUTE); + if (categoryName.equals(categoryAttribute) && + definitionName.equals(nameAttribute)) { + return element; + } + } + } + return null; + } + + /** + * Extract a trace definition from an XML element. + * + * @param definitionElement + * Definition element + * @return The extracted trace definition + */ + public static CustomXmlTraceDefinition extractDefinition(Element definitionElement) { + CustomXmlTraceDefinition def = new CustomXmlTraceDefinition(); + + def.categoryName = definitionElement.getAttribute(CATEGORY_ATTRIBUTE); + if (def.categoryName.isEmpty()) { + def.categoryName = TmfTraceType.CUSTOM_XML_CATEGORY; + } + def.definitionName = definitionElement.getAttribute(NAME_ATTRIBUTE); + if (def.definitionName.isEmpty()) { + return null; + } + + NodeList nodeList = definitionElement.getChildNodes(); + for (int i = 0; i < nodeList.getLength(); i++) { + Node node = nodeList.item(i); + String nodeName = node.getNodeName(); + if (nodeName.equals(TIME_STAMP_OUTPUT_FORMAT_ELEMENT)) { + Element formatElement = (Element) node; + def.timeStampOutputFormat = formatElement.getTextContent(); + } else if (nodeName.equals(INPUT_ELEMENT_ELEMENT)) { + InputElement inputElement = extractInputElement((Element) node); + if (inputElement != null) { + if (def.rootInputElement == null) { + def.rootInputElement = inputElement; + } else { + return null; + } + } + } else if (nodeName.equals(OUTPUT_COLUMN_ELEMENT)) { + Element outputColumnElement = (Element) node; + OutputColumn outputColumn = new OutputColumn(); + outputColumn.name = outputColumnElement.getAttribute(NAME_ATTRIBUTE); + def.outputs.add(outputColumn); + } + } + return def; + } + + private static InputElement extractInputElement(Element inputElementElement) { + InputElement inputElement = new InputElement(); + inputElement.elementName = inputElementElement.getAttribute(NAME_ATTRIBUTE); + inputElement.logEntry = (Boolean.toString(true).equals(inputElementElement.getAttribute(LOG_ENTRY_ATTRIBUTE))) ? true : false; + NodeList nodeList = inputElementElement.getChildNodes(); + for (int i = 0; i < nodeList.getLength(); i++) { + Node node = nodeList.item(i); + String nodeName = node.getNodeName(); + if (nodeName.equals(INPUT_DATA_ELEMENT)) { + Element inputDataElement = (Element) node; + inputElement.inputName = inputDataElement.getAttribute(NAME_ATTRIBUTE); + inputElement.inputAction = Integer.parseInt(inputDataElement.getAttribute(ACTION_ATTRIBUTE)); + inputElement.inputFormat = inputDataElement.getAttribute(FORMAT_ATTRIBUTE); + } else if (nodeName.equals(ATTRIBUTE_ELEMENT)) { + Element attributeElement = (Element) node; + InputAttribute attribute = new InputAttribute(); + attribute.attributeName = attributeElement.getAttribute(NAME_ATTRIBUTE); + NodeList attributeNodeList = attributeElement.getChildNodes(); + for (int j = 0; j < attributeNodeList.getLength(); j++) { + Node attributeNode = attributeNodeList.item(j); + String attributeNodeName = attributeNode.getNodeName(); + if (attributeNodeName.equals(INPUT_DATA_ELEMENT)) { + Element inputDataElement = (Element) attributeNode; + attribute.inputName = inputDataElement.getAttribute(NAME_ATTRIBUTE); + attribute.inputAction = Integer.parseInt(inputDataElement.getAttribute(ACTION_ATTRIBUTE)); + attribute.inputFormat = inputDataElement.getAttribute(FORMAT_ATTRIBUTE); + } + } + inputElement.addAttribute(attribute); + } else if (nodeName.equals(INPUT_ELEMENT_ELEMENT)) { + Element childInputElementElement = (Element) node; + InputElement childInputElement = extractInputElement(childInputElementElement); + if (childInputElement != null) { + inputElement.addChild(childInputElement); + } + } + } + return inputElement; + } + + /** + * Delete a definition from the currently loaded ones. + * + * @param definitionName + * The name of the definition to delete + * @deprecated Use {@link #delete(String, String)} + */ + @Deprecated + public static void delete(String definitionName) { + delete(TmfTraceType.CUSTOM_XML_CATEGORY, definitionName); + } + + /** + * Delete a definition from the currently loaded ones. + * + * @param categoryName + * The category of the definition to delete + * @param definitionName + * The name of the definition to delete + * @since 3.2 + */ + public static void delete(String categoryName, String definitionName) { + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + + // The following allows xml parsing without access to the dtd + EntityResolver resolver = new EntityResolver() { + @Override + public InputSource resolveEntity(String publicId, String systemId) { + String empty = ""; //$NON-NLS-1$ + ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); + return new InputSource(bais); + } + }; + db.setEntityResolver(resolver); + + // The following catches xml parsing exceptions + db.setErrorHandler(new ErrorHandler() { + @Override + public void error(SAXParseException saxparseexception) throws SAXException { + } + + @Override + public void warning(SAXParseException saxparseexception) throws SAXException { + } + + @Override + public void fatalError(SAXParseException saxparseexception) throws SAXException { + throw saxparseexception; + } + }); + + File file = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME); + Document doc = db.parse(file); + + Element root = doc.getDocumentElement(); + if (!root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) { + return; + } + + Element definitionElement = findDefinitionElement(root, categoryName, definitionName); + if (definitionElement != null) { + root.removeChild(definitionElement); + } + + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ + + // initialize StreamResult with File object to save to file + StreamResult result = new StreamResult(new StringWriter()); + DOMSource source = new DOMSource(doc); + transformer.transform(source, result); + String xmlString = result.getWriter().toString(); + + try (FileWriter writer = new FileWriter(file);) { + writer.write(xmlString); + } + + TmfTraceType.removeCustomTraceType(CustomXmlTrace.class, categoryName, definitionName); + // Check if default definition needs to be reloaded + TmfTraceType.addCustomTraceType(CustomXmlTrace.class, categoryName, definitionName); + + } catch (ParserConfigurationException | SAXException | IOException | TransformerFactoryConfigurationError | TransformerException e) { + Activator.logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/Messages.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/Messages.java new file mode 100644 index 0000000000..c74fc1c0a2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/Messages.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.parsers.custom; + +import org.eclipse.osgi.util.NLS; + +/** + * @since 3.0 + */ +@SuppressWarnings("javadoc") +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.core.parsers.custom.messages"; //$NON-NLS-1$ + + public static String CustomTrace_FileNotFound; + + // TODO: These strings should not be externalized + public static String CustomTraceDefinition_messageTag; + public static String CustomTraceDefinition_otherTag; + public static String CustomTraceDefinition_timestampTag; + public static String CustomTxtTraceDefinition_action; + public static String CustomTxtTraceDefinition_cardinality; + /** @since 3.2*/ + public static String CustomTxtTraceDefinition_category; + public static String CustomTxtTraceDefinition_definition; + public static String CustomTxtTraceDefinition_definitionRootElement; + public static String CustomTxtTraceDefinition_format; + public static String CustomTxtTraceDefinition_inputData; + public static String CustomTxtTraceDefinition_inputLine; + public static String CustomTxtTraceDefinition_max; + public static String CustomTxtTraceDefinition_min; + public static String CustomTxtTraceDefinition_name; + public static String CustomTxtTraceDefinition_outputColumn; + public static String CustomTxtTraceDefinition_regEx; + public static String CustomTxtTraceDefinition_timestampOutputFormat; + public static String CustomXmlTraceDefinition_action; + public static String CustomXmlTraceDefinition_attribute; + /** @since 3.2*/ + public static String CustomXmlTraceDefinition_category; + public static String CustomXmlTraceDefinition_definition; + public static String CustomXmlTraceDefinition_definitionRootElement; + public static String CustomXmlTraceDefinition_format; + public static String CustomXmlTraceDefinition_ignoreTag; + public static String CustomXmlTraceDefinition_inputData; + public static String CustomXmlTraceDefinition_inputElement; + public static String CustomXmlTraceDefinition_logEntry; + public static String CustomXmlTraceDefinition_name; + public static String CustomXmlTraceDefinition_outputColumn; + public static String CustomXmlTraceDefinition_timestampOutputFormat; + + static { + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/messages.properties b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/messages.properties new file mode 100644 index 0000000000..5f12afdde8 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/parsers/custom/messages.properties @@ -0,0 +1,44 @@ +############################################################################### +# Copyright (c) 2013, 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### + +CustomTrace_FileNotFound=File not found + +CustomTraceDefinition_messageTag=Message +CustomTraceDefinition_otherTag=Other +CustomTraceDefinition_timestampTag=Time Stamp +CustomTxtTraceDefinition_action=action +CustomTxtTraceDefinition_cardinality=Cardinality +CustomTxtTraceDefinition_category=category +CustomTxtTraceDefinition_definition=Definition +CustomTxtTraceDefinition_definitionRootElement=CustomTxtTraceDefinitionList +CustomTxtTraceDefinition_format=format +CustomTxtTraceDefinition_inputData=InputData +CustomTxtTraceDefinition_inputLine=InputLine +CustomTxtTraceDefinition_max=max +CustomTxtTraceDefinition_min=min +CustomTxtTraceDefinition_name=name +CustomTxtTraceDefinition_outputColumn=OutputColumn +CustomTxtTraceDefinition_regEx=RegEx +CustomTxtTraceDefinition_timestampOutputFormat=TimeStampOutputFormat +CustomXmlTraceDefinition_action=action +CustomXmlTraceDefinition_attribute=Attribute +CustomXmlTraceDefinition_category=category +CustomXmlTraceDefinition_definition=Definition +CustomXmlTraceDefinition_definitionRootElement=CustomXMLTraceDefinitionList +CustomXmlTraceDefinition_format=format +CustomXmlTraceDefinition_ignoreTag=Ignore +CustomXmlTraceDefinition_inputData=InputData +CustomXmlTraceDefinition_inputElement=InputElement +CustomXmlTraceDefinition_logEntry=logentry +CustomXmlTraceDefinition_name=name +CustomXmlTraceDefinition_outputColumn=OutputColumn +CustomXmlTraceDefinition_timestampOutputFormat=TimeStampOutputFormat diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/project/model/TmfTraceImportException.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/project/model/TmfTraceImportException.java new file mode 100644 index 0000000000..db42df0eaa --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/project/model/TmfTraceImportException.java @@ -0,0 +1,45 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.core.project.model; + +/** + * Tmf trace import exception + * + * @author Matthew Khouzam + * @since 3.0 + */ +public class TmfTraceImportException extends Exception { + + private static final long serialVersionUID = -6902068313782751330L; + + /** + * Constructs a new TmfTraceImportException with null as its + * detail message. The cause is not initialized, and may subsequently be + * initialized by a call to {@link #initCause}. + */ + public TmfTraceImportException() { + } + + /** + * Constructs a new exception with the specified detail message. The cause + * is not initialized, and may subsequently be initialized by a call to + * {@link #initCause}. + * + * @param message + * the detail message. The detail message is saved for later + * retrieval by the {@link #getMessage()} method. + */ + public TmfTraceImportException(String message) { + super(message); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/project/model/TmfTraceType.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/project/model/TmfTraceType.java new file mode 100644 index 0000000000..14bfd1056b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/project/model/TmfTraceType.java @@ -0,0 +1,691 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Matthew Khouzam - Added import functionalities + * Geneviève Bastien - Added support for experiment types + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.project.model; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.Platform; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTrace; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTrace; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Utility class for accessing TMF trace type extensions from the platform's + * extensions registry. + * + * @version 1.0 + * @author Patrick Tasse + * @author Matthew Khouzam + * @since 3.0 + */ +public final class TmfTraceType { + + // ------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------ + + private static final char SEPARATOR = ':'; + + /** Extension point ID */ + public static final String TMF_TRACE_TYPE_ID = "org.eclipse.linuxtools.tmf.core.tracetype"; //$NON-NLS-1$ + + /** Extension point element 'Category' */ + public static final String CATEGORY_ELEM = "category"; //$NON-NLS-1$ + + /** Extension point element 'Type' */ + public static final String TYPE_ELEM = "type"; //$NON-NLS-1$ + + /** Extension point element 'Experiment' */ + public static final String EXPERIMENT_ELEM = "experiment"; //$NON-NLS-1$ + + /** Extension point attribute 'ID' */ + public static final String ID_ATTR = "id"; //$NON-NLS-1$ + + /** Extension point attribute 'name' */ + public static final String NAME_ATTR = "name"; //$NON-NLS-1$ + + /** Extension point attribute 'category' */ + public static final String CATEGORY_ATTR = "category"; //$NON-NLS-1$ + + /** Extension point attribute 'trace_type' */ + public static final String TRACE_TYPE_ATTR = "trace_type"; //$NON-NLS-1$ + + /** Extension point attribute 'event_type' */ + public static final String EVENT_TYPE_ATTR = "event_type"; //$NON-NLS-1$ + + /** Extension point attribute 'experiment_type' */ + public static final String EXPERIMENT_TYPE_ATTR = "experiment_type"; //$NON-NLS-1$ + + /** Extension point attribute 'isDirectory' */ + public static final String IS_DIR_ATTR = "isDirectory"; //$NON-NLS-1$ + + /** + * Custom text label used internally and therefore should not be + * externalized + */ + public static final String CUSTOM_TXT_CATEGORY = "Custom Text"; //$NON-NLS-1$ + + /** + * Custom XML label used internally and therefore should not be externalized + */ + public static final String CUSTOM_XML_CATEGORY = "Custom XML"; //$NON-NLS-1$ + + /** Default experiment type */ + public static final String DEFAULT_EXPERIMENT_TYPE = "org.eclipse.linuxtools.tmf.core.experiment.generic"; //$NON-NLS-1$ + + // The mapping of available trace type IDs to their corresponding + // configuration element + private static final Map TRACE_TYPE_ATTRIBUTES = new HashMap<>(); + private static final Map TRACE_CATEGORIES = new HashMap<>(); + private static final Map TRACE_TYPES = new LinkedHashMap<>(); + + static { + populateCategoriesAndTraceTypes(); + populateCustomTraceTypes(); + } + + /** + * Enum to say whether a type applies to a trace or experiment + * + * @author Geneviève Bastien + */ + public enum TraceElementType { + /** Trace type applies to trace */ + TRACE, + /** Trace type applies to experiment */ + EXPERIMENT, + } + + // ------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------ + + private TmfTraceType() { + } + + // ------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------ + + /** + * Retrieves the category name from the platform extension registry based on + * the category ID + * + * @param categoryId + * The category ID + * @return the category name or empty string if not found + */ + public static String getCategoryName(String categoryId) { + IConfigurationElement[] elements = Platform.getExtensionRegistry() + .getConfigurationElementsFor(TMF_TRACE_TYPE_ID); + for (IConfigurationElement element : elements) { + if (element.getName().equals(CATEGORY_ELEM) && element.getAttribute(ID_ATTR).equals(categoryId)) { + return element.getAttribute(NAME_ATTR); + } + } + return ""; //$NON-NLS-1$ + } + + /** + * Retrieves all configuration elements from the platform extension registry + * for the trace type extension that apply to traces and not experiments. + * + * @return an array of trace type configuration elements + */ + public static IConfigurationElement[] getTypeElements() { + IConfigurationElement[] elements = Platform.getExtensionRegistry() + .getConfigurationElementsFor(TMF_TRACE_TYPE_ID); + List typeElements = new LinkedList<>(); + for (IConfigurationElement element : elements) { + if (element.getName().equals(TYPE_ELEM)) { + typeElements.add(element); + } + } + return typeElements.toArray(new IConfigurationElement[typeElements.size()]); + } + + /** + * Retrieve the TraceTypeHelper for a given trace type ID + * + * @param id + * The trace type ID + * @return The corresponding TraceTypeHelper, or null if there is none for + * the specified ID + * @deprecated Use {@link #getTraceType(String)} + */ + @Deprecated + public static TraceTypeHelper getTraceTypeHelper(String id) { + return TRACE_TYPES.get(id); + } + + /** + * Get an iterable view of the existing trace type IDs. + * + * @return The currently registered trace type IDs + */ + public static Iterable getTraceTypeIDs() { + return TRACE_TYPES.keySet(); + } + + /** + * Get an iterable view of the existing trace type helpers. + * + * @return The currently registered trace type helpers + */ + public static Iterable getTraceTypeHelpers() { + return TRACE_TYPES.values(); + } + + /** + * Returns a list of "category:tracetype , ..." + * + * Returns only trace types, not experiment types + * + * @return returns a list of "category:tracetype , ..." + */ + public static String[] getAvailableTraceTypes() { + return getAvailableTraceTypes(null); + } + + /** + * Returns a list of "category:tracetype , ..." sorted by given comparator. + * + * Returns only trace types, not experiment types + * + * @param comparator + * Comparator class (type String) or null for alphabetical order. + * @return sorted list according to the given comparator + */ + public static String[] getAvailableTraceTypes(Comparator comparator) { + + // Generate the list of Category:TraceType to populate the ComboBox + List traceTypes = new ArrayList<>(); + + for (String key : TRACE_TYPES.keySet()) { + TraceTypeHelper tt = TRACE_TYPES.get(key); + if (!tt.isExperimentType()) { + traceTypes.add(tt.getCategoryName() + SEPARATOR + tt.getName()); + } + } + + if (comparator == null) { + Collections.sort(traceTypes); + } else { + Collections.sort(traceTypes, comparator); + } + + // Format result + return traceTypes.toArray(new String[traceTypes.size()]); + } + + /** + * Gets the custom trace types (custom text and friends) + * + * @param type + * the type to get (Text, xml or other...) + * @return the list of custom trace types + */ + public static List getCustomTraceTypes(String type) { + List traceTypes = new ArrayList<>(); + if (type.equals(CUSTOM_TXT_CATEGORY)) { + for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) { + String traceTypeName = def.definitionName; + traceTypes.add(traceTypeName); + } + } + if (type.equals(CUSTOM_XML_CATEGORY)) { + for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { + String traceTypeName = def.definitionName; + traceTypes.add(traceTypeName); + } + } + return traceTypes; + } + + /** + * Gets all the custom trace types + * + * @return the list of custom trace types + */ + public static List getCustomTraceTypes() { + + List traceTypes = new ArrayList<>(); + for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) { + String traceTypeName = def.definitionName; + traceTypes.add(traceTypeName); + } + for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { + String traceTypeName = def.definitionName; + traceTypes.add(traceTypeName); + } + return traceTypes; + } + + private static void populateCustomTraceTypes() { + // add the custom trace types + for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) { + String traceTypeId = CustomTxtTrace.class.getCanonicalName() + SEPARATOR + def.categoryName + SEPARATOR + def.definitionName; + ITmfTrace trace = new CustomTxtTrace(def); + TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, def.categoryName, def.definitionName, trace, false, TraceElementType.TRACE); + TRACE_TYPES.put(traceTypeId, tt); + // Deregister trace as signal handler because it is only used for validation + TmfSignalManager.deregister(trace); + } + for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { + String traceTypeId = CustomXmlTrace.class.getCanonicalName() + SEPARATOR + def.categoryName + SEPARATOR + def.definitionName; + ITmfTrace trace = new CustomXmlTrace(def); + TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, def.categoryName, def.definitionName, trace, false, TraceElementType.TRACE); + TRACE_TYPES.put(traceTypeId, tt); + // Deregister trace as signal handler because it is only used for validation + TmfSignalManager.deregister(trace); + } + } + + /** + * Add or replace a custom trace type + * + * @param category + * The custom parser category + * @param definitionName + * The custom parser definition name to add or replace + * @deprecated Use {@link #addCustomTraceType(Class, String, String)} + */ + @Deprecated + public static void addCustomTraceType(String category, String definitionName) { + if (category.equals(CUSTOM_TXT_CATEGORY)) { + addCustomTraceType(CustomTxtTrace.class, category, definitionName); + } else if (category.equals(CUSTOM_XML_CATEGORY)) { + addCustomTraceType(CustomXmlTrace.class, category, definitionName); + } + } + + /** + * Add or replace a custom trace type + * + * @param traceClass + * The custom trace class, either {@link CustomTxtTrace} or + * {@link CustomXmlTrace} + * @param category + * The custom parser category + * @param definitionName + * The custom parser definition name to add or replace + */ + public static void addCustomTraceType(Class traceClass, String category, String definitionName) { + String traceTypeId = null; + ITmfTrace trace = null; + + if (traceClass.equals(CustomTxtTrace.class)) { + traceTypeId = CustomTxtTrace.class.getCanonicalName() + SEPARATOR + category + SEPARATOR + definitionName; + CustomTxtTraceDefinition def = CustomTxtTraceDefinition.load(category, definitionName); + if (def != null) { + trace = new CustomTxtTrace(def); + } + } else if (traceClass.equals(CustomXmlTrace.class)) { + traceTypeId = CustomXmlTrace.class.getCanonicalName() + SEPARATOR + category + SEPARATOR + definitionName; + CustomXmlTraceDefinition def = CustomXmlTraceDefinition.load(category, definitionName); + if (def != null) { + trace = new CustomXmlTrace(def); + } + } + + if (traceTypeId != null && trace != null) { + TraceTypeHelper helper = TRACE_TYPES.get(traceTypeId); + if (helper != null) { + helper.getTrace().dispose(); + } + TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, category, definitionName, trace, false, TraceElementType.TRACE); + TRACE_TYPES.put(traceTypeId, tt); + // Deregister trace as signal handler because it is only used for validation + TmfSignalManager.deregister(trace); + } + } + + /** + * Remove a custom trace type + * + * @param category + * The custom parser category + * @param definitionName + * The custom parser definition name to add or replace + * @deprecated Use {@link #removeCustomTraceType(Class, String, String)} + */ + @Deprecated + public static void removeCustomTraceType(String category, String definitionName) { + if (category.equals(CUSTOM_TXT_CATEGORY)) { + removeCustomTraceType(CustomTxtTrace.class, category, definitionName); + } else if (category.equals(CUSTOM_XML_CATEGORY)) { + removeCustomTraceType(CustomXmlTrace.class, category, definitionName); + } + } + + /** + * Remove a custom trace type + * + * @param traceClass + * The custom trace class, either {@link CustomTxtTrace} or + * {@link CustomXmlTrace} + * @param category + * The custom parser category + * @param definitionName + * The custom parser definition name to add or replace + */ + public static void removeCustomTraceType(Class traceClass, String category, String definitionName) { + String traceTypeId = traceClass.getCanonicalName() + SEPARATOR + category + SEPARATOR + definitionName; + TraceTypeHelper helper = TRACE_TYPES.remove(traceTypeId); + if (helper != null) { + helper.getTrace().dispose(); + } + } + + /** + * Gets a trace type for a given canonical id + * + * @param id + * the ID of the trace + * @return the return type + */ + public static TraceTypeHelper getTraceType(String id) { + return TRACE_TYPES.get(id); + } + + private static void populateCategoriesAndTraceTypes() { + if (TRACE_TYPES.isEmpty()) { + // Populate the Categories and Trace Types + IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType.TMF_TRACE_TYPE_ID); + for (IConfigurationElement ce : config) { + String elementName = ce.getName(); + if (elementName.equals(TmfTraceType.TYPE_ELEM)) { + String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR); + TRACE_TYPE_ATTRIBUTES.put(traceTypeId, ce); + } else if (elementName.equals(TmfTraceType.CATEGORY_ELEM)) { + String categoryId = ce.getAttribute(TmfTraceType.ID_ATTR); + TRACE_CATEGORIES.put(categoryId, ce); + } else if (elementName.equals(TmfTraceType.EXPERIMENT_ELEM)) { + String experimentTypeId = ce.getAttribute(TmfTraceType.ID_ATTR); + TRACE_TYPE_ATTRIBUTES.put(experimentTypeId, ce); + } + } + // create the trace types + for (String typeId : TRACE_TYPE_ATTRIBUTES.keySet()) { + IConfigurationElement ce = TRACE_TYPE_ATTRIBUTES.get(typeId); + final String category = getCategory(ce); + final String attribute = ce.getAttribute(TmfTraceType.NAME_ATTR); + ITmfTrace trace = null; + TraceElementType elementType = TraceElementType.TRACE; + try { + if (ce.getName().equals(TmfTraceType.TYPE_ELEM)) { + trace = (ITmfTrace) ce.createExecutableExtension(TmfTraceType.TRACE_TYPE_ATTR); + } else if (ce.getName().equals(TmfTraceType.EXPERIMENT_ELEM)) { + trace = (ITmfTrace) ce.createExecutableExtension(TmfTraceType.EXPERIMENT_TYPE_ATTR); + elementType = TraceElementType.EXPERIMENT; + } + if (trace == null) { + break; + } + // Deregister trace as signal handler because it is only + // used for validation + TmfSignalManager.deregister(trace); + + final String dirString = ce.getAttribute(TmfTraceType.IS_DIR_ATTR); + boolean isDir = Boolean.parseBoolean(dirString); + + TraceTypeHelper tt = new TraceTypeHelper(typeId, category, attribute, trace, isDir, elementType); + TRACE_TYPES.put(typeId, tt); + } catch (CoreException e) { + } + + } + } + } + + private static String getCategory(IConfigurationElement ce) { + final String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR); + if (categoryId != null) { + IConfigurationElement category = TRACE_CATEGORIES.get(categoryId); + if (category != null && !category.getName().equals("")) { //$NON-NLS-1$ + return category.getAttribute(TmfTraceType.NAME_ATTR); + } + } + return "[no category]"; //$NON-NLS-1$ + } + + /** + * Returns the list of trace categories + * + * @return the list of trace categories + */ + public static List getTraceCategories() { + List categoryNames = new ArrayList<>(); + for (String key : TRACE_TYPES.keySet()) { + final String categoryName = TRACE_TYPES.get(key).getCategoryName(); + if (!categoryNames.contains(categoryName)) { + categoryNames.add(categoryName); + } + } + return categoryNames; + } + + /** + * Get the trace type helper classes from category name. Return only the + * trace types, not the experiment types + * + * @param categoryName + * the categoryName to lookup + * @return a list of trace type helper classes {@link TraceTypeHelper} + */ + public static List getTraceTypes(String categoryName) { + List traceNames = new ArrayList<>(); + for (String key : TRACE_TYPES.keySet()) { + if (!TRACE_TYPES.get(key).isExperimentType()) { + final String storedCategoryName = TRACE_TYPES.get(key).getCategoryName(); + if (storedCategoryName.equals(categoryName)) { + traceNames.add(TRACE_TYPES.get(key)); + } + } + } + return traceNames; + } + + /** + * Validate a trace type + * + * @param traceTypeName + * the trace category (canonical name) + * @param fileName + * the file name (and path) + * @return true if the trace is of a valid type + */ + public static boolean validate(String traceTypeName, String fileName) { + if (traceTypeName != null && !traceTypeName.isEmpty()) { + final TraceTypeHelper traceTypeHelper = TRACE_TYPES.get(traceTypeName); + if (traceTypeHelper == null || !traceTypeHelper.validate(fileName).isOK()) { + return false; + } + } + return true; + } + + /** + * Validate a trace + * + * @param traceToValidate + * the trace category (canonical name) + * @return true if the trace is of a valid type + */ + public static boolean validate(TraceValidationHelper traceToValidate) { + return validate(traceToValidate.getTraceType(), traceToValidate.getTraceToScan()); + } + + /** + * Validate a list of files with a tracetype + * + * @param traceTypeName + * the trace category (canonical name) + * @param traces + * the list of files to check if they are trace + * @return true if all the traces are valid + */ + public static boolean validateTraceFiles(String traceTypeName, List traces) { + if (traceTypeName != null && !"".equals(traceTypeName) && //$NON-NLS-1$ + !traceTypeName.startsWith(TmfTraceType.CUSTOM_TXT_CATEGORY) && !traceTypeName.startsWith(TmfTraceType.CUSTOM_XML_CATEGORY)) { + for (File trace : traces) { + if (!validate(traceTypeName, trace.getAbsolutePath())) { + return false; + } + } + } + return true; + } + + /** + * Get a configuration element for a given name + * + * @param traceType + * the name canonical + * @return the configuration element, can be null + */ + public static IConfigurationElement getTraceAttributes(String traceType) { + return TRACE_TYPE_ATTRIBUTES.get(traceType); + } + + /** + * Find the id of a trace type by its parameters + * + * @param category + * like "ctf" or "custom text" + * @param traceType + * like "kernel" + * @return an id like "org.eclipse.linuxtools.blabla... + */ + public static String getTraceTypeId(String category, String traceType) { + for (String key : TRACE_TYPES.keySet()) { + if (TRACE_TYPES.get(key).getCategoryName().equals(category.trim()) && TRACE_TYPES.get(key).getName().equals(traceType.trim())) { + return key; + } + } + return null; + } + + /** + * Gets the custom trace type ID from the custom trace name + * + * @param traceType + * The trace type in human form (category:name) + * @return the trace type ID or null if the trace is not a custom one + * @deprecated Use {@link #getTraceTypeId(String, String)} + */ + @Deprecated + public static String getCustomTraceTypeId(String traceType) { + String traceTypeToken[] = traceType.split(":", 2); //$NON-NLS-1$ + if (traceTypeToken.length == 2) { + return getTraceTypeId(traceTypeToken[0], traceTypeToken[1]); + } + return null; + } + + /** + * Is the trace a custom (user-defined) trace type. These are the traces + * like : text and xml defined by the custom trace wizard. + * + * @param traceType + * the trace type in human form (category:name) + * @return true if the trace is a custom type + * @deprecated Use {@link #getTraceTypeId(String, String)} and check prefix + */ + @Deprecated + public static boolean isCustomTrace(String traceType) { + String traceTypeId = getCustomTraceTypeId(traceType); + if (traceTypeId != null) { + return traceTypeId.startsWith(CustomTxtTrace.class.getCanonicalName() + SEPARATOR) || + traceTypeId.startsWith(CustomXmlTrace.class.getCanonicalName() + SEPARATOR); + } + return false; + } + + /** + * Checks if a trace is a valid directory trace + * @param path + * the file name (and path) + * @return true if the trace is a valid directory trace else false + */ + public static boolean isDirectoryTrace(String path) { + final Iterable traceTypeHelpers = getTraceTypeHelpers(); + for (TraceTypeHelper traceTypeHelper : traceTypeHelpers) { + if (traceTypeHelper.isDirectoryTraceType() && + traceTypeHelper.validate(path).isOK()) { + return true; + } + } + return false; + } + + /** + * @param traceType + * the trace type + * @return true it is a directory trace type else else false + */ + public static boolean isDirectoryTraceType(String traceType) { + if (traceType != null) { + TraceTypeHelper traceTypeHelper = getTraceType(traceType); + if (traceTypeHelper != null) { + return traceTypeHelper.isDirectoryTraceType(); + } + } + throw new IllegalArgumentException("Invalid trace type string: " + traceType); //$NON-NLS-1$ + } + + /** + * Get the trace type id for a resource + * + * @param resource + * the resource + * @return the trace type id or null if it is not set + * @throws CoreException + * if the trace type id cannot be accessed + * @since 3.2 + */ + public static String getTraceTypeId(IResource resource) throws CoreException { + String traceTypeId = resource.getPersistentProperties().get(TmfCommonConstants.TRACETYPE); + // Fix custom trace type id with old class name or without category name for backward compatibility + if (traceTypeId != null) { + int index = traceTypeId.lastIndexOf(':'); + if (index != -1) { + if (traceTypeId.contains(CustomTxtTrace.class.getSimpleName() + ':') && traceTypeId.indexOf(':') == index) { + traceTypeId = CustomTxtTrace.class.getCanonicalName() + ':' + + TmfTraceType.CUSTOM_TXT_CATEGORY + traceTypeId.substring(index); + } else if (traceTypeId.contains(CustomXmlTrace.class.getSimpleName() + ':') && traceTypeId.indexOf(':') == index) { + traceTypeId = CustomXmlTrace.class.getCanonicalName() + ':' + + TmfTraceType.CUSTOM_XML_CATEGORY + traceTypeId.substring(index); + } + } + } + return traceTypeId; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/project/model/TraceTypeHelper.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/project/model/TraceTypeHelper.java new file mode 100644 index 0000000000..f432ea0dd9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/project/model/TraceTypeHelper.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Bernd Hufmann - Handling of directory traces types + * Geneviève Bastien - Added support of experiment types + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.project.model; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType.TraceElementType; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TraceValidationStatus; + +/** + * TraceTypeHelper, a helper that can link a few names to a configuration element + * and a trace + * + * @author Matthew Khouzam + * @since 3.0 + */ +public class TraceTypeHelper { + + private final String fName; + private final String fCategoryName; + private final String fCanonicalName; + private final TraceElementType fElementType; + @NonNull + private final ITmfTrace fTrace; + private final boolean fIsDirectory; + + /** + * Constructor for a trace type helper. It is a link between a canonical + * (hard to read) name, a category name, a name and a trace object. It is + * used for trace validation. + * + * @param canonicalName + * The "path" of the tracetype + * @param categoryName + * the category of the trace type + * @param name + * the name of the trace + * @param trace + * an object of the trace type + * @param isDir + * flag indicating whether the trace type is for a directory or file trace + * @param elementType + * True if this helper is for an experiment type + */ + public TraceTypeHelper(String canonicalName, String categoryName, String name, @NonNull ITmfTrace trace, boolean isDir, TraceElementType elementType) { + fName = name; + fCategoryName = categoryName; + fCanonicalName = canonicalName; + fTrace = trace; + fIsDirectory = isDir; + fElementType = elementType; + } + + /** + * Get the name + * + * @return the name + */ + public String getName() { + return fName; + } + + /** + * Get the category name + * + * @return the category name + */ + public String getCategoryName() { + return fCategoryName; + } + + /** + * Get the canonical name + * + * @return the canonical Name + */ + public String getCanonicalName() { + return fCanonicalName; + } + + /** + * Is the trace of this type? + * + * @param path + * the trace to validate + * @return whether it passes the validation + */ + public IStatus validate(String path) { + return fTrace.validate(null, path); + } + + /** + * Validate a trace against this trace type with confidence level + * + * @param path + * the trace to validate + * @return the confidence level (0 is lowest) or -1 if validation fails + * @since 3.0 + */ + public int validateWithConfidence(String path) { + int result = -1; + IStatus status = fTrace.validate(null, path); + if (status.isOK()) { + result = 0; + if (status instanceof TraceValidationStatus) { + result = ((TraceValidationStatus) status).getConfidence(); + } + } + return result; + } + + /** + * Get an object of the trace type + * @return an object of the trace type + * @since 2.1 + */ + public ITmfTrace getTrace() { + return fTrace; + } + + /** + * Return whether this helper applies to a trace type or experiment type + * + * @return True if experiment type, false otherwise + */ + public boolean isExperimentType() { + return fElementType == TraceElementType.EXPERIMENT; + } + + /** + * Get the class associated with this trace type + * + * @return The trace class + * @since 3.0 + */ + public Class getTraceClass() { + return fTrace.getClass(); + } + + /** + * Returns whether trace type is for a directory trace or a single file trace + * @return true if trace type is for a directory trace else false + */ + public boolean isDirectoryTraceType() { + return fIsDirectory; + } + + + @Override + public String toString() { + return fName; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/project/model/TraceValidationHelper.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/project/model/TraceValidationHelper.java new file mode 100644 index 0000000000..095e2c4c3e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/project/model/TraceValidationHelper.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.project.model; + +/** + * Trace import helper class + * + * @author Matthew Khouzam + * @since 3.0 + */ +public class TraceValidationHelper implements Comparable { + + private final String fTraceToScan; + private final String fTraceType; + + /** + * Trace To validate constructor + * + * @param traceToScan + * the path of the trace + * @param traceType + * the trace type of the trace to add (canonical name) + */ + public TraceValidationHelper(String traceToScan, String traceType) { + this.fTraceToScan = traceToScan; + this.fTraceType = traceType; + } + + /** + * @return the trace filename + */ + public String getTraceToScan() { + return fTraceToScan; + } + + /** + * @return the trace type canonical name + */ + public String getTraceType() { + return fTraceType; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((fTraceToScan == null) ? 0 : fTraceToScan.hashCode()); + result = prime * result + ((fTraceType == null) ? 0 : fTraceType.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof TraceValidationHelper)) { + return false; + } + TraceValidationHelper other = (TraceValidationHelper) obj; + if (fTraceToScan == null) { + if (other.fTraceToScan != null) { + return false; + } + } else if (!fTraceToScan.equals(other.fTraceToScan)) { + return false; + } + if (fTraceType == null) { + if (other.fTraceType != null) { + return false; + } + } else if (!fTraceType.equals(other.fTraceType)) { + return false; + } + return true; + } + + @Override + public int compareTo(TraceValidationHelper o) { + int retVal = fTraceToScan.compareTo(o.getTraceToScan()); + if (retVal == 0) { + retVal = fTraceType.compareTo(o.fTraceType); + } + return retVal; + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/request/ITmfEventRequest.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/request/ITmfEventRequest.java new file mode 100644 index 0000000000..646205231e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/request/ITmfEventRequest.java @@ -0,0 +1,199 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Alexandre Montplaisir - Merge with ITmfDataRequest + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.request; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; + +/** + * The TMF event request + * + * @author Francois Chouinard + */ +public interface ITmfEventRequest { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** The request count for all the events + * @since 3.0*/ + static final int ALL_DATA = Integer.MAX_VALUE; + + /** The request execution type/priority + * @since 3.0*/ + enum ExecutionType { + /** + * Backgroung, long-running, lower priority request + */ + BACKGROUND, + /** + * Foreground, short-running, high priority request + */ + FOREGROUND + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * @return request data type (T) + */ + Class getDataType(); + + /** + * @return request ID + */ + int getRequestId(); + + /** + * @return request ID + * @since 3.0 + */ + ExecutionType getExecType(); + + /** + * @return the index of the first event requested + */ + long getIndex(); + + /** + * @return the number of requested events + */ + int getNbRequested(); + + /** + * @return the number of events read so far + */ + int getNbRead(); + + /** + * @return the requested time range + */ + TmfTimeRange getRange(); + + // ------------------------------------------------------------------------ + // Request state predicates + // ------------------------------------------------------------------------ + + /** + * @return true if the request is still active + */ + boolean isRunning(); + + /** + * @return true if the request is completed + */ + boolean isCompleted(); + + /** + * @return true if the request has failed + */ + boolean isFailed(); + + /** + * @return true if the request was cancelled + */ + boolean isCancelled(); + + // ------------------------------------------------------------------------ + // Data handling + // ------------------------------------------------------------------------ + + /** + * Process the piece of data + * + * @param event + * The trace event to process + */ + void handleData(@NonNull ITmfEvent event); + + // ------------------------------------------------------------------------ + // Request notifications + // ------------------------------------------------------------------------ + + /** + * Request processing start notification + */ + void handleStarted(); + + /** + * Request processing completion notification + */ + void handleCompleted(); + + /** + * Request successful completion notification + */ + void handleSuccess(); + + /** + * Request failure notification + */ + void handleFailure(); + + /** + * Request cancellation notification + */ + void handleCancel(); + + /** + * To suspend the client thread until the request completes (or is + * cancelled). + * + * @throws InterruptedException + * thrown if the request was cancelled + */ + void waitForCompletion() throws InterruptedException; + + // ------------------------------------------------------------------------ + // Request state modifiers + // ------------------------------------------------------------------------ + + /** + * Put the request in the running state + */ + void start(); + + /** + * Put the request in the completed state + */ + void done(); + + /** + * Put the request in the failed completed state + */ + void fail(); + + /** + * Put the request in the cancelled completed state + */ + void cancel(); + + // ------------------------------------------------------------------------ + // Others + // ------------------------------------------------------------------------ + + /** + * This method is called by the event provider to set the index + * corresponding to the time range start time + * + * @param index + * The start time index + */ + void setStartIndex(int index); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/request/TmfEventRequest.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/request/TmfEventRequest.java new file mode 100644 index 0000000000..76a71f646e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/request/TmfEventRequest.java @@ -0,0 +1,426 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Alexandre Montplaisir - Consolidate constructors, merge with TmfDataRequest + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.request; + +import java.util.concurrent.CountDownLatch; + +import org.eclipse.tracecompass.internal.tmf.core.TmfCoreTracer; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; + +/** + * TmfEventRequest's are used to obtain series of events from an event provider. + * Open ranges can be used, especially for continuous streaming. + *

+ * The request is processed asynchronously by a TmfEventProvider and, as events + * become available, handleData() is invoked synchronously for each one. + *

+ * The TmfEventProvider indicates that the request is completed by calling + * done(). The request can be cancelled at any time with cancel(). + *

+ * Typical usage: + * + *


+ * TmfEventRequest request = new TmfEventRequest(DataType.class, range, startIndex, nbEvents, priority) {
+ *
+ *     public void handleData(ITmfEvent event) {
+ *         // do something with the event
+ *     }
+ *
+ *     public void handleSuccess() {
+ *         // callback for when the request completes successfully
+ *     }
+ *
+ *     public void handleFailure() {
+ *         // callback for when the request fails due to an error
+ *     }
+ *
+ *     public void handleCancel() {
+ *         // callback for when the request is cancelled via .cancel()
+ *     }
+ *
+ * };
+ *
+ * eventProvider.sendRequest(request);
+ * 
+ * + * + * TODO: Implement request failures (codes, etc...) + * + * @author Francois Chouinard + * @since 3.0 + */ +public abstract class TmfEventRequest implements ITmfEventRequest { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + private static int fRequestNumber = 0; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final Class fDataType; + private final ExecutionType fExecType; + + /** A unique request ID */ + private final int fRequestId; + + /** The requested events time range */ + private final TmfTimeRange fRange; + + /** The index (rank) of the requested event + * @since 3.0*/ + protected long fIndex; + + /** The number of requested events (ALL_DATA for all) + * @since 3.0*/ + protected int fNbRequested; + + /** The number of reads so far */ + private int fNbRead; + + private final CountDownLatch startedLatch = new CountDownLatch(1); + private final CountDownLatch completedLatch = new CountDownLatch(1); + + private boolean fRequestRunning; + private boolean fRequestCompleted; + private boolean fRequestFailed; + private boolean fRequestCanceled; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Request 'n' events of a given type, for the *whole* trace, at the given + * priority. + * + * @param dataType + * The requested data type. + * @param index + * The index of the first event to retrieve. You can use '0' to + * start at the beginning of the trace. + * @param nbRequested + * The number of events requested. You can use + * {@link TmfEventRequest#ALL_DATA} to indicate you want all + * events in the trace. + * @param priority + * The requested execution priority. + */ + public TmfEventRequest(Class dataType, + long index, + int nbRequested, + ExecutionType priority) { + this(dataType, TmfTimeRange.ETERNITY, index, nbRequested, priority); + } + + /** + * Request 'n' events of a given type, for the given time range, at the + * given priority. + * + * @param dataType + * The requested data type. + * @param range + * The time range of the requested events. You can use + * {@link TmfTimeRange#ETERNITY} to indicate you want to cover + * the whole trace. + * @param index + * The index of the first event to retrieve. You can use '0' to + * start at the beginning of the trace. + * @param nbRequested + * The number of events requested. You can use + * {@link TmfEventRequest#ALL_DATA} to indicate you want all + * events in the time range. + * @param priority + * The requested execution priority. + */ + public TmfEventRequest(Class dataType, + TmfTimeRange range, + long index, + int nbRequested, + ExecutionType priority) { + + fRequestId = fRequestNumber++; + fDataType = dataType; + fIndex = index; + fNbRequested = nbRequested; + fExecType = priority; + fRange = range; + fNbRead = 0; + + fRequestRunning = false; + fRequestCompleted = false; + fRequestFailed = false; + fRequestCanceled = false; + + /* Setup the request tracing if it's enabled */ + if (TmfCoreTracer.isRequestTraced()) { + String type = getClass().getName(); + type = type.substring(type.lastIndexOf('.') + 1); + @SuppressWarnings("nls") + String message = "CREATED " + + (getExecType() == ExecutionType.BACKGROUND ? "(BG)" : "(FG)") + + " Type=" + type + " Index=" + getIndex() + " NbReq=" + getNbRequested() + + " Range=" + getRange() + + " DataType=" + getDataType().getSimpleName(); + TmfCoreTracer.traceRequest(this, message); + } + } + + /** + * Resets the request counter (used for testing) + */ + public static void reset() { + fRequestNumber = 0; + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + @Override + public int getRequestId() { + return fRequestId; + } + + @Override + public long getIndex() { + return fIndex; + } + + /** + * @since 3.0 + */ + @Override + public ExecutionType getExecType() { + return fExecType; + } + + @Override + public int getNbRequested() { + return fNbRequested; + } + + @Override + public synchronized int getNbRead() { + return fNbRead; + } + + @Override + public synchronized boolean isRunning() { + return fRequestRunning; + } + + @Override + public synchronized boolean isCompleted() { + return fRequestCompleted; + } + + @Override + public synchronized boolean isFailed() { + return fRequestFailed; + } + + @Override + public synchronized boolean isCancelled() { + return fRequestCanceled; + } + + @Override + public Class getDataType() { + return fDataType; + } + + @Override + public TmfTimeRange getRange() { + return fRange; + } + + // ------------------------------------------------------------------------ + // Setters + // ------------------------------------------------------------------------ + + /** + * This method is called by the event provider to set the index + * corresponding to the time range start time + * + * @param index + * The start time index + */ + protected void setIndex(int index) { + fIndex = index; + } + + @Override + public void setStartIndex(int index) { + setIndex(index); + } + + // ------------------------------------------------------------------------ + // Operators + // ------------------------------------------------------------------------ + + @Override + public void handleData(ITmfEvent event) { + fNbRead++; + } + + @Override + public void handleStarted() { + if (TmfCoreTracer.isRequestTraced()) { + TmfCoreTracer.traceRequest(this, "STARTED"); //$NON-NLS-1$ + } + } + + @Override + public void handleCompleted() { + boolean requestFailed = false; + boolean requestCanceled = false; + synchronized (this) { + requestFailed = fRequestFailed; + requestCanceled = fRequestCanceled; + } + + if (requestFailed) { + handleFailure(); + } else if (requestCanceled) { + handleCancel(); + } else { + handleSuccess(); + } + if (TmfCoreTracer.isRequestTraced()) { + TmfCoreTracer.traceRequest(this, "COMPLETED (" + fNbRead + " events read)"); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + @Override + public void handleSuccess() { + if (TmfCoreTracer.isRequestTraced()) { + TmfCoreTracer.traceRequest(this, "SUCCEEDED"); //$NON-NLS-1$ + } + } + + @Override + public void handleFailure() { + if (TmfCoreTracer.isRequestTraced()) { + TmfCoreTracer.traceRequest(this, "FAILED"); //$NON-NLS-1$ + } + } + + @Override + public void handleCancel() { + if (TmfCoreTracer.isRequestTraced()) { + TmfCoreTracer.traceRequest(this, "CANCELLED"); //$NON-NLS-1$ + } + } + + /** + * To suspend the client thread until the request starts (or is canceled). + * + * @throws InterruptedException + * If the thread was interrupted while waiting + */ + public void waitForStart() throws InterruptedException { + while (!fRequestRunning) { + startedLatch.await(); + } + } + + @Override + public void waitForCompletion() throws InterruptedException { + while (!fRequestCompleted) { + completedLatch.await(); + } + } + + @Override + public void start() { + synchronized (this) { + fRequestRunning = true; + } + handleStarted(); + startedLatch.countDown(); + } + + @Override + public void done() { + synchronized (this) { + if (!fRequestCompleted) { + fRequestRunning = false; + fRequestCompleted = true; + } else { + return; + } + } + try { + handleCompleted(); + } finally { + completedLatch.countDown(); + } + } + + @Override + public void fail() { + synchronized (this) { + fRequestFailed = true; + } + done(); + } + + @Override + public void cancel() { + synchronized (this) { + fRequestCanceled = true; + } + done(); + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + // All requests have a unique id + public int hashCode() { + return getRequestId(); + } + + @Override + public boolean equals(Object other) { + if (other instanceof TmfEventRequest) { + TmfEventRequest request = (TmfEventRequest) other; + return request.fDataType == fDataType + && request.fIndex == fIndex + && request.fNbRequested == fNbRequested + && request.fRange.equals(fRange); + } + return false; + } + + @Override + public String toString() { + String name = getClass().getName(); + int dot = name.lastIndexOf('.'); + if (dot >= 0) { + name = name.substring(dot + 1); + } + return '[' + name + '(' + getRequestId() + ',' + getDataType().getSimpleName() + + ',' + getExecType() + ',' + getRange() + ',' + getIndex() + + ',' + getNbRequested() + ")]"; //$NON-NLS-1$ + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfEndSynchSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfEndSynchSignal.java new file mode 100644 index 0000000000..ad3b6cf22a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfEndSynchSignal.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2009, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +/** + * End of signal synchronization + * + * @version 1.0 + * @author Francois Chouinard + */ +public class TmfEndSynchSignal extends TmfSignal { + + /** + * Constructor + * + * @param synchId + * The ID assigned to this signal + */ + public TmfEndSynchSignal(int synchId) { + super(null, synchId); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfEventFilterAppliedSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfEventFilterAppliedSignal.java new file mode 100644 index 0000000000..9a337cd4be --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfEventFilterAppliedSignal.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +import org.eclipse.tracecompass.tmf.core.filter.ITmfFilter; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Signal indicating an event filter has been applied. + * + * @version 1.0 + * @author Patrick Tasse + * @since 2.0 + */ +public class TmfEventFilterAppliedSignal extends TmfSignal { + + private final ITmfTrace fTrace; + private final ITmfFilter fEventFilter; + + /** + * Constructor for a new signal. + * + * @param source + * The object sending this signal + * @param trace + * The trace to which filter is applied + * @param filter + * The applied event filter or null + */ + public TmfEventFilterAppliedSignal(Object source, ITmfTrace trace, ITmfFilter filter) { + super(source); + fTrace = trace; + fEventFilter = filter; + } + + /** + * Get the trace object concerning this signal + * + * @return The trace + */ + public ITmfTrace getTrace() { + return fTrace; + } + + /** + * Get the event filter being applied + * + * @return The filter + */ + public ITmfFilter getEventFilter() { + return fEventFilter; + } + + @Override + public String toString() { + return "[TmfEventFilterAppliedSignal (" + fTrace.getName() + " : " + fEventFilter + ")]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfEventSearchAppliedSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfEventSearchAppliedSignal.java new file mode 100644 index 0000000000..864300c4ab --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfEventSearchAppliedSignal.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +import org.eclipse.tracecompass.tmf.core.filter.ITmfFilter; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Signal indicating an event search has been applied. + * + * @version 1.0 + * @author Patrick Tasse + * @since 2.0 + */ +public class TmfEventSearchAppliedSignal extends TmfSignal { + + private final ITmfTrace fTrace; + private final ITmfFilter fSearchFilter; + + /** + * Constructor for a new signal. + * + * @param source + * The object sending this signal + * @param trace + * The trace to which search is applied + * @param filter + * The applied search filter or null + */ + public TmfEventSearchAppliedSignal(Object source, ITmfTrace trace, ITmfFilter filter) { + super(source); + fTrace = trace; + fSearchFilter = filter; + } + + /** + * Get the trace object concerning this signal + * + * @return The trace + */ + public ITmfTrace getTrace() { + return fTrace; + } + + /** + * Get the search filter being applied + * + * @return The search filter + */ + public ITmfFilter getSearchFilter() { + return fSearchFilter; + } + + @Override + public String toString() { + return "[TmfSearchFilterAppliedSignal (" + fTrace.getName() + " : " + fSearchFilter + ")]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfEventSelectedSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfEventSelectedSignal.java new file mode 100644 index 0000000000..ac5e8bfcf3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfEventSelectedSignal.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * Signal indicating a trace event has been selected. + * + * The specified event has been selected. + * + * @author Patrick Tasse + * @since 3.2 + */ +public class TmfEventSelectedSignal extends TmfSignal { + + private final ITmfEvent fEvent; + + /** + * Constructor + * + * @param source + * Object sending this signal + * @param event + * The event that was selected + */ + public TmfEventSelectedSignal(Object source, ITmfEvent event) { + super(source); + fEvent = event; + } + + /** + * @return The event referred to by this signal + */ + public ITmfEvent getEvent() { + return fEvent; + } + + @Override + public String toString() { + return "[TmfEventSelectedSignal (" + fEvent.toString() + ")]"; //$NON-NLS-1$ //$NON-NLS-2$ + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfRangeSynchSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfRangeSynchSignal.java new file mode 100644 index 0000000000..b3a535326d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfRangeSynchSignal.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Deprecate current time + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; + +/** + * A new time range has been selected. + * + * This is the visible (zoom) time range. To synchronize on the selection range, + * use {@link TmfTimeSynchSignal}. + * + * @version 1.0 + * @author Francois Chouinard + */ +public class TmfRangeSynchSignal extends TmfSignal { + + private final TmfTimeRange fCurrentRange; + + /** + * Constructor + * + * @param source + * Object sending this signal + * @param range + * The new time range + * @since 2.1 + */ + public TmfRangeSynchSignal(Object source, TmfTimeRange range) { + super(source); + fCurrentRange = range; + } + + /** + * @return This signal's time range + * @since 2.0 + */ + public TmfTimeRange getCurrentRange() { + return fCurrentRange; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignal.java new file mode 100644 index 0000000000..7dc8bef4b7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignal.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2009, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +/** + * Base class for TMF signals + * + * @version 1.0 + * @author Francois Chouinard + */ +public abstract class TmfSignal { + + private final Object fSource; + private int fReference; + + /** + * Basic constructor, which uses a default of "0" for the reference index + * + * @param source + * Object sending this signal + */ + public TmfSignal(Object source) { + this(source, 0); + } + + /** + * Standard constructor + * + * @param source + * Object sending this signal + * @param reference + * Reference index to assign to this signal + */ + public TmfSignal(Object source, int reference) { + fSource = source; + fReference = reference; + } + + /** + * @return The source object of this signal + */ + public Object getSource() { + return fSource; + } + + /** + * Change this signal's reference index + * + * @param reference + * The new reference to use + */ + public void setReference(int reference) { + fReference = reference; + } + + /** + * @return This signal's reference index + */ + public int getReference() { + return fReference; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignalHandler.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignalHandler.java new file mode 100644 index 0000000000..5fb38c7325 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignalHandler.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2009, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marker for TMF signal handlers. + * + * @version 1.0 + * @author Francois Chouinard + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface TmfSignalHandler { + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignalManager.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignalManager.java new file mode 100644 index 0000000000..e0af04d3ba --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignalManager.java @@ -0,0 +1,231 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Update register methods + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.internal.tmf.core.TmfCoreTracer; + +/** + * This class manages the set of signal listeners and the signals they are + * interested in. When a signal is broadcasted, the appropriate listeners + * signal handlers are invoked. + * + * @version 1.0 + * @author Francois Chouinard + */ +public class TmfSignalManager { + + // The set of event listeners and their corresponding handler methods. + // Note: listeners could be restricted to ITmfComponents but there is no + // harm in letting anyone use this since it is not tied to anything but + // the signal data type. + private static Map fListeners = new HashMap<>(); + private static Map fVIPListeners = new HashMap<>(); + + // The signal executor for asynchronous signals + private static final ExecutorService fExecutor = Executors.newSingleThreadExecutor(); + + // If requested, add universal signal tracer + // TODO: Temporary solution: should be enabled/disabled dynamically + private static boolean fTraceIsActive = false; + private static TmfSignalTracer fSignalTracer; + + static { + if (fTraceIsActive) { + fSignalTracer = TmfSignalTracer.getInstance(); + register(fSignalTracer); + } + } + + /** + * Register an object to the signal manager. This object can then implement + * handler methods, marked with @TmfSignalHandler and with the expected + * signal type as parameter. + * + * @param listener + * The object that will be notified of new signals + */ + public static synchronized void register(Object listener) { + deregister(listener); // make sure that listener is only registered once + Method[] methods = getSignalHandlerMethods(listener); + if (methods.length > 0) { + fListeners.put(listener, methods); + } + } + + /** + * Register an object to the signal manager as a "VIP" listener. All VIP + * listeners will all receive the signal before the manager moves on to the + * lowly, non-VIP listeners. + * + * @param listener + * The object that will be notified of new signals + */ + public static synchronized void registerVIP(Object listener) { + deregister(listener); // make sure that listener is only registered once + Method[] methods = getSignalHandlerMethods(listener); + if (methods.length > 0) { + fVIPListeners.put(listener, methods); + } + } + + /** + * De-register a listener object from the signal manager. This means that + * its @TmfSignalHandler methods will no longer be called. + * + * @param listener + * The object to de-register + */ + public static synchronized void deregister(Object listener) { + fVIPListeners.remove(listener); + fListeners.remove(listener); + } + + /** + * Returns the list of signal handlers in the listener. Signal handler name + * is irrelevant; only the annotation (@TmfSignalHandler) is important. + * + * @param listener + * @return + */ + private static Method[] getSignalHandlerMethods(Object listener) { + List handlers = new ArrayList<>(); + Method[] methods = listener.getClass().getMethods(); + for (Method method : methods) { + if (method.isAnnotationPresent(TmfSignalHandler.class)) { + handlers.add(method); + } + } + return handlers.toArray(new Method[handlers.size()]); + } + + static int fSignalId = 0; + + /** + * Invokes the handling methods that listens to signals of a given type in + * the current thread. + * + * The list of handlers is built on-the-fly to allow for the dynamic + * creation/deletion of signal handlers. Since the number of signal handlers + * shouldn't be too high, this is not a big performance issue to pay for the + * flexibility. + * + * For synchronization purposes, the signal is bracketed by two synch + * signals. + * + * @param signal + * the signal to dispatch + */ + public static synchronized void dispatchSignal(TmfSignal signal) { + int signalId = fSignalId++; + sendSignal(new TmfStartSynchSignal(signalId)); + signal.setReference(signalId); + sendSignal(signal); + sendSignal(new TmfEndSynchSignal(signalId)); + } + + /** + * Invokes the handling methods that listens to signals of a given type + * in a separate thread which will call + * {@link TmfSignalManager#dispatchSignal(TmfSignal)}. + * + * If a signal is already processed the signal will be queued and + * dispatched after the ongoing signal finishes. + * + * @param signal + * the signal to dispatch + * @since 3.0 + */ + public static void dispatchSignalAsync(final TmfSignal signal) { + if (!fExecutor.isShutdown()) { + fExecutor.execute(new Runnable() { + @Override + public void run() { + dispatchSignal(signal); + } + }); + } + } + + /** + * Disposes the signal manager + * @since 3.0 + */ + public static void dispose() { + fExecutor.shutdown(); + } + + private static void sendSignal(TmfSignal signal) { + sendSignal(fVIPListeners, signal); + sendSignal(fListeners, signal); + } + + private static void sendSignal(Map listeners, TmfSignal signal) { + + if (TmfCoreTracer.isSignalTraced()) { + TmfCoreTracer.traceSignal(signal, "(start)"); //$NON-NLS-1$ + } + + // Build the list of listener methods that are registered for this signal + Class signalClass = signal.getClass(); + Map> targets = new HashMap<>(); + targets.clear(); + for (Map.Entry entry : listeners.entrySet()) { + List matchingMethods = new ArrayList<>(); + for (Method method : entry.getValue()) { + if (method.getParameterTypes()[0].isAssignableFrom(signalClass)) { + matchingMethods.add(method); + } + } + if (!matchingMethods.isEmpty()) { + targets.put(entry.getKey(), matchingMethods); + } + } + + // Call the signal handlers + for (Map.Entry> entry : targets.entrySet()) { + for (Method method : entry.getValue()) { + try { + method.invoke(entry.getKey(), new Object[] { signal }); + if (TmfCoreTracer.isSignalTraced()) { + Object key = entry.getKey(); + String hash = String.format("%1$08X", entry.getKey().hashCode()); //$NON-NLS-1$ + String target = "[" + hash + "] " + key.getClass().getSimpleName() + ":" + method.getName(); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + TmfCoreTracer.traceSignal(signal, target); + } + } catch (IllegalArgumentException e) { + Activator.logError("Exception handling signal " + signal + " in method " + method, e); //$NON-NLS-1$ //$NON-NLS-2$ + } catch (IllegalAccessException e) { + Activator.logError("Exception handling signal " + signal + " in method " + method, e); //$NON-NLS-1$ //$NON-NLS-2$ + } catch (InvocationTargetException e) { + Activator.logError("Exception handling signal " + signal + " in method " + method, e); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + } + + if (TmfCoreTracer.isSignalTraced()) { + TmfCoreTracer.traceSignal(signal, "(end)"); //$NON-NLS-1$ + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignalThrottler.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignalThrottler.java new file mode 100644 index 0000000000..5c02643c41 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignalThrottler.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +import java.util.Timer; +import java.util.TimerTask; + +import org.eclipse.tracecompass.tmf.core.component.ITmfComponent; +import org.eclipse.tracecompass.tmf.core.component.TmfComponent; + +/** + * "Buffer" between a TmfComponent and the signal manager. You can use this if + * you want to throttle the amount of signals your component will send. + * + * It works by specifying a delay, then calling {@link #queue}. The signals will + * only be really sent if no other call to {@link #queue} happens within $delay + * milliseconds afterwards. This guarantees that only the *last* signal is + * actually broadcasted. + * + * Note that this class does not discriminate for signal types, sources, or + * whatever. If you want to throttle different signals in different ways, you + * can use multiple signal throttlers in your component and call them + * accordingly. + * + * @author Alexandre Montplaisir + * @since 2.0 + */ +public class TmfSignalThrottler { + + private final ITmfComponent fComponent; + private final long fDelay; + private final Timer fTimer; + private TimerTask fCurrentTask; + + /** + * Constructor + * + * @param component + * The source component of the signals + * @param delay + * Time to wait before actually sending signals (in ms) + */ + public TmfSignalThrottler(ITmfComponent component, long delay) { + this.fComponent = component; + this.fDelay = delay; + this.fTimer = new Timer(); + + /* + * Initialize currentTask to something, so we don't have to do a null + * check every time + */ + fCurrentTask = new TimerTask() { @Override public void run() {} }; + } + + /** + * Queue a signal for sending. It will only be forward to the centralized + * signal handler if 'delay' elapses without another signal being sent + * through this method. + * + * You call this instead of calling {@link TmfComponent#broadcast}. + * + * @param signal + * The signal to queue for broadcasting + */ + public synchronized void queue(TmfSignal signal) { + fCurrentTask.cancel(); + fCurrentTask = new BroadcastRequest(signal); + fTimer.schedule(fCurrentTask, fDelay); + } + + /** + * Dispose method. Will prevent any pending signal from being sent, and this + * throttler from be used again. + */ + public synchronized void dispose() { + fTimer.cancel(); + fTimer.purge(); + } + + private class BroadcastRequest extends TimerTask { + + private final TmfSignal signal; + + BroadcastRequest(TmfSignal signal) { + this.signal = signal; + } + + @Override + public void run() { + fComponent.broadcast(signal); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignalTracer.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignalTracer.java new file mode 100644 index 0000000000..75f30179bd --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfSignalTracer.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2009, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +/** + * This object (singleton) traces all TmfSignals in the application. + * + * @version 1.0 + * @author Francois Chouinard + */ +public class TmfSignalTracer { + + static TmfSignalTracer fInstance; + + /** + * @return The single instance of the signal tracer object + */ + static public TmfSignalTracer getInstance() { + if (fInstance == null) { + fInstance = new TmfSignalTracer(); + } + return fInstance; + } + + private TmfSignalTracer() { + } + + /** + * Handler for all TMF signal types + * + * @param signal + * Incoming signal + */ + @TmfSignalHandler + public void traceSignal(TmfSignal signal) { + System.out.println(signal.getSource().toString() + ": " + signal.toString()); //$NON-NLS-1$ + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfStartAnalysisSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfStartAnalysisSignal.java new file mode 100644 index 0000000000..7e3ec7022a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfStartAnalysisSignal.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; + +/** + * Signal indicating an analysis has started. Views and outputs may use it to + * update themselves with the results. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfStartAnalysisSignal extends TmfSignal { + + private final IAnalysisModule fModule; + + /** + * Constructor for a new signal. + * + * @param source + * The object sending this signal + * @param module + * The analysis module + */ + public TmfStartAnalysisSignal(Object source, IAnalysisModule module) { + super(source); + fModule = module; + } + + /** + * Get the trace object concerning this signal + * + * @return The trace + */ + public IAnalysisModule getAnalysisModule() { + return fModule; + } + + @Override + public String toString() { + return "[" + this.getClass().getSimpleName() + " (" + fModule.getName() + ")]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfStartSynchSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfStartSynchSignal.java new file mode 100644 index 0000000000..97a8bb4aea --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfStartSynchSignal.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2009, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +/** + * Start of signal synchronization + * + * @version 1.0 + * @author Francois Chouinard + */ +public class TmfStartSynchSignal extends TmfSignal { + + + /** + * Constructor + * + * @param synchId + * The synch ID of this signal + */ + public TmfStartSynchSignal(int synchId) { + super(null, synchId); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTimeSynchSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTimeSynchSignal.java new file mode 100644 index 0000000000..e5249a36e2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTimeSynchSignal.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Support selection range + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; + +/** + * A new time or time range selection has been made. + * + * This is the selected time or time range. To synchronize on the visible + * (zoom) range, use {@link TmfRangeSynchSignal}. + * + * @version 1.0 + * @author Francois Chouinard +*/ +public class TmfTimeSynchSignal extends TmfSignal { + + private final ITmfTimestamp fBeginTime; + private final ITmfTimestamp fEndTime; + + /** + * Constructor + * + * @param source + * Object sending this signal + * @param ts + * Timestamp of selection + * @since 2.0 + */ + public TmfTimeSynchSignal(Object source, ITmfTimestamp ts) { + super(source); + fBeginTime = ts; + fEndTime = ts; + } + + /** + * Constructor + * + * @param source + * Object sending this signal + * @param begin + * Timestamp of begin of selection range + * @param end + * Timestamp of end of selection range + * @since 2.1 + */ + public TmfTimeSynchSignal(Object source, ITmfTimestamp begin, ITmfTimestamp end) { + super(source); + fBeginTime = begin; + fEndTime = end; + } + + /** + * @return The begin timestamp of selection + * @since 2.1 + */ + public ITmfTimestamp getBeginTime() { + return fBeginTime; + } + + /** + * @return The end timestamp of selection + * @since 2.1 + */ + public ITmfTimestamp getEndTime() { + return fEndTime; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("[TmfTimeSynchSignal ("); //$NON-NLS-1$ + if (fBeginTime != null) { + sb.append(fBeginTime.toString()); + if (!fBeginTime.equals(fEndTime) && fEndTime != null) { + sb.append('-'); + sb.append(fEndTime.toString()); + } + } + sb.append(")]"); //$NON-NLS-1$ + return sb.toString(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTimestampFormatUpdateSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTimestampFormatUpdateSignal.java new file mode 100644 index 0000000000..0fbe741b97 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTimestampFormatUpdateSignal.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +/** + * The default timestamp/interval format was modified + * + * @author Francois Chouinard + * @version 1.0 + * @since 2.0 + */ +public class TmfTimestampFormatUpdateSignal extends TmfSignal { + + /** + * @param source the signal source + */ + public TmfTimestampFormatUpdateSignal(Object source) { + super(source); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceClosedSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceClosedSignal.java new file mode 100644 index 0000000000..20642c7b79 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceClosedSignal.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Signal indicating a trace is being closed. + * + * Receivers should cancel any jobs, threads or requests for the specified trace + * and clear any user interface component related to it as soon as possible. + * The trace will be disposed after the signal has been processed. + * + * @version 1.0 + * @author Patrick Tasse + * @since 2.0 + */ +@NonNullByDefault +public class TmfTraceClosedSignal extends TmfSignal { + + private final ITmfTrace fTrace; + + /** + * Constructor for a new signal + * + * @param source + * The object sending this signal + * @param trace + * The trace being closed + */ + public TmfTraceClosedSignal(Object source, ITmfTrace trace) { + super(source); + fTrace = trace; + } + + /** + * Get a reference to the trace being closed + * + * @return The trace object + */ + public ITmfTrace getTrace() { + return fTrace; + } + + @Override + public String toString() { + return "[TmfTraceClosedSignal (" + fTrace.getName() + ")]"; //$NON-NLS-1$ //$NON-NLS-2$ + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceOpenedSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceOpenedSignal.java new file mode 100644 index 0000000000..917f2e095e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceOpenedSignal.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +import org.eclipse.core.resources.IFile; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Signal indicating a trace has been opened. + * + * Receivers can get ready to receive TmfTraceRangeUpdatedSignal for coalescing + * and can expect TmfTraceSelectedSignal to follow. + * + * @version 1.0 + * @author Patrick Tasse + * @since 2.0 + */ +public class TmfTraceOpenedSignal extends TmfSignal { + + private final ITmfTrace fTrace; + private final IFile fEditorFile; + + /** + * Constructor for a new signal. + * + * @param source + * The object sending this signal + * @param trace + * The trace that has been opened + * @param editorFile + * Pointer to the editor file + */ + public TmfTraceOpenedSignal(Object source, ITmfTrace trace, IFile editorFile) { + super(source); + fTrace = trace; + fEditorFile = editorFile; + } + + /** + * Get the trace object concerning this signal + * + * @return The trace + */ + public ITmfTrace getTrace() { + return fTrace; + } + + /** + * Get a pointer to the editor file for this trace + * + * @return The IFile object + * @since 3.0 + */ + public IFile getEditorFile() { + return fEditorFile; + } + + @Override + public String toString() { + return "[TmfTraceOpenedSignal (" + fTrace.getName() + ")]"; //$NON-NLS-1$ //$NON-NLS-2$ + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceRangeUpdatedSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceRangeUpdatedSignal.java new file mode 100644 index 0000000000..11ba787dc4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceRangeUpdatedSignal.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Signal indicating a trace range has been updated. + * + * Receivers can safely perform event requests for the specified time range. + * The signal acts as a trigger for coalescing such requests. + * + * @version 1.0 + * @author Patrick Tasse + * @since 2.0 + */ +public class TmfTraceRangeUpdatedSignal extends TmfSignal { + + private final ITmfTrace fTrace; + private final TmfTimeRange fTimeRange; + + /** + * Constructor + * + * @param source + * Object sending this signal + * @param trace + * Trace whose range was updated + * @param range + * The new time range of the trace + */ + public TmfTraceRangeUpdatedSignal(Object source, ITmfTrace trace, TmfTimeRange range) { + super(source); + fTrace = trace; + fTimeRange = range; + } + + /** + * @return The trace + */ + public ITmfTrace getTrace() { + return fTrace; + } + + /** + * @return The time range + */ + public TmfTimeRange getRange() { + return fTimeRange; + } + + @Override + @SuppressWarnings("nls") + public String toString() { + return "[TmfTraceRangeUpdatedSignal (" + fTrace.getName() + ", " + fTimeRange.toString() + ")]"; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceSelectedSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceSelectedSignal.java new file mode 100644 index 0000000000..e872c42a0c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceSelectedSignal.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Signal indicating a trace has been selected. + * + * The specified trace is the active trace and has been brought to top + * or the signal is used as a trigger to bring it to top. + * + * @version 1.0 + * @author Patrick Tasse + */ +public class TmfTraceSelectedSignal extends TmfSignal { + + private final ITmfTrace fTrace; + + /** + * Constructor + * + * @param source + * Object sending this signal + * @param trace + * The trace that was selected + */ + public TmfTraceSelectedSignal(Object source, ITmfTrace trace) { + super(source); + fTrace = trace; + } + + /** + * @return The trace referred to by this signal + */ + public ITmfTrace getTrace() { + return fTrace; + } + + @Override + public String toString() { + return "[TmfTraceSelectedSignal (" + fTrace.getName() + ")]"; //$NON-NLS-1$ //$NON-NLS-2$ + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceSynchronizedSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceSynchronizedSignal.java new file mode 100644 index 0000000000..e5e5bf4049 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceSynchronizedSignal.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +import org.eclipse.tracecompass.tmf.core.synchronization.SynchronizationAlgorithm; + +/** + * Signal indicating a trace synchronization has been done + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfTraceSynchronizedSignal extends TmfSignal { + + private final SynchronizationAlgorithm fAlgoSync; + + /** + * Constructor + * + * @param source + * Object sending this signal + * @param algoSync + * The synchronization algorithm used + */ + public TmfTraceSynchronizedSignal(Object source, SynchronizationAlgorithm algoSync) { + super(source); + fAlgoSync = algoSync; + } + + /** + * Synchronization algorithm getter + * + * @return The algorithm object + */ + public SynchronizationAlgorithm getSyncAlgo() { + return fAlgoSync; + } + + @Override + public String toString() { + return "[" + getClass().getSimpleName() + " (" + fAlgoSync.toString() + ")]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceUpdatedSignal.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceUpdatedSignal.java new file mode 100644 index 0000000000..bbcd96157e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/signal/TmfTraceUpdatedSignal.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.signal; + +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Signal indicating a trace has been updated. + * + * The trace has been indexed up to the specified range. + * + * @version 1.0 + * @author Francois Chouinard + */ +public class TmfTraceUpdatedSignal extends TmfSignal { + + private final ITmfTrace fTrace; + private final TmfTimeRange fTimeRange; + private final long fNbEvents; + + /** + * Constructor + * + * @param source + * Object sending this signal + * @param trace + * The trace that was updated + * @param range + * The new time range of the trace + * @param nbEvents + * The number of events in the trace + * @since 3.0 + */ + public TmfTraceUpdatedSignal(Object source, ITmfTrace trace, TmfTimeRange range, long nbEvents) { + super(source); + fTrace = trace; + fTimeRange = range; + fNbEvents = nbEvents; + } + + /** + * @return The trace referred to by this signal + */ + public ITmfTrace getTrace() { + return fTrace; + } + + /** + * @return The time range indicated by this signal + * @since 2.0 + */ + public TmfTimeRange getRange() { + return fTimeRange; + } + + /** + * Returns the number of events indicated by this signal + * + * @return the number of events indicated by this signal + * @since 3.0 + */ + public long getNbEvents() { + return fNbEvents; + } + + @Override + @SuppressWarnings("nls") + public String toString() { + return "[TmfTraceUpdatedSignal (" + fTrace.toString() + ", " + + fTimeRange.toString() + ")]"; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statesystem/AbstractTmfStateProvider.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statesystem/AbstractTmfStateProvider.java new file mode 100644 index 0000000000..c744cf3fe1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statesystem/AbstractTmfStateProvider.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.statesystem; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Instead of using IStateChangeInput directly, one can extend this class, which + * defines a lot of the common functions of the state change input plugin. + * + * It will handle the state-system-processing in a separate thread, which is + * normally not a bad idea for traces of some size. + * + * processEvent() is replaced with eventHandle(), so that all the multi-thread + * logic is abstracted away. + * + * @author Alexandre Montplaisir + * @since 2.0 + */ +public abstract class AbstractTmfStateProvider implements ITmfStateProvider { + + private static final int DEFAULT_EVENTS_QUEUE_SIZE = 10000; + + private final ITmfTrace trace; + private final Class eventType; + private final BlockingQueue eventsQueue; + private final Thread eventHandlerThread; + + private boolean ssAssigned; + + /** State system in which to insert the state changes */ + protected ITmfStateSystemBuilder ss = null; + + /** + * Instantiate a new state provider plugin. + * + * @param trace + * The LTTng 2.0 kernel trace directory + * @param eventType + * The specific class for the event type that will be used within + * the subclass + * @param id + * Name given to this state change input. Only used internally. + */ + public AbstractTmfStateProvider(ITmfTrace trace, + Class eventType, String id) { + this.trace = trace; + this.eventType = eventType; + eventsQueue = new ArrayBlockingQueue<>(DEFAULT_EVENTS_QUEUE_SIZE); + ssAssigned = false; + + String id2 = (id == null ? "Unamed" : id); //$NON-NLS-1$ + eventHandlerThread = new Thread(new EventProcessor(), id2 + " Event Handler"); //$NON-NLS-1$ + } + + @Override + public ITmfTrace getTrace() { + return trace; + } + + /** + * @since 3.0 + */ + @Override + public long getStartTime() { + return trace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + } + + /** + * @since 3.0 + */ + @Override + public void assignTargetStateSystem(ITmfStateSystemBuilder ssb) { + ss = ssb; + ssAssigned = true; + eventHandlerThread.start(); + } + + /** + * @since 3.0 + */ + @Override + public ITmfStateSystem getAssignedStateSystem() { + return ss; + } + + @Override + public void dispose() { + /* Insert a null event in the queue to stop the event handler's thread. */ + try { + eventsQueue.put(END_EVENT); + eventHandlerThread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + ssAssigned = false; + ss = null; + } + + @Override + public final Class getExpectedEventType() { + return eventType; + } + + @Override + public final void processEvent(ITmfEvent event) { + /* Make sure the target state system has been assigned */ + if (!ssAssigned) { + System.err.println("Cannot process event without a target state system"); //$NON-NLS-1$ + return; + } + + /* Insert the event we're received into the events queue */ + ITmfEvent curEvent = event; + try { + eventsQueue.put(curEvent); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * Block the caller until the events queue is empty. + */ + public void waitForEmptyQueue() { + /* + * We will first insert a dummy event that is guaranteed to not modify + * the state. That way, when that event leaves the queue, we will know + * for sure that the state system processed the preceding real event. + */ + try { + eventsQueue.put(EMPTY_QUEUE_EVENT); + while (!eventsQueue.isEmpty()) { + Thread.sleep(100); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + // ------------------------------------------------------------------------ + // Special event types + // ------------------------------------------------------------------------ + + /** Fake event indicating the build is over, and the provider should close */ + private static class EndEvent extends TmfEvent {} + /** Fake event indicating we want to clear the current queue */ + private static class EmptyQueueEvent extends TmfEvent {} + + private static final EndEvent END_EVENT = new EndEvent(); + private static final EmptyQueueEvent EMPTY_QUEUE_EVENT = new EmptyQueueEvent(); + + // ------------------------------------------------------------------------ + // Inner classes + // ------------------------------------------------------------------------ + + /** + * This is the runner class for the second thread, which will take the + * events from the queue and pass them through the state system. + */ + private class EventProcessor implements Runnable { + + private ITmfEvent currentEvent; + + @Override + public void run() { + if (ss == null) { + System.err.println("Cannot run event manager without assigning a target state system first!"); //$NON-NLS-1$ + return; + } + ITmfEvent event; + + try { + event = eventsQueue.take(); + /* This is a singleton, we want to do != instead of !x.equals */ + while (event != END_EVENT) { + if (event == EMPTY_QUEUE_EVENT) { + /* Synchronization event, should be ignored */ + event = eventsQueue.take(); + continue; + } + + currentEvent = event; + + /* Make sure this is an event the sub-class can process */ + if (eventType.isInstance(event) && event.getType() != null) { + eventHandle(event); + } + event = eventsQueue.take(); + } + /* We've received the last event, clean up */ + closeStateSystem(); + } catch (InterruptedException e) { + /* We've been interrupted abnormally */ + System.out.println("Event handler interrupted!"); //$NON-NLS-1$ + e.printStackTrace(); + } + } + + private void closeStateSystem() { + final long endTime = (currentEvent == null) ? 0 : + currentEvent.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + ss.closeHistory(endTime); + } + } + + // ------------------------------------------------------------------------ + // Abstract methods + // ------------------------------------------------------------------------ + + /** + * Handle the given event and send the appropriate state transitions into + * the the state system. + * + * This is basically the same thing as IStateChangeInput.processEvent(), + * except here processEvent() and eventHandle() are run in two different + * threads (and the AbstractStateChangeInput takes care of processEvent() + * already). + * + * @param event + * The event to process. If you need a specific event type, you + * should check for its instance right at the beginning. + */ + protected abstract void eventHandle(ITmfEvent event); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statesystem/ITmfAnalysisModuleWithStateSystems.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statesystem/ITmfAnalysisModuleWithStateSystems.java new file mode 100644 index 0000000000..76a86429a9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statesystem/ITmfAnalysisModuleWithStateSystems.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.statesystem; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; + +/** + * Interface for analysis modules providing state systems. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public interface ITmfAnalysisModuleWithStateSystems extends IAnalysisModule { + + /** + * Return a specific state system provided by this analysis. + * + * @param id + * The ID of the state system + * @return The state system corresponding to the given ID, null if there is + * no match. + */ + @Nullable + ITmfStateSystem getStateSystem(@NonNull String id); + + /** + * Return all the state systems provided by this analysis module, in + * Iterable format. + * + * @return The state systems + */ + @NonNull + Iterable getStateSystems(); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statesystem/ITmfStateProvider.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statesystem/ITmfStateProvider.java new file mode 100644 index 0000000000..fa5260c27a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statesystem/ITmfStateProvider.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * Copyright (c) 2010, 2011 École Polytechnique de Montréal + * Copyright (c) 2010, 2011 Alexandre Montplaisir + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.statesystem; + +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * This is the interface used to define the "state change input", which is the + * main type of input that goes in the state system. + * + * Usually a state change input, also called "state provider" is the piece of + * the pipeline which converts trace events to state changes. + * + * @author Alexandre Montplaisir + * @since 2.0 + */ +public interface ITmfStateProvider { + + /** + * Event handler plugins should provide a version number. This is used to + * determine if a potential existing file can be re-opened later (if the + * versions in the file and in the viewer match), or if the file should be + * rebuilt from scratch (if the versions don't match). + * + * @return The version number of the input plugin + * @since 2.0 + */ + int getVersion(); + + /** + * Get the trace with which this state input plugin is associated. + * + * @return The associated trace + */ + ITmfTrace getTrace(); + + /** + * Return the start time of this "state change input", which is normally the + * start time of the originating trace (or it can be the time of the first + * state-changing event). + * + * @return The start time + */ + long getStartTime(); + + /** + * Method for the input plugin to specify which type of events it expects. + * This will guarantee that all events it receives via processEvent() are + * indeed of the given type, so it should be safe to cast to that type. + * + * @return The expected Class of the event. Only events of this class (and + * valid subclasses) will be handled. + * @since 2.0 + */ + Class getExpectedEventType(); + + /** + * Assign the target state system where this SCI will insert its state + * changes. Because of dependencies issues, this can normally not be done at + * the constructor. + * + * This needs to be called before .run()! + * + * @param ssb + * Target state system for the state changes generated by this + * input plugin + * @since 3.0 + */ + void assignTargetStateSystem(ITmfStateSystemBuilder ssb); + + /** + * Return the currently assigned target state system. + * + * @return Reference to the currently assigned state system, or null if no + * SS is assigned yet + * @since 3.0 + */ + ITmfStateSystem getAssignedStateSystem(); + + /** + * Send an event to this input plugin for processing. The implementation + * should check the contents, and call the state-modifying methods of its + * IStateSystemBuilder object accordingly. + * + * @param event + * The event (which should be safe to cast to the + * expectedEventType) that has to be processed. + */ + void processEvent(ITmfEvent event); + + /** + * Provide a non-initialized copy of this state input plugin. You will need + * to call {@link #assignTargetStateSystem} on it to assign its target. + * + * @return A new state change input object, of the same type, but without an + * assigned target state system + * @since 2.0 + */ + ITmfStateProvider getNewInstance(); + + /** + * Indicate to the state history building process that we are done (for now), + * and that it should close its current history. + */ + void dispose(); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statesystem/TmfStateSystemAnalysisModule.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statesystem/TmfStateSystemAnalysisModule.java new file mode 100644 index 0000000000..0c79f3179c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statesystem/TmfStateSystemAnalysisModule.java @@ -0,0 +1,501 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + * Bernd Hufmann - Integrated history builder functionality + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.statesystem; + +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.concurrent.CountDownLatch; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder; +import org.eclipse.linuxtools.statesystem.core.StateSystemFactory; +import org.eclipse.linuxtools.statesystem.core.backend.IStateHistoryBackend; +import org.eclipse.linuxtools.statesystem.core.backend.InMemoryBackend; +import org.eclipse.linuxtools.statesystem.core.backend.NullBackend; +import org.eclipse.linuxtools.statesystem.core.backend.historytree.HistoryTreeBackend; +import org.eclipse.linuxtools.statesystem.core.backend.historytree.ThreadedHistoryTreeBackend; +import org.eclipse.tracecompass.internal.tmf.core.statesystem.backends.partial.PartialHistoryBackend; +import org.eclipse.tracecompass.internal.tmf.core.statesystem.backends.partial.PartialStateSystem; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; + +/** + * Abstract analysis module to generate a state system. It is a base class that + * can be used as a shortcut by analysis who just need to build a single state + * system with a state provider. + * + * Analysis implementing this class should only need to provide a state system + * and optionally a backend (default to NULL) and, if required, a filename + * (defaults to the analysis'ID) + * + * @author Geneviève Bastien + * @since 3.0 + */ +@NonNullByDefault +public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisModule + implements ITmfAnalysisModuleWithStateSystems { + + private static final String EXTENSION = ".ht"; //$NON-NLS-1$ + + private final CountDownLatch fInitialized = new CountDownLatch(1); + + @Nullable private ITmfStateSystemBuilder fStateSystem; + @Nullable private ITmfStateProvider fStateProvider; + @Nullable private IStateHistoryBackend fHtBackend; + @Nullable private ITmfEventRequest fRequest; + + /** + * State system backend types + * + * @author Geneviève Bastien + */ + protected enum StateSystemBackendType { + /** Full history in file */ + FULL, + /** In memory state system */ + INMEM, + /** Null history */ + NULL, + /** State system backed with partial history */ + PARTIAL + } + + + /** + * Retrieve a state system belonging to trace, by passing the ID of the + * relevant analysis module. + * + * This will start the execution of the analysis module, and start the + * construction of the state system, if needed. + * + * @param trace + * The trace for which you want the state system + * @param moduleId + * The ID of the state system analysis module + * @return The state system, or null if there was no match + * @since 3.1 + */ + public static @Nullable ITmfStateSystem getStateSystem(ITmfTrace trace, String moduleId) { + TmfStateSystemAnalysisModule module = + trace.getAnalysisModuleOfClass(TmfStateSystemAnalysisModule.class, moduleId); + if (module != null) { + module.schedule(); + module.waitForInitialization(); + /* + * FIXME If we keep a reference to "module", the compiler expects us to + * close it. The Analysis Module's API should be reworked to not expose + * these objects directly (utility classes instead?) + */ + return module.getStateSystem(); + } + return null; + } + + /** + * Get the state provider for this analysis module + * + * @return the state provider + */ + protected abstract ITmfStateProvider createStateProvider(); + + /** + * Get the state system backend type used by this module + * + * @return The {@link StateSystemBackendType} + */ + protected StateSystemBackendType getBackendType() { + /* Using full history by default, sub-classes can override */ + return StateSystemBackendType.FULL; + } + + /** + * Get the supplementary file name where to save this state system. The + * default is the ID of the analysis followed by the extension. + * + * @return The supplementary file name + */ + protected String getSsFileName() { + return getId() + EXTENSION; + } + + /** + * Get the state system generated by this analysis, or null if it is not yet + * created. + * + * @return The state system + */ + @Nullable + public ITmfStateSystem getStateSystem() { + return fStateSystem; + } + + /** + * Block the calling thread until the analysis module has been initialized. + * After this method returns, {@link #getStateSystem()} should not return + * null anymore. + */ + public void waitForInitialization() { + try { + fInitialized.await(); + } catch (InterruptedException e) {} + } + + // ------------------------------------------------------------------------ + // TmfAbstractAnalysisModule + // ------------------------------------------------------------------------ + + @Override + protected boolean executeAnalysis(@Nullable final IProgressMonitor monitor) { + IProgressMonitor mon = (monitor == null ? new NullProgressMonitor() : monitor); + final ITmfStateProvider provider = createStateProvider(); + + String id = getId(); + + /* FIXME: State systems should make use of the monitor, to be cancelled */ + try { + /* Get the state system according to backend */ + StateSystemBackendType backend = getBackendType(); + String directory; + File htFile; + switch (backend) { + case FULL: + directory = TmfTraceManager.getSupplementaryFileDir(getTrace()); + htFile = new File(directory + getSsFileName()); + createFullHistory(id, provider, htFile); + break; + case PARTIAL: + directory = TmfTraceManager.getSupplementaryFileDir(getTrace()); + htFile = new File(directory + getSsFileName()); + createPartialHistory(id, provider, htFile); + break; + case INMEM: + createInMemoryHistory(id, provider); + break; + case NULL: + createNullHistory(id, provider); + break; + default: + break; + } + } catch (TmfTraceException e) { + return false; + } + return !mon.isCanceled(); + } + + @Override + protected void canceling() { + ITmfEventRequest req = fRequest; + if ((req != null) && (!req.isCompleted())) { + req.cancel(); + } + } + + @Override + public void dispose() { + super.dispose(); + if (fStateSystem != null) { + fStateSystem.dispose(); + } + } + + // ------------------------------------------------------------------------ + // History creation methods + // ------------------------------------------------------------------------ + + /* + * Load the history file matching the target trace. If the file already + * exists, it will be opened directly. If not, it will be created from + * scratch. + */ + private void createFullHistory(String id, ITmfStateProvider provider, File htFile) throws TmfTraceException { + + /* If the target file already exists, do not rebuild it uselessly */ + // TODO for now we assume it's complete. Might be a good idea to check + // at least if its range matches the trace's range. + + if (htFile.exists()) { + /* Load an existing history */ + final int version = provider.getVersion(); + try { + IStateHistoryBackend backend = new HistoryTreeBackend(htFile, version); + fHtBackend = backend; + fStateSystem = StateSystemFactory.newStateSystem(id, backend, false); + fInitialized.countDown(); + return; + } catch (IOException e) { + /* + * There was an error opening the existing file. Perhaps it was + * corrupted, perhaps it's an old version? We'll just + * fall-through and try to build a new one from scratch instead. + */ + } + } + + /* Size of the blocking queue to use when building a state history */ + final int QUEUE_SIZE = 10000; + + try { + IStateHistoryBackend backend = new ThreadedHistoryTreeBackend(htFile, + provider.getStartTime(), provider.getVersion(), QUEUE_SIZE); + fHtBackend = backend; + fStateSystem = StateSystemFactory.newStateSystem(id, backend); + provider.assignTargetStateSystem(fStateSystem); + build(provider); + } catch (IOException e) { + /* + * If it fails here however, it means there was a problem writing to + * the disk, so throw a real exception this time. + */ + throw new TmfTraceException(e.toString(), e); + } + } + + /* + * Create a new state system backed with a partial history. A partial + * history is similar to a "full" one (which you get with + * {@link #newFullHistory}), except that the file on disk is much smaller, + * but queries are a bit slower. + * + * Also note that single-queries are implemented using a full-query + * underneath, (which are much slower), so this might not be a good fit for + * a use case where you have to do lots of single queries. + */ + private void createPartialHistory(String id, ITmfStateProvider provider, File htPartialFile) + throws TmfTraceException { + /* + * The order of initializations is very tricky (but very important!) + * here. We need to follow this pattern: + * (1 is done before the call to this method) + * + * 1- Instantiate realStateProvider + * 2- Instantiate realBackend + * 3- Instantiate partialBackend, with prereqs: + * 3a- Instantiate partialProvider, via realProvider.getNew() + * 3b- Instantiate nullBackend (partialSS's backend) + * 3c- Instantiate partialSS + * 3d- partialProvider.assignSS(partialSS) + * 4- Instantiate realSS + * 5- partialSS.assignUpstream(realSS) + * 6- realProvider.assignSS(realSS) + * 7- Call HistoryBuilder(realProvider, realSS, partialBackend) to build the thing. + */ + + /* Size of the blocking queue to use when building a state history */ + final int QUEUE_SIZE = 10000; + + final long granularity = 50000; + + /* 2 */ + IStateHistoryBackend realBackend = null; + try { + realBackend = new ThreadedHistoryTreeBackend(htPartialFile, + provider.getStartTime(), provider.getVersion(), QUEUE_SIZE); + } catch (IOException e) { + throw new TmfTraceException(e.toString(), e); + } + + /* 3a */ + ITmfStateProvider partialProvider = provider.getNewInstance(); + + /* 3b-3c, constructor automatically uses a NullBackend */ + PartialStateSystem pss = new PartialStateSystem(); + + /* 3d */ + partialProvider.assignTargetStateSystem(pss); + + /* 3 */ + IStateHistoryBackend partialBackend = + new PartialHistoryBackend(partialProvider, pss, realBackend, granularity); + + /* 4 */ + @SuppressWarnings("restriction") + org.eclipse.linuxtools.internal.statesystem.core.StateSystem realSS = + (org.eclipse.linuxtools.internal.statesystem.core.StateSystem) StateSystemFactory.newStateSystem(id, partialBackend); + + /* 5 */ + pss.assignUpstream(realSS); + + /* 6 */ + provider.assignTargetStateSystem(realSS); + + /* 7 */ + fHtBackend = partialBackend; + fStateSystem = realSS; + + build(provider); + } + + /* + * Create a new state system using a null history back-end. This means that + * no history intervals will be saved anywhere, and as such only + * {@link ITmfStateSystem#queryOngoingState} will be available. + */ + private void createNullHistory(String id, ITmfStateProvider provider) { + IStateHistoryBackend backend = new NullBackend(); + fHtBackend = backend; + fStateSystem = StateSystemFactory.newStateSystem(id, backend); + provider.assignTargetStateSystem(fStateSystem); + build(provider); + } + + /* + * Create a new state system using in-memory interval storage. This should + * only be done for very small state system, and will be naturally limited + * to 2^31 intervals. + */ + private void createInMemoryHistory(String id, ITmfStateProvider provider) { + IStateHistoryBackend backend = new InMemoryBackend(provider.getStartTime()); + fHtBackend = backend; + fStateSystem = StateSystemFactory.newStateSystem(id, backend); + provider.assignTargetStateSystem(fStateSystem); + build(provider); + } + + private void disposeProvider(boolean deleteFiles) { + ITmfStateProvider provider = fStateProvider; + if (provider != null) { + provider.dispose(); + } + if (deleteFiles && (fHtBackend != null)) { + fHtBackend.removeFiles(); + } + } + + private void build(ITmfStateProvider provider) { + if ((fStateSystem == null) || (fHtBackend == null)) { + throw new IllegalArgumentException(); + } + + ITmfEventRequest request = fRequest; + if ((request != null) && (!request.isCompleted())) { + request.cancel(); + } + + request = new StateSystemEventRequest(provider); + provider.getTrace().sendRequest(request); + + /* + * Only now that we've actually started the build, we'll update the + * class fields, so that they become visible for other callers. + */ + fStateProvider = provider; + fRequest = request; + + /* + * The state system object is now created, we can consider this module + * "initialized" (components can retrieve it and start doing queries). + */ + fInitialized.countDown(); + + /* + * Block the executeAnalysis() construction is complete (so that the + * progress monitor displays that it is running). + */ + try { + request.waitForCompletion(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + private class StateSystemEventRequest extends TmfEventRequest { + private final ITmfStateProvider sci; + private final ITmfTrace trace; + + public StateSystemEventRequest(ITmfStateProvider sp) { + super(sp.getExpectedEventType(), + TmfTimeRange.ETERNITY, + 0, + ITmfEventRequest.ALL_DATA, + ITmfEventRequest.ExecutionType.BACKGROUND); + this.sci = sp; + + // sci.getTrace() will eventually return a @NonNull + @SuppressWarnings("null") + @NonNull ITmfTrace tr = sci.getTrace(); + trace = tr; + + } + + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + if (event.getTrace() == trace) { + sci.processEvent(event); + } else if (trace instanceof TmfExperiment) { + /* + * If the request is for an experiment, check if the event is + * from one of the child trace + */ + for (ITmfTrace childTrace : ((TmfExperiment) trace).getTraces()) { + if (childTrace == event.getTrace()) { + sci.processEvent(event); + } + } + } + } + + @Override + public void handleSuccess() { + super.handleSuccess(); + disposeProvider(false); + } + + @Override + public void handleCancel() { + super.handleCancel(); + disposeProvider(true); + } + + @Override + public void handleFailure() { + super.handleFailure(); + disposeProvider(true); + } + } + + // ------------------------------------------------------------------------ + // ITmfAnalysisModuleWithStateSystems + // ------------------------------------------------------------------------ + + @Override + @Nullable + public ITmfStateSystem getStateSystem(String id) { + if (id.equals(getId())) { + return fStateSystem; + } + return null; + } + + @Override + public Iterable getStateSystems() { + @SuppressWarnings("null") + @NonNull Iterable ret = Collections.singleton((ITmfStateSystem) fStateSystem); + return ret; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/ITmfStatistics.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/ITmfStatistics.java new file mode 100644 index 0000000000..e210d313bf --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/ITmfStatistics.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.statistics; + +import java.util.List; +import java.util.Map; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; + +/** + * Provider for statistics, which is assigned to a trace. This can be used to + * populate views like the Statistics View or the Histogram. + * + * As a guideline, since any trace type can use this interface, all timestamps + * should be normalized to nanoseconds when using these methods + * ({@link ITmfTimestamp#NANOSECOND_SCALE}). + * + * @author Alexandre Montplaisir + * @since 2.0 + */ +public interface ITmfStatistics { + + /** + * Run a histogram query on the statistics back-end. This means, return the + * total number of events in a series of 'nb' equal-sized ranges between + * 'start' and 'end'. As its name implies, this is typically used to fill + * the histogram data (where each range represents one pixel on the + * histogram). + * + * This method will block the caller until the results are returned, so it + * should not be called from a signal handler or from the UI thread. + * + * @param start + * Start time of the query + * @param end + * End time of the query + * @param nb + * The number of ranges to separate the complete time range into. + * It will be the size() of the returned array. + * @return The array representing the number of events found in each + * sub-range. + */ + List histogramQuery(long start, long end, int nb); + + /** + * Return the total number of events in the trace. + * + * @return The total number of events + */ + long getEventsTotal(); + + /** + * Return a Map of the total events in the trace, per event type. The event + * type should come from ITmfEvent.getType().getName(). + * + * @return The map of , for the whole trace + */ + Map getEventTypesTotal(); + + /** + * Retrieve the number of events in the trace in a given time interval. + * + * @param start + * Start time of the time range + * @param end + * End time of the time range + * @return The number of events found + */ + long getEventsInRange(long start, long end); + + /** + * Retrieve the number of events in the trace, per event type, in a given + * time interval. + * + * @param start + * Start time of the time range + * @param end + * End time of the time range + * @return The map of , for the given time range + */ + Map getEventTypesInRange(long start, long end); + + /** + * Notify the statistics back-end that the trace is being closed, so it + * should dispose itself as appropriate (release file descriptors, etc.) + */ + void dispose(); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfEventsStatistics.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfEventsStatistics.java new file mode 100644 index 0000000000..2c274b9627 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfEventsStatistics.java @@ -0,0 +1,285 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.statistics; + +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfLostEvent; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Implementation of ITmfStatistics which uses event requests to the trace to + * retrieve its information. + * + * There is almost no setup time, but queries themselves are longer than with a + * TmfStateStatistics. Queries are O(n * m), where n is the size of the trace, + * and m is the portion of the trace covered by the selected interval. + * + * @author Alexandre Montplaisir + * @since 2.0 + */ +public class TmfEventsStatistics implements ITmfStatistics { + + /* All timestamps should be stored in nanoseconds in the statistics backend */ + private static final int SCALE = ITmfTimestamp.NANOSECOND_SCALE; + + private final ITmfTrace trace; + + /* Event request objects for the time-range request. */ + private StatsTotalRequest totalRequest = null; + private StatsPerTypeRequest perTypeRequest = null; + + /** + * Constructor + * + * @param trace + * The trace for which we are building the statistics + */ + public TmfEventsStatistics(ITmfTrace trace) { + this.trace = trace; + } + + @Override + public void dispose() { + cancelOngoingRequests(); + } + + @Override + public List histogramQuery(long start, long end, int nb) { + final long[] borders = new long[nb]; + final long increment = (end - start) / nb; + + long curTime = start; + for (int i = 0; i < nb; i++) { + borders[i] = curTime; + curTime += increment; + } + + HistogramQueryRequest req = new HistogramQueryRequest(borders, end); + sendAndWait(req); + + List results = new LinkedList<>(req.getResults()); + return results; + + } + + private synchronized void cancelOngoingRequests() { + if (totalRequest != null && totalRequest.isRunning()) { + totalRequest.cancel(); + } + if (perTypeRequest != null && perTypeRequest.isRunning()) { + perTypeRequest.cancel(); + } + } + + @Override + public long getEventsTotal() { + StatsTotalRequest request = new StatsTotalRequest(trace, TmfTimeRange.ETERNITY); + sendAndWait(request); + + long total = request.getResult(); + return total; + } + + @Override + public Map getEventTypesTotal() { + StatsPerTypeRequest request = new StatsPerTypeRequest(trace, TmfTimeRange.ETERNITY); + sendAndWait(request); + + Map stats = request.getResults(); + return stats; + } + + @Override + public long getEventsInRange(long start, long end) { + ITmfTimestamp startTS = new TmfTimestamp(start, SCALE); + ITmfTimestamp endTS = new TmfTimestamp(end, SCALE); + TmfTimeRange range = new TmfTimeRange(startTS, endTS); + + StatsTotalRequest request = new StatsTotalRequest(trace, range); + sendAndWait(request); + + long total = request.getResult(); + return total; + } + + @Override + public Map getEventTypesInRange(long start, long end) { + ITmfTimestamp startTS = new TmfTimestamp(start, SCALE); + ITmfTimestamp endTS = new TmfTimestamp(end, SCALE); + TmfTimeRange range = new TmfTimeRange(startTS, endTS); + + StatsPerTypeRequest request = new StatsPerTypeRequest(trace, range); + sendAndWait(request); + + Map stats = request.getResults(); + return stats; + } + + private void sendAndWait(TmfEventRequest request) { + trace.sendRequest(request); + try { + request.waitForCompletion(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + + /** + * Event request to get the total number of events + */ + private class StatsTotalRequest extends TmfEventRequest { + + /* Total number of events the request has found */ + private long total; + + public StatsTotalRequest(ITmfTrace trace, TmfTimeRange range) { + super(trace.getEventType(), range, 0, ITmfEventRequest.ALL_DATA, + ITmfEventRequest.ExecutionType.BACKGROUND); + total = 0; + } + + public long getResult() { + return total; + } + + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + if (!(event instanceof ITmfLostEvent) && event.getTrace() == trace) { + total += 1; + } + } + } + + + /** + * Event request to get the counts per event type + */ + private class StatsPerTypeRequest extends TmfEventRequest { + + /* Map in which the results are saved */ + private final Map stats; + + public StatsPerTypeRequest(ITmfTrace trace, TmfTimeRange range) { + super(trace.getEventType(), range, 0, ITmfEventRequest.ALL_DATA, + ITmfEventRequest.ExecutionType.BACKGROUND); + this.stats = new HashMap<>(); + } + + public Map getResults() { + return stats; + } + + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + if (event.getTrace() == trace) { + String eventType = event.getType().getName(); + /* + * Special handling for lost events: instead of counting just + * one, we will count how many actual events it represents. + */ + if (event instanceof ITmfLostEvent) { + ITmfLostEvent le = (ITmfLostEvent) event; + incrementStats(eventType, le.getNbLostEvents()); + return; + } + + /* For standard event types, just increment by one */ + incrementStats(eventType, 1L); + } + } + + private void incrementStats(String key, long count) { + if (stats.containsKey(key)) { + long curValue = stats.get(key); + stats.put(key, curValue + count); + } else { + stats.put(key, count); + } + } + } + + /** + * Event request for histogram queries. It is much faster to do one event + * request then set the results accordingly than doing thousands of them one + * by one. + */ + private class HistogramQueryRequest extends TmfEventRequest { + + /** Map of */ + private final TreeMap results; + + /** + * New histogram request + * + * @param borders + * The array of borders (not including the end time). The + * first element should be the start time of the queries. + * @param endTime + * The end time of the query. Not used in the results map, + * but we need to know when to stop the event request. + */ + public HistogramQueryRequest(long[] borders, long endTime) { + super(trace.getEventType(), + new TmfTimeRange( + new TmfTimestamp(borders[0], SCALE), + new TmfTimestamp(endTime, SCALE)), + 0, + ITmfEventRequest.ALL_DATA, + ITmfEventRequest.ExecutionType.BACKGROUND); + + /* Prepare the results map, with all counts at 0 */ + results = new TreeMap<>(); + for (long border : borders) { + results.put(border, 0L); + } + } + + public Collection getResults() { + return results.values(); + } + + @Override + public void handleData(ITmfEvent event) { + super.handleData(event); + if (event.getTrace() == trace) { + long ts = event.getTimestamp().normalize(0, SCALE).getValue(); + Long key = results.floorKey(ts); + if (key != null) { + incrementValue(key); + } + } + } + + private void incrementValue(Long key) { + long value = results.get(key); + value++; + results.put(key, value); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStateStatistics.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStateStatistics.java new file mode 100644 index 0000000000..06afd44e6d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStateStatistics.java @@ -0,0 +1,323 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + * Patrick Tasse - Fix TimeRangeException + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.statistics; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; +import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; + +/** + * Implementation of ITmfStatistics which uses a state history for storing its + * information. In reality, it uses two state histories, one for "event totals" + * information (which should ideally use a fast backend), and another one for + * the rest (per event type, per CPU, etc.). + * + * Compared to the event-request-based statistics calculations, it adds the + * building the history first, but gives much faster response times once built : + * Queries are O(log n) wrt the size of the trace, and O(1) wrt to the size of + * the time interval selected. + * + * @author Alexandre Montplaisir + * @since 2.0 + */ +public class TmfStateStatistics implements ITmfStatistics { + + // ------------------------------------------------------------------------ + // Fields + // ------------------------------------------------------------------------ + + /** The event totals state system */ + private final ITmfStateSystem totalsStats; + + /** The state system for event types */ + private final ITmfStateSystem typesStats; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructor + * + * @param totals + * The state system containing the "totals" information + * @param eventTypes + * The state system containing the "event types" information + * @since 3.0 + */ + public TmfStateStatistics(@NonNull ITmfStateSystem totals, @NonNull ITmfStateSystem eventTypes) { + this.totalsStats = totals; + this.typesStats = eventTypes; + } + + /** + * Return the state system containing the "totals" values + * + * @return The "totals" state system + * @since 3.0 + */ + public ITmfStateSystem getTotalsSS() { + return totalsStats; + } + + /** + * Return the state system containing the "event types" values + * + * @return The "event types" state system + * @since 3.0 + */ + public ITmfStateSystem getEventTypesSS() { + return typesStats; + } + + // ------------------------------------------------------------------------ + // ITmfStatistics + // ------------------------------------------------------------------------ + + @Override + public void dispose() { + totalsStats.dispose(); + typesStats.dispose(); + } + + @Override + public List histogramQuery(final long start, final long end, final int nb) { + final List list = new LinkedList<>(); + final long increment = (end - start) / nb; + + if (totalsStats.isCancelled()) { + return list; + } + + /* + * We will do one state system query per "border", and save the + * differences between each border. + */ + long prevTotal = (start == totalsStats.getStartTime()) ? 0 : getEventCountAt(start); + long curTime = start + increment; + + long curTotal, count; + for (int i = 0; i < nb - 1; i++) { + curTotal = getEventCountAt(curTime); + count = curTotal - prevTotal; + list.add(count); + + curTime += increment; + prevTotal = curTotal; + } + + /* + * For the last bucket, we'll stretch its end time to the end time of + * the requested range, in case it got truncated down. + */ + curTotal = getEventCountAt(end); + count = curTotal - prevTotal; + list.add(count); + + return list; + } + + @Override + public long getEventsTotal() { + long endTime = totalsStats.getCurrentEndTime(); + int count = 0; + + try { + final int quark = totalsStats.getQuarkAbsolute(Attributes.TOTAL); + count= totalsStats.querySingleState(endTime, quark).getStateValue().unboxInt(); + + } catch (StateSystemDisposedException e) { + /* Assume there is no events for that range */ + return 0; + } catch (AttributeNotFoundException e) { + e.printStackTrace(); + } + + return count; + } + + @Override + public Map getEventTypesTotal() { + final Map map = new HashMap<>(); + long endTime = typesStats.getCurrentEndTime(); + + try { + /* Get the list of quarks, one for each even type in the database */ + int quark = typesStats.getQuarkAbsolute(Attributes.EVENT_TYPES); + List quarks = typesStats.getSubAttributes(quark, false); + + /* Since we want the total we can look only at the end */ + List endState = typesStats.queryFullState(endTime); + + String curEventName; + long eventCount; + for (int typeQuark : quarks) { + curEventName = typesStats.getAttributeName(typeQuark); + eventCount = endState.get(typeQuark).getStateValue().unboxInt(); + map.put(curEventName, eventCount); + } + + } catch (StateSystemDisposedException e) { + /* Assume there is no events, nothing will be put in the map. */ + } catch (AttributeNotFoundException e) { + e.printStackTrace(); + } + return map; + } + + @Override + public long getEventsInRange(long start, long end) { + long startCount; + if (start == totalsStats.getStartTime()) { + startCount = 0; + } else { + /* + * We want the events happening at "start" to be included, so we'll + * need to query one unit before that point. + */ + startCount = getEventCountAt(start - 1); + } + long endCount = getEventCountAt(end); + + return endCount - startCount; + } + + @Override + public Map getEventTypesInRange(long start, long end) { + final Map map = new HashMap<>(); + List quarks; + + /* Make sure the start/end times are within the state history, so we + * don't get TimeRange exceptions. + */ + long startTime = checkStartTime(start, typesStats); + long endTime = checkEndTime(end, typesStats); + if (endTime < startTime) { + /* The start/end times do not intersect this state system range. + * Return the empty map. */ + return map; + } + + try { + /* Get the list of quarks, one for each even type in the database */ + int quark = typesStats.getQuarkAbsolute(Attributes.EVENT_TYPES); + quarks = typesStats.getSubAttributes(quark, false); + } catch (AttributeNotFoundException e) { + /* + * The state system does not (yet?) have the needed attributes, it + * probably means there are no events counted yet. Return the empty + * map. + */ + return map; + } + + try { + List endState = typesStats.queryFullState(endTime); + + if (startTime == typesStats.getStartTime()) { + /* Only use the values picked up at the end time */ + for (int typeQuark : quarks) { + String curEventName = typesStats.getAttributeName(typeQuark); + long eventCount = endState.get(typeQuark).getStateValue().unboxInt(); + if (eventCount == -1) { + eventCount = 0; + } + map.put(curEventName, eventCount); + } + } else { + /* + * Query the start time at -1, so the beginning of the interval + * is inclusive. + */ + List startState = typesStats.queryFullState(startTime - 1); + for (int typeQuark : quarks) { + String curEventName = typesStats.getAttributeName(typeQuark); + long countAtStart = startState.get(typeQuark).getStateValue().unboxInt(); + long countAtEnd = endState.get(typeQuark).getStateValue().unboxInt(); + + if (countAtStart == -1) { + countAtStart = 0; + } + if (countAtEnd == -1) { + countAtEnd = 0; + } + long eventCount = countAtEnd - countAtStart; + map.put(curEventName, eventCount); + } + } + + } catch (StateSystemDisposedException e) { + /* Assume there is no (more) events, nothing will be put in the map. */ + } + return map; + } + + // ------------------------------------------------------------------------ + // Helper methods + // ------------------------------------------------------------------------ + + private long getEventCountAt(long timestamp) { + /* Make sure the target time is within the range of the history */ + long ts = checkStartTime(timestamp, totalsStats); + ts = checkEndTime(ts, totalsStats); + + try { + final int quark = totalsStats.getQuarkAbsolute(Attributes.TOTAL); + long count = totalsStats.querySingleState(ts, quark).getStateValue().unboxInt(); + return count; + + } catch (StateSystemDisposedException e) { + /* Assume there is no (more) events, nothing will be put in the map. */ + } catch (AttributeNotFoundException e) { + e.printStackTrace(); + } + + return 0; + } + + private static long checkStartTime(long initialStart, ITmfStateSystem ss) { + long start = initialStart; + if (start < ss.getStartTime()) { + return ss.getStartTime(); + } + return start; + } + + private static long checkEndTime(long initialEnd, ITmfStateSystem ss) { + long end = initialEnd; + if (end > ss.getCurrentEndTime()) { + return ss.getCurrentEndTime(); + } + return end; + } + + /** + * The attribute names that are used in the state provider + */ + public static class Attributes { + + /** Total nb of events */ + public static final String TOTAL = "total"; //$NON-NLS-1$ + + /** event_types */ + public static final String EVENT_TYPES = "event_types"; //$NON-NLS-1$< + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStatisticsEventTypesModule.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStatisticsEventTypesModule.java new file mode 100644 index 0000000000..dcfa11cbf2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStatisticsEventTypesModule.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.statistics; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfLostEvent; +import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.core.statistics.TmfStateStatistics.Attributes; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * The analysis module building the "event types" statistics state system. + * + * It is not in the extension point (and as such, not registered in the + * TmfAnalysisManager), as it is being handled by the TmfStatisticsModule. + * + * @author Alexandre Montplaisir + * @since 3.0 + */ +public class TmfStatisticsEventTypesModule extends TmfStateSystemAnalysisModule { + + /** + * The ID of this analysis module (which is also the ID of the state system) + */ + @NonNull + public static final String ID = "org.eclipse.linuxtools.tmf.statistics.types"; //$NON-NLS-1$ + + private static final String NAME = "TMF Statistics, events per type"; //$NON-NLS-1$ + + /** + * Constructor + */ + public TmfStatisticsEventTypesModule() { + super(); + setId(ID); + setName(NAME); + } + + @Override + protected ITmfStateProvider createStateProvider() { + return new StatsProviderEventTypes(getTrace()); + } + + @Override + protected String getSsFileName() { + return "statistics-types.ht"; //$NON-NLS-1$ + } + + + /** + * The state provider for traces statistics that use TmfStateStatistics. It + * should work with any trace type for which we can use the state system. + * + * It will store number of events seen, per event types. The resulting attribute + * tree will look like this: + * + *
+     * (root)
+     *   \-- event_types
+     *        |-- (event name 1)
+     *        |-- (event name 2)
+     *        |-- (event name 3)
+     *       ...
+     * 
+ * + * And each (event name)'s value will be an integer, representing how many times + * this particular event type has been seen in the trace so far. + * + * @author Alexandre Montplaisir + * @version 1.0 + */ + class StatsProviderEventTypes extends AbstractTmfStateProvider { + + /** + * Version number of this input handler. Please bump this if you modify the + * contents of the generated state history in some way. + */ + private static final int VERSION = 2; + + /** + * Constructor + * + * @param trace + * The trace for which we build this state system + */ + public StatsProviderEventTypes(ITmfTrace trace) { + super(trace, ITmfEvent.class ,"TMF Statistics, events per type"); //$NON-NLS-1$ + } + + @Override + public int getVersion() { + return VERSION; + } + + @Override + public StatsProviderEventTypes getNewInstance() { + return new StatsProviderEventTypes(this.getTrace()); + } + + @Override + protected void eventHandle(ITmfEvent event) { + int quark; + + /* Since this can be used for any trace types, normalize all the + * timestamp values to nanoseconds. */ + final long ts = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + + final String eventName = event.getType().getName(); + + try { + /* Special handling for lost events */ + if (event instanceof ITmfLostEvent) { + ITmfLostEvent le = (ITmfLostEvent) event; + quark = ss.getQuarkAbsoluteAndAdd(Attributes.EVENT_TYPES, eventName); + + int curVal = ss.queryOngoingState(quark).unboxInt(); + if (curVal == -1) { + curVal = 0; + } + + TmfStateValue value = TmfStateValue.newValueInt((int) (curVal + le.getNbLostEvents())); + ss.modifyAttribute(ts, value, quark); + return; + } + + /* Number of events of each type, globally */ + quark = ss.getQuarkAbsoluteAndAdd(Attributes.EVENT_TYPES, eventName); + ss.incrementAttribute(ts, quark); + +// /* Number of events per CPU */ +// quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATISTICS, Attributes.EVENT_TYPES, eventName); +// ss.incrementAttribute(ts, quark); + // +// /* Number of events per process */ +// quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATISTICS, Attributes.EVENT_TYPES, eventName); +// ss.incrementAttribute(ts, quark); + + } catch (StateValueTypeException | TimeRangeException | AttributeNotFoundException e) { + e.printStackTrace(); + } + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStatisticsModule.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStatisticsModule.java new file mode 100644 index 0000000000..6ab199a8df --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStatisticsModule.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.statistics; + +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.CountDownLatch; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfAnalysisModuleWithStateSystems; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Analysis module to compute the statistics of a trace. + * + * @author Alexandre Montplaisir + * @since 3.0 + */ +public class TmfStatisticsModule extends TmfAbstractAnalysisModule + implements ITmfAnalysisModuleWithStateSystems { + + /** ID of this analysis module */ + public static final String ID = "org.eclipse.linuxtools.tmf.core.statistics.analysis"; //$NON-NLS-1$ + + /** The trace's statistics */ + private ITmfStatistics fStatistics = null; + + private final TmfStateSystemAnalysisModule totalsModule = new TmfStatisticsTotalsModule(); + private final TmfStateSystemAnalysisModule eventTypesModule = new TmfStatisticsEventTypesModule(); + + private final CountDownLatch fInitialized = new CountDownLatch(1); + + /** + * Constructor + */ + public TmfStatisticsModule() { + super(); + } + + /** + * Get the statistics object built by this analysis + * + * @return The ITmfStatistics object + */ + @Nullable + public ITmfStatistics getStatistics() { + return fStatistics; + } + + /** + * Wait until the analyses/state systems underneath are ready to be queried. + */ + public void waitForInitialization() { + try { + fInitialized.await(); + } catch (InterruptedException e) {} + } + + // ------------------------------------------------------------------------ + // TmfAbstractAnalysisModule + // ------------------------------------------------------------------------ + + @Override + public void dispose() { + /* + * The sub-analyses are not registered to the trace directly, so we need + * to tell them when the trace is disposed. + */ + super.dispose(); + totalsModule.dispose(); + eventTypesModule.dispose(); + } + + @Override + public void setTrace(ITmfTrace trace) throws TmfAnalysisException { + super.setTrace(trace); + + /* + * Since these sub-analyzes are not built from an extension point, we + * have to assign the trace ourselves. Very important to do so before + * calling schedule()! + */ + totalsModule.setTrace(trace); + eventTypesModule.setTrace(trace); + } + + @Override + protected boolean executeAnalysis(IProgressMonitor monitor) throws TmfAnalysisException { + ITmfTrace trace = getTrace(); + if (trace == null) { + /* This analysis's trace should not be null when this is called */ + throw new IllegalStateException(); + } + + IStatus status1 = totalsModule.schedule(); + IStatus status2 = eventTypesModule.schedule(); + if (!(status1.isOK() && status2.isOK())) { + cancelSubAnalyses(); + return false; + } + + /* Wait until the two modules are initialized */ + totalsModule.waitForInitialization(); + eventTypesModule.waitForInitialization(); + + ITmfStateSystem totalsSS = totalsModule.getStateSystem(); + ITmfStateSystem eventTypesSS = eventTypesModule.getStateSystem(); + + if (totalsSS == null || eventTypesSS == null) { + /* Better safe than sorry... */ + throw new IllegalStateException(); + } + + fStatistics = new TmfStateStatistics(totalsSS, eventTypesSS); + + /* fStatistics is now set, consider this module initialized */ + fInitialized.countDown(); + + /* + * The rest of this "execute" will encompass the "execute" of the two + * sub-analyzes. + */ + if (!(totalsModule.waitForCompletion(monitor) && + eventTypesModule.waitForCompletion(monitor))) { + return false; + } + return true; + } + + @Override + protected void canceling() { + /* + * FIXME The "right" way to cancel state system construction is not + * available yet... + */ + cancelSubAnalyses(); + + ITmfStatistics stats = fStatistics; + if (stats != null) { + stats.dispose(); + } + } + + private void cancelSubAnalyses() { + totalsModule.cancel(); + eventTypesModule.cancel(); + } + + // ------------------------------------------------------------------------ + // ITmfStateSystemAnalysisModule + // ------------------------------------------------------------------------ + + @Override + public ITmfStateSystem getStateSystem(String id) { + switch (id) { + case TmfStatisticsTotalsModule.ID: + return totalsModule.getStateSystem(); + case TmfStatisticsEventTypesModule.ID: + return eventTypesModule.getStateSystem(); + default: + return null; + } + } + + @Override + public Iterable getStateSystems() { + List list = new LinkedList<>(); + list.add(totalsModule.getStateSystem()); + list.add(eventTypesModule.getStateSystem()); + return list; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStatisticsTotalsModule.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStatisticsTotalsModule.java new file mode 100644 index 0000000000..071e09b55b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStatisticsTotalsModule.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.statistics; + +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfLostEvent; +import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.core.statistics.TmfStateStatistics.Attributes; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * The analysis module building the "totals" statistics state system. + * + * It is not in the extension point (and as such, not registered in the + * TmfAnalysisManager), as it is being handled by the TmfStatisticsModule. + * + * @author Alexandre Montplaisir + * @since 3.0 + */ +public class TmfStatisticsTotalsModule extends TmfStateSystemAnalysisModule { + + /** + * The ID of this analysis module (which is also the ID of the state system) + */ + public static final String ID = "org.eclipse.linuxtools.tmf.statistics.totals"; //$NON-NLS-1$ + + private static final String NAME = "TMF Statistics, event totals"; //$NON-NLS-1$ + + /** + * Constructor + */ + public TmfStatisticsTotalsModule() { + super(); + setId(ID); + setName(NAME); + } + + @Override + protected ITmfStateProvider createStateProvider() { + return new StatsProviderTotals(getTrace()); + } + + @Override + protected String getSsFileName() { + return "statistics-totals.ht"; //$NON-NLS-1$ + } + + + /** + * The state provider for traces statistics that use TmfStateStatistics. It + * should work with any trace type for which we can use the state system. + * + * Only one attribute will be stored, containing the total of events seen so + * far. The resulting attribute tree will look like this: + * + *
+     * (root)
+     *   \-- total
+     * 
+ * + * @author Alexandre Montplaisir + * @version 1.0 + */ + class StatsProviderTotals extends AbstractTmfStateProvider { + + /** + * Version number of this input handler. Please bump this if you modify the + * contents of the generated state history in some way. + */ + private static final int VERSION = 2; + + /** + * Constructor + * + * @param trace + * The trace for which we build this state system + */ + public StatsProviderTotals(ITmfTrace trace) { + super(trace, ITmfEvent.class , NAME); + } + + @Override + public int getVersion() { + return VERSION; + } + + @Override + public StatsProviderTotals getNewInstance() { + return new StatsProviderTotals(this.getTrace()); + } + + @Override + protected void eventHandle(ITmfEvent event) { + /* Do not count lost events in the total */ + if (event instanceof ITmfLostEvent) { + return; + } + + /* Since this can be used for any trace types, normalize all the + * timestamp values to nanoseconds. */ + final long ts = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + + try { + /* Total number of events */ + int quark = ss.getQuarkAbsoluteAndAdd(Attributes.TOTAL); + ss.incrementAttribute(ts, quark); + + } catch (StateValueTypeException | TimeRangeException | AttributeNotFoundException e) { + e.printStackTrace(); + } + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/ITmfTimestampTransform.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/ITmfTimestampTransform.java new file mode 100644 index 0000000000..c86149afb1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/ITmfTimestampTransform.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.synchronization; + +import java.io.Serializable; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; + +/** + * This class contains a formula to transform the value of a timestamp, for + * example after trace synchronization + * + * @author Geneviève Bastien + * @since 3.0 + */ +public interface ITmfTimestampTransform extends Serializable { + + /** + * Transforms a timestamp + * + * @param timestamp + * The timestamp to transform + * @return the transformed timestamp + */ + ITmfTimestamp transform(ITmfTimestamp timestamp); + + /** + * Transforms a timestamp value + * + * @param timestamp + * The timestamp to transform in nanoseconds + * @return the transformed value + */ + long transform(long timestamp); + + /** + * Returns a timestamp transform that is the composition of two timestamp + * transforms. + * + * @param composeWith + * The transform to first apply on the timestamp before applying + * the current object + * @return A new timestamp transform object with the resulting composition. + */ + ITmfTimestampTransform composeWith(ITmfTimestampTransform composeWith); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/Messages.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/Messages.java new file mode 100644 index 0000000000..d2672768ca --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/Messages.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.synchronization; + +import org.eclipse.osgi.util.NLS; + +/** + * Messages class + * + * @since 3.0 + */ +@SuppressWarnings("javadoc") +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.core.synchronization.messages"; //$NON-NLS-1$ + public static String SyncAlgorithmFullyIncremental_absent; + public static String SyncAlgorithmFullyIncremental_alpha; + public static String SyncAlgorithmFullyIncremental_beta; + public static String SyncAlgorithmFullyIncremental_T_; + public static String SyncAlgorithmFullyIncremental_otherformula; + public static String SyncAlgorithmFullyIncremental_mult; + public static String SyncAlgorithmFullyIncremental_add; + public static String SyncAlgorithmFullyIncremental_ub; + public static String SyncAlgorithmFullyIncremental_lb; + public static String SyncAlgorithmFullyIncremental_accuracy; + public static String SyncAlgorithmFullyIncremental_accurate; + public static String SyncAlgorithmFullyIncremental_approx; + public static String SyncAlgorithmFullyIncremental_fail; + public static String SyncAlgorithmFullyIncremental_incomplete; + public static String SyncAlgorithmFullyIncremental_nbmatch; + public static String SyncAlgorithmFullyIncremental_nbacc; + public static String SyncAlgorithmFullyIncremental_refhost; + public static String SyncAlgorithmFullyIncremental_otherhost; + public static String SyncAlgorithmFullyIncremental_refformula; + public static String SyncAlgorithmFullyIncremental_NA; + public static String SyncAlgorithmFullyIncremental_quality; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java new file mode 100644 index 0000000000..57381248e5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java @@ -0,0 +1,626 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + * Francis Giraldeau - Transform computation using synchronization graph + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.synchronization; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.math.BigDecimal; +import java.math.MathContext; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.eclipse.tracecompass.internal.tmf.core.synchronization.graph.SyncSpanningTree; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.matching.TmfEventDependency; +import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform; +import org.eclipse.tracecompass.tmf.core.synchronization.Messages; +import org.eclipse.tracecompass.tmf.core.synchronization.SynchronizationAlgorithm; +import org.eclipse.tracecompass.tmf.core.synchronization.TimestampTransformFactory; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Class implementing fully incremental trace synchronization approach as + * described in + * + * Masoume Jabbarifar, Michel Dagenais and Alireza Shameli-Sendi, + * "Streaming Mode Incremental Clock Synchronization" + * + * Since the algorithm itself applies to two traces, it is implemented in a + * private class, while this public class manages the synchronization between + * all traces. + * + * @author Geneviève Bastien + * @since 3.0 + * @deprecated This class has been moved to internal. Use one of + * {@link SynchronizationAlgorithmFactory#getFullyIncrementalAlgorithm()} + * method to get this algorithm. + */ +@Deprecated +public class SyncAlgorithmFullyIncremental extends SynchronizationAlgorithm { + + /** + * Auto-generated serial UID + */ + private static final long serialVersionUID = -1782788842774838830L; + + private static final MathContext fMc = MathContext.DECIMAL128; + + /** @serial */ + private final List fSyncs; + + private SyncSpanningTree fTree = null; + + /** + * Initialization of the attributes + */ + public SyncAlgorithmFullyIncremental() { + fSyncs = new LinkedList<>(); + } + + /** + * Function called after all matching has been done, to do any post-match + * treatment. For this class, it calculates stats, while the data is + * available + */ + @Override + public void matchingEnded() { + getStats(); + } + + @Override + public void init(Collection traces) { + ITmfTrace[] traceArr = traces.toArray(new ITmfTrace[traces.size()]); + fSyncs.clear(); + /* Create a convex hull for all trace pairs */ + // FIXME: is it necessary to make ConvexHull for every pairs up-front? + // The ConvexHull seems to be created on the fly in processMatch(). + for (int i = 0; i < traceArr.length; i++) { + for (int j = i + 1; j < traceArr.length; j++) { + ConvexHull algo = new ConvexHull(traceArr[i].getHostId(), traceArr[j].getHostId()); + fSyncs.add(algo); + } + } + } + + @Override + protected void processMatch(TmfEventDependency match) { + String host1 = match.getSourceEvent().getTrace().getHostId(); + String host2 = match.getDestinationEvent().getTrace().getHostId(); + + /* Process only if source and destination are different */ + if (host1.equals(host2)) { + return; + } + + /* Check if a convex hull algorithm already exists for these 2 hosts */ + ConvexHull algo = null; + for (ConvexHull traceSync : fSyncs) { + if (traceSync.isForHosts(host1, host2)) { + algo = traceSync; + } + } + if (algo == null) { + algo = new ConvexHull(host1, host2); + fSyncs.add(algo); + } + algo.processMatch(match); + invalidateSyncGraph(); + } + + private void invalidateSyncGraph() { + fTree = null; + } + + @Override + public ITmfTimestampTransform getTimestampTransform(ITmfTrace trace) { + return getTimestampTransform(trace.getHostId()); + } + + @Override + public ITmfTimestampTransform getTimestampTransform(String hostId) { + SyncSpanningTree tree = getSyncTree(); + return tree.getTimestampTransform(hostId); + } + + /** + * Each convex hull computes the synchronization between 2 given hosts. A + * synchronization can be done on multiple hosts that may not all + * communicate with each other. We must use another algorithm to determine + * which host will be the reference node and what synchronization formula + * will be used between each host and this reference node. + * + * For example, take traces a, b and c where a and c talk to b but do not + * know each other ({@literal a <-> b <-> c}). The convex hulls will contain + * the formulae between their 2 traces, but if a is the reference node, then + * the resulting formula of c would be the composition of {@literal a <-> b} + * and {@literal b <-> c} + * + * @return The synchronization spanning tree for this synchronization + */ + private SyncSpanningTree getSyncTree() { + if (fTree == null) { + fTree = new SyncSpanningTree(); + for (ConvexHull traceSync : fSyncs) { + SyncQuality q = traceSync.getQuality(); + if (q == SyncQuality.ACCURATE || q == SyncQuality.APPROXIMATE) { + String from = traceSync.getReferenceHost(); + String to = traceSync.getOtherHost(); + fTree.addSynchronization(from, to, traceSync.getTimestampTransform(to), traceSync.getAccuracy()); + } + } + } + return fTree; + } + + @Override + public SyncQuality getSynchronizationQuality(ITmfTrace trace1, ITmfTrace trace2) { + for (ConvexHull traceSync : fSyncs) { + if (traceSync.isForHosts(trace1.getHostId(), trace2.getHostId())) { + return traceSync.getQuality(); + } + } + return SyncQuality.ABSENT; + } + + @Override + public boolean isTraceSynced(String hostId) { + ITmfTimestampTransform t = getTimestampTransform(hostId); + return !t.equals(TimestampTransformFactory.getDefaultTransform()); + } + + @Override + public Map> getStats() { + /* + * TODO: Stats, while still accurate, may be misleading now that the + * sync tree changes synchronization formula. The stats should use the + * tree instead + */ + Map> statmap = new LinkedHashMap<>(); + for (ConvexHull traceSync : fSyncs) { + statmap.put(traceSync.getReferenceHost() + " <==> " + traceSync.getOtherHost(), traceSync.getStats()); //$NON-NLS-1$ + } + return statmap; + } + + @Override + public String toString() { + StringBuilder b = new StringBuilder(); + b.append(getClass().getSimpleName() + " "); //$NON-NLS-1$ + b.append(fSyncs); + return b.toString(); + } + + /** + * This is the actual synchronization algorithm between two traces using + * convex hull + */ + private class ConvexHull implements Serializable { + + private static final long serialVersionUID = 8309351175030935291L; + + /** + * The list of meaningful points on the upper hull (received by the + * reference trace, below in a graph) + */ + private final LinkedList fUpperBoundList = new LinkedList<>(); + + /** + * The list of meaninful points on the lower hull (sent by the reference + * trace, above in a graph) + */ + private final LinkedList fLowerBoundList = new LinkedList<>(); + + /** Points forming the line with maximum slope */ + private final SyncPoint[] fLmax; + + /** Points forming the line with minimum slope */ + private final SyncPoint[] fLmin; + + /** + * Slopes and ordinate at origin of respectively fLmin, fLmax and the + * bisector + */ + private BigDecimal fAlphamin, fBetamax, fAlphamax, fBetamin, fAlpha, fBeta; + + private int fNbMatches, fNbAccurateMatches; + private String fReferenceHost = "", fOtherHost = ""; //$NON-NLS-1$//$NON-NLS-2$ + private SyncQuality fQuality; + + private Map fStats = new LinkedHashMap<>(); + + /** + * Initialization of the attributes + * + * @param host1 + * ID of the first host + * @param host2 + * ID of the second host + */ + public ConvexHull(String host1, String host2) { + if (host1.compareTo(host2) > 0) { + fReferenceHost = host2; + fOtherHost = host1; + } else { + fReferenceHost = host1; + fOtherHost = host2; + } + fLmax = new SyncPoint[2]; + fLmin = new SyncPoint[2]; + fAlpha = BigDecimal.ONE; + fAlphamax = BigDecimal.ONE; + fAlphamin = BigDecimal.ONE; + fBeta = BigDecimal.ZERO; + fBetamax = BigDecimal.ZERO; + fBetamin = BigDecimal.ZERO; + fNbMatches = 0; + fNbAccurateMatches = 0; + fQuality = SyncQuality.ABSENT; // default quality + } + + protected void processMatch(TmfEventDependency match) { + + LinkedList boundList, otherBoundList; + + SyncPoint[] line, otherLine; + SyncPoint p; + int inversionFactor = 1; + boolean qualify = false; + fNbMatches++; + + /* Initialize data depending on the which hull the match is part of */ + if (match.getSourceEvent().getTrace().getHostId().compareTo(match.getDestinationEvent().getTrace().getHostId()) > 0) { + boundList = fUpperBoundList; + otherBoundList = fLowerBoundList; + line = fLmin; + otherLine = fLmax; + p = new SyncPoint(match.getDestinationEvent(), match.getSourceEvent()); + inversionFactor = 1; + } else { + boundList = fLowerBoundList; + otherBoundList = fUpperBoundList; + line = fLmax; + otherLine = fLmin; + p = new SyncPoint(match.getSourceEvent(), match.getDestinationEvent()); + inversionFactor = -1; + } + + /* + * Does the message qualify for the hull, or is in on the wrong side + * of the reference line + */ + if ((line[0] == null) || (line[1] == null) || (p.crossProduct(line[0], line[1]) * inversionFactor > 0)) { + /* + * If message qualifies, verify if points need to be removed + * from the hull and add the new point as the maximum reference + * point for the line. Also clear the stats that are not good + * anymore + */ + fNbAccurateMatches++; + qualify = true; + removeUselessPoints(p, boundList, inversionFactor); + line[1] = p; + fStats.clear(); + } + + /* + * Adjust the boundary of the reference line and if one of the + * reference point of the other line was removed from the hull, also + * adjust the other line + */ + adjustBound(line, otherBoundList, inversionFactor); + if ((otherLine[1] != null) && !boundList.contains(otherLine[0])) { + adjustBound(otherLine, boundList, inversionFactor * -1); + } + + if (qualify) { + approximateSync(); + } + + } + + /** + * Calculates slopes and ordinate at origin of fLmax and fLmin to obtain + * and approximation of the synchronization at this time + */ + private void approximateSync() { + + /** + * Line slopes functions + * + * Lmax = alpha_max T + beta_min + * + * Lmin = alpha_min T + beta_max + */ + if ((fLmax[0] != null) || (fLmin[0] != null)) { + /** + * Do not recalculate synchronization after it is failed. We + * keep the last not failed result. + */ + if (getQuality() != SyncQuality.FAIL) { + BigDecimal alphamax = fLmax[1].getAlpha(fLmax[0]); + BigDecimal alphamin = fLmin[1].getAlpha(fLmin[0]); + SyncQuality quality = null; + + if ((fLmax[0] == null) || (fLmin[0] == null)) { + quality = SyncQuality.APPROXIMATE; + } + else if (alphamax.compareTo(alphamin) > 0) { + quality = SyncQuality.ACCURATE; + } else { + /* Lines intersect, not good */ + quality = SyncQuality.FAIL; + } + /* + * Only calculate sync if this match does not cause failure + * of synchronization + */ + if (quality != SyncQuality.FAIL) { + fAlphamax = alphamax; + fBetamin = fLmax[1].getBeta(fAlphamax); + fAlphamin = alphamin; + fBetamax = fLmin[1].getBeta(fAlphamin); + fAlpha = fAlphamax.add(fAlphamin).divide(BigDecimal.valueOf(2), fMc); + fBeta = fBetamin.add(fBetamax).divide(BigDecimal.valueOf(2), fMc); + } + setQuality(quality); + } + } else if (((fLmax[0] == null) && (fLmin[1] == null)) + || ((fLmax[1] == null) && (fLmin[0] == null))) { + /* Either there is no upper hull point or no lower hull */ + setQuality(SyncQuality.INCOMPLETE); + } + } + + /* + * Verify if the line should be adjusted to be more accurate give the + * hull + */ + private void adjustBound(SyncPoint[] line, LinkedList otherBoundList, int inversionFactor) { + SyncPoint minPoint = null, nextPoint; + boolean finishedSearch = false; + + /* + * Find in the other bound, the origin point of the line, start from + * the beginning if the point was lost + */ + int i = Math.max(0, otherBoundList.indexOf(line[0])); + + while ((i < otherBoundList.size() - 1) && !finishedSearch) { + minPoint = otherBoundList.get(i); + nextPoint = otherBoundList.get(i + 1); + + /* + * If the rotation (cross-product) is not optimal, move to next + * point as reference for the line (if available) + * + * Otherwise, the current minPoint is the minPoint of the line + */ + if (minPoint.crossProduct(nextPoint, line[1]) * inversionFactor > 0) { + if (nextPoint.getTimeX() < line[1].getTimeX()) { + i++; + } else { + line[0] = null; + finishedSearch = true; + } + } else { + line[0] = minPoint; + finishedSearch = true; + } + } + + if (line[0] == null) { + line[0] = minPoint; + } + + /* Make sure point 0 is before point 1 */ + if ((line[0] != null) && (line[0].getTimeX() > line[1].getTimeX())) { + line[0] = null; + } + } + + /* + * When a point qualifies to be in a hull, we verify if any of the + * existing points need to be removed from the hull + */ + private void removeUselessPoints(final SyncPoint p, final LinkedList boundList, final int inversionFactor) { + + boolean checkRemove = true; + + while (checkRemove && boundList.size() >= 2) { + if (p.crossProduct(boundList.get(boundList.size() - 2), boundList.getLast()) * inversionFactor > 0) { + boundList.removeLast(); + } else { + checkRemove = false; + } + } + boundList.addLast(p); + } + + public ITmfTimestampTransform getTimestampTransform(String hostId) { + if (hostId.equals(fOtherHost) && (getQuality() == SyncQuality.ACCURATE || getQuality() == SyncQuality.APPROXIMATE || getQuality() == SyncQuality.FAIL)) { + /* alpha: beta => 1 / fAlpha, -1 * fBeta / fAlpha); */ + return TimestampTransformFactory.createLinear(BigDecimal.ONE.divide(fAlpha, fMc), BigDecimal.valueOf(-1).multiply(fBeta).divide(fAlpha, fMc)); + } + return TimestampTransformFactory.getDefaultTransform(); + } + + public SyncQuality getQuality() { + return fQuality; + } + + public BigDecimal getAccuracy() { + return fAlphamax.subtract(fAlphamin); + } + + public Map getStats() { + if (fStats.size() == 0) { + String syncQuality; + switch (getQuality()) { + case ABSENT: + syncQuality = Messages.SyncAlgorithmFullyIncremental_absent; + break; + case ACCURATE: + syncQuality = Messages.SyncAlgorithmFullyIncremental_accurate; + break; + case APPROXIMATE: + syncQuality = Messages.SyncAlgorithmFullyIncremental_approx; + break; + case INCOMPLETE: + syncQuality = Messages.SyncAlgorithmFullyIncremental_incomplete; + break; + case FAIL: + default: + syncQuality = Messages.SyncAlgorithmFullyIncremental_fail; + break; + } + + fStats.put(Messages.SyncAlgorithmFullyIncremental_refhost, fReferenceHost); + fStats.put(Messages.SyncAlgorithmFullyIncremental_otherhost, fOtherHost); + fStats.put(Messages.SyncAlgorithmFullyIncremental_quality, syncQuality); + fStats.put(Messages.SyncAlgorithmFullyIncremental_alpha, fAlpha); + fStats.put(Messages.SyncAlgorithmFullyIncremental_beta, fBeta); + fStats.put(Messages.SyncAlgorithmFullyIncremental_ub, (fUpperBoundList.size() == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fUpperBoundList.size()); + fStats.put(Messages.SyncAlgorithmFullyIncremental_lb, (fLowerBoundList.size() == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fLowerBoundList.size()); + fStats.put(Messages.SyncAlgorithmFullyIncremental_accuracy, getAccuracy().doubleValue()); + fStats.put(Messages.SyncAlgorithmFullyIncremental_nbmatch, (fNbMatches == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fNbMatches); + fStats.put(Messages.SyncAlgorithmFullyIncremental_nbacc, (fNbAccurateMatches == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fNbAccurateMatches); + fStats.put(Messages.SyncAlgorithmFullyIncremental_refformula, Messages.SyncAlgorithmFullyIncremental_T_ + fReferenceHost); + fStats.put(Messages.SyncAlgorithmFullyIncremental_otherformula, fAlpha + Messages.SyncAlgorithmFullyIncremental_mult + Messages.SyncAlgorithmFullyIncremental_T_ + fReferenceHost + Messages.SyncAlgorithmFullyIncremental_add + fBeta); + } + return fStats; + + } + + public String getReferenceHost() { + return fReferenceHost; + } + + public String getOtherHost() { + return fOtherHost; + } + + public boolean isForHosts(String hostId1, String hostId2) { + return ((fReferenceHost.equals(hostId1) && fOtherHost.equals(hostId2)) || (fReferenceHost.equals(hostId2) && fOtherHost.equals(hostId1))); + } + + private void writeObject(ObjectOutputStream s) + throws IOException { + /* + * Remove calculation data because most of it is not serializable. + * We have the statistics anyway + */ + fUpperBoundList.clear(); + fLowerBoundList.clear(); + fLmin[0] = null; + fLmin[1] = null; + fLmax[0] = null; + fLmax[1] = null; + s.defaultWriteObject(); + } + + @SuppressWarnings("nls") + @Override + public String toString() { + StringBuilder b = new StringBuilder(); + b.append("Between " + fReferenceHost + " and " + fOtherHost + " ["); + b.append(" alpha " + fAlpha + " beta " + fBeta + " ]"); + return b.toString(); + } + + private void setQuality(SyncQuality fQuality) { + this.fQuality = fQuality; + } + + } + + /** + * Private class representing a point to synchronize on a graph. The x axis + * is the timestamp of the event from the reference trace while the y axis + * is the timestamp of the event on the other trace + */ + private class SyncPoint { + private final ITmfTimestamp x, y; + + public SyncPoint(ITmfEvent ex, ITmfEvent ey) { + x = ex.getTimestamp(); + y = ey.getTimestamp(); + } + + public long getTimeX() { + return x.getValue(); + } + + /** + * Calculate a cross product of 3 points: + * + * If the cross-product < 0, then p, pa, pb are clockwise + * + * If the cross-product > 0, then p, pa, pb are counter-clockwise + * + * If cross-product == 0, then they are in a line + * + * @param pa + * First point + * @param pb + * Second point + * @return The cross product + */ + public long crossProduct(SyncPoint pa, SyncPoint pb) { + long cp = ((pa.x.getValue() - x.getValue()) * (pb.y.getValue() - y.getValue()) - (pa.y.getValue() - y.getValue()) * (pb.x.getValue() - x.getValue())); + return cp; + } + + /* + * Gets the alpha (slope) between two points + */ + public BigDecimal getAlpha(SyncPoint p1) { + if (p1 == null) { + return BigDecimal.ONE; + } + BigDecimal deltay = BigDecimal.valueOf(y.getValue() - p1.y.getValue()); + BigDecimal deltax = BigDecimal.valueOf(x.getValue() - p1.x.getValue()); + if (deltax.equals(BigDecimal.ZERO)) { + return BigDecimal.ONE; + } + return deltay.divide(deltax, fMc); + } + + /* + * Get the beta value (when x = 0) of the line given alpha + */ + public BigDecimal getBeta(BigDecimal alpha) { + return BigDecimal.valueOf(y.getValue()).subtract(alpha.multiply(BigDecimal.valueOf(x.getValue()), fMc)); + } + + @Override + public String toString() { + return String.format("%s (%s, %s)", this.getClass().getCanonicalName(), x, y); //$NON-NLS-1$ + } + } + + private void writeObject(ObjectOutputStream s) + throws IOException { + /* + * Remove the tree because it is not serializable + */ + fTree = null; + s.defaultWriteObject(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SynchronizationAlgorithm.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SynchronizationAlgorithm.java new file mode 100644 index 0000000000..b07d4de4e7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SynchronizationAlgorithm.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.synchronization; + +import java.io.Serializable; +import java.util.Map; + +import org.eclipse.tracecompass.tmf.core.event.matching.TmfEventDependency; +import org.eclipse.tracecompass.tmf.core.event.matching.TmfEventMatches; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Abstract class for synchronization algorithm + * + * @author Geneviève Bastien + * @since 3.0 + */ +public abstract class SynchronizationAlgorithm extends TmfEventMatches implements Serializable { + + private static final long serialVersionUID = -3083906749528872196L; + + /** + * Quality of the result obtained by the synchronization algorithm + */ + public enum SyncQuality { + /** + * Algorithm returned a result satisfying all hypothesis for the + * algorithm + */ + ACCURATE, + /** + * Best effort of the algorithm + */ + APPROXIMATE, + /** + * There is communication only in one direction + */ + INCOMPLETE, + /** + * No communication between two traces + */ + ABSENT, + /** + * Hypothesis of the algorithm are not satisfied for some reason + */ + FAIL + } + + @Override + public void addMatch(TmfEventDependency match) { + super.addMatch(match); + processMatch(match); + } + + /** + * Function for synchronization algorithm to do something with the received + * match + * + * @param match + * The match of events + */ + protected abstract void processMatch(TmfEventDependency match); + + /** + * Returns a map of staticstics relating to this algorithm. Those stats + * could be used to be displayed in a view for example. + * + * @return A map of statistics for this algorithm + */ + public abstract Map> getStats(); + + /** + * Returns a timestamp transformation algorithm + * + * @param trace + * The trace to get the transform for + * @return The timestamp transformation formula + */ + public abstract ITmfTimestampTransform getTimestampTransform(ITmfTrace trace); + + /** + * Returns a timestamp transformation algorithm + * + * @param hostId + * The host ID of the trace to get the transform for + * @return The timestamp transformation formula + */ + public abstract ITmfTimestampTransform getTimestampTransform(String hostId); + + /** + * Gets the quality of the synchronization between two given traces + * + * @param trace1 + * First trace + * @param trace2 + * Second trace + * @return The synchronization quality + */ + public abstract SyncQuality getSynchronizationQuality(ITmfTrace trace1, ITmfTrace trace2); + + /** + * Returns whether a given trace has a synchronization formula that is not + * identity. This function returns true if the synchronization algorithm has + * failed for some reason + * + * @param hostId + * The host ID of the trace + * @return true if trace has formula + */ + public abstract boolean isTraceSynced(String hostId); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SynchronizationAlgorithmFactory.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SynchronizationAlgorithmFactory.java new file mode 100644 index 0000000000..a142208e31 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SynchronizationAlgorithmFactory.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.synchronization; + +import org.eclipse.tracecompass.internal.tmf.core.synchronization.SyncAlgorithmFullyIncremental; + +/** + * A factory to generate synchronization algorithm to synchronize traces + * + * @author Geneviève Bastien + * @since 3.2 + */ +public final class SynchronizationAlgorithmFactory { + + private SynchronizationAlgorithmFactory() { + + } + + /** + * Returns the system's default trace synchronization algorithm, ie the + * fully incremental convex hull synchronization algorithm. + * + * @return The default trace synchronization algorithm + */ + public static SynchronizationAlgorithm getDefaultAlgorithm() { + return new SyncAlgorithmFullyIncremental(); + } + + /** + * Returns the class implementing the fully incremental convex hull trace + * synchronization approach as described in + * + * Masoume Jabbarifar, Michel Dagenais and Alireza Shameli-Sendi, + * "Streaming Mode Incremental Clock Synchronization" + * + * @return The {@link SynchronizationAlgorithm} implementing the fully + * incremental convex hull synchronization algorithm + */ + public static SynchronizationAlgorithm getFullyIncrementalAlgorithm() { + return new SyncAlgorithmFullyIncremental(); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SynchronizationBackend.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SynchronizationBackend.java new file mode 100644 index 0000000000..372658edd6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SynchronizationBackend.java @@ -0,0 +1,196 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.synchronization; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; + +import org.eclipse.tracecompass.internal.tmf.core.Activator; + +/** + * Class to fetch and save synchronization information between traces + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class SynchronizationBackend { + + private static final int SYNC_FILE_MAGIC_NUMBER = 0x0DECAF00; + + private static final int FILE_VERSION = 1; + + private static final int HEADER_SIZE = 20; + + private final File fSyncFile; + + /** + * Constructor + * + * @param syncFile + * The file containing synchronization information + * @throws IOException + * If the file couldn't be opened for some reason + */ + public SynchronizationBackend(File syncFile) throws IOException { + this(syncFile, true); + } + + /** + * Constructor with possibility to tell whether to throw errors on exception + * or not + * + * @param syncFile + * The file containing synchronization information + * @param throwErrors + * Whether to throw exceptions or not + * @throws IOException + * If the file couldn't be opened for some reason + */ + public SynchronizationBackend(File syncFile, boolean throwErrors) throws IOException { + /* + * Open the file ourselves, get the header information we need, then + * pass on the descriptor. + */ + int res; + + fSyncFile = syncFile; + + if (syncFile == null) { + return; + } + + if (!syncFile.exists()) { + if (throwErrors) { + throw new IOException("Selected synchronization file does not exist"); //$NON-NLS-1$ + } + return; + } + if (syncFile.length() <= 0) { + if (throwErrors) { + throw new IOException("Invalid synchronization file selected, " + //$NON-NLS-1$ + "target file is empty"); //$NON-NLS-1$ + } + return; + } + + try (FileInputStream fis = new FileInputStream(syncFile); + FileChannel fc = fis.getChannel();) { + ByteBuffer buffer = ByteBuffer.allocate(HEADER_SIZE); + buffer.clear(); + fc.read(buffer); + buffer.flip(); + + /* + * Check the magic number,to make sure we're opening the right type + * of file + */ + res = buffer.getInt(); + if (res != SYNC_FILE_MAGIC_NUMBER) { + throw new IOException("Selected file does not" + //$NON-NLS-1$ + "look like a synchronization file"); //$NON-NLS-1$ + } + + res = buffer.getInt(); /* Major version number */ + if (res != FILE_VERSION) { + throw new IOException("Select synchronization file is of an older " //$NON-NLS-1$ + + "format. Synchronization will have to be computed again."); //$NON-NLS-1$ + } + + res = buffer.getInt(); /* Minor version number */ + } + } + + /** + * Opens an existing synchronization file + * + * @return The synchronization algorithm contained in the file + * @throws IOException + * Exception returned file functions + */ + public SynchronizationAlgorithm openExistingSync() throws IOException { + + if (fSyncFile == null) { + return null; + } + + try (/* Set the position after the header */ + FileInputStream fis = new FileInputStream(fSyncFile); + FileChannel fc = fis.getChannel().position(HEADER_SIZE); + /* Read the input stream */ + ObjectInputStream ois = new ObjectInputStream(fis);) { + + return (SynchronizationAlgorithm) ois.readObject(); + } catch (ClassNotFoundException e) { + return null; + } + + + } + + /** + * Saves the synchronization algorithm object to file + * + * @param syncAlgo + * The algorithm to save + * @throws FileNotFoundException + * propagate callee's exceptions + */ + public void saveSync(SynchronizationAlgorithm syncAlgo) throws FileNotFoundException { + + if (fSyncFile == null) { + return; + } + + /* Save the header of the file */ + try (FileOutputStream fos = new FileOutputStream(fSyncFile, false); + FileChannel fc = fos.getChannel();) { + + ByteBuffer buffer = ByteBuffer.allocate(HEADER_SIZE); + buffer.clear(); + + fc.position(0); + + buffer.putInt(SYNC_FILE_MAGIC_NUMBER); + + buffer.putInt(FILE_VERSION); + + buffer.flip(); + int res = fc.write(buffer); + assert (res <= HEADER_SIZE); + /* done writing the file header */ + + fc.position(HEADER_SIZE); + + try (ObjectOutputStream oos = new ObjectOutputStream(fos);) { + oos.writeObject(syncAlgo); + } + + } catch (FileNotFoundException e) { + /* Send this upwards */ + throw e; + } catch (IOException e) { + /* Handle other cases of IOException's */ + Activator.logError("Error saving trace synchronization data", e); //$NON-NLS-1$ + } + return; + + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SynchronizationManager.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SynchronizationManager.java new file mode 100644 index 0000000000..7c6c7e22c1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/SynchronizationManager.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.synchronization; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; + +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.component.TmfComponent; +import org.eclipse.tracecompass.tmf.core.event.matching.ITmfEventMatching; +import org.eclipse.tracecompass.tmf.core.event.matching.TmfNetworkEventMatching; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * This abstract manager class handles loading trace synchronization data or + * otherwise their calculation. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public abstract class SynchronizationManager extends TmfComponent { + + /** + * Function called to synchronize traces using the fully incremental + * synchronization algorithm + * + * @param syncFile + * The target name of the synchronization file. If it exists, it + * will be opened, otherwise it will be created and data from + * this synchro run will be saved there + * @param traces + * The list of traces to synchronize + * @param doSync + * Whether to actually synchronize or just try opening a sync + * file + * @return The synchronization object + */ + public static SynchronizationAlgorithm synchronizeTraces(final File syncFile, final Collection traces, boolean doSync) { + + SynchronizationAlgorithm syncAlgo; + if (doSync) { + syncAlgo = synchronize(syncFile, traces, SynchronizationAlgorithmFactory.getDefaultAlgorithm()); + } else { + syncAlgo = openExisting(syncFile); + if (syncAlgo == null) { + syncAlgo = SynchronizationAlgorithmFactory.getDefaultAlgorithm(); + } + } + return syncAlgo; + } + + /** + * Function called to synchronize traces with a specific synchronization + * algorithm. If a synchronization already exists, but is not the requested + * algorithm, the synchronization is done again using the new algorithm + * + * @param syncFile + * The target name of the synchronization file. If it exists, it + * will be opened, otherwise it will be created and data from + * this synchro run will be saved there + * @param traces + * The list of traces to synchronize + * @param algo + * A synchronization algorithm object to determine the algorithm + * used to synchronization. + * @param doSync + * Whether to actually synchronize or just try opening a sync + * file + * @return The synchronization object + */ + public static SynchronizationAlgorithm synchronizeTraces(final File syncFile, final Collection traces, SynchronizationAlgorithm algo, boolean doSync) { + + SynchronizationAlgorithm syncAlgo; + if (doSync) { + syncAlgo = synchronize(syncFile, traces, algo); + } else { + syncAlgo = openExisting(syncFile); + if (syncAlgo == null || (syncAlgo.getClass() != algo.getClass())) { + if (algo != null) { + syncAlgo = algo; + } else { + syncAlgo = SynchronizationAlgorithmFactory.getDefaultAlgorithm(); + } + } + } + + return syncAlgo; + } + + private static SynchronizationAlgorithm openExisting(final File syncFile) { + if ((syncFile != null) && syncFile.exists()) { + /* Load an existing history */ + try { + SynchronizationBackend syncBackend = new SynchronizationBackend(syncFile); + SynchronizationAlgorithm algo = syncBackend.openExistingSync(); + return algo; + } catch (IOException e) { + /* + * There was an error opening the existing file. Perhaps it was + * corrupted, perhaps it's an old version? We'll just + * fall-through and try to build a new one from scratch instead. + */ + Activator.logInfo("Problem opening existing trace synchronization file", e); //$NON-NLS-1$ + } + } + return null; + } + + private static SynchronizationAlgorithm synchronize(final File syncFile, final Collection traces, SynchronizationAlgorithm syncAlgo) { + ITmfEventMatching matching = new TmfNetworkEventMatching(traces, syncAlgo); + matching.matchEvents(); + + SynchronizationBackend syncBackend; + try { + syncBackend = new SynchronizationBackend(syncFile, false); + syncBackend.saveSync(syncAlgo); + } catch (IOException e) { + Activator.logError("Error while saving trace synchronization file", e); //$NON-NLS-1$ + } + return syncAlgo; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/TimestampTransformFactory.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/TimestampTransformFactory.java new file mode 100644 index 0000000000..bb916112cc --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/TimestampTransformFactory.java @@ -0,0 +1,208 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial implementation and API + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.core.synchronization; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.math.BigDecimal; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.internal.tmf.core.synchronization.TmfConstantTransform; +import org.eclipse.tracecompass.internal.tmf.core.synchronization.TmfTimestampTransform; +import org.eclipse.tracecompass.internal.tmf.core.synchronization.TmfTimestampTransformLinear; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; + +/** + * A factory to generate timestamp tranforms + * + * @author Matthew Khouzam + * @since 3.1 + */ +public final class TimestampTransformFactory { + + private static final String SYNCHRONIZATION_FORMULA_FILE = "sync_formula"; //$NON-NLS-1$ + + private TimestampTransformFactory() { + } + + /** + * Creates the identity timestamp transform + * + * @return The identity timestamp transform + */ + public static ITmfTimestampTransform getDefaultTransform() { + return TmfTimestampTransform.IDENTITY; + } + + /** + * Create an offsetted transform + * + * @param offset + * the offset in long format, nanosecond scale + * @return the offsetted transform + */ + public static ITmfTimestampTransform createWithOffset(long offset) { + if (offset == 0) { + return TmfTimestampTransform.IDENTITY; + } + return new TmfConstantTransform(offset); + } + + /** + * Create an offsetted transform + * + * @param offset + * the offset in a timestamp with scale + * @return the offsetted transform + */ + public static ITmfTimestampTransform createWithOffset(ITmfTimestamp offset) { + if (offset.getValue() == 0) { + return TmfTimestampTransform.IDENTITY; + } + return new TmfConstantTransform(offset); + } + + /** + * Create a timestamp transform corresponding to a linear equation, with + * slope and offset. The expected timestamp transform is such that f(t) = + * m*x + b, where m is the slope and b the offset. + * + * @param factor + * the slope + * @param offset + * the offset + * @return the transform + */ + public static ITmfTimestampTransform createLinear(double factor, ITmfTimestamp offset) { + if (factor == 1.0) { + return createWithOffset(offset); + } + return new TmfTimestampTransformLinear(factor, offset.normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue()); + } + + /** + * Create a timestamp transform corresponding to a linear equation, with + * slope and offset. The expected timestamp transform is such that f(t) = + * m*x + b, where m is the slope and b the offset. + * + * @param factor + * the slope + * @param offset + * the offset in nanoseconds + * @return the transform + */ + public static ITmfTimestampTransform createLinear(double factor, long offset) { + if (factor == 1.0) { + return createWithOffset(offset); + } + return new TmfTimestampTransformLinear(factor, offset); + } + + /** + * Create a timestamp transform corresponding to a linear equation, with + * slope and offset expressed in BigDecimal. The expected timestamp + * transform is such that f(t) = m*x + b, where m is the slope and b the + * offset. + * + * @param factor + * the slope + * @param offset + * the offset in nanoseconds + * @return the transform + */ + public static ITmfTimestampTransform createLinear(BigDecimal factor, BigDecimal offset) { + if (factor.equals(BigDecimal.ONE)) { + return createWithOffset(offset.longValueExact()); + } + return new TmfTimestampTransformLinear(factor, offset); + } + + /** + * Returns the file resource used to store synchronization formula. The file + * may not exist. + * + * @param resource + * the trace resource + * @return the synchronization file + */ + private static File getSyncFormulaFile(IResource resource) { + if (resource == null) { + return null; + } + try { + String supplDirectory = resource.getPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER); + return new File(supplDirectory + File.separator + SYNCHRONIZATION_FORMULA_FILE); + } catch (CoreException e) { + /* Ignored */ + } + return null; + } + + /** + * Returns the timestamp transform for a trace resource + * + * @param resource + * the trace resource + * @return the timestamp transform + * @since 3.2 + */ + public static ITmfTimestampTransform getTimestampTransform(IResource resource) { + File syncFile = getSyncFormulaFile(resource); + if (syncFile != null && syncFile.exists()) { + /* Read the serialized object from file */ + try (FileInputStream fis = new FileInputStream(syncFile); + ObjectInputStream ois = new ObjectInputStream(fis);) { + return (ITmfTimestampTransform) ois.readObject(); + } catch (ClassNotFoundException | IOException e) { + } + } + return TimestampTransformFactory.getDefaultTransform(); + } + + /** + * Sets the trace resource's timestamp transform + * + * @param resource + * the trace resource + * @param tt + * The timestamp transform for all timestamps of this trace, or + * null to clear it + * @since 3.2 + */ + public static void setTimestampTransform(IResource resource, ITmfTimestampTransform tt) { + /* Save the timestamp transform to a file */ + File syncFile = getSyncFormulaFile(resource); + if (syncFile != null) { + if (syncFile.exists()) { + syncFile.delete(); + } + if (tt == null) { + return; + } + /* Write the serialized object to file */ + try (FileOutputStream fos = new FileOutputStream(syncFile, false); + ObjectOutputStream oos = new ObjectOutputStream(fos);) { + oos.writeObject(tt); + } catch (IOException e1) { + Activator.logError("Error writing timestamp transform for trace", e1); //$NON-NLS-1$ + } + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/TmfTimestampTransform.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/TmfTimestampTransform.java new file mode 100644 index 0000000000..3ad21c5a01 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/TmfTimestampTransform.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.synchronization; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; + +/** + * A default simple, identity timestamp transform. It is a singleton class and + * returns the timestamp itself + * + * @author Geneviève Bastien + * @since 3.0 + * @deprecated This class has been moved to internal. Use one of + * {@link TimestampTransformFactory} methods to create the timestamp + * transform. For the identity, use + * {@link TimestampTransformFactory#getDefaultTransform()} + */ +@Deprecated +public class TmfTimestampTransform implements ITmfTimestampTransform { + + /** + * Generated serial UID + */ + private static final long serialVersionUID = -1480581417493073304L; + + /** + * The unique instance of this transform, since it is always the same + */ + public static final TmfTimestampTransform IDENTITY = new TmfTimestampTransform(); + + /** + * Default constructor + */ + protected TmfTimestampTransform() { + + } + + @Override + public ITmfTimestamp transform(ITmfTimestamp timestamp) { + return timestamp; + } + + @Override + public long transform(long timestamp) { + return timestamp; + } + + @Override + public ITmfTimestampTransform composeWith(ITmfTimestampTransform composeWith) { + /* Since this transform will not modify anything, return the other */ + return composeWith; + } + + @Override + public boolean equals(Object other) { + return other.getClass().equals(TmfTimestampTransform.class); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = (prime * result) + TmfTimestampTransform.class.hashCode(); + return result; + } + + @Override + public String toString() { + return "TmfTimestampTransform [ IDENTITY ]"; //$NON-NLS-1$ + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/TmfTimestampTransformLinear.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/TmfTimestampTransformLinear.java new file mode 100644 index 0000000000..79d39d16fe --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/TmfTimestampTransformLinear.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.synchronization; + +import java.math.BigDecimal; +import java.math.MathContext; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; + +/** + * Class implementing a linear timestamp transform, with a slope and/or offset + * + * f(t) = alpha*t + beta + * + * @author Geneviève Bastien + * @since 3.0 + * @deprecated This class has been moved to internal. Use one of + * {@link TimestampTransformFactory} methods to create the timestamp + * transform. It will return an optimized transform for the + * parameters given. To have a linear transform, use methods + * createLinear from the factory. + */ +@Deprecated +public class TmfTimestampTransformLinear implements ITmfTimestampTransform { + + /** + * Generated serial UID + */ + private static final long serialVersionUID = -4756608071358979461L; + + /** + * Respectively the slope and offset and this linear equation. + */ + private final BigDecimal fAlpha; + private final BigDecimal fBeta; + + private static final MathContext fMc = MathContext.DECIMAL128; + + /** + * Default constructor + */ + public TmfTimestampTransformLinear() { + fAlpha = BigDecimal.ONE; + fBeta = BigDecimal.ZERO; + } + + /** + * Constructor with alpha and beta + * + * @param alpha + * The slope of the linear transform + * @param beta + * The initial offset of the linear transform + */ + public TmfTimestampTransformLinear(final double alpha, final double beta) { + fAlpha = BigDecimal.valueOf(alpha); + fBeta = BigDecimal.valueOf(beta); + } + + /** + * Constructor with alpha and beta in big decimal + * + * @param fAlpha2 + * The slope of the linear transform + * @param fBeta2 + * The initial offset of the linear transform + */ + public TmfTimestampTransformLinear(final BigDecimal fAlpha2, final BigDecimal fBeta2) { + if (fAlpha2 != null) { + fAlpha = fAlpha2; + } else { + fAlpha = BigDecimal.ONE; + } + if (fBeta2 != null) { + fBeta = fBeta2; + } else { + fBeta = BigDecimal.ZERO; + } + } + + @Override + public ITmfTimestamp transform(ITmfTimestamp timestamp) { + BigDecimal newvalue = BigDecimal.valueOf(timestamp.getValue()).multiply(fAlpha, fMc).add(fBeta); + return new TmfTimestamp(timestamp, newvalue.longValue()); + } + + @Override + public long transform(long timestamp) { + BigDecimal t = BigDecimal.valueOf(timestamp).multiply(fAlpha, fMc).add(fBeta); + return t.longValue(); + } + + @Override + public ITmfTimestampTransform composeWith(ITmfTimestampTransform composeWith) { + if (composeWith.equals(TmfTimestampTransform.IDENTITY)) { + /* If composing with identity, just return this */ + return this; + } else if (composeWith instanceof TmfTimestampTransformLinear) { + /* If composeWith is a linear transform, add the two together */ + TmfTimestampTransformLinear ttl = (TmfTimestampTransformLinear) composeWith; + BigDecimal newAlpha = fAlpha.multiply(ttl.fAlpha, fMc); + BigDecimal newBeta = fAlpha.multiply(ttl.fBeta, fMc).add(fBeta); + return new TmfTimestampTransformLinear(newAlpha, newBeta); + } else { + /* + * We do not know what to do with this kind of transform, just + * return this + */ + return this; + } + } + + @Override + public boolean equals(Object other) { + boolean result = false; + if (other instanceof TmfTimestampTransformLinear) { + TmfTimestampTransformLinear that = (TmfTimestampTransformLinear) other; + result = ((that.fAlpha.equals(fAlpha)) && (that.fBeta.equals(fBeta))); + } + return result; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = (prime * result) + (fBeta.multiply(fAlpha).intValue()); + return result; + } + + @Override + public String toString() { + return "TmfTimestampLinear [ alpha = " + fAlpha.toString() + //$NON-NLS-1$ + ", beta = " + fBeta.toString() + //$NON-NLS-1$ + " ]"; //$NON-NLS-1$ + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/messages.properties b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/messages.properties new file mode 100644 index 0000000000..328fe23af4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/synchronization/messages.properties @@ -0,0 +1,32 @@ +############################################################################### +# Copyright (c) 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### +SyncAlgorithmFullyIncremental_absent=Absent +SyncAlgorithmFullyIncremental_alpha=Alpha +SyncAlgorithmFullyIncremental_beta=Beta +SyncAlgorithmFullyIncremental_T_=T_ +SyncAlgorithmFullyIncremental_otherformula=C_T1(t) +SyncAlgorithmFullyIncremental_mult=* +SyncAlgorithmFullyIncremental_add=\ + +SyncAlgorithmFullyIncremental_ub=Number of points in upper hull +SyncAlgorithmFullyIncremental_lb=Number of points in lower hull +SyncAlgorithmFullyIncremental_accuracy=Accuracy +SyncAlgorithmFullyIncremental_accurate=Accurate +SyncAlgorithmFullyIncremental_approx=Approximate +SyncAlgorithmFullyIncremental_fail=Fail +SyncAlgorithmFullyIncremental_incomplete=Incomplete +SyncAlgorithmFullyIncremental_nbmatch=Number of matching packets received +SyncAlgorithmFullyIncremental_nbacc=Number of accurate packets +SyncAlgorithmFullyIncremental_refhost=T0 +SyncAlgorithmFullyIncremental_otherhost=T1 +SyncAlgorithmFullyIncremental_refformula=C_T0(t) +SyncAlgorithmFullyIncremental_NA=N/A +SyncAlgorithmFullyIncremental_quality=Quality \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/ITmfTimePreferencesConstants.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/ITmfTimePreferencesConstants.java new file mode 100644 index 0000000000..7d0dcdc67b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/ITmfTimePreferencesConstants.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.timestamp; + +/** + * @since 2.1 + * @noimplement This interface is not intended to be implemented by clients. + */ +@SuppressWarnings({ "javadoc", "nls" }) +public interface ITmfTimePreferencesConstants { + public static final String TIME_FORMAT_PREF = "org.eclipse.linuxtools.tmf.core.prefs.time.format"; + public static final String DEFAULT_TIME_PATTERN = "HH:mm:ss.SSS SSS SSS"; + public static final String DATIME = TIME_FORMAT_PREF + ".datime"; + public static final String SUBSEC = TIME_FORMAT_PREF + ".subsec"; + public static final String TIME_ZONE = TIME_FORMAT_PREF + ".timezone"; + public static final String DATE_DELIMITER = TIME_FORMAT_PREF + ".date.delimiter"; + public static final String TIME_DELIMITER = TIME_FORMAT_PREF + ".time.delimiter"; + public static final String SSEC_DELIMITER = TIME_FORMAT_PREF + ".ssec.delimiter"; + public static final String DATE_YEAR_FMT = "yyyy-MM-dd HH:mm:ss"; + public static final String DATE_YEAR2_FMT = "yy-MM-dd HH:mm:ss"; + public static final String DATE_MONTH_FMT = "MM-dd HH:mm:ss"; + public static final String DATE_DAY_FMT = "dd HH:mm:ss"; + public static final String DATE_JDAY_FMT = "DDD HH:mm:ss"; + public static final String DATE_NO_FMT = "HH:mm:ss"; + public static final String TIME_HOUR_FMT = "HH:mm:ss"; + public static final String TIME_MINUTE_FMT = "mm:ss"; + public static final String TIME_SECOND_FMT = "ss"; + public static final String TIME_ELAPSED_FMT = "TTT"; + public static final String TIME_NO_FMT = ""; + public static final String SUBSEC_MILLI_FMT = "SSS"; + public static final String SUBSEC_MICRO_FMT = "SSS SSS"; + public static final String SUBSEC_NANO_FMT = "SSS SSS SSS"; + public static final String SUBSEC_NO_FMT = ""; + public static final String DELIMITER_NONE = ""; + public static final String DELIMITER_SPACE = " "; + public static final String DELIMITER_PERIOD = "."; + public static final String DELIMITER_COMMA = ","; + public static final String DELIMITER_DASH = "-"; + public static final String DELIMITER_UNDERLINE = "_"; + public static final String DELIMITER_COLON = ":"; + public static final String DELIMITER_SEMICOLON = ";"; + public static final String DELIMITER_SLASH = "/"; + public static final String DELIMITER_DQUOT = "\""; + /** @since 3.0 */ + public static final String DELIMITER_QUOTE = "''"; + /** @since 3.2*/ + public static final String LOCALE = TIME_FORMAT_PREF + ".locale"; +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/ITmfTimestamp.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/ITmfTimestamp.java new file mode 100644 index 0000000000..da7f6394aa --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/ITmfTimestamp.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.timestamp; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * The fundamental time reference in the TMF. + *

+ * It defines a generic timestamp interface in its most basic form: + *

    + *
  • timestamp = [value] * 10**[scale] +/- [precision] + *
+ * Where: + *
    + *
  • [value] is an unstructured integer value + *
  • [scale] is the magnitude of the value wrt some application-specific + * base unit (e.g. the second) + *
  • [precision] indicates the error on the value (useful for comparing + * timestamps in different scales). Default: 0. + *
+ * + * @author Francois Chouinard + * @version 2.0 + * @since 2.0 + * + * @see ITmfEvent + * @see TmfTimeRange + */ +public interface ITmfTimestamp extends Comparable { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The millisecond scale factor (10e0) + */ + public static final int SECOND_SCALE = 0; + + /** + * The millisecond scale factor (10e-3) + */ + public static final int MILLISECOND_SCALE = -3; + + /** + * The microsecond scale factor (10e-6) + */ + public static final int MICROSECOND_SCALE = -6; + + /** + * The nanosecond scale factor (10e-9) + */ + public static final int NANOSECOND_SCALE = -9; + + // ------------------------------------------------------------------------ + // Getters + // ------------------------------------------------------------------------ + + /** + * @return the timestamp value (magnitude) + */ + long getValue(); + + /** + * @return the timestamp scale (exponent) + */ + int getScale(); + + /** + * @return the timestamp precision (measurement tolerance) + */ + int getPrecision(); + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Normalize (adjust scale and offset) of the timestamp + * + * @param offset the offset to apply to the timestamp value (after scaling) + * @param scale the new timestamp scale + * @return a new 'adjusted' ITmfTimestamp + */ + ITmfTimestamp normalize(long offset, int scale); + + /** + * Compares [this] and [ts] within timestamp precision + * + * @param ts the other timestamp + * @param withinPrecision consider the precision when testing for equality + * @return -1, 0 or 1 (less than, equals, greater than) + */ + int compareTo(ITmfTimestamp ts, boolean withinPrecision); + + /** + * Returns the difference between [this] and [ts] as a timestamp + * + * @param ts the other timestamp + * @return the time difference (this - other) as an ITmfTimestamp + */ + ITmfTimestamp getDelta(ITmfTimestamp ts); + + /** + * Returns if this timestamp intersects the given time range. Borders are + * inclusive (for more fine-grained behavior, you can use + * {@link #compareTo(ITmfTimestamp)}. + * + * @param range + * The time range to compare to + * @return True if this timestamp is part of the time range, false if not + */ + boolean intersects(TmfTimeRange range); + + // ------------------------------------------------------------------------ + // Comparable + // ------------------------------------------------------------------------ + + @Override + int compareTo(ITmfTimestamp ts); + + /** + * Format the timestamp as per the format provided + * + * @param format the timestamp formatter + * @return the formatted timestamp + * @since 2.0 + */ + String toString(final TmfTimestampFormat format); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfNanoTimestamp.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfNanoTimestamp.java new file mode 100644 index 0000000000..8354522163 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfNanoTimestamp.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Modified from TmfSimpleTimestamp to use nanosecond scale + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.timestamp; + +/** + * A simplified timestamp where scale is nanoseconds and precision is set to 0. + * + * @since 2.1 + */ +public class TmfNanoTimestamp extends TmfTimestamp { + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor (value = 0) + */ + public TmfNanoTimestamp() { + this(0); + } + + /** + * Full constructor + * + * @param value the timestamp value + */ + public TmfNanoTimestamp(final long value) { + super(value, ITmfTimestamp.NANOSECOND_SCALE, 0); + } + + /** + * Copy constructor. + * + * If the parameter is not a TmfNanoTimestamp, the timestamp will be + * scaled to nanoseconds, and the precision will be discarded. + * + * @param timestamp + * The timestamp to copy + */ + public TmfNanoTimestamp(final ITmfTimestamp timestamp) { + super(timestamp.normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(), ITmfTimestamp.NANOSECOND_SCALE, 0); + } + + // ------------------------------------------------------------------------ + // ITmfTimestamp + // ------------------------------------------------------------------------ + + @Override + public ITmfTimestamp normalize(final long offset, final int scale) { + if (scale == ITmfTimestamp.NANOSECOND_SCALE) { + return new TmfNanoTimestamp(getValue() + offset); + } + return super.normalize(offset, scale); + } + + @Override + public int compareTo(final ITmfTimestamp ts, final boolean withinPrecision) { + if (ts instanceof TmfNanoTimestamp) { + final long delta = getValue() - ts.getValue(); + return (delta == 0) ? 0 : (delta > 0) ? 1 : -1; + } + return super.compareTo(ts, withinPrecision); + } + + @Override + public ITmfTimestamp getDelta(final ITmfTimestamp ts) { + if (ts instanceof TmfNanoTimestamp) { + return new TmfTimestampDelta(getValue() - ts.getValue(), ITmfTimestamp.NANOSECOND_SCALE); + } + return super.getDelta(ts); + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(final Object other) { + if (this == other) { + return true; + } + if (other == null) { + return false; + } + if (!(other instanceof TmfNanoTimestamp)) { + return super.equals(other); + } + final TmfNanoTimestamp ts = (TmfNanoTimestamp) other; + + return compareTo(ts, false) == 0; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfSimpleTimestamp.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfSimpleTimestamp.java new file mode 100644 index 0000000000..00c5e6fc8c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfSimpleTimestamp.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Standardize on the default toString() + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.timestamp; + +/** + * A simplified timestamp where scale and precision are set to 0. + * + * @author Francois Chouinard + * @version 1.1 + * @since 2.0 + */ +public class TmfSimpleTimestamp extends TmfTimestamp { + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor (value = 0) + */ + public TmfSimpleTimestamp() { + this(0); + } + + /** + * Full constructor + * + * @param value the timestamp value + */ + public TmfSimpleTimestamp(final long value) { + super(value, 0, 0); + } + + /** + * Copy constructor. + * + * If the parameter is not a TmfSimpleTimestamp, the timestamp will be + * scaled to seconds, and the precision will be discarded. + * + * @param timestamp + * The timestamp to copy + */ + public TmfSimpleTimestamp(final ITmfTimestamp timestamp) { + super(timestamp.normalize(0, ITmfTimestamp.SECOND_SCALE).getValue(), 0, 0); + } + + // ------------------------------------------------------------------------ + // ITmfTimestamp + // ------------------------------------------------------------------------ + + @Override + public ITmfTimestamp normalize(final long offset, final int scale) { + if (scale == 0) { + return new TmfSimpleTimestamp(getValue() + offset); + } + return super.normalize(offset, scale); + } + + @Override + public int compareTo(final ITmfTimestamp ts, final boolean withinPrecision) { + if (ts instanceof TmfSimpleTimestamp) { + final long delta = getValue() - ts.getValue(); + return (delta == 0) ? 0 : (delta > 0) ? 1 : -1; + } + return super.compareTo(ts, withinPrecision); + } + + @Override + public ITmfTimestamp getDelta(final ITmfTimestamp ts) { + if (ts instanceof TmfSimpleTimestamp) { + return new TmfTimestampDelta(getValue() - ts.getValue()); + } + return super.getDelta(ts); + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(final Object other) { + if (this == other) { + return true; + } + if (other == null) { + return false; + } + if (!(other instanceof TmfSimpleTimestamp)) { + return super.equals(other); + } + final TmfSimpleTimestamp ts = (TmfSimpleTimestamp) other; + + return compareTo(ts, false) == 0; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimePreferences.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimePreferences.java new file mode 100644 index 0000000000..9248201f1d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimePreferences.java @@ -0,0 +1,213 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Marc-Andre Laperle - Add time zone preference + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.timestamp; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.TimeZone; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.DefaultScope; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.tracecompass.internal.tmf.core.Activator; + +/** + * TMF Time format preferences + * + * @author Francois Chouinard + * @version 1.0 + * @since 2.1 + */ +public class TmfTimePreferences { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + private static final String DATIME_DEFAULT = ITmfTimePreferencesConstants.TIME_HOUR_FMT; + private static final String SUBSEC_DEFAULT = ITmfTimePreferencesConstants.SUBSEC_NANO_FMT; + private static final String DATE_DELIMITER_DEFAULT = ITmfTimePreferencesConstants.DELIMITER_DASH; + private static final String TIME_DELIMITER_DEFAULT = ITmfTimePreferencesConstants.DELIMITER_COLON; + private static final String SSEC_DELIMITER_DEFAULT = ITmfTimePreferencesConstants.DELIMITER_SPACE; + private static final String TIME_ZONE_DEFAULT = TimeZone.getDefault().getID(); + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private static TmfTimePreferences fPreferences; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Initialize the default preferences and the singleton + */ + public static void init() { + IEclipsePreferences defaultPreferences = DefaultScope.INSTANCE.getNode(Activator.PLUGIN_ID); + defaultPreferences.put(ITmfTimePreferencesConstants.DATIME, DATIME_DEFAULT); + defaultPreferences.put(ITmfTimePreferencesConstants.SUBSEC, SUBSEC_DEFAULT); + defaultPreferences.put(ITmfTimePreferencesConstants.DATE_DELIMITER, DATE_DELIMITER_DEFAULT); + defaultPreferences.put(ITmfTimePreferencesConstants.TIME_DELIMITER, TIME_DELIMITER_DEFAULT); + defaultPreferences.put(ITmfTimePreferencesConstants.SSEC_DELIMITER, SSEC_DELIMITER_DEFAULT); + defaultPreferences.put(ITmfTimePreferencesConstants.TIME_ZONE, TIME_ZONE_DEFAULT); + + // Create the singleton and update default formats + getInstance(); + } + + /** + * Get the TmfTimePreferences singleton + * + * @return The TmfTimePreferences instance + */ + public static synchronized TmfTimePreferences getInstance() { + if (fPreferences == null) { + fPreferences = new TmfTimePreferences(); + TmfTimestampFormat.updateDefaultFormats(); + } + return fPreferences; + } + + /** + * Local constructor + */ + private TmfTimePreferences() { + } + + // ------------------------------------------------------------------------ + // Getters/Setters + // ------------------------------------------------------------------------ + + /** + * Return the timestamp pattern + * + * @return the timestamp pattern + */ + public String getTimePattern() { + return computeTimePattern(getPreferenceMap(false)); + } + + /** + * Return the interval pattern + * + * @return the interval pattern + */ + public String getIntervalPattern() { + return computeIntervalPattern(getPreferenceMap(false)); + } + + /** + * Get the time zone + * + * @return the time zone + */ + public TimeZone getTimeZone() { + return TimeZone.getTimeZone(Platform.getPreferencesService().getString(Activator.PLUGIN_ID, ITmfTimePreferencesConstants.TIME_ZONE, TimeZone.getDefault().getID(), null)); + } + + /** + * Get the locale + * + * @return the locale + * @since 3.2 + */ + public Locale getLocale() { + return Locale.forLanguageTag(Platform.getPreferencesService().getString(Activator.PLUGIN_ID, ITmfTimePreferencesConstants.LOCALE, Locale.getDefault().toLanguageTag(), null)); + } + + /** + * Get the default preferences map + * + * @return a collection containing the default preferences + */ + public Map getDefaultPreferenceMap() { + return getPreferenceMap(true); + } + + /** + * Get the current preferences map + * + * @return a collection containing the current preferences + */ + public Map getPreferenceMap() { + return getPreferenceMap(false); + } + + private static Map getPreferenceMap(boolean defaultValues) { + Map prefsMap = new HashMap<>(); + IEclipsePreferences prefs = defaultValues ? DefaultScope.INSTANCE.getNode(Activator.PLUGIN_ID) : InstanceScope.INSTANCE.getNode(Activator.PLUGIN_ID); + prefToMap(prefs, prefsMap, ITmfTimePreferencesConstants.SUBSEC, SUBSEC_DEFAULT); + prefToMap(prefs, prefsMap, ITmfTimePreferencesConstants.TIME_DELIMITER, TIME_DELIMITER_DEFAULT); + prefToMap(prefs, prefsMap, ITmfTimePreferencesConstants.SSEC_DELIMITER, SSEC_DELIMITER_DEFAULT); + prefToMap(prefs, prefsMap, ITmfTimePreferencesConstants.DATIME, DATIME_DEFAULT); + prefToMap(prefs, prefsMap, ITmfTimePreferencesConstants.DATE_DELIMITER, DATE_DELIMITER_DEFAULT); + return prefsMap; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + private static String computeIntervalPattern(Map prefsMap) { + String ssecFmt = computeSubSecFormat(prefsMap); + return ITmfTimePreferencesConstants.TIME_ELAPSED_FMT + "." + ssecFmt; //$NON-NLS-1$ + } + + private static String computeSubSecFormat(Map prefsMap) { + String sSecFormat = prefsMap.get(ITmfTimePreferencesConstants.SUBSEC); + String sSecFieldSep = prefsMap.get(ITmfTimePreferencesConstants.SSEC_DELIMITER); + String ssecFmt = sSecFormat.replaceAll(" ", sSecFieldSep); //$NON-NLS-1$ + return ssecFmt; + } + + private static void prefToMap(IEclipsePreferences node, Map prefsMap, String key, String defaultValue) { + prefsMap.put(key, node.get(key, defaultValue)); + } + + /** + * Compute the time pattern with the collection of preferences + * + * @param prefsMap the preferences to apply when computing the time pattern + * @return the time pattern resulting in applying the preferences + */ + public String computeTimePattern(Map prefsMap) { + String dateTimeFormat = prefsMap.get(ITmfTimePreferencesConstants.DATIME); + if (dateTimeFormat == null) { + dateTimeFormat = ITmfTimePreferencesConstants.DEFAULT_TIME_PATTERN; + } + + String dateFormat; + String timeFormat; + int index = dateTimeFormat.indexOf(' '); + if (index != -1) { + dateFormat = dateTimeFormat.substring(0, dateTimeFormat.indexOf(' ') + 1); + timeFormat = dateTimeFormat.substring(dateFormat.length()); + } else { + dateFormat = ""; //$NON-NLS-1$ + timeFormat = dateTimeFormat; + } + + String dateFieldSep = prefsMap.get(ITmfTimePreferencesConstants.DATE_DELIMITER); + String timeFieldSep = prefsMap.get(ITmfTimePreferencesConstants.TIME_DELIMITER); + String dateFmt = dateFormat.replaceAll("-", dateFieldSep); //$NON-NLS-1$ + String timeFmt = timeFormat.replaceAll(":", timeFieldSep); //$NON-NLS-1$ + + String ssecFmt = computeSubSecFormat(prefsMap); + return dateFmt + timeFmt + (ssecFmt.equals(ITmfTimePreferencesConstants.SUBSEC_NO_FMT) ? "" : '.' + ssecFmt); //$NON-NLS-1$; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimeRange.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimeRange.java new file mode 100644 index 0000000000..1bb0cff9e3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimeRange.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Updated as per TMF Event Model 1.0 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.timestamp; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * A utility class to define and manage time ranges. + * + * @author Francois Chouinard + * @version 1.0 + * @since 2.0 + * + * @see ITmfTimestamp + */ +public class TmfTimeRange { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The full possible time range + */ + public static final @NonNull TmfTimeRange ETERNITY = new EternityTimeRange(); + + /** + * The null time range + */ + public static final @NonNull TmfTimeRange NULL_RANGE = new TmfTimeRange(); + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final ITmfTimestamp fStartTime; + private final ITmfTimestamp fEndTime; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + private TmfTimeRange() { + fStartTime = TmfTimestamp.BIG_BANG; + fEndTime = TmfTimestamp.BIG_BANG; + } + + /** + * Full constructor + * + * @param startTime start of the time range + * @param endTime end of the time range + */ + public TmfTimeRange(final ITmfTimestamp startTime, final ITmfTimestamp endTime) { + if (startTime == null || endTime == null) { + throw new IllegalArgumentException(); + } + fStartTime = startTime; + fEndTime = endTime; + } + + /** + * Copy constructor + * + * @param range the other time range + */ + public TmfTimeRange(final TmfTimeRange range) { + if (range == null) { + throw new IllegalArgumentException(); + } + fStartTime = range.getStartTime(); + fEndTime = range.getEndTime(); + } + + // ------------------------------------------------------------------------ + // Getters + // ------------------------------------------------------------------------ + + /** + * @return the time range start time + */ + public ITmfTimestamp getStartTime() { + return fStartTime; + } + + /** + * @return the time range end time + */ + public ITmfTimestamp getEndTime() { + return fEndTime; + } + + // ------------------------------------------------------------------------ + // Predicates + // ------------------------------------------------------------------------ + + /** + * Check if the timestamp is within the time range + * + * @param ts + * The timestamp to check + * @return True if [startTime] <= [ts] <= [endTime] + */ + public boolean contains(final ITmfTimestamp ts) { + return (fStartTime.compareTo(ts, true) <= 0) && (fEndTime.compareTo(ts, true) >= 0); + } + + /** + * Check if the time range is within the time range + * + * @param range + * The other time range + * @return True if [range] is fully contained + */ + public boolean contains(final TmfTimeRange range) { + final ITmfTimestamp startTime = range.getStartTime(); + final ITmfTimestamp endTime = range.getEndTime(); + return (fStartTime.compareTo(startTime, true) <= 0) && (fEndTime.compareTo(endTime, true) >= 0); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Get intersection of two time ranges + * + * @param range the other time range + * @return the intersection time range, or null if no intersection exists + */ + public TmfTimeRange getIntersection(final TmfTimeRange range) { + if (fStartTime.compareTo(range.fEndTime, true) > 0 || fEndTime.compareTo(range.fStartTime, true) < 0) { + return null; // no intersection + } + + return new TmfTimeRange(fStartTime.compareTo(range.fStartTime, true) < 0 + ? range.fStartTime + : fStartTime, fEndTime.compareTo(range.fEndTime, true) > 0 + ? range.fEndTime + : fEndTime); + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + fEndTime.hashCode(); + result = prime * result + fStartTime.hashCode(); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof TmfTimeRange)) { + return false; + } + final TmfTimeRange other = (TmfTimeRange) obj; + if (!fEndTime.equals(other.fEndTime)) { + return false; + } + if (!fStartTime.equals(other.fStartTime)) { + return false; + } + return true; + } + + @Override + @SuppressWarnings("nls") + public String toString() { + return "TmfTimeRange [fStartTime=" + fStartTime + ", fEndTime=" + fEndTime + "]"; + } + + // ------------------------------------------------------------------------ + // Inner classes + // ------------------------------------------------------------------------ + + /** + * "Eternity" time range, representing the largest time range possible, + * which includes any other time range or timestamp. + */ + private static final class EternityTimeRange extends TmfTimeRange { + + public EternityTimeRange() { + super(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); + } + + @Override + public boolean contains(ITmfTimestamp ts) { + return true; + } + + @Override + public boolean contains(TmfTimeRange range) { + return true; + } + + @Override + public TmfTimeRange getIntersection(TmfTimeRange range) { + return range; + } + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimestamp.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimestamp.java new file mode 100644 index 0000000000..033ed0b8ac --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimestamp.java @@ -0,0 +1,384 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Thomas Gatterweh - Updated scaling / synchronization + * Francois Chouinard - Refactoring to align with TMF Event Model 1.0 + * Francois Chouinard - Implement augmented interface + * Geneviève Bastien - Added copy constructor with new value + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.timestamp; + +import java.nio.ByteBuffer; + +/** + * A generic timestamp implementation. The timestamp is represented by the + * tuple { value, scale, precision }. By default, timestamps are scaled in + * seconds. + * + * @author Francois Chouinard + * @version 1.1 + * @since 2.0 + */ +public class TmfTimestamp implements ITmfTimestamp { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The beginning of time + */ + public static final ITmfTimestamp BIG_BANG = + new TmfTimestamp(Long.MIN_VALUE, Integer.MAX_VALUE, 0); + + /** + * The end of time + */ + public static final ITmfTimestamp BIG_CRUNCH = + new TmfTimestamp(Long.MAX_VALUE, Integer.MAX_VALUE, 0); + + /** + * A more practical definition of "beginning of time" + */ + public static final ITmfTimestamp PROJECT_IS_FUNDED = BIG_BANG; + + /** + * A more practical definition of "end of time" + */ + public static final ITmfTimestamp PROJECT_IS_CANNED = BIG_CRUNCH; + + /** + * Zero + */ + public static final ITmfTimestamp ZERO = + new TmfTimestamp(0, 0, 0); + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The timestamp raw value (mantissa) + */ + private final long fValue; + + /** + * The timestamp scale (magnitude) + */ + private final int fScale; + + /** + * The value precision (tolerance) + */ + private final int fPrecision; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + public TmfTimestamp() { + this(0, ITmfTimestamp.SECOND_SCALE, 0); + } + + /** + * Simple constructor (scale = precision = 0) + * + * @param value the timestamp value + */ + public TmfTimestamp(final long value) { + this(value, ITmfTimestamp.SECOND_SCALE, 0); + } + + /** + * Simple constructor (precision = 0) + * + * @param value the timestamp value + * @param scale the timestamp scale + */ + public TmfTimestamp(final long value, final int scale) { + this(value, scale, 0); + } + + /** + * Full constructor + * + * @param value the timestamp value + * @param scale the timestamp scale + * @param precision the timestamp precision + */ + public TmfTimestamp(final long value, final int scale, final int precision) { + fValue = value; + fScale = scale; + fPrecision = Math.abs(precision); + } + + /** + * Copy constructor + * + * @param timestamp the timestamp to copy + */ + public TmfTimestamp(final ITmfTimestamp timestamp) { + if (timestamp == null) { + throw new IllegalArgumentException(); + } + fValue = timestamp.getValue(); + fScale = timestamp.getScale(); + fPrecision = timestamp.getPrecision(); + } + + /** + * Copies a timestamp but with a new time value + * + * @param timestamp + * The timestamp to copy + * @param newvalue + * The value the new timestamp will have + * @since 3.0 + */ + public TmfTimestamp(ITmfTimestamp timestamp, long newvalue) { + if (timestamp == null) { + throw new IllegalArgumentException(); + } + fValue = newvalue; + fScale = timestamp.getScale(); + fPrecision = timestamp.getPrecision(); + } + + // ------------------------------------------------------------------------ + // ITmfTimestamp + // ------------------------------------------------------------------------ + + /** + * Construct the timestamp from the ByteBuffer. + * + * @param bufferIn + * the buffer to read from + * + * @since 3.0 + */ + public TmfTimestamp(ByteBuffer bufferIn) { + this(bufferIn.getLong(), bufferIn.getInt(), bufferIn.getInt()); + } + + @Override + public long getValue() { + return fValue; + } + + @Override + public int getScale() { + return fScale; + } + + @Override + public int getPrecision() { + return fPrecision; + } + + private static final long scalingFactors[] = new long[] { + 1L, + 10L, + 100L, + 1000L, + 10000L, + 100000L, + 1000000L, + 10000000L, + 100000000L, + 1000000000L, + 10000000000L, + 100000000000L, + 1000000000000L, + 10000000000000L, + 100000000000000L, + 1000000000000000L, + 10000000000000000L, + 100000000000000000L, + 1000000000000000000L, + }; + + @Override + public ITmfTimestamp normalize(final long offset, final int scale) { + + long value = fValue; + int precision = fPrecision; + + // Handle the trivial case + if (fScale == scale && offset == 0) { + return this; + } + + // In case of big bang and big crunch just return this (no need to normalize) + if (this.equals(BIG_BANG) || this.equals(BIG_CRUNCH)) { + return this; + } + + // First, scale the timestamp + if (fScale != scale) { + final int scaleDiff = Math.abs(fScale - scale); + if (scaleDiff >= scalingFactors.length) { + throw new ArithmeticException("Scaling exception"); //$NON-NLS-1$ + } + + final long scalingFactor = scalingFactors[scaleDiff]; + if (scale < fScale) { + value *= scalingFactor; + precision *= scalingFactor; + } else { + value /= scalingFactor; + precision /= scalingFactor; + } + } + + // Then, apply the offset + if (offset < 0) { + value = (value < Long.MIN_VALUE - offset) ? Long.MIN_VALUE : value + offset; + } else { + value = (value > Long.MAX_VALUE - offset) ? Long.MAX_VALUE : value + offset; + } + + return new TmfTimestamp(value, scale, precision); + } + + @Override + public int compareTo(final ITmfTimestamp ts, final boolean withinPrecision) { + + // Check the corner cases (we can't use equals() because it uses compareTo()...) + if (ts == null) { + return 1; + } + if (this == ts || (fValue == ts.getValue() && fScale == ts.getScale())) { + return 0; + } + if ((fValue == BIG_BANG.getValue() && fScale == BIG_BANG.getScale()) || (ts.getValue() == BIG_CRUNCH.getValue() && ts.getScale() == BIG_CRUNCH.getScale())) { + return -1; + } + if ((fValue == BIG_CRUNCH.getValue() && fScale == BIG_CRUNCH.getScale()) || (ts.getValue() == BIG_BANG.getValue() && ts.getScale() == BIG_BANG.getScale())) { + return 1; + } + + try { + final ITmfTimestamp nts = ts.normalize(0, fScale); + final long delta = fValue - nts.getValue(); + if ((delta == 0) || (withinPrecision && (Math.abs(delta) <= (fPrecision + nts.getPrecision())))) { + return 0; + } + return (delta > 0) ? 1 : -1; + } + catch (final ArithmeticException e) { + // Scaling error. We can figure it out nonetheless. + + // First, look at the sign of the mantissa + final long value = ts.getValue(); + if (fValue == 0 && value == 0) { + return 0; + } + if (fValue < 0 && value >= 0) { + return -1; + } + if (fValue >= 0 && value < 0) { + return 1; + } + + // Otherwise, just compare the scales + final int scale = ts.getScale(); + return (fScale > scale) ? (fValue >= 0) ? 1 : -1 : (fValue >= 0) ? -1 : 1; + } + } + + @Override + public ITmfTimestamp getDelta(final ITmfTimestamp ts) { + final ITmfTimestamp nts = ts.normalize(0, fScale); + final long value = fValue - nts.getValue(); + return new TmfTimestampDelta(value, fScale, fPrecision + nts.getPrecision()); + } + + @Override + public boolean intersects(TmfTimeRange range) { + if (this.compareTo(range.getStartTime()) >= 0 && + this.compareTo(range.getEndTime()) <= 0) { + return true; + } + return false; + } + + // ------------------------------------------------------------------------ + // Comparable + // ------------------------------------------------------------------------ + + @Override + public int compareTo(final ITmfTimestamp ts) { + return compareTo(ts, false); + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (int) (fValue ^ (fValue >>> 32)); + result = prime * result + fScale; + result = prime * result + fPrecision; + return result; + } + + @Override + public boolean equals(final Object other) { + if (this == other) { + return true; + } + if (other == null) { + return false; + } + if (!(other instanceof TmfTimestamp)) { + return false; + } + final TmfTimestamp ts = (TmfTimestamp) other; + return compareTo(ts, false) == 0; + } + + @Override + public String toString() { + return toString(TmfTimestampFormat.getDefaulTimeFormat()); + } + + /** + * @since 2.0 + */ + @Override + public String toString(final TmfTimestampFormat format) { + try { + ITmfTimestamp ts = normalize(0, ITmfTimestamp.NANOSECOND_SCALE); + return format.format(ts.getValue()); + } + catch (ArithmeticException e) { + return format.format(0); + } + } + + /** + * Write the time stamp to the ByteBuffer so that it can be saved to disk. + * @param bufferOut the buffer to write to + * + * @since 3.0 + */ + public void serialize(ByteBuffer bufferOut) { + bufferOut.putLong(fValue); + bufferOut.putInt(fScale); + bufferOut.putInt(fPrecision); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimestampDelta.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimestampDelta.java new file mode 100644 index 0000000000..aac78c284b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimestampDelta.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.core.timestamp; + +import java.util.TimeZone; + +/** + * A generic timestamp implementation for delta between timestamps. + * The toString() method takes negative values into consideration. + * + * @author Bernd Hufmann + * @since 2.0 + */ +public class TmfTimestampDelta extends TmfTimestamp { + + // ------------------------------------------------------------------------ + // Members + // ------------------------------------------------------------------------ + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor + */ + public TmfTimestampDelta() { + super(); + } + + /** + * Simple constructor (scale = precision = 0) + * + * @param value the timestamp value + */ + + public TmfTimestampDelta(long value) { + super(value); + } + + /** + * Simple constructor (precision = 0) + * + * @param value the timestamp value + * @param scale the timestamp scale + */ + public TmfTimestampDelta(long value, int scale) { + super(value, scale); + } + + + /** + * Copy constructor + * + * @param timestamp the timestamp to copy + */ + public TmfTimestampDelta(ITmfTimestamp timestamp) { + super(timestamp); + } + + /** + * Full constructor + * + * @param value the timestamp value + * @param scale the timestamp scale + * @param precision the timestamp precision + */ + public TmfTimestampDelta(long value, int scale, int precision) { + super(value, scale, precision); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Override + public ITmfTimestamp normalize(final long offset, final int scale) { + ITmfTimestamp nts = super.normalize(offset, scale); + return new TmfTimestampDelta(nts.getValue(), nts.getScale(), nts.getPrecision()); + } + + @Override + public String toString() { + return toString(TmfTimestampFormat.getDefaulIntervalFormat()); + } + + @Override + public String toString(TmfTimestampFormat format) { + if (getValue() < 0) { + TmfTimestampDelta tmpTs = new TmfTimestampDelta(-getValue(), getScale(), getPrecision()); + return "-" + tmpTs.toString(format); //$NON-NLS-1$ + } + TmfTimestampFormat deltaFormat = new TmfTimestampFormat(format.toPattern()); + deltaFormat.setTimeZone(TimeZone.getTimeZone("UTC")); //$NON-NLS-1$ + return super.toString(deltaFormat); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimestampFormat.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimestampFormat.java new file mode 100644 index 0000000000..498d2c006b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/timestamp/TmfTimestampFormat.java @@ -0,0 +1,802 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Marc-Andre Laperle - Add time zone preference + * Patrick Tasse - Updated for negative value formatting and fraction of sec + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.timestamp; + +import java.text.DecimalFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; + +/** + * A formatting and parsing facility that can handle timestamps that span the + * epoch with a precision down to the nanosecond. It can be understood as an + * extension of SimpleDateFormat that supports seconds since the epoch (Jan 1, + * 1970, 00:00:00 GMT), additional sub-second patterns and optional delimiters. + *

+ * The timestamp representation is broken down into a number of optional + * components that can be assembled into a fairly simple way. + * + *

Date and Time Patterns

+ * All date and time pattern letters defined in {@link SimpleDateFormat} are + * supported with the following exceptions: + *
+ * + * + * + * + * + *
Format + * Description + * Value Range + * Example + *
T + * The seconds since the epoch + * 0-9223372036 + * 1332170682 + *
S + * Millisecond + * N/A + * Not supported + *
W + * Week in month + * N/A + * Not supported + *
+ *
+ *

+ * Note: When parsing, if "T" is used, no other Date and Time + * pattern letter will be interpreted and the entire pre-delimiter input string + * will be parsed as a number. Also, "T" should be used for time intervals. + *

+ * Note: The decimal separator between the Date and Time + * pattern and the Sub-Seconds pattern is mandatory (if there is a fractional + * part) and must be one of the sub-second delimiters. Date and Time pattern + * letters are not interpreted after the decimal separator. + *

+ *

Sub-Seconds Patterns

+ *
+ * + * + * + * + * + *
Format + * Description + * Value Range + * Example + *
S + * Fraction of second + * 0-999999999 + * 123456789 + *
C + * Microseconds in ms + * 0-999 + * 456 + *
N + * Nanoseconds in µs + * 0-999 + * 789 + *
+ *
+ * Note: The fraction of second pattern can be split, in which + * case parsing and formatting continues at the next digit. Digits beyond the + * total number of pattern letters are ignored when parsing and truncated when + * formatting. + *

+ * Note: When parsing, "S", "C" and "N" are interchangeable + * and are all handled as fraction of second ("S"). The use of "C" and "N" is + * discouraged but is supported for backward compatibility. + *

+ * + * The recognized sub-second delimiters are: + *

    + *
  • Space (" ") + *
  • Period (".") + *
  • Comma (",") + *
  • Dash ("-") + *
  • Underline ("_") + *
  • Colon (":") + *
  • Semicolon (";") + *
  • Slash ("/") + *
  • Single-quote ("''") + *
  • Double-quote (""") + *
+ *

+ * Note: When parsing, sub-second delimiters are optional if + * unquoted. However, an extra delimiter or any other unexpected character in + * the input string ends the parsing of digits. All other quoted or unquoted + * characters in the sub-second pattern are matched against the input string. + * + *

Examples

+ * The following examples show how timestamp patterns are interpreted in + * the U.S. locale. The given timestamp is 1332170682539677389L, the number + * of nanoseconds since 1970/01/01. + * + *
+ * + * + * + * + * + * + * + * + *
Date and Time Pattern + * Result + *
"yyyy-MM-dd HH:mm:ss.SSS.SSS.SSS" + * 2012-03-19 11:24:42.539.677.389 + *
"yyyy-MM-dd HH:mm:ss.SSS.SSS" + * 2012-03-19 11:24:42.539.677 + *
"yyyy-D HH:mm:ss.SSS.SSS" + * 2012-79 11:24:42.539.677 + *
"ss,SSSS" + * 42,5397 + *
"T.SSS SSS SSS" + * 1332170682.539 677 389 + *
"T" + * 1332170682 + *
+ *
+ *

+ * @version 1.0 + * @since 2.0 + * @author Francois Chouinard + */ +public class TmfTimestampFormat extends SimpleDateFormat { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * This class' serialization ID + */ + private static final long serialVersionUID = 2835829763122454020L; + + /** + * The default timestamp pattern + */ + public static final String DEFAULT_TIME_PATTERN = "HH:mm:ss.SSS SSS SSS"; //$NON-NLS-1$ + + /** + * The default interval pattern + */ + public static final String DEFAULT_INTERVAL_PATTERN = "TTT.SSS SSS SSS"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // The default timestamp pattern + private static TmfTimestampFormat fDefaultTimeFormat = null; + + // The default time interval format + private static TmfTimestampFormat fDefaultIntervalFormat = null; + + // The timestamp pattern + private String fPattern; + + // The index of the decimal separator in the pattern + private int fPatternDecimalSeparatorIndex; + + // The decimal separator + private char fDecimalSeparator = '\0'; + + // The date and time pattern unquoted characters + private String fDateTimePattern; + + // The sub-seconds pattern + private String fSubSecPattern; + + // The list of supplementary patterns + private List fSupplPatterns = new ArrayList<>(); + + // The locale + private final Locale fLocale; + + /** + * The supplementary pattern letters. Can be redefined by sub-classes + * to either override existing letters or augment the letter set. + * If so, the format() method must provide the (re-)implementation of the + * pattern. + */ + protected String fSupplPatternLetters = "TSCN"; //$NON-NLS-1$ + /** + * The sub-second pattern letters. + * @since 3.0 + */ + protected String fSubSecPatternChars = "SCN"; //$NON-NLS-1$ + /** + * The optional sub-second delimiter characters. + * @since 3.0 + */ + protected String fDelimiterChars = " .,-_:;/'\""; //$NON-NLS-1$ + + /* + * The bracketing symbols used to mitigate the risk of a format string + * that contains escaped sequences that would conflict with our format + * extension. + */ + /** The open bracket symbol */ + protected String fOpenBracket = "[&"; //$NON-NLS-1$ + + /** The closing bracket symbol */ + protected String fCloseBracket = "&]"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * The default constructor (uses the default pattern) + */ + public TmfTimestampFormat() { + this(TmfTimePreferences.getInstance().getTimePattern()); + } + + /** + * The normal constructor + * + * @param pattern the format pattern + */ + public TmfTimestampFormat(String pattern) { + fLocale = Locale.getDefault(); + applyPattern(pattern); + } + + /** + * The full constructor + * + * @param pattern the format pattern + * @param timeZone the time zone + * @since 2.1 + */ + public TmfTimestampFormat(String pattern, TimeZone timeZone) { + fLocale = Locale.getDefault(); + setTimeZone(timeZone); + applyPattern(pattern); + } + + /** + * The fuller constructor + * + * @param pattern the format pattern + * @param timeZone the time zone + * @param locale the locale + * @since 3.2 + */ + public TmfTimestampFormat(String pattern, TimeZone timeZone, Locale locale) { + super("", locale); //$NON-NLS-1$ + fLocale = locale; + setTimeZone(timeZone); + setCalendar(Calendar.getInstance(timeZone, locale)); + applyPattern(pattern); + } + + /** + * The copy constructor + * + * @param other the other format pattern + */ + public TmfTimestampFormat(TmfTimestampFormat other) { + this(other.fPattern, other.getTimeZone(), other.fLocale); + } + + // ------------------------------------------------------------------------ + // Getters/setters + // ------------------------------------------------------------------------ + + /** + * @since 2.1 + */ + public static void updateDefaultFormats() { + fDefaultTimeFormat = new TmfTimestampFormat( + TmfTimePreferences.getInstance().getTimePattern(), + TmfTimePreferences.getInstance().getTimeZone(), + TmfTimePreferences.getInstance().getLocale()); + fDefaultIntervalFormat = new TmfTimestampFormat(TmfTimePreferences.getInstance().getIntervalPattern()); + } + + /** + * @return the default time format pattern + */ + public static TmfTimestampFormat getDefaulTimeFormat() { + if (fDefaultTimeFormat == null) { + fDefaultTimeFormat = new TmfTimestampFormat( + TmfTimePreferences.getInstance().getTimePattern(), + TmfTimePreferences.getInstance().getTimeZone(), + TmfTimePreferences.getInstance().getLocale()); + } + return fDefaultTimeFormat; + } + + /** + * @return the default interval format pattern + */ + public static TmfTimestampFormat getDefaulIntervalFormat() { + if (fDefaultIntervalFormat == null) { + fDefaultIntervalFormat = new TmfTimestampFormat(TmfTimePreferences.getInstance().getIntervalPattern()); + } + return fDefaultIntervalFormat; + } + + @Override + public void applyPattern(String pattern) { + fPattern = pattern; + fPatternDecimalSeparatorIndex = indexOfPatternDecimalSeparator(pattern); + fDateTimePattern = unquotePattern(pattern.substring(0, fPatternDecimalSeparatorIndex)); + // Check that 'S' is not present in the date and time pattern + if (fDateTimePattern.indexOf('S') != -1) { + throw new IllegalArgumentException("Illegal pattern character 'S'"); //$NON-NLS-1$ + } + // Check that 'W' is not present in the date and time pattern + if (fDateTimePattern.indexOf('W') != -1) { + throw new IllegalArgumentException("Illegal pattern character 'W'"); //$NON-NLS-1$ + } + // The super pattern is the date/time pattern, quoted and bracketed + super.applyPattern(quoteSpecificTags(pattern.substring(0, fPatternDecimalSeparatorIndex), true)); + // The sub-seconds pattern is bracketed (but not quoted) + fSubSecPattern = quoteSpecificTags(pattern.substring(fPatternDecimalSeparatorIndex), false); + } + + @Override + public String toPattern() { + return fPattern; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Format the timestamp according to its pattern. + * + * @param value the timestamp value to format (in ns) + * @return the formatted timestamp + */ + public synchronized String format(long value) { + + // Split the timestamp value into its sub-components + long date = value / 1000000; // milliseconds since January 1, 1970, 00:00:00 GMT + long sec = value / 1000000000; // seconds since January 1, 1970, 00:00:00 GMT + long ms = Math.abs((value % 1000000000) / 1000000); // milliseconds + long cs = Math.abs((value % 1000000) / 1000); // microseconds + long ns = Math.abs(value % 1000); // nanoseconds + + // Adjust for negative value when formatted as a date + if (value < 0 && ms + cs + ns > 0 && !super.toPattern().contains(fOpenBracket + "T")) { //$NON-NLS-1$ + date -= 1; + long nanosec = 1000000000 - (1000000 * ms + 1000 * cs + ns); + ms = nanosec / 1000000; + cs = (nanosec % 1000000) / 1000; + ns = nanosec % 1000; + } + + // Let the base class format the date/time pattern + StringBuffer result = new StringBuffer(super.format(date)); + // Append the sub-second pattern + result.append(fSubSecPattern); + + int fractionDigitsPrinted = 0; + // Fill in our extensions + for (String pattern : fSupplPatterns) { + int length = pattern.length(); + long val = 0; + int bufLength = 0; + + // Format the proper value as per the pattern + switch (pattern.charAt(0)) { + case 'T': + if (value < 0 && sec == 0) { + result.insert(0, '-'); + } + val = sec; + bufLength = Math.min(length, 10); + break; + case 'S': + val = 1000000 * ms + 1000 * cs + ns; + bufLength = 9; + break; + case 'C': + val = cs; + bufLength = Math.min(length, 3); + break; + case 'N': + val = ns; + bufLength = Math.min(length, 3); + break; + default: + break; + } + + // Prepare the format buffer + StringBuffer fmt = new StringBuffer(); + for (int i = 0; i < bufLength; i++) { + fmt.append("0"); //$NON-NLS-1$ + } + DecimalFormat dfmt = new DecimalFormat(fmt.toString()); + String fmtVal = dfmt.format(val); + if (pattern.charAt(0) == 'S') { + fmtVal = fmtVal.substring(fractionDigitsPrinted, Math.min(bufLength, fractionDigitsPrinted + length)); + fractionDigitsPrinted += fmtVal.length(); + } + + // Substitute the placeholder pattern with the formatted value + String ph = new StringBuffer(fOpenBracket + pattern + fCloseBracket).toString(); + int loc = result.indexOf(ph); + result.replace(loc, loc + length + fOpenBracket.length() + fCloseBracket.length(), fmtVal); + } + + return result.toString(); + } + + /** + * Parse a string according to the format pattern + * + * @param source the source string + * @param ref the reference (base) time (in ns) + * @return the parsed value (in ns) + * @throws ParseException if the string has an invalid format + */ + public synchronized long parseValue(final String source, final long ref) throws ParseException { + + // Trivial case + if (source == null || source.length() == 0) { + return 0; + } + + long seconds = 0; + boolean isNegative = source.charAt(0) == '-'; + boolean isDateTimeFormat = true; + + int index = indexOfSourceDecimalSeparator(source); + + // Check for seconds in epoch pattern + for (String pattern : fSupplPatterns) { + if (pattern.charAt(0) == 'T') { + isDateTimeFormat = false; + // Remove everything up to the first "." and compute the + // number of seconds since the epoch. If there is no period, + // assume an integer value and return immediately + if (index == 0 || (isNegative && index <= 1)) { + seconds = 0; + } else if (index == source.length()) { + return new DecimalFormat("0").parse(source).longValue() * 1000000000; //$NON-NLS-1$ + } else { + seconds = new DecimalFormat("0").parse(source.substring(0, index)).longValue(); //$NON-NLS-1$ + } + break; + } + } + + // If there was no "T" (thus not an interval), parse as a date + if (isDateTimeFormat && super.toPattern().length() > 0) { + Date baseDate = super.parse(source.substring(0, index)); + getCalendar(); + + if (ref != Long.MIN_VALUE) { + Calendar baseTime = Calendar.getInstance(getTimeZone(), fLocale); + baseTime.setTimeInMillis(baseDate.getTime()); + Calendar newTime = Calendar.getInstance(getTimeZone(), fLocale); + newTime.setTimeInMillis(ref / 1000000); + boolean setRemainingFields = false; + if (dateTimePatternContains("yY")) { //$NON-NLS-1$ + newTime.set(Calendar.YEAR, baseTime.get(Calendar.YEAR)); + setRemainingFields = true; + } + if (setRemainingFields || dateTimePatternContains("M")) { //$NON-NLS-1$ + newTime.set(Calendar.MONTH, baseTime.get(Calendar.MONTH)); + setRemainingFields = true; + } + if (setRemainingFields || dateTimePatternContains("d")) { //$NON-NLS-1$ + newTime.set(Calendar.DATE, baseTime.get(Calendar.DATE)); + setRemainingFields = true; + } else if (dateTimePatternContains("D")) { //$NON-NLS-1$ + newTime.set(Calendar.DAY_OF_YEAR, baseTime.get(Calendar.DAY_OF_YEAR)); + setRemainingFields = true; + } else if (dateTimePatternContains("w")) { //$NON-NLS-1$ + newTime.set(Calendar.WEEK_OF_YEAR, baseTime.get(Calendar.WEEK_OF_YEAR)); + setRemainingFields = true; + } + if (dateTimePatternContains("F")) { //$NON-NLS-1$ + newTime.set(Calendar.DAY_OF_WEEK_IN_MONTH, baseTime.get(Calendar.DAY_OF_WEEK_IN_MONTH)); + setRemainingFields = true; + } + if (dateTimePatternContains("Eu")) { //$NON-NLS-1$ + newTime.set(Calendar.DAY_OF_WEEK, baseTime.get(Calendar.DAY_OF_WEEK)); + setRemainingFields = true; + } + if (setRemainingFields || dateTimePatternContains("aHkKh")) { //$NON-NLS-1$ + newTime.set(Calendar.HOUR_OF_DAY, baseTime.get(Calendar.HOUR_OF_DAY)); + setRemainingFields = true; + } + if (setRemainingFields || dateTimePatternContains("m")) { //$NON-NLS-1$ + newTime.set(Calendar.MINUTE, baseTime.get(Calendar.MINUTE)); + setRemainingFields = true; + } + if (setRemainingFields || dateTimePatternContains("s")) { //$NON-NLS-1$ + newTime.set(Calendar.SECOND, baseTime.get(Calendar.SECOND)); + } + newTime.set(Calendar.MILLISECOND, 0); + seconds = newTime.getTimeInMillis() / 1000; + } else { + seconds = baseDate.getTime() / 1000; + } + } else if (isDateTimeFormat && ref != Long.MIN_VALUE) { + // If the date and time pattern is empty, adjust for reference + seconds = ref / 1000000000; + } + + long nanos = parseSubSeconds(source.substring(index)); + if (isNegative && !isDateTimeFormat) { + nanos = -nanos; + } + // Compute the value in ns + return seconds * 1000000000 + nanos; + } + + /** + * Parse a string according to the format pattern + * + * @param source the source string + * @return the parsed value (in ns) + * @throws ParseException if the string has an invalid format + */ + public long parseValue(final String source) throws ParseException { + long result = parseValue(source, Long.MIN_VALUE); + return result; + + } + + // ------------------------------------------------------------------------ + // Helper functions + // ------------------------------------------------------------------------ + + /** + * Finds the index of the decimal separator in the pattern string, which is + * the last delimiter found before the first sub-second pattern character. + * Returns the pattern string length if decimal separator is not found. + */ + private int indexOfPatternDecimalSeparator(String pattern) { + int lastDelimiterIndex = pattern.length(); + boolean inQuote = false; + int index = 0; + while (index < pattern.length()) { + char ch = pattern.charAt(index); + if (ch == '\'') { + if (index + 1 < pattern.length()) { + index++; + ch = pattern.charAt(index); + if (ch != '\'') { + inQuote = !inQuote; + } + } + } + if (!inQuote) { + if (fSubSecPatternChars.indexOf(ch) != -1) { + if (lastDelimiterIndex < pattern.length()) { + fDecimalSeparator = pattern.charAt(lastDelimiterIndex); + } + return lastDelimiterIndex; + } + if (fDelimiterChars.indexOf(ch) != -1) { + lastDelimiterIndex = index; + if (ch == '\'') { + lastDelimiterIndex--; + } + } + } + index++; + } + return pattern.length(); + } + + /** + * Finds the first index of a decimal separator in the source string. + * Skips the number of decimal separators in the format pattern. + * Returns the source string length if decimal separator is not found. + */ + private int indexOfSourceDecimalSeparator(String source) { + String pattern = fPattern.substring(0, fPatternDecimalSeparatorIndex); + String separator = fDecimalSeparator == '\'' ? "''" : String.valueOf(fDecimalSeparator); //$NON-NLS-1$ + int sourcePos = source.indexOf(fDecimalSeparator); + int patternPos = pattern.indexOf(separator); + while (patternPos != -1 && sourcePos != -1) { + sourcePos = source.indexOf(fDecimalSeparator, sourcePos + 1); + patternPos = pattern.indexOf(separator, patternPos + separator.length()); + } + if (sourcePos == -1) { + sourcePos = source.length(); + } + return sourcePos; + } + + /** + * Parse the sub-second digits in the input. Handle delimiters as optional + * characters. Match any non-pattern and non-delimiter pattern characters + * against the input. Returns the number of nanoseconds. + */ + private long parseSubSeconds(String input) throws ParseException { + StringBuilder digits = new StringBuilder("000000000"); //$NON-NLS-1$ + String pattern = fPattern.substring(fPatternDecimalSeparatorIndex); + boolean inQuote = false; + int digitIndex = 0; + int inputIndex = 0; + int patternIndex = 0; + while (patternIndex < pattern.length()) { + char ch = pattern.charAt(patternIndex); + if (ch == '\'') { + patternIndex++; + if (patternIndex < pattern.length()) { + ch = pattern.charAt(patternIndex); + if (ch != '\'') { + inQuote = !inQuote; + } + } else if (inQuote) { + // final end quote + break; + } + } + if (fDelimiterChars.indexOf(ch) != -1 && !inQuote) { + // delimiter is optional if not in quote + if (inputIndex < input.length() && input.charAt(inputIndex) == ch) { + inputIndex++; + } + patternIndex++; + continue; + } else if (fSubSecPatternChars.indexOf(ch) != -1 && !inQuote) { + // read digit if not in quote + if (inputIndex < input.length() && Character.isDigit(input.charAt(inputIndex))) { + if (digitIndex < digits.length()) { + digits.setCharAt(digitIndex, input.charAt(inputIndex)); + digitIndex++; + } + inputIndex++; + } else { + // not a digit, stop parsing digits + digitIndex = digits.length(); + } + patternIndex++; + continue; + } + if (inputIndex >= input.length() || input.charAt(inputIndex) != ch) { + throw new ParseException("Unparseable sub-seconds: \"" + input + '\"', inputIndex); //$NON-NLS-1$ + } + patternIndex++; + inputIndex++; + } + return Long.parseLong(digits.toString()); + } + + /** + * Copy the pattern but quote (bracket with "[&" and "&]") the + * TmfTimestampFormat specific tags. Optionally surround tags with single + * quotes so these fields are treated as comments by the base class. + * + * It also keeps track of the corresponding quoted fields so they can be + * properly populated later on (by format()). + * + * @param pattern + * the 'extended' pattern + * @param includeQuotes + * true to include quotes from pattern and add single quotes + * around tags + * @return the quoted and bracketed pattern + */ + private String quoteSpecificTags(final String pattern, boolean includeQuotes) { + + StringBuffer result = new StringBuffer(); + + int length = pattern.length(); + boolean inQuote = false; + + for (int i = 0; i < length; i++) { + char c = pattern.charAt(i); + if (c != '\'' || includeQuotes) { + result.append(c); + } + if (c == '\'') { + // '' is treated as a single quote regardless of being + // in a quoted section. + if ((i + 1) < length) { + c = pattern.charAt(i + 1); + if (c == '\'') { + i++; + result.append(c); + continue; + } + } + inQuote = !inQuote; + continue; + } + if (!inQuote && (fSupplPatternLetters.indexOf(c) != -1)) { + if (pattern.charAt(0) == fDecimalSeparator) { + if (fSubSecPatternChars.indexOf(c) == -1) { + // do not quote non-sub-second pattern letters in sub-second pattern + continue; + } + } else { + if (fSubSecPatternChars.indexOf(c) != -1) { + // do not quote sub-second pattern letters in date and time pattern + continue; + } + } + StringBuilder pat = new StringBuilder(); + pat.append(c); + if (includeQuotes) { + result.insert(result.length() - 1, "'"); //$NON-NLS-1$ + } + result.insert(result.length() - 1, fOpenBracket); + while ((i + 1) < length && pattern.charAt(i + 1) == c) { + result.append(c); + pat.append(c); + i++; + } + result.append(fCloseBracket); + if (includeQuotes) { + result.append("'"); //$NON-NLS-1$ + } + fSupplPatterns.add(pat.toString()); + } + } + return result.toString(); + } + + /** + * Returns the unquoted characters in this pattern. + */ + private static String unquotePattern(String pattern) { + boolean inQuote = false; + int index = 0; + StringBuilder result = new StringBuilder(); + while (index < pattern.length()) { + char ch = pattern.charAt(index); + if (ch == '\'') { + if (index + 1 < pattern.length()) { + index++; + ch = pattern.charAt(index); + if (ch != '\'') { + inQuote = !inQuote; + } + } + } + if (!inQuote) { + result.append(ch); + } + index++; + } + return result.toString(); + } + + /** + * Returns true if the date and time pattern contains any of these chars. + */ + private boolean dateTimePatternContains(String chars) { + int index = 0; + while (index < chars.length()) { + char ch = chars.charAt(index); + if (fDateTimePattern.indexOf(ch) != -1) { + return true; + } + index++; + } + return false; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfContext.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfContext.java new file mode 100644 index 0000000000..8459685ae0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfContext.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Updated as per TMF Trace Model 1.0 + * Patrick Tasse - Updated for removal of context clone + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace; + +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +/** + * The basic trace context structure in TMF. The purpose of the context is to + * associate a trace location to an event at a specific rank (order). + *

+ * The context should be sufficient to allow the trace to position itself so + * that performing a trace read operation will yield the corresponding 'nth' + * event. + * + * @version 1.0 + * @author Francois Chouinard + * + * @see ITmfLocation + */ +public interface ITmfContext { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The unknown event rank + */ + public long UNKNOWN_RANK = -1L; + + // ------------------------------------------------------------------------ + // Getters + // ------------------------------------------------------------------------ + + /** + * @return the rank of the event at the context location + */ + long getRank(); + + /** + * @return the location of the event at the context rank + * @since 3.0 + */ + ITmfLocation getLocation(); + + /** + * @return indicates if the context rank is valid (!= UNKNOWN_RANK) + */ + boolean hasValidRank(); + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * @param location the new location + * @since 3.0 + */ + void setLocation(ITmfLocation location); + + /** + * @param rank the new rank + */ + void setRank(long rank); + + /** + * Increment the context rank + */ + void increaseRank(); + + /** + * Cleanup hook + */ + void dispose(); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfEventParser.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfEventParser.java new file mode 100644 index 0000000000..7a345791d6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfEventParser.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Updated as per TMF Trace Model 1.0 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * The generic trace parser in TMF. + * + * @version 1.0 + * @author Francois Chouinard + * + * @see ITmfEvent + * @see ITmfContext + */ +public interface ITmfEventParser { + + /** + * Parses the trace event referenced by the context. + * The context should *not* be altered. + * + * @param context the trace context + * @return a parsed event (null if none) + */ + ITmfEvent parseEvent(ITmfContext context); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTrace.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTrace.java new file mode 100644 index 0000000000..77e46a3866 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTrace.java @@ -0,0 +1,457 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Updated as per TMF Trace Model 1.0 + * Geneviève Bastien - Added timestamp transforms and timestamp + * creation functions + * Patrick Tasse - Add support for folder elements + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; +import org.eclipse.tracecompass.tmf.core.component.ITmfEventProvider; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +/** + * The event stream structure in TMF. In its basic form, a trace has: + *

    + *
  • an associated Eclipse resource + *
  • a path to its location on the file system + *
  • the type of the events it contains + *
  • the number of events it contains + *
  • the time range (span) of the events it contains + *
+ * Concrete ITmfTrace classes have to provide a parameter-less constructor and + * an initialization method (initTrace) if they are to be opened from the + * Project View. Also, a validation method (validate) has to be provided + * to ensure that the trace is of the correct type. + *

+ * A trace can be accessed simultaneously from multiple threads by various + * application components. To avoid obvious multi-threading issues, the trace + * uses an ITmfContext as a synchronization aid for its read operations. + *

+ * A proper ITmfContext can be obtained by performing a seek operation on the + * trace. Seek operations can be performed for a particular event (by rank or + * timestamp) or for a plain trace location. + *

+ * Example 1: Process a whole trace + *

+ * ITmfContext context = trace.seekEvent(0);
+ * ITmfEvent event = trace.getNext(context);
+ * while (event != null) {
+ *     processEvent(event);
+ *     event = trace.getNext(context);
+ * }
+ * 
+ * Example 2: Process 50 events starting from the 1000th event + *
+ * int nbEventsRead = 0;
+ * ITmfContext context = trace.seekEvent(1000);
+ * ITmfEvent event = trace.getNext(context);
+ * while (event != null && nbEventsRead < 50) {
+ *     nbEventsRead++;
+ *     processEvent(event);
+ *     event = trace.getNext(context);
+ * }
+ * 
+ * Example 3: Process the events between 2 timestamps (inclusive) + *
+ * ITmfTimestamp startTime = ...;
+ * ITmfTimestamp endTime = ...;
+ * ITmfContext context = trace.seekEvent(startTime);
+ * ITmfEvent event = trace.getNext(context);
+ * while (event != null && event.getTimestamp().compareTo(endTime) <= 0) {
+ *     processEvent(event);
+ *     event = trace.getNext(context);
+ * }
+ * 
+ * + * A trace is also an event provider so it can process event requests + * asynchronously (and coalesce compatible, concurrent requests). + *

+ * + * Example 4: Process a whole trace (see ITmfEventRequest for + * variants) + *

+ * ITmfRequest request = new TmfEventRequest<MyEventType>(MyEventType.class) {
+ *     @Override
+ *     public void handleData(MyEventType event) {
+ *         super.handleData(event);
+ *         processEvent(event);
+ *     }
+ *
+ *     @Override
+ *     public void handleCompleted() {
+ *         finish();
+ *         super.handleCompleted();
+ *     }
+ * };
+ *
+ * fTrace.handleRequest(request);
+ * if (youWant) {
+ *     request.waitForCompletion();
+ * }
+ * 
+ * + * @version 1.0 + * @author Francois Chouinard + * + * @see ITmfContext + * @see ITmfEvent + * @see ITmfTraceIndexer + * @see ITmfEventParser + */ +public interface ITmfTrace extends ITmfEventProvider { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The default trace cache size + */ + public static final int DEFAULT_TRACE_CACHE_SIZE = 1000; + + // ------------------------------------------------------------------------ + // Initializers + // ------------------------------------------------------------------------ + + /** + * Initialize a newly instantiated "empty" trace object. This is used to + * properly parameterize an ITmfTrace instantiated with its parameterless + * constructor. + *

+ * Typically, the parameterless constructor will provide the block size and + * its associated parser and indexer. + * + * @param resource + * the trace resource + * @param path + * the trace path. The path should suitable for passing to + * java.io.File(String) and should use the + * platform-dependent path separator. + * @param type + * the trace event type + * @throws TmfTraceException + * If we couldn't open the trace + */ + void initTrace(IResource resource, String path, Class type) throws TmfTraceException; + + /** + * Initialize a newly instantiated "empty" trace object. This is used to + * properly parameterize an ITmfTrace instantiated with its parameterless + * constructor. + *

+ * Typically, the parameterless constructor will provide the block size and + * its associated parser and indexer. + * + * @param resource + * the trace resource + * @param path + * the trace path + * @param type + * the trace event type + * @param name + * the trace name + * @throws TmfTraceException + * If we couldn't open the trace + */ + void initTrace(IResource resource, String path, Class type, String name) throws TmfTraceException; + + /** + * Validate that the trace is of the correct type. The implementation should + * return a TraceValidationStatus to indicate success with a certain level + * of confidence. + * + * @param project + * the eclipse project + * @param path + * the trace path. The path should suitable for passing to + * java.io.File(String) and should use the + * platform-dependent path separator. + * + * @return an IStatus object with validation result. Use severity OK to + * indicate success. + * @see TraceValidationStatus + * @since 2.0 + */ + IStatus validate(IProject project, String path); + + // ------------------------------------------------------------------------ + // Basic getters + // ------------------------------------------------------------------------ + + /** + * @return the trace event type + */ + Class getEventType(); + + /** + * @return the associated trace resource + */ + IResource getResource(); + + /** + * @return the trace path + */ + String getPath(); + + /** + * @return the trace cache size + */ + int getCacheSize(); + + /** + * Index the trace. Depending on the trace type, this could be done at the + * constructor or initTrace phase too, so this could be implemented as a + * no-op. + * + * @param waitForCompletion + * Should we block the caller until indexing is finished, or not. + * @since 2.0 + */ + void indexTrace(boolean waitForCompletion); + + // ------------------------------------------------------------------------ + // Analysis getters + // ------------------------------------------------------------------------ + + /** + * Returns an analysis module with the given ID. + * + * @param id + * The analysis module ID + * @return The {@link IAnalysisModule} object, or null if an analysis with + * the given ID does no exist. + * @since 3.0 + */ + @Nullable + IAnalysisModule getAnalysisModule(String id); + + /** + * Get a list of all analysis modules currently available for this trace. + * + * @return An iterable view of the analysis modules + * @since 3.0 + */ + @NonNull + Iterable getAnalysisModules(); + + /** + * Get an analysis module belonging to this trace, with the specified ID and + * class. + * + * @param moduleClass + * Returned modules must extend this class + * @param id + * The ID of the analysis module + * @return The analysis module with specified class and ID, or null if no + * such module exists. + * @since 3.0 + */ + @Nullable + T getAnalysisModuleOfClass(Class moduleClass, String id); + + /** + * Return the analysis modules that are of a given class. Module are already + * casted to the requested class. + * + * @param moduleClass + * Returned modules must extend this class + * @return List of modules of class moduleClass + * @since 3.0 + */ + @NonNull + Iterable getAnalysisModulesOfClass(Class moduleClass); + + // ------------------------------------------------------------------------ + // Trace characteristics getters + // ------------------------------------------------------------------------ + + /** + * @return the number of events in the trace + */ + long getNbEvents(); + + /** + * @return the trace time range + * @since 2.0 + */ + TmfTimeRange getTimeRange(); + + /** + * @return the timestamp of the first trace event + * @since 2.0 + */ + ITmfTimestamp getStartTime(); + + /** + * @return the timestamp of the last trace event + * @since 2.0 + */ + ITmfTimestamp getEndTime(); + + /** + * @return the streaming interval in ms (0 if not a streaming trace) + */ + long getStreamingInterval(); + + // ------------------------------------------------------------------------ + // Trace positioning getters + // ------------------------------------------------------------------------ + + /** + * @return the current trace location + * @since 3.0 + */ + ITmfLocation getCurrentLocation(); + + /** + * Returns the ratio (proportion) corresponding to the specified location. + * + * @param location + * a trace specific location + * @return a floating-point number between 0.0 (beginning) and 1.0 (end) + * @since 3.0 + */ + double getLocationRatio(ITmfLocation location); + + // ------------------------------------------------------------------------ + // SeekEvent operations (returning a trace context) + // ------------------------------------------------------------------------ + + /** + * Position the trace at the specified (trace specific) location. + *

+ * A null location is interpreted as seeking for the first event of the + * trace. + *

+ * If not null, the location requested must be valid otherwise the returned + * context is undefined (up to the implementation to recover if possible). + *

+ * + * @param location + * the trace specific location + * @return a context which can later be used to read the corresponding event + * @since 3.0 + */ + ITmfContext seekEvent(ITmfLocation location); + + /** + * Position the trace at the 'rank'th event in the trace. + *

+ * A rank <= 0 is interpreted as seeking for the first event of the trace. + *

+ * If the requested rank is beyond the last trace event, the context + * returned will yield a null event if used in a subsequent read. + * + * @param rank + * the event rank + * @return a context which can later be used to read the corresponding event + */ + ITmfContext seekEvent(long rank); + + /** + * Position the trace at the first event with the specified timestamp. If + * there is no event with the requested timestamp, a context pointing to the + * next chronological event is returned. + *

+ * A null timestamp is interpreted as seeking for the first event of the + * trace. + *

+ * If the requested timestamp is beyond the last trace event, the context + * returned will yield a null event if used in a subsequent read. + * + * @param timestamp + * the timestamp of desired event + * @return a context which can later be used to read the corresponding event + * @since 2.0 + */ + ITmfContext seekEvent(ITmfTimestamp timestamp); + + /** + * Position the trace at the event located at the specified ratio in the + * trace file. + *

+ * The notion of ratio (0.0 <= r <= 1.0) is trace specific and left + * voluntarily vague. Typically, it would refer to the event proportional + * rank (arguably more intuitive) or timestamp in the trace file. + * + * @param ratio + * the proportional 'rank' in the trace + * @return a context which can later be used to read the corresponding event + */ + ITmfContext seekEvent(double ratio); + + /** + * Returns the initial range offset + * + * @return the initial range offset + * @since 2.0 + */ + ITmfTimestamp getInitialRangeOffset(); + + /** + * Returns the ID of the host this trace is from. The host ID is not + * necessarily the hostname, but should be a unique identifier for the + * machine on which the trace was taken. It can be used to determine if two + * traces were taken on the exact same machine (timestamp are already + * synchronized, resources with same id are the same if taken at the same + * time, etc). + * + * @return The host id of this trace + * @since 3.0 + */ + String getHostId(); + + // ------------------------------------------------------------------------ + // Timestamp transformation functions + // ------------------------------------------------------------------------ + + /** + * Returns the timestamp transformation for this trace + * + * @return the timestamp transform + * @since 3.0 + */ + ITmfTimestampTransform getTimestampTransform(); + + /** + * Sets the trace's timestamp transform + * + * @param tt + * The timestamp transform for all timestamps of this trace + * @since 3.0 + */ + void setTimestampTransform(final ITmfTimestampTransform tt); + + /** + * Creates a timestamp for this trace, using the transformation formula + * + * @param ts + * The time in nanoseconds with which to create the timestamp + * @return The new timestamp + * @since 3.0 + */ + ITmfTimestamp createTimestamp(long ts); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTraceCompleteness.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTraceCompleteness.java new file mode 100644 index 0000000000..af8a172202 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTraceCompleteness.java @@ -0,0 +1,38 @@ +/********************************************************************** + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial implementation + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace; + +/** + * An interface that provides information about the completeness of a trace. A + * trace is considered complete when it is known that no more data will be added + * to it. + * + * @since 3.1 + */ +public interface ITmfTraceCompleteness { + + /** + * Returns whether or not a trace is complete. + * + * @return true if a trace is complete, false otherwise + */ + boolean isComplete(); + + /** + * Set the completeness of a trace. + * + * @param isComplete + * whether the trace should be considered complete or not + */ + void setComplete(boolean isComplete); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTraceProperties.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTraceProperties.java new file mode 100644 index 0000000000..981c190fe8 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTraceProperties.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace; + +import java.util.Map; + +/** + * Interface for trace types to implement when they can provide additional + * trace-wide properties. + * + * This information will be displayed in the trace's Properties View, among + * other things. + * + * @author Alexandre Montplaisir + * @since 2.0 + */ +public interface ITmfTraceProperties { + + /** + * Get the properties related to this trace. + * + * @return The map of properties, + */ + public Map getTraceProperties(); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTraceWithPreDefinedEvents.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTraceWithPreDefinedEvents.java new file mode 100644 index 0000000000..36f365bce1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTraceWithPreDefinedEvents.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal, Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace; + +import java.util.Set; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; + +/** + * This interface should be implemented by all trace classes who have a way to + * know in advance what events it may contain. It allows analyses and other + * external components to ask the list of events for the trace might contain. + * + * The methods from this interface will typically be called to determine whether + * or not it is worth reading a trace. If we can know in advance that a trace + * does not contain the events required by an analysis, then the analysis will + * not be run. So the response should not involve having to actually read the + * trace. + * + * @author Geneviève Bastien + * @author Matthew Khouzam + * @since 3.0 + */ +public interface ITmfTraceWithPreDefinedEvents { + + /** + * Return a set of event types declared in the trace, without actually + * reading the trace. This method can be called before reading a trace but + * after it is initialized, in order to compare this set with a set of + * events that a request handles, to determine whether or not it is worth + * reading the trace. + * + * Some trace types have ways to determine the events that were traced + * without having to read the whole trace and this is what this method will + * query. The presence of an event in the returned set does not guarantee + * that an event with this name actually happened during this trace, only + * that it can be there. + * + * The set should be immutable. Destructive set operations should be + * performed on a copy of this set.A helper class + * {@link TmfEventTypeCollectionHelper} will provide ways of working with + * this data structure. + * + * @return The set of events that might be present in the trace + */ + Set getContainedEventTypes(); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfContext.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfContext.java new file mode 100644 index 0000000000..b0809de567 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfContext.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Updated as per TMF Trace Model 1.0 + * Patrick Tasse - Updated for removal of context clone + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace; + +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +/** + * A basic implementation of ITmfContext. + *

+ * It ties a trace location to an event rank. The context should be enough to + * restore the trace state so the corresponding event can be read. + * + * @version 1.0 + * @author Francois Chouinard + * + * @see ITmfLocation + */ +public class TmfContext implements ITmfContext { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // The trace location + private ITmfLocation fLocation; + + // The event rank + private long fRank; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + public TmfContext() { + this(null, UNKNOWN_RANK); + } + + /** + * Simple constructor (unknown rank) + * + * @param location the event location + * @since 3.0 + */ + public TmfContext(final ITmfLocation location) { + this(location, UNKNOWN_RANK); + } + + /** + * Full constructor + * + * @param location the event location + * @param rank the event rank + * @since 3.0 + */ + public TmfContext(final ITmfLocation location, final long rank) { + fLocation = location; + fRank = rank; + } + + /** + * Copy constructor + * + * @param context the other context + */ + public TmfContext(final TmfContext context) { + if (context == null) { + throw new IllegalArgumentException(); + } + fLocation = context.fLocation; + fRank = context.fRank; + } + + // ------------------------------------------------------------------------ + // ITmfContext + // ------------------------------------------------------------------------ + + /** + * @since 3.0 + */ + @Override + public ITmfLocation getLocation() { + return fLocation; + } + + /** + * @since 3.0 + */ + @Override + public void setLocation(final ITmfLocation location) { + fLocation = location; + } + + @Override + public long getRank() { + return fRank; + } + + @Override + public void setRank(final long rank) { + fRank = rank; + } + + @Override + public void increaseRank() { + if (hasValidRank()) { + fRank++; + } + } + + @Override + public boolean hasValidRank() { + return fRank != UNKNOWN_RANK; + } + + @Override + public void dispose() { + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((fLocation == null) ? 0 : fLocation.hashCode()); + result = prime * result + (int) (fRank ^ (fRank >>> 32)); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final TmfContext other = (TmfContext) obj; + if (fLocation == null) { + if (other.fLocation != null) { + return false; + } + } else if (!fLocation.equals(other.fLocation)) { + return false; + } + if (fRank != other.fRank) { + return false; + } + return true; + } + + @Override + @SuppressWarnings("nls") + public String toString() { + return "TmfContext [fLocation=" + fLocation + ", fRank=" + fRank + "]"; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfEventTypeCollectionHelper.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfEventTypeCollectionHelper.java new file mode 100644 index 0000000000..403e429a5e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfEventTypeCollectionHelper.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; + +/** + * Set Helper for sets of ITmfTraceType + * + * TODO Remove once Java 8 is used (replace with Streams) + * + * @author Matthew Khouzam + * @since 3.0 + */ +public final class TmfEventTypeCollectionHelper { + + private TmfEventTypeCollectionHelper() { + } + + /** + * Gets the event names from a collection of event types + * + * @param eventTypes + * an iterable collection of ITmfEventTypes + * @return a set of the names of these events, if some names are clashing + * they will only appear once + */ + public static Set getEventNames(Iterable eventTypes) { + Set retSet = new HashSet<>(); + for (ITmfEventType eventType : eventTypes) { + retSet.add(eventType.getName()); + } + return retSet; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfExperiment.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfExperiment.java new file mode 100644 index 0000000000..3fe56d7266 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfExperiment.java @@ -0,0 +1,736 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Updated as per TMF Trace Model 1.0 + * Patrick Tasse - Updated for removal of context clone + * Patrick Tasse - Updated for ranks in experiment location + * Geneviève Bastien - Added support of experiment synchronization + * Added the initExperiment method and default constructor + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace; + +import java.io.File; +import java.nio.ByteBuffer; +import java.util.Arrays; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.internal.tmf.core.trace.TmfExperimentContext; +import org.eclipse.tracecompass.internal.tmf.core.trace.TmfExperimentLocation; +import org.eclipse.tracecompass.internal.tmf.core.trace.TmfLocationArray; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceRangeUpdatedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSynchronizedSignal; +import org.eclipse.tracecompass.tmf.core.synchronization.SynchronizationAlgorithm; +import org.eclipse.tracecompass.tmf.core.synchronization.SynchronizationManager; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfPersistentlyIndexable; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.indexer.TmfBTreeTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +/** + * TmfExperiment presents a time-ordered, unified view of a set of ITmfTrace:s + * that are part of a tracing experiment. + * + * @version 1.0 + * @author Francois Chouinard + */ +public class TmfExperiment extends TmfTrace implements ITmfEventParser, ITmfPersistentlyIndexable { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The file name of the Synchronization + * + * @since 3.0 + * @deprecated This file name shouldn't be used directly anymore. All + * synchronization files have been moved to a folder and you + * should use the {@link #getSynchronizationFolder(boolean)} + * method to return the path to this folder. + */ + @Deprecated + public static final String SYNCHRONIZATION_FILE_NAME = "synchronization.bin"; //$NON-NLS-1$ + + /** + * The name of the directory containing trace synchronization data. This + * directory typically will be preserved when traces are synchronized. + * Analysis involved in synchronization can put their supplementary files in + * there so they are not deleted when synchronized traces are copied. + */ + private static final String SYNCHRONIZATION_DIRECTORY = "sync_data"; //$NON-NLS-1$ + + /** + * The default index page size + */ + public static final int DEFAULT_INDEX_PAGE_SIZE = 5000; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The set of traces that constitute the experiment + */ + protected ITmfTrace[] fTraces; + + /** + * The set of traces that constitute the experiment + */ + private boolean fInitialized = false; + + // ------------------------------------------------------------------------ + // Construction + // ------------------------------------------------------------------------ + + /** + * Default constructor + * + * @since 3.0 + */ + public TmfExperiment() { + super(); + } + + /** + * Constructor with parameters + * + * @param type + * the event type + * @param id + * the experiment id + * @param traces + * the experiment set of traces + */ + public TmfExperiment(final Class type, final String id, final ITmfTrace[] traces) { + this(type, id, traces, DEFAULT_INDEX_PAGE_SIZE, null); + } + + /** + * Constructor of experiment taking type, path, traces and resource + * + * @param type + * the event type + * @param id + * the experiment id + * @param traces + * the experiment set of traces + * @param resource + * the resource associated to the experiment + */ + public TmfExperiment(final Class type, final String id, final ITmfTrace[] traces, IResource resource) { + this(type, id, traces, DEFAULT_INDEX_PAGE_SIZE, resource); + } + + /** + * @param type + * the event type + * @param path + * the experiment path + * @param traces + * the experiment set of traces + * @param indexPageSize + * the experiment index page size + */ + public TmfExperiment(final Class type, final String path, final ITmfTrace[] traces, final int indexPageSize) { + this(type, path, traces, indexPageSize, null); + } + + /** + * Full constructor of an experiment, taking the type, path, traces, + * indexPageSize and resource + * + * @param type + * the event type + * @param path + * the experiment path + * @param traces + * the experiment set of traces + * @param indexPageSize + * the experiment index page size + * @param resource + * the resource associated to the experiment + */ + public TmfExperiment(final Class type, final String path, final ITmfTrace[] traces, final int indexPageSize, IResource resource) { + initExperiment(type, path, traces, indexPageSize, resource); + } + + @Override + protected ITmfTraceIndexer createIndexer(int interval) { + if (getCheckpointSize() > 0) { + return new TmfBTreeTraceIndexer(this, interval); + } + return super.createIndexer(interval); + } + + /** + * Clears the experiment + */ + @Override + public synchronized void dispose() { + + // Clean up the index if applicable + if (getIndexer() != null) { + getIndexer().dispose(); + } + + if (fTraces != null) { + for (final ITmfTrace trace : fTraces) { + trace.dispose(); + } + fTraces = null; + } + super.dispose(); + } + + // ------------------------------------------------------------------------ + // ITmfTrace - Initializers + // ------------------------------------------------------------------------ + + @Override + public void initTrace(final IResource resource, final String path, final Class type) { + } + + /** + * Initialization of an experiment, taking the type, path, traces, + * indexPageSize and resource + * + * @param type + * the event type + * @param path + * the experiment path + * @param traces + * the experiment set of traces + * @param indexPageSize + * the experiment index page size + * @param resource + * the resource associated to the experiment + * @since 3.0 + */ + public void initExperiment(final Class type, final String path, final ITmfTrace[] traces, final int indexPageSize, IResource resource) { + setCacheSize(indexPageSize); + setStreamingInterval(0); + setParser(this); + // traces have to be set before super.initialize() + fTraces = traces; + try { + super.initialize(resource, path, type); + } catch (TmfTraceException e) { + Activator.logError("Error initializing experiment", e); //$NON-NLS-1$ + } + + if (resource != null) { + this.synchronizeTraces(); + } + } + + /** + * @since 2.0 + */ + @Override + public IStatus validate(final IProject project, final String path) { + return Status.OK_STATUS; + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * Get the traces contained in this experiment. + * + * @return The array of contained traces + */ + public ITmfTrace[] getTraces() { + return fTraces; + } + + /** + * Returns the timestamp of the event at the requested index. If none, + * returns null. + * + * @param index + * the event index (rank) + * @return the corresponding event timestamp + * @since 2.0 + */ + public ITmfTimestamp getTimestamp(final int index) { + final ITmfContext context = seekEvent(index); + final ITmfEvent event = getNext(context); + context.dispose(); + return (event != null) ? event.getTimestamp() : null; + } + + // ------------------------------------------------------------------------ + // Request management + // ------------------------------------------------------------------------ + + /** + * @since 2.0 + */ + @Override + public synchronized ITmfContext armRequest(final ITmfEventRequest request) { + + // Make sure we have something to read from + if (fTraces == null) { + return null; + } + + if (!TmfTimestamp.BIG_BANG.equals(request.getRange().getStartTime()) + && request.getIndex() == 0) { + final ITmfContext context = seekEvent(request.getRange().getStartTime()); + request.setStartIndex((int) context.getRank()); + return context; + + } + + return seekEvent(request.getIndex()); + } + + // ------------------------------------------------------------------------ + // ITmfTrace trace positioning + // ------------------------------------------------------------------------ + + /** + * @since 3.0 + */ + @Override + public synchronized ITmfContext seekEvent(final ITmfLocation location) { + // Validate the location + if (location != null && !(location instanceof TmfExperimentLocation)) { + return null; // Throw an exception? + } + // Make sure we have something to read from + if (fTraces == null) { + return null; + } + + // Initialize the location array if necessary + TmfLocationArray locationArray = ((location == null) ? + new TmfLocationArray(fTraces.length) : + ((TmfExperimentLocation) location).getLocationInfo()); + + ITmfLocation[] locations = locationArray.getLocations(); + long[] ranks = locationArray.getRanks(); + + // Create and populate the context's traces contexts + final TmfExperimentContext context = new TmfExperimentContext(fTraces.length); + + // Position the traces + long rank = 0; + for (int i = 0; i < fTraces.length; i++) { + // Get the relevant trace attributes + final ITmfContext traceContext = fTraces[i].seekEvent(locations[i]); + context.setContext(i, traceContext); + traceContext.setRank(ranks[i]); + // update location after seek + locations[i] = traceContext.getLocation(); + context.setEvent(i, fTraces[i].getNext(traceContext)); + rank += ranks[i]; + } + + // Finalize context + context.setLocation(new TmfExperimentLocation(new TmfLocationArray(locations, ranks))); + context.setLastTrace(TmfExperimentContext.NO_TRACE); + context.setRank(rank); + + return context; + } + + // ------------------------------------------------------------------------ + // ITmfTrace - SeekEvent operations (returning a trace context) + // ------------------------------------------------------------------------ + + @Override + public ITmfContext seekEvent(final double ratio) { + final ITmfContext context = seekEvent(Math.round(ratio * getNbEvents())); + return context; + } + + /** + * @since 3.0 + */ + @Override + public double getLocationRatio(final ITmfLocation location) { + if (location instanceof TmfExperimentLocation) { + long rank = 0; + TmfLocationArray locationArray = ((TmfExperimentLocation) location).getLocationInfo(); + for (int i = 0; i < locationArray.size(); i++) { + rank += locationArray.getRank(i); + } + return (double) rank / getNbEvents(); + } + return 0.0; + } + + /** + * @since 3.0 + */ + @Override + public ITmfLocation getCurrentLocation() { + // never used + return null; + } + + // ------------------------------------------------------------------------ + // ITmfTrace trace positioning + // ------------------------------------------------------------------------ + + @Override + public synchronized ITmfEvent parseEvent(final ITmfContext context) { + final ITmfContext tmpContext = seekEvent(context.getLocation()); + final ITmfEvent event = getNext(tmpContext); + return event; + } + + @Override + public synchronized ITmfEvent getNext(ITmfContext context) { + + // Validate the context + if (!(context instanceof TmfExperimentContext)) { + return null; // Throw an exception? + } + + // Make sure that we have something to read from + if (fTraces == null) { + return null; + } + + TmfExperimentContext expContext = (TmfExperimentContext) context; + + // If an event was consumed previously, first get the next one from that + // trace + final int lastTrace = expContext.getLastTrace(); + if (lastTrace != TmfExperimentContext.NO_TRACE) { + final ITmfContext traceContext = expContext.getContext(lastTrace); + expContext.setEvent(lastTrace, fTraces[lastTrace].getNext(traceContext)); + expContext.setLastTrace(TmfExperimentContext.NO_TRACE); + } + + // Scan the candidate events and identify the "next" trace to read from + int trace = TmfExperimentContext.NO_TRACE; + ITmfTimestamp timestamp = TmfTimestamp.BIG_CRUNCH; + for (int i = 0; i < fTraces.length; i++) { + final ITmfEvent event = expContext.getEvent(i); + if (event != null && event.getTimestamp() != null) { + final ITmfTimestamp otherTS = event.getTimestamp(); + if (otherTS.compareTo(timestamp, true) < 0) { + trace = i; + timestamp = otherTS; + } + } + } + + ITmfEvent event = null; + if (trace != TmfExperimentContext.NO_TRACE) { + event = expContext.getEvent(trace); + if (event != null) { + updateAttributes(expContext, event.getTimestamp()); + expContext.increaseRank(); + expContext.setLastTrace(trace); + final ITmfContext traceContext = expContext.getContext(trace); + if (traceContext == null) { + throw new IllegalStateException(); + } + + // Update the experiment location + TmfLocationArray locationArray = new TmfLocationArray( + ((TmfExperimentLocation) expContext.getLocation()).getLocationInfo(), + trace, traceContext.getLocation(), traceContext.getRank()); + expContext.setLocation(new TmfExperimentLocation(locationArray)); + + processEvent(event); + } + } + + return event; + } + + /** + * @since 2.0 + */ + @Override + public ITmfTimestamp getInitialRangeOffset() { + if ((fTraces == null) || (fTraces.length == 0)) { + return super.getInitialRangeOffset(); + } + + ITmfTimestamp initTs = TmfTimestamp.BIG_CRUNCH; + for (int i = 0; i < fTraces.length; i++) { + ITmfTimestamp ts = fTraces[i].getInitialRangeOffset(); + if (ts.compareTo(initTs) < 0) { + initTs = ts; + } + } + return initTs; + } + + /** + * Get the path to the folder in the supplementary file where + * synchronization-related data can be kept so they are not deleted when the + * experiment is synchronized. Analysis involved in synchronization can put + * their supplementary files in there so they are preserved after + * synchronization. + * + * If the directory does not exist, it will be created. A return value of + * null means either the trace resource does not exist or + * supplementary resources cannot be kept. + * + * @param absolute + * If true, it returns the absolute path in the file + * system, including the supplementary file path. Otherwise, it + * returns only the directory name. + * @return The path to the folder where synchronization-related + * supplementary files can be kept or null if not + * available. + * @since 3.2 + */ + public String getSynchronizationFolder(boolean absolute) { + /* Set up the path to the synchronization file we'll use */ + IResource resource = this.getResource(); + String syncDirectory = null; + + try { + /* get the directory where the file will be stored. */ + if (resource != null) { + String fullDirectory = resource.getPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER); + /* Create the synchronization data directory if not present */ + if (fullDirectory != null) { + fullDirectory = fullDirectory + File.separator + SYNCHRONIZATION_DIRECTORY; + File syncDir = new File(fullDirectory); + syncDir.mkdirs(); + } + if (absolute) { + syncDirectory = fullDirectory; + } else { + syncDirectory = SYNCHRONIZATION_DIRECTORY; + } + } + } catch (CoreException e) { + return null; + } + + return syncDirectory; + } + + /** + * Synchronizes the traces of an experiment. By default it only tries to + * read a synchronization file if it exists + * + * @return The synchronization object + * @since 3.0 + */ + public synchronized SynchronizationAlgorithm synchronizeTraces() { + return synchronizeTraces(false); + } + + /** + * Synchronizes the traces of an experiment. + * + * @param doSync + * Whether to actually synchronize or just try opening a sync + * file + * @return The synchronization object + * @since 3.0 + */ + public synchronized SynchronizationAlgorithm synchronizeTraces(boolean doSync) { + + String syncDirectory = getSynchronizationFolder(true); + + final File syncFile = (syncDirectory != null) ? new File(syncDirectory + File.separator + SYNCHRONIZATION_FILE_NAME) : null; + + final SynchronizationAlgorithm syncAlgo = SynchronizationManager.synchronizeTraces(syncFile, Arrays.asList(fTraces), doSync); + + final TmfTraceSynchronizedSignal signal = new TmfTraceSynchronizedSignal(this, syncAlgo); + + /* Broadcast in separate thread to prevent deadlock */ + new Thread() { + @Override + public void run() { + broadcast(signal); + } + }.start(); + + return syncAlgo; + } + + @Override + @SuppressWarnings("nls") + public synchronized String toString() { + return "[TmfExperiment (" + getName() + ")]"; + } + + // ------------------------------------------------------------------------ + // Streaming support + // ------------------------------------------------------------------------ + + private synchronized void initializeStreamingMonitor() { + + if (fInitialized) { + return; + } + fInitialized = true; + + if (getStreamingInterval() == 0) { + final ITmfContext context = seekEvent(0); + final ITmfEvent event = getNext(context); + context.dispose(); + if (event == null) { + return; + } + final TmfTimeRange timeRange = new TmfTimeRange(event.getTimestamp(), TmfTimestamp.BIG_CRUNCH); + final TmfTraceRangeUpdatedSignal signal = new TmfTraceRangeUpdatedSignal(this, this, timeRange); + + // Broadcast in separate thread to prevent deadlock + new Thread() { + @Override + public void run() { + broadcast(signal); + } + }.start(); + return; + } + + final Thread thread = new Thread("Streaming Monitor for experiment " + getName()) { //$NON-NLS-1$ + private ITmfTimestamp safeTimestamp = null; + private ITmfTimestamp lastSafeTimestamp = null; + private TmfTimeRange timeRange = null; + + @Override + public void run() { + while (!executorIsShutdown()) { + if (!getIndexer().isIndexing()) { + ITmfTimestamp startTimestamp = TmfTimestamp.BIG_CRUNCH; + ITmfTimestamp endTimestamp = TmfTimestamp.BIG_BANG; + for (final ITmfTrace trace : fTraces) { + if (trace.getStartTime().compareTo(startTimestamp) < 0) { + startTimestamp = trace.getStartTime(); + } + if (trace.getStreamingInterval() != 0 && trace.getEndTime().compareTo(endTimestamp) > 0) { + endTimestamp = trace.getEndTime(); + } + } + if (safeTimestamp != null && (lastSafeTimestamp == null || safeTimestamp.compareTo(lastSafeTimestamp, false) > 0)) { + timeRange = new TmfTimeRange(startTimestamp, safeTimestamp); + lastSafeTimestamp = safeTimestamp; + } else { + timeRange = null; + } + safeTimestamp = endTimestamp; + if (timeRange != null) { + final TmfTraceRangeUpdatedSignal signal = + new TmfTraceRangeUpdatedSignal(TmfExperiment.this, TmfExperiment.this, timeRange); + broadcast(signal); + } + } + try { + Thread.sleep(getStreamingInterval()); + } catch (final InterruptedException e) { + e.printStackTrace(); + } + } + } + }; + thread.start(); + } + + @Override + public long getStreamingInterval() { + long interval = 0; + for (final ITmfTrace trace : fTraces) { + interval = Math.max(interval, trace.getStreamingInterval()); + } + return interval; + } + + // ------------------------------------------------------------------------ + // Signal handlers + // ------------------------------------------------------------------------ + + @Override + @TmfSignalHandler + public void traceOpened(TmfTraceOpenedSignal signal) { + if (signal.getTrace() == this) { + initializeStreamingMonitor(); + + /* Initialize the analysis */ + MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, null, null); + status.add(executeAnalysis()); + if (!status.isOK()) { + Activator.log(status); + } + TmfTraceManager.refreshSupplementaryFiles(this); + } + } + + /** + * @since 3.0 + */ + @Override + public synchronized int getCheckpointSize() { + int totalCheckpointSize = 0; + try { + if (fTraces != null) { + for (final ITmfTrace trace : fTraces) { + if (!(trace instanceof ITmfPersistentlyIndexable)) { + return 0; + } + + ITmfPersistentlyIndexable persistableIndexTrace = (ITmfPersistentlyIndexable) trace; + int currentTraceCheckpointSize = persistableIndexTrace.getCheckpointSize(); + if (currentTraceCheckpointSize <= 0) { + return 0; + } + totalCheckpointSize += currentTraceCheckpointSize; + // each entry in the TmfLocationArray has a rank in addition + // of the location + totalCheckpointSize += 8; + } + } + } catch (UnsupportedOperationException e) { + return 0; + } + + return totalCheckpointSize; + } + + /** + * @since 3.0 + */ + @Override + public ITmfLocation restoreLocation(ByteBuffer bufferIn) { + ITmfLocation[] locations = new ITmfLocation[fTraces.length]; + long[] ranks = new long[fTraces.length]; + for (int i = 0; i < fTraces.length; ++i) { + final ITmfTrace trace = fTraces[i]; + locations[i] = ((ITmfPersistentlyIndexable) trace).restoreLocation(bufferIn); + ranks[i] = bufferIn.getLong(); + } + TmfLocationArray arr = new TmfLocationArray(locations, ranks); + TmfExperimentLocation l = new TmfExperimentLocation(arr); + return l; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTrace.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTrace.java new file mode 100644 index 0000000000..ca8da33d71 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTrace.java @@ -0,0 +1,826 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Updated as per TMF Trace Model 1.0 + * Patrick Tasse - Updated for removal of context clone + * Geneviève Bastien - Added timestamp transforms, its saving to file and + * timestamp creation functions + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace; + +import java.io.File; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager; +import org.eclipse.tracecompass.tmf.core.component.TmfEventProvider; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceRangeUpdatedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceUpdatedSignal; +import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform; +import org.eclipse.tracecompass.tmf.core.synchronization.TimestampTransformFactory; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +/** + * Abstract implementation of ITmfTrace. + *

+ * Since the concept of 'location' is trace specific, the concrete classes have + * to provide the related methods, namely: + *

    + *
  • public ITmfLocation getCurrentLocation() + *
  • public double getLocationRatio(ITmfLocation location) + *
  • public ITmfContext seekEvent(ITmfLocation location) + *
  • public ITmfContext seekEvent(double ratio) + *
  • public IStatus validate(IProject project, String path) + *
+ * A concrete trace must provide its corresponding parser. A common way to + * accomplish this is by making the concrete class extend TmfTrace and + * implement ITmfEventParser. + *

+ * When constructing an event, the concrete trace should use the trace's + * timestamp transform to create the timestamp, by either transforming the + * parsed time value directly or by using the method createTimestamp(). + *

+ * The concrete class can either specify its own indexer or use the provided + * TmfCheckpointIndexer (default). In this case, the trace cache size will be + * used as checkpoint interval. + * + * @version 1.0 + * @author Francois Chouinard + * + * @see ITmfEvent + * @see ITmfTraceIndexer + * @see ITmfEventParser + */ +public abstract class TmfTrace extends TmfEventProvider implements ITmfTrace, ITmfTraceCompleteness { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // The resource used for persistent properties for this trace + private IResource fResource; + + // The trace path + private String fPath; + + // The trace cache page size + private int fCacheSize = ITmfTrace.DEFAULT_TRACE_CACHE_SIZE; + + // The number of events collected (so far) + private volatile long fNbEvents = 0; + + // The time span of the event stream + private ITmfTimestamp fStartTime = TmfTimestamp.BIG_BANG; + private ITmfTimestamp fEndTime = TmfTimestamp.BIG_BANG; + + // The trace streaming interval (0 = no streaming) + private long fStreamingInterval = 0; + + // The trace indexer + private ITmfTraceIndexer fIndexer; + + // The trace parser + private ITmfEventParser fParser; + + private ITmfTimestampTransform fTsTransform; + + private final Map fAnalysisModules = + Collections.synchronizedMap(new LinkedHashMap()); + + // ------------------------------------------------------------------------ + // Construction + // ------------------------------------------------------------------------ + + /** + * The default, parameterless, constructor + */ + public TmfTrace() { + super(); + fIndexer = createIndexer(DEFAULT_BLOCK_SIZE); + } + + /** + * Full constructor. + * + * @param resource + * The resource associated to the trace + * @param type + * The type of events that will be read from this trace + * @param path + * The path to the trace on the filesystem + * @param cacheSize + * The trace cache size. Pass '-1' to use the default specified + * in {@link ITmfTrace#DEFAULT_TRACE_CACHE_SIZE} + * @param interval + * The trace streaming interval. You can use '0' for post-mortem + * traces. + * @param parser + * The trace event parser. Use 'null' if (and only if) the trace + * object itself is also the ITmfEventParser to be used. + * @throws TmfTraceException + * If something failed during the opening + */ + protected TmfTrace(final IResource resource, + final Class type, + final String path, + final int cacheSize, + final long interval, + final ITmfEventParser parser) + throws TmfTraceException { + super(); + fCacheSize = (cacheSize > 0) ? cacheSize : ITmfTrace.DEFAULT_TRACE_CACHE_SIZE; + fStreamingInterval = interval; + fParser = parser; + initialize(resource, path, type); + } + + /** + * Copy constructor + * + * @param trace the original trace + * @throws TmfTraceException Should not happen usually + */ + public TmfTrace(final TmfTrace trace) throws TmfTraceException { + super(); + if (trace == null) { + throw new IllegalArgumentException(); + } + fCacheSize = trace.getCacheSize(); + fStreamingInterval = trace.getStreamingInterval(); + fParser = trace.fParser; + initialize(trace.getResource(), trace.getPath(), trace.getEventType()); + } + + /** + * Creates the indexer instance. Classes extending this class can override + * this to provide a different indexer implementation. + * + * @param interval the checkpoints interval + * + * @return the indexer + * @since 3.0 + */ + protected ITmfTraceIndexer createIndexer(int interval) { + return new TmfCheckpointIndexer(this, interval); + } + + // ------------------------------------------------------------------------ + // ITmfTrace - Initializers + // ------------------------------------------------------------------------ + + @Override + public void initTrace(final IResource resource, final String path, final Class type, String name) throws TmfTraceException { + setName(name); + initTrace(resource, path, type); + } + + @Override + public void initTrace(final IResource resource, final String path, final Class type) throws TmfTraceException { + initialize(resource, path, type); + } + + /** + * Initialize the trace common attributes and the base component. + * + * @param resource the Eclipse resource (trace) + * @param path the trace path + * @param type the trace event type + * + * @throws TmfTraceException If something failed during the initialization + */ + protected void initialize(final IResource resource, + final String path, + final Class type) + throws TmfTraceException { + if (path == null) { + throw new TmfTraceException("Invalid trace path"); //$NON-NLS-1$ + } + fPath = path; + fResource = resource; + String traceName = getName(); + if (traceName == null || traceName.isEmpty()) { + traceName = (resource != null) ? resource.getName() : new Path(path).lastSegment(); + } + if (fParser == null) { + if (this instanceof ITmfEventParser) { + fParser = (ITmfEventParser) this; + } else { + throw new TmfTraceException("Invalid trace parser"); //$NON-NLS-1$ + } + } + super.init(traceName, type); + // register as VIP after super.init() because TmfComponent registers to signal manager there + TmfSignalManager.registerVIP(this); + if (fIndexer != null) { + fIndexer.dispose(); + } + fIndexer = createIndexer(fCacheSize); + } + + /** + * Indicates if the path points to an existing file/directory + * + * @param path the path to test + * @return true if the file/directory exists + */ + protected boolean fileExists(final String path) { + final File file = new File(path); + return file.exists(); + } + + /** + * @since 2.0 + */ + @Override + public void indexTrace(boolean waitForCompletion) { + getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, waitForCompletion); + } + + /** + * Instantiate the applicable analysis modules and executes the analysis + * modules that are meant to be automatically executed + * + * @return An IStatus indicating whether the analysis could be run + * successfully or not + * @since 3.0 + */ + protected IStatus executeAnalysis() { + MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, null, null); + Map modules = TmfAnalysisManager.getAnalysisModules(this.getClass()); + for (IAnalysisModuleHelper helper : modules.values()) { + try { + IAnalysisModule module = helper.newModule(this); + fAnalysisModules.put(module.getId(), module); + if (module.isAutomatic()) { + status.add(module.schedule()); + } + } catch (TmfAnalysisException e) { + status.add(new Status(IStatus.WARNING, Activator.PLUGIN_ID, e.getMessage())); + } + } + return status; + } + + /** + * @since 3.0 + */ + @Override + public IAnalysisModule getAnalysisModule(String analysisId) { + return fAnalysisModules.get(analysisId); + } + + + /** + * @since 3.0 + */ + @Override + public Iterable getAnalysisModules() { + synchronized (fAnalysisModules) { + Set modules = new HashSet<>(fAnalysisModules.values()); + return modules; + } + } + + /** + * @since 3.0 + */ + @Override + public T getAnalysisModuleOfClass(Class moduleClass, String id) { + Iterable modules = getAnalysisModulesOfClass(moduleClass); + for (T module : modules) { + if (id.equals(module.getId())) { + return module; + } + } + return null; + } + + /** + * @since 3.0 + */ + @Override + public Iterable getAnalysisModulesOfClass(Class moduleClass) { + Set modules = new HashSet<>(); + synchronized (fAnalysisModules) { + for (Entry entry : fAnalysisModules.entrySet()) { + if (moduleClass.isAssignableFrom(entry.getValue().getClass())) { + modules.add(moduleClass.cast(entry.getValue())); + } + } + } + return modules; + } + + /** + * Clears the trace + */ + @Override + public synchronized void dispose() { + /* Clean up the index if applicable */ + if (getIndexer() != null) { + getIndexer().dispose(); + } + + /* Clean up the analysis modules */ + synchronized (fAnalysisModules) { + for (IAnalysisModule module : fAnalysisModules.values()) { + module.dispose(); + } + fAnalysisModules.clear(); + } + + super.dispose(); + } + + // ------------------------------------------------------------------------ + // ITmfTrace - Basic getters + // ------------------------------------------------------------------------ + + @Override + public Class getEventType() { + return super.getType(); + } + + @Override + public IResource getResource() { + return fResource; + } + + @Override + public String getPath() { + return fPath; + } + + @Override + public int getCacheSize() { + return fCacheSize; + } + + @Override + public long getStreamingInterval() { + return fStreamingInterval; + } + + /** + * @return the trace indexer + * @since 3.0 + */ + protected ITmfTraceIndexer getIndexer() { + return fIndexer; + } + + /** + * @return the trace parser + */ + protected ITmfEventParser getParser() { + return fParser; + } + + // ------------------------------------------------------------------------ + // ITmfTrace - Trace characteristics getters + // ------------------------------------------------------------------------ + + @Override + public long getNbEvents() { + return fNbEvents; + } + + /** + * @since 2.0 + */ + @Override + public TmfTimeRange getTimeRange() { + return new TmfTimeRange(fStartTime, fEndTime); + } + + /** + * @since 2.0 + */ + @Override + public ITmfTimestamp getStartTime() { + return fStartTime; + } + + /** + * @since 2.0 + */ + @Override + public ITmfTimestamp getEndTime() { + return fEndTime; + } + + /** + * @since 2.0 + */ + @Override + public ITmfTimestamp getInitialRangeOffset() { + final long DEFAULT_INITIAL_OFFSET_VALUE = (1L * 100 * 1000 * 1000); // .1sec + return new TmfTimestamp(DEFAULT_INITIAL_OFFSET_VALUE, ITmfTimestamp.NANOSECOND_SCALE); + } + + /** + * @since 3.0 + */ + @Override + public String getHostId() { + return this.getName(); + } + + // ------------------------------------------------------------------------ + // Convenience setters + // ------------------------------------------------------------------------ + + /** + * Set the trace cache size. Must be done at initialization time. + * + * @param cacheSize The trace cache size + */ + protected void setCacheSize(final int cacheSize) { + fCacheSize = cacheSize; + } + + /** + * Set the trace known number of events. This can be quite dynamic + * during indexing or for live traces. + * + * @param nbEvents The number of events + */ + protected synchronized void setNbEvents(final long nbEvents) { + fNbEvents = (nbEvents > 0) ? nbEvents : 0; + } + + /** + * Update the trace events time range + * + * @param range the new time range + * @since 2.0 + */ + protected void setTimeRange(final TmfTimeRange range) { + fStartTime = range.getStartTime(); + fEndTime = range.getEndTime(); + } + + /** + * Update the trace chronologically first event timestamp + * + * @param startTime the new first event timestamp + * @since 2.0 + */ + protected void setStartTime(final ITmfTimestamp startTime) { + fStartTime = startTime; + } + + /** + * Update the trace chronologically last event timestamp + * + * @param endTime the new last event timestamp + * @since 2.0 + */ + protected void setEndTime(final ITmfTimestamp endTime) { + fEndTime = endTime; + } + + /** + * Set the polling interval for live traces (default = 0 = no streaming). + * + * @param interval the new trace streaming interval + */ + protected void setStreamingInterval(final long interval) { + fStreamingInterval = (interval > 0) ? interval : 0; + } + + /** + * Set the trace parser. Must be done at initialization time. + * + * @param parser the new trace parser + */ + protected void setParser(final ITmfEventParser parser) { + fParser = parser; + } + + // ------------------------------------------------------------------------ + // ITmfTrace - SeekEvent operations (returning a trace context) + // ------------------------------------------------------------------------ + + @Override + public synchronized ITmfContext seekEvent(final long rank) { + + // A rank <= 0 indicates to seek the first event + if (rank <= 0) { + ITmfContext context = seekEvent((ITmfLocation) null); + context.setRank(0); + return context; + } + + // Position the trace at the checkpoint + final ITmfContext context = fIndexer.seekIndex(rank); + + // And locate the requested event context + long pos = context.getRank(); + if (pos < rank) { + ITmfEvent event = getNext(context); + while ((event != null) && (++pos < rank)) { + event = getNext(context); + } + } + return context; + } + + /** + * @since 2.0 + */ + @Override + public synchronized ITmfContext seekEvent(final ITmfTimestamp timestamp) { + + // A null timestamp indicates to seek the first event + if (timestamp == null) { + ITmfContext context = seekEvent((ITmfLocation) null); + context.setRank(0); + return context; + } + + // Position the trace at the checkpoint + ITmfContext context = fIndexer.seekIndex(timestamp); + + // And locate the requested event context + ITmfLocation previousLocation = context.getLocation(); + long previousRank = context.getRank(); + ITmfEvent event = getNext(context); + while (event != null && event.getTimestamp().compareTo(timestamp, false) < 0) { + previousLocation = context.getLocation(); + previousRank = context.getRank(); + event = getNext(context); + } + if (event == null) { + context.setLocation(null); + context.setRank(ITmfContext.UNKNOWN_RANK); + } else { + context.dispose(); + context = seekEvent(previousLocation); + context.setRank(previousRank); + } + return context; + } + + // ------------------------------------------------------------------------ + // ITmfTrace - Read operations (returning an actual event) + // ------------------------------------------------------------------------ + + @Override + public synchronized ITmfEvent getNext(final ITmfContext context) { + // parseEvent() does not update the context + final ITmfEvent event = fParser.parseEvent(context); + if (event != null) { + updateAttributes(context, event.getTimestamp()); + context.setLocation(getCurrentLocation()); + context.increaseRank(); + processEvent(event); + } + return event; + } + + /** + * Hook for special event processing by the concrete class + * (called by TmfTrace.getEvent()) + * + * @param event the event + */ + protected void processEvent(final ITmfEvent event) { + // Do nothing + } + + /** + * Update the trace attributes + * + * @param context the current trace context + * @param timestamp the corresponding timestamp + * @since 2.0 + */ + protected synchronized void updateAttributes(final ITmfContext context, final ITmfTimestamp timestamp) { + if (fStartTime.equals(TmfTimestamp.BIG_BANG) || (fStartTime.compareTo(timestamp, false) > 0)) { + fStartTime = timestamp; + } + if (fEndTime.equals(TmfTimestamp.BIG_CRUNCH) || (fEndTime.compareTo(timestamp, false) < 0)) { + fEndTime = timestamp; + } + if (context.hasValidRank()) { + long rank = context.getRank(); + if (fNbEvents <= rank) { + fNbEvents = rank + 1; + } + if (fIndexer != null) { + fIndexer.updateIndex(context, timestamp); + } + } + } + + // ------------------------------------------------------------------------ + // TmfDataProvider + // ------------------------------------------------------------------------ + + /** + * @since 2.0 + */ + @Override + public synchronized ITmfContext armRequest(final ITmfEventRequest request) { + if (executorIsShutdown()) { + return null; + } + if (!TmfTimestamp.BIG_BANG.equals(request.getRange().getStartTime()) + && (request.getIndex() == 0)) { + final ITmfContext context = seekEvent(request.getRange().getStartTime()); + request.setStartIndex((int) context.getRank()); + return context; + + } + return seekEvent(request.getIndex()); + } + + // ------------------------------------------------------------------------ + // Signal handlers + // ------------------------------------------------------------------------ + + /** + * Handler for the Trace Opened signal + * + * @param signal + * The incoming signal + * @since 2.0 + */ + @TmfSignalHandler + public void traceOpened(TmfTraceOpenedSignal signal) { + boolean signalIsForUs = false; + for (ITmfTrace trace : TmfTraceManager.getTraceSet(signal.getTrace())) { + if (trace == this) { + signalIsForUs = true; + break; + } + } + + if (!signalIsForUs) { + return; + } + + /* + * The signal is either for this trace, or for an experiment containing + * this trace. + */ + IStatus status = executeAnalysis(); + if (!status.isOK()) { + Activator.log(status); + } + + TmfTraceManager.refreshSupplementaryFiles(this); + + if (signal.getTrace() == this) { + /* Additionally, the signal is directly for this trace. */ + if (getNbEvents() == 0) { + return; + } + + /* For a streaming trace, the range updated signal should be sent + * by the subclass when a new safe time is determined. + */ + if (getStreamingInterval() > 0) { + return; + } + + if (isComplete()) { + final TmfTimeRange timeRange = new TmfTimeRange(getStartTime(), TmfTimestamp.BIG_CRUNCH); + final TmfTraceRangeUpdatedSignal rangeUpdatedsignal = new TmfTraceRangeUpdatedSignal(this, this, timeRange); + + // Broadcast in separate thread to prevent deadlock + broadcastAsync(rangeUpdatedsignal); + } + return; + } + } + + /** + * Signal handler for the TmfTraceRangeUpdatedSignal signal + * + * @param signal The incoming signal + * @since 2.0 + */ + @TmfSignalHandler + public void traceRangeUpdated(final TmfTraceRangeUpdatedSignal signal) { + if (signal.getTrace() == this) { + getIndexer().buildIndex(getNbEvents(), signal.getRange(), false); + } + } + + /** + * Signal handler for the TmfTraceUpdatedSignal signal + * + * @param signal The incoming signal + * @since 3.0 + */ + @TmfSignalHandler + public void traceUpdated(final TmfTraceUpdatedSignal signal) { + if (signal.getSource() == getIndexer()) { + fNbEvents = signal.getNbEvents(); + fStartTime = signal.getRange().getStartTime(); + fEndTime = signal.getRange().getEndTime(); + } + } + + // ------------------------------------------------------------------------ + // Timestamp transformation functions + // ------------------------------------------------------------------------ + + /** + * @since 3.0 + */ + @Override + public ITmfTimestampTransform getTimestampTransform() { + if (fTsTransform == null) { + fTsTransform = TimestampTransformFactory.getTimestampTransform(getResource()); + } + return fTsTransform; + } + + /** + * @since 3.0 + */ + @Override + public void setTimestampTransform(final ITmfTimestampTransform tt) { + fTsTransform = tt; + TimestampTransformFactory.setTimestampTransform(getResource(), tt); + } + + /** + * @since 3.0 + */ + @Override + public ITmfTimestamp createTimestamp(long ts) { + return new TmfNanoTimestamp(getTimestampTransform().transform(ts)); + } + + // ------------------------------------------------------------------------ + // toString + // ------------------------------------------------------------------------ + + @Override + @SuppressWarnings("nls") + public synchronized String toString() { + return "TmfTrace [fPath=" + fPath + ", fCacheSize=" + fCacheSize + + ", fNbEvents=" + fNbEvents + ", fStartTime=" + fStartTime + + ", fEndTime=" + fEndTime + ", fStreamingInterval=" + fStreamingInterval + "]"; + } + + /** + * @since 3.1 + */ + @Override + public boolean isComplete() { + /* + * Be default, all traces are "complete" which means no more data will + * be added later + */ + return true; + } + + /** + * @since 3.1 + */ + @Override + public void setComplete(boolean isComplete) { + /* + * This should be overridden by trace classes that can support live + * reading (traces in an incomplete state) + */ + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTraceContext.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTraceContext.java new file mode 100644 index 0000000000..96bfa7555e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTraceContext.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + * Patrick Tasse - Support selection range + * Xavier Raynaud - Support filters tracking + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace; + +import org.eclipse.core.resources.IFile; +import org.eclipse.tracecompass.tmf.core.filter.ITmfFilter; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; + +/** + * Context of a trace, which is the representation of the "view" the user + * currently has on this trace (window time range, selected time or time range). + * + * TODO could be extended to support the notion of current location too. + * + * @author Alexandre Montplaisir + * @since 2.0 + */ +final class TmfTraceContext { + + static final TmfTraceContext NULL_CONTEXT = + new TmfTraceContext(TmfTimestamp.BIG_CRUNCH, TmfTimestamp.BIG_CRUNCH, TmfTimeRange.NULL_RANGE, null); + + private final TmfTimeRange fSelection; + private final TmfTimeRange fWindowRange; + private final IFile fEditorFile; + private final ITmfFilter fFilter; + + public TmfTraceContext(ITmfTimestamp beginTs, ITmfTimestamp endTs, TmfTimeRange tr, IFile editorFile) { + fSelection = new TmfTimeRange(beginTs, endTs); + fWindowRange = tr; + fEditorFile = editorFile; + fFilter = null; + } + + public TmfTraceContext(TmfTraceContext prevCtx, ITmfTimestamp beginTs, ITmfTimestamp endTs) { + fSelection = new TmfTimeRange(beginTs, endTs); + fWindowRange = prevCtx.fWindowRange; + fEditorFile = prevCtx.fEditorFile; + fFilter = prevCtx.fFilter; + } + + public TmfTraceContext(TmfTraceContext prevCtx, TmfTimeRange tr) { + fSelection = prevCtx.fSelection; + fWindowRange = tr; + fEditorFile = prevCtx.fEditorFile; + fFilter = prevCtx.fFilter; + } + + /** + * @param prevCtx + * The previous context + * @param filter + * The applied filter + * @since 2.2 + */ + public TmfTraceContext(TmfTraceContext prevCtx, ITmfFilter filter) { + fSelection = prevCtx.fSelection; + fWindowRange = prevCtx.fWindowRange; + fEditorFile = prevCtx.fEditorFile; + fFilter = filter; + } + + public ITmfTimestamp getSelectionBegin() { + return fSelection.getStartTime(); + } + + public ITmfTimestamp getSelectionEnd() { + return fSelection.getEndTime(); + } + + public TmfTimeRange getWindowRange() { + return fWindowRange; + } + + public IFile getEditorFile() { + return fEditorFile; + } + + /** + * @return the current filter applied to the trace + * @since 2.2 + */ + public ITmfFilter getFilter() { + return fFilter; + } + + public boolean isValid() { + if (fSelection.getStartTime().compareTo(TmfTimestamp.ZERO) <= 0 || + fSelection.getEndTime().compareTo(TmfTimestamp.ZERO) <= 0 || + fWindowRange.getEndTime().compareTo(fWindowRange.getStartTime()) <= 0) { + return false; + } + return true; + } + + @Override + public String toString() { + return getClass().getSimpleName() + "[fSelection=" + fSelection + //$NON-NLS-1$ + ", fWindowRange=" + fWindowRange + ']'; //$NON-NLS-1$ + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTraceManager.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTraceManager.java new file mode 100644 index 0000000000..da3d90589d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTraceManager.java @@ -0,0 +1,524 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + * Patrick Tasse - Support selection range + * Xavier Raynaud - Support filters tracking + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace; + +import java.io.File; +import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.filter.ITmfFilter; +import org.eclipse.tracecompass.tmf.core.signal.TmfEventFilterAppliedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfRangeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; + +/** + * Central trace manager for TMF. It tracks the currently opened traces and + * experiment, as well as the currently-selected time or time range and the + * current window time range for each one of those. It also tracks filters + * applied for each trace. + * + * It's a singleton class, so only one instance should exist (available via + * {@link #getInstance()}). + * + * @author Alexandre Montplaisir + * @since 2.0 + */ +public final class TmfTraceManager { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final Map fTraces; + + /** The currently-selected trace. Should always be part of the trace map */ + private ITmfTrace fCurrentTrace = null; + + private static final String TEMP_DIR_NAME = ".temp"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + private TmfTraceManager() { + fTraces = new LinkedHashMap<>(); + TmfSignalManager.registerVIP(this); + } + + /** Singleton instance */ + private static TmfTraceManager tm = null; + + /** + * Get an instance of the trace manager. + * + * @return The trace manager + */ + public static synchronized TmfTraceManager getInstance() { + if (tm == null) { + tm = new TmfTraceManager(); + } + return tm; + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * @return The begin timestamp of selection + * @since 2.1 + */ + public ITmfTimestamp getSelectionBeginTime() { + return getCurrentTraceContext().getSelectionBegin(); + } + + /** + * @return The end timestamp of selection + * @since 2.1 + */ + public ITmfTimestamp getSelectionEndTime() { + return getCurrentTraceContext().getSelectionEnd(); + } + + /** + * Return the current window time range. + * + * @return the current window time range + */ + public synchronized TmfTimeRange getCurrentRange() { + return getCurrentTraceContext().getWindowRange(); + } + + /** + * Gets the filter applied to the current trace + * + * @return + * a filter, or null + * @since 2.2 + */ + public synchronized ITmfFilter getCurrentFilter() { + return getCurrentTraceContext().getFilter(); + } + + /** + * Get the currently selected trace (normally, the focused editor). + * + * @return The active trace + */ + public synchronized ITmfTrace getActiveTrace() { + return fCurrentTrace; + } + + /** + * Get the trace set of the currently active trace. + * + * @return The active trace set + * @see #getTraceSet(ITmfTrace) + */ + public synchronized ITmfTrace[] getActiveTraceSet() { + final ITmfTrace trace = fCurrentTrace; + return getTraceSet(trace); + } + + /** + * Get the currently-opened traces, as an unmodifiable set. + * + * @return A set containing the opened traces + */ + public synchronized Set getOpenedTraces() { + return Collections.unmodifiableSet(fTraces.keySet()); + } + + /** + * Get the editor file for an opened trace. + * + * @param trace + * the trace + * @return the editor file or null if the trace is not opened + * @since 3.0 + */ + public synchronized IFile getTraceEditorFile(ITmfTrace trace) { + TmfTraceContext ctx = fTraces.get(trace); + if (ctx != null) { + return ctx.getEditorFile(); + } + return null; + } + + private TmfTraceContext getCurrentTraceContext() { + TmfTraceContext curCtx = fTraces.get(fCurrentTrace); + if (curCtx == null) { + /* There are no traces opened at the moment. */ + return TmfTraceContext.NULL_CONTEXT; + } + return curCtx; + } + + // ------------------------------------------------------------------------ + // Public utility methods + // ------------------------------------------------------------------------ + + /** + * Get the trace set of a given trace. For a standard trace, this is simply + * an array with only that trace in it. For experiments, this is an array of + * all the traces contained in this experiment. + * + * @param trace + * The trace or experiment + * @return The corresponding trace set + */ + public static ITmfTrace[] getTraceSet(ITmfTrace trace) { + if (trace == null) { + return null; + } + if (trace instanceof TmfExperiment) { + TmfExperiment exp = (TmfExperiment) trace; + return exp.getTraces(); + } + return new ITmfTrace[] { trace }; + } + + /** + * Get the trace set of a given trace or experiment, including the + * experiment. For a standard trace, this is simply a set containing only + * that trace. For experiments, it is the set of all the traces contained in + * this experiment, along with the experiment. + * + * @param trace + * The trace or experiment + * @return The corresponding trace set, including the experiment + * @since 3.1 + */ + public static @NonNull Set getTraceSetWithExperiment(ITmfTrace trace) { + if (trace == null) { + @SuppressWarnings("null") + @NonNull Set emptySet = Collections.EMPTY_SET; + return emptySet; + } + if (trace instanceof TmfExperiment) { + TmfExperiment exp = (TmfExperiment) trace; + ITmfTrace[] traces = exp.getTraces(); + Set alltraces = new LinkedHashSet<>(Arrays.asList(traces)); + alltraces.add(exp); + return alltraces; + } + @SuppressWarnings("null") + @NonNull Set singleton = Collections.singleton(trace); + return singleton; + } + + /** + * Return the path (as a string) to the directory for supplementary files to + * use with a given trace. If no supplementary file directory has been + * configured, a temporary directory based on the trace's name will be + * provided. + * + * @param trace + * The trace + * @return The path to the supplementary file directory (trailing slash is + * INCLUDED!) + */ + public static String getSupplementaryFileDir(ITmfTrace trace) { + IResource resource = trace.getResource(); + if (resource == null) { + return getTemporaryDir(trace); + } + + String supplDir = null; + try { + supplDir = resource.getPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER); + } catch (CoreException e) { + return getTemporaryDir(trace); + } + return supplDir + File.separator; + } + + /** + * Refresh the supplementary files resources for a trace, so it can pick up + * new files that got created. + * + * @param trace + * The trace for which to refresh the supplementary files + * @since 3.0 + */ + public static void refreshSupplementaryFiles(ITmfTrace trace) { + IResource resource = trace.getResource(); + if (resource != null && resource.exists()) { + String supplFolderPath = getSupplementaryFileDir(trace); + IProject project = resource.getProject(); + /* Remove the project's path from the supplementary path dir */ + if (!supplFolderPath.startsWith(project.getLocationURI().getPath())) { + Activator.logWarning(String.format("Supplementary files folder for trace %s is not within the project.", trace.getName())); //$NON-NLS-1$ + return; + } + IFolder supplFolder = project.getFolder(supplFolderPath.substring(project.getLocationURI().getPath().length())); + if (supplFolder.exists()) { + try { + supplFolder.refreshLocal(IResource.DEPTH_INFINITE, null); + } catch (CoreException e) { + Activator.logError("Error refreshing resources", e); //$NON-NLS-1$ + } + } + } + } + + // ------------------------------------------------------------------------ + // Signal handlers + // ------------------------------------------------------------------------ + + /** + * Signal handler for the traceOpened signal. + * + * @param signal + * The incoming signal + */ + @TmfSignalHandler + public synchronized void traceOpened(final TmfTraceOpenedSignal signal) { + final ITmfTrace trace = signal.getTrace(); + final IFile editorFile = signal.getEditorFile(); + final ITmfTimestamp startTs = trace.getStartTime(); + + /* Calculate the initial time range */ + final int SCALE = ITmfTimestamp.NANOSECOND_SCALE; + long offset = trace.getInitialRangeOffset().normalize(0, SCALE).getValue(); + long endTime = startTs.normalize(0, SCALE).getValue() + offset; + final TmfTimeRange startTr = new TmfTimeRange(startTs, new TmfTimestamp(endTime, SCALE)); + + final TmfTraceContext startCtx = new TmfTraceContext(startTs, startTs, startTr, editorFile); + + fTraces.put(trace, startCtx); + + /* We also want to set the newly-opened trace as the active trace */ + fCurrentTrace = trace; + } + + + /** + * Handler for the TmfTraceSelectedSignal. + * + * @param signal + * The incoming signal + */ + @TmfSignalHandler + public synchronized void traceSelected(final TmfTraceSelectedSignal signal) { + final ITmfTrace newTrace = signal.getTrace(); + if (!fTraces.containsKey(newTrace)) { + throw new RuntimeException(); + } + fCurrentTrace = newTrace; + } + + /** + * Signal handler for the filterApplied signal. + * + * @param signal + * The incoming signal + * @since 2.2 + */ + @TmfSignalHandler + public synchronized void filterApplied(TmfEventFilterAppliedSignal signal) { + final ITmfTrace newTrace = signal.getTrace(); + TmfTraceContext context = fTraces.get(newTrace); + if (context == null) { + throw new RuntimeException(); + } + fTraces.put(newTrace, new TmfTraceContext(context, signal.getEventFilter())); + } + + /** + * Signal handler for the traceClosed signal. + * + * @param signal + * The incoming signal + */ + @TmfSignalHandler + public synchronized void traceClosed(final TmfTraceClosedSignal signal) { + fTraces.remove(signal.getTrace()); + if (fTraces.size() == 0) { + fCurrentTrace = null; + /* + * In other cases, we should receive a traceSelected signal that + * will indicate which trace is the new one. + */ + } + } + + /** + * Signal handler for the TmfTimeSynchSignal signal. + * + * The current time of *all* traces whose range contains the requested new + * selection time range will be updated. + * + * @param signal + * The incoming signal + */ + @TmfSignalHandler + public synchronized void timeUpdated(final TmfTimeSynchSignal signal) { + final ITmfTimestamp beginTs = signal.getBeginTime(); + final ITmfTimestamp endTs = signal.getEndTime(); + + for (Map.Entry entry : fTraces.entrySet()) { + final ITmfTrace trace = entry.getKey(); + if (beginTs.intersects(getValidTimeRange(trace)) || endTs.intersects(getValidTimeRange(trace))) { + TmfTraceContext prevCtx = entry.getValue(); + TmfTraceContext newCtx = new TmfTraceContext(prevCtx, beginTs, endTs); + entry.setValue(newCtx); + } + } + } + + /** + * Signal handler for the TmfRangeSynchSignal signal. + * + * The current window time range of *all* valid traces will be updated + * to the new requested times. + * + * @param signal + * The incoming signal + */ + @TmfSignalHandler + public synchronized void timeRangeUpdated(final TmfRangeSynchSignal signal) { + for (Map.Entry entry : fTraces.entrySet()) { + final ITmfTrace trace = entry.getKey(); + final TmfTraceContext curCtx = entry.getValue(); + + final TmfTimeRange validTr = getValidTimeRange(trace); + + /* Determine the new time range */ + TmfTimeRange targetTr = signal.getCurrentRange().getIntersection(validTr); + TmfTimeRange newTr = (targetTr == null ? curCtx.getWindowRange() : targetTr); + + /* Update the values */ + TmfTraceContext newCtx = new TmfTraceContext(curCtx, newTr); + entry.setValue(newCtx); + } + } + + // ------------------------------------------------------------------------ + // Private utility methods + // ------------------------------------------------------------------------ + + /** + * Return the valid time range of a trace (not the current window time + * range, but the range of all possible valid timestamps). + * + * For a real trace this is the whole range of the trace. For an experiment, + * it goes from the start time of the earliest trace to the end time of the + * latest one. + * + * @param trace + * The trace to check for + * @return The valid time span, or 'null' if the trace is not valid + */ + private TmfTimeRange getValidTimeRange(ITmfTrace trace) { + if (!fTraces.containsKey(trace)) { + /* Trace is not part of the currently opened traces */ + return null; + } + if (!(trace instanceof TmfExperiment)) { + /* "trace" is a single trace, return its time range directly */ + return trace.getTimeRange(); + } + final ITmfTrace[] traces = ((TmfExperiment) trace).getTraces(); + if (traces.length == 0) { + /* We are being trolled */ + return null; + } + if (traces.length == 1) { + /* Trace is an experiment with only 1 trace */ + return traces[0].getTimeRange(); + } + /* + * Trace is an experiment with 2+ traces, so get the earliest start and + * the latest end. + */ + ITmfTimestamp start = traces[0].getStartTime(); + ITmfTimestamp end = traces[0].getEndTime(); + for (int i = 1; i < traces.length; i++) { + ITmfTrace curTrace = traces[i]; + if (curTrace.getStartTime().compareTo(start) < 0) { + start = curTrace.getStartTime(); + } + if (curTrace.getEndTime().compareTo(end) > 0) { + end = curTrace.getEndTime(); + } + } + return new TmfTimeRange(start, end); + } + + /** + * Get the temporary directory path. If there is an instance of Eclipse + * running, the temporary directory will reside under the workspace. + * + * @return the temporary directory path suitable to be passed to the + * java.io.File constructor without a trailing separator + * @since 3.2 + */ + public static String getTemporaryDirPath() { + // Get the workspace path from the properties + String property = System.getProperty("osgi.instance.area"); //$NON-NLS-1$ + if (property != null) { + try { + File dir = URIUtil.toFile(URIUtil.fromString(property)); + dir = new File(dir.getAbsolutePath() + File.separator + TEMP_DIR_NAME); + if (!dir.exists()) { + dir.mkdirs(); + } + return dir.getAbsolutePath(); + } catch (URISyntaxException e) { + Activator.logError(e.getLocalizedMessage(), e); + } + } + return System.getProperty("java.io.tmpdir"); //$NON-NLS-1$ + } + + /** + * Get a temporary directory based on a trace's name. We will create the + * directory if it doesn't exist, so that it's ready to be used. + */ + private static String getTemporaryDir(ITmfTrace trace) { + String pathName = getTemporaryDirPath() + + File.separator + + trace.getName() + + File.separator; + File dir = new File(pathName); + if (!dir.exists()) { + dir.mkdirs(); + } + return pathName; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TraceValidationStatus.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TraceValidationStatus.java new file mode 100644 index 0000000000..356a28c115 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TraceValidationStatus.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace; + +import org.eclipse.core.runtime.Status; + +/** + * A class representing the validation status of a trace against a particular + * trace type. + * + * @since 3.0 + */ +public class TraceValidationStatus extends Status { + + private int fConfidence; + + /** + * Construct a successful validation status with a confidence level + * + * @param confidence the confidence level, 0 is lowest + * @param pluginId the unique identifier of the relevant plug-in + */ + public TraceValidationStatus(int confidence, String pluginId) { + super(OK, pluginId, OK_STATUS.getMessage()); + if (confidence < 0) { + throw new IllegalArgumentException(); + } + fConfidence = confidence; + } + + /** + * Gets the confidence level + * + * @return the confidence level, 0 is lowest + */ + public int getConfidence() { + return fConfidence; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/ITmfPersistentlyIndexable.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/ITmfPersistentlyIndexable.java new file mode 100644 index 0000000000..621e0b2a81 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/ITmfPersistentlyIndexable.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace.indexer; + +import java.nio.ByteBuffer; + +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +/** + * A trace implementing this interface can be indexed and its index can be + * persisted to disk. + * + * @author Marc-Andre Laperle + * @since 3.0 + */ +public interface ITmfPersistentlyIndexable { + + /** + * Instantiate a ITmfLocation from a ByteBuffer, typically from disk. + * + * @param bufferIn + * the buffer to read from + * @return the instantiated location + * + * @since 3.0 + */ + ITmfLocation restoreLocation(ByteBuffer bufferIn); + + /** + * Get the checkpoint size for this trace + * + * @return the checkpoint size + * + * @since 3.0 + */ + public int getCheckpointSize(); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/ITmfTraceIndexer.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/ITmfTraceIndexer.java new file mode 100644 index 0000000000..0806146342 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/ITmfTraceIndexer.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace.indexer; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * The generic trace indexer in TMF with support for incremental indexing. + * + * @see ITmfTrace + * @see ITmfEvent + * + * @author Francois Chouinard + * @since 3.0 + */ +public interface ITmfTraceIndexer { + + /** + * Start an asynchronous index building job and waits for the job completion + * if required. Typically, the indexing job sends notifications at regular + * intervals to indicate its progress. + *

+ * Example 1: Index a whole trace asynchronously + * + *

+     * trace.getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, false);
+     * 
+ * + * Example 2: Index a whole trace synchronously + * + *
+     * trace.getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, true);
+     * 
+ * + * Example 3: Index a trace asynchronously, starting at rank 100 + * + *
+     * trace.getIndexer().buildIndex(100, TmfTimeRange.ETERNITY, false);
+     * 
+ * + * Example 4: Index a trace asynchronously, starting at rank 100 for + * events between T1 and T2 (inclusive). This is used for incremental + * indexing. + * + *
+     * TmfTimeRange range = new TmfTimeRange(T1, T2);
+     * trace.getIndexer().buildIndex(100, range, false);
+     * 
+ * + * @param offset + * The offset of the first event to consider + * @param range + * The time range to consider + * @param waitForCompletion + * Should we block the calling thread until the build is + * complete? + * @since 2.0 + */ + void buildIndex(long offset, TmfTimeRange range, boolean waitForCompletion); + + /** + * Indicates that the indexer is busy indexing the trace. + * Will always return false if the indexing is done synchronously. + * + * @return the state of the indexer (indexing or not) + */ + boolean isIndexing(); + + /** + * Adds an entry to the trace index. + * + * @param context The trace context to save + * @param timestamp The timestamp matching this context + * @since 2.0 + */ + void updateIndex(ITmfContext context, ITmfTimestamp timestamp); + + /** + * Returns the context of the checkpoint immediately preceding the requested + * timestamp (or at the timestamp if it coincides with a checkpoint). + * + * @param timestamp the requested timestamp + * @return the checkpoint context + * @since 2.0 + */ + ITmfContext seekIndex(ITmfTimestamp timestamp); + + /** + * Returns the context of the checkpoint immediately preceding the requested + * rank (or at rank if it coincides with a checkpoint). + * + * @param rank the requested event rank + * @return the checkpoint context + */ + ITmfContext seekIndex(long rank); + + /** + * Perform cleanup when the indexer is no longer required. + */ + void dispose(); + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/TmfBTreeTraceIndex.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/TmfBTreeTraceIndex.java new file mode 100644 index 0000000000..611757136f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/TmfBTreeTraceIndex.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace.indexer; + +import java.io.File; + +import org.eclipse.tracecompass.internal.tmf.core.trace.indexer.BTree; +import org.eclipse.tracecompass.internal.tmf.core.trace.indexer.FlatArray; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; + +/** + * A checkpoint index that uses a BTree to store and search checkpoints by time stamps. + * It's possible to have the checkpoints time stamps in a different order than their checkpoint ranks. + * Because of that, we use a separate structure FlatArray that is better suited for searching + * by checkpoint rank (O(1)). + * + * @since 3.0 + * @author Marc-Andre Laperle + */ +public class TmfBTreeTraceIndex implements ITmfCheckpointIndex { + + private final BTree fCheckpoints; + private final FlatArray fCheckpointRanks; + + private static final int BTREE_DEGREE = 15; + + /** + * Creates an index for the given trace + * + * @param trace the trace + */ + public TmfBTreeTraceIndex(ITmfTrace trace) { + BTree bTree = createBTree(trace); + FlatArray flatArray = createFlatArray(trace); + + // If one of the files is created from scratch, make sure we rebuild the other one too + if (bTree.isCreatedFromScratch() != flatArray.isCreatedFromScratch()) { + bTree.delete(); + flatArray.delete(); + bTree = createBTree(trace); + flatArray = createFlatArray(trace); + } + + fCheckpoints = bTree; + fCheckpointRanks = flatArray; + } + + private static FlatArray createFlatArray(ITmfTrace trace) { + return new FlatArray(getIndexFile(trace, FlatArray.INDEX_FILE_NAME), (ITmfPersistentlyIndexable)trace); + } + + private static BTree createBTree(ITmfTrace trace) { + return new BTree(BTREE_DEGREE, getIndexFile(trace, BTree.INDEX_FILE_NAME), (ITmfPersistentlyIndexable)trace); + } + + private static File getIndexFile(ITmfTrace trace, String fileName) { + String directory = TmfTraceManager.getSupplementaryFileDir(trace); + return new File(directory + fileName); + } + + @Override + public void dispose() { + fCheckpoints.dispose(); + fCheckpointRanks.dispose(); + } + + @Override + public void insert(ITmfCheckpoint checkpoint) { + fCheckpoints.insert(checkpoint); + fCheckpointRanks.insert(checkpoint); + fCheckpoints.setSize(fCheckpoints.size() + 1); + } + + @Override + public ITmfCheckpoint get(long checkpoint) { + return fCheckpointRanks.get(checkpoint); + } + + @Override + public long binarySearch(ITmfCheckpoint checkpoint) { + return fCheckpoints.binarySearch(checkpoint); + } + + @Override + public boolean isEmpty() { + return size() == 0; + } + + @Override + public int size() { + return fCheckpoints.size(); + } + + @Override + public boolean isCreatedFromScratch() { + return fCheckpoints.isCreatedFromScratch(); + } + + @Override + public void setTimeRange(TmfTimeRange timeRange) { + fCheckpoints.setTimeRange(timeRange); + } + + @Override + public void setNbEvents(long nbEvents) { + fCheckpoints.setNbEvents(nbEvents); + } + + @Override + public TmfTimeRange getTimeRange() { + return fCheckpoints.getTimeRange(); + } + + @Override + public long getNbEvents() { + return fCheckpoints.getNbEvents(); + } + + @Override + public void setIndexComplete() { + fCheckpoints.setIndexComplete(); + fCheckpointRanks.setIndexComplete(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/TmfBTreeTraceIndexer.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/TmfBTreeTraceIndexer.java new file mode 100644 index 0000000000..132e16cecc --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/TmfBTreeTraceIndexer.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace.indexer; + +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer; + +/** + * An indexer that uses a Btree index to store checkpoints + * + * @since 3.0 + * @author Marc-Andre Laperle + */ +public class TmfBTreeTraceIndexer extends TmfCheckpointIndexer { + + /** + * Full trace indexer + * + * @param trace + * the trace to index + * @param interval + * the checkpoints interval + */ + public TmfBTreeTraceIndexer(ITmfTrace trace, int interval) { + super(trace, interval); + } + + @Override + protected ITmfCheckpointIndex createIndex(ITmfTrace trace) { + return new TmfBTreeTraceIndex(trace); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/TmfFlatArrayTraceIndex.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/TmfFlatArrayTraceIndex.java new file mode 100644 index 0000000000..44a1556a9b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/TmfFlatArrayTraceIndex.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace.indexer; + +import java.io.File; + +import org.eclipse.tracecompass.internal.tmf.core.trace.indexer.FlatArray; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; + +/** + *

A checkpoint index that uses a FlatArray to store and search checkpoints by + * time stamps and by checkpoint rank.

+ * + *

Note: This index alone will not work for + * traces that have events with time stamps that are out of order.

+ * + * @since 3.0 + * @author Marc-Andre Laperle + */ +public class TmfFlatArrayTraceIndex implements ITmfCheckpointIndex { + + private final FlatArray fCheckpoints; + + /** + * Creates an index for the given trace + * + * @param trace the trace + */ + public TmfFlatArrayTraceIndex(ITmfTrace trace) { + fCheckpoints = new FlatArray(getIndexFile(trace, FlatArray.INDEX_FILE_NAME), (ITmfPersistentlyIndexable)trace); + } + + private static File getIndexFile(ITmfTrace trace, String fileName) { + String directory = TmfTraceManager.getSupplementaryFileDir(trace); + return new File(directory + fileName); + } + + @Override + public void dispose() { + fCheckpoints.dispose(); + } + + @Override + public void insert(ITmfCheckpoint checkpoint) { + fCheckpoints.insert(checkpoint); + } + + @Override + public ITmfCheckpoint get(long checkpoint) { + return fCheckpoints.get(checkpoint); + } + + @Override + public long binarySearch(ITmfCheckpoint checkpoint) { + return fCheckpoints.binarySearch(checkpoint); + } + + @Override + public boolean isEmpty() { + return size() == 0; + } + + @Override + public int size() { + return fCheckpoints.size(); + } + + @Override + public boolean isCreatedFromScratch() { + return fCheckpoints.isCreatedFromScratch(); + } + + @Override + public void setTimeRange(TmfTimeRange timeRange) { + fCheckpoints.setTimeRange(timeRange); + } + + @Override + public void setNbEvents(long nbEvents) { + fCheckpoints.setNbEvents(nbEvents); + } + + @Override + public TmfTimeRange getTimeRange() { + return fCheckpoints.getTimeRange(); + } + + @Override + public long getNbEvents() { + return fCheckpoints.getNbEvents(); + } + + @Override + public void setIndexComplete() { + fCheckpoints.setIndexComplete(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/TmfFlatArrayTraceIndexer.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/TmfFlatArrayTraceIndexer.java new file mode 100644 index 0000000000..9a9c9fd316 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/TmfFlatArrayTraceIndexer.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace.indexer; + +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer; + +/** + * An indexer that uses a FlatArray index to store checkpoints + * + * @since 3.0 + * @author Marc-Andre Laperle + */ +public class TmfFlatArrayTraceIndexer extends TmfCheckpointIndexer { + + /** + * Full trace indexer + * + * @param trace + * the trace to index + * @param interval + * the checkpoints interval + */ + public TmfFlatArrayTraceIndexer(ITmfTrace trace, int interval) { + super(trace, interval); + } + + @Override + protected ITmfCheckpointIndex createIndex(ITmfTrace trace) { + return new TmfFlatArrayTraceIndex(trace); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/checkpoint/ITmfCheckpoint.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/checkpoint/ITmfCheckpoint.java new file mode 100644 index 0000000000..11122421c9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/checkpoint/ITmfCheckpoint.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Updated for location in checkpoint + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint; + +import java.nio.ByteBuffer; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +/** + * The basic trace checkpoint structure in TMF. The purpose of the checkpoint is + * to associate a trace location to an event timestamp. + * * + * @see ITmfTimestamp + * @see ITmfLocation + * + * @author Francois Chouinard + * @since 3.0 + */ +public interface ITmfCheckpoint extends Comparable { + + // ------------------------------------------------------------------------ + // Getters + // ------------------------------------------------------------------------ + + /** + * The maximum size of the serialize buffer when determining the checkpoint + * size + */ + static final int MAX_SERIALIZE_SIZE = 1024; + + /** + * @return the timestamp of the event referred to by the context + * @since 2.0 + */ + ITmfTimestamp getTimestamp(); + + /** + * @return the location of the event referred to by the checkpoint + */ + ITmfLocation getLocation(); + + // ------------------------------------------------------------------------ + // Comparable + // ------------------------------------------------------------------------ + + @Override + int compareTo(ITmfCheckpoint checkpoint); + + /** + * Returns the checkpoint rank for this checkpoint. The checkpoint rank can + * be seen as the index of the checkpoint in the order it was added. + * + * @return the checkpoint rank for this checkpoint + * @since 3.0 + */ + long getCheckpointRank(); + + /** + * Write the checkpoint to the ByteBuffer so that it can be saved to disk. + * + * @param bufferOut + * the buffer to write to + * + * @since 3.0 + */ + void serialize(ByteBuffer bufferOut); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/checkpoint/ITmfCheckpointIndex.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/checkpoint/ITmfCheckpointIndex.java new file mode 100644 index 0000000000..3a06b57385 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/checkpoint/ITmfCheckpointIndex.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint; + +import java.util.Collections; + +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; + +/** + * A trace index contains the data (checkpoints) needed by the indexer so that it can perform + * its operations. Implementors can store checkpoints in various ways and + * optionally restore them later, see ({@link #isCreatedFromScratch}) + * + * @since 3.0 + * @author Marc-Andre Laperle + */ +public interface ITmfCheckpointIndex { + + /** + * Add a checkpoint to the index + * + * @param checkpoint + * the checkpoint to add + */ + void insert(ITmfCheckpoint checkpoint); + + /** + * Get a checkpoint by checkpoint rank + * + * @param checkpointRank + * the checkpoint rank to search for + * @return the checkpoint found for the given checkpoint rank + */ + ITmfCheckpoint get(long checkpointRank); + + /** + * Find the checkpoint rank of a checkpoint. Implementors must respect the + * contract of {@link Collections#binarySearch} + * + * @param checkpoint + * the checkpoint to search for + * @return the checkpoint rank of the searched checkpoint, if it is + * contained in the index; otherwise, (-(insertion point) - 1). + */ + long binarySearch(ITmfCheckpoint checkpoint); + + /** + * Returns whether or not the index is empty + * + * @return true if empty false otherwise + */ + boolean isEmpty(); + + /** + * Returns the number of checkpoints in the index + * + * @return the number of checkpoints + */ + int size(); + + /** + * Dispose the index and its resources + */ + void dispose(); + + /** + * Returns whether or not the index was created from scratch. An index not + * created from scratch was typically loaded from disk. + * + * @return true if the index was created from scratch, false otherwise + */ + boolean isCreatedFromScratch(); + + /** + * Set trace time range to be stored in the index + * + * @param timeRange + * the time range to be stored in the index + */ + void setTimeRange(TmfTimeRange timeRange); + + /** + * Set the total number of events in the trace to be stored in the index + * + * @param nbEvents + * the total number of events + */ + void setNbEvents(long nbEvents); + + /** + * Get the trace time range stored in the index + * + * @return the trace time range + */ + TmfTimeRange getTimeRange(); + + /** + * Get the total number of events in the trace stored in the index + * + * @return the total number of events + */ + long getNbEvents(); + + /** + * Set the index as complete. No more checkpoints will be inserted. + */ + void setIndexComplete(); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/checkpoint/TmfCheckpoint.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/checkpoint/TmfCheckpoint.java new file mode 100644 index 0000000000..523557ad16 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/checkpoint/TmfCheckpoint.java @@ -0,0 +1,222 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Updated as per TMF Trace Model 1.0 + * Patrick Tasse - Updated for location in checkpoint + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint; + +import java.nio.ByteBuffer; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +/** + * A basic implementation of ITmfCheckpoint. It simply maps an event timestamp + * to a generic location. + * + * @see ITmfLocation + * @see ITmfTimestamp + * + * @author Francois Chouinard + * @since 3.0 + */ +public class TmfCheckpoint implements ITmfCheckpoint { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // The checkpoint location + private final ITmfLocation fLocation; + + // The checkpoint timestamp + private final ITmfTimestamp fTimestamp; + + private final long fCheckpointRank; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Full constructor + * + * @param timestamp + * the checkpoint timestamp + * @param location + * the corresponding trace location + * @param checkpointRank + * the rank of the checkpoint + * @since 3.0 + */ + public TmfCheckpoint(final ITmfTimestamp timestamp, final ITmfLocation location, long checkpointRank) { + fTimestamp = timestamp; + fLocation = location; + fCheckpointRank = checkpointRank; + } + + /** + * Constructs a checkpoint using also a byte buffer to read the rank from + * disk. + * + * @param timestamp + * the checkpoint timestamp + * @param location + * the corresponding trace location + * @param bufferIn + * the byte buffer to read from + * + * @since 3.0 + */ + public TmfCheckpoint(final ITmfTimestamp timestamp, final ITmfLocation location, ByteBuffer bufferIn) { + fTimestamp = timestamp; + fLocation = location; + fCheckpointRank = bufferIn.getLong(); + } + + /** + * Copy constructor + * + * @param other the other checkpoint + */ + public TmfCheckpoint(final TmfCheckpoint other) { + if (other == null) { + throw new IllegalArgumentException(); + } + fTimestamp = other.fTimestamp; + fLocation = other.fLocation; + fCheckpointRank = other.fCheckpointRank; + } + + // ------------------------------------------------------------------------ + // ITmfCheckpoint + // ------------------------------------------------------------------------ + + /** + * @since 2.0 + */ + @Override + public ITmfTimestamp getTimestamp() { + return fTimestamp; + } + + @Override + public ITmfLocation getLocation() { + return fLocation; + } + + // ------------------------------------------------------------------------ + // Comparable + // ------------------------------------------------------------------------ + + @Override + @SuppressWarnings({ "unchecked", "rawtypes" }) + public int compareTo(final ITmfCheckpoint other) { + int comp = 0; + if ((fTimestamp != null) && (other.getTimestamp() != null)) { + comp = fTimestamp.compareTo(other.getTimestamp(), false); + if (comp != 0) { + return comp; + } + // compare locations if timestamps are the same + } + + if ((fLocation == null) && (other.getLocation() == null)) { + return 0; + } + + // treat location of other as null location which is before any location + if ((fLocation != null) && (other.getLocation() == null)) { + return 1; + } + + // treat this as null location which is before any other locations + if ((fLocation == null) && (other.getLocation() != null)) { + return -1; + } + + // compare location + final Comparable location1 = getLocation().getLocationInfo(); + final Comparable location2 = other.getLocation().getLocationInfo(); + return location1.compareTo(location2); + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((fLocation == null) ? 0 : fLocation.hashCode()); + result = prime * result + ((fTimestamp == null) ? 0 : fTimestamp.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof TmfCheckpoint)) { + return false; + } + final TmfCheckpoint other = (TmfCheckpoint) obj; + if (fLocation == null) { + if (other.fLocation != null) { + return false; + } + } else if (!fLocation.equals(other.fLocation)) { + return false; + } + if (fTimestamp == null) { + if (other.fTimestamp != null) { + return false; + } + } else if (!fTimestamp.equals(other.fTimestamp)) { + return false; + } + return true; + } + + @Override + @SuppressWarnings("nls") + public String toString() { + return getClass().getSimpleName() + " [fLocation=" + fLocation + ", fTimestamp=" + fTimestamp + ", fCheckpointRank=" + fCheckpointRank + "]"; + } + + /** + * @since 3.0 + */ + @Override + public void serialize(ByteBuffer bufferOut) { + fLocation.serialize(bufferOut); + // Always serialize as base TmfTimestamp, this should be sufficient for indexing. + // If not, we can add API for the test to restore the time stamp, similarly to the location. + TmfTimestamp t = new TmfTimestamp(fTimestamp); + t.serialize(bufferOut); + bufferOut.putLong(fCheckpointRank); + } + + /** + * @since 3.0 + */ + @Override + public long getCheckpointRank() { + return fCheckpointRank; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/checkpoint/TmfCheckpointIndexer.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/checkpoint/TmfCheckpointIndexer.java new file mode 100644 index 0000000000..36e3c4e2b4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/checkpoint/TmfCheckpointIndexer.java @@ -0,0 +1,355 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Update way of broadcasting of TmfTraceUpdatedSignal + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.tracecompass.internal.tmf.core.Messages; +import org.eclipse.tracecompass.internal.tmf.core.trace.indexer.TmfMemoryIndex; +import org.eclipse.tracecompass.tmf.core.component.TmfEventProvider; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceUpdatedSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceCompleteness; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +/** + * A simple indexer that manages the trace index as an array of trace + * checkpoints. Checkpoints are stored in memory at fixed intervals (event rank) in + * ascending timestamp order. + *

+ * The goal being to access a random trace event reasonably fast from the user's + * standpoint, picking the right interval value becomes a trade-off between speed + * and memory usage (a shorter inter-event interval is faster but requires more + * checkpoints). + *

+ * Locating a specific checkpoint is trivial for both rank (rank % interval) and + * timestamp (bsearch in the array). + * * + * @see ITmfTrace + * @see ITmfEvent + * + * @author Francois Chouinard + * @since 3.0 + */ +public class TmfCheckpointIndexer implements ITmfTraceIndexer { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** The event trace to index */ + protected final ITmfTrace fTrace; + + /** The interval between checkpoints */ + private final int fCheckpointInterval; + + /** The event trace to index */ + private boolean fIsIndexing; + + /** + * The trace index. It is composed of checkpoints taken at intervals of + * fCheckpointInterval events. + */ + protected final ITmfCheckpointIndex fTraceIndex; + + /** + * The indexing request + */ + private ITmfEventRequest fIndexingRequest = null; + + // ------------------------------------------------------------------------ + // Construction + // ------------------------------------------------------------------------ + + /** + * Basic constructor that uses the default trace block size as checkpoints + * intervals + * + * @param trace the trace to index + */ + public TmfCheckpointIndexer(final ITmfTrace trace) { + this(trace, TmfEventProvider.DEFAULT_BLOCK_SIZE); + } + + /** + * Full trace indexer + * + * @param trace the trace to index + * @param interval the checkpoints interval + */ + public TmfCheckpointIndexer(final ITmfTrace trace, final int interval) { + fTrace = trace; + fCheckpointInterval = interval; + fTraceIndex = createIndex(trace); + fIsIndexing = false; + } + + /** + * Creates the index instance. Classes extending this class + * can override this to provide a different index implementation. + * + * @param trace the trace to index + * @return the index + * @since 3.0 + */ + protected ITmfCheckpointIndex createIndex(final ITmfTrace trace) { + return new TmfMemoryIndex(trace); + } + + @Override + public void dispose() { + if ((fIndexingRequest != null) && !fIndexingRequest.isCompleted()) { + fIndexingRequest.cancel(); + } + + fTraceIndex.dispose(); + } + + // ------------------------------------------------------------------------ + // ITmfTraceIndexer - isIndexing + // ------------------------------------------------------------------------ + + @Override + public boolean isIndexing() { + return fIsIndexing; + } + + // ------------------------------------------------------------------------ + // ITmfTraceIndexer - buildIndex + // ------------------------------------------------------------------------ + + /** + * @since 2.0 + */ + @Override + public void buildIndex(final long offset, final TmfTimeRange range, final boolean waitForCompletion) { + + // Don't do anything if we are already indexing + synchronized (fTraceIndex) { + if (fIsIndexing) { + return; + } + fIsIndexing = true; + } + + // No need to build the index, it has been restored + if (!fTraceIndex.isCreatedFromScratch()) { + // Set some trace attributes that depends on indexing + TmfTraceUpdatedSignal signal = new TmfTraceUpdatedSignal(this, fTrace, new TmfTimeRange(fTraceIndex.getTimeRange().getStartTime(), fTraceIndex.getTimeRange().getEndTime()), fTraceIndex.getNbEvents()); + if (waitForCompletion) { + fTrace.broadcast(signal); + } else { + fTrace.broadcastAsync(signal); + } + fIsIndexing = false; + return; + } + + // The monitoring job + final Job job = new Job("Indexing " + fTrace.getName() + "...") { //$NON-NLS-1$ //$NON-NLS-2$ + @Override + protected IStatus run(final IProgressMonitor monitor) { + monitor.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$ + while (!monitor.isCanceled()) { + try { + long prevNbEvents = fTrace.getNbEvents(); + Thread.sleep(250); + long nbEvents = fTrace.getNbEvents(); + setName(Messages.TmfCheckpointIndexer_Indexing + ' ' + fTrace.getName() + " (" + nbEvents + ")"); //$NON-NLS-1$ //$NON-NLS-2$ + // setName doesn't refresh the UI, setTaskName does + long rate = (nbEvents - prevNbEvents) * 4; + monitor.setTaskName(rate + " " + Messages.TmfCheckpointIndexer_EventsPerSecond); //$NON-NLS-1$ + } catch (final InterruptedException e) { + return Status.OK_STATUS; + } + } + monitor.done(); + return Status.OK_STATUS; + } + }; + job.setSystem(!isCompleteTrace(fTrace)); + job.schedule(); + + // Build a background request for all the trace data. The index is + // updated as we go by readNextEvent(). + fIndexingRequest = new TmfEventRequest(ITmfEvent.class, + range, offset, ITmfEventRequest.ALL_DATA, + ITmfEventRequest.ExecutionType.BACKGROUND) { + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + // Update the trace status at regular intervals + if ((getNbRead() % fCheckpointInterval) == 0) { + updateTraceStatus(); + } + } + + @Override + public void handleSuccess() { + fTraceIndex.setTimeRange(fTrace.getTimeRange()); + fTraceIndex.setNbEvents(fTrace.getNbEvents()); + if (isCompleteTrace(fTrace)) { + fTraceIndex.setIndexComplete(); + } + updateTraceStatus(); + } + + @Override + public void handleCompleted() { + job.cancel(); + super.handleCompleted(); + fIsIndexing = false; + } + + private void updateTraceStatus() { + if (fTrace.getNbEvents() > 0) { + signalNewTimeRange(fTrace.getStartTime(), fTrace.getEndTime()); + } + } + }; + + // Submit the request and wait for completion if required + fTrace.sendRequest(fIndexingRequest); + if (waitForCompletion) { + try { + fIndexingRequest.waitForCompletion(); + } catch (final InterruptedException e) { + } + } + } + + /** + * Notify the interested parties that the trace time range has changed + * + * @param startTime the new start time + * @param endTime the new end time + */ + private void signalNewTimeRange(final ITmfTimestamp startTime, final ITmfTimestamp endTime) { + fTrace.broadcast(new TmfTraceUpdatedSignal(fTrace, fTrace, new TmfTimeRange(startTime, endTime), fTrace.getNbEvents())); + } + + // ------------------------------------------------------------------------ + // ITmfTraceIndexer - updateIndex + // ------------------------------------------------------------------------ + + /** + * @since 2.0 + */ + @Override + public synchronized void updateIndex(final ITmfContext context, final ITmfTimestamp timestamp) { + if ((context.getRank() % fCheckpointInterval) == 0) { + // Determine the table position + final long position = context.getRank() / fCheckpointInterval; + // Add new entry at proper location (if empty) + if (fTraceIndex.size() == position) { + fTraceIndex.insert(new TmfCheckpoint(timestamp, context.getLocation(), position)); + } + } + } + + // ------------------------------------------------------------------------ + // ITmfTraceIndexer - seekIndex + // ------------------------------------------------------------------------ + + /** + * @since 2.0 + */ + @Override + public synchronized ITmfContext seekIndex(final ITmfTimestamp timestamp) { + + // A null timestamp indicates to seek the first event + if (timestamp == null) { + return fTrace.seekEvent(0); + } + + // Find the checkpoint at or before the requested timestamp. + // In the very likely event that the timestamp is not at a checkpoint + // boundary, bsearch will return index = (- (insertion point + 1)). + // It is then trivial to compute the index of the previous checkpoint. + long index = fTraceIndex.binarySearch(new TmfCheckpoint(timestamp, null, 0)); + if (index < 0) { + index = Math.max(0, -(index + 2)); + } else { + // If timestamp was in the list, use previous index to be able to find the + // first event with the same timestamp before the checkpoint + index = Math.max(0, index - 1); + } + + // Position the trace at the checkpoint + return restoreCheckpoint(index); + } + + @Override + public ITmfContext seekIndex(final long rank) { + + // A rank < 0 indicates to seek the first event + if (rank < 0) { + return fTrace.seekEvent(0); + } + + // Find the checkpoint at or before the requested rank. + final int index = (int) rank / fCheckpointInterval; + + // Position the trace at the checkpoint + return restoreCheckpoint(index); + } + + /** + * Position the trace at the given checkpoint + * + * @param checkpoint the checkpoint index + * @return the corresponding context + */ + private ITmfContext restoreCheckpoint(final long checkpoint) { + ITmfLocation location = null; + long index = 0; + synchronized (fTraceIndex) { + if (!fTraceIndex.isEmpty()) { + index = checkpoint; + if (index >= fTraceIndex.size()) { + index = fTraceIndex.size() - 1; + } + location = fTraceIndex.get(index).getLocation(); + } + } + final ITmfContext context = fTrace.seekEvent(location); + context.setRank(index * fCheckpointInterval); + return context; + } + + // ------------------------------------------------------------------------ + // Getters + // ------------------------------------------------------------------------ + + /** + * @return the trace index + * @since 3.0 + */ + protected ITmfCheckpointIndex getTraceIndex() { + return fTraceIndex; + } + + private static boolean isCompleteTrace(ITmfTrace trace) { + return !(trace instanceof ITmfTraceCompleteness) || ((ITmfTraceCompleteness)trace).isComplete(); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/location/ITmfLocation.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/location/ITmfLocation.java new file mode 100644 index 0000000000..4ad7bfe455 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/location/ITmfLocation.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Updated as per TMF Trace Model 1.0 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace.location; + +import java.nio.ByteBuffer; + +/** + * The generic trace location in TMF. + *

+ * An ITmfLocation is the equivalent of a random-access file position, holding + * enough information to allow the positioning of the trace 'pointer' to read an + * arbitrary event. + *

+ * This location is trace-specific, must be comparable and immutable. + * + * @author Francois Chouinard + * @since 3.0 + */ +public interface ITmfLocation { + + // ------------------------------------------------------------------------ + // Getters + // ------------------------------------------------------------------------ + + /** + * Returns the concrete trace location information + * + * @return the location information + * @since 2.0 + */ + Comparable getLocationInfo(); + + /** + * Write the location to the ByteBuffer so that it can be saved to disk. + * @param bufferOut the buffer to write to + * + * @since 3.0 + */ + void serialize(ByteBuffer bufferOut); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/location/TmfLocation.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/location/TmfLocation.java new file mode 100644 index 0000000000..9426c05aed --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/location/TmfLocation.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Updated as per TMF Trace Model 1.0 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace.location; + + +/** + * A abstract implementation of ITmfLocation. The concrete classes must provide + * comparable location information. + * + * @author Francois Chouinard + * @since 3.0 + */ +public abstract class TmfLocation implements ITmfLocation { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final Comparable fLocationInfo; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Standard constructor. + * + * @param locationInfo + * The concrete trace location + */ + public TmfLocation(final Comparable locationInfo) { + fLocationInfo = locationInfo; + } + + /** + * Copy constructor + * + * @param location + * The original trace location + */ + public TmfLocation(final TmfLocation location) { + fLocationInfo = location.fLocationInfo; + } + + // ------------------------------------------------------------------------ + // Getters + // ------------------------------------------------------------------------ + + /** + * @since 2.0 + */ + @Override + public Comparable getLocationInfo() { + return fLocationInfo; + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((fLocationInfo != null) ? fLocationInfo.hashCode() : 0); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final TmfLocation other = (TmfLocation) obj; + if (fLocationInfo == null) { + if (other.fLocationInfo != null) { + return false; + } + } else if (!fLocationInfo.equals(other.fLocationInfo)) { + return false; + } + return true; + } + + @Override + @SuppressWarnings("nls") + public String toString() { + return getClass().getSimpleName() + " [fLocationInfo=" + fLocationInfo + "]"; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/location/TmfLongLocation.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/location/TmfLongLocation.java new file mode 100644 index 0000000000..bb4209df9b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/location/TmfLongLocation.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace.location; + +import java.nio.ByteBuffer; + +/** + * A concrete implementation of TmfLocation based on Long:s + * + * @author Francois Chouinard + * @since 3.0 + */ +public final class TmfLongLocation extends TmfLocation { + + /** + * Constructor + * + * @param locationInfo + * The concrete location + */ + public TmfLongLocation(long locationInfo) { + super(Long.valueOf(locationInfo)); + } + + /** + * The normal constructor + * + * @param locationInfo the concrete location + */ + public TmfLongLocation(final Long locationInfo) { + super(locationInfo); + } + + /** + * The copy constructor + * + * @param other the other location + */ + public TmfLongLocation(final TmfLongLocation other) { + super(other.getLocationInfo()); + } + + /** + * Construct the location from the ByteBuffer. + * + * @param bufferIn + * the buffer to read from + * + * @since 3.0 + */ + public TmfLongLocation(ByteBuffer bufferIn) { + this(bufferIn.getLong()); + } + + @Override + public Long getLocationInfo() { + return (Long) super.getLocationInfo(); + } + + /** + * @since 3.0 + */ + @Override + public void serialize(ByteBuffer bufferOut) { + bufferOut.putLong(getLocationInfo().longValue()); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/location/TmfTimestampLocation.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/location/TmfTimestampLocation.java new file mode 100644 index 0000000000..132d08d603 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/location/TmfTimestampLocation.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace.location; + +import java.nio.ByteBuffer; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; + +/** + * A concrete implementation of TmfLocation based on ITmfTimestamp:s + * + * @author Francois Chouinard + * @since 3.0 + */ +public final class TmfTimestampLocation extends TmfLocation { + + /** + * The normal constructor + * + * @param locationInfo the concrete location + */ + public TmfTimestampLocation(final ITmfTimestamp locationInfo) { + super(locationInfo); + } + + /** + * The copy constructor + * + * @param other the other location + */ + public TmfTimestampLocation(final TmfTimestampLocation other) { + super(other.getLocationInfo()); + } + + /** + * Construct the location from the ByteBuffer. + * + * @param bufferIn + * the buffer to read from + * + * @since 3.0 + */ + public TmfTimestampLocation(ByteBuffer bufferIn) { + super(new TmfTimestamp(bufferIn)); + } + + @Override + public ITmfTimestamp getLocationInfo() { + return (ITmfTimestamp) super.getLocationInfo(); + } + + /** + * @since 3.0 + */ + @Override + public void serialize(ByteBuffer bufferOut) { + TmfTimestamp t = new TmfTimestamp(getLocationInfo()); + t.serialize(bufferOut); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/text/TextTrace.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/text/TextTrace.java new file mode 100644 index 0000000000..a87b447e33 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/text/TextTrace.java @@ -0,0 +1,382 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Marc-Andre Laperle - Add persistent index support + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace.text; + +import java.io.File; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.io.BufferedRandomAccessFile; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfEventParser; +import org.eclipse.tracecompass.tmf.core.trace.TmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TraceValidationStatus; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfPersistentlyIndexable; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.indexer.TmfBTreeTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; + +/** + * Extension of TmfTrace for handling of line-based text traces parsed using + * regular expressions. Each line that matches the first line pattern indicates + * the start of a new event. The subsequent lines can contain additional + * information that is added to the current event. + * + * @param + * TmfEvent class returned by this trace + * + * @since 3.0 + */ +public abstract class TextTrace extends TmfTrace implements ITmfEventParser, ITmfPersistentlyIndexable { + + private static final TmfLongLocation NULL_LOCATION = new TmfLongLocation(-1L); + private static final int MAX_LINES = 100; + private static final int MAX_CONFIDENCE = 100; + + /** The default separator used for multi-line fields */ + protected static final String SEPARATOR = " | "; //$NON-NLS-1$ + + /** The text file */ + protected BufferedRandomAccessFile fFile; + + /** + * Constructor + */ + public TextTrace() { + } + + /** + * {@inheritDoc} + *

+ * The default implementation computes the confidence as the sum of weighted + * values of the first 100 lines of the file which match any of the provided + * validation patterns. For each matching line a weighted value between 1.5 + * and 2.0 is assigned based on the group count of the matching patterns. + * The higher the group count, the closer the weighted value will be to 2.0. + */ + @Override + public IStatus validate(IProject project, String path) { + File file = new File(path); + if (!file.exists()) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "File not found: " + path); //$NON-NLS-1$ + } + if (!file.isFile()) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Not a file. It's a directory: " + path); //$NON-NLS-1$ + } + int confidence = 0; + try (BufferedRandomAccessFile rafile = new BufferedRandomAccessFile(path, "r")) { //$NON-NLS-1$ + int lineCount = 0; + double matches = 0.0; + String line = rafile.getNextLine(); + List validationPatterns = getValidationPatterns(); + while ((line != null) && (lineCount++ < MAX_LINES)) { + for(Pattern pattern : validationPatterns) { + Matcher matcher = pattern.matcher(line); + if (matcher.matches()) { + int groupCount = matcher.groupCount(); + matches += (1.0 + groupCount / ((double) groupCount + 1)); + } + } + confidence = (int) (MAX_CONFIDENCE * matches / lineCount); + line = rafile.getNextLine(); + } + } catch (IOException e) { + Activator.logError("Error validating file: " + path, e); //$NON-NLS-1$ + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "IOException validating file: " + path, e); //$NON-NLS-1$ + } + + return new TraceValidationStatus(confidence, Activator.PLUGIN_ID); + + } + @Override + public void initTrace(IResource resource, String path, Class type) throws TmfTraceException { + super.initTrace(resource, path, type); + try { + fFile = new BufferedRandomAccessFile(getPath(), "r"); //$NON-NLS-1$ + } catch (IOException e) { + throw new TmfTraceException(e.getMessage(), e); + } + } + + @Override + public synchronized void dispose() { + super.dispose(); + if (fFile != null) { + try { + fFile.close(); + } catch (IOException e) { + } finally { + fFile = null; + } + } + } + + @Override + public synchronized TextTraceContext seekEvent(ITmfLocation location) { + TextTraceContext context = new TextTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK); + if (NULL_LOCATION.equals(location) || fFile == null) { + return context; + } + try { + if (location == null) { + fFile.seek(0); + } else if (location.getLocationInfo() instanceof Long) { + fFile.seek((Long) location.getLocationInfo()); + } + long rawPos = fFile.getFilePointer(); + String line = fFile.getNextLine(); + while (line != null) { + Matcher matcher = getFirstLinePattern().matcher(line); + if (matcher.matches()) { + setupContext(context, rawPos, line, matcher); + return context; + } + rawPos = fFile.getFilePointer(); + line = fFile.getNextLine(); + } + return context; + } catch (IOException e) { + Activator.logError("Error seeking file: " + getPath(), e); //$NON-NLS-1$ + return context; + } + } + + private void setupContext(TextTraceContext context, long rawPos, String line, Matcher matcher) throws IOException { + context.setLocation(new TmfLongLocation(rawPos)); + context.firstLineMatcher = matcher; + context.firstLine = line; + context.nextLineLocation = fFile.getFilePointer(); + } + + @Override + public synchronized TextTraceContext seekEvent(double ratio) { + if (fFile == null) { + return new TextTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK); + } + try { + long pos = (long) (ratio * fFile.length()); + while (pos > 0) { + fFile.seek(pos - 1); + if (fFile.read() == '\n') { + break; + } + pos--; + } + ITmfLocation location = new TmfLongLocation(Long.valueOf(pos)); + TextTraceContext context = seekEvent(location); + context.setRank(ITmfContext.UNKNOWN_RANK); + return context; + } catch (IOException e) { + Activator.logError("Error seeking file: " + getPath(), e); //$NON-NLS-1$ + return new TextTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK); + } + } + + @Override + public double getLocationRatio(ITmfLocation location) { + if (fFile == null) { + return 0; + } + try { + long length = fFile.length(); + if (length == 0) { + return 0; + } + if (location.getLocationInfo() instanceof Long) { + return (double) ((Long) location.getLocationInfo()) / length; + } + } catch (IOException e) { + Activator.logError("Error reading file: " + getPath(), e); //$NON-NLS-1$ + } + return 0; + } + + @Override + public ITmfLocation getCurrentLocation() { + return null; + } + + @Override + public TextTraceEvent parseEvent(ITmfContext tmfContext) { + TextTraceContext context = seekEvent(tmfContext.getLocation()); + return parse(context); + } + + @Override + public synchronized T getNext(ITmfContext context) { + if (!(context instanceof TextTraceContext)) { + throw new IllegalArgumentException(); + } + TextTraceContext savedContext = new TextTraceContext(context.getLocation(), context.getRank()); + T event = parse((TextTraceContext) context); + if (event != null) { + updateAttributes(savedContext, event.getTimestamp()); + context.increaseRank(); + } + return event; + } + + /** + * Parse the next event. The context is advanced. + * + * @param tmfContext + * the context + * @return the next event or null + */ + protected synchronized T parse(TextTraceContext tmfContext) { + if (fFile == null) { + return null; + } + TextTraceContext context = tmfContext; + if (context.getLocation() == null || !(context.getLocation().getLocationInfo() instanceof Long) || NULL_LOCATION.equals(context.getLocation())) { + return null; + } + + T event = parseFirstLine(context.firstLineMatcher, context.firstLine); + + try { + if (fFile.getFilePointer() != context.nextLineLocation) { + fFile.seek(context.nextLineLocation); + } + long rawPos = fFile.getFilePointer(); + String line = fFile.getNextLine(); + while (line != null) { + Matcher matcher = getFirstLinePattern().matcher(line); + if (matcher.matches()) { + setupContext(context, rawPos, line, matcher); + return event; + } + parseNextLine(event, line); + rawPos = fFile.getFilePointer(); + line = fFile.getNextLine(); + } + } catch (IOException e) { + Activator.logError("Error reading file: " + getPath(), e); //$NON-NLS-1$ + } + + context.setLocation(NULL_LOCATION); + return event; + } + + /** + * Gets the first line pattern. + * + * @return The first line pattern + */ + protected abstract Pattern getFirstLinePattern(); + + /** + * Parses the first line data and returns a new event. When constructing the + * event, the concrete trace should use the trace's timestamp transform to + * create the timestamp, by either transforming the parsed time value + * directly or by using the method {@link #createTimestamp(long)}. + * + * @param matcher + * The matcher + * @param line + * The line to parse + * @return The parsed event + */ + protected abstract T parseFirstLine(Matcher matcher, String line); + + /** + * Parses the next line data for the current event. + * + * @param event + * The current event being parsed + * @param line + * The line to parse + */ + protected abstract void parseNextLine(T event, String line); + + /** + * Returns a ordered list of validation patterns that will be used in + * the default {@link #validate(IProject, String)} method to match + * the first 100 to compute the confidence level + * + * @return collection of patterns to validate against + * @since 3.2 + */ + protected List getValidationPatterns() { + return Collections.singletonList(getFirstLinePattern()); + } + + // ------------------------------------------------------------------------ + // Helper methods + // ------------------------------------------------------------------------ + + /** + * Strip quotes surrounding a string + * + * @param input + * The input string + * @return The string without quotes + */ + protected static String replaceQuotes(String input) { + String out = input.replaceAll("^\"|(\"\\s*)$", ""); //$NON-NLS-1$//$NON-NLS-2$ + return out; + } + + /** + * Strip brackets surrounding a string + * + * @param input + * The input string + * @return The string without brackets + */ + protected static String replaceBrackets(String input) { + String out = input.replaceAll("^\\{|(\\}\\s*)$", ""); //$NON-NLS-1$//$NON-NLS-2$ + return out; + } + + private static int fCheckpointSize = -1; + + @Override + public synchronized int getCheckpointSize() { + if (fCheckpointSize == -1) { + TmfCheckpoint c = new TmfCheckpoint(TmfTimestamp.ZERO, new TmfLongLocation(0L), 0); + ByteBuffer b = ByteBuffer.allocate(ITmfCheckpoint.MAX_SERIALIZE_SIZE); + b.clear(); + c.serialize(b); + fCheckpointSize = b.position(); + } + + return fCheckpointSize; + } + + @Override + protected ITmfTraceIndexer createIndexer(int interval) { + return new TmfBTreeTraceIndexer(this, interval); + } + + @Override + public ITmfLocation restoreLocation(ByteBuffer bufferIn) { + return new TmfLongLocation(bufferIn); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/text/TextTraceContext.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/text/TextTraceContext.java new file mode 100644 index 0000000000..709b823392 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/text/TextTraceContext.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace.text; + +import java.util.regex.Matcher; + +import org.eclipse.tracecompass.tmf.core.trace.TmfContext; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +/** + * Implementation of a TmfContext for text traces. + * + * @since 3.0 + */ +public class TextTraceContext extends TmfContext { + + /** The Matcher object for the first line. */ + public Matcher firstLineMatcher; + /** The first line string */ + public String firstLine; + /** The location of the next line */ + public long nextLineLocation; + + /** + * Constructor + * + * @param location + * Trace location + * @param rank + * Event rank + */ + public TextTraceContext(final ITmfLocation location, final long rank) { + super(location, rank); + } + + /** + * Copy Constructor + * + * @param other + * the other TextTraceContext + */ + public TextTraceContext(TextTraceContext other) { + this(other.getLocation(), other.getRank()); + firstLine = other.firstLine; + firstLineMatcher = other.firstLineMatcher; + nextLineLocation = other.nextLineLocation; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((firstLine == null) ? 0 : firstLine.hashCode()); + result = prime * result + ((firstLineMatcher == null) ? 0 : firstLineMatcher.hashCode()); + result = prime * result + (int) (nextLineLocation ^ (nextLineLocation >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TextTraceContext other = (TextTraceContext) obj; + if (firstLine == null) { + if (other.firstLine != null) { + return false; + } + } else if (!firstLine.equals(other.firstLine)) { + return false; + } + if (firstLineMatcher == null) { + if (other.firstLineMatcher != null) { + return false; + } + } else if (!firstLineMatcher.equals(other.firstLineMatcher)) { + return false; + } + if (nextLineLocation != other.nextLineLocation) { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/text/TextTraceEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/text/TextTraceEvent.java new file mode 100644 index 0000000000..e8d605c84e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/text/TextTraceEvent.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace.text; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; + +/** + * Class to store the common functionality of text trace events. + * + * @author Alexandre Montplaisir + * @since 3.0 + */ +public abstract class TextTraceEvent extends TmfEvent { + + /** + * Full Constructor. + * + * Compared to {@link TmfEvent}'s constructor, 'content' is restricted to a + * {@link TextTraceEventContent}. + * + * @param parentTrace + * The parent trace + * @param timestamp + * The event timestamp + * @param source + * The event source + * @param type + * The event type + * @param content + * The event content (payload) + * @param reference + * The event reference + */ + public TextTraceEvent(TextTrace parentTrace, + final ITmfTimestamp timestamp, + final String source, + final ITmfEventType type, + final TextTraceEventContent content, + final String reference) { + super(parentTrace, timestamp, source, type, content, reference); + } + + /** + * Copy constructor + * + * @param other + * The event to copy + */ + public TextTraceEvent(final TextTraceEvent other) { + super(other); + } + + @Override + public TextTrace getTrace() { + /* Cast should be safe, type is restricted by the constructor */ + return (TextTrace) super.getTrace(); + } + + @Override + public TextTraceEventContent getContent() { + /* Cast should be safe, type is restricted by the constructor */ + return (TextTraceEventContent) super.getContent(); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/text/TextTraceEventContent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/text/TextTraceEventContent.java new file mode 100644 index 0000000000..cbb9713421 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/text/TextTraceEventContent.java @@ -0,0 +1,312 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Bernd Hufmann - Updated equals, clone and hashCode to consider StringBuffer values + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.trace.text; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; + +/** + * Implementation of ITmfEventField for Text Traces. + * + * @since 3.0 + */ +public class TextTraceEventContent implements ITmfEventField { + + private final @NonNull String fName; + private final @NonNull List fFields; + + private @Nullable Object fValue; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructor for a root event content + * + * @param fieldNames + * the array of field names + */ + public TextTraceEventContent(String[] fieldNames) { + fName = ITmfEventField.ROOT_FIELD_ID; + fValue = null; + fFields = new ArrayList<>(fieldNames.length); + for (String fieldName : fieldNames) { + if (fieldName == null) { + throw new IllegalArgumentException("Null field name not allowed"); //$NON-NLS-1$ + } + fFields.add(new TextTraceEventContent(fieldName)); + } + } + + /** + * Constructor for a subfield + * + * @param fieldNames + * the array of field names + */ + private TextTraceEventContent(@NonNull String fieldName) { + fName = fieldName; + fValue = null; + @SuppressWarnings("null") + @NonNull List fields = Collections.EMPTY_LIST; + fFields = fields; + } + + // ------------------------------------------------------------------------ + // ITmfEventField + // ------------------------------------------------------------------------ + + @Override + public String getName() { + return fName; + } + + @Override + public Object getValue() { + return fValue; + } + + @Override + public List getFieldNames() { + List fieldNames = new ArrayList<>(fFields.size()); + for (TextTraceEventContent field : fFields) { + fieldNames.add(field.getName()); + } + return fieldNames; + } + + @Override + public List getFields() { + return new ArrayList<>(fFields); + } + + @Override + public ITmfEventField getField(String name) { + for (TextTraceEventContent field : fFields) { + if (field.getName().equals(name)) { + return field; + } + } + return null; + } + + @Override + public String getFormattedValue() { + Object value = fValue; + if (value == null) { + return null; + } + return value.toString(); + } + + @Override + public ITmfEventField getSubField(String... names) { + // There are no sub fields + if (names.length == 1) { + return getField(names[0]); + } + return null; + } + + // ------------------------------------------------------------------------ + // Convenience getters and setters + // ------------------------------------------------------------------------ + + /** + * Get a field name by index + * + * @param index + * The index of the field + * @return The name of the field at that index + */ + public String getFieldName(int index) { + if (index >= 0 && index < fFields.size()) { + return fFields.get(index).getName(); + } + return null; + } + + /** + * Get a field by index + * + * @param index + * The index of the field + * @return The field object at the requested index + */ + public ITmfEventField getField(int index) { + if (index >= 0 && index < fFields.size()) { + return fFields.get(index); + } + return null; + } + + /** + * Get a subfield value by name + * + * @param name + * a subfield name + * @return field value object + */ + public Object getFieldValue(String name) { + for (int i = 0; i < fFields.size(); i++) { + if (fFields.get(i).getName().equals(name)) { + return fFields.get(i).getValue(); + } + } + return null; + } + + /** + * Get a subfield value by index + * + * @param index + * a subfield index + * @return field value object + */ + public Object getFieldValue(int index) { + if (index >= 0 && index < fFields.size()) { + return fFields.get(index).getValue(); + } + return null; + } + + /** + * Set the content value + * + * @param value + * the content value + */ + public void setValue(Object value) { + fValue = value; + } + + /** + * Set a subfield value by name + * + * @param name + * a subfield name + * @param value + * the subfield value + */ + public void setFieldValue(String name, Object value) { + for (int i = 0; i < fFields.size(); i++) { + if (fFields.get(i).getName().equals(name)) { + fFields.get(i).fValue = value; + } + } + } + + /** + * Set a subfield value by index + * + * @param index + * a subfield index + * @param value + * the subfield value + */ + public void setFieldValue(int index, Object value) { + if (index >= 0 && index < fFields.size()) { + fFields.get(index).fValue = value; + } + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + fFields.hashCode(); + result = prime * result + fName.hashCode(); + int tmpHash = 0; // initialize for fValue equals null; + Object value = fValue; + if (value != null) { + if (value instanceof StringBuffer) { + tmpHash = value.toString().hashCode(); + } else { + tmpHash = value.hashCode(); + } + } + result = prime * result + tmpHash; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TextTraceEventContent other = (TextTraceEventContent) obj; + if (!fFields.equals(other.fFields)) { + return false; + } + if (!fName.equals(other.fName)) { + return false; + } + + Object value = fValue; + if (value == null) { + if (other.fValue != null) { + return false; + } + } else { + if ((value instanceof StringBuffer) && (other.fValue instanceof StringBuffer)) { + Object otherValue = other.getValue(); + if (otherValue == null) { + return false; + } + if (!value.toString().equals(otherValue.toString())) { + return false; + } + } else if (!value.equals(other.fValue)) { + return false; + } + } + return true; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + if (fName == ITmfEventField.ROOT_FIELD_ID) { + for (int i = 0; i < getFields().size(); i++) { + ITmfEventField field = getFields().get(i); + if (i != 0) { + sb.append(", "); //$NON-NLS-1$ + } + sb.append(field.toString()); + } + } else { + sb.append(fName); + sb.append('='); + sb.append(fValue); + } + return sb.toString(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/uml2sd/ITmfAsyncSequenceDiagramEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/uml2sd/ITmfAsyncSequenceDiagramEvent.java new file mode 100644 index 0000000000..06253e7c95 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/uml2sd/ITmfAsyncSequenceDiagramEvent.java @@ -0,0 +1,32 @@ +/********************************************************************** + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ +package org.eclipse.tracecompass.tmf.core.uml2sd; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; + +/** + *

+ * Interface for asynchronous sequence diagram events. + *

+ * + * @version 1.0 + * @author Bernd Hufmann + */ +public interface ITmfAsyncSequenceDiagramEvent extends ITmfSyncSequenceDiagramEvent { + /** + * Returns end timestamp of message (i.e. receive time) + * + * @return end timestamp of message (i.e. receive time) + * @since 2.0 + */ + ITmfTimestamp getEndTime(); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/uml2sd/ITmfSyncSequenceDiagramEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/uml2sd/ITmfSyncSequenceDiagramEvent.java new file mode 100644 index 0000000000..85aba4f31f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/uml2sd/ITmfSyncSequenceDiagramEvent.java @@ -0,0 +1,54 @@ +/********************************************************************** + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ +package org.eclipse.tracecompass.tmf.core.uml2sd; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; + +/** + *

+ * Interface for synchronous sequence diagram events. + *

+ * + * @version 1.0 + * @author Bernd Hufmann + */ +public interface ITmfSyncSequenceDiagramEvent { + + /** + * Returns Name of message. + * + * @return Name of message + */ + String getName(); + + /** + * Returns name of sender of message. + * + * @return name of sender of message + */ + String getSender(); + + /** + * Returns Name of receiver of message. + * + * @return Name of receiver of message + */ + String getReceiver(); + + /** + * Returns Start time of message (i.e. send time). + * + * @return Start timestamp of message (i.e. send time) + * @since 2.0 + */ + ITmfTimestamp getStartTime(); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/uml2sd/TmfAsyncSequenceDiagramEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/uml2sd/TmfAsyncSequenceDiagramEvent.java new file mode 100644 index 0000000000..cb78b8df72 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/uml2sd/TmfAsyncSequenceDiagramEvent.java @@ -0,0 +1,67 @@ +/********************************************************************** + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ +package org.eclipse.tracecompass.tmf.core.uml2sd; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; + +/** + *

+ * A basic implementation of ITmfAsyncSequenceDiagramEvent. + *

+ * + * @version 1.0 + * @author Bernd Hufmann + */ +public class TmfAsyncSequenceDiagramEvent extends TmfSyncSequenceDiagramEvent implements ITmfAsyncSequenceDiagramEvent { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The end time of the sequence diagram event (i.e. time when signal was received). + */ + private final ITmfTimestamp fEndTime; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Constructor + * + * @param startEvent The start event (on sender side). + * @param endEvent The end event (receiver side). + * @param sender The name of sender of signal. + * @param receiver The Name of receiver of signal. + * @param name - The signal name + */ + public TmfAsyncSequenceDiagramEvent(ITmfEvent startEvent, ITmfEvent endEvent, String sender, String receiver, String name) { + super(startEvent, sender, receiver, name); + + if (endEvent == null) { + throw new IllegalArgumentException("TmfAsyncSequenceDiagramEvent constructor: endEvent=null"); //$NON-NLS-1$ + } + fEndTime = endEvent.getTimestamp(); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * @since 2.0 + */ + @Override + public ITmfTimestamp getEndTime() { + return fEndTime; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/uml2sd/TmfSyncSequenceDiagramEvent.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/uml2sd/TmfSyncSequenceDiagramEvent.java new file mode 100644 index 0000000000..15d37c90fa --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/uml2sd/TmfSyncSequenceDiagramEvent.java @@ -0,0 +1,102 @@ +/********************************************************************** + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ +package org.eclipse.tracecompass.tmf.core.uml2sd; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; + +/** + *

+ * A basic implementation of ITmfSyncSequenceDiagramEvent. + *

+ * + * @version 1.0 + * @author Bernd Hufmann + */ +public class TmfSyncSequenceDiagramEvent implements ITmfSyncSequenceDiagramEvent { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The start time of the sequence diagram event (i.e. time when signal was sent). + */ + private final ITmfTimestamp fStartTime; + /** + * The name of the sender of the signal. + */ + private final String fSender; + /** + * The name of the receiver of the signal. + */ + private final String fReceiver; + /** + * The name of the signal + */ + private final String fName; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Constructor + * + * @param startEvent The start event (on sender side). + * @param sender The name of sender of signal. + * @param receiver The Name of receiver of signal. + * @param name - The signal name + */ + public TmfSyncSequenceDiagramEvent(ITmfEvent startEvent, String sender, String receiver, String name) { + + if ((startEvent == null) || (sender == null) || (receiver == null) || (name == null)) { + throw new IllegalArgumentException("TmfSyncSequenceDiagramEvent constructor: " + //$NON-NLS-1$ + (startEvent == null ? ", startEvent=null" : "") + //$NON-NLS-1$ //$NON-NLS-2$ + (sender == null ? ", sender=null" : "") + //$NON-NLS-1$ //$NON-NLS-2$ + (receiver == null ? ", receiver=null" : "") + //$NON-NLS-1$ //$NON-NLS-2$ + (name == null ? ", name=null" : "")); //$NON-NLS-1$ //$NON-NLS-2$ + } + + fStartTime = startEvent.getTimestamp(); + + fSender = sender; + fReceiver = receiver; + + fName = name; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Override + public String getSender() { + return fSender; + } + + @Override + public String getReceiver() { + return fReceiver; + } + + @Override + public String getName() { + return fName; + } + + /** + * @since 2.0 + */ + @Override + public ITmfTimestamp getStartTime() { + return fStartTime; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/util/Pair.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/util/Pair.java new file mode 100644 index 0000000000..368df79823 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/util/Pair.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (c) 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Philippe Sawicki (INF4990.A2010@gmail.com) - Initial API and implementation + * Mathieu Denis (mathieu.denis55@gmail.com) - Refactored code + * Bernd Hufmann - Integrated to TMF, fixed hashCode() and equals() methods + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.core.util; + +/** + * Pair utility class, encapsulates a pair of objects. + * + * @param + * The type of the first object. + * @param + * The type of the second object. + * + * @author Philippe Sawicki + * @since 2.0 + */ +public class Pair { + + /** + * A reference to the first object. + */ + protected A fFirst; + /** + * A reference to the second object. + */ + protected B fSecond; + + /** + * Constructor. + * @param first + * The pair's first object. + * @param second + * The pair's second object. + */ + public Pair(A first, B second) { + fFirst = first; + fSecond = second; + } + + /** + * Constructor. + */ + public Pair() { + this(null, null); + } + + /** + * Pair hash code. + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((fFirst == null) ? 0 : fFirst.hashCode()); + result = prime * result + ((fSecond == null) ? 0 : fSecond.hashCode()); + return result; + } + + /** + * Object comparison. + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj == null) { + return false; + } + + if (getClass() != obj.getClass()) { + return false; + } + + Pair other = (Pair) obj; + + if (fFirst == null) { + if (other.fFirst != null) { + return false; + } + } else if (!fFirst.equals(other.fFirst)) { + return false; + } + if (fSecond == null) { + if (other.fSecond != null) { + return false; + } + } else if (!fSecond.equals(other.fSecond)) { + return false; + } + return true; + } + + /** + * Object to string. + */ + @Override + public String toString() { + return "(" + fFirst + ", " + fSecond + ")"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ + } + + /** + * Returns a reference to the pair's first object. + * @return A reference to the pair's first object. + */ + public A getFirst() { + return fFirst; + } + + /** + * Sets the pair's first object. + * @param first + * The pair's first object. + */ + public void setFirst(A first) { + fFirst = first; + } + + /** + * Returns a reference to the pair's second object. + * @return A reference to the pair's second object. + */ + public B getSecond() { + return fSecond; + } + + /** + * Sets the pair's second object. + * @param second + * The pair's second object. + */ + public void setSecond(B second) { + fSecond = second; + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/META-INF/MANIFEST.MF b/org.eclipse.tracecompass.tmf.ctf.core.tests/META-INF/MANIFEST.MF index e2339c3080..dba5776c80 100644 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/META-INF/MANIFEST.MF @@ -15,14 +15,14 @@ Require-Bundle: org.junit;bundle-version="4.0.0", org.eclipse.tracecompass.tmf.ctf.core, org.eclipse.tracecompass.ctf.core, org.eclipse.tracecompass.ctf.core.tests -Export-Package: org.eclipse.linuxtools.tmf.ctf.core.tests, - org.eclipse.linuxtools.tmf.ctf.core.tests.headless;x-internal:=true, - org.eclipse.linuxtools.tmf.ctf.core.tests.perf, - org.eclipse.linuxtools.tmf.ctf.core.tests.perf.experiment;x-internal:=true, - org.eclipse.linuxtools.tmf.ctf.core.tests.request;x-internal:=true, - org.eclipse.linuxtools.tmf.ctf.core.tests.shared, - org.eclipse.linuxtools.tmf.ctf.core.tests.statistics;x-internal:=true, - org.eclipse.linuxtools.tmf.ctf.core.tests.stubs, - org.eclipse.linuxtools.tmf.ctf.core.tests.tracemanager;x-internal:=true +Export-Package: org.eclipse.tracecompass.tmf.ctf.core.tests, + org.eclipse.tracecompass.tmf.ctf.core.tests.headless;x-internal:=true, + org.eclipse.tracecompass.tmf.ctf.core.tests.perf, + org.eclipse.tracecompass.tmf.ctf.core.tests.perf.experiment;x-internal:=true, + org.eclipse.tracecompass.tmf.ctf.core.tests.request;x-internal:=true, + org.eclipse.tracecompass.tmf.ctf.core.tests.shared, + org.eclipse.tracecompass.tmf.ctf.core.tests.statistics;x-internal:=true, + org.eclipse.tracecompass.tmf.ctf.core.tests.stubs, + org.eclipse.tracecompass.tmf.ctf.core.tests.tracemanager;x-internal:=true Import-Package: com.google.common.collect, org.eclipse.test.performance diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/linuxtools/tmf/ctf/core/tests/perf/AllPerfTests.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/linuxtools/tmf/ctf/core/tests/perf/AllPerfTests.java deleted file mode 100644 index 630b212ea1..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/linuxtools/tmf/ctf/core/tests/perf/AllPerfTests.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests.perf; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * The class AllPerformanceTests builds a suite that can be used to - * run all of the performance tests within its package as well as within any - * subpackages of its package. - * - * @author Geneviève Bastien - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - org.eclipse.linuxtools.tmf.ctf.core.tests.perf.experiment.AllPerfTests.class -}) -public class AllPerfTests { - -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/linuxtools/tmf/ctf/core/tests/perf/experiment/AllPerfTests.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/linuxtools/tmf/ctf/core/tests/perf/experiment/AllPerfTests.java deleted file mode 100644 index c7727eadfe..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/linuxtools/tmf/ctf/core/tests/perf/experiment/AllPerfTests.java +++ /dev/null @@ -1,26 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests.perf.experiment; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - ExperimentBenchmark.class -}) -public class AllPerfTests { -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/linuxtools/tmf/ctf/core/tests/perf/experiment/ExperimentBenchmark.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/linuxtools/tmf/ctf/core/tests/perf/experiment/ExperimentBenchmark.java deleted file mode 100644 index 4506e82a93..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/linuxtools/tmf/ctf/core/tests/perf/experiment/ExperimentBenchmark.java +++ /dev/null @@ -1,163 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Geneviève Bastien - Convert to JUnit performance test - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests.perf.experiment; - -import java.io.File; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.linuxtools.ctf.core.tests.shared.CtfTestTrace; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest.ExecutionType; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfExperimentStub; -import org.eclipse.test.performance.Dimension; -import org.eclipse.test.performance.Performance; -import org.eclipse.test.performance.PerformanceMeter; -import org.junit.Test; - -/** - * Coalescing benchmark - * - * @author Matthew Khouzam - */ -public class ExperimentBenchmark { - - private static final String TEST_ID = "org.eclipse.linuxtools#Experiment benchmark#"; - private static final int MAX_TRACES = 160; - private static final int BLOCK_SIZE = 100; - private static final String TRACES_ROOT_PATH = CtfTestTrace.TRACE_EXPERIMENT.getPath(); - private static final int SAMPLE_SIZE_SLOW = 20; - private static final int SAMPLE_SIZE = 100; - - private TmfExperimentStub fExperiment; - - /** - * Run the benchmark - */ - @Test - public void benchmarkExperimentSizeRequest() { - Performance perf = Performance.getDefault(); - - for (int numTraces = 1; numTraces < MAX_TRACES; numTraces = (int) (1.6 * (numTraces + 1))) { - PerformanceMeter pm = perf.createPerformanceMeter(TEST_ID + numTraces + " traces"); - perf.tagAsSummary(pm, "Experiment Benchmark:" + numTraces + " traces", Dimension.CPU_TIME); - if ((int) (1.6 * (numTraces + 1)) > MAX_TRACES) { - perf.tagAsGlobalSummary(pm, "Experiment Benchmark:" + numTraces + " traces", Dimension.CPU_TIME); - } - - int sampleSize = SAMPLE_SIZE; - if (numTraces > 20) { - sampleSize = SAMPLE_SIZE_SLOW; - } - - for (int s = 0; s < sampleSize; s++) { - - InnerEventRequest expReq = new InnerEventRequest(ITmfEvent.class, 0, ITmfEventRequest.ALL_DATA, ExecutionType.BACKGROUND); - InnerEventRequest traceReq[] = new InnerEventRequest[numTraces]; - - init(numTraces); - fExperiment.sendRequest(expReq); - ITmfTrace[] traces = fExperiment.getTraces(); - for (int i = 0; i < numTraces; i++) { - traceReq[i] = new InnerEventRequest(ITmfEvent.class, 0, ITmfEventRequest.ALL_DATA, ExecutionType.BACKGROUND); - traces[i].sendRequest(traceReq[i]); - } - - pm.start(); - waitForRequest(expReq, traceReq); - pm.stop(); - - for (int i = 0; i < traces.length; i++) { - if (!expReq.isTraceHandled(traces[i])) { - System.err.println("Trace " + i + " not handled!"); - } - } - - fExperiment.dispose(); - } - pm.commit(); - } - } - - /** - * Initialization - * - * @param maxTraces - * maximum number of traces to open - */ - private void init(int maxTraces) { - try { - File parentDir = new File(TRACES_ROOT_PATH); - File[] traceFiles = parentDir.listFiles(); - ITmfTrace[] traces = new CtfTmfTrace[Math.min(maxTraces, traceFiles.length)]; - for (int i = 0; i < traces.length; i++) { - traces[i] = new CtfTmfTrace(); - } - fExperiment = new TmfExperimentStub("MegaExperiment", traces, BLOCK_SIZE); - int j = 0; - for (int i = 0; i < (traces.length) && (j < traces.length); i++) { - String absolutePath = traceFiles[j].getAbsolutePath(); - if (traces[i].validate(null, absolutePath).isOK()) { - traces[i].initTrace(null, absolutePath, ITmfEvent.class); - } else { - i--; - } - j++; - } - if (traces[traces.length - 1].getPath() == null) { - throw new TmfTraceException("Insufficient valid traces in directory"); - } - } catch (TmfTraceException e) { - System.out.println(e.getMessage()); - } - } - - private static void waitForRequest(InnerEventRequest expReq, InnerEventRequest[] traceReqs) { - try { - expReq.waitForCompletion(); - List reqs = Arrays.asList(traceReqs); - for (InnerEventRequest traceReq : reqs) { - traceReq.waitForCompletion(); - } - } catch (InterruptedException e) { - } - } - - private static class InnerEventRequest extends TmfEventRequest { - private Set fTraces = new HashSet<>(); - - public InnerEventRequest(Class dataType, long index, int nbRequested, ExecutionType priority) { - super(dataType, index, nbRequested, priority); - } - - @Override - public void handleData(ITmfEvent event) { - super.handleData(event); - if (!fTraces.contains(event.getTrace().getName())) { - fTraces.add(event.getTrace().getName()); - } - } - - public boolean isTraceHandled(ITmfTrace trace) { - return fTraces.contains(trace.getName()); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/tracecompass/tmf/ctf/core/tests/perf/AllPerfTests.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/tracecompass/tmf/ctf/core/tests/perf/AllPerfTests.java new file mode 100644 index 0000000000..f96e647d3b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/tracecompass/tmf/ctf/core/tests/perf/AllPerfTests.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests.perf; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * The class AllPerformanceTests builds a suite that can be used to + * run all of the performance tests within its package as well as within any + * subpackages of its package. + * + * @author Geneviève Bastien + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + org.eclipse.tracecompass.tmf.ctf.core.tests.perf.experiment.AllPerfTests.class +}) +public class AllPerfTests { + +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/tracecompass/tmf/ctf/core/tests/perf/experiment/AllPerfTests.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/tracecompass/tmf/ctf/core/tests/perf/experiment/AllPerfTests.java new file mode 100644 index 0000000000..23b4f4f55d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/tracecompass/tmf/ctf/core/tests/perf/experiment/AllPerfTests.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests.perf.experiment; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + ExperimentBenchmark.class +}) +public class AllPerfTests { +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/tracecompass/tmf/ctf/core/tests/perf/experiment/ExperimentBenchmark.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/tracecompass/tmf/ctf/core/tests/perf/experiment/ExperimentBenchmark.java new file mode 100644 index 0000000000..5e274e1808 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/perf/org/eclipse/tracecompass/tmf/ctf/core/tests/perf/experiment/ExperimentBenchmark.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Geneviève Bastien - Convert to JUnit performance test + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests.perf.experiment; + +import java.io.File; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.linuxtools.ctf.core.tests.shared.CtfTestTrace; +import org.eclipse.test.performance.Dimension; +import org.eclipse.test.performance.Performance; +import org.eclipse.test.performance.PerformanceMeter; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfExperimentStub; +import org.junit.Test; + +/** + * Coalescing benchmark + * + * @author Matthew Khouzam + */ +public class ExperimentBenchmark { + + private static final String TEST_ID = "org.eclipse.linuxtools#Experiment benchmark#"; + private static final int MAX_TRACES = 160; + private static final int BLOCK_SIZE = 100; + private static final String TRACES_ROOT_PATH = CtfTestTrace.TRACE_EXPERIMENT.getPath(); + private static final int SAMPLE_SIZE_SLOW = 20; + private static final int SAMPLE_SIZE = 100; + + private TmfExperimentStub fExperiment; + + /** + * Run the benchmark + */ + @Test + public void benchmarkExperimentSizeRequest() { + Performance perf = Performance.getDefault(); + + for (int numTraces = 1; numTraces < MAX_TRACES; numTraces = (int) (1.6 * (numTraces + 1))) { + PerformanceMeter pm = perf.createPerformanceMeter(TEST_ID + numTraces + " traces"); + perf.tagAsSummary(pm, "Experiment Benchmark:" + numTraces + " traces", Dimension.CPU_TIME); + if ((int) (1.6 * (numTraces + 1)) > MAX_TRACES) { + perf.tagAsGlobalSummary(pm, "Experiment Benchmark:" + numTraces + " traces", Dimension.CPU_TIME); + } + + int sampleSize = SAMPLE_SIZE; + if (numTraces > 20) { + sampleSize = SAMPLE_SIZE_SLOW; + } + + for (int s = 0; s < sampleSize; s++) { + + InnerEventRequest expReq = new InnerEventRequest(ITmfEvent.class, 0, ITmfEventRequest.ALL_DATA, ExecutionType.BACKGROUND); + InnerEventRequest traceReq[] = new InnerEventRequest[numTraces]; + + init(numTraces); + fExperiment.sendRequest(expReq); + ITmfTrace[] traces = fExperiment.getTraces(); + for (int i = 0; i < numTraces; i++) { + traceReq[i] = new InnerEventRequest(ITmfEvent.class, 0, ITmfEventRequest.ALL_DATA, ExecutionType.BACKGROUND); + traces[i].sendRequest(traceReq[i]); + } + + pm.start(); + waitForRequest(expReq, traceReq); + pm.stop(); + + for (int i = 0; i < traces.length; i++) { + if (!expReq.isTraceHandled(traces[i])) { + System.err.println("Trace " + i + " not handled!"); + } + } + + fExperiment.dispose(); + } + pm.commit(); + } + } + + /** + * Initialization + * + * @param maxTraces + * maximum number of traces to open + */ + private void init(int maxTraces) { + try { + File parentDir = new File(TRACES_ROOT_PATH); + File[] traceFiles = parentDir.listFiles(); + ITmfTrace[] traces = new CtfTmfTrace[Math.min(maxTraces, traceFiles.length)]; + for (int i = 0; i < traces.length; i++) { + traces[i] = new CtfTmfTrace(); + } + fExperiment = new TmfExperimentStub("MegaExperiment", traces, BLOCK_SIZE); + int j = 0; + for (int i = 0; i < (traces.length) && (j < traces.length); i++) { + String absolutePath = traceFiles[j].getAbsolutePath(); + if (traces[i].validate(null, absolutePath).isOK()) { + traces[i].initTrace(null, absolutePath, ITmfEvent.class); + } else { + i--; + } + j++; + } + if (traces[traces.length - 1].getPath() == null) { + throw new TmfTraceException("Insufficient valid traces in directory"); + } + } catch (TmfTraceException e) { + System.out.println(e.getMessage()); + } + } + + private static void waitForRequest(InnerEventRequest expReq, InnerEventRequest[] traceReqs) { + try { + expReq.waitForCompletion(); + List reqs = Arrays.asList(traceReqs); + for (InnerEventRequest traceReq : reqs) { + traceReq.waitForCompletion(); + } + } catch (InterruptedException e) { + } + } + + private static class InnerEventRequest extends TmfEventRequest { + private Set fTraces = new HashSet<>(); + + public InnerEventRequest(Class dataType, long index, int nbRequested, ExecutionType priority) { + super(dataType, index, nbRequested, priority); + } + + @Override + public void handleData(ITmfEvent event) { + super.handleData(event); + if (!fTraces.contains(event.getTrace().getName())) { + fTraces.add(event.getTrace().getName()); + } + } + + public boolean isTraceHandled(ITmfTrace trace) { + return fTraces.contains(trace.getName()); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/plugin.xml b/org.eclipse.tracecompass.tmf.ctf.core.tests/plugin.xml index 5fa1596cf3..bda640ab5f 100644 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/plugin.xml +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/plugin.xml @@ -5,11 +5,11 @@ point="org.eclipse.linuxtools.tmf.core.tracetype"> + trace_type="org.eclipse.tracecompass.tmf.ctf.core.tests.stubs.CtfTmfTraceStub"> diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/shared/org/eclipse/linuxtools/tmf/ctf/core/tests/shared/CtfTmfTestTrace.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/shared/org/eclipse/linuxtools/tmf/ctf/core/tests/shared/CtfTmfTestTrace.java deleted file mode 100644 index ad72c2e5ca..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/shared/org/eclipse/linuxtools/tmf/ctf/core/tests/shared/CtfTmfTestTrace.java +++ /dev/null @@ -1,123 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests.shared; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.ctf.core.tests.shared.CtfTestTrace; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfEvent; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.stubs.CtfTmfTraceStub; - -/** - * Available CTF TMF test traces. Kind-of-extends {@link CtfTestTrace}. - * - * To run tests using these, you first need to run the "get-traces.[xml|sh]" - * script located under lttng/org.eclipse.tracecompass.ctf.core.tests/traces/ . - * - * @author Alexandre Montplaisir - */ -@NonNullByDefault -public enum CtfTmfTestTrace { - /** Example kernel trace */ - KERNEL, - /** Another kernel trace */ - TRACE2, - /** Kernel trace with event contexts */ - KERNEL_VM, - /** Trace synchronization: source trace */ - SYNC_SRC, - /** Trace synchronization: destination trace */ - SYNC_DEST, - /** Trace synchronization (case 2): django client trace */ - DJANGO_CLIENT, - /** Trace synchronization (case 2): django db trace */ - DJANGO_DB, - /** Trace synchronization (case 2): django web server trace */ - DJANGO_HTTPD, - /** UST trace with lots of lost events */ - HELLO_LOST, - /** UST trace with lttng-ust-cyg-profile events (aka -finstrument-functions) */ - CYG_PROFILE, - /** UST trace with lttng-ust-cyg-profile-fast events (no address in func_exit) */ - CYG_PROFILE_FAST, - /** Autogenerated Syntetic trace */ - SYNTHETIC_TRACE, - /** Trace with non-standard field sizes */ - FUNKY_TRACE; - - - private final String fPath; - private @Nullable CtfTmfTraceStub fTrace = null; - - private CtfTmfTestTrace() { - @SuppressWarnings("null") - @NonNull String path = CtfTestTrace.valueOf(this.name()).getPath(); - fPath = path; - } - - /** - * @return The path of this trace - */ - public String getPath() { - return fPath; - } - - /** - * Return a CtfTmfTraceStub object of this test trace. It will be already - * initTrace()'ed. - * - * Make sure you call {@link #exists()} before calling this! - * - * After being used by unit tests, traces must be properly disposed of by - * calling the {@link CtfTmfTestTrace#dispose()} method. - * - * @return A CtfTmfTrace reference to this trace - */ - public synchronized CtfTmfTrace getTrace() { - CtfTmfTraceStub trace = fTrace; - if (trace != null) { - trace.close(); - } - trace = new CtfTmfTraceStub(); - try { - trace.initTrace(null, fPath, CtfTmfEvent.class); - } catch (TmfTraceException e) { - /* Should not happen if tracesExist() passed */ - throw new RuntimeException(e); - } - fTrace = trace; - return trace; - } - - /** - * Check if the trace actually exists on disk or not. - * - * @return If the trace is present - */ - public boolean exists() { - return CtfTestTrace.valueOf(this.name()).exists(); - } - - /** - * Dispose of the trace - */ - public void dispose() { - if (fTrace != null) { - fTrace.dispose(); - fTrace = null; - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/shared/org/eclipse/tracecompass/tmf/ctf/core/tests/shared/CtfTmfTestTrace.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/shared/org/eclipse/tracecompass/tmf/ctf/core/tests/shared/CtfTmfTestTrace.java new file mode 100644 index 0000000000..4c726d118a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/shared/org/eclipse/tracecompass/tmf/ctf/core/tests/shared/CtfTmfTestTrace.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests.shared; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.linuxtools.ctf.core.tests.shared.CtfTestTrace; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfEvent; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.stubs.CtfTmfTraceStub; + +/** + * Available CTF TMF test traces. Kind-of-extends {@link CtfTestTrace}. + * + * To run tests using these, you first need to run the "get-traces.[xml|sh]" + * script located under lttng/org.eclipse.tracecompass.ctf.core.tests/traces/ . + * + * @author Alexandre Montplaisir + */ +@NonNullByDefault +public enum CtfTmfTestTrace { + /** Example kernel trace */ + KERNEL, + /** Another kernel trace */ + TRACE2, + /** Kernel trace with event contexts */ + KERNEL_VM, + /** Trace synchronization: source trace */ + SYNC_SRC, + /** Trace synchronization: destination trace */ + SYNC_DEST, + /** Trace synchronization (case 2): django client trace */ + DJANGO_CLIENT, + /** Trace synchronization (case 2): django db trace */ + DJANGO_DB, + /** Trace synchronization (case 2): django web server trace */ + DJANGO_HTTPD, + /** UST trace with lots of lost events */ + HELLO_LOST, + /** UST trace with lttng-ust-cyg-profile events (aka -finstrument-functions) */ + CYG_PROFILE, + /** UST trace with lttng-ust-cyg-profile-fast events (no address in func_exit) */ + CYG_PROFILE_FAST, + /** Autogenerated Syntetic trace */ + SYNTHETIC_TRACE, + /** Trace with non-standard field sizes */ + FUNKY_TRACE; + + + private final String fPath; + private @Nullable CtfTmfTraceStub fTrace = null; + + private CtfTmfTestTrace() { + @SuppressWarnings("null") + @NonNull String path = CtfTestTrace.valueOf(this.name()).getPath(); + fPath = path; + } + + /** + * @return The path of this trace + */ + public String getPath() { + return fPath; + } + + /** + * Return a CtfTmfTraceStub object of this test trace. It will be already + * initTrace()'ed. + * + * Make sure you call {@link #exists()} before calling this! + * + * After being used by unit tests, traces must be properly disposed of by + * calling the {@link CtfTmfTestTrace#dispose()} method. + * + * @return A CtfTmfTrace reference to this trace + */ + public synchronized CtfTmfTrace getTrace() { + CtfTmfTraceStub trace = fTrace; + if (trace != null) { + trace.close(); + } + trace = new CtfTmfTraceStub(); + try { + trace.initTrace(null, fPath, CtfTmfEvent.class); + } catch (TmfTraceException e) { + /* Should not happen if tracesExist() passed */ + throw new RuntimeException(e); + } + fTrace = trace; + return trace; + } + + /** + * Check if the trace actually exists on disk or not. + * + * @return If the trace is present + */ + public boolean exists() { + return CtfTestTrace.valueOf(this.name()).exists(); + } + + /** + * Dispose of the trace + */ + public void dispose() { + if (fTrace != null) { + fTrace.dispose(); + fTrace = null; + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/AllTests.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/AllTests.java deleted file mode 100644 index 3230a87700..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/AllTests.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial generation with CodePro tools - * Alexandre Montplaisir - Clean up, consolidate redundant tests - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * The class TestAll builds a suite that can be used to run all - * of the tests within its package as well as within any subpackages of its - * package. - * - * @author ematkho - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - CtfIteratorTest.class, - CtfLocationDataTest.class, - CtfLocationTest.class, - CtfTmfContextTest.class, - CtfTmfEventFieldTest.class, - CtfTmfEventTest.class, - CtfTmfEventTypeTest.class, - CtfTmfLostEventsTest.class, - CtfTmfTimestampTest.class, - CtfTmfTraceTest.class, - EventContextTest.class, - FunkyTraceTest.class, - - /* Tests in other packages (that are there because of CTF) */ - org.eclipse.linuxtools.tmf.ctf.core.tests.request.AllTests.class, - org.eclipse.linuxtools.tmf.ctf.core.tests.statistics.AllTests.class, - org.eclipse.linuxtools.tmf.ctf.core.tests.tracemanager.AllTests.class -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfIteratorTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfIteratorTest.java deleted file mode 100644 index 9100880f68..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfIteratorTest.java +++ /dev/null @@ -1,243 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial generation with CodePro tools - * Alexandre Montplaisir - Clean up, consolidate redundant tests - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; - -import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException; -import org.eclipse.linuxtools.tmf.ctf.core.CtfIterator; -import org.eclipse.linuxtools.tmf.ctf.core.CtfLocation; -import org.eclipse.linuxtools.tmf.ctf.core.CtfLocationInfo; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfEvent; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * The class CtfIteratorTest contains tests for the class - * {@link CtfIterator}. - * - * @author ematkho - * @version 1.0 - */ -public class CtfIteratorTest { - - private static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.KERNEL; - - private CtfTmfTrace trace; - private CtfIterator iterator; - - /** - * Perform pre-test initialization. - * @throws CTFReaderException error - */ - @Before - public void setUp() throws CTFReaderException { - assumeTrue(testTrace.exists()); - trace = testTrace.getTrace(); - iterator = new CtfIterator(trace); - CtfLocation ctfLocation = new CtfLocation(new CtfLocationInfo(1, 0)); - iterator.setLocation(ctfLocation); - iterator.increaseRank(); - } - - /** - * Perform post-test clean-up. - */ - @After - public void tearDown() { - if (trace != null) { - trace.dispose(); - } - if (iterator != null) { - iterator.dispose(); - } - } - - /** - * Run the CtfIterator(CtfTmfTrace) constructor on a non init'ed trace. - * @throws CTFReaderException error - */ - @Test - public void testCtfIterator_noinit() throws CTFReaderException { - try (CtfIterator result = new CtfIterator(trace);) { - assertNotNull(result); - } - } - - /** - * Run the CtfIterator(CtfTmfTrace) constructor on an init'ed trace. - * @throws CTFReaderException error - */ - @Test - public void testCtfIterator_init() throws CTFReaderException { - trace.init("test"); - try (CtfIterator result = new CtfIterator(trace);) { - assertNotNull(result); - } - } - - /** - * Run the CtfIterator(CtfTmfTrace,long,long) constructor test, which - * specifies an initial position for the iterator. - * @throws CTFReaderException error - */ - @Test - public void testCtfIterator_position() throws CTFReaderException { - long timestampValue = 1L; - long rank = 1L; - try (CtfIterator result = new CtfIterator(trace, new CtfLocationInfo(timestampValue, 0), rank);) { - assertNotNull(result); - } - } - - - /** - * Run the boolean advance() method test. - */ - @Test - public void testAdvance() { - boolean result = iterator.advance(); - assertTrue(result); - } - - /** - * Run the int compareTo(CtfIterator) method test. - * @throws CTFReaderException error - */ - @Test - public void testCompareTo() throws CTFReaderException { - try (CtfIterator o = new CtfIterator(trace);) { - int result = iterator.compareTo(o); - assertEquals(1L, result); - } - } - - /** - * Run the boolean equals(Object) method test. Compare with another iterator - * on the same trace. - * @throws CTFReaderException error - */ - @Test - public void testEquals_other() throws CTFReaderException { - try (CtfIterator obj = new CtfIterator(trace);) { - CtfLocation ctfLocation1 = new CtfLocation(new CtfLocationInfo(1, 0)); - obj.setLocation(ctfLocation1); - obj.increaseRank(); - - boolean result = iterator.equals(obj); - assertTrue(result); - } - } - - /** - * Run the boolean equals(Object) method test. Compare with an empty object. - */ - @Test - public void testEquals_empty() { - Object obj = new Object(); - boolean result = iterator.equals(obj); - - assertFalse(result); - } - - /** - * Run the CtfTmfTrace getCtfTmfTrace() method test. - */ - @Test - public void testGetCtfTmfTrace() { - try (CtfTmfTrace result = iterator.getCtfTmfTrace();) { - assertNotNull(result); - } - } - - /** - * Run the CtfTmfEvent getCurrentEvent() method test. - */ - @Test - public void testGetCurrentEvent() { - CtfTmfEvent result = iterator.getCurrentEvent(); - assertNotNull(result); - } - - /** - * Run the CtfLocation getLocation() method test. - */ - @Test - public void testGetLocation() { - CtfLocation result = iterator.getLocation(); - assertNotNull(result); - } - - /** - * Run the long getRank() method test. - */ - @Test - public void testGetRank() { - long result = iterator.getRank(); - assertEquals(1L, result); - } - - /** - * Run the boolean hasValidRank() method test. - */ - @Test - public void testHasValidRank() { - boolean result = iterator.hasValidRank(); - assertTrue(result); - } - - /** - * Run the int hashCode() method test. - */ - @Test - public void testHashCode() { - int result = iterator.hashCode(); - int result2 = iterator.hashCode(); - assertEquals(result, result2); - } - - /** - * Run the void increaseRank() method test. - */ - @Test - public void testIncreaseRank() { - iterator.increaseRank(); - } - - /** - * Run the boolean seek(long) method test. - */ - @Test - public void testSeek() { - long timestamp = 1L; - boolean result = iterator.seek(timestamp); - assertTrue(result); - } - - /** - * Run the void setLocation(ITmfLocation) method test. - */ - @Test - public void testSetLocation() { - CtfLocation location = new CtfLocation(new CtfLocationInfo(1, 0)); - iterator.setLocation(location); - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfLocationDataTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfLocationDataTest.java deleted file mode 100644 index 2a963b477a..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfLocationDataTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.eclipse.linuxtools.tmf.ctf.core.CtfLocationInfo; -import org.junit.Before; -import org.junit.Test; - -/** - * Collection of tests for the {@link CtfLocationInfo} - * - * @author alexmont - */ -public class CtfLocationDataTest { - - private CtfLocationInfo fixture; - - /** - * Perform pre-test initialization. - */ - @Before - public void setUp() { - fixture = new CtfLocationInfo(1, 0); - } - - /** - * Test for the .getTimestamp() and .getIndex() methods - */ - @Test - public void testGetters() { - long timestamp = fixture.getTimestamp(); - long index = fixture.getIndex(); - - assertEquals(1, timestamp); - assertEquals(0, index); - } - - /** - * Test for the .hashCode() method - */ - @Test - public void testHashCode() { - int code = fixture.hashCode(); - assertEquals(962, code); - } - - /** - * Test for the .equals() method - */ - @Test - public void testEquals() { - CtfLocationInfo same = new CtfLocationInfo(1, 0); - CtfLocationInfo diff1 = new CtfLocationInfo(100, 0); - CtfLocationInfo diff2 = new CtfLocationInfo(1, 10); - - assertTrue(fixture.equals(same)); - assertFalse(fixture.equals(diff1)); - assertFalse(fixture.equals(diff2)); - } - - /** - * Test for the .compareTo() method - */ - @Test - public void testCompareTo() { - CtfLocationInfo same = new CtfLocationInfo(1, 0); - CtfLocationInfo smaller = new CtfLocationInfo(0, 0); - CtfLocationInfo bigger1 = new CtfLocationInfo(1000, 500); - CtfLocationInfo bigger2 = new CtfLocationInfo(1, 1); - - assertEquals(0, same.compareTo(fixture)); - assertEquals(-1, smaller.compareTo(fixture)); - assertEquals(1, bigger1.compareTo(fixture)); - assertEquals(1, bigger2.compareTo(fixture)); - } - - /** - * Test for the .toString() method - */ - @Test - public void testToString() { - String expected = "Element [1/0]"; - assertEquals(expected, fixture.toString()); - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfLocationTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfLocationTest.java deleted file mode 100644 index dd0a965892..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfLocationTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial generation with CodePro tools - * Alexandre Montplaisir - Clean up, consolidate redundant tests - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.ctf.core.CtfLocation; -import org.eclipse.linuxtools.tmf.ctf.core.CtfLocationInfo; -import org.junit.Before; -import org.junit.Test; - -/** - * The class CtfLocationTest contains tests for the class - * {@link CtfLocation}. - * - * @author ematkho - * @version 1.0 - */ -public class CtfLocationTest { - - private CtfLocation fixture; - - /** - * Perform pre-test initialization. - */ - @Before - public void setUp() { - fixture = new CtfLocation(new CtfLocationInfo(1, 0)); - } - - /** - * Run the CtfLocation(Long) constructor test. - */ - @Test - public void testCtfLocation_long() { - CtfLocationInfo location = new CtfLocationInfo(1, 0); - CtfLocation result = new CtfLocation(location); - - assertNotNull(result); - assertEquals(1L, result.getLocationInfo().getTimestamp()); - } - - /** - * Run the CtfLocation(ITmfTimestamp) constructor test. - */ - @Test - public void testCtfLocation_timestamp() { - ITmfTimestamp timestamp = new TmfTimestamp(); - CtfLocation result = new CtfLocation(timestamp); - - assertNotNull(result); - assertEquals(0L, result.getLocationInfo().getTimestamp()); - } - - /** - * Run the Long getLocation() method test. - */ - @Test - public void testGetLocation() { - CtfLocationInfo location = fixture.getLocationInfo(); - long result = location.getTimestamp(); - assertEquals(1L, result); - } - - /** - * Run the void setLocation(Long) method test. - */ - @Test - public void testSetLocation() { - CtfLocationInfo location = new CtfLocationInfo(1337, 7331); - fixture = new CtfLocation(location); - } - - /** - * Test the toString() method with a valid location. - */ - @Test - public void testToString_valid(){ - CtfLocation fixture2 = new CtfLocation(new CtfLocationInfo(1337, 7331)); - assertEquals("CtfLocation [fLocationInfo=Element [1337/7331]]", fixture2.toString()); - } - - /** - * Test the toString() method with an invalid location. - */ - @Test - public void testToString_invalid(){ - CtfLocation fixture2 = new CtfLocation(new CtfLocationInfo(-1, -1)); - assertEquals("CtfLocation [INVALID]", fixture2.toString()); - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfContextTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfContextTest.java deleted file mode 100644 index 2aa8224264..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfContextTest.java +++ /dev/null @@ -1,126 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial implementation - * Alexandre Montplaisir - * Patrick Tasse - Updated for removal of context clone - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; - -import java.util.ArrayList; - -import org.eclipse.core.resources.IResource; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfContext; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfEvent; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; -import org.junit.Before; -import org.junit.Test; - -/** - * Tests for the CtfTmfLightweightContext class - * - * @author Matthew Khouzam - * @version 1.1 - */ -public class CtfTmfContextTest { - - private static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.KERNEL; - private static final long begin = 1332170682440133097L; /* Trace start time */ - private static final long end = 1332170692664579801L; /* Trace end time */ - - private CtfTmfTrace trace; - - private class SeekerThread extends Thread { - long val; - - public void setVal(long val) { - this.val = val; - } - } - - /** - * Pre-test initialization - * - * @throws TmfTraceException - * If the trace couldn't be init'ed, which shouldn't happen. - */ - @Before - public void setUp() throws TmfTraceException { - assumeTrue(testTrace.exists()); - trace = new CtfTmfTrace(); - String path = testTrace.getPath(); - trace.initTrace((IResource) null, path, CtfTmfEvent.class); - } - - /** - * Index all the events in the test trace. - */ - @Test - public void testIndexing() { - CtfTmfContext context = new CtfTmfContext(trace); - context.seek(0); - - int count = 0; - while (trace.getNext(context) != null) { - count++; - } - assertTrue(count > 0); - } - - /** - * Context fuzzer. Use an amount of contexts greater than the size of the - * iterator cache and have them access the trace in parallel. - * - * @throws InterruptedException - * Would fail the test - */ - @Test - public void testTooManyContexts() throws InterruptedException { - final int lwcCount = 101; - double increment = (end - begin) / lwcCount; - final ArrayList vals = new ArrayList<>(); - final ArrayList threads = new ArrayList<>(); - final ArrayList tooManyContexts = new ArrayList<>(); - - for (double i = begin; i < end; i += increment) { - SeekerThread thread = new SeekerThread() { - @Override - public void run() { - CtfTmfContext lwc = new CtfTmfContext(trace); - lwc.seek(val); - trace.getNext(lwc); - synchronized(trace){ - if (lwc.getCurrentEvent() != null) { - vals.add(lwc.getCurrentEvent().getTimestamp().getValue()); - } - tooManyContexts.add(lwc); - } - } - }; - thread.setVal((long)i); - threads.add(thread); - thread.start(); - } - - for (Thread t: threads){ - t.join(); - } - - for (long val : vals){ - assertTrue(val >= begin); - assertTrue(val <= end); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfEventFieldTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfEventFieldTest.java deleted file mode 100644 index fe94569d24..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfEventFieldTest.java +++ /dev/null @@ -1,324 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial generation with CodePro tools - * Alexandre Montplaisir - Clean up, consolidate redundant tests - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; - -import java.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.ctf.core.event.io.BitBuffer; -import org.eclipse.linuxtools.ctf.core.event.types.EnumDeclaration; -import org.eclipse.linuxtools.ctf.core.event.types.FloatDeclaration; -import org.eclipse.linuxtools.ctf.core.event.types.FloatDefinition; -import org.eclipse.linuxtools.ctf.core.event.types.IDefinition; -import org.eclipse.linuxtools.ctf.core.event.types.IntegerDeclaration; -import org.eclipse.linuxtools.ctf.core.event.types.StringDeclaration; -import org.eclipse.linuxtools.ctf.core.event.types.StructDeclaration; -import org.eclipse.linuxtools.ctf.core.event.types.StructDefinition; -import org.eclipse.linuxtools.ctf.core.event.types.VariantDeclaration; -import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException; -import org.eclipse.linuxtools.internal.ctf.core.event.types.ArrayDeclaration; -import org.eclipse.linuxtools.internal.ctf.core.event.types.SequenceDeclaration; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfEventField; -import org.junit.Before; -import org.junit.Test; - -/** - * The class CtfTmfEventFieldTest contains tests for the class - * {@link CtfTmfEventField}. - * - * @author Matthew Khouzam - * @version 1.0 - */ -public class CtfTmfEventFieldTest { - - private static final @NonNull String ROOT = "root"; - private static final String SEQ = "seq"; - private static final @NonNull String ARRAY_STR = "array_str"; - private static final @NonNull String ARRAY_FLOAT = "array_float"; - private static final @NonNull String ARRAY_INT = "array_int"; - private static final @NonNull String ARRAY_STRUCT = "array_struct"; - private static final @NonNull String ARRAY_VARIANT = "array_variant"; - private static final @NonNull String ARRAY_ENUM = "array_enum"; - private static final String STR = "str"; - private static final String FLOAT = "float"; - private static final String LEN = "len"; - private static final String INT = "int"; - private static final String NAME = "test"; - private static final String STRUCT = "struct"; - private static final String VARIANT = "variant"; - private static final String ENUM = "enum"; - - private static final byte TEST_NUMBER = 2; - private static final String TEST_STRING = "two"; - - private static final int ARRAY_SIZE = 2; - - private StructDefinition fixture; - - /** - * Perform pre-test initialization. - * - * @throws UnsupportedEncodingException - * Thrown when UTF-8 encoding is not available. - * @throws CTFReaderException - * error - */ - @Before - public void setUp() throws UnsupportedEncodingException, CTFReaderException { - final byte[] testStringBytes = TEST_STRING.getBytes("UTF-8"); - - int capacity = 2048; - ByteBuffer bb = ByteBuffer.allocateDirect(capacity); - - StructDeclaration sDec = new StructDeclaration(1l); - StringDeclaration strDec = new StringDeclaration(); - IntegerDeclaration intDec = IntegerDeclaration.UINT_8_DECL; - FloatDeclaration flDec = new FloatDeclaration(8, 24, - ByteOrder.BIG_ENDIAN, 8); - SequenceDeclaration seqDec = new SequenceDeclaration(LEN, intDec); - StructDeclaration structDec = new StructDeclaration(8); - EnumDeclaration enumDec = new EnumDeclaration(intDec); - VariantDeclaration varDec = new VariantDeclaration(); - ArrayDeclaration arrStrDec = new ArrayDeclaration(ARRAY_SIZE, strDec); - ArrayDeclaration arrFloatDec = new ArrayDeclaration(ARRAY_SIZE, flDec); - ArrayDeclaration arrIntDec = new ArrayDeclaration(ARRAY_SIZE, intDec); - ArrayDeclaration arrStructDec = new ArrayDeclaration(ARRAY_SIZE, structDec); - ArrayDeclaration arrVariantDec = new ArrayDeclaration(ARRAY_SIZE, varDec); - ArrayDeclaration arrEnumDec = new ArrayDeclaration(ARRAY_SIZE, enumDec); - - sDec.addField(INT, intDec); - bb.put(TEST_NUMBER); - - sDec.addField(ARRAY_INT, arrIntDec); - for (int i = 0; i < ARRAY_SIZE; ++i) { - bb.put(TEST_NUMBER); - } - - sDec.addField(LEN, intDec); - bb.put(TEST_NUMBER); - - sDec.addField(FLOAT, flDec); - bb.putFloat(TEST_NUMBER); - - sDec.addField(ARRAY_FLOAT, arrFloatDec); - for (int i = 0; i < ARRAY_SIZE; ++i) { - bb.putFloat(TEST_NUMBER); - } - - sDec.addField(STR, strDec); - bb.put(testStringBytes); - bb.put((byte) 0); - - sDec.addField(ARRAY_STR, arrStrDec); - for (int i = 0; i < ARRAY_SIZE; ++i) { - bb.put(testStringBytes); - bb.put((byte) 0); - } - - sDec.addField(SEQ, seqDec); - bb.put(TEST_NUMBER); - bb.put(TEST_NUMBER); - - structDec.addField(STR, strDec); - structDec.addField(INT, intDec); - sDec.addField(STRUCT, structDec); - bb.put(testStringBytes); - bb.put((byte) 0); - bb.put(TEST_NUMBER); - - sDec.addField(ARRAY_STRUCT, arrStructDec); - for (int i = 0; i < ARRAY_SIZE; ++i) { - bb.put(testStringBytes); - bb.put((byte) 0); - bb.put(TEST_NUMBER); - } - - enumDec.add(0, 1, LEN); - enumDec.add(2, 3, FLOAT); - sDec.addField(ENUM, enumDec); - bb.put(TEST_NUMBER); - - sDec.addField(ARRAY_ENUM, arrEnumDec); - for (int i = 0; i < ARRAY_SIZE; ++i) { - bb.put(TEST_NUMBER); - } - - varDec.addField(LEN, intDec); - varDec.addField(FLOAT, flDec); - varDec.setTag(ENUM); - sDec.addField(VARIANT, varDec); - bb.putFloat(TEST_NUMBER); - - sDec.addField(ARRAY_VARIANT, arrVariantDec); - for (int i = 0; i < ARRAY_SIZE; ++i) { - bb.putFloat(TEST_NUMBER); - } - - fixture = sDec.createDefinition(fixture, ROOT, new BitBuffer(bb)); - - } - - /** - * Run the CtfTmfEventField parseField(Definition,String) method test. - */ - @Test - public void testParseField_float() { - FloatDefinition fieldDef = (FloatDefinition) fixture.lookupDefinition(FLOAT); - CtfTmfEventField result = CtfTmfEventField.parseField((IDefinition)fieldDef, "_" + NAME); - assertEquals("test=2.0", result.toString()); - } - - /** - * Run the CtfTmfEventField parseField(Definition,String) method test for an - * array of floats field. - */ - @Test - public void testParseField_array_float() { - IDefinition fieldDef = fixture.lookupArrayDefinition(ARRAY_FLOAT); - CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); - assertEquals("test=[2.0, 2.0]", result.toString()); - } - - /** - * Run the CtfTmfEventField parseField(Definition,String) method test. - */ - @Test - public void testParseField_int() { - IDefinition fieldDef = fixture.lookupDefinition(INT); - CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); - assertEquals("test=2", result.toString()); - } - - /** - * Run the CtfTmfEventField parseField(Definition,String) method test for an - * array of integers field. - */ - @Test - public void testParseField_array_int() { - IDefinition fieldDef = fixture.lookupArrayDefinition(ARRAY_INT); - CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); - assertEquals("test=[2, 2]", result.toString()); - } - - /** - * Run the CtfTmfEventField parseField(Definition,String) method test. - */ - @Test - public void testParseField_sequence() { - IDefinition fieldDef = fixture.lookupDefinition(SEQ); - CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); - assertEquals("test=[2, 2]", result.toString()); - } - - /** - * Run the CtfTmfEventField parseField(Definition,String) method test. - */ - @Test - public void testParseField_sequence_value() { - IDefinition fieldDef = fixture.lookupDefinition(SEQ); - CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); - long[] values = (long[]) result.getValue(); - long[] expected = new long[] { 2, 2 }; - assertArrayEquals(expected, values); - } - - /** - * Run the CtfTmfEventField parseField(Definition,String) method test. - */ - @Test - public void testParseField_string() { - IDefinition fieldDef = fixture.lookupDefinition(STR); - CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); - assertEquals("test=two", result.toString()); - } - - /** - * Run the CtfTmfEventField parseField(Definition,String) method test for an - * array of strings field. - */ - @Test - public void testParseField_array_string() { - IDefinition fieldDef = fixture.lookupArrayDefinition(ARRAY_STR); - CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); - assertEquals("test=[two, two]", result.toString()); - } - - /** - * Run the CtfTmfEventField parseField(Definition,String) method test. - */ - @Test - public void testParseField_struct() { - IDefinition fieldDef = fixture.lookupDefinition(STRUCT); - CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); - assertEquals("test=[str=two, int=2]", result.toString()); - } - - /** - * Run the CtfTmfEventField parseField(Definition,String) method test for an - * array of structs field. - */ - @Test - public void testParseField_array_struct() { - IDefinition fieldDef = fixture.lookupArrayDefinition(ARRAY_STRUCT); - CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); - assertEquals("test=[[str=two, int=2], [str=two, int=2]]", result.toString()); - } - - /** - * Run the CtfTmfEventField parseField(Definition,String) method test. - */ - @Test - public void testParseField_enum() { - IDefinition fieldDef = fixture.lookupDefinition(ENUM); - CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); - assertEquals("test=float", result.toString()); - } - - /** - * Run the CtfTmfEventField parseField(Definition,String) method test for an - * array of enums field. - */ - @Test - public void testParseField_array_enum() { - IDefinition fieldDef = fixture.lookupArrayDefinition(ARRAY_ENUM); - CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); - assertEquals("test=[float, float]", result.toString()); - } - - /** - * Run the CtfTmfEventField parseField(Definition,String) method test. - */ - @Test - public void testParseField_variant() { - IDefinition fieldDef = fixture.lookupDefinition(VARIANT); - CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); - assertEquals("test=float=2.0", result.toString()); - } - - /** - * Run the CtfTmfEventField parseField(Definition,String) method test for an - * array of variants field. - */ - @Test - public void testParseField_array_variant() { - IDefinition fieldDef = fixture.lookupArrayDefinition(ARRAY_VARIANT); - CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); - assertEquals("test=[float=2.0, float=2.0]", result.toString()); - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfEventTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfEventTest.java deleted file mode 100644 index 2411dd2199..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfEventTest.java +++ /dev/null @@ -1,227 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial generation with CodePro tools - * Alexandre Montplaisir - Clean up, consolidate redundant tests - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assume.assumeTrue; - -import java.util.Collection; -import java.util.Set; - -import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.ctf.core.CtfIterator; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfEvent; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfEventFactory; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * The class CtfTmfEventTest contains tests for the class - * {@link CtfTmfEvent}. - * - * @author ematkho - * @version $Revision: 1.0 $ - */ -public class CtfTmfEventTest { - - private static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.KERNEL; - - private static CtfTmfEvent nullEvent; - private CtfTmfEvent fixture; - - /** - * Test class initialization - */ - @BeforeClass - public static void initialize() { - nullEvent = CtfTmfEventFactory.getNullEvent(); - } - - /** - * Perform pre-test initialization. - * - * @throws CTFReaderException - * error - */ - @Before - public void setUp() throws CTFReaderException { - assumeTrue(testTrace.exists()); - try (CtfTmfTrace trace = testTrace.getTrace(); - CtfIterator tr = new CtfIterator(trace);) { - tr.advance(); - fixture = tr.getCurrentEvent(); - } - } - - /** - * Run the CTFEvent(EventDefinition,StreamInputReader) constructor test. - */ - @Test - public void testCTFEvent_read() { - assertNotNull(fixture); - } - - /** - * Run the int getCPU() method test. - */ - @Test - public void testGetCPU() { - int result = nullEvent.getCPU(); - assertEquals(-1, result); - } - - /** - * Run the String getEventName() method test. - */ - @Test - public void testGetEventName() { - String result = nullEvent.getType().getName(); - assertEquals("Empty CTF event", result); - } - - /** - * Run the ArrayList getFieldNames() method test. - */ - @Test - public void testGetFieldNames() { - Collection result = fixture.getContent().getFieldNames(); - assertNotNull(result); - } - - /** - * Run the Object getFieldValue(String) method test. - */ - @Test - public void testGetFieldValue() { - String fieldName = "pid"; - ITmfEventField result = fixture.getContent().getField(fieldName); - - assertNotNull(result); - assertNotNull(result.getValue()); - } - - /** - * Run the HashMap getFields() method test. - */ - @Test - public void testGetFields() { - Collection fields = nullEvent.getContent().getFields(); - assertEquals(0, fields.size()); - } - - /** - * Run the ITmfEventField getSubFieldValue(String[]) method test. - */ - @Test - public void testGetSubFieldValue() { - /* Field exists */ - String[] names = { "pid" }; - assertNotNull(fixture.getContent().getSubField(names)); - - /* First field exists, not the second */ - String[] names2 = { "pid", "abcd" }; - assertNull(fixture.getContent().getSubField(names2)); - - /* Both field do not exist */ - String[] names3 = { "pfid", "abcd" }; - assertNull(fixture.getContent().getSubField(names3)); - - /* TODO Missing case of embedded field, need event for it */ - } - - /** - * Run the long getID() method test. - */ - @Test - public void testGetID() { - long result = nullEvent.getID(); - assertEquals(-1L, result); - } - - /** - * Run the long getTimestamp() method test. - */ - @Test - public void testGetTimestamp() { - long result = nullEvent.getTimestamp().getValue(); - assertEquals(-1L, result); - } - - /** - * Test the getters for the reference, source and type. - */ - @Test - public void testGetters() { - long rank = fixture.getRank(); - try (CtfTmfTrace trace = fixture.getTrace();) { - assertEquals("kernel", trace.getName()); - } - String reference = fixture.getReference(); - String source = fixture.getSource(); - ITmfEventType type = fixture.getType(); - assertEquals(ITmfContext.UNKNOWN_RANK, rank); - - assertEquals("channel0_1", reference); - assertEquals("1", source); - assertEquals("lttng_statedump_vm_map", type.toString()); - } - - /** - * Test the custom CTF attributes methods. The test trace doesn't have any, - * so the list of attributes should be empty. - */ - @Test - public void testCustomAttributes() { - Set attributes = fixture.listCustomAttributes(); - assertEquals(0, attributes.size()); - - String attrib = fixture.getCustomAttribute("bozo"); - assertNull(attrib); - } - - /** - * Test the toString() method - */ - @Test - public void testToString() { - String s = fixture.getContent().toString(); - assertEquals("pid=1922, start=0xb73ea000, end=0xb73ec000, flags=0x8000075, inode=917738, pgoff=0", s); - } - - /** - * Test the {@link CtfTmfEventFactory#getNullEvent()} method, and the - * nullEvent's values. - */ - @Test - public void testNullEvent() { - CtfTmfEvent nullEvent2 = CtfTmfEventFactory.getNullEvent(); - assertSame(nullEvent2, nullEvent); - assertNotNull(nullEvent); - assertEquals(-1, nullEvent.getCPU()); - assertEquals("Empty CTF event", nullEvent.getType().getName()); - assertNull(nullEvent.getReference()); - assertEquals(0, nullEvent.getContent().getFields().size()); - assertEquals(-1L, nullEvent.getID()); - assertEquals(-1L, nullEvent.getTimestamp().getValue()); - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfEventTypeTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfEventTypeTest.java deleted file mode 100644 index 167bce8f95..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfEventTypeTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial generation with CodePro tools - * Alexandre Montplaisir - Clean up, consolidate redundant tests - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfEventType; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; -import org.junit.Test; - -/** - * The class CtfTmfEventTypeTest contains tests for the class - * {@link CtfTmfEventType}. - * - * @author ematkho - * @version 1.0 - */ -public class CtfTmfEventTypeTest { - - /** - * Run the CtfTmfEventType(String,String,ITmfEventField) constructor test. - */ - @Test - public void testCtfTmfEventType() { - String eventName = ""; - ITmfEventField content = new TmfEventField("", null, new ITmfEventField[] {}); - CtfTmfEventType result = new CtfTmfEventType(eventName, new TmfTraceStub(), content); - - assertNotNull(result); - assertEquals("", result.toString()); - assertEquals("", result.getName()); - assertEquals("Ctf Event/null", result.getContext()); - } - - /** - * Run the String toString() method test. - */ - @Test - public void testToString() { - ITmfEventField emptyField = new TmfEventField("", null, new ITmfEventField[] {}); - CtfTmfEventType fixture = new CtfTmfEventType("", new TmfTraceStub() , emptyField); - - String result = fixture.toString(); - - assertEquals("", result); - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfLostEventStatisticsTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfLostEventStatisticsTest.java deleted file mode 100644 index 069281492d..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfLostEventStatisticsTest.java +++ /dev/null @@ -1,167 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeTrue; - -import java.util.Map; - -import org.eclipse.linuxtools.ctf.core.CTFStrings; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.statistics.ITmfStatistics; -import org.eclipse.linuxtools.tmf.core.statistics.TmfStateStatistics; -import org.eclipse.linuxtools.tmf.core.statistics.TmfStatisticsEventTypesModule; -import org.eclipse.linuxtools.tmf.core.statistics.TmfStatisticsTotalsModule; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; -import org.junit.rules.Timeout; - -/** - * Unit tests for handling of lost events by the statistics backends. - * - * @author Alexandre Montplaisir - */ -public class CtfTmfLostEventStatisticsTest { - - /** Time-out tests after 30 seconds */ - @Rule - public TestRule globalTimeout= new Timeout(30000); - - /**Test trace with lost events */ - private static final CtfTmfTestTrace lostEventsTrace = CtfTmfTestTrace.HELLO_LOST; - - private ITmfTrace fTrace; - - /** The statistics back-end object for the trace with lost events */ - private ITmfStatistics fStats; - - /* The two analysis modules needed for fStats */ - private TmfStatisticsTotalsModule fTotalsMod; - private TmfStatisticsEventTypesModule fEventTypesMod; - - // ------------------------------------------------------------------------ - // Maintenance - // ------------------------------------------------------------------------ - - /** - * Class setup - */ - @BeforeClass - public static void setUpClass() { - assumeTrue(lostEventsTrace.exists()); - } - - /** - * Test setup - */ - @Before - public void setUp() { - fTrace = lostEventsTrace.getTrace(); - - /* Prepare the two analysis-backed state systems */ - fTotalsMod = new TmfStatisticsTotalsModule(); - fEventTypesMod = new TmfStatisticsEventTypesModule(); - try { - fTotalsMod.setTrace(fTrace); - fEventTypesMod.setTrace(fTrace); - } catch (TmfAnalysisException e) { - fail(); - } - - fTotalsMod.schedule(); - fEventTypesMod.schedule(); - assertTrue(fTotalsMod.waitForCompletion()); - assertTrue(fEventTypesMod.waitForCompletion()); - - ITmfStateSystem totalsSS = fTotalsMod.getStateSystem(); - ITmfStateSystem eventTypesSS = fEventTypesMod.getStateSystem(); - assertNotNull(totalsSS); - assertNotNull(eventTypesSS); - - fStats = new TmfStateStatistics(totalsSS, eventTypesSS); - } - - /** - * Test cleanup - */ - @After - public void tearDown() { - fStats.dispose(); - fTotalsMod.close(); - fEventTypesMod.close(); - fTrace.dispose(); - } - - // ------------------------------------------------------------------------ - // Test methods - // ------------------------------------------------------------------------ - - /* - * Trace start = 1376592664828559410 - * Trace end = 1376592665108210547 - */ - - private static final long rangeStart = 1376592664900000000L; - private static final long rangeEnd = 1376592665000000000L; - - /** - * Test the total number of "real" events. Make sure the lost events aren't - * counted in the total. - */ - @Test - public void testLostEventsTotals() { - long realEvents = fStats.getEventsTotal(); - assertEquals(32300, realEvents); - } - - /** - * Test the number of real events in a given range. Lost events shouldn't be - * counted. - */ - @Test - public void testLostEventsTotalInRange() { - long realEventsInRange = fStats.getEventsInRange(rangeStart, rangeEnd); - assertEquals(11209L, realEventsInRange); - } - - /** - * Test the total number of lost events reported in the trace. - */ - @Test - public void testLostEventsTypes() { - Map events = fStats.getEventTypesTotal(); - Long lostEvents = events.get(CTFStrings.LOST_EVENT_NAME); - assertEquals(Long.valueOf(967700L), lostEvents); - } - - /** - * Test the number of lost events reported in a given range. - */ - @Test - public void testLostEventsTypesInRange() { - Map eventsInRange = fStats.getEventTypesInRange(rangeStart, rangeEnd); - long lostEventsInRange = eventsInRange.get(CTFStrings.LOST_EVENT_NAME); - assertEquals(363494L, lostEventsInRange); - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfLostEventsTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfLostEventsTest.java deleted file mode 100644 index 02f3db41af..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfLostEventsTest.java +++ /dev/null @@ -1,256 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfLostEvent; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfEvent; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTimestamp; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Tests to verify that lost events are handled correctly. - * - * Be wary if you are using Babeltrace to cross-check those values. There could - * be a bug in Babeltrace with regards to lost events. See - * http://bugs.lttng.org/issues/589 - * - * It's not 100% sure at this point which implementation is correct, so for now - * these tests assume the Java implementation is the right one. - * - * @author Alexandre Montplaisir - */ -public class CtfTmfLostEventsTest { - - private static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.HELLO_LOST; - - private CtfTmfTrace fixture = null; - - /** - * Class setup - */ - @Before - public void setUp() { - assumeTrue(testTrace.exists()); - fixture = testTrace.getTrace(); - fixture.indexTrace(true); - } - - /** - * Clean-up - */ - @After - public void tearDown() { - if (fixture != null) { - fixture.dispose(); - } - } - - // ------------------------------------------------------------------------ - // Test methods - // ------------------------------------------------------------------------ - - /** - * Test that the number of events is reported correctly (a range of lost - * events is counted as one event). - */ - @Test - public void testNbEvents() { - final long expectedReal = 32300; - final long expectedLost = 562; - - EventCountRequest req = new EventCountRequest(); - fixture.sendRequest(req); - try { - req.waitForCompletion(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - assertEquals(expectedReal, req.getReal()); - assertEquals(expectedLost, req.getLost()); - } - - /** - * Test getting the first lost event from the trace. - */ - @Test - public void testFirstLostEvent() { - final long rank = 153; - final ITmfTimestamp start = new CtfTmfTimestamp(1376592664828848222L); - final ITmfTimestamp end = new CtfTmfTimestamp(1376592664828848540L); - final long nbLost = 859; - - final CtfTmfEvent ev = getOneEventTime(start); - /* Make sure seeking by rank yields the same event */ - final CtfTmfEvent ev2 = getOneEventRank(rank); - assertEquals(ev, ev2); - - assertTrue(ev instanceof ITmfLostEvent); - ITmfLostEvent event = (ITmfLostEvent) ev; - - assertEquals(start, event.getTimestamp()); - assertEquals(start, event.getTimeRange().getStartTime()); - assertEquals(end, event.getTimeRange().getEndTime()); - assertEquals(nbLost, event.getNbLostEvents()); - } - - /** - * Test getting the second lost event from the trace. - */ - @Test - public void testSecondLostEvent() { - final long rank = 191; - final ITmfTimestamp start = new CtfTmfTimestamp(1376592664829402521L); - final ITmfTimestamp end = new CtfTmfTimestamp(1376592664829403076L); - final long nbLost = 488; - - final CtfTmfEvent ev = getOneEventTime(start); - /* Make sure seeking by rank yields the same event */ - final CtfTmfEvent ev2 = getOneEventRank(rank); - assertEquals(ev, ev2); - - assertTrue(ev instanceof ITmfLostEvent); - ITmfLostEvent event = (ITmfLostEvent) ev; - - assertEquals(start, event.getTimestamp()); - assertEquals(start, event.getTimeRange().getStartTime()); - assertEquals(end, event.getTimeRange().getEndTime()); - assertEquals(nbLost, event.getNbLostEvents()); - } - - /** - * Test getting one normal event from the trace (lost events should not - * interfere). - */ - @Test - public void testNormalEvent() { - final long rank = 200; - final ITmfTimestamp ts = new CtfTmfTimestamp(1376592664829423928L); - - final CtfTmfEvent event = getOneEventTime(ts); - /* Make sure seeking by rank yields the same event */ - final CtfTmfEvent event2 = getOneEventRank(rank); - assertEquals(event, event2); - - assertFalse(event instanceof ITmfLostEvent); - assertEquals(ts, event.getTimestamp()); - } - - // ------------------------------------------------------------------------ - // Event requests - // ------------------------------------------------------------------------ - - private CtfTmfEvent getOneEventRank(long rank) { - OneEventRequestPerRank req = new OneEventRequestPerRank(rank); - fixture.sendRequest(req); - try { - req.waitForCompletion(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - return req.getEvent(); - } - - private CtfTmfEvent getOneEventTime(ITmfTimestamp ts) { - OneEventRequestPerTs req = new OneEventRequestPerTs(ts); - fixture.sendRequest(req); - try { - req.waitForCompletion(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - return req.getEvent(); - } - - private class OneEventRequestPerRank extends TmfEventRequest { - - private CtfTmfEvent event = null; - - public OneEventRequestPerRank(long rank) { - super(CtfTmfEvent.class, TmfTimeRange.ETERNITY, rank, 1, ExecutionType.FOREGROUND); - } - - @Override - public void handleData(ITmfEvent ev) { - /* Type is checked by the request, cast should be safe */ - event = (CtfTmfEvent) ev; - } - - public CtfTmfEvent getEvent() { - return event; - } - } - - private class OneEventRequestPerTs extends TmfEventRequest { - - private CtfTmfEvent event = null; - - public OneEventRequestPerTs(ITmfTimestamp ts) { - super(CtfTmfEvent.class, - new TmfTimeRange(ts, TmfTimestamp.PROJECT_IS_CANNED), - 0, 1, ExecutionType.FOREGROUND); - } - - @Override - public void handleData(ITmfEvent ev) { - event = (CtfTmfEvent) ev; - } - - public CtfTmfEvent getEvent() { - return event; - } - } - - private class EventCountRequest extends TmfEventRequest { - - private long nbReal = 0; - private long nbLost = 0; - - public EventCountRequest() { - super(CtfTmfEvent.class, TmfTimeRange.ETERNITY, 0, - ITmfEventRequest.ALL_DATA, ExecutionType.FOREGROUND); - } - - @Override - public void handleData(ITmfEvent event) { - if (event instanceof ITmfLostEvent) { - nbLost++; - } else { - nbReal++; - } - } - - public long getReal() { - return nbReal; - } - - public long getLost() { - return nbLost; - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfTimestampTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfTimestampTest.java deleted file mode 100644 index b16bccc5f7..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfTimestampTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial generation with CodePro tools - * Alexandre Montplaisir - Clean up, consolidate redundant tests - * Patrick Tasse - Fix for local time zone - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTimestamp; -import org.junit.Test; - -/** - * The class CtfTmfTimestampTest contains tests for the class - * {@link CtfTmfTimestamp}. - * - * @author ematkho - * @version 1.0 - */ -public class CtfTmfTimestampTest { - - /** - * Run the CtfTmfTimestamp(long) constructor test. - */ - @Test - public void testCtfTmfTimestamp() { - long timestamp = 1L; - DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS"); - Date d = new Date(timestamp / 1000000); - - CtfTmfTimestamp result = new CtfTmfTimestamp(timestamp); - - assertNotNull(result); - assertEquals(df.format(d) + " 000 001", result.toString()); - assertEquals(0, result.getPrecision()); - assertEquals(-9, result.getScale()); - assertEquals(1L, result.getValue()); - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfTraceTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfTraceTest.java deleted file mode 100644 index 795fd6ecd2..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/CtfTmfTraceTest.java +++ /dev/null @@ -1,393 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial generation with CodePro tools - * Alexandre Montplaisir - Clean up, consolidate redundant tests - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.signal.TmfEndSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.TmfEventTypeCollectionHelper; -import org.eclipse.linuxtools.tmf.ctf.core.CtfLocation; -import org.eclipse.linuxtools.tmf.ctf.core.CtfLocationInfo; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfEvent; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTimestamp; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * The class CtfTmfTraceTest contains tests for the class - * {@link CtfTmfTrace}. - * - * @author ematkho - * @version 1.0 - */ -public class CtfTmfTraceTest { - - private static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.KERNEL; - - private CtfTmfTrace fixture; - - /** - * Perform pre-test initialization. - * - * @throws TmfTraceException - * If the test trace is not found - */ - @Before - public void setUp() throws TmfTraceException { - assumeTrue(testTrace.exists()); - fixture = new CtfTmfTrace(); - fixture.initTrace((IResource) null, testTrace.getPath(), CtfTmfEvent.class); - } - - /** - * Perform post-test clean-up. - */ - @After - public void tearDown() { - if (fixture != null) { - fixture.dispose(); - } - } - - /** - * Run the CtfTmfTrace() constructor test. - */ - @Test - public void testCtfTmfTrace() { - try (CtfTmfTrace result = new CtfTmfTrace();) { - assertNotNull(result); - assertEquals(1000, result.getCacheSize()); - assertEquals(0L, result.getNbEvents()); - assertEquals(0L, result.getStreamingInterval()); - assertNull(result.getResource()); - assertNull(result.getType()); - } - } - - /** - * Test the parseEvent() method - */ - @Test - public void testParseEvent() { - ITmfContext ctx = fixture.seekEvent(0); - fixture.getNext(ctx); - CtfTmfEvent event = fixture.parseEvent(ctx); - assertNotNull(event); - } - - /** - * Run the void broadcast(TmfSignal) method test. - */ - @Test - public void testBroadcast() { - TmfSignal signal = new TmfEndSynchSignal(1); - fixture.broadcast(signal); - } - - /** - * Run the void dispose() method test. - */ - @Test - public void testClose() { - try (CtfTmfTrace emptyFixture = new CtfTmfTrace();) { - } - } - - /** - * Run the int getCacheSize() method test. - */ - @Test - public void testGetCacheSize() { - try (CtfTmfTrace emptyFixture = new CtfTmfTrace();) { - int result = emptyFixture.getCacheSize(); - assertEquals(1000, result); - } - } - - /** - * Run the ITmfLocation getCurrentLocation() method test. - */ - @Test - public void testGetCurrentLocation() { - CtfLocation result = (CtfLocation) fixture.getCurrentLocation(); - assertNull(result); - } - - /** - * Test the seekEvent() method with a null location. - */ - @Test - public void testSeekEventLoc_null() { - CtfLocation loc = null; - fixture.seekEvent(loc); - assertNotNull(fixture); - } - - /** - * Test the seekEvent() method with a location from a timestamp. - */ - @Test - public void testSeekEventLoc_timetamp() { - CtfLocation loc = new CtfLocation(new CtfTmfTimestamp(0L)); - fixture.seekEvent(loc); - assertNotNull(fixture); - } - - /** - * Run the ITmfTimestamp getEndTime() method test. - */ - @Test - public void testGetEndTime() { - ITmfTimestamp result = fixture.getEndTime(); - assertNotNull(result); - } - - /** - * Run the String getEnvironment method test. - */ - @Test - public void testGetEnvValue() { - String key = "tracer_name"; - String result = fixture.getTraceProperties().get(key); - assertEquals("\"lttng-modules\"", result); - } - - /** - * Test the {@link CtfTmfTrace#getEventType()} method. - */ - @Test - public void testGetEventType() { - Class result = fixture.getEventType(); - assertNotNull(result); - assertEquals(CtfTmfEvent.class, result); - } - - /** - * Run the Class getContainedEventTypes() method test. - */ - @Test - public void testGetContainedEventTypes() { - Set result = fixture.getContainedEventTypes(); - assertNotNull(result); - assertFalse(result.isEmpty()); - } - - /** - * Run the double getLocationRatio(ITmfLocation) method test. - */ - @Test - public void testGetLocationRatio() { - final CtfLocationInfo location2 = new CtfLocationInfo(1, 0); - CtfLocation location = new CtfLocation(location2); - double result = fixture.getLocationRatio(location); - - assertEquals(Double.NEGATIVE_INFINITY, result, 0.1); - } - - /** - * Run the String getName() method test. - */ - @Test - public void testGetName() { - String result = fixture.getName(); - assertNotNull(result); - } - - /** - * Run the getTraceProperties() method test. - */ - @Test - public void testGetTraceProperties() { - int result = fixture.getTraceProperties().size(); - assertEquals(9, result); - } - - /** - * Run the long getNbEvents() method test. - */ - @Test - public void testGetNbEvents() { - long result = fixture.getNbEvents(); - assertEquals(1L, result); - } - - /** - * Run the CtfTmfEvent getNext(ITmfContext) method test. - */ - @Test - public void testGetNext() { - ITmfContext context = fixture.seekEvent(0); - CtfTmfEvent result = fixture.getNext(context); - assertNotNull(result); - } - - /** - * Run the String getPath() method test. - */ - @Test - public void testGetPath() { - String result = fixture.getPath(); - assertNotNull(result); - } - - /** - * Run the IResource getResource() method test. - */ - @Test - public void testGetResource() { - IResource result = fixture.getResource(); - assertNull(result); - } - - /** - * Run the ITmfTimestamp getStartTime() method test. - */ - @Test - public void testGetStartTime() { - ITmfTimestamp result = fixture.getStartTime(); - assertNotNull(result); - } - - /** - * Run the long getStreamingInterval() method test. - */ - @Test - public void testGetStreamingInterval() { - long result = fixture.getStreamingInterval(); - assertEquals(0L, result); - } - - /** - * Run the TmfTimeRange getTimeRange() method test. - */ - @Test - public void testGetTimeRange() { - TmfTimeRange result = fixture.getTimeRange(); - assertNotNull(result); - } - - /** - * Run the CtfTmfEvent readNextEvent(ITmfContext) method test. - */ - @Test - public void testReadNextEvent() { - ITmfContext context = fixture.seekEvent(0); - CtfTmfEvent result = fixture.getNext(context); - assertNotNull(result); - } - - /** - * Run the ITmfContext seekEvent(double) method test. - */ - @Test - public void testSeekEvent_ratio() { - double ratio = 0.99; - ITmfContext result = fixture.seekEvent(ratio); - assertNotNull(result); - } - - /** - * Run the ITmfContext seekEvent(long) method test. - */ - @Test - public void testSeekEvent_rank() { - long rank = 1L; - ITmfContext result = fixture.seekEvent(rank); - assertNotNull(result); - } - - /** - * Run the ITmfContext seekEvent(ITmfTimestamp) method test. - */ - @Test - public void testSeekEvent_timestamp() { - ITmfTimestamp timestamp = new TmfTimestamp(); - ITmfContext result = fixture.seekEvent(timestamp); - assertNotNull(result); - } - - /** - * Run the ITmfContext seekEvent(ITmfLocation) method test. - */ - @Test - public void testSeekEvent_location() { - final CtfLocationInfo location2 = new CtfLocationInfo(1L, 0L); - CtfLocation ctfLocation = new CtfLocation(location2); - ITmfContext result = fixture.seekEvent(ctfLocation); - assertNotNull(result); - } - - /** - * Run the boolean validate(IProject,String) method test. - */ - @Test - public void testValidate() { - IProject project = null; - IStatus result = fixture.validate(project, testTrace.getPath()); - assertTrue(result.isOK()); - } - - /** - * Run the boolean hasEvent(final String) method test - */ - @Test - public void testEventLookup() { - Set eventTypes = fixture.getContainedEventTypes(); - Set eventNames = TmfEventTypeCollectionHelper.getEventNames(eventTypes); - assertTrue(eventNames.contains("sched_switch")); - assertFalse(eventNames.contains("Sched_switch")); - String[] events = { "sched_switch", "sched_wakeup", "timer_init" }; - assertTrue(eventNames.containsAll(Arrays.asList(events))); - Set copy = new HashSet<>(eventNames); - copy.retainAll(Arrays.asList(events)); - assertFalse(copy.isEmpty()); - String[] names = { "inexistent", "sched_switch", "SomeThing" }; - copy = new HashSet<>(eventNames); - copy.retainAll(Arrays.asList(names)); - assertTrue(!copy.isEmpty()); - assertFalse(eventNames.containsAll(Arrays.asList(names))); - } - - /** - * Run the String getHostId() method test - */ - @Test - public void testCtfHostId() { - String a = fixture.getHostId(); - assertEquals("\"84db105b-b3f4-4821-b662-efc51455106a\"", a); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/EventContextTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/EventContextTest.java deleted file mode 100644 index 0cfdb8f953..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/EventContextTest.java +++ /dev/null @@ -1,241 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assume.assumeTrue; - -import org.eclipse.core.resources.IResource; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfEvent; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTimestamp; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Tests for reading event contexts from a CtfTmfTrace. - * - * @author Alexandre Montplaisir - */ -public class EventContextTest { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /* We use test trace #2, kernel_vm, which has event contexts */ - private static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.KERNEL_VM; - - private CtfTmfTrace fixture; - private long startTime; - private long endTime; - - // ------------------------------------------------------------------------ - // Class methods - // ------------------------------------------------------------------------ - - /** - * Perform pre-class initialization. - * - * @throws TmfTraceException - * If the test trace is not found - */ - @Before - public void setUp() throws TmfTraceException { - assumeTrue(testTrace.exists()); - fixture = new CtfTmfTrace(); - fixture.initTrace((IResource) null, testTrace.getPath(), CtfTmfEvent.class); - fixture.indexTrace(true); - - startTime = fixture.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - endTime = fixture.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - } - - /** - * Perform post-class clean-up. - */ - @After - public void tearDown() { - if (fixture != null) { - fixture.dispose(); - } - } - - // ------------------------------------------------------------------------ - // Test methods - // ------------------------------------------------------------------------ - - /** - * Make sure the trace is the correct one, and its timestamps are read - * correctly. - */ - @Test - public void testTrace() { - assertEquals(1363700740555978750L, startTime); - assertEquals(1363700770550261288L, endTime); - } - - /** - * Test the context of the very first event of the trace. - */ - @Test - public void testContextStart() { - CtfTmfEvent firstEvent = getEventAt(startTime); - long perfPageFault = (Long) firstEvent.getContent().getField("context._perf_page_fault").getValue(); - String procname = (String) firstEvent.getContent().getField("context._procname").getValue(); - long tid = (Long) firstEvent.getContent().getField("context._tid").getValue(); - - assertEquals(613, perfPageFault); - assertEquals("lttng-sessiond", procname); - assertEquals(1230, tid); - } - - /** - * Test the context of the event at 1363700745.559739078. - */ - @Test - public void testContext1() { - long time = startTime + 5000000000L; // 1363700745.559739078 - CtfTmfEvent event = getEventAt(time); - long perfPageFault = (Long) event.getContent().getField("context._perf_page_fault").getValue(); - String procname = (String) event.getContent().getField("context._procname").getValue(); - long tid = (Long) event.getContent().getField("context._tid").getValue(); - - assertEquals(6048, perfPageFault); - assertEquals("swapper/0", procname); - assertEquals(0, tid); - } - - /** - * Test the context of the event at 1363700750.559707062. - */ - @Test - public void testContext2() { - long time = startTime + 2 * 5000000000L; // 1363700750.559707062 - CtfTmfEvent event = getEventAt(time); - long perfPageFault = (Long) event.getContent().getField("context._perf_page_fault").getValue(); - String procname = (String) event.getContent().getField("context._procname").getValue(); - long tid = (Long) event.getContent().getField("context._tid").getValue(); - - assertEquals(13258, perfPageFault); - assertEquals("swapper/0", procname); - assertEquals(0, tid); - } - - /** - * Test the context of the event at 1363700755.555723128, which is roughly - * mid-way through the trace. - */ - @Test - public void testContextMiddle() { - long midTime = startTime + (endTime - startTime) / 2L; // 1363700755.555723128 - CtfTmfEvent midEvent = getEventAt(midTime); - long perfPageFault = (Long) midEvent.getContent().getField("context._perf_page_fault").getValue(); - String procname = (String) midEvent.getContent().getField("context._procname").getValue(); - long tid = (Long) midEvent.getContent().getField("context._tid").getValue(); - - assertEquals(19438, perfPageFault); - assertEquals("swapper/0", procname); - assertEquals(0, tid); - } - - /** - * Test the context of the event at 1363700760.559719724. - */ - @Test - public void testContext3() { - long time = startTime + 4 * 5000000000L; // 1363700760.559719724 - CtfTmfEvent event = getEventAt(time); - long perfPageFault = (Long) event.getContent().getField("context._perf_page_fault").getValue(); - String procname = (String) event.getContent().getField("context._procname").getValue(); - long tid = (Long) event.getContent().getField("context._tid").getValue(); - - assertEquals(21507, perfPageFault); - assertEquals("swapper/0", procname); - assertEquals(0, tid); - } - - /** - * Test the context of the event at 1363700765.559714634. - */ - @Test - public void testContext4() { - long time = startTime + 5 * 5000000000L; // 1363700765.559714634 - CtfTmfEvent event = getEventAt(time); - long perfPageFault = (Long) event.getContent().getField("context._perf_page_fault").getValue(); - String procname = (String) event.getContent().getField("context._procname").getValue(); - long tid = (Long) event.getContent().getField("context._tid").getValue(); - - assertEquals(21507, perfPageFault); - assertEquals("swapper/0", procname); - assertEquals(0, tid); - } - - /** - * Test the context of the last event of the trace. - */ - @Test - public void testContextEnd() { - CtfTmfEvent lastEvent = getEventAt(endTime); - long perfPageFault = (Long) lastEvent.getContent().getField("context._perf_page_fault").getValue(); - String procname = (String) lastEvent.getContent().getField("context._procname").getValue(); - long tid = (Long) lastEvent.getContent().getField("context._tid").getValue(); - - assertEquals(22117, perfPageFault); - assertEquals("lttng-sessiond", procname); - assertEquals(1230, tid); - } - - // ------------------------------------------------------------------------ - // Private stuff - // ------------------------------------------------------------------------ - - private synchronized CtfTmfEvent getEventAt(long timestamp) { - EventContextTestRequest req = new EventContextTestRequest(timestamp); - fixture.sendRequest(req); - try { - req.waitForCompletion(); - } catch (InterruptedException e) { - return null; - } - return req.getEvent(); - } - - private class EventContextTestRequest extends TmfEventRequest { - - private CtfTmfEvent retEvent = null; - - public EventContextTestRequest(long timestamp) { - super(CtfTmfEvent.class, - new TmfTimeRange(new CtfTmfTimestamp(timestamp), TmfTimestamp.BIG_CRUNCH), - 0, 1, ExecutionType.FOREGROUND); - } - - @Override - public void handleData(ITmfEvent event) { - retEvent = (CtfTmfEvent) event; - } - - public CtfTmfEvent getEvent() { - return retEvent; - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/FunkyTraceTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/FunkyTraceTest.java deleted file mode 100644 index 9303d64451..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/FunkyTraceTest.java +++ /dev/null @@ -1,212 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assume.assumeTrue; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.ctf.core.CtfEnumPair; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfEvent; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; -import org.junit.rules.Timeout; - -/** - * More advanced CTF tests using "funky_trace", a trace generated with the - * Babeltrace CTF writer API, which has lots of fun things like different - * integer/float sizes and non-standard struct alignments. - * - * @author Alexandre Montplaisir - */ -public class FunkyTraceTest { - - /** Time-out tests after 20 seconds */ - @Rule - public TestRule globalTimeout= new Timeout(20000); - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.FUNKY_TRACE; - private static final double DELTA = 0.0000001; - - private CtfTmfTrace fTrace; - - // ------------------------------------------------------------------------ - // Setup - // ------------------------------------------------------------------------ - - /** - * Test setup - */ - @Before - public void setup() { - assumeTrue(testTrace.exists()); - fTrace = testTrace.getTrace(); - fTrace.indexTrace(true); - } - - /** - * Clean-up - */ - @After - public void tearDown() { - if (fTrace != null) { - fTrace.dispose(); - } - } - - // ------------------------------------------------------------------------ - // Test methods - // ------------------------------------------------------------------------ - - /** - * Verify the contents of the first event - */ - @Test - public void testFirstEvent() { - CtfTmfEvent event = getEvent(0); - assertEquals("Simple Event", event.getType().getName()); - assertEquals(1234567, event.getTimestamp().getValue()); - assertEquals(42, ((Long) event.getContent().getField("integer_field").getValue()).intValue()); - assertEquals(3.1415, ((Double) event.getContent().getField("float_field").getValue()).doubleValue(), DELTA); - } - - /** - * Verify the contents of the second event (the first "spammy event") - */ - @Test - public void testSecondEvent() { - CtfTmfEvent event = getEvent(1); - assertEquals("Spammy_Event", event.getType().getName()); - assertEquals(1234568, event.getTimestamp().getValue()); - assertEquals(0, ((Long) event.getContent().getField("field_1").getValue()).intValue()); - assertEquals("This is a test", event.getContent().getField("a_string").getValue()); - } - - /** - * Verify the contents of the last "spammy event" - */ - @Test - public void testSecondToLastEvent() { - CtfTmfEvent event = getEvent(100000); - assertEquals("Spammy_Event", event.getType().getName()); - assertEquals(1334567, event.getTimestamp().getValue()); - assertEquals(99999, ((Long) event.getContent().getField("field_1").getValue()).intValue()); - assertEquals("This is a test", event.getContent().getField("a_string").getValue()); - } - - /** - * Verify the contents of the last, complex event - */ - @Test - public void testLastEvent() { - /* - * Last event as seen in Babeltrace: - * [19:00:00.001334568] (+0.000000001) Complex Test Event: { }, { - * uint_35 = 0xDDF00D, - * int_16 = -12345, - * complex_structure = { - * variant_selector = ( INT16_TYPE : container = 1 ), - * a_string = "Test string", - * variant_value = { INT16_TYPE = -200 }, - * inner_structure = { - * seq_len = 0xA, - * a_sequence = [ [0] = 4, [1] = 3, [2] = 2, [3] = 1, [4] = 0, [5] = -1, [6] = -2, [7] = -3, [8] = -4, [9] = -5 ] - * } - * } - * } - */ - - CtfTmfEvent event = getEvent(100001); - assertEquals("Complex Test Event", event.getType().getName()); - assertEquals(1334568, event.getTimestamp().getValue()); - assertEquals(0xddf00d, ((Long) event.getContent().getField("uint_35").getValue()).intValue()); - assertEquals(-12345, ((Long) event.getContent().getField("int_16").getValue()).intValue()); - - ITmfEventField[] complexStruct = - (ITmfEventField[]) event.getContent().getField("complex_structure").getValue(); - - assertEquals("variant_selector", complexStruct[0].getName()); - CtfEnumPair variant1 = (CtfEnumPair) complexStruct[0].getValue(); - assertEquals("INT16_TYPE", variant1.getStringValue()); - assertEquals(Long.valueOf(1), variant1.getLongValue()); - - assertEquals("a_string", complexStruct[1].getName()); - assertEquals("Test string", complexStruct[1].getValue()); - - assertEquals("variant_value", complexStruct[2].getName()); - ITmfEventField variantField = (ITmfEventField) complexStruct[2].getValue(); - assertEquals("INT16_TYPE", variantField.getName()); - assertEquals(Long.valueOf(-200), variantField.getValue()); - - ITmfEventField[] innerStruct = (ITmfEventField[]) complexStruct[3].getValue(); - - assertEquals("seq_len", innerStruct[0].getName()); - assertEquals(Long.valueOf(10), innerStruct[0].getValue()); - - assertEquals("a_sequence", innerStruct[1].getName()); - long[] seqValues = (long[]) innerStruct[1].getValue(); - long[] expectedValues = { 4, 3, 2, 1, 0, -1, -2, -3, -4, -5 }; - assertArrayEquals(expectedValues, seqValues); - } - - // ------------------------------------------------------------------------ - // Private stuff - // ------------------------------------------------------------------------ - - private synchronized CtfTmfEvent getEvent(long index) { - TestEventRequest req = new TestEventRequest(index); - fTrace.sendRequest(req); - try { - req.waitForCompletion(); - } catch (InterruptedException e) { - return null; - } - return req.getEvent(); - } - - private class TestEventRequest extends TmfEventRequest { - - private CtfTmfEvent fRetEvent = null; - - public TestEventRequest(long index) { - super(CtfTmfEvent.class, - TmfTimeRange.ETERNITY, - index, - 1, - ExecutionType.FOREGROUND); - } - - @Override - public void handleData(ITmfEvent event) { - fRetEvent = (CtfTmfEvent) event; - } - - public CtfTmfEvent getEvent() { - return fRetEvent; - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/headless/Benchmark.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/headless/Benchmark.java deleted file mode 100644 index 8782a70528..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/headless/Benchmark.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests.headless; - -import java.util.Vector; - -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfContext; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfEvent; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; - -/** - * Test and benchmark reading a CTF LTTng kernel trace. - * - * @author Matthew Khouzam - */ -public class Benchmark { - - /** - * Run the benchmark. - * - * @param args The command-line arguments - */ - public static void main(final String[] args) { - final String TRACE_PATH = "testfiles/kernel"; - final int NUM_LOOPS = 100; - - // Change this to enable text output - final boolean USE_TEXT = true; - - // Work variables - long nbEvent = 0L; - final Vector benchs = new Vector<>(); - long start, stop; - for (int loops = 0; loops < NUM_LOOPS; loops++) { - nbEvent = 0L; - try (CtfTmfTrace trace = new CtfTmfTrace();) { - try { - trace.initTrace(null, TRACE_PATH, CtfTmfEvent.class); - } catch (final TmfTraceException e) { - loops = NUM_LOOPS + 1; - break; - } - - start = System.nanoTime(); - if (nbEvent != -1) { - final CtfTmfContext traceReader = (CtfTmfContext) trace.seekEvent(0); - - start = System.nanoTime(); - CtfTmfEvent current = traceReader.getCurrentEvent(); - while (current != null) { - nbEvent++; - if (USE_TEXT) { - - System.out.println("Event " + nbEvent + " Time " - + current.getTimestamp().toString() + " type " + current.getType().getName() - + " on CPU " + current.getSource() + " " + current.getContent().toString()); - } - // advance the trace to the next event. - boolean hasMore = traceReader.advance(); - if (hasMore) { - // you can know the trace has more events. - } - current = traceReader.getCurrentEvent(); - } - } - stop = System.nanoTime(); - System.out.print('.'); - final double time = (stop - start) / (double) nbEvent; - benchs.add(time); - } // trace.close() - } - System.out.println(""); - double avg = 0; - for (final double val : benchs) { - avg += val; - } - avg /= benchs.size(); - System.out.println("Time to read = " + avg + " events/ns"); - for (final Double val : benchs) { - System.out.print(val); - System.out.print(", "); - } - - } - -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/headless/RequestBenchmark.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/headless/RequestBenchmark.java deleted file mode 100644 index 7f063eb876..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/headless/RequestBenchmark.java +++ /dev/null @@ -1,130 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * William Bourque - Initial API and implementation - * Matthew Khouzam - Update to CtfTmf trace and events - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests.headless; - -import java.util.Vector; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfEvent; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; - -/** - * Benchmark the event request subsystem of TMF. - */ -public class RequestBenchmark extends TmfEventRequest { - - private RequestBenchmark(final Class dataType, - final TmfTimeRange range, final int nbRequested) { - super(dataType, range, 0, nbRequested, ExecutionType.FOREGROUND); - } - - // Path of the trace - private static final String TRACE_PATH = "../org.eclipse.linuxtools.ctf.core.tests/traces/kernel"; - - // Change this to run several time over the same trace - private static final int NB_OF_PASS = 100; - - // Work variables - private static int nbEvent = 0; - private static TmfExperiment fExperiment = null; - private static Vector benchs = new Vector<>(); - - /** - * Run the benchmark - * - * @param args - * The command-line arguments - */ - public static void main(final String[] args) { - - try { - /* Our experiment will contains ONE trace */ - final ITmfTrace[] traces = new ITmfTrace[1]; - traces[0] = new CtfTmfTrace(); - traces[0].initTrace(null, TRACE_PATH, CtfTmfEvent.class); - /* Create our new experiment */ - fExperiment = new TmfExperiment(CtfTmfEvent.class, "Headless", traces); - - /* - * We will issue a request for each "pass". TMF will then process - * them synchronously. - */ - RequestBenchmark request = null; - for (int x = 0; x < NB_OF_PASS; x++) { - request = new RequestBenchmark(CtfTmfEvent.class, - TmfTimeRange.ETERNITY, Integer.MAX_VALUE); - fExperiment.sendRequest(request); - } - prev = System.nanoTime(); - } catch (final NullPointerException e) { - /* - * Silently dismiss Null pointer exception The only way to "finish" - * the threads in TMF is by crashing them with null. - */ - } catch (final Exception e) { - e.printStackTrace(); - } - - } - - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - nbEvent++; - - } - - static long prev; - static long done = 0; - @Override - public void handleCompleted() { - final long next = System.nanoTime(); - double val = next - prev; - final int nbEvent2 = nbEvent; - val /= nbEvent2; - - nbEvent = 0; - prev = next; - benchs.add(val); - if (benchs.size() == NB_OF_PASS) { - try { - System.out.println("Nb events : " + nbEvent2); - - for (final double value : benchs) { - System.out.print(value + ", "); - } - fExperiment.sendRequest(null); - - } catch (final Exception e) { - } - } - } - - @Override - public void handleSuccess() { - } - - @Override - public void handleFailure() { - } - - @Override - public void handleCancel() { - } - -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/request/AllTests.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/request/AllTests.java deleted file mode 100644 index 6fe21d2525..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/request/AllTests.java +++ /dev/null @@ -1,25 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests.request; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TmfSchedulerTest.class -}) -public class AllTests {} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/request/TmfSchedulerBenchmark.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/request/TmfSchedulerBenchmark.java deleted file mode 100644 index cffdf1fe49..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/request/TmfSchedulerBenchmark.java +++ /dev/null @@ -1,360 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Simon Delisle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests.request; - -import java.io.PrintWriter; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; - -/** - * Benchmark for the request scheduler - * - * The benchmark has three tests. The first one is the latency (time between the - * creation of the request and the beginning of its execution). The second one - * is the average waiting time for a request. The last one is the total - * completion time. - */ -public class TmfSchedulerBenchmark { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - private static final int NUM_LOOPS = 10; - private static final int NANOSECONDS_IN_MILLISECONDS = 1000000; - private static final int NANOSECONDS_IN_SECONDS = 1000000000; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private static CtfTmfTrace trace = CtfTmfTestTrace.KERNEL.getTrace(); - private static ForegroundRequest lastForegroundRequest = null; - private static BackgroundRequest lastBackgroundRequest = null; - - private static PrintWriter pw = new PrintWriter(System.out, true); - - /** - * Start the benchmark - * - * @param args - * The command-line arguments - */ - public static void main(final String[] args) { - trace.indexTrace(true); - pw.println("---------- Benchmark started ----------"); - latencyBenchmark(); - averageWaitingTime(); - completedTime(); - benchmarkResults(); - trace.dispose(); - } - - private static void latencyBenchmark() { - long averageLatency = 0; - - pw.println("----- Latency -----"); - for (int i = 0; i < NUM_LOOPS; i++) { - try { - ForegroundRequest foreground1 = new ForegroundRequest(TmfTimeRange.ETERNITY); - trace.sendRequest(foreground1); - foreground1.waitForCompletion(); - averageLatency += foreground1.getLatency(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - pw.println((averageLatency / NUM_LOOPS) / NANOSECONDS_IN_MILLISECONDS + " ms"); - } - - private static void averageWaitingTime() { - long averageWaitingBackground = 0; - long averageWaitingForeground1 = 0; - long averageWaitingForeground2 = 0; - - pw.println("----- Average waiting time with 3 requests -----"); - for (int i = 0; i < NUM_LOOPS; i++) { - ForegroundRequest foreground1 = new ForegroundRequest(TmfTimeRange.ETERNITY); - ForegroundRequest foreground2 = new ForegroundRequest(TmfTimeRange.ETERNITY); - BackgroundRequest background1 = new BackgroundRequest(TmfTimeRange.ETERNITY); - trace.sendRequest(background1); - trace.sendRequest(foreground1); - trace.sendRequest(foreground2); - try { - foreground1.waitForCompletion(); - foreground2.waitForCompletion(); - background1.waitForCompletion(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - averageWaitingBackground += background1.getAverageWaitingTime(); - averageWaitingForeground1 += foreground1.getAverageWaitingTime(); - averageWaitingForeground2 += foreground2.getAverageWaitingTime(); - } - pw.print("-- Background : "); - pw.println((averageWaitingBackground / NUM_LOOPS) / NANOSECONDS_IN_MILLISECONDS + " ms"); - - pw.print("-- First foreground : "); - pw.println((averageWaitingForeground1 / NUM_LOOPS) / NANOSECONDS_IN_MILLISECONDS + " ms"); - - pw.print("-- Second foreground : "); - pw.println((averageWaitingForeground2 / NUM_LOOPS) / NANOSECONDS_IN_MILLISECONDS + " ms"); - } - - private static void completedTime() { - long averageCompletedTime1 = 0; - long averageCompletedTime2 = 0; - long averageCompletedTime3 = 0; - long averageCompletedTime4 = 0; - long averageCompletedTime5 = 0; - long averageCompletedTime6 = 0; - - pw.println("----- Time to complete request -----"); - for (int i = 0; i < NUM_LOOPS; i++) { - try { - ForegroundRequest foreground1 = new ForegroundRequest(TmfTimeRange.ETERNITY); - trace.sendRequest(foreground1); - foreground1.waitForCompletion(); - averageCompletedTime1 += foreground1.getCompletedTime(); - - ForegroundRequest foreground2 = new ForegroundRequest(TmfTimeRange.ETERNITY); - ForegroundRequest foreground3 = new ForegroundRequest(TmfTimeRange.ETERNITY); - trace.sendRequest(foreground2); - trace.sendRequest(foreground3); - foreground2.waitForCompletion(); - foreground3.waitForCompletion(); - averageCompletedTime2 += (foreground2.getCompletedTime() + foreground3.getCompletedTime()); - - ForegroundRequest foreground4 = new ForegroundRequest(TmfTimeRange.ETERNITY); - BackgroundRequest background1 = new BackgroundRequest(TmfTimeRange.ETERNITY); - trace.sendRequest(foreground4); - trace.sendRequest(background1); - foreground4.waitForCompletion(); - background1.waitForCompletion(); - averageCompletedTime3 += (foreground4.getCompletedTime() + background1.getCompletedTime()); - - ForegroundRequest foreground5 = new ForegroundRequest(TmfTimeRange.ETERNITY); - ForegroundRequest foreground6 = new ForegroundRequest(TmfTimeRange.ETERNITY); - BackgroundRequest background2 = new BackgroundRequest(TmfTimeRange.ETERNITY); - trace.sendRequest(foreground5); - trace.sendRequest(foreground6); - trace.sendRequest(background2); - foreground5.waitForCompletion(); - foreground6.waitForCompletion(); - background2.waitForCompletion(); - averageCompletedTime4 += (foreground5.getCompletedTime() + foreground6.getCompletedTime() + background2.getCompletedTime()); - - ForegroundRequest foreground7 = new ForegroundRequest(TmfTimeRange.ETERNITY); - ForegroundRequest foreground8 = new ForegroundRequest(TmfTimeRange.ETERNITY); - ForegroundRequest foreground9 = new ForegroundRequest(TmfTimeRange.ETERNITY); - BackgroundRequest background3 = new BackgroundRequest(TmfTimeRange.ETERNITY); - trace.sendRequest(foreground7); - trace.sendRequest(foreground8); - trace.sendRequest(foreground9); - trace.sendRequest(background3); - foreground7.waitForCompletion(); - foreground8.waitForCompletion(); - foreground9.waitForCompletion(); - background3.waitForCompletion(); - averageCompletedTime5 += (foreground7.getCompletedTime() + foreground8.getCompletedTime() + foreground9.getCompletedTime() + background3.getCompletedTime()); - - ForegroundRequest foreground10 = new ForegroundRequest(TmfTimeRange.ETERNITY); - ForegroundRequest foreground11 = new ForegroundRequest(TmfTimeRange.ETERNITY); - ForegroundRequest foreground12 = new ForegroundRequest(TmfTimeRange.ETERNITY); - ForegroundRequest foreground13 = new ForegroundRequest(TmfTimeRange.ETERNITY); - BackgroundRequest background4 = new BackgroundRequest(TmfTimeRange.ETERNITY); - trace.sendRequest(foreground10); - trace.sendRequest(foreground11); - trace.sendRequest(foreground12); - trace.sendRequest(foreground13); - trace.sendRequest(background4); - foreground10.waitForCompletion(); - foreground11.waitForCompletion(); - foreground12.waitForCompletion(); - foreground13.waitForCompletion(); - background4.waitForCompletion(); - averageCompletedTime6 += (foreground10.getCompletedTime() + foreground11.getCompletedTime() + foreground12.getCompletedTime() + foreground13.getCompletedTime() + background4.getCompletedTime()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - pw.print("-- Time to complete one request : "); - pw.println((averageCompletedTime1 / NUM_LOOPS) / NANOSECONDS_IN_SECONDS + " s"); - - pw.print("-- Time to complete 2 requests (2 foreground) : "); - pw.println((averageCompletedTime2 / NUM_LOOPS) / NANOSECONDS_IN_SECONDS + " s"); - - pw.print("-- Time to complete 2 requests (1 foreground, 1 background) : "); - pw.println((averageCompletedTime3 / NUM_LOOPS) / NANOSECONDS_IN_SECONDS + " s"); - - pw.print("-- Time to complete 3 requests (2 foreground, 1 background) : "); - pw.println((averageCompletedTime4 / NUM_LOOPS) / NANOSECONDS_IN_SECONDS + " s"); - - pw.print("-- Time to complete 4 requests (3 foreground, 1 background) : "); - pw.println((averageCompletedTime5 / NUM_LOOPS) / NANOSECONDS_IN_SECONDS + " s"); - - pw.print("-- Time to complete 5 requests (4 foreground, 1 background) : "); - pw.println((averageCompletedTime6 / NUM_LOOPS) / NANOSECONDS_IN_SECONDS + " s"); - } - - /** - * The benchmark results - */ - public static void benchmarkResults() { - pw.println("---------- Benchmark completed ----------"); - } - - // ------------------------------------------------------------------------ - // Helper methods - // ------------------------------------------------------------------------ - - private static class BackgroundRequest extends TmfEventRequest { - private long startTime; - private long endTimeLatency = -1; - private long completedTime = 0; - private long waitingTimeStart = 0; - private long waitingTimeEnd = 0; - private long waitingTime = 0; - private int waitingCounter = 0; - private boolean isWaiting = false; - - BackgroundRequest(TmfTimeRange timeRange) { - super(trace.getEventType(), - timeRange, - 0, - ITmfEventRequest.ALL_DATA, - ExecutionType.BACKGROUND); - startTime = System.nanoTime(); - } - - @Override - public void handleData(final ITmfEvent event) { - if (endTimeLatency == -1) { - endTimeLatency = System.nanoTime(); - } - super.handleData(event); - if (lastForegroundRequest == null && lastBackgroundRequest == null) { - lastBackgroundRequest = this; - } - if (isWaiting) { - waitingTimeEnd = System.nanoTime(); - waitingTime += waitingTimeEnd - waitingTimeStart; - ++waitingCounter; - isWaiting = false; - } - if (lastForegroundRequest != null) { - lastForegroundRequest.waitingTimeStart = System.nanoTime(); - lastForegroundRequest.isWaiting = true; - lastForegroundRequest = null; - lastBackgroundRequest = this; - } - if (lastBackgroundRequest != this) { - lastBackgroundRequest.waitingTimeStart = System.nanoTime(); - lastBackgroundRequest.isWaiting = true; - lastBackgroundRequest = this; - } - } - - @Override - public void handleCompleted() { - completedTime = System.nanoTime(); - super.handleCompleted(); - } - - public long getCompletedTime() { - return completedTime - startTime; - } - - public long getAverageWaitingTime() { - if (waitingCounter == 0) { - return 0; - } - return waitingTime / waitingCounter; - } - } - - private static class ForegroundRequest extends TmfEventRequest { - private long startTime = 0; - private long endTimeLatency = -1; - private long completedTime = 0; - private long waitingTimeStart = 0; - private long waitingTimeEnd = 0; - private long waitingTime = 0; - private int waitingCounter = 0; - private boolean isWaiting = false; - - ForegroundRequest(TmfTimeRange timeRange) { - super(trace.getEventType(), - timeRange, - 0, - ITmfEventRequest.ALL_DATA, - ExecutionType.FOREGROUND); - startTime = System.nanoTime(); - } - - @Override - public void handleData(final ITmfEvent event) { - if (endTimeLatency == -1) { - endTimeLatency = System.nanoTime(); - } - super.handleData(event); - if (lastBackgroundRequest == null && lastForegroundRequest == null) { - lastForegroundRequest = this; - } - if (isWaiting) { - waitingTimeEnd = System.nanoTime(); - waitingTime += waitingTimeEnd - waitingTimeStart; - ++waitingCounter; - isWaiting = false; - } - if (lastBackgroundRequest != null) { - lastBackgroundRequest.waitingTimeStart = System.nanoTime(); - lastBackgroundRequest.isWaiting = true; - lastBackgroundRequest = null; - lastForegroundRequest = this; - } - if (lastForegroundRequest != this) { - lastForegroundRequest.waitingTimeStart = System.nanoTime(); - lastForegroundRequest.isWaiting = true; - lastForegroundRequest = this; - } - } - - @Override - public void handleCompleted() { - completedTime = System.nanoTime(); - super.handleCompleted(); - } - - public long getLatency() { - return endTimeLatency - startTime; - } - - public long getCompletedTime() { - return completedTime - startTime; - } - - public long getAverageWaitingTime() { - if (waitingCounter == 0) { - return 0; - } - return waitingTime / waitingCounter; - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/request/TmfSchedulerTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/request/TmfSchedulerTest.java deleted file mode 100644 index a86a62ee8a..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/request/TmfSchedulerTest.java +++ /dev/null @@ -1,451 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Simon Delisle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests.request; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeTrue; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; - -import org.eclipse.core.resources.IResource; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfEvent; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; -import org.junit.rules.Timeout; - -/** - * Test suite for the scheduler. - */ -public class TmfSchedulerTest { - - /** Time-out tests after 60 seconds */ - @Rule - public TestRule globalTimeout= new Timeout(60000); - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - private static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.KERNEL; - private static final int NB_EVENTS_TRACE = 695319; - private static final int NB_EVENTS_TIME_RANGE = 155133; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private CtfTmfTrace fixture; - - private long fStartTime; - private long fEndTime; - private TmfTimeRange fForegroundTimeRange; - - private final List fOrderList = new ArrayList<>(); - private int fForegroundId = 0; - private int fBackgroundId = 0; - - /** - * Perform pre-test initialization. - * - * @throws TmfTraceException - * If the test trace is not found - */ - @Before - public void setUp() throws TmfTraceException { - assumeTrue(testTrace.exists()); - fixture = new CtfTmfTrace(); - fixture.initTrace((IResource) null, testTrace.getPath(), CtfTmfEvent.class); - fixture.indexTrace(true); - fStartTime = fixture.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - fEndTime = fixture.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - - long foregroundStartTime = fStartTime + ((fEndTime - fStartTime) / 4); - long foregroundEndTime = fStartTime + ((fEndTime - fStartTime) / 2); - fForegroundTimeRange = new TmfTimeRange(new TmfTimestamp(foregroundStartTime, ITmfTimestamp.NANOSECOND_SCALE, 0), new TmfTimestamp(foregroundEndTime, ITmfTimestamp.NANOSECOND_SCALE, 0)); - } - - /** - * Perform post-test clean-up. - */ - @After - public void tearDown() { - if (fixture != null) { - fixture.dispose(); - } - } - - // ------------------------------------------------------------------------ - // Tests cases - // ------------------------------------------------------------------------ - - /** - * Test one background request - */ - @Test - public void backgroundRequest() { - BackgroundRequest background = new BackgroundRequest(TmfTimeRange.ETERNITY); - fixture.sendRequest(background); - try { - background.waitForCompletion(); - } catch (InterruptedException e) { - fail(); - } - assertEquals(NB_EVENTS_TRACE, background.getNbEvents()); - } - - /** - * Test one foreground request - */ - @Test - public void foregroundRequest() { - ForegroundRequest foreground = new ForegroundRequest(TmfTimeRange.ETERNITY); - fixture.sendRequest(foreground); - try { - foreground.waitForCompletion(); - } catch (InterruptedException e) { - fail(); - } - assertEquals(NB_EVENTS_TRACE, foreground.getNbEvents()); - } - - /** - * Test one foreground and one background request for the entire trace at - * the same time - */ - @Test - public void TestMultiRequest1() { - BackgroundRequest background = new BackgroundRequest(TmfTimeRange.ETERNITY); - ForegroundRequest foreground = new ForegroundRequest(TmfTimeRange.ETERNITY); - - fixture.sendRequest(background); - fixture.sendRequest(foreground); - try { - background.waitForCompletion(); - foreground.waitForCompletion(); - } catch (InterruptedException e) { - fail(); - } - - assertEquals(NB_EVENTS_TRACE, background.getNbEvents()); - assertEquals(NB_EVENTS_TRACE, foreground.getNbEvents()); - } - - /** - * Test one background request for the entire trace and one foreground - * request for smaller time range - */ - @Test - public void TestMultiRequest2() { - BackgroundRequest background2 = new BackgroundRequest(TmfTimeRange.ETERNITY); - ForegroundRequest foreground2 = new ForegroundRequest(fForegroundTimeRange); - - fixture.sendRequest(background2); - fixture.sendRequest(foreground2); - try { - background2.waitForCompletion(); - foreground2.waitForCompletion(); - } catch (InterruptedException e) { - fail(); - } - - assertEquals(NB_EVENTS_TRACE, background2.getNbEvents()); - assertEquals(NB_EVENTS_TIME_RANGE, foreground2.getNbEvents()); - } - - /** - * Test two foreground request, one to select a time range and one to select - * an event in this time range - */ - @Test - public void TestMultiRequest3() { - ForegroundRequest foreground3 = new ForegroundRequest(TmfTimeRange.ETERNITY); - fixture.sendRequest(foreground3); - - TmfTimeSynchSignal signal3 = new TmfTimeSynchSignal(this, new TmfTimestamp(fForegroundTimeRange.getStartTime())); - fixture.broadcast(signal3); - - try { - foreground3.waitForCompletion(); - } catch (InterruptedException e) { - fail(); - } - - assertEquals(NB_EVENTS_TRACE, foreground3.getNbEvents()); - } - - /** - * Test two foreground request, one to select a time range and one to select - * an event before this time range - */ - @Test - public void TestMultiRequest4() { - ForegroundRequest foreground4 = new ForegroundRequest(fForegroundTimeRange); - fixture.sendRequest(foreground4); - TmfTimeSynchSignal signal4 = new TmfTimeSynchSignal(this, new TmfTimestamp(fStartTime + ((fEndTime - fStartTime) / 8))); - fixture.broadcast(signal4); - - try { - foreground4.waitForCompletion(); - } catch (InterruptedException e) { - fail(); - } - - assertEquals(NB_EVENTS_TIME_RANGE, foreground4.getNbEvents()); - } - - /** - * Test two foreground request, one to select a time range and one to select - * an event after this time range - */ - @Test - public void TestMultiRequest5() { - ForegroundRequest foreground5 = new ForegroundRequest(fForegroundTimeRange); - fixture.sendRequest(foreground5); - TmfTimeSynchSignal signal5 = new TmfTimeSynchSignal(this, new TmfTimestamp(fEndTime - ((fEndTime - fStartTime) / 4))); - fixture.broadcast(signal5); - - try { - foreground5.waitForCompletion(); - } catch (InterruptedException e) { - fail(); - } - - assertEquals(NB_EVENTS_TIME_RANGE, foreground5.getNbEvents()); - } - - /** - * Test one background and one foreground request for the entire trace and - * one foreground request to select an event - */ - @Test - public void TestMultiRequest6() { - BackgroundRequest background6 = new BackgroundRequest(TmfTimeRange.ETERNITY); - ForegroundRequest foreground6 = new ForegroundRequest(TmfTimeRange.ETERNITY); - - fixture.sendRequest(background6); - fixture.sendRequest(foreground6); - - TmfTimeSynchSignal signal6 = new TmfTimeSynchSignal(this, new TmfTimestamp(fStartTime + ((fEndTime - fStartTime) / 8))); - fixture.broadcast(signal6); - - try { - background6.waitForCompletion(); - foreground6.waitForCompletion(); - } catch (InterruptedException e) { - fail(); - } - - assertEquals(NB_EVENTS_TRACE, background6.getNbEvents()); - assertEquals(NB_EVENTS_TRACE, foreground6.getNbEvents()); - } - - /** - * Four request, two foreground and two background - */ - @Test - public void TestMultiRequest7() { - ForegroundRequest foreground7 = new ForegroundRequest(TmfTimeRange.ETERNITY); - ForegroundRequest foreground8 = new ForegroundRequest(fForegroundTimeRange); - BackgroundRequest background7 = new BackgroundRequest(TmfTimeRange.ETERNITY); - BackgroundRequest background8 = new BackgroundRequest(TmfTimeRange.ETERNITY); - fixture.sendRequest(foreground7); - fixture.sendRequest(foreground8); - fixture.sendRequest(background7); - fixture.sendRequest(background8); - try { - foreground7.waitForCompletion(); - foreground8.waitForCompletion(); - background7.waitForCompletion(); - background8.waitForCompletion(); - } catch (InterruptedException e) { - fail(); - } - assertEquals(NB_EVENTS_TRACE, foreground7.getNbEvents()); - assertEquals(NB_EVENTS_TIME_RANGE, foreground8.getNbEvents()); - assertEquals(NB_EVENTS_TRACE, background7.getNbEvents()); - assertEquals(NB_EVENTS_TRACE, background8.getNbEvents()); - } - - /** - * One long foreground request and one short foreground request, the short - * one should finish first - */ - @Test - public void preemptedForegroundRequest() { - ForegroundRequest foreground9 = new ForegroundRequest(TmfTimeRange.ETERNITY); - TmfTimeRange shortTimeRange = new TmfTimeRange(new TmfTimestamp(fStartTime, ITmfTimestamp.NANOSECOND_SCALE, 0), new TmfTimestamp(fStartTime + ((fEndTime - fStartTime) / 16), ITmfTimestamp.NANOSECOND_SCALE, 0)); - ForegroundRequest shortForeground = new ForegroundRequest(shortTimeRange); - fixture.sendRequest(foreground9); - try { - foreground9.waitForStart(); - } catch (InterruptedException e) { - fail(); - } - fixture.sendRequest(shortForeground); - try { - shortForeground.waitForCompletion(); - } catch (InterruptedException e) { - fail(); - } - assertFalse(foreground9.isCompleted()); - } - - /** - * One long background request and one short foreground request, the - * foreground request should finish first - */ - @Test - public void preemptedBackgroundRequest() { - BackgroundRequest background9 = new BackgroundRequest(TmfTimeRange.ETERNITY); - ForegroundRequest foreground10 = new ForegroundRequest(fForegroundTimeRange); - fixture.sendRequest(background9); - fixture.sendRequest(foreground10); - try { - foreground10.waitForCompletion(); - } catch (InterruptedException e) { - fail(); - } - assertTrue(foreground10.isCompleted()); - assertFalse(background9.isCompleted()); - } - - /** - * Test if the scheduler is working as expected - */ - @Ignore - @Test - public void executionOrder() { - List expectedOrder = new LinkedList<>(); - expectedOrder.add("FOREGROUND1"); - expectedOrder.add("FOREGROUND2"); - expectedOrder.add("FOREGROUND3"); - expectedOrder.add("FOREGROUND4"); - expectedOrder.add("BACKGROUND1"); - expectedOrder.add("FOREGROUND1"); - expectedOrder.add("FOREGROUND2"); - expectedOrder.add("FOREGROUND3"); - expectedOrder.add("FOREGROUND4"); - expectedOrder.add("BACKGROUND2"); - - fOrderList.clear(); - fForegroundId = 0; - fBackgroundId = 0; - - BackgroundRequest background1 = new BackgroundRequest(TmfTimeRange.ETERNITY); - BackgroundRequest background2 = new BackgroundRequest(TmfTimeRange.ETERNITY); - - ForegroundRequest foreground1 = new ForegroundRequest(TmfTimeRange.ETERNITY); - ForegroundRequest foreground2 = new ForegroundRequest(TmfTimeRange.ETERNITY); - ForegroundRequest foreground3 = new ForegroundRequest(TmfTimeRange.ETERNITY); - ForegroundRequest foreground4 = new ForegroundRequest(TmfTimeRange.ETERNITY); - - fixture.sendRequest(foreground1); - fixture.sendRequest(foreground2); - fixture.sendRequest(foreground3); - fixture.sendRequest(foreground4); - fixture.sendRequest(background1); - fixture.sendRequest(background2); - try { - foreground1.waitForCompletion(); - foreground2.waitForCompletion(); - foreground3.waitForCompletion(); - foreground4.waitForCompletion(); - background1.waitForCompletion(); - background2.waitForCompletion(); - } catch (InterruptedException e) { - fail(); - } - assertEquals(expectedOrder, fOrderList.subList(0, expectedOrder.size())); - } - - // ------------------------------------------------------------------------ - // Helper methods - // ------------------------------------------------------------------------ - - private class BackgroundRequest extends TmfEventRequest { - private int nbEvents = 0; - private String backgroundName; - - BackgroundRequest(TmfTimeRange timeRange) { - super(fixture.getEventType(), - timeRange, - 0, - ITmfEventRequest.ALL_DATA, - ExecutionType.BACKGROUND); - backgroundName = getExecType().toString() + ++fBackgroundId; - } - - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - synchronized (fOrderList) { - if (fOrderList.isEmpty() || !fOrderList.get(fOrderList.size() - 1).equals(backgroundName)) { - fOrderList.add(backgroundName); - } - } - ++nbEvents; - } - - public int getNbEvents() { - return nbEvents; - } - } - - private class ForegroundRequest extends TmfEventRequest { - private int nbEvents = 0; - private String foregroundName; - - ForegroundRequest(TmfTimeRange timeRange) { - super(fixture.getEventType(), - timeRange, - 0, - ITmfEventRequest.ALL_DATA, - ExecutionType.FOREGROUND); - foregroundName = getExecType().toString() + ++fForegroundId; - } - - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - synchronized (fOrderList) { - if (fOrderList.isEmpty() || !fOrderList.get(fOrderList.size() - 1).equals(foregroundName)) { - fOrderList.add(foregroundName); - } - } - ++nbEvents; - } - - public int getNbEvents() { - return nbEvents; - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/statistics/AllTests.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/statistics/AllTests.java deleted file mode 100644 index 11721ed7dc..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/statistics/AllTests.java +++ /dev/null @@ -1,26 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests.statistics; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TmfEventsStatisticsTest.class, - TmfStateStatisticsTest.class -}) -public class AllTests {} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/statistics/TmfEventsStatisticsTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/statistics/TmfEventsStatisticsTest.java deleted file mode 100644 index 18d475b8f7..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/statistics/TmfEventsStatisticsTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests.statistics; - -import static org.junit.Assume.assumeTrue; - -import org.eclipse.linuxtools.tmf.core.statistics.TmfEventsStatistics; -import org.junit.BeforeClass; - -/** - * Unit tests for the {@link TmfEventsStatistics} - * - * @author Alexandre Montplaisir - */ -public class TmfEventsStatisticsTest extends TmfStatisticsTest { - - /** - * Set up the fixture once for all tests. - */ - @BeforeClass - public static void setUpClass() { - assumeTrue(testTrace.exists()); - backend = new TmfEventsStatistics(testTrace.getTrace()); - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/statistics/TmfStateStatisticsTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/statistics/TmfStateStatisticsTest.java deleted file mode 100644 index b8a6c526df..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/statistics/TmfStateStatisticsTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests.statistics; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeTrue; - -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.statistics.TmfStateStatistics; -import org.eclipse.linuxtools.tmf.core.statistics.TmfStatisticsEventTypesModule; -import org.eclipse.linuxtools.tmf.core.statistics.TmfStatisticsTotalsModule; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; - -/** - * Unit tests for the {@link TmfStateStatistics} - * - * @author Alexandre Montplaisir - */ -public class TmfStateStatisticsTest extends TmfStatisticsTest { - - private ITmfTrace fTrace; - - private TmfStatisticsTotalsModule fTotalsMod; - private TmfStatisticsEventTypesModule fEventTypesMod; - - /** - * Class setup - */ - @BeforeClass - public static void setUpClass() { - assumeTrue(testTrace.exists()); - } - - /** - * Test setup - */ - @Before - public void setUp() { - fTrace = testTrace.getTrace(); - - /* Prepare the two analysis-backed state systems */ - fTotalsMod = new TmfStatisticsTotalsModule(); - fEventTypesMod = new TmfStatisticsEventTypesModule(); - try { - fTotalsMod.setTrace(fTrace); - fEventTypesMod.setTrace(fTrace); - } catch (TmfAnalysisException e) { - fail(); - } - - fTotalsMod.schedule(); - fEventTypesMod.schedule(); - assertTrue(fTotalsMod.waitForCompletion()); - assertTrue(fEventTypesMod.waitForCompletion()); - - ITmfStateSystem totalsSS = fTotalsMod.getStateSystem(); - ITmfStateSystem eventTypesSS = fEventTypesMod.getStateSystem(); - assertNotNull(totalsSS); - assertNotNull(eventTypesSS); - - backend = new TmfStateStatistics(totalsSS, eventTypesSS); - } - - /** - * Test cleanup - */ - @After - public void tearDown() { - fTotalsMod.close(); - fEventTypesMod.close(); - fTrace.dispose(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/statistics/TmfStatisticsTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/statistics/TmfStatisticsTest.java deleted file mode 100644 index 97aa9bd148..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/statistics/TmfStatisticsTest.java +++ /dev/null @@ -1,364 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests.statistics; - -import static org.junit.Assert.assertEquals; - -import java.util.List; -import java.util.Map; - -import org.eclipse.linuxtools.tmf.core.statistics.ITmfStatistics; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; -import org.junit.rules.Timeout; - -/** - * Base unit test class for any type of ITmfStatistics. Sub-classes should - * implement a "@BeforeClass" method to setup the 'backend' fixture accordingly. - * - * @author Alexandre Montplaisir - */ -public abstract class TmfStatisticsTest { - - /** Time-out tests after 30 seconds */ - @Rule public TestRule globalTimeout= new Timeout(30000); - - /** Test trace used for these tests */ - protected static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.KERNEL; - - /** The statistics back-end object */ - protected static ITmfStatistics backend; - - /* Known values about the trace */ - private static final int totalNbEvents = 695319; - private static final long tStart = 1332170682440133097L; /* Timestamp of first event */ - private static final long tEnd = 1332170692664579801L; /* Timestamp of last event */ - - /* Timestamps of interest */ - private static final long t1 = 1332170682490946000L; - private static final long t2 = 1332170682490947524L; /* event exactly here */ - private static final long t3 = 1332170682490948000L; - private static final long t4 = 1332170682490949000L; - private static final long t5 = 1332170682490949270L; /* following event here */ - private static final long t6 = 1332170682490949300L; - - private static final String eventType = "lttng_statedump_process_state"; - - - // ------------------------------------------------------------------------ - // Tests for histogramQuery() - // ------------------------------------------------------------------------ - - /** - * Test the {@link ITmfStatistics#histogramQuery} method for the small known - * interval. - */ - @Test - public void testHistogramQuerySmall() { - final int NB_REQ = 10; - List results = backend.histogramQuery(t1, t6, NB_REQ); - - /* Make sure the returned array has the right size */ - assertEquals(NB_REQ, results.size()); - - /* Check the contents of each "bucket" */ - assertEquals(0, results.get(0).longValue()); - assertEquals(0, results.get(1).longValue()); - assertEquals(0, results.get(2).longValue()); - assertEquals(0, results.get(3).longValue()); - assertEquals(1, results.get(4).longValue()); - assertEquals(0, results.get(5).longValue()); - assertEquals(0, results.get(6).longValue()); - assertEquals(0, results.get(7).longValue()); - assertEquals(0, results.get(8).longValue()); - assertEquals(1, results.get(9).longValue()); - - } - - /** - * Test the {@link ITmfStatistics#histogramQuery} method over the whole - * trace. - */ - @Test - public void testHistogramQueryFull() { - final int NB_REQ = 10; - List results = backend.histogramQuery(tStart, tEnd, NB_REQ); - - /* Make sure the returned array has the right size */ - assertEquals(NB_REQ, results.size()); - - /* Check the total number of events */ - long count = 0; - for (long val : results) { - count += val; - } - assertEquals(totalNbEvents, count); - - /* Check the contents of each "bucket" */ - assertEquals(94161, results.get(0).longValue()); - assertEquals(87348, results.get(1).longValue()); - assertEquals(58941, results.get(2).longValue()); - assertEquals(59879, results.get(3).longValue()); - assertEquals(66941, results.get(4).longValue()); - assertEquals(68939, results.get(5).longValue()); - assertEquals(72746, results.get(6).longValue()); - assertEquals(60749, results.get(7).longValue()); - assertEquals(61208, results.get(8).longValue()); - assertEquals(64407, results.get(9).longValue()); - } - - // ------------------------------------------------------------------------ - // Test for getEventsTotal() - // ------------------------------------------------------------------------ - - /** - * Basic test for {@link ITmfStatistics#getEventsTotal} - */ - @Test - public void testGetEventsTotal() { - long count = backend.getEventsTotal(); - assertEquals(totalNbEvents, count); - } - - // ------------------------------------------------------------------------ - // Test for getEventTypesTotal() - // ------------------------------------------------------------------------ - - /** - * Basic test for {@link ITmfStatistics#getEventTypesTotal} - */ - @Test - public void testEventTypesTotal() { - Map res = backend.getEventTypesTotal(); - assertEquals(126, res.size()); /* Number of different event types in the trace */ - - long count = sumOfEvents(res); - assertEquals(totalNbEvents, count); - } - - // ------------------------------------------------------------------------ - // Tests for getEventsInRange(ITmfTimestamp start, ITmfTimestamp end) - // ------------------------------------------------------------------------ - - /** - * Test for {@link ITmfStatistics#getEventsInRange} over the whole trace. - */ - @Test - public void testGetEventsInRangeWholeRange() { - long count = backend.getEventsInRange(tStart, tEnd); - assertEquals(totalNbEvents, count); - } - - /** - * Test for {@link ITmfStatistics#getEventsInRange} for the whole range, - * except the start time (there is only one event at the start time). - */ - @Test - public void testGetEventsInRangeMinusStart() { - long count = backend.getEventsInRange(tStart + 1, tEnd); - assertEquals(totalNbEvents - 1, count); - } - - /** - * Test for {@link ITmfStatistics#getEventsInRange} for the whole range, - * except the end time (there is only one event at the end time). - */ - @Test - public void testGetEventsInRangeMinusEnd() { - long count = backend.getEventsInRange(tStart, tEnd - 1); - assertEquals(totalNbEvents - 1, count); - } - - /** - * Test for {@link ITmfStatistics#getEventsInRange} when both the start and - * end times don't match an event. - */ - @Test - public void testGetEventsInRangeNoEventsAtEdges() { - long count = backend.getEventsInRange(t1, t6); - assertEquals(2, count); - } - - /** - * Test for {@link ITmfStatistics#getEventsInRange} when the *start* of the - * interval is exactly on an event (that event should be included). - */ - @Test - public void testGetEventsInRangeEventAtStart() { - long count = backend.getEventsInRange(t2, t3); - assertEquals(1, count); - - count = backend.getEventsInRange(t2, t6); - assertEquals(2, count); - } - - /** - * Test for {@link ITmfStatistics#getEventsInRange} when the *end* of the - * interval is exactly on an event (that event should be included). - */ - @Test - public void testGetEventsInRangeEventAtEnd() { - long count = backend.getEventsInRange(t4, t5); - assertEquals(1, count); - - count = backend.getEventsInRange(t1, t5); - assertEquals(2, count); - } - - /** - * Test for {@link ITmfStatistics#getEventsInRange} when there are events - * matching exactly both the start and end times of the range (both should - * be included). - */ - @Test - public void testGetEventsInRangeEventAtBoth() { - long count = backend.getEventsInRange(t2, t5); - assertEquals(2, count); - } - - /** - * Test for {@link ITmfStatistics#getEventsInRange} when there are no events - * in a given range. - */ - @Test - public void testGetEventsInRangeNoEvents() { - long count = backend.getEventsInRange(t3, t4); - assertEquals(0, count); - } - - // ------------------------------------------------------------------------ - // Tests for getEventTypesInRange(ITmfTimestamp start, ITmfTimestamp end) - // ------------------------------------------------------------------------ - - /** - * Test for {@link ITmfStatistics#getEventTypesInRange} over the whole trace. - */ - @Test - public void testGetEventTypesInRangeWholeRange() { - Map result = backend.getEventTypesInRange(tStart, tEnd); - /* Number of events of that type in the whole trace */ - assertEquals(new Long(464L), result.get(eventType)); - - long count = sumOfEvents(result); - assertEquals(totalNbEvents, count); - } - - /** - * Test for {@link ITmfStatistics#getEventTypesInRange} for the whole range, - * except the start time (there is only one event at the start time). - */ - @Test - public void testGetEventTypesInRangeMinusStart() { - Map result = backend.getEventTypesInRange(tStart + 1, tEnd); - - long count = sumOfEvents(result); - assertEquals(totalNbEvents - 1, count); - } - - /** - * Test for {@link ITmfStatistics#getEventTypesInRange} for the whole range, - * except the end time (there is only one event at the end time). - */ - @Test - public void testGetEventTypesInRangeMinusEnd() { - Map result = backend.getEventTypesInRange(tStart, tEnd - 1); - - long count = sumOfEvents(result); - assertEquals(totalNbEvents - 1, count); - } - - /** - * Test for {@link ITmfStatistics#getEventTypesInRange} when both the start - * and end times don't match an event. - */ - @Test - public void testGetEventTypesInRangeNoEventsAtEdges() { - Map result = backend.getEventTypesInRange(t1, t6); - assertEquals(new Long(2L), result.get(eventType)); - - long count = sumOfEvents(result); - assertEquals(2, count); - } - - /** - * Test for {@link ITmfStatistics#getEventTypesInRange} when the *start* of - * the interval is exactly on an event (that event should be included). - */ - @Test - public void testGetEventTypesInRangeEventAtStart() { - Map result = backend.getEventTypesInRange(t2, t3); - assertEquals(new Long(1L), result.get(eventType)); - long count = sumOfEvents(result); - assertEquals(1, count); - - result = backend.getEventTypesInRange(t2, t6); - assertEquals(new Long(2L), result.get(eventType)); - count = sumOfEvents(result); - assertEquals(2, count); - } - - /** - * Test for {@link ITmfStatistics#getEventTypesInRange} when the *end* of - * the interval is exactly on an event (that event should be included). - */ - @Test - public void testGetEventTypesInRangeEventAtEnd() { - Map result = backend.getEventTypesInRange(t4, t5); - assertEquals(new Long(1L), result.get(eventType)); - long count = sumOfEvents(result); - assertEquals(1, count); - - result = backend.getEventTypesInRange(t1, t5); - assertEquals(new Long(2L), result.get(eventType)); - count = sumOfEvents(result); - assertEquals(2, count); - } - - /** - * Test for {@link ITmfStatistics#getEventTypesInRange} when there are - * events matching exactly both the start and end times of the range (both - * should be included). - */ - @Test - public void testGetEventTypesInRangeEventAtBoth() { - Map result = backend.getEventTypesInRange(t2, t5); - assertEquals(new Long(2L), result.get(eventType)); - long count = sumOfEvents(result); - assertEquals(2, count); - } - - /** - * Test for {@link ITmfStatistics#getEventTypesInRange} when there are no - * events in a given range. - */ - @Test - public void testGetEventTypesInRangeNoEvents() { - Map result = backend.getEventTypesInRange(t3, t4); - long count = sumOfEvents(result); - assertEquals(0, count); - } - - // ------------------------------------------------------------------------ - // Convenience methods - // ------------------------------------------------------------------------ - - private static long sumOfEvents(Map map) { - long count = 0; - for (long val : map.values()) { - count += val; - } - return count; - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/tracemanager/AllTests.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/tracemanager/AllTests.java deleted file mode 100644 index e0831e5dc8..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/tracemanager/AllTests.java +++ /dev/null @@ -1,25 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests.tracemanager; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TmfTraceManagerTest.class -}) -public class AllTests {} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/tracemanager/TmfTraceManagerTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/tracemanager/TmfTraceManagerTest.java deleted file mode 100644 index 5919d827cc..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/linuxtools/tmf/ctf/core/tests/tracemanager/TmfTraceManagerTest.java +++ /dev/null @@ -1,720 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - * Patrick Tasse - Support selection range - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests.tracemanager; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assume.assumeTrue; - -import java.io.File; -import java.util.Set; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.google.common.collect.ImmutableSet; - -/** - * Test suite for the {@link TmfTraceManager}. - * - * @author Alexandre Montplaisir - */ -public class TmfTraceManagerTest { - - private static final int SCALE = ITmfTimestamp.NANOSECOND_SCALE; - - private static ITmfTrace trace1; - private static final long t1start = 1331668247314038062L; - private static final long t1end = 1331668259054285979L; - - private static ITmfTrace trace2; - private static final long t2start = 1332170682440133097L; - private static final long t2end = 1332170692664579801L; - - private static final long ONE_SECOND = 1000000000L; - - private TmfTraceManager tm; - - - /** - * Test class initialization - */ - @BeforeClass - public static void setUpClass() { - assumeTrue(CtfTmfTestTrace.TRACE2.exists()); - assumeTrue(CtfTmfTestTrace.KERNEL.exists()); - trace1 = CtfTmfTestTrace.TRACE2.getTrace(); - trace2 = CtfTmfTestTrace.KERNEL.getTrace(); - - trace1.indexTrace(true); - trace2.indexTrace(true); - - // Deregister traces from signal manager so that they don't - // interfere with the TmfTraceManager tests - TmfSignalManager.deregister(trace1); - TmfSignalManager.deregister(trace2); - } - - /** - * Test initialization - */ - @Before - public void setUp() { - tm = TmfTraceManager.getInstance(); - } - - /** - * Test clean-up - */ - @After - public void tearDown() { - while (tm.getActiveTrace() != null) { - closeTrace(tm.getActiveTrace()); - } - } - - /** - * Test class clean-up - */ - @AfterClass - public static void tearDownClass() { - CtfTmfTestTrace.TRACE2.dispose(); - CtfTmfTestTrace.KERNEL.dispose(); - } - - // ------------------------------------------------------------------------ - // Dummy actions (fake signals) - // ------------------------------------------------------------------------ - - private void openTrace(ITmfTrace trace) { - if (trace == null) { - throw new IllegalArgumentException(); - } - TmfSignalManager.dispatchSignal(new TmfTraceOpenedSignal(this, trace, null)); - selectTrace(trace); - } - - private void closeTrace(ITmfTrace trace) { - if (trace == null) { - throw new IllegalArgumentException(); - } - TmfSignalManager.dispatchSignal(new TmfTraceClosedSignal(this, trace)); - /* - * In TMF, the next tab would now be selected (if there are some), which - * would select another trace automatically. - */ - if (tm.getOpenedTraces().size() > 0) { - selectTrace(tm.getOpenedTraces().toArray(new ITmfTrace[0])[0]); - } - } - - private void selectTrace(ITmfTrace trace) { - TmfSignalManager.dispatchSignal(new TmfTraceSelectedSignal(this, trace)); - } - - private void selectTimestamp(ITmfTimestamp ts) { - TmfSignalManager.dispatchSignal(new TmfTimeSynchSignal(this, ts)); - } - - private void selectTimeRange(TmfTimeRange tr) { - TmfSignalManager.dispatchSignal(new TmfRangeSynchSignal(this, tr)); - } - - // ------------------------------------------------------------------------ - // General tests - // ------------------------------------------------------------------------ - - /** - * Test that the manager is correctly initialized - */ - @Test - public void testInitialize() { - TmfTraceManager mgr = TmfTraceManager.getInstance(); - assertNotNull(mgr); - assertSame(tm, mgr); - } - - /** - * Test the contents of a trace set with one trace. - */ - @Test - public void testTraceSet() { - openTrace(trace1); - openTrace(trace2); - selectTrace(trace2); - - ITmfTrace[] expected = new ITmfTrace[] { trace2 }; - ITmfTrace[] actual = tm.getActiveTraceSet(); - - assertEquals(1, actual.length); - assertArrayEquals(expected, actual); - } - - /** - * Test the contents of a trace set with an experiment. - */ - @Test - public void testTraceSetExperiment() { - TmfExperiment exp = createExperiment(trace1, trace2); - openTrace(trace1); - openTrace(exp); - - ITmfTrace[] expected = new ITmfTrace[] { trace1, trace2 }; - ITmfTrace[] actual = tm.getActiveTraceSet(); - - assertEquals(2, actual.length); - assertArrayEquals(expected, actual); - } - - /** - * Test the contents of the complete trace set. - */ - @Test - public void testTraceSetWithExperiment() { - /* Test with a trace */ - Set expected = ImmutableSet.of(trace1); - Set actual = TmfTraceManager.getTraceSetWithExperiment(trace1); - assertEquals(1, actual.size()); - assertEquals(expected, actual); - - /* Test with an experiment */ - TmfExperiment exp = createExperiment(trace1, trace2); - expected = ImmutableSet.of(trace1, trace2, exp); - actual = TmfTraceManager.getTraceSetWithExperiment(exp); - assertEquals(3, actual.size()); - assertEquals(expected, actual); - } - - /** - * Test the {@link TmfTraceManager#getSupplementaryFileDir} method. - */ - @Test - public void testSupplementaryFileDir() { - String name1 = trace1.getName(); - String name2 = trace2.getName(); - String basePath = TmfTraceManager.getTemporaryDirPath() + File.separator; - - String expected1 = basePath + name1 + File.separator; - String expected2 = basePath + name2 + File.separator; - - assertEquals(expected1, TmfTraceManager.getSupplementaryFileDir(trace1)); - assertEquals(expected2, TmfTraceManager.getSupplementaryFileDir(trace2)); - } - - // ------------------------------------------------------------------------ - // Test a single trace - // ------------------------------------------------------------------------ - - /** - * Test the initial range of a single trace. - */ - @Test - public void testTraceInitialRange() { - openTrace(trace2); - final TmfTimeRange expectedRange = new TmfTimeRange( - trace2.getStartTime(), - calculateOffset(trace2.getStartTime(), trace2.getInitialRangeOffset())); - TmfTimeRange actualRange = tm.getCurrentRange(); - assertEquals(expectedRange, actualRange); - } - - /** - * Try selecting a timestamp contained inside the trace's range. The trace's - * current time should get updated correctly. - */ - @Test - public void testNewTimestamp() { - openTrace(trace2); - ITmfTimestamp ts = new TmfTimestamp(t2start + ONE_SECOND, SCALE); - selectTimestamp(ts); - - ITmfTimestamp afterTs = tm.getSelectionBeginTime(); - assertEquals(ts, afterTs); - afterTs = tm.getSelectionEndTime(); - assertEquals(ts, afterTs); - } - - /** - * Try selecting a timestamp happening before the trace's start. The change - * should be ignored. - */ - @Test - public void testTimestampBefore() { - openTrace(trace2); - ITmfTimestamp beforeTs = tm.getSelectionBeginTime(); - ITmfTimestamp ts = new TmfTimestamp(t2start - ONE_SECOND, SCALE); - selectTimestamp(ts); - - ITmfTimestamp curTs = tm.getSelectionBeginTime(); - assertEquals(beforeTs, curTs); - curTs = tm.getSelectionEndTime(); - assertEquals(beforeTs, curTs); - } - - /** - * Try selecting a timestamp happening after the trace's end. The change - * should be ignored. - */ - @Test - public void testTimestampAfter() { - openTrace(trace2); - ITmfTimestamp beforeTs = tm.getSelectionBeginTime(); - ITmfTimestamp ts = new TmfTimestamp(t2end + ONE_SECOND, SCALE); - selectTimestamp(ts); - - ITmfTimestamp curTs = tm.getSelectionBeginTime(); - assertEquals(beforeTs, curTs); - curTs = tm.getSelectionEndTime(); - assertEquals(beforeTs, curTs); - } - - /** - * Test selecting a normal sub-range of a single trace. - */ - @Test - public void testTraceNewTimeRange() { - openTrace(trace2); - TmfTimeRange range = new TmfTimeRange( - new TmfTimestamp(t2start + ONE_SECOND, SCALE), - new TmfTimestamp(t2end - ONE_SECOND, SCALE)); - selectTimeRange(range); - - TmfTimeRange curRange = tm.getCurrentRange(); - assertEquals(range.getStartTime(), curRange.getStartTime()); - assertEquals(range.getEndTime(), curRange.getEndTime()); - } - - /** - * Test selecting a range whose start time is before the trace's start time. - * The selected range should get clamped to the trace's range. - */ - @Test - public void testTraceTimeRangeClampingStart() { - openTrace(trace2); - TmfTimeRange range = new TmfTimeRange( - new TmfTimestamp(t2start - ONE_SECOND, SCALE), // minus here - new TmfTimestamp(t2end - ONE_SECOND, SCALE)); - selectTimeRange(range); - - TmfTimeRange curRange = tm.getCurrentRange(); - assertEquals(t2start, curRange.getStartTime().getValue()); - assertEquals(range.getEndTime(), curRange.getEndTime()); - } - - /** - * Test selecting a range whose end time is after the trace's end time. - * The selected range should get clamped to the trace's range. - */ - @Test - public void testTraceTimeRangeClampingEnd() { - openTrace(trace2); - TmfTimeRange range = new TmfTimeRange( - new TmfTimestamp(t2start + ONE_SECOND, SCALE), - new TmfTimestamp(t2end + ONE_SECOND, SCALE)); // plus here - selectTimeRange(range); - - TmfTimeRange curRange = tm.getCurrentRange(); - assertEquals(range.getStartTime(), curRange.getStartTime()); - assertEquals(t2end, curRange.getEndTime().getValue()); - } - - /** - * Test selecting a range whose both start and end times are outside of the - * trace's range. The selected range should get clamped to the trace's - * range. - */ - @Test - public void testTraceTimeRangeClampingBoth() { - openTrace(trace2); - TmfTimeRange range = new TmfTimeRange( - new TmfTimestamp(t2start - ONE_SECOND, SCALE), // minus here - new TmfTimestamp(t2end + ONE_SECOND, SCALE)); // plus here - selectTimeRange(range); - - TmfTimeRange curRange = tm.getCurrentRange(); - assertEquals(t2start, curRange.getStartTime().getValue()); - assertEquals(t2end, curRange.getEndTime().getValue()); - } - - // ------------------------------------------------------------------------ - // Test multiple, non-overlapping traces in parallel - // ------------------------------------------------------------------------ - - /** - * Test, with two traces in parallel, when we select a timestamp that is - * part of the first trace. - * - * The first trace's timestamp should be updated, but the second trace's one - * should not change. - */ - @Test - public void testTwoTracesTimestampValid() { - openTrace(trace1); - openTrace(trace2); - selectTrace(trace1); - TmfTimestamp ts = new TmfTimestamp(t1start + ONE_SECOND, SCALE); - selectTimestamp(ts); - - /* Timestamp of trace1 should have been updated */ - assertEquals(ts, tm.getSelectionBeginTime()); - assertEquals(ts, tm.getSelectionEndTime()); - - /* Timestamp of trace2 should not have changed */ - selectTrace(trace2); - assertEquals(trace2.getStartTime(), tm.getSelectionBeginTime()); - assertEquals(trace2.getStartTime(), tm.getSelectionEndTime()); - } - - /** - * Test, with two traces in parallel, when we select a timestamp that is - * between two traces. - * - * None of the trace's timestamps should be updated (we are not in an - * experiment!) - */ - @Test - public void testTwoTracesTimestampInBetween() { - openTrace(trace1); - openTrace(trace2); - selectTrace(trace1); - TmfTimestamp ts = new TmfTimestamp(t1end + ONE_SECOND, SCALE); - selectTimestamp(ts); - - /* Timestamp of trace1 should not have changed */ - assertEquals(trace1.getStartTime(), tm.getSelectionBeginTime()); - assertEquals(trace1.getStartTime(), tm.getSelectionEndTime()); - - /* Timestamp of trace2 should not have changed */ - selectTrace(trace2); - assertEquals(trace2.getStartTime(), tm.getSelectionBeginTime()); - assertEquals(trace2.getStartTime(), tm.getSelectionEndTime()); - } - - /** - * Test, with two traces in parallel, when we select a timestamp that is - * completely out of the trace's range. - * - * None of the trace's timestamps should be updated. - */ - @Test - public void testTwoTracesTimestampInvalid() { - openTrace(trace1); - openTrace(trace2); - selectTrace(trace1); - TmfTimestamp ts = new TmfTimestamp(t2end + ONE_SECOND, SCALE); - selectTimestamp(ts); - - /* Timestamp of trace1 should not have changed */ - assertEquals(trace1.getStartTime(), tm.getSelectionBeginTime()); - assertEquals(trace1.getStartTime(), tm.getSelectionEndTime()); - - /* Timestamp of trace2 should not have changed */ - selectTrace(trace2); - assertEquals(trace2.getStartTime(), tm.getSelectionBeginTime()); - assertEquals(trace2.getStartTime(), tm.getSelectionEndTime()); - } - - /** - * Test, with two traces opened in parallel (not in an experiment), if we - * select a time range valid in one of them. That trace's time range should - * be updated, but not the other one. - */ - @Test - public void testTwoTracesTimeRangeAllInOne() { - openTrace(trace1); - openTrace(trace2); - selectTrace(trace1); - TmfTimeRange range = new TmfTimeRange( - new TmfTimestamp(t1start + ONE_SECOND, SCALE), - new TmfTimestamp(t1end - ONE_SECOND, SCALE)); - selectTimeRange(range); - - /* Range of trace1 should be equal to the requested one */ - assertEquals(range, tm.getCurrentRange()); - - /* The range of trace 2 should not have changed */ - selectTrace(trace2); - assertEquals(getInitialRange(trace2), tm.getCurrentRange()); - } - - /** - * Test, with two traces in parallel, when we select a time range that is - * only partially valid for one of the traces. - * - * The first trace's time range should be clamped to a valid range, and the - * second one's should not change. - */ - @Test - public void testTwoTracesTimeRangePartiallyInOne() { - openTrace(trace1); - openTrace(trace2); - selectTrace(trace1); - TmfTimeRange range = new TmfTimeRange( - new TmfTimestamp(t1start + ONE_SECOND, SCALE), - new TmfTimestamp(t1end + ONE_SECOND, SCALE)); - selectTimeRange(range); - - /* Range of trace1 should get clamped to its end time */ - TmfTimeRange expectedRange = new TmfTimeRange( - new TmfTimestamp(t1start + ONE_SECOND, SCALE), - new TmfTimestamp(t1end, SCALE)); - assertEquals(expectedRange, tm.getCurrentRange()); - - /* Range of trace2 should not have changed */ - selectTrace(trace2); - assertEquals(getInitialRange(trace2), tm.getCurrentRange()); - } - - /** - * Test, with two traces in parallel, when we select a time range that is - * only partially valid for both traces. - * - * Each trace's time range should get clamped to respectively valid ranges. - */ - @Test - public void testTwoTracesTimeRangeInBoth() { - openTrace(trace1); - openTrace(trace2); - selectTrace(trace1); - TmfTimeRange range = new TmfTimeRange( - new TmfTimestamp(t1end - ONE_SECOND, SCALE), - new TmfTimestamp(t2start + ONE_SECOND, SCALE)); - selectTimeRange(range); - - /* Range of trace1 should be clamped to its end time */ - TmfTimeRange expectedRange = new TmfTimeRange( - new TmfTimestamp(t1end - ONE_SECOND, SCALE), - new TmfTimestamp(t1end, SCALE)); - assertEquals(expectedRange, tm.getCurrentRange()); - - /* Range of trace2 should be clamped to its start time */ - selectTrace(trace2); - expectedRange = new TmfTimeRange( - new TmfTimestamp(t2start, SCALE), - new TmfTimestamp(t2start + ONE_SECOND, SCALE)); - assertEquals(expectedRange, tm.getCurrentRange()); - } - - /** - * Test, with two traces in parallel, when we select a time range that is - * not valid for any trace. - * - * Each trace's time range should not be modified. - */ - @Test - public void testTwoTracesTimeRangeInBetween() { - openTrace(trace1); - openTrace(trace2); - selectTrace(trace1); - TmfTimeRange range = new TmfTimeRange( - new TmfTimestamp(t1end + ONE_SECOND, SCALE), - new TmfTimestamp(t1end - ONE_SECOND, SCALE)); - selectTimeRange(range); - - /* Range of trace1 should not have changed */ - TmfTimeRange expectedRange = getInitialRange(trace1); - TmfTimeRange curRange = tm.getCurrentRange(); - assertEquals(expectedRange.getStartTime(), curRange.getStartTime()); - assertEquals(expectedRange.getEndTime(), curRange.getEndTime()); - - /* Range of trace2 should not have changed */ - selectTrace(trace2); - expectedRange = getInitialRange(trace2); - curRange = tm.getCurrentRange(); - assertEquals(expectedRange.getStartTime(), curRange.getStartTime()); - assertEquals(expectedRange.getEndTime(), curRange.getEndTime()); - } - - // ------------------------------------------------------------------------ - // Test an experiment - // ------------------------------------------------------------------------ - - /** - * Test in an experiment when we select a timestamp that is part of one of - * the experiment's traces. - * - * The experiment's current time should be correctly updated. - */ - @Test - public void testExperimentTimestampInTrace() { - TmfExperiment exp = createExperiment(trace1, trace2); - openTrace(exp); - TmfTimestamp ts = new TmfTimestamp(t1start + ONE_SECOND, SCALE); - selectTimestamp(ts); - - /* The experiment's current time should be updated. */ - assertEquals(ts, tm.getSelectionBeginTime()); - assertEquals(ts, tm.getSelectionEndTime()); - } - - /** - * Test in an experiment when we select a timestamp that is between two - * traces in the experiment. - * - * The experiment's current time should still be updated, since the - * timestamp is valid in the experiment itself. - */ - @Test - public void testExperimentTimestampInBetween() { - TmfExperiment exp = createExperiment(trace1, trace2); - openTrace(exp); - TmfTimestamp ts = new TmfTimestamp(t1end + ONE_SECOND, SCALE); - selectTimestamp(ts); - - /* The experiment's current time should be updated. */ - assertEquals(ts, tm.getSelectionBeginTime()); - assertEquals(ts, tm.getSelectionEndTime()); - } - - /** - * Test in an experiment when we select a timestamp that is outside of the - * total range of the experiment. - * - * The experiment's current time should not be updated. - */ - @Test - public void testExperimentTimestampInvalid() { - TmfExperiment exp = createExperiment(trace1, trace2); - openTrace(exp); - TmfTimestamp ts = new TmfTimestamp(t2end + ONE_SECOND, SCALE); - selectTimestamp(ts); - - /* The experiment's current time should NOT be updated. */ - assertEquals(trace1.getStartTime(), tm.getSelectionBeginTime()); - assertEquals(trace1.getStartTime(), tm.getSelectionEndTime()); - } - - /** - * Test the initial range of an experiment. - */ - @Test - public void testExperimentInitialRange() { - TmfExperiment exp = createExperiment(trace1, trace2); - openTrace(exp); - /* - * The initial range should be == to the initial range of the earliest - * trace (here trace1). - */ - final TmfTimeRange actualRange = tm.getCurrentRange(); - - assertEquals(getInitialRange(trace1), actualRange); - assertEquals(getInitialRange(exp), actualRange); - } - - /** - * Test the range clamping with the start time of the range outside of the - * earliest trace's range. Only that start time should get clamped. - */ - @Test - public void testExperimentRangeClampingOne() { - TmfExperiment exp = createExperiment(trace1, trace2); - openTrace(exp); - - final TmfTimeRange range = new TmfTimeRange( - new TmfTimestamp(t1start - ONE_SECOND, SCALE), - new TmfTimestamp(t1end - ONE_SECOND, SCALE)); - selectTimeRange(range); - - TmfTimeRange actualRange = tm.getCurrentRange(); - assertEquals(t1start, actualRange.getStartTime().getValue()); - assertEquals(t1end - ONE_SECOND, actualRange.getEndTime().getValue()); - } - - /** - * Test the range clamping when both the start and end times of the signal's - * range are outside of the trace's range. The range should clamp to the - * experiment's range. - */ - @Test - public void testExperimentRangeClampingBoth() { - TmfExperiment exp = createExperiment(trace1, trace2); - openTrace(exp); - - final TmfTimeRange range = new TmfTimeRange( - new TmfTimestamp(t1start - ONE_SECOND, SCALE), - new TmfTimestamp(t2end + ONE_SECOND, SCALE)); - selectTimeRange(range); - - TmfTimeRange actualRange = tm.getCurrentRange(); - assertEquals(t1start, actualRange.getStartTime().getValue()); - assertEquals(t2end, actualRange.getEndTime().getValue()); - } - - /** - * Test selecting a range in-between two disjoint traces in an experiment. - * The range should still get correctly selected, even if no trace has any - * events in that range. - */ - @Test - public void testExperimentRangeInBetween() { - TmfExperiment exp = createExperiment(trace1, trace2); - openTrace(exp); - - final TmfTimeRange range = new TmfTimeRange( - new TmfTimestamp(t1end + ONE_SECOND, SCALE), - new TmfTimestamp(t2start - ONE_SECOND, SCALE)); - selectTimeRange(range); - - TmfTimeRange actualRange = tm.getCurrentRange(); - assertEquals(range, actualRange); - } - - // ------------------------------------------------------------------------ - // Utility methods - // ------------------------------------------------------------------------ - - private static TmfExperiment createExperiment(ITmfTrace t1, ITmfTrace t2) { - ITmfTrace[] traces = new ITmfTrace[] { t1, t2 }; - TmfExperiment exp = new TmfExperiment(ITmfEvent.class, "test-exp", traces); - exp.indexTrace(true); - // Deregister experiment from signal manager so that it doesn't - // interfere with the TmfTraceManager tests - TmfSignalManager.deregister(exp); - return exp; - } - - private static TmfTimeRange getInitialRange(ITmfTrace trace) { - return new TmfTimeRange( - trace.getStartTime(), - calculateOffset(trace.getStartTime(), trace.getInitialRangeOffset())); - } - - /** - * Basically a "initial + offset" operation, but for ITmfTimetamp objects. - */ - private static ITmfTimestamp calculateOffset(ITmfTimestamp initialTs, ITmfTimestamp offsetTs) { - long start = initialTs.normalize(0, SCALE).getValue(); - long offset = offsetTs.normalize(0, SCALE).getValue(); - return new TmfTimestamp(start + offset, SCALE); - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/AllTests.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/AllTests.java new file mode 100644 index 0000000000..88f33ad8e4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/AllTests.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial generation with CodePro tools + * Alexandre Montplaisir - Clean up, consolidate redundant tests + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * The class TestAll builds a suite that can be used to run all + * of the tests within its package as well as within any subpackages of its + * package. + * + * @author ematkho + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + CtfIteratorTest.class, + CtfLocationDataTest.class, + CtfLocationTest.class, + CtfTmfContextTest.class, + CtfTmfEventFieldTest.class, + CtfTmfEventTest.class, + CtfTmfEventTypeTest.class, + CtfTmfLostEventsTest.class, + CtfTmfTimestampTest.class, + CtfTmfTraceTest.class, + EventContextTest.class, + FunkyTraceTest.class, + + /* Tests in other packages (that are there because of CTF) */ + org.eclipse.tracecompass.tmf.ctf.core.tests.request.AllTests.class, + org.eclipse.tracecompass.tmf.ctf.core.tests.statistics.AllTests.class, + org.eclipse.tracecompass.tmf.ctf.core.tests.tracemanager.AllTests.class +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfIteratorTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfIteratorTest.java new file mode 100644 index 0000000000..e30d2e7e27 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfIteratorTest.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial generation with CodePro tools + * Alexandre Montplaisir - Clean up, consolidate redundant tests + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; + +import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException; +import org.eclipse.tracecompass.tmf.ctf.core.CtfIterator; +import org.eclipse.tracecompass.tmf.ctf.core.CtfLocation; +import org.eclipse.tracecompass.tmf.ctf.core.CtfLocationInfo; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfEvent; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * The class CtfIteratorTest contains tests for the class + * {@link CtfIterator}. + * + * @author ematkho + * @version 1.0 + */ +public class CtfIteratorTest { + + private static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.KERNEL; + + private CtfTmfTrace trace; + private CtfIterator iterator; + + /** + * Perform pre-test initialization. + * @throws CTFReaderException error + */ + @Before + public void setUp() throws CTFReaderException { + assumeTrue(testTrace.exists()); + trace = testTrace.getTrace(); + iterator = new CtfIterator(trace); + CtfLocation ctfLocation = new CtfLocation(new CtfLocationInfo(1, 0)); + iterator.setLocation(ctfLocation); + iterator.increaseRank(); + } + + /** + * Perform post-test clean-up. + */ + @After + public void tearDown() { + if (trace != null) { + trace.dispose(); + } + if (iterator != null) { + iterator.dispose(); + } + } + + /** + * Run the CtfIterator(CtfTmfTrace) constructor on a non init'ed trace. + * @throws CTFReaderException error + */ + @Test + public void testCtfIterator_noinit() throws CTFReaderException { + try (CtfIterator result = new CtfIterator(trace);) { + assertNotNull(result); + } + } + + /** + * Run the CtfIterator(CtfTmfTrace) constructor on an init'ed trace. + * @throws CTFReaderException error + */ + @Test + public void testCtfIterator_init() throws CTFReaderException { + trace.init("test"); + try (CtfIterator result = new CtfIterator(trace);) { + assertNotNull(result); + } + } + + /** + * Run the CtfIterator(CtfTmfTrace,long,long) constructor test, which + * specifies an initial position for the iterator. + * @throws CTFReaderException error + */ + @Test + public void testCtfIterator_position() throws CTFReaderException { + long timestampValue = 1L; + long rank = 1L; + try (CtfIterator result = new CtfIterator(trace, new CtfLocationInfo(timestampValue, 0), rank);) { + assertNotNull(result); + } + } + + + /** + * Run the boolean advance() method test. + */ + @Test + public void testAdvance() { + boolean result = iterator.advance(); + assertTrue(result); + } + + /** + * Run the int compareTo(CtfIterator) method test. + * @throws CTFReaderException error + */ + @Test + public void testCompareTo() throws CTFReaderException { + try (CtfIterator o = new CtfIterator(trace);) { + int result = iterator.compareTo(o); + assertEquals(1L, result); + } + } + + /** + * Run the boolean equals(Object) method test. Compare with another iterator + * on the same trace. + * @throws CTFReaderException error + */ + @Test + public void testEquals_other() throws CTFReaderException { + try (CtfIterator obj = new CtfIterator(trace);) { + CtfLocation ctfLocation1 = new CtfLocation(new CtfLocationInfo(1, 0)); + obj.setLocation(ctfLocation1); + obj.increaseRank(); + + boolean result = iterator.equals(obj); + assertTrue(result); + } + } + + /** + * Run the boolean equals(Object) method test. Compare with an empty object. + */ + @Test + public void testEquals_empty() { + Object obj = new Object(); + boolean result = iterator.equals(obj); + + assertFalse(result); + } + + /** + * Run the CtfTmfTrace getCtfTmfTrace() method test. + */ + @Test + public void testGetCtfTmfTrace() { + try (CtfTmfTrace result = iterator.getCtfTmfTrace();) { + assertNotNull(result); + } + } + + /** + * Run the CtfTmfEvent getCurrentEvent() method test. + */ + @Test + public void testGetCurrentEvent() { + CtfTmfEvent result = iterator.getCurrentEvent(); + assertNotNull(result); + } + + /** + * Run the CtfLocation getLocation() method test. + */ + @Test + public void testGetLocation() { + CtfLocation result = iterator.getLocation(); + assertNotNull(result); + } + + /** + * Run the long getRank() method test. + */ + @Test + public void testGetRank() { + long result = iterator.getRank(); + assertEquals(1L, result); + } + + /** + * Run the boolean hasValidRank() method test. + */ + @Test + public void testHasValidRank() { + boolean result = iterator.hasValidRank(); + assertTrue(result); + } + + /** + * Run the int hashCode() method test. + */ + @Test + public void testHashCode() { + int result = iterator.hashCode(); + int result2 = iterator.hashCode(); + assertEquals(result, result2); + } + + /** + * Run the void increaseRank() method test. + */ + @Test + public void testIncreaseRank() { + iterator.increaseRank(); + } + + /** + * Run the boolean seek(long) method test. + */ + @Test + public void testSeek() { + long timestamp = 1L; + boolean result = iterator.seek(timestamp); + assertTrue(result); + } + + /** + * Run the void setLocation(ITmfLocation) method test. + */ + @Test + public void testSetLocation() { + CtfLocation location = new CtfLocation(new CtfLocationInfo(1, 0)); + iterator.setLocation(location); + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfLocationDataTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfLocationDataTest.java new file mode 100644 index 0000000000..44707c0fd4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfLocationDataTest.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.eclipse.tracecompass.tmf.ctf.core.CtfLocationInfo; +import org.junit.Before; +import org.junit.Test; + +/** + * Collection of tests for the {@link CtfLocationInfo} + * + * @author alexmont + */ +public class CtfLocationDataTest { + + private CtfLocationInfo fixture; + + /** + * Perform pre-test initialization. + */ + @Before + public void setUp() { + fixture = new CtfLocationInfo(1, 0); + } + + /** + * Test for the .getTimestamp() and .getIndex() methods + */ + @Test + public void testGetters() { + long timestamp = fixture.getTimestamp(); + long index = fixture.getIndex(); + + assertEquals(1, timestamp); + assertEquals(0, index); + } + + /** + * Test for the .hashCode() method + */ + @Test + public void testHashCode() { + int code = fixture.hashCode(); + assertEquals(962, code); + } + + /** + * Test for the .equals() method + */ + @Test + public void testEquals() { + CtfLocationInfo same = new CtfLocationInfo(1, 0); + CtfLocationInfo diff1 = new CtfLocationInfo(100, 0); + CtfLocationInfo diff2 = new CtfLocationInfo(1, 10); + + assertTrue(fixture.equals(same)); + assertFalse(fixture.equals(diff1)); + assertFalse(fixture.equals(diff2)); + } + + /** + * Test for the .compareTo() method + */ + @Test + public void testCompareTo() { + CtfLocationInfo same = new CtfLocationInfo(1, 0); + CtfLocationInfo smaller = new CtfLocationInfo(0, 0); + CtfLocationInfo bigger1 = new CtfLocationInfo(1000, 500); + CtfLocationInfo bigger2 = new CtfLocationInfo(1, 1); + + assertEquals(0, same.compareTo(fixture)); + assertEquals(-1, smaller.compareTo(fixture)); + assertEquals(1, bigger1.compareTo(fixture)); + assertEquals(1, bigger2.compareTo(fixture)); + } + + /** + * Test for the .toString() method + */ + @Test + public void testToString() { + String expected = "Element [1/0]"; + assertEquals(expected, fixture.toString()); + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfLocationTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfLocationTest.java new file mode 100644 index 0000000000..299cbe2acc --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfLocationTest.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial generation with CodePro tools + * Alexandre Montplaisir - Clean up, consolidate redundant tests + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.ctf.core.CtfLocation; +import org.eclipse.tracecompass.tmf.ctf.core.CtfLocationInfo; +import org.junit.Before; +import org.junit.Test; + +/** + * The class CtfLocationTest contains tests for the class + * {@link CtfLocation}. + * + * @author ematkho + * @version 1.0 + */ +public class CtfLocationTest { + + private CtfLocation fixture; + + /** + * Perform pre-test initialization. + */ + @Before + public void setUp() { + fixture = new CtfLocation(new CtfLocationInfo(1, 0)); + } + + /** + * Run the CtfLocation(Long) constructor test. + */ + @Test + public void testCtfLocation_long() { + CtfLocationInfo location = new CtfLocationInfo(1, 0); + CtfLocation result = new CtfLocation(location); + + assertNotNull(result); + assertEquals(1L, result.getLocationInfo().getTimestamp()); + } + + /** + * Run the CtfLocation(ITmfTimestamp) constructor test. + */ + @Test + public void testCtfLocation_timestamp() { + ITmfTimestamp timestamp = new TmfTimestamp(); + CtfLocation result = new CtfLocation(timestamp); + + assertNotNull(result); + assertEquals(0L, result.getLocationInfo().getTimestamp()); + } + + /** + * Run the Long getLocation() method test. + */ + @Test + public void testGetLocation() { + CtfLocationInfo location = fixture.getLocationInfo(); + long result = location.getTimestamp(); + assertEquals(1L, result); + } + + /** + * Run the void setLocation(Long) method test. + */ + @Test + public void testSetLocation() { + CtfLocationInfo location = new CtfLocationInfo(1337, 7331); + fixture = new CtfLocation(location); + } + + /** + * Test the toString() method with a valid location. + */ + @Test + public void testToString_valid(){ + CtfLocation fixture2 = new CtfLocation(new CtfLocationInfo(1337, 7331)); + assertEquals("CtfLocation [fLocationInfo=Element [1337/7331]]", fixture2.toString()); + } + + /** + * Test the toString() method with an invalid location. + */ + @Test + public void testToString_invalid(){ + CtfLocation fixture2 = new CtfLocation(new CtfLocationInfo(-1, -1)); + assertEquals("CtfLocation [INVALID]", fixture2.toString()); + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfContextTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfContextTest.java new file mode 100644 index 0000000000..2eb96bdda0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfContextTest.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial implementation + * Alexandre Montplaisir + * Patrick Tasse - Updated for removal of context clone + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; + +import java.util.ArrayList; + +import org.eclipse.core.resources.IResource; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfContext; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfEvent; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests for the CtfTmfLightweightContext class + * + * @author Matthew Khouzam + * @version 1.1 + */ +public class CtfTmfContextTest { + + private static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.KERNEL; + private static final long begin = 1332170682440133097L; /* Trace start time */ + private static final long end = 1332170692664579801L; /* Trace end time */ + + private CtfTmfTrace trace; + + private class SeekerThread extends Thread { + long val; + + public void setVal(long val) { + this.val = val; + } + } + + /** + * Pre-test initialization + * + * @throws TmfTraceException + * If the trace couldn't be init'ed, which shouldn't happen. + */ + @Before + public void setUp() throws TmfTraceException { + assumeTrue(testTrace.exists()); + trace = new CtfTmfTrace(); + String path = testTrace.getPath(); + trace.initTrace((IResource) null, path, CtfTmfEvent.class); + } + + /** + * Index all the events in the test trace. + */ + @Test + public void testIndexing() { + CtfTmfContext context = new CtfTmfContext(trace); + context.seek(0); + + int count = 0; + while (trace.getNext(context) != null) { + count++; + } + assertTrue(count > 0); + } + + /** + * Context fuzzer. Use an amount of contexts greater than the size of the + * iterator cache and have them access the trace in parallel. + * + * @throws InterruptedException + * Would fail the test + */ + @Test + public void testTooManyContexts() throws InterruptedException { + final int lwcCount = 101; + double increment = (end - begin) / lwcCount; + final ArrayList vals = new ArrayList<>(); + final ArrayList threads = new ArrayList<>(); + final ArrayList tooManyContexts = new ArrayList<>(); + + for (double i = begin; i < end; i += increment) { + SeekerThread thread = new SeekerThread() { + @Override + public void run() { + CtfTmfContext lwc = new CtfTmfContext(trace); + lwc.seek(val); + trace.getNext(lwc); + synchronized(trace){ + if (lwc.getCurrentEvent() != null) { + vals.add(lwc.getCurrentEvent().getTimestamp().getValue()); + } + tooManyContexts.add(lwc); + } + } + }; + thread.setVal((long)i); + threads.add(thread); + thread.start(); + } + + for (Thread t: threads){ + t.join(); + } + + for (long val : vals){ + assertTrue(val >= begin); + assertTrue(val <= end); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfEventFieldTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfEventFieldTest.java new file mode 100644 index 0000000000..150b57b19e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfEventFieldTest.java @@ -0,0 +1,324 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial generation with CodePro tools + * Alexandre Montplaisir - Clean up, consolidate redundant tests + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.ctf.core.event.io.BitBuffer; +import org.eclipse.linuxtools.ctf.core.event.types.EnumDeclaration; +import org.eclipse.linuxtools.ctf.core.event.types.FloatDeclaration; +import org.eclipse.linuxtools.ctf.core.event.types.FloatDefinition; +import org.eclipse.linuxtools.ctf.core.event.types.IDefinition; +import org.eclipse.linuxtools.ctf.core.event.types.IntegerDeclaration; +import org.eclipse.linuxtools.ctf.core.event.types.StringDeclaration; +import org.eclipse.linuxtools.ctf.core.event.types.StructDeclaration; +import org.eclipse.linuxtools.ctf.core.event.types.StructDefinition; +import org.eclipse.linuxtools.ctf.core.event.types.VariantDeclaration; +import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException; +import org.eclipse.linuxtools.internal.ctf.core.event.types.ArrayDeclaration; +import org.eclipse.linuxtools.internal.ctf.core.event.types.SequenceDeclaration; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfEventField; +import org.junit.Before; +import org.junit.Test; + +/** + * The class CtfTmfEventFieldTest contains tests for the class + * {@link CtfTmfEventField}. + * + * @author Matthew Khouzam + * @version 1.0 + */ +public class CtfTmfEventFieldTest { + + private static final @NonNull String ROOT = "root"; + private static final String SEQ = "seq"; + private static final @NonNull String ARRAY_STR = "array_str"; + private static final @NonNull String ARRAY_FLOAT = "array_float"; + private static final @NonNull String ARRAY_INT = "array_int"; + private static final @NonNull String ARRAY_STRUCT = "array_struct"; + private static final @NonNull String ARRAY_VARIANT = "array_variant"; + private static final @NonNull String ARRAY_ENUM = "array_enum"; + private static final String STR = "str"; + private static final String FLOAT = "float"; + private static final String LEN = "len"; + private static final String INT = "int"; + private static final String NAME = "test"; + private static final String STRUCT = "struct"; + private static final String VARIANT = "variant"; + private static final String ENUM = "enum"; + + private static final byte TEST_NUMBER = 2; + private static final String TEST_STRING = "two"; + + private static final int ARRAY_SIZE = 2; + + private StructDefinition fixture; + + /** + * Perform pre-test initialization. + * + * @throws UnsupportedEncodingException + * Thrown when UTF-8 encoding is not available. + * @throws CTFReaderException + * error + */ + @Before + public void setUp() throws UnsupportedEncodingException, CTFReaderException { + final byte[] testStringBytes = TEST_STRING.getBytes("UTF-8"); + + int capacity = 2048; + ByteBuffer bb = ByteBuffer.allocateDirect(capacity); + + StructDeclaration sDec = new StructDeclaration(1l); + StringDeclaration strDec = new StringDeclaration(); + IntegerDeclaration intDec = IntegerDeclaration.UINT_8_DECL; + FloatDeclaration flDec = new FloatDeclaration(8, 24, + ByteOrder.BIG_ENDIAN, 8); + SequenceDeclaration seqDec = new SequenceDeclaration(LEN, intDec); + StructDeclaration structDec = new StructDeclaration(8); + EnumDeclaration enumDec = new EnumDeclaration(intDec); + VariantDeclaration varDec = new VariantDeclaration(); + ArrayDeclaration arrStrDec = new ArrayDeclaration(ARRAY_SIZE, strDec); + ArrayDeclaration arrFloatDec = new ArrayDeclaration(ARRAY_SIZE, flDec); + ArrayDeclaration arrIntDec = new ArrayDeclaration(ARRAY_SIZE, intDec); + ArrayDeclaration arrStructDec = new ArrayDeclaration(ARRAY_SIZE, structDec); + ArrayDeclaration arrVariantDec = new ArrayDeclaration(ARRAY_SIZE, varDec); + ArrayDeclaration arrEnumDec = new ArrayDeclaration(ARRAY_SIZE, enumDec); + + sDec.addField(INT, intDec); + bb.put(TEST_NUMBER); + + sDec.addField(ARRAY_INT, arrIntDec); + for (int i = 0; i < ARRAY_SIZE; ++i) { + bb.put(TEST_NUMBER); + } + + sDec.addField(LEN, intDec); + bb.put(TEST_NUMBER); + + sDec.addField(FLOAT, flDec); + bb.putFloat(TEST_NUMBER); + + sDec.addField(ARRAY_FLOAT, arrFloatDec); + for (int i = 0; i < ARRAY_SIZE; ++i) { + bb.putFloat(TEST_NUMBER); + } + + sDec.addField(STR, strDec); + bb.put(testStringBytes); + bb.put((byte) 0); + + sDec.addField(ARRAY_STR, arrStrDec); + for (int i = 0; i < ARRAY_SIZE; ++i) { + bb.put(testStringBytes); + bb.put((byte) 0); + } + + sDec.addField(SEQ, seqDec); + bb.put(TEST_NUMBER); + bb.put(TEST_NUMBER); + + structDec.addField(STR, strDec); + structDec.addField(INT, intDec); + sDec.addField(STRUCT, structDec); + bb.put(testStringBytes); + bb.put((byte) 0); + bb.put(TEST_NUMBER); + + sDec.addField(ARRAY_STRUCT, arrStructDec); + for (int i = 0; i < ARRAY_SIZE; ++i) { + bb.put(testStringBytes); + bb.put((byte) 0); + bb.put(TEST_NUMBER); + } + + enumDec.add(0, 1, LEN); + enumDec.add(2, 3, FLOAT); + sDec.addField(ENUM, enumDec); + bb.put(TEST_NUMBER); + + sDec.addField(ARRAY_ENUM, arrEnumDec); + for (int i = 0; i < ARRAY_SIZE; ++i) { + bb.put(TEST_NUMBER); + } + + varDec.addField(LEN, intDec); + varDec.addField(FLOAT, flDec); + varDec.setTag(ENUM); + sDec.addField(VARIANT, varDec); + bb.putFloat(TEST_NUMBER); + + sDec.addField(ARRAY_VARIANT, arrVariantDec); + for (int i = 0; i < ARRAY_SIZE; ++i) { + bb.putFloat(TEST_NUMBER); + } + + fixture = sDec.createDefinition(fixture, ROOT, new BitBuffer(bb)); + + } + + /** + * Run the CtfTmfEventField parseField(Definition,String) method test. + */ + @Test + public void testParseField_float() { + FloatDefinition fieldDef = (FloatDefinition) fixture.lookupDefinition(FLOAT); + CtfTmfEventField result = CtfTmfEventField.parseField((IDefinition)fieldDef, "_" + NAME); + assertEquals("test=2.0", result.toString()); + } + + /** + * Run the CtfTmfEventField parseField(Definition,String) method test for an + * array of floats field. + */ + @Test + public void testParseField_array_float() { + IDefinition fieldDef = fixture.lookupArrayDefinition(ARRAY_FLOAT); + CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); + assertEquals("test=[2.0, 2.0]", result.toString()); + } + + /** + * Run the CtfTmfEventField parseField(Definition,String) method test. + */ + @Test + public void testParseField_int() { + IDefinition fieldDef = fixture.lookupDefinition(INT); + CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); + assertEquals("test=2", result.toString()); + } + + /** + * Run the CtfTmfEventField parseField(Definition,String) method test for an + * array of integers field. + */ + @Test + public void testParseField_array_int() { + IDefinition fieldDef = fixture.lookupArrayDefinition(ARRAY_INT); + CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); + assertEquals("test=[2, 2]", result.toString()); + } + + /** + * Run the CtfTmfEventField parseField(Definition,String) method test. + */ + @Test + public void testParseField_sequence() { + IDefinition fieldDef = fixture.lookupDefinition(SEQ); + CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); + assertEquals("test=[2, 2]", result.toString()); + } + + /** + * Run the CtfTmfEventField parseField(Definition,String) method test. + */ + @Test + public void testParseField_sequence_value() { + IDefinition fieldDef = fixture.lookupDefinition(SEQ); + CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); + long[] values = (long[]) result.getValue(); + long[] expected = new long[] { 2, 2 }; + assertArrayEquals(expected, values); + } + + /** + * Run the CtfTmfEventField parseField(Definition,String) method test. + */ + @Test + public void testParseField_string() { + IDefinition fieldDef = fixture.lookupDefinition(STR); + CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); + assertEquals("test=two", result.toString()); + } + + /** + * Run the CtfTmfEventField parseField(Definition,String) method test for an + * array of strings field. + */ + @Test + public void testParseField_array_string() { + IDefinition fieldDef = fixture.lookupArrayDefinition(ARRAY_STR); + CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); + assertEquals("test=[two, two]", result.toString()); + } + + /** + * Run the CtfTmfEventField parseField(Definition,String) method test. + */ + @Test + public void testParseField_struct() { + IDefinition fieldDef = fixture.lookupDefinition(STRUCT); + CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); + assertEquals("test=[str=two, int=2]", result.toString()); + } + + /** + * Run the CtfTmfEventField parseField(Definition,String) method test for an + * array of structs field. + */ + @Test + public void testParseField_array_struct() { + IDefinition fieldDef = fixture.lookupArrayDefinition(ARRAY_STRUCT); + CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); + assertEquals("test=[[str=two, int=2], [str=two, int=2]]", result.toString()); + } + + /** + * Run the CtfTmfEventField parseField(Definition,String) method test. + */ + @Test + public void testParseField_enum() { + IDefinition fieldDef = fixture.lookupDefinition(ENUM); + CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); + assertEquals("test=float", result.toString()); + } + + /** + * Run the CtfTmfEventField parseField(Definition,String) method test for an + * array of enums field. + */ + @Test + public void testParseField_array_enum() { + IDefinition fieldDef = fixture.lookupArrayDefinition(ARRAY_ENUM); + CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); + assertEquals("test=[float, float]", result.toString()); + } + + /** + * Run the CtfTmfEventField parseField(Definition,String) method test. + */ + @Test + public void testParseField_variant() { + IDefinition fieldDef = fixture.lookupDefinition(VARIANT); + CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); + assertEquals("test=float=2.0", result.toString()); + } + + /** + * Run the CtfTmfEventField parseField(Definition,String) method test for an + * array of variants field. + */ + @Test + public void testParseField_array_variant() { + IDefinition fieldDef = fixture.lookupArrayDefinition(ARRAY_VARIANT); + CtfTmfEventField result = CtfTmfEventField.parseField(fieldDef, NAME); + assertEquals("test=[float=2.0, float=2.0]", result.toString()); + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfEventTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfEventTest.java new file mode 100644 index 0000000000..10ec86188b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfEventTest.java @@ -0,0 +1,227 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial generation with CodePro tools + * Alexandre Montplaisir - Clean up, consolidate redundant tests + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assume.assumeTrue; + +import java.util.Collection; +import java.util.Set; + +import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.ctf.core.CtfIterator; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfEvent; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfEventFactory; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * The class CtfTmfEventTest contains tests for the class + * {@link CtfTmfEvent}. + * + * @author ematkho + * @version $Revision: 1.0 $ + */ +public class CtfTmfEventTest { + + private static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.KERNEL; + + private static CtfTmfEvent nullEvent; + private CtfTmfEvent fixture; + + /** + * Test class initialization + */ + @BeforeClass + public static void initialize() { + nullEvent = CtfTmfEventFactory.getNullEvent(); + } + + /** + * Perform pre-test initialization. + * + * @throws CTFReaderException + * error + */ + @Before + public void setUp() throws CTFReaderException { + assumeTrue(testTrace.exists()); + try (CtfTmfTrace trace = testTrace.getTrace(); + CtfIterator tr = new CtfIterator(trace);) { + tr.advance(); + fixture = tr.getCurrentEvent(); + } + } + + /** + * Run the CTFEvent(EventDefinition,StreamInputReader) constructor test. + */ + @Test + public void testCTFEvent_read() { + assertNotNull(fixture); + } + + /** + * Run the int getCPU() method test. + */ + @Test + public void testGetCPU() { + int result = nullEvent.getCPU(); + assertEquals(-1, result); + } + + /** + * Run the String getEventName() method test. + */ + @Test + public void testGetEventName() { + String result = nullEvent.getType().getName(); + assertEquals("Empty CTF event", result); + } + + /** + * Run the ArrayList getFieldNames() method test. + */ + @Test + public void testGetFieldNames() { + Collection result = fixture.getContent().getFieldNames(); + assertNotNull(result); + } + + /** + * Run the Object getFieldValue(String) method test. + */ + @Test + public void testGetFieldValue() { + String fieldName = "pid"; + ITmfEventField result = fixture.getContent().getField(fieldName); + + assertNotNull(result); + assertNotNull(result.getValue()); + } + + /** + * Run the HashMap getFields() method test. + */ + @Test + public void testGetFields() { + Collection fields = nullEvent.getContent().getFields(); + assertEquals(0, fields.size()); + } + + /** + * Run the ITmfEventField getSubFieldValue(String[]) method test. + */ + @Test + public void testGetSubFieldValue() { + /* Field exists */ + String[] names = { "pid" }; + assertNotNull(fixture.getContent().getSubField(names)); + + /* First field exists, not the second */ + String[] names2 = { "pid", "abcd" }; + assertNull(fixture.getContent().getSubField(names2)); + + /* Both field do not exist */ + String[] names3 = { "pfid", "abcd" }; + assertNull(fixture.getContent().getSubField(names3)); + + /* TODO Missing case of embedded field, need event for it */ + } + + /** + * Run the long getID() method test. + */ + @Test + public void testGetID() { + long result = nullEvent.getID(); + assertEquals(-1L, result); + } + + /** + * Run the long getTimestamp() method test. + */ + @Test + public void testGetTimestamp() { + long result = nullEvent.getTimestamp().getValue(); + assertEquals(-1L, result); + } + + /** + * Test the getters for the reference, source and type. + */ + @Test + public void testGetters() { + long rank = fixture.getRank(); + try (CtfTmfTrace trace = fixture.getTrace();) { + assertEquals("kernel", trace.getName()); + } + String reference = fixture.getReference(); + String source = fixture.getSource(); + ITmfEventType type = fixture.getType(); + assertEquals(ITmfContext.UNKNOWN_RANK, rank); + + assertEquals("channel0_1", reference); + assertEquals("1", source); + assertEquals("lttng_statedump_vm_map", type.toString()); + } + + /** + * Test the custom CTF attributes methods. The test trace doesn't have any, + * so the list of attributes should be empty. + */ + @Test + public void testCustomAttributes() { + Set attributes = fixture.listCustomAttributes(); + assertEquals(0, attributes.size()); + + String attrib = fixture.getCustomAttribute("bozo"); + assertNull(attrib); + } + + /** + * Test the toString() method + */ + @Test + public void testToString() { + String s = fixture.getContent().toString(); + assertEquals("pid=1922, start=0xb73ea000, end=0xb73ec000, flags=0x8000075, inode=917738, pgoff=0", s); + } + + /** + * Test the {@link CtfTmfEventFactory#getNullEvent()} method, and the + * nullEvent's values. + */ + @Test + public void testNullEvent() { + CtfTmfEvent nullEvent2 = CtfTmfEventFactory.getNullEvent(); + assertSame(nullEvent2, nullEvent); + assertNotNull(nullEvent); + assertEquals(-1, nullEvent.getCPU()); + assertEquals("Empty CTF event", nullEvent.getType().getName()); + assertNull(nullEvent.getReference()); + assertEquals(0, nullEvent.getContent().getFields().size()); + assertEquals(-1L, nullEvent.getID()); + assertEquals(-1L, nullEvent.getTimestamp().getValue()); + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfEventTypeTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfEventTypeTest.java new file mode 100644 index 0000000000..1c3ef134e5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfEventTypeTest.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial generation with CodePro tools + * Alexandre Montplaisir - Clean up, consolidate redundant tests + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfEventType; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; +import org.junit.Test; + +/** + * The class CtfTmfEventTypeTest contains tests for the class + * {@link CtfTmfEventType}. + * + * @author ematkho + * @version 1.0 + */ +public class CtfTmfEventTypeTest { + + /** + * Run the CtfTmfEventType(String,String,ITmfEventField) constructor test. + */ + @Test + public void testCtfTmfEventType() { + String eventName = ""; + ITmfEventField content = new TmfEventField("", null, new ITmfEventField[] {}); + CtfTmfEventType result = new CtfTmfEventType(eventName, new TmfTraceStub(), content); + + assertNotNull(result); + assertEquals("", result.toString()); + assertEquals("", result.getName()); + assertEquals("Ctf Event/null", result.getContext()); + } + + /** + * Run the String toString() method test. + */ + @Test + public void testToString() { + ITmfEventField emptyField = new TmfEventField("", null, new ITmfEventField[] {}); + CtfTmfEventType fixture = new CtfTmfEventType("", new TmfTraceStub() , emptyField); + + String result = fixture.toString(); + + assertEquals("", result); + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfLostEventStatisticsTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfLostEventStatisticsTest.java new file mode 100644 index 0000000000..338109be68 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfLostEventStatisticsTest.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + +import java.util.Map; + +import org.eclipse.linuxtools.ctf.core.CTFStrings; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.statistics.ITmfStatistics; +import org.eclipse.tracecompass.tmf.core.statistics.TmfStateStatistics; +import org.eclipse.tracecompass.tmf.core.statistics.TmfStatisticsEventTypesModule; +import org.eclipse.tracecompass.tmf.core.statistics.TmfStatisticsTotalsModule; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.rules.Timeout; + +/** + * Unit tests for handling of lost events by the statistics backends. + * + * @author Alexandre Montplaisir + */ +public class CtfTmfLostEventStatisticsTest { + + /** Time-out tests after 30 seconds */ + @Rule + public TestRule globalTimeout= new Timeout(30000); + + /**Test trace with lost events */ + private static final CtfTmfTestTrace lostEventsTrace = CtfTmfTestTrace.HELLO_LOST; + + private ITmfTrace fTrace; + + /** The statistics back-end object for the trace with lost events */ + private ITmfStatistics fStats; + + /* The two analysis modules needed for fStats */ + private TmfStatisticsTotalsModule fTotalsMod; + private TmfStatisticsEventTypesModule fEventTypesMod; + + // ------------------------------------------------------------------------ + // Maintenance + // ------------------------------------------------------------------------ + + /** + * Class setup + */ + @BeforeClass + public static void setUpClass() { + assumeTrue(lostEventsTrace.exists()); + } + + /** + * Test setup + */ + @Before + public void setUp() { + fTrace = lostEventsTrace.getTrace(); + + /* Prepare the two analysis-backed state systems */ + fTotalsMod = new TmfStatisticsTotalsModule(); + fEventTypesMod = new TmfStatisticsEventTypesModule(); + try { + fTotalsMod.setTrace(fTrace); + fEventTypesMod.setTrace(fTrace); + } catch (TmfAnalysisException e) { + fail(); + } + + fTotalsMod.schedule(); + fEventTypesMod.schedule(); + assertTrue(fTotalsMod.waitForCompletion()); + assertTrue(fEventTypesMod.waitForCompletion()); + + ITmfStateSystem totalsSS = fTotalsMod.getStateSystem(); + ITmfStateSystem eventTypesSS = fEventTypesMod.getStateSystem(); + assertNotNull(totalsSS); + assertNotNull(eventTypesSS); + + fStats = new TmfStateStatistics(totalsSS, eventTypesSS); + } + + /** + * Test cleanup + */ + @After + public void tearDown() { + fStats.dispose(); + fTotalsMod.close(); + fEventTypesMod.close(); + fTrace.dispose(); + } + + // ------------------------------------------------------------------------ + // Test methods + // ------------------------------------------------------------------------ + + /* + * Trace start = 1376592664828559410 + * Trace end = 1376592665108210547 + */ + + private static final long rangeStart = 1376592664900000000L; + private static final long rangeEnd = 1376592665000000000L; + + /** + * Test the total number of "real" events. Make sure the lost events aren't + * counted in the total. + */ + @Test + public void testLostEventsTotals() { + long realEvents = fStats.getEventsTotal(); + assertEquals(32300, realEvents); + } + + /** + * Test the number of real events in a given range. Lost events shouldn't be + * counted. + */ + @Test + public void testLostEventsTotalInRange() { + long realEventsInRange = fStats.getEventsInRange(rangeStart, rangeEnd); + assertEquals(11209L, realEventsInRange); + } + + /** + * Test the total number of lost events reported in the trace. + */ + @Test + public void testLostEventsTypes() { + Map events = fStats.getEventTypesTotal(); + Long lostEvents = events.get(CTFStrings.LOST_EVENT_NAME); + assertEquals(Long.valueOf(967700L), lostEvents); + } + + /** + * Test the number of lost events reported in a given range. + */ + @Test + public void testLostEventsTypesInRange() { + Map eventsInRange = fStats.getEventTypesInRange(rangeStart, rangeEnd); + long lostEventsInRange = eventsInRange.get(CTFStrings.LOST_EVENT_NAME); + assertEquals(363494L, lostEventsInRange); + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfLostEventsTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfLostEventsTest.java new file mode 100644 index 0000000000..de67ea5c31 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfLostEventsTest.java @@ -0,0 +1,256 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfLostEvent; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfEvent; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTimestamp; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests to verify that lost events are handled correctly. + * + * Be wary if you are using Babeltrace to cross-check those values. There could + * be a bug in Babeltrace with regards to lost events. See + * http://bugs.lttng.org/issues/589 + * + * It's not 100% sure at this point which implementation is correct, so for now + * these tests assume the Java implementation is the right one. + * + * @author Alexandre Montplaisir + */ +public class CtfTmfLostEventsTest { + + private static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.HELLO_LOST; + + private CtfTmfTrace fixture = null; + + /** + * Class setup + */ + @Before + public void setUp() { + assumeTrue(testTrace.exists()); + fixture = testTrace.getTrace(); + fixture.indexTrace(true); + } + + /** + * Clean-up + */ + @After + public void tearDown() { + if (fixture != null) { + fixture.dispose(); + } + } + + // ------------------------------------------------------------------------ + // Test methods + // ------------------------------------------------------------------------ + + /** + * Test that the number of events is reported correctly (a range of lost + * events is counted as one event). + */ + @Test + public void testNbEvents() { + final long expectedReal = 32300; + final long expectedLost = 562; + + EventCountRequest req = new EventCountRequest(); + fixture.sendRequest(req); + try { + req.waitForCompletion(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + assertEquals(expectedReal, req.getReal()); + assertEquals(expectedLost, req.getLost()); + } + + /** + * Test getting the first lost event from the trace. + */ + @Test + public void testFirstLostEvent() { + final long rank = 153; + final ITmfTimestamp start = new CtfTmfTimestamp(1376592664828848222L); + final ITmfTimestamp end = new CtfTmfTimestamp(1376592664828848540L); + final long nbLost = 859; + + final CtfTmfEvent ev = getOneEventTime(start); + /* Make sure seeking by rank yields the same event */ + final CtfTmfEvent ev2 = getOneEventRank(rank); + assertEquals(ev, ev2); + + assertTrue(ev instanceof ITmfLostEvent); + ITmfLostEvent event = (ITmfLostEvent) ev; + + assertEquals(start, event.getTimestamp()); + assertEquals(start, event.getTimeRange().getStartTime()); + assertEquals(end, event.getTimeRange().getEndTime()); + assertEquals(nbLost, event.getNbLostEvents()); + } + + /** + * Test getting the second lost event from the trace. + */ + @Test + public void testSecondLostEvent() { + final long rank = 191; + final ITmfTimestamp start = new CtfTmfTimestamp(1376592664829402521L); + final ITmfTimestamp end = new CtfTmfTimestamp(1376592664829403076L); + final long nbLost = 488; + + final CtfTmfEvent ev = getOneEventTime(start); + /* Make sure seeking by rank yields the same event */ + final CtfTmfEvent ev2 = getOneEventRank(rank); + assertEquals(ev, ev2); + + assertTrue(ev instanceof ITmfLostEvent); + ITmfLostEvent event = (ITmfLostEvent) ev; + + assertEquals(start, event.getTimestamp()); + assertEquals(start, event.getTimeRange().getStartTime()); + assertEquals(end, event.getTimeRange().getEndTime()); + assertEquals(nbLost, event.getNbLostEvents()); + } + + /** + * Test getting one normal event from the trace (lost events should not + * interfere). + */ + @Test + public void testNormalEvent() { + final long rank = 200; + final ITmfTimestamp ts = new CtfTmfTimestamp(1376592664829423928L); + + final CtfTmfEvent event = getOneEventTime(ts); + /* Make sure seeking by rank yields the same event */ + final CtfTmfEvent event2 = getOneEventRank(rank); + assertEquals(event, event2); + + assertFalse(event instanceof ITmfLostEvent); + assertEquals(ts, event.getTimestamp()); + } + + // ------------------------------------------------------------------------ + // Event requests + // ------------------------------------------------------------------------ + + private CtfTmfEvent getOneEventRank(long rank) { + OneEventRequestPerRank req = new OneEventRequestPerRank(rank); + fixture.sendRequest(req); + try { + req.waitForCompletion(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return req.getEvent(); + } + + private CtfTmfEvent getOneEventTime(ITmfTimestamp ts) { + OneEventRequestPerTs req = new OneEventRequestPerTs(ts); + fixture.sendRequest(req); + try { + req.waitForCompletion(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return req.getEvent(); + } + + private class OneEventRequestPerRank extends TmfEventRequest { + + private CtfTmfEvent event = null; + + public OneEventRequestPerRank(long rank) { + super(CtfTmfEvent.class, TmfTimeRange.ETERNITY, rank, 1, ExecutionType.FOREGROUND); + } + + @Override + public void handleData(ITmfEvent ev) { + /* Type is checked by the request, cast should be safe */ + event = (CtfTmfEvent) ev; + } + + public CtfTmfEvent getEvent() { + return event; + } + } + + private class OneEventRequestPerTs extends TmfEventRequest { + + private CtfTmfEvent event = null; + + public OneEventRequestPerTs(ITmfTimestamp ts) { + super(CtfTmfEvent.class, + new TmfTimeRange(ts, TmfTimestamp.PROJECT_IS_CANNED), + 0, 1, ExecutionType.FOREGROUND); + } + + @Override + public void handleData(ITmfEvent ev) { + event = (CtfTmfEvent) ev; + } + + public CtfTmfEvent getEvent() { + return event; + } + } + + private class EventCountRequest extends TmfEventRequest { + + private long nbReal = 0; + private long nbLost = 0; + + public EventCountRequest() { + super(CtfTmfEvent.class, TmfTimeRange.ETERNITY, 0, + ITmfEventRequest.ALL_DATA, ExecutionType.FOREGROUND); + } + + @Override + public void handleData(ITmfEvent event) { + if (event instanceof ITmfLostEvent) { + nbLost++; + } else { + nbReal++; + } + } + + public long getReal() { + return nbReal; + } + + public long getLost() { + return nbLost; + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfTimestampTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfTimestampTest.java new file mode 100644 index 0000000000..161d3b7f40 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfTimestampTest.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial generation with CodePro tools + * Alexandre Montplaisir - Clean up, consolidate redundant tests + * Patrick Tasse - Fix for local time zone + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTimestamp; +import org.junit.Test; + +/** + * The class CtfTmfTimestampTest contains tests for the class + * {@link CtfTmfTimestamp}. + * + * @author ematkho + * @version 1.0 + */ +public class CtfTmfTimestampTest { + + /** + * Run the CtfTmfTimestamp(long) constructor test. + */ + @Test + public void testCtfTmfTimestamp() { + long timestamp = 1L; + DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS"); + Date d = new Date(timestamp / 1000000); + + CtfTmfTimestamp result = new CtfTmfTimestamp(timestamp); + + assertNotNull(result); + assertEquals(df.format(d) + " 000 001", result.toString()); + assertEquals(0, result.getPrecision()); + assertEquals(-9, result.getScale()); + assertEquals(1L, result.getValue()); + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfTraceTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfTraceTest.java new file mode 100644 index 0000000000..b9eba8521a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/CtfTmfTraceTest.java @@ -0,0 +1,393 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial generation with CodePro tools + * Alexandre Montplaisir - Clean up, consolidate redundant tests + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.signal.TmfEndSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.TmfEventTypeCollectionHelper; +import org.eclipse.tracecompass.tmf.ctf.core.CtfLocation; +import org.eclipse.tracecompass.tmf.ctf.core.CtfLocationInfo; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfEvent; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTimestamp; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * The class CtfTmfTraceTest contains tests for the class + * {@link CtfTmfTrace}. + * + * @author ematkho + * @version 1.0 + */ +public class CtfTmfTraceTest { + + private static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.KERNEL; + + private CtfTmfTrace fixture; + + /** + * Perform pre-test initialization. + * + * @throws TmfTraceException + * If the test trace is not found + */ + @Before + public void setUp() throws TmfTraceException { + assumeTrue(testTrace.exists()); + fixture = new CtfTmfTrace(); + fixture.initTrace((IResource) null, testTrace.getPath(), CtfTmfEvent.class); + } + + /** + * Perform post-test clean-up. + */ + @After + public void tearDown() { + if (fixture != null) { + fixture.dispose(); + } + } + + /** + * Run the CtfTmfTrace() constructor test. + */ + @Test + public void testCtfTmfTrace() { + try (CtfTmfTrace result = new CtfTmfTrace();) { + assertNotNull(result); + assertEquals(1000, result.getCacheSize()); + assertEquals(0L, result.getNbEvents()); + assertEquals(0L, result.getStreamingInterval()); + assertNull(result.getResource()); + assertNull(result.getType()); + } + } + + /** + * Test the parseEvent() method + */ + @Test + public void testParseEvent() { + ITmfContext ctx = fixture.seekEvent(0); + fixture.getNext(ctx); + CtfTmfEvent event = fixture.parseEvent(ctx); + assertNotNull(event); + } + + /** + * Run the void broadcast(TmfSignal) method test. + */ + @Test + public void testBroadcast() { + TmfSignal signal = new TmfEndSynchSignal(1); + fixture.broadcast(signal); + } + + /** + * Run the void dispose() method test. + */ + @Test + public void testClose() { + try (CtfTmfTrace emptyFixture = new CtfTmfTrace();) { + } + } + + /** + * Run the int getCacheSize() method test. + */ + @Test + public void testGetCacheSize() { + try (CtfTmfTrace emptyFixture = new CtfTmfTrace();) { + int result = emptyFixture.getCacheSize(); + assertEquals(1000, result); + } + } + + /** + * Run the ITmfLocation getCurrentLocation() method test. + */ + @Test + public void testGetCurrentLocation() { + CtfLocation result = (CtfLocation) fixture.getCurrentLocation(); + assertNull(result); + } + + /** + * Test the seekEvent() method with a null location. + */ + @Test + public void testSeekEventLoc_null() { + CtfLocation loc = null; + fixture.seekEvent(loc); + assertNotNull(fixture); + } + + /** + * Test the seekEvent() method with a location from a timestamp. + */ + @Test + public void testSeekEventLoc_timetamp() { + CtfLocation loc = new CtfLocation(new CtfTmfTimestamp(0L)); + fixture.seekEvent(loc); + assertNotNull(fixture); + } + + /** + * Run the ITmfTimestamp getEndTime() method test. + */ + @Test + public void testGetEndTime() { + ITmfTimestamp result = fixture.getEndTime(); + assertNotNull(result); + } + + /** + * Run the String getEnvironment method test. + */ + @Test + public void testGetEnvValue() { + String key = "tracer_name"; + String result = fixture.getTraceProperties().get(key); + assertEquals("\"lttng-modules\"", result); + } + + /** + * Test the {@link CtfTmfTrace#getEventType()} method. + */ + @Test + public void testGetEventType() { + Class result = fixture.getEventType(); + assertNotNull(result); + assertEquals(CtfTmfEvent.class, result); + } + + /** + * Run the Class getContainedEventTypes() method test. + */ + @Test + public void testGetContainedEventTypes() { + Set result = fixture.getContainedEventTypes(); + assertNotNull(result); + assertFalse(result.isEmpty()); + } + + /** + * Run the double getLocationRatio(ITmfLocation) method test. + */ + @Test + public void testGetLocationRatio() { + final CtfLocationInfo location2 = new CtfLocationInfo(1, 0); + CtfLocation location = new CtfLocation(location2); + double result = fixture.getLocationRatio(location); + + assertEquals(Double.NEGATIVE_INFINITY, result, 0.1); + } + + /** + * Run the String getName() method test. + */ + @Test + public void testGetName() { + String result = fixture.getName(); + assertNotNull(result); + } + + /** + * Run the getTraceProperties() method test. + */ + @Test + public void testGetTraceProperties() { + int result = fixture.getTraceProperties().size(); + assertEquals(9, result); + } + + /** + * Run the long getNbEvents() method test. + */ + @Test + public void testGetNbEvents() { + long result = fixture.getNbEvents(); + assertEquals(1L, result); + } + + /** + * Run the CtfTmfEvent getNext(ITmfContext) method test. + */ + @Test + public void testGetNext() { + ITmfContext context = fixture.seekEvent(0); + CtfTmfEvent result = fixture.getNext(context); + assertNotNull(result); + } + + /** + * Run the String getPath() method test. + */ + @Test + public void testGetPath() { + String result = fixture.getPath(); + assertNotNull(result); + } + + /** + * Run the IResource getResource() method test. + */ + @Test + public void testGetResource() { + IResource result = fixture.getResource(); + assertNull(result); + } + + /** + * Run the ITmfTimestamp getStartTime() method test. + */ + @Test + public void testGetStartTime() { + ITmfTimestamp result = fixture.getStartTime(); + assertNotNull(result); + } + + /** + * Run the long getStreamingInterval() method test. + */ + @Test + public void testGetStreamingInterval() { + long result = fixture.getStreamingInterval(); + assertEquals(0L, result); + } + + /** + * Run the TmfTimeRange getTimeRange() method test. + */ + @Test + public void testGetTimeRange() { + TmfTimeRange result = fixture.getTimeRange(); + assertNotNull(result); + } + + /** + * Run the CtfTmfEvent readNextEvent(ITmfContext) method test. + */ + @Test + public void testReadNextEvent() { + ITmfContext context = fixture.seekEvent(0); + CtfTmfEvent result = fixture.getNext(context); + assertNotNull(result); + } + + /** + * Run the ITmfContext seekEvent(double) method test. + */ + @Test + public void testSeekEvent_ratio() { + double ratio = 0.99; + ITmfContext result = fixture.seekEvent(ratio); + assertNotNull(result); + } + + /** + * Run the ITmfContext seekEvent(long) method test. + */ + @Test + public void testSeekEvent_rank() { + long rank = 1L; + ITmfContext result = fixture.seekEvent(rank); + assertNotNull(result); + } + + /** + * Run the ITmfContext seekEvent(ITmfTimestamp) method test. + */ + @Test + public void testSeekEvent_timestamp() { + ITmfTimestamp timestamp = new TmfTimestamp(); + ITmfContext result = fixture.seekEvent(timestamp); + assertNotNull(result); + } + + /** + * Run the ITmfContext seekEvent(ITmfLocation) method test. + */ + @Test + public void testSeekEvent_location() { + final CtfLocationInfo location2 = new CtfLocationInfo(1L, 0L); + CtfLocation ctfLocation = new CtfLocation(location2); + ITmfContext result = fixture.seekEvent(ctfLocation); + assertNotNull(result); + } + + /** + * Run the boolean validate(IProject,String) method test. + */ + @Test + public void testValidate() { + IProject project = null; + IStatus result = fixture.validate(project, testTrace.getPath()); + assertTrue(result.isOK()); + } + + /** + * Run the boolean hasEvent(final String) method test + */ + @Test + public void testEventLookup() { + Set eventTypes = fixture.getContainedEventTypes(); + Set eventNames = TmfEventTypeCollectionHelper.getEventNames(eventTypes); + assertTrue(eventNames.contains("sched_switch")); + assertFalse(eventNames.contains("Sched_switch")); + String[] events = { "sched_switch", "sched_wakeup", "timer_init" }; + assertTrue(eventNames.containsAll(Arrays.asList(events))); + Set copy = new HashSet<>(eventNames); + copy.retainAll(Arrays.asList(events)); + assertFalse(copy.isEmpty()); + String[] names = { "inexistent", "sched_switch", "SomeThing" }; + copy = new HashSet<>(eventNames); + copy.retainAll(Arrays.asList(names)); + assertTrue(!copy.isEmpty()); + assertFalse(eventNames.containsAll(Arrays.asList(names))); + } + + /** + * Run the String getHostId() method test + */ + @Test + public void testCtfHostId() { + String a = fixture.getHostId(); + assertEquals("\"84db105b-b3f4-4821-b662-efc51455106a\"", a); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/EventContextTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/EventContextTest.java new file mode 100644 index 0000000000..2791fa663f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/EventContextTest.java @@ -0,0 +1,241 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assume.assumeTrue; + +import org.eclipse.core.resources.IResource; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfEvent; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTimestamp; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests for reading event contexts from a CtfTmfTrace. + * + * @author Alexandre Montplaisir + */ +public class EventContextTest { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /* We use test trace #2, kernel_vm, which has event contexts */ + private static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.KERNEL_VM; + + private CtfTmfTrace fixture; + private long startTime; + private long endTime; + + // ------------------------------------------------------------------------ + // Class methods + // ------------------------------------------------------------------------ + + /** + * Perform pre-class initialization. + * + * @throws TmfTraceException + * If the test trace is not found + */ + @Before + public void setUp() throws TmfTraceException { + assumeTrue(testTrace.exists()); + fixture = new CtfTmfTrace(); + fixture.initTrace((IResource) null, testTrace.getPath(), CtfTmfEvent.class); + fixture.indexTrace(true); + + startTime = fixture.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + endTime = fixture.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + } + + /** + * Perform post-class clean-up. + */ + @After + public void tearDown() { + if (fixture != null) { + fixture.dispose(); + } + } + + // ------------------------------------------------------------------------ + // Test methods + // ------------------------------------------------------------------------ + + /** + * Make sure the trace is the correct one, and its timestamps are read + * correctly. + */ + @Test + public void testTrace() { + assertEquals(1363700740555978750L, startTime); + assertEquals(1363700770550261288L, endTime); + } + + /** + * Test the context of the very first event of the trace. + */ + @Test + public void testContextStart() { + CtfTmfEvent firstEvent = getEventAt(startTime); + long perfPageFault = (Long) firstEvent.getContent().getField("context._perf_page_fault").getValue(); + String procname = (String) firstEvent.getContent().getField("context._procname").getValue(); + long tid = (Long) firstEvent.getContent().getField("context._tid").getValue(); + + assertEquals(613, perfPageFault); + assertEquals("lttng-sessiond", procname); + assertEquals(1230, tid); + } + + /** + * Test the context of the event at 1363700745.559739078. + */ + @Test + public void testContext1() { + long time = startTime + 5000000000L; // 1363700745.559739078 + CtfTmfEvent event = getEventAt(time); + long perfPageFault = (Long) event.getContent().getField("context._perf_page_fault").getValue(); + String procname = (String) event.getContent().getField("context._procname").getValue(); + long tid = (Long) event.getContent().getField("context._tid").getValue(); + + assertEquals(6048, perfPageFault); + assertEquals("swapper/0", procname); + assertEquals(0, tid); + } + + /** + * Test the context of the event at 1363700750.559707062. + */ + @Test + public void testContext2() { + long time = startTime + 2 * 5000000000L; // 1363700750.559707062 + CtfTmfEvent event = getEventAt(time); + long perfPageFault = (Long) event.getContent().getField("context._perf_page_fault").getValue(); + String procname = (String) event.getContent().getField("context._procname").getValue(); + long tid = (Long) event.getContent().getField("context._tid").getValue(); + + assertEquals(13258, perfPageFault); + assertEquals("swapper/0", procname); + assertEquals(0, tid); + } + + /** + * Test the context of the event at 1363700755.555723128, which is roughly + * mid-way through the trace. + */ + @Test + public void testContextMiddle() { + long midTime = startTime + (endTime - startTime) / 2L; // 1363700755.555723128 + CtfTmfEvent midEvent = getEventAt(midTime); + long perfPageFault = (Long) midEvent.getContent().getField("context._perf_page_fault").getValue(); + String procname = (String) midEvent.getContent().getField("context._procname").getValue(); + long tid = (Long) midEvent.getContent().getField("context._tid").getValue(); + + assertEquals(19438, perfPageFault); + assertEquals("swapper/0", procname); + assertEquals(0, tid); + } + + /** + * Test the context of the event at 1363700760.559719724. + */ + @Test + public void testContext3() { + long time = startTime + 4 * 5000000000L; // 1363700760.559719724 + CtfTmfEvent event = getEventAt(time); + long perfPageFault = (Long) event.getContent().getField("context._perf_page_fault").getValue(); + String procname = (String) event.getContent().getField("context._procname").getValue(); + long tid = (Long) event.getContent().getField("context._tid").getValue(); + + assertEquals(21507, perfPageFault); + assertEquals("swapper/0", procname); + assertEquals(0, tid); + } + + /** + * Test the context of the event at 1363700765.559714634. + */ + @Test + public void testContext4() { + long time = startTime + 5 * 5000000000L; // 1363700765.559714634 + CtfTmfEvent event = getEventAt(time); + long perfPageFault = (Long) event.getContent().getField("context._perf_page_fault").getValue(); + String procname = (String) event.getContent().getField("context._procname").getValue(); + long tid = (Long) event.getContent().getField("context._tid").getValue(); + + assertEquals(21507, perfPageFault); + assertEquals("swapper/0", procname); + assertEquals(0, tid); + } + + /** + * Test the context of the last event of the trace. + */ + @Test + public void testContextEnd() { + CtfTmfEvent lastEvent = getEventAt(endTime); + long perfPageFault = (Long) lastEvent.getContent().getField("context._perf_page_fault").getValue(); + String procname = (String) lastEvent.getContent().getField("context._procname").getValue(); + long tid = (Long) lastEvent.getContent().getField("context._tid").getValue(); + + assertEquals(22117, perfPageFault); + assertEquals("lttng-sessiond", procname); + assertEquals(1230, tid); + } + + // ------------------------------------------------------------------------ + // Private stuff + // ------------------------------------------------------------------------ + + private synchronized CtfTmfEvent getEventAt(long timestamp) { + EventContextTestRequest req = new EventContextTestRequest(timestamp); + fixture.sendRequest(req); + try { + req.waitForCompletion(); + } catch (InterruptedException e) { + return null; + } + return req.getEvent(); + } + + private class EventContextTestRequest extends TmfEventRequest { + + private CtfTmfEvent retEvent = null; + + public EventContextTestRequest(long timestamp) { + super(CtfTmfEvent.class, + new TmfTimeRange(new CtfTmfTimestamp(timestamp), TmfTimestamp.BIG_CRUNCH), + 0, 1, ExecutionType.FOREGROUND); + } + + @Override + public void handleData(ITmfEvent event) { + retEvent = (CtfTmfEvent) event; + } + + public CtfTmfEvent getEvent() { + return retEvent; + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/FunkyTraceTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/FunkyTraceTest.java new file mode 100644 index 0000000000..f86236f064 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/FunkyTraceTest.java @@ -0,0 +1,212 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assume.assumeTrue; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.ctf.core.CtfEnumPair; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfEvent; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.rules.Timeout; + +/** + * More advanced CTF tests using "funky_trace", a trace generated with the + * Babeltrace CTF writer API, which has lots of fun things like different + * integer/float sizes and non-standard struct alignments. + * + * @author Alexandre Montplaisir + */ +public class FunkyTraceTest { + + /** Time-out tests after 20 seconds */ + @Rule + public TestRule globalTimeout= new Timeout(20000); + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.FUNKY_TRACE; + private static final double DELTA = 0.0000001; + + private CtfTmfTrace fTrace; + + // ------------------------------------------------------------------------ + // Setup + // ------------------------------------------------------------------------ + + /** + * Test setup + */ + @Before + public void setup() { + assumeTrue(testTrace.exists()); + fTrace = testTrace.getTrace(); + fTrace.indexTrace(true); + } + + /** + * Clean-up + */ + @After + public void tearDown() { + if (fTrace != null) { + fTrace.dispose(); + } + } + + // ------------------------------------------------------------------------ + // Test methods + // ------------------------------------------------------------------------ + + /** + * Verify the contents of the first event + */ + @Test + public void testFirstEvent() { + CtfTmfEvent event = getEvent(0); + assertEquals("Simple Event", event.getType().getName()); + assertEquals(1234567, event.getTimestamp().getValue()); + assertEquals(42, ((Long) event.getContent().getField("integer_field").getValue()).intValue()); + assertEquals(3.1415, ((Double) event.getContent().getField("float_field").getValue()).doubleValue(), DELTA); + } + + /** + * Verify the contents of the second event (the first "spammy event") + */ + @Test + public void testSecondEvent() { + CtfTmfEvent event = getEvent(1); + assertEquals("Spammy_Event", event.getType().getName()); + assertEquals(1234568, event.getTimestamp().getValue()); + assertEquals(0, ((Long) event.getContent().getField("field_1").getValue()).intValue()); + assertEquals("This is a test", event.getContent().getField("a_string").getValue()); + } + + /** + * Verify the contents of the last "spammy event" + */ + @Test + public void testSecondToLastEvent() { + CtfTmfEvent event = getEvent(100000); + assertEquals("Spammy_Event", event.getType().getName()); + assertEquals(1334567, event.getTimestamp().getValue()); + assertEquals(99999, ((Long) event.getContent().getField("field_1").getValue()).intValue()); + assertEquals("This is a test", event.getContent().getField("a_string").getValue()); + } + + /** + * Verify the contents of the last, complex event + */ + @Test + public void testLastEvent() { + /* + * Last event as seen in Babeltrace: + * [19:00:00.001334568] (+0.000000001) Complex Test Event: { }, { + * uint_35 = 0xDDF00D, + * int_16 = -12345, + * complex_structure = { + * variant_selector = ( INT16_TYPE : container = 1 ), + * a_string = "Test string", + * variant_value = { INT16_TYPE = -200 }, + * inner_structure = { + * seq_len = 0xA, + * a_sequence = [ [0] = 4, [1] = 3, [2] = 2, [3] = 1, [4] = 0, [5] = -1, [6] = -2, [7] = -3, [8] = -4, [9] = -5 ] + * } + * } + * } + */ + + CtfTmfEvent event = getEvent(100001); + assertEquals("Complex Test Event", event.getType().getName()); + assertEquals(1334568, event.getTimestamp().getValue()); + assertEquals(0xddf00d, ((Long) event.getContent().getField("uint_35").getValue()).intValue()); + assertEquals(-12345, ((Long) event.getContent().getField("int_16").getValue()).intValue()); + + ITmfEventField[] complexStruct = + (ITmfEventField[]) event.getContent().getField("complex_structure").getValue(); + + assertEquals("variant_selector", complexStruct[0].getName()); + CtfEnumPair variant1 = (CtfEnumPair) complexStruct[0].getValue(); + assertEquals("INT16_TYPE", variant1.getStringValue()); + assertEquals(Long.valueOf(1), variant1.getLongValue()); + + assertEquals("a_string", complexStruct[1].getName()); + assertEquals("Test string", complexStruct[1].getValue()); + + assertEquals("variant_value", complexStruct[2].getName()); + ITmfEventField variantField = (ITmfEventField) complexStruct[2].getValue(); + assertEquals("INT16_TYPE", variantField.getName()); + assertEquals(Long.valueOf(-200), variantField.getValue()); + + ITmfEventField[] innerStruct = (ITmfEventField[]) complexStruct[3].getValue(); + + assertEquals("seq_len", innerStruct[0].getName()); + assertEquals(Long.valueOf(10), innerStruct[0].getValue()); + + assertEquals("a_sequence", innerStruct[1].getName()); + long[] seqValues = (long[]) innerStruct[1].getValue(); + long[] expectedValues = { 4, 3, 2, 1, 0, -1, -2, -3, -4, -5 }; + assertArrayEquals(expectedValues, seqValues); + } + + // ------------------------------------------------------------------------ + // Private stuff + // ------------------------------------------------------------------------ + + private synchronized CtfTmfEvent getEvent(long index) { + TestEventRequest req = new TestEventRequest(index); + fTrace.sendRequest(req); + try { + req.waitForCompletion(); + } catch (InterruptedException e) { + return null; + } + return req.getEvent(); + } + + private class TestEventRequest extends TmfEventRequest { + + private CtfTmfEvent fRetEvent = null; + + public TestEventRequest(long index) { + super(CtfTmfEvent.class, + TmfTimeRange.ETERNITY, + index, + 1, + ExecutionType.FOREGROUND); + } + + @Override + public void handleData(ITmfEvent event) { + fRetEvent = (CtfTmfEvent) event; + } + + public CtfTmfEvent getEvent() { + return fRetEvent; + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/headless/Benchmark.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/headless/Benchmark.java new file mode 100644 index 0000000000..5d9f31e4e9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/headless/Benchmark.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests.headless; + +import java.util.Vector; + +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfContext; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfEvent; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; + +/** + * Test and benchmark reading a CTF LTTng kernel trace. + * + * @author Matthew Khouzam + */ +public class Benchmark { + + /** + * Run the benchmark. + * + * @param args The command-line arguments + */ + public static void main(final String[] args) { + final String TRACE_PATH = "testfiles/kernel"; + final int NUM_LOOPS = 100; + + // Change this to enable text output + final boolean USE_TEXT = true; + + // Work variables + long nbEvent = 0L; + final Vector benchs = new Vector<>(); + long start, stop; + for (int loops = 0; loops < NUM_LOOPS; loops++) { + nbEvent = 0L; + try (CtfTmfTrace trace = new CtfTmfTrace();) { + try { + trace.initTrace(null, TRACE_PATH, CtfTmfEvent.class); + } catch (final TmfTraceException e) { + loops = NUM_LOOPS + 1; + break; + } + + start = System.nanoTime(); + if (nbEvent != -1) { + final CtfTmfContext traceReader = (CtfTmfContext) trace.seekEvent(0); + + start = System.nanoTime(); + CtfTmfEvent current = traceReader.getCurrentEvent(); + while (current != null) { + nbEvent++; + if (USE_TEXT) { + + System.out.println("Event " + nbEvent + " Time " + + current.getTimestamp().toString() + " type " + current.getType().getName() + + " on CPU " + current.getSource() + " " + current.getContent().toString()); + } + // advance the trace to the next event. + boolean hasMore = traceReader.advance(); + if (hasMore) { + // you can know the trace has more events. + } + current = traceReader.getCurrentEvent(); + } + } + stop = System.nanoTime(); + System.out.print('.'); + final double time = (stop - start) / (double) nbEvent; + benchs.add(time); + } // trace.close() + } + System.out.println(""); + double avg = 0; + for (final double val : benchs) { + avg += val; + } + avg /= benchs.size(); + System.out.println("Time to read = " + avg + " events/ns"); + for (final Double val : benchs) { + System.out.print(val); + System.out.print(", "); + } + + } + +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/headless/RequestBenchmark.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/headless/RequestBenchmark.java new file mode 100644 index 0000000000..ae1be87f5d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/headless/RequestBenchmark.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * William Bourque - Initial API and implementation + * Matthew Khouzam - Update to CtfTmf trace and events + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests.headless; + +import java.util.Vector; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfEvent; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; + +/** + * Benchmark the event request subsystem of TMF. + */ +public class RequestBenchmark extends TmfEventRequest { + + private RequestBenchmark(final Class dataType, + final TmfTimeRange range, final int nbRequested) { + super(dataType, range, 0, nbRequested, ExecutionType.FOREGROUND); + } + + // Path of the trace + private static final String TRACE_PATH = "../org.eclipse.linuxtools.ctf.core.tests/traces/kernel"; + + // Change this to run several time over the same trace + private static final int NB_OF_PASS = 100; + + // Work variables + private static int nbEvent = 0; + private static TmfExperiment fExperiment = null; + private static Vector benchs = new Vector<>(); + + /** + * Run the benchmark + * + * @param args + * The command-line arguments + */ + public static void main(final String[] args) { + + try { + /* Our experiment will contains ONE trace */ + final ITmfTrace[] traces = new ITmfTrace[1]; + traces[0] = new CtfTmfTrace(); + traces[0].initTrace(null, TRACE_PATH, CtfTmfEvent.class); + /* Create our new experiment */ + fExperiment = new TmfExperiment(CtfTmfEvent.class, "Headless", traces); + + /* + * We will issue a request for each "pass". TMF will then process + * them synchronously. + */ + RequestBenchmark request = null; + for (int x = 0; x < NB_OF_PASS; x++) { + request = new RequestBenchmark(CtfTmfEvent.class, + TmfTimeRange.ETERNITY, Integer.MAX_VALUE); + fExperiment.sendRequest(request); + } + prev = System.nanoTime(); + } catch (final NullPointerException e) { + /* + * Silently dismiss Null pointer exception The only way to "finish" + * the threads in TMF is by crashing them with null. + */ + } catch (final Exception e) { + e.printStackTrace(); + } + + } + + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + nbEvent++; + + } + + static long prev; + static long done = 0; + @Override + public void handleCompleted() { + final long next = System.nanoTime(); + double val = next - prev; + final int nbEvent2 = nbEvent; + val /= nbEvent2; + + nbEvent = 0; + prev = next; + benchs.add(val); + if (benchs.size() == NB_OF_PASS) { + try { + System.out.println("Nb events : " + nbEvent2); + + for (final double value : benchs) { + System.out.print(value + ", "); + } + fExperiment.sendRequest(null); + + } catch (final Exception e) { + } + } + } + + @Override + public void handleSuccess() { + } + + @Override + public void handleFailure() { + } + + @Override + public void handleCancel() { + } + +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/request/AllTests.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/request/AllTests.java new file mode 100644 index 0000000000..7708dbfd48 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/request/AllTests.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests.request; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TmfSchedulerTest.class +}) +public class AllTests {} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/request/TmfSchedulerBenchmark.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/request/TmfSchedulerBenchmark.java new file mode 100644 index 0000000000..501feb5e9c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/request/TmfSchedulerBenchmark.java @@ -0,0 +1,360 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Simon Delisle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests.request; + +import java.io.PrintWriter; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; + +/** + * Benchmark for the request scheduler + * + * The benchmark has three tests. The first one is the latency (time between the + * creation of the request and the beginning of its execution). The second one + * is the average waiting time for a request. The last one is the total + * completion time. + */ +public class TmfSchedulerBenchmark { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + private static final int NUM_LOOPS = 10; + private static final int NANOSECONDS_IN_MILLISECONDS = 1000000; + private static final int NANOSECONDS_IN_SECONDS = 1000000000; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private static CtfTmfTrace trace = CtfTmfTestTrace.KERNEL.getTrace(); + private static ForegroundRequest lastForegroundRequest = null; + private static BackgroundRequest lastBackgroundRequest = null; + + private static PrintWriter pw = new PrintWriter(System.out, true); + + /** + * Start the benchmark + * + * @param args + * The command-line arguments + */ + public static void main(final String[] args) { + trace.indexTrace(true); + pw.println("---------- Benchmark started ----------"); + latencyBenchmark(); + averageWaitingTime(); + completedTime(); + benchmarkResults(); + trace.dispose(); + } + + private static void latencyBenchmark() { + long averageLatency = 0; + + pw.println("----- Latency -----"); + for (int i = 0; i < NUM_LOOPS; i++) { + try { + ForegroundRequest foreground1 = new ForegroundRequest(TmfTimeRange.ETERNITY); + trace.sendRequest(foreground1); + foreground1.waitForCompletion(); + averageLatency += foreground1.getLatency(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + pw.println((averageLatency / NUM_LOOPS) / NANOSECONDS_IN_MILLISECONDS + " ms"); + } + + private static void averageWaitingTime() { + long averageWaitingBackground = 0; + long averageWaitingForeground1 = 0; + long averageWaitingForeground2 = 0; + + pw.println("----- Average waiting time with 3 requests -----"); + for (int i = 0; i < NUM_LOOPS; i++) { + ForegroundRequest foreground1 = new ForegroundRequest(TmfTimeRange.ETERNITY); + ForegroundRequest foreground2 = new ForegroundRequest(TmfTimeRange.ETERNITY); + BackgroundRequest background1 = new BackgroundRequest(TmfTimeRange.ETERNITY); + trace.sendRequest(background1); + trace.sendRequest(foreground1); + trace.sendRequest(foreground2); + try { + foreground1.waitForCompletion(); + foreground2.waitForCompletion(); + background1.waitForCompletion(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + averageWaitingBackground += background1.getAverageWaitingTime(); + averageWaitingForeground1 += foreground1.getAverageWaitingTime(); + averageWaitingForeground2 += foreground2.getAverageWaitingTime(); + } + pw.print("-- Background : "); + pw.println((averageWaitingBackground / NUM_LOOPS) / NANOSECONDS_IN_MILLISECONDS + " ms"); + + pw.print("-- First foreground : "); + pw.println((averageWaitingForeground1 / NUM_LOOPS) / NANOSECONDS_IN_MILLISECONDS + " ms"); + + pw.print("-- Second foreground : "); + pw.println((averageWaitingForeground2 / NUM_LOOPS) / NANOSECONDS_IN_MILLISECONDS + " ms"); + } + + private static void completedTime() { + long averageCompletedTime1 = 0; + long averageCompletedTime2 = 0; + long averageCompletedTime3 = 0; + long averageCompletedTime4 = 0; + long averageCompletedTime5 = 0; + long averageCompletedTime6 = 0; + + pw.println("----- Time to complete request -----"); + for (int i = 0; i < NUM_LOOPS; i++) { + try { + ForegroundRequest foreground1 = new ForegroundRequest(TmfTimeRange.ETERNITY); + trace.sendRequest(foreground1); + foreground1.waitForCompletion(); + averageCompletedTime1 += foreground1.getCompletedTime(); + + ForegroundRequest foreground2 = new ForegroundRequest(TmfTimeRange.ETERNITY); + ForegroundRequest foreground3 = new ForegroundRequest(TmfTimeRange.ETERNITY); + trace.sendRequest(foreground2); + trace.sendRequest(foreground3); + foreground2.waitForCompletion(); + foreground3.waitForCompletion(); + averageCompletedTime2 += (foreground2.getCompletedTime() + foreground3.getCompletedTime()); + + ForegroundRequest foreground4 = new ForegroundRequest(TmfTimeRange.ETERNITY); + BackgroundRequest background1 = new BackgroundRequest(TmfTimeRange.ETERNITY); + trace.sendRequest(foreground4); + trace.sendRequest(background1); + foreground4.waitForCompletion(); + background1.waitForCompletion(); + averageCompletedTime3 += (foreground4.getCompletedTime() + background1.getCompletedTime()); + + ForegroundRequest foreground5 = new ForegroundRequest(TmfTimeRange.ETERNITY); + ForegroundRequest foreground6 = new ForegroundRequest(TmfTimeRange.ETERNITY); + BackgroundRequest background2 = new BackgroundRequest(TmfTimeRange.ETERNITY); + trace.sendRequest(foreground5); + trace.sendRequest(foreground6); + trace.sendRequest(background2); + foreground5.waitForCompletion(); + foreground6.waitForCompletion(); + background2.waitForCompletion(); + averageCompletedTime4 += (foreground5.getCompletedTime() + foreground6.getCompletedTime() + background2.getCompletedTime()); + + ForegroundRequest foreground7 = new ForegroundRequest(TmfTimeRange.ETERNITY); + ForegroundRequest foreground8 = new ForegroundRequest(TmfTimeRange.ETERNITY); + ForegroundRequest foreground9 = new ForegroundRequest(TmfTimeRange.ETERNITY); + BackgroundRequest background3 = new BackgroundRequest(TmfTimeRange.ETERNITY); + trace.sendRequest(foreground7); + trace.sendRequest(foreground8); + trace.sendRequest(foreground9); + trace.sendRequest(background3); + foreground7.waitForCompletion(); + foreground8.waitForCompletion(); + foreground9.waitForCompletion(); + background3.waitForCompletion(); + averageCompletedTime5 += (foreground7.getCompletedTime() + foreground8.getCompletedTime() + foreground9.getCompletedTime() + background3.getCompletedTime()); + + ForegroundRequest foreground10 = new ForegroundRequest(TmfTimeRange.ETERNITY); + ForegroundRequest foreground11 = new ForegroundRequest(TmfTimeRange.ETERNITY); + ForegroundRequest foreground12 = new ForegroundRequest(TmfTimeRange.ETERNITY); + ForegroundRequest foreground13 = new ForegroundRequest(TmfTimeRange.ETERNITY); + BackgroundRequest background4 = new BackgroundRequest(TmfTimeRange.ETERNITY); + trace.sendRequest(foreground10); + trace.sendRequest(foreground11); + trace.sendRequest(foreground12); + trace.sendRequest(foreground13); + trace.sendRequest(background4); + foreground10.waitForCompletion(); + foreground11.waitForCompletion(); + foreground12.waitForCompletion(); + foreground13.waitForCompletion(); + background4.waitForCompletion(); + averageCompletedTime6 += (foreground10.getCompletedTime() + foreground11.getCompletedTime() + foreground12.getCompletedTime() + foreground13.getCompletedTime() + background4.getCompletedTime()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + pw.print("-- Time to complete one request : "); + pw.println((averageCompletedTime1 / NUM_LOOPS) / NANOSECONDS_IN_SECONDS + " s"); + + pw.print("-- Time to complete 2 requests (2 foreground) : "); + pw.println((averageCompletedTime2 / NUM_LOOPS) / NANOSECONDS_IN_SECONDS + " s"); + + pw.print("-- Time to complete 2 requests (1 foreground, 1 background) : "); + pw.println((averageCompletedTime3 / NUM_LOOPS) / NANOSECONDS_IN_SECONDS + " s"); + + pw.print("-- Time to complete 3 requests (2 foreground, 1 background) : "); + pw.println((averageCompletedTime4 / NUM_LOOPS) / NANOSECONDS_IN_SECONDS + " s"); + + pw.print("-- Time to complete 4 requests (3 foreground, 1 background) : "); + pw.println((averageCompletedTime5 / NUM_LOOPS) / NANOSECONDS_IN_SECONDS + " s"); + + pw.print("-- Time to complete 5 requests (4 foreground, 1 background) : "); + pw.println((averageCompletedTime6 / NUM_LOOPS) / NANOSECONDS_IN_SECONDS + " s"); + } + + /** + * The benchmark results + */ + public static void benchmarkResults() { + pw.println("---------- Benchmark completed ----------"); + } + + // ------------------------------------------------------------------------ + // Helper methods + // ------------------------------------------------------------------------ + + private static class BackgroundRequest extends TmfEventRequest { + private long startTime; + private long endTimeLatency = -1; + private long completedTime = 0; + private long waitingTimeStart = 0; + private long waitingTimeEnd = 0; + private long waitingTime = 0; + private int waitingCounter = 0; + private boolean isWaiting = false; + + BackgroundRequest(TmfTimeRange timeRange) { + super(trace.getEventType(), + timeRange, + 0, + ITmfEventRequest.ALL_DATA, + ExecutionType.BACKGROUND); + startTime = System.nanoTime(); + } + + @Override + public void handleData(final ITmfEvent event) { + if (endTimeLatency == -1) { + endTimeLatency = System.nanoTime(); + } + super.handleData(event); + if (lastForegroundRequest == null && lastBackgroundRequest == null) { + lastBackgroundRequest = this; + } + if (isWaiting) { + waitingTimeEnd = System.nanoTime(); + waitingTime += waitingTimeEnd - waitingTimeStart; + ++waitingCounter; + isWaiting = false; + } + if (lastForegroundRequest != null) { + lastForegroundRequest.waitingTimeStart = System.nanoTime(); + lastForegroundRequest.isWaiting = true; + lastForegroundRequest = null; + lastBackgroundRequest = this; + } + if (lastBackgroundRequest != this) { + lastBackgroundRequest.waitingTimeStart = System.nanoTime(); + lastBackgroundRequest.isWaiting = true; + lastBackgroundRequest = this; + } + } + + @Override + public void handleCompleted() { + completedTime = System.nanoTime(); + super.handleCompleted(); + } + + public long getCompletedTime() { + return completedTime - startTime; + } + + public long getAverageWaitingTime() { + if (waitingCounter == 0) { + return 0; + } + return waitingTime / waitingCounter; + } + } + + private static class ForegroundRequest extends TmfEventRequest { + private long startTime = 0; + private long endTimeLatency = -1; + private long completedTime = 0; + private long waitingTimeStart = 0; + private long waitingTimeEnd = 0; + private long waitingTime = 0; + private int waitingCounter = 0; + private boolean isWaiting = false; + + ForegroundRequest(TmfTimeRange timeRange) { + super(trace.getEventType(), + timeRange, + 0, + ITmfEventRequest.ALL_DATA, + ExecutionType.FOREGROUND); + startTime = System.nanoTime(); + } + + @Override + public void handleData(final ITmfEvent event) { + if (endTimeLatency == -1) { + endTimeLatency = System.nanoTime(); + } + super.handleData(event); + if (lastBackgroundRequest == null && lastForegroundRequest == null) { + lastForegroundRequest = this; + } + if (isWaiting) { + waitingTimeEnd = System.nanoTime(); + waitingTime += waitingTimeEnd - waitingTimeStart; + ++waitingCounter; + isWaiting = false; + } + if (lastBackgroundRequest != null) { + lastBackgroundRequest.waitingTimeStart = System.nanoTime(); + lastBackgroundRequest.isWaiting = true; + lastBackgroundRequest = null; + lastForegroundRequest = this; + } + if (lastForegroundRequest != this) { + lastForegroundRequest.waitingTimeStart = System.nanoTime(); + lastForegroundRequest.isWaiting = true; + lastForegroundRequest = this; + } + } + + @Override + public void handleCompleted() { + completedTime = System.nanoTime(); + super.handleCompleted(); + } + + public long getLatency() { + return endTimeLatency - startTime; + } + + public long getCompletedTime() { + return completedTime - startTime; + } + + public long getAverageWaitingTime() { + if (waitingCounter == 0) { + return 0; + } + return waitingTime / waitingCounter; + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/request/TmfSchedulerTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/request/TmfSchedulerTest.java new file mode 100644 index 0000000000..df4f035ba3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/request/TmfSchedulerTest.java @@ -0,0 +1,451 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Simon Delisle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests.request; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.core.resources.IResource; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfEvent; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.rules.Timeout; + +/** + * Test suite for the scheduler. + */ +public class TmfSchedulerTest { + + /** Time-out tests after 60 seconds */ + @Rule + public TestRule globalTimeout= new Timeout(60000); + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + private static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.KERNEL; + private static final int NB_EVENTS_TRACE = 695319; + private static final int NB_EVENTS_TIME_RANGE = 155133; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private CtfTmfTrace fixture; + + private long fStartTime; + private long fEndTime; + private TmfTimeRange fForegroundTimeRange; + + private final List fOrderList = new ArrayList<>(); + private int fForegroundId = 0; + private int fBackgroundId = 0; + + /** + * Perform pre-test initialization. + * + * @throws TmfTraceException + * If the test trace is not found + */ + @Before + public void setUp() throws TmfTraceException { + assumeTrue(testTrace.exists()); + fixture = new CtfTmfTrace(); + fixture.initTrace((IResource) null, testTrace.getPath(), CtfTmfEvent.class); + fixture.indexTrace(true); + fStartTime = fixture.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + fEndTime = fixture.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + + long foregroundStartTime = fStartTime + ((fEndTime - fStartTime) / 4); + long foregroundEndTime = fStartTime + ((fEndTime - fStartTime) / 2); + fForegroundTimeRange = new TmfTimeRange(new TmfTimestamp(foregroundStartTime, ITmfTimestamp.NANOSECOND_SCALE, 0), new TmfTimestamp(foregroundEndTime, ITmfTimestamp.NANOSECOND_SCALE, 0)); + } + + /** + * Perform post-test clean-up. + */ + @After + public void tearDown() { + if (fixture != null) { + fixture.dispose(); + } + } + + // ------------------------------------------------------------------------ + // Tests cases + // ------------------------------------------------------------------------ + + /** + * Test one background request + */ + @Test + public void backgroundRequest() { + BackgroundRequest background = new BackgroundRequest(TmfTimeRange.ETERNITY); + fixture.sendRequest(background); + try { + background.waitForCompletion(); + } catch (InterruptedException e) { + fail(); + } + assertEquals(NB_EVENTS_TRACE, background.getNbEvents()); + } + + /** + * Test one foreground request + */ + @Test + public void foregroundRequest() { + ForegroundRequest foreground = new ForegroundRequest(TmfTimeRange.ETERNITY); + fixture.sendRequest(foreground); + try { + foreground.waitForCompletion(); + } catch (InterruptedException e) { + fail(); + } + assertEquals(NB_EVENTS_TRACE, foreground.getNbEvents()); + } + + /** + * Test one foreground and one background request for the entire trace at + * the same time + */ + @Test + public void TestMultiRequest1() { + BackgroundRequest background = new BackgroundRequest(TmfTimeRange.ETERNITY); + ForegroundRequest foreground = new ForegroundRequest(TmfTimeRange.ETERNITY); + + fixture.sendRequest(background); + fixture.sendRequest(foreground); + try { + background.waitForCompletion(); + foreground.waitForCompletion(); + } catch (InterruptedException e) { + fail(); + } + + assertEquals(NB_EVENTS_TRACE, background.getNbEvents()); + assertEquals(NB_EVENTS_TRACE, foreground.getNbEvents()); + } + + /** + * Test one background request for the entire trace and one foreground + * request for smaller time range + */ + @Test + public void TestMultiRequest2() { + BackgroundRequest background2 = new BackgroundRequest(TmfTimeRange.ETERNITY); + ForegroundRequest foreground2 = new ForegroundRequest(fForegroundTimeRange); + + fixture.sendRequest(background2); + fixture.sendRequest(foreground2); + try { + background2.waitForCompletion(); + foreground2.waitForCompletion(); + } catch (InterruptedException e) { + fail(); + } + + assertEquals(NB_EVENTS_TRACE, background2.getNbEvents()); + assertEquals(NB_EVENTS_TIME_RANGE, foreground2.getNbEvents()); + } + + /** + * Test two foreground request, one to select a time range and one to select + * an event in this time range + */ + @Test + public void TestMultiRequest3() { + ForegroundRequest foreground3 = new ForegroundRequest(TmfTimeRange.ETERNITY); + fixture.sendRequest(foreground3); + + TmfTimeSynchSignal signal3 = new TmfTimeSynchSignal(this, new TmfTimestamp(fForegroundTimeRange.getStartTime())); + fixture.broadcast(signal3); + + try { + foreground3.waitForCompletion(); + } catch (InterruptedException e) { + fail(); + } + + assertEquals(NB_EVENTS_TRACE, foreground3.getNbEvents()); + } + + /** + * Test two foreground request, one to select a time range and one to select + * an event before this time range + */ + @Test + public void TestMultiRequest4() { + ForegroundRequest foreground4 = new ForegroundRequest(fForegroundTimeRange); + fixture.sendRequest(foreground4); + TmfTimeSynchSignal signal4 = new TmfTimeSynchSignal(this, new TmfTimestamp(fStartTime + ((fEndTime - fStartTime) / 8))); + fixture.broadcast(signal4); + + try { + foreground4.waitForCompletion(); + } catch (InterruptedException e) { + fail(); + } + + assertEquals(NB_EVENTS_TIME_RANGE, foreground4.getNbEvents()); + } + + /** + * Test two foreground request, one to select a time range and one to select + * an event after this time range + */ + @Test + public void TestMultiRequest5() { + ForegroundRequest foreground5 = new ForegroundRequest(fForegroundTimeRange); + fixture.sendRequest(foreground5); + TmfTimeSynchSignal signal5 = new TmfTimeSynchSignal(this, new TmfTimestamp(fEndTime - ((fEndTime - fStartTime) / 4))); + fixture.broadcast(signal5); + + try { + foreground5.waitForCompletion(); + } catch (InterruptedException e) { + fail(); + } + + assertEquals(NB_EVENTS_TIME_RANGE, foreground5.getNbEvents()); + } + + /** + * Test one background and one foreground request for the entire trace and + * one foreground request to select an event + */ + @Test + public void TestMultiRequest6() { + BackgroundRequest background6 = new BackgroundRequest(TmfTimeRange.ETERNITY); + ForegroundRequest foreground6 = new ForegroundRequest(TmfTimeRange.ETERNITY); + + fixture.sendRequest(background6); + fixture.sendRequest(foreground6); + + TmfTimeSynchSignal signal6 = new TmfTimeSynchSignal(this, new TmfTimestamp(fStartTime + ((fEndTime - fStartTime) / 8))); + fixture.broadcast(signal6); + + try { + background6.waitForCompletion(); + foreground6.waitForCompletion(); + } catch (InterruptedException e) { + fail(); + } + + assertEquals(NB_EVENTS_TRACE, background6.getNbEvents()); + assertEquals(NB_EVENTS_TRACE, foreground6.getNbEvents()); + } + + /** + * Four request, two foreground and two background + */ + @Test + public void TestMultiRequest7() { + ForegroundRequest foreground7 = new ForegroundRequest(TmfTimeRange.ETERNITY); + ForegroundRequest foreground8 = new ForegroundRequest(fForegroundTimeRange); + BackgroundRequest background7 = new BackgroundRequest(TmfTimeRange.ETERNITY); + BackgroundRequest background8 = new BackgroundRequest(TmfTimeRange.ETERNITY); + fixture.sendRequest(foreground7); + fixture.sendRequest(foreground8); + fixture.sendRequest(background7); + fixture.sendRequest(background8); + try { + foreground7.waitForCompletion(); + foreground8.waitForCompletion(); + background7.waitForCompletion(); + background8.waitForCompletion(); + } catch (InterruptedException e) { + fail(); + } + assertEquals(NB_EVENTS_TRACE, foreground7.getNbEvents()); + assertEquals(NB_EVENTS_TIME_RANGE, foreground8.getNbEvents()); + assertEquals(NB_EVENTS_TRACE, background7.getNbEvents()); + assertEquals(NB_EVENTS_TRACE, background8.getNbEvents()); + } + + /** + * One long foreground request and one short foreground request, the short + * one should finish first + */ + @Test + public void preemptedForegroundRequest() { + ForegroundRequest foreground9 = new ForegroundRequest(TmfTimeRange.ETERNITY); + TmfTimeRange shortTimeRange = new TmfTimeRange(new TmfTimestamp(fStartTime, ITmfTimestamp.NANOSECOND_SCALE, 0), new TmfTimestamp(fStartTime + ((fEndTime - fStartTime) / 16), ITmfTimestamp.NANOSECOND_SCALE, 0)); + ForegroundRequest shortForeground = new ForegroundRequest(shortTimeRange); + fixture.sendRequest(foreground9); + try { + foreground9.waitForStart(); + } catch (InterruptedException e) { + fail(); + } + fixture.sendRequest(shortForeground); + try { + shortForeground.waitForCompletion(); + } catch (InterruptedException e) { + fail(); + } + assertFalse(foreground9.isCompleted()); + } + + /** + * One long background request and one short foreground request, the + * foreground request should finish first + */ + @Test + public void preemptedBackgroundRequest() { + BackgroundRequest background9 = new BackgroundRequest(TmfTimeRange.ETERNITY); + ForegroundRequest foreground10 = new ForegroundRequest(fForegroundTimeRange); + fixture.sendRequest(background9); + fixture.sendRequest(foreground10); + try { + foreground10.waitForCompletion(); + } catch (InterruptedException e) { + fail(); + } + assertTrue(foreground10.isCompleted()); + assertFalse(background9.isCompleted()); + } + + /** + * Test if the scheduler is working as expected + */ + @Ignore + @Test + public void executionOrder() { + List expectedOrder = new LinkedList<>(); + expectedOrder.add("FOREGROUND1"); + expectedOrder.add("FOREGROUND2"); + expectedOrder.add("FOREGROUND3"); + expectedOrder.add("FOREGROUND4"); + expectedOrder.add("BACKGROUND1"); + expectedOrder.add("FOREGROUND1"); + expectedOrder.add("FOREGROUND2"); + expectedOrder.add("FOREGROUND3"); + expectedOrder.add("FOREGROUND4"); + expectedOrder.add("BACKGROUND2"); + + fOrderList.clear(); + fForegroundId = 0; + fBackgroundId = 0; + + BackgroundRequest background1 = new BackgroundRequest(TmfTimeRange.ETERNITY); + BackgroundRequest background2 = new BackgroundRequest(TmfTimeRange.ETERNITY); + + ForegroundRequest foreground1 = new ForegroundRequest(TmfTimeRange.ETERNITY); + ForegroundRequest foreground2 = new ForegroundRequest(TmfTimeRange.ETERNITY); + ForegroundRequest foreground3 = new ForegroundRequest(TmfTimeRange.ETERNITY); + ForegroundRequest foreground4 = new ForegroundRequest(TmfTimeRange.ETERNITY); + + fixture.sendRequest(foreground1); + fixture.sendRequest(foreground2); + fixture.sendRequest(foreground3); + fixture.sendRequest(foreground4); + fixture.sendRequest(background1); + fixture.sendRequest(background2); + try { + foreground1.waitForCompletion(); + foreground2.waitForCompletion(); + foreground3.waitForCompletion(); + foreground4.waitForCompletion(); + background1.waitForCompletion(); + background2.waitForCompletion(); + } catch (InterruptedException e) { + fail(); + } + assertEquals(expectedOrder, fOrderList.subList(0, expectedOrder.size())); + } + + // ------------------------------------------------------------------------ + // Helper methods + // ------------------------------------------------------------------------ + + private class BackgroundRequest extends TmfEventRequest { + private int nbEvents = 0; + private String backgroundName; + + BackgroundRequest(TmfTimeRange timeRange) { + super(fixture.getEventType(), + timeRange, + 0, + ITmfEventRequest.ALL_DATA, + ExecutionType.BACKGROUND); + backgroundName = getExecType().toString() + ++fBackgroundId; + } + + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + synchronized (fOrderList) { + if (fOrderList.isEmpty() || !fOrderList.get(fOrderList.size() - 1).equals(backgroundName)) { + fOrderList.add(backgroundName); + } + } + ++nbEvents; + } + + public int getNbEvents() { + return nbEvents; + } + } + + private class ForegroundRequest extends TmfEventRequest { + private int nbEvents = 0; + private String foregroundName; + + ForegroundRequest(TmfTimeRange timeRange) { + super(fixture.getEventType(), + timeRange, + 0, + ITmfEventRequest.ALL_DATA, + ExecutionType.FOREGROUND); + foregroundName = getExecType().toString() + ++fForegroundId; + } + + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + synchronized (fOrderList) { + if (fOrderList.isEmpty() || !fOrderList.get(fOrderList.size() - 1).equals(foregroundName)) { + fOrderList.add(foregroundName); + } + } + ++nbEvents; + } + + public int getNbEvents() { + return nbEvents; + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/statistics/AllTests.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/statistics/AllTests.java new file mode 100644 index 0000000000..264bddda60 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/statistics/AllTests.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests.statistics; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TmfEventsStatisticsTest.class, + TmfStateStatisticsTest.class +}) +public class AllTests {} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/statistics/TmfEventsStatisticsTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/statistics/TmfEventsStatisticsTest.java new file mode 100644 index 0000000000..b393fdbfb8 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/statistics/TmfEventsStatisticsTest.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests.statistics; + +import static org.junit.Assume.assumeTrue; + +import org.eclipse.tracecompass.tmf.core.statistics.TmfEventsStatistics; +import org.junit.BeforeClass; + +/** + * Unit tests for the {@link TmfEventsStatistics} + * + * @author Alexandre Montplaisir + */ +public class TmfEventsStatisticsTest extends TmfStatisticsTest { + + /** + * Set up the fixture once for all tests. + */ + @BeforeClass + public static void setUpClass() { + assumeTrue(testTrace.exists()); + backend = new TmfEventsStatistics(testTrace.getTrace()); + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/statistics/TmfStateStatisticsTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/statistics/TmfStateStatisticsTest.java new file mode 100644 index 0000000000..997215a928 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/statistics/TmfStateStatisticsTest.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests.statistics; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.statistics.TmfStateStatistics; +import org.eclipse.tracecompass.tmf.core.statistics.TmfStatisticsEventTypesModule; +import org.eclipse.tracecompass.tmf.core.statistics.TmfStatisticsTotalsModule; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; + +/** + * Unit tests for the {@link TmfStateStatistics} + * + * @author Alexandre Montplaisir + */ +public class TmfStateStatisticsTest extends TmfStatisticsTest { + + private ITmfTrace fTrace; + + private TmfStatisticsTotalsModule fTotalsMod; + private TmfStatisticsEventTypesModule fEventTypesMod; + + /** + * Class setup + */ + @BeforeClass + public static void setUpClass() { + assumeTrue(testTrace.exists()); + } + + /** + * Test setup + */ + @Before + public void setUp() { + fTrace = testTrace.getTrace(); + + /* Prepare the two analysis-backed state systems */ + fTotalsMod = new TmfStatisticsTotalsModule(); + fEventTypesMod = new TmfStatisticsEventTypesModule(); + try { + fTotalsMod.setTrace(fTrace); + fEventTypesMod.setTrace(fTrace); + } catch (TmfAnalysisException e) { + fail(); + } + + fTotalsMod.schedule(); + fEventTypesMod.schedule(); + assertTrue(fTotalsMod.waitForCompletion()); + assertTrue(fEventTypesMod.waitForCompletion()); + + ITmfStateSystem totalsSS = fTotalsMod.getStateSystem(); + ITmfStateSystem eventTypesSS = fEventTypesMod.getStateSystem(); + assertNotNull(totalsSS); + assertNotNull(eventTypesSS); + + backend = new TmfStateStatistics(totalsSS, eventTypesSS); + } + + /** + * Test cleanup + */ + @After + public void tearDown() { + fTotalsMod.close(); + fEventTypesMod.close(); + fTrace.dispose(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/statistics/TmfStatisticsTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/statistics/TmfStatisticsTest.java new file mode 100644 index 0000000000..6ddf662f05 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/statistics/TmfStatisticsTest.java @@ -0,0 +1,364 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests.statistics; + +import static org.junit.Assert.assertEquals; + +import java.util.List; +import java.util.Map; + +import org.eclipse.tracecompass.tmf.core.statistics.ITmfStatistics; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.rules.Timeout; + +/** + * Base unit test class for any type of ITmfStatistics. Sub-classes should + * implement a "@BeforeClass" method to setup the 'backend' fixture accordingly. + * + * @author Alexandre Montplaisir + */ +public abstract class TmfStatisticsTest { + + /** Time-out tests after 30 seconds */ + @Rule public TestRule globalTimeout= new Timeout(30000); + + /** Test trace used for these tests */ + protected static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.KERNEL; + + /** The statistics back-end object */ + protected static ITmfStatistics backend; + + /* Known values about the trace */ + private static final int totalNbEvents = 695319; + private static final long tStart = 1332170682440133097L; /* Timestamp of first event */ + private static final long tEnd = 1332170692664579801L; /* Timestamp of last event */ + + /* Timestamps of interest */ + private static final long t1 = 1332170682490946000L; + private static final long t2 = 1332170682490947524L; /* event exactly here */ + private static final long t3 = 1332170682490948000L; + private static final long t4 = 1332170682490949000L; + private static final long t5 = 1332170682490949270L; /* following event here */ + private static final long t6 = 1332170682490949300L; + + private static final String eventType = "lttng_statedump_process_state"; + + + // ------------------------------------------------------------------------ + // Tests for histogramQuery() + // ------------------------------------------------------------------------ + + /** + * Test the {@link ITmfStatistics#histogramQuery} method for the small known + * interval. + */ + @Test + public void testHistogramQuerySmall() { + final int NB_REQ = 10; + List results = backend.histogramQuery(t1, t6, NB_REQ); + + /* Make sure the returned array has the right size */ + assertEquals(NB_REQ, results.size()); + + /* Check the contents of each "bucket" */ + assertEquals(0, results.get(0).longValue()); + assertEquals(0, results.get(1).longValue()); + assertEquals(0, results.get(2).longValue()); + assertEquals(0, results.get(3).longValue()); + assertEquals(1, results.get(4).longValue()); + assertEquals(0, results.get(5).longValue()); + assertEquals(0, results.get(6).longValue()); + assertEquals(0, results.get(7).longValue()); + assertEquals(0, results.get(8).longValue()); + assertEquals(1, results.get(9).longValue()); + + } + + /** + * Test the {@link ITmfStatistics#histogramQuery} method over the whole + * trace. + */ + @Test + public void testHistogramQueryFull() { + final int NB_REQ = 10; + List results = backend.histogramQuery(tStart, tEnd, NB_REQ); + + /* Make sure the returned array has the right size */ + assertEquals(NB_REQ, results.size()); + + /* Check the total number of events */ + long count = 0; + for (long val : results) { + count += val; + } + assertEquals(totalNbEvents, count); + + /* Check the contents of each "bucket" */ + assertEquals(94161, results.get(0).longValue()); + assertEquals(87348, results.get(1).longValue()); + assertEquals(58941, results.get(2).longValue()); + assertEquals(59879, results.get(3).longValue()); + assertEquals(66941, results.get(4).longValue()); + assertEquals(68939, results.get(5).longValue()); + assertEquals(72746, results.get(6).longValue()); + assertEquals(60749, results.get(7).longValue()); + assertEquals(61208, results.get(8).longValue()); + assertEquals(64407, results.get(9).longValue()); + } + + // ------------------------------------------------------------------------ + // Test for getEventsTotal() + // ------------------------------------------------------------------------ + + /** + * Basic test for {@link ITmfStatistics#getEventsTotal} + */ + @Test + public void testGetEventsTotal() { + long count = backend.getEventsTotal(); + assertEquals(totalNbEvents, count); + } + + // ------------------------------------------------------------------------ + // Test for getEventTypesTotal() + // ------------------------------------------------------------------------ + + /** + * Basic test for {@link ITmfStatistics#getEventTypesTotal} + */ + @Test + public void testEventTypesTotal() { + Map res = backend.getEventTypesTotal(); + assertEquals(126, res.size()); /* Number of different event types in the trace */ + + long count = sumOfEvents(res); + assertEquals(totalNbEvents, count); + } + + // ------------------------------------------------------------------------ + // Tests for getEventsInRange(ITmfTimestamp start, ITmfTimestamp end) + // ------------------------------------------------------------------------ + + /** + * Test for {@link ITmfStatistics#getEventsInRange} over the whole trace. + */ + @Test + public void testGetEventsInRangeWholeRange() { + long count = backend.getEventsInRange(tStart, tEnd); + assertEquals(totalNbEvents, count); + } + + /** + * Test for {@link ITmfStatistics#getEventsInRange} for the whole range, + * except the start time (there is only one event at the start time). + */ + @Test + public void testGetEventsInRangeMinusStart() { + long count = backend.getEventsInRange(tStart + 1, tEnd); + assertEquals(totalNbEvents - 1, count); + } + + /** + * Test for {@link ITmfStatistics#getEventsInRange} for the whole range, + * except the end time (there is only one event at the end time). + */ + @Test + public void testGetEventsInRangeMinusEnd() { + long count = backend.getEventsInRange(tStart, tEnd - 1); + assertEquals(totalNbEvents - 1, count); + } + + /** + * Test for {@link ITmfStatistics#getEventsInRange} when both the start and + * end times don't match an event. + */ + @Test + public void testGetEventsInRangeNoEventsAtEdges() { + long count = backend.getEventsInRange(t1, t6); + assertEquals(2, count); + } + + /** + * Test for {@link ITmfStatistics#getEventsInRange} when the *start* of the + * interval is exactly on an event (that event should be included). + */ + @Test + public void testGetEventsInRangeEventAtStart() { + long count = backend.getEventsInRange(t2, t3); + assertEquals(1, count); + + count = backend.getEventsInRange(t2, t6); + assertEquals(2, count); + } + + /** + * Test for {@link ITmfStatistics#getEventsInRange} when the *end* of the + * interval is exactly on an event (that event should be included). + */ + @Test + public void testGetEventsInRangeEventAtEnd() { + long count = backend.getEventsInRange(t4, t5); + assertEquals(1, count); + + count = backend.getEventsInRange(t1, t5); + assertEquals(2, count); + } + + /** + * Test for {@link ITmfStatistics#getEventsInRange} when there are events + * matching exactly both the start and end times of the range (both should + * be included). + */ + @Test + public void testGetEventsInRangeEventAtBoth() { + long count = backend.getEventsInRange(t2, t5); + assertEquals(2, count); + } + + /** + * Test for {@link ITmfStatistics#getEventsInRange} when there are no events + * in a given range. + */ + @Test + public void testGetEventsInRangeNoEvents() { + long count = backend.getEventsInRange(t3, t4); + assertEquals(0, count); + } + + // ------------------------------------------------------------------------ + // Tests for getEventTypesInRange(ITmfTimestamp start, ITmfTimestamp end) + // ------------------------------------------------------------------------ + + /** + * Test for {@link ITmfStatistics#getEventTypesInRange} over the whole trace. + */ + @Test + public void testGetEventTypesInRangeWholeRange() { + Map result = backend.getEventTypesInRange(tStart, tEnd); + /* Number of events of that type in the whole trace */ + assertEquals(new Long(464L), result.get(eventType)); + + long count = sumOfEvents(result); + assertEquals(totalNbEvents, count); + } + + /** + * Test for {@link ITmfStatistics#getEventTypesInRange} for the whole range, + * except the start time (there is only one event at the start time). + */ + @Test + public void testGetEventTypesInRangeMinusStart() { + Map result = backend.getEventTypesInRange(tStart + 1, tEnd); + + long count = sumOfEvents(result); + assertEquals(totalNbEvents - 1, count); + } + + /** + * Test for {@link ITmfStatistics#getEventTypesInRange} for the whole range, + * except the end time (there is only one event at the end time). + */ + @Test + public void testGetEventTypesInRangeMinusEnd() { + Map result = backend.getEventTypesInRange(tStart, tEnd - 1); + + long count = sumOfEvents(result); + assertEquals(totalNbEvents - 1, count); + } + + /** + * Test for {@link ITmfStatistics#getEventTypesInRange} when both the start + * and end times don't match an event. + */ + @Test + public void testGetEventTypesInRangeNoEventsAtEdges() { + Map result = backend.getEventTypesInRange(t1, t6); + assertEquals(new Long(2L), result.get(eventType)); + + long count = sumOfEvents(result); + assertEquals(2, count); + } + + /** + * Test for {@link ITmfStatistics#getEventTypesInRange} when the *start* of + * the interval is exactly on an event (that event should be included). + */ + @Test + public void testGetEventTypesInRangeEventAtStart() { + Map result = backend.getEventTypesInRange(t2, t3); + assertEquals(new Long(1L), result.get(eventType)); + long count = sumOfEvents(result); + assertEquals(1, count); + + result = backend.getEventTypesInRange(t2, t6); + assertEquals(new Long(2L), result.get(eventType)); + count = sumOfEvents(result); + assertEquals(2, count); + } + + /** + * Test for {@link ITmfStatistics#getEventTypesInRange} when the *end* of + * the interval is exactly on an event (that event should be included). + */ + @Test + public void testGetEventTypesInRangeEventAtEnd() { + Map result = backend.getEventTypesInRange(t4, t5); + assertEquals(new Long(1L), result.get(eventType)); + long count = sumOfEvents(result); + assertEquals(1, count); + + result = backend.getEventTypesInRange(t1, t5); + assertEquals(new Long(2L), result.get(eventType)); + count = sumOfEvents(result); + assertEquals(2, count); + } + + /** + * Test for {@link ITmfStatistics#getEventTypesInRange} when there are + * events matching exactly both the start and end times of the range (both + * should be included). + */ + @Test + public void testGetEventTypesInRangeEventAtBoth() { + Map result = backend.getEventTypesInRange(t2, t5); + assertEquals(new Long(2L), result.get(eventType)); + long count = sumOfEvents(result); + assertEquals(2, count); + } + + /** + * Test for {@link ITmfStatistics#getEventTypesInRange} when there are no + * events in a given range. + */ + @Test + public void testGetEventTypesInRangeNoEvents() { + Map result = backend.getEventTypesInRange(t3, t4); + long count = sumOfEvents(result); + assertEquals(0, count); + } + + // ------------------------------------------------------------------------ + // Convenience methods + // ------------------------------------------------------------------------ + + private static long sumOfEvents(Map map) { + long count = 0; + for (long val : map.values()) { + count += val; + } + return count; + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/tracemanager/AllTests.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/tracemanager/AllTests.java new file mode 100644 index 0000000000..27c9e8963a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/tracemanager/AllTests.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests.tracemanager; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TmfTraceManagerTest.class +}) +public class AllTests {} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/tracemanager/TmfTraceManagerTest.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/tracemanager/TmfTraceManagerTest.java new file mode 100644 index 0000000000..9cabdc3a72 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/tracemanager/TmfTraceManagerTest.java @@ -0,0 +1,720 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + * Patrick Tasse - Support selection range + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests.tracemanager; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assume.assumeTrue; + +import java.io.File; +import java.util.Set; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.signal.TmfRangeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * Test suite for the {@link TmfTraceManager}. + * + * @author Alexandre Montplaisir + */ +public class TmfTraceManagerTest { + + private static final int SCALE = ITmfTimestamp.NANOSECOND_SCALE; + + private static ITmfTrace trace1; + private static final long t1start = 1331668247314038062L; + private static final long t1end = 1331668259054285979L; + + private static ITmfTrace trace2; + private static final long t2start = 1332170682440133097L; + private static final long t2end = 1332170692664579801L; + + private static final long ONE_SECOND = 1000000000L; + + private TmfTraceManager tm; + + + /** + * Test class initialization + */ + @BeforeClass + public static void setUpClass() { + assumeTrue(CtfTmfTestTrace.TRACE2.exists()); + assumeTrue(CtfTmfTestTrace.KERNEL.exists()); + trace1 = CtfTmfTestTrace.TRACE2.getTrace(); + trace2 = CtfTmfTestTrace.KERNEL.getTrace(); + + trace1.indexTrace(true); + trace2.indexTrace(true); + + // Deregister traces from signal manager so that they don't + // interfere with the TmfTraceManager tests + TmfSignalManager.deregister(trace1); + TmfSignalManager.deregister(trace2); + } + + /** + * Test initialization + */ + @Before + public void setUp() { + tm = TmfTraceManager.getInstance(); + } + + /** + * Test clean-up + */ + @After + public void tearDown() { + while (tm.getActiveTrace() != null) { + closeTrace(tm.getActiveTrace()); + } + } + + /** + * Test class clean-up + */ + @AfterClass + public static void tearDownClass() { + CtfTmfTestTrace.TRACE2.dispose(); + CtfTmfTestTrace.KERNEL.dispose(); + } + + // ------------------------------------------------------------------------ + // Dummy actions (fake signals) + // ------------------------------------------------------------------------ + + private void openTrace(ITmfTrace trace) { + if (trace == null) { + throw new IllegalArgumentException(); + } + TmfSignalManager.dispatchSignal(new TmfTraceOpenedSignal(this, trace, null)); + selectTrace(trace); + } + + private void closeTrace(ITmfTrace trace) { + if (trace == null) { + throw new IllegalArgumentException(); + } + TmfSignalManager.dispatchSignal(new TmfTraceClosedSignal(this, trace)); + /* + * In TMF, the next tab would now be selected (if there are some), which + * would select another trace automatically. + */ + if (tm.getOpenedTraces().size() > 0) { + selectTrace(tm.getOpenedTraces().toArray(new ITmfTrace[0])[0]); + } + } + + private void selectTrace(ITmfTrace trace) { + TmfSignalManager.dispatchSignal(new TmfTraceSelectedSignal(this, trace)); + } + + private void selectTimestamp(ITmfTimestamp ts) { + TmfSignalManager.dispatchSignal(new TmfTimeSynchSignal(this, ts)); + } + + private void selectTimeRange(TmfTimeRange tr) { + TmfSignalManager.dispatchSignal(new TmfRangeSynchSignal(this, tr)); + } + + // ------------------------------------------------------------------------ + // General tests + // ------------------------------------------------------------------------ + + /** + * Test that the manager is correctly initialized + */ + @Test + public void testInitialize() { + TmfTraceManager mgr = TmfTraceManager.getInstance(); + assertNotNull(mgr); + assertSame(tm, mgr); + } + + /** + * Test the contents of a trace set with one trace. + */ + @Test + public void testTraceSet() { + openTrace(trace1); + openTrace(trace2); + selectTrace(trace2); + + ITmfTrace[] expected = new ITmfTrace[] { trace2 }; + ITmfTrace[] actual = tm.getActiveTraceSet(); + + assertEquals(1, actual.length); + assertArrayEquals(expected, actual); + } + + /** + * Test the contents of a trace set with an experiment. + */ + @Test + public void testTraceSetExperiment() { + TmfExperiment exp = createExperiment(trace1, trace2); + openTrace(trace1); + openTrace(exp); + + ITmfTrace[] expected = new ITmfTrace[] { trace1, trace2 }; + ITmfTrace[] actual = tm.getActiveTraceSet(); + + assertEquals(2, actual.length); + assertArrayEquals(expected, actual); + } + + /** + * Test the contents of the complete trace set. + */ + @Test + public void testTraceSetWithExperiment() { + /* Test with a trace */ + Set expected = ImmutableSet.of(trace1); + Set actual = TmfTraceManager.getTraceSetWithExperiment(trace1); + assertEquals(1, actual.size()); + assertEquals(expected, actual); + + /* Test with an experiment */ + TmfExperiment exp = createExperiment(trace1, trace2); + expected = ImmutableSet.of(trace1, trace2, exp); + actual = TmfTraceManager.getTraceSetWithExperiment(exp); + assertEquals(3, actual.size()); + assertEquals(expected, actual); + } + + /** + * Test the {@link TmfTraceManager#getSupplementaryFileDir} method. + */ + @Test + public void testSupplementaryFileDir() { + String name1 = trace1.getName(); + String name2 = trace2.getName(); + String basePath = TmfTraceManager.getTemporaryDirPath() + File.separator; + + String expected1 = basePath + name1 + File.separator; + String expected2 = basePath + name2 + File.separator; + + assertEquals(expected1, TmfTraceManager.getSupplementaryFileDir(trace1)); + assertEquals(expected2, TmfTraceManager.getSupplementaryFileDir(trace2)); + } + + // ------------------------------------------------------------------------ + // Test a single trace + // ------------------------------------------------------------------------ + + /** + * Test the initial range of a single trace. + */ + @Test + public void testTraceInitialRange() { + openTrace(trace2); + final TmfTimeRange expectedRange = new TmfTimeRange( + trace2.getStartTime(), + calculateOffset(trace2.getStartTime(), trace2.getInitialRangeOffset())); + TmfTimeRange actualRange = tm.getCurrentRange(); + assertEquals(expectedRange, actualRange); + } + + /** + * Try selecting a timestamp contained inside the trace's range. The trace's + * current time should get updated correctly. + */ + @Test + public void testNewTimestamp() { + openTrace(trace2); + ITmfTimestamp ts = new TmfTimestamp(t2start + ONE_SECOND, SCALE); + selectTimestamp(ts); + + ITmfTimestamp afterTs = tm.getSelectionBeginTime(); + assertEquals(ts, afterTs); + afterTs = tm.getSelectionEndTime(); + assertEquals(ts, afterTs); + } + + /** + * Try selecting a timestamp happening before the trace's start. The change + * should be ignored. + */ + @Test + public void testTimestampBefore() { + openTrace(trace2); + ITmfTimestamp beforeTs = tm.getSelectionBeginTime(); + ITmfTimestamp ts = new TmfTimestamp(t2start - ONE_SECOND, SCALE); + selectTimestamp(ts); + + ITmfTimestamp curTs = tm.getSelectionBeginTime(); + assertEquals(beforeTs, curTs); + curTs = tm.getSelectionEndTime(); + assertEquals(beforeTs, curTs); + } + + /** + * Try selecting a timestamp happening after the trace's end. The change + * should be ignored. + */ + @Test + public void testTimestampAfter() { + openTrace(trace2); + ITmfTimestamp beforeTs = tm.getSelectionBeginTime(); + ITmfTimestamp ts = new TmfTimestamp(t2end + ONE_SECOND, SCALE); + selectTimestamp(ts); + + ITmfTimestamp curTs = tm.getSelectionBeginTime(); + assertEquals(beforeTs, curTs); + curTs = tm.getSelectionEndTime(); + assertEquals(beforeTs, curTs); + } + + /** + * Test selecting a normal sub-range of a single trace. + */ + @Test + public void testTraceNewTimeRange() { + openTrace(trace2); + TmfTimeRange range = new TmfTimeRange( + new TmfTimestamp(t2start + ONE_SECOND, SCALE), + new TmfTimestamp(t2end - ONE_SECOND, SCALE)); + selectTimeRange(range); + + TmfTimeRange curRange = tm.getCurrentRange(); + assertEquals(range.getStartTime(), curRange.getStartTime()); + assertEquals(range.getEndTime(), curRange.getEndTime()); + } + + /** + * Test selecting a range whose start time is before the trace's start time. + * The selected range should get clamped to the trace's range. + */ + @Test + public void testTraceTimeRangeClampingStart() { + openTrace(trace2); + TmfTimeRange range = new TmfTimeRange( + new TmfTimestamp(t2start - ONE_SECOND, SCALE), // minus here + new TmfTimestamp(t2end - ONE_SECOND, SCALE)); + selectTimeRange(range); + + TmfTimeRange curRange = tm.getCurrentRange(); + assertEquals(t2start, curRange.getStartTime().getValue()); + assertEquals(range.getEndTime(), curRange.getEndTime()); + } + + /** + * Test selecting a range whose end time is after the trace's end time. + * The selected range should get clamped to the trace's range. + */ + @Test + public void testTraceTimeRangeClampingEnd() { + openTrace(trace2); + TmfTimeRange range = new TmfTimeRange( + new TmfTimestamp(t2start + ONE_SECOND, SCALE), + new TmfTimestamp(t2end + ONE_SECOND, SCALE)); // plus here + selectTimeRange(range); + + TmfTimeRange curRange = tm.getCurrentRange(); + assertEquals(range.getStartTime(), curRange.getStartTime()); + assertEquals(t2end, curRange.getEndTime().getValue()); + } + + /** + * Test selecting a range whose both start and end times are outside of the + * trace's range. The selected range should get clamped to the trace's + * range. + */ + @Test + public void testTraceTimeRangeClampingBoth() { + openTrace(trace2); + TmfTimeRange range = new TmfTimeRange( + new TmfTimestamp(t2start - ONE_SECOND, SCALE), // minus here + new TmfTimestamp(t2end + ONE_SECOND, SCALE)); // plus here + selectTimeRange(range); + + TmfTimeRange curRange = tm.getCurrentRange(); + assertEquals(t2start, curRange.getStartTime().getValue()); + assertEquals(t2end, curRange.getEndTime().getValue()); + } + + // ------------------------------------------------------------------------ + // Test multiple, non-overlapping traces in parallel + // ------------------------------------------------------------------------ + + /** + * Test, with two traces in parallel, when we select a timestamp that is + * part of the first trace. + * + * The first trace's timestamp should be updated, but the second trace's one + * should not change. + */ + @Test + public void testTwoTracesTimestampValid() { + openTrace(trace1); + openTrace(trace2); + selectTrace(trace1); + TmfTimestamp ts = new TmfTimestamp(t1start + ONE_SECOND, SCALE); + selectTimestamp(ts); + + /* Timestamp of trace1 should have been updated */ + assertEquals(ts, tm.getSelectionBeginTime()); + assertEquals(ts, tm.getSelectionEndTime()); + + /* Timestamp of trace2 should not have changed */ + selectTrace(trace2); + assertEquals(trace2.getStartTime(), tm.getSelectionBeginTime()); + assertEquals(trace2.getStartTime(), tm.getSelectionEndTime()); + } + + /** + * Test, with two traces in parallel, when we select a timestamp that is + * between two traces. + * + * None of the trace's timestamps should be updated (we are not in an + * experiment!) + */ + @Test + public void testTwoTracesTimestampInBetween() { + openTrace(trace1); + openTrace(trace2); + selectTrace(trace1); + TmfTimestamp ts = new TmfTimestamp(t1end + ONE_SECOND, SCALE); + selectTimestamp(ts); + + /* Timestamp of trace1 should not have changed */ + assertEquals(trace1.getStartTime(), tm.getSelectionBeginTime()); + assertEquals(trace1.getStartTime(), tm.getSelectionEndTime()); + + /* Timestamp of trace2 should not have changed */ + selectTrace(trace2); + assertEquals(trace2.getStartTime(), tm.getSelectionBeginTime()); + assertEquals(trace2.getStartTime(), tm.getSelectionEndTime()); + } + + /** + * Test, with two traces in parallel, when we select a timestamp that is + * completely out of the trace's range. + * + * None of the trace's timestamps should be updated. + */ + @Test + public void testTwoTracesTimestampInvalid() { + openTrace(trace1); + openTrace(trace2); + selectTrace(trace1); + TmfTimestamp ts = new TmfTimestamp(t2end + ONE_SECOND, SCALE); + selectTimestamp(ts); + + /* Timestamp of trace1 should not have changed */ + assertEquals(trace1.getStartTime(), tm.getSelectionBeginTime()); + assertEquals(trace1.getStartTime(), tm.getSelectionEndTime()); + + /* Timestamp of trace2 should not have changed */ + selectTrace(trace2); + assertEquals(trace2.getStartTime(), tm.getSelectionBeginTime()); + assertEquals(trace2.getStartTime(), tm.getSelectionEndTime()); + } + + /** + * Test, with two traces opened in parallel (not in an experiment), if we + * select a time range valid in one of them. That trace's time range should + * be updated, but not the other one. + */ + @Test + public void testTwoTracesTimeRangeAllInOne() { + openTrace(trace1); + openTrace(trace2); + selectTrace(trace1); + TmfTimeRange range = new TmfTimeRange( + new TmfTimestamp(t1start + ONE_SECOND, SCALE), + new TmfTimestamp(t1end - ONE_SECOND, SCALE)); + selectTimeRange(range); + + /* Range of trace1 should be equal to the requested one */ + assertEquals(range, tm.getCurrentRange()); + + /* The range of trace 2 should not have changed */ + selectTrace(trace2); + assertEquals(getInitialRange(trace2), tm.getCurrentRange()); + } + + /** + * Test, with two traces in parallel, when we select a time range that is + * only partially valid for one of the traces. + * + * The first trace's time range should be clamped to a valid range, and the + * second one's should not change. + */ + @Test + public void testTwoTracesTimeRangePartiallyInOne() { + openTrace(trace1); + openTrace(trace2); + selectTrace(trace1); + TmfTimeRange range = new TmfTimeRange( + new TmfTimestamp(t1start + ONE_SECOND, SCALE), + new TmfTimestamp(t1end + ONE_SECOND, SCALE)); + selectTimeRange(range); + + /* Range of trace1 should get clamped to its end time */ + TmfTimeRange expectedRange = new TmfTimeRange( + new TmfTimestamp(t1start + ONE_SECOND, SCALE), + new TmfTimestamp(t1end, SCALE)); + assertEquals(expectedRange, tm.getCurrentRange()); + + /* Range of trace2 should not have changed */ + selectTrace(trace2); + assertEquals(getInitialRange(trace2), tm.getCurrentRange()); + } + + /** + * Test, with two traces in parallel, when we select a time range that is + * only partially valid for both traces. + * + * Each trace's time range should get clamped to respectively valid ranges. + */ + @Test + public void testTwoTracesTimeRangeInBoth() { + openTrace(trace1); + openTrace(trace2); + selectTrace(trace1); + TmfTimeRange range = new TmfTimeRange( + new TmfTimestamp(t1end - ONE_SECOND, SCALE), + new TmfTimestamp(t2start + ONE_SECOND, SCALE)); + selectTimeRange(range); + + /* Range of trace1 should be clamped to its end time */ + TmfTimeRange expectedRange = new TmfTimeRange( + new TmfTimestamp(t1end - ONE_SECOND, SCALE), + new TmfTimestamp(t1end, SCALE)); + assertEquals(expectedRange, tm.getCurrentRange()); + + /* Range of trace2 should be clamped to its start time */ + selectTrace(trace2); + expectedRange = new TmfTimeRange( + new TmfTimestamp(t2start, SCALE), + new TmfTimestamp(t2start + ONE_SECOND, SCALE)); + assertEquals(expectedRange, tm.getCurrentRange()); + } + + /** + * Test, with two traces in parallel, when we select a time range that is + * not valid for any trace. + * + * Each trace's time range should not be modified. + */ + @Test + public void testTwoTracesTimeRangeInBetween() { + openTrace(trace1); + openTrace(trace2); + selectTrace(trace1); + TmfTimeRange range = new TmfTimeRange( + new TmfTimestamp(t1end + ONE_SECOND, SCALE), + new TmfTimestamp(t1end - ONE_SECOND, SCALE)); + selectTimeRange(range); + + /* Range of trace1 should not have changed */ + TmfTimeRange expectedRange = getInitialRange(trace1); + TmfTimeRange curRange = tm.getCurrentRange(); + assertEquals(expectedRange.getStartTime(), curRange.getStartTime()); + assertEquals(expectedRange.getEndTime(), curRange.getEndTime()); + + /* Range of trace2 should not have changed */ + selectTrace(trace2); + expectedRange = getInitialRange(trace2); + curRange = tm.getCurrentRange(); + assertEquals(expectedRange.getStartTime(), curRange.getStartTime()); + assertEquals(expectedRange.getEndTime(), curRange.getEndTime()); + } + + // ------------------------------------------------------------------------ + // Test an experiment + // ------------------------------------------------------------------------ + + /** + * Test in an experiment when we select a timestamp that is part of one of + * the experiment's traces. + * + * The experiment's current time should be correctly updated. + */ + @Test + public void testExperimentTimestampInTrace() { + TmfExperiment exp = createExperiment(trace1, trace2); + openTrace(exp); + TmfTimestamp ts = new TmfTimestamp(t1start + ONE_SECOND, SCALE); + selectTimestamp(ts); + + /* The experiment's current time should be updated. */ + assertEquals(ts, tm.getSelectionBeginTime()); + assertEquals(ts, tm.getSelectionEndTime()); + } + + /** + * Test in an experiment when we select a timestamp that is between two + * traces in the experiment. + * + * The experiment's current time should still be updated, since the + * timestamp is valid in the experiment itself. + */ + @Test + public void testExperimentTimestampInBetween() { + TmfExperiment exp = createExperiment(trace1, trace2); + openTrace(exp); + TmfTimestamp ts = new TmfTimestamp(t1end + ONE_SECOND, SCALE); + selectTimestamp(ts); + + /* The experiment's current time should be updated. */ + assertEquals(ts, tm.getSelectionBeginTime()); + assertEquals(ts, tm.getSelectionEndTime()); + } + + /** + * Test in an experiment when we select a timestamp that is outside of the + * total range of the experiment. + * + * The experiment's current time should not be updated. + */ + @Test + public void testExperimentTimestampInvalid() { + TmfExperiment exp = createExperiment(trace1, trace2); + openTrace(exp); + TmfTimestamp ts = new TmfTimestamp(t2end + ONE_SECOND, SCALE); + selectTimestamp(ts); + + /* The experiment's current time should NOT be updated. */ + assertEquals(trace1.getStartTime(), tm.getSelectionBeginTime()); + assertEquals(trace1.getStartTime(), tm.getSelectionEndTime()); + } + + /** + * Test the initial range of an experiment. + */ + @Test + public void testExperimentInitialRange() { + TmfExperiment exp = createExperiment(trace1, trace2); + openTrace(exp); + /* + * The initial range should be == to the initial range of the earliest + * trace (here trace1). + */ + final TmfTimeRange actualRange = tm.getCurrentRange(); + + assertEquals(getInitialRange(trace1), actualRange); + assertEquals(getInitialRange(exp), actualRange); + } + + /** + * Test the range clamping with the start time of the range outside of the + * earliest trace's range. Only that start time should get clamped. + */ + @Test + public void testExperimentRangeClampingOne() { + TmfExperiment exp = createExperiment(trace1, trace2); + openTrace(exp); + + final TmfTimeRange range = new TmfTimeRange( + new TmfTimestamp(t1start - ONE_SECOND, SCALE), + new TmfTimestamp(t1end - ONE_SECOND, SCALE)); + selectTimeRange(range); + + TmfTimeRange actualRange = tm.getCurrentRange(); + assertEquals(t1start, actualRange.getStartTime().getValue()); + assertEquals(t1end - ONE_SECOND, actualRange.getEndTime().getValue()); + } + + /** + * Test the range clamping when both the start and end times of the signal's + * range are outside of the trace's range. The range should clamp to the + * experiment's range. + */ + @Test + public void testExperimentRangeClampingBoth() { + TmfExperiment exp = createExperiment(trace1, trace2); + openTrace(exp); + + final TmfTimeRange range = new TmfTimeRange( + new TmfTimestamp(t1start - ONE_SECOND, SCALE), + new TmfTimestamp(t2end + ONE_SECOND, SCALE)); + selectTimeRange(range); + + TmfTimeRange actualRange = tm.getCurrentRange(); + assertEquals(t1start, actualRange.getStartTime().getValue()); + assertEquals(t2end, actualRange.getEndTime().getValue()); + } + + /** + * Test selecting a range in-between two disjoint traces in an experiment. + * The range should still get correctly selected, even if no trace has any + * events in that range. + */ + @Test + public void testExperimentRangeInBetween() { + TmfExperiment exp = createExperiment(trace1, trace2); + openTrace(exp); + + final TmfTimeRange range = new TmfTimeRange( + new TmfTimestamp(t1end + ONE_SECOND, SCALE), + new TmfTimestamp(t2start - ONE_SECOND, SCALE)); + selectTimeRange(range); + + TmfTimeRange actualRange = tm.getCurrentRange(); + assertEquals(range, actualRange); + } + + // ------------------------------------------------------------------------ + // Utility methods + // ------------------------------------------------------------------------ + + private static TmfExperiment createExperiment(ITmfTrace t1, ITmfTrace t2) { + ITmfTrace[] traces = new ITmfTrace[] { t1, t2 }; + TmfExperiment exp = new TmfExperiment(ITmfEvent.class, "test-exp", traces); + exp.indexTrace(true); + // Deregister experiment from signal manager so that it doesn't + // interfere with the TmfTraceManager tests + TmfSignalManager.deregister(exp); + return exp; + } + + private static TmfTimeRange getInitialRange(ITmfTrace trace) { + return new TmfTimeRange( + trace.getStartTime(), + calculateOffset(trace.getStartTime(), trace.getInitialRangeOffset())); + } + + /** + * Basically a "initial + offset" operation, but for ITmfTimetamp objects. + */ + private static ITmfTimestamp calculateOffset(ITmfTimestamp initialTs, ITmfTimestamp offsetTs) { + long start = initialTs.normalize(0, SCALE).getValue(); + long offset = offsetTs.normalize(0, SCALE).getValue(); + return new TmfTimestamp(start + offset, SCALE); + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/stubs/org/eclipse/linuxtools/tmf/ctf/core/tests/stubs/CtfTmfTraceStub.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/stubs/org/eclipse/linuxtools/tmf/ctf/core/tests/stubs/CtfTmfTraceStub.java deleted file mode 100644 index 5a52a131b4..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core.tests/stubs/org/eclipse/linuxtools/tmf/ctf/core/tests/stubs/CtfTmfTraceStub.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core.tests.stubs; - -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; - -/** - * Dummy test ctf trace - */ -public class CtfTmfTraceStub extends CtfTmfTrace { - - /** - * Simulate trace opening, to be called by tests who need an actively opened - * trace - */ - public void openTrace() { - TmfSignalManager.dispatchSignal(new TmfTraceOpenedSignal(this, this, null)); - selectTrace(); - } - - /** - * Simulate selecting the trace - */ - public void selectTrace() { - TmfSignalManager.dispatchSignal(new TmfTraceSelectedSignal(this, this)); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core.tests/stubs/org/eclipse/tracecompass/tmf/ctf/core/tests/stubs/CtfTmfTraceStub.java b/org.eclipse.tracecompass.tmf.ctf.core.tests/stubs/org/eclipse/tracecompass/tmf/ctf/core/tests/stubs/CtfTmfTraceStub.java new file mode 100644 index 0000000000..0e968f182b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core.tests/stubs/org/eclipse/tracecompass/tmf/ctf/core/tests/stubs/CtfTmfTraceStub.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core.tests.stubs; + +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; + +/** + * Dummy test ctf trace + */ +public class CtfTmfTraceStub extends CtfTmfTrace { + + /** + * Simulate trace opening, to be called by tests who need an actively opened + * trace + */ + public void openTrace() { + TmfSignalManager.dispatchSignal(new TmfTraceOpenedSignal(this, this, null)); + selectTrace(); + } + + /** + * Simulate selecting the trace + */ + public void selectTrace() { + TmfSignalManager.dispatchSignal(new TmfTraceSelectedSignal(this, this)); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/META-INF/MANIFEST.MF b/org.eclipse.tracecompass.tmf.ctf.core/META-INF/MANIFEST.MF index d8f5e28445..db5c2f7f64 100644 --- a/org.eclipse.tracecompass.tmf.ctf.core/META-INF/MANIFEST.MF +++ b/org.eclipse.tracecompass.tmf.ctf.core/META-INF/MANIFEST.MF @@ -5,14 +5,14 @@ Bundle-Vendor: %Bundle-Vendor Bundle-Version: 3.1.0.qualifier Bundle-Localization: plugin Bundle-SymbolicName: org.eclipse.tracecompass.tmf.ctf.core;singleton:=true -Bundle-Activator: org.eclipse.linuxtools.internal.tmf.ctf.core.Activator +Bundle-Activator: org.eclipse.tracecompass.internal.tmf.ctf.core.Activator Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.resources, org.eclipse.tracecompass.ctf.core;bundle-version="3.1.0", org.eclipse.tracecompass.tmf.core;bundle-version="3.1.0" -Export-Package: org.eclipse.linuxtools.internal.tmf.ctf.core;x-internal:=true, - org.eclipse.linuxtools.tmf.ctf.core +Export-Package: org.eclipse.tracecompass.internal.tmf.ctf.core;x-internal:=true, + org.eclipse.tracecompass.tmf.ctf.core Import-Package: com.google.common.collect, org.eclipse.emf.common.util diff --git a/org.eclipse.tracecompass.tmf.ctf.core/plugin.xml b/org.eclipse.tracecompass.tmf.ctf.core/plugin.xml index edf9524381..a126f9aa8c 100644 --- a/org.eclipse.tracecompass.tmf.ctf.core/plugin.xml +++ b/org.eclipse.tracecompass.tmf.ctf.core/plugin.xml @@ -9,11 +9,11 @@ + trace_type="org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace"> diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/internal/tmf/ctf/core/Activator.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/internal/tmf/ctf/core/Activator.java deleted file mode 100644 index 6a13879c8b..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/internal/tmf/ctf/core/Activator.java +++ /dev/null @@ -1,137 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ctf.core; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Plugin; -import org.eclipse.core.runtime.Status; -import org.osgi.framework.BundleContext; - -/** - * Activator - *

- * The activator class controls the plug-in life cycle - */ -public class Activator extends Plugin { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The plug-in ID - */ - public static final String PLUGIN_ID = "org.eclipse.linuxtools.tmf.ctf.core"; //$NON-NLS-1$ - - /** - * The shared instance - */ - private static Activator plugin; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * The constructor - */ - public Activator() { - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static Activator getDefault() { - return plugin; - } - - // ------------------------------------------------------------------------ - // Operators - // ------------------------------------------------------------------------ - - @Override - public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - } - - @Override - public void stop(BundleContext context) throws Exception { - plugin = null; - super.stop(context); - } - - /** - * Logs a message with severity INFO in the runtime log of the plug-in. - * - * @param message A message to log - */ - public void logInfo(String message) { - getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity INFO in the runtime log of the plug-in. - * - * @param message A message to log - * @param exception A exception to log - */ - public void logInfo(String message, Throwable exception) { - getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message, exception)); - } - - /** - * Logs a message and exception with severity WARNING in the runtime log of the plug-in. - * - * @param message A message to log - */ - public void logWarning(String message) { - getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity WARNING in the runtime log of the plug-in. - * - * @param message A message to log - * @param exception A exception to log - */ - public void logWarning(String message, Throwable exception) { - getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message, exception)); - } - - /** - * Logs a message and exception with severity ERROR in the runtime log of the plug-in. - * - * @param message A message to log - */ - public void logError(String message) { - getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity ERROR in the runtime log of the plug-in. - * - * @param message A message to log - * @param exception A exception to log - */ - public void logError(String message, Throwable exception) { - getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, exception)); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfConstants.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfConstants.java deleted file mode 100644 index 97fd143c5b..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfConstants.java +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson, Ecole Polytechnique de Montreal and others - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ansgar Radermacher - support for model URI - * Patrick Tasse - context strings - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core; - -import org.eclipse.core.runtime.QualifiedName; - -/** - * Set of constants used by the CTF adaptor classes - * - * @since 2.0 - * @noimplement This interface is not intended to be implemented by clients. - */ -@SuppressWarnings("nls") -public interface CtfConstants { - - /* - * Context strings - */ - - /** Prefix for context information stored as CtfTmfEventfield */ - public static final String CONTEXT_FIELD_PREFIX = "context."; - - /** Key for ip field */ - public static final String IP_KEY = "_ip"; - - /* - * Custom attributes names (key within hash table) - */ - - /** Model URI for traces related to EMF models */ - public final String MODEL_URI_KEY = "model.emf.uri"; - - /** - * The host persistent property for the live session. - * - * @since 3.1 - */ - QualifiedName LIVE_HOST = new QualifiedName("org.eclipse.linuxtools.tmf.ctf.core", "live.host"); //$NON-NLS-1$//$NON-NLS-2$ - - /** - * The port persistent property for the live session. - * - * @since 3.1 - */ - QualifiedName LIVE_PORT = new QualifiedName("org.eclipse.linuxtools.tmf.ctf.core", "live.port"); //$NON-NLS-1$//$NON-NLS-2$ - - /** - * The live session name persistent property. - * - * @since 3.1 - */ - QualifiedName LIVE_SESSION_NAME = new QualifiedName("org.eclipse.linuxtools.tmf.ctf.core", "live.session.name"); //$NON-NLS-1$//$NON-NLS-2$; -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfEnumPair.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfEnumPair.java deleted file mode 100644 index f27894d0dc..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfEnumPair.java +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core; - -import org.eclipse.linuxtools.tmf.core.util.Pair; - -/** - * Pair of Enum value name and its long value. - * - * @author Bernd Hufmann - * @since 2.0 - */ -public class CtfEnumPair extends Pair { - - /** - * Constructs a CtfEnumPair - * - * @param strValue - * The first parameter of the pair (String) - * @param longValue - * The second parameter of the pair (Long) - */ - public CtfEnumPair(String strValue, Long longValue) { - super(strValue, longValue); - } - - /** - * Returns the String value of the Enum. - * - * @return the string value - */ - public String getStringValue() { - return getFirst(); - } - - /** - * Returns the long value of the Enum. - * - * @return the Long value - */ - public Long getLongValue() { - return getSecond(); - } - - @Override - public String toString() { - return getFirst(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfIterator.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfIterator.java deleted file mode 100644 index 7d384fbcbd..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfIterator.java +++ /dev/null @@ -1,353 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Florian Wininger - Performance improvements - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core; - -import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException; -import org.eclipse.linuxtools.ctf.core.trace.CTFStreamInputReader; -import org.eclipse.linuxtools.ctf.core.trace.CTFTraceReader; -import org.eclipse.linuxtools.internal.tmf.ctf.core.Activator; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - -/** - * The CTF trace reader iterator. - * - * It doesn't reserve a file handle, so many iterators can be used without - * worries of I/O errors or resource exhaustion. - * - * @author Matthew Khouzam - */ -public class CtfIterator extends CTFTraceReader - implements ITmfContext, Comparable { - - /** An invalid location */ - public static final CtfLocation NULL_LOCATION = new CtfLocation(CtfLocation.INVALID_LOCATION); - - private final CtfTmfTrace fTrace; - - private CtfLocation fCurLocation; - private long fCurRank; - - private CtfLocation fPreviousLocation; - private CtfTmfEvent fPreviousEvent; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Create a new CTF trace iterator, which initially points at the first - * event in the trace. - * - * @param trace - * The trace to iterate over - * @throws CTFReaderException - * If the iterator couldn't not be instantiated, probably due to - * a read error. - */ - public CtfIterator(CtfTmfTrace trace) throws CTFReaderException { - super(trace.getCTFTrace()); - fTrace = trace; - if (hasMoreEvents()) { - fCurLocation = new CtfLocation(trace.getStartTime()); - fCurRank = 0; - } else { - setUnknownLocation(); - } - } - - /** - * Create a new CTF trace iterator, which will initially point to the given - * location/rank. - * - * @param trace - * The trace to iterate over - * @param ctfLocationData - * The initial timestamp the iterator will be pointing to - * @param rank - * The initial rank - * @throws CTFReaderException - * If the iterator couldn't not be instantiated, probably due to - * a read error. - * @since 2.0 - */ - public CtfIterator(CtfTmfTrace trace, CtfLocationInfo ctfLocationData, long rank) - throws CTFReaderException { - super(trace.getCTFTrace()); - - this.fTrace = trace; - if (this.hasMoreEvents()) { - this.fCurLocation = new CtfLocation(ctfLocationData); - if (this.getCurrentEvent().getTimestamp().getValue() != ctfLocationData.getTimestamp()) { - this.seek(ctfLocationData); - this.fCurRank = rank; - } - } else { - setUnknownLocation(); - } - } - - @Override - public void dispose() { - close(); - } - - private void setUnknownLocation() { - fCurLocation = NULL_LOCATION; - fCurRank = UNKNOWN_RANK; - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Return this iterator's trace. - * - * @return CtfTmfTrace The iterator's trace - */ - public CtfTmfTrace getCtfTmfTrace() { - return fTrace; - } - - /** - * Return the current event pointed to by the iterator. - * - * @return CtfTmfEvent The current event - */ - public synchronized CtfTmfEvent getCurrentEvent() { - final CTFStreamInputReader top = super.getPrio().peek(); - if (top != null) { - if (!fCurLocation.equals(fPreviousLocation)) { - fPreviousLocation = fCurLocation; - fPreviousEvent = CtfTmfEventFactory.createEvent(top.getCurrentEvent(), - top.getFilename(), fTrace); - } - return fPreviousEvent; - } - return null; - } - - /** - * Return the current timestamp location pointed to by the iterator. - * This is the timestamp for use in CtfLocation, not the event timestamp. - * - * @return long The current timestamp location - */ - public synchronized long getCurrentTimestamp() { - final CTFStreamInputReader top = super.getPrio().peek(); - if (top != null) { - long ts = top.getCurrentEvent().getTimestamp(); - return fTrace.getCTFTrace().timestampCyclesToNanos(ts); - } - return 0; - } - - /** - * Seek this iterator to a given location. - * - * @param ctfLocationData - * The LocationData representing the position to seek to - * @return boolean True if the seek was successful, false if there was an - * error seeking. - * @since 2.0 - */ - public synchronized boolean seek(CtfLocationInfo ctfLocationData) { - boolean ret = false; - - /* Avoid the cost of seeking at the current location. */ - if (fCurLocation.getLocationInfo().equals(ctfLocationData)) { - return super.hasMoreEvents(); - } - - /* Adjust the timestamp depending on the trace's offset */ - long currTimestamp = ctfLocationData.getTimestamp(); - final long offsetTimestamp = this.getCtfTmfTrace().getCTFTrace().timestampNanoToCycles(currTimestamp); - try { - if (offsetTimestamp < 0) { - ret = super.seek(0L); - } else { - ret = super.seek(offsetTimestamp); - } - } catch (CTFReaderException e) { - Activator.getDefault().logError(e.getMessage(), e); - return false; - } - /* - * Check if there is already one or more events for that timestamp, and - * assign the location index correctly - */ - long index = 0; - final CtfTmfEvent currentEvent = this.getCurrentEvent(); - if (currentEvent != null) { - currTimestamp = currentEvent.getTimestamp().getValue(); - - for (long i = 0; i < ctfLocationData.getIndex(); i++) { - if (currTimestamp == currentEvent.getTimestamp().getValue()) { - index++; - } else { - index = 0; - } - this.advance(); - } - } else { - ret = false; - } - /* Seek the current location accordingly */ - if (ret) { - fCurLocation = new CtfLocation(new CtfLocationInfo(getCurrentEvent().getTimestamp().getValue(), index)); - } else { - fCurLocation = NULL_LOCATION; - } - - return ret; - } - - // ------------------------------------------------------------------------ - // CTFTraceReader - // ------------------------------------------------------------------------ - - @Override - public boolean seek(long timestamp) { - return seek(new CtfLocationInfo(timestamp, 0)); - } - - @Override - public synchronized boolean advance() { - boolean ret = false; - try { - ret = super.advance(); - } catch (CTFReaderException e) { - Activator.getDefault().logError(e.getMessage(), e); - } - - if (ret) { - long timestamp = fCurLocation.getLocationInfo().getTimestamp(); - final long timestampValue = getCurrentTimestamp(); - if (timestamp == timestampValue) { - long index = fCurLocation.getLocationInfo().getIndex(); - fCurLocation = new CtfLocation(timestampValue, index + 1); - } else { - fCurLocation = new CtfLocation(timestampValue, 0L); - } - } else { - fCurLocation = NULL_LOCATION; - } - return ret; - } - - // ------------------------------------------------------------------------ - // ITmfContext - // ------------------------------------------------------------------------ - - @Override - public long getRank() { - return fCurRank; - } - - @Override - public void setRank(long rank) { - fCurRank = rank; - } - - @Override - public void increaseRank() { - /* Only increase the rank if it's valid */ - if (hasValidRank()) { - fCurRank++; - } - } - - @Override - public boolean hasValidRank() { - return (getRank() >= 0); - } - - /** - * @since 3.0 - */ - @Override - public void setLocation(ITmfLocation location) { - // FIXME alex: isn't there a cleaner way than a cast here? - fCurLocation = (CtfLocation) location; - seek(((CtfLocation) location).getLocationInfo()); - } - - @Override - public CtfLocation getLocation() { - return fCurLocation; - } - - // ------------------------------------------------------------------------ - // Comparable - // ------------------------------------------------------------------------ - - @Override - public int compareTo(final CtfIterator o) { - if (getRank() < o.getRank()) { - return -1; - } else if (getRank() > o.getRank()) { - return 1; - } - return 0; - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = (prime * result) - + ((fTrace == null) ? 0 : fTrace.hashCode()); - result = (prime * result) - + ((fCurLocation == null) ? 0 : fCurLocation.hashCode()); - result = (prime * result) + (int) (fCurRank ^ (fCurRank >>> 32)); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof CtfIterator)) { - return false; - } - CtfIterator other = (CtfIterator) obj; - if (fTrace == null) { - if (other.fTrace != null) { - return false; - } - } else if (!fTrace.equals(other.fTrace)) { - return false; - } - if (fCurLocation == null) { - if (other.fCurLocation != null) { - return false; - } - } else if (!fCurLocation.equals(other.fCurLocation)) { - return false; - } - if (fCurRank != other.fCurRank) { - return false; - } - return true; - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfIteratorManager.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfIteratorManager.java deleted file mode 100644 index 7ca324f5eb..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfIteratorManager.java +++ /dev/null @@ -1,229 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Simon Delisle - Added a method to remove the iterator - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ctf.core; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Random; - -/** - * Ctf Iterator Manager, allows mapping of iterators (a limited resource) to - * contexts (many many resources). - * - * @author Matthew Khouzam - * @version 1.0 - * @since 1.1 - */ -public abstract class CtfIteratorManager { - /* - * A side note synchronized works on the whole object, Therefore add and - * remove will be thread safe. - */ - - /* - * The map of traces to trace managers. - */ - private static HashMap map = new HashMap<>(); - - /** - * Registers a trace to the iterator manager, the trace can now get - * iterators. - * - * @param trace - * the trace to register. - */ - public static synchronized void addTrace(final CtfTmfTrace trace) { - map.put(trace, new CtfTraceManager(trace)); - } - - /** - * Removes a trace to the iterator manager. - * - * @param trace - * the trace to register. - */ - public static synchronized void removeTrace(final CtfTmfTrace trace) { - CtfTraceManager mgr = map.remove(trace); - if (mgr != null) { - mgr.clear(); - } - } - - /** - * Get an iterator for a given trace and context. - * - * @param trace - * the trace - * @param ctx - * the context - * @return the iterator - * @since 2.0 - */ - public static synchronized CtfIterator getIterator(final CtfTmfTrace trace, - final CtfTmfContext ctx) { - return map.get(trace).getIterator(ctx); - } - - /** - * Remove an iterator for a given trace and context - * - * @param trace - * the trace - * @param ctx - * the context - * @since 2.1 - */ - public static synchronized void removeIterator(final CtfTmfTrace trace, final CtfTmfContext ctx) { - CtfTraceManager traceManager = map.get(trace); - if (traceManager != null) { - traceManager.removeIterator(ctx); - } - } -} - -/** - * A trace manager - * - * @author Matthew Khouzam - */ -class CtfTraceManager { - /* - * Cache size. Under 1023 on linux32 systems. Number of file handles - * created. - */ - private final static int MAX_SIZE = 100; - /* - * The map of the cache. - */ - private final HashMap fMap; - /* - * An array pointing to the same cache. this allows fast "random" accesses. - */ - private final ArrayList fRandomAccess; - /* - * The parent trace - */ - private final CtfTmfTrace fTrace; - /* - * Random number generator - */ - private final Random fRnd; - - public CtfTraceManager(CtfTmfTrace trace) { - fMap = new HashMap<>(); - fRandomAccess = new ArrayList<>(); - fRnd = new Random(System.nanoTime()); - fTrace = trace; - } - - /** - * This needs explaining: the iterator table is effectively a cache. - * Originally the contexts had a 1 to 1 structure with the file handles of a - * trace. This failed since there is a limit to how many file handles we can - * have opened simultaneously. Then a round-robin scheme was implemented, - * this lead up to a two competing contexts syncing up and using the same - * file handler, causing horrible slowdowns. Now a random replacement - * algorithm is selected. This is the same as used by arm processors, and it - * works quite well when many cores so this looks promising for very - * multi-threaded systems. - * - * @param context - * the context to look up - * @return the iterator referring to the context - */ - public CtfIterator getIterator(final CtfTmfContext context) { - /* - * if the element is in the map, we don't need to do anything else. - */ - CtfIterator retVal = fMap.get(context); - if (retVal == null) { - /* - * Assign an iterator to a context, this means we will need to seek - * at the end. - */ - if (fRandomAccess.size() < MAX_SIZE) { - /* - * if we're not full yet, just add an element. - */ - retVal = fTrace.createIterator(); - addElement(context, retVal); - - } else { - /* - * if we're full, randomly replace an element - */ - retVal = replaceRandomElement(context); - } - if (context.getLocation() != null) { - final CtfLocationInfo location = (CtfLocationInfo) context.getLocation().getLocationInfo(); - retVal.seek(location); - } - } - return retVal; - } - - public void removeIterator(CtfTmfContext context) { - try (CtfIterator removed = fMap.remove(context)) { - } - - fRandomAccess.remove(context); - } - - /** - * Add a pair of context and element to the hashmap and the arraylist. - * - * @param context - * the context - * @param elem - * the iterator - */ - private void addElement(final CtfTmfContext context, - final CtfIterator elem) { - fMap.put(context, elem); - fRandomAccess.add(context); - } - - /** - * Replace a random element - * - * @param context - * the context to swap in - * @return the iterator of the removed elements. - */ - private CtfIterator replaceRandomElement( - final CtfTmfContext context) { - /* - * This needs some explanation too: We need to select a random victim - * and remove it. The order of the elements is not important, so instead - * of just calling arraylist.remove(element) which has an O(n) - * complexity, we pick an random number. The element is swapped out of - * the array and removed and replaced in the hashmap. - */ - final int size = fRandomAccess.size(); - final int pos = fRnd.nextInt(size); - final CtfTmfContext victim = fRandomAccess.get(pos); - fRandomAccess.set(pos, context); - final CtfIterator elem = fMap.remove(victim); - fMap.put(context, elem); - victim.dispose(); - return elem; - } - - void clear() { - for (CtfIterator iterator : fMap.values()) { - iterator.dispose(); - } - fMap.clear(); - fRandomAccess.clear(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfLocation.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfLocation.java deleted file mode 100644 index e909c8face..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfLocation.java +++ /dev/null @@ -1,147 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Alexandre Montplaisir - Extends TmfLocation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ctf.core; - -import java.nio.ByteBuffer; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLocation; - -/** - * The nugget of information that is unique to a location in a CTF trace. - * - * It can be copied and used to restore a position in a given trace. - * - * @version 1.0 - * @author Matthew Khouzam - */ -public final class CtfLocation extends TmfLocation { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * An invalid location - */ - public static final CtfLocationInfo INVALID_LOCATION = new CtfLocationInfo(-1, -1); - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Basic constructor for CtfLocation. Uses a default index of 0. - * - * @param timestamp - * The timestamp of this location - * @since 2.0 - */ - public CtfLocation(final ITmfTimestamp timestamp) { - this(timestamp.getValue(), 0); - } - - /** - * Constructor using timestamp object and index - * - * @param timestamp - * The timestamp of this location - * @param index - * The index of this location for this timestamp - * @since 2.0 - */ - public CtfLocation(final ITmfTimestamp timestamp, long index) { - this(timestamp.getValue(), index); - } - - /** - * Constructor using a long value for the timestamp, and an index - * - * @param timestampValue - * The new timestamp - * @param index - * The new index - * @since 2.0 - */ - public CtfLocation(final long timestampValue, final long index) { - super(new CtfLocationInfo(timestampValue, index)); - } - - /** - * Constructor using a pre-made locationInfo object - * - * @param locationInfo - * The locationInfo object to use - * @since 2.0 - */ - public CtfLocation(CtfLocationInfo locationInfo) { - super(locationInfo); - } - - /** - * Copy constructor - * - * @param location - * Other location to copy - * @since 2.0 - */ - public CtfLocation(final CtfLocation location) { - super(location); - } - - // ------------------------------------------------------------------------ - // TmfLocation - // ------------------------------------------------------------------------ - - /** - * Construct the location from the ByteBuffer. - * - * @param bufferIn - * the buffer to read from - * - * @since 3.0 - */ - public CtfLocation(ByteBuffer bufferIn) { - super(new CtfLocationInfo(bufferIn)); - } - - /** - * @since 2.0 - */ - @Override - public CtfLocationInfo getLocationInfo() { - return (CtfLocationInfo) super.getLocationInfo(); - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public String toString() { - if (getLocationInfo().equals(CtfLocation.INVALID_LOCATION )) { - return getClass().getSimpleName() + " [INVALID]"; //$NON-NLS-1$ - } - return super.toString(); - } - - /** - * Constructs the location from the ByteBuffer. This typically happens when reading from disk. - * - * @since 3.0 - */ - @Override - public void serialize(ByteBuffer bufferOut) { - getLocationInfo().serialize(bufferOut); - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfLocationInfo.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfLocationInfo.java deleted file mode 100644 index c0088ac578..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfLocationInfo.java +++ /dev/null @@ -1,137 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: Matthew Khouzam - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ctf.core; - -import java.nio.ByteBuffer; - -/** - * The data object to go in a {@link CtfLocation}. - * - * @author Matthew Khouzam - * @since 2.0 - */ -public class CtfLocationInfo implements Comparable { - - private final long fTimestamp; - private final long fIndex; - - /** - * @param ts - * Timestamp - * @param index - * Index of this event (if there are N elements with the same - * timestamp, which one is it.) - */ - public CtfLocationInfo(long ts, long index) { - fTimestamp = ts; - fIndex = index; - } - - /** - * Construct the location from the ByteBuffer. - * - * @param bufferIn - * the buffer to read from - * - * @since 3.0 - */ - public CtfLocationInfo(ByteBuffer bufferIn) { - fTimestamp = bufferIn.getLong(); - fIndex = bufferIn.getLong(); - } - - /** - * @return The timestamp - */ - public long getTimestamp() { - return fTimestamp; - } - - /** - * @return The index of the element - */ - public long getIndex() { - return fIndex; - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + (int) (fIndex ^ (fIndex >>> 32)); - result = (prime * result) + (int) (fTimestamp ^ (fTimestamp >>> 32)); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof CtfLocationInfo)) { - return false; - } - CtfLocationInfo other = (CtfLocationInfo) obj; - if (fIndex != other.fIndex) { - return false; - } - if (fTimestamp != other.fTimestamp) { - return false; - } - return true; - } - - @Override - public String toString() { - return "Element [" + fTimestamp + '/' + fIndex + ']'; //$NON-NLS-1$ - } - - // ------------------------------------------------------------------------ - // Comparable - // ------------------------------------------------------------------------ - - @Override - public int compareTo(CtfLocationInfo other) { - if (fTimestamp > other.getTimestamp()) { - return 1; - } - if (fTimestamp < other.getTimestamp()) { - return -1; - } - if (fIndex > other.getIndex()) { - return 1; - } - if (fIndex < other.getIndex()) { - return -1; - } - return 0; - } - - /** - * Write the location to the ByteBuffer so that it can be saved to disk. - * - * @param bufferOut - * the buffer to write to - * - * @since 3.0 - */ - public void serialize(ByteBuffer bufferOut) { - bufferOut.putLong(fTimestamp); - bufferOut.putLong(fIndex); - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfCallsite.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfCallsite.java deleted file mode 100644 index 867db01d42..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfCallsite.java +++ /dev/null @@ -1,116 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Bernd Hufmann - Updated for new parent class - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core; - -import org.eclipse.linuxtools.ctf.core.event.CTFCallsite; -import org.eclipse.linuxtools.tmf.core.event.lookup.TmfCallsite; - -/** - * CTF TMF call site information for source code lookup. - * - * @author Patrick Tasse - * @since 2.0 - */ -public class CtfTmfCallsite extends TmfCallsite { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** The event name. */ - final private String fEventName; - - /** The instruction pointer. */ - final private long fInstructionPointer; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Standard Constructor. - * - * @param callsite - * - a CTF call site - */ - CtfTmfCallsite(CTFCallsite callsite) { - super(callsite.getFileName(), callsite.getFunctionName(), callsite.getLineNumber()); - fEventName = callsite.getEventName(); - fInstructionPointer = callsite.getIp(); - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Returns the event name of the call site. - * @return the event name - */ - public String getEventName() { - return fEventName; - } - - /** - * Returns the instruction pointer of the call site. - * @return the instruction pointer - */ - public long getIntructionPointer() { - return fInstructionPointer; - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((fEventName == null) ? 0 : fEventName.hashCode()); - result = prime * result + (int) (fInstructionPointer ^ (fInstructionPointer >>> 32)); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - CtfTmfCallsite other = (CtfTmfCallsite) obj; - if (fEventName == null) { - if (other.fEventName != null) { - return false; - } - } else if (!fEventName.equals(other.fEventName)) { - return false; - } - if (fInstructionPointer != other.fInstructionPointer) { - return false; - } - return true; - } - - @Override - public String toString() { - return getEventName() + "@0x" + Long.toHexString(fInstructionPointer) + ": " + //$NON-NLS-1$ //$NON-NLS-2$ - getFileName() + ':' + Long.toString(getLineNumber()) + ' ' + getFileName() + "()"; //$NON-NLS-1$ - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfContext.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfContext.java deleted file mode 100644 index 0825b84f2f..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfContext.java +++ /dev/null @@ -1,202 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Simon Delisle - Remove the iterator in dispose() - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core; - -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - -/** - * Lightweight Context for CtfTmf traces. Should only use 3 references, 1 ref to - * a boxed Long, a long and an int. - * - * @author Matthew Khouzam - * @version 1.0 - * @since 2.0 - */ -public class CtfTmfContext implements ITmfContext { - - // ------------------------------------------- - // Fields - // ------------------------------------------- - - private CtfLocation fCurLocation; - private long fCurRank; - - private final CtfTmfTrace fTrace; - - // ------------------------------------------- - // Constructor - // ------------------------------------------- - - /** - * Constructor - * - * @param ctfTmfTrace - * the parent trace - * @since 1.1 - */ - public CtfTmfContext(CtfTmfTrace ctfTmfTrace) { - fTrace = ctfTmfTrace; - fCurLocation = new CtfLocation(new CtfLocationInfo(0, 0)); - } - - // ------------------------------------------- - // TmfContext Overrides - // ------------------------------------------- - - @Override - public long getRank() { - return fCurRank; - } - - /** - * @since 3.0 - */ - @Override - public synchronized ITmfLocation getLocation() { - return fCurLocation; - } - - @Override - public boolean hasValidRank() { - return fCurRank != CtfLocation.INVALID_LOCATION.getTimestamp(); - } - - /** - * @since 3.0 - */ - @Override - public synchronized void setLocation(ITmfLocation location) { - fCurLocation = (CtfLocation) location; - if (fCurLocation != null) { - getIterator().seek(fCurLocation.getLocationInfo()); - } - } - - @Override - public void setRank(long rank) { - fCurRank = rank; - - } - - @Override - public void increaseRank() { - if (hasValidRank()) { - fCurRank++; - } - } - - // ------------------------------------------- - // CtfTmfTrace Helpers - // ------------------------------------------- - - /** - * Gets the trace of this context. - * - * @return The trace of this context - */ - public CtfTmfTrace getTrace() { - return fTrace; - } - - /** - * Gets the current event. Wrapper to help CtfTmfTrace - * - * @return The event or null - */ - public synchronized CtfTmfEvent getCurrentEvent() { - return getIterator().getCurrentEvent(); - } - - /** - * Advances to a the next event. Wrapper to help CtfTmfTrace - * - * @return success or not - */ - public synchronized boolean advance() { - final CtfLocationInfo curLocationData = fCurLocation.getLocationInfo(); - CtfIterator iterator = getIterator(); - boolean retVal = iterator.advance(); - CtfTmfEvent currentEvent = iterator.getCurrentEvent(); - - if (currentEvent != null) { - final long timestampValue = iterator.getCurrentTimestamp(); - if (curLocationData.getTimestamp() == timestampValue) { - fCurLocation = new CtfLocation(timestampValue, curLocationData.getIndex() + 1); - } else { - fCurLocation = new CtfLocation(timestampValue, 0L); - } - } else { - fCurLocation = new CtfLocation(CtfLocation.INVALID_LOCATION); - } - - return retVal; - } - - @Override - public void dispose() { - CtfIteratorManager.removeIterator(fTrace, this); - } - - /** - * Seeks to a given timestamp. Wrapper to help CtfTmfTrace - * - * @param timestamp - * desired timestamp - * @return success or not - */ - public synchronized boolean seek(final long timestamp) { - fCurLocation = new CtfLocation(timestamp, 0); - return getIterator().seek(timestamp); - } - - /** - * Seeks to a given location. Wrapper to help CtfTmfTrace - * @param location - * unique location to find the event. - * - * @return success or not - * @since 2.0 - */ - public synchronized boolean seek(final CtfLocationInfo location) { - fCurLocation = new CtfLocation(location); - return getIterator().seek(location); - } - - @Override - public CtfTmfContext clone() { - CtfTmfContext ret = null; - try { - ret = (CtfTmfContext) super.clone(); - /* Fields are immutable, no need to deep-copy them */ - } catch (CloneNotSupportedException e) { - /* Should not happen, we're calling Object.clone() */ - } - return ret; - } - - // ------------------------------------------- - // Private helpers - // ------------------------------------------- - - /** - * Get iterator, called every time to get an iterator, no local copy is - * stored so that there is no need to "update" - * - * @return an iterator - */ - private CtfIterator getIterator() { - return CtfIteratorManager.getIterator(fTrace, this); - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfEvent.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfEvent.java deleted file mode 100644 index 7ab14408b5..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfEvent.java +++ /dev/null @@ -1,262 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - * Bernd Hufmann - Updated for source and model lookup interfaces - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.ctf.core.event.CTFCallsite; -import org.eclipse.linuxtools.ctf.core.event.EventDefinition; -import org.eclipse.linuxtools.ctf.core.event.IEventDeclaration; -import org.eclipse.linuxtools.ctf.core.event.types.ICompositeDefinition; -import org.eclipse.linuxtools.ctf.core.event.types.IDefinition; -import org.eclipse.linuxtools.ctf.core.trace.CTFTrace; -import org.eclipse.linuxtools.tmf.core.event.ITmfCustomAttributes; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.lookup.ITmfModelLookup; -import org.eclipse.linuxtools.tmf.core.event.lookup.ITmfSourceLookup; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; - -/** - * A wrapper class around CTF's Event Definition/Declaration that maps all types - * of Declaration to native Java types. - * - * @version 1.0 - * @author Alexandre Montplaisir - * @since 2.0 - */ -public class CtfTmfEvent extends TmfEvent - implements ITmfSourceLookup, ITmfModelLookup, ITmfCustomAttributes { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - private static final String EMPTY_CTF_EVENT_NAME = "Empty CTF event"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final int fSourceCPU; - private final long fTypeId; - private final String fEventName; - private final IEventDeclaration fEventDeclaration; - @NonNull - private final EventDefinition fEvent; - private ITmfEventField fContent; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructor used by {@link CtfTmfEventFactory#createEvent} - */ - CtfTmfEvent(CtfTmfTrace trace, long rank, CtfTmfTimestamp timestamp, - String fileName, int cpu, IEventDeclaration declaration, @NonNull EventDefinition eventDefinition) { - super(trace, - rank, - timestamp, - String.valueOf(cpu), // Source - null, // Event type. We don't use TmfEvent's field here, we - // re-implement getType() - null, // Content handled with a lazy loaded re-implemented in - // getContent() - fileName // Reference - ); - - fEventDeclaration = declaration; - fSourceCPU = cpu; - fTypeId = declaration.getId().longValue(); - fEventName = declaration.getName(); - fEvent = eventDefinition; - - } - - /** - * Inner constructor to create "null" events. Don't use this directly in - * normal usage, use {@link CtfTmfEventFactory#getNullEvent()} to get an - * instance of an empty event. - * - * This needs to be public however because it's used in extension points, - * and the framework will use this constructor to get the class type. - */ - public CtfTmfEvent() { - super(null, - ITmfContext.UNKNOWN_RANK, - new CtfTmfTimestamp(-1), - null, - null, - new TmfEventField("", null, new CtfTmfEventField[0]), //$NON-NLS-1$ - null); - fSourceCPU = -1; - fTypeId = -1; - fEventName = EMPTY_CTF_EVENT_NAME; - fEventDeclaration = null; - fEvent = EventDefinition.NULL_EVENT; - } - - // ------------------------------------------------------------------------ - // Getters/Setters/Predicates - // ------------------------------------------------------------------------ - - /** - * Gets the cpu core the event was recorded on. - * - * @return The cpu id for a given source. In lttng it's from CPUINFO - */ - public int getCPU() { - return fSourceCPU; - } - - /** - * Return this event's ID, according to the trace's metadata. - * - * Watch out, this ID is not constant from one trace to another for the same - * event types! Use "getEventName()" for a constant reference. - * - * @return The event ID - */ - public long getID() { - return fTypeId; - } - - @Override - public CtfTmfTrace getTrace() { - /* - * Should be of the right type, since we take a CtfTmfTrace at the - * constructor - */ - return (CtfTmfTrace) super.getTrace(); - } - - @Override - public ITmfEventType getType() { - CtfTmfEventType ctfTmfEventType = CtfTmfEventType.get(getTrace(), fEventName); - if (ctfTmfEventType == null) { - /* Should only return null the first time */ - ctfTmfEventType = new CtfTmfEventType(fEventName, getTrace(), getContent()); - } - return ctfTmfEventType; - } - - /** - * @since 2.0 - */ - @Override - public Set listCustomAttributes() { - if (fEventDeclaration == null) { - return new HashSet<>(); - } - return fEventDeclaration.getCustomAttributes(); - } - - /** - * @since 2.0 - */ - @Override - public String getCustomAttribute(String name) { - if (fEventDeclaration == null) { - return null; - } - return fEventDeclaration.getCustomAttribute(name); - } - - /** - * Get the call site for this event. - * - * @return the call site information, or null if there is none - * @since 2.0 - */ - @Override - public CtfTmfCallsite getCallsite() { - CTFCallsite callsite = null; - CtfTmfTrace trace = getTrace(); - if (trace == null) { - return null; - } - CTFTrace ctfTrace = trace.getCTFTrace(); - /* Should not happen, but it is a good check */ - if (ctfTrace == null) { - return null; - } - if (getContent() != null) { - ITmfEventField ipField = getContent().getField(CtfConstants.CONTEXT_FIELD_PREFIX + CtfConstants.IP_KEY); - if (ipField != null && ipField.getValue() instanceof Long) { - long ip = (Long) ipField.getValue(); - callsite = ctfTrace.getCallsite(fEventName, ip); - } - } - if (callsite == null) { - callsite = ctfTrace.getCallsite(fEventName); - } - if (callsite != null) { - return new CtfTmfCallsite(callsite); - } - return null; - } - - /** - * @since 2.0 - */ - @Override - public String getModelUri() { - return getCustomAttribute(CtfConstants.MODEL_URI_KEY); - } - - @Override - public synchronized ITmfEventField getContent() { - if (fContent == null) { - fContent = new TmfEventField( - ITmfEventField.ROOT_FIELD_ID, null, parseFields(fEvent)); - } - return fContent; - } - - /** - * Extract the field information from the structDefinition haze-inducing - * mess, and put them into something ITmfEventField can cope with. - */ - private static CtfTmfEventField[] parseFields(@NonNull EventDefinition eventDef) { - List fields = new ArrayList<>(); - - ICompositeDefinition structFields = eventDef.getFields(); - if (structFields != null) { - if (structFields.getFieldNames() != null) { - for (String curFieldName : structFields.getFieldNames()) { - fields.add(CtfTmfEventField.parseField((IDefinition) structFields.getDefinition(curFieldName), curFieldName)); - } - } - } - /* Add context information as CtfTmfEventField */ - ICompositeDefinition structContext = eventDef.getContext(); - if (structContext != null) { - for (String contextName : structContext.getFieldNames()) { - /* Prefix field name */ - String curContextName = CtfConstants.CONTEXT_FIELD_PREFIX + contextName; - fields.add(CtfTmfEventField.parseField((IDefinition) structContext.getDefinition(contextName), curContextName)); - } - } - - return fields.toArray(new CtfTmfEventField[fields.size()]); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfEventFactory.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfEventFactory.java deleted file mode 100644 index 2de1d23061..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfEventFactory.java +++ /dev/null @@ -1,121 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core; - -import org.eclipse.linuxtools.ctf.core.CTFStrings; -import org.eclipse.linuxtools.ctf.core.event.EventDefinition; -import org.eclipse.linuxtools.ctf.core.event.IEventDeclaration; -import org.eclipse.linuxtools.ctf.core.event.types.IDefinition; -import org.eclipse.linuxtools.ctf.core.event.types.IntegerDefinition; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; - -/** - * Factory for CtfTmfEvent's. - * - * This code was moved out of CtfTmfEvent to provide better separation between - * the parsing/instantiation of events, and the usual TMF API implementations. - * - * @author Alexandre Montplaisir - * @since 2.0 - */ -public final class CtfTmfEventFactory { - - private static final String NO_STREAM = "No stream"; //$NON-NLS-1$ - - /** - * Don't let anyone instantiate this class. - */ - private CtfTmfEventFactory() {} - - /** - * Factory method to instantiate new {@link CtfTmfEvent}'s. - * - * @param eventDef - * CTF EventDefinition object corresponding to this trace event - * @param fileName - * The path to the trace file - * @param originTrace - * The trace from which this event originates - * @return The newly-built CtfTmfEvent - */ - public static CtfTmfEvent createEvent(EventDefinition eventDef, - String fileName, CtfTmfTrace originTrace) { - - /* Prepare what to pass to CtfTmfEvent's constructor */ - final IEventDeclaration eventDecl = eventDef.getDeclaration(); - final long ts = eventDef.getTimestamp(); - final CtfTmfTimestamp timestamp = originTrace.createTimestamp( - originTrace.getCTFTrace().timestampCyclesToNanos(ts)); - - int sourceCPU = eventDef.getCPU(); - - String reference = fileName == null ? NO_STREAM : fileName; - - /* Handle the special case of lost events */ - if (eventDecl.getName().equals(CTFStrings.LOST_EVENT_NAME)) { - IDefinition nbLostEventsDef = eventDef.getFields().getDefinition(CTFStrings.LOST_EVENTS_FIELD); - IDefinition durationDef = eventDef.getFields().getDefinition(CTFStrings.LOST_EVENTS_DURATION); - if (!(nbLostEventsDef instanceof IntegerDefinition) || !(durationDef instanceof IntegerDefinition)) { - /* - * One or both of these fields doesn't exist, or is not of the - * right type. The event claims to be a "lost event", but is - * malformed. Log it and return a null event instead. - */ - return getNullEvent(); - } - long nbLostEvents = ((IntegerDefinition) nbLostEventsDef).getValue(); - long duration = ((IntegerDefinition) durationDef).getValue(); - CtfTmfTimestamp timestampEnd = new CtfTmfTimestamp( - originTrace.getCTFTrace().timestampCyclesToNanos(ts) + duration); - - CtfTmfLostEvent lostEvent = new CtfTmfLostEvent(originTrace, - ITmfContext.UNKNOWN_RANK, - reference, // filename - sourceCPU, - eventDecl, - new TmfTimeRange(timestamp, timestampEnd), - nbLostEvents, - eventDef); - return lostEvent; - } - - /* Handle standard event types */ - CtfTmfEvent event = new CtfTmfEvent( - originTrace, - ITmfContext.UNKNOWN_RANK, - timestamp, - reference, // filename - sourceCPU, - eventDecl, - eventDef); - return event; - } - - /* Singleton instance of a null event */ - private static CtfTmfEvent nullEvent = null; - - /** - * Get an instance of a null event. - * - * @return An empty event - */ - public static CtfTmfEvent getNullEvent() { - if (nullEvent == null) { - nullEvent = new CtfTmfEvent(); - } - return nullEvent; - } - - -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfEventField.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfEventField.java deleted file mode 100644 index 0f2496f29f..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfEventField.java +++ /dev/null @@ -1,472 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Alexandre Montplaisir - Initial API and implementation, extend TmfEventField - * Bernd Hufmann - Add Enum field handling - * Geneviève Bastien - Add Struct and Variant field handling - * Jean-Christian Kouame - Correct handling of unsigned integer fields - * François Doray - Add generic array field type - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import org.eclipse.linuxtools.ctf.core.event.types.CompoundDeclaration; -import org.eclipse.linuxtools.ctf.core.event.types.Definition; -import org.eclipse.linuxtools.ctf.core.event.types.EnumDefinition; -import org.eclipse.linuxtools.ctf.core.event.types.FloatDefinition; -import org.eclipse.linuxtools.ctf.core.event.types.ICompositeDefinition; -import org.eclipse.linuxtools.ctf.core.event.types.IDeclaration; -import org.eclipse.linuxtools.ctf.core.event.types.IDefinition; -import org.eclipse.linuxtools.ctf.core.event.types.IntegerDeclaration; -import org.eclipse.linuxtools.ctf.core.event.types.IntegerDefinition; -import org.eclipse.linuxtools.ctf.core.event.types.StringDefinition; -import org.eclipse.linuxtools.ctf.core.event.types.VariantDefinition; -import org.eclipse.linuxtools.internal.ctf.core.event.types.ArrayDefinition; -import org.eclipse.linuxtools.internal.ctf.core.event.types.ByteArrayDefinition; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; - -/** - * The CTF implementation of the TMF event field model - * - * @version 2.0 - * @author Matthew Khouzam - * @author Alexandre Montplaisir - */ -public abstract class CtfTmfEventField extends TmfEventField { - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Standard constructor. Only to be used internally, call parseField() to - * generate a new field object. - * - * @param name - * The name of this field - * @param value - * The value of this field. Its type should match the field type. - * @param fields - * The children fields. Useful for composite fields - * @since 2.0 - */ - protected CtfTmfEventField(String name, Object value, ITmfEventField[] fields) { - super(/* Strip the underscore from the field name if there is one */ - name.startsWith("_") ? name.substring(1) : name, //$NON-NLS-1$ - value, - fields); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Factory method to instantiate CtfTmfEventField objects. - * - * @param fieldDef - * The CTF Definition of this event field - * @param fieldName - * String The name to assign to this field - * @return The resulting CtfTmfEventField object - * @deprecated use {@link CtfTmfEventField#parseField(IDefinition, String)} - */ - @Deprecated - public static CtfTmfEventField parseField(Definition fieldDef, - String fieldName) { - return parseField((IDefinition) fieldDef, fieldName); - } - - /** - * Factory method to instantiate CtfTmfEventField objects. - * - * @param fieldDef - * The CTF Definition of this event field - * @param fieldName - * String The name to assign to this field - * @return The resulting CtfTmfEventField object - * @since 3.1 - */ - public static CtfTmfEventField parseField(IDefinition fieldDef, - String fieldName) { - CtfTmfEventField field = null; - - /* Determine the Definition type */ - if (fieldDef instanceof IntegerDefinition) { - IntegerDefinition intDef = (IntegerDefinition) fieldDef; - int base = intDef.getDeclaration().getBase(); - field = new CTFIntegerField(fieldName, intDef.getValue(), base, intDef.getDeclaration().isSigned()); - - } else if (fieldDef instanceof EnumDefinition) { - EnumDefinition enumDef = (EnumDefinition) fieldDef; - field = new CTFEnumField(fieldName, new CtfEnumPair(enumDef.getValue(), enumDef.getIntegerValue())); - - } else if (fieldDef instanceof StringDefinition) { - field = new CTFStringField(fieldName, ((StringDefinition) fieldDef).getValue()); - - } else if (fieldDef instanceof FloatDefinition) { - FloatDefinition floatDef = (FloatDefinition) fieldDef; - field = new CTFFloatField(fieldName, floatDef.getValue()); - - } else if (fieldDef instanceof ArrayDefinition) { - ArrayDefinition arrayDef = (ArrayDefinition) fieldDef; - IDeclaration decl = arrayDef.getDeclaration(); - if (!(decl instanceof CompoundDeclaration)) { - throw new IllegalArgumentException("Array definitions should only come from sequence or array declarations"); //$NON-NLS-1$ - } - CompoundDeclaration arrDecl = (CompoundDeclaration) decl; - IDeclaration elemType = null; - Collection definitions = arrayDef.getDefinitions(); - elemType = arrDecl.getElementType(); - if (elemType instanceof IntegerDeclaration) { - /* Array of integers => CTFIntegerArrayField, unless it's a CTFStringField */ - IntegerDeclaration elemIntType = (IntegerDeclaration) elemType; - /* Are the integers characters and encoded? */ - if (elemIntType.isCharacter()) { - /* it's a CTFStringField */ - field = new CTFStringField(fieldName, arrayDef.toString()); - } else { - /* it's a CTFIntegerArrayField */ - long[] values = new long[arrayDef.getLength()]; - for (int i = 0; i < arrayDef.getLength(); i++) { - IDefinition elem = arrayDef.getDefinitions().get(i); - if (elem == null) { - break; - } - values[i] = ((IntegerDefinition) elem).getValue(); - } - field = new CTFIntegerArrayField(fieldName, values, - elemIntType.getBase(), - elemIntType.isSigned()); - } - } else { - /* Arrays of elements of any other type */ - CtfTmfEventField[] elements = new CtfTmfEventField[arrayDef.getLength()]; - /* Parse the elements of the array. */ - int i = 0; - for (IDefinition definition : definitions) { - CtfTmfEventField curField = CtfTmfEventField.parseField( - definition, fieldName + '[' + i + ']'); - elements[i] = curField; - i++; - } - - field = new CTFArrayField(fieldName, elements); - } - } else if (fieldDef instanceof ByteArrayDefinition) { - /* This is an array of ascii bytes, a.k.a. a String! */ - field = new CTFStringField(fieldName, fieldDef.toString()); - - } else if (fieldDef instanceof ICompositeDefinition) { - ICompositeDefinition strDef = (ICompositeDefinition) fieldDef; - - List list = new ArrayList<>(); - /* Recursively parse the fields */ - for (String curFieldName : strDef.getFieldNames()) { - list.add(CtfTmfEventField.parseField(strDef.getDefinition(curFieldName), curFieldName)); - } - field = new CTFStructField(fieldName, list.toArray(new CtfTmfEventField[list.size()])); - - } else if (fieldDef instanceof VariantDefinition) { - VariantDefinition varDef = (VariantDefinition) fieldDef; - - String curFieldName = varDef.getCurrentFieldName(); - IDefinition curFieldDef = varDef.getCurrentField(); - if (curFieldDef != null) { - CtfTmfEventField subField = CtfTmfEventField.parseField(curFieldDef, curFieldName); - field = new CTFVariantField(fieldName, subField); - } else { - /* A safe-guard, but curFieldDef should never be null */ - field = new CTFStringField(curFieldName, ""); //$NON-NLS-1$ - } - - } else { - /* - * Safe-guard, to avoid null exceptions later, field is expected not - * to be null - */ - field = new CTFStringField(fieldName, Messages.CtfTmfEventField_UnsupportedType + fieldDef.getClass().toString()); - } - return field; - } - - @Override - public String toString() { - return getName() + '=' + getFormattedValue(); - } - -} - -/** - * The CTF field implementation for integer fields. - * - * @author alexmont - */ -final class CTFIntegerField extends CtfTmfEventField { - - private final int fBase; - private final boolean fSigned; - - /** - * A CTF "IntegerDefinition" can be an integer of any byte size, so in the - * Java parser this is interpreted as a long. - * - * @param name - * The name of this field - * @param longValue - * The integer value of this field - * @param signed - * Is the value signed or not - */ - CTFIntegerField(String name, long longValue, int base, boolean signed) { - super(name, longValue, null); - fSigned = signed; - fBase = base; - } - - @Override - public Long getValue() { - return (Long) super.getValue(); - } - - @Override - public String getFormattedValue() { - return IntegerDefinition.formatNumber(getValue(), fBase, fSigned); - } - -} - -/** - * The CTF field implementation for string fields - * - * @author alexmont - */ -final class CTFStringField extends CtfTmfEventField { - - /** - * Constructor for CTFStringField. - * - * @param strValue - * The string value of this field - * @param name - * The name of this field - */ - CTFStringField(String name, String strValue) { - super(name, strValue, null); - } - - @Override - public String getValue() { - return (String) super.getValue(); - } -} - -/** - * CTF field implementation for arrays of integers. - * - * @author alexmont - */ -final class CTFIntegerArrayField extends CtfTmfEventField { - - private final int fBase; - private final boolean fSigned; - private String fFormattedValue = null; - - /** - * Constructor for CTFIntegerArrayField. - * - * @param name - * The name of this field - * @param longValues - * The array of integers (as longs) that compose this field's - * value - * @param signed - * Are the values in the array signed or not - */ - CTFIntegerArrayField(String name, long[] longValues, int base, boolean signed) { - super(name, longValues, null); - fBase = base; - fSigned = signed; - } - - @Override - public long[] getValue() { - return (long[]) super.getValue(); - } - - @Override - public synchronized String getFormattedValue() { - if (fFormattedValue == null) { - List strings = new ArrayList<>(); - for (long value : getValue()) { - strings.add(IntegerDefinition.formatNumber(value, fBase, fSigned)); - } - fFormattedValue = strings.toString(); - } - return fFormattedValue; - } - -} - -/** - * CTF field implementation for arrays of arbitrary types. - * - * @author fdoray - */ -final class CTFArrayField extends CtfTmfEventField { - - private String fFormattedValue = null; - - /** - * Constructor for CTFArrayField. - * - * @param name - * The name of this field - * @param elements - * The array elements of this field - */ - CTFArrayField(String name, CtfTmfEventField[] elements) { - super(name, elements, elements); - } - - @Override - public CtfTmfEventField[] getValue() { - return (CtfTmfEventField[]) super.getValue(); - } - - @Override - public synchronized String getFormattedValue() { - if (fFormattedValue == null) { - List strings = new ArrayList<>(); - for (CtfTmfEventField element : getValue()) { - strings.add(element.getFormattedValue()); - } - fFormattedValue = strings.toString(); - } - return fFormattedValue; - } -} - -/** - * CTF field implementation for floats. - * - * @author emathko - */ -final class CTFFloatField extends CtfTmfEventField { - - /** - * Constructor for CTFFloatField. - * - * @param value - * The float value (actually a double) of this field - * @param name - * The name of this field - */ - protected CTFFloatField(String name, double value) { - super(name, value, null); - } - - @Override - public Double getValue() { - return (Double) super.getValue(); - } -} - -/** - * The CTF field implementation for Enum fields - * - * @author Bernd Hufmann - */ -final class CTFEnumField extends CtfTmfEventField { - - /** - * Constructor for CTFEnumField. - * - * @param enumValue - * The Enum value consisting of a pair of Enum value name and its - * long value - * @param name - * The name of this field - */ - CTFEnumField(String name, CtfEnumPair enumValue) { - super(name, new CtfEnumPair(enumValue.getFirst(), - enumValue.getSecond()), null); - } - - @Override - public CtfEnumPair getValue() { - return (CtfEnumPair) super.getValue(); - } -} - -/** - * The CTF field implementation for struct fields with sub-fields - * - * @author gbastien - */ -final class CTFStructField extends CtfTmfEventField { - - /** - * Constructor for CTFStructField. - * - * @param fields - * The children of this field - * @param name - * The name of this field - */ - CTFStructField(String name, CtfTmfEventField[] fields) { - super(name, fields, fields); - } - - @Override - public CtfTmfEventField[] getValue() { - return (CtfTmfEventField[]) super.getValue(); - } - - @Override - public String getFormattedValue() { - return Arrays.toString(getValue()); - } - -} - -/** - * The CTF field implementation for variant fields its child - * - * @author gbastien - */ -final class CTFVariantField extends CtfTmfEventField { - - /** - * Constructor for CTFVariantField. - * - * @param field - * The field selected for this variant - * @param name - * The name of this field - */ - CTFVariantField(String name, CtfTmfEventField field) { - super(name, field, new CtfTmfEventField[] { field }); - } - - @Override - public CtfTmfEventField getValue() { - return (CtfTmfEventField) super.getValue(); - } - -} - -/* Implement other possible fields types here... */ diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfEventType.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfEventType.java deleted file mode 100644 index 85bb249141..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfEventType.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.eclipse.linuxtools.tmf.core.event.TmfEventTypeManager; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * The CTF extension of the TMF event type - * - * @version 1.0 - * @author Matthew khouzam - */ -public class CtfTmfEventType extends TmfEventType { - - /** - * CTFTmfEventType context for the event type manager - */ - private static final String CONTEXT_ID = "Ctf Event"; //$NON-NLS-1$ - - private static final String UNKNOWN_TRACE = "unknown"; //$NON-NLS-1$ - - /** - * Constructor for CtfTmfEventType. - * - * @param eventName - * The event name - * @param trace - * the parent trace - * @param content - * The event field - * @since 3.0 - */ - public CtfTmfEventType(String eventName, ITmfTrace trace, ITmfEventField content) { - super(computeContextName(trace), eventName, content); - } - - /** - * Method toString. - * - * @return String - */ - @Override - public String toString() { - return getName(); - } - - /** - * gets the event type for an event name - * - * @param trace - * the parent trace - * @param eventName - * the event name - * @return the event type - * @since 3.0 - */ - public static CtfTmfEventType get(CtfTmfTrace trace, String eventName) { - return (CtfTmfEventType) TmfEventTypeManager.getInstance().getType(computeContextName(trace), eventName); - } - - /** - * Get the context name of a ctf trace - * - * @param trace - * the trace - * @return the context name - * @since 3.0 - */ - public static String computeContextName(ITmfTrace trace) { - return CONTEXT_ID + "/" + (trace == null ? UNKNOWN_TRACE : trace.getPath()); //$NON-NLS-1$ - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfLostEvent.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfLostEvent.java deleted file mode 100644 index c699de0aeb..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfLostEvent.java +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.ctf.core.event.EventDefinition; -import org.eclipse.linuxtools.ctf.core.event.IEventDeclaration; -import org.eclipse.linuxtools.tmf.core.event.ITmfLostEvent; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; - -/** - * An implementation of {@link ITmfLostEvent} for use in the CTF adaptor. - * - * @author Alexandre Montplaisir - * @since 2.2 - */ -public class CtfTmfLostEvent extends CtfTmfEvent implements ITmfLostEvent { - - private final TmfTimeRange fTimeRange; - private final long fNbLost; - - /** - * Constructor. Only {@link CtfTmfEventFactory} should call this. - * - * @param trace - * The origin trace - * @param rank - * The rank of the event in the trace - * @param content - * The event's payload (fields). In case this event has some. - * @param fileName - * The name of the trace file from which this event comes - * @param cpu - * The CPU on which this event happened - * @param declaration - * The CTF Event Declaration object that created this event - * @param timeRange - * The time range of lost events indicated by this one - * @param nbLost - * The number of lost events in the range - */ - CtfTmfLostEvent(CtfTmfTrace trace, - long rank, - String fileName, - int cpu, - IEventDeclaration declaration, - TmfTimeRange timeRange, - long nbLost, - @NonNull EventDefinition def) { - /* - * Only the factory should call this method, the case to - * (CtfTmfTimestamp) should be safe. - */ - super(trace, rank, (CtfTmfTimestamp) timeRange.getStartTime(), fileName, cpu, declaration, def); - fTimeRange = timeRange; - fNbLost = nbLost; - } - - @Override - public TmfTimeRange getTimeRange() { - return fTimeRange; - } - - @Override - public long getNbLostEvents() { - return fNbLost; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfTimestamp.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfTimestamp.java deleted file mode 100644 index 1d6873c74e..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfTimestamp.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; - -/** - * The CTF adapter for the TMF timestamp. It's basically the same as a - * TmfTimestamp, but the scale is always nanoseconds, and the precision is 0. - * - * @version 1.2 - * @author Matthew khouzam - */ -public final class CtfTmfTimestamp extends TmfTimestamp { - - /** - * Constructor for CtfTmfTimestamp. - * - * @param timestamp - * The timestamp value (in nanoseconds) - */ - public CtfTmfTimestamp(long timestamp) { - super(timestamp, ITmfTimestamp.NANOSECOND_SCALE, 0); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfTrace.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfTrace.java deleted file mode 100644 index a2831cf6bd..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/CtfTmfTrace.java +++ /dev/null @@ -1,518 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Patrick Tasse - Updated for removal of context clone - * Geneviève Bastien - Added the createTimestamp function - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core; - -import java.nio.BufferOverflowException; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.linuxtools.ctf.core.event.CTFClock; -import org.eclipse.linuxtools.ctf.core.event.IEventDeclaration; -import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException; -import org.eclipse.linuxtools.ctf.core.trace.CTFTrace; -import org.eclipse.linuxtools.ctf.core.trace.CTFTraceReader; -import org.eclipse.linuxtools.internal.tmf.ctf.core.Activator; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventTypeManager; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTraceProperties; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTraceWithPreDefinedEvents; -import org.eclipse.linuxtools.tmf.core.trace.TmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TraceValidationStatus; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfPersistentlyIndexable; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.indexer.TmfBTreeTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; - -import com.google.common.collect.ImmutableSet; - -/** - * The CTf trace handler - * - * @version 1.0 - * @author Matthew khouzam - */ -public class CtfTmfTrace extends TmfTrace - implements ITmfEventParser, ITmfTraceProperties, ITmfPersistentlyIndexable, - ITmfTraceWithPreDefinedEvents, AutoCloseable { - - // ------------------------------------------- - // Constants - // ------------------------------------------- - /** - * Default cache size for CTF traces - */ - protected static final int DEFAULT_CACHE_SIZE = 50000; - - /* - * The Ctf clock unique identifier field - */ - private static final String CLOCK_HOST_PROPERTY = "uuid"; //$NON-NLS-1$ - private static final int CONFIDENCE = 10; - - // ------------------------------------------- - // Fields - // ------------------------------------------- - - /* Reference to the CTF Trace */ - private CTFTrace fTrace; - - // ------------------------------------------- - // TmfTrace Overrides - // ------------------------------------------- - /** - * Method initTrace. - * - * @param resource - * The resource associated with this trace - * @param path - * The path to the trace file - * @param eventType - * The type of events that will be read from this trace - * @throws TmfTraceException - * If something went wrong while reading the trace - */ - @Override - public void initTrace(final IResource resource, final String path, final Class eventType) - throws TmfTraceException { - /* - * Set the cache size. This has to be done before the call to super() - * because the super needs to know the cache size. - */ - setCacheSize(); - - super.initTrace(resource, path, eventType); - - try { - this.fTrace = new CTFTrace(path); - CtfIteratorManager.addTrace(this); - CtfTmfContext ctx; - /* Set the start and (current) end times for this trace */ - ctx = (CtfTmfContext) seekEvent(0L); - CtfTmfEvent event = getNext(ctx); - if ((ctx.getLocation().equals(CtfIterator.NULL_LOCATION)) || (ctx.getCurrentEvent() == null)) { - /* Handle the case where the trace is empty */ - this.setStartTime(TmfTimestamp.BIG_BANG); - } else { - final ITmfTimestamp curTime = event.getTimestamp(); - this.setStartTime(curTime); - this.setEndTime(curTime); - } - /* - * Register every event type. When you call getType, it will - * register a trace to that type in the TmfEventTypeManager - */ - try (CtfIterator iter = CtfIteratorManager.getIterator(this, ctx)) { - for (IEventDeclaration ied : iter.getEventDeclarations()) { - CtfTmfEventType ctfTmfEventType = CtfTmfEventType.get(this, ied.getName()); - if (ctfTmfEventType == null) { - List content = new ArrayList<>(); - /* Should only return null the first time */ - for (String fieldName : ied.getFields().getFieldsList()) { - content.add(new TmfEventField(fieldName, null, null)); - } - ITmfEventField contentTree = new TmfEventField( - ITmfEventField.ROOT_FIELD_ID, - null, - content.toArray(new ITmfEventField[content.size()]) - ); - - ctfTmfEventType = new CtfTmfEventType(ied.getName(), this, contentTree); - } - } - } - } catch (final CTFReaderException e) { - /* - * If it failed at the init(), we can assume it's because the file - * was not found or was not recognized as a CTF trace. Throw into - * the new type of exception expected by the rest of TMF. - */ - throw new TmfTraceException(e.getMessage(), e); - } - } - - @Override - public void close() { - dispose(); - } - - @Override - public synchronized void dispose() { - CtfIteratorManager.removeTrace(this); - if (fTrace != null) { - fTrace.close(); - fTrace = null; - } - super.dispose(); - } - - /** - * {@inheritDoc} - *

- * The default implementation sets the confidence to 10 if the trace is a - * valid CTF trace. - */ - @Override - public IStatus validate(final IProject project, final String path) { - IStatus status = new TraceValidationStatus(CONFIDENCE, Activator.PLUGIN_ID); - try (final CTFTrace temp = new CTFTrace(path);) { - if (!temp.majorIsSet()) { - status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_MajorNotSet); - } else { - try (CTFTraceReader ctfTraceReader = new CTFTraceReader(temp);) { - if (!ctfTraceReader.hasMoreEvents()) { - // TODO: This will need an additional check when we - // support live traces - // because having no event is valid for a live trace - status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_NoEvent); - } - } - } - } catch (final CTFReaderException e) { - status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_ReadingError + ": " + e.toString()); //$NON-NLS-1$ - } catch (final BufferOverflowException e) { - status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_ReadingError + ": " + Messages.CtfTmfTrace_BufferOverflowErrorMessage); //$NON-NLS-1$ - } - - return status; - } - - /** - * Method getCurrentLocation. This is not applicable in CTF - * - * @return null, since the trace has no knowledge of the current location - * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCurrentLocation() - * @since 3.0 - */ - @Override - public ITmfLocation getCurrentLocation() { - return null; - } - - /** - * @since 3.0 - */ - @Override - public double getLocationRatio(ITmfLocation location) { - final CtfLocation curLocation = (CtfLocation) location; - final CtfTmfContext context = new CtfTmfContext(this); - context.setLocation(curLocation); - context.seek(curLocation.getLocationInfo()); - final CtfLocationInfo currentTime = ((CtfLocationInfo) context.getLocation().getLocationInfo()); - final long startTime = getIterator(this, context).getStartTime(); - final long endTime = getIterator(this, context).getEndTime(); - return ((double) currentTime.getTimestamp() - startTime) - / (endTime - startTime); - } - - /** - * Method seekEvent. - * - * @param location - * ITmfLocation - * @return ITmfContext - * @since 3.0 - */ - @Override - public synchronized ITmfContext seekEvent(final ITmfLocation location) { - CtfLocation currentLocation = (CtfLocation) location; - CtfTmfContext context = new CtfTmfContext(this); - if (fTrace == null) { - context.setLocation(null); - context.setRank(ITmfContext.UNKNOWN_RANK); - return context; - } - /* - * The rank is set to 0 if the iterator seeks the beginning. If not, it - * will be set to UNKNOWN_RANK, since CTF traces don't support seeking - * by rank for now. - */ - if (currentLocation == null) { - currentLocation = new CtfLocation(new CtfLocationInfo(0L, 0L)); - context.setRank(0); - } - if (currentLocation.getLocationInfo() == CtfLocation.INVALID_LOCATION) { - currentLocation = new CtfLocation(getCTFTrace().getCurrentEndTime() + 1, 0L); - } - context.setLocation(currentLocation); - if (location == null) { - long timestamp = getIterator(this, context).getCurrentTimestamp(); - currentLocation = new CtfLocation(timestamp, 0); - } - if (context.getRank() != 0) { - context.setRank(ITmfContext.UNKNOWN_RANK); - } - return context; - } - - @Override - public synchronized ITmfContext seekEvent(double ratio) { - CtfTmfContext context = new CtfTmfContext(this); - if (fTrace == null) { - context.setLocation(null); - context.setRank(ITmfContext.UNKNOWN_RANK); - return context; - } - final long end = getCTFTrace().getCurrentEndTime(); - final long start = getCTFTrace().getCurrentStartTime(); - final long diff = end - start; - final long ratioTs = Math.round(diff * ratio) + start; - context.seek(ratioTs); - context.setRank(ITmfContext.UNKNOWN_RANK); - return context; - } - - /** - * Method readNextEvent. - * - * @param context - * ITmfContext - * @return CtfTmfEvent - * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getNext(ITmfContext) - */ - @Override - public synchronized CtfTmfEvent getNext(final ITmfContext context) { - if (fTrace == null) { - return null; - } - CtfTmfEvent event = null; - if (context instanceof CtfTmfContext) { - if (context.getLocation() == null || CtfLocation.INVALID_LOCATION.equals(context.getLocation().getLocationInfo())) { - return null; - } - CtfTmfContext ctfContext = (CtfTmfContext) context; - event = ctfContext.getCurrentEvent(); - - if (event != null) { - updateAttributes(context, event.getTimestamp()); - ctfContext.advance(); - ctfContext.increaseRank(); - } - } - - return event; - } - - /** - * gets the CTFtrace that this is wrapping - * - * @return the CTF trace - */ - public CTFTrace getCTFTrace() { - return fTrace; - } - - /** - * Ctf traces have a clock with a unique uuid that will be used to identify - * the host. Traces with the same clock uuid will be known to have been made - * on the same machine. - * - * Note: uuid is an optional field, it may not be there for a clock. - */ - @Override - public String getHostId() { - CTFClock clock = getCTFTrace().getClock(); - if (clock != null) { - String clockHost = (String) clock.getProperty(CLOCK_HOST_PROPERTY); - if (clockHost != null) { - return clockHost; - } - } - return super.getHostId(); - } - - // ------------------------------------------- - // ITmfTraceProperties - // ------------------------------------------- - - /** - * @since 2.0 - */ - @Override - public Map getTraceProperties() { - Map properties = new HashMap<>(); - properties.putAll(fTrace.getEnvironment()); - properties.put(Messages.CtfTmfTrace_HostID, getHostId()); - return properties; - } - - // ------------------------------------------- - // Clocks - // ------------------------------------------- - - /** - * gets the clock offset - * - * @return the clock offset in ns - */ - public long getOffset() { - if (fTrace != null) { - return fTrace.getOffset(); - } - return 0; - } - - /** - * Gets the list of declared events - * - * @since 3.0 - */ - @Override - public Set getContainedEventTypes() { - TmfEventTypeManager instance = TmfEventTypeManager.getInstance(); - Set eventTypes = instance.getTypes(CtfTmfEventType.computeContextName(this)); - return ImmutableSet.copyOf(eventTypes); - } - - // ------------------------------------------- - // Parser - // ------------------------------------------- - - @Override - public CtfTmfEvent parseEvent(ITmfContext context) { - CtfTmfEvent event = null; - if (context instanceof CtfTmfContext) { - final ITmfContext tmpContext = seekEvent(context.getLocation()); - event = getNext(tmpContext); - } - return event; - } - - /** - * Sets the cache size for a CtfTmfTrace. - */ - protected void setCacheSize() { - setCacheSize(DEFAULT_CACHE_SIZE); - } - - // ------------------------------------------- - // Helpers - // ------------------------------------------- - - private static CtfIterator getIterator(CtfTmfTrace trace, CtfTmfContext context) { - return CtfIteratorManager.getIterator(trace, context); - } - - /** - * Get an iterator to the trace - * - * @return an iterator to the trace - * @since 2.0 - */ - public CtfIterator createIterator() { - try { - return new CtfIterator(this); - } catch (CTFReaderException e) { - Activator.getDefault().logError(e.getMessage(), e); - } - return null; - } - - // ------------------------------------------------------------------------ - // Timestamp transformation functions - // ------------------------------------------------------------------------ - - /** - * @since 3.0 - */ - @Override - public CtfTmfTimestamp createTimestamp(long ts) { - return new CtfTmfTimestamp(getTimestampTransform().transform(ts)); - } - - private static int fCheckpointSize = -1; - - /** - * @since 3.0 - */ - @Override - public synchronized int getCheckpointSize() { - if (fCheckpointSize == -1) { - TmfCheckpoint c = new TmfCheckpoint(new CtfTmfTimestamp(0), new CtfLocation(0, 0), 0); - ByteBuffer b = ByteBuffer.allocate(ITmfCheckpoint.MAX_SERIALIZE_SIZE); - b.clear(); - c.serialize(b); - fCheckpointSize = b.position(); - } - - return fCheckpointSize; - } - - @Override - protected ITmfTraceIndexer createIndexer(int interval) { - return new TmfBTreeTraceIndexer(this, interval); - } - - /** - * @since 3.0 - */ - @Override - public ITmfLocation restoreLocation(ByteBuffer bufferIn) { - return new CtfLocation(bufferIn); - } - - @Override - public boolean isComplete() { - if (getResource() == null) { - return true; - } - - String host = null; - String port = null; - String sessionName = null; - try { - host = getResource().getPersistentProperty(CtfConstants.LIVE_HOST); - port = getResource().getPersistentProperty(CtfConstants.LIVE_PORT); - sessionName = getResource().getPersistentProperty(CtfConstants.LIVE_SESSION_NAME); - } catch (CoreException e) { - Activator.getDefault().logError(e.getMessage(), e); - // Something happened to the resource, assume we won't get any more data from it - return true; - } - return host == null || port == null || sessionName == null; - } - - @Override - public void setComplete(final boolean isComplete) { - super.setComplete(isComplete); - try { - if (isComplete) { - getResource().setPersistentProperty(CtfConstants.LIVE_HOST, null); - getResource().setPersistentProperty(CtfConstants.LIVE_PORT, null); - getResource().setPersistentProperty(CtfConstants.LIVE_SESSION_NAME, null); - } - } catch (CoreException e) { - Activator.getDefault().logError(e.getMessage(), e); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/Messages.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/Messages.java deleted file mode 100644 index 0401ace838..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/Messages.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.core; - -import org.eclipse.osgi.util.NLS; - -/** - * Message bundle for tmf.core.ctfadaptor - * - * @author Matthew Khouzam - * @since 2.0 - */ -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.ctf.core.messages"; //$NON-NLS-1$ - - /** Buffer overflow detected - * @since 2.1*/ - public static String CtfTmfTrace_BufferOverflowErrorMessage; - - /** - * Text for host ID - * - * @since 3.1 - */ - public static String CtfTmfTrace_HostID; - - /** Major version number not set */ - public static String CtfTmfTrace_MajorNotSet; - - /** Reading error */ - public static String CtfTmfTrace_ReadingError; - - /** No event */ - public static String CtfTmfTrace_NoEvent; - - /** Unsupported field type */ - public static String CtfTmfEventField_UnsupportedType; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/messages.properties b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/messages.properties deleted file mode 100644 index 14d393b2db..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/linuxtools/tmf/ctf/core/messages.properties +++ /dev/null @@ -1,18 +0,0 @@ -############################################################################### -# Copyright (c) 2013 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### - -CtfTmfTrace_BufferOverflowErrorMessage=Buffer overflow exception, trace is malformed -CtfTmfTrace_HostID=host ID -CtfTmfTrace_MajorNotSet=Major version number not set -CtfTmfTrace_ReadingError=Reading error -CtfTmfTrace_NoEvent=Trace has no events -CtfTmfEventField_UnsupportedType=Unsupported field type: \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/internal/tmf/ctf/core/Activator.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/internal/tmf/ctf/core/Activator.java new file mode 100644 index 0000000000..cd8f029036 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/internal/tmf/ctf/core/Activator.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ctf.core; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; +import org.osgi.framework.BundleContext; + +/** + * Activator + *

+ * The activator class controls the plug-in life cycle + */ +public class Activator extends Plugin { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The plug-in ID + */ + public static final String PLUGIN_ID = "org.eclipse.linuxtools.tmf.ctf.core"; //$NON-NLS-1$ + + /** + * The shared instance + */ + private static Activator plugin; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * The constructor + */ + public Activator() { + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + + // ------------------------------------------------------------------------ + // Operators + // ------------------------------------------------------------------------ + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Logs a message with severity INFO in the runtime log of the plug-in. + * + * @param message A message to log + */ + public void logInfo(String message) { + getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity INFO in the runtime log of the plug-in. + * + * @param message A message to log + * @param exception A exception to log + */ + public void logInfo(String message, Throwable exception) { + getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message, exception)); + } + + /** + * Logs a message and exception with severity WARNING in the runtime log of the plug-in. + * + * @param message A message to log + */ + public void logWarning(String message) { + getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity WARNING in the runtime log of the plug-in. + * + * @param message A message to log + * @param exception A exception to log + */ + public void logWarning(String message, Throwable exception) { + getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message, exception)); + } + + /** + * Logs a message and exception with severity ERROR in the runtime log of the plug-in. + * + * @param message A message to log + */ + public void logError(String message) { + getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity ERROR in the runtime log of the plug-in. + * + * @param message A message to log + * @param exception A exception to log + */ + public void logError(String message, Throwable exception) { + getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, exception)); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfConstants.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfConstants.java new file mode 100644 index 0000000000..ca7e4a4d17 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfConstants.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson, Ecole Polytechnique de Montreal and others + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ansgar Radermacher - support for model URI + * Patrick Tasse - context strings + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core; + +import org.eclipse.core.runtime.QualifiedName; + +/** + * Set of constants used by the CTF adaptor classes + * + * @since 2.0 + * @noimplement This interface is not intended to be implemented by clients. + */ +@SuppressWarnings("nls") +public interface CtfConstants { + + /* + * Context strings + */ + + /** Prefix for context information stored as CtfTmfEventfield */ + public static final String CONTEXT_FIELD_PREFIX = "context."; + + /** Key for ip field */ + public static final String IP_KEY = "_ip"; + + /* + * Custom attributes names (key within hash table) + */ + + /** Model URI for traces related to EMF models */ + public final String MODEL_URI_KEY = "model.emf.uri"; + + /** + * The host persistent property for the live session. + * + * @since 3.1 + */ + QualifiedName LIVE_HOST = new QualifiedName("org.eclipse.linuxtools.tmf.ctf.core", "live.host"); //$NON-NLS-1$//$NON-NLS-2$ + + /** + * The port persistent property for the live session. + * + * @since 3.1 + */ + QualifiedName LIVE_PORT = new QualifiedName("org.eclipse.linuxtools.tmf.ctf.core", "live.port"); //$NON-NLS-1$//$NON-NLS-2$ + + /** + * The live session name persistent property. + * + * @since 3.1 + */ + QualifiedName LIVE_SESSION_NAME = new QualifiedName("org.eclipse.linuxtools.tmf.ctf.core", "live.session.name"); //$NON-NLS-1$//$NON-NLS-2$; +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfEnumPair.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfEnumPair.java new file mode 100644 index 0000000000..70c659282b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfEnumPair.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core; + +import org.eclipse.tracecompass.tmf.core.util.Pair; + +/** + * Pair of Enum value name and its long value. + * + * @author Bernd Hufmann + * @since 2.0 + */ +public class CtfEnumPair extends Pair { + + /** + * Constructs a CtfEnumPair + * + * @param strValue + * The first parameter of the pair (String) + * @param longValue + * The second parameter of the pair (Long) + */ + public CtfEnumPair(String strValue, Long longValue) { + super(strValue, longValue); + } + + /** + * Returns the String value of the Enum. + * + * @return the string value + */ + public String getStringValue() { + return getFirst(); + } + + /** + * Returns the long value of the Enum. + * + * @return the Long value + */ + public Long getLongValue() { + return getSecond(); + } + + @Override + public String toString() { + return getFirst(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfIterator.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfIterator.java new file mode 100644 index 0000000000..f6fecdd1aa --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfIterator.java @@ -0,0 +1,353 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Florian Wininger - Performance improvements + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core; + +import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException; +import org.eclipse.linuxtools.ctf.core.trace.CTFStreamInputReader; +import org.eclipse.linuxtools.ctf.core.trace.CTFTraceReader; +import org.eclipse.tracecompass.internal.tmf.ctf.core.Activator; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +/** + * The CTF trace reader iterator. + * + * It doesn't reserve a file handle, so many iterators can be used without + * worries of I/O errors or resource exhaustion. + * + * @author Matthew Khouzam + */ +public class CtfIterator extends CTFTraceReader + implements ITmfContext, Comparable { + + /** An invalid location */ + public static final CtfLocation NULL_LOCATION = new CtfLocation(CtfLocation.INVALID_LOCATION); + + private final CtfTmfTrace fTrace; + + private CtfLocation fCurLocation; + private long fCurRank; + + private CtfLocation fPreviousLocation; + private CtfTmfEvent fPreviousEvent; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Create a new CTF trace iterator, which initially points at the first + * event in the trace. + * + * @param trace + * The trace to iterate over + * @throws CTFReaderException + * If the iterator couldn't not be instantiated, probably due to + * a read error. + */ + public CtfIterator(CtfTmfTrace trace) throws CTFReaderException { + super(trace.getCTFTrace()); + fTrace = trace; + if (hasMoreEvents()) { + fCurLocation = new CtfLocation(trace.getStartTime()); + fCurRank = 0; + } else { + setUnknownLocation(); + } + } + + /** + * Create a new CTF trace iterator, which will initially point to the given + * location/rank. + * + * @param trace + * The trace to iterate over + * @param ctfLocationData + * The initial timestamp the iterator will be pointing to + * @param rank + * The initial rank + * @throws CTFReaderException + * If the iterator couldn't not be instantiated, probably due to + * a read error. + * @since 2.0 + */ + public CtfIterator(CtfTmfTrace trace, CtfLocationInfo ctfLocationData, long rank) + throws CTFReaderException { + super(trace.getCTFTrace()); + + this.fTrace = trace; + if (this.hasMoreEvents()) { + this.fCurLocation = new CtfLocation(ctfLocationData); + if (this.getCurrentEvent().getTimestamp().getValue() != ctfLocationData.getTimestamp()) { + this.seek(ctfLocationData); + this.fCurRank = rank; + } + } else { + setUnknownLocation(); + } + } + + @Override + public void dispose() { + close(); + } + + private void setUnknownLocation() { + fCurLocation = NULL_LOCATION; + fCurRank = UNKNOWN_RANK; + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * Return this iterator's trace. + * + * @return CtfTmfTrace The iterator's trace + */ + public CtfTmfTrace getCtfTmfTrace() { + return fTrace; + } + + /** + * Return the current event pointed to by the iterator. + * + * @return CtfTmfEvent The current event + */ + public synchronized CtfTmfEvent getCurrentEvent() { + final CTFStreamInputReader top = super.getPrio().peek(); + if (top != null) { + if (!fCurLocation.equals(fPreviousLocation)) { + fPreviousLocation = fCurLocation; + fPreviousEvent = CtfTmfEventFactory.createEvent(top.getCurrentEvent(), + top.getFilename(), fTrace); + } + return fPreviousEvent; + } + return null; + } + + /** + * Return the current timestamp location pointed to by the iterator. + * This is the timestamp for use in CtfLocation, not the event timestamp. + * + * @return long The current timestamp location + */ + public synchronized long getCurrentTimestamp() { + final CTFStreamInputReader top = super.getPrio().peek(); + if (top != null) { + long ts = top.getCurrentEvent().getTimestamp(); + return fTrace.getCTFTrace().timestampCyclesToNanos(ts); + } + return 0; + } + + /** + * Seek this iterator to a given location. + * + * @param ctfLocationData + * The LocationData representing the position to seek to + * @return boolean True if the seek was successful, false if there was an + * error seeking. + * @since 2.0 + */ + public synchronized boolean seek(CtfLocationInfo ctfLocationData) { + boolean ret = false; + + /* Avoid the cost of seeking at the current location. */ + if (fCurLocation.getLocationInfo().equals(ctfLocationData)) { + return super.hasMoreEvents(); + } + + /* Adjust the timestamp depending on the trace's offset */ + long currTimestamp = ctfLocationData.getTimestamp(); + final long offsetTimestamp = this.getCtfTmfTrace().getCTFTrace().timestampNanoToCycles(currTimestamp); + try { + if (offsetTimestamp < 0) { + ret = super.seek(0L); + } else { + ret = super.seek(offsetTimestamp); + } + } catch (CTFReaderException e) { + Activator.getDefault().logError(e.getMessage(), e); + return false; + } + /* + * Check if there is already one or more events for that timestamp, and + * assign the location index correctly + */ + long index = 0; + final CtfTmfEvent currentEvent = this.getCurrentEvent(); + if (currentEvent != null) { + currTimestamp = currentEvent.getTimestamp().getValue(); + + for (long i = 0; i < ctfLocationData.getIndex(); i++) { + if (currTimestamp == currentEvent.getTimestamp().getValue()) { + index++; + } else { + index = 0; + } + this.advance(); + } + } else { + ret = false; + } + /* Seek the current location accordingly */ + if (ret) { + fCurLocation = new CtfLocation(new CtfLocationInfo(getCurrentEvent().getTimestamp().getValue(), index)); + } else { + fCurLocation = NULL_LOCATION; + } + + return ret; + } + + // ------------------------------------------------------------------------ + // CTFTraceReader + // ------------------------------------------------------------------------ + + @Override + public boolean seek(long timestamp) { + return seek(new CtfLocationInfo(timestamp, 0)); + } + + @Override + public synchronized boolean advance() { + boolean ret = false; + try { + ret = super.advance(); + } catch (CTFReaderException e) { + Activator.getDefault().logError(e.getMessage(), e); + } + + if (ret) { + long timestamp = fCurLocation.getLocationInfo().getTimestamp(); + final long timestampValue = getCurrentTimestamp(); + if (timestamp == timestampValue) { + long index = fCurLocation.getLocationInfo().getIndex(); + fCurLocation = new CtfLocation(timestampValue, index + 1); + } else { + fCurLocation = new CtfLocation(timestampValue, 0L); + } + } else { + fCurLocation = NULL_LOCATION; + } + return ret; + } + + // ------------------------------------------------------------------------ + // ITmfContext + // ------------------------------------------------------------------------ + + @Override + public long getRank() { + return fCurRank; + } + + @Override + public void setRank(long rank) { + fCurRank = rank; + } + + @Override + public void increaseRank() { + /* Only increase the rank if it's valid */ + if (hasValidRank()) { + fCurRank++; + } + } + + @Override + public boolean hasValidRank() { + return (getRank() >= 0); + } + + /** + * @since 3.0 + */ + @Override + public void setLocation(ITmfLocation location) { + // FIXME alex: isn't there a cleaner way than a cast here? + fCurLocation = (CtfLocation) location; + seek(((CtfLocation) location).getLocationInfo()); + } + + @Override + public CtfLocation getLocation() { + return fCurLocation; + } + + // ------------------------------------------------------------------------ + // Comparable + // ------------------------------------------------------------------------ + + @Override + public int compareTo(final CtfIterator o) { + if (getRank() < o.getRank()) { + return -1; + } else if (getRank() > o.getRank()) { + return 1; + } + return 0; + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = (prime * result) + + ((fTrace == null) ? 0 : fTrace.hashCode()); + result = (prime * result) + + ((fCurLocation == null) ? 0 : fCurLocation.hashCode()); + result = (prime * result) + (int) (fCurRank ^ (fCurRank >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof CtfIterator)) { + return false; + } + CtfIterator other = (CtfIterator) obj; + if (fTrace == null) { + if (other.fTrace != null) { + return false; + } + } else if (!fTrace.equals(other.fTrace)) { + return false; + } + if (fCurLocation == null) { + if (other.fCurLocation != null) { + return false; + } + } else if (!fCurLocation.equals(other.fCurLocation)) { + return false; + } + if (fCurRank != other.fCurRank) { + return false; + } + return true; + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfIteratorManager.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfIteratorManager.java new file mode 100644 index 0000000000..09ee972e59 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfIteratorManager.java @@ -0,0 +1,229 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Simon Delisle - Added a method to remove the iterator + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ctf.core; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Random; + +/** + * Ctf Iterator Manager, allows mapping of iterators (a limited resource) to + * contexts (many many resources). + * + * @author Matthew Khouzam + * @version 1.0 + * @since 1.1 + */ +public abstract class CtfIteratorManager { + /* + * A side note synchronized works on the whole object, Therefore add and + * remove will be thread safe. + */ + + /* + * The map of traces to trace managers. + */ + private static HashMap map = new HashMap<>(); + + /** + * Registers a trace to the iterator manager, the trace can now get + * iterators. + * + * @param trace + * the trace to register. + */ + public static synchronized void addTrace(final CtfTmfTrace trace) { + map.put(trace, new CtfTraceManager(trace)); + } + + /** + * Removes a trace to the iterator manager. + * + * @param trace + * the trace to register. + */ + public static synchronized void removeTrace(final CtfTmfTrace trace) { + CtfTraceManager mgr = map.remove(trace); + if (mgr != null) { + mgr.clear(); + } + } + + /** + * Get an iterator for a given trace and context. + * + * @param trace + * the trace + * @param ctx + * the context + * @return the iterator + * @since 2.0 + */ + public static synchronized CtfIterator getIterator(final CtfTmfTrace trace, + final CtfTmfContext ctx) { + return map.get(trace).getIterator(ctx); + } + + /** + * Remove an iterator for a given trace and context + * + * @param trace + * the trace + * @param ctx + * the context + * @since 2.1 + */ + public static synchronized void removeIterator(final CtfTmfTrace trace, final CtfTmfContext ctx) { + CtfTraceManager traceManager = map.get(trace); + if (traceManager != null) { + traceManager.removeIterator(ctx); + } + } +} + +/** + * A trace manager + * + * @author Matthew Khouzam + */ +class CtfTraceManager { + /* + * Cache size. Under 1023 on linux32 systems. Number of file handles + * created. + */ + private final static int MAX_SIZE = 100; + /* + * The map of the cache. + */ + private final HashMap fMap; + /* + * An array pointing to the same cache. this allows fast "random" accesses. + */ + private final ArrayList fRandomAccess; + /* + * The parent trace + */ + private final CtfTmfTrace fTrace; + /* + * Random number generator + */ + private final Random fRnd; + + public CtfTraceManager(CtfTmfTrace trace) { + fMap = new HashMap<>(); + fRandomAccess = new ArrayList<>(); + fRnd = new Random(System.nanoTime()); + fTrace = trace; + } + + /** + * This needs explaining: the iterator table is effectively a cache. + * Originally the contexts had a 1 to 1 structure with the file handles of a + * trace. This failed since there is a limit to how many file handles we can + * have opened simultaneously. Then a round-robin scheme was implemented, + * this lead up to a two competing contexts syncing up and using the same + * file handler, causing horrible slowdowns. Now a random replacement + * algorithm is selected. This is the same as used by arm processors, and it + * works quite well when many cores so this looks promising for very + * multi-threaded systems. + * + * @param context + * the context to look up + * @return the iterator referring to the context + */ + public CtfIterator getIterator(final CtfTmfContext context) { + /* + * if the element is in the map, we don't need to do anything else. + */ + CtfIterator retVal = fMap.get(context); + if (retVal == null) { + /* + * Assign an iterator to a context, this means we will need to seek + * at the end. + */ + if (fRandomAccess.size() < MAX_SIZE) { + /* + * if we're not full yet, just add an element. + */ + retVal = fTrace.createIterator(); + addElement(context, retVal); + + } else { + /* + * if we're full, randomly replace an element + */ + retVal = replaceRandomElement(context); + } + if (context.getLocation() != null) { + final CtfLocationInfo location = (CtfLocationInfo) context.getLocation().getLocationInfo(); + retVal.seek(location); + } + } + return retVal; + } + + public void removeIterator(CtfTmfContext context) { + try (CtfIterator removed = fMap.remove(context)) { + } + + fRandomAccess.remove(context); + } + + /** + * Add a pair of context and element to the hashmap and the arraylist. + * + * @param context + * the context + * @param elem + * the iterator + */ + private void addElement(final CtfTmfContext context, + final CtfIterator elem) { + fMap.put(context, elem); + fRandomAccess.add(context); + } + + /** + * Replace a random element + * + * @param context + * the context to swap in + * @return the iterator of the removed elements. + */ + private CtfIterator replaceRandomElement( + final CtfTmfContext context) { + /* + * This needs some explanation too: We need to select a random victim + * and remove it. The order of the elements is not important, so instead + * of just calling arraylist.remove(element) which has an O(n) + * complexity, we pick an random number. The element is swapped out of + * the array and removed and replaced in the hashmap. + */ + final int size = fRandomAccess.size(); + final int pos = fRnd.nextInt(size); + final CtfTmfContext victim = fRandomAccess.get(pos); + fRandomAccess.set(pos, context); + final CtfIterator elem = fMap.remove(victim); + fMap.put(context, elem); + victim.dispose(); + return elem; + } + + void clear() { + for (CtfIterator iterator : fMap.values()) { + iterator.dispose(); + } + fMap.clear(); + fRandomAccess.clear(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfLocation.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfLocation.java new file mode 100644 index 0000000000..d36983defc --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfLocation.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Alexandre Montplaisir - Extends TmfLocation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ctf.core; + +import java.nio.ByteBuffer; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLocation; + +/** + * The nugget of information that is unique to a location in a CTF trace. + * + * It can be copied and used to restore a position in a given trace. + * + * @version 1.0 + * @author Matthew Khouzam + */ +public final class CtfLocation extends TmfLocation { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * An invalid location + */ + public static final CtfLocationInfo INVALID_LOCATION = new CtfLocationInfo(-1, -1); + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Basic constructor for CtfLocation. Uses a default index of 0. + * + * @param timestamp + * The timestamp of this location + * @since 2.0 + */ + public CtfLocation(final ITmfTimestamp timestamp) { + this(timestamp.getValue(), 0); + } + + /** + * Constructor using timestamp object and index + * + * @param timestamp + * The timestamp of this location + * @param index + * The index of this location for this timestamp + * @since 2.0 + */ + public CtfLocation(final ITmfTimestamp timestamp, long index) { + this(timestamp.getValue(), index); + } + + /** + * Constructor using a long value for the timestamp, and an index + * + * @param timestampValue + * The new timestamp + * @param index + * The new index + * @since 2.0 + */ + public CtfLocation(final long timestampValue, final long index) { + super(new CtfLocationInfo(timestampValue, index)); + } + + /** + * Constructor using a pre-made locationInfo object + * + * @param locationInfo + * The locationInfo object to use + * @since 2.0 + */ + public CtfLocation(CtfLocationInfo locationInfo) { + super(locationInfo); + } + + /** + * Copy constructor + * + * @param location + * Other location to copy + * @since 2.0 + */ + public CtfLocation(final CtfLocation location) { + super(location); + } + + // ------------------------------------------------------------------------ + // TmfLocation + // ------------------------------------------------------------------------ + + /** + * Construct the location from the ByteBuffer. + * + * @param bufferIn + * the buffer to read from + * + * @since 3.0 + */ + public CtfLocation(ByteBuffer bufferIn) { + super(new CtfLocationInfo(bufferIn)); + } + + /** + * @since 2.0 + */ + @Override + public CtfLocationInfo getLocationInfo() { + return (CtfLocationInfo) super.getLocationInfo(); + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public String toString() { + if (getLocationInfo().equals(CtfLocation.INVALID_LOCATION )) { + return getClass().getSimpleName() + " [INVALID]"; //$NON-NLS-1$ + } + return super.toString(); + } + + /** + * Constructs the location from the ByteBuffer. This typically happens when reading from disk. + * + * @since 3.0 + */ + @Override + public void serialize(ByteBuffer bufferOut) { + getLocationInfo().serialize(bufferOut); + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfLocationInfo.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfLocationInfo.java new file mode 100644 index 0000000000..0e2c7db7dc --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfLocationInfo.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Matthew Khouzam - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ctf.core; + +import java.nio.ByteBuffer; + +/** + * The data object to go in a {@link CtfLocation}. + * + * @author Matthew Khouzam + * @since 2.0 + */ +public class CtfLocationInfo implements Comparable { + + private final long fTimestamp; + private final long fIndex; + + /** + * @param ts + * Timestamp + * @param index + * Index of this event (if there are N elements with the same + * timestamp, which one is it.) + */ + public CtfLocationInfo(long ts, long index) { + fTimestamp = ts; + fIndex = index; + } + + /** + * Construct the location from the ByteBuffer. + * + * @param bufferIn + * the buffer to read from + * + * @since 3.0 + */ + public CtfLocationInfo(ByteBuffer bufferIn) { + fTimestamp = bufferIn.getLong(); + fIndex = bufferIn.getLong(); + } + + /** + * @return The timestamp + */ + public long getTimestamp() { + return fTimestamp; + } + + /** + * @return The index of the element + */ + public long getIndex() { + return fIndex; + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = (prime * result) + (int) (fIndex ^ (fIndex >>> 32)); + result = (prime * result) + (int) (fTimestamp ^ (fTimestamp >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof CtfLocationInfo)) { + return false; + } + CtfLocationInfo other = (CtfLocationInfo) obj; + if (fIndex != other.fIndex) { + return false; + } + if (fTimestamp != other.fTimestamp) { + return false; + } + return true; + } + + @Override + public String toString() { + return "Element [" + fTimestamp + '/' + fIndex + ']'; //$NON-NLS-1$ + } + + // ------------------------------------------------------------------------ + // Comparable + // ------------------------------------------------------------------------ + + @Override + public int compareTo(CtfLocationInfo other) { + if (fTimestamp > other.getTimestamp()) { + return 1; + } + if (fTimestamp < other.getTimestamp()) { + return -1; + } + if (fIndex > other.getIndex()) { + return 1; + } + if (fIndex < other.getIndex()) { + return -1; + } + return 0; + } + + /** + * Write the location to the ByteBuffer so that it can be saved to disk. + * + * @param bufferOut + * the buffer to write to + * + * @since 3.0 + */ + public void serialize(ByteBuffer bufferOut) { + bufferOut.putLong(fTimestamp); + bufferOut.putLong(fIndex); + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfCallsite.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfCallsite.java new file mode 100644 index 0000000000..aa30803bfa --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfCallsite.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Bernd Hufmann - Updated for new parent class + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core; + +import org.eclipse.linuxtools.ctf.core.event.CTFCallsite; +import org.eclipse.tracecompass.tmf.core.event.lookup.TmfCallsite; + +/** + * CTF TMF call site information for source code lookup. + * + * @author Patrick Tasse + * @since 2.0 + */ +public class CtfTmfCallsite extends TmfCallsite { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** The event name. */ + final private String fEventName; + + /** The instruction pointer. */ + final private long fInstructionPointer; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Standard Constructor. + * + * @param callsite + * - a CTF call site + */ + CtfTmfCallsite(CTFCallsite callsite) { + super(callsite.getFileName(), callsite.getFunctionName(), callsite.getLineNumber()); + fEventName = callsite.getEventName(); + fInstructionPointer = callsite.getIp(); + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * Returns the event name of the call site. + * @return the event name + */ + public String getEventName() { + return fEventName; + } + + /** + * Returns the instruction pointer of the call site. + * @return the instruction pointer + */ + public long getIntructionPointer() { + return fInstructionPointer; + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((fEventName == null) ? 0 : fEventName.hashCode()); + result = prime * result + (int) (fInstructionPointer ^ (fInstructionPointer >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + CtfTmfCallsite other = (CtfTmfCallsite) obj; + if (fEventName == null) { + if (other.fEventName != null) { + return false; + } + } else if (!fEventName.equals(other.fEventName)) { + return false; + } + if (fInstructionPointer != other.fInstructionPointer) { + return false; + } + return true; + } + + @Override + public String toString() { + return getEventName() + "@0x" + Long.toHexString(fInstructionPointer) + ": " + //$NON-NLS-1$ //$NON-NLS-2$ + getFileName() + ':' + Long.toString(getLineNumber()) + ' ' + getFileName() + "()"; //$NON-NLS-1$ + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfContext.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfContext.java new file mode 100644 index 0000000000..5ab11e0ee5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfContext.java @@ -0,0 +1,202 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Simon Delisle - Remove the iterator in dispose() + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core; + +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +/** + * Lightweight Context for CtfTmf traces. Should only use 3 references, 1 ref to + * a boxed Long, a long and an int. + * + * @author Matthew Khouzam + * @version 1.0 + * @since 2.0 + */ +public class CtfTmfContext implements ITmfContext { + + // ------------------------------------------- + // Fields + // ------------------------------------------- + + private CtfLocation fCurLocation; + private long fCurRank; + + private final CtfTmfTrace fTrace; + + // ------------------------------------------- + // Constructor + // ------------------------------------------- + + /** + * Constructor + * + * @param ctfTmfTrace + * the parent trace + * @since 1.1 + */ + public CtfTmfContext(CtfTmfTrace ctfTmfTrace) { + fTrace = ctfTmfTrace; + fCurLocation = new CtfLocation(new CtfLocationInfo(0, 0)); + } + + // ------------------------------------------- + // TmfContext Overrides + // ------------------------------------------- + + @Override + public long getRank() { + return fCurRank; + } + + /** + * @since 3.0 + */ + @Override + public synchronized ITmfLocation getLocation() { + return fCurLocation; + } + + @Override + public boolean hasValidRank() { + return fCurRank != CtfLocation.INVALID_LOCATION.getTimestamp(); + } + + /** + * @since 3.0 + */ + @Override + public synchronized void setLocation(ITmfLocation location) { + fCurLocation = (CtfLocation) location; + if (fCurLocation != null) { + getIterator().seek(fCurLocation.getLocationInfo()); + } + } + + @Override + public void setRank(long rank) { + fCurRank = rank; + + } + + @Override + public void increaseRank() { + if (hasValidRank()) { + fCurRank++; + } + } + + // ------------------------------------------- + // CtfTmfTrace Helpers + // ------------------------------------------- + + /** + * Gets the trace of this context. + * + * @return The trace of this context + */ + public CtfTmfTrace getTrace() { + return fTrace; + } + + /** + * Gets the current event. Wrapper to help CtfTmfTrace + * + * @return The event or null + */ + public synchronized CtfTmfEvent getCurrentEvent() { + return getIterator().getCurrentEvent(); + } + + /** + * Advances to a the next event. Wrapper to help CtfTmfTrace + * + * @return success or not + */ + public synchronized boolean advance() { + final CtfLocationInfo curLocationData = fCurLocation.getLocationInfo(); + CtfIterator iterator = getIterator(); + boolean retVal = iterator.advance(); + CtfTmfEvent currentEvent = iterator.getCurrentEvent(); + + if (currentEvent != null) { + final long timestampValue = iterator.getCurrentTimestamp(); + if (curLocationData.getTimestamp() == timestampValue) { + fCurLocation = new CtfLocation(timestampValue, curLocationData.getIndex() + 1); + } else { + fCurLocation = new CtfLocation(timestampValue, 0L); + } + } else { + fCurLocation = new CtfLocation(CtfLocation.INVALID_LOCATION); + } + + return retVal; + } + + @Override + public void dispose() { + CtfIteratorManager.removeIterator(fTrace, this); + } + + /** + * Seeks to a given timestamp. Wrapper to help CtfTmfTrace + * + * @param timestamp + * desired timestamp + * @return success or not + */ + public synchronized boolean seek(final long timestamp) { + fCurLocation = new CtfLocation(timestamp, 0); + return getIterator().seek(timestamp); + } + + /** + * Seeks to a given location. Wrapper to help CtfTmfTrace + * @param location + * unique location to find the event. + * + * @return success or not + * @since 2.0 + */ + public synchronized boolean seek(final CtfLocationInfo location) { + fCurLocation = new CtfLocation(location); + return getIterator().seek(location); + } + + @Override + public CtfTmfContext clone() { + CtfTmfContext ret = null; + try { + ret = (CtfTmfContext) super.clone(); + /* Fields are immutable, no need to deep-copy them */ + } catch (CloneNotSupportedException e) { + /* Should not happen, we're calling Object.clone() */ + } + return ret; + } + + // ------------------------------------------- + // Private helpers + // ------------------------------------------- + + /** + * Get iterator, called every time to get an iterator, no local copy is + * stored so that there is no need to "update" + * + * @return an iterator + */ + private CtfIterator getIterator() { + return CtfIteratorManager.getIterator(fTrace, this); + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfEvent.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfEvent.java new file mode 100644 index 0000000000..aa5aacb2d0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfEvent.java @@ -0,0 +1,262 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + * Bernd Hufmann - Updated for source and model lookup interfaces + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.ctf.core.event.CTFCallsite; +import org.eclipse.linuxtools.ctf.core.event.EventDefinition; +import org.eclipse.linuxtools.ctf.core.event.IEventDeclaration; +import org.eclipse.linuxtools.ctf.core.event.types.ICompositeDefinition; +import org.eclipse.linuxtools.ctf.core.event.types.IDefinition; +import org.eclipse.linuxtools.ctf.core.trace.CTFTrace; +import org.eclipse.tracecompass.tmf.core.event.ITmfCustomAttributes; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfModelLookup; +import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfSourceLookup; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; + +/** + * A wrapper class around CTF's Event Definition/Declaration that maps all types + * of Declaration to native Java types. + * + * @version 1.0 + * @author Alexandre Montplaisir + * @since 2.0 + */ +public class CtfTmfEvent extends TmfEvent + implements ITmfSourceLookup, ITmfModelLookup, ITmfCustomAttributes { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + private static final String EMPTY_CTF_EVENT_NAME = "Empty CTF event"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final int fSourceCPU; + private final long fTypeId; + private final String fEventName; + private final IEventDeclaration fEventDeclaration; + @NonNull + private final EventDefinition fEvent; + private ITmfEventField fContent; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructor used by {@link CtfTmfEventFactory#createEvent} + */ + CtfTmfEvent(CtfTmfTrace trace, long rank, CtfTmfTimestamp timestamp, + String fileName, int cpu, IEventDeclaration declaration, @NonNull EventDefinition eventDefinition) { + super(trace, + rank, + timestamp, + String.valueOf(cpu), // Source + null, // Event type. We don't use TmfEvent's field here, we + // re-implement getType() + null, // Content handled with a lazy loaded re-implemented in + // getContent() + fileName // Reference + ); + + fEventDeclaration = declaration; + fSourceCPU = cpu; + fTypeId = declaration.getId().longValue(); + fEventName = declaration.getName(); + fEvent = eventDefinition; + + } + + /** + * Inner constructor to create "null" events. Don't use this directly in + * normal usage, use {@link CtfTmfEventFactory#getNullEvent()} to get an + * instance of an empty event. + * + * This needs to be public however because it's used in extension points, + * and the framework will use this constructor to get the class type. + */ + public CtfTmfEvent() { + super(null, + ITmfContext.UNKNOWN_RANK, + new CtfTmfTimestamp(-1), + null, + null, + new TmfEventField("", null, new CtfTmfEventField[0]), //$NON-NLS-1$ + null); + fSourceCPU = -1; + fTypeId = -1; + fEventName = EMPTY_CTF_EVENT_NAME; + fEventDeclaration = null; + fEvent = EventDefinition.NULL_EVENT; + } + + // ------------------------------------------------------------------------ + // Getters/Setters/Predicates + // ------------------------------------------------------------------------ + + /** + * Gets the cpu core the event was recorded on. + * + * @return The cpu id for a given source. In lttng it's from CPUINFO + */ + public int getCPU() { + return fSourceCPU; + } + + /** + * Return this event's ID, according to the trace's metadata. + * + * Watch out, this ID is not constant from one trace to another for the same + * event types! Use "getEventName()" for a constant reference. + * + * @return The event ID + */ + public long getID() { + return fTypeId; + } + + @Override + public CtfTmfTrace getTrace() { + /* + * Should be of the right type, since we take a CtfTmfTrace at the + * constructor + */ + return (CtfTmfTrace) super.getTrace(); + } + + @Override + public ITmfEventType getType() { + CtfTmfEventType ctfTmfEventType = CtfTmfEventType.get(getTrace(), fEventName); + if (ctfTmfEventType == null) { + /* Should only return null the first time */ + ctfTmfEventType = new CtfTmfEventType(fEventName, getTrace(), getContent()); + } + return ctfTmfEventType; + } + + /** + * @since 2.0 + */ + @Override + public Set listCustomAttributes() { + if (fEventDeclaration == null) { + return new HashSet<>(); + } + return fEventDeclaration.getCustomAttributes(); + } + + /** + * @since 2.0 + */ + @Override + public String getCustomAttribute(String name) { + if (fEventDeclaration == null) { + return null; + } + return fEventDeclaration.getCustomAttribute(name); + } + + /** + * Get the call site for this event. + * + * @return the call site information, or null if there is none + * @since 2.0 + */ + @Override + public CtfTmfCallsite getCallsite() { + CTFCallsite callsite = null; + CtfTmfTrace trace = getTrace(); + if (trace == null) { + return null; + } + CTFTrace ctfTrace = trace.getCTFTrace(); + /* Should not happen, but it is a good check */ + if (ctfTrace == null) { + return null; + } + if (getContent() != null) { + ITmfEventField ipField = getContent().getField(CtfConstants.CONTEXT_FIELD_PREFIX + CtfConstants.IP_KEY); + if (ipField != null && ipField.getValue() instanceof Long) { + long ip = (Long) ipField.getValue(); + callsite = ctfTrace.getCallsite(fEventName, ip); + } + } + if (callsite == null) { + callsite = ctfTrace.getCallsite(fEventName); + } + if (callsite != null) { + return new CtfTmfCallsite(callsite); + } + return null; + } + + /** + * @since 2.0 + */ + @Override + public String getModelUri() { + return getCustomAttribute(CtfConstants.MODEL_URI_KEY); + } + + @Override + public synchronized ITmfEventField getContent() { + if (fContent == null) { + fContent = new TmfEventField( + ITmfEventField.ROOT_FIELD_ID, null, parseFields(fEvent)); + } + return fContent; + } + + /** + * Extract the field information from the structDefinition haze-inducing + * mess, and put them into something ITmfEventField can cope with. + */ + private static CtfTmfEventField[] parseFields(@NonNull EventDefinition eventDef) { + List fields = new ArrayList<>(); + + ICompositeDefinition structFields = eventDef.getFields(); + if (structFields != null) { + if (structFields.getFieldNames() != null) { + for (String curFieldName : structFields.getFieldNames()) { + fields.add(CtfTmfEventField.parseField((IDefinition) structFields.getDefinition(curFieldName), curFieldName)); + } + } + } + /* Add context information as CtfTmfEventField */ + ICompositeDefinition structContext = eventDef.getContext(); + if (structContext != null) { + for (String contextName : structContext.getFieldNames()) { + /* Prefix field name */ + String curContextName = CtfConstants.CONTEXT_FIELD_PREFIX + contextName; + fields.add(CtfTmfEventField.parseField((IDefinition) structContext.getDefinition(contextName), curContextName)); + } + } + + return fields.toArray(new CtfTmfEventField[fields.size()]); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfEventFactory.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfEventFactory.java new file mode 100644 index 0000000000..6d9e5104b8 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfEventFactory.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core; + +import org.eclipse.linuxtools.ctf.core.CTFStrings; +import org.eclipse.linuxtools.ctf.core.event.EventDefinition; +import org.eclipse.linuxtools.ctf.core.event.IEventDeclaration; +import org.eclipse.linuxtools.ctf.core.event.types.IDefinition; +import org.eclipse.linuxtools.ctf.core.event.types.IntegerDefinition; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; + +/** + * Factory for CtfTmfEvent's. + * + * This code was moved out of CtfTmfEvent to provide better separation between + * the parsing/instantiation of events, and the usual TMF API implementations. + * + * @author Alexandre Montplaisir + * @since 2.0 + */ +public final class CtfTmfEventFactory { + + private static final String NO_STREAM = "No stream"; //$NON-NLS-1$ + + /** + * Don't let anyone instantiate this class. + */ + private CtfTmfEventFactory() {} + + /** + * Factory method to instantiate new {@link CtfTmfEvent}'s. + * + * @param eventDef + * CTF EventDefinition object corresponding to this trace event + * @param fileName + * The path to the trace file + * @param originTrace + * The trace from which this event originates + * @return The newly-built CtfTmfEvent + */ + public static CtfTmfEvent createEvent(EventDefinition eventDef, + String fileName, CtfTmfTrace originTrace) { + + /* Prepare what to pass to CtfTmfEvent's constructor */ + final IEventDeclaration eventDecl = eventDef.getDeclaration(); + final long ts = eventDef.getTimestamp(); + final CtfTmfTimestamp timestamp = originTrace.createTimestamp( + originTrace.getCTFTrace().timestampCyclesToNanos(ts)); + + int sourceCPU = eventDef.getCPU(); + + String reference = fileName == null ? NO_STREAM : fileName; + + /* Handle the special case of lost events */ + if (eventDecl.getName().equals(CTFStrings.LOST_EVENT_NAME)) { + IDefinition nbLostEventsDef = eventDef.getFields().getDefinition(CTFStrings.LOST_EVENTS_FIELD); + IDefinition durationDef = eventDef.getFields().getDefinition(CTFStrings.LOST_EVENTS_DURATION); + if (!(nbLostEventsDef instanceof IntegerDefinition) || !(durationDef instanceof IntegerDefinition)) { + /* + * One or both of these fields doesn't exist, or is not of the + * right type. The event claims to be a "lost event", but is + * malformed. Log it and return a null event instead. + */ + return getNullEvent(); + } + long nbLostEvents = ((IntegerDefinition) nbLostEventsDef).getValue(); + long duration = ((IntegerDefinition) durationDef).getValue(); + CtfTmfTimestamp timestampEnd = new CtfTmfTimestamp( + originTrace.getCTFTrace().timestampCyclesToNanos(ts) + duration); + + CtfTmfLostEvent lostEvent = new CtfTmfLostEvent(originTrace, + ITmfContext.UNKNOWN_RANK, + reference, // filename + sourceCPU, + eventDecl, + new TmfTimeRange(timestamp, timestampEnd), + nbLostEvents, + eventDef); + return lostEvent; + } + + /* Handle standard event types */ + CtfTmfEvent event = new CtfTmfEvent( + originTrace, + ITmfContext.UNKNOWN_RANK, + timestamp, + reference, // filename + sourceCPU, + eventDecl, + eventDef); + return event; + } + + /* Singleton instance of a null event */ + private static CtfTmfEvent nullEvent = null; + + /** + * Get an instance of a null event. + * + * @return An empty event + */ + public static CtfTmfEvent getNullEvent() { + if (nullEvent == null) { + nullEvent = new CtfTmfEvent(); + } + return nullEvent; + } + + +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfEventField.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfEventField.java new file mode 100644 index 0000000000..3895aa2d91 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfEventField.java @@ -0,0 +1,472 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Alexandre Montplaisir - Initial API and implementation, extend TmfEventField + * Bernd Hufmann - Add Enum field handling + * Geneviève Bastien - Add Struct and Variant field handling + * Jean-Christian Kouame - Correct handling of unsigned integer fields + * François Doray - Add generic array field type + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.eclipse.linuxtools.ctf.core.event.types.CompoundDeclaration; +import org.eclipse.linuxtools.ctf.core.event.types.Definition; +import org.eclipse.linuxtools.ctf.core.event.types.EnumDefinition; +import org.eclipse.linuxtools.ctf.core.event.types.FloatDefinition; +import org.eclipse.linuxtools.ctf.core.event.types.ICompositeDefinition; +import org.eclipse.linuxtools.ctf.core.event.types.IDeclaration; +import org.eclipse.linuxtools.ctf.core.event.types.IDefinition; +import org.eclipse.linuxtools.ctf.core.event.types.IntegerDeclaration; +import org.eclipse.linuxtools.ctf.core.event.types.IntegerDefinition; +import org.eclipse.linuxtools.ctf.core.event.types.StringDefinition; +import org.eclipse.linuxtools.ctf.core.event.types.VariantDefinition; +import org.eclipse.linuxtools.internal.ctf.core.event.types.ArrayDefinition; +import org.eclipse.linuxtools.internal.ctf.core.event.types.ByteArrayDefinition; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; + +/** + * The CTF implementation of the TMF event field model + * + * @version 2.0 + * @author Matthew Khouzam + * @author Alexandre Montplaisir + */ +public abstract class CtfTmfEventField extends TmfEventField { + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Standard constructor. Only to be used internally, call parseField() to + * generate a new field object. + * + * @param name + * The name of this field + * @param value + * The value of this field. Its type should match the field type. + * @param fields + * The children fields. Useful for composite fields + * @since 2.0 + */ + protected CtfTmfEventField(String name, Object value, ITmfEventField[] fields) { + super(/* Strip the underscore from the field name if there is one */ + name.startsWith("_") ? name.substring(1) : name, //$NON-NLS-1$ + value, + fields); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Factory method to instantiate CtfTmfEventField objects. + * + * @param fieldDef + * The CTF Definition of this event field + * @param fieldName + * String The name to assign to this field + * @return The resulting CtfTmfEventField object + * @deprecated use {@link CtfTmfEventField#parseField(IDefinition, String)} + */ + @Deprecated + public static CtfTmfEventField parseField(Definition fieldDef, + String fieldName) { + return parseField((IDefinition) fieldDef, fieldName); + } + + /** + * Factory method to instantiate CtfTmfEventField objects. + * + * @param fieldDef + * The CTF Definition of this event field + * @param fieldName + * String The name to assign to this field + * @return The resulting CtfTmfEventField object + * @since 3.1 + */ + public static CtfTmfEventField parseField(IDefinition fieldDef, + String fieldName) { + CtfTmfEventField field = null; + + /* Determine the Definition type */ + if (fieldDef instanceof IntegerDefinition) { + IntegerDefinition intDef = (IntegerDefinition) fieldDef; + int base = intDef.getDeclaration().getBase(); + field = new CTFIntegerField(fieldName, intDef.getValue(), base, intDef.getDeclaration().isSigned()); + + } else if (fieldDef instanceof EnumDefinition) { + EnumDefinition enumDef = (EnumDefinition) fieldDef; + field = new CTFEnumField(fieldName, new CtfEnumPair(enumDef.getValue(), enumDef.getIntegerValue())); + + } else if (fieldDef instanceof StringDefinition) { + field = new CTFStringField(fieldName, ((StringDefinition) fieldDef).getValue()); + + } else if (fieldDef instanceof FloatDefinition) { + FloatDefinition floatDef = (FloatDefinition) fieldDef; + field = new CTFFloatField(fieldName, floatDef.getValue()); + + } else if (fieldDef instanceof ArrayDefinition) { + ArrayDefinition arrayDef = (ArrayDefinition) fieldDef; + IDeclaration decl = arrayDef.getDeclaration(); + if (!(decl instanceof CompoundDeclaration)) { + throw new IllegalArgumentException("Array definitions should only come from sequence or array declarations"); //$NON-NLS-1$ + } + CompoundDeclaration arrDecl = (CompoundDeclaration) decl; + IDeclaration elemType = null; + Collection definitions = arrayDef.getDefinitions(); + elemType = arrDecl.getElementType(); + if (elemType instanceof IntegerDeclaration) { + /* Array of integers => CTFIntegerArrayField, unless it's a CTFStringField */ + IntegerDeclaration elemIntType = (IntegerDeclaration) elemType; + /* Are the integers characters and encoded? */ + if (elemIntType.isCharacter()) { + /* it's a CTFStringField */ + field = new CTFStringField(fieldName, arrayDef.toString()); + } else { + /* it's a CTFIntegerArrayField */ + long[] values = new long[arrayDef.getLength()]; + for (int i = 0; i < arrayDef.getLength(); i++) { + IDefinition elem = arrayDef.getDefinitions().get(i); + if (elem == null) { + break; + } + values[i] = ((IntegerDefinition) elem).getValue(); + } + field = new CTFIntegerArrayField(fieldName, values, + elemIntType.getBase(), + elemIntType.isSigned()); + } + } else { + /* Arrays of elements of any other type */ + CtfTmfEventField[] elements = new CtfTmfEventField[arrayDef.getLength()]; + /* Parse the elements of the array. */ + int i = 0; + for (IDefinition definition : definitions) { + CtfTmfEventField curField = CtfTmfEventField.parseField( + definition, fieldName + '[' + i + ']'); + elements[i] = curField; + i++; + } + + field = new CTFArrayField(fieldName, elements); + } + } else if (fieldDef instanceof ByteArrayDefinition) { + /* This is an array of ascii bytes, a.k.a. a String! */ + field = new CTFStringField(fieldName, fieldDef.toString()); + + } else if (fieldDef instanceof ICompositeDefinition) { + ICompositeDefinition strDef = (ICompositeDefinition) fieldDef; + + List list = new ArrayList<>(); + /* Recursively parse the fields */ + for (String curFieldName : strDef.getFieldNames()) { + list.add(CtfTmfEventField.parseField(strDef.getDefinition(curFieldName), curFieldName)); + } + field = new CTFStructField(fieldName, list.toArray(new CtfTmfEventField[list.size()])); + + } else if (fieldDef instanceof VariantDefinition) { + VariantDefinition varDef = (VariantDefinition) fieldDef; + + String curFieldName = varDef.getCurrentFieldName(); + IDefinition curFieldDef = varDef.getCurrentField(); + if (curFieldDef != null) { + CtfTmfEventField subField = CtfTmfEventField.parseField(curFieldDef, curFieldName); + field = new CTFVariantField(fieldName, subField); + } else { + /* A safe-guard, but curFieldDef should never be null */ + field = new CTFStringField(curFieldName, ""); //$NON-NLS-1$ + } + + } else { + /* + * Safe-guard, to avoid null exceptions later, field is expected not + * to be null + */ + field = new CTFStringField(fieldName, Messages.CtfTmfEventField_UnsupportedType + fieldDef.getClass().toString()); + } + return field; + } + + @Override + public String toString() { + return getName() + '=' + getFormattedValue(); + } + +} + +/** + * The CTF field implementation for integer fields. + * + * @author alexmont + */ +final class CTFIntegerField extends CtfTmfEventField { + + private final int fBase; + private final boolean fSigned; + + /** + * A CTF "IntegerDefinition" can be an integer of any byte size, so in the + * Java parser this is interpreted as a long. + * + * @param name + * The name of this field + * @param longValue + * The integer value of this field + * @param signed + * Is the value signed or not + */ + CTFIntegerField(String name, long longValue, int base, boolean signed) { + super(name, longValue, null); + fSigned = signed; + fBase = base; + } + + @Override + public Long getValue() { + return (Long) super.getValue(); + } + + @Override + public String getFormattedValue() { + return IntegerDefinition.formatNumber(getValue(), fBase, fSigned); + } + +} + +/** + * The CTF field implementation for string fields + * + * @author alexmont + */ +final class CTFStringField extends CtfTmfEventField { + + /** + * Constructor for CTFStringField. + * + * @param strValue + * The string value of this field + * @param name + * The name of this field + */ + CTFStringField(String name, String strValue) { + super(name, strValue, null); + } + + @Override + public String getValue() { + return (String) super.getValue(); + } +} + +/** + * CTF field implementation for arrays of integers. + * + * @author alexmont + */ +final class CTFIntegerArrayField extends CtfTmfEventField { + + private final int fBase; + private final boolean fSigned; + private String fFormattedValue = null; + + /** + * Constructor for CTFIntegerArrayField. + * + * @param name + * The name of this field + * @param longValues + * The array of integers (as longs) that compose this field's + * value + * @param signed + * Are the values in the array signed or not + */ + CTFIntegerArrayField(String name, long[] longValues, int base, boolean signed) { + super(name, longValues, null); + fBase = base; + fSigned = signed; + } + + @Override + public long[] getValue() { + return (long[]) super.getValue(); + } + + @Override + public synchronized String getFormattedValue() { + if (fFormattedValue == null) { + List strings = new ArrayList<>(); + for (long value : getValue()) { + strings.add(IntegerDefinition.formatNumber(value, fBase, fSigned)); + } + fFormattedValue = strings.toString(); + } + return fFormattedValue; + } + +} + +/** + * CTF field implementation for arrays of arbitrary types. + * + * @author fdoray + */ +final class CTFArrayField extends CtfTmfEventField { + + private String fFormattedValue = null; + + /** + * Constructor for CTFArrayField. + * + * @param name + * The name of this field + * @param elements + * The array elements of this field + */ + CTFArrayField(String name, CtfTmfEventField[] elements) { + super(name, elements, elements); + } + + @Override + public CtfTmfEventField[] getValue() { + return (CtfTmfEventField[]) super.getValue(); + } + + @Override + public synchronized String getFormattedValue() { + if (fFormattedValue == null) { + List strings = new ArrayList<>(); + for (CtfTmfEventField element : getValue()) { + strings.add(element.getFormattedValue()); + } + fFormattedValue = strings.toString(); + } + return fFormattedValue; + } +} + +/** + * CTF field implementation for floats. + * + * @author emathko + */ +final class CTFFloatField extends CtfTmfEventField { + + /** + * Constructor for CTFFloatField. + * + * @param value + * The float value (actually a double) of this field + * @param name + * The name of this field + */ + protected CTFFloatField(String name, double value) { + super(name, value, null); + } + + @Override + public Double getValue() { + return (Double) super.getValue(); + } +} + +/** + * The CTF field implementation for Enum fields + * + * @author Bernd Hufmann + */ +final class CTFEnumField extends CtfTmfEventField { + + /** + * Constructor for CTFEnumField. + * + * @param enumValue + * The Enum value consisting of a pair of Enum value name and its + * long value + * @param name + * The name of this field + */ + CTFEnumField(String name, CtfEnumPair enumValue) { + super(name, new CtfEnumPair(enumValue.getFirst(), + enumValue.getSecond()), null); + } + + @Override + public CtfEnumPair getValue() { + return (CtfEnumPair) super.getValue(); + } +} + +/** + * The CTF field implementation for struct fields with sub-fields + * + * @author gbastien + */ +final class CTFStructField extends CtfTmfEventField { + + /** + * Constructor for CTFStructField. + * + * @param fields + * The children of this field + * @param name + * The name of this field + */ + CTFStructField(String name, CtfTmfEventField[] fields) { + super(name, fields, fields); + } + + @Override + public CtfTmfEventField[] getValue() { + return (CtfTmfEventField[]) super.getValue(); + } + + @Override + public String getFormattedValue() { + return Arrays.toString(getValue()); + } + +} + +/** + * The CTF field implementation for variant fields its child + * + * @author gbastien + */ +final class CTFVariantField extends CtfTmfEventField { + + /** + * Constructor for CTFVariantField. + * + * @param field + * The field selected for this variant + * @param name + * The name of this field + */ + CTFVariantField(String name, CtfTmfEventField field) { + super(name, field, new CtfTmfEventField[] { field }); + } + + @Override + public CtfTmfEventField getValue() { + return (CtfTmfEventField) super.getValue(); + } + +} + +/* Implement other possible fields types here... */ diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfEventType.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfEventType.java new file mode 100644 index 0000000000..c4274188f5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfEventType.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.eclipse.tracecompass.tmf.core.event.TmfEventTypeManager; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * The CTF extension of the TMF event type + * + * @version 1.0 + * @author Matthew khouzam + */ +public class CtfTmfEventType extends TmfEventType { + + /** + * CTFTmfEventType context for the event type manager + */ + private static final String CONTEXT_ID = "Ctf Event"; //$NON-NLS-1$ + + private static final String UNKNOWN_TRACE = "unknown"; //$NON-NLS-1$ + + /** + * Constructor for CtfTmfEventType. + * + * @param eventName + * The event name + * @param trace + * the parent trace + * @param content + * The event field + * @since 3.0 + */ + public CtfTmfEventType(String eventName, ITmfTrace trace, ITmfEventField content) { + super(computeContextName(trace), eventName, content); + } + + /** + * Method toString. + * + * @return String + */ + @Override + public String toString() { + return getName(); + } + + /** + * gets the event type for an event name + * + * @param trace + * the parent trace + * @param eventName + * the event name + * @return the event type + * @since 3.0 + */ + public static CtfTmfEventType get(CtfTmfTrace trace, String eventName) { + return (CtfTmfEventType) TmfEventTypeManager.getInstance().getType(computeContextName(trace), eventName); + } + + /** + * Get the context name of a ctf trace + * + * @param trace + * the trace + * @return the context name + * @since 3.0 + */ + public static String computeContextName(ITmfTrace trace) { + return CONTEXT_ID + "/" + (trace == null ? UNKNOWN_TRACE : trace.getPath()); //$NON-NLS-1$ + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfLostEvent.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfLostEvent.java new file mode 100644 index 0000000000..12276a1264 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfLostEvent.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.ctf.core.event.EventDefinition; +import org.eclipse.linuxtools.ctf.core.event.IEventDeclaration; +import org.eclipse.tracecompass.tmf.core.event.ITmfLostEvent; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; + +/** + * An implementation of {@link ITmfLostEvent} for use in the CTF adaptor. + * + * @author Alexandre Montplaisir + * @since 2.2 + */ +public class CtfTmfLostEvent extends CtfTmfEvent implements ITmfLostEvent { + + private final TmfTimeRange fTimeRange; + private final long fNbLost; + + /** + * Constructor. Only {@link CtfTmfEventFactory} should call this. + * + * @param trace + * The origin trace + * @param rank + * The rank of the event in the trace + * @param content + * The event's payload (fields). In case this event has some. + * @param fileName + * The name of the trace file from which this event comes + * @param cpu + * The CPU on which this event happened + * @param declaration + * The CTF Event Declaration object that created this event + * @param timeRange + * The time range of lost events indicated by this one + * @param nbLost + * The number of lost events in the range + */ + CtfTmfLostEvent(CtfTmfTrace trace, + long rank, + String fileName, + int cpu, + IEventDeclaration declaration, + TmfTimeRange timeRange, + long nbLost, + @NonNull EventDefinition def) { + /* + * Only the factory should call this method, the case to + * (CtfTmfTimestamp) should be safe. + */ + super(trace, rank, (CtfTmfTimestamp) timeRange.getStartTime(), fileName, cpu, declaration, def); + fTimeRange = timeRange; + fNbLost = nbLost; + } + + @Override + public TmfTimeRange getTimeRange() { + return fTimeRange; + } + + @Override + public long getNbLostEvents() { + return fNbLost; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfTimestamp.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfTimestamp.java new file mode 100644 index 0000000000..c591c6322c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfTimestamp.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; + +/** + * The CTF adapter for the TMF timestamp. It's basically the same as a + * TmfTimestamp, but the scale is always nanoseconds, and the precision is 0. + * + * @version 1.2 + * @author Matthew khouzam + */ +public final class CtfTmfTimestamp extends TmfTimestamp { + + /** + * Constructor for CtfTmfTimestamp. + * + * @param timestamp + * The timestamp value (in nanoseconds) + */ + public CtfTmfTimestamp(long timestamp) { + super(timestamp, ITmfTimestamp.NANOSECOND_SCALE, 0); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfTrace.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfTrace.java new file mode 100644 index 0000000000..529f12eb12 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/CtfTmfTrace.java @@ -0,0 +1,518 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Patrick Tasse - Updated for removal of context clone + * Geneviève Bastien - Added the createTimestamp function + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core; + +import java.nio.BufferOverflowException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.linuxtools.ctf.core.event.CTFClock; +import org.eclipse.linuxtools.ctf.core.event.IEventDeclaration; +import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException; +import org.eclipse.linuxtools.ctf.core.trace.CTFTrace; +import org.eclipse.linuxtools.ctf.core.trace.CTFTraceReader; +import org.eclipse.tracecompass.internal.tmf.ctf.core.Activator; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventTypeManager; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfEventParser; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceProperties; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceWithPreDefinedEvents; +import org.eclipse.tracecompass.tmf.core.trace.TmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TraceValidationStatus; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfPersistentlyIndexable; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.indexer.TmfBTreeTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +import com.google.common.collect.ImmutableSet; + +/** + * The CTf trace handler + * + * @version 1.0 + * @author Matthew khouzam + */ +public class CtfTmfTrace extends TmfTrace + implements ITmfEventParser, ITmfTraceProperties, ITmfPersistentlyIndexable, + ITmfTraceWithPreDefinedEvents, AutoCloseable { + + // ------------------------------------------- + // Constants + // ------------------------------------------- + /** + * Default cache size for CTF traces + */ + protected static final int DEFAULT_CACHE_SIZE = 50000; + + /* + * The Ctf clock unique identifier field + */ + private static final String CLOCK_HOST_PROPERTY = "uuid"; //$NON-NLS-1$ + private static final int CONFIDENCE = 10; + + // ------------------------------------------- + // Fields + // ------------------------------------------- + + /* Reference to the CTF Trace */ + private CTFTrace fTrace; + + // ------------------------------------------- + // TmfTrace Overrides + // ------------------------------------------- + /** + * Method initTrace. + * + * @param resource + * The resource associated with this trace + * @param path + * The path to the trace file + * @param eventType + * The type of events that will be read from this trace + * @throws TmfTraceException + * If something went wrong while reading the trace + */ + @Override + public void initTrace(final IResource resource, final String path, final Class eventType) + throws TmfTraceException { + /* + * Set the cache size. This has to be done before the call to super() + * because the super needs to know the cache size. + */ + setCacheSize(); + + super.initTrace(resource, path, eventType); + + try { + this.fTrace = new CTFTrace(path); + CtfIteratorManager.addTrace(this); + CtfTmfContext ctx; + /* Set the start and (current) end times for this trace */ + ctx = (CtfTmfContext) seekEvent(0L); + CtfTmfEvent event = getNext(ctx); + if ((ctx.getLocation().equals(CtfIterator.NULL_LOCATION)) || (ctx.getCurrentEvent() == null)) { + /* Handle the case where the trace is empty */ + this.setStartTime(TmfTimestamp.BIG_BANG); + } else { + final ITmfTimestamp curTime = event.getTimestamp(); + this.setStartTime(curTime); + this.setEndTime(curTime); + } + /* + * Register every event type. When you call getType, it will + * register a trace to that type in the TmfEventTypeManager + */ + try (CtfIterator iter = CtfIteratorManager.getIterator(this, ctx)) { + for (IEventDeclaration ied : iter.getEventDeclarations()) { + CtfTmfEventType ctfTmfEventType = CtfTmfEventType.get(this, ied.getName()); + if (ctfTmfEventType == null) { + List content = new ArrayList<>(); + /* Should only return null the first time */ + for (String fieldName : ied.getFields().getFieldsList()) { + content.add(new TmfEventField(fieldName, null, null)); + } + ITmfEventField contentTree = new TmfEventField( + ITmfEventField.ROOT_FIELD_ID, + null, + content.toArray(new ITmfEventField[content.size()]) + ); + + ctfTmfEventType = new CtfTmfEventType(ied.getName(), this, contentTree); + } + } + } + } catch (final CTFReaderException e) { + /* + * If it failed at the init(), we can assume it's because the file + * was not found or was not recognized as a CTF trace. Throw into + * the new type of exception expected by the rest of TMF. + */ + throw new TmfTraceException(e.getMessage(), e); + } + } + + @Override + public void close() { + dispose(); + } + + @Override + public synchronized void dispose() { + CtfIteratorManager.removeTrace(this); + if (fTrace != null) { + fTrace.close(); + fTrace = null; + } + super.dispose(); + } + + /** + * {@inheritDoc} + *

+ * The default implementation sets the confidence to 10 if the trace is a + * valid CTF trace. + */ + @Override + public IStatus validate(final IProject project, final String path) { + IStatus status = new TraceValidationStatus(CONFIDENCE, Activator.PLUGIN_ID); + try (final CTFTrace temp = new CTFTrace(path);) { + if (!temp.majorIsSet()) { + status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_MajorNotSet); + } else { + try (CTFTraceReader ctfTraceReader = new CTFTraceReader(temp);) { + if (!ctfTraceReader.hasMoreEvents()) { + // TODO: This will need an additional check when we + // support live traces + // because having no event is valid for a live trace + status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_NoEvent); + } + } + } + } catch (final CTFReaderException e) { + status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_ReadingError + ": " + e.toString()); //$NON-NLS-1$ + } catch (final BufferOverflowException e) { + status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_ReadingError + ": " + Messages.CtfTmfTrace_BufferOverflowErrorMessage); //$NON-NLS-1$ + } + + return status; + } + + /** + * Method getCurrentLocation. This is not applicable in CTF + * + * @return null, since the trace has no knowledge of the current location + * @see org.eclipse.tracecompass.tmf.core.trace.ITmfTrace#getCurrentLocation() + * @since 3.0 + */ + @Override + public ITmfLocation getCurrentLocation() { + return null; + } + + /** + * @since 3.0 + */ + @Override + public double getLocationRatio(ITmfLocation location) { + final CtfLocation curLocation = (CtfLocation) location; + final CtfTmfContext context = new CtfTmfContext(this); + context.setLocation(curLocation); + context.seek(curLocation.getLocationInfo()); + final CtfLocationInfo currentTime = ((CtfLocationInfo) context.getLocation().getLocationInfo()); + final long startTime = getIterator(this, context).getStartTime(); + final long endTime = getIterator(this, context).getEndTime(); + return ((double) currentTime.getTimestamp() - startTime) + / (endTime - startTime); + } + + /** + * Method seekEvent. + * + * @param location + * ITmfLocation + * @return ITmfContext + * @since 3.0 + */ + @Override + public synchronized ITmfContext seekEvent(final ITmfLocation location) { + CtfLocation currentLocation = (CtfLocation) location; + CtfTmfContext context = new CtfTmfContext(this); + if (fTrace == null) { + context.setLocation(null); + context.setRank(ITmfContext.UNKNOWN_RANK); + return context; + } + /* + * The rank is set to 0 if the iterator seeks the beginning. If not, it + * will be set to UNKNOWN_RANK, since CTF traces don't support seeking + * by rank for now. + */ + if (currentLocation == null) { + currentLocation = new CtfLocation(new CtfLocationInfo(0L, 0L)); + context.setRank(0); + } + if (currentLocation.getLocationInfo() == CtfLocation.INVALID_LOCATION) { + currentLocation = new CtfLocation(getCTFTrace().getCurrentEndTime() + 1, 0L); + } + context.setLocation(currentLocation); + if (location == null) { + long timestamp = getIterator(this, context).getCurrentTimestamp(); + currentLocation = new CtfLocation(timestamp, 0); + } + if (context.getRank() != 0) { + context.setRank(ITmfContext.UNKNOWN_RANK); + } + return context; + } + + @Override + public synchronized ITmfContext seekEvent(double ratio) { + CtfTmfContext context = new CtfTmfContext(this); + if (fTrace == null) { + context.setLocation(null); + context.setRank(ITmfContext.UNKNOWN_RANK); + return context; + } + final long end = getCTFTrace().getCurrentEndTime(); + final long start = getCTFTrace().getCurrentStartTime(); + final long diff = end - start; + final long ratioTs = Math.round(diff * ratio) + start; + context.seek(ratioTs); + context.setRank(ITmfContext.UNKNOWN_RANK); + return context; + } + + /** + * Method readNextEvent. + * + * @param context + * ITmfContext + * @return CtfTmfEvent + * @see org.eclipse.tracecompass.tmf.core.trace.ITmfTrace#getNext(ITmfContext) + */ + @Override + public synchronized CtfTmfEvent getNext(final ITmfContext context) { + if (fTrace == null) { + return null; + } + CtfTmfEvent event = null; + if (context instanceof CtfTmfContext) { + if (context.getLocation() == null || CtfLocation.INVALID_LOCATION.equals(context.getLocation().getLocationInfo())) { + return null; + } + CtfTmfContext ctfContext = (CtfTmfContext) context; + event = ctfContext.getCurrentEvent(); + + if (event != null) { + updateAttributes(context, event.getTimestamp()); + ctfContext.advance(); + ctfContext.increaseRank(); + } + } + + return event; + } + + /** + * gets the CTFtrace that this is wrapping + * + * @return the CTF trace + */ + public CTFTrace getCTFTrace() { + return fTrace; + } + + /** + * Ctf traces have a clock with a unique uuid that will be used to identify + * the host. Traces with the same clock uuid will be known to have been made + * on the same machine. + * + * Note: uuid is an optional field, it may not be there for a clock. + */ + @Override + public String getHostId() { + CTFClock clock = getCTFTrace().getClock(); + if (clock != null) { + String clockHost = (String) clock.getProperty(CLOCK_HOST_PROPERTY); + if (clockHost != null) { + return clockHost; + } + } + return super.getHostId(); + } + + // ------------------------------------------- + // ITmfTraceProperties + // ------------------------------------------- + + /** + * @since 2.0 + */ + @Override + public Map getTraceProperties() { + Map properties = new HashMap<>(); + properties.putAll(fTrace.getEnvironment()); + properties.put(Messages.CtfTmfTrace_HostID, getHostId()); + return properties; + } + + // ------------------------------------------- + // Clocks + // ------------------------------------------- + + /** + * gets the clock offset + * + * @return the clock offset in ns + */ + public long getOffset() { + if (fTrace != null) { + return fTrace.getOffset(); + } + return 0; + } + + /** + * Gets the list of declared events + * + * @since 3.0 + */ + @Override + public Set getContainedEventTypes() { + TmfEventTypeManager instance = TmfEventTypeManager.getInstance(); + Set eventTypes = instance.getTypes(CtfTmfEventType.computeContextName(this)); + return ImmutableSet.copyOf(eventTypes); + } + + // ------------------------------------------- + // Parser + // ------------------------------------------- + + @Override + public CtfTmfEvent parseEvent(ITmfContext context) { + CtfTmfEvent event = null; + if (context instanceof CtfTmfContext) { + final ITmfContext tmpContext = seekEvent(context.getLocation()); + event = getNext(tmpContext); + } + return event; + } + + /** + * Sets the cache size for a CtfTmfTrace. + */ + protected void setCacheSize() { + setCacheSize(DEFAULT_CACHE_SIZE); + } + + // ------------------------------------------- + // Helpers + // ------------------------------------------- + + private static CtfIterator getIterator(CtfTmfTrace trace, CtfTmfContext context) { + return CtfIteratorManager.getIterator(trace, context); + } + + /** + * Get an iterator to the trace + * + * @return an iterator to the trace + * @since 2.0 + */ + public CtfIterator createIterator() { + try { + return new CtfIterator(this); + } catch (CTFReaderException e) { + Activator.getDefault().logError(e.getMessage(), e); + } + return null; + } + + // ------------------------------------------------------------------------ + // Timestamp transformation functions + // ------------------------------------------------------------------------ + + /** + * @since 3.0 + */ + @Override + public CtfTmfTimestamp createTimestamp(long ts) { + return new CtfTmfTimestamp(getTimestampTransform().transform(ts)); + } + + private static int fCheckpointSize = -1; + + /** + * @since 3.0 + */ + @Override + public synchronized int getCheckpointSize() { + if (fCheckpointSize == -1) { + TmfCheckpoint c = new TmfCheckpoint(new CtfTmfTimestamp(0), new CtfLocation(0, 0), 0); + ByteBuffer b = ByteBuffer.allocate(ITmfCheckpoint.MAX_SERIALIZE_SIZE); + b.clear(); + c.serialize(b); + fCheckpointSize = b.position(); + } + + return fCheckpointSize; + } + + @Override + protected ITmfTraceIndexer createIndexer(int interval) { + return new TmfBTreeTraceIndexer(this, interval); + } + + /** + * @since 3.0 + */ + @Override + public ITmfLocation restoreLocation(ByteBuffer bufferIn) { + return new CtfLocation(bufferIn); + } + + @Override + public boolean isComplete() { + if (getResource() == null) { + return true; + } + + String host = null; + String port = null; + String sessionName = null; + try { + host = getResource().getPersistentProperty(CtfConstants.LIVE_HOST); + port = getResource().getPersistentProperty(CtfConstants.LIVE_PORT); + sessionName = getResource().getPersistentProperty(CtfConstants.LIVE_SESSION_NAME); + } catch (CoreException e) { + Activator.getDefault().logError(e.getMessage(), e); + // Something happened to the resource, assume we won't get any more data from it + return true; + } + return host == null || port == null || sessionName == null; + } + + @Override + public void setComplete(final boolean isComplete) { + super.setComplete(isComplete); + try { + if (isComplete) { + getResource().setPersistentProperty(CtfConstants.LIVE_HOST, null); + getResource().setPersistentProperty(CtfConstants.LIVE_PORT, null); + getResource().setPersistentProperty(CtfConstants.LIVE_SESSION_NAME, null); + } + } catch (CoreException e) { + Activator.getDefault().logError(e.getMessage(), e); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/Messages.java b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/Messages.java new file mode 100644 index 0000000000..c34bac7bf8 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/Messages.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.core; + +import org.eclipse.osgi.util.NLS; + +/** + * Message bundle for tmf.core.ctfadaptor + * + * @author Matthew Khouzam + * @since 2.0 + */ +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.ctf.core.messages"; //$NON-NLS-1$ + + /** Buffer overflow detected + * @since 2.1*/ + public static String CtfTmfTrace_BufferOverflowErrorMessage; + + /** + * Text for host ID + * + * @since 3.1 + */ + public static String CtfTmfTrace_HostID; + + /** Major version number not set */ + public static String CtfTmfTrace_MajorNotSet; + + /** Reading error */ + public static String CtfTmfTrace_ReadingError; + + /** No event */ + public static String CtfTmfTrace_NoEvent; + + /** Unsupported field type */ + public static String CtfTmfEventField_UnsupportedType; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/messages.properties b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/messages.properties new file mode 100644 index 0000000000..14d393b2db --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/messages.properties @@ -0,0 +1,18 @@ +############################################################################### +# Copyright (c) 2013 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### + +CtfTmfTrace_BufferOverflowErrorMessage=Buffer overflow exception, trace is malformed +CtfTmfTrace_HostID=host ID +CtfTmfTrace_MajorNotSet=Major version number not set +CtfTmfTrace_ReadingError=Reading error +CtfTmfTrace_NoEvent=Trace has no events +CtfTmfEventField_UnsupportedType=Unsupported field type: \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/META-INF/MANIFEST.MF b/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/META-INF/MANIFEST.MF index 4674ca5f69..2e58d3acaa 100644 --- a/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/META-INF/MANIFEST.MF @@ -7,7 +7,7 @@ Bundle-Localization: plugin Bundle-SymbolicName: org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests;singleton:=true Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.7 -Export-Package: org.eclipse.linuxtools.tmf.ctf.ui.swtbot.tests +Export-Package: org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests Require-Bundle: org.junit;bundle-version="4.0.0", org.eclipse.core.resources, org.eclipse.core.runtime, diff --git a/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/pom.xml b/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/pom.xml index 27164aea5c..0cbd07f298 100644 --- a/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/pom.xml +++ b/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/pom.xml @@ -33,7 +33,7 @@ ${tycho-version} org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests - org.eclipse.linuxtools.tmf.ctf.ui.swtbot.tests.AllTests + org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests.AllTests true false ${tycho.testArgLine} ${base.ui.test.vmargs} diff --git a/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ctf/ui/swtbot/tests/AbstractImportAndReadSmokeTest.java b/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ctf/ui/swtbot/tests/AbstractImportAndReadSmokeTest.java deleted file mode 100644 index 12803adb19..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ctf/ui/swtbot/tests/AbstractImportAndReadSmokeTest.java +++ /dev/null @@ -1,336 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * (Extracted from ImportAndReadSmokeTest.java) - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.ui.swtbot.tests; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assume.assumeTrue; - -import java.util.List; - -import org.apache.log4j.Logger; -import org.apache.log4j.varia.NullAppender; -import org.eclipse.core.runtime.IPath; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfEvent; -import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace; -import org.eclipse.linuxtools.tmf.ui.editors.TmfEventsEditor; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTracesFolder; -import org.eclipse.linuxtools.tmf.ui.swtbot.tests.SWTBotUtil; -import org.eclipse.linuxtools.tmf.ui.swtbot.tests.conditions.ConditionHelpers; -import org.eclipse.linuxtools.tmf.ui.views.histogram.HistogramView; -import org.eclipse.linuxtools.tmf.ui.views.statistics.TmfStatisticsView; -import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; -import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; -import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; -import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; -import org.eclipse.swtbot.swt.finder.results.VoidResult; -import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences; -import org.eclipse.swtbot.swt.finder.waits.Conditions; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotText; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarButton; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IEditorReference; -import org.eclipse.ui.IPageLayout; -import org.eclipse.ui.IViewPart; -import org.eclipse.ui.IViewReference; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.views.properties.PropertySheet; -import org.junit.BeforeClass; -import org.junit.runner.RunWith; - -/** - * Abstract SWTBot Smoke test class. - * - * @author Matthew Khouzam - * @author Bernd Hufmann - */ -@RunWith(SWTBotJunit4ClassRunner.class) -public abstract class AbstractImportAndReadSmokeTest { - - /** Trace name */ - protected static final String TRACE_NAME = "scp_dest"; - /** Trace folder */ - protected static final String TRACE_FOLDER = "synctraces"; - /** Trace type name for generic CTF traces */ - protected static final String TRACE_TYPE_NAME = "Generic CTF Trace"; - /** A Generic CTF Trace*/ - protected static final CtfTmfTestTrace fTrace = CtfTmfTestTrace.SYNC_DEST; - /** SWT BOT workbench reference */ - protected static SWTWorkbenchBot fBot; - /** Wizard to use */ - protected static Wizard fWizard; - - /** The Log4j logger instance. */ - protected static final Logger fLogger = Logger.getRootLogger(); - - /** Test Class setup */ - @BeforeClass - public static void init() { - assumeTrue(fTrace.exists()); - SWTBotUtil.failIfUIThread(); - - /* set up for swtbot */ - SWTBotPreferences.TIMEOUT = 50000; /* 50 second timeout */ - fLogger.addAppender(new NullAppender()); - fBot = new SWTWorkbenchBot(); - - SWTBotUtil.closeView("welcome", fBot); - - SWTBotUtil.switchToTracingPerspective(); - /* finish waiting for eclipse to load */ - SWTBotUtil.waitForJobs(); - } - - /** - * Creates a tracing projects - */ - protected void createProject() { - SWTBotUtil.focusMainWindow(fBot.shells()); - fBot.menu("File").menu("New").menu("Project...").click(); - - fBot.shell("New Project").setFocus(); - SWTBotTree tree = fBot.tree(); - assertNotNull(tree); - final String tracingKey = "Tracing"; - fBot.waitUntil(ConditionHelpers.IsTreeNodeAvailable(tracingKey, tree)); - final SWTBotTreeItem tracingNode = tree.expandNode(tracingKey); - - tracingNode.select(); - final String projectKey = "Tracing Project"; - fBot.waitUntil(ConditionHelpers.IsTreeChildNodeAvailable(projectKey, tracingNode)); - final SWTBotTreeItem tracingProject = tracingNode.getNode(projectKey); - assertNotNull(tracingProject); - - tracingProject.select(); - tracingProject.click(); - - SWTBotButton nextButton = fBot.button("Next >"); - fBot.waitUntil(Conditions.widgetIsEnabled(nextButton)); - nextButton.click(); - fBot.shell("Tracing Project").setFocus(); - - final SWTBotText text = fBot.text(); - text.setText(getProjectName()); - - fBot.button("Finish").click(); - SWTBotUtil.waitForJobs(); - } - - /** - * Opens and get the TmfEventsEditor - * - * @param elementPath - * the trace element path (relative to Traces folder) - * @return TmfEventsEditor - */ - protected TmfEventsEditor openEditor(IPath elementPath) { - final SWTBotView projectExplorerBot = fBot.viewById(IPageLayout.ID_PROJECT_EXPLORER); - projectExplorerBot.setFocus(); - - final SWTBotTree tree = fBot.tree(); - final SWTBotTreeItem treeItem = tree.getTreeItem(getProjectName()); - treeItem.expand(); - - String nodeName = getFullNodeName(treeItem, TmfTracesFolder.TRACES_FOLDER_NAME); - fBot.waitUntil(ConditionHelpers.IsTreeChildNodeAvailable(nodeName, treeItem)); - SWTBotTreeItem tracesNode = treeItem.getNode(nodeName); - tracesNode.expand(); - - SWTBotTreeItem currentNode = tracesNode; - for (String segment : elementPath.segments()) { - String fullNodeName = getFullNodeName(currentNode, segment); - fBot.waitUntil(ConditionHelpers.IsTreeChildNodeAvailable(fullNodeName, currentNode)); - SWTBotTreeItem newNode = currentNode.getNode(fullNodeName); - newNode.select(); - newNode.doubleClick(); - currentNode = newNode; - } - - SWTBotUtil.delay(1000); - SWTBotUtil.waitForJobs(); - final String expectedTitle = elementPath.toString(); - - final IEditorPart iep[] = new IEditorPart[1]; - UIThreadRunnable.syncExec(new VoidResult() { - @Override - public void run() { - IEditorReference[] ieds = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getEditorReferences(); - assertNotNull(ieds); - iep[0] = null; - for (IEditorReference ied : ieds) { - if (ied.getTitle().equals(expectedTitle)) { - iep[0] = ied.getEditor(true); - break; - } - } - } - }); - assertNotNull(iep[0]); - return (TmfEventsEditor) iep[0]; - } - - private static String getFullNodeName(final SWTBotTreeItem treeItem, String prefix) { - List nodes = treeItem.getNodes(); - String nodeName = ""; - for (String node : nodes) { - if (node.startsWith(prefix)) { - nodeName = node; - } - } - return nodeName; - } - - /** - * Finishes the wizard - */ - protected void importFinish() { - SWTBotShell shell = fBot.activeShell(); - final SWTBotButton finishButton = fBot.button("Finish"); - finishButton.click(); - fBot.waitUntil(Conditions.shellCloses(shell)); - SWTBotUtil.waitForJobs(); - } - - /** - * Gets the project Name - * @return the project name - */ - protected abstract String getProjectName(); - - // --------------------------------------------- - // Helpers for testing views - // --------------------------------------------- - - /** - * Verifies the properties view for a given view part - * - * @param vp - * a view part - */ - protected void testPropertyView(IViewPart vp) { - PropertySheet pv = (PropertySheet) vp; - assertNotNull(pv); - } - - /** - * Verifies the Histogram View - * @param vp - * the view part - * @param tmfEd - * the events editor - */ - protected void testHistogramView(IViewPart vp, final TmfEventsEditor tmfEd) { - final CtfTmfEvent desiredEvent1 = getEvent(100); - UIThreadRunnable.syncExec(new VoidResult() { - @Override - public void run() { - tmfEd.setFocus(); - tmfEd.selectionChanged(new SelectionChangedEvent(tmfEd, new StructuredSelection(desiredEvent1))); - } - }); - - SWTBotUtil.waitForJobs(); - SWTBotUtil.delay(1000); - - final CtfTmfEvent desiredEvent2 = getEvent(10000); - SWTBotView hvBot = fBot.viewById(HistogramView.ID); - List hvTools = hvBot.getToolbarButtons(); - for (SWTBotToolbarButton hvTool : hvTools) { - if (hvTool.getToolTipText().toLowerCase().contains("lost")) { - hvTool.click(); - } - } - HistogramView hv = (HistogramView) vp; - final TmfTimeSynchSignal signal = new TmfTimeSynchSignal(hv, desiredEvent1.getTimestamp()); - final TmfTimeSynchSignal signal2 = new TmfTimeSynchSignal(hv, desiredEvent2.getTimestamp()); - hv.updateTimeRange(100000); - SWTBotUtil.waitForJobs(); - hv.currentTimeUpdated(signal); - hv.broadcast(signal); - SWTBotUtil.waitForJobs(); - SWTBotUtil.delay(1000); - - hv.updateTimeRange(1000000000); - SWTBotUtil.waitForJobs(); - hv.currentTimeUpdated(signal2); - hv.broadcast(signal2); - SWTBotUtil.waitForJobs(); - SWTBotUtil.delay(1000); - assertNotNull(hv); - } - - /** - * Verifies the statistics view - * @param vp - * the view part - */ - protected void testStatisticsView(IViewPart vp) { - TmfStatisticsView sv = (TmfStatisticsView) vp; - assertNotNull(sv); - } - - // --------------------------------------------- - // Trace helpers - // --------------------------------------------- - - /** - * Gets an event at a given rank - * @param rank - * a rank - * @return the event at given rank - */ - protected CtfTmfEvent getEvent(int rank) { - try (CtfTmfTrace trace = fTrace.getTrace()) { - ITmfContext ctx = trace.seekEvent(0); - for (int i = 0; i < rank; i++) { - trace.getNext(ctx); - } - return trace.getNext(ctx); - } - } - - /** - * Gets a view part based on view title - * @param viewTile - * a view title - * @return the view part - */ - protected IViewPart getViewPart(final String viewTile) { - final IViewPart[] vps = new IViewPart[1]; - UIThreadRunnable.syncExec(new VoidResult() { - @Override - public void run() { - IViewReference[] viewRefs = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getViewReferences(); - for (IViewReference viewRef : viewRefs) { - IViewPart vp = viewRef.getView(true); - if (vp.getTitle().equals(viewTile)) { - vps[0] = vp; - return; - } - } - } - }); - - return vps[0]; - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ctf/ui/swtbot/tests/AllTests.java b/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ctf/ui/swtbot/tests/AllTests.java deleted file mode 100644 index bb3df9e919..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ctf/ui/swtbot/tests/AllTests.java +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.ui.swtbot.tests; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * SWTBot test suite for tmf.ui - * - * @author Matthew Khouzam - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - ImportAndReadSmokeTest.class, - StandardImportAndReadSmokeTest.class -}) -public class AllTests { -} diff --git a/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ctf/ui/swtbot/tests/ImportAndReadSmokeTest.java b/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ctf/ui/swtbot/tests/ImportAndReadSmokeTest.java deleted file mode 100644 index 717eb5a9dd..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ctf/ui/swtbot/tests/ImportAndReadSmokeTest.java +++ /dev/null @@ -1,142 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Marc-Andre Laperle - * Bernd Hufmann - Extracted functionality to class AbstractImportAndReadSmokeTest - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.ui.swtbot.tests; - -import static org.junit.Assert.assertNotNull; - -import org.eclipse.core.runtime.Path; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.wizard.IWizardPage; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace.BatchImportTraceWizard; -import org.eclipse.linuxtools.tmf.ui.editors.TmfEventsEditor; -import org.eclipse.linuxtools.tmf.ui.swtbot.tests.SWTBotUtil; -import org.eclipse.linuxtools.tmf.ui.swtbot.tests.conditions.ConditionHelpers; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; -import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; -import org.eclipse.swtbot.swt.finder.results.VoidResult; -import org.eclipse.swtbot.swt.finder.waits.Conditions; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * SWTBot Smoke test. base for other tests - * - * @author Matthew Khouzam - */ -@RunWith(SWTBotJunit4ClassRunner.class) -public class ImportAndReadSmokeTest extends AbstractImportAndReadSmokeTest { - - private static final String TRACE_PROJECT_NAME = "test"; - - /** - * Main test case - */ - @Test - public void test() { - createProject(); - - batchImportOpenWizard(); - batchImportSelecTraceType(); - batchImportAddDirectory(); - batchImportSelectTrace(); - importFinish(); - - TmfEventsEditor tmfEd = openEditor(new Path(TRACE_NAME)); - - testHistogramView(getViewPart("Histogram"), tmfEd); - testPropertyView(getViewPart("Properties")); - testStatisticsView(getViewPart("Statistics")); - fBot.closeAllEditors(); - - SWTBotUtil.deleteProject(getProjectName(), fBot); - } - - private static void batchImportOpenWizard() { - fWizard = new BatchImportTraceWizard(); - - UIThreadRunnable.asyncExec(new VoidResult() { - @Override - public void run() { - final IWorkbench workbench = PlatformUI.getWorkbench(); - // Fire the Import Trace Wizard - if (workbench != null) { - final IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow(); - Shell shell = activeWorkbenchWindow.getShell(); - assertNotNull(shell); - ((BatchImportTraceWizard) fWizard).init(PlatformUI.getWorkbench(), StructuredSelection.EMPTY); - WizardDialog dialog = new WizardDialog(shell, fWizard); - dialog.open(); - } - } - }); - - fBot.waitUntil(ConditionHelpers.isWizardReady(fWizard)); - } - - private static void batchImportSelecTraceType() { - final SWTBotTree tree = fBot.tree(); - final String ctfId = "Common Trace Format"; - fBot.waitUntil(ConditionHelpers.IsTreeNodeAvailable(ctfId, tree)); - fBot.waitUntil(ConditionHelpers.IsTreeChildNodeAvailable(TRACE_TYPE_NAME, tree.getTreeItem(ctfId))); - tree.getTreeItem(ctfId).getNode(TRACE_TYPE_NAME).check(); - batchImportClickNext(); - } - - private static void batchImportAddDirectory() { - UIThreadRunnable.syncExec(new VoidResult() { - @Override - public void run() { - ((BatchImportTraceWizard) fWizard).addFileToScan(fTrace.getPath()); - } - }); - final SWTBotButton removeButton = fBot.button("Remove"); - fBot.waitUntil(Conditions.widgetIsEnabled(removeButton)); - removeButton.click(); - fBot.waitUntil(Conditions.tableHasRows(fBot.table(), 1)); - - batchImportClickNext(); - } - - private static void batchImportSelectTrace() { - SWTBotTree tree = fBot.tree(); - fBot.waitUntil(Conditions.widgetIsEnabled(tree)); - final SWTBotTreeItem genericCtfTreeItem = tree.getTreeItem(TRACE_TYPE_NAME); - fBot.waitUntil(Conditions.widgetIsEnabled(genericCtfTreeItem)); - genericCtfTreeItem.expand(); - genericCtfTreeItem.check(); - batchImportClickNext(); - } - - private static void batchImportClickNext() { - IWizardPage currentPage = fWizard.getContainer().getCurrentPage(); - IWizardPage desiredPage = fWizard.getNextPage(currentPage); - SWTBotButton nextButton = fBot.button("Next >"); - nextButton.click(); - fBot.waitUntil(ConditionHelpers.isWizardOnPage(fWizard, desiredPage)); - } - - @Override - protected String getProjectName() { - return TRACE_PROJECT_NAME; - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ctf/ui/swtbot/tests/StandardImportAndReadSmokeTest.java b/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ctf/ui/swtbot/tests/StandardImportAndReadSmokeTest.java deleted file mode 100644 index 3b245d3ed2..0000000000 --- a/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ctf/ui/swtbot/tests/StandardImportAndReadSmokeTest.java +++ /dev/null @@ -1,315 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ctf.ui.swtbot.tests; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Path; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace.ImportTraceWizard; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace.ImportTraceWizardPage; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace.Messages; -import org.eclipse.linuxtools.tmf.ui.editors.TmfEventsEditor; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTracesFolder; -import org.eclipse.linuxtools.tmf.ui.swtbot.tests.SWTBotUtil; -import org.eclipse.linuxtools.tmf.ui.swtbot.tests.conditions.ConditionHelpers; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; -import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; -import org.eclipse.swtbot.swt.finder.results.VoidResult; -import org.eclipse.swtbot.swt.finder.waits.Conditions; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotCheckBox; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotCombo; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotRadio; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotText; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * SWTBot Smoke test using ImportTraceWizard. - * - * @author Bernd Hufmann - */ -@RunWith(SWTBotJunit4ClassRunner.class) -public class StandardImportAndReadSmokeTest extends AbstractImportAndReadSmokeTest { - - private static final String TRACE_FOLDER_PARENT_PATH = fTrace.getPath() + File.separator + ".." + File.separator + ".." + File.separator; - private static final String TRACE_ARCHIVE_PATH = TRACE_FOLDER_PARENT_PATH + "synctraces.tar.gz"; - private static final String TRACE_PROJECT_NAME = "Tracing"; - - /** - * Test import from directory - */ - @Test - public void testImportFromDirectory() { - testImport(0, false, false); - } - - /** - * Test import from directory, create links - */ - @Test - public void testImportFromDirectoryLinks() { - testImport(ImportTraceWizardPage.OPTION_CREATE_LINKS_IN_WORKSPACE, false, false); - } - - /** - * Test import from directory, preserve folder structure - */ - @Test - public void testImportFromDirectoryPreserveFolder() { - testImport(ImportTraceWizardPage.OPTION_PRESERVE_FOLDER_STRUCTURE, false, false); - } - - /** - * Test import from directory, create links, preserve folder structure - */ - @Test - public void testImportFromDirectoryLinksPreserveFolder() { - int options = ImportTraceWizardPage.OPTION_CREATE_LINKS_IN_WORKSPACE | ImportTraceWizardPage.OPTION_PRESERVE_FOLDER_STRUCTURE; - testImport(options, false, false); - } - - /** - * Test import from directory, overwrite all - */ - @Test - public void testImportFromDirectoryOverwrite() { - testImport(0, false, false); - testImport(ImportTraceWizardPage.OPTION_OVERWRITE_EXISTING_RESOURCES, false, false); - } - - /** - * Test import from archive - */ - @Test - public void testImportFromArchive() { - testImport(ImportTraceWizardPage.OPTION_PRESERVE_FOLDER_STRUCTURE, true, true); - } - - /** - * Test import from directory, preserve folder structure - */ - @Test - public void testImportFromArchivePreserveFolder() { - testImport(ImportTraceWizardPage.OPTION_PRESERVE_FOLDER_STRUCTURE, false, true); - } - - /** - * Test import from directory, overwrite all - */ - @Test - public void testImportFromArchiveOverwrite() { - testImport(0, false, true); - testImport(ImportTraceWizardPage.OPTION_OVERWRITE_EXISTING_RESOURCES, false, true); - } - - private void testImport(int options, boolean testViews, boolean fromArchive) { - createProject(); - - importOpenWizard(); - if (fromArchive) { - importAddArchive(); - } else { - importAddDirectory(); - } - - setOptions(options, ImportTraceWizardPage.TRACE_TYPE_AUTO_DETECT); - importFinish(); - - checkOptions(options); - TmfEventsEditor tmfEd = openEditor(getTraceElementPath(options)); - if (testViews) { - testViews(tmfEd); - } - - fBot.closeAllEditors(); - - SWTBotUtil.deleteProject(getProjectName(), fBot); - } - - private void testViews(TmfEventsEditor editor) { - testHistogramView(getViewPart("Histogram"), editor); - testPropertyView(getViewPart("Properties")); - testStatisticsView(getViewPart("Statistics")); - } - - private static void importOpenWizard() { - fWizard = new ImportTraceWizard(); - - UIThreadRunnable.asyncExec(new VoidResult() { - @Override - public void run() { - final IWorkbench workbench = PlatformUI.getWorkbench(); - // Fire the Import Trace Wizard - if (workbench != null) { - final IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow(); - Shell shell = activeWorkbenchWindow.getShell(); - assertNotNull(shell); - ((ImportTraceWizard) fWizard).init(PlatformUI.getWorkbench(), StructuredSelection.EMPTY); - WizardDialog dialog = new WizardDialog(shell, fWizard); - dialog.open(); - } - } - }); - - fBot.waitUntil(ConditionHelpers.isWizardReady(fWizard)); - } - - private static void importAddDirectory() { - SWTBotRadio button = fBot.radio("Select roo&t directory:"); - button.click(); - - SWTBotCombo sourceCombo = fBot.comboBox(); - File traceFolderParent = new File(TRACE_FOLDER_PARENT_PATH); - sourceCombo.setText(traceFolderParent.getAbsolutePath()); - - SWTBotText text = fBot.text(); - text.setFocus(); - - fBot.activeShell(); - SWTBotTree tree = fBot.tree(); - fBot.waitUntil(Conditions.widgetIsEnabled(tree)); - - final String traceFolderParentName = new Path(traceFolderParent.getAbsolutePath()).lastSegment(); - fBot.waitUntil(ConditionHelpers.IsTreeNodeAvailable(traceFolderParentName, tree)); - final SWTBotTreeItem folderParentNode = tree.getTreeItem(traceFolderParentName); - folderParentNode.expand(); - - fBot.waitUntil(ConditionHelpers.IsTreeChildNodeAvailable(TRACE_FOLDER, folderParentNode)); - final SWTBotTreeItem folderNode = folderParentNode.getNode(TRACE_FOLDER); - folderNode.check(); - } - - private static void importAddArchive() { - SWTBotRadio button = fBot.radio("Select &archive file:"); - button.click(); - - SWTBotCombo sourceCombo = fBot.comboBox(1); - - sourceCombo.setText(new File(TRACE_ARCHIVE_PATH).getAbsolutePath()); - - SWTBotText text = fBot.text(); - text.setFocus(); - - SWTBotTree tree = fBot.tree(); - fBot.waitUntil(Conditions.widgetIsEnabled(tree)); - final SWTBotTreeItem genericCtfTreeItem = tree.getTreeItem("/"); - fBot.waitUntil(Conditions.widgetIsEnabled(genericCtfTreeItem)); - genericCtfTreeItem.check(); - - SWTBotCheckBox checkBox = fBot.checkBox(Messages.ImportTraceWizard_CreateLinksInWorkspace); - assertFalse(checkBox.isEnabled()); - } - - private static void setOptions(int optionFlags, String traceTypeName) { - SWTBotCheckBox checkBox = fBot.checkBox(Messages.ImportTraceWizard_CreateLinksInWorkspace); - if (checkBox.isEnabled()) { - if ((optionFlags & ImportTraceWizardPage.OPTION_CREATE_LINKS_IN_WORKSPACE) != 0) { - checkBox.select(); - } else { - checkBox.deselect(); - } - } - - checkBox = fBot.checkBox(Messages.ImportTraceWizard_PreserveFolderStructure); - if ((optionFlags & ImportTraceWizardPage.OPTION_PRESERVE_FOLDER_STRUCTURE) != 0) { - checkBox.select(); - } else { - checkBox.deselect(); - } - - checkBox = fBot.checkBox(Messages.ImportTraceWizard_ImportUnrecognized); - if ((optionFlags & ImportTraceWizardPage.OPTION_IMPORT_UNRECOGNIZED_TRACES) != 0) { - checkBox.select(); - } else { - checkBox.deselect(); - } - - checkBox = fBot.checkBox(Messages.ImportTraceWizard_OverwriteExistingTrace); - if ((optionFlags & ImportTraceWizardPage.OPTION_OVERWRITE_EXISTING_RESOURCES) != 0) { - checkBox.select(); - } else { - checkBox.deselect(); - } - - SWTBotCombo comboBox = fBot.comboBoxWithLabel(Messages.ImportTraceWizard_TraceType); - if (traceTypeName != null && !traceTypeName.isEmpty()) { - comboBox.setSelection(traceTypeName); - } else { - comboBox.setSelection(ImportTraceWizardPage.TRACE_TYPE_AUTO_DETECT); - } - } - - private static void checkOptions(int optionFlags) { - IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(TRACE_PROJECT_NAME); - assertTrue(project.exists()); - TmfProjectElement tmfProject = TmfProjectRegistry.getProject(project, true); - assertNotNull(tmfProject); - TmfTraceFolder tracesFolder = tmfProject.getTracesFolder(); - assertNotNull(tracesFolder); - List traces = tracesFolder.getTraces(); - assertFalse(traces.isEmpty()); - Collections.sort(traces, new Comparator() { - @Override - public int compare(TmfTraceElement arg0, TmfTraceElement arg1) { - return arg0.getElementPath().compareTo(arg1.getElementPath()); - } - }); - - TmfTraceElement tmfTraceElement = traces.get(0); - IResource traceResource = tmfTraceElement.getResource(); - - assertEquals((optionFlags & ImportTraceWizardPage.OPTION_CREATE_LINKS_IN_WORKSPACE) != 0, traceResource.isLinked()); - - // i.e. /Tracing/Traces - IPath expectedPath = Path.ROOT.append(new Path(TRACE_PROJECT_NAME)).append(TmfTracesFolder.TRACES_FOLDER_NAME); - expectedPath = expectedPath.append(getTraceElementPath(optionFlags)); - assertEquals(expectedPath, traceResource.getFullPath()); - } - - private static IPath getTraceElementPath(int optionFlags) { - IPath traceElementPath = new Path(""); - if ((optionFlags & ImportTraceWizardPage.OPTION_PRESERVE_FOLDER_STRUCTURE) != 0) { - traceElementPath = traceElementPath.append(TRACE_FOLDER); - } - return traceElementPath.append(TRACE_NAME); - } - - @Override - protected String getProjectName() { - return TRACE_PROJECT_NAME; - } -} diff --git a/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/AbstractImportAndReadSmokeTest.java b/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/AbstractImportAndReadSmokeTest.java new file mode 100644 index 0000000000..465304f059 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/AbstractImportAndReadSmokeTest.java @@ -0,0 +1,336 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * (Extracted from ImportAndReadSmokeTest.java) + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assume.assumeTrue; + +import java.util.List; + +import org.apache.log4j.Logger; +import org.apache.log4j.varia.NullAppender; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; +import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; +import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; +import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; +import org.eclipse.swtbot.swt.finder.results.VoidResult; +import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences; +import org.eclipse.swtbot.swt.finder.waits.Conditions; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotText; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarButton; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfEvent; +import org.eclipse.tracecompass.tmf.ctf.core.CtfTmfTrace; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; +import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTracesFolder; +import org.eclipse.tracecompass.tmf.ui.swtbot.tests.SWTBotUtil; +import org.eclipse.tracecompass.tmf.ui.swtbot.tests.conditions.ConditionHelpers; +import org.eclipse.tracecompass.tmf.ui.views.histogram.HistogramView; +import org.eclipse.tracecompass.tmf.ui.views.statistics.TmfStatisticsView; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.views.properties.PropertySheet; +import org.junit.BeforeClass; +import org.junit.runner.RunWith; + +/** + * Abstract SWTBot Smoke test class. + * + * @author Matthew Khouzam + * @author Bernd Hufmann + */ +@RunWith(SWTBotJunit4ClassRunner.class) +public abstract class AbstractImportAndReadSmokeTest { + + /** Trace name */ + protected static final String TRACE_NAME = "scp_dest"; + /** Trace folder */ + protected static final String TRACE_FOLDER = "synctraces"; + /** Trace type name for generic CTF traces */ + protected static final String TRACE_TYPE_NAME = "Generic CTF Trace"; + /** A Generic CTF Trace*/ + protected static final CtfTmfTestTrace fTrace = CtfTmfTestTrace.SYNC_DEST; + /** SWT BOT workbench reference */ + protected static SWTWorkbenchBot fBot; + /** Wizard to use */ + protected static Wizard fWizard; + + /** The Log4j logger instance. */ + protected static final Logger fLogger = Logger.getRootLogger(); + + /** Test Class setup */ + @BeforeClass + public static void init() { + assumeTrue(fTrace.exists()); + SWTBotUtil.failIfUIThread(); + + /* set up for swtbot */ + SWTBotPreferences.TIMEOUT = 50000; /* 50 second timeout */ + fLogger.addAppender(new NullAppender()); + fBot = new SWTWorkbenchBot(); + + SWTBotUtil.closeView("welcome", fBot); + + SWTBotUtil.switchToTracingPerspective(); + /* finish waiting for eclipse to load */ + SWTBotUtil.waitForJobs(); + } + + /** + * Creates a tracing projects + */ + protected void createProject() { + SWTBotUtil.focusMainWindow(fBot.shells()); + fBot.menu("File").menu("New").menu("Project...").click(); + + fBot.shell("New Project").setFocus(); + SWTBotTree tree = fBot.tree(); + assertNotNull(tree); + final String tracingKey = "Tracing"; + fBot.waitUntil(ConditionHelpers.IsTreeNodeAvailable(tracingKey, tree)); + final SWTBotTreeItem tracingNode = tree.expandNode(tracingKey); + + tracingNode.select(); + final String projectKey = "Tracing Project"; + fBot.waitUntil(ConditionHelpers.IsTreeChildNodeAvailable(projectKey, tracingNode)); + final SWTBotTreeItem tracingProject = tracingNode.getNode(projectKey); + assertNotNull(tracingProject); + + tracingProject.select(); + tracingProject.click(); + + SWTBotButton nextButton = fBot.button("Next >"); + fBot.waitUntil(Conditions.widgetIsEnabled(nextButton)); + nextButton.click(); + fBot.shell("Tracing Project").setFocus(); + + final SWTBotText text = fBot.text(); + text.setText(getProjectName()); + + fBot.button("Finish").click(); + SWTBotUtil.waitForJobs(); + } + + /** + * Opens and get the TmfEventsEditor + * + * @param elementPath + * the trace element path (relative to Traces folder) + * @return TmfEventsEditor + */ + protected TmfEventsEditor openEditor(IPath elementPath) { + final SWTBotView projectExplorerBot = fBot.viewById(IPageLayout.ID_PROJECT_EXPLORER); + projectExplorerBot.setFocus(); + + final SWTBotTree tree = fBot.tree(); + final SWTBotTreeItem treeItem = tree.getTreeItem(getProjectName()); + treeItem.expand(); + + String nodeName = getFullNodeName(treeItem, TmfTracesFolder.TRACES_FOLDER_NAME); + fBot.waitUntil(ConditionHelpers.IsTreeChildNodeAvailable(nodeName, treeItem)); + SWTBotTreeItem tracesNode = treeItem.getNode(nodeName); + tracesNode.expand(); + + SWTBotTreeItem currentNode = tracesNode; + for (String segment : elementPath.segments()) { + String fullNodeName = getFullNodeName(currentNode, segment); + fBot.waitUntil(ConditionHelpers.IsTreeChildNodeAvailable(fullNodeName, currentNode)); + SWTBotTreeItem newNode = currentNode.getNode(fullNodeName); + newNode.select(); + newNode.doubleClick(); + currentNode = newNode; + } + + SWTBotUtil.delay(1000); + SWTBotUtil.waitForJobs(); + final String expectedTitle = elementPath.toString(); + + final IEditorPart iep[] = new IEditorPart[1]; + UIThreadRunnable.syncExec(new VoidResult() { + @Override + public void run() { + IEditorReference[] ieds = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getEditorReferences(); + assertNotNull(ieds); + iep[0] = null; + for (IEditorReference ied : ieds) { + if (ied.getTitle().equals(expectedTitle)) { + iep[0] = ied.getEditor(true); + break; + } + } + } + }); + assertNotNull(iep[0]); + return (TmfEventsEditor) iep[0]; + } + + private static String getFullNodeName(final SWTBotTreeItem treeItem, String prefix) { + List nodes = treeItem.getNodes(); + String nodeName = ""; + for (String node : nodes) { + if (node.startsWith(prefix)) { + nodeName = node; + } + } + return nodeName; + } + + /** + * Finishes the wizard + */ + protected void importFinish() { + SWTBotShell shell = fBot.activeShell(); + final SWTBotButton finishButton = fBot.button("Finish"); + finishButton.click(); + fBot.waitUntil(Conditions.shellCloses(shell)); + SWTBotUtil.waitForJobs(); + } + + /** + * Gets the project Name + * @return the project name + */ + protected abstract String getProjectName(); + + // --------------------------------------------- + // Helpers for testing views + // --------------------------------------------- + + /** + * Verifies the properties view for a given view part + * + * @param vp + * a view part + */ + protected void testPropertyView(IViewPart vp) { + PropertySheet pv = (PropertySheet) vp; + assertNotNull(pv); + } + + /** + * Verifies the Histogram View + * @param vp + * the view part + * @param tmfEd + * the events editor + */ + protected void testHistogramView(IViewPart vp, final TmfEventsEditor tmfEd) { + final CtfTmfEvent desiredEvent1 = getEvent(100); + UIThreadRunnable.syncExec(new VoidResult() { + @Override + public void run() { + tmfEd.setFocus(); + tmfEd.selectionChanged(new SelectionChangedEvent(tmfEd, new StructuredSelection(desiredEvent1))); + } + }); + + SWTBotUtil.waitForJobs(); + SWTBotUtil.delay(1000); + + final CtfTmfEvent desiredEvent2 = getEvent(10000); + SWTBotView hvBot = fBot.viewById(HistogramView.ID); + List hvTools = hvBot.getToolbarButtons(); + for (SWTBotToolbarButton hvTool : hvTools) { + if (hvTool.getToolTipText().toLowerCase().contains("lost")) { + hvTool.click(); + } + } + HistogramView hv = (HistogramView) vp; + final TmfTimeSynchSignal signal = new TmfTimeSynchSignal(hv, desiredEvent1.getTimestamp()); + final TmfTimeSynchSignal signal2 = new TmfTimeSynchSignal(hv, desiredEvent2.getTimestamp()); + hv.updateTimeRange(100000); + SWTBotUtil.waitForJobs(); + hv.currentTimeUpdated(signal); + hv.broadcast(signal); + SWTBotUtil.waitForJobs(); + SWTBotUtil.delay(1000); + + hv.updateTimeRange(1000000000); + SWTBotUtil.waitForJobs(); + hv.currentTimeUpdated(signal2); + hv.broadcast(signal2); + SWTBotUtil.waitForJobs(); + SWTBotUtil.delay(1000); + assertNotNull(hv); + } + + /** + * Verifies the statistics view + * @param vp + * the view part + */ + protected void testStatisticsView(IViewPart vp) { + TmfStatisticsView sv = (TmfStatisticsView) vp; + assertNotNull(sv); + } + + // --------------------------------------------- + // Trace helpers + // --------------------------------------------- + + /** + * Gets an event at a given rank + * @param rank + * a rank + * @return the event at given rank + */ + protected CtfTmfEvent getEvent(int rank) { + try (CtfTmfTrace trace = fTrace.getTrace()) { + ITmfContext ctx = trace.seekEvent(0); + for (int i = 0; i < rank; i++) { + trace.getNext(ctx); + } + return trace.getNext(ctx); + } + } + + /** + * Gets a view part based on view title + * @param viewTile + * a view title + * @return the view part + */ + protected IViewPart getViewPart(final String viewTile) { + final IViewPart[] vps = new IViewPart[1]; + UIThreadRunnable.syncExec(new VoidResult() { + @Override + public void run() { + IViewReference[] viewRefs = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getViewReferences(); + for (IViewReference viewRef : viewRefs) { + IViewPart vp = viewRef.getView(true); + if (vp.getTitle().equals(viewTile)) { + vps[0] = vp; + return; + } + } + } + }); + + return vps[0]; + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/AllTests.java b/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/AllTests.java new file mode 100644 index 0000000000..b5c0f462ac --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/AllTests.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * SWTBot test suite for tmf.ui + * + * @author Matthew Khouzam + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + ImportAndReadSmokeTest.class, + StandardImportAndReadSmokeTest.class +}) +public class AllTests { +} diff --git a/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/ImportAndReadSmokeTest.java b/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/ImportAndReadSmokeTest.java new file mode 100644 index 0000000000..ab062c12c7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/ImportAndReadSmokeTest.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Marc-Andre Laperle + * Bernd Hufmann - Extracted functionality to class AbstractImportAndReadSmokeTest + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests; + +import static org.junit.Assert.assertNotNull; + +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; +import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; +import org.eclipse.swtbot.swt.finder.results.VoidResult; +import org.eclipse.swtbot.swt.finder.waits.Conditions; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace.BatchImportTraceWizard; +import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor; +import org.eclipse.tracecompass.tmf.ui.swtbot.tests.SWTBotUtil; +import org.eclipse.tracecompass.tmf.ui.swtbot.tests.conditions.ConditionHelpers; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * SWTBot Smoke test. base for other tests + * + * @author Matthew Khouzam + */ +@RunWith(SWTBotJunit4ClassRunner.class) +public class ImportAndReadSmokeTest extends AbstractImportAndReadSmokeTest { + + private static final String TRACE_PROJECT_NAME = "test"; + + /** + * Main test case + */ + @Test + public void test() { + createProject(); + + batchImportOpenWizard(); + batchImportSelecTraceType(); + batchImportAddDirectory(); + batchImportSelectTrace(); + importFinish(); + + TmfEventsEditor tmfEd = openEditor(new Path(TRACE_NAME)); + + testHistogramView(getViewPart("Histogram"), tmfEd); + testPropertyView(getViewPart("Properties")); + testStatisticsView(getViewPart("Statistics")); + fBot.closeAllEditors(); + + SWTBotUtil.deleteProject(getProjectName(), fBot); + } + + private static void batchImportOpenWizard() { + fWizard = new BatchImportTraceWizard(); + + UIThreadRunnable.asyncExec(new VoidResult() { + @Override + public void run() { + final IWorkbench workbench = PlatformUI.getWorkbench(); + // Fire the Import Trace Wizard + if (workbench != null) { + final IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow(); + Shell shell = activeWorkbenchWindow.getShell(); + assertNotNull(shell); + ((BatchImportTraceWizard) fWizard).init(PlatformUI.getWorkbench(), StructuredSelection.EMPTY); + WizardDialog dialog = new WizardDialog(shell, fWizard); + dialog.open(); + } + } + }); + + fBot.waitUntil(ConditionHelpers.isWizardReady(fWizard)); + } + + private static void batchImportSelecTraceType() { + final SWTBotTree tree = fBot.tree(); + final String ctfId = "Common Trace Format"; + fBot.waitUntil(ConditionHelpers.IsTreeNodeAvailable(ctfId, tree)); + fBot.waitUntil(ConditionHelpers.IsTreeChildNodeAvailable(TRACE_TYPE_NAME, tree.getTreeItem(ctfId))); + tree.getTreeItem(ctfId).getNode(TRACE_TYPE_NAME).check(); + batchImportClickNext(); + } + + private static void batchImportAddDirectory() { + UIThreadRunnable.syncExec(new VoidResult() { + @Override + public void run() { + ((BatchImportTraceWizard) fWizard).addFileToScan(fTrace.getPath()); + } + }); + final SWTBotButton removeButton = fBot.button("Remove"); + fBot.waitUntil(Conditions.widgetIsEnabled(removeButton)); + removeButton.click(); + fBot.waitUntil(Conditions.tableHasRows(fBot.table(), 1)); + + batchImportClickNext(); + } + + private static void batchImportSelectTrace() { + SWTBotTree tree = fBot.tree(); + fBot.waitUntil(Conditions.widgetIsEnabled(tree)); + final SWTBotTreeItem genericCtfTreeItem = tree.getTreeItem(TRACE_TYPE_NAME); + fBot.waitUntil(Conditions.widgetIsEnabled(genericCtfTreeItem)); + genericCtfTreeItem.expand(); + genericCtfTreeItem.check(); + batchImportClickNext(); + } + + private static void batchImportClickNext() { + IWizardPage currentPage = fWizard.getContainer().getCurrentPage(); + IWizardPage desiredPage = fWizard.getNextPage(currentPage); + SWTBotButton nextButton = fBot.button("Next >"); + nextButton.click(); + fBot.waitUntil(ConditionHelpers.isWizardOnPage(fWizard, desiredPage)); + } + + @Override + protected String getProjectName() { + return TRACE_PROJECT_NAME; + } +} diff --git a/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/StandardImportAndReadSmokeTest.java b/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/StandardImportAndReadSmokeTest.java new file mode 100644 index 0000000000..3697752d1b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/StandardImportAndReadSmokeTest.java @@ -0,0 +1,315 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; +import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; +import org.eclipse.swtbot.swt.finder.results.VoidResult; +import org.eclipse.swtbot.swt.finder.waits.Conditions; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotCheckBox; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotCombo; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotRadio; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotText; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace.ImportTraceWizard; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace.ImportTraceWizardPage; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace.Messages; +import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTracesFolder; +import org.eclipse.tracecompass.tmf.ui.swtbot.tests.SWTBotUtil; +import org.eclipse.tracecompass.tmf.ui.swtbot.tests.conditions.ConditionHelpers; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * SWTBot Smoke test using ImportTraceWizard. + * + * @author Bernd Hufmann + */ +@RunWith(SWTBotJunit4ClassRunner.class) +public class StandardImportAndReadSmokeTest extends AbstractImportAndReadSmokeTest { + + private static final String TRACE_FOLDER_PARENT_PATH = fTrace.getPath() + File.separator + ".." + File.separator + ".." + File.separator; + private static final String TRACE_ARCHIVE_PATH = TRACE_FOLDER_PARENT_PATH + "synctraces.tar.gz"; + private static final String TRACE_PROJECT_NAME = "Tracing"; + + /** + * Test import from directory + */ + @Test + public void testImportFromDirectory() { + testImport(0, false, false); + } + + /** + * Test import from directory, create links + */ + @Test + public void testImportFromDirectoryLinks() { + testImport(ImportTraceWizardPage.OPTION_CREATE_LINKS_IN_WORKSPACE, false, false); + } + + /** + * Test import from directory, preserve folder structure + */ + @Test + public void testImportFromDirectoryPreserveFolder() { + testImport(ImportTraceWizardPage.OPTION_PRESERVE_FOLDER_STRUCTURE, false, false); + } + + /** + * Test import from directory, create links, preserve folder structure + */ + @Test + public void testImportFromDirectoryLinksPreserveFolder() { + int options = ImportTraceWizardPage.OPTION_CREATE_LINKS_IN_WORKSPACE | ImportTraceWizardPage.OPTION_PRESERVE_FOLDER_STRUCTURE; + testImport(options, false, false); + } + + /** + * Test import from directory, overwrite all + */ + @Test + public void testImportFromDirectoryOverwrite() { + testImport(0, false, false); + testImport(ImportTraceWizardPage.OPTION_OVERWRITE_EXISTING_RESOURCES, false, false); + } + + /** + * Test import from archive + */ + @Test + public void testImportFromArchive() { + testImport(ImportTraceWizardPage.OPTION_PRESERVE_FOLDER_STRUCTURE, true, true); + } + + /** + * Test import from directory, preserve folder structure + */ + @Test + public void testImportFromArchivePreserveFolder() { + testImport(ImportTraceWizardPage.OPTION_PRESERVE_FOLDER_STRUCTURE, false, true); + } + + /** + * Test import from directory, overwrite all + */ + @Test + public void testImportFromArchiveOverwrite() { + testImport(0, false, true); + testImport(ImportTraceWizardPage.OPTION_OVERWRITE_EXISTING_RESOURCES, false, true); + } + + private void testImport(int options, boolean testViews, boolean fromArchive) { + createProject(); + + importOpenWizard(); + if (fromArchive) { + importAddArchive(); + } else { + importAddDirectory(); + } + + setOptions(options, ImportTraceWizardPage.TRACE_TYPE_AUTO_DETECT); + importFinish(); + + checkOptions(options); + TmfEventsEditor tmfEd = openEditor(getTraceElementPath(options)); + if (testViews) { + testViews(tmfEd); + } + + fBot.closeAllEditors(); + + SWTBotUtil.deleteProject(getProjectName(), fBot); + } + + private void testViews(TmfEventsEditor editor) { + testHistogramView(getViewPart("Histogram"), editor); + testPropertyView(getViewPart("Properties")); + testStatisticsView(getViewPart("Statistics")); + } + + private static void importOpenWizard() { + fWizard = new ImportTraceWizard(); + + UIThreadRunnable.asyncExec(new VoidResult() { + @Override + public void run() { + final IWorkbench workbench = PlatformUI.getWorkbench(); + // Fire the Import Trace Wizard + if (workbench != null) { + final IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow(); + Shell shell = activeWorkbenchWindow.getShell(); + assertNotNull(shell); + ((ImportTraceWizard) fWizard).init(PlatformUI.getWorkbench(), StructuredSelection.EMPTY); + WizardDialog dialog = new WizardDialog(shell, fWizard); + dialog.open(); + } + } + }); + + fBot.waitUntil(ConditionHelpers.isWizardReady(fWizard)); + } + + private static void importAddDirectory() { + SWTBotRadio button = fBot.radio("Select roo&t directory:"); + button.click(); + + SWTBotCombo sourceCombo = fBot.comboBox(); + File traceFolderParent = new File(TRACE_FOLDER_PARENT_PATH); + sourceCombo.setText(traceFolderParent.getAbsolutePath()); + + SWTBotText text = fBot.text(); + text.setFocus(); + + fBot.activeShell(); + SWTBotTree tree = fBot.tree(); + fBot.waitUntil(Conditions.widgetIsEnabled(tree)); + + final String traceFolderParentName = new Path(traceFolderParent.getAbsolutePath()).lastSegment(); + fBot.waitUntil(ConditionHelpers.IsTreeNodeAvailable(traceFolderParentName, tree)); + final SWTBotTreeItem folderParentNode = tree.getTreeItem(traceFolderParentName); + folderParentNode.expand(); + + fBot.waitUntil(ConditionHelpers.IsTreeChildNodeAvailable(TRACE_FOLDER, folderParentNode)); + final SWTBotTreeItem folderNode = folderParentNode.getNode(TRACE_FOLDER); + folderNode.check(); + } + + private static void importAddArchive() { + SWTBotRadio button = fBot.radio("Select &archive file:"); + button.click(); + + SWTBotCombo sourceCombo = fBot.comboBox(1); + + sourceCombo.setText(new File(TRACE_ARCHIVE_PATH).getAbsolutePath()); + + SWTBotText text = fBot.text(); + text.setFocus(); + + SWTBotTree tree = fBot.tree(); + fBot.waitUntil(Conditions.widgetIsEnabled(tree)); + final SWTBotTreeItem genericCtfTreeItem = tree.getTreeItem("/"); + fBot.waitUntil(Conditions.widgetIsEnabled(genericCtfTreeItem)); + genericCtfTreeItem.check(); + + SWTBotCheckBox checkBox = fBot.checkBox(Messages.ImportTraceWizard_CreateLinksInWorkspace); + assertFalse(checkBox.isEnabled()); + } + + private static void setOptions(int optionFlags, String traceTypeName) { + SWTBotCheckBox checkBox = fBot.checkBox(Messages.ImportTraceWizard_CreateLinksInWorkspace); + if (checkBox.isEnabled()) { + if ((optionFlags & ImportTraceWizardPage.OPTION_CREATE_LINKS_IN_WORKSPACE) != 0) { + checkBox.select(); + } else { + checkBox.deselect(); + } + } + + checkBox = fBot.checkBox(Messages.ImportTraceWizard_PreserveFolderStructure); + if ((optionFlags & ImportTraceWizardPage.OPTION_PRESERVE_FOLDER_STRUCTURE) != 0) { + checkBox.select(); + } else { + checkBox.deselect(); + } + + checkBox = fBot.checkBox(Messages.ImportTraceWizard_ImportUnrecognized); + if ((optionFlags & ImportTraceWizardPage.OPTION_IMPORT_UNRECOGNIZED_TRACES) != 0) { + checkBox.select(); + } else { + checkBox.deselect(); + } + + checkBox = fBot.checkBox(Messages.ImportTraceWizard_OverwriteExistingTrace); + if ((optionFlags & ImportTraceWizardPage.OPTION_OVERWRITE_EXISTING_RESOURCES) != 0) { + checkBox.select(); + } else { + checkBox.deselect(); + } + + SWTBotCombo comboBox = fBot.comboBoxWithLabel(Messages.ImportTraceWizard_TraceType); + if (traceTypeName != null && !traceTypeName.isEmpty()) { + comboBox.setSelection(traceTypeName); + } else { + comboBox.setSelection(ImportTraceWizardPage.TRACE_TYPE_AUTO_DETECT); + } + } + + private static void checkOptions(int optionFlags) { + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(TRACE_PROJECT_NAME); + assertTrue(project.exists()); + TmfProjectElement tmfProject = TmfProjectRegistry.getProject(project, true); + assertNotNull(tmfProject); + TmfTraceFolder tracesFolder = tmfProject.getTracesFolder(); + assertNotNull(tracesFolder); + List traces = tracesFolder.getTraces(); + assertFalse(traces.isEmpty()); + Collections.sort(traces, new Comparator() { + @Override + public int compare(TmfTraceElement arg0, TmfTraceElement arg1) { + return arg0.getElementPath().compareTo(arg1.getElementPath()); + } + }); + + TmfTraceElement tmfTraceElement = traces.get(0); + IResource traceResource = tmfTraceElement.getResource(); + + assertEquals((optionFlags & ImportTraceWizardPage.OPTION_CREATE_LINKS_IN_WORKSPACE) != 0, traceResource.isLinked()); + + // i.e. /Tracing/Traces + IPath expectedPath = Path.ROOT.append(new Path(TRACE_PROJECT_NAME)).append(TmfTracesFolder.TRACES_FOLDER_NAME); + expectedPath = expectedPath.append(getTraceElementPath(optionFlags)); + assertEquals(expectedPath, traceResource.getFullPath()); + } + + private static IPath getTraceElementPath(int optionFlags) { + IPath traceElementPath = new Path(""); + if ((optionFlags & ImportTraceWizardPage.OPTION_PRESERVE_FOLDER_STRUCTURE) != 0) { + traceElementPath = traceElementPath.append(TRACE_FOLDER); + } + return traceElementPath.append(TRACE_NAME); + } + + @Override + protected String getProjectName() { + return TRACE_PROJECT_NAME; + } +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/META-INF/MANIFEST.MF b/org.eclipse.tracecompass.tmf.pcap.core.tests/META-INF/MANIFEST.MF index 1655d7ac64..af530c0023 100644 --- a/org.eclipse.tracecompass.tmf.pcap.core.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.tracecompass.tmf.pcap.core.tests/META-INF/MANIFEST.MF @@ -16,9 +16,9 @@ Require-Bundle: org.junit;bundle-version="4.0.0", org.eclipse.tracecompass.tmf.core.tests;bundle-version="3.1.0", org.eclipse.tracecompass.tmf.pcap.core;bundle-version="1.0.0" Import-Package: com.google.common.collect -Export-Package: org.eclipse.linuxtools.tmf.pcap.core.tests, - org.eclipse.linuxtools.tmf.pcap.core.tests.analysis;x-internal:=true, - org.eclipse.linuxtools.tmf.pcap.core.tests.event;x-internal:=true, - org.eclipse.linuxtools.tmf.pcap.core.tests.shared;x-friends:="org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests", - org.eclipse.linuxtools.tmf.pcap.core.tests.stubs;x-internal:=true, - org.eclipse.linuxtools.tmf.pcap.core.tests.trace;x-internal:=true +Export-Package: org.eclipse.tracecompass.tmf.pcap.core.tests, + org.eclipse.tracecompass.tmf.pcap.core.tests.analysis;x-internal:=true, + org.eclipse.tracecompass.tmf.pcap.core.tests.event;x-internal:=true, + org.eclipse.tracecompass.tmf.pcap.core.tests.shared;x-friends:="org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests", + org.eclipse.tracecompass.tmf.pcap.core.tests.stubs;x-internal:=true, + org.eclipse.tracecompass.tmf.pcap.core.tests.trace;x-internal:=true diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/shared/org/eclipse/linuxtools/tmf/pcap/core/tests/shared/PcapTmfTestTrace.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/shared/org/eclipse/linuxtools/tmf/pcap/core/tests/shared/PcapTmfTestTrace.java deleted file mode 100644 index ad0f499473..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core.tests/shared/org/eclipse/linuxtools/tmf/pcap/core/tests/shared/PcapTmfTestTrace.java +++ /dev/null @@ -1,122 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.pcap.core.tests.shared; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.internal.tmf.pcap.core.event.PcapEvent; -import org.eclipse.linuxtools.internal.tmf.pcap.core.trace.PcapTrace; -import org.eclipse.linuxtools.pcap.core.tests.shared.PcapTestTrace; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.pcap.core.tests.stubs.PcapTmfTraceStub; - -/** - * Available Pcap TMF test traces. Kind-of-extends {@link PcapTestTrace}. - * - * To run tests using these, you first need to run the "get-traces.[xml|sh]" - * script located under lttng/org.eclipse.linuxtools.pcap.core.tests/rsc/ . - * - * @author Vincent Perot - */ -@NonNullByDefault -public enum PcapTmfTestTrace { - /** A bad pcap file. */ - BAD_PCAPFILE, - - /** A Valid Pcap that is empty. */ - EMPTY_PCAP, - - /** A Pcap that mostly contains TCP packets. */ - MOSTLY_TCP, - - /** A Pcap that mostly contains UDP packets. */ - MOSTLY_UDP, - - /** A big-endian trace that contains two packets. */ - SHORT_BIG_ENDIAN, - - /** A little-endian trace that contains two packets. */ - SHORT_LITTLE_ENDIAN, - - /** A trace used for benchmarking. */ - BENCHMARK_TRACE, - - /** A Kernel trace directory. */ - KERNEL_DIRECTORY, - - /** A Kernel trace file. */ - KERNEL_TRACE; - - private final String fPath; - private @Nullable PcapTmfTraceStub fTrace = null; - - private PcapTmfTestTrace() { - @SuppressWarnings("null") - @NonNull String path = PcapTestTrace.valueOf(this.name()).getPath().toString(); - fPath = path; - } - - /** - * @return The path of this trace - */ - public String getPath() { - return fPath; - } - - /** - * Return a PcapTmfTraceStub object of this test trace. It will be already - * initTrace()'ed. - * - * Make sure you call {@link #exists()} before calling this! - * - * After being used by unit tests, traces must be properly disposed of by - * calling the {@link PcapTmfTestTrace#dispose()} method. - * - * @return A PcapTmfTrace reference to this trace - */ - public synchronized PcapTrace getTrace() { - PcapTmfTraceStub trace = fTrace; - if (trace != null) { - trace.dispose(); - } - trace = new PcapTmfTraceStub(); - try { - trace.initTrace(null, fPath, PcapEvent.class); - } catch (TmfTraceException e) { - /* Should not happen if tracesExist() passed */ - throw new RuntimeException(e); - } - fTrace = trace; - return trace; - } - - /** - * Check if the trace actually exists on disk or not. - * - * @return If the trace is present - */ - public boolean exists() { - return PcapTestTrace.valueOf(this.name()).exists(); - } - - /** - * Dispose of the trace - */ - public void dispose() { - if (fTrace != null) { - fTrace.dispose(); - fTrace = null; - } - } -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/shared/org/eclipse/tracecompass/tmf/pcap/core/tests/shared/PcapTmfTestTrace.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/shared/org/eclipse/tracecompass/tmf/pcap/core/tests/shared/PcapTmfTestTrace.java new file mode 100644 index 0000000000..e1cfe70a98 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core.tests/shared/org/eclipse/tracecompass/tmf/pcap/core/tests/shared/PcapTmfTestTrace.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.pcap.core.tests.shared; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.linuxtools.pcap.core.tests.shared.PcapTestTrace; +import org.eclipse.tracecompass.internal.tmf.pcap.core.event.PcapEvent; +import org.eclipse.tracecompass.internal.tmf.pcap.core.trace.PcapTrace; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.pcap.core.tests.stubs.PcapTmfTraceStub; + +/** + * Available Pcap TMF test traces. Kind-of-extends {@link PcapTestTrace}. + * + * To run tests using these, you first need to run the "get-traces.[xml|sh]" + * script located under lttng/org.eclipse.linuxtools.pcap.core.tests/rsc/ . + * + * @author Vincent Perot + */ +@NonNullByDefault +public enum PcapTmfTestTrace { + /** A bad pcap file. */ + BAD_PCAPFILE, + + /** A Valid Pcap that is empty. */ + EMPTY_PCAP, + + /** A Pcap that mostly contains TCP packets. */ + MOSTLY_TCP, + + /** A Pcap that mostly contains UDP packets. */ + MOSTLY_UDP, + + /** A big-endian trace that contains two packets. */ + SHORT_BIG_ENDIAN, + + /** A little-endian trace that contains two packets. */ + SHORT_LITTLE_ENDIAN, + + /** A trace used for benchmarking. */ + BENCHMARK_TRACE, + + /** A Kernel trace directory. */ + KERNEL_DIRECTORY, + + /** A Kernel trace file. */ + KERNEL_TRACE; + + private final String fPath; + private @Nullable PcapTmfTraceStub fTrace = null; + + private PcapTmfTestTrace() { + @SuppressWarnings("null") + @NonNull String path = PcapTestTrace.valueOf(this.name()).getPath().toString(); + fPath = path; + } + + /** + * @return The path of this trace + */ + public String getPath() { + return fPath; + } + + /** + * Return a PcapTmfTraceStub object of this test trace. It will be already + * initTrace()'ed. + * + * Make sure you call {@link #exists()} before calling this! + * + * After being used by unit tests, traces must be properly disposed of by + * calling the {@link PcapTmfTestTrace#dispose()} method. + * + * @return A PcapTmfTrace reference to this trace + */ + public synchronized PcapTrace getTrace() { + PcapTmfTraceStub trace = fTrace; + if (trace != null) { + trace.dispose(); + } + trace = new PcapTmfTraceStub(); + try { + trace.initTrace(null, fPath, PcapEvent.class); + } catch (TmfTraceException e) { + /* Should not happen if tracesExist() passed */ + throw new RuntimeException(e); + } + fTrace = trace; + return trace; + } + + /** + * Check if the trace actually exists on disk or not. + * + * @return If the trace is present + */ + public boolean exists() { + return PcapTestTrace.valueOf(this.name()).exists(); + } + + /** + * Dispose of the trace + */ + public void dispose() { + if (fTrace != null) { + fTrace.dispose(); + fTrace = null; + } + } +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/AllTmfPcapCoreTests.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/AllTmfPcapCoreTests.java deleted file mode 100644 index ca551a0208..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/AllTmfPcapCoreTests.java +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial generation with CodePro tools - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.pcap.core.tests; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * The class AllTmfPcapCoreTests builds a suite to run all the - * tests. - * - * @author Vincent Perot - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - org.eclipse.linuxtools.tmf.pcap.core.tests.analysis.AllTests.class, - org.eclipse.linuxtools.tmf.pcap.core.tests.event.AllTests.class, - org.eclipse.linuxtools.tmf.pcap.core.tests.trace.AllTests.class -}) -public class AllTmfPcapCoreTests { - -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/analysis/AllTests.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/analysis/AllTests.java deleted file mode 100644 index 99aa8010a5..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/analysis/AllTests.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.pcap.core.tests.analysis; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Analysis test suite - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - StreamListAnalysisTest.class -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/analysis/StreamListAnalysisTest.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/analysis/StreamListAnalysisTest.java deleted file mode 100644 index 6acf92615a..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/analysis/StreamListAnalysisTest.java +++ /dev/null @@ -1,126 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.pcap.core.tests.analysis; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeTrue; - -import org.eclipse.linuxtools.internal.tmf.pcap.core.analysis.StreamListAnalysis; -import org.eclipse.linuxtools.internal.tmf.pcap.core.event.TmfPacketStreamBuilder; -import org.eclipse.linuxtools.internal.tmf.pcap.core.protocol.TmfPcapProtocol; -import org.eclipse.linuxtools.internal.tmf.pcap.core.trace.PcapTrace; -import org.eclipse.linuxtools.pcap.core.tests.shared.PcapTestTrace; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.junit.Test; - -/** - * JUnit that test the StreamListAnalysis class. - * - * @author Vincent Perot - */ -public class StreamListAnalysisTest { - - /** - * Method that tests the constructor. - */ - @Test - public void constructorTest() { - try (StreamListAnalysis analysis = new StreamListAnalysis();) { - analysis.setId(StreamListAnalysis.ID); - for (TmfPcapProtocol protocol : TmfPcapProtocol.values()) { - if (protocol.supportsStream()) { - assertNotNull(analysis.getBuilder(protocol)); - } - } - assertFalse(analysis.isFinished()); - } - } - - /** - * Method that tests canExecute(). - * - * @throws TmfTraceException - * Thrown when the trace cannot be initialized. Fails the test. - */ - @Test - public void canExecuteTest() throws TmfTraceException { - PcapTestTrace trace = PcapTestTrace.MOSTLY_TCP; - assumeTrue(trace.exists()); - String path = trace.getPath().toString(); - try (PcapTrace pcapTrace = new PcapTrace(); - StreamListAnalysis analysis = new StreamListAnalysis();) { - analysis.setId(StreamListAnalysis.ID); - pcapTrace.initTrace(null, path, null); - assertTrue(analysis.canExecute(pcapTrace)); - } - } - - /** - * Method that execute the analysis and verify the results. - * - * @throws TmfAnalysisException - * Thrown when an analysis error occurs during the setup or - * execution. Fails the test. - * @throws TmfTraceException - * Thrown when the trace cannot be initialized. Fails the test. - */ - @Test - public void executeAnalysisTest() throws TmfAnalysisException, TmfTraceException { - PcapTestTrace trace = PcapTestTrace.MOSTLY_TCP; - assumeTrue(trace.exists()); - String path = trace.getPath().toString(); - try (PcapTrace pcapTrace = new PcapTrace(); - StreamListAnalysis analysis = new StreamListAnalysis();) { - pcapTrace.initTrace(null, path, null); - analysis.setId(StreamListAnalysis.ID); - analysis.setTrace(pcapTrace); - analysis.schedule(); - analysis.waitForCompletion(); - - // Verify that builders are not empty. - TmfPacketStreamBuilder builder = analysis.getBuilder(TmfPcapProtocol.ETHERNET_II); - if (builder == null) { - fail("The PacketStreamBuilder is null!"); - return; - } - assertEquals(1, builder.getNbStreams()); - - builder = analysis.getBuilder(TmfPcapProtocol.IPV4); - if (builder == null) { - fail("The PacketStreamBuilder is null!"); - return; - } - assertEquals(3, builder.getNbStreams()); - - builder = analysis.getBuilder(TmfPcapProtocol.TCP); - if (builder == null) { - fail("The PacketStreamBuilder is null!"); - return; - } - assertEquals(2, builder.getNbStreams()); - - builder = analysis.getBuilder(TmfPcapProtocol.UDP); - if (builder == null) { - fail("The PacketStreamBuilder is null!"); - return; - } - assertEquals(1, builder.getNbStreams()); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/event/AllTests.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/event/AllTests.java deleted file mode 100644 index 90768d05fe..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/event/AllTests.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.pcap.core.tests.event; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Event and Event Field test suite - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - PcapEventTest.class, - PcapEventFieldTest.class -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/event/PcapEventFieldTest.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/event/PcapEventFieldTest.java deleted file mode 100644 index 67f624f95b..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/event/PcapEventFieldTest.java +++ /dev/null @@ -1,243 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.pcap.core.tests.event; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeTrue; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.pcap.core.packet.BadPacketException; -import org.eclipse.linuxtools.internal.pcap.core.packet.Packet; -import org.eclipse.linuxtools.internal.pcap.core.protocol.ipv4.IPv4Packet; -import org.eclipse.linuxtools.internal.pcap.core.trace.BadPcapFileException; -import org.eclipse.linuxtools.internal.pcap.core.trace.PcapFile; -import org.eclipse.linuxtools.internal.tmf.pcap.core.event.PcapEventField; -import org.eclipse.linuxtools.internal.tmf.pcap.core.event.PcapRootEventField; -import org.eclipse.linuxtools.pcap.core.tests.shared.PcapTestTrace; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * JUnit that test the PcapEventField class. - * - * @author Vincent Perot - */ -public class PcapEventFieldTest { - - private static final @NonNull String EMPTY_STRING = ""; - private static PcapEventField fRegularField; - private static PcapRootEventField fRootField; - - /** - * Initialize the Packet and the Event. - * - * @throws BadPcapFileException - * Thrown when the pcap file is erroneous. - * @throws IOException - * Thrown when an IO error occurs. - * @throws BadPacketException - * Thrown when the packet is erroneous. - */ - @BeforeClass - public static void setUp() throws IOException, BadPcapFileException, BadPacketException { - ByteBuffer bb = ByteBuffer.allocate(25); - bb.order(ByteOrder.BIG_ENDIAN); - - // Version + IHL - bb.put((byte) 0x46); - - // DSCP + ECN - bb.put((byte) 0x9A); - - // Total length - this is randomly chosen so that we verify that the - // packet handles wrong total length. - bb.put((byte) 0x00); - bb.put((byte) 0xFF); - - // Identification - bb.put((byte) 0x0F); - bb.put((byte) 0xF0); - - // Flags + Fragment Offset - bb.put((byte) 0x1E); - bb.put((byte) 0xE1); - - // Time to live - bb.put((byte) 0xA0); - - // Protocol - Unknown - bb.put((byte) 0xFE); - - // Header checksum - chosen randomly - bb.put((byte) 0x33); - bb.put((byte) 0x44); - - // Source IP - 4 bytes - bb.put((byte) 192); - bb.put((byte) 168); - bb.put((byte) 1); - bb.put((byte) 0); - - // Destination IP - 4 bytes - bb.put((byte) 193); - bb.put((byte) 169); - bb.put((byte) 2); - bb.put((byte) 1); - - // Options - 4 bytes - bb.put((byte) 0xA2); - bb.put((byte) 0x56); - bb.put((byte) 0xA2); - bb.put((byte) 0x56); - - // Payload - 1 byte - bb.put((byte) 0xA6); - - bb.flip(); - - PcapTestTrace trace = PcapTestTrace.MOSTLY_TCP; - assumeTrue(trace.exists()); - try (PcapFile dummy = new PcapFile(trace.getPath())) { - IPv4Packet packet = new IPv4Packet(dummy, null, bb); - ITmfEventField[] fieldArray = generatePacketFields(packet); - fRegularField = new PcapEventField("Regular Field", EMPTY_STRING, fieldArray, packet); - fRootField = new PcapRootEventField(EMPTY_STRING, fieldArray, packet); - } - - } - - /** - * Method that tests the copy constructor. - */ - @Test - public void copyConstructorTest() { - PcapEventField oldField = fRegularField; - if (oldField == null) { - fail("The field has not been initialized!"); - return; - } - PcapEventField newField = new PcapEventField(oldField); - assertEquals(fRegularField.hashCode(), newField.hashCode()); - assertEquals(fRegularField, newField); - } - - /** - * Method that tests a standard field value request. - */ - @Test - public void regularFieldValueRequestTest() { - ITmfEventField field = fRootField.getField("Internet Protocol Version 4"); - if (field == null) { - fail("The field is null!"); - return; - } - - ITmfEventField subfield = field.getField("Source IP Address"); - if (subfield == null) { - fail("The subfield is null!"); - return; - } - - String string = subfield.getValue().toString(); - assertEquals("192.168.1.0", string); - } - - /** - * Method that tests a custom field value request. - */ - @Test - public void customFieldValueRequestTest() { - ITmfEventField field = fRootField.getField(":protocol:"); - if (field == null) { - fail("The field is null!"); - return; - } - String string = field.getValue().toString(); - assertEquals("IPV4", string); - - field = fRootField.getField(":packetsource:"); - if (field == null) { - fail("The field is null!"); - return; - } - string = field.getValue().toString(); - assertEquals("192.168.1.0", string); - - field = fRootField.getField(":packetdestination:"); - if (field == null) { - fail("The field is null!"); - return; - } - string = field.getValue().toString(); - assertEquals("193.169.2.1", string); - - } - - /** - * Method that teststhe toString() method for a non-root field. - */ - @Test - public void regularToStringTest() { - assertEquals("Src: 192.168.1.0 , Dst: 193.169.2.1", fRegularField.toString()); - } - - /** - * Method that teststhe toString() method for a root field. - */ - @Test - public void rootToStringTest() { - assertEquals("192.168.1.0 > 193.169.2.1 Id=4080 Len=1", fRootField.toString()); - } - - // Convenience method - private static ITmfEventField[] generatePacketFields(Packet packet) { - List fieldList = new ArrayList<>(); - List subfieldList = new ArrayList<>(); - Packet localPacket = packet; - - while (localPacket != null) { - subfieldList.clear(); - for (Map.Entry entry : localPacket.getFields().entrySet()) { - - @SuppressWarnings("null") - @NonNull - String key = entry.getKey(); - - @SuppressWarnings("null") - @NonNull - String value = entry.getValue(); - subfieldList.add(new TmfEventField(key, value, null)); - } - ITmfEventField[] subfieldArray = subfieldList.toArray(new ITmfEventField[subfieldList.size()]); - fieldList.add(new PcapEventField(localPacket.getProtocol().getName(), EMPTY_STRING, subfieldArray, localPacket)); - localPacket = localPacket.getChildPacket(); - } - - ITmfEventField[] fieldArray = fieldList.toArray(new ITmfEventField[fieldList.size()]); - if (fieldArray == null) { - return new ITmfEventField[0]; - } - return fieldArray; - } - -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/event/PcapEventTest.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/event/PcapEventTest.java deleted file mode 100644 index ab90499111..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/event/PcapEventTest.java +++ /dev/null @@ -1,153 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.pcap.core.tests.event; - -import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.eclipse.linuxtools.internal.pcap.core.trace.BadPcapFileException; -import org.eclipse.linuxtools.internal.pcap.core.trace.PcapFile; -import org.eclipse.linuxtools.internal.tmf.pcap.core.event.PcapEvent; -import org.eclipse.linuxtools.internal.tmf.pcap.core.protocol.TmfPcapProtocol; -import org.eclipse.linuxtools.internal.tmf.pcap.core.trace.PcapTrace; -import org.eclipse.linuxtools.pcap.core.tests.shared.PcapTestTrace; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.trace.TmfContext; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.google.common.collect.ImmutableList; - -/** - * JUnit that test the PcapEvent class. - * - * @author Vincent Perot - */ -public class PcapEventTest { - - private static PcapEvent fEvent; - private static List fProtocolList; - - /** - * Initialize the Packet and the EventField. - * - * @throws BadPcapFileException - * Thrown when the pcap file is erroneous. - * @throws IOException - * Thrown when an IO error occurs. - * @throws TmfTraceException - * Thrown when the trace is not valid. - */ - @BeforeClass - public static void setUp() throws IOException, BadPcapFileException, TmfTraceException { - - PcapTestTrace trace = PcapTestTrace.MOSTLY_TCP; - assumeTrue(trace.exists()); - try (PcapFile pcap = new PcapFile(trace.getPath()); - PcapTrace pcapTrace = new PcapTrace();) { - pcapTrace.initTrace(null, trace.getPath().toString(), PcapEvent.class); - fEvent = pcapTrace.parseEvent(new TmfContext(new TmfLongLocation(3), 3)); - } - - // Initialize protocol list. - List list = new ArrayList<>(); - list.add(TmfPcapProtocol.PCAP); - list.add(TmfPcapProtocol.ETHERNET_II); - list.add(TmfPcapProtocol.IPV4); - list.add(TmfPcapProtocol.TCP); - list.add(TmfPcapProtocol.UNKNOWN); - fProtocolList = ImmutableList.copyOf(list); - } - - /** - * Method that tests getProtocols of PcapEvent. - */ - @Test - public void getProtocolsTest() { - assertEquals(fProtocolList, fEvent.getProtocols()); - } - - /** - * Method that tests getMostEncapsulatedProtocol of PcapEvent. - */ - @Test - public void getMostEncapsulatedProtocolTest() { - assertEquals(TmfPcapProtocol.TCP, fEvent.getMostEncapsulatedProtocol()); - } - - /** - * Method that tests getFields of PcapEvent. - */ - @Test - public void getFieldsTest() { - Map map = fEvent.getFields(TmfPcapProtocol.IPV4); - if (map == null) { - fail("getFieldsTest() failed because map is null!"); - return; - } - assertEquals("145.254.160.237", map.get("Source IP Address")); - } - - /** - * Method that tests getPayload of PcapEvent. - */ - @Test - public void getPayloadTest() { - ByteBuffer bb = fEvent.getPayload(TmfPcapProtocol.TCP); - if (bb == null) { - fail("getPayloadTest() failed because bb is null!"); - return; - } - assertEquals((byte) 0x47, bb.get()); - } - - /** - * Method that tests getSourceEndpoint of PcapEvent. - */ - @Test - public void getSourceEndpointTest() { - assertEquals("00:00:01:00:00:00/145.254.160.237/3372", fEvent.getSourceEndpoint(TmfPcapProtocol.TCP)); - } - - /** - * Method that tests getDestinationEndpointTest of PcapEvent. - */ - @Test - public void getDestinationEndpointTest() { - assertEquals("fe:ff:20:00:01:00", fEvent.getDestinationEndpoint(TmfPcapProtocol.ETHERNET_II)); - } - - /** - * Method that tests toString() of PcapEvent. - */ - @Test - public void toStringTest() { - assertEquals("3372 > 80 [ACK, PSH] Seq=951057940 Ack=290218380 Len=20", fEvent.toString()); - } - - /** - * Method that tests toString(protocol) of PcapEvent. - */ - @Test - public void toStringAtSpecificProtocolTest() { - assertEquals("Src: 145.254.160.237 , Dst: 65.208.228.223", fEvent.toString(TmfPcapProtocol.IPV4)); - } - -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/trace/AllTests.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/trace/AllTests.java deleted file mode 100644 index a17b490e96..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/trace/AllTests.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.pcap.core.tests.trace; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Pcap trace test suite - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - PcapTraceTest.class -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/trace/PcapTraceTest.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/trace/PcapTraceTest.java deleted file mode 100644 index d1bc1f948a..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/linuxtools/tmf/pcap/core/tests/trace/PcapTraceTest.java +++ /dev/null @@ -1,307 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.pcap.core.tests.trace; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.linuxtools.internal.tmf.pcap.core.event.PcapEvent; -import org.eclipse.linuxtools.internal.tmf.pcap.core.trace.PcapTrace; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.signal.TmfEndSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation; -import org.eclipse.linuxtools.tmf.pcap.core.tests.shared.PcapTmfTestTrace; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * JUnit that test the PcapTrace class. - * - * @author Vincent Perot - */ -public class PcapTraceTest { - - private static final PcapTmfTestTrace TEST_TRACE = PcapTmfTestTrace.MOSTLY_TCP; - - private PcapTrace fFixture; - - /** - * Perform pre-test initialization. - * - * @throws TmfTraceException - * If the test trace is not found - */ - @Before - public void setUp() throws TmfTraceException { - assumeTrue(TEST_TRACE.exists()); - fFixture = new PcapTrace(); - fFixture.initTrace((IResource) null, TEST_TRACE.getPath(), PcapEvent.class); - } - - /** - * Perform post-test clean-up. - */ - @After - public void tearDown() { - if (fFixture != null) { - fFixture.dispose(); - } - } - - /** - * Run the PcapTrace() constructor test. - */ - @Test - public void testPcapTrace() { - try (PcapTrace result = new PcapTrace();) { - assertNotNull(result); - assertEquals(1000, result.getCacheSize()); - assertEquals(0L, result.getNbEvents()); - assertEquals(0L, result.getStreamingInterval()); - assertNull(result.getResource()); - assertNull(result.getType()); - } - } - - /** - * Test the parseEvent() method - */ - @Test - public void testParseEvent() { - ITmfContext ctx = fFixture.seekEvent(0); - fFixture.getNext(ctx); - PcapEvent event = fFixture.parseEvent(ctx); - assertNotNull(event); - } - - /** - * Run the void broadcast(TmfSignal) method test. - */ - @Test - public void testBroadcast() { - TmfSignal signal = new TmfEndSynchSignal(1); - fFixture.broadcast(signal); - } - - /** - * Run the void dispose() method test. - */ - @Test - public void testClose() { - try (PcapTrace emptyFixture = new PcapTrace();) { - } - } - - /** - * Run the int getCacheSize() method test. - */ - @Test - public void testGetCacheSize() { - try (PcapTrace emptyFixture = new PcapTrace();) { - int result = emptyFixture.getCacheSize(); - assertEquals(1000, result); - } - } - - /** - * Run the ITmfLocation getCurrentLocation() method test. - */ - @Test - public void testGetCurrentLocation() { - TmfLongLocation result = (TmfLongLocation) fFixture.getCurrentLocation(); - assertEquals(new TmfLongLocation(0), result); - } - - /** - * Test the seekEvent() method with a null location. - */ - @Test - public void testSeekEventLoc_null() { - TmfLongLocation loc = null; - fFixture.seekEvent(loc); - assertNotNull(fFixture); - } - - /** - * Test the seekEvent() method with a normal location. - */ - @Test - public void testSeekEventLoc_normal() { - TmfLongLocation loc = new TmfLongLocation(3L); - fFixture.seekEvent(loc); - assertNotNull(fFixture); - } - - /** - * Run the ITmfTimestamp getEndTime() method test. - */ - @Test - public void testGetEndTime() { - ITmfTimestamp result = fFixture.getEndTime(); - assertNotNull(result); - } - - /** - * Test the {@link PcapTrace#getEventType()} method. - */ - @Test - public void testGetEventType() { - Class result = fFixture.getEventType(); - assertNotNull(result); - assertEquals(PcapEvent.class, result); - } - - /** - * Run the double getLocationRatio(ITmfLocation) method test. - */ - @Test - public void testGetLocationRatio() { - TmfLongLocation location = new TmfLongLocation(20L); - double result = fFixture.getLocationRatio(location); - - assertEquals(20.0 / 43.0, result, 0.01); - } - - /** - * Run the String getName() method test. - */ - @Test - public void testGetName() { - String result = fFixture.getName(); - assertNotNull(result); - } - - /** - * Run the getTraceProperties() method test. - */ - @Test - public void testGetTraceProperties() { - int result = fFixture.getTraceProperties().size(); - assertEquals(6, result); - } - - /** - * Run the long getNbEvents() method test. - */ - @Test - public void testGetNbEvents() { - long result = fFixture.getNbEvents(); - assertEquals(0, result); - } - - /** - * Run the String getPath() method test. - */ - @Test - public void testGetPath() { - String result = fFixture.getPath(); - assertNotNull(result); - } - - /** - * Run the IResource getResource() method test. - */ - @Test - public void testGetResource() { - IResource result = fFixture.getResource(); - assertNull(result); - } - - /** - * Run the ITmfTimestamp getStartTime() method test. - */ - @Test - public void testGetStartTime() { - ITmfTimestamp result = fFixture.getStartTime(); - assertNotNull(result); - } - - /** - * Run the long getStreamingInterval() method test. - */ - @Test - public void testGetStreamingInterval() { - long result = fFixture.getStreamingInterval(); - assertEquals(0L, result); - } - - /** - * Run the TmfTimeRange getTimeRange() method test. - */ - @Test - public void testGetTimeRange() { - TmfTimeRange result = fFixture.getTimeRange(); - assertNotNull(result); - } - - /** - * Run the ITmfContext seekEvent(double) method test. - */ - @Test - public void testSeekEvent_ratio() { - double ratio = 21.0 / 43.0; - ITmfContext result = fFixture.seekEvent(ratio); - assertNotNull(result); - } - - /** - * Run the ITmfContext seekEvent(long) method test. - */ - @Test - public void testSeekEvent_rank() { - long rank = 1L; - ITmfContext result = fFixture.seekEvent(rank); - assertNotNull(result); - } - - /** - * Run the ITmfContext seekEvent(ITmfLocation) method test. - */ - @Test - public void testSeekEvent_location() { - TmfLongLocation pcapLocation = new TmfLongLocation(10L); - ITmfContext result = fFixture.seekEvent(pcapLocation); - assertNotNull(result); - } - - /** - * Run the boolean validate(IProject,String) method test. - */ - @Test - public void testValidate() { - IProject project = null; - IStatus result = fFixture.validate(project, TEST_TRACE.getPath()); - assertTrue(result.isOK()); - } - - /** - * Run the String getHostId() method test - */ - @Test - public void getSource() { - String a = fFixture.getHostId(); - assertEquals("mostlyTCP.pcap", a); - } - -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/AllTmfPcapCoreTests.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/AllTmfPcapCoreTests.java new file mode 100644 index 0000000000..4229e7a1f2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/AllTmfPcapCoreTests.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial generation with CodePro tools + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.pcap.core.tests; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * The class AllTmfPcapCoreTests builds a suite to run all the + * tests. + * + * @author Vincent Perot + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + org.eclipse.tracecompass.tmf.pcap.core.tests.analysis.AllTests.class, + org.eclipse.tracecompass.tmf.pcap.core.tests.event.AllTests.class, + org.eclipse.tracecompass.tmf.pcap.core.tests.trace.AllTests.class +}) +public class AllTmfPcapCoreTests { + +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/analysis/AllTests.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/analysis/AllTests.java new file mode 100644 index 0000000000..1e53578a33 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/analysis/AllTests.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.pcap.core.tests.analysis; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Analysis test suite + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + StreamListAnalysisTest.class +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/analysis/StreamListAnalysisTest.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/analysis/StreamListAnalysisTest.java new file mode 100644 index 0000000000..44d038cf7c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/analysis/StreamListAnalysisTest.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.pcap.core.tests.analysis; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + +import org.eclipse.linuxtools.pcap.core.tests.shared.PcapTestTrace; +import org.eclipse.tracecompass.internal.tmf.pcap.core.analysis.StreamListAnalysis; +import org.eclipse.tracecompass.internal.tmf.pcap.core.event.TmfPacketStreamBuilder; +import org.eclipse.tracecompass.internal.tmf.pcap.core.protocol.TmfPcapProtocol; +import org.eclipse.tracecompass.internal.tmf.pcap.core.trace.PcapTrace; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.junit.Test; + +/** + * JUnit that test the StreamListAnalysis class. + * + * @author Vincent Perot + */ +public class StreamListAnalysisTest { + + /** + * Method that tests the constructor. + */ + @Test + public void constructorTest() { + try (StreamListAnalysis analysis = new StreamListAnalysis();) { + analysis.setId(StreamListAnalysis.ID); + for (TmfPcapProtocol protocol : TmfPcapProtocol.values()) { + if (protocol.supportsStream()) { + assertNotNull(analysis.getBuilder(protocol)); + } + } + assertFalse(analysis.isFinished()); + } + } + + /** + * Method that tests canExecute(). + * + * @throws TmfTraceException + * Thrown when the trace cannot be initialized. Fails the test. + */ + @Test + public void canExecuteTest() throws TmfTraceException { + PcapTestTrace trace = PcapTestTrace.MOSTLY_TCP; + assumeTrue(trace.exists()); + String path = trace.getPath().toString(); + try (PcapTrace pcapTrace = new PcapTrace(); + StreamListAnalysis analysis = new StreamListAnalysis();) { + analysis.setId(StreamListAnalysis.ID); + pcapTrace.initTrace(null, path, null); + assertTrue(analysis.canExecute(pcapTrace)); + } + } + + /** + * Method that execute the analysis and verify the results. + * + * @throws TmfAnalysisException + * Thrown when an analysis error occurs during the setup or + * execution. Fails the test. + * @throws TmfTraceException + * Thrown when the trace cannot be initialized. Fails the test. + */ + @Test + public void executeAnalysisTest() throws TmfAnalysisException, TmfTraceException { + PcapTestTrace trace = PcapTestTrace.MOSTLY_TCP; + assumeTrue(trace.exists()); + String path = trace.getPath().toString(); + try (PcapTrace pcapTrace = new PcapTrace(); + StreamListAnalysis analysis = new StreamListAnalysis();) { + pcapTrace.initTrace(null, path, null); + analysis.setId(StreamListAnalysis.ID); + analysis.setTrace(pcapTrace); + analysis.schedule(); + analysis.waitForCompletion(); + + // Verify that builders are not empty. + TmfPacketStreamBuilder builder = analysis.getBuilder(TmfPcapProtocol.ETHERNET_II); + if (builder == null) { + fail("The PacketStreamBuilder is null!"); + return; + } + assertEquals(1, builder.getNbStreams()); + + builder = analysis.getBuilder(TmfPcapProtocol.IPV4); + if (builder == null) { + fail("The PacketStreamBuilder is null!"); + return; + } + assertEquals(3, builder.getNbStreams()); + + builder = analysis.getBuilder(TmfPcapProtocol.TCP); + if (builder == null) { + fail("The PacketStreamBuilder is null!"); + return; + } + assertEquals(2, builder.getNbStreams()); + + builder = analysis.getBuilder(TmfPcapProtocol.UDP); + if (builder == null) { + fail("The PacketStreamBuilder is null!"); + return; + } + assertEquals(1, builder.getNbStreams()); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/event/AllTests.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/event/AllTests.java new file mode 100644 index 0000000000..ffc4de3759 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/event/AllTests.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.pcap.core.tests.event; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Event and Event Field test suite + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + PcapEventTest.class, + PcapEventFieldTest.class +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/event/PcapEventFieldTest.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/event/PcapEventFieldTest.java new file mode 100644 index 0000000000..2e0021ae65 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/event/PcapEventFieldTest.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.pcap.core.tests.event; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.internal.pcap.core.packet.BadPacketException; +import org.eclipse.linuxtools.internal.pcap.core.packet.Packet; +import org.eclipse.linuxtools.internal.pcap.core.protocol.ipv4.IPv4Packet; +import org.eclipse.linuxtools.internal.pcap.core.trace.BadPcapFileException; +import org.eclipse.linuxtools.internal.pcap.core.trace.PcapFile; +import org.eclipse.linuxtools.pcap.core.tests.shared.PcapTestTrace; +import org.eclipse.tracecompass.internal.tmf.pcap.core.event.PcapEventField; +import org.eclipse.tracecompass.internal.tmf.pcap.core.event.PcapRootEventField; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * JUnit that test the PcapEventField class. + * + * @author Vincent Perot + */ +public class PcapEventFieldTest { + + private static final @NonNull String EMPTY_STRING = ""; + private static PcapEventField fRegularField; + private static PcapRootEventField fRootField; + + /** + * Initialize the Packet and the Event. + * + * @throws BadPcapFileException + * Thrown when the pcap file is erroneous. + * @throws IOException + * Thrown when an IO error occurs. + * @throws BadPacketException + * Thrown when the packet is erroneous. + */ + @BeforeClass + public static void setUp() throws IOException, BadPcapFileException, BadPacketException { + ByteBuffer bb = ByteBuffer.allocate(25); + bb.order(ByteOrder.BIG_ENDIAN); + + // Version + IHL + bb.put((byte) 0x46); + + // DSCP + ECN + bb.put((byte) 0x9A); + + // Total length - this is randomly chosen so that we verify that the + // packet handles wrong total length. + bb.put((byte) 0x00); + bb.put((byte) 0xFF); + + // Identification + bb.put((byte) 0x0F); + bb.put((byte) 0xF0); + + // Flags + Fragment Offset + bb.put((byte) 0x1E); + bb.put((byte) 0xE1); + + // Time to live + bb.put((byte) 0xA0); + + // Protocol - Unknown + bb.put((byte) 0xFE); + + // Header checksum - chosen randomly + bb.put((byte) 0x33); + bb.put((byte) 0x44); + + // Source IP - 4 bytes + bb.put((byte) 192); + bb.put((byte) 168); + bb.put((byte) 1); + bb.put((byte) 0); + + // Destination IP - 4 bytes + bb.put((byte) 193); + bb.put((byte) 169); + bb.put((byte) 2); + bb.put((byte) 1); + + // Options - 4 bytes + bb.put((byte) 0xA2); + bb.put((byte) 0x56); + bb.put((byte) 0xA2); + bb.put((byte) 0x56); + + // Payload - 1 byte + bb.put((byte) 0xA6); + + bb.flip(); + + PcapTestTrace trace = PcapTestTrace.MOSTLY_TCP; + assumeTrue(trace.exists()); + try (PcapFile dummy = new PcapFile(trace.getPath())) { + IPv4Packet packet = new IPv4Packet(dummy, null, bb); + ITmfEventField[] fieldArray = generatePacketFields(packet); + fRegularField = new PcapEventField("Regular Field", EMPTY_STRING, fieldArray, packet); + fRootField = new PcapRootEventField(EMPTY_STRING, fieldArray, packet); + } + + } + + /** + * Method that tests the copy constructor. + */ + @Test + public void copyConstructorTest() { + PcapEventField oldField = fRegularField; + if (oldField == null) { + fail("The field has not been initialized!"); + return; + } + PcapEventField newField = new PcapEventField(oldField); + assertEquals(fRegularField.hashCode(), newField.hashCode()); + assertEquals(fRegularField, newField); + } + + /** + * Method that tests a standard field value request. + */ + @Test + public void regularFieldValueRequestTest() { + ITmfEventField field = fRootField.getField("Internet Protocol Version 4"); + if (field == null) { + fail("The field is null!"); + return; + } + + ITmfEventField subfield = field.getField("Source IP Address"); + if (subfield == null) { + fail("The subfield is null!"); + return; + } + + String string = subfield.getValue().toString(); + assertEquals("192.168.1.0", string); + } + + /** + * Method that tests a custom field value request. + */ + @Test + public void customFieldValueRequestTest() { + ITmfEventField field = fRootField.getField(":protocol:"); + if (field == null) { + fail("The field is null!"); + return; + } + String string = field.getValue().toString(); + assertEquals("IPV4", string); + + field = fRootField.getField(":packetsource:"); + if (field == null) { + fail("The field is null!"); + return; + } + string = field.getValue().toString(); + assertEquals("192.168.1.0", string); + + field = fRootField.getField(":packetdestination:"); + if (field == null) { + fail("The field is null!"); + return; + } + string = field.getValue().toString(); + assertEquals("193.169.2.1", string); + + } + + /** + * Method that teststhe toString() method for a non-root field. + */ + @Test + public void regularToStringTest() { + assertEquals("Src: 192.168.1.0 , Dst: 193.169.2.1", fRegularField.toString()); + } + + /** + * Method that teststhe toString() method for a root field. + */ + @Test + public void rootToStringTest() { + assertEquals("192.168.1.0 > 193.169.2.1 Id=4080 Len=1", fRootField.toString()); + } + + // Convenience method + private static ITmfEventField[] generatePacketFields(Packet packet) { + List fieldList = new ArrayList<>(); + List subfieldList = new ArrayList<>(); + Packet localPacket = packet; + + while (localPacket != null) { + subfieldList.clear(); + for (Map.Entry entry : localPacket.getFields().entrySet()) { + + @SuppressWarnings("null") + @NonNull + String key = entry.getKey(); + + @SuppressWarnings("null") + @NonNull + String value = entry.getValue(); + subfieldList.add(new TmfEventField(key, value, null)); + } + ITmfEventField[] subfieldArray = subfieldList.toArray(new ITmfEventField[subfieldList.size()]); + fieldList.add(new PcapEventField(localPacket.getProtocol().getName(), EMPTY_STRING, subfieldArray, localPacket)); + localPacket = localPacket.getChildPacket(); + } + + ITmfEventField[] fieldArray = fieldList.toArray(new ITmfEventField[fieldList.size()]); + if (fieldArray == null) { + return new ITmfEventField[0]; + } + return fieldArray; + } + +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/event/PcapEventTest.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/event/PcapEventTest.java new file mode 100644 index 0000000000..aa458c4fd5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/event/PcapEventTest.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.pcap.core.tests.event; + +import static org.junit.Assert.*; +import static org.junit.Assume.assumeTrue; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.eclipse.linuxtools.internal.pcap.core.trace.BadPcapFileException; +import org.eclipse.linuxtools.internal.pcap.core.trace.PcapFile; +import org.eclipse.linuxtools.pcap.core.tests.shared.PcapTestTrace; +import org.eclipse.tracecompass.internal.tmf.pcap.core.event.PcapEvent; +import org.eclipse.tracecompass.internal.tmf.pcap.core.protocol.TmfPcapProtocol; +import org.eclipse.tracecompass.internal.tmf.pcap.core.trace.PcapTrace; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.trace.TmfContext; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.google.common.collect.ImmutableList; + +/** + * JUnit that test the PcapEvent class. + * + * @author Vincent Perot + */ +public class PcapEventTest { + + private static PcapEvent fEvent; + private static List fProtocolList; + + /** + * Initialize the Packet and the EventField. + * + * @throws BadPcapFileException + * Thrown when the pcap file is erroneous. + * @throws IOException + * Thrown when an IO error occurs. + * @throws TmfTraceException + * Thrown when the trace is not valid. + */ + @BeforeClass + public static void setUp() throws IOException, BadPcapFileException, TmfTraceException { + + PcapTestTrace trace = PcapTestTrace.MOSTLY_TCP; + assumeTrue(trace.exists()); + try (PcapFile pcap = new PcapFile(trace.getPath()); + PcapTrace pcapTrace = new PcapTrace();) { + pcapTrace.initTrace(null, trace.getPath().toString(), PcapEvent.class); + fEvent = pcapTrace.parseEvent(new TmfContext(new TmfLongLocation(3), 3)); + } + + // Initialize protocol list. + List list = new ArrayList<>(); + list.add(TmfPcapProtocol.PCAP); + list.add(TmfPcapProtocol.ETHERNET_II); + list.add(TmfPcapProtocol.IPV4); + list.add(TmfPcapProtocol.TCP); + list.add(TmfPcapProtocol.UNKNOWN); + fProtocolList = ImmutableList.copyOf(list); + } + + /** + * Method that tests getProtocols of PcapEvent. + */ + @Test + public void getProtocolsTest() { + assertEquals(fProtocolList, fEvent.getProtocols()); + } + + /** + * Method that tests getMostEncapsulatedProtocol of PcapEvent. + */ + @Test + public void getMostEncapsulatedProtocolTest() { + assertEquals(TmfPcapProtocol.TCP, fEvent.getMostEncapsulatedProtocol()); + } + + /** + * Method that tests getFields of PcapEvent. + */ + @Test + public void getFieldsTest() { + Map map = fEvent.getFields(TmfPcapProtocol.IPV4); + if (map == null) { + fail("getFieldsTest() failed because map is null!"); + return; + } + assertEquals("145.254.160.237", map.get("Source IP Address")); + } + + /** + * Method that tests getPayload of PcapEvent. + */ + @Test + public void getPayloadTest() { + ByteBuffer bb = fEvent.getPayload(TmfPcapProtocol.TCP); + if (bb == null) { + fail("getPayloadTest() failed because bb is null!"); + return; + } + assertEquals((byte) 0x47, bb.get()); + } + + /** + * Method that tests getSourceEndpoint of PcapEvent. + */ + @Test + public void getSourceEndpointTest() { + assertEquals("00:00:01:00:00:00/145.254.160.237/3372", fEvent.getSourceEndpoint(TmfPcapProtocol.TCP)); + } + + /** + * Method that tests getDestinationEndpointTest of PcapEvent. + */ + @Test + public void getDestinationEndpointTest() { + assertEquals("fe:ff:20:00:01:00", fEvent.getDestinationEndpoint(TmfPcapProtocol.ETHERNET_II)); + } + + /** + * Method that tests toString() of PcapEvent. + */ + @Test + public void toStringTest() { + assertEquals("3372 > 80 [ACK, PSH] Seq=951057940 Ack=290218380 Len=20", fEvent.toString()); + } + + /** + * Method that tests toString(protocol) of PcapEvent. + */ + @Test + public void toStringAtSpecificProtocolTest() { + assertEquals("Src: 145.254.160.237 , Dst: 65.208.228.223", fEvent.toString(TmfPcapProtocol.IPV4)); + } + +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/trace/AllTests.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/trace/AllTests.java new file mode 100644 index 0000000000..f359830304 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/trace/AllTests.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.pcap.core.tests.trace; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Pcap trace test suite + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + PcapTraceTest.class +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/trace/PcapTraceTest.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/trace/PcapTraceTest.java new file mode 100644 index 0000000000..cce04a17f9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core.tests/src/org/eclipse/tracecompass/tmf/pcap/core/tests/trace/PcapTraceTest.java @@ -0,0 +1,307 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.pcap.core.tests.trace; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.tracecompass.internal.tmf.pcap.core.event.PcapEvent; +import org.eclipse.tracecompass.internal.tmf.pcap.core.trace.PcapTrace; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.signal.TmfEndSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; +import org.eclipse.tracecompass.tmf.pcap.core.tests.shared.PcapTmfTestTrace; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * JUnit that test the PcapTrace class. + * + * @author Vincent Perot + */ +public class PcapTraceTest { + + private static final PcapTmfTestTrace TEST_TRACE = PcapTmfTestTrace.MOSTLY_TCP; + + private PcapTrace fFixture; + + /** + * Perform pre-test initialization. + * + * @throws TmfTraceException + * If the test trace is not found + */ + @Before + public void setUp() throws TmfTraceException { + assumeTrue(TEST_TRACE.exists()); + fFixture = new PcapTrace(); + fFixture.initTrace((IResource) null, TEST_TRACE.getPath(), PcapEvent.class); + } + + /** + * Perform post-test clean-up. + */ + @After + public void tearDown() { + if (fFixture != null) { + fFixture.dispose(); + } + } + + /** + * Run the PcapTrace() constructor test. + */ + @Test + public void testPcapTrace() { + try (PcapTrace result = new PcapTrace();) { + assertNotNull(result); + assertEquals(1000, result.getCacheSize()); + assertEquals(0L, result.getNbEvents()); + assertEquals(0L, result.getStreamingInterval()); + assertNull(result.getResource()); + assertNull(result.getType()); + } + } + + /** + * Test the parseEvent() method + */ + @Test + public void testParseEvent() { + ITmfContext ctx = fFixture.seekEvent(0); + fFixture.getNext(ctx); + PcapEvent event = fFixture.parseEvent(ctx); + assertNotNull(event); + } + + /** + * Run the void broadcast(TmfSignal) method test. + */ + @Test + public void testBroadcast() { + TmfSignal signal = new TmfEndSynchSignal(1); + fFixture.broadcast(signal); + } + + /** + * Run the void dispose() method test. + */ + @Test + public void testClose() { + try (PcapTrace emptyFixture = new PcapTrace();) { + } + } + + /** + * Run the int getCacheSize() method test. + */ + @Test + public void testGetCacheSize() { + try (PcapTrace emptyFixture = new PcapTrace();) { + int result = emptyFixture.getCacheSize(); + assertEquals(1000, result); + } + } + + /** + * Run the ITmfLocation getCurrentLocation() method test. + */ + @Test + public void testGetCurrentLocation() { + TmfLongLocation result = (TmfLongLocation) fFixture.getCurrentLocation(); + assertEquals(new TmfLongLocation(0), result); + } + + /** + * Test the seekEvent() method with a null location. + */ + @Test + public void testSeekEventLoc_null() { + TmfLongLocation loc = null; + fFixture.seekEvent(loc); + assertNotNull(fFixture); + } + + /** + * Test the seekEvent() method with a normal location. + */ + @Test + public void testSeekEventLoc_normal() { + TmfLongLocation loc = new TmfLongLocation(3L); + fFixture.seekEvent(loc); + assertNotNull(fFixture); + } + + /** + * Run the ITmfTimestamp getEndTime() method test. + */ + @Test + public void testGetEndTime() { + ITmfTimestamp result = fFixture.getEndTime(); + assertNotNull(result); + } + + /** + * Test the {@link PcapTrace#getEventType()} method. + */ + @Test + public void testGetEventType() { + Class result = fFixture.getEventType(); + assertNotNull(result); + assertEquals(PcapEvent.class, result); + } + + /** + * Run the double getLocationRatio(ITmfLocation) method test. + */ + @Test + public void testGetLocationRatio() { + TmfLongLocation location = new TmfLongLocation(20L); + double result = fFixture.getLocationRatio(location); + + assertEquals(20.0 / 43.0, result, 0.01); + } + + /** + * Run the String getName() method test. + */ + @Test + public void testGetName() { + String result = fFixture.getName(); + assertNotNull(result); + } + + /** + * Run the getTraceProperties() method test. + */ + @Test + public void testGetTraceProperties() { + int result = fFixture.getTraceProperties().size(); + assertEquals(6, result); + } + + /** + * Run the long getNbEvents() method test. + */ + @Test + public void testGetNbEvents() { + long result = fFixture.getNbEvents(); + assertEquals(0, result); + } + + /** + * Run the String getPath() method test. + */ + @Test + public void testGetPath() { + String result = fFixture.getPath(); + assertNotNull(result); + } + + /** + * Run the IResource getResource() method test. + */ + @Test + public void testGetResource() { + IResource result = fFixture.getResource(); + assertNull(result); + } + + /** + * Run the ITmfTimestamp getStartTime() method test. + */ + @Test + public void testGetStartTime() { + ITmfTimestamp result = fFixture.getStartTime(); + assertNotNull(result); + } + + /** + * Run the long getStreamingInterval() method test. + */ + @Test + public void testGetStreamingInterval() { + long result = fFixture.getStreamingInterval(); + assertEquals(0L, result); + } + + /** + * Run the TmfTimeRange getTimeRange() method test. + */ + @Test + public void testGetTimeRange() { + TmfTimeRange result = fFixture.getTimeRange(); + assertNotNull(result); + } + + /** + * Run the ITmfContext seekEvent(double) method test. + */ + @Test + public void testSeekEvent_ratio() { + double ratio = 21.0 / 43.0; + ITmfContext result = fFixture.seekEvent(ratio); + assertNotNull(result); + } + + /** + * Run the ITmfContext seekEvent(long) method test. + */ + @Test + public void testSeekEvent_rank() { + long rank = 1L; + ITmfContext result = fFixture.seekEvent(rank); + assertNotNull(result); + } + + /** + * Run the ITmfContext seekEvent(ITmfLocation) method test. + */ + @Test + public void testSeekEvent_location() { + TmfLongLocation pcapLocation = new TmfLongLocation(10L); + ITmfContext result = fFixture.seekEvent(pcapLocation); + assertNotNull(result); + } + + /** + * Run the boolean validate(IProject,String) method test. + */ + @Test + public void testValidate() { + IProject project = null; + IStatus result = fFixture.validate(project, TEST_TRACE.getPath()); + assertTrue(result.isOK()); + } + + /** + * Run the String getHostId() method test + */ + @Test + public void getSource() { + String a = fFixture.getHostId(); + assertEquals("mostlyTCP.pcap", a); + } + +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/stubs/org/eclipse/linuxtools/tmf/pcap/core/tests/stubs/PcapTmfTraceStub.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/stubs/org/eclipse/linuxtools/tmf/pcap/core/tests/stubs/PcapTmfTraceStub.java deleted file mode 100644 index ab0228ddc2..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core.tests/stubs/org/eclipse/linuxtools/tmf/pcap/core/tests/stubs/PcapTmfTraceStub.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.pcap.core.tests.stubs; - -import org.eclipse.linuxtools.internal.tmf.pcap.core.trace.PcapTrace; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; - -/** - * Dummy test pcap trace - */ -public class PcapTmfTraceStub extends PcapTrace { - - /** - * Simulate trace opening, to be called by tests who need an actively opened - * trace - */ - public void openTrace() { - TmfSignalManager.dispatchSignal(new TmfTraceOpenedSignal(this, this, null)); - selectTrace(); - } - - /** - * Simulate selecting the trace - */ - public void selectTrace() { - TmfSignalManager.dispatchSignal(new TmfTraceSelectedSignal(this, this)); - } - -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core.tests/stubs/org/eclipse/tracecompass/tmf/pcap/core/tests/stubs/PcapTmfTraceStub.java b/org.eclipse.tracecompass.tmf.pcap.core.tests/stubs/org/eclipse/tracecompass/tmf/pcap/core/tests/stubs/PcapTmfTraceStub.java new file mode 100644 index 0000000000..808d148114 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core.tests/stubs/org/eclipse/tracecompass/tmf/pcap/core/tests/stubs/PcapTmfTraceStub.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.pcap.core.tests.stubs; + +import org.eclipse.tracecompass.internal.tmf.pcap.core.trace.PcapTrace; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; + +/** + * Dummy test pcap trace + */ +public class PcapTmfTraceStub extends PcapTrace { + + /** + * Simulate trace opening, to be called by tests who need an actively opened + * trace + */ + public void openTrace() { + TmfSignalManager.dispatchSignal(new TmfTraceOpenedSignal(this, this, null)); + selectTrace(); + } + + /** + * Simulate selecting the trace + */ + public void selectTrace() { + TmfSignalManager.dispatchSignal(new TmfTraceSelectedSignal(this, this)); + } + +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/META-INF/MANIFEST.MF b/org.eclipse.tracecompass.tmf.pcap.core/META-INF/MANIFEST.MF index 1eed1d8ecd..0d27f61391 100644 --- a/org.eclipse.tracecompass.tmf.pcap.core/META-INF/MANIFEST.MF +++ b/org.eclipse.tracecompass.tmf.pcap.core/META-INF/MANIFEST.MF @@ -5,18 +5,18 @@ Bundle-Vendor: %Bundle-Vendor Bundle-Version: 1.0.0.qualifier Bundle-Localization: plugin Bundle-SymbolicName: org.eclipse.tracecompass.tmf.pcap.core;singleton:=true -Bundle-Activator: org.eclipse.linuxtools.internal.tmf.pcap.core.Activator +Bundle-Activator: org.eclipse.tracecompass.internal.tmf.pcap.core.Activator Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.resources, org.eclipse.tracecompass.tmf.core;bundle-version="3.1.0", org.eclipse.tracecompass.pcap.core;bundle-version="1.0.0" -Export-Package: org.eclipse.linuxtools.internal.tmf.pcap.core;x-internal:=true, - org.eclipse.linuxtools.internal.tmf.pcap.core.analysis;x-friends:="org.eclipse.tracecompass.tmf.pcap.core.tests,org.eclipse.tracecompass.tmf.pcap.ui", - org.eclipse.linuxtools.internal.tmf.pcap.core.event;x-friends:="org.eclipse.tracecompass.tmf.pcap.core.tests,org.eclipse.tracecompass.tmf.pcap.ui", - org.eclipse.linuxtools.internal.tmf.pcap.core.protocol;x-friends:="org.eclipse.tracecompass.tmf.pcap.core.tests,org.eclipse.tracecompass.tmf.pcap.ui", - org.eclipse.linuxtools.internal.tmf.pcap.core.signal;x-friends:="org.eclipse.tracecompass.tmf.pcap.ui", - org.eclipse.linuxtools.internal.tmf.pcap.core.trace;x-friends:="org.eclipse.tracecompass.tmf.pcap.core.tests,org.eclipse.tracecompass.tmf.pcap.ui,org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests", - org.eclipse.linuxtools.internal.tmf.pcap.core.util;x-internal:=true +Export-Package: org.eclipse.tracecompass.internal.tmf.pcap.core;x-internal:=true, + org.eclipse.tracecompass.internal.tmf.pcap.core.analysis;x-friends:="org.eclipse.tracecompass.tmf.pcap.core.tests,org.eclipse.tracecompass.tmf.pcap.ui", + org.eclipse.tracecompass.internal.tmf.pcap.core.event;x-friends:="org.eclipse.tracecompass.tmf.pcap.core.tests,org.eclipse.tracecompass.tmf.pcap.ui", + org.eclipse.tracecompass.internal.tmf.pcap.core.protocol;x-friends:="org.eclipse.tracecompass.tmf.pcap.core.tests,org.eclipse.tracecompass.tmf.pcap.ui", + org.eclipse.tracecompass.internal.tmf.pcap.core.signal;x-friends:="org.eclipse.tracecompass.tmf.pcap.ui", + org.eclipse.tracecompass.internal.tmf.pcap.core.trace;x-friends:="org.eclipse.tracecompass.tmf.pcap.core.tests,org.eclipse.tracecompass.tmf.pcap.ui,org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests", + org.eclipse.tracecompass.internal.tmf.pcap.core.util;x-internal:=true Import-Package: com.google.common.collect diff --git a/org.eclipse.tracecompass.tmf.pcap.core/plugin.xml b/org.eclipse.tracecompass.tmf.pcap.core/plugin.xml index 4062b329f4..227adf50e5 100644 --- a/org.eclipse.tracecompass.tmf.pcap.core/plugin.xml +++ b/org.eclipse.tracecompass.tmf.pcap.core/plugin.xml @@ -9,23 +9,23 @@ + trace_type="org.eclipse.tracecompass.internal.tmf.pcap.core.trace.PcapTrace"> + class="org.eclipse.tracecompass.internal.tmf.pcap.core.trace.PcapTrace"> diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/Activator.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/Activator.java deleted file mode 100644 index 86f2a81a0a..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/Activator.java +++ /dev/null @@ -1,212 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.core; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Plugin; -import org.eclipse.core.runtime.Status; -import org.eclipse.jdt.annotation.Nullable; -import org.osgi.framework.BundleContext; - -/** - * Activator - *

- * The activator class controls the plug-in life cycle - */ -public class Activator extends Plugin { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The plug-in ID - */ - public static final String PLUGIN_ID = "org.eclipse.linuxtools.tmf.pcap.core"; //$NON-NLS-1$ - - /** - * The shared instance - */ - private static @Nullable Activator fPlugin; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructor - */ - public Activator() { - setDefault(this); - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Returns the TMF Core plug-in instance. - * - * @return the TMF Core plug-in instance. - */ - public static @Nullable Activator getDefault() { - return fPlugin; - } - - // Sets plug-in instance - private static void setDefault(@Nullable Activator plugin) { - fPlugin = plugin; - } - - // ------------------------------------------------------------------------ - // Plugin - // ------------------------------------------------------------------------ - - @Override - public void start(@Nullable BundleContext context) throws Exception { - super.start(context); - setDefault(this); - } - - @Override - public void stop(@Nullable BundleContext context) throws Exception { - setDefault(null); - super.stop(context); - } - - - // ------------------------------------------------------------------------ - // Log an IStatus - // ------------------------------------------------------------------------ - - /** - * Log an IStatus object directly - * - * @param status - * The status to log - */ - public static void log(IStatus status) { - Activator activator = fPlugin; - if (activator == null) { - return; - } - activator.getLog().log(status); - } - - // ------------------------------------------------------------------------ - // Log INFO - // ------------------------------------------------------------------------ - - /** - * Logs a message with severity INFO in the runtime log of the plug-in. - * - * @param message - * A message to log - */ - public static void logInfo(String message) { - Activator activator = fPlugin; - if (activator == null) { - return; - } - activator.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity INFO in the runtime log of the - * plug-in. - * - * @param message - * A message to log - * @param exception - * The corresponding exception - */ - public static void logInfo(String message, Throwable exception) { - Activator activator = fPlugin; - if (activator == null) { - return; - } - activator.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message, exception)); - } - - // ------------------------------------------------------------------------ - // Log WARNING - // ------------------------------------------------------------------------ - - /** - * Logs a message and exception with severity WARNING in the runtime log of - * the plug-in. - * - * @param message - * A message to log - */ - public static void logWarning(String message) { - Activator activator = fPlugin; - if (activator == null) { - return; - } - activator.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity WARNING in the runtime log of - * the plug-in. - * - * @param message - * A message to log - * @param exception - * The corresponding exception - */ - public static void logWarning(String message, Throwable exception) { - Activator activator = fPlugin; - if (activator == null) { - return; - } - activator.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message, exception)); - } - - // ------------------------------------------------------------------------ - // Log ERROR - // ------------------------------------------------------------------------ - - /** - * Logs a message and exception with severity ERROR in the runtime log of - * the plug-in. - * - * @param message - * A message to log - */ - public static void logError(String message) { - Activator activator = fPlugin; - if (activator == null) { - return; - } - activator.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity ERROR in the runtime log of - * the plug-in. - * - * @param message - * A message to log - * @param exception - * The corresponding exception - */ - public static void logError(String message, Throwable exception) { - Activator activator = fPlugin; - if (activator == null) { - return; - } - activator.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, exception)); - } -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/analysis/StreamListAnalysis.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/analysis/StreamListAnalysis.java deleted file mode 100644 index 47a2c60c05..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/analysis/StreamListAnalysis.java +++ /dev/null @@ -1,164 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.core.analysis; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.internal.tmf.pcap.core.event.PcapEvent; -import org.eclipse.linuxtools.internal.tmf.pcap.core.event.TmfPacketStreamBuilder; -import org.eclipse.linuxtools.internal.tmf.pcap.core.protocol.TmfPcapProtocol; -import org.eclipse.linuxtools.internal.tmf.pcap.core.trace.PcapTrace; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAbstractAnalysisModule; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; - -/** - * A pcap-specific analysis that parse an entire trace to find all the streams. - * - * @author Vincent Perot - */ -public class StreamListAnalysis extends TmfAbstractAnalysisModule { - - /** - * The Stream List analysis ID. - */ - public static final String ID = "org.eclipse.linuxtools.tmf.pcap.core.analysis.stream"; //$NON-NLS-1$ - - private @Nullable ITmfEventRequest fRequest; - private final Map fBuilders; - - /** - * The default constructor. It initializes all variables. - */ - public StreamListAnalysis() { - super(); - fBuilders = new HashMap<>(); - for (TmfPcapProtocol protocol : TmfPcapProtocol.values()) { - if (protocol.supportsStream()) { - fBuilders.put(protocol, new TmfPacketStreamBuilder(protocol)); - } - } - } - - @Override - public boolean canExecute(ITmfTrace trace) { - - // Trace is Pcap - if (trace instanceof PcapTrace) { - return true; - } - - // Trace is not a TmfExperiment - if (!(trace instanceof TmfExperiment)) { - return false; - } - - // Trace is TmfExperiment. Check if it has a PcapTrace. - TmfExperiment experiment = (TmfExperiment) trace; - ITmfTrace[] traces = experiment.getTraces(); - for (int i = 0; i < traces.length; i++) { - if (traces[i] instanceof PcapTrace) { - return true; - } - } - - // No Pcap :( - return false; - } - - @Override - protected boolean executeAnalysis(@Nullable IProgressMonitor monitor) throws TmfAnalysisException { - IProgressMonitor mon = (monitor == null ? new NullProgressMonitor() : monitor); - if (getTrace() == null) { - return false; - } - - ITmfEventRequest request = fRequest; - if ((request != null) && (!request.isCompleted())) { - request.cancel(); - } - - request = new TmfEventRequest(PcapEvent.class, - TmfTimeRange.ETERNITY, 0L, ITmfEventRequest.ALL_DATA, - ITmfEventRequest.ExecutionType.BACKGROUND) { - - @Override - public void handleData(ITmfEvent data) { - // Called for each event - super.handleData(data); - if (!(data instanceof PcapEvent)) { - return; - } - PcapEvent event = (PcapEvent) data; - for (TmfPcapProtocol protocol : fBuilders.keySet()) { - fBuilders.get(protocol).addEventToStream(event); - } - - } - }; - getTrace().sendRequest(request); - fRequest = request; - try { - request.waitForCompletion(); - } catch (InterruptedException e) { - // Request was canceled. - return false; - } - - return !mon.isCanceled() && !request.isCancelled() && !request.isFailed(); - - } - - @Override - protected void canceling() { - ITmfEventRequest req = fRequest; - if ((req != null) && (!req.isCompleted())) { - req.cancel(); - } - } - - /** - * Getter method that returns the packet builder associated to a particular - * protocol. - * - * @param protocol - * The specified protocol. - * @return The builder. - */ - public @Nullable TmfPacketStreamBuilder getBuilder(TmfPcapProtocol protocol) { - return fBuilders.get(protocol); - } - - /** - * Method that indicates if the analysis is still running or has finished. - * - * @return Whether the analysis is finished or not. - */ - public boolean isFinished() { - ITmfEventRequest req = fRequest; - if (req == null) { - return false; - } - return req.isCompleted(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/analysis/package-info.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/analysis/package-info.java deleted file mode 100644 index 664044c86f..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/analysis/package-info.java +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ericsson - Initial API and implementation - *******************************************************************************/ - -@org.eclipse.jdt.annotation.NonNullByDefault -package org.eclipse.linuxtools.internal.tmf.pcap.core.analysis; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/Messages.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/Messages.java deleted file mode 100644 index 47df1b161e..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/Messages.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.core.event; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.osgi.util.NLS; - -@NonNullByDefault(false) -@SuppressWarnings("javadoc") -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.tmf.pcap.core.event.messages"; //$NON-NLS-1$ - - public static @Nullable String PcapEventType_DefaultContext; - public static @Nullable String PcapEventType_DefaultTypeID; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/PcapEvent.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/PcapEvent.java deleted file mode 100644 index 705c521984..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/PcapEvent.java +++ /dev/null @@ -1,242 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.core.event; - -import java.nio.ByteBuffer; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.internal.pcap.core.packet.Packet; -import org.eclipse.linuxtools.internal.pcap.core.protocol.PcapProtocol; -import org.eclipse.linuxtools.internal.tmf.pcap.core.protocol.TmfPcapProtocol; -import org.eclipse.linuxtools.internal.tmf.pcap.core.util.ProtocolConversion; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -import com.google.common.collect.ImmutableList; - -/** - * Class that extends TmfEvent to allow TMF to use the packets from the parser. - * It is a simple TmfEvent that wraps a Packet. - * - * @author Vincent Perot - */ -public class PcapEvent extends TmfEvent { - - /** Packet Source Field ID */ - public static final String EVENT_FIELD_PACKET_SOURCE = ":packetsource:"; //$NON-NLS-1$ - /** Packet Destination Field ID */ - public static final String EVENT_FIELD_PACKET_DESTINATION = ":packetdestination:"; //$NON-NLS-1$ - /** Packet Protocol Field ID */ - public static final String EVENT_FIELD_PACKET_PROTOCOL = ":protocol:"; //$NON-NLS-1$ - - private static final String EMPTY_STRING = ""; //$NON-NLS-1$ - - private final Packet fPacket; - - /** - * Lazy-loaded field representing all the protocols in this event - */ - private transient @Nullable Collection fProtocols; - - /** - * Full constructor. - * - * @param trace - * the parent trace - * @param rank - * the event rank (in the trace) - * @param timestamp - * the event timestamp - * @param source - * the event source - * @param type - * the event type - * @param content - * the event content (payload) - * @param reference - * the event reference - * @param packet - * The packet contained in this event - */ - public PcapEvent(ITmfTrace trace, - long rank, - ITmfTimestamp timestamp, - String source, - TmfEventType type, - ITmfEventField content, - String reference, - Packet packet) { - - super(trace, rank, timestamp, source, type, content, reference); - fPacket = packet; - } - - /** - * Method that returns an immutable map containing all the fields of a - * packet at a certain protocol. For instance, to get the Source IP Address, - * use: - * event.getFields(TmfProtocol.IPV4).get("Source IP Address");.
- * It returns null if the protocol is inexistent in the PcapEvent. - * - * @param protocol - * The specified protocol - * @return A map containing the fields. - */ - public @Nullable Map getFields(TmfPcapProtocol protocol) { - PcapProtocol p = ProtocolConversion.unwrap(protocol); - Packet packet = fPacket.getPacket(p); - if (packet == null) { - return null; - } - return packet.getFields(); - } - - /** - * Method that returns the payload at a certain protocol level. It returns - * null if the protocol is inexistent in the PcapEvent. - * - * @param protocol - * The specified protocol - * @return The payload as a ByteBuffer. - */ - public @Nullable ByteBuffer getPayload(TmfPcapProtocol protocol) { - PcapProtocol p = ProtocolConversion.unwrap(protocol); - Packet packet = fPacket.getPacket(p); - if (packet == null) { - return null; - } - return packet.getPayload(); - } - - /** - * Method that returns the source endpoint at a certain protocol level. It - * returns null if the protocol is inexistent in the PcapEvent. - * - * @param protocol - * The specified protocol - * @return The source endpoint. - */ - public @Nullable String getSourceEndpoint(TmfPcapProtocol protocol) { - PcapProtocol p = ProtocolConversion.unwrap(protocol); - Packet packet = fPacket.getPacket(p); - if (packet == null) { - return null; - } - return packet.getSourceEndpoint().toString(); - } - - /** - * Method that returns the destination endpoint at a certain protocol level. - * It returns null if the protocol is inexistent in the PcapEvent. - * - * @param protocol - * The specified protocol - * @return The destination endpoint. - */ - public @Nullable String getDestinationEndpoint(TmfPcapProtocol protocol) { - PcapProtocol p = ProtocolConversion.unwrap(protocol); - Packet packet = fPacket.getPacket(p); - if (packet == null) { - return null; - } - return packet.getDestinationEndpoint().toString(); - } - - /** - * Method that returns the most encapsulated protocol in this PcapEvent. If - * it is an unknown protocol, it returns the last known protocol. - * - * @return The most encapsulated TmfProtocol. - */ - public TmfPcapProtocol getMostEncapsulatedProtocol() { - return ProtocolConversion.wrap(fPacket.getMostEcapsulatedPacket().getProtocol()); - } - - /** - * Method that returns all the protocols in this PcapEvent. - * - * @return A list containing all the TmfProtocol. - */ - public Collection getProtocols() { - if (fProtocols != null) { - return fProtocols; - } - ImmutableList.Builder builder = new ImmutableList.Builder<>(); - Packet packet = fPacket; - - // Go to start. - while (packet != null && packet.getParentPacket() != null) { - packet = packet.getParentPacket(); - } - - if (packet == null) { - @SuppressWarnings("null") - @NonNull List emptyList = Collections.EMPTY_LIST; - fProtocols = emptyList; - return fProtocols; - } - // Go through all the packets and add them to list. - builder.add(ProtocolConversion.wrap(packet.getProtocol())); - while (packet != null && packet.getChildPacket() != null) { - packet = packet.getChildPacket(); - if (packet != null) { - builder.add(ProtocolConversion.wrap(packet.getProtocol())); - } - } - - @SuppressWarnings("null") - @NonNull ImmutableList immutableList = builder.build(); - fProtocols = immutableList; - return immutableList; - } - - /** - * Getter method that returns the packet. This is default visible since it - * is only used by tmf.pcap.core and thus should not be visible to other - * packages - * - * @return The packet. - */ - Packet getPacket() { - return fPacket; - } - - @Override - public String toString() { - return fPacket.getGlobalSummaryString(); - } - - /** - * Return the signification of the PcapEvent at a specific protocol level. - * - * @param protocol - * The specified protocol. - * @return The signification as a String. - */ - public String toString(TmfPcapProtocol protocol) { - PcapProtocol p = ProtocolConversion.unwrap(protocol); - Packet packet = fPacket.getPacket(p); - if (packet == null) { - return EMPTY_STRING; - } - return packet.getLocalSummaryString(); - } -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/PcapEventField.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/PcapEventField.java deleted file mode 100644 index 004f50d3b0..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/PcapEventField.java +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.core.event; - -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.internal.pcap.core.packet.Packet; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; - -/** - * Class that represents a TMF Pcap Event Field. It is identical to a - * TmfEventField, except that it overrides the toString() method. - * - * @author Vincent Perot - */ -public class PcapEventField extends TmfEventField { - - private final String fSummaryString; - - /** - * Full constructor - * - * @param name - * The event field id. - * @param value - * The event field value. - * @param fields - * The list of subfields. - * @param packet - * The packet from which to take the fields from. - * @throws IllegalArgumentException - * If 'name' is null, or if 'fields' has duplicate field names. - */ - public PcapEventField(String name, Object value, @Nullable ITmfEventField[] fields, Packet packet) { - super(name, value, fields); - fSummaryString = packet.getLocalSummaryString(); - } - - /** - * Copy constructor - * - * @param field - * the other event field - */ - public PcapEventField(final PcapEventField field) { - super(field); - fSummaryString = field.fSummaryString; - } - - @Override - public String toString() { - return fSummaryString; - } -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/PcapEventType.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/PcapEventType.java deleted file mode 100644 index d15975fea0..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/PcapEventType.java +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.core.event; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; - -/** - * Class that represents the type of a PcapEvent. - * - * @author Vincent Perot - */ -public class PcapEventType extends TmfEventType { - - private static final String EMPTY_STRING = ""; //$NON-NLS-1$ - - /** - * The default Context ID for a PcapEvent - */ - @SuppressWarnings("null") - public static final @NonNull String DEFAULT_PCAP_CONTEXT_ID = Messages.PcapEventType_DefaultContext == null ? EMPTY_STRING : Messages.PcapEventType_DefaultContext; - - /** - * The default Pcap Type ID for a PcapEvent - */ - @SuppressWarnings("null") - public static final @NonNull String DEFAULT_PCAP_TYPE_ID = Messages.PcapEventType_DefaultTypeID == null ? EMPTY_STRING : Messages.PcapEventType_DefaultTypeID; - - /** - * Default constructor - */ - public PcapEventType() { - this(DEFAULT_PCAP_TYPE_ID, null); - } - - /** - * Full constructor - * - * @param typeId - * the type name - * @param root - * the root field - */ - public PcapEventType(final String typeId, final @Nullable ITmfEventField root) { - super(DEFAULT_PCAP_CONTEXT_ID, typeId, root); - } - - /** - * Copy constructor - * - * @param type - * the other type - */ - public PcapEventType(final PcapEventType type) { - super(type); - } - - @Override - public @Nullable String toString() { - return getName(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/PcapRootEventField.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/PcapRootEventField.java deleted file mode 100644 index 66654fcd74..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/PcapRootEventField.java +++ /dev/null @@ -1,90 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.core.event; - -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.internal.pcap.core.packet.Packet; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; - -/** - * Class that represents the root node of Pcap Event Field. - * - * @author Vincent Perot - */ -public class PcapRootEventField extends TmfEventField { - - private final TmfEventField fPacketSourceField; - private final TmfEventField fPacketDestinationField; - private final TmfEventField fProtocolField; - private final String fSummaryString; - - /** - * Full constructor - * - * @param value - * The event field value. - * @param fields - * The list of subfields. - * @param packet - * The packet from which to take the fields from. - * @throws IllegalArgumentException - * If 'name' is null, or if 'fields' has duplicate field names. - */ - public PcapRootEventField(Object value, @Nullable ITmfEventField[] fields, Packet packet) { - super(ITmfEventField.ROOT_FIELD_ID, value, fields); - fPacketSourceField = new TmfEventField(PcapEvent.EVENT_FIELD_PACKET_SOURCE, - packet.getMostEcapsulatedPacket().getSourceEndpoint().toString(), null); - fPacketDestinationField = new TmfEventField(PcapEvent.EVENT_FIELD_PACKET_DESTINATION, - packet.getMostEcapsulatedPacket().getDestinationEndpoint().toString(), null); - fProtocolField = new TmfEventField(PcapEvent.EVENT_FIELD_PACKET_PROTOCOL, - packet.getMostEcapsulatedPacket().getProtocol().getShortName().toUpperCase(), null); - fSummaryString = packet.getGlobalSummaryString(); - } - - /** - * Copy constructor - * - * @param field - * the other event field - */ - public PcapRootEventField(final PcapRootEventField field) { - super(field); - fPacketSourceField = field.fPacketSourceField; - fPacketDestinationField = field.fPacketDestinationField; - fProtocolField = field.fProtocolField; - fSummaryString = field.fSummaryString; - } - - @Override - public String toString() { - return fSummaryString; - } - - @Override - public @Nullable ITmfEventField getField(@Nullable String name) { - if (name == null) { - return null; - } - switch (name) { - case PcapEvent.EVENT_FIELD_PACKET_SOURCE: - return fPacketSourceField; - case PcapEvent.EVENT_FIELD_PACKET_DESTINATION: - return fPacketDestinationField; - case PcapEvent.EVENT_FIELD_PACKET_PROTOCOL: - return fProtocolField; - default: - return super.getField(name); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/TmfPacketStream.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/TmfPacketStream.java deleted file mode 100644 index 7a32d7a047..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/TmfPacketStream.java +++ /dev/null @@ -1,175 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.core.event; - -import org.eclipse.linuxtools.internal.pcap.core.stream.PacketStream; -import org.eclipse.linuxtools.internal.tmf.pcap.core.protocol.TmfPcapProtocol; -import org.eclipse.linuxtools.internal.tmf.pcap.core.util.ProtocolConversion; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; - -/** - * Class that wraps a Packet Stream. - * - * @author Vincent Perot - */ -public class TmfPacketStream { - - private final PacketStream fPacketStream; - - /** - * Class constructor. - * - * @param stream - * The stream to build the TmfPacketStream from. - */ - public TmfPacketStream(PacketStream stream) { - fPacketStream = stream; - } - - /** - * Method that returns the first endpoint of the packet stream. - * - * @return The first endpoint. - */ - public String getFirstEndpoint() { - return fPacketStream.getEndpointPair().getFirstEndpoint().toString(); - } - - /** - * Method that returns the second endpoint of the packet stream. - * - * @return The second endpoint. - */ - public String getSecondEndpoint() { - return fPacketStream.getEndpointPair().getSecondEndpoint().toString(); - } - - /** - * Method that returns the ID of the packet stream. - * - * @return The ID of the packet stream. - */ - public int getID() { - return fPacketStream.getID(); - } - - /** - * Method that returns the TmfProtocol of the packet stream. - * - * @return The TmfProtocol of the packet stream. - */ - public TmfPcapProtocol getProtocol() { - return ProtocolConversion.wrap(fPacketStream.getProtocol()); - } - - /** - * Get the number of packets going from the first endpoint to the second. - * - * @return The number of packets from A to B. - */ - public synchronized long getNbPacketsAtoB() { - return fPacketStream.getNbPacketsAtoB(); - } - - /** - * Get the number of packets going from the second endpoint to the first. - * - * @return The number of packets from B to A. - */ - public synchronized long getNbPacketsBtoA() { - return fPacketStream.getNbPacketsBtoA(); - } - - /** - * Get the total number of packets in this stream. - * - * @return The total number of packets. - */ - public synchronized long getNbPackets() { - return fPacketStream.getNbPackets(); - } - - /** - * Get the number of bytes going from the first endpoint to the second. - * - * @return The number of bytes from A to B. - */ - public synchronized long getNbBytesAtoB() { - return fPacketStream.getNbBytesAtoB(); - } - - /** - * Get the number of bytes going from the second endpoint to the first. - * - * @return The number of bytes from B to A. - */ - public synchronized long getNbBytesBtoA() { - return fPacketStream.getNbBytesBtoA(); - } - - /** - * Get the total number of bytes in this stream. - * - * @return The total number of bytes. - */ - public synchronized long getNbBytes() { - return fPacketStream.getNbBytes(); - } - - /** - * Get the start time of this stream. - * - * @return The start time. - */ - public synchronized ITmfTimestamp getStartTime() { - return new TmfTimestamp(fPacketStream.getStartTime(), ITmfTimestamp.NANOSECOND_SCALE); - } - - /** - * Get the stop time of this stream. - * - * @return The stop time. - */ - public synchronized ITmfTimestamp getStopTime() { - return new TmfTimestamp(fPacketStream.getStopTime(), ITmfTimestamp.NANOSECOND_SCALE); - } - - /** - * Get the duration of this stream, in seconds - * - * @return The duration of this stream. - */ - public synchronized double getDuration() { - return fPacketStream.getDuration(); - } - - /** - * Get the the average byte per second from A to B. - * - * @return the average byte per second from A to B. - */ - public synchronized double getBPSAtoB() { - return fPacketStream.getBPSAtoB(); - } - - /** - * Get the the average byte per second from B to A. - * - * @return the average byte per second from B to A. - */ - public synchronized double getBPSBtoA() { - return fPacketStream.getBPSBtoA(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/TmfPacketStreamBuilder.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/TmfPacketStreamBuilder.java deleted file mode 100644 index b6fd527646..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/TmfPacketStreamBuilder.java +++ /dev/null @@ -1,86 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.core.event; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.linuxtools.internal.pcap.core.packet.Packet; -import org.eclipse.linuxtools.internal.pcap.core.protocol.PcapProtocol; -import org.eclipse.linuxtools.internal.pcap.core.protocol.pcap.PcapPacket; -import org.eclipse.linuxtools.internal.pcap.core.stream.PacketStream; -import org.eclipse.linuxtools.internal.pcap.core.stream.PacketStreamBuilder; -import org.eclipse.linuxtools.internal.tmf.pcap.core.protocol.TmfPcapProtocol; -import org.eclipse.linuxtools.internal.tmf.pcap.core.util.ProtocolConversion; - -/** - * Class that wraps a PacketStreamBuilder. - * - * @author Vincent Perot - */ -public class TmfPacketStreamBuilder { - - private final PacketStreamBuilder fBuilder; - - /** - * Constructor. - * - * @param protocol - * The protocol of the streams to build. - */ - public TmfPacketStreamBuilder(TmfPcapProtocol protocol) { - fBuilder = new PacketStreamBuilder(ProtocolConversion.unwrap(protocol)); - } - - /** - * Method that adds an event to this builder. - * - * @param event - * The event to add. - */ - public synchronized void addEventToStream(PcapEvent event) { - Packet packet = event.getPacket().getPacket(PcapProtocol.PCAP); - if (packet == null || !(packet instanceof PcapPacket)) { - return; - } - PcapPacket pcapPacket = (PcapPacket) packet; - fBuilder.addPacketToStream(pcapPacket); - } - - /** - * Method that returns the number of streams built. - * - * @return The number of streams built. - */ - public synchronized int getNbStreams() { - return fBuilder.getNbStreams(); - } - - /** - * Method that returns an iterable on the streams built so far. - * - * @return An iterable on the streams. - */ - public synchronized Iterable getStreams() { - // We can't store in immutable list since the stream number/content can - // change dynamically. - List list = new ArrayList<>(); - for (PacketStream stream : fBuilder.getStreams()) { - if (stream != null) { - list.add(new TmfPacketStream(stream)); - } - } - return list; - } - -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/messages.properties b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/messages.properties deleted file mode 100644 index fcf8ca253a..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/messages.properties +++ /dev/null @@ -1,14 +0,0 @@ -############################################################################### -# Copyright (c) 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### - -PcapEventType_DefaultContext=Network/Pcap Event -PcapEventType_DefaultTypeID=packet diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/package-info.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/package-info.java deleted file mode 100644 index b5720b9340..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/event/package-info.java +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ericsson - Initial API and implementation - *******************************************************************************/ - -@org.eclipse.jdt.annotation.NonNullByDefault -package org.eclipse.linuxtools.internal.tmf.pcap.core.event; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/package-info.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/package-info.java deleted file mode 100644 index ce245a8678..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/package-info.java +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ericsson - Initial API and implementation - *******************************************************************************/ - -@org.eclipse.jdt.annotation.NonNullByDefault -package org.eclipse.linuxtools.internal.tmf.pcap.core; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/protocol/TmfPcapProtocol.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/protocol/TmfPcapProtocol.java deleted file mode 100644 index 2b6a96336b..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/protocol/TmfPcapProtocol.java +++ /dev/null @@ -1,109 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.core.protocol; - -import org.eclipse.linuxtools.internal.pcap.core.protocol.PcapProtocol; - -/** - * Enumeration as a TMF wrapper of the different Protocols. To register a - * protocol in TMF, it must be present in - * org.eclipse.linuxtools.pcap.core.protocol.Protocol and must have the same - * name. - * - * @author Vincent Perot - */ -public enum TmfPcapProtocol { - - // Layer 0 - /** - * The Pcap Protocol is not a real protocol but is used as an helper to - * generate Pcap packets. - */ - PCAP(PcapProtocol.PCAP), - - // Layer 1 - // Should always be empty. - - // Layer 2 - /** - * The description of the Ethernet II Protocol. - */ - ETHERNET_II(PcapProtocol.ETHERNET_II), - - // Layer 3 - /** - * The description of the Internet Protocol Version 4. - */ - IPV4(PcapProtocol.IPV4), - - // Layer 4 - /** - * The description of the Transmission Control Protocol. - */ - TCP(PcapProtocol.TCP), - /** - * The description of the User Datagram Protocol. - */ - UDP(PcapProtocol.UDP), - - // Layer 5 - - // Layer 6 - - // Layer 7 - /** - * This protocol is used as an helper if the protocol of a packet is not - * recognized. Since all its data goes into payload, it can also be seen as - * a "payload packet". This is considered to be on layer 7 since its always - * the most encapsulated packet if present. - */ - UNKNOWN(PcapProtocol.UNKNOWN); - - private final String fName; - private final String fShortName; - private final boolean fSupportsStream; - - private TmfPcapProtocol(PcapProtocol pcapProto) { - fName = pcapProto.getName(); - fShortName = pcapProto.getShortName(); - fSupportsStream = pcapProto.supportsStream(); - } - - /** - * Getter method for the long name of the protocol. - * - * @return The long name of the protocol, as a string. - */ - public String getName() { - return fName; - } - - /** - * Getter method for the short name of the protocol. - * - * @return The short name of the protocol, as a string. - */ - public String getShortName() { - return fShortName; - } - - /** - * Getter method that indicates if the protocol supports streams. - * - * @return Whether the protocol supports streams or not. - */ - public boolean supportsStream() { - return fSupportsStream; - } - -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/protocol/package-info.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/protocol/package-info.java deleted file mode 100644 index f3b9157c71..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/protocol/package-info.java +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ericsson - Initial API and implementation - *******************************************************************************/ - -@org.eclipse.jdt.annotation.NonNullByDefault -package org.eclipse.linuxtools.internal.tmf.pcap.core.protocol; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/signal/TmfPacketStreamSelectedSignal.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/signal/TmfPacketStreamSelectedSignal.java deleted file mode 100644 index 9cd6c0caec..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/signal/TmfPacketStreamSelectedSignal.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.core.signal; - -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.internal.tmf.pcap.core.event.TmfPacketStream; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignal; - -/** - * TmfSignal that is broadcasted when a new packet stream is chosen. Views that - * are network-specific can uses this signal to track when the user selects a - * new stream. - * - * @author Vincent Perot - */ -public class TmfPacketStreamSelectedSignal extends TmfSignal { - - private final @Nullable TmfPacketStream fStream; - - /** - * Standard constructor - * - * @param source - * Object sending this signal - * @param reference - * Reference index to assign to this signal - * @param stream - * The new stream. It can be null if the user cleared the - * selection. - */ - public TmfPacketStreamSelectedSignal(Object source, int reference, @Nullable TmfPacketStream stream) { - super(source, reference); - fStream = stream; - } - - /** - * Getter method that returns the stream. - * - * @return The stream. - */ - public @Nullable TmfPacketStream getStream() { - return fStream; - } -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/signal/package-info.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/signal/package-info.java deleted file mode 100644 index d43ac2918f..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/signal/package-info.java +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ericsson - Initial API and implementation - *******************************************************************************/ - -@org.eclipse.jdt.annotation.NonNullByDefault -package org.eclipse.linuxtools.internal.tmf.pcap.core.signal; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/trace/Messages.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/trace/Messages.java deleted file mode 100644 index 3b4018da4a..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/trace/Messages.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.core.trace; - -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.osgi.util.NLS; - -@SuppressWarnings("javadoc") -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.tmf.pcap.core.trace.messages"; //$NON-NLS-1$ - - public static @Nullable String PcapTrace_FileEndianness; - public static @Nullable String PcapTrace_LinkLayerHeaderType; - public static @Nullable String PcapTrace_MaxSnapLength; - public static @Nullable String PcapTrace_TimestampAccuracy; - public static @Nullable String PcapTrace_TimeZoneCorrection; - public static @Nullable String PcapTrace_Version; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/trace/PcapTrace.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/trace/PcapTrace.java deleted file mode 100644 index 20e3f5c0f4..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/trace/PcapTrace.java +++ /dev/null @@ -1,251 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.core.trace; - -import java.io.IOException; -import java.nio.channels.ClosedChannelException; -import java.nio.file.FileSystems; -import java.nio.file.Path; -import java.util.Map; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.internal.pcap.core.packet.BadPacketException; -import org.eclipse.linuxtools.internal.pcap.core.protocol.pcap.PcapPacket; -import org.eclipse.linuxtools.internal.pcap.core.trace.BadPcapFileException; -import org.eclipse.linuxtools.internal.pcap.core.trace.PcapFile; -import org.eclipse.linuxtools.internal.pcap.core.util.LinkTypeHelper; -import org.eclipse.linuxtools.internal.tmf.pcap.core.Activator; -import org.eclipse.linuxtools.internal.tmf.pcap.core.event.PcapEvent; -import org.eclipse.linuxtools.internal.tmf.pcap.core.util.PcapEventFactory; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTraceProperties; -import org.eclipse.linuxtools.tmf.core.trace.TmfContext; -import org.eclipse.linuxtools.tmf.core.trace.TmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TraceValidationStatus; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; -import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation; - -import com.google.common.collect.ImmutableMap; - -/** - * Class that represents a TMF Pcap Trace. It is used to make the glue between - * the Pcap parser and TMF. - * - * TODO handle fields in TmfEventType for the filter view. - * - * @author Vincent Perot - */ -public class PcapTrace extends TmfTrace implements ITmfEventParser, ITmfTraceProperties, AutoCloseable { - - @SuppressWarnings("null") - private static final @NonNull Map EMPTY_MAP = ImmutableMap.of(); - private static final String EMPTY_STRING = ""; //$NON-NLS-1$ - private static final int CONFIDENCE = 50; - private @Nullable PcapFile fPcapFile; - private @Nullable ImmutableMap fTraceProperties = null; - - @Override - public synchronized ITmfLocation getCurrentLocation() { - PcapFile pcap = fPcapFile; - if (pcap == null) { - return new TmfLongLocation(0); - } - return new TmfLongLocation(pcap.getCurrentRank()); - } - - @Override - public synchronized double getLocationRatio(@Nullable ITmfLocation location) { - TmfLongLocation loc = (TmfLongLocation) location; - PcapFile pcap = fPcapFile; - if (loc == null || pcap == null) { - return 0; - } - try { - return (pcap.getTotalNbPackets() == 0 ? 0 : ((double) loc.getLocationInfo()) / pcap.getTotalNbPackets()); - } catch (IOException | BadPcapFileException e) { - String message = e.getMessage(); - if (message == null) { - message = EMPTY_STRING; - } - Activator.logError(message, e); - return 0; - } - - } - - @Override - public synchronized void initTrace(@Nullable IResource resource, @Nullable String path, @Nullable Class type) throws TmfTraceException { - super.initTrace(resource, path, type); - if (path == null) { - throw new TmfTraceException("No path has been specified."); //$NON-NLS-1$ - } - @SuppressWarnings("null") - @NonNull Path filePath = FileSystems.getDefault().getPath(path); - try { - fPcapFile = new PcapFile(filePath); - } catch (IOException | BadPcapFileException e) { - throw new TmfTraceException(e.getMessage(), e); - } - } - - @Override - public synchronized @Nullable PcapEvent parseEvent(@Nullable ITmfContext context) { - if (context == null) { - return null; - } - - long rank = context.getRank(); - PcapPacket packet = null; - PcapFile pcap = fPcapFile; - if (pcap == null) { - return null; - } - try { - pcap.seekPacket(rank); - packet = pcap.parseNextPacket(); - } catch (ClosedChannelException e) { - /* - * This is handled independently and happens when the user closes - * the trace while it is being parsed. It simply stops the parsing. - * No need to log a error. - */ - return null; - } catch (IOException | BadPcapFileException | BadPacketException e) { - String message = e.getMessage(); - if (message == null) { - message = EMPTY_STRING; - } - Activator.logError(message, e); - return null; - } - - if (packet == null) { - return null; - } - - // Generate an event from this packet and return it. - return PcapEventFactory.createEvent(packet, pcap, this); - - } - - @Override - public synchronized ITmfContext seekEvent(double ratio) { - long position; - PcapFile pcap = fPcapFile; - if (pcap == null) { - return new TmfContext(new TmfLongLocation(0), 0); - } - - try { - /* - * The ratio is between 0 and 1. We multiply it by the total number - * of packets to get the position. - */ - position = (long) (ratio * pcap.getTotalNbPackets()); - } catch (IOException | BadPcapFileException e) { - String message = e.getMessage(); - if (message == null) { - message = EMPTY_STRING; - } - Activator.logError(message, e); - return new TmfContext(new TmfLongLocation(0), 0); - } - TmfLongLocation loc = new TmfLongLocation(position); - return new TmfContext(loc, loc.getLocationInfo()); - } - - @Override - public synchronized ITmfContext seekEvent(@Nullable ITmfLocation location) { - TmfLongLocation loc = (TmfLongLocation) location; - if (loc == null) { - return new TmfContext(new TmfLongLocation(0)); - } - - return new TmfContext(loc, loc.getLocationInfo()); - } - - @Override - public IStatus validate(@Nullable IProject project, @Nullable String path) { - - // All validations are made when making a new pcap file. - if (path == null) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, EMPTY_STRING); - } - @SuppressWarnings("null") - @NonNull Path filePath = FileSystems.getDefault().getPath(path); - try (PcapFile file = new PcapFile(filePath)) { - } catch (IOException | BadPcapFileException e) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.toString()); - } - return new TraceValidationStatus(CONFIDENCE, Activator.PLUGIN_ID); - } - - @Override - public synchronized void dispose() { - super.dispose(); - PcapFile pcap = fPcapFile; - if (pcap == null) { - return; - } - try { - pcap.close(); - fPcapFile = null; - } catch (IOException e) { - String message = e.getMessage(); - if (message == null) { - message = EMPTY_STRING; - } - Activator.logError(message, e); - return; - } - } - - @Override - public synchronized Map getTraceProperties() { - PcapFile pcap = fPcapFile; - if (pcap == null) { - return EMPTY_MAP; - } - - ImmutableMap properties = fTraceProperties; - if (properties == null) { - @SuppressWarnings("null") - @NonNull ImmutableMap newProperties = ImmutableMap. builder() - .put(Messages.PcapTrace_Version, String.format("%d%c%d", pcap.getMajorVersion(), '.', pcap.getMinorVersion())) //$NON-NLS-1$ - .put(Messages.PcapTrace_TimeZoneCorrection, pcap.getTimeZoneCorrection() + " s") //$NON-NLS-1$ - .put(Messages.PcapTrace_TimestampAccuracy, String.valueOf(pcap.getTimeAccuracy())) - .put(Messages.PcapTrace_MaxSnapLength, pcap.getSnapLength() + " bytes") //$NON-NLS-1$ - .put(Messages.PcapTrace_LinkLayerHeaderType, LinkTypeHelper.toString((int) pcap.getDataLinkType()) + " (" + pcap.getDataLinkType() + ")") //$NON-NLS-1$ //$NON-NLS-2$ - .put(Messages.PcapTrace_FileEndianness, pcap.getByteOrder().toString()) - .build(); - fTraceProperties = newProperties; - return newProperties; - - } - - return properties; - } - - @Override - public void close() { - dispose(); - } -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/trace/messages.properties b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/trace/messages.properties deleted file mode 100644 index 9a390273ee..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/trace/messages.properties +++ /dev/null @@ -1,18 +0,0 @@ -############################################################################### -# Copyright (c) 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### - -PcapTrace_FileEndianness=File Endianness -PcapTrace_LinkLayerHeaderType=Link-Layer Header Type -PcapTrace_MaxSnapLength=Maximum Snapshot Length -PcapTrace_TimestampAccuracy=Timestamp Accuracy -PcapTrace_TimeZoneCorrection=Time Zone Correction -PcapTrace_Version=Version diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/trace/package-info.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/trace/package-info.java deleted file mode 100644 index 5740e6798c..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/trace/package-info.java +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ericsson - Initial API and implementation - *******************************************************************************/ - -@org.eclipse.jdt.annotation.NonNullByDefault -package org.eclipse.linuxtools.internal.tmf.pcap.core.trace; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/Messages.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/Messages.java deleted file mode 100644 index 88116c0bcd..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/Messages.java +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.core.util; - -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.osgi.util.NLS; - -@SuppressWarnings("javadoc") -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.tmf.pcap.core.util.messages"; //$NON-NLS-1$ - - public static @Nullable String PcapEventFactory_LinkType; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/PcapEventFactory.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/PcapEventFactory.java deleted file mode 100644 index ececebc641..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/PcapEventFactory.java +++ /dev/null @@ -1,133 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.core.util; - -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.internal.pcap.core.packet.Packet; -import org.eclipse.linuxtools.internal.pcap.core.protocol.PcapProtocol; -import org.eclipse.linuxtools.internal.pcap.core.protocol.pcap.PcapPacket; -import org.eclipse.linuxtools.internal.pcap.core.trace.PcapFile; -import org.eclipse.linuxtools.internal.pcap.core.util.LinkTypeHelper; -import org.eclipse.linuxtools.internal.pcap.core.util.PcapTimestampScale; -import org.eclipse.linuxtools.internal.tmf.pcap.core.event.PcapEvent; -import org.eclipse.linuxtools.internal.tmf.pcap.core.event.PcapEventField; -import org.eclipse.linuxtools.internal.tmf.pcap.core.event.PcapEventType; -import org.eclipse.linuxtools.internal.tmf.pcap.core.event.PcapRootEventField; -import org.eclipse.linuxtools.internal.tmf.pcap.core.trace.PcapTrace; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; - -/** - * Factory class that helps generating Pcap Events. - * - * @author Vincent Perot - */ -public class PcapEventFactory { - - private static final ITmfEventField[] EMPTY_FIELD_ARRAY = new ITmfEventField[0]; - private static final String EMPTY_STRING = ""; //$NON-NLS-1$ - - private static final Map fEventTypes = new HashMap<>(); - - private PcapEventFactory() { - } - - /** - * Method that create a PcapEvent from a packet. - * - * @param pcapPacket - * The packet to generate the event from. - * @param pcap - * The pcap file to which the packet belongs. - * @param trace - * The trace to which this packet belongs. - * @return The generated PcapEvent. - */ - public static @Nullable PcapEvent createEvent(PcapPacket pcapPacket, PcapFile pcap, PcapTrace trace) { - long rank = pcapPacket.getIndex(); - long timestamp = pcapPacket.getTimestamp(); - PcapTimestampScale scale = pcapPacket.getTimestampScale(); - ITmfTimestamp tmfTimestamp; - switch (scale) { - case MICROSECOND: - long us = trace.getTimestampTransform().transform(timestamp * 1000) / 1000; - tmfTimestamp = new TmfTimestamp(us, ITmfTimestamp.MICROSECOND_SCALE, (int) pcap.getTimeAccuracy()); - break; - case NANOSECOND: - long ns = trace.getTimestampTransform().transform(timestamp); - tmfTimestamp = new TmfTimestamp(ns, ITmfTimestamp.NANOSECOND_SCALE, (int) pcap.getTimeAccuracy()); - break; - default: - throw new IllegalArgumentException("The timestamp precision is not valid!"); //$NON-NLS-1$ - } - Path filePath = pcap.getPath().getFileName(); - @SuppressWarnings("null") // for .toString() - @NonNull String fileName = (filePath == null ? EMPTY_STRING : filePath.toString()); - - String dataLink = Messages.PcapEventFactory_LinkType + ':' + LinkTypeHelper.toString((int) pcapPacket.getPcapFile().getDataLinkType()); - - ITmfEventField[] fields = generatePacketFields(pcapPacket); - ITmfEventField field = new PcapRootEventField(EMPTY_STRING, fields, pcapPacket); - Packet packet = pcapPacket.getMostEcapsulatedPacket(); - if (!fEventTypes.containsKey(packet.getProtocol())) { - String typeIdString = PcapEventType.DEFAULT_PCAP_TYPE_ID + ':' + packet.getProtocol().getShortName(); - fEventTypes.put(packet.getProtocol(), new PcapEventType(typeIdString, null)); - } - TmfEventType eventType = fEventTypes.get(packet.getProtocol()); - if (eventType == null) { - eventType = new TmfEventType(); - } - return new PcapEvent(trace, rank, tmfTimestamp, dataLink, eventType, field, fileName, packet); - - } - - private static ITmfEventField[] generatePacketFields(Packet packet) { - // TODO This is SOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO slow. Must find a - // way to use less intermediate data structures. - List fieldList = new ArrayList<>(); - List subfieldList = new ArrayList<>(); - Packet localPacket = packet.getPacket(PcapProtocol.PCAP); - - while (localPacket != null) { - subfieldList.clear(); - for (Map.Entry entry : localPacket.getFields().entrySet()) { - - @SuppressWarnings("null") - @NonNull String key = entry.getKey(); - - @SuppressWarnings("null") - @NonNull String value = entry.getValue(); - subfieldList.add(new TmfEventField(key, value, null)); - } - ITmfEventField[] subfieldArray = subfieldList.toArray(new ITmfEventField[subfieldList.size()]); - fieldList.add(new PcapEventField(localPacket.getProtocol().getName(), EMPTY_STRING, subfieldArray, localPacket)); - localPacket = localPacket.getChildPacket(); - } - - ITmfEventField[] fieldArray = fieldList.toArray(new ITmfEventField[fieldList.size()]); - if (fieldArray == null) { - return EMPTY_FIELD_ARRAY; - } - return fieldArray; - } -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/ProtocolConversion.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/ProtocolConversion.java deleted file mode 100644 index 4fd5249e0d..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/ProtocolConversion.java +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.core.util; - -import org.eclipse.linuxtools.internal.pcap.core.protocol.PcapProtocol; -import org.eclipse.linuxtools.internal.tmf.pcap.core.protocol.TmfPcapProtocol; - -/** - * Helper class that allows the conversion between Protocol and TmfProtocol. - * This is only used by this project and thus is internal (not API). - * - * @author Vincent Perot - */ -public final class ProtocolConversion { - - private ProtocolConversion() {} - - /** - * Wrap a {@link PcapProtocol} into a {@link TmfPcapProtocol}. - * - * @param protocol - * The {@link PcapProtocol} to match - * @return The TmfProtocol - */ - public static TmfPcapProtocol wrap(PcapProtocol protocol) { - switch (protocol) { - case ETHERNET_II: - return TmfPcapProtocol.ETHERNET_II; - case IPV4: - return TmfPcapProtocol.IPV4; - case PCAP: - return TmfPcapProtocol.PCAP; - case TCP: - return TmfPcapProtocol.TCP; - case UDP: - return TmfPcapProtocol.UDP; - case UNKNOWN: - return TmfPcapProtocol.UNKNOWN; - default: - throw new IllegalArgumentException(); - } - } - - /** - * Unwrap a {@link TmfPcapProtocol} from a {@link PcapProtocol}. - * - * @param protocol - * The TmfProtocol - * @return The Protocol - */ - public static PcapProtocol unwrap(TmfPcapProtocol protocol) { - switch (protocol) { - case ETHERNET_II: - return PcapProtocol.ETHERNET_II; - case IPV4: - return PcapProtocol.IPV4; - case PCAP: - return PcapProtocol.PCAP; - case TCP: - return PcapProtocol.TCP; - case UDP: - return PcapProtocol.UDP; - case UNKNOWN: - return PcapProtocol.UNKNOWN; - default: - throw new IllegalArgumentException(); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/messages.properties b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/messages.properties deleted file mode 100644 index 5630ca0536..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/messages.properties +++ /dev/null @@ -1,13 +0,0 @@ -############################################################################### -# Copyright (c) 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### - -PcapEventFactory_LinkType=linktype diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/package-info.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/package-info.java deleted file mode 100644 index e209f6b2c7..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/linuxtools/internal/tmf/pcap/core/util/package-info.java +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ericsson - Initial API and implementation - *******************************************************************************/ - -@org.eclipse.jdt.annotation.NonNullByDefault -package org.eclipse.linuxtools.internal.tmf.pcap.core.util; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/Activator.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/Activator.java new file mode 100644 index 0000000000..e09fc7d4e6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/Activator.java @@ -0,0 +1,212 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.core; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; +import org.eclipse.jdt.annotation.Nullable; +import org.osgi.framework.BundleContext; + +/** + * Activator + *

+ * The activator class controls the plug-in life cycle + */ +public class Activator extends Plugin { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The plug-in ID + */ + public static final String PLUGIN_ID = "org.eclipse.linuxtools.tmf.pcap.core"; //$NON-NLS-1$ + + /** + * The shared instance + */ + private static @Nullable Activator fPlugin; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructor + */ + public Activator() { + setDefault(this); + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * Returns the TMF Core plug-in instance. + * + * @return the TMF Core plug-in instance. + */ + public static @Nullable Activator getDefault() { + return fPlugin; + } + + // Sets plug-in instance + private static void setDefault(@Nullable Activator plugin) { + fPlugin = plugin; + } + + // ------------------------------------------------------------------------ + // Plugin + // ------------------------------------------------------------------------ + + @Override + public void start(@Nullable BundleContext context) throws Exception { + super.start(context); + setDefault(this); + } + + @Override + public void stop(@Nullable BundleContext context) throws Exception { + setDefault(null); + super.stop(context); + } + + + // ------------------------------------------------------------------------ + // Log an IStatus + // ------------------------------------------------------------------------ + + /** + * Log an IStatus object directly + * + * @param status + * The status to log + */ + public static void log(IStatus status) { + Activator activator = fPlugin; + if (activator == null) { + return; + } + activator.getLog().log(status); + } + + // ------------------------------------------------------------------------ + // Log INFO + // ------------------------------------------------------------------------ + + /** + * Logs a message with severity INFO in the runtime log of the plug-in. + * + * @param message + * A message to log + */ + public static void logInfo(String message) { + Activator activator = fPlugin; + if (activator == null) { + return; + } + activator.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity INFO in the runtime log of the + * plug-in. + * + * @param message + * A message to log + * @param exception + * The corresponding exception + */ + public static void logInfo(String message, Throwable exception) { + Activator activator = fPlugin; + if (activator == null) { + return; + } + activator.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message, exception)); + } + + // ------------------------------------------------------------------------ + // Log WARNING + // ------------------------------------------------------------------------ + + /** + * Logs a message and exception with severity WARNING in the runtime log of + * the plug-in. + * + * @param message + * A message to log + */ + public static void logWarning(String message) { + Activator activator = fPlugin; + if (activator == null) { + return; + } + activator.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity WARNING in the runtime log of + * the plug-in. + * + * @param message + * A message to log + * @param exception + * The corresponding exception + */ + public static void logWarning(String message, Throwable exception) { + Activator activator = fPlugin; + if (activator == null) { + return; + } + activator.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message, exception)); + } + + // ------------------------------------------------------------------------ + // Log ERROR + // ------------------------------------------------------------------------ + + /** + * Logs a message and exception with severity ERROR in the runtime log of + * the plug-in. + * + * @param message + * A message to log + */ + public static void logError(String message) { + Activator activator = fPlugin; + if (activator == null) { + return; + } + activator.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity ERROR in the runtime log of + * the plug-in. + * + * @param message + * A message to log + * @param exception + * The corresponding exception + */ + public static void logError(String message, Throwable exception) { + Activator activator = fPlugin; + if (activator == null) { + return; + } + activator.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, exception)); + } +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/analysis/StreamListAnalysis.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/analysis/StreamListAnalysis.java new file mode 100644 index 0000000000..a1ba93ee4d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/analysis/StreamListAnalysis.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.core.analysis; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.internal.tmf.pcap.core.event.PcapEvent; +import org.eclipse.tracecompass.internal.tmf.pcap.core.event.TmfPacketStreamBuilder; +import org.eclipse.tracecompass.internal.tmf.pcap.core.protocol.TmfPcapProtocol; +import org.eclipse.tracecompass.internal.tmf.pcap.core.trace.PcapTrace; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; + +/** + * A pcap-specific analysis that parse an entire trace to find all the streams. + * + * @author Vincent Perot + */ +public class StreamListAnalysis extends TmfAbstractAnalysisModule { + + /** + * The Stream List analysis ID. + */ + public static final String ID = "org.eclipse.linuxtools.tmf.pcap.core.analysis.stream"; //$NON-NLS-1$ + + private @Nullable ITmfEventRequest fRequest; + private final Map fBuilders; + + /** + * The default constructor. It initializes all variables. + */ + public StreamListAnalysis() { + super(); + fBuilders = new HashMap<>(); + for (TmfPcapProtocol protocol : TmfPcapProtocol.values()) { + if (protocol.supportsStream()) { + fBuilders.put(protocol, new TmfPacketStreamBuilder(protocol)); + } + } + } + + @Override + public boolean canExecute(ITmfTrace trace) { + + // Trace is Pcap + if (trace instanceof PcapTrace) { + return true; + } + + // Trace is not a TmfExperiment + if (!(trace instanceof TmfExperiment)) { + return false; + } + + // Trace is TmfExperiment. Check if it has a PcapTrace. + TmfExperiment experiment = (TmfExperiment) trace; + ITmfTrace[] traces = experiment.getTraces(); + for (int i = 0; i < traces.length; i++) { + if (traces[i] instanceof PcapTrace) { + return true; + } + } + + // No Pcap :( + return false; + } + + @Override + protected boolean executeAnalysis(@Nullable IProgressMonitor monitor) throws TmfAnalysisException { + IProgressMonitor mon = (monitor == null ? new NullProgressMonitor() : monitor); + if (getTrace() == null) { + return false; + } + + ITmfEventRequest request = fRequest; + if ((request != null) && (!request.isCompleted())) { + request.cancel(); + } + + request = new TmfEventRequest(PcapEvent.class, + TmfTimeRange.ETERNITY, 0L, ITmfEventRequest.ALL_DATA, + ITmfEventRequest.ExecutionType.BACKGROUND) { + + @Override + public void handleData(ITmfEvent data) { + // Called for each event + super.handleData(data); + if (!(data instanceof PcapEvent)) { + return; + } + PcapEvent event = (PcapEvent) data; + for (TmfPcapProtocol protocol : fBuilders.keySet()) { + fBuilders.get(protocol).addEventToStream(event); + } + + } + }; + getTrace().sendRequest(request); + fRequest = request; + try { + request.waitForCompletion(); + } catch (InterruptedException e) { + // Request was canceled. + return false; + } + + return !mon.isCanceled() && !request.isCancelled() && !request.isFailed(); + + } + + @Override + protected void canceling() { + ITmfEventRequest req = fRequest; + if ((req != null) && (!req.isCompleted())) { + req.cancel(); + } + } + + /** + * Getter method that returns the packet builder associated to a particular + * protocol. + * + * @param protocol + * The specified protocol. + * @return The builder. + */ + public @Nullable TmfPacketStreamBuilder getBuilder(TmfPcapProtocol protocol) { + return fBuilders.get(protocol); + } + + /** + * Method that indicates if the analysis is still running or has finished. + * + * @return Whether the analysis is finished or not. + */ + public boolean isFinished() { + ITmfEventRequest req = fRequest; + if (req == null) { + return false; + } + return req.isCompleted(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/analysis/package-info.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/analysis/package-info.java new file mode 100644 index 0000000000..d6732b3af1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/analysis/package-info.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +@org.eclipse.jdt.annotation.NonNullByDefault +package org.eclipse.tracecompass.internal.tmf.pcap.core.analysis; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/Messages.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/Messages.java new file mode 100644 index 0000000000..f9ce624a2f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/Messages.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.core.event; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.osgi.util.NLS; + +@NonNullByDefault(false) +@SuppressWarnings("javadoc") +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.tmf.pcap.core.event.messages"; //$NON-NLS-1$ + + public static @Nullable String PcapEventType_DefaultContext; + public static @Nullable String PcapEventType_DefaultTypeID; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/PcapEvent.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/PcapEvent.java new file mode 100644 index 0000000000..3f549da202 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/PcapEvent.java @@ -0,0 +1,242 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.core.event; + +import java.nio.ByteBuffer; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.linuxtools.internal.pcap.core.packet.Packet; +import org.eclipse.linuxtools.internal.pcap.core.protocol.PcapProtocol; +import org.eclipse.tracecompass.internal.tmf.pcap.core.protocol.TmfPcapProtocol; +import org.eclipse.tracecompass.internal.tmf.pcap.core.util.ProtocolConversion; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +import com.google.common.collect.ImmutableList; + +/** + * Class that extends TmfEvent to allow TMF to use the packets from the parser. + * It is a simple TmfEvent that wraps a Packet. + * + * @author Vincent Perot + */ +public class PcapEvent extends TmfEvent { + + /** Packet Source Field ID */ + public static final String EVENT_FIELD_PACKET_SOURCE = ":packetsource:"; //$NON-NLS-1$ + /** Packet Destination Field ID */ + public static final String EVENT_FIELD_PACKET_DESTINATION = ":packetdestination:"; //$NON-NLS-1$ + /** Packet Protocol Field ID */ + public static final String EVENT_FIELD_PACKET_PROTOCOL = ":protocol:"; //$NON-NLS-1$ + + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + + private final Packet fPacket; + + /** + * Lazy-loaded field representing all the protocols in this event + */ + private transient @Nullable Collection fProtocols; + + /** + * Full constructor. + * + * @param trace + * the parent trace + * @param rank + * the event rank (in the trace) + * @param timestamp + * the event timestamp + * @param source + * the event source + * @param type + * the event type + * @param content + * the event content (payload) + * @param reference + * the event reference + * @param packet + * The packet contained in this event + */ + public PcapEvent(ITmfTrace trace, + long rank, + ITmfTimestamp timestamp, + String source, + TmfEventType type, + ITmfEventField content, + String reference, + Packet packet) { + + super(trace, rank, timestamp, source, type, content, reference); + fPacket = packet; + } + + /** + * Method that returns an immutable map containing all the fields of a + * packet at a certain protocol. For instance, to get the Source IP Address, + * use: + * event.getFields(TmfProtocol.IPV4).get("Source IP Address");.
+ * It returns null if the protocol is inexistent in the PcapEvent. + * + * @param protocol + * The specified protocol + * @return A map containing the fields. + */ + public @Nullable Map getFields(TmfPcapProtocol protocol) { + PcapProtocol p = ProtocolConversion.unwrap(protocol); + Packet packet = fPacket.getPacket(p); + if (packet == null) { + return null; + } + return packet.getFields(); + } + + /** + * Method that returns the payload at a certain protocol level. It returns + * null if the protocol is inexistent in the PcapEvent. + * + * @param protocol + * The specified protocol + * @return The payload as a ByteBuffer. + */ + public @Nullable ByteBuffer getPayload(TmfPcapProtocol protocol) { + PcapProtocol p = ProtocolConversion.unwrap(protocol); + Packet packet = fPacket.getPacket(p); + if (packet == null) { + return null; + } + return packet.getPayload(); + } + + /** + * Method that returns the source endpoint at a certain protocol level. It + * returns null if the protocol is inexistent in the PcapEvent. + * + * @param protocol + * The specified protocol + * @return The source endpoint. + */ + public @Nullable String getSourceEndpoint(TmfPcapProtocol protocol) { + PcapProtocol p = ProtocolConversion.unwrap(protocol); + Packet packet = fPacket.getPacket(p); + if (packet == null) { + return null; + } + return packet.getSourceEndpoint().toString(); + } + + /** + * Method that returns the destination endpoint at a certain protocol level. + * It returns null if the protocol is inexistent in the PcapEvent. + * + * @param protocol + * The specified protocol + * @return The destination endpoint. + */ + public @Nullable String getDestinationEndpoint(TmfPcapProtocol protocol) { + PcapProtocol p = ProtocolConversion.unwrap(protocol); + Packet packet = fPacket.getPacket(p); + if (packet == null) { + return null; + } + return packet.getDestinationEndpoint().toString(); + } + + /** + * Method that returns the most encapsulated protocol in this PcapEvent. If + * it is an unknown protocol, it returns the last known protocol. + * + * @return The most encapsulated TmfProtocol. + */ + public TmfPcapProtocol getMostEncapsulatedProtocol() { + return ProtocolConversion.wrap(fPacket.getMostEcapsulatedPacket().getProtocol()); + } + + /** + * Method that returns all the protocols in this PcapEvent. + * + * @return A list containing all the TmfProtocol. + */ + public Collection getProtocols() { + if (fProtocols != null) { + return fProtocols; + } + ImmutableList.Builder builder = new ImmutableList.Builder<>(); + Packet packet = fPacket; + + // Go to start. + while (packet != null && packet.getParentPacket() != null) { + packet = packet.getParentPacket(); + } + + if (packet == null) { + @SuppressWarnings("null") + @NonNull List emptyList = Collections.EMPTY_LIST; + fProtocols = emptyList; + return fProtocols; + } + // Go through all the packets and add them to list. + builder.add(ProtocolConversion.wrap(packet.getProtocol())); + while (packet != null && packet.getChildPacket() != null) { + packet = packet.getChildPacket(); + if (packet != null) { + builder.add(ProtocolConversion.wrap(packet.getProtocol())); + } + } + + @SuppressWarnings("null") + @NonNull ImmutableList immutableList = builder.build(); + fProtocols = immutableList; + return immutableList; + } + + /** + * Getter method that returns the packet. This is default visible since it + * is only used by tmf.pcap.core and thus should not be visible to other + * packages + * + * @return The packet. + */ + Packet getPacket() { + return fPacket; + } + + @Override + public String toString() { + return fPacket.getGlobalSummaryString(); + } + + /** + * Return the signification of the PcapEvent at a specific protocol level. + * + * @param protocol + * The specified protocol. + * @return The signification as a String. + */ + public String toString(TmfPcapProtocol protocol) { + PcapProtocol p = ProtocolConversion.unwrap(protocol); + Packet packet = fPacket.getPacket(p); + if (packet == null) { + return EMPTY_STRING; + } + return packet.getLocalSummaryString(); + } +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/PcapEventField.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/PcapEventField.java new file mode 100644 index 0000000000..308a501cc7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/PcapEventField.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.core.event; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.linuxtools.internal.pcap.core.packet.Packet; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; + +/** + * Class that represents a TMF Pcap Event Field. It is identical to a + * TmfEventField, except that it overrides the toString() method. + * + * @author Vincent Perot + */ +public class PcapEventField extends TmfEventField { + + private final String fSummaryString; + + /** + * Full constructor + * + * @param name + * The event field id. + * @param value + * The event field value. + * @param fields + * The list of subfields. + * @param packet + * The packet from which to take the fields from. + * @throws IllegalArgumentException + * If 'name' is null, or if 'fields' has duplicate field names. + */ + public PcapEventField(String name, Object value, @Nullable ITmfEventField[] fields, Packet packet) { + super(name, value, fields); + fSummaryString = packet.getLocalSummaryString(); + } + + /** + * Copy constructor + * + * @param field + * the other event field + */ + public PcapEventField(final PcapEventField field) { + super(field); + fSummaryString = field.fSummaryString; + } + + @Override + public String toString() { + return fSummaryString; + } +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/PcapEventType.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/PcapEventType.java new file mode 100644 index 0000000000..e232d53b63 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/PcapEventType.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.core.event; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; + +/** + * Class that represents the type of a PcapEvent. + * + * @author Vincent Perot + */ +public class PcapEventType extends TmfEventType { + + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + + /** + * The default Context ID for a PcapEvent + */ + @SuppressWarnings("null") + public static final @NonNull String DEFAULT_PCAP_CONTEXT_ID = Messages.PcapEventType_DefaultContext == null ? EMPTY_STRING : Messages.PcapEventType_DefaultContext; + + /** + * The default Pcap Type ID for a PcapEvent + */ + @SuppressWarnings("null") + public static final @NonNull String DEFAULT_PCAP_TYPE_ID = Messages.PcapEventType_DefaultTypeID == null ? EMPTY_STRING : Messages.PcapEventType_DefaultTypeID; + + /** + * Default constructor + */ + public PcapEventType() { + this(DEFAULT_PCAP_TYPE_ID, null); + } + + /** + * Full constructor + * + * @param typeId + * the type name + * @param root + * the root field + */ + public PcapEventType(final String typeId, final @Nullable ITmfEventField root) { + super(DEFAULT_PCAP_CONTEXT_ID, typeId, root); + } + + /** + * Copy constructor + * + * @param type + * the other type + */ + public PcapEventType(final PcapEventType type) { + super(type); + } + + @Override + public @Nullable String toString() { + return getName(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/PcapRootEventField.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/PcapRootEventField.java new file mode 100644 index 0000000000..2b2570d3a6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/PcapRootEventField.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.core.event; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.linuxtools.internal.pcap.core.packet.Packet; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; + +/** + * Class that represents the root node of Pcap Event Field. + * + * @author Vincent Perot + */ +public class PcapRootEventField extends TmfEventField { + + private final TmfEventField fPacketSourceField; + private final TmfEventField fPacketDestinationField; + private final TmfEventField fProtocolField; + private final String fSummaryString; + + /** + * Full constructor + * + * @param value + * The event field value. + * @param fields + * The list of subfields. + * @param packet + * The packet from which to take the fields from. + * @throws IllegalArgumentException + * If 'name' is null, or if 'fields' has duplicate field names. + */ + public PcapRootEventField(Object value, @Nullable ITmfEventField[] fields, Packet packet) { + super(ITmfEventField.ROOT_FIELD_ID, value, fields); + fPacketSourceField = new TmfEventField(PcapEvent.EVENT_FIELD_PACKET_SOURCE, + packet.getMostEcapsulatedPacket().getSourceEndpoint().toString(), null); + fPacketDestinationField = new TmfEventField(PcapEvent.EVENT_FIELD_PACKET_DESTINATION, + packet.getMostEcapsulatedPacket().getDestinationEndpoint().toString(), null); + fProtocolField = new TmfEventField(PcapEvent.EVENT_FIELD_PACKET_PROTOCOL, + packet.getMostEcapsulatedPacket().getProtocol().getShortName().toUpperCase(), null); + fSummaryString = packet.getGlobalSummaryString(); + } + + /** + * Copy constructor + * + * @param field + * the other event field + */ + public PcapRootEventField(final PcapRootEventField field) { + super(field); + fPacketSourceField = field.fPacketSourceField; + fPacketDestinationField = field.fPacketDestinationField; + fProtocolField = field.fProtocolField; + fSummaryString = field.fSummaryString; + } + + @Override + public String toString() { + return fSummaryString; + } + + @Override + public @Nullable ITmfEventField getField(@Nullable String name) { + if (name == null) { + return null; + } + switch (name) { + case PcapEvent.EVENT_FIELD_PACKET_SOURCE: + return fPacketSourceField; + case PcapEvent.EVENT_FIELD_PACKET_DESTINATION: + return fPacketDestinationField; + case PcapEvent.EVENT_FIELD_PACKET_PROTOCOL: + return fProtocolField; + default: + return super.getField(name); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/TmfPacketStream.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/TmfPacketStream.java new file mode 100644 index 0000000000..cc4a1156e9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/TmfPacketStream.java @@ -0,0 +1,175 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.core.event; + +import org.eclipse.linuxtools.internal.pcap.core.stream.PacketStream; +import org.eclipse.tracecompass.internal.tmf.pcap.core.protocol.TmfPcapProtocol; +import org.eclipse.tracecompass.internal.tmf.pcap.core.util.ProtocolConversion; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; + +/** + * Class that wraps a Packet Stream. + * + * @author Vincent Perot + */ +public class TmfPacketStream { + + private final PacketStream fPacketStream; + + /** + * Class constructor. + * + * @param stream + * The stream to build the TmfPacketStream from. + */ + public TmfPacketStream(PacketStream stream) { + fPacketStream = stream; + } + + /** + * Method that returns the first endpoint of the packet stream. + * + * @return The first endpoint. + */ + public String getFirstEndpoint() { + return fPacketStream.getEndpointPair().getFirstEndpoint().toString(); + } + + /** + * Method that returns the second endpoint of the packet stream. + * + * @return The second endpoint. + */ + public String getSecondEndpoint() { + return fPacketStream.getEndpointPair().getSecondEndpoint().toString(); + } + + /** + * Method that returns the ID of the packet stream. + * + * @return The ID of the packet stream. + */ + public int getID() { + return fPacketStream.getID(); + } + + /** + * Method that returns the TmfProtocol of the packet stream. + * + * @return The TmfProtocol of the packet stream. + */ + public TmfPcapProtocol getProtocol() { + return ProtocolConversion.wrap(fPacketStream.getProtocol()); + } + + /** + * Get the number of packets going from the first endpoint to the second. + * + * @return The number of packets from A to B. + */ + public synchronized long getNbPacketsAtoB() { + return fPacketStream.getNbPacketsAtoB(); + } + + /** + * Get the number of packets going from the second endpoint to the first. + * + * @return The number of packets from B to A. + */ + public synchronized long getNbPacketsBtoA() { + return fPacketStream.getNbPacketsBtoA(); + } + + /** + * Get the total number of packets in this stream. + * + * @return The total number of packets. + */ + public synchronized long getNbPackets() { + return fPacketStream.getNbPackets(); + } + + /** + * Get the number of bytes going from the first endpoint to the second. + * + * @return The number of bytes from A to B. + */ + public synchronized long getNbBytesAtoB() { + return fPacketStream.getNbBytesAtoB(); + } + + /** + * Get the number of bytes going from the second endpoint to the first. + * + * @return The number of bytes from B to A. + */ + public synchronized long getNbBytesBtoA() { + return fPacketStream.getNbBytesBtoA(); + } + + /** + * Get the total number of bytes in this stream. + * + * @return The total number of bytes. + */ + public synchronized long getNbBytes() { + return fPacketStream.getNbBytes(); + } + + /** + * Get the start time of this stream. + * + * @return The start time. + */ + public synchronized ITmfTimestamp getStartTime() { + return new TmfTimestamp(fPacketStream.getStartTime(), ITmfTimestamp.NANOSECOND_SCALE); + } + + /** + * Get the stop time of this stream. + * + * @return The stop time. + */ + public synchronized ITmfTimestamp getStopTime() { + return new TmfTimestamp(fPacketStream.getStopTime(), ITmfTimestamp.NANOSECOND_SCALE); + } + + /** + * Get the duration of this stream, in seconds + * + * @return The duration of this stream. + */ + public synchronized double getDuration() { + return fPacketStream.getDuration(); + } + + /** + * Get the the average byte per second from A to B. + * + * @return the average byte per second from A to B. + */ + public synchronized double getBPSAtoB() { + return fPacketStream.getBPSAtoB(); + } + + /** + * Get the the average byte per second from B to A. + * + * @return the average byte per second from B to A. + */ + public synchronized double getBPSBtoA() { + return fPacketStream.getBPSBtoA(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/TmfPacketStreamBuilder.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/TmfPacketStreamBuilder.java new file mode 100644 index 0000000000..2eacbf7abc --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/TmfPacketStreamBuilder.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.core.event; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.linuxtools.internal.pcap.core.packet.Packet; +import org.eclipse.linuxtools.internal.pcap.core.protocol.PcapProtocol; +import org.eclipse.linuxtools.internal.pcap.core.protocol.pcap.PcapPacket; +import org.eclipse.linuxtools.internal.pcap.core.stream.PacketStream; +import org.eclipse.linuxtools.internal.pcap.core.stream.PacketStreamBuilder; +import org.eclipse.tracecompass.internal.tmf.pcap.core.protocol.TmfPcapProtocol; +import org.eclipse.tracecompass.internal.tmf.pcap.core.util.ProtocolConversion; + +/** + * Class that wraps a PacketStreamBuilder. + * + * @author Vincent Perot + */ +public class TmfPacketStreamBuilder { + + private final PacketStreamBuilder fBuilder; + + /** + * Constructor. + * + * @param protocol + * The protocol of the streams to build. + */ + public TmfPacketStreamBuilder(TmfPcapProtocol protocol) { + fBuilder = new PacketStreamBuilder(ProtocolConversion.unwrap(protocol)); + } + + /** + * Method that adds an event to this builder. + * + * @param event + * The event to add. + */ + public synchronized void addEventToStream(PcapEvent event) { + Packet packet = event.getPacket().getPacket(PcapProtocol.PCAP); + if (packet == null || !(packet instanceof PcapPacket)) { + return; + } + PcapPacket pcapPacket = (PcapPacket) packet; + fBuilder.addPacketToStream(pcapPacket); + } + + /** + * Method that returns the number of streams built. + * + * @return The number of streams built. + */ + public synchronized int getNbStreams() { + return fBuilder.getNbStreams(); + } + + /** + * Method that returns an iterable on the streams built so far. + * + * @return An iterable on the streams. + */ + public synchronized Iterable getStreams() { + // We can't store in immutable list since the stream number/content can + // change dynamically. + List list = new ArrayList<>(); + for (PacketStream stream : fBuilder.getStreams()) { + if (stream != null) { + list.add(new TmfPacketStream(stream)); + } + } + return list; + } + +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/messages.properties b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/messages.properties new file mode 100644 index 0000000000..fcf8ca253a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/messages.properties @@ -0,0 +1,14 @@ +############################################################################### +# Copyright (c) 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### + +PcapEventType_DefaultContext=Network/Pcap Event +PcapEventType_DefaultTypeID=packet diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/package-info.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/package-info.java new file mode 100644 index 0000000000..e50a3db975 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/event/package-info.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +@org.eclipse.jdt.annotation.NonNullByDefault +package org.eclipse.tracecompass.internal.tmf.pcap.core.event; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/package-info.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/package-info.java new file mode 100644 index 0000000000..3216bffdce --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/package-info.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +@org.eclipse.jdt.annotation.NonNullByDefault +package org.eclipse.tracecompass.internal.tmf.pcap.core; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/protocol/TmfPcapProtocol.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/protocol/TmfPcapProtocol.java new file mode 100644 index 0000000000..9a249da160 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/protocol/TmfPcapProtocol.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.core.protocol; + +import org.eclipse.linuxtools.internal.pcap.core.protocol.PcapProtocol; + +/** + * Enumeration as a TMF wrapper of the different Protocols. To register a + * protocol in TMF, it must be present in + * org.eclipse.linuxtools.pcap.core.protocol.Protocol and must have the same + * name. + * + * @author Vincent Perot + */ +public enum TmfPcapProtocol { + + // Layer 0 + /** + * The Pcap Protocol is not a real protocol but is used as an helper to + * generate Pcap packets. + */ + PCAP(PcapProtocol.PCAP), + + // Layer 1 + // Should always be empty. + + // Layer 2 + /** + * The description of the Ethernet II Protocol. + */ + ETHERNET_II(PcapProtocol.ETHERNET_II), + + // Layer 3 + /** + * The description of the Internet Protocol Version 4. + */ + IPV4(PcapProtocol.IPV4), + + // Layer 4 + /** + * The description of the Transmission Control Protocol. + */ + TCP(PcapProtocol.TCP), + /** + * The description of the User Datagram Protocol. + */ + UDP(PcapProtocol.UDP), + + // Layer 5 + + // Layer 6 + + // Layer 7 + /** + * This protocol is used as an helper if the protocol of a packet is not + * recognized. Since all its data goes into payload, it can also be seen as + * a "payload packet". This is considered to be on layer 7 since its always + * the most encapsulated packet if present. + */ + UNKNOWN(PcapProtocol.UNKNOWN); + + private final String fName; + private final String fShortName; + private final boolean fSupportsStream; + + private TmfPcapProtocol(PcapProtocol pcapProto) { + fName = pcapProto.getName(); + fShortName = pcapProto.getShortName(); + fSupportsStream = pcapProto.supportsStream(); + } + + /** + * Getter method for the long name of the protocol. + * + * @return The long name of the protocol, as a string. + */ + public String getName() { + return fName; + } + + /** + * Getter method for the short name of the protocol. + * + * @return The short name of the protocol, as a string. + */ + public String getShortName() { + return fShortName; + } + + /** + * Getter method that indicates if the protocol supports streams. + * + * @return Whether the protocol supports streams or not. + */ + public boolean supportsStream() { + return fSupportsStream; + } + +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/protocol/package-info.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/protocol/package-info.java new file mode 100644 index 0000000000..1e64e74a90 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/protocol/package-info.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +@org.eclipse.jdt.annotation.NonNullByDefault +package org.eclipse.tracecompass.internal.tmf.pcap.core.protocol; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/signal/TmfPacketStreamSelectedSignal.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/signal/TmfPacketStreamSelectedSignal.java new file mode 100644 index 0000000000..a1c142f389 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/signal/TmfPacketStreamSelectedSignal.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.core.signal; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.internal.tmf.pcap.core.event.TmfPacketStream; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignal; + +/** + * TmfSignal that is broadcasted when a new packet stream is chosen. Views that + * are network-specific can uses this signal to track when the user selects a + * new stream. + * + * @author Vincent Perot + */ +public class TmfPacketStreamSelectedSignal extends TmfSignal { + + private final @Nullable TmfPacketStream fStream; + + /** + * Standard constructor + * + * @param source + * Object sending this signal + * @param reference + * Reference index to assign to this signal + * @param stream + * The new stream. It can be null if the user cleared the + * selection. + */ + public TmfPacketStreamSelectedSignal(Object source, int reference, @Nullable TmfPacketStream stream) { + super(source, reference); + fStream = stream; + } + + /** + * Getter method that returns the stream. + * + * @return The stream. + */ + public @Nullable TmfPacketStream getStream() { + return fStream; + } +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/signal/package-info.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/signal/package-info.java new file mode 100644 index 0000000000..3433b23161 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/signal/package-info.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +@org.eclipse.jdt.annotation.NonNullByDefault +package org.eclipse.tracecompass.internal.tmf.pcap.core.signal; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/trace/Messages.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/trace/Messages.java new file mode 100644 index 0000000000..2b1b84492c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/trace/Messages.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.core.trace; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.osgi.util.NLS; + +@SuppressWarnings("javadoc") +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.tmf.pcap.core.trace.messages"; //$NON-NLS-1$ + + public static @Nullable String PcapTrace_FileEndianness; + public static @Nullable String PcapTrace_LinkLayerHeaderType; + public static @Nullable String PcapTrace_MaxSnapLength; + public static @Nullable String PcapTrace_TimestampAccuracy; + public static @Nullable String PcapTrace_TimeZoneCorrection; + public static @Nullable String PcapTrace_Version; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/trace/PcapTrace.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/trace/PcapTrace.java new file mode 100644 index 0000000000..80f6f00aca --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/trace/PcapTrace.java @@ -0,0 +1,251 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.core.trace; + +import java.io.IOException; +import java.nio.channels.ClosedChannelException; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.util.Map; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.linuxtools.internal.pcap.core.packet.BadPacketException; +import org.eclipse.linuxtools.internal.pcap.core.protocol.pcap.PcapPacket; +import org.eclipse.linuxtools.internal.pcap.core.trace.BadPcapFileException; +import org.eclipse.linuxtools.internal.pcap.core.trace.PcapFile; +import org.eclipse.linuxtools.internal.pcap.core.util.LinkTypeHelper; +import org.eclipse.tracecompass.internal.tmf.pcap.core.Activator; +import org.eclipse.tracecompass.internal.tmf.pcap.core.event.PcapEvent; +import org.eclipse.tracecompass.internal.tmf.pcap.core.util.PcapEventFactory; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfEventParser; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceProperties; +import org.eclipse.tracecompass.tmf.core.trace.TmfContext; +import org.eclipse.tracecompass.tmf.core.trace.TmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TraceValidationStatus; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; +import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; + +import com.google.common.collect.ImmutableMap; + +/** + * Class that represents a TMF Pcap Trace. It is used to make the glue between + * the Pcap parser and TMF. + * + * TODO handle fields in TmfEventType for the filter view. + * + * @author Vincent Perot + */ +public class PcapTrace extends TmfTrace implements ITmfEventParser, ITmfTraceProperties, AutoCloseable { + + @SuppressWarnings("null") + private static final @NonNull Map EMPTY_MAP = ImmutableMap.of(); + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + private static final int CONFIDENCE = 50; + private @Nullable PcapFile fPcapFile; + private @Nullable ImmutableMap fTraceProperties = null; + + @Override + public synchronized ITmfLocation getCurrentLocation() { + PcapFile pcap = fPcapFile; + if (pcap == null) { + return new TmfLongLocation(0); + } + return new TmfLongLocation(pcap.getCurrentRank()); + } + + @Override + public synchronized double getLocationRatio(@Nullable ITmfLocation location) { + TmfLongLocation loc = (TmfLongLocation) location; + PcapFile pcap = fPcapFile; + if (loc == null || pcap == null) { + return 0; + } + try { + return (pcap.getTotalNbPackets() == 0 ? 0 : ((double) loc.getLocationInfo()) / pcap.getTotalNbPackets()); + } catch (IOException | BadPcapFileException e) { + String message = e.getMessage(); + if (message == null) { + message = EMPTY_STRING; + } + Activator.logError(message, e); + return 0; + } + + } + + @Override + public synchronized void initTrace(@Nullable IResource resource, @Nullable String path, @Nullable Class type) throws TmfTraceException { + super.initTrace(resource, path, type); + if (path == null) { + throw new TmfTraceException("No path has been specified."); //$NON-NLS-1$ + } + @SuppressWarnings("null") + @NonNull Path filePath = FileSystems.getDefault().getPath(path); + try { + fPcapFile = new PcapFile(filePath); + } catch (IOException | BadPcapFileException e) { + throw new TmfTraceException(e.getMessage(), e); + } + } + + @Override + public synchronized @Nullable PcapEvent parseEvent(@Nullable ITmfContext context) { + if (context == null) { + return null; + } + + long rank = context.getRank(); + PcapPacket packet = null; + PcapFile pcap = fPcapFile; + if (pcap == null) { + return null; + } + try { + pcap.seekPacket(rank); + packet = pcap.parseNextPacket(); + } catch (ClosedChannelException e) { + /* + * This is handled independently and happens when the user closes + * the trace while it is being parsed. It simply stops the parsing. + * No need to log a error. + */ + return null; + } catch (IOException | BadPcapFileException | BadPacketException e) { + String message = e.getMessage(); + if (message == null) { + message = EMPTY_STRING; + } + Activator.logError(message, e); + return null; + } + + if (packet == null) { + return null; + } + + // Generate an event from this packet and return it. + return PcapEventFactory.createEvent(packet, pcap, this); + + } + + @Override + public synchronized ITmfContext seekEvent(double ratio) { + long position; + PcapFile pcap = fPcapFile; + if (pcap == null) { + return new TmfContext(new TmfLongLocation(0), 0); + } + + try { + /* + * The ratio is between 0 and 1. We multiply it by the total number + * of packets to get the position. + */ + position = (long) (ratio * pcap.getTotalNbPackets()); + } catch (IOException | BadPcapFileException e) { + String message = e.getMessage(); + if (message == null) { + message = EMPTY_STRING; + } + Activator.logError(message, e); + return new TmfContext(new TmfLongLocation(0), 0); + } + TmfLongLocation loc = new TmfLongLocation(position); + return new TmfContext(loc, loc.getLocationInfo()); + } + + @Override + public synchronized ITmfContext seekEvent(@Nullable ITmfLocation location) { + TmfLongLocation loc = (TmfLongLocation) location; + if (loc == null) { + return new TmfContext(new TmfLongLocation(0)); + } + + return new TmfContext(loc, loc.getLocationInfo()); + } + + @Override + public IStatus validate(@Nullable IProject project, @Nullable String path) { + + // All validations are made when making a new pcap file. + if (path == null) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, EMPTY_STRING); + } + @SuppressWarnings("null") + @NonNull Path filePath = FileSystems.getDefault().getPath(path); + try (PcapFile file = new PcapFile(filePath)) { + } catch (IOException | BadPcapFileException e) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.toString()); + } + return new TraceValidationStatus(CONFIDENCE, Activator.PLUGIN_ID); + } + + @Override + public synchronized void dispose() { + super.dispose(); + PcapFile pcap = fPcapFile; + if (pcap == null) { + return; + } + try { + pcap.close(); + fPcapFile = null; + } catch (IOException e) { + String message = e.getMessage(); + if (message == null) { + message = EMPTY_STRING; + } + Activator.logError(message, e); + return; + } + } + + @Override + public synchronized Map getTraceProperties() { + PcapFile pcap = fPcapFile; + if (pcap == null) { + return EMPTY_MAP; + } + + ImmutableMap properties = fTraceProperties; + if (properties == null) { + @SuppressWarnings("null") + @NonNull ImmutableMap newProperties = ImmutableMap. builder() + .put(Messages.PcapTrace_Version, String.format("%d%c%d", pcap.getMajorVersion(), '.', pcap.getMinorVersion())) //$NON-NLS-1$ + .put(Messages.PcapTrace_TimeZoneCorrection, pcap.getTimeZoneCorrection() + " s") //$NON-NLS-1$ + .put(Messages.PcapTrace_TimestampAccuracy, String.valueOf(pcap.getTimeAccuracy())) + .put(Messages.PcapTrace_MaxSnapLength, pcap.getSnapLength() + " bytes") //$NON-NLS-1$ + .put(Messages.PcapTrace_LinkLayerHeaderType, LinkTypeHelper.toString((int) pcap.getDataLinkType()) + " (" + pcap.getDataLinkType() + ")") //$NON-NLS-1$ //$NON-NLS-2$ + .put(Messages.PcapTrace_FileEndianness, pcap.getByteOrder().toString()) + .build(); + fTraceProperties = newProperties; + return newProperties; + + } + + return properties; + } + + @Override + public void close() { + dispose(); + } +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/trace/messages.properties b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/trace/messages.properties new file mode 100644 index 0000000000..9a390273ee --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/trace/messages.properties @@ -0,0 +1,18 @@ +############################################################################### +# Copyright (c) 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### + +PcapTrace_FileEndianness=File Endianness +PcapTrace_LinkLayerHeaderType=Link-Layer Header Type +PcapTrace_MaxSnapLength=Maximum Snapshot Length +PcapTrace_TimestampAccuracy=Timestamp Accuracy +PcapTrace_TimeZoneCorrection=Time Zone Correction +PcapTrace_Version=Version diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/trace/package-info.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/trace/package-info.java new file mode 100644 index 0000000000..5c651a05dc --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/trace/package-info.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +@org.eclipse.jdt.annotation.NonNullByDefault +package org.eclipse.tracecompass.internal.tmf.pcap.core.trace; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/Messages.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/Messages.java new file mode 100644 index 0000000000..50bc090c3f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/Messages.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.core.util; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.osgi.util.NLS; + +@SuppressWarnings("javadoc") +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.tmf.pcap.core.util.messages"; //$NON-NLS-1$ + + public static @Nullable String PcapEventFactory_LinkType; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/PcapEventFactory.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/PcapEventFactory.java new file mode 100644 index 0000000000..e926de329f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/PcapEventFactory.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.core.util; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.linuxtools.internal.pcap.core.packet.Packet; +import org.eclipse.linuxtools.internal.pcap.core.protocol.PcapProtocol; +import org.eclipse.linuxtools.internal.pcap.core.protocol.pcap.PcapPacket; +import org.eclipse.linuxtools.internal.pcap.core.trace.PcapFile; +import org.eclipse.linuxtools.internal.pcap.core.util.LinkTypeHelper; +import org.eclipse.linuxtools.internal.pcap.core.util.PcapTimestampScale; +import org.eclipse.tracecompass.internal.tmf.pcap.core.event.PcapEvent; +import org.eclipse.tracecompass.internal.tmf.pcap.core.event.PcapEventField; +import org.eclipse.tracecompass.internal.tmf.pcap.core.event.PcapEventType; +import org.eclipse.tracecompass.internal.tmf.pcap.core.event.PcapRootEventField; +import org.eclipse.tracecompass.internal.tmf.pcap.core.trace.PcapTrace; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; + +/** + * Factory class that helps generating Pcap Events. + * + * @author Vincent Perot + */ +public class PcapEventFactory { + + private static final ITmfEventField[] EMPTY_FIELD_ARRAY = new ITmfEventField[0]; + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + + private static final Map fEventTypes = new HashMap<>(); + + private PcapEventFactory() { + } + + /** + * Method that create a PcapEvent from a packet. + * + * @param pcapPacket + * The packet to generate the event from. + * @param pcap + * The pcap file to which the packet belongs. + * @param trace + * The trace to which this packet belongs. + * @return The generated PcapEvent. + */ + public static @Nullable PcapEvent createEvent(PcapPacket pcapPacket, PcapFile pcap, PcapTrace trace) { + long rank = pcapPacket.getIndex(); + long timestamp = pcapPacket.getTimestamp(); + PcapTimestampScale scale = pcapPacket.getTimestampScale(); + ITmfTimestamp tmfTimestamp; + switch (scale) { + case MICROSECOND: + long us = trace.getTimestampTransform().transform(timestamp * 1000) / 1000; + tmfTimestamp = new TmfTimestamp(us, ITmfTimestamp.MICROSECOND_SCALE, (int) pcap.getTimeAccuracy()); + break; + case NANOSECOND: + long ns = trace.getTimestampTransform().transform(timestamp); + tmfTimestamp = new TmfTimestamp(ns, ITmfTimestamp.NANOSECOND_SCALE, (int) pcap.getTimeAccuracy()); + break; + default: + throw new IllegalArgumentException("The timestamp precision is not valid!"); //$NON-NLS-1$ + } + Path filePath = pcap.getPath().getFileName(); + @SuppressWarnings("null") // for .toString() + @NonNull String fileName = (filePath == null ? EMPTY_STRING : filePath.toString()); + + String dataLink = Messages.PcapEventFactory_LinkType + ':' + LinkTypeHelper.toString((int) pcapPacket.getPcapFile().getDataLinkType()); + + ITmfEventField[] fields = generatePacketFields(pcapPacket); + ITmfEventField field = new PcapRootEventField(EMPTY_STRING, fields, pcapPacket); + Packet packet = pcapPacket.getMostEcapsulatedPacket(); + if (!fEventTypes.containsKey(packet.getProtocol())) { + String typeIdString = PcapEventType.DEFAULT_PCAP_TYPE_ID + ':' + packet.getProtocol().getShortName(); + fEventTypes.put(packet.getProtocol(), new PcapEventType(typeIdString, null)); + } + TmfEventType eventType = fEventTypes.get(packet.getProtocol()); + if (eventType == null) { + eventType = new TmfEventType(); + } + return new PcapEvent(trace, rank, tmfTimestamp, dataLink, eventType, field, fileName, packet); + + } + + private static ITmfEventField[] generatePacketFields(Packet packet) { + // TODO This is SOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO slow. Must find a + // way to use less intermediate data structures. + List fieldList = new ArrayList<>(); + List subfieldList = new ArrayList<>(); + Packet localPacket = packet.getPacket(PcapProtocol.PCAP); + + while (localPacket != null) { + subfieldList.clear(); + for (Map.Entry entry : localPacket.getFields().entrySet()) { + + @SuppressWarnings("null") + @NonNull String key = entry.getKey(); + + @SuppressWarnings("null") + @NonNull String value = entry.getValue(); + subfieldList.add(new TmfEventField(key, value, null)); + } + ITmfEventField[] subfieldArray = subfieldList.toArray(new ITmfEventField[subfieldList.size()]); + fieldList.add(new PcapEventField(localPacket.getProtocol().getName(), EMPTY_STRING, subfieldArray, localPacket)); + localPacket = localPacket.getChildPacket(); + } + + ITmfEventField[] fieldArray = fieldList.toArray(new ITmfEventField[fieldList.size()]); + if (fieldArray == null) { + return EMPTY_FIELD_ARRAY; + } + return fieldArray; + } +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/ProtocolConversion.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/ProtocolConversion.java new file mode 100644 index 0000000000..136bbfeb4c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/ProtocolConversion.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.core.util; + +import org.eclipse.linuxtools.internal.pcap.core.protocol.PcapProtocol; +import org.eclipse.tracecompass.internal.tmf.pcap.core.protocol.TmfPcapProtocol; + +/** + * Helper class that allows the conversion between Protocol and TmfProtocol. + * This is only used by this project and thus is internal (not API). + * + * @author Vincent Perot + */ +public final class ProtocolConversion { + + private ProtocolConversion() {} + + /** + * Wrap a {@link PcapProtocol} into a {@link TmfPcapProtocol}. + * + * @param protocol + * The {@link PcapProtocol} to match + * @return The TmfProtocol + */ + public static TmfPcapProtocol wrap(PcapProtocol protocol) { + switch (protocol) { + case ETHERNET_II: + return TmfPcapProtocol.ETHERNET_II; + case IPV4: + return TmfPcapProtocol.IPV4; + case PCAP: + return TmfPcapProtocol.PCAP; + case TCP: + return TmfPcapProtocol.TCP; + case UDP: + return TmfPcapProtocol.UDP; + case UNKNOWN: + return TmfPcapProtocol.UNKNOWN; + default: + throw new IllegalArgumentException(); + } + } + + /** + * Unwrap a {@link TmfPcapProtocol} from a {@link PcapProtocol}. + * + * @param protocol + * The TmfProtocol + * @return The Protocol + */ + public static PcapProtocol unwrap(TmfPcapProtocol protocol) { + switch (protocol) { + case ETHERNET_II: + return PcapProtocol.ETHERNET_II; + case IPV4: + return PcapProtocol.IPV4; + case PCAP: + return PcapProtocol.PCAP; + case TCP: + return PcapProtocol.TCP; + case UDP: + return PcapProtocol.UDP; + case UNKNOWN: + return PcapProtocol.UNKNOWN; + default: + throw new IllegalArgumentException(); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/messages.properties b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/messages.properties new file mode 100644 index 0000000000..5630ca0536 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/messages.properties @@ -0,0 +1,13 @@ +############################################################################### +# Copyright (c) 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### + +PcapEventFactory_LinkType=linktype diff --git a/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/package-info.java b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/package-info.java new file mode 100644 index 0000000000..44a29fec52 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.core/src/org/eclipse/tracecompass/internal/tmf/pcap/core/util/package-info.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +@org.eclipse.jdt.annotation.NonNullByDefault +package org.eclipse.tracecompass.internal.tmf.pcap.core.util; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/META-INF/MANIFEST.MF b/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/META-INF/MANIFEST.MF index 0355056977..eb39bfa839 100644 --- a/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/META-INF/MANIFEST.MF @@ -7,7 +7,7 @@ Bundle-Localization: plugin Bundle-SymbolicName: org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests;singleton:=true Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.7 -Export-Package: org.eclipse.linuxtools.tmf.pcap.ui.swtbot.tests +Export-Package: org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests Require-Bundle: org.apache.log4j, org.eclipse.core.resources, org.eclipse.core.runtime, diff --git a/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/pom.xml b/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/pom.xml index 222217f599..c3fc954a4c 100644 --- a/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/pom.xml +++ b/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/pom.xml @@ -33,7 +33,7 @@ ${tycho-version} org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests - org.eclipse.linuxtools.tmf.pcap.ui.swtbot.tests.AllTests + org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests.AllTests true false ${tycho.testArgLine} ${base.ui.test.vmargs} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/pcap/ui/swtbot/tests/AllTests.java b/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/pcap/ui/swtbot/tests/AllTests.java deleted file mode 100644 index 35c51ec78f..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/pcap/ui/swtbot/tests/AllTests.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.pcap.ui.swtbot.tests; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite for UI on the PCAP parser and networking perspective - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - ImportAndReadPcapTest.class, - NetworkPerspectiveChecker.class -}) -public class AllTests { -} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/pcap/ui/swtbot/tests/ImportAndReadPcapTest.java b/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/pcap/ui/swtbot/tests/ImportAndReadPcapTest.java deleted file mode 100644 index 232cf868b3..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/pcap/ui/swtbot/tests/ImportAndReadPcapTest.java +++ /dev/null @@ -1,269 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.pcap.ui.swtbot.tests; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeTrue; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.apache.log4j.ConsoleAppender; -import org.apache.log4j.Logger; -import org.apache.log4j.SimpleLayout; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.pcap.core.tests.shared.PcapTmfTestTrace; -import org.eclipse.linuxtools.internal.tmf.pcap.core.trace.PcapTrace; -import org.eclipse.linuxtools.internal.tmf.pcap.ui.NetworkingPerspectiveFactory; -import org.eclipse.linuxtools.internal.tmf.pcap.ui.stream.StreamListView; -import org.eclipse.linuxtools.tmf.ui.editors.TmfEventsEditor; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfOpenTraceHelper; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.linuxtools.tmf.ui.swtbot.tests.SWTBotUtil; -import org.eclipse.linuxtools.tmf.ui.swtbot.tests.conditions.ConditionHelpers; -import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; -import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; -import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; -import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; -import org.eclipse.swtbot.swt.finder.results.BoolResult; -import org.eclipse.swtbot.swt.finder.results.VoidResult; -import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IEditorReference; -import org.eclipse.ui.IViewPart; -import org.eclipse.ui.IViewReference; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.WorkbenchException; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * SWTBot Smoke test for Pcap UI. - * - * @author Matthew Khouzam - */ -@RunWith(SWTBotJunit4ClassRunner.class) -public class ImportAndReadPcapTest { - - private static final String NETWORK_PERSPECTIVE_ID = NetworkingPerspectiveFactory.ID; - private static final String TRACE_PROJECT_NAME = "test"; - - private static SWTWorkbenchBot fBot; - private ITmfEvent fDesired1; - private static PcapTmfTestTrace pttt = PcapTmfTestTrace.BENCHMARK_TRACE; - - /** The Log4j logger instance. */ - private static final Logger fLogger = Logger.getRootLogger(); - - /** - * Test Class setup - */ - @BeforeClass - public static void init() { - - SWTBotUtil.failIfUIThread(); - - /* set up for swtbot */ - SWTBotPreferences.TIMEOUT = 300000; /* 300 second timeout */ - fLogger.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender.SYSTEM_OUT)); - fBot = new SWTWorkbenchBot(); - - final List openViews = fBot.views(); - for (SWTBotView view : openViews) { - if (view.getTitle().equals("Welcome")) { - view.close(); - fBot.waitUntil(ConditionHelpers.ViewIsClosed(view)); - } - } - /* Switch perspectives */ - switchNetworkPerspective(); - /* Finish waiting for eclipse to load */ - SWTBotUtil.waitForJobs(); - } - - private static void switchNetworkPerspective() { - final Exception retE[] = new Exception[1]; - if (!UIThreadRunnable.syncExec(new BoolResult() { - @Override - public Boolean run() { - try { - PlatformUI.getWorkbench().showPerspective(NETWORK_PERSPECTIVE_ID, - PlatformUI.getWorkbench().getActiveWorkbenchWindow()); - } catch (WorkbenchException e) { - retE[0] = e; - return false; - } - return true; - } - })) { - fail(retE[0].getMessage()); - } - - } - - /** - * Main test case - */ - @Test - public void test() { - assumeTrue(pttt.exists()); - SWTBotUtil.createProject(TRACE_PROJECT_NAME); - openTrace(); - openEditor(); - testHV(getViewPart("Histogram")); - testStreamView(getViewPartRef("Stream List")); - fBot.closeAllEditors(); - SWTBotUtil.deleteProject(TRACE_PROJECT_NAME, fBot); - } - - private void testStreamView(IViewReference viewPart) { - SWTBotView botView = new SWTBotView(viewPart, fBot); - StreamListView slv = (StreamListView) getViewPart("Stream List"); - botView.setFocus(); - SWTBotTree botTree = fBot.tree(); - assertNotNull(botTree); - final TmfTimeSynchSignal signal = new TmfTimeSynchSignal(slv, fDesired1.getTimestamp()); - slv.broadcast(signal); - SWTBotUtil.waitForJobs(); - // FIXME This is a race condition: - // TmfEventsTable launches an async exec that may be run after the wait - // for jobs. This last delay catches it. - SWTBotUtil.delay(1000); - - } - - private static void openTrace() { - final Exception exception[] = new Exception[1]; - exception[0] = null; - UIThreadRunnable.syncExec(new VoidResult() { - @Override - public void run() { - try { - IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(TRACE_PROJECT_NAME); - TmfTraceFolder destinationFolder = TmfProjectRegistry.getProject(project, true).getTracesFolder(); - String absolutePath = (new File(pttt.getTrace().getPath())).getAbsolutePath(); - TmfOpenTraceHelper.openTraceFromPath(destinationFolder, absolutePath, PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "org.eclipse.linuxtools.tmf.pcap.core.pcaptrace"); - } catch (CoreException e) { - exception[0] = e; - } - } - }); - if (exception[0] != null) { - fail(exception[0].getMessage()); - } - - SWTBotUtil.delay(1000); - SWTBotUtil.waitForJobs(); - } - - private void openEditor() { - final List editorRefs = new ArrayList<>(); - UIThreadRunnable.syncExec(new VoidResult() { - @Override - public void run() { - IEditorReference[] ieds = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getEditorReferences(); - editorRefs.addAll(Arrays.asList(ieds)); - } - - }); - assertFalse(editorRefs.isEmpty()); - IEditorPart iep = null; - for (IEditorReference ied : editorRefs) { - if (ied.getTitle().equals(pttt.getTrace().getName())) { - iep = ied.getEditor(true); - break; - } - } - assertNotNull(iep); - fDesired1 = getEvent(100); - final TmfEventsEditor tmfEd = (TmfEventsEditor) iep; - UIThreadRunnable.syncExec(new VoidResult() { - @Override - public void run() { - tmfEd.setFocus(); - tmfEd.selectionChanged(new SelectionChangedEvent(tmfEd, new StructuredSelection(fDesired1))); - } - }); - - SWTBotUtil.waitForJobs(); - SWTBotUtil.delay(1000); - assertNotNull(tmfEd); - } - - private static void testHV(IViewPart vp) { - assertNotNull(vp); - } - - private static ITmfEvent getEvent(int rank) { - try (PcapTrace trace = pttt.getTrace()) { - ITmfContext ctx = trace.seekEvent(0); - for (int i = 0; i < rank; i++) { - trace.getNext(ctx); - } - return trace.getNext(ctx); - } - - } - - private static IViewPart getViewPart(final String viewTile) { - final IViewPart[] vps = new IViewPart[1]; - UIThreadRunnable.syncExec(new VoidResult() { - @Override - public void run() { - IViewReference[] viewRefs = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getViewReferences(); - for (IViewReference viewRef : viewRefs) { - IViewPart vp = viewRef.getView(true); - if (vp.getTitle().equals(viewTile)) { - vps[0] = vp; - return; - } - } - } - }); - - return vps[0]; - } - - private static IViewReference getViewPartRef(final String viewTile) { - final IViewReference[] vrs = new IViewReference[1]; - UIThreadRunnable.syncExec(new VoidResult() { - @Override - public void run() { - IViewReference[] viewRefs = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getViewReferences(); - for (IViewReference viewRef : viewRefs) { - IViewPart vp = viewRef.getView(true); - if (vp.getTitle().equals(viewTile)) { - vrs[0] = viewRef; - return; - } - } - } - }); - - return vrs[0]; - } -} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/pcap/ui/swtbot/tests/NetworkPerspectiveChecker.java b/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/pcap/ui/swtbot/tests/NetworkPerspectiveChecker.java deleted file mode 100644 index 5e8fb8efd9..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/pcap/ui/swtbot/tests/NetworkPerspectiveChecker.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.pcap.ui.swtbot.tests; - -import java.util.ArrayList; -import java.util.Arrays; - -import org.eclipse.linuxtools.internal.tmf.pcap.ui.NetworkingPerspectiveFactory; -import org.eclipse.linuxtools.internal.tmf.pcap.ui.stream.StreamListView; -import org.eclipse.linuxtools.tmf.ui.swtbot.tests.AbstractPerspectiveChecker; -import org.eclipse.linuxtools.tmf.ui.views.colors.ColorsView; -import org.eclipse.linuxtools.tmf.ui.views.filter.FilterView; -import org.eclipse.linuxtools.tmf.ui.views.histogram.HistogramView; -import org.eclipse.linuxtools.tmf.ui.views.statistics.TmfStatisticsView; -import org.eclipse.ui.IPageLayout; -import org.junit.Before; - -/** - * Tracing perspective view checker - * - * @author Matthew Khouzam - */ -public class NetworkPerspectiveChecker extends AbstractPerspectiveChecker { - - /** - * Set up arrays for test - */ - @Before - public void init() { - fPerspectiveId = NetworkingPerspectiveFactory.ID; - fViewIds = new ArrayList<>(); - fViewIds.addAll(Arrays.asList(new String[] { - // TMF views - HistogramView.ID, - TmfStatisticsView.ID, - FilterView.ID, - ColorsView.ID, - // PCAP - StreamListView.ID, - // Standard Eclipse views - IPageLayout.ID_PROJECT_EXPLORER, - IPageLayout.ID_PROP_SHEET, - IPageLayout.ID_BOOKMARKS - })); - } -} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/pcap/ui/swtbot/tests/AllTests.java b/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/pcap/ui/swtbot/tests/AllTests.java new file mode 100644 index 0000000000..2766171311 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/pcap/ui/swtbot/tests/AllTests.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for UI on the PCAP parser and networking perspective + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + ImportAndReadPcapTest.class, + NetworkPerspectiveChecker.class +}) +public class AllTests { +} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/pcap/ui/swtbot/tests/ImportAndReadPcapTest.java b/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/pcap/ui/swtbot/tests/ImportAndReadPcapTest.java new file mode 100644 index 0000000000..022bfd31b7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/pcap/ui/swtbot/tests/ImportAndReadPcapTest.java @@ -0,0 +1,269 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.log4j.ConsoleAppender; +import org.apache.log4j.Logger; +import org.apache.log4j.SimpleLayout; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; +import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; +import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; +import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; +import org.eclipse.swtbot.swt.finder.results.BoolResult; +import org.eclipse.swtbot.swt.finder.results.VoidResult; +import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; +import org.eclipse.tracecompass.internal.tmf.pcap.core.trace.PcapTrace; +import org.eclipse.tracecompass.internal.tmf.pcap.ui.NetworkingPerspectiveFactory; +import org.eclipse.tracecompass.internal.tmf.pcap.ui.stream.StreamListView; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.pcap.core.tests.shared.PcapTmfTestTrace; +import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfOpenTraceHelper; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.tracecompass.tmf.ui.swtbot.tests.SWTBotUtil; +import org.eclipse.tracecompass.tmf.ui.swtbot.tests.conditions.ConditionHelpers; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.WorkbenchException; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * SWTBot Smoke test for Pcap UI. + * + * @author Matthew Khouzam + */ +@RunWith(SWTBotJunit4ClassRunner.class) +public class ImportAndReadPcapTest { + + private static final String NETWORK_PERSPECTIVE_ID = NetworkingPerspectiveFactory.ID; + private static final String TRACE_PROJECT_NAME = "test"; + + private static SWTWorkbenchBot fBot; + private ITmfEvent fDesired1; + private static PcapTmfTestTrace pttt = PcapTmfTestTrace.BENCHMARK_TRACE; + + /** The Log4j logger instance. */ + private static final Logger fLogger = Logger.getRootLogger(); + + /** + * Test Class setup + */ + @BeforeClass + public static void init() { + + SWTBotUtil.failIfUIThread(); + + /* set up for swtbot */ + SWTBotPreferences.TIMEOUT = 300000; /* 300 second timeout */ + fLogger.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender.SYSTEM_OUT)); + fBot = new SWTWorkbenchBot(); + + final List openViews = fBot.views(); + for (SWTBotView view : openViews) { + if (view.getTitle().equals("Welcome")) { + view.close(); + fBot.waitUntil(ConditionHelpers.ViewIsClosed(view)); + } + } + /* Switch perspectives */ + switchNetworkPerspective(); + /* Finish waiting for eclipse to load */ + SWTBotUtil.waitForJobs(); + } + + private static void switchNetworkPerspective() { + final Exception retE[] = new Exception[1]; + if (!UIThreadRunnable.syncExec(new BoolResult() { + @Override + public Boolean run() { + try { + PlatformUI.getWorkbench().showPerspective(NETWORK_PERSPECTIVE_ID, + PlatformUI.getWorkbench().getActiveWorkbenchWindow()); + } catch (WorkbenchException e) { + retE[0] = e; + return false; + } + return true; + } + })) { + fail(retE[0].getMessage()); + } + + } + + /** + * Main test case + */ + @Test + public void test() { + assumeTrue(pttt.exists()); + SWTBotUtil.createProject(TRACE_PROJECT_NAME); + openTrace(); + openEditor(); + testHV(getViewPart("Histogram")); + testStreamView(getViewPartRef("Stream List")); + fBot.closeAllEditors(); + SWTBotUtil.deleteProject(TRACE_PROJECT_NAME, fBot); + } + + private void testStreamView(IViewReference viewPart) { + SWTBotView botView = new SWTBotView(viewPart, fBot); + StreamListView slv = (StreamListView) getViewPart("Stream List"); + botView.setFocus(); + SWTBotTree botTree = fBot.tree(); + assertNotNull(botTree); + final TmfTimeSynchSignal signal = new TmfTimeSynchSignal(slv, fDesired1.getTimestamp()); + slv.broadcast(signal); + SWTBotUtil.waitForJobs(); + // FIXME This is a race condition: + // TmfEventsTable launches an async exec that may be run after the wait + // for jobs. This last delay catches it. + SWTBotUtil.delay(1000); + + } + + private static void openTrace() { + final Exception exception[] = new Exception[1]; + exception[0] = null; + UIThreadRunnable.syncExec(new VoidResult() { + @Override + public void run() { + try { + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(TRACE_PROJECT_NAME); + TmfTraceFolder destinationFolder = TmfProjectRegistry.getProject(project, true).getTracesFolder(); + String absolutePath = (new File(pttt.getTrace().getPath())).getAbsolutePath(); + TmfOpenTraceHelper.openTraceFromPath(destinationFolder, absolutePath, PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "org.eclipse.linuxtools.tmf.pcap.core.pcaptrace"); + } catch (CoreException e) { + exception[0] = e; + } + } + }); + if (exception[0] != null) { + fail(exception[0].getMessage()); + } + + SWTBotUtil.delay(1000); + SWTBotUtil.waitForJobs(); + } + + private void openEditor() { + final List editorRefs = new ArrayList<>(); + UIThreadRunnable.syncExec(new VoidResult() { + @Override + public void run() { + IEditorReference[] ieds = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getEditorReferences(); + editorRefs.addAll(Arrays.asList(ieds)); + } + + }); + assertFalse(editorRefs.isEmpty()); + IEditorPart iep = null; + for (IEditorReference ied : editorRefs) { + if (ied.getTitle().equals(pttt.getTrace().getName())) { + iep = ied.getEditor(true); + break; + } + } + assertNotNull(iep); + fDesired1 = getEvent(100); + final TmfEventsEditor tmfEd = (TmfEventsEditor) iep; + UIThreadRunnable.syncExec(new VoidResult() { + @Override + public void run() { + tmfEd.setFocus(); + tmfEd.selectionChanged(new SelectionChangedEvent(tmfEd, new StructuredSelection(fDesired1))); + } + }); + + SWTBotUtil.waitForJobs(); + SWTBotUtil.delay(1000); + assertNotNull(tmfEd); + } + + private static void testHV(IViewPart vp) { + assertNotNull(vp); + } + + private static ITmfEvent getEvent(int rank) { + try (PcapTrace trace = pttt.getTrace()) { + ITmfContext ctx = trace.seekEvent(0); + for (int i = 0; i < rank; i++) { + trace.getNext(ctx); + } + return trace.getNext(ctx); + } + + } + + private static IViewPart getViewPart(final String viewTile) { + final IViewPart[] vps = new IViewPart[1]; + UIThreadRunnable.syncExec(new VoidResult() { + @Override + public void run() { + IViewReference[] viewRefs = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getViewReferences(); + for (IViewReference viewRef : viewRefs) { + IViewPart vp = viewRef.getView(true); + if (vp.getTitle().equals(viewTile)) { + vps[0] = vp; + return; + } + } + } + }); + + return vps[0]; + } + + private static IViewReference getViewPartRef(final String viewTile) { + final IViewReference[] vrs = new IViewReference[1]; + UIThreadRunnable.syncExec(new VoidResult() { + @Override + public void run() { + IViewReference[] viewRefs = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getViewReferences(); + for (IViewReference viewRef : viewRefs) { + IViewPart vp = viewRef.getView(true); + if (vp.getTitle().equals(viewTile)) { + vrs[0] = viewRef; + return; + } + } + } + }); + + return vrs[0]; + } +} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/pcap/ui/swtbot/tests/NetworkPerspectiveChecker.java b/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/pcap/ui/swtbot/tests/NetworkPerspectiveChecker.java new file mode 100644 index 0000000000..61fffc318a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/pcap/ui/swtbot/tests/NetworkPerspectiveChecker.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests; + +import java.util.ArrayList; +import java.util.Arrays; + +import org.eclipse.tracecompass.internal.tmf.pcap.ui.NetworkingPerspectiveFactory; +import org.eclipse.tracecompass.internal.tmf.pcap.ui.stream.StreamListView; +import org.eclipse.tracecompass.tmf.ui.swtbot.tests.AbstractPerspectiveChecker; +import org.eclipse.tracecompass.tmf.ui.views.colors.ColorsView; +import org.eclipse.tracecompass.tmf.ui.views.filter.FilterView; +import org.eclipse.tracecompass.tmf.ui.views.histogram.HistogramView; +import org.eclipse.tracecompass.tmf.ui.views.statistics.TmfStatisticsView; +import org.eclipse.ui.IPageLayout; +import org.junit.Before; + +/** + * Tracing perspective view checker + * + * @author Matthew Khouzam + */ +public class NetworkPerspectiveChecker extends AbstractPerspectiveChecker { + + /** + * Set up arrays for test + */ + @Before + public void init() { + fPerspectiveId = NetworkingPerspectiveFactory.ID; + fViewIds = new ArrayList<>(); + fViewIds.addAll(Arrays.asList(new String[] { + // TMF views + HistogramView.ID, + TmfStatisticsView.ID, + FilterView.ID, + ColorsView.ID, + // PCAP + StreamListView.ID, + // Standard Eclipse views + IPageLayout.ID_PROJECT_EXPLORER, + IPageLayout.ID_PROP_SHEET, + IPageLayout.ID_BOOKMARKS + })); + } +} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/META-INF/MANIFEST.MF b/org.eclipse.tracecompass.tmf.pcap.ui/META-INF/MANIFEST.MF index 941ff871fe..1829ca9f8a 100644 --- a/org.eclipse.tracecompass.tmf.pcap.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.tracecompass.tmf.pcap.ui/META-INF/MANIFEST.MF @@ -5,7 +5,7 @@ Bundle-Vendor: %Bundle-Vendor Bundle-Version: 1.0.0.qualifier Bundle-Localization: plugin Bundle-SymbolicName: org.eclipse.tracecompass.tmf.pcap.ui;singleton:=true -Bundle-Activator: org.eclipse.linuxtools.internal.tmf.pcap.ui.Activator +Bundle-Activator: org.eclipse.tracecompass.internal.tmf.pcap.ui.Activator Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Require-Bundle: org.eclipse.core.runtime, @@ -15,7 +15,7 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.tracecompass.tmf.core;bundle-version="3.1.0", org.eclipse.tracecompass.tmf.ui;bundle-version="3.1.0", org.eclipse.tracecompass.tmf.pcap.core;bundle-version="1.0.0" -Export-Package: org.eclipse.linuxtools.internal.tmf.pcap.ui;x-friends:="org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests", - org.eclipse.linuxtools.internal.tmf.pcap.ui.editor;x-internal:=true, - org.eclipse.linuxtools.internal.tmf.pcap.ui.stream;x-friends:="org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests" +Export-Package: org.eclipse.tracecompass.internal.tmf.pcap.ui;x-friends:="org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests", + org.eclipse.tracecompass.internal.tmf.pcap.ui.editor;x-internal:=true, + org.eclipse.tracecompass.internal.tmf.pcap.ui.stream;x-friends:="org.eclipse.tracecompass.tmf.pcap.ui.swtbot.tests" Import-Package: com.google.common.collect diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/plugin.xml b/org.eclipse.tracecompass.tmf.pcap.ui/plugin.xml index 31fd1d8211..d8723ba052 100644 --- a/org.eclipse.tracecompass.tmf.pcap.ui/plugin.xml +++ b/org.eclipse.tracecompass.tmf.pcap.ui/plugin.xml @@ -7,7 +7,7 @@ icon="icons/pcap.png" tracetype="org.eclipse.linuxtools.tmf.pcap.core.pcaptrace"> + class="org.eclipse.tracecompass.internal.tmf.pcap.ui.editor.PcapEventTableColumns"> @@ -20,7 +20,7 @@ + class="org.eclipse.tracecompass.internal.tmf.pcap.core.analysis.StreamListAnalysis"> diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/Activator.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/Activator.java deleted file mode 100644 index 5c9ebaa93f..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/Activator.java +++ /dev/null @@ -1,212 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.ui; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Plugin; -import org.eclipse.core.runtime.Status; -import org.eclipse.jdt.annotation.Nullable; -import org.osgi.framework.BundleContext; - -/** - * Activator - *

- * The activator class controls the plug-in life cycle - */ -public class Activator extends Plugin { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The plug-in ID - */ - public static final String PLUGIN_ID = "org.eclipse.linuxtools.tmf.pcap.ui"; //$NON-NLS-1$ - - /** - * The shared instance - */ - private static @Nullable Activator fPlugin; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructor - */ - public Activator() { - setDefault(this); - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Returns the TMF Core plug-in instance. - * - * @return the TMF Core plug-in instance. - */ - public static @Nullable Activator getDefault() { - return fPlugin; - } - - // Sets plug-in instance - private static void setDefault(@Nullable Activator plugin) { - fPlugin = plugin; - } - - // ------------------------------------------------------------------------ - // Plugin - // ------------------------------------------------------------------------ - - @Override - public void start(@Nullable BundleContext context) throws Exception { - super.start(context); - setDefault(this); - } - - @Override - public void stop(@Nullable BundleContext context) throws Exception { - setDefault(null); - super.stop(context); - } - - - // ------------------------------------------------------------------------ - // Log an IStatus - // ------------------------------------------------------------------------ - - /** - * Log an IStatus object directly - * - * @param status - * The status to log - */ - public static void log(IStatus status) { - Activator activator = fPlugin; - if (activator == null) { - return; - } - activator.getLog().log(status); - } - - // ------------------------------------------------------------------------ - // Log INFO - // ------------------------------------------------------------------------ - - /** - * Logs a message with severity INFO in the runtime log of the plug-in. - * - * @param message - * A message to log - */ - public static void logInfo(String message) { - Activator activator = fPlugin; - if (activator == null) { - return; - } - activator.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity INFO in the runtime log of the - * plug-in. - * - * @param message - * A message to log - * @param exception - * The corresponding exception - */ - public static void logInfo(String message, Throwable exception) { - Activator activator = fPlugin; - if (activator == null) { - return; - } - activator.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message, exception)); - } - - // ------------------------------------------------------------------------ - // Log WARNING - // ------------------------------------------------------------------------ - - /** - * Logs a message and exception with severity WARNING in the runtime log of - * the plug-in. - * - * @param message - * A message to log - */ - public static void logWarning(String message) { - Activator activator = fPlugin; - if (activator == null) { - return; - } - activator.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity WARNING in the runtime log of - * the plug-in. - * - * @param message - * A message to log - * @param exception - * The corresponding exception - */ - public static void logWarning(String message, Throwable exception) { - Activator activator = fPlugin; - if (activator == null) { - return; - } - activator.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message, exception)); - } - - // ------------------------------------------------------------------------ - // Log ERROR - // ------------------------------------------------------------------------ - - /** - * Logs a message and exception with severity ERROR in the runtime log of - * the plug-in. - * - * @param message - * A message to log - */ - public static void logError(String message) { - Activator activator = fPlugin; - if (activator == null) { - return; - } - activator.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity ERROR in the runtime log of - * the plug-in. - * - * @param message - * A message to log - * @param exception - * The corresponding exception - */ - public static void logError(String message, Throwable exception) { - Activator activator = fPlugin; - if (activator == null) { - return; - } - activator.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, exception)); - } -} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/NetworkingPerspectiveFactory.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/NetworkingPerspectiveFactory.java deleted file mode 100644 index 616b3b0bc7..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/NetworkingPerspectiveFactory.java +++ /dev/null @@ -1,90 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.ui; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.internal.tmf.pcap.ui.stream.StreamListView; -import org.eclipse.linuxtools.tmf.ui.project.wizards.NewTmfProjectWizard; -import org.eclipse.linuxtools.tmf.ui.views.colors.ColorsView; -import org.eclipse.linuxtools.tmf.ui.views.filter.FilterView; -import org.eclipse.linuxtools.tmf.ui.views.histogram.HistogramView; -import org.eclipse.linuxtools.tmf.ui.views.statistics.TmfStatisticsView; -import org.eclipse.ui.IFolderLayout; -import org.eclipse.ui.IPageLayout; -import org.eclipse.ui.IPerspectiveFactory; - -/** - * The networking perspective definition. - * - * @author Vincent Perot - */ -public class NetworkingPerspectiveFactory implements IPerspectiveFactory { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** The Perspective ID */ - public static final String ID = "org.eclipse.linuxtools.tmf.pcap.ui.perspective.network"; //$NON-NLS-1$ - - // Views - @SuppressWarnings("null") - private static final @NonNull String PROJECT_VIEW_ID = IPageLayout.ID_PROJECT_EXPLORER; - @SuppressWarnings("null") - private static final @NonNull String PROPERTIES_VIEW_ID = IPageLayout.ID_PROP_SHEET; - @SuppressWarnings("null") - private static final @NonNull String BOOKMARKS_VIEW_ID = IPageLayout.ID_BOOKMARKS; - private static final String FILTER_VIEW_ID = FilterView.ID; - private static final String HISTOGRAM_VIEW_ID = HistogramView.ID; - private static final String STATISTICS_VIEW_ID = TmfStatisticsView.ID; - private static final String COLOR_VIEW_ID = ColorsView.ID; - private static final String STREAM_LIST_VIEW_ID = StreamListView.ID; - - // ------------------------------------------------------------------------ - // IPerspectiveFactory - // ------------------------------------------------------------------------ - - @Override - public void createInitialLayout(@Nullable IPageLayout layout) { - - if (layout == null) { - return; - } - - // Editor area - layout.setEditorAreaVisible(true); - - // Create the top left folder - IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.15f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$ - topLeftFolder.addView(PROJECT_VIEW_ID); - - // Create the middle right folder - IFolderLayout middleRightFolder = layout.createFolder("middleRightFolder", IPageLayout.BOTTOM, 0.40f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$ - middleRightFolder.addView(PROPERTIES_VIEW_ID); - middleRightFolder.addView(HISTOGRAM_VIEW_ID); - middleRightFolder.addView(STATISTICS_VIEW_ID); - middleRightFolder.addView(COLOR_VIEW_ID); - - // Create the bottom right folder - IFolderLayout bottomRightFolder = layout.createFolder("bottomRightFolder", IPageLayout.BOTTOM, 0.65f, "middleRightFolder"); //$NON-NLS-1$ //$NON-NLS-2$ - bottomRightFolder.addView(FILTER_VIEW_ID); - bottomRightFolder.addView(BOOKMARKS_VIEW_ID); - bottomRightFolder.addView(STREAM_LIST_VIEW_ID); - - // Populate menus, etc - layout.addPerspectiveShortcut(ID); - layout.addNewWizardShortcut(NewTmfProjectWizard.ID); - } - -} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/editor/Messages.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/editor/Messages.java deleted file mode 100644 index 590d964dc7..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/editor/Messages.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.ui.editor; - -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.osgi.util.NLS; - -@SuppressWarnings("javadoc") -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.tmf.pcap.ui.editor.messages"; //$NON-NLS-1$ - - public static @Nullable String PcapEventsTable_Content; - public static @Nullable String PcapEventsTable_Destination; - public static @Nullable String PcapEventsTable_Protocol; - public static @Nullable String PcapEventsTable_Reference; - public static @Nullable String PcapEventsTable_Source; - public static @Nullable String PcapEventsTable_Timestamp; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/editor/PcapEventTableColumns.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/editor/PcapEventTableColumns.java deleted file mode 100644 index 227dd04eea..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/editor/PcapEventTableColumns.java +++ /dev/null @@ -1,144 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - * Alexandre Montplaisir - Update to new TmfEventTableColumn API - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.ui.editor; - -import java.util.Collection; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.internal.tmf.pcap.core.event.PcapEvent; -import org.eclipse.linuxtools.internal.tmf.pcap.core.protocol.TmfPcapProtocol; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.ITmfEventTableColumns; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn; - -import com.google.common.collect.ImmutableList; - -/** - * Default event table for pcap traces. - * - * @author Vincent Perot - */ -public class PcapEventTableColumns implements ITmfEventTableColumns { - - // ------------------------------------------------------------------------ - // Table data - // ------------------------------------------------------------------------ - - @SuppressWarnings("null") - private static final @NonNull Collection PCAP_COLUMNS = ImmutableList.of( - TmfEventTableColumn.BaseColumns.TIMESTAMP, - new PcapSourceColumn(), - new PcapDestinationColumn(), - TmfEventTableColumn.BaseColumns.REFERENCE, - new PcapProtocolColumn(), - TmfEventTableColumn.BaseColumns.CONTENTS - ); - - /** - * The "packet source" column for pcap events - */ - private static class PcapSourceColumn extends TmfEventTableColumn { - - public PcapSourceColumn() { - super(getString(Messages.PcapEventsTable_Source)); - } - - @Override - public String getItemString(ITmfEvent event) { - if (!(event instanceof PcapEvent)) { - return EMPTY_STRING; - } - PcapEvent pcapEvent = (PcapEvent) event; - TmfPcapProtocol protocol = pcapEvent.getMostEncapsulatedProtocol(); - - return getString(pcapEvent.getSourceEndpoint(protocol)); - } - - @Override - public @Nullable String getFilterFieldId() { - return PcapEvent.EVENT_FIELD_PACKET_SOURCE; - } - } - - /** - * The "packet destination" column for pcap events - */ - private static class PcapDestinationColumn extends TmfEventTableColumn { - - public PcapDestinationColumn() { - super(getString(Messages.PcapEventsTable_Destination)); - } - - @Override - public String getItemString(ITmfEvent event) { - if (!(event instanceof PcapEvent)) { - return EMPTY_STRING; - } - PcapEvent pcapEvent = (PcapEvent) event; - TmfPcapProtocol protocol = pcapEvent.getMostEncapsulatedProtocol(); - return getString(pcapEvent.getDestinationEndpoint(protocol)); - } - - @Override - public @Nullable String getFilterFieldId() { - return PcapEvent.EVENT_FIELD_PACKET_DESTINATION; - } - } - - /** - * The "packet protocol" column for pcap events - */ - private static class PcapProtocolColumn extends TmfEventTableColumn { - - public PcapProtocolColumn() { - super(getString(Messages.PcapEventsTable_Protocol)); - } - - @Override - public String getItemString(ITmfEvent event) { - if (!(event instanceof PcapEvent)) { - return EMPTY_STRING; - } - PcapEvent pcapEvent = (PcapEvent) event; - TmfPcapProtocol protocol = pcapEvent.getMostEncapsulatedProtocol(); - - @SuppressWarnings("null") - @NonNull String proto = protocol.getShortName().toUpperCase(); - return proto; - } - - @Override - public @Nullable String getFilterFieldId() { - return PcapEvent.EVENT_FIELD_PACKET_PROTOCOL; - } - } - - /** - * Little convenience method to work around the incompatibilities between - * null annotations and NLS files... - */ - private static String getString(@Nullable String str) { - return (str == null ? "" : str); //$NON-NLS-1$ - } - - // ------------------------------------------------------------------------ - // ITmfEventTableColumns - // ------------------------------------------------------------------------ - - @Override - public Collection getEventTableColumns() { - return PCAP_COLUMNS; - } -} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/editor/messages.properties b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/editor/messages.properties deleted file mode 100644 index fe4006df00..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/editor/messages.properties +++ /dev/null @@ -1,18 +0,0 @@ -############################################################################### -# Copyright (c) 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### - -PcapEventsTable_Content=Content -PcapEventsTable_Destination=Destination -PcapEventsTable_Protocol=Protocol -PcapEventsTable_Reference=Reference -PcapEventsTable_Source=Source -PcapEventsTable_Timestamp=Timestamp diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/editor/package-info.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/editor/package-info.java deleted file mode 100644 index f3c77e9d57..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/editor/package-info.java +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ericsson - Initial API and implementation - *******************************************************************************/ - -@org.eclipse.jdt.annotation.NonNullByDefault -package org.eclipse.linuxtools.internal.tmf.pcap.ui.editor; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/package-info.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/package-info.java deleted file mode 100644 index 0567038652..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/package-info.java +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ericsson - Initial API and implementation - *******************************************************************************/ - -@org.eclipse.jdt.annotation.NonNullByDefault -package org.eclipse.linuxtools.internal.tmf.pcap.ui; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/stream/Messages.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/stream/Messages.java deleted file mode 100644 index 06b3efd3e7..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/stream/Messages.java +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.ui.stream; - -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.osgi.util.NLS; - -@SuppressWarnings("javadoc") -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.tmf.pcap.ui.stream.messages"; //$NON-NLS-1$ - - public static @Nullable String StreamListView_BPSAtoB; - public static @Nullable String StreamListView_BPSBtoA; - public static @Nullable String StreamListView_BytesAtoB; - public static @Nullable String StreamListView_BytesBtoA; - public static @Nullable String StreamListView_Clear; - public static @Nullable String StreamListView_Duration; - public static @Nullable String StreamListView_EndpointA; - public static @Nullable String StreamListView_EndpointB; - public static @Nullable String StreamListView_ExtractAsFilter; - public static @Nullable String StreamListView_FilterName_Stream; - public static @Nullable String StreamListView_FollowStream; - public static @Nullable String StreamListView_ID; - public static @Nullable String StreamListView_PacketsAtoB; - public static @Nullable String StreamListView_PacketsBtoA; - public static @Nullable String StreamListView_StartTime; - public static @Nullable String StreamListView_StopTime; - public static @Nullable String StreamListView_TotalBytes; - public static @Nullable String StreamListView_TotalPackets; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/stream/StreamListView.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/stream/StreamListView.java deleted file mode 100644 index b55e2ea213..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/stream/StreamListView.java +++ /dev/null @@ -1,498 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.pcap.ui.stream; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.internal.tmf.pcap.core.analysis.StreamListAnalysis; -import org.eclipse.linuxtools.internal.tmf.pcap.core.event.PcapEvent; -import org.eclipse.linuxtools.internal.tmf.pcap.core.event.TmfPacketStream; -import org.eclipse.linuxtools.internal.tmf.pcap.core.event.TmfPacketStreamBuilder; -import org.eclipse.linuxtools.internal.tmf.pcap.core.protocol.TmfPcapProtocol; -import org.eclipse.linuxtools.internal.tmf.pcap.core.signal.TmfPacketStreamSelectedSignal; -import org.eclipse.linuxtools.internal.tmf.pcap.core.trace.PcapTrace; -import org.eclipse.linuxtools.internal.tmf.pcap.ui.Activator; -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterAndNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterContainsNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterOrNode; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.project.model.TraceUtils; -import org.eclipse.linuxtools.tmf.ui.views.TmfView; -import org.eclipse.linuxtools.tmf.ui.views.filter.FilterManager; -import org.eclipse.linuxtools.tmf.ui.views.filter.FilterView; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.custom.CTabItem; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.MenuItem; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.TableItem; -import org.eclipse.ui.IViewPart; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.PlatformUI; - -/** - * Class that represents the Stream List View. Such a view lists all the - * available streams from the current experiment.
- *
- * TODO Switch to TmfUiRefreshHandler once the behavior is fixed - * - * FIXME analysis is leaking ressource. Someone I will not name told me not to worry about it since - * AnalysisModule will not be autocloseable later. - * - * @author Vincent Perot - */ -public class StreamListView extends TmfView { - - /** - * The Stream List View ID. - */ - public static final String ID = "org.eclipse.linuxtools.tmf.pcap.ui.view.stream.list"; //$NON-NLS-1$ - - private static final String[] COLUMN_NAMES = - { Messages.StreamListView_ID, - Messages.StreamListView_EndpointA, - Messages.StreamListView_EndpointB, - Messages.StreamListView_TotalPackets, - Messages.StreamListView_TotalBytes, - Messages.StreamListView_PacketsAtoB, - Messages.StreamListView_BytesAtoB, - Messages.StreamListView_PacketsBtoA, - Messages.StreamListView_BytesBtoA, - Messages.StreamListView_StartTime, - Messages.StreamListView_StopTime, - Messages.StreamListView_Duration, - Messages.StreamListView_BPSAtoB, - Messages.StreamListView_BPSBtoA - }; - - private static final int[] COLUMN_SIZES = - { 75, - 350, - 350, - 110, - 110, - 110, - 110, - 110, - 110, - 180, - 180, - 110, - 110, - 110 }; - - private static final String KEY_PROTOCOL = "$protocol$"; //$NON-NLS-1$ - private static final String KEY_STREAM = "$stream$"; //$NON-NLS-1$ - - private static final String EMPTY_STRING = ""; //$NON-NLS-1$ - - private static final long WAIT_TIME = 1000; - - private @Nullable CTabFolder fTabFolder; - private @Nullable Map fTableMap; - - private @Nullable TmfPacketStream fCurrentStream; - private @Nullable ITmfTrace fCurrentTrace; - - private volatile boolean fStopThread; - - /** - * Constructor of the StreamListView class. - */ - public StreamListView() { - super(ID); - } - - /** - * Handler called when an trace is opened. - * - * @param signal - * Contains the information about the selection. - */ - @TmfSignalHandler - public void traceOpened(TmfTraceOpenedSignal signal) { - fCurrentTrace = signal.getTrace(); - resetView(); - queryAnalysis(); - } - - /** - * Handler called when an trace is closed. Checks if the trace is the - * current trace and update the view accordingly. - * - * @param signal - * Contains the information about the selection. - */ - @TmfSignalHandler - public void traceClosed(TmfTraceClosedSignal signal) { - if (fCurrentTrace == signal.getTrace()) { - fCurrentTrace = null; - resetView(); - } - } - - /** - * Handler called when an trace is selected. Checks if the trace has changed - * and requests the selected trace if it has not yet been cached. - * - * @param signal - * Contains the information about the selection. - */ - @TmfSignalHandler - public void traceSelected(TmfTraceSelectedSignal signal) { - if (fCurrentTrace != signal.getTrace()) { - fCurrentTrace = signal.getTrace(); - resetView(); - queryAnalysis(); - } - } - - private void queryAnalysis() { - Thread thread = new Thread(new Runnable() { - - @Override - public void run() { - ITmfTrace trace = fCurrentTrace; - if (trace == null || (!(trace instanceof PcapTrace))) { - return; - } - StreamListAnalysis analysis = trace.getAnalysisModuleOfClass(StreamListAnalysis.class, StreamListAnalysis.ID); - if (analysis == null) { - return; - } - while (!analysis.isFinished() && !fStopThread) { - updateUI(); - try { - Thread.sleep(WAIT_TIME); - } catch (InterruptedException e) { - String message = e.getMessage(); - if (message == null) { - message = EMPTY_STRING; - } - Activator.logError(message, e); - return; - } - } - // Update UI one more time (daft punk) - if (!fStopThread) { - updateUI(); - } - - } - }); - - fStopThread = false; - thread.start(); - } - - private void resetView() { - - // Stop thread if needed - fStopThread = true; - - // Remove all content in tables - final Display display = Display.getDefault(); - if (display == null || display.isDisposed()) { - return; - } - display.asyncExec(new Runnable() { - - @Override - public void run() { - if (display.isDisposed()) { - return; - } - Map tableMap = fTableMap; - if (tableMap == null) { - return; - } - for (TmfPcapProtocol protocol : tableMap.keySet()) { - if (!(tableMap.get(protocol).isDisposed())) { - tableMap.get(protocol).removeAll(); - } - } - } - }); - } - - private void updateUI() { - final Display display = Display.getDefault(); - if (display == null || display.isDisposed()) { - return; - } - display.asyncExec(new Runnable() { - - @Override - public void run() { - if (display.isDisposed()) { - return; - } - ITmfTrace trace = fCurrentTrace; - if (trace == null) { - return; - } - - StreamListAnalysis analysis = trace.getAnalysisModuleOfClass(StreamListAnalysis.class, StreamListAnalysis.ID); - if (analysis == null) { - return; - } - - Map tables = fTableMap; - if (tables == null) { - return; - } - for (TmfPcapProtocol p : tables.keySet()) { - @SuppressWarnings("null") - @NonNull TmfPcapProtocol protocol = p; - TmfPacketStreamBuilder builder = analysis.getBuilder(protocol); - if (builder != null && !(tables.get(protocol).isDisposed())) { - for (TmfPacketStream stream : builder.getStreams()) { - - TableItem item; - if (stream.getID() < tables.get(protocol).getItemCount()) { - item = tables.get(protocol).getItem(stream.getID()); - } else { - item = new TableItem(tables.get(protocol), SWT.NONE); - } - item.setText(0, String.valueOf(stream.getID())); - item.setText(1, stream.getFirstEndpoint().toString()); - item.setText(2, stream.getSecondEndpoint().toString()); - item.setText(3, String.valueOf(stream.getNbPackets())); - item.setText(4, String.valueOf(stream.getNbBytes())); - item.setText(5, String.valueOf(stream.getNbPacketsAtoB())); - item.setText(6, String.valueOf(stream.getNbBytesAtoB())); - item.setText(7, String.valueOf(stream.getNbPacketsBtoA())); - item.setText(8, String.valueOf(stream.getNbBytesBtoA())); - item.setText(9, stream.getStartTime().toString()); - item.setText(10, stream.getStopTime().toString()); - item.setText(11, String.format("%.3f", stream.getDuration())); //$NON-NLS-1$ - item.setText(12, String.format("%.3f", stream.getBPSAtoB())); //$NON-NLS-1$ - item.setText(13, String.format("%.3f", stream.getBPSBtoA())); //$NON-NLS-1$ - item.setData(KEY_STREAM, stream); - } - } - } - } - - }); - } - - @Override - public void createPartControl(@Nullable Composite parent) { - // Initialize - fTableMap = new HashMap<>(); - fCurrentTrace = getActiveTrace(); - fCurrentStream = null; - - // Add a tab folder - fTabFolder = new CTabFolder(parent, SWT.NONE); - fTabFolder.addSelectionListener(new SelectionAdapter() { - - @Override - public void widgetSelected(@Nullable SelectionEvent e) { - Map tables = fTableMap; - if (tables == null || e == null) { - return; - } - TmfPcapProtocol protocol = (TmfPcapProtocol) e.item.getData(KEY_PROTOCOL); - tables.get(protocol).deselectAll(); - fCurrentStream = null; - } - - }); - - // Add items and tables for each protocol - for (TmfPcapProtocol protocol : TmfPcapProtocol.values()) { - if (protocol.supportsStream()) { - CTabItem item = new CTabItem(fTabFolder, SWT.NONE); - item.setText(protocol.getName()); - item.setData(KEY_PROTOCOL, protocol); - Table table = new Table(fTabFolder, SWT.NONE); - table.setHeaderVisible(true); - table.setLinesVisible(true); - - // Add columns to table - for (int i = 0; i < COLUMN_NAMES.length || i < COLUMN_SIZES.length; i++) { - TableColumn column = new TableColumn(table, SWT.NONE); - column.setText(COLUMN_NAMES[i]); - column.setWidth(COLUMN_SIZES[i]); - } - item.setControl(table); - table.addSelectionListener(new SelectionAdapter() { - - @Override - public void widgetSelected(@Nullable SelectionEvent e) { - if (e == null) { - return; - } - fCurrentStream = (TmfPacketStream) e.item.getData(KEY_STREAM); - } - - }); - - Map tables = fTableMap; - if (tables == null) { - return; - } - - tables.put(protocol, table); - - // Add right click menu - Menu menu = new Menu(table); - MenuItem menuItem = new MenuItem(menu, SWT.PUSH); - menuItem.setText(Messages.StreamListView_FollowStream); - menuItem.addListener(SWT.Selection, new Listener() { - - @Override - public void handleEvent(@Nullable Event event) { - TmfSignal signal = new TmfPacketStreamSelectedSignal(this, 0, fCurrentStream); - TmfSignalManager.dispatchSignal(signal); - } - }); - menuItem = new MenuItem(menu, SWT.PUSH); - menuItem.setText(Messages.StreamListView_Clear); - menuItem.addListener(SWT.Selection, new Listener() { - - @Override - public void handleEvent(@Nullable Event event) { - TmfSignal signal = new TmfPacketStreamSelectedSignal(this, 0, null); - TmfSignalManager.dispatchSignal(signal); - - } - }); - menuItem = new MenuItem(menu, SWT.PUSH); - menuItem.setText(Messages.StreamListView_ExtractAsFilter); - menuItem.addListener(SWT.Selection, new Listener() { - - @Override - public void handleEvent(@Nullable Event event) { - // Generate filter. - ITmfFilterTreeNode filter = generateFilter(); - - // Update view and XML - updateFilters(filter); - - } - - private void updateFilters(@Nullable ITmfFilterTreeNode filter) { - if (filter == null) { - return; - } - - // Update XML - List newFilters = new ArrayList<>(); - ITmfFilterTreeNode[] oldFilters = FilterManager.getSavedFilters(); - for (int i = 0; i < oldFilters.length; i++) { - newFilters.add(oldFilters[i]); - } - if (!(newFilters.contains(filter))) { - newFilters.add(filter); - FilterManager.setSavedFilters(newFilters.toArray(new ITmfFilterTreeNode[newFilters.size()])); - } - - // Update Filter View - try { - final IWorkbench wb = PlatformUI.getWorkbench(); - final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); - IViewPart view = activePage.showView(FilterView.ID); - FilterView filterView = (FilterView) view; - filterView.addFilter(filter); - } catch (final PartInitException e) { - TraceUtils.displayErrorMsg(Messages.StreamListView_ExtractAsFilter, "Error opening view " + FilterView.ID + e.getMessage()); //$NON-NLS-1$ - Activator.logError("Error opening view " + FilterView.ID, e); //$NON-NLS-1$ - return; - } - - } - - private @Nullable ITmfFilterTreeNode generateFilter() { - TmfPacketStream stream = fCurrentStream; - if (stream == null) { - return null; - } - - // First stage - root - String name = Messages.StreamListView_FilterName_Stream + ' ' + stream.getProtocol().getShortName() + ' ' + stream.getFirstEndpoint() - + " <--> " + stream.getSecondEndpoint(); //$NON-NLS-1$ - TmfFilterNode root = new TmfFilterNode(name); - - // Second stage - and - TmfFilterAndNode and = new TmfFilterAndNode(root); - - // Third stage - protocol + or - TmfFilterContainsNode protocolFilter = new TmfFilterContainsNode(and); - protocolFilter.setField(stream.getProtocol().getName()); - protocolFilter.setValue(EMPTY_STRING); - TmfFilterOrNode or = new TmfFilterOrNode(and); - - // Fourth stage - and - TmfFilterAndNode andA = new TmfFilterAndNode(or); - TmfFilterAndNode andB = new TmfFilterAndNode(or); - - // Fourth stage - endpoints - TmfFilterContainsNode endpointAAndA = new TmfFilterContainsNode(andA); - endpointAAndA.setField(PcapEvent.EVENT_FIELD_PACKET_SOURCE); - endpointAAndA.setValue(stream.getFirstEndpoint()); - TmfFilterContainsNode endpointBAndA = new TmfFilterContainsNode(andA); - endpointBAndA.setField(PcapEvent.EVENT_FIELD_PACKET_DESTINATION); - endpointBAndA.setValue(stream.getSecondEndpoint()); - TmfFilterContainsNode endpointAAndB = new TmfFilterContainsNode(andB); - endpointAAndB.setField(PcapEvent.EVENT_FIELD_PACKET_SOURCE); - endpointAAndB.setValue(stream.getSecondEndpoint()); - TmfFilterContainsNode endpointBAndB = new TmfFilterContainsNode(andB); - endpointBAndB.setField(PcapEvent.EVENT_FIELD_PACKET_DESTINATION); - endpointBAndB.setValue(stream.getFirstEndpoint()); - - return root; - } - }); - table.setMenu(menu); - } - } - - // Ask the analysis for data. - queryAnalysis(); - } - - @Override - public void setFocus() { - CTabFolder tabFolder = fTabFolder; - if (tabFolder != null && !(tabFolder.isDisposed())) { - tabFolder.setFocus(); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/stream/messages.properties b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/stream/messages.properties deleted file mode 100644 index 2ceb87c3b0..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/stream/messages.properties +++ /dev/null @@ -1,30 +0,0 @@ -############################################################################### -# Copyright (c) 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### - -StreamListView_Clear=Clear -StreamListView_Duration=Duration -StreamListView_EndpointA=Endpoint A -StreamListView_EndpointB=Endpoint B -StreamListView_ExtractAsFilter=Extract as Filter -StreamListView_FilterName_Stream=stream -StreamListView_FollowStream=Follow Stream -StreamListView_ID=ID -StreamListView_TotalBytes=Bytes -StreamListView_TotalPackets=Packets -StreamListView_PacketsAtoB=Packets A -> B -StreamListView_PacketsBtoA=Packets B -> A -StreamListView_BytesAtoB=Bytes A -> B -StreamListView_BytesBtoA=Bytes B -> A -StreamListView_StartTime=Start Time -StreamListView_StopTime=Stop Time -StreamListView_BPSBtoA=BPS B -> A -StreamListView_BPSAtoB=BPS A -> B diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/stream/package-info.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/stream/package-info.java deleted file mode 100644 index 9aeb3c64eb..0000000000 --- a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/linuxtools/internal/tmf/pcap/ui/stream/package-info.java +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ericsson - Initial API and implementation - *******************************************************************************/ - -@org.eclipse.jdt.annotation.NonNullByDefault -package org.eclipse.linuxtools.internal.tmf.pcap.ui.stream; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/Activator.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/Activator.java new file mode 100644 index 0000000000..7752eda489 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/Activator.java @@ -0,0 +1,212 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.ui; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; +import org.eclipse.jdt.annotation.Nullable; +import org.osgi.framework.BundleContext; + +/** + * Activator + *

+ * The activator class controls the plug-in life cycle + */ +public class Activator extends Plugin { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The plug-in ID + */ + public static final String PLUGIN_ID = "org.eclipse.linuxtools.tmf.pcap.ui"; //$NON-NLS-1$ + + /** + * The shared instance + */ + private static @Nullable Activator fPlugin; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructor + */ + public Activator() { + setDefault(this); + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * Returns the TMF Core plug-in instance. + * + * @return the TMF Core plug-in instance. + */ + public static @Nullable Activator getDefault() { + return fPlugin; + } + + // Sets plug-in instance + private static void setDefault(@Nullable Activator plugin) { + fPlugin = plugin; + } + + // ------------------------------------------------------------------------ + // Plugin + // ------------------------------------------------------------------------ + + @Override + public void start(@Nullable BundleContext context) throws Exception { + super.start(context); + setDefault(this); + } + + @Override + public void stop(@Nullable BundleContext context) throws Exception { + setDefault(null); + super.stop(context); + } + + + // ------------------------------------------------------------------------ + // Log an IStatus + // ------------------------------------------------------------------------ + + /** + * Log an IStatus object directly + * + * @param status + * The status to log + */ + public static void log(IStatus status) { + Activator activator = fPlugin; + if (activator == null) { + return; + } + activator.getLog().log(status); + } + + // ------------------------------------------------------------------------ + // Log INFO + // ------------------------------------------------------------------------ + + /** + * Logs a message with severity INFO in the runtime log of the plug-in. + * + * @param message + * A message to log + */ + public static void logInfo(String message) { + Activator activator = fPlugin; + if (activator == null) { + return; + } + activator.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity INFO in the runtime log of the + * plug-in. + * + * @param message + * A message to log + * @param exception + * The corresponding exception + */ + public static void logInfo(String message, Throwable exception) { + Activator activator = fPlugin; + if (activator == null) { + return; + } + activator.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message, exception)); + } + + // ------------------------------------------------------------------------ + // Log WARNING + // ------------------------------------------------------------------------ + + /** + * Logs a message and exception with severity WARNING in the runtime log of + * the plug-in. + * + * @param message + * A message to log + */ + public static void logWarning(String message) { + Activator activator = fPlugin; + if (activator == null) { + return; + } + activator.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity WARNING in the runtime log of + * the plug-in. + * + * @param message + * A message to log + * @param exception + * The corresponding exception + */ + public static void logWarning(String message, Throwable exception) { + Activator activator = fPlugin; + if (activator == null) { + return; + } + activator.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message, exception)); + } + + // ------------------------------------------------------------------------ + // Log ERROR + // ------------------------------------------------------------------------ + + /** + * Logs a message and exception with severity ERROR in the runtime log of + * the plug-in. + * + * @param message + * A message to log + */ + public static void logError(String message) { + Activator activator = fPlugin; + if (activator == null) { + return; + } + activator.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity ERROR in the runtime log of + * the plug-in. + * + * @param message + * A message to log + * @param exception + * The corresponding exception + */ + public static void logError(String message, Throwable exception) { + Activator activator = fPlugin; + if (activator == null) { + return; + } + activator.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, exception)); + } +} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/NetworkingPerspectiveFactory.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/NetworkingPerspectiveFactory.java new file mode 100644 index 0000000000..d7f3761e09 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/NetworkingPerspectiveFactory.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.ui; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.internal.tmf.pcap.ui.stream.StreamListView; +import org.eclipse.tracecompass.tmf.ui.project.wizards.NewTmfProjectWizard; +import org.eclipse.tracecompass.tmf.ui.views.colors.ColorsView; +import org.eclipse.tracecompass.tmf.ui.views.filter.FilterView; +import org.eclipse.tracecompass.tmf.ui.views.histogram.HistogramView; +import org.eclipse.tracecompass.tmf.ui.views.statistics.TmfStatisticsView; +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +/** + * The networking perspective definition. + * + * @author Vincent Perot + */ +public class NetworkingPerspectiveFactory implements IPerspectiveFactory { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** The Perspective ID */ + public static final String ID = "org.eclipse.linuxtools.tmf.pcap.ui.perspective.network"; //$NON-NLS-1$ + + // Views + @SuppressWarnings("null") + private static final @NonNull String PROJECT_VIEW_ID = IPageLayout.ID_PROJECT_EXPLORER; + @SuppressWarnings("null") + private static final @NonNull String PROPERTIES_VIEW_ID = IPageLayout.ID_PROP_SHEET; + @SuppressWarnings("null") + private static final @NonNull String BOOKMARKS_VIEW_ID = IPageLayout.ID_BOOKMARKS; + private static final String FILTER_VIEW_ID = FilterView.ID; + private static final String HISTOGRAM_VIEW_ID = HistogramView.ID; + private static final String STATISTICS_VIEW_ID = TmfStatisticsView.ID; + private static final String COLOR_VIEW_ID = ColorsView.ID; + private static final String STREAM_LIST_VIEW_ID = StreamListView.ID; + + // ------------------------------------------------------------------------ + // IPerspectiveFactory + // ------------------------------------------------------------------------ + + @Override + public void createInitialLayout(@Nullable IPageLayout layout) { + + if (layout == null) { + return; + } + + // Editor area + layout.setEditorAreaVisible(true); + + // Create the top left folder + IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.15f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$ + topLeftFolder.addView(PROJECT_VIEW_ID); + + // Create the middle right folder + IFolderLayout middleRightFolder = layout.createFolder("middleRightFolder", IPageLayout.BOTTOM, 0.40f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$ + middleRightFolder.addView(PROPERTIES_VIEW_ID); + middleRightFolder.addView(HISTOGRAM_VIEW_ID); + middleRightFolder.addView(STATISTICS_VIEW_ID); + middleRightFolder.addView(COLOR_VIEW_ID); + + // Create the bottom right folder + IFolderLayout bottomRightFolder = layout.createFolder("bottomRightFolder", IPageLayout.BOTTOM, 0.65f, "middleRightFolder"); //$NON-NLS-1$ //$NON-NLS-2$ + bottomRightFolder.addView(FILTER_VIEW_ID); + bottomRightFolder.addView(BOOKMARKS_VIEW_ID); + bottomRightFolder.addView(STREAM_LIST_VIEW_ID); + + // Populate menus, etc + layout.addPerspectiveShortcut(ID); + layout.addNewWizardShortcut(NewTmfProjectWizard.ID); + } + +} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/Messages.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/Messages.java new file mode 100644 index 0000000000..7d8fdc9d9d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/Messages.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.ui.editor; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.osgi.util.NLS; + +@SuppressWarnings("javadoc") +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.tmf.pcap.ui.editor.messages"; //$NON-NLS-1$ + + public static @Nullable String PcapEventsTable_Content; + public static @Nullable String PcapEventsTable_Destination; + public static @Nullable String PcapEventsTable_Protocol; + public static @Nullable String PcapEventsTable_Reference; + public static @Nullable String PcapEventsTable_Source; + public static @Nullable String PcapEventsTable_Timestamp; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/PcapEventTableColumns.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/PcapEventTableColumns.java new file mode 100644 index 0000000000..7318a15244 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/PcapEventTableColumns.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + * Alexandre Montplaisir - Update to new TmfEventTableColumn API + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.ui.editor; + +import java.util.Collection; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.internal.tmf.pcap.core.event.PcapEvent; +import org.eclipse.tracecompass.internal.tmf.pcap.core.protocol.TmfPcapProtocol; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.ITmfEventTableColumns; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; + +import com.google.common.collect.ImmutableList; + +/** + * Default event table for pcap traces. + * + * @author Vincent Perot + */ +public class PcapEventTableColumns implements ITmfEventTableColumns { + + // ------------------------------------------------------------------------ + // Table data + // ------------------------------------------------------------------------ + + @SuppressWarnings("null") + private static final @NonNull Collection PCAP_COLUMNS = ImmutableList.of( + TmfEventTableColumn.BaseColumns.TIMESTAMP, + new PcapSourceColumn(), + new PcapDestinationColumn(), + TmfEventTableColumn.BaseColumns.REFERENCE, + new PcapProtocolColumn(), + TmfEventTableColumn.BaseColumns.CONTENTS + ); + + /** + * The "packet source" column for pcap events + */ + private static class PcapSourceColumn extends TmfEventTableColumn { + + public PcapSourceColumn() { + super(getString(Messages.PcapEventsTable_Source)); + } + + @Override + public String getItemString(ITmfEvent event) { + if (!(event instanceof PcapEvent)) { + return EMPTY_STRING; + } + PcapEvent pcapEvent = (PcapEvent) event; + TmfPcapProtocol protocol = pcapEvent.getMostEncapsulatedProtocol(); + + return getString(pcapEvent.getSourceEndpoint(protocol)); + } + + @Override + public @Nullable String getFilterFieldId() { + return PcapEvent.EVENT_FIELD_PACKET_SOURCE; + } + } + + /** + * The "packet destination" column for pcap events + */ + private static class PcapDestinationColumn extends TmfEventTableColumn { + + public PcapDestinationColumn() { + super(getString(Messages.PcapEventsTable_Destination)); + } + + @Override + public String getItemString(ITmfEvent event) { + if (!(event instanceof PcapEvent)) { + return EMPTY_STRING; + } + PcapEvent pcapEvent = (PcapEvent) event; + TmfPcapProtocol protocol = pcapEvent.getMostEncapsulatedProtocol(); + return getString(pcapEvent.getDestinationEndpoint(protocol)); + } + + @Override + public @Nullable String getFilterFieldId() { + return PcapEvent.EVENT_FIELD_PACKET_DESTINATION; + } + } + + /** + * The "packet protocol" column for pcap events + */ + private static class PcapProtocolColumn extends TmfEventTableColumn { + + public PcapProtocolColumn() { + super(getString(Messages.PcapEventsTable_Protocol)); + } + + @Override + public String getItemString(ITmfEvent event) { + if (!(event instanceof PcapEvent)) { + return EMPTY_STRING; + } + PcapEvent pcapEvent = (PcapEvent) event; + TmfPcapProtocol protocol = pcapEvent.getMostEncapsulatedProtocol(); + + @SuppressWarnings("null") + @NonNull String proto = protocol.getShortName().toUpperCase(); + return proto; + } + + @Override + public @Nullable String getFilterFieldId() { + return PcapEvent.EVENT_FIELD_PACKET_PROTOCOL; + } + } + + /** + * Little convenience method to work around the incompatibilities between + * null annotations and NLS files... + */ + private static String getString(@Nullable String str) { + return (str == null ? "" : str); //$NON-NLS-1$ + } + + // ------------------------------------------------------------------------ + // ITmfEventTableColumns + // ------------------------------------------------------------------------ + + @Override + public Collection getEventTableColumns() { + return PCAP_COLUMNS; + } +} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/messages.properties b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/messages.properties new file mode 100644 index 0000000000..fe4006df00 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/messages.properties @@ -0,0 +1,18 @@ +############################################################################### +# Copyright (c) 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### + +PcapEventsTable_Content=Content +PcapEventsTable_Destination=Destination +PcapEventsTable_Protocol=Protocol +PcapEventsTable_Reference=Reference +PcapEventsTable_Source=Source +PcapEventsTable_Timestamp=Timestamp diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/package-info.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/package-info.java new file mode 100644 index 0000000000..001822976a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/package-info.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +@org.eclipse.jdt.annotation.NonNullByDefault +package org.eclipse.tracecompass.internal.tmf.pcap.ui.editor; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/package-info.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/package-info.java new file mode 100644 index 0000000000..0106fac7fd --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/package-info.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +@org.eclipse.jdt.annotation.NonNullByDefault +package org.eclipse.tracecompass.internal.tmf.pcap.ui; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/stream/Messages.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/stream/Messages.java new file mode 100644 index 0000000000..f0880db772 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/stream/Messages.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.ui.stream; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.osgi.util.NLS; + +@SuppressWarnings("javadoc") +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.tmf.pcap.ui.stream.messages"; //$NON-NLS-1$ + + public static @Nullable String StreamListView_BPSAtoB; + public static @Nullable String StreamListView_BPSBtoA; + public static @Nullable String StreamListView_BytesAtoB; + public static @Nullable String StreamListView_BytesBtoA; + public static @Nullable String StreamListView_Clear; + public static @Nullable String StreamListView_Duration; + public static @Nullable String StreamListView_EndpointA; + public static @Nullable String StreamListView_EndpointB; + public static @Nullable String StreamListView_ExtractAsFilter; + public static @Nullable String StreamListView_FilterName_Stream; + public static @Nullable String StreamListView_FollowStream; + public static @Nullable String StreamListView_ID; + public static @Nullable String StreamListView_PacketsAtoB; + public static @Nullable String StreamListView_PacketsBtoA; + public static @Nullable String StreamListView_StartTime; + public static @Nullable String StreamListView_StopTime; + public static @Nullable String StreamListView_TotalBytes; + public static @Nullable String StreamListView_TotalPackets; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/stream/StreamListView.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/stream/StreamListView.java new file mode 100644 index 0000000000..7c49d15406 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/stream/StreamListView.java @@ -0,0 +1,498 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.pcap.ui.stream; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.tracecompass.internal.tmf.pcap.core.analysis.StreamListAnalysis; +import org.eclipse.tracecompass.internal.tmf.pcap.core.event.PcapEvent; +import org.eclipse.tracecompass.internal.tmf.pcap.core.event.TmfPacketStream; +import org.eclipse.tracecompass.internal.tmf.pcap.core.event.TmfPacketStreamBuilder; +import org.eclipse.tracecompass.internal.tmf.pcap.core.protocol.TmfPcapProtocol; +import org.eclipse.tracecompass.internal.tmf.pcap.core.signal.TmfPacketStreamSelectedSignal; +import org.eclipse.tracecompass.internal.tmf.pcap.core.trace.PcapTrace; +import org.eclipse.tracecompass.internal.tmf.pcap.ui.Activator; +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterAndNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterContainsNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterOrNode; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.project.model.TraceUtils; +import org.eclipse.tracecompass.tmf.ui.views.TmfView; +import org.eclipse.tracecompass.tmf.ui.views.filter.FilterManager; +import org.eclipse.tracecompass.tmf.ui.views.filter.FilterView; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; + +/** + * Class that represents the Stream List View. Such a view lists all the + * available streams from the current experiment.
+ *
+ * TODO Switch to TmfUiRefreshHandler once the behavior is fixed + * + * FIXME analysis is leaking ressource. Someone I will not name told me not to worry about it since + * AnalysisModule will not be autocloseable later. + * + * @author Vincent Perot + */ +public class StreamListView extends TmfView { + + /** + * The Stream List View ID. + */ + public static final String ID = "org.eclipse.linuxtools.tmf.pcap.ui.view.stream.list"; //$NON-NLS-1$ + + private static final String[] COLUMN_NAMES = + { Messages.StreamListView_ID, + Messages.StreamListView_EndpointA, + Messages.StreamListView_EndpointB, + Messages.StreamListView_TotalPackets, + Messages.StreamListView_TotalBytes, + Messages.StreamListView_PacketsAtoB, + Messages.StreamListView_BytesAtoB, + Messages.StreamListView_PacketsBtoA, + Messages.StreamListView_BytesBtoA, + Messages.StreamListView_StartTime, + Messages.StreamListView_StopTime, + Messages.StreamListView_Duration, + Messages.StreamListView_BPSAtoB, + Messages.StreamListView_BPSBtoA + }; + + private static final int[] COLUMN_SIZES = + { 75, + 350, + 350, + 110, + 110, + 110, + 110, + 110, + 110, + 180, + 180, + 110, + 110, + 110 }; + + private static final String KEY_PROTOCOL = "$protocol$"; //$NON-NLS-1$ + private static final String KEY_STREAM = "$stream$"; //$NON-NLS-1$ + + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + + private static final long WAIT_TIME = 1000; + + private @Nullable CTabFolder fTabFolder; + private @Nullable Map fTableMap; + + private @Nullable TmfPacketStream fCurrentStream; + private @Nullable ITmfTrace fCurrentTrace; + + private volatile boolean fStopThread; + + /** + * Constructor of the StreamListView class. + */ + public StreamListView() { + super(ID); + } + + /** + * Handler called when an trace is opened. + * + * @param signal + * Contains the information about the selection. + */ + @TmfSignalHandler + public void traceOpened(TmfTraceOpenedSignal signal) { + fCurrentTrace = signal.getTrace(); + resetView(); + queryAnalysis(); + } + + /** + * Handler called when an trace is closed. Checks if the trace is the + * current trace and update the view accordingly. + * + * @param signal + * Contains the information about the selection. + */ + @TmfSignalHandler + public void traceClosed(TmfTraceClosedSignal signal) { + if (fCurrentTrace == signal.getTrace()) { + fCurrentTrace = null; + resetView(); + } + } + + /** + * Handler called when an trace is selected. Checks if the trace has changed + * and requests the selected trace if it has not yet been cached. + * + * @param signal + * Contains the information about the selection. + */ + @TmfSignalHandler + public void traceSelected(TmfTraceSelectedSignal signal) { + if (fCurrentTrace != signal.getTrace()) { + fCurrentTrace = signal.getTrace(); + resetView(); + queryAnalysis(); + } + } + + private void queryAnalysis() { + Thread thread = new Thread(new Runnable() { + + @Override + public void run() { + ITmfTrace trace = fCurrentTrace; + if (trace == null || (!(trace instanceof PcapTrace))) { + return; + } + StreamListAnalysis analysis = trace.getAnalysisModuleOfClass(StreamListAnalysis.class, StreamListAnalysis.ID); + if (analysis == null) { + return; + } + while (!analysis.isFinished() && !fStopThread) { + updateUI(); + try { + Thread.sleep(WAIT_TIME); + } catch (InterruptedException e) { + String message = e.getMessage(); + if (message == null) { + message = EMPTY_STRING; + } + Activator.logError(message, e); + return; + } + } + // Update UI one more time (daft punk) + if (!fStopThread) { + updateUI(); + } + + } + }); + + fStopThread = false; + thread.start(); + } + + private void resetView() { + + // Stop thread if needed + fStopThread = true; + + // Remove all content in tables + final Display display = Display.getDefault(); + if (display == null || display.isDisposed()) { + return; + } + display.asyncExec(new Runnable() { + + @Override + public void run() { + if (display.isDisposed()) { + return; + } + Map tableMap = fTableMap; + if (tableMap == null) { + return; + } + for (TmfPcapProtocol protocol : tableMap.keySet()) { + if (!(tableMap.get(protocol).isDisposed())) { + tableMap.get(protocol).removeAll(); + } + } + } + }); + } + + private void updateUI() { + final Display display = Display.getDefault(); + if (display == null || display.isDisposed()) { + return; + } + display.asyncExec(new Runnable() { + + @Override + public void run() { + if (display.isDisposed()) { + return; + } + ITmfTrace trace = fCurrentTrace; + if (trace == null) { + return; + } + + StreamListAnalysis analysis = trace.getAnalysisModuleOfClass(StreamListAnalysis.class, StreamListAnalysis.ID); + if (analysis == null) { + return; + } + + Map tables = fTableMap; + if (tables == null) { + return; + } + for (TmfPcapProtocol p : tables.keySet()) { + @SuppressWarnings("null") + @NonNull TmfPcapProtocol protocol = p; + TmfPacketStreamBuilder builder = analysis.getBuilder(protocol); + if (builder != null && !(tables.get(protocol).isDisposed())) { + for (TmfPacketStream stream : builder.getStreams()) { + + TableItem item; + if (stream.getID() < tables.get(protocol).getItemCount()) { + item = tables.get(protocol).getItem(stream.getID()); + } else { + item = new TableItem(tables.get(protocol), SWT.NONE); + } + item.setText(0, String.valueOf(stream.getID())); + item.setText(1, stream.getFirstEndpoint().toString()); + item.setText(2, stream.getSecondEndpoint().toString()); + item.setText(3, String.valueOf(stream.getNbPackets())); + item.setText(4, String.valueOf(stream.getNbBytes())); + item.setText(5, String.valueOf(stream.getNbPacketsAtoB())); + item.setText(6, String.valueOf(stream.getNbBytesAtoB())); + item.setText(7, String.valueOf(stream.getNbPacketsBtoA())); + item.setText(8, String.valueOf(stream.getNbBytesBtoA())); + item.setText(9, stream.getStartTime().toString()); + item.setText(10, stream.getStopTime().toString()); + item.setText(11, String.format("%.3f", stream.getDuration())); //$NON-NLS-1$ + item.setText(12, String.format("%.3f", stream.getBPSAtoB())); //$NON-NLS-1$ + item.setText(13, String.format("%.3f", stream.getBPSBtoA())); //$NON-NLS-1$ + item.setData(KEY_STREAM, stream); + } + } + } + } + + }); + } + + @Override + public void createPartControl(@Nullable Composite parent) { + // Initialize + fTableMap = new HashMap<>(); + fCurrentTrace = getActiveTrace(); + fCurrentStream = null; + + // Add a tab folder + fTabFolder = new CTabFolder(parent, SWT.NONE); + fTabFolder.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(@Nullable SelectionEvent e) { + Map tables = fTableMap; + if (tables == null || e == null) { + return; + } + TmfPcapProtocol protocol = (TmfPcapProtocol) e.item.getData(KEY_PROTOCOL); + tables.get(protocol).deselectAll(); + fCurrentStream = null; + } + + }); + + // Add items and tables for each protocol + for (TmfPcapProtocol protocol : TmfPcapProtocol.values()) { + if (protocol.supportsStream()) { + CTabItem item = new CTabItem(fTabFolder, SWT.NONE); + item.setText(protocol.getName()); + item.setData(KEY_PROTOCOL, protocol); + Table table = new Table(fTabFolder, SWT.NONE); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + // Add columns to table + for (int i = 0; i < COLUMN_NAMES.length || i < COLUMN_SIZES.length; i++) { + TableColumn column = new TableColumn(table, SWT.NONE); + column.setText(COLUMN_NAMES[i]); + column.setWidth(COLUMN_SIZES[i]); + } + item.setControl(table); + table.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(@Nullable SelectionEvent e) { + if (e == null) { + return; + } + fCurrentStream = (TmfPacketStream) e.item.getData(KEY_STREAM); + } + + }); + + Map tables = fTableMap; + if (tables == null) { + return; + } + + tables.put(protocol, table); + + // Add right click menu + Menu menu = new Menu(table); + MenuItem menuItem = new MenuItem(menu, SWT.PUSH); + menuItem.setText(Messages.StreamListView_FollowStream); + menuItem.addListener(SWT.Selection, new Listener() { + + @Override + public void handleEvent(@Nullable Event event) { + TmfSignal signal = new TmfPacketStreamSelectedSignal(this, 0, fCurrentStream); + TmfSignalManager.dispatchSignal(signal); + } + }); + menuItem = new MenuItem(menu, SWT.PUSH); + menuItem.setText(Messages.StreamListView_Clear); + menuItem.addListener(SWT.Selection, new Listener() { + + @Override + public void handleEvent(@Nullable Event event) { + TmfSignal signal = new TmfPacketStreamSelectedSignal(this, 0, null); + TmfSignalManager.dispatchSignal(signal); + + } + }); + menuItem = new MenuItem(menu, SWT.PUSH); + menuItem.setText(Messages.StreamListView_ExtractAsFilter); + menuItem.addListener(SWT.Selection, new Listener() { + + @Override + public void handleEvent(@Nullable Event event) { + // Generate filter. + ITmfFilterTreeNode filter = generateFilter(); + + // Update view and XML + updateFilters(filter); + + } + + private void updateFilters(@Nullable ITmfFilterTreeNode filter) { + if (filter == null) { + return; + } + + // Update XML + List newFilters = new ArrayList<>(); + ITmfFilterTreeNode[] oldFilters = FilterManager.getSavedFilters(); + for (int i = 0; i < oldFilters.length; i++) { + newFilters.add(oldFilters[i]); + } + if (!(newFilters.contains(filter))) { + newFilters.add(filter); + FilterManager.setSavedFilters(newFilters.toArray(new ITmfFilterTreeNode[newFilters.size()])); + } + + // Update Filter View + try { + final IWorkbench wb = PlatformUI.getWorkbench(); + final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); + IViewPart view = activePage.showView(FilterView.ID); + FilterView filterView = (FilterView) view; + filterView.addFilter(filter); + } catch (final PartInitException e) { + TraceUtils.displayErrorMsg(Messages.StreamListView_ExtractAsFilter, "Error opening view " + FilterView.ID + e.getMessage()); //$NON-NLS-1$ + Activator.logError("Error opening view " + FilterView.ID, e); //$NON-NLS-1$ + return; + } + + } + + private @Nullable ITmfFilterTreeNode generateFilter() { + TmfPacketStream stream = fCurrentStream; + if (stream == null) { + return null; + } + + // First stage - root + String name = Messages.StreamListView_FilterName_Stream + ' ' + stream.getProtocol().getShortName() + ' ' + stream.getFirstEndpoint() + + " <--> " + stream.getSecondEndpoint(); //$NON-NLS-1$ + TmfFilterNode root = new TmfFilterNode(name); + + // Second stage - and + TmfFilterAndNode and = new TmfFilterAndNode(root); + + // Third stage - protocol + or + TmfFilterContainsNode protocolFilter = new TmfFilterContainsNode(and); + protocolFilter.setField(stream.getProtocol().getName()); + protocolFilter.setValue(EMPTY_STRING); + TmfFilterOrNode or = new TmfFilterOrNode(and); + + // Fourth stage - and + TmfFilterAndNode andA = new TmfFilterAndNode(or); + TmfFilterAndNode andB = new TmfFilterAndNode(or); + + // Fourth stage - endpoints + TmfFilterContainsNode endpointAAndA = new TmfFilterContainsNode(andA); + endpointAAndA.setField(PcapEvent.EVENT_FIELD_PACKET_SOURCE); + endpointAAndA.setValue(stream.getFirstEndpoint()); + TmfFilterContainsNode endpointBAndA = new TmfFilterContainsNode(andA); + endpointBAndA.setField(PcapEvent.EVENT_FIELD_PACKET_DESTINATION); + endpointBAndA.setValue(stream.getSecondEndpoint()); + TmfFilterContainsNode endpointAAndB = new TmfFilterContainsNode(andB); + endpointAAndB.setField(PcapEvent.EVENT_FIELD_PACKET_SOURCE); + endpointAAndB.setValue(stream.getSecondEndpoint()); + TmfFilterContainsNode endpointBAndB = new TmfFilterContainsNode(andB); + endpointBAndB.setField(PcapEvent.EVENT_FIELD_PACKET_DESTINATION); + endpointBAndB.setValue(stream.getFirstEndpoint()); + + return root; + } + }); + table.setMenu(menu); + } + } + + // Ask the analysis for data. + queryAnalysis(); + } + + @Override + public void setFocus() { + CTabFolder tabFolder = fTabFolder; + if (tabFolder != null && !(tabFolder.isDisposed())) { + tabFolder.setFocus(); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/stream/messages.properties b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/stream/messages.properties new file mode 100644 index 0000000000..2ceb87c3b0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/stream/messages.properties @@ -0,0 +1,30 @@ +############################################################################### +# Copyright (c) 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### + +StreamListView_Clear=Clear +StreamListView_Duration=Duration +StreamListView_EndpointA=Endpoint A +StreamListView_EndpointB=Endpoint B +StreamListView_ExtractAsFilter=Extract as Filter +StreamListView_FilterName_Stream=stream +StreamListView_FollowStream=Follow Stream +StreamListView_ID=ID +StreamListView_TotalBytes=Bytes +StreamListView_TotalPackets=Packets +StreamListView_PacketsAtoB=Packets A -> B +StreamListView_PacketsBtoA=Packets B -> A +StreamListView_BytesAtoB=Bytes A -> B +StreamListView_BytesBtoA=Bytes B -> A +StreamListView_StartTime=Start Time +StreamListView_StopTime=Stop Time +StreamListView_BPSBtoA=BPS B -> A +StreamListView_BPSAtoB=BPS A -> B diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/stream/package-info.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/stream/package-info.java new file mode 100644 index 0000000000..026591be9a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/stream/package-info.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +@org.eclipse.jdt.annotation.NonNullByDefault +package org.eclipse.tracecompass.internal.tmf.pcap.ui.stream; \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/META-INF/MANIFEST.MF b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/META-INF/MANIFEST.MF index 67d8c7df8c..1be38feae9 100644 --- a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/META-INF/MANIFEST.MF @@ -7,8 +7,8 @@ Bundle-Localization: plugin Bundle-SymbolicName: org.eclipse.tracecompass.tmf.ui.swtbot.tests;singleton:=true Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.7 -Export-Package: org.eclipse.linuxtools.tmf.ui.swtbot.tests, - org.eclipse.linuxtools.tmf.ui.swtbot.tests.conditions +Export-Package: org.eclipse.tracecompass.tmf.ui.swtbot.tests, + org.eclipse.tracecompass.tmf.ui.swtbot.tests.conditions Require-Bundle: org.junit;bundle-version="4.0.0", org.eclipse.core.resources, org.eclipse.core.runtime, diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/pom.xml b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/pom.xml index 3166b551d7..1f74ce1bc8 100644 --- a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/pom.xml +++ b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/pom.xml @@ -33,7 +33,7 @@ ${tycho-version} org.eclipse.tracecompass.tmf.ui.swtbot.tests - org.eclipse.linuxtools.tmf.ui.swtbot.tests.AllTmfUISWTBotTests + org.eclipse.tracecompass.tmf.ui.swtbot.tests.AllTmfUISWTBotTests true false ${tycho.testArgLine} ${base.ui.test.vmargs} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/AbstractCustomParserWizard.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/AbstractCustomParserWizard.java deleted file mode 100644 index 2a9782d098..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/AbstractCustomParserWizard.java +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.swtbot.tests; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.RandomAccessFile; - -import org.apache.log4j.ConsoleAppender; -import org.apache.log4j.Logger; -import org.apache.log4j.SimpleLayout; -import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; -import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences; -import org.junit.BeforeClass; - -/** - * Abstract custom parser - * @author Matthew Khouzam - * - */ -public class AbstractCustomParserWizard { - - /** The Log4j logger instance. */ - static final Logger fLogger = Logger.getRootLogger(); - - /** - * The SWTBot running the test - */ - protected static SWTWorkbenchBot fBot; - - /** Test Class setup */ - @BeforeClass - public static void init() { - SWTBotUtil.failIfUIThread(); - Thread.currentThread().setName("SWTBot Thread"); // for the debugger - /* set up for swtbot */ - SWTBotPreferences.TIMEOUT = 20000; /* 20 second timeout */ - fLogger.addAppender(new ConsoleAppender(new SimpleLayout())); - fBot = new SWTWorkbenchBot(); - - SWTBotUtil.closeView("welcome", fBot); - - SWTBotUtil.switchToTracingPerspective(); - /* finish waiting for eclipse to load */ - SWTBotUtil.waitForJobs(); - - } - - /** - * Extract test XML file - * - * @param xmlFile - * the XML file to open - * @param category - * the category of the parser - * @param definitionName - * the name of the definition - * @return an XML string of the definition - * @throws IOException - * Error reading the file - * @throws FileNotFoundException - * File is not found - */ - protected static String extractTestXml(File xmlFile, String category, String definitionName) throws IOException, FileNotFoundException { - StringBuilder xmlPart = new StringBuilder(); - boolean started = false; - try (RandomAccessFile raf = new RandomAccessFile(xmlFile, "r");) { - String s = raf.readLine(); - while (s != null) { - if (s.equals("")) { - started = true; - } - if (started) { - if (s.equals("")) { - break; - } - xmlPart.append(s); - xmlPart.append('\n'); - } - s = raf.readLine(); - } - } - return xmlPart.toString(); - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/AbstractPerspectiveChecker.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/AbstractPerspectiveChecker.java deleted file mode 100644 index 85b50256e7..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/AbstractPerspectiveChecker.java +++ /dev/null @@ -1,111 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.swtbot.tests; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.Collection; -import java.util.List; - -import org.apache.log4j.Logger; -import org.apache.log4j.varia.NullAppender; -import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; -import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; -import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; -import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences; -import org.eclipse.ui.IViewReference; -import org.hamcrest.BaseMatcher; -import org.hamcrest.Description; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Tests perspectives to make sure they have all the views - * - * @author Matthew Khouzam - */ -@RunWith(SWTBotJunit4ClassRunner.class) -public abstract class AbstractPerspectiveChecker { - - private static SWTWorkbenchBot fBot; - /** The Log4j logger instance. */ - private static final Logger fLogger = Logger.getRootLogger(); - - /** - * The perspective id - */ - protected String fPerspectiveId; - /** - * the view id collection - */ - protected Collection fViewIds; - - /** Test Class setup */ - @BeforeClass - public static void beforeInit() { - SWTBotUtil.failIfUIThread(); - - /* set up for swtbot */ - SWTBotPreferences.TIMEOUT = 50000; /* 50 second timeout */ - fLogger.addAppender(new NullAppender()); - fBot = new SWTWorkbenchBot(); - - SWTBotUtil.closeView("welcome", fBot); - - } - - /** - * Gets the perspective and checks if all the views specified in the list - * are present in the perspective - */ - @Test - public void testPerspectiveForViews() { - SWTBotUtil.switchToPerspective(fPerspectiveId); - SWTBotUtil.waitForJobs(); - for (final String viewID : fViewIds) { - List view = fBot.views(new BaseMatcher() { - - @Override - public boolean matches(Object item) { - if (!(item instanceof IViewReference)) { - return false; - } - IViewReference reference = (IViewReference) item; - return reference.getId().equals(viewID); - } - - @Override - public void describeTo(Description description) { - } - - }); - assertEquals("view " + viewID + "is present", 1, view.size()); - } - } - - /** - * Gets the perspective and checks if all the views of that perspective are - * in the list - */ - @Test - public void testPerspectiveComplete() { - SWTBotUtil.switchToPerspective(fPerspectiveId); - SWTBotUtil.waitForJobs(); - for (SWTBotView view : fBot.views()) { - assertTrue("view " + view.toString() + "is present", fViewIds.contains(view.getViewReference().getId())); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/AllTmfUISWTBotTests.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/AllTmfUISWTBotTests.java deleted file mode 100644 index 0695023fae..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/AllTmfUISWTBotTests.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.swtbot.tests; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * SWTBot test suite for tmf.ui - * - * @author Matthew Khouzam - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TestCustomTxtWizard.class, - TestCustomXmlWizard.class, - TracingPerspectiveChecker.class, - org.eclipse.linuxtools.tmf.ui.swtbot.tests.table.AllTests.class -}) -public class AllTmfUISWTBotTests { -} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/SWTBotUtil.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/SWTBotUtil.java deleted file mode 100644 index 55224d9c67..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/SWTBotUtil.java +++ /dev/null @@ -1,275 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.swtbot.tests; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; - -import java.util.List; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.linuxtools.tmf.ui.editors.TmfEventsEditor; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfOpenTraceHelper; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.linuxtools.tmf.ui.swtbot.tests.conditions.ConditionHelpers; -import org.eclipse.linuxtools.tmf.ui.views.TracingPerspectiveFactory; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; -import org.eclipse.swtbot.eclipse.finder.matchers.WidgetMatcherFactory; -import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor; -import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; -import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; -import org.eclipse.swtbot.swt.finder.results.VoidResult; -import org.eclipse.swtbot.swt.finder.waits.Conditions; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotCheckBox; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IEditorReference; -import org.eclipse.ui.IPageLayout; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.WorkbenchException; -import org.hamcrest.Matcher; - -/** - * SWTBot Helper functions - * - * @author Matthew Khouzam - */ -public abstract class SWTBotUtil { - private static final String TRACING_PERSPECTIVE_ID = TracingPerspectiveFactory.ID; - - /** - * Waits for all Eclipse jobs to finish - */ - public static void waitForJobs() { - while (!Job.getJobManager().isIdle()) { - delay(100); - } - } - - /** - * Sleeps current thread for a given time. - * - * @param waitTimeMillis - * time in milliseconds to wait - */ - public static void delay(final long waitTimeMillis) { - try { - Thread.sleep(waitTimeMillis); - } catch (final InterruptedException e) { - // Ignored - } - } - - /** - * Create a tracing project - * - * @param projectName - * the name of the tracing project - */ - public static void createProject(final String projectName) { - /* - * Make a new test - */ - UIThreadRunnable.syncExec(new VoidResult() { - @Override - public void run() { - IProject project = TmfProjectRegistry.createProject(projectName, null, new NullProgressMonitor()); - assertNotNull(project); - } - }); - - SWTBotUtil.waitForJobs(); - } - - /** - * Deletes a tracing project - * - * @param projectName - * the name of the tracing project - * @param bot - * the workbench bot - */ - public static void deleteProject(String projectName, SWTWorkbenchBot bot) { - // Wait for any analysis to complete because it might create - // supplementary files - SWTBotUtil.waitForJobs(); - try { - ResourcesPlugin.getWorkspace().getRoot().getProject(projectName).refreshLocal(IResource.DEPTH_INFINITE, null); - } catch (CoreException e) { - } - - SWTBotUtil.waitForJobs(); - - final SWTBotView projectViewBot = bot.viewById(IPageLayout.ID_PROJECT_EXPLORER); - projectViewBot.setFocus(); - - SWTBotTree treeBot = projectViewBot.bot().tree(); - SWTBotTreeItem treeItem = treeBot.getTreeItem(projectName); - SWTBotMenu contextMenu = treeItem.contextMenu("Delete"); - contextMenu.click(); - - bot.shell("Delete Resources").setFocus(); - final SWTBotCheckBox checkBox = bot.checkBox(); - bot.waitUntil(Conditions.widgetIsEnabled(checkBox)); - checkBox.click(); - - final SWTBotButton okButton = bot.button("OK"); - bot.waitUntil(Conditions.widgetIsEnabled(okButton)); - okButton.click(); - - SWTBotUtil.waitForJobs(); - } - - /** - * Focus on the main window - * - * @param shellBots - * swtbotshells for all the shells - */ - public static void focusMainWindow(SWTBotShell[] shellBots) { - for (SWTBotShell shellBot : shellBots) { - if (shellBot.getText().toLowerCase().contains("eclipse")) { - shellBot.activate(); - } - } - } - - /** - * Close a view with a title - * - * @param title - * the title, like "welcome" - * @param bot - * the workbench bot - */ - public static void closeView(String title, SWTWorkbenchBot bot) { - final List openViews = bot.views(); - for (SWTBotView view : openViews) { - if (view.getTitle().equalsIgnoreCase(title)) { - view.close(); - bot.waitUntil(ConditionHelpers.ViewIsClosed(view)); - } - } - } - - /** - * Switch to the tracing perspective - */ - public static void switchToTracingPerspective() { - switchToPerspective(TRACING_PERSPECTIVE_ID); - } - - /** - * Switch to a given perspective - * - * @param id - * the perspective id (like - * "org.eclipse.linuxtools.tmf.ui.perspective" - */ - public static void switchToPerspective(final String id) { - UIThreadRunnable.syncExec(new VoidResult() { - @Override - public void run() { - try { - PlatformUI.getWorkbench().showPerspective(id, PlatformUI.getWorkbench().getActiveWorkbenchWindow()); - } catch (WorkbenchException e) { - fail(e.getMessage()); - } - } - }); - } - - /** - * If the test is running in the UI thread then fail - */ - public static void failIfUIThread() { - if (Display.getCurrent() != null && Display.getCurrent().getThread() == Thread.currentThread()) { - fail("SWTBot test needs to run in a non-UI thread. Make sure that \"Run in UI thread\" is unchecked in your launch configuration or" - + " that useUIThread is set to false in the pom.xml"); - } - - } - - /** - * Open a trace, this does not perform any validation though - * - * @param projectName - * The project name - * @param tracePath - * the path of the trace file (absolute or relative) - * @param traceType - * the trace canonical string (eg: - * org.eclipse.linuxtools.btf.trace) - */ - public static void openTrace(final String projectName, final String tracePath, final String traceType) { - final Exception exception[] = new Exception[1]; - exception[0] = null; - UIThreadRunnable.syncExec(new VoidResult() { - @Override - public void run() { - try { - IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); - TmfTraceFolder destinationFolder = TmfProjectRegistry.getProject(project, true).getTracesFolder(); - TmfOpenTraceHelper.openTraceFromPath(destinationFolder, tracePath, PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), traceType); - } catch (CoreException e) { - exception[0] = e; - } - } - }); - if (exception[0] != null) { - fail(exception[0].getMessage()); - } - - delay(1000); - waitForJobs(); - } - - /** - * Opens an editor and sets focus to the editor - * - * @param bot - * the workbench bot - * @param editorName - * the editor name - * @return the corresponding SWTBotEditor - */ - public static SWTBotEditor openEditor(SWTWorkbenchBot bot, String editorName) { - Matcher matcher = WidgetMatcherFactory.withPartName(editorName); - final SWTBotEditor editorBot = bot.editor(matcher); - IEditorPart iep = editorBot.getReference().getEditor(true); - final TmfEventsEditor tmfEd = (TmfEventsEditor) iep; - editorBot.show(); - UIThreadRunnable.syncExec(new VoidResult() { - @Override - public void run() { - tmfEd.setFocus(); - } - }); - - SWTBotUtil.waitForJobs(); - SWTBotUtil.delay(1000); - assertNotNull(tmfEd); - return editorBot; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/TestCustomTxtWizard.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/TestCustomTxtWizard.java deleted file mode 100644 index 17d007a65c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/TestCustomTxtWizard.java +++ /dev/null @@ -1,262 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.swtbot.tests; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileWriter; -import java.io.IOException; - -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; -import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Custom text wizard tests - * - * Some reminders to help making tests (javadoc to keep formatting) - * - * Button reminder - * - *

- * 0 Time Stamp Format Help
- * 1 Remove line
- * 2 Add next line
- * 3 Add child line
- * 4 Move up
- * 5 Move down
- * 6 Regular Expression Help
- * 7 Remove group (group 1 toggle)
- * 8 Remove group (group 2 toggle)
- * 9 Add group (group 3 toggle ...)
- * 10 Show parsing result
- * 11 Preview Legend
- * 
- * - * Combo box reminder - * - *
- * 0 cardinality
- * 1 event type (message, timestamp...)
- * 2 how to handle the data (set, append...)
- * repeat
- * 
- * - * @author Matthew Khouzam - * - */ -@RunWith(SWTBotJunit4ClassRunner.class) -public class TestCustomTxtWizard extends AbstractCustomParserWizard { - - private static final String MANAGE_CUSTOM_PARSERS_SHELL_TITLE = "Manage Custom Parsers"; - private static final String PROJECT_NAME = "TestText"; - private static final String CATEGORY_NAME = "Test Category"; - private static final String TRACETYPE_NAME = "Test Trace"; - private static final String EXPECTED_TEST_DEFINITION = "\n" + - "ss\n" + - "\n" + - "\n" + - "\\s*(\\d\\d)\\s(.*\\S)\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "([^0-9]*)\n" + - "\n" + - "\n" + - "\n" + - "\n"; - - /** - * Test to create a custom txt trace and compare the xml - * - * @throws IOException - * the xml file is not accessible, this is bad - * @throws FileNotFoundException - * the xml file wasn't written, this is bad - */ - @Test - public void testNew() throws FileNotFoundException, IOException { - File xmlFile = ResourcesPlugin.getWorkspace().getRoot().getLocation().append(".metadata/.plugins/org.eclipse.tracecompass.tmf.core/custom_txt_parsers.xml").toFile(); - SWTBotUtil.createProject(PROJECT_NAME); - SWTBotView proejctExplorerBot = fBot.viewByTitle("Project Explorer"); - proejctExplorerBot.show(); - SWTBotTreeItem treeItem = proejctExplorerBot.bot().tree().getTreeItem(PROJECT_NAME); - treeItem.select(); - treeItem.expand(); - SWTBotTreeItem treeNode = null; - for (String node : treeItem.getNodes()) { - if (node.startsWith("Trace")) { - treeNode = treeItem.getNode(node); - break; - } - - } - assertNotNull(treeNode); - treeNode.contextMenu("Manage Custom Parsers...").click(); - fBot.shell(MANAGE_CUSTOM_PARSERS_SHELL_TITLE).setFocus(); - - fBot.button("New...").click(); - - fBot.textWithLabel("Category:").setText(CATEGORY_NAME); - fBot.textWithLabel("Trace type:").setText(TRACETYPE_NAME); - fBot.textWithLabel("Time Stamp format:").setText("ss"); - fBot.comboBox(1).setSelection("Time Stamp"); - fBot.textWithLabel("format:").setText("ss"); - fBot.button(8).click(); - fBot.button(2).click(); - SWTBotTreeItem[] treeItems = fBot.tree().getAllItems(); - SWTBotTreeItem eventLine[] = new SWTBotTreeItem[2]; - treeItems = fBot.tree().getAllItems(); - for (SWTBotTreeItem item : treeItems) { - if (item.getText().startsWith("Root Line 1")) { - eventLine[0] = item; - } - if (item.getText().startsWith("Root Line 2")) { - eventLine[1] = item; - } - } - assertNotNull(eventLine[0]); - assertNotNull(eventLine[1]); - fBot.styledText().setText("12 Hello\nWorld\n23 Goodbye\ncruel world"); - eventLine[0].select(); - SWTBotUtil.waitForJobs(); - fBot.textWithLabel("Regular expression:").setText("\\s*(\\d\\d)\\s(.*\\S)"); - eventLine[1].select(); - fBot.textWithLabel("Regular expression:").setText("([^0-9]*)"); - fBot.button(7).click(); - fBot.comboBox("Set").setSelection("Append with |"); - fBot.button("Highlight All").click(); - fBot.button("Next >").click(); - fBot.button("Finish").click(); - String xmlPart = extractTestXml(xmlFile, CATEGORY_NAME, TRACETYPE_NAME); - assertEquals(EXPECTED_TEST_DEFINITION, xmlPart); - fBot.list().select(CATEGORY_NAME + " : " + TRACETYPE_NAME); - fBot.button("Delete").click(); - fBot.button("Yes").click(); - fBot.button("Close").click(); - xmlPart = extractTestXml(xmlFile, CATEGORY_NAME, TRACETYPE_NAME); - assertEquals("", xmlPart); - - SWTBotUtil.deleteProject(PROJECT_NAME, fBot); - } - - /** - * Test to edit a custom txt trace and compare the xml - * - * @throws IOException - * the xml file is not accessible, this is bad - * @throws FileNotFoundException - * the xml file wasn't written, this is bad - */ - @Test - public void testEdit() throws FileNotFoundException, IOException { - File xmlFile = ResourcesPlugin.getWorkspace().getRoot().getLocation().append(".metadata/.plugins/org.eclipse.tracecompass.tmf.core/custom_txt_parsers.xml").toFile(); - try (FileWriter fw = new FileWriter(xmlFile)) { - String xmlContent = "\n" + - "\n" + - "\n" + - "sss\n" + - "\n" + - "\n" + - "\\s*(\\d*)\\s(.*)\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "sssssss.ssssss\n" + - "\n" + - "\n" + - "^[([0-9]*\\.[0.9]*)]\\s(.*)\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - ""; - fw.write(xmlContent); - fw.flush(); - } - SWTBotUtil.createProject(PROJECT_NAME); - SWTBotView proejctExplorerBot = fBot.viewByTitle("Project Explorer"); - proejctExplorerBot.show(); - SWTBotTreeItem treeItem = proejctExplorerBot.bot().tree().getTreeItem(PROJECT_NAME); - treeItem.select(); - treeItem.expand(); - SWTBotTreeItem treeNode = null; - for (String node : treeItem.getNodes()) { - if (node.startsWith("Trace")) { - treeNode = treeItem.getNode(node); - break; - } - - } - assertNotNull(treeNode); - treeNode.contextMenu("Manage Custom Parsers...").click(); - fBot.shell(MANAGE_CUSTOM_PARSERS_SHELL_TITLE).setFocus(); - fBot.list().select("Demo Category : Demo trace"); - fBot.button("Edit...").click(); - - fBot.textWithLabel("Category:").setText(CATEGORY_NAME); - fBot.textWithLabel("Trace type:").setText(TRACETYPE_NAME); - fBot.textWithLabel("Time Stamp format:").setText("ss"); - fBot.comboBox(1).setSelection("Time Stamp"); - fBot.textWithLabel("format:").setText("ss"); - fBot.button(2).click(); - SWTBotTreeItem[] treeItems = fBot.tree().getAllItems(); - SWTBotTreeItem eventLine[] = new SWTBotTreeItem[2]; - for (SWTBotTreeItem item : treeItems) { - if (item.getText().startsWith("Root Line 1")) { - eventLine[0] = item; - } - if (item.getText().startsWith("Root Line 2")) { - eventLine[1] = item; - } - } - treeItems = fBot.tree().getAllItems(); - assertNotNull(eventLine[0]); - assertNotNull(eventLine[1]); - fBot.styledText().setText("12 Hello\nWorld\n23 Goodbye\ncruel world"); - eventLine[0].select(); - SWTBotUtil.waitForJobs(); - fBot.textWithLabel("Regular expression:").setText("\\s*(\\d\\d)\\s(.*\\S)"); - eventLine[1].select(); - fBot.textWithLabel("Regular expression:").setText("([^0-9]*)"); - fBot.button(7).click(); - fBot.comboBox("Set").setSelection("Append with |"); - fBot.button("Highlight All").click(); - fBot.button("Next >").click(); - fBot.button("Finish").click(); - String xmlPart = extractTestXml(xmlFile, CATEGORY_NAME, TRACETYPE_NAME); - assertEquals(EXPECTED_TEST_DEFINITION, xmlPart); - fBot.list().select(CATEGORY_NAME + " : " + TRACETYPE_NAME); - fBot.button("Delete").click(); - fBot.button("Yes").click(); - fBot.button("Close").click(); - xmlPart = extractTestXml(xmlFile, CATEGORY_NAME, TRACETYPE_NAME); - assertEquals("", xmlPart); - - SWTBotUtil.deleteProject(PROJECT_NAME, fBot); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/TestCustomXmlWizard.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/TestCustomXmlWizard.java deleted file mode 100644 index ca9e256469..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/TestCustomXmlWizard.java +++ /dev/null @@ -1,117 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.swtbot.tests; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; - -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; -import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Custom XML wizard tests - * - * This test will help validate the CustomXmlParserInputWizardPage - * - * @author Matthew Khouzam - * - */ -@RunWith(SWTBotJunit4ClassRunner.class) -public class TestCustomXmlWizard extends AbstractCustomParserWizard { - - private static final String EVENT = "event"; - private static final String TRACE = "trace"; - private static final String XML_TRACE1 = "\n\t\n\t"; - private static final String MANAGE_CUSTOM_PARSERS_SHELL_TITLE = "Manage Custom Parsers"; - private static final String PROJECT_NAME = "TestXML"; - private static final String CATEGORY_NAME = "Test Category"; - private static final String TRACETYPE_NAME = "Test Trace"; - private static final String EXPECTED_TEST_DEFINITION = "\n" + - "ss\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n"; - - /** - * Test to create a custom XML trace and compare the XML generated - * - * @throws IOException - * the xml file is not accessible, this is bad - * @throws FileNotFoundException - * the xml file wasn't written, this is bad - */ - @Test - public void testNew() throws FileNotFoundException, IOException { - File xmlFile = ResourcesPlugin.getWorkspace().getRoot().getLocation().append(".metadata/.plugins/org.eclipse.tracecompass.tmf.core/custom_xml_parsers.xml").toFile(); - SWTBotUtil.createProject(PROJECT_NAME); - SWTBotView proejctExplorerBot = fBot.viewByTitle("Project Explorer"); - proejctExplorerBot.show(); - SWTBotTreeItem treeItem = proejctExplorerBot.bot().tree().getTreeItem(PROJECT_NAME); - treeItem.select(); - treeItem.expand(); - SWTBotTreeItem treeNode = null; - for (String node : treeItem.getNodes()) { - if (node.startsWith("Trace")) { - treeNode = treeItem.getNode(node); - break; - } - - } - assertNotNull(treeNode); - treeNode.contextMenu("Manage Custom Parsers...").click(); - fBot.shell(MANAGE_CUSTOM_PARSERS_SHELL_TITLE).setFocus(); - fBot.radio("XML").click(); - fBot.button("New...").click(); - fBot.textWithLabel("Category:").setText(CATEGORY_NAME); - fBot.textWithLabel("Trace type:").setText(TRACETYPE_NAME); - fBot.textWithLabel("Time Stamp format:").setText("ss"); - - fBot.styledText().setText(XML_TRACE1); - fBot.buttonWithTooltip("Feeling lucky").click(); - - fBot.tree().getTreeItem(TRACE).getNode(EVENT).select(); - fBot.checkBox("Log Entry").click(); - fBot.button("Next >").click(); - fBot.button("Finish").click(); - - String xmlPart = extractTestXml(xmlFile, CATEGORY_NAME, TRACETYPE_NAME); - assertEquals(EXPECTED_TEST_DEFINITION, xmlPart); - fBot.list().select(CATEGORY_NAME + " : " + TRACETYPE_NAME); - fBot.button("Delete").click(); - fBot.button("Yes").click(); - fBot.button("Close").click(); - xmlPart = extractTestXml(xmlFile, CATEGORY_NAME, TRACETYPE_NAME); - assertEquals("", xmlPart); - - SWTBotUtil.deleteProject(PROJECT_NAME, fBot); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/TracingPerspectiveChecker.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/TracingPerspectiveChecker.java deleted file mode 100644 index 67262c47c4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/TracingPerspectiveChecker.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.swtbot.tests; - -import java.util.ArrayList; -import java.util.Arrays; - -import org.eclipse.linuxtools.tmf.ui.views.TracingPerspectiveFactory; -import org.eclipse.linuxtools.tmf.ui.views.histogram.HistogramView; -import org.eclipse.linuxtools.tmf.ui.views.statistics.TmfStatisticsView; -import org.eclipse.ui.IPageLayout; -import org.junit.Before; - -/** - * Tracing perspective view checker - * - * @author Matthew Khouzam - */ -public class TracingPerspectiveChecker extends AbstractPerspectiveChecker { - - /** - * Set up arrays for test - */ - @Before - public void init() { - fPerspectiveId = TracingPerspectiveFactory.ID; - fViewIds = new ArrayList<>(); - fViewIds.addAll(Arrays.asList(new String[] { - HistogramView.ID, - TmfStatisticsView.ID, - // Standard Eclipse views - IPageLayout.ID_PROJECT_EXPLORER, - IPageLayout.ID_PROP_SHEET, - IPageLayout.ID_BOOKMARKS - })); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/ConditionHelpers.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/ConditionHelpers.java deleted file mode 100644 index e6fb0e7f9a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/ConditionHelpers.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.swtbot.tests.conditions; - -import org.eclipse.jface.wizard.IWizardPage; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; -import org.eclipse.swtbot.swt.finder.waits.ICondition; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; - -/** - * Is a tree node available - * - * @author Matthew Khouzam - */ -public abstract class ConditionHelpers { - - /** - * Is a tree node available - * - * @param name - * the name of the node - * @param tree - * the parent tree - * @return true or false, it should swallow all exceptions - */ - public static ICondition IsTreeNodeAvailable(String name, SWTBotTree tree) { - return new TreeNodeAvailable(name, tree); - } - - /** - * Is the treeItem's node available - * - * @param name - * the name of the node - * @param treeItem - * the treeItem - * @return true or false, it should swallow all exceptions - */ - public static ICondition IsTreeChildNodeAvailable(String name, SWTBotTreeItem treeItem) { - return new TreeItemNodeAvailable(name, treeItem); - } - - /** - * Checks if the wizard's shell is null - * - * @param wizard - * the null - * @return false if either are null - */ - public static ICondition isWizardReady(Wizard wizard) { - return new WizardReady(wizard); - } - - /** - * Is the wizard on the page you want? - * - * @param wizard - * wizard - * @param desiredPage - * the desired page - * @return true or false - */ - public static ICondition isWizardOnPage(Wizard wizard, IWizardPage desiredPage) { - return new WizardOnPage(wizard, desiredPage); - } - - /** - * Wait for a view to close - * - * @param view - * bot view for the view - * @return true if the view is closed, false if it's active. - */ - public static ICondition ViewIsClosed(SWTBotView view) { - return new ViewClosed(view); - } - - /** - * Wait till table cell has a given content. - * - * @param table - * the table bot reference - * @param content - * the content to check - * @param row - * the row of the cell - * @param column - * the column of the cell - * @return ICondition for verification - */ - public static ICondition isTableCellFilled(SWTBotTable table, String content, int row, int column) { - return new TableCellFilled(table, content, row, column); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/TableCellFilled.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/TableCellFilled.java deleted file mode 100644 index 29be0e6637..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/TableCellFilled.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.swtbot.tests.conditions; - -import org.eclipse.swtbot.swt.finder.SWTBot; -import org.eclipse.swtbot.swt.finder.waits.ICondition; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable; - -/** - * Is a table cell filled? tests if the table cell has a given content. - * - * @author Bernd Hufmann - */ -class TableCellFilled implements ICondition { - - private final SWTBotTable fTable; - private final String fContent; - private final int fRow; - private final int fColumn; - - public TableCellFilled(SWTBotTable table, String content, int row, int column) { - fTable = table; - fContent = content; - fRow = row; - fColumn = column; - } - - @Override - public boolean test() throws Exception { - try { - return fContent.equals(fTable.cell(fRow, fColumn)); - } catch (Exception e) { - } - return false; - } - - @Override - public void init(SWTBot bot) { - } - - @Override - public String getFailureMessage() { - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/TreeItemNodeAvailable.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/TreeItemNodeAvailable.java deleted file mode 100644 index 402964478c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/TreeItemNodeAvailable.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.swtbot.tests.conditions; - -import org.eclipse.swtbot.swt.finder.SWTBot; -import org.eclipse.swtbot.swt.finder.waits.ICondition; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; - -/** - * Is a TreeItem's node available? tests if the tree has an item with a given name - * - * @author Matthew Khouzam - */ -class TreeItemNodeAvailable implements ICondition { - - private final SWTBotTreeItem fTreeItem; - private final String fName; - - public TreeItemNodeAvailable(String name, SWTBotTreeItem treeItem) { - fName = name; - fTreeItem = treeItem; - } - - @Override - public boolean test() throws Exception { - try { - return fTreeItem.getNode(fName) != null; - } catch (Exception e) { - } - return false; - } - - @Override - public void init(SWTBot bot) { - } - - @Override - public String getFailureMessage() { - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/TreeNodeAvailable.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/TreeNodeAvailable.java deleted file mode 100644 index 0e9894ec3c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/TreeNodeAvailable.java +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.swtbot.tests.conditions; - -import org.eclipse.swtbot.swt.finder.SWTBot; -import org.eclipse.swtbot.swt.finder.waits.ICondition; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; - -/** - * Is a tree node available? - * - * @author Matthew Khouzam - */ -class TreeNodeAvailable implements ICondition { - - private final SWTBotTree fTree; - private final String fName; - - /** - * Is a tree node available - * - * @param name - * The name of the node - * @param tree - * the swtbotTree - */ - public TreeNodeAvailable(String name, SWTBotTree tree) { - fTree = tree; - fName = name; - } - - @Override - public boolean test() throws Exception { - try { - final SWTBotTreeItem[] treeItems = fTree.getAllItems(); - for( SWTBotTreeItem ti : treeItems){ - final String text = ti.getText(); - if( text.equals(fName)) { - return true; - } - } - } catch (Exception e) { - } - return false; - } - - @Override - public void init(SWTBot bot) { - } - - @Override - public String getFailureMessage() { - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/ViewClosed.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/ViewClosed.java deleted file mode 100644 index d128277b58..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/ViewClosed.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.swtbot.tests.conditions; - -import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; -import org.eclipse.swtbot.swt.finder.SWTBot; -import org.eclipse.swtbot.swt.finder.waits.ICondition; - -/** - * Is a view closed? - * - * @author Matthew Khouzam - */ -class ViewClosed implements ICondition { - private final SWTBotView fView; - - public ViewClosed(SWTBotView view) { - fView = view; - } - - @Override - public boolean test() throws Exception { - return (fView != null) && (!fView.isActive()); - } - - @Override - public void init(SWTBot bot) { - } - - @Override - public String getFailureMessage() { - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/WizardOnPage.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/WizardOnPage.java deleted file mode 100644 index 8d4d1d8e8b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/WizardOnPage.java +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.swtbot.tests.conditions; - -import org.eclipse.jface.wizard.IWizardContainer; -import org.eclipse.jface.wizard.IWizardPage; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.swtbot.swt.finder.SWTBot; -import org.eclipse.swtbot.swt.finder.waits.ICondition; - -/** - * Is the wizard on the page you want? - * @author Matthew Khouzam - */ -class WizardOnPage implements ICondition { - - private final Wizard fWizard; - private final IWizardPage fPage; - - public WizardOnPage(Wizard wizard, IWizardPage desiredPage) { - fWizard = wizard; - fPage = desiredPage; - } - - @Override - public boolean test() throws Exception { - if (fWizard == null || fPage == null) { - return false; - } - final IWizardContainer container = fWizard.getContainer(); - if (container == null) { - return false; - } - IWizardPage currentPage = container.getCurrentPage(); - return fPage.equals(currentPage); - } - - @Override - public void init(SWTBot bot) { - } - - @Override - public String getFailureMessage() { - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/WizardReady.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/WizardReady.java deleted file mode 100644 index 046c5654e3..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/conditions/WizardReady.java +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.swtbot.tests.conditions; - -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.swtbot.swt.finder.SWTBot; -import org.eclipse.swtbot.swt.finder.waits.ICondition; - -/** - * Is a given wizard ready? - * - * @author Matthew Khouzam - */ -class WizardReady implements ICondition { - - private final Wizard fWizard; - - public WizardReady(Wizard wizard) { - fWizard = wizard; - } - - @Override - public boolean test() throws Exception { - if (fWizard.getShell() == null) { - return false; - } - return true; - } - - @Override - public void init(SWTBot bot) { - } - - @Override - public String getFailureMessage() { - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/table/AllTests.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/table/AllTests.java deleted file mode 100644 index 55d6983991..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/table/AllTests.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.swtbot.tests.table; - -import org.junit.Ignore; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * SWTBot test suite for testing of the TMF events table. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - CollapseEventsInTableTest.class, -}) -@Ignore -public class AllTests { -} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/table/CollapseEventsInTableTest.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/table/CollapseEventsInTableTest.java deleted file mode 100644 index 1b83805905..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/linuxtools/tmf/ui/swtbot/tests/table/CollapseEventsInTableTest.java +++ /dev/null @@ -1,195 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.swtbot.tests.table; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeTrue; - -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; - -import org.apache.log4j.ConsoleAppender; -import org.apache.log4j.Logger; -import org.apache.log4j.SimpleLayout; -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.preferences.IEclipsePreferences; -import org.eclipse.core.runtime.preferences.InstanceScope; -import org.eclipse.jface.bindings.keys.IKeyLookup; -import org.eclipse.jface.bindings.keys.KeyStroke; -import org.eclipse.jface.bindings.keys.ParseException; -import org.eclipse.linuxtools.internal.tmf.core.Activator; -import org.eclipse.linuxtools.tmf.core.tests.TmfCoreTestPlugin; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimePreferencesConstants; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampFormat; -import org.eclipse.linuxtools.tmf.ui.swtbot.tests.SWTBotUtil; -import org.eclipse.linuxtools.tmf.ui.swtbot.tests.conditions.ConditionHelpers; -import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; -import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor; -import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; -import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * SWTBot test for testing collapsing feature. - * - * @author Bernd Hufmann - */ -@RunWith(SWTBotJunit4ClassRunner.class) -public class CollapseEventsInTableTest { - - private static final String TRACE_PROJECT_NAME = "test"; - private static final String COLLAPSE_TRACE_NAME = "syslog_collapse"; - private static final String COLLAPSE_TRACE_PATH = "testfiles/" + COLLAPSE_TRACE_NAME; - private static final String COLLAPSE_TRACE_TYPE = "org.eclipse.linuxtools.tmf.tests.stubs.trace.text.testsyslog"; - - private static File fTestFile = null; - - private static SWTWorkbenchBot fBot; - - /** The Log4j logger instance. */ - private static final Logger fLogger = Logger.getRootLogger(); - - /** - * Test Class setup - */ - @BeforeClass - public static void init() { - SWTBotUtil.failIfUIThread(); - - /* set up test trace*/ - URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(COLLAPSE_TRACE_PATH), null); - URI uri; - try { - uri = FileLocator.toFileURL(location).toURI(); - fTestFile = new File(uri); - } catch (URISyntaxException | IOException e) { - e.printStackTrace(); - fail(); - } - - assumeTrue(fTestFile.exists()); - - IEclipsePreferences defaultPreferences = InstanceScope.INSTANCE.getNode(Activator.PLUGIN_ID); - defaultPreferences.put(ITmfTimePreferencesConstants.DATIME, "MMM d HH:mm:ss"); - defaultPreferences.put(ITmfTimePreferencesConstants.SUBSEC, ITmfTimePreferencesConstants.SUBSEC_NO_FMT); - TmfTimestampFormat.updateDefaultFormats(); - - /* Set up for swtbot */ - SWTBotPreferences.TIMEOUT = 20000; /* 20 second timeout */ - fLogger.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender.SYSTEM_OUT)); - fBot = new SWTWorkbenchBot(); - - /* Close welcome view */ - SWTBotUtil.closeView("Welcome", fBot); - - /* Switch perspectives */ - SWTBotUtil.switchToTracingPerspective(); - - /* Finish waiting for eclipse to load */ - SWTBotUtil.waitForJobs(); - } - - /** - * Test class tear down method. - */ - @AfterClass - public static void tearDown() { - /* Set timestamp defaults */ - IEclipsePreferences defaultPreferences = InstanceScope.INSTANCE.getNode(Activator.PLUGIN_ID); - defaultPreferences.put(ITmfTimePreferencesConstants.DATIME, ITmfTimePreferencesConstants.TIME_HOUR_FMT); - defaultPreferences.put(ITmfTimePreferencesConstants.SUBSEC, ITmfTimePreferencesConstants.SUBSEC_NANO_FMT); - TmfTimestampFormat.updateDefaultFormats(); - } - - /** - * Main test case - */ - @Test - public void test() { - SWTBotUtil.createProject(TRACE_PROJECT_NAME); - SWTBotUtil.openTrace(TRACE_PROJECT_NAME, fTestFile.getAbsolutePath(), COLLAPSE_TRACE_TYPE); - SWTBotEditor editorBot = SWTBotUtil.openEditor(fBot, fTestFile.getName()); - - SWTBotTable tableBot = editorBot.bot().table(); - - /* Maximize editor area */ - maximizeTable(tableBot); - tableBot.click(1, 0); - - /* Collapse Events */ - SWTBotMenu menuBot = tableBot.contextMenu("Collapse Events"); - menuBot.click(); - fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "7/22", 1, 1)); - - String filterString = tableBot.cell(1, 1); - assertEquals("filterString", "7/22", filterString); - - /* Verify collapsed event */ - filterString = tableBot.cell(7, 0); - assertEquals("repeatCount", "+14", filterString); - - filterString = tableBot.cell(7, 1); - assertEquals("first timestamp", "Jan 1 06:06:06", filterString); - - filterString = tableBot.cell(7, 2); - assertEquals("source", "", filterString); - - filterString = tableBot.cell(7, 3); - assertEquals("type", "Syslog", filterString); - - filterString = tableBot.cell(7, 4); - assertEquals("file", "", filterString); - - filterString = tableBot.cell(7, 5); - assertEquals("content", "Timestamp=Jan 1 06:06:06, Host=HostF, Logger=LoggerF, Message=Message F", filterString); - - filterString = tableBot.cell(8, 0); - assertEquals("repeatCount", "+1", filterString); - - filterString = tableBot.cell(8, 1); - assertEquals("first timestamp (2nd collapse)", "Jan 1 06:06:21", filterString); - - filterString = tableBot.cell(8, 5); - assertEquals("content", "Timestamp=Jan 1 06:06:21, Host=HostF, Logger=LoggerF, Message=Message D", filterString); - - /* Clear Filter */ - menuBot = tableBot.contextMenu("Clear Filters"); - menuBot.click(); - fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "Jan 1 01:01:01", 1, 1)); - assertEquals("timestamp", "Jan 1 01:01:01", tableBot.cell(1, 1)); - - maximizeTable(tableBot); - - fBot.closeAllEditors(); - SWTBotUtil.deleteProject(TRACE_PROJECT_NAME, fBot); - } - - private static void maximizeTable(SWTBotTable tableBot) { - try { - tableBot.pressShortcut(KeyStroke.getInstance(IKeyLookup.CTRL_NAME + "+"), KeyStroke.getInstance("M")); - } catch (ParseException e) { - fail(); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/AbstractCustomParserWizard.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/AbstractCustomParserWizard.java new file mode 100644 index 0000000000..ca52225567 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/AbstractCustomParserWizard.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.swtbot.tests; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; + +import org.apache.log4j.ConsoleAppender; +import org.apache.log4j.Logger; +import org.apache.log4j.SimpleLayout; +import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; +import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences; +import org.junit.BeforeClass; + +/** + * Abstract custom parser + * @author Matthew Khouzam + * + */ +public class AbstractCustomParserWizard { + + /** The Log4j logger instance. */ + static final Logger fLogger = Logger.getRootLogger(); + + /** + * The SWTBot running the test + */ + protected static SWTWorkbenchBot fBot; + + /** Test Class setup */ + @BeforeClass + public static void init() { + SWTBotUtil.failIfUIThread(); + Thread.currentThread().setName("SWTBot Thread"); // for the debugger + /* set up for swtbot */ + SWTBotPreferences.TIMEOUT = 20000; /* 20 second timeout */ + fLogger.addAppender(new ConsoleAppender(new SimpleLayout())); + fBot = new SWTWorkbenchBot(); + + SWTBotUtil.closeView("welcome", fBot); + + SWTBotUtil.switchToTracingPerspective(); + /* finish waiting for eclipse to load */ + SWTBotUtil.waitForJobs(); + + } + + /** + * Extract test XML file + * + * @param xmlFile + * the XML file to open + * @param category + * the category of the parser + * @param definitionName + * the name of the definition + * @return an XML string of the definition + * @throws IOException + * Error reading the file + * @throws FileNotFoundException + * File is not found + */ + protected static String extractTestXml(File xmlFile, String category, String definitionName) throws IOException, FileNotFoundException { + StringBuilder xmlPart = new StringBuilder(); + boolean started = false; + try (RandomAccessFile raf = new RandomAccessFile(xmlFile, "r");) { + String s = raf.readLine(); + while (s != null) { + if (s.equals("")) { + started = true; + } + if (started) { + if (s.equals("")) { + break; + } + xmlPart.append(s); + xmlPart.append('\n'); + } + s = raf.readLine(); + } + } + return xmlPart.toString(); + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/AbstractPerspectiveChecker.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/AbstractPerspectiveChecker.java new file mode 100644 index 0000000000..ae23a4cc88 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/AbstractPerspectiveChecker.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.swtbot.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Collection; +import java.util.List; + +import org.apache.log4j.Logger; +import org.apache.log4j.varia.NullAppender; +import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; +import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; +import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; +import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences; +import org.eclipse.ui.IViewReference; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Tests perspectives to make sure they have all the views + * + * @author Matthew Khouzam + */ +@RunWith(SWTBotJunit4ClassRunner.class) +public abstract class AbstractPerspectiveChecker { + + private static SWTWorkbenchBot fBot; + /** The Log4j logger instance. */ + private static final Logger fLogger = Logger.getRootLogger(); + + /** + * The perspective id + */ + protected String fPerspectiveId; + /** + * the view id collection + */ + protected Collection fViewIds; + + /** Test Class setup */ + @BeforeClass + public static void beforeInit() { + SWTBotUtil.failIfUIThread(); + + /* set up for swtbot */ + SWTBotPreferences.TIMEOUT = 50000; /* 50 second timeout */ + fLogger.addAppender(new NullAppender()); + fBot = new SWTWorkbenchBot(); + + SWTBotUtil.closeView("welcome", fBot); + + } + + /** + * Gets the perspective and checks if all the views specified in the list + * are present in the perspective + */ + @Test + public void testPerspectiveForViews() { + SWTBotUtil.switchToPerspective(fPerspectiveId); + SWTBotUtil.waitForJobs(); + for (final String viewID : fViewIds) { + List view = fBot.views(new BaseMatcher() { + + @Override + public boolean matches(Object item) { + if (!(item instanceof IViewReference)) { + return false; + } + IViewReference reference = (IViewReference) item; + return reference.getId().equals(viewID); + } + + @Override + public void describeTo(Description description) { + } + + }); + assertEquals("view " + viewID + "is present", 1, view.size()); + } + } + + /** + * Gets the perspective and checks if all the views of that perspective are + * in the list + */ + @Test + public void testPerspectiveComplete() { + SWTBotUtil.switchToPerspective(fPerspectiveId); + SWTBotUtil.waitForJobs(); + for (SWTBotView view : fBot.views()) { + assertTrue("view " + view.toString() + "is present", fViewIds.contains(view.getViewReference().getId())); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/AllTmfUISWTBotTests.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/AllTmfUISWTBotTests.java new file mode 100644 index 0000000000..9c3e3b64c7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/AllTmfUISWTBotTests.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.swtbot.tests; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * SWTBot test suite for tmf.ui + * + * @author Matthew Khouzam + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TestCustomTxtWizard.class, + TestCustomXmlWizard.class, + TracingPerspectiveChecker.class, + org.eclipse.tracecompass.tmf.ui.swtbot.tests.table.AllTests.class +}) +public class AllTmfUISWTBotTests { +} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/SWTBotUtil.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/SWTBotUtil.java new file mode 100644 index 0000000000..fab54d6e64 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/SWTBotUtil.java @@ -0,0 +1,275 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.swtbot.tests; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.util.List; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; +import org.eclipse.swtbot.eclipse.finder.matchers.WidgetMatcherFactory; +import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor; +import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; +import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; +import org.eclipse.swtbot.swt.finder.results.VoidResult; +import org.eclipse.swtbot.swt.finder.waits.Conditions; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotCheckBox; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; +import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfOpenTraceHelper; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.tracecompass.tmf.ui.swtbot.tests.conditions.ConditionHelpers; +import org.eclipse.tracecompass.tmf.ui.views.TracingPerspectiveFactory; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.WorkbenchException; +import org.hamcrest.Matcher; + +/** + * SWTBot Helper functions + * + * @author Matthew Khouzam + */ +public abstract class SWTBotUtil { + private static final String TRACING_PERSPECTIVE_ID = TracingPerspectiveFactory.ID; + + /** + * Waits for all Eclipse jobs to finish + */ + public static void waitForJobs() { + while (!Job.getJobManager().isIdle()) { + delay(100); + } + } + + /** + * Sleeps current thread for a given time. + * + * @param waitTimeMillis + * time in milliseconds to wait + */ + public static void delay(final long waitTimeMillis) { + try { + Thread.sleep(waitTimeMillis); + } catch (final InterruptedException e) { + // Ignored + } + } + + /** + * Create a tracing project + * + * @param projectName + * the name of the tracing project + */ + public static void createProject(final String projectName) { + /* + * Make a new test + */ + UIThreadRunnable.syncExec(new VoidResult() { + @Override + public void run() { + IProject project = TmfProjectRegistry.createProject(projectName, null, new NullProgressMonitor()); + assertNotNull(project); + } + }); + + SWTBotUtil.waitForJobs(); + } + + /** + * Deletes a tracing project + * + * @param projectName + * the name of the tracing project + * @param bot + * the workbench bot + */ + public static void deleteProject(String projectName, SWTWorkbenchBot bot) { + // Wait for any analysis to complete because it might create + // supplementary files + SWTBotUtil.waitForJobs(); + try { + ResourcesPlugin.getWorkspace().getRoot().getProject(projectName).refreshLocal(IResource.DEPTH_INFINITE, null); + } catch (CoreException e) { + } + + SWTBotUtil.waitForJobs(); + + final SWTBotView projectViewBot = bot.viewById(IPageLayout.ID_PROJECT_EXPLORER); + projectViewBot.setFocus(); + + SWTBotTree treeBot = projectViewBot.bot().tree(); + SWTBotTreeItem treeItem = treeBot.getTreeItem(projectName); + SWTBotMenu contextMenu = treeItem.contextMenu("Delete"); + contextMenu.click(); + + bot.shell("Delete Resources").setFocus(); + final SWTBotCheckBox checkBox = bot.checkBox(); + bot.waitUntil(Conditions.widgetIsEnabled(checkBox)); + checkBox.click(); + + final SWTBotButton okButton = bot.button("OK"); + bot.waitUntil(Conditions.widgetIsEnabled(okButton)); + okButton.click(); + + SWTBotUtil.waitForJobs(); + } + + /** + * Focus on the main window + * + * @param shellBots + * swtbotshells for all the shells + */ + public static void focusMainWindow(SWTBotShell[] shellBots) { + for (SWTBotShell shellBot : shellBots) { + if (shellBot.getText().toLowerCase().contains("eclipse")) { + shellBot.activate(); + } + } + } + + /** + * Close a view with a title + * + * @param title + * the title, like "welcome" + * @param bot + * the workbench bot + */ + public static void closeView(String title, SWTWorkbenchBot bot) { + final List openViews = bot.views(); + for (SWTBotView view : openViews) { + if (view.getTitle().equalsIgnoreCase(title)) { + view.close(); + bot.waitUntil(ConditionHelpers.ViewIsClosed(view)); + } + } + } + + /** + * Switch to the tracing perspective + */ + public static void switchToTracingPerspective() { + switchToPerspective(TRACING_PERSPECTIVE_ID); + } + + /** + * Switch to a given perspective + * + * @param id + * the perspective id (like + * "org.eclipse.linuxtools.tmf.ui.perspective" + */ + public static void switchToPerspective(final String id) { + UIThreadRunnable.syncExec(new VoidResult() { + @Override + public void run() { + try { + PlatformUI.getWorkbench().showPerspective(id, PlatformUI.getWorkbench().getActiveWorkbenchWindow()); + } catch (WorkbenchException e) { + fail(e.getMessage()); + } + } + }); + } + + /** + * If the test is running in the UI thread then fail + */ + public static void failIfUIThread() { + if (Display.getCurrent() != null && Display.getCurrent().getThread() == Thread.currentThread()) { + fail("SWTBot test needs to run in a non-UI thread. Make sure that \"Run in UI thread\" is unchecked in your launch configuration or" + + " that useUIThread is set to false in the pom.xml"); + } + + } + + /** + * Open a trace, this does not perform any validation though + * + * @param projectName + * The project name + * @param tracePath + * the path of the trace file (absolute or relative) + * @param traceType + * the trace canonical string (eg: + * org.eclipse.linuxtools.btf.trace) + */ + public static void openTrace(final String projectName, final String tracePath, final String traceType) { + final Exception exception[] = new Exception[1]; + exception[0] = null; + UIThreadRunnable.syncExec(new VoidResult() { + @Override + public void run() { + try { + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + TmfTraceFolder destinationFolder = TmfProjectRegistry.getProject(project, true).getTracesFolder(); + TmfOpenTraceHelper.openTraceFromPath(destinationFolder, tracePath, PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), traceType); + } catch (CoreException e) { + exception[0] = e; + } + } + }); + if (exception[0] != null) { + fail(exception[0].getMessage()); + } + + delay(1000); + waitForJobs(); + } + + /** + * Opens an editor and sets focus to the editor + * + * @param bot + * the workbench bot + * @param editorName + * the editor name + * @return the corresponding SWTBotEditor + */ + public static SWTBotEditor openEditor(SWTWorkbenchBot bot, String editorName) { + Matcher matcher = WidgetMatcherFactory.withPartName(editorName); + final SWTBotEditor editorBot = bot.editor(matcher); + IEditorPart iep = editorBot.getReference().getEditor(true); + final TmfEventsEditor tmfEd = (TmfEventsEditor) iep; + editorBot.show(); + UIThreadRunnable.syncExec(new VoidResult() { + @Override + public void run() { + tmfEd.setFocus(); + } + }); + + SWTBotUtil.waitForJobs(); + SWTBotUtil.delay(1000); + assertNotNull(tmfEd); + return editorBot; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/TestCustomTxtWizard.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/TestCustomTxtWizard.java new file mode 100644 index 0000000000..c91235520b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/TestCustomTxtWizard.java @@ -0,0 +1,262 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.swtbot.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; + +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; +import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Custom text wizard tests + * + * Some reminders to help making tests (javadoc to keep formatting) + * + * Button reminder + * + *
+ * 0 Time Stamp Format Help
+ * 1 Remove line
+ * 2 Add next line
+ * 3 Add child line
+ * 4 Move up
+ * 5 Move down
+ * 6 Regular Expression Help
+ * 7 Remove group (group 1 toggle)
+ * 8 Remove group (group 2 toggle)
+ * 9 Add group (group 3 toggle ...)
+ * 10 Show parsing result
+ * 11 Preview Legend
+ * 
+ * + * Combo box reminder + * + *
+ * 0 cardinality
+ * 1 event type (message, timestamp...)
+ * 2 how to handle the data (set, append...)
+ * repeat
+ * 
+ * + * @author Matthew Khouzam + * + */ +@RunWith(SWTBotJunit4ClassRunner.class) +public class TestCustomTxtWizard extends AbstractCustomParserWizard { + + private static final String MANAGE_CUSTOM_PARSERS_SHELL_TITLE = "Manage Custom Parsers"; + private static final String PROJECT_NAME = "TestText"; + private static final String CATEGORY_NAME = "Test Category"; + private static final String TRACETYPE_NAME = "Test Trace"; + private static final String EXPECTED_TEST_DEFINITION = "\n" + + "ss\n" + + "\n" + + "\n" + + "\\s*(\\d\\d)\\s(.*\\S)\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "([^0-9]*)\n" + + "\n" + + "\n" + + "\n" + + "\n"; + + /** + * Test to create a custom txt trace and compare the xml + * + * @throws IOException + * the xml file is not accessible, this is bad + * @throws FileNotFoundException + * the xml file wasn't written, this is bad + */ + @Test + public void testNew() throws FileNotFoundException, IOException { + File xmlFile = ResourcesPlugin.getWorkspace().getRoot().getLocation().append(".metadata/.plugins/org.eclipse.tracecompass.tmf.core/custom_txt_parsers.xml").toFile(); + SWTBotUtil.createProject(PROJECT_NAME); + SWTBotView proejctExplorerBot = fBot.viewByTitle("Project Explorer"); + proejctExplorerBot.show(); + SWTBotTreeItem treeItem = proejctExplorerBot.bot().tree().getTreeItem(PROJECT_NAME); + treeItem.select(); + treeItem.expand(); + SWTBotTreeItem treeNode = null; + for (String node : treeItem.getNodes()) { + if (node.startsWith("Trace")) { + treeNode = treeItem.getNode(node); + break; + } + + } + assertNotNull(treeNode); + treeNode.contextMenu("Manage Custom Parsers...").click(); + fBot.shell(MANAGE_CUSTOM_PARSERS_SHELL_TITLE).setFocus(); + + fBot.button("New...").click(); + + fBot.textWithLabel("Category:").setText(CATEGORY_NAME); + fBot.textWithLabel("Trace type:").setText(TRACETYPE_NAME); + fBot.textWithLabel("Time Stamp format:").setText("ss"); + fBot.comboBox(1).setSelection("Time Stamp"); + fBot.textWithLabel("format:").setText("ss"); + fBot.button(8).click(); + fBot.button(2).click(); + SWTBotTreeItem[] treeItems = fBot.tree().getAllItems(); + SWTBotTreeItem eventLine[] = new SWTBotTreeItem[2]; + treeItems = fBot.tree().getAllItems(); + for (SWTBotTreeItem item : treeItems) { + if (item.getText().startsWith("Root Line 1")) { + eventLine[0] = item; + } + if (item.getText().startsWith("Root Line 2")) { + eventLine[1] = item; + } + } + assertNotNull(eventLine[0]); + assertNotNull(eventLine[1]); + fBot.styledText().setText("12 Hello\nWorld\n23 Goodbye\ncruel world"); + eventLine[0].select(); + SWTBotUtil.waitForJobs(); + fBot.textWithLabel("Regular expression:").setText("\\s*(\\d\\d)\\s(.*\\S)"); + eventLine[1].select(); + fBot.textWithLabel("Regular expression:").setText("([^0-9]*)"); + fBot.button(7).click(); + fBot.comboBox("Set").setSelection("Append with |"); + fBot.button("Highlight All").click(); + fBot.button("Next >").click(); + fBot.button("Finish").click(); + String xmlPart = extractTestXml(xmlFile, CATEGORY_NAME, TRACETYPE_NAME); + assertEquals(EXPECTED_TEST_DEFINITION, xmlPart); + fBot.list().select(CATEGORY_NAME + " : " + TRACETYPE_NAME); + fBot.button("Delete").click(); + fBot.button("Yes").click(); + fBot.button("Close").click(); + xmlPart = extractTestXml(xmlFile, CATEGORY_NAME, TRACETYPE_NAME); + assertEquals("", xmlPart); + + SWTBotUtil.deleteProject(PROJECT_NAME, fBot); + } + + /** + * Test to edit a custom txt trace and compare the xml + * + * @throws IOException + * the xml file is not accessible, this is bad + * @throws FileNotFoundException + * the xml file wasn't written, this is bad + */ + @Test + public void testEdit() throws FileNotFoundException, IOException { + File xmlFile = ResourcesPlugin.getWorkspace().getRoot().getLocation().append(".metadata/.plugins/org.eclipse.tracecompass.tmf.core/custom_txt_parsers.xml").toFile(); + try (FileWriter fw = new FileWriter(xmlFile)) { + String xmlContent = "\n" + + "\n" + + "\n" + + "sss\n" + + "\n" + + "\n" + + "\\s*(\\d*)\\s(.*)\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "sssssss.ssssss\n" + + "\n" + + "\n" + + "^[([0-9]*\\.[0.9]*)]\\s(.*)\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + ""; + fw.write(xmlContent); + fw.flush(); + } + SWTBotUtil.createProject(PROJECT_NAME); + SWTBotView proejctExplorerBot = fBot.viewByTitle("Project Explorer"); + proejctExplorerBot.show(); + SWTBotTreeItem treeItem = proejctExplorerBot.bot().tree().getTreeItem(PROJECT_NAME); + treeItem.select(); + treeItem.expand(); + SWTBotTreeItem treeNode = null; + for (String node : treeItem.getNodes()) { + if (node.startsWith("Trace")) { + treeNode = treeItem.getNode(node); + break; + } + + } + assertNotNull(treeNode); + treeNode.contextMenu("Manage Custom Parsers...").click(); + fBot.shell(MANAGE_CUSTOM_PARSERS_SHELL_TITLE).setFocus(); + fBot.list().select("Demo Category : Demo trace"); + fBot.button("Edit...").click(); + + fBot.textWithLabel("Category:").setText(CATEGORY_NAME); + fBot.textWithLabel("Trace type:").setText(TRACETYPE_NAME); + fBot.textWithLabel("Time Stamp format:").setText("ss"); + fBot.comboBox(1).setSelection("Time Stamp"); + fBot.textWithLabel("format:").setText("ss"); + fBot.button(2).click(); + SWTBotTreeItem[] treeItems = fBot.tree().getAllItems(); + SWTBotTreeItem eventLine[] = new SWTBotTreeItem[2]; + for (SWTBotTreeItem item : treeItems) { + if (item.getText().startsWith("Root Line 1")) { + eventLine[0] = item; + } + if (item.getText().startsWith("Root Line 2")) { + eventLine[1] = item; + } + } + treeItems = fBot.tree().getAllItems(); + assertNotNull(eventLine[0]); + assertNotNull(eventLine[1]); + fBot.styledText().setText("12 Hello\nWorld\n23 Goodbye\ncruel world"); + eventLine[0].select(); + SWTBotUtil.waitForJobs(); + fBot.textWithLabel("Regular expression:").setText("\\s*(\\d\\d)\\s(.*\\S)"); + eventLine[1].select(); + fBot.textWithLabel("Regular expression:").setText("([^0-9]*)"); + fBot.button(7).click(); + fBot.comboBox("Set").setSelection("Append with |"); + fBot.button("Highlight All").click(); + fBot.button("Next >").click(); + fBot.button("Finish").click(); + String xmlPart = extractTestXml(xmlFile, CATEGORY_NAME, TRACETYPE_NAME); + assertEquals(EXPECTED_TEST_DEFINITION, xmlPart); + fBot.list().select(CATEGORY_NAME + " : " + TRACETYPE_NAME); + fBot.button("Delete").click(); + fBot.button("Yes").click(); + fBot.button("Close").click(); + xmlPart = extractTestXml(xmlFile, CATEGORY_NAME, TRACETYPE_NAME); + assertEquals("", xmlPart); + + SWTBotUtil.deleteProject(PROJECT_NAME, fBot); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/TestCustomXmlWizard.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/TestCustomXmlWizard.java new file mode 100644 index 0000000000..f3abde84e1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/TestCustomXmlWizard.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.swtbot.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; +import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Custom XML wizard tests + * + * This test will help validate the CustomXmlParserInputWizardPage + * + * @author Matthew Khouzam + * + */ +@RunWith(SWTBotJunit4ClassRunner.class) +public class TestCustomXmlWizard extends AbstractCustomParserWizard { + + private static final String EVENT = "event"; + private static final String TRACE = "trace"; + private static final String XML_TRACE1 = "\n\t\n\t"; + private static final String MANAGE_CUSTOM_PARSERS_SHELL_TITLE = "Manage Custom Parsers"; + private static final String PROJECT_NAME = "TestXML"; + private static final String CATEGORY_NAME = "Test Category"; + private static final String TRACETYPE_NAME = "Test Trace"; + private static final String EXPECTED_TEST_DEFINITION = "\n" + + "ss\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n"; + + /** + * Test to create a custom XML trace and compare the XML generated + * + * @throws IOException + * the xml file is not accessible, this is bad + * @throws FileNotFoundException + * the xml file wasn't written, this is bad + */ + @Test + public void testNew() throws FileNotFoundException, IOException { + File xmlFile = ResourcesPlugin.getWorkspace().getRoot().getLocation().append(".metadata/.plugins/org.eclipse.tracecompass.tmf.core/custom_xml_parsers.xml").toFile(); + SWTBotUtil.createProject(PROJECT_NAME); + SWTBotView proejctExplorerBot = fBot.viewByTitle("Project Explorer"); + proejctExplorerBot.show(); + SWTBotTreeItem treeItem = proejctExplorerBot.bot().tree().getTreeItem(PROJECT_NAME); + treeItem.select(); + treeItem.expand(); + SWTBotTreeItem treeNode = null; + for (String node : treeItem.getNodes()) { + if (node.startsWith("Trace")) { + treeNode = treeItem.getNode(node); + break; + } + + } + assertNotNull(treeNode); + treeNode.contextMenu("Manage Custom Parsers...").click(); + fBot.shell(MANAGE_CUSTOM_PARSERS_SHELL_TITLE).setFocus(); + fBot.radio("XML").click(); + fBot.button("New...").click(); + fBot.textWithLabel("Category:").setText(CATEGORY_NAME); + fBot.textWithLabel("Trace type:").setText(TRACETYPE_NAME); + fBot.textWithLabel("Time Stamp format:").setText("ss"); + + fBot.styledText().setText(XML_TRACE1); + fBot.buttonWithTooltip("Feeling lucky").click(); + + fBot.tree().getTreeItem(TRACE).getNode(EVENT).select(); + fBot.checkBox("Log Entry").click(); + fBot.button("Next >").click(); + fBot.button("Finish").click(); + + String xmlPart = extractTestXml(xmlFile, CATEGORY_NAME, TRACETYPE_NAME); + assertEquals(EXPECTED_TEST_DEFINITION, xmlPart); + fBot.list().select(CATEGORY_NAME + " : " + TRACETYPE_NAME); + fBot.button("Delete").click(); + fBot.button("Yes").click(); + fBot.button("Close").click(); + xmlPart = extractTestXml(xmlFile, CATEGORY_NAME, TRACETYPE_NAME); + assertEquals("", xmlPart); + + SWTBotUtil.deleteProject(PROJECT_NAME, fBot); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/TracingPerspectiveChecker.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/TracingPerspectiveChecker.java new file mode 100644 index 0000000000..8d5e58f704 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/TracingPerspectiveChecker.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.swtbot.tests; + +import java.util.ArrayList; +import java.util.Arrays; + +import org.eclipse.tracecompass.tmf.ui.views.TracingPerspectiveFactory; +import org.eclipse.tracecompass.tmf.ui.views.histogram.HistogramView; +import org.eclipse.tracecompass.tmf.ui.views.statistics.TmfStatisticsView; +import org.eclipse.ui.IPageLayout; +import org.junit.Before; + +/** + * Tracing perspective view checker + * + * @author Matthew Khouzam + */ +public class TracingPerspectiveChecker extends AbstractPerspectiveChecker { + + /** + * Set up arrays for test + */ + @Before + public void init() { + fPerspectiveId = TracingPerspectiveFactory.ID; + fViewIds = new ArrayList<>(); + fViewIds.addAll(Arrays.asList(new String[] { + HistogramView.ID, + TmfStatisticsView.ID, + // Standard Eclipse views + IPageLayout.ID_PROJECT_EXPLORER, + IPageLayout.ID_PROP_SHEET, + IPageLayout.ID_BOOKMARKS + })); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/ConditionHelpers.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/ConditionHelpers.java new file mode 100644 index 0000000000..83a60421ed --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/ConditionHelpers.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.swtbot.tests.conditions; + +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; +import org.eclipse.swtbot.swt.finder.waits.ICondition; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; + +/** + * Is a tree node available + * + * @author Matthew Khouzam + */ +public abstract class ConditionHelpers { + + /** + * Is a tree node available + * + * @param name + * the name of the node + * @param tree + * the parent tree + * @return true or false, it should swallow all exceptions + */ + public static ICondition IsTreeNodeAvailable(String name, SWTBotTree tree) { + return new TreeNodeAvailable(name, tree); + } + + /** + * Is the treeItem's node available + * + * @param name + * the name of the node + * @param treeItem + * the treeItem + * @return true or false, it should swallow all exceptions + */ + public static ICondition IsTreeChildNodeAvailable(String name, SWTBotTreeItem treeItem) { + return new TreeItemNodeAvailable(name, treeItem); + } + + /** + * Checks if the wizard's shell is null + * + * @param wizard + * the null + * @return false if either are null + */ + public static ICondition isWizardReady(Wizard wizard) { + return new WizardReady(wizard); + } + + /** + * Is the wizard on the page you want? + * + * @param wizard + * wizard + * @param desiredPage + * the desired page + * @return true or false + */ + public static ICondition isWizardOnPage(Wizard wizard, IWizardPage desiredPage) { + return new WizardOnPage(wizard, desiredPage); + } + + /** + * Wait for a view to close + * + * @param view + * bot view for the view + * @return true if the view is closed, false if it's active. + */ + public static ICondition ViewIsClosed(SWTBotView view) { + return new ViewClosed(view); + } + + /** + * Wait till table cell has a given content. + * + * @param table + * the table bot reference + * @param content + * the content to check + * @param row + * the row of the cell + * @param column + * the column of the cell + * @return ICondition for verification + */ + public static ICondition isTableCellFilled(SWTBotTable table, String content, int row, int column) { + return new TableCellFilled(table, content, row, column); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/TableCellFilled.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/TableCellFilled.java new file mode 100644 index 0000000000..3ebc1b4223 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/TableCellFilled.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.swtbot.tests.conditions; + +import org.eclipse.swtbot.swt.finder.SWTBot; +import org.eclipse.swtbot.swt.finder.waits.ICondition; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable; + +/** + * Is a table cell filled? tests if the table cell has a given content. + * + * @author Bernd Hufmann + */ +class TableCellFilled implements ICondition { + + private final SWTBotTable fTable; + private final String fContent; + private final int fRow; + private final int fColumn; + + public TableCellFilled(SWTBotTable table, String content, int row, int column) { + fTable = table; + fContent = content; + fRow = row; + fColumn = column; + } + + @Override + public boolean test() throws Exception { + try { + return fContent.equals(fTable.cell(fRow, fColumn)); + } catch (Exception e) { + } + return false; + } + + @Override + public void init(SWTBot bot) { + } + + @Override + public String getFailureMessage() { + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/TreeItemNodeAvailable.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/TreeItemNodeAvailable.java new file mode 100644 index 0000000000..fdf2e9cb5d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/TreeItemNodeAvailable.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.swtbot.tests.conditions; + +import org.eclipse.swtbot.swt.finder.SWTBot; +import org.eclipse.swtbot.swt.finder.waits.ICondition; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; + +/** + * Is a TreeItem's node available? tests if the tree has an item with a given name + * + * @author Matthew Khouzam + */ +class TreeItemNodeAvailable implements ICondition { + + private final SWTBotTreeItem fTreeItem; + private final String fName; + + public TreeItemNodeAvailable(String name, SWTBotTreeItem treeItem) { + fName = name; + fTreeItem = treeItem; + } + + @Override + public boolean test() throws Exception { + try { + return fTreeItem.getNode(fName) != null; + } catch (Exception e) { + } + return false; + } + + @Override + public void init(SWTBot bot) { + } + + @Override + public String getFailureMessage() { + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/TreeNodeAvailable.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/TreeNodeAvailable.java new file mode 100644 index 0000000000..6cd0219170 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/TreeNodeAvailable.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.swtbot.tests.conditions; + +import org.eclipse.swtbot.swt.finder.SWTBot; +import org.eclipse.swtbot.swt.finder.waits.ICondition; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; + +/** + * Is a tree node available? + * + * @author Matthew Khouzam + */ +class TreeNodeAvailable implements ICondition { + + private final SWTBotTree fTree; + private final String fName; + + /** + * Is a tree node available + * + * @param name + * The name of the node + * @param tree + * the swtbotTree + */ + public TreeNodeAvailable(String name, SWTBotTree tree) { + fTree = tree; + fName = name; + } + + @Override + public boolean test() throws Exception { + try { + final SWTBotTreeItem[] treeItems = fTree.getAllItems(); + for( SWTBotTreeItem ti : treeItems){ + final String text = ti.getText(); + if( text.equals(fName)) { + return true; + } + } + } catch (Exception e) { + } + return false; + } + + @Override + public void init(SWTBot bot) { + } + + @Override + public String getFailureMessage() { + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/ViewClosed.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/ViewClosed.java new file mode 100644 index 0000000000..2b38e2bbc6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/ViewClosed.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.swtbot.tests.conditions; + +import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; +import org.eclipse.swtbot.swt.finder.SWTBot; +import org.eclipse.swtbot.swt.finder.waits.ICondition; + +/** + * Is a view closed? + * + * @author Matthew Khouzam + */ +class ViewClosed implements ICondition { + private final SWTBotView fView; + + public ViewClosed(SWTBotView view) { + fView = view; + } + + @Override + public boolean test() throws Exception { + return (fView != null) && (!fView.isActive()); + } + + @Override + public void init(SWTBot bot) { + } + + @Override + public String getFailureMessage() { + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/WizardOnPage.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/WizardOnPage.java new file mode 100644 index 0000000000..03eed89002 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/WizardOnPage.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.swtbot.tests.conditions; + +import org.eclipse.jface.wizard.IWizardContainer; +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.swtbot.swt.finder.SWTBot; +import org.eclipse.swtbot.swt.finder.waits.ICondition; + +/** + * Is the wizard on the page you want? + * @author Matthew Khouzam + */ +class WizardOnPage implements ICondition { + + private final Wizard fWizard; + private final IWizardPage fPage; + + public WizardOnPage(Wizard wizard, IWizardPage desiredPage) { + fWizard = wizard; + fPage = desiredPage; + } + + @Override + public boolean test() throws Exception { + if (fWizard == null || fPage == null) { + return false; + } + final IWizardContainer container = fWizard.getContainer(); + if (container == null) { + return false; + } + IWizardPage currentPage = container.getCurrentPage(); + return fPage.equals(currentPage); + } + + @Override + public void init(SWTBot bot) { + } + + @Override + public String getFailureMessage() { + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/WizardReady.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/WizardReady.java new file mode 100644 index 0000000000..6cdb36723c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/conditions/WizardReady.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.swtbot.tests.conditions; + +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.swtbot.swt.finder.SWTBot; +import org.eclipse.swtbot.swt.finder.waits.ICondition; + +/** + * Is a given wizard ready? + * + * @author Matthew Khouzam + */ +class WizardReady implements ICondition { + + private final Wizard fWizard; + + public WizardReady(Wizard wizard) { + fWizard = wizard; + } + + @Override + public boolean test() throws Exception { + if (fWizard.getShell() == null) { + return false; + } + return true; + } + + @Override + public void init(SWTBot bot) { + } + + @Override + public String getFailureMessage() { + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/table/AllTests.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/table/AllTests.java new file mode 100644 index 0000000000..f9faa1ee86 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/table/AllTests.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.swtbot.tests.table; + +import org.junit.Ignore; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * SWTBot test suite for testing of the TMF events table. + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + CollapseEventsInTableTest.class, +}) +@Ignore +public class AllTests { +} diff --git a/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/table/CollapseEventsInTableTest.java b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/table/CollapseEventsInTableTest.java new file mode 100644 index 0000000000..a531ee9bd4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/table/CollapseEventsInTableTest.java @@ -0,0 +1,195 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.swtbot.tests.table; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; + +import org.apache.log4j.ConsoleAppender; +import org.apache.log4j.Logger; +import org.apache.log4j.SimpleLayout; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.bindings.keys.IKeyLookup; +import org.eclipse.jface.bindings.keys.KeyStroke; +import org.eclipse.jface.bindings.keys.ParseException; +import org.eclipse.tracecompass.internal.tmf.core.Activator; +import org.eclipse.tracecompass.tmf.core.tests.TmfCoreTestPlugin; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimePreferencesConstants; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; +import org.eclipse.tracecompass.tmf.ui.swtbot.tests.SWTBotUtil; +import org.eclipse.tracecompass.tmf.ui.swtbot.tests.conditions.ConditionHelpers; +import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; +import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor; +import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; +import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * SWTBot test for testing collapsing feature. + * + * @author Bernd Hufmann + */ +@RunWith(SWTBotJunit4ClassRunner.class) +public class CollapseEventsInTableTest { + + private static final String TRACE_PROJECT_NAME = "test"; + private static final String COLLAPSE_TRACE_NAME = "syslog_collapse"; + private static final String COLLAPSE_TRACE_PATH = "testfiles/" + COLLAPSE_TRACE_NAME; + private static final String COLLAPSE_TRACE_TYPE = "org.eclipse.linuxtools.tmf.tests.stubs.trace.text.testsyslog"; + + private static File fTestFile = null; + + private static SWTWorkbenchBot fBot; + + /** The Log4j logger instance. */ + private static final Logger fLogger = Logger.getRootLogger(); + + /** + * Test Class setup + */ + @BeforeClass + public static void init() { + SWTBotUtil.failIfUIThread(); + + /* set up test trace*/ + URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(COLLAPSE_TRACE_PATH), null); + URI uri; + try { + uri = FileLocator.toFileURL(location).toURI(); + fTestFile = new File(uri); + } catch (URISyntaxException | IOException e) { + e.printStackTrace(); + fail(); + } + + assumeTrue(fTestFile.exists()); + + IEclipsePreferences defaultPreferences = InstanceScope.INSTANCE.getNode(Activator.PLUGIN_ID); + defaultPreferences.put(ITmfTimePreferencesConstants.DATIME, "MMM d HH:mm:ss"); + defaultPreferences.put(ITmfTimePreferencesConstants.SUBSEC, ITmfTimePreferencesConstants.SUBSEC_NO_FMT); + TmfTimestampFormat.updateDefaultFormats(); + + /* Set up for swtbot */ + SWTBotPreferences.TIMEOUT = 20000; /* 20 second timeout */ + fLogger.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender.SYSTEM_OUT)); + fBot = new SWTWorkbenchBot(); + + /* Close welcome view */ + SWTBotUtil.closeView("Welcome", fBot); + + /* Switch perspectives */ + SWTBotUtil.switchToTracingPerspective(); + + /* Finish waiting for eclipse to load */ + SWTBotUtil.waitForJobs(); + } + + /** + * Test class tear down method. + */ + @AfterClass + public static void tearDown() { + /* Set timestamp defaults */ + IEclipsePreferences defaultPreferences = InstanceScope.INSTANCE.getNode(Activator.PLUGIN_ID); + defaultPreferences.put(ITmfTimePreferencesConstants.DATIME, ITmfTimePreferencesConstants.TIME_HOUR_FMT); + defaultPreferences.put(ITmfTimePreferencesConstants.SUBSEC, ITmfTimePreferencesConstants.SUBSEC_NANO_FMT); + TmfTimestampFormat.updateDefaultFormats(); + } + + /** + * Main test case + */ + @Test + public void test() { + SWTBotUtil.createProject(TRACE_PROJECT_NAME); + SWTBotUtil.openTrace(TRACE_PROJECT_NAME, fTestFile.getAbsolutePath(), COLLAPSE_TRACE_TYPE); + SWTBotEditor editorBot = SWTBotUtil.openEditor(fBot, fTestFile.getName()); + + SWTBotTable tableBot = editorBot.bot().table(); + + /* Maximize editor area */ + maximizeTable(tableBot); + tableBot.click(1, 0); + + /* Collapse Events */ + SWTBotMenu menuBot = tableBot.contextMenu("Collapse Events"); + menuBot.click(); + fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "7/22", 1, 1)); + + String filterString = tableBot.cell(1, 1); + assertEquals("filterString", "7/22", filterString); + + /* Verify collapsed event */ + filterString = tableBot.cell(7, 0); + assertEquals("repeatCount", "+14", filterString); + + filterString = tableBot.cell(7, 1); + assertEquals("first timestamp", "Jan 1 06:06:06", filterString); + + filterString = tableBot.cell(7, 2); + assertEquals("source", "", filterString); + + filterString = tableBot.cell(7, 3); + assertEquals("type", "Syslog", filterString); + + filterString = tableBot.cell(7, 4); + assertEquals("file", "", filterString); + + filterString = tableBot.cell(7, 5); + assertEquals("content", "Timestamp=Jan 1 06:06:06, Host=HostF, Logger=LoggerF, Message=Message F", filterString); + + filterString = tableBot.cell(8, 0); + assertEquals("repeatCount", "+1", filterString); + + filterString = tableBot.cell(8, 1); + assertEquals("first timestamp (2nd collapse)", "Jan 1 06:06:21", filterString); + + filterString = tableBot.cell(8, 5); + assertEquals("content", "Timestamp=Jan 1 06:06:21, Host=HostF, Logger=LoggerF, Message=Message D", filterString); + + /* Clear Filter */ + menuBot = tableBot.contextMenu("Clear Filters"); + menuBot.click(); + fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "Jan 1 01:01:01", 1, 1)); + assertEquals("timestamp", "Jan 1 01:01:01", tableBot.cell(1, 1)); + + maximizeTable(tableBot); + + fBot.closeAllEditors(); + SWTBotUtil.deleteProject(TRACE_PROJECT_NAME, fBot); + } + + private static void maximizeTable(SWTBotTable tableBot) { + try { + tableBot.pressShortcut(KeyStroke.getInstance(IKeyLookup.CTRL_NAME + "+"), KeyStroke.getInstance("M")); + } catch (ParseException e) { + fail(); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/META-INF/MANIFEST.MF b/org.eclipse.tracecompass.tmf.ui.tests/META-INF/MANIFEST.MF index 6ece9472b9..43b3aa096b 100644 --- a/org.eclipse.tracecompass.tmf.ui.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.tracecompass.tmf.ui.tests/META-INF/MANIFEST.MF @@ -16,6 +16,6 @@ Require-Bundle: org.junit;bundle-version="4.0.0", org.eclipse.tracecompass.tmf.ui;bundle-version="3.1.0", org.eclipse.tracecompass.tmf.core.tests;bundle-version="3.1.0", org.eclipse.ui.ide -Export-Package: org.eclipse.linuxtools.tmf.ui.tests -Bundle-Activator: org.eclipse.linuxtools.tmf.ui.tests.TmfUITestPlugin +Export-Package: org.eclipse.tracecompass.tmf.ui.tests +Bundle-Activator: org.eclipse.tracecompass.tmf.ui.tests.TmfUITestPlugin Import-Package: com.google.common.collect diff --git a/org.eclipse.tracecompass.tmf.ui.tests/plugin.xml b/org.eclipse.tracecompass.tmf.ui.tests/plugin.xml index 3dc023721d..a1622fc36f 100644 --- a/org.eclipse.tracecompass.tmf.ui.tests/plugin.xml +++ b/org.eclipse.tracecompass.tmf.ui.tests/plugin.xml @@ -6,27 +6,27 @@ @@ -35,7 +35,7 @@ + class="org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub"> + class="org.eclipse.tracecompass.tmf.ui.tests.stubs.analysis.TestAnalysisUi"> diff --git a/org.eclipse.tracecompass.tmf.ui.tests/pom.xml b/org.eclipse.tracecompass.tmf.ui.tests/pom.xml index 7c19432554..903d83f1fd 100644 --- a/org.eclipse.tracecompass.tmf.ui.tests/pom.xml +++ b/org.eclipse.tracecompass.tmf.ui.tests/pom.xml @@ -42,7 +42,7 @@ ${tycho-version} org.eclipse.tracecompass.tmf.ui.tests - org.eclipse.linuxtools.tmf.ui.tests.AllTmfUITests + org.eclipse.tracecompass.tmf.ui.tests.AllTmfUITests true true ${tycho.testArgLine} ${base.ui.test.vmargs} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/shared/org/eclipse/linuxtools/tmf/ui/tests/shared/ProjectModelTestData.java b/org.eclipse.tracecompass.tmf.ui.tests/shared/org/eclipse/linuxtools/tmf/ui/tests/shared/ProjectModelTestData.java deleted file mode 100644 index b9db1265c7..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/shared/org/eclipse/linuxtools/tmf/ui/tests/shared/ProjectModelTestData.java +++ /dev/null @@ -1,265 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.shared; - -import java.io.File; -import java.lang.reflect.InvocationTargetException; -import java.util.concurrent.TimeoutException; - -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Path; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.project.model.TmfImportHelper; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace; -import org.eclipse.linuxtools.tmf.ui.project.model.ITmfProjectModelElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfCommonProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTracesFolder; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.actions.WorkspaceModifyOperation; - -/** - * Creates objects used for this package's testing purposes - * - * @author Geneviève Bastien - */ -public class ProjectModelTestData { - - /* Maximum number of thread delays the main thread will do before timing out */ - private static final int DELAY_COUNTER = 1000; - /* Default delay time when having the main thread sleep. */ - private static final long DEFAULT_DELAY = 500; - - /** Default test project name */ - public static final String PROJECT_NAME = "Test_Project"; - - private static final TmfTestTrace testTrace = TmfTestTrace.A_TEST_10K; - - /** - * Gets a project element with traces all initialized - * - * @return A project stub element - * @throws CoreException - * If something happened with the project creation - */ - public static TmfProjectElement getFilledProject() throws CoreException { - - IProject project = TmfProjectRegistry.createProject(PROJECT_NAME, null, null); - IFolder traceFolder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME); - - /* Create a trace, if it exist, it will be replaced */ - File file = new File(testTrace.getFullPath()); - String path = file.getAbsolutePath(); - final IPath pathString = Path.fromOSString(path); - IResource linkedTrace = TmfImportHelper.createLink(traceFolder, pathString, pathString.lastSegment()); - if (!(linkedTrace != null && linkedTrace.exists())) { - return null; - } - linkedTrace.setPersistentProperty(TmfCommonConstants.TRACETYPE, - "org.eclipse.linuxtools.tmf.core.tests.tracetype"); - - final TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true); - TmfTraceElement traceElement = projectElement.getTracesFolder().getTraces().get(0); - traceElement.refreshTraceType(); - - projectElement.refresh(); - - return projectElement; - } - - /** - * Adds a new experiment to the project - * - * @param projectElement - * The project to add to - * @param experimentName - * Name of the experiment - * @return The newly created experiment - */ - public static TmfExperimentElement addExperiment(TmfProjectElement projectElement, String experimentName) { - IFolder experimentFolder = projectElement.getExperimentsFolder().getResource(); - final IFolder folder = experimentFolder.getFolder(experimentName); - - WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { - @Override - public void execute(IProgressMonitor monitor) throws CoreException { - monitor.beginTask("", 1000); - folder.create(false, true, monitor); - monitor.done(); - } - }; - try { - PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); - } catch (InterruptedException | InvocationTargetException | RuntimeException exception) { - - } - - for (ITmfProjectModelElement el : projectElement.getExperimentsFolder().getChildren()) { - if (el.getName().equals(experimentName) && (el instanceof TmfExperimentElement)) { - return (TmfExperimentElement) el; - } - } - return null; - } - - /** - * Get the name of the test trace element - * - * @return The trace name - */ - public static String getTraceName() { - File file = new File(testTrace.getPath()); - String path = file.getAbsolutePath(); - final IPath pathString = Path.fromOSString(path); - return pathString.lastSegment(); - } - - /** - * Deletes a project - * - * @param project - * Project to delete - */ - public static void deleteProject(TmfProjectElement project) { - /* Delete experiments */ - ITmfProjectModelElement[] experiments = project.getExperimentsFolder().getChildren().toArray(new ITmfProjectModelElement[0]); - for (ITmfProjectModelElement element : experiments) { - if (element instanceof TmfExperimentElement) { - TmfExperimentElement experiment = (TmfExperimentElement) element; - IResource resource = experiment.getResource(); - - /* Close the experiment if open */ - experiment.closeEditors(); - - IPath path = resource.getLocation(); - if (path != null) { - /* Delete supplementary files */ - experiment.deleteSupplementaryFolder(); - } - - /* Finally, delete the experiment */ - try { - resource.delete(true, null); - } catch (CoreException e) { - Activator.getDefault().logError("Error deleting experiment element", e); - } - } - } - - /* Delete traces */ - ITmfProjectModelElement[] traces = project.getTracesFolder().getChildren().toArray(new ITmfProjectModelElement[0]); - for (ITmfProjectModelElement element : traces) { - if (element instanceof TmfTraceElement) { - TmfTraceElement trace = (TmfTraceElement) element; - IResource resource = trace.getResource(); - - /* Close the trace if open */ - trace.closeEditors(); - - IPath path = resource.getLocation(); - if (path != null) { - /* Delete supplementary files */ - trace.deleteSupplementaryFolder(); - } - - /* Finally, delete the trace */ - try { - resource.delete(true, new NullProgressMonitor()); - } catch (CoreException e) { - Activator.getDefault().logError("Error deleting trace element", e); - } - } - } - - /* Delete the project itself */ - try { - project.getResource().delete(true, null); - } catch (CoreException e) { - Activator.getDefault().logError("Error deleting project", e); - } - } - - /** - * Makes the main display thread sleep, so it gives a chance to other - * threads needing the main display to execute - * - * @param waitTimeMillis - * time to wait in millisecond - */ - public static void delayThread(final long waitTimeMillis) { - final Display display = Display.getCurrent(); - if (display != null) { - final long endTimeMillis = System.currentTimeMillis() + waitTimeMillis; - while (System.currentTimeMillis() < endTimeMillis) { - if (!display.readAndDispatch()) { - display.sleep(); - } - display.update(); - } - } else { - try { - Thread.sleep(waitTimeMillis); - } catch (final InterruptedException e) { - // Ignored - } - } - } - - /** - * Makes the main display thread sleep to give a chance to other threads to - * execute. It sleeps until the a trace element's corresponding trace is - * available (opened) or returns after a timeout. It allows to set short - * delays, while still not failing tests when it randomly takes a bit more - * time for the trace to open. - * - * If the project model element sent in parameter is not a trace element, - * then the thread is delayed only once by the default delay time. For - * longer delays in those cases, it is preferable to use the - * {@link ProjectModelTestData#delayThread(long)} instead. - * - * Timeout is DELAY_COUNTER * DEFAULT_DELAY ms - * - * @param projectElement - * The trace element we are waiting for. If the element if not of - * type TmfTraceElement, the thread is delayed only once. - * @throws TimeoutException - * If after the maximum number of delays the trace is still - * null, we throw a timeout exception, the trace has not opened. - */ - public static void delayUntilTraceOpened(final ITmfProjectModelElement projectElement) throws TimeoutException { - if (projectElement instanceof TmfCommonProjectElement) { - TmfCommonProjectElement traceElement = (TmfCommonProjectElement) projectElement; - final long deadline = System.nanoTime() + (DELAY_COUNTER * DEFAULT_DELAY * 1000000L); - do { - delayThread(DEFAULT_DELAY); - if (traceElement.getTrace() != null) { - return; - } - } while (System.nanoTime() < deadline); - throw new TimeoutException("Timeout while waiting for " + traceElement); - } - delayThread(DEFAULT_DELAY); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/shared/org/eclipse/tracecompass/tmf/ui/tests/shared/ProjectModelTestData.java b/org.eclipse.tracecompass.tmf.ui.tests/shared/org/eclipse/tracecompass/tmf/ui/tests/shared/ProjectModelTestData.java new file mode 100644 index 0000000000..a04f31d549 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/shared/org/eclipse/tracecompass/tmf/ui/tests/shared/ProjectModelTestData.java @@ -0,0 +1,265 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.shared; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.TimeoutException; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.project.model.TmfImportHelper; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace; +import org.eclipse.tracecompass.tmf.ui.project.model.ITmfProjectModelElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfCommonProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTracesFolder; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.WorkspaceModifyOperation; + +/** + * Creates objects used for this package's testing purposes + * + * @author Geneviève Bastien + */ +public class ProjectModelTestData { + + /* Maximum number of thread delays the main thread will do before timing out */ + private static final int DELAY_COUNTER = 1000; + /* Default delay time when having the main thread sleep. */ + private static final long DEFAULT_DELAY = 500; + + /** Default test project name */ + public static final String PROJECT_NAME = "Test_Project"; + + private static final TmfTestTrace testTrace = TmfTestTrace.A_TEST_10K; + + /** + * Gets a project element with traces all initialized + * + * @return A project stub element + * @throws CoreException + * If something happened with the project creation + */ + public static TmfProjectElement getFilledProject() throws CoreException { + + IProject project = TmfProjectRegistry.createProject(PROJECT_NAME, null, null); + IFolder traceFolder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME); + + /* Create a trace, if it exist, it will be replaced */ + File file = new File(testTrace.getFullPath()); + String path = file.getAbsolutePath(); + final IPath pathString = Path.fromOSString(path); + IResource linkedTrace = TmfImportHelper.createLink(traceFolder, pathString, pathString.lastSegment()); + if (!(linkedTrace != null && linkedTrace.exists())) { + return null; + } + linkedTrace.setPersistentProperty(TmfCommonConstants.TRACETYPE, + "org.eclipse.linuxtools.tmf.core.tests.tracetype"); + + final TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true); + TmfTraceElement traceElement = projectElement.getTracesFolder().getTraces().get(0); + traceElement.refreshTraceType(); + + projectElement.refresh(); + + return projectElement; + } + + /** + * Adds a new experiment to the project + * + * @param projectElement + * The project to add to + * @param experimentName + * Name of the experiment + * @return The newly created experiment + */ + public static TmfExperimentElement addExperiment(TmfProjectElement projectElement, String experimentName) { + IFolder experimentFolder = projectElement.getExperimentsFolder().getResource(); + final IFolder folder = experimentFolder.getFolder(experimentName); + + WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { + @Override + public void execute(IProgressMonitor monitor) throws CoreException { + monitor.beginTask("", 1000); + folder.create(false, true, monitor); + monitor.done(); + } + }; + try { + PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); + } catch (InterruptedException | InvocationTargetException | RuntimeException exception) { + + } + + for (ITmfProjectModelElement el : projectElement.getExperimentsFolder().getChildren()) { + if (el.getName().equals(experimentName) && (el instanceof TmfExperimentElement)) { + return (TmfExperimentElement) el; + } + } + return null; + } + + /** + * Get the name of the test trace element + * + * @return The trace name + */ + public static String getTraceName() { + File file = new File(testTrace.getPath()); + String path = file.getAbsolutePath(); + final IPath pathString = Path.fromOSString(path); + return pathString.lastSegment(); + } + + /** + * Deletes a project + * + * @param project + * Project to delete + */ + public static void deleteProject(TmfProjectElement project) { + /* Delete experiments */ + ITmfProjectModelElement[] experiments = project.getExperimentsFolder().getChildren().toArray(new ITmfProjectModelElement[0]); + for (ITmfProjectModelElement element : experiments) { + if (element instanceof TmfExperimentElement) { + TmfExperimentElement experiment = (TmfExperimentElement) element; + IResource resource = experiment.getResource(); + + /* Close the experiment if open */ + experiment.closeEditors(); + + IPath path = resource.getLocation(); + if (path != null) { + /* Delete supplementary files */ + experiment.deleteSupplementaryFolder(); + } + + /* Finally, delete the experiment */ + try { + resource.delete(true, null); + } catch (CoreException e) { + Activator.getDefault().logError("Error deleting experiment element", e); + } + } + } + + /* Delete traces */ + ITmfProjectModelElement[] traces = project.getTracesFolder().getChildren().toArray(new ITmfProjectModelElement[0]); + for (ITmfProjectModelElement element : traces) { + if (element instanceof TmfTraceElement) { + TmfTraceElement trace = (TmfTraceElement) element; + IResource resource = trace.getResource(); + + /* Close the trace if open */ + trace.closeEditors(); + + IPath path = resource.getLocation(); + if (path != null) { + /* Delete supplementary files */ + trace.deleteSupplementaryFolder(); + } + + /* Finally, delete the trace */ + try { + resource.delete(true, new NullProgressMonitor()); + } catch (CoreException e) { + Activator.getDefault().logError("Error deleting trace element", e); + } + } + } + + /* Delete the project itself */ + try { + project.getResource().delete(true, null); + } catch (CoreException e) { + Activator.getDefault().logError("Error deleting project", e); + } + } + + /** + * Makes the main display thread sleep, so it gives a chance to other + * threads needing the main display to execute + * + * @param waitTimeMillis + * time to wait in millisecond + */ + public static void delayThread(final long waitTimeMillis) { + final Display display = Display.getCurrent(); + if (display != null) { + final long endTimeMillis = System.currentTimeMillis() + waitTimeMillis; + while (System.currentTimeMillis() < endTimeMillis) { + if (!display.readAndDispatch()) { + display.sleep(); + } + display.update(); + } + } else { + try { + Thread.sleep(waitTimeMillis); + } catch (final InterruptedException e) { + // Ignored + } + } + } + + /** + * Makes the main display thread sleep to give a chance to other threads to + * execute. It sleeps until the a trace element's corresponding trace is + * available (opened) or returns after a timeout. It allows to set short + * delays, while still not failing tests when it randomly takes a bit more + * time for the trace to open. + * + * If the project model element sent in parameter is not a trace element, + * then the thread is delayed only once by the default delay time. For + * longer delays in those cases, it is preferable to use the + * {@link ProjectModelTestData#delayThread(long)} instead. + * + * Timeout is DELAY_COUNTER * DEFAULT_DELAY ms + * + * @param projectElement + * The trace element we are waiting for. If the element if not of + * type TmfTraceElement, the thread is delayed only once. + * @throws TimeoutException + * If after the maximum number of delays the trace is still + * null, we throw a timeout exception, the trace has not opened. + */ + public static void delayUntilTraceOpened(final ITmfProjectModelElement projectElement) throws TimeoutException { + if (projectElement instanceof TmfCommonProjectElement) { + TmfCommonProjectElement traceElement = (TmfCommonProjectElement) projectElement; + final long deadline = System.nanoTime() + (DELAY_COUNTER * DEFAULT_DELAY * 1000000L); + do { + delayThread(DEFAULT_DELAY); + if (traceElement.getTrace() != null) { + return; + } + } while (System.nanoTime() < deadline); + throw new TimeoutException("Timeout while waiting for " + traceElement); + } + delayThread(DEFAULT_DELAY); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/AllTmfUITests.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/AllTmfUITests.java deleted file mode 100644 index 2e53bf9dc3..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/AllTmfUITests.java +++ /dev/null @@ -1,39 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Bernd Hufmann - Add UML2SD tests - * Mathieu Denis - Add Statistics test - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Master test suite for TMF UI Core. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - org.eclipse.linuxtools.tmf.ui.tests.histogram.AllTests.class, - org.eclipse.linuxtools.tmf.ui.tests.project.model.AllTests.class, - org.eclipse.linuxtools.tmf.ui.tests.statistics.AllTests.class, - /* - * Sequence diagram tests disabled during the move to Trace Compass. - * TODO Please fix and re-enable - */ -// org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.dialogs.AllTests.class, -// org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.load.AllTests.class, -// org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.loader.AllTests.class -}) -public class AllTmfUITests { - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/TmfUITestPlugin.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/TmfUITestPlugin.java deleted file mode 100644 index aff6973d55..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/TmfUITestPlugin.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests; - -import org.eclipse.core.runtime.Plugin; -import org.osgi.framework.BundleContext; - -/** - * TmfUITestPlugin - *

- * The activator class controls the plug-in life cycle - * - * @author Marc-Andre Laperle - */ -public class TmfUITestPlugin extends Plugin { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The plug-in ID - */ - public static final String PLUGIN_ID = "org.eclipse.tracecompass.tmf.ui.tests"; - - // The shared instance - private static TmfUITestPlugin fPlugin; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * The constructor - */ - public TmfUITestPlugin() { - setDefault(this); - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * @return the shared instance - */ - public static TmfUITestPlugin getDefault() { - return fPlugin; - } - - /** - * @param plugin the shared instance - */ - private static void setDefault(TmfUITestPlugin plugin) { - fPlugin = plugin; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Override - public void start(BundleContext context) throws Exception { - super.start(context); - setDefault(this); - } - - @Override - public void stop(BundleContext context) throws Exception { - setDefault(null); - super.stop(context); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/histogram/AllTests.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/histogram/AllTests.java deleted file mode 100644 index c4afae7b79..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/histogram/AllTests.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.histogram; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite class for histogram tests. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - HistogramDataModelTest.class -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/histogram/HistogramDataModelTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/histogram/HistogramDataModelTest.java deleted file mode 100644 index 3799c51acd..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/histogram/HistogramDataModelTest.java +++ /dev/null @@ -1,703 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Adapt to junit.framework.TestCase - * Alexandre Montplaisir - Port to JUnit4 - * Patrick Tasse - Support selection range - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.histogram; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.views.histogram.HistogramBucket; -import org.eclipse.linuxtools.tmf.ui.views.histogram.HistogramDataModel; -import org.eclipse.linuxtools.tmf.ui.views.histogram.HistogramScaledData; -import org.eclipse.linuxtools.tmf.ui.views.histogram.IHistogramModelListener; -import org.junit.Test; - -/** - * Unit tests for the HistogramDataModel class. - */ -public class HistogramDataModelTest { - - private static final double DELTA = 1e-15; - - private final static HistogramBucket _0 = new HistogramBucket(new int[] {0}); - private final static HistogramBucket _1 = new HistogramBucket(new int[] {1}); - private final static HistogramBucket _2 = new HistogramBucket(new int[] {2}); - private final static HistogramBucket _4 = new HistogramBucket(new int[] {4}); - private final static HistogramBucket _9 = new HistogramBucket(new int[] {9}); - private final static HistogramBucket _20 = new HistogramBucket(new int[] {20}); - private final static HistogramBucket _24 = new HistogramBucket(new int[] {24}); - - /** - * Test method for {@link HistogramDataModel#HistogramDataModel()}. - */ - @Test - public void testHistogramDataModel() { - HistogramDataModel model = new HistogramDataModel(); - testModelConsistency(model, HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS,0, 1, 0 , 0 , 0 , HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS); - } - - /** - * Test method for {@link HistogramDataModel#HistogramDataModel(HistogramDataModel)}. - */ - @Test - public void testHistogramDataModelCopyConstructor() { - HistogramDataModel model = new HistogramDataModel(); - HistogramDataModel copy = new HistogramDataModel(model); - testModelConsistency(copy, HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS,0, 1, 0 , 0 , 0 , HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS); - } - - /** - * Test method for {@link HistogramDataModel#HistogramDataModel(int)}. - */ - @Test - public void testHistogramDataModelInt() { - final int nbBuckets = 5 * 1000; - HistogramDataModel model = new HistogramDataModel(nbBuckets); - testModelConsistency(model, nbBuckets, 0, 1, 0, 0, 0, nbBuckets); - } - - /** - * Test methods for {@link HistogramDataModel#countEvent(long,long, ITmfTrace)}. - */ - @Test - public void testClear() { - final int nbBuckets = 100; - HistogramDataModel model = new HistogramDataModel(nbBuckets); - model.countEvent(0, -1, null); - - testModelConsistency(model, nbBuckets, 0, 1, 0, 0, 0, nbBuckets); - } - - /** - * Test methods for {@link HistogramDataModel#countEvent(long,long, ITmfTrace)}. - */ - @Test - public void testCountEvent_0() { - final int nbBuckets = 100; - HistogramDataModel model = new HistogramDataModel(nbBuckets); - model.countEvent(0, -1, null); - - testModelConsistency(model, nbBuckets, 0, 1, 0, 0, 0, nbBuckets); - } - - /** - * Test methods for {@link HistogramDataModel#countEvent(long,long, ITmfTrace)} and - * {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testCountEvent_1() { - final int nbBuckets = 100; - final int maxHeight = 10; - - HistogramDataModel model = new HistogramDataModel(nbBuckets); - - HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); - - for (int i = 0; i < result.fData.length; i++) { - assertEquals(_0, result.fData[i]); - } - - testModelConsistency(model, nbBuckets, 0, 1, 0, 0, 0, nbBuckets); - } - - /** - * Test methods for {@link HistogramDataModel#countEvent(long,long, ITmfTrace)} and - * {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testCountEvent_2() { - final int nbBuckets = 100; - final int maxHeight = 10; - - HistogramDataModel model = new HistogramDataModel(nbBuckets); - model.countEvent(0, 1, null); - - HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); - assertEquals(_1, result.fData[0]); - - assertArrayEqualsInt(0, result.fData,1); - - testModelConsistency(model, nbBuckets, 1, 1, 1, 1, 1, nbBuckets + 1); - } - - /** - * Test methods for {@link HistogramDataModel#countEvent(long,long, ITmfTrace)} and - * {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testCountEvent_3() { - final int nbBuckets = 100; - final int maxHeight = 10; - - HistogramDataModel model = new HistogramDataModel(nbBuckets); - countEventsInModel(nbBuckets, model); - - HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); - - assertArrayEqualsInt(1, result.fData); - - testModelConsistency(model, nbBuckets, nbBuckets, 1, 0, 0, nbBuckets - 1, nbBuckets); - } - - /** - * Test methods for {@link HistogramDataModel#countEvent(long,long,ITmfTrace)} and - * {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testCountEvent_4() { - final int nbBuckets = 100; - final int maxHeight = 10; - - HistogramDataModel model = new HistogramDataModel(nbBuckets); - // to different to call elsewhere - for (int i = 0; i < nbBuckets; i++) { - model.countEvent(i, i, null); - model.countEvent(i + 1, i, null); - } - - HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); - - assertArrayEqualsInt(2, result.fData); - - testModelConsistency(model, nbBuckets, 2 * nbBuckets, 1, 0, 0, nbBuckets- 1, nbBuckets); - } - - - /** - * Test methods for {@link HistogramDataModel#countEvent(long,long,ITmfTrace)} and - * {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testCountEvent_5() { - final int nbBuckets = 100; - final int startTime = 25; - final int maxHeight = 10; - - HistogramDataModel model = new HistogramDataModel(nbBuckets); - for (int i = startTime; i < startTime + nbBuckets; i++) { - model.countEvent(i, i, null); - } - - HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); - - assertArrayEqualsInt(1, result.fData); - - testModelConsistency(model, nbBuckets, nbBuckets, 1, startTime, startTime, startTime + nbBuckets- 1, startTime + nbBuckets); - } - - /** - * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testScaleTo_0() { - HistogramDataModel model = new HistogramDataModel(10); - try { - model.scaleTo(10, 0, 1); - } catch (AssertionError e1) { - try { - model.scaleTo(0, 10, 1); - } catch (AssertionError e2) { - try { - model.scaleTo(0, 0, 1); - } catch (AssertionError e3) { - return; - } - } - } - fail("Uncaught assertion error"); - } - - /** - * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testScaleTo_1() { - final int nbBuckets = 10; - final int maxHeight = 10; - final int nbEvents = nbBuckets / 2; - final HistogramBucket[] expectedResult = new HistogramBucket[] { _1, _1, _1, _1, _1, _0, _0, _0, _0, _0 }; - - HistogramDataModel model = new HistogramDataModel(nbBuckets); - countEventsInModel(nbEvents, model); - - HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); - - assertArrayEquals( expectedResult, result.fData); - - testModelConsistency(model, nbBuckets, nbEvents, 1, 0, 0, nbEvents - 1, nbBuckets); - } - - /** - * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testScaleTo_2() { - final int nbBuckets = 10; - final int maxHeight = 10; - final int nbEvents = nbBuckets; - final HistogramBucket[] expectedResult = new HistogramBucket[] { _1, _1, _1, _1, _1, _1, _1, _1, _1, _1 }; - - HistogramDataModel model = new HistogramDataModel(nbBuckets); - countEventsInModel(nbEvents, model); - - HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); - - assertArrayEquals(expectedResult, result.fData); - - testModelConsistency(model, nbBuckets, nbEvents, 1, 0, 0, nbEvents - 1, nbBuckets); - } - - /** - * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testScaleTo_3() { - final int nbBuckets = 10; - final int maxHeight = 10; - final int nbEvents = 2 * nbBuckets; - final HistogramBucket[] expectedResult = new HistogramBucket[] { _2, _2, _2, _2, _2, _2, _2, _2, _2, _2 }; - - HistogramDataModel model = new HistogramDataModel(nbBuckets); - countEventsInModel(nbEvents, model); - - HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); - - assertArrayEquals(expectedResult, result.fData); - - testModelConsistency(model, nbBuckets, nbEvents, 2, 0, 0, nbEvents - 1, 2 * nbBuckets); - } - - /** - * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testScaleTo_4() { - final int nbBuckets = 10; - final int maxHeight = 10; - final int nbEvents = 3 * nbBuckets; - final HistogramBucket[] expectedResult = new HistogramBucket[] { _4, _4, _4, _4, _4, _4, _4, _2, _0, _0 }; - - HistogramDataModel model = new HistogramDataModel(nbBuckets); - countEventsInModel(nbEvents, model); - - HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); - - assertArrayEquals(expectedResult, result.fData); - - testModelConsistency(model, nbBuckets, nbEvents, 4, 0, 0, nbEvents - 1, 4 * nbBuckets); - } - - /** - * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testScaleTo_5() { - final int nbBuckets = 100; - final int maxHeight = 20; - final int nbEvents = 2 * nbBuckets; - final HistogramBucket[] expectedResult = new HistogramBucket[] { _20, _20, _20, _20, _20, _20, _20, _20, _20, _20 }; - - HistogramDataModel model = new HistogramDataModel(nbBuckets); - countEventsInModel(nbEvents, model); - - HistogramScaledData result = model.scaleTo(10, maxHeight, 1); - - assertArrayEquals(expectedResult, result.fData); - - testModelConsistency(model, nbBuckets, nbEvents, 2, 0, 0, nbEvents - 1, 2 * nbBuckets); - } - - /** - * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testScaleTo_6() { - final int nbBuckets = 100; - final int maxHeight = 24; - final int nbEvents = 2 * nbBuckets + 1; - final HistogramBucket[] expectedResult = new HistogramBucket[] { _24, _24, _24, _24, _24, _24, _24, _24, _9, _0 }; - - HistogramDataModel model = new HistogramDataModel(nbBuckets); - countEventsInModel(nbEvents, model); - - HistogramScaledData result = model.scaleTo(10, maxHeight, 1); - - assertArrayEquals(expectedResult, result.fData); - - testModelConsistency(model, nbBuckets, nbEvents, 4, 0, 0, nbEvents - 1, 4 * nbBuckets); - } - - /** - * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testScaleTo_7() { - // verify scaleTo with barWidth > 1 - final int nbBuckets = 100; - final int maxHeight = 24; - final int width = 10; - final int barWidth = 4; - final int nbEvents = 2 * nbBuckets + 1; - - // (int)(width / barWith) = 2 - // -> 2 bars -> expected result needs two buckets (scaled data) - // - // buckets (in model) per bar = last bucket id / nbBars + 1 (plus 1 to - // cover all used buckets) - // -> buckets per bar = 50 / 2 + 1 = 26 - // -> first entry in expected result is 26 * 4 = 104 - // -> second entry in expected result is 22 * 4 + 9 = 97 - final HistogramBucket[] expectedResult = new HistogramBucket[] { new HistogramBucket(new int[] {104}) , new HistogramBucket(new int[] {97}) }; - - HistogramDataModel model = new HistogramDataModel(nbBuckets); - countEventsInModel(nbEvents, model); - - // verify scaled data - HistogramScaledData result = model.scaleTo(width, maxHeight, barWidth); - - assertEquals(4 * 26, result.fBucketDuration); - assertEquals(0, result.fSelectionBeginBucket); - assertEquals(0, result.fSelectionEndBucket); - assertEquals(0, result.fFirstBucketTime); - assertEquals(0, result.fFirstEventTime); - assertEquals(1, result.fLastBucket); - assertEquals(104, result.fMaxValue); - assertEquals((double) maxHeight / 104, result.fScalingFactor, DELTA); - assertEquals(maxHeight, result.fHeight); - assertEquals(width, result.fWidth); - assertEquals(barWidth, result.fBarWidth); - - assertArrayEquals(expectedResult, result.fData); - - // verify model - testModelConsistency(model, nbBuckets, nbEvents, 4, 0, 0, nbEvents - 1, 4 * nbBuckets); - } - - /** - * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testScaleToReverse_1() { - final int nbBuckets = 100; - final int maxHeight = 24; - final int width = 10; - final int barWidth = 1; - final int nbEvents = 2 * nbBuckets + 1; - - // (int)(width / barWith) = 10 - // -> 10 bars -> expected result needs 10 buckets (scaled data) - // - // buckets in (model) per bar = last bucket id / nbBars + 1 (plus 1 to - // cover all used buckets) - // -> buckets per bar = 50 / 10 + 1 = 6 - final HistogramBucket[] expectedResult = new HistogramBucket[] { new HistogramBucket(new int[] {21}), _24, _24, _24, _24, _24, _24, _24, new HistogramBucket(new int[] {12}), _0 }; - - HistogramDataModel model = new HistogramDataModel(nbBuckets); - countInvertedEvents(nbEvents, model); - - // verify scaled data - HistogramScaledData result = model.scaleTo(width, maxHeight, barWidth); - - assertEquals(4 * 6, result.fBucketDuration); - assertEquals(0, result.fSelectionBeginBucket); - assertEquals(0, result.fSelectionEndBucket); - assertEquals(-3, result.fFirstBucketTime); // negative is correct, can - // happen when reverse - assertEquals(0, result.fFirstEventTime); - assertEquals(9, result.fLastBucket); - assertEquals(24, result.fMaxValue); - assertEquals((double) maxHeight / 24, result.fScalingFactor, DELTA); - assertEquals(maxHeight, result.fHeight); - assertEquals(width, result.fWidth); - assertEquals(barWidth, result.fBarWidth); - - assertArrayEquals(expectedResult, result.fData); - - // verify model - testModelConsistency(model, nbBuckets, nbEvents, 4, -3, 0, nbEvents - 1, -3 + 4 * nbBuckets); - } - - private static void countInvertedEvents(final int nbEvents, HistogramDataModel model) { - for (int i = nbEvents - 1; i >= 0; i--) { - model.countEvent(i, i, null); - } - } - - /** - * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testScaleToReverse_2() { - final int nbBuckets = 100; - final int maxHeight = 24; - final int width = 10; - final int barWidth = 1; - - final int nbEvents = 2 * nbBuckets; - - HistogramDataModel model = new HistogramDataModel(nbBuckets); - countEventsInModel(nbEvents, model); - - HistogramScaledData result = model.scaleTo(width, maxHeight, barWidth); - - model.clear(); - - countInvertedEvents(nbEvents, model); - - HistogramScaledData revResult = model.scaleTo(width, maxHeight, barWidth); - - testModelConsistency(model, nbBuckets, nbEvents, 2, 0, 0, nbEvents - 1, 2 * nbBuckets); - - // For the above number of events, result and revResult are exactly the same. - - assertEquals(result.fBucketDuration, revResult.fBucketDuration); - assertEquals(result.fSelectionBeginBucket, revResult.fSelectionBeginBucket); - assertEquals(result.fSelectionEndBucket, revResult.fSelectionEndBucket); - assertEquals(result.fFirstBucketTime, revResult.fFirstBucketTime); - assertEquals(result.fMaxValue, revResult.fMaxValue); - assertEquals(result.fScalingFactor, revResult.fScalingFactor, DELTA); - assertEquals(result.fLastBucket, revResult.fLastBucket); - assertEquals(result.getBucketEndTime(0), revResult.getBucketEndTime(0)); - assertEquals(result.getBucketStartTime(0), revResult.getBucketStartTime(0)); - - assertArrayEquals(revResult.fData, result.fData); - } - - /** - * Test method for testing model listener. - */ - @Test - public void testModelListener() { - final int nbBuckets = 2000; - final int nbEvents = 10 * nbBuckets + 256; - final int[] count = new int[1]; - count[0] = 0; - - // Test add listener and call of listener - IHistogramModelListener listener = new IHistogramModelListener() { - @Override - public void modelUpdated() { - count[0]++; - } - }; - - // Test that the listener interface is called every 16000 events. - HistogramDataModel model = new HistogramDataModel(nbBuckets); - model.addHistogramListener(listener); - - countEventsInModel(nbEvents, model, 1); - - assertEquals(1, count[0]); - - // Test that the listener interface is called when complete is called. - model.complete(); - assertEquals(2, count[0]); - - // Test that clear triggers call of listener interface - model.clear(); - assertEquals(3, count[0]); - - // Test remove listener - count[0] = 0; - model.removeHistogramListener(listener); - - countEventsInModel(nbEvents, model); - model.complete(); - assertEquals(0, count[0]); - } - - /** - * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testLostEventsScaleTo_0() { - final int nbBuckets = 10; - final int maxHeight = 10; - final int nbEvents = 3 * nbBuckets; - final int nbLostEvents_0 = 4; - final int nbLostEvents_1 = 9; - final int nbCombinedEvents = nbEvents + 2; - final HistogramBucket[] expectedResult = new HistogramBucket[] { _4, _4, _4, _4, _4, _4, _4, _2, _0, _0 }; - final int[] expectedLostEventsResult = new int[] { 0, 2, 2, 0, 3, 3, 3, 0, 0, 0 }; - - HistogramDataModel model = new HistogramDataModel(nbBuckets); - countEventsInModel(nbEvents, model); - - final TmfTimeRange timeRange_0 = new TmfTimeRange( - new TmfTimestamp(5L, ITmfTimestamp.NANOSECOND_SCALE), - new TmfTimestamp(10L, ITmfTimestamp.NANOSECOND_SCALE)); - model.countLostEvent(timeRange_0, nbLostEvents_0, false); - - final TmfTimeRange timeRange_1 = new TmfTimeRange( - new TmfTimestamp(18L, ITmfTimestamp.NANOSECOND_SCALE), - new TmfTimestamp(27L, ITmfTimestamp.NANOSECOND_SCALE)); - model.countLostEvent(timeRange_1, nbLostEvents_1, false); - - HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); - - assertArrayEquals(expectedResult, result.fData); - - assertArrayEquals(expectedLostEventsResult, result.fLostEventsData); - - testModelConsistency(model, nbBuckets, nbCombinedEvents, 4, 0, 0, nbEvents - 1, 4 * nbBuckets); - assertEquals(7, result.fMaxCombinedValue); - } - - /** - * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testLostEventsScaleTo_1() { - final int nbBuckets = 10; - final int maxHeight = 10; - final int nbEvents = 3 * nbBuckets; - final int nbLostEvents_0 = 4; - final int nbLostEvents_1 = 9; - final int nbCombinedEvents = nbEvents + 2; - final int[] expectedLostEventsResult = new int[] { 0, 2, 5, 3, 3, 0, 0, 0, 0, 0 }; - - HistogramDataModel model = new HistogramDataModel(nbBuckets); - countEventsInModel(nbEvents, model); - - final TmfTimeRange timeRange_0 = new TmfTimeRange( - new TmfTimestamp(5L, ITmfTimestamp.NANOSECOND_SCALE), - new TmfTimestamp(10L, ITmfTimestamp.NANOSECOND_SCALE)); - model.countLostEvent(timeRange_0, nbLostEvents_0, false); - - final TmfTimeRange timeRange_1 = new TmfTimeRange( - new TmfTimestamp(11L, ITmfTimestamp.NANOSECOND_SCALE), - new TmfTimestamp(18L, ITmfTimestamp.NANOSECOND_SCALE)); - model.countLostEvent(timeRange_1, nbLostEvents_1, false); - - HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); - - assertArrayEquals(expectedLostEventsResult, result.fLostEventsData); - - testModelConsistency(model, nbBuckets, nbCombinedEvents, 4, 0, 0, nbEvents - 1, 4 * nbBuckets); - assertEquals(9, result.fMaxCombinedValue); - } - - /** - * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testLostEventsScaleTo_2() { - final int nbBuckets = 10; - final int maxHeight = 10; - final int nbEvents = 3 * nbBuckets; - final int nbLostEvents_0 = 5; - final int nbLostEvents_1 = 15; - final int nbLostEvents_2 = 2; - final int nbCombinedEvents = nbEvents + 3; - final int[] expectedLostEventsResult = new int[] { 0, 0, 3, 3, 6, 5, 3, 2, 0, 0 }; - - HistogramDataModel model = new HistogramDataModel(nbBuckets); - countEventsInModel(nbEvents, model); - - final TmfTimeRange timeRange_0 = new TmfTimeRange( - new TmfTimestamp(18L, ITmfTimestamp.NANOSECOND_SCALE), - new TmfTimestamp(22L, ITmfTimestamp.NANOSECOND_SCALE)); - model.countLostEvent(timeRange_0, nbLostEvents_0, false); - - final TmfTimeRange timeRange_2 = new TmfTimeRange( - new TmfTimestamp(28L, ITmfTimestamp.NANOSECOND_SCALE), - new TmfTimestamp(29L, ITmfTimestamp.NANOSECOND_SCALE)); - model.countLostEvent(timeRange_2, nbLostEvents_2, false); - - final TmfTimeRange timeRange_1 = new TmfTimeRange( - new TmfTimestamp(11L, ITmfTimestamp.NANOSECOND_SCALE), - new TmfTimestamp(26L, ITmfTimestamp.NANOSECOND_SCALE)); - model.countLostEvent(timeRange_1, nbLostEvents_1, false); - - HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); - - assertArrayEquals(expectedLostEventsResult, result.fLostEventsData ); - - testModelConsistency(model, nbBuckets, nbCombinedEvents, 4, 0, 0, nbEvents - 1, 4 * nbBuckets); - assertEquals(10, result.fMaxCombinedValue); - } - - /** - * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. - */ - @Test - public void testLostEventsScaleTo_3() { - final int nbBuckets = 10; - final int maxHeight = 10; - final int nbEvents = 3 * nbBuckets; - final int nbLostEvents_0 = 23; - final int nbCombinedEvents = nbEvents + 1; - final int[] expectedLostEventsResult = new int[] { 0, 0, 5, 5, 5, 5, 3, 0, 0, 0 }; - - HistogramDataModel model = new HistogramDataModel(nbBuckets); - countEventsInModel(nbEvents, model); - - final TmfTimeRange timeRange_0 = new TmfTimeRange( - new TmfTimestamp(11L, ITmfTimestamp.NANOSECOND_SCALE), - new TmfTimestamp(26L, ITmfTimestamp.NANOSECOND_SCALE)); - model.countLostEvent(timeRange_0, nbLostEvents_0, false); - - HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); - - assertArrayEquals(expectedLostEventsResult, result.fLostEventsData ); - - testModelConsistency(model, nbBuckets, nbCombinedEvents, 4, 0, 0, nbEvents - 1, 4 * nbBuckets); - assertEquals(9, result.fMaxCombinedValue); - } - - /* - * helpers - */ - - private static void countEventsInModel(final int nbEvents, HistogramDataModel model) { - countEventsInModel(nbEvents, model, 0); - } - - private static void countEventsInModel(final int nbEvents, HistogramDataModel model, int offset) { - countEventsInModel(nbEvents, model, offset, 0); - } - - private static void countEventsInModel(final int nbEvents, HistogramDataModel model, int offset, int startTime) { - for (int i = startTime; i < nbEvents + startTime; i++) { - model.countEvent(i + offset, i, null); - } - } - - private static void testModelConsistency(HistogramDataModel model, int numberOfBuckets,int nbEvents, int bucketduration,int firstBucketTime, int startTime, int endTime, int timeLimit) { - assertEquals(numberOfBuckets, model.getNbBuckets()); - assertEquals(nbEvents, model.getNbEvents()); - assertEquals(bucketduration, model.getBucketDuration()); - assertEquals(firstBucketTime, model.getFirstBucketTime()); - assertEquals(startTime, model.getStartTime()); - assertEquals(endTime, model.getEndTime()); - assertEquals(timeLimit, model.getTimeLimit()); - } - - private static void assertArrayEqualsInt(final int val , HistogramBucket[] result) { - assertArrayEqualsInt(val, result, 0); - } - - private static void assertArrayEqualsInt(final int val , HistogramBucket[] result, int startVal ) { - for (int i = startVal; i < result.length; i++) { - assertEquals(val, result[i].getNbEvents()); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/AllTests.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/AllTests.java deleted file mode 100644 index cd58290922..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/AllTests.java +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.project.model; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite for org.eclipse.linuxtools.tmf.ui.project.model - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - ProjectModelAnalysisTest.class, - ProjectModelOutputTest.class, - ProjectModelTraceTest.class, - TraceAndExperimentTypeTest.class -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelAnalysisTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelAnalysisTest.java deleted file mode 100644 index befa33fac7..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelAnalysisTest.java +++ /dev/null @@ -1,161 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.project.model; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; - -import java.util.List; -import java.util.concurrent.TimeoutException; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.project.model.ITmfProjectModelElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfAnalysisElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.tests.shared.ProjectModelTestData; -import org.eclipse.linuxtools.tmf.ui.tests.stubs.analysis.TestAnalysisUi; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Test suite for the {@link TmfAnalysisElement} class. - * - * @author Geneviève Bastien - */ -public class ProjectModelAnalysisTest { - - /** ID of analysis module in UI */ - public static final String MODULE_UI = "org.eclipse.linuxtools.tmf.ui.tests.test"; - private TmfProjectElement fixture; - - /** - * Perform pre-test initialization. - */ - @Before - public void setUp() { - try { - fixture = ProjectModelTestData.getFilledProject(); - } catch (CoreException e) { - fail(e.getMessage()); - } - } - - /** - * Cleans up the project after tests have been executed - */ - @After - public void cleanUp() { - ProjectModelTestData.deleteProject(fixture); - } - - private TmfTraceElement getTraceElement() { - TmfTraceElement trace = null; - for (ITmfProjectModelElement element : fixture.getTracesFolder().getChildren()) { - if (element instanceof TmfTraceElement) { - TmfTraceElement traceElement = (TmfTraceElement) element; - if (traceElement.getName().equals(ProjectModelTestData.getTraceName())) { - trace = traceElement; - } - } - } - assertNotNull(trace); - return trace; - } - - /** - * Test the getAvailableAnalysis() method - */ - @Test - public void testListAnalysis() { - TmfTraceElement trace = getTraceElement(); - - /* Make sure the analysis list is not empty */ - List analysisList = trace.getAvailableAnalysis(); - assertFalse(analysisList.isEmpty()); - - /* Make sure TestAnalysisUi is there */ - TmfAnalysisElement analysis = null; - for (TmfAnalysisElement analysisElement : analysisList) { - if (analysisElement.getAnalysisId().equals(MODULE_UI)) { - analysis = analysisElement; - } - } - assertNotNull(analysis); - - assertEquals("Test analysis in UI", analysis.getName()); - } - - /** - * Test if the list of available analysis is correctly populated by the - * content provider - */ - @Test - public void testPopulate() { - TmfTraceElement trace = getTraceElement(); - - /* Make sure the analysis list is not empty */ - List analysisList = trace.getChildren(); - assertFalse(analysisList.isEmpty()); - - /* Make sure TestAnalysisUi is there */ - TmfAnalysisElement analysis = null; - for (ITmfProjectModelElement element : analysisList) { - if (element instanceof TmfAnalysisElement) { - TmfAnalysisElement analysisElement = (TmfAnalysisElement) element; - if (analysisElement.getAnalysisId().equals(MODULE_UI)) { - analysis = analysisElement; - } - } - } - assertNotNull(analysis); - - assertEquals("Test analysis in UI", analysis.getName()); - } - - /** - * Test the instantiateAnalysis method - */ - @Test - public void testInstantiate() { - TmfTraceElement traceElement = getTraceElement(); - - TmfAnalysisElement analysis = null; - for (TmfAnalysisElement analysisElement : traceElement.getAvailableAnalysis()) { - if (analysisElement.getAnalysisId().equals(MODULE_UI)) { - analysis = analysisElement; - } - } - assertNotNull(analysis); - - /* Instantiate an analysis on a trace that is closed */ - traceElement.closeEditors(); - analysis.activateParent(); - - try { - ProjectModelTestData.delayUntilTraceOpened(traceElement); - } catch (TimeoutException e) { - fail("The analysis parent did not open in a reasonable time"); - } - ITmfTrace trace = traceElement.getTrace(); - - assertNotNull(trace); - TestAnalysisUi module = (TestAnalysisUi) trace.getAnalysisModule(analysis.getAnalysisId()); - assertNotNull(module); - - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelOutputTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelOutputTest.java deleted file mode 100644 index 108e1d7b8e..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelOutputTest.java +++ /dev/null @@ -1,171 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.project.model; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.List; -import java.util.concurrent.TimeoutException; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.linuxtools.tmf.ui.project.model.ITmfProjectModelElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfAnalysisElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfAnalysisOutputElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.tests.shared.ProjectModelTestData; -import org.eclipse.linuxtools.tmf.ui.tests.stubs.analysis.TestAnalysisUi; -import org.eclipse.ui.IViewPart; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PlatformUI; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Test suite for the {@link TmfAnalysisOutputElement} class. - * - * @author Geneviève Bastien - */ -public class ProjectModelOutputTest { - - private TmfProjectElement fixture; - - /** - * Perform pre-test initialization. - */ - @Before - public void setUp() { - try { - fixture = ProjectModelTestData.getFilledProject(); - } catch (CoreException e) { - fail(e.getMessage()); - } - } - - /** - * Cleans up the project after tests have been executed - */ - @After - public void cleanUp() { - ProjectModelTestData.deleteProject(fixture); - } - - private TmfTraceElement getTraceElement() { - TmfTraceElement trace = null; - for (ITmfProjectModelElement element : fixture.getTracesFolder().getChildren()) { - if (element instanceof TmfTraceElement) { - TmfTraceElement traceElement = (TmfTraceElement) element; - if (traceElement.getName().equals(ProjectModelTestData.getTraceName())) { - trace = traceElement; - } - } - } - assertNotNull(trace); - return trace; - } - - private TmfAnalysisElement getTestAnalysisUi() { - TmfTraceElement trace = getTraceElement(); - - /* Make sure the analysis list is not empty */ - List analysisList = trace.getAvailableAnalysis(); - assertFalse(analysisList.isEmpty()); - - /* Make sure TestAnalysisUi is there */ - TmfAnalysisElement analysis = null; - for (TmfAnalysisElement analysisElement : analysisList) { - if (analysisElement.getAnalysisId().equals(ProjectModelAnalysisTest.MODULE_UI)) { - analysis = analysisElement; - } - } - assertNotNull(analysis); - return analysis; - } - - /** - * Test the getAvailableOutputs() method - */ - @Test - public void testListOutputs() { - TmfAnalysisElement analysis = getTestAnalysisUi(); - - /* To get the list of outputs the trace needs to be opened */ - analysis.activateParent(); - try { - ProjectModelTestData.delayUntilTraceOpened(analysis.getParent()); - } catch (TimeoutException e) { - fail("The analysis parent did not open in a reasonable time"); - } - - /* Make sure the output list is not empty */ - List outputList = analysis.getAvailableOutputs(); - assertFalse(outputList.isEmpty()); - boolean found = false; - for (ITmfProjectModelElement element : outputList) { - if (element instanceof TmfAnalysisOutputElement) { - TmfAnalysisOutputElement outputElement = (TmfAnalysisOutputElement) element; - if (outputElement.getName().equals("Test Analysis View")) { - found = true; - } - } - } - assertTrue(found); - } - - /** - * Test the outputAnalysis method for a view - */ - @Test - public void testOpenView() { - TmfAnalysisElement analysis = getTestAnalysisUi(); - - analysis.activateParent(); - try { - ProjectModelTestData.delayUntilTraceOpened(analysis.getParent()); - } catch (TimeoutException e) { - fail("The analysis parent did not open in a reasonable time"); - } - - List outputList = analysis.getAvailableOutputs(); - assertFalse(outputList.isEmpty()); - - final IWorkbench wb = PlatformUI.getWorkbench(); - final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); - - IViewPart view = activePage.findView(TestAnalysisUi.VIEW_ID); - if (view != null) { - activePage.hideView(view); - } - - TmfAnalysisOutputElement outputElement = null; - for (ITmfProjectModelElement element : outputList) { - if (element instanceof TmfAnalysisOutputElement) { - TmfAnalysisOutputElement el = (TmfAnalysisOutputElement) element; - if (el.getName().equals("Test Analysis View")) { - outputElement = el; - } - } - } - assertNotNull(outputElement); - - outputElement.outputAnalysis(); - ProjectModelTestData.delayThread(1000); - view = activePage.findView(TestAnalysisUi.VIEW_ID); - assertNotNull(view); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelTraceTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelTraceTest.java deleted file mode 100644 index 50b7291863..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelTraceTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.project.model; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.concurrent.TimeoutException; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfOpenTraceHelper; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.tests.shared.ProjectModelTestData; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Test suite for the TmfTraceElement class. - * - * @author Geneviève Bastien - */ -public class ProjectModelTraceTest { - - private TmfProjectElement fixture; - - /** - * Perform pre-test initialization. - */ - @Before - public void setUp() { - try { - fixture = ProjectModelTestData.getFilledProject(); - } catch (CoreException e) { - fail(e.getMessage()); - } - } - - /** - * Cleans up the project after tests have been executed - */ - @After - public void cleanUp() { - ProjectModelTestData.deleteProject(fixture); - } - - /** - * Test the getTrace() and trace opening - */ - @Test - public void testOpenTrace() { - assertNotNull(fixture); - - final TmfTraceElement traceElement = fixture.getTracesFolder().getTraces().get(0); - - /* - * Get the trace from the element, it is not opened yet, should be null - */ - ITmfTrace trace = traceElement.getTrace(); - assertNull(trace); - - TmfOpenTraceHelper.openTraceFromElement(traceElement); - - /* Give the trace a chance to open */ - try { - ProjectModelTestData.delayUntilTraceOpened(traceElement); - } catch (TimeoutException e) { - fail("The trace did not open in a reasonable delay"); - } - - trace = traceElement.getTrace(); - assertNotNull(trace); - - /* - * Open the trace from project, then get from element, both should be - * the exact same element as the active trace - */ - TmfOpenTraceHelper.openTraceFromElement(traceElement); - try { - ProjectModelTestData.delayUntilTraceOpened(traceElement); - } catch (TimeoutException e) { - fail("The trace did not open in a reasonable delay"); - } - - ITmfTrace trace2 = TmfTraceManager.getInstance().getActiveTrace(); - - /* The trace was reopened, it should be the same as before */ - assertTrue(trace2 == trace); - - /* Here, the getTrace() should return the same as active trace */ - trace = traceElement.getTrace(); - assertTrue(trace2 == trace); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/TraceAndExperimentTypeTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/TraceAndExperimentTypeTest.java deleted file mode 100644 index 1d533b14e3..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/TraceAndExperimentTypeTest.java +++ /dev/null @@ -1,199 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.project.model; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.concurrent.TimeoutException; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfExperimentStub; -import org.eclipse.linuxtools.tmf.ui.editors.TmfEventsEditor; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfOpenTraceHelper; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; -import org.eclipse.linuxtools.tmf.ui.tests.experiment.type.TmfEventsEditorStub; -import org.eclipse.linuxtools.tmf.ui.tests.shared.ProjectModelTestData; -import org.eclipse.linuxtools.tmf.ui.viewers.events.TmfEventsTable; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PlatformUI; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Some unit tests for trace types and experiment types - * - * @author Geneviève Bastien - */ -public class TraceAndExperimentTypeTest { - - /** Test experiment type id */ - public final static String TEST_EXPERIMENT_TYPE = "org.eclipse.linuxtools.tmf.core.tests.experimenttype"; - - private TmfProjectElement fixture; - private TmfExperimentElement fExperiment; - private final String EXPERIMENT_NAME = "exp_test"; - - /** - * Perform pre-test initialization. - */ - @Before - public void setUp() { - try { - fixture = ProjectModelTestData.getFilledProject(); - fExperiment = ProjectModelTestData.addExperiment(fixture, EXPERIMENT_NAME); - assertNotNull(fExperiment); - } catch (CoreException e) { - fail(e.getMessage()); - } - } - - /** - * Cleans up the project after tests have been executed - */ - @After - public void cleanUp() { - ProjectModelTestData.deleteProject(fixture); - } - - /** - * Test whether a newly created experiment has the default experiment type, - * even though none was specified - */ - @Test - public void testDefaultExperimentType() { - TmfExperimentElement experimentElement = ProjectModelTestData.addExperiment(fixture, "testDefaultExpType"); - assertNotNull(experimentElement); - TmfExperiment experiment = experimentElement.instantiateTrace(); - assertNotNull(experiment); - assertEquals(TmfTraceType.DEFAULT_EXPERIMENT_TYPE, experimentElement.getTraceType()); - } - - /** - * Test that the experiment opened is of the right class - */ - @Test - public void testExperimentType() { - - IResource resource = fExperiment.getResource(); - try { - resource.setPersistentProperty(TmfCommonConstants.TRACETYPE, TEST_EXPERIMENT_TYPE); - fExperiment.refreshTraceType(); - } catch (CoreException e) { - fail(e.getMessage()); - } - - TmfOpenTraceHelper.openTraceFromElement(fExperiment); - try { - ProjectModelTestData.delayUntilTraceOpened(fExperiment); - } catch (TimeoutException e1) { - fail (e1.getMessage()); - } - - ITmfTrace trace = fExperiment.getTrace(); - assertTrue(trace instanceof TmfExperimentStub); - } - - /** - * Test that event editor, event table and statistics viewer are the default - * ones for a generic experiment - */ - @Test - public void testNoExperimentTypeChildren() { - TmfOpenTraceHelper.openTraceFromElement(fExperiment); - - try { - ProjectModelTestData.delayUntilTraceOpened(fExperiment); - } catch (TimeoutException e1) { - fail (e1.getMessage()); - } - - final IWorkbench wb = PlatformUI.getWorkbench(); - final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); - IEditorPart editor = activePage.getActiveEditor(); - - /* Test the editor class. Cannot test table class since it is unexposed */ - assertNotNull(editor); - assertTrue(editor.getClass().equals(TmfEventsEditor.class)); - } - - /** - * Test that event editor, event table and statistics viewer are built - * correctly when specified - */ - @Test - public void testExperimentTypeChildren() { - - /* Set the trace type of the experiment */ - IResource resource = fExperiment.getResource(); - try { - resource.setPersistentProperty(TmfCommonConstants.TRACETYPE, TEST_EXPERIMENT_TYPE); - fExperiment.refreshTraceType(); - } catch (CoreException e) { - fail(e.getMessage()); - } - - TmfOpenTraceHelper.openTraceFromElement(fExperiment); - - ProjectModelTestData.delayThread(500); - - /* Test the editor class */ - final IWorkbench wb = PlatformUI.getWorkbench(); - final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); - IEditorPart editor = activePage.getActiveEditor(); - - assertNotNull(editor); - assertTrue(editor.getClass().equals(TmfEventsEditorStub.class)); - - /* Test the event table class */ - TmfEventsEditorStub editorStub = (TmfEventsEditorStub) editor; - TmfEventsTable table = editorStub.getNewEventsTable(); - - assertNotNull(table); - assertTrue(table.getClass().equals(TmfEventsTable.class)); - - } - - /** - * Test that the analysis get populated under an experiment of the proper type - */ - @Test - public void testExperimentTypeAnalysis() { - - /* Set the trace type of the experiment */ - IResource resource = fExperiment.getResource(); - try { - resource.setPersistentProperty(TmfCommonConstants.TRACETYPE, TEST_EXPERIMENT_TYPE); - fExperiment.refreshTraceType(); - } catch (CoreException e) { - fail(e.getMessage()); - } - - /* Force the refresh of the experiment */ - fExperiment.getParent().refresh(); - assertFalse(fExperiment.getAvailableAnalysis().isEmpty()); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/AllTests.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/AllTests.java deleted file mode 100644 index c1f8a1986e..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/AllTests.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial API and Implementation - * Bernd Hufmann - Fixed suite name - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.statistics; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite for statistic tests. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TmfBaseColumnDataProviderTest.class, - TmfBaseColumnDataTest.class, - TmfBaseStatisticsDataTest.class, - TmfStatisticsTest.class, - TmfStatisticsTreeNodeTest.class, - TmfStatisticsTreeManagerTest.class, - TmfTreeContentProviderTest.class -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfBaseColumnDataProviderTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfBaseColumnDataProviderTest.java deleted file mode 100644 index f774433b7b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfBaseColumnDataProviderTest.java +++ /dev/null @@ -1,173 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial API and Implementation - * Bernd Hufmann - Fixed header and warnings - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.statistics; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.util.List; - -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.ViewerComparator; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.Messages; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfBaseColumnData; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfBaseColumnData.ITmfColumnPercentageProvider; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfBaseColumnDataProvider; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTree; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode; -import org.junit.Test; - -/** - * TmfBaseColumnDataProvider test cases. - * - */ -public class TmfBaseColumnDataProviderTest { - - // ------------------------------------------------------------------------ - // Fields - // ------------------------------------------------------------------------ - - private static final double DELTA = 1e-15; - - private final static String LEVEL_COLUMN = Messages.TmfStatisticsView_LevelColumn; - private final static String EVENTS_COUNT_COLUMN = Messages.TmfStatisticsView_NbEventsColumn; - - private TmfBaseColumnDataProvider provider; - - private static final String fTestName = "ColumnDataProviderTest"; - - private final String fContext = "UnitTest"; - - private final String fTypeId1 = "Some type1"; - private final String fTypeId2 = "Some type2"; - - private final String fLabel0 = "label1"; - private final String fLabel1 = "label2"; - private final String fLabel2 = "label3"; - private final String[] fLabels = new String[] { fLabel0, fLabel1, fLabel2 }; - - private final TmfTimestamp fTimestamp1 = new TmfTimestamp(12345, (byte) 2, 5); - private final TmfTimestamp fTimestamp2 = new TmfTimestamp(12350, (byte) 2, 5); - private final TmfTimestamp fTimestamp3 = new TmfTimestamp(12355, (byte) 2, 5); - - private final String fSource = "Source"; - - private final TmfEventType fType1 = new TmfEventType(fContext, fTypeId1, TmfEventField.makeRoot(fLabels)); - private final TmfEventType fType2 = new TmfEventType(fContext, fTypeId1, TmfEventField.makeRoot(fLabels)); - private final TmfEventType fType3 = new TmfEventType(fContext, fTypeId2, TmfEventField.makeRoot(fLabels)); - - private final String fReference = "Some reference"; - - private final ITmfEvent fEvent1; - private final ITmfEvent fEvent2; - private final ITmfEvent fEvent3; - - private final TmfEventField fContent1; - private final TmfEventField fContent2; - private final TmfEventField fContent3; - - private final TmfStatisticsTree fStatsData; - - // ------------------------------------------------------------------------ - // Housekeeping - // ------------------------------------------------------------------------ - - /** - * Constructor - */ - public TmfBaseColumnDataProviderTest() { - fContent1 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some content", null); - fEvent1 = new TmfEvent(null, fTimestamp1, fSource, fType1, fContent1, fReference); - - fContent2 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some other content", null); - fEvent2 = new TmfEvent(null, fTimestamp2, fSource, fType2, fContent2, fReference); - - fContent3 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some other different content", null); - fEvent3 = new TmfEvent(null, fTimestamp3, fSource, fType3, fContent3, fReference); - - fStatsData = new TmfStatisticsTree(); - - fStatsData.getOrCreateNode(fTestName, Messages.TmfStatisticsData_EventTypes); - - fStatsData.setTotal(fTestName, true, 3); - fStatsData.setTypeCount(fTestName, fEvent1.getType().getName(), true, 1); - fStatsData.setTypeCount(fTestName, fEvent2.getType().getName(), true, 1); - fStatsData.setTypeCount(fTestName, fEvent3.getType().getName(), true, 1); - - provider = new TmfBaseColumnDataProvider(); - } - - // ------------------------------------------------------------------------ - // Get Column Data - // ------------------------------------------------------------------------ - - /** - * Method with test cases. - */ - @Test - public void testGetColumnData() { - List columnsData = provider.getColumnData(); - assertNotNull("getColumnData", columnsData); - assertEquals("getColumnData", 4, columnsData.size()); - - TmfStatisticsTreeNode parentNode = fStatsData.getNode(fTestName); - TmfStatisticsTreeNode treeNode1 = fStatsData.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fEvent1.getType().getName()); - TmfStatisticsTreeNode treeNode2 = fStatsData.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fEvent3.getType().getName()); - ViewerComparator vComp = null; - for (TmfBaseColumnData columnData : columnsData) { - assertNotNull("getColumnData", columnData); - assertNotNull("getColumnData", columnData.getHeader()); - assertNotNull("getColumnData", columnData.getTooltip()); - - // Testing labelProvider - ColumnLabelProvider labelProvider = columnData.getLabelProvider(); - if (columnData.getHeader().compareTo(LEVEL_COLUMN) == 0) { - assertEquals("getColumnData", 0, labelProvider.getText(treeNode1).compareTo(treeNode1.getName())); - } else if (columnData.getHeader().compareTo(EVENTS_COUNT_COLUMN) == 0) { - // might not work because of machine local number format - assertEquals("getColumnData", "1", labelProvider.getText(treeNode1)); - } - - // Testing comparator - vComp = columnData.getComparator(); - if (columnData.getHeader().compareTo(LEVEL_COLUMN) == 0) { - assertTrue("getColumnData", vComp.compare(null, treeNode1, treeNode2) < 0); - assertTrue("getColumnData", vComp.compare(null, treeNode2, treeNode1) > 0); - assertTrue("getColumnData", vComp.compare(null, treeNode1, treeNode1) == 0); - } else if (columnData.getHeader().compareTo(EVENTS_COUNT_COLUMN) == 0) { - assertTrue("getColumnData", vComp.compare(null, treeNode1, treeNode2) == 0); - assertTrue("getColumnData", vComp.compare(null, treeNode2, treeNode1) == 0); - assertTrue("getColumnData", vComp.compare(null, treeNode1, treeNode1) == 0); - } - - // Testing percentage provider - ITmfColumnPercentageProvider percentProvider = columnData.getPercentageProvider(); - if (columnData.getHeader().compareTo(LEVEL_COLUMN) == 0) { - assertNull("getColumnData", percentProvider); - } else if (columnData.getHeader().compareTo(EVENTS_COUNT_COLUMN) == 0) { - double percentage = (double) treeNode1.getValues().getTotal() / parentNode.getValues().getTotal(); - assertEquals("getColumnData", percentage, percentProvider.getPercentage(treeNode1), DELTA); - } - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfBaseColumnDataTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfBaseColumnDataTest.java deleted file mode 100755 index 72d6b492ec..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfBaseColumnDataTest.java +++ /dev/null @@ -1,169 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial design and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.statistics; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerComparator; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfBaseColumnData; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfBaseColumnData.ITmfColumnPercentageProvider; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTree; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.ui.ISharedImages; -import org.eclipse.ui.PlatformUI; -import org.junit.Before; -import org.junit.Test; - -/** - * TmfBaseColumnData Test Case. - */ -public class TmfBaseColumnDataTest { - - // ------------------------------------------------------------------------ - // Fields - // ------------------------------------------------------------------------ - - private int fAlignment; - private int fWidth; - private String fHeader; - private String fToolTip; - private ColumnLabelProvider fLabelProvider; - private ViewerComparator fComparator; - private ITmfColumnPercentageProvider fPercentageProvider; - private TmfStatisticsTreeNode fTreeNode; - private String fTraceName; - private TmfBaseColumnData fBaseColumnData; - - // ------------------------------------------------------------------------ - // Housekeeping - // ------------------------------------------------------------------------ - - /** - * Pre-test setup - */ - @Before - public void init() { - fHeader = "test Column1"; - fWidth = 300; - fAlignment = SWT.LEFT; - fToolTip = "Tooltip " + fHeader; - fLabelProvider = new ColumnLabelProvider() { - @Override - public String getText(Object element) { - return ((TmfStatisticsTreeNode) element).getName(); - } - - @Override - public Image getImage(Object element) { - return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT); - } - }; - fComparator = new ViewerComparator() { - @Override - public int compare(Viewer viewer, Object e1, Object e2) { - TmfStatisticsTreeNode n1 = (TmfStatisticsTreeNode) e1; - TmfStatisticsTreeNode n2 = (TmfStatisticsTreeNode) e2; - - return n1.getName().compareTo(n2.getName()); - } - }; - fPercentageProvider = new ITmfColumnPercentageProvider() { - @Override - public double getPercentage(TmfStatisticsTreeNode node) { - TmfStatisticsTreeNode parent = node; - do { - parent = parent.getParent(); - } while (parent != null && parent.getValues().getTotal() == 0); - - if (parent == null) { - return 0; - } - return (double) node.getValues().getTotal() / parent.getValues().getTotal(); - } - }; - - TmfStatisticsTree baseData = new TmfStatisticsTree(); - fTraceName = "trace1"; - fTreeNode = new TmfStatisticsTreeNode(baseData, baseData.getRootNode(), fTraceName); - - fBaseColumnData = new TmfBaseColumnData(fHeader, fWidth, fAlignment, fToolTip, fLabelProvider, fComparator, fPercentageProvider); - } - - // ------------------------------------------------------------------------ - // Test methods - // ------------------------------------------------------------------------ - - /** - * Test get header - */ - @Test - public void testGetHeader() { - assertEquals("getHeader", 0, fBaseColumnData.getHeader().compareTo(fHeader)); - } - - /** - * Test getting of column width. - */ - @Test - public void testGetWidth() { - assertEquals("getWidth", fWidth, fBaseColumnData.getWidth()); - } - - /** - * Test getting of alignment value - */ - @Test - public void testGetAlignment() { - assertEquals("getAlignment", fAlignment, fBaseColumnData.getAlignment()); - } - - /** - * Test getting of tooltip. - */ - @Test - public void testGetTooltip() { - assertEquals("getTooltip", fToolTip, fBaseColumnData.getTooltip()); - } - - /** - * Test getting of label provider - */ - @Test - public void testGetLabelProvider() { - assertEquals("getLabelProvider", 0, fBaseColumnData.getLabelProvider().getText(fTreeNode).compareTo(fLabelProvider.getText(fTreeNode))); - assertTrue("getLabelProvider", fBaseColumnData.getLabelProvider().getImage(fTreeNode).equals(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT))); - assertTrue("getLabelProvider", fBaseColumnData.getLabelProvider().equals(fLabelProvider)); - } - - /** - * Test getting of comparator. - */ - @Test - public void testGetComparator() { - assertTrue("getComparator", fBaseColumnData.getComparator().equals(fComparator)); - } - - /** - * Test getting of percentage provider. - */ - @Test - public void testGetPercentageProvider() { - assertTrue("getPercentageProvider", fBaseColumnData.getPercentageProvider().equals(fPercentageProvider)); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfBaseStatisticsDataTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfBaseStatisticsDataTest.java deleted file mode 100755 index c00ed83053..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfBaseStatisticsDataTest.java +++ /dev/null @@ -1,238 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial design and implementation - * Bernd Hufmann - Fixed warnings - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.statistics; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import java.util.Vector; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.Messages; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTree; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode; -import org.junit.Test; - -/** - * TmfBaseStatistics Test Cases. - */ -public class TmfBaseStatisticsDataTest { - - // ------------------------------------------------------------------------ - // Fields - // ------------------------------------------------------------------------ - - private static final String fTestName = "StatisticsDataTest"; - - private final String fContext = "UnitTest"; - private final String fTypeId1 = "Some type1"; - private final String fTypeId2 = "Some type2"; - - private final String fLabel0 = "label1"; - private final String fLabel1 = "label2"; - private final String fLabel2 = "label3"; - private final String[] fLabels = new String[] { fLabel0, fLabel1, fLabel2 }; - - private final TmfTimestamp fTimestamp1 = new TmfTimestamp(12345, (byte) 2, 5); - private final TmfTimestamp fTimestamp2 = new TmfTimestamp(12350, (byte) 2, 5); - private final TmfTimestamp fTimestamp3 = new TmfTimestamp(12355, (byte) 2, 5); - - private final String fSource = "Source"; - - private final TmfEventType fType1 = new TmfEventType(fContext, fTypeId1, TmfEventField.makeRoot(fLabels)); - private final TmfEventType fType2 = new TmfEventType(fContext, fTypeId1, TmfEventField.makeRoot(fLabels)); - private final TmfEventType fType3 = new TmfEventType(fContext, fTypeId2, TmfEventField.makeRoot(fLabels)); - - private final String fReference = "Some reference"; - - private final ITmfEvent fEvent1; - private final ITmfEvent fEvent2; - private final ITmfEvent fEvent3; - - private final TmfEventField fContent1; - private final TmfEventField fContent2; - private final TmfEventField fContent3; - - private final TmfStatisticsTree fStatsTree; - - // ------------------------------------------------------------------------ - // Housekeeping - // ------------------------------------------------------------------------ - - /** - * Constructor - */ - public TmfBaseStatisticsDataTest() { - fContent1 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some content", null); - fEvent1 = new TmfEvent(null, fTimestamp1, fSource, fType1, fContent1, fReference); - - fContent2 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some other content", null); - fEvent2 = new TmfEvent(null, fTimestamp2, fSource, fType2, fContent2, fReference); - - fContent3 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some other different content", null); - fEvent3 = new TmfEvent(null, fTimestamp3, fSource, fType3, fContent3, fReference); - - fStatsTree = new TmfStatisticsTree(); - - fStatsTree.setTotal(fTestName, true, 3); - fStatsTree.setTypeCount(fTestName, fEvent1.getType().getName(), true, 1); - fStatsTree.setTypeCount(fTestName, fEvent2.getType().getName(), true, 1); - fStatsTree.setTypeCount(fTestName, fEvent3.getType().getName(), true, 1); - } - - // ------------------------------------------------------------------------ - // Test methods - // ------------------------------------------------------------------------ - - /** - * Test getting of children. - */ - @Test - public void testGetChildren() { - // Getting children of the ROOT - Collection childrenTreeNode = fStatsTree.getRootNode().getChildren(); - assertEquals("getChildren", 1, childrenTreeNode.size()); - TmfStatisticsTreeNode treeNode = childrenTreeNode.iterator().next(); - assertEquals("getChildren", fTestName, treeNode.getName()); - - // Getting children of the trace - childrenTreeNode = fStatsTree.getNode(fTestName).getChildren(); - assertEquals("getChildren", 1, childrenTreeNode.size()); - treeNode = childrenTreeNode.iterator().next(); - assertEquals("getChildren", Messages.TmfStatisticsData_EventTypes, treeNode.getName()); - - Vector keyExpected = new Vector<>(); - keyExpected.add(fEvent1.getType().getName()); - keyExpected.add(fEvent3.getType().getName()); - // Getting children of a category - childrenTreeNode = treeNode.getChildren(); - assertEquals("getChildren", 2, childrenTreeNode.size()); - - Iterator iterChild = childrenTreeNode.iterator(); - TmfStatisticsTreeNode temp; - while (iterChild.hasNext()) { - temp = iterChild.next(); - assertEquals(0, temp.getChildren().size()); - if (keyExpected.contains(temp.getName())) { - keyExpected.removeElement(temp.getName()); - } else { - fail(); - } - } - - // Get children of a specific event type - childrenTreeNode = childrenTreeNode.iterator().next().getChildren(); - assertEquals("getChildren", 0, childrenTreeNode.size()); - } - - /** - * Test registering of events. - */ - @Test - public void testRegisterEvent() { - TmfStatisticsTreeNode trace = fStatsTree.getNode(fTestName); - assertEquals("registerEvent", 3, trace.getValues().getTotal()); - - Collection childrenTreeNode = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes).getChildren(); - for (TmfStatisticsTreeNode child : childrenTreeNode) { - if (child.getName().compareTo(fEvent1.getType().getName()) == 0) { - assertEquals("registerEvent", 1, child.getValues().getTotal()); - } else if (child.getName().compareTo(fEvent3.getType().getName()) == 0) { - assertEquals("registerEvent", 1, child.getValues().getTotal()); - } - } - } - - /** - * Test getter. - */ - @Test - public void testGet() { - TmfStatisticsTreeNode traceRoot = fStatsTree.getNode(fTestName); - assertNotNull("get", traceRoot); - assertEquals("get", 0, traceRoot.getPath()[0].compareTo(fTestName)); - assertEquals("get", 3, traceRoot.getValues().getTotal()); - assertEquals("get", 1, traceRoot.getNbChildren()); - } - - /** - * Test getting or creating of node entries. - */ - @Test - public void testGetOrCreate() { - String[] newEventType = new String[] { fTestName, Messages.TmfStatisticsData_EventTypes, "Fancy Type" }; - TmfStatisticsTreeNode newEventTypeNode; - - // newEventType is not in the tree - newEventTypeNode = fStatsTree.getNode(newEventType); - assertNull(newEventTypeNode); - - newEventTypeNode = fStatsTree.getOrCreateNode(newEventType); - assertNotNull(newEventTypeNode); - assertTrue(Arrays.equals(newEventType, newEventTypeNode.getPath())); - - // newEventType is in the tree - newEventTypeNode.reset(); - newEventTypeNode = fStatsTree.getNode(newEventType); - assertNotNull(newEventTypeNode); - - newEventTypeNode = fStatsTree.getOrCreateNode(newEventType); - assertNotNull(newEventTypeNode); - assertTrue(Arrays.equals(newEventType, newEventTypeNode.getPath())); - } - - /** - * Test getting of parent node. - */ - @Test - public void testGetParent() { - TmfStatisticsTreeNode parentNode = fStatsTree.getRootNode().getParent(); - assertNull(parentNode); - - parentNode = fStatsTree.getNode(fTestName).getParent(); - assertNotNull(parentNode); - assertEquals(parentNode.getPath().toString(), fStatsTree.getRootNode().getPath().toString()); - - parentNode = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes).getParent(); - assertNotNull(parentNode); - assertEquals(parentNode.getPath().toString(), fStatsTree.getNode(fTestName).getPath().toString()); - } - - /** - * Test reset method - */ - @Test - public void testReset() { - fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes).reset(); - - assertEquals(0, fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes).getChildren().size()); - assertNull(fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fType1.getName())); - assertNull(fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fType3.getName())); - - fStatsTree.getNode(fTestName).reset(); - assertEquals(0, fStatsTree.getNode(fTestName).getChildren().size()); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfStatisticsTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfStatisticsTest.java deleted file mode 100644 index 6ab9f57a48..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfStatisticsTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.statistics; - -import static org.junit.Assert.assertEquals; - -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsValues; -import org.junit.Test; - -/** - * TmfStatistics Test Cases. - */ -public class TmfStatisticsTest { - - private TmfStatisticsValues stats = new TmfStatisticsValues(); - - /** - * Test the initial state of the counters - */ - @Test - public void testInitialState() { - assertEquals(0, stats.getTotal()); - assertEquals(0, stats.getPartial()); - } - - /** - * Test incrementing the total counter by an amount - */ - @Test - public void testSetValue() { - final int i = 100; - - /* Set the Global counter */ - stats.setValue(true, i); - assertEquals(i, stats.getTotal()); - // Try to assign a negative number. Should do nothing. - stats.setValue(true, -10); - assertEquals(i, stats.getTotal()); - // Checks if the partial counter was affected - assertEquals(0, stats.getPartial()); - - /* Set the time range counter */ - stats.resetTotalCount(); - stats.setValue(false, i); - assertEquals(i, stats.getPartial()); - // Try to assign a negative number. Should do nothing. - stats.setValue(false, -10); - assertEquals(i, stats.getPartial()); - // Checks if the total counter was affected - assertEquals(0, stats.getTotal()); - } - - /** - * Test of the reset for the total counter - */ - @Test - public void testResetTotal() { - stats.setValue(true, 123); - assertEquals(123, stats.getTotal()); - - stats.resetTotalCount(); - assertEquals(0, stats.getTotal()); - - // test when already at 0 - stats.resetTotalCount(); - assertEquals(0, stats.getTotal()); - } - - /** - * Test of the reset for the partial counter - */ - @Test - public void testResetPartial() { - stats.setValue(false, 456); - assertEquals(456, stats.getPartial()); - - stats.resetPartialCount(); - assertEquals(0, stats.getPartial()); - - // test when already at 0 - stats.resetPartialCount(); - assertEquals(0, stats.getPartial()); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfStatisticsTreeManagerTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfStatisticsTreeManagerTest.java deleted file mode 100755 index 409def230e..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfStatisticsTreeManagerTest.java +++ /dev/null @@ -1,177 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial design and implementation - * Bernd Hufmann - Fixed warnings - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.statistics; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTree; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTreeManager; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode; -import org.junit.Before; -import org.junit.Test; - -/** - * TmfStatisticsTreeRootFactory Test Case. - */ -public class TmfStatisticsTreeManagerTest { - - // ------------------------------------------------------------------------ - // Fields - // ------------------------------------------------------------------------ - - private TmfStatisticsTree fStatisticsData1; - private TmfStatisticsTree fStatisticsData2; - private TmfStatisticsTree fStatisticsData3; - private String fDataKey1 = "key1"; - private String fDataKey2 = "key2"; - private String fDataKey3 = "key3"; - - - // ------------------------------------------------------------------------ - // Housekeeping - // ------------------------------------------------------------------------ - - /** - * Initialization - */ - @Before - public void setUp() { - fStatisticsData1 = new TmfStatisticsTree(); - fStatisticsData2 = new TmfStatisticsTree(); - fStatisticsData3 = new TmfStatisticsTree(); - TmfStatisticsTreeManager.addStatsTreeRoot(fDataKey1, fStatisticsData1); - TmfStatisticsTreeManager.addStatsTreeRoot(fDataKey2, fStatisticsData2); - TmfStatisticsTreeManager.addStatsTreeRoot(fDataKey2, fStatisticsData3); - } - - /** - * Clean the statistics tree - */ - private static void removeStatsTreeRoot() { - TmfStatisticsTreeManager.removeAll(); - } - - /** - * Test adding of statistics tree root. It should not throw exceptions - */ - @Test - public void testaddStatsTreeRoot() { - removeStatsTreeRoot(); - - try { - assertNull(TmfStatisticsTreeManager.addStatsTreeRoot(null, null)); - assertNull(TmfStatisticsTreeManager.addStatsTreeRoot(null, fStatisticsData1)); - assertNull(TmfStatisticsTreeManager.addStatsTreeRoot(fDataKey1, null)); - assertNull(TmfStatisticsTreeManager.getStatTreeRoot(fDataKey1)); - - TmfStatisticsTreeNode returnRootNode = TmfStatisticsTreeManager.addStatsTreeRoot(fDataKey1, fStatisticsData1); - assertSame(fStatisticsData1, TmfStatisticsTreeManager.getStatTree(fDataKey1)); - assertSame(fStatisticsData1.getRootNode(), returnRootNode); - - // Overwriting the value - returnRootNode = TmfStatisticsTreeManager.addStatsTreeRoot(fDataKey1, fStatisticsData2); - assertSame(fStatisticsData2, TmfStatisticsTreeManager.getStatTree(fDataKey1)); - assertSame(fStatisticsData2.getRootNode(), returnRootNode); - - // Success - } catch(Exception e) { - fail("AddStatsTreeRoot"); - } - } - - // ------------------------------------------------------------------------ - // get - // ------------------------------------------------------------------------ - - /** - * Test getting of statistics tree root. - */ - @Test - public void testGetStatTreeRoot() { - TmfStatisticsTreeNode value1 = TmfStatisticsTreeManager.getStatTreeRoot(fDataKey1); - TmfStatisticsTreeNode value2 = TmfStatisticsTreeManager.getStatTreeRoot(fDataKey2); - TmfStatisticsTreeNode value3 = TmfStatisticsTreeManager.getStatTreeRoot(fDataKey1); - assertNotSame("getStatTreeRoot", value1, value2); - assertNotSame("getStatTreeRoot", value2, value3); - assertSame("getStatTreeRoot", value1, value3); - assertNull("getStatTreeRoot", TmfStatisticsTreeManager.getStatTreeRoot(null)); - } - - /** - * Test getting statistics tree. - */ - @Test - public void testGetStatTree() { - TmfStatisticsTree value1 = TmfStatisticsTreeManager.getStatTree(fDataKey1); - TmfStatisticsTree value2 = TmfStatisticsTreeManager.getStatTree(fDataKey2); - TmfStatisticsTree value3 = TmfStatisticsTreeManager.getStatTree(fDataKey1); - assertNotSame("getStatTree", value1, value2); - assertNotSame("getStatTree", value2, value3); - assertSame("getStatTree", value1, value3); - assertNull("getStatTreeRoot", TmfStatisticsTreeManager.getStatTree(null)); - } - - // ------------------------------------------------------------------------ - // contains - // ------------------------------------------------------------------------ - - /** - * Test checking for tree root existence. - */ - @Test - public void testContainsTreeRoot() { - assertTrue("containsTreeRoot", TmfStatisticsTreeManager.containsTreeRoot(fDataKey1)); - assertTrue("containsTreeRoot", TmfStatisticsTreeManager.containsTreeRoot(fDataKey2)); - assertFalse("containsTreeRoot", TmfStatisticsTreeManager.containsTreeRoot(null)); - } - - // ------------------------------------------------------------------------ - // remove - // ------------------------------------------------------------------------ - - /** - * Test removal of statistics tree node. - */ - @Test - public void testRemoveStatTreeRoot() { - TmfStatisticsTreeManager.removeStatTreeRoot(fDataKey1); - assertNull("removeStatTreeRoot", TmfStatisticsTreeManager.getStatTree(fDataKey1)); - - try { - // Trying to remove the same branch from the tree. - TmfStatisticsTreeManager.removeStatTreeRoot(fDataKey1); - - TmfStatisticsTreeManager.removeStatTreeRoot(null); - // Success - } catch (Exception e) { - fail("removeStatTreeRoot"); - } - } - - /** - * Test removal of all root nodes. - */ - @Test - public void testRemoveAll() { - TmfStatisticsTreeManager.removeAll(); - assertNull("removeAll", TmfStatisticsTreeManager.getStatTreeRoot(fDataKey2)); - assertNull("removeAll", TmfStatisticsTreeManager.getStatTreeRoot(fDataKey3)); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfStatisticsTreeNodeTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfStatisticsTreeNodeTest.java deleted file mode 100755 index dc6da20226..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfStatisticsTreeNodeTest.java +++ /dev/null @@ -1,385 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial design and implementation - * Bernd Hufmann - Fixed warnings - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.statistics; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.Collection; -import java.util.Iterator; -import java.util.Vector; - -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.Messages; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTree; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode; -import org.junit.Test; - -/** - * TmfStatisticsTreeNode Test Cases. - */ -public class TmfStatisticsTreeNodeTest { - - // ------------------------------------------------------------------------ - // Fields - // ------------------------------------------------------------------------ - - private final String fTypeId1 = "Some type1"; - private final String fTypeId2 = "Some type2"; - private final String fTypeId3 = "Some type3"; - - private final TmfStatisticsTree fStatsTree; - - private static final String fTestName = "StatisticsTreeNodeTest"; - - // ------------------------------------------------------------------------ - // Housekeeping - // ------------------------------------------------------------------------ - - /** - * Constructor - */ - public TmfStatisticsTreeNodeTest() { - fStatsTree = new TmfStatisticsTree(); - - /* Enter some global values */ - fStatsTree.setTotal(fTestName, true, 18); - fStatsTree.setTypeCount(fTestName, fTypeId1, true, 5); - fStatsTree.setTypeCount(fTestName, fTypeId2, true, 6); - fStatsTree.setTypeCount(fTestName, fTypeId3, true, 7); - - /* Enter some time range values */ - fStatsTree.setTotal(fTestName, false, 9); - fStatsTree.setTypeCount(fTestName, fTypeId1, false, 2); - fStatsTree.setTypeCount(fTestName, fTypeId2, false, 3); - fStatsTree.setTypeCount(fTestName, fTypeId3, false, 4); - } - - /** - * Test checking for child. - */ - @Test - public void testContainsChild() { - TmfStatisticsTreeNode rootNode = fStatsTree.getRootNode(); - TmfStatisticsTreeNode traceNode = fStatsTree.getNode(fTestName); - // Creates a category from the key already created - TmfStatisticsTreeNode catNode = traceNode.getChildren().iterator().next(); - - assertTrue(rootNode.containsChild(fTestName)); - assertFalse(rootNode.containsChild(catNode.getName())); - - assertTrue(traceNode.containsChild(catNode.getName())); - assertFalse(traceNode.containsChild(fTypeId1)); - - assertTrue(catNode.containsChild(fTypeId1)); - assertTrue(catNode.containsChild(fTypeId2)); - } - - /** - * Test getting of children. - */ - @Test - public void testGetChildren() { - // Getting children of the ROOT - Collection childrenTreeNode = fStatsTree.getRootNode().getChildren(); - assertEquals(1, childrenTreeNode.size()); - TmfStatisticsTreeNode treeNode = childrenTreeNode.iterator().next(); - assertEquals(fTestName, treeNode.getName()); - - // Getting children of the trace - childrenTreeNode = fStatsTree.getNode(fTestName).getChildren(); - assertEquals(1, childrenTreeNode.size()); - treeNode = childrenTreeNode.iterator().next(); - assertEquals(Messages.TmfStatisticsData_EventTypes, treeNode.getName()); - - Vector keyExpected = new Vector<>(); - keyExpected.add(fTypeId1); - keyExpected.add(fTypeId2); - keyExpected.add(fTypeId3); - // Getting children of a category - childrenTreeNode = treeNode.getChildren(); - assertEquals(3, childrenTreeNode.size()); - - Iterator iterChild = childrenTreeNode.iterator(); - TmfStatisticsTreeNode temp; - while (iterChild.hasNext()) { - temp = iterChild.next(); - if (keyExpected.contains(temp.getName())) { - keyExpected.removeElement(temp.getName()); - } else { - fail(); - } - } - - // Get children of a specific event type - childrenTreeNode = fStatsTree.getNode(childrenTreeNode.iterator().next().getPath()).getChildren(); - assertEquals(0, childrenTreeNode.size()); - } - - /** - * Test getting of number of children. - */ - @Test - public void testGetNbChildren() { - TmfStatisticsTreeNode rootNode = fStatsTree.getRootNode(); - TmfStatisticsTreeNode traceNode = fStatsTree.getNode(fTestName); - TmfStatisticsTreeNode catNode = traceNode.getChildren().iterator().next(); - TmfStatisticsTreeNode elementNode = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1); - - assertEquals(1, rootNode.getNbChildren()); - assertEquals(1, traceNode.getNbChildren()); - assertEquals(3, catNode.getNbChildren()); - assertEquals(0, elementNode.getNbChildren()); - } - - /** - * Test checking for children. - */ - @Test - public void testHasChildren() { - TmfStatisticsTreeNode rootNode = fStatsTree.getRootNode(); - TmfStatisticsTreeNode traceNode = fStatsTree.getNode(fTestName); - TmfStatisticsTreeNode catNode = traceNode.getChildren().iterator().next(); - TmfStatisticsTreeNode elementNode = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1); - - assertTrue(rootNode.hasChildren()); - assertTrue(traceNode.hasChildren()); - assertTrue(catNode.hasChildren()); - assertFalse(elementNode.hasChildren()); - } - - /** - * Test getting of parent. - */ - @Test - public void testGetParent() { - final TmfStatisticsTreeNode rootNode = fStatsTree.getRootNode(); - TmfStatisticsTreeNode parentNode = rootNode.getParent(); - assertNull(parentNode); - - TmfStatisticsTreeNode newTraceNode = new TmfStatisticsTreeNode(fStatsTree, rootNode, "newly created trace node"); - parentNode = newTraceNode.getParent(); - assertNotNull(parentNode); - assertTrue(fStatsTree.getRootNode() == parentNode); - - TmfStatisticsTreeNode traceNode = fStatsTree.getNode(fTestName); - parentNode = traceNode.getParent(); - assertNotNull(parentNode); - assertTrue(rootNode == parentNode); - - TmfStatisticsTreeNode elementNode = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1); - parentNode = elementNode.getParent(); - assertTrue(parentNode == fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes)); - - TmfStatisticsTreeNode catNode = traceNode.getChildren().iterator().next(); - parentNode = catNode.getParent(); - assertNotNull(parentNode); - assertTrue(parentNode == fStatsTree.getNode(fTestName)); - - parentNode = elementNode.getParent(); - assertNotNull(parentNode); - assertTrue(arraysEqual(parentNode.getPath(), fTestName, Messages.TmfStatisticsData_EventTypes)); - } - - /** - * Test getting of key. - */ - @Test - public void testgetName() { - TmfStatisticsTreeNode rootNode = fStatsTree.getRootNode(); - TmfStatisticsTreeNode traceNode = fStatsTree.getNode(fTestName); - TmfStatisticsTreeNode catNode = traceNode.getChildren().iterator().next(); - TmfStatisticsTreeNode elementNode = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1); - - assertEquals(0, rootNode.getName().compareTo("root")); - assertEquals(0, traceNode.getName().compareTo(fTestName)); - assertEquals(0, catNode.getName().compareTo(Messages.TmfStatisticsData_EventTypes)); - assertEquals(0, elementNode.getName().compareTo(fTypeId1)); - } - - /** - * Test getting of path to node. - */ - @Test - public void testGetPath() { - TmfStatisticsTreeNode rootNode = fStatsTree.getRootNode(); - TmfStatisticsTreeNode traceNode = fStatsTree.getNode(fTestName); - TmfStatisticsTreeNode catNode = traceNode.getChildren().iterator().next(); - TmfStatisticsTreeNode elementNode = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1); - - assertEquals(0, rootNode.getPath().length); /* Root node has an empty path */ - assertTrue(arraysEqual(traceNode.getPath(), fTestName)); - assertTrue(arraysEqual(catNode.getPath(), - fTestName, Messages.TmfStatisticsData_EventTypes)); - assertTrue(arraysEqual(elementNode.getPath(), - fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1)); - } - - /** - * Test getting statistic value. - */ - @Test - public void testGetValue() { - TmfStatisticsTreeNode rootNode, traceNode, catNode, elementNode1, elementNode2, elementNode3; - rootNode = fStatsTree.getRootNode(); - traceNode = fStatsTree.getNode(fTestName); - catNode = traceNode.getChildren().iterator().next(); - elementNode1 = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1); - elementNode2 = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId2); - elementNode3 = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId3); - - assertEquals(0, rootNode.getValues().getTotal()); - assertEquals(18, traceNode.getValues().getTotal()); - assertEquals(0, catNode.getValues().getTotal()); - assertEquals(5, elementNode1.getValues().getTotal()); - assertEquals(6, elementNode2.getValues().getTotal()); - assertEquals(7, elementNode3.getValues().getTotal()); - - assertEquals(0, rootNode.getValues().getPartial()); - assertEquals(9, traceNode.getValues().getPartial()); - assertEquals(0, catNode.getValues().getPartial()); - assertEquals(2, elementNode1.getValues().getPartial()); - assertEquals(3, elementNode2.getValues().getPartial()); - assertEquals(4, elementNode3.getValues().getPartial()); - } - - /** - * Test reset of tree. - */ - @Test - public void testReset() { - TmfStatisticsTreeNode rootNode, traceNode, catNode, elementNode; - rootNode = fStatsTree.getRootNode(); - traceNode = fStatsTree.getNode(fTestName); - catNode = traceNode.getChildren().iterator().next(); - elementNode = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1); - - elementNode.reset(); - assertEquals(0, elementNode.getValues().getTotal()); - assertEquals(0, elementNode.getValues().getPartial()); - - catNode.reset(); - assertEquals(0, catNode.getValues().getTotal()); - assertEquals(0, catNode.getValues().getPartial()); - assertEquals(0, catNode.getNbChildren()); - assertNull(fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1)); - - traceNode.reset(); - assertEquals(0, traceNode.getValues().getTotal()); - assertEquals(0, traceNode.getValues().getPartial()); - assertEquals(0, traceNode.getNbChildren()); - - rootNode.reset(); - assertEquals(0, rootNode.getValues().getTotal()); - assertEquals(0, rootNode.getValues().getPartial()); - assertEquals(0, rootNode.getNbChildren()); - } - - /** - * Test reset global value of the node in the tree. It should only clear - * the global value without removing any node from the tree. - */ - @Test - public void testResetGlobalValue() { - TmfStatisticsTreeNode rootNode, traceNode, catNode, eventTypeNode1, eventTypeNode2, eventTypeNode3; - rootNode = fStatsTree.getRootNode(); - traceNode = fStatsTree.getNode(fTestName); - catNode = traceNode.getChildren().iterator().next(); - eventTypeNode1 = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1); - eventTypeNode2 = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId2); - eventTypeNode3 = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId3); - - rootNode.resetGlobalValue(); - - assertEquals(0, rootNode.getValues().getTotal()); - assertEquals(0, traceNode.getValues().getTotal()); - assertEquals(0, catNode.getValues().getTotal()); - assertEquals(0, eventTypeNode1.getValues().getTotal()); - assertEquals(0, eventTypeNode2.getValues().getTotal()); - assertEquals(0, eventTypeNode3.getValues().getTotal()); - - // Checks the state of the statistics tree - Collection rootChildren = rootNode.getChildren(); - assertEquals(1, rootChildren.size()); - assertTrue(rootChildren.contains(traceNode)); - - Collection traceChildren = traceNode.getChildren(); - assertEquals(1, traceChildren.size()); - assertTrue(traceChildren.contains(catNode)); - - Collection catChildren = catNode.getChildren(); - assertEquals(3, catChildren.size()); - assertTrue(catChildren.contains(eventTypeNode1)); - assertTrue(catChildren.contains(eventTypeNode2)); - assertTrue(catChildren.contains(eventTypeNode3)); - } - - /** - * Test reset time range value of the node in the tree. It should only clear - * the time range value without removing any node from the tree. - */ - @Test - public void testResetTimeRangeValue() { - TmfStatisticsTreeNode rootNode, traceNode, catNode, eventTypeNode1, eventTypeNode2, eventTypeNode3; - rootNode = fStatsTree.getRootNode(); - traceNode = fStatsTree.getNode(fTestName); - catNode = traceNode.getChildren().iterator().next(); - eventTypeNode1 = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1); - eventTypeNode2 = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId2); - eventTypeNode3 = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId3); - - rootNode.resetTimeRangeValue(); - - assertEquals(0, rootNode.getValues().getPartial()); - assertEquals(0, traceNode.getValues().getPartial()); - assertEquals(0, catNode.getValues().getPartial()); - assertEquals(0, eventTypeNode1.getValues().getPartial()); - assertEquals(0, eventTypeNode2.getValues().getPartial()); - - // Checks the state of the statistics tree - Collection rootChildren = rootNode.getChildren(); - assertEquals(1, rootChildren.size()); - assertTrue(rootChildren.contains(traceNode)); - - Collection traceChildren = traceNode.getChildren(); - assertEquals(1, traceChildren.size()); - assertTrue(traceChildren.contains(catNode)); - - Collection catChildren = catNode.getChildren(); - assertEquals(3, catChildren.size()); - assertTrue(catChildren.contains(eventTypeNode1)); - assertTrue(catChildren.contains(eventTypeNode2)); - assertTrue(catChildren.contains(eventTypeNode3)); - } - - /** - * Check if two String arrays are equals, by comparing their contents. - * Unlike Arrays.equals(), we can use varargs for the second argument. - */ - private static boolean arraysEqual(String[] array1, String... array2) { - if (array1.length != array2.length) { - return false; - } - for (int i = 0; i < array1.length; i++) { - if (!array1[i].equals(array2[i])) { - return false; - } - } - return true; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfTreeContentProviderTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfTreeContentProviderTest.java deleted file mode 100755 index 96eb0d67da..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/statistics/TmfTreeContentProviderTest.java +++ /dev/null @@ -1,187 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial design and implementation - * Bernd Hufmann - Fixed warnings - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.statistics; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.Arrays; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.Messages; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTree; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfTreeContentProvider; -import org.junit.Test; - -/** - * TmfTreeContentProvider Test Cases. - */ -public class TmfTreeContentProviderTest { - - // ------------------------------------------------------------------------ - // Fields - // ------------------------------------------------------------------------ - - private static final String fTestName = "TreeContentProviderTest"; - - private final String fContext = "UnitTest"; - private final String fTypeId1 = "Some type1"; - private final String fTypeId2 = "Some type2"; - - private final String fLabel0 = "label1"; - private final String fLabel1 = "label2"; - private final String[] fLabels = new String[] { fLabel0, fLabel1 }; - - private final TmfTimestamp fTimestamp1 = new TmfTimestamp(12345, (byte) 2, 5); - private final TmfTimestamp fTimestamp2 = new TmfTimestamp(12350, (byte) 2, 5); - - private final String fSource = "Source"; - - private final TmfEventType fType1 = new TmfEventType(fContext, fTypeId1, TmfEventField.makeRoot(fLabels)); - private final TmfEventType fType2 = new TmfEventType(fContext, fTypeId2, TmfEventField.makeRoot(fLabels)); - - private final String fReference = "Some reference"; - - private final ITmfEvent fEvent1; - private final ITmfEvent fEvent2; - - private final TmfEventField fContent1; - private final TmfEventField fContent2; - - private final TmfStatisticsTree fStatsData; - - private final TmfTreeContentProvider treeProvider; - - // ------------------------------------------------------------------------ - // Housekeeping - // ------------------------------------------------------------------------ - - /** - * Constructor - */ - public TmfTreeContentProviderTest() { - fContent1 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some content", null); - fEvent1 = new TmfEvent(null, fTimestamp1, fSource, fType1, fContent1, fReference); - - fContent2 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some other content", null); - fEvent2 = new TmfEvent(null, fTimestamp2, fSource, fType2, fContent2, fReference); - - fStatsData = new TmfStatisticsTree(); - - fStatsData.setTotal(fTestName, true, 2); - fStatsData.setTypeCount(fTestName, fEvent1.getType().getName(), true, 1); - fStatsData.setTypeCount(fTestName, fEvent2.getType().getName(), true, 1); - - treeProvider = new TmfTreeContentProvider(); - } - - // ------------------------------------------------------------------------ - // Test methods - // ------------------------------------------------------------------------ - - /** - * Test getting of children. - * FIXME this test was quickly adapted when we removed the TmfFixedArray, - * but it could be rewritten to be much more simple... - */ - @Test - public void testGetChildren() { - Object[] objectArray = treeProvider.getChildren(fStatsData.getOrCreateNode(fTestName, Messages.TmfStatisticsData_EventTypes)); - TmfStatisticsTreeNode[] childrenNode = Arrays.asList(objectArray).toArray(new TmfStatisticsTreeNode[0]); - - String[][] childrenExpected = new String[][] { - new String[] { fTestName, Messages.TmfStatisticsData_EventTypes, fEvent1.getType().getName() }, - new String[] { fTestName, Messages.TmfStatisticsData_EventTypes, fEvent2.getType().getName() } - }; - - assertEquals("getChildren", childrenExpected.length, childrenNode.length); - // assertTrue("getChildren", childrenPath.equals(childrenExpected)); - for (TmfStatisticsTreeNode childNode : childrenNode) { - if (!arrayOfArraysContains(childrenExpected, childNode.getPath())) { - fail(); - } - } - } - - private static boolean arrayOfArraysContains(String[][] arrayOfArrays, String[] array) { - for (String[] curArray : arrayOfArrays) { - if (arraysEqual(curArray, array)) { - return true; - } - } - return false; - } - - private static boolean arraysEqual(String[] array1, String[] array2) { - if (array1.length != array2.length) { - return false; - } - for (int i = 0; i < array1.length; i++) { - if (!array1[i].equals(array2[i])) { - return false; - } - } - return true; - } - - /** - * Test getting of parent. - */ - @Test - public void testGetParent() { - TmfStatisticsTreeNode parent = (TmfStatisticsTreeNode) treeProvider.getParent(fStatsData.getNode(fTestName)); - - assertNotNull("getParent", parent); - assertTrue("getParent", parent.getPath().equals(fStatsData.getRootNode().getPath())); - } - - /** - * Test checking for children. - */ - @Test - public void testHasChildren() { - boolean hasChildren = treeProvider.hasChildren(fStatsData.getRootNode()); - assertTrue("hasChildren", hasChildren); - - hasChildren = treeProvider.hasChildren(fStatsData.getOrCreateNode(fTestName)); - assertTrue("hasChildren", hasChildren); - - hasChildren = treeProvider.hasChildren(fStatsData.getOrCreateNode(fTestName, Messages.TmfStatisticsData_EventTypes)); - assertTrue("hasChildren", hasChildren); - - hasChildren = treeProvider.hasChildren(fStatsData.getOrCreateNode(fTestName, Messages.TmfStatisticsData_EventTypes, fEvent1.getType().getName())); - assertFalse("hasChildren", hasChildren); - } - - /** - * Test getting of elements. - */ - @Test - public void testGetElements() { - Object[] objectElements = treeProvider.getElements(fStatsData.getRootNode()); - TmfStatisticsTreeNode[] nodeElements = Arrays.asList(objectElements).toArray(new TmfStatisticsTreeNode[0]); - assertEquals("getElements", 1, nodeElements.length); - assertTrue("getElements", nodeElements[0].getPath()[0].equals(fTestName)); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/AbstractCustomTraceIndexTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/AbstractCustomTraceIndexTest.java deleted file mode 100644 index da8138a2b7..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/AbstractCustomTraceIndexTest.java +++ /dev/null @@ -1,191 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.trace; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.File; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfContext; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.core.trace.indexer.TmfBTreeTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Common test code for custom trace indexes - * - * @author Marc-Andre Laperle - */ -public abstract class AbstractCustomTraceIndexTest { - - /** - * Time format use for event creation - */ - protected static final String TIMESTAMP_FORMAT = "dd/MM/yyyy HH:mm:ss:SSS"; - /** - * Block size used for the indexer - */ - protected static final int BLOCK_SIZE = 100; - /** - * The total number of events in the generated trace - */ - protected static final int NB_EVENTS = 10000; - private TestTrace fTrace = null; - - /** - * A common test indexer for custom trace index tests - */ - protected static class TestIndexer extends TmfBTreeTraceIndexer { - - /** - * Constructs a new test indexer - * - * @param trace the trace - * @param interval the checkpoint interval - */ - public TestIndexer(ITmfTrace trace, int interval) { - super(trace, interval); - } - - /** - * Get the index - * - * @return the index - */ - public ITmfCheckpointIndex getCheckpoints() { - return getTraceIndex(); - } - } - - interface TestTrace extends ITmfTrace { - TestIndexer getIndexer(); - } - - /** - * Setup the test - * - * @throws Exception when error occurs - */ - @Before - public void setUp() throws Exception { - setupTrace(); - } - - private synchronized void setupTrace() throws Exception { - File traceDirectory = new File(getTraceDirectory()); - if (traceDirectory.exists()) { - traceDirectory.delete(); - } - traceDirectory.mkdir(); - if (fTrace == null) { - fTrace = createTrace(); - fTrace.indexTrace(true); - } - } - - /** - * Create a test trace, varies between tests - * - * @return the test trace - * @throws Exception when error occurs - */ - abstract protected TestTrace createTrace() throws Exception; - /** - * Return the trace directory for the generated trace - * - * @return the trace directory for the generated trace - */ - abstract protected String getTraceDirectory(); - - /** - * Tear down the test - */ - @After - public void tearDown() { - String directory = TmfTraceManager.getSupplementaryFileDir(fTrace); - try { - fTrace.dispose(); - fTrace = null; - } finally { - File dir = new File(directory); - if (dir.exists()) { - File[] files = dir.listFiles(); - for (File file : files) { - file.delete(); - } - dir.delete(); - } - - File trace = new File(getTraceDirectory()); - if (trace.exists()) { - trace.delete(); - } - } - - } - - /** - * Test the content of the index after building the full index - */ - @Test - public void testTmfTraceIndexing() { - verifyIndexContent(); - } - - private void verifyIndexContent() { - assertEquals("getCacheSize", BLOCK_SIZE, fTrace.getCacheSize()); - assertEquals("getTraceSize", NB_EVENTS, fTrace.getNbEvents()); - assertEquals("getRange-start", 0, fTrace.getTimeRange().getStartTime().getValue()); - assertEquals("getRange-end", NB_EVENTS - 1, fTrace.getTimeRange().getEndTime().getValue()); - assertEquals("getStartTime", 0, fTrace.getStartTime().getValue()); - assertEquals("getEndTime", NB_EVENTS - 1, fTrace.getEndTime().getValue()); - - ITmfCheckpointIndex checkpoints = fTrace.getIndexer().getCheckpoints(); - int pageSize = fTrace.getCacheSize(); - assertTrue("Checkpoints exist", checkpoints != null); - assertEquals("Checkpoints size", NB_EVENTS / BLOCK_SIZE, checkpoints.size()); - - // Validate that each checkpoint points to the right event - for (int i = 0; i < checkpoints.size(); i++) { - ITmfCheckpoint checkpoint = checkpoints.get(i); - TmfContext context = new TmfContext(checkpoint.getLocation(), i * pageSize); - ITmfEvent event = ((ITmfEventParser)fTrace).parseEvent(context); - assertTrue(context.getRank() == i * pageSize); - assertTrue((checkpoint.getTimestamp().compareTo(event.getTimestamp(), false) == 0)); - } - } - - /** - * Test that a fully built index has the same content when reloaded from disk - * - * @throws Exception when error occurs - */ - @Test - public void testReopenIndex() throws Exception { - fTrace.dispose(); - fTrace = createTrace(); - assertFalse(fTrace.getIndexer().getCheckpoints().isCreatedFromScratch()); - fTrace.indexTrace(true); - - verifyIndexContent(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/AllTests.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/AllTests.java deleted file mode 100644 index 63f07ab917..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/AllTests.java +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.trace; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite for custom parsers - * @author Matthew Khouzam - * - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - CustomXmlTraceInvalidTest.class, - CustomXmlTraceBadlyFormedTest.class, - CustomXmlTraceValidTest.class, - CustomXmlIndexTest.class, - CustomTxtIndexTest.class -}) -public class AllTests { -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomTxtIndexTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomTxtIndexTest.java deleted file mode 100644 index ef29108817..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomTxtIndexTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Adapted for TMF Trace Model 1.0 - * Alexandre Montplaisir - Port to JUnit4 - * Marc-Andre Laperle - Adapted to CustomTxtTrace - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.trace; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTrace; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTraceDefinition; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer; - -/** - * Test suite for indexing using a CustomTxtTrace. - * - * @author Marc-Andre Laperle - */ -public class CustomTxtIndexTest extends AbstractCustomTraceIndexTest { - - private static final String TRACE_DIRECTORY = TmfTraceManager.getTemporaryDirPath() + File.separator + "dummyTxtTrace"; - private static final String TRACE_PATH = TRACE_DIRECTORY + File.separator + "test.txt"; - private static final String DEFINITION_PATH = "tracesets" + File.separator + "txt" + File.separator + "testTxtDefinition.xml"; - - private static CustomTxtTraceDefinition createDefinition() { - CustomTxtTraceDefinition[] definitions = CustomTxtTraceDefinition.loadAll(new File(DEFINITION_PATH).toString()); - return definitions[0]; - } - - @Override - protected String getTraceDirectory() { - return TRACE_DIRECTORY; - } - - @Override - protected TestTrace createTrace() throws Exception { - CustomTxtTraceDefinition definition = createDefinition(); - final File file = new File(TRACE_PATH); - try (BufferedWriter writer = new BufferedWriter(new FileWriter(file));) { - for (int i = 0; i < NB_EVENTS; ++i) { - SimpleDateFormat f = new SimpleDateFormat(TIMESTAMP_FORMAT); - String eventStr = f.format(new Date(i)) + " hello world\n"; - writer.write(eventStr); - } - } - - return new TestTxtTrace(file.toString(), definition, BLOCK_SIZE); - } - - private class TestTxtTrace extends CustomTxtTrace implements TestTrace { - public TestTxtTrace(String path, CustomTxtTraceDefinition createDefinition, int blockSize) throws TmfTraceException { - super(null, createDefinition, path, blockSize); - } - - @Override - protected ITmfTraceIndexer createIndexer(int interval) { - return new TestIndexer(this, interval); - } - - @Override - public TestIndexer getIndexer() { - return (TestIndexer) super.getIndexer(); - } - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlIndexTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlIndexTest.java deleted file mode 100644 index bc1edebb8a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlIndexTest.java +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Adapted for TMF Trace Model 1.0 - * Alexandre Montplaisir - Port to JUnit4 - * Marc-Andre Laperle - Adapted to CustomXmlTrace - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.trace; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTrace; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer; - -/** - * Test suite for indexing using a CustomXmlTrace. - * - * @author Marc-Andre Laperle - */ -public class CustomXmlIndexTest extends AbstractCustomTraceIndexTest { - - private static final String TRACE_DIRECTORY = TmfTraceManager.getTemporaryDirPath() + File.separator + "dummyXmlTrace"; - private static final String TRACE_PATH = TRACE_DIRECTORY + File.separator + "test.xml"; - private static final String DEFINITION_PATH = "tracesets" + File.separator + "xml" + File.separator + "testDefinition.xml"; - - private static CustomXmlTraceDefinition createDefinition() { - CustomXmlTraceDefinition[] definitions = CustomXmlTraceDefinition.loadAll(new File(DEFINITION_PATH).toString()); - return definitions[0]; - } - - @Override - protected String getTraceDirectory() { - return TRACE_DIRECTORY; - } - - @Override - protected TestTrace createTrace() throws Exception { - CustomXmlTraceDefinition definition = createDefinition(); - final File file = new File(TRACE_PATH); - try (BufferedWriter writer = new BufferedWriter(new FileWriter(file));) { - writer.write(""); - for (int i = 0; i < NB_EVENTS; ++i) { - SimpleDateFormat f = new SimpleDateFormat(TIMESTAMP_FORMAT); - String eventStr = "message\n"; - writer.write(eventStr); - } - writer.write(""); - } - - return new TestXmlTrace(file.toString(), definition, BLOCK_SIZE); - } - - private class TestXmlTrace extends CustomXmlTrace implements TestTrace { - public TestXmlTrace(String path, CustomXmlTraceDefinition createDefinition, int blockSize) throws TmfTraceException { - super(null, createDefinition, path, blockSize); - } - - @Override - protected ITmfTraceIndexer createIndexer(int interval) { - return new TestIndexer(this, interval); - } - - @Override - public TestIndexer getIndexer() { - return (TestIndexer) super.getIndexer(); - } - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlTraceBadlyFormedTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlTraceBadlyFormedTest.java deleted file mode 100644 index a5e6e71c98..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlTraceBadlyFormedTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.trace; - -import static org.junit.Assert.fail; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; - -import org.eclipse.core.runtime.IStatus; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -/** - * Malformed xml test, dangerous errors - * @author Matthew Khouzam - * - */ -@RunWith(Parameterized.class) -public class CustomXmlTraceBadlyFormedTest extends CustomXmlTraceTest { - - private final static String pathname = "tracesets/xml/malformed"; - - /** - * This should create the parameters to launch the project - * - * @return the path of the parameters - */ - @Parameters(name = "{index}: path {0}") - public static Collection getFiles() { - File[] malformedFiles = (new File(pathname)).listFiles(); - Collection params = new ArrayList<>(); - for (File f : malformedFiles) { - Object[] arr = new Object[] { f.getAbsolutePath() }; - params.add(arr); - } - return params; - } - - /** - * Test all the invalid xml files - */ - @Test - public void testBadlyFormed() { - IStatus valid = getTrace().validate(null, getPath()); - if (IStatus.ERROR != valid.getSeverity()) { - fail(valid.toString()); - } - } - - /** - * ctor - * - * @param filePath - * the path - */ - public CustomXmlTraceBadlyFormedTest(String filePath) { - this.setPath(filePath); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlTraceInvalidTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlTraceInvalidTest.java deleted file mode 100644 index f5a1209b61..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlTraceInvalidTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.trace; - -import static org.junit.Assert.fail; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; - -import org.eclipse.core.runtime.IStatus; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -/** - * Invalid Xml files, random errors - * - * @author Matthew Khouzam - * - */ -@RunWith(Parameterized.class) -public class CustomXmlTraceInvalidTest extends CustomXmlTraceTest{ - - private final static String pathname = "tracesets/xml/invalid"; - - /** - * This should create the parameters to launch the project - * - * @return the path of the parameters - */ - @Parameters(name = "{index}: path {0}") - public static Collection getFiles() { - File[] invalidFiles = (new File(pathname)).listFiles(); - Collection params = new ArrayList<>(); - for (File f : invalidFiles) { - Object[] arr = new Object[] { f.getAbsolutePath() }; - params.add(arr); - } - return params; - } - - /** - * ctor - * - * @param filePath - * the path - */ - public CustomXmlTraceInvalidTest(String filePath) { - setPath(filePath); - } - - /** - * Test all the invalid xml files - */ - @Test - public void testInvalid() { - IStatus invalid = getTrace().validate(null, getPath()); - if (IStatus.ERROR != invalid.getSeverity()) { - fail(getPath()); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlTraceTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlTraceTest.java deleted file mode 100644 index 1c40531a38..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlTraceTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.trace; - -import java.util.ArrayList; - -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTrace; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTraceDefinition.OutputColumn; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition.InputElement; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.junit.Before; - -/** - * Abstract test parent - * - * @author Matthew Khouzam - * - */ -public abstract class CustomXmlTraceTest { - private CustomXmlTraceDefinition cxtd; - /** - * The trace to use to "validate" the xml files - */ - private CustomXmlTrace t; - /** - * The path of the trace - */ - private String path; - - - /** - * set up directories - */ - @Before - public void init() { - cxtd = new CustomXmlTraceDefinition(TmfTraceType.CUSTOM_XML_CATEGORY, "test", new InputElement(), new ArrayList(), "s"); - t = new CustomXmlTrace(cxtd); - } - - - /** - * @return the trace - */ - public CustomXmlTrace getTrace() { - return t; - } - - - /** - * @return the path - */ - public String getPath() { - return path; - } - - - /** - * @param path the path to set - */ - public void setPath(String path) { - this.path = path; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlTraceValidTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlTraceValidTest.java deleted file mode 100644 index 970d66175b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/trace/CustomXmlTraceValidTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.trace; - -import static org.junit.Assert.fail; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; - -import org.eclipse.core.runtime.IStatus; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -/** - * Well formed XML - * @author Matthew Khouzam - * - */ -@RunWith(Parameterized.class) -public class CustomXmlTraceValidTest extends CustomXmlTraceTest { - - private final static String pathname = "tracesets/xml/valid"; - - - /** - * This should create the parameters to launch the project - * - * @return the path of the parameters - */ - @Parameters(name = "{index}: path {0}") - public static Collection getFiles() { - File[] validFiles = (new File(pathname)).listFiles(); - Collection params = new ArrayList<>(); - for (File f : validFiles) { - Object[] arr = new Object[] { f.getAbsolutePath() }; - params.add(arr); - } - return params; - } - - /** - * Test all the invalid xml files - */ - @Test - public void testValid() { - IStatus valid = getTrace().validate(null, getPath()); - if (IStatus.OK != valid.getSeverity()) { - fail(valid.toString()); - } - } - - /** - * ctor - * - * @param filePath - * the path - */ - public CustomXmlTraceValidTest(String filePath) { - this.setPath(filePath); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/dialogs/AllTests.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/dialogs/AllTests.java deleted file mode 100644 index f20c764c28..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/dialogs/AllTests.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.dialogs; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite of UML2SD dialog tests. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - CriteriaTest.class -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/dialogs/CriteriaTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/dialogs/CriteriaTest.java deleted file mode 100644 index c6b332332a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/dialogs/CriteriaTest.java +++ /dev/null @@ -1,304 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.dialogs; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.util.List; -import java.util.regex.Pattern; - -import org.eclipse.jface.dialogs.DialogSettings; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.Criteria; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.FilterCriteria; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDFilterProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter; -import org.junit.Test; - -/** - * Test cases to test Criteria class. - */ -public class CriteriaTest { - - /** - * Test default constructor. - */ - @Test - public void testCriteria() { - Criteria criteria = new Criteria(); - assertFalse("testCriteria", criteria.isAsyncMessageReturnSelected()); - assertFalse("testCriteria", criteria.isAsyncMessageSelected()); - assertFalse("testCriteria", criteria.isCaseSenstiveSelected()); - assertFalse("testCriteria", criteria.isLifeLineSelected()); - assertFalse("testCriteria", criteria.isStopSelected()); - assertFalse("testCriteria", criteria.isSyncMessageReturnSelected()); - assertFalse("testCriteria", criteria.isSyncMessageSelected()); - assertNull("testCriteria", criteria.getExpression()); - assertNull("testCriteria", criteria.getPattern()); - } - - /** - * Test copy constructor. - */ - @Test - public void testCriteriaCriteria() { - Criteria criteria = new Criteria(); - criteria.setExpression("test"); - criteria.setLifeLineSelected(true); - criteria.setSyncMessageSelected(true); - - Criteria copy = new Criteria(criteria); - - assertEquals("testCriteriaCriteria", criteria.isAsyncMessageReturnSelected(), copy.isAsyncMessageReturnSelected()); - assertEquals("testCriteriaCriteria", criteria.isAsyncMessageSelected(), copy.isAsyncMessageSelected()); - assertEquals("testCriteriaCriteria", criteria.isCaseSenstiveSelected(), copy.isCaseSenstiveSelected()); - assertEquals("testCriteriaCriteria", criteria.isLifeLineSelected(), copy.isLifeLineSelected()); - assertEquals("testCriteriaCriteria", criteria.isStopSelected(), copy.isStopSelected()); - assertEquals("testCriteriaCriteria", criteria.isSyncMessageReturnSelected(), copy.isSyncMessageReturnSelected()); - assertEquals("testCriteriaCriteria", criteria.isSyncMessageSelected(), copy.isSyncMessageSelected()); - assertEquals("testCriteriaCriteria", criteria.getExpression(), copy.getExpression()); - assertEquals("testCriteriaCriteria", criteria.getPattern().pattern(), copy.getPattern().pattern()); - } - - /** - * Test accessor methods. - */ - @Test - public void testAccessors() { - Criteria criteria = new Criteria(); - criteria.setAsyncMessageReturnSelected(true); - criteria.setAsyncMessageSelected(true); - criteria.setCaseSenstiveSelected(true); - criteria.setLifeLineSelected(true); - criteria.setStopSelected(true); - criteria.setSyncMessageReturnSelected(true); - criteria.setSyncMessageSelected(true); - criteria.setExpression("test.*"); - - // set true to all flags - assertTrue("testAccessors", criteria.isAsyncMessageReturnSelected()); - assertTrue("testAccessors", criteria.isAsyncMessageSelected()); - assertTrue("testAccessors", criteria.isCaseSenstiveSelected()); - assertTrue("testAccessors", criteria.isLifeLineSelected()); - assertTrue("testAccessors", criteria.isStopSelected()); - assertTrue("testAccessors", criteria.isSyncMessageReturnSelected()); - assertTrue("testAccessors", criteria.isSyncMessageSelected()); - assertEquals("testAccessors", "test.*", criteria.getExpression()); - assertNotNull("testAccessors", criteria.getPattern()); - assertEquals("testAccessors", "test.*", criteria.getPattern().pattern()); - assertEquals("testAccessors", 0, criteria.getPattern().flags() & Pattern.CASE_INSENSITIVE); - - // set false to all flags - criteria.setAsyncMessageReturnSelected(false); - criteria.setAsyncMessageSelected(false); - criteria.setCaseSenstiveSelected(false); - criteria.setLifeLineSelected(false); - criteria.setStopSelected(false); - criteria.setSyncMessageReturnSelected(false); - criteria.setSyncMessageSelected(false); - - assertFalse("testAccessors", criteria.isAsyncMessageReturnSelected()); - assertFalse("testAccessors", criteria.isAsyncMessageSelected()); - assertFalse("testAccessors", criteria.isCaseSenstiveSelected()); - assertFalse("testAccessors", criteria.isLifeLineSelected()); - assertFalse("testAccessors", criteria.isStopSelected()); - assertFalse("testAccessors", criteria.isSyncMessageReturnSelected()); - assertFalse("testAccessors", criteria.isSyncMessageSelected()); - assertEquals("testAccessors", "test.*", criteria.getExpression()); - assertNotNull("testAccessors", criteria.getPattern()); - assertEquals("testAccessors", "test.*", criteria.getPattern().pattern()); - assertEquals("testAccessors", Pattern.CASE_INSENSITIVE, criteria.getPattern().flags() & Pattern.CASE_INSENSITIVE); - } - - /** - * Test compartTo method. - */ - @Test - public void testCompareTo() { - Criteria criteria = new Criteria(); - criteria.setExpression("test"); - criteria.setLifeLineSelected(true); - criteria.setSyncMessageSelected(true); - - Criteria copy = new Criteria(criteria); - assertTrue("testCompareTo", criteria.compareTo(copy)); - assertTrue("testCompareTo", copy.compareTo(criteria)); - assertTrue("testCompareTo", criteria.compareTo(criteria)); - - copy.setExpression(null); - assertFalse("testCompareTo", criteria.compareTo(copy)); - assertFalse("testCompareTo", copy.compareTo(criteria)); - - criteria.setExpression(null); - assertTrue("testCompareTo", criteria.compareTo(copy)); - assertTrue("testCompareTo", copy.compareTo(criteria)); - - criteria.setExpression("test"); - copy.setExpression("test.*[12345]"); - assertFalse("testCompareTo", criteria.compareTo(copy)); - assertFalse("testCompareTo", copy.compareTo(criteria)); - - copy.setExpression("test"); - copy.setAsyncMessageReturnSelected(true); - assertFalse("testCompareTo", criteria.compareTo(copy)); - assertFalse("testCompareTo", copy.compareTo(criteria)); - } - - /** - * Test save to disk. - */ - @Test - public void testSave() { - DialogSettings settings = new DialogSettings("mysettings"); - - Criteria criteria = new Criteria(); - criteria.setExpression("test"); - criteria.setLifeLineSelected(true); - criteria.setSyncMessageSelected(true); - - // Save the criteria to the dialog settings - criteria.save(settings); - - // Check if all values are saved as expected - assertEquals("testSave", "test", settings.get("expression")); - assertEquals("testSave", "false", settings.get("isCaseSenstiveSelected")); - assertEquals("testSave", "false", settings.get("isAsyncMessageReturnSelected")); - assertEquals("testSave", "false", settings.get("isAsyncMessageSelected")); - assertEquals("testSave", "true", settings.get("isLifeLineSelected")); - assertEquals("testSave", "false", settings.get("isStopSelected")); - assertEquals("testSave", "false", settings.get("isSyncMessageReturnSelected")); - assertEquals("testSave", "true", settings.get("isSyncMessageSelected")); - } - - /** - * Test restore from disk. - */ - @Test - public void testLoad() { - DialogSettings settings = new DialogSettings("mysettings"); - - Criteria criteria = new Criteria(); - criteria.setExpression("test"); - criteria.setLifeLineSelected(true); - criteria.setSyncMessageSelected(true); - - // Save the criteria to the dialog settings - criteria.save(settings); - - // Load the criteria from the dialog settings - Criteria copy = new Criteria(); - copy.load(settings); - - assertTrue("testCompareTo", criteria.compareTo(copy)); - assertTrue("testCompareTo", copy.compareTo(criteria)); - } - - /** - * Test graph node summary usage. - */ - @Test - public void testGetGraphNodeSummary() { - - // Create a dummy provider - ISDFilterProvider provider = new ISDFilterProvider() { - - @Override - public boolean isNodeSupported(int nodeType) { - return true; - } - - @Override - public String getNodeName(int nodeType, String loaderClassName) { - // not clear about purpose loaderClassName - switch (nodeType) { - case ISDGraphNodeSupporter.LIFELINE: - return "MyLifeline"; - case ISDGraphNodeSupporter.SYNCMESSAGE: - return "MySyncMessage"; - case ISDGraphNodeSupporter.SYNCMESSAGERETURN: - return "MySyncMessageReturn"; - case ISDGraphNodeSupporter.ASYNCMESSAGE: - return "MyAsyncMessage"; - case ISDGraphNodeSupporter.ASYNCMESSAGERETURN: - return "MyAsyncMessageReturn"; - case ISDGraphNodeSupporter.STOP: - return "MyStop"; - default: - return ""; - } - } - - @Override - public boolean filter(List filters) { - return false; - } - }; - - Criteria criteria = new Criteria(); - criteria.setExpression("BALL_.*"); - criteria.setAsyncMessageReturnSelected(true); - criteria.setAsyncMessageSelected(true); - criteria.setLifeLineSelected(true); - criteria.setStopSelected(true); - criteria.setSyncMessageReturnSelected(true); - criteria.setSyncMessageSelected(true); - - // Test summary when provider is available - String summary = criteria.getGraphNodeSummary(provider, null); - assertEquals("testGetGraphNodeSummary", "[MyLifeline or MySyncMessage or MySyncMessageReturn or MyAsyncMessage or MyAsyncMessageReturn or MyStop]", summary); - - // Test default summary when no provider is provided - summary = criteria.getGraphNodeSummary(null, null); - assertEquals("testGetGraphNodeSummary", "[Lifeline or Synchronous message or Synchronous message return or Asynchronous message or Asynchronous message return or Stop]", summary); - - } - - /** - * Test matches algorithm. - */ - @Test - public void testMatches() { - Criteria criteria = new Criteria(); - criteria.setExpression("BALL_.*"); - - /* - * Note that method matches uses the Pattern class. Test - * only case sensitive/case insensitive case. All other regular - * expression cases are covered by Pattern class. - */ - - // case insensitive - assertTrue("testMatches", criteria.matches("BALL_REQUEST")); - assertTrue("testMatches", criteria.matches("BALL_REPLY")); - assertTrue("testMatches", criteria.matches("BALL_R")); - assertTrue("testMatches", criteria.matches("ball_request")); - assertTrue("testMatches", criteria.matches("ball_request")); - assertFalse("testMatches", criteria.matches("NOBALL_REQUEST")); - assertFalse("testMatches", criteria.matches("BLABLA")); - - // case sensitive - criteria.setCaseSenstiveSelected(true); - assertTrue("testMatches", criteria.matches("BALL_REQUEST")); - assertTrue("testMatches", criteria.matches("BALL_REPLY")); - assertTrue("testMatches", criteria.matches("BALL_R")); - assertFalse("testMatches", criteria.matches("ball_request")); - assertFalse("testMatches", criteria.matches("ball_request")); - assertFalse("testMatches", criteria.matches("NOBALL_REQUEST")); - assertFalse("testMatches", criteria.matches("BLABLA")); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/load/AllTests.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/load/AllTests.java deleted file mode 100644 index 12ba3a7047..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/load/AllTests.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.load; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite for testing loader manager of UML2SD extension point. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - LoadersManagerTest.class -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/load/LoadersManagerTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/load/LoadersManagerTest.java deleted file mode 100644 index 8560b3616e..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/load/LoadersManagerTest.java +++ /dev/null @@ -1,157 +0,0 @@ -/********************************************************************** - * Copyright (c) 2011, 2013 Ericsson. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.load; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; - -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.load.IUml2SDLoader; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.load.LoadersManager; -import org.eclipse.ui.PlatformUI; -import org.junit.Test; - -/** - * Test cases class to test loader manager of UML2SD extension point. - */ -public class LoadersManagerTest { - - private final static String SDVIEW_WITH_ONE_LOADER = "org.eclipse.linuxtools.tmf.ui.tests.testSDView1Loader"; - private final static String SDVIEW_WITH_MULTIPLE_LOADER = "org.eclipse.linuxtools.tmf.ui.tests.testSDView2Loaders"; - private final static String TEST_LOADER_CLASS_NAME = "org.eclipse.linuxtools.tmf.ui.tests.uml2sd.load.TestLoaders"; - private final static String TMF_UML2SD_LOADER_CLASS_NAME = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.loader.TmfUml2SDSyncLoader"; - - private static final String LOADER_TAG = "uml2SDLoader"; - private static final String LOADER_PREFIX = LOADER_TAG + "."; - - /** - * Tests of loader manager singleton class. - */ - @Test - public void testLoaderManager() { - SDView view = null; - try { - - /* - * Test creation of a loader (one per SD view) - */ - - // Open view - // Note this will create the default loader! - view = (SDView)PlatformUI.getWorkbench() - .getActiveWorkbenchWindow() - .getActivePage() - .showView(SDVIEW_WITH_ONE_LOADER); - - IUml2SDLoader defaultLoader = LoadersManager.getInstance().getCurrentLoader(SDVIEW_WITH_ONE_LOADER, view); - assertNotNull("testLoaderManager", defaultLoader); - - // Test createLoader where loader doesn't exist - assertNull("testLoaderManager", LoadersManager.getInstance().createLoader("blabla", view)); - - // Test createLoader - IUml2SDLoader loader = LoadersManager.getInstance().createLoader(TEST_LOADER_CLASS_NAME, view); - - assertNotNull("testLoaderManager", loader); - assertEquals("testLoaderManager", "Test Loader", loader.getTitleString()); - assertEquals("testLoaderManager", loader, LoadersManager.getInstance().getCurrentLoader(SDVIEW_WITH_ONE_LOADER)); - - // compare loader and default loader. Even if they are the same class, they are different instances - assertFalse("testLoaderManager", loader==defaultLoader); - - // test getCurrentLoader(viewId, view) - IUml2SDLoader loader2 = LoadersManager.getInstance().getCurrentLoader(SDVIEW_WITH_ONE_LOADER, view); - assertEquals("testLoaderManager", loader, loader2); - - // Hide the view - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().hideView(view); - - // test that view restores the previous associated loader - view = (SDView)PlatformUI.getWorkbench() - .getActiveWorkbenchWindow() - .getActivePage() - .showView(SDVIEW_WITH_ONE_LOADER); - - // Well, this is the only way test which loader is set - assertEquals("testLoaderManager", "Sequence Diagram - First Page", view.getFrame().getName()); - - // Test view == null - assertNull("testLoaderManager", LoadersManager.getInstance().createLoader(TEST_LOADER_CLASS_NAME, null)); - - // Hide the view - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().hideView(view); - - /* - * Test creation of loaders with re-uses the same SD view - */ - - // test that view restores the previous associated loader - view = (SDView)PlatformUI.getWorkbench() - .getActiveWorkbenchWindow() - .getActivePage() - .showView(SDVIEW_WITH_MULTIPLE_LOADER); - - // Test that default loader is set. Note that 2 default loaders are define in the plugin.xml and the - // the first one should be selected. - - // Well, this is the only way test which loader is set - assertEquals("testLoaderManager", "Sequence Diagram - First Page", view.getFrame().getName()); - - loader = LoadersManager.getInstance().getCurrentLoader(SDVIEW_WITH_MULTIPLE_LOADER, view); - assertNotNull("testLoaderManager", loader); - assertEquals("testLoaderManager", "Test Loader", loader.getTitleString()); - assertEquals("testLoaderManager", loader, LoadersManager.getInstance().getCurrentLoader(SDVIEW_WITH_MULTIPLE_LOADER)); - - // Test createLoader for loader with class name TMF_UML2SD_LOADER_CLASS_NAME - loader = LoadersManager.getInstance().createLoader(TMF_UML2SD_LOADER_CLASS_NAME, view); - - assertNotNull("testLoaderManager", loader); - assertEquals("testLoaderManager", "Component Interactions", loader.getTitleString()); - assertEquals("testLoaderManager", loader, LoadersManager.getInstance().getCurrentLoader(SDVIEW_WITH_MULTIPLE_LOADER)); - - // Verify if the correct loader is stored in the preferences as the current loader for this view - assertEquals("testLoaderManager", TMF_UML2SD_LOADER_CLASS_NAME, getSavedLoader(SDVIEW_WITH_MULTIPLE_LOADER)); - - // Test createLoader for loader with class name TEST_LOADER_CLASS_NAME - loader = LoadersManager.getInstance().createLoader(TEST_LOADER_CLASS_NAME, view); - - assertNotNull("testLoaderManager", loader); - assertEquals("testLoaderManager", "Test Loader", loader.getTitleString()); - assertEquals("testLoaderManager", loader, LoadersManager.getInstance().getCurrentLoader(SDVIEW_WITH_MULTIPLE_LOADER)); - - // Verify if the correct loader is stored in the preferences as the current loader for this view - assertEquals("testLoaderManager", TEST_LOADER_CLASS_NAME, getSavedLoader(SDVIEW_WITH_MULTIPLE_LOADER)); - assertEquals("testLoaderManager", TEST_LOADER_CLASS_NAME, LoadersManager.getInstance().getSavedLoader(SDVIEW_WITH_MULTIPLE_LOADER)); - - // Hide the view - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().hideView(view); - - // Test reset loader - LoadersManager.getInstance().resetLoader(SDVIEW_WITH_MULTIPLE_LOADER); - - } catch (Exception e) { - e.printStackTrace(); - fail(); - } - } - - private static String getSavedLoader(String viewId) { - IPreferenceStore p = Activator.getDefault().getPreferenceStore(); - return p.getString(LOADER_PREFIX + viewId); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/AllTests.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/AllTests.java deleted file mode 100644 index 903ff5f4e9..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/AllTests.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.loader; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Test suite for testing the TmfUml2SDSyncLoader class. - * - * @author Bernd Hufmann - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TmfUml2SDSyncLoaderExpTest.class, - TmfUml2SDSyncLoaderFilterTest.class, - TmfUml2SDSyncLoaderFindTest.class, - TmfUml2SDSyncLoaderPagesTest.class, - TmfUml2SDSyncLoaderSignalTest.class, - TmfUml2SDSyncLoaderTimeTest.class -}) -public class AllTests { - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/IUml2SDTestConstants.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/IUml2SDTestConstants.java deleted file mode 100644 index 18e5edc071..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/IUml2SDTestConstants.java +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.loader; - -/** - * Common constants for the TMF UML2SD test cases - * @author Bernd Hufmann - */ -public interface IUml2SDTestConstants { - - /** - * Timeout for waiting of jobs to finish (in milliseconds). - */ - public static final int WAIT_FOR_JOBS_DELAY = 1000; - /** - * Timeout for waiting for GUI display to refresh (in milliseconds). - */ - public static final int GUI_REFESH_DELAY = 1000; - /** - * Initial delay before indexing (in milliseconds). - */ - public static final int INITIAL_INDEX_DELAY = 1000; - /** - * Delay after broadcasting a TMF signal (in milliseconds) - */ - public static final int BROADCAST_DELAY = 2000; - /** - * Total number of pages of test trace. - */ - public static final int TOTAL_NUMBER_OF_PAGES = 9; - /** - * Number of messages per page (as defined for loader class) - */ - public static final int MAX_MESSEAGES_PER_PAGE = 10000; - /** - * Number of messages of last page of the test trace. - */ - public static final int NUM_MESSAGES_OF_LAST_PAGE = 32; - /** - * Default number of lifelines of test trace. - */ - public static final int DEFAULT_NUM_LIFELINES = 2; - /** - * Number of lifelines of test trace when all lifelines are visible. - */ - public static final int NUM_OF_ALL_LIFELINES = 3; - /** - * Page number of test trace where all lifelines are visible. - */ - public static final int PAGE_OF_ALL_LIFELINES = 4; - /** - * Time scale of test trace. - */ - public static final byte TIME_SCALE = -9; - /** - * Master player name (property of test trace) - */ - public static final String MASTER_PLAYER_NAME = "Master"; - /** - * First player name (property of test trace) - */ - public static final String FIRST_PLAYER_NAME = "player1"; - /** - * Second player name (property of test trace) - */ - public static final String SECOND_PLAYER_NAME = "player2"; - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/IUml2SdSignalValidator.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/IUml2SdSignalValidator.java deleted file mode 100644 index 186f0a9650..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/IUml2SdSignalValidator.java +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.loader; - -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; - -/** - * Interface for testing signal handling within TmfUml2SD - * - * @author Bernd Hufmann - */ -public interface IUml2SdSignalValidator { - /** - * @return if signal is received or not - */ - boolean isSignalReceived(); - /** - * Sets signal received value - * @param received boolean value to set - */ - void setSignalReceived(boolean received); - - /** - * @return whether source of signal is correct or not - */ - boolean isSourceError(); - /** - * Sets the source error flag. - * @param fIsSourceError boolean value to set - */ - void setSourceError(boolean fIsSourceError); - - /** - * @return whether received current time is correct or not - */ - boolean isCurrentTimeError(); - /** - * Sets the current time error flag. - * @param fIsCurrentTimeError boolean value to set - */ - void setCurrentTimeError(boolean fIsCurrentTimeError); - - /** - * @return whether received range is correct or not - */ - boolean isRangeError(); - /** - * Sets the range error flag. - * @param fIsRangeError boolean value to set - */ - void setRangeError(boolean fIsRangeError); - - /** - * @return whether signal was received or not - */ - boolean isSignalError(); - /** - * Sets signal error flag. - * @param fIsSignalError boolean value to set - */ - void setSignalError(boolean fIsSignalError); - - /** - * @return source of expected signal. - */ - Object getSource(); - /** - * Sets source of expected signal - * @param source expected source component - */ - void setSource(Object source); - - /** - * @return the expected current time. - */ - TmfTimestamp getCurrentTime(); - /** - * Sets the expected current time - * @param currentTime Time to set - */ - void setCurrentTime(TmfTimestamp currentTime); - - /** - * @return the expected current time range. - */ - TmfTimeRange getCurrentRange(); - /** - * Sets the expected current time range. - * @param currentRange the expected current time range to set - */ - void setCurrentRange(TmfTimeRange currentRange); - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderExpTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderExpTest.java deleted file mode 100644 index db364a8f70..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderExpTest.java +++ /dev/null @@ -1,191 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.loader; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.FilterCriteria; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.FilterListDialog; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDAdvancedPagingProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDPagingProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.loader.TmfUml2SDSyncLoader; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Test cases for Experiment handling. - * - * @author Bernd Hufmann - */ -public class TmfUml2SDSyncLoaderExpTest { - - private static Uml2SDTestFacility fFacility; - - /** - * Initialization - */ - @BeforeClass - public static void setUpClass() { - fFacility = Uml2SDTestFacility.getInstance(); - // create filter criteria (incl. save) - fFacility.createFilterCriteria(); - fFacility.selectExperiment(); - } - - /** - * Cleanup - */ - @AfterClass - public static void tearDownClass() { - fFacility.disposeExperiment(); - fFacility = null; - } - - /** - * Verify setup - * - * Verified Methods: loader.getTitleString() - * view.getPartName() - * view.getFrame() - * Expected result: Title, view name are set properly. - */ - @Test - public void verifySetup() { - assertEquals("getTitleString", "Component Interactions", fFacility.getLoader().getTitleString()); - assertEquals("getPartName", "Sequence Diagram", fFacility.getSdView().getPartName()); - assertNotNull("getFrame", fFacility.getSdView().getFrame()); - - fFacility.disposeExperiment(); - - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - verifyPage(0, 0, false, false, 0); - } - - /** - * Verify cancellation of ongoing indexing. - * - * Verified Methods: loader.experimentSelected(), loader.experimentDisposed(), loader.nextPage() - * Expected result: No exceptions during cancellation and nextPage() operation. - * - * Note this test is not sufficient to verify the concurrent access of the loader attributes - * by multiple threads. Contention might happen but it's not guaranteed. - */ - @Test - public void verifyCancel() { - for(int i = 0; i < 5; i++) { - fFacility.selectExperiment(false); - fFacility.delay(IUml2SDTestConstants.INITIAL_INDEX_DELAY); - - try { - fFacility.disposeExperiment(); - fFacility.getLoader().nextPage(); // to test out of bounce - // Note: To actually create an out of bound exception remove - // safety-checks in nextPage/moveToPage of loader class - } catch (Exception e){ - // No Exception expected - fail("exp.select/exp.dispose"); - } - } - } - - /** - * Verify disposed experiment. - * - * Verified Methods: loader.nextPage(), - * loader.pagesCount(), loader.hasNextPage(), loader.hasPrevPage(), - * frame.syncMessagesCount, frame.lifeLinesCount - * Expected result: Page values and filter are reset. - * - * Note this test is not sufficient to verify the concurrent access of the loader attributes - * by multiple threads. Contention might happen but it's not guaranteed. - */ - @Test - public void verifyDispose() { - verifyPage(0, 0, false, false, 0); - - // verify that all enable filters are disabled after disposal - List filter = FilterListDialog.getGlobalFilters(); - - for (FilterCriteria filterCriteria : filter) { - assertFalse("exp.dispose", filterCriteria.isActive()); - } - } - - /** - * Verify the disposal of the loader. - * - * Verified Methods: loader.dispose() - * Expected result: All providers are removed from SDView. - */ - @Test - public void verifyLoaderDispose() { - fFacility.getLoader().dispose(); - assertTrue("loader.dispose", fFacility.getSdView().getSDPagingProvider() == null); - assertTrue("loader.dispose", fFacility.getSdView().getSDFindProvider() == null); - assertTrue("loader.dispose", fFacility.getSdView().getSDFilterProvider() == null); - assertTrue("loader.dispose", fFacility.getSdView().getExtendedFindProvider() == null); - assertTrue("loader.dispose", fFacility.getSdView().getExtendedFilterProvider() == null); - - // Set again loader as signal handler, which was removed by the the dispose above - TmfSignalManager.register(fFacility.getLoader()); - } - - /** - * Verify setViewer. - * - * Verified Methods: loader.setViewer - * Expected result: Paging, find and filter provider are set - */ - @Test - public void testSetViewer() { - fFacility.getLoader().setViewer(fFacility.getSdView()); - ISDPagingProvider pagingProvider = fFacility.getSdView().getSDPagingProvider(); - assertTrue("loader.setViewer", pagingProvider != null); - assertTrue("loader.setViewer", pagingProvider instanceof ISDAdvancedPagingProvider); - assertTrue("loader.setViewer", pagingProvider instanceof TmfUml2SDSyncLoader); - - assertTrue("loader.setViewer", fFacility.getSdView().getSDFindProvider() != null); - - assertTrue("loader.setViewer", fFacility.getSdView().getSDFilterProvider() != null); - - // All other providers are not used. - assertTrue("loader.setViewer", fFacility.getSdView().getExtendedFindProvider() == null); - assertTrue("loader.setViewer", fFacility.getSdView().getExtendedFilterProvider() == null); - } - - private static void verifyPage(int currentPage, int numMsg, boolean hasNext, - boolean hasPrev, int lifelineCount) { - assertEquals("currentPage", currentPage, fFacility.getLoader().currentPage()); - assertEquals("syncMessageCount, ", numMsg, fFacility.getSdView().getFrame().syncMessageCount()); - if (hasNext) { - assertTrue("hasNextpage", fFacility.getLoader().hasNextPage()); - } else { - assertFalse("hasNextPage", fFacility.getLoader().hasNextPage()); - } - if (hasPrev) { - assertTrue("hasPrevPage", fFacility.getLoader().hasPrevPage()); - } else { - assertFalse("hasPrevPage", fFacility.getLoader().hasPrevPage()); - } - assertEquals("lifeLinesCount", lifelineCount, fFacility.getSdView().getFrame().lifeLinesCount()); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderFilterTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderFilterTest.java deleted file mode 100644 index 90df11c936..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderFilterTest.java +++ /dev/null @@ -1,213 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.loader; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SyncMessage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.Criteria; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.FilterCriteria; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.loader.TmfSyncMessage; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Filter test cases. - * - * @author Bernd Hufmann - */ -public class TmfUml2SDSyncLoaderFilterTest { - - private static Uml2SDTestFacility fFacility; - private static List filterToSave; - - /** - * Initialization - */ - @BeforeClass - public static void setUpClass() { - fFacility = Uml2SDTestFacility.getInstance(); - fFacility.selectExperiment(); - - /* Create Filter Criteria */ - filterToSave = new ArrayList<>(); - Criteria criteria = new Criteria(); - criteria.setLifeLineSelected(true); - criteria.setExpression(IUml2SDTestConstants.FIRST_PLAYER_NAME); - filterToSave.add(new FilterCriteria(criteria, false, false)); - - criteria = new Criteria(); - criteria.setLifeLineSelected(true); - criteria.setExpression(IUml2SDTestConstants.MASTER_PLAYER_NAME); - filterToSave.add(new FilterCriteria(criteria, false, false)); - - criteria = new Criteria(); - criteria.setSyncMessageSelected(true); - criteria.setExpression("BALL_.*"); - filterToSave.add(new FilterCriteria(criteria, false, false)); - } - - /** - * Cleanup - */ - @AfterClass - public static void tearDownClass() { - fFacility.disposeExperiment(); - fFacility = null; - } - - /** - * Test Case set-up code. - */ - @Before - public void beforeTest(){ - // Make sure we are at the first page - fFacility.firstPage(); - } - - /** - * Test case clean-up code. - */ - @After - public void afterTest() { - filterToSave.get(0).setActive(false); - filterToSave.get(1).setActive(false); - filterToSave.get(2).setActive(false); - fFacility.getLoader().filter(filterToSave); - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - } - - /** - * Verify the filter lifelines (1 out of 2 is hidden) - * - * Verified Methods: loader.filter() - * Expected result: Only one lifeline is visible with no messages - */ - @Test - public void verifyFilter1of2() { - // Initialize the filter - filterToSave.get(0).setActive(true); - // Run the filter - fFacility.getLoader().filter(filterToSave); - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - - assertEquals("filter", 1, fFacility.getSdView().getFrame().lifeLinesCount()); - assertEquals("filter", IUml2SDTestConstants.MASTER_PLAYER_NAME, fFacility.getSdView().getFrame().getLifeline(0).getName()); - assertEquals("filter", 0, fFacility.getSdView().getFrame().syncMessageCount()); - } - - - /** - * Verify the filter lifelines (2 out of 2 are hidden) - * - * Verified Methods: loader.filter(), loader.fillCurrentPage() - * Expected result: Neiter liflines nor messages are visible - */ - @Test - public void verifyFilter2of2() { - // Initialize the filter - filterToSave.get(0).setActive(true); - filterToSave.get(1).setActive(true); - // Run the filter - fFacility.getLoader().filter(filterToSave); - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - - assertEquals("filter", 0, fFacility.getSdView().getFrame().lifeLinesCount()); - assertEquals("filter", 0, fFacility.getSdView().getFrame().syncMessageCount()); - } - - /** - * Verify removal of all filters - * - * Verified Methods: loader.filter(), loader.fillCurrentPage() - * Expected result: Everything is shown - */ - @Test - public void verifyRemoval() { - // First set 2 filter - filterToSave.get(0).setActive(true); - filterToSave.get(1).setActive(true); - fFacility.getLoader().filter(filterToSave); - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - - // Remove the filter - filterToSave.get(0).setActive(false); - filterToSave.get(1).setActive(false); - fFacility.getLoader().filter(filterToSave); - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - - assertEquals("filter", 2, fFacility.getSdView().getFrame().lifeLinesCount()); - assertEquals("filter", IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE, - fFacility.getSdView().getFrame().syncMessageCount()); - } - - /** - * Verify filter of messages - * - * Verified Methods: loader.filter(), loader.fillCurrentPage() - * Expected result: Only particular messages are shown - */ - @Test - public void verifyMessageFilter() { - // Initialize the filter - filterToSave.get(2).setActive(true); - // Run the filter - fFacility.getLoader().filter(filterToSave); - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - - assertEquals("filter", 2, fFacility.getSdView().getFrame().lifeLinesCount()); - assertEquals("filter", 6, fFacility.getSdView().getFrame().syncMessageCount()); - - String messages[] = { "REGISTER_PLAYER_REQUEST", "REGISTER_PLAYER_REPLY", - "GAME_REQUEST", "GAME_REPLY", "START_GAME_REQUEST", "START_GAME_REPLY" }; - - for (int i = 0; i < messages.length; i++) { - SyncMessage msg = fFacility.getSdView().getFrame().getSyncMessage(i); - assertTrue("filter", msg instanceof TmfSyncMessage); - assertEquals("filter", messages[i], msg.getName()); - } - } - - /** - * Verify filter lifeline (1 out of three lifelines). Note that filter was - * set during change of page. - * - * Verified Methods: loader.filter(), loader.fillCurrentPage() - * Expected result: Only 2 lifelines and their interactions are shown - */ - @Test - public void verifyFilter1of3() { - filterToSave.get(0).setActive(true); - fFacility.getLoader().filter(filterToSave); - fFacility.setPage(IUml2SDTestConstants.PAGE_OF_ALL_LIFELINES); - - assertEquals("filter", 2, fFacility.getSdView().getFrame().lifeLinesCount()); - String lifelines[] = { IUml2SDTestConstants.MASTER_PLAYER_NAME, IUml2SDTestConstants.SECOND_PLAYER_NAME }; - - for (int i = 0; i < lifelines.length; i++) { - Lifeline line = fFacility.getSdView().getFrame().getLifeline(i); - assertEquals("filter", lifelines[i], line.getName()); - } - - assertTrue(fFacility.getSdView().getFrame().syncMessageCount() > 0); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderFindTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderFindTest.java deleted file mode 100644 index d6f338cbcb..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderFindTest.java +++ /dev/null @@ -1,338 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.loader; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.Criteria; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.loader.TmfSyncMessage; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Search Test Cases. - * - * @author Bernd Hufmann - */ -public class TmfUml2SDSyncLoaderFindTest { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // Test case 002 expected values - final static private Uml2SDTestTimestamp TC_002_TIME_VALUE = new Uml2SDTestTimestamp(9788642104149L); - final static private String TC_002_MESSAGE_NAME = "GAME_REQUEST"; - final static private int TC_002_PAGE_VALUE = 0; - final static private int TC_002_START_OCCURRANCE = 3; - final static private int TC_002_END_OCCURRANCE = TC_002_START_OCCURRANCE; - final static private String TC_002_START_LIFELINE = IUml2SDTestConstants.FIRST_PLAYER_NAME; - final static private String TC_002_END_LIFELINE = IUml2SDTestConstants.MASTER_PLAYER_NAME; - - // Test case 003 expected values - final static private Uml2SDTestTimestamp TC_003_TIME_VALUE = new Uml2SDTestTimestamp(9788642113228L); - final static private String TC_003_MESSAGE_NAME = "GAME_REPLY"; - final static private int TC_003_PAGE_VALUE = 0; - final static private int TC_003_START_OCCURRANCE = 4; - final static private int TC_003_END_OCCURRANCE = TC_003_START_OCCURRANCE; - final static private String TC_003_START_LIFELINE = IUml2SDTestConstants.MASTER_PLAYER_NAME; - final static private String TC_003_END_LIFELINE = IUml2SDTestConstants.FIRST_PLAYER_NAME; - - // Test case 004 expected values - final static private Uml2SDTestTimestamp TC_004_TIME_VALUE = new Uml2SDTestTimestamp(9791893030834L); - final static private String TC_004_MESSAGE_NAME = "GAME_REQUEST"; - final static private int TC_004_PAGE_VALUE = 4; - final static private int TC_004_START_OCCURRANCE = 19; - final static private int TC_004_END_OCCURRANCE = TC_004_START_OCCURRANCE; - final static private String TC_004_START_LIFELINE = IUml2SDTestConstants.SECOND_PLAYER_NAME; - final static private String TC_004_END_LIFELINE = IUml2SDTestConstants.MASTER_PLAYER_NAME; - - // Test case 005 expected values - final static private int TC_005_PAGE_VALUE = 0; - final static private String TC_005_LIFELINE_NAME = IUml2SDTestConstants.FIRST_PLAYER_NAME; - - // Test case 006 expected values - final static private int TC_006_PAGE_VALUE = 4; - final static private String TC_006_LIFELINE_NAME = IUml2SDTestConstants.SECOND_PLAYER_NAME; - - // Fields used in tests - private static Uml2SDTestFacility fFacility; - private static Uml2SDSignalValidator fTmfComponent; - private static Criteria criteria; - private static List selection; - private static TmfSyncMessage msg; - private static Lifeline lifeline; - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Initialization - */ - @BeforeClass - public static void setUpClass() { - fFacility = Uml2SDTestFacility.getInstance(); - fFacility.selectExperiment(); - fTmfComponent = new Uml2SDSignalValidator(); - } - - /** - * Cleanup - */ - @AfterClass - public static void tearDownClass() { - fTmfComponent.dispose(); - fFacility.disposeExperiment(); - fFacility = null; - } - - /** - * Verify the ISDGraphNodeSupporter implementation. - * - * Verified Methods: loader.isNodeSupported(), loader.getNodeName() - * Expected result: Correct values are returned, i.e. only lifelines and - * sync. messages are supported. - */ - @Test - public void verifyISDGraphNodeSupporter() { - - fFacility.firstPage(); - - assertTrue("isNodeSupported", fFacility.getLoader().isNodeSupported(ISDGraphNodeSupporter.LIFELINE)); - assertTrue("isNodeSupported", fFacility.getLoader().isNodeSupported(ISDGraphNodeSupporter.SYNCMESSAGE)); - assertFalse("isNodeSupported", fFacility.getLoader().isNodeSupported(ISDGraphNodeSupporter.SYNCMESSAGERETURN)); - assertFalse("isNodeSupported", fFacility.getLoader().isNodeSupported(ISDGraphNodeSupporter.ASYNCMESSAGE)); - assertFalse("isNodeSupported", fFacility.getLoader().isNodeSupported(ISDGraphNodeSupporter.ASYNCMESSAGERETURN)); - assertFalse("isNodeSupported", fFacility.getLoader().isNodeSupported(ISDGraphNodeSupporter.STOP)); - - assertEquals("getNodeName", "Lifeline", fFacility.getLoader().getNodeName(ISDGraphNodeSupporter.LIFELINE, null)); - assertEquals("getNodeName", "Interaction", fFacility.getLoader().getNodeName(ISDGraphNodeSupporter.SYNCMESSAGE, null)); - assertEquals("getNodeName", "", fFacility.getLoader().getNodeName(ISDGraphNodeSupporter.SYNCMESSAGERETURN, null)); - assertEquals("getNodeName", "", fFacility.getLoader().getNodeName(ISDGraphNodeSupporter.ASYNCMESSAGE, null)); - assertEquals("getNodeName", "", fFacility.getLoader().getNodeName(ISDGraphNodeSupporter.ASYNCMESSAGERETURN, null)); - assertEquals("getNodeName", "", fFacility.getLoader().getNodeName(ISDGraphNodeSupporter.STOP, null)); - - fFacility.getLoader().cancel(); - } - - /** - * Verify 1st message find within page. - * - * Verified Methods: loader.find(), loader.moveToMessage() - * Expected result: Correct message is selected - */ - @Test - public void verifyFirstMessage() { - fFacility.firstPage(); - - criteria = new Criteria(); - criteria.setSyncMessageSelected(true); - criteria.setExpression("GAME_.*"); - - // set expected values - fTmfComponent.setSource(fFacility.getLoader()); - fTmfComponent.setCurrentTime(TC_002_TIME_VALUE); - fTmfComponent.setCurrentRange(null); // not used - fTmfComponent.setSignalReceived(false); - - fFacility.getLoader().find(criteria); - // Wait for the selection to finish - needed due to new platform behavior in Juno - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - assertTrue("find", fTmfComponent.isSignalReceived()); - assertFalse("find", fTmfComponent.isSignalError()); - assertFalse("find", fTmfComponent.isCurrentTimeError()); - assertFalse("find", fTmfComponent.isSourceError()); - - assertEquals("find", TC_002_PAGE_VALUE, fFacility.getLoader().currentPage()); - selection = fFacility.getSdView().getSDWidget().getSelection(); - assertNotNull(selection); - assertEquals("find", 1, selection.size()); - assertTrue(selection.get(0) instanceof TmfSyncMessage); - msg = (TmfSyncMessage) selection.get(0); - assertEquals("find", TC_002_MESSAGE_NAME, msg.getName()); - assertEquals("find", 0, TC_002_TIME_VALUE.compareTo(msg.getStartTime(), false)); - assertEquals("find", TC_002_START_OCCURRANCE, msg.getStartOccurrence()); - assertEquals("find", TC_002_END_OCCURRANCE, msg.getEndOccurrence()); - assertEquals("find", TC_002_START_LIFELINE, msg.getStartLifeline().getName()); - assertEquals("find", TC_002_END_LIFELINE, msg.getEndLifeline().getName()); - - /** - * Verify 2nd message find within page. - * - * Verified Methods: loader.find(), loader.moveToMessage() - * Expected result: Correct message is selected - */ - - // set expected values - fTmfComponent.setSource(fFacility.getLoader()); - fTmfComponent.setCurrentTime(TC_003_TIME_VALUE); - fTmfComponent.setCurrentRange(null); // not used - - fTmfComponent.setSignalReceived(false); - - fFacility.getLoader().find(criteria); - // Wait for the selection to finish - needed due to new platform behavior in Juno - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - assertTrue("find", fTmfComponent.isSignalReceived()); - assertFalse("find", fTmfComponent.isSignalError()); - assertFalse("find", fTmfComponent.isCurrentTimeError()); - assertFalse("find", fTmfComponent.isSourceError()); - - assertEquals("find", TC_003_PAGE_VALUE, fFacility.getLoader().currentPage()); - selection = fFacility.getSdView().getSDWidget().getSelection(); - assertNotNull(selection); - assertEquals("find", 1, selection.size()); - assertTrue(selection.get(0) instanceof TmfSyncMessage); - msg = (TmfSyncMessage) selection.get(0); - assertEquals("find", TC_003_MESSAGE_NAME, msg.getName()); - assertEquals("find", 0, TC_003_TIME_VALUE.compareTo(msg.getStartTime(), false)); - assertEquals("find", TC_003_START_OCCURRANCE, msg.getStartOccurrence()); - assertEquals("find", TC_003_END_OCCURRANCE, msg.getEndOccurrence()); - assertEquals("find", TC_003_START_LIFELINE, msg.getStartLifeline().getName()); - assertEquals("find", TC_003_END_LIFELINE, msg.getEndLifeline().getName()); - - /** - * Verify 1st message across page. - * - * Verified Methods: loader.find(), loader.moveToPage(), loader.moveToMessage() - * Expected result: Correct message is selected - */ - // set expected values - fTmfComponent.setSource(fFacility.getLoader()); - fTmfComponent.setCurrentTime(TC_004_TIME_VALUE); - fTmfComponent.setCurrentRange(new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH)); // not used - - fTmfComponent.setSignalReceived(false); - - fFacility.getLoader().find(criteria); - fFacility.waitForJobs(); // find across pages uses a job - // to make sure pageRequest has been started before calling waitforCompletion() - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - fFacility.getLoader().waitForCompletion(); - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - - assertTrue("find", fTmfComponent.isSignalReceived()); - assertFalse("find", fTmfComponent.isSignalError()); - assertFalse("find", fTmfComponent.isCurrentTimeError()); - assertFalse("find", fTmfComponent.isSourceError()); - - assertEquals("find", TC_004_PAGE_VALUE, fFacility.getLoader().currentPage()); - selection = fFacility.getSdView().getSDWidget().getSelection(); - assertNotNull(selection); - assertEquals("find", 1, selection.size()); - assertTrue(selection.get(0) instanceof TmfSyncMessage); - msg = (TmfSyncMessage) selection.get(0); - assertEquals("find", TC_004_MESSAGE_NAME, msg.getName()); - assertEquals("find", 0, TC_004_TIME_VALUE.compareTo(msg.getStartTime(), false)); - assertEquals("find", TC_004_START_OCCURRANCE, msg.getStartOccurrence()); - assertEquals("find", TC_004_END_OCCURRANCE, msg.getEndOccurrence()); - assertEquals("find", TC_004_START_LIFELINE, msg.getStartLifeline().getName()); - assertEquals("find", TC_004_END_LIFELINE, msg.getEndLifeline().getName()); - - // cancel find and go back to first page - fFacility.getLoader().cancel(); - } - - /** - * Verify find of lifeline within page. - * - * Verified Methods: loader.find(), loader.moveToPage(), loader.moveToMessage() - * Expected result: Correct message is selected - */ - @Test - public void verifyFind() { - fFacility.firstPage(); - - criteria = new Criteria(); - criteria.setLifeLineSelected(true); - criteria.setExpression(IUml2SDTestConstants.FIRST_PLAYER_NAME); - fFacility.getLoader().find(criteria); - // Wait for the selection to finish - needed due to new platform behavior in Juno - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - - assertEquals("find", TC_005_PAGE_VALUE, fFacility.getLoader().currentPage()); - selection = fFacility.getSdView().getSDWidget().getSelection(); - assertNotNull(selection); - assertEquals("find", 1, selection.size()); - assertTrue(selection.get(0) instanceof Lifeline); - lifeline = (Lifeline) selection.get(0); - assertEquals("find", TC_005_LIFELINE_NAME, lifeline.getName()); - - /** - * Verify lifeline across page. - * - * Verified Methods: loader.find(), loader.moveToPage(), loader.moveToMessage() - * Expected result: Correct message is selected - */ - criteria = new Criteria(); - criteria.setLifeLineSelected(true); - criteria.setExpression(IUml2SDTestConstants.SECOND_PLAYER_NAME); - - fFacility.getLoader().find(criteria); - fFacility.waitForJobs(); // find across pages uses a job - // to make sure pageRequest has been started before calling waitforCompletion() - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - fFacility.getLoader().waitForCompletion(); - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - - assertEquals("find", TC_006_PAGE_VALUE, fFacility.getLoader().currentPage()); - selection = fFacility.getSdView().getSDWidget().getSelection(); - assertNotNull(selection); - assertEquals("find", 1, selection.size()); - assertTrue(selection.get(0) instanceof Lifeline); - lifeline = (Lifeline) selection.get(0); - assertEquals("find", TC_006_LIFELINE_NAME, lifeline.getName()); - - // cancel find and go back to first page - fFacility.getLoader().cancel(); - } - - /** - * Verify cancel ongoing search job. - * - * Verified Methods: loader.find(), loader.find() - * Expected result: Cancelled find - */ - @Test - public void verifyCancelSearch() { - - fFacility.firstPage(); - - criteria = new Criteria(); - criteria.setLifeLineSelected(true); - criteria.setExpression(IUml2SDTestConstants.SECOND_PLAYER_NAME); - - fFacility.getLoader().find(criteria); - fFacility.delay(200); // to make sure job was started - fFacility.getLoader().cancel(); - - assertEquals("find", 0, fFacility.getLoader().currentPage()); // we are still at the first page - - // cancel find and go back to first page - fFacility.getLoader().cancel(); - fFacility.firstPage(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderPagesTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderPagesTest.java deleted file mode 100644 index c24028a7f4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderPagesTest.java +++ /dev/null @@ -1,215 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.loader; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Test cases for pages handling. - * - * @author Bernd Hufmann - */ -public class TmfUml2SDSyncLoaderPagesTest { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private static Uml2SDTestFacility fFacility; - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Initialization - */ - @BeforeClass - public static void setUpClass() { - fFacility = Uml2SDTestFacility.getInstance(); - fFacility.selectExperiment(); - } - - /** - * Cleanup - */ - @AfterClass - public static void tearDownClass() { - fFacility.disposeExperiment(); - fFacility = null; - } - - /** - * Test Case: 001 - * Description: Test number of pages. - * Verified Methods: loader.pagesCount(). - * Expected result: ITestConstants.TOTAL_NUMBER_OF_PAGES of pages - */ - @Test - public void verifyPagesCount() { - assertEquals(IUml2SDTestConstants.TOTAL_NUMBER_OF_PAGES, fFacility.getLoader().pagesCount()); - } - - - /** - * Test Case: 002 - * Description: Tests next page feature. - * Verified Methods: loader.nextPage(), loader.fillCurrentPage(), loader.pagesCount(), - * loader.hasNextPage(), loader.hasPrevPage(), - * frame.syncMessagesCount, frame.lifeLinesCount - * Expected result: Expected values are return. - */ - @Test - public void verifyNextPage() { - // assuming we are at the first page - for(int i = 0; i < IUml2SDTestConstants.TOTAL_NUMBER_OF_PAGES-2; i++) { - fFacility.nextPage(); - - if (i+1 == IUml2SDTestConstants.PAGE_OF_ALL_LIFELINES) { - verifyPage(i+1, IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE, true, true, IUml2SDTestConstants.NUM_OF_ALL_LIFELINES); - } - else { - verifyPage(i+1, IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE, true, true); - } - } - - // Last Page - fFacility.nextPage(); - verifyPage(IUml2SDTestConstants.TOTAL_NUMBER_OF_PAGES - 1, IUml2SDTestConstants.NUM_MESSAGES_OF_LAST_PAGE, false, true); - - // Check for index out of bounce - try { - fFacility.getLoader().nextPage(); - } catch (Exception e) { - fail(); - } - - fFacility.firstPage(); - } - - /** - * Test Case: 003 - * Description: Test previous page feature. - * Verified Methods: loader.prevPage(), loader.fillCurrentPage(), loader.pagesCount(), - * loader.hasNextPage(), loader.hasPrevPage(), - * frame.syncMessagesCount, frame.lifeLinesCount - * Expected result: Expected values are return. - */ - @Test - public void verifyPrevPage() { - // Last Page - fFacility.lastPage(); - assertEquals(IUml2SDTestConstants.TOTAL_NUMBER_OF_PAGES - 1, fFacility.getLoader().currentPage()); - assertEquals(IUml2SDTestConstants.NUM_MESSAGES_OF_LAST_PAGE, fFacility.getSdView().getFrame().syncMessageCount()); - assertFalse(fFacility.getLoader().hasNextPage()); - assertTrue(fFacility.getLoader().hasPrevPage()); - assertEquals(2, fFacility.getSdView().getFrame().lifeLinesCount()); - - for(int i = IUml2SDTestConstants.TOTAL_NUMBER_OF_PAGES-2; i > 0; i--) { - fFacility.prevPage(); - if (i == IUml2SDTestConstants.PAGE_OF_ALL_LIFELINES) { - verifyPage(i, IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE, true, true, IUml2SDTestConstants.NUM_OF_ALL_LIFELINES); - } else { - verifyPage(i, IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE, true, true); - } - } - - fFacility.prevPage(); - verifyPage(0, IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE, true, false); - - // Check for index out of bounce - try { - fFacility.getLoader().prevPage(); - } catch (Exception e) { - fail(); - } - } - - /** - * Test Case: 004 - * Description: Test first page feature. - * Verified Methods: loader.firstPage(), loader.fillCurrentPage(), loader.pagesCount(), - * loader.hasNextPage(), loader.hasPrevPage(), - * frame.syncMessagesCount, frame.lifeLinesCount - * Expected result: Expected values are return. - */ - @Test - public void verifyFirstPage() { - fFacility.lastPage(); - - // First Page - fFacility.firstPage(); - verifyPage(0, IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE, true, false); - } - - /** - * Test Case: 005 - * Description: Test last page feature. - * Verified Methods: loader.lastPage(), loader.pagesCount(), loader.hasNextPage(), loader.hasPrevPage() - * frame.syncMessagesCount, frame.lifeLinesCount - * Expected result: Expected values are return. - */ - @Test - public void verifyLastPage() { - fFacility.lastPage(); - verifyPage(IUml2SDTestConstants.TOTAL_NUMBER_OF_PAGES - 1, IUml2SDTestConstants.NUM_MESSAGES_OF_LAST_PAGE, false, true); - fFacility.firstPage(); - } - - /** - * Test Case: 006 - * Description: Test move to any page feature. - * Verified Methods: loader.pageNumberChanged(), loader.fillCurrentPage(), loader.pagesCount(), - * loader.hasNextPage(), loader.hasPrevPage(), - * frame.syncMessagesCount, frame.lifeLinesCount - * Expected result: Expected values are return. - */ - @Test - public void verifyPageNumberChanged() { - // any page - fFacility.setPage(IUml2SDTestConstants.PAGE_OF_ALL_LIFELINES); - verifyPage(IUml2SDTestConstants.PAGE_OF_ALL_LIFELINES, - IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE, true, true, - IUml2SDTestConstants.NUM_OF_ALL_LIFELINES); - fFacility.firstPage(); - } - - private static void verifyPage(int currentPage, int numMsg, boolean hasNext, boolean hasPrev) { - verifyPage(currentPage, numMsg, hasNext, hasPrev, IUml2SDTestConstants.DEFAULT_NUM_LIFELINES); - } - - private static void verifyPage(int currentPage, int numMsg, boolean hasNext, - boolean hasPrev, int lifelineCount) { - assertEquals("currentPage", currentPage, fFacility.getLoader().currentPage()); - assertEquals("syncMessageCount, ", numMsg, fFacility.getSdView().getFrame().syncMessageCount()); - if (hasNext) { - assertTrue("hasNextpage", fFacility.getLoader().hasNextPage()); - } else { - assertFalse("hasNextPage", fFacility.getLoader().hasNextPage()); - } - if (hasPrev) { - assertTrue("hasPrevPage", fFacility.getLoader().hasPrevPage()); - } else { - assertFalse("hasPrevPage", fFacility.getLoader().hasPrevPage()); - } - assertEquals("lifeLinesCount", lifelineCount, fFacility.getSdView().getFrame().lifeLinesCount()); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderSignalTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderSignalTest.java deleted file mode 100644 index 111780f1b1..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderSignalTest.java +++ /dev/null @@ -1,134 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - * Patrick Tasse - Support selection range - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.loader; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Test cases for signal handling. - * - * @author Bernd Hufmann - */ -public class TmfUml2SDSyncLoaderSignalTest { - - private static Uml2SDTestFacility fFacility; - private static Uml2SDSignalValidator fTmfComponent; - - private static TmfTimeRange range; - private static TmfTimestamp rangeWindow; - private static TmfTimestamp currentTime; - - /** - * Initialization - */ - @BeforeClass - public static void setUpClass() { - fFacility = Uml2SDTestFacility.getInstance(); - fFacility.selectExperiment(); - - range = new TmfTimeRange(new Uml2SDTestTimestamp(9789689220871L), new Uml2SDTestTimestamp(9789773881426L)); - // Get range window for tests below - rangeWindow = (TmfTimestamp) range.getEndTime().getDelta(range.getStartTime()); - currentTime = new Uml2SDTestTimestamp(9789773782043L); - - fFacility.getTrace().broadcast(new TmfRangeSynchSignal(fFacility, range)); - fFacility.getTrace().broadcast(new TmfTimeSynchSignal(fFacility, currentTime)); - fFacility.delay(IUml2SDTestConstants.BROADCAST_DELAY); - - fTmfComponent = new Uml2SDSignalValidator(); - } - - /** - * Cleanup - */ - @AfterClass - public static void tearDownClass() { - fFacility.disposeExperiment(); - fFacility = null; - } - - /** - * Test Case: 001 - * Description: Verify that time range signal is send with correct values when going to first page - * Verified Methods: broadcast() - * Expected result: Time range sync signal is sent with correct range and current time. - */ - @Test - public void verifyFirstPageSignal() { - currentTime = new Uml2SDTestTimestamp(9788641608418L); - range = new TmfTimeRange(currentTime, new Uml2SDTestTimestamp(currentTime.getValue() + rangeWindow.getValue())); - - fTmfComponent.setSignalError(false); - fTmfComponent.setSignalReceived(false); - fTmfComponent.setCurrentTimeError(false); - fTmfComponent.setRangeError(false); - fTmfComponent.setSourceError(false); - - // set expected values - fTmfComponent.setSource(fFacility.getLoader()); - fTmfComponent.setCurrentTime(currentTime); - fTmfComponent.setCurrentRange(range); - - fFacility.firstPage(); - assertTrue("TmfRangeSynchSignal", fTmfComponent.isSignalReceived()); - assertFalse("TmfRangeSynchSignal", fTmfComponent.isSignalError()); - assertFalse("TmfRangeSynchSignal", fTmfComponent.isCurrentTimeError()); - assertFalse("TmfRangeSynchSignal", fTmfComponent.isSourceError()); - assertFalse("TmfRangeSynchSignal", fTmfComponent.isRangeError()); - } - - /** - * Test Case: 002 - * Description: Verify that time sync signal is sent correctly after selection - * Verified Methods: loader.broadcast(), testSelectionChanged - * Expected result: Time sync signal is sent with correct current time. - */ - @Test - public void verifySelectionSignal() { - fTmfComponent.setSignalReceived(false); - - int count = fFacility.getSdView().getFrame().syncMessageCount(); - assertEquals("Test Preparation", IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE, count); - GraphNode node = fFacility.getSdView().getFrame().getSyncMessage(3); - - // set expected values - fTmfComponent.setSource(fFacility.getLoader()); - fTmfComponent.setCurrentTime(new Uml2SDTestTimestamp(9788642113228L)); - fTmfComponent.setCurrentRange(null); // not used - - fFacility.getSdView().getSDWidget().moveTo(node); // selects the given node - // Wait for the selection to finish - needed due to new platform behavior in Juno - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - assertTrue("TmfTimeSynchSignal", fTmfComponent.isSignalReceived()); - assertFalse("TmfTimeSynchSignal", fTmfComponent.isSignalError()); - assertFalse("TmfTimeSynchSignal", fTmfComponent.isCurrentTimeError()); - assertFalse("TmfTimeSynchSignal", fTmfComponent.isSourceError()); - - fTmfComponent.setSignalReceived(false); - - fTmfComponent.dispose(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderTimeTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderTimeTest.java deleted file mode 100644 index 829858322d..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderTimeTest.java +++ /dev/null @@ -1,311 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Alexandre Montplaisir - Port to JUnit4 - * Patrick Tasse - Support selection range - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.loader; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.loader.TmfSyncMessage; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Test cases for time synchronization handling. - * - * @author Bernd Hufmann - */ -public class TmfUml2SDSyncLoaderTimeTest { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // Test case 001 expected values - final static private Uml2SDTestTimestamp TC_001_TIME_VALUE = new Uml2SDTestTimestamp(9788642228395L); - final static private String TC_001_MESSAGE_NAME = "START_GAME_REPLY"; - final static private int TC_001_PAGE_VALUE = 0; - final static private int TC_001_START_OCCURRANCE = 6; - final static private int TC_001_END_OCCURRANCE = TC_001_START_OCCURRANCE; - final static private String TC_001_START_LIFELINE = IUml2SDTestConstants.MASTER_PLAYER_NAME; - final static private String TC_001_END_LIFELINE = IUml2SDTestConstants.FIRST_PLAYER_NAME; - - // Test case 002 expected values - final static private Uml2SDTestTimestamp TC_002_TIME_VALUE = new Uml2SDTestTimestamp(9789689830722L); - final static private String TC_002_MESSAGE_NAME = "PAUSE_GAME_REQUEST"; - final static private int TC_002_PAGE_VALUE = 2; - final static private int TC_002_START_OCCURRANCE = 7; - final static private int TC_002_END_OCCURRANCE = TC_002_START_OCCURRANCE; - final static private String TC_002_START_LIFELINE = IUml2SDTestConstants.FIRST_PLAYER_NAME; - final static private String TC_002_END_LIFELINE = IUml2SDTestConstants.MASTER_PLAYER_NAME; - - // Test case 003 expected values - final static private Uml2SDTestTimestamp TC_003_TIME_VALUE = new Uml2SDTestTimestamp(9790750000000L); - final static private int TC_003_PAGE_VALUE = 4; - - // Test case 004 expected values - final static private int TC_004_PAGE_VALUE = 0; - - // Test case 005 expected values - final static private int TC_005_PAGE_VALUE = IUml2SDTestConstants.TOTAL_NUMBER_OF_PAGES - 1; - - // Test case 006 expected values - final static private Uml2SDTestTimestamp TC_006_TIME_VALUE = new Uml2SDTestTimestamp(9792420661655L); - final static private int TC_006_PAGE_VALUE = 4; - final static private int TC_006_START_OCCURRANCE = IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE; - final static private int TC_006_END_OCCURRANCE = TC_006_START_OCCURRANCE; - - // Test case 007 expected values - final static private Uml2SDTestTimestamp TC_007_TIME_VALUE = new Uml2SDTestTimestamp(9792420756010L); - final static private int TC_007_PAGE_VALUE = 5; - final static private int TC_007_START_OCCURRANCE = 1; - final static private int TC_007_END_OCCURRANCE = TC_007_START_OCCURRANCE; - - // Test case 008 expected values - final static private Uml2SDTestTimestamp TC_008_TIME_VALUE = new Uml2SDTestTimestamp(9788642228395L); - final static private int TC_008_PAGE_VALUE = 0; - final static private Uml2SDTestTimestamp TC_008_START_TIME_VALUE = new Uml2SDTestTimestamp(9788642228395L); - final static private Uml2SDTestTimestamp TC_008_END_TIME_VALUE = new Uml2SDTestTimestamp(9789164833324L); - - // Test case 009 expected values - final static private Uml2SDTestTimestamp TC_009_TIME_VALUE = new Uml2SDTestTimestamp(9789689220871L); - final static private int TC_009_PAGE_VALUE = 1; - final static private Uml2SDTestTimestamp TC_009_START_TIME_VALUE = TC_009_TIME_VALUE; - final static private Uml2SDTestTimestamp TC_009_END_TIME_VALUE = new Uml2SDTestTimestamp(9789773881426L); - - // Fields used in tests - private static Uml2SDTestFacility fFacility; - private static List selection; - private static TmfSyncMessage msg; - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Initialization - */ - @BeforeClass - public static void setUpClass() { - fFacility = Uml2SDTestFacility.getInstance(); - fFacility.selectExperiment(); - } - - /** - * Cleanup - */ - @AfterClass - public static void tearDownClass() { - fFacility.disposeExperiment(); - fFacility = null; - } - - /** - * Test Case: 001 - * Description: Verify synchToTime (exact time in page), selection of message in page - * Verified Methods: loader.syncToTime(), loader.moveToMessage(), loader.moveToMessageInPage() - * Expected result: Correct message is selected. - */ - @Test - public void verifySynchToTimeInPage() { - fFacility.getTrace().broadcast(new TmfTimeSynchSignal(this, TC_001_TIME_VALUE)); - fFacility.getLoader().waitForCompletion(); - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - assertEquals("synchToTime", TC_001_PAGE_VALUE, fFacility.getLoader().currentPage()); - selection = fFacility.getSdView().getSDWidget().getSelection(); - assertNotNull(selection); - assertEquals("synchToTime", 1, selection.size()); - assertTrue(selection.get(0) instanceof TmfSyncMessage); - msg = (TmfSyncMessage) selection.get(0); - assertEquals("synchToTime", TC_001_MESSAGE_NAME, msg.getName()); - assertEquals("synchToTime", 0, TC_001_TIME_VALUE.compareTo(msg.getStartTime(), false)); - assertEquals("synchToTime", TC_001_START_OCCURRANCE, msg.getStartOccurrence()); - assertEquals("synchToTime", TC_001_END_OCCURRANCE, msg.getEndOccurrence()); - assertEquals("synchToTime", TC_001_START_LIFELINE, msg.getStartLifeline().getName()); - assertEquals("synchToTime", TC_001_END_LIFELINE, msg.getEndLifeline().getName()); - } - - /** - * Test Case: 002 - * Description: Verify synchToTime (exact time outside of page), selection of message in page - * Verified Methods: loader.syncToTime(), loader.moveToMessage(), loader.moveToPage() - * Expected result: Correct message is selected. - */ - @Test - public void verifySynchToTimeOutsidePage() { - fFacility.getTrace().broadcast(new TmfTimeSynchSignal(this, TC_002_TIME_VALUE)); - fFacility.getLoader().waitForCompletion(); - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - assertEquals("synchToTime", TC_002_PAGE_VALUE, fFacility.getLoader().currentPage()); - selection = fFacility.getSdView().getSDWidget().getSelection(); - assertNotNull("synchToTime", selection); - assertEquals("synchToTime", 1, selection.size()); - assertTrue("synchToTime", selection.get(0) instanceof TmfSyncMessage); - msg = (TmfSyncMessage) selection.get(0); - assertEquals("synchToTime", TC_002_MESSAGE_NAME, msg.getName()); - assertEquals(0, TC_002_TIME_VALUE.compareTo(msg.getStartTime(), false)); - assertEquals("synchToTime", TC_002_START_OCCURRANCE, msg.getStartOccurrence()); - assertEquals("synchToTime", TC_002_END_OCCURRANCE, msg.getEndOccurrence()); - assertEquals(TC_002_START_LIFELINE, msg.getStartLifeline().getName()); - assertEquals(TC_002_END_LIFELINE, msg.getEndLifeline().getName()); - } - - - /** - * Test Case: 003 - * Description: Verify synchToTime (timestamp doesn't exist in trace), no selection of message in page - * Verified Methods: loader.syncToTime(), loader.moveToMessage(), loader.moveToPage() - * Expected result: Move to correct page, currentTime is updated so that focus on the currentTime, but no selection. - */ - @Test - public void verifySynchToTimeNonExisting() { - fFacility.getLoader().firstPage(); - - fFacility.getTrace().broadcast(new TmfTimeSynchSignal(this, TC_003_TIME_VALUE)); - fFacility.getLoader().waitForCompletion(); - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - assertEquals("synchToTime", 0, TC_003_TIME_VALUE.compareTo(fFacility.getLoader().getCurrentTime(), false)); - assertEquals("synchToTime", TC_003_PAGE_VALUE, fFacility.getLoader().currentPage()); - selection = fFacility.getSdView().getSDWidget().getSelection(); - assertNotNull("synchToTime", selection); - assertEquals("synchToTime", 0, selection.size()); - } - - /** - * Test Case: 004 - * Description: Verify synchToTime (timestamp < experiment time range start) - * Verified Methods: loader.syncToTime(), loader.moveToMessage(), loader.moveToPage() - * Expected result: Move to first page, focus on the beginning of the page, but no selection. - */ - @Test - public void verifySynchToTimeBeforeExpStart() { - fFacility.getTrace().broadcast(new TmfTimeSynchSignal(this, TmfTimestamp.BIG_BANG)); - fFacility.getLoader().waitForCompletion(); - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - assertEquals("synchToTime", TC_004_PAGE_VALUE, fFacility.getLoader().currentPage()); - selection = fFacility.getSdView().getSDWidget().getSelection(); - assertNotNull("synchToTime", selection); - assertEquals("synchToTime", 0, selection.size()); - } - - /** - * Test Case: 005 - * Description: Verify synchToTime (timestamp > experiment time range end) - * Verified Methods: loader.syncToTime(), loader.moveToMessage(), loader.moveToPage() - * Expected result: Move to last page, focus on the end of the page, but no selection. - */ - @Test - public void verifySynchToTimeAfterExpEnd() { - fFacility.getTrace().broadcast(new TmfTimeSynchSignal(this, TmfTimestamp.BIG_CRUNCH)); - fFacility.getLoader().waitForCompletion(); - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - assertEquals("synchToTime", TC_005_PAGE_VALUE, fFacility.getLoader().currentPage()); - selection = fFacility.getSdView().getSDWidget().getSelection(); - assertNotNull(selection); - assertEquals("synchToTime", 0, selection.size()); - } - - /** - * Test Case: 006 - * Description: Verify synchToTime (timestamp of last message in page) - * Verified Methods: loader.syncToTime(), loader.moveToMessage(), loader.moveToPage(), loader.moveToMessageInPage() - * Expected result: Move to correct page, selection of last message in page. - */ - @Test - public void verifySynchToTimeEqualsLast() { - fFacility.getTrace().broadcast(new TmfTimeSynchSignal(this, TC_006_TIME_VALUE)); - fFacility.getLoader().waitForCompletion(); - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - assertEquals("synchToTime", TC_006_PAGE_VALUE, fFacility.getLoader().currentPage()); - selection = fFacility.getSdView().getSDWidget().getSelection(); - assertNotNull("synchToTime", selection); - assertEquals("synchToTime", 1, selection.size()); - msg = (TmfSyncMessage) selection.get(0); - assertEquals("synchToTime", TC_006_START_OCCURRANCE, msg.getStartOccurrence()); - assertEquals("synchToTime", TC_006_END_OCCURRANCE, msg.getEndOccurrence()); - } - - /** - * Test Case: 007 - * Description: Verify synchToTime (timestamp of first message in page) - * Verified Methods: loader.syncToTime(), loader.moveToMessage(), loader.moveToPage() - * Expected result: Move to correct page, selection of last message in page. - */ - @Test - public void verifySynchToTimeFirst() { - fFacility.getTrace().broadcast(new TmfTimeSynchSignal(this, TC_007_TIME_VALUE)); - fFacility.getLoader().waitForCompletion(); - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - assertEquals("synchToTime", TC_007_PAGE_VALUE, fFacility.getLoader().currentPage()); - selection = fFacility.getSdView().getSDWidget().getSelection(); - assertNotNull("synchToTime", selection); - msg = (TmfSyncMessage) selection.get(0); - assertEquals("synchToTime", 1, selection.size()); - assertEquals("synchToTime", TC_007_START_OCCURRANCE, msg.getStartOccurrence()); - assertEquals("synchToTime", TC_007_END_OCCURRANCE, msg.getEndOccurrence()); - } - - /** - * Test Case: 008 - * Description: Verify time range signal (start, end time and current time are in same page) - * Verified Methods: loader.synchToTimeRange(), loader.moveToMessage(), loader.moveToMessageInPage() - * Expected result: Move to correct page(=page of start time of range), set focus on start time of range, but no selection of message. - */ - @Test - public void verifyTimeRangeSamePage() { - // 9788.642228395 (page 0) -> 9789.164833324 (page 0) with selected time 9788.642228395 (page 0) - fFacility.getLoader().firstPage(); - TmfTimeRange range = new TmfTimeRange(TC_008_START_TIME_VALUE, TC_008_END_TIME_VALUE); - fFacility.getLoader().waitForCompletion(); - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - fFacility.getTrace().broadcast(new TmfRangeSynchSignal(this, range)); - assertEquals("synchToTimeRange", TC_008_PAGE_VALUE, fFacility.getLoader().currentPage()); - assertNotNull("synchToTimeRange", fFacility.getLoader().getCurrentTime()); - assertEquals("synchToTimeRange", 0, TC_008_TIME_VALUE.compareTo(fFacility.getLoader().getCurrentTime(), false)); - selection = fFacility.getSdView().getSDWidget().getSelection(); - // We actually don't want something to be selected!!! - assertNotNull("synchToTimeRange", selection); - assertEquals("synchToTimeRange", 0, selection.size()); - } - - /** - * Test Case: 009 - * Description: Verify time range signal (start and end time are across 2 pages) - * Verified Methods: loader.synchToTimeRange(), loader.moveToMessage(), loader.moveToPage() - * Expected result: Move to correct page (=page of start time of range), set focus on start time of range, but no selection of message. - */ - @Test - public void verifyTimeRangeDifferentPages() { - TmfTimeRange range = new TmfTimeRange(TC_009_START_TIME_VALUE, TC_009_END_TIME_VALUE); - fFacility.getTrace().broadcast(new TmfRangeSynchSignal(this, range)); - fFacility.getLoader().waitForCompletion(); - fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - assertEquals("synchToTimeRange", TC_009_PAGE_VALUE, fFacility.getLoader().currentPage()); - assertNotNull("synchToTimeRange", fFacility.getLoader().getCurrentTime()); - assertEquals("synchToTimeRange", 0, TC_009_TIME_VALUE.compareTo(fFacility.getLoader().getCurrentTime(), false)); - selection = fFacility.getSdView().getSDWidget().getSelection(); - // We actually don't want something to be selected!!! - assertNotNull("synchToTimeRange", selection); - assertEquals("synchToTimeRange", 0, selection.size()); - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/Uml2SDSignalValidator.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/Uml2SDSignalValidator.java deleted file mode 100644 index d41bc282a0..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/Uml2SDSignalValidator.java +++ /dev/null @@ -1,188 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Patrick Tasse - Support selection range - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.loader; - -import org.eclipse.linuxtools.tmf.core.component.TmfComponent; -import org.eclipse.linuxtools.tmf.core.signal.TmfEndSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfStartSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; - -/** - * Class to implement that certain signals are sent as well as are sent with correct content. - * - * @author Bernd Hufmann - */ -public class Uml2SDSignalValidator extends TmfComponent implements IUml2SdSignalValidator { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - private int fSignalDepth = 0; - private boolean fIsSignalReceived = false; - private boolean fIsSignalError = false; - private boolean fIsSourceError = false; - private boolean fIsCurrentTimeError = false; - private boolean fIsRangeError = false; - - private Object fSource = null; - private TmfTimestamp fCurrentTimestamp = null; - private TmfTimeRange fCurrentTimeRange = null; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - /** - * Constructor - */ - public Uml2SDSignalValidator() { - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - /** - * Signal handler for time synch signal. - * @param signal the signal to handle. - */ - @TmfSignalHandler - public void synchToTime(TmfTimeSynchSignal signal) { - // Set results so that it can be validated in the test case - setSignalReceived(true); - setSourceError(getSource() != signal.getSource()); - setCurrentTimeError(!getCurrentTime().equals(signal.getBeginTime())); - } - - /** - * Signal handler for time range synch signal. - * @param signal the signal to handle. - */ - @TmfSignalHandler - public void synchToTimeRange(TmfRangeSynchSignal signal) { - // Set results so that it can be validated in the test case - setSignalReceived(true); - if (getSource() != null) { - setSourceError(getSource() != signal.getSource()); - } - if (getCurrentRange() != null) { - setRangeError(!getCurrentRange().equals(signal.getCurrentRange())); - } - } - - /** - * Signal handler for handling start synch signal. - * @param signal the signal to handle. - */ - @TmfSignalHandler - public void startSynch(TmfStartSynchSignal signal) { - fSignalDepth++; - // make sure that the signal which is send by the loader class is not handled by the loader class - // after receiving it. i.e. it must not trigger a another signal - - // Set results so that it can be validated in the test case - setSignalError(fSignalDepth > 1); - } - - /** - * Signal handler for handling end synch signal. - * @param signal the signal to handle. - */ - @TmfSignalHandler - public void endSynch(TmfEndSynchSignal signal) { - fSignalDepth = fSignalDepth > 0 ? fSignalDepth - 1 : 0; - } - - @Override - public boolean isSignalReceived() { - return fIsSignalReceived; - } - - @Override - public void setSignalReceived(boolean received) { - fIsSignalReceived = received; - } - - @Override - public boolean isSourceError() { - return fIsSourceError; - } - - @Override - public void setSourceError(boolean fIsSourceError) { - this.fIsSourceError = fIsSourceError; - } - - @Override - public boolean isCurrentTimeError() { - return fIsCurrentTimeError; - } - - @Override - public void setCurrentTimeError(boolean fIsCurrentTimeError) { - this.fIsCurrentTimeError = fIsCurrentTimeError; - } - - @Override - public boolean isRangeError() { - return fIsRangeError; - } - - @Override - public void setRangeError(boolean fIsRangeError) { - this.fIsRangeError = fIsRangeError; - } - - @Override - public boolean isSignalError() { - return fIsSignalError; - } - - @Override - public void setSignalError(boolean fIsSignalError) { - this.fIsSignalError = fIsSignalError; - } - - @Override - public Object getSource() { - return fSource; - } - - @Override - public void setSource(Object source) { - fSource = source; - } - - @Override - public TmfTimestamp getCurrentTime() { - return fCurrentTimestamp; - } - - @Override - public void setCurrentTime(TmfTimestamp currentTime) { - fCurrentTimestamp = currentTime == null ? null : new TmfTimestamp(currentTime); - } - - @Override - public TmfTimeRange getCurrentRange() { - return fCurrentTimeRange; - } - - @Override - public void setCurrentRange(TmfTimeRange currentRange) { - fCurrentTimeRange = currentRange == null ? null : new TmfTimeRange(currentRange); - } -} - diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestFacility.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestFacility.java deleted file mode 100644 index 94020d9dcd..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestFacility.java +++ /dev/null @@ -1,360 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.loader; - -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; -import org.eclipse.linuxtools.tmf.ui.tests.uml2sd.trace.TmfUml2SDTestTrace; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.Criteria; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.FilterCriteria; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.FilterListDialog; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.load.LoadersManager; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.loader.TmfUml2SDSyncLoader; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IViewPart; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.PlatformUI; -import org.osgi.framework.FrameworkUtil; - -/** - * Singleton class to facilitate the test cases. Creates UML2SD view and loader objects as well as provides - * utility methods for interacting with the loader/view. - * - * @author Bernd Hufmann - */ -public class Uml2SDTestFacility { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - private static Uml2SDTestFacility fInstance = null; - - private TmfUml2SDSyncLoader fLoader; - private SDView fSdView; - private TmfTraceStub fTrace = null; - private TmfUml2SDTestTrace fParser = null; - private TmfExperiment fExperiment = null; - - private volatile boolean fIsInitialized = false; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - private Uml2SDTestFacility() { - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - /** - * @return the singleton instance. - */ - public synchronized static Uml2SDTestFacility getInstance() { - if (fInstance == null) { - fInstance = new Uml2SDTestFacility(); - fInstance.init(); - } - return fInstance; - } - - /** - * Initial the test facility. - */ - public void init() { - - if (!fIsInitialized) { - - fParser = new TmfUml2SDTestTrace(); - fTrace = setupTrace(fParser); - fParser.setTrace(fTrace); - - IViewPart view; - try { - // Remove welcome view to avoid interference during test execution - view = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow() - .getActivePage() - .findView("org.eclipse.ui.internal.introview"); - - if (view != null) { - PlatformUI.getWorkbench() - .getActiveWorkbenchWindow() - .getActivePage().hideView(view); - } - - view = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow() - .getActivePage() - .showView("org.eclipse.linuxtools.tmf.ui.tmfUml2SDSyncView"); - - } catch (final PartInitException e) { - throw new RuntimeException(e); - } - - fSdView = (SDView) view; - fLoader = (TmfUml2SDSyncLoader)LoadersManager.getInstance().createLoader( - "org.eclipse.linuxtools.tmf.ui.views.uml2sd.loader.TmfUml2SDSyncLoader", fSdView); - - delay(3000); - fIsInitialized = true; - } - } - - - private TmfTraceStub setupTrace(final ITmfEventParser parser) { - - try { - // Create test trace object - final URL location = FileLocator.find(FrameworkUtil.getBundle(this.getClass()), new Path("tracesets/sdEvents"), null); - final File test = new File(FileLocator.toFileURL(location).toURI()); - return new TmfTraceStub(test.getPath(), 500, true, parser); - } catch (final TmfTraceException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } catch (final URISyntaxException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } catch (final IOException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - /** - * Dispose the resource - */ - public void dispose() { - if (fIsInitialized) { - ITmfTrace trace = fTrace; - TmfExperiment experiment = fExperiment; - if (trace == null || experiment == null) { - throw new IllegalStateException(); - } - - trace.broadcast(new TmfTraceClosedSignal(this, experiment)); - experiment.dispose(); - - // Wait for all Eclipse jobs to finish - waitForJobs(); - - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().hideView(fSdView); - fIsInitialized = false; - } - } - - /** - * Sleeps current thread or GUI thread for a given time. - * @param waitTimeMillis time in milliseconds to wait - */ - public void delay(final long waitTimeMillis) { - final Display display = Display.getCurrent(); - if (display != null) { - final long endTimeMillis = System.currentTimeMillis() + waitTimeMillis; - while(System.currentTimeMillis() < endTimeMillis) { - if (!display.readAndDispatch()) { - // We do not use Display.sleep because it might never wake up - // if there is no user interaction - try { - Thread.sleep(Math.min(waitTimeMillis, 10)); - } catch (final InterruptedException e) { - // Ignored - } - } - display.update(); - } - } else { - try { - Thread.sleep(waitTimeMillis); - } catch (final InterruptedException e) { - // Ignored - } - } - } - - /** - * Waits for all Eclipse jobs to finish - */ - public void waitForJobs() { - while (!Job.getJobManager().isIdle()) { - delay(IUml2SDTestConstants.WAIT_FOR_JOBS_DELAY); - } - } - - /** - * @return current UML2SD loader - */ - public TmfUml2SDSyncLoader getLoader() { - return fLoader; - } - - /** - * @return current SD view - */ - public SDView getSdView() { - return fSdView; - } - - /** - * @return current trace - */ - public TmfTraceStub getTrace() { - return fTrace; - } - - /** - * @return Trace parser - */ - public TmfUml2SDTestTrace getParser() { - return fParser; - } - - /** - * @return current experiment. - */ - public TmfExperiment getExperiment() { - return fExperiment; - } - - /** - * Go to next page; - */ - public void nextPage() { - fLoader.nextPage(); - fLoader.waitForCompletion(); - delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - } - - /** - * Go to previous page. - */ - public void prevPage() { - fLoader.prevPage(); - fLoader.waitForCompletion(); - delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - } - - /** - * Go to last page. - */ - public void lastPage() { - fLoader.lastPage(); - fLoader.waitForCompletion(); - delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - } - - /** - * Go to first page. - */ - public void firstPage() { - fLoader.firstPage(); - fLoader.waitForCompletion(); - delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - } - - /** - * @param page number to set - */ - public void setPage(final int page) { - fLoader.pageNumberChanged(page); - fLoader.waitForCompletion(); - delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - } - - /** - * @see org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.loader.Uml2SDTestFacility#selectExperiment(boolean) - */ - public void selectExperiment() { - this.selectExperiment(true); - } - - /** - * Selects the experiment. - * @param wait true to wait for indexing to finish else false - */ - public void selectExperiment(final boolean wait) { - fParser = new TmfUml2SDTestTrace(); - fTrace = setupTrace(fParser); - fParser.setTrace(fTrace); - - final ITmfTrace traces[] = new ITmfTrace[1]; - traces[0] = fTrace; - fExperiment = new TmfExperiment(ITmfEvent.class, "TestExperiment", traces) { - @Override - protected ITmfTraceIndexer createIndexer(int interval) { - return new TmfCheckpointIndexer(this, interval); - } - }; - fTrace.broadcast(new TmfTraceOpenedSignal(this, fExperiment, null)); - fTrace.broadcast(new TmfTraceSelectedSignal(this, fExperiment)); - if (wait) { - while (fExperiment.getNbEvents() == 0) { - delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - } - waitForJobs(); - delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - } - } - - /** - * Disposes the experiment. - */ - public void disposeExperiment() { - ITmfTrace trace = fTrace; - TmfExperiment experiment = fExperiment; - if (trace == null || experiment == null) { - throw new IllegalStateException(); - } - trace.broadcast(new TmfTraceClosedSignal(this, experiment)); - experiment.dispose(); - delay(IUml2SDTestConstants.GUI_REFESH_DELAY); - } - - /** - * Creates some global filter criteria and saves them to disk. - */ - public void createFilterCriteria() { - // Create Filter Criteria and save tme - final List filterToSave = new ArrayList<>(); - Criteria criteria = new Criteria(); - criteria.setLifeLineSelected(true); - criteria.setExpression(IUml2SDTestConstants.FIRST_PLAYER_NAME); - filterToSave.add(new FilterCriteria(criteria, true, false)); - - criteria = new Criteria(); - criteria.setSyncMessageSelected(true); - criteria.setExpression("BALL_.*"); - filterToSave.add(new FilterCriteria(criteria, true, false)); - FilterListDialog.saveFiltersCriteria(filterToSave); - } - - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestSetup.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestSetup.java deleted file mode 100644 index 3ea6580ad0..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestSetup.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.loader; - -import junit.extensions.TestSetup; -import junit.framework.Test; - -/** - * Test setup class for one-time setUp() and tearDown() across test cases. - */ -public class Uml2SDTestSetup extends TestSetup { - - /** - * Constructor - * @param test the test to use. - */ - public Uml2SDTestSetup(Test test) { - super(test); - } - - @Override - protected void setUp() throws Exception { - Uml2SDTestFacility.getInstance().init(); - } - - @Override - protected void tearDown() throws Exception { - Uml2SDTestFacility.getInstance().dispose(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestTimestamp.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestTimestamp.java deleted file mode 100644 index 4e7a852190..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestTimestamp.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ui.tests.views.uml2sd.loader; - -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; - -/** - * Timestamp implementation for UML2SD test cases. - * - * @author Bernd Hufmann - * - */ -public class Uml2SDTestTimestamp extends TmfTimestamp { - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructor - * @param value time as long value (nanoseconds) - */ - public Uml2SDTestTimestamp(long value) { - super(value, IUml2SDTestConstants.TIME_SCALE); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/AllTmfUITests.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/AllTmfUITests.java new file mode 100644 index 0000000000..d5c2d35bae --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/AllTmfUITests.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2011-2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Bernd Hufmann - Add UML2SD tests + * Mathieu Denis - Add Statistics test + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Master test suite for TMF UI Core. + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + org.eclipse.tracecompass.tmf.ui.tests.histogram.AllTests.class, + org.eclipse.tracecompass.tmf.ui.tests.project.model.AllTests.class, + org.eclipse.tracecompass.tmf.ui.tests.statistics.AllTests.class, + /* + * Sequence diagram tests disabled during the move to Trace Compass. + * TODO Please fix and re-enable + */ +// org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.dialogs.AllTests.class, +// org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.load.AllTests.class, +// org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.loader.AllTests.class +}) +public class AllTmfUITests { + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/TmfUITestPlugin.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/TmfUITestPlugin.java new file mode 100644 index 0000000000..136b3bee5b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/TmfUITestPlugin.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests; + +import org.eclipse.core.runtime.Plugin; +import org.osgi.framework.BundleContext; + +/** + * TmfUITestPlugin + *

+ * The activator class controls the plug-in life cycle + * + * @author Marc-Andre Laperle + */ +public class TmfUITestPlugin extends Plugin { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The plug-in ID + */ + public static final String PLUGIN_ID = "org.eclipse.tracecompass.tmf.ui.tests"; + + // The shared instance + private static TmfUITestPlugin fPlugin; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * The constructor + */ + public TmfUITestPlugin() { + setDefault(this); + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * @return the shared instance + */ + public static TmfUITestPlugin getDefault() { + return fPlugin; + } + + /** + * @param plugin the shared instance + */ + private static void setDefault(TmfUITestPlugin plugin) { + fPlugin = plugin; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + setDefault(this); + } + + @Override + public void stop(BundleContext context) throws Exception { + setDefault(null); + super.stop(context); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/histogram/AllTests.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/histogram/AllTests.java new file mode 100644 index 0000000000..3da1fede92 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/histogram/AllTests.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.histogram; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite class for histogram tests. + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + HistogramDataModelTest.class +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/histogram/HistogramDataModelTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/histogram/HistogramDataModelTest.java new file mode 100644 index 0000000000..cbb8ab92ff --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/histogram/HistogramDataModelTest.java @@ -0,0 +1,703 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Adapt to junit.framework.TestCase + * Alexandre Montplaisir - Port to JUnit4 + * Patrick Tasse - Support selection range + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.histogram; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.views.histogram.HistogramBucket; +import org.eclipse.tracecompass.tmf.ui.views.histogram.HistogramDataModel; +import org.eclipse.tracecompass.tmf.ui.views.histogram.HistogramScaledData; +import org.eclipse.tracecompass.tmf.ui.views.histogram.IHistogramModelListener; +import org.junit.Test; + +/** + * Unit tests for the HistogramDataModel class. + */ +public class HistogramDataModelTest { + + private static final double DELTA = 1e-15; + + private final static HistogramBucket _0 = new HistogramBucket(new int[] {0}); + private final static HistogramBucket _1 = new HistogramBucket(new int[] {1}); + private final static HistogramBucket _2 = new HistogramBucket(new int[] {2}); + private final static HistogramBucket _4 = new HistogramBucket(new int[] {4}); + private final static HistogramBucket _9 = new HistogramBucket(new int[] {9}); + private final static HistogramBucket _20 = new HistogramBucket(new int[] {20}); + private final static HistogramBucket _24 = new HistogramBucket(new int[] {24}); + + /** + * Test method for {@link HistogramDataModel#HistogramDataModel()}. + */ + @Test + public void testHistogramDataModel() { + HistogramDataModel model = new HistogramDataModel(); + testModelConsistency(model, HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS,0, 1, 0 , 0 , 0 , HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS); + } + + /** + * Test method for {@link HistogramDataModel#HistogramDataModel(HistogramDataModel)}. + */ + @Test + public void testHistogramDataModelCopyConstructor() { + HistogramDataModel model = new HistogramDataModel(); + HistogramDataModel copy = new HistogramDataModel(model); + testModelConsistency(copy, HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS,0, 1, 0 , 0 , 0 , HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS); + } + + /** + * Test method for {@link HistogramDataModel#HistogramDataModel(int)}. + */ + @Test + public void testHistogramDataModelInt() { + final int nbBuckets = 5 * 1000; + HistogramDataModel model = new HistogramDataModel(nbBuckets); + testModelConsistency(model, nbBuckets, 0, 1, 0, 0, 0, nbBuckets); + } + + /** + * Test methods for {@link HistogramDataModel#countEvent(long,long, ITmfTrace)}. + */ + @Test + public void testClear() { + final int nbBuckets = 100; + HistogramDataModel model = new HistogramDataModel(nbBuckets); + model.countEvent(0, -1, null); + + testModelConsistency(model, nbBuckets, 0, 1, 0, 0, 0, nbBuckets); + } + + /** + * Test methods for {@link HistogramDataModel#countEvent(long,long, ITmfTrace)}. + */ + @Test + public void testCountEvent_0() { + final int nbBuckets = 100; + HistogramDataModel model = new HistogramDataModel(nbBuckets); + model.countEvent(0, -1, null); + + testModelConsistency(model, nbBuckets, 0, 1, 0, 0, 0, nbBuckets); + } + + /** + * Test methods for {@link HistogramDataModel#countEvent(long,long, ITmfTrace)} and + * {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testCountEvent_1() { + final int nbBuckets = 100; + final int maxHeight = 10; + + HistogramDataModel model = new HistogramDataModel(nbBuckets); + + HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); + + for (int i = 0; i < result.fData.length; i++) { + assertEquals(_0, result.fData[i]); + } + + testModelConsistency(model, nbBuckets, 0, 1, 0, 0, 0, nbBuckets); + } + + /** + * Test methods for {@link HistogramDataModel#countEvent(long,long, ITmfTrace)} and + * {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testCountEvent_2() { + final int nbBuckets = 100; + final int maxHeight = 10; + + HistogramDataModel model = new HistogramDataModel(nbBuckets); + model.countEvent(0, 1, null); + + HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); + assertEquals(_1, result.fData[0]); + + assertArrayEqualsInt(0, result.fData,1); + + testModelConsistency(model, nbBuckets, 1, 1, 1, 1, 1, nbBuckets + 1); + } + + /** + * Test methods for {@link HistogramDataModel#countEvent(long,long, ITmfTrace)} and + * {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testCountEvent_3() { + final int nbBuckets = 100; + final int maxHeight = 10; + + HistogramDataModel model = new HistogramDataModel(nbBuckets); + countEventsInModel(nbBuckets, model); + + HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); + + assertArrayEqualsInt(1, result.fData); + + testModelConsistency(model, nbBuckets, nbBuckets, 1, 0, 0, nbBuckets - 1, nbBuckets); + } + + /** + * Test methods for {@link HistogramDataModel#countEvent(long,long,ITmfTrace)} and + * {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testCountEvent_4() { + final int nbBuckets = 100; + final int maxHeight = 10; + + HistogramDataModel model = new HistogramDataModel(nbBuckets); + // to different to call elsewhere + for (int i = 0; i < nbBuckets; i++) { + model.countEvent(i, i, null); + model.countEvent(i + 1, i, null); + } + + HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); + + assertArrayEqualsInt(2, result.fData); + + testModelConsistency(model, nbBuckets, 2 * nbBuckets, 1, 0, 0, nbBuckets- 1, nbBuckets); + } + + + /** + * Test methods for {@link HistogramDataModel#countEvent(long,long,ITmfTrace)} and + * {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testCountEvent_5() { + final int nbBuckets = 100; + final int startTime = 25; + final int maxHeight = 10; + + HistogramDataModel model = new HistogramDataModel(nbBuckets); + for (int i = startTime; i < startTime + nbBuckets; i++) { + model.countEvent(i, i, null); + } + + HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); + + assertArrayEqualsInt(1, result.fData); + + testModelConsistency(model, nbBuckets, nbBuckets, 1, startTime, startTime, startTime + nbBuckets- 1, startTime + nbBuckets); + } + + /** + * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testScaleTo_0() { + HistogramDataModel model = new HistogramDataModel(10); + try { + model.scaleTo(10, 0, 1); + } catch (AssertionError e1) { + try { + model.scaleTo(0, 10, 1); + } catch (AssertionError e2) { + try { + model.scaleTo(0, 0, 1); + } catch (AssertionError e3) { + return; + } + } + } + fail("Uncaught assertion error"); + } + + /** + * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testScaleTo_1() { + final int nbBuckets = 10; + final int maxHeight = 10; + final int nbEvents = nbBuckets / 2; + final HistogramBucket[] expectedResult = new HistogramBucket[] { _1, _1, _1, _1, _1, _0, _0, _0, _0, _0 }; + + HistogramDataModel model = new HistogramDataModel(nbBuckets); + countEventsInModel(nbEvents, model); + + HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); + + assertArrayEquals( expectedResult, result.fData); + + testModelConsistency(model, nbBuckets, nbEvents, 1, 0, 0, nbEvents - 1, nbBuckets); + } + + /** + * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testScaleTo_2() { + final int nbBuckets = 10; + final int maxHeight = 10; + final int nbEvents = nbBuckets; + final HistogramBucket[] expectedResult = new HistogramBucket[] { _1, _1, _1, _1, _1, _1, _1, _1, _1, _1 }; + + HistogramDataModel model = new HistogramDataModel(nbBuckets); + countEventsInModel(nbEvents, model); + + HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); + + assertArrayEquals(expectedResult, result.fData); + + testModelConsistency(model, nbBuckets, nbEvents, 1, 0, 0, nbEvents - 1, nbBuckets); + } + + /** + * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testScaleTo_3() { + final int nbBuckets = 10; + final int maxHeight = 10; + final int nbEvents = 2 * nbBuckets; + final HistogramBucket[] expectedResult = new HistogramBucket[] { _2, _2, _2, _2, _2, _2, _2, _2, _2, _2 }; + + HistogramDataModel model = new HistogramDataModel(nbBuckets); + countEventsInModel(nbEvents, model); + + HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); + + assertArrayEquals(expectedResult, result.fData); + + testModelConsistency(model, nbBuckets, nbEvents, 2, 0, 0, nbEvents - 1, 2 * nbBuckets); + } + + /** + * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testScaleTo_4() { + final int nbBuckets = 10; + final int maxHeight = 10; + final int nbEvents = 3 * nbBuckets; + final HistogramBucket[] expectedResult = new HistogramBucket[] { _4, _4, _4, _4, _4, _4, _4, _2, _0, _0 }; + + HistogramDataModel model = new HistogramDataModel(nbBuckets); + countEventsInModel(nbEvents, model); + + HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); + + assertArrayEquals(expectedResult, result.fData); + + testModelConsistency(model, nbBuckets, nbEvents, 4, 0, 0, nbEvents - 1, 4 * nbBuckets); + } + + /** + * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testScaleTo_5() { + final int nbBuckets = 100; + final int maxHeight = 20; + final int nbEvents = 2 * nbBuckets; + final HistogramBucket[] expectedResult = new HistogramBucket[] { _20, _20, _20, _20, _20, _20, _20, _20, _20, _20 }; + + HistogramDataModel model = new HistogramDataModel(nbBuckets); + countEventsInModel(nbEvents, model); + + HistogramScaledData result = model.scaleTo(10, maxHeight, 1); + + assertArrayEquals(expectedResult, result.fData); + + testModelConsistency(model, nbBuckets, nbEvents, 2, 0, 0, nbEvents - 1, 2 * nbBuckets); + } + + /** + * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testScaleTo_6() { + final int nbBuckets = 100; + final int maxHeight = 24; + final int nbEvents = 2 * nbBuckets + 1; + final HistogramBucket[] expectedResult = new HistogramBucket[] { _24, _24, _24, _24, _24, _24, _24, _24, _9, _0 }; + + HistogramDataModel model = new HistogramDataModel(nbBuckets); + countEventsInModel(nbEvents, model); + + HistogramScaledData result = model.scaleTo(10, maxHeight, 1); + + assertArrayEquals(expectedResult, result.fData); + + testModelConsistency(model, nbBuckets, nbEvents, 4, 0, 0, nbEvents - 1, 4 * nbBuckets); + } + + /** + * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testScaleTo_7() { + // verify scaleTo with barWidth > 1 + final int nbBuckets = 100; + final int maxHeight = 24; + final int width = 10; + final int barWidth = 4; + final int nbEvents = 2 * nbBuckets + 1; + + // (int)(width / barWith) = 2 + // -> 2 bars -> expected result needs two buckets (scaled data) + // + // buckets (in model) per bar = last bucket id / nbBars + 1 (plus 1 to + // cover all used buckets) + // -> buckets per bar = 50 / 2 + 1 = 26 + // -> first entry in expected result is 26 * 4 = 104 + // -> second entry in expected result is 22 * 4 + 9 = 97 + final HistogramBucket[] expectedResult = new HistogramBucket[] { new HistogramBucket(new int[] {104}) , new HistogramBucket(new int[] {97}) }; + + HistogramDataModel model = new HistogramDataModel(nbBuckets); + countEventsInModel(nbEvents, model); + + // verify scaled data + HistogramScaledData result = model.scaleTo(width, maxHeight, barWidth); + + assertEquals(4 * 26, result.fBucketDuration); + assertEquals(0, result.fSelectionBeginBucket); + assertEquals(0, result.fSelectionEndBucket); + assertEquals(0, result.fFirstBucketTime); + assertEquals(0, result.fFirstEventTime); + assertEquals(1, result.fLastBucket); + assertEquals(104, result.fMaxValue); + assertEquals((double) maxHeight / 104, result.fScalingFactor, DELTA); + assertEquals(maxHeight, result.fHeight); + assertEquals(width, result.fWidth); + assertEquals(barWidth, result.fBarWidth); + + assertArrayEquals(expectedResult, result.fData); + + // verify model + testModelConsistency(model, nbBuckets, nbEvents, 4, 0, 0, nbEvents - 1, 4 * nbBuckets); + } + + /** + * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testScaleToReverse_1() { + final int nbBuckets = 100; + final int maxHeight = 24; + final int width = 10; + final int barWidth = 1; + final int nbEvents = 2 * nbBuckets + 1; + + // (int)(width / barWith) = 10 + // -> 10 bars -> expected result needs 10 buckets (scaled data) + // + // buckets in (model) per bar = last bucket id / nbBars + 1 (plus 1 to + // cover all used buckets) + // -> buckets per bar = 50 / 10 + 1 = 6 + final HistogramBucket[] expectedResult = new HistogramBucket[] { new HistogramBucket(new int[] {21}), _24, _24, _24, _24, _24, _24, _24, new HistogramBucket(new int[] {12}), _0 }; + + HistogramDataModel model = new HistogramDataModel(nbBuckets); + countInvertedEvents(nbEvents, model); + + // verify scaled data + HistogramScaledData result = model.scaleTo(width, maxHeight, barWidth); + + assertEquals(4 * 6, result.fBucketDuration); + assertEquals(0, result.fSelectionBeginBucket); + assertEquals(0, result.fSelectionEndBucket); + assertEquals(-3, result.fFirstBucketTime); // negative is correct, can + // happen when reverse + assertEquals(0, result.fFirstEventTime); + assertEquals(9, result.fLastBucket); + assertEquals(24, result.fMaxValue); + assertEquals((double) maxHeight / 24, result.fScalingFactor, DELTA); + assertEquals(maxHeight, result.fHeight); + assertEquals(width, result.fWidth); + assertEquals(barWidth, result.fBarWidth); + + assertArrayEquals(expectedResult, result.fData); + + // verify model + testModelConsistency(model, nbBuckets, nbEvents, 4, -3, 0, nbEvents - 1, -3 + 4 * nbBuckets); + } + + private static void countInvertedEvents(final int nbEvents, HistogramDataModel model) { + for (int i = nbEvents - 1; i >= 0; i--) { + model.countEvent(i, i, null); + } + } + + /** + * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testScaleToReverse_2() { + final int nbBuckets = 100; + final int maxHeight = 24; + final int width = 10; + final int barWidth = 1; + + final int nbEvents = 2 * nbBuckets; + + HistogramDataModel model = new HistogramDataModel(nbBuckets); + countEventsInModel(nbEvents, model); + + HistogramScaledData result = model.scaleTo(width, maxHeight, barWidth); + + model.clear(); + + countInvertedEvents(nbEvents, model); + + HistogramScaledData revResult = model.scaleTo(width, maxHeight, barWidth); + + testModelConsistency(model, nbBuckets, nbEvents, 2, 0, 0, nbEvents - 1, 2 * nbBuckets); + + // For the above number of events, result and revResult are exactly the same. + + assertEquals(result.fBucketDuration, revResult.fBucketDuration); + assertEquals(result.fSelectionBeginBucket, revResult.fSelectionBeginBucket); + assertEquals(result.fSelectionEndBucket, revResult.fSelectionEndBucket); + assertEquals(result.fFirstBucketTime, revResult.fFirstBucketTime); + assertEquals(result.fMaxValue, revResult.fMaxValue); + assertEquals(result.fScalingFactor, revResult.fScalingFactor, DELTA); + assertEquals(result.fLastBucket, revResult.fLastBucket); + assertEquals(result.getBucketEndTime(0), revResult.getBucketEndTime(0)); + assertEquals(result.getBucketStartTime(0), revResult.getBucketStartTime(0)); + + assertArrayEquals(revResult.fData, result.fData); + } + + /** + * Test method for testing model listener. + */ + @Test + public void testModelListener() { + final int nbBuckets = 2000; + final int nbEvents = 10 * nbBuckets + 256; + final int[] count = new int[1]; + count[0] = 0; + + // Test add listener and call of listener + IHistogramModelListener listener = new IHistogramModelListener() { + @Override + public void modelUpdated() { + count[0]++; + } + }; + + // Test that the listener interface is called every 16000 events. + HistogramDataModel model = new HistogramDataModel(nbBuckets); + model.addHistogramListener(listener); + + countEventsInModel(nbEvents, model, 1); + + assertEquals(1, count[0]); + + // Test that the listener interface is called when complete is called. + model.complete(); + assertEquals(2, count[0]); + + // Test that clear triggers call of listener interface + model.clear(); + assertEquals(3, count[0]); + + // Test remove listener + count[0] = 0; + model.removeHistogramListener(listener); + + countEventsInModel(nbEvents, model); + model.complete(); + assertEquals(0, count[0]); + } + + /** + * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testLostEventsScaleTo_0() { + final int nbBuckets = 10; + final int maxHeight = 10; + final int nbEvents = 3 * nbBuckets; + final int nbLostEvents_0 = 4; + final int nbLostEvents_1 = 9; + final int nbCombinedEvents = nbEvents + 2; + final HistogramBucket[] expectedResult = new HistogramBucket[] { _4, _4, _4, _4, _4, _4, _4, _2, _0, _0 }; + final int[] expectedLostEventsResult = new int[] { 0, 2, 2, 0, 3, 3, 3, 0, 0, 0 }; + + HistogramDataModel model = new HistogramDataModel(nbBuckets); + countEventsInModel(nbEvents, model); + + final TmfTimeRange timeRange_0 = new TmfTimeRange( + new TmfTimestamp(5L, ITmfTimestamp.NANOSECOND_SCALE), + new TmfTimestamp(10L, ITmfTimestamp.NANOSECOND_SCALE)); + model.countLostEvent(timeRange_0, nbLostEvents_0, false); + + final TmfTimeRange timeRange_1 = new TmfTimeRange( + new TmfTimestamp(18L, ITmfTimestamp.NANOSECOND_SCALE), + new TmfTimestamp(27L, ITmfTimestamp.NANOSECOND_SCALE)); + model.countLostEvent(timeRange_1, nbLostEvents_1, false); + + HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); + + assertArrayEquals(expectedResult, result.fData); + + assertArrayEquals(expectedLostEventsResult, result.fLostEventsData); + + testModelConsistency(model, nbBuckets, nbCombinedEvents, 4, 0, 0, nbEvents - 1, 4 * nbBuckets); + assertEquals(7, result.fMaxCombinedValue); + } + + /** + * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testLostEventsScaleTo_1() { + final int nbBuckets = 10; + final int maxHeight = 10; + final int nbEvents = 3 * nbBuckets; + final int nbLostEvents_0 = 4; + final int nbLostEvents_1 = 9; + final int nbCombinedEvents = nbEvents + 2; + final int[] expectedLostEventsResult = new int[] { 0, 2, 5, 3, 3, 0, 0, 0, 0, 0 }; + + HistogramDataModel model = new HistogramDataModel(nbBuckets); + countEventsInModel(nbEvents, model); + + final TmfTimeRange timeRange_0 = new TmfTimeRange( + new TmfTimestamp(5L, ITmfTimestamp.NANOSECOND_SCALE), + new TmfTimestamp(10L, ITmfTimestamp.NANOSECOND_SCALE)); + model.countLostEvent(timeRange_0, nbLostEvents_0, false); + + final TmfTimeRange timeRange_1 = new TmfTimeRange( + new TmfTimestamp(11L, ITmfTimestamp.NANOSECOND_SCALE), + new TmfTimestamp(18L, ITmfTimestamp.NANOSECOND_SCALE)); + model.countLostEvent(timeRange_1, nbLostEvents_1, false); + + HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); + + assertArrayEquals(expectedLostEventsResult, result.fLostEventsData); + + testModelConsistency(model, nbBuckets, nbCombinedEvents, 4, 0, 0, nbEvents - 1, 4 * nbBuckets); + assertEquals(9, result.fMaxCombinedValue); + } + + /** + * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testLostEventsScaleTo_2() { + final int nbBuckets = 10; + final int maxHeight = 10; + final int nbEvents = 3 * nbBuckets; + final int nbLostEvents_0 = 5; + final int nbLostEvents_1 = 15; + final int nbLostEvents_2 = 2; + final int nbCombinedEvents = nbEvents + 3; + final int[] expectedLostEventsResult = new int[] { 0, 0, 3, 3, 6, 5, 3, 2, 0, 0 }; + + HistogramDataModel model = new HistogramDataModel(nbBuckets); + countEventsInModel(nbEvents, model); + + final TmfTimeRange timeRange_0 = new TmfTimeRange( + new TmfTimestamp(18L, ITmfTimestamp.NANOSECOND_SCALE), + new TmfTimestamp(22L, ITmfTimestamp.NANOSECOND_SCALE)); + model.countLostEvent(timeRange_0, nbLostEvents_0, false); + + final TmfTimeRange timeRange_2 = new TmfTimeRange( + new TmfTimestamp(28L, ITmfTimestamp.NANOSECOND_SCALE), + new TmfTimestamp(29L, ITmfTimestamp.NANOSECOND_SCALE)); + model.countLostEvent(timeRange_2, nbLostEvents_2, false); + + final TmfTimeRange timeRange_1 = new TmfTimeRange( + new TmfTimestamp(11L, ITmfTimestamp.NANOSECOND_SCALE), + new TmfTimestamp(26L, ITmfTimestamp.NANOSECOND_SCALE)); + model.countLostEvent(timeRange_1, nbLostEvents_1, false); + + HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); + + assertArrayEquals(expectedLostEventsResult, result.fLostEventsData ); + + testModelConsistency(model, nbBuckets, nbCombinedEvents, 4, 0, 0, nbEvents - 1, 4 * nbBuckets); + assertEquals(10, result.fMaxCombinedValue); + } + + /** + * Test method for {@link HistogramDataModel#scaleTo(int,int,int)}. + */ + @Test + public void testLostEventsScaleTo_3() { + final int nbBuckets = 10; + final int maxHeight = 10; + final int nbEvents = 3 * nbBuckets; + final int nbLostEvents_0 = 23; + final int nbCombinedEvents = nbEvents + 1; + final int[] expectedLostEventsResult = new int[] { 0, 0, 5, 5, 5, 5, 3, 0, 0, 0 }; + + HistogramDataModel model = new HistogramDataModel(nbBuckets); + countEventsInModel(nbEvents, model); + + final TmfTimeRange timeRange_0 = new TmfTimeRange( + new TmfTimestamp(11L, ITmfTimestamp.NANOSECOND_SCALE), + new TmfTimestamp(26L, ITmfTimestamp.NANOSECOND_SCALE)); + model.countLostEvent(timeRange_0, nbLostEvents_0, false); + + HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1); + + assertArrayEquals(expectedLostEventsResult, result.fLostEventsData ); + + testModelConsistency(model, nbBuckets, nbCombinedEvents, 4, 0, 0, nbEvents - 1, 4 * nbBuckets); + assertEquals(9, result.fMaxCombinedValue); + } + + /* + * helpers + */ + + private static void countEventsInModel(final int nbEvents, HistogramDataModel model) { + countEventsInModel(nbEvents, model, 0); + } + + private static void countEventsInModel(final int nbEvents, HistogramDataModel model, int offset) { + countEventsInModel(nbEvents, model, offset, 0); + } + + private static void countEventsInModel(final int nbEvents, HistogramDataModel model, int offset, int startTime) { + for (int i = startTime; i < nbEvents + startTime; i++) { + model.countEvent(i + offset, i, null); + } + } + + private static void testModelConsistency(HistogramDataModel model, int numberOfBuckets,int nbEvents, int bucketduration,int firstBucketTime, int startTime, int endTime, int timeLimit) { + assertEquals(numberOfBuckets, model.getNbBuckets()); + assertEquals(nbEvents, model.getNbEvents()); + assertEquals(bucketduration, model.getBucketDuration()); + assertEquals(firstBucketTime, model.getFirstBucketTime()); + assertEquals(startTime, model.getStartTime()); + assertEquals(endTime, model.getEndTime()); + assertEquals(timeLimit, model.getTimeLimit()); + } + + private static void assertArrayEqualsInt(final int val , HistogramBucket[] result) { + assertArrayEqualsInt(val, result, 0); + } + + private static void assertArrayEqualsInt(final int val , HistogramBucket[] result, int startVal ) { + for (int i = startVal; i < result.length; i++) { + assertEquals(val, result[i].getNbEvents()); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/AllTests.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/AllTests.java new file mode 100644 index 0000000000..fb89a5fefe --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/AllTests.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.project.model; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for org.eclipse.linuxtools.tmf.ui.project.model + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + ProjectModelAnalysisTest.class, + ProjectModelOutputTest.class, + ProjectModelTraceTest.class, + TraceAndExperimentTypeTest.class +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/ProjectModelAnalysisTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/ProjectModelAnalysisTest.java new file mode 100644 index 0000000000..0a271f8784 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/ProjectModelAnalysisTest.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.project.model; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.util.List; +import java.util.concurrent.TimeoutException; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.project.model.ITmfProjectModelElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfAnalysisElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.tests.shared.ProjectModelTestData; +import org.eclipse.tracecompass.tmf.ui.tests.stubs.analysis.TestAnalysisUi; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Test suite for the {@link TmfAnalysisElement} class. + * + * @author Geneviève Bastien + */ +public class ProjectModelAnalysisTest { + + /** ID of analysis module in UI */ + public static final String MODULE_UI = "org.eclipse.linuxtools.tmf.ui.tests.test"; + private TmfProjectElement fixture; + + /** + * Perform pre-test initialization. + */ + @Before + public void setUp() { + try { + fixture = ProjectModelTestData.getFilledProject(); + } catch (CoreException e) { + fail(e.getMessage()); + } + } + + /** + * Cleans up the project after tests have been executed + */ + @After + public void cleanUp() { + ProjectModelTestData.deleteProject(fixture); + } + + private TmfTraceElement getTraceElement() { + TmfTraceElement trace = null; + for (ITmfProjectModelElement element : fixture.getTracesFolder().getChildren()) { + if (element instanceof TmfTraceElement) { + TmfTraceElement traceElement = (TmfTraceElement) element; + if (traceElement.getName().equals(ProjectModelTestData.getTraceName())) { + trace = traceElement; + } + } + } + assertNotNull(trace); + return trace; + } + + /** + * Test the getAvailableAnalysis() method + */ + @Test + public void testListAnalysis() { + TmfTraceElement trace = getTraceElement(); + + /* Make sure the analysis list is not empty */ + List analysisList = trace.getAvailableAnalysis(); + assertFalse(analysisList.isEmpty()); + + /* Make sure TestAnalysisUi is there */ + TmfAnalysisElement analysis = null; + for (TmfAnalysisElement analysisElement : analysisList) { + if (analysisElement.getAnalysisId().equals(MODULE_UI)) { + analysis = analysisElement; + } + } + assertNotNull(analysis); + + assertEquals("Test analysis in UI", analysis.getName()); + } + + /** + * Test if the list of available analysis is correctly populated by the + * content provider + */ + @Test + public void testPopulate() { + TmfTraceElement trace = getTraceElement(); + + /* Make sure the analysis list is not empty */ + List analysisList = trace.getChildren(); + assertFalse(analysisList.isEmpty()); + + /* Make sure TestAnalysisUi is there */ + TmfAnalysisElement analysis = null; + for (ITmfProjectModelElement element : analysisList) { + if (element instanceof TmfAnalysisElement) { + TmfAnalysisElement analysisElement = (TmfAnalysisElement) element; + if (analysisElement.getAnalysisId().equals(MODULE_UI)) { + analysis = analysisElement; + } + } + } + assertNotNull(analysis); + + assertEquals("Test analysis in UI", analysis.getName()); + } + + /** + * Test the instantiateAnalysis method + */ + @Test + public void testInstantiate() { + TmfTraceElement traceElement = getTraceElement(); + + TmfAnalysisElement analysis = null; + for (TmfAnalysisElement analysisElement : traceElement.getAvailableAnalysis()) { + if (analysisElement.getAnalysisId().equals(MODULE_UI)) { + analysis = analysisElement; + } + } + assertNotNull(analysis); + + /* Instantiate an analysis on a trace that is closed */ + traceElement.closeEditors(); + analysis.activateParent(); + + try { + ProjectModelTestData.delayUntilTraceOpened(traceElement); + } catch (TimeoutException e) { + fail("The analysis parent did not open in a reasonable time"); + } + ITmfTrace trace = traceElement.getTrace(); + + assertNotNull(trace); + TestAnalysisUi module = (TestAnalysisUi) trace.getAnalysisModule(analysis.getAnalysisId()); + assertNotNull(module); + + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/ProjectModelOutputTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/ProjectModelOutputTest.java new file mode 100644 index 0000000000..499fc73351 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/ProjectModelOutputTest.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.project.model; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.List; +import java.util.concurrent.TimeoutException; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.tracecompass.tmf.ui.project.model.ITmfProjectModelElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfAnalysisElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfAnalysisOutputElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.tests.shared.ProjectModelTestData; +import org.eclipse.tracecompass.tmf.ui.tests.stubs.analysis.TestAnalysisUi; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Test suite for the {@link TmfAnalysisOutputElement} class. + * + * @author Geneviève Bastien + */ +public class ProjectModelOutputTest { + + private TmfProjectElement fixture; + + /** + * Perform pre-test initialization. + */ + @Before + public void setUp() { + try { + fixture = ProjectModelTestData.getFilledProject(); + } catch (CoreException e) { + fail(e.getMessage()); + } + } + + /** + * Cleans up the project after tests have been executed + */ + @After + public void cleanUp() { + ProjectModelTestData.deleteProject(fixture); + } + + private TmfTraceElement getTraceElement() { + TmfTraceElement trace = null; + for (ITmfProjectModelElement element : fixture.getTracesFolder().getChildren()) { + if (element instanceof TmfTraceElement) { + TmfTraceElement traceElement = (TmfTraceElement) element; + if (traceElement.getName().equals(ProjectModelTestData.getTraceName())) { + trace = traceElement; + } + } + } + assertNotNull(trace); + return trace; + } + + private TmfAnalysisElement getTestAnalysisUi() { + TmfTraceElement trace = getTraceElement(); + + /* Make sure the analysis list is not empty */ + List analysisList = trace.getAvailableAnalysis(); + assertFalse(analysisList.isEmpty()); + + /* Make sure TestAnalysisUi is there */ + TmfAnalysisElement analysis = null; + for (TmfAnalysisElement analysisElement : analysisList) { + if (analysisElement.getAnalysisId().equals(ProjectModelAnalysisTest.MODULE_UI)) { + analysis = analysisElement; + } + } + assertNotNull(analysis); + return analysis; + } + + /** + * Test the getAvailableOutputs() method + */ + @Test + public void testListOutputs() { + TmfAnalysisElement analysis = getTestAnalysisUi(); + + /* To get the list of outputs the trace needs to be opened */ + analysis.activateParent(); + try { + ProjectModelTestData.delayUntilTraceOpened(analysis.getParent()); + } catch (TimeoutException e) { + fail("The analysis parent did not open in a reasonable time"); + } + + /* Make sure the output list is not empty */ + List outputList = analysis.getAvailableOutputs(); + assertFalse(outputList.isEmpty()); + boolean found = false; + for (ITmfProjectModelElement element : outputList) { + if (element instanceof TmfAnalysisOutputElement) { + TmfAnalysisOutputElement outputElement = (TmfAnalysisOutputElement) element; + if (outputElement.getName().equals("Test Analysis View")) { + found = true; + } + } + } + assertTrue(found); + } + + /** + * Test the outputAnalysis method for a view + */ + @Test + public void testOpenView() { + TmfAnalysisElement analysis = getTestAnalysisUi(); + + analysis.activateParent(); + try { + ProjectModelTestData.delayUntilTraceOpened(analysis.getParent()); + } catch (TimeoutException e) { + fail("The analysis parent did not open in a reasonable time"); + } + + List outputList = analysis.getAvailableOutputs(); + assertFalse(outputList.isEmpty()); + + final IWorkbench wb = PlatformUI.getWorkbench(); + final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); + + IViewPart view = activePage.findView(TestAnalysisUi.VIEW_ID); + if (view != null) { + activePage.hideView(view); + } + + TmfAnalysisOutputElement outputElement = null; + for (ITmfProjectModelElement element : outputList) { + if (element instanceof TmfAnalysisOutputElement) { + TmfAnalysisOutputElement el = (TmfAnalysisOutputElement) element; + if (el.getName().equals("Test Analysis View")) { + outputElement = el; + } + } + } + assertNotNull(outputElement); + + outputElement.outputAnalysis(); + ProjectModelTestData.delayThread(1000); + view = activePage.findView(TestAnalysisUi.VIEW_ID); + assertNotNull(view); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/ProjectModelTraceTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/ProjectModelTraceTest.java new file mode 100644 index 0000000000..0cd9c1e3a2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/ProjectModelTraceTest.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.project.model; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.concurrent.TimeoutException; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfOpenTraceHelper; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.tests.shared.ProjectModelTestData; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Test suite for the TmfTraceElement class. + * + * @author Geneviève Bastien + */ +public class ProjectModelTraceTest { + + private TmfProjectElement fixture; + + /** + * Perform pre-test initialization. + */ + @Before + public void setUp() { + try { + fixture = ProjectModelTestData.getFilledProject(); + } catch (CoreException e) { + fail(e.getMessage()); + } + } + + /** + * Cleans up the project after tests have been executed + */ + @After + public void cleanUp() { + ProjectModelTestData.deleteProject(fixture); + } + + /** + * Test the getTrace() and trace opening + */ + @Test + public void testOpenTrace() { + assertNotNull(fixture); + + final TmfTraceElement traceElement = fixture.getTracesFolder().getTraces().get(0); + + /* + * Get the trace from the element, it is not opened yet, should be null + */ + ITmfTrace trace = traceElement.getTrace(); + assertNull(trace); + + TmfOpenTraceHelper.openTraceFromElement(traceElement); + + /* Give the trace a chance to open */ + try { + ProjectModelTestData.delayUntilTraceOpened(traceElement); + } catch (TimeoutException e) { + fail("The trace did not open in a reasonable delay"); + } + + trace = traceElement.getTrace(); + assertNotNull(trace); + + /* + * Open the trace from project, then get from element, both should be + * the exact same element as the active trace + */ + TmfOpenTraceHelper.openTraceFromElement(traceElement); + try { + ProjectModelTestData.delayUntilTraceOpened(traceElement); + } catch (TimeoutException e) { + fail("The trace did not open in a reasonable delay"); + } + + ITmfTrace trace2 = TmfTraceManager.getInstance().getActiveTrace(); + + /* The trace was reopened, it should be the same as before */ + assertTrue(trace2 == trace); + + /* Here, the getTrace() should return the same as active trace */ + trace = traceElement.getTrace(); + assertTrue(trace2 == trace); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/TraceAndExperimentTypeTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/TraceAndExperimentTypeTest.java new file mode 100644 index 0000000000..20a6020a10 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/project/model/TraceAndExperimentTypeTest.java @@ -0,0 +1,199 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.project.model; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.concurrent.TimeoutException; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfExperimentStub; +import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfOpenTraceHelper; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; +import org.eclipse.tracecompass.tmf.ui.tests.experiment.type.TmfEventsEditorStub; +import org.eclipse.tracecompass.tmf.ui.tests.shared.ProjectModelTestData; +import org.eclipse.tracecompass.tmf.ui.viewers.events.TmfEventsTable; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Some unit tests for trace types and experiment types + * + * @author Geneviève Bastien + */ +public class TraceAndExperimentTypeTest { + + /** Test experiment type id */ + public final static String TEST_EXPERIMENT_TYPE = "org.eclipse.linuxtools.tmf.core.tests.experimenttype"; + + private TmfProjectElement fixture; + private TmfExperimentElement fExperiment; + private final String EXPERIMENT_NAME = "exp_test"; + + /** + * Perform pre-test initialization. + */ + @Before + public void setUp() { + try { + fixture = ProjectModelTestData.getFilledProject(); + fExperiment = ProjectModelTestData.addExperiment(fixture, EXPERIMENT_NAME); + assertNotNull(fExperiment); + } catch (CoreException e) { + fail(e.getMessage()); + } + } + + /** + * Cleans up the project after tests have been executed + */ + @After + public void cleanUp() { + ProjectModelTestData.deleteProject(fixture); + } + + /** + * Test whether a newly created experiment has the default experiment type, + * even though none was specified + */ + @Test + public void testDefaultExperimentType() { + TmfExperimentElement experimentElement = ProjectModelTestData.addExperiment(fixture, "testDefaultExpType"); + assertNotNull(experimentElement); + TmfExperiment experiment = experimentElement.instantiateTrace(); + assertNotNull(experiment); + assertEquals(TmfTraceType.DEFAULT_EXPERIMENT_TYPE, experimentElement.getTraceType()); + } + + /** + * Test that the experiment opened is of the right class + */ + @Test + public void testExperimentType() { + + IResource resource = fExperiment.getResource(); + try { + resource.setPersistentProperty(TmfCommonConstants.TRACETYPE, TEST_EXPERIMENT_TYPE); + fExperiment.refreshTraceType(); + } catch (CoreException e) { + fail(e.getMessage()); + } + + TmfOpenTraceHelper.openTraceFromElement(fExperiment); + try { + ProjectModelTestData.delayUntilTraceOpened(fExperiment); + } catch (TimeoutException e1) { + fail (e1.getMessage()); + } + + ITmfTrace trace = fExperiment.getTrace(); + assertTrue(trace instanceof TmfExperimentStub); + } + + /** + * Test that event editor, event table and statistics viewer are the default + * ones for a generic experiment + */ + @Test + public void testNoExperimentTypeChildren() { + TmfOpenTraceHelper.openTraceFromElement(fExperiment); + + try { + ProjectModelTestData.delayUntilTraceOpened(fExperiment); + } catch (TimeoutException e1) { + fail (e1.getMessage()); + } + + final IWorkbench wb = PlatformUI.getWorkbench(); + final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); + IEditorPart editor = activePage.getActiveEditor(); + + /* Test the editor class. Cannot test table class since it is unexposed */ + assertNotNull(editor); + assertTrue(editor.getClass().equals(TmfEventsEditor.class)); + } + + /** + * Test that event editor, event table and statistics viewer are built + * correctly when specified + */ + @Test + public void testExperimentTypeChildren() { + + /* Set the trace type of the experiment */ + IResource resource = fExperiment.getResource(); + try { + resource.setPersistentProperty(TmfCommonConstants.TRACETYPE, TEST_EXPERIMENT_TYPE); + fExperiment.refreshTraceType(); + } catch (CoreException e) { + fail(e.getMessage()); + } + + TmfOpenTraceHelper.openTraceFromElement(fExperiment); + + ProjectModelTestData.delayThread(500); + + /* Test the editor class */ + final IWorkbench wb = PlatformUI.getWorkbench(); + final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); + IEditorPart editor = activePage.getActiveEditor(); + + assertNotNull(editor); + assertTrue(editor.getClass().equals(TmfEventsEditorStub.class)); + + /* Test the event table class */ + TmfEventsEditorStub editorStub = (TmfEventsEditorStub) editor; + TmfEventsTable table = editorStub.getNewEventsTable(); + + assertNotNull(table); + assertTrue(table.getClass().equals(TmfEventsTable.class)); + + } + + /** + * Test that the analysis get populated under an experiment of the proper type + */ + @Test + public void testExperimentTypeAnalysis() { + + /* Set the trace type of the experiment */ + IResource resource = fExperiment.getResource(); + try { + resource.setPersistentProperty(TmfCommonConstants.TRACETYPE, TEST_EXPERIMENT_TYPE); + fExperiment.refreshTraceType(); + } catch (CoreException e) { + fail(e.getMessage()); + } + + /* Force the refresh of the experiment */ + fExperiment.getParent().refresh(); + assertFalse(fExperiment.getAvailableAnalysis().isEmpty()); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/AllTests.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/AllTests.java new file mode 100644 index 0000000000..aaa97a7dff --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/AllTests.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial API and Implementation + * Bernd Hufmann - Fixed suite name + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.statistics; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for statistic tests. + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TmfBaseColumnDataProviderTest.class, + TmfBaseColumnDataTest.class, + TmfBaseStatisticsDataTest.class, + TmfStatisticsTest.class, + TmfStatisticsTreeNodeTest.class, + TmfStatisticsTreeManagerTest.class, + TmfTreeContentProviderTest.class +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfBaseColumnDataProviderTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfBaseColumnDataProviderTest.java new file mode 100644 index 0000000000..ff6f844028 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfBaseColumnDataProviderTest.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial API and Implementation + * Bernd Hufmann - Fixed header and warnings + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.statistics; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.Messages; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfBaseColumnData; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfBaseColumnDataProvider; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTree; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfBaseColumnData.ITmfColumnPercentageProvider; +import org.junit.Test; + +/** + * TmfBaseColumnDataProvider test cases. + * + */ +public class TmfBaseColumnDataProviderTest { + + // ------------------------------------------------------------------------ + // Fields + // ------------------------------------------------------------------------ + + private static final double DELTA = 1e-15; + + private final static String LEVEL_COLUMN = Messages.TmfStatisticsView_LevelColumn; + private final static String EVENTS_COUNT_COLUMN = Messages.TmfStatisticsView_NbEventsColumn; + + private TmfBaseColumnDataProvider provider; + + private static final String fTestName = "ColumnDataProviderTest"; + + private final String fContext = "UnitTest"; + + private final String fTypeId1 = "Some type1"; + private final String fTypeId2 = "Some type2"; + + private final String fLabel0 = "label1"; + private final String fLabel1 = "label2"; + private final String fLabel2 = "label3"; + private final String[] fLabels = new String[] { fLabel0, fLabel1, fLabel2 }; + + private final TmfTimestamp fTimestamp1 = new TmfTimestamp(12345, (byte) 2, 5); + private final TmfTimestamp fTimestamp2 = new TmfTimestamp(12350, (byte) 2, 5); + private final TmfTimestamp fTimestamp3 = new TmfTimestamp(12355, (byte) 2, 5); + + private final String fSource = "Source"; + + private final TmfEventType fType1 = new TmfEventType(fContext, fTypeId1, TmfEventField.makeRoot(fLabels)); + private final TmfEventType fType2 = new TmfEventType(fContext, fTypeId1, TmfEventField.makeRoot(fLabels)); + private final TmfEventType fType3 = new TmfEventType(fContext, fTypeId2, TmfEventField.makeRoot(fLabels)); + + private final String fReference = "Some reference"; + + private final ITmfEvent fEvent1; + private final ITmfEvent fEvent2; + private final ITmfEvent fEvent3; + + private final TmfEventField fContent1; + private final TmfEventField fContent2; + private final TmfEventField fContent3; + + private final TmfStatisticsTree fStatsData; + + // ------------------------------------------------------------------------ + // Housekeeping + // ------------------------------------------------------------------------ + + /** + * Constructor + */ + public TmfBaseColumnDataProviderTest() { + fContent1 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some content", null); + fEvent1 = new TmfEvent(null, fTimestamp1, fSource, fType1, fContent1, fReference); + + fContent2 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some other content", null); + fEvent2 = new TmfEvent(null, fTimestamp2, fSource, fType2, fContent2, fReference); + + fContent3 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some other different content", null); + fEvent3 = new TmfEvent(null, fTimestamp3, fSource, fType3, fContent3, fReference); + + fStatsData = new TmfStatisticsTree(); + + fStatsData.getOrCreateNode(fTestName, Messages.TmfStatisticsData_EventTypes); + + fStatsData.setTotal(fTestName, true, 3); + fStatsData.setTypeCount(fTestName, fEvent1.getType().getName(), true, 1); + fStatsData.setTypeCount(fTestName, fEvent2.getType().getName(), true, 1); + fStatsData.setTypeCount(fTestName, fEvent3.getType().getName(), true, 1); + + provider = new TmfBaseColumnDataProvider(); + } + + // ------------------------------------------------------------------------ + // Get Column Data + // ------------------------------------------------------------------------ + + /** + * Method with test cases. + */ + @Test + public void testGetColumnData() { + List columnsData = provider.getColumnData(); + assertNotNull("getColumnData", columnsData); + assertEquals("getColumnData", 4, columnsData.size()); + + TmfStatisticsTreeNode parentNode = fStatsData.getNode(fTestName); + TmfStatisticsTreeNode treeNode1 = fStatsData.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fEvent1.getType().getName()); + TmfStatisticsTreeNode treeNode2 = fStatsData.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fEvent3.getType().getName()); + ViewerComparator vComp = null; + for (TmfBaseColumnData columnData : columnsData) { + assertNotNull("getColumnData", columnData); + assertNotNull("getColumnData", columnData.getHeader()); + assertNotNull("getColumnData", columnData.getTooltip()); + + // Testing labelProvider + ColumnLabelProvider labelProvider = columnData.getLabelProvider(); + if (columnData.getHeader().compareTo(LEVEL_COLUMN) == 0) { + assertEquals("getColumnData", 0, labelProvider.getText(treeNode1).compareTo(treeNode1.getName())); + } else if (columnData.getHeader().compareTo(EVENTS_COUNT_COLUMN) == 0) { + // might not work because of machine local number format + assertEquals("getColumnData", "1", labelProvider.getText(treeNode1)); + } + + // Testing comparator + vComp = columnData.getComparator(); + if (columnData.getHeader().compareTo(LEVEL_COLUMN) == 0) { + assertTrue("getColumnData", vComp.compare(null, treeNode1, treeNode2) < 0); + assertTrue("getColumnData", vComp.compare(null, treeNode2, treeNode1) > 0); + assertTrue("getColumnData", vComp.compare(null, treeNode1, treeNode1) == 0); + } else if (columnData.getHeader().compareTo(EVENTS_COUNT_COLUMN) == 0) { + assertTrue("getColumnData", vComp.compare(null, treeNode1, treeNode2) == 0); + assertTrue("getColumnData", vComp.compare(null, treeNode2, treeNode1) == 0); + assertTrue("getColumnData", vComp.compare(null, treeNode1, treeNode1) == 0); + } + + // Testing percentage provider + ITmfColumnPercentageProvider percentProvider = columnData.getPercentageProvider(); + if (columnData.getHeader().compareTo(LEVEL_COLUMN) == 0) { + assertNull("getColumnData", percentProvider); + } else if (columnData.getHeader().compareTo(EVENTS_COUNT_COLUMN) == 0) { + double percentage = (double) treeNode1.getValues().getTotal() / parentNode.getValues().getTotal(); + assertEquals("getColumnData", percentage, percentProvider.getPercentage(treeNode1), DELTA); + } + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfBaseColumnDataTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfBaseColumnDataTest.java new file mode 100755 index 0000000000..214ded22fb --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfBaseColumnDataTest.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial design and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.statistics; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfBaseColumnData; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTree; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfBaseColumnData.ITmfColumnPercentageProvider; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; +import org.junit.Before; +import org.junit.Test; + +/** + * TmfBaseColumnData Test Case. + */ +public class TmfBaseColumnDataTest { + + // ------------------------------------------------------------------------ + // Fields + // ------------------------------------------------------------------------ + + private int fAlignment; + private int fWidth; + private String fHeader; + private String fToolTip; + private ColumnLabelProvider fLabelProvider; + private ViewerComparator fComparator; + private ITmfColumnPercentageProvider fPercentageProvider; + private TmfStatisticsTreeNode fTreeNode; + private String fTraceName; + private TmfBaseColumnData fBaseColumnData; + + // ------------------------------------------------------------------------ + // Housekeeping + // ------------------------------------------------------------------------ + + /** + * Pre-test setup + */ + @Before + public void init() { + fHeader = "test Column1"; + fWidth = 300; + fAlignment = SWT.LEFT; + fToolTip = "Tooltip " + fHeader; + fLabelProvider = new ColumnLabelProvider() { + @Override + public String getText(Object element) { + return ((TmfStatisticsTreeNode) element).getName(); + } + + @Override + public Image getImage(Object element) { + return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT); + } + }; + fComparator = new ViewerComparator() { + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + TmfStatisticsTreeNode n1 = (TmfStatisticsTreeNode) e1; + TmfStatisticsTreeNode n2 = (TmfStatisticsTreeNode) e2; + + return n1.getName().compareTo(n2.getName()); + } + }; + fPercentageProvider = new ITmfColumnPercentageProvider() { + @Override + public double getPercentage(TmfStatisticsTreeNode node) { + TmfStatisticsTreeNode parent = node; + do { + parent = parent.getParent(); + } while (parent != null && parent.getValues().getTotal() == 0); + + if (parent == null) { + return 0; + } + return (double) node.getValues().getTotal() / parent.getValues().getTotal(); + } + }; + + TmfStatisticsTree baseData = new TmfStatisticsTree(); + fTraceName = "trace1"; + fTreeNode = new TmfStatisticsTreeNode(baseData, baseData.getRootNode(), fTraceName); + + fBaseColumnData = new TmfBaseColumnData(fHeader, fWidth, fAlignment, fToolTip, fLabelProvider, fComparator, fPercentageProvider); + } + + // ------------------------------------------------------------------------ + // Test methods + // ------------------------------------------------------------------------ + + /** + * Test get header + */ + @Test + public void testGetHeader() { + assertEquals("getHeader", 0, fBaseColumnData.getHeader().compareTo(fHeader)); + } + + /** + * Test getting of column width. + */ + @Test + public void testGetWidth() { + assertEquals("getWidth", fWidth, fBaseColumnData.getWidth()); + } + + /** + * Test getting of alignment value + */ + @Test + public void testGetAlignment() { + assertEquals("getAlignment", fAlignment, fBaseColumnData.getAlignment()); + } + + /** + * Test getting of tooltip. + */ + @Test + public void testGetTooltip() { + assertEquals("getTooltip", fToolTip, fBaseColumnData.getTooltip()); + } + + /** + * Test getting of label provider + */ + @Test + public void testGetLabelProvider() { + assertEquals("getLabelProvider", 0, fBaseColumnData.getLabelProvider().getText(fTreeNode).compareTo(fLabelProvider.getText(fTreeNode))); + assertTrue("getLabelProvider", fBaseColumnData.getLabelProvider().getImage(fTreeNode).equals(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT))); + assertTrue("getLabelProvider", fBaseColumnData.getLabelProvider().equals(fLabelProvider)); + } + + /** + * Test getting of comparator. + */ + @Test + public void testGetComparator() { + assertTrue("getComparator", fBaseColumnData.getComparator().equals(fComparator)); + } + + /** + * Test getting of percentage provider. + */ + @Test + public void testGetPercentageProvider() { + assertTrue("getPercentageProvider", fBaseColumnData.getPercentageProvider().equals(fPercentageProvider)); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfBaseStatisticsDataTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfBaseStatisticsDataTest.java new file mode 100755 index 0000000000..7a1ea5bd19 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfBaseStatisticsDataTest.java @@ -0,0 +1,238 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial design and implementation + * Bernd Hufmann - Fixed warnings + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.statistics; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.Vector; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.Messages; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTree; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode; +import org.junit.Test; + +/** + * TmfBaseStatistics Test Cases. + */ +public class TmfBaseStatisticsDataTest { + + // ------------------------------------------------------------------------ + // Fields + // ------------------------------------------------------------------------ + + private static final String fTestName = "StatisticsDataTest"; + + private final String fContext = "UnitTest"; + private final String fTypeId1 = "Some type1"; + private final String fTypeId2 = "Some type2"; + + private final String fLabel0 = "label1"; + private final String fLabel1 = "label2"; + private final String fLabel2 = "label3"; + private final String[] fLabels = new String[] { fLabel0, fLabel1, fLabel2 }; + + private final TmfTimestamp fTimestamp1 = new TmfTimestamp(12345, (byte) 2, 5); + private final TmfTimestamp fTimestamp2 = new TmfTimestamp(12350, (byte) 2, 5); + private final TmfTimestamp fTimestamp3 = new TmfTimestamp(12355, (byte) 2, 5); + + private final String fSource = "Source"; + + private final TmfEventType fType1 = new TmfEventType(fContext, fTypeId1, TmfEventField.makeRoot(fLabels)); + private final TmfEventType fType2 = new TmfEventType(fContext, fTypeId1, TmfEventField.makeRoot(fLabels)); + private final TmfEventType fType3 = new TmfEventType(fContext, fTypeId2, TmfEventField.makeRoot(fLabels)); + + private final String fReference = "Some reference"; + + private final ITmfEvent fEvent1; + private final ITmfEvent fEvent2; + private final ITmfEvent fEvent3; + + private final TmfEventField fContent1; + private final TmfEventField fContent2; + private final TmfEventField fContent3; + + private final TmfStatisticsTree fStatsTree; + + // ------------------------------------------------------------------------ + // Housekeeping + // ------------------------------------------------------------------------ + + /** + * Constructor + */ + public TmfBaseStatisticsDataTest() { + fContent1 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some content", null); + fEvent1 = new TmfEvent(null, fTimestamp1, fSource, fType1, fContent1, fReference); + + fContent2 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some other content", null); + fEvent2 = new TmfEvent(null, fTimestamp2, fSource, fType2, fContent2, fReference); + + fContent3 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some other different content", null); + fEvent3 = new TmfEvent(null, fTimestamp3, fSource, fType3, fContent3, fReference); + + fStatsTree = new TmfStatisticsTree(); + + fStatsTree.setTotal(fTestName, true, 3); + fStatsTree.setTypeCount(fTestName, fEvent1.getType().getName(), true, 1); + fStatsTree.setTypeCount(fTestName, fEvent2.getType().getName(), true, 1); + fStatsTree.setTypeCount(fTestName, fEvent3.getType().getName(), true, 1); + } + + // ------------------------------------------------------------------------ + // Test methods + // ------------------------------------------------------------------------ + + /** + * Test getting of children. + */ + @Test + public void testGetChildren() { + // Getting children of the ROOT + Collection childrenTreeNode = fStatsTree.getRootNode().getChildren(); + assertEquals("getChildren", 1, childrenTreeNode.size()); + TmfStatisticsTreeNode treeNode = childrenTreeNode.iterator().next(); + assertEquals("getChildren", fTestName, treeNode.getName()); + + // Getting children of the trace + childrenTreeNode = fStatsTree.getNode(fTestName).getChildren(); + assertEquals("getChildren", 1, childrenTreeNode.size()); + treeNode = childrenTreeNode.iterator().next(); + assertEquals("getChildren", Messages.TmfStatisticsData_EventTypes, treeNode.getName()); + + Vector keyExpected = new Vector<>(); + keyExpected.add(fEvent1.getType().getName()); + keyExpected.add(fEvent3.getType().getName()); + // Getting children of a category + childrenTreeNode = treeNode.getChildren(); + assertEquals("getChildren", 2, childrenTreeNode.size()); + + Iterator iterChild = childrenTreeNode.iterator(); + TmfStatisticsTreeNode temp; + while (iterChild.hasNext()) { + temp = iterChild.next(); + assertEquals(0, temp.getChildren().size()); + if (keyExpected.contains(temp.getName())) { + keyExpected.removeElement(temp.getName()); + } else { + fail(); + } + } + + // Get children of a specific event type + childrenTreeNode = childrenTreeNode.iterator().next().getChildren(); + assertEquals("getChildren", 0, childrenTreeNode.size()); + } + + /** + * Test registering of events. + */ + @Test + public void testRegisterEvent() { + TmfStatisticsTreeNode trace = fStatsTree.getNode(fTestName); + assertEquals("registerEvent", 3, trace.getValues().getTotal()); + + Collection childrenTreeNode = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes).getChildren(); + for (TmfStatisticsTreeNode child : childrenTreeNode) { + if (child.getName().compareTo(fEvent1.getType().getName()) == 0) { + assertEquals("registerEvent", 1, child.getValues().getTotal()); + } else if (child.getName().compareTo(fEvent3.getType().getName()) == 0) { + assertEquals("registerEvent", 1, child.getValues().getTotal()); + } + } + } + + /** + * Test getter. + */ + @Test + public void testGet() { + TmfStatisticsTreeNode traceRoot = fStatsTree.getNode(fTestName); + assertNotNull("get", traceRoot); + assertEquals("get", 0, traceRoot.getPath()[0].compareTo(fTestName)); + assertEquals("get", 3, traceRoot.getValues().getTotal()); + assertEquals("get", 1, traceRoot.getNbChildren()); + } + + /** + * Test getting or creating of node entries. + */ + @Test + public void testGetOrCreate() { + String[] newEventType = new String[] { fTestName, Messages.TmfStatisticsData_EventTypes, "Fancy Type" }; + TmfStatisticsTreeNode newEventTypeNode; + + // newEventType is not in the tree + newEventTypeNode = fStatsTree.getNode(newEventType); + assertNull(newEventTypeNode); + + newEventTypeNode = fStatsTree.getOrCreateNode(newEventType); + assertNotNull(newEventTypeNode); + assertTrue(Arrays.equals(newEventType, newEventTypeNode.getPath())); + + // newEventType is in the tree + newEventTypeNode.reset(); + newEventTypeNode = fStatsTree.getNode(newEventType); + assertNotNull(newEventTypeNode); + + newEventTypeNode = fStatsTree.getOrCreateNode(newEventType); + assertNotNull(newEventTypeNode); + assertTrue(Arrays.equals(newEventType, newEventTypeNode.getPath())); + } + + /** + * Test getting of parent node. + */ + @Test + public void testGetParent() { + TmfStatisticsTreeNode parentNode = fStatsTree.getRootNode().getParent(); + assertNull(parentNode); + + parentNode = fStatsTree.getNode(fTestName).getParent(); + assertNotNull(parentNode); + assertEquals(parentNode.getPath().toString(), fStatsTree.getRootNode().getPath().toString()); + + parentNode = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes).getParent(); + assertNotNull(parentNode); + assertEquals(parentNode.getPath().toString(), fStatsTree.getNode(fTestName).getPath().toString()); + } + + /** + * Test reset method + */ + @Test + public void testReset() { + fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes).reset(); + + assertEquals(0, fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes).getChildren().size()); + assertNull(fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fType1.getName())); + assertNull(fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fType3.getName())); + + fStatsTree.getNode(fTestName).reset(); + assertEquals(0, fStatsTree.getNode(fTestName).getChildren().size()); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfStatisticsTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfStatisticsTest.java new file mode 100644 index 0000000000..631389aefe --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfStatisticsTest.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.statistics; + +import static org.junit.Assert.assertEquals; + +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsValues; +import org.junit.Test; + +/** + * TmfStatistics Test Cases. + */ +public class TmfStatisticsTest { + + private TmfStatisticsValues stats = new TmfStatisticsValues(); + + /** + * Test the initial state of the counters + */ + @Test + public void testInitialState() { + assertEquals(0, stats.getTotal()); + assertEquals(0, stats.getPartial()); + } + + /** + * Test incrementing the total counter by an amount + */ + @Test + public void testSetValue() { + final int i = 100; + + /* Set the Global counter */ + stats.setValue(true, i); + assertEquals(i, stats.getTotal()); + // Try to assign a negative number. Should do nothing. + stats.setValue(true, -10); + assertEquals(i, stats.getTotal()); + // Checks if the partial counter was affected + assertEquals(0, stats.getPartial()); + + /* Set the time range counter */ + stats.resetTotalCount(); + stats.setValue(false, i); + assertEquals(i, stats.getPartial()); + // Try to assign a negative number. Should do nothing. + stats.setValue(false, -10); + assertEquals(i, stats.getPartial()); + // Checks if the total counter was affected + assertEquals(0, stats.getTotal()); + } + + /** + * Test of the reset for the total counter + */ + @Test + public void testResetTotal() { + stats.setValue(true, 123); + assertEquals(123, stats.getTotal()); + + stats.resetTotalCount(); + assertEquals(0, stats.getTotal()); + + // test when already at 0 + stats.resetTotalCount(); + assertEquals(0, stats.getTotal()); + } + + /** + * Test of the reset for the partial counter + */ + @Test + public void testResetPartial() { + stats.setValue(false, 456); + assertEquals(456, stats.getPartial()); + + stats.resetPartialCount(); + assertEquals(0, stats.getPartial()); + + // test when already at 0 + stats.resetPartialCount(); + assertEquals(0, stats.getPartial()); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfStatisticsTreeManagerTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfStatisticsTreeManagerTest.java new file mode 100755 index 0000000000..ea905e863e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfStatisticsTreeManagerTest.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial design and implementation + * Bernd Hufmann - Fixed warnings + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.statistics; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTree; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTreeManager; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode; +import org.junit.Before; +import org.junit.Test; + +/** + * TmfStatisticsTreeRootFactory Test Case. + */ +public class TmfStatisticsTreeManagerTest { + + // ------------------------------------------------------------------------ + // Fields + // ------------------------------------------------------------------------ + + private TmfStatisticsTree fStatisticsData1; + private TmfStatisticsTree fStatisticsData2; + private TmfStatisticsTree fStatisticsData3; + private String fDataKey1 = "key1"; + private String fDataKey2 = "key2"; + private String fDataKey3 = "key3"; + + + // ------------------------------------------------------------------------ + // Housekeeping + // ------------------------------------------------------------------------ + + /** + * Initialization + */ + @Before + public void setUp() { + fStatisticsData1 = new TmfStatisticsTree(); + fStatisticsData2 = new TmfStatisticsTree(); + fStatisticsData3 = new TmfStatisticsTree(); + TmfStatisticsTreeManager.addStatsTreeRoot(fDataKey1, fStatisticsData1); + TmfStatisticsTreeManager.addStatsTreeRoot(fDataKey2, fStatisticsData2); + TmfStatisticsTreeManager.addStatsTreeRoot(fDataKey2, fStatisticsData3); + } + + /** + * Clean the statistics tree + */ + private static void removeStatsTreeRoot() { + TmfStatisticsTreeManager.removeAll(); + } + + /** + * Test adding of statistics tree root. It should not throw exceptions + */ + @Test + public void testaddStatsTreeRoot() { + removeStatsTreeRoot(); + + try { + assertNull(TmfStatisticsTreeManager.addStatsTreeRoot(null, null)); + assertNull(TmfStatisticsTreeManager.addStatsTreeRoot(null, fStatisticsData1)); + assertNull(TmfStatisticsTreeManager.addStatsTreeRoot(fDataKey1, null)); + assertNull(TmfStatisticsTreeManager.getStatTreeRoot(fDataKey1)); + + TmfStatisticsTreeNode returnRootNode = TmfStatisticsTreeManager.addStatsTreeRoot(fDataKey1, fStatisticsData1); + assertSame(fStatisticsData1, TmfStatisticsTreeManager.getStatTree(fDataKey1)); + assertSame(fStatisticsData1.getRootNode(), returnRootNode); + + // Overwriting the value + returnRootNode = TmfStatisticsTreeManager.addStatsTreeRoot(fDataKey1, fStatisticsData2); + assertSame(fStatisticsData2, TmfStatisticsTreeManager.getStatTree(fDataKey1)); + assertSame(fStatisticsData2.getRootNode(), returnRootNode); + + // Success + } catch(Exception e) { + fail("AddStatsTreeRoot"); + } + } + + // ------------------------------------------------------------------------ + // get + // ------------------------------------------------------------------------ + + /** + * Test getting of statistics tree root. + */ + @Test + public void testGetStatTreeRoot() { + TmfStatisticsTreeNode value1 = TmfStatisticsTreeManager.getStatTreeRoot(fDataKey1); + TmfStatisticsTreeNode value2 = TmfStatisticsTreeManager.getStatTreeRoot(fDataKey2); + TmfStatisticsTreeNode value3 = TmfStatisticsTreeManager.getStatTreeRoot(fDataKey1); + assertNotSame("getStatTreeRoot", value1, value2); + assertNotSame("getStatTreeRoot", value2, value3); + assertSame("getStatTreeRoot", value1, value3); + assertNull("getStatTreeRoot", TmfStatisticsTreeManager.getStatTreeRoot(null)); + } + + /** + * Test getting statistics tree. + */ + @Test + public void testGetStatTree() { + TmfStatisticsTree value1 = TmfStatisticsTreeManager.getStatTree(fDataKey1); + TmfStatisticsTree value2 = TmfStatisticsTreeManager.getStatTree(fDataKey2); + TmfStatisticsTree value3 = TmfStatisticsTreeManager.getStatTree(fDataKey1); + assertNotSame("getStatTree", value1, value2); + assertNotSame("getStatTree", value2, value3); + assertSame("getStatTree", value1, value3); + assertNull("getStatTreeRoot", TmfStatisticsTreeManager.getStatTree(null)); + } + + // ------------------------------------------------------------------------ + // contains + // ------------------------------------------------------------------------ + + /** + * Test checking for tree root existence. + */ + @Test + public void testContainsTreeRoot() { + assertTrue("containsTreeRoot", TmfStatisticsTreeManager.containsTreeRoot(fDataKey1)); + assertTrue("containsTreeRoot", TmfStatisticsTreeManager.containsTreeRoot(fDataKey2)); + assertFalse("containsTreeRoot", TmfStatisticsTreeManager.containsTreeRoot(null)); + } + + // ------------------------------------------------------------------------ + // remove + // ------------------------------------------------------------------------ + + /** + * Test removal of statistics tree node. + */ + @Test + public void testRemoveStatTreeRoot() { + TmfStatisticsTreeManager.removeStatTreeRoot(fDataKey1); + assertNull("removeStatTreeRoot", TmfStatisticsTreeManager.getStatTree(fDataKey1)); + + try { + // Trying to remove the same branch from the tree. + TmfStatisticsTreeManager.removeStatTreeRoot(fDataKey1); + + TmfStatisticsTreeManager.removeStatTreeRoot(null); + // Success + } catch (Exception e) { + fail("removeStatTreeRoot"); + } + } + + /** + * Test removal of all root nodes. + */ + @Test + public void testRemoveAll() { + TmfStatisticsTreeManager.removeAll(); + assertNull("removeAll", TmfStatisticsTreeManager.getStatTreeRoot(fDataKey2)); + assertNull("removeAll", TmfStatisticsTreeManager.getStatTreeRoot(fDataKey3)); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfStatisticsTreeNodeTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfStatisticsTreeNodeTest.java new file mode 100755 index 0000000000..b22a7eadc2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfStatisticsTreeNodeTest.java @@ -0,0 +1,385 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial design and implementation + * Bernd Hufmann - Fixed warnings + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.statistics; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Vector; + +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.Messages; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTree; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode; +import org.junit.Test; + +/** + * TmfStatisticsTreeNode Test Cases. + */ +public class TmfStatisticsTreeNodeTest { + + // ------------------------------------------------------------------------ + // Fields + // ------------------------------------------------------------------------ + + private final String fTypeId1 = "Some type1"; + private final String fTypeId2 = "Some type2"; + private final String fTypeId3 = "Some type3"; + + private final TmfStatisticsTree fStatsTree; + + private static final String fTestName = "StatisticsTreeNodeTest"; + + // ------------------------------------------------------------------------ + // Housekeeping + // ------------------------------------------------------------------------ + + /** + * Constructor + */ + public TmfStatisticsTreeNodeTest() { + fStatsTree = new TmfStatisticsTree(); + + /* Enter some global values */ + fStatsTree.setTotal(fTestName, true, 18); + fStatsTree.setTypeCount(fTestName, fTypeId1, true, 5); + fStatsTree.setTypeCount(fTestName, fTypeId2, true, 6); + fStatsTree.setTypeCount(fTestName, fTypeId3, true, 7); + + /* Enter some time range values */ + fStatsTree.setTotal(fTestName, false, 9); + fStatsTree.setTypeCount(fTestName, fTypeId1, false, 2); + fStatsTree.setTypeCount(fTestName, fTypeId2, false, 3); + fStatsTree.setTypeCount(fTestName, fTypeId3, false, 4); + } + + /** + * Test checking for child. + */ + @Test + public void testContainsChild() { + TmfStatisticsTreeNode rootNode = fStatsTree.getRootNode(); + TmfStatisticsTreeNode traceNode = fStatsTree.getNode(fTestName); + // Creates a category from the key already created + TmfStatisticsTreeNode catNode = traceNode.getChildren().iterator().next(); + + assertTrue(rootNode.containsChild(fTestName)); + assertFalse(rootNode.containsChild(catNode.getName())); + + assertTrue(traceNode.containsChild(catNode.getName())); + assertFalse(traceNode.containsChild(fTypeId1)); + + assertTrue(catNode.containsChild(fTypeId1)); + assertTrue(catNode.containsChild(fTypeId2)); + } + + /** + * Test getting of children. + */ + @Test + public void testGetChildren() { + // Getting children of the ROOT + Collection childrenTreeNode = fStatsTree.getRootNode().getChildren(); + assertEquals(1, childrenTreeNode.size()); + TmfStatisticsTreeNode treeNode = childrenTreeNode.iterator().next(); + assertEquals(fTestName, treeNode.getName()); + + // Getting children of the trace + childrenTreeNode = fStatsTree.getNode(fTestName).getChildren(); + assertEquals(1, childrenTreeNode.size()); + treeNode = childrenTreeNode.iterator().next(); + assertEquals(Messages.TmfStatisticsData_EventTypes, treeNode.getName()); + + Vector keyExpected = new Vector<>(); + keyExpected.add(fTypeId1); + keyExpected.add(fTypeId2); + keyExpected.add(fTypeId3); + // Getting children of a category + childrenTreeNode = treeNode.getChildren(); + assertEquals(3, childrenTreeNode.size()); + + Iterator iterChild = childrenTreeNode.iterator(); + TmfStatisticsTreeNode temp; + while (iterChild.hasNext()) { + temp = iterChild.next(); + if (keyExpected.contains(temp.getName())) { + keyExpected.removeElement(temp.getName()); + } else { + fail(); + } + } + + // Get children of a specific event type + childrenTreeNode = fStatsTree.getNode(childrenTreeNode.iterator().next().getPath()).getChildren(); + assertEquals(0, childrenTreeNode.size()); + } + + /** + * Test getting of number of children. + */ + @Test + public void testGetNbChildren() { + TmfStatisticsTreeNode rootNode = fStatsTree.getRootNode(); + TmfStatisticsTreeNode traceNode = fStatsTree.getNode(fTestName); + TmfStatisticsTreeNode catNode = traceNode.getChildren().iterator().next(); + TmfStatisticsTreeNode elementNode = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1); + + assertEquals(1, rootNode.getNbChildren()); + assertEquals(1, traceNode.getNbChildren()); + assertEquals(3, catNode.getNbChildren()); + assertEquals(0, elementNode.getNbChildren()); + } + + /** + * Test checking for children. + */ + @Test + public void testHasChildren() { + TmfStatisticsTreeNode rootNode = fStatsTree.getRootNode(); + TmfStatisticsTreeNode traceNode = fStatsTree.getNode(fTestName); + TmfStatisticsTreeNode catNode = traceNode.getChildren().iterator().next(); + TmfStatisticsTreeNode elementNode = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1); + + assertTrue(rootNode.hasChildren()); + assertTrue(traceNode.hasChildren()); + assertTrue(catNode.hasChildren()); + assertFalse(elementNode.hasChildren()); + } + + /** + * Test getting of parent. + */ + @Test + public void testGetParent() { + final TmfStatisticsTreeNode rootNode = fStatsTree.getRootNode(); + TmfStatisticsTreeNode parentNode = rootNode.getParent(); + assertNull(parentNode); + + TmfStatisticsTreeNode newTraceNode = new TmfStatisticsTreeNode(fStatsTree, rootNode, "newly created trace node"); + parentNode = newTraceNode.getParent(); + assertNotNull(parentNode); + assertTrue(fStatsTree.getRootNode() == parentNode); + + TmfStatisticsTreeNode traceNode = fStatsTree.getNode(fTestName); + parentNode = traceNode.getParent(); + assertNotNull(parentNode); + assertTrue(rootNode == parentNode); + + TmfStatisticsTreeNode elementNode = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1); + parentNode = elementNode.getParent(); + assertTrue(parentNode == fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes)); + + TmfStatisticsTreeNode catNode = traceNode.getChildren().iterator().next(); + parentNode = catNode.getParent(); + assertNotNull(parentNode); + assertTrue(parentNode == fStatsTree.getNode(fTestName)); + + parentNode = elementNode.getParent(); + assertNotNull(parentNode); + assertTrue(arraysEqual(parentNode.getPath(), fTestName, Messages.TmfStatisticsData_EventTypes)); + } + + /** + * Test getting of key. + */ + @Test + public void testgetName() { + TmfStatisticsTreeNode rootNode = fStatsTree.getRootNode(); + TmfStatisticsTreeNode traceNode = fStatsTree.getNode(fTestName); + TmfStatisticsTreeNode catNode = traceNode.getChildren().iterator().next(); + TmfStatisticsTreeNode elementNode = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1); + + assertEquals(0, rootNode.getName().compareTo("root")); + assertEquals(0, traceNode.getName().compareTo(fTestName)); + assertEquals(0, catNode.getName().compareTo(Messages.TmfStatisticsData_EventTypes)); + assertEquals(0, elementNode.getName().compareTo(fTypeId1)); + } + + /** + * Test getting of path to node. + */ + @Test + public void testGetPath() { + TmfStatisticsTreeNode rootNode = fStatsTree.getRootNode(); + TmfStatisticsTreeNode traceNode = fStatsTree.getNode(fTestName); + TmfStatisticsTreeNode catNode = traceNode.getChildren().iterator().next(); + TmfStatisticsTreeNode elementNode = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1); + + assertEquals(0, rootNode.getPath().length); /* Root node has an empty path */ + assertTrue(arraysEqual(traceNode.getPath(), fTestName)); + assertTrue(arraysEqual(catNode.getPath(), + fTestName, Messages.TmfStatisticsData_EventTypes)); + assertTrue(arraysEqual(elementNode.getPath(), + fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1)); + } + + /** + * Test getting statistic value. + */ + @Test + public void testGetValue() { + TmfStatisticsTreeNode rootNode, traceNode, catNode, elementNode1, elementNode2, elementNode3; + rootNode = fStatsTree.getRootNode(); + traceNode = fStatsTree.getNode(fTestName); + catNode = traceNode.getChildren().iterator().next(); + elementNode1 = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1); + elementNode2 = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId2); + elementNode3 = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId3); + + assertEquals(0, rootNode.getValues().getTotal()); + assertEquals(18, traceNode.getValues().getTotal()); + assertEquals(0, catNode.getValues().getTotal()); + assertEquals(5, elementNode1.getValues().getTotal()); + assertEquals(6, elementNode2.getValues().getTotal()); + assertEquals(7, elementNode3.getValues().getTotal()); + + assertEquals(0, rootNode.getValues().getPartial()); + assertEquals(9, traceNode.getValues().getPartial()); + assertEquals(0, catNode.getValues().getPartial()); + assertEquals(2, elementNode1.getValues().getPartial()); + assertEquals(3, elementNode2.getValues().getPartial()); + assertEquals(4, elementNode3.getValues().getPartial()); + } + + /** + * Test reset of tree. + */ + @Test + public void testReset() { + TmfStatisticsTreeNode rootNode, traceNode, catNode, elementNode; + rootNode = fStatsTree.getRootNode(); + traceNode = fStatsTree.getNode(fTestName); + catNode = traceNode.getChildren().iterator().next(); + elementNode = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1); + + elementNode.reset(); + assertEquals(0, elementNode.getValues().getTotal()); + assertEquals(0, elementNode.getValues().getPartial()); + + catNode.reset(); + assertEquals(0, catNode.getValues().getTotal()); + assertEquals(0, catNode.getValues().getPartial()); + assertEquals(0, catNode.getNbChildren()); + assertNull(fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1)); + + traceNode.reset(); + assertEquals(0, traceNode.getValues().getTotal()); + assertEquals(0, traceNode.getValues().getPartial()); + assertEquals(0, traceNode.getNbChildren()); + + rootNode.reset(); + assertEquals(0, rootNode.getValues().getTotal()); + assertEquals(0, rootNode.getValues().getPartial()); + assertEquals(0, rootNode.getNbChildren()); + } + + /** + * Test reset global value of the node in the tree. It should only clear + * the global value without removing any node from the tree. + */ + @Test + public void testResetGlobalValue() { + TmfStatisticsTreeNode rootNode, traceNode, catNode, eventTypeNode1, eventTypeNode2, eventTypeNode3; + rootNode = fStatsTree.getRootNode(); + traceNode = fStatsTree.getNode(fTestName); + catNode = traceNode.getChildren().iterator().next(); + eventTypeNode1 = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1); + eventTypeNode2 = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId2); + eventTypeNode3 = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId3); + + rootNode.resetGlobalValue(); + + assertEquals(0, rootNode.getValues().getTotal()); + assertEquals(0, traceNode.getValues().getTotal()); + assertEquals(0, catNode.getValues().getTotal()); + assertEquals(0, eventTypeNode1.getValues().getTotal()); + assertEquals(0, eventTypeNode2.getValues().getTotal()); + assertEquals(0, eventTypeNode3.getValues().getTotal()); + + // Checks the state of the statistics tree + Collection rootChildren = rootNode.getChildren(); + assertEquals(1, rootChildren.size()); + assertTrue(rootChildren.contains(traceNode)); + + Collection traceChildren = traceNode.getChildren(); + assertEquals(1, traceChildren.size()); + assertTrue(traceChildren.contains(catNode)); + + Collection catChildren = catNode.getChildren(); + assertEquals(3, catChildren.size()); + assertTrue(catChildren.contains(eventTypeNode1)); + assertTrue(catChildren.contains(eventTypeNode2)); + assertTrue(catChildren.contains(eventTypeNode3)); + } + + /** + * Test reset time range value of the node in the tree. It should only clear + * the time range value without removing any node from the tree. + */ + @Test + public void testResetTimeRangeValue() { + TmfStatisticsTreeNode rootNode, traceNode, catNode, eventTypeNode1, eventTypeNode2, eventTypeNode3; + rootNode = fStatsTree.getRootNode(); + traceNode = fStatsTree.getNode(fTestName); + catNode = traceNode.getChildren().iterator().next(); + eventTypeNode1 = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId1); + eventTypeNode2 = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId2); + eventTypeNode3 = fStatsTree.getNode(fTestName, Messages.TmfStatisticsData_EventTypes, fTypeId3); + + rootNode.resetTimeRangeValue(); + + assertEquals(0, rootNode.getValues().getPartial()); + assertEquals(0, traceNode.getValues().getPartial()); + assertEquals(0, catNode.getValues().getPartial()); + assertEquals(0, eventTypeNode1.getValues().getPartial()); + assertEquals(0, eventTypeNode2.getValues().getPartial()); + + // Checks the state of the statistics tree + Collection rootChildren = rootNode.getChildren(); + assertEquals(1, rootChildren.size()); + assertTrue(rootChildren.contains(traceNode)); + + Collection traceChildren = traceNode.getChildren(); + assertEquals(1, traceChildren.size()); + assertTrue(traceChildren.contains(catNode)); + + Collection catChildren = catNode.getChildren(); + assertEquals(3, catChildren.size()); + assertTrue(catChildren.contains(eventTypeNode1)); + assertTrue(catChildren.contains(eventTypeNode2)); + assertTrue(catChildren.contains(eventTypeNode3)); + } + + /** + * Check if two String arrays are equals, by comparing their contents. + * Unlike Arrays.equals(), we can use varargs for the second argument. + */ + private static boolean arraysEqual(String[] array1, String... array2) { + if (array1.length != array2.length) { + return false; + } + for (int i = 0; i < array1.length; i++) { + if (!array1[i].equals(array2[i])) { + return false; + } + } + return true; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfTreeContentProviderTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfTreeContentProviderTest.java new file mode 100755 index 0000000000..2854fdb8b7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/statistics/TmfTreeContentProviderTest.java @@ -0,0 +1,187 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial design and implementation + * Bernd Hufmann - Fixed warnings + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.statistics; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Arrays; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.Messages; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTree; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfTreeContentProvider; +import org.junit.Test; + +/** + * TmfTreeContentProvider Test Cases. + */ +public class TmfTreeContentProviderTest { + + // ------------------------------------------------------------------------ + // Fields + // ------------------------------------------------------------------------ + + private static final String fTestName = "TreeContentProviderTest"; + + private final String fContext = "UnitTest"; + private final String fTypeId1 = "Some type1"; + private final String fTypeId2 = "Some type2"; + + private final String fLabel0 = "label1"; + private final String fLabel1 = "label2"; + private final String[] fLabels = new String[] { fLabel0, fLabel1 }; + + private final TmfTimestamp fTimestamp1 = new TmfTimestamp(12345, (byte) 2, 5); + private final TmfTimestamp fTimestamp2 = new TmfTimestamp(12350, (byte) 2, 5); + + private final String fSource = "Source"; + + private final TmfEventType fType1 = new TmfEventType(fContext, fTypeId1, TmfEventField.makeRoot(fLabels)); + private final TmfEventType fType2 = new TmfEventType(fContext, fTypeId2, TmfEventField.makeRoot(fLabels)); + + private final String fReference = "Some reference"; + + private final ITmfEvent fEvent1; + private final ITmfEvent fEvent2; + + private final TmfEventField fContent1; + private final TmfEventField fContent2; + + private final TmfStatisticsTree fStatsData; + + private final TmfTreeContentProvider treeProvider; + + // ------------------------------------------------------------------------ + // Housekeeping + // ------------------------------------------------------------------------ + + /** + * Constructor + */ + public TmfTreeContentProviderTest() { + fContent1 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some content", null); + fEvent1 = new TmfEvent(null, fTimestamp1, fSource, fType1, fContent1, fReference); + + fContent2 = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, "Some other content", null); + fEvent2 = new TmfEvent(null, fTimestamp2, fSource, fType2, fContent2, fReference); + + fStatsData = new TmfStatisticsTree(); + + fStatsData.setTotal(fTestName, true, 2); + fStatsData.setTypeCount(fTestName, fEvent1.getType().getName(), true, 1); + fStatsData.setTypeCount(fTestName, fEvent2.getType().getName(), true, 1); + + treeProvider = new TmfTreeContentProvider(); + } + + // ------------------------------------------------------------------------ + // Test methods + // ------------------------------------------------------------------------ + + /** + * Test getting of children. + * FIXME this test was quickly adapted when we removed the TmfFixedArray, + * but it could be rewritten to be much more simple... + */ + @Test + public void testGetChildren() { + Object[] objectArray = treeProvider.getChildren(fStatsData.getOrCreateNode(fTestName, Messages.TmfStatisticsData_EventTypes)); + TmfStatisticsTreeNode[] childrenNode = Arrays.asList(objectArray).toArray(new TmfStatisticsTreeNode[0]); + + String[][] childrenExpected = new String[][] { + new String[] { fTestName, Messages.TmfStatisticsData_EventTypes, fEvent1.getType().getName() }, + new String[] { fTestName, Messages.TmfStatisticsData_EventTypes, fEvent2.getType().getName() } + }; + + assertEquals("getChildren", childrenExpected.length, childrenNode.length); + // assertTrue("getChildren", childrenPath.equals(childrenExpected)); + for (TmfStatisticsTreeNode childNode : childrenNode) { + if (!arrayOfArraysContains(childrenExpected, childNode.getPath())) { + fail(); + } + } + } + + private static boolean arrayOfArraysContains(String[][] arrayOfArrays, String[] array) { + for (String[] curArray : arrayOfArrays) { + if (arraysEqual(curArray, array)) { + return true; + } + } + return false; + } + + private static boolean arraysEqual(String[] array1, String[] array2) { + if (array1.length != array2.length) { + return false; + } + for (int i = 0; i < array1.length; i++) { + if (!array1[i].equals(array2[i])) { + return false; + } + } + return true; + } + + /** + * Test getting of parent. + */ + @Test + public void testGetParent() { + TmfStatisticsTreeNode parent = (TmfStatisticsTreeNode) treeProvider.getParent(fStatsData.getNode(fTestName)); + + assertNotNull("getParent", parent); + assertTrue("getParent", parent.getPath().equals(fStatsData.getRootNode().getPath())); + } + + /** + * Test checking for children. + */ + @Test + public void testHasChildren() { + boolean hasChildren = treeProvider.hasChildren(fStatsData.getRootNode()); + assertTrue("hasChildren", hasChildren); + + hasChildren = treeProvider.hasChildren(fStatsData.getOrCreateNode(fTestName)); + assertTrue("hasChildren", hasChildren); + + hasChildren = treeProvider.hasChildren(fStatsData.getOrCreateNode(fTestName, Messages.TmfStatisticsData_EventTypes)); + assertTrue("hasChildren", hasChildren); + + hasChildren = treeProvider.hasChildren(fStatsData.getOrCreateNode(fTestName, Messages.TmfStatisticsData_EventTypes, fEvent1.getType().getName())); + assertFalse("hasChildren", hasChildren); + } + + /** + * Test getting of elements. + */ + @Test + public void testGetElements() { + Object[] objectElements = treeProvider.getElements(fStatsData.getRootNode()); + TmfStatisticsTreeNode[] nodeElements = Arrays.asList(objectElements).toArray(new TmfStatisticsTreeNode[0]); + assertEquals("getElements", 1, nodeElements.length); + assertTrue("getElements", nodeElements[0].getPath()[0].equals(fTestName)); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/AbstractCustomTraceIndexTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/AbstractCustomTraceIndexTest.java new file mode 100644 index 0000000000..b7e0afc4dd --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/AbstractCustomTraceIndexTest.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.trace; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.File; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.trace.ITmfEventParser; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfContext; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.core.trace.indexer.TmfBTreeTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Common test code for custom trace indexes + * + * @author Marc-Andre Laperle + */ +public abstract class AbstractCustomTraceIndexTest { + + /** + * Time format use for event creation + */ + protected static final String TIMESTAMP_FORMAT = "dd/MM/yyyy HH:mm:ss:SSS"; + /** + * Block size used for the indexer + */ + protected static final int BLOCK_SIZE = 100; + /** + * The total number of events in the generated trace + */ + protected static final int NB_EVENTS = 10000; + private TestTrace fTrace = null; + + /** + * A common test indexer for custom trace index tests + */ + protected static class TestIndexer extends TmfBTreeTraceIndexer { + + /** + * Constructs a new test indexer + * + * @param trace the trace + * @param interval the checkpoint interval + */ + public TestIndexer(ITmfTrace trace, int interval) { + super(trace, interval); + } + + /** + * Get the index + * + * @return the index + */ + public ITmfCheckpointIndex getCheckpoints() { + return getTraceIndex(); + } + } + + interface TestTrace extends ITmfTrace { + TestIndexer getIndexer(); + } + + /** + * Setup the test + * + * @throws Exception when error occurs + */ + @Before + public void setUp() throws Exception { + setupTrace(); + } + + private synchronized void setupTrace() throws Exception { + File traceDirectory = new File(getTraceDirectory()); + if (traceDirectory.exists()) { + traceDirectory.delete(); + } + traceDirectory.mkdir(); + if (fTrace == null) { + fTrace = createTrace(); + fTrace.indexTrace(true); + } + } + + /** + * Create a test trace, varies between tests + * + * @return the test trace + * @throws Exception when error occurs + */ + abstract protected TestTrace createTrace() throws Exception; + /** + * Return the trace directory for the generated trace + * + * @return the trace directory for the generated trace + */ + abstract protected String getTraceDirectory(); + + /** + * Tear down the test + */ + @After + public void tearDown() { + String directory = TmfTraceManager.getSupplementaryFileDir(fTrace); + try { + fTrace.dispose(); + fTrace = null; + } finally { + File dir = new File(directory); + if (dir.exists()) { + File[] files = dir.listFiles(); + for (File file : files) { + file.delete(); + } + dir.delete(); + } + + File trace = new File(getTraceDirectory()); + if (trace.exists()) { + trace.delete(); + } + } + + } + + /** + * Test the content of the index after building the full index + */ + @Test + public void testTmfTraceIndexing() { + verifyIndexContent(); + } + + private void verifyIndexContent() { + assertEquals("getCacheSize", BLOCK_SIZE, fTrace.getCacheSize()); + assertEquals("getTraceSize", NB_EVENTS, fTrace.getNbEvents()); + assertEquals("getRange-start", 0, fTrace.getTimeRange().getStartTime().getValue()); + assertEquals("getRange-end", NB_EVENTS - 1, fTrace.getTimeRange().getEndTime().getValue()); + assertEquals("getStartTime", 0, fTrace.getStartTime().getValue()); + assertEquals("getEndTime", NB_EVENTS - 1, fTrace.getEndTime().getValue()); + + ITmfCheckpointIndex checkpoints = fTrace.getIndexer().getCheckpoints(); + int pageSize = fTrace.getCacheSize(); + assertTrue("Checkpoints exist", checkpoints != null); + assertEquals("Checkpoints size", NB_EVENTS / BLOCK_SIZE, checkpoints.size()); + + // Validate that each checkpoint points to the right event + for (int i = 0; i < checkpoints.size(); i++) { + ITmfCheckpoint checkpoint = checkpoints.get(i); + TmfContext context = new TmfContext(checkpoint.getLocation(), i * pageSize); + ITmfEvent event = ((ITmfEventParser)fTrace).parseEvent(context); + assertTrue(context.getRank() == i * pageSize); + assertTrue((checkpoint.getTimestamp().compareTo(event.getTimestamp(), false) == 0)); + } + } + + /** + * Test that a fully built index has the same content when reloaded from disk + * + * @throws Exception when error occurs + */ + @Test + public void testReopenIndex() throws Exception { + fTrace.dispose(); + fTrace = createTrace(); + assertFalse(fTrace.getIndexer().getCheckpoints().isCreatedFromScratch()); + fTrace.indexTrace(true); + + verifyIndexContent(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/AllTests.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/AllTests.java new file mode 100644 index 0000000000..2535d93b53 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/AllTests.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.trace; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for custom parsers + * @author Matthew Khouzam + * + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + CustomXmlTraceInvalidTest.class, + CustomXmlTraceBadlyFormedTest.class, + CustomXmlTraceValidTest.class, + CustomXmlIndexTest.class, + CustomTxtIndexTest.class +}) +public class AllTests { +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomTxtIndexTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomTxtIndexTest.java new file mode 100644 index 0000000000..82a5419ad5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomTxtIndexTest.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Adapted for TMF Trace Model 1.0 + * Alexandre Montplaisir - Port to JUnit4 + * Marc-Andre Laperle - Adapted to CustomTxtTrace + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.trace; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTrace; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer; + +/** + * Test suite for indexing using a CustomTxtTrace. + * + * @author Marc-Andre Laperle + */ +public class CustomTxtIndexTest extends AbstractCustomTraceIndexTest { + + private static final String TRACE_DIRECTORY = TmfTraceManager.getTemporaryDirPath() + File.separator + "dummyTxtTrace"; + private static final String TRACE_PATH = TRACE_DIRECTORY + File.separator + "test.txt"; + private static final String DEFINITION_PATH = "tracesets" + File.separator + "txt" + File.separator + "testTxtDefinition.xml"; + + private static CustomTxtTraceDefinition createDefinition() { + CustomTxtTraceDefinition[] definitions = CustomTxtTraceDefinition.loadAll(new File(DEFINITION_PATH).toString()); + return definitions[0]; + } + + @Override + protected String getTraceDirectory() { + return TRACE_DIRECTORY; + } + + @Override + protected TestTrace createTrace() throws Exception { + CustomTxtTraceDefinition definition = createDefinition(); + final File file = new File(TRACE_PATH); + try (BufferedWriter writer = new BufferedWriter(new FileWriter(file));) { + for (int i = 0; i < NB_EVENTS; ++i) { + SimpleDateFormat f = new SimpleDateFormat(TIMESTAMP_FORMAT); + String eventStr = f.format(new Date(i)) + " hello world\n"; + writer.write(eventStr); + } + } + + return new TestTxtTrace(file.toString(), definition, BLOCK_SIZE); + } + + private class TestTxtTrace extends CustomTxtTrace implements TestTrace { + public TestTxtTrace(String path, CustomTxtTraceDefinition createDefinition, int blockSize) throws TmfTraceException { + super(null, createDefinition, path, blockSize); + } + + @Override + protected ITmfTraceIndexer createIndexer(int interval) { + return new TestIndexer(this, interval); + } + + @Override + public TestIndexer getIndexer() { + return (TestIndexer) super.getIndexer(); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlIndexTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlIndexTest.java new file mode 100644 index 0000000000..b7f6c3bc3d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlIndexTest.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Adapted for TMF Trace Model 1.0 + * Alexandre Montplaisir - Port to JUnit4 + * Marc-Andre Laperle - Adapted to CustomXmlTrace + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.trace; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTrace; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer; + +/** + * Test suite for indexing using a CustomXmlTrace. + * + * @author Marc-Andre Laperle + */ +public class CustomXmlIndexTest extends AbstractCustomTraceIndexTest { + + private static final String TRACE_DIRECTORY = TmfTraceManager.getTemporaryDirPath() + File.separator + "dummyXmlTrace"; + private static final String TRACE_PATH = TRACE_DIRECTORY + File.separator + "test.xml"; + private static final String DEFINITION_PATH = "tracesets" + File.separator + "xml" + File.separator + "testDefinition.xml"; + + private static CustomXmlTraceDefinition createDefinition() { + CustomXmlTraceDefinition[] definitions = CustomXmlTraceDefinition.loadAll(new File(DEFINITION_PATH).toString()); + return definitions[0]; + } + + @Override + protected String getTraceDirectory() { + return TRACE_DIRECTORY; + } + + @Override + protected TestTrace createTrace() throws Exception { + CustomXmlTraceDefinition definition = createDefinition(); + final File file = new File(TRACE_PATH); + try (BufferedWriter writer = new BufferedWriter(new FileWriter(file));) { + writer.write(""); + for (int i = 0; i < NB_EVENTS; ++i) { + SimpleDateFormat f = new SimpleDateFormat(TIMESTAMP_FORMAT); + String eventStr = "message\n"; + writer.write(eventStr); + } + writer.write(""); + } + + return new TestXmlTrace(file.toString(), definition, BLOCK_SIZE); + } + + private class TestXmlTrace extends CustomXmlTrace implements TestTrace { + public TestXmlTrace(String path, CustomXmlTraceDefinition createDefinition, int blockSize) throws TmfTraceException { + super(null, createDefinition, path, blockSize); + } + + @Override + protected ITmfTraceIndexer createIndexer(int interval) { + return new TestIndexer(this, interval); + } + + @Override + public TestIndexer getIndexer() { + return (TestIndexer) super.getIndexer(); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlTraceBadlyFormedTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlTraceBadlyFormedTest.java new file mode 100644 index 0000000000..7eec738eb7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlTraceBadlyFormedTest.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.trace; + +import static org.junit.Assert.fail; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.core.runtime.IStatus; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +/** + * Malformed xml test, dangerous errors + * @author Matthew Khouzam + * + */ +@RunWith(Parameterized.class) +public class CustomXmlTraceBadlyFormedTest extends CustomXmlTraceTest { + + private final static String pathname = "tracesets/xml/malformed"; + + /** + * This should create the parameters to launch the project + * + * @return the path of the parameters + */ + @Parameters(name = "{index}: path {0}") + public static Collection getFiles() { + File[] malformedFiles = (new File(pathname)).listFiles(); + Collection params = new ArrayList<>(); + for (File f : malformedFiles) { + Object[] arr = new Object[] { f.getAbsolutePath() }; + params.add(arr); + } + return params; + } + + /** + * Test all the invalid xml files + */ + @Test + public void testBadlyFormed() { + IStatus valid = getTrace().validate(null, getPath()); + if (IStatus.ERROR != valid.getSeverity()) { + fail(valid.toString()); + } + } + + /** + * ctor + * + * @param filePath + * the path + */ + public CustomXmlTraceBadlyFormedTest(String filePath) { + this.setPath(filePath); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlTraceInvalidTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlTraceInvalidTest.java new file mode 100644 index 0000000000..b1bbbfced2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlTraceInvalidTest.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.trace; + +import static org.junit.Assert.fail; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.core.runtime.IStatus; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +/** + * Invalid Xml files, random errors + * + * @author Matthew Khouzam + * + */ +@RunWith(Parameterized.class) +public class CustomXmlTraceInvalidTest extends CustomXmlTraceTest{ + + private final static String pathname = "tracesets/xml/invalid"; + + /** + * This should create the parameters to launch the project + * + * @return the path of the parameters + */ + @Parameters(name = "{index}: path {0}") + public static Collection getFiles() { + File[] invalidFiles = (new File(pathname)).listFiles(); + Collection params = new ArrayList<>(); + for (File f : invalidFiles) { + Object[] arr = new Object[] { f.getAbsolutePath() }; + params.add(arr); + } + return params; + } + + /** + * ctor + * + * @param filePath + * the path + */ + public CustomXmlTraceInvalidTest(String filePath) { + setPath(filePath); + } + + /** + * Test all the invalid xml files + */ + @Test + public void testInvalid() { + IStatus invalid = getTrace().validate(null, getPath()); + if (IStatus.ERROR != invalid.getSeverity()) { + fail(getPath()); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlTraceTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlTraceTest.java new file mode 100644 index 0000000000..e80e192605 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlTraceTest.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.trace; + +import java.util.ArrayList; + +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTrace; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition.OutputColumn; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition.InputElement; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.junit.Before; + +/** + * Abstract test parent + * + * @author Matthew Khouzam + * + */ +public abstract class CustomXmlTraceTest { + private CustomXmlTraceDefinition cxtd; + /** + * The trace to use to "validate" the xml files + */ + private CustomXmlTrace t; + /** + * The path of the trace + */ + private String path; + + + /** + * set up directories + */ + @Before + public void init() { + cxtd = new CustomXmlTraceDefinition(TmfTraceType.CUSTOM_XML_CATEGORY, "test", new InputElement(), new ArrayList(), "s"); + t = new CustomXmlTrace(cxtd); + } + + + /** + * @return the trace + */ + public CustomXmlTrace getTrace() { + return t; + } + + + /** + * @return the path + */ + public String getPath() { + return path; + } + + + /** + * @param path the path to set + */ + public void setPath(String path) { + this.path = path; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlTraceValidTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlTraceValidTest.java new file mode 100644 index 0000000000..cabf167cd4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/trace/CustomXmlTraceValidTest.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.trace; + +import static org.junit.Assert.fail; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.core.runtime.IStatus; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +/** + * Well formed XML + * @author Matthew Khouzam + * + */ +@RunWith(Parameterized.class) +public class CustomXmlTraceValidTest extends CustomXmlTraceTest { + + private final static String pathname = "tracesets/xml/valid"; + + + /** + * This should create the parameters to launch the project + * + * @return the path of the parameters + */ + @Parameters(name = "{index}: path {0}") + public static Collection getFiles() { + File[] validFiles = (new File(pathname)).listFiles(); + Collection params = new ArrayList<>(); + for (File f : validFiles) { + Object[] arr = new Object[] { f.getAbsolutePath() }; + params.add(arr); + } + return params; + } + + /** + * Test all the invalid xml files + */ + @Test + public void testValid() { + IStatus valid = getTrace().validate(null, getPath()); + if (IStatus.OK != valid.getSeverity()) { + fail(valid.toString()); + } + } + + /** + * ctor + * + * @param filePath + * the path + */ + public CustomXmlTraceValidTest(String filePath) { + this.setPath(filePath); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/dialogs/AllTests.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/dialogs/AllTests.java new file mode 100644 index 0000000000..4061d06981 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/dialogs/AllTests.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2011-2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.dialogs; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite of UML2SD dialog tests. + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + CriteriaTest.class +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/dialogs/CriteriaTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/dialogs/CriteriaTest.java new file mode 100644 index 0000000000..fa471bdf60 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/dialogs/CriteriaTest.java @@ -0,0 +1,304 @@ +/******************************************************************************* + * Copyright (c) 2011-2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.dialogs; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; +import java.util.regex.Pattern; + +import org.eclipse.jface.dialogs.DialogSettings; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.Criteria; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.FilterCriteria; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDFilterProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter; +import org.junit.Test; + +/** + * Test cases to test Criteria class. + */ +public class CriteriaTest { + + /** + * Test default constructor. + */ + @Test + public void testCriteria() { + Criteria criteria = new Criteria(); + assertFalse("testCriteria", criteria.isAsyncMessageReturnSelected()); + assertFalse("testCriteria", criteria.isAsyncMessageSelected()); + assertFalse("testCriteria", criteria.isCaseSenstiveSelected()); + assertFalse("testCriteria", criteria.isLifeLineSelected()); + assertFalse("testCriteria", criteria.isStopSelected()); + assertFalse("testCriteria", criteria.isSyncMessageReturnSelected()); + assertFalse("testCriteria", criteria.isSyncMessageSelected()); + assertNull("testCriteria", criteria.getExpression()); + assertNull("testCriteria", criteria.getPattern()); + } + + /** + * Test copy constructor. + */ + @Test + public void testCriteriaCriteria() { + Criteria criteria = new Criteria(); + criteria.setExpression("test"); + criteria.setLifeLineSelected(true); + criteria.setSyncMessageSelected(true); + + Criteria copy = new Criteria(criteria); + + assertEquals("testCriteriaCriteria", criteria.isAsyncMessageReturnSelected(), copy.isAsyncMessageReturnSelected()); + assertEquals("testCriteriaCriteria", criteria.isAsyncMessageSelected(), copy.isAsyncMessageSelected()); + assertEquals("testCriteriaCriteria", criteria.isCaseSenstiveSelected(), copy.isCaseSenstiveSelected()); + assertEquals("testCriteriaCriteria", criteria.isLifeLineSelected(), copy.isLifeLineSelected()); + assertEquals("testCriteriaCriteria", criteria.isStopSelected(), copy.isStopSelected()); + assertEquals("testCriteriaCriteria", criteria.isSyncMessageReturnSelected(), copy.isSyncMessageReturnSelected()); + assertEquals("testCriteriaCriteria", criteria.isSyncMessageSelected(), copy.isSyncMessageSelected()); + assertEquals("testCriteriaCriteria", criteria.getExpression(), copy.getExpression()); + assertEquals("testCriteriaCriteria", criteria.getPattern().pattern(), copy.getPattern().pattern()); + } + + /** + * Test accessor methods. + */ + @Test + public void testAccessors() { + Criteria criteria = new Criteria(); + criteria.setAsyncMessageReturnSelected(true); + criteria.setAsyncMessageSelected(true); + criteria.setCaseSenstiveSelected(true); + criteria.setLifeLineSelected(true); + criteria.setStopSelected(true); + criteria.setSyncMessageReturnSelected(true); + criteria.setSyncMessageSelected(true); + criteria.setExpression("test.*"); + + // set true to all flags + assertTrue("testAccessors", criteria.isAsyncMessageReturnSelected()); + assertTrue("testAccessors", criteria.isAsyncMessageSelected()); + assertTrue("testAccessors", criteria.isCaseSenstiveSelected()); + assertTrue("testAccessors", criteria.isLifeLineSelected()); + assertTrue("testAccessors", criteria.isStopSelected()); + assertTrue("testAccessors", criteria.isSyncMessageReturnSelected()); + assertTrue("testAccessors", criteria.isSyncMessageSelected()); + assertEquals("testAccessors", "test.*", criteria.getExpression()); + assertNotNull("testAccessors", criteria.getPattern()); + assertEquals("testAccessors", "test.*", criteria.getPattern().pattern()); + assertEquals("testAccessors", 0, criteria.getPattern().flags() & Pattern.CASE_INSENSITIVE); + + // set false to all flags + criteria.setAsyncMessageReturnSelected(false); + criteria.setAsyncMessageSelected(false); + criteria.setCaseSenstiveSelected(false); + criteria.setLifeLineSelected(false); + criteria.setStopSelected(false); + criteria.setSyncMessageReturnSelected(false); + criteria.setSyncMessageSelected(false); + + assertFalse("testAccessors", criteria.isAsyncMessageReturnSelected()); + assertFalse("testAccessors", criteria.isAsyncMessageSelected()); + assertFalse("testAccessors", criteria.isCaseSenstiveSelected()); + assertFalse("testAccessors", criteria.isLifeLineSelected()); + assertFalse("testAccessors", criteria.isStopSelected()); + assertFalse("testAccessors", criteria.isSyncMessageReturnSelected()); + assertFalse("testAccessors", criteria.isSyncMessageSelected()); + assertEquals("testAccessors", "test.*", criteria.getExpression()); + assertNotNull("testAccessors", criteria.getPattern()); + assertEquals("testAccessors", "test.*", criteria.getPattern().pattern()); + assertEquals("testAccessors", Pattern.CASE_INSENSITIVE, criteria.getPattern().flags() & Pattern.CASE_INSENSITIVE); + } + + /** + * Test compartTo method. + */ + @Test + public void testCompareTo() { + Criteria criteria = new Criteria(); + criteria.setExpression("test"); + criteria.setLifeLineSelected(true); + criteria.setSyncMessageSelected(true); + + Criteria copy = new Criteria(criteria); + assertTrue("testCompareTo", criteria.compareTo(copy)); + assertTrue("testCompareTo", copy.compareTo(criteria)); + assertTrue("testCompareTo", criteria.compareTo(criteria)); + + copy.setExpression(null); + assertFalse("testCompareTo", criteria.compareTo(copy)); + assertFalse("testCompareTo", copy.compareTo(criteria)); + + criteria.setExpression(null); + assertTrue("testCompareTo", criteria.compareTo(copy)); + assertTrue("testCompareTo", copy.compareTo(criteria)); + + criteria.setExpression("test"); + copy.setExpression("test.*[12345]"); + assertFalse("testCompareTo", criteria.compareTo(copy)); + assertFalse("testCompareTo", copy.compareTo(criteria)); + + copy.setExpression("test"); + copy.setAsyncMessageReturnSelected(true); + assertFalse("testCompareTo", criteria.compareTo(copy)); + assertFalse("testCompareTo", copy.compareTo(criteria)); + } + + /** + * Test save to disk. + */ + @Test + public void testSave() { + DialogSettings settings = new DialogSettings("mysettings"); + + Criteria criteria = new Criteria(); + criteria.setExpression("test"); + criteria.setLifeLineSelected(true); + criteria.setSyncMessageSelected(true); + + // Save the criteria to the dialog settings + criteria.save(settings); + + // Check if all values are saved as expected + assertEquals("testSave", "test", settings.get("expression")); + assertEquals("testSave", "false", settings.get("isCaseSenstiveSelected")); + assertEquals("testSave", "false", settings.get("isAsyncMessageReturnSelected")); + assertEquals("testSave", "false", settings.get("isAsyncMessageSelected")); + assertEquals("testSave", "true", settings.get("isLifeLineSelected")); + assertEquals("testSave", "false", settings.get("isStopSelected")); + assertEquals("testSave", "false", settings.get("isSyncMessageReturnSelected")); + assertEquals("testSave", "true", settings.get("isSyncMessageSelected")); + } + + /** + * Test restore from disk. + */ + @Test + public void testLoad() { + DialogSettings settings = new DialogSettings("mysettings"); + + Criteria criteria = new Criteria(); + criteria.setExpression("test"); + criteria.setLifeLineSelected(true); + criteria.setSyncMessageSelected(true); + + // Save the criteria to the dialog settings + criteria.save(settings); + + // Load the criteria from the dialog settings + Criteria copy = new Criteria(); + copy.load(settings); + + assertTrue("testCompareTo", criteria.compareTo(copy)); + assertTrue("testCompareTo", copy.compareTo(criteria)); + } + + /** + * Test graph node summary usage. + */ + @Test + public void testGetGraphNodeSummary() { + + // Create a dummy provider + ISDFilterProvider provider = new ISDFilterProvider() { + + @Override + public boolean isNodeSupported(int nodeType) { + return true; + } + + @Override + public String getNodeName(int nodeType, String loaderClassName) { + // not clear about purpose loaderClassName + switch (nodeType) { + case ISDGraphNodeSupporter.LIFELINE: + return "MyLifeline"; + case ISDGraphNodeSupporter.SYNCMESSAGE: + return "MySyncMessage"; + case ISDGraphNodeSupporter.SYNCMESSAGERETURN: + return "MySyncMessageReturn"; + case ISDGraphNodeSupporter.ASYNCMESSAGE: + return "MyAsyncMessage"; + case ISDGraphNodeSupporter.ASYNCMESSAGERETURN: + return "MyAsyncMessageReturn"; + case ISDGraphNodeSupporter.STOP: + return "MyStop"; + default: + return ""; + } + } + + @Override + public boolean filter(List filters) { + return false; + } + }; + + Criteria criteria = new Criteria(); + criteria.setExpression("BALL_.*"); + criteria.setAsyncMessageReturnSelected(true); + criteria.setAsyncMessageSelected(true); + criteria.setLifeLineSelected(true); + criteria.setStopSelected(true); + criteria.setSyncMessageReturnSelected(true); + criteria.setSyncMessageSelected(true); + + // Test summary when provider is available + String summary = criteria.getGraphNodeSummary(provider, null); + assertEquals("testGetGraphNodeSummary", "[MyLifeline or MySyncMessage or MySyncMessageReturn or MyAsyncMessage or MyAsyncMessageReturn or MyStop]", summary); + + // Test default summary when no provider is provided + summary = criteria.getGraphNodeSummary(null, null); + assertEquals("testGetGraphNodeSummary", "[Lifeline or Synchronous message or Synchronous message return or Asynchronous message or Asynchronous message return or Stop]", summary); + + } + + /** + * Test matches algorithm. + */ + @Test + public void testMatches() { + Criteria criteria = new Criteria(); + criteria.setExpression("BALL_.*"); + + /* + * Note that method matches uses the Pattern class. Test + * only case sensitive/case insensitive case. All other regular + * expression cases are covered by Pattern class. + */ + + // case insensitive + assertTrue("testMatches", criteria.matches("BALL_REQUEST")); + assertTrue("testMatches", criteria.matches("BALL_REPLY")); + assertTrue("testMatches", criteria.matches("BALL_R")); + assertTrue("testMatches", criteria.matches("ball_request")); + assertTrue("testMatches", criteria.matches("ball_request")); + assertFalse("testMatches", criteria.matches("NOBALL_REQUEST")); + assertFalse("testMatches", criteria.matches("BLABLA")); + + // case sensitive + criteria.setCaseSenstiveSelected(true); + assertTrue("testMatches", criteria.matches("BALL_REQUEST")); + assertTrue("testMatches", criteria.matches("BALL_REPLY")); + assertTrue("testMatches", criteria.matches("BALL_R")); + assertFalse("testMatches", criteria.matches("ball_request")); + assertFalse("testMatches", criteria.matches("ball_request")); + assertFalse("testMatches", criteria.matches("NOBALL_REQUEST")); + assertFalse("testMatches", criteria.matches("BLABLA")); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/load/AllTests.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/load/AllTests.java new file mode 100644 index 0000000000..69d6422661 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/load/AllTests.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.load; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for testing loader manager of UML2SD extension point. + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + LoadersManagerTest.class +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/load/LoadersManagerTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/load/LoadersManagerTest.java new file mode 100644 index 0000000000..c2ae7f6cb3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/load/LoadersManagerTest.java @@ -0,0 +1,157 @@ +/********************************************************************** + * Copyright (c) 2011, 2013 Ericsson. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.load; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.load.IUml2SDLoader; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.load.LoadersManager; +import org.eclipse.ui.PlatformUI; +import org.junit.Test; + +/** + * Test cases class to test loader manager of UML2SD extension point. + */ +public class LoadersManagerTest { + + private final static String SDVIEW_WITH_ONE_LOADER = "org.eclipse.linuxtools.tmf.ui.tests.testSDView1Loader"; + private final static String SDVIEW_WITH_MULTIPLE_LOADER = "org.eclipse.linuxtools.tmf.ui.tests.testSDView2Loaders"; + private final static String TEST_LOADER_CLASS_NAME = "org.eclipse.linuxtools.tmf.ui.tests.uml2sd.load.TestLoaders"; + private final static String TMF_UML2SD_LOADER_CLASS_NAME = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.loader.TmfUml2SDSyncLoader"; + + private static final String LOADER_TAG = "uml2SDLoader"; + private static final String LOADER_PREFIX = LOADER_TAG + "."; + + /** + * Tests of loader manager singleton class. + */ + @Test + public void testLoaderManager() { + SDView view = null; + try { + + /* + * Test creation of a loader (one per SD view) + */ + + // Open view + // Note this will create the default loader! + view = (SDView)PlatformUI.getWorkbench() + .getActiveWorkbenchWindow() + .getActivePage() + .showView(SDVIEW_WITH_ONE_LOADER); + + IUml2SDLoader defaultLoader = LoadersManager.getInstance().getCurrentLoader(SDVIEW_WITH_ONE_LOADER, view); + assertNotNull("testLoaderManager", defaultLoader); + + // Test createLoader where loader doesn't exist + assertNull("testLoaderManager", LoadersManager.getInstance().createLoader("blabla", view)); + + // Test createLoader + IUml2SDLoader loader = LoadersManager.getInstance().createLoader(TEST_LOADER_CLASS_NAME, view); + + assertNotNull("testLoaderManager", loader); + assertEquals("testLoaderManager", "Test Loader", loader.getTitleString()); + assertEquals("testLoaderManager", loader, LoadersManager.getInstance().getCurrentLoader(SDVIEW_WITH_ONE_LOADER)); + + // compare loader and default loader. Even if they are the same class, they are different instances + assertFalse("testLoaderManager", loader==defaultLoader); + + // test getCurrentLoader(viewId, view) + IUml2SDLoader loader2 = LoadersManager.getInstance().getCurrentLoader(SDVIEW_WITH_ONE_LOADER, view); + assertEquals("testLoaderManager", loader, loader2); + + // Hide the view + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().hideView(view); + + // test that view restores the previous associated loader + view = (SDView)PlatformUI.getWorkbench() + .getActiveWorkbenchWindow() + .getActivePage() + .showView(SDVIEW_WITH_ONE_LOADER); + + // Well, this is the only way test which loader is set + assertEquals("testLoaderManager", "Sequence Diagram - First Page", view.getFrame().getName()); + + // Test view == null + assertNull("testLoaderManager", LoadersManager.getInstance().createLoader(TEST_LOADER_CLASS_NAME, null)); + + // Hide the view + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().hideView(view); + + /* + * Test creation of loaders with re-uses the same SD view + */ + + // test that view restores the previous associated loader + view = (SDView)PlatformUI.getWorkbench() + .getActiveWorkbenchWindow() + .getActivePage() + .showView(SDVIEW_WITH_MULTIPLE_LOADER); + + // Test that default loader is set. Note that 2 default loaders are define in the plugin.xml and the + // the first one should be selected. + + // Well, this is the only way test which loader is set + assertEquals("testLoaderManager", "Sequence Diagram - First Page", view.getFrame().getName()); + + loader = LoadersManager.getInstance().getCurrentLoader(SDVIEW_WITH_MULTIPLE_LOADER, view); + assertNotNull("testLoaderManager", loader); + assertEquals("testLoaderManager", "Test Loader", loader.getTitleString()); + assertEquals("testLoaderManager", loader, LoadersManager.getInstance().getCurrentLoader(SDVIEW_WITH_MULTIPLE_LOADER)); + + // Test createLoader for loader with class name TMF_UML2SD_LOADER_CLASS_NAME + loader = LoadersManager.getInstance().createLoader(TMF_UML2SD_LOADER_CLASS_NAME, view); + + assertNotNull("testLoaderManager", loader); + assertEquals("testLoaderManager", "Component Interactions", loader.getTitleString()); + assertEquals("testLoaderManager", loader, LoadersManager.getInstance().getCurrentLoader(SDVIEW_WITH_MULTIPLE_LOADER)); + + // Verify if the correct loader is stored in the preferences as the current loader for this view + assertEquals("testLoaderManager", TMF_UML2SD_LOADER_CLASS_NAME, getSavedLoader(SDVIEW_WITH_MULTIPLE_LOADER)); + + // Test createLoader for loader with class name TEST_LOADER_CLASS_NAME + loader = LoadersManager.getInstance().createLoader(TEST_LOADER_CLASS_NAME, view); + + assertNotNull("testLoaderManager", loader); + assertEquals("testLoaderManager", "Test Loader", loader.getTitleString()); + assertEquals("testLoaderManager", loader, LoadersManager.getInstance().getCurrentLoader(SDVIEW_WITH_MULTIPLE_LOADER)); + + // Verify if the correct loader is stored in the preferences as the current loader for this view + assertEquals("testLoaderManager", TEST_LOADER_CLASS_NAME, getSavedLoader(SDVIEW_WITH_MULTIPLE_LOADER)); + assertEquals("testLoaderManager", TEST_LOADER_CLASS_NAME, LoadersManager.getInstance().getSavedLoader(SDVIEW_WITH_MULTIPLE_LOADER)); + + // Hide the view + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().hideView(view); + + // Test reset loader + LoadersManager.getInstance().resetLoader(SDVIEW_WITH_MULTIPLE_LOADER); + + } catch (Exception e) { + e.printStackTrace(); + fail(); + } + } + + private static String getSavedLoader(String viewId) { + IPreferenceStore p = Activator.getDefault().getPreferenceStore(); + return p.getString(LOADER_PREFIX + viewId); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/AllTests.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/AllTests.java new file mode 100644 index 0000000000..2aba1ebe7c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/AllTests.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2011-2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.loader; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for testing the TmfUml2SDSyncLoader class. + * + * @author Bernd Hufmann + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TmfUml2SDSyncLoaderExpTest.class, + TmfUml2SDSyncLoaderFilterTest.class, + TmfUml2SDSyncLoaderFindTest.class, + TmfUml2SDSyncLoaderPagesTest.class, + TmfUml2SDSyncLoaderSignalTest.class, + TmfUml2SDSyncLoaderTimeTest.class +}) +public class AllTests { + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/IUml2SDTestConstants.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/IUml2SDTestConstants.java new file mode 100644 index 0000000000..ae83874645 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/IUml2SDTestConstants.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.loader; + +/** + * Common constants for the TMF UML2SD test cases + * @author Bernd Hufmann + */ +public interface IUml2SDTestConstants { + + /** + * Timeout for waiting of jobs to finish (in milliseconds). + */ + public static final int WAIT_FOR_JOBS_DELAY = 1000; + /** + * Timeout for waiting for GUI display to refresh (in milliseconds). + */ + public static final int GUI_REFESH_DELAY = 1000; + /** + * Initial delay before indexing (in milliseconds). + */ + public static final int INITIAL_INDEX_DELAY = 1000; + /** + * Delay after broadcasting a TMF signal (in milliseconds) + */ + public static final int BROADCAST_DELAY = 2000; + /** + * Total number of pages of test trace. + */ + public static final int TOTAL_NUMBER_OF_PAGES = 9; + /** + * Number of messages per page (as defined for loader class) + */ + public static final int MAX_MESSEAGES_PER_PAGE = 10000; + /** + * Number of messages of last page of the test trace. + */ + public static final int NUM_MESSAGES_OF_LAST_PAGE = 32; + /** + * Default number of lifelines of test trace. + */ + public static final int DEFAULT_NUM_LIFELINES = 2; + /** + * Number of lifelines of test trace when all lifelines are visible. + */ + public static final int NUM_OF_ALL_LIFELINES = 3; + /** + * Page number of test trace where all lifelines are visible. + */ + public static final int PAGE_OF_ALL_LIFELINES = 4; + /** + * Time scale of test trace. + */ + public static final byte TIME_SCALE = -9; + /** + * Master player name (property of test trace) + */ + public static final String MASTER_PLAYER_NAME = "Master"; + /** + * First player name (property of test trace) + */ + public static final String FIRST_PLAYER_NAME = "player1"; + /** + * Second player name (property of test trace) + */ + public static final String SECOND_PLAYER_NAME = "player2"; + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/IUml2SdSignalValidator.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/IUml2SdSignalValidator.java new file mode 100644 index 0000000000..61d8d8c79c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/IUml2SdSignalValidator.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.loader; + +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; + +/** + * Interface for testing signal handling within TmfUml2SD + * + * @author Bernd Hufmann + */ +public interface IUml2SdSignalValidator { + /** + * @return if signal is received or not + */ + boolean isSignalReceived(); + /** + * Sets signal received value + * @param received boolean value to set + */ + void setSignalReceived(boolean received); + + /** + * @return whether source of signal is correct or not + */ + boolean isSourceError(); + /** + * Sets the source error flag. + * @param fIsSourceError boolean value to set + */ + void setSourceError(boolean fIsSourceError); + + /** + * @return whether received current time is correct or not + */ + boolean isCurrentTimeError(); + /** + * Sets the current time error flag. + * @param fIsCurrentTimeError boolean value to set + */ + void setCurrentTimeError(boolean fIsCurrentTimeError); + + /** + * @return whether received range is correct or not + */ + boolean isRangeError(); + /** + * Sets the range error flag. + * @param fIsRangeError boolean value to set + */ + void setRangeError(boolean fIsRangeError); + + /** + * @return whether signal was received or not + */ + boolean isSignalError(); + /** + * Sets signal error flag. + * @param fIsSignalError boolean value to set + */ + void setSignalError(boolean fIsSignalError); + + /** + * @return source of expected signal. + */ + Object getSource(); + /** + * Sets source of expected signal + * @param source expected source component + */ + void setSource(Object source); + + /** + * @return the expected current time. + */ + TmfTimestamp getCurrentTime(); + /** + * Sets the expected current time + * @param currentTime Time to set + */ + void setCurrentTime(TmfTimestamp currentTime); + + /** + * @return the expected current time range. + */ + TmfTimeRange getCurrentRange(); + /** + * Sets the expected current time range. + * @param currentRange the expected current time range to set + */ + void setCurrentRange(TmfTimeRange currentRange); + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderExpTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderExpTest.java new file mode 100644 index 0000000000..105b56136e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderExpTest.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (c) 2011-2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.loader; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.FilterCriteria; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.FilterListDialog; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDAdvancedPagingProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDPagingProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.loader.TmfUml2SDSyncLoader; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Test cases for Experiment handling. + * + * @author Bernd Hufmann + */ +public class TmfUml2SDSyncLoaderExpTest { + + private static Uml2SDTestFacility fFacility; + + /** + * Initialization + */ + @BeforeClass + public static void setUpClass() { + fFacility = Uml2SDTestFacility.getInstance(); + // create filter criteria (incl. save) + fFacility.createFilterCriteria(); + fFacility.selectExperiment(); + } + + /** + * Cleanup + */ + @AfterClass + public static void tearDownClass() { + fFacility.disposeExperiment(); + fFacility = null; + } + + /** + * Verify setup + * + * Verified Methods: loader.getTitleString() + * view.getPartName() + * view.getFrame() + * Expected result: Title, view name are set properly. + */ + @Test + public void verifySetup() { + assertEquals("getTitleString", "Component Interactions", fFacility.getLoader().getTitleString()); + assertEquals("getPartName", "Sequence Diagram", fFacility.getSdView().getPartName()); + assertNotNull("getFrame", fFacility.getSdView().getFrame()); + + fFacility.disposeExperiment(); + + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + verifyPage(0, 0, false, false, 0); + } + + /** + * Verify cancellation of ongoing indexing. + * + * Verified Methods: loader.experimentSelected(), loader.experimentDisposed(), loader.nextPage() + * Expected result: No exceptions during cancellation and nextPage() operation. + * + * Note this test is not sufficient to verify the concurrent access of the loader attributes + * by multiple threads. Contention might happen but it's not guaranteed. + */ + @Test + public void verifyCancel() { + for(int i = 0; i < 5; i++) { + fFacility.selectExperiment(false); + fFacility.delay(IUml2SDTestConstants.INITIAL_INDEX_DELAY); + + try { + fFacility.disposeExperiment(); + fFacility.getLoader().nextPage(); // to test out of bounce + // Note: To actually create an out of bound exception remove + // safety-checks in nextPage/moveToPage of loader class + } catch (Exception e){ + // No Exception expected + fail("exp.select/exp.dispose"); + } + } + } + + /** + * Verify disposed experiment. + * + * Verified Methods: loader.nextPage(), + * loader.pagesCount(), loader.hasNextPage(), loader.hasPrevPage(), + * frame.syncMessagesCount, frame.lifeLinesCount + * Expected result: Page values and filter are reset. + * + * Note this test is not sufficient to verify the concurrent access of the loader attributes + * by multiple threads. Contention might happen but it's not guaranteed. + */ + @Test + public void verifyDispose() { + verifyPage(0, 0, false, false, 0); + + // verify that all enable filters are disabled after disposal + List filter = FilterListDialog.getGlobalFilters(); + + for (FilterCriteria filterCriteria : filter) { + assertFalse("exp.dispose", filterCriteria.isActive()); + } + } + + /** + * Verify the disposal of the loader. + * + * Verified Methods: loader.dispose() + * Expected result: All providers are removed from SDView. + */ + @Test + public void verifyLoaderDispose() { + fFacility.getLoader().dispose(); + assertTrue("loader.dispose", fFacility.getSdView().getSDPagingProvider() == null); + assertTrue("loader.dispose", fFacility.getSdView().getSDFindProvider() == null); + assertTrue("loader.dispose", fFacility.getSdView().getSDFilterProvider() == null); + assertTrue("loader.dispose", fFacility.getSdView().getExtendedFindProvider() == null); + assertTrue("loader.dispose", fFacility.getSdView().getExtendedFilterProvider() == null); + + // Set again loader as signal handler, which was removed by the the dispose above + TmfSignalManager.register(fFacility.getLoader()); + } + + /** + * Verify setViewer. + * + * Verified Methods: loader.setViewer + * Expected result: Paging, find and filter provider are set + */ + @Test + public void testSetViewer() { + fFacility.getLoader().setViewer(fFacility.getSdView()); + ISDPagingProvider pagingProvider = fFacility.getSdView().getSDPagingProvider(); + assertTrue("loader.setViewer", pagingProvider != null); + assertTrue("loader.setViewer", pagingProvider instanceof ISDAdvancedPagingProvider); + assertTrue("loader.setViewer", pagingProvider instanceof TmfUml2SDSyncLoader); + + assertTrue("loader.setViewer", fFacility.getSdView().getSDFindProvider() != null); + + assertTrue("loader.setViewer", fFacility.getSdView().getSDFilterProvider() != null); + + // All other providers are not used. + assertTrue("loader.setViewer", fFacility.getSdView().getExtendedFindProvider() == null); + assertTrue("loader.setViewer", fFacility.getSdView().getExtendedFilterProvider() == null); + } + + private static void verifyPage(int currentPage, int numMsg, boolean hasNext, + boolean hasPrev, int lifelineCount) { + assertEquals("currentPage", currentPage, fFacility.getLoader().currentPage()); + assertEquals("syncMessageCount, ", numMsg, fFacility.getSdView().getFrame().syncMessageCount()); + if (hasNext) { + assertTrue("hasNextpage", fFacility.getLoader().hasNextPage()); + } else { + assertFalse("hasNextPage", fFacility.getLoader().hasNextPage()); + } + if (hasPrev) { + assertTrue("hasPrevPage", fFacility.getLoader().hasPrevPage()); + } else { + assertFalse("hasPrevPage", fFacility.getLoader().hasPrevPage()); + } + assertEquals("lifeLinesCount", lifelineCount, fFacility.getSdView().getFrame().lifeLinesCount()); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderFilterTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderFilterTest.java new file mode 100644 index 0000000000..5842a3c858 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderFilterTest.java @@ -0,0 +1,213 @@ +/******************************************************************************* + * Copyright (c) 2011-2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.loader; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Lifeline; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SyncMessage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.Criteria; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.FilterCriteria; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.loader.TmfSyncMessage; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Filter test cases. + * + * @author Bernd Hufmann + */ +public class TmfUml2SDSyncLoaderFilterTest { + + private static Uml2SDTestFacility fFacility; + private static List filterToSave; + + /** + * Initialization + */ + @BeforeClass + public static void setUpClass() { + fFacility = Uml2SDTestFacility.getInstance(); + fFacility.selectExperiment(); + + /* Create Filter Criteria */ + filterToSave = new ArrayList<>(); + Criteria criteria = new Criteria(); + criteria.setLifeLineSelected(true); + criteria.setExpression(IUml2SDTestConstants.FIRST_PLAYER_NAME); + filterToSave.add(new FilterCriteria(criteria, false, false)); + + criteria = new Criteria(); + criteria.setLifeLineSelected(true); + criteria.setExpression(IUml2SDTestConstants.MASTER_PLAYER_NAME); + filterToSave.add(new FilterCriteria(criteria, false, false)); + + criteria = new Criteria(); + criteria.setSyncMessageSelected(true); + criteria.setExpression("BALL_.*"); + filterToSave.add(new FilterCriteria(criteria, false, false)); + } + + /** + * Cleanup + */ + @AfterClass + public static void tearDownClass() { + fFacility.disposeExperiment(); + fFacility = null; + } + + /** + * Test Case set-up code. + */ + @Before + public void beforeTest(){ + // Make sure we are at the first page + fFacility.firstPage(); + } + + /** + * Test case clean-up code. + */ + @After + public void afterTest() { + filterToSave.get(0).setActive(false); + filterToSave.get(1).setActive(false); + filterToSave.get(2).setActive(false); + fFacility.getLoader().filter(filterToSave); + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + } + + /** + * Verify the filter lifelines (1 out of 2 is hidden) + * + * Verified Methods: loader.filter() + * Expected result: Only one lifeline is visible with no messages + */ + @Test + public void verifyFilter1of2() { + // Initialize the filter + filterToSave.get(0).setActive(true); + // Run the filter + fFacility.getLoader().filter(filterToSave); + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + + assertEquals("filter", 1, fFacility.getSdView().getFrame().lifeLinesCount()); + assertEquals("filter", IUml2SDTestConstants.MASTER_PLAYER_NAME, fFacility.getSdView().getFrame().getLifeline(0).getName()); + assertEquals("filter", 0, fFacility.getSdView().getFrame().syncMessageCount()); + } + + + /** + * Verify the filter lifelines (2 out of 2 are hidden) + * + * Verified Methods: loader.filter(), loader.fillCurrentPage() + * Expected result: Neiter liflines nor messages are visible + */ + @Test + public void verifyFilter2of2() { + // Initialize the filter + filterToSave.get(0).setActive(true); + filterToSave.get(1).setActive(true); + // Run the filter + fFacility.getLoader().filter(filterToSave); + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + + assertEquals("filter", 0, fFacility.getSdView().getFrame().lifeLinesCount()); + assertEquals("filter", 0, fFacility.getSdView().getFrame().syncMessageCount()); + } + + /** + * Verify removal of all filters + * + * Verified Methods: loader.filter(), loader.fillCurrentPage() + * Expected result: Everything is shown + */ + @Test + public void verifyRemoval() { + // First set 2 filter + filterToSave.get(0).setActive(true); + filterToSave.get(1).setActive(true); + fFacility.getLoader().filter(filterToSave); + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + + // Remove the filter + filterToSave.get(0).setActive(false); + filterToSave.get(1).setActive(false); + fFacility.getLoader().filter(filterToSave); + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + + assertEquals("filter", 2, fFacility.getSdView().getFrame().lifeLinesCount()); + assertEquals("filter", IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE, + fFacility.getSdView().getFrame().syncMessageCount()); + } + + /** + * Verify filter of messages + * + * Verified Methods: loader.filter(), loader.fillCurrentPage() + * Expected result: Only particular messages are shown + */ + @Test + public void verifyMessageFilter() { + // Initialize the filter + filterToSave.get(2).setActive(true); + // Run the filter + fFacility.getLoader().filter(filterToSave); + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + + assertEquals("filter", 2, fFacility.getSdView().getFrame().lifeLinesCount()); + assertEquals("filter", 6, fFacility.getSdView().getFrame().syncMessageCount()); + + String messages[] = { "REGISTER_PLAYER_REQUEST", "REGISTER_PLAYER_REPLY", + "GAME_REQUEST", "GAME_REPLY", "START_GAME_REQUEST", "START_GAME_REPLY" }; + + for (int i = 0; i < messages.length; i++) { + SyncMessage msg = fFacility.getSdView().getFrame().getSyncMessage(i); + assertTrue("filter", msg instanceof TmfSyncMessage); + assertEquals("filter", messages[i], msg.getName()); + } + } + + /** + * Verify filter lifeline (1 out of three lifelines). Note that filter was + * set during change of page. + * + * Verified Methods: loader.filter(), loader.fillCurrentPage() + * Expected result: Only 2 lifelines and their interactions are shown + */ + @Test + public void verifyFilter1of3() { + filterToSave.get(0).setActive(true); + fFacility.getLoader().filter(filterToSave); + fFacility.setPage(IUml2SDTestConstants.PAGE_OF_ALL_LIFELINES); + + assertEquals("filter", 2, fFacility.getSdView().getFrame().lifeLinesCount()); + String lifelines[] = { IUml2SDTestConstants.MASTER_PLAYER_NAME, IUml2SDTestConstants.SECOND_PLAYER_NAME }; + + for (int i = 0; i < lifelines.length; i++) { + Lifeline line = fFacility.getSdView().getFrame().getLifeline(i); + assertEquals("filter", lifelines[i], line.getName()); + } + + assertTrue(fFacility.getSdView().getFrame().syncMessageCount() > 0); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderFindTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderFindTest.java new file mode 100644 index 0000000000..ebb359fda0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderFindTest.java @@ -0,0 +1,338 @@ +/******************************************************************************* + * Copyright (c) 2011-2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.loader; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Lifeline; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.Criteria; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.loader.TmfSyncMessage; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Search Test Cases. + * + * @author Bernd Hufmann + */ +public class TmfUml2SDSyncLoaderFindTest { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // Test case 002 expected values + final static private Uml2SDTestTimestamp TC_002_TIME_VALUE = new Uml2SDTestTimestamp(9788642104149L); + final static private String TC_002_MESSAGE_NAME = "GAME_REQUEST"; + final static private int TC_002_PAGE_VALUE = 0; + final static private int TC_002_START_OCCURRANCE = 3; + final static private int TC_002_END_OCCURRANCE = TC_002_START_OCCURRANCE; + final static private String TC_002_START_LIFELINE = IUml2SDTestConstants.FIRST_PLAYER_NAME; + final static private String TC_002_END_LIFELINE = IUml2SDTestConstants.MASTER_PLAYER_NAME; + + // Test case 003 expected values + final static private Uml2SDTestTimestamp TC_003_TIME_VALUE = new Uml2SDTestTimestamp(9788642113228L); + final static private String TC_003_MESSAGE_NAME = "GAME_REPLY"; + final static private int TC_003_PAGE_VALUE = 0; + final static private int TC_003_START_OCCURRANCE = 4; + final static private int TC_003_END_OCCURRANCE = TC_003_START_OCCURRANCE; + final static private String TC_003_START_LIFELINE = IUml2SDTestConstants.MASTER_PLAYER_NAME; + final static private String TC_003_END_LIFELINE = IUml2SDTestConstants.FIRST_PLAYER_NAME; + + // Test case 004 expected values + final static private Uml2SDTestTimestamp TC_004_TIME_VALUE = new Uml2SDTestTimestamp(9791893030834L); + final static private String TC_004_MESSAGE_NAME = "GAME_REQUEST"; + final static private int TC_004_PAGE_VALUE = 4; + final static private int TC_004_START_OCCURRANCE = 19; + final static private int TC_004_END_OCCURRANCE = TC_004_START_OCCURRANCE; + final static private String TC_004_START_LIFELINE = IUml2SDTestConstants.SECOND_PLAYER_NAME; + final static private String TC_004_END_LIFELINE = IUml2SDTestConstants.MASTER_PLAYER_NAME; + + // Test case 005 expected values + final static private int TC_005_PAGE_VALUE = 0; + final static private String TC_005_LIFELINE_NAME = IUml2SDTestConstants.FIRST_PLAYER_NAME; + + // Test case 006 expected values + final static private int TC_006_PAGE_VALUE = 4; + final static private String TC_006_LIFELINE_NAME = IUml2SDTestConstants.SECOND_PLAYER_NAME; + + // Fields used in tests + private static Uml2SDTestFacility fFacility; + private static Uml2SDSignalValidator fTmfComponent; + private static Criteria criteria; + private static List selection; + private static TmfSyncMessage msg; + private static Lifeline lifeline; + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Initialization + */ + @BeforeClass + public static void setUpClass() { + fFacility = Uml2SDTestFacility.getInstance(); + fFacility.selectExperiment(); + fTmfComponent = new Uml2SDSignalValidator(); + } + + /** + * Cleanup + */ + @AfterClass + public static void tearDownClass() { + fTmfComponent.dispose(); + fFacility.disposeExperiment(); + fFacility = null; + } + + /** + * Verify the ISDGraphNodeSupporter implementation. + * + * Verified Methods: loader.isNodeSupported(), loader.getNodeName() + * Expected result: Correct values are returned, i.e. only lifelines and + * sync. messages are supported. + */ + @Test + public void verifyISDGraphNodeSupporter() { + + fFacility.firstPage(); + + assertTrue("isNodeSupported", fFacility.getLoader().isNodeSupported(ISDGraphNodeSupporter.LIFELINE)); + assertTrue("isNodeSupported", fFacility.getLoader().isNodeSupported(ISDGraphNodeSupporter.SYNCMESSAGE)); + assertFalse("isNodeSupported", fFacility.getLoader().isNodeSupported(ISDGraphNodeSupporter.SYNCMESSAGERETURN)); + assertFalse("isNodeSupported", fFacility.getLoader().isNodeSupported(ISDGraphNodeSupporter.ASYNCMESSAGE)); + assertFalse("isNodeSupported", fFacility.getLoader().isNodeSupported(ISDGraphNodeSupporter.ASYNCMESSAGERETURN)); + assertFalse("isNodeSupported", fFacility.getLoader().isNodeSupported(ISDGraphNodeSupporter.STOP)); + + assertEquals("getNodeName", "Lifeline", fFacility.getLoader().getNodeName(ISDGraphNodeSupporter.LIFELINE, null)); + assertEquals("getNodeName", "Interaction", fFacility.getLoader().getNodeName(ISDGraphNodeSupporter.SYNCMESSAGE, null)); + assertEquals("getNodeName", "", fFacility.getLoader().getNodeName(ISDGraphNodeSupporter.SYNCMESSAGERETURN, null)); + assertEquals("getNodeName", "", fFacility.getLoader().getNodeName(ISDGraphNodeSupporter.ASYNCMESSAGE, null)); + assertEquals("getNodeName", "", fFacility.getLoader().getNodeName(ISDGraphNodeSupporter.ASYNCMESSAGERETURN, null)); + assertEquals("getNodeName", "", fFacility.getLoader().getNodeName(ISDGraphNodeSupporter.STOP, null)); + + fFacility.getLoader().cancel(); + } + + /** + * Verify 1st message find within page. + * + * Verified Methods: loader.find(), loader.moveToMessage() + * Expected result: Correct message is selected + */ + @Test + public void verifyFirstMessage() { + fFacility.firstPage(); + + criteria = new Criteria(); + criteria.setSyncMessageSelected(true); + criteria.setExpression("GAME_.*"); + + // set expected values + fTmfComponent.setSource(fFacility.getLoader()); + fTmfComponent.setCurrentTime(TC_002_TIME_VALUE); + fTmfComponent.setCurrentRange(null); // not used + fTmfComponent.setSignalReceived(false); + + fFacility.getLoader().find(criteria); + // Wait for the selection to finish - needed due to new platform behavior in Juno + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + assertTrue("find", fTmfComponent.isSignalReceived()); + assertFalse("find", fTmfComponent.isSignalError()); + assertFalse("find", fTmfComponent.isCurrentTimeError()); + assertFalse("find", fTmfComponent.isSourceError()); + + assertEquals("find", TC_002_PAGE_VALUE, fFacility.getLoader().currentPage()); + selection = fFacility.getSdView().getSDWidget().getSelection(); + assertNotNull(selection); + assertEquals("find", 1, selection.size()); + assertTrue(selection.get(0) instanceof TmfSyncMessage); + msg = (TmfSyncMessage) selection.get(0); + assertEquals("find", TC_002_MESSAGE_NAME, msg.getName()); + assertEquals("find", 0, TC_002_TIME_VALUE.compareTo(msg.getStartTime(), false)); + assertEquals("find", TC_002_START_OCCURRANCE, msg.getStartOccurrence()); + assertEquals("find", TC_002_END_OCCURRANCE, msg.getEndOccurrence()); + assertEquals("find", TC_002_START_LIFELINE, msg.getStartLifeline().getName()); + assertEquals("find", TC_002_END_LIFELINE, msg.getEndLifeline().getName()); + + /** + * Verify 2nd message find within page. + * + * Verified Methods: loader.find(), loader.moveToMessage() + * Expected result: Correct message is selected + */ + + // set expected values + fTmfComponent.setSource(fFacility.getLoader()); + fTmfComponent.setCurrentTime(TC_003_TIME_VALUE); + fTmfComponent.setCurrentRange(null); // not used + + fTmfComponent.setSignalReceived(false); + + fFacility.getLoader().find(criteria); + // Wait for the selection to finish - needed due to new platform behavior in Juno + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + assertTrue("find", fTmfComponent.isSignalReceived()); + assertFalse("find", fTmfComponent.isSignalError()); + assertFalse("find", fTmfComponent.isCurrentTimeError()); + assertFalse("find", fTmfComponent.isSourceError()); + + assertEquals("find", TC_003_PAGE_VALUE, fFacility.getLoader().currentPage()); + selection = fFacility.getSdView().getSDWidget().getSelection(); + assertNotNull(selection); + assertEquals("find", 1, selection.size()); + assertTrue(selection.get(0) instanceof TmfSyncMessage); + msg = (TmfSyncMessage) selection.get(0); + assertEquals("find", TC_003_MESSAGE_NAME, msg.getName()); + assertEquals("find", 0, TC_003_TIME_VALUE.compareTo(msg.getStartTime(), false)); + assertEquals("find", TC_003_START_OCCURRANCE, msg.getStartOccurrence()); + assertEquals("find", TC_003_END_OCCURRANCE, msg.getEndOccurrence()); + assertEquals("find", TC_003_START_LIFELINE, msg.getStartLifeline().getName()); + assertEquals("find", TC_003_END_LIFELINE, msg.getEndLifeline().getName()); + + /** + * Verify 1st message across page. + * + * Verified Methods: loader.find(), loader.moveToPage(), loader.moveToMessage() + * Expected result: Correct message is selected + */ + // set expected values + fTmfComponent.setSource(fFacility.getLoader()); + fTmfComponent.setCurrentTime(TC_004_TIME_VALUE); + fTmfComponent.setCurrentRange(new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH)); // not used + + fTmfComponent.setSignalReceived(false); + + fFacility.getLoader().find(criteria); + fFacility.waitForJobs(); // find across pages uses a job + // to make sure pageRequest has been started before calling waitforCompletion() + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + fFacility.getLoader().waitForCompletion(); + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + + assertTrue("find", fTmfComponent.isSignalReceived()); + assertFalse("find", fTmfComponent.isSignalError()); + assertFalse("find", fTmfComponent.isCurrentTimeError()); + assertFalse("find", fTmfComponent.isSourceError()); + + assertEquals("find", TC_004_PAGE_VALUE, fFacility.getLoader().currentPage()); + selection = fFacility.getSdView().getSDWidget().getSelection(); + assertNotNull(selection); + assertEquals("find", 1, selection.size()); + assertTrue(selection.get(0) instanceof TmfSyncMessage); + msg = (TmfSyncMessage) selection.get(0); + assertEquals("find", TC_004_MESSAGE_NAME, msg.getName()); + assertEquals("find", 0, TC_004_TIME_VALUE.compareTo(msg.getStartTime(), false)); + assertEquals("find", TC_004_START_OCCURRANCE, msg.getStartOccurrence()); + assertEquals("find", TC_004_END_OCCURRANCE, msg.getEndOccurrence()); + assertEquals("find", TC_004_START_LIFELINE, msg.getStartLifeline().getName()); + assertEquals("find", TC_004_END_LIFELINE, msg.getEndLifeline().getName()); + + // cancel find and go back to first page + fFacility.getLoader().cancel(); + } + + /** + * Verify find of lifeline within page. + * + * Verified Methods: loader.find(), loader.moveToPage(), loader.moveToMessage() + * Expected result: Correct message is selected + */ + @Test + public void verifyFind() { + fFacility.firstPage(); + + criteria = new Criteria(); + criteria.setLifeLineSelected(true); + criteria.setExpression(IUml2SDTestConstants.FIRST_PLAYER_NAME); + fFacility.getLoader().find(criteria); + // Wait for the selection to finish - needed due to new platform behavior in Juno + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + + assertEquals("find", TC_005_PAGE_VALUE, fFacility.getLoader().currentPage()); + selection = fFacility.getSdView().getSDWidget().getSelection(); + assertNotNull(selection); + assertEquals("find", 1, selection.size()); + assertTrue(selection.get(0) instanceof Lifeline); + lifeline = (Lifeline) selection.get(0); + assertEquals("find", TC_005_LIFELINE_NAME, lifeline.getName()); + + /** + * Verify lifeline across page. + * + * Verified Methods: loader.find(), loader.moveToPage(), loader.moveToMessage() + * Expected result: Correct message is selected + */ + criteria = new Criteria(); + criteria.setLifeLineSelected(true); + criteria.setExpression(IUml2SDTestConstants.SECOND_PLAYER_NAME); + + fFacility.getLoader().find(criteria); + fFacility.waitForJobs(); // find across pages uses a job + // to make sure pageRequest has been started before calling waitforCompletion() + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + fFacility.getLoader().waitForCompletion(); + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + + assertEquals("find", TC_006_PAGE_VALUE, fFacility.getLoader().currentPage()); + selection = fFacility.getSdView().getSDWidget().getSelection(); + assertNotNull(selection); + assertEquals("find", 1, selection.size()); + assertTrue(selection.get(0) instanceof Lifeline); + lifeline = (Lifeline) selection.get(0); + assertEquals("find", TC_006_LIFELINE_NAME, lifeline.getName()); + + // cancel find and go back to first page + fFacility.getLoader().cancel(); + } + + /** + * Verify cancel ongoing search job. + * + * Verified Methods: loader.find(), loader.find() + * Expected result: Cancelled find + */ + @Test + public void verifyCancelSearch() { + + fFacility.firstPage(); + + criteria = new Criteria(); + criteria.setLifeLineSelected(true); + criteria.setExpression(IUml2SDTestConstants.SECOND_PLAYER_NAME); + + fFacility.getLoader().find(criteria); + fFacility.delay(200); // to make sure job was started + fFacility.getLoader().cancel(); + + assertEquals("find", 0, fFacility.getLoader().currentPage()); // we are still at the first page + + // cancel find and go back to first page + fFacility.getLoader().cancel(); + fFacility.firstPage(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderPagesTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderPagesTest.java new file mode 100644 index 0000000000..70e65f54db --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderPagesTest.java @@ -0,0 +1,215 @@ +/******************************************************************************* + * Copyright (c) 2011-2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.loader; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Test cases for pages handling. + * + * @author Bernd Hufmann + */ +public class TmfUml2SDSyncLoaderPagesTest { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private static Uml2SDTestFacility fFacility; + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Initialization + */ + @BeforeClass + public static void setUpClass() { + fFacility = Uml2SDTestFacility.getInstance(); + fFacility.selectExperiment(); + } + + /** + * Cleanup + */ + @AfterClass + public static void tearDownClass() { + fFacility.disposeExperiment(); + fFacility = null; + } + + /** + * Test Case: 001 + * Description: Test number of pages. + * Verified Methods: loader.pagesCount(). + * Expected result: ITestConstants.TOTAL_NUMBER_OF_PAGES of pages + */ + @Test + public void verifyPagesCount() { + assertEquals(IUml2SDTestConstants.TOTAL_NUMBER_OF_PAGES, fFacility.getLoader().pagesCount()); + } + + + /** + * Test Case: 002 + * Description: Tests next page feature. + * Verified Methods: loader.nextPage(), loader.fillCurrentPage(), loader.pagesCount(), + * loader.hasNextPage(), loader.hasPrevPage(), + * frame.syncMessagesCount, frame.lifeLinesCount + * Expected result: Expected values are return. + */ + @Test + public void verifyNextPage() { + // assuming we are at the first page + for(int i = 0; i < IUml2SDTestConstants.TOTAL_NUMBER_OF_PAGES-2; i++) { + fFacility.nextPage(); + + if (i+1 == IUml2SDTestConstants.PAGE_OF_ALL_LIFELINES) { + verifyPage(i+1, IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE, true, true, IUml2SDTestConstants.NUM_OF_ALL_LIFELINES); + } + else { + verifyPage(i+1, IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE, true, true); + } + } + + // Last Page + fFacility.nextPage(); + verifyPage(IUml2SDTestConstants.TOTAL_NUMBER_OF_PAGES - 1, IUml2SDTestConstants.NUM_MESSAGES_OF_LAST_PAGE, false, true); + + // Check for index out of bounce + try { + fFacility.getLoader().nextPage(); + } catch (Exception e) { + fail(); + } + + fFacility.firstPage(); + } + + /** + * Test Case: 003 + * Description: Test previous page feature. + * Verified Methods: loader.prevPage(), loader.fillCurrentPage(), loader.pagesCount(), + * loader.hasNextPage(), loader.hasPrevPage(), + * frame.syncMessagesCount, frame.lifeLinesCount + * Expected result: Expected values are return. + */ + @Test + public void verifyPrevPage() { + // Last Page + fFacility.lastPage(); + assertEquals(IUml2SDTestConstants.TOTAL_NUMBER_OF_PAGES - 1, fFacility.getLoader().currentPage()); + assertEquals(IUml2SDTestConstants.NUM_MESSAGES_OF_LAST_PAGE, fFacility.getSdView().getFrame().syncMessageCount()); + assertFalse(fFacility.getLoader().hasNextPage()); + assertTrue(fFacility.getLoader().hasPrevPage()); + assertEquals(2, fFacility.getSdView().getFrame().lifeLinesCount()); + + for(int i = IUml2SDTestConstants.TOTAL_NUMBER_OF_PAGES-2; i > 0; i--) { + fFacility.prevPage(); + if (i == IUml2SDTestConstants.PAGE_OF_ALL_LIFELINES) { + verifyPage(i, IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE, true, true, IUml2SDTestConstants.NUM_OF_ALL_LIFELINES); + } else { + verifyPage(i, IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE, true, true); + } + } + + fFacility.prevPage(); + verifyPage(0, IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE, true, false); + + // Check for index out of bounce + try { + fFacility.getLoader().prevPage(); + } catch (Exception e) { + fail(); + } + } + + /** + * Test Case: 004 + * Description: Test first page feature. + * Verified Methods: loader.firstPage(), loader.fillCurrentPage(), loader.pagesCount(), + * loader.hasNextPage(), loader.hasPrevPage(), + * frame.syncMessagesCount, frame.lifeLinesCount + * Expected result: Expected values are return. + */ + @Test + public void verifyFirstPage() { + fFacility.lastPage(); + + // First Page + fFacility.firstPage(); + verifyPage(0, IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE, true, false); + } + + /** + * Test Case: 005 + * Description: Test last page feature. + * Verified Methods: loader.lastPage(), loader.pagesCount(), loader.hasNextPage(), loader.hasPrevPage() + * frame.syncMessagesCount, frame.lifeLinesCount + * Expected result: Expected values are return. + */ + @Test + public void verifyLastPage() { + fFacility.lastPage(); + verifyPage(IUml2SDTestConstants.TOTAL_NUMBER_OF_PAGES - 1, IUml2SDTestConstants.NUM_MESSAGES_OF_LAST_PAGE, false, true); + fFacility.firstPage(); + } + + /** + * Test Case: 006 + * Description: Test move to any page feature. + * Verified Methods: loader.pageNumberChanged(), loader.fillCurrentPage(), loader.pagesCount(), + * loader.hasNextPage(), loader.hasPrevPage(), + * frame.syncMessagesCount, frame.lifeLinesCount + * Expected result: Expected values are return. + */ + @Test + public void verifyPageNumberChanged() { + // any page + fFacility.setPage(IUml2SDTestConstants.PAGE_OF_ALL_LIFELINES); + verifyPage(IUml2SDTestConstants.PAGE_OF_ALL_LIFELINES, + IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE, true, true, + IUml2SDTestConstants.NUM_OF_ALL_LIFELINES); + fFacility.firstPage(); + } + + private static void verifyPage(int currentPage, int numMsg, boolean hasNext, boolean hasPrev) { + verifyPage(currentPage, numMsg, hasNext, hasPrev, IUml2SDTestConstants.DEFAULT_NUM_LIFELINES); + } + + private static void verifyPage(int currentPage, int numMsg, boolean hasNext, + boolean hasPrev, int lifelineCount) { + assertEquals("currentPage", currentPage, fFacility.getLoader().currentPage()); + assertEquals("syncMessageCount, ", numMsg, fFacility.getSdView().getFrame().syncMessageCount()); + if (hasNext) { + assertTrue("hasNextpage", fFacility.getLoader().hasNextPage()); + } else { + assertFalse("hasNextPage", fFacility.getLoader().hasNextPage()); + } + if (hasPrev) { + assertTrue("hasPrevPage", fFacility.getLoader().hasPrevPage()); + } else { + assertFalse("hasPrevPage", fFacility.getLoader().hasPrevPage()); + } + assertEquals("lifeLinesCount", lifelineCount, fFacility.getSdView().getFrame().lifeLinesCount()); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderSignalTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderSignalTest.java new file mode 100644 index 0000000000..07c05287fb --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderSignalTest.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + * Patrick Tasse - Support selection range + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.loader; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.eclipse.tracecompass.tmf.core.signal.TmfRangeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Test cases for signal handling. + * + * @author Bernd Hufmann + */ +public class TmfUml2SDSyncLoaderSignalTest { + + private static Uml2SDTestFacility fFacility; + private static Uml2SDSignalValidator fTmfComponent; + + private static TmfTimeRange range; + private static TmfTimestamp rangeWindow; + private static TmfTimestamp currentTime; + + /** + * Initialization + */ + @BeforeClass + public static void setUpClass() { + fFacility = Uml2SDTestFacility.getInstance(); + fFacility.selectExperiment(); + + range = new TmfTimeRange(new Uml2SDTestTimestamp(9789689220871L), new Uml2SDTestTimestamp(9789773881426L)); + // Get range window for tests below + rangeWindow = (TmfTimestamp) range.getEndTime().getDelta(range.getStartTime()); + currentTime = new Uml2SDTestTimestamp(9789773782043L); + + fFacility.getTrace().broadcast(new TmfRangeSynchSignal(fFacility, range)); + fFacility.getTrace().broadcast(new TmfTimeSynchSignal(fFacility, currentTime)); + fFacility.delay(IUml2SDTestConstants.BROADCAST_DELAY); + + fTmfComponent = new Uml2SDSignalValidator(); + } + + /** + * Cleanup + */ + @AfterClass + public static void tearDownClass() { + fFacility.disposeExperiment(); + fFacility = null; + } + + /** + * Test Case: 001 + * Description: Verify that time range signal is send with correct values when going to first page + * Verified Methods: broadcast() + * Expected result: Time range sync signal is sent with correct range and current time. + */ + @Test + public void verifyFirstPageSignal() { + currentTime = new Uml2SDTestTimestamp(9788641608418L); + range = new TmfTimeRange(currentTime, new Uml2SDTestTimestamp(currentTime.getValue() + rangeWindow.getValue())); + + fTmfComponent.setSignalError(false); + fTmfComponent.setSignalReceived(false); + fTmfComponent.setCurrentTimeError(false); + fTmfComponent.setRangeError(false); + fTmfComponent.setSourceError(false); + + // set expected values + fTmfComponent.setSource(fFacility.getLoader()); + fTmfComponent.setCurrentTime(currentTime); + fTmfComponent.setCurrentRange(range); + + fFacility.firstPage(); + assertTrue("TmfRangeSynchSignal", fTmfComponent.isSignalReceived()); + assertFalse("TmfRangeSynchSignal", fTmfComponent.isSignalError()); + assertFalse("TmfRangeSynchSignal", fTmfComponent.isCurrentTimeError()); + assertFalse("TmfRangeSynchSignal", fTmfComponent.isSourceError()); + assertFalse("TmfRangeSynchSignal", fTmfComponent.isRangeError()); + } + + /** + * Test Case: 002 + * Description: Verify that time sync signal is sent correctly after selection + * Verified Methods: loader.broadcast(), testSelectionChanged + * Expected result: Time sync signal is sent with correct current time. + */ + @Test + public void verifySelectionSignal() { + fTmfComponent.setSignalReceived(false); + + int count = fFacility.getSdView().getFrame().syncMessageCount(); + assertEquals("Test Preparation", IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE, count); + GraphNode node = fFacility.getSdView().getFrame().getSyncMessage(3); + + // set expected values + fTmfComponent.setSource(fFacility.getLoader()); + fTmfComponent.setCurrentTime(new Uml2SDTestTimestamp(9788642113228L)); + fTmfComponent.setCurrentRange(null); // not used + + fFacility.getSdView().getSDWidget().moveTo(node); // selects the given node + // Wait for the selection to finish - needed due to new platform behavior in Juno + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + assertTrue("TmfTimeSynchSignal", fTmfComponent.isSignalReceived()); + assertFalse("TmfTimeSynchSignal", fTmfComponent.isSignalError()); + assertFalse("TmfTimeSynchSignal", fTmfComponent.isCurrentTimeError()); + assertFalse("TmfTimeSynchSignal", fTmfComponent.isSourceError()); + + fTmfComponent.setSignalReceived(false); + + fTmfComponent.dispose(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderTimeTest.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderTimeTest.java new file mode 100644 index 0000000000..da6fc75a23 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/TmfUml2SDSyncLoaderTimeTest.java @@ -0,0 +1,311 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Alexandre Montplaisir - Port to JUnit4 + * Patrick Tasse - Support selection range + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.loader; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.signal.TmfRangeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.loader.TmfSyncMessage; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Test cases for time synchronization handling. + * + * @author Bernd Hufmann + */ +public class TmfUml2SDSyncLoaderTimeTest { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // Test case 001 expected values + final static private Uml2SDTestTimestamp TC_001_TIME_VALUE = new Uml2SDTestTimestamp(9788642228395L); + final static private String TC_001_MESSAGE_NAME = "START_GAME_REPLY"; + final static private int TC_001_PAGE_VALUE = 0; + final static private int TC_001_START_OCCURRANCE = 6; + final static private int TC_001_END_OCCURRANCE = TC_001_START_OCCURRANCE; + final static private String TC_001_START_LIFELINE = IUml2SDTestConstants.MASTER_PLAYER_NAME; + final static private String TC_001_END_LIFELINE = IUml2SDTestConstants.FIRST_PLAYER_NAME; + + // Test case 002 expected values + final static private Uml2SDTestTimestamp TC_002_TIME_VALUE = new Uml2SDTestTimestamp(9789689830722L); + final static private String TC_002_MESSAGE_NAME = "PAUSE_GAME_REQUEST"; + final static private int TC_002_PAGE_VALUE = 2; + final static private int TC_002_START_OCCURRANCE = 7; + final static private int TC_002_END_OCCURRANCE = TC_002_START_OCCURRANCE; + final static private String TC_002_START_LIFELINE = IUml2SDTestConstants.FIRST_PLAYER_NAME; + final static private String TC_002_END_LIFELINE = IUml2SDTestConstants.MASTER_PLAYER_NAME; + + // Test case 003 expected values + final static private Uml2SDTestTimestamp TC_003_TIME_VALUE = new Uml2SDTestTimestamp(9790750000000L); + final static private int TC_003_PAGE_VALUE = 4; + + // Test case 004 expected values + final static private int TC_004_PAGE_VALUE = 0; + + // Test case 005 expected values + final static private int TC_005_PAGE_VALUE = IUml2SDTestConstants.TOTAL_NUMBER_OF_PAGES - 1; + + // Test case 006 expected values + final static private Uml2SDTestTimestamp TC_006_TIME_VALUE = new Uml2SDTestTimestamp(9792420661655L); + final static private int TC_006_PAGE_VALUE = 4; + final static private int TC_006_START_OCCURRANCE = IUml2SDTestConstants.MAX_MESSEAGES_PER_PAGE; + final static private int TC_006_END_OCCURRANCE = TC_006_START_OCCURRANCE; + + // Test case 007 expected values + final static private Uml2SDTestTimestamp TC_007_TIME_VALUE = new Uml2SDTestTimestamp(9792420756010L); + final static private int TC_007_PAGE_VALUE = 5; + final static private int TC_007_START_OCCURRANCE = 1; + final static private int TC_007_END_OCCURRANCE = TC_007_START_OCCURRANCE; + + // Test case 008 expected values + final static private Uml2SDTestTimestamp TC_008_TIME_VALUE = new Uml2SDTestTimestamp(9788642228395L); + final static private int TC_008_PAGE_VALUE = 0; + final static private Uml2SDTestTimestamp TC_008_START_TIME_VALUE = new Uml2SDTestTimestamp(9788642228395L); + final static private Uml2SDTestTimestamp TC_008_END_TIME_VALUE = new Uml2SDTestTimestamp(9789164833324L); + + // Test case 009 expected values + final static private Uml2SDTestTimestamp TC_009_TIME_VALUE = new Uml2SDTestTimestamp(9789689220871L); + final static private int TC_009_PAGE_VALUE = 1; + final static private Uml2SDTestTimestamp TC_009_START_TIME_VALUE = TC_009_TIME_VALUE; + final static private Uml2SDTestTimestamp TC_009_END_TIME_VALUE = new Uml2SDTestTimestamp(9789773881426L); + + // Fields used in tests + private static Uml2SDTestFacility fFacility; + private static List selection; + private static TmfSyncMessage msg; + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Initialization + */ + @BeforeClass + public static void setUpClass() { + fFacility = Uml2SDTestFacility.getInstance(); + fFacility.selectExperiment(); + } + + /** + * Cleanup + */ + @AfterClass + public static void tearDownClass() { + fFacility.disposeExperiment(); + fFacility = null; + } + + /** + * Test Case: 001 + * Description: Verify synchToTime (exact time in page), selection of message in page + * Verified Methods: loader.syncToTime(), loader.moveToMessage(), loader.moveToMessageInPage() + * Expected result: Correct message is selected. + */ + @Test + public void verifySynchToTimeInPage() { + fFacility.getTrace().broadcast(new TmfTimeSynchSignal(this, TC_001_TIME_VALUE)); + fFacility.getLoader().waitForCompletion(); + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + assertEquals("synchToTime", TC_001_PAGE_VALUE, fFacility.getLoader().currentPage()); + selection = fFacility.getSdView().getSDWidget().getSelection(); + assertNotNull(selection); + assertEquals("synchToTime", 1, selection.size()); + assertTrue(selection.get(0) instanceof TmfSyncMessage); + msg = (TmfSyncMessage) selection.get(0); + assertEquals("synchToTime", TC_001_MESSAGE_NAME, msg.getName()); + assertEquals("synchToTime", 0, TC_001_TIME_VALUE.compareTo(msg.getStartTime(), false)); + assertEquals("synchToTime", TC_001_START_OCCURRANCE, msg.getStartOccurrence()); + assertEquals("synchToTime", TC_001_END_OCCURRANCE, msg.getEndOccurrence()); + assertEquals("synchToTime", TC_001_START_LIFELINE, msg.getStartLifeline().getName()); + assertEquals("synchToTime", TC_001_END_LIFELINE, msg.getEndLifeline().getName()); + } + + /** + * Test Case: 002 + * Description: Verify synchToTime (exact time outside of page), selection of message in page + * Verified Methods: loader.syncToTime(), loader.moveToMessage(), loader.moveToPage() + * Expected result: Correct message is selected. + */ + @Test + public void verifySynchToTimeOutsidePage() { + fFacility.getTrace().broadcast(new TmfTimeSynchSignal(this, TC_002_TIME_VALUE)); + fFacility.getLoader().waitForCompletion(); + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + assertEquals("synchToTime", TC_002_PAGE_VALUE, fFacility.getLoader().currentPage()); + selection = fFacility.getSdView().getSDWidget().getSelection(); + assertNotNull("synchToTime", selection); + assertEquals("synchToTime", 1, selection.size()); + assertTrue("synchToTime", selection.get(0) instanceof TmfSyncMessage); + msg = (TmfSyncMessage) selection.get(0); + assertEquals("synchToTime", TC_002_MESSAGE_NAME, msg.getName()); + assertEquals(0, TC_002_TIME_VALUE.compareTo(msg.getStartTime(), false)); + assertEquals("synchToTime", TC_002_START_OCCURRANCE, msg.getStartOccurrence()); + assertEquals("synchToTime", TC_002_END_OCCURRANCE, msg.getEndOccurrence()); + assertEquals(TC_002_START_LIFELINE, msg.getStartLifeline().getName()); + assertEquals(TC_002_END_LIFELINE, msg.getEndLifeline().getName()); + } + + + /** + * Test Case: 003 + * Description: Verify synchToTime (timestamp doesn't exist in trace), no selection of message in page + * Verified Methods: loader.syncToTime(), loader.moveToMessage(), loader.moveToPage() + * Expected result: Move to correct page, currentTime is updated so that focus on the currentTime, but no selection. + */ + @Test + public void verifySynchToTimeNonExisting() { + fFacility.getLoader().firstPage(); + + fFacility.getTrace().broadcast(new TmfTimeSynchSignal(this, TC_003_TIME_VALUE)); + fFacility.getLoader().waitForCompletion(); + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + assertEquals("synchToTime", 0, TC_003_TIME_VALUE.compareTo(fFacility.getLoader().getCurrentTime(), false)); + assertEquals("synchToTime", TC_003_PAGE_VALUE, fFacility.getLoader().currentPage()); + selection = fFacility.getSdView().getSDWidget().getSelection(); + assertNotNull("synchToTime", selection); + assertEquals("synchToTime", 0, selection.size()); + } + + /** + * Test Case: 004 + * Description: Verify synchToTime (timestamp < experiment time range start) + * Verified Methods: loader.syncToTime(), loader.moveToMessage(), loader.moveToPage() + * Expected result: Move to first page, focus on the beginning of the page, but no selection. + */ + @Test + public void verifySynchToTimeBeforeExpStart() { + fFacility.getTrace().broadcast(new TmfTimeSynchSignal(this, TmfTimestamp.BIG_BANG)); + fFacility.getLoader().waitForCompletion(); + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + assertEquals("synchToTime", TC_004_PAGE_VALUE, fFacility.getLoader().currentPage()); + selection = fFacility.getSdView().getSDWidget().getSelection(); + assertNotNull("synchToTime", selection); + assertEquals("synchToTime", 0, selection.size()); + } + + /** + * Test Case: 005 + * Description: Verify synchToTime (timestamp > experiment time range end) + * Verified Methods: loader.syncToTime(), loader.moveToMessage(), loader.moveToPage() + * Expected result: Move to last page, focus on the end of the page, but no selection. + */ + @Test + public void verifySynchToTimeAfterExpEnd() { + fFacility.getTrace().broadcast(new TmfTimeSynchSignal(this, TmfTimestamp.BIG_CRUNCH)); + fFacility.getLoader().waitForCompletion(); + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + assertEquals("synchToTime", TC_005_PAGE_VALUE, fFacility.getLoader().currentPage()); + selection = fFacility.getSdView().getSDWidget().getSelection(); + assertNotNull(selection); + assertEquals("synchToTime", 0, selection.size()); + } + + /** + * Test Case: 006 + * Description: Verify synchToTime (timestamp of last message in page) + * Verified Methods: loader.syncToTime(), loader.moveToMessage(), loader.moveToPage(), loader.moveToMessageInPage() + * Expected result: Move to correct page, selection of last message in page. + */ + @Test + public void verifySynchToTimeEqualsLast() { + fFacility.getTrace().broadcast(new TmfTimeSynchSignal(this, TC_006_TIME_VALUE)); + fFacility.getLoader().waitForCompletion(); + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + assertEquals("synchToTime", TC_006_PAGE_VALUE, fFacility.getLoader().currentPage()); + selection = fFacility.getSdView().getSDWidget().getSelection(); + assertNotNull("synchToTime", selection); + assertEquals("synchToTime", 1, selection.size()); + msg = (TmfSyncMessage) selection.get(0); + assertEquals("synchToTime", TC_006_START_OCCURRANCE, msg.getStartOccurrence()); + assertEquals("synchToTime", TC_006_END_OCCURRANCE, msg.getEndOccurrence()); + } + + /** + * Test Case: 007 + * Description: Verify synchToTime (timestamp of first message in page) + * Verified Methods: loader.syncToTime(), loader.moveToMessage(), loader.moveToPage() + * Expected result: Move to correct page, selection of last message in page. + */ + @Test + public void verifySynchToTimeFirst() { + fFacility.getTrace().broadcast(new TmfTimeSynchSignal(this, TC_007_TIME_VALUE)); + fFacility.getLoader().waitForCompletion(); + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + assertEquals("synchToTime", TC_007_PAGE_VALUE, fFacility.getLoader().currentPage()); + selection = fFacility.getSdView().getSDWidget().getSelection(); + assertNotNull("synchToTime", selection); + msg = (TmfSyncMessage) selection.get(0); + assertEquals("synchToTime", 1, selection.size()); + assertEquals("synchToTime", TC_007_START_OCCURRANCE, msg.getStartOccurrence()); + assertEquals("synchToTime", TC_007_END_OCCURRANCE, msg.getEndOccurrence()); + } + + /** + * Test Case: 008 + * Description: Verify time range signal (start, end time and current time are in same page) + * Verified Methods: loader.synchToTimeRange(), loader.moveToMessage(), loader.moveToMessageInPage() + * Expected result: Move to correct page(=page of start time of range), set focus on start time of range, but no selection of message. + */ + @Test + public void verifyTimeRangeSamePage() { + // 9788.642228395 (page 0) -> 9789.164833324 (page 0) with selected time 9788.642228395 (page 0) + fFacility.getLoader().firstPage(); + TmfTimeRange range = new TmfTimeRange(TC_008_START_TIME_VALUE, TC_008_END_TIME_VALUE); + fFacility.getLoader().waitForCompletion(); + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + fFacility.getTrace().broadcast(new TmfRangeSynchSignal(this, range)); + assertEquals("synchToTimeRange", TC_008_PAGE_VALUE, fFacility.getLoader().currentPage()); + assertNotNull("synchToTimeRange", fFacility.getLoader().getCurrentTime()); + assertEquals("synchToTimeRange", 0, TC_008_TIME_VALUE.compareTo(fFacility.getLoader().getCurrentTime(), false)); + selection = fFacility.getSdView().getSDWidget().getSelection(); + // We actually don't want something to be selected!!! + assertNotNull("synchToTimeRange", selection); + assertEquals("synchToTimeRange", 0, selection.size()); + } + + /** + * Test Case: 009 + * Description: Verify time range signal (start and end time are across 2 pages) + * Verified Methods: loader.synchToTimeRange(), loader.moveToMessage(), loader.moveToPage() + * Expected result: Move to correct page (=page of start time of range), set focus on start time of range, but no selection of message. + */ + @Test + public void verifyTimeRangeDifferentPages() { + TmfTimeRange range = new TmfTimeRange(TC_009_START_TIME_VALUE, TC_009_END_TIME_VALUE); + fFacility.getTrace().broadcast(new TmfRangeSynchSignal(this, range)); + fFacility.getLoader().waitForCompletion(); + fFacility.delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + assertEquals("synchToTimeRange", TC_009_PAGE_VALUE, fFacility.getLoader().currentPage()); + assertNotNull("synchToTimeRange", fFacility.getLoader().getCurrentTime()); + assertEquals("synchToTimeRange", 0, TC_009_TIME_VALUE.compareTo(fFacility.getLoader().getCurrentTime(), false)); + selection = fFacility.getSdView().getSDWidget().getSelection(); + // We actually don't want something to be selected!!! + assertNotNull("synchToTimeRange", selection); + assertEquals("synchToTimeRange", 0, selection.size()); + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/Uml2SDSignalValidator.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/Uml2SDSignalValidator.java new file mode 100644 index 0000000000..d84894c094 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/Uml2SDSignalValidator.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Patrick Tasse - Support selection range + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.loader; + +import org.eclipse.tracecompass.tmf.core.component.TmfComponent; +import org.eclipse.tracecompass.tmf.core.signal.TmfEndSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfRangeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfStartSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; + +/** + * Class to implement that certain signals are sent as well as are sent with correct content. + * + * @author Bernd Hufmann + */ +public class Uml2SDSignalValidator extends TmfComponent implements IUml2SdSignalValidator { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + private int fSignalDepth = 0; + private boolean fIsSignalReceived = false; + private boolean fIsSignalError = false; + private boolean fIsSourceError = false; + private boolean fIsCurrentTimeError = false; + private boolean fIsRangeError = false; + + private Object fSource = null; + private TmfTimestamp fCurrentTimestamp = null; + private TmfTimeRange fCurrentTimeRange = null; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + /** + * Constructor + */ + public Uml2SDSignalValidator() { + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + /** + * Signal handler for time synch signal. + * @param signal the signal to handle. + */ + @TmfSignalHandler + public void synchToTime(TmfTimeSynchSignal signal) { + // Set results so that it can be validated in the test case + setSignalReceived(true); + setSourceError(getSource() != signal.getSource()); + setCurrentTimeError(!getCurrentTime().equals(signal.getBeginTime())); + } + + /** + * Signal handler for time range synch signal. + * @param signal the signal to handle. + */ + @TmfSignalHandler + public void synchToTimeRange(TmfRangeSynchSignal signal) { + // Set results so that it can be validated in the test case + setSignalReceived(true); + if (getSource() != null) { + setSourceError(getSource() != signal.getSource()); + } + if (getCurrentRange() != null) { + setRangeError(!getCurrentRange().equals(signal.getCurrentRange())); + } + } + + /** + * Signal handler for handling start synch signal. + * @param signal the signal to handle. + */ + @TmfSignalHandler + public void startSynch(TmfStartSynchSignal signal) { + fSignalDepth++; + // make sure that the signal which is send by the loader class is not handled by the loader class + // after receiving it. i.e. it must not trigger a another signal + + // Set results so that it can be validated in the test case + setSignalError(fSignalDepth > 1); + } + + /** + * Signal handler for handling end synch signal. + * @param signal the signal to handle. + */ + @TmfSignalHandler + public void endSynch(TmfEndSynchSignal signal) { + fSignalDepth = fSignalDepth > 0 ? fSignalDepth - 1 : 0; + } + + @Override + public boolean isSignalReceived() { + return fIsSignalReceived; + } + + @Override + public void setSignalReceived(boolean received) { + fIsSignalReceived = received; + } + + @Override + public boolean isSourceError() { + return fIsSourceError; + } + + @Override + public void setSourceError(boolean fIsSourceError) { + this.fIsSourceError = fIsSourceError; + } + + @Override + public boolean isCurrentTimeError() { + return fIsCurrentTimeError; + } + + @Override + public void setCurrentTimeError(boolean fIsCurrentTimeError) { + this.fIsCurrentTimeError = fIsCurrentTimeError; + } + + @Override + public boolean isRangeError() { + return fIsRangeError; + } + + @Override + public void setRangeError(boolean fIsRangeError) { + this.fIsRangeError = fIsRangeError; + } + + @Override + public boolean isSignalError() { + return fIsSignalError; + } + + @Override + public void setSignalError(boolean fIsSignalError) { + this.fIsSignalError = fIsSignalError; + } + + @Override + public Object getSource() { + return fSource; + } + + @Override + public void setSource(Object source) { + fSource = source; + } + + @Override + public TmfTimestamp getCurrentTime() { + return fCurrentTimestamp; + } + + @Override + public void setCurrentTime(TmfTimestamp currentTime) { + fCurrentTimestamp = currentTime == null ? null : new TmfTimestamp(currentTime); + } + + @Override + public TmfTimeRange getCurrentRange() { + return fCurrentTimeRange; + } + + @Override + public void setCurrentRange(TmfTimeRange currentRange) { + fCurrentTimeRange = currentRange == null ? null : new TmfTimeRange(currentRange); + } +} + diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestFacility.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestFacility.java new file mode 100644 index 0000000000..931174c66a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestFacility.java @@ -0,0 +1,360 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.loader; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.core.trace.ITmfEventParser; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; +import org.eclipse.tracecompass.tmf.ui.tests.uml2sd.trace.TmfUml2SDTestTrace; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.Criteria; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.FilterCriteria; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.FilterListDialog; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.load.LoadersManager; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.loader.TmfUml2SDSyncLoader; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.osgi.framework.FrameworkUtil; + +/** + * Singleton class to facilitate the test cases. Creates UML2SD view and loader objects as well as provides + * utility methods for interacting with the loader/view. + * + * @author Bernd Hufmann + */ +public class Uml2SDTestFacility { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + private static Uml2SDTestFacility fInstance = null; + + private TmfUml2SDSyncLoader fLoader; + private SDView fSdView; + private TmfTraceStub fTrace = null; + private TmfUml2SDTestTrace fParser = null; + private TmfExperiment fExperiment = null; + + private volatile boolean fIsInitialized = false; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + private Uml2SDTestFacility() { + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + /** + * @return the singleton instance. + */ + public synchronized static Uml2SDTestFacility getInstance() { + if (fInstance == null) { + fInstance = new Uml2SDTestFacility(); + fInstance.init(); + } + return fInstance; + } + + /** + * Initial the test facility. + */ + public void init() { + + if (!fIsInitialized) { + + fParser = new TmfUml2SDTestTrace(); + fTrace = setupTrace(fParser); + fParser.setTrace(fTrace); + + IViewPart view; + try { + // Remove welcome view to avoid interference during test execution + view = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow() + .getActivePage() + .findView("org.eclipse.ui.internal.introview"); + + if (view != null) { + PlatformUI.getWorkbench() + .getActiveWorkbenchWindow() + .getActivePage().hideView(view); + } + + view = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow() + .getActivePage() + .showView("org.eclipse.linuxtools.tmf.ui.tmfUml2SDSyncView"); + + } catch (final PartInitException e) { + throw new RuntimeException(e); + } + + fSdView = (SDView) view; + fLoader = (TmfUml2SDSyncLoader)LoadersManager.getInstance().createLoader( + "org.eclipse.linuxtools.tmf.ui.views.uml2sd.loader.TmfUml2SDSyncLoader", fSdView); + + delay(3000); + fIsInitialized = true; + } + } + + + private TmfTraceStub setupTrace(final ITmfEventParser parser) { + + try { + // Create test trace object + final URL location = FileLocator.find(FrameworkUtil.getBundle(this.getClass()), new Path("tracesets/sdEvents"), null); + final File test = new File(FileLocator.toFileURL(location).toURI()); + return new TmfTraceStub(test.getPath(), 500, true, parser); + } catch (final TmfTraceException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } catch (final URISyntaxException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } catch (final IOException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + /** + * Dispose the resource + */ + public void dispose() { + if (fIsInitialized) { + ITmfTrace trace = fTrace; + TmfExperiment experiment = fExperiment; + if (trace == null || experiment == null) { + throw new IllegalStateException(); + } + + trace.broadcast(new TmfTraceClosedSignal(this, experiment)); + experiment.dispose(); + + // Wait for all Eclipse jobs to finish + waitForJobs(); + + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().hideView(fSdView); + fIsInitialized = false; + } + } + + /** + * Sleeps current thread or GUI thread for a given time. + * @param waitTimeMillis time in milliseconds to wait + */ + public void delay(final long waitTimeMillis) { + final Display display = Display.getCurrent(); + if (display != null) { + final long endTimeMillis = System.currentTimeMillis() + waitTimeMillis; + while(System.currentTimeMillis() < endTimeMillis) { + if (!display.readAndDispatch()) { + // We do not use Display.sleep because it might never wake up + // if there is no user interaction + try { + Thread.sleep(Math.min(waitTimeMillis, 10)); + } catch (final InterruptedException e) { + // Ignored + } + } + display.update(); + } + } else { + try { + Thread.sleep(waitTimeMillis); + } catch (final InterruptedException e) { + // Ignored + } + } + } + + /** + * Waits for all Eclipse jobs to finish + */ + public void waitForJobs() { + while (!Job.getJobManager().isIdle()) { + delay(IUml2SDTestConstants.WAIT_FOR_JOBS_DELAY); + } + } + + /** + * @return current UML2SD loader + */ + public TmfUml2SDSyncLoader getLoader() { + return fLoader; + } + + /** + * @return current SD view + */ + public SDView getSdView() { + return fSdView; + } + + /** + * @return current trace + */ + public TmfTraceStub getTrace() { + return fTrace; + } + + /** + * @return Trace parser + */ + public TmfUml2SDTestTrace getParser() { + return fParser; + } + + /** + * @return current experiment. + */ + public TmfExperiment getExperiment() { + return fExperiment; + } + + /** + * Go to next page; + */ + public void nextPage() { + fLoader.nextPage(); + fLoader.waitForCompletion(); + delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + } + + /** + * Go to previous page. + */ + public void prevPage() { + fLoader.prevPage(); + fLoader.waitForCompletion(); + delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + } + + /** + * Go to last page. + */ + public void lastPage() { + fLoader.lastPage(); + fLoader.waitForCompletion(); + delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + } + + /** + * Go to first page. + */ + public void firstPage() { + fLoader.firstPage(); + fLoader.waitForCompletion(); + delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + } + + /** + * @param page number to set + */ + public void setPage(final int page) { + fLoader.pageNumberChanged(page); + fLoader.waitForCompletion(); + delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + } + + /** + * @see org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.loader.Uml2SDTestFacility#selectExperiment(boolean) + */ + public void selectExperiment() { + this.selectExperiment(true); + } + + /** + * Selects the experiment. + * @param wait true to wait for indexing to finish else false + */ + public void selectExperiment(final boolean wait) { + fParser = new TmfUml2SDTestTrace(); + fTrace = setupTrace(fParser); + fParser.setTrace(fTrace); + + final ITmfTrace traces[] = new ITmfTrace[1]; + traces[0] = fTrace; + fExperiment = new TmfExperiment(ITmfEvent.class, "TestExperiment", traces) { + @Override + protected ITmfTraceIndexer createIndexer(int interval) { + return new TmfCheckpointIndexer(this, interval); + } + }; + fTrace.broadcast(new TmfTraceOpenedSignal(this, fExperiment, null)); + fTrace.broadcast(new TmfTraceSelectedSignal(this, fExperiment)); + if (wait) { + while (fExperiment.getNbEvents() == 0) { + delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + } + waitForJobs(); + delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + } + } + + /** + * Disposes the experiment. + */ + public void disposeExperiment() { + ITmfTrace trace = fTrace; + TmfExperiment experiment = fExperiment; + if (trace == null || experiment == null) { + throw new IllegalStateException(); + } + trace.broadcast(new TmfTraceClosedSignal(this, experiment)); + experiment.dispose(); + delay(IUml2SDTestConstants.GUI_REFESH_DELAY); + } + + /** + * Creates some global filter criteria and saves them to disk. + */ + public void createFilterCriteria() { + // Create Filter Criteria and save tme + final List filterToSave = new ArrayList<>(); + Criteria criteria = new Criteria(); + criteria.setLifeLineSelected(true); + criteria.setExpression(IUml2SDTestConstants.FIRST_PLAYER_NAME); + filterToSave.add(new FilterCriteria(criteria, true, false)); + + criteria = new Criteria(); + criteria.setSyncMessageSelected(true); + criteria.setExpression("BALL_.*"); + filterToSave.add(new FilterCriteria(criteria, true, false)); + FilterListDialog.saveFiltersCriteria(filterToSave); + } + + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestSetup.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestSetup.java new file mode 100644 index 0000000000..d446dd55cb --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestSetup.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.loader; + +import junit.extensions.TestSetup; +import junit.framework.Test; + +/** + * Test setup class for one-time setUp() and tearDown() across test cases. + */ +public class Uml2SDTestSetup extends TestSetup { + + /** + * Constructor + * @param test the test to use. + */ + public Uml2SDTestSetup(Test test) { + super(test); + } + + @Override + protected void setUp() throws Exception { + Uml2SDTestFacility.getInstance().init(); + } + + @Override + protected void tearDown() throws Exception { + Uml2SDTestFacility.getInstance().dispose(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestTimestamp.java b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestTimestamp.java new file mode 100644 index 0000000000..dbbb19e447 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/views/uml2sd/loader/Uml2SDTestTimestamp.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ui.tests.views.uml2sd.loader; + +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; + +/** + * Timestamp implementation for UML2SD test cases. + * + * @author Bernd Hufmann + * + */ +public class Uml2SDTestTimestamp extends TmfTimestamp { + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructor + * @param value time as long value (nanoseconds) + */ + public Uml2SDTestTimestamp(long value) { + super(value, IUml2SDTestConstants.TIME_SCALE); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/experiment/type/TmfEventsEditorStub.java b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/experiment/type/TmfEventsEditorStub.java deleted file mode 100644 index 10f9d13f86..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/experiment/type/TmfEventsEditorStub.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.experiment.type; - -import org.eclipse.linuxtools.tmf.ui.editors.TmfEventsEditor; -import org.eclipse.linuxtools.tmf.ui.viewers.events.TmfEventsTable; -import org.eclipse.swt.widgets.Composite; - -/** - * Event editor stub for experiment type unit tests - * - * @author Geneviève Bastien - */ -public class TmfEventsEditorStub extends TmfEventsEditor { - - private Composite fParent; - - @Override - public void createPartControl(final Composite parent) { - super.createPartControl(parent); - fParent = parent; - } - - /** - * Get a new event table, because the one from the parent events editor is - * not available. - * - * This function is meant to be used for unit tests only - * - * @return A new event table - */ - public TmfEventsTable getNewEventsTable() { - TmfEventsTable table = createEventsTable(fParent, getTrace().getCacheSize()); - return table; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/stubs/analysis/TestAnalysisUi.java b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/stubs/analysis/TestAnalysisUi.java deleted file mode 100644 index ec99f24c07..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/stubs/analysis/TestAnalysisUi.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.stubs.analysis; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAbstractAnalysisModule; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * Stub for an analysis module with outputs - */ -public class TestAnalysisUi extends TmfAbstractAnalysisModule { - - /** ID of the view opened by this analysis module */ - public static final String VIEW_ID = "org.eclipse.linuxtools.tmf.ui.tests.testAnalysisView"; - - private String fTraceName; - - /** - * Constructor - */ - public TestAnalysisUi() { - super(); - } - - @Override - protected boolean executeAnalysis(final IProgressMonitor monitor) { - return false; - } - - @Override - protected void canceling() { - - } - - @Override - public ITmfTrace getTrace() { - return super.getTrace(); - } - - /** - * Returns the name of the trace that should be set - * - * @return Name of the trace - */ - public String getTraceName() { - return fTraceName; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/uml2sd/load/TestLoaders.java b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/uml2sd/load/TestLoaders.java deleted file mode 100644 index 0dcba3472a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/uml2sd/load/TestLoaders.java +++ /dev/null @@ -1,483 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.tests.uml2sd.load; - -import java.net.URL; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.AsyncMessageReturn; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.BasicExecutionOccurrence; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.EllipsisMessage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.ExecutionOccurrence; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Frame; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.HotSpot; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.LifelineCategories; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Stop; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SyncMessage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SyncMessageReturn; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.Criteria; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.FilterCriteria; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IImage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDFilterProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDFindProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDPagingProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.load.IUml2SDLoader; -import org.eclipse.swt.graphics.Image; -import org.eclipse.ui.ISelectionListener; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.PlatformUI; - -/** - * Test loader class. - */ -@SuppressWarnings("javadoc") -public class TestLoaders implements IUml2SDLoader, ISDFindProvider, ISDFilterProvider, ISDPagingProvider, ISelectionListener { - - public SDView v; - public int page; - private List findResults = new ArrayList<>(); - private Criteria findCriteria; - private int currentFindIndex = 0; - - private Frame savedFrame = null; - - public TestLoaders() { - this(""); - } - - /** - * Constructor - * - * @param name - */ - public TestLoaders(String name) { - page = 1; - } - - @Override - public void setViewer(SDView j) { - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().addPostSelectionListener(this); - v = j; - v.setSDPagingProvider(this); - v.setSDFindProvider(this); - v.setSDFilterProvider(this); - page = 1; - createFrame(); - } - - @Override - public boolean hasNextPage() { - return page == 1; - } - - @Override - public boolean hasPrevPage() { - return page == 2; - } - - @Override - public void prevPage() { - page--; - createFrame(); - } - - @Override - public void nextPage() { - page++; - createFrame(); - } - - private void createFrame() { - Frame testFrame = new Frame(); - if (page == 1) { - testFrame.setName("Sequence Diagram - First Page"); - LifelineCategories tt[] = new LifelineCategories[2]; - tt[0] = new LifelineCategories(); - tt[1] = new LifelineCategories(); - tt[1].setName("Categorie 1"); - tt[1].setImage(new LocalImageImpl("obj16/node_obj.gif")); - tt[0].setImage(new LocalImageImpl("obj16/class.gif")); - tt[0].setName("Categorie 0"); - testFrame.setLifelineCategories(tt); - Lifeline lifeline = new Lifeline(); - lifeline.setName("LifeLine 0"); - testFrame.addLifeLine(lifeline); - EllipsisMessage mn = new EllipsisMessage(); - lifeline.getNewEventOccurrence(); - mn.setStartLifeline(lifeline); - mn.setName("******************* EllipsisisMessage TEST ****************"); - testFrame.addMessage(mn); - SyncMessage mn3 = new SyncMessage(); - mn3.setStartLifeline(lifeline); - testFrame.addMessage(mn3); - SyncMessage mn2 = new SyncMessage(); - lifeline.getNewEventOccurrence(); - lifeline.setCategory(0); - mn2.setEndLifeline(lifeline); - mn2.setName("*******************Sync TEST ****************"); - testFrame.addMessage(mn2); - for (int i = 1; i < 300; i++) { - lifeline = new Lifeline(); - lifeline.setName((new StringBuilder("LifeLine ")).append(i).toString()); - lifeline.setCategory(1); - testFrame.addLifeLine(lifeline); - SyncMessage m3 = new SyncMessage(); - testFrame.getLifeline(i - 1).getNewEventOccurrence(); - m3.setStartLifeline(testFrame.getLifeline(i - 1)); - m3.setEndLifeline(testFrame.getLifeline(i)); - m3.setName((new StringBuilder("Sync Message ")).append(i).toString()); - testFrame.addMessage(m3); -// if (i == 11) -// m3.setTime(new TmfTimestamp(i - 400)); -// else if (i == 6) -// m3.setTime(new TmfTimestamp(i)); -// else - m3.setTime(new TmfTimestamp(i + 1)); - } - - for (int i = testFrame.lifeLinesCount() - 1; i > 0; i--) { - SyncMessageReturn m = new SyncMessageReturn(); - testFrame.getLifeline(i).getNewEventOccurrence(); - m.setStartLifeline(testFrame.getLifeline(i)); - m.setEndLifeline(testFrame.getLifeline(i - 1)); - testFrame.addMessage(m); - m.setName((new StringBuilder("Sync Message return ")).append(i).toString()); - if (i + 1 < testFrame.lifeLinesCount()) { - SyncMessage h = testFrame.getSyncMessage(i + 1); - m.setMessage(h); - } - } - - for (int i = 0; i < testFrame.lifeLinesCount(); i++) { - if (i > 0) { - ExecutionOccurrence occ = new ExecutionOccurrence(); - occ.setStartOccurrence(testFrame.getSyncMessage(i).getEventOccurrence() + 1); - occ.setEndOccurrence(testFrame.getSyncMessageReturn(testFrame.syncMessageReturnCount() - i).getEventOccurrence()); - testFrame.getLifeline(i).addExecution(occ); - occ.setName("******************* Execution Occurance TEST ****************"); - } - } - - Stop s = new Stop(); - s.setLifeline(testFrame.getLifeline(1)); - s.setEventOccurrence(testFrame.getLifeline(1).getNewEventOccurrence()); - testFrame.getLifeline(1).addNode(s); - HotSpot gg = new HotSpot(); - gg.setImage(new LocalImageImpl("obj16/plus_obj.gif")); - gg.setExecution((BasicExecutionOccurrence) testFrame.getLifeline(1).getExecutions().get(0)); - AsyncMessageReturn m = new AsyncMessageReturn(); - m.setStartLifeline(testFrame.getLifeline(1)); - m.setEndLifeline(testFrame.getLifeline(3)); - m.setStartOccurrence(2); - m.setEndOccurrence(6); - m.setStartTime(new TmfTimestamp(2)); - m.setEndTime(new TmfTimestamp(6)); - m.setName("*******************Async TEST ****************"); - testFrame.addMessage(m); - v.setFrame(testFrame); - v.getSDWidget().setReorderMode(true); - } else { - -// if (page == 2) { - testFrame.setName("Sequence Diagram"); - Lifeline lifeline = new Lifeline(); - lifeline.setName("LifeLine 0"); - testFrame.addLifeLine(lifeline); - lifeline = new Lifeline(); - lifeline.setName("LifeLine 1"); - testFrame.addLifeLine(lifeline); - for (int i = 1; i < 30; i++) { - SyncMessage m3 = new SyncMessage(); - m3.autoSetStartLifeline(testFrame.getLifeline(0)); - m3.autoSetEndLifeline(testFrame.getLifeline(0)); - m3.setName((new StringBuilder("Message ")).append(i).toString()); - testFrame.addMessage(m3); - SyncMessageReturn m = new SyncMessageReturn(); - m.autoSetStartLifeline(testFrame.getLifeline(0)); - m.autoSetEndLifeline(testFrame.getLifeline(0)); - testFrame.addMessage(m); - m.setName((new StringBuilder("Message return ")).append(i).toString()); - ExecutionOccurrence occ = new ExecutionOccurrence(); - occ.setStartOccurrence(testFrame.getSyncMessage(i - 1).getEventOccurrence()); - occ.setEndOccurrence(testFrame.getSyncMessageReturn(i - 1).getEventOccurrence()); - testFrame.getLifeline(0).addExecution(occ); - } - } - v.setFrame(testFrame); - } - - @Override - public boolean find(Criteria toSearch) { - Frame frame = v.getFrame(); - - if (frame == null) { - return false; - } - if (findResults == null || findCriteria == null || !findCriteria.compareTo(toSearch)) { - findResults = new ArrayList<>(); - findCriteria = toSearch; - if (findCriteria.isLifeLineSelected()) { - for (int i = 0; i < frame.lifeLinesCount(); i++) { - if (findCriteria.matches(frame.getLifeline(i).getName())) { - findResults.add(frame.getLifeline(i)); - } - } - - } - ArrayList msgs = new ArrayList<>(); - if (findCriteria.isSyncMessageSelected()) { - for (int i = 0; i < frame.syncMessageCount(); i++) { - if (findCriteria.matches(frame.getSyncMessage(i).getName())) { - msgs.add(frame.getSyncMessage(i)); - } - } - - for (int i = 0; i < frame.syncMessageReturnCount(); i++) { - if (findCriteria.matches(frame.getSyncMessageReturn(i).getName())) { - msgs.add(frame.getSyncMessageReturn(i)); - } - } - - } - // if(msgs.size() > 0) { - // GraphNode temp[] = msgs.toArray(new GraphNode[0]); - // Arrays.sort(temp, new DateComparator()); - // findResults.addAll(Arrays.asList(temp)); - // } - - msgs = new ArrayList<>(); - if (findCriteria.isAsyncMessageSelected()) { - for (int i = 0; i < frame.asyncMessageCount(); i++) { - if (findCriteria.matches(frame.getAsyncMessage(i).getName())) { - msgs.add(frame.getAsyncMessage(i)); - } - } - - for (int i = 0; i < frame.asyncMessageReturnCount(); i++) { - if (findCriteria.matches(frame.getAsyncMessageReturn(i).getName())) { - msgs.add(frame.getAsyncMessageReturn(i)); - } - } - - } - // if(msgs.size() > 0) { - // GraphNode temp[] = msgs.toArray(new GraphNode[0]); - // Arrays.sort(temp, new DateComparator()); - // findResults.addAll(Arrays.asList(temp)); - // } - - List selection = v.getSDWidget().getSelection(); - if (selection != null && selection.size() == 1) { - currentFindIndex = findResults.indexOf(selection.get(0)) + 1; - } else { - currentFindIndex = 0; - } - } else { - currentFindIndex++; - } - if (findResults.size() > currentFindIndex) { - GraphNode current = findResults.get(currentFindIndex); - v.getSDWidget().moveTo(current); - return true; - } - // return notFoundYet(findCriteria); // search in other page - return false; - } - - @Override - public void cancel() { - findResults = null; - findCriteria = null; - currentFindIndex = 0; - } - - public boolean isLifelineSupported() { - return false; - } - - public boolean isSyncMessageSupported() { - return false; - } - - public boolean isSyncMessageReturnSupported() { - return false; - } - - public boolean isAsyncMessageSupported() { - return false; - } - - public boolean isAsyncMessageReturnSupported() { - return false; - } - - public boolean isStopSupported() { - return false; - } - - public Action getFindAction() { - return null; - } - - @Override - public boolean filter(List filters) { - - if (savedFrame != null) { - savedFrame = v.getFrame(); - } - - Frame frame = v.getFrame(); - - if (frame == null) { - return false; - } - - if (filters.size() != 1) { - return false; - } - - FilterCriteria filterCriteria = filters.get(0); - - // One way is to set visiblity of the item, but this only works for messages and not - // for lifelines! It's better to create a new frame without the filtered messages. - boolean found = false; - if (filterCriteria.getCriteria().isSyncMessageSelected()) { - for (int i = 0; i < frame.syncMessageCount(); i++) { - if (filterCriteria.getCriteria().matches(frame.getSyncMessage(i).getName())) { - frame.getSyncMessage(i).setVisible(false); - found = true; - } - } - - for (int i = 0; i < frame.syncMessageReturnCount(); i++) { - if (filterCriteria.getCriteria().matches(frame.getSyncMessageReturn(i).getName())) { - frame.getSyncMessageReturn(i).setVisible(false); - found = true; - } - } - } - - v.getSDWidget().redraw(); - return found; - } - - public ArrayList getCurrentFilters() { - return null; - } - - @Override - public String getTitleString() { - return "Test Loader"; - } - - @Override - public void dispose() { - } - - - @Override - public void selectionChanged(IWorkbenchPart part, ISelection selection) { - ISelection sel = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().getSelection(); - if (sel != null && (sel instanceof StructuredSelection)) { - StructuredSelection stSel = (StructuredSelection) sel; - if (stSel.getFirstElement() instanceof HotSpot) { - // OpenToolBox gg = new OpenToolBox(v); - // gg.run(); - } - } - } - - @Override - public boolean isNodeSupported(int nodeType) { - switch (nodeType) { - case ISDGraphNodeSupporter.LIFELINE: - case ISDGraphNodeSupporter.SYNCMESSAGE: - case ISDGraphNodeSupporter.SYNCMESSAGERETURN: - case ISDGraphNodeSupporter.ASYNCMESSAGE: - case ISDGraphNodeSupporter.ASYNCMESSAGERETURN: - case ISDGraphNodeSupporter.STOP: - return true; - - default: - break; - } - return false; - } - - @Override - public String getNodeName(int nodeType, String loaderClassName) { - return null; - } - - public static class LocalImageImpl implements IImage { - protected Image img; - - public LocalImageImpl(String file) { - img = null; - img = getResourceImage(file); - } - - public LocalImageImpl(Image img_) { - img = null; - img = img_; - } - - public Image getResourceImage(String _name) { - ImageDescriptor imgage; - try { - URL BASIC_URL = new URL("platform", "localhost", "plugin"); - URL url = new URL(BASIC_URL, (new StringBuilder("plugin/org.eclipse.linuxtools.tmf.ui/icons/")).append(_name).toString()); - imgage = ImageDescriptor.createFromURL(url); - return imgage.createImage(); - } catch (Exception e) { - System.err.println(e); - } - return null; - } - - @Override - public Object getImage() { - return img; - } - - @Override - public void dispose() { - if (img != null) { - img.dispose(); - } - } - - } - - @Override - public void firstPage() { - page = 0; - createFrame(); - - } - - @Override - public void lastPage() { - page = 2; - createFrame(); - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/uml2sd/trace/TmfUml2SDTestTrace.java b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/uml2sd/trace/TmfUml2SDTestTrace.java deleted file mode 100644 index c4499cb830..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/uml2sd/trace/TmfUml2SDTestTrace.java +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ui.tests.uml2sd.trace; - -import java.io.EOFException; -import java.io.IOException; -import java.io.RandomAccessFile; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEvent; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventType; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub; - -/** - * Parser implementation for Uml2SD Test Traces. - * - */ -public class TmfUml2SDTestTrace implements ITmfEventParser { - - ITmfTrace fEventStream; - - /** - * Default Constructor - */ - public TmfUml2SDTestTrace() { - } - - /** - * Constructor - * @param eventStream ITmfTrace implementation - */ - public TmfUml2SDTestTrace(ITmfTrace eventStream) { - fEventStream = eventStream; - } - - /** - * @param eventStream ITmfTrace implementation to set - */ - public void setTrace(ITmfTrace eventStream) { - fEventStream = eventStream; - } - - @Override - public ITmfEvent parseEvent(ITmfContext context) { - if (! (fEventStream instanceof TmfTraceStub)) { - return null; - } - - // Highly inefficient... - RandomAccessFile stream = ((TmfTraceStub) fEventStream).getStream(); - -// String name = eventStream.getName(); -// name = name.substring(name.lastIndexOf('/') + 1); - - long location = 0; - if (context != null) { - location = (Long) context.getLocation().getLocationInfo(); - } - - try { - stream.seek(location); - - long ts = stream.readLong(); - String source = stream.readUTF(); - String type = stream.readUTF(); - String reference = stream.readUTF(); - String sender = stream.readUTF(); - String receiver = stream.readUTF(); - String signal = stream.readUTF(); - - String[] labels = {"sender", "receiver", "signal"}; - - TmfEventType tmfEventType = new TmfEventType("UnitTest", type, TmfEventField.makeRoot(labels)); - - String content = "["; - content += sender; - content += "," + receiver; - content += "," + signal; - content += "]"; - - // Pre-parse the content - TmfEventField[] fields = new TmfEventField[3]; - fields[0] = new TmfEventField("sender", sender, null); - fields[1] = new TmfEventField("receiver", receiver, null); - fields[2] = new TmfEventField("signal", signal, null); - - ITmfEventField tmfContent = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, content, fields); - ITmfEvent tmfEvent = new TmfEvent(fEventStream, new TmfTimestamp(ts, -9), source, tmfEventType, tmfContent, reference); - - return tmfEvent; - } catch (final EOFException e) { - } catch (final IOException e) { - } - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/adaption/TsfImplProvider.java b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/adaption/TsfImplProvider.java deleted file mode 100644 index 9e4170049d..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/adaption/TsfImplProvider.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.test.stub.adaption; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.test.stub.model.EventImpl; - -/** - * Time Graph Presentation Provider Stub. - */ -public class TsfImplProvider extends TimeGraphPresentationProvider { - - // ======================================================================== - // Methods - // ======================================================================== - @Override - public int getStateTableIndex(ITimeEvent event) { - return 0; - } - - @Override - public Map getEventHoverToolTipInfo(ITimeEvent revent) { - Map toolTipEventMsgs = new HashMap<>(); - if (revent instanceof EventImpl) { - toolTipEventMsgs.put("Test Tip1", "Test Value tip1"); - toolTipEventMsgs.put("Test Tip2", "Test Value tip2"); - } - - return toolTipEventMsgs; - } - - @Override - public String getEventName(ITimeEvent event) { - String name = "Unknown"; - if (event instanceof EventImpl) { - EventImpl devent = (EventImpl) event; - name = devent.getType().toString(); - } - return name; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/model/EventImpl.java b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/model/EventImpl.java deleted file mode 100644 index c8ed3d411d..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/model/EventImpl.java +++ /dev/null @@ -1,85 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.test.stub.model; - -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; - -/** - * ITimeEvent implementation for test purposes. - */ -@SuppressWarnings("javadoc") -public class EventImpl implements ITimeEvent { - // ======================================================================== - // Data - // ======================================================================== - public static enum Type {ERROR, WARNING, TIMEADJUSTMENT, ALARM, EVENT, INFORMATION, UNKNOWN, INFO1, INFO2, INFO3, INFO4, INFO5, INFO6, INFO7, INFO8, INFO9} - - private long time = 0; - private ITimeGraphEntry trace = null; - private Type myType = Type.UNKNOWN; - private long duration; - - // ======================================================================== - // Constructor - // ======================================================================== - public EventImpl(long time, ITimeGraphEntry trace, Type type) { - this.time = time; - this.trace = trace; - this.myType = type; - } - - // ======================================================================== - // Methods - // ======================================================================== - public Type getType() { - return myType; - } - - public void setType(Type myType) { - this.myType = myType; - } - - public void setTime(long time) { - this.time = time; - } - - public void setTrace(ITimeGraphEntry trace) { - this.trace = trace; - } - - @Override - public long getTime() { - return time; - } - - @Override - public ITimeGraphEntry getEntry() { - return trace; - } - - /** - * @param duration the duration to set - */ - public void setDuration(long duration) { - this.duration = duration; - } - - /** - * @return the duration - */ - @Override - public long getDuration() { - return duration; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/model/TraceImpl.java b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/model/TraceImpl.java deleted file mode 100644 index 62f6f3680c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/model/TraceImpl.java +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.test.stub.model; - -import java.util.Iterator; -import java.util.List; -import java.util.Vector; - -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; - -@SuppressWarnings("javadoc") -public class TraceImpl implements ITimeGraphEntry { - - // ======================================================================== - // Data - // ======================================================================== - - private String name = "traceDefaultName"; - private long startTime = 0; - private long stopTime = 1; - private String className = "defaultClassName"; - private Vector traceEvents = new Vector<>(); - - // ======================================================================== - // Constructor - // ======================================================================== - - public TraceImpl(String name, long sTime, long stopTime, String className) { - this.name = name; - this.startTime = sTime; - this.stopTime = stopTime; - this.className = className; - } - - // ======================================================================== - // Methods - // ======================================================================== - - public String getClassName() { - return className; - } - - public void setClassName(String className) { - this.className = className; - } - - public void setName(String name) { - this.name = name; - } - - public void setStartTime(long startTime) { - this.startTime = startTime; - } - - public void setStopTime(long stopTime) { - this.stopTime = stopTime; - } - - @Override - public String getName() { - return name; - } - - @Override - public long getStartTime() { - return startTime; - } - - @Override - public long getEndTime() { - return stopTime; - } - - @Override - public boolean hasTimeEvents() { - return traceEvents != null; - } - - @Override - public Iterator getTimeEventsIterator() { - return traceEvents.iterator(); - } - - @Override - public Iterator getTimeEventsIterator(long aStartTime, long aStopTime, long maxDuration) { - return traceEvents.iterator(); - } - - public void addTraceEvent(ITimeEvent event) { - traceEvents.add(event); - } - - @Override - public List getChildren() { - return null; - } - - @Override - public ITimeGraphEntry getParent() { - return null; - } - - @Override - public boolean hasChildren() { - return false; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/model/TraceModelImplFactory.java b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/model/TraceModelImplFactory.java deleted file mode 100644 index bd875921b0..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/model/TraceModelImplFactory.java +++ /dev/null @@ -1,232 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.test.stub.model; - -import java.util.Date; - -@SuppressWarnings("javadoc") -public class TraceModelImplFactory { - - // ======================================================================== - // Data - // ======================================================================== - private int count = 0; - private final TraceStrings[] traceNames; - private static final long msTons = 1000000; - private final Long timeRef = new Date().getTime() * msTons; - - // ======================================================================== - // Constructor - // ======================================================================== - public TraceModelImplFactory() { - traceNames = new TraceStrings[17]; - loadTraceNameStrings(); - } - - // ======================================================================== - // Methods - // ======================================================================== - public TraceImpl[] createTraces() { - TraceImpl trace; - TraceImpl[] traceArr = new TraceImpl[17]; - for (int i = 0; i < traceArr.length; i++) { - trace = new TraceImpl(traceNames[i].name, timeRef, timeRef + 40, - traceNames[i].classNmme); - count = i; - createEvents(trace); - traceArr[i] = trace; - } - return traceArr; - } - - /** - * 5000 Events per Trace. - * @param number - * @return - */ - public TraceImpl[] createLargeTraces(int number) { - TraceImpl trace; - TraceImpl[] traceArr = new TraceImpl[number]; - for (int i = 0; i < traceArr.length; i++) { - int counter = i%17; - long sTime = i * (long) 1E6; - trace = new TraceImpl(traceNames[counter].name, sTime , sTime + 20000, - traceNames[counter].classNmme); - create5000Events(trace); - traceArr[i] = trace; - } - return traceArr; - } - - private static void create5000Events(TraceImpl trace) { - EventImpl event; - Long eventTime; - int numEvents = 5000; - long sTime = trace.getStartTime(); - long eTime = trace.getEndTime(); - long duration = (eTime - sTime)/numEvents; - for (int i = 0; i < numEvents; i++) { - eventTime = sTime + (i * duration); - // eventTime = timeRef + (5 * (count % 4) + (5 * (int) (i/2) )); - // System.out.println("Trace: " + trace.getName() + " EventTime: " - // + eventTime); -// duration = i * msTons + (long) ((i % 4)); - - event = new EventImpl(eventTime, trace, getEventType(i%16)); - event.setDuration(duration); - trace.addTraceEvent(event); - } - } - - private void createEvents(TraceImpl trace) { - EventImpl event; - Long eventTime; - int numEvents = 17; - long duration = 0; - for (int i = 0; i < numEvents; i++) { - eventTime = timeRef + msTons * i + (5 * msTons * count) + (5 * i); - duration = msTons + i * msTons + ((i % 4)); -// duration = i + (long) ((i % 4)); - event = new EventImpl(eventTime, trace, getEventType(i)); - event.setDuration(duration); - trace.addTraceEvent(event); - } - } - - private static EventImpl.Type getEventType(int val) { - if (EventImpl.Type.ALARM.ordinal() == val) { - return EventImpl.Type.ALARM; - } - if (EventImpl.Type.ERROR.ordinal() == val) { - return EventImpl.Type.ERROR; - } - if (EventImpl.Type.EVENT.ordinal() == val) { - return EventImpl.Type.EVENT; - } - if (EventImpl.Type.INFORMATION.ordinal() == val) { - return EventImpl.Type.INFORMATION; - } - if (EventImpl.Type.TIMEADJUSTMENT.ordinal() == val) { - return EventImpl.Type.TIMEADJUSTMENT; - } - if (EventImpl.Type.WARNING.ordinal() == val) { - return EventImpl.Type.WARNING; - } - if (EventImpl.Type.INFO1.ordinal() == val) { - return EventImpl.Type.INFO1; - } - if (EventImpl.Type.INFO2.ordinal() == val) { - return EventImpl.Type.INFO2; - } - if (EventImpl.Type.INFO3.ordinal() == val) { - return EventImpl.Type.INFO3; - } - if (EventImpl.Type.INFO4.ordinal() == val) { - return EventImpl.Type.INFO4; - } - if (EventImpl.Type.INFO5.ordinal() == val) { - return EventImpl.Type.INFO5; - } - if (EventImpl.Type.INFO6.ordinal() == val) { - return EventImpl.Type.INFO6; - } - if (EventImpl.Type.INFO7.ordinal() == val) { - return EventImpl.Type.INFO7; - } - if (EventImpl.Type.INFO8.ordinal() == val) { - return EventImpl.Type.INFO8; - } - if (EventImpl.Type.INFO9.ordinal() == val) { - return EventImpl.Type.INFO9; - } - return EventImpl.Type.UNKNOWN; - } - - private void loadTraceNameStrings() { - traceNames[0] = new TraceStrings(); - traceNames[0].name = "TE Log - TATA BSC11"; - traceNames[0].classNmme = "All Boards"; - - traceNames[1] = new TraceStrings(); - traceNames[1].name = "System Log"; - traceNames[1].classNmme = "BSC11"; - - traceNames[2] = new TraceStrings(); - traceNames[2].name = "Alarm Log"; - traceNames[2].classNmme = "BSC11"; - - traceNames[3] = new TraceStrings(); - traceNames[3].name = "Events Log"; - traceNames[3].classNmme = "BSC 11"; - - traceNames[4] = new TraceStrings(); - traceNames[4].name = "CPU Load"; - traceNames[4].classNmme = "All Boards"; - - traceNames[5] = new TraceStrings(); - traceNames[5].name = "Performance Log"; - traceNames[5].classNmme = "BSC11"; - - traceNames[6] = new TraceStrings(); - traceNames[6].name = "TE Log - TATA BSC14"; - traceNames[6].classNmme = "Board 24"; - - traceNames[7] = new TraceStrings(); - traceNames[7].name = "TE Log - TATA BSC14"; - traceNames[7].classNmme = "Board 23"; - - traceNames[8] = new TraceStrings(); - traceNames[8].name = "TE Log - TATA BSC14"; - traceNames[8].classNmme = "Board 11"; - - traceNames[9] = new TraceStrings(); - traceNames[9].name = "TE Log - TATA BSC14"; - traceNames[9].classNmme = "Board 14, SPO"; - - traceNames[10] = new TraceStrings(); - traceNames[10].name = "INFO 1"; - traceNames[10].classNmme = "All Boards"; - - traceNames[11] = new TraceStrings(); - traceNames[11].name = "INFO2"; - traceNames[11].classNmme = "BSC11"; - - traceNames[12] = new TraceStrings(); - traceNames[12].name = "INFO3"; - traceNames[12].classNmme = "Board 24"; - - traceNames[13] = new TraceStrings(); - traceNames[13].name = "MISC1"; - traceNames[13].classNmme = "Board 23"; - - traceNames[14] = new TraceStrings(); - traceNames[14].name = "MISC2"; - traceNames[14].classNmme = "Board 11"; - - traceNames[15] = new TraceStrings(); - traceNames[15].name = "MISC3"; - traceNames[15].classNmme = "Board 23"; - - traceNames[16] = new TraceStrings(); - traceNames[16].name = "MISC4"; - traceNames[16].classNmme = "Board 11"; - - } - - // ======================================================================== - // Inner Class - // ======================================================================== - private static class TraceStrings { - public String name = ""; - public String classNmme = name + " class"; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/views/TsfTraceAnalysisView.java b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/views/TsfTraceAnalysisView.java deleted file mode 100644 index 09d122b8f8..0000000000 --- a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/test/stub/views/TsfTraceAnalysisView.java +++ /dev/null @@ -1,672 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation - * Patrick Tasse - Support selection range - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.test.stub.views; - -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; - -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.DoubleClickEvent; -import org.eclipse.jface.viewers.IDoubleClickListener; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerSorter; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphRangeListener; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphSelectionListener; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphTimeListener; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphSelectionEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphViewer; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.test.stub.adaption.TsfImplProvider; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.test.stub.model.EventImpl; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.test.stub.model.TraceImpl; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.test.stub.model.TraceModelImplFactory; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.SashForm; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.ui.IActionBars; -import org.eclipse.ui.ISharedImages; -import org.eclipse.ui.IWorkbenchActionConstants; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.part.DrillDownAdapter; -import org.eclipse.ui.part.ViewPart; - -@SuppressWarnings("javadoc") -public class TsfTraceAnalysisView extends ViewPart implements - ITimeGraphSelectionListener, ITimeGraphTimeListener, ITimeGraphRangeListener { - - // ======================================================================== - // Data - // ======================================================================== - - private TreeViewer viewer; - private DrillDownAdapter drillDownAdapter; - private Action action1; - private Action action2; - private Action resetScale; - private Action nextEvent; - private Action prevEvent; - private Action nextTrace; - private Action prevTrace; - private Action showLegent; - private Action zoomIn; - private Action zoomOut; - private Action events300K; - - private Action doubleClickAction; - private TimeGraphViewer tsfviewer; - private TimeGraphViewer tsfviewer2; - - private static SimpleDateFormat stimeformat = new SimpleDateFormat( - "yy/MM/dd HH:mm:ss"); - private TraceModelImplFactory fact; - - // ======================================================================== - // Inner Classes - // ======================================================================== - /* - * The content provider class is responsible for providing objects to the - * view. It can wrap existing objects in adapters or simply return objects - * as-is. These objects may be sensitive to the current input of the view, - * or ignore it and always show the same content (like Task List, for - * example). - */ - - class TreeObject implements IAdaptable { - private final String name; - private TreeParent parent; - - public TreeObject(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public void setParent(TreeParent parent) { - this.parent = parent; - } - - public TreeParent getParent() { - return parent; - } - - @Override - public String toString() { - return getName(); - } - - @Override - public Object getAdapter(Class key) { - return null; - } - } - - class TreeParent extends TreeObject { - private final ArrayList children; - - public TreeParent(String name) { - super(name); - children = new ArrayList<>(); - } - - public void addChild(TreeObject child) { - children.add(child); - child.setParent(this); - } - - public void removeChild(TreeObject child) { - children.remove(child); - child.setParent(null); - } - - public TreeObject[] getChildren() { - return children.toArray(new TreeObject[children - .size()]); - } - - public boolean hasChildren() { - return children.size() > 0; - } - } - - class ViewContentProvider implements ITreeContentProvider { - private TreeParent invisibleRoot; - - @Override - public void inputChanged(Viewer v, Object oldInput, Object newInput) { - } - - @Override - public void dispose() { - } - - @Override - public Object[] getElements(Object parent) { - if (parent.equals(getViewSite())) { - if (invisibleRoot == null) { - initialize(); - } - return getChildren(invisibleRoot); - } - return getChildren(parent); - } - - @Override - public Object getParent(Object child) { - if (child instanceof TreeObject) { - return ((TreeObject) child).getParent(); - } - return null; - } - - @Override - public Object[] getChildren(Object parent) { - if (parent instanceof TreeParent) { - return ((TreeParent) parent).getChildren(); - } - return new Object[0]; - } - - @Override - public boolean hasChildren(Object parent) { - if (parent instanceof TreeParent) { - return ((TreeParent) parent).hasChildren(); - } - return false; - } - - /* - * We will set up a dummy model to initialize tree heararchy. In a real - * code, you will connect to a real model and expose its hierarchy. - */ - private void initialize() { - TreeObject to1 = new TreeObject("Leaf 1"); - TreeObject to2 = new TreeObject("Leaf 2"); - TreeObject to3 = new TreeObject("Leaf 3"); - TreeParent p1 = new TreeParent("Parent 1"); - p1.addChild(to1); - p1.addChild(to2); - p1.addChild(to3); - - TreeObject to4 = new TreeObject("Leaf 4"); - TreeParent p2 = new TreeParent("Parent 2"); - p2.addChild(to4); - - TreeParent root = new TreeParent("Root"); - root.addChild(p1); - root.addChild(p2); - - invisibleRoot = new TreeParent(""); - invisibleRoot.addChild(root); - } - } - - static class ViewLabelProvider extends LabelProvider { - - @Override - public String getText(Object obj) { - return obj.toString(); - } - - @Override - public Image getImage(Object obj) { - String imageKey = ISharedImages.IMG_OBJ_ELEMENT; - if (obj instanceof TreeParent) { - imageKey = ISharedImages.IMG_OBJ_FOLDER; - } - return PlatformUI.getWorkbench().getSharedImages().getImage( - imageKey); - } - } - - static class NameSorter extends ViewerSorter { - } - - // ======================================================================== - // Methods - // ======================================================================== - /** - * This is a callback that will allow us to create the viewer and initialize - * it. - */ - @Override - public void createPartControl(Composite parent) { - final SashForm sashForm = new SashForm(parent, SWT.NONE); - final SashForm sashForm2 = new SashForm(sashForm, SWT.NONE); - - tsfviewer = new TimeGraphViewer(sashForm2, SWT.NONE); - tsfviewer.setTimeGraphProvider(new TsfImplProvider()); - tsfviewer2 = new TimeGraphViewer(sashForm2, SWT.NONE); - tsfviewer2.setTimeGraphProvider(new TsfImplProvider()); - - viewer = new TreeViewer(sashForm, SWT.MULTI | SWT.H_SCROLL - | SWT.V_SCROLL); - drillDownAdapter = new DrillDownAdapter(viewer); - viewer.setContentProvider(new ViewContentProvider()); - viewer.setLabelProvider(new ViewLabelProvider()); - viewer.setSorter(new NameSorter()); - viewer.setInput(getViewSite()); - - sashForm.setWeights(new int[] { 5, 1 }); - sashForm2.setWeights(new int[] { 1, 1 }); - - fact = new TraceModelImplFactory(); - ITimeGraphEntry[] traceArr = fact.createTraces(); - tsfviewer.setInput(traceArr); - tsfviewer.addSelectionListener(this); - tsfviewer.addRangeListener(this); - tsfviewer.setTimeFormat(TimeFormat.CALENDAR); - - tsfviewer2.setInput(traceArr); - tsfviewer2.addSelectionListener(this); - tsfviewer2.addRangeListener(this); - // tsfviewer2.setTimeFormat(TimeGraphViewer.timeFormat.epoch); - - makeActions(); - hookContextMenu(); - hookDoubleClickAction(); - contributeToActionBars(); - } - - private void hookContextMenu() { - MenuManager menuMgr = new MenuManager("#PopupMenu"); - menuMgr.setRemoveAllWhenShown(true); - menuMgr.addMenuListener(new IMenuListener() { - @Override - public void menuAboutToShow(IMenuManager manager) { - TsfTraceAnalysisView.this.fillContextMenu(manager); - } - }); - Menu menu = menuMgr.createContextMenu(viewer.getControl()); - viewer.getControl().setMenu(menu); - getSite().registerContextMenu(menuMgr, viewer); - } - - private void contributeToActionBars() { - IActionBars bars = getViewSite().getActionBars(); - fillLocalPullDown(bars.getMenuManager()); - fillLocalToolBar(bars.getToolBarManager()); - } - - private void fillLocalPullDown(IMenuManager manager) { - manager.add(action1); - manager.add(new Separator()); - manager.add(action2); - } - - private void fillContextMenu(IMenuManager manager) { - manager.add(action1); - manager.add(action2); - manager.add(new Separator()); - drillDownAdapter.addNavigationActions(manager); - // Other plug-ins can contribute there actions here - manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); - } - - private void fillLocalToolBar(IToolBarManager manager) { - manager.add(new Separator()); - manager.add(resetScale); - manager.add(nextEvent); - manager.add(prevEvent); - manager.add(nextTrace); - manager.add(prevTrace); - manager.add(showLegent); - manager.add(zoomIn); - manager.add(zoomOut); - manager.add(events300K); - manager.add(new Separator()); - - drillDownAdapter.addNavigationActions(manager); - } - - private TimeGraphViewer getActiveTsfCtrl() { - TimeGraphViewer inFocusViewer = null; - if (tsfviewer.isInFocus()) { - inFocusViewer = tsfviewer; - } else if (tsfviewer2.isInFocus()) { - inFocusViewer = tsfviewer2; - } - return inFocusViewer; - } - - private void makeActions() { - // action1 - action1 = new Action() { - @Override - public void run() { - showMessage("Action 1 executed"); - } - }; - action1.setText("Action 1"); - action1.setToolTipText("Action 1 tooltip"); - action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages() - .getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK)); - - // action2 - action2 = new Action() { - @Override - public void run() { - showMessage("Action 2 executed"); - } - }; - action2.setText("Action 2"); - action2.setToolTipText("Action 2 tooltip"); - action2.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages() - .getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK)); - - // action4 - resetScale = new Action() { - @Override - public void run() { - TimeGraphViewer inFocusViewer = getActiveTsfCtrl(); - if (inFocusViewer != null) { - inFocusViewer.resetStartFinishTime(); - } - - } - }; - resetScale.setText("Reset"); - resetScale.setToolTipText("Reset the Time Scale to Default"); - - // action5 - nextEvent = new Action() { - @Override - public void run() { - TimeGraphViewer inFocusViewer = getActiveTsfCtrl(); - if (inFocusViewer != null) { - inFocusViewer.selectNextEvent(); - } - } - }; - nextEvent.setText("NextEv"); - nextEvent.setToolTipText("Next Event"); - - // action6 - prevEvent = new Action() { - @Override - public void run() { - TimeGraphViewer inFocusViewer = getActiveTsfCtrl(); - if (inFocusViewer != null) { - inFocusViewer.selectPrevEvent(); - } - } - }; - prevEvent.setText("PrevEv"); - prevEvent.setToolTipText("Previous Event"); - - // action7 - nextTrace = new Action() { - @Override - public void run() { - TimeGraphViewer inFocusViewer = getActiveTsfCtrl(); - if (inFocusViewer != null) { - inFocusViewer.selectNextItem(); - } - } - }; - nextTrace.setText("NextTrace"); - nextTrace.setToolTipText("Select Next Event"); - - // action8 - prevTrace = new Action() { - @Override - public void run() { - TimeGraphViewer inFocusViewer = getActiveTsfCtrl(); - if (inFocusViewer != null) { - inFocusViewer.selectPrevItem(); - } - } - }; - prevTrace.setText("PrevTrace"); - prevTrace.setToolTipText("Select Previous Trace"); - - // action9 - showLegent = new Action() { - @Override - public void run() { - TimeGraphViewer inFocusViewer = getActiveTsfCtrl(); - if (inFocusViewer != null) { - inFocusViewer.showLegend(); - } - } - }; - showLegent.setText("Legend"); - showLegent.setToolTipText("Show Legend"); - - // action10 - zoomIn = new Action() { - @Override - public void run() { - TimeGraphViewer inFocusViewer = getActiveTsfCtrl(); - if (inFocusViewer != null) { - inFocusViewer.zoomIn(); - } - } - }; - zoomIn.setText("Zoom In"); - zoomIn.setToolTipText("Zoom In"); - - // action10 - zoomOut = new Action() { - @Override - public void run() { - TimeGraphViewer inFocusViewer = getActiveTsfCtrl(); - if (inFocusViewer != null) { - inFocusViewer.zoomOut(); - } - // ISelection selection = inFocusViewer.getSelection(); - // Object sel = null; - // if (selection != null && !selection.isEmpty()) { - // sel = ((IStructuredSelection) selection) - // .getFirstElement(); - // if (sel instanceof EventImpl) { - // EventImpl event = (EventImpl) sel; - // inFocusViewer.selectNextEvent(); - // } - // } - } - }; - zoomOut.setText("Zoom Out"); - zoomOut.setToolTipText("Zoom Out"); - - // action12 - events300K = new Action() { - @Override - public void run() { - TimeGraphViewer inFocusViewer = getActiveTsfCtrl(); - if (inFocusViewer != null) { - ITimeGraphEntry[] traceArr = fact - .createLargeTraces(60); - inFocusViewer.setInput(traceArr); - } - } - }; - events300K.setText("300K Events"); - events300K.setToolTipText("Add 300K Events"); - - doubleClickAction = new Action() { - @Override - public void run() { - ISelection selection = viewer.getSelection(); - Object obj = ((IStructuredSelection) selection) - .getFirstElement(); - showMessage("Double-click detected on " + obj.toString()); - } - }; - } - - private void hookDoubleClickAction() { - viewer.addDoubleClickListener(new IDoubleClickListener() { - @Override - public void doubleClick(DoubleClickEvent event) { - doubleClickAction.run(); - } - }); - } - - private void showMessage(String message) { - MessageDialog.openInformation(viewer.getControl().getShell(), - "TsfTrace Analysis View", message); - } - - /** - * Passing the focus request to the viewer's control. - */ - @Override - public void setFocus() { - viewer.getControl().setFocus(); - } - - @Override - public void selectionChanged(TimeGraphSelectionEvent event) { - Object source = event.getSource(); - if (source == null || !(source instanceof TimeGraphViewer)) { - return; - } - - TimeGraphViewer rViewer = (TimeGraphViewer) event.getSource(); - TimeGraphViewer synchViewer = null; - // Synchronize viewer selections if Enabled, - // make sure the selection does not go in loops - if (tsfviewer == rViewer) { - synchViewer = tsfviewer2; - } else { - synchViewer = tsfviewer; - } - Object selection = event.getSelection(); - - if (selection instanceof EventImpl) { - EventImpl selEvent = (EventImpl) selection; - System.out - .println("TsfTraceAnalysisView.selectionChanged() Selected Event: \nType: " - + selEvent.getType().toString() - + "\nTime: " - + selEvent.getTime() - + "\nTrace Name: " - + selEvent.getEntry().getName()); - - synchViewer.setSelectedEvent(selEvent, source); - - } else if (selection instanceof TraceImpl) { - TraceImpl selTrace = (TraceImpl) selection; - System.out - .println("TsfTraceAnalysisView.selectionChanged() Selected Trace: \nName: " - + selTrace.getName().toString() - + "\nClass Name: " - + selTrace.getClassName()); - - synchViewer.setSelection(selTrace); - } else { - System.out - .println("TsfTmIncubatorListener.tsfTmProcessEvent() Unexpected event source received: " - + selection.getClass().getName()); - } - - } - - @Override - public void timeSelected(TimeGraphTimeEvent event) { - TimeGraphViewer rViewer = (TimeGraphViewer) event.getSource(); - TimeGraphViewer synchViewer = null; - // Synchronize viewer selections if Enabled, - // make sure the selection does not go in loops - if (tsfviewer == rViewer) { - synchViewer = tsfviewer2; - } else { - synchViewer = tsfviewer; - } - long selTimens = event.getBeginTime(); - long tms = (long) (selTimens * 1E-6); - Date date = new Date(tms); - String fDate = stimeformat.format(date); - String ns = formatNs(selTimens); - - System.out.println("TsfTraceAnalysisView.timeSelected() Selected Event: \nTime: " - + event.getBeginTime() - + "\nSelected Time: " - + selTimens + " " + fDate + " " + ns); - - synchViewer.setSelectedTime(event.getBeginTime(), true); - } - - @Override - public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) { - if (event == null) { - return; - } - Object source = event.getSource(); - if (source == null || !(source instanceof TimeGraphViewer)) { - return; - } - - TimeGraphRangeUpdateEvent rEvent = event; - TimeGraphViewer rViewer = (TimeGraphViewer) event - .getSource(); - TimeGraphViewer synchViewer = null; - // Synchronize viewer selections if Enabled, - // make sure the selection does not go in loops - if (tsfviewer == rViewer) { - synchViewer = tsfviewer2; - } else { - synchViewer = tsfviewer; - } - - synchViewer.setSelectVisTimeWindow(rEvent.getStartTime(), rEvent.getEndTime(), source); - } - - /** - * Obtains the remainder fraction on unit Seconds of the entered value in - * nanoseconds. e.g. input: 1241207054171080214 ns The number of seconds can - * be obtain by removing the last 9 digits: 1241207054 the fractional - * portion of seconds, expressed in ns is: 171080214 - * - * @param v - * @return - */ - public String formatNs(long v) { - StringBuffer str = new StringBuffer(); - long val = v; - boolean neg = val < 0; - if (neg) { - val = -val; - str.append('-'); - } - - String strVal = String.valueOf(val); - if (val < 1000000000) { - return strVal; - } - - // Extract the last nine digits (e.g. fraction of a S expressed in ns - return strVal.substring(strVal.length() - 9); - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/tests/experiment/type/TmfEventsEditorStub.java b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/tests/experiment/type/TmfEventsEditorStub.java new file mode 100644 index 0000000000..e3cb3172f2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/tests/experiment/type/TmfEventsEditorStub.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.experiment.type; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor; +import org.eclipse.tracecompass.tmf.ui.viewers.events.TmfEventsTable; + +/** + * Event editor stub for experiment type unit tests + * + * @author Geneviève Bastien + */ +public class TmfEventsEditorStub extends TmfEventsEditor { + + private Composite fParent; + + @Override + public void createPartControl(final Composite parent) { + super.createPartControl(parent); + fParent = parent; + } + + /** + * Get a new event table, because the one from the parent events editor is + * not available. + * + * This function is meant to be used for unit tests only + * + * @return A new event table + */ + public TmfEventsTable getNewEventsTable() { + TmfEventsTable table = createEventsTable(fParent, getTrace().getCacheSize()); + return table; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/tests/stubs/analysis/TestAnalysisUi.java b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/tests/stubs/analysis/TestAnalysisUi.java new file mode 100644 index 0000000000..2b85a05e16 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/tests/stubs/analysis/TestAnalysisUi.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.stubs.analysis; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * Stub for an analysis module with outputs + */ +public class TestAnalysisUi extends TmfAbstractAnalysisModule { + + /** ID of the view opened by this analysis module */ + public static final String VIEW_ID = "org.eclipse.linuxtools.tmf.ui.tests.testAnalysisView"; + + private String fTraceName; + + /** + * Constructor + */ + public TestAnalysisUi() { + super(); + } + + @Override + protected boolean executeAnalysis(final IProgressMonitor monitor) { + return false; + } + + @Override + protected void canceling() { + + } + + @Override + public ITmfTrace getTrace() { + return super.getTrace(); + } + + /** + * Returns the name of the trace that should be set + * + * @return Name of the trace + */ + public String getTraceName() { + return fTraceName; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/tests/uml2sd/load/TestLoaders.java b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/tests/uml2sd/load/TestLoaders.java new file mode 100644 index 0000000000..487a1d1599 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/tests/uml2sd/load/TestLoaders.java @@ -0,0 +1,483 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.uml2sd.load; + +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.graphics.Image; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.AsyncMessageReturn; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.BasicExecutionOccurrence; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.EllipsisMessage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.ExecutionOccurrence; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Frame; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.HotSpot; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Lifeline; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.LifelineCategories; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Stop; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SyncMessage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SyncMessageReturn; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.Criteria; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.FilterCriteria; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IImage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDFilterProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDFindProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDPagingProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.load.IUml2SDLoader; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PlatformUI; + +/** + * Test loader class. + */ +@SuppressWarnings("javadoc") +public class TestLoaders implements IUml2SDLoader, ISDFindProvider, ISDFilterProvider, ISDPagingProvider, ISelectionListener { + + public SDView v; + public int page; + private List findResults = new ArrayList<>(); + private Criteria findCriteria; + private int currentFindIndex = 0; + + private Frame savedFrame = null; + + public TestLoaders() { + this(""); + } + + /** + * Constructor + * + * @param name + */ + public TestLoaders(String name) { + page = 1; + } + + @Override + public void setViewer(SDView j) { + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().addPostSelectionListener(this); + v = j; + v.setSDPagingProvider(this); + v.setSDFindProvider(this); + v.setSDFilterProvider(this); + page = 1; + createFrame(); + } + + @Override + public boolean hasNextPage() { + return page == 1; + } + + @Override + public boolean hasPrevPage() { + return page == 2; + } + + @Override + public void prevPage() { + page--; + createFrame(); + } + + @Override + public void nextPage() { + page++; + createFrame(); + } + + private void createFrame() { + Frame testFrame = new Frame(); + if (page == 1) { + testFrame.setName("Sequence Diagram - First Page"); + LifelineCategories tt[] = new LifelineCategories[2]; + tt[0] = new LifelineCategories(); + tt[1] = new LifelineCategories(); + tt[1].setName("Categorie 1"); + tt[1].setImage(new LocalImageImpl("obj16/node_obj.gif")); + tt[0].setImage(new LocalImageImpl("obj16/class.gif")); + tt[0].setName("Categorie 0"); + testFrame.setLifelineCategories(tt); + Lifeline lifeline = new Lifeline(); + lifeline.setName("LifeLine 0"); + testFrame.addLifeLine(lifeline); + EllipsisMessage mn = new EllipsisMessage(); + lifeline.getNewEventOccurrence(); + mn.setStartLifeline(lifeline); + mn.setName("******************* EllipsisisMessage TEST ****************"); + testFrame.addMessage(mn); + SyncMessage mn3 = new SyncMessage(); + mn3.setStartLifeline(lifeline); + testFrame.addMessage(mn3); + SyncMessage mn2 = new SyncMessage(); + lifeline.getNewEventOccurrence(); + lifeline.setCategory(0); + mn2.setEndLifeline(lifeline); + mn2.setName("*******************Sync TEST ****************"); + testFrame.addMessage(mn2); + for (int i = 1; i < 300; i++) { + lifeline = new Lifeline(); + lifeline.setName((new StringBuilder("LifeLine ")).append(i).toString()); + lifeline.setCategory(1); + testFrame.addLifeLine(lifeline); + SyncMessage m3 = new SyncMessage(); + testFrame.getLifeline(i - 1).getNewEventOccurrence(); + m3.setStartLifeline(testFrame.getLifeline(i - 1)); + m3.setEndLifeline(testFrame.getLifeline(i)); + m3.setName((new StringBuilder("Sync Message ")).append(i).toString()); + testFrame.addMessage(m3); +// if (i == 11) +// m3.setTime(new TmfTimestamp(i - 400)); +// else if (i == 6) +// m3.setTime(new TmfTimestamp(i)); +// else + m3.setTime(new TmfTimestamp(i + 1)); + } + + for (int i = testFrame.lifeLinesCount() - 1; i > 0; i--) { + SyncMessageReturn m = new SyncMessageReturn(); + testFrame.getLifeline(i).getNewEventOccurrence(); + m.setStartLifeline(testFrame.getLifeline(i)); + m.setEndLifeline(testFrame.getLifeline(i - 1)); + testFrame.addMessage(m); + m.setName((new StringBuilder("Sync Message return ")).append(i).toString()); + if (i + 1 < testFrame.lifeLinesCount()) { + SyncMessage h = testFrame.getSyncMessage(i + 1); + m.setMessage(h); + } + } + + for (int i = 0; i < testFrame.lifeLinesCount(); i++) { + if (i > 0) { + ExecutionOccurrence occ = new ExecutionOccurrence(); + occ.setStartOccurrence(testFrame.getSyncMessage(i).getEventOccurrence() + 1); + occ.setEndOccurrence(testFrame.getSyncMessageReturn(testFrame.syncMessageReturnCount() - i).getEventOccurrence()); + testFrame.getLifeline(i).addExecution(occ); + occ.setName("******************* Execution Occurance TEST ****************"); + } + } + + Stop s = new Stop(); + s.setLifeline(testFrame.getLifeline(1)); + s.setEventOccurrence(testFrame.getLifeline(1).getNewEventOccurrence()); + testFrame.getLifeline(1).addNode(s); + HotSpot gg = new HotSpot(); + gg.setImage(new LocalImageImpl("obj16/plus_obj.gif")); + gg.setExecution((BasicExecutionOccurrence) testFrame.getLifeline(1).getExecutions().get(0)); + AsyncMessageReturn m = new AsyncMessageReturn(); + m.setStartLifeline(testFrame.getLifeline(1)); + m.setEndLifeline(testFrame.getLifeline(3)); + m.setStartOccurrence(2); + m.setEndOccurrence(6); + m.setStartTime(new TmfTimestamp(2)); + m.setEndTime(new TmfTimestamp(6)); + m.setName("*******************Async TEST ****************"); + testFrame.addMessage(m); + v.setFrame(testFrame); + v.getSDWidget().setReorderMode(true); + } else { + +// if (page == 2) { + testFrame.setName("Sequence Diagram"); + Lifeline lifeline = new Lifeline(); + lifeline.setName("LifeLine 0"); + testFrame.addLifeLine(lifeline); + lifeline = new Lifeline(); + lifeline.setName("LifeLine 1"); + testFrame.addLifeLine(lifeline); + for (int i = 1; i < 30; i++) { + SyncMessage m3 = new SyncMessage(); + m3.autoSetStartLifeline(testFrame.getLifeline(0)); + m3.autoSetEndLifeline(testFrame.getLifeline(0)); + m3.setName((new StringBuilder("Message ")).append(i).toString()); + testFrame.addMessage(m3); + SyncMessageReturn m = new SyncMessageReturn(); + m.autoSetStartLifeline(testFrame.getLifeline(0)); + m.autoSetEndLifeline(testFrame.getLifeline(0)); + testFrame.addMessage(m); + m.setName((new StringBuilder("Message return ")).append(i).toString()); + ExecutionOccurrence occ = new ExecutionOccurrence(); + occ.setStartOccurrence(testFrame.getSyncMessage(i - 1).getEventOccurrence()); + occ.setEndOccurrence(testFrame.getSyncMessageReturn(i - 1).getEventOccurrence()); + testFrame.getLifeline(0).addExecution(occ); + } + } + v.setFrame(testFrame); + } + + @Override + public boolean find(Criteria toSearch) { + Frame frame = v.getFrame(); + + if (frame == null) { + return false; + } + if (findResults == null || findCriteria == null || !findCriteria.compareTo(toSearch)) { + findResults = new ArrayList<>(); + findCriteria = toSearch; + if (findCriteria.isLifeLineSelected()) { + for (int i = 0; i < frame.lifeLinesCount(); i++) { + if (findCriteria.matches(frame.getLifeline(i).getName())) { + findResults.add(frame.getLifeline(i)); + } + } + + } + ArrayList msgs = new ArrayList<>(); + if (findCriteria.isSyncMessageSelected()) { + for (int i = 0; i < frame.syncMessageCount(); i++) { + if (findCriteria.matches(frame.getSyncMessage(i).getName())) { + msgs.add(frame.getSyncMessage(i)); + } + } + + for (int i = 0; i < frame.syncMessageReturnCount(); i++) { + if (findCriteria.matches(frame.getSyncMessageReturn(i).getName())) { + msgs.add(frame.getSyncMessageReturn(i)); + } + } + + } + // if(msgs.size() > 0) { + // GraphNode temp[] = msgs.toArray(new GraphNode[0]); + // Arrays.sort(temp, new DateComparator()); + // findResults.addAll(Arrays.asList(temp)); + // } + + msgs = new ArrayList<>(); + if (findCriteria.isAsyncMessageSelected()) { + for (int i = 0; i < frame.asyncMessageCount(); i++) { + if (findCriteria.matches(frame.getAsyncMessage(i).getName())) { + msgs.add(frame.getAsyncMessage(i)); + } + } + + for (int i = 0; i < frame.asyncMessageReturnCount(); i++) { + if (findCriteria.matches(frame.getAsyncMessageReturn(i).getName())) { + msgs.add(frame.getAsyncMessageReturn(i)); + } + } + + } + // if(msgs.size() > 0) { + // GraphNode temp[] = msgs.toArray(new GraphNode[0]); + // Arrays.sort(temp, new DateComparator()); + // findResults.addAll(Arrays.asList(temp)); + // } + + List selection = v.getSDWidget().getSelection(); + if (selection != null && selection.size() == 1) { + currentFindIndex = findResults.indexOf(selection.get(0)) + 1; + } else { + currentFindIndex = 0; + } + } else { + currentFindIndex++; + } + if (findResults.size() > currentFindIndex) { + GraphNode current = findResults.get(currentFindIndex); + v.getSDWidget().moveTo(current); + return true; + } + // return notFoundYet(findCriteria); // search in other page + return false; + } + + @Override + public void cancel() { + findResults = null; + findCriteria = null; + currentFindIndex = 0; + } + + public boolean isLifelineSupported() { + return false; + } + + public boolean isSyncMessageSupported() { + return false; + } + + public boolean isSyncMessageReturnSupported() { + return false; + } + + public boolean isAsyncMessageSupported() { + return false; + } + + public boolean isAsyncMessageReturnSupported() { + return false; + } + + public boolean isStopSupported() { + return false; + } + + public Action getFindAction() { + return null; + } + + @Override + public boolean filter(List filters) { + + if (savedFrame != null) { + savedFrame = v.getFrame(); + } + + Frame frame = v.getFrame(); + + if (frame == null) { + return false; + } + + if (filters.size() != 1) { + return false; + } + + FilterCriteria filterCriteria = filters.get(0); + + // One way is to set visiblity of the item, but this only works for messages and not + // for lifelines! It's better to create a new frame without the filtered messages. + boolean found = false; + if (filterCriteria.getCriteria().isSyncMessageSelected()) { + for (int i = 0; i < frame.syncMessageCount(); i++) { + if (filterCriteria.getCriteria().matches(frame.getSyncMessage(i).getName())) { + frame.getSyncMessage(i).setVisible(false); + found = true; + } + } + + for (int i = 0; i < frame.syncMessageReturnCount(); i++) { + if (filterCriteria.getCriteria().matches(frame.getSyncMessageReturn(i).getName())) { + frame.getSyncMessageReturn(i).setVisible(false); + found = true; + } + } + } + + v.getSDWidget().redraw(); + return found; + } + + public ArrayList getCurrentFilters() { + return null; + } + + @Override + public String getTitleString() { + return "Test Loader"; + } + + @Override + public void dispose() { + } + + + @Override + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + ISelection sel = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().getSelection(); + if (sel != null && (sel instanceof StructuredSelection)) { + StructuredSelection stSel = (StructuredSelection) sel; + if (stSel.getFirstElement() instanceof HotSpot) { + // OpenToolBox gg = new OpenToolBox(v); + // gg.run(); + } + } + } + + @Override + public boolean isNodeSupported(int nodeType) { + switch (nodeType) { + case ISDGraphNodeSupporter.LIFELINE: + case ISDGraphNodeSupporter.SYNCMESSAGE: + case ISDGraphNodeSupporter.SYNCMESSAGERETURN: + case ISDGraphNodeSupporter.ASYNCMESSAGE: + case ISDGraphNodeSupporter.ASYNCMESSAGERETURN: + case ISDGraphNodeSupporter.STOP: + return true; + + default: + break; + } + return false; + } + + @Override + public String getNodeName(int nodeType, String loaderClassName) { + return null; + } + + public static class LocalImageImpl implements IImage { + protected Image img; + + public LocalImageImpl(String file) { + img = null; + img = getResourceImage(file); + } + + public LocalImageImpl(Image img_) { + img = null; + img = img_; + } + + public Image getResourceImage(String _name) { + ImageDescriptor imgage; + try { + URL BASIC_URL = new URL("platform", "localhost", "plugin"); + URL url = new URL(BASIC_URL, (new StringBuilder("plugin/org.eclipse.linuxtools.tmf.ui/icons/")).append(_name).toString()); + imgage = ImageDescriptor.createFromURL(url); + return imgage.createImage(); + } catch (Exception e) { + System.err.println(e); + } + return null; + } + + @Override + public Object getImage() { + return img; + } + + @Override + public void dispose() { + if (img != null) { + img.dispose(); + } + } + + } + + @Override + public void firstPage() { + page = 0; + createFrame(); + + } + + @Override + public void lastPage() { + page = 2; + createFrame(); + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/tests/uml2sd/trace/TmfUml2SDTestTrace.java b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/tests/uml2sd/trace/TmfUml2SDTestTrace.java new file mode 100644 index 0000000000..2d0d6841c7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/tests/uml2sd/trace/TmfUml2SDTestTrace.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ui.tests.uml2sd.trace; + +import java.io.EOFException; +import java.io.IOException; +import java.io.RandomAccessFile; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEvent; +import org.eclipse.tracecompass.tmf.core.event.TmfEventField; +import org.eclipse.tracecompass.tmf.core.event.TmfEventType; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfEventParser; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; + +/** + * Parser implementation for Uml2SD Test Traces. + * + */ +public class TmfUml2SDTestTrace implements ITmfEventParser { + + ITmfTrace fEventStream; + + /** + * Default Constructor + */ + public TmfUml2SDTestTrace() { + } + + /** + * Constructor + * @param eventStream ITmfTrace implementation + */ + public TmfUml2SDTestTrace(ITmfTrace eventStream) { + fEventStream = eventStream; + } + + /** + * @param eventStream ITmfTrace implementation to set + */ + public void setTrace(ITmfTrace eventStream) { + fEventStream = eventStream; + } + + @Override + public ITmfEvent parseEvent(ITmfContext context) { + if (! (fEventStream instanceof TmfTraceStub)) { + return null; + } + + // Highly inefficient... + RandomAccessFile stream = ((TmfTraceStub) fEventStream).getStream(); + +// String name = eventStream.getName(); +// name = name.substring(name.lastIndexOf('/') + 1); + + long location = 0; + if (context != null) { + location = (Long) context.getLocation().getLocationInfo(); + } + + try { + stream.seek(location); + + long ts = stream.readLong(); + String source = stream.readUTF(); + String type = stream.readUTF(); + String reference = stream.readUTF(); + String sender = stream.readUTF(); + String receiver = stream.readUTF(); + String signal = stream.readUTF(); + + String[] labels = {"sender", "receiver", "signal"}; + + TmfEventType tmfEventType = new TmfEventType("UnitTest", type, TmfEventField.makeRoot(labels)); + + String content = "["; + content += sender; + content += "," + receiver; + content += "," + signal; + content += "]"; + + // Pre-parse the content + TmfEventField[] fields = new TmfEventField[3]; + fields[0] = new TmfEventField("sender", sender, null); + fields[1] = new TmfEventField("receiver", receiver, null); + fields[2] = new TmfEventField("signal", signal, null); + + ITmfEventField tmfContent = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, content, fields); + ITmfEvent tmfEvent = new TmfEvent(fEventStream, new TmfTimestamp(ts, -9), source, tmfEventType, tmfContent, reference); + + return tmfEvent; + } catch (final EOFException e) { + } catch (final IOException e) { + } + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/adaption/TsfImplProvider.java b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/adaption/TsfImplProvider.java new file mode 100644 index 0000000000..f3b0ce6666 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/adaption/TsfImplProvider.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.test.stub.adaption; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.test.stub.model.EventImpl; + +/** + * Time Graph Presentation Provider Stub. + */ +public class TsfImplProvider extends TimeGraphPresentationProvider { + + // ======================================================================== + // Methods + // ======================================================================== + @Override + public int getStateTableIndex(ITimeEvent event) { + return 0; + } + + @Override + public Map getEventHoverToolTipInfo(ITimeEvent revent) { + Map toolTipEventMsgs = new HashMap<>(); + if (revent instanceof EventImpl) { + toolTipEventMsgs.put("Test Tip1", "Test Value tip1"); + toolTipEventMsgs.put("Test Tip2", "Test Value tip2"); + } + + return toolTipEventMsgs; + } + + @Override + public String getEventName(ITimeEvent event) { + String name = "Unknown"; + if (event instanceof EventImpl) { + EventImpl devent = (EventImpl) event; + name = devent.getType().toString(); + } + return name; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/model/EventImpl.java b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/model/EventImpl.java new file mode 100644 index 0000000000..ab0b945316 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/model/EventImpl.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2009, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.test.stub.model; + +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; + +/** + * ITimeEvent implementation for test purposes. + */ +@SuppressWarnings("javadoc") +public class EventImpl implements ITimeEvent { + // ======================================================================== + // Data + // ======================================================================== + public static enum Type {ERROR, WARNING, TIMEADJUSTMENT, ALARM, EVENT, INFORMATION, UNKNOWN, INFO1, INFO2, INFO3, INFO4, INFO5, INFO6, INFO7, INFO8, INFO9} + + private long time = 0; + private ITimeGraphEntry trace = null; + private Type myType = Type.UNKNOWN; + private long duration; + + // ======================================================================== + // Constructor + // ======================================================================== + public EventImpl(long time, ITimeGraphEntry trace, Type type) { + this.time = time; + this.trace = trace; + this.myType = type; + } + + // ======================================================================== + // Methods + // ======================================================================== + public Type getType() { + return myType; + } + + public void setType(Type myType) { + this.myType = myType; + } + + public void setTime(long time) { + this.time = time; + } + + public void setTrace(ITimeGraphEntry trace) { + this.trace = trace; + } + + @Override + public long getTime() { + return time; + } + + @Override + public ITimeGraphEntry getEntry() { + return trace; + } + + /** + * @param duration the duration to set + */ + public void setDuration(long duration) { + this.duration = duration; + } + + /** + * @return the duration + */ + @Override + public long getDuration() { + return duration; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/model/TraceImpl.java b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/model/TraceImpl.java new file mode 100644 index 0000000000..3b8cd5b585 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/model/TraceImpl.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.test.stub.model; + +import java.util.Iterator; +import java.util.List; +import java.util.Vector; + +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; + +@SuppressWarnings("javadoc") +public class TraceImpl implements ITimeGraphEntry { + + // ======================================================================== + // Data + // ======================================================================== + + private String name = "traceDefaultName"; + private long startTime = 0; + private long stopTime = 1; + private String className = "defaultClassName"; + private Vector traceEvents = new Vector<>(); + + // ======================================================================== + // Constructor + // ======================================================================== + + public TraceImpl(String name, long sTime, long stopTime, String className) { + this.name = name; + this.startTime = sTime; + this.stopTime = stopTime; + this.className = className; + } + + // ======================================================================== + // Methods + // ======================================================================== + + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } + + public void setName(String name) { + this.name = name; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + } + + public void setStopTime(long stopTime) { + this.stopTime = stopTime; + } + + @Override + public String getName() { + return name; + } + + @Override + public long getStartTime() { + return startTime; + } + + @Override + public long getEndTime() { + return stopTime; + } + + @Override + public boolean hasTimeEvents() { + return traceEvents != null; + } + + @Override + public Iterator getTimeEventsIterator() { + return traceEvents.iterator(); + } + + @Override + public Iterator getTimeEventsIterator(long aStartTime, long aStopTime, long maxDuration) { + return traceEvents.iterator(); + } + + public void addTraceEvent(ITimeEvent event) { + traceEvents.add(event); + } + + @Override + public List getChildren() { + return null; + } + + @Override + public ITimeGraphEntry getParent() { + return null; + } + + @Override + public boolean hasChildren() { + return false; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/model/TraceModelImplFactory.java b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/model/TraceModelImplFactory.java new file mode 100644 index 0000000000..a5abc2de92 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/model/TraceModelImplFactory.java @@ -0,0 +1,232 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.test.stub.model; + +import java.util.Date; + +@SuppressWarnings("javadoc") +public class TraceModelImplFactory { + + // ======================================================================== + // Data + // ======================================================================== + private int count = 0; + private final TraceStrings[] traceNames; + private static final long msTons = 1000000; + private final Long timeRef = new Date().getTime() * msTons; + + // ======================================================================== + // Constructor + // ======================================================================== + public TraceModelImplFactory() { + traceNames = new TraceStrings[17]; + loadTraceNameStrings(); + } + + // ======================================================================== + // Methods + // ======================================================================== + public TraceImpl[] createTraces() { + TraceImpl trace; + TraceImpl[] traceArr = new TraceImpl[17]; + for (int i = 0; i < traceArr.length; i++) { + trace = new TraceImpl(traceNames[i].name, timeRef, timeRef + 40, + traceNames[i].classNmme); + count = i; + createEvents(trace); + traceArr[i] = trace; + } + return traceArr; + } + + /** + * 5000 Events per Trace. + * @param number + * @return + */ + public TraceImpl[] createLargeTraces(int number) { + TraceImpl trace; + TraceImpl[] traceArr = new TraceImpl[number]; + for (int i = 0; i < traceArr.length; i++) { + int counter = i%17; + long sTime = i * (long) 1E6; + trace = new TraceImpl(traceNames[counter].name, sTime , sTime + 20000, + traceNames[counter].classNmme); + create5000Events(trace); + traceArr[i] = trace; + } + return traceArr; + } + + private static void create5000Events(TraceImpl trace) { + EventImpl event; + Long eventTime; + int numEvents = 5000; + long sTime = trace.getStartTime(); + long eTime = trace.getEndTime(); + long duration = (eTime - sTime)/numEvents; + for (int i = 0; i < numEvents; i++) { + eventTime = sTime + (i * duration); + // eventTime = timeRef + (5 * (count % 4) + (5 * (int) (i/2) )); + // System.out.println("Trace: " + trace.getName() + " EventTime: " + // + eventTime); +// duration = i * msTons + (long) ((i % 4)); + + event = new EventImpl(eventTime, trace, getEventType(i%16)); + event.setDuration(duration); + trace.addTraceEvent(event); + } + } + + private void createEvents(TraceImpl trace) { + EventImpl event; + Long eventTime; + int numEvents = 17; + long duration = 0; + for (int i = 0; i < numEvents; i++) { + eventTime = timeRef + msTons * i + (5 * msTons * count) + (5 * i); + duration = msTons + i * msTons + ((i % 4)); +// duration = i + (long) ((i % 4)); + event = new EventImpl(eventTime, trace, getEventType(i)); + event.setDuration(duration); + trace.addTraceEvent(event); + } + } + + private static EventImpl.Type getEventType(int val) { + if (EventImpl.Type.ALARM.ordinal() == val) { + return EventImpl.Type.ALARM; + } + if (EventImpl.Type.ERROR.ordinal() == val) { + return EventImpl.Type.ERROR; + } + if (EventImpl.Type.EVENT.ordinal() == val) { + return EventImpl.Type.EVENT; + } + if (EventImpl.Type.INFORMATION.ordinal() == val) { + return EventImpl.Type.INFORMATION; + } + if (EventImpl.Type.TIMEADJUSTMENT.ordinal() == val) { + return EventImpl.Type.TIMEADJUSTMENT; + } + if (EventImpl.Type.WARNING.ordinal() == val) { + return EventImpl.Type.WARNING; + } + if (EventImpl.Type.INFO1.ordinal() == val) { + return EventImpl.Type.INFO1; + } + if (EventImpl.Type.INFO2.ordinal() == val) { + return EventImpl.Type.INFO2; + } + if (EventImpl.Type.INFO3.ordinal() == val) { + return EventImpl.Type.INFO3; + } + if (EventImpl.Type.INFO4.ordinal() == val) { + return EventImpl.Type.INFO4; + } + if (EventImpl.Type.INFO5.ordinal() == val) { + return EventImpl.Type.INFO5; + } + if (EventImpl.Type.INFO6.ordinal() == val) { + return EventImpl.Type.INFO6; + } + if (EventImpl.Type.INFO7.ordinal() == val) { + return EventImpl.Type.INFO7; + } + if (EventImpl.Type.INFO8.ordinal() == val) { + return EventImpl.Type.INFO8; + } + if (EventImpl.Type.INFO9.ordinal() == val) { + return EventImpl.Type.INFO9; + } + return EventImpl.Type.UNKNOWN; + } + + private void loadTraceNameStrings() { + traceNames[0] = new TraceStrings(); + traceNames[0].name = "TE Log - TATA BSC11"; + traceNames[0].classNmme = "All Boards"; + + traceNames[1] = new TraceStrings(); + traceNames[1].name = "System Log"; + traceNames[1].classNmme = "BSC11"; + + traceNames[2] = new TraceStrings(); + traceNames[2].name = "Alarm Log"; + traceNames[2].classNmme = "BSC11"; + + traceNames[3] = new TraceStrings(); + traceNames[3].name = "Events Log"; + traceNames[3].classNmme = "BSC 11"; + + traceNames[4] = new TraceStrings(); + traceNames[4].name = "CPU Load"; + traceNames[4].classNmme = "All Boards"; + + traceNames[5] = new TraceStrings(); + traceNames[5].name = "Performance Log"; + traceNames[5].classNmme = "BSC11"; + + traceNames[6] = new TraceStrings(); + traceNames[6].name = "TE Log - TATA BSC14"; + traceNames[6].classNmme = "Board 24"; + + traceNames[7] = new TraceStrings(); + traceNames[7].name = "TE Log - TATA BSC14"; + traceNames[7].classNmme = "Board 23"; + + traceNames[8] = new TraceStrings(); + traceNames[8].name = "TE Log - TATA BSC14"; + traceNames[8].classNmme = "Board 11"; + + traceNames[9] = new TraceStrings(); + traceNames[9].name = "TE Log - TATA BSC14"; + traceNames[9].classNmme = "Board 14, SPO"; + + traceNames[10] = new TraceStrings(); + traceNames[10].name = "INFO 1"; + traceNames[10].classNmme = "All Boards"; + + traceNames[11] = new TraceStrings(); + traceNames[11].name = "INFO2"; + traceNames[11].classNmme = "BSC11"; + + traceNames[12] = new TraceStrings(); + traceNames[12].name = "INFO3"; + traceNames[12].classNmme = "Board 24"; + + traceNames[13] = new TraceStrings(); + traceNames[13].name = "MISC1"; + traceNames[13].classNmme = "Board 23"; + + traceNames[14] = new TraceStrings(); + traceNames[14].name = "MISC2"; + traceNames[14].classNmme = "Board 11"; + + traceNames[15] = new TraceStrings(); + traceNames[15].name = "MISC3"; + traceNames[15].classNmme = "Board 23"; + + traceNames[16] = new TraceStrings(); + traceNames[16].name = "MISC4"; + traceNames[16].classNmme = "Board 11"; + + } + + // ======================================================================== + // Inner Class + // ======================================================================== + private static class TraceStrings { + public String name = ""; + public String classNmme = name + " class"; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/views/TsfTraceAnalysisView.java b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/views/TsfTraceAnalysisView.java new file mode 100644 index 0000000000..fab7e5f333 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui.tests/widgetStubs/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/test/stub/views/TsfTraceAnalysisView.java @@ -0,0 +1,672 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + * Patrick Tasse - Support selection range + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.test.stub.views; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphRangeListener; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphSelectionListener; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphTimeListener; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphSelectionEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphTimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphViewer; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.test.stub.adaption.TsfImplProvider; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.test.stub.model.EventImpl; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.test.stub.model.TraceImpl; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.test.stub.model.TraceModelImplFactory; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.DrillDownAdapter; +import org.eclipse.ui.part.ViewPart; + +@SuppressWarnings("javadoc") +public class TsfTraceAnalysisView extends ViewPart implements + ITimeGraphSelectionListener, ITimeGraphTimeListener, ITimeGraphRangeListener { + + // ======================================================================== + // Data + // ======================================================================== + + private TreeViewer viewer; + private DrillDownAdapter drillDownAdapter; + private Action action1; + private Action action2; + private Action resetScale; + private Action nextEvent; + private Action prevEvent; + private Action nextTrace; + private Action prevTrace; + private Action showLegent; + private Action zoomIn; + private Action zoomOut; + private Action events300K; + + private Action doubleClickAction; + private TimeGraphViewer tsfviewer; + private TimeGraphViewer tsfviewer2; + + private static SimpleDateFormat stimeformat = new SimpleDateFormat( + "yy/MM/dd HH:mm:ss"); + private TraceModelImplFactory fact; + + // ======================================================================== + // Inner Classes + // ======================================================================== + /* + * The content provider class is responsible for providing objects to the + * view. It can wrap existing objects in adapters or simply return objects + * as-is. These objects may be sensitive to the current input of the view, + * or ignore it and always show the same content (like Task List, for + * example). + */ + + class TreeObject implements IAdaptable { + private final String name; + private TreeParent parent; + + public TreeObject(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setParent(TreeParent parent) { + this.parent = parent; + } + + public TreeParent getParent() { + return parent; + } + + @Override + public String toString() { + return getName(); + } + + @Override + public Object getAdapter(Class key) { + return null; + } + } + + class TreeParent extends TreeObject { + private final ArrayList children; + + public TreeParent(String name) { + super(name); + children = new ArrayList<>(); + } + + public void addChild(TreeObject child) { + children.add(child); + child.setParent(this); + } + + public void removeChild(TreeObject child) { + children.remove(child); + child.setParent(null); + } + + public TreeObject[] getChildren() { + return children.toArray(new TreeObject[children + .size()]); + } + + public boolean hasChildren() { + return children.size() > 0; + } + } + + class ViewContentProvider implements ITreeContentProvider { + private TreeParent invisibleRoot; + + @Override + public void inputChanged(Viewer v, Object oldInput, Object newInput) { + } + + @Override + public void dispose() { + } + + @Override + public Object[] getElements(Object parent) { + if (parent.equals(getViewSite())) { + if (invisibleRoot == null) { + initialize(); + } + return getChildren(invisibleRoot); + } + return getChildren(parent); + } + + @Override + public Object getParent(Object child) { + if (child instanceof TreeObject) { + return ((TreeObject) child).getParent(); + } + return null; + } + + @Override + public Object[] getChildren(Object parent) { + if (parent instanceof TreeParent) { + return ((TreeParent) parent).getChildren(); + } + return new Object[0]; + } + + @Override + public boolean hasChildren(Object parent) { + if (parent instanceof TreeParent) { + return ((TreeParent) parent).hasChildren(); + } + return false; + } + + /* + * We will set up a dummy model to initialize tree heararchy. In a real + * code, you will connect to a real model and expose its hierarchy. + */ + private void initialize() { + TreeObject to1 = new TreeObject("Leaf 1"); + TreeObject to2 = new TreeObject("Leaf 2"); + TreeObject to3 = new TreeObject("Leaf 3"); + TreeParent p1 = new TreeParent("Parent 1"); + p1.addChild(to1); + p1.addChild(to2); + p1.addChild(to3); + + TreeObject to4 = new TreeObject("Leaf 4"); + TreeParent p2 = new TreeParent("Parent 2"); + p2.addChild(to4); + + TreeParent root = new TreeParent("Root"); + root.addChild(p1); + root.addChild(p2); + + invisibleRoot = new TreeParent(""); + invisibleRoot.addChild(root); + } + } + + static class ViewLabelProvider extends LabelProvider { + + @Override + public String getText(Object obj) { + return obj.toString(); + } + + @Override + public Image getImage(Object obj) { + String imageKey = ISharedImages.IMG_OBJ_ELEMENT; + if (obj instanceof TreeParent) { + imageKey = ISharedImages.IMG_OBJ_FOLDER; + } + return PlatformUI.getWorkbench().getSharedImages().getImage( + imageKey); + } + } + + static class NameSorter extends ViewerSorter { + } + + // ======================================================================== + // Methods + // ======================================================================== + /** + * This is a callback that will allow us to create the viewer and initialize + * it. + */ + @Override + public void createPartControl(Composite parent) { + final SashForm sashForm = new SashForm(parent, SWT.NONE); + final SashForm sashForm2 = new SashForm(sashForm, SWT.NONE); + + tsfviewer = new TimeGraphViewer(sashForm2, SWT.NONE); + tsfviewer.setTimeGraphProvider(new TsfImplProvider()); + tsfviewer2 = new TimeGraphViewer(sashForm2, SWT.NONE); + tsfviewer2.setTimeGraphProvider(new TsfImplProvider()); + + viewer = new TreeViewer(sashForm, SWT.MULTI | SWT.H_SCROLL + | SWT.V_SCROLL); + drillDownAdapter = new DrillDownAdapter(viewer); + viewer.setContentProvider(new ViewContentProvider()); + viewer.setLabelProvider(new ViewLabelProvider()); + viewer.setSorter(new NameSorter()); + viewer.setInput(getViewSite()); + + sashForm.setWeights(new int[] { 5, 1 }); + sashForm2.setWeights(new int[] { 1, 1 }); + + fact = new TraceModelImplFactory(); + ITimeGraphEntry[] traceArr = fact.createTraces(); + tsfviewer.setInput(traceArr); + tsfviewer.addSelectionListener(this); + tsfviewer.addRangeListener(this); + tsfviewer.setTimeFormat(TimeFormat.CALENDAR); + + tsfviewer2.setInput(traceArr); + tsfviewer2.addSelectionListener(this); + tsfviewer2.addRangeListener(this); + // tsfviewer2.setTimeFormat(TimeGraphViewer.timeFormat.epoch); + + makeActions(); + hookContextMenu(); + hookDoubleClickAction(); + contributeToActionBars(); + } + + private void hookContextMenu() { + MenuManager menuMgr = new MenuManager("#PopupMenu"); + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + @Override + public void menuAboutToShow(IMenuManager manager) { + TsfTraceAnalysisView.this.fillContextMenu(manager); + } + }); + Menu menu = menuMgr.createContextMenu(viewer.getControl()); + viewer.getControl().setMenu(menu); + getSite().registerContextMenu(menuMgr, viewer); + } + + private void contributeToActionBars() { + IActionBars bars = getViewSite().getActionBars(); + fillLocalPullDown(bars.getMenuManager()); + fillLocalToolBar(bars.getToolBarManager()); + } + + private void fillLocalPullDown(IMenuManager manager) { + manager.add(action1); + manager.add(new Separator()); + manager.add(action2); + } + + private void fillContextMenu(IMenuManager manager) { + manager.add(action1); + manager.add(action2); + manager.add(new Separator()); + drillDownAdapter.addNavigationActions(manager); + // Other plug-ins can contribute there actions here + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + } + + private void fillLocalToolBar(IToolBarManager manager) { + manager.add(new Separator()); + manager.add(resetScale); + manager.add(nextEvent); + manager.add(prevEvent); + manager.add(nextTrace); + manager.add(prevTrace); + manager.add(showLegent); + manager.add(zoomIn); + manager.add(zoomOut); + manager.add(events300K); + manager.add(new Separator()); + + drillDownAdapter.addNavigationActions(manager); + } + + private TimeGraphViewer getActiveTsfCtrl() { + TimeGraphViewer inFocusViewer = null; + if (tsfviewer.isInFocus()) { + inFocusViewer = tsfviewer; + } else if (tsfviewer2.isInFocus()) { + inFocusViewer = tsfviewer2; + } + return inFocusViewer; + } + + private void makeActions() { + // action1 + action1 = new Action() { + @Override + public void run() { + showMessage("Action 1 executed"); + } + }; + action1.setText("Action 1"); + action1.setToolTipText("Action 1 tooltip"); + action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages() + .getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK)); + + // action2 + action2 = new Action() { + @Override + public void run() { + showMessage("Action 2 executed"); + } + }; + action2.setText("Action 2"); + action2.setToolTipText("Action 2 tooltip"); + action2.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages() + .getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK)); + + // action4 + resetScale = new Action() { + @Override + public void run() { + TimeGraphViewer inFocusViewer = getActiveTsfCtrl(); + if (inFocusViewer != null) { + inFocusViewer.resetStartFinishTime(); + } + + } + }; + resetScale.setText("Reset"); + resetScale.setToolTipText("Reset the Time Scale to Default"); + + // action5 + nextEvent = new Action() { + @Override + public void run() { + TimeGraphViewer inFocusViewer = getActiveTsfCtrl(); + if (inFocusViewer != null) { + inFocusViewer.selectNextEvent(); + } + } + }; + nextEvent.setText("NextEv"); + nextEvent.setToolTipText("Next Event"); + + // action6 + prevEvent = new Action() { + @Override + public void run() { + TimeGraphViewer inFocusViewer = getActiveTsfCtrl(); + if (inFocusViewer != null) { + inFocusViewer.selectPrevEvent(); + } + } + }; + prevEvent.setText("PrevEv"); + prevEvent.setToolTipText("Previous Event"); + + // action7 + nextTrace = new Action() { + @Override + public void run() { + TimeGraphViewer inFocusViewer = getActiveTsfCtrl(); + if (inFocusViewer != null) { + inFocusViewer.selectNextItem(); + } + } + }; + nextTrace.setText("NextTrace"); + nextTrace.setToolTipText("Select Next Event"); + + // action8 + prevTrace = new Action() { + @Override + public void run() { + TimeGraphViewer inFocusViewer = getActiveTsfCtrl(); + if (inFocusViewer != null) { + inFocusViewer.selectPrevItem(); + } + } + }; + prevTrace.setText("PrevTrace"); + prevTrace.setToolTipText("Select Previous Trace"); + + // action9 + showLegent = new Action() { + @Override + public void run() { + TimeGraphViewer inFocusViewer = getActiveTsfCtrl(); + if (inFocusViewer != null) { + inFocusViewer.showLegend(); + } + } + }; + showLegent.setText("Legend"); + showLegent.setToolTipText("Show Legend"); + + // action10 + zoomIn = new Action() { + @Override + public void run() { + TimeGraphViewer inFocusViewer = getActiveTsfCtrl(); + if (inFocusViewer != null) { + inFocusViewer.zoomIn(); + } + } + }; + zoomIn.setText("Zoom In"); + zoomIn.setToolTipText("Zoom In"); + + // action10 + zoomOut = new Action() { + @Override + public void run() { + TimeGraphViewer inFocusViewer = getActiveTsfCtrl(); + if (inFocusViewer != null) { + inFocusViewer.zoomOut(); + } + // ISelection selection = inFocusViewer.getSelection(); + // Object sel = null; + // if (selection != null && !selection.isEmpty()) { + // sel = ((IStructuredSelection) selection) + // .getFirstElement(); + // if (sel instanceof EventImpl) { + // EventImpl event = (EventImpl) sel; + // inFocusViewer.selectNextEvent(); + // } + // } + } + }; + zoomOut.setText("Zoom Out"); + zoomOut.setToolTipText("Zoom Out"); + + // action12 + events300K = new Action() { + @Override + public void run() { + TimeGraphViewer inFocusViewer = getActiveTsfCtrl(); + if (inFocusViewer != null) { + ITimeGraphEntry[] traceArr = fact + .createLargeTraces(60); + inFocusViewer.setInput(traceArr); + } + } + }; + events300K.setText("300K Events"); + events300K.setToolTipText("Add 300K Events"); + + doubleClickAction = new Action() { + @Override + public void run() { + ISelection selection = viewer.getSelection(); + Object obj = ((IStructuredSelection) selection) + .getFirstElement(); + showMessage("Double-click detected on " + obj.toString()); + } + }; + } + + private void hookDoubleClickAction() { + viewer.addDoubleClickListener(new IDoubleClickListener() { + @Override + public void doubleClick(DoubleClickEvent event) { + doubleClickAction.run(); + } + }); + } + + private void showMessage(String message) { + MessageDialog.openInformation(viewer.getControl().getShell(), + "TsfTrace Analysis View", message); + } + + /** + * Passing the focus request to the viewer's control. + */ + @Override + public void setFocus() { + viewer.getControl().setFocus(); + } + + @Override + public void selectionChanged(TimeGraphSelectionEvent event) { + Object source = event.getSource(); + if (source == null || !(source instanceof TimeGraphViewer)) { + return; + } + + TimeGraphViewer rViewer = (TimeGraphViewer) event.getSource(); + TimeGraphViewer synchViewer = null; + // Synchronize viewer selections if Enabled, + // make sure the selection does not go in loops + if (tsfviewer == rViewer) { + synchViewer = tsfviewer2; + } else { + synchViewer = tsfviewer; + } + Object selection = event.getSelection(); + + if (selection instanceof EventImpl) { + EventImpl selEvent = (EventImpl) selection; + System.out + .println("TsfTraceAnalysisView.selectionChanged() Selected Event: \nType: " + + selEvent.getType().toString() + + "\nTime: " + + selEvent.getTime() + + "\nTrace Name: " + + selEvent.getEntry().getName()); + + synchViewer.setSelectedEvent(selEvent, source); + + } else if (selection instanceof TraceImpl) { + TraceImpl selTrace = (TraceImpl) selection; + System.out + .println("TsfTraceAnalysisView.selectionChanged() Selected Trace: \nName: " + + selTrace.getName().toString() + + "\nClass Name: " + + selTrace.getClassName()); + + synchViewer.setSelection(selTrace); + } else { + System.out + .println("TsfTmIncubatorListener.tsfTmProcessEvent() Unexpected event source received: " + + selection.getClass().getName()); + } + + } + + @Override + public void timeSelected(TimeGraphTimeEvent event) { + TimeGraphViewer rViewer = (TimeGraphViewer) event.getSource(); + TimeGraphViewer synchViewer = null; + // Synchronize viewer selections if Enabled, + // make sure the selection does not go in loops + if (tsfviewer == rViewer) { + synchViewer = tsfviewer2; + } else { + synchViewer = tsfviewer; + } + long selTimens = event.getBeginTime(); + long tms = (long) (selTimens * 1E-6); + Date date = new Date(tms); + String fDate = stimeformat.format(date); + String ns = formatNs(selTimens); + + System.out.println("TsfTraceAnalysisView.timeSelected() Selected Event: \nTime: " + + event.getBeginTime() + + "\nSelected Time: " + + selTimens + " " + fDate + " " + ns); + + synchViewer.setSelectedTime(event.getBeginTime(), true); + } + + @Override + public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) { + if (event == null) { + return; + } + Object source = event.getSource(); + if (source == null || !(source instanceof TimeGraphViewer)) { + return; + } + + TimeGraphRangeUpdateEvent rEvent = event; + TimeGraphViewer rViewer = (TimeGraphViewer) event + .getSource(); + TimeGraphViewer synchViewer = null; + // Synchronize viewer selections if Enabled, + // make sure the selection does not go in loops + if (tsfviewer == rViewer) { + synchViewer = tsfviewer2; + } else { + synchViewer = tsfviewer; + } + + synchViewer.setSelectVisTimeWindow(rEvent.getStartTime(), rEvent.getEndTime(), source); + } + + /** + * Obtains the remainder fraction on unit Seconds of the entered value in + * nanoseconds. e.g. input: 1241207054171080214 ns The number of seconds can + * be obtain by removing the last 9 digits: 1241207054 the fractional + * portion of seconds, expressed in ns is: 171080214 + * + * @param v + * @return + */ + public String formatNs(long v) { + StringBuffer str = new StringBuffer(); + long val = v; + boolean neg = val < 0; + if (neg) { + val = -val; + str.append('-'); + } + + String strVal = String.valueOf(val); + if (val < 1000000000) { + return strVal; + } + + // Extract the last nine digits (e.g. fraction of a S expressed in ns + return strVal.substring(strVal.length() - 9); + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/.settings/.api_filters b/org.eclipse.tracecompass.tmf.ui/.settings/.api_filters deleted file mode 100644 index ff31090892..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/.settings/.api_filters +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF b/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF index 03a616720f..f4efe752e7 100644 --- a/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF @@ -5,7 +5,7 @@ Bundle-Vendor: %Bundle-Vendor Bundle-Version: 3.2.0.qualifier Bundle-Localization: plugin Bundle-SymbolicName: org.eclipse.tracecompass.tmf.ui;singleton:=true -Bundle-Activator: org.eclipse.linuxtools.internal.tmf.ui.Activator +Bundle-Activator: org.eclipse.tracecompass.internal.tmf.ui.Activator Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Require-Bundle: org.eclipse.core.expressions, @@ -20,67 +20,67 @@ Require-Bundle: org.eclipse.core.expressions, org.swtchart, org.eclipse.cdt.core, com.ibm.icu -Export-Package: org.eclipse.linuxtools.internal.tmf.ui;x-friends:="org.eclipse.tracecompass.tmf.ui.tests,org.eclipse.tracecompass.tmf.ctf.ui.tests", - org.eclipse.linuxtools.internal.tmf.ui.commands;x-internal:=true, - org.eclipse.linuxtools.internal.tmf.ui.dialogs;x-internal:=true, - org.eclipse.linuxtools.internal.tmf.ui.editors.handlers;x-internal:=true, - org.eclipse.linuxtools.internal.tmf.ui.parsers.custom;x-friends:="org.eclipse.tracecompass.tmf.ui.tests", - org.eclipse.linuxtools.internal.tmf.ui.parsers.wizards;x-friends:="org.eclipse.tracecompass.tmf.ui.tests", - org.eclipse.linuxtools.internal.tmf.ui.preferences;x-internal:=true, - org.eclipse.linuxtools.internal.tmf.ui.project.dialogs;x-internal:=true, - org.eclipse.linuxtools.internal.tmf.ui.project.dialogs.offset;x-internal:=true, - org.eclipse.linuxtools.internal.tmf.ui.project.handlers;x-friends:="org.eclipse.tracecompass.tmf.ui.tests", - org.eclipse.linuxtools.internal.tmf.ui.project.model;x-friends:="org.eclipse.tracecompass.lttng2.ui,org.eclipse.tracecompass.tmf.ui.tests,org.eclipse.tracecompass.tmf.ctf.ui.tests", - org.eclipse.linuxtools.internal.tmf.ui.project.operations;x-internal:=true, - org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace;x-friends:="org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests,org.eclipse.tracecompass.tmf.ui,org.eclipse.tracecompass.lttng2.control.ui", - org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg;x-internal:=true, - org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.importexport;x-internal:=true, - org.eclipse.linuxtools.internal.tmf.ui.viewers.events.columns;x-internal:=true, - org.eclipse.linuxtools.tmf.ui, - org.eclipse.linuxtools.tmf.ui.analysis, - org.eclipse.linuxtools.tmf.ui.editors, - org.eclipse.linuxtools.tmf.ui.project.model, - org.eclipse.linuxtools.tmf.ui.project.wizards, - org.eclipse.linuxtools.tmf.ui.properties, - org.eclipse.linuxtools.tmf.ui.viewers, - org.eclipse.linuxtools.tmf.ui.viewers.events, - org.eclipse.linuxtools.tmf.ui.viewers.events.columns, - org.eclipse.linuxtools.tmf.ui.viewers.events.text, - org.eclipse.linuxtools.tmf.ui.viewers.statistics, - org.eclipse.linuxtools.tmf.ui.viewers.statistics.model, - org.eclipse.linuxtools.tmf.ui.viewers.tree, - org.eclipse.linuxtools.tmf.ui.viewers.xycharts, - org.eclipse.linuxtools.tmf.ui.viewers.xycharts.barcharts, - org.eclipse.linuxtools.tmf.ui.viewers.xycharts.linecharts, - org.eclipse.linuxtools.tmf.ui.views, - org.eclipse.linuxtools.tmf.ui.views.callstack, - org.eclipse.linuxtools.tmf.ui.views.colors, - org.eclipse.linuxtools.tmf.ui.views.distribution.model, - org.eclipse.linuxtools.tmf.ui.views.filter, - org.eclipse.linuxtools.tmf.ui.views.histogram, - org.eclipse.linuxtools.tmf.ui.views.statesystem, - org.eclipse.linuxtools.tmf.ui.views.statistics, - org.eclipse.linuxtools.tmf.ui.views.synchronization, - org.eclipse.linuxtools.tmf.ui.views.timechart, - org.eclipse.linuxtools.tmf.ui.views.timegraph, - org.eclipse.linuxtools.tmf.ui.views.uml2sd, - org.eclipse.linuxtools.tmf.ui.views.uml2sd.core, - org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs, - org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings, - org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.impl, - org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers, - org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider, - org.eclipse.linuxtools.tmf.ui.views.uml2sd.load, - org.eclipse.linuxtools.tmf.ui.views.uml2sd.loader, - org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences, - org.eclipse.linuxtools.tmf.ui.views.uml2sd.util, - org.eclipse.linuxtools.tmf.ui.widgets.rawviewer, - org.eclipse.linuxtools.tmf.ui.widgets.tabsview, - org.eclipse.linuxtools.tmf.ui.widgets.timegraph, - org.eclipse.linuxtools.tmf.ui.widgets.timegraph.dialogs, - org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model, - org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets, - org.eclipse.linuxtools.tmf.ui.widgets.virtualtable +Export-Package: org.eclipse.tracecompass.internal.tmf.ui;x-friends:="org.eclipse.tracecompass.tmf.ui.tests,org.eclipse.tracecompass.tmf.ctf.ui.tests", + org.eclipse.tracecompass.internal.tmf.ui.commands;x-internal:=true, + org.eclipse.tracecompass.internal.tmf.ui.dialogs;x-internal:=true, + org.eclipse.tracecompass.internal.tmf.ui.editors.handlers;x-internal:=true, + org.eclipse.tracecompass.internal.tmf.ui.parsers.custom;x-friends:="org.eclipse.tracecompass.tmf.ui.tests", + org.eclipse.tracecompass.internal.tmf.ui.parsers.wizards;x-friends:="org.eclipse.tracecompass.tmf.ui.tests", + org.eclipse.tracecompass.internal.tmf.ui.preferences;x-internal:=true, + org.eclipse.tracecompass.internal.tmf.ui.project.dialogs;x-internal:=true, + org.eclipse.tracecompass.internal.tmf.ui.project.dialogs.offset;x-internal:=true, + org.eclipse.tracecompass.internal.tmf.ui.project.handlers;x-friends:="org.eclipse.tracecompass.tmf.ui.tests", + org.eclipse.tracecompass.internal.tmf.ui.project.model;x-friends:="org.eclipse.tracecompass.lttng2.ui,org.eclipse.tracecompass.tmf.ui.tests,org.eclipse.tracecompass.tmf.ctf.ui.tests", + org.eclipse.tracecompass.internal.tmf.ui.project.operations;x-internal:=true, + org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace;x-friends:="org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests,org.eclipse.tracecompass.tmf.ui,org.eclipse.tracecompass.lttng2.control.ui", + org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg;x-internal:=true, + org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport;x-internal:=true, + org.eclipse.tracecompass.internal.tmf.ui.viewers.events.columns;x-internal:=true, + org.eclipse.tracecompass.tmf.ui, + org.eclipse.tracecompass.tmf.ui.analysis, + org.eclipse.tracecompass.tmf.ui.editors, + org.eclipse.tracecompass.tmf.ui.project.model, + org.eclipse.tracecompass.tmf.ui.project.wizards, + org.eclipse.tracecompass.tmf.ui.properties, + org.eclipse.tracecompass.tmf.ui.viewers, + org.eclipse.tracecompass.tmf.ui.viewers.events, + org.eclipse.tracecompass.tmf.ui.viewers.events.columns, + org.eclipse.tracecompass.tmf.ui.viewers.events.text, + org.eclipse.tracecompass.tmf.ui.viewers.statistics, + org.eclipse.tracecompass.tmf.ui.viewers.statistics.model, + org.eclipse.tracecompass.tmf.ui.viewers.tree, + org.eclipse.tracecompass.tmf.ui.viewers.xycharts, + org.eclipse.tracecompass.tmf.ui.viewers.xycharts.barcharts, + org.eclipse.tracecompass.tmf.ui.viewers.xycharts.linecharts, + org.eclipse.tracecompass.tmf.ui.views, + org.eclipse.tracecompass.tmf.ui.views.callstack, + org.eclipse.tracecompass.tmf.ui.views.colors, + org.eclipse.tracecompass.tmf.ui.views.distribution.model, + org.eclipse.tracecompass.tmf.ui.views.filter, + org.eclipse.tracecompass.tmf.ui.views.histogram, + org.eclipse.tracecompass.tmf.ui.views.statesystem, + org.eclipse.tracecompass.tmf.ui.views.statistics, + org.eclipse.tracecompass.tmf.ui.views.synchronization, + org.eclipse.tracecompass.tmf.ui.views.timechart, + org.eclipse.tracecompass.tmf.ui.views.timegraph, + org.eclipse.tracecompass.tmf.ui.views.uml2sd, + org.eclipse.tracecompass.tmf.ui.views.uml2sd.core, + org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs, + org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings, + org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.impl, + org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers, + org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider, + org.eclipse.tracecompass.tmf.ui.views.uml2sd.load, + org.eclipse.tracecompass.tmf.ui.views.uml2sd.loader, + org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences, + org.eclipse.tracecompass.tmf.ui.views.uml2sd.util, + org.eclipse.tracecompass.tmf.ui.widgets.rawviewer, + org.eclipse.tracecompass.tmf.ui.widgets.tabsview, + org.eclipse.tracecompass.tmf.ui.widgets.timegraph, + org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs, + org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model, + org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets, + org.eclipse.tracecompass.tmf.ui.widgets.virtualtable Import-Package: com.google.common.base, com.google.common.collect, org.eclipse.emf.common.util, diff --git a/org.eclipse.tracecompass.tmf.ui/plugin.xml b/org.eclipse.tracecompass.tmf.ui/plugin.xml index e3ccaf0129..39ff812e70 100644 --- a/org.eclipse.tracecompass.tmf.ui/plugin.xml +++ b/org.eclipse.tracecompass.tmf.ui/plugin.xml @@ -7,7 +7,7 @@ @@ -21,7 +21,7 @@ @@ -152,14 +152,14 @@ @@ -170,7 +170,7 @@ point="org.eclipse.core.resources.natures"> + class="org.eclipse.tracecompass.tmf.core.TmfProjectNature"> @@ -186,10 +186,10 @@ point="org.eclipse.ui.navigator.navigatorContent"> @@ -204,14 +204,14 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.ITmfProjectModelElement"> + value="org.eclipse.tracecompass.tmf.ui.project.model.ITmfProjectModelElement"> @@ -222,18 +222,18 @@ suppressedExtensionId="org.eclipse.ui.navigator.resourceContent"> + value="org.eclipse.tracecompass.tmf.ui.project.model.ITmfProjectModelElement"> @@ -247,7 +247,7 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.ITmfProjectModelElement"> @@ -265,7 +265,7 @@ @@ -298,7 +298,7 @@ state="true"> + name="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder"> @@ -311,7 +311,7 @@ state="true"> + name="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder"> @@ -325,7 +325,7 @@ + name="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder"> @@ -379,13 +379,13 @@ operator="and"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfAnalysisOutputElement"> @@ -414,7 +414,7 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder"> @@ -443,7 +443,7 @@ operator="or"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder"> @@ -480,19 +480,19 @@ operator="and"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTracesFolder"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder"> @@ -517,7 +517,7 @@ ifEmpty="false" operator="and"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTracesFolder"> @@ -572,7 +572,7 @@ ifEmpty="false" operator="and"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTracesFolder"> @@ -594,7 +594,7 @@ operator="and"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder"> @@ -650,10 +650,10 @@ operator="and"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement"> @@ -687,7 +687,7 @@ ifEmpty="false" operator="and"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder"> @@ -714,7 +714,7 @@ ifEmpty="false" operator="and"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement"> @@ -724,7 +724,7 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder"> @@ -751,7 +751,7 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder"> @@ -762,7 +762,7 @@ mnemonic="%command.select_trace_type.mnemonic" tooltip="%command.select_trace_type.description"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement"> @@ -793,7 +793,7 @@ mnemonic="%command.select_experiment_type.mnemonic" tooltip="%command.select_experiment_type.description"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement"> @@ -832,7 +832,7 @@ ifEmpty="false" operator="and"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement"> @@ -856,7 +856,7 @@ ifEmpty="false" operator="and"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement"> @@ -901,13 +901,13 @@ operator="and"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement"> @@ -932,7 +932,7 @@ ifEmpty="false" operator="and"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfAnalysisElement"> @@ -1148,7 +1148,7 @@ @@ -1169,11 +1169,11 @@ @@ -1185,13 +1185,13 @@ operator="and"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement"> @@ -1199,7 +1199,7 @@ @@ -1209,14 +1209,14 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement"> @@ -1226,14 +1226,14 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement"> @@ -1243,14 +1243,14 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfAnalysisElement"> @@ -1260,14 +1260,14 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfAnalysisOutputElement"> @@ -1283,7 +1283,7 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement"> @@ -1312,14 +1312,14 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement"> @@ -1329,14 +1329,14 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement"> @@ -1346,14 +1346,14 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement"> @@ -1365,11 +1365,11 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTracesFolder"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder"> @@ -1377,20 +1377,20 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder"> @@ -1419,22 +1419,22 @@ ifEmpty="false" operator="or"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder"> @@ -1444,14 +1444,14 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder"> @@ -1461,14 +1461,14 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement"> @@ -1496,14 +1496,14 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement"> @@ -1513,25 +1513,25 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement"> + value="org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor"> + value="org.eclipse.tracecompass.tmf.core.event.ITmfEvent"> + value="org.eclipse.tracecompass.tmf.ui.views.filter.FilterView"> + value="org.eclipse.tracecompass.tmf.ui.views.filter.FilterView"> + value="org.eclipse.tracecompass.tmf.ui.views.filter.FilterView"> + value="org.eclipse.tracecompass.tmf.ui.views.filter.FilterView"> @@ -1730,7 +1730,7 @@ + type="org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectModelElement"> @@ -1768,10 +1768,10 @@ + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement"> + value="org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement"> @@ -1781,7 +1781,7 @@ point="org.eclipse.ui.exportWizards"> @@ -1794,7 +1794,7 @@ diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/Activator.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/Activator.java deleted file mode 100644 index 4e843c879e..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/Activator.java +++ /dev/null @@ -1,245 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.preferences.InstanceScope; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.resource.ImageRegistry; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.ui.TmfUiRefreshHandler; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.viewers.events.TmfEventAdapterFactory; -import org.eclipse.swt.graphics.Image; -import org.eclipse.ui.plugin.AbstractUIPlugin; -import org.eclipse.ui.preferences.ScopedPreferenceStore; -import org.osgi.framework.BundleContext; - -/** - * The activator class controls the plug-in life cycle. - */ -public class Activator extends AbstractUIPlugin { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The plug-in ID - */ - public static final String PLUGIN_ID = "org.eclipse.tracecompass.tmf.ui"; //$NON-NLS-1$ - /** - * The core plug-in ID - */ - public static final String PLUGIN_CORE_ID = "org.eclipse.tracecompass.tmf.core"; //$NON-NLS-1$ - - /** - * The shared instance - */ - private static Activator plugin; - - private TmfEventAdapterFactory fTmfEventAdapterFactory; - private IPreferenceStore fCorePreferenceStore; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructor - */ - public Activator() { - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Returns the TMF UI plug-in instance. - * - * @return the TMF UI plug-in instance. - */ - public static Activator getDefault() { - return plugin; - } - - // ------------------------------------------------------------------------ - // AbstractUIPlugin - // ------------------------------------------------------------------------ - - @Override - public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - TmfUiRefreshHandler.getInstance(); // to classload/initialize it - TmfUiTracer.init(); - TmfTraceElement.init(); - TmfExperimentElement.init(); - - fTmfEventAdapterFactory = new TmfEventAdapterFactory(); - Platform.getAdapterManager().registerAdapters(fTmfEventAdapterFactory, ITmfEvent.class); - } - - @Override - public void stop(BundleContext context) throws Exception { - TmfUiTracer.stop(); - TmfUiRefreshHandler.getInstance().dispose(); - plugin = null; - - Platform.getAdapterManager().unregisterAdapters(fTmfEventAdapterFactory); - super.stop(context); - } - - /** - * Returns a preference store for org.eclipse.linux.tmf.core preferences - * @return the preference store - */ - public IPreferenceStore getCorePreferenceStore() { - if (fCorePreferenceStore == null) { - fCorePreferenceStore= new ScopedPreferenceStore(InstanceScope.INSTANCE, PLUGIN_CORE_ID); - } - return fCorePreferenceStore; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Gets an image object using given path within plug-in. - * - * @param path - * path to image file - * - * @return image object - */ - public Image getImageFromPath(String path) { - return getImageDescripterFromPath(path).createImage(); - } - - /** - * Gets an image descriptor using given path within plug-in. - * - * @param path - * path to image file - * - * @return image descriptor object - */ - public ImageDescriptor getImageDescripterFromPath(String path) { - return AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, path); - } - - /** - * Gets a image object from the image registry based on the given path. If - * the image is not in the registry it will be registered. - * - * @param path - * to the image file - * @return image object - */ - public Image getImageFromImageRegistry(String path) { - Image icon = getImageRegistry().get(path); - if (icon == null) { - icon = getImageDescripterFromPath(path).createImage(); - plugin.getImageRegistry().put(path, icon); - } - return icon; - } - - @Override - protected void initializeImageRegistry(ImageRegistry reg) { - reg.put(ITmfImageConstants.IMG_UI_ZOOM, getImageFromPath(ITmfImageConstants.IMG_UI_ZOOM)); - reg.put(ITmfImageConstants.IMG_UI_ZOOM_IN, getImageFromPath(ITmfImageConstants.IMG_UI_ZOOM_IN)); - reg.put(ITmfImageConstants.IMG_UI_ZOOM_OUT, getImageFromPath(ITmfImageConstants.IMG_UI_ZOOM_OUT)); - reg.put(ITmfImageConstants.IMG_UI_SEQ_DIAGRAM_OBJ, getImageFromPath(ITmfImageConstants.IMG_UI_SEQ_DIAGRAM_OBJ)); - reg.put(ITmfImageConstants.IMG_UI_ARROW_COLLAPSE_OBJ, getImageFromPath(ITmfImageConstants.IMG_UI_ARROW_COLLAPSE_OBJ)); - reg.put(ITmfImageConstants.IMG_UI_ARROW_UP_OBJ, getImageFromPath(ITmfImageConstants.IMG_UI_ARROW_UP_OBJ)); - reg.put(ITmfImageConstants.IMG_UI_CONFLICT, getImageFromPath(ITmfImageConstants.IMG_UI_CONFLICT)); - } - - /** - * Logs a message with severity INFO in the runtime log of the plug-in. - * - * @param message - * A message to log - */ - public void logInfo(String message) { - getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity INFO in the runtime log of the - * plug-in. - * - * @param message - * A message to log - * @param exception - * A exception to log - */ - public void logInfo(String message, Throwable exception) { - getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message, exception)); - } - - /** - * Logs a message and exception with severity WARNING in the runtime log of - * the plug-in. - * - * @param message - * A message to log - */ - public void logWarning(String message) { - getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity WARNING in the runtime log of - * the plug-in. - * - * @param message - * A message to log - * @param exception - * A exception to log - */ - public void logWarning(String message, Throwable exception) { - getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message, exception)); - } - - /** - * Logs a message and exception with severity ERROR in the runtime log of - * the plug-in. - * - * @param message - * A message to log - */ - public void logError(String message) { - getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message)); - } - - /** - * Logs a message and exception with severity ERROR in the runtime log of - * the plug-in. - * - * @param message - * A message to log - * @param exception - * A exception to log - */ - public void logError(String message, Throwable exception) { - getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, exception)); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/ITmfImageConstants.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/ITmfImageConstants.java deleted file mode 100755 index 9d21ec9b7b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/ITmfImageConstants.java +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - initial API and implementation - * Patrick Tasse - added icons - *******************************************************************************/ -package org.eclipse.linuxtools.internal.tmf.ui; - -/** - * Names for generic icons and buttons used in TMF - */ -@SuppressWarnings({"nls", "javadoc"}) -public interface ITmfImageConstants { - - public static final String ICONS_PATH = "icons/"; //$NON-NLS-1$ - - /* elcl16 */ - public static final String IMG_UI_HOME_MENU = ICONS_PATH + "elcl16/home_nav.gif"; - public static final String IMG_UI_SELECT_MENU = ICONS_PATH + "elcl16/select_menu.gif"; - public static final String IMG_UI_ZOOM_IN_MENU = ICONS_PATH + "elcl16/zoomin_nav.gif"; - public static final String IMG_UI_ZOOM_OUT_MENU = ICONS_PATH + "elcl16/zoomout_nav.gif"; - public static final String IMG_UI_FILTERS = ICONS_PATH + "elcl16/filter_items.gif"; - public static final String IMG_UI_SEARCH_SEQ = ICONS_PATH + "elcl16/search_seqdiag_menu.gif"; - public static final String IMG_UI_NEXT_PAGE = ICONS_PATH + "elcl16/next_menu.gif"; - public static final String IMG_UI_PREV_PAGE = ICONS_PATH + "elcl16/prev_menu.gif"; - public static final String IMG_UI_GOTO_PAGE = ICONS_PATH + "elcl16/gotopage_menu.gif"; - public static final String IMG_UI_NODE_START = ICONS_PATH + "elcl16/node_end.gif"; - public static final String IMG_UI_NODE_END = ICONS_PATH + "elcl16/node_start.gif"; - public static final String IMG_UI_SEARCH_MATCH = ICONS_PATH + "elcl16/search_match.gif"; - public static final String IMG_UI_FIRST_PAGE = ICONS_PATH + "elcl16/backward_nav.gif"; - public static final String IMG_UI_LAST_PAGE = ICONS_PATH + "elcl16/forward_nav.gif"; - public static final String IMG_UI_SHOW_LEGEND = ICONS_PATH + "elcl16/show_legend.gif"; - public static final String IMG_UI_NEXT_EVENT = ICONS_PATH + "elcl16/next_event.gif"; - public static final String IMG_UI_PREV_EVENT = ICONS_PATH + "elcl16/prev_event.gif"; -// public static final String IMG_UI_NEXT_ITEM = ICONS_PATH + "elcl16/next_item.gif"; -// public static final String IMG_UI_PREV_ITEM = ICONS_PATH + "elcl16/prev_item.gif"; - public static final String IMG_UI_NEXT_ITEM = IMG_UI_NEXT_PAGE; - public static final String IMG_UI_PREV_ITEM = IMG_UI_PREV_PAGE; - public static final String IMG_UI_PIN_VIEW = ICONS_PATH + "elcl16/pin_view.gif"; - public static final String IMG_UI_HIDE_ARROWS = ICONS_PATH + "elcl16/hide_arrows.gif"; - public static final String IMG_UI_FOLLOW_ARROW_FORWARD = ICONS_PATH + "elcl16/follow_arrow_fwd.gif"; - public static final String IMG_UI_FOLLOW_ARROW_BACKWARD = ICONS_PATH + "elcl16/follow_arrow_bwd.gif"; - public static final String IMG_UI_SHOW_LOST_EVENTS = ICONS_PATH + "elcl16/hide_lost_events.gif"; - public static final String IMG_UI_SHOW_HIST_TRACES = ICONS_PATH + "elcl16/show_hist_traces.gif"; - - /* eview16 */ - public static final String IMG_UI_SEQ_DIAGRAM_OBJ = ICONS_PATH + "eview16/sequencediagram_view.gif"; - - /* obj16 */ - public static final String IMG_UI_ZOOM = ICONS_PATH + "obj16/zoom_mask.bmp"; - public static final String IMG_UI_ZOOM_IN = ICONS_PATH + "obj16/zoomin_obj.bmp"; - public static final String IMG_UI_ZOOM_OUT = ICONS_PATH + "obj16/zoomout_obj.bmp"; - public static final String IMG_UI_ARROW_COLLAPSE_OBJ = ICONS_PATH + "obj16/arrow_colapse.bmp"; - public static final String IMG_UI_ARROW_UP_OBJ = ICONS_PATH + "obj16/arrow_up.bmp"; - - /* wizban */ - public static final String IMG_UI_CONFLICT = ICONS_PATH + "wizban/conflict_stat.gif"; -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/Messages.java deleted file mode 100644 index e82aaa8502..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/Messages.java +++ /dev/null @@ -1,306 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui; - -import org.eclipse.osgi.util.NLS; - -/** - * TMF message bundle - */ -@SuppressWarnings("javadoc") -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.tmf.ui.messages"; //$NON-NLS-1$ - - public static String ManageCustomParsersDialog_ConflictMessage; - public static String ManageCustomParsersDialog_ConflictRenameButtonLabel; - public static String ManageCustomParsersDialog_ConflictSkipButtonLabel; - public static String ManageCustomParsersDialog_DeleteButtonLabel; - public static String ManageCustomParsersDialog_DeleteConfirmation; - public static String ManageCustomParsersDialog_DeleteParserDialogHeader; - public static String ManageCustomParsersDialog_DialogHeader; - public static String ManageCustomParsersDialog_EditButtonLabel; - public static String ManageCustomParsersDialog_ExportButtonLabel; - public static String ManageCustomParsersDialog_ExportParserSelection; - public static String ManageCustomParsersDialog_ImportButtonLabel; - public static String ManageCustomParsersDialog_ImportParserSelection; - public static String ManageCustomParsersDialog_NewButtonLabel; - public static String ManageCustomParsersDialog_TextButtonLabel; - - public static String TmfEventsTable_AddBookmarkActionText; - public static String TmfEventsTable_AddBookmarkDialogMessage; - public static String TmfEventsTable_AddBookmarkDialogTitle; - public static String TmfEventsTable_ApplyPresetFilterMenuName; - public static String TmfEventsTable_ClearFiltersActionText; - public static String TmfEventsTable_CollapseFilterMenuName; - public static String TmfEventsTable_ContentColumnHeader; - public static String TmfEventsTable_Export_to_text; - public static String TmfEventsTable_FilterHint; - public static String TmfEventsTable_HideRawActionText; - public static String TmfEventsTable_HideTableActionText; - public static String TmfEventsTable_MultipleBookmarksToolTip; - public static String TmfEventsTable_OpenSourceCodeActionText; - public static String TmfEventsTable_OpenSourceCodeNotFound; - public static String TmfEventsTable_OpenSourceCodeSelectFileDialogTitle; - public static String TmfEventsTable_OpenModelActionText; - public static String TmfEventsTable_OpenModelUnsupportedURI; - public static String TmfEventsTable_ReferenceColumnHeader; - public static String TmfEventsTable_RemoveBookmarkActionText; - public static String TmfEventsTable_SearchHint; - public static String TmfEventsTable_SearchingJobName; - public static String TmfEventsTable_ShowFilterBarActionText; - public static String TmfEventsTable_ShowRawActionText; - public static String TmfEventsTable_ShowSearchBarActionText; - public static String TmfEventsTable_ShowTableActionText; - public static String TmfEventsTable_SourceColumnHeader; - public static String TmfEventsTable_TimestampColumnHeader; - public static String TmfEventsTable_TypeColumnHeader; - - public static String TmfTimeFilterDialog_EDIT_PROFILING_OPTIONS; - public static String TmfTimeFilterDialog_TRACE_FILTER; - public static String TmfTimeFilterDialog_TRACE_FILTER_DESC; - public static String TmfTimeFilterDialog_TRACE_ID; - public static String TmfTimeFilterDialog_TRACE_NAME; - public static String TmfTimeLegend_LEGEND; - public static String TmfTimeLegend_TRACE_STATES; - public static String TmfTimeLegend_TRACE_STATES_TITLE; - public static String TmfTimeLegend_WINDOW_TITLE; - public static String TmfTimeLegend_StateTypeName; - public static String TmfTimeFilterDialog_WINDOW_TITLE; - public static String TmfTimeFilterDialog_MESSAGE; - public static String TmfTimeFilterDialog_CHECK_ALL; - public static String TmfTimeFilterDialog_UNCHECK_ALL; - public static String TmfTimeFilterDialog_CHECK_SELECTED; - public static String TmfTimeFilterDialog_UNCHECK_SELECTED; - public static String TmfTimeFilterDialog_CHECK_SUBTREE; - public static String TmfTimeFilterDialog_UNCHECK_SUBTREE; - - public static String TmfTimeTipHandler_DURATION; - public static String TmfTimeTipHandler_LINK_SOURCE; - public static String TmfTimeTipHandler_LINK_SOURCE_TIME; - public static String TmfTimeTipHandler_LINK_TARGET; - public static String TmfTimeTipHandler_LINK_TARGET_TIME; - public static String TmfTimeTipHandler_LINK_TIME; - public static String TmfTimeTipHandler_TRACE_DATE; - public static String TmfTimeTipHandler_TRACE_EVENT_TIME; - public static String TmfTimeTipHandler_TRACE_START_TIME; - public static String TmfTimeTipHandler_TRACE_STATE; - public static String TmfTimeTipHandler_TRACE_STOP_TIME; - - public static String TmfTimeGraphCombo_FilterActionNameText; - public static String TmfTimeGraphCombo_FilterActionToolTipText; - - public static String TmfTimeGraphViewer_ResetScaleActionNameText; - public static String TmfTimeGraphViewer_ResetScaleActionToolTipText; - public static String TmfTimeGraphViewer_LegendActionNameText; - public static String TmfTimeGraphViewer_LegendActionToolTipText; - public static String TmfTimeGraphViewer_NextEventActionNameText; - public static String TmfTimeGraphViewer_NextEventActionToolTipText; - public static String TmfTimeGraphViewer_PreviousEventActionNameText; - public static String TmfTimeGraphViewer_PreviousEventActionToolTipText; - public static String TmfTimeGraphViewer_NextItemActionNameText; - public static String TmfTimeGraphViewer_NextItemActionToolTipText; - public static String TmfTimeGraphViewer_PreviousItemActionNameText; - public static String TmfTimeGraphViewer_PreviousItemActionToolTipText; - public static String TmfTimeGraphViewer_ZoomInActionNameText; - public static String TmfTimeGraphViewer_ZoomInActionToolTipText; - public static String TmfTimeGraphViewer_ZoomOutActionNameText; - public static String TmfTimeGraphViewer_ZoomOutActionToolTipText; - public static String TmfTimeGraphViewer_HideArrowsActionNameText; - public static String TmfTimeGraphViewer_HideArrowsActionToolTipText; - public static String TmfTimeGraphViewer_FollowArrowForwardActionNameText; - public static String TmfTimeGraphViewer_FollowArrowForwardActionToolTipText; - public static String TmfTimeGraphViewer_FollowArrowBackwardActionNameText; - public static String TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText; - - public static String Utils_ClockCyclesUnit; - - public static String ColorsView_AddActionToolTipText; - public static String ColorsView_BackgroundButtonText; - public static String ColorsView_BackgroundDialogText; - public static String ColorsView_DeleteActionToolTipText; - public static String ColorsView_ExportActionToolTipText; - public static String ColorsView_FilterButtonText; - public static String ColorsView_ForegroundButtonText; - public static String ColorsView_ForegroundDialogText; - public static String ColorsView_ImportActionToolTipText; - public static String ColorsView_ImportOverwriteDialogMessage1; - public static String ColorsView_ImportOverwriteDialogMessage2; - public static String ColorsView_ImportOverwriteDialogTitle; - public static String ColorsView_MoveDownActionToolTipText; - public static String ColorsView_MoveUpActionToolTipText; - public static String ColorsView_TickButtonText; - public static String TickColorDialog_TickColorDialogTitle; - - public static String CustomTxtParserInputWizardPage_addChildLine; - public static String CustomTxtParserInputWizardPage_addGroup; - public static String CustomTxtParserInputWizardPage_addNextLine; - public static String CustomTxtParserInputWizardPage_append; - public static String CustomTxtParserInputWizardPage_appendWith; - public static String CustomTxtParserInputWizardPage_capturedGroup; - public static String CustomTxtParserInputWizardPage_cardinality; - public static String CustomTxtParserInputWizardPage_category; - public static String CustomTxtParserInputWizardPage_desccriptionEdit; - public static String CustomTxtParserInputWizardPage_descriptionNew; - public static String CustomTxtParserInputWizardPage_format; - public static String CustomTxtParserInputWizardPage_group; - public static String CustomTxtParserInputWizardPage_highlightAll; - public static String CustomTxtParserInputWizardPage_logType; - public static String CustomTxtParserInputWizardPage_matchingOtherLine; - public static String CustomTxtParserInputWizardPage_matchingRootLine; - public static String CustomTxtParserInputWizardPage_max; - public static String CustomTxtParserInputWizardPage_min; - public static String CustomTxtParserInputWizardPage_moveDown; - public static String CustomTxtParserInputWizardPage_moveUp; - public static String CustomTxtParserInputWizardPage_name; - public static String CustomTxtParserInputWizardPage_newGroup; - public static String CustomTxtParserInputWizardPage_noMatch; - public static String CustomTxtParserInputWizardPage_noMatchingGroup; - public static String CustomTxtParserInputWizardPage_noMatchingLine; - public static String CustomTxtParserInputWizardPage_noMatchingTimestamp; - public static String CustomTxtParserInputWizardPage_noMathcingLine; - public static String CustomTxtParserInputWizardPage_nonMatchingLine; - public static String CustomTxtParserInputWizardPage_noTimestampGroup; - public static String CustomTxtParserInputWizardPage_preview; - public static String CustomTxtParserInputWizardPage_previewInput; - public static String CustomTxtParserInputWizardPage_previewLegend; - public static String CustomTxtParserInputWizardPage_regularExpression; - public static String CustomTxtParserInputWizardPage_regularExpressionHelp; - public static String CustomTxtParserInputWizardPage_removeGroup; - public static String CustomTxtParserInputWizardPage_removeLine; - public static String CustomTxtParserInputWizardPage_set; - public static String CustomTxtParserInputWizardPage_timestampFormat; - public static String CustomTxtParserInputWizardPage_timestampFormatHelp; - public static String CustomTxtParserInputWizardPage_uncapturedText; - public static String CustomTxtParserInputWizardPage_unidentifiedCaptureGroup; - public static String CustomTxtParserInputWizardPage_windowTitleEdit; - public static String CustomTxtParserInputWizardPage_windowTitleNew; - public static String CustomTxtParserOutputWizardPage_description; - public static String CustomTxtParserOutputWizardPage_moveAfter; - public static String CustomTxtParserOutputWizardPage_moveBefore; - public static String CustomTxtParserOutputWizardPage_visible; - public static String CustomXmlParserInputWizardPage_emptyCategoryError; - public static String CustomXmlParserInputWizardPage_emptyLogTypeError; - public static String CustomXmlParserInputWizardPage_invalidCategoryError; - public static String CustomXmlParserInputWizardPage_invalidLogTypeError; - public static String CustomXmlParserInputWizardPage_duplicatelogTypeError; - public static String CustomXmlParserInputWizardPage_noDocumentError; - public static String CustomXmlParserInputWizardPage_missingLogEntryError; - public static String CustomXmlParserInputWizardPage_missingTimestampFmtError; - public static String CustomXmlParserInputWizardPage_missingDocumentElementError; - public static String CustomXmlParserInputWizardPage_noTimestampElementOrAttribute; - public static String CustomXmlParserInputWizardPage_elementMissingNameError; - public static String CustomXmlParserInputWizardPage_elementMissingInputNameError; - public static String CustomXmlParserInputWizardPage_elementMissingTimestampFmtError; - public static String CustomXmlParserInputWizardPage_elementInvalidTimestampFmtError; - public static String CustomXmlParserInputWizardPage_elementDuplicateNameError; - public static String CustomXmlParserInputWizardPage_attributeMissingNameError; - public static String CustomXmlParserInputWizardPage_attributeMissingInputNameError; - public static String CustomXmlParserInputWizardPage_attributeMissingTimestampFmtError; - public static String CustomXmlParserInputWizardPage_attributeInvalidTimestampFmtError; - public static String CustomXmlParserInputWizardPage_attributeDuplicateNameError; - public static String CustomXmlParserInputWizardPage_addAttribute; - public static String CustomXmlParserInputWizardPage_addChildElement; - public static String CustomXmlParserInputWizardPage_addDocumentEleemnt; - public static String CustomXmlParserInputWizardPage_addDocumentElement; - public static String CustomXmlParserInputWizardPage_addNextElement; - public static String CustomXmlParserInputWizardPage_append; - public static String CustomXmlParserInputWizardPage_appendWith; - public static String CustomXmlParserInputWizardPage_attibute; - public static String CustomXmlParserInputWizardPage_category; - public static String CustomXmlParserInputWizardPage_descriptionEdit; - public static String CustomXmlParserInputWizardPage_descriptionNew; - public static String CustomXmlParserInputWizardPage_elementName; - public static String CustomXmlParserInputWizardPage_feelingLucky; - public static String CustomXmlParserInputWizardPage_format; - public static String CustomXmlParserInputWizardPage_logEntry; - public static String CustomXmlParserInputWizardPage_logType; - public static String CustomXmlParserInputWizardPage_moveDown; - public static String CustomXmlParserInputWizardPage_moveUp; - public static String CustomXmlParserInputWizardPage_name; - public static String CustomXmlParserInputWizardPage_newAttibute; - public static String CustomXmlParserInputWizardPage_noMatchingAttribute; - public static String CustomXmlParserInputWizardPage_noMatch; - public static String CustomXmlParserInputWizardPage_noMatchingElement; - public static String CustomXmlParserInputWizardPage_preview; - public static String CustomXmlParserInputWizardPage_previewInput; - public static String CustomXmlParserInputWizardPage_removeAttribute; - public static String CustomXmlParserInputWizardPage_removeElement; - public static String CustomXmlParserInputWizardPage_set; - public static String CustomXmlParserInputWizardPage_tagName; - public static String CustomXmlParserInputWizardPage_timestampFormat; - public static String CustomXmlParserInputWizardPage_timestampFormatHelp; - public static String CustomXmlParserInputWizardPage_titleEdit; - public static String CustomXmlParserInputWizardPage_titleNew; - public static String CustomXmlParserOutputWizardPage_description; - public static String CustomXmlParserOutputWizardPage_moveAfter; - public static String CustomXmlParserOutputWizardPage_moveBefore; - public static String CustomXmlParserOutputWizardPage_visible; - - public static String FilterDialog_FilterDialogTitle; - public static String FilterView_AddActionToolTipText; - public static String FilterView_DeleteActionToolTipText; - public static String FilterView_ExportActionToolTipText; - public static String FilterView_FileDialogFilterName; - public static String FilterView_ImportActionToolTipText; - public static String FilterView_SaveActionToolTipText; - public static String FilterViewer_EmptyTreeHintText; - public static String FilterViewer_CommonCategory; - public static String FilterViewer_AlphaButtonText; - public static String FilterViewer_FieldLabel; - public static String FilterViewer_FilterNameHint; - public static String FilterViewer_IgnoreCaseButtonText; - public static String FilterViewer_NameLabel; - public static String FilterViewer_NewPrefix; - public static String FilterViewer_NotLabel; - public static String FilterViewer_NumButtonText; - public static String FilterViewer_RegexHint; - public static String FilterViewer_RegexLabel; - public static String FilterViewer_ResultLabel; - public static String FilterViewer_Subfilter_ToolTip; - public static String FilterViewer_TimestampButtonText; - public static String FilterViewer_TypeLabel; - public static String FilterViewer_ValueHint; - public static String FilterViewer_ValueLabel; - - public static String TmfView_PinActionNameText; - public static String TmfView_PinActionToolTipText; - - public static String CallStackPresentationProvider_Thread; - public static String CallStackView_FunctionColumn; - public static String CallStackView_DepthColumn; - public static String CallStackView_EntryTimeColumn; - public static String CallStackView_ExitTimeColumn; - public static String CallStackView_DurationColumn; - public static String CallStackView_StackInfoNotAvailable; - public static String CallStackView_SortByThreadName; - public static String CallStackView_SortByThreadId; - public static String CallStackView_SortByThreadTime; - public static String CallStackView_ImportMappingButtonText; - public static String CallStackView_ImportMappingButtonTooltip; - public static String CallStackView_ImportMappingDialogTitle; - public static String CallStackView_ImportMappingJobName; - - public static String CallStackView_ImportBinaryFileButtonText; - public static String CallStackView_ImportBinaryFileButtonTooltip; - public static String CallStackView_ImportBinaryFileDialogTitle; - - public static String ExportToTextJob_Export_to; - public static String ExportToTextJob_Export_trace_to; - public static String ExportToTextJob_Unable_to_export_trace; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/TmfUiTracer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/TmfUiTracer.java deleted file mode 100644 index 24f4ed97fc..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/TmfUiTracer.java +++ /dev/null @@ -1,245 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui; - -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; - -import org.eclipse.core.runtime.Platform; - -/** - * Tracer class for the tmf.ui plugin - */ -@SuppressWarnings("nls") -public class TmfUiTracer { - - private static String pluginID = Activator.PLUGIN_ID; - - static boolean ERROR = false; - static boolean WARNING = false; - static boolean INFO = false; - - static boolean INDEX = false; - static boolean DISPLAY = false; - static boolean SORTING = false; - - private static String LOGNAME = "traceUI.log"; - private static BufferedWriter fTraceLog = null; - - private static BufferedWriter openLogFile(String filename) { - BufferedWriter outfile = null; - try { - outfile = new BufferedWriter(new FileWriter(filename)); - } catch (IOException e) { - Activator.getDefault().logError("Error creating log file " + LOGNAME, e); //$NON-NLS-1$ - } - return outfile; - } - - /** - * Initialize tracing - */ - public static void init() { - - String traceKey; - boolean isTracing = false; - - traceKey = Platform.getDebugOption(pluginID + "/error"); - if (traceKey != null) { - ERROR = (Boolean.valueOf(traceKey)).booleanValue(); - isTracing |= ERROR; - } - - traceKey = Platform.getDebugOption(pluginID + "/warning"); - if (traceKey != null) { - WARNING = (Boolean.valueOf(traceKey)).booleanValue(); - isTracing |= WARNING; - } - - traceKey = Platform.getDebugOption(pluginID + "/info"); - if (traceKey != null) { - INFO = (Boolean.valueOf(traceKey)).booleanValue(); - isTracing |= INFO; - } - - traceKey = Platform.getDebugOption(pluginID + "/updateindex"); - if (traceKey != null) { - INDEX = (Boolean.valueOf(traceKey)).booleanValue(); - isTracing |= INDEX; - } - - traceKey = Platform.getDebugOption(pluginID + "/display"); - if (traceKey != null) { - DISPLAY = (Boolean.valueOf(traceKey)).booleanValue(); - isTracing |= DISPLAY; - } - - traceKey = Platform.getDebugOption(pluginID + "/sorting"); - if (traceKey != null) { - SORTING = (Boolean.valueOf(traceKey)).booleanValue(); - isTracing |= SORTING; - } - - // Create trace log file if needed - if (isTracing) { - fTraceLog = openLogFile(LOGNAME); - } - } - - /** - * Stop tracing - */ - public static void stop() { - if (fTraceLog == null) { - return; - } - - try { - fTraceLog.close(); - fTraceLog = null; - } catch (IOException e) { - Activator.getDefault().logError("Error closing log file " + LOGNAME, e); //$NON-NLS-1$ - } - } - - // ------------------------------------------------------------------------ - // Predicates - // ------------------------------------------------------------------------ - - /** - * @return If ERROR messages are traced - */ - public static boolean isErrorTraced() { - return ERROR; - } - - /** - * @return If INDEX messages are traced - */ - public static boolean isIndexTraced() { - return INDEX; - } - - /** - * @return If DISPLAY messages are traced - */ - public static boolean isDisplayTraced() { - return DISPLAY; - } - - /** - * @return If SORTING messages are traced - */ - public static boolean isSortingTraced() { - return SORTING; - } - - - // ------------------------------------------------------------------------ - // Tracing methods - // ------------------------------------------------------------------------ - - /** - * Trace a generic event - * - * @param msg - * The event's message - */ - public static void trace(String msg) { - // Leave when there is no place to write the message. - if (fTraceLog == null) { - return; - } - - long currentTime = System.currentTimeMillis(); - StringBuilder message = new StringBuilder("["); - message.append(currentTime / 1000); - message.append("."); - message.append(String.format("%1$03d", currentTime % 1000)); - message.append("] "); - message.append(msg); - - try { - fTraceLog.write(message.toString()); - fTraceLog.newLine(); - fTraceLog.flush(); - } catch (IOException e) { - Activator.getDefault().logError("Error writing to log file " + LOGNAME, e); //$NON-NLS-1$ - } - } - - /** - * Trace an INDEX event - * - * @param msg - * The event's message - */ - public static void traceIndex(String msg) { - String message = ("[INDEX] " + msg); - trace(message); - } - - /** - * Trace a DISPLAY event - * - * @param msg - * The event's message - */ - public static void traceDisplay(String msg) { - String message = ("[DISPLAY]" + msg); - trace(message); - } - - /** - * Trace a SORTING event - * - * @param msg - * The event's message - */ - public static void traceSorting(String msg) { - String message = ("[SORT] " + msg); - trace(message); - } - - /** - * Trace an ERROR event - * - * @param msg - * The event's message - */ - public static void traceError(String msg) { - String message = ("[ERR] Thread=" + Thread.currentThread().getId() + " " + msg); - trace(message); - } - - /** - * Trace a WARNING event - * - * @param msg - * The event's message - */ - public static void traceWarning(String msg) { - String message = ("[WARN] Thread=" + Thread.currentThread().getId() + " " + msg); - trace(message); - } - - /** - * Trace an INFO event - * - * @param msg - * The event's message - */ - public static void traceInfo(String msg) { - String message = ("[INF] Thread=" + Thread.currentThread().getId() + " " + msg); - trace(message); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/ExportToTextCommandHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/ExportToTextCommandHandler.java deleted file mode 100644 index f8f4a82300..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/ExportToTextCommandHandler.java +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Kalray, Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xavier Raynaud - Initial API and implementation - * Bernd Hufmann - Adapted to new events table column API - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.commands; - -import java.util.List; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.expressions.IEvaluationContext; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.linuxtools.tmf.core.filter.ITmfFilter; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.ui.PlatformUI; - -/** - * This handler exports traces to text files. - * @author Xavier Raynaud - */ -public class ExportToTextCommandHandler extends AbstractHandler { - - /** Id of the export-to-text command */ - public static final String COMMAND_ID = "org.eclipse.linuxtools.tmf.ui.exportToText"; //$NON-NLS-1$ - /** - * Id used to retrieve the header (as a String) of the trace to export. - * This header is from the application context of this handler. - */ - public static final String TMF_EVENT_TABLE_COLUMNS_ID = "org.eclipse.linuxtools.tmf.ui.exportToText.columns"; //$NON-NLS-1$ - - /** - * Constructor - */ - public ExportToTextCommandHandler() { - } - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - List columns = getColumns(event.getApplicationContext()); - ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace(); - ITmfFilter filter = TmfTraceManager.getInstance().getCurrentFilter(); - if (trace != null) { - FileDialog fd = new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.SAVE); - fd.setFilterExtensions(new String[] { "*.csv", "*.*", "*" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - fd.setOverwrite(true); - final String s = fd.open(); - if (s != null) { - Job j = new ExportToTextJob(trace, filter, columns, s); - j.setUser(true); - j.schedule(); - } - } - return null; - } - - @SuppressWarnings("unchecked") - private static List getColumns(Object evaluationContext) { - if (evaluationContext instanceof IEvaluationContext) { - Object s = ((IEvaluationContext) evaluationContext).getVariable(TMF_EVENT_TABLE_COLUMNS_ID); - if (s instanceof List) { - return (List) s; - } - } - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/ExportToTextJob.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/ExportToTextJob.java deleted file mode 100644 index 4ffef85d23..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/ExportToTextJob.java +++ /dev/null @@ -1,135 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Kalray, Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xavier Raynaud - Initial API and implementation - * Bernd Hufmann - Adapted to new events table column API - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.commands; - -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Writer; -import java.text.MessageFormat; -import java.util.List; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.core.filter.ITmfFilter; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.osgi.util.NLS; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn; - -/** - * This job exports traces to text files. - * @author Xavier Raynaud - */ -public class ExportToTextJob extends Job { - - private static final int TOTAL_WORK = 100; - private static final int SLEEPING_INTERVAL = 100; - - /** the ExportToCSV job family */ - public static final Object ExportToCSVJobFamily = new Object(); - - private final ITmfTrace fTrace; - private final ITmfFilter fFilter; - private final List fColumns; - private final String destination; - - /** - * Job constructor. - * - * @param trace - * the trace to export - * @param filter - * the filter to apply when exporting the trace. may be null. - * @param columns - * the header to put at top of the exported file (may be null) - * @param destination - * the path of the file where the data is exported. - */ - public ExportToTextJob(ITmfTrace trace, ITmfFilter filter, List columns, String destination) { - super(MessageFormat.format(Messages.ExportToTextJob_Export_to, destination)); - this.fTrace = trace; - this.fFilter = filter; - this.fColumns = columns; - this.destination = destination; - } - - @Override - public IStatus run(IProgressMonitor monitor) { - monitor.beginTask(NLS.bind(Messages.ExportToTextJob_Export_trace_to, destination), TOTAL_WORK); - IStatus ret = saveImpl(monitor); - monitor.done(); - return ret; - } - - private IStatus saveImpl(IProgressMonitor monitor) { - try (final BufferedWriter bw = new BufferedWriter(new FileWriter(destination));) { - if (fColumns != null) { - boolean needTab = false; - for (TmfEventTableColumn column : fColumns) { - if (needTab) { - bw.write('\t'); - } - bw.write(column.getHeaderName()); - needTab = true; - } - bw.append('\n'); - } - return saveImpl(bw, monitor); - } catch (IOException ex) { - Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, - MessageFormat.format(Messages.ExportToTextJob_Unable_to_export_trace, destination), - ex); - return status; - } - } - - private IStatus saveImpl(Writer bw, IProgressMonitor monitor) { - ExportToTextRequest request = new ExportToTextRequest(bw, fFilter, fColumns); - fTrace.sendRequest(request); - int currentIndex = 0; - while (!request.isCompleted()) { - if (monitor.isCanceled()) { - request.cancel(); - return Status.CANCEL_STATUS; - } - int index = (int) (request.getNbRead() * TOTAL_WORK / fTrace.getNbEvents()); - if (index > currentIndex) { - int progress = index - currentIndex; - monitor.worked(progress); - currentIndex = index; - } - try { - Thread.sleep(SLEEPING_INTERVAL); - } catch (InterruptedException e) { - } - } - if (request.isFailed()) { - Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, - MessageFormat.format(Messages.ExportToTextJob_Unable_to_export_trace, destination), - request.getIOException()); - return status; - } - return Status.OK_STATUS; - } - - @Override - public boolean belongsTo(Object family) { - return ExportToCSVJobFamily.equals(family); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/ExportToTextRequest.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/ExportToTextRequest.java deleted file mode 100644 index 950d9739a9..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/ExportToTextRequest.java +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Kalray, Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xavier Raynaud - Initial API and implementation - * Bernd Hufmann - Adapted to new events table column API - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.commands; - -import java.io.IOException; -import java.io.Writer; -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.filter.ITmfFilter; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn; - -/** - * This TMF Requests exports traces to text files. - * @author Xavier Raynaud - */ -public class ExportToTextRequest extends TmfEventRequest { - - private final Writer fWriter; - private final ITmfFilter fFilter; - private final List fColumns; - private IOException fIOException; - - /** - * Constructor - * @param w - * a Writer, typically a FileWriter. - * @param filter - * a TmfFilter, if we want to filter some events. May be null. - * @param columns - * the {@link TmfEventTableColumn} requesting the export (may be null) - */ - public ExportToTextRequest(Writer w, ITmfFilter filter, List columns) { - super(ITmfEvent.class, TmfTimeRange.ETERNITY, 0, ITmfEventRequest.ALL_DATA, ExecutionType.FOREGROUND); - this.fWriter = w; - this.fFilter = filter; - this.fColumns = columns; - } - - /** - * Gets the IOException thrown by this export request, if any. - * @return the fIoException - */ - public IOException getIOException() { - return fIOException; - } - - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - if (isCancelled()) { - return; - } - try { - if (fFilter == null || fFilter.matches(event)) { - if (fColumns != null) { - boolean needTab = false; - for (TmfEventTableColumn column : fColumns) { - if (needTab) { - fWriter.write('\t'); - } - fWriter.write(column.getItemString(event)); - needTab = true; - } - } else { // fallback to default formatting - fWriter.write(event.getTimestamp().toString()); - fWriter.write('\t'); - fWriter.write(event.getSource()); - fWriter.write('\t'); - fWriter.write(event.getType().getName()); - fWriter.write('\t'); - fWriter.write(event.getReference()); - fWriter.write('\t'); - ITmfEventField content = event.getContent(); - Object value = content.getValue(); - if (value != null) { - fWriter.write(value.toString()); - } - } - fWriter.write('\n'); - } - } catch (IOException ex) { - fIOException = ex; - fail(); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/ManageCustomParsersCommandHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/ManageCustomParsersCommandHandler.java deleted file mode 100644 index 1f73c8a002..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/ManageCustomParsersCommandHandler.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.commands; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.linuxtools.internal.tmf.ui.dialogs.ManageCustomParsersDialog; -import org.eclipse.swt.widgets.Display; - -/** - * Command handler for custom text parsers. - * - * @author Patrick Tassé - */ -public class ManageCustomParsersCommandHandler extends AbstractHandler { - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - ManageCustomParsersDialog dialog = new ManageCustomParsersDialog(Display.getDefault().getActiveShell()); - dialog.open(); - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/Messages.java deleted file mode 100644 index d8d5d4ada3..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/Messages.java +++ /dev/null @@ -1,37 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - **********************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.commands; - -import org.eclipse.osgi.util.NLS; - -/** - * Messages for commands - * - * @author Marc-Andre Laperle - */ -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.tmf.ui.commands.messages"; //$NON-NLS-1$ - - /** Select trace directory */ - public static String OpenDirHandler_SelectTraceDirectory; - /** Select trace file */ - public static String OpenFileHandler_SelectTraceFile; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/OpenFileHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/OpenFileHandler.java deleted file mode 100644 index 456dd6bbbb..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/OpenFileHandler.java +++ /dev/null @@ -1,79 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Patrick Tasse - Add support for folder elements - **********************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.commands; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfOpenTraceHelper; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.handlers.HandlerUtil; - -/** - * Open file handler, used to open files (not directories) - * - * @author Matthew Khouzam - */ -public class OpenFileHandler extends AbstractHandler { - - @Override - public Object execute(ExecutionEvent event) { - - ISelection currentSelection = HandlerUtil.getCurrentSelection(event); - // Menu Selection is not null for context-sensitive menu - ISelection menuSelection = HandlerUtil.getActiveMenuSelection(event); - - // Get trace path - final Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); - FileDialog fd = new FileDialog(shell); - fd.setText(Messages.OpenFileHandler_SelectTraceFile); - String filePath = fd.open(); - if (filePath == null) { - return null; - } - - try { - - TmfTraceFolder destinationFolder; - - if ((menuSelection != null) && (currentSelection instanceof IStructuredSelection)) { - // If handler is called from the context sensitive menu of a tracing project import to - // the traces folder from this project - destinationFolder = TmfHandlerUtil.getTraceFolderFromSelection(currentSelection); - } else { - // If handler is called from file menu import into default tracing project - IProject project = TmfProjectRegistry.createProject( - TmfCommonConstants.DEFAULT_TRACE_PROJECT_NAME, null, new NullProgressMonitor()); - TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true); - destinationFolder = projectElement.getTracesFolder(); - } - - TmfOpenTraceHelper.openTraceFromPath(destinationFolder, filePath, shell); - } catch (CoreException e) { - Activator.getDefault().logError(e.getMessage(), e); - } - return null; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/TmfHandlerUtil.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/TmfHandlerUtil.java deleted file mode 100644 index ebfe2a49a6..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/TmfHandlerUtil.java +++ /dev/null @@ -1,76 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - * Patrick Tasse - Add support for folder elements - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.commands; - -import org.eclipse.core.resources.IProject; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.linuxtools.tmf.ui.project.model.ITmfProjectModelElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; - -/** - * Utility methods for handlers - * - * @author Marc-Andre Laperle - */ -public class TmfHandlerUtil { - - /** - * Get the enclosing project from the selection - * - * @param selection - * the selection - * - * @return the enclosing project or null if selection is no enclosed by a - * project - */ - public static IProject getProjectFromSelection(ISelection selection) { - if (selection instanceof IStructuredSelection) { - IStructuredSelection structuredSelection = (IStructuredSelection) selection; - Object firstElement = structuredSelection.getFirstElement(); - if (firstElement instanceof ITmfProjectModelElement) { - ITmfProjectModelElement tmfProjectElement = (ITmfProjectModelElement) firstElement; - return tmfProjectElement.getProject().getResource(); - } - } - - return null; - } - - /** - * Get the trace folder from the selection - * - * @param selection - * the selection - * - * @return the enclosing project or null if selection is no enclosed by a - * project - */ - public static TmfTraceFolder getTraceFolderFromSelection(ISelection selection) { - if (selection instanceof IStructuredSelection) { - IStructuredSelection structuredSelection = (IStructuredSelection) selection; - Object firstElement = structuredSelection.getFirstElement(); - if (firstElement instanceof ITmfProjectModelElement) { - ITmfProjectModelElement element = (ITmfProjectModelElement) firstElement; - while (element != null) { - if (element instanceof TmfTraceFolder) { - return (TmfTraceFolder) element; - } - element = element.getParent(); - } - } - } - return null; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/messages.properties deleted file mode 100644 index 911dd9d6eb..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/commands/messages.properties +++ /dev/null @@ -1,14 +0,0 @@ -############################################################################### -# Copyright (c) 2013 Ericsson. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Marc-Andre Laperle - initial API and implementation -############################################################################### - -OpenDirHandler_SelectTraceDirectory=Open trace directory -OpenFileHandler_SelectTraceFile=Open trace file \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/dialogs/ManageCustomParsersDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/dialogs/ManageCustomParsersDialog.java deleted file mode 100644 index 459a66016c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/dialogs/ManageCustomParsersDialog.java +++ /dev/null @@ -1,367 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.dialogs; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.window.Window; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.internal.tmf.ui.parsers.wizards.CustomTxtParserWizard; -import org.eclipse.linuxtools.internal.tmf.ui.parsers.wizards.CustomXmlParserWizard; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTraceDefinition; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTraceDefinition; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.List; -import org.eclipse.swt.widgets.Shell; - -/** - * Dialog for custom text parsers. - * - * @author Patrick Tassé - */ -public class ManageCustomParsersDialog extends Dialog { - - private static final String SEP = " : "; //$NON-NLS-1$ - private static final int SEP_LEN = SEP.length(); - - private static final Image image = Activator.getDefault().getImageFromPath("/icons/etool16/customparser_wizard.gif"); //$NON-NLS-1$ - - Button txtButton; - Button xmlButton; - List parserList; - Button newButton; - Button editButton; - Button deleteButton; - Button importButton; - Button exportButton; - - /** - * Constructor - * - * @param parent - * Parent shell of this dialog - */ - public ManageCustomParsersDialog(Shell parent) { - super(parent); - setShellStyle(SWT.RESIZE | SWT.MAX | getShellStyle()); - } - - @Override - protected Control createDialogArea(Composite parent) { - getShell().setText(Messages.ManageCustomParsersDialog_DialogHeader); - getShell().setImage(image); - - Composite composite = (Composite) super.createDialogArea(parent); - composite.setLayout(new GridLayout(2, false)); - - Composite listContainer = new Composite(composite, SWT.NONE); - listContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - GridLayout lcgl = new GridLayout(); - lcgl.marginHeight = 0; - lcgl.marginWidth = 0; - listContainer.setLayout(lcgl); - - Composite radioContainer = new Composite(listContainer, SWT.NONE); - GridLayout rcgl = new GridLayout(2, true); - rcgl.marginHeight = 0; - rcgl.marginWidth = 0; - radioContainer.setLayout(rcgl); - - txtButton = new Button(radioContainer, SWT.RADIO); - txtButton.setText(Messages.ManageCustomParsersDialog_TextButtonLabel); - txtButton.setSelection(true); - txtButton.addSelectionListener(new SelectionListener() { - @Override - public void widgetDefaultSelected(SelectionEvent e) {} - - @Override - public void widgetSelected(SelectionEvent e) { - fillParserList(); - } - }); - - xmlButton = new Button(radioContainer, SWT.RADIO); - xmlButton.setText("XML"); //$NON-NLS-1$ - xmlButton.addSelectionListener(new SelectionListener() { - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - - @Override - public void widgetSelected(SelectionEvent e) { - fillParserList(); - } - }); - - parserList = new List(listContainer, SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); - parserList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - parserList.addSelectionListener(new SelectionListener() { - @Override - public void widgetDefaultSelected(SelectionEvent e) {} - - @Override - public void widgetSelected(SelectionEvent e) { - if (parserList.getSelectionCount() == 0) { - editButton.setEnabled(false); - deleteButton.setEnabled(false); - exportButton.setEnabled(false); - } else { - editButton.setEnabled(true); - deleteButton.setEnabled(true); - exportButton.setEnabled(true); - } - } - }); - - Composite buttonContainer = new Composite(composite, SWT.NULL); - buttonContainer.setLayout(new GridLayout()); - buttonContainer.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, false, false)); - - newButton = new Button(buttonContainer, SWT.PUSH); - newButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); - newButton.setText(Messages.ManageCustomParsersDialog_NewButtonLabel); - newButton.addSelectionListener(new SelectionListener() { - @Override - public void widgetDefaultSelected(SelectionEvent e) {} - - @Override - public void widgetSelected(SelectionEvent e) { - WizardDialog dialog = null; - if (txtButton.getSelection()) { - dialog = new WizardDialog(getShell(), new CustomTxtParserWizard()); - } else if (xmlButton.getSelection()) { - dialog = new WizardDialog(getShell(), new CustomXmlParserWizard()); - } - if (dialog != null) { - dialog.open(); - if (dialog.getReturnCode() == Window.OK) { - fillParserList(); - } - } - } - }); - - editButton = new Button(buttonContainer, SWT.PUSH); - editButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); - editButton.setText(Messages.ManageCustomParsersDialog_EditButtonLabel); - editButton.setEnabled(false); - editButton.addSelectionListener(new SelectionListener() { - @Override - public void widgetDefaultSelected(SelectionEvent e) {} - - @Override - public void widgetSelected(SelectionEvent e) { - WizardDialog dialog = null; - String selection = parserList.getSelection()[0]; - String category = selection.substring(0, selection.indexOf(SEP)); - String name = selection.substring(selection.indexOf(SEP) + SEP_LEN); - if (txtButton.getSelection()) { - dialog = new WizardDialog(getShell(), - new CustomTxtParserWizard(CustomTxtTraceDefinition.load(category, name))); - } else if (xmlButton.getSelection()) { - dialog = new WizardDialog(getShell(), - new CustomXmlParserWizard(CustomXmlTraceDefinition.load(category, name))); - } - if (dialog != null) { - dialog.open(); - if (dialog.getReturnCode() == Window.OK) { - fillParserList(); - } - } - } - }); - - deleteButton = new Button(buttonContainer, SWT.PUSH); - deleteButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); - deleteButton.setText(Messages.ManageCustomParsersDialog_DeleteButtonLabel); - deleteButton.setEnabled(false); - deleteButton.addSelectionListener(new SelectionListener() { - @Override - public void widgetDefaultSelected(SelectionEvent e) {} - - @Override - public void widgetSelected(SelectionEvent e) { - boolean confirm = MessageDialog.openQuestion( - getShell(), - Messages.ManageCustomParsersDialog_DeleteParserDialogHeader, - NLS.bind(Messages.ManageCustomParsersDialog_DeleteConfirmation, parserList.getSelection()[0])); - if (confirm) { - String selection = parserList.getSelection()[0]; - String category = selection.substring(0, selection.indexOf(SEP)); - String name = selection.substring(selection.indexOf(SEP) + SEP_LEN); - if (txtButton.getSelection()) { - CustomTxtTraceDefinition.delete(category, name); - } else if (xmlButton.getSelection()) { - CustomXmlTraceDefinition.delete(category, name); - } - fillParserList(); - } - } - }); - - new Label(buttonContainer, SWT.NONE); // filler - - importButton = new Button(buttonContainer, SWT.PUSH); - importButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); - importButton.setText(Messages.ManageCustomParsersDialog_ImportButtonLabel); - importButton.addSelectionListener(new SelectionListener() { - @Override - public void widgetDefaultSelected(SelectionEvent e) {} - - @Override - public void widgetSelected(SelectionEvent e) { - FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(), SWT.OPEN); - dialog.setText(Messages.ManageCustomParsersDialog_ImportParserSelection); - dialog.setFilterExtensions(new String[] { "*.xml", "*" }); //$NON-NLS-1$ //$NON-NLS-2$ - String path = dialog.open(); - if (path != null) { - CustomTraceDefinition[] defs = null; - if (txtButton.getSelection()) { - defs = CustomTxtTraceDefinition.loadAll(path); - } else if (xmlButton.getSelection()) { - defs = CustomXmlTraceDefinition.loadAll(path); - } - if (defs != null && defs.length > 0) { - for (CustomTraceDefinition def : defs) { - boolean ok = checkNameConflict(def); - if (ok) { - def.save(); - } - } - fillParserList(); - } - } - } - }); - - exportButton = new Button(buttonContainer, SWT.PUSH); - exportButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); - exportButton.setText(Messages.ManageCustomParsersDialog_ExportButtonLabel); - exportButton.setEnabled(false); - exportButton.addSelectionListener(new SelectionListener() { - @Override - public void widgetDefaultSelected(SelectionEvent e) {} - - @Override - public void widgetSelected(SelectionEvent e) { - FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(), SWT.SAVE); - dialog.setText(NLS.bind(Messages.ManageCustomParsersDialog_ExportParserSelection, parserList.getSelection()[0])); - dialog.setFilterExtensions(new String[] { "*.xml", "*" }); //$NON-NLS-1$ //$NON-NLS-2$ - String path = dialog.open(); - if (path != null) { - String selection = parserList.getSelection()[0]; - String category = selection.substring(0, selection.indexOf(SEP)); - String name = selection.substring(selection.indexOf(SEP) + SEP_LEN); - CustomTraceDefinition def = null; - if (txtButton.getSelection()) { - def = CustomTxtTraceDefinition.load(category, name); - } else if (xmlButton.getSelection()) { - def = CustomXmlTraceDefinition.load(category, name); - } - if (def != null) { - def.save(path); - } - } - } - }); - - fillParserList(); - - getShell().setMinimumSize(300, 275); - return composite; - } - - @Override - protected void createButtonsForButtonBar(Composite parent) { - createButton(parent, IDialogConstants.OK_ID, IDialogConstants.CLOSE_LABEL, false); - } - - private void fillParserList() { - parserList.removeAll(); - if (txtButton.getSelection()) { - for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll(false)) { - parserList.add(def.categoryName + SEP + def.definitionName); - } - } else if (xmlButton.getSelection()) { - for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll(false)) { - parserList.add(def.categoryName + SEP + def.definitionName); - } - } - editButton.setEnabled(false); - deleteButton.setEnabled(false); - exportButton.setEnabled(false); - } - - private boolean checkNameConflict(CustomTraceDefinition def) { - for (TraceTypeHelper helper : TmfTraceType.getTraceTypeHelpers()) { - if (def.categoryName.equals(helper.getCategoryName()) && - def.definitionName.equals(helper.getName())) { - String newName = findAvailableName(def); - MessageDialog dialog = new MessageDialog( - getShell(), - null, - null, - NLS.bind(Messages.ManageCustomParsersDialog_ConflictMessage, - new Object[] { def.categoryName, def.definitionName, newName}), - MessageDialog.QUESTION, - new String[] { Messages.ManageCustomParsersDialog_ConflictRenameButtonLabel, - Messages.ManageCustomParsersDialog_ConflictSkipButtonLabel }, - 0); - int result = dialog.open(); - if (result == 0) { - def.definitionName = newName; - return true; - } - return false; - } - } - return true; - } - - private static String findAvailableName(CustomTraceDefinition def) { - int i = 2; - Iterable helpers = TmfTraceType.getTraceTypeHelpers(); - while (true) { - String newName = def.definitionName + '(' + Integer.toString(i++) + ')'; - boolean available = true; - for (TraceTypeHelper helper : helpers) { - if (def.categoryName.equals(helper.getCategoryName()) && - newName.equals(helper.getName())) { - available = false; - break; - } - } - if (available) { - return newName; - } - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/dialogs/MultiLineInputDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/dialogs/MultiLineInputDialog.java deleted file mode 100644 index 7d757cd5d5..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/dialogs/MultiLineInputDialog.java +++ /dev/null @@ -1,167 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.dialogs; - -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.IInputValidator; -import org.eclipse.jface.dialogs.InputDialog; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.KeyAdapter; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -/** - * A simple input dialog for soliciting an input string from the user. - * - * Overrides InputDialog to support multiple line text input. - * - * @author Patrick Tassé - */ -public class MultiLineInputDialog extends InputDialog { - - private final String dialogMessage; - - /* flag to indicate if CR can be used to submit the dialog */ - private boolean submitOnCR = true; - - /** - * Creates a multi line input dialog. - * - * @param parentShell - * the parent shell, or null to create a top-level shell - * @param dialogTitle - * the dialog title, or null if none - * @param dialogMessage - * the dialog message, or null if none - * @param initialValue - * the initial input value, or null if none (equivalent to the empty string) - * @param validator - * an input validator, or null if none - */ - public MultiLineInputDialog(Shell parentShell, String dialogTitle, - String dialogMessage, String initialValue, IInputValidator validator) { - super(parentShell, dialogTitle, null, initialValue, validator); - this.dialogMessage = dialogMessage; - } - - /** - * Creates a multi line input dialog with a not-empty text validator. - * - * @param parentShell - * the parent shell, or null to create a top-level shell - * @param dialogTitle - * the dialog title, or null if none - * @param dialogMessage - * the dialog message, or null if none - * @param initialValue - * the initial input value, or null if none (equivalent to the empty string) - */ - public MultiLineInputDialog(Shell parentShell, String dialogTitle, - String dialogMessage, String initialValue) { - super(parentShell, dialogTitle, null, initialValue, new NotEmptyValidator()); - this.dialogMessage = dialogMessage; - } - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - final Text text = getText(); - - /* create dialog message label here instead because default implementation uses GRAB_VERTICAL */ - if (dialogMessage != null) { - Label label = new Label(composite, SWT.WRAP); - label.setText(dialogMessage); - GridData data = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL - | GridData.VERTICAL_ALIGN_CENTER); - data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH); - label.setLayoutData(data); - label.setFont(parent.getFont()); - label.moveAbove(text); - } - - /* modify text layout data here because default implementation doesn't fill vertically */ - GridData gridData = new GridData(GridData.FILL_BOTH); - gridData.widthHint = convertHorizontalDLUsToPixels(250); - gridData.heightHint = convertHeightInCharsToPixels(3); - text.setLayoutData(gridData); - - text.addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(KeyEvent e) { - if (e.character == SWT.CR) { - if (submitOnCR) { - /* submit the dialog */ - e.doit = false; - okPressed(); - return; - } - } else if (e.character == SWT.TAB) { - /* don't insert a tab character in the text */ - e.doit = false; - text.traverse(SWT.TRAVERSE_TAB_NEXT); - } - /* don't allow CR to submit anymore */ - submitOnCR = false; - } - }); - - text.addMouseListener(new MouseAdapter() { - @Override - public void mouseDown(MouseEvent e) { - /* don't allow CR to submit anymore */ - submitOnCR = false; - } - }); - - return composite; - } - - @Override - protected Control createContents(Composite parent) { - Control control = super.createContents(parent); - - /* set the shell minimum size */ - Point clientArea = control.computeSize(SWT.DEFAULT, SWT.DEFAULT); - Rectangle trim = getShell().computeTrim(0, 0, clientArea.x, clientArea.y); - getShell().setMinimumSize(trim.width, trim.height); - - return control; - } - - @Override - protected int getInputTextStyle() { - return SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | SWT.BORDER; - } - - @Override - protected boolean isResizable() { - return true; - } - - private static class NotEmptyValidator implements IInputValidator { - @Override - public String isValid(String newText) { - return (newText == null || newText.trim().length() == 0) ? " " : null; //$NON-NLS-1$ - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/editors/handlers/AddBookmarkHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/editors/handlers/AddBookmarkHandler.java deleted file mode 100644 index 203bc2ce38..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/editors/handlers/AddBookmarkHandler.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.editors.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.linuxtools.tmf.ui.editors.TmfEventsEditor; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PlatformUI; - -/** - * Handler to add bookmarks. - * - * @author Patrick Tasse - */ -public class AddBookmarkHandler extends AbstractHandler { - - @Override - public boolean isEnabled() { - return true; - } - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - IWorkbench wb = PlatformUI.getWorkbench(); - IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); - IEditorPart activeEditor = activePage.getActiveEditor(); - if (activeEditor instanceof TmfEventsEditor) { - TmfEventsEditor editor = (TmfEventsEditor) activeEditor; - editor.addBookmark(); - } - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/messages.properties deleted file mode 100644 index a466259bdf..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/messages.properties +++ /dev/null @@ -1,297 +0,0 @@ -############################################################################### -# Copyright (c) 2013, 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### - -# org.eclipse.linuxtools.tmf.ui.dialogs -ManageCustomParsersDialog_ConflictMessage=Trace type ''{0} : {1}'' already exists.\nDo you want to rename to ''{2}'' or skip? -ManageCustomParsersDialog_ConflictRenameButtonLabel=Rename -ManageCustomParsersDialog_ConflictSkipButtonLabel=Skip -ManageCustomParsersDialog_DeleteButtonLabel=Delete -ManageCustomParsersDialog_DeleteConfirmation=Are you sure you want to delete {0}? -ManageCustomParsersDialog_DeleteParserDialogHeader=Delete Custom Parser -ManageCustomParsersDialog_DialogHeader=Manage Custom Parsers -ManageCustomParsersDialog_EditButtonLabel=Edit... -ManageCustomParsersDialog_ExportButtonLabel=Export... -ManageCustomParsersDialog_ExportParserSelection=Select file to export {0} -ManageCustomParsersDialog_ImportButtonLabel=Import... -ManageCustomParsersDialog_ImportParserSelection=Select custom parser file to import -ManageCustomParsersDialog_NewButtonLabel=New... -ManageCustomParsersDialog_TextButtonLabel=Text - -# org.eclipse.linuxtools.tmf.ui.viewers.events -TmfEventsTable_AddBookmarkActionText=Add Bookmark... -TmfEventsTable_AddBookmarkDialogMessage=Enter Bookmark Description: -TmfEventsTable_AddBookmarkDialogTitle=Add Bookmark -TmfEventsTable_ApplyPresetFilterMenuName=Apply Preset Filter... -TmfEventsTable_ClearFiltersActionText=Clear Filters -TmfEventsTable_CollapseFilterMenuName=Collapse Events -TmfEventsTable_ContentColumnHeader=Content -TmfEventsTable_Export_to_text=Export To Text... -TmfEventsTable_FilterHint= -TmfEventsTable_HideRawActionText=Hide Raw -TmfEventsTable_HideTableActionText=Hide Table -TmfEventsTable_MultipleBookmarksToolTip=Multiple bookmarks at this location -TmfEventsTable_OpenSourceCodeActionText=Open Source Code -TmfEventsTable_OpenSourceCodeNotFound=can not be found in the workspace. -TmfEventsTable_OpenSourceCodeSelectFileDialogTitle=Select source file for the call site -TmfEventsTable_OpenModelActionText=Open Model Element -TmfEventsTable_OpenModelUnsupportedURI=is not a supported model URI format. -TmfEventsTable_ReferenceColumnHeader=File -TmfEventsTable_RemoveBookmarkActionText=Remove Bookmark -TmfEventsTable_SearchHint= -TmfEventsTable_SearchingJobName=Searching... -TmfEventsTable_ShowFilterBarActionText=Show Filter Bar -TmfEventsTable_ShowRawActionText=Show Raw -TmfEventsTable_ShowSearchBarActionText=Show Search Bar -TmfEventsTable_ShowTableActionText=Show Table -TmfEventsTable_SourceColumnHeader=Source -TmfEventsTable_TimestampColumnHeader=Timestamp -TmfEventsTable_TypeColumnHeader=Type - -# org.eclipse.linuxtools.tmf.ui.viewers.timegraph.dialogs -TmfTimeFilterDialog_EDIT_PROFILING_OPTIONS=Edit Profiling Options -TmfTimeFilterDialog_TRACE_FILTER=Trace Filter -TmfTimeFilterDialog_TRACE_FILTER_DESC=Define the filter set -TmfTimeFilterDialog_TRACE_ID=Trace Id -TmfTimeFilterDialog_TRACE_NAME=Trace Name -TmfTimeLegend_LEGEND=Legend -TmfTimeLegend_TRACE_STATES=Trace -TmfTimeLegend_TRACE_STATES_TITLE=States Transition Visualizer -TmfTimeLegend_WINDOW_TITLE=Trace Visualizer's Legend -TmfTimeLegend_StateTypeName=States -TmfTimeFilterDialog_WINDOW_TITLE=Filter -TmfTimeFilterDialog_MESSAGE=Check the entries to show -TmfTimeFilterDialog_CHECK_ALL=Check all -TmfTimeFilterDialog_UNCHECK_ALL=Uncheck all -TmfTimeFilterDialog_CHECK_SELECTED=Check selected -TmfTimeFilterDialog_UNCHECK_SELECTED=Uncheck selected -TmfTimeFilterDialog_CHECK_SUBTREE=Check subtree -TmfTimeFilterDialog_UNCHECK_SUBTREE=Uncheck subtree - -# org.eclipse.linuxtools.tmf.ui.viewers.timegraph.widgets -TmfTimeTipHandler_DURATION=Duration -TmfTimeTipHandler_LINK_SOURCE=Source -TmfTimeTipHandler_LINK_SOURCE_TIME=Source Time -TmfTimeTipHandler_LINK_TARGET=Target -TmfTimeTipHandler_LINK_TARGET_TIME=Target Time -TmfTimeTipHandler_LINK_TIME=Time -TmfTimeTipHandler_TRACE_DATE=Date -TmfTimeTipHandler_TRACE_EVENT_TIME=Event Time -TmfTimeTipHandler_TRACE_START_TIME=Start Time -TmfTimeTipHandler_TRACE_STATE=State -TmfTimeTipHandler_TRACE_STOP_TIME=Stop Time - -TmfTimeGraphCombo_FilterActionNameText=Filter -TmfTimeGraphCombo_FilterActionToolTipText=Show View Filters - - -TmfTimeGraphViewer_ResetScaleActionNameText=Reset -TmfTimeGraphViewer_ResetScaleActionToolTipText=Reset the Time Scale to Default -TmfTimeGraphViewer_LegendActionNameText=Legend -TmfTimeGraphViewer_LegendActionToolTipText=Show Legend -TmfTimeGraphViewer_NextEventActionNameText=Next Event -TmfTimeGraphViewer_NextEventActionToolTipText=Select Next Event -TmfTimeGraphViewer_PreviousEventActionNameText=Previous Event -TmfTimeGraphViewer_PreviousEventActionToolTipText=Select Previous Event -TmfTimeGraphViewer_NextItemActionNameText=Next Item -TmfTimeGraphViewer_NextItemActionToolTipText=Select Next Item -TmfTimeGraphViewer_PreviousItemActionNameText=Previous Item -TmfTimeGraphViewer_PreviousItemActionToolTipText=Select Previous Item -TmfTimeGraphViewer_ZoomInActionNameText=Zoom In -TmfTimeGraphViewer_ZoomInActionToolTipText=Zoom In -TmfTimeGraphViewer_ZoomOutActionNameText=Zoom Out -TmfTimeGraphViewer_ZoomOutActionToolTipText=Zoom Out -TmfTimeGraphViewer_HideArrowsActionNameText=Hide Arrows -TmfTimeGraphViewer_HideArrowsActionToolTipText=Hide Arrows -TmfTimeGraphViewer_FollowArrowForwardActionNameText=Follow Arrow Forward -TmfTimeGraphViewer_FollowArrowForwardActionToolTipText=Follow Arrow Forward -TmfTimeGraphViewer_FollowArrowBackwardActionNameText=Follow Arrow Backward -TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText=Follow Arrow Backward - -Utils_ClockCyclesUnit=\u0020cc - -# org.eclipse.linuxtools.tmf.ui.views.colors -ColorsView_AddActionToolTipText=Insert new color setting -ColorsView_BackgroundButtonText=BG -ColorsView_BackgroundDialogText=Set background color -ColorsView_DeleteActionToolTipText=Delete color setting -ColorsView_ExportActionToolTipText=Export color settings -ColorsView_FilterButtonText=Filter... -ColorsView_ForegroundButtonText=FG -ColorsView_ForegroundDialogText=Set foreground color -ColorsView_ImportActionToolTipText=Import color settings -ColorsView_ImportOverwriteDialogMessage1=Do you want to overwrite the current color settings?\n -ColorsView_ImportOverwriteDialogMessage2=Answering No will insert the imported settings above the current selection. -ColorsView_ImportOverwriteDialogTitle=Overwrite current settings -ColorsView_MoveDownActionToolTipText=Decrease priority -ColorsView_MoveUpActionToolTipText=Increase priority -ColorsView_TickButtonText=Tick -TickColorDialog_TickColorDialogTitle=Choose tick color - -# org.eclipse.linuxtools.tmf.ui.wizards -CustomTxtParserInputWizardPage_addChildLine=Add child line -CustomTxtParserInputWizardPage_addGroup=Add group -CustomTxtParserInputWizardPage_addNextLine=Add next line -CustomTxtParserInputWizardPage_append=Append -CustomTxtParserInputWizardPage_appendWith=Append with | -CustomTxtParserInputWizardPage_capturedGroup=Captured group -CustomTxtParserInputWizardPage_cardinality=Cardinality: -CustomTxtParserInputWizardPage_category=Category: -CustomTxtParserInputWizardPage_desccriptionEdit=Edit an existing custom parser for text trace files -CustomTxtParserInputWizardPage_descriptionNew=Create a new custom parser for text trace files -CustomTxtParserInputWizardPage_format=format: -CustomTxtParserInputWizardPage_group=Group {0}: -CustomTxtParserInputWizardPage_highlightAll=Highlight All -CustomTxtParserInputWizardPage_logType=Trace type: -CustomTxtParserInputWizardPage_matchingOtherLine=Matching other line: -CustomTxtParserInputWizardPage_matchingRootLine=Matching root line : -CustomTxtParserInputWizardPage_max=max: -CustomTxtParserInputWizardPage_min=min: -CustomTxtParserInputWizardPage_moveDown=Move down -CustomTxtParserInputWizardPage_moveUp=Move up -CustomTxtParserInputWizardPage_name=name: -CustomTxtParserInputWizardPage_newGroup=New group -CustomTxtParserInputWizardPage_noMatch=*no match* -CustomTxtParserInputWizardPage_noMatchingGroup=*no matching group* -CustomTxtParserInputWizardPage_noMatchingLine=*no matching line* -CustomTxtParserInputWizardPage_noMatchingTimestamp=*no matching timestamp* -CustomTxtParserInputWizardPage_noMathcingLine=*no matching line* -CustomTxtParserInputWizardPage_nonMatchingLine=Non-matching line\n -CustomTxtParserInputWizardPage_noTimestampGroup=*no timestamp group* -CustomTxtParserInputWizardPage_preview=Preview: -CustomTxtParserInputWizardPage_previewInput=Preview input -CustomTxtParserInputWizardPage_previewLegend=Preview Legend -CustomTxtParserInputWizardPage_regularExpression=Regular expression: -CustomTxtParserInputWizardPage_regularExpressionHelp=Regular Expression Help -CustomTxtParserInputWizardPage_removeGroup=Remove group -CustomTxtParserInputWizardPage_removeLine=Remove line -CustomTxtParserInputWizardPage_set=Set -CustomTxtParserInputWizardPage_timestampFormat=Time Stamp format: -CustomTxtParserInputWizardPage_timestampFormatHelp=Time Stamp Format Help -CustomTxtParserInputWizardPage_uncapturedText=Uncaptured text -CustomTxtParserInputWizardPage_unidentifiedCaptureGroup=Unidentified captured group -CustomTxtParserInputWizardPage_windowTitleEdit=Edit Custom Text Parser -CustomTxtParserInputWizardPage_windowTitleNew=New Custom Text Parser -CustomTxtParserOutputWizardPage_description=Customize the output of the parser -CustomTxtParserOutputWizardPage_moveAfter=Move After -CustomTxtParserOutputWizardPage_moveBefore=Move Before -CustomTxtParserOutputWizardPage_visible=Visible -CustomXmlParserInputWizardPage_emptyCategoryError=Enter a category for the new trace type. -CustomXmlParserInputWizardPage_emptyLogTypeError=Enter a name for the new trace type. -CustomXmlParserInputWizardPage_invalidCategoryError=Invalid character ':' in category. -CustomXmlParserInputWizardPage_invalidLogTypeError=Invalid character ':' in trace type. -CustomXmlParserInputWizardPage_duplicatelogTypeError=The trace type name already exists. -CustomXmlParserInputWizardPage_noDocumentError=Add a document element. -CustomXmlParserInputWizardPage_missingLogEntryError=Identify a Log Entry element. -CustomXmlParserInputWizardPage_missingTimestampFmtError=Enter the output format for the Time Stamp field. -CustomXmlParserInputWizardPage_missingDocumentElementError=Enter a name for the document element. -CustomXmlParserInputWizardPage_noTimestampElementOrAttribute=*no time stamp element or attribute* -CustomXmlParserInputWizardPage_elementMissingNameError=Enter a name for the element (Element {0}). -CustomXmlParserInputWizardPage_elementMissingInputNameError=Enter a name for the input (Element {0}). -CustomXmlParserInputWizardPage_elementMissingTimestampFmtError=Enter the input format for the Time Stamp (Element {0}). -CustomXmlParserInputWizardPage_elementInvalidTimestampFmtError=Enter a valid output format for the Time Stamp field (Element {0}). -CustomXmlParserInputWizardPage_elementDuplicateNameError=Duplicate element names (Element {0}). -CustomXmlParserInputWizardPage_attributeMissingNameError=Enter a name for the attribute (Attribute {0}: ?). -CustomXmlParserInputWizardPage_attributeMissingInputNameError=Enter a name for the input (Attribute {0}). -CustomXmlParserInputWizardPage_attributeMissingTimestampFmtError=Enter the input format for the Time Stamp (Attribute {0}). -CustomXmlParserInputWizardPage_attributeInvalidTimestampFmtError=Enter a valid input format for the Time Stamp (Attribute {0}). -CustomXmlParserInputWizardPage_attributeDuplicateNameError=Duplicate attribute names (Attribute {0}). -CustomXmlParserInputWizardPage_addAttribute=Add attribute -CustomXmlParserInputWizardPage_addChildElement=Add child element -CustomXmlParserInputWizardPage_addDocumentEleemnt=Add document element -CustomXmlParserInputWizardPage_addDocumentElement=Add document element -CustomXmlParserInputWizardPage_addNextElement=Add next element -CustomXmlParserInputWizardPage_append=Append -CustomXmlParserInputWizardPage_appendWith=Append with | -CustomXmlParserInputWizardPage_attibute=Attribute -CustomXmlParserInputWizardPage_category=Category: -CustomXmlParserInputWizardPage_descriptionEdit=Edit an existing custom parser for XML trace files -CustomXmlParserInputWizardPage_descriptionNew=Create a new custom parser for XML trace files -CustomXmlParserInputWizardPage_elementName=Element name: -CustomXmlParserInputWizardPage_feelingLucky=Feeling lucky -CustomXmlParserInputWizardPage_format=format: -CustomXmlParserInputWizardPage_logEntry=Log Entry -CustomXmlParserInputWizardPage_logType=Trace type: -CustomXmlParserInputWizardPage_moveDown=Move down -CustomXmlParserInputWizardPage_moveUp=Move up -CustomXmlParserInputWizardPage_name=name: -CustomXmlParserInputWizardPage_newAttibute=New attribute -CustomXmlParserInputWizardPage_noMatch=*no match* -CustomXmlParserInputWizardPage_noMatchingAttribute=*no matching attribute* -CustomXmlParserInputWizardPage_noMatchingElement=*no matching element* -CustomXmlParserInputWizardPage_preview=Preview: -CustomXmlParserInputWizardPage_previewInput=Preview input -CustomXmlParserInputWizardPage_removeAttribute=Remove attribute -CustomXmlParserInputWizardPage_removeElement=Remove element -CustomXmlParserInputWizardPage_set=Set -CustomXmlParserInputWizardPage_tagName=tag name: -CustomXmlParserInputWizardPage_timestampFormat=Time Stamp format: -CustomXmlParserInputWizardPage_timestampFormatHelp=Time Stamp Format Help -CustomXmlParserInputWizardPage_titleEdit=Edit Custom XML Parser -CustomXmlParserInputWizardPage_titleNew=New Custom XML Parser -CustomXmlParserOutputWizardPage_description=Customize the output of the parser -CustomXmlParserOutputWizardPage_moveAfter=Move After -CustomXmlParserOutputWizardPage_moveBefore=Move Before -CustomXmlParserOutputWizardPage_visible=Visible - -# org.eclipse.linuxtools.tmf.ui.views.filter -FilterDialog_FilterDialogTitle=Edit filter -FilterView_AddActionToolTipText=Add new filter -FilterView_DeleteActionToolTipText=Delete filter node -FilterView_ExportActionToolTipText=Export filters -FilterView_FileDialogFilterName=TMF Filter files -FilterView_ImportActionToolTipText=Import filters -FilterView_SaveActionToolTipText=Save filters -FilterViewer_EmptyTreeHintText= -FilterViewer_CommonCategory=[common] -FilterViewer_AlphaButtonText=Alpha -FilterViewer_FieldLabel=field: -FilterViewer_FilterNameHint=type filter name -FilterViewer_IgnoreCaseButtonText=ignore case -FilterViewer_NameLabel=name: -FilterViewer_NewPrefix=New -FilterViewer_NotLabel=not: -FilterViewer_NumButtonText=Num -FilterViewer_RegexHint=type regular expression -FilterViewer_RegexLabel=regex: -FilterViewer_ResultLabel=result: -FilterViewer_Subfilter_ToolTip=Prefix with '/' to enter a path where subfields are separated by '/'. For an uninterpreted slash use '\\/'. -FilterViewer_TimestampButtonText=Timestamp -FilterViewer_TypeLabel=type: -FilterViewer_ValueHint=type value -FilterViewer_ValueLabel=value: - -TmfView_PinActionNameText=Pin View -TmfView_PinActionToolTipText=Pin View - -# Call Stack View -CallStackPresentationProvider_Thread=Thread -CallStackView_FunctionColumn=Function -CallStackView_DepthColumn=Depth -CallStackView_EntryTimeColumn=Entry time -CallStackView_ExitTimeColumn=Exit time -CallStackView_DurationColumn=Duration -CallStackView_StackInfoNotAvailable=Stack info not available -CallStackView_SortByThreadName=Sort threads by thread name -CallStackView_SortByThreadId=Sort threads by thread id -CallStackView_SortByThreadTime=Sort threads by start time -CallStackView_ImportMappingButtonText=Import mapping file... -CallStackView_ImportMappingButtonTooltip=Import a text file containing the mapping between addresses and function names -CallStackView_ImportMappingDialogTitle=Select Mapping File -CallStackView_ImportMappingJobName=Updating Call Stack view function mapping - -CallStackView_ImportBinaryFileButtonText=Import binary file... -CallStackView_ImportBinaryFileButtonTooltip=Import a binary file containing debugging symbols -CallStackView_ImportBinaryFileDialogTitle=Select Binary File - -ExportToTextJob_Export_to=Export to {0}... -ExportToTextJob_Export_trace_to=Export trace to {0} -ExportToTextJob_Unable_to_export_trace=Unable to export trace to {0} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/custom/CustomEventTableColumns.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/custom/CustomEventTableColumns.java deleted file mode 100644 index af90427a49..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/custom/CustomEventTableColumns.java +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Alexandre Montplaisir - Update for TmfEventTableColumn - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.parsers.custom; - -import java.util.Collection; -import java.util.List; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomEvent; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTraceDefinition; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTraceDefinition.OutputColumn; -import org.eclipse.linuxtools.tmf.ui.viewers.events.TmfEventsTable; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.ITmfEventTableColumns; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn; - -import com.google.common.collect.ImmutableList; - -/** - * Event table column definition for Custom {Text|XML} traces. - * - * Since this definition will be different for every single custom trace, this - * does not work the same as with {@link ITmfEventTableColumns}. - * - * Instead, one has to call {@link #generateColumns(CustomTraceDefinition)} with - * the CustomTraceDefinition of the the particular trace to display. Then the - * returned collection can be passed to the constructor - * {@link TmfEventsTable#TmfEventsTable(org.eclipse.swt.widgets.Composite, int, Collection)} - * as usual. - * - * @author Alexandre Montplaisir - */ -public class CustomEventTableColumns { - - /** - * Column for custom events, which uses an integer ID to represent each - * column. - */ - private static final class CustomEventTableColumn extends TmfEventTableColumn { - - private final int fIndex; - - /** - * Constructor - * - * @param name - * The name (title) of this column - * @param idx - * The index of this column, which should be the index of the - * field in the event's content to display. - */ - public CustomEventTableColumn(@NonNull String name, int idx) { - super(name); - fIndex = idx; - } - - @Override - public String getItemString(ITmfEvent event) { - if (event instanceof CustomEvent) { - String ret = ((CustomEvent) event).getEventString(fIndex); - return (ret == null ? EMPTY_STRING : ret); - } - return EMPTY_STRING; - } - - @Override - public String getFilterFieldId() { - return getHeaderName(); - } - } - - /** - * Get the event table columns for a given trace definition - * - * @param definition The {@link CustomTraceDefinition} of the trace for which you want the columns - * @return The set of columns for the given trace. - */ - public static Collection generateColumns(CustomTraceDefinition definition) { - ImmutableList.Builder builder = new ImmutableList.Builder<>(); - List outputs = definition.outputs; - for (int i = 0; i < outputs.size(); i++) { - String name = outputs.get(i).name; - if (name != null) { - builder.add(new CustomEventTableColumn(name, i)); - } - } - return builder.build(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomTxtParserInputWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomTxtParserInputWizardPage.java deleted file mode 100644 index c34dc77f3c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomTxtParserInputWizardPage.java +++ /dev/null @@ -1,1681 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.parsers.wizards; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URL; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Scanner; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTraceDefinition; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTraceDefinition; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTraceDefinition.Cardinality; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTraceDefinition.InputData; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTraceDefinition.InputLine; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampFormat; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.browser.Browser; -import org.eclipse.swt.browser.TitleEvent; -import org.eclipse.swt.browser.TitleListener; -import org.eclipse.swt.custom.SashForm; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.custom.StyleRange; -import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.events.VerifyEvent; -import org.eclipse.swt.events.VerifyListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.osgi.framework.Bundle; - -/** - * Input wizard page for custom text parsers. - * - * @author Patrick Tasse - */ -public class CustomTxtParserInputWizardPage extends WizardPage { - - private static final String DEFAULT_REGEX = "\\s*(.*\\S)"; //$NON-NLS-1$ - private static final String DEFAULT_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; //$NON-NLS-1$ - private static final String TIMESTAMP_FORMAT_BUNDLE = "org.eclipse.linuxtools.lttng.help"; //$NON-NLS-1$ - private static final String TIMESTAMP_FORMAT_PATH = "reference/api/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestampFormat.html"; //$NON-NLS-1$ - private static final String PATTERN_URL = "http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#sum"; //$NON-NLS-1$ - private static final Image LINE_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/line_icon.gif"); //$NON-NLS-1$ - private static final Image ADD_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/add_button.gif"); //$NON-NLS-1$ - private static final Image ADD_NEXT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/addnext_button.gif"); //$NON-NLS-1$ - private static final Image ADD_CHILD_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/addchild_button.gif"); //$NON-NLS-1$ - private static final Image DELETE_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/delete_button.gif"); //$NON-NLS-1$ - private static final Image MOVE_UP_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/moveup_button.gif"); //$NON-NLS-1$ - private static final Image MOVE_DOWN_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/movedown_button.gif"); //$NON-NLS-1$ - private static final Image HELP_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/help_button.gif"); //$NON-NLS-1$ - private static final Color COLOR_BLACK = Display.getDefault().getSystemColor(SWT.COLOR_BLACK); - private static final Color COLOR_LIGHT_GREEN = new Color(Display.getDefault(), 192, 255, 192); - private static final Color COLOR_GREEN = Display.getDefault().getSystemColor(SWT.COLOR_GREEN); - private static final Color COLOR_LIGHT_YELLOW = new Color(Display.getDefault(), 255, 255, 192); - private static final Color COLOR_YELLOW = Display.getDefault().getSystemColor(SWT.COLOR_YELLOW); - private static final Color COLOR_LIGHT_MAGENTA = new Color(Display.getDefault(), 255, 192, 255); - private static final Color COLOR_MAGENTA = Display.getDefault().getSystemColor(SWT.COLOR_MAGENTA); - private static final Color COLOR_LIGHT_RED = new Color(Display.getDefault(), 255, 192, 192); - private static final Color COLOR_TEXT_BACKGROUND = Display.getDefault().getSystemColor(SWT.COLOR_WHITE); - private static final Color COLOR_WIDGET_BACKGROUND = Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); - - private final ISelection selection; - private CustomTxtTraceDefinition definition; - private String editCategoryName; - private String editDefinitionName; - private String defaultDescription; - private Line selectedLine; - private Composite container; - private Text categoryText; - private Text logtypeText; - private Text timestampOutputFormatText; - private Text timestampPreviewText; - private ScrolledComposite lineScrolledComposite; - private TreeViewer treeViewer; - private Composite lineContainer; - private StyledText inputText; - private Font fixedFont; - private UpdateListener updateListener; - private Browser helpBrowser; - - // variables used recursively through line traversal - private String timeStampFormat; - private boolean timestampFound; - - /** - * Constructor - * - * @param selection - * The Selection object - * @param definition - * The trace definition - */ - protected CustomTxtParserInputWizardPage(ISelection selection, - CustomTxtTraceDefinition definition) { - super("CustomParserWizardPage"); //$NON-NLS-1$ - if (definition == null) { - setTitle(Messages.CustomTxtParserInputWizardPage_windowTitleNew); - defaultDescription = Messages.CustomTxtParserInputWizardPage_descriptionNew; - } else { - setTitle(Messages.CustomTxtParserInputWizardPage_windowTitleEdit); - defaultDescription = Messages.CustomTxtParserInputWizardPage_desccriptionEdit; - } - setDescription(defaultDescription); - this.selection = selection; - this.definition = definition; - if (definition != null) { - this.editCategoryName = definition.categoryName; - this.editDefinitionName = definition.definitionName; - } - } - - @Override - public void createControl(Composite parent) { - container = new Composite(parent, SWT.NULL); - container.setLayout(new GridLayout()); - - updateListener = new UpdateListener(); - - Composite headerComposite = new Composite(container, SWT.FILL); - GridLayout headerLayout = new GridLayout(5, false); - headerLayout.marginHeight = 0; - headerLayout.marginWidth = 0; - headerComposite.setLayout(headerLayout); - headerComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - Label categoryLabel = new Label(headerComposite, SWT.NULL); - categoryLabel.setText(Messages.CustomTxtParserInputWizardPage_category); - - categoryText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE); - categoryText.setLayoutData(new GridData(120, SWT.DEFAULT)); - - Label timestampFormatLabel = new Label(headerComposite, SWT.NULL); - timestampFormatLabel.setText(Messages.CustomTxtParserInputWizardPage_timestampFormat); - - timestampOutputFormatText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE); - timestampOutputFormatText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - timestampOutputFormatText.setText(DEFAULT_TIMESTAMP_FORMAT); - - Button timeStampFormatHelpButton = new Button(headerComposite, SWT.PUSH); - timeStampFormatHelpButton.setImage(HELP_IMAGE); - timeStampFormatHelpButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_timestampFormatHelp); - timeStampFormatHelpButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - Bundle plugin = Platform.getBundle(TIMESTAMP_FORMAT_BUNDLE); - IPath path = new Path(TIMESTAMP_FORMAT_PATH); - URL fileURL = FileLocator.find(plugin, path, null); - try { - URL pageURL = FileLocator.toFileURL(fileURL); - openHelpShell(pageURL.toString()); - } catch (IOException e1) { - } - } - }); - - Label logtypeLabel = new Label(headerComposite, SWT.NULL); - logtypeLabel.setText(Messages.CustomTxtParserInputWizardPage_logType); - - logtypeText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE); - logtypeText.setLayoutData(new GridData(120, SWT.DEFAULT)); - logtypeText.setFocus(); - - Label timestampPreviewLabel = new Label(headerComposite, SWT.NULL); - timestampPreviewLabel.setText(Messages.CustomTxtParserInputWizardPage_preview); - - timestampPreviewText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); - timestampPreviewText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); - timestampPreviewText.setText(Messages.CustomTxtParserInputWizardPage_noMatchingTimestamp); - - Composite buttonBar = new Composite(container, SWT.NONE); - GridLayout buttonBarLayout = new GridLayout(5, false); - buttonBarLayout.marginHeight = 0; - buttonBarLayout.marginWidth = 0; - buttonBar.setLayout(buttonBarLayout); - - Button removeButton = new Button(buttonBar, SWT.PUSH); - removeButton.setImage(DELETE_IMAGE); - removeButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_removeLine); - removeButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (treeViewer.getSelection().isEmpty() || selectedLine == null) { - return; - } - removeLine(); - InputLine inputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); - if (inputLine.parentInput == null) { - definition.inputs.remove(inputLine); - } else { - inputLine.parentInput.childrenInputs.remove(inputLine); - } - treeViewer.refresh(); - validate(); - updatePreviews(); - } - }); - Button addNextButton = new Button(buttonBar, SWT.PUSH); - addNextButton.setImage(ADD_NEXT_IMAGE); - addNextButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_addNextLine); - addNextButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - InputLine inputLine = new InputLine(Cardinality.ZERO_OR_MORE, "", null); //$NON-NLS-1$ - if (((List) treeViewer.getInput()).size() == 0) { - definition.inputs.add(inputLine); - } else if (treeViewer.getSelection().isEmpty()) { - return; - } else { - InputLine previousInputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); - if (previousInputLine.parentInput == null) { - for (int i = 0; i < definition.inputs.size(); i++) { - if (definition.inputs.get(i).equals(previousInputLine)) { - definition.inputs.add(i + 1, inputLine); - } - } - } else { - previousInputLine.addNext(inputLine); - } - } - treeViewer.refresh(); - treeViewer.setSelection(new StructuredSelection(inputLine), true); - } - }); - Button addChildButton = new Button(buttonBar, SWT.PUSH); - addChildButton.setImage(ADD_CHILD_IMAGE); - addChildButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_addChildLine); - addChildButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - InputLine inputLine = new InputLine(Cardinality.ZERO_OR_MORE, "", null); //$NON-NLS-1$ - if (((List) treeViewer.getInput()).size() == 0) { - definition.inputs.add(inputLine); - } else if (treeViewer.getSelection().isEmpty()) { - return; - } else { - InputLine parentInputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); - parentInputLine.addChild(inputLine); - } - treeViewer.refresh(); - treeViewer.setSelection(new StructuredSelection(inputLine), true); - } - }); - Button moveUpButton = new Button(buttonBar, SWT.PUSH); - moveUpButton.setImage(MOVE_UP_IMAGE); - moveUpButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_moveUp); - moveUpButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (treeViewer.getSelection().isEmpty()) { - return; - } - InputLine inputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); - if (inputLine.parentInput == null) { - for (int i = 1; i < definition.inputs.size(); i++) { - if (definition.inputs.get(i).equals(inputLine)) { - definition.inputs.add(i - 1, definition.inputs.remove(i)); - break; - } - } - } else { - inputLine.moveUp(); - } - treeViewer.refresh(); - validate(); - updatePreviews(); - } - }); - Button moveDownButton = new Button(buttonBar, SWT.PUSH); - moveDownButton.setImage(MOVE_DOWN_IMAGE); - moveDownButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_moveDown); - moveDownButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (treeViewer.getSelection().isEmpty()) { - return; - } - InputLine inputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); - if (inputLine.parentInput == null) { - for (int i = 0; i < definition.inputs.size() - 1; i++) { - if (definition.inputs.get(i).equals(inputLine)) { - definition.inputs.add(i + 1, definition.inputs.remove(i)); - break; - } - } - } else { - inputLine.moveDown(); - } - treeViewer.refresh(); - validate(); - updatePreviews(); - } - }); - - SashForm vSash = new SashForm(container, SWT.VERTICAL); - vSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - vSash.setBackground(vSash.getDisplay().getSystemColor(SWT.COLOR_GRAY)); - - SashForm hSash = new SashForm(vSash, SWT.HORIZONTAL); - hSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - ScrolledComposite treeScrolledComposite = new ScrolledComposite(hSash, SWT.V_SCROLL | SWT.H_SCROLL); - GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); - gd.heightHint = 200; - gd.widthHint = 200; - treeScrolledComposite.setLayoutData(gd); - Composite treeContainer = new Composite(treeScrolledComposite, SWT.NONE); - treeContainer.setLayout(new FillLayout()); - treeScrolledComposite.setContent(treeContainer); - treeScrolledComposite.setExpandHorizontal(true); - treeScrolledComposite.setExpandVertical(true); - - treeViewer = new TreeViewer(treeContainer, SWT.SINGLE | SWT.BORDER); - treeViewer.setContentProvider(new InputLineTreeNodeContentProvider()); - treeViewer.setLabelProvider(new InputLineTreeLabelProvider()); - treeViewer.addSelectionChangedListener(new InputLineTreeSelectionChangedListener()); - treeContainer.layout(); - - treeScrolledComposite.setMinSize(treeContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, treeContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y); - - lineScrolledComposite = new ScrolledComposite(hSash, SWT.V_SCROLL); - lineScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - lineContainer = new Composite(lineScrolledComposite, SWT.NONE); - GridLayout linesLayout = new GridLayout(); - linesLayout.marginHeight = 1; - linesLayout.marginWidth = 0; - lineContainer.setLayout(linesLayout); - lineScrolledComposite.setContent(lineContainer); - lineScrolledComposite.setExpandHorizontal(true); - lineScrolledComposite.setExpandVertical(true); - - if (definition == null) { - definition = new CustomTxtTraceDefinition(); - definition.inputs.add(new InputLine(Cardinality.ZERO_OR_MORE, DEFAULT_REGEX, - Arrays.asList(new InputData(CustomTraceDefinition.TAG_MESSAGE, CustomTraceDefinition.ACTION_SET)))); - } - loadDefinition(definition); - treeViewer.expandAll(); - lineContainer.layout(); - - categoryText.addModifyListener(updateListener); - logtypeText.addModifyListener(updateListener); - timestampOutputFormatText.addModifyListener(updateListener); - - lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); - - hSash.setWeights(new int[] { 1, 2 }); - - Composite sashBottom = new Composite(vSash, SWT.NONE); - GridLayout sashBottomLayout = new GridLayout(3, false); - sashBottomLayout.marginHeight = 0; - sashBottomLayout.marginWidth = 0; - sashBottom.setLayout(sashBottomLayout); - - Label previewLabel = new Label(sashBottom, SWT.NULL); - previewLabel.setText(Messages.CustomTxtParserInputWizardPage_previewInput); - previewLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - Button highlightAllButton = new Button(sashBottom, SWT.PUSH); - highlightAllButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - highlightAllButton.setText(Messages.CustomTxtParserInputWizardPage_highlightAll); - highlightAllButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - updatePreviews(true); - } - }); - - Button legendButton = new Button(sashBottom, SWT.PUSH); - legendButton.setImage(HELP_IMAGE); - legendButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_previewLegend); - legendButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - legendButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - openLegend(); - } - }); - - inputText = new StyledText(sashBottom, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL); - if (fixedFont == null) { - if (System.getProperty("os.name").contains("Windows")) { //$NON-NLS-1$ //$NON-NLS-2$ - fixedFont = new Font(Display.getCurrent(), new FontData("Courier New", 10, SWT.NORMAL)); //$NON-NLS-1$ - } else { - fixedFont = new Font(Display.getCurrent(), new FontData("Monospace", 10, SWT.NORMAL)); //$NON-NLS-1$ - } - } - inputText.setFont(fixedFont); - gd = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1); - gd.heightHint = inputText.computeSize(SWT.DEFAULT, inputText.getLineHeight() * 4).y; - gd.widthHint = 800; - inputText.setLayoutData(gd); - inputText.setText(getSelectionText()); - inputText.addModifyListener(updateListener); - - vSash.setWeights(new int[] { hSash.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, sashBottom.computeSize(SWT.DEFAULT, SWT.DEFAULT).y }); - - setControl(container); - - validate(); - updatePreviews(); - } - - private static class InputLineTreeNodeContentProvider implements ITreeContentProvider { - - @Override - public Object[] getElements(Object inputElement) { - return ((List) inputElement).toArray(); - } - - @Override - public Object[] getChildren(Object parentElement) { - InputLine inputLine = (InputLine) parentElement; - if (inputLine.childrenInputs == null) { - return new InputLine[0]; - } - return inputLine.childrenInputs.toArray(); - } - - @Override - public boolean hasChildren(Object element) { - InputLine inputLine = (InputLine) element; - return (inputLine.childrenInputs != null && inputLine.childrenInputs.size() > 0); - } - - @Override - public void dispose() { - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - @Override - public Object getParent(Object element) { - InputLine inputLine = (InputLine) element; - return inputLine.parentInput; - } - } - - private class InputLineTreeLabelProvider extends ColumnLabelProvider { - - @Override - public Image getImage(Object element) { - return LINE_IMAGE; - } - - @Override - public String getText(Object element) { - InputLine inputLine = (InputLine) element; - if (inputLine.parentInput == null) { - return "Root Line " + getName(inputLine) + " " + inputLine.cardinality.toString() + " : " + inputLine.getRegex(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - return "Line " + getName(inputLine) + " " + inputLine.cardinality.toString() + " : " + inputLine.getRegex(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - } - - private class InputLineTreeSelectionChangedListener implements ISelectionChangedListener { - @Override - public void selectionChanged(SelectionChangedEvent event) { - if (selectedLine != null) { - selectedLine.dispose(); - } - if (!(event.getSelection().isEmpty()) && event.getSelection() instanceof IStructuredSelection) { - IStructuredSelection sel = (IStructuredSelection) event.getSelection(); - InputLine inputLine = (InputLine) sel.getFirstElement(); - selectedLine = new Line(lineContainer, getName(inputLine), inputLine); - lineContainer.layout(); - lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); - container.layout(); - validate(); - updatePreviews(); - } - } - } - - @Override - public void dispose() { - if (fixedFont != null) { - fixedFont.dispose(); - fixedFont = null; - } - super.dispose(); - } - - private void loadDefinition(CustomTxtTraceDefinition def) { - categoryText.setText(def.categoryName); - logtypeText.setText(def.definitionName); - timestampOutputFormatText.setText(def.timeStampOutputFormat); - treeViewer.setInput(def.inputs); - if (def.inputs.size() > 0) { - InputLine inputLine = def.inputs.get(0); - treeViewer.setSelection(new StructuredSelection(inputLine)); - } - } - - private String getName(InputLine inputLine) { - if (inputLine.parentInput == null) { - return Integer.toString(definition.inputs.indexOf(inputLine) + 1); - } - return getName(inputLine.parentInput) + "." + Integer.toString(inputLine.parentInput.childrenInputs.indexOf(inputLine) + 1); //$NON-NLS-1$ - } - - /** - * Get the global list of input names. - * - * @return The list of input names - */ - public List getInputNames() { - List inputs = new ArrayList<>(); - for (InputLine inputLine : definition.inputs) { - for (String inputName : getInputNames(inputLine)) { - if (!inputs.contains(inputName)) { - inputs.add(inputName); - } - } - } - return inputs; - } - - /** - * Get the list of input names for the given input line. - * - * @param inputLine - * The input line - * @return The list of input names - */ - public List getInputNames(InputLine inputLine) { - List inputs = new ArrayList<>(); - if (inputLine.columns != null) { - for (InputData inputData : inputLine.columns) { - String inputName = inputData.name; - if (!inputs.contains(inputName)) { - inputs.add(inputName); - } - } - } - if (inputLine.childrenInputs != null) { - for (InputLine childInputLine : inputLine.childrenInputs) { - for (String inputName : getInputNames(childInputLine)) { - if (!inputs.contains(inputName)) { - inputs.add(inputName); - } - } - } - } - return inputs; - } - - private void removeLine() { - selectedLine.dispose(); - selectedLine = null; - lineContainer.layout(); - lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); - container.layout(); - } - - private String getSelectionText() { - if (this.selection instanceof IStructuredSelection) { - Object sel = ((IStructuredSelection) this.selection).getFirstElement(); - if (sel instanceof IFile) { - IFile file = (IFile) sel; - BufferedReader reader = null; - try { - reader = new BufferedReader(new InputStreamReader(file.getContents())); - StringBuilder sb = new StringBuilder(); - String line = null; - while ((line = reader.readLine()) != null) { - sb.append(line + "\n"); //$NON-NLS-1$ - } - return sb.toString(); - } catch (CoreException e) { - return ""; //$NON-NLS-1$ - } catch (IOException e) { - return ""; //$NON-NLS-1$ - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException e) { - } - } - } - } - } - return ""; //$NON-NLS-1$ - } - - private void updatePreviews() { - updatePreviews(false); - } - - private void updatePreviews(boolean updateAll) { - if (inputText == null) { - // early update during construction - return; - } - inputText.setStyleRanges(new StyleRange[] {}); - - try (Scanner scanner = new Scanner(inputText.getText());) { - scanner.useDelimiter("\n"); //$NON-NLS-1$ - - int rawPos = 0; - // skip starting delimiters - String skip = scanner.findWithinHorizon("\\A\n+", 0); //$NON-NLS-1$ - if (skip != null) { - rawPos += skip.length(); - } - - timeStampFormat = null; - if (selectedLine != null) { - for (InputGroup input : selectedLine.inputs) { - input.previewText.setText(Messages.CustomTxtParserInputWizardPage_noMathcingLine); - } - } - - Map data = new HashMap<>(); - int rootLineMatches = 0; - String firstEntryTimeStamp = null; - String firstEntryTimeStampInputFormat = null; - String line = null; - boolean lineIsNull = true; // needed because of JDT bug with continue at label - event: while (scanner.hasNext() || !lineIsNull) { - if (rootLineMatches > 0 && !updateAll) { - break; - } - if (line == null) { - line = scanner.next(); - lineIsNull = false; - } - int length = line.length(); - String log = line.replaceAll("\r", ""); //$NON-NLS-1$ //$NON-NLS-2$ - for (InputLine rootInputLine : definition.inputs) { - Pattern pattern; - try { - pattern = rootInputLine.getPattern(); - } catch (PatternSyntaxException e) { - continue; - } - Matcher matcher = pattern.matcher(log); - if (matcher.matches()) { - rootLineMatches++; - inputText.setStyleRange(new StyleRange(rawPos, length, - COLOR_BLACK, COLOR_YELLOW, SWT.ITALIC)); - data = new HashMap<>(); - timeStampFormat = null; - updatePreviewLine(rootInputLine, matcher, data, rawPos, rootLineMatches); - if (rootLineMatches == 1) { - firstEntryTimeStamp = data.get(CustomTraceDefinition.TAG_TIMESTAMP); - firstEntryTimeStampInputFormat = timeStampFormat; - } - HashMap countMap = new HashMap<>(); - InputLine currentInput = null; - if (rootInputLine.childrenInputs != null && rootInputLine.childrenInputs.size() > 0) { - currentInput = rootInputLine.childrenInputs.get(0); - countMap.put(currentInput, 0); - } - rawPos += length + 1; // +1 for \n - while (scanner.hasNext()) { - line = scanner.next(); - length = line.length(); - log = line.replaceAll("\r", ""); //$NON-NLS-1$ //$NON-NLS-2$ - boolean processed = false; - if (currentInput == null) { - for (InputLine input : definition.inputs) { - try { - matcher = input.getPattern().matcher(log); - } catch (PatternSyntaxException e) { - continue; - } - if (matcher.matches()) { - continue event; - } - } - } else { - if (countMap.get(currentInput) >= currentInput.getMinCount()) { - List nextInputs = currentInput.getNextInputs(countMap); - if (nextInputs.size() == 0 || nextInputs.get(nextInputs.size() - 1).getMinCount() == 0) { - for (InputLine input : definition.inputs) { - try { - matcher = input.getPattern().matcher(log); - } catch (PatternSyntaxException e) { - continue; - } - if (matcher.matches()) { - continue event; - } - } - } - for (InputLine input : nextInputs) { - try { - matcher = input.getPattern().matcher(log); - } catch (PatternSyntaxException e) { - continue; - } - if (matcher.matches()) { - inputText.setStyleRange(new StyleRange(rawPos, length, - COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC)); - currentInput = input; - updatePreviewLine(currentInput, matcher, data, rawPos, rootLineMatches); - if (countMap.get(currentInput) == null) { - countMap.put(currentInput, 1); - } else { - countMap.put(currentInput, countMap.get(currentInput) + 1); - } - Iterator iter = countMap.keySet().iterator(); - while (iter.hasNext()) { - InputLine inputLine = iter.next(); - if (inputLine.level > currentInput.level) { - iter.remove(); - } - } - if (currentInput.childrenInputs != null && currentInput.childrenInputs.size() > 0) { - currentInput = currentInput.childrenInputs.get(0); - countMap.put(currentInput, 0); - } else { - if (countMap.get(currentInput) >= currentInput.getMaxCount()) { - if (currentInput.getNextInputs(countMap).size() > 0) { - currentInput = currentInput.getNextInputs(countMap).get(0); - if (countMap.get(currentInput) == null) { - countMap.put(currentInput, 0); - } - iter = countMap.keySet().iterator(); - while (iter.hasNext()) { - InputLine inputLine = iter.next(); - if (inputLine.level > currentInput.level) { - iter.remove(); - } - } - } else { - currentInput = null; - } - } - } - processed = true; - break; - } - } - } - if (!processed && currentInput != null) { - matcher = null; - try { - matcher = currentInput.getPattern().matcher(log); - } catch (PatternSyntaxException e) { - } - if (matcher != null && matcher.matches()) { - inputText.setStyleRange(new StyleRange(rawPos, length, - COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC)); - updatePreviewLine(currentInput, matcher, data, rawPos, rootLineMatches); - countMap.put(currentInput, countMap.get(currentInput) + 1); - if (currentInput.childrenInputs != null && currentInput.childrenInputs.size() > 0) { - currentInput = currentInput.childrenInputs.get(0); - countMap.put(currentInput, 0); - } else { - if (countMap.get(currentInput) >= currentInput.getMaxCount()) { - if (currentInput.getNextInputs(countMap).size() > 0) { - currentInput = currentInput.getNextInputs(countMap).get(0); - if (countMap.get(currentInput) == null) { - countMap.put(currentInput, 0); - } - Iterator iter = countMap.keySet().iterator(); - while (iter.hasNext()) { - InputLine inputLine = iter.next(); - if (inputLine.level > currentInput.level) { - iter.remove(); - } - } - } else { - currentInput = null; - } - } - } - } - } - } - rawPos += length + 1; // +1 for \n - } - - break; - } - } - rawPos += length + 1; // +1 for \n - line = null; - lineIsNull = true; - } - - if (rootLineMatches == 1) { - firstEntryTimeStamp = data.get(CustomTraceDefinition.TAG_TIMESTAMP); - firstEntryTimeStampInputFormat = timeStampFormat; - } - if (firstEntryTimeStamp == null) { - timestampPreviewText.setText(Messages.CustomTxtParserInputWizardPage_noTimestampGroup); - if (selectedLine != null) { - for (InputGroup group : selectedLine.inputs) { - if (group.tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - timestampPreviewText.setText(Messages.CustomTxtParserInputWizardPage_noMatchingTimestamp); - break; - } - } - } - } else { - try { - TmfTimestampFormat timestampFormat = new TmfTimestampFormat(firstEntryTimeStampInputFormat); - long timestamp = timestampFormat.parseValue(firstEntryTimeStamp); - timestampFormat = new TmfTimestampFormat(timestampOutputFormatText.getText().trim()); - timestampPreviewText.setText(timestampFormat.format(timestamp)); - } catch (ParseException e) { - timestampPreviewText.setText("*parse exception* [" + firstEntryTimeStamp + "] <> [" + firstEntryTimeStampInputFormat + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } catch (IllegalArgumentException e) { - timestampPreviewText.setText("*parse exception* [Illegal Argument: " + e.getMessage() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - } - } - } - - private void updatePreviewLine(InputLine line, Matcher matcher, Map data, int rawPos, int rootLineMatches) { - for (int i = 0; i < line.columns.size(); i++) { - InputData input = line.columns.get(i); - if (i < matcher.groupCount() && matcher.group(i + 1) != null) { - if (line.parentInput == null) { - inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i + 1), matcher.end(i + 1) - matcher.start(i + 1), - COLOR_BLACK, COLOR_GREEN, SWT.BOLD)); - } else { - inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i + 1), matcher.end(i + 1) - matcher.start(i + 1), - COLOR_BLACK, COLOR_LIGHT_GREEN, SWT.BOLD)); - } - String value = matcher.group(i + 1).trim(); - if (selectedLine != null && selectedLine.inputLine.equals(line) && rootLineMatches == 1 && - selectedLine.inputs.get(i).previewText.getText().equals(Messages.CustomTxtParserInputWizardPage_noMatchingLine)) { - selectedLine.inputs.get(i).previewText.setText(value); - } - if (value.length() == 0) { - continue; - } - if (input.action == CustomTraceDefinition.ACTION_SET) { - data.put(input.name, value); - if (input.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - timeStampFormat = input.format; - } - } else if (input.action == CustomTraceDefinition.ACTION_APPEND) { - String s = data.get(input.name); - if (s != null) { - data.put(input.name, s + value); - } else { - data.put(input.name, value); - } - if (input.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - if (timeStampFormat != null) { - timeStampFormat += input.format; - } else { - timeStampFormat = input.format; - } - } - } else if (input.action == CustomTraceDefinition.ACTION_APPEND_WITH_SEPARATOR) { - String s = data.get(input.name); - if (s != null) { - data.put(input.name, s + " | " + value); //$NON-NLS-1$ - } else { - data.put(input.name, value); - } - if (input.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - if (timeStampFormat != null) { - timeStampFormat += " | " + input.format; //$NON-NLS-1$ - } else { - timeStampFormat = input.format; - } - } - } - } else { - if (selectedLine != null && selectedLine.inputLine.equals(line) && rootLineMatches == 1) { - if (selectedLine.inputs.get(i).previewText.getText().equals(Messages.CustomTxtParserInputWizardPage_noMatchingLine)) { - selectedLine.inputs.get(i).previewText.setText(Messages.CustomTxtParserInputWizardPage_noMatchingGroup); - } - } - } - } - // highlight the matching groups that have no corresponponding input - for (int i = line.columns.size(); i < matcher.groupCount(); i++) { - if (matcher.group(i + 1) != null) { - if (line.parentInput == null) { - inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i + 1), matcher.end(i + 1) - matcher.start(i + 1), - COLOR_BLACK, COLOR_MAGENTA)); - } else { - inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i + 1), matcher.end(i + 1) - matcher.start(i + 1), - COLOR_BLACK, COLOR_LIGHT_MAGENTA)); - } - } - } - } - - private void openHelpShell(String url) { - if (helpBrowser != null && !helpBrowser.isDisposed()) { - helpBrowser.getShell().setActive(); - if (!helpBrowser.getUrl().equals(url)) { - helpBrowser.setUrl(url); - } - return; - } - final Shell helpShell = new Shell(getShell(), SWT.SHELL_TRIM); - helpShell.setLayout(new FillLayout()); - helpBrowser = new Browser(helpShell, SWT.NONE); - helpBrowser.addTitleListener(new TitleListener() { - @Override - public void changed(TitleEvent event) { - helpShell.setText(event.title); - } - }); - Rectangle r = container.getBounds(); - Point p = container.toDisplay(r.x, r.y); - Rectangle trim = helpShell.computeTrim(p.x + (r.width - 750) / 2, p.y + (r.height - 400) / 2, 750, 400); - helpShell.setBounds(trim); - helpShell.open(); - helpBrowser.setUrl(url); - } - - private void openLegend() { - final String cg = Messages.CustomTxtParserInputWizardPage_capturedGroup; - final String ucg = Messages.CustomTxtParserInputWizardPage_unidentifiedCaptureGroup; - final String ut = Messages.CustomTxtParserInputWizardPage_uncapturedText; - int line1start = 0; - String line1 = Messages.CustomTxtParserInputWizardPage_nonMatchingLine; - int line2start = line1start + line1.length(); - String line2 = Messages.CustomTxtParserInputWizardPage_matchingRootLine + ' ' + cg + ' ' + ucg + ' ' + ut + " \n"; //$NON-NLS-1$ - int line3start = line2start + line2.length(); - String line3 = Messages.CustomTxtParserInputWizardPage_matchingOtherLine + ' ' + cg + ' ' + ucg + ' ' + ut + " \n"; //$NON-NLS-1$ - int line4start = line3start + line3.length(); - String line4 = Messages.CustomTxtParserInputWizardPage_matchingOtherLine + ' ' + cg + ' ' + ucg + ' ' + ut + " \n"; //$NON-NLS-1$ - int line5start = line4start + line4.length(); - String line5 = Messages.CustomTxtParserInputWizardPage_nonMatchingLine; - int line6start = line5start + line5.length(); - String line6 = Messages.CustomTxtParserInputWizardPage_matchingRootLine + cg + ' ' + ucg + ' ' + ut + " \n"; //$NON-NLS-1$ - - final Shell legendShell = new Shell(getShell(), SWT.DIALOG_TRIM); - legendShell.setLayout(new FillLayout()); - StyledText legendText = new StyledText(legendShell, SWT.MULTI); - legendText.setFont(fixedFont); - legendText.setText(line1 + line2 + line3 + line4 + line5 + line6); - legendText.setStyleRange(new StyleRange(line2start, line2.length(), COLOR_BLACK, COLOR_YELLOW, SWT.ITALIC)); - legendText.setStyleRange(new StyleRange(line3start, line3.length(), COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC)); - legendText.setStyleRange(new StyleRange(line4start, line4.length(), COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC)); - legendText.setStyleRange(new StyleRange(line6start, line6.length(), COLOR_BLACK, COLOR_YELLOW, SWT.ITALIC)); - legendText.setStyleRange(new StyleRange(line2start + line2.indexOf(cg), cg.length(), COLOR_BLACK, COLOR_GREEN, SWT.BOLD)); - legendText.setStyleRange(new StyleRange(line2start + line2.indexOf(ucg), ucg.length(), COLOR_BLACK, COLOR_MAGENTA)); - legendText.setStyleRange(new StyleRange(line3start + line3.indexOf(cg), cg.length(), COLOR_BLACK, COLOR_LIGHT_GREEN, SWT.BOLD)); - legendText.setStyleRange(new StyleRange(line3start + line3.indexOf(ucg), ucg.length(), COLOR_BLACK, COLOR_LIGHT_MAGENTA)); - legendText.setStyleRange(new StyleRange(line4start + line4.indexOf(cg), cg.length(), COLOR_BLACK, COLOR_LIGHT_GREEN, SWT.BOLD)); - legendText.setStyleRange(new StyleRange(line4start + line4.indexOf(ucg), ucg.length(), COLOR_BLACK, COLOR_LIGHT_MAGENTA)); - legendText.setStyleRange(new StyleRange(line6start + line6.indexOf(cg), cg.length(), COLOR_BLACK, COLOR_GREEN, SWT.BOLD)); - legendText.setStyleRange(new StyleRange(line6start + line6.indexOf(ucg), ucg.length(), COLOR_BLACK, COLOR_MAGENTA)); - legendShell.setText(Messages.CustomTxtParserInputWizardPage_previewLegend); - legendShell.pack(); - legendShell.open(); - } - - private class UpdateListener implements ModifyListener, SelectionListener { - - @Override - public void modifyText(ModifyEvent e) { - validate(); - updatePreviews(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - validate(); - updatePreviews(); - } - - @Override - public void widgetSelected(SelectionEvent e) { - validate(); - updatePreviews(); - } - - } - - private class Line { - private static final String INFINITY_STRING = "\u221E"; //$NON-NLS-1$ - private InputLine inputLine; - private Group group; - private Composite labelComposite; - private Text regexText; - private Composite cardinalityContainer; - private Combo cardinalityCombo; - private Label cardinalityMinLabel; - private Text cardinalityMinText; - private Label cardinalityMaxLabel; - private Text cardinalityMaxText; - private Button infiniteButton; - private List inputs = new ArrayList<>(); - private Button addGroupButton; - private Label addGroupLabel; - - public Line(Composite parent, String name, InputLine inputLine) { - this.inputLine = inputLine; - - group = new Group(parent, SWT.NONE); - group.setText(name); - group.setLayout(new GridLayout(2, false)); - group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - labelComposite = new Composite(group, SWT.FILL); - GridLayout labelLayout = new GridLayout(1, false); - labelLayout.marginWidth = 0; - labelLayout.marginHeight = 0; - labelComposite.setLayout(labelLayout); - labelComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - - Label label = new Label(labelComposite, SWT.NULL); - label.setText(Messages.CustomTxtParserInputWizardPage_regularExpression); - - Composite regexContainer = new Composite(group, SWT.NONE); - GridLayout regexLayout = new GridLayout(2, false); - regexLayout.marginHeight = 0; - regexLayout.marginWidth = 0; - regexContainer.setLayout(regexLayout); - regexContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - regexText = new Text(regexContainer, SWT.BORDER | SWT.SINGLE); - GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); - gd.widthHint = 0; - regexText.setLayoutData(gd); - regexText.setText(inputLine.getRegex()); - regexText.addModifyListener(updateListener); - - Button regexHelpButton = new Button(regexContainer, SWT.PUSH); - regexHelpButton.setImage(HELP_IMAGE); - regexHelpButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_regularExpressionHelp); - regexHelpButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - openHelpShell(PATTERN_URL); - } - }); - - label = new Label(group, SWT.NONE); - label.setText(Messages.CustomTxtParserInputWizardPage_cardinality); - label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - - cardinalityContainer = new Composite(group, SWT.NONE); - GridLayout cardinalityLayout = new GridLayout(6, false); - cardinalityLayout.marginHeight = 0; - cardinalityLayout.marginWidth = 0; - cardinalityContainer.setLayout(cardinalityLayout); - cardinalityContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - cardinalityCombo = new Combo(cardinalityContainer, SWT.DROP_DOWN | SWT.READ_ONLY); - cardinalityCombo.setItems(new String[] { - Cardinality.ZERO_OR_MORE.toString(), - Cardinality.ONE_OR_MORE.toString(), - Cardinality.ZERO_OR_ONE.toString(), - Cardinality.ONE.toString(), "(?,?)" }); //$NON-NLS-1$ - cardinalityCombo.addSelectionListener(new SelectionListener() { - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - - @Override - public void widgetSelected(SelectionEvent e) { - switch (cardinalityCombo.getSelectionIndex()) { - case 4: // (?,?) - cardinalityMinLabel.setVisible(true); - cardinalityMinText.setVisible(true); - cardinalityMaxLabel.setVisible(true); - cardinalityMaxText.setVisible(true); - infiniteButton.setVisible(true); - break; - default: - cardinalityMinLabel.setVisible(false); - cardinalityMinText.setVisible(false); - cardinalityMaxLabel.setVisible(false); - cardinalityMaxText.setVisible(false); - infiniteButton.setVisible(false); - break; - } - cardinalityContainer.layout(); - validate(); - updatePreviews(); - } - }); - - cardinalityMinLabel = new Label(cardinalityContainer, SWT.NONE); - cardinalityMinLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - cardinalityMinLabel.setText(Messages.CustomTxtParserInputWizardPage_min); - cardinalityMinLabel.setVisible(false); - - cardinalityMinText = new Text(cardinalityContainer, SWT.BORDER | SWT.SINGLE); - gd = new GridData(SWT.CENTER, SWT.CENTER, false, false); - gd.widthHint = 20; - cardinalityMinText.setLayoutData(gd); - cardinalityMinText.setVisible(false); - - cardinalityMaxLabel = new Label(cardinalityContainer, SWT.NONE); - cardinalityMaxLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - cardinalityMaxLabel.setText(Messages.CustomTxtParserInputWizardPage_max); - cardinalityMaxLabel.setVisible(false); - - cardinalityMaxText = new Text(cardinalityContainer, SWT.BORDER | SWT.SINGLE); - gd = new GridData(SWT.CENTER, SWT.CENTER, false, false); - gd.widthHint = 20; - cardinalityMaxText.setLayoutData(gd); - cardinalityMaxText.setVisible(false); - - infiniteButton = new Button(cardinalityContainer, SWT.PUSH); - infiniteButton.setText(INFINITY_STRING); - infiniteButton.setVisible(false); - infiniteButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - cardinalityMaxText.setText(INFINITY_STRING); - } - }); - - if (inputLine.cardinality.equals(Cardinality.ZERO_OR_MORE)) { - cardinalityCombo.select(0); - } else if (inputLine.cardinality.equals(Cardinality.ONE_OR_MORE)) { - cardinalityCombo.select(1); - } else if (inputLine.cardinality.equals(Cardinality.ZERO_OR_ONE)) { - cardinalityCombo.select(2); - } else if (inputLine.cardinality.equals(Cardinality.ONE)) { - cardinalityCombo.select(3); - } else { - cardinalityCombo.select(4); - cardinalityMinLabel.setVisible(true); - cardinalityMinText.setVisible(true); - if (inputLine.getMinCount() >= 0) { - cardinalityMinText.setText(Integer.toString(inputLine.getMinCount())); - } - cardinalityMaxLabel.setVisible(true); - cardinalityMaxText.setVisible(true); - if (inputLine.getMaxCount() == Cardinality.INF) { - cardinalityMaxText.setText(INFINITY_STRING); - } else if (inputLine.getMaxCount() >= 0) { - cardinalityMaxText.setText(Integer.toString(inputLine.getMaxCount())); - } - infiniteButton.setVisible(true); - } - - VerifyListener digitsListener = new VerifyListener() { - @Override - public void verifyText(VerifyEvent e) { - if (e.text.equals(INFINITY_STRING)) { - e.doit = e.widget == cardinalityMaxText && e.start == 0 && e.end == ((Text) e.widget).getText().length(); - } else { - if (((Text) e.widget).getText().equals(INFINITY_STRING)) { - e.doit = e.start == 0 && e.end == ((Text) e.widget).getText().length(); - } - for (int i = 0; i < e.text.length(); i++) { - if (!Character.isDigit(e.text.charAt(i))) { - e.doit = false; - break; - } - } - } - } - }; - - cardinalityMinText.addModifyListener(updateListener); - cardinalityMaxText.addModifyListener(updateListener); - cardinalityMinText.addVerifyListener(digitsListener); - cardinalityMaxText.addVerifyListener(digitsListener); - - if (inputLine.columns != null) { - for (InputData inputData : inputLine.columns) { - InputGroup inputGroup = new InputGroup(group, this, inputs.size() + 1); - if (inputData.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - inputGroup.tagCombo.select(0); - inputGroup.tagText.setText(inputData.format); - inputGroup.tagLabel.setText(Messages.CustomTxtParserInputWizardPage_format); - inputGroup.tagLabel.setVisible(true); - inputGroup.tagText.setVisible(true); - inputGroup.tagText.addModifyListener(updateListener); - } else if (inputData.name.equals(CustomTraceDefinition.TAG_MESSAGE)) { - inputGroup.tagCombo.select(1); - } else { - inputGroup.tagCombo.select(2); - inputGroup.tagText.setText(inputData.name); - inputGroup.tagLabel.setText(Messages.CustomTxtParserInputWizardPage_name); - inputGroup.tagLabel.setVisible(true); - inputGroup.tagText.setVisible(true); - inputGroup.tagText.addModifyListener(updateListener); - } - inputGroup.actionCombo.select(inputData.action); - inputs.add(inputGroup); - } - } - - createAddGroupButton(); - } - - private void createAddGroupButton() { - addGroupButton = new Button(group, SWT.PUSH); - addGroupButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - addGroupButton.setImage(ADD_IMAGE); - addGroupButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_addGroup); - addGroupButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - removeAddGroupButton(); - inputs.add(new InputGroup(group, Line.this, inputs.size() + 1)); - createAddGroupButton(); - lineContainer.layout(); - lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); - group.getParent().layout(); - validate(); - updatePreviews(); - } - }); - - addGroupLabel = new Label(group, SWT.NULL); - addGroupLabel.setText(Messages.CustomTxtParserInputWizardPage_newGroup); - } - - private void removeAddGroupButton() { - addGroupButton.dispose(); - addGroupLabel.dispose(); - } - - private void removeInput(int inputNumber) { - int nb = inputNumber; - if (--nb < inputs.size()) { - inputs.remove(nb).dispose(); - for (int i = nb; i < inputs.size(); i++) { - inputs.get(i).setInputNumber(i + 1); - } - lineContainer.layout(); - lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); - group.getParent().layout(); - } - } - - private void dispose() { - group.dispose(); - } - - private void extractInputs() { - inputLine.setRegex(selectedLine.regexText.getText()); - switch (cardinalityCombo.getSelectionIndex()) { - case 0: - inputLine.cardinality = Cardinality.ZERO_OR_MORE; - break; - case 1: - inputLine.cardinality = Cardinality.ONE_OR_MORE; - break; - case 2: - inputLine.cardinality = Cardinality.ZERO_OR_ONE; - break; - case 3: - inputLine.cardinality = Cardinality.ONE; - break; - case 4: // (?,?) - int min, - max; - try { - min = Integer.parseInt(cardinalityMinText.getText()); - } catch (NumberFormatException e) { - min = -1; - } - try { - if (cardinalityMaxText.getText().equals(INFINITY_STRING)) { - max = Cardinality.INF; - } else { - max = Integer.parseInt(cardinalityMaxText.getText()); - } - } catch (NumberFormatException e) { - max = -1; - } - inputLine.cardinality = new Cardinality(min, max); - break; - default: - inputLine.cardinality = Cardinality.ZERO_OR_MORE; - break; - } - inputLine.columns = new ArrayList<>(inputs.size()); - for (int i = 0; i < inputs.size(); i++) { - InputGroup grp = inputs.get(i); - InputData inputData = new InputData(); - if (grp.tagCombo.getText().equals(CustomTraceDefinition.TAG_OTHER)) { - inputData.name = grp.tagText.getText().trim(); - } else { - inputData.name = grp.tagCombo.getText(); - if (grp.tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - inputData.format = grp.tagText.getText().trim(); - } - } - inputData.action = grp.actionCombo.getSelectionIndex(); - inputLine.columns.add(inputData); - } - } - } - - private class InputGroup { - private Line line; - private int inputNumber; - - // children of parent (must be disposed) - private Composite labelComposite; - private Composite tagComposite; - private Label previewLabel; - private Text previewText; - - // children of labelComposite - private Label inputLabel; - - // children of tagComposite - private Combo tagCombo; - private Label tagLabel; - private Text tagText; - private Combo actionCombo; - - public InputGroup(Composite parent, Line line, int inputNumber) { - this.line = line; - this.inputNumber = inputNumber; - - labelComposite = new Composite(parent, SWT.FILL); - GridLayout labelLayout = new GridLayout(2, false); - labelLayout.marginWidth = 0; - labelLayout.marginHeight = 0; - labelComposite.setLayout(labelLayout); - labelComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - - Button deleteButton = new Button(labelComposite, SWT.PUSH); - deleteButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - deleteButton.setImage(DELETE_IMAGE); - deleteButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_removeGroup); - deleteButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - InputGroup.this.line.removeInput(InputGroup.this.inputNumber); - validate(); - updatePreviews(); - } - }); - - inputLabel = new Label(labelComposite, SWT.NULL); - inputLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - inputLabel.setText(NLS.bind(Messages.CustomTxtParserInputWizardPage_group, inputNumber)); - - tagComposite = new Composite(parent, SWT.FILL); - GridLayout tagLayout = new GridLayout(4, false); - tagLayout.marginWidth = 0; - tagLayout.marginHeight = 0; - tagComposite.setLayout(tagLayout); - tagComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - tagCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY); - tagCombo.setItems(new String[] { CustomTraceDefinition.TAG_TIMESTAMP, - CustomTraceDefinition.TAG_MESSAGE, - CustomTraceDefinition.TAG_OTHER }); - tagCombo.select(1); - tagCombo.addSelectionListener(new SelectionListener() { - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - - @Override - public void widgetSelected(SelectionEvent e) { - tagText.removeModifyListener(updateListener); - switch (tagCombo.getSelectionIndex()) { - case 0: // Time Stamp - tagLabel.setText(Messages.CustomTxtParserInputWizardPage_format); - tagLabel.setVisible(true); - tagText.setVisible(true); - tagText.addModifyListener(updateListener); - break; - case 1: // Message - tagLabel.setVisible(false); - tagText.setVisible(false); - break; - case 2: // Other - tagLabel.setText(Messages.CustomTxtParserInputWizardPage_name); - tagLabel.setVisible(true); - tagText.setVisible(true); - tagText.addModifyListener(updateListener); - break; - case 3: // Continue - tagLabel.setVisible(false); - tagText.setVisible(false); - break; - default: - break; - } - tagComposite.layout(); - validate(); - updatePreviews(); - } - }); - - tagLabel = new Label(tagComposite, SWT.NULL); - tagLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - tagLabel.setVisible(false); - - tagText = new Text(tagComposite, SWT.BORDER | SWT.SINGLE); - GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); - gd.widthHint = 0; - tagText.setLayoutData(gd); - tagText.setVisible(false); - - actionCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY); - actionCombo.setItems(new String[] { Messages.CustomTxtParserInputWizardPage_set, Messages.CustomTxtParserInputWizardPage_append, Messages.CustomTxtParserInputWizardPage_appendWith }); - actionCombo.select(0); - actionCombo.addSelectionListener(updateListener); - - previewLabel = new Label(parent, SWT.NULL); - previewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - previewLabel.setText(Messages.CustomTxtParserInputWizardPage_preview); - - previewText = new Text(parent, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); - gd = new GridData(SWT.FILL, SWT.CENTER, true, false); - gd.widthHint = 0; - previewText.setLayoutData(gd); - previewText.setText(Messages.CustomTxtParserInputWizardPage_noMatch); - previewText.setBackground(COLOR_WIDGET_BACKGROUND); - } - - private void dispose() { - labelComposite.dispose(); - tagComposite.dispose(); - previewLabel.dispose(); - previewText.dispose(); - } - - private void setInputNumber(int inputNumber) { - this.inputNumber = inputNumber; - inputLabel.setText(NLS.bind(Messages.CustomTxtParserInputWizardPage_group, inputNumber)); - labelComposite.layout(); - } - } - - private void validate() { - - definition.categoryName = categoryText.getText().trim(); - definition.definitionName = logtypeText.getText().trim(); - definition.timeStampOutputFormat = timestampOutputFormatText.getText().trim(); - - if (selectedLine != null) { - selectedLine.extractInputs(); - treeViewer.refresh(); - } - - StringBuffer errors = new StringBuffer(); - - if (definition.categoryName.length() == 0) { - errors.append("Enter a category for the new trace type. "); //$NON-NLS-1$ - categoryText.setBackground(COLOR_LIGHT_RED); - } else if (definition.definitionName.length() == 0) { - errors.append("Enter a name for the new trace type. "); //$NON-NLS-1$ - logtypeText.setBackground(COLOR_LIGHT_RED); - } else { - categoryText.setBackground(COLOR_TEXT_BACKGROUND); - logtypeText.setBackground(COLOR_TEXT_BACKGROUND); - if (definition.categoryName.indexOf(':') != -1) { - errors.append("Invalid character ':' in category. "); //$NON-NLS-1$ - categoryText.setBackground(COLOR_LIGHT_RED); - } - if (definition.definitionName.indexOf(':') != -1) { - errors.append("Invalid character ':' in trace type. "); //$NON-NLS-1$ - logtypeText.setBackground(COLOR_LIGHT_RED); - } - for (TraceTypeHelper helper : TmfTraceType.getTraceTypeHelpers()) { - if (definition.categoryName.equals(helper.getCategoryName()) && - definition.definitionName.equals(helper.getName()) && - (editDefinitionName == null || !editDefinitionName.equals(definition.definitionName)) && - (editCategoryName == null || !editCategoryName.equals(definition.categoryName))) { - errors.append("The trace type name already exists. "); //$NON-NLS-1$ - logtypeText.setBackground(COLOR_LIGHT_RED); - break; - } - } - } - - timestampFound = false; - for (int i = 0; i < definition.inputs.size(); i++) { - - InputLine inputLine = definition.inputs.get(i); - String name = Integer.toString(i + 1); - errors.append(validateLine(inputLine, name)); - } - if (timestampFound) { - if (definition.timeStampOutputFormat.length() == 0) { - errors.append("Enter the output format for the Time Stamp field. "); //$NON-NLS-1$ - timestampOutputFormatText.setBackground(COLOR_LIGHT_RED); - } else { - try { - new TmfTimestampFormat(definition.timeStampOutputFormat); - timestampOutputFormatText.setBackground(COLOR_TEXT_BACKGROUND); - } catch (IllegalArgumentException e) { - errors.append("Enter a valid output format for the Time Stamp field [" + e.getMessage() + "]."); //$NON-NLS-1$ //$NON-NLS-2$ - timestampOutputFormatText.setBackground(COLOR_LIGHT_RED); - } - } - - } else { - timestampOutputFormatText.setBackground(COLOR_TEXT_BACKGROUND); - } - - if (errors.length() == 0) { - setDescription(defaultDescription); - setPageComplete(true); - } else { - setDescription(errors.toString()); - setPageComplete(false); - } - } - - /** - * Validate an input line. - * - * @param inputLine - * The line to clean up - * @param name - * The name of the line - * @return The cleaned up line - */ - public StringBuffer validateLine(InputLine inputLine, String name) { - StringBuffer errors = new StringBuffer(); - Line line = null; - if (selectedLine != null && selectedLine.inputLine.equals(inputLine)) { - line = selectedLine; - } - try { - Pattern.compile(inputLine.getRegex()); - if (line != null) { - line.regexText.setBackground(COLOR_TEXT_BACKGROUND); - } - } catch (PatternSyntaxException e) { - errors.append("Enter a valid regular expression (Line " + name + "). "); //$NON-NLS-1$ //$NON-NLS-2$ - if (line != null) { - line.regexText.setBackground(COLOR_LIGHT_RED); - } - } - if (inputLine.getMinCount() == -1) { - errors.append("Enter a minimum value for cardinality (Line " + name + "). "); //$NON-NLS-1$ //$NON-NLS-2$ - if (line != null) { - line.cardinalityMinText.setBackground(COLOR_LIGHT_RED); - } - } else { - if (line != null) { - line.cardinalityMinText.setBackground(COLOR_TEXT_BACKGROUND); - } - } - if (inputLine.getMaxCount() == -1) { - errors.append("Enter a maximum value for cardinality (Line " + name + "). "); //$NON-NLS-1$ //$NON-NLS-2$ - if (line != null) { - line.cardinalityMaxText.setBackground(COLOR_LIGHT_RED); - } - } else if (inputLine.getMinCount() > inputLine.getMaxCount()) { - errors.append("Enter correct (min <= max) values for cardinality (Line " + name + "). "); //$NON-NLS-1$ //$NON-NLS-2$ - if (line != null) { - line.cardinalityMinText.setBackground(COLOR_LIGHT_RED); - } - if (line != null) { - line.cardinalityMaxText.setBackground(COLOR_LIGHT_RED); - } - } else { - if (line != null) { - line.cardinalityMaxText.setBackground(COLOR_TEXT_BACKGROUND); - } - } - for (int i = 0; inputLine.columns != null && i < inputLine.columns.size(); i++) { - InputData inputData = inputLine.columns.get(i); - InputGroup group = null; - if (line != null) { - group = line.inputs.get(i); - } - if (inputData.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - timestampFound = true; - if (inputData.format.length() == 0) { - errors.append("Enter the input format for the Time Stamp (Line " + name + " Group " + (i + 1) + "). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - if (group != null) { - group.tagText.setBackground(COLOR_LIGHT_RED); - } - } else { - try { - new TmfTimestampFormat(inputData.format); - if (group != null) { - group.tagText.setBackground(COLOR_TEXT_BACKGROUND); - } - } catch (IllegalArgumentException e) { - errors.append("Enter a valid input format for the Time Stamp (Line " + name + " Group " + (i + 1) + ") [" + e.getMessage() + "]. "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - if (group != null) { - group.tagText.setBackground(COLOR_LIGHT_RED); - } - } - } - } else if (inputData.name.length() == 0) { - errors.append("Enter a name for the data group (Line " + name + " Group " + (i + 1) + "). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - if (group != null) { - group.tagText.setBackground(COLOR_LIGHT_RED); - } - } else { - if (group != null) { - group.tagText.setBackground(COLOR_TEXT_BACKGROUND); - } - } - } - for (int i = 0; inputLine.childrenInputs != null && i < inputLine.childrenInputs.size(); i++) { - errors.append(validateLine(inputLine.childrenInputs.get(i), name + "." + (i + 1))); //$NON-NLS-1$ - } - return errors; - } - - /** - * Get the trace definition. - * - * @return The trace definition - */ - public CustomTxtTraceDefinition getDefinition() { - return definition; - } - - /** - * Get the raw text of the input. - * - * @return The raw input text - */ - public char[] getInputText() { - return inputText.getText().toCharArray(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomTxtParserOutputWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomTxtParserOutputWizardPage.java deleted file mode 100644 index b93f94c3bc..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomTxtParserOutputWizardPage.java +++ /dev/null @@ -1,340 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.parsers.wizards; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomEventTableColumns; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTraceDefinition.OutputColumn; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTrace; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTraceDefinition; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer; -import org.eclipse.linuxtools.tmf.ui.viewers.events.TmfEventsTable; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.SashForm; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Text; - -/** - * Output wizard page for custom text trace parsers. - * - * @author Patrick Tasse - */ -public class CustomTxtParserOutputWizardPage extends WizardPage { - - private static final Image UP_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/up_button.gif"); //$NON-NLS-1$ - private static final Image DOWN_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/down_button.gif"); //$NON-NLS-1$ - private final CustomTxtParserWizard wizard; - private CustomTxtTraceDefinition definition; - private List outputs = new ArrayList<>(); - private Composite container; - private SashForm sash; - private ScrolledComposite outputsScrolledComposite; - private Composite outputsContainer; - private Composite tableContainer; - private TmfEventsTable previewTable; - private File tmpFile; - - /** - * Constructor - * - * @param wizard - * The wizard to which this page belongs - */ - protected CustomTxtParserOutputWizardPage(final CustomTxtParserWizard wizard) { - super("CustomParserOutputWizardPage"); //$NON-NLS-1$ - setTitle(wizard.inputPage.getTitle()); - setDescription(Messages.CustomTxtParserOutputWizardPage_description); - this.wizard = wizard; - setPageComplete(false); - } - - @Override - public void createControl(final Composite parent) { - container = new Composite(parent, SWT.NULL); - container.setLayout(new GridLayout()); - - sash = new SashForm(container, SWT.VERTICAL); - sash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - sash.setBackground(sash.getDisplay().getSystemColor(SWT.COLOR_GRAY)); - - outputsScrolledComposite = new ScrolledComposite(sash, SWT.V_SCROLL); - outputsScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - outputsContainer = new Composite(outputsScrolledComposite, SWT.NONE); - final GridLayout outputsLayout = new GridLayout(4, false); - outputsLayout.marginHeight = 10; - outputsLayout.marginWidth = 0; - outputsContainer.setLayout(outputsLayout); - outputsScrolledComposite.setContent(outputsContainer); - outputsScrolledComposite.setExpandHorizontal(true); - outputsScrolledComposite.setExpandVertical(true); - - outputsContainer.layout(); - - outputsScrolledComposite.setMinSize(outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-5); - - tableContainer = new Composite(sash, SWT.NONE); - final GridLayout tableLayout = new GridLayout(); - tableLayout.marginHeight = 0; - tableLayout.marginWidth = 0; - tableContainer.setLayout(tableLayout); - previewTable = new TmfEventsTable(tableContainer, 0, CustomEventTableColumns.generateColumns(new CustomTxtTraceDefinition())); - previewTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - if (wizard.definition != null) { - loadDefinition(wizard.definition); - } - setControl(container); - - } - - @Override - public void dispose() { - previewTable.dispose(); - super.dispose(); - } - - private void loadDefinition(final CustomTxtTraceDefinition def) { - for (final OutputColumn outputColumn : def.outputs) { - final Output output = new Output(outputsContainer, outputColumn.name); - outputs.add(output); - } - } - - @Override - public void setVisible(final boolean visible) { - if (visible) { - this.definition = wizard.inputPage.getDefinition(); - final List outputNames = wizard.inputPage.getInputNames(); - - // dispose outputs that have been removed in the input page - final Iterator iter = outputs.iterator(); - while (iter.hasNext()) { - final Output output = iter.next(); - boolean found = false; - for (final String name : outputNames) { - if (output.name.equals(name)) { - found = true; - break; - } - } - if (!found) { - output.dispose(); - iter.remove(); - } - } - - // create outputs that have been added in the input page - for (final String name : outputNames) { - boolean found = false; - for (final Output output : outputs) { - if (output.name.equals(name)) { - found = true; - break; - } - } - if (!found) { - outputs.add(new Output(outputsContainer, name)); - } - } - - outputsContainer.layout(); - outputsScrolledComposite.setMinSize(outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-5); - updatePreviewTable(); - if (sash.getSize().y > outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y + previewTable.getTable().getItemHeight()) { - sash.setWeights(new int[] {outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, sash.getSize().y - outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y}); - } else { - sash.setWeights(new int[] {outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, previewTable.getTable().getItemHeight()}); - } - setPageComplete(true); - } else { - setPageComplete(false); - } - super.setVisible(visible); - } - - private void moveBefore(final Output moved) { - final int i = outputs.indexOf(moved); - if (i > 0) { - final Output previous = outputs.get(i-1); - moved.enabledButton.moveAbove(previous.enabledButton); - moved.nameLabel.moveBelow(moved.enabledButton); - moved.upButton.moveBelow(moved.nameLabel); - moved.downButton.moveBelow(moved.upButton); - outputs.add(i-1, outputs.remove(i)); - outputsContainer.layout(); - outputsScrolledComposite.setMinSize(outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-5); - container.layout(); - updatePreviewTable(); - } - } - - private void moveAfter(final Output moved) { - final int i = outputs.indexOf(moved); - if (i+1 < outputs.size()) { - final Output next = outputs.get(i+1); - moved.enabledButton.moveBelow(next.downButton); - moved.nameLabel.moveBelow(moved.enabledButton); - moved.upButton.moveBelow(moved.nameLabel); - moved.downButton.moveBelow(moved.upButton); - outputs.add(i+1, outputs.remove(i)); - outputsContainer.layout(); - outputsScrolledComposite.setMinSize(outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-5); - container.layout(); - updatePreviewTable(); - } - } - - private void updatePreviewTable() { - final int CACHE_SIZE = 50; - definition.outputs = extractOutputs(); - tmpFile = Activator.getDefault().getStateLocation().addTrailingSeparator().append("customwizard.tmp").toFile(); //$NON-NLS-1$ - - try (final FileWriter writer = new FileWriter(tmpFile);) { - writer.write(wizard.inputPage.getInputText()); - } catch (final IOException e) { - Activator.getDefault().logError("Error creating CustomTxtTrace. File:" + tmpFile.getAbsolutePath(), e); //$NON-NLS-1$ - } - - try { - final CustomTxtTrace trace = new CustomTxtTrace(null, definition, tmpFile.getAbsolutePath(), CACHE_SIZE) { - @Override - protected ITmfTraceIndexer createIndexer(int interval) { - return new TmfCheckpointIndexer(this, interval); - } - }; - trace.getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, false); - previewTable.dispose(); - previewTable = new TmfEventsTable(tableContainer, CACHE_SIZE, CustomEventTableColumns.generateColumns(definition)); - previewTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - previewTable.setTrace(trace, true); - } catch (final TmfTraceException e) { - Activator.getDefault().logError("Error creating CustomTxtTrace. File:" + tmpFile.getAbsolutePath(), e); //$NON-NLS-1$ - } - - tableContainer.layout(); - container.layout(); - } - - /** - * Extract the list of output columns from the page's contents. - * - * @return The output columns - */ - public List extractOutputs() { - int numColumns = 0; - for (int i = 0; i < outputs.size(); i++) { - if (outputs.get(i).enabledButton.getSelection()) { - numColumns++; - } - } - final List outputColumns = new ArrayList<>(numColumns); - numColumns = 0; - for (int i = 0; i < outputs.size(); i++) { - final Output output = outputs.get(i); - if (output.enabledButton.getSelection()) { - final OutputColumn column = new OutputColumn(); - column.name = output.nameLabel.getText(); - outputColumns.add(column); - } - } - return outputColumns; - } - - private class Output { - String name; - Button enabledButton; - Text nameLabel; - Button upButton; - Button downButton; - - public Output(final Composite parent, final String name) { - this.name = name; - - enabledButton = new Button(parent, SWT.CHECK); - enabledButton.setToolTipText(Messages.CustomTxtParserOutputWizardPage_visible); - enabledButton.setSelection(true); - enabledButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(final SelectionEvent e) { - updatePreviewTable(); - } - }); - // if (messageOutput != null) { - // enabledButton.moveAbove(messageOutput.enabledButton); - // } - - nameLabel = new Text(parent, SWT.BORDER | SWT.READ_ONLY | SWT.SINGLE); - nameLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); - nameLabel.setText(name); - nameLabel.moveBelow(enabledButton); - - upButton = new Button(parent, SWT.PUSH); - upButton.setImage(UP_IMAGE); - upButton.setToolTipText(Messages.CustomTxtParserOutputWizardPage_moveBefore); - upButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(final SelectionEvent e) { - moveBefore(Output.this); - } - }); - upButton.moveBelow(nameLabel); - - downButton = new Button(parent, SWT.PUSH); - downButton.setImage(DOWN_IMAGE); - downButton.setToolTipText(Messages.CustomTxtParserOutputWizardPage_moveAfter); - downButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(final SelectionEvent e) { - moveAfter(Output.this); - } - }); - downButton.moveBelow(upButton); - } - - private void dispose() { - enabledButton.dispose(); - nameLabel.dispose(); - upButton.dispose(); - downButton.dispose(); - } - } - - /** - * Get the trace definition. - * - * @return The trace definition - */ - public CustomTxtTraceDefinition getDefinition() { - return definition; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomTxtParserWizard.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomTxtParserWizard.java deleted file mode 100644 index 6c884ea2b8..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomTxtParserWizard.java +++ /dev/null @@ -1,82 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.parsers.wizards; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTraceDefinition; -import org.eclipse.ui.INewWizard; -import org.eclipse.ui.IWorkbench; - -/** - * Wizard for custom text trace parsers. - * - * @author Patrick Tasse - */ -public class CustomTxtParserWizard extends Wizard implements INewWizard { - - CustomTxtParserInputWizardPage inputPage; - CustomTxtParserOutputWizardPage outputPage; - private ISelection selection; - CustomTxtTraceDefinition definition; - String initialCategoryName; - String initialDefinitionName; - - /** - * Default constructor - */ - public CustomTxtParserWizard() { - super(); - } - - /** - * Constructor - * - * @param definition - * The trace definition - */ - public CustomTxtParserWizard(CustomTxtTraceDefinition definition) { - super(); - this.definition = definition; - if (definition != null) { - initialCategoryName = definition.categoryName; - initialDefinitionName = definition.definitionName; - } - } - - @Override - public boolean performFinish() { - CustomTxtTraceDefinition def = outputPage.getDefinition(); - if (definition != null && (!initialCategoryName.equals(def.categoryName) || - !initialDefinitionName.equals(def.definitionName))) { - CustomTxtTraceDefinition.delete(initialCategoryName, initialDefinitionName); - } - def.save(); - return true; - } - - @Override - public void addPages() { - inputPage = new CustomTxtParserInputWizardPage(selection, definition); - addPage(inputPage); - outputPage = new CustomTxtParserOutputWizardPage(this); - addPage(outputPage); - } - - @Override - public void init(IWorkbench workbench, IStructuredSelection sel) { - this.selection = sel; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomXmlParserInputWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomXmlParserInputWizardPage.java deleted file mode 100644 index 69e33ab022..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomXmlParserInputWizardPage.java +++ /dev/null @@ -1,1765 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.parsers.wizards; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.eclipse.jface.viewers.AbstractTreeViewer; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTraceDefinition; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTrace; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition.InputAttribute; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition.InputElement; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampFormat; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.browser.Browser; -import org.eclipse.swt.browser.TitleEvent; -import org.eclipse.swt.browser.TitleListener; -import org.eclipse.swt.custom.SashForm; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.custom.StyleRange; -import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.osgi.framework.Bundle; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.EntityResolver; -import org.xml.sax.ErrorHandler; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -import com.google.common.base.Joiner; - -/** - * Input wizard page for custom XML trace parsers. - * - * @author Patrick Tasse - */ -public class CustomXmlParserInputWizardPage extends WizardPage { - - private static final String DEFAULT_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; //$NON-NLS-1$ - private static final String TIMESTAMP_FORMAT_BUNDLE = "org.eclipse.linuxtools.lttng.help"; //$NON-NLS-1$ - private static final String TIMESTAMP_FORMAT_PATH = "reference/api/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestampFormat.html"; //$NON-NLS-1$ - private static final Image ELEMENT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/element_icon.gif"); //$NON-NLS-1$ - private static final Image ADD_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/add_button.gif"); //$NON-NLS-1$ - private static final Image ADD_NEXT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/addnext_button.gif"); //$NON-NLS-1$ - private static final Image ADD_CHILD_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/addchild_button.gif"); //$NON-NLS-1$ - private static final Image ADD_MANY_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/addmany_button.gif"); //$NON-NLS-1$ - private static final Image DELETE_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/delete_button.gif"); //$NON-NLS-1$ - private static final Image MOVE_UP_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/moveup_button.gif"); //$NON-NLS-1$ - private static final Image MOVE_DOWN_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/movedown_button.gif"); //$NON-NLS-1$ - private static final Image HELP_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/help_button.gif"); //$NON-NLS-1$ - private static final Color COLOR_LIGHT_RED = new Color(Display.getDefault(), 255, 192, 192); - private static final Color COLOR_TEXT_BACKGROUND = Display.getDefault().getSystemColor(SWT.COLOR_WHITE); - private static final Color COLOR_WIDGET_BACKGROUND = Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); - - private final ISelection selection; - private CustomXmlTraceDefinition definition; - private String editCategoryName; - private String editDefinitionName; - private String defaultDescription; - private ElementNode selectedElement; - private Composite container; - private Text categoryText; - private Text logtypeText; - private Text timeStampOutputFormatText; - private Text timeStampPreviewText; - private Button removeButton; - private Button addChildButton; - private Button addNextButton; - private Button moveUpButton; - private Button moveDownButton; - private ScrolledComposite elementScrolledComposite; - private TreeViewer treeViewer; - private Composite elementContainer; - private Text errorText; - private StyledText inputText; - private Font fixedFont; - private UpdateListener updateListener; - private Browser helpBrowser; - private Element documentElement; - - // variables used recursively through element traversal - private String timeStampValue; - private String timeStampFormat; - private boolean timeStampFound; - private int logEntriesCount; - private boolean logEntryFound; - - /** - * Constructor - * - * @param selection - * Selection object - * @param definition - * Trace definition - */ - protected CustomXmlParserInputWizardPage(ISelection selection, CustomXmlTraceDefinition definition) { - super("CustomXmlParserWizardPage"); //$NON-NLS-1$ - if (definition == null) { - setTitle(Messages.CustomXmlParserInputWizardPage_titleNew); - defaultDescription = Messages.CustomXmlParserInputWizardPage_descriptionNew; - } else { - setTitle(Messages.CustomXmlParserInputWizardPage_titleEdit); - defaultDescription = Messages.CustomXmlParserInputWizardPage_descriptionEdit; - } - setDescription(defaultDescription); - this.selection = selection; - this.definition = definition; - if (definition != null) { - this.editCategoryName = definition.categoryName; - this.editDefinitionName = definition.definitionName; - } - } - - @Override - public void createControl(Composite parent) { - container = new Composite(parent, SWT.NULL); - container.setLayout(new GridLayout()); - - updateListener = new UpdateListener(); - - Composite headerComposite = new Composite(container, SWT.FILL); - GridLayout headerLayout = new GridLayout(5, false); - headerLayout.marginHeight = 0; - headerLayout.marginWidth = 0; - headerComposite.setLayout(headerLayout); - headerComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - Label categoryLabel = new Label(headerComposite, SWT.NULL); - categoryLabel.setText(Messages.CustomXmlParserInputWizardPage_category); - - categoryText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE); - categoryText.setLayoutData(new GridData(120, SWT.DEFAULT)); - - Label timeStampFormatLabel = new Label(headerComposite, SWT.NULL); - timeStampFormatLabel.setText(Messages.CustomXmlParserInputWizardPage_timestampFormat); - - timeStampOutputFormatText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE); - timeStampOutputFormatText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - timeStampOutputFormatText.setText(DEFAULT_TIMESTAMP_FORMAT); - - Button timeStampFormatHelpButton = new Button(headerComposite, SWT.PUSH); - timeStampFormatHelpButton.setImage(HELP_IMAGE); - timeStampFormatHelpButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_timestampFormatHelp); - timeStampFormatHelpButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - Bundle plugin = Platform.getBundle(TIMESTAMP_FORMAT_BUNDLE); - IPath path = new Path(TIMESTAMP_FORMAT_PATH); - URL fileURL = FileLocator.find(plugin, path, null); - try { - URL pageURL = FileLocator.toFileURL(fileURL); - openHelpShell(pageURL.toString()); - } catch (IOException e1) { - } - } - }); - - Label logtypeLabel = new Label(headerComposite, SWT.NULL); - logtypeLabel.setText(Messages.CustomXmlParserInputWizardPage_logType); - - logtypeText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE); - logtypeText.setLayoutData(new GridData(120, SWT.DEFAULT)); - logtypeText.setFocus(); - - Label timeStampPreviewLabel = new Label(headerComposite, SWT.NULL); - timeStampPreviewLabel.setText(Messages.CustomXmlParserInputWizardPage_preview); - - timeStampPreviewText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); - timeStampPreviewText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); - timeStampPreviewText.setText("*no time stamp element or attribute*"); //$NON-NLS-1$ - - createButtonBar(); - - SashForm vSash = new SashForm(container, SWT.VERTICAL); - vSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - vSash.setBackground(vSash.getDisplay().getSystemColor(SWT.COLOR_GRAY)); - - SashForm hSash = new SashForm(vSash, SWT.HORIZONTAL); - hSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - ScrolledComposite treeScrolledComposite = new ScrolledComposite(hSash, SWT.V_SCROLL | SWT.H_SCROLL); - treeScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - Composite treeContainer = new Composite(treeScrolledComposite, SWT.NONE); - treeContainer.setLayout(new FillLayout()); - treeScrolledComposite.setContent(treeContainer); - treeScrolledComposite.setExpandHorizontal(true); - treeScrolledComposite.setExpandVertical(true); - - treeViewer = new TreeViewer(treeContainer, SWT.SINGLE | SWT.BORDER); - treeViewer.setContentProvider(new InputElementTreeNodeContentProvider()); - treeViewer.setLabelProvider(new InputElementTreeLabelProvider()); - treeViewer.addSelectionChangedListener(new InputElementTreeSelectionChangedListener()); - treeContainer.layout(); - - treeScrolledComposite - .setMinSize(treeContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, treeContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y); - - elementScrolledComposite = new ScrolledComposite(hSash, SWT.V_SCROLL); - elementScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - elementContainer = new Composite(elementScrolledComposite, SWT.NONE); - GridLayout gl = new GridLayout(); - gl.marginHeight = 1; - gl.marginWidth = 0; - elementContainer.setLayout(gl); - elementScrolledComposite.setContent(elementContainer); - elementScrolledComposite.setExpandHorizontal(true); - elementScrolledComposite.setExpandVertical(true); - - if (definition == null) { - definition = new CustomXmlTraceDefinition(); - } - loadDefinition(definition); - treeViewer.expandAll(); - elementContainer.layout(); - - categoryText.addModifyListener(updateListener); - logtypeText.addModifyListener(updateListener); - timeStampOutputFormatText.addModifyListener(updateListener); - - elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, - elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); - - hSash.setWeights(new int[] { 1, 2 }); - - if (definition.rootInputElement == null) { - removeButton.setEnabled(false); - addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addDocumentElement); - addNextButton.setEnabled(false); - moveUpButton.setEnabled(false); - moveDownButton.setEnabled(false); - } else { // root is selected - addNextButton.setEnabled(false); - } - - Composite sashBottom = new Composite(vSash, SWT.NONE); - GridLayout sashBottomLayout = new GridLayout(2, false); - sashBottomLayout.marginHeight = 0; - sashBottomLayout.marginWidth = 0; - sashBottom.setLayout(sashBottomLayout); - - Label previewLabel = new Label(sashBottom, SWT.NULL); - previewLabel.setText(Messages.CustomXmlParserInputWizardPage_previewInput); - - errorText = new Text(sashBottom, SWT.SINGLE | SWT.READ_ONLY); - errorText.setBackground(COLOR_WIDGET_BACKGROUND); - errorText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - errorText.setVisible(false); - - inputText = new StyledText(sashBottom, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL); - if (fixedFont == null) { - if (System.getProperty("os.name").contains("Windows")) { //$NON-NLS-1$ //$NON-NLS-2$ - fixedFont = new Font(Display.getCurrent(), new FontData("Courier New", 10, SWT.NORMAL)); //$NON-NLS-1$ - } else { - fixedFont = new Font(Display.getCurrent(), new FontData("Monospace", 10, SWT.NORMAL)); //$NON-NLS-1$ - } - } - inputText.setFont(fixedFont); - GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1); - gd.heightHint = inputText.computeSize(SWT.DEFAULT, inputText.getLineHeight() * 4).y; - gd.widthHint = 800; - inputText.setLayoutData(gd); - inputText.setText(getSelectionText()); - inputText.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - parseXmlInput(inputText.getText()); - } - }); - inputText.addModifyListener(updateListener); - - vSash.setWeights(new int[] { hSash.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, sashBottom.computeSize(SWT.DEFAULT, SWT.DEFAULT).y }); - - setControl(container); - } - - private void createButtonBar() { - Composite buttonBar = new Composite(container, SWT.NONE); - GridLayout buttonBarLayout = new GridLayout(6, false); - buttonBarLayout.marginHeight = 0; - buttonBarLayout.marginWidth = 0; - buttonBar.setLayout(buttonBarLayout); - - removeButton = new Button(buttonBar, SWT.PUSH); - removeButton.setImage(DELETE_IMAGE); - removeButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_removeElement); - removeButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (treeViewer.getSelection().isEmpty() || selectedElement == null) { - return; - } - removeElement(); - InputElement inputElement = (InputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); - if (inputElement == definition.rootInputElement) { - definition.rootInputElement = null; - } else { - inputElement.parentElement.childElements.remove(inputElement); - } - treeViewer.refresh(); - validate(); - updatePreviews(); - removeButton.setEnabled(false); - if (definition.rootInputElement == null) { - addChildButton.setEnabled(true); - addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addDocumentEleemnt); - } else { - addChildButton.setEnabled(false); - } - addNextButton.setEnabled(false); - moveUpButton.setEnabled(false); - moveDownButton.setEnabled(false); - } - }); - - addChildButton = new Button(buttonBar, SWT.PUSH); - addChildButton.setImage(ADD_CHILD_IMAGE); - addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addChildElement); - addChildButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - InputElement inputElement = new InputElement("", false, CustomXmlTraceDefinition.TAG_IGNORE, 0, "", null); //$NON-NLS-1$ //$NON-NLS-2$ - if (definition.rootInputElement == null) { - definition.rootInputElement = inputElement; - inputElement.elementName = getChildNameSuggestion(null); - } else if (treeViewer.getSelection().isEmpty()) { - return; - } else { - InputElement parentInputElement = (InputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); - parentInputElement.addChild(inputElement); - inputElement.elementName = getChildNameSuggestion(parentInputElement); - } - treeViewer.refresh(); - treeViewer.setSelection(new StructuredSelection(inputElement), true); - } - }); - - addNextButton = new Button(buttonBar, SWT.PUSH); - addNextButton.setImage(ADD_NEXT_IMAGE); - addNextButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addNextElement); - addNextButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - InputElement inputElement = new InputElement("", false, CustomXmlTraceDefinition.TAG_IGNORE, 0, "", null); //$NON-NLS-1$ //$NON-NLS-2$ - if (definition.rootInputElement == null) { - definition.rootInputElement = inputElement; - inputElement.elementName = getChildNameSuggestion(null); - } else if (treeViewer.getSelection().isEmpty()) { - return; - } else { - InputElement previousInputElement = (InputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); - if (previousInputElement == definition.rootInputElement) { - return; - } - previousInputElement.addNext(inputElement); - inputElement.elementName = getChildNameSuggestion(inputElement.parentElement); - } - treeViewer.refresh(); - treeViewer.setSelection(new StructuredSelection(inputElement), true); - } - }); - - Button feelingLuckyButton = new Button(buttonBar, SWT.PUSH); - feelingLuckyButton.setImage(ADD_MANY_IMAGE); - feelingLuckyButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_feelingLucky); - feelingLuckyButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - InputElement inputElement = null; - if (definition.rootInputElement == null) { - if (getChildNameSuggestion(null).length() != 0) { - inputElement = new InputElement(getChildNameSuggestion(null), false, CustomXmlTraceDefinition.TAG_IGNORE, 0, "", null); //$NON-NLS-1$ - definition.rootInputElement = inputElement; - feelingLucky(inputElement); - } else { - return; - } - } else if (treeViewer.getSelection().isEmpty()) { - return; - } else { - inputElement = (InputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); - feelingLucky(inputElement); - } - treeViewer.refresh(); - treeViewer.setSelection(new StructuredSelection(inputElement), true); - treeViewer.expandToLevel(inputElement, AbstractTreeViewer.ALL_LEVELS); - } - }); - - moveUpButton = new Button(buttonBar, SWT.PUSH); - moveUpButton.setImage(MOVE_UP_IMAGE); - moveUpButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_moveUp); - moveUpButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (treeViewer.getSelection().isEmpty()) { - return; - } - InputElement inputElement = (InputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); - if (inputElement == definition.rootInputElement) { - return; - } - inputElement.moveUp(); - treeViewer.refresh(); - validate(); - updatePreviews(); - } - }); - - moveDownButton = new Button(buttonBar, SWT.PUSH); - moveDownButton.setImage(MOVE_DOWN_IMAGE); - moveDownButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_moveDown); - moveDownButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (treeViewer.getSelection().isEmpty()) { - return; - } - InputElement inputElement = (InputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); - if (inputElement == definition.rootInputElement) { - return; - } - inputElement.moveDown(); - treeViewer.refresh(); - validate(); - updatePreviews(); - } - }); - } - - private void feelingLucky(InputElement inputElement) { - while (true) { - String attributeName = getAttributeNameSuggestion(inputElement); - if (attributeName.length() == 0) { - break; - } - InputAttribute attribute = new InputAttribute(attributeName, attributeName, 0, ""); //$NON-NLS-1$ - inputElement.addAttribute(attribute); - } - while (true) { - String childName = getChildNameSuggestion(inputElement); - if (childName.length() == 0) { - break; - } - InputElement childElement = new InputElement(childName, false, CustomXmlTraceDefinition.TAG_IGNORE, 0, "", null); //$NON-NLS-1$ - inputElement.addChild(childElement); - feelingLucky(childElement); - } - } - - private static class InputElementTreeNodeContentProvider implements ITreeContentProvider { - - @Override - public Object[] getElements(Object inputElement) { - CustomXmlTraceDefinition def = (CustomXmlTraceDefinition) inputElement; - if (def.rootInputElement != null) { - return new Object[] { def.rootInputElement }; - } - return new Object[0]; - } - - @Override - public Object[] getChildren(Object parentElement) { - InputElement inputElement = (InputElement) parentElement; - if (inputElement.childElements == null) { - return new InputElement[0]; - } - return inputElement.childElements.toArray(); - } - - @Override - public boolean hasChildren(Object element) { - InputElement inputElement = (InputElement) element; - return (inputElement.childElements != null && inputElement.childElements.size() > 0); - } - - @Override - public void dispose() { - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - @Override - public Object getParent(Object element) { - InputElement inputElement = (InputElement) element; - return inputElement.parentElement; - } - } - - private static class InputElementTreeLabelProvider extends ColumnLabelProvider { - - @Override - public Image getImage(Object element) { - return ELEMENT_IMAGE; - } - - @Override - public String getText(Object element) { - InputElement inputElement = (InputElement) element; - return (inputElement.elementName.trim().length() == 0) ? "?" : inputElement.elementName; //$NON-NLS-1$ - } - } - - private class InputElementTreeSelectionChangedListener implements ISelectionChangedListener { - @Override - public void selectionChanged(SelectionChangedEvent event) { - if (selectedElement != null) { - selectedElement.dispose(); - } - if (!(event.getSelection().isEmpty()) && event.getSelection() instanceof IStructuredSelection) { - IStructuredSelection sel = (IStructuredSelection) event.getSelection(); - InputElement inputElement = (InputElement) sel.getFirstElement(); - selectedElement = new ElementNode(elementContainer, inputElement); - elementContainer.layout(); - elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, - elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); - container.layout(); - validate(); - updatePreviews(); - removeButton.setEnabled(true); - addChildButton.setEnabled(true); - addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addChildElement); - if (definition.rootInputElement == inputElement) { - addNextButton.setEnabled(false); - } else { - addNextButton.setEnabled(true); - } - moveUpButton.setEnabled(true); - moveDownButton.setEnabled(true); - } else { - removeButton.setEnabled(false); - if (definition.rootInputElement == null) { - addChildButton.setEnabled(true); - addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addDocumentElement); - } else { - addChildButton.setEnabled(false); - } - addNextButton.setEnabled(false); - moveUpButton.setEnabled(false); - moveDownButton.setEnabled(false); - } - } - } - - @Override - public void dispose() { - if (fixedFont != null) { - fixedFont.dispose(); - fixedFont = null; - } - super.dispose(); - } - - private void loadDefinition(CustomXmlTraceDefinition def) { - categoryText.setText(def.categoryName); - logtypeText.setText(def.definitionName); - timeStampOutputFormatText.setText(def.timeStampOutputFormat); - treeViewer.setInput(def); - - if (def.rootInputElement != null) { - treeViewer.setSelection(new StructuredSelection(def.rootInputElement)); - } - } - - private String getName(InputElement inputElement) { - String name = (inputElement.elementName.trim().length() == 0) ? "?" : inputElement.elementName.trim(); //$NON-NLS-1$ - if (inputElement.parentElement == null) { - return name; - } - return getName(inputElement.parentElement) + " : " + name; //$NON-NLS-1$ - } - - private String getName(InputAttribute inputAttribute, InputElement inputElement) { - String name = (inputAttribute.attributeName.trim().length() == 0) ? "?" : inputAttribute.attributeName.trim(); //$NON-NLS-1$ - return getName(inputElement) + " : " + name; //$NON-NLS-1$ - } - - @Override - public void setVisible(boolean visible) { - if (visible) { - validate(); - updatePreviews(); - } - super.setVisible(visible); - } - - /** - * Get the global list of input names. - * - * @return The list of input names - */ - public List getInputNames() { - return getInputNames(definition.rootInputElement); - } - - /** - * Get the list of input names for a given element. - * - * @param inputElement - * The element - * @return The input names for this element - */ - public List getInputNames(InputElement inputElement) { - List inputs = new ArrayList<>(); - if (inputElement.inputName != null && !inputElement.inputName.equals(CustomXmlTraceDefinition.TAG_IGNORE)) { - String inputName = inputElement.inputName; - if (!inputs.contains(inputName)) { - inputs.add(inputName); - } - } - if (inputElement.attributes != null) { - for (InputAttribute attribute : inputElement.attributes) { - String inputName = attribute.inputName; - if (!inputs.contains(inputName)) { - inputs.add(inputName); - } - } - } - if (inputElement.childElements != null) { - for (InputElement childInputElement : inputElement.childElements) { - for (String inputName : getInputNames(childInputElement)) { - if (!inputs.contains(inputName)) { - inputs.add(inputName); - } - } - } - } - return inputs; - } - - private void removeElement() { - selectedElement.dispose(); - selectedElement = null; - elementContainer.layout(); - elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, - elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); - container.layout(); - } - - private String getSelectionText() { - InputStream inputStream = null; - if (this.selection instanceof IStructuredSelection) { - Object sel = ((IStructuredSelection) this.selection).getFirstElement(); - if (sel instanceof IFile) { - IFile file = (IFile) sel; - try { - inputStream = file.getContents(); - } catch (CoreException e) { - return ""; //$NON-NLS-1$ - } - } - } - if (inputStream != null) { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));) { - StringBuilder sb = new StringBuilder(); - String line = null; - while ((line = reader.readLine()) != null) { - sb.append(line + "\n"); //$NON-NLS-1$ - } - parseXmlInput(sb.toString()); - return sb.toString(); - } catch (IOException e) { - return ""; //$NON-NLS-1$ - } - } - return ""; //$NON-NLS-1$ - } - - private void parseXmlInput(final String string) { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - - // The following allows xml parsing without access to the dtd - EntityResolver resolver = new EntityResolver() { - @Override - public InputSource resolveEntity(String publicId, String systemId) { - String empty = ""; //$NON-NLS-1$ - ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); - return new InputSource(bais); - } - }; - db.setEntityResolver(resolver); - - // The following catches xml parsing exceptions - db.setErrorHandler(new ErrorHandler() { - @Override - public void error(SAXParseException saxparseexception) throws SAXException { - } - - @Override - public void warning(SAXParseException saxparseexception) throws SAXException { - } - - @Override - public void fatalError(SAXParseException saxparseexception) throws SAXException { - if (string.trim().length() != 0) { - errorText.setText(saxparseexception.getMessage()); - errorText.setBackground(COLOR_LIGHT_RED); - errorText.setVisible(true); - } - throw saxparseexception; - } - }); - - errorText.setVisible(false); - Document doc = null; - doc = db.parse(new ByteArrayInputStream(string.getBytes())); - documentElement = doc.getDocumentElement(); - } catch (ParserConfigurationException e) { - Activator.getDefault().logError("Error pasing XML input string: " + string, e); //$NON-NLS-1$ - documentElement = null; - } catch (SAXException e) { - documentElement = null; - } catch (IOException e) { - Activator.getDefault().logError("Error pasing XML input string: " + string, e); //$NON-NLS-1$ - documentElement = null; - } - } - - private void initValues() { - timeStampValue = null; - timeStampFormat = null; - logEntriesCount = 0; - logEntryFound = false; - } - - private void updatePreviews() { - if (inputText == null) { - // early update during construction - return; - } - inputText.setStyleRanges(new StyleRange[] {}); - if (selectedElement == null) { - return; - } - - initValues(); - - selectedElement.updatePreview(); - - if (timeStampValue != null && timeStampFormat != null) { - try { - TmfTimestampFormat timestampFormat = new TmfTimestampFormat(timeStampFormat); - long timestamp = timestampFormat.parseValue(timeStampValue); - timestampFormat = new TmfTimestampFormat(timeStampOutputFormatText.getText().trim()); - timeStampPreviewText.setText(timestampFormat.format(timestamp)); - } catch (ParseException e) { - timeStampPreviewText.setText("*parse exception* [" + timeStampValue + "] <> [" + timeStampFormat + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } catch (IllegalArgumentException e) { - timeStampPreviewText.setText("*parse exception* [Illegal Argument]"); //$NON-NLS-1$ - } - } else { - timeStampPreviewText.setText("*no matching time stamp*"); //$NON-NLS-1$ - } - } - - private void openHelpShell(String url) { - if (helpBrowser != null && !helpBrowser.isDisposed()) { - helpBrowser.getShell().setActive(); - if (!helpBrowser.getUrl().equals(url)) { - helpBrowser.setUrl(url); - } - return; - } - final Shell helpShell = new Shell(getShell(), SWT.SHELL_TRIM); - helpShell.setLayout(new FillLayout()); - helpBrowser = new Browser(helpShell, SWT.NONE); - helpBrowser.addTitleListener(new TitleListener() { - @Override - public void changed(TitleEvent event) { - helpShell.setText(event.title); - } - }); - Rectangle r = container.getBounds(); - Point p = container.toDisplay(r.x, r.y); - Rectangle trim = helpShell.computeTrim(p.x + (r.width - 750) / 2, p.y + (r.height - 400) / 2, 750, 400); - helpShell.setBounds(trim); - helpShell.open(); - helpBrowser.setUrl(url); - } - - private class UpdateListener implements ModifyListener, SelectionListener { - - @Override - public void modifyText(ModifyEvent e) { - validate(); - updatePreviews(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - validate(); - updatePreviews(); - } - - @Override - public void widgetSelected(SelectionEvent e) { - validate(); - updatePreviews(); - } - - } - - private class ElementNode { - private final InputElement inputElement; - private final Group group; - private List attributes = new ArrayList<>(); - private List childElements = new ArrayList<>(); - private Text elementNameText; - private Composite tagComposite; - private Combo tagCombo; - private Label tagLabel; - private Text tagText; - private Combo actionCombo; - private Label previewLabel; - private Text previewText; - private Button logEntryButton; - private Label fillerLabel; - private Composite addAttributeComposite; - private Button addAttributeButton; - private Label addAttributeLabel; - - public ElementNode(Composite parent, InputElement inputElement) { - this.inputElement = inputElement; - - group = new Group(parent, SWT.NONE); - GridLayout gl = new GridLayout(2, false); - gl.marginHeight = 0; - group.setLayout(gl); - group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - group.setText(getName(inputElement)); - - Label label = new Label(group, SWT.NULL); - label.setText(Messages.CustomXmlParserInputWizardPage_elementName); - label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - - elementNameText = new Text(group, SWT.BORDER | SWT.SINGLE); - GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); - gd.widthHint = 0; - elementNameText.setLayoutData(gd); - elementNameText.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - ElementNode.this.inputElement.elementName = elementNameText.getText().trim(); - group.setText(getName(ElementNode.this.inputElement)); - } - }); - elementNameText.setText(inputElement.elementName); - elementNameText.addModifyListener(updateListener); - - if (inputElement.parentElement != null) { - previewLabel = new Label(group, SWT.NULL); - previewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - previewLabel.setText(Messages.CustomXmlParserInputWizardPage_preview); - - previewText = new Text(group, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); - gd = new GridData(SWT.FILL, SWT.CENTER, true, false); - gd.widthHint = 0; - previewText.setLayoutData(gd); - previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatchingElement); - previewText.setBackground(COLOR_WIDGET_BACKGROUND); - - logEntryButton = new Button(group, SWT.CHECK); - logEntryButton.setText(Messages.CustomXmlParserInputWizardPage_logEntry); - logEntryButton.setSelection(inputElement.logEntry); - logEntryButton.addSelectionListener(new SelectionListener() { - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - - @Override - public void widgetSelected(SelectionEvent e) { - InputElement parentElem = ElementNode.this.inputElement.parentElement; - while (parentElem != null) { - parentElem.logEntry = false; - parentElem = parentElem.parentElement; - } - } - }); - logEntryButton.addSelectionListener(updateListener); - - tagComposite = new Composite(group, SWT.FILL); - GridLayout tagLayout = new GridLayout(4, false); - tagLayout.marginWidth = 0; - tagLayout.marginHeight = 0; - tagComposite.setLayout(tagLayout); - tagComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - tagCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY); - tagCombo.setItems(new String[] { CustomXmlTraceDefinition.TAG_IGNORE, CustomTraceDefinition.TAG_TIMESTAMP, - CustomTraceDefinition.TAG_MESSAGE, CustomTraceDefinition.TAG_OTHER }); - tagCombo.setVisibleItemCount(tagCombo.getItemCount()); - tagCombo.addSelectionListener(new SelectionListener() { - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - - @Override - public void widgetSelected(SelectionEvent e) { - tagText.removeModifyListener(updateListener); - switch (tagCombo.getSelectionIndex()) { - case 0: // Ignore - tagLabel.setVisible(false); - tagText.setVisible(false); - actionCombo.setVisible(false); - break; - case 1: // Time Stamp - tagLabel.setText(Messages.CustomXmlParserInputWizardPage_format); - tagLabel.setVisible(true); - tagText.setVisible(true); - tagText.addModifyListener(updateListener); - actionCombo.setVisible(true); - break; - case 2: // Message - tagLabel.setVisible(false); - tagText.setVisible(false); - actionCombo.setVisible(true); - break; - case 3: // Other - tagLabel.setText(Messages.CustomXmlParserInputWizardPage_tagName); - tagLabel.setVisible(true); - if (tagText.getText().trim().length() == 0) { - tagText.setText(elementNameText.getText().trim()); - } - tagText.setVisible(true); - tagText.addModifyListener(updateListener); - actionCombo.setVisible(true); - break; - default: - break; - } - tagComposite.layout(); - validate(); - updatePreviews(); - } - }); - - tagLabel = new Label(tagComposite, SWT.NULL); - tagLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - - tagText = new Text(tagComposite, SWT.BORDER | SWT.SINGLE); - gd = new GridData(SWT.FILL, SWT.CENTER, true, false); - gd.widthHint = 0; - tagText.setLayoutData(gd); - - actionCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY); - actionCombo.setItems(new String[] { Messages.CustomXmlParserInputWizardPage_set, Messages.CustomXmlParserInputWizardPage_append, - Messages.CustomXmlParserInputWizardPage_appendWith }); - actionCombo.select(inputElement.inputAction); - actionCombo.addSelectionListener(updateListener); - - if (inputElement.inputName.equals(CustomXmlTraceDefinition.TAG_IGNORE)) { - tagCombo.select(0); - tagLabel.setVisible(false); - tagText.setVisible(false); - actionCombo.setVisible(false); - } else if (inputElement.inputName.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - tagCombo.select(1); - tagLabel.setText(Messages.CustomXmlParserInputWizardPage_format); - tagText.setText(inputElement.inputFormat); - tagText.addModifyListener(updateListener); - } else if (inputElement.inputName.equals(CustomTraceDefinition.TAG_MESSAGE)) { - tagCombo.select(2); - tagLabel.setVisible(false); - tagText.setVisible(false); - } else { - tagCombo.select(3); - tagLabel.setText(Messages.CustomXmlParserInputWizardPage_tagName); - tagText.setText(inputElement.inputName); - tagText.addModifyListener(updateListener); - } - } - - if (inputElement.attributes != null) { - for (InputAttribute inputAttribute : inputElement.attributes) { - Attribute attribute = new Attribute(group, this, inputAttribute, attributes.size() + 1); - attributes.add(attribute); - } - } - - createAddButton(); - } - - private void updatePreview() { - Element element = getPreviewElement(inputElement); - if (inputElement.parentElement != null) { // no preview text for - // document element - previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatchingElement); - if (element != null) { - previewText.setText(CustomXmlTrace.parseElement(element, new StringBuffer()).toString()); - if (logEntryButton.getSelection()) { - if (!logEntryFound) { - logEntryFound = true; - logEntriesCount++; - } else { - logEntryButton.setSelection(false); // remove nested - // log entry - } - } - if (tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP) && logEntriesCount <= 1) { - String value = previewText.getText().trim(); - if (value.length() != 0) { - if (actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_SET) { - timeStampValue = value; - timeStampFormat = tagText.getText().trim(); - } else if (actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_APPEND) { - if (timeStampValue != null) { - timeStampValue += value; - timeStampFormat += tagText.getText().trim(); - } else { - timeStampValue = value; - timeStampFormat = tagText.getText().trim(); - } - } else if (actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_APPEND_WITH_SEPARATOR) { - if (timeStampValue != null) { - timeStampValue += " | " + value; //$NON-NLS-1$ - timeStampFormat += " | " + tagText.getText().trim(); //$NON-NLS-1$ - } else { - timeStampValue = value; - timeStampFormat = tagText.getText().trim(); - } - } - } - } - } - } - for (Attribute attribute : attributes) { - if (element != null) { - String value = element.getAttribute(attribute.attributeNameText.getText().trim()); - if (value.length() != 0) { - attribute.previewText.setText(value); - if (attribute.tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP) && logEntriesCount <= 1) { - if (attribute.actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_SET) { - timeStampValue = value; - timeStampFormat = attribute.tagText.getText().trim(); - } else if (attribute.actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_APPEND) { - if (timeStampValue != null) { - timeStampValue += value; - timeStampFormat += attribute.tagText.getText().trim(); - } else { - timeStampValue = value; - timeStampFormat = attribute.tagText.getText().trim(); - } - } else if (attribute.actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_APPEND_WITH_SEPARATOR) { - if (timeStampValue != null) { - timeStampValue += " | " + value; //$NON-NLS-1$ - timeStampFormat += " | " + attribute.tagText.getText().trim(); //$NON-NLS-1$ - } else { - timeStampValue = value; - timeStampFormat = attribute.tagText.getText().trim(); - } - } - } - } else { - attribute.previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatchingAttribute); - } - } else { - attribute.previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatchingElement); - } - } - for (ElementNode child : childElements) { - child.updatePreview(); - } - if (logEntryButton != null && logEntryButton.getSelection()) { - logEntryFound = false; - } - } - - private void createAddButton() { - fillerLabel = new Label(group, SWT.NONE); - - addAttributeComposite = new Composite(group, SWT.NONE); - addAttributeComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - GridLayout addAttributeLayout = new GridLayout(2, false); - addAttributeLayout.marginHeight = 0; - addAttributeLayout.marginWidth = 0; - addAttributeComposite.setLayout(addAttributeLayout); - - addAttributeButton = new Button(addAttributeComposite, SWT.PUSH); - addAttributeButton.setImage(ADD_IMAGE); - addAttributeButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addAttribute); - addAttributeButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - removeAddButton(); - String attributeName = getAttributeNameSuggestion(inputElement); - InputAttribute inputAttribute = new InputAttribute(attributeName, attributeName, 0, ""); //$NON-NLS-1$ - attributes.add(new Attribute(group, ElementNode.this, inputAttribute, attributes.size() + 1)); - createAddButton(); - elementContainer.layout(); - elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, - elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); - group.getParent().layout(); - validate(); - updatePreviews(); - } - }); - - addAttributeLabel = new Label(addAttributeComposite, SWT.NULL); - addAttributeLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - addAttributeLabel.setText(Messages.CustomXmlParserInputWizardPage_newAttibute); - } - - private void removeAddButton() { - fillerLabel.dispose(); - addAttributeComposite.dispose(); - } - - private void removeAttribute(int attributeNumber) { - int nb = attributeNumber; - if (--nb < attributes.size()) { - attributes.remove(nb).dispose(); - for (int i = nb; i < attributes.size(); i++) { - attributes.get(i).setAttributeNumber(i + 1); - } - elementContainer.layout(); - elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, - elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); - group.getParent().layout(); - } - } - - private void dispose() { - group.dispose(); - } - - private void extractInputs() { - inputElement.elementName = elementNameText.getText().trim(); - if (inputElement.parentElement != null) { - inputElement.logEntry = logEntryButton.getSelection(); - if (tagCombo.getText().equals(CustomTraceDefinition.TAG_OTHER)) { - inputElement.inputName = tagText.getText().trim(); - } else { - inputElement.inputName = tagCombo.getText(); - if (tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - inputElement.inputFormat = tagText.getText().trim(); - } - } - inputElement.inputAction = actionCombo.getSelectionIndex(); - } - inputElement.attributes = new ArrayList<>(attributes.size()); - for (int i = 0; i < attributes.size(); i++) { - Attribute attribute = attributes.get(i); - InputAttribute inputAttribute = new InputAttribute(); - inputAttribute.attributeName = attribute.attributeNameText.getText().trim(); - if (attribute.tagCombo.getText().equals(CustomTraceDefinition.TAG_OTHER)) { - inputAttribute.inputName = attribute.tagText.getText().trim(); - } else { - inputAttribute.inputName = attribute.tagCombo.getText(); - if (attribute.tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - inputAttribute.inputFormat = attribute.tagText.getText().trim(); - } - } - inputAttribute.inputAction = attribute.actionCombo.getSelectionIndex(); - inputElement.addAttribute(inputAttribute); - } - } - } - - private class Attribute { - private ElementNode element; - private int attributeNumber; - - // children of parent (must be disposed) - private Composite labelComposite; - private Composite attributeComposite; - private Label filler; - private Composite tagComposite; - - // children of labelComposite - private Label attributeLabel; - - // children of attributeComposite - private Text attributeNameText; - private Text previewText; - - // children of tagComposite - private Combo tagCombo; - private Label tagLabel; - private Text tagText; - private Combo actionCombo; - - public Attribute(Composite parent, ElementNode element, InputAttribute inputAttribute, int attributeNumber) { - this.element = element; - this.attributeNumber = attributeNumber; - - labelComposite = new Composite(parent, SWT.FILL); - GridLayout labelLayout = new GridLayout(2, false); - labelLayout.marginWidth = 0; - labelLayout.marginHeight = 0; - labelComposite.setLayout(labelLayout); - labelComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - - Button deleteButton = new Button(labelComposite, SWT.PUSH); - deleteButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - deleteButton.setImage(DELETE_IMAGE); - deleteButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_removeAttribute); - deleteButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - Attribute.this.element.removeAttribute(Attribute.this.attributeNumber); - validate(); - updatePreviews(); - } - }); - - attributeLabel = new Label(labelComposite, SWT.NULL); - attributeLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - attributeLabel.setText(Messages.CustomXmlParserInputWizardPage_attibute); - - attributeComposite = new Composite(parent, SWT.FILL); - GridLayout attributeLayout = new GridLayout(4, false); - attributeLayout.marginWidth = 0; - attributeLayout.marginHeight = 0; - attributeComposite.setLayout(attributeLayout); - attributeComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - Label nameLabel = new Label(attributeComposite, SWT.NONE); - nameLabel.setText(Messages.CustomXmlParserInputWizardPage_name); - - attributeNameText = new Text(attributeComposite, SWT.BORDER | SWT.SINGLE); - attributeNameText.setLayoutData(new GridData(120, SWT.DEFAULT)); - attributeNameText.setText(inputAttribute.attributeName); - attributeNameText.addModifyListener(updateListener); - - Label previewLabel = new Label(attributeComposite, SWT.NONE); - previewLabel.setText(Messages.CustomXmlParserInputWizardPage_preview); - - previewText = new Text(attributeComposite, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); - GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); - gd.widthHint = 0; - previewText.setLayoutData(gd); - previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatch); - previewText.setBackground(COLOR_WIDGET_BACKGROUND); - - filler = new Label(parent, SWT.NULL); - - tagComposite = new Composite(parent, SWT.FILL); - GridLayout tagLayout = new GridLayout(4, false); - tagLayout.marginWidth = 0; - tagLayout.marginHeight = 0; - tagComposite.setLayout(tagLayout); - tagComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - tagCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY); - tagCombo.setItems(new String[] { CustomTraceDefinition.TAG_TIMESTAMP, CustomTraceDefinition.TAG_MESSAGE, - CustomTraceDefinition.TAG_OTHER }); - tagCombo.select(2); // Other - tagCombo.addSelectionListener(new SelectionListener() { - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - - @Override - public void widgetSelected(SelectionEvent e) { - tagText.removeModifyListener(updateListener); - switch (tagCombo.getSelectionIndex()) { - case 0: // Time Stamp - tagLabel.setText(Messages.CustomXmlParserInputWizardPage_format); - tagLabel.setVisible(true); - tagText.setVisible(true); - tagText.addModifyListener(updateListener); - break; - case 1: // Message - tagLabel.setVisible(false); - tagText.setVisible(false); - break; - case 2: // Other - tagLabel.setText(Messages.CustomXmlParserInputWizardPage_tagName); - tagLabel.setVisible(true); - if (tagText.getText().trim().length() == 0) { - tagText.setText(attributeNameText.getText().trim()); - } - tagText.setVisible(true); - tagText.addModifyListener(updateListener); - break; - default: - break; - } - tagComposite.layout(); - validate(); - updatePreviews(); - } - }); - - tagLabel = new Label(tagComposite, SWT.NULL); - tagLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - - tagText = new Text(tagComposite, SWT.BORDER | SWT.SINGLE); - gd = new GridData(SWT.FILL, SWT.CENTER, true, false); - gd.widthHint = 0; - tagText.setLayoutData(gd); - tagText.setText(attributeNameText.getText()); - - actionCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY); - actionCombo.setItems(new String[] { Messages.CustomXmlParserInputWizardPage_set, Messages.CustomXmlParserInputWizardPage_append, - Messages.CustomXmlParserInputWizardPage_appendWith }); - actionCombo.select(inputAttribute.inputAction); - actionCombo.addSelectionListener(updateListener); - - if (inputAttribute.inputName.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - tagCombo.select(0); - tagLabel.setText(Messages.CustomXmlParserInputWizardPage_format); - tagText.setText(inputAttribute.inputFormat); - tagText.addModifyListener(updateListener); - } else if (inputAttribute.inputName.equals(CustomTraceDefinition.TAG_MESSAGE)) { - tagCombo.select(1); - tagLabel.setVisible(false); - tagText.setVisible(false); - } else { - tagCombo.select(2); - tagLabel.setText(Messages.CustomXmlParserInputWizardPage_tagName); - tagText.setText(inputAttribute.inputName); - tagText.addModifyListener(updateListener); - } - } - - private void dispose() { - labelComposite.dispose(); - attributeComposite.dispose(); - filler.dispose(); - tagComposite.dispose(); - } - - private void setAttributeNumber(int attributeNumber) { - this.attributeNumber = attributeNumber; - labelComposite.layout(); - } - } - - private Element getPreviewElement(InputElement inputElement) { - InputElement currentElement = inputElement; - Element element = documentElement; - if (element != null) { - if (!documentElement.getNodeName().equals(definition.rootInputElement.elementName)) { - return null; - } - ArrayList elementNames = new ArrayList<>(); - while (currentElement != null) { - elementNames.add(currentElement.elementName); - currentElement = currentElement.parentElement; - } - for (int i = elementNames.size() - 1; --i >= 0;) { - NodeList childList = element.getChildNodes(); - element = null; - for (int j = 0; j < childList.getLength(); j++) { - Node child = childList.item(j); - if (child instanceof Element && child.getNodeName().equals(elementNames.get(i))) { - element = (Element) child; - break; - } - } - if (element == null) { - break; - } - } - if (element != null) { - return element; - } - } - return null; - } - - private String getChildNameSuggestion(InputElement inputElement) { - if (inputElement == null) { - if (documentElement != null) { - return documentElement.getNodeName(); - } - } else { - Element element = getPreviewElement(inputElement); - if (element != null) { - NodeList childNodes = element.getChildNodes(); - for (int i = 0; i < childNodes.getLength(); i++) { - Node node = childNodes.item(i); - if (node instanceof Element) { - boolean unused = true; - if (inputElement.childElements != null) { - for (InputElement child : inputElement.childElements) { - if (child.elementName.equals(node.getNodeName())) { - unused = false; - break; - } - } - } - if (unused) { - return node.getNodeName(); - } - } - } - } - } - return ""; //$NON-NLS-1$ - } - - private String getAttributeNameSuggestion(InputElement inputElement) { - Element element = getPreviewElement(inputElement); - if (element != null) { - NamedNodeMap attributeMap = element.getAttributes(); - for (int i = 0; i < attributeMap.getLength(); i++) { - Node node = attributeMap.item(i); - boolean unused = true; - if (inputElement.attributes != null) { - for (InputAttribute attribute : inputElement.attributes) { - if (attribute.attributeName.equals(node.getNodeName())) { - unused = false; - break; - } - } - } - if (unused) { - return node.getNodeName(); - } - } - } - return ""; //$NON-NLS-1$ - } - - private void validate() { - definition.categoryName = categoryText.getText().trim(); - definition.definitionName = logtypeText.getText().trim(); - definition.timeStampOutputFormat = timeStampOutputFormatText.getText().trim(); - - if (selectedElement != null) { - selectedElement.extractInputs(); - treeViewer.refresh(); - } - - List errors = new ArrayList<>(); - - if (definition.categoryName.length() == 0) { - errors.add(Messages.CustomXmlParserInputWizardPage_emptyCategoryError); - categoryText.setBackground(COLOR_LIGHT_RED); - } else if (definition.definitionName.length() == 0) { - errors.add(Messages.CustomXmlParserInputWizardPage_emptyLogTypeError); - logtypeText.setBackground(COLOR_LIGHT_RED); - } else { - categoryText.setBackground(COLOR_TEXT_BACKGROUND); - logtypeText.setBackground(COLOR_TEXT_BACKGROUND); - if (definition.categoryName.indexOf(':') != -1) { - errors.add(Messages.CustomXmlParserInputWizardPage_invalidCategoryError); - categoryText.setBackground(COLOR_LIGHT_RED); - } - if (definition.definitionName.indexOf(':') != -1) { - errors.add(Messages.CustomXmlParserInputWizardPage_invalidLogTypeError); - logtypeText.setBackground(COLOR_LIGHT_RED); - } - for (TraceTypeHelper helper : TmfTraceType.getTraceTypeHelpers()) { - if (definition.categoryName.equals(helper.getCategoryName()) && - definition.definitionName.equals(helper.getName()) && - (editDefinitionName == null || !editDefinitionName.equals(definition.definitionName)) && - (editCategoryName == null || !editCategoryName.equals(definition.categoryName))) { - errors.add(Messages.CustomXmlParserInputWizardPage_duplicatelogTypeError); - logtypeText.setBackground(COLOR_LIGHT_RED); - break; - } - } - } - - if (definition.rootInputElement == null) { - errors.add(Messages.CustomXmlParserInputWizardPage_noDocumentError); - } - - if (definition.rootInputElement != null) { - logEntryFound = false; - timeStampFound = false; - - errors.addAll(validateElement(definition.rootInputElement)); - - if ((definition.rootInputElement.attributes != null && definition.rootInputElement.attributes.size() != 0) - || (definition.rootInputElement.childElements != null && definition.rootInputElement.childElements.size() != 0) - || errors.size() == 0) { - if (!logEntryFound) { - errors.add(Messages.CustomXmlParserInputWizardPage_missingLogEntryError); - } - - if (timeStampFound) { - if (timeStampOutputFormatText.getText().trim().length() == 0) { - errors.add(Messages.CustomXmlParserInputWizardPage_missingTimestampFmtError); - timeStampOutputFormatText.setBackground(COLOR_LIGHT_RED); - } else { - try { - new TmfTimestampFormat(timeStampOutputFormatText.getText().trim()); - timeStampOutputFormatText.setBackground(COLOR_TEXT_BACKGROUND); - } catch (IllegalArgumentException e) { - errors.add(Messages.CustomXmlParserInputWizardPage_elementInvalidTimestampFmtError); - timeStampOutputFormatText.setBackground(COLOR_LIGHT_RED); - } - } - } else { - timeStampPreviewText.setText(Messages.CustomXmlParserInputWizardPage_noTimestampElementOrAttribute); - } - } - } else { - timeStampPreviewText.setText(Messages.CustomXmlParserInputWizardPage_noTimestampElementOrAttribute); - } - - if (errors.size() == 0) { - setDescription(defaultDescription); - setPageComplete(true); - } else { - setDescription(Joiner.on(' ').join(errors)); - setPageComplete(false); - } - } - - /** - * Clean up the specified XML element. - * - * @param inputElement - * The element to clean up - * @return The validated element - */ - public List validateElement(InputElement inputElement) { - List errors = new ArrayList<>(); - ElementNode elementNode = null; - if (selectedElement != null && selectedElement.inputElement.equals(inputElement)) { - elementNode = selectedElement; - } - if (inputElement == definition.rootInputElement) { - if (inputElement.elementName.length() == 0) { - errors.add(Messages.CustomXmlParserInputWizardPage_missingDocumentElementError); - if (elementNode != null) { - elementNode.elementNameText.setBackground(COLOR_LIGHT_RED); - } - } else { - if (elementNode != null) { - elementNode.elementNameText.setBackground(COLOR_TEXT_BACKGROUND); - } - } - } - if (inputElement != definition.rootInputElement) { - if (inputElement.logEntry) { - logEntryFound = true; - } - if (inputElement.inputName.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - timeStampFound = true; - if (inputElement.inputFormat.length() == 0) { - errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_elementMissingTimestampFmtError, getName(inputElement))); - if (elementNode != null) { - elementNode.tagText.setBackground(COLOR_LIGHT_RED); - } - } else { - try { - new TmfTimestampFormat(inputElement.inputFormat); - if (elementNode != null) { - elementNode.tagText.setBackground(COLOR_TEXT_BACKGROUND); - } - } catch (IllegalArgumentException e) { - errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_elementInvalidTimestampFmtError, getName(inputElement))); - if (elementNode != null) { - elementNode.tagText.setBackground(COLOR_LIGHT_RED); - } - } - } - } else if (inputElement.inputName.length() == 0) { - errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_elementMissingInputNameError, getName(inputElement))); - if (elementNode != null) { - elementNode.tagText.setBackground(COLOR_LIGHT_RED); - } - } else { - if (elementNode != null) { - elementNode.tagText.setBackground(COLOR_TEXT_BACKGROUND); - } - } - } - if (inputElement.attributes != null) { - if (elementNode != null) { - for (Attribute attribute : elementNode.attributes) { - attribute.attributeNameText.setBackground(COLOR_TEXT_BACKGROUND); - } - } - for (int i = 0; i < inputElement.attributes.size(); i++) { - InputAttribute attribute = inputElement.attributes.get(i); - boolean duplicate = false; - for (int j = i + 1; j < inputElement.attributes.size(); j++) { - InputAttribute otherAttribute = inputElement.attributes.get(j); - if (otherAttribute.attributeName.equals(attribute.attributeName)) { - duplicate = true; - if (elementNode != null) { - elementNode.attributes.get(j).attributeNameText.setBackground(COLOR_LIGHT_RED); - } - } - } - if (attribute.attributeName.length() == 0) { - errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_attributeMissingNameError, getName(inputElement))); - if (elementNode != null) { - elementNode.attributes.get(i).attributeNameText.setBackground(COLOR_LIGHT_RED); - } - } else if (duplicate) { - errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_attributeDuplicateNameError, getName(attribute, inputElement))); - if (elementNode != null) { - elementNode.attributes.get(i).attributeNameText.setBackground(COLOR_LIGHT_RED); - } - } - if (attribute.inputName.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { - timeStampFound = true; - if (attribute.inputFormat.length() == 0) { - errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_attributeMissingTimestampFmtError, getName(attribute, inputElement))); - if (elementNode != null) { - elementNode.attributes.get(i).tagText.setBackground(COLOR_LIGHT_RED); - } - } else { - try { - new TmfTimestampFormat(attribute.inputFormat); - if (elementNode != null) { - elementNode.attributes.get(i).tagText.setBackground(COLOR_TEXT_BACKGROUND); - } - } catch (IllegalArgumentException e) { - errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_attributeInvalidTimestampFmtError, getName(attribute, inputElement))); - if (elementNode != null) { - elementNode.attributes.get(i).tagText.setBackground(COLOR_LIGHT_RED); - } - } - } - } else if (attribute.inputName.length() == 0) { - errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_attributeMissingInputNameError, getName(attribute, inputElement))); - if (elementNode != null) { - elementNode.attributes.get(i).tagText.setBackground(COLOR_LIGHT_RED); - } - } else { - if (elementNode != null) { - elementNode.attributes.get(i).tagText.setBackground(COLOR_TEXT_BACKGROUND); - } - } - } - } - if (inputElement.childElements != null) { - for (InputElement child : inputElement.childElements) { - ElementNode childElementNode = null; - if (selectedElement != null && selectedElement.inputElement.equals(child)) { - childElementNode = selectedElement; - } - if (childElementNode != null) { - childElementNode.elementNameText.setBackground(COLOR_TEXT_BACKGROUND); - } - } - for (int i = 0; i < inputElement.childElements.size(); i++) { - InputElement child = inputElement.childElements.get(i); - ElementNode childElementNode = null; - if (selectedElement != null && selectedElement.inputElement.equals(child)) { - childElementNode = selectedElement; - } - if (child.elementName.length() == 0) { - errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_elementMissingNameError, getName(child))); - if (childElementNode != null) { - childElementNode.elementNameText.setBackground(COLOR_LIGHT_RED); - } - } else { - boolean duplicate = false; - for (int j = i + 1; j < inputElement.childElements.size(); j++) { - InputElement otherChild = inputElement.childElements.get(j); - if (otherChild.elementName.equals(child.elementName)) { - duplicate = true; - ElementNode otherChildElementNode = null; - if (selectedElement != null && selectedElement.inputElement.equals(otherChild)) { - otherChildElementNode = selectedElement; - } - if (otherChildElementNode != null) { - otherChildElementNode.elementNameText.setBackground(COLOR_LIGHT_RED); - } - } - } - if (duplicate) { - errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_elementDuplicateNameError, getName(child))); - if (childElementNode != null) { - childElementNode.elementNameText.setBackground(COLOR_LIGHT_RED); - } - } - } - - errors.addAll(validateElement(child)); - } - } - return errors; - } - - /** - * Get the trace definition. - * - * @return The trace definition - */ - public CustomXmlTraceDefinition getDefinition() { - return definition; - } - - /** - * Get the raw text input. - * - * @return The raw text input. - */ - public char[] getInputText() { - return inputText.getText().toCharArray(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomXmlParserOutputWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomXmlParserOutputWizardPage.java deleted file mode 100644 index d8784fcb5c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomXmlParserOutputWizardPage.java +++ /dev/null @@ -1,341 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.parsers.wizards; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomEventTableColumns; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTraceDefinition; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTraceDefinition.OutputColumn; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTrace; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer; -import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer; -import org.eclipse.linuxtools.tmf.ui.viewers.events.TmfEventsTable; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.SashForm; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Text; - -/** - * Output wizard page for custom XML trace parsers. - * - * @author Patrick Tasse - */ -public class CustomXmlParserOutputWizardPage extends WizardPage { - - private static final Image UP_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/up_button.gif"); //$NON-NLS-1$ - private static final Image DOWN_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/down_button.gif"); //$NON-NLS-1$ - private final CustomXmlParserWizard wizard; - private CustomXmlTraceDefinition definition; - private List outputs = new ArrayList<>(); - private Composite container; - private SashForm sash; - private ScrolledComposite outputsScrolledComposite; - private Composite outputsContainer; - private Composite tableContainer; - private TmfEventsTable previewTable; - private File tmpFile; - - /** - * Constructor - * - * @param wizard - * The wizard to which this page belongs - */ - protected CustomXmlParserOutputWizardPage(final CustomXmlParserWizard wizard) { - super("CustomParserOutputWizardPage"); //$NON-NLS-1$ - setTitle(wizard.inputPage.getTitle()); - setDescription(Messages.CustomXmlParserOutputWizardPage_description); - this.wizard = wizard; - setPageComplete(false); - } - - @Override - public void createControl(final Composite parent) { - container = new Composite(parent, SWT.NULL); - container.setLayout(new GridLayout()); - - sash = new SashForm(container, SWT.VERTICAL); - sash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - sash.setBackground(sash.getDisplay().getSystemColor(SWT.COLOR_GRAY)); - - outputsScrolledComposite = new ScrolledComposite(sash, SWT.V_SCROLL); - outputsScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - outputsContainer = new Composite(outputsScrolledComposite, SWT.NONE); - final GridLayout outputsLayout = new GridLayout(4, false); - outputsLayout.marginHeight = 10; - outputsLayout.marginWidth = 0; - outputsContainer.setLayout(outputsLayout); - outputsScrolledComposite.setContent(outputsContainer); - outputsScrolledComposite.setExpandHorizontal(true); - outputsScrolledComposite.setExpandVertical(true); - - outputsContainer.layout(); - - outputsScrolledComposite.setMinSize(outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-5); - - tableContainer = new Composite(sash, SWT.NONE); - final GridLayout tableLayout = new GridLayout(); - tableLayout.marginHeight = 0; - tableLayout.marginWidth = 0; - tableContainer.setLayout(tableLayout); - previewTable = new TmfEventsTable(tableContainer, 0, CustomEventTableColumns.generateColumns(new CustomXmlTraceDefinition())); - previewTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - if (wizard.definition != null) { - loadDefinition(wizard.definition); - } - setControl(container); - - } - - @Override - public void dispose() { - previewTable.dispose(); - super.dispose(); - } - - private void loadDefinition(final CustomTraceDefinition def) { - for (final OutputColumn outputColumn : def.outputs) { - final Output output = new Output(outputsContainer, outputColumn.name); - outputs.add(output); - } - } - - @Override - public void setVisible(final boolean visible) { - if (visible) { - this.definition = wizard.inputPage.getDefinition(); - final List outputNames = wizard.inputPage.getInputNames(); - - // dispose outputs that have been removed in the input page - final Iterator iter = outputs.iterator(); - while (iter.hasNext()) { - final Output output = iter.next(); - boolean found = false; - for (final String name : outputNames) { - if (output.name.equals(name)) { - found = true; - break; - } - } - if (!found) { - output.dispose(); - iter.remove(); - } - } - - // create outputs that have been added in the input page - for (final String name : outputNames) { - boolean found = false; - for (final Output output : outputs) { - if (output.name.equals(name)) { - found = true; - break; - } - } - if (!found) { - outputs.add(new Output(outputsContainer, name)); - } - } - - outputsContainer.layout(); - outputsScrolledComposite.setMinSize(outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-5); - updatePreviewTable(); - if (sash.getSize().y > outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y + previewTable.getTable().getItemHeight()) { - sash.setWeights(new int[] {outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, sash.getSize().y - outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y}); - } else { - sash.setWeights(new int[] {outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, previewTable.getTable().getItemHeight()}); - } - setPageComplete(true); - } else { - setPageComplete(false); - } - super.setVisible(visible); - } - - private void moveBefore(final Output moved) { - final int i = outputs.indexOf(moved); - if (i > 0) { - final Output previous = outputs.get(i-1); - moved.enabledButton.moveAbove(previous.enabledButton); - moved.nameLabel.moveBelow(moved.enabledButton); - moved.upButton.moveBelow(moved.nameLabel); - moved.downButton.moveBelow(moved.upButton); - outputs.add(i-1, outputs.remove(i)); - outputsContainer.layout(); - outputsScrolledComposite.setMinSize(outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-5); - container.layout(); - updatePreviewTable(); - } - } - - private void moveAfter(final Output moved) { - final int i = outputs.indexOf(moved); - if (i+1 < outputs.size()) { - final Output next = outputs.get(i+1); - moved.enabledButton.moveBelow(next.downButton); - moved.nameLabel.moveBelow(moved.enabledButton); - moved.upButton.moveBelow(moved.nameLabel); - moved.downButton.moveBelow(moved.upButton); - outputs.add(i+1, outputs.remove(i)); - outputsContainer.layout(); - outputsScrolledComposite.setMinSize(outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-5); - container.layout(); - updatePreviewTable(); - } - } - - private void updatePreviewTable() { - final int CACHE_SIZE = 50; - definition.outputs = extractOutputs(); - tmpFile = Activator.getDefault().getStateLocation().addTrailingSeparator().append("customwizard.tmp").toFile(); //$NON-NLS-1$ - - try (final FileWriter writer = new FileWriter(tmpFile);) { - writer.write(wizard.inputPage.getInputText()); - } catch (final IOException e) { - Activator.getDefault().logError("Error creating CustomXmlTrace. File:" + tmpFile.getAbsolutePath(), e); //$NON-NLS-1$ - } - - try { - final CustomXmlTrace trace = new CustomXmlTrace(null, definition, tmpFile.getAbsolutePath(), CACHE_SIZE) { - @Override - protected ITmfTraceIndexer createIndexer(int interval) { - return new TmfCheckpointIndexer(this, interval); - } - }; - trace.getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, false); - previewTable.dispose(); - previewTable = new TmfEventsTable(tableContainer, CACHE_SIZE, CustomEventTableColumns.generateColumns(definition)); - previewTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - previewTable.setTrace(trace, true); - } catch (final TmfTraceException e) { - Activator.getDefault().logError("Error creating CustomXmlTrace. File:" + tmpFile.getAbsolutePath(), e); //$NON-NLS-1$ - } - - tableContainer.layout(); - container.layout(); - } - - /** - * Extract the output columns from the page's current contents. - * - * @return The list of output columns - */ - public List extractOutputs() { - int numColumns = 0; - for (int i = 0; i < outputs.size(); i++) { - if (outputs.get(i).enabledButton.getSelection()) { - numColumns++; - } - } - final List outputColumns = new ArrayList<>(numColumns); - numColumns = 0; - for (int i = 0; i < outputs.size(); i++) { - final Output output = outputs.get(i); - if (output.enabledButton.getSelection()) { - final OutputColumn column = new OutputColumn(); - column.name = output.nameLabel.getText(); - outputColumns.add(column); - } - } - return outputColumns; - } - - private class Output { - String name; - Button enabledButton; - Text nameLabel; - Button upButton; - Button downButton; - - public Output(final Composite parent, final String name) { - this.name = name; - - enabledButton = new Button(parent, SWT.CHECK); - enabledButton.setToolTipText(Messages.CustomXmlParserOutputWizardPage_visible); - enabledButton.setSelection(true); - enabledButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(final SelectionEvent e) { - updatePreviewTable(); - } - }); - // if (messageOutput != null) { - // enabledButton.moveAbove(messageOutput.enabledButton); - // } - - nameLabel = new Text(parent, SWT.BORDER | SWT.READ_ONLY | SWT.SINGLE); - nameLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); - nameLabel.setText(name); - nameLabel.moveBelow(enabledButton); - - upButton = new Button(parent, SWT.PUSH); - upButton.setImage(UP_IMAGE); - upButton.setToolTipText(Messages.CustomXmlParserOutputWizardPage_moveBefore); - upButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(final SelectionEvent e) { - moveBefore(Output.this); - } - }); - upButton.moveBelow(nameLabel); - - downButton = new Button(parent, SWT.PUSH); - downButton.setImage(DOWN_IMAGE); - downButton.setToolTipText(Messages.CustomXmlParserOutputWizardPage_moveAfter); - downButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(final SelectionEvent e) { - moveAfter(Output.this); - } - }); - downButton.moveBelow(upButton); - } - - private void dispose() { - enabledButton.dispose(); - nameLabel.dispose(); - upButton.dispose(); - downButton.dispose(); - } - } - - /** - * Get the trace definition. - * - * @return The trace definition - */ - public CustomXmlTraceDefinition getDefinition() { - return definition; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomXmlParserWizard.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomXmlParserWizard.java deleted file mode 100644 index 5da5f43bdc..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/parsers/wizards/CustomXmlParserWizard.java +++ /dev/null @@ -1,86 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.parsers.wizards; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition; -import org.eclipse.ui.INewWizard; -import org.eclipse.ui.IWorkbench; - -/** - * Wizard for custom XML trace parsers. - * - * @author Patrick Tasse - */ -public class CustomXmlParserWizard extends Wizard implements INewWizard { - - CustomXmlParserInputWizardPage inputPage; - CustomXmlParserOutputWizardPage outputPage; - private ISelection selection; - CustomXmlTraceDefinition definition; - String initialCategoryName; - String initialDefinitionName; - - /** - * Default constructor - */ - public CustomXmlParserWizard() { - super(); - } - - /** - * Constructor - * - * @param definition - * The trace definition - */ - public CustomXmlParserWizard(CustomXmlTraceDefinition definition) { - super(); - this.definition = definition; - if (definition != null) { - initialCategoryName = definition.categoryName; - initialDefinitionName = definition.definitionName; - } - } - - @Override - public boolean performFinish() { - CustomXmlTraceDefinition def = outputPage.getDefinition(); - if (definition != null && (!initialCategoryName.equals(def.categoryName) || - !initialDefinitionName.equals(def.definitionName))) { - CustomXmlTraceDefinition.delete(initialCategoryName, initialDefinitionName); - } - def.save(); - return true; - } - - /** - * Adding the page to the wizard. - */ - - @Override - public void addPages() { - inputPage = new CustomXmlParserInputWizardPage(selection, definition); - addPage(inputPage); - outputPage = new CustomXmlParserOutputWizardPage(this); - addPage(outputPage); - } - - @Override - public void init(IWorkbench workbench, IStructuredSelection sel) { - this.selection = sel; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/preferences/TmfTracingPreferencePage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/preferences/TmfTracingPreferencePage.java deleted file mode 100644 index bc6618c0de..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/preferences/TmfTracingPreferencePage.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - ******************************************************************************/ -package org.eclipse.linuxtools.internal.tmf.ui.preferences; - -import org.eclipse.jface.preference.PreferencePage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPreferencePage; - -/** - * Top Level Preference Page for Tracing. - * - * @version 1.0 - * @author Bernd Hufmann - */ -public class TmfTracingPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Override - protected Control createContents(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - // No content yet! - return composite; - } - - @Override - public void init(IWorkbench workbench) { - // Nothing to do yet! - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/Messages.java deleted file mode 100644 index ab451ab7b3..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/Messages.java +++ /dev/null @@ -1,38 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Marc-Andre Laperle - Add select/deselect all - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.dialogs; - -import org.eclipse.osgi.util.NLS; - -/** - * Message bundle for dialog messages. - */ -@SuppressWarnings("javadoc") -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.tmf.ui.project.dialogs.messages"; //$NON-NLS-1$ - - public static String SelectSpplementaryResources_DialogTitle; - public static String SelectSpplementaryResources_ResourcesGroupTitle; - public static String Dialog_SelectAll; - public static String Dialog_DeselectAll; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/SelectSupplementaryResourcesDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/SelectSupplementaryResourcesDialog.java deleted file mode 100644 index e86d836071..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/SelectSupplementaryResourcesDialog.java +++ /dev/null @@ -1,324 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Copied and adapted from NewFolderDialog - * Marc-Andre Laperle - Add select/deselect all - * Patrick Tasse - Add support for folder elements - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.dialogs; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Map.Entry; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IPath; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.viewers.CheckStateChangedEvent; -import org.eclipse.jface.viewers.CheckboxTreeViewer; -import org.eclipse.jface.viewers.ICheckStateListener; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfCommonProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.ui.ISharedImages; -import org.eclipse.ui.PlatformUI; - -import com.google.common.collect.Multimap; - -/** - * SelectSupplementaryResourcesDialog - */ -public class SelectSupplementaryResourcesDialog extends Dialog { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - private static final Image EXPERIMENT_IMAGE = Activator.getDefault().getImageFromPath("icons/elcl16/experiment.gif"); //$NON-NLS-1$ - private static final Image TRACE_IMAGE = Activator.getDefault().getImageFromPath("icons/elcl16/trace.gif"); //$NON-NLS-1$ - private static final Image RESOURCE_IMAGE = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE); - - // ------------------------------------------------------------------------ - // Members - // ------------------------------------------------------------------------ - private CheckboxTreeViewer fTreeViewer; - private final Multimap fResourceMap; - private IResource[] fReturnedResources; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructor. - * - * @param shell - * Parent shell of this dialog - * @param resourceMap - * Map of element to supplementary resources - */ - public SelectSupplementaryResourcesDialog(Shell shell, Multimap resourceMap) { - super(shell); - fResourceMap = resourceMap; - setShellStyle(SWT.RESIZE | getShellStyle()); - } - - // ------------------------------------------------------------------------ - // Getters/Setters - // ------------------------------------------------------------------------ - - /** - * @return A copy of the selected resources - */ - public IResource[] getResources() { - return Arrays.copyOf(fReturnedResources, fReturnedResources.length); - } - - // ------------------------------------------------------------------------ - // Dialog - // ------------------------------------------------------------------------ - - @Override - protected void configureShell(Shell newShell) { - super.configureShell(newShell); - newShell.setText(Messages.SelectSpplementaryResources_DialogTitle); - newShell.setImage(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_ETOOL_DELETE)); - } - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - composite.setLayout(new GridLayout()); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - - Group contextGroup = new Group(composite, SWT.SHADOW_NONE); - contextGroup.setText(Messages.SelectSpplementaryResources_ResourcesGroupTitle); - contextGroup.setLayout(new GridLayout(2, false)); - contextGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); - - fTreeViewer = new CheckboxTreeViewer(contextGroup, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); - GridData data = new GridData(GridData.FILL_BOTH); - Tree tree = fTreeViewer.getTree(); - tree.setLayoutData(data); - fTreeViewer.setContentProvider(new ITreeContentProvider() { - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - @Override - public void dispose() { - } - - @Override - public boolean hasChildren(Object element) { - return element instanceof TmfCommonProjectElement; - } - - @Override - public Object getParent(Object element) { - if (element instanceof IResource) { - getParentElement((IResource) element); - } - return null; - } - - @Override - public Object[] getElements(Object inputElement) { - if (inputElement instanceof Object[]) { - return (Object[]) inputElement; - } - return null; - } - - @Override - public Object[] getChildren(Object parentElement) { - if (parentElement instanceof TmfCommonProjectElement) { - return fResourceMap.get((TmfCommonProjectElement) parentElement).toArray(); - } - return null; - } - }); - - fTreeViewer.setLabelProvider(new LabelProvider() { - @Override - public String getText(Object element) { - if (element instanceof IResource) { - IResource resource = (IResource) element; - TmfCommonProjectElement projectElement = getParentElement(resource); - // remove .tracing/ segments - IPath suppFolderPath = projectElement.getTraceSupplementaryFolder(projectElement.getElementPath()).getFullPath(); - return resource.getFullPath().removeFirstSegments(suppFolderPath.segmentCount()).toString(); - } else if (element instanceof TmfCommonProjectElement) { - TmfCommonProjectElement projectElement = (TmfCommonProjectElement) element; - return projectElement.getElementPath(); - } - return super.getText(element); - } - - @Override - public Image getImage(Object element) { - if (element instanceof IResource) { - return RESOURCE_IMAGE; - } else if (element instanceof TmfTraceElement) { - return TRACE_IMAGE; - } else if (element instanceof TmfExperimentElement) { - return EXPERIMENT_IMAGE; - } - return null; - } - - }); - - fTreeViewer.setInput(fResourceMap.keySet().toArray()); - - fTreeViewer.expandAll(); - setAllChecked(true); - - fTreeViewer.addCheckStateListener(new ICheckStateListener() { - @Override - public void checkStateChanged(CheckStateChangedEvent event) { - if (event.getElement() instanceof TmfCommonProjectElement) { - fTreeViewer.setSubtreeChecked(event.getElement(), event.getChecked()); - fTreeViewer.setGrayed(event.getElement(), false); - } else if (event.getElement() instanceof IResource) { - TmfCommonProjectElement projectElement = getParentElement((IResource) event.getElement()); - int checkedCount = 0; - Collection resources = fResourceMap.get(projectElement); - for (IResource resource : resources) { - if (fTreeViewer.getChecked(resource)) { - checkedCount++; - } - } - if (checkedCount == resources.size()) { - fTreeViewer.setChecked(projectElement, true); - fTreeViewer.setGrayed(projectElement, false); - } else if (checkedCount > 0) { - fTreeViewer.setGrayChecked(projectElement, true); - } else { - fTreeViewer.setGrayChecked(projectElement, false); - } - } - } - }); - - fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() { - @Override - public void selectionChanged(SelectionChangedEvent event) { - updateOKButtonEnablement(); - } - }); - - Composite btComp = new Composite(contextGroup, SWT.NONE); - FillLayout layout = new FillLayout(SWT.VERTICAL); - layout.spacing = 4; - btComp.setLayout(layout); - - GridData gd = new GridData(); - gd.verticalAlignment = SWT.CENTER; - btComp.setLayoutData(gd); - - final Button selectAll = new Button(btComp, SWT.PUSH); - selectAll.setText(Messages.Dialog_SelectAll); - selectAll.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - setAllChecked(true); - - updateOKButtonEnablement(); - } - }); - - final Button deselectAll = new Button(btComp, SWT.PUSH); - deselectAll.setText(Messages.Dialog_DeselectAll); - deselectAll.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - setAllChecked(false); - - updateOKButtonEnablement(); - } - }); - - getShell().setMinimumSize(new Point(300, 150)); - - return composite; - } - - private TmfCommonProjectElement getParentElement(IResource resource) { - for (Entry entry : fResourceMap.entries()) { - if (entry.getValue().equals(resource)) { - return entry.getKey(); - } - } - return null; - } - - private void setAllChecked(boolean state) { - for (Object element : fResourceMap.keySet()) { - fTreeViewer.setSubtreeChecked(element, state); - fTreeViewer.setGrayed(element, false); - } - } - - private void updateOKButtonEnablement() { - Object[] checked = fTreeViewer.getCheckedElements(); - getButton(IDialogConstants.OK_ID).setEnabled(checked.length > 0); - } - - @Override - protected Control createButtonBar(Composite parent) { - Control control = super.createButtonBar(parent); - updateOKButtonEnablement(); - return control; - } - - @Override - protected void createButtonsForButtonBar(Composite parent) { - createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, true); - createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); - } - - @Override - protected void okPressed() { - Object[] checkedElements = fTreeViewer.getCheckedElements(); - List checkedResources = new ArrayList<>(checkedElements.length); - for (Object checked : checkedElements) { - if (checked instanceof IResource) { - checkedResources.add((IResource) checked); - } - } - fReturnedResources = checkedResources.toArray(new IResource[0]); - super.okPressed(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/messages.properties deleted file mode 100644 index 476306e1fd..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/messages.properties +++ /dev/null @@ -1,16 +0,0 @@ -############################################################################### -# Copyright (c) 2012, 2013 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Bernd Hufmann - initial API and implementation -# Marc-Andre Laperle - Add select/deselect all -############################################################################### -SelectSpplementaryResources_DialogTitle=Delete Resources -SelectSpplementaryResources_ResourcesGroupTitle=Select resources to delete -Dialog_SelectAll=Select All -Dialog_DeselectAll=Deselect All \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/offset/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/offset/Messages.java deleted file mode 100644 index f545096a63..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/offset/Messages.java +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.dialogs.offset; - -import org.eclipse.osgi.util.NLS; - -/** - * Messages for the offset dialog - */ -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.tmf.ui.project.dialogs.offset.messages"; //$NON-NLS-1$ - - /** - * Advanced mode button - */ - public static String OffsetDialog_AdvancedButton; - /** - * Advanced mode dialog message - */ - public static String OffsetDialog_AdvancedMessage; - /** - * Basic mode button - */ - public static String OffsetDialog_BasicButton; - /** - * Basic mode dialog message - */ - public static String OffsetDialog_BasicMessage; - /** - * Offset time - */ - public static String OffsetDialog_OffsetTime; - /** - * Reference time - */ - public static String OffsetDialog_ReferenceTime; - /** - * Target time - */ - public static String OffsetDialog_TargetTime; - /** - * Dialog title - */ - public static String OffsetDialog_Title; - /** - * Trace name - */ - public static String OffsetDialog_TraceName; - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/offset/OffsetDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/offset/OffsetDialog.java deleted file mode 100644 index 3789d61442..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/offset/OffsetDialog.java +++ /dev/null @@ -1,578 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.dialogs.offset; - -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Path; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.viewers.CellEditor; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.ColumnViewer; -import org.eclipse.jface.viewers.ColumnViewerEditor; -import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; -import org.eclipse.jface.viewers.EditingSupport; -import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter; -import org.eclipse.jface.viewers.TextCellEditor; -import org.eclipse.jface.viewers.TreeViewerColumn; -import org.eclipse.jface.viewers.TreeViewerEditor; -import org.eclipse.jface.viewers.TreeViewerFocusCellManager; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.linuxtools.tmf.core.signal.TmfEventSelectedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampFormat; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfOpenTraceHelper; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.viewers.ArrayTreeContentProvider; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.TreeEditor; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.TreeColumn; -import org.eclipse.swt.widgets.TreeItem; -import org.eclipse.ui.dialogs.FilteredTree; -import org.eclipse.ui.dialogs.PatternFilter; - -/** - * Offset wizard dialog - * - * @author Matthew Khouzam - * - */ -public class OffsetDialog extends Dialog { - - private static final int TREE_EDITOR_MIN_WIDTH = 50; - private static final String EDITOR_KEY = "$editor$"; //$NON-NLS-1$ - private static final String WIDTH_KEY = "$width$"; //$NON-NLS-1$ - - private static final TmfTimestampFormat TIME_FORMAT = new TmfTimestampFormat("yyyy-MM-dd HH:mm:ss.SSS SSS SSS"); //$NON-NLS-1$ - private static final TmfTimestampFormat OFFSET_FORMAT = new TmfTimestampFormat("T.SSS SSS SSS"); //$NON-NLS-1$ - - private final Map fOffsetMap; - private final Map fRefTimeMap; - private final Map fTargetTimeMap; - - private Label fBasicMessageLabel; - private Group fButtonGroup; - private Label fAdvancedMessageLabel; - private FilteredTree fViewer; - - private boolean fAdvancedMode = true; - private TreeColumn fRefTimeColumn; - private TreeViewerColumn fButtonViewerColumn; - private TreeColumn fTargetTimeColumn; - - private abstract class ColumnEditingSupport extends EditingSupport { - private final TextCellEditor textCellEditor; - - private ColumnEditingSupport(ColumnViewer viewer, TextCellEditor textCellEditor) { - super(viewer); - this.textCellEditor = textCellEditor; - } - - @Override - protected CellEditor getCellEditor(Object element) { - return textCellEditor; - } - - @Override - protected boolean canEdit(Object element) { - return true; - } - } - - private class TimeEditingSupport extends ColumnEditingSupport { - private Map map; - - private TimeEditingSupport(ColumnViewer viewer, TextCellEditor textCellEditor, Map map) { - super(viewer, textCellEditor); - this.map = map; - } - - @Override - protected void setValue(Object element, Object value) { - if (value instanceof String) { - String string = (String) value; - if (string.trim().isEmpty()) { - map.remove(element); - } else { - try { - ITmfTimestamp refTime = map.get(element); - long ref = refTime == null ? 0 : refTime.normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - Long newVal = TIME_FORMAT.parseValue(string, ref); - map.put((TmfTraceElement) element, new TmfNanoTimestamp(newVal)); - } catch (ParseException e) { - /* Ignore and reload previous value */ - } - } - fViewer.getViewer().update(element, null); - } - } - - @Override - protected Object getValue(Object element) { - if (map.get(element) == null) { - return ""; //$NON-NLS-1$ - } - return TIME_FORMAT.format(map.get(element).normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue()); - } - } - - private class RefTimeEditingSupport extends TimeEditingSupport { - private RefTimeEditingSupport(ColumnViewer viewer, TextCellEditor textCellEditor) { - super(viewer, textCellEditor, fRefTimeMap); - } - } - - private class TargetTimeEditingSupport extends TimeEditingSupport { - private TargetTimeEditingSupport(ColumnViewer viewer, TextCellEditor textCellEditor) { - super(viewer, textCellEditor, fTargetTimeMap); - } - } - - private class OffsetEditingSupport extends ColumnEditingSupport { - private OffsetEditingSupport(ColumnViewer viewer, TextCellEditor textCellEditor) { - super(viewer, textCellEditor); - } - - @Override - protected void setValue(Object element, Object value) { - if (value instanceof String) { - String string = (String) value; - if (string.trim().isEmpty()) { - fOffsetMap.put((TmfTraceElement) element, 0L); - } else { - try { - Long newVal = OFFSET_FORMAT.parseValue(string); - fOffsetMap.put((TmfTraceElement) element, newVal); - } catch (ParseException e) { - /* Ignore and reload previous value */ - } - } - fViewer.getViewer().update(element, null); - } - } - - @Override - protected Object getValue(Object element) { - if (fOffsetMap.get(element) == 0) { - return ""; //$NON-NLS-1$ - } - return OFFSET_FORMAT.format((long) fOffsetMap.get(element)); - } - } - - /** - * Constructor - * - * @param parent - * parent shell - * @param results - * results to put the data into - */ - public OffsetDialog(Shell parent, Map results) { - super(parent); - setShellStyle(getShellStyle() & ~SWT.APPLICATION_MODAL); - fOffsetMap = results; - fRefTimeMap = new HashMap<>(); - fTargetTimeMap = new HashMap<>(); - } - - @Override - protected boolean isResizable() { - return true; - } - - @Override - protected Control createDialogArea(Composite parent) { - getShell().setText(Messages.OffsetDialog_Title); - Composite area = (Composite) super.createDialogArea(parent); - Composite composite = new Composite(area, SWT.NONE); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - GridLayout gl = new GridLayout(); - gl.marginHeight = 0; - gl.marginWidth = 0; - composite.setLayout(new GridLayout()); - createBasicMessage(composite); - createButtonGroup(composite); - createAdvancedMessage(composite); - createViewer(composite); - - /* set label width hint equal to tree width */ - int widthHint = fViewer.getViewer().getTree().computeSize(SWT.DEFAULT, SWT.DEFAULT).x; - GridData gd = (GridData) fBasicMessageLabel.getLayoutData(); - gd.widthHint = widthHint; - gd = (GridData) fAdvancedMessageLabel.getLayoutData(); - gd.widthHint = widthHint; - gd = (GridData) composite.getLayoutData(); - gd.heightHint = composite.computeSize(widthHint, SWT.DEFAULT).y; - setBasicMode(); - - TmfSignalManager.register(this); - composite.addDisposeListener(new DisposeListener() { - @Override - public void widgetDisposed(DisposeEvent e) { - TmfSignalManager.deregister(this); - } - }); - return area; - } - - private void createBasicMessage(final Composite parent) { - fBasicMessageLabel = new Label(parent, SWT.WRAP); - fBasicMessageLabel.setText(Messages.OffsetDialog_BasicMessage); - GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); - gd.widthHint = 0; - gd.heightHint = SWT.DEFAULT; - fBasicMessageLabel.setLayoutData(gd); - } - - private void createButtonGroup(final Composite parent) { - fButtonGroup = new Group(parent, SWT.SHADOW_NONE); - fButtonGroup.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); - fButtonGroup.setLayout(new RowLayout(SWT.HORIZONTAL)); - - final Button basicButton = new Button(fButtonGroup, SWT.RADIO); - basicButton.setText(Messages.OffsetDialog_BasicButton); - basicButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (!basicButton.getSelection() || !fAdvancedMode) { - return; - } - setBasicMode(); - parent.layout(); - } - }); - basicButton.setSelection(true); - - final Button advancedButton = new Button(fButtonGroup, SWT.RADIO); - advancedButton.setText(Messages.OffsetDialog_AdvancedButton); - advancedButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (!advancedButton.getSelection() || fAdvancedMode) { - return; - } - setAdvancedMode(); - parent.layout(); - } - }); - } - - private void createAdvancedMessage(final Composite parent) { - fAdvancedMessageLabel = new Label(parent, SWT.WRAP); - fAdvancedMessageLabel.setText(Messages.OffsetDialog_AdvancedMessage); - GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); - gd.widthHint = 0; - gd.heightHint = SWT.DEFAULT; - fAdvancedMessageLabel.setLayoutData(gd); - } - - private void createViewer(Composite parent) { - - // Define the TableViewer - fViewer = new FilteredTree(parent, SWT.MULTI | SWT.H_SCROLL - | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER, new PatternFilter() { - @Override - protected boolean isLeafMatch(Viewer viewer, Object element) { - return wordMatches(((TmfTraceElement) element).getElementPath()); - } - }, true); - - // Make lines and make header visible - final Tree tree = fViewer.getViewer().getTree(); - tree.setHeaderVisible(true); - tree.setLinesVisible(true); - - TreeViewerFocusCellManager focusCellManager = new TreeViewerFocusCellManager(fViewer.getViewer(), new FocusCellOwnerDrawHighlighter(fViewer.getViewer())); - ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(fViewer.getViewer()); - TreeViewerEditor.create(fViewer.getViewer(), focusCellManager, actSupport, ColumnViewerEditor.TABBING_HORIZONTAL - | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR - | ColumnViewerEditor.TABBING_VERTICAL | ColumnViewerEditor.KEYBOARD_ACTIVATION); - - final TextCellEditor textCellEditor = new TextCellEditor(fViewer.getViewer().getTree(), SWT.RIGHT); - - fViewer.getViewer().setColumnProperties(new String[] { Messages.OffsetDialog_TraceName, Messages.OffsetDialog_ReferenceTime, Messages.OffsetDialog_OffsetTime }); - - TreeViewerColumn column = createTreeViewerColumn(Messages.OffsetDialog_TraceName, SWT.NONE); - column.setLabelProvider(new ColumnLabelProvider() { - @Override - public String getText(Object element) { - return ((TmfTraceElement) element).getElementPath(); - } - }); - - column = createTreeViewerColumn(Messages.OffsetDialog_ReferenceTime, SWT.RIGHT); - column.setLabelProvider(new ColumnLabelProvider() { - @Override - public String getText(Object element) { - return super.getText(fRefTimeMap.get(element)); - } - }); - column.setEditingSupport(new RefTimeEditingSupport(fViewer.getViewer(), textCellEditor)); - fRefTimeColumn = column.getColumn(); - - column = createTreeViewerColumn(Messages.OffsetDialog_OffsetTime, SWT.RIGHT); - column.setLabelProvider(new ColumnLabelProvider() { - @Override - public String getText(Object element) { - if (fOffsetMap.get(element) != 0) { - return super.getText(OFFSET_FORMAT.format((long) fOffsetMap.get(element))); - } - return ""; //$NON-NLS-1$ - } - }); - column.setEditingSupport(new OffsetEditingSupport(fViewer.getViewer(), textCellEditor)); - - column = createTreeViewerColumn("", SWT.NONE); //$NON-NLS-1$ - column.setLabelProvider(new ColumnLabelProvider() { - @Override - public String getText(Object element) { - return ""; //$NON-NLS-1$ - } - }); - column.getColumn().setWidth(TREE_EDITOR_MIN_WIDTH); - column.getColumn().setResizable(false); - fButtonViewerColumn = column; - - column = createTreeViewerColumn(Messages.OffsetDialog_TargetTime, SWT.RIGHT); - column.setLabelProvider(new ColumnLabelProvider() { - @Override - public String getText(Object element) { - return super.getText(fTargetTimeMap.get(element)); - } - }); - column.setEditingSupport(new TargetTimeEditingSupport(fViewer.getViewer(), textCellEditor)); - fTargetTimeColumn = column.getColumn(); - - List traces = new ArrayList<>(fOffsetMap.keySet()); - Collections.sort(traces, new Comparator() { - @Override - public int compare(TmfTraceElement o1, TmfTraceElement o2) { - IPath folder1 = new Path(o1.getElementPath()).removeLastSegments(1); - IPath folder2 = new Path(o2.getElementPath()).removeLastSegments(1); - if (folder1.equals(folder2)) { - return o1.getName().compareToIgnoreCase(o2.getName()); - } - if (folder1.isPrefixOf(folder2)) { - return 1; - } else if (folder2.isPrefixOf(folder1)) { - return -1; - } - return folder1.toString().compareToIgnoreCase(folder2.toString()); - } - }); - - fViewer.getViewer().setContentProvider(new ArrayTreeContentProvider()); - fViewer.getViewer().setInput(traces); - - /* add button as tree editors to fourth column of every item */ - for (TreeItem treeItem : tree.getItems()) { - TreeEditor treeEditor = new TreeEditor(tree); - Button applyButton = new Button(tree, SWT.PUSH); - applyButton.setText("<<"); //$NON-NLS-1$ - applyButton.setData(treeItem.getData()); - applyButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - TmfTraceElement traceElement = (TmfTraceElement) e.widget.getData(); - ITmfTimestamp targetTime = fTargetTimeMap.get(traceElement); - ITmfTimestamp refTime = fRefTimeMap.get(traceElement); - if (targetTime != null && refTime != null) { - long offset = new TmfNanoTimestamp(targetTime).getValue() - - new TmfNanoTimestamp(refTime).getValue(); - fOffsetMap.put(traceElement, offset); - fViewer.getViewer().update(traceElement, null); - } - } - }); - treeEditor.grabHorizontal = true; - treeEditor.minimumWidth = TREE_EDITOR_MIN_WIDTH; - treeEditor.setEditor(applyButton, treeItem, 3); - treeItem.setData(EDITOR_KEY, applyButton); - } - - /* put temporary values in maps to pack according to time formats */ - fRefTimeMap.put(traces.get(0), new TmfNanoTimestamp()); - fTargetTimeMap.put(traces.get(0), new TmfNanoTimestamp()); - fViewer.getViewer().update(traces.get(0), null); - for (final TreeColumn treeColumn : tree.getColumns()) { - if (treeColumn.getResizable()) { - treeColumn.pack(); - } - } - fRefTimeMap.clear(); - fTargetTimeMap.clear(); - fViewer.getViewer().update(traces.get(0), null); - - for (TmfTraceElement traceElement : fOffsetMap.keySet()) { - for (ITmfTrace parentTrace : TmfTraceManager.getInstance().getOpenedTraces()) { - for (ITmfTrace trace : TmfTraceManager.getTraceSet(parentTrace)) { - if (traceElement.getResource().equals(trace.getResource())) { - fRefTimeMap.put(traceElement, trace.getStartTime()); - fViewer.getViewer().update(traceElement, null); - break; - } - } - if (fRefTimeMap.get(traceElement) != null) { - break; - } - } - } - - /* open trace when double-clicking a tree item */ - tree.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetDefaultSelected(SelectionEvent e) { - TmfTraceElement traceElement = (TmfTraceElement) e.item.getData(); - TmfOpenTraceHelper.openTraceFromElement(traceElement); - } - }); - - tree.setFocus(); - } - - private TreeViewerColumn createTreeViewerColumn(String title, int style) { - final TreeViewerColumn viewerColumn = new TreeViewerColumn(fViewer.getViewer(), style); - final TreeColumn column = viewerColumn.getColumn(); - column.setText(title); - column.setResizable(true); - return viewerColumn; - } - - private void setBasicMode() { - fAdvancedMode = false; - fRefTimeColumn.setData(WIDTH_KEY, fRefTimeColumn.getWidth()); - fTargetTimeColumn.setData(WIDTH_KEY, fTargetTimeColumn.getWidth()); - for (TreeItem treeItem : fViewer.getViewer().getTree().getItems()) { - Control editor = (Control) treeItem.getData(EDITOR_KEY); - editor.setVisible(false); - } - fRefTimeColumn.setWidth(0); - fRefTimeColumn.setResizable(false); - fButtonViewerColumn.getColumn().setWidth(0); - fTargetTimeColumn.setWidth(0); - fTargetTimeColumn.setResizable(false); - fAdvancedMessageLabel.setText(""); //$NON-NLS-1$ - } - - private void setAdvancedMode() { - fAdvancedMode = true; - fRefTimeColumn.setWidth((Integer) fRefTimeColumn.getData(WIDTH_KEY)); - fRefTimeColumn.setResizable(true); - fButtonViewerColumn.getColumn().setWidth(TREE_EDITOR_MIN_WIDTH); - fTargetTimeColumn.setWidth((Integer) fTargetTimeColumn.getData(WIDTH_KEY)); - fTargetTimeColumn.setResizable(true); - for (TreeItem treeItem : fViewer.getViewer().getTree().getItems()) { - Control editor = (Control) treeItem.getData(EDITOR_KEY); - editor.setVisible(true); - } - fAdvancedMessageLabel.setText(Messages.OffsetDialog_AdvancedMessage); - } - - /** - * Handler for the event selected signal - * - * @param signal - * the event selected signal - */ - @TmfSignalHandler - public void eventSelected(final TmfEventSelectedSignal signal) { - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - for (TmfTraceElement traceElement : fOffsetMap.keySet()) { - if (traceElement.getResource().equals(signal.getEvent().getTrace().getResource())) { - fRefTimeMap.put(traceElement, signal.getEvent().getTimestamp()); - fViewer.getViewer().update(traceElement, null); - break; - } - } - } - }); - } - - /** - * Handler for the time selected signal - * - * @param signal - * the event selected signal - */ - @TmfSignalHandler - public void timeSelected(final TmfTimeSynchSignal signal) { - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - for (TmfTraceElement traceElement : fOffsetMap.keySet()) { - fTargetTimeMap.put(traceElement, signal.getBeginTime()); - fViewer.getViewer().update(traceElement, null); - } - } - }); - } - - /** - * Handler for the trace opened signal - * - * @param signal - * the trace opened signal - */ - @TmfSignalHandler - public void traceOpened(final TmfTraceOpenedSignal signal) { - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - for (ITmfTrace trace : TmfTraceManager.getTraceSet(signal.getTrace())) { - for (TmfTraceElement traceElement : fOffsetMap.keySet()) { - if (traceElement.getResource().equals(trace.getResource())) { - if (fRefTimeMap.get(traceElement) == null) { - fRefTimeMap.put(traceElement, trace.getStartTime()); - fViewer.getViewer().update(traceElement, null); - } - break; - } - } - } - } - }); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/offset/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/offset/messages.properties deleted file mode 100644 index af1de0d719..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/dialogs/offset/messages.properties +++ /dev/null @@ -1,24 +0,0 @@ -############################################################################### -# Copyright (c) 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Matthew Khouzam - Initial API and implementation -# Patrick Tasse - Initial API and implementation -############################################################################### - -OffsetDialog_AdvancedButton=Advanced -OffsetDialog_AdvancedMessage=Double-click a trace to open it, and select an event to set a reference time. \ -If the reference time and target time are set, press the button to compute their offset automatically. \ -The reference time and target time can be entered in format 'yyyy-mm-dd hh:mm:ss.sss sss sss'. -OffsetDialog_BasicButton=Basic -OffsetDialog_BasicMessage=Set the time offset to apply to each trace. -OffsetDialog_OffsetTime=Offset in seconds -OffsetDialog_ReferenceTime=Reference Time -OffsetDialog_TargetTime=Target Time -OffsetDialog_Title=Apply time offset -OffsetDialog_TraceName=Trace name diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/BatchImportTraceHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/BatchImportTraceHandler.java deleted file mode 100644 index 6aa6b2b229..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/BatchImportTraceHandler.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Bernd Hufmann - Simplify selection logic - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace.BatchImportTraceWizard; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.handlers.HandlerUtil; - -/** - * Batch import handler, spawn a wizard - * - * @author Matthew Khouzam - * @since 2.0 - */ -public class BatchImportTraceHandler extends AbstractHandler { - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - BatchImportTraceWizard w = new BatchImportTraceWizard(); - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - - if (window == null) { - return false; - } - - ISelection currentSelection = HandlerUtil.getCurrentSelection(event); - - IStructuredSelection sec = StructuredSelection.EMPTY; - if (currentSelection instanceof IStructuredSelection) { - sec = (IStructuredSelection) currentSelection; - } - - w.init(PlatformUI.getWorkbench(), sec); - WizardDialog dialog = new WizardDialog(window.getShell(), w); - dialog.open(); - - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/ClearTraceOffsetHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/ClearTraceOffsetHandler.java deleted file mode 100644 index b9df3f0b64..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/ClearTraceOffsetHandler.java +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import java.lang.reflect.InvocationTargetException; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.linuxtools.internal.tmf.ui.project.operations.TmfWorkspaceModifyOperation; -import org.eclipse.linuxtools.tmf.core.synchronization.TimestampTransformFactory; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.MessageBox; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.handlers.HandlerUtil; - -/** - * Clear Trace Offset Handler - * - * @author Patrick Tasse - */ -public class ClearTraceOffsetHandler extends AbstractHandler { - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - @Override - public Object execute(final ExecutionEvent event) throws ExecutionException { - - ISelection selection = HandlerUtil.getCurrentSelection(event); - - // Get the set of selected trace elements - final Set traceElements = new HashSet<>(); - if (selection instanceof StructuredSelection) { - Iterator iterator = ((StructuredSelection) selection).iterator(); - while (iterator.hasNext()) { - Object element = iterator.next(); - if (element instanceof TmfTraceElement) { - TmfTraceElement trace = (TmfTraceElement) element; - traceElements.add(trace.getElementUnderTraceFolder()); - } else if (element instanceof TmfExperimentElement) { - TmfExperimentElement exp = (TmfExperimentElement) element; - for (TmfTraceElement trace : exp.getTraces()) { - traceElements.add(trace.getElementUnderTraceFolder()); - } - } else if (element instanceof TmfTraceFolder) { - TmfTraceFolder folder = (TmfTraceFolder) element; - traceElements.addAll(folder.getTraces()); - } - } - } - - Shell shell = HandlerUtil.getActiveShellChecked(event); - MessageBox mb = new MessageBox(shell, SWT.ICON_QUESTION | SWT.CANCEL | SWT.OK); - mb.setText(Messages.ClearTraceOffsetHandler_Title); - mb.setMessage(Messages.ClearTraceOffsetHandler_ConfirmMessage); - if (mb.open() != SWT.OK) { - return null; - } - - TmfWorkspaceModifyOperation operation = new TmfWorkspaceModifyOperation() { - @Override - public void execute(IProgressMonitor monitor) throws CoreException { - for (final TmfTraceElement trace : traceElements) { - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - if (!TimestampTransformFactory.getTimestampTransform(trace.getResource()).equals(TimestampTransformFactory.getDefaultTransform())) { - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - trace.closeEditors(); - } - }); - trace.deleteSupplementaryResources(); - TimestampTransformFactory.setTimestampTransform(trace.getResource(), null); - trace.refreshSupplementaryFolder(); - } - } - } - }; - try { - PlatformUI.getWorkbench().getProgressService().run(true, true, operation); - } catch (InterruptedException e) { - return null; - } catch (InvocationTargetException e) { - MessageDialog.openError(shell, e.toString(), e.getTargetException().toString()); - return null; - } - - return null; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/CopyExperimentHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/CopyExperimentHandler.java deleted file mode 100644 index 507011c876..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/CopyExperimentHandler.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Remove enable check - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.wizards.CopyExperimentDialog; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.handlers.HandlerUtil; - -/** - * CopyExperimentHandler - *

- */ -public class CopyExperimentHandler extends AbstractHandler { - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - // Get selection already validated by handler in plugin.xml - ISelection selection = HandlerUtil.getCurrentSelectionChecked(event); - if (!(selection instanceof IStructuredSelection)) { - return null; - } - TmfExperimentElement experiment = (TmfExperimentElement) ((IStructuredSelection) selection).getFirstElement(); - - // Fire the Copy Experiment dialog - Shell shell = HandlerUtil.getActiveShellChecked(event); - CopyExperimentDialog dialog = new CopyExperimentDialog(shell, experiment); - dialog.open(); - - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/CopyTraceHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/CopyTraceHandler.java deleted file mode 100644 index 91d83be589..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/CopyTraceHandler.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Remove enable check - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.wizards.CopyTraceDialog; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.handlers.HandlerUtil; - -/** - * CopyTraceHandler - *

- */ -public class CopyTraceHandler extends AbstractHandler { - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - // Get selection already validated by handler in plugin.xml - ISelection selection = HandlerUtil.getCurrentSelectionChecked(event); - if (!(selection instanceof IStructuredSelection)) { - return null; - } - TmfTraceElement trace = (TmfTraceElement) ((IStructuredSelection) selection).getFirstElement(); - - // Fire the Copy Trace dialog - Shell shell = HandlerUtil.getActiveShellChecked(event); - CopyTraceDialog dialog = new CopyTraceDialog(shell, trace); - dialog.open(); - - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/DeleteExperimentHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/DeleteExperimentHandler.java deleted file mode 100644 index b85a0e8375..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/DeleteExperimentHandler.java +++ /dev/null @@ -1,113 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Close editors to release resources - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import java.util.Iterator; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.MessageBox; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -/** - * DeleteExperimentHandler - *

- */ -public class DeleteExperimentHandler extends AbstractHandler { - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - - // Confirm the operation - Shell shell = window.getShell(); - MessageBox confirmOperation = new MessageBox(shell, SWT.ICON_QUESTION | SWT.CANCEL | SWT.OK); - confirmOperation.setText(Messages.DeleteDialog_Title); - confirmOperation.setMessage(Messages.DeleteExperimentHandler_Message); - if (confirmOperation.open() != SWT.OK) { - return null; - } - - // Get the selection - IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - IWorkbenchPart part = page.getActivePart(); - if (part == null) { - return Boolean.FALSE; - } - ISelection selection = part.getSite().getSelectionProvider().getSelection(); - - if (selection instanceof TreeSelection) { - TreeSelection sel = (TreeSelection) selection; - Iterator iterator = sel.iterator(); - while (iterator.hasNext()) { - Object element = iterator.next(); - if (element instanceof TmfExperimentElement) { - final TmfExperimentElement experiment = (TmfExperimentElement) element; - IResource resource = experiment.getResource(); - - try { - // Close the experiment if open - experiment.closeEditors(); - - IPath path = resource.getLocation(); - if (path != null) { - // Delete supplementary files - experiment.deleteSupplementaryFolder(); - } - - // Finally, delete the experiment - resource.delete(true, null); - - } catch (final CoreException e) { - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - final MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()); - mb.setText(Messages.DeleteTraceHandler_Error + ' ' + experiment.getName()); - mb.setMessage(e.getMessage()); - mb.open(); - } - }); - Activator.getDefault().logError("Error deleting experiment: " + experiment.getName(), e); //$NON-NLS-1$ - } - } - } - } - - return null; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/DeleteTraceFolderElementHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/DeleteTraceFolderElementHandler.java deleted file mode 100644 index 6ef2fd1572..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/DeleteTraceFolderElementHandler.java +++ /dev/null @@ -1,349 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Close editors to release resources - * Geneviève Bastien - Moved the delete code to element model's classes - * Marc-Andre Laperle - Merged DeleteTraceHandler and DeleteFolderHandler - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import java.lang.reflect.InvocationTargetException; -import java.util.Iterator; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceVisitor; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.project.operations.TmfWorkspaceModifyOperation; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTracesFolder; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.MessageBox; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.handlers.HandlerUtil; - -/** - * An handler for deletion of both traces and trace folders. It allows mixing - * both types of elements. - */ -public class DeleteTraceFolderElementHandler extends AbstractHandler { - - private TreeSelection fSelection = null; - - private enum DeleteType { - /** - * Only trace folders are selected. - */ - DELETE_TRACE_FOLDERS, - /** - * Only traces are selected. - */ - DELETE_TRACES, - /** - * A mix of different elements are selected. - */ - DELETE_GENERIC, - /** - * Only Traces (top trace folders) are selected. - */ - CLEAR_TRACES_FOLDER, - /** - * Only Traces under experiments are selected. - */ - REMOVE_TRACES_FROM_EXPERIMENT - } - - // ------------------------------------------------------------------------ - // Validation - // ------------------------------------------------------------------------ - - @Override - public boolean isEnabled() { - - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return false; - } - - // Get the selection - IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - IWorkbenchPart part = page.getActivePart(); - if (part == null) { - return false; - } - ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); - if (selectionProvider == null) { - return false; - } - ISelection selection = selectionProvider.getSelection(); - - // Make sure selection contains only traces and trace folders - fSelection = null; - if (selection instanceof TreeSelection) { - fSelection = (TreeSelection) selection; - Iterator iterator = fSelection.iterator(); - while (iterator.hasNext()) { - Object element = iterator.next(); - if (!(element instanceof TmfTraceElement) && !(element instanceof TmfTraceFolder)) { - return false; - } - } - } - - // If we get here, either nothing is selected or everything is a trace or folder - return !selection.isEmpty(); - } - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - private static DeleteType getDeleteType(ISelection selection) { - int numTracesFolder = 0; - int numTraceFolder = 0; - int numTraces = 0; - int numTracesUnderExperiment = 0; - - @SuppressWarnings("rawtypes") - Iterator iterator = ((IStructuredSelection) selection).iterator(); - while (iterator.hasNext()) { - Object next = iterator.next(); - if ((next instanceof TmfTracesFolder)) { - numTracesFolder++; - } else if (next instanceof TmfTraceFolder) { - numTraceFolder++; - } else if (next instanceof TmfTraceElement) { - TmfTraceElement traceElement = (TmfTraceElement) next; - if (traceElement.getParent() instanceof TmfExperimentElement) { - numTracesUnderExperiment++; - } else { - numTraces++; - } - } - } - - int total = numTraceFolder + numTracesFolder + numTracesUnderExperiment + numTraces; - - if (numTracesFolder == total) { - return DeleteType.CLEAR_TRACES_FOLDER; - } - - if (numTraceFolder == total) { - return DeleteType.DELETE_TRACE_FOLDERS; - } - - if (numTraces == total) { - return DeleteType.DELETE_TRACES; - } - - if (numTracesUnderExperiment == total) { - return DeleteType.REMOVE_TRACES_FROM_EXPERIMENT; - } - - return DeleteType.DELETE_GENERIC; - } - - private static String getTitle(final DeleteType deleteType) { - switch (deleteType) - { - case DELETE_GENERIC: - case DELETE_TRACES: - case DELETE_TRACE_FOLDERS: - return Messages.DeleteDialog_Title; - case CLEAR_TRACES_FOLDER: - return Messages.ClearDialog_Title; - case REMOVE_TRACES_FROM_EXPERIMENT: - return Messages.RemoveDialog_Title; - default: - throw new IllegalArgumentException(); - } - } - - private static String getMessage(DeleteType deleteType) { - switch (deleteType) - { - case DELETE_GENERIC: - return Messages.DeleteTraceHandlerGeneric_Message; - case DELETE_TRACES: - return Messages.DeleteTraceHandler_Message; - case CLEAR_TRACES_FOLDER: - return Messages.DeleteFolderHandlerClear_Message; - case DELETE_TRACE_FOLDERS: - return Messages.DeleteFolderHandler_Message; - case REMOVE_TRACES_FROM_EXPERIMENT: - return Messages.RemoveTraceFromExperimentHandler_Message; - default: - throw new IllegalArgumentException(); - } - } - - private static String getTraceErrorMessage(DeleteType deleteType) { - return deleteType == DeleteType.REMOVE_TRACES_FROM_EXPERIMENT ? Messages.RemoveTraceFromExperimentHandler_Error : Messages.DeleteFolderHandler_Error; - } - - private static String getFolderErrorMessage(DeleteType deleteType) { - return deleteType == DeleteType.CLEAR_TRACES_FOLDER ? Messages.DeleteFolderHandlerClear_Error : Messages.DeleteFolderHandler_Error; - } - - private static String getTraceTaskName(DeleteType deleteType) { - return deleteType == DeleteType.REMOVE_TRACES_FROM_EXPERIMENT ? Messages.RemoveTraceFromExperimentHandler_TaskName : Messages.DeleteFolderHandler_TaskName; - } - - private static String getTraceFolderTaskName(DeleteType deleteType) { - return deleteType == DeleteType.CLEAR_TRACES_FOLDER ? Messages.DeleteFolderHandlerClear_TaskName : Messages.DeleteFolderHandler_TaskName; - } - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - - // Get the selection - ISelection selection = HandlerUtil.getCurrentSelection(event); - if (!(selection instanceof IStructuredSelection)) { - return null; - } - final DeleteType deleteType = getDeleteType(selection); - - // Confirm the operation - Shell shell = window.getShell(); - MessageBox confirmOperation = new MessageBox(shell, SWT.ICON_QUESTION | SWT.CANCEL | SWT.OK); - confirmOperation.setText(getTitle(deleteType)); - confirmOperation.setMessage(getMessage(deleteType)); - if (confirmOperation.open() != SWT.OK) { - return null; - } - - final Iterator iterator = fSelection.iterator(); - final int nbElements = fSelection.size(); - - TmfWorkspaceModifyOperation operation = new TmfWorkspaceModifyOperation() { - @Override - public void execute(IProgressMonitor monitor) throws CoreException { - SubMonitor subMonitor = SubMonitor.convert(monitor, nbElements); - - while (iterator.hasNext()) { - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - Object element = iterator.next(); - SubProgressMonitor elementSubMonitor = new SubProgressMonitor(subMonitor, 1); - if (element instanceof TmfTraceElement) { - final TmfTraceElement trace = (TmfTraceElement) element; - if (!trace.getResource().exists()) { - continue; - } - subMonitor.setTaskName(getTraceTaskName(deleteType) + " " + trace.getElementPath()); //$NON-NLS-1$ - try { - SubMonitor deleteSubMonitor = SubMonitor.convert(elementSubMonitor, 1); - trace.delete(deleteSubMonitor); - } catch (final CoreException e) { - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - final MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()); - mb.setText(getTraceErrorMessage(deleteType) + ' ' + trace.getName()); - mb.setMessage(e.getMessage()); - mb.open(); - } - }); - Activator.getDefault().logError(getTraceErrorMessage(deleteType) + trace.getName(), e); - } - } else if (element instanceof TmfTraceFolder) { - final TmfTraceFolder folder = (TmfTraceFolder) element; - final IResource resource = folder.getResource(); - if (!resource.exists()) { - continue; - } - - subMonitor.setTaskName(getTraceFolderTaskName(deleteType) + " " + folder.getPath()); //$NON-NLS-1$ - - try { - // delete all traces under this folder - SubMonitor childrenSubMonitor = SubMonitor.convert(elementSubMonitor, folder.getTraces().size() + 1); - for (TmfTraceElement traceElement : folder.getTraces()) { - SubProgressMonitor deleteSubMonitor = new SubProgressMonitor(childrenSubMonitor, 1); - traceElement.delete(deleteSubMonitor); - } - - // Finally, delete the folder. For the Traces - // folder, we only delete the children since the - // folder should always be there. - final SubProgressMonitor deleteSubMonitor = new SubProgressMonitor(subMonitor, 1); - if (folder instanceof TmfTracesFolder) { - resource.accept(new IResourceVisitor() { - @Override - public boolean visit(IResource visitedResource) throws CoreException { - if (visitedResource != resource) { - visitedResource.delete(true, deleteSubMonitor); - } - return true; - } - }, IResource.DEPTH_ONE, 0); - } else { - resource.delete(true, deleteSubMonitor); - } - childrenSubMonitor.done(); - } catch (final CoreException e) { - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - final MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()); - mb.setText(getFolderErrorMessage(deleteType) + ' ' + folder.getName()); - mb.setMessage(e.getMessage()); - mb.open(); - } - }); - Activator.getDefault().logError(getFolderErrorMessage(deleteType) + folder.getName(), e); - } - } - subMonitor.setTaskName(""); //$NON-NLS-1$ - elementSubMonitor.done(); - } - } - }; - - try { - PlatformUI.getWorkbench().getProgressService().run(true, true, operation); - } catch (InterruptedException e) { - return null; - } catch (InvocationTargetException e) { - MessageDialog.openError(window.getShell(), e.toString(), e.getTargetException().toString()); - return null; - } - return null; - } - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/DeleteTraceSupplementaryFilesHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/DeleteTraceSupplementaryFilesHandler.java deleted file mode 100644 index 7345391cb2..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/DeleteTraceSupplementaryFilesHandler.java +++ /dev/null @@ -1,192 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Patrick Tasse - Close editors to release resources - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.window.Window; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.project.dialogs.SelectSupplementaryResourcesDialog; -import org.eclipse.linuxtools.internal.tmf.ui.project.operations.TmfWorkspaceModifyOperation; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfCommonProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.handlers.HandlerUtil; - -import com.google.common.collect.Multimap; -import com.google.common.collect.TreeMultimap; - -/** - * Handler for Delete Supplementary Files command on trace - */ -public class DeleteTraceSupplementaryFilesHandler extends AbstractHandler { - - // ------------------------------------------------------------------------ - // Inner classes - // ------------------------------------------------------------------------ - - private class ElementComparator implements Comparator { - @Override - public int compare(TmfCommonProjectElement e1, TmfCommonProjectElement e2) { - return e1.getPath().toString().compareTo(e2.getPath().toString()); - } - } - - private class ResourceComparator implements Comparator { - @Override - public int compare(IResource r1, IResource r2) { - return r1.getFullPath().toString().compareTo(r2.getFullPath().toString()); - } - } - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - - // Get the selection - ISelection selection = HandlerUtil.getCurrentSelection(event); - if (!(selection instanceof IStructuredSelection)) { - return null; - } - final Multimap resourceMap = - TreeMultimap.create(new ElementComparator(), new ResourceComparator()); - final Iterator iterator = ((IStructuredSelection) selection).iterator(); - - while (iterator.hasNext()) { - Object element = iterator.next(); - if (element instanceof TmfTraceElement) { - TmfTraceElement trace = (TmfTraceElement) element; - // If trace is under an experiment, use the original trace from the traces folder - trace = trace.getElementUnderTraceFolder(); - for (IResource resource : trace.getSupplementaryResources()) { - resourceMap.put(trace, resource); - } - - } else if (element instanceof TmfExperimentElement) { - TmfExperimentElement experiment = (TmfExperimentElement) element; - for (IResource resource : experiment.getSupplementaryResources()) { - resourceMap.put(experiment, resource); - } - for (TmfTraceElement trace : experiment.getTraces()) { - // If trace is under an experiment, use the original trace from the traces folder - trace = trace.getElementUnderTraceFolder(); - for (IResource resource : trace.getSupplementaryResources()) { - resourceMap.put(trace, resource); - } - } - } - } - - final SelectSupplementaryResourcesDialog dialog = - new SelectSupplementaryResourcesDialog(window.getShell(), resourceMap); - if (dialog.open() != Window.OK) { - return null; - } - - TmfWorkspaceModifyOperation operation = new TmfWorkspaceModifyOperation() { - @Override - public void execute(IProgressMonitor monitor) throws CoreException { - - Set projectsToRefresh = new HashSet<>(); - - // Delete the resources that were selected - List allResourcesToDelete = Arrays.asList(dialog.getResources()); - - SubMonitor subMonitor = SubMonitor.convert(monitor, allResourcesToDelete.size()); - - for (final TmfCommonProjectElement element : resourceMap.keySet()) { - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - List traceResourcesToDelete = new ArrayList<>(resourceMap.get(element)); - traceResourcesToDelete.retainAll(allResourcesToDelete); - if (!traceResourcesToDelete.isEmpty()) { - subMonitor.setTaskName(NLS.bind(Messages.DeleteSupplementaryFiles_DeletionTask, element.getElementPath())); - // Delete the selected resources - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - element.closeEditors(); - } - }); - element.deleteSupplementaryResources(traceResourcesToDelete.toArray(new IResource[0])); - projectsToRefresh.add(element.getProject().getResource()); - } - subMonitor.worked(traceResourcesToDelete.size()); - } - - subMonitor = SubMonitor.convert(monitor, projectsToRefresh.size()); - - // Refresh projects - Iterator projectIterator = projectsToRefresh.iterator(); - while (projectIterator.hasNext()) { - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - IProject project = projectIterator.next(); - subMonitor.setTaskName(NLS.bind(Messages.DeleteSupplementaryFiles_ProjectRefreshTask, project.getName())); - try { - project.refreshLocal(IResource.DEPTH_INFINITE, null); - } catch (CoreException e) { - Activator.getDefault().logError("Error refreshing project " + project, e); //$NON-NLS-1$ - } - subMonitor.worked(1); - } - } - }; - - try { - PlatformUI.getWorkbench().getProgressService().run(true, true, operation); - } catch (InterruptedException e) { - return null; - } catch (InvocationTargetException e) { - MessageDialog.openError(window.getShell(), e.toString(), e.getTargetException().toString()); - return null; - } - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/DropAdapterAssistant.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/DropAdapterAssistant.java deleted file mode 100644 index ab6f0823ac..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/DropAdapterAssistant.java +++ /dev/null @@ -1,669 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Patrick Tasse - Add support for DROP_LINK and rename prompt on name clash - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; -import java.util.List; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.URIUtil; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceImportException; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; -import org.eclipse.linuxtools.tmf.core.trace.TmfTrace; -import org.eclipse.linuxtools.tmf.ui.project.model.ITmfProjectModelElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceTypeUIUtils; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.dnd.DND; -import org.eclipse.swt.dnd.DropTargetEvent; -import org.eclipse.swt.dnd.FileTransfer; -import org.eclipse.swt.dnd.TransferData; -import org.eclipse.swt.widgets.MessageBox; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.actions.WorkspaceModifyDelegatingOperation; -import org.eclipse.ui.dialogs.IOverwriteQuery; -import org.eclipse.ui.navigator.CommonDropAdapter; -import org.eclipse.ui.navigator.CommonDropAdapterAssistant; -import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider; -import org.eclipse.ui.wizards.datatransfer.ImportOperation; - -/** - * Drop adapter assistant for project explorer - */ -public class DropAdapterAssistant extends CommonDropAdapterAssistant { - - /** - * Default constructor - */ - public DropAdapterAssistant() { - } - - @Override - public boolean isSupportedType(TransferData aTransferType) { - return super.isSupportedType(aTransferType) || FileTransfer.getInstance().isSupportedType(aTransferType); - } - - @Override - public IStatus validateDrop(Object target, int operation, TransferData transferType) { - if (target instanceof TmfTraceFolder) { - return Status.OK_STATUS; - } - if (target instanceof TmfExperimentElement) { - return Status.OK_STATUS; - } - if (target instanceof TmfTraceElement) { - ITmfProjectModelElement parent = ((TmfTraceElement) target).getParent(); - if (parent instanceof TmfTraceFolder) { - return Status.OK_STATUS; - } - if (parent instanceof TmfExperimentElement) { - return Status.OK_STATUS; - } - } - if (target instanceof IProject) { - return Status.OK_STATUS; - } - return Status.CANCEL_STATUS; - } - - @Override - public IStatus handleDrop(CommonDropAdapter aDropAdapter, DropTargetEvent aDropTargetEvent, Object aTarget) { - boolean ok = false; - - // Use local variable to avoid parameter assignment - Object targetToUse = aTarget; - - int operation = aDropTargetEvent.detail; - if (operation != DND.DROP_LINK) { - operation = DND.DROP_COPY; - } - - // If target is a trace, use its parent (either trace folder or experiment) - if (targetToUse instanceof TmfTraceElement) { - targetToUse = ((TmfTraceElement) targetToUse).getParent(); - } - - // If target is a project, use its trace folder - if (targetToUse instanceof IProject) { - TmfProjectElement projectElement = TmfProjectRegistry.getProject((IProject) targetToUse, true); - if (projectElement != null) { - targetToUse = projectElement.getTracesFolder(); - } - } - - if (aDropTargetEvent.data instanceof IStructuredSelection) { - IStructuredSelection selection = (IStructuredSelection) aDropTargetEvent.data; - for (Object source : selection.toArray()) { - if (source instanceof IResource) { - // If source resource is a trace, use the trace element - IResource sourceResource = (IResource) source; - TmfProjectElement projectElement = TmfProjectRegistry.getProject(sourceResource.getProject()); - if (projectElement != null && projectElement.getTracesFolder() != null) { - for (TmfTraceElement trace : projectElement.getTracesFolder().getTraces()) { - if (trace.getResource().equals(sourceResource)) { - source = trace; - break; - } - } - } - } - if (source instanceof TmfTraceElement) { - TmfTraceElement sourceTrace = (TmfTraceElement) source; - // If source trace is under an experiment, use the original trace from the traces folder - sourceTrace = sourceTrace.getElementUnderTraceFolder(); - if (targetToUse instanceof TmfExperimentElement) { - TmfExperimentElement targetExperiment = (TmfExperimentElement) targetToUse; - ok |= drop(sourceTrace, targetExperiment, operation); - } else if (targetToUse instanceof TmfTraceFolder) { - TmfTraceFolder traceFolder = (TmfTraceFolder) targetToUse; - ok |= drop(sourceTrace, traceFolder, operation); - } - } else if (source instanceof IResource) { - IResource sourceResource = (IResource) source; - if (sourceResource.getType() != IResource.FILE && sourceResource.getType() != IResource.FOLDER) { - continue; - } - if (targetToUse instanceof TmfExperimentElement) { - TmfExperimentElement targetExperiment = (TmfExperimentElement) targetToUse; - ok |= (drop(sourceResource, targetExperiment, operation) != null); - } else if (targetToUse instanceof TmfTraceFolder) { - TmfTraceFolder traceFolder = (TmfTraceFolder) targetToUse; - ok |= (drop(sourceResource, traceFolder, operation) != null); - } - } - } - } else if (aDropTargetEvent.data instanceof String[]) { - String[] sources = (String[]) aDropTargetEvent.data; - for (String source : sources) { - Path path = new Path(source); - if (targetToUse instanceof TmfExperimentElement) { - TmfExperimentElement targetExperiment = (TmfExperimentElement) targetToUse; - ok |= drop(path, targetExperiment, operation); - } else if (targetToUse instanceof TmfTraceFolder) { - TmfTraceFolder traceFolder = (TmfTraceFolder) targetToUse; - ok |= drop(path, traceFolder, operation); - } - } - } - return (ok ? Status.OK_STATUS : Status.CANCEL_STATUS); - } - - - /** - * Drop a trace by copying/linking a trace element in a target experiment - * - * @param sourceTrace the source trace element to copy - * @param targetExperiment the target experiment - * @param operation the drop operation (DND.DROP_COPY | DND.DROP_LINK) - * @return true if successful - */ - private static boolean drop(TmfTraceElement sourceTrace, - TmfExperimentElement targetExperiment, - int operation) { - - IResource sourceResource = sourceTrace.getResource(); - IResource targetResource = drop(sourceResource, targetExperiment, operation); - - if (targetResource != null) { - if (! sourceTrace.getProject().equals(targetExperiment.getProject())) { - IFolder destinationSupplementaryFolder = targetExperiment.getTraceSupplementaryFolder(targetResource.getName()); - sourceTrace.copySupplementaryFolder(destinationSupplementaryFolder); - } - return true; - } - return false; - } - - /** - * Drop a trace by copying/linking a resource in a target experiment - * - * @param sourceResource the source resource - * @param targetExperiment the target experiment - * @param operation the drop operation (DND.DROP_COPY | DND.DROP_LINK) - * @return the target resource or null if unsuccessful - */ - private static IResource drop(IResource sourceResource, - TmfExperimentElement targetExperiment, - int operation) { - - IResource traceResource = sourceResource; - - IPath tracesFolderPath = targetExperiment.getProject().getTracesFolder().getPath(); - if (tracesFolderPath.isPrefixOf(sourceResource.getFullPath())) { - String elementPath = sourceResource.getFullPath().makeRelativeTo(tracesFolderPath).toString(); - for (TmfTraceElement trace : targetExperiment.getTraces()) { - if (trace.getElementPath().equals(elementPath)) { - return null; - } - } - } else { - String targetName = sourceResource.getName(); - for (ITmfProjectModelElement element : targetExperiment.getProject().getTracesFolder().getChildren()) { - if (element.getName().equals(targetName)) { - targetName = promptRename(element); - if (targetName == null) { - return null; - } - break; - } - } - try { - if (operation == DND.DROP_COPY && !sourceResource.isLinked()) { - IPath destination = targetExperiment.getProject().getTracesFolder().getResource().getFullPath().addTrailingSeparator().append(targetName); - sourceResource.copy(destination, false, null); - cleanupBookmarks(destination); - } else { - createLink(targetExperiment.getProject().getTracesFolder().getResource(), sourceResource, targetName); - } - // use the copied resource for the experiment - if (sourceResource.getType() == IResource.FILE) { - traceResource = targetExperiment.getProject().getTracesFolder().getResource().getFile(targetName); - } else if (sourceResource.getType() == IResource.FOLDER) { - traceResource = targetExperiment.getProject().getTracesFolder().getResource().getFolder(targetName); - } - String sourceLocation = sourceResource.getPersistentProperty(TmfCommonConstants.SOURCE_LOCATION); - if (sourceLocation == null) { - sourceLocation = URIUtil.toUnencodedString(new File(sourceResource.getLocationURI()).toURI()); - } - traceResource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation); - } catch (CoreException e) { - displayException(e); - return null; - } - } - if (traceResource != null && traceResource.exists()) { - setTraceType(traceResource); - for (TmfTraceElement trace : targetExperiment.getProject().getTracesFolder().getTraces()) { - if (trace.getResource().equals(traceResource)) { - targetExperiment.addTrace(trace); - targetExperiment.closeEditors(); - targetExperiment.deleteSupplementaryResources(); - break; - } - } - return traceResource; - } - return null; - } - - /** - * Drop a trace by copying/linking a trace element in a trace folder - * - * @param sourceTrace the source trace - * @param traceFolder the target trace folder - * @param operation the drop operation (DND.DROP_COPY | DND.DROP_LINK) - * @return true if successful - */ - private static boolean drop(TmfTraceElement sourceTrace, - TmfTraceFolder traceFolder, - int operation) { - - IResource sourceResource = sourceTrace.getResource(); - IResource targetResource = drop(sourceResource, traceFolder, operation); - - if (targetResource != null) { - String elementPath = targetResource.getFullPath().makeRelativeTo(traceFolder.getProject().getTracesFolder().getPath()).toString(); - IFolder destinationSupplementaryFolder = traceFolder.getTraceSupplementaryFolder(elementPath); - sourceTrace.copySupplementaryFolder(destinationSupplementaryFolder); - return true; - } - return false; - } - - /** - * Drop a trace by copying/linking a resource in a trace folder - * - * @param sourceResource the source resource - * @param traceFolder the target trace folder - * @param operation the drop operation (DND.DROP_COPY | DND.DROP_LINK) - * @return the target resource or null if unsuccessful - */ - private static IResource drop(IResource sourceResource, - TmfTraceFolder traceFolder, - int operation) { - - if (sourceResource.getParent().equals(traceFolder.getResource())) { - return null; - } - String targetName = sourceResource.getName(); - for (ITmfProjectModelElement element : traceFolder.getChildren()) { - if (element.getName().equals(targetName)) { - targetName = promptRename(element); - if (targetName == null) { - return null; - } - break; - } - } - try { - if (operation == DND.DROP_COPY && !sourceResource.isLinked()) { - IPath destination = traceFolder.getResource().getFullPath().addTrailingSeparator().append(targetName); - sourceResource.copy(destination, false, null); - cleanupBookmarks(destination); - } else { - createLink(traceFolder.getResource(), sourceResource, targetName); - } - IResource traceResource = traceFolder.getResource().findMember(targetName); - if (traceResource != null && traceResource.exists()) { - String sourceLocation = sourceResource.getPersistentProperty(TmfCommonConstants.SOURCE_LOCATION); - if (sourceLocation == null) { - sourceLocation = URIUtil.toUnencodedString(new File(sourceResource.getLocationURI()).toURI()); - } - traceResource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation); - setTraceType(traceResource); - } - return traceResource; - } catch (CoreException e) { - displayException(e); - } - return null; - } - - /** - * Drop a trace by importing/linking a path in a target experiment - * - * @param path the source path - * @param targetExperiment the target experiment - * @param operation the drop operation (DND.DROP_COPY | DND.DROP_LINK) - * @return true if successful - */ - private static boolean drop(Path path, - TmfExperimentElement targetExperiment, - int operation) { - - IPath tracesFolderPath = targetExperiment.getProject().getTracesFolder().getResource().getLocation(); - IResource traceResource = null; - if (tracesFolderPath.isPrefixOf(path)) { - String elementPath = path.makeRelativeTo(tracesFolderPath).toString(); - for (TmfTraceElement trace : targetExperiment.getTraces()) { - if (trace.getElementPath().equals(elementPath)) { - return false; - } - } - traceResource = targetExperiment.getProject().getTracesFolder().getResource().findMember(elementPath); - } else { - String targetName = path.lastSegment(); - for (ITmfProjectModelElement element : targetExperiment.getProject().getTracesFolder().getChildren()) { - if (element.getName().equals(targetName)) { - targetName = promptRename(element); - if (targetName == null) { - return false; - } - break; - } - } - if (operation == DND.DROP_COPY) { - importTrace(targetExperiment.getProject().getTracesFolder().getResource(), path, targetName); - } else { - createLink(targetExperiment.getProject().getTracesFolder().getResource(), path, targetName); - } - // use the copied resource for the experiment - File file = new File(path.toString()); - if (file.exists() && file.isFile()) { - traceResource = targetExperiment.getProject().getTracesFolder().getResource().getFile(targetName); - } else if (file.exists() && file.isDirectory()) { - traceResource = targetExperiment.getProject().getTracesFolder().getResource().getFolder(targetName); - } - } - if (traceResource != null && traceResource.exists()) { - try { - String sourceLocation = URIUtil.toUnencodedString(path.toFile().toURI()); - traceResource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation); - } catch (CoreException e) { - displayException(e); - } - setTraceType(traceResource); - for (TmfTraceElement trace : targetExperiment.getProject().getTracesFolder().getTraces()) { - if (trace.getResource().equals(traceResource)) { - targetExperiment.addTrace(trace); - targetExperiment.closeEditors(); - targetExperiment.deleteSupplementaryResources(); - break; - } - } - return true; - } - return false; - } - - /** - * Drop a trace by importing/linking a path in a trace folder - * - * @param path the source path - * @param traceFolder the target trace folder - * @param operation the drop operation (DND.DROP_COPY | DND.DROP_LINK) - * @return true if successful - */ - private static boolean drop(Path path, - TmfTraceFolder traceFolder, - int operation) { - - String targetName = path.lastSegment(); - for (ITmfProjectModelElement element : traceFolder.getChildren()) { - if (element.getName().equals(targetName)) { - targetName = promptRename(element); - if (targetName == null) { - return false; - } - break; - } - } - if (operation == DND.DROP_COPY) { - importTrace(traceFolder.getResource(), path, targetName); - } else { - createLink(traceFolder.getResource(), path, targetName); - } - IResource traceResource = traceFolder.getResource().findMember(targetName); - if (traceResource != null && traceResource.exists()) { - try { - String sourceLocation = URIUtil.toUnencodedString(path.toFile().toURI()); - traceResource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation); - } catch (CoreException e) { - displayException(e); - } - setTraceType(traceResource); - } - return true; - } - - /** - * Import a trace to the trace folder - * - * @param folder the trace folder resource - * @param path the path to the trace to import - * @param targetName the target name - */ - private static void importTrace(final IFolder folder, final Path path, final String targetName) { - final File source = new File(path.toString()); - if (source.isDirectory()) { - IPath containerPath = folder.getFullPath().addTrailingSeparator().append(targetName); - IOverwriteQuery overwriteImplementor = new IOverwriteQuery() { - @Override - public String queryOverwrite(String pathString) { - return IOverwriteQuery.NO_ALL; - } - }; - List filesToImport = Arrays.asList(source.listFiles()); - ImportOperation operation = new ImportOperation( - containerPath, - source, - FileSystemStructureProvider.INSTANCE, - overwriteImplementor, - filesToImport); - operation.setCreateContainerStructure(false); - try { - operation.run(new NullProgressMonitor()); - } catch (InvocationTargetException e) { - displayException(e); - } catch (InterruptedException e) { - displayException(e); - } - } else { - IRunnableWithProgress runnable = new IRunnableWithProgress() { - @Override - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - try (InputStream inputStream = new FileInputStream(source);) { - IFile targetFile = folder.getFile(targetName); - targetFile.create(inputStream, IResource.NONE, monitor); - } catch (CoreException | IOException e) { - displayException(e); - } - } - }; - WorkspaceModifyDelegatingOperation operation = new WorkspaceModifyDelegatingOperation(runnable); - try { - operation.run(new NullProgressMonitor()); - } catch (InvocationTargetException e) { - displayException(e); - } catch (InterruptedException e) { - displayException(e); - } - } - } - - /** - * Create a link to the actual trace and set the trace type - * - * @param parentFolder the parent folder - * @param resource the resource - * @param targetName the target name - */ - private static void createLink(IFolder parentFolder, IResource resource, String targetName) { - IPath location = resource.getLocation(); - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - try { - String traceType = TmfTraceType.getTraceTypeId(resource); - TraceTypeHelper traceTypeHelper = TmfTraceType.getTraceType(traceType); - - if (resource instanceof IFolder) { - IFolder folder = parentFolder.getFolder(targetName); - IStatus result = workspace.validateLinkLocation(folder, location); - if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) { - folder.createLink(location, IResource.REPLACE, null); - if (traceTypeHelper != null) { - TmfTraceTypeUIUtils.setTraceType(folder, traceTypeHelper); - } - } else { - Activator.getDefault().logError("Invalid Trace Location"); //$NON-NLS-1$ - } - } else { - IFile file = parentFolder.getFile(targetName); - IStatus result = workspace.validateLinkLocation(file, location); - if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) { - file.createLink(location, IResource.REPLACE, null); - if (traceTypeHelper != null) { - TmfTraceTypeUIUtils.setTraceType(file, traceTypeHelper); - } - } else { - Activator.getDefault().logError("Invalid Trace Location"); //$NON-NLS-1$ - } - } - } catch (CoreException e) { - displayException(e); - } - } - - /** - * Create a link to a file or folder - * - * @param parentFolder the parent folder - * @param source the file or folder - * @param targetName the target name - */ - private static void createLink(IFolder parentFolder, IPath location, String targetName) { - File source = new File(location.toString()); - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - try { - - if (source.isDirectory()) { - IFolder folder = parentFolder.getFolder(targetName); - IStatus result = workspace.validateLinkLocation(folder, location); - if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) { - folder.createLink(location, IResource.REPLACE, null); - } else { - Activator.getDefault().logError("Invalid Trace Location"); //$NON-NLS-1$ - } - } else { - IFile file = parentFolder.getFile(targetName); - IStatus result = workspace.validateLinkLocation(file, location); - if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) { - file.createLink(location, IResource.REPLACE, null); - } else { - Activator.getDefault().logError("Invalid Trace Location"); //$NON-NLS-1$ - } - } - } catch (CoreException e) { - displayException(e); - } - } - - /** - * Prompts the user to rename a trace - * - * @param element the conflicting element - * @return the new name to use or null if rename is canceled - */ - private static String promptRename(ITmfProjectModelElement element) { - MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.ICON_QUESTION | SWT.CANCEL | SWT.OK); - mb.setText(Messages.DropAdapterAssistant_RenameTraceTitle); - mb.setMessage(NLS.bind(Messages.DropAdapterAssistant_RenameTraceMessage, element.getName())); - if (mb.open() != SWT.OK) { - return null; - } - IContainer folder = element.getResource().getParent(); - int i = 2; - while (true) { - String name = element.getName() + '(' + Integer.toString(i++) + ')'; - IResource resource = folder.findMember(name); - if (resource == null) { - return name; - } - } - } - - /** - * Cleanup bookmarks file in copied trace - */ - private static void cleanupBookmarks(IPath path) { - IFolder folder = ResourcesPlugin.getWorkspace().getRoot().getFolder(path); - if (folder.exists()) { - try { - for (IResource member : folder.members()) { - if (TmfTrace.class.getCanonicalName().equals(TmfTraceType.getTraceTypeId(member))) { - member.delete(true, null); - } - } - } catch (CoreException e) { - displayException(e); - } - } - } - - private static void setTraceType(IResource traceResource) { - try { - String traceType = TmfTraceType.getTraceTypeId(traceResource); - TraceTypeHelper traceTypeHelper = TmfTraceType.getTraceType(traceType); - if (traceTypeHelper == null) { - traceTypeHelper = TmfTraceTypeUIUtils.selectTraceType(traceResource.getLocation().toOSString(), null, null); - } - if (traceTypeHelper != null) { - TmfTraceTypeUIUtils.setTraceType(traceResource, traceTypeHelper); - } - } catch (TmfTraceImportException e) { - } catch (CoreException e) { - displayException(e); - } - } - - /** - * Display an exception in a message box - * - * @param e the exception - */ - private static void displayException(Exception e) { - MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()); - mb.setText(e.getClass().getName()); - mb.setMessage(e.getMessage()); - mb.open(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/ImportTraceHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/ImportTraceHandler.java deleted file mode 100644 index b558b87c3c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/ImportTraceHandler.java +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Update selection handling - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace.ImportTraceWizard; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.handlers.HandlerUtil; - -/** - * ImportTraceHandler - *

- * Starts an ImportTraceWizard that will handle the lowly details. - */ -public class ImportTraceHandler extends AbstractHandler { - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - ImportTraceWizard w = new ImportTraceWizard(); - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - - if (window == null) { - return false; - } - - ISelection currentSelection = HandlerUtil.getCurrentSelection(event); - // Menu Selection is only not null for context-sensitive menu - ISelection menuSelection = HandlerUtil.getActiveMenuSelection(event); - - IStructuredSelection sec = StructuredSelection.EMPTY; - - // Only use the selection if handler is called from context-sensitive menu - if ((menuSelection != null) && (currentSelection instanceof IStructuredSelection)) { - sec = (IStructuredSelection) currentSelection; - } - - w.init(PlatformUI.getWorkbench(), sec); - WizardDialog dialog = new WizardDialog(window.getShell(), w); - dialog.open(); - return null; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/Messages.java deleted file mode 100644 index 0b93660ae3..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/Messages.java +++ /dev/null @@ -1,85 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Added drag and drop messages - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import org.eclipse.osgi.util.NLS; - -/** - * Messages file - * - * @author Francois Chouinard - * @version 1.0 - */ -@SuppressWarnings("javadoc") -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.tmf.ui.project.handlers.messages"; //$NON-NLS-1$ - - public static String DeleteDialog_Title; - public static String DeleteTraceHandler_Message; - public static String DeleteTraceHandler_Error; - public static String DeleteTraceHandler_TaskName; - public static String DeleteTraceHandlerGeneric_Message; - public static String DeleteTraceHandlerGeneric_Error; - public static String DeleteExperimentHandler_Message; - public static String DeleteExperimentHandler_Error; - public static String DeleteFolderHandler_Message; - public static String DeleteFolderHandler_Error; - public static String DeleteFolderHandler_TaskName; - - public static String RemoveDialog_Title; - public static String RemoveTraceFromExperimentHandler_Message; - public static String RemoveTraceFromExperimentHandler_TaskName; - public static String RemoveTraceFromExperimentHandler_Error; - public static String ClearDialog_Title; - public static String DeleteFolderHandlerClear_Message; - public static String DeleteFolderHandlerClear_Error; - public static String DeleteFolderHandlerClear_TaskName; - - public static String SelectTraceTypeHandler_ErrorSelectingTrace; - public static String SelectTraceTypeHandler_Title; - public static String SelectTraceTypeHandler_TraceFailedValidation; - public static String SelectTraceTypeHandler_TracesFailedValidation; - public static String SelectTraceTypeHandler_InvalidTraceType; - - public static String DropAdapterAssistant_RenameTraceTitle; - public static String DropAdapterAssistant_RenameTraceMessage; - - public static String SynchronizeTracesHandler_InitError; - public static String SynchronizeTracesHandler_CopyProblem; - public static String SynchronizeTracesHandler_WrongType; - public static String SynchronizeTracesHandler_WrongTraceNumber; - public static String SynchronizeTracesHandler_Title; - public static String SynchronizeTracesHandler_Error; - public static String SynchronizeTracesHandler_ErrorSynchingExperiment; - public static String SynchronizeTracesHandler_ErrorSynchingForTrace; - - public static String ClearTraceOffsetHandler_Title; - public static String ClearTraceOffsetHandler_ConfirmMessage; - - public static String DeleteSupplementaryFiles_DeletionTask; - public static String DeleteSupplementaryFiles_ProjectRefreshTask; - - public static String AnalysisModule_Help; - - public static String TmfActionProvider_OpenWith; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/NewExperimentHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/NewExperimentHandler.java deleted file mode 100644 index b0b15f5a9b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/NewExperimentHandler.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentFolder; -import org.eclipse.linuxtools.tmf.ui.project.wizards.NewExperimentDialog; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -/** - * NewExperimentHandler - *

- */ -public class NewExperimentHandler extends AbstractHandler { - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - - // Get the selection - IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - IWorkbenchPart part = page.getActivePart(); - if (part == null) { - return Boolean.FALSE; - } - ISelection selection = part.getSite().getSelectionProvider().getSelection(); - TmfExperimentFolder experimentFolder = null; - if (selection instanceof TreeSelection) { - TreeSelection sel = (TreeSelection) selection; - Object element = sel.getFirstElement(); - if (element instanceof TmfExperimentFolder) { - experimentFolder = (TmfExperimentFolder) element; - } - } - if (experimentFolder == null) { - return null; - } - - // Fire the New Experiment dialog - Shell shell = window.getShell(); - NewExperimentDialog dialog = new NewExperimentDialog(shell, experimentFolder); - dialog.open(); - - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/NewFolderHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/NewFolderHandler.java deleted file mode 100644 index f9e98c590a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/NewFolderHandler.java +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.linuxtools.tmf.ui.project.wizards.NewFolderDialog; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.handlers.HandlerUtil; - -/** - * Handler for the New Folder command. - */ -public class NewFolderHandler extends AbstractHandler { - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - - ISelection selection = HandlerUtil.getCurrentSelection(event); - if (!(selection instanceof IStructuredSelection)) { - return null; - } - final Object element = ((IStructuredSelection) selection).getFirstElement(); - if (!(element instanceof TmfTraceFolder)) { - return null; - } - TmfTraceFolder parent = (TmfTraceFolder) element; - - // Fire the New Folder dialog - Shell shell = window.getShell(); - NewFolderDialog dialog = new NewFolderDialog(shell, parent); - dialog.open(); - - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OffsetTraceHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OffsetTraceHandler.java deleted file mode 100644 index 564e9debb9..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OffsetTraceHandler.java +++ /dev/null @@ -1,132 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import java.lang.reflect.InvocationTargetException; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.window.Window; -import org.eclipse.linuxtools.internal.tmf.ui.project.dialogs.offset.OffsetDialog; -import org.eclipse.linuxtools.internal.tmf.ui.project.operations.TmfWorkspaceModifyOperation; -import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform; -import org.eclipse.linuxtools.tmf.core.synchronization.TimestampTransformFactory; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.handlers.HandlerUtil; - -/** - * Offset Handler - * - * @author Matthew Khouzam - */ -public class OffsetTraceHandler extends AbstractHandler { - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - @Override - public Object execute(final ExecutionEvent event) throws ExecutionException { - - ISelection selection = HandlerUtil.getCurrentSelection(event); - - // Get the set of selected trace elements - final Set traceElements = new HashSet<>(); - if (selection instanceof StructuredSelection) { - Iterator iterator = ((StructuredSelection) selection).iterator(); - while (iterator.hasNext()) { - Object element = iterator.next(); - if (element instanceof TmfTraceElement) { - TmfTraceElement trace = (TmfTraceElement) element; - traceElements.add(trace.getElementUnderTraceFolder()); - } else if (element instanceof TmfExperimentElement) { - TmfExperimentElement exp = (TmfExperimentElement) element; - for (TmfTraceElement trace : exp.getTraces()) { - traceElements.add(trace.getElementUnderTraceFolder()); - } - } else if (element instanceof TmfTraceFolder) { - TmfTraceFolder folder = (TmfTraceFolder) element; - traceElements.addAll(folder.getTraces()); - } - } - } - - final Map offsets = new LinkedHashMap<>(traceElements.size()); - for (TmfTraceElement trace : traceElements) { - offsets.put(trace, 0L); - } - - Shell shell = HandlerUtil.getActiveShellChecked(event); - OffsetDialog dialog = new OffsetDialog(shell, offsets); - dialog.open(); - - if (dialog.getReturnCode() != Window.OK) { - return null; - } - - TmfWorkspaceModifyOperation operation = new TmfWorkspaceModifyOperation() { - @Override - public void execute(IProgressMonitor monitor) throws CoreException { - for (final TmfTraceElement trace : offsets.keySet()) { - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - Long offset = offsets.get(trace); - if (offset != 0 && trace.getResource().exists()) { - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - trace.closeEditors(); - } - }); - long previousOffset = TimestampTransformFactory.getTimestampTransform(trace.getResource()).transform(0); - ITmfTimestampTransform transform = TimestampTransformFactory.createWithOffset(previousOffset + offset); - trace.deleteSupplementaryResources(); - // make sure the supplementary folder exists - trace.refreshSupplementaryFolder(); - TimestampTransformFactory.setTimestampTransform(trace.getResource(), transform); - trace.refreshSupplementaryFolder(); - } - } - } - }; - try { - PlatformUI.getWorkbench().getProgressService().run(true, true, operation); - } catch (InterruptedException e) { - return null; - } catch (InvocationTargetException e) { - MessageDialog.openError(shell, e.toString(), e.getTargetException().toString()); - return null; - } - - return null; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAction.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAction.java deleted file mode 100644 index 70b418bb6b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAction.java +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.commands.NotEnabledException; -import org.eclipse.core.commands.NotHandledException; -import org.eclipse.core.commands.common.NotDefinedException; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfAnalysisOutputElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectModelElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.handlers.IHandlerService; - -/** - * OpenAction - */ -public class OpenAction extends Action { - - private static final String OPEN_COMMAND_ID = "org.eclipse.ui.navigate.openResource"; //$NON-NLS-1$ - - private final IWorkbenchPage page; - private final ISelectionProvider selectionProvider; - private TmfProjectModelElement element; - - /** - * Default constructor - * @param page the workbench page - * @param selectionProvider the selection provider - */ - public OpenAction(IWorkbenchPage page, ISelectionProvider selectionProvider) { - this.page = page; - this.selectionProvider = selectionProvider; - } - - @Override - public boolean isEnabled() { - ISelection selection = selectionProvider.getSelection(); - if (!selection.isEmpty()) { - IStructuredSelection sSelection = (IStructuredSelection) selection; - if (sSelection.size() == 1) { - if (sSelection.getFirstElement() instanceof TmfTraceElement || - sSelection.getFirstElement() instanceof TmfExperimentElement || - sSelection.getFirstElement() instanceof TmfAnalysisOutputElement) { - element = (TmfProjectModelElement) sSelection.getFirstElement(); - return true; - } - } - } - return false; - } - - @Override - public void run() { - try { - IHandlerService handlerService = (IHandlerService) page.getActivePart().getSite().getService(IHandlerService.class); - boolean executeCommand = ((element instanceof TmfTraceElement) || (element instanceof TmfAnalysisOutputElement)); - - if (!executeCommand && element instanceof TmfExperimentElement) { - TmfExperimentElement experiment = (TmfExperimentElement) element; - executeCommand = (experiment.getTraces().size() > 0); - } - - if (executeCommand) { - handlerService.executeCommand(OPEN_COMMAND_ID, null); - } - } catch (ExecutionException e) { - Activator.getDefault().logError("Error opening resource " + element.getName(), e); //$NON-NLS-1$ - } catch (NotDefinedException e) { - Activator.getDefault().logError("Error opening resource " + element.getName(), e); //$NON-NLS-1$ - } catch (NotEnabledException e) { - Activator.getDefault().logError("Error opening resource " + element.getName(), e); //$NON-NLS-1$ - } catch (NotHandledException e) { - Activator.getDefault().logError("Error opening resource " + element.getName(), e); //$NON-NLS-1$ - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAnalysisHelpHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAnalysisHelpHandler.java deleted file mode 100644 index 6ad18fce45..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAnalysisHelpHandler.java +++ /dev/null @@ -1,114 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfAnalysisElement; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.MessageBox; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -/** - * Handler for when user wants to open the analysis help text - * - * @author Geneviève Bastien - */ -public class OpenAnalysisHelpHandler extends AbstractHandler { - - private TmfAnalysisElement fAnalysis; - - @Override - public boolean isEnabled() { - // Check if we are closing down - final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return false; - } - - // Get the selection - final IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - final IWorkbenchPart part = page.getActivePart(); - if (part == null) { - return false; - } - final ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); - if (selectionProvider == null) { - return false; - } - final ISelection selection = selectionProvider.getSelection(); - - // Make sure there is only one selection and that it is a trace - fAnalysis = null; - if (selection instanceof TreeSelection) { - final TreeSelection sel = (TreeSelection) selection; - // There should be only one item selected as per the plugin.xml - final Object element = sel.getFirstElement(); - if (element instanceof TmfAnalysisElement) { - fAnalysis = (TmfAnalysisElement) element; - } - } - - return (fAnalysis != null); - } - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - // Check if we are closing down - final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - - // Check that the trace is valid - if (fAnalysis == null) { - return null; - } - - Thread thread = new Thread() { - @Override - public void run() { - displayHelpMsg(fAnalysis.getHelpMessage()); - } - }; - - thread.start(); - - return null; - } - - private static void displayHelpMsg(final String errorMsg) { - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - /* - * TODO: A message box is not the best place to show help. - * Something should be done with the Eclipse help - */ - final MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()); - mb.setText(Messages.AnalysisModule_Help); - mb.setMessage(errorMsg); - mb.open(); - } - }); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAnalysisOutputHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAnalysisOutputHandler.java deleted file mode 100644 index 772450d16b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAnalysisOutputHandler.java +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfAnalysisOutputElement; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -/** - * Handler to programatically open a view - * - * @author Geneviève Bastien - */ -public class OpenAnalysisOutputHandler extends AbstractHandler { - - private TmfAnalysisOutputElement fOutputElement; - - @Override - public boolean isEnabled() { - /* Check if we are closing down */ - final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return false; - } - - /* Get the selection */ - final IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - final IWorkbenchPart part = page.getActivePart(); - if (part == null) { - return false; - } - final ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); - if (selectionProvider == null) { - return false; - } - final ISelection selection = selectionProvider.getSelection(); - - /* Make sure there is only one selection and that it is an analysis output */ - fOutputElement = null; - if (selection instanceof TreeSelection) { - final TreeSelection sel = (TreeSelection) selection; - // There should be only one item selected as per the plugin.xml - final Object element = sel.getFirstElement(); - if (element instanceof TmfAnalysisOutputElement) { - fOutputElement = (TmfAnalysisOutputElement) element; - } - } - - return (fOutputElement != null); - } - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - /* Check if we are closing down */ - final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - - /* Check that the view is valid */ - if (fOutputElement == null) { - return null; - } - - fOutputElement.outputAnalysis(); - - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenExperimentHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenExperimentHandler.java deleted file mode 100644 index f4eac3ce10..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenExperimentHandler.java +++ /dev/null @@ -1,99 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Geneviève Bastien - Experiment instantiates with an experiment type - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfOpenTraceHelper; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -/** - * OpenExperimentHandler - *

- */ -public class OpenExperimentHandler extends AbstractHandler { - - private TmfExperimentElement fExperiment = null; - - // ------------------------------------------------------------------------ - // Validation - // ------------------------------------------------------------------------ - - @Override - public boolean isEnabled() { - - // Check if we are closing down - final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return false; - } - - // Get the selection - final IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - final IWorkbenchPart part = page.getActivePart(); - if (part == null) { - return false; - } - final ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); - if (selectionProvider == null) { - return false; - } - final ISelection selection = selectionProvider.getSelection(); - - // Make sure there is only one selection and that it is an experiment - fExperiment = null; - if (selection instanceof TreeSelection) { - final TreeSelection sel = (TreeSelection) selection; - // There should be only one item selected as per the plugin.xml - final Object element = sel.getFirstElement(); - if (element instanceof TmfExperimentElement) { - fExperiment = (TmfExperimentElement) element; - } - } - - // We only enable opening from the Traces folder for now - return ((fExperiment != null) && (fExperiment.getTraces().size() > 0)); - } - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - @Override - public Object execute(final ExecutionEvent event) throws ExecutionException { - - // Check if we are closing down - final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - - // Check that the experiment is valid - if (fExperiment == null) { - return null; - } - - TmfOpenTraceHelper.openTraceFromElement(fExperiment); - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenTraceHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenTraceHandler.java deleted file mode 100644 index 1eeb9f97b4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenTraceHandler.java +++ /dev/null @@ -1,104 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfOpenTraceHelper; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -/** - * OpenTraceHandler - *

- * TODO: Add support for multiple trace selection - */ -public class OpenTraceHandler extends AbstractHandler { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private TmfTraceElement fTrace = null; - - // ------------------------------------------------------------------------ - // Validation - // ------------------------------------------------------------------------ - - @Override - public boolean isEnabled() { - - // Check if we are closing down - final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return false; - } - - // Get the selection - final IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - final IWorkbenchPart part = page.getActivePart(); - if (part == null) { - return false; - } - final ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); - if (selectionProvider == null) { - return false; - } - final ISelection selection = selectionProvider.getSelection(); - - // Make sure there is only one selection and that it is a trace - fTrace = null; - if (selection instanceof TreeSelection) { - final TreeSelection sel = (TreeSelection) selection; - // There should be only one item selected as per the plugin.xml - final Object element = sel.getFirstElement(); - if (element instanceof TmfTraceElement) { - fTrace = (TmfTraceElement) element; - } - } - - // We only enable opening from the Traces folder for now - return (fTrace != null); - } - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - @Override - public Object execute(final ExecutionEvent event) throws ExecutionException { - - // Check if we are closing down - final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - - // Check that the trace is valid - if (fTrace == null) { - return null; - } - - // If trace is under an experiment, use the original trace from the traces folder - TmfOpenTraceHelper.openTraceFromElement(fTrace.getElementUnderTraceFolder()); - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/RefreshHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/RefreshHandler.java deleted file mode 100644 index c947be07c3..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/RefreshHandler.java +++ /dev/null @@ -1,87 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentFolder; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -/** - * RefreshHandler - *

- * TODO: Handle multiple selections - */ -public class RefreshHandler extends AbstractHandler { - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - - // Get the selection - IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - IWorkbenchPart part = page.getActivePart(); - if (part == null) { - return false; - } - ISelection selection = part.getSite().getSelectionProvider().getSelection(); - if (selection instanceof TreeSelection) { - TreeSelection treeSelection = (TreeSelection) selection; - Object element = treeSelection.getFirstElement(); - IResource resource = null; - if (element instanceof TmfTraceFolder) { - TmfTraceFolder folder = (TmfTraceFolder) element; - resource = folder.getResource(); - } - else if (element instanceof TmfExperimentFolder) { - TmfExperimentFolder folder = (TmfExperimentFolder) element; - resource = folder.getResource(); - } - else if (element instanceof TmfExperimentElement) { - TmfExperimentElement folder = (TmfExperimentElement) element; - resource = folder.getResource(); - } - try { - if (resource != null) { - resource.refreshLocal(IResource.DEPTH_INFINITE, null); - } - } catch (CoreException e) { - Activator.getDefault().logError("Error refreshing projects", e); //$NON-NLS-1$ - } - } - - - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/RenameExperimentHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/RenameExperimentHandler.java deleted file mode 100644 index de96794c14..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/RenameExperimentHandler.java +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.wizards.RenameExperimentDialog; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -/** - * RenameExperimentHandler - *

- */ -public class RenameExperimentHandler extends AbstractHandler { - - private TmfExperimentElement fExperiment = null; - - // ------------------------------------------------------------------------ - // isEnabled - // ------------------------------------------------------------------------ - - @Override - public boolean isEnabled() { - - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return false; - } - - // Get the selection - IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - IWorkbenchPart part = page.getActivePart(); - if (part == null) { - return false; - } - ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); - if (selectionProvider == null) { - return false; - } - ISelection selection = selectionProvider.getSelection(); - - // Make sure there is only selection and that it is an experiment - fExperiment = null; - if (selection instanceof TreeSelection) { - TreeSelection sel = (TreeSelection) selection; - Object element = sel.getFirstElement(); - if (element instanceof TmfExperimentElement) { - fExperiment = (TmfExperimentElement) element; - } - } - - return (fExperiment != null); - } - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - - // Fire the Rename Experiment dialog - Shell shell = window.getShell(); - RenameExperimentDialog dialog = new RenameExperimentDialog(shell, fExperiment); - dialog.open(); - - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/RenameFolderHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/RenameFolderHandler.java deleted file mode 100644 index 81db31c20f..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/RenameFolderHandler.java +++ /dev/null @@ -1,158 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.window.Window; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.linuxtools.tmf.ui.project.wizards.RenameFolderDialog; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.actions.WorkspaceModifyOperation; -import org.eclipse.ui.handlers.HandlerUtil; - -/** - * Handler for the Rename Folder command. - */ -public class RenameFolderHandler extends AbstractHandler { - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - - ISelection selection = HandlerUtil.getCurrentSelection(event); - TmfTraceFolder selectedFolder = null; - if (selection instanceof IStructuredSelection) { - Object element = ((IStructuredSelection) selection).getFirstElement(); - if (element instanceof TmfTraceFolder) { - selectedFolder = (TmfTraceFolder) element; - } - } - if (selectedFolder == null) { - return null; - } - final TmfTraceFolder oldFolder = selectedFolder; - - // Fire the Rename Folder dialog - RenameFolderDialog dialog = new RenameFolderDialog(window.getShell(), oldFolder); - dialog.open(); - - if (dialog.getReturnCode() != Window.OK) { - return null; - } - - final String newName = (String) dialog.getFirstResult(); - - IContainer parentFolder = oldFolder.getResource().getParent(); - final TmfTraceFolder tracesFolder = oldFolder.getProject().getTracesFolder(); - final IPath newFolderPath = parentFolder.getFullPath().append(newName); - - WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { - @Override - public void execute(IProgressMonitor monitor) throws CoreException { - try { - monitor.beginTask("", 1000); //$NON-NLS-1$ - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - - for (TmfTraceElement traceElement : oldFolder.getTraces()) { - traceElement.closeEditors(); - - IPath relativePath = traceElement.getPath().makeRelativeTo(oldFolder.getPath()); - String newElementPath = newFolderPath.makeRelativeTo(tracesFolder.getPath()).append(relativePath).toString(); - traceElement.renameSupplementaryFolder(newElementPath); - } - - oldFolder.getResource().move(newFolderPath, IResource.FORCE | IResource.SHALLOW, monitor); - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - } finally { - monitor.done(); - } - } - }; - - try { - PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); - } catch (InterruptedException e) { - return null; - } catch (InvocationTargetException e) { - MessageDialog.openError(window.getShell(), e.toString(), e.getTargetException().toString()); - return null; - } - - /* We need to split the WorkspaceModifyOperation so that the new model - * elements get created by the resource changed event */ - operation = new WorkspaceModifyOperation() { - @Override - protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException { - - IPath oldFolderElementPath = oldFolder.getPath().makeRelativeTo(tracesFolder.getPath()); - IPath newFolderElementPath = oldFolderElementPath.removeLastSegments(1).append(newName); - for (TmfExperimentElement experiment : oldFolder.getProject().getExperimentsFolder().getExperiments()) { - for (TmfTraceElement oldTrace : experiment.getTraces()) { - if (oldTrace.getElementPath().startsWith(oldFolderElementPath.toString())) { - experiment.removeTrace(oldTrace); - String relativePath = oldTrace.getElementPath().substring(oldFolderElementPath.toString().length() + 1); - String newTraceElementPath = newFolderElementPath.append(relativePath).toString(); - for (TmfTraceElement newTrace : tracesFolder.getTraces()) { - if (newTrace.getElementPath().equals(newTraceElementPath)) { - experiment.addTrace(newTrace); - break; - } - } - } - } - } - } - }; - - try { - PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); - } catch (InterruptedException e) { - return null; - } catch (InvocationTargetException e) { - MessageDialog.openError(window.getShell(), e.toString(), e.getTargetException().toString()); - return null; - } - - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/RenameTraceHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/RenameTraceHandler.java deleted file mode 100644 index 6458a73fb2..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/RenameTraceHandler.java +++ /dev/null @@ -1,171 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Add support for folder elements - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.window.Window; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentFolder; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.linuxtools.tmf.ui.project.wizards.RenameTraceDialog; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.actions.WorkspaceModifyOperation; -import org.eclipse.ui.handlers.HandlerUtil; - -/** - * Handler for the Rename Trace command. - */ -public class RenameTraceHandler extends AbstractHandler { - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - - ISelection selection = HandlerUtil.getCurrentSelection(event); - TmfTraceElement selectedTrace = null; - if (selection instanceof IStructuredSelection) { - Object element = ((IStructuredSelection) selection).getFirstElement(); - if (element instanceof TmfTraceElement) { - selectedTrace = (TmfTraceElement) element; - } - } - if (selectedTrace == null) { - return null; - } - - // If trace is under an experiment, use the original trace from the traces folder - final TmfTraceElement oldTrace = selectedTrace.getElementUnderTraceFolder(); - - RenameTraceDialog dialog = new RenameTraceDialog(window.getShell(), oldTrace); - if (dialog.open() != Window.OK) { - return null; - } - - final TmfTraceFolder traceFolder = (TmfTraceFolder) oldTrace.getParent(); - final String newName = (String) dialog.getFirstResult(); - - IFolder parentFolder = (IFolder) oldTrace.getParent().getResource(); - final TmfTraceFolder tracesFolder = oldTrace.getProject().getTracesFolder(); - final IPath newPath = parentFolder.getFullPath().append(newName); - - WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { - @Override - public void execute(IProgressMonitor monitor) throws CoreException { - try { - monitor.beginTask("", 1000); //$NON-NLS-1$ - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - // Close the trace if open - oldTrace.closeEditors(); - - if (oldTrace.getResource() instanceof IFolder) { - IFolder folder = (IFolder) oldTrace.getResource(); - IFile bookmarksFile = oldTrace.getBookmarksFile(); - if (bookmarksFile.exists()) { - IFile newBookmarksFile = folder.getFile(bookmarksFile.getName().replace(oldTrace.getName(), newName)); - if (!newBookmarksFile.exists()) { - IPath newBookmarksPath = newBookmarksFile.getFullPath(); - bookmarksFile.move(newBookmarksPath, IResource.FORCE | IResource.SHALLOW, monitor); - } - } - } - - String newElementPath = newPath.makeRelativeTo(tracesFolder.getPath()).toString(); - oldTrace.renameSupplementaryFolder(newElementPath); - oldTrace.getResource().move(newPath, IResource.FORCE | IResource.SHALLOW, monitor); - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - } finally { - monitor.done(); - } - } - }; - - try { - PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); - } catch (InterruptedException e) { - return null; - } catch (InvocationTargetException e) { - MessageDialog.openError(window.getShell(), e.toString(), e.getTargetException().toString()); - return null; - } - - /* We need to split the WorkspaceModifyOperation so that the new model - * elements get created by the resource changed event */ - operation = new WorkspaceModifyOperation() { - @Override - protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException { - - // Locate the new trace object - TmfTraceElement newTrace = null; - String newElementPath = oldTrace.getParent().getPath().append(newName).makeRelativeTo(tracesFolder.getPath()).toString(); - for (TmfTraceElement element : traceFolder.getTraces()) { - if (element.getElementPath().equals(newElementPath)) { - newTrace = element; - break; - } - } - if (newTrace == null) { - return; - } - - TmfExperimentFolder experimentFolder = newTrace.getProject().getExperimentsFolder(); - for (final TmfExperimentElement experiment : experimentFolder.getExperiments()) { - for (final TmfTraceElement expTrace : experiment.getTraces()) { - if (expTrace.getElementPath().equals(oldTrace.getElementPath())) { - experiment.removeTrace(expTrace); - experiment.addTrace(newTrace); - } - } - } - } - }; - - try { - PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); - } catch (InterruptedException e) { - } catch (InvocationTargetException e) { - MessageDialog.openError(window.getShell(), e.toString(), e.getTargetException().toString()); - } - - return null; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SelectElementTypeContributionItem.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SelectElementTypeContributionItem.java deleted file mode 100644 index 56e911041f..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SelectElementTypeContributionItem.java +++ /dev/null @@ -1,269 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Geneviève Bastien - Moved SelectTraceTypeContributionItem to this class - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.Platform; -import org.eclipse.jface.action.IContributionItem; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTrace; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTraceDefinition; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTrace; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType.TraceElementType; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceTypeUIUtils; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.actions.CompoundContributionItem; -import org.eclipse.ui.menus.CommandContributionItem; -import org.eclipse.ui.menus.CommandContributionItemParameter; - -/** - * ContributionItem for the element type selection. - * - * @author Patrick Tassé - */ -public class SelectElementTypeContributionItem extends CompoundContributionItem { - - private static final ImageDescriptor SELECTED_ICON = Activator.getDefault().getImageDescripterFromPath("icons/elcl16/bullet.gif"); //$NON-NLS-1$ - private static final String BUNDLE_PARAMETER = "org.eclipse.linuxtools.tmf.ui.commandparameter.select_trace_type.bundle"; //$NON-NLS-1$ - private static final String TYPE_PARAMETER = "org.eclipse.linuxtools.tmf.ui.commandparameter.select_trace_type.type"; //$NON-NLS-1$ - private static final String ICON_PARAMETER = "org.eclipse.linuxtools.tmf.ui.commandparameter.select_trace_type.icon"; //$NON-NLS-1$ - private static final String SELECT_TRACE_TYPE_COMMAND_ID = "org.eclipse.linuxtools.tmf.ui.command.select_trace_type"; //$NON-NLS-1$ - private static final String DEFAULT_TRACE_ICON_PATH = "icons/elcl16/trace.gif"; //$NON-NLS-1$ - - @Override - protected IContributionItem[] getContributionItems() { - - /* - * Fill the selected trace types and verify if selection applies only to - * either traces or experiments - */ - Set selectedTraceTypes = new HashSet<>(); - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - IWorkbenchPage page = window.getActivePage(); - ISelection selection = page.getSelection(); - boolean forTraces = false, forExperiments = false; - if (selection instanceof StructuredSelection) { - for (Object element : ((StructuredSelection) selection).toList()) { - if (element instanceof TmfTraceElement) { - TmfTraceElement trace = (TmfTraceElement) element; - selectedTraceTypes.add(trace.getTraceType()); - forTraces = true; - } else if (element instanceof TmfExperimentElement) { - TmfExperimentElement exp = (TmfExperimentElement) element; - selectedTraceTypes.add(exp.getTraceType()); - forExperiments = true; - } - } - } - - if (forTraces && forExperiments) { - /* This should never happen anyways */ - throw new RuntimeException("You must select only experiments or only traces to set the element type"); //$NON-NLS-1$ - } - - return getContributionItems(selectedTraceTypes, forExperiments); - } - - /** - * Get the contribution items for traces - * - * @param selectedTraceTypes - * The set of selected trace types - * @param forExperiments - * true if the contribution items are requested for - * experiments, false for traces - * - * @return The list of contribution items - */ - protected IContributionItem[] getContributionItems(Set selectedTraceTypes, boolean forExperiments) { - - String ceType = forExperiments ? TmfTraceType.EXPERIMENT_ELEM : TmfTraceType.TYPE_ELEM; - TraceElementType elementType = forExperiments ? TraceElementType.EXPERIMENT : TraceElementType.TRACE; - - List list = new LinkedList<>(); - - Map categoriesMap = new HashMap<>(); - IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor( - TmfTraceType.TMF_TRACE_TYPE_ID); - for (IConfigurationElement ce : config) { - if (ce.getName().equals(TmfTraceType.CATEGORY_ELEM)) { - String categoryId = ce.getAttribute(TmfTraceType.ID_ATTR); - ImageDescriptor icon = isSelectedCategory(categoryId, config, selectedTraceTypes) ? SELECTED_ICON : null; - MenuManager subMenu = new MenuManager(ce.getAttribute(TmfTraceType.NAME_ATTR), icon, null); - categoriesMap.put(categoryId, subMenu); - list.add(subMenu); - } - } - - for (IConfigurationElement ce : config) { - if (ce.getName().equals(ceType)) { - String traceBundle = ce.getContributor().getName(); - String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR); - String label = ce.getAttribute(TmfTraceType.NAME_ATTR).replaceAll("&", "&&"); //$NON-NLS-1$ //$NON-NLS-2$ - boolean selected = selectedTraceTypes.contains(traceTypeId); - MenuManager subMenu = categoriesMap.get(ce.getAttribute(TmfTraceType.CATEGORY_ATTR)); - - /* Get the icon from the tmftracetypeui extension, if it exists */ - String traceIcon = null; - IConfigurationElement uiCE = TmfTraceTypeUIUtils.getTraceUIAttributes(traceTypeId, elementType); - if (uiCE != null) { - traceIcon = uiCE.getAttribute(TmfTraceTypeUIUtils.ICON_ATTR); - } - - addContributionItem(list, traceBundle, traceTypeId, traceIcon, label, selected, subMenu); - } - } - - Comparator comparator = new Comparator() { - @Override - public int compare(IContributionItem o1, IContributionItem o2) { - if (o1 instanceof MenuManager) { - if (o2 instanceof MenuManager) { - MenuManager m1 = (MenuManager) o1; - MenuManager m2 = (MenuManager) o2; - return m1.getMenuText().compareTo(m2.getMenuText()); - } - return -1; - } - if (o2 instanceof MenuManager) { - return 1; - } - CommandContributionItem c1 = (CommandContributionItem) o1; - CommandContributionItem c2 = (CommandContributionItem) o2; - return c1.getData().label.compareTo(c2.getData().label); - } - }; - - if (forExperiments) { - Collections.sort(list, comparator); - return list.toArray(new IContributionItem[list.size()]); - } - - /* - * Add the custom txt and xml trace type to the contribution items for - * traces - */ - for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) { - String traceBundle = Activator.getDefault().getBundle().getSymbolicName(); - String traceTypeId = CustomTxtTrace.class.getCanonicalName() + ':' + def.categoryName + ':' + def.definitionName; - String traceIcon = DEFAULT_TRACE_ICON_PATH; - String label = def.definitionName; - boolean selected = selectedTraceTypes.contains(traceTypeId); - MenuManager subMenu = getCategorySubMenu(list, categoriesMap, def.categoryName, selected); - - addContributionItem(list, traceBundle, traceTypeId, traceIcon, label, selected, subMenu); - } - for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { - String traceBundle = Activator.getDefault().getBundle().getSymbolicName(); - String traceTypeId = CustomXmlTrace.class.getCanonicalName() + ':' + def.categoryName + ':' + def.definitionName; - String traceIcon = DEFAULT_TRACE_ICON_PATH; - String label = def.definitionName; - boolean selected = selectedTraceTypes.contains(traceTypeId); - MenuManager subMenu = getCategorySubMenu(list, categoriesMap, def.categoryName, selected); - - addContributionItem(list, traceBundle, traceTypeId, traceIcon, label, selected, subMenu); - } - - Collections.sort(list, comparator); - return list.toArray(new IContributionItem[list.size()]); - } - - private static MenuManager getCategorySubMenu(List list, - Map categoriesMap, String categoryName, boolean selected) { - for (Entry entry : categoriesMap.entrySet()) { - MenuManager subMenu = entry.getValue(); - if (subMenu.getMenuText().equals(categoryName)) { - if (selected) { - subMenu.setImageDescriptor(SELECTED_ICON); - } - return subMenu; - } - } - ImageDescriptor icon = selected ? SELECTED_ICON : null; - MenuManager subMenu = new MenuManager(categoryName, icon, null); - categoriesMap.put(categoryName, subMenu); - list.add(subMenu); - return subMenu; - } - - private static void addContributionItem(List list, - String traceBundle, String traceTypeId, String traceIcon, - String label, boolean selected, - MenuManager subMenu) { - Map params; - - params = new HashMap<>(); - params.put(BUNDLE_PARAMETER, traceBundle); - params.put(TYPE_PARAMETER, traceTypeId); - params.put(ICON_PARAMETER, traceIcon); - - ImageDescriptor icon = null; - if (selected) { - icon = SELECTED_ICON; - } - - CommandContributionItemParameter param = new CommandContributionItemParameter( - PlatformUI.getWorkbench().getActiveWorkbenchWindow(), // serviceLocator - "my.parameterid", // id //$NON-NLS-1$ - SELECT_TRACE_TYPE_COMMAND_ID, // commandId - CommandContributionItem.STYLE_PUSH // style - ); - param.parameters = params; - param.icon = icon; - param.disabledIcon = icon; - param.hoverIcon = icon; - param.label = label; - param.visibleEnabled = true; - - if (subMenu != null) { - subMenu.add(new CommandContributionItem(param)); - } else { - list.add(new CommandContributionItem(param)); - } - } - - private static boolean isSelectedCategory(String categoryId, IConfigurationElement[] config, Set selectedTraceTypes) { - for (IConfigurationElement ce : config) { - if (ce.getName().equals(TmfTraceType.TYPE_ELEM)) { - String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR); - if (selectedTraceTypes.contains(traceTypeId)) { - if (categoryId.equals(ce.getAttribute(TmfTraceType.CATEGORY_ATTR))) { - return true; - } - } - } - } - return false; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SelectTraceTypeHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SelectTraceTypeHandler.java deleted file mode 100644 index 5d765227fb..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SelectTraceTypeHandler.java +++ /dev/null @@ -1,203 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Fix propagation to experiment traces - * Geneviève Bastien - Add support of experiment types - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfCommonProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentFolder; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceTypeUIUtils; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -/** - * SetTraceTypeHandler - *

- */ -public class SelectTraceTypeHandler extends AbstractHandler { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - private static final String TYPE_PARAMETER = "org.eclipse.linuxtools.tmf.ui.commandparameter.select_trace_type.type"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private TreeSelection fSelection = null; - - // ------------------------------------------------------------------------ - // Validation - // ------------------------------------------------------------------------ - - @Override - public boolean isEnabled() { - - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return false; - } - - // Get the selection - IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - IWorkbenchPart part = page.getActivePart(); - if (part == null) { - return false; - } - ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); - if (selectionProvider == null) { - return false; - } - ISelection selection = selectionProvider.getSelection(); - - // Make sure selection contains only traces - fSelection = null; - if (selection instanceof TreeSelection) { - fSelection = (TreeSelection) selection; - Iterator iterator = fSelection.iterator(); - while (iterator.hasNext()) { - Object element = iterator.next(); - if (!(element instanceof TmfCommonProjectElement)) { - return false; - } - } - } - - // If we get here, either nothing is selected or everything is a trace - return !selection.isEmpty(); - } - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - List statuses = new ArrayList<>(); - Set projects = new HashSet<>(); - boolean ok = true; - for (Object element : fSelection.toList()) { - TmfCommonProjectElement trace = (TmfCommonProjectElement) element; - if (trace instanceof TmfTraceElement) { - trace = ((TmfTraceElement) trace).getElementUnderTraceFolder(); - } - IResource resource = trace.getResource(); - if (resource != null) { - try { - // Set the trace type for this resource - String traceType = event.getParameter(TYPE_PARAMETER); - String previousTraceType = trace.getTraceType(); - IStatus status = propagateProperties(trace, traceType); - ok &= status.isOK(); - - if (status.isOK()) { - if ((previousTraceType != null) && (!traceType.equals(previousTraceType))) { - // Close the trace if open - trace.closeEditors(); - // Delete all supplementary resources - trace.deleteSupplementaryResources(); - } - } else { - statuses.add(status); - } - projects.add(trace.getProject()); - } catch (CoreException e) { - Activator.getDefault().logError(Messages.SelectTraceTypeHandler_ErrorSelectingTrace + trace.getName(), e); - } - } - trace.getProject(); - } - for (TmfProjectElement project : projects) { - project.refresh(); - } - - if (!ok) { - final Shell shell = window.getShell(); - MultiStatus info = new MultiStatus(Activator.PLUGIN_ID, 1, Messages.SelectTraceTypeHandler_TraceFailedValidation, null); - if (statuses.size() > 1) - { - info = new MultiStatus(Activator.PLUGIN_ID, 1, Messages.SelectTraceTypeHandler_TracesFailedValidation, null); - } - for (IStatus status : statuses) { - info.add(status); - } - ErrorDialog.openError(shell, Messages.SelectTraceTypeHandler_Title, Messages.SelectTraceTypeHandler_InvalidTraceType, info); - } - return null; - } - - private static IStatus propagateProperties(TmfCommonProjectElement element, String traceType) - throws CoreException { - - TraceTypeHelper traceTypeHelper = TmfTraceType.getTraceType(traceType); - if (traceTypeHelper == null) { - return Status.CANCEL_STATUS; - } - final IStatus validateTraceType = traceTypeHelper.validate(element.getResource().getLocation().toOSString()); - if (!validateTraceType.isOK()) { - return validateTraceType; - } - - IResource resource = element.getResource(); - TmfTraceTypeUIUtils.setTraceType(resource, traceTypeHelper); - - TmfExperimentFolder experimentFolder = element.getProject().getExperimentsFolder(); - for (final TmfExperimentElement experiment : experimentFolder.getExperiments()) { - for (final TmfTraceElement child : experiment.getTraces()) { - if (child.getName().equals(element.getName())) { - TmfTraceTypeUIUtils.setTraceType(child.getResource(), traceTypeHelper); - break; - } - } - } - - return Status.OK_STATUS; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SelectTracesHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SelectTracesHandler.java deleted file mode 100644 index c46b5a85ae..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SelectTracesHandler.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentFolder; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.wizards.SelectTracesWizard; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -/** - * SelectTracesHandler - *

- */ -public class SelectTracesHandler extends AbstractHandler { - - private TmfExperimentElement fExperiment = null; - - // ------------------------------------------------------------------------ - // Validation - // ------------------------------------------------------------------------ - - @Override - public boolean isEnabled() { - - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return false; - } - - // Get the selection - IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - IWorkbenchPart part = page.getActivePart(); - if (part == null) { - return false; - } - ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); - if (selectionProvider == null) { - return false; - } - ISelection selection = selectionProvider.getSelection(); - - // Make sure there is only one selection and that it is an experiment - fExperiment = null; - if (selection instanceof TreeSelection) { - TreeSelection sel = (TreeSelection) selection; - // There should be only one item selected as per the plugin.xml - Object element = sel.getFirstElement(); - if (element instanceof TmfExperimentElement) { - fExperiment = (TmfExperimentElement) element; - } - } - - return (fExperiment != null); - } - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - - // Fire the Select Traces Wizard - IWorkbench workbench = PlatformUI.getWorkbench(); - Shell shell = workbench.getActiveWorkbenchWindow().getShell(); - - TmfExperimentFolder experiments = (TmfExperimentFolder) fExperiment.getParent(); - TmfProjectElement project = (TmfProjectElement) experiments.getParent(); - SelectTracesWizard wizard = new SelectTracesWizard(project, fExperiment); - wizard.init(PlatformUI.getWorkbench(), null); - WizardDialog dialog = new WizardDialog(shell, wizard); - dialog.open(); - - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SynchronizeTracesHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SynchronizeTracesHandler.java deleted file mode 100644 index e7f18dbca6..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SynchronizeTracesHandler.java +++ /dev/null @@ -1,279 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithm; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TraceUtils; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -/** - * Handles the synchronization of an experiment, when the user selects this - * option in the menu - */ -public class SynchronizeTracesHandler extends AbstractHandler { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private TreeSelection fSelection = null; - private static final String CR = System.getProperty("line.separator"); //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Validation - // ------------------------------------------------------------------------ - - @Override - public boolean isEnabled() { - return true; - } - - // ------------------------------------------------------------------------ - // Execution - // ------------------------------------------------------------------------ - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - - // Get the selection - IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - IWorkbenchPart part = page.getActivePart(); - if (part == null) { - return Boolean.FALSE; - } - ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); - if (selectionProvider == null) { - return Boolean.FALSE; - } - ISelection selection = selectionProvider.getSelection(); - - // Make sure selection contains only traces - fSelection = null; - final ArrayList tl = new ArrayList<>(); - final ArrayList uiexperiment = new ArrayList<>(); - if (selection instanceof TreeSelection) { - fSelection = (TreeSelection) selection; - Iterator iterator = fSelection.iterator(); - while (iterator.hasNext()) { - Object element = iterator.next(); - if (element instanceof TmfTraceElement) { - tl.add((TmfTraceElement) element); - } else if (element instanceof TmfExperimentElement) { - TmfExperimentElement exp = (TmfExperimentElement) element; - uiexperiment.add(exp); - for (TmfTraceElement trace : exp.getTraces()) { - tl.add(trace); - } - } - } - } - - if ((uiexperiment.size() != 1) || (tl.size() < 2)) { - TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, Messages.SynchronizeTracesHandler_WrongTraceNumber); - return null; - } - - Thread thread = new Thread() { - @Override - public void run() { - - final ITmfTrace[] traces = new ITmfTrace[tl.size()]; - final TmfExperimentElement exp = uiexperiment.get(0); - - for (int i = 0; i < tl.size(); i++) { - ITmfTrace trace = tl.get(i).instantiateTrace(); - ITmfEvent traceEvent = tl.get(i).instantiateEvent(); - if (trace == null) { - TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, Messages.SynchronizeTracesHandler_WrongType + tl.get(i).getName()); - for (int j = 0; j < i; j++) { - traces[j].dispose(); - } - return; - } - try { - trace.initTrace(tl.get(i).getResource(), tl.get(i).getResource().getLocation().toOSString(), traceEvent.getClass()); - TmfTraceManager.refreshSupplementaryFiles(trace); - } catch (TmfTraceException e) { - TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, Messages.SynchronizeTracesHandler_InitError + CR + CR + e); - trace.dispose(); - for (int j = 0; j < i; j++) { - traces[j].dispose(); - } - return; - } - traces[i] = trace; - } - - /* - * FIXME Unlike traces, there is no instanceExperiment, so - * we call this function here alone. Maybe it would be - * better to do this on experiment's element constructor? - */ - exp.refreshSupplementaryFolder(); - final TmfExperiment experiment = new TmfExperiment(ITmfEvent.class, exp.getName(), traces, exp.getResource()); - - final SynchronizationAlgorithm syncAlgo = experiment.synchronizeTraces(true); - TmfTraceManager.refreshSupplementaryFiles(experiment); - - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - List tracesToAdd = new ArrayList<>(); - List tracesToRemove = new ArrayList<>(); - /* - * For each trace in the experiment, if there is - * a transform equation, copy the original - * trace, so that a new state system will be - * generated with sync time. - */ - for (TmfTraceElement traceel : tl) { - /* - * Find the trace corresponding to this - * element in the experiment - */ - ITmfTrace expTrace = null; - for (ITmfTrace t : experiment.getTraces()) { - if (t.getResource().equals(traceel.getResource())) { - expTrace = t; - break; - } - } - if ((expTrace != null) && syncAlgo.isTraceSynced(expTrace.getHostId())) { - - /* Find the original trace */ - TmfTraceElement origtrace = traceel.getElementUnderTraceFolder(); - - /* - * Make sure a trace with the - * new name does not exist - */ - String newname = traceel.getName(); - IContainer parentFolder = origtrace.getResource().getParent(); - boolean traceexists; - do { - traceexists = false; - newname += "_"; //$NON-NLS-1$ - if (parentFolder.findMember(newname) != null) { - traceexists = true; - } - } while (traceexists); - - /* Copy the original trace */ - TmfTraceElement newtrace = origtrace.copy(newname); - if (newtrace == null) { - TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, - Messages.SynchronizeTracesHandler_Error + CR + CR + String.format(Messages.SynchronizeTracesHandler_CopyProblem, origtrace.getName())); - continue; - } - - /* - * Instantiate the new trace - * and set its sync formula - */ - ITmfTrace trace = newtrace.instantiateTrace(); - ITmfEvent traceEvent = newtrace.instantiateEvent(); - - try { - trace.initTrace(newtrace.getResource(), newtrace.getResource().getLocation().toOSString(), traceEvent.getClass()); - } catch (TmfTraceException e) { - Activator.getDefault().logError(String.format(Messages.SynchronizeTracesHandler_ErrorSynchingForTrace, exp.getName(), traceel.getName()), e); - TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, Messages.SynchronizeTracesHandler_Error + CR + CR + e.getMessage()); - } - trace.setTimestampTransform(syncAlgo.getTimestampTransform(trace)); - TmfTraceManager.refreshSupplementaryFiles(trace); - trace.dispose(); - - tracesToAdd.add(newtrace); - tracesToRemove.add(traceel); - } - } - experiment.dispose(); - - // Move synchronization file temporarily so that - // it doesn't get deleted by the experiment change - IFolder tmpFolder = exp.getTraceSupplementaryFolder(exp.getName() + '.' + experiment.getSynchronizationFolder(false)); - IResource syncFile = null; - for (IResource resource : exp.getSupplementaryResources()) { - if (resource.getName().equals(experiment.getSynchronizationFolder(false))) { - try { - resource.move(tmpFolder.getFullPath(), false, null); - syncFile = resource; - break; - } catch (CoreException e) { - Activator.getDefault().logError(String.format(Messages.SynchronizeTracesHandler_ErrorSynchingExperiment, exp.getName()), e); - } - } - } - - for (TmfTraceElement trace : tracesToRemove) { - try { - exp.removeTrace(trace); - } catch (CoreException e) { - Activator.getDefault().logError(String.format(Messages.SynchronizeTracesHandler_ErrorSynchingForTrace, exp.getName(), trace.getName()), e); - TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, Messages.SynchronizeTracesHandler_Error + CR + CR + e.getMessage()); - } - } - for (TmfTraceElement trace : tracesToAdd) { - exp.addTrace(trace); - } - - // Move synchronization file back - if (tmpFolder.exists() && syncFile != null) { - try { - tmpFolder.move(syncFile.getFullPath(), false, null); - } catch (CoreException e) { - Activator.getDefault().logError(String.format(Messages.SynchronizeTracesHandler_ErrorSynchingExperiment, exp.getName()), e); - } - } - } - }); - } - }; - thread.start(); - - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/TmfActionProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/TmfActionProvider.java deleted file mode 100644 index e6921f77ca..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/TmfActionProvider.java +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import org.eclipse.core.resources.IFile; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.ui.IActionBars; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.actions.OpenWithMenu; -import org.eclipse.ui.navigator.CommonActionProvider; -import org.eclipse.ui.navigator.ICommonActionConstants; -import org.eclipse.ui.navigator.ICommonActionExtensionSite; -import org.eclipse.ui.navigator.ICommonMenuConstants; -import org.eclipse.ui.navigator.ICommonViewerSite; -import org.eclipse.ui.navigator.ICommonViewerWorkbenchSite; - -/** - * Base action provider. - * - * @author Patrick Tassé - */ -public class TmfActionProvider extends CommonActionProvider { - - private OpenAction openAction; - - private IWorkbenchPage page; - - /** - * Default constructor - */ - public TmfActionProvider() { - } - - @Override - public void init(ICommonActionExtensionSite aSite) { - ICommonViewerSite viewSite = aSite.getViewSite(); - if (viewSite instanceof ICommonViewerWorkbenchSite) { - ICommonViewerWorkbenchSite workbenchSite = (ICommonViewerWorkbenchSite) viewSite; - page = workbenchSite.getPage(); - openAction = new OpenAction(page, workbenchSite.getSelectionProvider()); - } - } - - @Override - public void fillContextMenu(IMenuManager menu) { - ISelection selection = getContext().getSelection(); - if (selection instanceof IStructuredSelection) { - IStructuredSelection structuredSelection = (IStructuredSelection) selection; - if (structuredSelection.size() == 1 && structuredSelection.getFirstElement() instanceof TmfTraceElement) { - TmfTraceElement traceElement = (TmfTraceElement) structuredSelection.getFirstElement(); - if (traceElement.getResource() instanceof IFile) { - MenuManager openWithMenu = new MenuManager(Messages.TmfActionProvider_OpenWith); - openWithMenu.add(new OpenWithMenu(page, traceElement.getResource())); - menu.insertAfter(ICommonMenuConstants.GROUP_OPEN_WITH, openWithMenu); - } - } - } - } - - @Override - public void fillActionBars(IActionBars actionBars) { - if (openAction.isEnabled()) { - actionBars.setGlobalActionHandler(ICommonActionConstants.OPEN, openAction); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/TracePropertyTester.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/TracePropertyTester.java deleted file mode 100644 index ec07402015..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/TracePropertyTester.java +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.handlers; - -import java.util.Iterator; - -import org.eclipse.core.expressions.PropertyTester; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; - -/** - * TracePropertyTester - *

- */ -public class TracePropertyTester extends PropertyTester { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - private final static String IS_IN_TRACE_FOLDER = "isInTraceFolder"; //$NON-NLS-1$ - private final static String IS_EXPERIMENT_TRACE = "isExperimentTrace"; //$NON-NLS-1$ - private final static String HAS_SUPPLEMENTARY_FILES = "hasSupplementaryFiles"; //$NON-NLS-1$ - private final static String TRACE_TYPE = "traceType"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - public TracePropertyTester() { - } - - // ------------------------------------------------------------------------ - // IPropertyTester - // ------------------------------------------------------------------------ - - @Override - public boolean test(Object receiver, String property, Object[] args, Object expectedValue) { - - // Check if the selected elements are in the trace folder - if (IS_IN_TRACE_FOLDER.equals(property)) { - if (receiver != null && receiver instanceof IStructuredSelection) { - Iterator iter = ((IStructuredSelection) receiver).iterator(); - while (iter.hasNext()) { - Object item = iter.next(); - if (item instanceof TmfTraceElement) { - TmfTraceElement trace = (TmfTraceElement) item; - if (!(trace.getParent() instanceof TmfTraceFolder)) { - return false; - } - } else { - return false; - } - } - return true; - } - } - - // Check if the parent of a trace element is an experiment - if (IS_EXPERIMENT_TRACE.equals(property)) { - if (receiver != null && receiver instanceof TmfTraceElement) { - TmfTraceElement trace = (TmfTraceElement) receiver; - return trace.getParent() instanceof TmfExperimentElement; - } - return false; - } - - // Check if traces has supplementary files - if (HAS_SUPPLEMENTARY_FILES.equals(property)) { - if (receiver == null) { - return false; - } - - if (receiver instanceof TmfTraceElement) { - TmfTraceElement trace = (TmfTraceElement) receiver; - return trace.hasSupplementaryResources(); - } else if (receiver instanceof TmfExperimentElement) { - TmfExperimentElement trace = (TmfExperimentElement) receiver; - boolean hasHistory = false; - for (TmfTraceElement aTrace : trace.getTraces()) { - hasHistory |= aTrace.hasSupplementaryResources(); - } - hasHistory |= trace.hasSupplementaryResources(); - return hasHistory; - } - return false; - } - - // Check if the trace element is of a specific trace type - if (TRACE_TYPE.equals(property)) { - if (receiver != null && receiver instanceof TmfTraceElement) { - TmfTraceElement trace = (TmfTraceElement) receiver; - if (expectedValue instanceof String && expectedValue.equals(trace.getTraceType())) { - return true; - } - } - return false; - } - - return false; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/messages.properties deleted file mode 100644 index 95ab3da1f3..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/messages.properties +++ /dev/null @@ -1,70 +0,0 @@ -############################################################################### -# Copyright (c) 2013, 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### - -# Delete message -DeleteDialog_Title = Confirm Delete -DeleteTraceHandler_Message = Are you sure you want to delete the selected trace(s)? -DeleteTraceHandler_Error = Error deleting trace -DeleteTraceHandler_TaskName = Deleting trace -RemoveDialog_Title = Confirm Remove -RemoveTraceFromExperimentHandler_Message = Are you sure you want to remove the selected trace(s)? -RemoveTraceFromExperimentHandler_TaskName = Removing trace -RemoveTraceFromExperimentHandler_Error = Error removing trace -DeleteExperimentHandler_Message = Are you sure you want to delete this experiment? -DeleteExperimentHandler_Error = Error deleting experiment -DeleteFolderHandler_Message = Are you sure you want to delete the selected folder(s)? -DeleteFolderHandler_Error = Error deleting folder -DeleteFolderHandler_TaskName = Deleting folder -DeleteTraceHandlerGeneric_Message = Are you sure you want to delete the selected elements? -DeleteTraceHandlerGeneric_Error= Error deleting elements - -# Clear message -ClearDialog_Title = Confirm Clear -DeleteFolderHandlerClear_TaskName = Clearing folder -DeleteFolderHandlerClear_Message = Are you sure you want to clear the selected folder(s)? -DeleteFolderHandlerClear_Error = Error clearing folder - -# Set Trace Type -SelectTraceTypeHandler_ErrorSelectingTrace=Error selecting trace type for trace -SelectTraceTypeHandler_Title = Validation Error -SelectTraceTypeHandler_TraceFailedValidation=A trace has failed validation -SelectTraceTypeHandler_TracesFailedValidation=Several trace files failed validation -SelectTraceTypeHandler_InvalidTraceType = Type could not be set for one or more traces - -# Drag and drop -DropAdapterAssistant_RenameTraceTitle=Confirm rename trace -DropAdapterAssistant_RenameTraceMessage=An element with the name ''{0}'' already exists in the target folder.\nRename the dropped trace? - -# Trace synchronization -SynchronizeTracesHandler_InitError=Error initializing trace -SynchronizeTracesHandler_CopyProblem=Couldn't copy the original trace %s -SynchronizeTracesHandler_WrongTraceNumber=Experiment must have more than one trace -SynchronizeTracesHandler_Title=Synchronize traces -SynchronizeTracesHandler_WrongType=Trace is not a kernel trace:\n -SynchronizeTracesHandler_Error=Error synchronizing experiment - -SynchronizeTracesHandler_ErrorSynchingExperiment=Error synchronizing experiment %s -SynchronizeTracesHandler_ErrorSynchingForTrace=Error synchronizing experiment %s for trace %s - -ClearTraceOffsetHandler_Title=Clear time offset -ClearTraceOffsetHandler_ConfirmMessage=Are you sure you want to clear the time offset for the selected trace(s)? - -# Delete Supplementary Files messages -DeleteSupplementaryFiles_DeletionTask=Deleting supplementary files for {0} -DeleteSupplementaryFiles_ProjectRefreshTask=Refreshing project {0} - - -# Analysis modules -AnalysisModule_Help=Help - -# TMF Action Provider -TmfActionProvider_OpenWith=Open With diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/model/TmfEditorLinkHelper.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/model/TmfEditorLinkHelper.java deleted file mode 100644 index 552123ea3c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/model/TmfEditorLinkHelper.java +++ /dev/null @@ -1,130 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.internal.tmf.ui.project.model; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; -import org.eclipse.linuxtools.tmf.core.trace.TmfTrace; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IEditorReference; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.ide.ResourceUtil; -import org.eclipse.ui.navigator.ILinkHelper; -import org.eclipse.ui.part.FileEditorInput; - -/** - * Implementation of ILinkHelper interface for linking with editor extension for traces and - * experiments. - * - * @author Bernd Hufmann - */ -public class TmfEditorLinkHelper implements ILinkHelper { - - @Override - public IStructuredSelection findSelection(IEditorInput anInput) { - IFile file = ResourceUtil.getFile(anInput); - if (file != null) { - - try { - // Get the trace type ID - String traceTypeId = file.getPersistentProperty(TmfCommonConstants.TRACETYPE); - if (traceTypeId == null) { - return StructuredSelection.EMPTY; - } - - final TmfProjectElement project = TmfProjectRegistry.getProject(file.getProject(), true); - - // Check for experiments, traces which are folders or traces which are files - if (traceTypeId.equals(TmfExperiment.class.getCanonicalName())) { - // Case 1: Experiment - for (final TmfExperimentElement experimentElement : project.getExperimentsFolder().getExperiments()) { - if (experimentElement.getResource().equals(file.getParent())) { - return new StructuredSelection(experimentElement); - } - } - } else if (traceTypeId.equals(TmfTrace.class.getCanonicalName())) { - // Case 2: Trace that is a folder - for (final TmfTraceElement traceElement : project.getTracesFolder().getTraces()) { - if (traceElement.getResource().equals(file.getParent())) { - return new StructuredSelection(traceElement); - } - } - } else { - // Case 3: Trace that is a file - for (final TmfTraceElement traceElement : project.getTracesFolder().getTraces()) { - if (traceElement.getResource().equals(file)) { - return new StructuredSelection(traceElement); - } - } - } - } catch (CoreException e) { - return StructuredSelection.EMPTY; - } - } - return StructuredSelection.EMPTY; - } - - @Override - public void activateEditor(IWorkbenchPage aPage, IStructuredSelection aSelection) { - if (aSelection == null || aSelection.isEmpty()) { - return; - } - - IFile file = null; - - if ((aSelection.getFirstElement() instanceof TmfTraceElement)) { - TmfTraceElement traceElement = ((TmfTraceElement)aSelection.getFirstElement()); - - // If trace is under an experiment, use the original trace from the traces folder - traceElement = traceElement.getElementUnderTraceFolder(); - file = traceElement.getBookmarksFile(); - } else if ((aSelection.getFirstElement() instanceof TmfExperimentElement)) { - TmfExperimentElement experimentElement = (TmfExperimentElement) aSelection.getFirstElement(); - file = experimentElement.getBookmarksFile(); - } - - if (file != null) { - IEditorInput tmpInput = new FileEditorInput(file); - IEditorPart localEditor = aPage.findEditor(tmpInput); - if (localEditor != null) { - // Editor found. - aPage.bringToTop(localEditor); - } else { - // Search in references for corresponding editor - IEditorReference[] refs = aPage.getEditorReferences(); - for (IEditorReference editorReference : refs) { - try { - if (editorReference.getEditorInput().equals(tmpInput)) { - localEditor = editorReference.getEditor(true); - if (localEditor != null) { - aPage.bringToTop(localEditor); - } - } - } catch (PartInitException e) { - // Ignore - } - } - } - } - } -} - diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/model/TmfImportHelper.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/model/TmfImportHelper.java deleted file mode 100644 index 11ed7e41f4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/model/TmfImportHelper.java +++ /dev/null @@ -1,76 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - **********************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.model; - -import java.io.File; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; - -/** - * Import helper used to import traces - * - * It has two purposes: - import files and directories into projects - set the - * resource types - * - * @author Matthew Khouzam - */ -public class TmfImportHelper { - - /** - * Create a link and replace what was already there. - * - * @param parentFolder - * the resource to import to, does not contain the element name - * @param location - * where the resource (file/directory) is located - * @param targetName - * the name to display - * @return the resource created. Should not be null - * @throws CoreException - * an exception made by createLink. - */ - public static IResource createLink(IFolder parentFolder, IPath location, String targetName) throws CoreException { - File source = new File(location.toString()); - IResource res = null; - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - if (source.isDirectory()) { - IFolder folder = parentFolder.getFolder(targetName); - IStatus result = workspace.validateLinkLocation(folder, location); - if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) { - folder.createLink(location, IResource.REPLACE, new NullProgressMonitor()); - } else { - Activator.getDefault().logError(result.getMessage()); - } - } else { - IFile file = parentFolder.getFile(targetName); - IStatus result = workspace.validateLinkLocation(file, location); - if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) { - file.createLink(location, IResource.REPLACE, - new NullProgressMonitor()); - } else { - Activator.getDefault().logError(result.getMessage()); - } - } - res = parentFolder.findMember(targetName); - return res; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/operations/TmfWorkspaceModifyOperation.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/operations/TmfWorkspaceModifyOperation.java deleted file mode 100644 index a0b5ac2b19..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/operations/TmfWorkspaceModifyOperation.java +++ /dev/null @@ -1,114 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.internal.tmf.ui.project.operations; - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.ui.actions.WorkspaceModifyOperation; - -/** - * Operation to modify the workspace that refreshes workspace at the end of the operation. - * - * For refreshing periodically use {@link WorkspaceModifyOperation} instead. - * - * @author Bernd Hufmann - * - */ -public abstract class TmfWorkspaceModifyOperation implements IRunnableWithProgress { - - private ISchedulingRule rule; - - /** - * Creates a new operation. - */ - protected TmfWorkspaceModifyOperation() { - this(ResourcesPlugin.getWorkspace().getRoot()); - } - - /** - * Creates a new operation that will run using the provided scheduling rule. - * - * @param rule - * The ISchedulingRule to use or null. - */ - protected TmfWorkspaceModifyOperation(ISchedulingRule rule) { - this.rule = rule; - } - - @Override - public synchronized final void run(IProgressMonitor monitor) - throws InvocationTargetException, InterruptedException { - final InvocationTargetException[] iteHolder = new InvocationTargetException[1]; - try { - IWorkspaceRunnable workspaceRunnable = new IWorkspaceRunnable() { - @Override - public void run(IProgressMonitor pm) throws CoreException { - try { - execute(pm); - } catch (InvocationTargetException e) { - // Pass it outside the workspace runnable - iteHolder[0] = e; - } catch (InterruptedException e) { - // Re-throw as OperationCanceledException, which will be - // caught and re-thrown as InterruptedException below. - throw new OperationCanceledException(e.getMessage()); - } - // CoreException and OperationCanceledException are propagated - } - }; - - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - workspace.run(workspaceRunnable, rule, IWorkspace.AVOID_UPDATE, monitor); - } catch (CoreException e) { - throw new InvocationTargetException(e); - } catch (OperationCanceledException e) { - throw new InterruptedException(e.getMessage()); - } - // Re-throw the InvocationTargetException, if any occurred - if (iteHolder[0] != null) { - throw iteHolder[0]; - } - } - - /** - * Performs the steps that are to be treated as a single logical workspace - * change. - *

- * Subclasses must implement this method. - *

- * - * @param monitor - * the progress monitor to use to display progress and field user - * requests to cancel - * @exception CoreException - * if the operation fails due to a CoreException - * @exception InvocationTargetException - * if the operation fails due to an exception other than - * CoreException - * @exception InterruptedException - * if the operation detects a request to cancel, using - * IProgressMonitor.isCanceled(), it should exit - * by throwing InterruptedException. It is also - * possible to throw OperationCanceledException, - * which gets mapped to InterruptedException by - * the run method. - */ - protected abstract void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException; -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/AbstractImportTraceWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/AbstractImportTraceWizardPage.java deleted file mode 100644 index f5037b41c6..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/AbstractImportTraceWizardPage.java +++ /dev/null @@ -1,154 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace; - -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.linuxtools.tmf.core.TmfProjectNature; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTracesFolder; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.dialogs.WizardResourceImportPage; - -/** - * The abstract import trace wizard page, the base for the import trace wizard - * pages. - * - * @author Matthew Khouzam - * @since 2.0 - */ -abstract class AbstractImportTraceWizardPage extends WizardResourceImportPage { - - /** - * Import String - */ - protected static final String BATCH_IMPORT_WIZARD_PAGE = "BatchImportWizardPage"; //$NON-NLS-1$ - - /** - * The trace folder, something like "//Traces/" - */ - protected IFolder fTargetFolder; - - /** - * The project "/" - */ - protected IProject fProject; - - /** - * The batch import trace wizard (parent) - */ - private BatchImportTraceWizard fBatchImportTraceWizard; - - /** - * @param name - * the name of the page - * @param selection - * The current selection - */ - protected AbstractImportTraceWizardPage(String name, IStructuredSelection selection) { - super(name, selection); - } - - /** - * Constructor - * - * @param workbench - * The workbench reference. - * @param selection - * The current selection - */ - public AbstractImportTraceWizardPage(IWorkbench workbench, IStructuredSelection selection) { - this(BATCH_IMPORT_WIZARD_PAGE, selection); - setTitle(null); - setDescription(null); - - // Locate the target trace folder - IFolder traceFolder = null; - Object element = selection.getFirstElement(); - - if (element instanceof TmfTraceFolder) { - TmfTraceFolder tmfTraceFolder = (TmfTraceFolder) element; - fProject = (tmfTraceFolder.getProject().getResource()); - traceFolder = tmfTraceFolder.getResource(); - } else if (element instanceof IProject) { - IProject project = (IProject) element; - try { - if (project.hasNature(TmfProjectNature.ID)) { - traceFolder = (IFolder) project.findMember(TmfTracesFolder.TRACES_FOLDER_NAME); - } - } catch (CoreException e) { - } - } - - // Set the target trace folder - if (traceFolder != null) { - fTargetFolder = (traceFolder); - String path = traceFolder.getFullPath().toOSString(); - setContainerFieldValue(path); - } - - } - - /** - * The Batch Import Wizard - * - * @return the Batch Import Wizard - */ - public BatchImportTraceWizard getBatchWizard() { - return fBatchImportTraceWizard; - } - - @Override - public void createControl(Composite parent) { - Composite composite = new Composite(parent, SWT.NULL); - composite.setLayout(new GridLayout()); - composite.setFont(parent.getFont()); - // arbitrary size - final GridData layoutData = new GridData(); - parent.getShell().setLayoutData(layoutData); - parent.getShell().redraw(); - this.setControl(composite); - - // arbitrary sizes - parent.getShell().setMinimumSize(new Point(525, 400)); - fBatchImportTraceWizard = (BatchImportTraceWizard) getWizard(); - } - - // the following methods are stubbed out on purpose. - - @Override - protected void createSourceGroup(Composite parent) { - // do nothing - } - - @Override - protected ITreeContentProvider getFileProvider() { - // do nothing - return null; - } - - @Override - protected ITreeContentProvider getFolderProvider() { - // do nothing - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/BatchImportTraceWizard.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/BatchImportTraceWizard.java deleted file mode 100644 index 117347cbf4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/BatchImportTraceWizard.java +++ /dev/null @@ -1,699 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Marc-Andre Laperle - Log some exceptions - * Patrick Tasse - Add support for source location - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace; - -import java.io.File; -import java.io.FileInputStream; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; -import java.util.concurrent.BlockingQueue; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.core.runtime.URIUtil; -import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.wizard.IWizardPage; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.project.model.TmfImportHelper; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; -import org.eclipse.linuxtools.tmf.core.project.model.TraceValidationHelper; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceTypeUIUtils; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.dialogs.IOverwriteQuery; -import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider; -import org.eclipse.ui.wizards.datatransfer.ImportOperation; - -/** - * Batch Import trace wizard. - * - * @author Matthew Khouzam - * @since 2.0 - */ -public class BatchImportTraceWizard extends ImportTraceWizard { - - private static final int WIN_HEIGHT = 400; - private static final int WIN_WIDTH = 800; - private static final Status CANCEL_STATUS = new Status(IStatus.CANCEL, Activator.PLUGIN_ID, ""); //$NON-NLS-1$ - private static final int TOTALWORK = 65536; - // ----------------- - // Constants - // ----------------- - - private static final int MAX_FILES = TOTALWORK - 1; - private static final String BATCH_IMPORT_WIZARD = "BatchImportTraceWizard"; //$NON-NLS-1$ - - // ------------------ - // Fields - // ------------------ - - private IWizardPage fSelectDirectoriesPage; - private ImportTraceWizardScanPage fScanPage; - private IWizardPage fSelectTypePage; - private IWizardPage fOptions; - - private final List fTraceTypesToScan = new ArrayList<>(); - private final Set fParentFilesToScan = new HashSet<>(); - - private ImportTraceContentProvider fScannedTraces = new ImportTraceContentProvider(fTraceTypesToScan, fParentFilesToScan); - - private final Map fResults = new HashMap<>(); - private boolean fOverwrite = true; - private boolean fLinked = true; - - private BlockingQueue fTracesToScan; - private final Set fTraces = new TreeSet<>(); - - private Map> fParentFiles = new HashMap<>(); - - // Target import directory (trace folder) - private IFolder fTargetFolder; - - /** - * Returns the ScannedTraces model - * - * @return the ScannedTraces model - */ - public ImportTraceContentProvider getScannedTraces() { - return fScannedTraces; - } - - /** - * Constructor - */ - public BatchImportTraceWizard() { - IDialogSettings workbenchSettings = Activator.getDefault().getDialogSettings(); - IDialogSettings section = workbenchSettings.getSection(BATCH_IMPORT_WIZARD); - if (section == null) { - section = workbenchSettings.addNewSection(BATCH_IMPORT_WIZARD); - } - setDialogSettings(section); - setNeedsProgressMonitor(true); - } - - @Override - public void init(IWorkbench workbench, IStructuredSelection selection) { - - fSelectDirectoriesPage = new ImportTraceWizardSelectDirectoriesPage(workbench, selection); - fScanPage = new ImportTraceWizardScanPage(workbench, selection); - fSelectTypePage = new ImportTraceWizardSelectTraceTypePage(workbench, selection); - fOptions = new ImportTraceWizardPageOptions(workbench, selection); - // keep in case it's called later - Iterator iter = selection.iterator(); - while (iter.hasNext()) { - Object selected = iter.next(); - if (selected instanceof TmfTraceFolder) { - fTargetFolder = ((TmfTraceFolder) selected).getResource(); - break; - } - } - fResults.clear(); - } - - @Override - public void addPages() { - addPage(fSelectTypePage); - addPage(fSelectDirectoriesPage); - addPage(fScanPage); - addPage(fOptions); - final WizardDialog container = (WizardDialog) getContainer(); - if (container != null) { - container.setPageSize(WIN_WIDTH, WIN_HEIGHT); - } - } - - /** - * Add a file to scan - * - * @param fileName - * the file to scan - */ - public void addFileToScan(final String fileName) { - String absolutePath = new File(fileName).getAbsolutePath(); - if (!fParentFiles.containsKey(absolutePath)) { - fParentFiles.put(absolutePath, new HashSet()); - startUpdateTask(Messages.BatchImportTraceWizardAdd + ' ' + absolutePath, absolutePath); - - } - - } - - /** - * Remove files from selection - * - * @param fileName - * the name of the file to remove - */ - public void removeFile(final String fileName) { - fParentFiles.remove(fileName); - fParentFilesToScan.remove(fileName); - startUpdateTask(Messages.BatchImportTraceWizardRemove + ' ' + fileName, null); - } - - private void startUpdateTask(final String taskName, final String fileAbsolutePath) { - try { - this.getContainer().run(true, true, new IRunnableWithProgress() { - - @Override - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - synchronized (BatchImportTraceWizard.this) { // this should - // only run one - // at a time - SubMonitor sm; - sm = SubMonitor.convert(monitor); - sm.setTaskName(taskName); - sm.setWorkRemaining(TOTALWORK); - updateFiles(sm, fileAbsolutePath); - sm.done(); - } - } - }); - } catch (InvocationTargetException e) { - Activator.getDefault().logError(Messages.ImportTraceWizardImportProblem, e); - } catch (InterruptedException e) { - } - } - - /** - * The set of names of the selected files - * - * @return the set of names of the selected files - */ - public Set getFileNames() { - return fParentFilesToScan; - } - - /** - * Reset the trace list to import - */ - public void clearTraces() { - fTraces.clear(); - } - - @Override - public boolean performFinish() { - if (fTraces.isEmpty()) { - return false; - } - // if this turns out to be too slow, put in a progress monitor. Does not - // appear to be slow for the moment. - boolean success = importTraces(); - return success; - } - - private boolean importTraces() { - boolean success = false; - IOverwriteQuery overwriteQuery = new IOverwriteQuery() { - @Override - public String queryOverwrite(String file) { - return fOverwrite ? IOverwriteQuery.ALL : IOverwriteQuery.NO_ALL; - } - }; - FileSystemStructureProvider fileSystemStructureProvider = FileSystemStructureProvider.INSTANCE; - - for (FileAndName traceToImport : fTraces) { - try { - if (fLinked) { - if (TmfImportHelper.createLink(fTargetFolder, Path.fromOSString(traceToImport.getFile().getAbsolutePath()), traceToImport.getName()) == null) { - success = false; - } - else { - success = setTraceTypeAndSourceLocation(traceToImport).isOK(); - } - } - else { - List subList = new ArrayList<>(); - IPath path = fTargetFolder.getFullPath(); - File parentFile = traceToImport.getFile(); - final boolean isFile = parentFile.isFile(); - if (isFile) { - IFile resource = ResourcesPlugin.getWorkspace().getRoot().getFile(path.append(traceToImport.getName())); - if (fOverwrite || !resource.exists()) { - subList.add(parentFile); - parentFile = parentFile.getParentFile(); - try (final FileInputStream source = new FileInputStream(traceToImport.getFile());) { - if (resource.exists()) { - resource.delete(IResource.FORCE, new NullProgressMonitor()); - } - resource.create(source, true, new NullProgressMonitor()); - } - setTraceTypeAndSourceLocation(traceToImport); - success = true; - } - } else { - path = path.addTrailingSeparator().append(traceToImport.getName()); - // Add all files in trace directory - File[] fileList = traceToImport.getFile().listFiles(); - for (File child : fileList) { - subList.add(child); - } - - Collections.sort(subList, new Comparator() { - @Override - public int compare(File o1, File o2) { - return o1.getAbsolutePath().compareTo(o2.getAbsolutePath()); - } - }); - ImportOperation operation = new ImportOperation( - path, - parentFile, - fileSystemStructureProvider, - overwriteQuery, - subList); - operation.setContext(getShell()); - operation.setCreateContainerStructure(false); - if (executeImportOperation(operation)) { - setTraceTypeAndSourceLocation(traceToImport); - success = true; - } - } - - } - } catch (Exception e) { - } - } - return success; - } - - private IStatus setTraceTypeAndSourceLocation(FileAndName traceToImport) { - IStatus status = Status.OK_STATUS; - IResource resource = fTargetFolder.findMember(traceToImport.getName()); - if (resource != null) { - try { - // Set the trace type for this resource - String traceTypeId = traceToImport.getTraceTypeId(); - TraceTypeHelper traceType = TmfTraceType.getTraceType(traceTypeId); - if (traceType != null) { - status = TmfTraceTypeUIUtils.setTraceType(resource, traceType); - } - - // Set the source location for this resource - File file = traceToImport.getFile(); - String sourceLocation = null; - IResource sourceResource; - if (file.isDirectory()) { - sourceResource = ResourcesPlugin.getWorkspace().getRoot().getContainerForLocation(Path.fromOSString(file.getAbsolutePath())); - } else { - sourceResource = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(Path.fromOSString(file.getAbsolutePath())); - } - if (sourceResource != null && sourceResource.exists()) { - sourceLocation = sourceResource.getPersistentProperty(TmfCommonConstants.SOURCE_LOCATION); - } - if (sourceLocation == null) { - sourceLocation = URIUtil.toUnencodedString(file.toURI()); - } - resource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation); - } catch (CoreException e) { - Activator.getDefault().logError(Messages.BatchImportTraceWizardErrorImportingTraceResource - + ' ' + resource.getName(), e); - } - } - return status; - } - - @Override - public boolean canFinish() { - return super.canFinish() && hasTracesToImport() && !hasConflicts() && (fTargetFolder != null); - } - - /** - * Returns if a trace to import is selected - * - * @return if there are traces to import - */ - public boolean hasTracesToImport() { - return fTraces.size() > 0; - } - - /** - * Reset the files to scan - */ - public void clearFilesToScan() { - fTracesToScan.clear(); - } - - /** - * Set the trace types to scan - * - * @param tracesToScan - * a list of trace types to scan for - */ - public void setTraceTypesToScan(List tracesToScan) { - // intersection to know if there's a diff. - // if there's a diff, we need to re-enque everything - List added = new ArrayList<>(); - for (String traceLoc : tracesToScan) { - if (!fTraceTypesToScan.contains(traceLoc)) { - added.add(traceLoc); - } - } - fTraceTypesToScan.clear(); - fTraceTypesToScan.addAll(tracesToScan); - updateTracesToScan(added); - } - - /** - * Get the trace types to scan - * - * @return a list of traces to Scan for - */ - public List getTraceTypesToScan() { - return fTraceTypesToScan; - } - - /** - * Add files to Import - * - * @param element - * add the file and tracetype to import - */ - public void addFileToImport(FileAndName element) { - fTraces.add(element); - updateConflicts(); - } - - /** - * Remove the file to scan - * - * @param element - * the element to remove - */ - public void removeFileToImport(FileAndName element) { - fTraces.remove(element); - element.setConflictingName(false); - updateConflicts(); - } - - /** - * Updates the trace to see if there are conflicts. - */ - public void updateConflicts() { - final FileAndName[] fChildren = fTraces.toArray(new FileAndName[0]); - for (int i = 0; i < fChildren.length; i++) { - fChildren[i].setConflictingName(false); - } - for (int i = 1; i < fChildren.length; i++) { - for (int j = 0; j < i; j++) { - if (fChildren[i].getName().equals(fChildren[j].getName())) { - fChildren[i].setConflictingName(true); - fChildren[j].setConflictingName(true); - } - } - } - getContainer().updateButtons(); - } - - /** - * Is there a name conflict - */ - boolean hasConflicts() { - boolean conflict = false; - for (FileAndName child : fTraces) { - conflict |= child.isConflictingName(); - } - return conflict; - } - - private boolean executeImportOperation(ImportOperation op) { - initializeOperation(op); - - try { - getContainer().run(true, true, op); - } catch (InterruptedException e) { - return false; - } catch (InvocationTargetException e) { - Activator.getDefault().logError(Messages.ImportTraceWizardImportProblem, e); - return false; - } - - IStatus status = op.getStatus(); - if (!status.isOK()) { - ErrorDialog.openError(getContainer().getShell(), Messages.ImportTraceWizardImportProblem, null, status); - return false; - } - - return true; - } - - private static void initializeOperation(ImportOperation op) { - op.setCreateContainerStructure(false); - op.setOverwriteResources(false); - op.setVirtualFolders(false); - } - - /** - * Override existing resources - * - * @param selection - * true or false - */ - public void setOverwrite(boolean selection) { - fOverwrite = selection; - } - - /** - * Is the trace linked? - * - * @param isLink - * true or false - */ - public void setLinked(boolean isLink) { - fLinked = isLink; - } - - /** - * @param tracesToScan - * sets the common traces to scan - */ - public void setTracesToScan(BlockingQueue tracesToScan) { - fTracesToScan = tracesToScan; - } - - /** - * @param traceToScan - * The trace to scan - * @return if the trace has been scanned yet or not - * @since 3.0 - */ - public boolean hasScanned(TraceValidationHelper traceToScan) { - return fResults.containsKey(traceToScan); - } - - /** - * Add a result to a cache - * - * @param traceToScan - * The trace that has been scanned - * @param validate - * if the trace is valid - * @since 3.0 - */ - public void addResult(TraceValidationHelper traceToScan, boolean validate) { - fResults.put(traceToScan, validate); - } - - /** - * Gets if the trace has been scanned or not - * - * @param traceToScan - * the scanned trace - * @return whether it passes or not - * @since 3.0 - */ - public boolean getResult(TraceValidationHelper traceToScan) { - return fResults.get(traceToScan); - } - - /** - * Returns the amount of files scanned - * - * @return the amount of files scanned - */ - public int getNumberOfResults() { - return fResults.size(); - } - - private void updateTracesToScan(final List added) { - // Treeset is used instead of a hashset since the traces should be read - // in the order they were added. - final Set filesToScan = new TreeSet<>(); - for (String name : fParentFiles.keySet()) { - filesToScan.addAll(fParentFiles.get(name)); - } - IProgressMonitor pm = new NullProgressMonitor(); - try { - updateScanQueue(pm, filesToScan, added); - } catch (InterruptedException e) { - } - - } - - /* - * I am a job. Make me work - */ - private synchronized IStatus updateFiles(IProgressMonitor monitor, String traceToScanAbsPath) { - final Set filesToScan = new TreeSet<>(); - - int workToDo = 1; - for (String name : fParentFiles.keySet()) { - - final File file = new File(name); - final File[] listFiles = file.listFiles(); - if (listFiles != null) { - workToDo += listFiles.length; - } - } - int step = TOTALWORK / workToDo; - try { - for (String name : fParentFiles.keySet()) { - final File fileToAdd = new File(name); - final Set parentFilesToScan = fParentFiles.get(fileToAdd.getAbsolutePath()); - recurse(parentFilesToScan, fileToAdd, monitor, step); - if (monitor.isCanceled()) { - fParentFilesToScan.remove(traceToScanAbsPath); - fParentFiles.remove(traceToScanAbsPath); - return CANCEL_STATUS; - } - } - filesToScan.clear(); - for (String name : fParentFiles.keySet()) { - filesToScan.addAll(fParentFiles.get(name)); - fParentFilesToScan.add(name); - } - IStatus cancelled = updateScanQueue(monitor, filesToScan, fTraceTypesToScan); - if (cancelled.matches(IStatus.CANCEL)) { - fParentFilesToScan.remove(traceToScanAbsPath); - fParentFiles.remove(traceToScanAbsPath); - } - } catch (InterruptedException e) { - monitor.done(); - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e); - } - - monitor.done(); - return Status.OK_STATUS; - } - - private IStatus updateScanQueue(IProgressMonitor monitor, final Set filesToScan, final List traceTypes) throws InterruptedException { - for (String fileToScan : filesToScan) { - for (String traceCat : traceTypes) { - TraceValidationHelper tv = new TraceValidationHelper(fileToScan, traceCat); - // for thread safety, keep checks in this order. - if (!fResults.containsKey(tv)) { - if (!fTracesToScan.contains(tv)) { - fTracesToScan.put(tv); - monitor.subTask(tv.getTraceToScan()); - if (monitor.isCanceled()) { - fScanPage.refresh(); - return CANCEL_STATUS; - } - } - } - } - } - fScanPage.refresh(); - return Status.OK_STATUS; - } - - private IStatus recurse(Set filesToScan, File fileToAdd, IProgressMonitor monitor, int step) { - final String absolutePath = fileToAdd.getAbsolutePath(); - if (!filesToScan.contains(absolutePath) && (filesToScan.size() < MAX_FILES)) { - filesToScan.add(absolutePath); - final File[] listFiles = fileToAdd.listFiles(); - if (null != listFiles) { - for (File child : listFiles) { - monitor.subTask(child.getName()); - if (monitor.isCanceled()) { - return CANCEL_STATUS; - } - IStatus retVal = recurse(filesToScan, child, monitor); - if (retVal.matches(IStatus.CANCEL)) { - return retVal; - } - monitor.worked(step); - } - } - } - return Status.OK_STATUS; - } - - private IStatus recurse(Set filesToScan, File fileToAdd, IProgressMonitor monitor) { - final String absolutePath = fileToAdd.getAbsolutePath(); - if (!filesToScan.contains(absolutePath) && (filesToScan.size() < MAX_FILES)) { - filesToScan.add(absolutePath); - final File[] listFiles = fileToAdd.listFiles(); - if (null != listFiles) { - for (File child : listFiles) { - if (monitor.isCanceled()) { - return CANCEL_STATUS; - } - IStatus retVal = recurse(filesToScan, child, monitor); - if (retVal.matches(IStatus.CANCEL)) { - return retVal; - } - } - } - } - return Status.OK_STATUS; - } - - /** - * Gets the folder in the resource (project) - * - * @param targetFolder - * the folder to import to - */ - public void setTraceFolder(IFolder targetFolder) { - fTargetFolder = targetFolder; - if (this.getContainer() != null && this.getContainer().getCurrentPage() != null) { - this.getContainer().updateButtons(); - } - } - - /** - * Gets the target folder - * - * @return the target folder - */ - public IFolder getTargetFolder() { - return fTargetFolder; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/FileAndName.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/FileAndName.java deleted file mode 100644 index 81629e7752..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/FileAndName.java +++ /dev/null @@ -1,188 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace; - -import java.io.File; - -/** - * File and name internal helper class
- * it has the file, a name to display, whether the name is conflicting and a - * reference to the configuration element defining its trace type. - * - * @author Matthew Khouzam - * @since 2.0 - */ -class FileAndName implements Comparable { - - final private File fFile; - private String fTraceTypeId; - private String fName; - private boolean fConflict; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * A file and name - * - * @param f - * the file, can only be set here - * @param n - * the name, can be renamed - * - */ - public FileAndName(File f, String n) { - fFile = f; - fName = n; - fTraceTypeId = null; - } - - // ------------------------------------------------------------------------ - // Getter / Setter - // ------------------------------------------------------------------------ - - /** - * Get the name - * - * @return the name - */ - public String getName() { - return fName; - } - - /** - * Set the name - * - * @param name - * the name to set - */ - public void setName(String name) { - this.fName = name; - } - - /** - * Sets the configuration element of the - * - * @param elem - * the element - */ - public void setTraceTypeId(String elem) { - fTraceTypeId = elem; - } - - /** - * Gets the configuration element canonical name - * - * @return gets the configuration element canonical name - */ - public String getTraceTypeId() { - return fTraceTypeId; - } - - /** - * Get the file - * - * @return the file - */ - public File getFile() { - return fFile; - } - - /** - * Set that the name is conflicting or not - * - * @param conflict - * if the name is conflicting or not - */ - public void setConflictingName(boolean conflict) { - fConflict = conflict; - } - - /** - * Is the name conflicting? - * - * @return is the name conflicting? - */ - public boolean isConflictingName() { - return fConflict; - } - - /** - * Is the fileAndName renamed - * - * @return true if the name does not match the filename - */ - public boolean isRenamed() { - return !fName.equals(fFile.getName()); - } - - // ------------------------------------------------------------------------ - // Comparator & Equals - // ------------------------------------------------------------------------ - - @Override - public int compareTo(FileAndName o) { - int retVal = getFile().compareTo(o.getFile()); - if (retVal == 0) { - if (getTraceTypeId() != null) { - if (getTraceTypeId() != null) { - if (o.getTraceTypeId() != null) { - retVal = getTraceTypeId().compareTo(o.getTraceTypeId()); - } - } - } - } - return retVal; - } - - @Override - public int hashCode() { - // do not take "name" into account since it can change on the fly. - final int prime = 31; - int result = 1; - result = prime * result + ((fTraceTypeId == null) ? 0 : fTraceTypeId.hashCode()); - result = prime * result + ((fFile == null) ? 0 : fFile.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - // do not take "name" into account since it can change on the fly. - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof FileAndName)) { - return false; - } - FileAndName other = (FileAndName) obj; - if (fTraceTypeId == null) { - if (other.fTraceTypeId != null) { - return false; - } - } else if (!fTraceTypeId.equals(other.fTraceTypeId)) { - return false; - } - if (fFile == null) { - if (other.fFile != null) { - return false; - } - } else if (!fFile.equals(other.fFile)) { - return false; - } - return true; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceContentProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceContentProvider.java deleted file mode 100644 index 6873662b49..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceContentProvider.java +++ /dev/null @@ -1,183 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.TreeSet; - -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; - -/** - * A helper class to show the trace types and files and names. it contains the - * model which can be defined as follows : {tracetype -> { file1, file2, ... } - * }+ - * - * @author Matthew Khouzam - * @since 2.0 - */ -class ImportTraceContentProvider implements ITreeContentProvider { - - private final Map fTraceTypes = new HashMap<>(); - private final Map> fTraceFiles = new HashMap<>(); - private final List fTraceTypesToScan; - private final Set fParentFilesToScan; - - public ImportTraceContentProvider(List traceTypesToScan, Set parentFilesToScan) { - fTraceTypesToScan = traceTypesToScan; - fParentFilesToScan = parentFilesToScan; - } - - /** - * Add a trace candidate to display - * - * @param traceTypeId - * the trace type id of the trace - * @param traceToOpen - * the trace file. - */ - public synchronized void addCandidate(String traceTypeId, File traceToOpen) { - TraceTypeHelper traceTypeHelper = TmfTraceType.getTraceType(traceTypeId); - if (traceTypeHelper == null) { - return; - } - fTraceTypes.put(traceTypeHelper.getName(), traceTypeId); - if (!fTraceFiles.containsKey(traceTypeId)) { - fTraceFiles.put(traceTypeId, new TreeSet()); - } - final FileAndName traceFile = new FileAndName(traceToOpen, traceToOpen.getName()); - traceFile.setTraceTypeId(traceTypeId); - final Set categorySet = fTraceFiles.get(traceTypeId); - categorySet.add(traceFile); - } - - /** - * Reset all the candidates - */ - public synchronized void clearCandidates() { - fTraceTypes.clear(); - fTraceFiles.clear(); - } - - @Override - public void dispose() { - fTraceFiles.clear(); - fTraceTypes.clear(); - - } - - @Override - public synchronized void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - if (oldInput != newInput && newInput != null) { - ImportTraceContentProvider input = (ImportTraceContentProvider) newInput; - clearCandidates(); - fTraceTypes.putAll(input.fTraceTypes); - fTraceFiles.putAll(fTraceFiles); - } - } - - @Override - public synchronized Object[] getElements(Object inputElement) { - List candidates = new ArrayList<>(); - - for (String candidate : fTraceTypesToScan) { - for (Entry entry : fTraceTypes.entrySet()) { - if (entry.getValue().equals(candidate)) { - candidates.add(entry.getKey()); - break; - } - } - - } - return candidates.toArray(new String[candidates.size()]); - } - - @Override - public synchronized Object[] getChildren(Object parentElement) { - if (parentElement instanceof String) { - final Set children = fTraceFiles.get(fTraceTypes.get(parentElement)); - if (children != null) { - Set candidates = new TreeSet<>(); - for (FileAndName child : children) { - for (String parent : fParentFilesToScan) { - // this is going to be slow, but less slow than UI - // display and should not be done for more than 10k - // elements. - if (child.getFile().getAbsolutePath().startsWith(parent)) { - candidates.add(child); - } - } - } - return candidates.toArray(new FileAndName[0]); - } - } - return null; - } - - /** - * Gets the brothers and systems of a file element - * - * @param element - * the child leaf - * @return the siblings of an element, including itself. Should never be - * null - */ - public synchronized FileAndName[] getSiblings(FileAndName element) { - String key = (String) getParent(element); - return (FileAndName[]) getChildren(key); - - } - - @Override - public synchronized Object getParent(Object element) { - if (element instanceof FileAndName) { - for (String key : fTraceFiles.keySet()) { - Set fanSet = fTraceFiles.get(key); - if (fanSet.contains(element)) { - return key; - } - } - } - return null; - } - - @Override - public synchronized boolean hasChildren(Object element) { - if (element instanceof String) { - String key = (String) element; - return fTraceFiles.containsKey(fTraceTypes.get(key)); - } - return false; - } - - /** - * Gets the number of traces to import - * - * @return the number of traces to import - */ - public synchronized int getSize() { - int tot = 0; - for (String s : fTraceFiles.keySet()) { - tot += fTraceFiles.get(s).size(); - } - return tot; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceLabelProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceLabelProvider.java deleted file mode 100644 index 662da31c4a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceLabelProvider.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace; - -import java.io.File; - -import org.eclipse.jface.viewers.LabelProvider; - -/** - * Trace label provider for the candidate tree - * - * @author Matthew Khouzam - * @since 2.0 - */ -class ImportTraceLabelProvider extends LabelProvider { - - @Override - public String getText(Object element) { - if (element instanceof String) { - return (String) element; - } - if (element instanceof FileAndName) { - final File file = ((FileAndName) element).getFile(); - if (file != null) { // should never not happen since file is final - // and always set automatically - return file.getName(); - } - } - return null; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizard.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizard.java deleted file mode 100644 index 9a386f7ea6..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizard.java +++ /dev/null @@ -1,87 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace; - -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.ui.IImportWizard; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.plugin.AbstractUIPlugin; - -/** - * The import trace wizard implementation. - *

- * @version 1.0 - * @author Francois Chouinard - * @since 2.0 - */ -public class ImportTraceWizard extends Wizard implements IImportWizard { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - static private final String PLUGIN_ID = Activator.PLUGIN_ID; - static private final String IMPORT_WIZARD = "ImportTraceWizard"; //$NON-NLS-1$ - static private final String ICON_PATH = "icons/wizban/trace_import_wiz.png"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private IStructuredSelection fSelection; - private ImportTraceWizardPage fTraceImportWizardPage; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - /** - * Default constructor - */ - public ImportTraceWizard() { - IDialogSettings workbenchSettings = Activator.getDefault().getDialogSettings(); - IDialogSettings section = workbenchSettings.getSection(IMPORT_WIZARD); - if (section == null) { - section = workbenchSettings.addNewSection(IMPORT_WIZARD); - } - setDialogSettings(section); - } - - // ------------------------------------------------------------------------ - // Wizard - // ------------------------------------------------------------------------ - - @Override - public void init(IWorkbench workbench, IStructuredSelection selection) { - fSelection = selection; - - setWindowTitle(Messages.ImportTraceWizard_DialogTitle); - setDefaultPageImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, ICON_PATH)); - setNeedsProgressMonitor(true); - } - - @Override - public void addPages() { - super.addPages(); - fTraceImportWizardPage = new ImportTraceWizardPage(fSelection); - addPage(fTraceImportWizardPage); - } - - @Override - public boolean performFinish() { - return fTraceImportWizardPage.finish(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardPage.java deleted file mode 100644 index 4abb69d572..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardPage.java +++ /dev/null @@ -1,2234 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson and others. - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Got rid of dependency on internal platform class - * Francois Chouinard - Complete re-design - * Anna Dushistova(Montavista) - [383047] NPE while importing a CFT trace - * Matthew Khouzam - Moved out some common functions - * Patrick Tasse - Add sorting of file system elements - * Bernd Hufmann - Re-design of trace selection and trace validation - * Marc-Andre Laperle - Preserve folder structure on import - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.zip.ZipEntry; -import java.util.zip.ZipException; -import java.util.zip.ZipFile; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.core.runtime.URIUtil; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.layout.PixelConverter; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.operation.ModalContext; -import org.eclipse.jface.viewers.CheckStateChangedEvent; -import org.eclipse.jface.viewers.ICheckStateListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.TmfProjectNature; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceImportException; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceTypeUIUtils; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTracesFolder; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.BusyIndicator; -import org.eclipse.swt.events.FocusAdapter; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.TraverseEvent; -import org.eclipse.swt.events.TraverseListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.DirectoryDialog; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.dialogs.FileSystemElement; -import org.eclipse.ui.dialogs.IOverwriteQuery; -import org.eclipse.ui.dialogs.WizardResourceImportPage; -import org.eclipse.ui.internal.ide.DialogUtil; -import org.eclipse.ui.internal.ide.dialogs.IElementFilter; -import org.eclipse.ui.internal.wizards.datatransfer.ArchiveFileManipulations; -import org.eclipse.ui.internal.wizards.datatransfer.ILeveledImportStructureProvider; -import org.eclipse.ui.internal.wizards.datatransfer.TarEntry; -import org.eclipse.ui.internal.wizards.datatransfer.TarException; -import org.eclipse.ui.internal.wizards.datatransfer.TarFile; -import org.eclipse.ui.internal.wizards.datatransfer.TarLeveledStructureProvider; -import org.eclipse.ui.internal.wizards.datatransfer.ZipLeveledStructureProvider; -import org.eclipse.ui.model.AdaptableList; -import org.eclipse.ui.model.WorkbenchContentProvider; -import org.eclipse.ui.model.WorkbenchLabelProvider; -import org.eclipse.ui.model.WorkbenchViewerComparator; -import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider; -import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider; -import org.eclipse.ui.wizards.datatransfer.ImportOperation; - -/** - * A variant of the standard resource import wizard for importing traces to - * given tracing project. If no project or tracing project was selected the - * wizard imports it to the default tracing project which is created if - * necessary. - * - * In our case traces could be files or a directory structure. This wizard - * supports both cases. It imports traces for a selected trace type or, if no - * trace type is selected, it tries to detect the trace type automatically. - * However, the automatic detection is a best-effort and cannot guarantee that - * the detection is successful. The reason for this is that there might be - * multiple trace types that can be assigned to a single trace. - * - * - * @author Francois Chouinard - * @since 2.0 - */ -@SuppressWarnings("restriction") -public class ImportTraceWizardPage extends WizardResourceImportPage { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - private static final String IMPORT_WIZARD_PAGE_NAME = "ImportTraceWizardPage"; //$NON-NLS-1$ - private static final String IMPORT_WIZARD_ROOT_DIRECTORY_ID = ".import_root_directory_id"; //$NON-NLS-1$; - private static final String IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID = ".import_archive_file_name_id"; //$NON-NLS-1$ - private static final String IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID = ".import_unrecognized_traces_id"; //$NON-NLS-1$ - private static final String IMPORT_WIZARD_PRESERVE_FOLDERS_ID = ".import_preserve_folders_id"; //$NON-NLS-1$ - private static final String IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID = ".import_from_directory"; //$NON-NLS-1$ - private static final String SEPARATOR = ":"; //$NON-NLS-1$ - - // constant from WizardArchiveFileResourceImportPage1 - private static final String[] FILE_IMPORT_MASK = { "*.jar;*.zip;*.tar;*.tar.gz;*.tgz", "*.*" }; //$NON-NLS-1$ //$NON-NLS-2$ - private static final String TRACE_IMPORT_TEMP_FOLDER = ".traceImport"; //$NON-NLS-1$ - - /** - * A special trace type value to communicate that automatic trace type - * detection will occur instead of setting a specific trace type when - * importing the traces. - */ - public static final String TRACE_TYPE_AUTO_DETECT = Messages.ImportTraceWizard_AutoDetection; - - /** - * Preserve the folder structure of the import traces. - */ - public static final int OPTION_PRESERVE_FOLDER_STRUCTURE = 1 << 1; - /** - * Create links to the trace files instead of copies. - */ - public static final int OPTION_CREATE_LINKS_IN_WORKSPACE = 1 << 2; - /** - * Import files that were not recognized as the selected trace type. - */ - public static final int OPTION_IMPORT_UNRECOGNIZED_TRACES = 1 << 3; - /** - * Overwrite existing resources without prompting. - */ - public static final int OPTION_OVERWRITE_EXISTING_RESOURCES = 1 << 4; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // Target import directory ('Traces' folder) - private IFolder fTargetFolder; - // Target Trace folder element - private TmfTraceFolder fTraceFolderElement; - // Flag to handle destination folder change event - private Boolean fIsDestinationChanged = false; - // Combo box containing trace types - private Combo fTraceTypes; - // Button to ignore unrecognized traces or not - private Button fImportUnrecognizedButton; - // Button to overwrite existing resources or not - private Button fOverwriteExistingResourcesCheckbox; - // Button to link or copy traces to workspace - private Button fCreateLinksInWorkspaceButton; - // Button to preserve folder structure - private Button fPreserveFolderStructureButton; - private boolean entryChanged = false; - // The import from directory radio button - private Button fImportFromDirectoryRadio; - // The import from archive radio button - private Button fImportFromArchiveRadio; - // Flag to remember the "create links" checkbox when it gets disabled by - // the import from archive radio button - private Boolean fPreviousCreateLinksValue = true; - - /** The archive name field */ - protected Combo fArchiveNameField; - /** The archive browse button. */ - protected Button fArchiveBrowseButton; - /** The directory name field */ - protected Combo directoryNameField; - /** The directory browse button. */ - protected Button directoryBrowseButton; - - /** - * ResourceTreeAndListGroup was internal in Kepler and we referenced it. It - * is now removed in Luna. To keep our builds compatible with Kepler, we - * need to have our own version of this class. Once we stop supporting - * Kepler, we can delete this class and use the public one from the - * platform. - */ - private ResourceTreeAndListGroup fSelectionGroup; - - // Keep trace of the selection root so that we can dispose its related - // resources - private TraceFileSystemElement fSelectionGroupRoot; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructor. Creates the trace wizard page. - * - * @param name - * The name of the page. - * @param selection - * The current selection - */ - protected ImportTraceWizardPage(String name, IStructuredSelection selection) { - super(name, selection); - setTitle(Messages.ImportTraceWizard_FileSystemTitle); - setDescription(Messages.ImportTraceWizard_ImportTrace); - - // Locate the target trace folder - IFolder traceFolder = null; - Object element = selection.getFirstElement(); - - if (element instanceof TmfTraceFolder) { - fTraceFolderElement = (TmfTraceFolder) element; - traceFolder = fTraceFolderElement.getResource(); - } else if (element instanceof IProject) { - IProject project = (IProject) element; - try { - if (project.hasNature(TmfProjectNature.ID)) { - TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true); - fTraceFolderElement = projectElement.getTracesFolder(); - traceFolder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME); - } - } catch (CoreException e) { - } - } - - // If no tracing project was selected or trace folder doesn't exist use - // default tracing project - if (traceFolder == null) { - IProject project = TmfProjectRegistry.createProject( - TmfCommonConstants.DEFAULT_TRACE_PROJECT_NAME, null, new NullProgressMonitor()); - TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true); - fTraceFolderElement = projectElement.getTracesFolder(); - traceFolder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME); - } - - // Set the target trace folder - if (traceFolder != null) { - fTargetFolder = traceFolder; - String path = traceFolder.getFullPath().toString(); - setContainerFieldValue(path); - } - } - - /** - * Constructor - * - * @param selection - * The current selection - */ - public ImportTraceWizardPage(IStructuredSelection selection) { - this(IMPORT_WIZARD_PAGE_NAME, selection); - } - - /** - * Create the import source selection widget. (Copied from - * WizardResourceImportPage but instead always uses the internal - * ResourceTreeAndListGroup to keep compatibility with Kepler) - */ - @Override - protected void createFileSelectionGroup(Composite parent) { - - // Just create with a dummy root. - fSelectionGroup = new ResourceTreeAndListGroup(parent, - new FileSystemElement("Dummy", null, true),//$NON-NLS-1$ - getFolderProvider(), new WorkbenchLabelProvider(), - getFileProvider(), new WorkbenchLabelProvider(), SWT.NONE, - DialogUtil.inRegularFontMode(parent)); - - ICheckStateListener listener = new ICheckStateListener() { - @Override - public void checkStateChanged(CheckStateChangedEvent event) { - updateWidgetEnablements(); - } - }; - - WorkbenchViewerComparator comparator = new WorkbenchViewerComparator(); - fSelectionGroup.setTreeComparator(comparator); - fSelectionGroup.setListComparator(comparator); - fSelectionGroup.addCheckStateListener(listener); - - } - - // ------------------------------------------------------------------------ - // WizardResourceImportPage - // ------------------------------------------------------------------------ - - @Override - protected void createSourceGroup(Composite parent) { - createSourceSelectionGroup(parent); - createFileSelectionGroup(parent); - createTraceTypeGroup(parent); - validateSourceGroup(); - } - - @Override - protected ITreeContentProvider getFileProvider() { - return new WorkbenchContentProvider() { - @Override - public Object[] getChildren(Object object) { - if (object instanceof TraceFileSystemElement) { - TraceFileSystemElement element = (TraceFileSystemElement) object; - return element.getFiles().getChildren(element); - } - return new Object[0]; - } - }; - } - - @Override - protected ITreeContentProvider getFolderProvider() { - return new WorkbenchContentProvider() { - @Override - public Object[] getChildren(Object o) { - if (o instanceof TraceFileSystemElement) { - TraceFileSystemElement element = (TraceFileSystemElement) o; - return element.getFolders().getChildren(); - } - return new Object[0]; - } - - @Override - public boolean hasChildren(Object o) { - if (o instanceof TraceFileSystemElement) { - TraceFileSystemElement element = (TraceFileSystemElement) o; - if (element.isPopulated()) { - return getChildren(element).length > 0; - } - // If we have not populated then wait until asked - return true; - } - return false; - } - }; - } - - // ------------------------------------------------------------------------ - // Directory Selection Group (forked WizardFileSystemResourceImportPage1) - // ------------------------------------------------------------------------ - - /** - * creates the source selection group. - * - * @param parent - * the parent composite - */ - protected void createSourceSelectionGroup(Composite parent) { - - Composite sourceGroup = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.numColumns = 3; - layout.makeColumnsEqualWidth = false; - layout.marginWidth = 0; - sourceGroup.setLayout(layout); - sourceGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - // import from directory radio button - fImportFromDirectoryRadio = new Button(sourceGroup, SWT.RADIO); - fImportFromDirectoryRadio - .setText(Messages.ImportTraceWizard_DirectoryLocation); - - // import location entry combo - directoryNameField = createPathSelectionCombo(sourceGroup); - createDirectoryBrowseButton(sourceGroup); - - // import from archive radio button - fImportFromArchiveRadio = new Button(sourceGroup, SWT.RADIO); - fImportFromArchiveRadio - .setText(Messages.ImportTraceWizard_ArchiveLocation); - - // import location entry combo - fArchiveNameField = createPathSelectionCombo(sourceGroup); - createArchiveBrowseButton(sourceGroup); - - fImportFromDirectoryRadio.setSelection(true); - fArchiveNameField.setEnabled(false); - fArchiveBrowseButton.setEnabled(false); - - fImportFromDirectoryRadio.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - directoryRadioSelected(); - } - }); - - fImportFromArchiveRadio.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - archiveRadioSelected(); - } - }); - } - - /** - * Select or deselect all files in the file selection group - * - * @param checked - * whether or not the files should be checked - */ - protected void setFileSelectionGroupChecked(boolean checked) { - if (fSelectionGroup != null) { - fSelectionGroup.setAllSelections(checked); - } - } - - /** - * Create a combo that will be used to select a path to specify the source - * of the import. The parent is assumed to have a GridLayout. - * - * @param parent - * the parent composite - * @return the created path selection combo - */ - protected Combo createPathSelectionCombo(Composite parent) { - Combo pathSelectionCombo = new Combo(parent, SWT.BORDER); - - GridData layoutData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL); - layoutData.widthHint = new PixelConverter(pathSelectionCombo).convertWidthInCharsToPixels(25); - pathSelectionCombo.setLayoutData(layoutData); - - TraverseListener traverseListener = new TraverseListener() { - @Override - public void keyTraversed(TraverseEvent e) { - if (e.detail == SWT.TRAVERSE_RETURN) { - e.doit = false; - entryChanged = false; - updateFromSourceField(); - } - } - }; - - FocusAdapter focusAdapter = new FocusAdapter() { - @Override - public void focusLost(FocusEvent e) { - // Clear the flag to prevent constant update - if (entryChanged) { - entryChanged = false; - updateFromSourceField(); - } - } - }; - - SelectionAdapter selectionAdapter = new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - entryChanged = false; - updateFromSourceField(); - } - }; - - ModifyListener modifyListner = new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - entryChanged = true; - } - }; - - pathSelectionCombo.addModifyListener(modifyListner); - pathSelectionCombo.addTraverseListener(traverseListener); - pathSelectionCombo.addFocusListener(focusAdapter); - pathSelectionCombo.addSelectionListener(selectionAdapter); - - return pathSelectionCombo; - } - - /** - * Create the directory browse button. - * - * @param parent - * the parent composite - */ - protected void createDirectoryBrowseButton(Composite parent) { - directoryBrowseButton = createPathSelectionBrowseButton(parent); - directoryBrowseButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - handleSourceDirectoryBrowseButtonPressed(); - } - }); - } - - /** - * Create the archive browse button. - * - * @param parent - * the parent composite - */ - protected void createArchiveBrowseButton(Composite parent) { - fArchiveBrowseButton = createPathSelectionBrowseButton(parent); - fArchiveBrowseButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - handleArchiveBrowseButtonPressed(FILE_IMPORT_MASK); - } - }); - } - - /** - * Create a browse button that will be used to browse for a path to specify - * the source of the import. The parent is assumed to have a GridLayout. - * - * @param parent - * the parent composite - * @return the created path selection combo - */ - protected Button createPathSelectionBrowseButton(Composite parent) { - Button pathSelectionBrowseButton = new Button(parent, SWT.PUSH); - pathSelectionBrowseButton.setText(Messages.ImportTraceWizard_BrowseButton); - setButtonLayoutData(pathSelectionBrowseButton); - - return pathSelectionBrowseButton; - } - - private void archiveRadioSelected() { - if (!isImportFromDirectory()) { - directoryNameField.setEnabled(false); - directoryBrowseButton.setEnabled(false); - fArchiveNameField.setEnabled(true); - fArchiveBrowseButton.setEnabled(true); - updateFromSourceField(); - fArchiveNameField.setFocus(); - if (fCreateLinksInWorkspaceButton != null) { - fPreviousCreateLinksValue = fCreateLinksInWorkspaceButton.getSelection(); - fCreateLinksInWorkspaceButton.setSelection(false); - fCreateLinksInWorkspaceButton.setEnabled(false); - } - } - } - - private void directoryRadioSelected() { - if (isImportFromDirectory()) { - directoryNameField.setEnabled(true); - directoryBrowseButton.setEnabled(true); - fArchiveNameField.setEnabled(false); - fArchiveBrowseButton.setEnabled(false); - updateFromSourceField(); - directoryNameField.setFocus(); - if (fCreateLinksInWorkspaceButton != null) { - fCreateLinksInWorkspaceButton.setSelection(fPreviousCreateLinksValue); - fCreateLinksInWorkspaceButton.setEnabled(true); - } - } - } - - // ------------------------------------------------------------------------ - // Browse for the source directory - // ------------------------------------------------------------------------ - - @Override - public void handleEvent(Event event) { - if (event.widget == directoryBrowseButton) { - handleSourceDirectoryBrowseButtonPressed(); - } - - // Avoid overwriting destination path without repeatedly trigger - // call of handleEvent(); - synchronized (fIsDestinationChanged) { - if (fIsDestinationChanged == false) { - event.display.asyncExec(new Runnable() { - @Override - public void run() { - synchronized (fIsDestinationChanged) { - fIsDestinationChanged = true; - String path = fTargetFolder.getFullPath().toString(); - setContainerFieldValue(path); - } - } - }); - } else { - fIsDestinationChanged = false; - } - } - super.handleEvent(event); - } - - @Override - protected void handleContainerBrowseButtonPressed() { - // Do nothing so that destination directory cannot be changed. - } - - /** - * Handle the button pressed event - */ - protected void handleSourceDirectoryBrowseButtonPressed() { - String currentSource = directoryNameField.getText(); - DirectoryDialog dialog = new DirectoryDialog(directoryNameField.getShell(), SWT.SAVE | SWT.SHEET); - dialog.setText(Messages.ImportTraceWizard_SelectTraceDirectoryTitle); - dialog.setMessage(Messages.ImportTraceWizard_SelectTraceDirectoryMessage); - dialog.setFilterPath(getSourceDirectoryName(currentSource)); - - String selectedDirectory = dialog.open(); - if (selectedDirectory != null) { - // Just quit if the directory is not valid - if ((getSourceDirectory(selectedDirectory) == null) || selectedDirectory.equals(currentSource)) { - return; - } - // If it is valid then proceed to populate - setErrorMessage(null); - setSourcePath(selectedDirectory); - } - } - - /** - * Handle the button pressed event - * - * @param extensions - * file extensions used to filter files shown to the user - */ - protected void handleArchiveBrowseButtonPressed(String[] extensions) { - FileDialog dialog = new FileDialog(fArchiveNameField.getShell(), SWT.SHEET); - dialog.setFilterExtensions(extensions); - dialog.setText(Messages.ImportTraceWizard_SelectTraceArchiveTitle); - String fileName = fArchiveNameField.getText().trim(); - if (!fileName.isEmpty()) { - File path = new File(fileName).getParentFile(); - if (path != null && path.exists()) { - dialog.setFilterPath(path.toString()); - } - } - - String selectedArchive = dialog.open(); - if (selectedArchive != null) { - setErrorMessage(null); - setSourcePath(selectedArchive); - updateWidgetEnablements(); - } - } - - private File getSourceDirectory() { - if (directoryNameField == null) { - return null; - } - return getSourceDirectory(directoryNameField.getText()); - } - - private File getSourceArchiveFile() { - if (fArchiveNameField == null) { - return null; - } - - return getSourceArchiveFile(fArchiveNameField.getText()); - } - - private String getSourceContainerPath() { - if (isImportFromDirectory()) { - File sourceDirectory = getSourceDirectory(); - if (sourceDirectory != null) { - return sourceDirectory.getAbsolutePath(); - } - } - File sourceArchiveFile = getSourceArchiveFile(); - if (sourceArchiveFile != null) { - return sourceArchiveFile.getParent(); - } - return null; - } - - private static File getSourceDirectory(String path) { - File sourceDirectory = new File(getSourceDirectoryName(path)); - if (!sourceDirectory.exists() || !sourceDirectory.isDirectory()) { - return null; - } - - return sourceDirectory; - } - - private static File getSourceArchiveFile(String path) { - File sourceArchiveFile = new File(path); - if (!sourceArchiveFile.exists() || sourceArchiveFile.isDirectory()) { - return null; - } - - return sourceArchiveFile; - } - - private static String getSourceDirectoryName(String sourceName) { - IPath result = new Path(sourceName.trim()); - if (result.getDevice() != null && result.segmentCount() == 0) { - result = result.addTrailingSeparator(); - } else { - result = result.removeTrailingSeparator(); - } - return result.toOSString(); - } - - private void updateFromSourceField() { - setSourcePath(getSourceField().getText()); - updateWidgetEnablements(); - } - - private Combo getSourceField() { - if (directoryNameField == null) { - return fArchiveNameField; - } - - return directoryNameField.isEnabled() ? directoryNameField : fArchiveNameField; - } - - /** - * Set the source path that was selected by the user by various input - * methods (Browse button, typing, etc). - * - * Clients can also call this to set the path programmatically (hard-coded - * initial path) and this can also be overridden to be notified when the - * source path changes. - * - * @param path - * the source path - */ - protected void setSourcePath(String path) { - Combo sourceField = getSourceField(); - if (sourceField == null) { - return; - } - - if (path.length() > 0) { - String[] currentItems = sourceField.getItems(); - int selectionIndex = -1; - for (int i = 0; i < currentItems.length; i++) { - if (currentItems[i].equals(path)) { - selectionIndex = i; - } - } - if (selectionIndex < 0) { - int oldLength = currentItems.length; - String[] newItems = new String[oldLength + 1]; - System.arraycopy(currentItems, 0, newItems, 0, oldLength); - newItems[oldLength] = path; - sourceField.setItems(newItems); - selectionIndex = oldLength; - } - sourceField.select(selectionIndex); - } - resetSelection(); - } - - // ------------------------------------------------------------------------ - // File Selection Group (forked WizardFileSystemResourceImportPage1) - // ------------------------------------------------------------------------ - private void resetSelection() { - if (fSelectionGroupRoot != null) { - disposeSelectionGroupRoot(); - } - fSelectionGroupRoot = getFileSystemTree(); - fSelectionGroup.setRoot(fSelectionGroupRoot); - } - - private void disposeSelectionGroupRoot() { - if (fSelectionGroupRoot != null && fSelectionGroupRoot.getProvider() != null) { - FileSystemObjectImportStructureProvider provider = fSelectionGroupRoot.getProvider(); - provider.dispose(); - fSelectionGroupRoot = null; - } - } - - private TraceFileSystemElement getFileSystemTree() { - IFileSystemObject rootElement = null; - FileSystemObjectImportStructureProvider importStructureProvider = null; - - // Import from directory - if (isImportFromDirectory()) { - importStructureProvider = new FileSystemObjectImportStructureProvider(FileSystemStructureProvider.INSTANCE, null); - File sourceDirectory = getSourceDirectory(); - if (sourceDirectory == null) { - return null; - } - rootElement = importStructureProvider.getIFileSystemObject(sourceDirectory); - } else { - // Import from archive - FileSystemObjectLeveledImportStructureProvider leveledImportStructureProvider = null; - String archivePath = getSourceArchiveFile() != null ? getSourceArchiveFile().getAbsolutePath() : ""; //$NON-NLS-1$ - if (ArchiveFileManipulations.isTarFile(archivePath)) { - if (ensureTarSourceIsValid(archivePath)) { - // We close the file when we dispose the import provider, - // see disposeSelectionGroupRoot - TarFile tarFile = getSpecifiedTarSourceFile(archivePath); - leveledImportStructureProvider = new FileSystemObjectLeveledImportStructureProvider(new TarLeveledStructureProvider(tarFile), archivePath); - } - } else if (ensureZipSourceIsValid(archivePath)) { - // We close the file when we dispose the import provider, see - // disposeSelectionGroupRoot - @SuppressWarnings("resource") - ZipFile zipFile = getSpecifiedZipSourceFile(archivePath); - leveledImportStructureProvider = new FileSystemObjectLeveledImportStructureProvider(new ZipLeveledStructureProvider(zipFile), archivePath); - } - if (leveledImportStructureProvider == null) { - return null; - } - rootElement = leveledImportStructureProvider.getRoot(); - importStructureProvider = leveledImportStructureProvider; - } - - if (rootElement == null) { - return null; - } - - return selectFiles(rootElement, importStructureProvider); - } - - /** - * An import provider that makes use of the IFileSystemObject abstraction - * instead of using plain file system objects (File, TarEntry, ZipEntry) - */ - private static class FileSystemObjectImportStructureProvider implements IImportStructureProvider { - - private IImportStructureProvider fImportProvider; - private String fArchivePath; - - private FileSystemObjectImportStructureProvider(IImportStructureProvider importStructureProvider, String archivePath) { - fImportProvider = importStructureProvider; - fArchivePath = archivePath; - } - - @Override - public List getChildren(Object element) { - @SuppressWarnings("rawtypes") - List children = fImportProvider.getChildren(((IFileSystemObject) element).getRawFileSystemObject()); - List adapted = new ArrayList<>(children.size()); - for (Object o : children) { - adapted.add(getIFileSystemObject(o)); - } - return adapted; - } - - public IFileSystemObject getIFileSystemObject(Object o) { - if (o == null) { - return null; - } - - if (o instanceof File) { - return new FileFileSystemObject((File) o); - } else if (o instanceof TarEntry) { - return new TarFileSystemObject((TarEntry) o, fArchivePath); - } else if (o instanceof ZipEntry) { - return new ZipFileSystemObject((ZipEntry) o, fArchivePath); - } - - throw new IllegalArgumentException("Object type not handled"); //$NON-NLS-1$ - } - - @Override - public InputStream getContents(Object element) { - return fImportProvider.getContents(((IFileSystemObject) element).getRawFileSystemObject()); - } - - @Override - public String getFullPath(Object element) { - return fImportProvider.getFullPath(((IFileSystemObject) element).getRawFileSystemObject()); - } - - @Override - public String getLabel(Object element) { - return fImportProvider.getLabel(((IFileSystemObject) element).getRawFileSystemObject()); - } - - @Override - public boolean isFolder(Object element) { - return fImportProvider.isFolder(((IFileSystemObject) element).getRawFileSystemObject()); - } - - /** - * Disposes of the resources associated with the provider. - */ - public void dispose() { - } - } - - /** - * An import provider that both supports using IFileSystemObject and adds - * "archive functionality" by delegating to a leveled import provider - * (TarLeveledStructureProvider, ZipLeveledStructureProvider) - */ - private static class FileSystemObjectLeveledImportStructureProvider extends FileSystemObjectImportStructureProvider implements ILeveledImportStructureProvider { - - private ILeveledImportStructureProvider fLeveledImportProvider; - - private FileSystemObjectLeveledImportStructureProvider(ILeveledImportStructureProvider importStructureProvider, String archivePath) { - super(importStructureProvider, archivePath); - fLeveledImportProvider = importStructureProvider; - } - - @Override - public IFileSystemObject getRoot() { - return getIFileSystemObject(fLeveledImportProvider.getRoot()); - } - - @Override - public void setStrip(int level) { - fLeveledImportProvider.setStrip(level); - } - - @Override - public int getStrip() { - return fLeveledImportProvider.getStrip(); - } - - @Override - public boolean closeArchive() { - return fLeveledImportProvider.closeArchive(); - } - } - - @SuppressWarnings("resource") - private boolean ensureZipSourceIsValid(String archivePath) { - ZipFile specifiedFile = getSpecifiedZipSourceFile(archivePath); - if (specifiedFile == null) { - return false; - } - return ArchiveFileManipulations.closeZipFile(specifiedFile, getShell()); - } - - private boolean ensureTarSourceIsValid(String archivePath) { - TarFile specifiedFile = getSpecifiedTarSourceFile(archivePath); - if (specifiedFile == null) { - return false; - } - return ArchiveFileManipulations.closeTarFile(specifiedFile, getShell()); - } - - private static ZipFile getSpecifiedZipSourceFile(String fileName) { - if (fileName.length() == 0) { - return null; - } - - try { - return new ZipFile(fileName); - } catch (ZipException e) { - // ignore - } catch (IOException e) { - // ignore - } - - return null; - } - - private static TarFile getSpecifiedTarSourceFile(String fileName) { - if (fileName.length() == 0) { - return null; - } - - try { - return new TarFile(fileName); - } catch (TarException e) { - // ignore - } catch (IOException e) { - // ignore - } - - return null; - } - - private TraceFileSystemElement selectFiles(final IFileSystemObject rootFileSystemObject, - final FileSystemObjectImportStructureProvider structureProvider) { - final TraceFileSystemElement[] results = new TraceFileSystemElement[1]; - BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() { - @Override - public void run() { - // Create the root element from the supplied file system object - results[0] = createRootElement(rootFileSystemObject, structureProvider); - } - }); - return results[0]; - } - - private static TraceFileSystemElement createRootElement(IFileSystemObject element, - FileSystemObjectImportStructureProvider provider) { - boolean isContainer = provider.isFolder(element); - String elementLabel = provider.getLabel(element); - - // Use an empty label so that display of the element's full name - // doesn't include a confusing label - TraceFileSystemElement dummyParent = new TraceFileSystemElement("", null, true, provider);//$NON-NLS-1$ - Object dummyParentFileSystemObject = element; - Object rawFileSystemObject = element.getRawFileSystemObject(); - if (rawFileSystemObject instanceof File) { - dummyParentFileSystemObject = provider.getIFileSystemObject(((File) rawFileSystemObject).getParentFile()); - } - dummyParent.setFileSystemObject(dummyParentFileSystemObject); - dummyParent.setPopulated(); - TraceFileSystemElement result = new TraceFileSystemElement( - elementLabel, dummyParent, isContainer, provider); - result.setFileSystemObject(element); - - // Get the files for the element so as to build the first level - result.getFiles(); - - return dummyParent; - } - - // ------------------------------------------------------------------------ - // Trace Type Group - // ------------------------------------------------------------------------ - private final void createTraceTypeGroup(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.numColumns = 3; - layout.makeColumnsEqualWidth = false; - composite.setLayout(layout); - composite.setFont(parent.getFont()); - GridData buttonData = new GridData(SWT.FILL, SWT.FILL, true, false); - composite.setLayoutData(buttonData); - - // Trace type label ("Trace Type:") - Label typeLabel = new Label(composite, SWT.NONE); - typeLabel.setText(Messages.ImportTraceWizard_TraceType); - typeLabel.setFont(parent.getFont()); - - // Trace type combo - fTraceTypes = new Combo(composite, SWT.BORDER | SWT.READ_ONLY); - GridData data = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1); - fTraceTypes.setLayoutData(data); - fTraceTypes.setFont(parent.getFont()); - - String[] availableTraceTypes = TmfTraceType.getAvailableTraceTypes(); - String[] traceTypeList = new String[availableTraceTypes.length + 1]; - traceTypeList[0] = TRACE_TYPE_AUTO_DETECT; - for (int i = 0; i < availableTraceTypes.length; i++) { - traceTypeList[i + 1] = availableTraceTypes[i]; - } - fTraceTypes.setItems(traceTypeList); - fTraceTypes.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - updateWidgetEnablements(); - boolean enabled = fTraceTypes.getText().equals(TRACE_TYPE_AUTO_DETECT); - fImportUnrecognizedButton.setEnabled(enabled); - } - }); - fTraceTypes.select(0); - - // Unrecognized checkbox - fImportUnrecognizedButton = new Button(composite, SWT.CHECK); - fImportUnrecognizedButton.setSelection(true); - fImportUnrecognizedButton.setText(Messages.ImportTraceWizard_ImportUnrecognized); - } - - // ------------------------------------------------------------------------ - // Options - // ------------------------------------------------------------------------ - - @Override - protected void createOptionsGroupButtons(Group optionsGroup) { - - // Overwrite checkbox - fOverwriteExistingResourcesCheckbox = new Button(optionsGroup, SWT.CHECK); - fOverwriteExistingResourcesCheckbox.setFont(optionsGroup.getFont()); - fOverwriteExistingResourcesCheckbox.setText(Messages.ImportTraceWizard_OverwriteExistingTrace); - fOverwriteExistingResourcesCheckbox.setSelection(false); - - // Create links checkbox - fCreateLinksInWorkspaceButton = new Button(optionsGroup, SWT.CHECK); - fCreateLinksInWorkspaceButton.setFont(optionsGroup.getFont()); - fCreateLinksInWorkspaceButton.setText(Messages.ImportTraceWizard_CreateLinksInWorkspace); - fCreateLinksInWorkspaceButton.setSelection(true); - - fCreateLinksInWorkspaceButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - updateWidgetEnablements(); - } - }); - - fPreserveFolderStructureButton = new Button(optionsGroup, SWT.CHECK); - fPreserveFolderStructureButton.setFont(optionsGroup.getFont()); - fPreserveFolderStructureButton.setText(Messages.ImportTraceWizard_PreserveFolderStructure); - fPreserveFolderStructureButton.setSelection(true); - - updateWidgetEnablements(); - } - - // ------------------------------------------------------------------------ - // Determine if the finish button can be enabled - // ------------------------------------------------------------------------ - @Override - public boolean validateSourceGroup() { - - File source = isImportFromDirectory() ? getSourceDirectory() : getSourceArchiveFile(); - if (source == null) { - setMessage(Messages.ImportTraceWizard_SelectTraceSourceEmpty); - setErrorMessage(null); - return false; - } - - if (sourceConflictsWithDestination(new Path(source.getPath()))) { - setMessage(null); - setErrorMessage(getSourceConflictMessage()); - return false; - } - - if (!isImportFromDirectory()) { - if (!ensureTarSourceIsValid(source.getAbsolutePath()) && !ensureZipSourceIsValid(source.getAbsolutePath())) { - setMessage(null); - setErrorMessage(Messages.ImportTraceWizard_BadArchiveFormat); - return false; - } - } - - if (fSelectionGroup.getCheckedElementCount() == 0) { - setMessage(null); - setErrorMessage(Messages.ImportTraceWizard_SelectTraceNoneSelected); - return false; - } - - IContainer container = getSpecifiedContainer(); - if (container != null && container.isVirtual()) { - if (Platform.getPreferencesService().getBoolean(Activator.PLUGIN_ID, ResourcesPlugin.PREF_DISABLE_LINKING, false, null)) { - setMessage(null); - setErrorMessage(Messages.ImportTraceWizard_CannotImportFilesUnderAVirtualFolder); - return false; - } - if (fCreateLinksInWorkspaceButton == null || !fCreateLinksInWorkspaceButton.getSelection()) { - setMessage(null); - setErrorMessage(Messages.ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder); - return false; - } - } - - setErrorMessage(null); - return true; - } - - private boolean isImportFromDirectory() { - return fImportFromDirectoryRadio != null && fImportFromDirectoryRadio.getSelection(); - } - - @Override - protected void restoreWidgetValues() { - super.restoreWidgetValues(); - - IDialogSettings settings = getDialogSettings(); - boolean value; - if (fImportUnrecognizedButton != null) { - if (settings.get(getPageStoreKey(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID)) == null) { - value = true; - } else { - value = settings.getBoolean(getPageStoreKey(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID)); - } - fImportUnrecognizedButton.setSelection(value); - } - - if (fPreserveFolderStructureButton != null) { - if (settings.get(getPageStoreKey(IMPORT_WIZARD_PRESERVE_FOLDERS_ID)) == null) { - value = true; - } else { - value = settings.getBoolean(getPageStoreKey(IMPORT_WIZARD_PRESERVE_FOLDERS_ID)); - } - fPreserveFolderStructureButton.setSelection(value); - } - - if (settings.get(getPageStoreKey(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID)) == null) { - value = true; - } else { - value = settings.getBoolean(getPageStoreKey(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID)); - } - - if (directoryNameField != null) { - restoreComboValues(directoryNameField, settings, getPageStoreKey(IMPORT_WIZARD_ROOT_DIRECTORY_ID)); - } - if (fArchiveNameField != null) { - restoreComboValues(fArchiveNameField, settings, getPageStoreKey(IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID)); - } - - if (fImportFromDirectoryRadio != null) { - fImportFromDirectoryRadio.setSelection(value); - if (value) { - directoryRadioSelected(); - } - } - if (fImportFromArchiveRadio != null) { - fImportFromArchiveRadio.setSelection(!value); - if (!value) { - archiveRadioSelected(); - } - } - } - - @Override - protected void saveWidgetValues() { - // Persist dialog settings - IDialogSettings settings = getDialogSettings(); - if (fImportUnrecognizedButton != null) { - settings.put(getPageStoreKey(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID), fImportUnrecognizedButton.getSelection()); - } - if (fPreserveFolderStructureButton != null) { - settings.put(getPageStoreKey(IMPORT_WIZARD_PRESERVE_FOLDERS_ID), fPreserveFolderStructureButton.getSelection()); - } - settings.put(getPageStoreKey(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID), isImportFromDirectory()); - - if (directoryNameField != null) { - saveComboValues(directoryNameField, settings, getPageStoreKey(IMPORT_WIZARD_ROOT_DIRECTORY_ID)); - } - if (fArchiveNameField != null) { - saveComboValues(fArchiveNameField, settings, getPageStoreKey(IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID)); - } - } - - private String getPageStoreKey(String key) { - return getName() + key; - } - - private static void restoreComboValues(Combo combo, IDialogSettings settings, String key) { - String[] directoryNames = settings.getArray(key); - if ((directoryNames != null) && (directoryNames.length != 0)) { - for (int i = 0; i < directoryNames.length; i++) { - combo.add(directoryNames[i]); - } - } - } - - private void saveComboValues(Combo combo, IDialogSettings settings, String key) { - // update names history - String[] directoryNames = settings.getArray(key); - if (directoryNames == null) { - directoryNames = new String[0]; - } - - String items[] = combo.getItems(); - for (int i = 0; i < items.length; i++) { - directoryNames = addToHistory(directoryNames, items[i]); - } - settings.put(key, directoryNames); - } - - // ------------------------------------------------------------------------ - // Import the trace(s) - // ------------------------------------------------------------------------ - - /** - * Finish the import. - * - * @return true if successful else false - */ - public boolean finish() { - String traceTypeName = getImportTraceTypeId(); - String traceId = null; - if (!TRACE_TYPE_AUTO_DETECT.equals(traceTypeName)) { - String tokens[] = traceTypeName.split(SEPARATOR, 2); - if (tokens.length < 2) { - return false; - } - traceId = TmfTraceType.getTraceTypeId(tokens[0], tokens[1]); - } - - // Save dialog settings - saveWidgetValues(); - - IPath baseSourceContainerPath = new Path(getSourceContainerPath()); - boolean importFromArchive = getSourceArchiveFile() != null; - int importOptionFlags = getImportOptionFlags(); - - final TraceValidateAndImportOperation operation = new TraceValidateAndImportOperation(traceId, baseSourceContainerPath, getContainerFullPath(), importFromArchive, - importOptionFlags); - - IStatus status = Status.OK_STATUS; - try { - getContainer().run(true, true, new IRunnableWithProgress() { - @Override - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - operation.run(monitor); - monitor.done(); - } - }); - - status = operation.getStatus(); - } catch (InvocationTargetException e) { - status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.ImportTraceWizard_ImportProblem, e); - } catch (InterruptedException e) { - status = Status.CANCEL_STATUS; - } - if (!status.isOK()) { - if (status.getSeverity() == IStatus.CANCEL) { - setMessage(Messages.ImportTraceWizard_ImportOperationCancelled); - setErrorMessage(null); - } else { - if (status.getException() != null) { - displayErrorDialog(status.getMessage() + ": " + status.getException()); //$NON-NLS-1$ - } - setMessage(null); - setErrorMessage(Messages.ImportTraceWizard_ImportProblem); - } - return false; - } - setErrorMessage(null); - return true; - } - - /** - * Get the trace type id to import as. This can also return - * {@link #TRACE_TYPE_AUTO_DETECT} to communicate that automatic trace type - * detection will occur instead of setting a specific trace type when - * importing the traces. - * - * @return the trace type id or {@link #TRACE_TYPE_AUTO_DETECT} - */ - protected String getImportTraceTypeId() { - return fTraceTypes.getText(); - } - - /** - * Get import options in the form of flags (bits). - * - * @return the import flags. - * @see #OPTION_CREATE_LINKS_IN_WORKSPACE - * @see #OPTION_IMPORT_UNRECOGNIZED_TRACES - * @see #OPTION_OVERWRITE_EXISTING_RESOURCES - * @see #OPTION_PRESERVE_FOLDER_STRUCTURE - */ - protected int getImportOptionFlags() { - int flags = 0; - if (fCreateLinksInWorkspaceButton != null && fCreateLinksInWorkspaceButton.getSelection()) { - flags |= OPTION_CREATE_LINKS_IN_WORKSPACE; - } - if (fImportUnrecognizedButton != null && fImportUnrecognizedButton.getSelection()) { - flags |= OPTION_IMPORT_UNRECOGNIZED_TRACES; - } - if (fOverwriteExistingResourcesCheckbox != null && fOverwriteExistingResourcesCheckbox.getSelection()) { - flags |= OPTION_OVERWRITE_EXISTING_RESOURCES; - } - if (fPreserveFolderStructureButton != null && fPreserveFolderStructureButton.getSelection()) { - flags |= OPTION_PRESERVE_FOLDER_STRUCTURE; - } - return flags; - } - - @Override - public void dispose() { - super.dispose(); - disposeSelectionGroupRoot(); - } - - // ------------------------------------------------------------------------ - // Classes - // ------------------------------------------------------------------------ - - private class TraceValidateAndImportOperation { - private IStatus fStatus; - private String fTraceType; - private IPath fDestinationContainerPath; - private IPath fBaseSourceContainerPath; - private boolean fImportFromArchive; - private int fImportOptionFlags; - private ImportConfirmation fConfirmationMode = ImportConfirmation.SKIP; - - private TraceValidateAndImportOperation(String traceId, IPath baseSourceContainerPath, IPath destinationContainerPath, boolean importFromArchive, int importOptionFlags) { - fTraceType = traceId; - fBaseSourceContainerPath = baseSourceContainerPath; - fDestinationContainerPath = destinationContainerPath; - fImportOptionFlags = importOptionFlags; - fImportFromArchive = importFromArchive; - - boolean overwriteExistingResources = (importOptionFlags & OPTION_OVERWRITE_EXISTING_RESOURCES) != 0; - if (overwriteExistingResources) { - fConfirmationMode = ImportConfirmation.OVERWRITE_ALL; - } - } - - public void run(IProgressMonitor progressMonitor) { - String currentPath = null; - final Map folderElements = new HashMap<>(); - try { - - final ArrayList fileSystemElements = new ArrayList<>(); - IElementFilter passThroughFilter = new IElementFilter() { - - @Override - public void filterElements(Collection elements, IProgressMonitor monitor) { - fileSystemElements.addAll(elements); - } - - @Override - public void filterElements(Object[] elements, IProgressMonitor monitor) { - for (int i = 0; i < elements.length; i++) { - fileSystemElements.add((TraceFileSystemElement) elements[i]); - } - } - }; - - // List fileSystemElements will be filled using the - // passThroughFilter - SubMonitor subMonitor = SubMonitor.convert(progressMonitor, 1); - fSelectionGroup.getAllCheckedListItems(passThroughFilter, subMonitor); - - // Check if operation was cancelled. - ModalContext.checkCanceled(subMonitor); - - Iterator fileSystemElementsIter = fileSystemElements.iterator(); - IFolder destTempFolder = null; - subMonitor = SubMonitor.convert(progressMonitor, fileSystemElements.size()); - if (fImportFromArchive) { - // When importing from archive, we first extract the - // *selected* files to a temporary folder then create a new - // Iterator that points to the - // extracted files. This way, the import operator can - // continue as it normally would. - - subMonitor = SubMonitor.convert(progressMonitor, fileSystemElements.size() * 2); - destTempFolder = fTargetFolder.getProject().getFolder(TRACE_IMPORT_TEMP_FOLDER); - if (destTempFolder.exists()) { - SubProgressMonitor monitor = new SubProgressMonitor(subMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK); - destTempFolder.delete(true, monitor); - } - SubProgressMonitor monitor = new SubProgressMonitor(subMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK); - destTempFolder.create(IResource.HIDDEN, true, monitor); - - fileSystemElementsIter = extractSelectedFiles(fileSystemElementsIter, destTempFolder, subMonitor); - // We need to update the source container path because the - // "preserve folder structure" option would create the - // wrong folders otherwise. - fBaseSourceContainerPath = destTempFolder.getLocation(); - } - - while (fileSystemElementsIter.hasNext()) { - ModalContext.checkCanceled(progressMonitor); - currentPath = null; - TraceFileSystemElement element = fileSystemElementsIter.next(); - IFileSystemObject fileSystemObject = element.getFileSystemObject(); - String resourcePath = element.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString()); - element.setDestinationContainerPath(computeDestinationContainerPath(new Path(resourcePath))); - - currentPath = resourcePath; - SubMonitor sub = subMonitor.newChild(1); - if (element.isDirectory()) { - if (!folderElements.containsKey(resourcePath)) { - if (isDirectoryTrace(element)) { - folderElements.put(resourcePath, element); - validateAndImportTrace(element, sub); - } - } - } else { - TraceFileSystemElement parentElement = (TraceFileSystemElement) element.getParent(); - String parentPath = parentElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString()); - parentElement.setDestinationContainerPath(computeDestinationContainerPath(new Path(parentPath))); - currentPath = parentPath; - if (!folderElements.containsKey(parentPath)) { - if (isDirectoryTrace(parentElement)) { - folderElements.put(parentPath, parentElement); - validateAndImportTrace(parentElement, sub); - } else { - if (fileSystemObject.exists()) { - validateAndImportTrace(element, sub); - } - } - } - } - } - - if (destTempFolder != null && destTempFolder.exists()) { - destTempFolder.delete(true, progressMonitor); - } - - setStatus(Status.OK_STATUS); - } catch (InterruptedException e) { - setStatus(Status.CANCEL_STATUS); - } catch (Exception e) { - String errorMessage = Messages.ImportTraceWizard_ImportProblem + ": " + //$NON-NLS-1$ - (currentPath != null ? currentPath : ""); //$NON-NLS-1$ - Activator.getDefault().logError(errorMessage, e); - setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, errorMessage, e)); - } - } - - private Iterator extractSelectedFiles(Iterator fileSystemElementsIter, IFolder tempFolder, IProgressMonitor progressMonitor) throws InterruptedException, - InvocationTargetException { - List subList = new ArrayList<>(); - Map sourceLocationMap = new HashMap<>(); - // Collect all the elements - while (fileSystemElementsIter.hasNext()) { - ModalContext.checkCanceled(progressMonitor); - TraceFileSystemElement element = fileSystemElementsIter.next(); - sourceLocationMap.put(new Path(element.getFileSystemObject().getName()).removeTrailingSeparator(), element.getSourceLocation()); - TraceFileSystemElement parentElement = (TraceFileSystemElement) element.getParent(); - sourceLocationMap.put(new Path(parentElement.getFileSystemObject().getName()).removeTrailingSeparator(), parentElement.getSourceLocation()); - if (element.isDirectory()) { - Object[] array = element.getFiles().getChildren(); - for (int i = 0; i < array.length; i++) { - subList.add((TraceFileSystemElement) array[i]); - } - } - subList.add(element); - } - - // Find a sensible root element - TraceFileSystemElement root = subList.get(0); - while (root.getParent() != null) { - root = (TraceFileSystemElement) root.getParent(); - } - - ImportProvider fileSystemStructureProvider = new ImportProvider(); - - IOverwriteQuery myQueryImpl = new IOverwriteQuery() { - @Override - public String queryOverwrite(String file) { - return IOverwriteQuery.NO_ALL; - } - }; - - progressMonitor.setTaskName(Messages.ImportTraceWizard_ExtractImportOperationTaskName); - IPath containerPath = tempFolder.getFullPath(); - ImportOperation operation = new ImportOperation(containerPath, root, fileSystemStructureProvider, myQueryImpl, subList); - operation.setContext(getShell()); - - operation.setCreateContainerStructure(true); - operation.setOverwriteResources(false); - operation.setVirtualFolders(false); - - operation.run(new SubProgressMonitor(progressMonitor, subList.size(), SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); - - // Create the new import provider and root element based on the - // extracted temp folder - FileSystemObjectImportStructureProvider importStructureProvider = new FileSystemObjectImportStructureProvider(FileSystemStructureProvider.INSTANCE, null); - IFileSystemObject rootElement = importStructureProvider.getIFileSystemObject(new File(tempFolder.getLocation().toOSString())); - TraceFileSystemElement createRootElement = createRootElement(rootElement, importStructureProvider); - List list = new ArrayList<>(); - getAllChildren(list, createRootElement); - Iterator extractedElementsIter = list.iterator(); - IPath tempPath = new Path(tempFolder.getLocation().toOSString()); - for (TraceFileSystemElement element : list) { - IPath path = new Path(((File) element.getFileSystemObject().getRawFileSystemObject()).getAbsolutePath()).makeRelativeTo(tempPath); - element.setSourceLocation(sourceLocationMap.get(path)); - TraceFileSystemElement parentElement = (TraceFileSystemElement) element.getParent(); - IPath parentPath = new Path(((File) parentElement.getFileSystemObject().getRawFileSystemObject()).getAbsolutePath()).makeRelativeTo(tempPath); - parentElement.setSourceLocation(sourceLocationMap.get(parentPath)); - } - return extractedElementsIter; - } - - /** - * Get all the TraceFileSystemElements recursively. - * - * @param result - * the list accumulating the result - * @param rootElement - * the root element of the file system to be imported - */ - private void getAllChildren(List result, TraceFileSystemElement rootElement) { - AdaptableList files = rootElement.getFiles(); - for (Object file : files.getChildren()) { - result.add((TraceFileSystemElement) file); - } - - AdaptableList folders = rootElement.getFolders(); - for (Object folder : folders.getChildren()) { - getAllChildren(result, (TraceFileSystemElement) folder); - } - } - - private IPath computeDestinationContainerPath(Path resourcePath) { - IPath destinationContainerPath = fDestinationContainerPath; - - // We need to figure out the new destination path relative to the - // selected "base" source directory. - // Here for example, the selected source directory is /home/user - if ((fImportOptionFlags & OPTION_PRESERVE_FOLDER_STRUCTURE) != 0) { - // /home/user/bar/foo/trace -> /home/user/bar/foo - IPath sourceContainerPath = resourcePath.removeLastSegments(1); - if (fBaseSourceContainerPath.equals(resourcePath)) { - // Use resourcePath directory if fBaseSourceContainerPath - // points to a directory trace - sourceContainerPath = resourcePath; - } - // /home/user/bar/foo, /home/user -> bar/foo - IPath relativeContainerPath = sourceContainerPath.makeRelativeTo(fBaseSourceContainerPath); - // project/Traces + bar/foo -> project/Traces/bar/foo - destinationContainerPath = fDestinationContainerPath.append(relativeContainerPath); - } - return destinationContainerPath; - } - - private void validateAndImportTrace(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor) - throws TmfTraceImportException, CoreException, InvocationTargetException, InterruptedException { - String parentContainerPath = fBaseSourceContainerPath.toOSString(); - String path = fileSystemElement.getFileSystemObject().getAbsolutePath(parentContainerPath); - TraceTypeHelper traceTypeHelper = null; - - if (fTraceType == null) { - // Auto Detection - try { - traceTypeHelper = TmfTraceTypeUIUtils.selectTraceType(path, null, null); - } catch (TmfTraceImportException e) { - // the trace did not match any trace type - } - if (traceTypeHelper == null) { - if ((fImportOptionFlags & OPTION_IMPORT_UNRECOGNIZED_TRACES) != 0) { - importResource(fileSystemElement, monitor); - } - return; - } - } else { - boolean isDirectoryTraceType = TmfTraceType.isDirectoryTraceType(fTraceType); - if (fileSystemElement.isDirectory() != isDirectoryTraceType) { - return; - } - traceTypeHelper = TmfTraceType.getTraceType(fTraceType); - - if (traceTypeHelper == null) { - // Trace type not found - throw new TmfTraceImportException(Messages.ImportTraceWizard_TraceTypeNotFound); - } - - if (!traceTypeHelper.validate(path).isOK()) { - // Trace type exist but doesn't validate for given trace. - return; - } - } - - // Finally import trace - IResource importedResource = importResource(fileSystemElement, monitor); - if (importedResource != null) { - TmfTraceTypeUIUtils.setTraceType(importedResource, traceTypeHelper); - } - - } - - /** - * Imports a trace resource to project. In case of name collision the - * user will be asked to confirm overwriting the existing trace, - * overwriting or skipping the trace to be imported. - * - * @param fileSystemElement - * trace file system object to import - * @param monitor - * a progress monitor - * @return the imported resource or null if no resource was imported - * - * @throws InvocationTargetException - * if problems during import operation - * @throws InterruptedException - * if cancelled - * @throws CoreException - * if problems with workspace - */ - private IResource importResource(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor) - throws InvocationTargetException, InterruptedException, CoreException { - - ImportConfirmation mode = checkForNameClashes(fileSystemElement); - switch (mode) { - case RENAME: - case RENAME_ALL: - rename(fileSystemElement); - break; - case OVERWRITE: - case OVERWRITE_ALL: - delete(fileSystemElement, monitor); - break; - case CONTINUE: - break; - case SKIP: - case SKIP_ALL: - default: - return null; - } - - List subList = new ArrayList<>(); - - FileSystemElement parentFolder = fileSystemElement.getParent(); - - IPath containerPath = fileSystemElement.getDestinationContainerPath(); - IPath tracePath = containerPath.addTrailingSeparator().append(fileSystemElement.getLabel()); - boolean createLinksInWorkspace = (fImportOptionFlags & OPTION_CREATE_LINKS_IN_WORKSPACE) != 0; - if (fileSystemElement.isDirectory() && !createLinksInWorkspace) { - containerPath = tracePath; - - Object[] array = fileSystemElement.getFiles().getChildren(); - for (int i = 0; i < array.length; i++) { - subList.add((TraceFileSystemElement) array[i]); - } - parentFolder = fileSystemElement; - - } else { - subList.add(fileSystemElement); - } - - ImportProvider fileSystemStructureProvider = new ImportProvider(); - - IOverwriteQuery myQueryImpl = new IOverwriteQuery() { - @Override - public String queryOverwrite(String file) { - return IOverwriteQuery.NO_ALL; - } - }; - - monitor.setTaskName(Messages.ImportTraceWizard_ImportOperationTaskName + " " + fileSystemElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString())); //$NON-NLS-1$ - ImportOperation operation = new ImportOperation(containerPath, parentFolder, fileSystemStructureProvider, myQueryImpl, subList); - operation.setContext(getShell()); - - operation.setCreateContainerStructure(false); - operation.setOverwriteResources(false); - operation.setCreateLinks(createLinksInWorkspace); - operation.setVirtualFolders(false); - - operation.run(new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); - String sourceLocation = fileSystemElement.getSourceLocation(); - IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(tracePath); - if (sourceLocation != null) { - resource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation); - } - - return resource; - } - - private boolean isDirectoryTrace(TraceFileSystemElement fileSystemElement) { - String path = fileSystemElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString()); - if (TmfTraceType.isDirectoryTrace(path)) { - return true; - } - return false; - } - - private ImportConfirmation checkForNameClashes(TraceFileSystemElement fileSystemElement) throws InterruptedException { - IPath tracePath = getInitialDestinationPath(fileSystemElement); - - // handle rename - if (getExistingTrace(tracePath) != null) { - if ((fConfirmationMode == ImportConfirmation.RENAME_ALL) || - (fConfirmationMode == ImportConfirmation.OVERWRITE_ALL) || - (fConfirmationMode == ImportConfirmation.SKIP_ALL)) { - return fConfirmationMode; - } - - int returnCode = promptForOverwrite(tracePath); - if (returnCode < 0) { - // Cancel - throw new InterruptedException(); - } - fConfirmationMode = ImportConfirmation.values()[returnCode]; - return fConfirmationMode; - } - return ImportConfirmation.CONTINUE; - } - - private int promptForOverwrite(IPath tracePath) { - final MessageDialog dialog = new MessageDialog(getContainer() - .getShell(), null, null, NLS.bind(Messages.ImportTraceWizard_TraceAlreadyExists, tracePath.makeRelativeTo(fTraceFolderElement.getProject().getPath())), - MessageDialog.QUESTION, new String[] { - ImportConfirmation.RENAME.getInName(), - ImportConfirmation.RENAME_ALL.getInName(), - ImportConfirmation.OVERWRITE.getInName(), - ImportConfirmation.OVERWRITE_ALL.getInName(), - ImportConfirmation.SKIP.getInName(), - ImportConfirmation.SKIP_ALL.getInName(), - }, 4) { - @Override - protected int getShellStyle() { - return super.getShellStyle() | SWT.SHEET; - } - }; - - final int[] returnValue = new int[1]; - getShell().getDisplay().syncExec(new Runnable() { - - @Override - public void run() { - returnValue[0] = dialog.open(); - } - }); - return returnValue[0]; - } - - /** - * @return the initial destination path, before rename, if any - */ - private IPath getInitialDestinationPath(TraceFileSystemElement fileSystemElement) { - IPath traceFolderPath = fileSystemElement.getDestinationContainerPath(); - return traceFolderPath.append(fileSystemElement.getFileSystemObject().getLabel()); - } - - private void rename(TraceFileSystemElement fileSystemElement) { - IPath tracePath = getInitialDestinationPath(fileSystemElement); - TmfTraceElement trace = getExistingTrace(tracePath); - if (trace == null) { - return; - } - - // Not using IFolder on purpose to leave the door open to import - // directly into an IProject - IContainer folder = (IContainer) trace.getParent().getResource(); - int i = 2; - while (true) { - String name = trace.getName() + '(' + Integer.toString(i++) + ')'; - IResource resource = folder.findMember(name); - if (resource == null) { - fileSystemElement.setLabel(name); - return; - } - } - } - - private void delete(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor) throws CoreException { - IPath tracePath = getInitialDestinationPath(fileSystemElement); - TmfTraceElement trace = getExistingTrace(tracePath); - if (trace == null) { - return; - } - - trace.delete(monitor); - } - - private TmfTraceElement getExistingTrace(IPath tracePath) { - List traces = fTraceFolderElement.getTraces(); - for (TmfTraceElement t : traces) { - if (t.getPath().equals(tracePath)) { - return t; - } - } - return null; - } - - /** - * Set the status for this operation - * - * @param status - * the status - */ - protected void setStatus(IStatus status) { - fStatus = status; - } - - public IStatus getStatus() { - return fStatus; - } - } - - /** - * The TraceFileSystemElement is a - * FileSystemElement that knows if it has been populated or - * not. - */ - private static class TraceFileSystemElement extends FileSystemElement { - - private boolean fIsPopulated = false; - private String fLabel = null; - private IPath fDestinationContainerPath; - private FileSystemObjectImportStructureProvider fProvider; - private String fSourceLocation; - - public TraceFileSystemElement(String name, FileSystemElement parent, boolean isDirectory, FileSystemObjectImportStructureProvider provider) { - super(name, parent, isDirectory); - fProvider = provider; - } - - public void setDestinationContainerPath(IPath destinationContainerPath) { - fDestinationContainerPath = destinationContainerPath; - } - - public void setPopulated() { - fIsPopulated = true; - } - - public boolean isPopulated() { - return fIsPopulated; - } - - @Override - public AdaptableList getFiles() { - if (!fIsPopulated) { - populateElementChildren(); - } - return super.getFiles(); - } - - @Override - public AdaptableList getFolders() { - if (!fIsPopulated) { - populateElementChildren(); - } - return super.getFolders(); - } - - /** - * Sets the label for the trace to be used when importing at trace. - * - * @param name - * the label for the trace - */ - public void setLabel(String name) { - fLabel = name; - } - - /** - * Returns the label for the trace to be used when importing at trace. - * - * @return the label of trace resource - */ - public String getLabel() { - if (fLabel == null) { - return getFileSystemObject().getLabel(); - } - return fLabel; - } - - /** - * The full path to the container that will contain the trace - * - * @return the destination container path - */ - public IPath getDestinationContainerPath() { - return fDestinationContainerPath; - } - - /** - * Populates the children of the specified parent - * FileSystemElement - */ - private void populateElementChildren() { - List allchildren = fProvider.getChildren(this.getFileSystemObject()); - Object child = null; - TraceFileSystemElement newelement = null; - Iterator iter = allchildren.iterator(); - while (iter.hasNext()) { - child = iter.next(); - newelement = new TraceFileSystemElement(fProvider.getLabel(child), this, fProvider.isFolder(child), fProvider); - newelement.setFileSystemObject(child); - } - setPopulated(); - } - - public FileSystemObjectImportStructureProvider getProvider() { - return fProvider; - } - - @Override - public IFileSystemObject getFileSystemObject() { - Object fileSystemObject = super.getFileSystemObject(); - return (IFileSystemObject) fileSystemObject; - } - - public String getSourceLocation() { - if (fSourceLocation == null) { - fSourceLocation = getFileSystemObject().getSourceLocation(); - } - return fSourceLocation; - } - - public void setSourceLocation(String sourceLocation) { - fSourceLocation = sourceLocation; - } - } - - /** - * This interface abstracts the differences between different kinds of - * FileSystemObjects such as File, TarEntry and ZipEntry. This allows - * clients (TraceFileSystemElement, TraceValidateAndImportOperation) to - * handle all the types transparently. - */ - private interface IFileSystemObject { - String getLabel(); - - String getName(); - - String getAbsolutePath(String parentContainerPath); - - String getSourceLocation(); - - Object getRawFileSystemObject(); - - boolean exists(); - } - - /** - * The "File" implementation of an IFileSystemObject - */ - private static class FileFileSystemObject implements IFileSystemObject { - - private File fFileSystemObject; - - private FileFileSystemObject(File fileSystemObject) { - fFileSystemObject = fileSystemObject; - } - - @Override - public String getLabel() { - String name = fFileSystemObject.getName(); - if (name.length() == 0) { - return fFileSystemObject.getPath(); - } - return name; - } - - @Override - public String getName() { - return fFileSystemObject.getName(); - } - - @Override - public String getAbsolutePath(String parentContainerPath) { - return fFileSystemObject.getAbsolutePath(); - } - - @Override - public boolean exists() { - return fFileSystemObject.exists(); - } - - @Override - public String getSourceLocation() { - IResource sourceResource; - String sourceLocation = null; - if (fFileSystemObject.isDirectory()) { - sourceResource = ResourcesPlugin.getWorkspace().getRoot().getContainerForLocation(Path.fromOSString(fFileSystemObject.getAbsolutePath())); - } else { - sourceResource = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(Path.fromOSString(fFileSystemObject.getAbsolutePath())); - } - if (sourceResource != null && sourceResource.exists()) { - try { - sourceLocation = sourceResource.getPersistentProperty(TmfCommonConstants.SOURCE_LOCATION); - } catch (CoreException e) { - // Something went wrong with the already existing resource. - // This is not a problem, we'll assign a new location below. - } - } - if (sourceLocation == null) { - sourceLocation = URIUtil.toUnencodedString(fFileSystemObject.toURI()); - } - return sourceLocation; - } - - @Override - public Object getRawFileSystemObject() { - return fFileSystemObject; - } - } - - /** - * The "Tar" implementation of an IFileSystemObject - */ - private static class TarFileSystemObject implements IFileSystemObject { - - private TarEntry fFileSystemObject; - private String fArchivePath; - - private TarFileSystemObject(TarEntry fileSystemObject, String archivePath) { - fFileSystemObject = fileSystemObject; - fArchivePath = archivePath; - } - - @Override - public String getLabel() { - return new Path(fFileSystemObject.getName()).lastSegment(); - } - - @Override - public String getName() { - return fFileSystemObject.getName(); - } - - @Override - public String getAbsolutePath(String parentContainerPath) { - return new Path(parentContainerPath).append(fFileSystemObject.getName()).toOSString(); - } - - @Override - public boolean exists() { - return true; - } - - @Override - public String getSourceLocation() { - URI uri = new File(fArchivePath).toURI(); - IPath entryPath = new Path(fFileSystemObject.getName()); - return URIUtil.toUnencodedString(URIUtil.toJarURI(uri, entryPath)); - } - - @Override - public Object getRawFileSystemObject() { - return fFileSystemObject; - } - } - - /** - * The "Zip" implementation of an IFileSystemObject - */ - private static class ZipFileSystemObject implements IFileSystemObject { - - private ZipEntry fFileSystemObject; - private String fArchivePath; - - private ZipFileSystemObject(ZipEntry fileSystemObject, String archivePath) { - fFileSystemObject = fileSystemObject; - fArchivePath = archivePath; - } - - @Override - public String getLabel() { - return new Path(fFileSystemObject.getName()).lastSegment(); - } - - @Override - public String getName() { - return fFileSystemObject.getName(); - } - - @Override - public String getAbsolutePath(String parentContainerPath) { - return new Path(parentContainerPath).append(fFileSystemObject.getName()).toOSString(); - } - - @Override - public boolean exists() { - return true; - } - - @Override - public String getSourceLocation() { - URI uri = new File(fArchivePath).toURI(); - IPath entryPath = new Path(fFileSystemObject.getName()); - return URIUtil.toUnencodedString(URIUtil.toJarURI(uri, entryPath)); - } - - @Override - public Object getRawFileSystemObject() { - return fFileSystemObject; - } - } - - private class ImportProvider implements IImportStructureProvider { - - ImportProvider() { - } - - @Override - public String getLabel(Object element) { - TraceFileSystemElement resource = (TraceFileSystemElement) element; - return resource.getLabel(); - } - - @Override - public List getChildren(Object element) { - TraceFileSystemElement resource = (TraceFileSystemElement) element; - Object[] array = resource.getFiles().getChildren(); - List list = new ArrayList<>(); - for (int i = 0; i < array.length; i++) { - list.add(array[i]); - } - return list; - } - - @Override - public InputStream getContents(Object element) { - TraceFileSystemElement resource = (TraceFileSystemElement) element; - return resource.getProvider().getContents(resource.getFileSystemObject()); - } - - @Override - public String getFullPath(Object element) { - TraceFileSystemElement resource = (TraceFileSystemElement) element; - return resource.getProvider().getFullPath(resource.getFileSystemObject()); - } - - @Override - public boolean isFolder(Object element) { - TraceFileSystemElement resource = (TraceFileSystemElement) element; - return resource.isDirectory(); - } - } - - private enum ImportConfirmation { - // ------------------------------------------------------------------------ - // Enum definition - // ------------------------------------------------------------------------ - RENAME(Messages.ImportTraceWizard_ImportConfigurationRename), - RENAME_ALL(Messages.ImportTraceWizard_ImportConfigurationRenameAll), - OVERWRITE(Messages.ImportTraceWizard_ImportConfigurationOverwrite), - OVERWRITE_ALL(Messages.ImportTraceWizard_ImportConfigurationOverwriteAll), - SKIP(Messages.ImportTraceWizard_ImportConfigurationSkip), - SKIP_ALL(Messages.ImportTraceWizard_ImportConfigurationSkipAll), - CONTINUE("CONTINUE"); //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * Name of enum - */ - private final String fInName; - - // ------------------------------------------------------------------------ - // Constuctors - // ------------------------------------------------------------------------ - - /** - * Private constructor - * - * @param name - * the name of state - */ - private ImportConfirmation(String name) { - fInName = name; - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - /** - * @return state name - */ - public String getInName() { - return fInName; - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardPageOptions.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardPageOptions.java deleted file mode 100644 index dc17bba85a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardPageOptions.java +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Marc-Andre Laperle - Use common method to get opened tmf projects - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace; - -import java.util.LinkedHashMap; -import java.util.Map; - -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTracesFolder; -import org.eclipse.linuxtools.tmf.ui.project.model.TraceUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.List; -import org.eclipse.ui.IWorkbench; - -/** - * This page selects the project to import to. - * - * @author Matthew Khouzam - * @since 2.0 - */ -public class ImportTraceWizardPageOptions extends AbstractImportTraceWizardPage { - - private List fProjects; - private final Map fProjectsMap = new LinkedHashMap<>(); - - /** - * Import page that tells where the trace will go - * - * @param workbench - * The workbench reference. - * @param selection - * The current selection - */ - public ImportTraceWizardPageOptions(IWorkbench workbench, IStructuredSelection selection) { - super(workbench, selection); - } - - @Override - public void createControl(Composite parent) { - super.createControl(parent); - IFolder originalFolder = getBatchWizard().getTargetFolder(); - IProject proj = null; - if (originalFolder != null) { - proj = originalFolder.getProject(); - } - - Composite optionPane = (Composite) this.getControl(); - optionPane.setLayout(new GridLayout()); - optionPane.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true)); - - fProjects = new List(optionPane, SWT.V_SCROLL); - fProjects.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - for (IProject project : TraceUtils.getOpenedTmfProjects()) { - final String name = project.getName(); - fProjectsMap.put(name, project); - fProjects.add(name); - } - - fProjects.getSelection(); - fProjects.addSelectionListener(new SelectionListener() { - - @Override - public void widgetSelected(SelectionEvent e) { - updateWithSelection(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - updateWithSelection(); - } - }); - if (proj != null) { - fProjects.setSelection(fProjects.indexOf(proj.getName())); - } else if (fProjects.getItemCount() > 0) { - fProjects.setSelection(0); - updateWithSelection(); - } - setMessage(Messages.SharedSelectProject); - this.setTitle(Messages.ImportTraceWizardPageOptionsTitle); - } - - private void updateWithSelection() { - String[] selection = fProjects.getSelection(); - if (selection.length > 0) { - final String listItem = selection[0]; - IFolder folder = fProjectsMap.get(listItem).getFolder(TmfTracesFolder.TRACES_FOLDER_NAME); - getBatchWizard().setTraceFolder(folder); - ImportTraceWizardPageOptions.this.setErrorMessage(null); - } else { - ImportTraceWizardPageOptions.this.setErrorMessage(Messages.SharedSelectProject); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardScanPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardScanPage.java deleted file mode 100644 index 6a19be7f9c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardScanPage.java +++ /dev/null @@ -1,566 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace; - -import java.io.File; -import java.text.DecimalFormat; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.jface.viewers.CellEditor; -import org.eclipse.jface.viewers.CheckStateChangedEvent; -import org.eclipse.jface.viewers.CheckboxTreeViewer; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.ColumnViewer; -import org.eclipse.jface.viewers.ColumnViewerEditor; -import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; -import org.eclipse.jface.viewers.EditingSupport; -import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter; -import org.eclipse.jface.viewers.ICheckStateListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.TextCellEditor; -import org.eclipse.jface.viewers.TreeViewerColumn; -import org.eclipse.jface.viewers.TreeViewerEditor; -import org.eclipse.jface.viewers.TreeViewerFocusCellManager; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TraceValidationHelper; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.ui.IWorkbench; - -/** - * Import page that scans files, can be cancelled this page is the third - * of three pages shown. This one selects the traces to be imported that are to - * be scanned. - * - * @author Matthew Khouzam - * @since 2.0 - */ -public class ImportTraceWizardScanPage extends AbstractImportTraceWizardPage { - - private static final int COL_WIDTH = 200; - private static final int MAX_TRACES = 65536; - private CheckboxTreeViewer traceTypeViewer; - - final ScanRunnable fRunnable = new ScanRunnable("Scan job"); //$NON-NLS-1$ - final private BlockingQueue fTracesToScan = new ArrayBlockingQueue<>(MAX_TRACES); - private volatile boolean fCanRun = true; - - // -------------------------------------------------------------------------------- - // Constructor and destructor - // -------------------------------------------------------------------------------- - - /** - * Import page that scans files, can be cancelled. - * - * @param name - * The name of the page. - * @param selection - * The current selection - */ - protected ImportTraceWizardScanPage(String name, IStructuredSelection selection) { - super(name, selection); - } - - /** - * Import page that scans files, can be cancelled - * - * @param workbench - * The workbench reference. - * @param selection - * The current selection - */ - public ImportTraceWizardScanPage(IWorkbench workbench, IStructuredSelection selection) { - super(workbench, selection); - } - - @Override - public void dispose() { - fCanRun = false; - fRunnable.done(Status.OK_STATUS); - super.dispose(); - } - - /* - * Init - */ - - @Override - public void createControl(Composite parent) { - super.createControl(parent); - final Composite control = (Composite) this.getControl(); - setTitle(Messages.ImportTraceWizardScanPageTitle); - traceTypeViewer = new CheckboxTreeViewer(control, SWT.CHECK); - traceTypeViewer.setContentProvider(getBatchWizard().getScannedTraces()); - traceTypeViewer.getTree().setHeaderVisible(true); - traceTypeViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - traceTypeViewer.setInput(getBatchWizard().getScannedTraces()); - traceTypeViewer.addCheckStateListener(new ImportTraceCheckStateListener()); - - TreeViewerFocusCellManager focusCellManager = new TreeViewerFocusCellManager(traceTypeViewer, new FocusCellOwnerDrawHighlighter(traceTypeViewer)); - ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(traceTypeViewer) { - }; - TreeViewerEditor.create(traceTypeViewer, focusCellManager, actSupport, ColumnViewerEditor.TABBING_HORIZONTAL - | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR - | ColumnViewerEditor.TABBING_VERTICAL | ColumnViewerEditor.KEYBOARD_ACTIVATION); - - final TextCellEditor textCellEditor = new TextCellEditor(traceTypeViewer.getTree()); - // -------------------- - // Column 1 - // -------------------- - TreeViewerColumn column = new TreeViewerColumn(traceTypeViewer, SWT.NONE); - column.getColumn().setWidth(COL_WIDTH); - column.getColumn().setText(Messages.ImportTraceWizardTraceDisplayName); - column.setLabelProvider(new FirstColumnLabelProvider()); - column.setEditingSupport(new ColumnEditorSupport(traceTypeViewer, textCellEditor)); - - // -------------------- - // Column 2 - // -------------------- - - column = new TreeViewerColumn(traceTypeViewer, SWT.NONE); - column.getColumn().setWidth(500); - column.getColumn().setText(Messages.ImportTraceWizardImportCaption); - column.setLabelProvider(new ColumnLabelProvider() { - @Override - public String getText(Object element) { - if (element instanceof FileAndName) { - FileAndName elem = (FileAndName) element; - return elem.getFile().getPath(); - } - return null; - } - }); - // -------------------- - // Column 3 - // -------------------- - - column = new TreeViewerColumn(traceTypeViewer, SWT.NONE); - - column.getColumn().setWidth(80); - column.getColumn().setText(Messages.ImportTraceWizardScanPageSize); - column.getColumn().setAlignment(SWT.RIGHT); - column.setLabelProvider(new ColumnLabelProvider() { - - @Override - public String getText(Object element) { - if (element instanceof FileAndName) { - - FileAndName elem = (FileAndName) element; - long len = recurseSize(elem.getFile()); - if (len > 0) { - double sizeb10 = Math.log10(len); - DecimalFormat df = new DecimalFormat(); - df.setMaximumFractionDigits(2); - df.setMinimumFractionDigits(0); - if (sizeb10 > 12) { - final double tbSize = len / 1024.0 / 1024 / 1024 / 1024; - return df.format(tbSize) + Messages.ImportTraceWizardScanPageTerabyte; - } - if (sizeb10 > 9) { - final double gbSize = len / 1024.0 / 1024 / 1024; - return df.format(gbSize) + Messages.ImportTraceWizardScanPageGigabyte; - } - if (sizeb10 > 6) { - final double mbSize = len / 1024.0 / 1024; - return df.format(mbSize) + Messages.ImportTraceWizardScanPageMegabyte; - } - if (sizeb10 > 3) { - final double kbSize = len / 1024.0; - return df.format(kbSize) + Messages.ImportTraceWizardScanPageKilobyte; - } - } - return Long.toString(len) + Messages.ImportTraceWizardScanPagebyte; - - } - return null; - } - - private long recurseSize(File file) { - if (file.isFile() && file.canRead()) { - return file.length(); - } - long size = 0; - if (file.exists() && file.isDirectory() && file.canRead()) { - final File[] listFiles = file.listFiles(); - if (listFiles != null) { - for (File child : listFiles) { - if (child.isFile() && child.canRead()) { - size += child.length(); - } else if (child.isDirectory()) { - size += recurseSize(child); - } else { - Activator.getDefault().logError("Unknown \"file\" type for " + child + ' ' + child.toString()); //$NON-NLS-1$ - } - } - } - } - return size; - } - }); - - init(); - getBatchWizard().setTracesToScan(fTracesToScan); - getBatchWizard().setTraceFolder(fTargetFolder); - - fRunnable.schedule(); - setErrorMessage(Messages.ImportTraceWizardScanPageSelectAtleastOne); - } - - private void init() { - Composite optionPane = (Composite) this.getControl(); - - optionPane.setLayout(new GridLayout()); - optionPane.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true)); - - final Button fLink = new Button(optionPane, SWT.RADIO); - fLink.setText(Messages.ImportTraceWizardLinkTraces); - fLink.setSelection(true); - fLink.setLayoutData(new GridData()); - - final Button fCopy = new Button(optionPane, SWT.RADIO); - fCopy.setText(Messages.ImportTraceWizardCopyTraces); - fCopy.setLayoutData(new GridData()); - - final SelectionListener linkedListener = new RadioChooser(fLink); - - fLink.addSelectionListener(linkedListener); - fCopy.addSelectionListener(linkedListener); - - Button fOverwrite = new Button(optionPane, SWT.CHECK); - fOverwrite.setText(Messages.ImportTraceWizardOverwriteTraces); - fOverwrite.setLayoutData(new GridData()); - fOverwrite.setSelection(true); - fOverwrite.addSelectionListener(new SelectionListener() { - - @Override - public void widgetSelected(SelectionEvent e) { - getBatchWizard().setOverwrite(((Button) e.widget).getSelection()); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - }); - } - - /* - * Helper classes - */ - - private final class RadioChooser implements SelectionListener { - final private Button isLinked; - - public RadioChooser(Button desiredButton) { - isLinked = desiredButton; - } - - @Override - public void widgetSelected(SelectionEvent e) { - - final Button widget = (Button) e.widget; - getBatchWizard().setLinked(widget.equals(isLinked)); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - - } - } - - private final class ColumnEditorSupport extends EditingSupport { - private final TextCellEditor textCellEditor; - - private ColumnEditorSupport(ColumnViewer viewer, TextCellEditor textCellEditor) { - super(viewer); - this.textCellEditor = textCellEditor; - } - - @Override - protected boolean canEdit(Object element) { - return element instanceof FileAndName; - } - - @Override - protected CellEditor getCellEditor(Object element) { - return textCellEditor; - } - - @Override - protected Object getValue(Object element) { - if (element instanceof FileAndName) { - return ((FileAndName) element).getName(); - } - return null; - } - - @Override - protected void setValue(Object element, Object value) { - FileAndName fan = (FileAndName) element; - fan.setName((String) value); - getBatchWizard().updateConflicts(); - traceTypeViewer.update(element, null); - traceTypeViewer.refresh(); - } - } - - private final class FirstColumnLabelProvider extends ColumnLabelProvider { - Image fConflict; - - @Override - public Image getImage(Object element) { - if (element instanceof FileAndName) { - final FileAndName fan = (FileAndName) element; - if (fan.isConflictingName()) { - if (fConflict == null) { - fConflict = Activator.getDefault().getImageFromImageRegistry(ITmfImageConstants.IMG_UI_CONFLICT); - } - return fConflict; - } - } - return null; - } - - @Override - public String getText(Object element) { - if (element instanceof FileAndName) { - FileAndName elem = (FileAndName) element; - return elem.getName(); - } - if (element instanceof String) { - return (String) element; - } - return null; - } - } - - private final class ImportTraceCheckStateListener implements ICheckStateListener { - @Override - public void checkStateChanged(CheckStateChangedEvent event) { - final CheckboxTreeViewer tv = (CheckboxTreeViewer) - event.getSource(); - if (event.getElement() instanceof FileAndName) { - final FileAndName element = (FileAndName) event.getElement(); - if (event.getChecked()) { - getBatchWizard().addFileToImport(element); - traceTypeViewer.update(element, null); - } - else { - getBatchWizard().removeFileToImport(element); - traceTypeViewer.update(element, null); - } - maintainCheckIntegrity(tv, element); - } - if (event.getElement() instanceof String) { - - tv.setSubtreeChecked(event.getElement(), event.getChecked()); - final Object[] children = - getBatchWizard().getScannedTraces().getChildren(event.getElement()); - if (event.getChecked()) { - for (int i = 0; i < children.length; i++) { - final FileAndName element = (FileAndName) children[i]; - getBatchWizard().addFileToImport(element); - traceTypeViewer.update(children[i], null); - } - } - else { - for (int i = 0; i < children.length; i++) { - getBatchWizard().removeFileToImport((FileAndName) children[i]); - - } - } - - } - getBatchWizard().updateConflicts(); - if (getBatchWizard().hasConflicts()) { - setErrorMessage(Messages.ImportTraceWizardScanPageRenameError); - } else if (!getBatchWizard().hasTracesToImport()) { - setErrorMessage(Messages.ImportTraceWizardScanPageSelectAtleastOne); - } else { - setErrorMessage(null); - } - getWizard().getContainer().updateButtons(); - traceTypeViewer.update(event.getElement(), null); - } - - private void maintainCheckIntegrity(final CheckboxTreeViewer viewer, final FileAndName element) { - final ImportTraceContentProvider scannedTraces = getBatchWizard().getScannedTraces(); - String parentElement = (String) scannedTraces.getParent(element); - boolean allChecked = true; - final FileAndName[] siblings = scannedTraces.getSiblings(element); - if (siblings != null) { - for (FileAndName child : siblings) { - allChecked &= viewer.getChecked(child); - } - } - viewer.setChecked(parentElement, allChecked); - } - } - - private final class ScanRunnable extends Job { - - // monitor is stored here, starts as the main monitor but becomes a - // submonitor - private IProgressMonitor fMonitor; - - public ScanRunnable(String name) { - super(name); - this.setSystem(true); - } - - private synchronized IProgressMonitor getMonitor() { - return fMonitor; - } - - @Override - public IStatus run(IProgressMonitor monitor) { - /* - * Set up phase, it is synchronous - */ - fMonitor = monitor; - final Control control = traceTypeViewer.getControl(); - // please note the sync exec here is to allow us to set - control.getDisplay().syncExec(new Runnable() { - @Override - public void run() { - // monitor gets overwritten here so it's necessary to save - // it in a field. - fMonitor = SubMonitor.convert(getMonitor()); - getMonitor().setTaskName(Messages.ImportTraceWizardPageScanScanning + ' '); - ((SubMonitor) getMonitor()).setWorkRemaining(IProgressMonitor.UNKNOWN); - } - }); - /* - * At this point we start calling async execs and updating the view. - * This is a good candidate to parallelise. - */ - while (fCanRun == true) { - boolean updated = false; - boolean validCombo; - if (fTracesToScan.isEmpty() && !control.isDisposed()) { - control.getDisplay().asyncExec(new Runnable() { - - @Override - public void run() { - if (!control.isDisposed()) { - getMonitor().setTaskName(Messages.ImportTraceWizardPageScanScanning + ' '); - getMonitor().subTask(Messages.ImportTraceWizardPageScanDone); - ImportTraceWizardScanPage.this.setMessage(Messages.ImportTraceWizardPageScanScanning + ' ' + Messages.ImportTraceWizardPageScanDone); - } - } - }); - } - try { - final TraceValidationHelper traceToScan = fTracesToScan.take(); - - if (!getBatchWizard().hasScanned(traceToScan)) { - getBatchWizard().addResult(traceToScan, TmfTraceType.validate(traceToScan)); - } - - /* - * The following is to update the UI - */ - validCombo = getBatchWizard().getResult(traceToScan); - if (validCombo) { - // Synched on it's parent - - getBatchWizard().getScannedTraces().addCandidate(traceToScan.getTraceType(), new File(traceToScan.getTraceToScan())); - updated = true; - } - final int scanned = getBatchWizard().getNumberOfResults(); - final int total = scanned + fTracesToScan.size(); - final int prevVal = (int) ((scanned - 1) * 100.0 / total); - final int curVal = (int) ((scanned) * 100.0 / total); - if (curVal != prevVal) { - updated = true; - } - /* - * update the progress - */ - if (updated) { - if (!control.isDisposed()) { - control.getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - if (!control.isDisposed()) { - getMonitor().setTaskName(Messages.ImportTraceWizardPageScanScanning + ' '); - getMonitor().subTask(traceToScan.getTraceToScan()); - getMonitor().worked(1); - ImportTraceWizardScanPage.this.setMessage(Messages.ImportTraceWizardPageScanScanning + ' ' - + Integer.toString(curVal) - + '%'); - } - } - } - ); - } - } - - /* - * here we update the table - */ - final boolean editing = traceTypeViewer.isCellEditorActive(); - if (updated && !editing) { - if (!control.isDisposed()) { - control.getDisplay().asyncExec(new Runnable() { - - @Override - public void run() { - if (!control.isDisposed()) { - if (!traceTypeViewer.isCellEditorActive()) { - traceTypeViewer.refresh(); - } - } - } - }); - } - } - } catch (InterruptedException e) { - return new Status(IStatus.CANCEL, Activator.PLUGIN_ID, new String()); - } - } - return Status.OK_STATUS; - } - } - - /** - * Refresh the view and the corresponding model. - */ - public void refresh() { - final Control control = traceTypeViewer.getControl(); - if (!control.isDisposed()) { - control.getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - if (!control.isDisposed()) { - traceTypeViewer.refresh(); - } - } - }); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardSelectDirectoriesPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardSelectDirectoriesPage.java deleted file mode 100644 index 0ff8919bf4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardSelectDirectoriesPage.java +++ /dev/null @@ -1,261 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Marc-Andre Laperle - Remember last selected directory - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace; - -import java.io.File; - -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.DirectoryDialog; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableItem; -import org.eclipse.ui.IWorkbench; - -/** - * Select the directories to scan for traces this page is the second of - * three pages shown. This one selects the files to be scanned. - * - * @author Matthew Khouzam - * @since 2.0 - */ -public class ImportTraceWizardSelectDirectoriesPage extends AbstractImportTraceWizardPage { - - /** - * ID - */ - public static String ID = "org.eclipse.linuxtools.tmf.ui.project.wizards.importtrace.ImportTraceWizardPagePopulate"; //$NON-NLS-1$ - - private static final String STORE_DIRECTORY_ID = ID + ".STORE_DIRECTORY_ID"; //$NON-NLS-1$ - - /** - * Constructor. Creates the trace wizard page. - * - * @param name - * The name of the page. - * @param selection - * The current selection - */ - protected ImportTraceWizardSelectDirectoriesPage(String name, IStructuredSelection selection) { - super(name, selection); - } - - /** - * Constructor - * - * @param workbench - * The workbench reference. - * @param selection - * The current selection - */ - public ImportTraceWizardSelectDirectoriesPage(IWorkbench workbench, IStructuredSelection selection) { - super(workbench, selection); - } - - @Override - public void createControl(Composite parent) { - super.createControl(parent); - final Composite control = (Composite) this.getControl(); - control.setLayout(new GridLayout(2, false)); - control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - final Table selectedFiles = new Table(control, SWT.H_SCROLL | SWT.V_SCROLL); - selectedFiles.clearAll(); - selectedFiles.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - selectedFiles.setLinesVisible(true); - - Composite buttonArea = new Composite(control, SWT.None); - buttonArea.setLayout(new GridLayout()); - buttonArea.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false)); - - Button addFile = new Button(buttonArea, SWT.PUSH); - addFile.setText(Messages.ImportTraceWizardAddFile); - addFile.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - addFile.addSelectionListener(new AddFileHandler()); - addFile.setAlignment(SWT.CENTER); - - Button addDirectory = new Button(buttonArea, SWT.PUSH); - addDirectory.setText(Messages.ImportTraceWizardAddDirectory); - addDirectory.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - addDirectory.addSelectionListener(new AddDirectoryHandler()); - addDirectory.setAlignment(SWT.CENTER); - - Button removeFile = new Button(buttonArea, SWT.PUSH); - removeFile.setText(Messages.ImportTraceWizardRemove); - removeFile.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - removeFile.addSelectionListener(new RemoveFileHandler(selectedFiles)); - removeFile.setAlignment(SWT.CENTER); - -// int maxSize = Math.max(addFile.getSize().x, Math.max(addDirectory.getSize().x, removeFile.getSize().x)); -// int maxHeight = Math.max(addFile.getSize().y, Math.max(addDirectory.getSize().y, removeFile.getSize().y)); -// addFile.setSize(maxSize, maxHeight); -// addDirectory.setSize(maxSize, maxHeight); -// removeFile.setSize(maxSize, maxHeight); - - this.setTitle(Messages.ImportTraceWizardDirectoryTitle); - } - - private void updateButtons() { - BatchImportTraceWizard wiz = getBatchWizard(); - updateTable(); - wiz.getContainer().updateButtons(); - } - - private void updateTable() { - final Table selectedFiles = (Table) ((Composite) getControl()).getChildren()[0]; - selectedFiles.clearAll(); - selectedFiles.setItemCount(0); - for (String s : ((BatchImportTraceWizard) getWizard()).getFileNames()) { - TableItem ti = new TableItem(selectedFiles, SWT.None); - ti.setText(s); - } - } - - @Override - public boolean canFlipToNextPage() { - final Table selectedFiles = (Table) ((Composite) getControl()).getChildren()[0]; - boolean canLoad = selectedFiles.getItemCount() > 0; - if (canLoad) { - setErrorMessage(null); - } else { - setErrorMessage(Messages.ImportTraceWizardDirectoryHint); - } - return canLoad; - } - - private final class AddFileHandler implements SelectionListener { - @Override - public void widgetSelected(SelectionEvent e) { - - FileDialog dialog = new - FileDialog(Display.getCurrent().getActiveShell(), SWT.NONE); - - String lastDirectory = getLastSelectedDirectory(); - if (lastDirectory != null) { - dialog.setFilterPath(lastDirectory); - } - - String fn = dialog.open(); - if (null != fn) { - File f = new File(fn); - if (f.exists()) { - getBatchWizard().addFileToScan(fn); - saveSelectedDirectory(f.getParentFile()); - } - } - updateButtons(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - } - - private final class AddDirectoryHandler implements SelectionListener { - @Override - public void widgetSelected(SelectionEvent e) { - - // BUG BUG BUG BUG BUG IN SWT. Cannot read multiple files in a - // fake directory. - -// FileDialog dialog = new -// FileDialog(Display.getCurrent().getActiveShell(), SWT.OPEN | -// SWT.MULTI); -// dialog.setFilterPath("."); -// if (null != dialog.open()) { -// for (String fn : dialog.getFileNames()) { -// final String pathname = dialog.getFilterPath() + -// File.separator + fn; -// File f = new File(pathname); -// if (f.exists()) { -// ((BatchImportTraceWizard) getWizard()).addFile(fn, f); -// } -// } -// } - - DirectoryDialog dialog = new - DirectoryDialog(Display.getCurrent().getActiveShell(), SWT.NONE); - String lastDirectory = getLastSelectedDirectory(); - if (lastDirectory != null) { - dialog.setFilterPath(lastDirectory); - } - - String fn = dialog.open(); - if (null != fn) { - File f = new File(fn); - if (f.exists()) { - getBatchWizard().addFileToScan(fn); - saveSelectedDirectory(f); - } - } - updateButtons(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - } - - private String getLastSelectedDirectory() { - final IDialogSettings settings = getDialogSettings(); - if (settings != null) { - final String directory = settings.get(STORE_DIRECTORY_ID); - if (directory != null && !directory.isEmpty()) { - final File file = new File(directory); - if (file.exists()) { - return directory.toString(); - } - } - } - - return null; - } - - private void saveSelectedDirectory(File directory) { - final IDialogSettings settings = getDialogSettings(); - if (settings != null && directory != null && directory.exists()) { - settings.put(STORE_DIRECTORY_ID, directory.toString()); - } - } - - private final class RemoveFileHandler implements SelectionListener { - private final Table selectedFiles; - - private RemoveFileHandler(Table selectedFiles) { - this.selectedFiles = selectedFiles; - } - - @Override - public void widgetSelected(SelectionEvent e) { - TableItem selectedToRemove[] = selectedFiles.getSelection(); - for (TableItem victim : selectedToRemove) { - String victimName = victim.getText(); - ((BatchImportTraceWizard) getWizard()).removeFile(victimName); - } - updateButtons(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardSelectTraceTypePage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardSelectTraceTypePage.java deleted file mode 100644 index ec83439e1c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardSelectTraceTypePage.java +++ /dev/null @@ -1,184 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.viewers.CheckStateChangedEvent; -import org.eclipse.jface.viewers.CheckboxTreeViewer; -import org.eclipse.jface.viewers.ICheckStateListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.ui.IWorkbench; - -/** - * Select trace types to import, this page is the first of three pages - * shown. This one selects the type of traces that are to be scanned. - * - * @author Matthew Khouzam - * @since 2.0 - */ -public class ImportTraceWizardSelectTraceTypePage extends AbstractImportTraceWizardPage { - - private CheckboxTreeViewer fTreeView; - private final TraceTypeContentProvider fProvider = new TraceTypeContentProvider(); - - /** - * Select trace types to import - * - * @param name - * The name of the page. - * @param selection - * The current selection - */ - protected ImportTraceWizardSelectTraceTypePage(String name, IStructuredSelection selection) { - super(name, selection); - } - - /** - * Select trace types to import - * - * @param workbench - * The workbench reference. - * @param selection - * The current selection - */ - public ImportTraceWizardSelectTraceTypePage(IWorkbench workbench, IStructuredSelection selection) { - super(workbench, selection); - } - - @Override - public void createControl(Composite parent) { - super.createControl(parent); - Composite control = (Composite) this.getControl(); - - final ICheckStateListener listener = new TraceTypeCheckListener(); - - setTitle(Messages.ImportTraceWizardSelectTraceTypePageTitle); - - fTreeView = new CheckboxTreeViewer(control, SWT.BORDER); - fTreeView.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - fTreeView.setContentProvider(fProvider); - fTreeView.setInput(fProvider); - fTreeView.setLabelProvider(new LabelProvider() { - @Override - public String getText(Object element) { - return element.toString(); - } - }); - fTreeView.addCheckStateListener(listener); - - // populateTree(treeView); - - Composite buttonArea = new Composite(control, SWT.NONE); - buttonArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - buttonArea.setLayout(new GridLayout(2, false)); - - Button selectAll = new Button(buttonArea, SWT.NONE); - selectAll.setText(Messages.ImportTraceWizardSelectAll); - selectAll.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false)); - selectAll.addListener(SWT.Selection, new Listener() { - @Override - public void handleEvent(Event event) { - String elements[] = (String[]) ((ITreeContentProvider) fTreeView.getContentProvider()).getElements(null); - for (String key : elements) { - fTreeView.setSubtreeChecked(key, true); - } - getWizard().getContainer().updateButtons(); - } - }); - - Button selectNone = new Button(buttonArea, SWT.NONE); - selectNone.setText(Messages.ImportTraceWizardPageSelectNone); - selectNone.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); - selectNone.addListener(SWT.Selection, new Listener() { - @Override - public void handleEvent(Event event) { - String elements[] = (String[]) ((ITreeContentProvider) fTreeView.getContentProvider()).getElements(null); - for (String key : elements) { - fTreeView.setSubtreeChecked(key, false); - } - getWizard().getContainer().updateButtons(); - } - }); - fTreeView.expandAll(); - } - - @Override - public boolean canFlipToNextPage() { - List tracesToScan = new ArrayList<>(); - String elements[] = (String[]) fProvider.getElements(null); - for (String traceFamily : elements) { - final TraceTypeHelper[] children = (TraceTypeHelper[]) fProvider.getChildren(traceFamily); - if (children != null) { - for (TraceTypeHelper traceType : children) { - if (fTreeView.getChecked(traceType)) { - tracesToScan.add(traceType.getCanonicalName()); - } - } - } - } - ((BatchImportTraceWizard) getWizard()).setTraceTypesToScan(tracesToScan); - if (tracesToScan.isEmpty()) { - setErrorMessage(Messages.ImportTraceWizardPageSelectHint); - } else { - setErrorMessage(null); - } - return super.canFlipToNextPage() && !tracesToScan.isEmpty(); - } - - private final class TraceTypeCheckListener implements ICheckStateListener { - @Override - public void checkStateChanged(CheckStateChangedEvent event) { - - boolean checkStatus = event.getChecked(); - Object element = event.getElement(); - - fTreeView.setGrayed(element, false); - fTreeView.setSubtreeChecked(element, checkStatus); - ITreeContentProvider tcp = (ITreeContentProvider) fTreeView.getContentProvider(); - String parentElement = (String) tcp.getParent(element); - if (parentElement != null) { - TraceTypeHelper[] siblings = (TraceTypeHelper[]) tcp.getChildren(parentElement); - final TraceTypeHelper first = siblings[0]; - final boolean isFirstChecked = fTreeView.getChecked(first); - boolean allSame = true; - for (TraceTypeHelper peer : siblings) { - final boolean peerChecked = fTreeView.getChecked(peer); - if (peerChecked != isFirstChecked) { - allSame = false; - } - } - if (allSame) { - fTreeView.setGrayed(parentElement, false); - fTreeView.setChecked(parentElement, checkStatus); - } else { - fTreeView.setChecked(parentElement, false); - fTreeView.setGrayed(parentElement, true); - } - } - getWizard().getContainer().updateButtons(); - - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/Messages.java deleted file mode 100644 index c66cc968fd..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/Messages.java +++ /dev/null @@ -1,237 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Bernd Hufmann - Add ImportTraceWizard messages - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace; - -import org.eclipse.osgi.util.NLS; - -/** - * The messages for import trace wizards. - * @author Matthew Khouzam - */ -@SuppressWarnings("javadoc") -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace.messages"; //$NON-NLS-1$ - - // Import Trace Wizard - /** - * The dialog title of the import trace wizard - */ - public static String ImportTraceWizard_DialogTitle; - /** - * The title of the file system within the import trace wizard - */ - public static String ImportTraceWizard_FileSystemTitle; - /** - * The title of the the import trace wizard page. - */ - public static String ImportTraceWizard_ImportTrace; - /** - * The label of the directory location (import trace wizard) - */ - public static String ImportTraceWizard_DirectoryLocation; - /** - * The label of the archive location (import trace wizard) - */ - public static String ImportTraceWizard_ArchiveLocation; - /** - * The title of the select trace directory dialog (import trace wizard) - */ - public static String ImportTraceWizard_SelectTraceDirectoryTitle; - /** - * The title of the select trace archive dialog (import trace wizard) - */ - public static String ImportTraceWizard_SelectTraceArchiveTitle; - /** - * The message of the select trace directory dialog (import trace wizard) - */ - public static String ImportTraceWizard_SelectTraceDirectoryMessage; - /** - * The title of the trace type label (import trace wizard) - */ - public static String ImportTraceWizard_TraceType; - /** - * The label of the overwrite checkbox (import trace wizard) - */ - public static String ImportTraceWizard_OverwriteExistingTrace; - /** - * The label of the checkbox to create a link to the trace in workspace (import trace wizard) - */ - public static String ImportTraceWizard_CreateLinksInWorkspace; - /** - * The label of the checkbox to preserve the folder structure of selected the traces in workspace (import trace wizard) - */ - public static String ImportTraceWizard_PreserveFolderStructure; - /** - * The error message for invalid trace directory (import trace wizard) - */ - public static String ImportTraceWizard_InvalidTraceDirectory; - /** - * The error message when a trace validation failed (import trace wizard). - */ - public static String ImportTraceWizard_TraceValidationFailed; - /** - * The error message when a trace already exists in project (import trace wizard). - */ - public static String ImportTraceWizard_TraceAlreadyExists; - /** - * The title of rename button for import configuration dialog. - */ - public static String ImportTraceWizard_ImportConfigurationRename; - /** - * The title of rename all button for import configuration dialog. - */ - public static String ImportTraceWizard_ImportConfigurationRenameAll; - /** - * The title of overwrite button for import configuration dialog. - */ - public static String ImportTraceWizard_ImportConfigurationOverwrite; - /** - * The title of overwrite all button for import configuration dialog. - */ - public static String ImportTraceWizard_ImportConfigurationOverwriteAll; - /** - * The title of skip button for import configuration dialog. - */ - public static String ImportTraceWizard_ImportConfigurationSkip; - /** - * The title of skip all button for import configuration dialog. - */ - public static String ImportTraceWizard_ImportConfigurationSkipAll; - /** - * The error message when trace source is empty (import trace wizard). - */ - public static String ImportTraceWizard_SelectTraceSourceEmpty; - /** - * The error message when the specified archive file is not valid. - */ - public static String ImportTraceWizard_BadArchiveFormat; - /** - * The error message when no trace is selected (import trace wizard). - */ - public static String ImportTraceWizard_SelectTraceNoneSelected; - /** - * The error message when an error occurred during import operation. - */ - public static String ImportTraceWizard_ImportProblem; - /** - * The error message if destination directory is a virtual folder. - */ - public static String ImportTraceWizard_CannotImportFilesUnderAVirtualFolder; - /** - * The error message if destination directory is a virtual folder (for a link). - */ - public static String ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder; - /** - * The label string of the browse button. - */ - public static String ImportTraceWizard_BrowseButton; - /** - * The information label string. - */ - public static String ImportTraceWizard_Information; - /** - * The label of the checkbox to import unrecognized trace files - */ - public static String ImportTraceWizard_ImportUnrecognized; - /** - * The message when the import operation was cancelled. - */ - public static String ImportTraceWizard_ImportOperationCancelled; - /** - * The message when the trace type is not found. - */ - public static String ImportTraceWizard_TraceTypeNotFound; - /** - * The import operation task name. - */ - public static String ImportTraceWizard_ImportOperationTaskName; - /** - * The extract import operation task name - */ - public static String ImportTraceWizard_ExtractImportOperationTaskName; - /** - * The label to indicate that trace type auto detection shall be used. - */ - public static String ImportTraceWizard_AutoDetection; - - - // Batch Import Wizard - public static String ImportTraceWizardImportProblem ; - public static String ImportTraceWizardImportCaption; - public static String ImportTraceWizardTraceDisplayName; - public static String ImportTraceWizardLinkTraces; - public static String ImportTraceWizardCopyTraces; - public static String ImportTraceWizardOverwriteTraces; - public static String ImportTraceWizardAddFile; - public static String ImportTraceWizardAddDirectory; - public static String ImportTraceWizardRemove; - public static String ImportTraceWizardDirectoryTitle; - public static String ImportTraceWizardDirectoryHint; - /** - * @since 2.2 - */ - public static String ImportTraceWizardScanPagebyte; - - /** - * @since 2.2 - */ - public static String ImportTraceWizardScanPageGigabyte; - - /** - * @since 2.2 - */ - public static String ImportTraceWizardScanPageKilobyte; - - /** - * @since 2.2 - */ - public static String ImportTraceWizardScanPageMegabyte; - - public static String ImportTraceWizardScanPageRenameError; - /** - * @since 2.2 - */ - public static String ImportTraceWizardScanPageSelectAtleastOne; - - /** - * @since 2.2 - */ - public static String ImportTraceWizardScanPageSize; - public static String ImportTraceWizardSelectAll; - /** - * @since 2.2 - */ - public static String ImportTraceWizardScanPageTerabyte; - - public static String ImportTraceWizardScanPageTitle; - public static String ImportTraceWizardSelectTraceTypePageTitle; - public static String ImportTraceWizardPageOptionsTitle; - public static String ImportTraceWizardPageScanDone; - public static String ImportTraceWizardPageScanScanning; - public static String ImportTraceWizardPageSelectNone; - public static String ImportTraceWizardPageSelectHint; - public static String BatchImportTraceWizardRemove; - public static String BatchImportTraceWizardAdd; - public static String BatchImportTraceWizardErrorImportingTraceResource; - - public static String SharedSelectProject; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ResourceTreeAndListGroup.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ResourceTreeAndListGroup.java deleted file mode 100644 index 6eb421894b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ResourceTreeAndListGroup.java +++ /dev/null @@ -1,1203 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2014 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - * Marc-Andre Laperle - Copied from platform (org.eclipse.ui.internal.ide.dialogs) - *******************************************************************************/ -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.eclipse.core.commands.common.EventManager; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.jface.viewers.CheckStateChangedEvent; -import org.eclipse.jface.viewers.CheckboxTableViewer; -import org.eclipse.jface.viewers.CheckboxTreeViewer; -import org.eclipse.jface.viewers.ICheckStateListener; -import org.eclipse.jface.viewers.ILabelProvider; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.ITreeViewerListener; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.TreeExpansionEvent; -import org.eclipse.jface.viewers.ViewerComparator; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.BusyIndicator; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.ui.internal.ide.dialogs.IElementFilter; - -/** - * Workbench-level composite that combines a CheckboxTreeViewer and CheckboxListViewer. - * All viewer selection-driven interactions are handled within this object - */ -@SuppressWarnings({"restriction", "rawtypes", "javadoc", "unchecked"}) -class ResourceTreeAndListGroup extends EventManager implements - ICheckStateListener, ISelectionChangedListener, ITreeViewerListener { - private Object root; - - private Object currentTreeSelection; - - private Collection expandedTreeNodes = new HashSet(); - - private Map checkedStateStore = new HashMap(9); - - private HashSet whiteCheckedTreeItems = new HashSet(); - - private ITreeContentProvider treeContentProvider; - - private IStructuredContentProvider listContentProvider; - - private ILabelProvider treeLabelProvider; - - private ILabelProvider listLabelProvider; - - // widgets - private CheckboxTreeViewer treeViewer; - - private CheckboxTableViewer listViewer; - - //height hint for viewers - private static int PREFERRED_HEIGHT = 150; - - /** - * Create an instance of this class. Use this constructor if you wish to specify - * the width and/or height of the combined widget (to only hardcode one of the - * sizing dimensions, specify the other dimension's value as -1) - * - * @param parent - * @param rootObject - * @param treeContentProvider - * @param treeLabelProvider - * @param listContentProvider - * @param listLabelProvider - * @param style - * @param useHeightHint If true then use the height hint - * to make this group big enough - * - */ - public ResourceTreeAndListGroup(Composite parent, Object rootObject, - ITreeContentProvider treeContentProvider, - ILabelProvider treeLabelProvider, - IStructuredContentProvider listContentProvider, - ILabelProvider listLabelProvider, int style, boolean useHeightHint) { - - root = rootObject; - this.treeContentProvider = treeContentProvider; - this.listContentProvider = listContentProvider; - this.treeLabelProvider = treeLabelProvider; - this.listLabelProvider = listLabelProvider; - createContents(parent, style, useHeightHint); - } - - /** - * This method must be called just before this window becomes visible. - */ - public void aboutToOpen() { - determineWhiteCheckedDescendents(root); - checkNewTreeElements(treeContentProvider.getElements(root)); - currentTreeSelection = null; - - //select the first element in the list - Object[] elements = treeContentProvider.getElements(root); - Object primary = elements.length > 0 ? elements[0] : null; - if (primary != null) { - treeViewer.setSelection(new StructuredSelection(primary)); - } - treeViewer.getControl().setFocus(); - } - - /** - * Add the passed listener to self's collection of clients - * that listen for changes to element checked states - * - * @param listener ICheckStateListener - */ - public void addCheckStateListener(ICheckStateListener listener) { - addListenerObject(listener); - } - - /** - * Return a boolean indicating whether all children of the passed tree element - * are currently white-checked - * - * @return boolean - * @param treeElement java.lang.Object - */ - protected boolean areAllChildrenWhiteChecked(Object treeElement) { - Object[] children = treeContentProvider.getChildren(treeElement); - for (int i = 0; i < children.length; ++i) { - if (!whiteCheckedTreeItems.contains(children[i])) { - return false; - } - } - - return true; - } - - /** - * Return a boolean indicating whether all list elements associated with - * the passed tree element are currently checked - * - * @return boolean - * @param treeElement java.lang.Object - */ - protected boolean areAllElementsChecked(Object treeElement) { - List checkedElements = (List) checkedStateStore.get(treeElement); - if (checkedElements == null) { - return false; - } - - return getListItemsSize(treeElement) == checkedElements.size(); - } - - /** - * Iterate through the passed elements which are being realized for the first - * time and check each one in the tree viewer as appropriate - */ - protected void checkNewTreeElements(Object[] elements) { - for (int i = 0; i < elements.length; ++i) { - Object currentElement = elements[i]; - boolean checked = checkedStateStore.containsKey(currentElement); - treeViewer.setChecked(currentElement, checked); - treeViewer.setGrayed(currentElement, checked - && !whiteCheckedTreeItems.contains(currentElement)); - } - } - - /** - * An item was checked in one of self's two views. Determine which - * view this occurred in and delegate appropriately - * - * @param event CheckStateChangedEvent - */ - @Override - public void checkStateChanged(final CheckStateChangedEvent event) { - - //Potentially long operation - show a busy cursor - BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), - new Runnable() { - @Override - public void run() { - if (event.getCheckable().equals(treeViewer)) { - treeItemChecked(event.getElement(), event - .getChecked()); - } else { - listItemChecked(event.getElement(), event - .getChecked(), true); - } - - notifyCheckStateChangeListeners(event); - } - }); - } - - /** - * Lay out and initialize self's visual components. - * - * @param parent org.eclipse.swt.widgets.Composite - * @param style the style flags for the new Composite - * @param useHeightHint If true yse the preferredHeight. - */ - protected void createContents(Composite parent, int style, - boolean useHeightHint) { - // group pane - Composite composite = new Composite(parent, style); - composite.setFont(parent.getFont()); - GridLayout layout = new GridLayout(); - layout.numColumns = 2; - layout.makeColumnsEqualWidth = true; - layout.marginHeight = 0; - layout.marginWidth = 0; - composite.setLayout(layout); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - - createTreeViewer(composite, useHeightHint); - createListViewer(composite, useHeightHint); - - initialize(); - } - - /** - * Create this group's list viewer. - */ - protected void createListViewer(Composite parent, boolean useHeightHint) { - listViewer = CheckboxTableViewer.newCheckList(parent, SWT.BORDER); - GridData data = new GridData(GridData.FILL_BOTH); - if (useHeightHint) { - data.heightHint = PREFERRED_HEIGHT; - } - listViewer.getTable().setLayoutData(data); - listViewer.getTable().setFont(parent.getFont()); - listViewer.setContentProvider(listContentProvider); - listViewer.setLabelProvider(listLabelProvider); - listViewer.addCheckStateListener(this); - } - - /** - * Create this group's tree viewer. - */ - protected void createTreeViewer(Composite parent, boolean useHeightHint) { - Tree tree = new Tree(parent, SWT.CHECK | SWT.BORDER); - GridData data = new GridData(GridData.FILL_BOTH); - if (useHeightHint) { - data.heightHint = PREFERRED_HEIGHT; - } - tree.setLayoutData(data); - tree.setFont(parent.getFont()); - - treeViewer = new CheckboxTreeViewer(tree); - treeViewer.setContentProvider(treeContentProvider); - treeViewer.setLabelProvider(treeLabelProvider); - treeViewer.addTreeListener(this); - treeViewer.addCheckStateListener(this); - treeViewer.addSelectionChangedListener(this); - } - - /** - * Returns a boolean indicating whether the passed tree element should be - * at LEAST gray-checked. Note that this method does not consider whether - * it should be white-checked, so a specified tree item which should be - * white-checked will result in a true answer from this method. - * To determine whether a tree item should be white-checked use method - * #determineShouldBeWhiteChecked(Object). - * - * @param treeElement java.lang.Object - * @return boolean - * @see #determineShouldBeWhiteChecked(Object) - */ - protected boolean determineShouldBeAtLeastGrayChecked(Object treeElement) { - // if any list items associated with treeElement are checked then it - // retains its gray-checked status regardless of its children - List checked = (List) checkedStateStore.get(treeElement); - if (checked != null && (!checked.isEmpty())) { - return true; - } - - // if any children of treeElement are still gray-checked then treeElement - // must remain gray-checked as well. Only ask expanded nodes - if (expandedTreeNodes.contains(treeElement)) { - Object[] children = treeContentProvider.getChildren(treeElement); - for (int i = 0; i < children.length; ++i) { - if (checkedStateStore.containsKey(children[i])) { - return true; - } - } - } - - return false; - } - - /** - * Returns a boolean indicating whether the passed tree item should be - * white-checked. - * - * @return boolean - * @param treeElement java.lang.Object - */ - protected boolean determineShouldBeWhiteChecked(Object treeElement) { - return areAllChildrenWhiteChecked(treeElement) - && areAllElementsChecked(treeElement); - } - - /** - * Recursively add appropriate tree elements to the collection of - * known white-checked tree elements. - * - * @param treeElement java.lang.Object - */ - protected void determineWhiteCheckedDescendents(Object treeElement) { - // always go through all children first since their white-checked - // statuses will be needed to determine the white-checked status for - // this tree element - Object[] children = treeContentProvider.getElements(treeElement); - for (int i = 0; i < children.length; ++i) { - determineWhiteCheckedDescendents(children[i]); - } - - // now determine the white-checked status for this tree element - if (determineShouldBeWhiteChecked(treeElement)) { - setWhiteChecked(treeElement, true); - } - } - - /** - * Cause the tree viewer to expand all its items - */ - public void expandAll() { - treeViewer.expandAll(); - } - - /** - * Expand an element in a tree viewer - */ - private void expandTreeElement(final Object item) { - BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), - new Runnable() { - @Override - public void run() { - - // First see if the children need to be given their checked state at all. If they've - // already been realized then this won't be necessary - if (expandedTreeNodes.contains(item)) { - checkNewTreeElements(treeContentProvider - .getChildren(item)); - } else { - - expandedTreeNodes.add(item); - if (whiteCheckedTreeItems.contains(item)) { - //If this is the first expansion and this is a white checked node then check the children - Object[] children = treeContentProvider - .getChildren(item); - for (int i = 0; i < children.length; ++i) { - if (!whiteCheckedTreeItems - .contains(children[i])) { - Object child = children[i]; - setWhiteChecked(child, true); - treeViewer.setChecked(child, true); - checkedStateStore.put(child, - new ArrayList()); - } - } - - //Now be sure to select the list of items too - setListForWhiteSelection(item); - } - } - - } - }); - } - - /** - * Add all of the selected children of nextEntry to result recursively. - * This does not set any values in the checked state. - * @param treeElement The tree elements being queried - * @param addAll a boolean to indicate if the checked state store needs to be queried - * @param filter IElementFilter - the filter being used on the data - * @param monitor IProgressMonitor or null that the cancel is polled for - */ - private void findAllSelectedListElements(Object treeElement, - String parentLabel, boolean addAll, IElementFilter filter, - IProgressMonitor monitor) throws InterruptedException { - - String fullLabel = null; - if (monitor != null && monitor.isCanceled()) { - return; - } - if (monitor != null) { - fullLabel = getFullLabel(treeElement, parentLabel); - monitor.subTask(fullLabel); - } - - if (addAll) { - filter.filterElements(listContentProvider.getElements(treeElement), - monitor); - } else { //Add what we have stored - if (checkedStateStore.containsKey(treeElement)) { - filter.filterElements((Collection) checkedStateStore - .get(treeElement), monitor); - } - } - - Object[] treeChildren = treeContentProvider.getChildren(treeElement); - for (int i = 0; i < treeChildren.length; i++) { - Object child = treeChildren[i]; - if (addAll) { - findAllSelectedListElements(child, fullLabel, true, filter, - monitor); - } else { //Only continue for those with checked state - if (checkedStateStore.containsKey(child)) { - findAllSelectedListElements(child, fullLabel, - whiteCheckedTreeItems.contains(child), filter, - monitor); - } - } - - } - } - - /** - * Find all of the white checked children of the treeElement and add them to the collection. - * If the element itself is white select add it. If not then add any selected list elements - * and recurse down to the children. - * @param treeElement java.lang.Object - * @param result java.util.Collection - */ - private void findAllWhiteCheckedItems(Object treeElement, Collection result) { - - if (whiteCheckedTreeItems.contains(treeElement)) { - result.add(treeElement); - } else { - Collection listChildren = (Collection) checkedStateStore - .get(treeElement); - //if it is not in the store then it and it's children are not interesting - if (listChildren == null) { - return; - } - result.addAll(listChildren); - Object[] children = treeContentProvider.getChildren(treeElement); - for (int i = 0; i < children.length; ++i) { - findAllWhiteCheckedItems(children[i], result); - } - } - } - - /** - * Returns a flat list of all of the leaf elements which are checked. Filter - * then based on the supplied ElementFilter. If monitor is cancelled then - * return null - * - * @param filter - - * the filter for the data - * @param monitor - * IProgressMonitor or null - * @throws InterruptedException - * If the find is interrupted. - */ - public void getAllCheckedListItems(IElementFilter filter, - IProgressMonitor monitor) throws InterruptedException { - - //Iterate through the children of the root as the root is not in the store - Object[] children = treeContentProvider.getChildren(root); - for (int i = 0; i < children.length; ++i) { - findAllSelectedListElements(children[i], null, - whiteCheckedTreeItems.contains(children[i]), filter, - monitor); - } - } - - /** Returns whether all items in the list are checked. - * This method is required, because this widget will keep items grey - * checked even though all children are selected (see grayUpdateHierarchy()). - * @return true if all items in the list are checked - false if not - */ - public boolean isEveryItemChecked() { - //Iterate through the children of the root as the root is not in the store - Object[] children = treeContentProvider.getChildren(root); - for (int i = 0; i < children.length; ++i) { - if (!whiteCheckedTreeItems.contains(children[i])) { - if (!treeViewer.getGrayed(children[i])) { - return false; - } - if (!isEveryChildrenChecked(children[i])) { - return false; - } - } - } - return true; - } - - /**Verifies of all list items of the tree element are checked, and - * if all children are white checked. If not, verify their children - * so that if an element is not white checked, but all its children - * are while checked, then, all items are considered checked. - * @param treeElement the treeElement which status to verify - * @return true if all items are checked, false otherwise. - */ - private boolean isEveryChildrenChecked(Object treeElement) { - List checked = (List) checkedStateStore.get(treeElement); - if (checked != null && (!checked.isEmpty())) { - Object[] listItems = listContentProvider.getElements(treeElement); - if (listItems.length != checked.size()) { - return false; - } - } - Object[] children = treeContentProvider.getChildren(treeElement); - for (int i = 0; i < children.length; ++i) { - if (!whiteCheckedTreeItems.contains(children[i])) { - if (!treeViewer.getGrayed(children[i])) { - return false; - } - if (!isEveryChildrenChecked(children[i])) { - return false; - } - } - } - return true; - } - - /** - * Returns a flat list of all of the leaf elements which are checked. - * - * @return all of the leaf elements which are checked. This API does not - * return null in order to keep backwards compatibility. - */ - public List getAllCheckedListItems() { - - final ArrayList returnValue = new ArrayList(); - - IElementFilter passThroughFilter = new IElementFilter() { - - @Override - public void filterElements(Collection elements, - IProgressMonitor monitor) { - returnValue.addAll(elements); - } - - @Override - public void filterElements(Object[] elements, - IProgressMonitor monitor) { - for (int i = 0; i < elements.length; i++) { - returnValue.add(elements[i]); - } - } - }; - - try { - getAllCheckedListItems(passThroughFilter, null); - } catch (InterruptedException exception) { - return new ArrayList(); - } - return returnValue; - - } - - /** - * Returns a flat list of all of the leaf elements. - * - * @return all of the leaf elements. - */ - public List getAllListItems() { - - final ArrayList returnValue = new ArrayList(); - - IElementFilter passThroughFilter = new IElementFilter() { - - @Override - public void filterElements(Collection elements, - IProgressMonitor monitor) { - returnValue.addAll(elements); - } - - @Override - public void filterElements(Object[] elements, - IProgressMonitor monitor) { - for (int i = 0; i < elements.length; i++) { - returnValue.add(elements[i]); - } - } - }; - - try { - Object[] children = treeContentProvider.getChildren(root); - for (int i = 0; i < children.length; ++i) { - findAllSelectedListElements(children[i], null, true, passThroughFilter, - null); - } - } catch (InterruptedException exception) { - return new ArrayList(); - } - return returnValue; - - } - - /** - * Returns a list of all of the items that are white checked. - * Any folders that are white checked are added and then any files - * from white checked folders are added. - * - * @return the list of all of the items that are white checked - */ - public List getAllWhiteCheckedItems() { - - List result = new ArrayList(); - - //Iterate through the children of the root as the root is not in the store - Object[] children = treeContentProvider.getChildren(root); - for (int i = 0; i < children.length; ++i) { - findAllWhiteCheckedItems(children[i], result); - } - - return result; - } - - /** - * Answer the number of elements that have been checked by the - * user. - * - * @return int - */ - public int getCheckedElementCount() { - return checkedStateStore.size(); - } - - /** - * Get the full label of the treeElement (its name and its parent's name). - * @param treeElement - the element being exported - * @param parentLabel - the label of the parent, can be null - * @return String - */ - protected String getFullLabel(Object treeElement, String parentLabel) { - String label = parentLabel; - if (parentLabel == null){ - label = ""; //$NON-NLS-1$ - } - IPath parentName = new Path(label); - - String elementText = treeLabelProvider.getText(treeElement); - if(elementText == null) { - return parentName.toString(); - } - return parentName.append(elementText).toString(); - } - - /** - * Return a count of the number of list items associated with a - * given tree item. - * - * @return int - * @param treeElement java.lang.Object - */ - protected int getListItemsSize(Object treeElement) { - Object[] elements = listContentProvider.getElements(treeElement); - return elements.length; - } - - /** - * Get the table the list viewer uses. - * @return org.eclipse.swt.widgets.Table - */ - public Table getListTable() { - return this.listViewer.getTable(); - } - - /** - * Logically gray-check all ancestors of treeItem by ensuring that they - * appear in the checked table - */ - protected void grayCheckHierarchy(Object treeElement) { - - //expand the element first to make sure we have populated for it - expandTreeElement(treeElement); - - // if this tree element is already gray then its ancestors all are as well - if (checkedStateStore.containsKey(treeElement)) { - return; // no need to proceed upwards from here - } - - checkedStateStore.put(treeElement, new ArrayList()); - Object parent = treeContentProvider.getParent(treeElement); - if (parent != null) { - grayCheckHierarchy(parent); - } - } - - /** - * Set the checked state of self and all ancestors appropriately. Do not white check anyone - this is - * only done down a hierarchy. - */ - private void grayUpdateHierarchy(Object treeElement) { - - boolean shouldBeAtLeastGray = determineShouldBeAtLeastGrayChecked(treeElement); - - treeViewer.setGrayChecked(treeElement, shouldBeAtLeastGray); - - if (whiteCheckedTreeItems.contains(treeElement)) { - whiteCheckedTreeItems.remove(treeElement); - } - - // proceed up the tree element hierarchy - Object parent = treeContentProvider.getParent(treeElement); - if (parent != null) { - grayUpdateHierarchy(parent); - } - } - - /** - * Set the initial checked state of the passed list element to true. - * @param element - */ - public void initialCheckListItem(Object element) { - Object parent = treeContentProvider.getParent(element); - selectAndReveal(parent); - //Check the element in the viewer as if it had been manually checked - listViewer.setChecked(element, true); - //As this is not done from the UI then set the box for updating from the selection to false - listItemChecked(element, true, false); - grayUpdateHierarchy(parent); - } - - /** - * Set the initial checked state of the passed element to true, - * as well as to all of its children and associated list elements - * @param element - */ - public void initialCheckTreeItem(Object element) { - treeItemChecked(element, true); - selectAndReveal(element); - } - - private void selectAndReveal(Object treeElement) { - treeViewer.reveal(treeElement); - IStructuredSelection selection = new StructuredSelection(treeElement); - treeViewer.setSelection(selection); - } - - /** - * Initialize this group's viewers after they have been laid out. - */ - protected void initialize() { - treeViewer.setInput(root); - this.expandedTreeNodes = new ArrayList(); - this.expandedTreeNodes.add(root); - - } - - /** - * Callback that's invoked when the checked status of an item in the list - * is changed by the user. Do not try and update the hierarchy if we are building the - * initial list. - */ - protected void listItemChecked(Object listElement, boolean state, - boolean updatingFromSelection) { - List checkedListItems = (List) checkedStateStore - .get(currentTreeSelection); - //If it has not been expanded do so as the selection of list items will affect gray state - if (!expandedTreeNodes.contains(currentTreeSelection)) { - expandTreeElement(currentTreeSelection); - } - - if (state) { - if (checkedListItems == null) { - // since the associated tree item has gone from 0 -> 1 checked - // list items, tree checking may need to be updated - grayCheckHierarchy(currentTreeSelection); - checkedListItems = (List) checkedStateStore - .get(currentTreeSelection); - } - checkedListItems.add(listElement); - } else { - checkedListItems.remove(listElement); - if (checkedListItems.isEmpty()) { - // since the associated tree item has gone from 1 -> 0 checked - // list items, tree checking may need to be updated - ungrayCheckHierarchy(currentTreeSelection); - } - } - - //Update the list with the selections if there are any - if (checkedListItems.size() > 0) { - checkedStateStore.put(currentTreeSelection, checkedListItems); - } - if (updatingFromSelection) { - grayUpdateHierarchy(currentTreeSelection); - } - } - - /** - * Notify all checked state listeners that the passed element has had - * its checked state changed to the passed state - */ - protected void notifyCheckStateChangeListeners( - final CheckStateChangedEvent event) { - Object[] array = getListeners(); - for (int i = 0; i < array.length; i++) { - final ICheckStateListener l = (ICheckStateListener) array[i]; - SafeRunner.run(new SafeRunnable() { - @Override - public void run() { - l.checkStateChanged(event); - } - }); - } - } - - /** - *Set the contents of the list viewer based upon the specified selected - *tree element. This also includes checking the appropriate list items. - * - *@param treeElement java.lang.Object - */ - protected void populateListViewer(final Object treeElement) { - listViewer.setInput(treeElement); - - //If the element is white checked but not expanded we have not set up all of the children yet - if (!(expandedTreeNodes.contains(treeElement)) - && whiteCheckedTreeItems.contains(treeElement)) { - - //Potentially long operation - show a busy cursor - BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), - new Runnable() { - @Override - public void run() { - setListForWhiteSelection(treeElement); - listViewer.setAllChecked(true); - } - }); - - } else { - List listItemsToCheck = (List) checkedStateStore.get(treeElement); - - if (listItemsToCheck != null) { - Iterator listItemsEnum = listItemsToCheck.iterator(); - while (listItemsEnum.hasNext()) { - listViewer.setChecked(listItemsEnum.next(), true); - } - } - } - } - - /** - * Logically gray-check all ancestors of treeItem by ensuring that they - * appear in the checked table. Add any elements to the selectedNodes - * so we can track that has been done. - */ - private void primeHierarchyForSelection(Object item, Set selectedNodes) { - - //Only prime it if we haven't visited yet - if (selectedNodes.contains(item)) { - return; - } - - checkedStateStore.put(item, new ArrayList()); - - //mark as expanded as we are going to populate it after this - expandedTreeNodes.add(item); - selectedNodes.add(item); - - Object parent = treeContentProvider.getParent(item); - if (parent != null) { - primeHierarchyForSelection(parent, selectedNodes); - } - } - - /** - * Remove the passed listener from self's collection of clients - * that listen for changes to element checked states - * - * @param listener ICheckStateListener - */ - public void removeCheckStateListener(ICheckStateListener listener) { - removeListenerObject(listener); - } - - /** - * Handle the selection of an item in the tree viewer - * - * @param event SelectionChangedEvent - */ - @Override - public void selectionChanged(SelectionChangedEvent event) { - IStructuredSelection selection = (IStructuredSelection) event - .getSelection(); - Object selectedElement = selection.getFirstElement(); - if (selectedElement == null) { - currentTreeSelection = null; - listViewer.setInput(currentTreeSelection); - return; - } - - // ie.- if not an item deselection - if (selectedElement != currentTreeSelection) { - populateListViewer(selectedElement); - } - - currentTreeSelection = selectedElement; - } - - /** - * Select or deselect all of the elements in the tree depending on the value of the selection - * boolean. Be sure to update the displayed files as well. - * @param selection - */ - public void setAllSelections(final boolean selection) { - - //If there is no root there is nothing to select - if (root == null) { - return; - } - - //Potentially long operation - show a busy cursor - BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), - new Runnable() { - @Override - public void run() { - setTreeChecked(root, selection); - listViewer.setAllChecked(selection); - } - }); - } - - /** - * The treeElement has been white selected. Get the list for the element and - * set it in the checked state store. - * @param treeElement the element being updated - */ - private void setListForWhiteSelection(Object treeElement) { - - Object[] listItems = listContentProvider.getElements(treeElement); - List listItemsChecked = new ArrayList(); - for (int i = 0; i < listItems.length; ++i) { - listItemsChecked.add(listItems[i]); - } - - checkedStateStore.put(treeElement, listItemsChecked); - } - - /** - * Set the list viewer's providers to those passed - * - * @param contentProvider ITreeContentProvider - * @param labelProvider ILabelProvider - */ - public void setListProviders(IStructuredContentProvider contentProvider, - ILabelProvider labelProvider) { - listViewer.setContentProvider(contentProvider); - listViewer.setLabelProvider(labelProvider); - } - - /** - * Set the comparator that is to be applied to self's list viewer - * - * @param comparator the sorter for the list - */ - public void setListComparator(ViewerComparator comparator) { - listViewer.setComparator(comparator); - } - - /** - * Set the root of the widget to be new Root. Regenerate all of the tables and lists from this - * value. - * @param newRoot - */ - public void setRoot(Object newRoot) { - this.root = newRoot; - initialize(); - } - - /** - * Set the checked state of the passed tree element appropriately, and - * do so recursively to all of its child tree elements as well - */ - protected void setTreeChecked(Object treeElement, boolean state) { - - if (treeElement.equals(currentTreeSelection)) { - listViewer.setAllChecked(state); - } - - if (state) { - setListForWhiteSelection(treeElement); - } else { - checkedStateStore.remove(treeElement); - } - - setWhiteChecked(treeElement, state); - treeViewer.setChecked(treeElement, state); - treeViewer.setGrayed(treeElement, false); - - // now logically check/uncheck all children as well if it has been expanded - if (expandedTreeNodes.contains(treeElement)) { - Object[] children = treeContentProvider.getChildren(treeElement); - for (int i = 0; i < children.length; ++i) { - setTreeChecked(children[i], state); - } - } - } - - /** - * Set the tree viewer's providers to those passed - * - * @param contentProvider ITreeContentProvider - * @param labelProvider ILabelProvider - */ - public void setTreeProviders(ITreeContentProvider contentProvider, - ILabelProvider labelProvider) { - treeViewer.setContentProvider(contentProvider); - treeViewer.setLabelProvider(labelProvider); - } - - /** - * Set the comparator that is to be applied to self's tree viewer - * - * @param comparator the comparator for the tree - */ - public void setTreeComparator(ViewerComparator comparator) { - treeViewer.setComparator(comparator); - } - - /** - * Adjust the collection of references to white-checked tree elements appropriately. - * - * @param treeElement java.lang.Object - * @param isWhiteChecked boolean - */ - protected void setWhiteChecked(Object treeElement, boolean isWhiteChecked) { - if (isWhiteChecked) { - if (!whiteCheckedTreeItems.contains(treeElement)) { - whiteCheckedTreeItems.add(treeElement); - } - } else { - whiteCheckedTreeItems.remove(treeElement); - } - } - - /** - * Handle the collapsing of an element in a tree viewer - */ - @Override - public void treeCollapsed(TreeExpansionEvent event) { - // We don't need to do anything with this - } - - /** - * Handle the expansionsion of an element in a tree viewer - */ - @Override - public void treeExpanded(TreeExpansionEvent event) { - expandTreeElement(event.getElement()); - } - - /** - * Callback that's invoked when the checked status of an item in the tree - * is changed by the user. - */ - protected void treeItemChecked(Object treeElement, boolean state) { - - // recursively adjust all child tree elements appropriately - setTreeChecked(treeElement, state); - - Object parent = treeContentProvider.getParent(treeElement); - - // workspace root is not shown in the tree, so ignore it - if (parent == null || parent instanceof IWorkspaceRoot) { - return; - } - - // now update upwards in the tree hierarchy - if (state) { - grayCheckHierarchy(parent); - } else { - ungrayCheckHierarchy(parent); - } - - //Update the hierarchy but do not white select the parent - grayUpdateHierarchy(parent); - } - - /** - * Logically un-gray-check all ancestors of treeItem iff appropriate. - */ - protected void ungrayCheckHierarchy(Object treeElement) { - if (!determineShouldBeAtLeastGrayChecked(treeElement)) { - checkedStateStore.remove(treeElement); - } - - Object parent = treeContentProvider.getParent(treeElement); - if (parent != null) { - ungrayCheckHierarchy(parent); - } - } - - /** - * Set the checked state of self and all ancestors appropriately - */ - protected void updateHierarchy(Object treeElement) { - - boolean whiteChecked = determineShouldBeWhiteChecked(treeElement); - boolean shouldBeAtLeastGray = determineShouldBeAtLeastGrayChecked(treeElement); - - treeViewer.setChecked(treeElement, shouldBeAtLeastGray); - setWhiteChecked(treeElement, whiteChecked); - if (whiteChecked) { - treeViewer.setGrayed(treeElement, false); - } else { - treeViewer.setGrayed(treeElement, shouldBeAtLeastGray); - } - - // proceed up the tree element hierarchy but gray select all of them - Object parent = treeContentProvider.getParent(treeElement); - if (parent != null) { - grayUpdateHierarchy(parent); - } - } - - /** - * Update the selections of the tree elements in items to reflect the new - * selections provided. - * @param items Map with keys of Object (the tree element) and values of List (the selected - * list elements). - * NOTE: This method does not special case keys with no values (i.e., - * a tree element with an empty list). If a tree element does not have any selected - * items, do not include the element in the Map. - */ - public void updateSelections(Map items) { - // We are replacing all selected items with the given selected items, - // so reinitialize everything. - this.listViewer.setAllChecked(false); - this.treeViewer.setCheckedElements(new Object[0]); - this.whiteCheckedTreeItems = new HashSet(); - Set selectedNodes = new HashSet(); - checkedStateStore = new HashMap(); - - //Update the store before the hierarchy to prevent updating parents before all of the children are done - Iterator keyIterator = items.keySet().iterator(); - while (keyIterator.hasNext()) { - Object key = keyIterator.next(); - List selections = (List) items.get(key); - //Replace the items in the checked state store with those from the supplied items - checkedStateStore.put(key, selections); - selectedNodes.add(key); - // proceed up the tree element hierarchy - Object parent = treeContentProvider.getParent(key); - if (parent != null) { - // proceed up the tree element hierarchy and make sure everything is in the table - primeHierarchyForSelection(parent, selectedNodes); - } - } - - // Update the checked tree items. Since each tree item has a selected - // item, all the tree items will be gray checked. - treeViewer.setCheckedElements(checkedStateStore.keySet().toArray()); - treeViewer.setGrayedElements(checkedStateStore.keySet().toArray()); - - // Update the listView of the currently selected tree item. - if (currentTreeSelection != null) { - Object displayItems = items.get(currentTreeSelection); - if (displayItems != null) { - listViewer.setCheckedElements(((List) displayItems).toArray()); - } - } - } - - /** - * Set the focus on to the list widget. - */ - public void setFocus() { - - treeViewer.getTree().setFocus(); - if(treeViewer.getSelection().isEmpty()) { - Object[] elements = treeContentProvider.getElements(root); - if(elements.length > 0) { - StructuredSelection selection = new StructuredSelection(elements[0]); - treeViewer.setSelection(selection); - } - } - - } - -} - diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/TraceTypeContentProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/TraceTypeContentProvider.java deleted file mode 100644 index d52e43511d..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/TraceTypeContentProvider.java +++ /dev/null @@ -1,101 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; - -/** - * Trace type content provider, a helper for showing trace types - * - * @author Matthew Khouzam - * @since 2.0 - */ -public class TraceTypeContentProvider implements ITreeContentProvider { - - private final List fTraceCategory = new ArrayList<>(); - private final Map> fTraceType = new HashMap<>(); - - /** - * Default Constructor - */ - public TraceTypeContentProvider() { - fTraceType.clear(); - fTraceCategory.clear(); - - for (String category : TmfTraceType.getTraceCategories()) { - List value = TmfTraceType.getTraceTypes(category); - if (!value.isEmpty()) { - fTraceCategory.add(category); - fTraceType.put(category, value); - } - } - } - - @Override - public void dispose() { - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - // Do nothing - } - - @Override - public Object[] getElements(Object inputElement) { - return fTraceCategory.toArray(new String[0]); - } - - @Override - public Object[] getChildren(Object parentElement) { - if (parentElement instanceof String) { - final List children = fTraceType.get(parentElement); - if (children != null) { - return children.toArray(new TraceTypeHelper[0]); - } - } - return null; - } - - @Override - public Object getParent(Object element) { - if (element instanceof TraceTypeHelper) { - for (String key : fTraceCategory) { - List traceSet = fTraceType.get(key); - if (traceSet != null) { - if (traceSet.contains(element)) { - return key; - } - } - } - } - return null; - } - - @Override - public boolean hasChildren(Object element) { - if (element instanceof String) { - String key = (String) element; - return fTraceType.containsKey(key); - } - return false; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/messages.properties deleted file mode 100644 index f3fdaf8e0c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/messages.properties +++ /dev/null @@ -1,81 +0,0 @@ -############################################################################### -# Copyright (c) 2013, 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### - -# ImportTraceWizard -ImportTraceWizard_DialogTitle=Trace Import -ImportTraceWizard_FileSystemTitle=File system -ImportTraceWizard_ImportTrace=Import a trace from the local file system -ImportTraceWizard_DirectoryLocation=Select roo&t directory: -ImportTraceWizard_ArchiveLocation=Select &archive file: -ImportTraceWizard_BrowseButton=B&rowse... -ImportTraceWizard_TraceType=Trace Type: -ImportTraceWizard_SelectTraceDirectoryTitle=Select trace directory -ImportTraceWizard_SelectTraceArchiveTitle=Select trace archive file -ImportTraceWizard_SelectTraceDirectoryMessage=Select directory to import trace from -ImportTraceWizard_OverwriteExistingTrace=Overwrite existing trace without warning -ImportTraceWizard_CreateLinksInWorkspace=Create lin&ks in workspace -ImportTraceWizard_PreserveFolderStructure=Preserve &folder structure -ImportTraceWizard_TraceValidationFailed=Validation failed for trace resource {0} -ImportTraceWizard_TraceAlreadyExists=Trace with name "{0}" already exists in project. Do you want to rename, overwrite or skip? -ImportTraceWizard_ImportConfigurationRename=Rename -ImportTraceWizard_ImportConfigurationRenameAll=Rename All -ImportTraceWizard_ImportConfigurationOverwrite=Overwrite -ImportTraceWizard_ImportConfigurationOverwriteAll=Overwrite All -ImportTraceWizard_ImportConfigurationSkip=Skip -ImportTraceWizard_ImportConfigurationSkipAll=Skip All -ImportTraceWizard_InvalidTraceDirectory=Invalid trace directory -ImportTraceWizard_SelectTraceSourceEmpty=Source must not be empty -ImportTraceWizard_BadArchiveFormat=Source file is not a valid tar or zip file. -ImportTraceWizard_SelectTraceNoneSelected=No trace selected -ImportTraceWizard_ImportProblem=Import problem -ImportTraceWizard_CannotImportFilesUnderAVirtualFolder=Can not import trace under a virtual folder -ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder=Have to create link under a virtual folder -ImportTraceWizard_Information=Information -ImportTraceWizard_ImportUnrecognized=Import unrecognized traces -ImportTraceWizard_ImportOperationCancelled=Import operation cancelled -ImportTraceWizard_TraceTypeNotFound=No trace type helper found -ImportTraceWizard_ImportOperationTaskName=Importing -ImportTraceWizard_ExtractImportOperationTaskName=Extracting files -ImportTraceWizard_AutoDetection= - -# BatchImportTraceWizard -ImportTraceWizardImportCaption=Trace to import -ImportTraceWizardTraceDisplayName=Trace display name -ImportTraceWizardLinkTraces=Link traces (Recommended) -ImportTraceWizardCopyTraces=Copy traces -ImportTraceWizardOverwriteTraces=Overwrite existing traces (recommended) -ImportTraceWizardAddFile=Add File... -ImportTraceWizardAddDirectory=Add Directory... -ImportTraceWizardRemove=Remove -ImportTraceWizardDirectoryTitle=Pick directories and files to scan -ImportTraceWizardDirectoryHint=Select at least one file or directory to scan -ImportTraceWizardScanPagebyte=\ B -ImportTraceWizardScanPageGigabyte=\ GB -ImportTraceWizardScanPageKilobyte=\ KB -ImportTraceWizardScanPageMegabyte=\ MB -ImportTraceWizardScanPageRenameError=Each selected trace must have a unique name, please rename. -ImportTraceWizardScanPageSelectAtleastOne=Select at least one trace to import -ImportTraceWizardScanPageSize=Size -ImportTraceWizardSelectAll=Select All -ImportTraceWizardScanPageTerabyte=\ TB -ImportTraceWizardScanPageTitle=Valid traces -ImportTraceWizardSelectTraceTypePageTitle=Available trace types -ImportTraceWizardPageOptionsTitle=Select Target Project -ImportTraceWizardPageScanDone=Done\! -ImportTraceWizardPageScanScanning=Scanning: -ImportTraceWizardPageSelectNone=Deselect All -ImportTraceWizardPageSelectHint=Select at least one trace type -BatchImportTraceWizardRemove=Removing -BatchImportTraceWizardAdd=Adding -BatchImportTraceWizardErrorImportingTraceResource=Error importing trace resource -ImportTraceWizardImportProblem=Error -SharedSelectProject=Select a project to import to diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/AbstractTracePackageOperation.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/AbstractTracePackageOperation.java deleted file mode 100644 index e440aa7dc3..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/AbstractTracePackageOperation.java +++ /dev/null @@ -1,369 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Enumeration; -import java.util.Vector; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.ui.internal.wizards.datatransfer.TarEntry; -import org.eclipse.ui.internal.wizards.datatransfer.TarException; -import org.eclipse.ui.internal.wizards.datatransfer.TarFile; - -/** - * An abstract operation containing common code useful for other trace package - * operations - * - * @author Marc-Andre Laperle - */ -@SuppressWarnings("restriction") -abstract public class AbstractTracePackageOperation { - private IStatus fStatus; - // Result of this operation, if any - private TracePackageElement[] fResultElements; - - private final String fFileName; - - /** - * Constructs a new trace package operation - * - * @param fileName - * the output file name - */ - public AbstractTracePackageOperation(String fileName) { - fFileName = fileName; - } - - /** - * Run the operation. The status (result) of the operation can be obtained - * with {@link #getStatus} - * - * @param progressMonitor - * the progress monitor to use to display progress and receive - * requests for cancellation - */ - public abstract void run(IProgressMonitor progressMonitor); - - /** - * Returns the status of the operation (result) - * - * @return the status of the operation - */ - public IStatus getStatus() { - return fStatus; - } - - /** - * Get the resulting elements for this operation, if any - * - * @return the resulting elements or null if no result is produced by this - * operation - */ - public TracePackageElement[] getResultElements() { - return fResultElements; - } - - /** - * Set the resulting elements for this operation, if any - * - * @param elements - * the resulting elements produced by this operation, can be set - * to null - */ - public void setResultElements(TracePackageElement[] elements) { - fResultElements = elements; - } - - /** - * Set the status for this operation - * - * @param status - * the status - */ - protected void setStatus(IStatus status) { - fStatus = status; - } - - /** - * Get the file name of the package - * - * @return the file name - */ - protected String getFileName() { - return fFileName; - } - - /** - * Answer a handle to the archive file currently specified as being the - * source. Return null if this file does not exist or is not of valid - * format. - * - * @return the archive file - */ - public ArchiveFile getSpecifiedArchiveFile() { - if (fFileName.length() == 0) { - return null; - } - - try { - return new ZipArchiveFile(new ZipFile(fFileName)); - } catch (IOException e) { - // ignore - } - - try { - return new TarArchiveFile(new TarFile(fFileName)); - } catch (TarException | IOException e) { - // ignore - } - - return null; - } - - /** - * Get the number of checked elements in the array and the children - * - * @param elements - * the elements to check for checked - * @return the number of checked elements - */ - protected int getNbCheckedElements(TracePackageElement[] elements) { - int totalWork = 0; - for (TracePackageElement tracePackageElement : elements) { - TracePackageElement[] children = tracePackageElement.getChildren(); - if (children != null && children.length > 0) { - totalWork += getNbCheckedElements(children); - } else if (tracePackageElement.isChecked()) { - ++totalWork; - } - } - - return totalWork; - } - - /** - * Returns whether or not the Files element is checked under the given trace - * package element - * - * @param tracePackageElement - * the trace package element - * @return whether or not the Files element is checked under the given trace - * package element - */ - public static boolean isFilesChecked(TracePackageElement tracePackageElement) { - for (TracePackageElement element : tracePackageElement.getChildren()) { - if (element instanceof TracePackageFilesElement) { - return element.isChecked(); - } - } - - return false; - } - - /** - * Common interface between ZipEntry and TarEntry - */ - protected interface ArchiveEntry { - /** - * The name of the entry - * - * @return The name of the entry - */ - String getName(); - } - - /** - * Common interface between ZipFile and TarFile - */ - protected interface ArchiveFile { - /** - * Returns an enumeration cataloging the archive. - * - * @return enumeration of all files in the archive - */ - Enumeration entries(); - - /** - * Close the file input stream. - * - * @throws IOException - */ - void close() throws IOException; - - /** - * Returns a new InputStream for the given file in the archive. - * - * @param entry - * the given file - * @return an input stream for the given file - * @throws TarException - * @throws IOException - */ - InputStream getInputStream(ArchiveEntry entry) throws TarException, IOException; - } - - /** - * Adapter for TarFile to ArchiveFile - */ - protected class TarArchiveFile implements ArchiveFile { - - private TarFile fTarFile; - - /** - * Constructs a TarAchiveFile for a TarFile - * - * @param tarFile - * the TarFile - */ - public TarArchiveFile(TarFile tarFile) { - this.fTarFile = tarFile; - } - - @Override - public Enumeration entries() { - Vector v = new Vector<>(); - for (Enumeration e = fTarFile.entries(); e.hasMoreElements();) { - v.add(new TarArchiveEntry((TarEntry) e.nextElement())); - } - - return v.elements(); - } - - @Override - public void close() throws IOException { - fTarFile.close(); - } - - @Override - public InputStream getInputStream(ArchiveEntry entry) throws TarException, IOException { - return fTarFile.getInputStream(((TarArchiveEntry) entry).getTarEntry()); - } - } - - /** - * Adapter for TarEntry to ArchiveEntry - */ - protected class TarArchiveEntry implements ArchiveEntry { - private TarEntry fTarEntry; - - /** - * Constructs a TarArchiveEntry for a TarEntry - * - * @param tarEntry - * the TarEntry - */ - public TarArchiveEntry(TarEntry tarEntry) { - this.fTarEntry = tarEntry; - } - - @Override - public String getName() { - return fTarEntry.getName(); - } - - /** - * Get the corresponding TarEntry - * - * @return the corresponding TarEntry - */ - public TarEntry getTarEntry() { - return fTarEntry; - } - - @Override - public String toString() { - return getName(); - } - } - - /** - * Adapter for ArchiveEntry to ArchiveEntry - */ - protected class ZipAchiveEntry implements ArchiveEntry { - - private ZipEntry fZipEntry; - - /** - * Constructs a ZipAchiveEntry for a ZipEntry - * - * @param zipEntry - * the ZipEntry - */ - public ZipAchiveEntry(ZipEntry zipEntry) { - this.fZipEntry = zipEntry; - } - - @Override - public String getName() { - return fZipEntry.getName(); - } - - /** - * Get the corresponding ZipEntry - * - * @return the corresponding ZipEntry - */ - public ZipEntry getZipEntry() { - return fZipEntry; - } - - @Override - public String toString() { - return getName(); - } - } - - /** - * Adapter for ZipFile to ArchiveFile - */ - protected class ZipArchiveFile implements ArchiveFile { - - private ZipFile fZipFile; - - /** - * Constructs a ZipArchiveFile for a ZipFile - * - * @param zipFile - * the ZipFile - */ - public ZipArchiveFile(ZipFile zipFile) { - this.fZipFile = zipFile; - } - - @Override - public Enumeration entries() { - Vector v = new Vector<>(); - for (Enumeration e = fZipFile.entries(); e.hasMoreElements();) { - v.add(new ZipAchiveEntry((ZipEntry) e.nextElement())); - } - - return v.elements(); - } - - @Override - public void close() throws IOException { - fZipFile.close(); - } - - @Override - public InputStream getInputStream(ArchiveEntry entry) throws TarException, IOException { - return fZipFile.getInputStream(((ZipAchiveEntry) entry).getZipEntry()); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/AbstractTracePackageWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/AbstractTracePackageWizardPage.java deleted file mode 100644 index c30d201e85..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/AbstractTracePackageWizardPage.java +++ /dev/null @@ -1,565 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.CheckStateChangedEvent; -import org.eclipse.jface.viewers.CheckboxTreeViewer; -import org.eclipse.jface.viewers.ICheckStateListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.TreeItem; - -/** - * An abstract wizard page containing common code useful for both import and - * export trace package wizard pages - * - * @author Marc-Andre Laperle - */ -abstract public class AbstractTracePackageWizardPage extends WizardPage { - - private static final int COMBO_HISTORY_LENGTH = 5; - private static final String STORE_FILE_PATHS_ID = ".STORE_FILEPATHS_ID"; //$NON-NLS-1$ - - private final String fStoreFilePathId; - private final IStructuredSelection fSelection; - - private CheckboxTreeViewer fElementViewer; - private Button fSelectAllButton; - private Button fDeselectAllButton; - private Combo fFilePathCombo; - private Button fBrowseButton; - - /** - * Create the trace package wizard page - * - * @param pageName - * the name of the page - * @param title - * the title for this wizard page, or null if none - * @param titleImage - * the image descriptor for the title of this wizard page, or - * null if none - * @param selection - * the current object selection - */ - protected AbstractTracePackageWizardPage(String pageName, String title, ImageDescriptor titleImage, IStructuredSelection selection) { - super(pageName, title, titleImage); - fStoreFilePathId = getName() + STORE_FILE_PATHS_ID; - fSelection = selection; - } - - /** - * Create the element viewer - * - * @param compositeParent - * the parent composite - */ - protected void createElementViewer(Composite compositeParent) { - fElementViewer = new CheckboxTreeViewer(compositeParent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.CHECK); - - fElementViewer.addCheckStateListener(new ICheckStateListener() { - @Override - public void checkStateChanged(CheckStateChangedEvent event) { - TracePackageElement element = (TracePackageElement) event.getElement(); - if (!element.isEnabled()) { - fElementViewer.setChecked(element, element.isChecked()); - } else { - setSubtreeChecked(fElementViewer, element, true, event.getChecked()); - } - maintainCheckIntegrity(element); - - if (element.getParent() != null) { - // Uncheck everything in this trace if Trace files are unchecked - if (element instanceof TracePackageFilesElement) { - if (!element.isChecked()) { - setSubtreeChecked(fElementViewer, element.getParent(), false, false); - } - // Check Trace files if anything else is selected - } else if (element.isChecked()) { - TracePackageElement parent = element.getParent(); - while (parent != null) { - for (TracePackageElement e : parent.getChildren()) { - if (e instanceof TracePackageFilesElement) { - setSubtreeChecked(fElementViewer, e, false, true); - break; - } - } - parent = parent.getParent(); - } - } - } - - - updateApproximateSelectedSize(); - updatePageCompletion(); - } - - private void maintainCheckIntegrity(final TracePackageElement element) { - TracePackageElement parentElement = element.getParent(); - boolean allChecked = true; - boolean oneChecked = false; - if (parentElement != null) { - if (parentElement.getChildren() != null) { - for (TracePackageElement child : parentElement.getChildren()) { - boolean checked = fElementViewer.getChecked(child) && !fElementViewer.getGrayed(child); - oneChecked |= checked; - allChecked &= checked; - } - } - if (oneChecked && !allChecked) { - fElementViewer.setGrayChecked(parentElement, true); - } else { - fElementViewer.setGrayed(parentElement, false); - fElementViewer.setChecked(parentElement, allChecked); - } - maintainCheckIntegrity(parentElement); - } - } - }); - GridData layoutData = new GridData(GridData.FILL_BOTH); - fElementViewer.getTree().setLayoutData(layoutData); - fElementViewer.setContentProvider(new TracePackageContentProvider()); - fElementViewer.setLabelProvider(new TracePackageLabelProvider()); - } - - /** - * Create the input for the element viewer - * - * @return the input for the element viewer - */ - protected abstract Object createElementViewerInput(); - - /** - * Create the file path group that allows the user to type or browse for a - * file path - * - * @param parent - * the parent composite - * @param label - * the label to describe the file path (i.e. import/export) - * @param fileDialogStyle - * SWT.OPEN or SWT.SAVE - */ - protected void createFilePathGroup(Composite parent, String label, final int fileDialogStyle) { - - Composite filePathSelectionGroup = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.numColumns = 3; - filePathSelectionGroup.setLayout(layout); - filePathSelectionGroup.setLayoutData(new GridData( - GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL)); - - Label destinationLabel = new Label(filePathSelectionGroup, SWT.NONE); - destinationLabel.setText(label); - - fFilePathCombo = new Combo(filePathSelectionGroup, SWT.SINGLE - | SWT.BORDER); - GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL - | GridData.GRAB_HORIZONTAL); - data.grabExcessHorizontalSpace = true; - fFilePathCombo.setLayoutData(data); - - fBrowseButton = new Button(filePathSelectionGroup, - SWT.PUSH); - fBrowseButton.setText(org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_Browse); - fBrowseButton.addListener(SWT.Selection, new Listener() { - @Override - public void handleEvent(Event event) { - handleFilePathBrowseButtonPressed(fileDialogStyle); - } - }); - setButtonLayoutData(fBrowseButton); - } - - /** - * Update the page with the file path the current file path selection - */ - abstract protected void updateWithFilePathSelection(); - - /** - * Creates the buttons for selecting all or none of the elements. - * - * @param parent - * the parent control - * @return the button group - */ - protected Composite createButtonsGroup(Composite parent) { - - // top level group - Composite buttonComposite = new Composite(parent, SWT.NONE); - - GridLayout layout = new GridLayout(); - layout.numColumns = 3; - buttonComposite.setLayout(layout); - buttonComposite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL - | GridData.HORIZONTAL_ALIGN_FILL)); - - fSelectAllButton = new Button(buttonComposite, SWT.PUSH); - fSelectAllButton.setText(org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_SelectAll); - - SelectionListener listener = new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - setAllChecked(fElementViewer, true, true); - updateApproximateSelectedSize(); - updatePageCompletion(); - } - }; - fSelectAllButton.addSelectionListener(listener); - - fDeselectAllButton = new Button(buttonComposite, SWT.PUSH); - fDeselectAllButton.setText(org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_DeselectAll); - - listener = new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - setAllChecked(fElementViewer, true, false); - updateApproximateSelectedSize(); - updatePageCompletion(); - } - }; - fDeselectAllButton.addSelectionListener(listener); - - return buttonComposite; - } - - /** - * Restore widget values to the values that they held last time this wizard - * was used to completion. - */ - protected void restoreWidgetValues() { - IDialogSettings settings = getDialogSettings(); - if (settings != null) { - String[] directoryNames = settings.getArray(fStoreFilePathId); - if (directoryNames == null || directoryNames.length == 0) { - return; - } - - for (int i = 0; i < directoryNames.length; i++) { - fFilePathCombo.add(directoryNames[i]); - } - } - } - - /** - * Save widget values to Dialog settings - */ - protected void saveWidgetValues() { - IDialogSettings settings = getDialogSettings(); - if (settings != null) { - // update directory names history - String[] directoryNames = settings.getArray(fStoreFilePathId); - if (directoryNames == null) { - directoryNames = new String[0]; - } - - directoryNames = addToHistory(directoryNames, getFilePathValue()); - settings.put(fStoreFilePathId, directoryNames); - } - } - - /** - * Determine if the page is complete and update the page appropriately. - */ - protected void updatePageCompletion() { - boolean pageComplete = determinePageCompletion(); - setPageComplete(pageComplete); - if (pageComplete) { - setErrorMessage(null); - } - } - - /** - * Determine if the page is completed or not - * - * @return true if the page is completed, false otherwise - */ - protected boolean determinePageCompletion() { - return fElementViewer.getCheckedElements().length > 0 && !getFilePathValue().isEmpty(); - } - - /** - * Handle error status - * - * @param status - * the error status - */ - protected void handleErrorStatus(IStatus status) { - - Throwable exception = status.getException(); - String message = status.getMessage().length() > 0 ? status.getMessage() : org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation; - - if (!status.isMultiStatus()) { - handleError(message, exception); - return; - } - - // Build a string with all the children status messages, exception - // messages and stack traces - StringBuilder sb = new StringBuilder(); - for (IStatus childStatus : status.getChildren()) { - StringBuilder childSb = new StringBuilder(); - if (!childStatus.getMessage().isEmpty()) { - childSb.append(childStatus.getMessage() + '\n'); - } - - Throwable childException = childStatus.getException(); - if (childException != null) { - String reason = childException.getMessage(); - // Some system exceptions have no message - if (reason == null) { - reason = childException.toString(); - } - - String stackMessage = getExceptionStackMessage(childException); - if (stackMessage == null) { - stackMessage = reason; - } - - childSb.append(stackMessage); - } - - if (childSb.length() > 0) { - childSb.insert(0, '\n'); - sb.append(childSb.toString()); - } - } - - // ErrorDialog only prints the call stack for a CoreException - exception = new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, sb.toString(), null)); - final Status statusWithException = new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorMultipleProblems, exception); - - Activator.getDefault().logError(message, exception); - ErrorDialog.openError(getContainer().getShell(), org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_InternalErrorTitle, message, statusWithException); - } - - /** - * Handle errors occurring in the wizard operations - * - * @param message - * the error message - * @param exception - * the exception attached to the message - */ - protected void handleError(String message, Throwable exception) { - Activator.getDefault().logError(message, exception); - displayErrorDialog(message, exception); - } - - private static String getExceptionStackMessage(Throwable exception) { - String stackMessage = null; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - PrintStream ps = new PrintStream(baos); - exception.printStackTrace(ps); - ps.flush(); - try { - baos.flush(); - stackMessage = baos.toString(); - } catch (IOException e) { - } - - return stackMessage; - } - - private void displayErrorDialog(String message, Throwable exception) { - if (exception == null) { - final Status s = new Status(IStatus.ERROR, Activator.PLUGIN_ID, message); - ErrorDialog.openError(getContainer().getShell(), org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_InternalErrorTitle, null, s); - return; - } - - String reason = exception.getMessage(); - // Some system exceptions have no message - if (reason == null) { - reason = exception.toString(); - } - - String stackMessage = getExceptionStackMessage(exception); - if (stackMessage == null || stackMessage.isEmpty()) { - stackMessage = reason; - } - - // ErrorDialog only prints the call stack for a CoreException - CoreException coreException = new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, stackMessage, exception)); - final Status s = new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, reason, coreException); - ErrorDialog.openError(getContainer().getShell(), org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_InternalErrorTitle, message, s); - } - - /** - * A version of setSubtreeChecked that is aware of isEnabled - * - * @param viewer - * the viewer - * @param element - * the element - * @param enabledOnly - * if only enabled elements should be considered - * @param checked - * true if the item should be checked, and false if it should be - * unchecked - */ - protected static void setSubtreeChecked(CheckboxTreeViewer viewer, TracePackageElement element, boolean enabledOnly, boolean checked) { - if (!enabledOnly || element.isEnabled()) { - viewer.setChecked(element, checked); - if (checked) { - viewer.setGrayed(element, false); - } - element.setChecked(checked); - if (element.getChildren() != null) { - for (TracePackageElement child : element.getChildren()) { - setSubtreeChecked(viewer, child, enabledOnly, checked); - } - } - } - } - - /** - * Sets all items in the element viewer to be checked or unchecked - * - * @param viewer - * the viewer - * @param enabledOnly - * if only enabled elements should be considered - * @param checked - * whether or not items should be checked - */ - protected static void setAllChecked(CheckboxTreeViewer viewer, boolean enabledOnly, boolean checked) { - TreeItem[] items = viewer.getTree().getItems(); - for (int i = 0; i < items.length; i++) { - Object element = items[i].getData(); - setSubtreeChecked(viewer, (TracePackageElement) element, enabledOnly, checked); - } - } - - private static void addToHistory(List history, String newEntry) { - history.remove(newEntry); - history.add(0, newEntry); - - // since only one new item was added, we can be over the limit - // by at most one item - if (history.size() > COMBO_HISTORY_LENGTH) { - history.remove(COMBO_HISTORY_LENGTH); - } - } - - private static String[] addToHistory(String[] history, String newEntry) { - ArrayList l = new ArrayList<>(Arrays.asList(history)); - addToHistory(l, newEntry); - String[] r = new String[l.size()]; - l.toArray(r); - return r; - } - - /** - * Open an appropriate file dialog so that the user can specify a file to - * import/export - * @param fileDialogStyle - */ - private void handleFilePathBrowseButtonPressed(int fileDialogStyle) { - FileDialog dialog = new FileDialog(getContainer().getShell(), fileDialogStyle | SWT.SHEET); - dialog.setFilterExtensions(new String[] { "*.zip;*.tar.gz;*.tar;*.tgz", "*.*" }); //$NON-NLS-1$ //$NON-NLS-2$ - dialog.setText(Messages.TracePackage_FileDialogTitle); - String currentSourceString = getFilePathValue(); - int lastSeparatorIndex = currentSourceString.lastIndexOf(File.separator); - if (lastSeparatorIndex != -1) { - dialog.setFilterPath(currentSourceString.substring(0, lastSeparatorIndex)); - } - String selectedFileName = dialog.open(); - - if (selectedFileName != null) { - setFilePathValue(selectedFileName); - updateWithFilePathSelection(); - } - } - - /** - * Get the current file path value - * - * @return the current file path value - */ - protected String getFilePathValue() { - return fFilePathCombo.getText().trim(); - } - - /** - * Set the file path value - * - * @param value - * file path value - */ - protected void setFilePathValue(String value) { - fFilePathCombo.setText(value); - updatePageCompletion(); - } - - /** - * Update the approximate size of the selected elements - */ - protected void updateApproximateSelectedSize() { - } - - /** - * Get the element tree viewer - * - * @return the element tree viewer - */ - protected CheckboxTreeViewer getElementViewer() { - return fElementViewer; - } - - /** - * Get the file path combo box - * - * @return the file path combo box - */ - protected Combo getFilePathCombo() { - return fFilePathCombo; - } - - /** - * Get the object selection when the wizard was created - * - * @return the object selection - */ - protected IStructuredSelection getSelection() { - return fSelection; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/ITracePackageConstants.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/ITracePackageConstants.java deleted file mode 100644 index 640a6c6ec2..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/ITracePackageConstants.java +++ /dev/null @@ -1,76 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg; - -/** - * Constants used in the trace package (XML attribute and element names, etc). - * - * @author Marc-Andre Laperle - */ -public interface ITracePackageConstants { - - /** - * The file name for the package manifest file - */ - public static final String MANIFEST_FILENAME = "export-manifest.xml"; //$NON-NLS-1$ - - /** - * The root element of an export - */ - public static final String TMF_EXPORT_ELEMENT = "tmf-export"; //$NON-NLS-1$ - - /** - * Element representing a single trace - */ - public static final String TRACE_ELEMENT = "trace"; //$NON-NLS-1$ - - /** - * Attribute for the name of a trace - */ - public static final String TRACE_NAME_ATTRIB = "name"; //$NON-NLS-1$ - - /** - * Attribute for the type of a trace - */ - public static final String TRACE_TYPE_ATTRIB = "type"; //$NON-NLS-1$ - - /** - * Element representing a single supplementary file - */ - public static final String SUPPLEMENTARY_FILE_ELEMENT = "supplementary-file"; //$NON-NLS-1$ - - /** - * Attribute for the name of a supplementary file - */ - public static final String SUPPLEMENTARY_FILE_NAME_ATTRIB = "name"; //$NON-NLS-1$ - - /** - * Element representing a trace file or folder - */ - public static final String TRACE_FILE_ELEMENT = "file"; //$NON-NLS-1$ - - /** - * Attribute for the name of the file - */ - public static final String TRACE_FILE_NAME_ATTRIB = "name"; //$NON-NLS-1$ - - /** - * Element representing the bookmarks of a trace - */ - public static final String BOOKMARKS_ELEMENT = "bookmarks"; //$NON-NLS-1$ - - /** - * Element representing a single bookmark of a trace - */ - public static final String BOOKMARK_ELEMENT = "bookmark"; //$NON-NLS-1$ -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/Messages.java deleted file mode 100644 index 452b32cd28..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/Messages.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg; - -import org.eclipse.osgi.util.NLS; - -/** - * Messages common to trace package operations - * - * @author Marc-Andre Laperle - */ -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.messages"; //$NON-NLS-1$ - - /** - * Text for supplementary files in the element viewer - */ - public static String TracePackage_SupplementaryFiles; - - /** - * Text for trace in the element viewer - */ - public static String TracePackage_TraceElement; - - /** - * Text for bookmarks in the element viewer - */ - public static String TracePackage_Bookmarks; - - /** - * Text for browse button in the wizard pages - */ - public static String TracePackage_Browse; - - /** - * Title for the file dialog - */ - public static String TracePackage_FileDialogTitle; - - /** - * Text for browse select all button in the wizard pages - */ - public static String TracePackage_SelectAll; - - /** - * Text for browse deselect all button in the wizard pages - */ - public static String TracePackage_DeselectAll; - - /** - * Generic error message for wizard operations - */ - public static String TracePackage_ErrorOperation; - - /** - * Generic error when multiple problems occur (MultiStatus) - */ - public static String TracePackage_ErrorMultipleProblems; - - /** - * Generic dialog message for error in wizard operations - */ - public static String TracePackage_InternalErrorTitle; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageBookmarkElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageBookmarkElement.java deleted file mode 100644 index 65c374524d..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageBookmarkElement.java +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg; - -import java.util.List; -import java.util.Map; - -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.swt.graphics.Image; - -/** - * A trace package element representing the bookmarks of a trace - * - * @author Marc-Andre Laperle - */ -public class TracePackageBookmarkElement extends TracePackageElement { - private static final String BOOKMARK_IMAGE_PATH = "icons/elcl16/bookmark_obj.gif"; //$NON-NLS-1$ - private final List> bookmarkAttribs; - - /** - * Construct a bookmark element containing all the bookmarks - * - * @param parent - * the parent node - * @param bookmarkAttribs - * the bookmarks for the trace - */ - public TracePackageBookmarkElement(TracePackageElement parent, List> bookmarkAttribs) { - super(parent); - this.bookmarkAttribs = bookmarkAttribs; - } - - @Override - public long getSize(boolean checkedOnly) { - return 0; - } - - @Override - public String getText() { - return Messages.TracePackage_Bookmarks; - } - - @Override - public Image getImage() { - return Activator.getDefault().getImageFromImageRegistry(BOOKMARK_IMAGE_PATH); - } - - /** - * Get all the bookmarks - * - * @return the bookmarks - */ - public List> getBookmarks() { - return bookmarkAttribs; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageContentProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageContentProvider.java deleted file mode 100644 index b71ff33004..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageContentProvider.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg; - -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; - -/** - * A content provider to display the content of a trace package in a tree - * - * @author Marc-Andre Laperle - */ -public class TracePackageContentProvider implements ITreeContentProvider { - - @Override - public void dispose() { - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - @Override - public Object[] getElements(Object inputElement) { - if (inputElement instanceof TracePackageElement[]) { - return (TracePackageElement[]) inputElement; - } - return null; - } - - @Override - public Object[] getChildren(Object parentElement) { - return ((TracePackageElement) parentElement).getVisibleChildren(); - } - - @Override - public Object getParent(Object element) { - return ((TracePackageElement) element).getParent(); - } - - @Override - public boolean hasChildren(Object element) { - TracePackageElement traceTransferElement = (TracePackageElement) element; - TracePackageElement[] visibleChildren = traceTransferElement.getVisibleChildren(); - return visibleChildren != null && visibleChildren.length > 0; - } - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageElement.java deleted file mode 100644 index 4792f2e962..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageElement.java +++ /dev/null @@ -1,179 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.swt.graphics.Image; -import org.eclipse.ui.model.WorkbenchAdapter; - -/** - * An ExportTraceElement represents an item in the ExportTraceWizard tree. - * - * @author Marc-Andre Laperle - */ -public abstract class TracePackageElement extends WorkbenchAdapter { - private TracePackageElement[] fChildren; - private final TracePackageElement fParent; - private boolean fEnabled; - private boolean fChecked; - private boolean fVisible; - - /** - * - * @param parent - * the parent of this element, can be set to null - */ - public TracePackageElement(TracePackageElement parent) { - fParent = parent; - fEnabled = true; - fVisible = true; - fChildren = new TracePackageElement[0]; - } - - /** - * @return the parent of this element or null if there is no parent - */ - public TracePackageElement getParent() { - return fParent; - } - - /** - * Get the text representation of this element to be displayed in the tree. - * - * @return the text representation - */ - abstract public String getText(); - - /** - * Get the children of this element - * - * @return the children of this element - */ - public TracePackageElement[] getChildren() { - return fChildren; - } - - /** - * Get the visible children of this element - * - * @return the visible children of this element - */ - public TracePackageElement[] getVisibleChildren() { - List visibleChildren = new ArrayList<>(); - for (TracePackageElement child : fChildren) { - if (child.isVisible()) { - visibleChildren.add(child); - } - } - return visibleChildren.toArray(new TracePackageElement[0]); - } - - /** - * Set the children of this element - * - * @param children - * the children of this element - */ - public void setChildren(TracePackageElement[] children) { - this.fChildren = children; - } - - /** - * Get the total size of the element including its children - * - * @param checkedOnly - * only count checked elements - * - * @return the total size of the element - */ - public long getSize(boolean checkedOnly) { - long size = 0; - if (fChildren != null) { - for (TracePackageElement child : fChildren) { - size += child.getSize(checkedOnly); - } - } - - return size; - } - - /** - * Get the image representation of this element to be displayed in the tree. - * - * @return the image representation - */ - public Image getImage() { - return null; - } - - /** - * Returns whether or not the element is enabled (grayed and not - * modifiable). - * - * @return whether or not the element is enabled - */ - public boolean isEnabled() { - return fEnabled; - } - - /** - * Returns whether or not the element is checked. - * - * @return whether or not the element is checked - */ - public boolean isChecked() { - return fChecked; - } - - /** - * Returns whether or not the element is visible. - * - * @return whether or not the element is visible - */ - public boolean isVisible() { - return fVisible; - } - - /** - * Sets whether or not the element should be enabled (grayed and not - * modifiable). - * - * @param enabled - * if the element should be enabled - */ - public void setEnabled(boolean enabled) { - fEnabled = enabled; - } - - /** - * Sets whether or not the element should be checked. - * - * @param checked - * if the element should be checked - */ - public void setChecked(boolean checked) { - fChecked = checked; - } - - /** - * Sets whether or not the element is visible. - * - * @param visible - * if the element should be visible - */ - public void setVisible(boolean visible) { - fVisible = visible; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageFilesElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageFilesElement.java deleted file mode 100644 index 881a9cfa6a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageFilesElement.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg; - -import java.io.File; - -import org.eclipse.core.resources.IResource; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.swt.graphics.Image; - -/** - * An ExportTraceElement representing the trace files of a trace. - * - * @author Marc-Andre Laperle - */ -public class TracePackageFilesElement extends TracePackageElement { - - private static final String TRACE_ICON_PATH = "icons/elcl16/trace.gif"; //$NON-NLS-1$ - private final String fFileName; - private final IResource fResource; - private long fSize = -1; - - /** - * Constructs an instance of ExportTraceFilesElement when exporting - * - * @param parent - * the parent of this element, can be set to null - * @param resource - * the resource representing the trace file or folder in the - * workspace - */ - public TracePackageFilesElement(TracePackageElement parent, IResource resource) { - super(parent); - fFileName = null; - fResource = resource; - } - - /** - * Constructs an instance of ExportTraceFilesElement when importing - * - * @param parent - * the parent of this element, can be set to null - * @param fileName - * the name of the file to be imported - */ - public TracePackageFilesElement(TracePackageElement parent, String fileName) { - super(parent); - fFileName = fileName; - fResource = null; - } - - private long getSize(File file) { - if (file.isDirectory()) { - long size = 0; - for (File f : file.listFiles()) { - size += getSize(f); - } - return size; - } - - return file.length(); - } - - @Override - public long getSize(boolean checkedOnly) { - if (checkedOnly && !isChecked()) { - return 0; - } - - if (fSize == -1 && fResource.exists()) { - File file = fResource.getLocation().toFile(); - fSize = getSize(file); - } - - return fSize; - } - - @Override - public String getText() { - return Messages.TracePackage_TraceElement; - } - - @Override - public Image getImage() { - return Activator.getDefault().getImageFromImageRegistry(TRACE_ICON_PATH); - } - - /** - * Get the file name for this trace file or folder - * - * @return the file name for this trace file or folder - */ - public String getFileName() { - return fFileName; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageLabelProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageLabelProvider.java deleted file mode 100644 index e9b0f9886c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageLabelProvider.java +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg; - -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.ILabelProviderListener; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Display; - -/** - * A label provider for the export trace tree. - * - * @author Marc-Andre Laperle - */ -public class TracePackageLabelProvider extends ColumnLabelProvider { - - @Override - public void addListener(ILabelProviderListener listener) { - } - - @Override - public void dispose() { - } - - @Override - public boolean isLabelProperty(Object element, String property) { - return false; - } - - @Override - public void removeListener(ILabelProviderListener listener) { - } - - @Override - public Image getImage(Object element) { - return ((TracePackageElement) element).getImage(); - } - - @Override - public String getText(Object element) { - return ((TracePackageElement) element).getText(); - } - - @Override - public Color getForeground(Object element) { - if (!((TracePackageElement) element).isEnabled()) { - return Display.getDefault().getSystemColor(SWT.COLOR_GRAY); - } - return null; - } - - @Override - public Color getBackground(Object element) { - return null; - } - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageSupplFileElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageSupplFileElement.java deleted file mode 100644 index a9091f7fc3..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageSupplFileElement.java +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg; - -import org.eclipse.core.resources.IResource; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.swt.graphics.Image; - -/** - * A trace package element representing a single supplementary file - * - * @author Marc-Andre Laperle - */ -public class TracePackageSupplFileElement extends TracePackageElement { - - private static final String SUPPL_FILE_ICON_PATH = "icons/obj16/thread_obj.gif"; //$NON-NLS-1$ - - private final IResource fResource; - private final String fSuppFileName; - - /** - * Constructor used when exporting - * - * @param resource - * the resource representing this supplementary file in the - * workspace - * @param parent - * the parent element - */ - public TracePackageSupplFileElement(IResource resource, TracePackageElement parent) { - super(parent); - fResource = resource; - fSuppFileName = null; - } - - /** - * Constructor used when importing - * - * @param suppFileName - * the name to be used for the supplementary file in the - * workspace - * @param parent - * the parent element - */ - public TracePackageSupplFileElement(String suppFileName, TracePackageElement parent) { - super(parent); - this.fSuppFileName = suppFileName; - fResource = null; - } - - /** - * Get the resource corresponding to this supplementary file - * - * @return the resource corresponding to this supplementary file - */ - public IResource getResource() { - return fResource; - } - - @Override - public String getText() { - return fResource != null ? fResource.getName() : fSuppFileName; - } - - @Override - public long getSize(boolean checkedOnly) { - if (checkedOnly && !isChecked()) { - return 0; - } - - return fResource.getLocation().toFile().length(); - } - - @Override - public Image getImage() { - return Activator.getDefault().getImageFromImageRegistry(SUPPL_FILE_ICON_PATH); - } - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageSupplFilesElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageSupplFilesElement.java deleted file mode 100644 index 70cb7c74da..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageSupplFilesElement.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg; - -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.swt.graphics.Image; - -/** - * A trace package element used for grouping supplementary file under a single - * subtree - * - * @author Marc-Andre Laperle - */ -public class TracePackageSupplFilesElement extends TracePackageElement { - - private static final String SUPPL_FILE_ICON_PATH = "icons/obj16/thread_obj.gif"; //$NON-NLS-1$ - - /** - * Construct a new TracePackageSupplFilesElement instance - * - * @param parent - * the parent of this element, can be set to null - */ - public TracePackageSupplFilesElement(TracePackageElement parent) { - super(parent); - } - - @Override - public String getText() { - return Messages.TracePackage_SupplementaryFiles; - } - - @Override - public Image getImage() { - return Activator.getDefault().getImageFromImageRegistry(SUPPL_FILE_ICON_PATH); - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageTraceElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageTraceElement.java deleted file mode 100644 index a17ed2c070..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/TracePackageTraceElement.java +++ /dev/null @@ -1,149 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg; - -import org.eclipse.core.runtime.IPath; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfCommonProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfNavigatorLabelProvider; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.swt.graphics.Image; - -/** - * An ExportTraceElement associated to a TmfTraceElement. This will be the - * parent of other elements (events, supplementary files, bookmarks, etc). - * - * @author Marc-Andre Laperle - */ -public class TracePackageTraceElement extends TracePackageElement { - - private final TmfTraceElement fTraceElement; - private final String fImportName; - private final String fTraceType; - - /** - * Construct an instance associated to a TmfTraceElement. For exporting. - * - * @param parent - * the parent of this element, can be set to null - * @param traceElement - * the associated TmfTraceElement - */ - public TracePackageTraceElement(TracePackageElement parent, TmfTraceElement traceElement) { - super(parent); - fTraceElement = traceElement; - fImportName = null; - fTraceType = null; - } - - /** - * Construct an instance associated to a TmfTraceElement. For importing. - * - * @param parent - * the parent of this element, can be set to null - * @param importName - * the name to use to identify this trace - * @param traceType - * the trace type to set for this trace - */ - public TracePackageTraceElement(TracePackageElement parent, String importName, String traceType) { - super(parent); - fImportName = importName; - fTraceElement = null; - fTraceType = traceType; - } - - @Override - public String getText() { - return fTraceElement != null ? fTraceElement.getElementPath() : getDestinationElementPath(); - } - - /** - * Return the target TmfCommonProjectElement element path for a given trace - * package element. {@link TmfCommonProjectElement#getElementPath()} - * - * @return the element path - */ - public String getDestinationElementPath() { - String traceName = getImportName(); - for (TracePackageElement element : getChildren()) { - if (element instanceof TracePackageFilesElement) { - TracePackageFilesElement tracePackageFilesElement = (TracePackageFilesElement) element; - String fileName = tracePackageFilesElement.getFileName(); - String parentDir = removeLastSegment(fileName); - return append(parentDir, traceName); - } - } - - return traceName; - } - - /** - * We do this outside of the Path class because we don't want it to convert - * \ to / on Windows in the presence of regular expressions - */ - private static String removeLastSegment(String str) { - String ret = removeAllTrailing(str, IPath.SEPARATOR); - int lastIndexOf = ret.lastIndexOf(IPath.SEPARATOR); - if (lastIndexOf != -1) { - ret = ret.substring(0, lastIndexOf); - ret = removeAllTrailing(ret, IPath.SEPARATOR); - } else { - ret = ""; //$NON-NLS-1$ - } - - return ret; - } - - private static String removeAllTrailing(String str, char toRemove) { - String ret = str; - while (ret.endsWith(Character.toString(toRemove))) { - ret = ret.substring(0, ret.length() - 1); - } - return ret; - } - - private static String append(String path, String str) { - if (!path.isEmpty()) { - return path + IPath.SEPARATOR + str; - } - - return str; - } - - /** - * @return the associated TmfTraceElement - */ - public TmfTraceElement getTraceElement() { - return fTraceElement; - } - - /** - * @return the import name - */ - public String getImportName() { - return fImportName; - } - - /** - * @return the trace type of this trace - */ - public String getTraceType() { - return fTraceType; - } - - @Override - public Image getImage() { - TmfNavigatorLabelProvider tmfNavigatorLabelProvider = new TmfNavigatorLabelProvider(); - return tmfNavigatorLabelProvider.getImage(fTraceElement); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageHandler.java deleted file mode 100644 index f64a5169cb..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageHandler.java +++ /dev/null @@ -1,105 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.importexport; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.ui.ISources; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.handlers.HandlerUtil; - -/** - * Handler for exporting a trace package - * - * @author Marc-Andre Laperle - */ -public class ExportTracePackageHandler extends AbstractHandler { - - private boolean fEnabled = false; - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return Boolean.FALSE; - } - - ISelection currentSelection = HandlerUtil.getCurrentSelection(event); - IStructuredSelection sec = StructuredSelection.EMPTY; - List selectedTraces = new ArrayList<>(); - if (currentSelection instanceof IStructuredSelection) { - sec = (IStructuredSelection) currentSelection; - Object[] selectedElements = sec.toArray(); - for (Object selectedElement : selectedElements) { - if (selectedElement instanceof TmfTraceElement) { - TmfTraceElement tmfTraceElement = (TmfTraceElement) selectedElement; - selectedTraces.add(tmfTraceElement.getElementUnderTraceFolder()); - } else if (selectedElement instanceof TmfTraceFolder) { - TmfTraceFolder tmfTraceFolder = (TmfTraceFolder) selectedElement; - selectedTraces = tmfTraceFolder.getTraces(); - } - } - } - - ExportTracePackageWizard w = new ExportTracePackageWizard(selectedTraces); - - w.init(PlatformUI.getWorkbench(), sec); - WizardDialog dialog = new WizardDialog(window.getShell(), w); - dialog.open(); - return null; - } - - @Override - public boolean isEnabled() { - return super.isEnabled() && fEnabled; - } - - @Override - public void setEnabled(Object evaluationContext) { - super.setEnabled(evaluationContext); - - fEnabled = true; - - Object s = HandlerUtil.getVariable(evaluationContext, ISources.ACTIVE_MENU_SELECTION_NAME); - if (s instanceof IStructuredSelection) { - IStructuredSelection selection = (IStructuredSelection) s; - // If we have traces selected, make sure they are all from the same - // project, disable handler otherwise - Object[] selectedElements = selection.toArray(); - TmfProjectElement firstProject = null; - for (Object selectedElement : selectedElements) { - if (selectedElement instanceof TmfTraceElement) { - TmfTraceElement tmfTraceElement = (TmfTraceElement) selectedElement; - TmfProjectElement project = tmfTraceElement.getProject(); - if (firstProject != null && !project.equals(firstProject)) { - fEnabled = false; - } - - firstProject = project; - } - } - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageSelectTraceWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageSelectTraceWizardPage.java deleted file mode 100644 index 8a6c190138..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageSelectTraceWizardPage.java +++ /dev/null @@ -1,218 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.importexport; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.resources.IProject; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfNavigatorContentProvider; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfNavigatorLabelProvider; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.linuxtools.tmf.ui.project.model.TraceUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableItem; -import org.eclipse.ui.model.WorkbenchLabelProvider; - -/** - * A wizard page for selecting the trace to export when no trace was previously - * selected. - * - * @author Marc-Andre Laperle - */ -public class ExportTracePackageSelectTraceWizardPage extends WizardPage { - - private static final String PAGE_NAME = "ExportTracePackageSelectTraceWizardPage"; //$NON-NLS-1$ - - /** - * Construct the select trace page - */ - public ExportTracePackageSelectTraceWizardPage() { - super(PAGE_NAME); - } - - private IProject fSelectedProject; - private Table fTraceTable; - - @Override - public void createControl(Composite parent) { - Composite projectSelectionGroup = new Composite(parent, SWT.NONE); - projectSelectionGroup.setLayout(new GridLayout(2, true)); - projectSelectionGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); - projectSelectionGroup.setFont(parent.getFont()); - - Label projectLabel = new Label(projectSelectionGroup, SWT.NONE); - projectLabel.setText(Messages.ExportTracePackageSelectTraceWizardPage_ProjectSelection); - projectLabel.setLayoutData(new GridData()); - - Label configLabel = new Label(projectSelectionGroup, SWT.NONE); - configLabel.setText(Messages.ExportTracePackageSelectTraceWizardPage_TraceSelection); - configLabel.setLayoutData(new GridData()); - - final Table projectTable = new Table(projectSelectionGroup, SWT.SINGLE | SWT.BORDER); - projectTable.setLayoutData(new GridData(GridData.FILL_BOTH)); - - TableViewer projectViewer = new TableViewer(projectTable); - projectViewer.setContentProvider(new TmfNavigatorContentProvider() { - - @Override - public Object[] getElements(Object inputElement) { - return (IProject[]) inputElement; - } - }); - projectViewer.setLabelProvider(new WorkbenchLabelProvider()); - projectViewer.setInput(TraceUtils.getOpenedTmfProjects().toArray(new IProject[] {})); - - fTraceTable = new Table(projectSelectionGroup, SWT.BORDER | SWT.CHECK); - fTraceTable.setLayoutData(new GridData(GridData.FILL_BOTH)); - - final TableViewer traceViewer = new TableViewer(fTraceTable); - traceViewer.setContentProvider(new IStructuredContentProvider() { - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - @Override - public void dispose() { - } - - @Override - public Object[] getElements(Object inputElement) { - if (inputElement instanceof TmfTraceElement[]) { - return (TmfTraceElement[]) inputElement; - } - return null; - } - }); - traceViewer.setLabelProvider(new ExportLabelProvider()); - fTraceTable.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - getWizard().getContainer().updateButtons(); - updateNextPageData(); - } - }); - - projectTable.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - TableItem[] items = projectTable.getSelection(); - fSelectedProject = (IProject) items[0].getData(); - - TmfProjectElement project = TmfProjectRegistry.getProject(fSelectedProject, true); - - TmfTraceFolder tracesFolder = project.getTracesFolder(); - List traces = tracesFolder.getTraces(); - TmfTraceElement[] array = traces.toArray(new TmfTraceElement[] {}); - traceViewer.setInput(array); - traceViewer.refresh(); - fTraceTable.select(0); - fTraceTable.notifyListeners(SWT.Selection, new Event()); - getWizard().getContainer().updateButtons(); - } - }); - - Composite btComp = new Composite(projectSelectionGroup, SWT.NONE); - btComp.setLayout(new GridLayout(2, true)); - GridData gd = new GridData(); - gd.horizontalSpan = 2; - gd.horizontalAlignment = SWT.RIGHT; - btComp.setLayoutData(gd); - - final Button selectAll = new Button(btComp, SWT.PUSH); - selectAll.setText(org.eclipse.linuxtools.internal.tmf.ui.project.dialogs.Messages.Dialog_SelectAll); - selectAll.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - TableItem[] items = fTraceTable.getItems(); - for (TableItem item : items) { - item.setChecked(true); - } - - getWizard().getContainer().updateButtons(); - updateNextPageData(); - } - }); - - final Button deselectAll = new Button(btComp, SWT.PUSH); - deselectAll.setText(org.eclipse.linuxtools.internal.tmf.ui.project.dialogs.Messages.Dialog_DeselectAll); - deselectAll.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - TableItem[] items = fTraceTable.getItems(); - for (TableItem item : items) { - item.setChecked(false); - } - - getWizard().getContainer().updateButtons(); - updateNextPageData(); - } - }); - - setControl(projectSelectionGroup); - setTitle(Messages.ExportTracePackageWizardPage_Title); - setMessage(Messages.ExportTracePackageSelectTraceWizardPage_ChooseTrace); - } - - private ArrayList getCheckedTraces() { - TableItem[] items = fTraceTable.getItems(); - ArrayList traces = new ArrayList<>(); - for (TableItem item : items) { - if (item.getChecked()) { - TmfTraceElement trace = (TmfTraceElement) item.getData(); - traces.add(trace); - } - } - return traces; - } - - private void updateNextPageData() { - ExportTracePackageWizardPage page = (ExportTracePackageWizardPage) getWizard().getPage(ExportTracePackageWizardPage.PAGE_NAME); - page.setSelectedTraces(getCheckedTraces()); - } - - @Override - public boolean canFlipToNextPage() { - return getCheckedTraces().size() > 0; - } - - private class ExportLabelProvider extends TmfNavigatorLabelProvider { - @Override - public String getText(Object element) { - - if (element instanceof TmfTraceElement) { - TmfTraceElement folder = (TmfTraceElement) element; - return folder.getElementPath(); - } - return super.getText(element); - } - } - - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageWizard.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageWizard.java deleted file mode 100644 index 6a81ae5a84..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageWizard.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.importexport; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.ui.IExportWizard; -import org.eclipse.ui.IWorkbench; - -/** - * Wizard for exporting a trace package - * - * @author Marc-Andre Laperle - */ -public class ExportTracePackageWizard extends Wizard implements IExportWizard { - - private static final String STORE_EXPORT_TRACE_WIZARD = "ExportTraceWizard"; //$NON-NLS-1$ - private IStructuredSelection fSelection; - private List fSelectedTraces; - private ExportTracePackageWizardPage fPage; - - /** - * Constructor for the export trace wizard - */ - public ExportTracePackageWizard() { - IDialogSettings workbenchSettings = Activator.getDefault().getDialogSettings(); - IDialogSettings section = workbenchSettings - .getSection(STORE_EXPORT_TRACE_WIZARD); - if (section == null) { - section = workbenchSettings.addNewSection(STORE_EXPORT_TRACE_WIZARD); - } - setDialogSettings(section); - fSelectedTraces = new ArrayList<>(); - } - - /** - * Constructor for the export trace wizard with known selected traces - * - * @param selectedTraces - * the selected traces - */ - public ExportTracePackageWizard(List selectedTraces) { - this(); - fSelectedTraces = selectedTraces; - } - - @Override - public void init(IWorkbench workbench, IStructuredSelection selection) { - fSelection = selection; - - setNeedsProgressMonitor(true); - } - - @Override - public boolean performFinish() { - return fPage.finish(); - } - - @Override - public void addPages() { - super.addPages(); - fPage = new ExportTracePackageWizardPage(fSelection, fSelectedTraces); - if (fSelectedTraces.isEmpty()) { - addPage(new ExportTracePackageSelectTraceWizardPage()); - } - addPage(fPage); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageWizardPage.java deleted file mode 100644 index 05cd4b92c6..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageWizardPage.java +++ /dev/null @@ -1,453 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.importexport; - -import java.io.File; -import java.lang.reflect.InvocationTargetException; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.viewers.CheckboxTreeViewer; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.TreeViewerColumn; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageWizardPage; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageBookmarkElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageLabelProvider; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFileElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFilesElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; - -/** - * Wizard page for the export trace package wizard - * - * @author Marc-Andre Laperle - */ -public class ExportTracePackageWizardPage extends AbstractTracePackageWizardPage { - - private static final int CONTENT_COL_WIDTH = 300; - private static final int SIZE_COL_WIDTH = 100; - - private static final String ZIP_EXTENSION = ".zip"; //$NON-NLS-1$ - private static final String TAR_EXTENSION = ".tar"; //$NON-NLS-1$ - private static final String TAR_GZ_EXTENSION = ".tar.gz"; //$NON-NLS-1$ - private static final String TGZ_EXTENSION = ".tgz"; //$NON-NLS-1$ - - private static final String ICON_PATH = "icons/wizban/export_wiz.png"; //$NON-NLS-1$ - - /** - * The page name, can be referenced from other pages - */ - public static final String PAGE_NAME = "ExportTracePackageWizardPage"; //$NON-NLS-1$ - // dialog store id constants - private static final String STORE_COMPRESS_CONTENTS_ID = PAGE_NAME + ".STORE_COMPRESS_CONTENTS_ID"; //$NON-NLS-1$ - private static final String STORE_FORMAT_ID = PAGE_NAME + ".STORE_FORMAT_ID"; //$NON-NLS-1$ - - private Button fCompressContentsCheckbox; - private Button fZipFormatButton; - private Button fTargzFormatButton; - private Label fApproximateSizeLabel; - private List fSelectedTraces; - - /** - * Constructor for the export trace package wizard page - * - * @param selection - * the current object selection - * @param selectedTraces - * the selected traces from the selection - */ - public ExportTracePackageWizardPage(IStructuredSelection selection, List selectedTraces) { - super(PAGE_NAME, Messages.ExportTracePackageWizardPage_Title, Activator.getDefault().getImageDescripterFromPath(ICON_PATH), selection); - fSelectedTraces = selectedTraces; - } - - /** - * Set the selected trace from the previous page to be displayed in the - * element viewer - * - * @param selectedTraces - * the selected trace - */ - public void setSelectedTraces(List selectedTraces) { - if (!fSelectedTraces.containsAll(selectedTraces) || !selectedTraces.containsAll(fSelectedTraces)) { - fSelectedTraces = selectedTraces; - CheckboxTreeViewer elementViewer = getElementViewer(); - elementViewer.setInput(createElementViewerInput()); - elementViewer.expandToLevel(2); - setAllChecked(elementViewer, false, true); - updateApproximateSelectedSize(); - } - } - - @Override - public void createControl(Composite parent) { - - initializeDialogUnits(parent); - - Composite composite = new Composite(parent, SWT.NULL); - composite.setLayout(new GridLayout()); - composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL)); - - createElementViewer(composite); - createButtonsGroup(composite); - createFilePathGroup(composite, Messages.ExportTracePackageWizardPage_ToArchive, SWT.SAVE); - createOptionsGroup(composite); - - restoreWidgetValues(); - setMessage(Messages.ExportTracePackageWizardPage_ChooseContent); - - updateApproximateSelectedSize(); - updatePageCompletion(); - - setControl(composite); - } - - @Override - public void setVisible(boolean visible) { - super.setVisible(visible); - if (visible) { - updatePageCompletion(); - } else { - setPageComplete(false); - } - } - - /** - * Restore widget values to the values that they held last time this wizard - * was used to completion. - */ - @Override - protected void restoreWidgetValues() { - super.restoreWidgetValues(); - - IDialogSettings settings = getDialogSettings(); - if (settings != null) { - if (getFilePathCombo().getItemCount() > 0) { - String item = getFilePathCombo().getItem(0); - setFilePathValue(item); - } - fCompressContentsCheckbox.setSelection(settings.getBoolean(STORE_COMPRESS_CONTENTS_ID)); - fZipFormatButton.setSelection(settings.getBoolean(STORE_FORMAT_ID)); - fTargzFormatButton.setSelection(!settings.getBoolean(STORE_FORMAT_ID)); - updateWithFilePathSelection(); - } - } - - @Override - protected void createFilePathGroup(Composite parent, String label, int fileDialogStyle) { - super.createFilePathGroup(parent, label, fileDialogStyle); - - getFilePathCombo().addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - updatePageCompletion(); - } - }); - } - - private void createOptionsGroup(Composite parent) { - Group optionsGroup = new Group(parent, SWT.NONE); - optionsGroup.setLayout(new RowLayout(SWT.VERTICAL)); - optionsGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL - | GridData.GRAB_HORIZONTAL)); - optionsGroup.setText(Messages.ExportTracePackageWizardPage_Options); - - SelectionAdapter listener = new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - updateWithFilePathSelection(); - } - }; - - fZipFormatButton = new Button(optionsGroup, SWT.RADIO | SWT.LEFT); - fZipFormatButton.setText(Messages.ExportTracePackageWizardPage_SaveInZipFormat); - fZipFormatButton.setSelection(true); - fZipFormatButton.addSelectionListener(listener); - - fTargzFormatButton = new Button(optionsGroup, SWT.RADIO | SWT.LEFT); - fTargzFormatButton.setText(Messages.ExportTracePackageWizardPage_SaveInTarFormat); - fTargzFormatButton.setSelection(false); - fTargzFormatButton.addSelectionListener(listener); - - fCompressContentsCheckbox = new Button(optionsGroup, SWT.CHECK | SWT.LEFT); - fCompressContentsCheckbox.setText(Messages.ExportTracePackageWizardPage_CompressContents); - fCompressContentsCheckbox.setSelection(true); - fCompressContentsCheckbox.addSelectionListener(listener); - } - - @Override - protected void createElementViewer(Composite parent) { - super.createElementViewer(parent); - - CheckboxTreeViewer elementViewer = getElementViewer(); - elementViewer.getTree().setHeaderVisible(true); - // Content column - TreeViewerColumn column = new TreeViewerColumn(elementViewer, SWT.NONE); - column.getColumn().setWidth(CONTENT_COL_WIDTH); - column.getColumn().setText(Messages.ExportTracePackageWizardPage_ContentColumnName); - column.setLabelProvider(new TracePackageLabelProvider()); - - // Size column - column = new TreeViewerColumn(elementViewer, SWT.NONE); - column.getColumn().setWidth(SIZE_COL_WIDTH); - column.getColumn().setText(Messages.ExportTracePackageWizardPage_SizeColumnName); - column.setLabelProvider(new ColumnLabelProvider() { - @Override - public String getText(Object element) { - TracePackageElement tracePackageElement = (TracePackageElement) element; - long size = tracePackageElement.getSize(false); - if (size == 0) { - return null; - } - int level = 0; - TracePackageElement curElement = tracePackageElement.getParent(); - while (curElement != null) { - curElement = curElement.getParent(); - ++level; - } - - return indent(getHumanReadable(size), level); - } - - private String indent(String humanReadable, int level) { - StringBuilder s = new StringBuilder(humanReadable); - for (int i = 0; i < level; ++i) { - final String indentStr = " "; //$NON-NLS-1$ - s.insert(0, indentStr); - } - return s.toString(); - } - }); - - elementViewer.setInput(createElementViewerInput()); - elementViewer.expandToLevel(2); - setAllChecked(elementViewer, false, true); - } - - @Override - protected void updateApproximateSelectedSize() { - long checkedSize = 0; - TracePackageElement[] tracePackageElements = (TracePackageElement[]) getElementViewer().getInput(); - for (TracePackageElement element : tracePackageElements) { - checkedSize += element.getSize(true); - } - checkedSize = Math.max(0, checkedSize); - fApproximateSizeLabel.setText(MessageFormat.format(Messages.ExportTracePackageWizardPage_ApproximateSizeLbl, getHumanReadable(checkedSize))); - } - - /** - * Get the human readable string for a size in bytes. (KB, MB, etc). - * - * @param size - * the size to print in human readable, - * @return the human readable string - */ - private static String getHumanReadable(long size) { - String humanSuffix[] = { Messages.ExportTracePackageWizardPage_SizeByte, Messages.ExportTracePackageWizardPage_SizeKilobyte, - Messages.ExportTracePackageWizardPage_SizeMegabyte, Messages.ExportTracePackageWizardPage_SizeGigabyte, - Messages.ExportTracePackageWizardPage_SizeTerabyte }; - long curSize = size; - - int suffixIndex = 0; - while (curSize >= 1024) { - curSize /= 1024; - ++suffixIndex; - } - - return Long.toString(curSize) + " " + humanSuffix[suffixIndex]; //$NON-NLS-1$ - } - - @Override - protected Object createElementViewerInput() { - List traceElements = new ArrayList<>(); - for (TmfTraceElement tmfTraceElement : fSelectedTraces) { - TracePackageTraceElement traceElement = new TracePackageTraceElement(null, tmfTraceElement); - - // Trace files - List children = new ArrayList<>(); - TracePackageFilesElement filesElement = new TracePackageFilesElement(traceElement, tmfTraceElement.getResource()); - filesElement.setChecked(true); - children.add(filesElement); - - // Supplementary files - IResource[] supplementaryResources = tmfTraceElement.getSupplementaryResources(); - List suppFilesChildren = new ArrayList<>(); - TracePackageSupplFilesElement suppFilesElement = new TracePackageSupplFilesElement(traceElement); - children.add(suppFilesElement); - for (IResource res : supplementaryResources) { - suppFilesChildren.add(new TracePackageSupplFileElement(res, suppFilesElement)); - } - suppFilesElement.setChildren(suppFilesChildren.toArray(new TracePackageElement[] {})); - - // Bookmarks - IFile bookmarksFile = tmfTraceElement.getBookmarksFile(); - if (bookmarksFile != null && bookmarksFile.exists()) { - IMarker[] findMarkers; - try { - findMarkers = bookmarksFile.findMarkers(IMarker.BOOKMARK, false, IResource.DEPTH_ZERO); - if (findMarkers.length > 0) { - children.add(new TracePackageBookmarkElement(traceElement, null)); - } - } catch (CoreException e) { - // Should not happen since we just checked bookmarksFile.exists() but log it just in case - Activator.getDefault().logError("Error finding bookmarks", e); //$NON-NLS-1$ - } - } - - traceElement.setChildren(children.toArray(new TracePackageElement[] {})); - - traceElements.add(traceElement); - - } - - return traceElements.toArray(new TracePackageTraceElement[] {}); - } - - @Override - protected final Composite createButtonsGroup(Composite parent) { - Composite buttonGroup = super.createButtonsGroup(parent); - - // Add the label on the same row of the select/deselect all buttons - fApproximateSizeLabel = new Label(buttonGroup, SWT.RIGHT); - GridData layoutData = new GridData(GridData.FILL_HORIZONTAL); - layoutData.grabExcessHorizontalSpace = true; - fApproximateSizeLabel.setLayoutData(layoutData); - - return buttonGroup; - } - - /** - * Save widget values to Dialog settings - */ - @Override - protected void saveWidgetValues() { - super.saveWidgetValues(); - - IDialogSettings settings = getDialogSettings(); - if (settings != null) { - settings.put(STORE_COMPRESS_CONTENTS_ID, fCompressContentsCheckbox.getSelection()); - settings.put(STORE_FORMAT_ID, fZipFormatButton.getSelection()); - } - } - - private String getOutputExtension() { - if (fZipFormatButton.getSelection()) { - return ZIP_EXTENSION; - } else if (fCompressContentsCheckbox.getSelection()) { - return TAR_GZ_EXTENSION; - } else { - return TAR_EXTENSION; - } - } - - @Override - protected void updateWithFilePathSelection() { - String filePathValue = getFilePathValue(); - if (filePathValue.isEmpty()) { - return; - } - - filePathValue = stripKnownExtension(filePathValue); - filePathValue = filePathValue.concat(getOutputExtension()); - - setFilePathValue(filePathValue); - } - - private static String stripKnownExtension(String str) { - String ret = str; - if (str.endsWith(TAR_GZ_EXTENSION)) { - ret = ret.substring(0, ret.lastIndexOf(".")); //$NON-NLS-1$ - } - - if (ret.endsWith(ZIP_EXTENSION) | ret.endsWith(TAR_EXTENSION) | ret.endsWith(TGZ_EXTENSION)) { - ret = ret.substring(0, ret.lastIndexOf(".")); //$NON-NLS-1$ - } - - return ret; - } - - /** - * Finish the wizard page - * - * @return true on success - */ - public boolean finish() { - if (!checkForOverwrite()) { - return false; - } - - saveWidgetValues(); - - TracePackageTraceElement[] traceExportElements = (TracePackageTraceElement[]) getElementViewer().getInput(); - boolean useCompression = fCompressContentsCheckbox.getSelection(); - boolean useTar = fTargzFormatButton.getSelection(); - String fileName = getFilePathValue(); - final TracePackageExportOperation exporter = new TracePackageExportOperation(traceExportElements, useCompression, useTar, fileName); - - try { - getContainer().run(true, true, new IRunnableWithProgress() { - - @Override - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - exporter.run(monitor); - } - }); - - IStatus status = exporter.getStatus(); - if (status.getSeverity() == IStatus.ERROR) { - handleErrorStatus(status); - } - - } catch (InvocationTargetException e) { - handleError(org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, e); - } catch (InterruptedException e) { - } - - return exporter.getStatus().getSeverity() == IStatus.OK; - } - - private boolean checkForOverwrite() { - File file = new File(getFilePathValue()); - if (file.exists()) { - return MessageDialog.openQuestion(getContainer().getShell(), null, Messages.ExportTracePackageWizardPage_AlreadyExitst); - } - return true; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageHandler.java deleted file mode 100644 index 4fd8d62adc..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageHandler.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.importexport; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.handlers.HandlerUtil; - -/** - * Handler for importing a trace package - * - * @author Marc-Andre Laperle - */ -public class ImportTracePackageHandler extends AbstractHandler { - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - ImportTracePackageWizard w = new ImportTracePackageWizard(); - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - - if (window == null) { - return Boolean.FALSE; - } - - ISelection currentSelection = HandlerUtil.getCurrentSelection(event); - IStructuredSelection sec = StructuredSelection.EMPTY; - if (currentSelection instanceof IStructuredSelection) { - sec = (IStructuredSelection) currentSelection; - } - - w.init(PlatformUI.getWorkbench(), sec); - WizardDialog dialog = new WizardDialog(window.getShell(), w); - dialog.open(); - return null; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageWizard.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageWizard.java deleted file mode 100644 index 8acf158f8d..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageWizard.java +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.importexport; - -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.ui.IImportWizard; -import org.eclipse.ui.IWorkbench; - -/** - * Wizard for importing a trace package - * - * @author Marc-Andre Laperle - */ -public class ImportTracePackageWizard extends Wizard implements IImportWizard { - - private static final String STORE_IMPORT_TRACE_PKG_WIZARD = "ImportTracePackageWizard"; //$NON-NLS-1$ - private IStructuredSelection fSelection; - private ImportTracePackageWizardPage fPage; - - /** - * Constructs the import trace package wizard - */ - public ImportTracePackageWizard() { - IDialogSettings workbenchSettings = Activator.getDefault().getDialogSettings(); - IDialogSettings section = workbenchSettings - .getSection(STORE_IMPORT_TRACE_PKG_WIZARD); - if (section == null) { - section = workbenchSettings.addNewSection(STORE_IMPORT_TRACE_PKG_WIZARD); - } - setDialogSettings(section); - } - - @Override - public void init(IWorkbench workbench, IStructuredSelection selection) { - fSelection = selection; - setNeedsProgressMonitor(true); - } - - @Override - public boolean performFinish() { - return fPage.finish(); - } - - @Override - public void addPages() { - super.addPages(); - fPage = new ImportTracePackageWizardPage(fSelection); - addPage(fPage); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageWizardPage.java deleted file mode 100644 index 6787584d4e..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageWizardPage.java +++ /dev/null @@ -1,417 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.importexport; - -import java.io.File; -import java.lang.reflect.InvocationTargetException; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.viewers.CheckboxTreeViewer; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageOperation; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageWizardPage; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.linuxtools.tmf.ui.project.model.TraceUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.TraverseEvent; -import org.eclipse.swt.events.TraverseListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.dialogs.ElementListSelectionDialog; -import org.eclipse.ui.model.WorkbenchLabelProvider; - -/** - * Wizard page for the import trace package wizard - * - * @author Marc-Andre Laperle - */ -public class ImportTracePackageWizardPage extends AbstractTracePackageWizardPage { - - private static final String ICON_PATH = "icons/wizban/trace_import_wiz.png"; //$NON-NLS-1$ - private static final String PAGE_NAME = "ImportTracePackagePage"; //$NON-NLS-1$ - private static final String STORE_PROJECT_NAME_ID = PAGE_NAME + ".STORE_PROJECT_NAME_ID"; //$NON-NLS-1$ - - private String fValidatedFilePath; - private TmfTraceFolder fTmfTraceFolder; - private Text fProjectText; - private List fOpenedTmfProjects; - - /** - * Constructor for the import trace package wizard page - * - * @param selection - * the current object selection - */ - public ImportTracePackageWizardPage(IStructuredSelection selection) { - super(PAGE_NAME, Messages.ImportTracePackageWizardPage_Title, Activator.getDefault().getImageDescripterFromPath(ICON_PATH), selection); - - if (getSelection().getFirstElement() instanceof TmfTraceFolder) { - fTmfTraceFolder = (TmfTraceFolder) getSelection().getFirstElement(); - } - } - - @Override - public void createControl(Composite parent) { - initializeDialogUnits(parent); - - Composite composite = new Composite(parent, SWT.NULL); - composite.setLayout(new GridLayout()); - composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL - | GridData.HORIZONTAL_ALIGN_FILL)); - composite.setFont(parent.getFont()); - - createFilePathGroup(composite, Messages.ImportTracePackageWizardPage_FromArchive, SWT.OPEN); - createElementViewer(composite); - createButtonsGroup(composite); - if (fTmfTraceFolder == null) { - createProjectSelectionGroup(composite); - } - - restoreWidgetValues(); - setMessage(Messages.ImportTracePackageWizardPage_Message); - updatePageCompletion(); - - setControl(composite); - } - - private void createProjectSelectionGroup(Composite parent) { - - Composite projectSelectionGroup = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.numColumns = 3; - projectSelectionGroup.setLayout(layout); - projectSelectionGroup.setLayoutData(new GridData( - GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL)); - - Label projectLabel = new Label(projectSelectionGroup, SWT.NONE); - projectLabel.setText(Messages.ImportTracePackageWizardPage_Project); - - fProjectText = new Text(projectSelectionGroup, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); - GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL - | GridData.GRAB_HORIZONTAL); - data.grabExcessHorizontalSpace = true; - fProjectText.setLayoutData(data); - - fOpenedTmfProjects = TraceUtils.getOpenedTmfProjects(); - - // No project to import to, create a default project if it doesn't exist - if (fOpenedTmfProjects.isEmpty()) { - IProject defaultProject = ResourcesPlugin.getWorkspace().getRoot().getProject(TmfCommonConstants.DEFAULT_TRACE_PROJECT_NAME); - if (!defaultProject.exists()) { - IProject project = TmfProjectRegistry.createProject(TmfCommonConstants.DEFAULT_TRACE_PROJECT_NAME, null, null); - fOpenedTmfProjects.add(project); - } - } - - if (!fOpenedTmfProjects.isEmpty()) { - selectProject(fOpenedTmfProjects.get(0)); - } - - Button button = new Button(projectSelectionGroup, - SWT.PUSH); - button.setText(Messages.ImportTracePackageWizardPage_SelectProjectButton); - button.addListener(SWT.Selection, new Listener() { - @Override - public void handleEvent(Event event) { - ElementListSelectionDialog d = new ElementListSelectionDialog(getContainer().getShell(), new WorkbenchLabelProvider()); - - d.setBlockOnOpen(true); - d.setTitle(Messages.ImportTracePackageWizardPage_SelectProjectDialogTitle); - - d.setElements(fOpenedTmfProjects.toArray(new IProject[] {})); - - d.open(); - if (d.getFirstResult() != null) { - IProject project = (IProject) d.getFirstResult(); - selectProject(project); - } - } - }); - setButtonLayoutData(button); - } - - @Override - protected void restoreWidgetValues() { - super.restoreWidgetValues(); - IDialogSettings settings = getDialogSettings(); - if (settings != null && fProjectText != null) { - - // Restore last selected project - String projectName = settings.get(STORE_PROJECT_NAME_ID); - if (projectName != null && !projectName.isEmpty()) { - for (IProject project : fOpenedTmfProjects) { - if (project.getName().equals(projectName)) { - selectProject(project); - break; - } - } - } - } - } - - @Override - protected void saveWidgetValues() { - super.saveWidgetValues(); - - IDialogSettings settings = getDialogSettings(); - if (settings != null) { - settings.put(STORE_PROJECT_NAME_ID, fTmfTraceFolder.getProject().getResource().getName()); - } - } - - private void selectProject(IProject project) { - fProjectText.setText(project.getName()); - fTmfTraceFolder = TmfProjectRegistry.getProject(project, true).getTracesFolder(); - updatePageCompletion(); - } - - @Override - protected boolean determinePageCompletion() { - return super.determinePageCompletion() && fTmfTraceFolder != null; - } - - /** - * Create the operation that will be responsible of creating the manifest - * based on the file name. - * - * @param fileName the file name to generate the manifest from - * - * @return the operation that will extract the manifest - */ - protected AbstractTracePackageOperation createExtractManifestOperation(String fileName) { - return new TracePackageExtractManifestOperation(fileName); - } - - @Override - protected Object createElementViewerInput() { - - final AbstractTracePackageOperation op = createExtractManifestOperation(getFilePathValue()); - - try { - getContainer().run(true, true, new IRunnableWithProgress() { - - @Override - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - monitor.beginTask(Messages.ImportTracePackageWizardPage_ReadingPackage, 10); - op.run(monitor); - monitor.done(); - } - - }); - - IStatus status = op.getStatus(); - if (status.getSeverity() == IStatus.ERROR) { - handleErrorStatus(status); - } - } catch (InvocationTargetException e1) { - handleError(Messages.TracePackageExtractManifestOperation_ErrorReadingManifest, e1); - } catch (InterruptedException e1) { - // Canceled - } - - TracePackageElement[] resultElements = op.getResultElements(); - if (resultElements == null || resultElements.length == 0) { - return null; - } - - return resultElements; - } - - @Override - protected void createFilePathGroup(Composite parent, String label, int fileDialogStyle) { - super.createFilePathGroup(parent, label, fileDialogStyle); - - Combo filePathCombo = getFilePathCombo(); - filePathCombo.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - updateWithFilePathSelection(); - } - }); - - // User can type-in path and press return to validate - filePathCombo.addTraverseListener(new TraverseListener() { - @Override - public void keyTraversed(TraverseEvent e) { - if (e.detail == SWT.TRAVERSE_RETURN) { - e.doit = false; - updateWithFilePathSelection(); - } - } - }); - } - - @Override - protected void updateWithFilePathSelection() { - if (!isFilePathValid()) { - setErrorMessage(Messages.ImportTracePackageWizardPage_ErrorFileNotFound); - getElementViewer().setInput(null); - return; - } - setErrorMessage(null); - - getContainer().getShell().getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - CheckboxTreeViewer elementViewer = getElementViewer(); - Object elementViewerInput = createElementViewerInput(); - elementViewer.setInput(elementViewerInput); - if (elementViewerInput != null) { - elementViewer.expandToLevel(2); - setAllChecked(elementViewer, false, true); - fValidatedFilePath = getFilePathValue(); - } - - updatePageCompletion(); - } - }); - } - - private boolean isFilePathValid() { - return new File(getFilePathValue()).exists(); - } - - /** - * Finish the wizard page - * - * @return true on success - */ - public boolean finish() { - if (!checkForOverwrite()) { - return false; - } - - saveWidgetValues(); - - Object input = getElementViewer().getInput(); - TracePackageElement[] traceElements = (TracePackageElement[]) input; - final TracePackageImportOperation importOperation = new TracePackageImportOperation(fValidatedFilePath, traceElements, fTmfTraceFolder); - - try { - getContainer().run(true, true, new IRunnableWithProgress() { - @Override - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - importOperation.run(monitor); - } - }); - - IStatus status = importOperation.getStatus(); - if (status.getSeverity() == IStatus.ERROR) { - handleErrorStatus(status); - } - - } catch (InvocationTargetException e) { - handleError(Messages.ImportTracePackageWizardPage_ErrorOperation, e); - } catch (InterruptedException e) { - } - - return importOperation.getStatus().getSeverity() == IStatus.OK; - } - - private boolean checkForOverwrite() { - TracePackageElement[] traceElements = (TracePackageElement[]) getElementViewer().getInput(); - List noImportTraces = new ArrayList<>(); - boolean noToAll = false; - for (TracePackageElement packageElement : traceElements) { - TracePackageTraceElement traceElement = (TracePackageTraceElement) packageElement; - if (!AbstractTracePackageOperation.isFilesChecked(traceElement)) { - continue; - } - - if (noToAll) { - noImportTraces.add(traceElement); - continue; - } - - if (traceExists(traceElement)) { - int returnCode = promptForOverwrite(traceElement.getDestinationElementPath()); - // The return code is an index to a button in the dialog but the - // 'X' button in the window corner is not considered a button - // therefore it returns -1 and unfortunately, there is no - // constant for that. - if (returnCode < 0) { - return false; - } - - final String[] response = new String[] { IDialogConstants.NO_TO_ALL_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.YES_TO_ALL_LABEL, IDialogConstants.YES_LABEL }; - if (response[returnCode].equals(IDialogConstants.YES_TO_ALL_LABEL)) { - break; - } else if (response[returnCode].equals(IDialogConstants.NO_TO_ALL_LABEL)) { - noToAll = true; - noImportTraces.add(traceElement); - } else if (response[returnCode].equals(IDialogConstants.NO_LABEL)) { - noImportTraces.add(traceElement); - } - } - } - - // Unselect the traces that the user decided not to import - for (TracePackageTraceElement t : noImportTraces) { - for (TracePackageElement e : t.getChildren()) { - if (e instanceof TracePackageFilesElement) { - ((TracePackageFilesElement) e).setChecked(false); - } - } - } - - return true; - } - - private boolean traceExists(TracePackageTraceElement traceElement) { - IResource traceRes = fTmfTraceFolder.getResource().findMember(traceElement.getDestinationElementPath()); - return traceRes != null; - } - - private int promptForOverwrite(String traceName) { - final MessageDialog dialog = new MessageDialog(getContainer() - .getShell(), null, null, MessageFormat.format(Messages.ImportTracePackageWizardPage_AlreadyExists, traceName), - MessageDialog.QUESTION, new String[] { - IDialogConstants.NO_TO_ALL_LABEL, - IDialogConstants.NO_LABEL, - IDialogConstants.YES_TO_ALL_LABEL, - IDialogConstants.YES_LABEL, - }, 3) { - @Override - protected int getShellStyle() { - return super.getShellStyle() | SWT.SHEET; - } - }; - return dialog.open(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ManifestReader.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ManifestReader.java deleted file mode 100644 index e2e320511f..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/ManifestReader.java +++ /dev/null @@ -1,191 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.importexport; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.xml.XMLConstants; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.ITracePackageConstants; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageBookmarkElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFileElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFilesElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -/** - * Reads a manifest from an input stream - * - * @author Marc-Andre Laperle - */ -public class ManifestReader { - - private static final String SCHEMA_FOLDER_NAME = "schema"; //$NON-NLS-1$ - private static final String EXPORT_MANIFEST_SCHEMA_FILE_NAME = "export-manifest.xsd"; //$NON-NLS-1$ - private static final TracePackageElement [] EMPTY_ARRAY = new TracePackageElement[0]; - - /** - * Validate the content of a manifest from an input stream - * - * @param input the input stream to validate from - * @throws IOException on error - */ - public static void validateManifest(InputStream input) throws IOException - { - URL schemaFileUrl = FileLocator.find(Activator.getDefault().getBundle(), new Path(SCHEMA_FOLDER_NAME).append(EXPORT_MANIFEST_SCHEMA_FILE_NAME), null); - if (schemaFileUrl == null) { - throw new IOException(MessageFormat.format(Messages.TracePackageExtractManifestOperation_SchemaFileNotFound, EXPORT_MANIFEST_SCHEMA_FILE_NAME)); - } - - try { - SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - Schema schema = factory.newSchema(new StreamSource(schemaFileUrl.openStream())); - Validator validator = schema.newValidator(); - validator.validate(new StreamSource(input)); - } catch (SAXException e) { - throw new IOException(Messages.TracePackageExtractManifestOperation_ErrorManifestNotValid, e); - } catch (IOException e) { - throw new IOException(Messages.TracePackageExtractManifestOperation_ErrorManifestNotValid, e); - } - } - - /** - * Load package elements from a manifest (input stream) - * - * The manifest looks like this: - * - * - * - * - * - * - * - * - * - * - * - * See schema/export-manifest.xsd for details. - * - * @param inputStream - * the input stream that contains the manifest - * @return the loaded elements - * @throws IOException - * when an error occurs when parsing - * @throws SAXException - * when an error occurs when parsing - * @throws ParserConfigurationException - * when an error occurs when parsing - */ - public static TracePackageElement[] loadElementsFromManifest(InputStream inputStream) throws IOException, SAXException, ParserConfigurationException { - - List packageElements = new ArrayList<>(); - TracePackageElement element = null; - Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); - - NodeList traceElements = doc.getDocumentElement().getElementsByTagName(ITracePackageConstants.TRACE_ELEMENT); - for (int i = 0; i < traceElements.getLength(); i++) { - Node traceNode = traceElements.item(i); - if (traceNode.getNodeType() == Node.ELEMENT_NODE) { - Element traceElement = (Element) traceNode; - String traceName = traceElement.getAttribute(ITracePackageConstants.TRACE_NAME_ATTRIB); - String traceType = traceElement.getAttribute(ITracePackageConstants.TRACE_TYPE_ATTRIB); - element = new TracePackageTraceElement(null, traceName, traceType); - - List children = new ArrayList<>(); - NodeList fileElements = traceElement.getElementsByTagName(ITracePackageConstants.TRACE_FILE_ELEMENT); - for (int j = 0; j < fileElements.getLength(); j++) { - Node fileNode = fileElements.item(j); - if (fileNode.getNodeType() == Node.ELEMENT_NODE) { - Element fileElement = (Element) fileNode; - String fileName = fileElement.getAttribute(ITracePackageConstants.TRACE_FILE_NAME_ATTRIB); - children.add(new TracePackageFilesElement(element, fileName)); - } - } - - TracePackageSupplFilesElement supplFilesElement = new TracePackageSupplFilesElement(element); - - // Supplementary files - List suppFiles = new ArrayList<>(); - NodeList suppFilesElements = traceElement.getElementsByTagName(ITracePackageConstants.SUPPLEMENTARY_FILE_ELEMENT); - for (int j = 0; j < suppFilesElements.getLength(); j++) { - Node suppFileNode = suppFilesElements.item(j); - if (suppFileNode.getNodeType() == Node.ELEMENT_NODE) { - Element suppFileElement = (Element) suppFileNode; - String fileName = suppFileElement.getAttribute(ITracePackageConstants.SUPPLEMENTARY_FILE_NAME_ATTRIB); - TracePackageSupplFileElement supplFile = new TracePackageSupplFileElement(fileName, supplFilesElement); - suppFiles.add(supplFile); - } - } - - if (!suppFiles.isEmpty()) { - supplFilesElement.setChildren(suppFiles.toArray(EMPTY_ARRAY)); - children.add(supplFilesElement); - } - - // bookmarks - List> bookmarkAttribs = new ArrayList<>(); - NodeList bookmarksElements = traceElement.getElementsByTagName(ITracePackageConstants.BOOKMARKS_ELEMENT); - for (int j = 0; j < bookmarksElements.getLength(); j++) { - Node bookmarksNode = bookmarksElements.item(j); - if (bookmarksNode.getNodeType() == Node.ELEMENT_NODE) { - NodeList bookmarkElements = traceElement.getElementsByTagName(ITracePackageConstants.BOOKMARK_ELEMENT); - for (int k = 0; k < bookmarkElements.getLength(); k++) { - Node bookmarkNode = bookmarkElements.item(k); - if (bookmarkNode.getNodeType() == Node.ELEMENT_NODE) { - Element bookmarkElement = (Element) bookmarkNode; - NamedNodeMap attributesMap = bookmarkElement.getAttributes(); - Map attribs = new HashMap<>(); - for (int l = 0; l < attributesMap.getLength(); l++) { - Node item = attributesMap.item(l); - attribs.put(item.getNodeName(), item.getNodeValue()); - } - bookmarkAttribs.add(attribs); - } - } - } - } - if (!bookmarkAttribs.isEmpty()) { - children.add(new TracePackageBookmarkElement(element, bookmarkAttribs)); - } - - element.setChildren(children.toArray(EMPTY_ARRAY)); - packageElements.add(element); - } - } - return packageElements.toArray(EMPTY_ARRAY); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/Messages.java deleted file mode 100644 index f8a6f0bf4e..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/Messages.java +++ /dev/null @@ -1,239 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.importexport; - -import org.eclipse.osgi.util.NLS; - -/** - * Messages for the trace package export wizard - * - * @author Marc-Andre Laperle - */ -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.importexport.messages"; //$NON-NLS-1$ - - /** - * The message under the select trace wizard page title - */ - public static String ExportTracePackageSelectTraceWizardPage_ChooseTrace; - - /** - * The description of the project selection list - */ - public static String ExportTracePackageSelectTraceWizardPage_ProjectSelection; - - /** - * The description of the trace selection list - */ - public static String ExportTracePackageSelectTraceWizardPage_TraceSelection; - - /** - * Dialog text when target file already exists - */ - public static String ExportTracePackageWizardPage_AlreadyExitst; - - /** - * The approximate size label - */ - public static String ExportTracePackageWizardPage_ApproximateSizeLbl; - - /** - * The message under the wizard page title - */ - public static String ExportTracePackageWizardPage_ChooseContent; - - /** - * Text for the compress contents checkbox - */ - public static String ExportTracePackageWizardPage_CompressContents; - - /** - * Text for the first column (content) - */ - public static String ExportTracePackageWizardPage_ContentColumnName; - - /** - * Text for the options group - */ - public static String ExportTracePackageWizardPage_Options; - - /** - * Text for the tar format option - */ - public static String ExportTracePackageWizardPage_SaveInTarFormat; - - /** - * Text for the zip format option - */ - public static String ExportTracePackageWizardPage_SaveInZipFormat; - - /** - * Byte units - */ - public static String ExportTracePackageWizardPage_SizeByte; - - /** - * Text for the second column (size) - */ - public static String ExportTracePackageWizardPage_SizeColumnName; - - /** - * Gigabyte units - */ - public static String ExportTracePackageWizardPage_SizeGigabyte; - - /** - * Kilobyte units - */ - public static String ExportTracePackageWizardPage_SizeKilobyte; - - /** - * Megabyte units - */ - public static String ExportTracePackageWizardPage_SizeMegabyte; - - /** - * Terabyte units - */ - public static String ExportTracePackageWizardPage_SizeTerabyte; - - /** - * Title for the wizard page - */ - public static String ExportTracePackageWizardPage_Title; - - /** - * Label for the file path - */ - public static String ExportTracePackageWizardPage_ToArchive; - - /** - * Dialog text when a trace with the same name already exists - */ - public static String ImportTracePackageWizardPage_AlreadyExists; - - /** - * Title for the import page - */ - public static String ImportTracePackageWizardPage_Title; - - /** - * Text for the source archive label - */ - public static String ImportTracePackageWizardPage_FromArchive; - - /** - * Text for the reading package job - */ - public static String ImportTracePackageWizardPage_ReadingPackage; - - /** - * Message when file is not found - */ - public static String ImportTracePackageWizardPage_ErrorFileNotFound; - - /** - * Message when trace type could not be set - */ - public static String ImportTracePackageWizardPage_ErrorSettingTraceType; - - /** - * Message when the trace could not be found after importing the files - */ - public static String ImportTracePackageWizardPage_ErrorFindingImportedTrace; - - /** - * The message displayed under the title - */ - public static String ImportTracePackageWizardPage_Message; - - /** - * Generic error message for the import operation - */ - public static String ImportTracePackageWizardPage_ErrorOperation; - - /** - * Project text label - */ - public static String ImportTracePackageWizardPage_Project; - - /** - * The select project button text - */ - public static String ImportTracePackageWizardPage_SelectProjectButton; - - /** - * The select project dialog title - */ - public static String ImportTracePackageWizardPage_SelectProjectDialogTitle; - - /** - * Text for the generating package job - */ - public static String TracePackageExportOperation_GeneratingPackage; - - /** - * Text when error occurs creating a bookmark - */ - public static String TracePackageImportOperation_ErrorCreatingBookmark; - - /** - * Text for the detecting trace type job - */ - public static String TracePackageImportOperation_DetectingTraceType; - - /** - * Text when error occurs creating a bookmark file - */ - public static String TracePackageImportOperation_ErrorCreatingBookmarkFile; - - /** - * Text for the importing package job - */ - public static String TracePackageImportOperation_ImportingPackage; - - /** - * Text when error occurs when the manifest is not found in the archive - */ - public static String TracePackageExtractManifestOperation_ErrorManifestNotFound; - - /** - * Text when error occurs when the manifest is not valid - */ - public static String TracePackageExtractManifestOperation_ErrorManifestNotValid; - - /** - * Generic error message when reading the manifest - */ - public static String TracePackageExtractManifestOperation_ErrorReadingManifest; - - /** - * Error message when the file is an invalid format - */ - public static String TracePackageExtractManifestOperation_InvalidFormat; - - /** - * Error when the schema file cannot be found to validate the export - * manifest - */ - public static String TracePackageExtractManifestOperation_SchemaFileNotFound; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageExportOperation.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageExportOperation.java deleted file mode 100644 index 86347a33c4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageExportOperation.java +++ /dev/null @@ -1,304 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.importexport; - -import java.io.ByteArrayInputStream; -import java.io.StringWriter; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; - -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.jface.operation.ModalContext; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageOperation; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.ITracePackageConstants; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageBookmarkElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFileElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFilesElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TraceUtils; -import org.eclipse.ui.internal.wizards.datatransfer.ArchiveFileExportOperation; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -/** - * An operation that exports a trace package to an archive - * - * @author Marc-Andre Laperle - */ -@SuppressWarnings("restriction") -public class TracePackageExportOperation extends AbstractTracePackageOperation { - - private static final String TRACE_EXPORT_TEMP_FOLDER = ".traceExport"; //$NON-NLS-1$ - - private final TracePackageTraceElement[] fTraceExportElements; - private final boolean fUseCompression; - private final boolean fUseTar; - private final Set fResources; - private IFolder fExportFolder; - - /** - * Constructs a new export operation - * - * @param traceExportElements - * the trace elements to be exported - * @param useCompression - * whether or not to use compression - * @param useTar - * use tar format or zip - * @param fileName - * the output file name - */ - public TracePackageExportOperation(TracePackageTraceElement[] traceExportElements, boolean useCompression, boolean useTar, String fileName) { - super(fileName); - fTraceExportElements = traceExportElements; - fUseCompression = useCompression; - fUseTar = useTar; - fResources = new HashSet<>(); - } - - /** - * Run the operation. The status (result) of the operation can be obtained - * with {@link #getStatus} - * - * @param progressMonitor - * the progress monitor to use to display progress and receive - * requests for cancellation - */ - @Override - public void run(IProgressMonitor progressMonitor) { - - try { - int totalWork = getNbCheckedElements(fTraceExportElements) * 2; - progressMonitor.beginTask(Messages.TracePackageExportOperation_GeneratingPackage, totalWork); - - fExportFolder = createExportFolder(progressMonitor); - - Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); - Element createElement = doc.createElement(ITracePackageConstants.TMF_EXPORT_ELEMENT); - Node tmfNode = doc.appendChild(createElement); - - for (TracePackageTraceElement tracePackageElement : fTraceExportElements) { - if (!isFilesChecked(tracePackageElement)) { - continue; - } - - exportTrace(progressMonitor, tmfNode, tracePackageElement); - } - - Transformer transformer = TransformerFactory.newInstance().newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ - transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); //$NON-NLS-1$ //$NON-NLS-2$ - DOMSource source = new DOMSource(doc); - StringWriter buffer = new StringWriter(); - StreamResult result = new StreamResult(buffer); - transformer.transform(source, result); - String content = buffer.getBuffer().toString(); - - ModalContext.checkCanceled(progressMonitor); - - exportManifest(content); - - setStatus(exportToArchive(progressMonitor, totalWork)); - - fExportFolder.delete(true, new SubProgressMonitor(progressMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); - - progressMonitor.done(); - - } catch (Exception e) { - if (e instanceof InterruptedException) { - setStatus(Status.CANCEL_STATUS); - } else { - setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, e)); - } - } - } - - private IFolder createExportFolder(IProgressMonitor monitor) throws CoreException { - IFolder folder = fTraceExportElements[0].getTraceElement().getProject().getResource().getFolder(TRACE_EXPORT_TEMP_FOLDER); - if (folder.exists()) { - folder.delete(true, null); - } - folder.create(IResource.FORCE | IResource.HIDDEN, true, new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); - return folder; - } - - private void exportTrace(IProgressMonitor monitor, Node tmfNode, TracePackageTraceElement tracePackageElement) throws InterruptedException, CoreException { - TmfTraceElement traceElement = tracePackageElement.getTraceElement(); - Element traceXmlElement = tmfNode.getOwnerDocument().createElement(ITracePackageConstants.TRACE_ELEMENT); - traceXmlElement.setAttribute(ITracePackageConstants.TRACE_NAME_ATTRIB, traceElement.getResource().getName()); - traceXmlElement.setAttribute(ITracePackageConstants.TRACE_TYPE_ATTRIB, traceElement.getTraceType()); - Node traceNode = tmfNode.appendChild(traceXmlElement); - - for (TracePackageElement element : tracePackageElement.getChildren()) { - ModalContext.checkCanceled(monitor); - if (!element.isChecked()) { - continue; - } - - if (element instanceof TracePackageSupplFilesElement) { - exportSupplementaryFiles(monitor, traceNode, traceElement, (TracePackageSupplFilesElement) element); - } else if (element instanceof TracePackageBookmarkElement) { - exportBookmarks(monitor, traceNode, (TracePackageBookmarkElement) element); - } else if (element instanceof TracePackageFilesElement) { - exportTraceFiles(monitor, traceNode, (TracePackageFilesElement) element); - } - - monitor.worked(1); - } - } - - private void exportSupplementaryFiles(IProgressMonitor monitor, Node traceNode, TmfTraceElement traceElement, TracePackageSupplFilesElement element) throws InterruptedException, CoreException { - Document doc = traceNode.getOwnerDocument(); - if (element.getChildren().length > 0) { - - IPath projectPath = traceElement.getProject().getPath(); - - for (TracePackageElement child : element.getChildren()) { - TracePackageSupplFileElement supplFile = (TracePackageSupplFileElement) child; - ModalContext.checkCanceled(monitor); - IResource res = supplFile.getResource(); - // project/.tracing/A/B/statistics.ht -> .tracing/A/B/statistics.ht - IPath relativeToExportFolder = res.getFullPath().makeRelativeTo(projectPath); - - // project/.traceExport/.tracing/A/B - IFolder folder = fExportFolder.getFolder(relativeToExportFolder.removeLastSegments(1)); - TraceUtils.createFolder(folder, new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); - - res.refreshLocal(0, new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); - createExportResource(folder, res); - Element suppFileElement = doc.createElement(ITracePackageConstants.SUPPLEMENTARY_FILE_ELEMENT); - - suppFileElement.setAttribute(ITracePackageConstants.SUPPLEMENTARY_FILE_NAME_ATTRIB, relativeToExportFolder.toString()); - traceNode.appendChild(suppFileElement); - } - - IFolder suppFilesFolder = fExportFolder.getFolder(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER_NAME); - fResources.add(suppFilesFolder); - } - } - - private void exportTraceFiles(IProgressMonitor monitor, Node traceNode, TracePackageFilesElement element) throws CoreException { - Document doc = traceNode.getOwnerDocument(); - TmfTraceElement traceElement = ((TracePackageTraceElement) element.getParent()).getTraceElement(); - IResource resource = traceElement.getResource(); - IPath traceFolderPath = traceElement.getProject().getTracesFolder().getPath(); - - // project/Traces/A/B/Kernel -> A/B/Kernel - IPath relativeToExportFolder = resource.getFullPath().makeRelativeTo(traceFolderPath); - - // project/.traceExport/A/B - IFolder folder = fExportFolder.getFolder(relativeToExportFolder.removeLastSegments(1)); - TraceUtils.createFolder(folder, new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); - - createExportResource(folder, resource); - Element fileElement = doc.createElement(ITracePackageConstants.TRACE_FILE_ELEMENT); - - fileElement.setAttribute(ITracePackageConstants.TRACE_FILE_NAME_ATTRIB, relativeToExportFolder.toString()); - traceNode.appendChild(fileElement); - - // Always export the top-most folder containing the trace or the trace itself - IResource exportedResource = fExportFolder.findMember(relativeToExportFolder.segment(0)); - fResources.add(exportedResource); - } - - /** - * Creates a linked resource in the specified folder - * - * @param exportFolder the folder that will contain the linked resource - * @param res the resource to export - * @throws CoreException when createLink fails - * @return the created linked resource - */ - private static IResource createExportResource(IFolder exportFolder, IResource res) throws CoreException { - IResource ret = null; - // Note: The resources cannot be HIDDEN or else they are ignored by ArchiveFileExportOperation - if (res instanceof IFolder) { - IFolder folder = exportFolder.getFolder(res.getName()); - folder.createLink(res.getLocationURI(), IResource.NONE, null); - ret = folder; - } else if (res instanceof IFile) { - IFile file = exportFolder.getFile(res.getName()); - file.createLink(res.getLocationURI(), IResource.NONE, null); - ret = file; - } - return ret; - } - - private static void exportBookmarks(IProgressMonitor monitor, Node traceNode, TracePackageBookmarkElement element) throws CoreException, InterruptedException { - Document doc = traceNode.getOwnerDocument(); - IFile bookmarksFile = ((TracePackageTraceElement) element.getParent()).getTraceElement().getBookmarksFile(); - if (bookmarksFile != null && bookmarksFile.exists()) { - IMarker[] findMarkers = bookmarksFile.findMarkers(IMarker.BOOKMARK, false, IResource.DEPTH_ZERO); - if (findMarkers.length > 0) { - Element bookmarksXmlElement = doc.createElement(ITracePackageConstants.BOOKMARKS_ELEMENT); - Node bookmarksNode = traceNode.appendChild(bookmarksXmlElement); - - for (IMarker marker : findMarkers) { - ModalContext.checkCanceled(monitor); - - Element singleBookmarkXmlElement = doc.createElement(ITracePackageConstants.BOOKMARK_ELEMENT); - for (String key : marker.getAttributes().keySet()) { - singleBookmarkXmlElement.setAttribute(key, marker.getAttribute(key).toString()); - } - - bookmarksNode.appendChild(singleBookmarkXmlElement); - } - } - } - } - - private void exportManifest(String content) throws CoreException { - IFile file = fExportFolder.getFile(ITracePackageConstants.MANIFEST_FILENAME); - ByteArrayInputStream inputStream = new ByteArrayInputStream(content.getBytes()); - if (file.exists()) { - file.setContents(inputStream, IResource.FORCE, null); - } else { - file.create(inputStream, IResource.FORCE | IResource.HIDDEN, null); - } - fResources.add(file); - } - - private IStatus exportToArchive(IProgressMonitor monitor, int totalWork) throws InvocationTargetException, InterruptedException { - ArchiveFileExportOperation op = new ArchiveFileExportOperation(new ArrayList<>(fResources), getFileName()); - op.setCreateLeadupStructure(false); - op.setUseCompression(fUseCompression); - op.setUseTarFormat(fUseTar); - op.run(new SubProgressMonitor(monitor, totalWork / 2, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); - - return op.getStatus(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageExtractManifestOperation.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageExtractManifestOperation.java deleted file mode 100644 index 1596872726..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageExtractManifestOperation.java +++ /dev/null @@ -1,142 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.importexport; - -import java.io.InputStream; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.operation.ModalContext; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageOperation; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.ITracePackageConstants; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement; - -/** - * An operation that extracts information from the manifest located in an - * archive - * - * @author Marc-Andre Laperle - */ -public class TracePackageExtractManifestOperation extends AbstractTracePackageOperation { - - /** - * Constructs a new import operation for reading the manifest - * - * @param fileName - * the output file name - */ - public TracePackageExtractManifestOperation(String fileName) { - super(fileName); - } - - /** - * Run extract the manifest operation. The status (result) of the operation - * can be obtained with {@link #getStatus} - * - * @param progressMonitor - * the progress monitor to use to display progress and receive - * requests for cancellation - */ - @Override - public void run(IProgressMonitor progressMonitor) { - TracePackageElement[] elements = null; - try { - progressMonitor.worked(1); - ArchiveFile archiveFile = getSpecifiedArchiveFile(); - progressMonitor.worked(1); - if (archiveFile == null) { - setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.TracePackageExtractManifestOperation_InvalidFormat)); - return; - } - - Enumeration entries = archiveFile.entries(); - - boolean found = false; - while (entries.hasMoreElements()) { - ModalContext.checkCanceled(progressMonitor); - - ArchiveEntry entry = (ArchiveEntry) entries.nextElement(); - IPath p = new Path(entry.getName()); - //Remove project name - p = p.removeFirstSegments(1); - - if (entry.getName().endsWith(ITracePackageConstants.MANIFEST_FILENAME)) { - found = true; - InputStream inputStream = archiveFile.getInputStream(entry); - ManifestReader.validateManifest(inputStream); - - inputStream = archiveFile.getInputStream(entry); - elements = ManifestReader.loadElementsFromManifest(inputStream); - break; - } - - progressMonitor.worked(1); - } - - if (found) { - setStatus(Status.OK_STATUS); - } - else { - elements = generateElementsFromArchive(); - if (elements.length > 0) { - setStatus(Status.OK_STATUS); - } else { - setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, MessageFormat.format(Messages.TracePackageExtractManifestOperation_ErrorManifestNotFound, ITracePackageConstants.MANIFEST_FILENAME))); - } - } - - setResultElements(elements); - - } catch (InterruptedException e) { - setStatus(Status.CANCEL_STATUS); - } catch (Exception e) { - setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.TracePackageExtractManifestOperation_ErrorReadingManifest, e)); - } - } - - private TracePackageElement[] generateElementsFromArchive() { - ArchiveFile archiveFile = getSpecifiedArchiveFile(); - Enumeration entries = archiveFile.entries(); - Set traceFileNames = new HashSet<>(); - while (entries.hasMoreElements()) { - ArchiveEntry entry = (ArchiveEntry) entries.nextElement(); - String entryName = entry.getName(); - IPath fullArchivePath = new Path(entryName); - if (!fullArchivePath.hasTrailingSeparator() && fullArchivePath.segmentCount() > 0) { - traceFileNames.add(fullArchivePath.segment(0)); - } - } - - List packageElements = new ArrayList<>(); - for (String traceFileName : traceFileNames) { - TracePackageTraceElement traceElement = new TracePackageTraceElement(null, traceFileName, null); - traceElement.setChildren(new TracePackageElement[] { new TracePackageFilesElement(traceElement, traceFileName) }); - packageElements.add(traceElement); - } - - return packageElements.toArray(new TracePackageElement[] {}); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageImportOperation.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageImportOperation.java deleted file mode 100644 index b2e9587123..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageImportOperation.java +++ /dev/null @@ -1,487 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - * Patrick Tasse - Add support for source location - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.importexport; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.core.runtime.URIUtil; -import org.eclipse.jface.operation.ModalContext; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageOperation; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageBookmarkElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFileElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFilesElement; -import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceImportException; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; -import org.eclipse.linuxtools.tmf.core.util.Pair; -import org.eclipse.linuxtools.tmf.ui.editors.TmfEventsEditor; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceTypeUIUtils; -import org.eclipse.ui.dialogs.IOverwriteQuery; -import org.eclipse.ui.ide.IDE; -import org.eclipse.ui.internal.wizards.datatransfer.TarException; -import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider; -import org.eclipse.ui.wizards.datatransfer.ImportOperation; - -/** - * An operation that imports a trace package from an archive - * - * @author Marc-Andre Laperle - */ -@SuppressWarnings("restriction") -public class TracePackageImportOperation extends AbstractTracePackageOperation implements IOverwriteQuery { - - private final TracePackageElement[] fImportTraceElements; - private final TmfTraceFolder fTmfTraceFolder; - - /** - * Constructs a new import operation - * - * @param importTraceElements - * the trace element to be imported - * @param fileName - * the output file name - * @param tmfTraceFolder - * the destination folder - */ - public TracePackageImportOperation(String fileName, TracePackageElement[] importTraceElements, TmfTraceFolder tmfTraceFolder) { - super(fileName); - fImportTraceElements = importTraceElements; - fTmfTraceFolder = tmfTraceFolder; - } - - private class ImportProvider implements IImportStructureProvider { - - private Exception fException; - - @Override - public List getChildren(Object element) { - return null; - } - - @Override - public InputStream getContents(Object element) { - InputStream inputStream = null; - // We can add throws - try { - inputStream = ((ArchiveProviderElement) element).getContents(); - } catch (IOException e) { - fException = e; - } catch (TarException e) { - fException = e; - } - return inputStream; - } - - @Override - public String getFullPath(Object element) { - return ((ArchiveProviderElement) element).getFullPath(); - } - - @Override - public String getLabel(Object element) { - return ((ArchiveProviderElement) element).getLabel(); - } - - @Override - public boolean isFolder(Object element) { - return ((ArchiveProviderElement) element).isFolder(); - } - - public Exception getException() { - return fException; - } - } - - private class ArchiveProviderElement { - - private final String fPath; - private final String fLabel; - - private ArchiveFile fArchiveFile; - private ArchiveEntry fEntry; - - public ArchiveProviderElement(String destinationPath, String label, ArchiveFile archiveFile, ArchiveEntry entry) { - fPath = destinationPath; - fLabel = label; - this.fArchiveFile = archiveFile; - this.fEntry = entry; - } - - public InputStream getContents() throws TarException, IOException { - return fArchiveFile.getInputStream(fEntry); - } - - public String getFullPath() { - return fPath; - } - - public String getLabel() { - return fLabel; - } - - public boolean isFolder() { - return false; - } - } - - /** - * Run the operation. The status (result) of the operation can be obtained - * with {@link #getStatus} - * - * @param progressMonitor - * the progress monitor to use to display progress and receive - * requests for cancellation - */ - @Override - public void run(IProgressMonitor progressMonitor) { - int totalWork = getNbCheckedElements(fImportTraceElements) * 2; - progressMonitor.beginTask(Messages.TracePackageImportOperation_ImportingPackage, totalWork); - doRun(progressMonitor); - progressMonitor.done(); - } - - private void doRun(IProgressMonitor progressMonitor) { - try { - setStatus(deleteExistingTraces(progressMonitor)); - if (getStatus().getSeverity() != IStatus.OK) { - return; - } - - TracePackageFilesElement traceFilesElement = null; - for (TracePackageElement packageElement : fImportTraceElements) { - TracePackageTraceElement traceElement = (TracePackageTraceElement) packageElement; - if (!isFilesChecked(packageElement)) { - continue; - } - - TracePackageElement[] children = traceElement.getChildren(); - for (TracePackageElement element : children) { - ModalContext.checkCanceled(progressMonitor); - - if (element instanceof TracePackageFilesElement) { - traceFilesElement = (TracePackageFilesElement) element; - setStatus(importTraceFiles(traceFilesElement, traceElement, progressMonitor)); - - } else if (element instanceof TracePackageSupplFilesElement) { - TracePackageSupplFilesElement suppFilesElement = (TracePackageSupplFilesElement) element; - setStatus(importSupplFiles(suppFilesElement, traceElement, progressMonitor)); - } - - if (getStatus().getSeverity() != IStatus.OK) { - return; - } - } - } - - } catch (InterruptedException e) { - setStatus(Status.CANCEL_STATUS); - } - } - - /** - * Returns whether or not the Files element is checked under the given trace - * package element - * - * @param tracePackageElement - * the trace package element - * @return whether or not the Files element is checked under the given trace - * package element - */ - public static boolean isFilesChecked(TracePackageElement tracePackageElement) { - for (TracePackageElement element : tracePackageElement.getChildren()) { - if (element instanceof TracePackageFilesElement) { - return element.isChecked(); - } - } - - return false; - } - - /** - * Return the matching TmfTraceElement for a given trace element. - */ - private TmfTraceElement getMatchingTraceElement(TracePackageTraceElement tracePackageElement) { - IPath tracePath = fTmfTraceFolder.getPath().append(tracePackageElement.getDestinationElementPath()); - List traces = fTmfTraceFolder.getTraces(); - for (TmfTraceElement t : traces) { - if (t.getPath().equals(tracePath)) { - return t; - } - } - - return null; - } - - private IStatus deleteExistingTraces(IProgressMonitor progressMonitor) { - for (TracePackageElement packageElement : fImportTraceElements) { - TracePackageTraceElement traceElement = (TracePackageTraceElement) packageElement; - if (!isFilesChecked(traceElement)) { - continue; - } - - TmfTraceElement existingTrace = getMatchingTraceElement(traceElement); - if (existingTrace != null) { - try { - existingTrace.delete(new SubProgressMonitor(progressMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); - } catch (CoreException e) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, e); - } - } - } - - return Status.OK_STATUS; - } - - private void importBookmarks(IResource traceRes, TracePackageTraceElement traceElement, IProgressMonitor monitor) { - for (TracePackageElement o : traceElement.getChildren()) { - if (o instanceof TracePackageBookmarkElement && o.isChecked()) { - - // Get element - IFile bookmarksFile = null; - TmfTraceElement tmfTraceElement = getMatchingTraceElement(traceElement); - if (tmfTraceElement != null) { - try { - bookmarksFile = tmfTraceElement.createBookmarksFile(); - - // Make sure that if a bookmark is double-clicked first - // before opening the trace, it opens the right editor - - // Get the editor id from the extension point - String traceEditorId = tmfTraceElement.getEditorId(); - final String editorId = (traceEditorId != null) ? traceEditorId : TmfEventsEditor.ID; - IDE.setDefaultEditor(bookmarksFile, editorId); - - } catch (CoreException e) { - Activator.getDefault().logError(MessageFormat.format(Messages.TracePackageImportOperation_ErrorCreatingBookmarkFile, traceRes.getName()), e); - } - } - - if (bookmarksFile == null) { - break; - } - - TracePackageBookmarkElement bookmarkElement = (TracePackageBookmarkElement) o; - - List> bookmarks = bookmarkElement.getBookmarks(); - for (Map attrs : bookmarks) { - IMarker createMarker = null; - try { - createMarker = bookmarksFile.createMarker(IMarker.BOOKMARK); - } catch (CoreException e) { - Activator.getDefault().logError(MessageFormat.format(Messages.TracePackageImportOperation_ErrorCreatingBookmark, traceRes.getName()), e); - } - if (createMarker != null && createMarker.exists()) { - try { - for (String key : attrs.keySet()) { - String value = attrs.get(key); - if (key.equals(IMarker.LOCATION)) { - createMarker.setAttribute(IMarker.LOCATION, Integer.valueOf(value).intValue()); - } else { - createMarker.setAttribute(key, value); - } - } - } catch (CoreException e) { - Activator.getDefault().logError(MessageFormat.format(Messages.TracePackageImportOperation_ErrorCreatingBookmark, traceRes.getName()), e); - } - } - } - } - } - - monitor.worked(1); - } - - private IStatus importTraceFiles(TracePackageFilesElement traceFilesElement, TracePackageTraceElement traceElement, IProgressMonitor monitor) { - List> fileNameAndLabelPairs = new ArrayList<>(); - - String sourceName = traceFilesElement.getFileName(); - String destinationName = traceElement.getImportName(); - - fileNameAndLabelPairs.add(new Pair<>(sourceName, destinationName)); - - IPath containerPath = fTmfTraceFolder.getPath(); - IStatus status = importFiles(getSpecifiedArchiveFile(), fileNameAndLabelPairs, containerPath, Path.EMPTY, monitor); - if (getStatus().getSeverity() != IStatus.OK) { - return status; - } - - // We need to set the trace type before importing the supplementary files so we do it here - IResource traceRes = fTmfTraceFolder.getResource().findMember(traceElement.getDestinationElementPath()); - if (traceRes == null || !traceRes.exists()) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, MessageFormat.format(Messages.ImportTracePackageWizardPage_ErrorFindingImportedTrace, destinationName)); - } - - TraceTypeHelper traceType = null; - String traceTypeStr = traceElement.getTraceType(); - if (traceTypeStr != null) { - traceType = TmfTraceType.getTraceType(traceTypeStr); - if (traceType == null) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, MessageFormat.format(Messages.ImportTracePackageWizardPage_ErrorSettingTraceType, traceElement.getTraceType(), destinationName)); - } - } else { - try { - monitor.subTask(MessageFormat.format(Messages.TracePackageImportOperation_DetectingTraceType, destinationName)); - traceType = TmfTraceTypeUIUtils.selectTraceType(traceRes.getLocation().toOSString(), null, null); - } catch (TmfTraceImportException e) { - // Could not figure out the type - } - } - - if (traceType != null) { - try { - TmfTraceTypeUIUtils.setTraceType(traceRes, traceType); - } catch (CoreException e) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, MessageFormat.format(Messages.ImportTracePackageWizardPage_ErrorSettingTraceType, traceElement.getTraceType(), destinationName), e); - } - } - - importBookmarks(traceRes, traceElement, monitor); - - try { - URI uri = new File(getFileName()).toURI(); - IPath entryPath = new Path(traceFilesElement.getFileName()); - if (traceRes instanceof IFolder) { - entryPath = entryPath.addTrailingSeparator(); - } - String sourceLocation = URIUtil.toUnencodedString(URIUtil.toJarURI(uri, entryPath)); - traceRes.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation); - } catch (CoreException e) { - } - - return status; - } - - private IStatus importSupplFiles(TracePackageSupplFilesElement suppFilesElement, TracePackageTraceElement traceElement, IProgressMonitor monitor) { - List> fileNameAndLabelPairs = new ArrayList<>(); - for (TracePackageElement child : suppFilesElement.getChildren()) { - TracePackageSupplFileElement supplFile = (TracePackageSupplFileElement) child; - fileNameAndLabelPairs.add(new Pair<>(supplFile.getText(), new Path(supplFile.getText()).lastSegment())); - } - - if (!fileNameAndLabelPairs.isEmpty()) { - TmfTraceElement existingTrace = getMatchingTraceElement(traceElement); - if (existingTrace != null) { - ArchiveFile archiveFile = getSpecifiedArchiveFile(); - existingTrace.refreshSupplementaryFolder(); - // Project/Traces/A/B -> A/B - IPath traceFolderRelativePath = fTmfTraceFolder.getPath().makeRelativeTo(fTmfTraceFolder.getProject().getTracesFolder().getPath()); - // Project/.tracing/A/B/ - IFolder traceSupplementaryFolder = fTmfTraceFolder.getTraceSupplementaryFolder(traceFolderRelativePath.toString()); - IPath destinationContainerPath = traceSupplementaryFolder.getFullPath(); - // Remove the .tracing segment at the beginnin so that a file in folder .tracing/A/B/ imports destinationContainerPath/A/B/ - Path baseSourcePath = new Path(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER_NAME); - return importFiles(archiveFile, fileNameAndLabelPairs, destinationContainerPath, baseSourcePath, monitor); - } - } - - return Status.OK_STATUS; - } - - private IStatus importFiles(ArchiveFile archiveFile, List> fileNameAndLabelPairs, IPath destinationContainerPath, IPath baseSourcePath, IProgressMonitor monitor) { - List objects = new ArrayList<>(); - Enumeration entries = archiveFile.entries(); - while (entries.hasMoreElements()) { - ArchiveEntry entry = (ArchiveEntry) entries.nextElement(); - String entryName = entry.getName(); - IPath fullArchivePath = new Path(entryName); - if (fullArchivePath.hasTrailingSeparator()) { - // We only care about file entries as the folders will get created by the ImportOperation - continue; - } - - for (Pair fileNameAndLabel : fileNameAndLabelPairs) { - - // Examples: Traces/aaa/kernel/ .tracing/aaa/testtexttrace.txt/statistics.ht - IPath searchedArchivePath = new Path(fileNameAndLabel.getFirst()); - - // Check if this archive entry matches the searched file name at this archive location - boolean fileMatch = entryName.equalsIgnoreCase(searchedArchivePath.toString()); - // For example Traces/aaa/kernel/metadata matches Traces/aaa/kernel/ - boolean folderMatch = entryName.startsWith(searchedArchivePath + "/"); //$NON-NLS-1$ - - if (fileMatch || folderMatch) { - // .tracing/aaa/testtexttrace.txt/statistics.ht -> aaa/testtexttrace.txt/statistics.ht - IPath destinationPath = fullArchivePath.makeRelativeTo(baseSourcePath); - - // metadata statistics.ht - // We don't use the label when the entry is a folder match because the labels for individual files - // under the folder are not specified in the manifest so just use the last segment. - String resourceLabel = folderMatch ? fullArchivePath.lastSegment() : fileNameAndLabel.getSecond(); - - ArchiveProviderElement pe = new ArchiveProviderElement(destinationPath.toString(), resourceLabel, archiveFile, entry); - objects.add(pe); - break; - } - } - } - - ImportProvider provider = new ImportProvider(); - - ImportOperation operation = new ImportOperation(destinationContainerPath, - null, provider, this, - objects); - operation.setCreateContainerStructure(true); - operation.setOverwriteResources(true); - - try { - operation.run(new SubProgressMonitor(monitor, fileNameAndLabelPairs.size(), SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); - archiveFile.close(); - } catch (InvocationTargetException e) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, e); - } catch (InterruptedException e) { - return Status.CANCEL_STATUS; - } catch (IOException e) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, e); - } - - if (provider.getException() != null) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, provider.getException()); - } - - return operation.getStatus(); - } - - @Override - public String queryOverwrite(String pathString) { - // We always overwrite once we reach this point - return null; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/messages.properties deleted file mode 100644 index a5fc3ed167..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/importexport/messages.properties +++ /dev/null @@ -1,53 +0,0 @@ -############################################################################### -# Copyright (c) 2013 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Marc-Andre Laperle - Initial API and implementation -############################################################################### - -ExportTracePackageSelectTraceWizardPage_ChooseTrace=Choose traces to export -ExportTracePackageSelectTraceWizardPage_ProjectSelection=Project -ExportTracePackageSelectTraceWizardPage_TraceSelection=Traces -ExportTracePackageWizardPage_AlreadyExitst = Target file already exists. Would you like to overwrite it? -ExportTracePackageWizardPage_ApproximateSizeLbl=Approximate uncompressed size: {0} -ExportTracePackageWizardPage_ChooseContent=Choose the content to export -ExportTracePackageWizardPage_CompressContents=Co&mpress the contents of the file -ExportTracePackageWizardPage_ContentColumnName=Content -ExportTracePackageWizardPage_Options=Options -ExportTracePackageWizardPage_SaveInTarFormat=Sa&ve in tar format -ExportTracePackageWizardPage_SaveInZipFormat=Save in &zip format -ExportTracePackageWizardPage_SizeByte=B -ExportTracePackageWizardPage_SizeColumnName=Size -ExportTracePackageWizardPage_SizeGigabyte=GB -ExportTracePackageWizardPage_SizeKilobyte=KB -ExportTracePackageWizardPage_SizeMegabyte=MB -ExportTracePackageWizardPage_SizeTerabyte=TB -ExportTracePackageWizardPage_Title=Export trace package -ExportTracePackageWizardPage_ToArchive=To &archive file: -ImportTracePackageWizardPage_AlreadyExists=A trace with the name ''{0}'' already exists. Would you like to overwrite it? -ImportTracePackageWizardPage_ErrorFileNotFound=File does not exist -ImportTracePackageWizardPage_ErrorOperation=Error occurred during import trace operation -ImportTracePackageWizardPage_ErrorSettingTraceType=Error setting the type {0} for the trace {1} -ImportTracePackageWizardPage_ErrorFindingImportedTrace=Could not find the imported trace {0} in the workspace -ImportTracePackageWizardPage_FromArchive=From &archive file: -ImportTracePackageWizardPage_Message=Choose the content to import -ImportTracePackageWizardPage_Project=Into project: -ImportTracePackageWizardPage_ReadingPackage=Reading package -ImportTracePackageWizardPage_SelectProjectButton=Select -ImportTracePackageWizardPage_SelectProjectDialogTitle=Select project -ImportTracePackageWizardPage_Title=Import trace package -TracePackageExportOperation_GeneratingPackage=Generating package -TracePackageExtractManifestOperation_ErrorManifestNotFound=The required manifest file {0} could not be found. -TracePackageExtractManifestOperation_ErrorManifestNotValid=The manifest file is not valid. -TracePackageExtractManifestOperation_ErrorReadingManifest=An error occurred when reading the manifest -TracePackageExtractManifestOperation_InvalidFormat=The selected file is not a supported file format -TracePackageExtractManifestOperation_SchemaFileNotFound=The schema file {0} could not be found. -TracePackageImportOperation_ErrorCreatingBookmark=Error creating bookmark for the trace {0} -TracePackageImportOperation_ErrorCreatingBookmarkFile=Error creating bookmark file for the trace {0} -TracePackageImportOperation_ImportingPackage=Importing package -TracePackageImportOperation_DetectingTraceType=Detecting trace type for ''{0}'' diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/messages.properties deleted file mode 100644 index 47ea91587e..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/tracepkg/messages.properties +++ /dev/null @@ -1,22 +0,0 @@ -############################################################################### -# Copyright (c) 2013 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Marc-Andre Laperle - Initial API and implementation -############################################################################### - -TracePackage_Bookmarks=Bookmarks -TracePackage_Browse=B&rowse... -TracePackage_DeselectAll=Deselect All -TracePackage_ErrorOperation=Error occurred during trace package operation -TracePackage_ErrorMultipleProblems=Multiple problems. Click Details for more information. -TracePackage_FileDialogTitle=Choose Archive File -TracePackage_InternalErrorTitle=Internal error -TracePackage_SelectAll=Select All -TracePackage_SupplementaryFiles=Supplementary files -TracePackage_TraceElement=Trace \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfContentsColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfContentsColumn.java deleted file mode 100644 index ee26dcde59..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfContentsColumn.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.viewers.events.columns; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn; - -/** - * Column for the event contents (fields) - * - * @author Alexandre Montplaisir - */ -public final class TmfContentsColumn extends TmfEventTableColumn { - - @SuppressWarnings("null") - private static final @NonNull String HEADER = Messages.TmfEventsTable_ContentColumnHeader; - - /** - * Constructor - */ - public TmfContentsColumn() { - super(HEADER); - } - - @Override - public String getItemString(ITmfEvent event) { - String ret = event.getContent().toString(); - return (ret == null ? EMPTY_STRING : ret); - } - - @Override - public String getFilterFieldId() { - return ITmfEvent.EVENT_FIELD_CONTENT; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfReferenceColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfReferenceColumn.java deleted file mode 100644 index 645c4e6168..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfReferenceColumn.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.viewers.events.columns; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn; - -/** - * Column for the event reference - * - * TODO Remove me, replace with trace-type-specific columns - */ -public final class TmfReferenceColumn extends TmfEventTableColumn { - - @SuppressWarnings("null") - private static final @NonNull String HEADER = Messages.TmfEventsTable_ReferenceColumnHeader; - - /** - * Constructor - */ - public TmfReferenceColumn() { - super(HEADER); - } - - @Override - public String getItemString(ITmfEvent event) { - String ref = event.getReference(); - return (ref == null ? EMPTY_STRING : ref); - } - - @Override - public String getFilterFieldId() { - return ITmfEvent.EVENT_FIELD_REFERENCE; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfSourceColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfSourceColumn.java deleted file mode 100644 index b2064e963b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfSourceColumn.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.viewers.events.columns; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn; - -/** - * Column for the event source - * - * TODO Remove me, replace with trace-type-specific columns - */ -public final class TmfSourceColumn extends TmfEventTableColumn { - - @SuppressWarnings("null") - private static final @NonNull String HEADER = Messages.TmfEventsTable_SourceColumnHeader; - - /** - * Constructor - */ - public TmfSourceColumn() { - super(HEADER); - } - - @Override - public String getItemString(ITmfEvent event) { - String source = event.getSource(); - return (source == null ? EMPTY_STRING : source); - } - - @Override - public String getFilterFieldId() { - return ITmfEvent.EVENT_FIELD_SOURCE; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfTimestampColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfTimestampColumn.java deleted file mode 100644 index d7fb6bcf77..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfTimestampColumn.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.viewers.events.columns; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn; - -/** - * Column for the timestamps - */ -public final class TmfTimestampColumn extends TmfEventTableColumn { - - @SuppressWarnings("null") - private static final @NonNull String HEADER = Messages.TmfEventsTable_TimestampColumnHeader; - - /** - * Constructor - */ - public TmfTimestampColumn() { - super(HEADER); - } - - @Override - public String getItemString(ITmfEvent event) { - String ret = event.getTimestamp().toString(); - return (ret == null ? EMPTY_STRING : ret); - } - - @Override - public String getFilterFieldId() { - return ITmfEvent.EVENT_FIELD_TIMESTAMP; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfTypeColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfTypeColumn.java deleted file mode 100644 index 7209a366ac..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/viewers/events/columns/TmfTypeColumn.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.ui.viewers.events.columns; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn; - -/** - * Column for the event type - */ -public final class TmfTypeColumn extends TmfEventTableColumn { - - @SuppressWarnings("null") - private static final @NonNull String HEADER = Messages.TmfEventsTable_TypeColumnHeader; - - /** - * Constructor - */ - public TmfTypeColumn() { - super(HEADER); - } - - @Override - public String getItemString(ITmfEvent event) { - ITmfEventType type = event.getType(); - if (type == null) { - return EMPTY_STRING; - } - String typeName = type.getName(); - return (typeName == null ? EMPTY_STRING : typeName); - } - - @Override - public String getFilterFieldId() { - return ITmfEvent.EVENT_FIELD_TYPE; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/TmfUiRefreshHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/TmfUiRefreshHandler.java deleted file mode 100644 index 0a4d15a77b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/TmfUiRefreshHandler.java +++ /dev/null @@ -1,131 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - * Patrick Tasse - Update queue handling - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui; - -import java.util.LinkedHashMap; -import java.util.Map; - -import org.eclipse.swt.widgets.Display; - -/** - * This handler offers "coalescing" of UI updates. - * - * When displaying live experiments containing a high number of traces, every - * trace will want to regularly update views with their new available data. This - * can cause a high number of threads calling {@link Display#asyncExec} - * repeatedly, which can really impede UI responsiveness. - *

- * Instead of calling {@link Display#asyncExec} directly, threads that want to - * queue updates to the UI can instead call - * {@link TmfUiRefreshHandler#queueUpdate}. If the handler is not currently - * executing another update it will be scheduled immediately. Otherwise the - * update will be queued. - *

- * The handler will only execute one update at a time. While it is busy, new - * requests received from a source that is already in the queue will replace the - * previous one (as we assume the latest UI update request is the most - * up-to-date and interesting one), preserving the previous request order. New - * requests received from other sources will be added to the end of the queue - * (keeping only the latest request from each source). - *

- * Once the current update is completed, the oldest request in the queue will be - * sent to the UI thread via one single call to {@link Display#syncExec}. - * - * @author Alexandre Montplaisir - * @since 3.1 - */ -public class TmfUiRefreshHandler { - - /** Singleton instance */ - private static TmfUiRefreshHandler fInstance = null; - - private final Map fUpdates = new LinkedHashMap<>(); - private Thread fCurrentTask; - - - /** - * Internal constructor - */ - private TmfUiRefreshHandler() { - fCurrentTask = null; - } - - /** - * Get the handler's instance - * - * @return The singleton instance - */ - public static synchronized TmfUiRefreshHandler getInstance() { - if (fInstance == null) { - fInstance = new TmfUiRefreshHandler(); - } - return fInstance; - } - - /** - * Cancel all current requests and dispose the handler. - */ - public synchronized void dispose() { - fUpdates.clear(); - fCurrentTask = null; - } - - /** - * Queue a UI update. Threads that want to benefit from "UI coalescing" - * should send their {@link Runnable} to this method, instead of - * {@link Display#asyncExec(Runnable)}. - * - * @param source - * The source sending the request. Typically callers should use - * "this". When multiple requests are queued before being - * executed, only the latest request per source is actually sent. - * @param task - * The {@link Runnable} to execute in the UI thread. - */ - public synchronized void queueUpdate(Object source, Runnable task) { - fUpdates.put(source, task); - if (fCurrentTask == null) { - fCurrentTask = new RunAllUpdates(); - fCurrentTask.start(); - } - } - - /** - * Task to empty the update queue, and send each task to the UI thread. - */ - private class RunAllUpdates extends Thread { - @Override - public void run() { - while (true) { - Runnable nextTask = null; - synchronized (TmfUiRefreshHandler.this) { - if (!fUpdates.isEmpty()) { - Object firstKey = fUpdates.keySet().iterator().next(); - nextTask = fUpdates.get(firstKey); - fUpdates.remove(firstKey); - } - if (nextTask == null) { - /* - * No updates remaining in the queue, put fCurrentTask - * back to null so that a new task can be scheduled. - */ - fCurrentTask = null; - break; - } - } - Display.getDefault().syncExec(nextTask); - } - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/analysis/TmfAnalysisViewOutput.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/analysis/TmfAnalysisViewOutput.java deleted file mode 100644 index 1406333e34..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/analysis/TmfAnalysisViewOutput.java +++ /dev/null @@ -1,133 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.analysis; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExecutableExtension; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisOutput; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisModuleOutputs; -import org.eclipse.linuxtools.tmf.ui.project.model.Messages; -import org.eclipse.linuxtools.tmf.ui.project.model.TraceUtils; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IViewPart; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.part.WorkbenchPart; -import org.eclipse.ui.views.IViewDescriptor; - -/** - * Class that implements analysis output as a view. This just opens the view. - * The view itself needs to manage how and when it will execute the analysis and - * display which output. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfAnalysisViewOutput implements IAnalysisOutput, IExecutableExtension { - - private String fViewId; - private final Map fProperties = new HashMap<>(); - - /** - * Default constructor - */ - public TmfAnalysisViewOutput() { - - } - - /** - * Constructor - * - * @param viewid - * id of the view to display as output - */ - public TmfAnalysisViewOutput(String viewid) { - fViewId = viewid; - } - - /** - * Returns the view id of the corresponding view - * - * @return The view id - */ - public String getViewId() { - return fViewId; - } - - @Override - public String getName() { - IViewDescriptor descr = PlatformUI.getWorkbench().getViewRegistry().find(fViewId); - String viewName = (descr != null) ? descr.getLabel() : fViewId + Messages.TmfAnalysisViewOutput_ViewUnavailable; - return viewName; - } - - @Override - public void requestOutput() { - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - - try { - final IWorkbench wb = PlatformUI.getWorkbench(); - final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); - - IViewPart view = activePage.showView(fViewId); - if (!(fProperties.isEmpty()) && (view instanceof WorkbenchPart)) { - WorkbenchPart wbPart = (WorkbenchPart) view; - for (String key : fProperties.keySet()) { - wbPart.setPartProperty(key, fProperties.get(key)); - } - } - - } catch (final PartInitException e) { - TraceUtils.displayErrorMsg(Messages.TmfAnalysisViewOutput_Title, "Error opening view " + getName() + e.getMessage()); //$NON-NLS-1$ - Activator.getDefault().logError("Error opening view " + getName(), e); //$NON-NLS-1$ - } - } - }); - } - - @Override - public void setOutputProperty(@NonNull String key, String value, boolean immediate) { - if (value == null) { - fProperties.remove(key); - } else { - fProperties.put(key, value); - /* - * If the property is immediate, we forward it to the view if the - * view is active - */ - if (immediate) { - final IWorkbench wb = PlatformUI.getWorkbench(); - final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); - IViewPart view = activePage.findView(fViewId); - if (view instanceof WorkbenchPart) { - ((WorkbenchPart) view).setPartProperty(key, value); - } - } - } - } - - @Override - public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException { - fViewId = config.getAttribute(TmfAnalysisModuleOutputs.ID_ATTR); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/ITmfTraceEditor.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/ITmfTraceEditor.java deleted file mode 100644 index a8c5726eb5..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/ITmfTraceEditor.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.editors; - -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * The trace editor interface - * - * @version 1.0 - * @author Patrick Tasse - */ -public interface ITmfTraceEditor { - - /** - * Get the trace to which this editor is assigned - * - * @return The trace - */ - ITmfTrace getTrace(); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/TmfEditor.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/TmfEditor.java deleted file mode 100644 index 359a771925..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/TmfEditor.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Bernd Hufmann - Add interface for broadcasting signals asynchronously - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.editors; - -import org.eclipse.linuxtools.tmf.core.component.ITmfComponent; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.ui.part.EditorPart; - -/** - * The main editor abstract class for use in TMF. - * - * @version 1.0 - * @author Patrick Tasse - */ -public abstract class TmfEditor extends EditorPart implements ITmfComponent { - - private final String fName; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - public TmfEditor() { - super(); - fName = "TmfEditor"; //$NON-NLS-1$ - TmfSignalManager.register(this); - } - - @Override - public void dispose() { - TmfSignalManager.deregister(this); - super.dispose(); - } - - // ------------------------------------------------------------------------ - // ITmfComponent - // ------------------------------------------------------------------------ - - @Override - public String getName() { - return fName; - } - - @Override - public void broadcast(TmfSignal signal) { - TmfSignalManager.dispatchSignal(signal); - } - - /** - * @since 3.0 - */ - @Override - public void broadcastAsync(TmfSignal signal) { - TmfSignalManager.dispatchSignalAsync(signal); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/TmfEditorInput.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/TmfEditorInput.java deleted file mode 100644 index 0a4618f458..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/TmfEditorInput.java +++ /dev/null @@ -1,136 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.editors; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.content.IContentType; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IPersistableElement; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.ide.IDE; - -/** - * The input interface for TMF editors. - * - * @version 1.0 - * @author Patrick Tasse - */ -public class TmfEditorInput implements IEditorInput { - - private final IFile fFile; - private final ITmfTrace fTrace; - - /** - * Standard constructor - * - * @param file The IFile pointer - * @param trace Reference to the trace - */ - public TmfEditorInput(IFile file, ITmfTrace trace) { - fFile = file; - fTrace = trace; - } - - @Override - public Object getAdapter(Class adapter) { - return null; - } - - @Override - public boolean exists() { - /* prevent this input from appearing in "Files Most Recently Used" list, - * as this causes lingering reference to ITmfTrace in the platform */ - return false; - } - - @Override - public ImageDescriptor getImageDescriptor() { - IContentType contentType = IDE.getContentType(fFile); - return PlatformUI.getWorkbench().getEditorRegistry() - .getImageDescriptor(fFile.getName(), contentType); - } - - @Override - public String getName() { - return fTrace.getName(); - } - - @Override - public IPersistableElement getPersistable() { - return null; - } - - @Override - public String getToolTipText() { - return fFile.getFullPath().makeRelative().toString(); - } - - /** - * Get this editor input's file object - * - * @return The IFile - */ - public IFile getFile() { - return fFile; - } - - /** - * Get this editor input's trace - * - * @return The trace - */ - public ITmfTrace getTrace() { - return fTrace; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((fFile == null) ? 0 : fFile.getLocation().hashCode()); - result = prime * result + ((fTrace == null) ? 0 : fTrace.getName().hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TmfEditorInput other = (TmfEditorInput) obj; - if (fFile == null) { - if (other.fFile != null) { - return false; - } - } else if (!fFile.getLocation().equals(other.fFile.getLocation())) { - return false; - } - if (fTrace == null) { - if (other.fTrace != null) { - return false; - } - } else if (!fTrace.getName().equals(other.fTrace.getName())) { - return false; - } - return true; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/TmfEventsEditor.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/TmfEventsEditor.java deleted file mode 100644 index 1e5d385228..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/TmfEventsEditor.java +++ /dev/null @@ -1,649 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Geneviève Bastien - Experiment instantiated with experiment type - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.editors; - -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.Set; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.resources.IMarkerDelta; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceChangeEvent; -import org.eclipse.core.resources.IResourceChangeListener; -import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.InvalidRegistryObjectException; -import org.eclipse.core.runtime.ListenerList; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.jface.action.IStatusLineManager; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimestampFormatUpdateSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; -import org.eclipse.linuxtools.tmf.core.trace.TmfTrace; -import org.eclipse.linuxtools.tmf.ui.project.model.Messages; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfOpenTraceHelper; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceTypeUIUtils; -import org.eclipse.linuxtools.tmf.ui.viewers.events.TmfEventsTable; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IEditorSite; -import org.eclipse.ui.IFileEditorInput; -import org.eclipse.ui.IPartListener; -import org.eclipse.ui.IPropertyListener; -import org.eclipse.ui.IReusableEditor; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.ide.IGotoMarker; -import org.eclipse.ui.part.FileEditorInput; -import org.eclipse.ui.views.properties.IPropertySheetPage; - -/** - * Editor for TMF events - * - * @version 1.0 - * @author Patrick Tasse - * @since 2.0 - */ -public class TmfEventsEditor extends TmfEditor implements ITmfTraceEditor, IReusableEditor, IPropertyListener, IResourceChangeListener, ISelectionProvider, ISelectionChangedListener, IPartListener, IGotoMarker { - - /** ID for this class */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.editors.events"; //$NON-NLS-1$ - - private TmfEventsTable fEventsTable; - private IFile fFile; - private ITmfTrace fTrace; - private Composite fParent; - private ListenerList fSelectionChangedListeners = new ListenerList(); - private boolean fTraceSelected; - private IMarker fPendingGotoMarker; - - @Override - public void doSave(final IProgressMonitor monitor) { - } - - @Override - public void doSaveAs() { - } - - @Override - public void init(final IEditorSite site, IEditorInput input) throws PartInitException { - IFileEditorInput fileEditorInput; - if (input instanceof TmfEditorInput) { - fFile = ((TmfEditorInput) input).getFile(); - fTrace = ((TmfEditorInput) input).getTrace(); - /* change the input to a FileEditorInput to allow open handlers to find this editor */ - fileEditorInput = new FileEditorInput(fFile); - } else if (input instanceof IFileEditorInput) { - fileEditorInput = (IFileEditorInput) input; - fFile = fileEditorInput.getFile(); - if (fFile == null) { - throw new PartInitException("Invalid IFileEditorInput: " + fileEditorInput); //$NON-NLS-1$ - } - try { - final String traceTypeId = fFile.getPersistentProperty(TmfCommonConstants.TRACETYPE); - if (traceTypeId == null) { - throw new PartInitException(Messages.TmfOpenTraceHelper_NoTraceType); - } - if (traceTypeId.equals(TmfExperiment.class.getCanonicalName())) { - // Special case: experiment bookmark resource - final TmfProjectElement project = TmfProjectRegistry.getProject(fFile.getProject(), true); - if (project == null) { - throw new PartInitException(Messages.TmfOpenTraceHelper_NoTraceType); - } - for (final TmfExperimentElement experimentElement : project.getExperimentsFolder().getExperiments()) { - if (experimentElement.getResource().equals(fFile.getParent())) { - setPartName(experimentElement.getName()); - super.setSite(site); - super.setInput(fileEditorInput); - TmfOpenTraceHelper.reopenTraceFromElement(experimentElement, this); - return; - } - } - } else if (traceTypeId.equals(TmfTrace.class.getCanonicalName())) { - // Special case: trace bookmark resource - final TmfProjectElement project = TmfProjectRegistry.getProject(fFile.getProject(), true); - for (final TmfTraceElement traceElement : project.getTracesFolder().getTraces()) { - if (traceElement.getResource().equals(fFile.getParent())) { - setPartName(traceElement.getName()); - super.setSite(site); - super.setInput(fileEditorInput); - TmfOpenTraceHelper.reopenTraceFromElement(traceElement, this); - return; - } - } - } else { - final TmfProjectElement project = TmfProjectRegistry.getProject(fFile.getProject(), true); - for (final TmfTraceElement traceElement : project.getTracesFolder().getTraces()) { - if (traceElement.getResource().equals(fFile)) { - setPartName(traceElement.getName()); - super.setSite(site); - super.setInput(fileEditorInput); - TmfOpenTraceHelper.reopenTraceFromElement(traceElement, this); - return; - } - } - } - } catch (final PartInitException e) { - throw e; - } catch (final InvalidRegistryObjectException e) { - Activator.getDefault().logError("Error initializing TmfEventsEditor", e); //$NON-NLS-1$ - } catch (final CoreException e) { - Activator.getDefault().logError("Error initializing TmfEventsEditor", e); //$NON-NLS-1$ - } - } else { - throw new PartInitException("Invalid IEditorInput: " + input.getClass()); //$NON-NLS-1$ - } - if (fTrace == null) { - throw new PartInitException("Invalid IEditorInput: " + fFile.getName()); //$NON-NLS-1$ - } - super.setSite(site); - super.setInput(fileEditorInput); - } - - @Override - public boolean isDirty() { - return false; - } - - @Override - public boolean isSaveAsAllowed() { - return false; - } - - @Override - public void setInput(final IEditorInput input) { - super.setInput(input); - firePropertyChange(IEditorPart.PROP_INPUT); - } - - @Override - public void propertyChanged(final Object source, final int propId) { - if (propId == IEditorPart.PROP_INPUT && getEditorInput() instanceof TmfEditorInput) { - if (fTrace != null) { - broadcast(new TmfTraceClosedSignal(this, fTrace)); - } - fTraceSelected = false; - fFile = ((TmfEditorInput) getEditorInput()).getFile(); - fTrace = ((TmfEditorInput) getEditorInput()).getTrace(); - /* change the input to a FileEditorInput to allow open handlers to find this editor */ - super.setInput(new FileEditorInput(fFile)); - fEventsTable.dispose(); - if (fTrace != null) { - setPartName(fTrace.getName()); - fEventsTable = createEventsTable(fParent, fTrace.getCacheSize()); - fEventsTable.addSelectionChangedListener(this); - fEventsTable.setTrace(fTrace, true); - fEventsTable.refreshBookmarks(fFile); - if (fPendingGotoMarker != null) { - fEventsTable.gotoMarker(fPendingGotoMarker); - fPendingGotoMarker = null; - } - - /* ensure start time is set */ - final ITmfContext context = fTrace.seekEvent(0); - fTrace.getNext(context); - context.dispose(); - - broadcast(new TmfTraceOpenedSignal(this, fTrace, fFile)); - } else { - setPartName(getEditorInput().getName()); - fEventsTable = new TmfEventsTable(fParent, 0); - fEventsTable.addSelectionChangedListener(this); - } - fParent.layout(); - } - } - - @Override - public void createPartControl(final Composite parent) { - fParent = parent; - if (fTrace != null) { - setPartName(fTrace.getName()); - fEventsTable = createEventsTable(parent, fTrace.getCacheSize()); - fEventsTable.addSelectionChangedListener(this); - fEventsTable.setTrace(fTrace, true); - fEventsTable.refreshBookmarks(fFile); - - /* ensure start time is set */ - final ITmfContext context = fTrace.seekEvent(0); - fTrace.getNext(context); - context.dispose(); - - broadcast(new TmfTraceOpenedSignal(this, fTrace, fFile)); - } else { - fEventsTable = new TmfEventsTable(parent, 0); - fEventsTable.addSelectionChangedListener(this); - } - IStatusLineManager statusLineManager = getEditorSite().getActionBars().getStatusLineManager(); - fEventsTable.setStatusLineManager(statusLineManager); - addPropertyListener(this); - ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE); - // we need to wrap the ISelectionProvider interface in the editor because - // the events table can be replaced later while the selection changed listener - // is only added once by the platform to the selection provider set here - getSite().setSelectionProvider(this); - getSite().getPage().addPartListener(this); - } - - @Override - public void dispose() { - if (getSite() != null) { - getSite().getPage().removePartListener(this); - } - ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); - removePropertyListener(this); - if (fTrace != null) { - broadcast(new TmfTraceClosedSignal(this, fTrace)); - } - if (fEventsTable != null) { - fEventsTable.dispose(); - } - super.dispose(); - } - - /** - * Create the event table - * - * @param parent - * The parent composite - * @param cacheSize - * The cache size - * @return The event table instance - */ - protected @NonNull TmfEventsTable createEventsTable(final Composite parent, final int cacheSize) { - return getEventTable(fTrace, parent, cacheSize); - } - - /** - * Get the event table for the given trace. It will be of the type defined - * by the extension point if applicable, else it will be a default table - * with the extension-point-defined columns (if any). - * - * @param trace - * The event table is for this trace - * @param parent - * The parent composite of the table - * @param cacheSize - * The cache size to use - * @return The event table for the trace - */ - private static @NonNull TmfEventsTable getEventTable(ITmfTrace trace, - final Composite parent, final int cacheSize) { - if (trace instanceof TmfExperiment) { - return getExperimentEventTable((TmfExperiment) trace, parent, cacheSize); - } - - TmfEventsTable table = TmfTraceTypeUIUtils.getEventTable(trace, parent, cacheSize); - if (table != null) { - /* - * The trace type specified an event table type, we will give it to - * them. - */ - return table; - } - - /* - * The trace type did not specify an event table, we will use a default - * table with the columns it asked for (if any). - */ - Collection columns = TmfTraceTypeUIUtils.getEventTableColumns(trace); - if (columns != null) { - return new TmfEventsTable(parent, cacheSize, columns); - } - - /* - * No columns were defined either, use a default table with the default - * columns. - */ - return new TmfEventsTable(parent, cacheSize); - - } - - /** - * Get the events table for an experiment. If all traces in the experiment - * are of the same type, use the same behavior as if it was one trace of - * that type. - * - * @param experiment - * the experiment - * @param parent - * the parent Composite - * @param cacheSize - * the event table cache size - * @return An event table of the appropriate type - */ - private static @NonNull TmfEventsTable getExperimentEventTable( - final TmfExperiment experiment, final Composite parent, - final int cacheSize) { - - String commonTraceType = getCommonTraceType(experiment); - if (commonTraceType != null) { - /* - * All the traces in this experiment are of the same type, let's - * just use the normal table for that type. - */ - return getEventTable(experiment.getTraces()[0], parent, cacheSize); - } - - /* - * There are different trace types in the experiment, so we are - * definitely using a TmfEventsTable. Aggregate the columns from all - * trace types. - */ - ITmfTrace[] traces = experiment.getTraces(); - Set cols = new LinkedHashSet<>(); - - for (ITmfTrace trace : traces) { - Collection traceCols = - TmfTraceTypeUIUtils.getEventTableColumns(trace); - if (traceCols == null) { - cols.addAll(TmfEventsTable.DEFAULT_COLUMNS); - } else { - cols.addAll(traceCols); - } - } - - return new TmfEventsTable(parent, cacheSize, cols); - } - - /** - * Check if an experiment contains traces of all the same type. If so, - * returns this type as a String. If not, returns null. - * - * @param experiment - * The experiment - * @return The common trace type if there is one, or 'null' if there are - * different types. - */ - private static @Nullable String getCommonTraceType(TmfExperiment experiment) { - String commonTraceType = null; - try { - for (final ITmfTrace trace : experiment.getTraces()) { - final IResource resource = trace.getResource(); - if (resource == null) { - return null; - } - - final String traceType = resource.getPersistentProperty(TmfCommonConstants.TRACETYPE); - if ((commonTraceType != null) && !commonTraceType.equals(traceType)) { - return null; - } - commonTraceType = traceType; - } - } catch (CoreException e) { - /* - * One of the traces didn't advertise its type, we can't infer - * anything. - */ - return null; - } - return commonTraceType; - } - - @Override - public ITmfTrace getTrace() { - return fTrace; - } - - @Override - public void setFocus() { - fEventsTable.setFocus(); - } - - @Override - public Object getAdapter(final Class adapter) { - if (IGotoMarker.class.equals(adapter)) { - if (fTrace == null || fEventsTable == null) { - return this; - } - return fEventsTable; - } else if (IPropertySheetPage.class.equals(adapter)) { - return new UnsortedPropertySheetPage(); - } - return super.getAdapter(adapter); - } - - /** - * @since 2.1 - */ - @Override - public void gotoMarker(IMarker marker) { - if (fTrace == null || fEventsTable == null) { - fPendingGotoMarker = marker; - } else { - fEventsTable.gotoMarker(marker); - } - } - - @Override - public void resourceChanged(final IResourceChangeEvent event) { - for (final IMarkerDelta delta : event.findMarkerDeltas(IMarker.BOOKMARK, false)) { - if (delta.getResource().equals(fFile)) { - if (delta.getKind() == IResourceDelta.REMOVED) { - final IMarker bookmark = delta.getMarker(); - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - fEventsTable.removeBookmark(bookmark); - } - }); - } else if (delta.getKind() == IResourceDelta.CHANGED) { - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - fEventsTable.getTable().refresh(); - } - }); - } - } - } - } - - // ------------------------------------------------------------------------ - // ISelectionProvider - // ------------------------------------------------------------------------ - - /** - * @since 2.0 - */ - @Override - public void addSelectionChangedListener(ISelectionChangedListener listener) { - fSelectionChangedListeners.add(listener); - } - - /** - * @since 2.0 - */ - @Override - public ISelection getSelection() { - if (fEventsTable == null) { - return StructuredSelection.EMPTY; - } - return fEventsTable.getSelection(); - } - - /** - * @since 2.0 - */ - @Override - public void removeSelectionChangedListener(ISelectionChangedListener listener) { - fSelectionChangedListeners.remove(listener); - } - - /** - * @since 2.0 - */ - @Override - public void setSelection(ISelection selection) { - // not implemented - } - - /** - * Notifies any selection changed listeners that the viewer's selection has changed. - * Only listeners registered at the time this method is called are notified. - * - * @param event a selection changed event - * - * @see ISelectionChangedListener#selectionChanged - * @since 2.0 - */ - protected void fireSelectionChanged(final SelectionChangedEvent event) { - Object[] listeners = fSelectionChangedListeners.getListeners(); - for (int i = 0; i < listeners.length; ++i) { - final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i]; - SafeRunnable.run(new SafeRunnable() { - @Override - public void run() { - l.selectionChanged(event); - } - }); - } - } - - // ------------------------------------------------------------------------ - // ISelectionChangedListener - // ------------------------------------------------------------------------ - - /** - * @since 2.0 - */ - @Override - public void selectionChanged(SelectionChangedEvent event) { - fireSelectionChanged(event); - } - - // ------------------------------------------------------------------------ - // IPartListener - // ------------------------------------------------------------------------ - - /** - * @since 2.0 - */ - @Override - public void partActivated(IWorkbenchPart part) { - if (part == this && fTrace != null) { - if (fTraceSelected) { - return; - } - fTraceSelected = true; - broadcast(new TmfTraceSelectedSignal(this, fTrace)); - } - } - - /** - * @since 2.0 - */ - @Override - public void partBroughtToTop(IWorkbenchPart part) { - if (part == this && fTrace != null) { - if (fTraceSelected) { - return; - } - fTraceSelected = true; - broadcast(new TmfTraceSelectedSignal(this, fTrace)); - } - } - - /** - * @since 2.0 - */ - @Override - public void partClosed(IWorkbenchPart part) { - } - - /** - * @since 2.0 - */ - @Override - public void partDeactivated(IWorkbenchPart part) { - } - - /** - * @since 2.0 - */ - @Override - public void partOpened(IWorkbenchPart part) { - } - - // ------------------------------------------------------------------------ - // Global commands - // ------------------------------------------------------------------------ - - /** - * Add a bookmark - */ - public void addBookmark() { - fEventsTable.addBookmark(fFile); - } - - - // ------------------------------------------------------------------------ - // Signal handlers - // ------------------------------------------------------------------------ - - /** - * Handler for the Trace Selected signal - * - * @param signal The incoming signal - */ - @TmfSignalHandler - public void traceSelected(final TmfTraceSelectedSignal signal) { - if ((signal.getSource() != this)) { - if (signal.getTrace().equals(fTrace)) { - getSite().getPage().bringToTop(this); - } else { - fTraceSelected = false; - } - } - } - - /** - * Update the display to use the updated timestamp format - * - * @param signal the incoming signal - * @since 2.0 - */ - @TmfSignalHandler - public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) { - if (fEventsTable != null) { - fEventsTable.refresh(); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/TmfMultiPageEditorPart.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/TmfMultiPageEditorPart.java deleted file mode 100644 index 1b9fbd91db..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/TmfMultiPageEditorPart.java +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.editors; - -import org.eclipse.linuxtools.tmf.core.component.ITmfComponent; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.ui.part.MultiPageEditorPart; - -/** - * Multi-page editor part abstract class for use in TMF. - * - * @version 1.0 - * @author Patrick Tasse - */ -public abstract class TmfMultiPageEditorPart extends MultiPageEditorPart implements ITmfComponent { - - private final String fName; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - public TmfMultiPageEditorPart() { - super(); - fName = "TmfMultiPageEditorPart"; //$NON-NLS-1$ - TmfSignalManager.register(this); - } - - @Override - public void dispose() { - TmfSignalManager.deregister(this); - super.dispose(); - } - - // ------------------------------------------------------------------------ - // ITmfComponent - // ------------------------------------------------------------------------ - - @Override - public String getName() { - return fName; - } - - @Override - public void broadcast(TmfSignal signal) { - TmfSignalManager.dispatchSignal(signal); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/UnsortedPropertySheetPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/UnsortedPropertySheetPage.java deleted file mode 100644 index 88f097e851..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/editors/UnsortedPropertySheetPage.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.editors; - -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.views.properties.IPropertySheetEntry; -import org.eclipse.ui.views.properties.PropertySheetPage; -import org.eclipse.ui.views.properties.PropertySheetSorter; - -/** - * Property sheet page with empty sorter - * - * @version 1.0 - * @author Patrick Tasse - * @since 2.0 - */ -public class UnsortedPropertySheetPage extends PropertySheetPage { - - @Override - public void createControl(Composite parent) { - super.createControl(parent); - // Override for unsorted property sheet page - // See bug 1883 comment 43 and bug 109617 - setSorter(new PropertySheetSorter() { - @Override - public void sort(IPropertySheetEntry[] entries) { - } - }); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/ITmfProjectModelElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/ITmfProjectModelElement.java deleted file mode 100644 index 1386c23858..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/ITmfProjectModelElement.java +++ /dev/null @@ -1,87 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import java.net.URI; -import java.util.List; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IPath; - -/** - * The TMF project model interface. - * - * The TMF tracing project is integrated in the Common Navigator framework. - * Each tracing tree element has to implement this interface to be visible in the - * Project Explorer. - * - * @version 1.0 - * @author Francois Chouinard - */ -public interface ITmfProjectModelElement { - - /** - * Returns the name of the project model element. - * @return the name of the project element. - */ - String getName(); - /** - * Returns the resource associated with the project model element. - * @return the model resource. - */ - IResource getResource(); - /** - * Returns the path of the project model resource. - * @return the resource path. - */ - IPath getPath(); - /** - * Returns the URI (location) of the resource. - * @return the resource URI. - */ - URI getLocation(); - /** - * Returns the project model element. - * @return the project model element. - */ - TmfProjectElement getProject(); - /** - * Returns the parent of this model element. - * @return the parent of this model element. - */ - ITmfProjectModelElement getParent(); - /** - * Returns whether this model element has children or not. - * @return true if this model has children else false - */ - boolean hasChildren(); - /** - * Returns a list of children model elements. - * @return a list of children model elements. - */ - List getChildren(); - /** - * Method to add a child to the model element. - * @param child A child element to add. - */ - void addChild(ITmfProjectModelElement child); - /** - * Method to remove a child from the model element. - * @param child A child element to remove - */ - void removeChild(ITmfProjectModelElement child); - /** - * Method to request to refresh the project. - */ - void refresh(); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/ITmfStyledProjectModelElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/ITmfStyledProjectModelElement.java deleted file mode 100644 index 67d9541098..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/ITmfStyledProjectModelElement.java +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.jface.viewers.StyledString.Styler; - -/** - * This interface can be implemented by elements to a style to their text. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public interface ITmfStyledProjectModelElement { - - /** - * Return the styler who will apply its style to the text string. - * - * @return The style object, or 'null' for no special style - */ - @Nullable - Styler getStyler(); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/Messages.java deleted file mode 100644 index 9d845daf01..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/Messages.java +++ /dev/null @@ -1,146 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Jean-Christian Kouamé - Initial API and implementation - * Patrick Tasse - Add support for source location - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import org.eclipse.osgi.util.NLS; - -/** - * Message strings for TMF model handling. - * - * @author Jean-Christian Kouamé - * @since 2.1 - */ -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.ui.project.model.messages"; //$NON-NLS-1$ - - /** Instantiate analysis message box title - * @since 3.0*/ - public static String TmfAnalysisElement_InstantiateAnalysis; - - /** The message when analysis view is not available - * @since 3.0*/ - public static String TmfAnalysisViewOutput_ViewUnavailable; - /** Analysis view title - * @since 3.0 */ - public static String TmfAnalysisViewOutput_Title; - - /** Error message when closing editor - * @since 3.0 */ - public static String TmfCommonProjectElement_ErrorClosingEditor; - - /** Error message when refreshing persistent property - * @since 3.0 */ - public static String TmfCommonProjectElement_ErrorRefreshingProperty; - - /** Error message when instantiating trace - * @since 3.0 */ - public static String TmfExperimentElement_ErrorInstantiatingTrace; - /** Experiment text - * @since 3.0*/ - public static String TmfExperimentElement_TypeName; - - /** The category of the resource properties */ - public static String TmfTraceElement_ResourceProperties; - - /** The category of the trace properties */ - public static String TmfTraceElement_TraceProperties; - - /** The descriptor for the name property */ - public static String TmfTraceElement_Name; - - /** The descriptor for the path property */ - public static String TmfTraceElement_Path; - - /** The descriptor for the location properties */ - public static String TmfTraceElement_Location; - - /** The descriptor for the event type property */ - public static String TmfTraceElement_EventType; - - /** The descriptor for the linked property */ - public static String TmfTraceElement_IsLinked; - - /** The descriptor for the source location property - * @since 3.0*/ - public static String TmfTraceElement_SourceLocation; - - /** The descriptor for the time offset property - * @since 3.2*/ - public static String TmfTraceElement_TimeOffset; - - /** The descriptor for the last modified property - * @since 3.2 */ - public static String TmfTraceElement_LastModified; - - /** The descriptor for the size property - * @since 3.2 */ - public static String TmfTraceElement_Size; - - /** The format string for the size property of a file - * @since 3.2 */ - public static String TmfTraceElement_FileSizeString; - - /** The format string for the size property of a folder - * @since 3.2 */ - public static String TmfTraceElement_FolderSizeString; - - /** The format string for the size property of a folder with too many members - * @since 3.2 */ - public static String TmfTraceElement_FolderSizeOverflowString; - - /** Trace text - * @since 3.0*/ - public static String TmfTraceElement_TypeName; - /** - * The title for the select trace type dialog - * @since 2.2 - * */ - public static String TmfTraceType_SelectTraceType; - - /** Error opening a trace or experiment - * @since 3.0*/ - public static String TmfOpenTraceHelper_ErrorOpeningElement; - /** Could not link trace */ - public static String TmfOpenTraceHelper_LinkFailed; - /** No trace type match */ - public static String TmfOpenTraceHelper_NoTraceTypeMatch; - /** Open trace or experiment - * @since 3.0*/ - public static String TmfOpenTraceHelper_OpenElement; - /** Reduce was too efficient, no candidates found! */ - public static String TmfOpenTraceHelper_ReduceError; - /** No trace or experiment type - * @since 3.0*/ - public static String TmfOpenTraceHelper_NoTraceOrExperimentType; - /** No trace type */ - public static String TmfOpenTraceHelper_NoTraceType; - /** Error opening trace or experiment - * @since 3.0*/ - public static String TmfOpenTraceHelper_ErrorElement; - /** Init error */ - public static String TmfOpenTraceHelper_InitError; - /** Trace not found - * @since 3.0*/ - public static String TmfOpenTraceHelper_TraceNotFound; - - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfAnalysisElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfAnalysisElement.java deleted file mode 100644 index 0b479a33df..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfAnalysisElement.java +++ /dev/null @@ -1,254 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - * Patrick Tasse - Add support for folder elements - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.IPath; -import org.eclipse.jface.viewers.StyledString.Styler; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisOutput; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.swt.graphics.TextStyle; -import org.osgi.framework.Bundle; - -/** - * Class for project elements of type analysis modules - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfAnalysisElement extends TmfProjectModelElement implements ITmfStyledProjectModelElement { - - private static final Styler ANALYSIS_CANT_EXECUTE_STYLER = new Styler() { - @Override - public void applyStyles(TextStyle textStyle) { - textStyle.strikeout = true; - } - }; - - private final String fAnalysisId; - private boolean fCanExecute = true; - - /** - * Constructor - * - * @param name - * Name of the analysis - * @param resource - * The resource - * @param parent - * Parent of the analysis - * @param id - * The analysis module id - */ - protected TmfAnalysisElement(String name, IResource resource, ITmfProjectModelElement parent, String id) { - super(name, resource, parent); - fAnalysisId = id; - parent.addChild(this); - } - - // ------------------------------------------------------------------------ - // TmfProjectModelElement - // ------------------------------------------------------------------------ - - @Override - void refreshChildren() { - fCanExecute = true; - - /* Refresh the outputs of this analysis */ - Map childrenMap = new HashMap<>(); - for (TmfAnalysisOutputElement output : getAvailableOutputs()) { - childrenMap.put(output.getName(), output); - } - - IAnalysisModuleHelper helper = TmfAnalysisManager.getAnalysisModule(fAnalysisId); - if (helper == null) { - deleteOutputs(); - return; - } - - /** Get base path for resource */ - IPath path = getProject().getTracesFolder().getPath(); - if (fResource instanceof IFolder) { - path = ((IFolder) fResource).getFullPath(); - } - - /* - * We can get a list of available outputs once the analysis is - * instantiated when the trace is opened - */ - ITmfProjectModelElement parent = getParent(); - if (parent instanceof TmfCommonProjectElement) { - ITmfTrace trace = ((TmfCommonProjectElement) parent).getTrace(); - if (trace == null) { - deleteOutputs(); - return; - } - - IAnalysisModule module = trace.getAnalysisModule(fAnalysisId); - if (module == null) { - deleteOutputs(); - /* - * Trace is opened, but the analysis is null, so it does not - * apply - */ - fCanExecute = false; - return; - } - - for (IAnalysisOutput output : module.getOutputs()) { - TmfAnalysisOutputElement outputElement = childrenMap.remove(output.getName()); - if (outputElement == null) { - IFolder newresource = ResourcesPlugin.getWorkspace().getRoot().getFolder(path.append(output.getName())); - outputElement = new TmfAnalysisOutputElement(output.getName(), newresource, this, output); - } - outputElement.refreshChildren(); - } - - } - /* Remove outputs that are not children of this analysis anymore */ - for (TmfAnalysisOutputElement output : childrenMap.values()) { - removeChild(output); - } - } - - // ------------------------------------------------------------------------ - // TmfProjectModelElement - // ------------------------------------------------------------------------ - - @Override - public Styler getStyler() { - if (!fCanExecute) { - return ANALYSIS_CANT_EXECUTE_STYLER; - } - return null; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Get the list of analysis output model elements under this analysis - * - * @return Array of analysis output elements - */ - public List getAvailableOutputs() { - List children = getChildren(); - List outputs = new ArrayList<>(); - for (ITmfProjectModelElement child : children) { - if (child instanceof TmfAnalysisOutputElement) { - outputs.add((TmfAnalysisOutputElement) child); - } - } - return outputs; - } - - /** - * Gets the analysis id of this module - * - * @return The analysis id - */ - public String getAnalysisId() { - return fAnalysisId; - } - - /** - * Gets the help message for this analysis - * - * @return The help message - */ - public String getHelpMessage() { - ITmfProjectModelElement parent = getParent(); - - ITmfTrace trace = null; - if (parent instanceof TmfTraceElement) { - TmfTraceElement traceElement = (TmfTraceElement) parent; - trace = traceElement.getTrace(); - if (trace != null) { - IAnalysisModule module = trace.getAnalysisModule(fAnalysisId); - if (module != null) { - return module.getHelpText(trace); - } - } - } - - IAnalysisModuleHelper helper = TmfAnalysisManager.getAnalysisModule(fAnalysisId); - if (helper == null) { - return new String(); - } - - if (trace != null) { - return helper.getHelpText(trace); - } - - return helper.getHelpText(); - } - - /** - * Gets the icon file name for the analysis - * - * @return The analysis icon file name - */ - public String getIconFile() { - IAnalysisModuleHelper helper = TmfAnalysisManager.getAnalysisModule(fAnalysisId); - if (helper == null) { - return null; - } - return helper.getIcon(); - } - - /** - * Gets the bundle this analysis is from - * - * @return The analysis bundle - */ - public Bundle getBundle() { - IAnalysisModuleHelper helper = TmfAnalysisManager.getAnalysisModule(fAnalysisId); - if (helper == null) { - return null; - } - return helper.getBundle(); - } - - /** Delete all outputs under this analysis element */ - private void deleteOutputs() { - for (TmfAnalysisOutputElement output : getAvailableOutputs()) { - removeChild(output); - } - } - - /** - * Make sure the trace this analysis is associated to is the currently - * selected one - */ - public void activateParent() { - ITmfProjectModelElement parent = getParent(); - - if (parent instanceof TmfTraceElement) { - TmfTraceElement traceElement = (TmfTraceElement) parent; - TmfOpenTraceHelper.openTraceFromElement(traceElement); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfAnalysisOutputElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfAnalysisOutputElement.java deleted file mode 100644 index 27d337709c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfAnalysisOutputElement.java +++ /dev/null @@ -1,86 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - * Patrick Tasse - Add support for folder elements - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import org.eclipse.core.resources.IResource; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisOutput; -import org.eclipse.linuxtools.tmf.ui.analysis.TmfAnalysisViewOutput; -import org.eclipse.swt.graphics.Image; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.views.IViewDescriptor; - -/** - * Class for project elements of type analysis output - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfAnalysisOutputElement extends TmfProjectModelElement { - - private final IAnalysisOutput fOutput; - - /** - * Constructor - * - * @param name - * Name of the view - * @param resource - * Resource for the view - * @param parent - * Parent analysis of the view - * @param output - * The output object - */ - protected TmfAnalysisOutputElement(String name, IResource resource, ITmfProjectModelElement parent, IAnalysisOutput output) { - super(name, resource, parent); - fOutput = output; - parent.addChild(this); - } - - /** - * Gets the icon of the view, if applicable - * - * @return The view icon or null if output is not a view - */ - public Image getIcon() { - if (fOutput instanceof TmfAnalysisViewOutput) { - IViewDescriptor descr = PlatformUI.getWorkbench().getViewRegistry().find( - ((TmfAnalysisViewOutput) fOutput).getViewId()); - if (descr != null) { - Activator bundle = Activator.getDefault(); - String key = descr.getId(); - Image icon = bundle.getImageRegistry().get(key); - if (icon == null) { - icon = descr.getImageDescriptor().createImage(); - bundle.getImageRegistry().put(key, icon); - } - return icon; - } - } - return null; - } - - /** - * Outputs the analysis - */ - public void outputAnalysis() { - ITmfProjectModelElement parent = getParent(); - if (parent instanceof TmfAnalysisElement) { - ((TmfAnalysisElement) parent).activateParent(); - fOutput.requestOutput(); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfCommonProjectElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfCommonProjectElement.java deleted file mode 100644 index 52e53a8fd5..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfCommonProjectElement.java +++ /dev/null @@ -1,573 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Added supplementary files handling (in class TmfTraceElement) - * Geneviève Bastien - Copied supplementary files handling from TmfTracElement - * Moved to this class code to copy a model element - * Renamed from TmfWithFolderElement to TmfCommonProjectElement - * Patrick Tasse - Add support for folder elements - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Path; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper; -import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; -import org.eclipse.linuxtools.tmf.core.trace.TmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.osgi.util.NLS; -import org.eclipse.ui.IEditorReference; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.part.FileEditorInput; - -/** - * Base class for tracing project elements: it implements the common behavior of - * all project elements: supplementary files, analysis, types, etc. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public abstract class TmfCommonProjectElement extends TmfProjectModelElement { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // This trace type ID as defined in plugin.xml - private String fTraceTypeId = null; - - private static final String BOOKMARKS_HIDDEN_FILE = ".bookmarks"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructor. Creates model element. - * - * @param name - * The name of the element - * @param resource - * The resource. - * @param parent - * The parent element - */ - public TmfCommonProjectElement(String name, IResource resource, TmfProjectModelElement parent) { - super(name, resource, parent); - parent.addChild(this); - refreshTraceType(); - TmfSignalManager.register(this); - } - - // ------------------------------------------------------------------------ - // TmfProjectModelElement - // ------------------------------------------------------------------------ - - @Override - void refreshChildren() { - - /* Refreshes the analysis under this trace */ - Map childrenMap = new HashMap<>(); - for (TmfAnalysisElement analysis : getAvailableAnalysis()) { - childrenMap.put(analysis.getAnalysisId(), analysis); - } - - TraceTypeHelper helper = TmfTraceType.getTraceType(getTraceType()); - - Class traceClass = null; - - if (helper != null) { - traceClass = helper.getTraceClass(); - } - - /* Remove all analysis and return */ - if (traceClass == null) { - for (TmfAnalysisElement analysis : childrenMap.values()) { - removeChild(analysis); - } - return; - } - - /** Get the base path to put the resource to */ - IPath path = fResource.getFullPath(); - - /* Add all new analysis modules or refresh outputs of existing ones */ - for (IAnalysisModuleHelper module : TmfAnalysisManager.getAnalysisModules(traceClass).values()) { - - /* If the analysis is not a child of the trace, create it */ - TmfAnalysisElement analysis = childrenMap.remove(module.getId()); - if (analysis == null) { - /** - * No need for the resource to exist, nothing will be done with - * it - */ - IFolder newresource = ResourcesPlugin.getWorkspace().getRoot().getFolder(path.append(module.getId())); - analysis = new TmfAnalysisElement(module.getName(), newresource, this, module.getId()); - } - analysis.refreshChildren(); - } - - /* Remove analysis that are not children of this trace anymore */ - for (TmfAnalysisElement analysis : childrenMap.values()) { - removeChild(analysis); - } - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Returns the trace type ID. - * - * @return trace type ID. - */ - public String getTraceType() { - return fTraceTypeId; - } - - /** - * Refreshes the trace type field by reading the trace type persistent - * property of the resource. - */ - public void refreshTraceType() { - try { - fTraceTypeId = TmfTraceType.getTraceTypeId(getResource()); - } catch (CoreException e) { - Activator.getDefault().logError(NLS.bind(Messages.TmfCommonProjectElement_ErrorRefreshingProperty, getName()), e); - } - } - - /** - * Instantiate a ITmfTrace object based on the trace type and - * the corresponding extension. - * - * @return the ITmfTrace or null for an error - */ - public abstract ITmfTrace instantiateTrace(); - - /** - * Return the supplementary folder path for this element. The returned path - * is relative to the project's supplementary folder. - * - * @return The supplementary folder path for this element - */ - protected String getSupplementaryFolderPath() { - return getElementPath() + getSuffix(); - } - - /** - * Return the element path relative to its common element (traces folder, - * experiments folder or experiment element). - * - * @return The element path - */ - public String getElementPath() { - ITmfProjectModelElement parent = getParent(); - while (!(parent instanceof TmfTracesFolder || parent instanceof TmfExperimentElement || parent instanceof TmfExperimentFolder)) { - parent = parent.getParent(); - } - IPath path = fResource.getFullPath().makeRelativeTo(parent.getPath()); - return path.toString(); - } - - /** - * @return The suffix for the supplementary folder - */ - protected String getSuffix() { - return ""; //$NON-NLS-1$ - } - - /** - * Returns a list of TmfTraceElements contained in project element. - * - * @return a list of TmfTraceElements, empty list if none - */ - public List getTraces() { - return new ArrayList<>(); - } - - /** - * Get the instantiated trace associated with this element. - * - * @return The instantiated trace or null if trace is not (yet) available - */ - public ITmfTrace getTrace() { - for (ITmfTrace trace : TmfTraceManager.getInstance().getOpenedTraces()) { - if (trace.getResource().equals(getResource())) { - return trace; - } - } - return null; - } - - /** - * Returns the file resource used to store bookmarks after creating it if - * necessary. If the trace resource is a file, it is returned directly. If - * the trace resource is a folder, a linked file is returned. The file will - * be created if it does not exist. - * - * @return the bookmarks file - * @throws CoreException - * if the bookmarks file cannot be created - */ - public abstract IFile createBookmarksFile() throws CoreException; - - /** - * Actually returns the bookmark file or creates it in the project element's - * folder - * - * @param bookmarksFolder - * Folder where to put the bookmark file - * @param traceType - * The canonical name to set as tracetype - * @return The bookmark file - * @throws CoreException - * if the bookmarks file cannot be created - */ - protected IFile createBookmarksFile(IFolder bookmarksFolder, String traceType) throws CoreException { - IFile file = getBookmarksFile(); - if (!file.exists()) { - final IFile bookmarksFile = bookmarksFolder.getFile(BOOKMARKS_HIDDEN_FILE); - if (!bookmarksFile.exists()) { - final InputStream source = new ByteArrayInputStream(new byte[0]); - bookmarksFile.create(source, true, null); - } - bookmarksFile.setHidden(true); - file.createLink(bookmarksFile.getLocation(), IResource.REPLACE, null); - file.setHidden(true); - file.setPersistentProperty(TmfCommonConstants.TRACETYPE, traceType); - } - return file; - } - - /** - * Returns the optional editor ID from the trace type extension. - * - * @return the editor ID or null if not defined. - */ - public abstract String getEditorId(); - - /** - * Returns the file resource used to store bookmarks. The file may not - * exist. - * - * @return the bookmarks file - */ - public IFile getBookmarksFile() { - final IFolder folder = (IFolder) fResource; - IFile file = folder.getFile(getName() + '_'); - return file; - } - - /** - * Close open editors associated with this experiment. - */ - public void closeEditors() { - IFile file = getBookmarksFile(); - FileEditorInput input = new FileEditorInput(file); - IWorkbench wb = PlatformUI.getWorkbench(); - for (IWorkbenchWindow wbWindow : wb.getWorkbenchWindows()) { - for (IWorkbenchPage wbPage : wbWindow.getPages()) { - for (IEditorReference editorReference : wbPage.getEditorReferences()) { - try { - if (editorReference.getEditorInput().equals(input)) { - wbPage.closeEditor(editorReference.getEditor(false), false); - } - } catch (PartInitException e) { - Activator.getDefault().logError(NLS.bind(Messages.TmfCommonProjectElement_ErrorClosingEditor, getName()), e); - } - } - } - } - } - - /** - * Get a friendly name for the type of element this common project element - * is, to be displayed in UI messages. - * - * @return A string for the type of project element this object is, for - * example "trace" or "experiment" - */ - public abstract String getTypeName(); - - /** - * Copy this model element - * - * @param newName - * The name of the new element - * @param copySuppFiles - * Whether to copy supplementary files or not - * @return the new Resource object - */ - public IResource copy(final String newName, final boolean copySuppFiles) { - - final IPath newPath = getParent().getResource().getFullPath().addTrailingSeparator().append(newName); - - /* Copy supplementary files first, only if needed */ - if (copySuppFiles) { - String newElementPath = new Path(getElementPath()).removeLastSegments(1).append(newName).toString(); - copySupplementaryFolder(newElementPath); - } - /* Copy the trace */ - try { - getResource().copy(newPath, IResource.FORCE | IResource.SHALLOW, null); - IResource trace = ((IFolder) getParent().getResource()).findMember(newName); - - /* Delete any bookmarks file found in copied trace folder */ - if (trace instanceof IFolder) { - IFolder folderTrace = (IFolder) trace; - for (IResource member : folderTrace.members()) { - String traceTypeId = TmfTraceType.getTraceTypeId(member); - if (TmfTrace.class.getCanonicalName().equals(traceTypeId)) { - member.delete(true, null); - } else if (TmfExperiment.class.getCanonicalName().equals(traceTypeId)) { - member.delete(true, null); - } - } - } - return trace; - } catch (CoreException e) { - - } - return null; - } - - /** - * Get the list of analysis elements - * - * @return Array of analysis elements - */ - public List getAvailableAnalysis() { - List children = getChildren(); - List analysis = new ArrayList<>(); - for (ITmfProjectModelElement child : children) { - if (child instanceof TmfAnalysisElement) { - analysis.add((TmfAnalysisElement) child); - } - } - return analysis; - } - - // ------------------------------------------------------------------------ - // Supplementary files operations - // ------------------------------------------------------------------------ - - /** - * Deletes this element specific supplementary folder. - */ - public void deleteSupplementaryFolder() { - IFolder supplFolder = getTraceSupplementaryFolder(getSupplementaryFolderPath()); - try { - deleteFolder(supplFolder); - } catch (CoreException e) { - Activator.getDefault().logError("Error deleting supplementary folder " + supplFolder, e); //$NON-NLS-1$ - } - } - - private static void deleteFolder(IFolder folder) throws CoreException { - if (folder.exists()) { - folder.delete(true, new NullProgressMonitor()); - } - IContainer parent = folder.getParent(); - // delete empty folders up to the parent project - if (parent instanceof IFolder && (!parent.exists() || parent.members().length == 0)) { - deleteFolder((IFolder) parent); - } - } - - /** - * Renames the element specific supplementary folder according to the new - * element name or path. - * - * @param newElementPath - * The new element name or path - */ - public void renameSupplementaryFolder(String newElementPath) { - IFolder oldSupplFolder = getTraceSupplementaryFolder(getSupplementaryFolderPath()); - - // Rename supplementary folder - try { - if (oldSupplFolder.exists()) { - IFolder newSupplFolder = prepareTraceSupplementaryFolder(newElementPath + getSuffix(), false); - oldSupplFolder.move(newSupplFolder.getFullPath(), true, new NullProgressMonitor()); - } - deleteFolder(oldSupplFolder); - } catch (CoreException e) { - Activator.getDefault().logError("Error renaming supplementary folder " + oldSupplFolder, e); //$NON-NLS-1$ - } - } - - /** - * Copies the element specific supplementary folder to the new element name - * or path. - * - * @param newElementPath - * The new element name or path - */ - public void copySupplementaryFolder(String newElementPath) { - IFolder oldSupplFolder = getTraceSupplementaryFolder(getSupplementaryFolderPath()); - - // copy supplementary folder - if (oldSupplFolder.exists()) { - try { - IFolder newSupplFolder = prepareTraceSupplementaryFolder(newElementPath + getSuffix(), false); - oldSupplFolder.copy(newSupplFolder.getFullPath(), true, new NullProgressMonitor()); - } catch (CoreException e) { - Activator.getDefault().logError("Error renaming supplementary folder " + oldSupplFolder, e); //$NON-NLS-1$ - } - } - } - - /** - * Copies the element specific supplementary folder a new folder. - * - * @param destination - * The destination folder to copy to. - */ - public void copySupplementaryFolder(IFolder destination) { - IFolder oldSupplFolder = getTraceSupplementaryFolder(getSupplementaryFolderPath()); - - // copy supplementary folder - if (oldSupplFolder.exists()) { - try { - TraceUtils.createFolder((IFolder) destination.getParent(), new NullProgressMonitor()); - oldSupplFolder.copy(destination.getFullPath(), true, new NullProgressMonitor()); - } catch (CoreException e) { - Activator.getDefault().logError("Error copying supplementary folder " + oldSupplFolder, e); //$NON-NLS-1$ - } - } - } - - /** - * Refreshes the element specific supplementary folder information. It - * creates the folder if not exists. It sets the persistence property of the - * trace resource - */ - public void refreshSupplementaryFolder() { - IFolder supplFolder = createSupplementaryFolder(); - try { - supplFolder.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); - } catch (CoreException e) { - Activator.getDefault().logError("Error refreshing supplementary folder " + supplFolder, e); //$NON-NLS-1$ - } - } - - /** - * Checks if supplementary resource exist or not. - * - * @return true if one or more files are under the element - * supplementary folder - */ - public boolean hasSupplementaryResources() { - IResource[] resources = getSupplementaryResources(); - return (resources.length > 0); - } - - /** - * Returns the supplementary resources under the trace supplementary folder. - * - * @return array of resources under the trace supplementary folder. - */ - public IResource[] getSupplementaryResources() { - IFolder supplFolder = getTraceSupplementaryFolder(getSupplementaryFolderPath()); - if (supplFolder.exists()) { - try { - return supplFolder.members(); - } catch (CoreException e) { - Activator.getDefault().logError("Error deleting supplementary folder " + supplFolder, e); //$NON-NLS-1$ - } - } - return new IResource[0]; - } - - /** - * Deletes the given resources. - * - * @param resources - * array of resources to delete. - */ - public void deleteSupplementaryResources(IResource[] resources) { - - for (int i = 0; i < resources.length; i++) { - try { - resources[i].delete(true, new NullProgressMonitor()); - } catch (CoreException e) { - Activator.getDefault().logError("Error deleting supplementary resource " + resources[i], e); //$NON-NLS-1$ - } - } - } - - /** - * Deletes all supplementary resources in the supplementary directory - */ - public void deleteSupplementaryResources() { - deleteSupplementaryResources(getSupplementaryResources()); - } - - private IFolder createSupplementaryFolder() { - IFolder supplFolder = prepareTraceSupplementaryFolder(getSupplementaryFolderPath(), true); - - try { - fResource.setPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER, supplFolder.getLocationURI().getPath()); - } catch (CoreException e) { - Activator.getDefault().logError("Error setting persistant property " + TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER, e); //$NON-NLS-1$ - } - return supplFolder; - } - - // ------------------------------------------------------- - // Signal handlers - // ------------------------------------------------------- - - /** - * Handler for the Trace Opened signal - * - * @param signal - * The incoming signal - */ - @TmfSignalHandler - public void traceOpened(TmfTraceOpenedSignal signal) { - IResource resource = signal.getTrace().getResource(); - if ((resource == null) || !resource.equals(getResource())) { - return; - } - - getParent().refresh(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfExperimentElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfExperimentElement.java deleted file mode 100644 index 3ca82bf5b0..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfExperimentElement.java +++ /dev/null @@ -1,478 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Geneviève Bastien - Copied code to add/remove traces in this class - * Patrick Tasse - Close editors to release resources - * Geneviève Bastien - Experiment instantiated with trace type - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceProxy; -import org.eclipse.core.resources.IResourceProxyVisitor; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.InvalidRegistryObjectException; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Platform; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; -import org.eclipse.linuxtools.tmf.ui.editors.TmfEventsEditor; -import org.eclipse.linuxtools.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; -import org.eclipse.osgi.util.NLS; -import org.eclipse.ui.views.properties.IPropertyDescriptor; -import org.eclipse.ui.views.properties.IPropertySource2; - -/** - * Implementation of TMF Experiment Model Element. - *

- * @version 1.0 - * @author Francois Chouinard - * - */ -public class TmfExperimentElement extends TmfCommonProjectElement implements IPropertySource2 { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - // Property View stuff - private static final String sfInfoCategory = "Info"; //$NON-NLS-1$ - private static final String sfName = "name"; //$NON-NLS-1$ - private static final String sfPath = "path"; //$NON-NLS-1$ - private static final String sfLocation = "location"; //$NON-NLS-1$ - private static final String sfFolderSuffix = "_exp"; //$NON-NLS-1$ - private static final String sfExperimentType = "type"; //$NON-NLS-1$ - - private static final ReadOnlyTextPropertyDescriptor sfNameDescriptor = new ReadOnlyTextPropertyDescriptor(sfName, sfName); - private static final ReadOnlyTextPropertyDescriptor sfPathDescriptor = new ReadOnlyTextPropertyDescriptor(sfPath, sfPath); - private static final ReadOnlyTextPropertyDescriptor sfLocationDescriptor = new ReadOnlyTextPropertyDescriptor(sfLocation, - sfLocation); - private static final ReadOnlyTextPropertyDescriptor sfTypeDescriptor = new ReadOnlyTextPropertyDescriptor(sfExperimentType, sfExperimentType); - - private static final IPropertyDescriptor[] sfDescriptors = { sfNameDescriptor, sfPathDescriptor, - sfLocationDescriptor, sfTypeDescriptor }; - - static { - sfNameDescriptor.setCategory(sfInfoCategory); - sfPathDescriptor.setCategory(sfInfoCategory); - sfLocationDescriptor.setCategory(sfInfoCategory); - sfTypeDescriptor.setCategory(sfInfoCategory); - } - - // The mapping of available trace type IDs to their corresponding - // configuration element - private static final Map sfTraceTypeAttributes = new HashMap<>(); - private static final Map sfTraceTypeUIAttributes = new HashMap<>(); - private static final Map sfTraceCategories = new HashMap<>(); - - // ------------------------------------------------------------------------ - // Static initialization - // ------------------------------------------------------------------------ - - /** - * Initialize statically at startup by getting extensions from the platform - * extension registry. - * @since 3.0 - */ - public static void init() { - IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType.TMF_TRACE_TYPE_ID); - for (IConfigurationElement ce : config) { - String elementName = ce.getName(); - if (elementName.equals(TmfTraceType.EXPERIMENT_ELEM)) { - String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR); - sfTraceTypeAttributes.put(traceTypeId, ce); - } else if (elementName.equals(TmfTraceType.CATEGORY_ELEM)) { - String categoryId = ce.getAttribute(TmfTraceType.ID_ATTR); - sfTraceCategories.put(categoryId, ce); - } - } - - /* - * Read the corresponding tmf.ui "tracetypeui" extension point for this - * trace type, if it exists. - */ - config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceTypeUIUtils.TMF_TRACE_TYPE_UI_ID); - for (IConfigurationElement ce : config) { - String elemName = ce.getName(); - if (TmfTraceTypeUIUtils.EXPERIMENT_ELEM.equals(elemName)) { - String traceType = ce.getAttribute(TmfTraceTypeUIUtils.TRACETYPE_ATTR); - sfTraceTypeUIAttributes.put(traceType, ce); - } - } - } - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Constructor - * @param name The name of the experiment - * @param folder The folder reference - * @param parent The experiment folder reference. - */ - public TmfExperimentElement(String name, IFolder folder, TmfExperimentFolder parent) { - super(name, folder, parent); - } - - // ------------------------------------------------------------------------ - // TmfProjectModelElement - // ------------------------------------------------------------------------ - - @Override - public IFolder getResource() { - return (IFolder) fResource; - } - - @Override - void refreshChildren() { - IFolder folder = getResource(); - - /* Update the trace children of this experiment */ - // Get the children from the model - Map childrenMap = new HashMap<>(); - for (TmfTraceElement trace : getTraces()) { - childrenMap.put(trace.getElementPath(), trace); - } - - List members = getTraceResources(); - for (IResource resource : members) { - String name = resource.getName(); - String elementPath = resource.getFullPath().makeRelativeTo(folder.getFullPath()).toString(); - ITmfProjectModelElement element = childrenMap.get(elementPath); - if (element instanceof TmfTraceElement) { - childrenMap.remove(elementPath); - } else { - element = new TmfTraceElement(name, resource, this); - } - } - - // Cleanup dangling children from the model - for (ITmfProjectModelElement danglingChild : childrenMap.values()) { - removeChild(danglingChild); - } - - /* Update the analysis under this experiment */ - super.refreshChildren(); - } - - private List getTraceResources() { - IFolder folder = getResource(); - final List list = new ArrayList<>(); - try { - folder.accept(new IResourceProxyVisitor() { - @Override - public boolean visit(IResourceProxy resource) throws CoreException { - if (resource.isLinked()) { - list.add(resource.requestResource()); - } - return true; - } - }, IResource.NONE); - } catch (CoreException e) { - } - return list; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Refreshes the trace type filed by reading the trace type persistent - * property of the resource reference. - * - * If trace type is null after refresh, set it to the generic trace type - * (for seamless upgrade) - */ - @Override - public void refreshTraceType() { - super.refreshTraceType(); - if (getTraceType() == null) { - IConfigurationElement ce = TmfTraceType.getTraceAttributes(TmfTraceType.DEFAULT_EXPERIMENT_TYPE); - if (ce != null) { - try { - IFolder experimentFolder = getResource(); - experimentFolder.setPersistentProperty(TmfCommonConstants.TRACETYPE, ce.getAttribute(TmfTraceType.ID_ATTR)); - super.refreshTraceType(); - } catch (InvalidRegistryObjectException | CoreException e) { - } - } - } - } - - /** - * Returns a list of TmfTraceElements contained in this experiment. - * @return a list of TmfTraceElements - */ - @Override - public List getTraces() { - List children = getChildren(); - List traces = new ArrayList<>(); - for (ITmfProjectModelElement child : children) { - if (child instanceof TmfTraceElement) { - traces.add((TmfTraceElement) child); - } - } - return traces; - } - - /** - * Adds a trace to the experiment - * - * @param trace The trace element to add - * @since 2.0 - */ - public void addTrace(TmfTraceElement trace) { - addTrace(trace, true); - } - - /** - * Adds a trace to the experiment - * - * @param trace The trace element to add - * @param refresh Flag for refreshing the project - * - * @since 3.1 - */ - public void addTrace(TmfTraceElement trace, boolean refresh) { - /** - * Create a link to the actual trace and set the trace type - */ - IFolder experiment = getResource(); - IResource resource = trace.getResource(); - IPath location = resource.getLocation(); - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - try { - String traceTypeId = TmfTraceType.getTraceTypeId(trace.getResource()); - TraceTypeHelper traceType = TmfTraceType.getTraceType(traceTypeId); - - if (resource instanceof IFolder) { - IFolder folder = experiment.getFolder(trace.getElementPath()); - TraceUtils.createFolder((IFolder) folder.getParent(), new NullProgressMonitor()); - IStatus result = workspace.validateLinkLocation(folder, location); - if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) { - folder.createLink(location, IResource.REPLACE, null); - if (traceType != null) { - TmfTraceTypeUIUtils.setTraceType(folder, traceType, refresh); - } - - } else { - Activator.getDefault().logError("Error creating link. Invalid trace location " + location); //$NON-NLS-1$ - } - } else { - IFile file = experiment.getFile(trace.getElementPath()); - TraceUtils.createFolder((IFolder) file.getParent(), new NullProgressMonitor()); - IStatus result = workspace.validateLinkLocation(file, location); - if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) { - file.createLink(location, IResource.REPLACE, null); - if (traceType != null) { - TmfTraceTypeUIUtils.setTraceType(file, traceType, refresh); - } - } else { - Activator.getDefault().logError("Error creating link. Invalid trace location " + location); //$NON-NLS-1$ - } - } - } catch (CoreException e) { - Activator.getDefault().logError("Error creating link to location " + location, e); //$NON-NLS-1$ - } - - } - - /** - * Removes a trace from an experiment - * - * @param trace The trace to remove - * @throws CoreException exception - * @since 2.0 - */ - public void removeTrace(TmfTraceElement trace) throws CoreException { - - // Close the experiment if open - closeEditors(); - - /* Finally, remove the trace from experiment*/ - removeChild(trace); - deleteTraceResource(trace.getResource()); - deleteSupplementaryResources(); - } - - private void deleteTraceResource(IResource resource) throws CoreException { - resource.delete(true, null); - IContainer parent = resource.getParent(); - // delete empty folders up to the parent experiment folder - if (!parent.equals(getResource()) && parent.members().length == 0) { - deleteTraceResource(parent); - } - } - - @Override - public IFile createBookmarksFile() throws CoreException { - return createBookmarksFile(getProject().getExperimentsFolder().getResource(), TmfExperiment.class.getCanonicalName()); - } - - @Override - public String getEditorId() { - /* See if a default editor was set for this experiment type */ - if (getTraceType() != null) { - IConfigurationElement ce = sfTraceTypeUIAttributes.get(getTraceType()); - if (ce != null) { - IConfigurationElement[] defaultEditorCE = ce.getChildren(TmfTraceTypeUIUtils.DEFAULT_EDITOR_ELEM); - if (defaultEditorCE.length == 1) { - return defaultEditorCE[0].getAttribute(TmfTraceType.ID_ATTR); - } - } - } - - /* No default editor, try to find a common editor for all traces */ - final List traceEntries = getTraces(); - String commonEditorId = null; - - for (TmfTraceElement element : traceEntries) { - // If all traces use the same editorId, use it, otherwise use the - // default - final String editorId = element.getEditorId(); - if (commonEditorId == null) { - commonEditorId = (editorId != null) ? editorId : TmfEventsEditor.ID; - } else if (!commonEditorId.equals(editorId)) { - commonEditorId = TmfEventsEditor.ID; - } - } - return null; - } - - /** - * Instantiate a {@link TmfExperiment} object based on the experiment type - * and the corresponding extension. - * - * @return the {@link TmfExperiment} or null for an error - * @since 3.0 - */ - @Override - public TmfExperiment instantiateTrace() { - try { - - // make sure that supplementary folder exists - refreshSupplementaryFolder(); - - if (getTraceType() != null) { - - IConfigurationElement ce = sfTraceTypeAttributes.get(getTraceType()); - if (ce == null) { - return null; - } - TmfExperiment experiment = (TmfExperiment) ce.createExecutableExtension(TmfTraceType.EXPERIMENT_TYPE_ATTR); - return experiment; - } - } catch (CoreException e) { - Activator.getDefault().logError(NLS.bind(Messages.TmfExperimentElement_ErrorInstantiatingTrace, getName()), e); - } - return null; - } - - @Override - public String getTypeName() { - return Messages.TmfExperimentElement_TypeName; - } - - // ------------------------------------------------------------------------ - // IPropertySource2 - // ------------------------------------------------------------------------ - - @Override - public Object getEditableValue() { - return null; - } - - @Override - public IPropertyDescriptor[] getPropertyDescriptors() { - return Arrays.copyOf(sfDescriptors, sfDescriptors.length); - } - - @Override - public Object getPropertyValue(Object id) { - - if (sfName.equals(id)) { - return getName(); - } - - if (sfPath.equals(id)) { - return getPath().toString(); - } - - if (sfLocation.equals(id)) { - return getLocation().toString(); - } - - if (sfExperimentType.equals(id)) { - if (getTraceType() != null) { - IConfigurationElement ce = sfTraceTypeAttributes.get(getTraceType()); - if (ce == null) { - return ""; //$NON-NLS-1$ - } - String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR); - if (categoryId != null) { - IConfigurationElement category = sfTraceCategories.get(categoryId); - if (category != null) { - return category.getAttribute(TmfTraceType.NAME_ATTR) + ':' + ce.getAttribute(TmfTraceType.NAME_ATTR); - } - } - return ce.getAttribute(TmfTraceType.NAME_ATTR); - } - } - - return null; - } - - @Override - public void resetPropertyValue(Object id) { - } - - @Override - public void setPropertyValue(Object id, Object value) { - } - - @Override - public boolean isPropertyResettable(Object id) { - return false; - } - - @Override - public boolean isPropertySet(Object id) { - return false; - } - - /** - * Return the suffix for resource names - * @return The folder suffix - */ - @Override - public String getSuffix() { - return sfFolderSuffix; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfExperimentFolder.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfExperimentFolder.java deleted file mode 100644 index 214f15c920..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfExperimentFolder.java +++ /dev/null @@ -1,196 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Add support for folder elements - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.linuxtools.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; -import org.eclipse.ui.views.properties.IPropertyDescriptor; -import org.eclipse.ui.views.properties.IPropertySource2; - -/** - * Implementation of model element representing the unique "Experiments" folder - * in the project. - *

- * - * @version 1.0 - * @author Francois Chouinard - * - */ -public class TmfExperimentFolder extends TmfProjectModelElement implements IPropertySource2 { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The name of the experiment folder. - */ - public static final String EXPER_FOLDER_NAME = "Experiments"; //$NON-NLS-1$ - - // Property View stuff - private static final String sfInfoCategory = "Info"; //$NON-NLS-1$ - private static final String sfName = "name"; //$NON-NLS-1$ - private static final String sfPath = "path"; //$NON-NLS-1$ - private static final String sfLocation = "location"; //$NON-NLS-1$ - - private static final ReadOnlyTextPropertyDescriptor sfNameDescriptor = new ReadOnlyTextPropertyDescriptor(sfName, sfName); - private static final ReadOnlyTextPropertyDescriptor sfPathDescriptor = new ReadOnlyTextPropertyDescriptor(sfPath, sfPath); - private static final ReadOnlyTextPropertyDescriptor sfLocationDescriptor = new ReadOnlyTextPropertyDescriptor(sfLocation, sfLocation); - - private static final IPropertyDescriptor[] sfDescriptors = { sfNameDescriptor, sfPathDescriptor, sfLocationDescriptor }; - - static { - sfNameDescriptor.setCategory(sfInfoCategory); - sfPathDescriptor.setCategory(sfInfoCategory); - sfLocationDescriptor.setCategory(sfInfoCategory); - } - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructor. - * Creates a TmfExperimentFolder model element. - * @param name The name of the folder - * @param folder The folder reference - * @param parent The parent (project element) - */ - public TmfExperimentFolder(String name, IFolder folder, TmfProjectElement parent) { - super(name, folder, parent); - parent.addChild(this); - } - - // ------------------------------------------------------------------------ - // TmfProjectModelElement - // ------------------------------------------------------------------------ - - @Override - public IFolder getResource() { - return (IFolder) fResource; - } - - @Override - void refreshChildren() { - IFolder folder = getResource(); - - // Get the children from the model - Map childrenMap = new HashMap<>(); - for (ITmfProjectModelElement element : getChildren()) { - childrenMap.put(element.getResource().getName(), element); - } - - try { - IResource[] members = folder.members(); - for (IResource resource : members) { - if (resource instanceof IFolder) { - IFolder expFolder = (IFolder) resource; - String name = resource.getName(); - ITmfProjectModelElement element = childrenMap.get(name); - if (element instanceof TmfExperimentElement) { - childrenMap.remove(name); - } else { - element = new TmfExperimentElement(name, expFolder, this); - } - ((TmfExperimentElement) element).refreshChildren(); - } - } - } catch (CoreException e) { - } - - // Cleanup dangling children from the model - for (ITmfProjectModelElement danglingChild : childrenMap.values()) { - removeChild(danglingChild); - } - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Returns a list of experiment model elements under the experiments folder. - * @return list of experiment model elements - * @since 3.0 - */ - public List getExperiments() { - List children = getChildren(); - List traces = new ArrayList<>(); - for (ITmfProjectModelElement child : children) { - if (child instanceof TmfExperimentElement) { - traces.add((TmfExperimentElement) child); - } - } - return traces; - } - - // ------------------------------------------------------------------------ - // IPropertySource2 - // ------------------------------------------------------------------------ - - @Override - public Object getEditableValue() { - return null; - } - - @Override - public IPropertyDescriptor[] getPropertyDescriptors() { - return Arrays.copyOf(sfDescriptors, sfDescriptors.length); - } - - @Override - public Object getPropertyValue(Object id) { - - if (sfName.equals(id)) { - return getName(); - } - - if (sfPath.equals(id)) { - return getPath().toString(); - } - - if (sfLocation.equals(id)) { - return getLocation().toString(); - } - - return null; - } - - @Override - public void resetPropertyValue(Object id) { - } - - @Override - public void setPropertyValue(Object id, Object value) { - } - - @Override - public boolean isPropertyResettable(Object id) { - return false; - } - - @Override - public boolean isPropertySet(Object id) { - return false; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfNavigatorContentProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfNavigatorContentProvider.java deleted file mode 100644 index 30e128ebdc..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfNavigatorContentProvider.java +++ /dev/null @@ -1,193 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Implement getParent() - * Patrick Tasse - Add support for folder elements - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import java.util.Set; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.ui.IMemento; -import org.eclipse.ui.navigator.ICommonContentExtensionSite; -import org.eclipse.ui.navigator.IPipelinedTreeContentProvider; -import org.eclipse.ui.navigator.PipelinedShapeModification; -import org.eclipse.ui.navigator.PipelinedViewerUpdate; - -/** - * The TMF project content provider for the tree viewer in the project explorer view. - *

- * @version 1.0 - * @author Francois Chouinard - */ -public class TmfNavigatorContentProvider implements IPipelinedTreeContentProvider { - - // ------------------------------------------------------------------------ - // ICommonContentProvider - // ------------------------------------------------------------------------ - - @Override - public Object[] getElements(Object inputElement) { - return null; - } - - @Override - public Object getParent(Object element) { - if (element instanceof IProject) { - IProject project = (IProject) element; - return project.getParent(); - } - - if (element instanceof TmfTracesFolder) { - TmfTracesFolder folder = (TmfTracesFolder) element; - // Return the corresponding IProject as parent because from CNF point of view the IProject is the parent. - // The IProject is needed e.g. for link with Editor to work correctly. - return folder.getParent().getResource(); - } - - if (element instanceof TmfExperimentFolder) { - TmfExperimentFolder folder = (TmfExperimentFolder) element; - // Return the corresponding IProject as parent because from CNF point of view the IProject is the parent. - // The IProject is needed e.g. for link with Editor to work correctly. - return folder.getParent().getResource(); - } - - if (element instanceof ITmfProjectModelElement) { - ITmfProjectModelElement modelElement = (ITmfProjectModelElement) element; - return modelElement.getParent(); - } - - return null; - } - - @Override - public boolean hasChildren(Object element) { - if (element instanceof IProject) { - IProject project = (IProject) element; - return project.isAccessible(); - } - if (element instanceof ITmfProjectModelElement) { - ITmfProjectModelElement modelElement = (ITmfProjectModelElement) element; - return modelElement.hasChildren(); - } - return false; - } - - @Override - public void dispose() { - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - @Override - public void restoreState(IMemento aMemento) { - } - - @Override - public void saveState(IMemento aMemento) { - } - - @Override - public void init(ICommonContentExtensionSite aConfig) { - } - - // ------------------------------------------------------------------------ - // ICommonContentProvider - getChildren() - // ------------------------------------------------------------------------ - - @Override - public synchronized Object[] getChildren(Object parentElement) { - - // Tracing project level - if (parentElement instanceof IProject) { - TmfProjectElement element = TmfProjectRegistry.getProject((IProject) parentElement, true); - return element.getChildren().toArray(); - } - - // Other project model elements - if (parentElement instanceof ITmfProjectModelElement) { - return ((ITmfProjectModelElement) parentElement).getChildren().toArray(); - } - - return new Object[0]; - } - - // ------------------------------------------------------------------------ - // IPipelinedTreeContentProvider - // ------------------------------------------------------------------------ - - @Override - public void getPipelinedChildren(Object parent, Set currentChildren) { - customizeTmfElements(getChildren(parent), currentChildren); - } - - @Override - public void getPipelinedElements(Object input, Set currentElements) { - customizeTmfElements(getElements(input), currentElements); - } - - /** - * Add/replace the ITmfProjectElement to the list of children - * - * @param elements - * the list returned by getChildren() - * @param children - * the current children - */ - private static void customizeTmfElements(Object[] elements, - Set children) { - if (elements != null && children != null) { - for (Object element : elements) { - if (element instanceof ITmfProjectModelElement) { - ITmfProjectModelElement tmfElement = (ITmfProjectModelElement) element; - IResource resource = tmfElement.getResource(); - if (resource != null) { - children.remove(resource); - } - children.add(element); - } - else if (element != null) { - children.add(element); - } - } - } - } - - @Override - public Object getPipelinedParent(Object anObject, Object aSuggestedParent) { - return aSuggestedParent; - } - - @Override - public PipelinedShapeModification interceptAdd(PipelinedShapeModification anAddModification) { - return anAddModification; - } - - @Override - public PipelinedShapeModification interceptRemove(PipelinedShapeModification aRemoveModification) { - return null; - } - - @Override - public boolean interceptRefresh(PipelinedViewerUpdate aRefreshSynchronization) { - return false; - } - - @Override - public boolean interceptUpdate(PipelinedViewerUpdate anUpdateSynchronization) { - return false; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfNavigatorLabelProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfNavigatorLabelProvider.java deleted file mode 100644 index d1d7cbb6db..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfNavigatorLabelProvider.java +++ /dev/null @@ -1,267 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Add support for unknown trace type icon - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import java.net.URL; - -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.Platform; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider; -import org.eclipse.jface.viewers.ILabelProviderListener; -import org.eclipse.jface.viewers.StyledString; -import org.eclipse.jface.viewers.StyledString.Styler; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType.TraceElementType; -import org.eclipse.swt.graphics.Image; -import org.eclipse.ui.IMemento; -import org.eclipse.ui.ISharedImages; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.model.WorkbenchLabelProvider; -import org.eclipse.ui.navigator.ICommonContentExtensionSite; -import org.eclipse.ui.navigator.ICommonLabelProvider; -import org.osgi.framework.Bundle; - -/** - * The TMF project label provider for the tree viewer in the project explorer view. - *

- * @version 1.0 - * @author Francois Chouinard - */ -public class TmfNavigatorLabelProvider implements ICommonLabelProvider, IStyledLabelProvider { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - private static final Image fFolderIcon = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER); - private static final String fTraceIconFile = "icons/elcl16/trace.gif"; //$NON-NLS-1$ - private static final String fExperimentIconFile = "icons/elcl16/experiment.gif"; //$NON-NLS-1$ - private static final String fAnalysisIconFile = "icons/ovr16/experiment_folder_ovr.png"; //$NON-NLS-1$ - private static final String fViewIconFile = "icons/obj16/node_obj.gif"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final Image fTraceFolderIcon = fFolderIcon; - private final Image fExperimentFolderIcon = fFolderIcon; - - private final Image fDefaultTraceIcon; - private final Image fExperimentIcon; - private final Image fDefaultAnalysisIcon; - private final Image fDefaultViewIcon; - - private final WorkbenchLabelProvider fWorkspaceLabelProvider = new WorkbenchLabelProvider(); - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructor. - * - * Creates the TMF navigator content provider. - */ - public TmfNavigatorLabelProvider() { - Bundle bundle = Activator.getDefault().getBundle(); - fDefaultTraceIcon = loadIcon(bundle, fTraceIconFile); - fExperimentIcon = loadIcon(bundle, fExperimentIconFile); - fDefaultAnalysisIcon = loadIcon(bundle, fAnalysisIconFile); - fDefaultViewIcon = loadIcon(bundle, fViewIconFile); - } - - private static Image loadIcon(Bundle bundle, String url) { - Activator plugin = Activator.getDefault(); - String key = bundle.getSymbolicName() + "/" + url; //$NON-NLS-1$ - Image icon = plugin.getImageRegistry().get(key); - if (icon == null) { - URL imageURL = bundle.getResource(url); - ImageDescriptor descriptor = ImageDescriptor.createFromURL(imageURL); - if (descriptor != null) { - icon = descriptor.createImage(); - plugin.getImageRegistry().put(key, icon); - } - } - return icon; - } - - // ------------------------------------------------------------------------ - // ICommonLabelProvider - // ------------------------------------------------------------------------ - - @Override - public Image getImage(Object element) { - - if (element instanceof TmfCommonProjectElement) { - TmfCommonProjectElement trace = (TmfCommonProjectElement) element; - String traceType = trace.getTraceType(); - if (traceType == null || TmfTraceType.getTraceType(traceType) == null) { - // request the label to the Eclipse platform - return fWorkspaceLabelProvider.getImage(((TmfCommonProjectElement) element).getResource()); - } - - IConfigurationElement traceUIAttributes = TmfTraceTypeUIUtils.getTraceUIAttributes(traceType, (element instanceof TmfTraceElement) ? TraceElementType.TRACE : TraceElementType.EXPERIMENT); - if (traceUIAttributes != null) { - String iconAttr = traceUIAttributes.getAttribute(TmfTraceTypeUIUtils.ICON_ATTR); - if (iconAttr != null) { - String name = traceUIAttributes.getContributor().getName(); - if (name != null) { - Bundle bundle = Platform.getBundle(name); - if (bundle != null) { - Image image = loadIcon(bundle, iconAttr); - if (image != null) { - return image; - } - } - } - } - - } - if (element instanceof TmfTraceElement) { - return fDefaultTraceIcon; - } - return fExperimentIcon; - } - - if (element instanceof TmfExperimentFolder) { - return fExperimentFolderIcon; - } - - if (element instanceof TmfTraceFolder) { - return fTraceFolderIcon; - } - - if (element instanceof TmfAnalysisOutputElement) { - TmfAnalysisOutputElement output = (TmfAnalysisOutputElement) element; - Image icon = output.getIcon(); - if (icon == null) { - return fDefaultViewIcon; - } - return icon; - } - - if (element instanceof TmfAnalysisElement) { - TmfAnalysisElement analysis = (TmfAnalysisElement) element; - String iconFile = analysis.getIconFile(); - if (iconFile != null) { - Bundle bundle = analysis.getBundle(); - if (bundle != null) { - Image icon = loadIcon(bundle, iconFile); - return icon; - } - } - return fDefaultAnalysisIcon; - } - - return null; - } - - @Override - public String getText(Object element) { - - if (element instanceof TmfTracesFolder) { - TmfTracesFolder folder = (TmfTracesFolder) element; - return folder.getName() + " [" + folder.getTraces().size() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - if (element instanceof TmfTraceFolder) { - TmfTraceFolder folder = (TmfTraceFolder) element; - int nbTraces = folder.getTraces().size(); - if (nbTraces > 0) { - return folder.getName() + " [" + folder.getTraces().size() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ - } - return folder.getName(); - } - - if (element instanceof TmfTraceElement) { - TmfTraceElement trace = (TmfTraceElement) element; - if (trace.getParent() instanceof TmfExperimentElement) { - return trace.getElementPath(); - } - return trace.getName(); - } - - if (element instanceof TmfExperimentElement) { - TmfExperimentElement folder = (TmfExperimentElement) element; - return folder.getName() + " [" + folder.getTraces().size() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - if (element instanceof TmfExperimentFolder) { - TmfExperimentFolder folder = (TmfExperimentFolder) element; - return folder.getName() + " [" + folder.getChildren().size() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - // Catch all - if (element instanceof ITmfProjectModelElement) { - return ((ITmfProjectModelElement) element).getName(); - } - - return null; - } - - @Override - public void addListener(ILabelProviderListener listener) { - } - - @Override - public void dispose() { - } - - @Override - public boolean isLabelProperty(Object element, String property) { - return false; - } - - @Override - public void removeListener(ILabelProviderListener listener) { - } - - @Override - public void restoreState(IMemento aMemento) { - } - - @Override - public void saveState(IMemento aMemento) { - } - - @Override - public String getDescription(Object anElement) { - return getText(anElement); - } - - @Override - public void init(ICommonContentExtensionSite aConfig) { - } - - /** - * @since 3.0 - */ - @Override - public StyledString getStyledText(Object element) { - String text = getText(element); - if (text != null) { - if (element instanceof ITmfStyledProjectModelElement) { - Styler styler = ((ITmfStyledProjectModelElement) element).getStyler(); - if (styler != null) { - return new StyledString(text, styler); - } - } - return new StyledString(text); - } - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfOpenTraceHelper.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfOpenTraceHelper.java deleted file mode 100644 index 1441a4c635..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfOpenTraceHelper.java +++ /dev/null @@ -1,464 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Patrick Tasse - Update open trace and add open experiment - * Geneviève Bastien - Merge methods to open trace and experiments - * Bernd Hufmann - Updated handling of directory traces - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import java.io.File; -import java.util.List; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.URIUtil; -import org.eclipse.jface.util.OpenStrategy; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.project.model.TmfImportHelper; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceImportException; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; -import org.eclipse.linuxtools.tmf.ui.editors.TmfEditorInput; -import org.eclipse.linuxtools.tmf.ui.editors.TmfEventsEditor; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.MessageBox; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IEditorReference; -import org.eclipse.ui.IReusableEditor; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.ide.IDE; -import org.eclipse.ui.part.FileEditorInput; - -/** - * Open trace helper - * - * Helper class for opening trace resources and loading them to a tracing - * project. - * - * @author Matthew Khouzam - * @since 2.1 - */ -public class TmfOpenTraceHelper { - - private TmfOpenTraceHelper() { - } - - private static final String ENDL = System.getProperty("line.separator"); //$NON-NLS-1$ - - /** - * Opens a trace from a path while importing it to the destination folder. - * The trace is linked as a resource. - * - * @param destinationFolder - * The destination trace folder - * @param path - * the file to import - * @param shell - * the shell to use for dialogs - * @return IStatus OK if successful - * @throws CoreException - * core exceptions if something is not well set up in the back - * end - * @since 3.0 - */ - public static IStatus openTraceFromPath(TmfTraceFolder destinationFolder, String path, Shell shell) throws CoreException { - return openTraceFromPath(destinationFolder, path, shell, null); - } - - /** - * Opens a trace from a path while importing it to the destination folder. - * The trace is linked as a resource. - * - * @param destinationFolder - * The destination trace folder - * @param path - * the file to import - * @param shell - * the shell to use for dialogs - * @param tracetypeHint - * The trace type id, can be null - * @return IStatus OK if successful - * @throws CoreException - * core exceptions if something is not well set up in the back - * end - * - * @since 3.0 - */ - public static IStatus openTraceFromPath(TmfTraceFolder destinationFolder, String path, Shell shell, String tracetypeHint) throws CoreException { - final String pathToUse = checkTracePath(path); - TraceTypeHelper traceTypeToSet = null; - try { - traceTypeToSet = TmfTraceTypeUIUtils.selectTraceType(pathToUse, null, tracetypeHint); - } catch (TmfTraceImportException e) { - MessageBox mb = new MessageBox(shell); - mb.setMessage(e.getMessage()); - mb.open(); - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage()); - } - - IFolder folder = destinationFolder.getResource(); - String traceName = getTraceName(pathToUse, folder); - if (traceExists(pathToUse, folder)) { - return openTraceFromFolder(destinationFolder, traceName); - } - final IPath pathString = Path.fromOSString(pathToUse); - IResource linkedTrace = TmfImportHelper.createLink(folder, pathString, traceName); - - if (linkedTrace == null || !linkedTrace.exists()) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, - Messages.TmfOpenTraceHelper_LinkFailed); - } - - String sourceLocation = URIUtil.toUnencodedString(pathString.toFile().toURI()); - linkedTrace.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation); - - // No trace type was determined. - if (traceTypeToSet == null) { - return Status.OK_STATUS; - } - - IStatus ret = TmfTraceTypeUIUtils.setTraceType(linkedTrace, traceTypeToSet); - if (ret.isOK()) { - ret = openTraceFromFolder(destinationFolder, traceName); - } - return ret; - } - - /** - * Checks whether the parent or grandparent of given path to a file is a - * valid directory trace. If it is a directory trace then return the parent - * or grandparent path. - * - * @param path - * the path to check - * @return path to use for trace type validation. - */ - private static String checkTracePath(String path) { - File file = new File(path); - if (file.exists() && !file.isDirectory()) { - // First check parent - File parent = file.getParentFile(); - String pathToUse = parent.getAbsolutePath(); - if (TmfTraceType.isDirectoryTrace(pathToUse)) { - return pathToUse; - } - // Second check grandparent - File grandParent = parent.getParentFile(); - if (grandParent != null) { - pathToUse = grandParent.getAbsolutePath(); - if (TmfTraceType.isDirectoryTrace(pathToUse)) { - return pathToUse; - } - } - } - return path; - } - - private static boolean traceExists(String path, IFolder folder) { - String val = getTraceName(path, folder); - return (folder.findMember(val) != null); - } - - private static boolean isWrongMember(IFolder folder, String name, final File traceFile) { - final IResource candidate = folder.findMember(name); - if (candidate != null) { - final IPath rawLocation = candidate.getRawLocation(); - final File file = rawLocation.toFile(); - return !file.equals(traceFile); - } - return false; - } - - /** - * Gets the display name, either "filename" or "filename(n)" if there is - * already a filename existing where n is the next unused integer starting - * from 2 - * - * @param path - * the file path - * @param folder - * the folder to import to - * @return the filename - */ - private static String getTraceName(String path, IFolder folder) { - String name; - final File traceFile = new File(path); - name = traceFile.getName(); - for (int i = 2; isWrongMember(folder, name, traceFile); i++) { - name = traceFile.getName() + '(' + i + ')'; - } - return name; - } - - /** - * Open a trace from a trace folder - * - * @param destinationFolder - * The destination trace folder - * @param traceName - * the trace name - * @return success or error - * @since 3.0 - */ - private static IStatus openTraceFromFolder(TmfTraceFolder destinationFolder, String traceName) { - final List elements = destinationFolder.getChildren(); - TmfTraceElement traceElement = null; - for (ITmfProjectModelElement element : elements) { - if (element instanceof TmfTraceElement && element.getName().equals(traceName)) { - traceElement = (TmfTraceElement) element; - } - } - if (traceElement == null) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(Messages.TmfOpenTraceHelper_TraceNotFound, traceName)); - } - openTraceFromElement(traceElement); - return Status.OK_STATUS; - } - - private static ITmfTrace openTraceElement(final TmfTraceElement traceElement) { - final ITmfTrace trace = traceElement.instantiateTrace(); - final ITmfEvent traceEvent = traceElement.instantiateEvent(); - if ((trace == null) || (traceEvent == null)) { - TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, traceElement.getTypeName()), - Messages.TmfOpenTraceHelper_NoTraceType); - if (trace != null) { - trace.dispose(); - } - return null; - } - - try { - trace.initTrace(traceElement.getResource(), traceElement.getResource().getLocation().toOSString(), traceEvent.getClass(), traceElement.getElementPath()); - } catch (final TmfTraceException e) { - TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, traceElement.getTypeName()), - Messages.TmfOpenTraceHelper_InitError + ENDL + ENDL + e); - trace.dispose(); - return null; - } - return trace; - } - - private static ITmfTrace openExperimentElement(final TmfExperimentElement experimentElement) { - /* Experiment element now has an experiment type associated with it */ - final TmfExperiment experiment = experimentElement.instantiateTrace(); - if (experiment == null) { - TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, experimentElement.getTypeName()), - NLS.bind(Messages.TmfOpenTraceHelper_NoTraceOrExperimentType, experimentElement.getTypeName())); - return null; - } - - // Instantiate the experiment's traces - final List traceEntries = experimentElement.getTraces(); - int cacheSize = Integer.MAX_VALUE; - final ITmfTrace[] traces = new ITmfTrace[traceEntries.size()]; - for (int i = 0; i < traceEntries.size(); i++) { - TmfTraceElement element = traceEntries.get(i); - - // Since trace is under an experiment, use the original trace from - // the traces folder - element = element.getElementUnderTraceFolder(); - - ITmfTrace trace = openTraceElement(element); - - if (trace == null) { - for (int j = 0; j < i; j++) { - traces[j].dispose(); - } - return null; - } - cacheSize = Math.min(cacheSize, trace.getCacheSize()); - - traces[i] = trace; - } - - // Create the experiment - experiment.initExperiment(ITmfEvent.class, experimentElement.getName(), traces, cacheSize, experimentElement.getResource()); - - return experiment; - } - - private static ITmfTrace openProjectElement(final TmfCommonProjectElement element) { - ITmfTrace trace = null; - if (element instanceof TmfTraceElement) { - trace = openTraceElement((TmfTraceElement) element); - } else if (element instanceof TmfExperimentElement) { - trace = openExperimentElement((TmfExperimentElement) element); - } - return trace; - } - - /** - * Open a trace (or experiment) from a project element. If the trace is already opened, its - * editor is activated and brought to top. - * - * @param traceElement - * the {@link TmfTraceElement} to open - * @since 3.0 - */ - public static void openTraceFromElement(final TmfCommonProjectElement traceElement) { - - final IFile file; - try { - file = traceElement.createBookmarksFile(); - } catch (final CoreException e) { - Activator.getDefault().logError(NLS.bind(Messages.TmfOpenTraceHelper_ErrorOpeningElement, traceElement.getTypeName()) + ' ' + traceElement.getName()); - TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, traceElement.getTypeName()), - NLS.bind(Messages.TmfOpenTraceHelper_ErrorElement, traceElement.getTypeName()) + ENDL + ENDL + e.getMessage()); - return; - } - - final IWorkbench wb = PlatformUI.getWorkbench(); - final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); - final IEditorPart editor = findEditor(new FileEditorInput(file), true); - if (editor != null) { - activePage.activate(editor); - return; - } - - // If a trace type is not set then delegate it to the eclipse platform - if ((traceElement instanceof TmfTraceElement) && (traceElement.getResource() instanceof IFile) && (traceElement.getTraceType() == null)) { - try { - boolean activate = OpenStrategy.activateOnOpen(); - // only local open is supported - IDE.openEditor(activePage, file, activate); - } catch (PartInitException e) { - TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, traceElement.getTypeName()), - NLS.bind(Messages.TmfOpenTraceHelper_ErrorOpeningElement, traceElement.getElementPath()) + ENDL + ENDL + e.getMessage()); - } - return; - } - - Thread thread = new Thread() { - @Override - public void run() { - final ITmfTrace trace = openProjectElement(traceElement); - - if (trace == null) { - return; - } - - // Get the editor id from the extension point - String traceEditorId = traceElement.getEditorId(); - final String editorId = (traceEditorId != null) ? traceEditorId : TmfEventsEditor.ID; - final IEditorInput editorInput = new TmfEditorInput(file, trace); - - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - try { - activePage.openEditor(editorInput, editorId); - IDE.setDefaultEditor(file, editorId); - // editor should dispose the trace on close - } catch (final PartInitException e) { - TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, traceElement.getTypeName()), - NLS.bind(Messages.TmfOpenTraceHelper_ErrorOpeningElement, traceElement.getTypeName()) + ENDL + ENDL + e.getMessage()); - Activator.getDefault().logError(NLS.bind(Messages.TmfOpenTraceHelper_ErrorOpeningElement, traceElement.getTypeName()) + ' ' + traceElement.getName()); - trace.dispose(); - } - } - }); - } - }; - thread.start(); - } - - /** - * Returns the editor with the specified input. Returns null if there is no - * opened editor with that input. If restore is requested, the method finds - * and returns the editor even if it is not restored yet after a restart. - * - * @param input - * the editor input - * @param restore - * true if the editor should be restored - * @return an editor with input equals to input - */ - private static IEditorPart findEditor(IEditorInput input, boolean restore) { - final IWorkbench wb = PlatformUI.getWorkbench(); - final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); - for (IEditorReference editorReference : activePage.getEditorReferences()) { - try { - IEditorInput editorInput = editorReference.getEditorInput(); - if (editorInput.equals(input)) { - return editorReference.getEditor(restore); - } - } catch (PartInitException e) { - } - } - return null; - } - - /** - * Reopen a trace or experiment from a project element in the provided - * editor - * - * @param traceElement - * the {@link TmfTraceElement} to open - * @param editor - * the reusable editor - * @since 3.0 - */ - public static void reopenTraceFromElement(final TmfCommonProjectElement traceElement, final IReusableEditor editor) { - - final IFile file; - try { - file = traceElement.createBookmarksFile(); - } catch (final CoreException e) { - Activator.getDefault().logError(NLS.bind(Messages.TmfOpenTraceHelper_ErrorOpeningElement, traceElement.getTypeName()) + ' ' + traceElement.getName()); - TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, traceElement.getTypeName()), - NLS.bind(Messages.TmfOpenTraceHelper_ErrorElement, traceElement.getTypeName()) + ENDL + ENDL + e.getMessage()); - return; - } - - Thread thread = new Thread() { - @Override - public void run() { - - final ITmfTrace trace = openProjectElement(traceElement); - if (trace == null) { - return; - } - - final IEditorInput editorInput = new TmfEditorInput(file, trace); - - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - final IWorkbench wb = PlatformUI.getWorkbench(); - final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); - activePage.reuseEditor(editor, editorInput); - activePage.activate(editor); - } - }); - } - }; - thread.start(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfProjectElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfProjectElement.java deleted file mode 100644 index 29265e4a09..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfProjectElement.java +++ /dev/null @@ -1,146 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Refactor resource change listener - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; - -/** - * The implementation of TMF project model element. - * - * @version 1.0 - * @author Francois Chouinard - */ -public class TmfProjectElement extends TmfProjectModelElement { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private TmfTraceFolder fTraceFolder = null; - private TmfExperimentFolder fExperimentFolder = null; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - /** - * Constructor. - * - * Creates the TMF project model element. - * @param name The name of the project. - * @param project The project reference. - * @param parent The parent element - */ - public TmfProjectElement(String name, IProject project, ITmfProjectModelElement parent) { - super(name, project, parent); - } - - // ------------------------------------------------------------------------ - // TmfProjectModelElement - // ------------------------------------------------------------------------ - - @Override - public IProject getResource() { - return (IProject) fResource; - } - - @Override - public void addChild(ITmfProjectModelElement child) { - super.addChild(child); - if (child instanceof TmfTraceFolder) { - fTraceFolder = (TmfTraceFolder) child; - return; - } - if (child instanceof TmfExperimentFolder) { - fExperimentFolder = (TmfExperimentFolder) child; - return; - } - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Returns the containing trace folder element. - * @return the TMF trace folder element. - */ - public TmfTraceFolder getTracesFolder() { - return fTraceFolder; - } - - /** - * Returns the containing experiment folder element. - * @return the TMF experiment folder element. - */ - public TmfExperimentFolder getExperimentsFolder() { - return fExperimentFolder; - } - - // ------------------------------------------------------------------------ - // TmfProjectModelElement - // ------------------------------------------------------------------------ - - @Override - void refreshChildren() { - IProject project = getResource(); - - // Get the children from the model - Map childrenMap = new HashMap<>(); - for (ITmfProjectModelElement element : getChildren()) { - childrenMap.put(element.getResource().getName(), element); - } - - // Add the model folder if the corresponding resource exists and is not - // accounted for - IFolder folder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME); - if (folder != null && folder.exists()) { - String name = folder.getName(); - ITmfProjectModelElement element = childrenMap.get(name); - if (element instanceof TmfTracesFolder) { - childrenMap.remove(name); - } else { - element = new TmfTracesFolder(TmfTracesFolder.TRACES_FOLDER_NAME, folder, this); - } - ((TmfTracesFolder) element).refreshChildren(); - } - - // Add the model folder if the corresponding resource exists and is not - // accounted for - folder = project.getFolder(TmfExperimentFolder.EXPER_FOLDER_NAME); - if (folder != null && folder.exists()) { - String name = folder.getName(); - ITmfProjectModelElement element = childrenMap.get(name); - if (element instanceof TmfExperimentFolder) { - childrenMap.remove(name); - } else { - element = new TmfExperimentFolder(TmfExperimentFolder.EXPER_FOLDER_NAME, folder, this); - } - ((TmfExperimentFolder) element).refreshChildren(); - } - - // Cleanup dangling children from the model - for (ITmfProjectModelElement danglingChild : childrenMap.values()) { - removeChild(danglingChild); - } - } - - @Override - public TmfProjectElement getProject() { - return this; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfProjectModelElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfProjectModelElement.java deleted file mode 100644 index a958d24bb4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfProjectModelElement.java +++ /dev/null @@ -1,271 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Added supplementary files/folder handling - * Patrick Tasse - Refactor resource change listener - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import java.io.File; -import java.net.URI; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IViewPart; -import org.eclipse.ui.IViewReference; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.navigator.CommonNavigator; -import org.eclipse.ui.navigator.CommonViewer; - -/** - * The implementation of the base TMF project model element. It provides default implementation - * of the ITmfProjectModelElement interface. - *

- * @version 1.0 - * @author Francois Chouinard - */ -public abstract class TmfProjectModelElement implements ITmfProjectModelElement { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final String fName; - /** - * The project model element resource. - */ - protected final IResource fResource; - /** - * The project model resource location (URI) - */ - protected final URI fLocation; - /** - * The project model path of a resource. - */ - protected final IPath fPath; - private final ITmfProjectModelElement fParent; - /** - * The list of children elements. - */ - protected final List fChildren; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - /** - * Constructor. - * - * Creates a base project model element. - * @param name The name of the element. - * @param resource The element resource. - * @param parent The parent model element. - */ - protected TmfProjectModelElement(String name, IResource resource, ITmfProjectModelElement parent) { - fName = name; - fResource = resource; - fPath = resource.getFullPath(); - fLocation = new File(resource.getLocationURI()).toURI(); - fParent = parent; - fChildren = new CopyOnWriteArrayList<>(); - } - - // ------------------------------------------------------------------------ - // ITmfProjectModelElement - // ------------------------------------------------------------------------ - - @Override - public String getName() { - return fName; - } - - @Override - public IResource getResource() { - return fResource; - } - - @Override - public IPath getPath() { - return fPath; - } - - @Override - public URI getLocation() { - return fLocation; - } - - /** - * @since 3.0 - */ - @Override - public TmfProjectElement getProject() { - return fParent.getProject(); - } - - @Override - public ITmfProjectModelElement getParent() { - return fParent; - } - - @Override - public boolean hasChildren() { - return fChildren.size() > 0; - } - - @Override - public List getChildren() { - return fChildren; - } - - @Override - public void addChild(ITmfProjectModelElement child) { - fChildren.add(child); - } - - @Override - public void removeChild(ITmfProjectModelElement child) { - fChildren.remove(child); - } - - @Override - public void refresh() { - // make sure the model is updated in the current thread - refreshChildren(); - - Display.getDefault().asyncExec(new Runnable(){ - @Override - public void run() { - IWorkbench wb = PlatformUI.getWorkbench(); - IWorkbenchWindow wbWindow = wb.getActiveWorkbenchWindow(); - if (wbWindow == null) { - return; - } - IWorkbenchPage activePage = wbWindow.getActivePage(); - if (activePage == null) { - return; - } - - for (IViewReference viewReference : activePage.getViewReferences()) { - IViewPart viewPart = viewReference.getView(false); - if (viewPart instanceof CommonNavigator) { - CommonViewer commonViewer = ((CommonNavigator) viewPart).getCommonViewer(); - Object element = TmfProjectModelElement.this; - if (element instanceof TmfProjectElement) { - // for the project element the viewer uses the IProject resource - element = getResource(); - } - commonViewer.refresh(element); - } - } - }}); - } - - // ------------------------------------------------------------------------ - // Object - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((fPath == null) ? 0 : fPath.hashCode()); - return result; - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - if (other == null) { - return false; - } - if (!(other instanceof TmfProjectModelElement)) { - return false; - } - TmfProjectModelElement element = (TmfProjectModelElement) other; - return element.fPath.equals(fPath); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Refresh the children of this model element, adding new children and - * removing dangling children as necessary. The remaining children should - * also refresh their own children sub-tree. - */ - void refreshChildren() { - // Sub-classes may override this method as needed - } - - /** - * Returns the trace specific supplementary folder under the project's - * supplementary folder. The returned folder and its parent folders may not - * exist. - * - * @param supplFolderPath - * folder path relative to the project's supplementary folder - * @return the trace specific supplementary folder - */ - public IFolder getTraceSupplementaryFolder(String supplFolderPath) { - TmfProjectElement project = getProject(); - IProject projectResource = project.getResource(); - IFolder supplFolderParent = projectResource.getFolder(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER_NAME); - IFolder folder = supplFolderParent.getFolder(supplFolderPath); - return folder; - } - - /** - * Returns the trace specific supplementary folder under the project's - * supplementary folder. Its parent folders will be created if they don't - * exist. If createFolder is true, the returned folder will be created, - * otherwise it may not exist. - * - * @param supplFolderPath - * folder path relative to the project's supplementary folder - * @param createFolder - * if true, the returned folder will be created - * @return the trace specific supplementary folder - * @since 3.0 - */ - public IFolder prepareTraceSupplementaryFolder(String supplFolderPath, boolean createFolder) { - IFolder folder = getTraceSupplementaryFolder(supplFolderPath); - try { - if (createFolder) { - TraceUtils.createFolder(folder, new NullProgressMonitor()); - } else { - TraceUtils.createFolder((IFolder) folder.getParent(), new NullProgressMonitor()); - } - } catch (CoreException e) { - Activator.getDefault().logError("Error creating supplementary folder " + folder.getFullPath(), e); //$NON-NLS-1$ - } - return folder; - } - - @Override - public String toString() { - return getClass().getSimpleName() + '(' + getPath() + ')'; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfProjectRegistry.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfProjectRegistry.java deleted file mode 100644 index 2cc37f4a82..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfProjectRegistry.java +++ /dev/null @@ -1,205 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Added project creation utility - * Patrick Tasse - Refactor resource change listener - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IProjectDescription; -import org.eclipse.core.resources.IResourceChangeEvent; -import org.eclipse.core.resources.IResourceChangeListener; -import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.TmfProjectNature; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.actions.WorkspaceModifyOperation; - -/** - * Factory class storing TMF tracing projects and creating TMF project model elements. - *

- * @version 1.0 - * @author Francois Chouinard - */ -public class TmfProjectRegistry implements IResourceChangeListener { - - // Create the singleton instance - static { - new TmfProjectRegistry(); - } - - // The map of project resource to project model elements - private static Map registry = new HashMap<>(); - - private TmfProjectRegistry() { - ResourcesPlugin.getWorkspace().addResourceChangeListener(this); - } - - /** - * Get the project model element for a project resource - * @param project the project resource - * @return the project model element or null if it does not exist - */ - public static synchronized TmfProjectElement getProject(IProject project) { - return getProject(project, false); - } - - /** - * Get the project model element for a project resource - * @param project the project resource - * @param force a flag controlling whether a new project should be created if it doesn't exist - * @return the project model element - */ - public static synchronized TmfProjectElement getProject(IProject project, boolean force) { - TmfProjectElement element = registry.get(project); - if (element == null && force) { - registry.put(project, new TmfProjectElement(project.getName(), project, null)); - element = registry.get(project); - // force the model to be populated - element.refreshChildren(); - } - return element; - } - - /** - * Utility method to create a tracing project. - * - * @param projectName - * - A project name - * @param projectLocation - * - A project location URI. Use null for default location (which is workspace). - * @param monitor - * - A progress monitor - * @return the IProject object or null - * @since 2.0 - */ - public static IProject createProject(String projectName, final URI projectLocation, IProgressMonitor monitor) { - - final IWorkspace workspace = ResourcesPlugin.getWorkspace(); - IWorkspaceRoot root = workspace.getRoot(); - final IProject project = root.getProject(projectName); - WorkspaceModifyOperation action = new WorkspaceModifyOperation() { - @Override - protected void execute(IProgressMonitor progressMonitor) throws CoreException, InvocationTargetException, InterruptedException { - if (!project.exists()) { - IProjectDescription description = workspace.newProjectDescription(project.getName()); - if (projectLocation != null) { - description.setLocationURI(projectLocation); - } - project.create(description, progressMonitor); - } - - if (!project.isOpen()) { - project.open(progressMonitor); - } - - IProjectDescription description = project.getDescription(); - description.setNatureIds(new String[] { TmfProjectNature.ID }); - project.setDescription(description, null); - - IFolder folder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME); - if (!folder.exists()) { - folder.create(true, true, null); - } - - folder = project.getFolder(TmfExperimentFolder.EXPER_FOLDER_NAME); - if (!folder.exists()) { - folder.create(true, true, null); - } - - // create folder for supplementary tracing files - folder = project.getFolder(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER_NAME); - - if (!folder.exists()) { - folder.create(true, true, null); - } - } - }; - try { - PlatformUI.getWorkbench().getProgressService().run(false, false, action); - } catch (InvocationTargetException e) { - Activator.getDefault().logError("Error creating TMF project " + project.getName(), e); //$NON-NLS-1$ - } catch (InterruptedException e) { - } - return project; - } - - // ------------------------------------------------------------------------ - // IResourceChangeListener - // ------------------------------------------------------------------------ - - /** - * @since 3.0 - */ - @Override - public void resourceChanged(IResourceChangeEvent event) { - if (event.getType() == IResourceChangeEvent.PRE_DELETE || event.getType() == IResourceChangeEvent.PRE_CLOSE) { - if (event.getResource() instanceof IProject) { - IProject project = (IProject) event.getResource(); - try { - if (project.isAccessible() && project.hasNature(TmfProjectNature.ID)) { - TmfProjectElement tmfProjectElement = registry.get(project); - if (tmfProjectElement == null) { - return; - } - final List traces = tmfProjectElement.getTracesFolder().getTraces(); - if (!traces.isEmpty()) { - // Close editors in UI Thread - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - for (TmfTraceElement traceElement : traces) { - traceElement.closeEditors(); - } - } - }); - } - } - } catch (CoreException e) { - Activator.getDefault().logError("Error handling resource change event for " + project.getName(), e); //$NON-NLS-1$ - } - } - } else if (event.getType() == IResourceChangeEvent.POST_CHANGE) { - for (IResourceDelta delta : event.getDelta().getAffectedChildren()) { - if (delta.getResource() instanceof IProject) { - IProject project = (IProject) delta.getResource(); - try { - if (delta.getKind() == IResourceDelta.CHANGED && - project.isOpen() && project.hasNature(TmfProjectNature.ID)) { - TmfProjectElement projectElement = getProject(project, true); - projectElement.refresh(); - } else if (delta.getKind() == IResourceDelta.REMOVED) { - registry.remove(project); - } - } catch (CoreException e) { - Activator.getDefault().logError("Error handling resource change event for " + project.getName(), e); //$NON-NLS-1$ - } - } - } - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfTraceElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfTraceElement.java deleted file mode 100644 index eaf20d7358..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfTraceElement.java +++ /dev/null @@ -1,700 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Added supplementary files handling - * Geneviève Bastien - Moved supplementary files handling to parent class, - * added code to copy trace - * Patrick Tasse - Close editors to release resources - * Jean-Christian Kouame - added trace properties to be shown into - * the properties view - * Geneviève Bastien - Moved trace type related methods to parent class - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.filesystem.EFS; -import org.eclipse.core.filesystem.IFileInfo; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.URIUtil; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtEvent; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTrace; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTraceDefinition; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlEvent; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTrace; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; -import org.eclipse.linuxtools.tmf.core.synchronization.TimestampTransformFactory; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampFormat; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTraceProperties; -import org.eclipse.linuxtools.tmf.core.trace.TmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ui.editors.TmfEventsEditor; -import org.eclipse.linuxtools.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IActionFilter; -import org.eclipse.ui.views.properties.IPropertyDescriptor; -import org.eclipse.ui.views.properties.IPropertySource2; - -import com.ibm.icu.text.DateFormat; -import com.ibm.icu.text.NumberFormat; - -/** - * Implementation of trace model element representing a trace. It provides - * methods to instantiate ITmfTrace and ITmfEvent as - * well as editor ID from the trace type extension definition. - * - * @version 1.0 - * @author Francois Chouinard - */ -public class TmfTraceElement extends TmfCommonProjectElement implements IActionFilter, IPropertySource2 { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - // Other attributes - /** - * Bundle attribute name - */ - public static final String BUNDLE = "bundle"; //$NON-NLS-1$ - /** - * IsLinked attribute name. - */ - public static final String IS_LINKED = "isLinked"; //$NON-NLS-1$ - - // Property View stuff - private static final String sfResourcePropertiesCategory = Messages.TmfTraceElement_ResourceProperties; - private static final String sfName = Messages.TmfTraceElement_Name; - private static final String sfPath = Messages.TmfTraceElement_Path; - private static final String sfLocation = Messages.TmfTraceElement_Location; - private static final String sfTraceType = Messages.TmfTraceElement_EventType; - private static final String sfIsLinked = Messages.TmfTraceElement_IsLinked; - private static final String sfSourceLocation = Messages.TmfTraceElement_SourceLocation; - private static final String sfTimeOffset = Messages.TmfTraceElement_TimeOffset; - private static final String sfLastModified = Messages.TmfTraceElement_LastModified; - private static final String sfSize = Messages.TmfTraceElement_Size; - private static final String sfTracePropertiesCategory = Messages.TmfTraceElement_TraceProperties; - - private static final ReadOnlyTextPropertyDescriptor sfNameDescriptor = new ReadOnlyTextPropertyDescriptor(sfName, sfName); - private static final ReadOnlyTextPropertyDescriptor sfPathDescriptor = new ReadOnlyTextPropertyDescriptor(sfPath, sfPath); - private static final ReadOnlyTextPropertyDescriptor sfLocationDescriptor = new ReadOnlyTextPropertyDescriptor(sfLocation, sfLocation); - private static final ReadOnlyTextPropertyDescriptor sfTypeDescriptor = new ReadOnlyTextPropertyDescriptor(sfTraceType, sfTraceType); - private static final ReadOnlyTextPropertyDescriptor sfIsLinkedDescriptor = new ReadOnlyTextPropertyDescriptor(sfIsLinked, sfIsLinked); - private static final ReadOnlyTextPropertyDescriptor sfSourceLocationDescriptor = new ReadOnlyTextPropertyDescriptor(sfSourceLocation, sfSourceLocation); - private static final ReadOnlyTextPropertyDescriptor sfTimeOffsetDescriptor = new ReadOnlyTextPropertyDescriptor(sfTimeOffset, sfTimeOffset); - private static final ReadOnlyTextPropertyDescriptor sfLastModifiedDescriptor = new ReadOnlyTextPropertyDescriptor(sfLastModified, sfLastModified); - private static final ReadOnlyTextPropertyDescriptor sfSizeDescriptor = new ReadOnlyTextPropertyDescriptor(sfSize, sfSize); - - private static final IPropertyDescriptor[] sfDescriptors = { sfNameDescriptor, sfPathDescriptor, sfLocationDescriptor, - sfTypeDescriptor, sfIsLinkedDescriptor, sfSourceLocationDescriptor, - sfTimeOffsetDescriptor, sfLastModifiedDescriptor, sfSizeDescriptor }; - - static { - sfNameDescriptor.setCategory(sfResourcePropertiesCategory); - sfPathDescriptor.setCategory(sfResourcePropertiesCategory); - sfLocationDescriptor.setCategory(sfResourcePropertiesCategory); - sfTypeDescriptor.setCategory(sfResourcePropertiesCategory); - sfIsLinkedDescriptor.setCategory(sfResourcePropertiesCategory); - sfSourceLocationDescriptor.setCategory(sfResourcePropertiesCategory); - sfTimeOffsetDescriptor.setCategory(sfResourcePropertiesCategory); - sfLastModifiedDescriptor.setCategory(sfResourcePropertiesCategory); - sfSizeDescriptor.setCategory(sfResourcePropertiesCategory); - } - - private static final TmfTimestampFormat OFFSET_FORMAT = new TmfTimestampFormat("T.SSS SSS SSS s"); //$NON-NLS-1$ - - private static final int FOLDER_MAX_COUNT = 1024; - - // ------------------------------------------------------------------------ - // Static initialization - // ------------------------------------------------------------------------ - - // The mapping of available trace type IDs to their corresponding - // configuration element - private static final Map sfTraceTypeAttributes = new HashMap<>(); - private static final Map sfTraceTypeUIAttributes = new HashMap<>(); - private static final Map sfTraceCategories = new HashMap<>(); - - /** - * Initialize statically at startup by getting extensions from the platform - * extension registry. - */ - public static void init() { - /* Read the tmf.core "tracetype" extension point */ - IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType.TMF_TRACE_TYPE_ID); - for (IConfigurationElement ce : config) { - switch (ce.getName()) { - case TmfTraceType.TYPE_ELEM: - String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR); - sfTraceTypeAttributes.put(traceTypeId, ce); - break; - case TmfTraceType.CATEGORY_ELEM: - String categoryId = ce.getAttribute(TmfTraceType.ID_ATTR); - sfTraceCategories.put(categoryId, ce); - break; - default: - } - } - - /* - * Read the corresponding tmf.ui "tracetypeui" extension point for this - * trace type, if it exists. - */ - config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceTypeUIUtils.TMF_TRACE_TYPE_UI_ID); - for (IConfigurationElement ce : config) { - String elemName = ce.getName(); - if (TmfTraceTypeUIUtils.TYPE_ELEM.equals(elemName)) { - String traceType = ce.getAttribute(TmfTraceTypeUIUtils.TRACETYPE_ATTR); - sfTraceTypeUIAttributes.put(traceType, ce); - } - } - } - - // ------------------------------------------------------------------------ - // Classes - // ------------------------------------------------------------------------ - - private class FileInfo { - long lastModified; - long size; - int count; - } - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private FileInfo fFileInfo; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Constructor. Creates trace model element under the trace folder. - * - * @param name - * The name of trace - * @param trace - * The trace resource. - * @param parent - * The parent element (trace folder) - */ - public TmfTraceElement(String name, IResource trace, TmfTraceFolder parent) { - super(name, trace, parent); - } - - /** - * Constructor. Creates trace model element under the experiment folder. - * - * @param name - * The name of trace - * @param trace - * The trace resource. - * @param parent - * The parent element (experiment folder) - */ - public TmfTraceElement(String name, IResource trace, TmfExperimentElement parent) { - super(name, trace, parent); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Instantiate a ITmfTrace object based on the trace type and - * the corresponding extension. - * - * @return the ITmfTrace or null for an error - */ - @Override - public ITmfTrace instantiateTrace() { - try { - - // make sure that supplementary folder exists - refreshSupplementaryFolder(); - - if (getTraceType() != null) { - if (getTraceType().startsWith(CustomTxtTrace.class.getCanonicalName())) { - for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) { - if (getTraceType().equals(CustomTxtTrace.class.getCanonicalName() + ':' + def.categoryName+ ':' + def.definitionName)) { - return new CustomTxtTrace(def); - } - } - } - if (getTraceType().startsWith(CustomXmlTrace.class.getCanonicalName())) { - for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { - if (getTraceType().equals(CustomXmlTrace.class.getCanonicalName() + ':' + def.categoryName+ ':' + def.definitionName)) { - return new CustomXmlTrace(def); - } - } - } - IConfigurationElement ce = sfTraceTypeAttributes.get(getTraceType()); - if (ce == null) { - return null; - } - ITmfTrace trace = (ITmfTrace) ce.createExecutableExtension(TmfTraceType.TRACE_TYPE_ATTR); - return trace; - } - } catch (CoreException e) { - Activator.getDefault().logError("Error instantiating ITmfTrace object for trace " + getName(), e); //$NON-NLS-1$ - } - return null; - } - - /** - * Instantiate a ITmfEvent object based on the trace type and - * the corresponding extension. - * - * @return the ITmfEvent or null for an error - */ - public ITmfEvent instantiateEvent() { - try { - if (getTraceType() != null) { - if (getTraceType().startsWith(CustomTxtTrace.class.getCanonicalName())) { - for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) { - if (getTraceType().equals(CustomTxtTrace.class.getCanonicalName() + ':' + def.categoryName+ ':' + def.definitionName)) { - return new CustomTxtEvent(def); - } - } - } - if (getTraceType().startsWith(CustomXmlTrace.class.getCanonicalName())) { - for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { - if (getTraceType().equals(CustomXmlTrace.class.getCanonicalName() + ':' + def.categoryName+ ':' + def.definitionName)) { - return new CustomXmlEvent(def); - } - } - } - IConfigurationElement ce = sfTraceTypeAttributes.get(getTraceType()); - if (ce == null) { - return null; - } - ITmfEvent event = (ITmfEvent) ce.createExecutableExtension(TmfTraceType.EVENT_TYPE_ATTR); - return event; - } - } catch (CoreException e) { - Activator.getDefault().logError("Error instantiating ITmfEvent object for trace " + getName(), e); //$NON-NLS-1$ - } - return null; - } - - @Override - public String getEditorId() { - if (getTraceType() != null) { - if (getTraceType().startsWith(CustomTxtTrace.class.getCanonicalName())) { - return TmfEventsEditor.ID; - } - if (getTraceType().startsWith(CustomXmlTrace.class.getCanonicalName())) { - return TmfEventsEditor.ID; - } - IConfigurationElement ce = sfTraceTypeUIAttributes.get(getTraceType()); - if (ce == null) { - /* This trace type does not define UI attributes */ - return null; - } - IConfigurationElement[] defaultEditorCE = ce.getChildren(TmfTraceTypeUIUtils.DEFAULT_EDITOR_ELEM); - if (defaultEditorCE.length == 1) { - return defaultEditorCE[0].getAttribute(TmfTraceType.ID_ATTR); - } - } - return null; - } - - /** - * Returns the file resource used to store bookmarks after creating it if - * necessary. If the trace resource is a file, it is returned directly. If - * the trace resource is a folder, a linked file is returned. The file will - * be created if it does not exist. - * - * @return the bookmarks file - * @throws CoreException - * if the bookmarks file cannot be created - * @since 2.0 - */ - @Override - public IFile createBookmarksFile() throws CoreException { - IFile file = getBookmarksFile(); - if (fResource instanceof IFolder) { - return createBookmarksFile(getProject().getTracesFolder().getResource(), TmfTrace.class.getCanonicalName()); - } - return file; - } - - /** - * Returns the file resource used to store bookmarks. The file may not - * exist. - * - * @return the bookmarks file - * @since 2.0 - */ - @Override - public IFile getBookmarksFile() { - IFile file = null; - if (fResource instanceof IFile) { - file = (IFile) fResource; - } else if (fResource instanceof IFolder) { - final IFolder folder = (IFolder) fResource; - file = folder.getFile(getName() + '_'); - } - return file; - } - - /** - * Returns the TmfTraceElement located under the - * TmfTracesFolder. - * - * @return this if this element is under the - * TmfTracesFolder else the corresponding - * TmfTraceElement if this element is under - * TmfExperimentElement. - */ - public TmfTraceElement getElementUnderTraceFolder() { - - // If trace is under an experiment, return original trace from the - // traces folder - if (getParent() instanceof TmfExperimentElement) { - for (TmfTraceElement aTrace : getProject().getTracesFolder().getTraces()) { - if (aTrace.getElementPath().equals(getElementPath())) { - return aTrace; - } - } - } - return this; - } - - @Override - public String getTypeName() { - return Messages.TmfTraceElement_TypeName; - } - - // ------------------------------------------------------------------------ - // IActionFilter - // ------------------------------------------------------------------------ - - @Override - public boolean testAttribute(Object target, String name, String value) { - if (name.equals(IS_LINKED)) { - boolean isLinked = getResource().isLinked(); - return Boolean.toString(isLinked).equals(value); - } - return false; - } - - // ------------------------------------------------------------------------ - // IPropertySource2 - // ------------------------------------------------------------------------ - - @Override - public Object getEditableValue() { - return null; - } - - /** - * Get the trace properties of this traceElement if the corresponding trace - * is opened in an editor - * - * @return a map with the names and values of the trace properties - * respectively as keys and values - */ - private Map getTraceProperties() { - for (ITmfTrace openedTrace : TmfTraceManager.getInstance().getOpenedTraces()) { - for (ITmfTrace singleTrace : TmfTraceManager.getTraceSet(openedTrace)) { - if (getElementUnderTraceFolder().getResource().equals(singleTrace.getResource())) { - if (singleTrace instanceof ITmfTraceProperties) { - ITmfTraceProperties traceProperties = (ITmfTraceProperties) singleTrace; - return traceProperties.getTraceProperties(); - } - } - } - } - return new HashMap<>(); - } - - @Override - public IPropertyDescriptor[] getPropertyDescriptors() { - Map traceProperties = getTraceProperties(); - if (!traceProperties.isEmpty()) { - IPropertyDescriptor[] propertyDescriptorArray = new IPropertyDescriptor[traceProperties.size() + sfDescriptors.length]; - int index = 0; - for (Map.Entry varName : traceProperties.entrySet()) { - ReadOnlyTextPropertyDescriptor descriptor = new ReadOnlyTextPropertyDescriptor(this.getName() + "_" + varName.getKey(), varName.getKey()); //$NON-NLS-1$ - descriptor.setCategory(sfTracePropertiesCategory); - propertyDescriptorArray[index] = descriptor; - index++; - } - for (int i = 0; i < sfDescriptors.length; i++) { - propertyDescriptorArray[index] = sfDescriptors[i]; - index++; - } - return propertyDescriptorArray; - } - return Arrays.copyOf(sfDescriptors, sfDescriptors.length); - } - - @Override - public Object getPropertyValue(Object id) { - - if (sfName.equals(id)) { - return getName(); - } - - if (sfPath.equals(id)) { - return getPath().toString(); - } - - if (sfLocation.equals(id)) { - return URIUtil.toUnencodedString(getLocation()); - } - - if (sfIsLinked.equals(id)) { - return Boolean.valueOf(getResource().isLinked()).toString(); - } - - if (sfSourceLocation.equals(id)) { - try { - String sourceLocation = getElementUnderTraceFolder().getResource().getPersistentProperty(TmfCommonConstants.SOURCE_LOCATION); - if (sourceLocation != null) { - return sourceLocation; - } - } catch (CoreException e) { - } - return ""; //$NON-NLS-1$ - } - - if (sfLastModified.equals(id)) { - FileInfo fileInfo = getFileInfo(); - if (fileInfo == null) { - return ""; //$NON-NLS-1$ - } - long date = fileInfo.lastModified; - DateFormat format = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.MEDIUM); - return format.format(new Date(date)); - } - - if (sfSize.equals(id)) { - FileInfo fileInfo = getFileInfo(); - if (fileInfo == null) { - return ""; //$NON-NLS-1$ - } - if (getResource() instanceof IFolder) { - if (fileInfo.count <= FOLDER_MAX_COUNT) { - return NLS.bind(Messages.TmfTraceElement_FolderSizeString, - NumberFormat.getInstance().format(fileInfo.size), fileInfo.count); - } - return NLS.bind(Messages.TmfTraceElement_FolderSizeOverflowString, - NumberFormat.getInstance().format(fileInfo.size), FOLDER_MAX_COUNT); - } - return NLS.bind(Messages.TmfTraceElement_FileSizeString, NumberFormat.getInstance().format(fileInfo.size)); - } - - if (sfTraceType.equals(id)) { - if (getTraceType() != null) { - TraceTypeHelper helper = TmfTraceType.getTraceType(getTraceType()); - if (helper != null) { - return helper.getCategoryName() + " : " + helper.getName(); //$NON-NLS-1$ - } - } - return ""; //$NON-NLS-1$ - } - - if (sfTimeOffset.equals(id)) { - long offset = TimestampTransformFactory.getTimestampTransform(getElementUnderTraceFolder().getResource()).transform(0); - if (offset != 0) { - return OFFSET_FORMAT.format(offset); - } - return ""; //$NON-NLS-1$ - } - - Map traceProperties = getTraceProperties(); - if (id != null && !traceProperties.isEmpty()) { - String key = (String) id; - key = key.substring(this.getName().length() + 1); // remove name_ - String value = traceProperties.get(key); - return value; - } - - return null; - } - - private FileInfo getFileInfo() { - /* FileInfo is needed for both 'last modified' and 'size' properties. - * It is freshly computed for one, and reused for the other, then - * cleared so that the information can be refreshed the next time. - */ - FileInfo fileInfo; - if (fFileInfo == null) { - try { - fileInfo = computeFileInfo(new FileInfo(), getResource()); - } catch (CoreException e) { - return null; - } - fFileInfo = fileInfo; - } else { - fileInfo = fFileInfo; - fFileInfo = null; - } - return fileInfo; - } - - private FileInfo computeFileInfo(FileInfo fileInfo, IResource resource) throws CoreException { - if (fileInfo == null || fileInfo.count > FOLDER_MAX_COUNT) { - return fileInfo; - } - if (resource instanceof IFolder) { - IFolder folder = (IFolder) resource; - for (IResource member : folder.members()) { - computeFileInfo(fileInfo, member); - } - return fileInfo; - } - IFileInfo info = EFS.getStore(resource.getLocationURI()).fetchInfo(); - fileInfo.lastModified = Math.max(fileInfo.lastModified, info.getLastModified()); - fileInfo.size += info.getLength(); - fileInfo.count++; - return fileInfo; - } - - @Override - public void resetPropertyValue(Object id) { - } - - @Override - public void setPropertyValue(Object id, Object value) { - } - - @Override - public boolean isPropertyResettable(Object id) { - return false; - } - - @Override - public boolean isPropertySet(Object id) { - return false; - } - - /** - * Copy this trace in the trace folder. No other parameters are mentioned so - * the trace is copied in this element's project trace folder - * - * @param newName - * The new trace name - * @return the new Resource object - * @since 2.0 - */ - public TmfTraceElement copy(String newName) { - TmfTraceFolder folder = (TmfTraceFolder) getParent(); - IResource res = super.copy(newName, false); - for (TmfTraceElement trace : folder.getTraces()) { - if (trace.getResource().equals(res)) { - return trace; - } - } - return null; - } - - /** - * Close opened editors associated with this trace. - * - * @since 2.0 - */ - @Override - public void closeEditors() { - super.closeEditors(); - - // Close experiments that contain the trace if open - if (getParent() instanceof TmfTraceFolder) { - TmfExperimentFolder experimentsFolder = getProject().getExperimentsFolder(); - for (TmfExperimentElement experiment : experimentsFolder.getExperiments()) { - for (TmfTraceElement trace : experiment.getTraces()) { - if (trace.getElementPath().equals(getElementPath())) { - experiment.closeEditors(); - break; - } - } - } - } else if (getParent() instanceof TmfExperimentElement) { - TmfExperimentElement experiment = (TmfExperimentElement) getParent(); - experiment.closeEditors(); - } - } - - /** - * Delete the trace resource, remove it from experiments and delete its - * supplementary files - * - * @param progressMonitor - * a progress monitor, or null if progress reporting is not - * desired - * - * @throws CoreException - * thrown when IResource.delete fails - * @since 2.2 - */ - public void delete(IProgressMonitor progressMonitor) throws CoreException { - // Close editors in UI Thread - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - closeEditors(); - } - }); - - IPath path = fResource.getLocation(); - if (path != null) { - if (getParent() instanceof TmfTraceFolder) { - TmfExperimentFolder experimentFolder = getProject().getExperimentsFolder(); - - // Propagate the removal to traces - for (TmfExperimentElement experiment : experimentFolder.getExperiments()) { - List toRemove = new LinkedList<>(); - for (TmfTraceElement trace : experiment.getTraces()) { - if (trace.getElementPath().equals(getElementPath())) { - toRemove.add(trace); - } - } - for (TmfTraceElement child : toRemove) { - experiment.removeTrace(child); - } - } - - // Delete supplementary files - deleteSupplementaryFolder(); - - } else if (getParent() instanceof TmfExperimentElement) { - TmfExperimentElement experimentElement = (TmfExperimentElement) getParent(); - experimentElement.removeTrace(this); - } - } - - // Finally, delete the trace - fResource.delete(true, progressMonitor); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfTraceFolder.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfTraceFolder.java deleted file mode 100644 index d7f9dfd9e1..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfTraceFolder.java +++ /dev/null @@ -1,209 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Add support for folder elements - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; -import org.eclipse.ui.views.properties.IPropertyDescriptor; -import org.eclipse.ui.views.properties.IPropertySource2; - -/** - * Implementation of trace folder model element representing a trace folder in - * the project. - *

- * @version 1.0 - * @author Francois Chouinard - */ -public class TmfTraceFolder extends TmfProjectModelElement implements IPropertySource2 { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - private static final String sfInfoCategory = "Info"; //$NON-NLS-1$ - private static final String sfName = "name"; //$NON-NLS-1$ - private static final String sfPath = "path"; //$NON-NLS-1$ - private static final String sfLocation = "location"; //$NON-NLS-1$ - - private static final ReadOnlyTextPropertyDescriptor sfNameDescriptor = new ReadOnlyTextPropertyDescriptor(sfName, sfName); - private static final ReadOnlyTextPropertyDescriptor sfPathDescriptor = new ReadOnlyTextPropertyDescriptor(sfPath, sfPath); - private static final ReadOnlyTextPropertyDescriptor sfLocationDescriptor = new ReadOnlyTextPropertyDescriptor(sfLocation, sfLocation); - - private static final IPropertyDescriptor[] sfDescriptors = { sfNameDescriptor, sfPathDescriptor, - sfLocationDescriptor }; - - static { - sfNameDescriptor.setCategory(sfInfoCategory); - sfPathDescriptor.setCategory(sfInfoCategory); - sfLocationDescriptor.setCategory(sfInfoCategory); - } - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructor. - * Creates folder model element under the project. - * @param name The name of trace folder. - * @param resource The folder resource. - * @param parent The parent element (project). - */ - public TmfTraceFolder(String name, IFolder resource, TmfProjectElement parent) { - super(name, resource, parent); - parent.addChild(this); - } - - /** - * Constructor. - * Creates folder model element under another folder. - * @param name The name of trace folder. - * @param resource The folder resource. - * @param parent The parent element (folder). - * @since 3.0 - */ - public TmfTraceFolder(String name, IFolder resource, TmfTraceFolder parent) { - super(name, resource, parent); - parent.addChild(this); - } - - // ------------------------------------------------------------------------ - // TmfProjectModelElement - // ------------------------------------------------------------------------ - - @Override - public IFolder getResource() { - return (IFolder) fResource; - } - - @Override - void refreshChildren() { - IFolder folder = getResource(); - - // Get the children from the model - Map childrenMap = new HashMap<>(); - for (ITmfProjectModelElement element : getChildren()) { - childrenMap.put(element.getResource().getName(), element); - } - - try { - IResource[] members = folder.members(); - for (IResource resource : members) { - String name = resource.getName(); - boolean isFolder = resource instanceof IFolder && - (TmfTraceType.getTraceTypeId(resource) == null); - ITmfProjectModelElement element = childrenMap.get(name); - if (isFolder && !(element instanceof TmfTraceFolder) && !(element instanceof TmfTraceElement)) { - if (TmfTraceType.isDirectoryTrace(resource.getLocationURI().getPath())) { - element = new TmfTraceElement(name, resource, this); - } else { - element = new TmfTraceFolder(name, (IFolder) resource, this); - } - } else if (!isFolder && !(element instanceof TmfTraceElement)) { - element = new TmfTraceElement(name, resource, this); - } else { - childrenMap.remove(name); - } - ((TmfProjectModelElement) element).refreshChildren(); - } - } catch (CoreException e) { - } - - // Cleanup dangling children from the model - for (ITmfProjectModelElement danglingChild : childrenMap.values()) { - removeChild(danglingChild); - } - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Returns a list of trace elements under the folder element, recursively. - * @return list of trace model elements - */ - public List getTraces() { - List children = getChildren(); - List traces = new ArrayList<>(); - for (ITmfProjectModelElement child : children) { - if (child instanceof TmfTraceElement) { - traces.add((TmfTraceElement) child); - } else if (child instanceof TmfTraceFolder) { - traces.addAll(((TmfTraceFolder) child).getTraces()); - } - } - return traces; - } - - // ------------------------------------------------------------------------ - // IPropertySource2 - // ------------------------------------------------------------------------ - - @Override - public Object getEditableValue() { - return null; - } - - @Override - public IPropertyDescriptor[] getPropertyDescriptors() { - return Arrays.copyOf(sfDescriptors, sfDescriptors.length); - } - - @Override - public Object getPropertyValue(Object id) { - - if (sfName.equals(id)) { - return getName(); - } - - if (sfPath.equals(id)) { - return getPath().toString(); - } - - if (sfLocation.equals(id)) { - return getLocation().toString(); - } - - return null; - } - - @Override - public void resetPropertyValue(Object id) { - } - - @Override - public void setPropertyValue(Object id, Object value) { - } - - @Override - public boolean isPropertyResettable(Object id) { - return false; - } - - @Override - public boolean isPropertySet(Object id) { - return false; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfTraceTypeUIUtils.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfTraceTypeUIUtils.java deleted file mode 100644 index c981e2f239..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfTraceTypeUIUtils.java +++ /dev/null @@ -1,494 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - * Patrick Tasse - Add support for folder elements - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.TreeSet; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomEventTableColumns; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTrace; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTrace; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceImportException; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType.TraceElementType; -import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.util.Pair; -import org.eclipse.linuxtools.tmf.ui.viewers.events.TmfEventsTable; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.ITmfEventTableColumns; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.osgi.framework.Bundle; - -/** - * Utils class for the UI-specific parts of @link {@link TmfTraceType}. - * - * @author Alexandre Montplaisir - * @since 3.0 - */ -public final class TmfTraceTypeUIUtils { - - /** Extension point ID */ - public static final String TMF_TRACE_TYPE_UI_ID = "org.eclipse.linuxtools.tmf.ui.tracetypeui"; //$NON-NLS-1$ - - /** Extension point element 'type' (should match the type in TmfTraceType) */ - public static final String TYPE_ELEM = "type"; //$NON-NLS-1$ - - /** - * Extension point element 'experiment' (should match the type in - * TmfTraceType) - */ - public static final String EXPERIMENT_ELEM = "experiment"; //$NON-NLS-1$ - - /** Extension point element 'Default editor' */ - public static final String DEFAULT_EDITOR_ELEM = "defaultEditor"; //$NON-NLS-1$ - - /** Extension point element 'Events table type' */ - public static final String EVENTS_TABLE_TYPE_ELEM = "eventsTableType"; //$NON-NLS-1$ - - /** Extension point element 'Event Table Columns' - * @since 3.2*/ - public static final String EVENT_TABLE_COLUMNS = "eventTableColumns"; //$NON-NLS-1$ - - /** Extension point attribute 'tracetype' */ - public static final String TRACETYPE_ATTR = "tracetype"; //$NON-NLS-1$ - - /** Extension point attribute 'icon' */ - public static final String ICON_ATTR = "icon"; //$NON-NLS-1$ - - /** Extension point attribute 'class' (attribute of other elements) */ - public static final String CLASS_ATTR = "class"; //$NON-NLS-1$ - - private TmfTraceTypeUIUtils() { - } - - private static List> reduce(List> candidates) { - List> retVal = new ArrayList<>(); - - // get all the tracetypes that are unique in that stage - for (Pair candidatePair : candidates) { - TraceTypeHelper candidate = candidatePair.getSecond(); - if (isUnique(candidate, candidates)) { - retVal.add(candidatePair); - } - } - return retVal; - } - - /* - * Only return the leaves of the trace types. Ignore custom trace types. - */ - private static boolean isUnique(TraceTypeHelper trace, List> set) { - if (trace.getTraceClass().equals(CustomTxtTrace.class) || - trace.getTraceClass().equals(CustomXmlTrace.class)) { - return true; - } - // check if the trace type is the leaf. we make an instance of the trace - // type and if it is only an instance of itself, it is a leaf - final ITmfTrace tmfTrace = trace.getTrace(); - int count = -1; - for (Pair child : set) { - final ITmfTrace traceCandidate = child.getSecond().getTrace(); - if (tmfTrace.getClass().isInstance(traceCandidate)) { - count++; - } - } - return count == 0; - } - - private static TraceTypeHelper getTraceTypeToSet(List> candidates, Shell shell) { - final Map names = new HashMap<>(); - Shell shellToShow = new Shell(shell); - shellToShow.setText(Messages.TmfTraceType_SelectTraceType); - final String candidatesToSet[] = new String[1]; - for (Pair candidatePair : candidates) { - TraceTypeHelper candidate = candidatePair.getSecond(); - Button b = new Button(shellToShow, SWT.RADIO); - final String displayName = candidate.getCategoryName() + ':' + candidate.getName(); - b.setText(displayName); - names.put(displayName, candidate.getCanonicalName()); - - b.addSelectionListener(new SelectionListener() { - - @Override - public void widgetSelected(SelectionEvent e) { - final Button source = (Button) e.getSource(); - candidatesToSet[0] = (names.get(source.getText())); - source.getParent().dispose(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - - } - }); - } - shellToShow.setLayout(new RowLayout(SWT.VERTICAL)); - shellToShow.pack(); - shellToShow.open(); - - Display display = shellToShow.getDisplay(); - while (!shellToShow.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - return TmfTraceType.getTraceType(candidatesToSet[0]); - } - - /** - * This member figures out the trace type of a given file. It will prompt - * the user if it needs more information to properly pick the trace type. - * - * @param path - * The path of file to import - * @param shell - * a shell to display the message to. If it is null, it is - * assumed to be cancelled. - * @param traceTypeHint - * the ID of a trace (like "o.e.l.specifictrace" ) - * @return null if the request is cancelled or a TraceTypeHelper if it - * passes. - * @throws TmfTraceImportException - * if the traces don't match or there are errors in the trace - * file - */ - public static TraceTypeHelper selectTraceType(String path, Shell shell, String traceTypeHint) throws TmfTraceImportException { - - Comparator> comparator = new Comparator>() { - @Override - public int compare(Pair o1, Pair o2) { - int res = -o1.getFirst().compareTo(o2.getFirst()); // invert so that highest confidence is first - if (res == 0) { - res = o1.getSecond().getName().compareTo(o2.getSecond().getName()); - } - return res; - } - }; - TreeSet> validCandidates = new TreeSet<>(comparator); - final Iterable traceTypeHelpers = TmfTraceType.getTraceTypeHelpers(); - for (TraceTypeHelper traceTypeHelper : traceTypeHelpers) { - if (traceTypeHelper.isExperimentType()) { - continue; - } - int confidence = traceTypeHelper.validateWithConfidence(path); - if (confidence >= 0) { - // insert in the tree map, ordered by confidence (highest confidence first) then name - Pair element = new Pair<>(confidence, traceTypeHelper); - validCandidates.add(element); - } - } - - TraceTypeHelper traceTypeToSet = null; - if (validCandidates.isEmpty()) { - final String errorMsg = NLS.bind(Messages.TmfOpenTraceHelper_NoTraceTypeMatch, path); - throw new TmfTraceImportException(errorMsg); - } else if (validCandidates.size() != 1) { - List> candidates = new ArrayList<>(validCandidates); - List> reducedCandidates = reduce(candidates); - for (Pair candidatePair : reducedCandidates) { - TraceTypeHelper candidate = candidatePair.getSecond(); - if (candidate.getCanonicalName().equals(traceTypeHint)) { - traceTypeToSet = candidate; - break; - } - } - if (traceTypeToSet == null) { - if (reducedCandidates.size() == 0) { - throw new TmfTraceImportException(Messages.TmfOpenTraceHelper_ReduceError); - } else if (reducedCandidates.size() == 1) { - traceTypeToSet = reducedCandidates.get(0).getSecond(); - } else if (shell == null) { - Pair candidate = reducedCandidates.get(0); - // if the best match has lowest confidence, don't select it - if (candidate.getFirst() > 0) { - traceTypeToSet = candidate.getSecond(); - } - } else { - traceTypeToSet = getTraceTypeToSet(reducedCandidates, shell); - } - } - } else { - traceTypeToSet = validCandidates.first().getSecond(); - } - return traceTypeToSet; - } - - /** - * Set the trace type of a {@link TraceTypeHelper}. Should only be - * used internally by this project. - * - * @param resource - * the resource to set - * @param traceType - * the {@link TraceTypeHelper} to set the trace type to. - * @return Status.OK_Status if successful, error is otherwise. - * @throws CoreException - * An exception caused by accessing eclipse project items. - */ - public static IStatus setTraceType(IResource resource, TraceTypeHelper traceType) throws CoreException { - return setTraceType(resource, traceType, true); - } - /** - * Set the trace type of a {@link TraceTypeHelper}. Should only be - * used internally by this project. - * - * @param resource - * the resource to set - * @param traceType - * the {@link TraceTypeHelper} to set the trace type to. - * @param refresh - * Flag for refreshing the project - * @return Status.OK_Status if successful, error is otherwise. - * @throws CoreException - * An exception caused by accessing eclipse project items. - * @since 3.1 - */ - public static IStatus setTraceType(IResource resource, TraceTypeHelper traceType, boolean refresh) throws CoreException { - String traceTypeId = traceType.getCanonicalName(); - - resource.setPersistentProperty(TmfCommonConstants.TRACETYPE, traceTypeId); - - TmfProjectElement tmfProject = TmfProjectRegistry.getProject(resource.getProject(), true); - if (tmfProject.getTracesFolder().getPath().isPrefixOf(resource.getFullPath())) { - String elementPath = resource.getFullPath().makeRelativeTo(tmfProject.getTracesFolder().getPath()).toString(); - refreshTraceElement(tmfProject.getTracesFolder().getTraces(), elementPath); - } else if (resource.getParent().equals(tmfProject.getExperimentsFolder().getResource())) { - /* The trace type to set is for an experiment */ - for (TmfExperimentElement experimentElement : tmfProject.getExperimentsFolder().getExperiments()) { - if (resource.equals(experimentElement.getResource())) { - experimentElement.refreshTraceType(); - break; - } - } - } else { - for (TmfExperimentElement experimentElement : tmfProject.getExperimentsFolder().getExperiments()) { - if (experimentElement.getPath().isPrefixOf(resource.getFullPath())) { - String elementPath = resource.getFullPath().makeRelativeTo(experimentElement.getPath()).toString(); - refreshTraceElement(experimentElement.getTraces(), elementPath); - break; - } - } - } - if (refresh) { - tmfProject.refresh(); - } - return Status.OK_STATUS; - } - - private static void refreshTraceElement(List traceElements, String elementPath) { - for (TmfTraceElement traceElement : traceElements) { - if (traceElement.getElementPath().equals(elementPath)) { - traceElement.refreshTraceType(); - break; - } - } - } - - /** - * Retrieves all configuration elements from the platform extension registry - * for the trace type UI extension. - * - * @param elType - * The type of trace type requested, either TRACE or EXPERIMENT - * @return An array of trace type configuration elements - */ - public static IConfigurationElement[] getTypeUIElements(TraceElementType elType) { - String elementName = TYPE_ELEM; - if (elType == TraceElementType.EXPERIMENT) { - elementName = EXPERIMENT_ELEM; - } - IConfigurationElement[] elements = - Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_TRACE_TYPE_UI_ID); - List typeElements = new LinkedList<>(); - for (IConfigurationElement element : elements) { - if (element.getName().equals(elementName)) { - typeElements.add(element); - } - } - return typeElements.toArray(new IConfigurationElement[typeElements.size()]); - } - - /** - * Get the UI elements for the given trace type - * - * @param traceType - * The tracetype ID - * @param elType - * The type of trace type requested, either TRACE or EXPERIMENT - * @return The top-level configuration element (access its children with - * .getChildren()). Or null if there is no such element. - */ - @Nullable - public static IConfigurationElement getTraceUIAttributes(String traceType, TraceElementType elType) { - IConfigurationElement[] elements = getTypeUIElements(elType); - for (IConfigurationElement ce : elements) { - if (traceType.equals(ce.getAttribute(TRACETYPE_ATTR))) { - return ce; - } - } - return null; - } - - /** - * Get the Event Table type specified by the trace type's extension point, - * if there is one. - * - * @param trace - * The trace for which we want the events table. - * @param parent - * The parent composite that the event table will have - * @param cacheSize - * The cache size to use with this event table. Should be defined - * by the trace type. - * @return The corresponding Event Table, or 'null' if this trace type did - * not specify any. - * @since 3.2 - */ - public static @Nullable TmfEventsTable getEventTable(ITmfTrace trace, Composite parent, int cacheSize) { - final String traceType = getTraceType(trace); - if (traceType == null) { - return null; - } - - for (final IConfigurationElement ce : TmfTraceTypeUIUtils.getTypeUIElements(TraceElementType.TRACE)) { - if (ce.getAttribute(TmfTraceTypeUIUtils.TRACETYPE_ATTR).equals(traceType)) { - final IConfigurationElement[] eventsTableTypeCE = ce.getChildren(TmfTraceTypeUIUtils.EVENTS_TABLE_TYPE_ELEM); - - if (eventsTableTypeCE.length != 1) { - break; - } - final String eventsTableType = eventsTableTypeCE[0].getAttribute(TmfTraceTypeUIUtils.CLASS_ATTR); - if (eventsTableType.isEmpty()) { - break; - } - try { - final Bundle bundle = Platform.getBundle(ce.getContributor().getName()); - final Class c = bundle.loadClass(eventsTableType); - final Class[] constructorArgs = new Class[] { Composite.class, int.class }; - final Constructor constructor = c.getConstructor(constructorArgs); - final Object[] args = new Object[] { parent, cacheSize }; - return (TmfEventsTable) constructor.newInstance(args); - - } catch (NoSuchMethodException | ClassNotFoundException | InstantiationException | - IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - return null; - } - } - } - return null; - } - - /** - * Get the Event Table columns specified by the trace type's extension - * point, if there are any. - * - * @param trace - * The trace for which we want the columns. - * @return The corresponding event table columns, or 'null' if this trace - * type did not specify any. - * @since 3.2 - */ - public static @Nullable Collection getEventTableColumns(ITmfTrace trace) { - final String traceType = getTraceType(trace); - if (traceType == null) { - return null; - } - - /* - * Custom traces are a special case : the columns are defined by the - * trace definition. - */ - if (traceType.startsWith(CustomTxtTrace.class.getCanonicalName())) { - return CustomEventTableColumns.generateColumns(((CustomTxtTrace) trace).getDefinition()); - } - if (traceType.startsWith(CustomXmlTrace.class.getCanonicalName())) { - return CustomEventTableColumns.generateColumns(((CustomXmlTrace) trace).getDefinition()); - } - - /* For all other trace types, we will go look into the extension point */ - for (final IConfigurationElement ce : TmfTraceTypeUIUtils.getTypeUIElements(TraceElementType.TRACE)) { - if (ce.getAttribute(TmfTraceTypeUIUtils.TRACETYPE_ATTR).equals(traceType)) { - final IConfigurationElement[] eventTableColumnsCE = ce.getChildren(TmfTraceTypeUIUtils.EVENT_TABLE_COLUMNS); - - if (eventTableColumnsCE.length != 1) { - break; - } - final String eventTableColumnsClass = eventTableColumnsCE[0].getAttribute(TmfTraceTypeUIUtils.CLASS_ATTR); - if ((eventTableColumnsClass == null) || (eventTableColumnsClass.isEmpty())) { - break; - } - try { - final Bundle bundle = Platform.getBundle(ce.getContributor().getName()); - final Class c = bundle.loadClass(eventTableColumnsClass); - final Constructor ctor = c.getConstructor(); - ITmfEventTableColumns cols = (ITmfEventTableColumns) ctor.newInstance(); - return cols.getEventTableColumns(); - - } catch (NoSuchMethodException | ClassNotFoundException | InstantiationException | - IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - return null; - } - } - } - return null; - } - - /** - * Get the trace type (as a String) for the given trace - * - * @param trace - * The trace object - * @return The String representing the trace type, or 'null' if this trace - * does not advertise it. - */ - private static @Nullable String getTraceType(ITmfTrace trace) { - IResource res = trace.getResource(); - if (res == null) { - return null; - } - try { - String traceType = res.getPersistentProperty(TmfCommonConstants.TRACETYPE); - /* May be null here too */ - return traceType; - - } catch (CoreException e) { - return null; - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfTracesFolder.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfTracesFolder.java deleted file mode 100644 index bfe8b9d789..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfTracesFolder.java +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import org.eclipse.core.resources.IFolder; - -/** - * Implementation of model element representing the unique "Traces" folder in - * the project. - * - * @since 3.0 - */ -public class TmfTracesFolder extends TmfTraceFolder { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The name of the traces folder - */ - public static final String TRACES_FOLDER_NAME = "Traces"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructor. - * Creates folder model element under the project. - * @param name The name of trace folder. - * @param resource The folder resource. - * @param parent The parent element (project). - */ - public TmfTracesFolder(String name, IFolder resource, TmfProjectElement parent) { - super(name, resource, parent); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfViewerSorter.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfViewerSorter.java deleted file mode 100644 index 63eac152f1..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfViewerSorter.java +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import org.eclipse.jface.viewers.ViewerSorter; - -/** - * Viewer sorter for TMF project model elements - * - * @since 3.0 - */ -public class TmfViewerSorter extends ViewerSorter { - - @Override - public int category(Object element) { - if (element instanceof TmfExperimentFolder) { - return 0; - } - if (element instanceof TmfTraceFolder) { - return 0; - } - if (element instanceof TmfExperimentElement) { - return 1; - } - if (element instanceof TmfTraceElement) { - return 1; - } - return 2; - } - - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TraceFolderContentProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TraceFolderContentProvider.java deleted file mode 100644 index 627f9cbe11..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TraceFolderContentProvider.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Add support for folder elements - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.Viewer; - -/** - * Content provider implementation for trace folders for tree viewers that display - * the content of a trace folder. - *

- * - * @version 1.0 - * @author Francois Chouinard - */ -public class TraceFolderContentProvider implements IStructuredContentProvider { - - @Override - public Object[] getElements(Object inputElement) { - if (inputElement instanceof TmfTraceFolder) { - TmfTraceFolder folder = (TmfTraceFolder) inputElement; - List elements = new ArrayList<>(); - for (TmfTraceElement trace : folder.getTraces()) { - if (trace.getTraceType() != null) { - elements.add(trace); - } - } - return elements.toArray(); - } - return null; - } - - @Override - public void dispose() { - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TraceFolderLabelProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TraceFolderLabelProvider.java deleted file mode 100644 index 9cfe0f41dd..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TraceFolderLabelProvider.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Add support for folder elements - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import org.eclipse.jface.viewers.LabelProvider; - -/** - * Label provider implementation for trace folders for viewers that display - * the content of a trace folder. - *

- * - * @version 1.0 - * @author Francois Chouinard - */ -public class TraceFolderLabelProvider extends LabelProvider { - - @Override - public String getText(Object element) { - if (element instanceof TmfTraceElement) { - TmfTraceElement entry = (TmfTraceElement) element; - return entry.getElementPath(); - } - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TraceUtils.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TraceUtils.java deleted file mode 100644 index bf0b03b39a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TraceUtils.java +++ /dev/null @@ -1,99 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal and others - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - * Marc-Andre Laperle - Add method to get opened tmf projects - * Patrick Tasse - Add support for folder elements - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.model; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.TmfProjectNature; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.MessageBox; -import org.eclipse.ui.PlatformUI; - -/** - * Utility class for common tmf.ui functionalities - * - * @since 2.1 - */ -public class TraceUtils { - - /** - * Displays an error message in a box - * - * @param boxTitle - * The message box title - * @param errorMsg - * The error message to display - */ - public static void displayErrorMsg(final String boxTitle, final String errorMsg) { - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - final MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()); - mb.setText(boxTitle); - mb.setMessage(errorMsg); - mb.open(); - } - }); - } - - /** - * Get the opened (accessible) projects with Tmf nature - * - * @return the Tmf projects - * @since 2.2 - */ - public static List getOpenedTmfProjects() { - IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); - List tmfProjects = new ArrayList<>(); - for (IProject project : projects) { - try { - if (project.isAccessible() && project.getNature(TmfProjectNature.ID) != null) { - tmfProjects.add(project); - } - } catch (CoreException e) { - Activator.getDefault().logError("Error getting opened tmf projects", e); //$NON-NLS-1$ - } - } - return tmfProjects; - } - - /** - * Create a folder, ensuring all parent folders are also created. - * - * @param folder - * the folder to create - * @param monitor - * the progress monitor - * @throws CoreException - * if the folder cannot be created - * @since 3.0 - */ - public static void createFolder(IFolder folder, IProgressMonitor monitor) throws CoreException { - if (!folder.exists()) { - if (folder.getParent() instanceof IFolder) { - createFolder((IFolder) folder.getParent(), monitor); - } - folder.create(true, true, monitor); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/messages.properties deleted file mode 100644 index f931a19a6f..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/messages.properties +++ /dev/null @@ -1,49 +0,0 @@ -############################################################################### -# Copyright (c) 2013, 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### - -# Environment properties dialog - -TmfAnalysisElement_InstantiateAnalysis=Instantiate analysis -TmfAnalysisViewOutput_ViewUnavailable=\ (view unavailable) -TmfAnalysisViewOutput_Title=Open analysis output -TmfCommonProjectElement_ErrorClosingEditor=Error closing editor for {0} -TmfCommonProjectElement_ErrorRefreshingProperty=Error refreshing trace type persistent property for trace {0} -TmfExperimentElement_ErrorInstantiatingTrace=Error instantiating ITmfTrace object for trace {0} -TmfExperimentElement_TypeName=Experiment -TmfTraceElement_ResourceProperties = Resource properties -TmfTraceElement_TraceProperties = Trace properties -TmfTraceElement_Name = name -TmfTraceElement_Path = path -TmfTraceElement_Location = location -TmfTraceElement_EventType = type -TmfTraceElement_IsLinked = linked -TmfTraceElement_SourceLocation = source location -TmfTraceElement_TimeOffset = time offset -TmfTraceElement_LastModified = last modified -TmfTraceElement_Size = size -TmfTraceElement_FileSizeString={0} bytes -TmfTraceElement_FolderSizeString={0} bytes in {1} files -TmfTraceElement_FolderSizeOverflowString=At least {0} bytes in more than {1} files -TmfTraceElement_TypeName=Trace -TmfTraceType_SelectTraceType=Select Trace Type - -# Open trace error messages -TmfOpenTraceHelper_ErrorOpeningElement=Error opening {0} -TmfOpenTraceHelper_LinkFailed=Link creation failed -TmfOpenTraceHelper_NoTraceTypeMatch=No trace types found to match location {0} -TmfOpenTraceHelper_OpenElement=Open {0} -TmfOpenTraceHelper_ReduceError=Something went wrong -TmfOpenTraceHelper_NoTraceType = No trace type associated to that trace\nPlease select a valid type -TmfOpenTraceHelper_NoTraceOrExperimentType=No experiment type associated to that {0}\nPlease select a valid type -TmfOpenTraceHelper_ErrorElement=Error opening {0}. -TmfOpenTraceHelper_InitError = Error initializing trace. -TmfOpenTraceHelper_TraceNotFound = Trace {0} not found. diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/CopyExperimentDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/CopyExperimentDialog.java deleted file mode 100644 index d908756b9f..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/CopyExperimentDialog.java +++ /dev/null @@ -1,226 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Copied and adapted from NewFolderDialog - * Geneviève Bastien - Moved the actual copy code to model element's class - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.wizards; - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentFolder; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.actions.WorkspaceModifyOperation; -import org.eclipse.ui.dialogs.SelectionStatusDialog; - -/** - * Implementation of the copy experiement dialog box. - *

- * - * @version 1.0 - * @author Francois Chouinard - */ -public class CopyExperimentDialog extends SelectionStatusDialog { - - // ------------------------------------------------------------------------ - // Members - // ------------------------------------------------------------------------ - - private final TmfExperimentElement fExperiment; - private Text fNewExperimentName; - private IFolder fExperimentFolder; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructor - * - * @param shell - * The parent shell - * @param experiment - * The TMF experiment model element - */ - public CopyExperimentDialog(Shell shell, TmfExperimentElement experiment) { - super(shell); - fExperiment = experiment; - TmfExperimentFolder folder = (TmfExperimentFolder) experiment.getParent(); - fExperimentFolder = folder.getResource(); - setTitle(Messages.CopyExperimentDialog_DialogTitle); - setStatusLineAboveButtons(true); - } - - // ------------------------------------------------------------------------ - // Dialog - // ------------------------------------------------------------------------ - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - composite.setLayout(new GridLayout()); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - - createNewExperimentNameGroup(composite); - return composite; - } - - private void createNewExperimentNameGroup(Composite parent) { - Font font = parent.getFont(); - Composite folderGroup = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.numColumns = 2; - folderGroup.setLayout(layout); - folderGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - // Old experiment name label - Label oldExperimentLabel = new Label(folderGroup, SWT.NONE); - oldExperimentLabel.setFont(font); - oldExperimentLabel.setText(Messages.CopyExperimentDialog_ExperimentName); - - // Old experiment name field - Text oldExperimentName = new Text(folderGroup, SWT.BORDER); - GridData data = new GridData(GridData.FILL_HORIZONTAL); - data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; - oldExperimentName.setLayoutData(data); - oldExperimentName.setFont(font); - oldExperimentName.setText(fExperiment.getName()); - oldExperimentName.setEnabled(false); - - // New experiment name label - Label newExperimentLabel = new Label(folderGroup, SWT.NONE); - newExperimentLabel.setFont(font); - newExperimentLabel.setText(Messages.CopyExperimentDialog_ExperimentNewName); - - // New experiment name entry field - fNewExperimentName = new Text(folderGroup, SWT.BORDER); - data = new GridData(GridData.FILL_HORIZONTAL); - data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; - fNewExperimentName.setLayoutData(data); - fNewExperimentName.setFont(font); - fNewExperimentName.addListener(SWT.Modify, new Listener() { - @Override - public void handleEvent(Event event) { - validateNewExperimentName(); - } - }); - } - - private void validateNewExperimentName() { - - String name = fNewExperimentName.getText(); - IWorkspace workspace = fExperimentFolder.getWorkspace(); - IStatus nameStatus = workspace.validateName(name, IResource.FOLDER); - - if ("".equals(name)) { //$NON-NLS-1$ - updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.Dialog_EmptyNameError, null)); - return; - } - - if (!nameStatus.isOK()) { - updateStatus(nameStatus); - return; - } - - IPath path = new Path(name); - if (fExperimentFolder.getFolder(path).exists() || fExperimentFolder.getFile(path).exists()) { - updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.Dialog_ExistingNameError, null)); - return; - } - - updateStatus(new Status(IStatus.OK, Activator.PLUGIN_ID, "")); //$NON-NLS-1$ - } - - // ------------------------------------------------------------------------ - // SelectionStatusDialog - // ------------------------------------------------------------------------ - - @Override - protected void computeResult() { - } - - @Override - public void create() { - super.create(); - getButton(IDialogConstants.OK_ID).setEnabled(false); - } - - @Override - protected void okPressed() { - IFolder folder = copyExperiment(fNewExperimentName.getText()); - if (folder == null) { - return; - } - setSelectionResult(new IFolder[] { folder }); - super.okPressed(); - } - - private IFolder copyExperiment(final String newName) { - - WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { - @Override - public void execute(IProgressMonitor monitor) throws CoreException { - try { - monitor.beginTask("", 1000); //$NON-NLS-1$ - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - - fExperiment.copy(newName, true); - - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - } finally { - monitor.done(); - } - } - }; - try { - PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); - } catch (InterruptedException exception) { - return null; - } catch (InvocationTargetException exception) { - MessageDialog.openError(getShell(), "", NLS.bind("", exception.getTargetException().getMessage())); //$NON-NLS-1$ //$NON-NLS-2$ - return null; - } catch (RuntimeException exception) { - return null; - } - - return fExperiment.getResource(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/CopyTraceDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/CopyTraceDialog.java deleted file mode 100644 index 3c4671a6ec..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/CopyTraceDialog.java +++ /dev/null @@ -1,223 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Copied and adapted from NewFolderDialog - * Geneviève Bastien - Moved the actual copy code to model element's class - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.wizards; - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.actions.WorkspaceModifyOperation; -import org.eclipse.ui.dialogs.SelectionStatusDialog; - -/** - * Implementation of the copy trace dialog box. - *

- * @version 1.0 - * @author Francois Chouinard - */ -public class CopyTraceDialog extends SelectionStatusDialog { - - // ------------------------------------------------------------------------ - // Members - // ------------------------------------------------------------------------ - - private final TmfTraceElement fTrace; - private Text fNewTraceName; - private final IFolder fTraceFolder; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - /** - * Constructor. - * @param shell The parent shell - * @param trace The trace model element. - */ - public CopyTraceDialog(Shell shell, TmfTraceElement trace) { - super(shell); - fTrace = trace; - TmfTraceFolder folder = (TmfTraceFolder) trace.getParent(); - fTraceFolder = folder.getResource(); - setTitle(Messages.CopyTraceDialog_DialogTitle); - setStatusLineAboveButtons(true); - } - - // ------------------------------------------------------------------------ - // Dialog - // ------------------------------------------------------------------------ - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - composite.setLayout(new GridLayout()); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - - createNewTraceNameGroup(composite); - return composite; - } - - private void createNewTraceNameGroup(Composite parent) { - Font font = parent.getFont(); - Composite folderGroup = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.numColumns = 2; - folderGroup.setLayout(layout); - folderGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - // Old trace name label - Label oldTraceLabel = new Label(folderGroup, SWT.NONE); - oldTraceLabel.setFont(font); - oldTraceLabel.setText(Messages.CopyTraceDialog_TraceName); - - // Old trace name field - Text oldTraceName = new Text(folderGroup, SWT.BORDER); - GridData data = new GridData(GridData.FILL_HORIZONTAL); - data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; - oldTraceName.setLayoutData(data); - oldTraceName.setFont(font); - oldTraceName.setText(fTrace.getName()); - oldTraceName.setEnabled(false); - - // New trace name label - Label newTraceLabel = new Label(folderGroup, SWT.NONE); - newTraceLabel.setFont(font); - newTraceLabel.setText(Messages.CopyTraceDialog_TraceNewName); - - // New trace name entry field - fNewTraceName = new Text(folderGroup, SWT.BORDER); - data = new GridData(GridData.FILL_HORIZONTAL); - data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; - fNewTraceName.setLayoutData(data); - fNewTraceName.setFont(font); - fNewTraceName.addListener(SWT.Modify, new Listener() { - @Override - public void handleEvent(Event event) { - validateNewTraceName(); - } - }); - } - - private void validateNewTraceName() { - - String name = fNewTraceName.getText(); - IWorkspace workspace = fTraceFolder.getWorkspace(); - IStatus nameStatus = workspace.validateName(name, IResource.FOLDER); - - if ("".equals(name)) { //$NON-NLS-1$ - updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, - Messages.Dialog_EmptyNameError, null)); - return; - } - - if (!nameStatus.isOK()) { - updateStatus(nameStatus); - return; - } - - IPath path = new Path(name); - if (fTraceFolder.getFolder(path).exists() || fTraceFolder.getFile(path).exists()) { - updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, - Messages.Dialog_ExistingNameError, null)); - return; - } - - updateStatus(new Status(IStatus.OK, Activator.PLUGIN_ID, "")); //$NON-NLS-1$ - } - - // ------------------------------------------------------------------------ - // SelectionStatusDialog - // ------------------------------------------------------------------------ - - @Override - protected void computeResult() { - } - - @Override - public void create() { - super.create(); - getButton(IDialogConstants.OK_ID).setEnabled(false); - } - - @Override - protected void okPressed() { - IResource trace = copyTrace(fNewTraceName.getText()); - if (trace == null) { - return; - } - setSelectionResult(new IResource[] { trace }); - super.okPressed(); - } - - private IResource copyTrace(final String newName) { - - WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { - @Override - public void execute(IProgressMonitor monitor) throws CoreException { - try { - monitor.beginTask("", 1000); //$NON-NLS-1$ - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - fTrace.copy(newName, true); - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - } finally { - monitor.done(); - } - } - }; - - try { - PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); - } catch (InterruptedException exception) { - return null; - } catch (InvocationTargetException exception) { - MessageDialog.openError(getShell(), "", NLS.bind("", exception.getTargetException().getMessage())); //$NON-NLS-1$ //$NON-NLS-2$ - return null; - } catch (RuntimeException exception) { - return null; - } - - return fTrace.getResource(); - - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/Messages.java deleted file mode 100644 index e883ebb085..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/Messages.java +++ /dev/null @@ -1,176 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Add support for folder elements - * Marc-Andre Laperle - Preserve folder structure on import - * Bernd Hufmann - Extract ImportTraceWizard messages - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.wizards; - -import org.eclipse.osgi.util.NLS; - -/** - * Message strings for TMF model handling. - * - * @version 1.0 - * @author Francois Chouinard - */ -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.ui.project.wizards.messages"; //$NON-NLS-1$ - - /** - * The dialog header of the new project wizard - */ - public static String NewProjectWizard_DialogHeader; - /** - * The dialog message of the new project wizard - */ - public static String NewProjectWizard_DialogMessage; - /** - * The title of the select traces wizard. - */ - public static String SelectTracesWizard_WindowTitle; - /** - * The column header for the traces (select traces wizard page). - */ - public static String SelectTracesWizardPage_TraceColumnHeader; - /** - * The title of select traces wizard page. - */ - public static String SelectTracesWizardPage_WindowTitle; - /** - * The description of the select traces wizard page. - */ - public static String SelectTracesWizardPage_Description; - /** - * The error message when selecting of traces for an experiment fails. - * @since 3.1 - */ - public static String SelectTracesWizardPage_SelectionError; - /** - * The task name for selecting of a trace for an experiment. - * @since 3.1 - */ - public static String SelectTracesWizardPage_TraceSelectionTask; - /** - * The task name for removing of a trace for an experiment. - * @since 3.1 - */ - public static String SelectTracesWizardPage_TraceRemovalTask; - /** - * The cancel message for the trace selection operation. - * @since 3.1 - */ - public static String SelectTracesWizardPage_SelectionOperationCancelled; - /** - * The error message title. - * @since 3.1 - */ - public static String SelectTracesWizardPage_InternalErrorTitle; - /** - * The error message when no name was entered in a dialog box (new trace or experiment dialog) - */ - public static String Dialog_EmptyNameError; - /** - * The error message when name of trace or experiment already exists - */ - public static String Dialog_ExistingNameError; - /** - * The title of the new experiment dialog. - */ - public static String NewExperimentDialog_DialogTitle; - /** - * The label of the new experiment name field. - */ - public static String NewExperimentDialog_ExperimentName; - /** - * The title of the rename experiment dialog. - */ - public static String RenameExperimentDialog_DialogTitle; - /** - * The label of the field of the current experiment name. - */ - public static String RenameExperimentDialog_ExperimentName; - /** - * The label of the field for entering the new experiment name. - */ - public static String RenameExperimentDialog_ExperimentNewName; - /** - * The title of the copy experiment dialog. - */ - public static String CopyExperimentDialog_DialogTitle; - /** - * The label of the field of the current experiment name. - */ - public static String CopyExperimentDialog_ExperimentName; - /** - * The label of the field for entering the new experiment name. - */ - public static String CopyExperimentDialog_ExperimentNewName; - /** - * The title of the rename trace dialog. - */ - public static String RenameTraceDialog_DialogTitle; - /** - * The label of the field of the current trace name. - */ - public static String RenameTraceDialog_TraceName; - /** - * The label of the field for entering the new trace name. - */ - public static String RenameTraceDialog_TraceNewName; - /** - * The title of the copy trace dialog. - */ - public static String CopyTraceDialog_DialogTitle; - /** - * The label of the field of the current trace name. - */ - public static String CopyTraceDialog_TraceName; - /** - * The label of the field for entering the new trace name. - */ - public static String CopyTraceDialog_TraceNewName; - /** - * The title of the new folder dialog. - * @since 3.0 - */ - public static String NewFolderDialog_DialogTitle; - /** - * The label of the new folder name field. - * @since 3.0 - */ - public static String NewFolderDialog_FolderName; - /** - * The title of the rename folder dialog. - * @since 3.0 - */ - public static String RenameFolderDialog_DialogTitle; - /** - * The label of the field of the current folder name. - * @since 3.0 - */ - public static String RenameFolderDialog_FolderName; - /** - * The label of the field for entering the new folder name. - * @since 3.0 - */ - public static String RenameFolderDialog_FolderNewName; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/NewExperimentDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/NewExperimentDialog.java deleted file mode 100644 index b77969d570..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/NewExperimentDialog.java +++ /dev/null @@ -1,231 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Copied and adapted from NewFolderDialog - * Geneviève Bastien - Add support of experiment types - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.wizards; - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.InvalidRegistryObjectException; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentFolder; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.actions.WorkspaceModifyOperation; -import org.eclipse.ui.dialogs.SelectionStatusDialog; - -/** - * Implementation of new experiment dialog that creates the experiment element. - *

- * - * @version 1.0 - * @author Francois Chouinard - */ -public class NewExperimentDialog extends SelectionStatusDialog { - - // ------------------------------------------------------------------------ - // Members - // ------------------------------------------------------------------------ - - private Text fExperimentName; - private final IContainer fExperimentFolder; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - /** - * Constructor - * - * @param shell - * The parent shell - * @param experimentFolder - * The parent experiment folder element - */ - public NewExperimentDialog(Shell shell, TmfExperimentFolder experimentFolder) { - super(shell); - fExperimentFolder = experimentFolder.getResource(); - setTitle(Messages.NewExperimentDialog_DialogTitle); - setStatusLineAboveButtons(true); - } - - // ------------------------------------------------------------------------ - // Dialog - // ------------------------------------------------------------------------ - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - composite.setLayout(new GridLayout()); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - - createExperimentNameGroup(composite); - return composite; - } - - private void createExperimentNameGroup(Composite parent) { - Font font = parent.getFont(); - Composite folderGroup = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.numColumns = 2; - folderGroup.setLayout(layout); - folderGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - // New experiment label - Label experimentLabel = new Label(folderGroup, SWT.NONE); - experimentLabel.setFont(font); - experimentLabel.setText(Messages.NewExperimentDialog_ExperimentName); - - // New experiment name entry field - fExperimentName = new Text(folderGroup, SWT.BORDER); - GridData data = new GridData(GridData.FILL_HORIZONTAL); - data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; - fExperimentName.setLayoutData(data); - fExperimentName.setFont(font); - fExperimentName.addListener(SWT.Modify, new Listener() { - @Override - public void handleEvent(Event event) { - validateNewExperimentName(); - } - }); - } - - private void validateNewExperimentName() { - - String name = fExperimentName.getText(); - IWorkspace workspace = fExperimentFolder.getWorkspace(); - IStatus nameStatus = workspace.validateName(name, IResource.FOLDER); - - if ("".equals(name)) { //$NON-NLS-1$ - updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.Dialog_EmptyNameError, null)); - return; - } - - if (!nameStatus.isOK()) { - updateStatus(nameStatus); - return; - } - - IPath path = new Path(name); - if (fExperimentFolder.getFolder(path).exists() || fExperimentFolder.getFile(path).exists()) { - updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.Dialog_ExistingNameError, null)); - return; - } - - updateStatus(new Status(IStatus.OK, Activator.PLUGIN_ID, "")); //$NON-NLS-1$ - } - - // ------------------------------------------------------------------------ - // SelectionStatusDialog - // ------------------------------------------------------------------------ - - @Override - protected void computeResult() { - } - - @Override - public void create() { - super.create(); - getButton(IDialogConstants.OK_ID).setEnabled(false); - } - - @Override - protected void okPressed() { - IFolder folder = createNewExperiment(fExperimentName.getText()); - if (folder == null) { - return; - } - setSelectionResult(new IFolder[] { folder }); - super.okPressed(); - } - - private IFolder createNewExperiment(String experimentName) { - - final IFolder experimentFolder = createExperiment(experimentName); - - WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { - @Override - public void execute(IProgressMonitor monitor) throws CoreException { - try { - monitor.beginTask("", 1000); //$NON-NLS-1$ - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - experimentFolder.create(false, true, monitor); - - /* - * Experiments can be set to the default experiment type. No - * need to force user to select an experiment type - */ - IConfigurationElement ce = TmfTraceType.getTraceAttributes(TmfTraceType.DEFAULT_EXPERIMENT_TYPE); - if (ce != null) { - try { - experimentFolder.setPersistentProperty(TmfCommonConstants.TRACETYPE, ce.getAttribute(TmfTraceType.ID_ATTR)); - } catch (InvalidRegistryObjectException | CoreException e) { - } - } - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - } finally { - monitor.done(); - } - } - }; - try { - PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); - } catch (InterruptedException | RuntimeException exception) { - return null; - } catch (InvocationTargetException exception) { - MessageDialog.openError(getShell(), "", NLS.bind("", exception.getTargetException().getMessage())); //$NON-NLS-1$ //$NON-NLS-2$ - return null; - } - - return experimentFolder; - } - - private IFolder createExperiment(String experimentName) { - IWorkspaceRoot workspaceRoot = fExperimentFolder.getWorkspace().getRoot(); - IPath folderPath = fExperimentFolder.getFullPath().append(experimentName); - IFolder folder = workspaceRoot.getFolder(folderPath); - - return folder; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/NewFolderDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/NewFolderDialog.java deleted file mode 100644 index 2b09bfabd1..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/NewFolderDialog.java +++ /dev/null @@ -1,192 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.wizards; - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.actions.WorkspaceModifyOperation; -import org.eclipse.ui.dialogs.SelectionStatusDialog; - -/** - * Implementation of new folder dialog that creates the folder element. - * @since 3.0 - */ -public class NewFolderDialog extends SelectionStatusDialog { - - // ------------------------------------------------------------------------ - // Members - // ------------------------------------------------------------------------ - - private Text fFolderName; - private final IFolder fParentFolder; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - /** - * Constructor - * - * @param shell - * The parent shell - * @param parent - * The parent trace folder - */ - public NewFolderDialog(Shell shell, TmfTraceFolder parent) { - super(shell); - fParentFolder = parent.getResource(); - setTitle(Messages.NewFolderDialog_DialogTitle); - setStatusLineAboveButtons(true); - } - - // ------------------------------------------------------------------------ - // Dialog - // ------------------------------------------------------------------------ - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - composite.setLayout(new GridLayout()); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - - createFolderNameGroup(composite); - return composite; - } - - private void createFolderNameGroup(Composite parent) { - Font font = parent.getFont(); - Composite folderGroup = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.numColumns = 2; - folderGroup.setLayout(layout); - folderGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - // New folder label - Label folderLabel = new Label(folderGroup, SWT.NONE); - folderLabel.setFont(font); - folderLabel.setText(Messages.NewFolderDialog_FolderName); - - // New folder name entry field - fFolderName = new Text(folderGroup, SWT.BORDER); - GridData data = new GridData(GridData.FILL_HORIZONTAL); - data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; - fFolderName.setLayoutData(data); - fFolderName.setFont(font); - fFolderName.addListener(SWT.Modify, new Listener() { - @Override - public void handleEvent(Event event) { - validateNewFolderName(); - } - }); - } - - private void validateNewFolderName() { - - String name = fFolderName.getText(); - IWorkspace workspace = fParentFolder.getWorkspace(); - IStatus nameStatus = workspace.validateName(name, IResource.FOLDER); - - if ("".equals(name)) { //$NON-NLS-1$ - updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.Dialog_EmptyNameError, null)); - return; - } - - if (!nameStatus.isOK()) { - updateStatus(nameStatus); - return; - } - - if (fParentFolder.findMember(name) != null) { - updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.Dialog_ExistingNameError, null)); - return; - } - - updateStatus(new Status(IStatus.OK, Activator.PLUGIN_ID, "")); //$NON-NLS-1$ - } - - // ------------------------------------------------------------------------ - // SelectionStatusDialog - // ------------------------------------------------------------------------ - - @Override - protected void computeResult() { - } - - @Override - public void create() { - super.create(); - getButton(IDialogConstants.OK_ID).setEnabled(false); - } - - @Override - protected void okPressed() { - IFolder folder = createNewFolder(fFolderName.getText()); - if (folder == null) { - return; - } - setSelectionResult(new IFolder[] { folder }); - super.okPressed(); - } - - private IFolder createNewFolder(String folderName) { - - final IFolder folder = fParentFolder.getFolder(new Path(folderName)); - - WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { - @Override - public void execute(IProgressMonitor monitor) throws CoreException { - try { - monitor.beginTask("", 1000); //$NON-NLS-1$ - folder.create(false, true, monitor); - } finally { - monitor.done(); - } - } - }; - try { - PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); - } catch (InterruptedException | RuntimeException exception) { - return null; - } catch (InvocationTargetException exception) { - MessageDialog.openError(getShell(), "", NLS.bind("", exception.getTargetException().getMessage())); //$NON-NLS-1$ //$NON-NLS-2$ - return null; - } - - return folder; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/NewTmfProjectMainWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/NewTmfProjectMainWizardPage.java deleted file mode 100644 index ccc84b0071..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/NewTmfProjectMainWizardPage.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.wizards; - -import org.eclipse.ui.dialogs.WizardNewProjectCreationPage; - -/** - * The wizard page for creation of a new TMF tracing project. - *

- * @version 1.0 - * @author Francois Chouinard - - */ -public class NewTmfProjectMainWizardPage extends WizardNewProjectCreationPage { - - /** - * Constructor - * - * @param pageName - * The name of this wizard page - */ - public NewTmfProjectMainWizardPage(String pageName) { - super(pageName); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/NewTmfProjectWizard.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/NewTmfProjectWizard.java deleted file mode 100644 index 85894718c2..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/NewTmfProjectWizard.java +++ /dev/null @@ -1,152 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Moved project creation utility method to TmfProjectRegistry - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.wizards; - -import java.net.URI; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExecutableExtension; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry; -import org.eclipse.ui.INewWizard; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.wizards.newresource.BasicNewProjectResourceWizard; - -/** - * Wizard implementation for creating a TMF tracing project. - * - * @version 1.0 - * @author Francois Chouinard - */ -public class NewTmfProjectWizard extends Wizard implements INewWizard, IExecutableExtension { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The wizard id - * - * @since 2.0 - */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.ui.wizards.newProject"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final String fTtitle; - private final String fDescription; - - /** - * Wizard main page - */ - protected NewTmfProjectMainWizardPage fMainPage; - - /** - * The Project name - */ - protected String fProjectName; - - /** - * The project location - */ - - protected URI fProjectLocation; - - /** - * The configuration element. - */ - protected IConfigurationElement fConfigElement; - - /** - * The project reference - */ - protected IProject fProject; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - public NewTmfProjectWizard() { - this(Messages.NewProjectWizard_DialogHeader, Messages.NewProjectWizard_DialogMessage); - } - - /** - * Constructor - * @param title The tile string - * @param desc The description string - */ - public NewTmfProjectWizard(String title, String desc) { - super(); - setDialogSettings(Activator.getDefault().getDialogSettings()); - setNeedsProgressMonitor(true); - setForcePreviousAndNextButtons(true); - setWindowTitle(title); - fTtitle = title; - fDescription = desc; - } - - // ------------------------------------------------------------------------ - // Wizard - // ------------------------------------------------------------------------ - - @Override - public void addPages() { - fMainPage = new NewTmfProjectMainWizardPage(Messages.NewProjectWizard_DialogHeader); - fMainPage.setTitle(fTtitle); - fMainPage.setDescription(fDescription); - addPage(fMainPage); - } - - @Override - public boolean performCancel() { - return true; - } - - @Override - public boolean performFinish() { - fProjectName = fMainPage.getProjectName(); - fProjectLocation = fMainPage.useDefaults() ? null : fMainPage.getLocationURI(); - fProject = TmfProjectRegistry.createProject(fProjectName, fProjectLocation, new NullProgressMonitor()); - BasicNewProjectResourceWizard.updatePerspective(fConfigElement); - return true; - } - - // ------------------------------------------------------------------------ - // INewWizard - // ------------------------------------------------------------------------ - - @Override - public void init(IWorkbench iworkbench, IStructuredSelection istructuredselection) { - } - - // ------------------------------------------------------------------------ - // IExecutableExtension - // ------------------------------------------------------------------------ - - @Override - public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException { - fConfigElement = config; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/RenameExperimentDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/RenameExperimentDialog.java deleted file mode 100644 index 09d16e4d09..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/RenameExperimentDialog.java +++ /dev/null @@ -1,242 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Copied and adapted from NewFolderDialog - * Patrick Tasse - Close editors to release resources - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.wizards; - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentFolder; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.actions.WorkspaceModifyOperation; -import org.eclipse.ui.dialogs.SelectionStatusDialog; - -/** - * Implementation of a dialog box to rename an experiment. - *

- * - * @version 1.0 - * @author Francois Chouinard - */ -public class RenameExperimentDialog extends SelectionStatusDialog { - - // ------------------------------------------------------------------------ - // Members - // ------------------------------------------------------------------------ - - private final TmfExperimentElement fExperiment; - private Text fNewExperimentName; - private final IContainer fExperimentFolder; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructor - * - * @param shell - * The parent shell - * @param experiment - * The experiment element rename - */ - public RenameExperimentDialog(Shell shell, TmfExperimentElement experiment) { - super(shell); - fExperiment = experiment; - TmfExperimentFolder folder = (TmfExperimentFolder) experiment.getParent(); - fExperimentFolder = folder.getResource(); - setTitle(Messages.RenameExperimentDialog_DialogTitle); - setStatusLineAboveButtons(true); - } - - // ------------------------------------------------------------------------ - // Dialog - // ------------------------------------------------------------------------ - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - composite.setLayout(new GridLayout()); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - - createNewExperimentNameGroup(composite); - return composite; - } - - private void createNewExperimentNameGroup(Composite parent) { - Font font = parent.getFont(); - Composite folderGroup = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.numColumns = 2; - folderGroup.setLayout(layout); - folderGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - // Old experiment name label - Label oldExperimentLabel = new Label(folderGroup, SWT.NONE); - oldExperimentLabel.setFont(font); - oldExperimentLabel.setText(Messages.RenameExperimentDialog_ExperimentName); - - // Old experiment name field - Text oldExperimentName = new Text(folderGroup, SWT.BORDER); - GridData data = new GridData(GridData.FILL_HORIZONTAL); - data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; - oldExperimentName.setLayoutData(data); - oldExperimentName.setFont(font); - oldExperimentName.setText(fExperiment.getName()); - oldExperimentName.setEnabled(false); - - // New experiment name label - Label newExperimentLabel = new Label(folderGroup, SWT.NONE); - newExperimentLabel.setFont(font); - newExperimentLabel.setText(Messages.RenameExperimentDialog_ExperimentNewName); - - // New experiment name entry field - fNewExperimentName = new Text(folderGroup, SWT.BORDER); - data = new GridData(GridData.FILL_HORIZONTAL); - data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; - fNewExperimentName.setLayoutData(data); - fNewExperimentName.setFont(font); - fNewExperimentName.addListener(SWT.Modify, new Listener() { - @Override - public void handleEvent(Event event) { - validateNewExperimentName(); - } - }); - } - - private void validateNewExperimentName() { - - String name = fNewExperimentName.getText(); - IWorkspace workspace = fExperimentFolder.getWorkspace(); - IStatus nameStatus = workspace.validateName(name, IResource.FOLDER); - - if ("".equals(name)) { //$NON-NLS-1$ - updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.Dialog_EmptyNameError, null)); - return; - } - - if (!nameStatus.isOK()) { - updateStatus(nameStatus); - return; - } - - IPath path = new Path(name); - if (fExperimentFolder.getFolder(path).exists() || fExperimentFolder.getFile(path).exists()) { - updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.Dialog_ExistingNameError, null)); - return; - } - - updateStatus(new Status(IStatus.OK, Activator.PLUGIN_ID, "")); //$NON-NLS-1$ - } - - // ------------------------------------------------------------------------ - // SelectionStatusDialog - // ------------------------------------------------------------------------ - - @Override - protected void computeResult() { - } - - @Override - public void create() { - super.create(); - getButton(IDialogConstants.OK_ID).setEnabled(false); - } - - @Override - protected void okPressed() { - IFolder folder = renameExperiment(fNewExperimentName.getText()); - if (folder == null) { - return; - } - setSelectionResult(new IFolder[] { folder }); - super.okPressed(); - } - - private IFolder renameExperiment(final String newName) { - - IPath oldPath = fExperiment.getResource().getFullPath(); - final IPath newPath = oldPath.append("../" + newName); //$NON-NLS-1$ - - WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { - @Override - public void execute(IProgressMonitor monitor) throws CoreException { - try { - monitor.beginTask("", 1000); //$NON-NLS-1$ - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - // Close the experiment if open - fExperiment.closeEditors(); - - IFolder folder = fExperiment.getResource(); - IFile bookmarksFile = fExperiment.getBookmarksFile(); - IFile newBookmarksFile = folder.getFile(bookmarksFile.getName().replace(fExperiment.getName(), newName)); - if (bookmarksFile.exists()) { - if (!newBookmarksFile.exists()) { - IPath newBookmarksPath = newBookmarksFile.getFullPath(); - bookmarksFile.move(newBookmarksPath, IResource.FORCE | IResource.SHALLOW, null); - } - } - - fExperiment.renameSupplementaryFolder(newName); - fExperiment.getResource().move(newPath, IResource.FORCE | IResource.SHALLOW, null); - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - } finally { - monitor.done(); - } - } - }; - try { - PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); - } catch (InterruptedException exception) { - return null; - } catch (InvocationTargetException exception) { - MessageDialog.openError(getShell(), "", exception.getTargetException().getMessage()); //$NON-NLS-1$ - return null; - } catch (RuntimeException exception) { - return null; - } - - return fExperiment.getResource(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/RenameFolderDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/RenameFolderDialog.java deleted file mode 100644 index ac0a947ef4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/RenameFolderDialog.java +++ /dev/null @@ -1,167 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.wizards; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.dialogs.SelectionStatusDialog; - -/** - * Implementation of a dialog box to rename a folder. - * @since 3.0 - */ -public class RenameFolderDialog extends SelectionStatusDialog { - - // ------------------------------------------------------------------------ - // Members - // ------------------------------------------------------------------------ - - private final TmfTraceFolder fFolder; - private Text fNewFolderNameText; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructor - * @param shell The parent shell - * @param folder The trace element to rename - */ - public RenameFolderDialog(Shell shell, TmfTraceFolder folder) { - super(shell); - fFolder = folder; - setTitle(Messages.RenameFolderDialog_DialogTitle); - setStatusLineAboveButtons(true); - } - - // ------------------------------------------------------------------------ - // Dialog - // ------------------------------------------------------------------------ - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - composite.setLayout(new GridLayout()); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - - createNewTraceNameGroup(composite); - return composite; - } - - private void createNewTraceNameGroup(Composite parent) { - Font font = parent.getFont(); - Composite folderGroup = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.numColumns = 2; - folderGroup.setLayout(layout); - folderGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - // Old trace name label - Label oldTraceLabel = new Label(folderGroup, SWT.NONE); - oldTraceLabel.setFont(font); - oldTraceLabel.setText(Messages.RenameFolderDialog_FolderName); - - // Old trace name field - Text oldTraceName = new Text(folderGroup, SWT.BORDER); - GridData data = new GridData(GridData.FILL_HORIZONTAL); - data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; - oldTraceName.setLayoutData(data); - oldTraceName.setFont(font); - oldTraceName.setText(fFolder.getName()); - oldTraceName.setEnabled(false); - - // New trace name label - Label newTaceLabel = new Label(folderGroup, SWT.NONE); - newTaceLabel.setFont(font); - newTaceLabel.setText(Messages.RenameFolderDialog_FolderNewName); - - // New trace name entry field - fNewFolderNameText = new Text(folderGroup, SWT.BORDER); - data = new GridData(GridData.FILL_HORIZONTAL); - data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; - fNewFolderNameText.setLayoutData(data); - fNewFolderNameText.setFont(font); - fNewFolderNameText.addListener(SWT.Modify, new Listener() { - @Override - public void handleEvent(Event event) { - validateNewFolderName(); - } - }); - } - - private void validateNewFolderName() { - - String newFolderName = fNewFolderNameText.getText(); - IWorkspace workspace = fFolder.getResource().getWorkspace(); - IStatus nameStatus = workspace.validateName(newFolderName, IResource.FOLDER); - - if ("".equals(newFolderName)) { //$NON-NLS-1$ - updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, - Messages.Dialog_EmptyNameError, null)); - return; - } - - if (!nameStatus.isOK()) { - updateStatus(nameStatus); - return; - } - - IContainer parentFolder = fFolder.getResource().getParent(); - if (parentFolder.findMember(newFolderName) != null) { - updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, - Messages.Dialog_ExistingNameError, null)); - return; - } - - updateStatus(new Status(IStatus.OK, Activator.PLUGIN_ID, "")); //$NON-NLS-1$ - } - - // ------------------------------------------------------------------------ - // SelectionStatusDialog - // ------------------------------------------------------------------------ - - @Override - protected void computeResult() { - } - - @Override - public void create() { - super.create(); - getButton(IDialogConstants.OK_ID).setEnabled(false); - } - - @Override - protected void okPressed() { - setSelectionResult(new String[] { fNewFolderNameText.getText() }); - super.okPressed(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/RenameTraceDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/RenameTraceDialog.java deleted file mode 100644 index ed2623ab97..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/RenameTraceDialog.java +++ /dev/null @@ -1,169 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Copied and adapted from NewFolderDialog - * Patrick Tasse - Close editors to release resources - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.wizards; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.dialogs.SelectionStatusDialog; - -/** - * Implementation of a dialog box to rename a trace. - *

- * @version 1.0 - * @author Francois Chouinard - */ -public class RenameTraceDialog extends SelectionStatusDialog { - - // ------------------------------------------------------------------------ - // Members - // ------------------------------------------------------------------------ - - private final TmfTraceElement fTrace; - private Text fNewTraceNameText; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - /** - * Constructor - * @param shell The parent shell - * @param trace The trace element to rename - */ - public RenameTraceDialog(Shell shell, TmfTraceElement trace) { - super(shell); - fTrace = trace; - setTitle(Messages.RenameTraceDialog_DialogTitle); - setStatusLineAboveButtons(true); - } - - // ------------------------------------------------------------------------ - // Dialog - // ------------------------------------------------------------------------ - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - composite.setLayout(new GridLayout()); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - - createNewTraceNameGroup(composite); - return composite; - } - - private void createNewTraceNameGroup(Composite parent) { - Font font = parent.getFont(); - Composite folderGroup = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.numColumns = 2; - folderGroup.setLayout(layout); - folderGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - // Old trace name label - Label oldTraceLabel = new Label(folderGroup, SWT.NONE); - oldTraceLabel.setFont(font); - oldTraceLabel.setText(Messages.RenameTraceDialog_TraceName); - - // Old trace name field - Text oldTraceName = new Text(folderGroup, SWT.BORDER); - GridData data = new GridData(GridData.FILL_HORIZONTAL); - data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; - oldTraceName.setLayoutData(data); - oldTraceName.setFont(font); - oldTraceName.setText(fTrace.getName()); - oldTraceName.setEnabled(false); - - // New trace name label - Label newTaceLabel = new Label(folderGroup, SWT.NONE); - newTaceLabel.setFont(font); - newTaceLabel.setText(Messages.RenameTraceDialog_TraceNewName); - - // New trace name entry field - fNewTraceNameText = new Text(folderGroup, SWT.BORDER); - data = new GridData(GridData.FILL_HORIZONTAL); - data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; - fNewTraceNameText.setLayoutData(data); - fNewTraceNameText.setFont(font); - fNewTraceNameText.addListener(SWT.Modify, new Listener() { - @Override - public void handleEvent(Event event) { - validateNewTraceName(); - } - }); - } - - private void validateNewTraceName() { - - String newTraceName = fNewTraceNameText.getText(); - IWorkspace workspace = fTrace.getResource().getWorkspace(); - IStatus nameStatus = workspace.validateName(newTraceName, IResource.FOLDER); - - if ("".equals(newTraceName)) { //$NON-NLS-1$ - updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, - Messages.Dialog_EmptyNameError, null)); - return; - } - - if (!nameStatus.isOK()) { - updateStatus(nameStatus); - return; - } - - IContainer parentFolder = fTrace.getResource().getParent(); - if (parentFolder.findMember(newTraceName) != null) { - updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, - Messages.Dialog_ExistingNameError, null)); - return; - } - - updateStatus(new Status(IStatus.OK, Activator.PLUGIN_ID, "")); //$NON-NLS-1$ - } - - // ------------------------------------------------------------------------ - // SelectionStatusDialog - // ------------------------------------------------------------------------ - - @Override - protected void computeResult() { - } - - @Override - public void create() { - super.create(); - getButton(IDialogConstants.OK_ID).setEnabled(false); - } - - @Override - protected void okPressed() { - setSelectionResult(new String[] { fNewTraceNameText.getText() }); - super.okPressed(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/SelectTracesWizard.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/SelectTracesWizard.java deleted file mode 100644 index 50f7ecc513..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/SelectTracesWizard.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.wizards; - -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; -import org.eclipse.ui.IImportWizard; -import org.eclipse.ui.IWorkbench; - -/** - * Wizard implementation to select traces for an experiment. - *

- * @version 1.0 - * @author Francois Chouinard - */ -public class SelectTracesWizard extends Wizard implements IImportWizard { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final TmfProjectElement fProject; - private final TmfExperimentElement fExperiment; - private SelectTracesWizardPage fSelectTraceWizardPage; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructor - * @param project The project model element - * @param experiment The experiemnt model element - */ - public SelectTracesWizard(TmfProjectElement project, TmfExperimentElement experiment) { - fProject = project; - fExperiment = experiment; - } - - // ------------------------------------------------------------------------ - // Wizard - // ------------------------------------------------------------------------ - - @Override - public void init(IWorkbench workbench, IStructuredSelection selection) { - setWindowTitle(Messages.SelectTracesWizard_WindowTitle); - setNeedsProgressMonitor(true); - } - - @Override - public void addPages() { - super.addPages(); - fSelectTraceWizardPage = new SelectTracesWizardPage(fProject, fExperiment); - addPage(fSelectTraceWizardPage); - } - - @Override - public boolean performFinish() { - return fSelectTraceWizardPage.performFinish(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/SelectTracesWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/SelectTracesWizardPage.java deleted file mode 100644 index 844f1ebdbb..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/SelectTracesWizardPage.java +++ /dev/null @@ -1,477 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Geneviève Bastien - Moved the add and remove code to the experiment class - * Patrick Tasse - Add support for folder elements - * Marc-Andre Laperle - Convert to tree structure and add select/deselect all - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.project.wizards; - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Vector; - -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.operation.ModalContext; -import org.eclipse.jface.viewers.CheckStateChangedEvent; -import org.eclipse.jface.viewers.CheckboxTreeViewer; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.ICheckStateListener; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.TreeViewerColumn; -import org.eclipse.jface.viewers.ViewerSorter; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.linuxtools.tmf.ui.project.model.ITmfProjectModelElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfNavigatorContentProvider; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfNavigatorLabelProvider; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; -import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.ui.dialogs.FilteredTree; -import org.eclipse.ui.dialogs.PatternFilter; - -/** - * Implementation of a wizard page for selecting trace for an experiment. - *

- * - * @version 1.0 - * @author Francois Chouinard - */ -public class SelectTracesWizardPage extends WizardPage { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final TmfProjectElement fProject; - private final TmfExperimentElement fExperiment; - private Map fPreviousTraces; - private CheckboxTreeViewer fCheckboxTreeViewer; - private TmfNavigatorContentProvider fContentProvider; - private TmfNavigatorLabelProvider fLabelProvider; - - private static final int COLUMN_WIDTH = 200; - private static final int BUTTON_SPACING = 4; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - /** - * Constructor - * - * @param project - * The project model element. - * @param experiment - * The experiment model experiment. - */ - protected SelectTracesWizardPage(TmfProjectElement project, TmfExperimentElement experiment) { - super(""); //$NON-NLS-1$ - setTitle(Messages.SelectTracesWizardPage_WindowTitle); - setDescription(Messages.SelectTracesWizardPage_Description); - fProject = project; - fExperiment = experiment; - } - - // ------------------------------------------------------------------------ - // Dialog - // ------------------------------------------------------------------------ - - @Override - public void createControl(Composite parent) { - Composite container = new Composite(parent, SWT.NULL); - container.setLayout(new GridLayout(2, false)); - setControl(container); - - new FilteredTree(container, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, new PatternFilter(), true) { - @Override - protected TreeViewer doCreateTreeViewer(Composite aparent, int style) { - return SelectTracesWizardPage.this.doCreateTreeViewer(aparent); - } - }; - - Composite buttonComposite = new Composite(container, SWT.NONE); - FillLayout layout = new FillLayout(SWT.VERTICAL); - layout.spacing = BUTTON_SPACING; - buttonComposite.setLayout(layout); - GridData gd = new GridData(); - gd.verticalAlignment = SWT.CENTER; - buttonComposite.setLayoutData(gd); - - Button selectAllButton = new Button(buttonComposite, SWT.PUSH); - selectAllButton.setText(org.eclipse.linuxtools.internal.tmf.ui.project.dialogs.Messages.Dialog_SelectAll); - selectAllButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - setAllChecked(true); - } - }); - - Button deselectAllButton = new Button(buttonComposite, SWT.PUSH); - deselectAllButton.setText(org.eclipse.linuxtools.internal.tmf.ui.project.dialogs.Messages.Dialog_DeselectAll); - deselectAllButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - setAllChecked(false); - } - }); - } - - private TreeViewer doCreateTreeViewer(Composite parent) { - fCheckboxTreeViewer = new CheckboxTreeViewer(parent, SWT.BORDER); - fContentProvider = new TmfNavigatorContentProvider() { - - @Override - public Object[] getElements(Object inputElement) { - return getChildren(inputElement); - } - - @Override - public synchronized Object[] getChildren(Object parentElement) { - // We only care about the content of trace folders - if (parentElement instanceof TmfTraceFolder) { - Object[] children = super.getChildren(parentElement); - List filteredChildren = new ArrayList<>(); - for (Object child : children) { - if (child instanceof TmfTraceElement) { - TmfTraceElement traceElement = (TmfTraceElement) child; - String traceType = traceElement.getTraceType(); - if (traceType != null && TmfTraceType.getTraceType(traceType) != null) { - filteredChildren.add(traceElement); - } - } else if (child instanceof TmfTraceFolder) { - filteredChildren.add((TmfTraceFolder) child); - } - } - return filteredChildren.toArray(); - } - return null; - } - - @Override - public boolean hasChildren(Object element) { - Object[] children = getChildren(element); - return children != null && children.length > 0; - } - }; - fCheckboxTreeViewer.setContentProvider(fContentProvider); - fLabelProvider = new TmfNavigatorLabelProvider(); - fCheckboxTreeViewer.setLabelProvider(fLabelProvider); - fCheckboxTreeViewer.setSorter(new ViewerSorter()); - - final Tree tree = fCheckboxTreeViewer.getTree(); - GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); - tree.setLayoutData(gd); - tree.setHeaderVisible(true); - - final TreeViewerColumn column = new TreeViewerColumn(fCheckboxTreeViewer, SWT.NONE); - column.getColumn().setWidth(COLUMN_WIDTH); - column.getColumn().setText(Messages.SelectTracesWizardPage_TraceColumnHeader); - column.setLabelProvider(new ColumnLabelProvider() { - @Override - public String getText(Object element) { - return fLabelProvider.getText(element); - } - - @Override - public Image getImage(Object element) { - return fLabelProvider.getImage(element); - } - }); - - // Get the list of traces already part of the experiment - fPreviousTraces = new HashMap<>(); - for (ITmfProjectModelElement child : fExperiment.getChildren()) { - if (child instanceof TmfTraceElement) { - TmfTraceElement trace = (TmfTraceElement) child; - String name = trace.getElementPath(); - fPreviousTraces.put(name, trace); - } - } - - // Populate the list of traces to choose from - Set keys = fPreviousTraces.keySet(); - TmfTraceFolder traceFolder = fProject.getTracesFolder(); - fCheckboxTreeViewer.setInput(traceFolder); - - // Set the checkbox for the traces already included - setCheckedAlreadyIncludedTraces(keys, fContentProvider.getElements(fCheckboxTreeViewer.getInput())); - - fCheckboxTreeViewer.addCheckStateListener(new ICheckStateListener() { - @Override - public void checkStateChanged(CheckStateChangedEvent event) { - Object element = event.getElement(); - setSubtreeChecked(element, event.getChecked()); - maintainCheckIntegrity(element); - } - }); - - return fCheckboxTreeViewer; - } - - private void maintainCheckIntegrity(final Object element) { - Object parentElement = fContentProvider.getParent(element); - boolean allChecked = true; - boolean oneChecked = false; - boolean oneGrayed = false; - if (parentElement != null) { - if (fContentProvider.getChildren(parentElement) != null) { - for (Object child : fContentProvider.getChildren(parentElement)) { - boolean checked = fCheckboxTreeViewer.getChecked(child); - oneChecked |= checked; - allChecked &= checked; - oneGrayed |= fCheckboxTreeViewer.getGrayed(child); - } - } - if (oneGrayed || oneChecked && !allChecked) { - fCheckboxTreeViewer.setGrayChecked(parentElement, true); - } else { - fCheckboxTreeViewer.setGrayed(parentElement, false); - fCheckboxTreeViewer.setChecked(parentElement, allChecked); - } - maintainCheckIntegrity(parentElement); - } - } - - private void setCheckedAlreadyIncludedTraces(Set alreadyIncludedTraces, Object[] elements) { - for (Object element : elements) { - if (element instanceof TmfTraceElement) { - TmfTraceElement trace = (TmfTraceElement) element; - String elementPath = trace.getElementPath(); - if (alreadyIncludedTraces.contains(elementPath)) { - fCheckboxTreeViewer.setChecked(element, true); - maintainCheckIntegrity(element); - } - } - Object[] children = fContentProvider.getChildren(element); - if (children != null) { - setCheckedAlreadyIncludedTraces(alreadyIncludedTraces, children); - } - } - } - - /** - * Sets all items in the element viewer to be checked or unchecked - * - * @param checked - * whether or not items should be checked - */ - private void setAllChecked(boolean checked) { - for (Object element : fContentProvider.getChildren(fCheckboxTreeViewer.getInput())) { - setSubtreeChecked(element, checked); - } - } - - /** - * A version of setSubtreeChecked that also handles the grayed state - * - * @param element - * the element - * @param checked - * true if the item should be checked, and false if it should be - * unchecked - */ - private void setSubtreeChecked(Object element, boolean checked) { - fCheckboxTreeViewer.setChecked(element, checked); - if (checked) { - fCheckboxTreeViewer.setGrayed(element, false); - } - Object[] children = fContentProvider.getChildren(element); - if (children != null) { - for (Object child : children) { - setSubtreeChecked(child, checked); - } - } - } - - /** - * Method to finalize the select operation. - * - * @return true if successful else false - */ - public boolean performFinish() { - - IFolder experiment = fExperiment.getResource(); - - final SelectTracesOperation operation = new SelectTracesOperation(experiment, getSelection()); - - IStatus status = Status.OK_STATUS; - try { - getContainer().run(true, true, new IRunnableWithProgress() { - @Override - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - // Wrapper to have only one resource changed event at the - // end of the operation. - IWorkspaceRunnable workspaceRunnable = new IWorkspaceRunnable() { - @Override - public void run(IProgressMonitor pm) throws CoreException { - operation.run(pm); - } - }; - - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - try { - workspace.run(workspaceRunnable, workspace.getRoot(), IWorkspace.AVOID_UPDATE, monitor); - } catch (CoreException e) { - throw new InvocationTargetException(e); - } finally { - monitor.done(); - } - } - }); - - status = operation.getStatus(); - } catch (InvocationTargetException e) { - status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.SelectTracesWizardPage_SelectionError, e); - } catch (InterruptedException e) { - status = Status.CANCEL_STATUS; - } - if (!status.isOK()) { - if (status.getSeverity() == IStatus.CANCEL) { - setMessage(Messages.SelectTracesWizardPage_SelectionOperationCancelled); - setErrorMessage(null); - } else { - if (status.getException() != null) { - MessageDialog.open(MessageDialog.ERROR, getContainer().getShell(), - Messages.SelectTracesWizardPage_InternalErrorTitle, status.getMessage() + ": " + status.getException(), SWT.SHEET); //$NON-NLS-1$ - } - setMessage(null); - setErrorMessage(Messages.SelectTracesWizardPage_SelectionError); - } - return false; - } - setErrorMessage(null); - - return true; - } - - private class SelectTracesOperation { - - IFolder experiment = null; - TmfTraceElement[] traces; - private IStatus fStatus; - - public SelectTracesOperation(IFolder experiment, TmfTraceElement[] traces) { - this.experiment = experiment; - this.traces = traces; - } - - public void run(IProgressMonitor progressMonitor) { - - // Check if operation was cancelled. - boolean changed = false; - - // Add the selected traces to the experiment - Set keys = fPreviousTraces.keySet(); - SubMonitor subMonitor = SubMonitor.convert(progressMonitor, traces.length + keys.size()); - try { - for (TmfTraceElement trace : traces) { - ModalContext.checkCanceled(progressMonitor); - String name = trace.getElementPath(); - if (keys.contains(name)) { - subMonitor.setTaskName(Messages.SelectTracesWizardPage_TraceRemovalTask + " " + trace.getElementPath()); //$NON-NLS-1$ - fPreviousTraces.remove(name); - } else { - subMonitor.setTaskName(Messages.SelectTracesWizardPage_TraceSelectionTask + " " + trace.getElementPath()); //$NON-NLS-1$ - fExperiment.addTrace(trace, false); - changed = true; - } - subMonitor.worked(1); - } - - // Remove traces that were unchecked (thus left in - // fPreviousTraces) - keys = fPreviousTraces.keySet(); - for (String key : keys) { - ModalContext.checkCanceled(progressMonitor); - TmfTraceElement trace = fPreviousTraces.get(key); - subMonitor.setTaskName(Messages.SelectTracesWizardPage_TraceRemovalTask + " " + trace.getElementPath()); //$NON-NLS-1$ - - try { - fExperiment.removeTrace(trace); - } catch (CoreException e) { - Activator.getDefault().logError(Messages.SelectTracesWizardPage_SelectionError + " " + experiment.getName(), e); //$NON-NLS-1$ - } - changed = true; - subMonitor.worked(1); - } - if (changed) { - fExperiment.closeEditors(); - fExperiment.deleteSupplementaryResources(); - } - setStatus(Status.OK_STATUS); - } catch (InterruptedException e) { - setStatus(Status.CANCEL_STATUS); - } catch (Exception e) { - Activator.getDefault().logError(Messages.SelectTracesWizardPage_SelectionError, e); - setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.SelectTracesWizardPage_SelectionError, e)); - } - } - - /** - * Set the status for this operation - * - * @param status - * the status - */ - protected void setStatus(IStatus status) { - fStatus = status; - } - - public IStatus getStatus() { - return fStatus; - } - - } - - /** - * Get the list of selected traces - */ - private TmfTraceElement[] getSelection() { - Vector traces = new Vector<>(); - Object[] selection = fCheckboxTreeViewer.getCheckedElements(); - for (Object sel : selection) { - if (sel instanceof TmfTraceElement) { - traces.add((TmfTraceElement) sel); - } - } - TmfTraceElement[] result = new TmfTraceElement[traces.size()]; - traces.toArray(result); - return result; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/messages.properties deleted file mode 100644 index 6993dcdd98..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/messages.properties +++ /dev/null @@ -1,64 +0,0 @@ -############################################################################### -# Copyright (c) 2013, 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -# Marc-Andre Laperle - Preserve folder structure on import -############################################################################### - -# NewProjectWizard -NewProjectWizard_DialogHeader = Tracing Project -NewProjectWizard_DialogMessage = Create a Tracing Project - -# SelectTracesWizard -SelectTracesWizard_WindowTitle=Select Traces -SelectTracesWizardPage_TraceColumnHeader=Trace -SelectTracesWizardPage_WindowTitle=Select Traces -SelectTracesWizardPage_Description=Select the traces to add to the experiment -SelectTracesWizardPage_SelectionError=Error selecting traces for experiment -SelectTracesWizardPage_TraceSelectionTask=Selecting trace -SelectTracesWizardPage_TraceRemovalTask=Removing trace -SelectTracesWizardPage_SelectionOperationCancelled=Selection operation cancelled -SelectTracesWizardPage_InternalErrorTitle=Internal Error - -# Common Experiment/Trace dialog errors -Dialog_EmptyNameError = No name specified -Dialog_ExistingNameError = Name already used - -# NewExperiment dialog -NewExperimentDialog_DialogTitle = New Experiment -NewExperimentDialog_ExperimentName = Experiment name: - -# RenameExperiment dialog -RenameExperimentDialog_DialogTitle = Rename Experiment -RenameExperimentDialog_ExperimentName = Old Experiment name: -RenameExperimentDialog_ExperimentNewName = New Experiment name: - -# CopyExperiment dialog -CopyExperimentDialog_DialogTitle = Copy Experiment -CopyExperimentDialog_ExperimentName = Source Experiment name: -CopyExperimentDialog_ExperimentNewName = New Experiment name: - -# RenameTrace dialog -RenameTraceDialog_DialogTitle = Rename Trace -RenameTraceDialog_TraceName = Old Trace name: -RenameTraceDialog_TraceNewName = New Trace name: - -# CopyTrace dialog -CopyTraceDialog_DialogTitle = Copy Trace -CopyTraceDialog_TraceName = Source Trace name: -CopyTraceDialog_TraceNewName = New Trace name: - -# NewFolder dialog -NewFolderDialog_DialogTitle = New Folder -NewFolderDialog_FolderName = Folder name: - -# RenameFolder dialog -RenameFolderDialog_DialogTitle = Rename Folder -RenameFolderDialog_FolderName = Old Folder name: -RenameFolderDialog_FolderNewName = New Folder name: diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/properties/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/properties/Messages.java deleted file mode 100644 index 19ae246b0c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/properties/Messages.java +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ui.properties; - -import org.eclipse.osgi.util.NLS; - -/** - * @since 2.1 - */ -@SuppressWarnings("javadoc") -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.ui.properties.messages"; //$NON-NLS-1$ - - public static String TmfTimestampFormatPage_LocalTime; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/properties/ReadOnlyTextPropertyDescriptor.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/properties/ReadOnlyTextPropertyDescriptor.java deleted file mode 100644 index 79dbbfaeb1..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/properties/ReadOnlyTextPropertyDescriptor.java +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.properties; - -import org.eclipse.jface.viewers.CellEditor; -import org.eclipse.jface.viewers.TextCellEditor; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.views.properties.PropertyDescriptor; -import org.eclipse.ui.views.properties.TextPropertyDescriptor; - -/** - * A uneditable version of a {@link TextPropertyDescriptor}. - * - * @author Alexandre Montplaisir - * @since 2.0 - */ -public class ReadOnlyTextPropertyDescriptor extends PropertyDescriptor { - - /** - * Creates an property descriptor with the given id and display name. - * - * @param id - * The id of the property - * @param displayName - * The name to display for the property - */ - public ReadOnlyTextPropertyDescriptor(Object id, String displayName) { - super(id, displayName); - } - - @Override - public CellEditor createPropertyEditor(Composite parent) { - CellEditor editor = new TextCellEditor(parent, SWT.READ_ONLY); - if (getValidator() != null) { - editor.setValidator(getValidator()); - } - return editor; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/properties/TmfTimestampFormatPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/properties/TmfTimestampFormatPage.java deleted file mode 100644 index 5c37a23eb2..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/properties/TmfTimestampFormatPage.java +++ /dev/null @@ -1,391 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Marc-Andre Laperle - Add time zone preference - * Patrick Tasse - Updated for fraction of seconds - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.properties; - -import java.util.Map; -import java.util.TimeZone; - -import org.eclipse.jface.preference.ComboFieldEditor; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.preference.PreferencePage; -import org.eclipse.jface.preference.RadioGroupFieldEditor; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimestampFormatUpdateSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimePreferencesConstants; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimePreferences; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampFormat; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPreferencePage; - -/** - * The TMF timestamp format configuration page. This page is used to select the - * global timestamp and interval time formats (for display and parsing). The - * user can either pick a pre-defined format or enter his/her own. - * - * @version 1.0 - * @author Francois Chouinard - * @since 2.0 - */ -public class TmfTimestampFormatPage extends PreferencePage implements IWorkbenchPreferencePage, SelectionListener, IPropertyChangeListener { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - // Date and Time formats - private static final String[][] fDateTimeFormats = new String[][] { - { ITmfTimePreferencesConstants.DATE_YEAR_FMT, ITmfTimePreferencesConstants.DATE_YEAR_FMT }, - { ITmfTimePreferencesConstants.DATE_YEAR2_FMT, ITmfTimePreferencesConstants.DATE_YEAR2_FMT }, - { ITmfTimePreferencesConstants.DATE_MONTH_FMT, ITmfTimePreferencesConstants.DATE_MONTH_FMT }, - { ITmfTimePreferencesConstants.DATE_DAY_FMT, ITmfTimePreferencesConstants.DATE_DAY_FMT }, - { ITmfTimePreferencesConstants.DATE_JDAY_FMT, ITmfTimePreferencesConstants.DATE_JDAY_FMT }, - { ITmfTimePreferencesConstants.TIME_HOUR_FMT, ITmfTimePreferencesConstants.TIME_HOUR_FMT }, - { ITmfTimePreferencesConstants.TIME_MINUTE_FMT, ITmfTimePreferencesConstants.TIME_MINUTE_FMT }, - { ITmfTimePreferencesConstants.TIME_SECOND_FMT, ITmfTimePreferencesConstants.TIME_SECOND_FMT }, - { ITmfTimePreferencesConstants.TIME_ELAPSED_FMT + " (secs in epoch)", ITmfTimePreferencesConstants.TIME_ELAPSED_FMT }, //$NON-NLS-1$ - { "(none)", ITmfTimePreferencesConstants.TIME_NO_FMT }, //$NON-NLS-1$ - }; - - // Sub-second formats - private static final String[][] fSubSecondFormats = new String[][] { - { ITmfTimePreferencesConstants.SUBSEC_MILLI_FMT + " (ms)", ITmfTimePreferencesConstants.SUBSEC_MILLI_FMT }, //$NON-NLS-1$ - { ITmfTimePreferencesConstants.SUBSEC_MICRO_FMT + " (µs)", ITmfTimePreferencesConstants.SUBSEC_MICRO_FMT }, //$NON-NLS-1$ - { ITmfTimePreferencesConstants.SUBSEC_NANO_FMT + " (ns)", ITmfTimePreferencesConstants.SUBSEC_NANO_FMT }, //$NON-NLS-1$ - }; - - // Date and Time delimiters - private static final String[][] fDateTimeDelimiters = new String[][] { - { "(none)", ITmfTimePreferencesConstants.DELIMITER_NONE }, //$NON-NLS-1$ - { " (space)", ITmfTimePreferencesConstants.DELIMITER_SPACE }, //$NON-NLS-1$ - { ", (comma)", ITmfTimePreferencesConstants.DELIMITER_COMMA }, //$NON-NLS-1$ - { "- (dash)", ITmfTimePreferencesConstants.DELIMITER_DASH }, //$NON-NLS-1$ - { "_ (underline)", ITmfTimePreferencesConstants.DELIMITER_UNDERLINE }, //$NON-NLS-1$ - { ": (colon)", ITmfTimePreferencesConstants.DELIMITER_COLON }, //$NON-NLS-1$ - { "; (semicolon)", ITmfTimePreferencesConstants.DELIMITER_SEMICOLON }, //$NON-NLS-1$ - { "/ (slash)", ITmfTimePreferencesConstants.DELIMITER_SLASH }, //$NON-NLS-1$ - { "' (quote)", ITmfTimePreferencesConstants.DELIMITER_QUOTE }, //$NON-NLS-1$ - { "\" (dbl-quote)", ITmfTimePreferencesConstants.DELIMITER_DQUOT }, //$NON-NLS-1$ - }; - - // Sub-Second delimiters - private static final String[][] fSubSecondDelimiters = new String[][] { - { "(none)", ITmfTimePreferencesConstants.DELIMITER_NONE }, //$NON-NLS-1$ - { " (space)", ITmfTimePreferencesConstants.DELIMITER_SPACE }, //$NON-NLS-1$ - { ", (comma)", ITmfTimePreferencesConstants.DELIMITER_COMMA }, //$NON-NLS-1$ - { "- (dash)", ITmfTimePreferencesConstants.DELIMITER_DASH }, //$NON-NLS-1$ - { "_ (underline)", ITmfTimePreferencesConstants.DELIMITER_UNDERLINE }, //$NON-NLS-1$ - { ": (colon)", ITmfTimePreferencesConstants.DELIMITER_COLON }, //$NON-NLS-1$ - { "; (semicolon)", ITmfTimePreferencesConstants.DELIMITER_SEMICOLON }, //$NON-NLS-1$ - { "/ (slash)", ITmfTimePreferencesConstants.DELIMITER_SLASH }, //$NON-NLS-1$ - { "' (quote)", ITmfTimePreferencesConstants.DELIMITER_QUOTE }, //$NON-NLS-1$ - { "\" (dbl-quote)", ITmfTimePreferencesConstants.DELIMITER_DQUOT }, //$NON-NLS-1$ - { ". (period)", ITmfTimePreferencesConstants.DELIMITER_PERIOD }, //$NON-NLS-1$ - }; - - // Time zones - @SuppressWarnings("nls") - private static final String[] timeZones = new String[] { - Messages.TmfTimestampFormatPage_LocalTime, - "GMT-12", - "GMT-11", - "GMT-10", - "GMT-9:30", - "GMT-9", - "GMT-7", - "GMT-6", - "GMT-5", - "GMT-4", - "GMT-3:30", - "GMT-3", - "GMT-2", - "GMT-1", - "GMT", - "GMT+1", - "GMT+2", - "GMT+3", - "GMT+3:30", - "GMT+4", - "GMT+4:30", - "GMT+5", - "GMT+5:30", - "GMT+6", - "GMT+7", - "GMT+8", - "GMT+9", - "GMT+9:30", - "GMT+10", - "GMT+10:30", - "GMT+11", - "GMT+11:30", - "GMT+12", - "GMT+13:00", - "GMT+14:00" - }; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // General stuff - private Composite fPage; - private IPreferenceStore fPreferenceStore; - private TmfTimePreferences fTimePreference; - - // Example section - private Composite fExampleSection; - private Text fPatternDisplay; - private Text fExampleDisplay; - - // Timezone section - private ComboFieldEditor fCombo; - - // Date/Time format section - private RadioGroupFieldEditor fDateTimeFields; - private RadioGroupFieldEditor fSSecFields; - - // Delimiters section - private RadioGroupFieldEditor fDateFieldDelim; - private RadioGroupFieldEditor fTimeFieldDelim; - private RadioGroupFieldEditor fSSecFieldDelim; - - // IPropertyChangeListener data - private String fProperty; - private String fChangedProperty; - - private Map fPreferenceMap; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * The default constructor - */ - public TmfTimestampFormatPage() { - fPreferenceStore = getPreferenceStore(); - fTimePreference = TmfTimePreferences.getInstance(); - fPreferenceMap = fTimePreference.getPreferenceMap(); - } - - // ------------------------------------------------------------------------ - // IWorkbenchPreferencePage - // ------------------------------------------------------------------------ - - @Override - protected IPreferenceStore doGetPreferenceStore() { - return Activator.getDefault().getCorePreferenceStore(); - } - - @Override - public void init(IWorkbench workbench) { - } - - // ------------------------------------------------------------------------ - // PreferencePage - // ------------------------------------------------------------------------ - - @Override - protected Control createContents(Composite parent) { - - // Overall preference page layout - GridLayout gl = new GridLayout(); - gl.marginHeight = 0; - gl.marginWidth = 0; - parent.setLayout(gl); - fPage = new Composite(parent, SWT.NONE); - fPage.setLayout(new GridLayout()); - fPage.setLayoutData(new GridData( - GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL)); - - // Example section - fExampleSection = new Composite(fPage, SWT.NONE); - fExampleSection.setLayout(new GridLayout(2, false)); - fExampleSection.setLayoutData(new GridData(GridData.FILL_BOTH)); - - Label patternLabel = new Label(fExampleSection, SWT.HORIZONTAL); - patternLabel.setText("Current Format: "); //$NON-NLS-1$ - fPatternDisplay = new Text(fExampleSection, SWT.BORDER | SWT.READ_ONLY); - fPatternDisplay.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - Label exampleLabel = new Label(fExampleSection, SWT.NONE); - exampleLabel.setText("Sample Display: "); //$NON-NLS-1$ - fExampleDisplay = new Text(fExampleSection, SWT.BORDER | SWT.READ_ONLY); - fExampleDisplay.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - Label separator = new Label(fPage, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.SHADOW_NONE); - separator.setLayoutData( - new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL)); - - // Time Zones - String[][] timeZoneIntervals = new String[timeZones.length][2]; - timeZoneIntervals[0][0] = timeZones[0]; - timeZoneIntervals[0][1] = fPreferenceStore.getDefaultString(ITmfTimePreferencesConstants.TIME_ZONE); - for (int i = 1; i < timeZones.length; i++) { - TimeZone tz = null; - try { - tz = TimeZone.getTimeZone(timeZones[i]); - timeZoneIntervals[i][0] = tz.getDisplayName(); - timeZoneIntervals[i][1] = tz.getID(); - } catch (NullPointerException e) { - System.out.println("TimeZone " + timeZones[i] + " does not exist."); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - fCombo = new ComboFieldEditor(ITmfTimePreferencesConstants.TIME_ZONE, "Time Zone", timeZoneIntervals, fPage); //$NON-NLS-1$ - fCombo.setPreferenceStore(fPreferenceStore); - fCombo.load(); - fCombo.setPropertyChangeListener(this); - - // Date and Time section - fDateTimeFields = new RadioGroupFieldEditor( - ITmfTimePreferencesConstants.DATIME, "Date and Time format", 3, fDateTimeFormats, fPage, true); //$NON-NLS-1$ - fDateTimeFields.setPreferenceStore(fPreferenceStore); - fDateTimeFields.load(); - fDateTimeFields.setPropertyChangeListener(this); - - // Sub-second section - fSSecFields = new RadioGroupFieldEditor( - ITmfTimePreferencesConstants.SUBSEC, "Sub-second format", 3, fSubSecondFormats, fPage, true); //$NON-NLS-1$ - fSSecFields.setPreferenceStore(fPreferenceStore); - fSSecFields.load(); - fSSecFields.setPropertyChangeListener(this); - - // Separators section - fDateFieldDelim = new RadioGroupFieldEditor( - ITmfTimePreferencesConstants.DATE_DELIMITER, "Date delimiter", 5, fDateTimeDelimiters, fPage, true); //$NON-NLS-1$ - fDateFieldDelim.setPreferenceStore(fPreferenceStore); - fDateFieldDelim.load(); - fDateFieldDelim.setPropertyChangeListener(this); - - fTimeFieldDelim = new RadioGroupFieldEditor( - ITmfTimePreferencesConstants.TIME_DELIMITER, "Time delimiter", 5, fDateTimeDelimiters, fPage, true); //$NON-NLS-1$ - fTimeFieldDelim.setPreferenceStore(fPreferenceStore); - fTimeFieldDelim.load(); - fTimeFieldDelim.setPropertyChangeListener(this); - - fSSecFieldDelim = new RadioGroupFieldEditor( - ITmfTimePreferencesConstants.SSEC_DELIMITER, "Sub-Second Delimiter", 5, fSubSecondDelimiters, fPage, true); //$NON-NLS-1$ - fSSecFieldDelim.setPreferenceStore(fPreferenceStore); - fSSecFieldDelim.load(); - fSSecFieldDelim.setPropertyChangeListener(this); - - refresh(); - return fPage; - } - - @Override - protected void performDefaults() { - fDateTimeFields.loadDefault(); - fSSecFields.loadDefault(); - fDateFieldDelim.loadDefault(); - fTimeFieldDelim.loadDefault(); - fSSecFieldDelim.loadDefault(); - fCombo.loadDefault(); - - fPreferenceMap = TmfTimePreferences.getInstance().getDefaultPreferenceMap(); - displayExample(); - } - - @Override - protected void performApply() { - fDateTimeFields.store(); - fSSecFields.store(); - fDateFieldDelim.store(); - fTimeFieldDelim.store(); - fSSecFieldDelim.store(); - fCombo.store(); - - TmfTimestampFormat.updateDefaultFormats(); - TmfSignalManager.dispatchSignal(new TmfTimestampFormatUpdateSignal(null)); - displayExample(); - } - - @Override - public boolean performOk() { - performApply(); - return super.performOk(); - } - - // ------------------------------------------------------------------------ - // SelectionListener - // ------------------------------------------------------------------------ - - @Override - public void widgetSelected(SelectionEvent e) { - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - - // ------------------------------------------------------------------------ - // IPropertyChangeListener - // ------------------------------------------------------------------------ - - @Override - public void propertyChange(PropertyChangeEvent event) { - Object source = event.getSource(); - Object value = event.getNewValue(); - if (source instanceof RadioGroupFieldEditor && value instanceof String && - !(value.equals(fChangedProperty) && source == fProperty)) - { - fProperty = ((RadioGroupFieldEditor) source).getPreferenceName(); - fChangedProperty = (String) value; - refresh(); - } - } - - // ------------------------------------------------------------------------ - // Helper functions - // ------------------------------------------------------------------------ - - private void refresh() { - updatePatterns(); - displayExample(); - } - - void updatePatterns() { - if (ITmfTimePreferencesConstants.DATIME.equals(fProperty) || - ITmfTimePreferencesConstants.SUBSEC.equals(fProperty) || - ITmfTimePreferencesConstants.DATE_DELIMITER.equals(fProperty) || - ITmfTimePreferencesConstants.TIME_DELIMITER.equals(fProperty) || - ITmfTimePreferencesConstants.SSEC_DELIMITER.equals(fProperty)) { - fPreferenceMap.put(fProperty, fChangedProperty); - } - } - - private void displayExample() { - long ts = 1332170682500677380L; - String timePattern = fTimePreference.computeTimePattern(fPreferenceMap); - fPatternDisplay.setText(timePattern); - fPatternDisplay.redraw(); - - fExampleDisplay.setText(new TmfTimestampFormat(timePattern).format(ts)); - fExampleDisplay.redraw(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/properties/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/properties/messages.properties deleted file mode 100644 index 446e99854a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/properties/messages.properties +++ /dev/null @@ -1,13 +0,0 @@ -############################################################################### -# Copyright (c) 2013 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Marc-Andre Laperle - Initial API and implementation -############################################################################### - -TmfTimestampFormatPage_LocalTime=Local time diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/ArrayTreeContentProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/ArrayTreeContentProvider.java deleted file mode 100644 index f561e5301c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/ArrayTreeContentProvider.java +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers; - -import java.util.Collection; - -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; - -/** - * This implementation of ITreeContentProvider handles the case - * where the viewer input is an unchanging array or collection of elements. - * The elements do not have children. - * - * @author Patrick Tasse - * @since 3.2 - */ -public class ArrayTreeContentProvider implements ITreeContentProvider { - - @Override - public void dispose() { - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - @Override - public Object[] getChildren(Object parentElement) { - return null; - } - - @Override - public Object getParent(Object element) { - return null; - } - - @Override - public boolean hasChildren(Object element) { - return false; - } - - @Override - public Object[] getElements(Object inputElement) { - if (inputElement instanceof Object[]) { - return (Object[]) inputElement; - } - if (inputElement instanceof Collection) { - return ((Collection) inputElement).toArray(); - } - return new Object[0]; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/ITmfTimeProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/ITmfTimeProvider.java deleted file mode 100644 index 39c9420b27..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/ITmfTimeProvider.java +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation in ITmfChartTimeProvider - * Geneviève Bastien - Moved methods from ITmfChartTimeProvider to this interface - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers; - -/** - * Interface for providing and updating time information. This is typically - * implemented by a viewer that is displaying trace data over time. - * - * @author Bernd Hufmann - * @author Geneviève Bastien - * @since 3.0 - */ -public interface ITmfTimeProvider extends ITmfViewer { - - /** - * Gets the start time of trace - * - * @return start time of trace - */ - long getStartTime(); - - /** - * Gets the end time of trace - * - * @return End time of trace - */ - long getEndTime(); - - /** - * Gets the start time of current time range displayed - * - * @return start time of current time range - */ - long getWindowStartTime(); - - /** - * Gets the end time of current time range displayed - * - * @return End time of current time range - */ - long getWindowEndTime(); - - /** - * Gets the duration of the current time range displayed - * - * @return duration of current time range - */ - long getWindowDuration(); - - /** - * Gets the begin time of the selected range - * - * @return the begin time of the selected range - */ - long getSelectionBeginTime(); - - /** - * Gets the end time of the selected range - * - * @return end time of the selected range - */ - long getSelectionEndTime(); - - /** - * Method to notify about a change of the current selected time. - * - * @param currentBeginTime - * The current selection begin time - * @param currentEndTime - * The current selection end time - */ - void updateSelectionRange(long currentBeginTime, long currentEndTime); - - /** - * Updates the current time range window. - * - * @param windowStartTime - * The window start time - * @param windowEndTime - * The window end time. - */ - void updateWindow(long windowStartTime, long windowEndTime); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/ITmfViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/ITmfViewer.java deleted file mode 100644 index f9e5ba7f9a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/ITmfViewer.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers; - -import org.eclipse.linuxtools.tmf.core.component.ITmfComponent; -import org.eclipse.swt.widgets.Control; - -/** - * Interface to viewers. - * - * Viewers are to be put into views which need to know how to refresh the - * viewer's contents. - * - * @author Mathieu Denis - * @version 2.0 - * @since 2.0 - */ -public interface ITmfViewer extends ITmfComponent { - - /** - * Returns the primary control associated with this viewer. - * - * @return the SWT control which displays this viewer's contents - */ - Control getControl(); - - /** - * Tells the viewer to refresh its contents. - */ - void refresh(); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/TmfTimeViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/TmfTimeViewer.java deleted file mode 100644 index 63915c89ba..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/TmfTimeViewer.java +++ /dev/null @@ -1,442 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation in TmfXYChartViewer - * Geneviève Bastien - Moved methods from TmfXYChartViewer to this interface - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers; - -import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalThrottler; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.swt.widgets.Composite; - -/** - * Abstract class that extends {@link TmfViewer} that adds methods to - * synchronize with a trace's time information. - * - * This class will be extended by viewers who require time information to update - * their content. - * - *

- * It provides three times of data:
- *   - start and end time of the trace (available)
- *   - start, end and duration of the current time window, ie the visible time range
- *   - start and end of the time range selected
- * 
- * - * @author Bernd Hufmann - * @author Geneviève Bastien - * @since 3.0 - */ -public abstract class TmfTimeViewer extends TmfViewer implements ITmfTimeProvider { - - /** Start time of trace */ - private long fStartTime; - /** End time of trace */ - private long fEndTime; - /** Start time of current time range */ - private long fWindowStartTime; - /** End time of current time range */ - private long fWindowEndTime; - /** Duration of current time range */ - private long fWindowDuration; - /** Current begin time of selection range */ - private long fSelectionBeginTime; - /** Current end of selection range */ - private long fSelectionEndTime; - /** The trace that is displayed by this viewer */ - private ITmfTrace fTrace; - /** A signal throttler for range updates */ - private final TmfSignalThrottler fTimeRangeSyncThrottle = new TmfSignalThrottler(this, 200); - - /** - * Default constructor. - */ - public TmfTimeViewer() { - super(); - } - - /** - * Constructor that initializes the parent of the viewer - * - * @param parent - * The parent composite that holds this viewer - */ - public TmfTimeViewer(Composite parent) { - this(parent, ""); //$NON-NLS-1$ - } - - /** - * Constructor that initializes the parent of the viewer and that sets the - * name of the viewer - * - * @param parent - * The parent composite that holds this viewer - * @param name - * The name of the viewer - */ - public TmfTimeViewer(Composite parent, String name) { - init(parent, name); - } - - // ------------------------------------------------------------------------ - // Getter/Setters - // ------------------------------------------------------------------------ - - /** - * Sets the start time of the trace - * - * @param startTime - * The start time to set - */ - protected void setStartTime(long startTime) { - fStartTime = startTime; - } - - /** - * Sets the end time of the trace - * - * @param endTime - * The start time to set - */ - protected void setEndTime(long endTime) { - fEndTime = endTime; - } - - /** - * Sets the start time of the current time range window (visible range) - * - * @param windowStartTime - * The start time to set - */ - protected void setWindowStartTime(long windowStartTime) { - fWindowStartTime = windowStartTime; - } - - /** - * Sets the end time of the current time range window (visible range) - * - * @param windowEndTime - * The start time to set - */ - protected void setWindowEndTime(long windowEndTime) { - fWindowEndTime = windowEndTime; - } - - /** - * Sets the duration of the current time range window (visible range) - * - * @param windowDuration - * The window duration - */ - protected void setWindowDuration(long windowDuration) { - fWindowDuration = windowDuration; - } - - /** - * Sets the begin time of the selected range. - * - * @param selectionBeginTime - * The begin time to set - */ - protected void setSelectionBeginTime(long selectionBeginTime) { - fSelectionBeginTime = selectionBeginTime; - } - - /** - * Sets the end time of the selected range. - * - * @param selectionEndTime - * The end time to set - */ - protected void setSelectionEndTime(long selectionEndTime) { - fSelectionEndTime = selectionEndTime; - } - - /** - * Sets the trace that is displayed by this viewer. - * - * @param trace - * The trace to set - */ - protected void setTrace(ITmfTrace trace) { - fTrace = trace; - } - - /** - * Gets the trace that is displayed by this viewer. - * - * @return the trace - */ - protected ITmfTrace getTrace() { - return fTrace; - } - - // ------------------------------------------------------------------------ - // ITmfTimeProvider - // ------------------------------------------------------------------------ - - @Override - public long getStartTime() { - return fStartTime; - } - - @Override - public long getEndTime() { - return fEndTime; - } - - @Override - public long getWindowStartTime() { - return fWindowStartTime; - } - - @Override - public long getWindowEndTime() { - return fWindowEndTime; - } - - @Override - public long getWindowDuration() { - return fWindowDuration; - } - - @Override - public long getSelectionBeginTime() { - return fSelectionBeginTime; - } - - @Override - public long getSelectionEndTime() { - return fSelectionEndTime; - } - - @Override - public void updateSelectionRange(final long currentBeginTime, final long currentEndTime) { - if (fTrace != null) { - setSelectionBeginTime(currentBeginTime); - setSelectionEndTime(currentEndTime); - - final ITmfTimestamp startTimestamp = new TmfTimestamp(getSelectionBeginTime(), ITmfTimestamp.NANOSECOND_SCALE); - final ITmfTimestamp endTimestamp = new TmfTimestamp(getSelectionEndTime(), ITmfTimestamp.NANOSECOND_SCALE); - - TmfTimeSynchSignal signal = new TmfTimeSynchSignal(this, startTimestamp, endTimestamp); - broadcast(signal); - } - } - - @Override - public void updateWindow(long windowStartTime, long windowEndTime) { - - setWindowStartTime(windowStartTime); - setWindowEndTime(windowEndTime); - setWindowDuration(windowEndTime - windowStartTime); - - // Build the new time range; keep the current time - TmfTimeRange timeRange = new TmfTimeRange( - new TmfTimestamp(getWindowStartTime(), ITmfTimestamp.NANOSECOND_SCALE), - new TmfTimestamp(getWindowEndTime(), ITmfTimestamp.NANOSECOND_SCALE)); - - // Send the signal - TmfRangeSynchSignal signal = new TmfRangeSynchSignal(this, timeRange); - fTimeRangeSyncThrottle.queue(signal); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - /** - * A Method to load a trace into the viewer. - * - * @param trace - * A trace to apply in the viewer - */ - public void loadTrace(ITmfTrace trace) { - fTrace = trace; - - long timestamp = TmfTraceManager.getInstance().getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - TmfTimeRange currentRange = TmfTraceManager.getInstance().getCurrentRange(); - long windowStartTime = currentRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - long windowEndTime = currentRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - long windowDuration = windowEndTime - windowStartTime; - long startTime = fTrace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - long endTime = fTrace.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - - setSelectionBeginTime(timestamp); - setSelectionEndTime(timestamp); - setStartTime(startTime); - setWindowStartTime(windowStartTime); - setWindowEndTime(windowEndTime); - setWindowDuration(windowDuration); - setEndTime(endTime); - } - - /** - * Resets the content of the viewer - */ - public void reset() { - // Reset the internal data - setSelectionBeginTime(0); - setSelectionEndTime(0); - setStartTime(0); - setWindowStartTime(0); - setWindowDuration(0); - setEndTime(0); - setWindowEndTime(0); - setTrace(null); - } - - // ------------------------------------------------------------------------ - // Signal Handler - // ------------------------------------------------------------------------ - - /** - * Signal handler for handling of the trace opened signal. - * - * @param signal - * The trace opened signal {@link TmfTraceOpenedSignal} - */ - @TmfSignalHandler - public void traceOpened(TmfTraceOpenedSignal signal) { - fTrace = signal.getTrace(); - loadTrace(getTrace()); - } - - /** - * Signal handler for handling of the trace selected signal. - * - * @param signal - * The trace selected signal {@link TmfTraceSelectedSignal} - */ - @TmfSignalHandler - public void traceSelected(TmfTraceSelectedSignal signal) { - if (fTrace != signal.getTrace()) { - fTrace = signal.getTrace(); - loadTrace(getTrace()); - } - } - - /** - * Signal handler for handling of the trace closed signal. - * - * @param signal - * The trace closed signal {@link TmfTraceClosedSignal} - */ - @TmfSignalHandler - public void traceClosed(TmfTraceClosedSignal signal) { - - if (signal.getTrace() != fTrace) { - return; - } - - // Reset the internal data - fTrace = null; - reset(); - } - - /** - * Signal handler for handling of the time synch signal, ie the selected range. - * - * @param signal - * The time synch signal {@link TmfTimeSynchSignal} - */ - @TmfSignalHandler - public void selectionRangeUpdated(TmfTimeSynchSignal signal) { - if ((signal.getSource() != this) && (fTrace != null)) { - ITmfTimestamp selectedTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE); - ITmfTimestamp selectedEndTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE); - setSelectionBeginTime(selectedTime.getValue()); - setSelectionEndTime(selectedEndTime.getValue()); - } - } - - /** - * Signal handler for handling of the time range synch signal, ie the visible range. - * - * @param signal - * The time range synch signal {@link TmfRangeSynchSignal} - */ - @TmfSignalHandler - public void timeRangeUpdated(TmfRangeSynchSignal signal) { - - if (fTrace != null) { - // Validate the time range - TmfTimeRange range = signal.getCurrentRange().getIntersection(fTrace.getTimeRange()); - if (range == null) { - return; - } - - if (signal.getSource() != this) { - // Update the time range - long windowStartTime = range.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - long windowEndTime = range.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - long windowDuration = windowEndTime - windowStartTime; - - setWindowStartTime(windowStartTime); - setWindowEndTime(windowEndTime); - setWindowDuration(windowDuration); - } - } - } - - /** - * Signal handler for handling of the trace range updated signal. - * - * @param signal - * The trace range signal {@link TmfTraceRangeUpdatedSignal} - */ - @TmfSignalHandler - public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal) { - - if (signal.getTrace() != fTrace) { - return; - } - - TmfTimeRange fullRange = signal.getRange(); - - long traceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - long traceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - - setStartTime(traceStartTime); - setEndTime(traceEndTime); - } - - /** - * Signal handler for handling of the trace updated signal. - * - * @param signal - * The trace updated signal {@link TmfTraceUpdatedSignal} - */ - @TmfSignalHandler - public void traceUpdated(TmfTraceUpdatedSignal signal) { - if (signal.getTrace() != fTrace) { - return; - } - TmfTimeRange fullRange = signal.getTrace().getTimeRange(); - long traceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - long traceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - - setStartTime(traceStartTime); - setEndTime(traceEndTime); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/TmfViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/TmfViewer.java deleted file mode 100644 index 82fea075ef..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/TmfViewer.java +++ /dev/null @@ -1,88 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers; - -import org.eclipse.linuxtools.tmf.core.component.TmfComponent; -import org.eclipse.swt.widgets.Composite; - -/** - * Abstract class that extends {@link TmfComponent} to be specific to viewers. - * - * It allows the access to the control and the parent of a viewer. - * - * @author Mathieu Denis - * @version 2.0 - * @since 2.0 - */ -public abstract class TmfViewer extends TmfComponent implements ITmfViewer { - - /** - * The parent composite that holds the viewer - */ - protected Composite fParent; - - /** - * Default constructor. The viewer have to be initialize through the - * {@link TmfViewer#init(Composite, String)} function later on. - */ - public TmfViewer() { - super(); - } - - /** - * Constructor that initializes the parent of the viewer - * - * @param parent - * The parent composite that holds this viewer - * - * @see TmfComponent#TmfComponent(String) - */ - public TmfViewer(Composite parent) { - this(parent, ""); //$NON-NLS-1$ - } - - /** - * Constructor that initializes the parent of the viewer and that sets the - * name of the viewer - * - * @param parent - * The parent composite that holds this viewer - * @param name - * The name of the viewer - */ - public TmfViewer(Composite parent, String name) { - init(parent, name); - } - - /** - * Performs initialization of the viewer. It initializes the component. Need - * to be called when the default constructor is used. - * - * @param parent - * The parent composite of the viewer - * @param name - * The name to give to this viewer - * @see TmfComponent#init(String) - */ - public void init(Composite parent, String name) { - super.init(name); - fParent = parent; - } - - /** - * @return the parent of this viewer - */ - public Composite getParent() { - return fParent; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventAdapterFactory.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventAdapterFactory.java deleted file mode 100644 index 05157b7b53..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventAdapterFactory.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc-Andre Laperle - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ui.viewers.events; - -import org.eclipse.core.runtime.IAdapterFactory; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.ui.views.properties.IPropertySource; - -/** - * Implements basic UI support for TMF events. - * - * @since 2.0 - */ -public class TmfEventAdapterFactory implements IAdapterFactory { - - private static Class[] PROPERTIES = new Class[] { - IPropertySource.class - }; - - @Override - public Class[] getAdapterList() { - return PROPERTIES; - } - - @Override - public Object getAdapter(Object element, Class key) { - ITmfEvent tmfEvent = (ITmfEvent) element; - if (IPropertySource.class.equals(key)) { - return new TmfEventPropertySource(tmfEvent); - } - return null; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventPropertySource.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventPropertySource.java deleted file mode 100644 index cb62632a46..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventPropertySource.java +++ /dev/null @@ -1,355 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Bernd Hufmann - Added call site and model URI properties - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.events; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.event.ITmfCustomAttributes; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.lookup.ITmfModelLookup; -import org.eclipse.linuxtools.tmf.core.event.lookup.ITmfSourceLookup; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; -import org.eclipse.ui.views.properties.IPropertyDescriptor; -import org.eclipse.ui.views.properties.IPropertySource; - -/** - * Property source for events - * - * @since 2.0 - */ -public class TmfEventPropertySource implements IPropertySource { - - private static final String ID_TIMESTAMP = "event_timestamp"; //$NON-NLS-1$ - private static final String ID_SOURCE = "event_source"; //$NON-NLS-1$ - private static final String ID_TYPE = "event_type"; //$NON-NLS-1$ - private static final String ID_REFERENCE = "event_reference"; //$NON-NLS-1$ - private static final String ID_TRACE = "trace_attribute"; //$NON-NLS-1$ - private static final String ID_CONTENT = "event_content"; //$NON-NLS-1$ - private static final String ID_SOURCE_LOOKUP = "event_lookup"; //$NON-NLS-1$ - private static final String ID_MODEL_URI = "model_uri"; //$NON-NLS-1$ - private static final String ID_CUSTOM_ATTRIBUTE = "custom_attribute"; //$NON-NLS-1$ - - private static final String NAME_TIMESTAMP = "Timestamp"; //$NON-NLS-1$ - private static final String NAME_SOURCE = "Source"; //$NON-NLS-1$ - private static final String NAME_TYPE = "Type"; //$NON-NLS-1$ - private static final String NAME_REFERENCE = "Reference"; //$NON-NLS-1$ - private static final String NAME_TRACE = "Trace"; //$NON-NLS-1$ - private static final String NAME_CONTENT = "Content"; //$NON-NLS-1$ - private static final String NAME_SOURCE_LOOKUP = "Source Lookup"; //$NON-NLS-1$ - private static final String NAME_MODEL_URI = "Model URI"; //$NON-NLS-1$ - private static final String NAME_CUSTOM_ATTRIBUTES = "Custom Attributes"; //$NON-NLS-1$ - - private static final String EMPTY_STRING = ""; //$NON-NLS-1$ - - private ITmfEvent fEvent; - - private class TimestampPropertySource implements IPropertySource { - private static final String ID_TIMESTAMP_VALUE = "timestamp_value"; //$NON-NLS-1$ - private static final String ID_TIMESTAMP_SCALE = "timestamp_scale"; //$NON-NLS-1$ - private static final String ID_TIMESTAMP_PRECISION = "timestamp_precision"; //$NON-NLS-1$ - private static final String NAME_TIMESTAMP_VALUE = "value"; //$NON-NLS-1$ - private static final String NAME_TIMESTAMP_SCALE = "scale"; //$NON-NLS-1$ - private static final String NAME_TIMESTAMP_PRECISION = "precision"; //$NON-NLS-1$ - - private ITmfTimestamp fTimestamp; - - public TimestampPropertySource(ITmfTimestamp timestamp) { - fTimestamp = timestamp; - } - - @Override - public Object getEditableValue() { - return fTimestamp.toString(); - } - - @Override - public IPropertyDescriptor[] getPropertyDescriptors() { - IPropertyDescriptor[] descriptors = new IPropertyDescriptor[3]; - descriptors[0] = new ReadOnlyTextPropertyDescriptor(ID_TIMESTAMP_VALUE, NAME_TIMESTAMP_VALUE); - descriptors[1] = new ReadOnlyTextPropertyDescriptor(ID_TIMESTAMP_SCALE, NAME_TIMESTAMP_SCALE); - descriptors[2] = new ReadOnlyTextPropertyDescriptor(ID_TIMESTAMP_PRECISION, NAME_TIMESTAMP_PRECISION); - return descriptors; - } - - @Override - public Object getPropertyValue(Object id) { - if (id.equals(ID_TIMESTAMP_VALUE)) { - return Long.toString(fTimestamp.getValue()); - } else if (id.equals(ID_TIMESTAMP_SCALE)) { - return Integer.toString(fTimestamp.getScale()); - } else if (id.equals(ID_TIMESTAMP_PRECISION)) { - return Integer.toString(fTimestamp.getPrecision()); - } - return null; - } - - @Override - public boolean isPropertySet(Object id) { - return false; - } - - @Override - public void resetPropertyValue(Object id) { - } - - @Override - public void setPropertyValue(Object id, Object value) { - } - } - - private class ContentPropertySource implements IPropertySource { - private ITmfEventField fContent; - - public ContentPropertySource(ITmfEventField content) { - fContent = content; - } - - @Override - public Object getEditableValue() { - return fContent.toString(); - } - - @Override - public IPropertyDescriptor[] getPropertyDescriptors() { - List descriptors = new ArrayList<>(fContent.getFields().size()); - for (ITmfEventField field : fContent.getFields()) { - if (field != null) { - descriptors.add(new ReadOnlyTextPropertyDescriptor(field, field.getName())); - } - } - return descriptors.toArray(new IPropertyDescriptor[0]); - } - - @Override - public Object getPropertyValue(Object id) { - ITmfEventField field = (ITmfEventField) id; - if (field.getFields() != null && field.getFields().size() > 0) { - return new ContentPropertySource(field); - } - return field.getFormattedValue(); - } - - @Override - public boolean isPropertySet(Object id) { - return false; - } - - @Override - public void resetPropertyValue(Object id) { - } - - @Override - public void setPropertyValue(Object id, Object value) { - } - } - - private class SourceLookupPropertySource implements IPropertySource { - - private static final String ID_FILE_NAME = "callsite_file"; //$NON-NLS-1$ - private static final String ID_FUNCTION_NAME = "callsite_function"; //$NON-NLS-1$ - private static final String ID_LINE_NUMBER = "callsite_line"; //$NON-NLS-1$ - - private static final String NAME_FILE_NAME = "File"; //$NON-NLS-1$ - private static final String NAME_FUNCTION_NAME = "Function"; //$NON-NLS-1$ - private static final String NAME_LINE_NUMBER = "Line"; //$NON-NLS-1$ - - final private ITmfSourceLookup fSourceLookup; - - public SourceLookupPropertySource(ITmfSourceLookup lookup) { - fSourceLookup = lookup; - } - - @Override - public Object getEditableValue() { - if (fSourceLookup.getCallsite() != null) { - return fSourceLookup.getCallsite().toString(); - } - return null; - } - - @Override - public IPropertyDescriptor[] getPropertyDescriptors() { - List descriptors= new ArrayList<>(); - if (fSourceLookup.getCallsite() != null) { - descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_FILE_NAME, NAME_FILE_NAME)); - descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_LINE_NUMBER, NAME_LINE_NUMBER)); - // only display function if available - if (fSourceLookup.getCallsite().getFunctionName() != null) { - descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_FUNCTION_NAME, NAME_FUNCTION_NAME)); - } - } - return descriptors.toArray(new IPropertyDescriptor[0]); - } - - @Override - public Object getPropertyValue(Object id) { - if (id.equals(ID_FILE_NAME)) { - return fSourceLookup.getCallsite().getFileName(); - } else if (id.equals(ID_FUNCTION_NAME)) { - return fSourceLookup.getCallsite().getFunctionName(); - } else if (id.equals(ID_LINE_NUMBER)) { - return Long.valueOf(fSourceLookup.getCallsite().getLineNumber()); - } - return null; - } - - @Override - public boolean isPropertySet(Object id) { - return false; - } - - @Override - public void resetPropertyValue(Object id) { - - } - - @Override - public void setPropertyValue(Object id, Object value) { - } - } - - private class CustomAttributePropertySource implements IPropertySource { - - private final ITmfCustomAttributes event; - - public CustomAttributePropertySource(ITmfCustomAttributes event) { - this.event = event; - } - - @Override - public Object getEditableValue() { - return EMPTY_STRING; - } - - @Override - public IPropertyDescriptor[] getPropertyDescriptors() { - List descriptors = new ArrayList<>(); - - for (String customAttribute : event.listCustomAttributes()) { - descriptors.add(new ReadOnlyTextPropertyDescriptor(customAttribute, customAttribute)); - } - - return descriptors.toArray(new IPropertyDescriptor[0]); - } - - @Override - public Object getPropertyValue(Object id) { - return event.getCustomAttribute((String) id); - } - - @Override - public boolean isPropertySet(Object id) { - return false; - } - - @Override - public void resetPropertyValue(Object id) { - } - - @Override - public void setPropertyValue(Object id, Object value) { - } - } - - /** - * Default constructor - * - * @param event the event - */ - public TmfEventPropertySource(ITmfEvent event) { - super(); - this.fEvent = event; - } - - @Override - public Object getEditableValue() { - return null; - } - - @Override - public IPropertyDescriptor[] getPropertyDescriptors() { - List descriptors= new ArrayList<>(); - - /* Display basic event information */ - descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_TIMESTAMP, NAME_TIMESTAMP)); - descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_SOURCE, NAME_SOURCE)); - descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_TYPE, NAME_TYPE)); - descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_REFERENCE, NAME_REFERENCE)); - descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_TRACE, NAME_TRACE)); - - /* Display event fields */ - descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_CONTENT, NAME_CONTENT)); - - /* Display source lookup information, if the event supplies it */ - if ((fEvent instanceof ITmfSourceLookup) && (((ITmfSourceLookup)fEvent).getCallsite() != null)) { - descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_SOURCE_LOOKUP, NAME_SOURCE_LOOKUP)); - } - - /* Display Model URI information, if the event supplies it */ - if ((fEvent instanceof ITmfModelLookup) && (((ITmfModelLookup) fEvent).getModelUri() != null)) { - descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_MODEL_URI, NAME_MODEL_URI)); - } - - /* Display custom attributes, if available */ - if (fEvent instanceof ITmfCustomAttributes) { - ITmfCustomAttributes event = (ITmfCustomAttributes) fEvent; - if (event.listCustomAttributes() != null && !event.listCustomAttributes().isEmpty()) { - descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_CUSTOM_ATTRIBUTE, NAME_CUSTOM_ATTRIBUTES)); - } - } - - return descriptors.toArray(new IPropertyDescriptor[0]); - } - - @Override - public Object getPropertyValue(Object id) { - if (id.equals(ID_TIMESTAMP) && fEvent.getTimestamp() != null) { - return new TimestampPropertySource(fEvent.getTimestamp()); - } else if (id.equals(ID_SOURCE) && fEvent.getSource() != null) { - return fEvent.getSource().toString(); - } else if (id.equals(ID_TYPE) && fEvent.getType() != null) { - return fEvent.getType().toString(); - } else if (id.equals(ID_REFERENCE) && fEvent.getReference() != null) { - return fEvent.getReference().toString(); - } else if (id.equals(ID_TRACE) && fEvent.getTrace() != null) { - return fEvent.getTrace().getName(); - } else if (id.equals(ID_MODEL_URI)) { - return ((ITmfModelLookup)fEvent).getModelUri(); - } else if (id.equals(ID_SOURCE_LOOKUP)) { - return new SourceLookupPropertySource(((ITmfSourceLookup)fEvent)); - } else if (id.equals(ID_CONTENT) && fEvent.getContent() != null) { - return new ContentPropertySource(fEvent.getContent()); - } else if (id.equals(ID_CUSTOM_ATTRIBUTE)) { - return new CustomAttributePropertySource((ITmfCustomAttributes) fEvent); - } - return null; - } - - @Override - public boolean isPropertySet(Object id) { - return false; - } - - @Override - public void resetPropertyValue(Object id) { - } - - @Override - public void setPropertyValue(Object id, Object value) { - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventsCache.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventsCache.java deleted file mode 100644 index 21a4b40d6a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventsCache.java +++ /dev/null @@ -1,489 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Bernd Hufmann - Add support for event collapsing - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.events; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.linuxtools.internal.tmf.core.filter.TmfCollapseFilter; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.component.ITmfEventProvider; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.core.filter.ITmfFilter; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; - -/** - * The generic TMF Events table events cache - * - * This can help avoid re-reading the trace when the user scrolls a window, - * for example. - * - * @author Patrick Tasse - */ -public class TmfEventsCache { - - /** - * The generic TMF Events table cached event. - * - * @author Patrick Tasse - */ - public static class CachedEvent implements ITmfEvent { - /** - * Event reference. - * - * When {@link TmfCollapseFilter} is active then it's event reference - * of the first event of repeated events. - */ - ITmfEvent event; - /** - * Events rank. - * - * When {@link TmfCollapseFilter} is active then it's event rank of the - * first event of repeated events. - */ - long rank; - /** - * Number times event is repeated. Updated by using {@link TmfCollapseFilter} - */ - long repeatCount; - - /** - * Constructor for new cached events. - * - * @param iTmfEvent - * The original trace event - * @param rank - * The rank of this event in the trace - */ - public CachedEvent (ITmfEvent iTmfEvent, long rank) { - this.event = iTmfEvent; - this.rank = rank; - } - /** - * @since 3.2 - */ - @Override - public Object getAdapter(Class adapter) { - return event.getAdapter(adapter); - } - /** - * @since 3.2 - */ - @Override - public ITmfTrace getTrace() { - return event.getTrace(); - } - /** - * @since 3.2 - */ - @Override - public long getRank() { - return event.getRank(); - } - /** - * @since 3.2 - */ - @Override - public ITmfTimestamp getTimestamp() { - return event.getTimestamp(); - } - /** - * @since 3.2 - */ - @Override - public String getSource() { - return event.getSource(); - } - /** - * @since 3.2 - */ - @Override - public ITmfEventType getType() { - return event.getType(); - } - /** - * @since 3.2 - */ - @Override - public ITmfEventField getContent() { - return event.getContent(); - } - /** - * @since 3.2 - */ - @Override - public String getReference() { - return event.getReference(); - } - } - - private final CachedEvent[] fCache; - private final int fCacheSize; - private int fCacheStartIndex = 0; - private int fCacheEndIndex = 0; - - private ITmfTrace fTrace; - private final TmfEventsTable fTable; - private ITmfFilter fFilter; - private final List fFilterIndex = new ArrayList<>(); // contains the event rank at each 'cache size' filtered events - - /** - * Constructor for the event cache - * - * @param cacheSize - * The size of the cache, in number of events - * @param table - * The Events table this cache will cover - */ - public TmfEventsCache(int cacheSize, TmfEventsTable table) { - fCacheSize = cacheSize; - fCache = new CachedEvent[cacheSize * 2]; // the cache holds two blocks of cache size - fTable = table; - } - - /** - * Assign a new trace to this events cache. This clears the current - * contents. - * - * @param trace - * The trace to assign. - */ - public void setTrace(ITmfTrace trace) { - fTrace = trace; - clear(); - } - - /** - * Clear the current contents of this cache. - */ - public synchronized void clear() { - if (job != null && job.getState() != Job.NONE) { - job.cancel(); - } - Arrays.fill(fCache, null); - fCacheStartIndex = 0; - fCacheEndIndex = 0; - fFilterIndex.clear(); - } - - /** - * Apply a filter on this event cache. This clears the current cache - * contents. - * - * @param filter - * The ITmfFilter to apply. - */ - public void applyFilter(ITmfFilter filter) { - fFilter = filter; - clear(); - } - - /** - * Clear the current filter on this cache. This also clears the current - * cache contents. - */ - public void clearFilter() { - fFilter = null; - clear(); - } - - /** - * Get an event from the cache. If the cache does not contain the event, - * a cache population request is triggered. - * - * @param index - * The index of this event in the cache - * @return The cached event, or 'null' if the event is not in the cache - */ - public synchronized CachedEvent getEvent(int index) { - if ((index >= fCacheStartIndex) && (index < fCacheEndIndex)) { - int i = index - fCacheStartIndex; - return fCache[i]; - } - populateCache(index); - return null; - } - - /** - * Peek an event in the cache. Does not trigger cache population. - * - * @param index - * Index of the event to peek - * @return The cached event, or 'null' if the event is not in the cache - */ - public synchronized CachedEvent peekEvent(int index) { - if ((index >= fCacheStartIndex) && (index < fCacheEndIndex)) { - int i = index - fCacheStartIndex; - return fCache[i]; - } - return null; - } - - /** - * Add a trace event to the cache. - * - * @param event - * The original trace event to be cached - * @param rank - * The rank of this event in the trace - * @param index - * The index this event will occupy in the cache - */ - public synchronized void storeEvent(ITmfEvent event, long rank, int index) { - if (index == fCacheEndIndex) { - int i = index - fCacheStartIndex; - if (i < fCache.length) { - fCache[i] = new CachedEvent(event, rank); - fCacheEndIndex++; - } - } - if ((fFilter != null) && ((index % fCacheSize) == 0)) { - int i = index / fCacheSize; - fFilterIndex.add(i, Integer.valueOf((int) rank)); - } - } - - /** - * Update event repeat count at index - * - * @param index - * The index this event occupies in the cache - * - * @since 3.2 - */ - public synchronized void updateCollapsedEvent(int index) { - int i = index - fCacheStartIndex; - if (i < fCache.length) { - fCache[i].repeatCount++; - } - } - - /** - * Get the cache index of an event from his rank in the trace. This will - * take in consideration any filter that might be applied. - * - * @param rank - * The rank of the event in the trace - * @return The position (index) this event should use once cached - */ - public int getFilteredEventIndex(final long rank) { - int current; - int startRank; - TmfEventRequest request; - final ITmfFilter filter = fFilter; - synchronized (this) { - int start = 0; - int end = fFilterIndex.size(); - - if ((fCacheEndIndex - fCacheStartIndex) > 1) { - if (rank < fCache[0].rank) { - end = (fCacheStartIndex / fCacheSize) + 1; - } else if (rank > fCache[fCacheEndIndex - fCacheStartIndex - 1].rank) { - start = fCacheEndIndex / fCacheSize; - } else { - for (int i = 0; i < (fCacheEndIndex - fCacheStartIndex); i++) { - if (fCache[i].rank >= rank) { - return fCacheStartIndex + i; - } - } - return fCacheEndIndex; - } - } - - current = (start + end) / 2; - while (current != start) { - if (rank < fFilterIndex.get(current)) { - end = current; - current = (start + end) / 2; - } else { - start = current; - current = (start + end) / 2; - } - } - startRank = fFilterIndex.size() > 0 ? fFilterIndex.get(current) : 0; - } - - final int index = current * fCacheSize; - - class DataRequest extends TmfEventRequest { - ITmfFilter requestFilter; - int requestRank; - int requestIndex; - - DataRequest(Class dataType, ITmfFilter reqFilter, int start, int nbRequested) { - super(dataType, TmfTimeRange.ETERNITY, start, nbRequested, - TmfEventRequest.ExecutionType.FOREGROUND); - requestFilter = reqFilter; - requestRank = start; - requestIndex = index; - } - - @Override - public void handleData(ITmfEvent event) { - super.handleData(event); - if (isCancelled()) { - return; - } - if (requestRank >= rank) { - cancel(); - return; - } - requestRank++; - if (requestFilter.matches(event)) { - requestIndex++; - } - } - - public int getFilteredIndex() { - return requestIndex; - } - } - - request = new DataRequest(ITmfEvent.class, filter, startRank, ITmfEventRequest.ALL_DATA); - ((ITmfEventProvider) fTrace).sendRequest(request); - try { - request.waitForCompletion(); - return ((DataRequest) request).getFilteredIndex(); - } catch (InterruptedException e) { - Activator.getDefault().logError("Filter request interrupted!", e); //$NON-NLS-1$ - } - return 0; - } - - // ------------------------------------------------------------------------ - // Event cache population - // ------------------------------------------------------------------------ - - // The event fetching job - private Job job; - private synchronized void populateCache(final int index) { - - /* Check if the current job will fetch the requested event: - * 1. The job must exist - * 2. It must be running (i.e. not completed) - * 3. The requested index must be within the cache range - * - * If the job meets these conditions, we simply exit. - * Otherwise, we create a new job but we might have to cancel - * an existing job for an obsolete range. - */ - if (job != null) { - if (job.getState() != Job.NONE) { - if ((index >= fCacheStartIndex) && (index < (fCacheStartIndex + fCache.length))) { - return; - } - // The new index is out of the requested range - // Kill the job and start a new one - job.cancel(); - } - } - - // Populate the cache starting at the index that is one block less - // of cache size than the requested index. The cache will hold two - // consecutive blocks of cache size, centered on the requested index. - fCacheStartIndex = Math.max(0, index - fCacheSize); - fCacheEndIndex = fCacheStartIndex; - - job = new Job("Fetching Events") { //$NON-NLS-1$ - private int startIndex = fCacheStartIndex; - private int skipCount = 0; - @Override - protected IStatus run(final IProgressMonitor monitor) { - - int nbRequested; - if (fFilter == null) { - nbRequested = fCache.length; - } else { - nbRequested = ITmfEventRequest.ALL_DATA; - int i = startIndex / fCacheSize; - if (i < fFilterIndex.size()) { - skipCount = startIndex - (i * fCacheSize); - startIndex = fFilterIndex.get(i); - } - } - - TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, - TmfTimeRange.ETERNITY, - startIndex, - nbRequested, - TmfEventRequest.ExecutionType.FOREGROUND) { - private int count = 0; - private long rank = startIndex; - @Override - public void handleData(ITmfEvent event) { - // If the job is canceled, cancel the request so waitForCompletion() will unlock - if (monitor.isCanceled()) { - cancel(); - return; - } - super.handleData(event); - if (((fFilter == null) || fFilter.matches(event)) && (skipCount-- <= 0)) { - synchronized (TmfEventsCache.this) { - if (monitor.isCanceled()) { - return; - } - fCache[count] = new CachedEvent(event, rank); - count++; - fCacheEndIndex++; - } - if (fFilter != null) { - fTable.cacheUpdated(false); - } - } else if (((fFilter != null) && !fFilter.matches(event)) && (skipCount <= 0)) { // TODO fix duplicated call to matches() - if ((count > 0) && (fFilter instanceof TmfCollapseFilter)) { - fCache[count - 1].repeatCount++; - } - } - if (count >= fCache.length) { - cancel(); - } else if ((fFilter != null) && (count >= (fTable.getTable().getItemCount() - 3))) { // -1 for header row, -2 for top and bottom filter status rows - cancel(); - } - rank++; - } - }; - - ((ITmfEventProvider) fTrace).sendRequest(request); - try { - request.waitForCompletion(); - } catch (InterruptedException e) { - Activator.getDefault().logError("Wait for completion interrupted for populateCache ", e); //$NON-NLS-1$ - } - - fTable.cacheUpdated(true); - - // Flag the UI thread that the cache is ready - if (monitor.isCanceled()) { - return Status.CANCEL_STATUS; - } - return Status.OK_STATUS; - } - }; - //job.setSystem(true); - job.setPriority(Job.SHORT); - job.schedule(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventsTable.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventsTable.java deleted file mode 100644 index 6523a7cf4b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventsTable.java +++ /dev/null @@ -1,2539 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation, replaced Table by TmfVirtualTable - * Patrick Tasse - Factored out from events view, - * Filter implementation (inspired by www.eclipse.org/mat) - * Ansgar Radermacher - Support navigation to model URIs (Bug 396956) - * Bernd Hufmann - Updated call site and model URI implementation - * Alexandre Montplaisir - Update to new column API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.events; - -import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map.Entry; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -import org.eclipse.core.commands.Command; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.commands.NotEnabledException; -import org.eclipse.core.commands.NotHandledException; -import org.eclipse.core.commands.ParameterizedCommand; -import org.eclipse.core.commands.common.NotDefinedException; -import org.eclipse.core.expressions.IEvaluationContext; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceVisitor; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.ListenerList; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.EValidator; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.IStatusLineManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.dialogs.InputDialog; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.resource.FontDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.util.OpenStrategy; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.jface.viewers.ArrayContentProvider; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.window.Window; -import org.eclipse.linuxtools.internal.tmf.core.filter.TmfCollapseFilter; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.internal.tmf.ui.commands.ExportToTextCommandHandler; -import org.eclipse.linuxtools.internal.tmf.ui.dialogs.MultiLineInputDialog; -import org.eclipse.linuxtools.tmf.core.component.ITmfEventProvider; -import org.eclipse.linuxtools.tmf.core.component.TmfComponent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.collapse.ITmfCollapsibleEvent; -import org.eclipse.linuxtools.tmf.core.event.lookup.ITmfCallsite; -import org.eclipse.linuxtools.tmf.core.event.lookup.ITmfModelLookup; -import org.eclipse.linuxtools.tmf.core.event.lookup.ITmfSourceLookup; -import org.eclipse.linuxtools.tmf.core.filter.ITmfFilter; -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterAndNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterMatchesNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterNode; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest.ExecutionType; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.signal.TmfEventFilterAppliedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfEventSearchAppliedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfEventSelectedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; -import org.eclipse.linuxtools.tmf.ui.viewers.events.TmfEventsCache.CachedEvent; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn; -import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableFieldColumn; -import org.eclipse.linuxtools.tmf.ui.views.colors.ColorSetting; -import org.eclipse.linuxtools.tmf.ui.views.colors.ColorSettingsManager; -import org.eclipse.linuxtools.tmf.ui.views.colors.IColorSettingsListener; -import org.eclipse.linuxtools.tmf.ui.views.filter.FilterManager; -import org.eclipse.linuxtools.tmf.ui.widgets.rawviewer.TmfRawEventViewer; -import org.eclipse.linuxtools.tmf.ui.widgets.virtualtable.TmfVirtualTable; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.SashForm; -import org.eclipse.swt.custom.TableEditor; -import org.eclipse.swt.events.FocusAdapter; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.KeyAdapter; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.MessageBox; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.TableItem; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.commands.ICommandService; -import org.eclipse.ui.dialogs.ListDialog; -import org.eclipse.ui.handlers.IHandlerService; -import org.eclipse.ui.ide.IDE; -import org.eclipse.ui.ide.IGotoMarker; -import org.eclipse.ui.themes.ColorUtil; - -import com.google.common.base.Joiner; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Multimap; - -/** - * The generic TMF Events table - * - * This is a view that will list events that are read from a trace. - * - * @author Francois Chouinard - * @author Patrick Tasse - * @since 2.0 - */ -public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorSettingsListener, ISelectionProvider { - - /** - * Empty string array, used by {@link #getItemStrings}. - * @since 3.0 - */ - protected static final @NonNull String[] EMPTY_STRING_ARRAY = new String[0]; - - /** - * Empty string - * @since 3.1 - */ - protected static final @NonNull String EMPTY_STRING = ""; //$NON-NLS-1$ - - private static final boolean IS_LINUX = System.getProperty("os.name").contains("Linux") ? true : false; //$NON-NLS-1$ //$NON-NLS-2$ - - private static final Image BOOKMARK_IMAGE = Activator.getDefault().getImageFromPath( - "icons/elcl16/bookmark_obj.gif"); //$NON-NLS-1$ - private static final Image SEARCH_IMAGE = Activator.getDefault().getImageFromPath("icons/elcl16/search.gif"); //$NON-NLS-1$ - private static final Image SEARCH_MATCH_IMAGE = Activator.getDefault().getImageFromPath( - "icons/elcl16/search_match.gif"); //$NON-NLS-1$ - private static final Image SEARCH_MATCH_BOOKMARK_IMAGE = Activator.getDefault().getImageFromPath( - "icons/elcl16/search_match_bookmark.gif"); //$NON-NLS-1$ - private static final Image FILTER_IMAGE = Activator.getDefault() - .getImageFromPath("icons/elcl16/filter_items.gif"); //$NON-NLS-1$ - private static final Image STOP_IMAGE = Activator.getDefault().getImageFromPath("icons/elcl16/stop.gif"); //$NON-NLS-1$ - private static final String SEARCH_HINT = Messages.TmfEventsTable_SearchHint; - private static final String FILTER_HINT = Messages.TmfEventsTable_FilterHint; - private static final int MAX_CACHE_SIZE = 1000; - - private static final int MARGIN_COLUMN_INDEX = 0; - private static final int FILTER_SUMMARY_INDEX = 1; - private static final int EVENT_COLUMNS_START_INDEX = MARGIN_COLUMN_INDEX + 1; - - /** - * Default set of columns to use for trace types that do not specify - * anything - * @since 3.2 - */ - public static final Collection DEFAULT_COLUMNS = ImmutableList.of( - TmfEventTableColumn.BaseColumns.TIMESTAMP, - TmfEventTableColumn.BaseColumns.SOURCE, - TmfEventTableColumn.BaseColumns.EVENT_TYPE, - TmfEventTableColumn.BaseColumns.REFERENCE, - TmfEventTableColumn.BaseColumns.CONTENTS - ); - - /** - * The events table search/filter keys - * - * @version 1.0 - * @author Patrick Tasse - */ - public interface Key { - /** Search text */ - String SEARCH_TXT = "$srch_txt"; //$NON-NLS-1$ - - /** Search object */ - String SEARCH_OBJ = "$srch_obj"; //$NON-NLS-1$ - - /** Filter text */ - String FILTER_TXT = "$fltr_txt"; //$NON-NLS-1$ - - /** Filter object */ - String FILTER_OBJ = "$fltr_obj"; //$NON-NLS-1$ - - /** Timestamp */ - String TIMESTAMP = "$time"; //$NON-NLS-1$ - - /** Rank */ - String RANK = "$rank"; //$NON-NLS-1$ - - /** Field ID */ - String FIELD_ID = "$field_id"; //$NON-NLS-1$ - - /** Bookmark indicator */ - String BOOKMARK = "$bookmark"; //$NON-NLS-1$ - } - - /** - * The events table search/filter state - * - * @version 1.0 - * @author Patrick Tasse - */ - public static enum HeaderState { - /** A search is being run */ - SEARCH, - - /** A filter is applied */ - FILTER - } - - interface Direction { - int FORWARD = +1; - int BACKWARD = -1; - } - - // ------------------------------------------------------------------------ - // Table data - // ------------------------------------------------------------------------ - - /** The virtual event table */ - protected TmfVirtualTable fTable; - - private Composite fComposite; - private SashForm fSashForm; - private TmfRawEventViewer fRawViewer; - private ITmfTrace fTrace; - volatile private boolean fPackDone = false; - private HeaderState fHeaderState = HeaderState.SEARCH; - private long fSelectedRank = 0; - private ITmfTimestamp fSelectedBeginTimestamp = null; - private IStatusLineManager fStatusLineManager = null; - - // Filter data - private long fFilterMatchCount; - private long fFilterCheckCount; - private FilterThread fFilterThread; - private boolean fFilterThreadResume = false; - private final Object fFilterSyncObj = new Object(); - private SearchThread fSearchThread; - private final Object fSearchSyncObj = new Object(); - - /** - * List of selection change listeners (element type: ISelectionChangedListener). - * - * @see #fireSelectionChanged - */ - private ListenerList selectionChangedListeners = new ListenerList(); - - // Bookmark map - private Multimap fBookmarksMap = HashMultimap.create(); - private IFile fBookmarksFile; - private long fPendingGotoRank = -1; - - // SWT resources - private LocalResourceManager fResourceManager = new LocalResourceManager(JFaceResources.getResources()); - private Color fGrayColor; - private Color fGreenColor; - private Font fBoldFont; - - private final List fColumns = new LinkedList<>(); - - // Event cache - private final TmfEventsCache fCache; - private boolean fCacheUpdateBusy = false; - private boolean fCacheUpdatePending = false; - private boolean fCacheUpdateCompleted = false; - private final Object fCacheUpdateSyncObj = new Object(); - - private boolean fDisposeOnClose; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Basic constructor, using the default set of columns - * - * @param parent - * The parent composite UI object - * @param cacheSize - * The size of the event table cache - */ - public TmfEventsTable(final Composite parent, final int cacheSize) { - this(parent, cacheSize, DEFAULT_COLUMNS); - } - - /** - * Legacy constructor, using ColumnData to define columns - * - * @param parent - * The parent composite UI object - * @param cacheSize - * The size of the event table cache - * @param columnData - * Unused - * @deprecated Deprecated constructor, use - * {@link #TmfEventsTable(Composite, int, Collection)} - */ - @Deprecated - public TmfEventsTable(final Composite parent, int cacheSize, - final org.eclipse.linuxtools.tmf.ui.widgets.virtualtable.ColumnData[] columnData) { - /* - * We'll do a "best-effort" to keep trace types still using this API to - * keep working, by defining a TmfEventTableFieldColumn for each - * ColumnData they passed. - */ - this(parent, cacheSize, convertFromColumnData(columnData)); - } - - @Deprecated - private static Collection convertFromColumnData( - org.eclipse.linuxtools.tmf.ui.widgets.virtualtable.ColumnData[] columnData) { - - ImmutableList.Builder builder = new ImmutableList.Builder<>(); - for (org.eclipse.linuxtools.tmf.ui.widgets.virtualtable.ColumnData col : columnData) { - String header = col.header; - if (header != null) { - builder.add(new TmfEventTableFieldColumn(header)); - } - } - return builder.build(); - } - - /** - * Standard constructor, where we define which columns to use. - * - * @param parent - * The parent composite UI object - * @param cacheSize - * The size of the event table cache - * @param columns - * The columns to use in this table. - *

- * The iteration order of this collection will correspond to the - * initial ordering of this series of columns in the table. - *

- * @since 3.1 - */ - public TmfEventsTable(final Composite parent, int cacheSize, - Collection columns) { - super("TmfEventsTable"); //$NON-NLS-1$ - - fComposite = new Composite(parent, SWT.NONE); - final GridLayout gl = new GridLayout(1, false); - gl.marginHeight = 0; - gl.marginWidth = 0; - gl.verticalSpacing = 0; - fComposite.setLayout(gl); - - fSashForm = new SashForm(fComposite, SWT.HORIZONTAL); - fSashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - // Create a virtual table - final int style = SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION; - fTable = new TmfVirtualTable(fSashForm, style); - - // Set the table layout - final GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); - fTable.setLayoutData(layoutData); - - // Some cosmetic enhancements - fTable.setHeaderVisible(true); - fTable.setLinesVisible(true); - - // Setup the columns - if (columns != null) { - fColumns.addAll(columns); - } - - TmfMarginColumn collapseCol = new TmfMarginColumn(); - fColumns.add(MARGIN_COLUMN_INDEX, collapseCol); - - // Create the UI columns in the table - for (TmfEventTableColumn col : fColumns) { - TableColumn column = fTable.newTableColumn(SWT.LEFT); - column.setText(col.getHeaderName()); - column.setToolTipText(col.getHeaderTooltip()); - column.setData(Key.FIELD_ID, col.getFilterFieldId()); - column.pack(); - if (col instanceof TmfMarginColumn) { - column.setResizable(false); - } - } - - // Set the frozen row for header row - fTable.setFrozenRowCount(1); - - // Create the header row cell editor - createHeaderEditor(); - - // Handle the table item selection - fTable.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(final SelectionEvent e) { - if (e.item == null) { - return; - } - updateStatusLine(null); - if (fTable.getSelectionIndices().length > 0) { - if (e.item.getData(Key.RANK) instanceof Long) { - fSelectedRank = (Long) e.item.getData(Key.RANK); - fRawViewer.selectAndReveal((Long) e.item.getData(Key.RANK)); - } - if (e.item.getData(Key.TIMESTAMP) instanceof ITmfTimestamp) { - final ITmfTimestamp ts = (ITmfTimestamp) e.item.getData(Key.TIMESTAMP); - if (fTable.getSelectionIndices().length == 1) { - fSelectedBeginTimestamp = ts; - } - if (fSelectedBeginTimestamp != null) { - if (fSelectedBeginTimestamp.compareTo(ts) <= 0) { - broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, fSelectedBeginTimestamp, ts)); - if (fTable.getSelectionIndices().length == 2) { - updateStatusLine(ts.getDelta(fSelectedBeginTimestamp)); - } - } else { - broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, ts, fSelectedBeginTimestamp)); - updateStatusLine(fSelectedBeginTimestamp.getDelta(ts)); - } - } - } else { - if (fTable.getSelectionIndices().length == 1) { - fSelectedBeginTimestamp = null; - } - } - } - if (e.item.getData() instanceof ITmfEvent) { - broadcast(new TmfEventSelectedSignal(TmfEventsTable.this, (ITmfEvent) e.item.getData())); - fireSelectionChanged(new SelectionChangedEvent(TmfEventsTable.this, new StructuredSelection(e.item.getData()))); - } else { - fireSelectionChanged(new SelectionChangedEvent(TmfEventsTable.this, StructuredSelection.EMPTY)); - } - } - }); - - int realCacheSize = Math.max(cacheSize, Display.getDefault().getBounds().height / fTable.getItemHeight()); - realCacheSize = Math.min(realCacheSize, MAX_CACHE_SIZE); - fCache = new TmfEventsCache(realCacheSize, this); - - // Handle the table item requests - fTable.addListener(SWT.SetData, new Listener() { - - @Override - public void handleEvent(final Event event) { - - final TableItem item = (TableItem) event.item; - int index = event.index - 1; // -1 for the header row - - if (event.index == 0) { - setHeaderRowItemData(item); - return; - } - - if (fTable.getData(Key.FILTER_OBJ) != null) { - if ((event.index == 1) || (event.index == (fTable.getItemCount() - 1))) { - setFilterStatusRowItemData(item); - return; - } - index = index - 1; // -1 for top filter status row - } - - final CachedEvent cachedEvent = fCache.getEvent(index); - if (cachedEvent != null) { - setItemData(item, cachedEvent, cachedEvent.rank); - return; - } - - // Else, fill the cache asynchronously (and off the UI thread) - event.doit = false; - } - }); - - fTable.addMouseListener(new MouseAdapter() { - @Override - public void mouseDoubleClick(final MouseEvent event) { - if (event.button != 1) { - return; - } - // Identify the selected row - final Point point = new Point(event.x, event.y); - final TableItem item = fTable.getItem(point); - if (item != null) { - final Rectangle imageBounds = item.getImageBounds(0); - imageBounds.width = BOOKMARK_IMAGE.getBounds().width; - if (imageBounds.contains(point)) { - final Long rank = (Long) item.getData(Key.RANK); - if (rank != null) { - toggleBookmark(rank); - } - } - } - } - }); - - final Listener tooltipListener = new Listener () { - Shell tooltipShell = null; - @Override - public void handleEvent(final Event event) { - switch (event.type) { - case SWT.MouseHover: - final TableItem item = fTable.getItem(new Point(event.x, event.y)); - if (item == null) { - return; - } - final Long rank = (Long) item.getData(Key.RANK); - if (rank == null) { - return; - } - final String tooltipText = (String) item.getData(Key.BOOKMARK); - final Rectangle bounds = item.getImageBounds(0); - bounds.width = BOOKMARK_IMAGE.getBounds().width; - if (!bounds.contains(event.x,event.y)) { - return; - } - if ((tooltipShell != null) && !tooltipShell.isDisposed()) { - tooltipShell.dispose(); - } - tooltipShell = new Shell(fTable.getShell(), SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL); - tooltipShell.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); - final FillLayout layout = new FillLayout(); - layout.marginWidth = 2; - tooltipShell.setLayout(layout); - final Label label = new Label(tooltipShell, SWT.WRAP); - String text = rank.toString() + (tooltipText != null ? ": " + tooltipText : EMPTY_STRING); //$NON-NLS-1$ - label.setForeground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND)); - label.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); - label.setText(text); - label.addListener(SWT.MouseExit, this); - label.addListener(SWT.MouseDown, this); - label.addListener(SWT.MouseWheel, this); - final Point size = tooltipShell.computeSize(SWT.DEFAULT, SWT.DEFAULT); - /* - * Bug in Linux. The coordinates of the event have an origin that excludes the table header but - * the method toDisplay() expects coordinates relative to an origin that includes the table header. - */ - int y = event.y; - if (IS_LINUX) { - y += fTable.getHeaderHeight(); - } - Point pt = fTable.toDisplay(event.x, y); - pt.x += BOOKMARK_IMAGE.getBounds().width; - pt.y += item.getBounds().height; - tooltipShell.setBounds(pt.x, pt.y, size.x, size.y); - tooltipShell.setVisible(true); - break; - case SWT.Dispose: - case SWT.KeyDown: - case SWT.MouseMove: - case SWT.MouseExit: - case SWT.MouseDown: - case SWT.MouseWheel: - if (tooltipShell != null) { - tooltipShell.dispose(); - tooltipShell = null; - } - break; - default: - break; - } - } - }; - - fTable.addListener(SWT.MouseHover, tooltipListener); - fTable.addListener(SWT.Dispose, tooltipListener); - fTable.addListener(SWT.KeyDown, tooltipListener); - fTable.addListener(SWT.MouseMove, tooltipListener); - fTable.addListener(SWT.MouseExit, tooltipListener); - fTable.addListener(SWT.MouseDown, tooltipListener); - fTable.addListener(SWT.MouseWheel, tooltipListener); - - // Create resources - createResources(); - - ColorSettingsManager.addColorSettingsListener(this); - - fTable.setItemCount(1); // +1 for header row - - fRawViewer = new TmfRawEventViewer(fSashForm, SWT.H_SCROLL | SWT.V_SCROLL); - - fRawViewer.addSelectionListener(new Listener() { - @Override - public void handleEvent(final Event e) { - if (e.data instanceof Long) { - final long rank = (Long) e.data; - int index = (int) rank; - if (fTable.getData(Key.FILTER_OBJ) != null) { - index = fCache.getFilteredEventIndex(rank) + 1; // +1 for top filter status row - } - fTable.setSelection(index + 1); // +1 for header row - fSelectedRank = rank; - updateStatusLine(null); - } else if (e.data instanceof ITmfLocation) { - // DOES NOT WORK: rank undefined in context from seekLocation() - // ITmfLocation location = (ITmfLocation) e.data; - // TmfContext context = fTrace.seekLocation(location); - // fTable.setSelection((int) context.getRank()); - return; - } else { - return; - } - final TableItem[] selection = fTable.getSelection(); - if ((selection != null) && (selection.length > 0)) { - final TmfTimestamp ts = (TmfTimestamp) fTable.getSelection()[0].getData(Key.TIMESTAMP); - if (ts != null) { - broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, ts)); - } - } - } - }); - - fSashForm.setWeights(new int[] { 1, 1 }); - fRawViewer.setVisible(false); - - createPopupMenu(); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Create a pop-up menu. - */ - protected void createPopupMenu() { - final IAction showTableAction = new Action(Messages.TmfEventsTable_ShowTableActionText) { - @Override - public void run() { - fTable.setVisible(true); - fSashForm.layout(); - } - }; - - final IAction hideTableAction = new Action(Messages.TmfEventsTable_HideTableActionText) { - @Override - public void run() { - fTable.setVisible(false); - fSashForm.layout(); - } - }; - - final IAction showRawAction = new Action(Messages.TmfEventsTable_ShowRawActionText) { - @Override - public void run() { - fRawViewer.setVisible(true); - fSashForm.layout(); - final int index = fTable.getSelectionIndex(); - if (index >= 1) { - fRawViewer.selectAndReveal(index - 1); - } - } - }; - - final IAction hideRawAction = new Action(Messages.TmfEventsTable_HideRawActionText) { - @Override - public void run() { - fRawViewer.setVisible(false); - fSashForm.layout(); - } - }; - - final IAction openCallsiteAction = new Action(Messages.TmfEventsTable_OpenSourceCodeActionText) { - @Override - public void run() { - final TableItem items[] = fTable.getSelection(); - if (items.length != 1) { - return; - } - final TableItem item = items[0]; - - final Object data = item.getData(); - if (data instanceof ITmfSourceLookup) { - ITmfSourceLookup event = (ITmfSourceLookup) data; - ITmfCallsite cs = event.getCallsite(); - if (cs == null || cs.getFileName() == null) { - return; - } - IMarker marker = null; - try { - String fileName = cs.getFileName(); - final String trimmedPath = fileName.replaceAll("\\.\\./", EMPTY_STRING); //$NON-NLS-1$ - final ArrayList files = new ArrayList<>(); - ResourcesPlugin.getWorkspace().getRoot().accept(new IResourceVisitor() { - @Override - public boolean visit(IResource resource) throws CoreException { - if (resource instanceof IFile && resource.getFullPath().toString().endsWith(trimmedPath)) { - files.add((IFile) resource); - } - return true; - } - }); - IFile file = null; - if (files.size() > 1) { - ListDialog dialog = new ListDialog(getTable().getShell()); - dialog.setContentProvider(ArrayContentProvider.getInstance()); - dialog.setLabelProvider(new LabelProvider() { - @Override - public String getText(Object element) { - return ((IFile) element).getFullPath().toString(); - } - }); - dialog.setInput(files); - dialog.setTitle(Messages.TmfEventsTable_OpenSourceCodeSelectFileDialogTitle); - dialog.setMessage(Messages.TmfEventsTable_OpenSourceCodeSelectFileDialogTitle + '\n' + cs.toString()); - dialog.open(); - Object[] result = dialog.getResult(); - if (result != null && result.length > 0) { - file = (IFile) result[0]; - } - } else if (files.size() == 1) { - file = files.get(0); - } - if (file != null) { - marker = file.createMarker(IMarker.MARKER); - marker.setAttribute(IMarker.LINE_NUMBER, Long.valueOf(cs.getLineNumber()).intValue()); - IDE.openEditor(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(), marker); - marker.delete(); - } else if (files.size() == 0){ - displayException(new FileNotFoundException('\'' + cs.toString() + '\'' + '\n' + Messages.TmfEventsTable_OpenSourceCodeNotFound)); - } - } catch (CoreException e) { - displayException(e); - } - } - } - }; - - final IAction openModelAction = new Action(Messages.TmfEventsTable_OpenModelActionText) { - @Override - public void run() { - - final TableItem items[] = fTable.getSelection(); - if (items.length != 1) { - return; - } - final TableItem item = items[0]; - - final Object eventData = item.getData(); - if (eventData instanceof ITmfModelLookup) { - String modelURI = ((ITmfModelLookup) eventData).getModelUri(); - - if (modelURI != null) { - IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - - IFile file = null; - final URI uri = URI.createURI(modelURI); - if (uri.isPlatformResource()) { - IPath path = new Path(uri.toPlatformString(true)); - file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); - } else if (uri.isFile() && !uri.isRelative()) { - file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation( - new Path(uri.toFileString())); - } - - if (file != null) { - try { - /* - * create a temporary validation marker on the - * model file, remove it afterwards thus, - * navigation works with all model editors - * supporting the navigation to a marker - */ - IMarker marker = file.createMarker(EValidator.MARKER); - marker.setAttribute(EValidator.URI_ATTRIBUTE, modelURI); - marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO); - - IDE.openEditor(activePage, marker, OpenStrategy.activateOnOpen()); - marker.delete(); - } - catch (CoreException e) { - displayException(e); - } - } else { - displayException(new FileNotFoundException('\'' + modelURI + '\'' + '\n' + Messages.TmfEventsTable_OpenModelUnsupportedURI)); - } - } - } - } - }; - - final IAction exportToTextAction = new Action(Messages.TmfEventsTable_Export_to_text) { - @Override - public void run() { - IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - IHandlerService handlerService = (IHandlerService) activePage.getActiveEditor().getSite().getService(IHandlerService.class); - ICommandService cmdService = (ICommandService) activePage.getActiveEditor().getSite().getService(ICommandService.class); - try { - HashMap parameters = new HashMap<>(); - Command command = cmdService.getCommand(ExportToTextCommandHandler.COMMAND_ID); - ParameterizedCommand cmd = ParameterizedCommand.generateCommand(command, parameters); - - IEvaluationContext context = handlerService.getCurrentState(); - // Omit the margin column - List exportColumns = fColumns.subList(EVENT_COLUMNS_START_INDEX, fColumns.size()); - context.addVariable(ExportToTextCommandHandler.TMF_EVENT_TABLE_COLUMNS_ID, exportColumns); - - handlerService.executeCommandInContext(cmd, null, context); - } catch (ExecutionException e) { - displayException(e); - } catch (NotDefinedException e) { - displayException(e); - } catch (NotEnabledException e) { - displayException(e); - } catch (NotHandledException e) { - displayException(e); - } - } - }; - - final IAction showSearchBarAction = new Action(Messages.TmfEventsTable_ShowSearchBarActionText) { - @Override - public void run() { - fHeaderState = HeaderState.SEARCH; - fTable.refresh(); - } - }; - - final IAction showFilterBarAction = new Action(Messages.TmfEventsTable_ShowFilterBarActionText) { - @Override - public void run() { - fHeaderState = HeaderState.FILTER; - fTable.refresh(); - } - }; - - final IAction clearFiltersAction = new Action(Messages.TmfEventsTable_ClearFiltersActionText) { - @Override - public void run() { - clearFilters(); - } - }; - - final IAction collapseAction = new Action(Messages.TmfEventsTable_CollapseFilterMenuName) { - @Override - public void run() { - applyFilter(new TmfCollapseFilter()); - } - }; - - class ToggleBookmarkAction extends Action { - Long fRank; - - public ToggleBookmarkAction(final String text, final Long rank) { - super(text); - fRank = rank; - } - - @Override - public void run() { - toggleBookmark(fRank); - } - } - - final MenuManager tablePopupMenu = new MenuManager(); - tablePopupMenu.setRemoveAllWhenShown(true); - tablePopupMenu.addMenuListener(new IMenuListener() { - @Override - public void menuAboutToShow(final IMenuManager manager) { - if (fTable.getSelectionIndex() == 0) { - // Right-click on header row - if (fHeaderState == HeaderState.FILTER) { - tablePopupMenu.add(showSearchBarAction); - } else { - tablePopupMenu.add(showFilterBarAction); - } - return; - } - final Point point = fTable.toControl(Display.getDefault().getCursorLocation()); - final TableItem item = fTable.getSelection().length > 0 ? fTable.getSelection()[0] : null; - if (item != null) { - final Rectangle imageBounds = item.getImageBounds(0); - imageBounds.width = BOOKMARK_IMAGE.getBounds().width; - if (point.x <= (imageBounds.x + imageBounds.width)) { - // Right-click on left margin - final Long rank = (Long) item.getData(Key.RANK); - if ((rank != null) && (fBookmarksFile != null)) { - if (fBookmarksMap.containsKey(rank)) { - tablePopupMenu.add(new ToggleBookmarkAction( - Messages.TmfEventsTable_RemoveBookmarkActionText, rank)); - } else { - tablePopupMenu.add(new ToggleBookmarkAction( - Messages.TmfEventsTable_AddBookmarkActionText, rank)); - } - } - return; - } - } - - // Right-click on table - if (fTable.isVisible() && fRawViewer.isVisible()) { - tablePopupMenu.add(hideTableAction); - tablePopupMenu.add(hideRawAction); - } else if (!fTable.isVisible()) { - tablePopupMenu.add(showTableAction); - } else if (!fRawViewer.isVisible()) { - tablePopupMenu.add(showRawAction); - } - tablePopupMenu.add(exportToTextAction); - tablePopupMenu.add(new Separator()); - - if (item != null) { - final Object data = item.getData(); - Separator separator = null; - if (data instanceof ITmfSourceLookup) { - ITmfSourceLookup event = (ITmfSourceLookup) data; - if (event.getCallsite() != null) { - tablePopupMenu.add(openCallsiteAction); - separator = new Separator(); - } - } - - if (data instanceof ITmfModelLookup) { - ITmfModelLookup event = (ITmfModelLookup) data; - if (event.getModelUri() != null) { - tablePopupMenu.add(openModelAction); - separator = new Separator(); - } - - if (separator != null) { - tablePopupMenu.add(separator); - } - } - } - - // only show collapse filter if at least one trace can be collapsed - boolean isCollapsible = false; - if (fTrace != null) { - ITmfTrace traces[] = TmfTraceManager.getTraceSet(fTrace); - for (ITmfTrace trace : traces) { - Class eventClass = trace.getEventType(); - isCollapsible = ITmfCollapsibleEvent.class.isAssignableFrom(eventClass); - if (isCollapsible) { - break; - } - } - } - - if (isCollapsible && !(fTable.getData(Key.FILTER_OBJ) instanceof TmfCollapseFilter)) { - tablePopupMenu.add(collapseAction); - tablePopupMenu.add(new Separator()); - } - - tablePopupMenu.add(clearFiltersAction); - final ITmfFilterTreeNode[] savedFilters = FilterManager.getSavedFilters(); - if (savedFilters.length > 0) { - final MenuManager subMenu = new MenuManager(Messages.TmfEventsTable_ApplyPresetFilterMenuName); - for (final ITmfFilterTreeNode node : savedFilters) { - if (node instanceof TmfFilterNode) { - final TmfFilterNode filter = (TmfFilterNode) node; - subMenu.add(new Action(filter.getFilterName()) { - @Override - public void run() { - applyFilter(filter); - } - }); - } - } - tablePopupMenu.add(subMenu); - } - appendToTablePopupMenu(tablePopupMenu, item); - } - }); - - final MenuManager rawViewerPopupMenu = new MenuManager(); - rawViewerPopupMenu.setRemoveAllWhenShown(true); - rawViewerPopupMenu.addMenuListener(new IMenuListener() { - @Override - public void menuAboutToShow(final IMenuManager manager) { - if (fTable.isVisible() && fRawViewer.isVisible()) { - rawViewerPopupMenu.add(hideTableAction); - rawViewerPopupMenu.add(hideRawAction); - } else if (!fTable.isVisible()) { - rawViewerPopupMenu.add(showTableAction); - } else if (!fRawViewer.isVisible()) { - rawViewerPopupMenu.add(showRawAction); - } - appendToRawPopupMenu(tablePopupMenu); - } - }); - - Menu menu = tablePopupMenu.createContextMenu(fTable); - fTable.setMenu(menu); - - menu = rawViewerPopupMenu.createContextMenu(fRawViewer); - fRawViewer.setMenu(menu); - } - - - /** - * Append an item to the event table's pop-up menu. - * - * @param tablePopupMenu - * The menu manager - * @param selectedItem - * The item to append - */ - protected void appendToTablePopupMenu(final MenuManager tablePopupMenu, final TableItem selectedItem) { - // override to append more actions - } - - /** - * Append an item to the raw viewer's pop-up menu. - * - * @param rawViewerPopupMenu - * The menu manager - */ - protected void appendToRawPopupMenu(final MenuManager rawViewerPopupMenu) { - // override to append more actions - } - - @Override - public void dispose() { - stopSearchThread(); - stopFilterThread(); - ColorSettingsManager.removeColorSettingsListener(this); - fComposite.dispose(); - if ((fTrace != null) && fDisposeOnClose) { - fTrace.dispose(); - } - fResourceManager.dispose(); - fRawViewer.dispose(); - super.dispose(); - } - - /** - * Assign a layout data object to this view. - * - * @param layoutData - * The layout data to assign - */ - public void setLayoutData(final Object layoutData) { - fComposite.setLayoutData(layoutData); - } - - /** - * Get the virtual table contained in this event table. - * - * @return The TMF virtual table - */ - public TmfVirtualTable getTable() { - return fTable; - } - - /** - * @param columnData - * columnData - * @deprecated The column headers are now set at the constructor, this - * shouldn't be called anymore. - */ - @Deprecated - protected void setColumnHeaders(final org.eclipse.linuxtools.tmf.ui.widgets.virtualtable.ColumnData [] columnData) { - /* No-op */ - } - - /** - * Set a table item's data. - * - * @param item - * The item to set - * @param event - * Which trace event to link with this entry - * @param rank - * Which rank this event has in the trace/experiment - */ - protected void setItemData(final TableItem item, final ITmfEvent event, final long rank) { - String[] itemStrings = getItemStrings(fColumns, event); - item.setText(itemStrings); - item.setData(event); - item.setData(Key.TIMESTAMP, new TmfTimestamp(event.getTimestamp())); - item.setData(Key.RANK, rank); - - final Collection markerIds = fBookmarksMap.get(rank); - if (!markerIds.isEmpty()) { - Joiner joiner = Joiner.on("\n -").skipNulls(); //$NON-NLS-1$ - List parts = new ArrayList<>(); - if (markerIds.size() > 1) { - parts.add(Messages.TmfEventsTable_MultipleBookmarksToolTip); - } - try { - for (long markerId : markerIds) { - final IMarker marker = fBookmarksFile.findMarker(markerId); - parts.add(marker.getAttribute(IMarker.MESSAGE)); - } - } catch (CoreException e) { - displayException(e); - } - item.setData(Key.BOOKMARK, joiner.join(parts)); - } else { - item.setData(Key.BOOKMARK, null); - } - - boolean searchMatch = false; - boolean searchNoMatch = false; - final ITmfFilter searchFilter = (ITmfFilter) fTable.getData(Key.SEARCH_OBJ); - if (searchFilter != null) { - if (searchFilter.matches(event)) { - searchMatch = true; - } else { - searchNoMatch = true; - } - } - - final ColorSetting colorSetting = ColorSettingsManager.getColorSetting(event); - if (searchNoMatch) { - item.setForeground(colorSetting.getDimmedForegroundColor()); - item.setBackground(colorSetting.getDimmedBackgroundColor()); - } else { - item.setForeground(colorSetting.getForegroundColor()); - item.setBackground(colorSetting.getBackgroundColor()); - } - - if (searchMatch) { - if (!markerIds.isEmpty()) { - item.setImage(SEARCH_MATCH_BOOKMARK_IMAGE); - } else { - item.setImage(SEARCH_MATCH_IMAGE); - } - } else if (!markerIds.isEmpty()) { - item.setImage(BOOKMARK_IMAGE); - } else { - item.setImage((Image) null); - } - - if ((itemStrings[MARGIN_COLUMN_INDEX] != null) && !itemStrings[MARGIN_COLUMN_INDEX].isEmpty()) { - packMarginColumn(); - } - } - - /** - * Set the item data of the header row. - * - * @param item - * The item to use as table header - */ - protected void setHeaderRowItemData(final TableItem item) { - String txtKey = null; - if (fHeaderState == HeaderState.SEARCH) { - item.setImage(SEARCH_IMAGE); - txtKey = Key.SEARCH_TXT; - } else if (fHeaderState == HeaderState.FILTER) { - item.setImage(FILTER_IMAGE); - txtKey = Key.FILTER_TXT; - } - item.setForeground(fGrayColor); - // Ignore collapse and image column - for (int i = EVENT_COLUMNS_START_INDEX; i < fTable.getColumns().length; i++) { - final TableColumn column = fTable.getColumns()[i]; - final String filter = (String) column.getData(txtKey); - if (filter == null) { - if (fHeaderState == HeaderState.SEARCH) { - item.setText(i, SEARCH_HINT); - } else if (fHeaderState == HeaderState.FILTER) { - item.setText(i, FILTER_HINT); - } - item.setForeground(i, fGrayColor); - item.setFont(i, fTable.getFont()); - } else { - item.setText(i, filter); - item.setForeground(i, fGreenColor); - item.setFont(i, fBoldFont); - } - } - } - - /** - * Set the item data of the "filter status" row. - * - * @param item - * The item to use as filter status row - */ - protected void setFilterStatusRowItemData(final TableItem item) { - for (int i = 0; i < fTable.getColumns().length; i++) { - if (i == MARGIN_COLUMN_INDEX) { - if ((fTrace == null) || (fFilterCheckCount == fTrace.getNbEvents())) { - item.setImage(FILTER_IMAGE); - } else { - item.setImage(STOP_IMAGE); - } - } - - if (i == FILTER_SUMMARY_INDEX) { - item.setText(FILTER_SUMMARY_INDEX, fFilterMatchCount + "/" + fFilterCheckCount); //$NON-NLS-1$ - } else { - item.setText(i, EMPTY_STRING); - } - } - item.setData(null); - item.setData(Key.TIMESTAMP, null); - item.setData(Key.RANK, null); - item.setForeground(null); - item.setBackground(null); - } - - /** - * Create an editor for the header. - */ - protected void createHeaderEditor() { - final TableEditor tableEditor = fTable.createTableEditor(); - tableEditor.horizontalAlignment = SWT.LEFT; - tableEditor.verticalAlignment = SWT.CENTER; - tableEditor.grabHorizontal = true; - tableEditor.minimumWidth = 50; - - // Handle the header row selection - fTable.addMouseListener(new MouseAdapter() { - int columnIndex; - TableColumn column; - TableItem item; - - @Override - public void mouseDown(final MouseEvent event) { - if (event.button != 1) { - return; - } - // Identify the selected row - final Point point = new Point(event.x, event.y); - item = fTable.getItem(point); - - // Header row selected - if ((item != null) && (fTable.indexOf(item) == 0)) { - - // Icon selected - if (item.getImageBounds(0).contains(point)) { - if (fHeaderState == HeaderState.SEARCH) { - fHeaderState = HeaderState.FILTER; - } else if (fHeaderState == HeaderState.FILTER) { - fHeaderState = HeaderState.SEARCH; - } - fTable.setSelection(0); - fTable.refresh(); - return; - } - - // Identify the selected column - columnIndex = -1; - for (int i = 0; i < fTable.getColumns().length; i++) { - final Rectangle rect = item.getBounds(i); - if (rect.contains(point)) { - columnIndex = i; - break; - } - } - - if (columnIndex == -1) { - return; - } - - column = fTable.getColumns()[columnIndex]; - - String txtKey = null; - if (fHeaderState == HeaderState.SEARCH) { - txtKey = Key.SEARCH_TXT; - } else if (fHeaderState == HeaderState.FILTER) { - txtKey = Key.FILTER_TXT; - } - - // The control that will be the editor must be a child of the Table - final Text newEditor = (Text) fTable.createTableEditorControl(Text.class); - final String headerString = (String) column.getData(txtKey); - if (headerString != null) { - newEditor.setText(headerString); - } - newEditor.addFocusListener(new FocusAdapter() { - @Override - public void focusLost(final FocusEvent e) { - final boolean changed = updateHeader(newEditor.getText()); - if (changed) { - applyHeader(); - } - } - }); - newEditor.addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(final KeyEvent e) { - if (e.character == SWT.CR) { - updateHeader(newEditor.getText()); - applyHeader(); - - // Set focus on the table so that the next carriage return goes to the next result - TmfEventsTable.this.getTable().setFocus(); - } else if (e.character == SWT.ESC) { - tableEditor.getEditor().dispose(); - } - } - }); - newEditor.selectAll(); - newEditor.setFocus(); - tableEditor.setEditor(newEditor, item, columnIndex); - } - } - - /* - * returns true is value was changed - */ - private boolean updateHeader(final String text) { - String objKey = null; - String txtKey = null; - if (fHeaderState == HeaderState.SEARCH) { - objKey = Key.SEARCH_OBJ; - txtKey = Key.SEARCH_TXT; - } else if (fHeaderState == HeaderState.FILTER) { - objKey = Key.FILTER_OBJ; - txtKey = Key.FILTER_TXT; - } - if (text.trim().length() > 0) { - try { - final String regex = TmfFilterMatchesNode.regexFix(text); - Pattern.compile(regex); - if (regex.equals(column.getData(txtKey))) { - tableEditor.getEditor().dispose(); - return false; - } - final TmfFilterMatchesNode filter = new TmfFilterMatchesNode(null); - String fieldId = (String) column.getData(Key.FIELD_ID); - if (fieldId == null) { - fieldId = column.getText(); - } - filter.setField(fieldId); - filter.setRegex(regex); - column.setData(objKey, filter); - column.setData(txtKey, regex); - } catch (final PatternSyntaxException ex) { - tableEditor.getEditor().dispose(); - MessageDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), - ex.getDescription(), ex.getMessage()); - return false; - } - } else { - if (column.getData(txtKey) == null) { - tableEditor.getEditor().dispose(); - return false; - } - column.setData(objKey, null); - column.setData(txtKey, null); - } - return true; - } - - private void applyHeader() { - if (fHeaderState == HeaderState.SEARCH) { - stopSearchThread(); - final TmfFilterAndNode filter = new TmfFilterAndNode(null); - for (final TableColumn col : fTable.getColumns()) { - final Object filterObj = col.getData(Key.SEARCH_OBJ); - if (filterObj instanceof ITmfFilterTreeNode) { - filter.addChild((ITmfFilterTreeNode) filterObj); - } - } - if (filter.getChildrenCount() > 0) { - fTable.setData(Key.SEARCH_OBJ, filter); - fTable.refresh(); - searchNext(); - fireSearchApplied(filter); - } else { - fTable.setData(Key.SEARCH_OBJ, null); - fTable.refresh(); - fireSearchApplied(null); - } - } else if (fHeaderState == HeaderState.FILTER) { - final TmfFilterAndNode filter = new TmfFilterAndNode(null); - for (final TableColumn col : fTable.getColumns()) { - final Object filterObj = col.getData(Key.FILTER_OBJ); - if (filterObj instanceof ITmfFilterTreeNode) { - filter.addChild((ITmfFilterTreeNode) filterObj); - } - } - if (filter.getChildrenCount() > 0) { - applyFilter(filter); - } else { - clearFilters(); - } - } - - tableEditor.getEditor().dispose(); - } - }); - - fTable.addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(final KeyEvent e) { - e.doit = false; - if (e.character == SWT.ESC) { - stopFilterThread(); - stopSearchThread(); - fTable.refresh(); - } else if (e.character == SWT.DEL) { - if (fHeaderState == HeaderState.SEARCH) { - stopSearchThread(); - for (final TableColumn column : fTable.getColumns()) { - column.setData(Key.SEARCH_OBJ, null); - column.setData(Key.SEARCH_TXT, null); - } - fTable.setData(Key.SEARCH_OBJ, null); - fTable.refresh(); - fireSearchApplied(null); - } else if (fHeaderState == HeaderState.FILTER) { - clearFilters(); - } - } else if (e.character == SWT.CR) { - if ((e.stateMask & SWT.SHIFT) == 0) { - searchNext(); - } else { - searchPrevious(); - } - } - } - }); - } - - /** - * Send an event indicating a filter has been applied. - * - * @param filter - * The filter that was just applied - */ - protected void fireFilterApplied(final ITmfFilter filter) { - broadcast(new TmfEventFilterAppliedSignal(this, fTrace, filter)); - } - - /** - * Send an event indicating that a search has been applied. - * - * @param filter - * The search filter that was just applied - */ - protected void fireSearchApplied(final ITmfFilter filter) { - broadcast(new TmfEventSearchAppliedSignal(this, fTrace, filter)); - } - - /** - * Start the filtering thread. - */ - protected void startFilterThread() { - synchronized (fFilterSyncObj) { - final ITmfFilterTreeNode filter = (ITmfFilterTreeNode) fTable.getData(Key.FILTER_OBJ); - if (fFilterThread == null || fFilterThread.filter != filter) { - if (fFilterThread != null) { - fFilterThread.cancel(); - fFilterThreadResume = false; - } - fFilterThread = new FilterThread(filter); - fFilterThread.start(); - } else { - fFilterThreadResume = true; - } - } - } - - /** - * Stop the filtering thread. - */ - protected void stopFilterThread() { - synchronized (fFilterSyncObj) { - if (fFilterThread != null) { - fFilterThread.cancel(); - fFilterThread = null; - fFilterThreadResume = false; - } - } - } - - /** - * Apply a filter. - * - * @param filter - * The filter to apply - * @since 1.1 - */ - protected void applyFilter(ITmfFilter filter) { - stopFilterThread(); - stopSearchThread(); - fFilterMatchCount = 0; - fFilterCheckCount = 0; - fCache.applyFilter(filter); - fTable.clearAll(); - fTable.setData(Key.FILTER_OBJ, filter); - fTable.setItemCount(3); // +1 for header row, +2 for top and bottom filter status rows - startFilterThread(); - fireFilterApplied(filter); - } - - /** - * Clear all currently active filters. - */ - protected void clearFilters() { - if (fTable.getData(Key.FILTER_OBJ) == null) { - return; - } - stopFilterThread(); - stopSearchThread(); - fCache.clearFilter(); - fTable.clearAll(); - for (final TableColumn column : fTable.getColumns()) { - column.setData(Key.FILTER_OBJ, null); - column.setData(Key.FILTER_TXT, null); - } - fTable.setData(Key.FILTER_OBJ, null); - if (fTrace != null) { - fTable.setItemCount((int) fTrace.getNbEvents() + 1); // +1 for header row - } else { - fTable.setItemCount(1); // +1 for header row - } - fFilterMatchCount = 0; - fFilterCheckCount = 0; - if (fSelectedRank >= 0) { - fTable.setSelection((int) fSelectedRank + 1); // +1 for header row - } else { - fTable.setSelection(0); - } - fireFilterApplied(null); - updateStatusLine(null); - - // Set original width - fTable.getColumns()[MARGIN_COLUMN_INDEX].setWidth(0); - packMarginColumn(); - } - - /** - * Wrapper Thread object for the filtering thread. - */ - protected class FilterThread extends Thread { - private final ITmfFilterTreeNode filter; - private TmfEventRequest request; - private boolean refreshBusy = false; - private boolean refreshPending = false; - private final Object syncObj = new Object(); - - /** - * Constructor. - * - * @param filter - * The filter this thread will be processing - */ - public FilterThread(final ITmfFilterTreeNode filter) { - super("Filter Thread"); //$NON-NLS-1$ - this.filter = filter; - } - - @Override - public void run() { - if (fTrace == null) { - return; - } - final int nbRequested = (int) (fTrace.getNbEvents() - fFilterCheckCount); - if (nbRequested <= 0) { - return; - } - request = new TmfEventRequest(ITmfEvent.class, TmfTimeRange.ETERNITY, - (int) fFilterCheckCount, nbRequested, ExecutionType.BACKGROUND) { - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - if (request.isCancelled()) { - return; - } - boolean refresh = false; - if (filter.matches(event)) { - final long rank = fFilterCheckCount; - final int index = (int) fFilterMatchCount; - fFilterMatchCount++; - fCache.storeEvent(event, rank, index); - refresh = true; - } else { - if (filter instanceof TmfCollapseFilter) { - fCache.updateCollapsedEvent((int) fFilterMatchCount - 1); - } - } - - if (refresh || (fFilterCheckCount % 100) == 0) { - refreshTable(); - } - fFilterCheckCount++; - } - }; - ((ITmfEventProvider) fTrace).sendRequest(request); - try { - request.waitForCompletion(); - } catch (final InterruptedException e) { - } - refreshTable(); - synchronized (fFilterSyncObj) { - fFilterThread = null; - if (fFilterThreadResume) { - fFilterThreadResume = false; - fFilterThread = new FilterThread(filter); - fFilterThread.start(); - } - } - } - - /** - * Refresh the filter. - */ - public void refreshTable() { - synchronized (syncObj) { - if (refreshBusy) { - refreshPending = true; - return; - } - refreshBusy = true; - } - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - if (request.isCancelled()) { - return; - } - if (fTable.isDisposed()) { - return; - } - fTable.setItemCount((int) fFilterMatchCount + 3); // +1 for header row, +2 for top and bottom filter status rows - fTable.refresh(); - synchronized (syncObj) { - refreshBusy = false; - if (refreshPending) { - refreshPending = false; - refreshTable(); - } - } - } - }); - } - - /** - * Cancel this filtering thread. - */ - public void cancel() { - if (request != null) { - request.cancel(); - } - } - } - - /** - * Go to the next item of a search. - */ - protected void searchNext() { - synchronized (fSearchSyncObj) { - if (fSearchThread != null) { - return; - } - final ITmfFilterTreeNode searchFilter = (ITmfFilterTreeNode) fTable.getData(Key.SEARCH_OBJ); - if (searchFilter == null) { - return; - } - final int selectionIndex = fTable.getSelectionIndex(); - int startIndex; - if (selectionIndex > 0) { - startIndex = selectionIndex; // -1 for header row, +1 for next event - } else { - // header row is selected, start at top event - startIndex = Math.max(0, fTable.getTopIndex() - 1); // -1 for header row - } - final ITmfFilterTreeNode eventFilter = (ITmfFilterTreeNode) fTable.getData(Key.FILTER_OBJ); - if (eventFilter != null) { - startIndex = Math.max(0, startIndex - 1); // -1 for top filter status row - } - fSearchThread = new SearchThread(searchFilter, eventFilter, startIndex, fSelectedRank, Direction.FORWARD); - fSearchThread.schedule(); - } - } - - /** - * Go to the previous item of a search. - */ - protected void searchPrevious() { - synchronized (fSearchSyncObj) { - if (fSearchThread != null) { - return; - } - final ITmfFilterTreeNode searchFilter = (ITmfFilterTreeNode) fTable.getData(Key.SEARCH_OBJ); - if (searchFilter == null) { - return; - } - final int selectionIndex = fTable.getSelectionIndex(); - int startIndex; - if (selectionIndex > 0) { - startIndex = selectionIndex - 2; // -1 for header row, -1 for previous event - } else { - // header row is selected, start at precedent of top event - startIndex = fTable.getTopIndex() - 2; // -1 for header row, -1 for previous event - } - final ITmfFilterTreeNode eventFilter = (ITmfFilterTreeNode) fTable.getData(Key.FILTER_OBJ); - if (eventFilter != null) { - startIndex = startIndex - 1; // -1 for top filter status row - } - fSearchThread = new SearchThread(searchFilter, eventFilter, startIndex, fSelectedRank, Direction.BACKWARD); - fSearchThread.schedule(); - } - } - - /** - * Stop the search thread. - */ - protected void stopSearchThread() { - fPendingGotoRank = -1; - synchronized (fSearchSyncObj) { - if (fSearchThread != null) { - fSearchThread.cancel(); - fSearchThread = null; - } - } - } - - /** - * Wrapper for the search thread. - */ - protected class SearchThread extends Job { - - private ITmfFilterTreeNode searchFilter; - private ITmfFilterTreeNode eventFilter; - private int startIndex; - private int direction; - private long rank; - private long foundRank = -1; - private TmfEventRequest request; - private ITmfTimestamp foundTimestamp = null; - - /** - * Constructor. - * - * @param searchFilter - * The search filter - * @param eventFilter - * The event filter - * @param startIndex - * The index at which we should start searching - * @param currentRank - * The current rank - * @param direction - * In which direction should we search, forward or backwards - */ - public SearchThread(final ITmfFilterTreeNode searchFilter, - final ITmfFilterTreeNode eventFilter, final int startIndex, - final long currentRank, final int direction) { - super(Messages.TmfEventsTable_SearchingJobName); - this.searchFilter = searchFilter; - this.eventFilter = eventFilter; - this.startIndex = startIndex; - this.rank = currentRank; - this.direction = direction; - } - - @Override - protected IStatus run(final IProgressMonitor monitor) { - if (fTrace == null) { - return Status.OK_STATUS; - } - final Display display = Display.getDefault(); - if (startIndex < 0) { - rank = (int) fTrace.getNbEvents() - 1; - } else if (startIndex >= (fTable.getItemCount() - (eventFilter == null ? 1 : 3))) { // -1 for header row, -2 for top and bottom filter status rows - rank = 0; - } else { - int idx = startIndex; - while (foundRank == -1) { - final CachedEvent event = fCache.peekEvent(idx); - if (event == null) { - break; - } - rank = event.rank; - if (searchFilter.matches(event.event) && ((eventFilter == null) || eventFilter.matches(event.event))) { - foundRank = event.rank; - foundTimestamp = event.event.getTimestamp(); - break; - } - if (direction == Direction.FORWARD) { - idx++; - } else { - idx--; - } - } - if (foundRank == -1) { - if (direction == Direction.FORWARD) { - rank++; - if (rank > (fTrace.getNbEvents() - 1)) { - rank = 0; - } - } else { - rank--; - if (rank < 0) { - rank = (int) fTrace.getNbEvents() - 1; - } - } - } - } - final int startRank = (int) rank; - boolean wrapped = false; - while (!monitor.isCanceled() && (foundRank == -1) && (fTrace != null)) { - int nbRequested = (direction == Direction.FORWARD ? Integer.MAX_VALUE : Math.min((int) rank + 1, fTrace.getCacheSize())); - if (direction == Direction.BACKWARD) { - rank = Math.max(0, rank - fTrace.getCacheSize() + 1); - } - request = new TmfEventRequest(ITmfEvent.class, TmfTimeRange.ETERNITY, - (int) rank, nbRequested, ExecutionType.BACKGROUND) { - long currentRank = rank; - - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - if (searchFilter.matches(event) && ((eventFilter == null) || eventFilter.matches(event))) { - foundRank = currentRank; - foundTimestamp = event.getTimestamp(); - if (direction == Direction.FORWARD) { - done(); - return; - } - } - currentRank++; - } - }; - ((ITmfEventProvider) fTrace).sendRequest(request); - try { - request.waitForCompletion(); - if (request.isCancelled()) { - return Status.OK_STATUS; - } - } catch (final InterruptedException e) { - synchronized (fSearchSyncObj) { - fSearchThread = null; - } - return Status.OK_STATUS; - } - if (foundRank == -1) { - if (direction == Direction.FORWARD) { - if (rank == 0) { - synchronized (fSearchSyncObj) { - fSearchThread = null; - } - return Status.OK_STATUS; - } - nbRequested = (int) rank; - rank = 0; - wrapped = true; - } else { - rank--; - if (rank < 0) { - rank = (int) fTrace.getNbEvents() - 1; - wrapped = true; - } - if ((rank <= startRank) && wrapped) { - synchronized (fSearchSyncObj) { - fSearchThread = null; - } - return Status.OK_STATUS; - } - } - } - } - int index = (int) foundRank; - if (eventFilter != null) { - index = fCache.getFilteredEventIndex(foundRank); - } - final int selection = index + 1 + (eventFilter != null ? +1 : 0); // +1 for header row, +1 for top filter status row - - display.asyncExec(new Runnable() { - @Override - public void run() { - if (monitor.isCanceled()) { - return; - } - if (fTable.isDisposed()) { - return; - } - fTable.setSelection(selection); - fSelectedRank = foundRank; - fRawViewer.selectAndReveal(fSelectedRank); - if (foundTimestamp != null) { - broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, foundTimestamp)); - } - fireSelectionChanged(new SelectionChangedEvent(TmfEventsTable.this, getSelection())); - synchronized (fSearchSyncObj) { - fSearchThread = null; - } - updateStatusLine(null); - } - }); - return Status.OK_STATUS; - } - - @Override - protected void canceling() { - request.cancel(); - synchronized (fSearchSyncObj) { - fSearchThread = null; - } - } - } - - /** - * Create the resources. - */ - protected void createResources() { - fGrayColor = fResourceManager.createColor(ColorUtil.blend(fTable.getBackground().getRGB(), fTable - .getForeground().getRGB())); - fGreenColor = fTable.getDisplay().getSystemColor(SWT.COLOR_DARK_GREEN); - fBoldFont = fResourceManager.createFont(FontDescriptor.createFrom(fTable.getFont()).setStyle(SWT.BOLD)); - } - - /** - * Pack the columns. - */ - protected void packColumns() { - if (fPackDone) { - return; - } - fTable.setRedraw(false); - try { - TableColumn tableColumns[] = fTable.getColumns(); - for (int i = 0; i < tableColumns.length; i++) { - final TableColumn column = tableColumns[i]; - packSingleColumn(i, column); - } - } finally { - // Make sure that redraw is always enabled. - fTable.setRedraw(true); - } - fPackDone = true; - } - - - private void packMarginColumn() { - TableColumn[] columns = fTable.getColumns(); - if (columns.length > 0) { - packSingleColumn(0, columns[0]); - } - } - - private void packSingleColumn(int i, final TableColumn column) { - final int headerWidth = column.getWidth(); - column.pack(); - // Workaround for Linux which doesn't consider the image width of - // search/filter row in TableColumn.pack() after having executed - // TableItem.setImage((Image)null) for other rows than search/filter row. - boolean isCollapseFilter = fTable.getData(Key.FILTER_OBJ) instanceof TmfCollapseFilter; - if (IS_LINUX && (i == 0) && isCollapseFilter) { - column.setWidth(column.getWidth() + SEARCH_IMAGE.getBounds().width); - } - - if (column.getWidth() < headerWidth) { - column.setWidth(headerWidth); - } - } - - /** - * Get the array of item strings (e.g., what to display in each cell of the - * table row) corresponding to the columns and trace event passed in - * parameter. The order of the Strings in the returned array will correspond - * to the iteration order of 'columns'. - * - *

- * To ensure consistent results, make sure only call this within a scope - * synchronized on 'columns'! If the order of 'columns' changes right after - * this method is called, the returned value won't be ordered correctly - * anymore. - */ - private static String[] getItemStrings(List columns, ITmfEvent event) { - if (event == null) { - return EMPTY_STRING_ARRAY; - } - synchronized (columns) { - List itemStrings = new ArrayList<>(columns.size()); - for (TmfEventTableColumn column : columns) { - ITmfEvent passedEvent = event; - if (!(column instanceof TmfMarginColumn) && (event instanceof CachedEvent)) { - // Make sure that the event object from the trace is passed - // to all columns but the TmfMarginColumn - passedEvent = ((CachedEvent) event).event; - } - if (passedEvent == null) { - itemStrings.add(EMPTY_STRING); - } else { - itemStrings.add(column.getItemString(passedEvent)); - } - - } - return itemStrings.toArray(new String[0]); - } - } - - /** - * Get the contents of the row in the events table corresponding to an - * event. The order of the elements corresponds to the current order of the - * columns. - * - * @param event - * The event printed in this row - * @return The event row entries - * @since 3.0 - */ - public String[] getItemStrings(ITmfEvent event) { - return getItemStrings(fColumns, event); - } - - /** - * Notify this table that is got the UI focus. - */ - public void setFocus() { - fTable.setFocus(); - } - - /** - * Assign a new trace to this event table. - * - * @param trace - * The trace to assign to this event table - * @param disposeOnClose - * true if the trace should be disposed when the table is - * disposed - */ - public void setTrace(final ITmfTrace trace, final boolean disposeOnClose) { - if ((fTrace != null) && fDisposeOnClose) { - fTrace.dispose(); - } - fTrace = trace; - fPackDone = false; - fSelectedRank = 0; - fDisposeOnClose = disposeOnClose; - - // Perform the updates on the UI thread - fTable.getDisplay().syncExec(new Runnable() { - @Override - public void run() { - fTable.removeAll(); - fCache.setTrace(fTrace); // Clear the cache - if (fTrace != null) { - if (!fTable.isDisposed() && (fTrace != null)) { - if (fTable.getData(Key.FILTER_OBJ) == null) { - fTable.setItemCount((int) fTrace.getNbEvents() + 1); // +1 for header row - } else { - stopFilterThread(); - fFilterMatchCount = 0; - fFilterCheckCount = 0; - fTable.setItemCount(3); // +1 for header row, +2 for top and bottom filter status rows - startFilterThread(); - } - } - } - fRawViewer.setTrace(fTrace); - } - }); - } - - /** - * Assign the status line manager - * - * @param statusLineManager - * The status line manager, or null to disable status line messages - * @since 2.1 - */ - public void setStatusLineManager(IStatusLineManager statusLineManager) { - if (fStatusLineManager != null && statusLineManager == null) { - fStatusLineManager.setMessage(EMPTY_STRING); - } - fStatusLineManager = statusLineManager; - } - - private void updateStatusLine(ITmfTimestamp delta) { - if (fStatusLineManager != null) { - if (delta != null) { - fStatusLineManager.setMessage("\u0394: " + delta); //$NON-NLS-1$ - } else { - fStatusLineManager.setMessage(null); - } - } - } - - // ------------------------------------------------------------------------ - // Event cache - // ------------------------------------------------------------------------ - - /** - * Notify that the event cache has been updated - * - * @param completed - * Also notify if the populating of the cache is complete, or - * not. - */ - public void cacheUpdated(final boolean completed) { - synchronized (fCacheUpdateSyncObj) { - if (fCacheUpdateBusy) { - fCacheUpdatePending = true; - fCacheUpdateCompleted = completed; - return; - } - fCacheUpdateBusy = true; - } - // Event cache is now updated. Perform update on the UI thread - if (!fTable.isDisposed()) { - fTable.getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - if (!fTable.isDisposed()) { - fTable.refresh(); - packColumns(); - } - if (completed) { - populateCompleted(); - } - synchronized (fCacheUpdateSyncObj) { - fCacheUpdateBusy = false; - if (fCacheUpdatePending) { - fCacheUpdatePending = false; - cacheUpdated(fCacheUpdateCompleted); - } - } - } - }); - } - } - - /** - * Callback for when populating the table is complete. - */ - protected void populateCompleted() { - // Nothing by default; - } - - // ------------------------------------------------------------------------ - // ISelectionProvider - // ------------------------------------------------------------------------ - - /** - * @since 2.0 - */ - @Override - public void addSelectionChangedListener(ISelectionChangedListener listener) { - selectionChangedListeners.add(listener); - } - - /** - * @since 2.0 - */ - @Override - public ISelection getSelection() { - if (fTable == null || fTable.isDisposed()) { - return StructuredSelection.EMPTY; - } - List list = new ArrayList<>(fTable.getSelection().length); - for (TableItem item : fTable.getSelection()) { - if (item.getData() != null) { - list.add(item.getData()); - } - } - return new StructuredSelection(list); - } - - /** - * @since 2.0 - */ - @Override - public void removeSelectionChangedListener(ISelectionChangedListener listener) { - selectionChangedListeners.remove(listener); - } - - /** - * @since 2.0 - */ - @Override - public void setSelection(ISelection selection) { - // not implemented - } - - /** - * Notifies any selection changed listeners that the viewer's selection has changed. - * Only listeners registered at the time this method is called are notified. - * - * @param event a selection changed event - * - * @see ISelectionChangedListener#selectionChanged - * @since 2.0 - */ - protected void fireSelectionChanged(final SelectionChangedEvent event) { - Object[] listeners = selectionChangedListeners.getListeners(); - for (int i = 0; i < listeners.length; ++i) { - final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i]; - SafeRunnable.run(new SafeRunnable() { - @Override - public void run() { - l.selectionChanged(event); - } - }); - } - } - - // ------------------------------------------------------------------------ - // Bookmark handling - // ------------------------------------------------------------------------ - - /** - * Add a bookmark to this event table. - * - * @param bookmarksFile - * The file to use for the bookmarks - */ - public void addBookmark(final IFile bookmarksFile) { - fBookmarksFile = bookmarksFile; - final TableItem[] selection = fTable.getSelection(); - if (selection.length > 0) { - final TableItem tableItem = selection[0]; - if (tableItem.getData(Key.RANK) != null) { - final StringBuffer defaultMessage = new StringBuffer(); - for (int i = 0; i < fTable.getColumns().length; i++) { - if (i > 0) { - defaultMessage.append(", "); //$NON-NLS-1$ - } - defaultMessage.append(tableItem.getText(i)); - } - final InputDialog dialog = new MultiLineInputDialog( - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), - Messages.TmfEventsTable_AddBookmarkDialogTitle, - Messages.TmfEventsTable_AddBookmarkDialogMessage, - defaultMessage.toString()); - if (dialog.open() == Window.OK) { - final String message = dialog.getValue(); - try { - final IMarker bookmark = bookmarksFile.createMarker(IMarker.BOOKMARK); - if (bookmark.exists()) { - bookmark.setAttribute(IMarker.MESSAGE, message.toString()); - final Long rank = (Long) tableItem.getData(Key.RANK); - final int location = rank.intValue(); - bookmark.setAttribute(IMarker.LOCATION, Integer.valueOf(location)); - fBookmarksMap.put(rank, bookmark.getId()); - fTable.refresh(); - } - } catch (final CoreException e) { - displayException(e); - } - } - } - } - - } - - /** - * Remove a bookmark from this event table. - * - * @param bookmark - * The bookmark to remove - */ - public void removeBookmark(final IMarker bookmark) { - for (final Entry entry : fBookmarksMap.entries()) { - if (entry.getValue().equals(bookmark.getId())) { - fBookmarksMap.remove(entry.getKey(), entry.getValue()); - fTable.refresh(); - return; - } - } - } - - private void toggleBookmark(final Long rank) { - if (fBookmarksFile == null) { - return; - } - if (fBookmarksMap.containsKey(rank)) { - final Collection markerIds = fBookmarksMap.removeAll(rank); - fTable.refresh(); - try { - for (long markerId : markerIds) { - final IMarker bookmark = fBookmarksFile.findMarker(markerId); - if (bookmark != null) { - bookmark.delete(); - } - } - } catch (final CoreException e) { - displayException(e); - } - } else { - addBookmark(fBookmarksFile); - } - } - - /** - * Refresh the bookmarks assigned to this trace, from the contents of a - * bookmark file. - * - * @param bookmarksFile - * The bookmark file to use - */ - public void refreshBookmarks(final IFile bookmarksFile) { - fBookmarksFile = bookmarksFile; - if (bookmarksFile == null) { - fBookmarksMap.clear(); - fTable.refresh(); - return; - } - try { - fBookmarksMap.clear(); - for (final IMarker bookmark : bookmarksFile.findMarkers(IMarker.BOOKMARK, false, IResource.DEPTH_ZERO)) { - final int location = bookmark.getAttribute(IMarker.LOCATION, -1); - if (location != -1) { - final long rank = location; - fBookmarksMap.put(rank, bookmark.getId()); - } - } - fTable.refresh(); - } catch (final CoreException e) { - displayException(e); - } - } - - @Override - public void gotoMarker(final IMarker marker) { - final int rank = marker.getAttribute(IMarker.LOCATION, -1); - if (rank != -1) { - int index = rank; - if (fTable.getData(Key.FILTER_OBJ) != null) { - index = fCache.getFilteredEventIndex(rank) + 1; // +1 for top filter status row - } else if (rank >= fTable.getItemCount()) { - fPendingGotoRank = rank; - } - fSelectedRank = rank; - fTable.setSelection(index + 1); // +1 for header row - updateStatusLine(null); - } - } - - // ------------------------------------------------------------------------ - // Listeners - // ------------------------------------------------------------------------ - - @Override - public void colorSettingsChanged(final ColorSetting[] colorSettings) { - fTable.refresh(); - } - - // ------------------------------------------------------------------------ - // Signal handlers - // ------------------------------------------------------------------------ - - /** - * Handler for the trace updated signal - * - * @param signal - * The incoming signal - */ - @TmfSignalHandler - public void traceUpdated(final TmfTraceUpdatedSignal signal) { - if ((signal.getTrace() != fTrace) || fTable.isDisposed()) { - return; - } - // Perform the refresh on the UI thread - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - if (!fTable.isDisposed() && (fTrace != null)) { - if (fTable.getData(Key.FILTER_OBJ) == null) { - fTable.setItemCount((int) fTrace.getNbEvents() + 1); // +1 for header row - if ((fPendingGotoRank != -1) && ((fPendingGotoRank + 1) < fTable.getItemCount())) { // +1 for header row - fTable.setSelection((int) fPendingGotoRank + 1); // +1 for header row - fPendingGotoRank = -1; - updateStatusLine(null); - } - } else { - startFilterThread(); - } - } - if (!fRawViewer.isDisposed() && (fTrace != null)) { - fRawViewer.refreshEventCount(); - } - } - }); - } - - /** - * Handler for the time synch signal. - * - * @param signal - * The incoming signal - */ - @TmfSignalHandler - public void currentTimeUpdated(final TmfTimeSynchSignal signal) { - if ((signal.getSource() != this) && (fTrace != null) && (!fTable.isDisposed())) { - - // Create a request for one event that will be queued after other ongoing requests. When this request is completed - // do the work to select the actual event with the timestamp specified in the signal. This procedure prevents - // the method fTrace.getRank() from interfering and delaying ongoing requests. - final TmfEventRequest subRequest = new TmfEventRequest(ITmfEvent.class, - TmfTimeRange.ETERNITY, 0, 1, ExecutionType.FOREGROUND) { - - TmfTimestamp ts = new TmfTimestamp(signal.getBeginTime()); - - @Override - public void handleData(final ITmfEvent event) { - super.handleData(event); - } - - @Override - public void handleCompleted() { - super.handleCompleted(); - if (fTrace == null) { - return; - } - - // Verify if the event is within the trace range and adjust if necessary - ITmfTimestamp timestamp = ts; - if (timestamp.compareTo(fTrace.getStartTime(), true) == -1) { - timestamp = fTrace.getStartTime(); - } - if (timestamp.compareTo(fTrace.getEndTime(), true) == 1) { - timestamp = fTrace.getEndTime(); - } - - // Get the rank of the selected event in the table - final ITmfContext context = fTrace.seekEvent(timestamp); - final long rank = context.getRank(); - context.dispose(); - fSelectedRank = rank; - - fTable.getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - // Return if table is disposed - if (fTable.isDisposed()) { - return; - } - - int index = (int) rank; - if (fTable.isDisposed()) { - return; - } - if (fTable.getData(Key.FILTER_OBJ) != null) { - index = fCache.getFilteredEventIndex(rank) + 1; // +1 for top filter status row - } - fTable.setSelection(index + 1); // +1 for header row - fRawViewer.selectAndReveal(rank); - updateStatusLine(null); - } - }); - } - }; - - ((ITmfEventProvider) fTrace).sendRequest(subRequest); - } - } - - // ------------------------------------------------------------------------ - // Error handling - // ------------------------------------------------------------------------ - - /** - * Display an exception in a message box - * - * @param e the exception - */ - private static void displayException(final Exception e) { - final MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()); - mb.setText(e.getClass().getSimpleName()); - mb.setMessage(e.getMessage()); - mb.open(); - } - - /** - * @since 2.0 - */ - public void refresh() { - fCache.clear(); - fTable.refresh(); - fTable.redraw(); - } - - /** - * Margin column for images and special text (e.g. collapse count) - */ - private static final class TmfMarginColumn extends TmfEventTableColumn { - - private static final @NonNull String HEADER = EMPTY_STRING; - - /** - * Constructor - */ - public TmfMarginColumn() { - super(HEADER); - } - - @Override - public String getItemString(ITmfEvent event) { - if (!(event instanceof CachedEvent) || ((CachedEvent) event).repeatCount == 0) { - return EMPTY_STRING; - } - return "+" + ((CachedEvent) event).repeatCount; //$NON-NLS-1$ - } - - @Override - public String getFilterFieldId() { - return null; - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/columns/ITmfEventTableColumns.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/columns/ITmfEventTableColumns.java deleted file mode 100644 index 7ca21dadd7..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/columns/ITmfEventTableColumns.java +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.events.columns; - -import java.util.Collection; - -import org.eclipse.jdt.annotation.NonNull; - -/** - * This class allows a trace type to specify which columns it wants to display - * in the Event Table. The "function" to populate the column for any given event - * is defined in each {@link TmfEventTableColumn}. - * - * @author Alexandre Montplaisir - * @since 3.2 - */ -public interface ITmfEventTableColumns { - - /** - * Return the columns specified by this trace type. - * - * The iteration order of the returned collection will correspond to the - * initial order of these columns in the view (from left to right). - *

- * Note to implementers: - *

- * Even if many traces of the same type can be opened at the same time, the - * column objects can (and probably should) be singleton instances. This - * means you do not need to create new column objects every time this method - * is called. - * - * @return The Event Table columns advertised by this trace type - */ - @NonNull Collection getEventTableColumns(); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/columns/TmfEventTableColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/columns/TmfEventTableColumn.java deleted file mode 100644 index 6069620d73..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/columns/TmfEventTableColumn.java +++ /dev/null @@ -1,159 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.events.columns; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.internal.tmf.ui.viewers.events.columns.TmfContentsColumn; -import org.eclipse.linuxtools.internal.tmf.ui.viewers.events.columns.TmfReferenceColumn; -import org.eclipse.linuxtools.internal.tmf.ui.viewers.events.columns.TmfSourceColumn; -import org.eclipse.linuxtools.internal.tmf.ui.viewers.events.columns.TmfTimestampColumn; -import org.eclipse.linuxtools.internal.tmf.ui.viewers.events.columns.TmfTypeColumn; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; - -/** - * A column in the - * {@link org.eclipse.linuxtools.tmf.ui.viewers.events.TmfEventsTable}. In - * addition to ones provided by default, trace types can extend this class to - * create additional columns specific to their events. - * - * Those additional columns can then be passed to the constructor - * {@link org.eclipse.linuxtools.tmf.ui.viewers.events.TmfEventsTable#TmfEventsTable(org.eclipse.swt.widgets.Composite, int, java.util.Collection)} - * - * @author Alexandre Montplaisir - * @since 3.1 - */ -@NonNullByDefault -public abstract class TmfEventTableColumn { - - // ------------------------------------------------------------------------ - // Class attributes - // ------------------------------------------------------------------------ - - /** - * The base set of columns, which can apply to any trace type. - */ - public static interface BaseColumns { - - /** Column showing the event timestamp */ - TmfEventTableColumn TIMESTAMP = new TmfTimestampColumn(); - - /** Column showing the event's source */ - TmfEventTableColumn SOURCE = new TmfSourceColumn(); - - /** Column showing the event type */ - TmfEventTableColumn EVENT_TYPE = new TmfTypeColumn(); - - /** Column showing the event reference */ - TmfEventTableColumn REFERENCE = new TmfReferenceColumn(); - - /** Column showing the aggregated event contents (fields) */ - TmfEventTableColumn CONTENTS = new TmfContentsColumn(); - } - - /** - * Static definition of an empty string. Return this instead of returning - * 'null'! - */ - protected static final String EMPTY_STRING = ""; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Fields - // ------------------------------------------------------------------------ - - private final String fHeaderName; - private final @Nullable String fHeaderTooltip; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructor with no tooltip. - * - * @param headerName - * The name (title) of this column. Should ideally be short. - */ - public TmfEventTableColumn(String headerName) { - fHeaderName = headerName; - fHeaderTooltip = null; - } - - /** - * Constructor with a tooltip. - * - * @param headerName - * The name (title) of this column. Should ideally be short. - * @param headerTooltip - * The tooltip text for the column header. Use 'null' for no - * tooltip. - */ - public TmfEventTableColumn(String headerName, @Nullable String headerTooltip) { - fHeaderName = headerName; - fHeaderTooltip = headerTooltip; - } - - // ------------------------------------------------------------------------ - // Getters - // ------------------------------------------------------------------------ - - /** - * Get this column's header name, a.k.a. title - * - * @return The column's title - */ - public String getHeaderName() { - return fHeaderName; - } - - /** - * Get the tooltip text for the column header - * - * @return The header's tooltip - */ - public @Nullable String getHeaderTooltip() { - return fHeaderTooltip; - } - - // ------------------------------------------------------------------------ - // Abstract methods - // ------------------------------------------------------------------------ - - /** - * Get the string that should be displayed in this column's cell for a given - * trace event. Basically, this defines "what to print in this column for - * this event". - *

- * Note to implementers: - *

- * This method takes an {@link ITmfEvent}, because any type of event could - * potentially be present in the table at the time. Do not assume that you - * will only receive events of your trace type. You'd probably want to - * return an empty string for event that don't match your expected class - * type here. - * - * @param event - * The trace event whose element we want to display - * @return The string to display in the column for this event - */ - public abstract String getItemString(ITmfEvent event); - - /** - * Return the FILTER_ID used by the filters to search this column. - * - * @return The filter ID for this column, or 'null' to not provide a filter - * ID (which will mean this column will probably not be - * searchable/filterable.) - */ - public abstract @Nullable String getFilterFieldId(); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/columns/TmfEventTableFieldColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/columns/TmfEventTableFieldColumn.java deleted file mode 100644 index fbbaed70cc..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/columns/TmfEventTableFieldColumn.java +++ /dev/null @@ -1,114 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.events.columns; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; - -/** - * Event table column that will print the value of a given event field, and - * whose column name is also the same as that field. - * - * @author Alexandre Montplaisir - * @since 3.1 - */ -@NonNullByDefault -public class TmfEventTableFieldColumn extends TmfEventTableColumn { - - private final String fFieldName; - - /** - * Basic constructor, which uses the same name for the field name and the - * column header. - * - * @param headerAndFieldName - * The string that is both the title of the column AND the field - * name to look for. - */ - public TmfEventTableFieldColumn(String headerAndFieldName) { - super(headerAndFieldName); - fFieldName = headerAndFieldName; - } - - /** - * Advanced constructor, which can define different field name and header. - * You can also define a tooltip, optionally. - * - * @param headerName - * The header (title) of the column - * @param fieldName - * The field name to look for in the event content to populate - * this column. - * @param headerTooltip - * The tooltip text for the column header. Use 'null' for no - * tooltip. - */ - public TmfEventTableFieldColumn(String headerName, String fieldName, - @Nullable String headerTooltip) { - super(headerName, headerTooltip); - fFieldName = fieldName; - } - - @Override - public final String getItemString(ITmfEvent event) { - ITmfEventField field = event.getContent().getField(fFieldName); - if (field == null) { - return EMPTY_STRING; - } - String val = field.getFormattedValue(); - return (val == null ? EMPTY_STRING : val); - } - - @Override - public @NonNull String getFilterFieldId() { - return fFieldName; - } - - // ------------------------------------------------------------------------ - // hashCode/equals (so that equivalent columns can be merged together) - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + fFieldName.hashCode(); - result = prime * result + getHeaderName().hashCode(); - return result; - } - - @Override - public boolean equals(@Nullable Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof TmfEventTableFieldColumn)) { - return false; - } - TmfEventTableFieldColumn other = (TmfEventTableFieldColumn) obj; - if (!fFieldName.equals(other.fFieldName)) { - return false; - } - if (!getHeaderName().equals(other.getHeaderName())) { - return false; - } - return true; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/text/TmfTextEventTable.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/text/TmfTextEventTable.java deleted file mode 100644 index 4238413fb4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/text/TmfTextEventTable.java +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.events.text; - -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.trace.text.TextTraceEvent; -import org.eclipse.linuxtools.tmf.core.trace.text.TextTraceEventContent; -import org.eclipse.linuxtools.tmf.ui.viewers.events.TmfEventsTable; -import org.eclipse.linuxtools.tmf.ui.widgets.virtualtable.ColumnData; -import org.eclipse.swt.widgets.Composite; - -/** - * Event table for text traces, which has one column for every event field. - * - * @author Alexandre Montplaisir - * @since 3.0 - * @deprecated Users of this class should instead use - * {@link TmfEventsTable#TmfEventsTable(Composite, int, java.util.Collection)} - * , by passing - * {@link org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn} - * or - * {@link org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableFieldColumn} - * . - */ -@Deprecated -public class TmfTextEventTable extends TmfEventsTable { - - /** - * Constructor - * - * @param parent - * The parent composite UI object - * @param cacheSize - * The size of the event table cache - * @param columnData - * The column data to use for this table - */ - public TmfTextEventTable(Composite parent, int cacheSize, ColumnData[] columnData) { - super(parent, cacheSize, columnData); - } - - /** - * @param event - * The event to get the column strings for. It should be an - * instance of {@link TextTraceEvent}. - */ - @Override - public String[] getItemStrings(ITmfEvent event) { - if (event instanceof TextTraceEvent) { - List fields = ((TextTraceEvent) event).getContent().getFields(); - String[] strings = new String[fields.size()]; - for (int i = 0; i < strings.length; i++) { - Object value = fields.get(i).getValue(); - strings[i] = (value == null ? EMPTY_STRING : value.toString()); - } - return strings; - } - return EMPTY_STRING_ARRAY; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/Messages.java deleted file mode 100644 index a9c23b4226..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/Messages.java +++ /dev/null @@ -1,39 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial API and Implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.statistics; - -import org.eclipse.osgi.util.NLS; - -/** - * Messages file for statistics view strings. - * - * @author Mathieu Denis - * @since 2.0 - */ -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.ui.viewers.statistics.messages"; //$NON-NLS-1$ - - /** - * String for unknown trace name. - */ - public static String TmfStatisticsView_UnknownTraceName; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/TmfStatisticsViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/TmfStatisticsViewer.java deleted file mode 100644 index 5099779119..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/TmfStatisticsViewer.java +++ /dev/null @@ -1,799 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial API and implementation - * Alexandre Montplaisir - Port to ITmfStatistics provider - * Patrick Tasse - Support selection range - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.statistics; - -import java.util.List; -import java.util.Map; - -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.TreeViewerColumn; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerComparator; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.tmf.core.component.TmfComponent; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal; -import org.eclipse.linuxtools.tmf.core.statistics.ITmfStatistics; -import org.eclipse.linuxtools.tmf.core.statistics.TmfStatisticsEventTypesModule; -import org.eclipse.linuxtools.tmf.core.statistics.TmfStatisticsModule; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ui.TmfUiRefreshHandler; -import org.eclipse.linuxtools.tmf.ui.viewers.TmfViewer; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfBaseColumnData; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfBaseColumnDataProvider; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsFormatter; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTree; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTreeManager; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfTreeContentProvider; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; - -/** - * A basic viewer to display statistics in the statistics view. - * - * It is linked to a single ITmfTrace until its disposal. - * - * @author Mathieu Denis - * @since 2.0 - */ -public class TmfStatisticsViewer extends TmfViewer { - - /** Timestamp scale used for all statistics (nanosecond) */ - private static final byte TIME_SCALE = ITmfTimestamp.NANOSECOND_SCALE; - - /** The delay (in ms) between each update in live-reading mode */ - private static final long LIVE_UPDATE_DELAY = 1000; - - /** The actual tree viewer to display */ - private TreeViewer fTreeViewer; - - /** The statistics tree linked to this viewer */ - private TmfStatisticsTree fStatisticsData; - - /** Update range synchronization object */ - private final Object fStatisticsRangeUpdateSyncObj = new Object(); - - /** The trace that is displayed by this viewer */ - private ITmfTrace fTrace; - - /** Indicates to process all events */ - private boolean fProcessAll; - - /** View instance counter (for multiple statistics views) */ - private static int fCountInstance = 0; - - /** Number of this instance. Used as an instance ID. */ - private int fInstanceNb; - - /** Object to store the cursor while waiting for the trace to load */ - private Cursor fWaitCursor = null; - - /** - * Counts the number of times waitCursor() has been called. It avoids - * removing the waiting cursor, since there may be multiple requests running - * at the same time. - */ - private int fWaitCursorCount = 0; - - /** Tells to send a time range request when the trace gets updated. */ - private boolean fSendRangeRequest = true; - - /** Reference to the trace manager */ - private final TmfTraceManager fTraceManager; - - /** - * Create a basic statistics viewer. To be used in conjunction with - * {@link TmfStatisticsViewer#init(Composite, String, ITmfTrace)} - * - * @param parent - * The parent composite that will hold the viewer - * @param viewerName - * The name that will be assigned to this viewer - * @param trace - * The trace that is displayed by this viewer - * @see TmfComponent - */ - public TmfStatisticsViewer(Composite parent, String viewerName, ITmfTrace trace) { - init(parent, viewerName, trace); - fTraceManager = TmfTraceManager.getInstance(); - } - - /** - * Initialize the statistics viewer. - * - * @param parent - * The parent component of the viewer. - * @param viewerName - * The name to give to the viewer. - * @param trace - * The trace that will be displayed by the viewer. - */ - public void init(Composite parent, String viewerName, ITmfTrace trace) { - super.init(parent, viewerName); - // Increment a counter to make sure the tree ID is unique. - fCountInstance++; - fInstanceNb = fCountInstance; - fTrace = trace; - - // The viewer will process all events if he is assigned to an experiment - fProcessAll = (trace instanceof TmfExperiment); - - initContent(parent); - initInput(); - } - - @Override - public void dispose() { - super.dispose(); - if (fWaitCursor != null) { - fWaitCursor.dispose(); - } - - // Clean the model for this viewer - TmfStatisticsTreeManager.removeStatTreeRoot(getTreeID()); - } - - // ------------------------------------------------------------------------ - // Signal handlers - // ------------------------------------------------------------------------ - - /** - * Handles the signal about new trace range. - * - * @param signal - * The trace range updated signal - */ - @TmfSignalHandler - public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal) { - ITmfTrace trace = signal.getTrace(); - // validate - if (!isListeningTo(trace)) { - return; - } - - synchronized (fStatisticsRangeUpdateSyncObj) { - // Sends the time range request only once from this method. - if (fSendRangeRequest) { - fSendRangeRequest = false; - ITmfTimestamp begin = fTraceManager.getSelectionBeginTime(); - ITmfTimestamp end = fTraceManager.getSelectionEndTime(); - TmfTimeRange timeRange = new TmfTimeRange(begin, end); - requestTimeRangeData(trace, timeRange); - } - } - requestData(trace, signal.getRange()); - } - - /** - * Handles the time synch updated signal. It updates the time range - * statistics. - * - * @param signal - * Contains the information about the new selected time range. - * @since 2.1 - */ - @TmfSignalHandler - public void timeSynchUpdated(TmfTimeSynchSignal signal) { - if (fTrace == null) { - return; - } - ITmfTimestamp begin = signal.getBeginTime(); - ITmfTimestamp end = signal.getEndTime(); - TmfTimeRange timeRange = new TmfTimeRange(begin, end); - requestTimeRangeData(fTrace, timeRange); - } - - // ------------------------------------------------------------------------ - // Class methods - // ------------------------------------------------------------------------ - - /* - * Returns the primary control associated with this viewer. - * - * @return the SWT control which displays this viewer's content - */ - @Override - public Control getControl() { - return fTreeViewer.getControl(); - } - - /** - * Get the input of the viewer. - * - * @return an object representing the input of the statistics viewer. - */ - public Object getInput() { - return fTreeViewer.getInput(); - } - - /** - * This method can be overridden to implement another way of representing - * the statistics data and to retrieve the information for display. - * - * @return a TmfStatisticsData object. - */ - public TmfStatisticsTree getStatisticData() { - if (fStatisticsData == null) { - fStatisticsData = new TmfStatisticsTree(); - } - return fStatisticsData; - } - - /** - * Returns a unique ID based on name to be associated with the statistics - * tree for this viewer. For a same name, it will always return the same ID. - * - * @return a unique statistics tree ID. - */ - public String getTreeID() { - return getName() + fInstanceNb; - } - - @Override - public void refresh() { - final Control viewerControl = getControl(); - // Ignore update if disposed - if (viewerControl.isDisposed()) { - return; - } - - TmfUiRefreshHandler.getInstance().queueUpdate(this, new Runnable() { - @Override - public void run() { - if (!viewerControl.isDisposed()) { - fTreeViewer.refresh(); - } - } - }); - } - - /** - * Will force a request on the partial event count if one is needed. - */ - public void sendPartialRequestOnNextUpdate() { - synchronized (fStatisticsRangeUpdateSyncObj) { - fSendRangeRequest = true; - } - } - - /** - * Focus on the statistics tree of the viewer - */ - public void setFocus() { - fTreeViewer.getTree().setFocus(); - } - - /** - * Cancels the request if it is not already completed - * - * @param request - * The request to be canceled - * @since 3.0 - */ - protected void cancelOngoingRequest(ITmfEventRequest request) { - if (request != null && !request.isCompleted()) { - request.cancel(); - } - } - - /** - * This method can be overridden to change the representation of the data in - * the columns. - * - * @return An object of type {@link TmfBaseColumnDataProvider}. - * @since 3.0 - */ - protected TmfBaseColumnDataProvider getColumnDataProvider() { - return new TmfBaseColumnDataProvider(); - } - - /** - * Initialize the content that will be drawn in this viewer - * - * @param parent - * The parent of the control to create - */ - protected void initContent(Composite parent) { - final List columnDataList = getColumnDataProvider().getColumnData(); - - fTreeViewer = new TreeViewer(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); - fTreeViewer.setContentProvider(new TmfTreeContentProvider()); - fTreeViewer.getTree().setHeaderVisible(true); - fTreeViewer.setUseHashlookup(true); - - // Creates the columns defined by the column data provider - for (final TmfBaseColumnData columnData : columnDataList) { - final TreeViewerColumn treeColumn = new TreeViewerColumn(fTreeViewer, columnData.getAlignment()); - treeColumn.getColumn().setText(columnData.getHeader()); - treeColumn.getColumn().setWidth(columnData.getWidth()); - treeColumn.getColumn().setToolTipText(columnData.getTooltip()); - - // If is dummy column - if (columnData == columnDataList.get(TmfBaseColumnDataProvider.StatsColumn.DUMMY.getIndex())) { - treeColumn.getColumn().setResizable(false); - } - - // A comparator is defined. - if (columnData.getComparator() != null) { - // Adds a listener on the columns header for sorting purpose. - treeColumn.getColumn().addSelectionListener(new SelectionAdapter() { - - private ViewerComparator reverseComparator; - - @Override - public void widgetSelected(SelectionEvent e) { - // Initializes the reverse comparator once. - if (reverseComparator == null) { - reverseComparator = new ViewerComparator() { - @Override - public int compare(Viewer viewer, Object e1, Object e2) { - return -1 * columnData.getComparator().compare(viewer, e1, e2); - } - }; - } - - if (fTreeViewer.getTree().getSortDirection() == SWT.UP - || fTreeViewer.getTree().getSortColumn() != treeColumn.getColumn()) { - /* - * Puts the descendant order if the old order was up - * or if the selected column has changed. - */ - fTreeViewer.setComparator(columnData.getComparator()); - fTreeViewer.getTree().setSortDirection(SWT.DOWN); - } else { - /* - * Puts the ascendant ordering if the selected - * column hasn't changed. - */ - fTreeViewer.setComparator(reverseComparator); - fTreeViewer.getTree().setSortDirection(SWT.UP); - } - fTreeViewer.getTree().setSortColumn(treeColumn.getColumn()); - } - }); - } - treeColumn.setLabelProvider(columnData.getLabelProvider()); - } - - // Handler that will draw the percentages and the bar charts. - fTreeViewer.getTree().addListener(SWT.EraseItem, new Listener() { - @Override - public void handleEvent(Event event) { - if (columnDataList.get(event.index).getPercentageProvider() != null) { - - TmfStatisticsTreeNode node = (TmfStatisticsTreeNode) event.item.getData(); - - // If node is hidden, exit immediately. - if (TmfBaseColumnDataProvider.HIDDEN_FOLDER_LEVELS.contains(node.getName())) { - return; - } - - // Otherwise, get percentage and draw bar and text if applicable. - double percentage = columnDataList.get(event.index).getPercentageProvider().getPercentage(node); - - // The item is selected. - if ((event.detail & SWT.SELECTED) > 0) { - // Draws our own background to avoid overwriting the bar. - event.gc.fillRectangle(event.x, event.y, event.width, event.height); - event.detail &= ~SWT.SELECTED; - } - - // Drawing the percentage text - // if events are present in top node - // and the current node is not the top node - // and if is total or partial events column. - // If not, exit the method. - if (!((event.index == TmfBaseColumnDataProvider.StatsColumn.TOTAL.getIndex() || event.index == TmfBaseColumnDataProvider.StatsColumn.PARTIAL.getIndex()) - && node != node.getTop())) { - return; - } - - long eventValue = event.index == TmfBaseColumnDataProvider.StatsColumn.TOTAL.getIndex() ? - node.getTop().getValues().getTotal() : node.getTop().getValues().getPartial(); - - if (eventValue != 0) { - - int oldAlpha = event.gc.getAlpha(); - Color oldForeground = event.gc.getForeground(); - Color oldBackground = event.gc.getBackground(); - - // Bar to draw - if (percentage != 0) { - /* - * Draws a transparent gradient rectangle from the - * color of foreground and background. - */ - int barWidth = (int) ((fTreeViewer.getTree().getColumn(event.index).getWidth() - 8) * percentage); - event.gc.setAlpha(64); - event.gc.setForeground(event.item.getDisplay().getSystemColor(SWT.COLOR_BLUE)); - event.gc.setBackground(event.item.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - event.gc.fillGradientRectangle(event.x, event.y, barWidth, event.height, true); - event.gc.drawRectangle(event.x, event.y, barWidth, event.height); - - // Restore old values - event.gc.setBackground(oldBackground); - event.gc.setAlpha(oldAlpha); - event.detail &= ~SWT.BACKGROUND; - - } - - String percentageText = TmfStatisticsFormatter.toPercentageText(percentage); - String absoluteNumberText = TmfStatisticsFormatter.toColumnData(node, TmfBaseColumnDataProvider.StatsColumn.getColumn(event.index)); - - if (event.width > event.gc.stringExtent(percentageText).x + event.gc.stringExtent(absoluteNumberText).x) { - int textHeight = event.gc.stringExtent(percentageText).y; - event.gc.setForeground(event.item.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY)); - event.gc.drawText(percentageText, event.x, event.y + (event.height - textHeight) / 2, true); - } - - // Restores old values - event.gc.setForeground(oldForeground); - - } - } - } - - }); - - // Initializes the comparator parameters - fTreeViewer.setComparator(columnDataList.get(0).getComparator()); - fTreeViewer.getTree().setSortColumn(fTreeViewer.getTree().getColumn(0)); - fTreeViewer.getTree().setSortDirection(SWT.DOWN); - } - - /** - * Initializes the input for the tree viewer. - */ - protected void initInput() { - String treeID = getTreeID(); - TmfStatisticsTreeNode statisticsTreeNode; - if (TmfStatisticsTreeManager.containsTreeRoot(treeID)) { - // The statistics root is already present - statisticsTreeNode = TmfStatisticsTreeManager.getStatTreeRoot(treeID); - - // Checks if the trace is already in the statistics tree. - int numNodeTraces = statisticsTreeNode.getNbChildren(); - - ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace); - int numTraces = traces.length; - - if (numTraces == numNodeTraces) { - boolean same = true; - /* - * Checks if the experiment contains the same traces as when - * previously selected. - */ - for (int i = 0; i < numTraces; i++) { - String traceName = traces[i].getName(); - if (!statisticsTreeNode.containsChild(traceName)) { - same = false; - break; - } - } - - if (same) { - // No need to reload data, all traces are already loaded - fTreeViewer.setInput(statisticsTreeNode); - return; - } - // Clears the old content to start over - statisticsTreeNode.reset(); - } - } else { - // Creates a new tree - statisticsTreeNode = TmfStatisticsTreeManager.addStatsTreeRoot(treeID, getStatisticData()); - } - - // Sets the input to a clean data model - fTreeViewer.setInput(statisticsTreeNode); - } - - /** - * Tells if the viewer is listening to a trace. - * - * @param trace - * The trace that the viewer may be listening - * @return true if the viewer is listening to the trace, false otherwise - */ - protected boolean isListeningTo(ITmfTrace trace) { - if (fProcessAll || trace == fTrace) { - return true; - } - return false; - } - - /** - * Called when an trace request has been completed successfully. - * - * @param global - * Tells if the request is a global or time range (partial) - * request. - */ - protected void modelComplete(boolean global) { - refresh(); - waitCursor(false); - } - - /** - * Called when an trace request has failed or has been cancelled. - * - * @param isGlobalRequest - * Tells if the request is a global or time range (partial) - * request. - */ - protected void modelIncomplete(boolean isGlobalRequest) { - if (isGlobalRequest) { // Clean the global statistics - /* - * No need to reset the global number of events, since the index of - * the last requested event is known. - */ - } else { // Clean the partial statistics - resetTimeRangeValue(); - } - refresh(); - waitCursor(false); - } - - /** - * Sends the request to the trace for the whole trace - * - * @param trace - * The trace used to send the request - * @param timeRange - * The range to request to the trace - */ - protected void requestData(final ITmfTrace trace, final TmfTimeRange timeRange) { - buildStatisticsTree(trace, timeRange, true); - } - - /** - * Sends the time range request from the trace - * - * @param trace - * The trace used to send the request - * @param timeRange - * The range to request to the trace - */ - protected void requestTimeRangeData(final ITmfTrace trace, final TmfTimeRange timeRange) { - buildStatisticsTree(trace, timeRange, false); - } - - /** - * Requests all the data of the trace to the state system which contains - * information about the statistics. - * - * Since the viewer may be listening to multiple traces, it may receive an - * experiment rather than a single trace. The filtering is done with the - * method {@link #isListeningTo(String trace)}. - * - * @param trace - * The trace for which a request must be done - * @param timeRange - * The time range that will be requested to the state system - * @param isGlobal - * Tells if the request is for the global event count or the - * partial one. - */ - private void buildStatisticsTree(final ITmfTrace trace, final TmfTimeRange timeRange, final boolean isGlobal) { - final TmfStatisticsTreeNode statTree = TmfStatisticsTreeManager.getStatTreeRoot(getTreeID()); - final TmfStatisticsTree statsData = TmfStatisticsTreeManager.getStatTree(getTreeID()); - if (statsData == null) { - return; - } - - synchronized (statsData) { - if (isGlobal) { - statTree.resetGlobalValue(); - } else { - statTree.resetTimeRangeValue(); - } - - for (final ITmfTrace aTrace : TmfTraceManager.getTraceSet(trace)) { - if (!isListeningTo(aTrace)) { - continue; - } - - /* Retrieve the statistics object */ - final TmfStatisticsModule statsMod = aTrace.getAnalysisModuleOfClass(TmfStatisticsModule.class, TmfStatisticsModule.ID); - if (statsMod == null) { - /* No statistics module available for this trace */ - continue; - } - - /* Run the potentially long queries in a separate thread */ - Thread statsThread = new Thread("Statistics update") { //$NON-NLS-1$ - @Override - public void run() { - /* Wait until the analysis is ready to be queried */ - statsMod.waitForInitialization(); - ITmfStatistics stats = statsMod.getStatistics(); - if (stats == null) { - /* It should have worked, but didn't */ - throw new IllegalStateException(); - } - - /* - * The generic statistics are stored in nanoseconds, so - * we must make sure the time range is scaled correctly. - */ - long start = timeRange.getStartTime().normalize(0, TIME_SCALE).getValue(); - long end = timeRange.getEndTime().normalize(0, TIME_SCALE).getValue(); - - /* - * Wait on the state system object we are going to query. - * - * TODO Eventually this could be exposed through the - * TmfStateSystemAnalysisModule directly. - */ - ITmfStateSystem ss = statsMod.getStateSystem(TmfStatisticsEventTypesModule.ID); - if (ss == null) { - /* - * It should be instantiated after the - * statsMod.waitForInitialization() above. - */ - throw new IllegalStateException(); - } - - /* - * Periodically update the statistics while they are - * being built (or, if the back-end is already - * completely built, it will skip over the while() immediately. - */ - while (!ss.waitUntilBuilt(LIVE_UPDATE_DELAY)) { - Map map = stats.getEventTypesInRange(start, end); - updateStats(aTrace, isGlobal, map); - } - /* Query one last time for the final values */ - Map map = stats.getEventTypesInRange(start, end); - updateStats(aTrace, isGlobal, map); - } - }; - statsThread.start(); - } - } - } - - /* - * Update statistics for a given trace - */ - private void updateStats(ITmfTrace trace, boolean isGlobal, Map eventsPerType) { - - final TmfStatisticsTree statsData = TmfStatisticsTreeManager.getStatTree(getTreeID()); - if (statsData == null) { - /* The stat tree has been disposed, abort mission. */ - return; - } - - Map map = eventsPerType; - String name = trace.getName(); - - - /* - * "Global", "partial", "total", etc., it's all very confusing... - * - * The base view shows the total count for the trace and for - * each even types, organized in columns like this: - * - * | Global | Time range | - * trace name | A | B | - * Event Type | | | - * | C | D | - * | ... | ... | - * ... | | | - * - * Here, we called the cells like this: - * A : GlobalTotal - * B : TimeRangeTotal - * C : GlobalTypeCount(s) - * D : TimeRangeTypeCount(s) - */ - - /* Fill in an the event counts (either cells C or D) */ - for (Map.Entry entry : map.entrySet()) { - statsData.setTypeCount(name, entry.getKey(), isGlobal, entry.getValue()); - } - - /* - * Calculate the totals (cell A or B, depending if isGlobal). We will - * use the results of the previous request instead of sending another - * one. - */ - long globalTotal = 0; - for (long val : map.values()) { - globalTotal += val; - } - statsData.setTotal(name, isGlobal, globalTotal); - - modelComplete(isGlobal); - } - - /** - * Resets the number of events within the time range - */ - protected void resetTimeRangeValue() { - TmfStatisticsTreeNode treeModelRoot = TmfStatisticsTreeManager.getStatTreeRoot(getTreeID()); - if (treeModelRoot != null && treeModelRoot.hasChildren()) { - treeModelRoot.resetTimeRangeValue(); - } - } - - /** - * When the trace is loading the cursor will be different so the user knows - * that the processing is not finished yet. - * - * Calls to this method are stacked. - * - * @param waitRequested - * Indicates if we need to show the waiting cursor, or the - * default one. - */ - protected void waitCursor(final boolean waitRequested) { - if ((fTreeViewer == null) || (fTreeViewer.getTree().isDisposed())) { - return; - } - - boolean needsUpdate = false; - Display display = fTreeViewer.getControl().getDisplay(); - if (waitRequested) { - fWaitCursorCount++; - if (fWaitCursor == null) { // The cursor hasn't been initialized yet - fWaitCursor = new Cursor(display, SWT.CURSOR_WAIT); - } - if (fWaitCursorCount == 1) { // The cursor is not in waiting mode - needsUpdate = true; - } - } else { - if (fWaitCursorCount > 0) { // The cursor is in waiting mode - fWaitCursorCount--; - if (fWaitCursorCount == 0) { // No more reason to wait - // Put back the default cursor - needsUpdate = true; - } - } - } - - if (needsUpdate) { - // Performs the updates on the UI thread - display.asyncExec(new Runnable() { - @Override - public void run() { - if ((fTreeViewer != null) - && (!fTreeViewer.getTree().isDisposed())) { - Cursor cursor = null; // indicates default - if (waitRequested) { - cursor = fWaitCursor; - } - fTreeViewer.getControl().setCursor(cursor); - } - } - }); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/messages.properties deleted file mode 100644 index c522f0aa1a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/messages.properties +++ /dev/null @@ -1,13 +0,0 @@ -############################################################################### -# Copyright (c) 2013 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### - -TmfStatisticsView_UnknownTraceName=Unknown_Trace \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/Messages.java deleted file mode 100755 index 7cabd61e23..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/Messages.java +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial API and Implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.statistics.model; - -import org.eclipse.osgi.util.NLS; - -/** - * Message strings for the statistics framework. - * - * @version 2.0 - * @author Mathieu Denis - * @since 2.0 - */ -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.messages"; //$NON-NLS-1$ - - /** - * CPU statistic name. - */ - public static String TmfStatisticsData_CPUs; - - /** - * Event type statistic name. - */ - public static String TmfStatisticsData_EventTypes; - - /** - * Level column name - */ - public static String TmfStatisticsView_LevelColumn; - - /** - * Level column tool tip. - */ - public static String TmfStatisticsView_LevelColumnTip; - - /** - * Number of events column name. - */ - public static String TmfStatisticsView_NbEventsColumn; - - /** - * Number of events column tool tip. - */ - public static String TmfStatisticsView_NbEventsTip; - - /** - * Partial number of events column. - * @since 2.0 - */ - public static String TmfStatisticsView_NbEventsTimeRangeColumn; - - /** - * Partial number of events column tool tip. - * @since 2.0 - */ - public static String TmfStatisticsView_NbEventsTimeRangeTip; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfBaseColumnData.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfBaseColumnData.java deleted file mode 100755 index 804e1f23f5..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfBaseColumnData.java +++ /dev/null @@ -1,178 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial Implementation - * Bernd Hufmann - Added Annotations - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.statistics.model; - -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.ViewerComparator; - -/** - * Contains all the information necessary to build a column of the table. - * - * @author Mathieu Denis - * @since 2.0 - */ -public class TmfBaseColumnData { - - /** - * Name of the column. - */ - private final String fHeader; - - /** - * Width of the column. - */ - private final int fWidth; - - /** - * Alignment of the column. - */ - private final int fAlignment; - - /** - * Tooltip of the column. - */ - private final String fTooltip; - - /** - * Adapts a StatisticsTreeNode into the content of it's corresponding cell - * for that column. - */ - private final ColumnLabelProvider fLabelProvider; - - /** - * Used to sort elements of this column. Can be null. - */ - private final @Nullable ViewerComparator fComparator; - - /** - * Used to draw bar charts in this column. Can be null. - */ - private final @Nullable ITmfColumnPercentageProvider fPercentageProvider; - - /** - * Used to draw bar charts in columns. - */ - public interface ITmfColumnPercentageProvider { - - /** - * Percentage provider - * - * @param node - * The statistics tree node - * @return The value as a percentage - */ - public double getPercentage(TmfStatisticsTreeNode node); - } - - /** - * Constructor with parameters - * - * @param h - * header of the column. The name will be shown at the top of the - * column. - * @param w - * width of the column. - * @param a - * alignment of the text - * @param t - * text to shown as a tooltip when the cursor comes over the - * header - * @param l - * provide all the column element - * @param c - * used to compare element between them to be able to classify - * the content of the columns - * @param p - * provide the percentage of a specific element - */ - public TmfBaseColumnData(String h, int w, int a, String t, - ColumnLabelProvider l, ViewerComparator c, - ITmfColumnPercentageProvider p) { - fHeader = h; - fWidth = w; - fAlignment = a; - fTooltip = t; - fLabelProvider = l; - fComparator = c; - fPercentageProvider = p; - } - - /** - * Return the column name. - * - * @return the name of the column. - */ - public String getHeader() { - return fHeader; - } - - /** - * Return the width of the column at the creation. - * - * @return the width of the column. - */ - public int getWidth() { - return fWidth; - } - - /** - * Return the alignment of the column. - * - * @see org.eclipse.swt.SWT - * @return an integer representing the alignment inside the column. - */ - public int getAlignment() { - return fAlignment; - } - - /** - * Provide the text to show in the tooltip when the cursor comes over the - * column header. - * - * @return text to show in the tooltip - */ - public String getTooltip() { - return fTooltip; - } - - /** - * Return the labelProvider which provides the information to put in column - * cells. - * - * @return a ColumnLabelProvider. - */ - public ColumnLabelProvider getLabelProvider() { - return fLabelProvider; - } - - /** - * Return a ViewerComparator used to sort viewer's contents. - * - * @return the comparator. - */ - public ViewerComparator getComparator() { - return fComparator; - } - - /** - * Return the provider of the percentage. Used to draw bar charts in - * columns. - * - * @return the percentageProvider. - */ - public ITmfColumnPercentageProvider getPercentageProvider() { - return fPercentageProvider; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfBaseColumnDataProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfBaseColumnDataProvider.java deleted file mode 100755 index 53fb004b04..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfBaseColumnDataProvider.java +++ /dev/null @@ -1,289 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Implementation and Initial API - * Vincent Perot - Add percentages to the label provider - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.statistics.model; - -import java.util.List; -import java.util.Set; - -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerComparator; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfBaseColumnData.ITmfColumnPercentageProvider; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.ui.ISharedImages; -import org.eclipse.ui.PlatformUI; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; - -/** - * Create a basic list of columns with providers. - * - * @author Mathieu Denis - * @since 3.0 - */ -public class TmfBaseColumnDataProvider { - - // ------------------------------------------------------------------------ - // Localized strings - // ------------------------------------------------------------------------ - - /** Level column names */ - private static final String LEVEL_COLUMN = Messages.TmfStatisticsView_LevelColumn; - - /** Number of events column names */ - private static final String EVENTS_COUNT_COLUMN = Messages.TmfStatisticsView_NbEventsColumn; - - /** Number of events in time range column names */ - private static final String PARTIAL_EVENTS_COUNT_COLUMN = Messages.TmfStatisticsView_NbEventsTimeRangeColumn; - - /** Level column tooltips */ - private static final String LEVEL_COLUMN_TIP = Messages.TmfStatisticsView_LevelColumnTip; - - /** Number of events column tooltips */ - private static final String EVENTS_COUNT_COLUMN_TIP = Messages.TmfStatisticsView_NbEventsTip; - - /** Number of events in time range column tooltips */ - private static final String PARTIAL_COUNT_COLUMN_TIP = Messages.TmfStatisticsView_NbEventsTimeRangeTip; - - // ------------------------------------------------------------------------ - // Class attributes - // ------------------------------------------------------------------------ - - /** - * Level for which statistics should not be displayed. - * - * @since 3.0 - */ - public static final Set HIDDEN_FOLDER_LEVELS = ImmutableSet.of("Event Types"); //$NON-NLS-1$ - - private static final String EMPTY_STRING = ""; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Column index (Ideally, this should not be hardcoded). - // ------------------------------------------------------------------------ - - /** - * Possible columns in the view - * - * @since 3.0 - */ - public static enum StatsColumn { - /** - * Column index for the event type column. - */ - EVENT(0), - /** - * Column index for the event total count column. - */ - TOTAL(1), - /** - * Column index for the event partial count column. - */ - PARTIAL(2), - /** - * Column index for the dummy column. - */ - DUMMY(3); - - private final int colIndex; - - private StatsColumn(int index) { - colIndex = index; - } - - /** - * Getter method for the column index. - * - * @return the index of the column - */ - public int getIndex() { - return colIndex; - } - - /** - * Method to get the column at a certain index. - * - * @param index the index of the column - * - * @return the column at the specified index - */ - public static StatsColumn getColumn(int index) { - switch(index) { - case 0: - return EVENT; - - case 1: - return TOTAL; - - case 2: - return PARTIAL; - - case 3: - return DUMMY; - - // Other values are illegal. - default: - throw new IllegalArgumentException(); - } - - } - } - - // ------------------------------------------------------------------------ - // Instance fields - // ------------------------------------------------------------------------ - - /** - * Contains the list of the columns - */ - private final List fColumnData; - - /** - * Create basic columns to represent the statistics data - */ - public TmfBaseColumnDataProvider() { - /* List that will be used to create the table. */ - ImmutableList.Builder builder = new ImmutableList.Builder<>(); - /* Column showing the name of the events and its level in the tree */ - builder.add(new TmfBaseColumnData( - LEVEL_COLUMN, - 200, - SWT.LEFT, - LEVEL_COLUMN_TIP, - new ColumnLabelProvider() { - @Override - public String getText(Object element) { - return ((TmfStatisticsTreeNode) element).getName(); - } - - @Override - public Image getImage(Object element) { - TmfStatisticsTreeNode node = (TmfStatisticsTreeNode) element; - if (HIDDEN_FOLDER_LEVELS.contains(node.getName())) { - return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER); - } - return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT); - } - }, - new ViewerComparator() { - @Override - public int compare(Viewer viewer, Object e1, Object e2) { - TmfStatisticsTreeNode n1 = (TmfStatisticsTreeNode) e1; - TmfStatisticsTreeNode n2 = (TmfStatisticsTreeNode) e2; - - return n1.getName().compareTo(n2.getName()); - } - }, - null)); - - /* Column showing the total number of events */ - builder.add(new TmfBaseColumnData( - EVENTS_COUNT_COLUMN, - 140, - SWT.RIGHT, - EVENTS_COUNT_COLUMN_TIP, - new ColumnLabelProvider() { - @Override - public String getText(Object element) { - TmfStatisticsTreeNode node = (TmfStatisticsTreeNode) element; - if (!HIDDEN_FOLDER_LEVELS.contains(node.getName())) { - return TmfStatisticsFormatter.toColumnData(node, StatsColumn.TOTAL); - } - return EMPTY_STRING; - } - }, - new ViewerComparator() { - @Override - public int compare(Viewer viewer, Object e1, Object e2) { - TmfStatisticsTreeNode n1 = (TmfStatisticsTreeNode) e1; - TmfStatisticsTreeNode n2 = (TmfStatisticsTreeNode) e2; - - return (int) (n1.getValues().getTotal() - n2.getValues().getTotal()); - } - }, - new ITmfColumnPercentageProvider() { - @Override - public double getPercentage(TmfStatisticsTreeNode node) { - TmfStatisticsTreeNode top = node.getTop(); - return (top == null || top.getValues().getTotal() == 0) ? - 0 : (double) (node.getValues().getTotal()) / top.getValues().getTotal(); - } - })); - - /* Column showing the number of events within the selected time range */ - builder.add(new TmfBaseColumnData( - PARTIAL_EVENTS_COUNT_COLUMN, - 140, - SWT.RIGHT, - PARTIAL_COUNT_COLUMN_TIP, - new ColumnLabelProvider() { - @Override - public String getText(Object element) { - TmfStatisticsTreeNode node = (TmfStatisticsTreeNode) element; - if (!HIDDEN_FOLDER_LEVELS.contains(node.getName())) { - return TmfStatisticsFormatter.toColumnData(node, StatsColumn.PARTIAL); - } - return EMPTY_STRING; - } - - }, - new ViewerComparator() { - @Override - public int compare(Viewer viewer, Object e1, Object e2) { - TmfStatisticsTreeNode n1 = (TmfStatisticsTreeNode) e1; - TmfStatisticsTreeNode n2 = (TmfStatisticsTreeNode) e2; - - return (int) (n1.getValues().getPartial() - n2.getValues().getPartial()); - } - }, - new ITmfColumnPercentageProvider() { - @Override - public double getPercentage(TmfStatisticsTreeNode node) { - TmfStatisticsTreeNode top = node.getTop(); - return (top == null || top.getValues().getPartial() == 0) ? - 0 : (double) (node.getValues().getPartial()) / top.getValues().getPartial(); - } - })); - - /* Dummy column used to "fix" the display on Linux (using GTK) */ - builder.add(new TmfBaseColumnData(EMPTY_STRING, 1, SWT.RIGHT, EMPTY_STRING, - new ColumnLabelProvider() { - @Override - public String getText(Object element) { - return EMPTY_STRING; - } - }, - new ViewerComparator(), - new ITmfColumnPercentageProvider() { - @Override - public double getPercentage(TmfStatisticsTreeNode node) { - return 0; - } - })); - - fColumnData = builder.build(); - } - - /** - * Return a list of the column created for the view - * - * @return columns list - */ - public List getColumnData() { - return fColumnData; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsFormatter.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsFormatter.java deleted file mode 100644 index 7ac6da0296..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsFormatter.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Vincent Perot - Add percentages to the label provider - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.statistics.model; - -import java.text.NumberFormat; -import java.util.Locale; - -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfBaseColumnDataProvider.StatsColumn; - -/** - * Class that format data for cells in the statistics view. - * - * @author Vincent Perot - * @since 3.0 - */ -public final class TmfStatisticsFormatter { - - /** - * Formatter for the column data - */ - private static final NumberFormat FORMATTER = NumberFormat.getNumberInstance(Locale.getDefault()); - - TmfStatisticsFormatter() { - // Nothing to construct. - } - - /** - * Generate the string for display in a cell. - * - * @param node - * Current node. - * @param config - * Configuration between total and partial. - * @return The formatted string ready for display. - */ - public static String toColumnData(TmfStatisticsTreeNode node, StatsColumn config) { - - long eventValue = 0; - - switch (config) { - - case TOTAL: - eventValue = node.getValues().getTotal(); - break; - - case PARTIAL: - eventValue = node.getValues().getPartial(); - break; - - // Other values are illegal. - // $CASES-OMITTED$ - default: - throw new IllegalArgumentException(); - } - - return FORMATTER.format(eventValue); - } - - /** - * Format the percentage according to user settings. - * - * @param percentage - * the percentage to format - * @return The formated percentage as a string. - */ - public static String toPercentageText(double percentage) { - - // The cast to long is needed because the formatter cannot truncate the number. - double truncPercentage = ((long) (1000.0 * percentage)) / 10.0; - - String percentageString = String.format("%s%s%s", " ", FORMATTER.format(truncPercentage), " % "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - return percentageString; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsTree.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsTree.java deleted file mode 100755 index 509f98a91c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsTree.java +++ /dev/null @@ -1,171 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Implementation and Initial API - * Alexandre Montplaisir - Merge TmfBaseStatisticsTree and AbsStatisticsTree - * Move the tree structure logic into the nodes - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.statistics.model; - - -/** - * Base class for the statistics storage. It allow to implement a tree structure - * while avoiding the need to run through the tree each time you need to add a - * node at a given place. - * - * @author Mathieu Denis - * @version 2.0 - * @since 2.0 - */ -public class TmfStatisticsTree { - - /** Header for the event type categories. */ - public static final String HEADER_EVENT_TYPES = Messages.TmfStatisticsData_EventTypes; - - /** Root node of this tree */ - private final TmfStatisticsTreeNode rootNode; - - /** - * Default constructor. Creates base statistics tree for counting total - * number of events and number of events per event type. - */ - public TmfStatisticsTree() { - rootNode = new TmfStatisticsTreeNode(this, null, new String[0]); - } - - /** - * Retrieve the root node of this tree. - * - * @return The root node - */ - public TmfStatisticsTreeNode getRootNode() { - return rootNode; - } - - /** - * Get a node. - * - * @param path - * Path to the node. - * @return The node, or null if it doesn't current exist in the tree. - */ - public TmfStatisticsTreeNode getNode(String... path) { - TmfStatisticsTreeNode curNode = rootNode; - for (String pathElem : path) { - curNode = curNode.getChild(pathElem); - if (curNode == null) { - /* The requested path doesn't exist, return null */ - break; - } - } - return curNode; - } - - /** - * Get or create a node. - * - * @param path - * Path to the node. - * @return The requested node. Will be created if it didn't exist. - */ - public TmfStatisticsTreeNode getOrCreateNode(String... path) { - TmfStatisticsTreeNode curNode = rootNode; - TmfStatisticsTreeNode nextNode; - for (String pathElem : path) { - nextNode = curNode.getChild(pathElem); - if (nextNode == null) { - nextNode = curNode.addChild(pathElem); - } - curNode = nextNode; - } - return curNode; - } - - /** - * Set the value to display in the "total" cells. This means the row - * indicating the total count of events for a trace. - * - * @param traceName - * The name of the trace (will be used as a sub-tree in the view) - * @param isGlobal - * Is this a for a global or a time range request? Determines if - * this goes in the Global column or the Selected Time Range one. - * @param qty - * The value to display - */ - public void setTotal(String traceName, boolean isGlobal, long qty) { - String[][] paths = getNormalPaths(traceName); - for (String path[] : paths) { - getOrCreateNode(path).getValues().setValue(isGlobal, qty); - } - } - - /** - * Set the value to display in the "Type count" cells. These are the counts - * for each event types. - * - * @param traceName - * The name of the trace (will be used as a sub-tree in the view) - * @param type - * The event type - * @param isGlobal - * Is this a for a global or a time range request? Determines if - * this goes in the Global column or the Selected Time Range one. - * @param qty - * The value to display - */ - public void setTypeCount(String traceName, String type, boolean isGlobal, long qty) { - String[][] paths = getTypePaths(traceName, type); - for (String[] path : paths) { - getOrCreateNode(path).getValues().setValue(isGlobal, qty); - } - } - - /** - * Get the event types paths. - * - * @param traceName - * The name of the trace (will be used as a sub-tree in the view) - * @param type - * The event type - * @return Array of arrays representing the paths - */ - protected String[][] getTypePaths(String traceName, String type) { - String[][] paths = { new String[] {traceName, HEADER_EVENT_TYPES, type } }; - return paths; - } - - /** - * Get the standard paths for an event. - * - * @param traceName - * The name of the trace (will be used as a sub-tree in the view) - * @return Array of arrays representing the paths - */ - protected String[][] getNormalPaths(String traceName) { - String[][] paths = { new String[] { traceName } }; - return paths; - } - - /** - * Function to merge many string more efficiently. - * - * @param strings - * Strings to merge. - * @return A new string containing all the strings. - */ - protected static String mergeString(String... strings) { - StringBuilder builder = new StringBuilder(); - for (String s : strings) { - builder.append(s); - } - return builder.toString(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsTreeManager.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsTreeManager.java deleted file mode 100755 index 33e794cd8f..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsTreeManager.java +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.statistics.model; - -import java.util.HashMap; -import java.util.Map; - -/** - * Factory class to create and store TMF statistic trees. - * - * Based on a given tree node ID a TMF statistic tree is stored internally. A - * root node is created for each tree. Using the tree node ID the statistics - * tree can be retrieved. - * - * @author Mathieu Denis - * @version 2.0 - * @since 2.0 - */ -public class TmfStatisticsTreeManager { - - /** - * Contains the experiment name as the key and the traces data - */ - private static final Map fTreeInstances = new HashMap<>(); - - /** - * Provide a statisticsTree instance per trace - * - * @param traceUniqueId - * Unique ID for the trace - * @return The root node of the corresponding trace statistics tree - */ - public static TmfStatisticsTreeNode getStatTreeRoot(String traceUniqueId) { - - TmfStatisticsTree tree = getStatTree(traceUniqueId); - if (tree == null) { - return null; - } - return tree.getRootNode(); - } - - /** - * Get the tree that's being used for statistics - * - * @param traceUniqueId - * Unique ID for the trace - * @return the corresponding trace statistics tree - */ - public static TmfStatisticsTree getStatTree(String traceUniqueId) { - if (traceUniqueId == null) { - return null; - } - - TmfStatisticsTree tree = fTreeInstances.get(traceUniqueId); - return tree; - } - - /** - * Add the new trace statistics data in the tree. Can be used later on if - * the same traces is selected back. - * - * @param traceUniqueId - * The name of the trace which will be used as a key to store the - * data. Must be different for each traces, otherwise the traces - * might be overwritten which would trigger a reload of the same - * trace. - * @param statsData - * The information about the trace - * @return The newly created root node of the trace statistics tree, or null if something went wrong - */ - public static TmfStatisticsTreeNode addStatsTreeRoot(String traceUniqueId, TmfStatisticsTree statsData) { - if (traceUniqueId == null || statsData == null) { - return null; - } - fTreeInstances.put(traceUniqueId, statsData); - return statsData.getRootNode(); - } - - /** - * Return if the given trace is currently known by the statistics manager. - * - * @param traceUniqueId - * The unique ID of the trace - * @return true if the trace id is known - */ - public static boolean containsTreeRoot(String traceUniqueId) { - return fTreeInstances.containsKey(traceUniqueId); - } - - /** - * Remove previously registered statistics tree. - * - * @param traceUniqueId - * The unique ID of the trace - */ - public static void removeStatTreeRoot(String traceUniqueId) { - if (traceUniqueId != null && fTreeInstances.containsKey(traceUniqueId)) { - fTreeInstances.remove(traceUniqueId); - } - } - - /** - * Remove all tree and root instances - */ - public static void removeAll() { - fTreeInstances.clear(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsTreeNode.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsTreeNode.java deleted file mode 100755 index a43bcbee75..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsTreeNode.java +++ /dev/null @@ -1,252 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Yann N. Dauphin - Implementation for stats - * Francois Godin - Re-design for new stats structure - * Mathieu Denis - Re-design for new stats structure (2) - * Alexandre Montplaisir - Move the tree structure logic into the nodes - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.statistics.model; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * A tree where nodes can be accessed efficiently using paths. - * - * It works like file systems. Each node is identified by a key. A path is an - * array of String. The elements of the array represent the path from the root - * to this node. - * - * @author Mathieu Denis - * @version 2.0 - * @since 2.0 - */ -public class TmfStatisticsTreeNode { - - /** Tree to which this node belongs */ - private final TmfStatisticsTree fTree; - - /** Path of this node. The last element represents its basename. */ - private final String[] fPath; - - /** Parent node */ - private final TmfStatisticsTreeNode fParent; - - /** Children of this node, indexed by their basename. */ - private final Map fChildren; - - /** Statistics values associated to this node. */ - private final TmfStatisticsValues fValues; - - /** - * Return the node at the top of the branch - */ - private final TmfStatisticsTreeNode fTopNode; - - /** - * Constructor. - * - * @param tree - * Owner tree of this node - * @param parent - * Parent node of this one - * @param path - * Path to the node. - */ - public TmfStatisticsTreeNode(TmfStatisticsTree tree, - TmfStatisticsTreeNode parent, final String... path) { - /* - * The path must not contain any null element, or else we won't be able - * to walk the tree. - */ - for (String elem : path) { - if (elem == null) { - throw new IllegalArgumentException(); - } - } - - fTree = tree; - fPath = path; - fParent = parent; - fChildren = new ConcurrentHashMap<>(); - fValues = new TmfStatisticsValues(); - - /* calculating top node */ - TmfStatisticsTreeNode topNode = this; - while (topNode.getParent() != null && topNode.getParent().getParent() != null) { - topNode = topNode.getParent(); - } - fTopNode = topNode; - } - - /** - * Get the name for this node. It's used as the key in the parent's node. - * - * @return Name of this node. - */ - public String getName() { - if (fPath.length == 0) { - /* This means we are the root node, which has no path itself */ - return "root"; //$NON-NLS-1$ - } - return fPath[fPath.length - 1]; - } - - /** - * Test if a node contain the specified child. - * - * @param childName - * Name of the child. - * @return true: if child with given key is present, false: if no child - * exists with given key name - */ - public boolean containsChild(String childName) { - return fChildren.containsKey(childName); - } - - /** - * Retrieve the given child from this node. - * - * @param childName - * The (base)name of the child you want - * @return The child object, or null if it doesn't exist - */ - public TmfStatisticsTreeNode getChild(String childName) { - return fChildren.get(childName); - } - - /** - * Get the children of this node. - * - * @return Direct children of this node. - */ - public Collection getChildren() { - return fChildren.values(); - } - - /** - * Add a child to this node. - * - * @param childName - * Name of the child to add - * @return The newly-created child - */ - public TmfStatisticsTreeNode addChild(String childName) { - TmfStatisticsTreeNode child; - String[] childPath = new String[fPath.length + 1]; - System.arraycopy(fPath, 0, childPath, 0, fPath.length); - childPath[fPath.length] = childName; - - child = new TmfStatisticsTreeNode(this.fTree, this, childPath); - fChildren.put(childName, child); - return child; - } - - /** - * Get the number of children this node have. - * - * @return Number of direct children of this node. - */ - public int getNbChildren() { - return fChildren.size(); - } - - /** - * Return the parent node. - * - * @return Parent node. - */ - public TmfStatisticsTreeNode getParent() { - return fParent; - } - - /** - * Return the top node. - * - * @return Top node. - * @since 3.0 - */ - public TmfStatisticsTreeNode getTop() { - return fTopNode; - } - - /** - * Get the path of the node. - * - * @return The path of the node. - */ - public String[] getPath() { - return fPath; - } - - /** - * Get the value of this node. - * - * @return Value associated with this node. - */ - public TmfStatisticsValues getValues() { - return fValues; - } - - /** - * Indicate if the node have children. - * - * @return True if the node has children. - */ - public boolean hasChildren() { - return (fChildren.size() > 0); - } - - /** - * Start from creation time i.e. keep key and parent but new statistics and - * no children. - */ - public void reset() { - fValues.resetTotalCount(); - fValues.resetPartialCount(); - fChildren.clear(); - } - - /** - * Resets the global number of events. It doesn't remove any node and - * doesn't modify the partial event count. Works recursively. - * - * @since 2.0 - */ - public void resetGlobalValue() { - for (TmfStatisticsTreeNode child : fChildren.values()) { - child.resetGlobalValue(); - } - fValues.resetTotalCount(); - } - - /** - * Resets the number of events in the time range. It doesn't remove any node - * and doesn't modify the global event count. Works recursively. - * - * @since 2.0 - */ - public void resetTimeRangeValue() { - for (TmfStatisticsTreeNode child : fChildren.values()) { - child.resetTimeRangeValue(); - } - fValues.resetPartialCount(); - } - - @Override - public String toString() { - /* Used for debugging only */ - return "Stats node, path = " + Arrays.toString(fPath) + //$NON-NLS-1$ - ", values = " + fValues.toString(); //$NON-NLS-1$ - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsValues.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsValues.java deleted file mode 100755 index b1fa4d0c46..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfStatisticsValues.java +++ /dev/null @@ -1,90 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Intial API and Implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.statistics.model; - -/** - * Primitive container for Statistics values. - * - * Contains information about statistics that can be retrieved with any type of - * traces. - * - * There are two counters : one for the total number of events in the trace, and - * another for the number of events in the selected time range. - * - * @author Mathieu Denis - * @version 2.0 - * @since 2.0 - */ -public class TmfStatisticsValues { - - /** - * Total number of events. - */ - protected long fNbEvents = 0; - - /** - * Number of events within a time range (Partial event count). - */ - protected long fNbEventsInTimeRange = 0; - - /** - * @return the total events count - */ - public long getTotal() { - return fNbEvents; - } - - /** - * @return the partial events count within a time range - */ - public long getPartial() { - return fNbEventsInTimeRange; - } - - /** - * Set either the "global" or the "time range" value. - * - * @param global - * True to set the global value, false for the timerange one. - * @param nb - * The new value to set - */ - public void setValue(boolean global, long nb) { - if (nb > 0) { - if (global) { - fNbEvents = nb; - } else { - fNbEventsInTimeRange = nb; - } - } - } - - /** - * Resets the total number of events. - */ - public void resetTotalCount() { - fNbEvents = 0; - } - - /** - * Resets the number of events within a time range (partial events count). - */ - public void resetPartialCount() { - fNbEventsInTimeRange = 0; - } - - @Override - public String toString() { - return fNbEvents + ", " + fNbEventsInTimeRange; //$NON-NLS-1$ - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfTreeContentProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfTreeContentProvider.java deleted file mode 100755 index 645f33fd61..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/TmfTreeContentProvider.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.statistics.model; - -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; - -/** - * Adapter TreeViewers can use to interact with StatisticsTreeNode objects. - * - * @version 2.0 - * @since 2.0 - * @author Mathieu Denis - * @see org.eclipse.jface.viewers.ITreeContentProvider - */ -public class TmfTreeContentProvider implements ITreeContentProvider { - - @Override - public Object[] getChildren(Object parentElement) { - return ((TmfStatisticsTreeNode) parentElement).getChildren().toArray(); - } - - @Override - public Object getParent(Object element) { - return ((TmfStatisticsTreeNode) element).getParent(); - } - - @Override - public boolean hasChildren(Object element) { - return ((TmfStatisticsTreeNode) element).hasChildren(); - } - - @Override - public Object[] getElements(Object inputElement) { - return getChildren(inputElement); - } - - @Override - public void dispose() { - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/messages.properties deleted file mode 100755 index 484648adca..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/statistics/model/messages.properties +++ /dev/null @@ -1,20 +0,0 @@ -############################################################################### -# Copyright (c) 2013 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### - -TmfStatisticsData_CPUs=CPUs -TmfStatisticsData_EventTypes=Event Types -TmfStatisticsView_LevelColumn=Level -TmfStatisticsView_LevelColumnTip=Level at which statistics apply. -TmfStatisticsView_NbEventsColumn=Events total -TmfStatisticsView_NbEventsTip=Total amount of events contained in the trace -TmfStatisticsView_NbEventsTimeRangeColumn=Events in selection -TmfStatisticsView_NbEventsTimeRangeTip=Number of events in the currently selected time range diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/AbstractTmfTreeViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/AbstractTmfTreeViewer.java deleted file mode 100644 index 7f669bb79f..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/AbstractTmfTreeViewer.java +++ /dev/null @@ -1,508 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.tree; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jface.viewers.AbstractTreeViewer; -import org.eclipse.jface.viewers.IBaseLabelProvider; -import org.eclipse.jface.viewers.ILabelProviderListener; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.ITableColorProvider; -import org.eclipse.jface.viewers.ITableFontProvider; -import org.eclipse.jface.viewers.ITableLabelProvider; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.viewers.TmfTimeViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.TreeColumn; - -/** - * Abstract class for viewers who will display data using a TreeViewer. It - * automatically synchronizes with time information of the UI. It also - * implements some common functionalities for all tree viewer, such as managing - * the column data, content initialization and update. The viewer implementing - * this does not have to worry about whether some code runs in the UI thread or - * not. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public abstract class AbstractTmfTreeViewer extends TmfTimeViewer { - - private final TreeViewer fTreeViewer; - - // ------------------------------------------------------------------------ - // Internal classes - // ------------------------------------------------------------------------ - - /* The elements of the tree viewer are of type ITmfTreeViewerEntry */ - private class TreeContentProvider implements ITreeContentProvider { - - @Override - public void dispose() { - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - @Override - public Object[] getElements(Object inputElement) { - if (inputElement instanceof ITmfTreeViewerEntry) { - return ((ITmfTreeViewerEntry) inputElement).getChildren().toArray(new ITmfTreeViewerEntry[0]); - } - return new ITmfTreeViewerEntry[0]; - } - - @Override - public Object[] getChildren(Object parentElement) { - ITmfTreeViewerEntry entry = (ITmfTreeViewerEntry) parentElement; - List children = entry.getChildren(); - return children.toArray(new ITmfTreeViewerEntry[children.size()]); - } - - @Override - public Object getParent(Object element) { - ITmfTreeViewerEntry entry = (ITmfTreeViewerEntry) element; - return entry.getParent(); - } - - @Override - public boolean hasChildren(Object element) { - ITmfTreeViewerEntry entry = (ITmfTreeViewerEntry) element; - return entry.hasChildren(); - } - - } - - /** - * Base class to provide the labels for the tree viewer. Views extending - * this class typically need to override the getColumnText method if they - * have more than one column to display. It also allows to change the font - * and colors of the cells. - */ - protected static class TreeLabelProvider implements ITableLabelProvider, ITableFontProvider, ITableColorProvider { - - @Override - public void addListener(ILabelProviderListener listener) { - } - - @Override - public void dispose() { - } - - @Override - public boolean isLabelProperty(Object element, String property) { - return false; - } - - @Override - public void removeListener(ILabelProviderListener listener) { - } - - @Override - public Image getColumnImage(Object element, int columnIndex) { - return null; - } - - @Override - public String getColumnText(Object element, int columnIndex) { - if ((element instanceof ITmfTreeViewerEntry) && (columnIndex == 0)) { - ITmfTreeViewerEntry entry = (ITmfTreeViewerEntry) element; - return entry.getName(); - } - return new String(); - } - - @Override - public Color getForeground(Object element, int columnIndex) { - return Display.getCurrent().getSystemColor(SWT.COLOR_LIST_FOREGROUND); - } - - @Override - public Color getBackground(Object element, int columnIndex) { - return Display.getCurrent().getSystemColor(SWT.COLOR_LIST_BACKGROUND); - } - - @Override - public Font getFont(Object element, int columnIndex) { - return null; - } - - } - - // ------------------------------------------------------------------------ - // Constructors and initialization methods - // ------------------------------------------------------------------------ - - /** - * Constructor - * - * @param parent - * The parent composite that holds this viewer - * @param allowMultiSelect - * Whether multiple selections are allowed - */ - public AbstractTmfTreeViewer(Composite parent, boolean allowMultiSelect) { - super(parent); - - int flags = SWT.FULL_SELECTION | SWT.H_SCROLL; - if (allowMultiSelect) { - flags |= SWT.MULTI; - } - - /* Build the tree viewer part of the view */ - fTreeViewer = new TreeViewer(parent, flags); - fTreeViewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS); - final Tree tree = fTreeViewer.getTree(); - tree.setHeaderVisible(true); - tree.setLinesVisible(true); - fTreeViewer.setContentProvider(new TreeContentProvider()); - fTreeViewer.setLabelProvider(new TreeLabelProvider()); - List columns = getColumnDataProvider().getColumnData(); - this.setTreeColumns(columns); - } - - /** - * Get the column data provider that will contain the list of columns to be - * part of this viewer. It is called once during the constructor. - * - * @return The tree column data provider for this viewer. - */ - protected abstract ITmfTreeColumnDataProvider getColumnDataProvider(); - - /** - * Sets the tree columns for this tree viewer - * - * @param columns - * The tree column data - */ - public void setTreeColumns(final List columns) { - boolean hasPercentProvider = false; - for (final TmfTreeColumnData columnData : columns) { - columnData.createColumn(fTreeViewer); - hasPercentProvider |= (columnData.getPercentageProvider() != null); - } - - if (hasPercentProvider) { - /* - * Handler that will draw bar charts in the cell using a percentage - * value. - */ - fTreeViewer.getTree().addListener(SWT.EraseItem, new Listener() { - @Override - public void handleEvent(Event event) { - if (columns.get(event.index).getPercentageProvider() != null) { - - double percentage = columns.get(event.index).getPercentageProvider().getPercentage(event.item.getData()); - if (percentage == 0) { // No bar to draw - return; - } - - if ((event.detail & SWT.SELECTED) > 0) { - /* - * The item is selected. Draw our own background to - * avoid overwriting the bar. - */ - event.gc.fillRectangle(event.x, event.y, event.width, event.height); - event.detail &= ~SWT.SELECTED; - } - - int barWidth = (int) ((fTreeViewer.getTree().getColumn(event.index).getWidth() - 8) * percentage); - int oldAlpha = event.gc.getAlpha(); - Color oldForeground = event.gc.getForeground(); - Color oldBackground = event.gc.getBackground(); - /* - * Draws a transparent gradient rectangle from the color - * of foreground and background. - */ - event.gc.setAlpha(64); - event.gc.setForeground(event.item.getDisplay().getSystemColor(SWT.COLOR_BLUE)); - event.gc.setBackground(event.item.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - event.gc.fillGradientRectangle(event.x, event.y, barWidth, event.height, true); - event.gc.drawRectangle(event.x, event.y, barWidth, event.height); - /* Restores old values */ - event.gc.setForeground(oldForeground); - event.gc.setBackground(oldBackground); - event.gc.setAlpha(oldAlpha); - event.detail &= ~SWT.BACKGROUND; - } - } - }); - } - } - - /** - * Set the label provider that will fill the columns of the tree viewer - * - * @param labelProvider - * The label provider to fill the columns - */ - protected void setLabelProvider(IBaseLabelProvider labelProvider) { - fTreeViewer.setLabelProvider(labelProvider); - } - - /** - * Get the tree viewer object - * - * @return The tree viewer object displayed by this viewer - */ - protected TreeViewer getTreeViewer() { - return fTreeViewer; - } - - // ------------------------------------------------------------------------ - // ITmfViewer - // ------------------------------------------------------------------------ - - @Override - public Control getControl() { - return fTreeViewer.getControl(); - } - - @Override - public void refresh() { - Tree tree = fTreeViewer.getTree(); - tree.setRedraw(false); - fTreeViewer.refresh(); - fTreeViewer.expandAll(); - tree.setRedraw(true); - } - - @Override - public void loadTrace(ITmfTrace trace) { - super.loadTrace(trace); - Thread thread = new Thread() { - @Override - public void run() { - initializeDataSource(); - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - clearContent(); - updateContent(getWindowStartTime(), getWindowEndTime(), false); - } - }); - } - }; - thread.start(); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Set the currently selected items in the treeviewer - * - * @param selection - * The list of selected items - * @since 3.1 - */ - public void setSelection(@NonNull List selection) { - IStructuredSelection sel = new StructuredSelection(selection); - fTreeViewer.setSelection(sel, true); - } - - /** - * Add a selection listener to the tree viewer. This will be called when the - * selection changes and contain all the selected items. - * - * The selection change listener can be used like this: - * - *

-     * getTreeViewer().addSelectionChangeListener(new ISelectionChangedListener() {
-     *     @Override
-     *     public void selectionChanged(SelectionChangedEvent event) {
-     *         if (event.getSelection() instanceof IStructuredSelection) {
-     *             Object selection = ((IStructuredSelection) event.getSelection()).getFirstElement();
-     *             if (selection instanceof ITmfTreeViewerEntry) {
-     *                 // Do something
-     *             }
-     *         }
-     *     }
-     * });
-     * 
- * - * @param listener - * The {@link ISelectionChangedListener} - */ - public void addSelectionChangeListener(ISelectionChangedListener listener) { - fTreeViewer.addSelectionChangedListener(listener); - } - - /** - * Method called when the trace is loaded, to initialize any data once the - * trace has been set, but before the first call to update the content of - * the viewer. - */ - protected void initializeDataSource() { - - } - - /** - * Clears the current content of the viewer. - */ - protected void clearContent() { - fTreeViewer.setInput(null); - } - - /** - * Method called after the content has been updated and the new input has - * been set on the tree. - * - * @param rootEntry - * The new input of this viewer, or null if none - * @since 3.1 - */ - protected void contentChanged(ITmfTreeViewerEntry rootEntry) { - - } - - /** - * Requests an update of the viewer's content in a given time range or - * selection time range. An extra parameter defines whether these times - * correspond to the selection or the visible range, as the viewer may - * update differently in those cases. - * - * @param start - * The start time of the requested content - * @param end - * The end time of the requested content - * @param isSelection - * true if this time range is for a selection, - * false for the visible time range - */ - protected void updateContent(final long start, final long end, final boolean isSelection) { - Thread thread = new Thread() { - @Override - public void run() { - final ITmfTreeViewerEntry rootEntry = updateElements(start, end, isSelection); - /* Set the input in main thread only if it didn't change */ - if (rootEntry != null) { - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - if (rootEntry != fTreeViewer.getInput()) { - fTreeViewer.setInput(rootEntry); - contentChanged(rootEntry); - } else { - fTreeViewer.refresh(); - fTreeViewer.expandToLevel(fTreeViewer.getAutoExpandLevel()); - } - // FIXME should add a bit of padding - for (TreeColumn column : fTreeViewer.getTree().getColumns()) { - column.pack(); - } - } - }); - } - } - }; - thread.start(); - } - - /** - * Update the entries to the given start/end time. An extra parameter - * defines whether these times correspond to the selection or the visible - * range, as the viewer may update differently in those cases. This methods - * returns a root node that is not meant to be visible. The children of this - * 'fake' root node are the first level of entries that will appear in the - * tree. If no update is necessary, the method should return - * null. To empty the tree, a root node containing an empty - * list of children should be returned. - * - * This method is not called in the UI thread when using the default viewer - * content update. Resource-intensive calculations here should not block the - * UI. - * - * @param start - * The start time of the requested content - * @param end - * The end time of the requested content - * @param isSelection - * true if this time range is for a selection, - * false for the visible time range - * @return The root entry of the list of entries to display or - * null if no update necessary - */ - protected abstract ITmfTreeViewerEntry updateElements(long start, long end, boolean isSelection); - - /** - * Get the current input displayed by the viewer - * - * @return The input of the tree viewer, the root entry - */ - protected ITmfTreeViewerEntry getInput() { - return (ITmfTreeViewerEntry) fTreeViewer.getInput(); - } - - // ------------------------------------------------------------------------ - // Signal Handler - // ------------------------------------------------------------------------ - - /** - * Signal handler for handling of the time synch signal. The times - * correspond to the selection by the user, not the visible time range. - * - * @param signal - * The time synch signal {@link TmfTimeSynchSignal} - */ - @Override - @TmfSignalHandler - public void selectionRangeUpdated(TmfTimeSynchSignal signal) { - super.selectionRangeUpdated(signal); - if ((signal.getSource() != this) && (getTrace() != null)) { - updateContent(this.getSelectionBeginTime(), this.getSelectionEndTime(), true); - } - } - - /** - * Signal handler for handling of the time range synch signal. This time - * range is the visible zone of the view. - * - * @param signal - * The time range synch signal {@link TmfRangeSynchSignal} - */ - @Override - @TmfSignalHandler - public void timeRangeUpdated(TmfRangeSynchSignal signal) { - super.timeRangeUpdated(signal); - updateContent(this.getWindowStartTime(), this.getWindowEndTime(), false); - } - - @Override - public void reset() { - super.reset(); - clearContent(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/ITmfTreeColumnDataProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/ITmfTreeColumnDataProvider.java deleted file mode 100755 index 26a62da2ed..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/ITmfTreeColumnDataProvider.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial API and Implementation - * Geneviève Bastien - Moved class and adapted it to abstract tree viewer - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.tree; - -import java.util.List; - -/** - * Basic methods that must be implemented in a column data provider. Tree - * viewers will use class implementing this to populate the columns. - * - * @author Mathieu Denis - * @since 3.0 - */ -public interface ITmfTreeColumnDataProvider { - - /** - * Return a list of the column created for the view - * - * @return columns list - */ - List getColumnData(); -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/ITmfTreeViewerEntry.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/ITmfTreeViewerEntry.java deleted file mode 100644 index 11e5b7af67..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/ITmfTreeViewerEntry.java +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.tree; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNull; - -/** - * Interface for an entry (row) in a TMF tree viewer - * - * @author Geneviève Bastien - * @since 3.0 - */ -public interface ITmfTreeViewerEntry { - - /** - * Returns the parent of this entry, or null if it has none. - * - * @return the parent element, or null if it has none - */ - ITmfTreeViewerEntry getParent(); - - /** - * Returns whether this entry has children. - * - * @return true if the given element has children, - * and false if it has no children - */ - boolean hasChildren(); - - /** - * Returns the child elements of this entry. - * - * @return an array of child elements - */ - @NonNull - List getChildren(); - - /** - * Returns the name of this entry. - * - * @return the entry name - */ - String getName(); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/TmfTreeColumnData.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/TmfTreeColumnData.java deleted file mode 100644 index 3f3053b798..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/TmfTreeColumnData.java +++ /dev/null @@ -1,266 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial Implementation and API (in TmfBaseColumnData of - * statistics framework) - * Bernd Hufmann - Added Annotations - * Geneviève Bastien - Moved TmfBaseColumnData to this class and adapted - * it for the abstract tree viewer - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.tree; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.TreeViewerColumn; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerComparator; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.widgets.Tree; - -/** - * Represents a column in an abstract tree viewer. It allows to define the - * column's characteristics: text, width, alignment, tooltip, comparators, - * percent providers, whether the column is movable, etc. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfTreeColumnData { - /** Name of the column. */ - private final String fText; - /** Width of the column. */ - private int fWidth = -1; - /** Alignment of the column. */ - private int fAlignment = SWT.LEAD; - /** Tooltip of the column. */ - private String fTooltip = null; - /** Used to sort elements of this column. If null, column is not sortable. */ - private ViewerComparator fComparator = null; - /** Whether the column is movable */ - private boolean fMovable = false; - /** Used to draw bar charts in this column. Can be null. */ - private ITmfColumnPercentageProvider fPercentageProvider = null; - - /** Used to draw bar charts in columns. */ - public interface ITmfColumnPercentageProvider { - - /** - * Percentage provider. Returns a percentage (between 0 and 100) from - * the given object. The object is usually an entry (a line of the tree - * viewer). - * - * @param data - * The data object corresponding to a line in the tree. - * @return The value as a percentage (between 0 and 100) - */ - public double getPercentage(Object data); - } - - /** - * Constructor with parameters - * - * @param text - * Text of the column. The name will be shown at the top of the - * column. - */ - public TmfTreeColumnData(String text) { - fText = text; - } - - /** - * Get the header text of a column - * - * @return The header text - */ - public String getText() { - return fText; - } - - /** - * Get the width of the column - * - * @return The column width - */ - public int getWidth() { - return fWidth; - } - - /** - * Get the alignment of the column - * - * @return The alignment (for example SWT.LEAD, SWT.RIGHT, etc) - */ - public int getAlignment() { - return fAlignment; - } - - /** - * Get the tooltip text to go with this column - * - * @return The tooltip text - */ - public String getTooltip() { - return fTooltip; - } - - /** - * Get the comparator used to sort columns. If null, then the - * column is not sortable - * - * @return The column comparator - */ - public ViewerComparator getComparator() { - return fComparator; - } - - /** - * Get the percentage provider for this column. This will allow to draw a - * bar chart inside the cells of this columns - * - * @return The percentage provider - */ - public ITmfColumnPercentageProvider getPercentageProvider() { - return fPercentageProvider; - } - - /** - * Return whether the column is movable or not - * - * @return True if column can be moved, false otherwise. - */ - public boolean isMovable() { - return fMovable; - } - - /** - * Set the width of the column. If not set, -1 is used. - * - * @param width - * Width of the column. Use -1 for tree viewer's default - * behavior. - */ - public void setWidth(int width) { - fWidth = width; - } - - /** - * Set the alignment of this column. If not set, default value is SWT.LEAD. - * - * @param alignment - * Alignment of the column. For example, SWT.LEAD, SWT.RIGHT, - * SWT.LEFT - */ - public void setAlignment(int alignment) { - fAlignment = alignment; - } - - /** - * Set the tooltip associated with this column - * - * @param tooltip - * the tooltip text - */ - public void setTooltip(String tooltip) { - fTooltip = tooltip; - } - - /** - * Set the comparator used to sort the column - * - * @param comparator - * The comparator. Use null to not sort the column. - */ - public void setComparator(ViewerComparator comparator) { - fComparator = comparator; - } - - /** - * Set the percentage provider that will provide a percentage value to draw - * a bar chart inside the cells of this column - * - * @param percentProvider - * The percentage provider - */ - public void setPercentageProvider(ITmfColumnPercentageProvider percentProvider) { - fPercentageProvider = percentProvider; - } - - /** - * Set whether the column can be moved in the tree viewer. Default is false. - * - * @param movable - * true if the column can be moved, false otherwise - */ - public void setMovable(boolean movable) { - fMovable = movable; - } - - /** - * Create a TreeColumn with this column's data and adds it to a {@link Tree} - * - * @param treeViewer - * The {@link TreeViewer} object to add the column to - * @return The newly created {@link TreeViewerColumn} - */ - @NonNull - public TreeViewerColumn createColumn(final TreeViewer treeViewer) { - final TreeViewerColumn column = new TreeViewerColumn(treeViewer, getAlignment()); - final TmfTreeColumnData columnData = this; - column.getColumn().setText(getText()); - if (getWidth() != -1) { - column.getColumn().setWidth(getWidth()); - } - if (getTooltip() != null) { - column.getColumn().setToolTipText(getTooltip()); - } - column.getColumn().setMoveable(isMovable()); - - /* Add the comparator to sort the column */ - if (getComparator() != null) { - column.getColumn().addSelectionListener(new SelectionAdapter() { - - @Override - public void widgetSelected(SelectionEvent e) { - - if (treeViewer.getTree().getSortDirection() == SWT.UP || treeViewer.getTree().getSortColumn() != column.getColumn()) { - /* - * Puts the descendant order if the old order was up - * or if the selected column has changed. - */ - treeViewer.setComparator(columnData.getComparator()); - treeViewer.getTree().setSortDirection(SWT.DOWN); - } else { - ViewerComparator reverseComparator; - /* Initializes the reverse comparator. */ - reverseComparator = new ViewerComparator() { - @Override - public int compare(Viewer viewer, Object e1, Object - e2) { - return -1 * columnData.getComparator().compare(viewer, e1, e2); - } - }; - - /* - * Puts the ascendant ordering if the selected - * column hasn't changed. - */ - treeViewer.setComparator(reverseComparator); - treeViewer.getTree().setSortDirection(SWT.UP); - } - treeViewer.getTree().setSortColumn(column.getColumn()); - } - }); - } - - return column; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/TmfTreeViewerEntry.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/TmfTreeViewerEntry.java deleted file mode 100644 index d9c96c61c4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/TmfTreeViewerEntry.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.tree; - -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -import org.eclipse.jdt.annotation.NonNull; - -/** - * Basic implementation of an entry for the TMF tree viewer. A name is all that is needed for this entry. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfTreeViewerEntry implements ITmfTreeViewerEntry { - - /** Entry's parent */ - private ITmfTreeViewerEntry fParent = null; - - /** List of child entries */ - @NonNull - private final List fChildren = new CopyOnWriteArrayList<>(); - - /** Name of this entry (default text to show in first column) */ - private String fName; - - /** - * Constructor - * - * @param name - * The name of this entry - */ - public TmfTreeViewerEntry(String name) { - fName = name; - } - - // --------------------------------------------- - // Getters and setters - // --------------------------------------------- - - @Override - public ITmfTreeViewerEntry getParent() { - return fParent; - } - - /** - * Sets the entry's parent - * - * @param entry The new parent entry - */ - protected void setParent(ITmfTreeViewerEntry entry) { - fParent = entry; - } - - @Override - public boolean hasChildren() { - return fChildren.size() > 0; - } - - @Override - public List getChildren() { - return fChildren; - } - - @Override - public String getName() { - return fName; - } - - /** - * Update the entry name - * - * @param name - * the updated entry name - */ - public void setName(String name) { - fName = name; - } - - /** - * Add a child entry to this one - * - * @param child - * The child entry - */ - public void addChild(TmfTreeViewerEntry child) { - child.fParent = this; - fChildren.add(child); - } - - @Override - public String toString() { - return getClass().getSimpleName() + '[' + fName + ']'; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/ITmfChartTimeProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/ITmfChartTimeProvider.java deleted file mode 100644 index 0b5439e4d1..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/ITmfChartTimeProvider.java +++ /dev/null @@ -1,54 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Geneviève Bastien - Moved some methods to ITmfTimeProvider - **********************************************************************/ -package org.eclipse.linuxtools.tmf.ui.viewers.xycharts; - -import org.eclipse.linuxtools.tmf.ui.viewers.ITmfTimeProvider; - -/** - * Interface adding some methods specific for SWT charts to the base time - * provider interface. Typically, the time will be shown on the x-axis. - * - * @author Bernd Hufmann - * @since 3.0 - */ -public interface ITmfChartTimeProvider extends ITmfTimeProvider { - - /** - * Returns a constant time offset that is used to normalize the time values - * to a range of 0..53 bits to avoid loss of precision when converting long - * <-> double. - * - * Time values are stored in TMF as long values. The SWT chart library uses - * values of type double (on x and y axis). To avoid loss of precision when - * converting long <-> double the values need to fit within 53 bits. - * - * Subtract the offset when using time values provided externally for - * internal usage in SWT chart. Add the offset when using time values - * provided by SWT chart (e.g. for display purposes) and when broadcasting - * them externally (e.g. time synchronization signals). - * - * For example the offset can be calculated as the time of the first time - * value in the current time range to be displayed in the chart. Add +1 to - * avoid 0 when using logarithmic scale. - * - * t0=10000, t2=20000, tn=N -> timeOffset=t0-1 -> t0'=1, t1'=10001, - * tn'=N-timeOffset - * - * where t0 ... tn are times used externally and t0' ... tn' are times used - * internally by the SWT chart. - * - * @return the time offset - */ - long getTimeOffset(); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfBaseProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfBaseProvider.java deleted file mode 100644 index dcc5690c0f..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfBaseProvider.java +++ /dev/null @@ -1,155 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ -package org.eclipse.linuxtools.tmf.ui.viewers.xycharts; - -import org.swtchart.Chart; -import org.swtchart.IAxis; - -/** - * Base class for any provider such as tool tip, zoom and selection providers. - * - * @author Bernd Hufmann - * @since 3.0 - */ -abstract public class TmfBaseProvider { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** Reference to the chart viewer */ - private final ITmfChartTimeProvider fChartViewer; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Standard constructor. - * - * @param tmfChartViewer - * The parent histogram object - */ - public TmfBaseProvider(ITmfChartTimeProvider tmfChartViewer) { - fChartViewer = tmfChartViewer; - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - /** - * Returns the chart viewer reference. - * @return the chart viewer reference - */ - public ITmfChartTimeProvider getChartViewer() { - return fChartViewer; - } - - /** - * Returns the SWT chart reference - * - * @return SWT chart reference. - */ - protected Chart getChart() { - return (Chart) fChartViewer.getControl(); - } - - /** - * Limits x data coordinate to window start and window end range - * - * @param x - * x to limit - * @return x if x >= begin && x <= end - * begin if x < begin - * end if x > end - */ - protected long limitXDataCoordinate(double x) { - ITmfChartTimeProvider viewer = getChartViewer(); - long windowStartTime = viewer.getWindowStartTime() - viewer.getTimeOffset(); - long windowEndTime = viewer.getWindowEndTime() - viewer.getTimeOffset(); - - if (x < windowStartTime) { - return windowStartTime; - } - - if (x > windowEndTime) { - return windowEndTime; - } - - return (long) x; - } - - /** - * Limits x pixel coordinate to window start and window end range - * - * @param axisIndex - * index of x-axis - * @param x - * x to limit - * @return x if x >= begin && x <= end - * begin if x < begin - * end if x > end - */ - protected int limitXPixelCoordinate(int axisIndex, int x) { - ITmfChartTimeProvider viewer = getChartViewer(); - long windowStartTime = viewer.getWindowStartTime() - viewer.getTimeOffset(); - long windowEndTime = viewer.getWindowEndTime() - viewer.getTimeOffset(); - - IAxis xAxis = getChart().getAxisSet().getXAxis(0); - int startX = xAxis.getPixelCoordinate(windowStartTime); - if (x < startX) { - return startX; - } - - int endX = xAxis.getPixelCoordinate(windowEndTime); - if (x > endX) { - return endX; - } - - return x; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - /** - * Method deregisters provider from chart viewer. Subclasses may override this method - * to dispose any resources. - */ - public void dispose() { - deregister(); - } - - /** - * Method to refresh the viewer. It will redraw the viewer. - */ - public void refresh() { - if (!TmfXYChartViewer.getDisplay().isDisposed()) { - TmfXYChartViewer.getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - getChart().redraw(); - } - }); - } - } - - /** - * Method to register the provider to chart viewer. - */ - protected abstract void register(); - - /** - * Method to deregister the provider from chart viewer. - */ - protected abstract void deregister(); - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfChartTimeStampFormat.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfChartTimeStampFormat.java deleted file mode 100644 index dd791bb8ae..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfChartTimeStampFormat.java +++ /dev/null @@ -1,63 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ -package org.eclipse.linuxtools.tmf.ui.viewers.xycharts; - -import java.text.FieldPosition; -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampFormat; - -/** - * SimpleDateFormat class for displaying time information in SWT charts - * using the TmfTimestampFormat class. - * - * @author Bernd Hufmann - * @since 3.0 - */ -public class TmfChartTimeStampFormat extends SimpleDateFormat { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - private static final long serialVersionUID = 3719743469686142387L; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - private long fOffset; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Standard Constructor - * - * @param offset - * offset to apply before formatting time (time = time + offset) - */ - public TmfChartTimeStampFormat(long offset) { - fOffset = offset; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - @Override - public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) { - - long time = date.getTime() + fOffset; - toAppendTo.append(TmfTimestampFormat.getDefaulTimeFormat().format(time)); - return toAppendTo; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfMouseDragProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfMouseDragProvider.java deleted file mode 100644 index 7d8c5ca52e..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfMouseDragProvider.java +++ /dev/null @@ -1,135 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ -package org.eclipse.linuxtools.tmf.ui.viewers.xycharts; - -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.MouseMoveListener; -import org.swtchart.IAxis; -import org.swtchart.Range; - -/** - * Class for updating time ranges based on middle mouse button drag. - * It also notifies the viewer about a change of range. - * - * @author Bernd Hufmann - * @since 3.0 - */ -public class TmfMouseDragProvider extends TmfBaseProvider implements MouseListener, MouseMoveListener { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** Cached start time */ - private long fStartTime; - /** Cached end time */ - private long fEndTime; - /** Flag indicating that an update is ongoing */ - private boolean fIsUpdate; - /** Cached position when mouse button was pressed */ - private int fStartPosition; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor - * - * @param tmfChartViewer - * the chart viewer reference. - */ - public TmfMouseDragProvider(ITmfChartTimeProvider tmfChartViewer) { - super(tmfChartViewer); - register(); - } - - // ------------------------------------------------------------------------ - // TmfBaseProvider - // ------------------------------------------------------------------------ - @Override - public void register() { - getChart().getPlotArea().addMouseListener(this); - getChart().getPlotArea().addMouseMoveListener(this); - } - - @Override - public void deregister() { - if ((getChartViewer().getControl() != null) && !getChartViewer().getControl().isDisposed()) { - getChart().getPlotArea().removeMouseListener(this); - getChart().getPlotArea().removeMouseMoveListener(this); - } - } - - @Override - public void refresh() { - // nothing to do - } - - // ------------------------------------------------------------------------ - // MouseListener - // ------------------------------------------------------------------------ - @Override - public void mouseDoubleClick(MouseEvent e) { - } - - @Override - public void mouseDown(MouseEvent e) { - if ((getChartViewer().getWindowDuration() != 0) && (e.button == 2)) { - fStartPosition = e.x; - fIsUpdate = true; - } - } - - @Override - public void mouseUp(MouseEvent e) { - if ((fIsUpdate) && (fStartTime != fEndTime)) { - ITmfChartTimeProvider viewer = getChartViewer(); - viewer.updateWindow(fStartTime, fEndTime); - } - fIsUpdate = false; - } - - // ------------------------------------------------------------------------ - // MouseMoveListener - // ------------------------------------------------------------------------ - @Override - public void mouseMove(MouseEvent e) { - if (fIsUpdate) { - IAxis xAxis = getChart().getAxisSet().getXAxis(0); - - ITmfChartTimeProvider viewer = getChartViewer(); - - fStartTime = viewer.getWindowStartTime(); - fEndTime = viewer.getWindowEndTime(); - - long startTime = viewer.getStartTime(); - long endTime = viewer.getEndTime(); - - long delta = 0; - if (fStartPosition > e.x) { - delta = (long) (xAxis.getDataCoordinate(fStartPosition) - xAxis.getDataCoordinate(e.x)); - long max = endTime - fEndTime; - delta = Math.max(0, Math.min(delta, max)); - fStartTime = fStartTime + delta; - fEndTime = fEndTime + delta; - } else if (fStartPosition < e.x) { - delta = (long) (xAxis.getDataCoordinate(e.x) - xAxis.getDataCoordinate(fStartPosition)); - long max = fStartTime - startTime; - delta = Math.max(0, Math.min(delta, max)); - fStartTime = fStartTime - delta; - fEndTime = fEndTime - delta; - } - - xAxis.setRange(new Range(fStartTime - viewer.getTimeOffset(), fEndTime - viewer.getTimeOffset())); - } - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfMouseDragZoomProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfMouseDragZoomProvider.java deleted file mode 100644 index 85ab035a2b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfMouseDragZoomProvider.java +++ /dev/null @@ -1,152 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ -package org.eclipse.linuxtools.tmf.ui.viewers.xycharts; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.events.PaintEvent; -import org.swtchart.IAxis; -import org.swtchart.ICustomPaintListener; -import org.swtchart.IPlotArea; - -/** - * Class for providing zooming based on mouse drag with right mouse button. - * It also notifies the viewer about a change of range. - * - * @author Bernd Hufmann - * @since 3.0 - */ -public class TmfMouseDragZoomProvider extends TmfBaseProvider implements MouseListener, MouseMoveListener, ICustomPaintListener { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** Cached start time */ - private long fStartTime; - /** Cached end time */ - private long fEndTime; - /** Flag indicating that an update is ongoing */ - private boolean fIsUpdate; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor - * - * @param tmfChartViewer - * the chart viewer reference. - */ - public TmfMouseDragZoomProvider(ITmfChartTimeProvider tmfChartViewer) { - super(tmfChartViewer); - register(); - } - - // ------------------------------------------------------------------------ - // TmfBaseProvider - // ------------------------------------------------------------------------ - @Override - public void register() { - getChart().getPlotArea().addMouseListener(this); - getChart().getPlotArea().addMouseMoveListener(this); - ((IPlotArea) getChart().getPlotArea()).addCustomPaintListener(this); - } - - @Override - public void deregister() { - if ((getChartViewer().getControl() != null) && !getChartViewer().getControl().isDisposed()) { - getChart().getPlotArea().removeMouseListener(this); - getChart().getPlotArea().removeMouseMoveListener(this); - ((IPlotArea) getChart().getPlotArea()).removeCustomPaintListener(this); - } - } - - @Override - public void refresh() { - // nothing to do - } - - // ------------------------------------------------------------------------ - // MouseListener - // ------------------------------------------------------------------------ - @Override - public void mouseDoubleClick(MouseEvent e) { - } - - @Override - public void mouseDown(MouseEvent e) { - if ((getChartViewer().getWindowDuration() != 0) && (e.button == 3)) { - IAxis xAxis = getChart().getAxisSet().getXAxis(0); - fStartTime = limitXDataCoordinate(xAxis.getDataCoordinate(e.x)); - fEndTime = fStartTime; - fIsUpdate = true; - } - } - - @Override - public void mouseUp(MouseEvent e) { - if ((fIsUpdate) && (fStartTime != fEndTime)) { - if (fStartTime > fEndTime) { - long tmp = fStartTime; - fStartTime = fEndTime; - fEndTime = tmp; - } - ITmfChartTimeProvider viewer = getChartViewer(); - viewer.updateWindow(fStartTime + viewer.getTimeOffset(), fEndTime + viewer.getTimeOffset()); - } - - if (fIsUpdate) { - getChart().redraw(); - } - fIsUpdate = false; - } - - // ------------------------------------------------------------------------ - // MouseMoveListener - // ------------------------------------------------------------------------ - @Override - public void mouseMove(MouseEvent e) { - if (fIsUpdate) { - IAxis xAxis = getChart().getAxisSet().getXAxis(0); - fEndTime = limitXDataCoordinate(xAxis.getDataCoordinate(e.x)); - getChart().redraw(); - } - } - - // ------------------------------------------------------------------------ - // ICustomPaintListener - // ------------------------------------------------------------------------ - @Override - public void paintControl(PaintEvent e) { - if (fIsUpdate && (fStartTime != fEndTime)) { - IAxis xAxis = getChart().getAxisSet().getXAxis(0); - int startX = xAxis.getPixelCoordinate(fStartTime); - int endX = xAxis.getPixelCoordinate(fEndTime); - - e.gc.setBackground(TmfXYChartViewer.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND)); - if (fStartTime < fEndTime) { - e.gc.fillRectangle(startX, 0, endX - startX, e.height); - } else { - e.gc.fillRectangle(endX, 0, startX - endX, e.height); - } - e.gc.drawLine(startX, 0, startX, e.height); - e.gc.drawLine(endX, 0, endX, e.height); - } - } - - @Override - public boolean drawBehindSeries() { - return true; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfMouseSelectionProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfMouseSelectionProvider.java deleted file mode 100644 index a38b2b27e0..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfMouseSelectionProvider.java +++ /dev/null @@ -1,164 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ -package org.eclipse.linuxtools.tmf.ui.viewers.xycharts; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.events.PaintEvent; -import org.swtchart.IAxis; -import org.swtchart.ICustomPaintListener; -import org.swtchart.IPlotArea; - -/** - * Class for providing selection of ranges with the left mouse button. - * It also notifies the viewer about a change of selection. - * - * @author Bernd Hufmann - * @since 3.0 - */ -public class TmfMouseSelectionProvider extends TmfBaseProvider implements MouseListener, MouseMoveListener, ICustomPaintListener { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** Cached start time */ - private long fBeginTime; - /** Cached end time */ - private long fEndTime; - /** Flag indicating that an update is ongoing */ - private boolean fIsInternalUpdate; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor - * - * @param tmfChartViewer - * The chart viewer reference. - */ - public TmfMouseSelectionProvider(ITmfChartTimeProvider tmfChartViewer) { - super(tmfChartViewer); - register(); - } - - // ------------------------------------------------------------------------ - // TmfBaseProvider - // ------------------------------------------------------------------------ - @Override - public void register() { - getChart().getPlotArea().addMouseListener(this); - getChart().getPlotArea().addMouseMoveListener(this); - ((IPlotArea) getChart().getPlotArea()).addCustomPaintListener(this); - } - - @Override - public void deregister() { - if ((getChartViewer().getControl() != null) && !getChartViewer().getControl().isDisposed()) { - getChart().getPlotArea().removeMouseListener(this); - getChart().getPlotArea().removeMouseMoveListener(this); - ((IPlotArea) getChart().getPlotArea()).removeCustomPaintListener(this); - } - } - - // ------------------------------------------------------------------------ - // MouseListener - // ------------------------------------------------------------------------ - @Override - public void mouseDoubleClick(MouseEvent e) { - } - - @Override - public void mouseDown(MouseEvent e) { - if ((getChartViewer().getWindowDuration() != 0) && (e.button == 1)) { - IAxis xAxis = getChart().getAxisSet().getXAxis(0); - fBeginTime = limitXDataCoordinate(xAxis.getDataCoordinate(e.x)); - fEndTime = fBeginTime; - fIsInternalUpdate = true; - } - } - - @Override - public void mouseUp(MouseEvent e) { - if (fIsInternalUpdate) { - if (fBeginTime > fEndTime) { - // Swap time - long tmp = fBeginTime; - fBeginTime = fEndTime; - fEndTime = tmp; - } - ITmfChartTimeProvider viewer = getChartViewer(); - viewer.updateSelectionRange(fBeginTime + viewer.getTimeOffset(), fEndTime + viewer.getTimeOffset()); - fIsInternalUpdate = false; - getChart().redraw(); - } - } - - // ------------------------------------------------------------------------ - // MouseMoveListener - // ------------------------------------------------------------------------ - @Override - public void mouseMove(MouseEvent e) { - if (fIsInternalUpdate) { - IAxis xAxis = getChart().getAxisSet().getXAxis(0); - fEndTime = limitXDataCoordinate(xAxis.getDataCoordinate(e.x)); - getChart().redraw(); - } - } - - // ------------------------------------------------------------------------ - // ICustomPaintListener - // ------------------------------------------------------------------------ - @Override - public void paintControl(PaintEvent e) { - ITmfChartTimeProvider viewer = getChartViewer(); - - if (!fIsInternalUpdate) { - fBeginTime = viewer.getSelectionBeginTime() - viewer.getTimeOffset(); - fEndTime = viewer.getSelectionEndTime() - viewer.getTimeOffset(); - } - long windowStartTime = viewer.getWindowStartTime() - viewer.getTimeOffset(); - long windowEndTime = viewer.getWindowEndTime() - viewer.getTimeOffset(); - - IAxis xAxis = getChart().getAxisSet().getXAxis(0); - e.gc.setBackground(TmfXYChartViewer.getDisplay().getSystemColor(SWT.COLOR_BLUE)); - e.gc.setForeground(TmfXYChartViewer.getDisplay().getSystemColor(SWT.COLOR_BLUE)); - e.gc.setLineStyle(SWT.LINE_SOLID); - if ((fBeginTime >= windowStartTime) && (fBeginTime <= windowEndTime)) { - int beginX = xAxis.getPixelCoordinate(fBeginTime); - e.gc.drawLine(beginX, 0, beginX, e.height); - } - - if ((fEndTime >= windowStartTime) && (fEndTime <= windowEndTime) && (fBeginTime != fEndTime)) { - int endX = xAxis.getPixelCoordinate(fEndTime); - e.gc.drawLine(endX, 0, endX, e.height); - } - e.gc.setAlpha(150); - if (Math.abs(fEndTime - fBeginTime) > 1) { - e.gc.setBackground(TmfXYChartViewer.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); - int beginX = xAxis.getPixelCoordinate(fBeginTime); - int endX = xAxis.getPixelCoordinate(fEndTime); - if (fEndTime > fBeginTime) { - e.gc.fillRectangle(beginX + 1, 0, endX - beginX - 1, e.height); - } else { - e.gc.fillRectangle(endX + 1, 0, beginX - endX - 1, e.height); - } - } - } - - @Override - public boolean drawBehindSeries() { - return false; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfMouseWheelZoomProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfMouseWheelZoomProvider.java deleted file mode 100644 index a1c7bf476c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfMouseWheelZoomProvider.java +++ /dev/null @@ -1,135 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.xycharts; - -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseWheelListener; -import org.swtchart.IAxis; - -/** - * Class for providing zooming based on mouse wheel. It centers the zoom on - * mouse position. It also notifies the viewer about a change of range. - * - * @author Bernd Hufmann - * @since 3.0 - */ -public class TmfMouseWheelZoomProvider extends TmfBaseProvider implements MouseWheelListener { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - private final static double ZOOM_FACTOR = 0.8; - private final static long MIN_WINDOW_SIZE = 1; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Standard constructor. - * - * @param tmfChartViewer - * The parent histogram object - */ - public TmfMouseWheelZoomProvider(ITmfChartTimeProvider tmfChartViewer) { - super(tmfChartViewer); - register(); - } - - // ------------------------------------------------------------------------ - // TmfBaseProvider - // ------------------------------------------------------------------------ - @Override - public void register() { - getChart().getPlotArea().addMouseWheelListener(this); - } - - @Override - public void deregister() { - if ((getChartViewer().getControl() != null) && !getChartViewer().getControl().isDisposed()) { - getChart().getPlotArea().removeMouseWheelListener(this); - } - } - - @Override - public void refresh() { - // nothing to do - } - - // ------------------------------------------------------------------------ - // MouseWheelListener - // ------------------------------------------------------------------------ - @Override - public synchronized void mouseScrolled(MouseEvent event) { - ITmfChartTimeProvider viewer = getChartViewer(); - - long oldDuration = viewer.getWindowDuration(); - - if (oldDuration == 0) { - return; - } - - // Compute the new time range - long newDuration = oldDuration; - double ratio = 1.0; - if (event.count > 0) { - ratio = ZOOM_FACTOR; - newDuration = Math.round(ZOOM_FACTOR * oldDuration); - } else { - ratio = 1.0 / ZOOM_FACTOR; - newDuration = (long) Math.ceil(oldDuration * ratio); - } - newDuration = Math.max(MIN_WINDOW_SIZE, newDuration); - - // Center the zoom on mouse position, distribute new duration and adjust for boundaries. - IAxis xAxis = getChart().getAxisSet().getXAxis(0); - long timeAtXPos = limitXDataCoordinate(xAxis.getDataCoordinate(event.x)) + viewer.getTimeOffset(); - // Note: ratio = newDuration/oldDuration - long newWindowStartTime = timeAtXPos - Math.round(ratio * (timeAtXPos - viewer.getWindowStartTime())); - long newWindowEndTime = validateWindowEndTime(newWindowStartTime, newWindowStartTime + newDuration); - newWindowStartTime = validateWindowStartTime(newWindowStartTime); - viewer.updateWindow(newWindowStartTime, newWindowEndTime); - } - - // ------------------------------------------------------------------------ - // Helper methods - // ------------------------------------------------------------------------ - private long validateWindowStartTime(long start) { - ITmfChartTimeProvider viewer = getChartViewer(); - long realStart = start; - - long startTime = viewer.getStartTime(); - long endTime = viewer.getEndTime(); - - if (realStart < startTime) { - realStart = startTime; - } - if (realStart > endTime) { - realStart = endTime; - } - return realStart; - } - - private long validateWindowEndTime(long start, long end) { - ITmfChartTimeProvider viewer = getChartViewer(); - long realEnd = end; - long endTime = viewer.getEndTime(); - - if (realEnd > endTime) { - realEnd = endTime; - } - if (realEnd < start + MIN_WINDOW_SIZE) { - realEnd = start + MIN_WINDOW_SIZE; - } - return realEnd; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfSimpleTooltipProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfSimpleTooltipProvider.java deleted file mode 100644 index 3a20f5cfba..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfSimpleTooltipProvider.java +++ /dev/null @@ -1,97 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ -package org.eclipse.linuxtools.tmf.ui.viewers.xycharts; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseTrackListener; -import org.swtchart.IAxis; - -/** - * Tool tip provider for TMF chart viewer. It displays the x and y - * value of the current mouse position. - * - * @author Bernd Hufmann - * @since 3.0 - */ -public class TmfSimpleTooltipProvider extends TmfBaseProvider implements MouseTrackListener { - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Constructor for a tool tip provider. - * - * @param tmfChartViewer - * The parent chart viewer - */ - public TmfSimpleTooltipProvider(ITmfChartTimeProvider tmfChartViewer) { - super(tmfChartViewer); - register(); - } - - // ------------------------------------------------------------------------ - // TmfBaseProvider - // ------------------------------------------------------------------------ - @Override - public void register() { - getChart().getPlotArea().addMouseTrackListener(this); - } - - @Override - public void deregister() { - if ((getChartViewer().getControl() != null) && !getChartViewer().getControl().isDisposed()) { - getChart().getPlotArea().removeMouseTrackListener(this); - } - } - - @Override - public void refresh() { - // nothing to do - } - - // ------------------------------------------------------------------------ - // MouseTrackListener - // ------------------------------------------------------------------------ - @Override - public void mouseEnter(MouseEvent e) { - } - - @Override - public void mouseExit(MouseEvent e) { - } - - @Override - public void mouseHover(MouseEvent e) { - if (getChartViewer().getWindowDuration() == 0) { - return; - } - - IAxis xAxis = getChart().getAxisSet().getXAxis(0); - IAxis yAxis = getChart().getAxisSet().getYAxis(0); - - double xCoordinate = xAxis.getDataCoordinate(e.x); - double yCoordinate = yAxis.getDataCoordinate(e.y); - - ITmfChartTimeProvider viewer = getChartViewer(); - - /* set tooltip of current data point */ - StringBuffer buffer = new StringBuffer(); - buffer.append("x="); //$NON-NLS-1$ - buffer.append(new TmfTimestamp((long) xCoordinate + viewer.getTimeOffset(), ITmfTimestamp.NANOSECOND_SCALE).toString()); - buffer.append("\n"); //$NON-NLS-1$ - buffer.append("y="); //$NON-NLS-1$ - buffer.append((long) yCoordinate); - getChart().getPlotArea().setToolTipText(buffer.toString()); - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfXYChartViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfXYChartViewer.java deleted file mode 100644 index fdb92f032a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/TmfXYChartViewer.java +++ /dev/null @@ -1,373 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Geneviève Bastien - Moved some methods to TmfTimeViewer - **********************************************************************/ -package org.eclipse.linuxtools.tmf.ui.viewers.xycharts; - -import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimestampFormatUpdateSignal; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.viewers.TmfTimeViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.swtchart.Chart; -import org.swtchart.IAxis; -import org.swtchart.ISeries; -import org.swtchart.ISeriesSet; - -/** - * Base class for a XY-Chart based on SWT chart. It provides a methods to define - * zoom, selection and tool tip providers. It also provides call backs to be - * notified by any changes caused by selection and zoom. - * - * @author Bernd Hufmann - * @since 3.0 - */ -public abstract class TmfXYChartViewer extends TmfTimeViewer implements ITmfChartTimeProvider { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The offset to apply to any x position. This offset ensures better - * precision when converting long to double and back. - */ - private long fTimeOffset; - /** The SWT Chart reference */ - private Chart fSwtChart; - /** The mouse selection provider */ - private TmfBaseProvider fMouseSelectionProvider; - /** The mouse drag zoom provider */ - private TmfBaseProvider fMouseDragZoomProvider; - /** The mouse wheel zoom provider */ - private TmfBaseProvider fMouseWheelZoomProvider; - /** The tooltip provider */ - private TmfBaseProvider fToolTipProvider; - /** The middle mouse drag provider */ - private TmfBaseProvider fMouseDragProvider; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructs a TmfXYChartViewer. - * - * @param parent - * The parent composite - * @param title - * The title of the viewer - * @param xLabel - * The label of the xAxis - * @param yLabel - * The label of the yAXIS - */ - public TmfXYChartViewer(Composite parent, String title, String xLabel, String yLabel) { - super(parent, title); - fSwtChart = new Chart(parent, SWT.NONE); - - IAxis xAxis = fSwtChart.getAxisSet().getXAxis(0); - IAxis yAxis = fSwtChart.getAxisSet().getYAxis(0); - - /* Set the title/labels, or hide them if they are not provided */ - if (title == null) { - fSwtChart.getTitle().setVisible(false); - } else { - fSwtChart.getTitle().setText(title); - } - if (xLabel == null) { - xAxis.getTitle().setVisible(false); - } else { - xAxis.getTitle().setText(xLabel); - } - if (yLabel == null) { - yAxis.getTitle().setVisible(false); - } else { - yAxis.getTitle().setText(yLabel); - } - - fMouseSelectionProvider = new TmfMouseSelectionProvider(this); - fMouseDragZoomProvider = new TmfMouseDragZoomProvider(this); - fMouseWheelZoomProvider = new TmfMouseWheelZoomProvider(this); - fToolTipProvider = new TmfSimpleTooltipProvider(this); - fMouseDragProvider = new TmfMouseDragProvider(this); - } - - // ------------------------------------------------------------------------ - // Getter/Setters - // ------------------------------------------------------------------------ - /** - * Sets the time offset to apply. - * @see ITmfChartTimeProvider#getTimeOffset() - * - * @param timeOffset - * The time offset to apply - */ - protected void setTimeOffset(long timeOffset) { - fTimeOffset = timeOffset; - } - - /** - * Sets the SWT Chart reference - * - * @param chart - * The SWT chart to set. - */ - protected void setSwtChart(Chart chart) { - fSwtChart = chart; - } - - /** - * Gets the SWT Chart reference - * - * @return the SWT chart to set. - */ - protected Chart getSwtChart() { - return fSwtChart; - } - - /** - * Sets a mouse selection provider. An existing provider will be - * disposed. Use null to disable the mouse selection provider. - * - * @param provider - * The selection provider to set - */ - public void setSelectionProvider(TmfBaseProvider provider) { - if (fMouseSelectionProvider != null) { - fMouseSelectionProvider.dispose(); - } - fMouseSelectionProvider = provider; - } - - /** - * Sets a mouse drag zoom provider. An existing provider will be - * disposed. Use null to disable the mouse drag zoom provider. - * - * @param provider - * The mouse drag zoom provider to set - */ - public void setMouseDragZoomProvider(TmfBaseProvider provider) { - if (fMouseDragZoomProvider != null) { - fMouseDragZoomProvider.dispose(); - } - fMouseDragZoomProvider = provider; - } - - /** - * Sets a mouse wheel zoom provider. An existing provider will be - * disposed. Use null to disable the mouse wheel zoom - * provider. - * - * @param provider - * The mouse wheel zoom provider to set - */ - public void setMouseWheelZoomProvider(TmfBaseProvider provider) { - if (fMouseWheelZoomProvider != null) { - fMouseWheelZoomProvider.dispose(); - } - fMouseWheelZoomProvider = provider; - } - - /** - * Sets a tooltip provider. An existing provider will be - * disposed. Use null to disable the tooltip provider. - * - * @param provider - * The tooltip provider to set - */ - public void setTooltipProvider(TmfBaseProvider provider) { - if (fToolTipProvider != null) { - fToolTipProvider.dispose(); - } - fToolTipProvider = provider; - } - - /** - * Sets a mouse drag provider. An existing provider will be - * disposed. Use null to disable the mouse drag provider. - * - * @param provider - * The mouse drag provider to set - */ - public void setMouseDrageProvider(TmfBaseProvider provider) { - if (fMouseDragProvider != null) { - fMouseDragProvider.dispose(); - } - fMouseDragProvider = provider; - } - - // ------------------------------------------------------------------------ - // ITmfChartTimeProvider - // ------------------------------------------------------------------------ - - @Override - public long getTimeOffset() { - return fTimeOffset; - } - - // ------------------------------------------------------------------------ - // ITmfViewer interface - // ------------------------------------------------------------------------ - @Override - public Control getControl() { - return fSwtChart; - } - - @Override - public void refresh() { - fSwtChart.redraw(); - } - - // ------------------------------------------------------------------------ - // TmfComponent - // ------------------------------------------------------------------------ - @Override - public void dispose() { - super.dispose(); - fSwtChart.dispose(); - - if (fMouseSelectionProvider != null) { - fMouseSelectionProvider.dispose(); - } - - if (fMouseDragZoomProvider != null) { - fMouseDragZoomProvider.dispose(); - } - - if (fMouseWheelZoomProvider != null) { - fMouseWheelZoomProvider.dispose(); - } - - if (fToolTipProvider != null) { - fToolTipProvider.dispose(); - } - - if (fMouseDragProvider != null) { - fMouseDragProvider.dispose(); - } - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - /** - * A Method to load a trace into the viewer. - * - * @param trace - * A trace to apply in the viewer - */ - @Override - public void loadTrace(ITmfTrace trace) { - super.loadTrace(trace); - clearContent(); - updateContent(); - } - - /** - * Resets the content of the viewer - */ - @Override - public void reset() { - super.reset(); - clearContent(); - } - - /** - * Method to implement to update the chart content. - */ - protected abstract void updateContent(); - - // ------------------------------------------------------------------------ - // Signal Handler - // ------------------------------------------------------------------------ - - /** - * Signal handler for handling of the time synch signal. - * - * @param signal - * The time synch signal {@link TmfTimeSynchSignal} - */ - @Override - @TmfSignalHandler - public void selectionRangeUpdated(TmfTimeSynchSignal signal) { - super.selectionRangeUpdated(signal); - if ((signal.getSource() != this) && (getTrace() != null)) { - if (fMouseSelectionProvider != null) { - fMouseSelectionProvider.refresh(); - } - } - } - - /** - * Signal handler for handling of the time range synch signal. - * - * @param signal - * The time range synch signal {@link TmfRangeSynchSignal} - */ - @Override - @TmfSignalHandler - public void timeRangeUpdated(TmfRangeSynchSignal signal) { - super.timeRangeUpdated(signal); - updateContent(); - } - - /** - * Signal handler for handling the signal that notifies about an updated - * timestamp format. - * - * @param signal - * The trace updated signal - * {@link TmfTimestampFormatUpdateSignal} - */ - @TmfSignalHandler - public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) { - fSwtChart.getAxisSet().adjustRange(); - fSwtChart.redraw(); - } - - // ------------------------------------------------------------------------ - // Helper Methods - // ------------------------------------------------------------------------ - - /** - * Clears the view content. - */ - protected void clearContent() { - if (!fSwtChart.isDisposed()) { - ISeriesSet set = fSwtChart.getSeriesSet(); - ISeries[] series = set.getSeries(); - for (int i = 0; i < series.length; i++) { - set.deleteSeries(series[i].getId()); - } - fSwtChart.redraw(); - } - } - - /** - * Returns the current or default display. - * - * @return the current or default display - */ - protected static Display getDisplay() { - Display display = Display.getCurrent(); - // may be null if outside the UI thread - if (display == null) { - display = Display.getDefault(); - } - return display; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/barcharts/TmfBarChartViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/barcharts/TmfBarChartViewer.java deleted file mode 100644 index cc01ea7065..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/barcharts/TmfBarChartViewer.java +++ /dev/null @@ -1,220 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - * Bernd Hufmann - Updated for TMF base chart viewer - **********************************************************************/ -package org.eclipse.linuxtools.tmf.ui.viewers.xycharts.barcharts; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.linuxtools.tmf.ui.viewers.xycharts.TmfChartTimeStampFormat; -import org.eclipse.linuxtools.tmf.ui.viewers.xycharts.TmfXYChartViewer; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.swtchart.Chart; -import org.swtchart.IAxisTick; -import org.swtchart.IBarSeries; -import org.swtchart.ISeries; -import org.swtchart.ISeries.SeriesType; - -/** - * Abstract bar chart viewer class implementation. Used for displaying - * histograms. - * - * @author Alexandre Montplaisir - * @author Bernd Hufmann - * @since 3.0 - */ -public abstract class TmfBarChartViewer extends TmfXYChartViewer { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** Width of each histogram bar, in pixels */ - public static final int MINIMUM_BAR_WIDTH = 1; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** List of series */ - private final List seriesNames = new ArrayList<>(); - /** List of colors */ - private final List colors = new ArrayList<>(); - /** the bar width */ - private int fBarWidth = MINIMUM_BAR_WIDTH; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Constructs a TmfXYChartViewer. - * - * @param parent - * The parent composite - * @param title - * The title of the viewer - * @param xLabel - * The label of the xAxis - * @param yLabel - * The label of the yAXIS - * @param barWidth - * The bar width - */ - public TmfBarChartViewer(Composite parent, String title, String xLabel, String yLabel, int barWidth) { - super(parent, title, xLabel, yLabel); - fBarWidth = barWidth; - - setTooltipProvider(new TmfHistogramTooltipProvider(this)); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - @Override - protected void updateContent() { - - getDisplay().asyncExec(new Runnable() { - - @Override - public void run() { - Chart swtChart = getSwtChart(); - int numRequests = swtChart.getPlotArea().getBounds().width / fBarWidth; - - for (int i = 0; i < seriesNames.size(); i++) { - ISeries series = swtChart.getSeriesSet().getSeries(seriesNames.get(i)); - if (series == null) { - series = initSeries(seriesNames.get(i), colors.get(i)); - } - readData(series, getWindowStartTime(), getWindowEndTime(), numRequests); - } - } - }); - } - - /** - * Method to add a series to the chart. - * - * @param name - * Name of series - * @param color - * color to use for series - */ - protected void addSeries(String name, RGB color) { - seriesNames.add(name); - colors.add(color); - } - - /** - * Clears all series - */ - protected void clearSeries() { - seriesNames.clear(); - colors.clear(); - } - - /** - * Draw the given series on the chart - * - * @param series - * The series to display - * @param x - * The X values. It can be computed with - * {@link TmfBarChartViewer#getXAxis} - * The values are stored in the internal time representation. - * To get the trace time one has to add the time offset - * {@link #getTimeOffset()}. - * @param y - * The Y values that were computed by the extended class - */ - protected void drawChart(final ISeries series, final double[] x, final double[] y) { - // Run in GUI thread to make sure that chart is ready after restart - final Display display = getDisplay(); - if (display.isDisposed()) { - return; - } - - display.syncExec(new Runnable() { - @Override - public void run() { - if (display.isDisposed()) { - return; - } - Chart swtChart = getSwtChart(); - IAxisTick xTick = swtChart.getAxisSet().getXAxis(0).getTick(); - xTick.setFormat(new TmfChartTimeStampFormat(getTimeOffset())); - series.setXSeries(x); - series.setYSeries(y); - xTick.setTickMarkStepHint(256); - - swtChart.getAxisSet().adjustRange(); - swtChart.redraw(); - } - }); - } - - /** - * Convenience method to compute the X axis values for a given time range. - * - * @param start - * Start of the time range - * @param end - * End of the range - * @param nb - * Number of steps. This will be the size of the returned array. - * @return The time values (converted to double) that match every step - */ - protected final double[] getXAxis(long start, long end, int nb) { - setTimeOffset(start - 1); - double timestamps[] = new double[nb]; - long steps = (end - start); - double step = steps / (double) nb; - - double curTime = 1; - for (int i = 0; i < nb; i++) { - timestamps[i] = curTime; - curTime += step; - } - return timestamps; - } - - /** - * Load the data for the given series. This method should call - * {@link TmfBarChartViewer#drawChart} to return the results when done. - * - * Careful, this method is called by a signal handler which also happens to - * be in the main UI thread. This means any processing will block the UI! In - * most cases it's probably better to start a separate Thread/Job to do the - * processing, and that one can call drawChart() when done to update the - * view. - * - * @param series - * Which series of the chart should the viewer update - * @param start - * The start time (in nanoseconds) of the range to display - * @param end - * The end time of the range to display. - * @param nb - * The number of 'steps' in the bar chart (fewer steps means each - * bar is wider). - */ - protected abstract void readData(ISeries series, long start, long end, int nb); - - // initializes a series - private IBarSeries initSeries(String name, RGB color) { - IBarSeries bs = (IBarSeries) getSwtChart().getSeriesSet().createSeries(SeriesType.BAR, name); - bs.enableStack(true); - bs.setBarColor(new Color(Display.getDefault(), color)); - bs.setBarPadding(0); - return bs; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/barcharts/TmfHistogramTooltipProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/barcharts/TmfHistogramTooltipProvider.java deleted file mode 100644 index 6647f6e06e..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/barcharts/TmfHistogramTooltipProvider.java +++ /dev/null @@ -1,179 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ -package org.eclipse.linuxtools.tmf.ui.viewers.xycharts.barcharts; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.ui.viewers.xycharts.ITmfChartTimeProvider; -import org.eclipse.linuxtools.tmf.ui.viewers.xycharts.TmfBaseProvider; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.events.MouseTrackListener; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.widgets.Display; -import org.swtchart.IAxis; -import org.swtchart.ISeries; - -/** - * Tool tip provider for TMF bar chart viewer. It displays the y value of - * position x as well as it highlights the bar of the x position. - * It only considers the first series of the chart. - * - * @author Bernd Hufmann - * @since 3.0 - */ -public class TmfHistogramTooltipProvider extends TmfBaseProvider implements MouseTrackListener, MouseMoveListener, PaintListener { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** X coordinate for highlighting */ - private int fHighlightX; - /** y coordinate for highlighting */ - private int fHighlightY; - /** Flag to do highlighting or not */ - private boolean fIsHighlight; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Constructor for a tool tip provider. - * - * @param tmfChartViewer - * - the parent chart viewer - */ - public TmfHistogramTooltipProvider(ITmfChartTimeProvider tmfChartViewer) { - super(tmfChartViewer); - register(); - } - - // ------------------------------------------------------------------------ - // TmfBaseProvider - // ------------------------------------------------------------------------ - @Override - public void register() { - getChart().getPlotArea().addMouseTrackListener(this); - getChart().getPlotArea().addMouseMoveListener(this); - getChart().getPlotArea().addPaintListener(this); - } - - @Override - public void deregister() { - if ((getChartViewer().getControl() != null) && !getChartViewer().getControl().isDisposed()) { - getChart().getPlotArea().removeMouseTrackListener(this); - getChart().getPlotArea().removeMouseMoveListener(this); - getChart().getPlotArea().removePaintListener(this); - } - } - - @Override - public void refresh() { - // nothing to do - } - - // ------------------------------------------------------------------------ - // MouseTrackListener - // ------------------------------------------------------------------------ - @Override - public void mouseEnter(MouseEvent e) { - } - - @Override - public void mouseExit(MouseEvent e) { - } - - @Override - public void mouseHover(MouseEvent e) { - if (getChartViewer().getWindowDuration() != 0) { - IAxis xAxis = getChart().getAxisSet().getXAxis(0); - IAxis yAxis = getChart().getAxisSet().getYAxis(0); - - double xCoordinate = xAxis.getDataCoordinate(e.x); - - ISeries[] series = getChart().getSeriesSet().getSeries(); - - if ((xCoordinate < 0) || (series.length == 0)) { - return; - } - - double y = 0.0; - double rangeStart = 0.0; - double rangeEnd = 0.0; - - // Consider first series only - double[] xS = series[0].getXSeries(); - double[] yS = series[0].getYSeries(); - - if ((xS == null) || (yS == null)) { - return; - } - - for (int i = 0; i < xS.length - 1; i++) { - int pixel = xAxis.getPixelCoordinate(xS[i]); - if (pixel <= e.x) { - rangeStart = xS[i]; - rangeEnd = (long) xS[i + 1]; - if (xCoordinate >= rangeStart) { - y = yS[i + 1]; - } else { - y = yS[i]; - } - } - } - - ITmfChartTimeProvider viewer = getChartViewer(); - - /* set tooltip of closest data point */ - StringBuffer buffer = new StringBuffer(); - buffer.append("Range=["); //$NON-NLS-1$ - buffer.append(new TmfTimestamp((long) rangeStart + viewer.getTimeOffset(), ITmfTimestamp.NANOSECOND_SCALE).toString()); - buffer.append(','); - buffer.append(new TmfTimestamp((long) rangeEnd + viewer.getTimeOffset(), ITmfTimestamp.NANOSECOND_SCALE).toString()); - buffer.append("]\n"); //$NON-NLS-1$ - buffer.append("y="); //$NON-NLS-1$ - buffer.append((long) y); - getChart().getPlotArea().setToolTipText(buffer.toString()); - - fHighlightX = e.x; - fHighlightY = yAxis.getPixelCoordinate(y); - fIsHighlight = true; - getChart().redraw(); - } - } - - // ------------------------------------------------------------------------ - // MouseMoveListener - // ------------------------------------------------------------------------ - @Override - public void mouseMove(MouseEvent e) { - fIsHighlight = false; - getChart().redraw(); - } - - // ------------------------------------------------------------------------ - // PaintListener - // ------------------------------------------------------------------------ - @Override - public void paintControl(PaintEvent e) { - if (fIsHighlight) { - e.gc.setBackground(Display.getDefault().getSystemColor( - SWT.COLOR_RED)); - e.gc.setAlpha(128); - - e.gc.fillOval(fHighlightX - 5, fHighlightY - 5, 10, 10); - } - } - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/linecharts/TmfCommonXLineChartTooltipProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/linecharts/TmfCommonXLineChartTooltipProvider.java deleted file mode 100644 index 95b72a926c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/linecharts/TmfCommonXLineChartTooltipProvider.java +++ /dev/null @@ -1,129 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.xycharts.linecharts; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.ui.viewers.xycharts.ITmfChartTimeProvider; -import org.eclipse.linuxtools.tmf.ui.viewers.xycharts.TmfBaseProvider; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseTrackListener; -import org.swtchart.IAxis; -import org.swtchart.ISeries; - -/** - * Displays a tooltip on line charts. For each series, it shows the y value at - * the selected x value. This tooltip assumes that all series share a common set - * of X axis values. If the X series is not common, the tooltip text may not be - * accurate. - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfCommonXLineChartTooltipProvider extends TmfBaseProvider implements MouseTrackListener { - - /** - * Constructor for the tooltip provider - * - * @param tmfChartViewer - * The parent chart viewer - */ - public TmfCommonXLineChartTooltipProvider(ITmfChartTimeProvider tmfChartViewer) { - super(tmfChartViewer); - register(); - } - - // ------------------------------------------------------------------------ - // TmfBaseProvider - // ------------------------------------------------------------------------ - - @Override - public void register() { - getChart().getPlotArea().addMouseTrackListener(this); - } - - @Override - public void deregister() { - if ((getChartViewer().getControl() != null) && !getChartViewer().getControl().isDisposed()) { - getChart().getPlotArea().removeMouseTrackListener(this); - } - } - - @Override - public void refresh() { - // nothing to do - } - - // ------------------------------------------------------------------------ - // MouseTrackListener - // ------------------------------------------------------------------------ - - @Override - public void mouseEnter(MouseEvent e) { - } - - @Override - public void mouseExit(MouseEvent e) { - } - - @Override - public void mouseHover(MouseEvent e) { - if (getChartViewer().getWindowDuration() != 0) { - IAxis xAxis = getChart().getAxisSet().getXAxis(0); - - double xCoordinate = xAxis.getDataCoordinate(e.x); - - ISeries[] series = getChart().getSeriesSet().getSeries(); - - if ((xCoordinate < 0) || (series.length == 0)) { - return; - } - - /* Find the index of the value we want */ - double[] xS = series[0].getXSeries(); - if (xS == null) { - return; - } - int index = 0; - for (int i = 0; i < xS.length; i++) { - if (xS[i] > xCoordinate) { - break; - } - index = i; - } - - /* set tooltip of closest data point */ - StringBuffer buffer = new StringBuffer(); - buffer.append("time="); //$NON-NLS-1$ - buffer.append(new TmfTimestamp((long) xCoordinate + getChartViewer().getTimeOffset(), ITmfTimestamp.NANOSECOND_SCALE).toString()); - buffer.append('\n'); - - /* For each series, get the value at the index */ - for (ISeries serie : series) { - double[] yS = serie.getYSeries(); - /* Make sure the series values and the value at index exist */ - if (yS == null || yS.length <= index) { - continue; - } - buffer.append(serie.getId()); - buffer.append('='); - buffer.append(yS[index]); - buffer.append('\n'); - } - - getChart().getPlotArea().setToolTipText(buffer.toString()); - getChart().redraw(); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/linecharts/TmfCommonXLineChartViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/linecharts/TmfCommonXLineChartViewer.java deleted file mode 100644 index d292817c68..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/xycharts/linecharts/TmfCommonXLineChartViewer.java +++ /dev/null @@ -1,374 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.viewers.xycharts.linecharts; - -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Map.Entry; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.TmfUiRefreshHandler; -import org.eclipse.linuxtools.tmf.ui.viewers.xycharts.TmfChartTimeStampFormat; -import org.eclipse.linuxtools.tmf.ui.viewers.xycharts.TmfXYChartViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.swtchart.IAxisTick; -import org.swtchart.ILineSeries; -import org.swtchart.ILineSeries.PlotSymbolType; -import org.swtchart.ISeries; -import org.swtchart.ISeries.SeriesType; -import org.swtchart.ISeriesSet; -import org.swtchart.LineStyle; -import org.swtchart.Range; - -/** - * Abstract line chart viewer class implementation. All series in this viewer - * use the same X axis values. They are automatically created as values are - * provided for a key. Series by default will be displayed as a line. Each - * series appearance can be overridden when creating it. - * - * @author - Geneviève Bastien - * @since 3.0 - */ -public abstract class TmfCommonXLineChartViewer extends TmfXYChartViewer { - - private static final double DEFAULT_MAXY = Double.MIN_VALUE; - private static final double DEFAULT_MINY = Double.MAX_VALUE; - - /* The desired number of points per pixel */ - private static final double RESOLUTION = 1.0; - - private static final int[] LINE_COLORS = { SWT.COLOR_BLUE, SWT.COLOR_RED, SWT.COLOR_GREEN, - SWT.COLOR_MAGENTA, SWT.COLOR_CYAN, - SWT.COLOR_DARK_BLUE, SWT.COLOR_DARK_RED, SWT.COLOR_DARK_GREEN, - SWT.COLOR_DARK_MAGENTA, SWT.COLOR_DARK_CYAN, SWT.COLOR_DARK_YELLOW, - SWT.COLOR_BLACK, SWT.COLOR_GRAY }; - private static final LineStyle[] LINE_STYLES = { LineStyle.SOLID, LineStyle.DASH, LineStyle.DOT, LineStyle.DASHDOT }; - - private final Map fSeriesValues = new LinkedHashMap<>(); - private double[] fXValues; - private double fResolution; - - private UpdateThread fUpdateThread; - - /** - * Constructor - * - * @param parent - * The parent composite - * @param title - * The title of the viewer - * @param xLabel - * The label of the xAxis - * @param yLabel - * The label of the yAXIS - */ - public TmfCommonXLineChartViewer(Composite parent, String title, String xLabel, String yLabel) { - super(parent, title, xLabel, yLabel); - - setResolution(RESOLUTION); - setTooltipProvider(new TmfCommonXLineChartTooltipProvider(this)); - } - - /** - * Set the number of requests per pixel that should be done on this chart - * - * @param resolution - * The number of points per pixels - */ - protected void setResolution(double resolution) { - fResolution = resolution; - } - - @Override - public void loadTrace(ITmfTrace trace) { - super.loadTrace(trace); - reinitialize(); - } - - /** - * Forces a reinitialization of the data sources, even if it has already - * been initialized for this trace before - * - * @since 3.1 - */ - protected void reinitialize() { - fSeriesValues.clear(); - Thread thread = new Thread() { - @Override - public void run() { - initializeDataSource(); - TmfUiRefreshHandler.getInstance().queueUpdate(TmfCommonXLineChartViewer.this, - new Runnable() { - @Override - public void run() { - if (!getSwtChart().isDisposed()) { - /* Delete the old series */ - clearContent(); - createSeries(); - } - } - }); - } - }; - thread.start(); - } - - /** - * Initialize the source of the data for this viewer. This method is run in - * a separate thread, so this is where for example one can execute an - * analysis module and wait for its completion to initialize the series - */ - protected void initializeDataSource() { - - } - - private class UpdateThread extends Thread { - private final IProgressMonitor fMonitor; - private final int fNumRequests; - - public UpdateThread(int numRequests) { - super("Line chart update"); //$NON-NLS-1$ - fNumRequests = numRequests; - fMonitor = new NullProgressMonitor(); - } - - @Override - public void run() { - updateData(getWindowStartTime(), getWindowEndTime(), fNumRequests, fMonitor); - updateThreadFinished(this); - } - - public void cancel() { - fMonitor.setCanceled(true); - } - } - - private synchronized void newUpdateThread() { - cancelUpdate(); - final int numRequests = (int) (getSwtChart().getPlotArea().getBounds().width * fResolution); - fUpdateThread = new UpdateThread(numRequests); - fUpdateThread.start(); - } - - private synchronized void updateThreadFinished(UpdateThread thread) { - if (thread == fUpdateThread) { - fUpdateThread = null; - } - } - - /** - * Cancels the currently running update thread. It is automatically called - * when the content is updated, but child viewers may want to call it - * manually to do some operations before calling - * {@link TmfCommonXLineChartViewer#updateContent} - */ - protected synchronized void cancelUpdate() { - if (fUpdateThread != null) { - fUpdateThread.cancel(); - } - } - - @Override - protected void updateContent() { - getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - newUpdateThread(); - } - }); - } - - /** - * Convenience method to compute the values of the X axis for a given time - * range. This method will return nb values depending, equally separated - * from start to end. - * - * The returned time values are in internal time, ie to get trace time, the - * time offset needs to be added to those values. - * - * @param start - * The start time of the time range - * @param end - * End time of the range - * @param nb - * The number of steps in the x axis. - * @return The time values (converted to double) to match every step. - */ - protected final double[] getXAxis(long start, long end, int nb) { - setTimeOffset(start - 1); - - double timestamps[] = new double[nb]; - long steps = (end - start); - double step = steps / (double) nb; - - double curTime = 1; - for (int i = 0; i < nb; i++) { - timestamps[i] = curTime; - curTime += step; - } - return timestamps; - } - - /** - * Set the values of the x axis. There is only one array of values for the x - * axis for all series of a line chart so it needs to be set once here. - * - * @param xaxis - * The values for the x axis. The values must be in internal - * time, ie time offset have been subtracted from trace time - * values. - */ - protected final void setXAxis(double[] xaxis) { - fXValues = xaxis; - } - - /** - * Update the series data because the time range has changed. The x axis - * values for this data update can be computed using the - * {@link TmfCommonXLineChartViewer#getXAxis(long, long, int)} method which - * will return a list of uniformely separated time values. - * - * Each series values should be set by calling the - * {@link TmfCommonXLineChartViewer#setSeries(String, double[])}. - * - * This method is responsible for calling the - * {@link TmfCommonXLineChartViewer#updateDisplay()} when needed for the new - * values to be displayed. - * - * @param start - * The start time of the range for which the get the data - * @param end - * The end time of the range - * @param nb - * The number of 'points' in the chart. - * @param monitor - * The progress monitor object - */ - protected abstract void updateData(long start, long end, int nb, IProgressMonitor monitor); - - /** - * Set the data for a given series of the graph. The series does not need to - * be created before calling this, but it needs to have at least as many - * values as the x axis. - * - * If the series does not exist, it will automatically be created at display - * time, with the default values. - * - * @param seriesName - * The name of the series for which to set the values - * @param seriesValues - * The array of values for the series - */ - protected void setSeries(String seriesName, double[] seriesValues) { - if (fXValues.length > seriesValues.length) { - throw new IllegalStateException(); - } - fSeriesValues.put(seriesName, seriesValues); - } - - /** - * Add a new series to the XY line chart. By default, it is a simple solid - * line. - * - * @param seriesName - * The name of the series to create - * @return The series so that the concrete viewer can modify its properties - * if required - */ - protected ILineSeries addSeries(String seriesName) { - ISeriesSet seriesSet = getSwtChart().getSeriesSet(); - int seriesCount = seriesSet.getSeries().length; - ILineSeries series = (ILineSeries) seriesSet.createSeries(SeriesType.LINE, seriesName); - series.setVisible(true); - series.enableArea(false); - series.setLineStyle(LINE_STYLES[(seriesCount / (LINE_COLORS.length)) % LINE_STYLES.length]); - series.setSymbolType(PlotSymbolType.NONE); - series.setLineColor(Display.getDefault().getSystemColor(LINE_COLORS[seriesCount % LINE_COLORS.length])); - return series; - } - - /** - * Delete a series from the chart and its values from the viewer. - * - * @param seriesName - * Name of the series to delete - */ - protected void deleteSeries(String seriesName) { - ISeries series = getSwtChart().getSeriesSet().getSeries(seriesName); - if (series != null) { - getSwtChart().getSeriesSet().deleteSeries(series.getId()); - } - fSeriesValues.remove(seriesName); - } - - /** - * Update the chart's values before refreshing the viewer - */ - protected void updateDisplay() { - Display.getDefault().asyncExec(new Runnable() { - final TmfChartTimeStampFormat tmfChartTimeStampFormat = new TmfChartTimeStampFormat(getTimeOffset()); - - @Override - public void run() { - if (!getSwtChart().isDisposed()) { - double maxy = DEFAULT_MAXY; - double miny = DEFAULT_MINY; - for (Entry entry : fSeriesValues.entrySet()) { - ILineSeries series = (ILineSeries) getSwtChart().getSeriesSet().getSeries(entry.getKey()); - if (series == null) { - series = addSeries(entry.getKey()); - } - series.setXSeries(fXValues); - /* Find the minimal and maximum values in this series */ - for (double value : entry.getValue()) { - maxy = Math.max(maxy, value); - miny = Math.min(miny, value); - } - series.setYSeries(entry.getValue()); - } - if (maxy == DEFAULT_MAXY) { - maxy = 1.0; - } - - IAxisTick xTick = getSwtChart().getAxisSet().getXAxis(0).getTick(); - xTick.setFormat(tmfChartTimeStampFormat); - - final double start = fXValues[0]; - int lastX = fXValues.length - 1; - double end = (start == fXValues[lastX]) ? start + 1 : fXValues[lastX]; - getSwtChart().getAxisSet().getXAxis(0).setRange(new Range(start, end)); - getSwtChart().getAxisSet().getXAxis(0).adjustRange(); - if (maxy > miny) { - getSwtChart().getAxisSet().getYAxis(0).setRange(new Range(miny, maxy)); - } - getSwtChart().redraw(); - } - } - }); - } - - /** - * Create the series once the initialization of the viewer's data source is - * done. Series do not need to be created before setting their values, but - * if their appearance needs to be customized, this method is a good place - * to do so. It is called only once per trace. - */ - protected void createSeries() { - - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/PinTmfViewAction.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/PinTmfViewAction.java deleted file mode 100644 index 961e947cfe..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/PinTmfViewAction.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ui.views; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; - -/** - * - * @version 1.0 - * @author Bernd Hufmann - * @since 2.0 - */ -public class PinTmfViewAction extends Action { - /** - * Creates a new PinPropertySheetAction. - */ - public PinTmfViewAction() { - super(Messages.TmfView_PinActionNameText, IAction.AS_CHECK_BOX); - - setId("org.eclipse.linuxtools.tmf.ui.views.PinTmfViewAction"); //$NON-NLS-1$ - setToolTipText(Messages.TmfView_PinActionToolTipText); - setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PIN_VIEW)); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/TmfChartView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/TmfChartView.java deleted file mode 100644 index 59417bac22..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/TmfChartView.java +++ /dev/null @@ -1,118 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ -package org.eclipse.linuxtools.tmf.ui.views; - -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.viewers.xycharts.TmfXYChartViewer; -import org.eclipse.swt.widgets.Composite; - -/** - * Base class to be used with a chart viewer {@link TmfXYChartViewer}. - * It is responsible to instantiate the viewer class and load the trace - * into the viewer when the view is created. - * - * @author Bernd Hufmann - * @since 3.0 - */ -abstract public class TmfChartView extends TmfView { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** The TMF XY Chart reference */ - private TmfXYChartViewer fChartViewer; - /** The Trace reference */ - private ITmfTrace fTrace; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Standard Constructor - * - * @param viewName - * The view name - */ - public TmfChartView(String viewName) { - super(viewName); - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - /** - * Returns the TMF XY chart viewer implementation. - * - * @return the TMF XY chart viewer {@link TmfXYChartViewer} - */ - protected TmfXYChartViewer getChartViewer() { - return fChartViewer; - } - - /** - * Sets the TMF XY chart viewer implementation. - * - * @param chartViewer - * The TMF XY chart viewer {@link TmfXYChartViewer} - */ - protected void setChartViewer(TmfXYChartViewer chartViewer) { - fChartViewer = chartViewer; - } - - /** - * Returns the ITmfTrace implementation - * - * @return the ITmfTrace implementation {@link ITmfTrace} - */ - protected ITmfTrace getTrace() { - return fTrace; - } - - /** - * Sets the ITmfTrace implementation - * - * @param trace - * The ITmfTrace implementation {@link ITmfTrace} - */ - protected void setTrace(ITmfTrace trace) { - fTrace = trace; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - @Override - public void createPartControl(Composite parent) { - ITmfTrace trace = getActiveTrace(); - if (trace != null) { - setTrace(trace); - loadTrace(); - } - } - - @Override - public void dispose() { - if (fChartViewer != null) { - fChartViewer.dispose(); - } - } - - /** - * Load the trace into view. - */ - protected void loadTrace() { - if (fChartViewer != null) { - fChartViewer.loadTrace(fTrace); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/TmfView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/TmfView.java deleted file mode 100644 index ace756e65e..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/TmfView.java +++ /dev/null @@ -1,149 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Added possibility to pin view - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views; - -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.linuxtools.tmf.core.component.ITmfComponent; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ui.editors.ITmfTraceEditor; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbenchActionConstants; -import org.eclipse.ui.part.ViewPart; - -/** - * Basic abstract TMF view class implementation. - * - * It registers any sub class to the signal manager for receiving and sending - * TMF signals. - * - * @version 1.2 - * @author Francois Chouinard - */ -public abstract class TmfView extends ViewPart implements ITmfComponent { - - private final String fName; - - /** - * Action class for pinning of TmfView. - * @since 2.0 - */ - protected PinTmfViewAction fPinAction; - - /** - * Reference to the trace manager - * @since 2.0 - */ - protected final TmfTraceManager fTraceManager; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructor. Creates a TMF view and registers to the signal manager. - * - * @param viewName - * A view name - */ - public TmfView(String viewName) { - super(); - fName = viewName; - fTraceManager = TmfTraceManager.getInstance(); - TmfSignalManager.register(this); - } - - /** - * Disposes this view and de-registers itself from the signal manager - */ - @Override - public void dispose() { - TmfSignalManager.deregister(this); - super.dispose(); - } - - // ------------------------------------------------------------------------ - // ITmfComponent - // ------------------------------------------------------------------------ - - @Override - public String getName() { - return fName; - } - - @Override - public void broadcast(TmfSignal signal) { - TmfSignalManager.dispatchSignal(signal); - } - - /** - * @since 3.0 - */ - @Override - public void broadcastAsync(TmfSignal signal) { - TmfSignalManager.dispatchSignalAsync(signal); - } - - // ------------------------------------------------------------------------ - // View pinning support - // ------------------------------------------------------------------------ - - /** - * Returns whether the pin flag is set. - * For example, this flag can be used to ignore time synchronization signals from other TmfViews. - * - * @return pin flag - * @since 2.0 - */ - public boolean isPinned() { - return ((fPinAction != null) && (fPinAction.isChecked())); - } - - /** - * Method adds a pin action to the TmfView. The pin action allows to toggle the fIsPinned flag. - * For example, this flag can be used to ignore time synchronization signals from other TmfViews. - * - * @since 2.0 - */ - protected void contributePinActionToToolBar() { - if (fPinAction == null) { - fPinAction = new PinTmfViewAction(); - - IToolBarManager toolBarManager = getViewSite().getActionBars() - .getToolBarManager(); - toolBarManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); - toolBarManager.add(fPinAction); - } - } - - /** - * Get the currently selected trace, or 'null' if the active editor is not a - * TMF trace. - * - * @return The active trace, or 'null' if not a trace - * @since 2.0 - */ - public ITmfTrace getActiveTrace() { - IEditorPart editor = getSite().getPage().getActiveEditor(); - if (editor instanceof ITmfTraceEditor) { - ITmfTrace trace = ((ITmfTraceEditor) editor).getTrace(); - return trace; - } - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/TracingPerspectiveFactory.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/TracingPerspectiveFactory.java deleted file mode 100644 index cc721d7375..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/TracingPerspectiveFactory.java +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views; - -import org.eclipse.linuxtools.tmf.ui.project.wizards.NewTmfProjectWizard; -import org.eclipse.linuxtools.tmf.ui.views.histogram.HistogramView; -import org.eclipse.linuxtools.tmf.ui.views.statistics.TmfStatisticsView; -import org.eclipse.ui.IFolderLayout; -import org.eclipse.ui.IPageLayout; -import org.eclipse.ui.IPerspectiveFactory; - -/** - * The tracing perspective definition. - * - * @version 1.0 - * @author Francois Chouinard - */ -public class TracingPerspectiveFactory implements IPerspectiveFactory { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** The Perspective ID */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.perspective"; //$NON-NLS-1$ - - // Standard TMF views - private static final String HISTOGRAM_VIEW_ID = HistogramView.ID; - - // Standard Eclipse views - private static final String PROJECT_VIEW_ID = IPageLayout.ID_PROJECT_EXPLORER; - private static final String STATISTICS_VIEW_ID = TmfStatisticsView.ID; - private static final String PROPERTIES_VIEW_ID = IPageLayout.ID_PROP_SHEET; - private static final String BOOKMARKS_VIEW_ID = IPageLayout.ID_BOOKMARKS; - - - // ------------------------------------------------------------------------ - // IPerspectiveFactory - // ------------------------------------------------------------------------ - - @Override - public void createInitialLayout(IPageLayout layout) { - - // Editor area - layout.setEditorAreaVisible(true); - - // Create the top left folder - IFolderLayout topLeftFolder = layout.createFolder( - "topLeftFolder", IPageLayout.LEFT, 0.15f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$ - topLeftFolder.addView(PROJECT_VIEW_ID); - - // Create the middle right folder - IFolderLayout middleRightFolder = layout.createFolder( - "middleRightFolder", IPageLayout.BOTTOM, 0.50f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$ - middleRightFolder.addView(STATISTICS_VIEW_ID); - - // Create the bottom right folder - IFolderLayout bottomRightFolder = layout.createFolder( - "bottomRightFolder", IPageLayout.BOTTOM, 0.55f, "middleRightFolder"); //$NON-NLS-1$ //$NON-NLS-2$ - bottomRightFolder.addView(HISTOGRAM_VIEW_ID); - bottomRightFolder.addView(PROPERTIES_VIEW_ID); - bottomRightFolder.addView(BOOKMARKS_VIEW_ID); - - // Populate menus, etc - layout.addPerspectiveShortcut(ID); - layout.addNewWizardShortcut(NewTmfProjectWizard.ID); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/AbstractCallStackAnalysis.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/AbstractCallStackAnalysis.java deleted file mode 100644 index d52a70211c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/AbstractCallStackAnalysis.java +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - * Patrick Tasse - Add methods to get attribute paths - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.callstack; - -import org.eclipse.linuxtools.tmf.core.callstack.CallStackStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.ui.analysis.TmfAnalysisViewOutput; - -/** - * The base classes for analyses who want to populate the CallStack View. - * - * @author Alexandre Montplaisir - * @since 3.0 - */ -public abstract class AbstractCallStackAnalysis extends TmfStateSystemAnalysisModule { - - private static final String[] DEFAULT_THREADS_PATTERN = - new String[] { CallStackStateProvider.THREADS, "*" }; //$NON-NLS-1$; - - private static final String[] DEFAULT_CALL_STACK_PATH = - new String[] { CallStackStateProvider.CALL_STACK }; - - /** - * Abstract constructor (should only be called via the sub-classes' - * constructors. - */ - public AbstractCallStackAnalysis() { - super(); - registerOutput(new TmfAnalysisViewOutput(CallStackView.ID)); - } - - /** - * Get the pattern of thread attributes. Override this method if the state - * system attributes do not match the default pattern defined by - * {@link CallStackStateProvider}. - * - * @return the absolute pattern of the thread attributes - * @since 3.1 - */ - public String[] getThreadsPattern() { - return DEFAULT_THREADS_PATTERN; - } - - /** - * Get the call stack attribute path relative to a thread attribute found by - * {@link #getThreadsPattern()}. Override this method if the state system - * attributes do not match the default pattern defined by - * {@link CallStackStateProvider}. - * - * @return the relative path of the call stack attribute - * @since 3.1 - */ - public String[] getCallStackPath() { - return DEFAULT_CALL_STACK_PATH; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackEntry.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackEntry.java deleted file mode 100644 index 32ca48b38a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackEntry.java +++ /dev/null @@ -1,192 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.callstack; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry; - -/** - * An entry, or row, in the Call Stack view - * - * @author Patrick Tasse - * @since 2.0 - */ -public class CallStackEntry extends TimeGraphEntry { - - private final int fQuark; - private final int fStackLevel; - private final ITmfTrace fTrace; - private String fFunctionName; - private long fFunctionEntryTime; - private long fFunctionExitTime; - private @NonNull ITmfStateSystem fSS; - - /** - * Standard constructor - * - * @param quark - * The call stack quark - * @param stackLevel - * The stack level - * @param trace - * The trace that this view is talking about - * @deprecated Use {@link #CallStackEntry(String, int, int, ITmfTrace, ITmfStateSystem)} - */ - @Deprecated - public CallStackEntry(int quark, int stackLevel, ITmfTrace trace) { - super(null, 0, 0); - throw new UnsupportedOperationException(); - } - - /** - * Standard constructor - * - * @param name - * The parent thread name - * @param quark - * The call stack quark - * @param stackLevel - * The stack level - * @param trace - * The trace that this view is talking about - * @param ss - * The call stack state system - * @since 3.1 - */ - public CallStackEntry(String name, int quark, int stackLevel, ITmfTrace trace, @NonNull ITmfStateSystem ss) { - super(name, 0, 0); - fQuark = quark; - fStackLevel = stackLevel; - fTrace = trace; - fFunctionName = ""; //$NON-NLS-1$ - fSS = ss; - } - - /** - * Get the function name of the call stack entry - * @return the function name - */ - public String getFunctionName() { - return fFunctionName; - } - - /** - * Set the function name of the call stack entry - * @param functionName the function name - */ - public void setFunctionName(String functionName) { - fFunctionName = functionName; - } - - /** - * Set the start time of the call stack entry - * @param startTime the start time - * @deprecated Use {@link #setFunctionEntryTime(long)} - */ - @Deprecated - public void setStartTime(long startTime) { - throw new UnsupportedOperationException(); - } - - /** - * Set the end time of the call stack entry - * @param endTime the end time - * @deprecated Use {@link #setFunctionExitTime(long)} - */ - @Deprecated - public void setEndTime(long endTime) { - throw new UnsupportedOperationException(); - } - - /** - * Set the selected function entry time - * - * @param entryTime - * the function entry time - * @since 3.1 - */ - public void setFunctionEntryTime(long entryTime) { - fFunctionEntryTime = entryTime; - } - - /** - * Get the selected function entry time - * - * @return the function entry time - * @since 3.1 - */ - public long getFunctionEntryTime() { - return fFunctionEntryTime; - } - - /** - * Set the selected function exit time - * - * @param exitTime - * the function exit time - * @since 3.1 - */ - public void setFunctionExitTime(long exitTime) { - fFunctionExitTime = exitTime; - } - - /** - * Get the selected function exit time - * - * @return the function exit time - * @since 3.1 - */ - public long getFunctionExitTime() { - return fFunctionExitTime; - } - - /** - * Retrieve the attribute quark that's represented by this entry. - * - * @return The integer quark - */ - public int getQuark() { - return fQuark; - } - - /** - * Retrieve the stack level associated with this entry. - * - * @return The stack level or 0 - */ - public int getStackLevel() { - return fStackLevel; - } - - /** - * Retrieve the trace that is associated to this view. - * - * @return The trace - */ - public ITmfTrace getTrace() { - return fTrace; - } - - /** - * Retrieve the call stack state system associated with this entry. - * - * @return The call stack state system - * @since 3.1 - */ - public @NonNull ITmfStateSystem getStateSystem() { - return fSS; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackEvent.java deleted file mode 100644 index 171ecee6dc..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackEvent.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.callstack; - -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeEvent; - -/** - * Time Event implementation specific to the Call Stack View - * - * @author Patrick Tasse - * @since 2.0 - */ -public class CallStackEvent extends TimeEvent { - - /** - * Standard constructor - * - * @param entry - * The entry that this event affects - * @param time - * The start time of the event - * @param duration - * The duration of the event - * @param value - * The event value (1-256) - */ - public CallStackEvent(CallStackEntry entry, long time, long duration, int value) { - super(entry, time, duration, value); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackPresentationProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackPresentationProvider.java deleted file mode 100644 index 0fc2f6b774..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackPresentationProvider.java +++ /dev/null @@ -1,153 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.callstack; - -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.StateItem; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.NullTimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.graphics.Rectangle; - -/** - * Presentation provider for the Call Stack view, based on the generic TMF - * presentation provider. - * - * @author Patrick Tasse - * @since 2.0 - */ -public class CallStackPresentationProvider extends TimeGraphPresentationProvider { - - /** Number of colors used for call stack events */ - public static final int NUM_COLORS = 360; - - private final CallStackView fView; - - private Integer fAverageCharWidth; - - private enum State { - MULTIPLE (new RGB(100, 100, 100)), - EXEC (new RGB(0, 200, 0)); - - private final RGB rgb; - - private State (RGB rgb) { - this.rgb = rgb; - } - } - - /** - * Constructor - * - * @param view - * The callstack view that will contain the time events - * @since 3.0 - */ - public CallStackPresentationProvider(CallStackView view) { - fView = view; - } - - @Override - public String getStateTypeName(ITimeGraphEntry entry) { - return Messages.CallStackPresentationProvider_Thread; - } - - @Override - public StateItem[] getStateTable() { - final float saturation = 0.6f; - final float brightness = 0.6f; - StateItem[] stateTable = new StateItem[NUM_COLORS + 1]; - stateTable[0] = new StateItem(State.MULTIPLE.rgb, State.MULTIPLE.toString()); - for (int i = 0; i < NUM_COLORS; i++) { - RGB rgb = new RGB(i, saturation, brightness); - stateTable[i + 1] = new StateItem(rgb, State.EXEC.toString()); - } - return stateTable; - } - - @Override - public int getStateTableIndex(ITimeEvent event) { - if (event instanceof CallStackEvent) { - CallStackEvent callStackEvent = (CallStackEvent) event; - return callStackEvent.getValue() + 1; - } else if (event instanceof NullTimeEvent) { - return INVISIBLE; - } - return State.MULTIPLE.ordinal(); - } - - @Override - public String getEventName(ITimeEvent event) { - if (event instanceof CallStackEvent) { - CallStackEntry entry = (CallStackEntry) event.getEntry(); - ITmfStateSystem ss = entry.getStateSystem(); - try { - ITmfStateValue value = ss.querySingleState(event.getTime(), entry.getQuark()).getStateValue(); - if (!value.isNull()) { - String address = value.toString(); - return fView.getFunctionName(address); - } - } catch (AttributeNotFoundException e) { - Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ - } catch (TimeRangeException e) { - Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ - } catch (StateSystemDisposedException e) { - /* Ignored */ - } - return null; - } - return State.MULTIPLE.toString(); - } - - @Override - public void postDrawEvent(ITimeEvent event, Rectangle bounds, GC gc) { - if (fAverageCharWidth == null) { - fAverageCharWidth = gc.getFontMetrics().getAverageCharWidth(); - } - if (bounds.width <= fAverageCharWidth) { - return; - } - if (!(event instanceof CallStackEvent)) { - return; - } - CallStackEntry entry = (CallStackEntry) event.getEntry(); - ITmfStateSystem ss = entry.getStateSystem(); - try { - ITmfStateValue value = ss.querySingleState(event.getTime(), entry.getQuark()).getStateValue(); - if (!value.isNull()) { - String address = value.toString(); - String name = fView.getFunctionName(address); - gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE)); - Utils.drawText(gc, name, bounds.x, bounds.y - 2, bounds.width, true, true); - } - } catch (AttributeNotFoundException e) { - Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ - } catch (TimeRangeException e) { - Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ - } catch (StateSystemDisposedException e) { - /* Ignored */ - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackView.java deleted file mode 100644 index d34a76ac84..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackView.java +++ /dev/null @@ -1,1569 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Bernd Hufmann - Updated signal handling - * Marc-Andre Laperle - Map from binary file - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.callstack; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CopyOnWriteArrayList; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IStatusLineManager; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.jface.viewers.DoubleClickEvent; -import org.eclipse.jface.viewers.IDoubleClickListener; -import org.eclipse.jface.viewers.ILabelProviderListener; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.ITableLabelProvider; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type; -import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampDelta; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ui.editors.ITmfTraceEditor; -import org.eclipse.linuxtools.tmf.ui.views.TmfView; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphContentProvider; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphRangeListener; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphTimeListener; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphCombo; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphViewer; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.NullTimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphControl; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphSelection; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ControlAdapter; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.ui.IActionBars; -import org.eclipse.ui.IEditorPart; - -/** - * Main implementation for the Call Stack view - * - * @author Patrick Tasse - * @since 2.0 - */ -public class CallStackView extends TmfView { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** View ID. */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.callstack"; //$NON-NLS-1$ - - /** - * Redraw state enum - */ - private enum State { - IDLE, BUSY, PENDING - } - - private static final String[] COLUMN_TIMES = new String[] { - Messages.CallStackView_FunctionColumn, - Messages.CallStackView_DepthColumn, - Messages.CallStackView_EntryTimeColumn, - Messages.CallStackView_ExitTimeColumn, - Messages.CallStackView_DurationColumn - }; - - private static final int[] COLUMN_WIDTHS = new int[] { - 200, - 50, - 120, - 120, - 120 - }; - - /** Timeout between updates in the build thread in ms */ - private static final long BUILD_UPDATE_TIMEOUT = 500; - - // Fraction of a function duration to be added as spacing - private static final double SPACING_RATIO = 0.01; - - private static final Image THREAD_IMAGE = Activator.getDefault().getImageFromPath("icons/obj16/thread_obj.gif"); //$NON-NLS-1$ - private static final Image STACKFRAME_IMAGE = Activator.getDefault().getImageFromPath("icons/obj16/stckframe_obj.gif"); //$NON-NLS-1$ - - private static final String IMPORT_MAPPING_ICON_PATH = "icons/etool16/import.gif"; //$NON-NLS-1$ - private static final String IMPORT_BINARY_ICON_PATH = "icons/obj16/binaries_obj.gif"; //$NON-NLS-1$ - - private static final ImageDescriptor SORT_BY_NAME_ICON = Activator.getDefault().getImageDescripterFromPath("icons/etool16/sort_alpha.gif"); //$NON-NLS-1$ - private static final ImageDescriptor SORT_BY_NAME_REV_ICON = Activator.getDefault().getImageDescripterFromPath("icons/etool16/sort_alpha_rev.gif"); //$NON-NLS-1$ - private static final ImageDescriptor SORT_BY_ID_ICON = Activator.getDefault().getImageDescripterFromPath("icons/etool16/sort_num.gif"); //$NON-NLS-1$ - private static final ImageDescriptor SORT_BY_ID_REV_ICON = Activator.getDefault().getImageDescripterFromPath("icons/etool16/sort_num_rev.gif"); //$NON-NLS-1$ - private static final ImageDescriptor SORT_BY_TIME_ICON = Activator.getDefault().getImageDescripterFromPath("icons/etool16/sort_time.gif"); //$NON-NLS-1$ - private static final ImageDescriptor SORT_BY_TIME_REV_ICON = Activator.getDefault().getImageDescripterFromPath("icons/etool16/sort_time_rev.gif"); //$NON-NLS-1$ - private static final String SORT_OPTION_KEY = "sort.option"; //$NON-NLS-1$ - - private enum SortOption { - BY_NAME, BY_NAME_REV, BY_ID, BY_ID_REV, BY_TIME, BY_TIME_REV - } - - private SortOption fSortOption; - private Comparator fThreadComparator = null; - private Action fSortByNameAction; - private Action fSortByIdAction; - private Action fSortByTimeAction; - - // ------------------------------------------------------------------------ - // Fields - // ------------------------------------------------------------------------ - - // The time graph combo - private TimeGraphCombo fTimeGraphCombo; - - // The selected trace - private ITmfTrace fTrace; - - // The selected thread map - private final Map fSelectedThreadMap = new HashMap<>(); - - // The time graph entry list - private List fEntryList; - - // The trace to entry list hash map - private final Map> fEntryListMap = new HashMap<>(); - - // The trace to build thread hash map - private final Map fBuildThreadMap = new HashMap<>(); - - /** The map to map function addresses to function names */ - private Map fNameMapping; - - // The start time - private long fStartTime; - - // The end time - private long fEndTime; - - // The display width - private int fDisplayWidth; - - // The next event action - private Action fNextEventAction; - - // The previous event action - private Action fPrevEventAction; - - // The next item action - private Action fNextItemAction; - - // The previous item action - private Action fPreviousItemAction; - - // The action to import a function-name mapping file - private Action fImportMappingAction; - - // The action to import a binary file mapping */ - private Action fImportBinaryFileMappingAction; - - // The zoom thread - private ZoomThread fZoomThread; - - // The redraw state used to prevent unnecessary queuing of display runnables - private State fRedrawState = State.IDLE; - - // The redraw synchronization object - private final Object fSyncObj = new Object(); - - // The saved time sync. signal used when switching off the pinning of a view - private TmfTimeSynchSignal fSavedTimeSyncSignal; - - // The saved time range sync. signal used when switching off the pinning of - // a view - private TmfRangeSynchSignal fSavedRangeSyncSignal; - - // ------------------------------------------------------------------------ - // Classes - // ------------------------------------------------------------------------ - - private class TraceEntry extends TimeGraphEntry { - public TraceEntry(String name, long startTime, long endTime) { - super(name, startTime, endTime); - } - - @Override - public boolean hasTimeEvents() { - return false; - } - } - - private class ThreadEntry extends TimeGraphEntry { - // The call stack quark - private final int fCallStackQuark; - // The state system from which this entry comes - private final ITmfStateSystem fSS; - // The thread id - private final long fThreadId; - - public ThreadEntry(ITmfStateSystem ss, String name, long threadId, int callStackQuark, long startTime, long endTime) { - super(name, startTime, endTime); - fCallStackQuark = callStackQuark; - fThreadId = threadId; - fSS = ss; - } - - @Override - public boolean hasTimeEvents() { - return false; - } - - public int getCallStackQuark() { - return fCallStackQuark; - } - - public long getThreadId() { - return fThreadId; - } - - @Nullable - public ITmfStateSystem getStateSystem() { - return fSS; - } - } - - private class ThreadNameComparator implements Comparator { - private boolean reverse; - - public ThreadNameComparator(boolean reverse) { - this.reverse = reverse; - } - - @Override - public int compare(ITimeGraphEntry o1, ITimeGraphEntry o2) { - return reverse ? o2.getName().compareTo(o1.getName()) : - o1.getName().compareTo(o2.getName()); - } - } - - private class ThreadIdComparator implements Comparator { - private boolean reverse; - - public ThreadIdComparator(boolean reverse) { - this.reverse = reverse; - } - - @Override - public int compare(ITimeGraphEntry o1, ITimeGraphEntry o2) { - ThreadEntry t1 = (ThreadEntry) o1; - ThreadEntry t2 = (ThreadEntry) o2; - return reverse ? Long.compare(t2.getThreadId(), t1.getThreadId()) : - Long.compare(t1.getThreadId(), t2.getThreadId()); - } - } - - private class ThreadTimeComparator implements Comparator { - private boolean reverse; - - public ThreadTimeComparator(boolean reverse) { - this.reverse = reverse; - } - - @Override - public int compare(ITimeGraphEntry o1, ITimeGraphEntry o2) { - return reverse ? Long.compare(o2.getStartTime(), o1.getStartTime()) : - Long.compare(o1.getStartTime(), o2.getStartTime()); - } - } - - private class TreeContentProvider implements ITreeContentProvider { - - @Override - public void dispose() { - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - @Override - public Object[] getElements(Object inputElement) { - if (inputElement != null) { - try { - return ((List) inputElement).toArray(new ITimeGraphEntry[0]); - } catch (ClassCastException e) { - } - } - return new ITimeGraphEntry[0]; - } - - @Override - public Object[] getChildren(Object parentElement) { - ITimeGraphEntry entry = (ITimeGraphEntry) parentElement; - return entry.getChildren().toArray(); - } - - @Override - public Object getParent(Object element) { - ITimeGraphEntry entry = (ITimeGraphEntry) element; - return entry.getParent(); - } - - @Override - public boolean hasChildren(Object element) { - ITimeGraphEntry entry = (ITimeGraphEntry) element; - return entry.hasChildren(); - } - - } - - private class TreeLabelProvider implements ITableLabelProvider { - - @Override - public void addListener(ILabelProviderListener listener) { - } - - @Override - public void dispose() { - } - - @Override - public boolean isLabelProperty(Object element, String property) { - return false; - } - - @Override - public void removeListener(ILabelProviderListener listener) { - } - - @Override - public Image getColumnImage(Object element, int columnIndex) { - if (columnIndex == 0) { - if (element instanceof ThreadEntry) { - return THREAD_IMAGE; - } else if (element instanceof CallStackEntry) { - CallStackEntry entry = (CallStackEntry) element; - if (entry.getFunctionName().length() > 0) { - return STACKFRAME_IMAGE; - } - } - } - return null; - } - - @Override - public String getColumnText(Object element, int columnIndex) { - if (element instanceof CallStackEntry) { - CallStackEntry entry = (CallStackEntry) element; - if (columnIndex == 0) { - return entry.getFunctionName(); - } else if (columnIndex == 1 && entry.getFunctionName().length() > 0) { - int depth = entry.getStackLevel(); - return Integer.toString(depth); - } else if (columnIndex == 2 && entry.getFunctionName().length() > 0) { - ITmfTimestamp ts = new TmfTimestamp(entry.getFunctionEntryTime(), ITmfTimestamp.NANOSECOND_SCALE); - return ts.toString(); - } else if (columnIndex == 3 && entry.getFunctionName().length() > 0) { - ITmfTimestamp ts = new TmfTimestamp(entry.getFunctionExitTime(), ITmfTimestamp.NANOSECOND_SCALE); - return ts.toString(); - } else if (columnIndex == 4 && entry.getFunctionName().length() > 0) { - ITmfTimestamp ts = new TmfTimestampDelta(entry.getFunctionExitTime() - entry.getFunctionEntryTime(), ITmfTimestamp.NANOSECOND_SCALE); - return ts.toString(); - } - } else if (element instanceof ITimeGraphEntry) { - if (columnIndex == 0) { - return ((ITimeGraphEntry) element).getName(); - } - } - return ""; //$NON-NLS-1$ - } - - } - - private class TimeGraphContentProvider implements ITimeGraphContentProvider { - - @Override - public ITimeGraphEntry[] getElements(Object inputElement) { - if (inputElement != null) { - try { - return ((List) inputElement).toArray(new ITimeGraphEntry[0]); - } catch (ClassCastException e) { - } - } - return new ITimeGraphEntry[0]; - } - - } - - private class BuildThread extends Thread { - private final ITmfTrace fBuildTrace; - private final ITmfTrace fParentTrace; - private final IProgressMonitor fMonitor; - - public BuildThread(ITmfTrace trace, ITmfTrace parentTrace) { - super("CallStackView build"); //$NON-NLS-1$ - fBuildTrace = trace; - fParentTrace = parentTrace; - fMonitor = new NullProgressMonitor(); - } - - @Override - public void run() { - buildThreadList(fBuildTrace, fParentTrace, fMonitor); - synchronized (fBuildThreadMap) { - fBuildThreadMap.remove(fBuildTrace); - } - } - - public void cancel() { - fMonitor.setCanceled(true); - } - } - - private class ZoomThread extends Thread { - private final List fZoomEntryList; - private final long fZoomStartTime; - private final long fZoomEndTime; - private final IProgressMonitor fMonitor; - - public ZoomThread(List entryList, long startTime, long endTime) { - super("CallStackView zoom"); //$NON-NLS-1$ - fZoomEntryList = entryList; - fZoomStartTime = startTime; - fZoomEndTime = endTime; - fMonitor = new NullProgressMonitor(); - } - - @Override - public void run() { - if (fZoomEntryList == null) { - return; - } - long resolution = Math.max(1, (fZoomEndTime - fZoomStartTime) / fDisplayWidth); - for (TraceEntry traceEntry : fZoomEntryList) { - for (ITimeGraphEntry threadEntry : traceEntry.getChildren()) { - ITmfStateSystem ss = ((ThreadEntry) threadEntry).getStateSystem(); - if (ss == null) { - continue; - } - ss.waitUntilBuilt(); - if (ss.isCancelled()) { - continue; - } - for (ITimeGraphEntry child : threadEntry.getChildren()) { - if (fMonitor.isCanceled()) { - break; - } - CallStackEntry entry = (CallStackEntry) child; - if (fZoomStartTime <= fStartTime && fZoomEndTime >= fEndTime) { - entry.setZoomedEventList(null); - } else { - List zoomedEventList = getEventList(entry, fZoomStartTime, fZoomEndTime, resolution, fMonitor); - if (zoomedEventList != null) { - entry.setZoomedEventList(zoomedEventList); - } - } - redraw(); - } - } - } - } - - public void cancel() { - fMonitor.setCanceled(true); - } - } - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - public CallStackView() { - super(ID); - fDisplayWidth = Display.getDefault().getBounds().width; - } - - // ------------------------------------------------------------------------ - // ViewPart - // ------------------------------------------------------------------------ - - @Override - public void createPartControl(Composite parent) { - fTimeGraphCombo = new TimeGraphCombo(parent, SWT.NONE); - - fTimeGraphCombo.setTreeContentProvider(new TreeContentProvider()); - - fTimeGraphCombo.setTreeLabelProvider(new TreeLabelProvider()); - - fTimeGraphCombo.setTreeColumns(COLUMN_TIMES); - - fTimeGraphCombo.getTreeViewer().getTree().getColumn(0).setWidth(COLUMN_WIDTHS[0]); - fTimeGraphCombo.getTreeViewer().getTree().getColumn(1).setWidth(COLUMN_WIDTHS[1]); - fTimeGraphCombo.getTreeViewer().getTree().getColumn(2).setWidth(COLUMN_WIDTHS[2]); - fTimeGraphCombo.getTreeViewer().getTree().getColumn(3).setWidth(COLUMN_WIDTHS[3]); - fTimeGraphCombo.getTreeViewer().getTree().getColumn(4).setWidth(COLUMN_WIDTHS[4]); - - fTimeGraphCombo.setTimeGraphContentProvider(new TimeGraphContentProvider()); - fTimeGraphCombo.setTimeGraphProvider(new CallStackPresentationProvider(this)); - fTimeGraphCombo.getTimeGraphViewer().setTimeFormat(TimeFormat.CALENDAR); - - fTimeGraphCombo.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() { - @Override - public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) { - long startTime = event.getStartTime(); - long endTime = event.getEndTime(); - TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime)); - broadcast(new TmfRangeSynchSignal(CallStackView.this, range)); - startZoomThread(startTime, endTime); - } - }); - - fTimeGraphCombo.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() { - @Override - public void timeSelected(TimeGraphTimeEvent event) { - long beginTime = event.getBeginTime(); - long endTime = event.getEndTime(); - synchingToTime(beginTime); - broadcast(new TmfTimeSynchSignal(CallStackView.this, new TmfNanoTimestamp(beginTime), new TmfNanoTimestamp(endTime))); - } - }); - - fTimeGraphCombo.getTimeGraphViewer().getControl().addControlListener(new ControlAdapter() { - @Override - public void controlResized(ControlEvent e) { - fDisplayWidth = fTimeGraphCombo.getTimeGraphViewer().getControl().getSize().x; - if (fEntryList != null) { - startZoomThread(fTimeGraphCombo.getTimeGraphViewer().getTime0(), fTimeGraphCombo.getTimeGraphViewer().getTime1()); - } - } - }); - - fTimeGraphCombo.getTreeViewer().addDoubleClickListener(new IDoubleClickListener() { - @Override - public void doubleClick(DoubleClickEvent event) { - Object selection = ((IStructuredSelection) event.getSelection()).getFirstElement(); - if (selection instanceof CallStackEntry) { - CallStackEntry entry = (CallStackEntry) selection; - if (entry.getFunctionName().length() > 0) { - long entryTime = entry.getFunctionEntryTime(); - long exitTime = entry.getFunctionExitTime(); - long spacingTime = (long) ((exitTime - entryTime) * SPACING_RATIO); - entryTime -= spacingTime; - exitTime += spacingTime; - TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(entryTime), new TmfNanoTimestamp(exitTime)); - broadcast(new TmfRangeSynchSignal(CallStackView.this, range)); - fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(entryTime, exitTime); - startZoomThread(entryTime, exitTime); - } - } - } - }); - - fTimeGraphCombo.getTimeGraphViewer().getTimeGraphControl().addMouseListener(new MouseAdapter() { - @Override - public void mouseDoubleClick(MouseEvent e) { - TimeGraphControl timeGraphControl = fTimeGraphCombo.getTimeGraphViewer().getTimeGraphControl(); - ISelection selection = timeGraphControl.getSelection(); - if (selection instanceof TimeGraphSelection) { - Object o = ((TimeGraphSelection) selection).getFirstElement(); - if (o instanceof CallStackEvent) { - CallStackEvent event = (CallStackEvent) o; - long startTime = event.getTime(); - long endTime = startTime + event.getDuration(); - long spacingTime = (long) ((endTime - startTime) * SPACING_RATIO); - startTime -= spacingTime; - endTime += spacingTime; - TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime)); - broadcast(new TmfRangeSynchSignal(CallStackView.this, range)); - fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime); - startZoomThread(startTime, endTime); - } - } - } - }); - - IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager(); - fTimeGraphCombo.getTimeGraphViewer().getTimeGraphControl().setStatusLineManager(statusLineManager); - - // View Action Handling - makeActions(); - contributeToActionBars(); - createContextMenu(); - loadSortOption(); - - IEditorPart editor = getSite().getPage().getActiveEditor(); - if (editor instanceof ITmfTraceEditor) { - ITmfTrace trace = ((ITmfTraceEditor) editor).getTrace(); - if (trace != null) { - traceSelected(new TmfTraceSelectedSignal(this, trace)); - } - } - } - - @Override - public void setFocus() { - fTimeGraphCombo.setFocus(); - } - - // ------------------------------------------------------------------------ - // Signal handlers - // ------------------------------------------------------------------------ - /** - * Handler for the trace opened signal. - * - * @param signal - * The incoming signal - * @since 2.0 - */ - @TmfSignalHandler - public void traceOpened(TmfTraceOpenedSignal signal) { - fTrace = signal.getTrace(); - loadTrace(); - } - - /** - * Handler for the trace selected signal - * - * @param signal - * The incoming signal - */ - @TmfSignalHandler - public void traceSelected(final TmfTraceSelectedSignal signal) { - if (signal.getTrace() == fTrace) { - return; - } - fTrace = signal.getTrace(); - loadTrace(); - } - - /** - * Trace is closed: clear the data structures and the view - * - * @param signal - * the signal received - */ - @TmfSignalHandler - public void traceClosed(final TmfTraceClosedSignal signal) { - synchronized (fBuildThreadMap) { - ITmfTrace[] traces = TmfTraceManager.getTraceSet(signal.getTrace()); - for (ITmfTrace trace : traces) { - BuildThread buildThread = fBuildThreadMap.remove(trace); - if (buildThread != null) { - buildThread.cancel(); - } - } - } - synchronized (fEntryListMap) { - fEntryListMap.remove(signal.getTrace()); - } - fSelectedThreadMap.remove(signal.getTrace()); - if (signal.getTrace() == fTrace) { - fTrace = null; - fStartTime = 0; - fEndTime = 0; - refresh(); - } - } - - /** - * Handler for the TimeSynch signal - * - * @param signal - * The incoming signal - */ - @TmfSignalHandler - public void synchToTime(final TmfTimeSynchSignal signal) { - - fSavedTimeSyncSignal = isPinned() ? new TmfTimeSynchSignal(signal.getSource(), signal.getBeginTime(), signal.getEndTime()) : null; - - if (signal.getSource() == this || fTrace == null || isPinned()) { - return; - } - final long beginTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - final long endTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - if (fTimeGraphCombo.isDisposed()) { - return; - } - if (beginTime == endTime) { - fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(beginTime, true); - } else { - fTimeGraphCombo.getTimeGraphViewer().setSelectionRange(beginTime, endTime); - } - synchingToTime(beginTime); - startZoomThread(fTimeGraphCombo.getTimeGraphViewer().getTime0(), fTimeGraphCombo.getTimeGraphViewer().getTime1()); - if (fEntryList == null) { - return; - } - TimeGraphViewer viewer = fTimeGraphCombo.getTimeGraphViewer(); - for (TraceEntry traceEntry : fEntryList) { - for (ITimeGraphEntry child : traceEntry.getChildren()) { - ThreadEntry threadEntry = (ThreadEntry) child; - ITmfStateSystem ss = threadEntry.getStateSystem(); - if (ss == null || beginTime < ss.getStartTime() || beginTime > ss.getCurrentEndTime()) { - continue; - } - try { - int quark = threadEntry.getCallStackQuark(); - ITmfStateInterval stackInterval = ss.querySingleState(beginTime, quark); - if (beginTime == stackInterval.getStartTime()) { - int stackLevel = stackInterval.getStateValue().unboxInt(); - ITimeGraphEntry selectedEntry = threadEntry.getChildren().get(Math.max(0, stackLevel - 1)); - fTimeGraphCombo.setSelection(selectedEntry); - viewer.getTimeGraphControl().fireSelectionChanged(); - break; - } - } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException | StateValueTypeException e) { - Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ - } - } - } - } - }); - } - - /** - * Handler for the RangeSynch signal - * - * @param signal - * The incoming signal - */ - @TmfSignalHandler - public void synchToRange(final TmfRangeSynchSignal signal) { - - if (isPinned()) { - fSavedRangeSyncSignal = - new TmfRangeSynchSignal(signal.getSource(), new TmfTimeRange(signal.getCurrentRange().getStartTime(), signal.getCurrentRange().getEndTime())); - - fSavedTimeSyncSignal = null; - } - - if (signal.getSource() == this || fTrace == null || isPinned()) { - return; - } - if (signal.getCurrentRange().getIntersection(fTrace.getTimeRange()) == null) { - return; - } - final long startTime = signal.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - final long endTime = signal.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - if (fTimeGraphCombo.isDisposed()) { - return; - } - fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime); - startZoomThread(startTime, endTime); - } - }); - } - - // ------------------------------------------------------------------------ - // Internal - // ------------------------------------------------------------------------ - - private void loadTrace() { - synchronized (fEntryListMap) { - fEntryList = fEntryListMap.get(fTrace); - if (fEntryList == null) { - fStartTime = Long.MAX_VALUE; - fEndTime = Long.MIN_VALUE; - synchronized (fBuildThreadMap) { - ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace); - for (ITmfTrace trace : traces) { - BuildThread buildThread = new BuildThread(trace, fTrace); - fBuildThreadMap.put(trace, buildThread); - buildThread.start(); - } - } - } else { - fStartTime = fTrace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - fEndTime = fTrace.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - refresh(); - } - } - } - - private void buildThreadList(final ITmfTrace trace, final ITmfTrace parentTrace, IProgressMonitor monitor) { - if (monitor.isCanceled()) { - return; - } - AbstractCallStackAnalysis module = getCallStackModule(trace); - if (module == null) { - addUnavailableEntry(trace, parentTrace); - return; - } - ITmfStateSystem ss = module.getStateSystem(); - if (ss == null) { - addUnavailableEntry(trace, parentTrace); - return; - } - - Map traceEntryMap = new HashMap<>(); - Map threadEntryMap = new HashMap<>(); - String[] threadPaths = module.getThreadsPattern(); - - long start = ss.getStartTime(); - - boolean complete = false; - while (!complete) { - if (monitor.isCanceled()) { - return; - } - complete = ss.waitUntilBuilt(BUILD_UPDATE_TIMEOUT); - if (ss.isCancelled()) { - return; - } - long end = ss.getCurrentEndTime(); - if (start == end && !complete) { // when complete execute one last time regardless of end time - continue; - } - List threadQuarks = ss.getQuarks(threadPaths); - TraceEntry traceEntry = traceEntryMap.get(trace); - if (traceEntry == null) { - traceEntry = new TraceEntry(trace.getName(), start, end + 1); - traceEntryMap.put(trace, traceEntry); - traceEntry.sortChildren(fThreadComparator); - addToEntryList(parentTrace, Collections.singletonList(traceEntry)); - } else { - traceEntry.updateEndTime(end); - } - for (int i = 0; i < threadQuarks.size(); i++) { - if (monitor.isCanceled()) { - return; - } - int threadQuark = threadQuarks.get(i); - try { - String[] callStackPath = module.getCallStackPath(); - int callStackQuark = ss.getQuarkRelative(threadQuark, callStackPath); - String threadName = ss.getAttributeName(threadQuark); - long threadEnd = end + 1; - ITmfStateInterval endInterval = ss.querySingleState(ss.getCurrentEndTime(), callStackQuark); - if (endInterval.getStateValue().isNull() && endInterval.getStartTime() != ss.getStartTime()) { - threadEnd = endInterval.getStartTime(); - } - ThreadEntry threadEntry = threadEntryMap.get(threadQuark); - if (threadEntry == null) { - long threadId = ss.querySingleState(ss.getCurrentEndTime(), threadQuark).getStateValue().unboxLong(); - long threadStart = start; - ITmfStateInterval startInterval = ss.querySingleState(start, callStackQuark); - if (startInterval.getStateValue().isNull()) { - threadStart = Math.min(startInterval.getEndTime() + 1, end + 1); - } - threadEntry = new ThreadEntry(ss, threadName, threadId, callStackQuark, threadStart, threadEnd); - threadEntryMap.put(threadQuark, threadEntry); - traceEntry.addChild(threadEntry); - } else { - threadEntry.updateEndTime(threadEnd); - } - int level = 1; - for (int stackLevelQuark : ss.getSubAttributes(callStackQuark, false)) { - if (level > threadEntry.getChildren().size()) { - CallStackEntry callStackEntry = new CallStackEntry(threadName, stackLevelQuark, level, trace, ss); - threadEntry.addChild(callStackEntry); - } - level++; - } - } catch (AttributeNotFoundException e) { - Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ - } catch (StateSystemDisposedException e) { - /* Ignored */ - } - } - if (parentTrace == fTrace) { - synchronized (fEntryListMap) { - fStartTime = Math.min(fStartTime, start); - fEndTime = Math.max(fEndTime, end + 1); - } - refresh(); - } - for (ITimeGraphEntry threadEntry : traceEntry.getChildren()) { - for (ITimeGraphEntry callStackEntry : threadEntry.getChildren()) { - if (monitor.isCanceled()) { - return; - } - buildStatusEvents(parentTrace, (CallStackEntry) callStackEntry, monitor, start, end); - } - } - start = end; - } - } - - private void addToEntryList(ITmfTrace trace, List list) { - synchronized (fEntryListMap) { - List entryList = fEntryListMap.get(trace); - if (entryList == null) { - fEntryListMap.put(trace, new CopyOnWriteArrayList<>(list)); - } else { - entryList.addAll(list); - } - } - } - - private void addUnavailableEntry(ITmfTrace trace, ITmfTrace parentTrace) { - String name = Messages.CallStackView_StackInfoNotAvailable + ' ' + '(' + trace.getName() + ')'; - TraceEntry unavailableEntry = new TraceEntry(name, 0, 0); - addToEntryList(parentTrace, Collections.singletonList(unavailableEntry)); - if (parentTrace == fTrace) { - refresh(); - } - } - - private void buildStatusEvents(ITmfTrace trace, CallStackEntry entry, IProgressMonitor monitor, long start, long end) { - ITmfStateSystem ss = entry.getStateSystem(); - long resolution = Math.max(1, (end - ss.getStartTime()) / fDisplayWidth); - List eventList = getEventList(entry, start, end + 1, resolution, monitor); - if (eventList != null) { - for (ITimeEvent event : eventList) { - entry.addEvent(event); - } - } - if (trace == fTrace) { - redraw(); - } - } - - private static List getEventList(CallStackEntry entry, - long startTime, long endTime, long resolution, - IProgressMonitor monitor) { - ITmfStateSystem ss = entry.getStateSystem(); - long start = Math.max(startTime, ss.getStartTime()); - long end = Math.min(endTime, ss.getCurrentEndTime() + 1); - if (end <= start) { - return null; - } - List eventList = null; - try { - List stackIntervals = ss.queryHistoryRange(entry.getQuark(), start, end - 1, resolution, monitor); - eventList = new ArrayList<>(stackIntervals.size()); - long lastEndTime = -1; - boolean lastIsNull = true; - for (ITmfStateInterval statusInterval : stackIntervals) { - if (monitor.isCanceled()) { - return null; - } - long time = statusInterval.getStartTime(); - long duration = statusInterval.getEndTime() - time + 1; - if (!statusInterval.getStateValue().isNull()) { - final int modulo = CallStackPresentationProvider.NUM_COLORS / 2; - int value = statusInterval.getStateValue().toString().hashCode() % modulo + modulo; - eventList.add(new CallStackEvent(entry, time, duration, value)); - lastIsNull = false; - } else { - if (lastEndTime == -1) { - // add null event if it intersects the start time - eventList.add(new NullTimeEvent(entry, time, duration)); - } else { - if (lastEndTime != time && lastIsNull) { - // add unknown event if between two null states - eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime)); - } - if (time + duration >= endTime) { - // add null event if it intersects the end time - eventList.add(new NullTimeEvent(entry, time, duration)); - } - } - lastIsNull = true; - } - lastEndTime = time + duration; - } - } catch (AttributeNotFoundException e) { - Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ - } catch (TimeRangeException e) { - Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ - } catch (StateSystemDisposedException e) { - /* Ignored */ - } - return eventList; - } - - private void synchingToTime(long time) { - if (fEntryList == null) { - return; - } - for (TraceEntry traceEntry : fEntryList) { - for (ITimeGraphEntry threadEntry : traceEntry.getChildren()) { - ITmfStateSystem ss = ((ThreadEntry) threadEntry).getStateSystem(); - if (ss == null) { - continue; - } - if (ss.isCancelled()) { - continue; - } - if (time < ss.getStartTime() || time > ss.getCurrentEndTime()) { - continue; - } - for (ITimeGraphEntry child : threadEntry.getChildren()) { - CallStackEntry callStackEntry = (CallStackEntry) child; - try { - ITmfStateInterval stackLevelInterval = ss.querySingleState(time, callStackEntry.getQuark()); - ITmfStateValue nameValue = stackLevelInterval.getStateValue(); - String name = ""; //$NON-NLS-1$ - try { - if (nameValue.getType() == Type.STRING) { - String address = nameValue.unboxStr(); - name = getFunctionName(address); - } else if (nameValue.getType() == Type.INTEGER) { - name = "0x" + Integer.toHexString(nameValue.unboxInt()); //$NON-NLS-1$ - } else if (nameValue.getType() == Type.LONG) { - name = "0x" + Long.toHexString(nameValue.unboxLong()); //$NON-NLS-1$ - } - } catch (StateValueTypeException e) { - } - callStackEntry.setFunctionName(name); - if (name.length() > 0) { - callStackEntry.setFunctionEntryTime(stackLevelInterval.getStartTime()); - callStackEntry.setFunctionExitTime(stackLevelInterval.getEndTime() + 1); - } - } catch (AttributeNotFoundException e) { - Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ - } catch (StateSystemDisposedException e) { - /* Ignored */ - } - } - } - } - fTimeGraphCombo.refresh(); - } - - private void refresh() { - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - if (fTimeGraphCombo.isDisposed()) { - return; - } - synchronized (fEntryListMap) { - fEntryList = fEntryListMap.get(fTrace); - if (fEntryList == null) { - fEntryList = new ArrayList<>(); - } - for (TraceEntry traceEntry : fEntryList) { - traceEntry.sortChildren(fThreadComparator); - } - } - if (fEntryList != fTimeGraphCombo.getInput()) { - fTimeGraphCombo.setInput(fEntryList); - } else { - fTimeGraphCombo.refresh(); - } - fTimeGraphCombo.getTimeGraphViewer().setTimeBounds(fStartTime, fEndTime); - - long selectionBeginTime = fTrace == null ? 0 : fTraceManager.getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - long selectionEndTime = fTrace == null ? 0 : fTraceManager.getSelectionEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - long startTime = fTrace == null ? 0 : fTraceManager.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - long endTime = fTrace == null ? 0 : fTraceManager.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - startTime = Math.max(startTime, fStartTime); - endTime = Math.min(endTime, fEndTime); - fTimeGraphCombo.getTimeGraphViewer().setSelectionRange(selectionBeginTime, selectionEndTime); - synchingToTime(selectionBeginTime); - fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime); - startZoomThread(startTime, endTime); - } - }); - } - - private void redraw() { - synchronized (fSyncObj) { - if (fRedrawState == State.IDLE) { - fRedrawState = State.BUSY; - } else { - fRedrawState = State.PENDING; - return; - } - } - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - if (fTimeGraphCombo.isDisposed()) { - return; - } - fTimeGraphCombo.redraw(); - fTimeGraphCombo.update(); - synchronized (fSyncObj) { - if (fRedrawState == State.PENDING) { - fRedrawState = State.IDLE; - redraw(); - } else { - fRedrawState = State.IDLE; - } - } - } - }); - } - - private void startZoomThread(long startTime, long endTime) { - if (fZoomThread != null) { - fZoomThread.cancel(); - } - fZoomThread = new ZoomThread(fEntryList, startTime, endTime); - fZoomThread.start(); - } - - private void makeActions() { - fPreviousItemAction = fTimeGraphCombo.getTimeGraphViewer().getPreviousItemAction(); - fPreviousItemAction.setText(Messages.TmfTimeGraphViewer_PreviousItemActionNameText); - fPreviousItemAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousItemActionToolTipText); - fNextItemAction = fTimeGraphCombo.getTimeGraphViewer().getNextItemAction(); - fNextItemAction.setText(Messages.TmfTimeGraphViewer_NextItemActionNameText); - fNextItemAction.setToolTipText(Messages.TmfTimeGraphViewer_NextItemActionToolTipText); - } - - private void contributeToActionBars() { - IActionBars bars = getViewSite().getActionBars(); - fillLocalToolBar(bars.getToolBarManager()); - - // Create pin action - contributePinActionToToolBar(); - fPinAction.addPropertyChangeListener(new IPropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent event) { - if (IAction.CHECKED.equals(event.getProperty()) && !isPinned()) { - if (fSavedRangeSyncSignal != null) { - synchToRange(fSavedRangeSyncSignal); - fSavedRangeSyncSignal = null; - } - - if (fSavedTimeSyncSignal != null) { - synchToTime(fSavedTimeSyncSignal); - fSavedTimeSyncSignal = null; - } - } - } - }); - } - - private void fillLocalToolBar(IToolBarManager manager) { - manager.add(getImportBinaryAction()); - manager.add(getImportMappingAction()); - manager.add(new Separator()); - manager.add(getSortByNameAction()); - manager.add(getSortByIdAction()); - manager.add(getSortByTimeAction()); - manager.add(new Separator()); - manager.add(fTimeGraphCombo.getTimeGraphViewer().getResetScaleAction()); - manager.add(getPreviousEventAction()); - manager.add(getNextEventAction()); - manager.add(fPreviousItemAction); - manager.add(fNextItemAction); - manager.add(fTimeGraphCombo.getTimeGraphViewer().getZoomInAction()); - manager.add(fTimeGraphCombo.getTimeGraphViewer().getZoomOutAction()); - manager.add(new Separator()); - } - - private void createContextMenu() { - final MenuManager contextMenu = new MenuManager(); - contextMenu.add(getSortByNameAction()); - contextMenu.add(getSortByIdAction()); - contextMenu.add(getSortByTimeAction()); - - Tree tree = fTimeGraphCombo.getTreeViewer().getTree(); - Menu menu = contextMenu.createContextMenu(tree); - tree.setMenu(menu); - } - - /** - * Get the the next event action. - * - * @return The action object - */ - private Action getNextEventAction() { - if (fNextEventAction == null) { - fNextEventAction = new Action() { - @Override - public void run() { - TimeGraphViewer viewer = fTimeGraphCombo.getTimeGraphViewer(); - ITimeGraphEntry entry = viewer.getSelection(); - if (entry instanceof CallStackEntry) { - try { - CallStackEntry callStackEntry = (CallStackEntry) entry; - ITmfStateSystem ss = callStackEntry.getStateSystem(); - long time = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), viewer.getSelectionBegin())); - ThreadEntry threadEntry = (ThreadEntry) callStackEntry.getParent(); - int quark = ss.getParentAttributeQuark(callStackEntry.getQuark()); - ITmfStateInterval stackInterval = ss.querySingleState(time, quark); - long newTime = stackInterval.getEndTime() + 1; - viewer.setSelectedTimeNotify(newTime, true); - stackInterval = ss.querySingleState(Math.min(ss.getCurrentEndTime(), newTime), quark); - int stackLevel = stackInterval.getStateValue().unboxInt(); - ITimeGraphEntry selectedEntry = threadEntry.getChildren().get(Math.max(0, stackLevel - 1)); - fTimeGraphCombo.setSelection(selectedEntry); - viewer.getTimeGraphControl().fireSelectionChanged(); - startZoomThread(viewer.getTime0(), viewer.getTime1()); - - } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException | StateValueTypeException e) { - Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ - } - } - } - }; - - fNextEventAction.setText(Messages.TmfTimeGraphViewer_NextEventActionNameText); - fNextEventAction.setToolTipText(Messages.TmfTimeGraphViewer_NextEventActionToolTipText); - fNextEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_EVENT)); - } - - return fNextEventAction; - } - - /** - * Get the previous event action. - * - * @return The Action object - */ - private Action getPreviousEventAction() { - if (fPrevEventAction == null) { - fPrevEventAction = new Action() { - @Override - public void run() { - TimeGraphViewer viewer = fTimeGraphCombo.getTimeGraphViewer(); - ITimeGraphEntry entry = viewer.getSelection(); - if (entry instanceof CallStackEntry) { - try { - CallStackEntry callStackEntry = (CallStackEntry) entry; - ITmfStateSystem ss = callStackEntry.getStateSystem(); - long time = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), viewer.getSelectionBegin())); - ThreadEntry threadEntry = (ThreadEntry) callStackEntry.getParent(); - int quark = ss.getParentAttributeQuark(callStackEntry.getQuark()); - ITmfStateInterval stackInterval = ss.querySingleState(time, quark); - if (stackInterval.getStartTime() == time && time > ss.getStartTime()) { - stackInterval = ss.querySingleState(time - 1, quark); - } - viewer.setSelectedTimeNotify(stackInterval.getStartTime(), true); - int stackLevel = stackInterval.getStateValue().unboxInt(); - ITimeGraphEntry selectedEntry = threadEntry.getChildren().get(Math.max(0, stackLevel - 1)); - fTimeGraphCombo.setSelection(selectedEntry); - viewer.getTimeGraphControl().fireSelectionChanged(); - startZoomThread(viewer.getTime0(), viewer.getTime1()); - - } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException | StateValueTypeException e) { - Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ - } - } - } - }; - - fPrevEventAction.setText(Messages.TmfTimeGraphViewer_PreviousEventActionNameText); - fPrevEventAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousEventActionToolTipText); - fPrevEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_EVENT)); - } - - return fPrevEventAction; - } - - private static @Nullable AbstractCallStackAnalysis getCallStackModule(ITmfTrace trace) { - /* - * Since we cannot know the exact analysis ID (in separate plugins), we - * will search using the analysis type. - */ - Iterable modules = - trace.getAnalysisModulesOfClass(AbstractCallStackAnalysis.class); - Iterator it = modules.iterator(); - if (!it.hasNext()) { - /* This trace does not provide a call-stack analysis */ - return null; - } - - /* - * We only look at the first module we find. - * - * TODO Handle the advanced case where one trace provides more than one - * call-stack analysis. - */ - AbstractCallStackAnalysis module = it.next(); - /* This analysis is not automatic, we need to schedule it on-demand */ - module.schedule(); - module.waitForInitialization(); - return module; - } - - // ------------------------------------------------------------------------ - // Methods related to function name mapping - // ------------------------------------------------------------------------ - - /** - * Common code for all import file mapping actions - */ - private abstract class AbstractImportFileMappingAction extends Action { - private final String fDialogTitle; - - private AbstractImportFileMappingAction(String dialogTitle) { - fDialogTitle = dialogTitle; - } - - @Override - public void run() { - FileDialog dialog = new FileDialog(getViewSite().getShell()); - dialog.setText(fDialogTitle); - final String filePath = dialog.open(); - if (filePath == null) { - /* No file was selected, don't change anything */ - return; - } - - /* - * Start the mapping import in a separate thread (we do not want to - * UI thread to do this). - */ - Job job = new Job(Messages.CallStackView_ImportMappingJobName) { - @Override - public IStatus run(IProgressMonitor monitor) { - fNameMapping = doMapping(new File(filePath)); - - /* Refresh call stack entries and event labels */ - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - synchingToTime(fTimeGraphCombo.getTimeGraphViewer().getSelectionBegin()); - } - }); - return Status.OK_STATUS; - } - }; - job.schedule(); - } - - abstract Map doMapping(File file); - } - - /** - * Toolbar icon to import the function address-to-name mapping file. - */ - private Action getImportMappingAction() { - if (fImportMappingAction != null) { - return fImportMappingAction; - } - fImportMappingAction = new AbstractImportFileMappingAction(Messages.CallStackView_ImportMappingDialogTitle) { - @Override - Map doMapping(File file) { - return FunctionNameMapper.mapFromNmTextFile(file); - } - }; - - fImportMappingAction.setText(Messages.CallStackView_ImportMappingButtonText); - fImportMappingAction.setToolTipText(Messages.CallStackView_ImportMappingButtonTooltip); - fImportMappingAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(IMPORT_MAPPING_ICON_PATH)); - - return fImportMappingAction; - } - - private Action getSortByNameAction() { - if (fSortByNameAction == null) { - fSortByNameAction = new Action(Messages.CallStackView_SortByThreadName, IAction.AS_CHECK_BOX) { - @Override - public void run() { - if (fSortOption == SortOption.BY_NAME) { - saveSortOption(SortOption.BY_NAME_REV); - } else { - saveSortOption(SortOption.BY_NAME); - } - } - }; - fSortByNameAction.setToolTipText(Messages.CallStackView_SortByThreadName); - fSortByNameAction.setImageDescriptor(SORT_BY_NAME_ICON); - } - return fSortByNameAction; - } - - private Action getSortByIdAction() { - if (fSortByIdAction == null) { - fSortByIdAction = new Action(Messages.CallStackView_SortByThreadId, IAction.AS_CHECK_BOX) { - @Override - public void run() { - if (fSortOption == SortOption.BY_ID) { - saveSortOption(SortOption.BY_ID_REV); - } else { - saveSortOption(SortOption.BY_ID); - } - } - }; - fSortByIdAction.setToolTipText(Messages.CallStackView_SortByThreadId); - fSortByIdAction.setImageDescriptor(SORT_BY_ID_ICON); - } - return fSortByIdAction; - } - - private Action getSortByTimeAction() { - if (fSortByTimeAction == null) { - fSortByTimeAction = new Action(Messages.CallStackView_SortByThreadTime, IAction.AS_CHECK_BOX) { - @Override - public void run() { - if (fSortOption == SortOption.BY_TIME) { - saveSortOption(SortOption.BY_TIME_REV); - } else { - saveSortOption(SortOption.BY_TIME); - } - } - }; - fSortByTimeAction.setToolTipText(Messages.CallStackView_SortByThreadTime); - fSortByTimeAction.setImageDescriptor(SORT_BY_TIME_ICON); - } - return fSortByTimeAction; - } - - private void loadSortOption() { - IDialogSettings settings = Activator.getDefault().getDialogSettings(); - IDialogSettings section = settings.getSection(getClass().getName()); - if (section == null) { - return; - } - String sortOption = section.get(SORT_OPTION_KEY); - if (sortOption == null) { - return; - } - - // reset defaults - getSortByNameAction().setChecked(false); - getSortByNameAction().setImageDescriptor(SORT_BY_NAME_ICON); - getSortByIdAction().setChecked(false); - getSortByIdAction().setImageDescriptor(SORT_BY_ID_ICON); - getSortByTimeAction().setChecked(false); - getSortByTimeAction().setImageDescriptor(SORT_BY_TIME_ICON); - - if (sortOption.equals(SortOption.BY_NAME.name())) { - fSortOption = SortOption.BY_NAME; - fThreadComparator = new ThreadNameComparator(false); - getSortByNameAction().setChecked(true); - } else if (sortOption.equals(SortOption.BY_NAME_REV.name())) { - fSortOption = SortOption.BY_NAME_REV; - fThreadComparator = new ThreadNameComparator(true); - getSortByNameAction().setChecked(true); - getSortByNameAction().setImageDescriptor(SORT_BY_NAME_REV_ICON); - } else if (sortOption.equals(SortOption.BY_ID.name())) { - fSortOption = SortOption.BY_ID; - fThreadComparator = new ThreadIdComparator(false); - getSortByIdAction().setChecked(true); - } else if (sortOption.equals(SortOption.BY_ID_REV.name())) { - fSortOption = SortOption.BY_ID_REV; - fThreadComparator = new ThreadIdComparator(true); - getSortByIdAction().setChecked(true); - getSortByIdAction().setImageDescriptor(SORT_BY_ID_REV_ICON); - } else if (sortOption.equals(SortOption.BY_TIME.name())) { - fSortOption = SortOption.BY_TIME; - fThreadComparator = new ThreadTimeComparator(false); - getSortByTimeAction().setChecked(true); - } else if (sortOption.equals(SortOption.BY_TIME_REV.name())) { - fSortOption = SortOption.BY_TIME_REV; - fThreadComparator = new ThreadTimeComparator(true); - getSortByTimeAction().setChecked(true); - getSortByTimeAction().setImageDescriptor(SORT_BY_TIME_REV_ICON); - } - } - - private void saveSortOption(SortOption sortOption) { - IDialogSettings settings = Activator.getDefault().getDialogSettings(); - IDialogSettings section = settings.getSection(getClass().getName()); - if (section == null) { - section = settings.addNewSection(getClass().getName()); - } - section.put(SORT_OPTION_KEY, sortOption.name()); - loadSortOption(); - if (fEntryList == null) { - return; - } - for (TraceEntry traceEntry : fEntryList) { - traceEntry.sortChildren(fThreadComparator); - } - refresh(); - } - - /** - * Toolbar icon to import the function address-to-name mapping binary file. - */ - private Action getImportBinaryAction() { - if (fImportBinaryFileMappingAction != null) { - return fImportBinaryFileMappingAction; - } - - fImportBinaryFileMappingAction = new AbstractImportFileMappingAction(Messages.CallStackView_ImportBinaryFileDialogTitle) { - @Override - Map doMapping(File file) { - return FunctionNameMapper.mapFromBinaryFile(file); - } - }; - - fImportBinaryFileMappingAction.setText(Messages.CallStackView_ImportBinaryFileButtonText); - fImportBinaryFileMappingAction.setToolTipText(Messages.CallStackView_ImportBinaryFileButtonTooltip); - fImportBinaryFileMappingAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(IMPORT_BINARY_ICON_PATH)); - - return fImportBinaryFileMappingAction; - } - - String getFunctionName(String address) { - if (fNameMapping == null) { - /* No mapping available, just print the addresses */ - return address; - } - String ret = fNameMapping.get(address); - if (ret == null) { - /* - * We didn't find this address in the mapping file, just use the - * address - */ - return address; - } - return ret; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/FunctionNameMapper.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/FunctionNameMapper.java deleted file mode 100644 index bcf6ce9494..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/FunctionNameMapper.java +++ /dev/null @@ -1,177 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - * Marc-Andre Laperle - Map from binary file - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.callstack; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.IBinaryParser; -import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; -import org.eclipse.cdt.core.IBinaryParser.ISymbol; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.ISafeRunnable; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; - -/** - * Class containing the different methods to import an address->name mapping. - * - * @author Alexandre Montplaisir - */ -class FunctionNameMapper { - - public static @Nullable Map mapFromNmTextFile(File mappingFile) { - Map map = new HashMap<>(); - - try (FileReader fr = new FileReader(mappingFile); - BufferedReader reader = new BufferedReader(fr);) { - for (String line = reader.readLine(); line != null; line = reader.readLine()) { - String[] elems = line.split(" "); //$NON-NLS-1$ - /* Only lines with 3 elements contain addresses */ - if (elems.length == 3) { - /* Strip the leading zeroes from the address */ - String address = elems[0].replaceFirst("^0+(?!$)", ""); //$NON-NLS-1$ //$NON-NLS-2$; - String name = elems[elems.length - 1]; - map.put(address, name); - } - } - } catch (FileNotFoundException e) { - return null; - } catch (IOException e) { - /* Stop reading the file at this point */ - } - - if (map.isEmpty()) { - return null; - } - return Collections.unmodifiableMap(map); - } - - /** - * Strip the leading zeroes from the address - * */ - private static String stripLeadingZeros(String address) { - return address.replaceFirst("^0+(?!$)", ""); //$NON-NLS-1$ //$NON-NLS-2$; - } - - public static @Nullable Map mapFromBinaryFile(File file) { - Map map = new HashMap<>(); - IBinaryParser.IBinaryObject binaryObject = getBinaryObject(file); - if (binaryObject != null) { - ISymbol[] symbols = binaryObject.getSymbols(); - for (ISymbol symbol : symbols) { - String address = symbol.getAddress().toHexAddressString(); - /* Remove "0x" */ - address = address.substring(2); - /* Strip the leading zeroes from the address */ - address = stripLeadingZeros(address); - map.put(address, symbol.getName()); - } - } - - return map; - } - - private static @Nullable IBinaryParser.IBinaryObject getBinaryObject(File file) { - IPath filePath = new Path(file.toString()); - - /* Get all the available binary parsers */ - final List binaryParsers = new ArrayList<>(); - IConfigurationElement[] elements = Platform.getExtensionRegistry() - .getConfigurationElementsFor(CCorePlugin.BINARY_PARSER_UNIQ_ID); - for (IConfigurationElement element : elements) { - IConfigurationElement[] children = element.getChildren("run"); //$NON-NLS-1$ - for (final IConfigurationElement run : children) { - SafeRunner.run(new ISafeRunnable() { - @Override - public void run() throws Exception { - IBinaryParser binaryParser = (IBinaryParser) run.createExecutableExtension("class"); //$NON-NLS-1$ - binaryParsers.add(binaryParser); - } - - @Override - public void handleException(Throwable exception) { - Activator.getDefault().logError("Error creating binary parser", exception); //$NON-NLS-1$ - } - }); - } - } - - /* Find the maximum "hint" buffer size we'll need from all the parsers */ - int hintBufferSize = 0; - for (IBinaryParser parser : binaryParsers) { - if (parser.getHintBufferSize() > hintBufferSize) { - hintBufferSize = Math.max(hintBufferSize, parser.getHintBufferSize()); - } - } - - /* Read the initial "hint" bytes */ - byte[] hintBuffer = new byte[hintBufferSize]; - if (hintBufferSize > 0) { - try (InputStream is = new FileInputStream(file) ){ - - int count = 0; - // Make sure we read up to 'hints' bytes if we possibly can - while (count < hintBufferSize) { - int bytesRead = is.read(hintBuffer, count, hintBufferSize - count); - if (bytesRead < 0) { - break; - } - count += bytesRead; - } - if (count > 0 && count < hintBuffer.length) { - byte[] array = new byte[count]; - System.arraycopy(hintBuffer, 0, array, 0, count); - hintBuffer = array; - } - } catch (IOException e) { - Activator.getDefault().logError("Error reading initial bytes of binary file", e); //$NON-NLS-1$ - return null; - } - } - - /* For all binary parsers, try to get a binary object */ - for (IBinaryParser parser : binaryParsers) { - if (parser.isBinary(hintBuffer, filePath)) { - IBinaryFile binFile; - try { - binFile = parser.getBinary(hintBuffer, filePath); - if (binFile != null && binFile instanceof IBinaryParser.IBinaryObject) { - return (IBinaryParser.IBinaryObject)binFile; - } - } catch (IOException e) { - Activator.getDefault().logError("Error parsing binary file", e); //$NON-NLS-1$ - } - } - } - - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/ColorSetting.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/ColorSetting.java deleted file mode 100644 index 2aa85bcd71..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/ColorSetting.java +++ /dev/null @@ -1,214 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Bernd Hufmann - Updated to use RGB for the tick color - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.colors; - -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.themes.ColorUtil; - -/** - * Class for storing color settings of a TMF filter. - * - * Application code must explicitly invoke the ColorSetting.dispose() method to release the operating system - * resources managed by each instance when those instances are no longer required. - * - * @version 1.0 - * @author Patrick Tasse - */ -public class ColorSetting { - - private RGB fForegroundRGB; - private RGB fBackgroundRGB; - private RGB fTickColorRGB; - private Color fForegroundColor; - private Color fBackgroundColor; - private Color fDimmedForegroundColor; - private Color fDimmedBackgroundColor; - private Color fTickColor; - private ITmfFilterTreeNode fFilter; - - /** - * Constructor - * - * You must dispose the color setting when it is no longer required. - * - * @param foreground - * The foreground color - * @param background - * The background color - * @param tickColorRGB - * The color for the checkbox ticks - * @param filter - * The filter tree node - */ - public ColorSetting(RGB foreground, RGB background, RGB tickColorRGB, ITmfFilterTreeNode filter) { - fForegroundRGB = foreground; - fBackgroundRGB = background; - fTickColorRGB = tickColorRGB; - fFilter = filter; - Display display = Display.getDefault(); - fForegroundColor = new Color(display, fForegroundRGB); - fBackgroundColor = new Color(display, fBackgroundRGB); - fDimmedForegroundColor = new Color(display, ColorUtil.blend( - fForegroundRGB, fBackgroundRGB)); - fDimmedBackgroundColor = new Color(display, ColorUtil.blend( - fBackgroundRGB, display.getSystemColor(SWT.COLOR_LIST_BACKGROUND).getRGB())); - fTickColor = new Color(display, fTickColorRGB); - } - - /** - * Dispose the color setting resources - */ - public void dispose() { - fForegroundColor.dispose(); - fBackgroundColor.dispose(); - fDimmedForegroundColor.dispose(); - fDimmedBackgroundColor.dispose(); - fTickColor.dispose(); - } - - /** - * Returns foreground RGB value. - * - * @return the foreground RGB - */ - public RGB getForegroundRGB() { - return fForegroundRGB; - } - - /** - * Sets the foreground RGB value - * - * @param foreground the foreground to set - */ - public void setForegroundRGB(RGB foreground) { - fForegroundRGB = foreground; - fForegroundColor.dispose(); - fDimmedForegroundColor.dispose(); - Display display = Display.getDefault(); - fForegroundColor = new Color(display, fForegroundRGB); - fDimmedForegroundColor = new Color(display, ColorUtil.blend( - fForegroundRGB, fBackgroundRGB)); - } - - /** - * Returns the background RGB value. - * - * @return the background RGB - */ - public RGB getBackgroundRGB() { - return fBackgroundRGB; - } - - /** - * Sets the background RGB value. - * - * @param background the background to set - */ - public void setBackgroundRGB(RGB background) { - fBackgroundRGB = background; - fBackgroundColor.dispose(); - fDimmedBackgroundColor.dispose(); - Display display = Display.getDefault(); - fBackgroundColor = new Color(display, fBackgroundRGB); - fDimmedBackgroundColor = new Color(display, ColorUtil.blend( - fBackgroundRGB, display.getSystemColor(SWT.COLOR_LIST_BACKGROUND).getRGB())); - } - - /** - * Returns the RGB of the tick color - * - * @return the RGB of the tick color - */ - public RGB getTickColorRGB() { - return fTickColorRGB; - } - - /** - * Sets the RGB of the tick color - * - * @param tickColorRGB the tick color TGB - */ - public void setTickColorRGB(RGB tickColorRGB) { - fTickColorRGB = tickColorRGB; - fTickColor.dispose(); - Display display = Display.getDefault(); - fTickColor = new Color(display, fTickColorRGB); - } - - /** - * Returns the filter implementation. - * @return the filter - */ - public ITmfFilterTreeNode getFilter() { - return fFilter; - } - - /** - * Sets the filter implementation. - * - * @param filter the filter to set - */ - public void setFilter(ITmfFilterTreeNode filter) { - fFilter = filter; - } - - /** - * Returns the foreground color. - * - * @return the foreground color - */ - public Color getForegroundColor() { - return fForegroundColor; - } - - /** - * Returns the background color. - * - * @return the background color - */ - public Color getBackgroundColor() { - return fBackgroundColor; - } - - /** - * Returns the dimmed foreground color. - * - * @return the dimmed foreground color - */ - public Color getDimmedForegroundColor() { - return fDimmedForegroundColor; - } - - /** - * Returns the dimmed background color. - * - * @return the dimmed background color - */ - public Color getDimmedBackgroundColor() { - return fDimmedBackgroundColor; - } - - /** - * Returns the tick color. - * - * @return the tick color - */ - public Color getTickColor() { - return fTickColor; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/ColorSettingsManager.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/ColorSettingsManager.java deleted file mode 100644 index 16a68e9805..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/ColorSettingsManager.java +++ /dev/null @@ -1,153 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Bernd Hufmann - Updated to use RGB for the tick color - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.colors; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Display; - -/** - * Static class for managing color settings. - * - * @version 1.0 - * @author Patrick Tasse - * - */ -public class ColorSettingsManager { - - // The color settings file name - private static final String COLOR_SETTINGS_FILE_NAME = "color_settings.xml"; //$NON-NLS-1$ - - // The path for the color settings file - private static final String COLOR_SETTINGS_PATH_NAME = - Activator.getDefault().getStateLocation().addTrailingSeparator().append(COLOR_SETTINGS_FILE_NAME).toString(); - - // The default color setting - private static final ColorSetting DEFAULT_COLOR_SETTING = new ColorSetting( - Display.getDefault().getSystemColor(SWT.COLOR_LIST_FOREGROUND).getRGB(), - Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND).getRGB(), - Display.getDefault().getSystemColor(SWT.COLOR_LIST_FOREGROUND).getRGB(), - null); - - /** - * Special value for priority if unknown. - */ - public static final int PRIORITY_NONE = Integer.MAX_VALUE; - - // The stored color settings - private static ColorSetting[] fColorSettings = ColorSettingsXML.load(COLOR_SETTINGS_PATH_NAME); - - // The listener list - private static List fListeners = new ArrayList<>(); - - /** - * Returns an array of color settings. - * - * @return an array of color settings. - */ - public static ColorSetting[] getColorSettings() { - return (fColorSettings != null) ? Arrays.copyOf(fColorSettings, fColorSettings.length) : null; - } - - /** - * Sets the array of color settings. - * - * @param colorSettings A array of color settings to set - */ - public static void setColorSettings(ColorSetting[] colorSettings) { - fColorSettings = (colorSettings != null) ? Arrays.copyOf(colorSettings, colorSettings.length) : null; - ColorSettingsXML.save(COLOR_SETTINGS_PATH_NAME, fColorSettings); - fireColorSettingsChanged(); - } - - /** - * Gets the color settings that matches the filter for given event. - * - * @param event - * The event to check - * - * @return color settings defined for filter if found else default color - * settings - */ - public static ColorSetting getColorSetting(ITmfEvent event) { - for (int i = 0; i < fColorSettings.length; i++) { - ColorSetting colorSetting = fColorSettings[i]; - if (colorSetting.getFilter() != null && colorSetting.getFilter().matches(event)) { - return colorSetting; - } - } - return DEFAULT_COLOR_SETTING; - } - - /** - * Gets the color settings priority for the given event. - * - * @param event A event the event to check - * @return the priority defined for the filter else PRIORITY_NONE - */ - public static int getColorSettingPriority(ITmfEvent event) { - for (int i = 0; i < fColorSettings.length; i++) { - ColorSetting colorSetting = fColorSettings[i]; - if (colorSetting.getFilter() != null && colorSetting.getFilter().matches(event)) { - return i; - } - } - return PRIORITY_NONE; - } - - /** - * Returns the color settings based the priority. - * - * @param priority A priority (index) of color settings - * @return the color settings defined for the priority else default color settings - */ - public static ColorSetting getColorSetting(int priority) { - if (priority < fColorSettings.length) { - return fColorSettings[priority]; - } - return DEFAULT_COLOR_SETTING; - } - - /** - * Adds a color settings listener. - * - * @param listener A listener to add. - */ - public static void addColorSettingsListener(IColorSettingsListener listener) { - if (! fListeners.contains(listener)) { - fListeners.add(listener); - } - } - - /** - * Removes a color settings listener. - * - * @param listener A listener to remove. - */ - public static void removeColorSettingsListener(IColorSettingsListener listener) { - fListeners.remove(listener); - } - - // Notify listeners - private static void fireColorSettingsChanged() { - for (IColorSettingsListener listener : fListeners) { - listener.colorSettingsChanged(fColorSettings); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/ColorSettingsXML.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/ColorSettingsXML.java deleted file mode 100644 index 481bfd36c1..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/ColorSettingsXML.java +++ /dev/null @@ -1,221 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Bernd Hufmann - Updated to use RGB for the tick color - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.colors; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParserFactory; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; -import org.eclipse.linuxtools.tmf.core.filter.xml.TmfFilterContentHandler; -import org.eclipse.linuxtools.tmf.core.filter.xml.TmfFilterXMLWriter; -import org.eclipse.swt.graphics.RGB; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.DefaultHandler; - -/** - * Class for saving and loading of color settings to/from file. - * - * @version 1.0 - * @author Patrick Tasse - * - */ -public class ColorSettingsXML { - - // XML Tags and attributes - private static final String COLOR_SETTINGS_TAG = "COLOR_SETTINGS"; //$NON-NLS-1$ - private static final String COLOR_SETTING_TAG = "COLOR_SETTING"; //$NON-NLS-1$ - private static final String FG_TAG = "FG"; //$NON-NLS-1$ - private static final String BG_TAG = "BG"; //$NON-NLS-1$ - private static final String R_ATTR = "R"; //$NON-NLS-1$ - private static final String G_ATTR = "G"; //$NON-NLS-1$ - private static final String B_ATTR = "B"; //$NON-NLS-1$ - private static final String TICK_TAG = "TICK"; //$NON-NLS-1$ - private static final String FILTER_TAG = "FILTER"; //$NON-NLS-1$ - - /** - * Saves the given color settings to file. - * - * @param pathName - * A file name with path - * @param colorSettings - * -An array of color settings to save. - */ - public static void save(String pathName, ColorSetting[] colorSettings) { - try { - DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); - Document document = documentBuilder.newDocument(); - - Element rootElement = document.createElement(COLOR_SETTINGS_TAG); - document.appendChild(rootElement); - - for (ColorSetting colorSetting : colorSettings) { - Element colorSettingElement = document.createElement(COLOR_SETTING_TAG); - rootElement.appendChild(colorSettingElement); - - Element fgElement = document.createElement(FG_TAG); - colorSettingElement.appendChild(fgElement); - RGB foreground = colorSetting.getForegroundRGB(); - fgElement.setAttribute(R_ATTR, Integer.toString(foreground.red)); - fgElement.setAttribute(G_ATTR, Integer.toString(foreground.green)); - fgElement.setAttribute(B_ATTR, Integer.toString(foreground.blue)); - - Element bgElement = document.createElement(BG_TAG); - colorSettingElement.appendChild(bgElement); - RGB background = colorSetting.getBackgroundRGB(); - bgElement.setAttribute(R_ATTR, Integer.toString(background.red)); - bgElement.setAttribute(G_ATTR, Integer.toString(background.green)); - bgElement.setAttribute(B_ATTR, Integer.toString(background.blue)); - - Element tickColorElement = document.createElement(TICK_TAG); - colorSettingElement.appendChild(tickColorElement); - RGB tickColor = colorSetting.getTickColorRGB(); - tickColorElement.setAttribute(R_ATTR, Integer.toString(tickColor.red)); - tickColorElement.setAttribute(G_ATTR, Integer.toString(tickColor.green)); - tickColorElement.setAttribute(B_ATTR, Integer.toString(tickColor.blue)); - - if (colorSetting.getFilter() != null) { - Element filterElement = document.createElement(FILTER_TAG); - colorSettingElement.appendChild(filterElement); - TmfFilterXMLWriter.buildXMLTree(document, colorSetting.getFilter(), filterElement); - } - } - - TransformerFactory transformerFactory = TransformerFactory.newInstance(); - - Transformer transformer = transformerFactory.newTransformer(); - DOMSource source = new DOMSource(document); - StreamResult result = new StreamResult(new File(pathName)); - transformer.transform(source, result); - } catch (ParserConfigurationException e) { - Activator.getDefault().logError("Error saving color xml file: " + pathName, e); //$NON-NLS-1$ - } catch (TransformerConfigurationException e) { - Activator.getDefault().logError("Error saving color xml file: " + pathName, e); //$NON-NLS-1$ - } catch (TransformerException e) { - Activator.getDefault().logError("Error saving color xml file: " + pathName, e); //$NON-NLS-1$ - } - } - - /** - * Loads color settings from file and returns it in an array. - * - * @param pathName - * A file name with path - * - * @return the color settings array loaded from file - */ - public static ColorSetting[] load(String pathName) { - if (!new File(pathName).canRead()) { - return new ColorSetting[0]; - } - SAXParserFactory parserFactory = SAXParserFactory.newInstance(); - parserFactory.setNamespaceAware(true); - - ColorSettingsContentHandler handler = new ColorSettingsContentHandler(); - try { - XMLReader saxReader = parserFactory.newSAXParser().getXMLReader(); - saxReader.setContentHandler(handler); - saxReader.parse(pathName); - return handler.colorSettings.toArray(new ColorSetting[0]); - } catch (ParserConfigurationException e) { - Activator.getDefault().logError("Error loading color xml file: " + pathName, e); //$NON-NLS-1$ - } catch (SAXException e) { - Activator.getDefault().logError("Error loading color xml file: " + pathName, e); //$NON-NLS-1$ - } catch (IOException e) { - Activator.getDefault().logError("Error loading color xml file: " + pathName, e); //$NON-NLS-1$ - } - // In case of error, dispose the partial list of color settings - for (ColorSetting colorSetting : handler.colorSettings) { - colorSetting.dispose(); - } - return new ColorSetting[0]; - } - - // Helper class - private static class ColorSettingsContentHandler extends DefaultHandler { - - private List colorSettings = new ArrayList<>(0); - private RGB fg = new RGB(0, 0, 0); - private RGB bg = new RGB(255, 255, 255); - private RGB tickColor = new RGB(0, 0, 0); - private ITmfFilterTreeNode filter; - private TmfFilterContentHandler filterContentHandler; - - @Override - public void startElement(String uri, String localName, String qName, Attributes attributes) - throws SAXException { - if (localName.equals(COLOR_SETTINGS_TAG)) { - colorSettings = new ArrayList<>(); - } else if (localName.equals(COLOR_SETTING_TAG)) { - fg = null; - bg = null; - filter = null; - } else if (localName.equals(FG_TAG)) { - int r = Integer.parseInt(attributes.getValue(R_ATTR)); - int g = Integer.parseInt(attributes.getValue(G_ATTR)); - int b = Integer.parseInt(attributes.getValue(B_ATTR)); - fg = new RGB(r, g, b); - } else if (localName.equals(BG_TAG)) { - int r = Integer.parseInt(attributes.getValue(R_ATTR)); - int g = Integer.parseInt(attributes.getValue(G_ATTR)); - int b = Integer.parseInt(attributes.getValue(B_ATTR)); - bg = new RGB(r, g, b); - } else if (localName.equals(TICK_TAG)) { - int r = Integer.parseInt(attributes.getValue(R_ATTR)); - int g = Integer.parseInt(attributes.getValue(G_ATTR)); - int b = Integer.parseInt(attributes.getValue(B_ATTR)); - tickColor = new RGB(r, g, b); - } else if (localName.equals(FILTER_TAG)) { - filterContentHandler = new TmfFilterContentHandler(); - } else if (filterContentHandler != null) { - filterContentHandler.startElement(uri, localName, qName, attributes); - } - } - - @Override - public void endElement(String uri, String localName, String qName) - throws SAXException { - if (localName.equals(COLOR_SETTINGS_TAG)) { - // Nothing to do - } else if (localName.equals(COLOR_SETTING_TAG)) { - ColorSetting colorSetting = new ColorSetting(fg, bg, tickColor, filter); - colorSettings.add(colorSetting); - } else if (localName.equals(FILTER_TAG)) { - filter = filterContentHandler.getTree(); - filterContentHandler = null; - } else if (filterContentHandler != null) { - filterContentHandler.endElement(uri, localName, qName); - } - } - - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/ColorsView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/ColorsView.java deleted file mode 100644 index 08ea59c132..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/ColorsView.java +++ /dev/null @@ -1,588 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Bernd Hufmann - Updated to use RGB for the tick color - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.colors; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.window.Window; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.ui.views.TmfView; -import org.eclipse.linuxtools.tmf.ui.views.filter.FilterDialog; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphColorScheme; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.ColorDialog; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IActionBars; - -/** - * Color view implementation. This view provides support for managing color settings for filters. - * - * @version 1.0 - * @author Patrick Tasse - * - */ -public class ColorsView extends TmfView { - - /** ID for the color view */ - public static final @NonNull String ID = "org.eclipse.linuxtools.tmf.ui.views.colors"; //$NON-NLS-1$ - - private static final Image ADD_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/add_button.gif"); //$NON-NLS-1$ - private static final Image DELETE_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/delete_button.gif"); //$NON-NLS-1$ - private static final Image MOVE_UP_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/moveup_button.gif"); //$NON-NLS-1$ - private static final Image MOVE_DOWN_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/movedown_button.gif"); //$NON-NLS-1$ - private static final Image IMPORT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/import_button.gif"); //$NON-NLS-1$ - private static final Image EXPORT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/export_button.gif"); //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Main data structures - // ------------------------------------------------------------------------ - - /** - * The composite shell. - */ - protected Shell fShell; - /** - * The main composite (scrolled composite) - */ - protected ScrolledComposite fScrolledComposite; - /** - * The list composite. - */ - protected Composite fListComposite; - /** - * The filler composite. - */ - protected Composite fFillerComposite; - /** - * The selected color settings row - */ - protected ColorSettingRow fSelectedRow = null; - /** - * The color scheme instance for managing colors - */ - protected TimeGraphColorScheme traceColorScheme = new TimeGraphColorScheme(); - /** - * An action to add a color settings row - */ - protected Action fAddAction; - /** - * An action to delete a color settings row - */ - protected Action fDeleteAction; - /** - * An action to move up a color settings row in the list. - */ - protected Action fMoveUpAction; - /** - * An action to move down a color settings row in the list. - */ - protected Action fMoveDownAction; - /** - * An action to import color settings from file. - */ - protected Action fImportAction; - /** - * An action to export color settings from file. - */ - protected Action fExportAction; - /** - * The list of existing color settings - */ - protected List fColorSettings; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Default Constructor - */ - public ColorsView() { - super("Colors"); //$NON-NLS-1$ - } - - @Override - public void createPartControl(Composite parent) { - fShell = parent.getShell(); - - fScrolledComposite = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL); - fScrolledComposite.setExpandHorizontal(true); - fScrolledComposite.setExpandVertical(true); - fListComposite = new Composite(fScrolledComposite, SWT.NONE); - fScrolledComposite.setContent(fListComposite); - - GridLayout gl = new GridLayout(); - gl.marginHeight = 0; - gl.marginWidth = 0; - gl.verticalSpacing = 1; - fListComposite.setLayout(gl); - - fColorSettings = new ArrayList<>(Arrays.asList(ColorSettingsManager.getColorSettings())); - for (ColorSetting colorSetting : fColorSettings) { - new ColorSettingRow(fListComposite, colorSetting); - } - - fFillerComposite = new Composite(fListComposite, SWT.NONE); - GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); - gd.heightHint = 0; - fFillerComposite.setLayoutData(gd); - gl = new GridLayout(); - gl.marginHeight = 1; - gl.marginWidth = 1; - fFillerComposite.setLayout(gl); - Label fillerLabel = new Label(fFillerComposite, SWT.NONE); - fillerLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - fillerLabel.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - - fFillerComposite.addPaintListener(new PaintListener() { - @Override - public void paintControl(PaintEvent e) { - if (fSelectedRow == null) { - Color lineColor = Display.getDefault().getSystemColor(SWT.COLOR_BLACK); - Point p = fFillerComposite.getSize(); - GC gc = e.gc; - gc.setForeground(lineColor); - gc.drawLine(0, 0, p.x - 1, 0); - } - } - }); - - MouseListener mouseListener = new MouseAdapter() { - @Override - public void mouseDown(MouseEvent e) { - fSelectedRow = null; - refresh(); - } - }; - fillerLabel.addMouseListener(mouseListener); - - fScrolledComposite.setMinSize(fListComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); - - fillToolBar(); - } - - @Override - public void setFocus() { - fScrolledComposite.setFocus(); - } - - /** - * Refreshes the view display and updates the view actions enablements. - */ - public void refresh() { - fListComposite.layout(); - fScrolledComposite.setMinSize(fListComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); - fListComposite.redraw(0, 0, fListComposite.getBounds().width, fListComposite.getBounds().height, true); - if (fSelectedRow == null) { - fDeleteAction.setEnabled(false); - fMoveUpAction.setEnabled(false); - fMoveDownAction.setEnabled(false); - } else { - fDeleteAction.setEnabled(true); - fMoveUpAction.setEnabled(true); - fMoveDownAction.setEnabled(true); - } - } - - private void fillToolBar() { - - fAddAction = new AddAction(); - fAddAction.setImageDescriptor(ImageDescriptor.createFromImage(ADD_IMAGE)); - fAddAction.setToolTipText(Messages.ColorsView_AddActionToolTipText); - - fDeleteAction = new DeleteAction(); - fDeleteAction.setImageDescriptor(ImageDescriptor.createFromImage(DELETE_IMAGE)); - fDeleteAction.setToolTipText(Messages.ColorsView_DeleteActionToolTipText); - fDeleteAction.setEnabled(false); - - fMoveUpAction = new MoveUpAction(); - fMoveUpAction.setImageDescriptor(ImageDescriptor.createFromImage(MOVE_UP_IMAGE)); - fMoveUpAction.setToolTipText(Messages.ColorsView_MoveUpActionToolTipText); - fMoveUpAction.setEnabled(false); - - fMoveDownAction = new MoveDownAction(); - fMoveDownAction.setImageDescriptor(ImageDescriptor.createFromImage(MOVE_DOWN_IMAGE)); - fMoveDownAction.setToolTipText(Messages.ColorsView_MoveDownActionToolTipText); - fMoveDownAction.setEnabled(false); - - fExportAction = new ExportAction(); - fExportAction.setImageDescriptor(ImageDescriptor.createFromImage(EXPORT_IMAGE)); - fExportAction.setToolTipText(Messages.ColorsView_ExportActionToolTipText); - - fImportAction = new ImportAction(); - fImportAction.setImageDescriptor(ImageDescriptor.createFromImage(IMPORT_IMAGE)); - fImportAction.setToolTipText(Messages.ColorsView_ImportActionToolTipText); - - IActionBars bars = getViewSite().getActionBars(); - IToolBarManager manager = bars.getToolBarManager(); - manager.add(fAddAction); - manager.add(fDeleteAction); - manager.add(fMoveUpAction); - manager.add(fMoveDownAction); - manager.add(new Separator()); - manager.add(fExportAction); - manager.add(fImportAction); - } - - private class AddAction extends Action { - @Override - public void run() { - ColorSetting colorSetting = new ColorSetting( - Display.getDefault().getSystemColor(SWT.COLOR_LIST_FOREGROUND).getRGB(), - Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND).getRGB(), - Display.getDefault().getSystemColor(SWT.COLOR_LIST_FOREGROUND).getRGB(), - null); - ColorSettingRow row = new ColorSettingRow(fListComposite, colorSetting); - if (fSelectedRow == null) { - fColorSettings.add(colorSetting); - row.moveAbove(fFillerComposite); - } else { - fColorSettings.add(fColorSettings.indexOf(fSelectedRow.getColorSetting()), colorSetting); - row.moveAbove(fSelectedRow); - } - fSelectedRow = row; - refresh(); - ColorSettingsManager.setColorSettings(fColorSettings.toArray(new ColorSetting[0])); - } - } - - private class DeleteAction extends Action { - - @Override - public void run() { - if (fSelectedRow != null) { - int index = fColorSettings.indexOf(fSelectedRow.getColorSetting()); - fColorSettings.remove(index); - fSelectedRow.fColorSetting.dispose(); - fSelectedRow.dispose(); - if (index < fColorSettings.size()) { - fSelectedRow = (ColorSettingRow) fListComposite.getChildren()[index]; - } else { - fSelectedRow = null; - } - refresh(); - ColorSettingsManager.setColorSettings(fColorSettings.toArray(new ColorSetting[0])); - } - } - } - - private class MoveUpAction extends Action { - @Override - public void run() { - if (fSelectedRow != null) { - int index = fColorSettings.indexOf(fSelectedRow.getColorSetting()); - if (index > 0) { - fColorSettings.add(index - 1, fColorSettings.remove(index)); - fSelectedRow.moveAbove(fListComposite.getChildren()[index - 1]); - refresh(); - ColorSettingsManager.setColorSettings(fColorSettings.toArray(new ColorSetting[0])); - } - } - } - } - - private class MoveDownAction extends Action { - @Override - public void run() { - if (fSelectedRow != null) { - int index = fColorSettings.indexOf(fSelectedRow.getColorSetting()); - if (index < fColorSettings.size() - 1) { - fColorSettings.add(index + 1, fColorSettings.remove(index)); - - fSelectedRow.moveBelow(fListComposite.getChildren()[index + 1]); - refresh(); - ColorSettingsManager.setColorSettings(fColorSettings.toArray(new ColorSetting[0])); - } - } - } - } - - private class ExportAction extends Action { - @Override - public void run() { - FileDialog fileDialog = new FileDialog(fShell, SWT.SAVE); - fileDialog.setFilterExtensions(new String[] {"*.xml"}); //$NON-NLS-1$ - fileDialog.setOverwrite(true); - String pathName = fileDialog.open(); - if (pathName != null) { - ColorSettingsXML.save(pathName, fColorSettings.toArray(new ColorSetting[0])); - } - } - } - - private class ImportAction extends Action { - @Override - public void run() { - FileDialog fileDialog = new FileDialog(fShell, SWT.OPEN); - fileDialog.setFilterExtensions(new String[] {"*.xml"}); //$NON-NLS-1$ - String pathName = fileDialog.open(); - if (pathName != null) { - ColorSetting[] colorSettings = ColorSettingsXML.load(pathName); - if (colorSettings.length > 0) { - if (fColorSettings.size() > 0) { - boolean overwrite = MessageDialog.openQuestion(fShell, - Messages.ColorsView_ImportOverwriteDialogTitle, - Messages.ColorsView_ImportOverwriteDialogMessage1 + - Messages.ColorsView_ImportOverwriteDialogMessage2); - if (overwrite) { - for (Control control : fListComposite.getChildren()) { - if (control instanceof ColorSettingRow) { - ((ColorSettingRow) control).fColorSetting.dispose(); - control.dispose(); - } - } - fColorSettings = new ArrayList<>(); - fSelectedRow = null; - } - } - for (ColorSetting colorSetting : colorSettings) { - ColorSettingRow row = new ColorSettingRow(fListComposite, colorSetting); - if (fSelectedRow == null) { - fColorSettings.add(colorSetting); - row.moveAbove(fFillerComposite); - } else { - fColorSettings.add(fColorSettings.indexOf(fSelectedRow.getColorSetting()), colorSetting); - row.moveAbove(fSelectedRow); - } - } - refresh(); - ColorSettingsManager.setColorSettings(fColorSettings.toArray(new ColorSetting[0])); - } - } - } - } - - private class ColorSettingRow extends Composite { - - ColorSetting fColorSetting; - - public ColorSettingRow(final Composite parent, final ColorSetting colorSetting) { - super(parent, SWT.NONE); - fColorSetting = colorSetting; - - setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - - setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - GridLayout gl = new GridLayout(7, false); - gl.marginHeight = 1; - gl.marginWidth = 1; - gl.horizontalSpacing = 1; - gl.verticalSpacing = 0; - setLayout(gl); - - final Button fgButton = new Button(this, SWT.PUSH); - fgButton.setText(Messages.ColorsView_ForegroundButtonText); - fgButton.setSize(fgButton.computeSize(SWT.DEFAULT, 19)); - fgButton.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - - final Button bgButton = new Button(this, SWT.PUSH); - bgButton.setText(Messages.ColorsView_BackgroundButtonText); - bgButton.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - - final Composite labelComposite = new Composite(this, SWT.NONE); - labelComposite.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, false, false)); - gl = new GridLayout(); - gl.marginHeight = 0; - gl.marginWidth = 0; - labelComposite.setLayout(gl); - labelComposite.setBackground(colorSetting.getBackgroundColor()); - - final Label label = new Label(labelComposite, SWT.NONE); - label.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, true)); - label.setText(" Text "); //$NON-NLS-1$ - label.setForeground(colorSetting.getForegroundColor()); - label.setBackground(colorSetting.getBackgroundColor()); - - fgButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - fSelectedRow = ColorSettingRow.this; - refresh(); - ColorDialog dialog = new ColorDialog(fShell); - dialog.setRGB(colorSetting.getForegroundRGB()); - dialog.setText(Messages.ColorsView_ForegroundDialogText); - dialog.open(); - RGB rgb = dialog.getRGB(); - if (rgb != null) { - colorSetting.setForegroundRGB(rgb); - ColorSettingsManager.setColorSettings(fColorSettings.toArray(new ColorSetting[0])); - label.setForeground(colorSetting.getForegroundColor()); - } - }}); - - bgButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - fSelectedRow = ColorSettingRow.this; - refresh(); - ColorDialog dialog = new ColorDialog(fShell); - dialog.setRGB(colorSetting.getBackgroundRGB()); - dialog.setText(Messages.ColorsView_BackgroundDialogText); - dialog.open(); - RGB rgb = dialog.getRGB(); - if (rgb != null) { - colorSetting.setBackgroundRGB(rgb); - ColorSettingsManager.setColorSettings(fColorSettings.toArray(new ColorSetting[0])); - labelComposite.setBackground(colorSetting.getBackgroundColor()); - label.setBackground(colorSetting.getBackgroundColor()); - } - }}); - - final Button tickButton = new Button(this, SWT.PUSH); - tickButton.setText(Messages.ColorsView_TickButtonText); - tickButton.setSize(tickButton.computeSize(SWT.DEFAULT, 19)); - tickButton.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - - final Canvas tickCanvas = new Canvas(this, SWT.NONE); - GridData gd = new GridData(SWT.CENTER, SWT.FILL, false, false); - gd.widthHint = 12; - gd.heightHint = bgButton.getSize().y; - tickCanvas.setLayoutData(gd); - tickCanvas.setBackground(traceColorScheme.getBkColor(false, false, false)); - tickCanvas.addPaintListener(new PaintListener() { - @Override - public void paintControl(PaintEvent e) { - Rectangle bounds = tickCanvas.getBounds(); - e.gc.setForeground(traceColorScheme.getColor(TimeGraphColorScheme.MID_LINE)); - int midy = bounds.y + bounds.height / 2 - 1; - //int midy = e.y + e.height / 2; - e.gc.drawLine(e.x, midy, e.x + e.width, midy); - Rectangle rect = new Rectangle(e.x + 1, bounds.y + 2, 0, bounds.height - 6); - for (int i = 1; i <= 3; i++) { - rect.x += i; - rect.width = i; - e.gc.setBackground(fColorSetting.getTickColor()); - e.gc.fillRectangle(rect); - } - }}); - - tickButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - fSelectedRow = ColorSettingRow.this; - ColorDialog dialog = new ColorDialog(fShell); - dialog.setRGB(colorSetting.getTickColorRGB()); - dialog.setText(Messages.TickColorDialog_TickColorDialogTitle); - dialog.open(); - RGB rgb = dialog.getRGB(); - if (rgb != null) { - colorSetting.setTickColorRGB(rgb); - ColorSettingsManager.setColorSettings(fColorSettings.toArray(new ColorSetting[0])); - refresh(); - } - }}); - - final Button filterButton = new Button(this, SWT.PUSH); - filterButton.setText(Messages.ColorsView_FilterButtonText); - filterButton.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - - final Label filterText = new Label(this, SWT.NONE); - if (colorSetting.getFilter() != null) { - filterText.setText(colorSetting.getFilter().toString()); - filterText.setToolTipText(colorSetting.getFilter().toString()); - } - filterText.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - filterText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - filterButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - fSelectedRow = ColorSettingRow.this; - refresh(); - FilterDialog dialog = new FilterDialog(fShell); - dialog.setFilter(colorSetting.getFilter()); - dialog.open(); - if (dialog.getReturnCode() == Window.OK) { - if (dialog.getFilter() != null) { - colorSetting.setFilter(dialog.getFilter()); - filterText.setText(dialog.getFilter().toString()); - filterText.setToolTipText(dialog.getFilter().toString()); - } else { - colorSetting.setFilter(null); - filterText.setText(""); //$NON-NLS-1$ - filterText.setToolTipText(""); //$NON-NLS-1$ - } - ColorSettingsManager.setColorSettings(fColorSettings.toArray(new ColorSetting[0])); - refresh(); - } - }}); - - addPaintListener(new PaintListener() { - @Override - public void paintControl(PaintEvent e) { - if (fSelectedRow == ColorSettingRow.this) { - Color borderColor = Display.getDefault().getSystemColor(SWT.COLOR_BLACK); - Point p = ColorSettingRow.this.getSize(); - Rectangle rect = new Rectangle(0, 0, p.x - 1, p.y - 1); - GC gc = e.gc; - gc.setForeground(borderColor); - gc.drawRectangle(rect); - } - } - }); - - MouseListener mouseListener = new MouseAdapter() { - @Override - public void mouseDown(MouseEvent e) { - fSelectedRow = ColorSettingRow.this; - refresh(); - } - }; - addMouseListener(mouseListener); - label.addMouseListener(mouseListener); - tickCanvas.addMouseListener(mouseListener); - filterText.addMouseListener(mouseListener); - } - - /** - * @return the ColorSetting - */ - public ColorSetting getColorSetting() { - return fColorSetting; - } - - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/IColorSettingsListener.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/IColorSettingsListener.java deleted file mode 100644 index a1b7f68ef2..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/colors/IColorSettingsListener.java +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.colors; - -/** - * A color change listener - * - * @version 1.0 - * @author Patrick Tasse - */ -public interface IColorSettingsListener { - - /** - * Notify the listener that the color settings have changed. - * - * @param colorSettings - * The new color settings - */ - void colorSettingsChanged(ColorSetting[] colorSettings); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/distribution/model/BaseDistributionData.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/distribution/model/BaseDistributionData.java deleted file mode 100644 index 9ed11868f0..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/distribution/model/BaseDistributionData.java +++ /dev/null @@ -1,243 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Francois Chouinard - Moved from LTTng to TMF - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.distribution.model; - -/** - * Class with basic distribution data used for distribution models. - * - * It stores number of events (with timestamp) in buckets with a start time and a - * certain duration. The duration is the same across all buckets. - * Note that Timestamps are stored as long values. - * - * @version 1.0 - * @author Bernd Hufmann - */ -public class BaseDistributionData { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * Constant indication that bucket is not filled. - */ - public final static int OUT_OF_RANGE_BUCKET = -1; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * Number of buckets - */ - protected final int fNbBuckets; - /** - * Duration of each bucket - */ - protected long fBucketDuration; - /** - * Bucket index of last event time - */ - protected int fLastBucket; - /** - * Timestamp of the first bucket. (could be negative when analyzing events with descending time!!!) - */ - protected long fFirstBucketTime; - /** - * Timestamp of the first event - */ - protected long fFirstEventTime; - /** - * Timestamp of the last event - */ - protected long fLastEventTime; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructs a base distribution data object. - * @param nbBuckets A total number of buckets - */ - public BaseDistributionData(int nbBuckets) { - fNbBuckets = nbBuckets; - clear(); - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - /** - * Returns the total number of buckets. - * - * @return the number of buckets. - */ - public int getNbBuckets() { - return fNbBuckets; - } - - /** - * Returns the duration of buckets. - * - * @return bucket duration - */ - public long getBucketDuration() { - return fBucketDuration; - } - - /** - * Set the bucket duration. - * - * @param bucketDuration The duration to set. - */ - public void setBucketDuration(long bucketDuration) { - fBucketDuration = bucketDuration; - } - - /** - * Returns the index of the last used bucket. - * - * @return last bucket index. - */ - public int getLastBucket() { - return fLastBucket; - } - - /** - * Sets the index of the last bucket used. - * - * @param lastBucket The last bucket index to set. - */ - public void setLastBucket(int lastBucket) { - fLastBucket = lastBucket; - } - - /** - * Returns the start time of the first bucket. - * - * @return first bucket time. - */ - public long getFirstBucketTime() { - return fFirstBucketTime; - } - - /** - * Sets the start time of the first bucket. - * - * @param firstBucketTime The bucket time to ser. - */ - public void setFirstBucketTime(long firstBucketTime) { - fFirstBucketTime = firstBucketTime; - } - - /** - * Returns the start time of the last bucket used. - * - * @return the start time of the last bucket. - */ - public long getLastBucketTime() { - return getBucketStartTime(fLastBucket); - } - - /** - * Returns the time of the event with the lowest timestamp. - * - * @return first event time. - */ - public long getFirstEventTime() { - return fFirstEventTime; - } - - /** - * Sets the time of the event with the lowest timestamp. - * - * @param firstEventTime The first event time to set. - */ - public void setFirstEventTime(long firstEventTime) { - fFirstEventTime = firstEventTime; - } - - /** - * Returns the time of the event with the biggest timestamp. - * - * @return the last event time. - */ - public long getLastEventTime() { - return fLastEventTime; - } - - /** - * Sets the time of the event with the biggest timestamp. - * - * @param lastEventTime The last event time to set. - */ - public void setLastEventTime(long lastEventTime) { - fLastEventTime = lastEventTime; - } - - /** - * Returns the bucket start time of a given bucket index. - * - * @param index The bucket index. - * @return the bucket start time of a given bucket index. - */ - public long getBucketStartTime(int index) { - return fFirstBucketTime + index * fBucketDuration; - } - - /** - * Returns the bucket end time of a given bucket index. - * - * @param index The bucket index. - * @return the bucket start time of a given bucket index. - */ - public long getBucketEndTime(int index) { - return getBucketStartTime(index) + fBucketDuration; - } - - /** - * Returns the bucket index of the bucket containing a given time. - * - * @param time The timestamp to check. - * @return the bucket index of the bucket containing the given time. - */ - public int getIndex(long time) { - return (int)((time - fFirstBucketTime) / fBucketDuration); - } - - /** - * Check if an index is valid. - * - * @param index - * The index to check - * @return If it's valid, true or false. - */ - public boolean isIndexValid(int index) { - return ((index >= 0) && (index <= fNbBuckets - 1)); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Clears the data model to default values. - */ - public void clear() { - fFirstBucketTime = 0; - fFirstEventTime = 0; - fLastEventTime = 0; - fLastBucket = 0; - fBucketDuration = 1; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/distribution/model/IBaseDistributionModel.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/distribution/model/IBaseDistributionModel.java deleted file mode 100644 index f44d5393b4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/distribution/model/IBaseDistributionModel.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Francois Chouinard - Moved from LTTng to TMF - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.distribution.model; - -/** - * Base distribution model interface. - * - * Distribution models such histograms need to implement this interface. - * - * @version 1.0 - * @author Bernd Hufmann - * - */ -public interface IBaseDistributionModel { - /** - * Complete the model (all data received) - */ - void complete(); - - /** - * Clear the model (delete all data). - */ - void clear(); -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/CopyHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/CopyHandler.java deleted file mode 100644 index 401d87937d..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/CopyHandler.java +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Kalray - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xavier Raynaud - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.filter; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.util.LocalSelectionTransfer; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -/** - * Handler for copy command in filter view - * @author Xavier Raynaud - * @since 3.0 - */ -public class CopyHandler extends AbstractHandler { - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - IWorkbenchPage page = window.getActivePage(); - FilterView part = (FilterView) page.getActivePart(); - ISelection selection = getSelection(part); - - LocalSelectionTransfer.getTransfer().setSelection(selection); - LocalSelectionTransfer.getTransfer().setSelectionSetTime(System.currentTimeMillis()); - return null; - } - - /** - * Retrieve the current selection - * - * @param tcv - * the FilterView - * @return the current selection in the FilterView - */ - protected ISelection getSelection(FilterView tcv) { - return tcv.getViewSite().getSelectionProvider().getSelection(); - } - - @Override - public boolean isEnabled() { - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return false; - } - - // Get the selection - IWorkbenchPage page = window.getActivePage(); - IWorkbenchPart part = page.getActivePart(); - if (part instanceof FilterView) { - FilterView tcv = (FilterView) part; - ISelection selection = tcv.getSite().getSelectionProvider().getSelection(); - if (!selection.isEmpty()) { - return true; - } - } - return false; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/CutHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/CutHandler.java deleted file mode 100644 index 5de70d43f7..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/CutHandler.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Kalray - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xavier Raynaud - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.filter; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; - -/** - * Handler for cut command in filter view - * @author Xavier Raynaud - * @since 3.0 - */ -public class CutHandler extends CopyHandler { - - @Override - protected ISelection getSelection(FilterView tcv) { - ISelection sel = super.getSelection(tcv); - if (sel instanceof IStructuredSelection) { - IStructuredSelection selection = (IStructuredSelection) sel; - Object o = selection.getFirstElement(); - if (o instanceof ITmfFilterTreeNode) { - ITmfFilterTreeNode node = (ITmfFilterTreeNode) o; - node = node.remove(); - tcv.refresh(); - return new StructuredSelection(node); - } - } - return sel; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/DeleteHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/DeleteHandler.java deleted file mode 100644 index 00e8064db8..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/DeleteHandler.java +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Kalray - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xavier Raynaud - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.filter; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -/** - * Handler for delete command in filter view - * @author Xavier Raynaud - * @since 3.0 - */ -public class DeleteHandler extends AbstractHandler { - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - IWorkbenchPage page = window.getActivePage(); - FilterView part = (FilterView) page.getActivePart(); - ISelection sel = part.getViewSite().getSelectionProvider().getSelection(); - if (sel instanceof IStructuredSelection) { - IStructuredSelection selection = (IStructuredSelection) sel; - Object o = selection.getFirstElement(); - if (o instanceof ITmfFilterTreeNode) { - ITmfFilterTreeNode node = (ITmfFilterTreeNode) o; - node = node.remove(); - part.refresh(); - } - } - return null; - } - - @Override - public boolean isEnabled() { - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return false; - } - - // Get the selection - IWorkbenchPage page = window.getActivePage(); - IWorkbenchPart part = page.getActivePart(); - if (part instanceof FilterView) { - FilterView tcv = (FilterView) part; - ISelection selection = tcv.getSite().getSelectionProvider().getSelection(); - if (!selection.isEmpty()) { - return true; - } - } - return false; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterDialog.java deleted file mode 100644 index d573c1760d..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterDialog.java +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.filter; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterNode; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Shell; - -/** - * The dialog for user-defined filters. - * - * @version 1.0 - * @author Patrick Tasse - */ -public class FilterDialog extends Dialog { - - TmfFilterNode fRoot; - FilterViewer fViewer; - - /** - * Constructor. - * - * @param shell - * The shell to which this dialog is attached - */ - public FilterDialog(Shell shell) { - super(shell); - setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX); - } - - @Override - protected Control createDialogArea(Composite parent) { - getShell().setText(Messages.FilterDialog_FilterDialogTitle); - getShell().setMinimumSize(getShell().computeSize(500, 200)); - Composite composite = (Composite) super.createDialogArea(parent); - - fViewer = new FilterViewer(composite, SWT.BORDER); - fViewer.setInput(fRoot); - return composite; - } - - /** - * @param filter - * the filter to set - */ - public void setFilter(ITmfFilterTreeNode filter) { - fRoot = new TmfFilterNode(null); - if (filter != null) { - fRoot.addChild(filter.clone()); - } - if (fViewer != null) { - fViewer.setInput(fRoot); - } - } - - /** - * @return the filter - */ - public ITmfFilterTreeNode getFilter() { - if (fRoot != null && fRoot.hasChildren()) { - return fRoot.getChild(0).clone(); - } - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterDragSourceAdapter.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterDragSourceAdapter.java deleted file mode 100644 index 983928ec1b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterDragSourceAdapter.java +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Kalray - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xavier Raynaud - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.filter; - -import org.eclipse.jface.util.LocalSelectionTransfer; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; -import org.eclipse.swt.dnd.DND; -import org.eclipse.swt.dnd.DragSourceAdapter; -import org.eclipse.swt.dnd.DragSourceEvent; - -/** - * DragSourceListener for filter view - * @author Xavier Raynaud - */ -class FilterDragSourceAdapter extends DragSourceAdapter { - - private FilterViewer fViewer; - - /** - * Constructor - * - * @param viewer - * the content of the FilterView - */ - public FilterDragSourceAdapter(FilterViewer viewer) { - super(); - this.fViewer = viewer; - } - - @Override - public void dragStart(DragSourceEvent event) { - ISelection s = fViewer.getTreeViewer().getSelection(); - LocalSelectionTransfer.getTransfer().setSelection(s); - LocalSelectionTransfer.getTransfer().setSelectionSetTime(event.time & 0xFFFFFFFFL); - } - - @Override - public void dragSetData(DragSourceEvent event) { - event.data = LocalSelectionTransfer.getTransfer().getSelection(); - } - - @Override - public void dragFinished(DragSourceEvent event) { - if (event.detail == DND.DROP_MOVE) { - IStructuredSelection selection = (IStructuredSelection) LocalSelectionTransfer.getTransfer().getSelection(); - for (Object data : selection.toList()) { - if (data instanceof ITmfFilterTreeNode) { - ITmfFilterTreeNode e = (ITmfFilterTreeNode) data; - e.remove(); - fViewer.refresh(); - } - } - } - LocalSelectionTransfer.getTransfer().setSelection(null); - LocalSelectionTransfer.getTransfer().setSelectionSetTime(0); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterDropTargetAdapter.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterDropTargetAdapter.java deleted file mode 100644 index dce866b2c8..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterDropTargetAdapter.java +++ /dev/null @@ -1,124 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Kalray - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xavier Raynaud - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.filter; - - -import org.eclipse.jface.util.LocalSelectionTransfer; -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterNode; -import org.eclipse.swt.dnd.DND; -import org.eclipse.swt.dnd.DropTargetAdapter; -import org.eclipse.swt.dnd.DropTargetEvent; -import org.eclipse.swt.widgets.TreeItem; - -/** - * DropTargetListener for filter view - * @author Xavier Raynaud - */ -class FilterDropTargetAdapter extends DropTargetAdapter { - - private FilterViewer fViewer; - - /** - * Constructor - * @param viewer the content of the FilterView - */ - public FilterDropTargetAdapter(FilterViewer viewer) { - super(); - this.fViewer = viewer; - } - - /** - * Returns true if droppedNode is an ancestor of node. - * - * @param droppedNode - * the ITmfFilterTreeNode to drop or paste - * @param node - * the ITmfFilterTreeNode receiving a new child - * @return true if droppedNode is and ancestor of node, - * false otherwise. - */ - private static boolean isAncestor(ITmfFilterTreeNode droppedNode, ITmfFilterTreeNode node) { - ITmfFilterTreeNode tmp = node; - - while (tmp != null) { - ITmfFilterTreeNode n = tmp.getParent(); - if (n == droppedNode) { - return true; - } - tmp = n; - } - return false; - } - - @Override - public void dropAccept(DropTargetEvent event) { - ITmfFilterTreeNode treeNodeToDrop = null; - if (LocalSelectionTransfer.getTransfer().isSupportedType(event.currentDataType)) { - treeNodeToDrop = FilterEditUtils.getTransferredTreeNode(); - } - if (treeNodeToDrop == null) { - // should never occur - event.detail = DND.DROP_NONE; - return; - } - if (event.item instanceof TreeItem) { - Object data = event.item.getData(); - if (data instanceof ITmfFilterTreeNode) { - ITmfFilterTreeNode node = (ITmfFilterTreeNode) data; - if (node.getValidChildren().contains(treeNodeToDrop.getNodeName())) { - if (isAncestor(treeNodeToDrop, node) && event.detail != DND.DROP_COPY) { - // do nothing in this case - event.detail = DND.DROP_NONE; - } - return; - } - } - } else { // accept only TmfFilterNode - if (!TmfFilterNode.NODE_NAME.equals(treeNodeToDrop.getNodeName())) { - event.detail = DND.DROP_NONE; - } - return; - } - event.detail = DND.DROP_NONE; - return; - } - - @Override - public void drop(DropTargetEvent event) { - ITmfFilterTreeNode treeNodeToDrop = FilterEditUtils.getTransferredTreeNode(); - if (event.item instanceof TreeItem) { - Object data = event.item.getData(); - if (data instanceof ITmfFilterTreeNode) { - ITmfFilterTreeNode node = (ITmfFilterTreeNode) data; - if (node.getValidChildren().contains(treeNodeToDrop.getNodeName())) { - treeNodeToDrop = treeNodeToDrop.clone(); - node.addChild(treeNodeToDrop); - fViewer.refresh(); - fViewer.setSelection(treeNodeToDrop, true); - return; - } - } - } else { // accept only TmfFilterNode - if (TmfFilterNode.NODE_NAME.equals(treeNodeToDrop.getNodeName())) { - ITmfFilterTreeNode root = fViewer.getInput(); - treeNodeToDrop = treeNodeToDrop.clone(); - root.addChild(treeNodeToDrop); - fViewer.refresh(); - fViewer.setSelection(treeNodeToDrop, true); - return; - } - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterEditUtils.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterEditUtils.java deleted file mode 100644 index 679c115411..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterEditUtils.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Kalray - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xavier Raynaud - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.filter; - -import org.eclipse.jface.util.LocalSelectionTransfer; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; - -/** - * Utilities for cut/copy/paste/dnd in filter view - * @author Xavier Raynaud - */ -class FilterEditUtils { - - /** - * Gets the ITmfFilterTreeNode in LocalSelectionTransfer, if any - * @return a ITmfFilterTreeNode or null - */ - public static ITmfFilterTreeNode getTransferredTreeNode() { - ITmfFilterTreeNode treeNodeToDrop = null; - ISelection sel = LocalSelectionTransfer.getTransfer().getSelection(); - if (sel instanceof IStructuredSelection) { - IStructuredSelection selection = (IStructuredSelection) sel; - for (Object data : selection.toList()) { - if (!(data instanceof ITmfFilterTreeNode)) { - return null; - } else if (treeNodeToDrop != null) { - // should never occur, since tree has SWT.SINGLE style - return null; - } else { - treeNodeToDrop = (ITmfFilterTreeNode) data; - } - } - } - return treeNodeToDrop; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterManager.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterManager.java deleted file mode 100644 index db6b551de8..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterManager.java +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.filter; - -import java.io.FileNotFoundException; -import java.io.IOException; - -import javax.xml.parsers.ParserConfigurationException; - -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterRootNode; -import org.eclipse.linuxtools.tmf.core.filter.xml.TmfFilterXMLParser; -import org.eclipse.linuxtools.tmf.core.filter.xml.TmfFilterXMLWriter; -import org.xml.sax.SAXException; - -/** - * Central filter manager - * - * @version 1.0 - * @author Patrick Tasse - */ -public class FilterManager { - - private static final String SAVED_FILTERS_FILE_NAME = "saved_filters.xml"; //$NON-NLS-1$ - private static final String SAVED_FILTERS_PATH_NAME = - Activator.getDefault().getStateLocation().addTrailingSeparator().append(SAVED_FILTERS_FILE_NAME).toString(); - - private static ITmfFilterTreeNode fRoot = new TmfFilterRootNode(); - static { - try { - fRoot = new TmfFilterXMLParser(SAVED_FILTERS_PATH_NAME).getTree(); - } catch (FileNotFoundException e) { - } catch (SAXException e) { - Activator.getDefault().logError("Error parsing saved filter xml file: " + SAVED_FILTERS_PATH_NAME, e); //$NON-NLS-1$ - } catch (IOException e) { - Activator.getDefault().logError("Error parsing saved filter xml file: " + SAVED_FILTERS_PATH_NAME, e); //$NON-NLS-1$ - } - } - - /** - * Retrieve the currently saved filters - * - * @return The array of filters - */ - public static ITmfFilterTreeNode[] getSavedFilters() { - return fRoot.clone().getChildren(); - } - - /** - * Set the passed filters as the currently saved ones. - * - * @param filters - * The filters to save - */ - public static void setSavedFilters(ITmfFilterTreeNode[] filters) { - fRoot = new TmfFilterRootNode(); - for (ITmfFilterTreeNode filter : filters) { - fRoot.addChild(filter.clone()); - } - try { - TmfFilterXMLWriter writerXML = new TmfFilterXMLWriter(fRoot); - writerXML.saveTree(SAVED_FILTERS_PATH_NAME); - } catch (ParserConfigurationException e) { - Activator.getDefault().logError("Error saving filter xml file: " + SAVED_FILTERS_PATH_NAME, e); //$NON-NLS-1$ - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterTreeContentProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterTreeContentProvider.java deleted file mode 100644 index 326e43dcca..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterTreeContentProvider.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Yuriy Vashchuk - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.filter; - -import java.util.ArrayList; - -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; - -/** - * This is the Content Provider of our tree - * - * @version 1.0 - * @author Yuriy Vashchuk - */ -public class FilterTreeContentProvider implements ITreeContentProvider { - - @Override - public void dispose() { - // TODO Auto-generated method stub - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - // TODO Auto-generated method stub - } - - @Override - public Object[] getElements(Object inputElement) { - if (inputElement instanceof ITmfFilterTreeNode) { - ArrayList result = new ArrayList<>(); - for (int i = 0; i < ((ITmfFilterTreeNode) inputElement).getChildrenCount(); i++) { - result.add(((ITmfFilterTreeNode) inputElement).getChild(i)); - } - - return result.toArray(); - } - return null; - } - - @Override - public Object[] getChildren(Object parentElement) { - ArrayList result = new ArrayList<>(); - for (int i = 0; i < ((ITmfFilterTreeNode) parentElement).getChildrenCount(); i++) { - result.add(((ITmfFilterTreeNode) parentElement).getChild(i)); - } - return result.toArray(); - } - - @Override - public Object getParent(Object element) { - return ((ITmfFilterTreeNode) element).getParent(); - } - - @Override - public boolean hasChildren(Object element) { - return ((ITmfFilterTreeNode) element).hasChildren(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterTreeLabelProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterTreeLabelProvider.java deleted file mode 100644 index 4657a34b32..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterTreeLabelProvider.java +++ /dev/null @@ -1,126 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Yuriy Vashchuk - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.filter; - -import org.eclipse.jface.viewers.ILabelProvider; -import org.eclipse.jface.viewers.ILabelProviderListener; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterAndNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterCompareNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterCompareNode.Type; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterContainsNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterEqualsNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterEventTypeNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterMatchesNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterOrNode; -import org.eclipse.swt.graphics.Image; - -/** - * This is the Label Provider for our Filter Tree - * - * @version 1.0 - * @author Yuriy Vashchuk - */ -public class FilterTreeLabelProvider implements ILabelProvider { - - @Override - public void addListener(ILabelProviderListener listener) { - // TODO Auto-generated method stub - } - - @Override - public void dispose() { - // TODO Auto-generated method stub - } - - @Override - public boolean isLabelProperty(Object element, String property) { - // TODO Auto-generated method stub - return false; - } - - @Override - public void removeListener(ILabelProviderListener listener) { - // TODO Auto-generated method stub - } - - @Override - public Image getImage(Object element) { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getText(Object element) { - String label = null; - - if (element instanceof TmfFilterNode) { - - TmfFilterNode node = (TmfFilterNode) element; - label = node.getNodeName() + " " + node.getFilterName(); //$NON-NLS-1$ - - } else if (element instanceof TmfFilterEventTypeNode) { - - TmfFilterEventTypeNode node = (TmfFilterEventTypeNode) element; - label = "WITH " + node.getNodeName() + (node.getName() != null ? " " + node.getName() : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - - } else if (element instanceof TmfFilterAndNode) { - - TmfFilterAndNode node = (TmfFilterAndNode) element; - label = (node.isNot() ? "NOT " : "") + node.getNodeName(); //$NON-NLS-1$ //$NON-NLS-2$ - - } else if (element instanceof TmfFilterOrNode) { - - TmfFilterOrNode node = (TmfFilterOrNode) element; - label = (node.isNot() ? "NOT " : "") + node.getNodeName(); //$NON-NLS-1$ //$NON-NLS-2$ - - } else if (element instanceof TmfFilterContainsNode) { - - TmfFilterContainsNode node = (TmfFilterContainsNode) element; - label = (node.isNot() ? "NOT " : "") + //$NON-NLS-1$ //$NON-NLS-2$ - (node.getField() != null ? node.getField() + " " : "") + //$NON-NLS-1$ //$NON-NLS-2$ - node.getNodeName() + - (node.getValue() != null && node.getValue().length() > 0 ? " \"" + node.getValue() + "\"" : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - - } else if (element instanceof TmfFilterEqualsNode) { - - TmfFilterEqualsNode node = (TmfFilterEqualsNode) element; - label = (node.isNot() ? "NOT " : "") + //$NON-NLS-1$ //$NON-NLS-2$ - (node.getField() != null ? node.getField() + " " : "") + //$NON-NLS-1$ //$NON-NLS-2$ - node.getNodeName() + - (node.getValue() != null && node.getValue().length() > 0 ? " \"" + node.getValue() + "\"" : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - - } else if (element instanceof TmfFilterMatchesNode) { - - TmfFilterMatchesNode node = (TmfFilterMatchesNode) element; - label = (node.isNot() ? "NOT " : "") + //$NON-NLS-1$ //$NON-NLS-2$ - (node.getField() != null ? node.getField() + " " : "") + //$NON-NLS-1$ //$NON-NLS-2$ - node.getNodeName() + - (node.getRegex() != null && node.getRegex().length() > 0 ? " \"" + node.getRegex() + "\"" : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - - } else if (element instanceof TmfFilterCompareNode) { - - TmfFilterCompareNode node = (TmfFilterCompareNode) element; - label = (node.isNot() ? "NOT " : "") + //$NON-NLS-1$ //$NON-NLS-2$ - (node.getField() != null ? node.getField() + " " : "") + //$NON-NLS-1$ //$NON-NLS-2$ - (node.getResult() < 0 ? "<" : (node.getResult() > 0 ? ">" : "=")) + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - (node.getValue() != null && node.getValue().length() > 0 ? - (node.getType() == Type.ALPHA ? " \"" + node.getValue() + "\"" : //$NON-NLS-1$ //$NON-NLS-2$ - (node.getType() == Type.TIMESTAMP ? " [" + node.getValue() + "]" : //$NON-NLS-1$ //$NON-NLS-2$ - " " + node.getValue())) : ""); //$NON-NLS-1$//$NON-NLS-2$ - - } - return label; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterView.java deleted file mode 100644 index 3bd9d8b9fc..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterView.java +++ /dev/null @@ -1,309 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Yuriy Vashchuk - Initial API and implementation - * Xavier Raynaud - add cut/copy/paste/dnd support - * based on Francois Chouinard ProjectView code. - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.filter; - -import java.io.IOException; - -import javax.xml.parsers.ParserConfigurationException; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterRootNode; -import org.eclipse.linuxtools.tmf.core.filter.xml.TmfFilterXMLParser; -import org.eclipse.linuxtools.tmf.core.filter.xml.TmfFilterXMLWriter; -import org.eclipse.linuxtools.tmf.ui.views.TmfView; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IActionBars; -import org.xml.sax.SAXException; - -/** - * View that contain UI to the TMF filter. - * - * @version 1.0 - * @author Yuriy Vashchuk - */ -public class FilterView extends TmfView { - - /** ID for the Filter view */ - public static final @NonNull String ID = "org.eclipse.linuxtools.tmf.ui.views.filter"; //$NON-NLS-1$ - - private static final Image SAVE_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/save_button.gif"); //$NON-NLS-1$ - private static final Image ADD_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/add_button.gif"); //$NON-NLS-1$ - private static final Image IMPORT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/import_button.gif"); //$NON-NLS-1$ - private static final Image EXPORT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/export_button.gif"); //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Main data structures - // ------------------------------------------------------------------------ - - private FilterViewer fViewer; - private final ITmfFilterTreeNode fRoot; - - private final IWorkspace fWorkspace; - - private SaveAction fSaveAction; - private AddAction fAddAction; - private ExportAction fExportAction; - private ImportAction fImportAction; - - /** - * Getter for the Filter Tree Root - * - * @return The root of builded tree - */ - public ITmfFilterTreeNode getFilterRoot() { - return fRoot; - } - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Default Constructor - */ - public FilterView() { - super("Filter"); //$NON-NLS-1$ - - fWorkspace = ResourcesPlugin.getWorkspace(); - try { - fWorkspace.getRoot().refreshLocal(IResource.DEPTH_INFINITE, null); - } catch (CoreException e) { - Activator.getDefault().logError("Error refreshing workspace", e); //$NON-NLS-1$ - } - - fRoot = new TmfFilterRootNode(); - for (ITmfFilterTreeNode node : FilterManager.getSavedFilters()) { - fRoot.addChild(node); - } - } - - /** - * Add a filter to the FilterView. This does not modify the XML, which must - * be done manually. If the filter is already in the FilterView, this is a - * no-op. - * - * @param filter - * The filter to add. - * @since 3.1 - */ - public void addFilter(ITmfFilterTreeNode filter) { - ITmfFilterTreeNode root = fViewer.getInput(); - for (ITmfFilterTreeNode node : root.getChildren()) { - if (node.equals(filter)) { - return; - } - } - root.addChild(filter); - fViewer.setInput(root); - } - - /** - * Refresh the tree widget - */ - public void refresh() { - fViewer.refresh(); - } - - /** - * Setter for selection - * - * @param node - * The node to select - */ - public void setSelection(ITmfFilterTreeNode node) { - fViewer.setSelection(node, true); - } - - // ------------------------------------------------------------------------ - // ViewPart - // ------------------------------------------------------------------------ - - @Override - public void createPartControl(Composite parent) { - - fViewer = new FilterViewer(parent, SWT.NONE); - fViewer.setInput(fRoot); - - contributeToActionBars(); - - fViewer.addSelectionChangedListener(new ISelectionChangedListener() { - @Override - public void selectionChanged(SelectionChangedEvent event) { - if (!(event.getSelection().isEmpty()) && event.getSelection() instanceof IStructuredSelection) { - fExportAction.setEnabled(true); - } else { - fExportAction.setEnabled(false); - } - } - }); - this.getSite().setSelectionProvider(fViewer.getTreeViewer()); - - MenuManager menuManager = fViewer.getMenuManager(); - this.getSite().registerContextMenu(menuManager, fViewer.getTreeViewer()); - } - - /** - * @return the ITmfFilterTreeNode currently selected - */ - ITmfFilterTreeNode getSelection() { - return fViewer.getSelection(); - } - - @Override - public void setFocus() { - fViewer.setFocus(); - } - - @Override - public String toString() { - return "[FilterView]"; //$NON-NLS-1$ - } - - /** - * Builds the menu toolbar - */ - private void contributeToActionBars() { - IActionBars bars = getViewSite().getActionBars(); - // fillLocalPullDown(bars.getMenuManager()); - fillLocalToolBar(bars.getToolBarManager()); - } - - /** - * Build the popup menu - * - * @param manager - * The manager to build - */ - private void fillLocalToolBar(IToolBarManager manager) { - - fSaveAction = new SaveAction(); - fSaveAction.setImageDescriptor(ImageDescriptor.createFromImage(SAVE_IMAGE)); - fSaveAction.setToolTipText(Messages.FilterView_SaveActionToolTipText); - - fAddAction = new AddAction(); - fAddAction.setImageDescriptor(ImageDescriptor.createFromImage(ADD_IMAGE)); - fAddAction.setToolTipText(Messages.FilterView_AddActionToolTipText); - - fExportAction = new ExportAction(); - fExportAction.setImageDescriptor(ImageDescriptor.createFromImage(EXPORT_IMAGE)); - fExportAction.setToolTipText(Messages.FilterView_ExportActionToolTipText); - - fImportAction = new ImportAction(); - fImportAction.setImageDescriptor(ImageDescriptor.createFromImage(IMPORT_IMAGE)); - fImportAction.setToolTipText(Messages.FilterView_ImportActionToolTipText); - - manager.add(fSaveAction); - manager.add(new Separator("add_delete")); //$NON-NLS-1$ - manager.add(fAddAction); - manager.add(new Separator("edit")); //$NON-NLS-1$ - manager.add(new Separator()); - manager.add(fExportAction); - manager.add(fImportAction); - } - - private class SaveAction extends Action { - @Override - public void run() { - FilterManager.setSavedFilters(fRoot.getChildren()); - } - } - - private class AddAction extends Action { - @Override - public void run() { - - TmfFilterNode newNode = new TmfFilterNode(fRoot, ""); //$NON-NLS-1$ - refresh(); - setSelection(newNode); - } - } - - private class ExportAction extends Action { - @Override - public void run() { - try { - FileDialog dlg = new FileDialog(new Shell(), SWT.SAVE); - dlg.setFilterNames(new String[] { Messages.FilterView_FileDialogFilterName + " (*.xml)" }); //$NON-NLS-1$ - dlg.setFilterExtensions(new String[] { "*.xml" }); //$NON-NLS-1$ - - String fn = dlg.open(); - if (fn != null) { - TmfFilterXMLWriter writerXML = new TmfFilterXMLWriter(fRoot); - writerXML.saveTree(fn); - } - - } catch (ParserConfigurationException e) { - Activator.getDefault().logError("Error parsing filter xml file", e); //$NON-NLS-1$ - } - } - } - - private class ImportAction extends Action { - @Override - public void run() { - if (fViewer != null) { - ITmfFilterTreeNode root = null; - try { - FileDialog dlg = new FileDialog(new Shell(), SWT.OPEN); - dlg.setFilterNames(new String[] { Messages.FilterView_FileDialogFilterName + " (*.xml)" }); //$NON-NLS-1$ - dlg.setFilterExtensions(new String[] { "*.xml" }); //$NON-NLS-1$ - - TmfFilterXMLParser parserXML = null; - String fn = dlg.open(); - if (fn != null) { - parserXML = new TmfFilterXMLParser(fn); - root = parserXML.getTree(); - } - - } catch (SAXException e) { - Activator.getDefault().logError("Error importing filter xml file", e); //$NON-NLS-1$ - } catch (IOException e) { - Activator.getDefault().logError("Error importing filter xml file", e); //$NON-NLS-1$ - } - - if (root != null) { - for (ITmfFilterTreeNode node : root.getChildren()) { - if (node instanceof TmfFilterNode) { - fRoot.addChild(node); - refresh(); - fViewer.setSelection(node); - } - } - } - } - } - } - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterViewer.java deleted file mode 100644 index fa2456a58f..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterViewer.java +++ /dev/null @@ -1,1124 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Xavier Raynaud - add cut/copy/paste/dnd support - * Vincent Perot - Add subfield filtering - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.filter; - -import java.util.ArrayList; -import java.util.Map; -import java.util.Map.Entry; -import java.util.TreeMap; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.util.LocalSelectionTransfer; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventType; -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterAndNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterCompareNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterCompareNode.Type; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterContainsNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterEqualsNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterEventTypeNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterMatchesNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterOrNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterRootNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterTreeNode; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTraceDefinition; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTraceDefinition.OutputColumn; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtEvent; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTraceDefinition; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlEvent; -import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition; -import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.SashForm; -import org.eclipse.swt.dnd.DND; -import org.eclipse.swt.dnd.DragSource; -import org.eclipse.swt.dnd.DropTarget; -import org.eclipse.swt.dnd.Transfer; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.TreeItem; - -class FilterViewer extends Composite { - - private static final String SEP = " : "; //$NON-NLS-1$ - - private TreeViewer fViewer; - - private Composite fComposite; - private MenuManager fMenuManager; - - public FilterViewer(Composite parent, int style) { - super(parent, style); - - setLayout(new FillLayout()); - GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); - setLayoutData(gd); - - final SashForm sash = new SashForm(this, SWT.HORIZONTAL); - - // Create the tree viewer to display the filter tree - fViewer = new TreeViewer(sash, SWT.NONE); - fViewer.setContentProvider(new FilterTreeContentProvider()); - fViewer.setLabelProvider(new FilterTreeLabelProvider()); - fViewer.setInput(new TmfFilterRootNode()); - - // Create the empty filter node properties panel - fComposite = new Composite(sash, SWT.NONE); - GridLayout gl = new GridLayout(); - gl.marginHeight = 0; - gl.marginWidth = 0; - fComposite.setLayout(gl); - - createContextMenu(); - - fViewer.addSelectionChangedListener(new ISelectionChangedListener() { - @Override - public void selectionChanged(SelectionChangedEvent event) { - if (!(event.getSelection().isEmpty()) && event.getSelection() instanceof IStructuredSelection) { - // Update the filter node properties panel to the selection - IStructuredSelection selection = (IStructuredSelection) event.getSelection(); - ITmfFilterTreeNode node = (ITmfFilterTreeNode) selection.getFirstElement(); - updateFilterNodeComposite(node); - // Highlight the selection's children - highlightTreeItems(fViewer.getTree().getSelection()[0].getItems()); - } else { - updateFilterNodeComposite(null); - } - } - }); - - fViewer.getTree().addPaintListener(new PaintListener() { - @Override - public void paintControl(PaintEvent e) { - TmfFilterTreeNode root = (TmfFilterTreeNode) fViewer.getInput(); - if (root == null || root.getChildrenCount() == 0) { - e.gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); - e.gc.drawText(Messages.FilterViewer_EmptyTreeHintText, 5, 0); - } - } - }); - - int operations = DND.DROP_MOVE | DND.DROP_COPY; - DragSource dragSource = new org.eclipse.swt.dnd.DragSource(fViewer.getTree(), operations); - dragSource.setTransfer(new Transfer[] { LocalSelectionTransfer.getTransfer() }); - dragSource.addDragListener(new FilterDragSourceAdapter(this)); - DropTarget dropTarget = new DropTarget(fViewer.getTree(), operations); - dropTarget.setTransfer(new Transfer[] { LocalSelectionTransfer.getTransfer() }); - dropTarget.addDropListener(new FilterDropTargetAdapter(this)); - } - - /** - * Create the context menu for the tree viewer - */ - private void createContextMenu() { - // Adds root context menu - fMenuManager = new MenuManager(); - fMenuManager.setRemoveAllWhenShown(true); - fMenuManager.addMenuListener(new IMenuListener() { - @Override - public void menuAboutToShow(IMenuManager manager) { - fillContextMenu(manager); - } - }); - - // Context - Menu contextMenu = fMenuManager.createContextMenu(fViewer.getTree()); - - // Publish it - fViewer.getTree().setMenu(contextMenu); - } - - public MenuManager getMenuManager() { - return fMenuManager; - } - - /** - * Fill the context menu for the tree viewer. - * - * @param manager - * The menu manager - */ - protected void fillContextMenu(IMenuManager manager) { - final ISelection selection = fViewer.getSelection(); - ITmfFilterTreeNode filterTreeNode = null; - if (selection instanceof StructuredSelection) { - Object element = ((StructuredSelection) selection).getFirstElement(); - if (element instanceof ITmfFilterTreeNode) { - filterTreeNode = (ITmfFilterTreeNode) element; - } - } - - if (filterTreeNode != null) { - fillContextMenuForNode(filterTreeNode, manager); - } - manager.add(new Separator("delete")); //$NON-NLS-1$ - manager.add(new Separator("edit")); //$NON-NLS-1$ - - if (fViewer.getInput() instanceof TmfFilterRootNode || filterTreeNode == null) { - manager.add(new Separator()); - ITmfFilterTreeNode root = (ITmfFilterTreeNode) fViewer.getInput(); - fillContextMenuForNode(root, manager); - } - } - - /** - * Fill the context menu with the valid children of the provided node - * - * @param node - * The target node - * @param manager - * The menu manager - */ - protected void fillContextMenuForNode(final ITmfFilterTreeNode node, IMenuManager manager) { - for (final String child : node.getValidChildren()) { - final Action action = new Action() { - @Override - public void run() { - ITmfFilterTreeNode newNode = null; - if (TmfFilterNode.NODE_NAME.equals(child)) { - newNode = new TmfFilterNode(node, ""); //$NON-NLS-1$ - } else if (TmfFilterEventTypeNode.NODE_NAME.equals(child)) { - newNode = new TmfFilterEventTypeNode(node); - } else if (TmfFilterAndNode.NODE_NAME.equals(child)) { - newNode = new TmfFilterAndNode(node); - } else if (TmfFilterOrNode.NODE_NAME.equals(child)) { - newNode = new TmfFilterOrNode(node); - } else if (TmfFilterContainsNode.NODE_NAME.equals(child)) { - newNode = new TmfFilterContainsNode(node); - } else if (TmfFilterEqualsNode.NODE_NAME.equals(child)) { - newNode = new TmfFilterEqualsNode(node); - } else if (TmfFilterMatchesNode.NODE_NAME.equals(child)) { - newNode = new TmfFilterMatchesNode(node); - } else if (TmfFilterCompareNode.NODE_NAME.equals(child)) { - newNode = new TmfFilterCompareNode(node); - } - if (newNode != null) { - fViewer.refresh(); - fViewer.setSelection(new StructuredSelection(newNode), true); - } - } - }; - if (TmfFilterNode.NODE_NAME.equals(child)) { - action.setText(Messages.FilterViewer_NewPrefix + " " + child); //$NON-NLS-1$ - } else { - action.setText(child); - } - manager.add(action); - } - } - - /** - * Create the appropriate filter node properties composite - */ - private void updateFilterNodeComposite(ITmfFilterTreeNode node) { - for (Control control : fComposite.getChildren()) { - control.dispose(); - } - - if (node instanceof TmfFilterNode) { - new FilterNodeComposite(fComposite, (TmfFilterNode) node); - } else if (node instanceof TmfFilterEventTypeNode) { - new FilterEventTypeNodeComposite(fComposite, (TmfFilterEventTypeNode) node); - } else if (node instanceof TmfFilterAndNode) { - new FilterAndNodeComposite(fComposite, (TmfFilterAndNode) node); - } else if (node instanceof TmfFilterOrNode) { - new FilterOrNodeComposite(fComposite, (TmfFilterOrNode) node); - } else if (node instanceof TmfFilterContainsNode) { - new FilterContainsNodeComposite(fComposite, (TmfFilterContainsNode) node); - } else if (node instanceof TmfFilterEqualsNode) { - new FilterEqualsNodeComposite(fComposite, (TmfFilterEqualsNode) node); - } else if (node instanceof TmfFilterMatchesNode) { - new FilterMatchesNodeComposite(fComposite, (TmfFilterMatchesNode) node); - } else if (node instanceof TmfFilterCompareNode) { - new FilterCompareNodeComposite(fComposite, (TmfFilterCompareNode) node); - } else { - new FilterBaseNodeComposite(fComposite); - } - fComposite.layout(); - } - - /** - * Highlight the provided tree items - */ - private void highlightTreeItems(TreeItem[] items) { - resetTreeItems(fViewer.getTree().getItems()); - for (TreeItem item : items) { - item.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLUE)); - } - - } - - /** - * Reset the provided tree items (remove highlight) - */ - private void resetTreeItems(TreeItem[] items) { - for (TreeItem item : items) { - item.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); - resetTreeItems(item.getItems()); - } - } - - public void setInput(ITmfFilterTreeNode root) { - fViewer.setInput(root); - fViewer.expandAll(); - - updateFilterNodeComposite(null); - } - - public ITmfFilterTreeNode getInput() { - return (ITmfFilterTreeNode) fViewer.getInput(); - } - - public void refresh() { - fViewer.refresh(); - } - - public void setSelection(ITmfFilterTreeNode node, boolean reveal) { - fViewer.setSelection(new StructuredSelection(node), reveal); - } - - public void setSelection(ITmfFilterTreeNode node) { - fViewer.setSelection(new StructuredSelection(node)); - } - - public ITmfFilterTreeNode getSelection() { - final ISelection selection = fViewer.getSelection(); - ITmfFilterTreeNode filterTreeNode = null; - if (selection instanceof StructuredSelection) { - Object element = ((StructuredSelection) selection).getFirstElement(); - if (element instanceof ITmfFilterTreeNode) { - filterTreeNode = (ITmfFilterTreeNode) element; - } - } - - final ITmfFilterTreeNode selectedNode = filterTreeNode; - return selectedNode; - } - - public void addSelectionChangedListener(ISelectionChangedListener listener) { - fViewer.addSelectionChangedListener(listener); - } - - public void removeSelectionChangedListener(ISelectionChangedListener listener) { - fViewer.removeSelectionChangedListener(listener); - } - - /** - * Gets the TreeViewer displaying filters - * - * @return a {@link TreeViewer} - */ - TreeViewer getTreeViewer() { - return fViewer; - } - - private class FilterBaseNodeComposite extends Composite { - - FilterBaseNodeComposite(Composite parent) { - super(parent, SWT.NONE); - setLayout(new GridLayout(2, false)); - setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - } - - protected Map getEventsTypeMap() { - Map eventsTypeMap = new TreeMap<>(); - for (IConfigurationElement ce : TmfTraceType.getTypeElements()) { - String categoryPrefix = ""; //$NON-NLS-1$ - String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR); - if (categoryId != null) { - categoryPrefix = TmfTraceType.getCategoryName(categoryId) + SEP; - } - String text = categoryPrefix + ce.getAttribute(TmfTraceType.NAME_ATTR); - eventsTypeMap.put(text, ce); - } - for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) { - String text = def.categoryName + SEP + def.definitionName; - eventsTypeMap.put(text, def); - } - for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { - String text = def.categoryName + SEP + def.definitionName; - eventsTypeMap.put(text, def); - } - return eventsTypeMap; - } - - protected String[] getFieldsList(ITmfFilterTreeNode node) { - ArrayList fieldsList = new ArrayList<>(); - ITmfFilterTreeNode curNode = node; - while (curNode != null) { - if (curNode instanceof TmfFilterEventTypeNode) { - TmfFilterEventTypeNode eventTypeNode = (TmfFilterEventTypeNode) curNode; - for (IConfigurationElement ce : TmfTraceType.getTypeElements()) { - if (ce.getAttribute(TmfTraceType.EVENT_TYPE_ATTR).equals(eventTypeNode.getEventType())) { - try { - ITmfEvent event = (ITmfEvent) ce.createExecutableExtension(TmfTraceType.EVENT_TYPE_ATTR); - ITmfEventType eventType = event.getType(); - if (eventType != null) { - for (String field : eventType.getRootField().getFieldNames()) { - fieldsList.add(field); - } - } - } catch (CoreException e) { - } - if (fieldsList.size() == 0) { - fieldsList.add(ITmfEvent.EVENT_FIELD_TIMESTAMP); - fieldsList.add(ITmfEvent.EVENT_FIELD_SOURCE); - fieldsList.add(ITmfEvent.EVENT_FIELD_TYPE); - fieldsList.add(ITmfEvent.EVENT_FIELD_REFERENCE); - fieldsList.add(ITmfEvent.EVENT_FIELD_CONTENT); - } - return fieldsList.toArray(new String[0]); - } - } - if (eventTypeNode.getEventType() != null && eventTypeNode.getEventType().startsWith(CustomTxtEvent.class.getCanonicalName())) { - for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) { - if (eventTypeNode.getEventType().equals(CustomTxtEvent.class.getCanonicalName() + ':' + def.categoryName + ':' + def.definitionName)) { - for (OutputColumn output : def.outputs) { - fieldsList.add(output.name); - } - return fieldsList.toArray(new String[0]); - } - } - } - if (eventTypeNode.getEventType() != null && eventTypeNode.getEventType().startsWith(CustomXmlEvent.class.getCanonicalName())) { - for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { - if (eventTypeNode.getEventType().equals(CustomXmlEvent.class.getCanonicalName() + ':' + def.categoryName + ':' + def.definitionName)) { - for (OutputColumn output : def.outputs) { - fieldsList.add(output.name); - } - return fieldsList.toArray(new String[0]); - } - } - } - } - curNode = curNode.getParent(); - } - - fieldsList.add(Messages.FilterViewer_CommonCategory); - fieldsList.add(ITmfEvent.EVENT_FIELD_TIMESTAMP); - fieldsList.add(ITmfEvent.EVENT_FIELD_SOURCE); - fieldsList.add(ITmfEvent.EVENT_FIELD_TYPE); - fieldsList.add(ITmfEvent.EVENT_FIELD_REFERENCE); - fieldsList.add(ITmfEvent.EVENT_FIELD_CONTENT); - fieldsList.add(""); //$NON-NLS-1$ - - for (Entry eventTypeEntry : getEventsTypeMap().entrySet()) { - Object value = eventTypeEntry.getValue(); - if (value instanceof IConfigurationElement) { - IConfigurationElement ce = (IConfigurationElement) value; - try { - ITmfEvent event = (ITmfEvent) ce.createExecutableExtension(TmfTraceType.EVENT_TYPE_ATTR); - ITmfEventType eventType = event.getType(); - if (eventType != null && eventType.getFieldNames().size() > 0) { - String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR); - if (categoryId != null) { - fieldsList.add('[' + TmfTraceType.getCategoryName(categoryId) + SEP - + ce.getAttribute(TmfTraceType.NAME_ATTR) + ']'); - } else { - fieldsList.add('[' + ce.getAttribute(TmfTraceType.NAME_ATTR) + ']'); - } - for (String field : eventType.getFieldNames()) { - fieldsList.add(field); - } - fieldsList.add(""); //$NON-NLS-1$ - } - } catch (CoreException e) { - } - } else if (value instanceof CustomTraceDefinition) { - CustomTraceDefinition def = (CustomTraceDefinition) value; - if (def.outputs.size() > 0) { - fieldsList.add('[' + def.categoryName + SEP + def.definitionName + ']'); - for (OutputColumn output : def.outputs) { - fieldsList.add(output.name); - } - fieldsList.add(""); //$NON-NLS-1$ - } - } - } - return fieldsList.toArray(new String[0]); - } - } - - private class FilterNodeComposite extends FilterBaseNodeComposite { - TmfFilterNode fNode; - Text fNameText; - - FilterNodeComposite(Composite parent, TmfFilterNode node) { - super(parent); - fNode = node; - - Label label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - label.setText(Messages.FilterViewer_NameLabel); - - fNameText = new Text(this, SWT.BORDER); - fNameText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - if (node.getFilterName() != null && node.getFilterName().length() > 0) { - fNameText.setText(node.getFilterName()); - } else { - fNameText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); - fNameText.setText(Messages.FilterViewer_FilterNameHint); - } - fNameText.addFocusListener(new FocusListener() { - @Override - public void focusLost(FocusEvent e) { - if (fNode.getFilterName() == null || fNode.getFilterName().length() == 0) { - fNameText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); - fNameText.setText(Messages.FilterViewer_FilterNameHint); - } - } - - @Override - public void focusGained(FocusEvent e) { - if (fNameText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { - fNameText.setText(""); //$NON-NLS-1$ - } - fNameText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); - } - }); - fNameText.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - if (!fNameText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { - fNode.setFilterName(fNameText.getText()); - fViewer.refresh(fNode); - } - } - }); - } - } - - private class FilterEventTypeNodeComposite extends FilterBaseNodeComposite { - TmfFilterEventTypeNode fNode; - Combo fTypeCombo; - Map fEventsTypeMap; - - FilterEventTypeNodeComposite(Composite parent, TmfFilterEventTypeNode node) { - super(parent); - fNode = node; - fEventsTypeMap = getEventsTypeMap(); - - Label label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - label.setText(Messages.FilterViewer_TypeLabel); - - fTypeCombo = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY); - fTypeCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - fTypeCombo.setItems(fEventsTypeMap.keySet().toArray(new String[0])); - if (fNode.getEventType() != null) { - fTypeCombo.setText(fNode.getName()); - } - fTypeCombo.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - for (Entry eventTypeEntry : fEventsTypeMap.entrySet()) { - if (eventTypeEntry.getKey().equals(fTypeCombo.getText())) { - Object value = eventTypeEntry.getValue(); - if (value instanceof IConfigurationElement) { - IConfigurationElement ce = (IConfigurationElement) value; - fNode.setEventType(ce.getAttribute(TmfTraceType.EVENT_TYPE_ATTR)); - String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR); - if (categoryId != null) { - fNode.setName(TmfTraceType.getCategoryName(categoryId) + SEP - + ce.getAttribute(TmfTraceType.NAME_ATTR)); - } else { - fNode.setName(ce.getAttribute(TmfTraceType.NAME_ATTR)); - } - } else if (value instanceof CustomTxtTraceDefinition) { - CustomTxtTraceDefinition def = (CustomTxtTraceDefinition) value; - fNode.setEventType(CustomTxtEvent.class.getCanonicalName() + ':' + def.categoryName + ':' + def.definitionName); - fNode.setName(def.categoryName + SEP + def.definitionName); - } else if (value instanceof CustomXmlTraceDefinition) { - CustomXmlTraceDefinition def = (CustomXmlTraceDefinition) value; - fNode.setEventType(CustomXmlEvent.class.getCanonicalName() + ':' + def.categoryName + ':' + def.definitionName); - fNode.setName(def.categoryName + SEP + def.definitionName); - } - fViewer.refresh(fNode); - break; - } - } - } - }); - } - } - - private class FilterAndNodeComposite extends FilterBaseNodeComposite { - TmfFilterAndNode fNode; - Button fNotButton; - - FilterAndNodeComposite(Composite parent, TmfFilterAndNode node) { - super(parent); - fNode = node; - - Label label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - label.setText(Messages.FilterViewer_NotLabel); - - fNotButton = new Button(this, SWT.CHECK); - fNotButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - fNotButton.setSelection(fNode.isNot()); - fNotButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - fNode.setNot(fNotButton.getSelection()); - fViewer.refresh(fNode); - } - }); - } - } - - private class FilterOrNodeComposite extends FilterBaseNodeComposite { - TmfFilterOrNode fNode; - Button fNotButton; - - FilterOrNodeComposite(Composite parent, TmfFilterOrNode node) { - super(parent); - fNode = node; - - Label label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - label.setText(Messages.FilterViewer_NotLabel); - - fNotButton = new Button(this, SWT.CHECK); - fNotButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - fNotButton.setSelection(fNode.isNot()); - fNotButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - fNode.setNot(fNotButton.getSelection()); - fViewer.refresh(fNode); - } - }); - } - } - - private class FilterContainsNodeComposite extends FilterBaseNodeComposite { - TmfFilterContainsNode fNode; - Button fNotButton; - Combo fFieldCombo; - Text fValueText; - Button fIgnoreCaseButton; - - FilterContainsNodeComposite(Composite parent, TmfFilterContainsNode node) { - super(parent); - fNode = node; - - Label label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - label.setText(Messages.FilterViewer_NotLabel); - - fNotButton = new Button(this, SWT.CHECK); - fNotButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - fNotButton.setSelection(fNode.isNot()); - fNotButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - fNode.setNot(fNotButton.getSelection()); - fViewer.refresh(fNode); - } - }); - - label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - label.setText(Messages.FilterViewer_FieldLabel); - - fFieldCombo = new Combo(this, SWT.DROP_DOWN); - fFieldCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - fFieldCombo.setItems(getFieldsList(fNode)); - fFieldCombo.setToolTipText(Messages.FilterViewer_Subfilter_ToolTip); - if (fNode.getField() != null) { - fFieldCombo.setText(fNode.getField()); - } - fFieldCombo.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - fNode.setField(fFieldCombo.getText()); - fViewer.refresh(fNode); - } - }); - - label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - label.setText(Messages.FilterViewer_ValueLabel); - - fValueText = new Text(this, SWT.BORDER); - fValueText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - if (node.getValue() != null && node.getValue().length() > 0) { - fValueText.setText(node.getValue()); - } else { - fValueText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); - fValueText.setText(Messages.FilterViewer_ValueHint); - } - fValueText.addFocusListener(new FocusListener() { - @Override - public void focusLost(FocusEvent e) { - if (fNode.getValue() == null || fNode.getValue().length() == 0) { - fValueText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); - fValueText.setText(Messages.FilterViewer_ValueHint); - } - } - - @Override - public void focusGained(FocusEvent e) { - if (fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { - fValueText.setText(""); //$NON-NLS-1$ - } - fValueText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); - } - }); - fValueText.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - if (!fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { - fNode.setValue(fValueText.getText()); - fViewer.refresh(fNode); - } - } - }); - - label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - - fIgnoreCaseButton = new Button(this, SWT.CHECK); - fIgnoreCaseButton.setSelection(fNode.isIgnoreCase()); - fIgnoreCaseButton.setText(Messages.FilterViewer_IgnoreCaseButtonText); - fIgnoreCaseButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - fIgnoreCaseButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - fNode.setIgnoreCase(fIgnoreCaseButton.getSelection()); - fViewer.refresh(fNode); - } - }); - } - } - - private class FilterEqualsNodeComposite extends FilterBaseNodeComposite { - TmfFilterEqualsNode fNode; - Button fNotButton; - Combo fFieldCombo; - Text fValueText; - Button fIgnoreCaseButton; - - FilterEqualsNodeComposite(Composite parent, TmfFilterEqualsNode node) { - super(parent); - fNode = node; - - Label label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - label.setText(Messages.FilterViewer_NotLabel); - - fNotButton = new Button(this, SWT.CHECK); - fNotButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - fNotButton.setSelection(fNode.isNot()); - fNotButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - fNode.setNot(fNotButton.getSelection()); - fViewer.refresh(fNode); - } - }); - - label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - label.setText(Messages.FilterViewer_FieldLabel); - - fFieldCombo = new Combo(this, SWT.DROP_DOWN); - fFieldCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - fFieldCombo.setItems(getFieldsList(fNode)); - fFieldCombo.setToolTipText(Messages.FilterViewer_Subfilter_ToolTip); - if (fNode.getField() != null) { - fFieldCombo.setText(fNode.getField()); - } - fFieldCombo.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - fNode.setField(fFieldCombo.getText()); - fViewer.refresh(fNode); - } - }); - - label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - label.setText(Messages.FilterViewer_ValueLabel); - - fValueText = new Text(this, SWT.BORDER); - fValueText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - if (node.getValue() != null && node.getValue().length() > 0) { - fValueText.setText(node.getValue()); - } else { - fValueText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); - fValueText.setText(Messages.FilterViewer_ValueHint); - } - fValueText.addFocusListener(new FocusListener() { - @Override - public void focusLost(FocusEvent e) { - if (fNode.getValue() == null || fNode.getValue().length() == 0) { - fValueText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); - fValueText.setText(Messages.FilterViewer_ValueHint); - } - } - - @Override - public void focusGained(FocusEvent e) { - if (fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { - fValueText.setText(""); //$NON-NLS-1$ - } - fValueText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); - } - }); - fValueText.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - if (!fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { - fNode.setValue(fValueText.getText()); - fViewer.refresh(fNode); - } - } - }); - - label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - - fIgnoreCaseButton = new Button(this, SWT.CHECK); - fIgnoreCaseButton.setSelection(fNode.isIgnoreCase()); - fIgnoreCaseButton.setText(Messages.FilterViewer_IgnoreCaseButtonText); - fIgnoreCaseButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - fIgnoreCaseButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - fNode.setIgnoreCase(fIgnoreCaseButton.getSelection()); - fViewer.refresh(fNode); - } - }); - } - } - - private class FilterMatchesNodeComposite extends FilterBaseNodeComposite { - TmfFilterMatchesNode fNode; - Button fNotButton; - Combo fFieldCombo; - Text fRegexText; - - FilterMatchesNodeComposite(Composite parent, TmfFilterMatchesNode node) { - super(parent); - fNode = node; - - Label label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - label.setText(Messages.FilterViewer_NotLabel); - - fNotButton = new Button(this, SWT.CHECK); - fNotButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - fNotButton.setSelection(fNode.isNot()); - fNotButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - fNode.setNot(fNotButton.getSelection()); - fViewer.refresh(fNode); - } - }); - - label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - label.setText(Messages.FilterViewer_FieldLabel); - - fFieldCombo = new Combo(this, SWT.DROP_DOWN); - fFieldCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - fFieldCombo.setItems(getFieldsList(fNode)); - fFieldCombo.setToolTipText(Messages.FilterViewer_Subfilter_ToolTip); - if (fNode.getField() != null) { - fFieldCombo.setText(fNode.getField()); - } - fFieldCombo.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - fNode.setField(fFieldCombo.getText()); - fViewer.refresh(fNode); - } - }); - - label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - label.setText(Messages.FilterViewer_RegexLabel); - - fRegexText = new Text(this, SWT.BORDER); - fRegexText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - if (node.getRegex() != null && node.getRegex().length() > 0) { - fRegexText.setText(node.getRegex()); - } else { - fRegexText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); - fRegexText.setText(Messages.FilterViewer_RegexHint); - } - fRegexText.addFocusListener(new FocusListener() { - @Override - public void focusLost(FocusEvent e) { - if (fNode.getRegex() == null || fNode.getRegex().length() == 0) { - fRegexText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); - fRegexText.setText(Messages.FilterViewer_RegexHint); - } - } - - @Override - public void focusGained(FocusEvent e) { - if (fRegexText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { - fRegexText.setText(""); //$NON-NLS-1$ - } - fRegexText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); - } - }); - fRegexText.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - if (!fRegexText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { - fNode.setRegex(fRegexText.getText()); - fViewer.refresh(fNode); - } - } - }); - } - } - - private class FilterCompareNodeComposite extends FilterBaseNodeComposite { - TmfFilterCompareNode fNode; - Button fNotButton; - Combo fFieldCombo; - Text fValueText; - Button fLTButton; - Button fEQButton; - Button fGTButton; - Button fNumButton; - Button fAlphaButton; - Button fTimestampButton; - - FilterCompareNodeComposite(Composite parent, TmfFilterCompareNode node) { - super(parent); - fNode = node; - - Label label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - label.setText(Messages.FilterViewer_NotLabel); - - fNotButton = new Button(this, SWT.CHECK); - fNotButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - fNotButton.setSelection(fNode.isNot()); - fNotButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - fNode.setNot(fNotButton.getSelection()); - fViewer.refresh(fNode); - } - }); - - label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - label.setText(Messages.FilterViewer_FieldLabel); - - fFieldCombo = new Combo(this, SWT.DROP_DOWN); - fFieldCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - fFieldCombo.setItems(getFieldsList(fNode)); - fFieldCombo.setToolTipText(Messages.FilterViewer_Subfilter_ToolTip); - if (fNode.getField() != null) { - fFieldCombo.setText(fNode.getField()); - } - fFieldCombo.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - fNode.setField(fFieldCombo.getText()); - fViewer.refresh(fNode); - } - }); - - label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - label.setText(Messages.FilterViewer_ResultLabel); - - Composite resultGroup = new Composite(this, SWT.NONE); - GridLayout rggl = new GridLayout(3, true); - rggl.marginHeight = 0; - rggl.marginWidth = 0; - resultGroup.setLayout(rggl); - resultGroup.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - - fLTButton = new Button(resultGroup, SWT.RADIO); - fLTButton.setSelection(fNode.getResult() < 0); - fLTButton.setText("<"); //$NON-NLS-1$ - fLTButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - fLTButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (fLTButton.getSelection()) { - fNode.setResult(-1); - } - fViewer.refresh(fNode); - } - }); - - fEQButton = new Button(resultGroup, SWT.RADIO); - fEQButton.setSelection(fNode.getResult() == 0); - fEQButton.setText("="); //$NON-NLS-1$ - fEQButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - fEQButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (fEQButton.getSelection()) { - fNode.setResult(0); - } - fViewer.refresh(fNode); - } - }); - - fGTButton = new Button(resultGroup, SWT.RADIO); - fGTButton.setSelection(fNode.getResult() > 0); - fGTButton.setText(">"); //$NON-NLS-1$ - fGTButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - fGTButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (fGTButton.getSelection()) { - fNode.setResult(1); - } - fViewer.refresh(fNode); - } - }); - - label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - label.setText(Messages.FilterViewer_TypeLabel); - - Composite typeGroup = new Composite(this, SWT.NONE); - GridLayout tggl = new GridLayout(3, false); - tggl.marginHeight = 0; - tggl.marginWidth = 0; - typeGroup.setLayout(tggl); - typeGroup.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - - fNumButton = new Button(typeGroup, SWT.RADIO); - fNumButton.setSelection(fNode.getType() == Type.NUM); - fNumButton.setText(Messages.FilterViewer_NumButtonText); - fNumButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - fNumButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (fNumButton.getSelection()) { - fNode.setType(Type.NUM); - } - fViewer.refresh(fNode); - } - }); - - fAlphaButton = new Button(typeGroup, SWT.RADIO); - fAlphaButton.setSelection(fNode.getType() == Type.ALPHA); - fAlphaButton.setText(Messages.FilterViewer_AlphaButtonText); - fAlphaButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - fAlphaButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (fAlphaButton.getSelection()) { - fNode.setType(Type.ALPHA); - } - fViewer.refresh(fNode); - } - }); - - fTimestampButton = new Button(typeGroup, SWT.RADIO); - fTimestampButton.setSelection(fNode.getType() == Type.TIMESTAMP); - fTimestampButton.setText(Messages.FilterViewer_TimestampButtonText); - fTimestampButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - fTimestampButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (fTimestampButton.getSelection()) { - fNode.setType(Type.TIMESTAMP); - } - fViewer.refresh(fNode); - } - }); - - label = new Label(this, SWT.NONE); - label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - label.setText(Messages.FilterViewer_ValueLabel); - - fValueText = new Text(this, SWT.BORDER); - fValueText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - if (node.getValue() != null && node.getValue().length() > 0) { - fValueText.setText(node.getValue()); - } else { - fValueText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); - fValueText.setText(Messages.FilterViewer_ValueHint); - } - fValueText.addFocusListener(new FocusListener() { - @Override - public void focusLost(FocusEvent e) { - if (fNode.getValue() == null || fNode.getValue().length() == 0) { - fValueText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); - fValueText.setText(Messages.FilterViewer_ValueHint); - } - } - - @Override - public void focusGained(FocusEvent e) { - if (fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { - fValueText.setText(""); //$NON-NLS-1$ - } - fValueText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); - } - }); - fValueText.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - if (!fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { - fNode.setValue(fValueText.getText()); - fViewer.refresh(fNode); - } - } - }); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/PasteHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/PasteHandler.java deleted file mode 100644 index 84a224f5c6..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/PasteHandler.java +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Kalray - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xavier Raynaud - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.filter; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; -import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterNode; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -/** - * Handler for paste command in filter view - * @author Xavier Raynaud - * @since 3.0 - */ -public class PasteHandler extends AbstractHandler { - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return null; - } - - // Get the selection - IWorkbenchPage page = window.getActivePage(); - IWorkbenchPart part = page.getActivePart(); - if (!(part instanceof FilterView)) { - return null; - } - FilterView v = (FilterView) part; - - ITmfFilterTreeNode objectToPaste = FilterEditUtils.getTransferredTreeNode(); - objectToPaste = objectToPaste.clone(); - ITmfFilterTreeNode sel = v.getSelection(); - if (sel == null || TmfFilterNode.NODE_NAME.equals(objectToPaste.getNodeName())) { - sel = v.getFilterRoot(); - } - - sel.addChild(objectToPaste); - v.refresh(); - v.setSelection(objectToPaste); - return null; - } - - @Override - public boolean isEnabled() { - // Check if we are closing down - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - return false; - } - - // Get the selection - IWorkbenchPage page = window.getActivePage(); - IWorkbenchPart part = page.getActivePart(); - if (!(part instanceof FilterView)) { - return false; - } - FilterView v = (FilterView) part; - ITmfFilterTreeNode sel = v.getSelection(); - if (sel == null) { - sel = v.getFilterRoot(); - } - ITmfFilterTreeNode objectToPaste = FilterEditUtils.getTransferredTreeNode(); - if (objectToPaste != null && - (sel.getValidChildren().contains(objectToPaste.getNodeName()) - || TmfFilterNode.NODE_NAME.equals(objectToPaste.getNodeName()))) { - return true; - } - return false; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/FullTraceHistogram.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/FullTraceHistogram.java deleted file mode 100644 index 1fa533bc8c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/FullTraceHistogram.java +++ /dev/null @@ -1,224 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Changed to updated histogram data model - * Patrick Tasse - Update for mouse wheel zoom - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.histogram; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; - -/** - * A histogram widget that displays the event distribution of a whole trace. - *

- * It also features a selected range window that can be dragged and zoomed. - * - * @version 1.1 - * @author Francois Chouinard - */ -public class FullTraceHistogram extends Histogram { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final HistogramZoom fZoom; - - private long fRangeStartTime = 0L; - private long fRangeDuration; - - // ------------------------------------------------------------------------ - // Construction - // ------------------------------------------------------------------------ - - /** - * Full Constructor - * - * @param view A reference to the parent histogram view - * @param parent A reference to the parent composite - */ - public FullTraceHistogram(HistogramView view, Composite parent) { - super(view, parent); - fZoom = new HistogramZoom(this, getStartTime(), getTimeLimit()); - } - - @Override - public void dispose() { - super.dispose(); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Override - public void clear() { - fRangeStartTime = 0L; - fRangeDuration = 0L; - if (fZoom != null) { - fZoom.setFullRange(0L, 0L); - fZoom.setNewRange(0L, 0L); - } - super.clear(); - } - - /** - * Sets the time range of the full histogram. - * - * @param startTime A start time - * @param endTime A end time - */ - public void setFullRange(long startTime, long endTime) { - fZoom.setFullRange(startTime, endTime); - fZoom.setNewRange(fRangeStartTime, fRangeDuration); - } - - /** - * Sets the selected time range. - * - * @param startTime The histogram start time - * @param duration The histogram duration - */ - public void setTimeRange(long startTime, long duration) { - fRangeStartTime = startTime; - fRangeDuration = duration; - fZoom.setNewRange(fRangeStartTime, fRangeDuration); - fDataModel.complete(); - } - - // ------------------------------------------------------------------------ - // MouseListener - // ------------------------------------------------------------------------ - - private int fStartDelta; - private boolean fMouseMoved; - - @Override - public void mouseDown(MouseEvent event) { - if (fScaledData != null && fDragState == DRAG_NONE && fDataModel.getStartTime() < fDataModel.getEndTime()) { - if (event.button == 2 || (event.button == 1 && (event.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL)) { - fDragState = DRAG_RANGE; - fDragButton = event.button; - int center = (int) (((fRangeStartTime + fRangeDuration / 2) - fScaledData.fFirstBucketTime) / fScaledData.fBucketDuration); - fStartDelta = center - event.x; - fMouseMoved = false; - return; - } else if (event.button == 3) { - fDragState = DRAG_ZOOM; - fDragButton = event.button; - long time = Math.min(getTimestamp(event.x), getEndTime()); - if ((event.stateMask & SWT.MODIFIER_MASK) == SWT.SHIFT) { - if (time < fRangeStartTime + fRangeDuration / 2) { - fRangeStartTime = fRangeStartTime + fRangeDuration; - } - } else { - fRangeStartTime = time; - } - fRangeDuration = time - fRangeStartTime; - fCanvas.redraw(); - return; - } - } - super.mouseDown(event); - } - - @Override - public void mouseUp(MouseEvent event) { - if (fDragState == DRAG_RANGE && event.button == fDragButton) { - fDragState = DRAG_NONE; - fDragButton = 0; - if (!fMouseMoved) { - // if single click without move, center on the click - long startTime = getTimestamp(event.x) - fRangeDuration / 2; - fRangeStartTime = Math.max(getStartTime(), Math.min(getEndTime() - fRangeDuration, startTime)); - } - ((HistogramView) fParentView).updateTimeRange(fRangeStartTime, fRangeStartTime + fRangeDuration); - return; - } else if (fDragState == DRAG_ZOOM && event.button == fDragButton) { - fDragState = DRAG_NONE; - fDragButton = 0; - if (fRangeDuration < 0) { - fRangeStartTime = fRangeStartTime + fRangeDuration; - fRangeDuration = -fRangeDuration; - } - if (fRangeDuration > 0) { - ((HistogramView) fParentView).updateTimeRange(fRangeStartTime, fRangeStartTime + fRangeDuration); - } else { - fRangeStartTime = fZoom.getStartTime(); - fRangeDuration = fZoom.getDuration(); - fCanvas.redraw(); - } - return; - } - super.mouseUp(event); - } - - // ------------------------------------------------------------------------ - // MouseMoveListener - // ------------------------------------------------------------------------ - - @Override - public void mouseMove(MouseEvent event) { - if (fDragState == DRAG_RANGE) { - int center = event.x + fStartDelta; - long newStart = getTimestamp(center) - fRangeDuration / 2; - fRangeStartTime = Math.max(getStartTime(), Math.min(getEndTime() - fRangeDuration, newStart)); - fCanvas.redraw(); - fMouseMoved = true; - return; - } else if (fDragState == DRAG_ZOOM) { - long endTime = Math.max(getStartTime(), Math.min(getEndTime(), getTimestamp(event.x))); - fRangeDuration = endTime - fRangeStartTime; - fCanvas.redraw(); - return; - } - super.mouseMove(event); - } - - // ------------------------------------------------------------------------ - // PaintListener - // ------------------------------------------------------------------------ - - @Override - public void paintControl(PaintEvent event) { - super.paintControl(event); - - Image image = (Image) fCanvas.getData(IMAGE_KEY); - assert image != null; - - Image rangeRectangleImage = new Image(image.getDevice(), image, SWT.IMAGE_COPY); - GC rangeWindowGC = new GC(rangeRectangleImage); - - if ((fScaledData != null) && (fRangeDuration != 0 || fDragState == DRAG_ZOOM)) { - drawTimeRangeWindow(rangeWindowGC, fRangeStartTime, fRangeDuration); - } - - // Draws the buffer image onto the canvas. - event.gc.drawImage(rangeRectangleImage, 0, 0); - - rangeWindowGC.dispose(); - rangeRectangleImage.dispose(); - } - - /** - * Get the histogram zoom - * @return the histogram zoom - * @since 2.0 - */ - public HistogramZoom getZoom() { - return fZoom; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/Histogram.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/Histogram.java deleted file mode 100644 index de0f720aeb..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/Histogram.java +++ /dev/null @@ -1,1045 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Changed to updated histogram data model - * Francois Chouinard - Reformat histogram labels on format change - * Patrick Tasse - Support selection range - * Xavier Raynaud - Support multi-trace coloring - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.histogram; - -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimestampFormatUpdateSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampDelta; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampFormat; -import org.eclipse.linuxtools.tmf.ui.views.TmfView; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.ControlListener; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.events.MouseTrackListener; -import org.eclipse.swt.events.MouseWheelListener; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; - -/** - * Re-usable histogram widget. - * - * It has the following features: - *

    - *
  • Y-axis labels displaying min/max count values - *
  • X-axis labels displaying time range - *
  • a histogram displaying the distribution of values over time (note that - * the histogram might not necessarily fill the whole canvas) - *
- * The widget also has 2 'markers' to identify: - *
    - *
  • a red dashed line over the bar that contains the currently selected event - *
  • a dark red dashed line that delimits the right end of the histogram (if - * it doesn't fill the canvas) - *
- * Clicking on the histogram will select the current event at the mouse - * location. - *

- * Once the histogram is selected, there is some limited keyboard support: - *

    - *
  • Home: go to the first histogram bar - *
  • End: go to the last histogram bar - *
  • Left: go to the previous histogram - *
  • Right: go to the next histogram bar - *
- * Finally, when the mouse hovers over the histogram, a tool tip showing the - * following information about the corresponding histogram bar time range: - *
    - *
  • start of the time range - *
  • end of the time range - *
  • number of events in that time range - *
- * - * @version 1.1 - * @author Francois Chouinard - */ -public abstract class Histogram implements ControlListener, PaintListener, KeyListener, MouseListener, MouseMoveListener, MouseTrackListener, IHistogramModelListener { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - // Histogram colors - - // System colors, they do not need to be disposed - private final Color fBackgroundColor = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE); - private final Color fSelectionForegroundColor = Display.getCurrent().getSystemColor(SWT.COLOR_BLUE); - private final Color fSelectionBackgroundColor = Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); - private final Color fLastEventColor = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_RED); - - // Application colors, they need to be disposed - private final Color[] fHistoBarColors = new Color[] {new Color(Display.getDefault(), 90, 90, 255), // blue - new Color(Display.getDefault(), 0, 240, 0), // green - new Color(Display.getDefault(), 255, 0, 0), // red - new Color(Display.getDefault(), 0, 255, 255), // cyan - new Color(Display.getDefault(), 255, 80, 255), // magenta - new Color(Display.getDefault(), 200, 200, 0), // yellow - new Color(Display.getDefault(), 200, 150, 0), // brown - new Color(Display.getDefault(), 150, 255, 150), // light green - new Color(Display.getDefault(), 200, 80, 80), // dark red - new Color(Display.getDefault(), 30, 150, 150), // dark cyan - new Color(Display.getDefault(), 200, 200, 255), // light blue - new Color(Display.getDefault(), 0, 120, 0), // dark green - new Color(Display.getDefault(), 255, 150, 150), // lighter red - new Color(Display.getDefault(), 140, 80, 140), // dark magenta - new Color(Display.getDefault(), 150, 100, 50), // brown - new Color(Display.getDefault(), 255, 80, 80), // light red - new Color(Display.getDefault(), 200, 200, 200), // light grey - new Color(Display.getDefault(), 255, 200, 80), // orange - new Color(Display.getDefault(), 255, 255, 80), // pale yellow - new Color(Display.getDefault(), 255, 200, 200), // pale red - new Color(Display.getDefault(), 255, 200, 255), // pale magenta - new Color(Display.getDefault(), 255, 255, 200), // pale pale yellow - new Color(Display.getDefault(), 200, 255, 255), // pale pale blue - }; - private final Color fTimeRangeColor = new Color(Display.getCurrent(), 255, 128, 0); - private final Color fLostEventColor = new Color(Display.getCurrent(), 208, 62, 120); - - // Drag states - /** - * No drag in progress - * @since 2.2 - */ - protected final int DRAG_NONE = 0; - /** - * Drag the selection - * @since 2.2 - */ - protected final int DRAG_SELECTION = 1; - /** - * Drag the time range - * @since 2.2 - */ - protected final int DRAG_RANGE = 2; - /** - * Drag the zoom range - * @since 2.2 - */ - protected final int DRAG_ZOOM = 3; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The parent TMF view. - */ - protected TmfView fParentView; - - private Composite fComposite; - private Font fFont; - - // Histogram text fields - private Label fMaxNbEventsLabel; - private Label fMinNbEventsLabel; - private Label fTimeRangeStartLabel; - private Label fTimeRangeEndLabel; - - /** - * Histogram drawing area - */ - protected Canvas fCanvas; - - /** - * The histogram data model. - */ - protected final HistogramDataModel fDataModel; - - /** - * The histogram data model scaled to current resolution and screen width. - */ - protected HistogramScaledData fScaledData; - - /** - * The current event value - */ - protected long fCurrentEventTime = 0L; - - /** - * The current selection begin time - */ - private long fSelectionBegin = 0L; - - /** - * The current selection end time - */ - private long fSelectionEnd = 0L; - - /** - * The drag state - * @see #DRAG_NONE - * @see #DRAG_SELECTION - * @see #DRAG_RANGE - * @see #DRAG_ZOOM - * @since 2.2 - */ - protected int fDragState = DRAG_NONE; - - /** - * The button that started a mouse drag, or 0 if no drag in progress - * @since 2.2 - */ - protected int fDragButton = 0; - - /** - * The bucket display offset - */ - private int fOffset = 0; - - /** - * show the traces or not - * @since 3.0 - */ - static boolean showTraces = true; - - // ------------------------------------------------------------------------ - // Construction - // ------------------------------------------------------------------------ - - /** - * Full constructor. - * - * @param view A reference to the parent TMF view. - * @param parent A parent composite - */ - public Histogram(final TmfView view, final Composite parent) { - fParentView = view; - - fComposite = createWidget(parent); - fDataModel = new HistogramDataModel(); - fDataModel.addHistogramListener(this); - clear(); - - fCanvas.addControlListener(this); - fCanvas.addPaintListener(this); - fCanvas.addKeyListener(this); - fCanvas.addMouseListener(this); - fCanvas.addMouseTrackListener(this); - fCanvas.addMouseMoveListener(this); - - TmfSignalManager.register(this); - } - - /** - * Dispose resources and unregisters listeners. - */ - public void dispose() { - TmfSignalManager.deregister(this); - fLostEventColor.dispose(); - for (Color c : fHistoBarColors) { - c.dispose(); - } - fTimeRangeColor.dispose(); - fFont.dispose(); - fDataModel.removeHistogramListener(this); - fDataModel.dispose(); - } - - private Composite createWidget(final Composite parent) { - - fFont = adjustFont(parent); - - final int initalWidth = 10; - - // -------------------------------------------------------------------- - // Define the histogram - // -------------------------------------------------------------------- - - final GridLayout gridLayout = new GridLayout(); - gridLayout.numColumns = 3; - gridLayout.marginHeight = 0; - gridLayout.marginWidth = 0; - gridLayout.marginTop = 0; - gridLayout.horizontalSpacing = 0; - gridLayout.verticalSpacing = 0; - gridLayout.marginLeft = 0; - gridLayout.marginRight = 0; - final Composite composite = new Composite(parent, SWT.FILL); - composite.setLayout(gridLayout); - - // Use all the horizontal space - GridData gridData = new GridData(); - gridData.horizontalAlignment = SWT.FILL; - gridData.verticalAlignment = SWT.FILL; - gridData.grabExcessHorizontalSpace = true; - gridData.grabExcessVerticalSpace = true; - composite.setLayoutData(gridData); - - // Y-axis max event - gridData = new GridData(); - gridData.horizontalAlignment = SWT.RIGHT; - gridData.verticalAlignment = SWT.TOP; - fMaxNbEventsLabel = new Label(composite, SWT.RIGHT); - fMaxNbEventsLabel.setFont(fFont); - fMaxNbEventsLabel.setText("0"); //$NON-NLS-1$ - fMaxNbEventsLabel.setLayoutData(gridData); - - // Histogram itself - Composite canvasComposite = new Composite(composite, SWT.BORDER); - gridData = new GridData(); - gridData.horizontalSpan = 2; - gridData.verticalSpan = 2; - gridData.horizontalAlignment = SWT.FILL; - gridData.verticalAlignment = SWT.FILL; - gridData.heightHint = 0; - gridData.widthHint = 0; - gridData.grabExcessHorizontalSpace = true; - gridData.grabExcessVerticalSpace = true; - canvasComposite.setLayoutData(gridData); - canvasComposite.setLayout(new FillLayout()); - fCanvas = new Canvas(canvasComposite, SWT.DOUBLE_BUFFERED); - fCanvas.addDisposeListener(new DisposeListener() { - @Override - public void widgetDisposed(DisposeEvent e) { - Object image = fCanvas.getData(IMAGE_KEY); - if (image instanceof Image) { - ((Image) image).dispose(); - } - } - }); - - // Y-axis min event (always 0...) - gridData = new GridData(); - gridData.horizontalAlignment = SWT.RIGHT; - gridData.verticalAlignment = SWT.BOTTOM; - fMinNbEventsLabel = new Label(composite, SWT.RIGHT); - fMinNbEventsLabel.setFont(fFont); - fMinNbEventsLabel.setText("0"); //$NON-NLS-1$ - fMinNbEventsLabel.setLayoutData(gridData); - - // Dummy cell - gridData = new GridData(initalWidth, SWT.DEFAULT); - gridData.horizontalAlignment = SWT.RIGHT; - gridData.verticalAlignment = SWT.BOTTOM; - final Label dummyLabel = new Label(composite, SWT.NONE); - dummyLabel.setLayoutData(gridData); - - // Window range start time - gridData = new GridData(); - gridData.horizontalAlignment = SWT.LEFT; - gridData.verticalAlignment = SWT.BOTTOM; - fTimeRangeStartLabel = new Label(composite, SWT.NONE); - fTimeRangeStartLabel.setFont(fFont); - fTimeRangeStartLabel.setLayoutData(gridData); - - // Window range end time - gridData = new GridData(); - gridData.horizontalAlignment = SWT.RIGHT; - gridData.verticalAlignment = SWT.BOTTOM; - fTimeRangeEndLabel = new Label(composite, SWT.NONE); - fTimeRangeEndLabel.setFont(fFont); - fTimeRangeEndLabel.setLayoutData(gridData); - - return composite; - } - - private static Font adjustFont(final Composite composite) { - // Reduce font size for a more pleasing rendering - final int fontSizeAdjustment = -2; - final Font font = composite.getFont(); - final FontData fontData = font.getFontData()[0]; - return new Font(font.getDevice(), fontData.getName(), fontData.getHeight() + fontSizeAdjustment, fontData.getStyle()); - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Returns the start time (equal first bucket time) - * @return the start time. - */ - public long getStartTime() { - return fDataModel.getFirstBucketTime(); - } - - /** - * Returns the end time. - * @return the end time. - */ - public long getEndTime() { - return fDataModel.getEndTime(); - } - - /** - * Returns the time limit (end of last bucket) - * @return the time limit. - */ - public long getTimeLimit() { - return fDataModel.getTimeLimit(); - } - - /** - * Returns a data model reference. - * @return data model. - */ - public HistogramDataModel getDataModel() { - return fDataModel; - } - - /** - * Set the max number events to be displayed - * - * @param maxNbEvents - * the maximum number of events - */ - void setMaxNbEvents(long maxNbEvents) { - fMaxNbEventsLabel.setText(Long.toString(maxNbEvents)); - fMaxNbEventsLabel.getParent().layout(); - fCanvas.redraw(); - } - - /** - * Return true if the traces must be displayed in the histogram, - * false otherwise. - * @return whether the traces should be displayed - * @since 3.0 - */ - public boolean showTraces() { - return showTraces && fDataModel.getNbTraces() < getMaxNbTraces(); - } - - /** - * Returns the maximum number of traces the histogram can display with separate colors. - * If there is more traces, histogram will use only one color to display them. - * @return the maximum number of traces the histogram can display. - * @since 3.0 - */ - public int getMaxNbTraces() { - return fHistoBarColors.length; - } - - /** - * Returns the color used to display the trace at the given index. - * @param traceIndex a trace index - * @return a {@link Color} - * @since 3.0 - */ - public Color getTraceColor(int traceIndex) { - return fHistoBarColors[traceIndex % fHistoBarColors.length]; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - /** - * Updates the time range. - * @param startTime A start time - * @param endTime A end time. - */ - public void updateTimeRange(long startTime, long endTime) { - if (fDragState == DRAG_NONE) { - ((HistogramView) fParentView).updateTimeRange(startTime, endTime); - } - } - - /** - * Clear the histogram and reset the data - */ - public void clear() { - fDataModel.clear(); - if (fDragState == DRAG_SELECTION) { - updateSelectionTime(); - } - fDragState = DRAG_NONE; - fDragButton = 0; - synchronized (fDataModel) { - fScaledData = null; - } - } - - /** - * Sets the current selection time range and refresh the display - * - * @param beginTime The begin time of the current selection - * @param endTime The end time of the current selection - * @since 2.1 - */ - public void setSelection(final long beginTime, final long endTime) { - fSelectionBegin = (beginTime > 0) ? beginTime : 0; - fSelectionEnd = (endTime > 0) ? endTime : 0; - fDataModel.setSelectionNotifyListeners(beginTime, endTime); - } - - /** - * Computes the timestamp of the bucket at [offset] - * - * @param offset offset from the left on the histogram - * @return the start timestamp of the corresponding bucket - */ - public synchronized long getTimestamp(final int offset) { - assert offset > 0 && offset < fScaledData.fWidth; - try { - return fScaledData.fFirstBucketTime + fScaledData.fBucketDuration * offset; - } catch (final Exception e) { - return 0; // TODO: Fix that racing condition (NPE) - } - } - - /** - * Computes the offset of the timestamp in the histogram - * - * @param timestamp the timestamp - * @return the offset of the corresponding bucket (-1 if invalid) - */ - public synchronized int getOffset(final long timestamp) { - if (timestamp < fDataModel.getFirstBucketTime() || timestamp > fDataModel.getEndTime()) { - return -1; - } - return (int) ((timestamp - fDataModel.getFirstBucketTime()) / fScaledData.fBucketDuration); - } - - /** - * Set the bucket display offset - * - * @param offset - * the bucket display offset - * @since 2.2 - */ - protected void setOffset(final int offset) { - fOffset = offset; - } - - /** - * Move the currently selected bar cursor to a non-empty bucket. - * - * @param keyCode the SWT key code - */ - protected void moveCursor(final int keyCode) { - - int index; - switch (keyCode) { - - case SWT.HOME: - index = 0; - while (index < fScaledData.fLastBucket && fScaledData.fData[index].isEmpty()) { - index++; - } - if (index < fScaledData.fLastBucket) { - fScaledData.fSelectionBeginBucket = index; - } - break; - - case SWT.ARROW_RIGHT: - index = Math.max(0, fScaledData.fSelectionBeginBucket + 1); - while (index < fScaledData.fWidth && fScaledData.fData[index].isEmpty()) { - index++; - } - if (index < fScaledData.fLastBucket) { - fScaledData.fSelectionBeginBucket = index; - } - break; - - case SWT.END: - index = fScaledData.fLastBucket; - while (index >= 0 && fScaledData.fData[index].isEmpty()) { - index--; - } - if (index >= 0) { - fScaledData.fSelectionBeginBucket = index; - } - break; - - case SWT.ARROW_LEFT: - index = Math.min(fScaledData.fLastBucket - 1, fScaledData.fSelectionBeginBucket - 1); - while (index >= 0 && fScaledData.fData[index].isEmpty()) { - index--; - } - if (index >= 0) { - fScaledData.fSelectionBeginBucket = index; - } - break; - - default: - return; - } - - fScaledData.fSelectionEndBucket = fScaledData.fSelectionBeginBucket; - fSelectionBegin = getTimestamp(fScaledData.fSelectionBeginBucket); - fSelectionEnd = fSelectionBegin; - updateSelectionTime(); - } - - /** - * Refresh the histogram display - */ - @Override - public void modelUpdated() { - if (!fCanvas.isDisposed() && fCanvas.getDisplay() != null) { - fCanvas.getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - if (!fCanvas.isDisposed()) { - // Retrieve and normalize the data - final int canvasWidth = fCanvas.getBounds().width; - final int canvasHeight = fCanvas.getBounds().height; - if (canvasWidth <= 0 || canvasHeight <= 0) { - return; - } - fDataModel.setSelection(fSelectionBegin, fSelectionEnd); - fScaledData = fDataModel.scaleTo(canvasWidth, canvasHeight, 1); - synchronized (fDataModel) { - if (fScaledData != null) { - fCanvas.redraw(); - // Display histogram and update X-,Y-axis labels - updateRangeTextControls(); - long maxNbEvents = HistogramScaledData.hideLostEvents ? fScaledData.fMaxValue : fScaledData.fMaxCombinedValue; - fMaxNbEventsLabel.setText(Long.toString(maxNbEvents)); - // The Y-axis area might need to be re-sized - GridData gd = (GridData) fMaxNbEventsLabel.getLayoutData(); - gd.widthHint = Math.max(gd.widthHint, fMaxNbEventsLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).x); - fMaxNbEventsLabel.getParent().layout(); - } - } - } - } - }); - } - } - - /** - * Add a mouse wheel listener to the histogram - * @param listener the mouse wheel listener - * @since 2.0 - */ - public void addMouseWheelListener(MouseWheelListener listener) { - fCanvas.addMouseWheelListener(listener); - } - - /** - * Remove a mouse wheel listener from the histogram - * @param listener the mouse wheel listener - * @since 2.0 - */ - public void removeMouseWheelListener(MouseWheelListener listener) { - fCanvas.removeMouseWheelListener(listener); - } - - /** - * Add a key listener to the histogram - * @param listener the key listener - * @since 3.1 - */ - public void addKeyListener(KeyListener listener) { - fCanvas.addKeyListener(listener); - } - - /** - * Remove a key listener from the histogram - * @param listener the key listener - * @since 3.1 - */ - public void removeKeyListener(KeyListener listener) { - fCanvas.removeKeyListener(listener); - } - - // ------------------------------------------------------------------------ - // Helper functions - // ------------------------------------------------------------------------ - - private void updateSelectionTime() { - if (fSelectionBegin > fSelectionEnd) { - long end = fSelectionBegin; - fSelectionBegin = fSelectionEnd; - fSelectionEnd = end; - } - ((HistogramView) fParentView).updateSelectionTime(fSelectionBegin, fSelectionEnd); - } - - /** - * Update the range text controls - */ - private void updateRangeTextControls() { - if (fDataModel.getStartTime() < fDataModel.getEndTime()) { - fTimeRangeStartLabel.setText(TmfTimestampFormat.getDefaulTimeFormat().format(fDataModel.getStartTime())); - fTimeRangeEndLabel.setText(TmfTimestampFormat.getDefaulTimeFormat().format(fDataModel.getEndTime())); - } else { - fTimeRangeStartLabel.setText(""); //$NON-NLS-1$ - fTimeRangeEndLabel.setText(""); //$NON-NLS-1$ - } - } - - // ------------------------------------------------------------------------ - // PaintListener - // ------------------------------------------------------------------------ - /** - * Image key string for the canvas. - */ - protected final String IMAGE_KEY = "double-buffer-image"; //$NON-NLS-1$ - - @Override - public void paintControl(final PaintEvent event) { - - // Get the geometry - final int canvasWidth = fCanvas.getBounds().width; - final int canvasHeight = fCanvas.getBounds().height; - - // Make sure we have something to draw upon - if (canvasWidth <= 0 || canvasHeight <= 0) { - return; - } - - // Retrieve image; re-create only if necessary - Image image = (Image) fCanvas.getData(IMAGE_KEY); - if (image == null || image.getBounds().width != canvasWidth || image.getBounds().height != canvasHeight) { - if (image != null) { - image.dispose(); - } - image = new Image(event.display, canvasWidth, canvasHeight); - fCanvas.setData(IMAGE_KEY, image); - } - - // Draw the histogram on its canvas - final GC imageGC = new GC(image); - formatImage(imageGC, image); - event.gc.drawImage(image, 0, 0); - imageGC.dispose(); - } - - private void formatImage(final GC imageGC, final Image image) { - - if (fScaledData == null) { - return; - } - - final HistogramScaledData scaledData = new HistogramScaledData(fScaledData); - - try { - // Get drawing boundaries - final int width = image.getBounds().width; - final int height = image.getBounds().height; - - // Clear the drawing area - imageGC.setBackground(fBackgroundColor); - imageGC.fillRectangle(0, 0, image.getBounds().width + 1, image.getBounds().height + 1); - - // Draw the histogram bars - final int limit = width < scaledData.fWidth ? width : scaledData.fWidth; - double factor = HistogramScaledData.hideLostEvents ? scaledData.fScalingFactor : scaledData.fScalingFactorCombined; - final boolean showTracesColors = showTraces(); - for (int i = 0; i < limit; i++) { - HistogramBucket hb = scaledData.fData[i]; - int totalNbEvents = hb.getNbEvents(); - int value = (int) Math.ceil(totalNbEvents * factor); - int x = i + fOffset; - - // in Linux, the last pixel in a line is not drawn, - // so draw lost events first, one pixel too far - if (!HistogramScaledData.hideLostEvents) { - imageGC.setForeground(fLostEventColor); - final int lostEventValue = (int) Math.ceil(scaledData.fLostEventsData[i] * factor); - if (lostEventValue != 0) { - // drawing a line is inclusive, so we should remove 1 from y2 - // but we don't because Linux - imageGC.drawLine(x, height - value - lostEventValue, x, height - value); - } - } - - // then draw normal events second, to overwrite that extra pixel - if (!hb.isEmpty()) { - if (showTracesColors) { - for (int traceIndex = 0; traceIndex < hb.getNbTraces(); traceIndex++) { - int nbEventsForTrace = hb.getNbEvent(traceIndex); - if (nbEventsForTrace > 0) { - Color c = fHistoBarColors[traceIndex % fHistoBarColors.length]; - imageGC.setForeground(c); - imageGC.drawLine(x, height - value, x, height); - totalNbEvents -= nbEventsForTrace; - value = (int) Math.ceil(totalNbEvents * scaledData.fScalingFactor); - } - } - } else { - Color c = fHistoBarColors[0]; - imageGC.setForeground(c); - imageGC.drawLine(x, height - value, x, height); - } - } - } - - // Draw the selection bars - int alpha = imageGC.getAlpha(); - imageGC.setAlpha(100); - imageGC.setForeground(fSelectionForegroundColor); - imageGC.setBackground(fSelectionBackgroundColor); - final int beginBucket = scaledData.fSelectionBeginBucket + fOffset; - if (beginBucket >= 0 && beginBucket < limit) { - imageGC.drawLine(beginBucket, 0, beginBucket, height); - } - final int endBucket = scaledData.fSelectionEndBucket + fOffset; - if (endBucket >= 0 && endBucket < limit && endBucket != beginBucket) { - imageGC.drawLine(endBucket, 0, endBucket, height); - } - if (Math.abs(endBucket - beginBucket) > 1) { - if (endBucket > beginBucket) { - imageGC.fillRectangle(beginBucket + 1, 0, endBucket - beginBucket - 1, height); - } else { - imageGC.fillRectangle(endBucket + 1, 0, beginBucket - endBucket - 1, height); - } - } - imageGC.setAlpha(alpha); - - // Add a dashed line as a delimiter - int delimiterIndex = (int) ((getDataModel().getEndTime() - scaledData.getFirstBucketTime()) / scaledData.fBucketDuration) + 1; - drawDelimiter(imageGC, fLastEventColor, height, delimiterIndex); - - // Fill the area to the right of delimiter with background color - imageGC.setBackground(fComposite.getBackground()); - imageGC.fillRectangle(delimiterIndex + 1, 0, width - (delimiterIndex + 1), height); - - } catch (final Exception e) { - // Do nothing - } - } - - private static void drawDelimiter(final GC imageGC, final Color color, - final int height, final int index) { - imageGC.setBackground(color); - final int dash = height / 4; - imageGC.fillRectangle(index, 0 * dash, 1, dash - 1); - imageGC.fillRectangle(index, 1 * dash, 1, dash - 1); - imageGC.fillRectangle(index, 2 * dash, 1, dash - 1); - imageGC.fillRectangle(index, 3 * dash, 1, height - 3 * dash); - } - - /** - * Draw a time range window - * - * @param imageGC - * the GC - * @param rangeStartTime - * the range start time - * @param rangeDuration - * the range duration - * @since 2.2 - */ - protected void drawTimeRangeWindow(GC imageGC, long rangeStartTime, long rangeDuration) { - - if (fScaledData == null) { - return; - } - - // Map times to histogram coordinates - long bucketSpan = Math.max(fScaledData.fBucketDuration, 1); - long startTime = Math.min(rangeStartTime, rangeStartTime + rangeDuration); - int rangeWidth = (int) (Math.abs(rangeDuration) / bucketSpan); - - int left = (int) ((startTime - fDataModel.getFirstBucketTime()) / bucketSpan); - int right = left + rangeWidth; - int center = (left + right) / 2; - int height = fCanvas.getSize().y; - int arc = Math.min(15, rangeWidth); - - // Draw the selection window - imageGC.setForeground(fTimeRangeColor); - imageGC.setLineWidth(1); - imageGC.setLineStyle(SWT.LINE_SOLID); - imageGC.drawRoundRectangle(left, 0, rangeWidth, height - 1, arc, arc); - - // Fill the selection window - imageGC.setBackground(fTimeRangeColor); - imageGC.setAlpha(35); - imageGC.fillRoundRectangle(left + 1, 1, rangeWidth - 1, height - 2, arc, arc); - imageGC.setAlpha(255); - - // Draw the cross hair - imageGC.setForeground(fTimeRangeColor); - imageGC.setLineWidth(1); - imageGC.setLineStyle(SWT.LINE_SOLID); - - int chHalfWidth = ((rangeWidth < 60) ? (rangeWidth * 2) / 3 : 40) / 2; - imageGC.drawLine(center - chHalfWidth, height / 2, center + chHalfWidth, height / 2); - imageGC.drawLine(center, (height / 2) - chHalfWidth, center, (height / 2) + chHalfWidth); - } - - // ------------------------------------------------------------------------ - // KeyListener - // ------------------------------------------------------------------------ - - @Override - public void keyPressed(final KeyEvent event) { - moveCursor(event.keyCode); - } - - @Override - public void keyReleased(final KeyEvent event) { - } - - // ------------------------------------------------------------------------ - // MouseListener - // ------------------------------------------------------------------------ - - @Override - public void mouseDoubleClick(final MouseEvent event) { - } - - @Override - public void mouseDown(final MouseEvent event) { - if (fScaledData != null && event.button == 1 && fDragState == DRAG_NONE && fDataModel.getStartTime() < fDataModel.getEndTime()) { - fDragState = DRAG_SELECTION; - fDragButton = event.button; - if ((event.stateMask & SWT.MODIFIER_MASK) == SWT.SHIFT) { - if (Math.abs(event.x - fScaledData.fSelectionBeginBucket) < Math.abs(event.x - fScaledData.fSelectionEndBucket)) { - fScaledData.fSelectionBeginBucket = fScaledData.fSelectionEndBucket; - fSelectionBegin = fSelectionEnd; - } - fSelectionEnd = Math.min(getTimestamp(event.x), getEndTime()); - fScaledData.fSelectionEndBucket = (int) ((fSelectionEnd - fScaledData.fFirstBucketTime) / fScaledData.fBucketDuration); - } else { - fSelectionBegin = Math.min(getTimestamp(event.x), getEndTime()); - fScaledData.fSelectionBeginBucket = (int) ((fSelectionBegin - fScaledData.fFirstBucketTime) / fScaledData.fBucketDuration); - fSelectionEnd = fSelectionBegin; - fScaledData.fSelectionEndBucket = fScaledData.fSelectionBeginBucket; - } - fCanvas.redraw(); - } - } - - @Override - public void mouseUp(final MouseEvent event) { - if (fDragState == DRAG_SELECTION && event.button == fDragButton) { - fDragState = DRAG_NONE; - fDragButton = 0; - updateSelectionTime(); - } - } - - // ------------------------------------------------------------------------ - // MouseMoveListener - // ------------------------------------------------------------------------ - - /** - * @since 2.2 - */ - @Override - public void mouseMove(MouseEvent event) { - if (fDragState == DRAG_SELECTION && fDataModel.getStartTime() < fDataModel.getEndTime()) { - fSelectionEnd = Math.max(getStartTime(), Math.min(getEndTime(), getTimestamp(event.x))); - fScaledData.fSelectionEndBucket = (int) ((fSelectionEnd - fScaledData.fFirstBucketTime) / fScaledData.fBucketDuration); - fCanvas.redraw(); - } - } - - // ------------------------------------------------------------------------ - // MouseTrackListener - // ------------------------------------------------------------------------ - - @Override - public void mouseEnter(final MouseEvent event) { - } - - @Override - public void mouseExit(final MouseEvent event) { - } - - @Override - public void mouseHover(final MouseEvent event) { - if (fDataModel.getStartTime() < fDataModel.getEndTime() && fScaledData != null) { - int delimiterIndex = (int) ((fDataModel.getEndTime() - fScaledData.getFirstBucketTime()) / fScaledData.fBucketDuration) + 1; - if (event.x < delimiterIndex) { - final String tooltip = formatToolTipLabel(event.x - fOffset); - fCanvas.setToolTipText(tooltip); - return; - } - } - fCanvas.setToolTipText(null); - } - - private String formatToolTipLabel(final int index) { - long startTime = fScaledData.getBucketStartTime(index); - // negative values are possible if time values came into the model in decreasing order - if (startTime < 0) { - startTime = 0; - } - final long endTime = fScaledData.getBucketEndTime(index); - final int nbEvents = (index >= 0) ? fScaledData.fData[index].getNbEvents() : 0; - final String newLine = System.getProperty("line.separator"); //$NON-NLS-1$ - final StringBuffer buffer = new StringBuffer(); - int selectionBeginBucket = Math.min(fScaledData.fSelectionBeginBucket, fScaledData.fSelectionEndBucket); - int selectionEndBucket = Math.max(fScaledData.fSelectionBeginBucket, fScaledData.fSelectionEndBucket); - if (selectionBeginBucket <= index && index <= selectionEndBucket && fSelectionBegin != fSelectionEnd) { - TmfTimestampDelta delta = new TmfTimestampDelta(Math.abs(fSelectionEnd - fSelectionBegin), ITmfTimestamp.NANOSECOND_SCALE); - buffer.append(NLS.bind(Messages.Histogram_selectionSpanToolTip, delta.toString())); - buffer.append(newLine); - } - buffer.append(NLS.bind(Messages.Histogram_bucketRangeToolTip, - new TmfTimestamp(startTime, ITmfTimestamp.NANOSECOND_SCALE).toString(), - new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE).toString())); - buffer.append(newLine); - buffer.append(NLS.bind(Messages.Histogram_eventCountToolTip, nbEvents)); - if (!HistogramScaledData.hideLostEvents) { - final int nbLostEvents = (index >= 0) ? fScaledData.fLostEventsData[index] : 0; - buffer.append(newLine); - buffer.append(NLS.bind(Messages.Histogram_lostEventCountToolTip, nbLostEvents)); - } - return buffer.toString(); - } - - // ------------------------------------------------------------------------ - // ControlListener - // ------------------------------------------------------------------------ - - @Override - public void controlMoved(final ControlEvent event) { - fDataModel.complete(); - } - - @Override - public void controlResized(final ControlEvent event) { - fDataModel.complete(); - } - - // ------------------------------------------------------------------------ - // Signal Handlers - // ------------------------------------------------------------------------ - - /** - * Format the timestamp and update the display - * - * @param signal - * the incoming signal - * @since 2.0 - */ - @TmfSignalHandler - public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) { - updateRangeTextControls(); - - fComposite.layout(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramBucket.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramBucket.java deleted file mode 100644 index 0ff0b78cf9..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramBucket.java +++ /dev/null @@ -1,175 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Kalray - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xavier Raynaud - Initial API and implementation - * Patrick Tasse - Fix concurrency issue - *******************************************************************************/ -package org.eclipse.linuxtools.tmf.ui.views.histogram; - -import java.util.Arrays; - -/** - * This class counts events for a particular time range, taking into account origin of the event. - * @author Xavier Raynaud - * @since 3.0 - */ -public class HistogramBucket { - - private int fNbEvents = 0; - private int fEvents[]; - - /** - * Constructor - * @param traceCount number of traces of the experiment. - */ - public HistogramBucket(int traceCount) { - fEvents = new int[traceCount]; - } - - /** - * Constructor - * @param values list of values - */ - public HistogramBucket(int... values) { - fEvents = values; - for (int i : fEvents) { - fNbEvents += i; - } - } - - /** - * Copy Constructor - * @param b a HistogramBucket to copy - */ - public HistogramBucket(HistogramBucket b) { - add(b); - } - - /** - * Merge Constructor - * @param b1 a HistogramBucket - * @param b2 another HistogramBucket - */ - public HistogramBucket(HistogramBucket b1, HistogramBucket b2) { - add(b1); - add(b2); - } - - /** - * @return the number of events in this bucket - */ - public int getNbEvents() { - return fNbEvents; - } - - /** - * Add an event in this bucket - * @param traceIndex a trace index - see {@link HistogramDataModel#setTrace}. - */ - public synchronized void addEvent(int traceIndex) { - ensureCapacity(traceIndex + 1); - fEvents[traceIndex]++; - fNbEvents++; - } - - private void ensureCapacity(int len) { - if (fEvents == null) { - fEvents = new int[len]; - } else if (fEvents.length < len) { - int[] oldArray = fEvents; - fEvents = new int[len]; - System.arraycopy(oldArray, 0, fEvents, 0, oldArray.length); - } - } - - /** - * Gets the number of event in this bucket belonging to given trace - * @param traceIndex a trace index - * @return the number of events in this bucket belonging to the given trace - */ - public int getNbEvent(int traceIndex) { - if (fEvents == null || fEvents.length<= traceIndex) { - return 0; - } - return fEvents[traceIndex]; - } - - /** - * @return the number of traces in this bucket - */ - public int getNbTraces() { - if (fEvents == null) { - return 0; - } - return fEvents.length; - } - - /** - * Merge the given bucket in this one. - * @param histogramBucket a bucket to merge in this one. - */ - public synchronized void add(HistogramBucket histogramBucket) { - if (histogramBucket != null && histogramBucket.fNbEvents != 0) { - int len = histogramBucket.fEvents.length; - ensureCapacity(len); - for (int i = 0; i < len; i++) { - int nbEvents = histogramBucket.fEvents[i]; - fEvents[i] += nbEvents; - fNbEvents += nbEvents; - } - } - } - - /** - * @return true if this bucket contains no event, false otherwise. - */ - public boolean isEmpty() { - return fNbEvents == 0; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + Arrays.hashCode(fEvents); - result = prime * result + fNbEvents; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - HistogramBucket other = (HistogramBucket) obj; - if (fNbEvents != other.fNbEvents) { - return false; - } - if (fNbEvents != 0 && !Arrays.equals(fEvents, other.fEvents)) { - return false; - } - return true; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(fNbEvents); - sb.append(": "); //$NON-NLS-1$ - sb.append(Arrays.toString(fEvents)); - return sb.toString(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramCurrentTimeControl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramCurrentTimeControl.java deleted file mode 100644 index e94254484e..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramCurrentTimeControl.java +++ /dev/null @@ -1,130 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Moved from LTTng to TMF - * Francois Chouinard - Simplified constructor, handle interval format change - * Patrick Tasse - Update value handling - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.histogram; - -import java.text.ParseException; - -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimestampFormatUpdateSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampFormat; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.swt.widgets.Composite; - -/** - * This control provides a group containing a text control. - * - * @version 1.1 - * @author Francois Chouinard - */ -public class HistogramCurrentTimeControl extends HistogramTextControl { - - // ------------------------------------------------------------------------ - // Construction - // ------------------------------------------------------------------------ - - /** - * Standard constructor - * - * @param parentView A parent histogram view - * @param parent A parent composite to draw in - * @param label A label - * @param value A value - * @since 2.0 - */ - public HistogramCurrentTimeControl(HistogramView parentView, Composite parent, - String label, long value) - { - super(parentView, parent, label, value); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Override - protected void updateValue() { - if (getValue() == Long.MIN_VALUE) { - fTextValue.setText(""); //$NON-NLS-1$ - return; - } - String string = fTextValue.getText(); - long value = getValue(); - try { - value = TmfTimestampFormat.getDefaulTimeFormat().parseValue(string, getValue()); - } catch (ParseException e) { - } - if (getValue() != value) { - // Make sure that the new time is within range - ITmfTrace trace = fParentView.getTrace(); - if (trace != null) { - TmfTimeRange range = trace.getTimeRange(); - long startTime = range.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - long endTime = range.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - if (value < startTime) { - value = startTime; - } else if (value > endTime) { - value = endTime; - } - } - - // Set and propagate - setValue(value); - updateSelectionTime(value); - } else { - setValue(value); - } - } - - /** - * Update the selection time - * - * @param time - * the new selected time - * @since 2.2 - */ - protected void updateSelectionTime(long time) { - fParentView.updateSelectionTime(time, time); - } - - @Override - public void setValue(long time) { - if (time != Long.MIN_VALUE) { - super.setValue(time, new TmfTimestamp(time, ITmfTimestamp.NANOSECOND_SCALE).toString()); - } else { - super.setValue(time, ""); //$NON-NLS-1$ - } - } - - // ------------------------------------------------------------------------ - // Signal Handlers - // ------------------------------------------------------------------------ - - /** - * Format the timestamp and update the display. Compute the new text size, - * adjust the text and group widgets and then refresh the view layout. - * - * @param signal the incoming signal - * @since 2.0 - */ - @TmfSignalHandler - public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) { - setValue(getValue()); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramDataModel.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramDataModel.java deleted file mode 100644 index f708d5ecde..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramDataModel.java +++ /dev/null @@ -1,717 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Implementation of new interfaces/listeners and support for - * time stamp in any order - * Francois Chouinard - Moved from LTTng to TMF - * Francois Chouinard - Added support for empty initial buckets - * Patrick Tasse - Support selection range - * Jean-Christian Kouamé, Simon Delisle - Added support to manage lost events - * Xavier Raynaud - Support multi-trace coloring - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.histogram; - -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.eclipse.core.runtime.ListenerList; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; - -/** - * Histogram-independent data model. - * - * It has the following characteristics: - *
    - *
  • The basetime is the timestamp of the first event - *
  • There is a fixed number (n) of buckets of uniform duration - * (d) - *
  • The timespan of the model is thus: n * d time units - *
  • Bucket i holds the number of events that occurred in time range: - * [basetime + i * d, basetime + (i + 1) * - * d) - *
- * Initially, the bucket durations is set to 1ns. As the events are read, they - * are tallied (using countEvent()) in the appropriate bucket (relative - * to the basetime). - *

- * Eventually, an event will have a timestamp that exceeds the timespan - * high end (determined by n, the number of buckets, and d, the - * bucket duration). At this point, the histogram needs to be compacted. This is - * done by simply merging adjacent buckets by pair, in effect doubling the - * timespan (timespan' = n * d', where d' = - * 2d). This compaction happens as needed as the trace is read. - *

- * The model allows for timestamps in not increasing order. The timestamps can - * be fed to the model in any order. If an event has a timestamp less than the - * basetime, the buckets will be moved to the right to account for the - * new smaller timestamp. The new basetime is a multiple of the bucket - * duration smaller then the previous basetime. Note that the - * basetime might no longer be the timestamp of an event. If necessary, - * the buckets will be compacted before moving to the right. This might be - * necessary to not lose any event counts at the end of the buckets array. - *

- * The mapping from the model to the UI is performed by the scaleTo() - * method. By keeping the number of buckets n relatively large with - * respect to to the number of pixels in the actual histogram, we should achieve - * a nice result when visualizing the histogram. - *

- * - * @version 2.0 - * @author Francois Chouinard - */ -public class HistogramDataModel implements IHistogramDataModel { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The default number of buckets - */ - public static final int DEFAULT_NUMBER_OF_BUCKETS = 16 * 1000; - - /** - * Number of events after which listeners will be notified. - */ - public static final int REFRESH_FREQUENCY = DEFAULT_NUMBER_OF_BUCKETS; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // Trace management - private ITmfTrace fTrace = null; - private final Map fTraceMap = new LinkedHashMap<>(); - - // Bucket management - private final int fNbBuckets; - private final HistogramBucket[] fBuckets; - private final long[] fLostEventsBuckets; - private long fBucketDuration; - private long fNbEvents; - private int fLastBucket; - - // Timestamps - private long fFirstBucketTime; // could be negative when analyzing events with descending order!!! - private long fFirstEventTime; - private long fEndTime; - private long fSelectionBegin; - private long fSelectionEnd; - private long fTimeLimit; - - // Private listener lists - private final ListenerList fModelListeners; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor with default number of buckets. - */ - public HistogramDataModel() { - this(0, DEFAULT_NUMBER_OF_BUCKETS); - } - - /** - * Default constructor with default number of buckets. - * - * @param startTime - * The histogram start time - * @since 2.0 - */ - public HistogramDataModel(long startTime) { - this(startTime, DEFAULT_NUMBER_OF_BUCKETS); - } - - /** - * Constructor with non-default number of buckets. - * - * @param nbBuckets - * A number of buckets. - */ - public HistogramDataModel(int nbBuckets) { - this(0, nbBuckets); - } - - /** - * Constructor with non-default number of buckets. - * - * @param startTime - * the histogram start time - * @param nbBuckets - * A number of buckets. - * @since 2.0 - */ - public HistogramDataModel(long startTime, int nbBuckets) { - fFirstBucketTime = fFirstEventTime = fEndTime = startTime; - fNbBuckets = nbBuckets; - fBuckets = new HistogramBucket[nbBuckets]; - fLostEventsBuckets = new long[nbBuckets]; - fModelListeners = new ListenerList(); - clear(); - } - - /** - * Copy constructor. - * - * @param other - * A model to copy. - */ - public HistogramDataModel(HistogramDataModel other) { - fNbBuckets = other.fNbBuckets; - fBuckets = new HistogramBucket[fNbBuckets]; - for (int i = 0; i < fNbBuckets; i++) { - fBuckets[i] = new HistogramBucket(other.fBuckets[i]); - } - fLostEventsBuckets = Arrays.copyOf(other.fLostEventsBuckets, fNbBuckets); - fBucketDuration = Math.max(other.fBucketDuration, 1); - fNbEvents = other.fNbEvents; - fLastBucket = other.fLastBucket; - fFirstBucketTime = other.fFirstBucketTime; - fFirstEventTime = other.fFirstEventTime; - fEndTime = other.fEndTime; - fSelectionBegin = other.fSelectionBegin; - fSelectionEnd = other.fSelectionEnd; - fTimeLimit = other.fTimeLimit; - fModelListeners = new ListenerList(); - Object[] listeners = other.fModelListeners.getListeners(); - for (Object listener : listeners) { - fModelListeners.add(listener); - } - } - - - /** - * Disposes the data model - * @since 3.0 - */ - public void dispose() { - fTraceMap.clear(); - fTrace = null; - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Returns the number of events in the data model. - * - * @return number of events. - */ - public long getNbEvents() { - return fNbEvents; - } - - /** - * Returns the number of buckets in the model. - * - * @return number of buckets. - */ - public int getNbBuckets() { - return fNbBuckets; - } - - /** - * Returns the current bucket duration. - * - * @return bucket duration - */ - public long getBucketDuration() { - return fBucketDuration; - } - - /** - * Returns the time value of the first bucket in the model. - * - * @return time of first bucket. - */ - public long getFirstBucketTime() { - return fFirstBucketTime; - } - - /** - * Returns the time of the first event in the model. - * - * @return time of first event. - */ - public long getStartTime() { - return fFirstEventTime; - } - - /** - * Sets the trace of this model. - * @param trace - a {@link ITmfTrace} - * @since 3.0 - */ - public void setTrace(ITmfTrace trace) { - this.fTrace = trace; - fTraceMap.clear(); - ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace); - if (traces != null) { - int i = 0; - for (ITmfTrace tr : traces) { - fTraceMap.put(tr, i); - i++; - } - } - } - - /** - * Gets the trace of this model. - * @return a {@link ITmfTrace} - * @since 3.0 - */ - public ITmfTrace getTrace() { - return this.fTrace; - } - - /** - * Gets the traces names of this model. - * @return an array of trace names - * @since 3.0 - */ - public String[] getTraceNames() { - ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace); - if (traces == null) { - return new String[0]; - } - String[] traceNames = new String[traces.length]; - int i = 0; - for (ITmfTrace tr : traces) { - traceNames[i] = tr.getName(); - i++; - } - return traceNames; - } - - /** - * Gets the number of traces of this model. - * @return the number of traces of this model. - * @since 3.0 - */ - public int getNbTraces() { - ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace); - if (traces == null) { - return 1; // - } - return traces.length; - } - - /** - * Sets the model start time - * - * @param startTime - * the histogram range start time - * @param endTime - * the histogram range end time - * @since 2.0 - */ - public void setTimeRange(long startTime, long endTime) { - fFirstBucketTime = fFirstEventTime = fEndTime = startTime; - fBucketDuration = 1; - updateEndTime(); - while (endTime >= fTimeLimit) { - mergeBuckets(); - } - } - - /** - * Set the end time. Setting this ensures that the corresponding bucket is - * displayed regardless of the event counts. - * - * @param endTime - * the time of the last used bucket - * @since 2.2 - */ - public void setEndTime(long endTime) { - fEndTime = endTime; - fLastBucket = (int) ((endTime - fFirstBucketTime) / fBucketDuration); - } - - /** - * Returns the end time. - * - * @return the time of the last used bucket - */ - public long getEndTime() { - return fEndTime; - } - - /** - * Returns the begin time of the current selection in the model. - * - * @return the begin time of the current selection. - * @since 2.1 - */ - public long getSelectionBegin() { - return fSelectionBegin; - } - - /** - * Returns the end time of the current selection in the model. - * - * @return the end time of the current selection. - * @since 2.1 - */ - public long getSelectionEnd() { - return fSelectionEnd; - } - - /** - * Returns the time limit with is: start time + nbBuckets * bucketDuration - * - * @return the time limit. - */ - public long getTimeLimit() { - return fTimeLimit; - } - - // ------------------------------------------------------------------------ - // Listener handling - // ------------------------------------------------------------------------ - - /** - * Add a listener to the model to be informed about model changes. - * - * @param listener - * A listener to add. - */ - public void addHistogramListener(IHistogramModelListener listener) { - fModelListeners.add(listener); - } - - /** - * Remove a given model listener. - * - * @param listener - * A listener to remove. - */ - public void removeHistogramListener(IHistogramModelListener listener) { - fModelListeners.remove(listener); - } - - // Notify listeners (always) - private void fireModelUpdateNotification() { - fireModelUpdateNotification(0); - } - - // Notify listener on boundary - private void fireModelUpdateNotification(long count) { - if ((count % REFRESH_FREQUENCY) == 0) { - Object[] listeners = fModelListeners.getListeners(); - for (Object listener2 : listeners) { - IHistogramModelListener listener = (IHistogramModelListener) listener2; - listener.modelUpdated(); - } - } - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Override - public void complete() { - fireModelUpdateNotification(); - } - - /** - * Clear the histogram model. - * - * @see org.eclipse.linuxtools.tmf.ui.views.distribution.model.IBaseDistributionModel#clear() - */ - @Override - public void clear() { - Arrays.fill(fBuckets, null); - Arrays.fill(fLostEventsBuckets, 0); - fNbEvents = 0; - fFirstBucketTime = 0; - fEndTime = 0; - fSelectionBegin = 0; - fSelectionEnd = 0; - fLastBucket = 0; - fBucketDuration = 1; - updateEndTime(); - fireModelUpdateNotification(); - } - - /** - * Sets the current selection time range (no notification of listeners) - * - * @param beginTime - * The selection begin time. - * @param endTime - * The selection end time. - * @since 2.1 - */ - public void setSelection(long beginTime, long endTime) { - fSelectionBegin = beginTime; - fSelectionEnd = endTime; - } - - /** - * Sets the current selection time range with notification of listeners - * - * @param beginTime - * The selection begin time. - * @param endTime - * The selection end time. - * @since 2.1 - */ - public void setSelectionNotifyListeners(long beginTime, long endTime) { - fSelectionBegin = beginTime; - fSelectionEnd = endTime; - fireModelUpdateNotification(); - } - - /** - * Add event to the correct bucket, compacting the if needed. - * - * @param eventCount - * The current event Count (for notification purposes) - * @param timestamp - * The timestamp of the event to count - * @param trace - * The event trace - * @since 3.0 - */ - @Override - public void countEvent(long eventCount, long timestamp, ITmfTrace trace) { - - // Validate - if (timestamp < 0) { - return; - } - - // Set the start/end time if not already done - if ((fFirstBucketTime == 0) && (fLastBucket == 0) && (fBuckets[0] == null) && (timestamp > 0)) { - fFirstBucketTime = timestamp; - fFirstEventTime = timestamp; - updateEndTime(); - } - - if (timestamp < fFirstEventTime) { - fFirstEventTime = timestamp; - } - - if (fEndTime < timestamp) { - fEndTime = timestamp; - } - - if (timestamp >= fFirstBucketTime) { - - // Compact as needed - while (timestamp >= fTimeLimit) { - mergeBuckets(); - } - - } else { - - // get offset for adjustment - int offset = getOffset(timestamp); - - // Compact as needed - while ((fLastBucket + offset) >= fNbBuckets) { - mergeBuckets(); - offset = getOffset(timestamp); - } - - moveBuckets(offset); - - fLastBucket = fLastBucket + offset; - - fFirstBucketTime = fFirstBucketTime - (offset * fBucketDuration); - updateEndTime(); - } - - // Increment the right bucket - int index = (int) ((timestamp - fFirstBucketTime) / fBucketDuration); - if (fBuckets[index] == null) { - fBuckets[index] = new HistogramBucket(getNbTraces()); - } - Integer traceIndex = fTraceMap.get(trace); - if (traceIndex == null) { - traceIndex = 0; - } - fBuckets[index].addEvent(traceIndex); - fNbEvents++; - if (fLastBucket < index) { - fLastBucket = index; - } - - fireModelUpdateNotification(eventCount); - } - - /** - * Add lost event to the correct bucket, compacting the if needed. - * - * @param timeRange - * time range of a lost event - * @param nbLostEvents - * the number of lost events - * @param fullRange - * Full range or time range for histogram request - * @since 2.2 - */ - public void countLostEvent(TmfTimeRange timeRange, long nbLostEvents, boolean fullRange) { - - // Validate - if (timeRange.getStartTime().getValue() < 0 || timeRange.getEndTime().getValue() < 0) { - return; - } - - // Compact as needed - if (fullRange) { - while (timeRange.getEndTime().getValue() >= fTimeLimit) { - mergeBuckets(); - } - } - - int indexStart = (int) ((timeRange.getStartTime().getValue() - fFirstBucketTime) / fBucketDuration); - int indexEnd = (int) ((timeRange.getEndTime().getValue() - fFirstBucketTime) / fBucketDuration); - int nbBucketRange = (indexEnd - indexStart) + 1; - - int lostEventPerBucket = (int) Math.ceil((double) nbLostEvents / nbBucketRange); - long lastLostCol = Math.max(1, nbLostEvents - lostEventPerBucket * (nbBucketRange - 1)); - - // Increment the right bucket, bear in mind that ranges make it almost certain that some lost events are out of range - for (int index = indexStart; index <= indexEnd && index < fLostEventsBuckets.length; index++) { - if (index == (indexStart + nbBucketRange - 1)) { - fLostEventsBuckets[index] += lastLostCol; - } else { - fLostEventsBuckets[index] += lostEventPerBucket; - } - } - - fNbEvents++; - - fireModelUpdateNotification(nbLostEvents); - } - - /** - * Scale the model data to the width, height and bar width requested. - * - * @param width - * A width of the histogram canvas - * @param height - * A height of the histogram canvas - * @param barWidth - * A width (in pixel) of a histogram bar - * @return the result array of size [width] and where the highest value - * doesn't exceed [height] - * - * @see org.eclipse.linuxtools.tmf.ui.views.histogram.IHistogramDataModel#scaleTo(int, - * int, int) - */ - @Override - public HistogramScaledData scaleTo(int width, int height, int barWidth) { - // Basic validation - if ((width <= 0) || (height <= 0) || (barWidth <= 0)) - { - throw new AssertionError("Invalid histogram dimensions (" + width + "x" + height + ", barWidth=" + barWidth + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - - // The result structure - HistogramScaledData result = new HistogramScaledData(width, height, barWidth); - - // Scale horizontally - result.fMaxValue = 0; - - int nbBars = width / barWidth; - int bucketsPerBar = (fLastBucket / nbBars) + 1; - result.fBucketDuration = Math.max(bucketsPerBar * fBucketDuration, 1); - for (int i = 0; i < nbBars; i++) { - int count = 0; - int countLostEvent = 0; - result.fData[i] = new HistogramBucket(getNbTraces()); - for (int j = i * bucketsPerBar; j < ((i + 1) * bucketsPerBar); j++) { - if (fNbBuckets <= j) { - break; - } - if (fBuckets[j] != null) { - count += fBuckets[j].getNbEvents(); - result.fData[i].add(fBuckets[j]); - } - countLostEvent += fLostEventsBuckets[j]; - } - result.fLostEventsData[i] = countLostEvent; - result.fLastBucket = i; - if (result.fMaxValue < count) { - result.fMaxValue = count; - } - if (result.fMaxCombinedValue < count + countLostEvent) { - result.fMaxCombinedValue = count + countLostEvent; - } - } - - // Scale vertically - if (result.fMaxValue > 0) { - result.fScalingFactor = (double) height / result.fMaxValue; - } - if (result.fMaxCombinedValue > 0) { - result.fScalingFactorCombined = (double) height / result.fMaxCombinedValue; - } - - fBucketDuration = Math.max(fBucketDuration, 1); - // Set selection begin and end index in the scaled histogram - result.fSelectionBeginBucket = (int) ((fSelectionBegin - fFirstBucketTime) / fBucketDuration) / bucketsPerBar; - result.fSelectionEndBucket = (int) ((fSelectionEnd - fFirstBucketTime) / fBucketDuration) / bucketsPerBar; - - result.fFirstBucketTime = fFirstBucketTime; - result.fFirstEventTime = fFirstEventTime; - return result; - } - - // ------------------------------------------------------------------------ - // Helper functions - // ------------------------------------------------------------------------ - - private void updateEndTime() { - fTimeLimit = fFirstBucketTime + (fNbBuckets * fBucketDuration); - } - - private void mergeBuckets() { - for (int i = 0; i < (fNbBuckets / 2); i++) { - fBuckets[i] = new HistogramBucket(fBuckets[2 * i], fBuckets[(2 * i) + 1]); - fLostEventsBuckets[i] = fLostEventsBuckets[2 * i] + fLostEventsBuckets[(2 * i) + 1]; - } - Arrays.fill(fBuckets, fNbBuckets / 2, fNbBuckets, null); - Arrays.fill(fLostEventsBuckets, fNbBuckets / 2, fNbBuckets, 0); - fBucketDuration *= 2; - updateEndTime(); - fLastBucket = (fNbBuckets / 2) - 1; - } - - private void moveBuckets(int offset) { - for (int i = fNbBuckets - 1; i >= offset; i--) { - fBuckets[i] = new HistogramBucket(fBuckets[i - offset]); - fLostEventsBuckets[i] = fLostEventsBuckets[i - offset]; - } - - for (int i = 0; i < offset; i++) { - fBuckets[i] = null; - fLostEventsBuckets[i] = 0; - } - } - - private int getOffset(long timestamp) { - int offset = (int) ((fFirstBucketTime - timestamp) / fBucketDuration); - if (((fFirstBucketTime - timestamp) % fBucketDuration) != 0) { - offset++; - } - return offset; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramRequest.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramRequest.java deleted file mode 100644 index d6f3c6bcca..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramRequest.java +++ /dev/null @@ -1,115 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * William Bourque - Initial API and implementation - * Yuriy Vashchuk - Heritage correction. - * Francois Chouinard - Cleanup and refactoring - * Francois Chouinard - Moved from LTTng to TMF - * Simon Delisle - Added a new parameter to the constructor - * Xavier Raynaud - Support multi-trace coloring - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.histogram; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfLostEvent; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; - -/** - * Class to request events for given time range from a trace to fill a - * HistogramDataModel and HistogramView. - * - * @version 1.0 - * @author Francois Chouinard - *

- */ -public class HistogramRequest extends TmfEventRequest { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The histogram data model to fill. - */ - protected final HistogramDataModel fHistogram; - - private final boolean fFullRange; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructor - * - * @param histogram - * The histogram data model - * @param range - * The time range to request data - * @param rank - * The index of the first event to retrieve - * @param nbEvents - * The number of events requested - * @param blockSize - * The number of events per block - * @param execType - * The requested execution priority - * @param fullRange - * Full range or time range for histogram request - * @since 3.0 - */ - public HistogramRequest(HistogramDataModel histogram, TmfTimeRange range, - int rank, int nbEvents, int blockSize, - ITmfEventRequest.ExecutionType execType, boolean fullRange) { - super(ITmfEvent.class, range, rank, nbEvents, execType); - fHistogram = histogram; - fFullRange = fullRange; - } - - // ------------------------------------------------------------------------ - // TmfEventRequest - // ------------------------------------------------------------------------ - - /** - * Handle the event from the trace by updating the histogram data model. - * - * @param event - * a event from the trace - * @see org.eclipse.linuxtools.tmf.core.request.TmfEventRequest#handleData(org.eclipse.linuxtools.tmf.core.event.ITmfEvent) - */ - @Override - public void handleData(ITmfEvent event) { - super.handleData(event); - if (event instanceof ITmfLostEvent) { - ITmfLostEvent lostEvents = (ITmfLostEvent) event; - /* clear the old data when it is a new request */ - fHistogram.countLostEvent(lostEvents.getTimeRange(), lostEvents.getNbLostEvents(), fFullRange); - - } else { /* handle lost event */ - long timestamp = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - fHistogram.countEvent(getNbRead(), timestamp, event.getTrace()); - } - } - - /** - * Complete the request. It also notifies the histogram model about the - * completion. - * - * @see org.eclipse.linuxtools.tmf.core.request.TmfEventRequest#handleCompleted() - */ - @Override - public void handleCompleted() { - fHistogram.complete(); - super.handleCompleted(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramScaledData.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramScaledData.java deleted file mode 100644 index 4a10cc4af0..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramScaledData.java +++ /dev/null @@ -1,210 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Added setter and getter and bar width support - * Francois Chouinard - Moved from LTTng to TMF - * Patrick Tasse - Support selection range - * Jean-Christian Kouamé - Support to manage lost events - * Xavier Raynaud - Support multi-trace coloring - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.histogram; - -import java.util.Arrays; - -/** - * Convenience class/struct for scaled histogram data. - * - * @version 1.0 - * @author Francois Chouinard - */ -public class HistogramScaledData { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * Indicator value that bucket is out of range (not filled). - */ - public static final int OUT_OF_RANGE_BUCKET = -1; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * Width of histogram canvas (number of pixels). - */ - public int fWidth; - /** - * Height of histogram canvas (number of pixels). - */ - public int fHeight; - /** - * Width of one histogram bar (number of pixels). - */ - public int fBarWidth; - /** - * Array of scaled values - */ - public HistogramBucket[] fData; - /** - * Array of scaled values combined including the lost events. - * This array contains the number of lost events for each bar in the histogram - * @since 2.2 - */ - public final int[] fLostEventsData; - /** - * The bucket duration of a scaled data bucket. - */ - public long fBucketDuration; - /** - * The maximum number of events of all buckets. - */ - public long fMaxValue; - /** - * the maximum of events of all buckets including the lost events - * @since 2.2 - */ - public long fMaxCombinedValue; - /** - * The index of the selection begin bucket. - * @since 2.1 - */ - public int fSelectionBeginBucket; - /** - * The index of the selection end bucket. - * @since 2.1 - */ - public int fSelectionEndBucket; - /** - * The index of the last bucket. - */ - public int fLastBucket; - /** - * The scaling factor used to fill the scaled data. - */ - public double fScalingFactor; - /** - * The scaling factor used to fill the scaled data including the lost events. - * @since 2.2 - */ - public double fScalingFactorCombined; - /** - * The scaling factor used to fill the combining scaled data including lost events - */ - /** - * Time of first bucket. - */ - public long fFirstBucketTime; - /** - * The time of the first event. - */ - public long fFirstEventTime; - /** - * show the lost events or not - * @since 2.2 - */ - public static volatile boolean hideLostEvents = false; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructor. - * @param width the canvas width - * @param height the canvas height - * @param barWidth the required bar width - */ - public HistogramScaledData(int width, int height, int barWidth) { - fWidth = width; - fHeight = height; - fBarWidth = barWidth; - fData = new HistogramBucket[width / fBarWidth]; - fLostEventsData = new int[width / fBarWidth]; - fBucketDuration = 1; - fMaxValue = 0; - fMaxCombinedValue = 0; - fSelectionBeginBucket = 0; - fSelectionEndBucket = 0; - fLastBucket = 0; - fScalingFactor = 1; - fScalingFactorCombined = 1; - fFirstBucketTime = 0; - } - - /** - * Copy constructor - * @param other another scaled data. - */ - public HistogramScaledData(HistogramScaledData other) { - fWidth = other.fWidth; - fHeight = other.fHeight; - fBarWidth = other.fBarWidth; - fData = Arrays.copyOf(other.fData, other.fData.length); - fLostEventsData = Arrays.copyOf(other.fLostEventsData, other.fLostEventsData.length); - fBucketDuration = other.fBucketDuration; - fMaxValue = other.fMaxValue; - fMaxCombinedValue = other.fMaxCombinedValue; - fSelectionBeginBucket = other.fSelectionBeginBucket; - fSelectionEndBucket = other.fSelectionEndBucket; - fLastBucket = other.fLastBucket; - fScalingFactor = other.fScalingFactor; - fScalingFactorCombined = other.fScalingFactorCombined; - fFirstBucketTime = other.fFirstBucketTime; - } - - // ------------------------------------------------------------------------ - // Setter and Getter - // ------------------------------------------------------------------------ - - /** - * Returns the time of the first bucket of the scaled data. - * @return the time of the first bucket. - */ - public long getFirstBucketTime() { - return fFirstBucketTime; - } - - /** - * Set the first event time. - * @param firstEventTime The time to set - */ - public void setFirstBucketTime(long firstEventTime) { - fFirstBucketTime = firstEventTime; - } - - /** - * Returns the time of the last bucket. - * @return last bucket time - */ - public long getLastBucketTime() { - return getBucketStartTime(fLastBucket); - } - - /** - * Returns the time of the bucket start time for given index. - * @param index A bucket index. - * @return the time of the bucket start time - */ - public long getBucketStartTime(int index) { - return fFirstBucketTime + index * fBucketDuration; - } - - /** - * Returns the time of the bucket end time for given index. - * @param index A bucket index. - * @return the time of the bucket end time - */ - public long getBucketEndTime(int index) { - return getBucketStartTime(index) + fBucketDuration; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramSelectionEndControl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramSelectionEndControl.java deleted file mode 100644 index c9e6913612..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramSelectionEndControl.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.histogram; - -import org.eclipse.swt.widgets.Composite; - -/** - * Text control for selection end time - * - * @since 2.2 - */ -public class HistogramSelectionEndControl extends HistogramCurrentTimeControl { - - /** - * Standard constructor - * - * @param parentView A parent histogram view - * @param parent A parent composite to draw in - * @param label A label - * @param value A value - */ - public HistogramSelectionEndControl(HistogramView parentView, Composite parent, String label, long value) { - super(parentView, parent, label, value); - } - - @Override - protected void updateSelectionTime(long time) { - long begin = Math.min(fParentView.getSelectionBegin(), time); - long end = Math.max(fParentView.getSelectionBegin(), time); - fParentView.updateSelectionTime(begin, end); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramSelectionStartControl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramSelectionStartControl.java deleted file mode 100644 index 3f259ff7e9..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramSelectionStartControl.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.histogram; - -import org.eclipse.swt.widgets.Composite; - -/** - * Text control for selection start time - * - * @since 2.2 - */ -public class HistogramSelectionStartControl extends HistogramCurrentTimeControl { - - /** - * Standard constructor - * - * @param parentView A parent histogram view - * @param parent A parent composite to draw in - * @param label A label - * @param value A value - */ - public HistogramSelectionStartControl(HistogramView parentView, Composite parent, String label, long value) { - super(parentView, parent, label, value); - } - - @Override - protected void updateSelectionTime(long time) { - if (fParentView.getLinkState()) { - fParentView.updateSelectionTime(time, time); - } else { - long begin = Math.min(time, fParentView.getSelectionEnd()); - long end = Math.max(time, fParentView.getSelectionEnd()); - fParentView.updateSelectionTime(begin, end); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramTextControl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramTextControl.java deleted file mode 100644 index d0404f67c7..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramTextControl.java +++ /dev/null @@ -1,280 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wiliam Bourque - Adapted from SpinnerGroup (in TimeFrameView) - * Francois Chouinard - Cleanup and refactoring - * Francois Chouinard - Moved from LTTng to TMF - * Francois Chouinard - Better handling of control display, support for signals - * Patrick Tasse - Update for mouse wheel zoom - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.histogram; - -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.MouseWheelListener; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; - -/** - * This control provides a group containing a text control. - * - * @version 1.1 - * @author Francois Chouinard - */ -public abstract class HistogramTextControl implements FocusListener, KeyListener { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The parent histogram view. - */ - protected final HistogramView fParentView; - - // Controls data - private final Composite fParent; - private Font fFont; - private final Composite fComposite; - private final Label fLabel; - - /** - * The text value field. - */ - protected final Text fTextValue; - - private long fValue; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructor with given group and text values. - * - * @param parentView The parent histogram view. - * @param parent The parent composite - * @param label The text label - * @param value The initial value - * @since 2.0 - */ - public HistogramTextControl(HistogramView parentView, Composite parent, String label, long value) - { - fParentView = parentView; - fParent = parent; - - // -------------------------------------------------------------------- - // Reduce font size for a more pleasing rendering - // -------------------------------------------------------------------- - - final int fontSizeAdjustment = -1; - final Font font = parent.getFont(); - final FontData fontData = font.getFontData()[0]; - fFont = new Font(font.getDevice(), fontData.getName(), fontData.getHeight() + fontSizeAdjustment, fontData.getStyle()); - - // -------------------------------------------------------------------- - // Create the group - // -------------------------------------------------------------------- - - // Re-used layout variables - GridLayout gridLayout; - GridData gridData; - - // Composite - gridLayout = new GridLayout(3, false); - gridLayout.marginHeight = 0; - gridLayout.marginWidth = 0; - fComposite = new Composite(fParent, SWT.NONE); - fComposite.setLayout(gridLayout); - - gridData = new GridData(SWT.FILL, SWT.CENTER, true, false); - Label filler = new Label(fComposite, SWT.NONE); - filler.setLayoutData(gridData); - - // Label - gridData = new GridData(SWT.CENTER, SWT.CENTER, false, false); - fLabel = new Label(fComposite, SWT.NONE); - fLabel.setText(label); - fLabel.setFont(fFont); - - // Text control - gridData = new GridData(SWT.CENTER, SWT.CENTER, false, false); - fTextValue = new Text(fComposite, SWT.BORDER); - fTextValue.setFont(fFont); - fTextValue.setLayoutData(gridData); - - // -------------------------------------------------------------------- - // Add listeners - // -------------------------------------------------------------------- - - fTextValue.addFocusListener(this); - fTextValue.addKeyListener(this); - - TmfSignalManager.register(this); - } - - /** - * Dispose of the widget - * @since 2.0 - */ - public void dispose() { - fFont.dispose(); - TmfSignalManager.deregister(this); - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Returns if widget isDisposed or not - * @return true if widget is disposed else false - */ - public boolean isDisposed() { - return fComposite.isDisposed(); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Updates the text value. - */ - protected abstract void updateValue(); - - /** - * Set the Grid Layout Data for the group. - * @param layoutData A GridData to set. - */ - public void setLayoutData(GridData layoutData) { - fComposite.setLayoutData(layoutData); - } - - /** - * Enables the receiver if the argument is true, - * and disables it otherwise. A disabled control is typically - * not selectable from the user interface and draws with an - * inactive or "grayed" look. - * - * @param enabled the new enabled state - * @since 2.2 - */ - public void setEnabled(boolean enabled) { - fTextValue.setEnabled(enabled); - } - - /** - * The time value in to set in the text field. - * - * @param time the time to set - * @param displayTime the display value - * @since 2.0 - */ - protected void setValue(final long time, final String displayTime) { - // If this is the UI thread, process now - Display display = Display.getCurrent(); - if (display != null) { - if (!isDisposed()) { - fValue = time; - fTextValue.setText(displayTime); - fComposite.layout(); - fParent.getParent().layout(); - } - return; - } - - // Call self from the UI thread - if (!isDisposed()) { - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - if (!isDisposed()) { - setValue(time, displayTime); - } - } - }); - } - } - - /** - * @param time the time value to display - */ - public abstract void setValue(long time); - - /** - * Returns the time value. - * @return time value. - */ - public long getValue() { - return fValue; - } - - /** - * Add a mouse wheel listener to the text control - * @param listener the mouse wheel listener - * @since 2.0 - */ - public void addMouseWheelListener(MouseWheelListener listener) { - fTextValue.addMouseWheelListener(listener); - } - - /** - * Remove a mouse wheel listener from the text control - * @param listener the mouse wheel listener - * @since 2.0 - */ - public void removeMouseWheelListener(MouseWheelListener listener) { - fTextValue.removeMouseWheelListener(listener); - } - - // ------------------------------------------------------------------------ - // FocusListener - // ------------------------------------------------------------------------ - - @Override - public void focusGained(FocusEvent event) { - } - - @Override - public void focusLost(FocusEvent event) { - updateValue(); - } - - // ------------------------------------------------------------------------ - // KeyListener - // ------------------------------------------------------------------------ - - @Override - public void keyPressed(KeyEvent event) { - switch (event.character) { - case SWT.CR: - updateValue(); - break; - default: - break; - } - } - - @Override - public void keyReleased(KeyEvent e) { - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramTimeRangeControl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramTimeRangeControl.java deleted file mode 100644 index cc064c3d3a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramTimeRangeControl.java +++ /dev/null @@ -1,106 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Moved from LTTng to TMF - * Francois Chouinard - Simplified constructor, handle interval format change - * Patrick Tasse - Update value handling - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.histogram; - -import java.text.ParseException; - -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimestampFormatUpdateSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampFormat; -import org.eclipse.swt.widgets.Composite; - -/** - * This control provides a group containing a text control. - * - * @version 2.0 - * @author Francois Chouinard - */ -public class HistogramTimeRangeControl extends HistogramTextControl { - - // ------------------------------------------------------------------------ - // Construction - // ------------------------------------------------------------------------ - - /** - * Constructor with given group and text values. - * - * @param parentView The parent histogram view. - * @param parent The parent composite - * @param groupLabel A group value - * @param value A text value - * @since 2.0 - */ - public HistogramTimeRangeControl(HistogramView parentView, Composite parent, - String groupLabel, long value) - { - super(parentView, parent, groupLabel, value); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Override - protected void updateValue() { - if (getValue() == Long.MIN_VALUE) { - fTextValue.setText(""); //$NON-NLS-1$ - return; - } - String string = fTextValue.getText(); - long value = getValue(); - try { - value = TmfTimestampFormat.getDefaulIntervalFormat().parseValue(string); - if (value < 1) { - value = getValue(); - } - } catch (ParseException e) { - } - if (getValue() != value) { - fParentView.updateTimeRange(value); - } else { - setValue(value); - } - } - - @Override - public void setValue(long time) { - if (time != Long.MIN_VALUE) { - ITmfTimestamp ts = new TmfTimestamp(time, ITmfTimestamp.NANOSECOND_SCALE); - super.setValue(time, ts.toString(TmfTimestampFormat.getDefaulIntervalFormat())); - } else { - super.setValue(time, ""); //$NON-NLS-1$ - } - } - - // ------------------------------------------------------------------------ - // Signal Handlers - // ------------------------------------------------------------------------ - - /** - * Format the interval and update the display. Compute the new text size, - * adjust the text and group widgets and then refresh the view layout. - * - * @param signal the incoming signal - * @since 2.0 - */ - @TmfSignalHandler - public void intervalFormatUpdated(TmfTimestampFormatUpdateSignal signal) { - setValue(getValue()); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramView.java deleted file mode 100644 index 3287b70226..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramView.java +++ /dev/null @@ -1,887 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * William Bourque - Initial API and implementation - * Yuriy Vashchuk - GUI reorganisation, simplification and some related code improvements. - * Yuriy Vashchuk - Histograms optimisation. - * Yuriy Vashchuk - Histogram Canvas Heritage correction - * Francois Chouinard - Cleanup and refactoring - * Francois Chouinard - Moved from LTTng to TMF - * Patrick Tasse - Update for mouse wheel zoom - * Xavier Raynaud - Support multi-trace coloring - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.histogram; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.Separator; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest.ExecutionType; -import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalThrottler; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ui.views.TmfView; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.CLabel; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseWheelListener; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.IActionBars; - -/** - * The purpose of this view is to provide graphical time distribution statistics about the trace events. - *

- * The view is composed of two histograms and two controls: - *

    - *
  • an event distribution histogram for the whole trace; - *
  • an event distribution histogram for current time window (window span); - *
  • the timestamp of the currently selected event; - *
  • the window span (size of the time window of the smaller histogram). - *
- * The histograms x-axis show their respective time range. - * - * @version 2.0 - * @author Francois Chouinard - */ -public class HistogramView extends TmfView { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The view ID as defined in plugin.xml - */ - public static final @NonNull String ID = "org.eclipse.linuxtools.tmf.ui.views.histogram"; //$NON-NLS-1$ - - private static final Image LINK_IMG = Activator.getDefault().getImageFromPath("/icons/etool16/link.gif"); //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // Parent widget - private Composite fParent; - - // The current trace - private ITmfTrace fTrace; - - // Current timestamp/time window - everything in the TIME_SCALE - private long fTraceStartTime; - private long fTraceEndTime; - private long fWindowStartTime; - private long fWindowEndTime; - private long fWindowSpan; - private long fSelectionBeginTime; - private long fSelectionEndTime; - - // Time controls - private HistogramTextControl fSelectionStartControl; - private HistogramTextControl fSelectionEndControl; - private HistogramTextControl fTimeSpanControl; - - // Link - private Label fLinkButton; - private boolean fLinkState; - - // Histogram/request for the full trace range - private static FullTraceHistogram fFullTraceHistogram; - private HistogramRequest fFullTraceRequest; - - // Histogram/request for the selected time range - private static TimeRangeHistogram fTimeRangeHistogram; - private HistogramRequest fTimeRangeRequest; - - // Legend area - private Composite fLegendArea; - private Image[] fLegendImages; - - // Throttlers for the time sync and time-range sync signals - private final TmfSignalThrottler fTimeSyncThrottle; - private final TmfSignalThrottler fTimeRangeSyncThrottle; - - // Action for toggle showing the lost events - private Action hideLostEventsAction; - // Action for toggle showing the traces - private Action showTraceAction; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - public HistogramView() { - super(ID); - fTimeSyncThrottle = new TmfSignalThrottler(this, 200); - fTimeRangeSyncThrottle = new TmfSignalThrottler(this, 200); - } - - @Override - public void dispose() { - if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) { - fTimeRangeRequest.cancel(); - } - if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) { - fFullTraceRequest.cancel(); - } - fFullTraceHistogram.dispose(); - fTimeRangeHistogram.dispose(); - fSelectionStartControl.dispose(); - fSelectionEndControl.dispose(); - fTimeSpanControl.dispose(); - super.dispose(); - } - - // ------------------------------------------------------------------------ - // TmfView - // ------------------------------------------------------------------------ - - @Override - public void createPartControl(Composite parent) { - - fParent = parent; - - // Control labels - final String selectionStartLabel = Messages.HistogramView_selectionStartLabel; - final String selectionEndLabel = Messages.HistogramView_selectionEndLabel; - final String windowSpanLabel = Messages.HistogramView_windowSpanLabel; - - // -------------------------------------------------------------------- - // Set the HistogramView layout - // -------------------------------------------------------------------- - - Composite viewComposite = new Composite(fParent, SWT.FILL); - GridLayout gridLayout = new GridLayout(); - gridLayout.numColumns = 2; - gridLayout.horizontalSpacing = 5; - gridLayout.verticalSpacing = 0; - gridLayout.marginHeight = 0; - gridLayout.marginWidth = 0; - viewComposite.setLayout(gridLayout); - - // -------------------------------------------------------------------- - // Time controls - // -------------------------------------------------------------------- - - Composite controlsComposite = new Composite(viewComposite, SWT.NONE); - gridLayout = new GridLayout(); - gridLayout.numColumns = 2; - gridLayout.marginHeight = 0; - gridLayout.marginWidth = 0; - gridLayout.horizontalSpacing = 5; - gridLayout.verticalSpacing = 1; - gridLayout.makeColumnsEqualWidth = false; - controlsComposite.setLayout(gridLayout); - GridData gridData = new GridData(SWT.FILL, SWT.CENTER, false, false); - controlsComposite.setLayoutData(gridData); - - Composite selectionGroup = new Composite(controlsComposite, SWT.BORDER); - gridLayout = new GridLayout(); - gridLayout.marginHeight = 0; - gridLayout.marginWidth = 0; - gridLayout.horizontalSpacing = 0; - gridLayout.verticalSpacing = 0; - selectionGroup.setLayout(gridLayout); - - // Selection start control - gridData = new GridData(); - gridData.horizontalAlignment = SWT.FILL; - gridData.verticalAlignment = SWT.CENTER; - fSelectionStartControl = new HistogramSelectionStartControl(this, selectionGroup, selectionStartLabel, 0L); - fSelectionStartControl.setLayoutData(gridData); - fSelectionStartControl.setValue(Long.MIN_VALUE); - - // Selection end control - gridData = new GridData(); - gridData.horizontalAlignment = SWT.FILL; - gridData.verticalAlignment = SWT.CENTER; - fSelectionEndControl = new HistogramSelectionEndControl(this, selectionGroup, selectionEndLabel, 0L); - fSelectionEndControl.setLayoutData(gridData); - fSelectionEndControl.setValue(Long.MIN_VALUE); - - // Link button - gridData = new GridData(); - fLinkButton = new Label(controlsComposite, SWT.NONE); - fLinkButton.setImage(LINK_IMG); - fLinkButton.setLayoutData(gridData); - addLinkButtonListeners(); - - // Window span time control - gridData = new GridData(); - gridData.horizontalAlignment = SWT.FILL; - gridData.verticalAlignment = SWT.CENTER; - fTimeSpanControl = new HistogramTimeRangeControl(this, controlsComposite, windowSpanLabel, 0L); - fTimeSpanControl.setLayoutData(gridData); - fTimeSpanControl.setValue(Long.MIN_VALUE); - - // -------------------------------------------------------------------- - // Time range histogram - // -------------------------------------------------------------------- - - Composite timeRangeComposite = new Composite(viewComposite, SWT.NONE); - gridLayout = new GridLayout(); - gridLayout.numColumns = 1; - gridLayout.marginHeight = 0; - gridLayout.marginWidth = 0; - gridLayout.marginTop = 5; - gridLayout.horizontalSpacing = 0; - gridLayout.verticalSpacing = 0; - gridLayout.marginLeft = 5; - gridLayout.marginRight = 5; - timeRangeComposite.setLayout(gridLayout); - - // Use remaining horizontal space - gridData = new GridData(); - gridData.horizontalAlignment = SWT.FILL; - gridData.verticalAlignment = SWT.FILL; - gridData.grabExcessHorizontalSpace = true; - gridData.grabExcessVerticalSpace = true; - timeRangeComposite.setLayoutData(gridData); - - // Histogram - fTimeRangeHistogram = new TimeRangeHistogram(this, timeRangeComposite); - - // -------------------------------------------------------------------- - // Full range histogram - // -------------------------------------------------------------------- - - Composite fullRangeComposite = new Composite(viewComposite, SWT.FILL); - gridLayout = new GridLayout(); - gridLayout.numColumns = 1; - gridLayout.marginHeight = 0; - gridLayout.marginWidth = 0; - gridLayout.marginTop = 5; - gridLayout.horizontalSpacing = 0; - gridLayout.verticalSpacing = 0; - gridLayout.marginLeft = 5; - gridLayout.marginRight = 5; - fullRangeComposite.setLayout(gridLayout); - - // Use remaining horizontal space - gridData = new GridData(); - gridData.horizontalAlignment = SWT.FILL; - gridData.verticalAlignment = SWT.FILL; - gridData.horizontalSpan = 2; - gridData.grabExcessHorizontalSpace = true; - gridData.grabExcessVerticalSpace = true; - fullRangeComposite.setLayoutData(gridData); - - // Histogram - fFullTraceHistogram = new FullTraceHistogram(this, fullRangeComposite); - - fLegendArea = new Composite(viewComposite, SWT.FILL); - fLegendArea.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, true, false, 2, 1)); - fLegendArea.setLayout(new RowLayout()); - - // Add mouse wheel listener to time span control - MouseWheelListener listener = fFullTraceHistogram.getZoom(); - fTimeSpanControl.addMouseWheelListener(listener); - - - // View Action Handling - contributeToActionBars(); - - ITmfTrace trace = getActiveTrace(); - if (trace != null) { - traceSelected(new TmfTraceSelectedSignal(this, trace)); - } - } - - @Override - public void setFocus() { - fFullTraceHistogram.fCanvas.setFocus(); - } - - void refresh() { - fParent.layout(true); - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Returns the current trace handled by the view - * - * @return the current trace - * @since 2.0 - */ - public ITmfTrace getTrace() { - return fTrace; - } - - /** - * Returns the time range of the current selected window (base on default time scale). - * - * @return the time range of current selected window. - * @since 2.0 - */ - public TmfTimeRange getTimeRange() { - return new TmfTimeRange( - new TmfTimestamp(fWindowStartTime, ITmfTimestamp.NANOSECOND_SCALE), - new TmfTimestamp(fWindowEndTime, ITmfTimestamp.NANOSECOND_SCALE)); - } - - /** - * get the show lost events action - * - * @return The action object - * @since 2.2 - */ - public Action getShowLostEventsAction() { - if (hideLostEventsAction == null) { - /* show lost events */ - hideLostEventsAction = new Action(Messages.HistogramView_hideLostEvents, IAction.AS_CHECK_BOX) { - @Override - public void run() { - HistogramScaledData.hideLostEvents = hideLostEventsAction.isChecked(); - long maxNbEvents = HistogramScaledData.hideLostEvents ? fFullTraceHistogram.fScaledData.fMaxValue : fFullTraceHistogram.fScaledData.fMaxCombinedValue; - fFullTraceHistogram.setMaxNbEvents(maxNbEvents); - maxNbEvents = HistogramScaledData.hideLostEvents ? fTimeRangeHistogram.fScaledData.fMaxValue : fTimeRangeHistogram.fScaledData.fMaxCombinedValue; - fTimeRangeHistogram.setMaxNbEvents(maxNbEvents); - } - }; - hideLostEventsAction.setText(Messages.HistogramView_hideLostEvents); - hideLostEventsAction.setToolTipText(Messages.HistogramView_hideLostEvents); - hideLostEventsAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_LOST_EVENTS)); - } - return hideLostEventsAction; - } - - /** - * get the show trace action - * - * @return The action object - * @since 3.0 - */ - public Action getShowTraceAction() { - if (showTraceAction == null) { - /* show lost events */ - showTraceAction = new Action(Messages.HistogramView_showTraces, IAction.AS_CHECK_BOX) { - @Override - public void run() { - Histogram.showTraces = showTraceAction.isChecked(); - fFullTraceHistogram.fCanvas.redraw(); - fTimeRangeHistogram.fCanvas.redraw(); - updateLegendArea(); - } - }; - showTraceAction.setChecked(true); - showTraceAction.setText(Messages.HistogramView_showTraces); - showTraceAction.setToolTipText(Messages.HistogramView_showTraces); - showTraceAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_HIST_TRACES)); - } - return showTraceAction; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Broadcast TmfSignal about new current selection time range. - * @param beginTime the begin time of current selection. - * @param endTime the end time of current selection. - */ - void updateSelectionTime(long beginTime, long endTime) { - updateDisplayedSelectionTime(beginTime, endTime); - TmfTimestamp beginTs = new TmfTimestamp(beginTime, ITmfTimestamp.NANOSECOND_SCALE); - TmfTimestamp endTs = new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE); - TmfTimeSynchSignal signal = new TmfTimeSynchSignal(this, beginTs, endTs); - fTimeSyncThrottle.queue(signal); - } - - /** - * Get selection begin time - * @return the begin time of current selection - */ - long getSelectionBegin() { - return fSelectionBeginTime; - } - - /** - * Get selection end time - * @return the end time of current selection - */ - long getSelectionEnd() { - return fSelectionEndTime; - } - - /** - * Get the link state - * @return true if begin and end selection time should be linked - */ - boolean getLinkState() { - return fLinkState; - } - - /** - * Broadcast TmfSignal about new selection time range. - * @param startTime the new start time - * @param endTime the new end time - */ - void updateTimeRange(long startTime, long endTime) { - if (fTrace != null) { - // Build the new time range; keep the current time - TmfTimeRange timeRange = new TmfTimeRange( - new TmfTimestamp(startTime, ITmfTimestamp.NANOSECOND_SCALE), - new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE)); - fTimeSpanControl.setValue(endTime - startTime); - - updateDisplayedTimeRange(startTime, endTime); - - // Send the FW signal - TmfRangeSynchSignal signal = new TmfRangeSynchSignal(this, timeRange); - fTimeRangeSyncThrottle.queue(signal); - } - } - - /** - * Broadcast TmfSignal about new selected time range. - * @param newDuration new duration (relative to current start time) - */ - public synchronized void updateTimeRange(long newDuration) { - if (fTrace != null) { - long delta = newDuration - fWindowSpan; - long newStartTime = fWindowStartTime - (delta / 2); - setNewRange(newStartTime, newDuration); - } - } - - private void setNewRange(long startTime, long duration) { - long realStart = startTime; - - if (realStart < fTraceStartTime) { - realStart = fTraceStartTime; - } - - long endTime = realStart + duration; - if (endTime > fTraceEndTime) { - endTime = fTraceEndTime; - if ((endTime - duration) > fTraceStartTime) { - realStart = endTime - duration; - } else { - realStart = fTraceStartTime; - } - } - updateTimeRange(realStart, endTime); - } - - // ------------------------------------------------------------------------ - // Signal handlers - // ------------------------------------------------------------------------ - - /** - * Handles trace opened signal. Loads histogram if new trace time range is not - * equal TmfTimeRange.NULL_RANGE - * @param signal the trace opened signal - * @since 2.0 - */ - @TmfSignalHandler - public void traceOpened(TmfTraceOpenedSignal signal) { - assert (signal != null); - fTrace = signal.getTrace(); - loadTrace(); - } - - /** - * Handles trace selected signal. Loads histogram if new trace time range is not - * equal TmfTimeRange.NULL_RANGE - * @param signal the trace selected signal - * @since 2.0 - */ - @TmfSignalHandler - public void traceSelected(TmfTraceSelectedSignal signal) { - assert (signal != null); - if (fTrace != signal.getTrace()) { - fTrace = signal.getTrace(); - loadTrace(); - } - } - - private void loadTrace() { - initializeHistograms(); - fParent.redraw(); - } - - /** - * Handles trace closed signal. Clears the view and data model and cancels requests. - * @param signal the trace closed signal - * @since 2.0 - */ - @TmfSignalHandler - public void traceClosed(TmfTraceClosedSignal signal) { - - if (signal.getTrace() != fTrace) { - return; - } - - // Kill any running request - if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) { - fTimeRangeRequest.cancel(); - } - if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) { - fFullTraceRequest.cancel(); - } - - // Initialize the internal data - fTrace = null; - fTraceStartTime = 0L; - fTraceEndTime = 0L; - fWindowStartTime = 0L; - fWindowEndTime = 0L; - fWindowSpan = 0L; - fSelectionBeginTime = 0L; - fSelectionEndTime = 0L; - - // Clear the UI widgets - fFullTraceHistogram.clear(); - fTimeRangeHistogram.clear(); - fSelectionStartControl.setValue(Long.MIN_VALUE); - fSelectionEndControl.setValue(Long.MIN_VALUE); - - fTimeSpanControl.setValue(Long.MIN_VALUE); - - for (Control c: fLegendArea.getChildren()) { - c.dispose(); - } - if (fLegendImages != null) { - for (Image i: fLegendImages) { - i.dispose(); - } - } - fLegendImages = null; - fLegendArea.layout(); - fLegendArea.getParent().layout(); - } - - /** - * Handles trace range updated signal. Extends histogram according to the new time range. If a - * HistogramRequest is already ongoing, it will be cancelled and a new request with the new range - * will be issued. - * - * @param signal the trace range updated signal - * @since 2.0 - */ - @TmfSignalHandler - public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal) { - - if (signal.getTrace() != fTrace) { - return; - } - - TmfTimeRange fullRange = signal.getRange(); - - fTraceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - fTraceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - - fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime); - fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime); - - sendFullRangeRequest(fullRange); - } - - /** - * Handles the trace updated signal. Used to update time limits (start and end time) - * @param signal the trace updated signal - * @since 2.0 - */ - @TmfSignalHandler - public void traceUpdated(TmfTraceUpdatedSignal signal) { - if (signal.getTrace() != fTrace) { - return; - } - TmfTimeRange fullRange = signal.getTrace().getTimeRange(); - fTraceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - fTraceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - - fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime); - fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime); - - if ((fFullTraceRequest != null) && fFullTraceRequest.getRange().getEndTime().compareTo(signal.getRange().getEndTime()) < 0) { - sendFullRangeRequest(fullRange); - } -} - - /** - * Handles the current time updated signal. Sets the current time in the time range - * histogram as well as the full histogram. - * - * @param signal the signal to process - */ - @TmfSignalHandler - public void currentTimeUpdated(final TmfTimeSynchSignal signal) { - if (Display.getCurrent() == null) { - // Make sure the signal is handled in the UI thread - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - if (fParent.isDisposed()) { - return; - } - currentTimeUpdated(signal); - } - }); - return; - } - - // Update the selected time range - ITmfTimestamp beginTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE); - ITmfTimestamp endTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE); - updateDisplayedSelectionTime(beginTime.getValue(), endTime.getValue()); - } - - /** - * Updates the current time range in the time range histogram and full range histogram. - * @param signal the signal to process - */ - @TmfSignalHandler - public void timeRangeUpdated(final TmfRangeSynchSignal signal) { - if (Display.getCurrent() == null) { - // Make sure the signal is handled in the UI thread - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - if (fParent.isDisposed()) { - return; - } - timeRangeUpdated(signal); - } - }); - return; - } - - if (fTrace != null) { - // Validate the time range - TmfTimeRange range = signal.getCurrentRange().getIntersection(fTrace.getTimeRange()); - if (range == null) { - return; - } - - updateDisplayedTimeRange( - range.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(), - range.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue()); - - // Send the event request to populate the small histogram - sendTimeRangeRequest(fWindowStartTime, fWindowEndTime); - - fTimeSpanControl.setValue(fWindowSpan); - } - } - - // ------------------------------------------------------------------------ - // Helper functions - // ------------------------------------------------------------------------ - - private void initializeHistograms() { - TmfTimeRange fullRange = updateTraceTimeRange(); - long selectionBeginTime = fTraceManager.getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - long selectionEndTime = fTraceManager.getSelectionEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - long startTime = fTraceManager.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - long duration = fTraceManager.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue() - startTime; - - if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) { - fTimeRangeRequest.cancel(); - } - fTimeRangeHistogram.clear(); - fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime); - fTimeRangeHistogram.setTimeRange(startTime, duration); - fTimeRangeHistogram.setSelection(selectionBeginTime, selectionEndTime); - fTimeRangeHistogram.fDataModel.setTrace(fTrace); - - if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) { - fFullTraceRequest.cancel(); - } - fFullTraceHistogram.clear(); - fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime); - fFullTraceHistogram.setTimeRange(startTime, duration); - fFullTraceHistogram.setSelection(selectionBeginTime, selectionEndTime); - fFullTraceHistogram.fDataModel.setTrace(fTrace); - - fWindowStartTime = startTime; - fWindowSpan = duration; - fWindowEndTime = startTime + duration; - - fSelectionBeginTime = selectionBeginTime; - fSelectionEndTime = selectionEndTime; - fSelectionStartControl.setValue(fSelectionBeginTime); - fSelectionEndControl.setValue(fSelectionEndTime); - - fTimeSpanControl.setValue(duration); - - ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace); - if (traces != null) { - this.showTraceAction.setEnabled(traces.length < fFullTraceHistogram.getMaxNbTraces()); - } - updateLegendArea(); - - if (!fullRange.equals(TmfTimeRange.NULL_RANGE)) { - sendTimeRangeRequest(startTime, startTime + duration); - sendFullRangeRequest(fullRange); - } - } - - private void updateLegendArea() { - for (Control c: fLegendArea.getChildren()) { - c.dispose(); - } - if (fLegendImages != null) { - for (Image i: fLegendImages) { - i.dispose(); - } - } - fLegendImages = null; - if (fFullTraceHistogram.showTraces()) { - ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace); - fLegendImages = new Image[traces.length]; - int traceIndex = 0; - for (ITmfTrace trace : traces) { - fLegendImages[traceIndex] = new Image(fLegendArea.getDisplay(), 16, 16); - GC gc = new GC(fLegendImages[traceIndex]); - gc.setBackground(fFullTraceHistogram.getTraceColor(traceIndex)); - gc.fillRectangle(0, 0, 15, 15); - gc.setForeground(fLegendArea.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - gc.drawRectangle(0, 0, 15, 15); - gc.dispose(); - - CLabel label = new CLabel(fLegendArea, SWT.NONE); - label.setText(trace.getName()); - label.setImage(fLegendImages[traceIndex]); - traceIndex++; - } - } - fLegendArea.layout(); - fLegendArea.getParent().layout(); - } - - private void updateDisplayedSelectionTime(long beginTime, long endTime) { - fSelectionBeginTime = beginTime; - fSelectionEndTime = endTime; - - fFullTraceHistogram.setSelection(fSelectionBeginTime, fSelectionEndTime); - fTimeRangeHistogram.setSelection(fSelectionBeginTime, fSelectionEndTime); - fSelectionStartControl.setValue(fSelectionBeginTime); - fSelectionEndControl.setValue(fSelectionEndTime); - } - - private void updateDisplayedTimeRange(long start, long end) { - fWindowStartTime = start; - fWindowEndTime = end; - fWindowSpan = fWindowEndTime - fWindowStartTime; - fFullTraceHistogram.setTimeRange(fWindowStartTime, fWindowSpan); - } - - private TmfTimeRange updateTraceTimeRange() { - fTraceStartTime = 0L; - fTraceEndTime = 0L; - - TmfTimeRange timeRange = fTrace.getTimeRange(); - if (!timeRange.equals(TmfTimeRange.NULL_RANGE)) { - fTraceStartTime = timeRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - fTraceEndTime = timeRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - } - return timeRange; - } - - private void sendTimeRangeRequest(long startTime, long endTime) { - if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) { - fTimeRangeRequest.cancel(); - } - TmfTimestamp startTS = new TmfTimestamp(startTime, ITmfTimestamp.NANOSECOND_SCALE); - TmfTimestamp endTS = new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE); - TmfTimeRange timeRange = new TmfTimeRange(startTS, endTS); - - fTimeRangeHistogram.clear(); - fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime); - fTimeRangeHistogram.setTimeRange(startTime, endTime - startTime); - - int cacheSize = fTrace.getCacheSize(); - fTimeRangeRequest = new HistogramRequest(fTimeRangeHistogram.getDataModel(), - timeRange, 0, ITmfEventRequest.ALL_DATA, cacheSize, ExecutionType.FOREGROUND, false); - fTrace.sendRequest(fTimeRangeRequest); - } - - private void sendFullRangeRequest(TmfTimeRange fullRange) { - if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) { - fFullTraceRequest.cancel(); - } - int cacheSize = fTrace.getCacheSize(); - fFullTraceRequest = new HistogramRequest(fFullTraceHistogram.getDataModel(), - fullRange, - (int) fFullTraceHistogram.fDataModel.getNbEvents(), - ITmfEventRequest.ALL_DATA, - cacheSize, - ExecutionType.BACKGROUND, true); - fTrace.sendRequest(fFullTraceRequest); - } - - private void contributeToActionBars() { - IActionBars bars = getViewSite().getActionBars(); - bars.getToolBarManager().add(getShowLostEventsAction()); - bars.getToolBarManager().add(getShowTraceAction()); - bars.getToolBarManager().add(new Separator()); - } - - private void addLinkButtonListeners() { - fLinkButton.addMouseListener(new MouseAdapter() { - @Override - public void mouseDown(MouseEvent e) { - fSelectionEndControl.setEnabled(fLinkState); - fLinkState = !fLinkState; - fLinkButton.redraw(); - } - }); - - fLinkButton.addPaintListener(new PaintListener() { - @Override - public void paintControl(PaintEvent e) { - if (fLinkState) { - Rectangle r = fLinkButton.getBounds(); - r.x = -1; - r.y = -1; - e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); - e.gc.drawRectangle(r); - r.x = 0; - r.y = 0; - e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_DARK_GRAY)); - e.gc.drawRectangle(r); - } - } - }); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramZoom.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramZoom.java deleted file mode 100644 index d839fb72ca..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramZoom.java +++ /dev/null @@ -1,210 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Francois Chouinard - Moved from LTTng to TMF - * Patrick Tasse - Update for mouse wheel zoom - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.histogram; - -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseWheelListener; - -/** - * Class to handle zooming within histogram windows.. - * - * @version 1.0 - * @author Francois Chouinard - *

- */ -public class HistogramZoom implements MouseWheelListener, KeyListener { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - private final static double ZOOM_FACTOR = 0.8; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private final Histogram fHistogram; - - private long fAbsoluteStartTime; - private long fAbsoluteEndTime; - private final long fMinWindowSize; - - private long fRangeStartTime; - private long fRangeDuration; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Standard constructor. - * - * @param histogram - * The parent histogram object - * @param start - * The start time of the zoom area - * @param end - * The end time of the zoom area - * @since 2.0 - */ - public HistogramZoom(Histogram histogram, long start, long end) { - fHistogram = histogram; - fAbsoluteStartTime = start; - fAbsoluteEndTime = end; - fMinWindowSize = 0; - - fRangeStartTime = fAbsoluteStartTime; - fRangeDuration = fAbsoluteStartTime + fMinWindowSize; - - histogram.addMouseWheelListener(this); - histogram.addKeyListener(this); - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Get start time of the zoom window. - * @return the start time. - */ - public synchronized long getStartTime() { - return fRangeStartTime; - } - - /** - * Get the end time of the zoom window. - * @return the end time - */ - public synchronized long getEndTime() { - return fRangeStartTime + fRangeDuration; - } - - /** - * Get the duration of the zoom window. - * @return the duration of the zoom window. - */ - public synchronized long getDuration() { - return fRangeDuration; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * The the full time range of the histogram - * - * @param startTime the start time the histogram - * @param endTime the end time of the histogram - */ - public synchronized void setFullRange(long startTime, long endTime) { - fAbsoluteStartTime = startTime; - fAbsoluteEndTime = endTime; - } - - /** - * Sets the new zoom window - * @param startTime the start time - * @param duration the duration - */ - public synchronized void setNewRange(long startTime, long duration) { - long realStart = startTime; - - if (realStart < fAbsoluteStartTime) { - realStart = fAbsoluteStartTime; - } - - long endTime = realStart + duration; - if (endTime > fAbsoluteEndTime) { - endTime = fAbsoluteEndTime; - if (endTime - duration > fAbsoluteStartTime) { - realStart = endTime - duration; - } else { - realStart = fAbsoluteStartTime; - } - } - - fRangeStartTime = realStart; - fRangeDuration = endTime - realStart; - } - - // ------------------------------------------------------------------------ - // MouseWheelListener - // ------------------------------------------------------------------------ - - @Override - public void mouseScrolled(MouseEvent event) { - zoom(event.count); - } - - /** - * @since 3.1 - */ - @Override - public void keyPressed(KeyEvent e) { - if (e.character == '+') { - zoom(1); - } else if (e.character == '-') { - zoom(-1); - } - } - - /** - * @since 3.1 - */ - @Override - public void keyReleased(KeyEvent e) { - } - - private synchronized void zoom(int nbClicks) { - // Compute the new time range - long requestedRange = (nbClicks > 0) ? Math.round(ZOOM_FACTOR * fRangeDuration) : (long) Math.ceil(fRangeDuration * (1.0 / ZOOM_FACTOR)); - - // Distribute delta and adjust for boundaries - long requestedStart = validateStart(fRangeStartTime + (fRangeDuration - requestedRange) / 2); - long requestedEnd = validateEnd(requestedStart, requestedStart + requestedRange); - requestedStart = validateStart(requestedEnd - requestedRange); - - fHistogram.updateTimeRange(requestedStart, requestedEnd); - } - - private long validateStart(long start) { - long realStart = start; - - if (realStart < fAbsoluteStartTime) { - realStart = fAbsoluteStartTime; - } - if (realStart > fAbsoluteEndTime) { - realStart = fAbsoluteEndTime - fMinWindowSize; - } - return realStart; - } - - private long validateEnd(long start, long end) { - long realEnd = end; - - if (realEnd > fAbsoluteEndTime) { - realEnd = fAbsoluteEndTime; - } - if (realEnd < start + fMinWindowSize) { - realEnd = start + fMinWindowSize; - } - return realEnd; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/IHistogramDataModel.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/IHistogramDataModel.java deleted file mode 100644 index d18d07e65a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/IHistogramDataModel.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Francois Chouinard - Moved from LTTng to TMF - * Xavier Raynaud - Support multi-trace coloring - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.histogram; - -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.views.distribution.model.IBaseDistributionModel; - -/** - * Histogram data model interface. - * - * @version 1.0 - * @author Bernd Hufmann - */ -public interface IHistogramDataModel extends IBaseDistributionModel { - /** - * Add event to the correct bucket, compacting the if needed. - * - * @param eventCount the event to count - * @param timestamp the timestamp of the event to count - * @param trace the trace corresponding to given events - * @since 3.0 - */ - void countEvent(long eventCount, long timestamp, ITmfTrace trace); - - /** - * Scale the model data to the width, height and bar width requested. - * - * @param width A width of the histogram canvas - * @param height A height of the histogram canvas - * @param barWidth A width (in pixel) of a histogram bar - * @return the result array of size [width] and where the highest value doesn't exceed [height] - * while considering the bar width [barWidth] - */ - HistogramScaledData scaleTo(int width, int height, int barWidth); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/IHistogramModelListener.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/IHistogramModelListener.java deleted file mode 100644 index 24305e5692..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/IHistogramModelListener.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - * Francois Chouinard - Moved from LTTng to TMF - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.histogram; - -/** - * Listener interface for receiving histogram data model notifications. - * - * @version 1.0 - * @author Bernd Hufmann - */ -public interface IHistogramModelListener { - /** - * Method to implement to receive notification about model updates. - */ - void modelUpdated(); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/Messages.java deleted file mode 100644 index 4841a42bea..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/Messages.java +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * William Bourque - Initial API and implementation - * Francois Chouinard - Cleanup and refactoring - * Francois Chouinard - Moved from LTTng to TMF - * Patrick Tasse - Update for histogram selection range and tool tip - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.histogram; - -import org.eclipse.osgi.util.NLS; - -/** - * Messages file for the histogram widgets. - *

- * - * @version 1.0 - * @author Francois Chouinard - */ -public class Messages extends NLS { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.ui.views.histogram.messages"; //$NON-NLS-1$ - - /** - * @since 3.0 - */ - public static String HistogramView_showTraces; - - /** - * @since 2.2 - */ - public static String HistogramView_hideLostEvents; - /** - * The label for the selection start time - * @since 2.2 - */ - public static String HistogramView_selectionStartLabel; - /** - * The label for the selection end time - * @since 2.2 - */ - public static String HistogramView_selectionEndLabel; - /** - * The label for the window span. - */ - public static String HistogramView_windowSpanLabel; - /** - * The tool tip text for the selection span. - * @since 2.2 - */ - public static String Histogram_selectionSpanToolTip; - /** - * The tool tip text for the bucket range. - * @since 2.2 - */ - public static String Histogram_bucketRangeToolTip; - /** - * The tool tip text for the event count. - * @since 2.2 - */ - public static String Histogram_eventCountToolTip; - /** - * The tool tip text for the lost event count. - * @since 2.2 - */ - public static String Histogram_lostEventCountToolTip; - - // ------------------------------------------------------------------------ - // Initializer - // ------------------------------------------------------------------------ - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - private Messages() { - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/TimeRangeHistogram.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/TimeRangeHistogram.java deleted file mode 100644 index f3226adc82..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/TimeRangeHistogram.java +++ /dev/null @@ -1,217 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Francois Chouinard - Initial API and implementation - * Bernd Hufmann - Changed to updated histogram data model - * Francois Chouinard - Moved from LTTng to TMF - * Patrick Tasse - Update for mouse wheel zoom - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.histogram; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; - -/** - * A basic histogram widget that displays the event distribution of a specific time range of a trace. - * It has the following additional features: - *

    - *
  • zoom in: mouse wheel up (or forward) - *
  • zoom out: mouse wheel down (or backward) - *
- * - * @version 1.1 - * @author Francois Chouinard - */ -public class TimeRangeHistogram extends Histogram { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private HistogramZoom fZoom = null; - - private long fRangeStartTime = 0L; - private long fRangeDuration; - private long fFullRangeStartTime = 0L; - private long fFullRangeEndTime = 0L; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - /** - * Constructor - * @param view The parent histogram view - * @param parent The parent composite - */ - public TimeRangeHistogram(HistogramView view, Composite parent) { - super(view, parent); - fZoom = new HistogramZoom(this, getStartTime(), getTimeLimit()); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Override - public synchronized void clear() { - fRangeStartTime = 0L; - fRangeDuration = 0L; - fFullRangeStartTime = 0L; - fFullRangeEndTime = 0L; - setOffset(0); - if (fZoom != null) { - fZoom.setFullRange(0L, 0L); - fZoom.setNewRange(0L, 0L); - } - super.clear(); - } - - /** - * Sets the time range of the histogram - * @param startTime The start time - * @param duration The duration of the time range - */ - public synchronized void setTimeRange(long startTime, long duration) { - fRangeStartTime = startTime; - fRangeDuration = duration; - fZoom.setNewRange(startTime, duration); - if (getDataModel().getNbEvents() == 0) { - getDataModel().setTimeRange(startTime, startTime + duration); - getDataModel().setEndTime(startTime + duration); - } - } - - /** - * Sets the full time range of the whole trace. - * @param startTime The start time - * @param endTime The end time - */ - public void setFullRange(long startTime, long endTime) { - fFullRangeStartTime = startTime; - fFullRangeEndTime = endTime; - fZoom.setFullRange(startTime, endTime); - fZoom.setNewRange(fRangeStartTime, fRangeDuration); - } - - // ------------------------------------------------------------------------ - // MouseListener - // ------------------------------------------------------------------------ - - private int fStartPosition; - private int fMinOffset; - private int fMaxOffset; - - @Override - public void mouseDown(MouseEvent event) { - if (fScaledData != null && fDragState == DRAG_NONE && fDataModel.getStartTime() < fDataModel.getEndTime()) { - if (event.button == 2 || (event.button == 1 && (event.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL)) { - fDragState = DRAG_RANGE; - fDragButton = event.button; - fStartPosition = event.x; - long maxOffset = (fRangeStartTime - fFullRangeStartTime) / fScaledData.fBucketDuration; - long minOffset = (fRangeStartTime + fRangeDuration - fFullRangeEndTime) / fScaledData.fBucketDuration; - fMaxOffset = (int) Math.max(Integer.MIN_VALUE, Math.min(Integer.MAX_VALUE, maxOffset)); - fMinOffset = (int) Math.max(Integer.MIN_VALUE, Math.min(Integer.MAX_VALUE, minOffset)); - return; - } else if (event.button == 3) { - fDragState = DRAG_ZOOM; - fDragButton = event.button; - fRangeStartTime = Math.min(getTimestamp(event.x), getEndTime()); - fRangeDuration = 0; - fCanvas.redraw(); - return; - } - } - super.mouseDown(event); - } - - @Override - public void mouseUp(MouseEvent event) { - if (fDragState == DRAG_RANGE && event.button == fDragButton) { - fDragState = DRAG_NONE; - fDragButton = 0; - if (event.x != fStartPosition) { - int nbBuckets = event.x - fStartPosition; - long delta = nbBuckets * fScaledData.fBucketDuration; - long startTime = fRangeStartTime - delta; - fRangeStartTime = Math.max(fFullRangeStartTime, Math.min(fFullRangeEndTime - fRangeDuration, startTime)); - ((HistogramView) fParentView).updateTimeRange(fRangeStartTime, fRangeStartTime + fRangeDuration); - setOffset(0); - } - return; - } else if (fDragState == DRAG_ZOOM && event.button == fDragButton) { - fDragState = DRAG_NONE; - fDragButton = 0; - if (fRangeDuration < 0) { - fRangeStartTime = fRangeStartTime + fRangeDuration; - fRangeDuration = -fRangeDuration; - } - if (fRangeDuration > 0) { - ((HistogramView) fParentView).updateTimeRange(fRangeStartTime, fRangeStartTime + fRangeDuration); - } else { - fRangeStartTime = fZoom.getStartTime(); - fRangeDuration = fZoom.getDuration(); - fCanvas.redraw(); - } - return; - } - super.mouseUp(event); - } - - // ------------------------------------------------------------------------ - // MouseMoveListener - // ------------------------------------------------------------------------ - - @Override - public void mouseMove(MouseEvent event) { - if (fDragState == DRAG_RANGE) { - int offset = Math.max(fMinOffset, Math.min(fMaxOffset, event.x - fStartPosition)); - setOffset(offset); - fCanvas.redraw(); - return; - } else if (fDragState == DRAG_ZOOM) { - long endTime = Math.max(getStartTime(), Math.min(getEndTime(), getTimestamp(event.x))); - fRangeDuration = endTime - fRangeStartTime; - fCanvas.redraw(); - return; - } - super.mouseMove(event); - } - - // ------------------------------------------------------------------------ - // PaintListener - // ------------------------------------------------------------------------ - - @Override - public void paintControl(PaintEvent event) { - super.paintControl(event); - - if (fDragState == DRAG_ZOOM) { - Image image = (Image) fCanvas.getData(IMAGE_KEY); - assert image != null; - - Image rangeRectangleImage = new Image(image.getDevice(), image, SWT.IMAGE_COPY); - GC rangeWindowGC = new GC(rangeRectangleImage); - - drawTimeRangeWindow(rangeWindowGC, fRangeStartTime, fRangeDuration); - - // Draws the buffer image onto the canvas. - event.gc.drawImage(rangeRectangleImage, 0, 0); - - rangeWindowGC.dispose(); - rangeRectangleImage.dispose(); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/messages.properties deleted file mode 100644 index 116ec9acc3..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/messages.properties +++ /dev/null @@ -1,21 +0,0 @@ -############################################################################### -# Copyright (c) 2013, 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### - -HistogramView_hideLostEvents=Hide Lost Events -HistogramView_showTraces=Activate Trace Coloring -HistogramView_selectionStartLabel=Selection Start -HistogramView_selectionEndLabel=Selection End -HistogramView_windowSpanLabel=Window Span -Histogram_selectionSpanToolTip=Selection Span = {0} -Histogram_bucketRangeToolTip=Bucket Range = [{0},{1}) -Histogram_eventCountToolTip=Event count = {0} -Histogram_lostEventCountToolTip=Lost event count = {0} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statesystem/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statesystem/Messages.java deleted file mode 100644 index c2bb33dbf1..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statesystem/Messages.java +++ /dev/null @@ -1,86 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Montplaisir - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.statesystem; - -import org.eclipse.osgi.util.NLS; - -/** - * Localizable strings in the State System Visualizer. - * - * @author Alexandre Montplaisir - * @since 2.0 - */ -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.ui.views.statesystem.messages"; //$NON-NLS-1$ - - /** - * Initializer - */ - static { - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - /** - * Private constructor (static class) - */ - private Messages() {} - - /** Label for the first column */ - public static String TreeNodeColumnLabel; - - /** Label for the "quark" column" */ - public static String QuarkColumnLabel; - - /** Label for the "value" column */ - public static String ValueColumnLabel; - - /** Label for the "type" column - * @since 2.1*/ - public static String TypeColumnLabel; - - /** Label for the "start time" column */ - public static String StartTimeColumLabel; - - /** Label for the "end time" column */ - public static String EndTimeColumLabel; - - /** Label for the "attribute path" column */ - public static String AttributePathColumnLabel; - - /** - * Printing "out of range" in the value column when the current timestamp is - * outside of the SS's range. - */ - public static String OutOfRangeMsg; - - /** Label for the Filter button - * @since 2.1*/ - public static String FilterButton; - - /** Label for the type Interger - * @since 2.1*/ - public static String TypeInteger; - - /** Label for the type Long - * @since 2.1*/ - public static String TypeLong; - - /** Label for type Double - * @since 3.0*/ - public static String TypeDouble; - - /** Label for the type String - * @since 2.1*/ - public static String TypeString; -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statesystem/TmfStateSystemExplorer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statesystem/TmfStateSystemExplorer.java deleted file mode 100644 index 6ea40e6f1d..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statesystem/TmfStateSystemExplorer.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 École Polytechnique de Montréal, Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Florian Wininger - Initial API and implementation - * Alexandre Montplaisir - Refactoring, performance tweaks - * Bernd Hufmann - Updated signal handling - * Marc-Andre Laperle - Add time zone preference - * Geneviève Bastien - Use a tree viewer instead of a tree - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.statesystem; - -import java.io.File; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.views.TmfView; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.IActionBars; - -/** - * Displays the State System at a current time. - * - * @author Florian Wininger - * @author Alexandre Montplaisir - * @since 2.0 - */ -public class TmfStateSystemExplorer extends TmfView { - - /** The Environment View's ID */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.ssview"; //$NON-NLS-1$ - - private static final Image FILTER_IMAGE = - Activator.getDefault().getImageFromPath( File.separator + "icons" + File.separator + "elcl16" + File.separator + "filter_items.gif"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - - private TmfStateSystemViewer fViewer; - - /** - * Default constructor - */ - public TmfStateSystemExplorer() { - super(ID); - } - - // ------------------------------------------------------------------------ - // ViewPart - // ------------------------------------------------------------------------ - - @Override - public void createPartControl(Composite parent) { - - fViewer = new TmfStateSystemViewer(parent); - - fillToolBar() ; - - ITmfTrace trace = getActiveTrace(); - if (trace != null) { - fViewer.traceSelected(new TmfTraceSelectedSignal(this, trace)); - } - - } - - // ------------------------------------------------------------------------ - // Part For Button Action - // ------------------------------------------------------------------------ - - private void fillToolBar() { - Action fFilterAction = new FilterAction(); - fFilterAction.setImageDescriptor(ImageDescriptor.createFromImage(FILTER_IMAGE)); - fFilterAction.setToolTipText(Messages.FilterButton) ; - fFilterAction.setChecked(false); - - IActionBars bars = getViewSite().getActionBars(); - IToolBarManager manager = bars.getToolBarManager(); - manager.add(fFilterAction); - } - - private class FilterAction extends Action { - @Override - public void run() { - fViewer.changeFilterStatus(); - } - } - - @Override - public void setFocus() { - } - - @Override - public void dispose() { - super.dispose(); - if (fViewer != null) { - fViewer.dispose(); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statesystem/TmfStateSystemViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statesystem/TmfStateSystemViewer.java deleted file mode 100644 index cd1db48635..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statesystem/TmfStateSystemViewer.java +++ /dev/null @@ -1,463 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Florian Wininger - Initial API and implementation - * Alexandre Montplaisir - Refactoring, performance tweaks - * Bernd Hufmann - Updated signal handling - * Marc-Andre Laperle - Add time zone preference - * Geneviève Bastien - Moved state system explorer to use the abstract tree viewer - * Patrick Tasse - Refactoring - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.statesystem; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jface.viewers.AbstractTreeViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerComparator; -import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; -import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; -import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; -import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimestampFormatUpdateSignal; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfAnalysisModuleWithStateSystems; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ui.viewers.tree.AbstractTmfTreeViewer; -import org.eclipse.linuxtools.tmf.ui.viewers.tree.ITmfTreeColumnDataProvider; -import org.eclipse.linuxtools.tmf.ui.viewers.tree.ITmfTreeViewerEntry; -import org.eclipse.linuxtools.tmf.ui.viewers.tree.TmfTreeColumnData; -import org.eclipse.linuxtools.tmf.ui.viewers.tree.TmfTreeViewerEntry; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; - -/** - * Displays the content of the state systems at the current time - * - * @author Florian Wininger - * @author Alexandre Montplaisir - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfStateSystemViewer extends AbstractTmfTreeViewer { - - private static final String EMPTY_STRING = ""; //$NON-NLS-1$ - private static final int DEFAULT_AUTOEXPAND = 2; - private boolean fFilterStatus = false; - private long fSelection = 0; - - /* Order of columns */ - private static final int ATTRIBUTE_NAME_COL = 0; - private static final int QUARK_COL = 1; - private static final int VALUE_COL = 2; - private static final int TYPE_COL = 3; - private static final int START_TIME_COL = 4; - private static final int END_TIME_COL = 5; - private static final int ATTRIBUTE_FULLPATH_COL = 6; - - /** - * Base class to provide the labels for the tree viewer. Views extending - * this class typically need to override the getColumnText method if they - * have more than one column to display - */ - protected static class StateSystemTreeLabelProvider extends TreeLabelProvider { - - @Override - public String getColumnText(Object element, int columnIndex) { - if (element instanceof StateEntry) { - StateEntry entry = (StateEntry) element; - switch (columnIndex) { - case ATTRIBUTE_NAME_COL: - return entry.getName(); - case QUARK_COL: - return String.valueOf(entry.getQuark()); - case VALUE_COL: - return entry.getValue(); - case TYPE_COL: - return entry.getType(); - case START_TIME_COL: - return entry.getStartTime(); - case END_TIME_COL: - return entry.getEndTime(); - case ATTRIBUTE_FULLPATH_COL: - return entry.getFullPath(); - default: - return EMPTY_STRING; - } - } - return super.getColumnText(element, columnIndex); - } - - @Override - public Color getBackground(Object element, int columnIndex) { - if (element instanceof StateEntry) { - if (((StateEntry) element).isModified()) { - return Display.getCurrent().getSystemColor(SWT.COLOR_YELLOW); - } - } - return super.getBackground(element, columnIndex); - } - } - - /** - * Constructor - * - * @param parent - * The parent containing this viewer - */ - public TmfStateSystemViewer(Composite parent) { - super(parent, false); - this.setLabelProvider(new StateSystemTreeLabelProvider()); - getTreeViewer().setAutoExpandLevel(DEFAULT_AUTOEXPAND); - } - - @Override - protected ITmfTreeColumnDataProvider getColumnDataProvider() { - return new ITmfTreeColumnDataProvider() { - - @Override - public List getColumnData() { - List columns = new ArrayList<>(); - TmfTreeColumnData column = new TmfTreeColumnData(Messages.TreeNodeColumnLabel); - columns.add(column); - column.setComparator(new ViewerComparator() { - @Override - public int compare(Viewer viewer, Object e1, Object e2) { - TmfTreeViewerEntry n1 = (TmfTreeViewerEntry) e1; - TmfTreeViewerEntry n2 = (TmfTreeViewerEntry) e2; - - return n1.getName().compareTo(n2.getName()); - } - }); - columns.add(new TmfTreeColumnData(Messages.QuarkColumnLabel)); - columns.add(new TmfTreeColumnData(Messages.ValueColumnLabel)); - columns.add(new TmfTreeColumnData(Messages.TypeColumnLabel)); - columns.add(new TmfTreeColumnData(Messages.StartTimeColumLabel)); - columns.add(new TmfTreeColumnData(Messages.EndTimeColumLabel)); - columns.add(new TmfTreeColumnData(Messages.AttributePathColumnLabel)); - return columns; - } - - }; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Override - protected ITmfTreeViewerEntry updateElements(long start, long end, boolean selection) { - - if (selection) { - fSelection = start; - } else { - fSelection = TmfTraceManager.getInstance().getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - } - - if (getTrace() == null) { - return null; - } - - ITmfTreeViewerEntry root = getInput(); - - if (root == null) { - root = createRoot(); - } else if (fFilterStatus) { - clearStateSystemEntries(root); - } - - /* - * Update the values of the elements of the state systems at the - * selection start time - */ - boolean changed = updateStateSystemEntries(root, fSelection); - - return selection || changed ? root : null; - } - - private ITmfTreeViewerEntry createRoot() { - // 'Fake' root node - TmfTreeViewerEntry rootEntry = new TmfTreeViewerEntry("root"); //$NON-NLS-1$ - - for (final ITmfTrace trace : TmfTraceManager.getTraceSetWithExperiment(getTrace())) { - if (trace != null) { - rootEntry.addChild(createTraceEntry(trace)); - } - } - return rootEntry; - } - - private static TmfTreeViewerEntry createTraceEntry(ITmfTrace trace) { - TmfTreeViewerEntry traceEntry = new TmfTreeViewerEntry(trace.getName()); - Iterable modules = trace.getAnalysisModulesOfClass(ITmfAnalysisModuleWithStateSystems.class); - for (ITmfAnalysisModuleWithStateSystems module : modules) { - /* Just schedule the module, the data will be filled when available */ - module.schedule(); - if (module instanceof TmfStateSystemAnalysisModule) { - // TODO: add this method to ITmfAnalysisModuleWithStateSystems - ((TmfStateSystemAnalysisModule) module).waitForInitialization(); - } - for (ITmfStateSystem ss : module.getStateSystems()) { - if (ss != null) { - traceEntry.addChild(new StateSystemEntry(ss)); - } - } - } - return traceEntry; - } - - private static void clearStateSystemEntries(ITmfTreeViewerEntry root) { - for (ITmfTreeViewerEntry traceEntry : root.getChildren()) { - for (ITmfTreeViewerEntry ssEntry : traceEntry.getChildren()) { - ssEntry.getChildren().clear(); - } - } - } - - private boolean updateStateSystemEntries(ITmfTreeViewerEntry root, long timestamp) { - boolean changed = false; - for (ITmfTreeViewerEntry traceEntry : root.getChildren()) { - for (ITmfTreeViewerEntry ssEntry : traceEntry.getChildren()) { - StateSystemEntry stateSystemEntry = (StateSystemEntry) ssEntry; - ITmfStateSystem ss = stateSystemEntry.getSS(); - try { - List fullState = ss.queryFullState(timestamp); - changed |= updateStateEntries(ss, fullState, stateSystemEntry, -1, timestamp); - } catch (TimeRangeException e) { - markOutOfRange(stateSystemEntry); - changed = true; - } catch (StateSystemDisposedException e) { - /* Ignored */ - } - } - } - return changed; - } - - private boolean updateStateEntries(ITmfStateSystem ss, List fullState, TmfTreeViewerEntry parent, int parentQuark, long timestamp) { - boolean changed = false; - try { - for (int quark : ss.getSubAttributes(parentQuark, false)) { - if (quark >= fullState.size()) { - // attribute was created after the full state query - continue; - } - ITmfStateInterval interval = fullState.get(quark); - StateEntry stateEntry = findStateEntry(parent, quark); - if (stateEntry == null) { - boolean modified = fFilterStatus ? - interval.getStartTime() == timestamp : - !interval.getStateValue().isNull(); - stateEntry = new StateEntry(ss.getAttributeName(quark), quark, ss.getFullAttributePath(quark), - interval.getStateValue(), - new TmfTimestamp(interval.getStartTime(), ITmfTimestamp.NANOSECOND_SCALE), - new TmfTimestamp(interval.getEndTime(), ITmfTimestamp.NANOSECOND_SCALE), - modified); - - // update children first to know if parent is really needed - updateStateEntries(ss, fullState, stateEntry, quark, timestamp); - - /* - * Add this entry to parent if filtering is off, or - * if the entry has children to display, or - * if there is a state change at the current timestamp - */ - if (!fFilterStatus || stateEntry.hasChildren() || interval.getStartTime() == timestamp) { - parent.addChild(stateEntry); - changed = true; - } - } else { - stateEntry.update(interval.getStateValue(), - new TmfTimestamp(interval.getStartTime(), ITmfTimestamp.NANOSECOND_SCALE), - new TmfTimestamp(interval.getEndTime(), ITmfTimestamp.NANOSECOND_SCALE)); - - // update children recursively - updateStateEntries(ss, fullState, stateEntry, quark, timestamp); - } - - } - } catch (AttributeNotFoundException e) { - /* Should not happen, we're iterating on known attributes */ - } - return changed; - } - - private static StateEntry findStateEntry(TmfTreeViewerEntry parent, int quark) { - for (ITmfTreeViewerEntry child : parent.getChildren()) { - StateEntry stateEntry = (StateEntry) child; - if (stateEntry.getQuark() == quark) { - return stateEntry; - } - } - return null; - } - /** - * Set the entries as out of range - */ - private static void markOutOfRange(ITmfTreeViewerEntry parent) { - for (ITmfTreeViewerEntry entry : parent.getChildren()) { - if (entry instanceof StateEntry) { - ((StateEntry) entry).setOutOfRange(); - - /* Update this node's children recursively */ - markOutOfRange(entry); - } - } - } - - /** - * Set the filter status of the viewer. By default, all entries of all state - * system are present, and the values that changed since last refresh are - * shown in yellow. When the filter status is true, only the entries with - * values modified at current time are displayed. - */ - public void changeFilterStatus() { - fFilterStatus = !fFilterStatus; - if (fFilterStatus) { - getTreeViewer().setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS); - } else { - getTreeViewer().setAutoExpandLevel(DEFAULT_AUTOEXPAND); - clearContent(); - } - updateContent(getSelectionBeginTime(), getSelectionEndTime(), true); - } - - /** - * Update the display to use the updated timestamp format - * - * @param signal - * the incoming signal - */ - @TmfSignalHandler - public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) { - updateContent(getSelectionBeginTime(), getSelectionEndTime(), true); - } - - private static class StateSystemEntry extends TmfTreeViewerEntry { - private final @NonNull ITmfStateSystem fSS; - - public StateSystemEntry(@NonNull ITmfStateSystem ss) { - super(ss.getSSID()); - fSS = ss; - } - - public @NonNull ITmfStateSystem getSS() { - return fSS; - } - } - - private class StateEntry extends TmfTreeViewerEntry { - - private final int fQuark; - private final String fFullPath; - private @NonNull TmfTimestamp fStart; - private @NonNull TmfTimestamp fEnd; - private ITmfStateValue fValue; - private boolean fModified; - private boolean fOutOfRange = false; - - public StateEntry(String name, int quark, String fullPath, ITmfStateValue value, @NonNull TmfTimestamp start, @NonNull TmfTimestamp end, boolean modified) { - super(name); - fQuark = quark; - fFullPath = fullPath; - fStart = start; - fEnd = end; - fValue = value; - fModified = modified; - } - - public int getQuark() { - return fQuark; - } - - public String getFullPath() { - return fFullPath; - } - - public String getStartTime() { - if (fOutOfRange) { - return EMPTY_STRING; - } - return fStart.toString(); - } - - public String getEndTime() { - if (fOutOfRange) { - return EMPTY_STRING; - } - return fEnd.toString(); - } - - public String getValue() { - if (fOutOfRange) { - return Messages.OutOfRangeMsg; - } - switch (fValue.getType()) { - case INTEGER: - case LONG: - case DOUBLE: - case STRING: - return fValue.toString(); - case NULL: - default: - return EMPTY_STRING; - } - } - - public String getType() { - if (fOutOfRange) { - return EMPTY_STRING; - } - switch (fValue.getType()) { - case INTEGER: - return Messages.TypeInteger; - case LONG: - return Messages.TypeLong; - case DOUBLE: - return Messages.TypeDouble; - case STRING: - return Messages.TypeString; - case NULL: - default: - return EMPTY_STRING; - } - } - - public boolean isModified() { - return fModified; - } - - public void update(ITmfStateValue value, @NonNull TmfTimestamp start, @NonNull TmfTimestamp end) { - fModified = false; - fOutOfRange = false; - if (!start.equals(fStart)) { - fModified = true; - fStart = start; - fEnd = end; - fValue = value; - } - } - - public void setOutOfRange() { - fModified = false; - fOutOfRange = true; - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statesystem/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statesystem/messages.properties deleted file mode 100644 index 33a5a3d741..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statesystem/messages.properties +++ /dev/null @@ -1,28 +0,0 @@ -############################################################################### -# Copyright (c) 2013 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### - -# Column names -TreeNodeColumnLabel=State System / Attribute -QuarkColumnLabel=Quark -ValueColumnLabel=Value at timestamp -TypeColumnLabel=Type -StartTimeColumLabel=Start time -EndTimeColumLabel=End time -AttributePathColumnLabel=Full attribute path - -# Other messages -OutOfRangeMsg=Out of Range -FilterButton=Only Display Changes at Selected Timestamp -TypeInteger=Int -TypeLong=Long -TypeDouble=Double -TypeString=String diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statistics/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statistics/Messages.java deleted file mode 100755 index 8284082f76..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statistics/Messages.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial API and Implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.statistics; - -import org.eclipse.osgi.util.NLS; - -/** - * Messages file for statistics view strings. - * - * @version 2.0 - * @author Mathieu Denis - * @since 2.0 - */ -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.ui.views.statistics.messages"; //$NON-NLS-1$ - - /** - * String for the global tab name - * @since 2.0 - */ - public static String TmfStatisticsView_GlobalTabName; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statistics/TmfStatisticsView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statistics/TmfStatisticsView.java deleted file mode 100755 index 140e0b329f..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statistics/TmfStatisticsView.java +++ /dev/null @@ -1,230 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Generalized version based on LTTng - * Bernd Hufmann - Updated to use trace reference in TmfEvent and streaming - * Mathieu Denis - New request added to update the statistics from the selected time range - * Mathieu Denis - Generalization of the view to instantiate a viewer specific to a trace type - * - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.statistics; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.viewers.ITmfViewer; -import org.eclipse.linuxtools.tmf.ui.viewers.statistics.TmfStatisticsViewer; -import org.eclipse.linuxtools.tmf.ui.views.TmfView; -import org.eclipse.linuxtools.tmf.ui.widgets.tabsview.TmfViewerFolder; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Shell; - -/** - * The generic Statistics View displays statistics for any kind of traces. - * - * It is implemented according to the MVC pattern. - The model is a - * TmfStatisticsTreeNode built by the State Manager. - The view is built with a - * TreeViewer. - The controller that keeps model and view synchronized is an - * observer of the model. - * - * @version 2.0 - * @author Mathieu Denis - */ -public class TmfStatisticsView extends TmfView { - - /** - * The ID corresponds to the package in which this class is embedded. - */ - public static final @NonNull String ID = "org.eclipse.linuxtools.tmf.ui.views.statistics"; //$NON-NLS-1$ - - /** - * The view name. - */ - public static final String TMF_STATISTICS_VIEW = "StatisticsView"; //$NON-NLS-1$ - - /** - * The viewer that builds the columns to show the statistics. - * - * @since 2.0 - */ - protected final TmfViewerFolder fStatsViewers; - - /** - * Stores a reference to the selected trace. - */ - private ITmfTrace fTrace; - - /** - * Constructor of a statistics view. - * - * @param viewName The name to give to the view. - */ - public TmfStatisticsView(String viewName) { - super(viewName); - /* - * Create a fake parent for initialization purpose, than set the parent - * as soon as createPartControl is called. - */ - Composite temporaryParent = new Shell(); - fStatsViewers = new TmfViewerFolder(temporaryParent); - } - - /** - * Default constructor. - */ - public TmfStatisticsView() { - this(TMF_STATISTICS_VIEW); - } - - @Override - public void createPartControl(Composite parent) { - fStatsViewers.setParent(parent); - createStatisticsViewers(); - - ITmfTrace trace = getActiveTrace(); - if (trace != null) { - traceSelected(new TmfTraceSelectedSignal(this, trace)); - } - } - - @Override - public void dispose() { - super.dispose(); - fStatsViewers.dispose(); - } - - /** - * Handler called when an trace is opened. - * - * @param signal - * Contains the information about the selection. - * @since 2.0 - */ - @TmfSignalHandler - public void traceOpened(TmfTraceOpenedSignal signal) { - /* - * Dispose the current viewer and adapt the new one to the trace - * type of the trace opened - */ - fStatsViewers.clear(); - // Update the current trace - fTrace = signal.getTrace(); - createStatisticsViewers(); - fStatsViewers.layout(); - } - - /** - * Handler called when an trace is selected. Checks if the trace - * has changed and requests the selected trace if it has not yet been - * cached. - * - * @param signal - * Contains the information about the selection. - * @since 2.0 - */ - @TmfSignalHandler - public void traceSelected(TmfTraceSelectedSignal signal) { - // Does not reload the same trace if already opened - if (signal.getTrace() != fTrace) { - /* - * Dispose the current viewer and adapt the new one to the trace - * type of the trace selected - */ - fStatsViewers.clear(); - // Update the current trace - fTrace = signal.getTrace(); - createStatisticsViewers(); - fStatsViewers.layout(); - - TmfTraceRangeUpdatedSignal updateSignal = new TmfTraceRangeUpdatedSignal(this, fTrace, fTrace.getTimeRange()); - - for (ITmfViewer viewer : fStatsViewers.getViewers()) { - TmfStatisticsViewer statsViewer = (TmfStatisticsViewer) viewer; - statsViewer.sendPartialRequestOnNextUpdate(); - statsViewer.traceRangeUpdated(updateSignal); - } - } else { - /* - * If the same trace is reselected, sends a notification to - * the viewers to make sure they reload correctly their partial - * event count. - */ - for (ITmfViewer viewer : fStatsViewers.getViewers()) { - TmfStatisticsViewer statsViewer = (TmfStatisticsViewer) viewer; - // Will update the partial event count if needed. - statsViewer.sendPartialRequestOnNextUpdate(); - } - } - } - - /** - * @param signal the incoming signal - * @since 2.0 - */ - @TmfSignalHandler - public void traceClosed(TmfTraceClosedSignal signal) { - if (signal.getTrace() != fTrace) { - return; - } - - // Clear the internal data - fTrace = null; - - // Clear the UI widgets - fStatsViewers.clear(); // Also cancels ongoing requests - createStatisticsViewers(); - fStatsViewers.layout(); - } - - @Override - public void setFocus() { - fStatsViewers.setFocus(); - } - - /** - * Creates the statistics viewers for all traces in an experiment and - * populates a viewer folder. Each viewer is placed in a different tab and - * the first one is selected automatically. - * - * It uses the extension point that defines the statistics viewer to build - * from the trace type. If no viewer is defined, another tab won't be - * created, since the global viewer already contains all the basic - * statistics. If there is no trace selected, a global statistics viewer will - * still be created. - * - * @since 2.0 - */ - protected void createStatisticsViewers() { - // Default style for the tabs that will be created - int defaultStyle = SWT.NONE; - - // The folder composite that will contain the tabs - Composite folder = fStatsViewers.getParentFolder(); - - // Instantiation of the global viewer - if (fTrace != null) { - // Shows the name of the trace in the global tab - TmfStatisticsViewer globalViewer = new TmfStatisticsViewer(folder, Messages.TmfStatisticsView_GlobalTabName + " - " + fTrace.getName(), fTrace); //$NON-NLS-1$ - fStatsViewers.addTab(globalViewer, Messages.TmfStatisticsView_GlobalTabName, defaultStyle); - - } else { - // There is no trace selected. Shows an empty global tab - TmfStatisticsViewer globalViewer = new TmfStatisticsViewer(folder, Messages.TmfStatisticsView_GlobalTabName, fTrace); - fStatsViewers.addTab(globalViewer, Messages.TmfStatisticsView_GlobalTabName, defaultStyle); - } - // Makes the global viewer visible - fStatsViewers.setSelection(0); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statistics/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statistics/messages.properties deleted file mode 100755 index 1a7d06c1e2..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/statistics/messages.properties +++ /dev/null @@ -1,13 +0,0 @@ -############################################################################### -# Copyright (c) 2013 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### - -TmfStatisticsView_GlobalTabName=Global diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/Messages.java deleted file mode 100644 index 41351a01ed..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/Messages.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.synchronization; - -import org.eclipse.osgi.util.NLS; - -/** - * Message file for the synchronization view - * @since 3.0 - */ -@SuppressWarnings("javadoc") -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.ui.views.synchronization.messages"; //$NON-NLS-1$ - public static String TmfSynchronizationView_NameColumn; - public static String TmfSynchronizationView_ValueColumn; - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/TmfSynchronizationView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/TmfSynchronizationView.java deleted file mode 100644 index c8188061ae..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/TmfSynchronizationView.java +++ /dev/null @@ -1,156 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial implementation and API - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.synchronization; - -import java.util.Map; - -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSynchronizedSignal; -import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithm; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ui.views.TmfView; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.TreeColumn; -import org.eclipse.swt.widgets.TreeItem; - -/** - * Small view to display statistics about a synchronization - * - * @author Geneviève Bastien - * @since 3.0 - */ -public class TmfSynchronizationView extends TmfView { - - /** - * The ID corresponds to the package in which this class is embedded. - */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.synchronization"; //$NON-NLS-1$ - - /** - * The view name. - */ - public static final String TMF_SYNCHRONIZATION_VIEW = "SynchronizationView"; //$NON-NLS-1$ - - /** - * The synchronization algorithm to display stats for - */ - private SynchronizationAlgorithm fAlgoSync; - - private Tree fTree; - - /** - * Default constructor - */ - public TmfSynchronizationView() { - super(TMF_SYNCHRONIZATION_VIEW); - } - - @Override - public void createPartControl(Composite parent) { - fTree = new Tree(parent, SWT.NONE); - TreeColumn nameCol = new TreeColumn(fTree, SWT.NONE, 0); - TreeColumn valueCol = new TreeColumn(fTree, SWT.NONE, 1); - nameCol.setText(Messages.TmfSynchronizationView_NameColumn); - valueCol.setText(Messages.TmfSynchronizationView_ValueColumn); - - fTree.setItemCount(0); - - fTree.setHeaderVisible(true); - nameCol.pack(); - valueCol.pack(); - - ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace(); - if (trace != null) { - traceSelected(new TmfTraceSelectedSignal(this, trace)); - } - } - - private void updateTable() { - fTree.setItemCount(0); - if (fAlgoSync == null) { - return; - } - - for (Map.Entry> entry : fAlgoSync.getStats().entrySet()) { - TreeItem item = new TreeItem(fTree, SWT.NONE); - item.setText(0, entry.getKey().toString()); - item.setText(1, entry.getValue().toString()); - - for (Map.Entry subentry : entry.getValue().entrySet()) { - TreeItem subitem = new TreeItem(item, SWT.NONE); - subitem.setText(0, subentry.getKey().toString()); - subitem.setText(1, subentry.getValue().toString()); - } - } - - /* Expand the tree items */ - for (int i = 0; i < fTree.getItemCount(); i++) { - fTree.getItem(i).setExpanded(true); - } - - for (TreeColumn column : fTree.getColumns()) { - column.pack(); - } - } - - @Override - public void setFocus() { - fTree.setFocus(); - } - - /** - * Handler called when a trace is selected - * - * @param signal - * Contains information about the selected trace - * @since 3.1 - */ - @TmfSignalHandler - public void traceSelected(TmfTraceSelectedSignal signal) { - fAlgoSync = null; - if (signal.getTrace() instanceof TmfExperiment) { - fAlgoSync = ((TmfExperiment) signal.getTrace()).synchronizeTraces(); - } - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - updateTable(); - } - }); - } - - /** - * Handler called when traces are synchronized - * - * @param signal - * Contains the information about the selection. - */ - @TmfSignalHandler - public void traceSynchronized(TmfTraceSynchronizedSignal signal) { - if (signal.getSyncAlgo() != fAlgoSync) { - fAlgoSync = signal.getSyncAlgo(); - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - updateTable(); - } - }); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/messages.properties deleted file mode 100644 index 86c84fe49e..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/messages.properties +++ /dev/null @@ -1,13 +0,0 @@ -############################################################################### -# Copyright (c) 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### -TmfSynchronizationView_NameColumn=Synchronization Information -TmfSynchronizationView_ValueColumn=Value diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartAnalysisEntry.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartAnalysisEntry.java deleted file mode 100644 index f2309ac626..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartAnalysisEntry.java +++ /dev/null @@ -1,277 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.timechart; - -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Vector; - -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; - -/** - * An entry (row) in the time chart analysis view - * - * @version 1.0 - * @author Patrick Tasse - */ -public class TimeChartAnalysisEntry implements ITimeGraphEntry { - - private final ITmfTrace fTrace; - private final Vector fTraceEvents; - private int fPower = 0; // 2^fPower nanoseconds per vector position - private long fReferenceTime = -1; // time corresponding to beginning of index 0 - private long fStartTime = -1; // time of first event - private long fStopTime = -1; // time of last event - private long fLastRank = -1; // rank of last processed trace event - - TimeChartAnalysisEntry(ITmfTrace trace, int modelSize) { - fTrace = trace; - fTraceEvents = new Vector<>(modelSize); - } - - /** - * @since 2.0 - */ - @Override - public List getChildren() { - return null; - } - - @Override - public ITimeGraphEntry getParent() { - return null; - } - - @Override - public boolean hasChildren() { - return false; - } - - @Override - public String getName() { - return fTrace.getName(); - } - - @Override - public long getStartTime() { - return fStartTime; - } - - @Override - public long getEndTime() { - return fStopTime; - } - - @Override - public boolean hasTimeEvents() { - return true; - } - - @Override - public Iterator getTimeEventsIterator() { - return new EntryIterator(0, Long.MAX_VALUE, 0); - } - - @Override - public Iterator getTimeEventsIterator(long startTime, long stopTime, long maxDuration) { - return new EntryIterator(startTime, stopTime, maxDuration); - } - - private class EntryIterator implements Iterator { - private final long fIteratorStartTime; - private final long fIteratorStopTime; - private final long fIteratorMaxDuration; - private long lastTime = -1; - private TimeChartEvent next = null; - private Iterator nestedIterator = null; - - public EntryIterator(long startTime, long stopTime, long maxDuration) { - fIteratorStartTime = startTime; - fIteratorStopTime = stopTime; - fIteratorMaxDuration = maxDuration; - } - - @Override - public boolean hasNext() { - synchronized (fTraceEvents) { - if (next != null) { - return true; - } - if (nestedIterator != null) { - if (nestedIterator.hasNext()) { - return true; - } - nestedIterator = null; - } - long time = (lastTime == -1) ? fStartTime : lastTime; - int index = (fReferenceTime == -1) ? 0 : (int) ((time - fReferenceTime) >> fPower); - while (index < fTraceEvents.size()) { - TimeChartEvent event = fTraceEvents.get(index++); - if (event != null && (lastTime == -1 || event.getTime() > time)) { - if (event.getTime() + event.getDuration() >= fIteratorStartTime && event.getTime() <= fIteratorStopTime) { - if (event.getItemizedEntry() == null || event.getDuration() <= fIteratorMaxDuration) { - lastTime = event.getTime() + event.getDuration(); - next = event; - return true; - } - nestedIterator = event.getItemizedEntry().getTimeEventsIterator(fIteratorStartTime, fIteratorStopTime, fIteratorMaxDuration); - return nestedIterator.hasNext(); - } - } - } - return false; - } - } - - @Override - public TimeChartEvent next() { - synchronized (fTraceEvents) { - if (nestedIterator != null) { - TimeChartEvent event = (TimeChartEvent) nestedIterator.next(); - lastTime = event.getTime() + event.getDuration(); - return event; - } - if (hasNext()) { - TimeChartEvent event = next; - next = null; - return event; - } - throw new NoSuchElementException(); - } - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - } - - /** - * Add a time event to the time chart entry - * - * @param timeEvent - * The event to add - */ - public void addTraceEvent(ITimeEvent timeEvent) { - long time = timeEvent.getTime(); - synchronized (fTraceEvents) { - long index = (fReferenceTime == -1) ? 0 : (time - fReferenceTime) >> fPower; - if (index < 0) { - if (fTraceEvents.capacity() - fTraceEvents.size() < -index) { - int powershift = (-index + fTraceEvents.size() <= 2 * fTraceEvents.capacity()) ? 1 : - (int) Math.ceil(Math.log((double) (-index + fTraceEvents.size()) / fTraceEvents.capacity()) / Math.log(2)); - merge(powershift); - index = (int) ((time - fReferenceTime) >> fPower); - } - shift((int) -index); - index = 0; - fTraceEvents.set(0, (TimeChartEvent) timeEvent); - } else if (index < fTraceEvents.capacity()) { - if (index >= fTraceEvents.size()) { - fTraceEvents.setSize((int) index + 1); - } - } else { - int powershift = (index < 2 * fTraceEvents.capacity()) ? 1 : - (int) Math.ceil(Math.log((double) (index + 1) / fTraceEvents.capacity()) / Math.log(2)); - merge(powershift); - index = (int) ((time - fReferenceTime) >> fPower); - fTraceEvents.setSize((int) index + 1); - } - TimeChartEvent event = fTraceEvents.get((int) index); - if (event == null) { - fTraceEvents.set((int) index, (TimeChartEvent) timeEvent); - } else { - if (event.getItemizedEntry() == null) { - event.merge((TimeChartEvent) timeEvent); - } else { - event.mergeDecorations((TimeChartEvent) timeEvent); - event.getItemizedEntry().addTraceEvent(timeEvent); - } - } - if (fReferenceTime == -1 || time < fReferenceTime) { - fReferenceTime = (time >> fPower) << fPower; - } - if (fStartTime == -1 || time < fStartTime) { - fStartTime = time; - } - if (fStopTime == -1 || time > fStopTime) { - fStopTime = time; - } - } - } - - private void merge(int powershift) { - fPower += powershift; - fReferenceTime = (fReferenceTime >> fPower) << fPower; - int index = 0; - for (int i = 0; i < fTraceEvents.size(); i++) { - TimeChartEvent event = fTraceEvents.get(i); - if (event != null) { - index = (int) ((event.getTime() - fReferenceTime) >> fPower); - TimeChartEvent mergedEvent = fTraceEvents.get(index); - if (mergedEvent == null) { - fTraceEvents.set(index, event); - } else { - mergedEvent.merge(event); - } - if (i != index) { - fTraceEvents.set(i, null); - } - } - } - fTraceEvents.setSize(index + 1); - } - - private void shift(int indexshift) { - int oldSize = fTraceEvents.size(); - fTraceEvents.setSize(oldSize + indexshift); - for (int i = oldSize - 1; i >= 0; i--) { - fTraceEvents.set(i + indexshift, fTraceEvents.get(i)); - } - for (int i = 0; i < indexshift; i++) { - fTraceEvents.set(i, null); - } - } - - /** - * Retrieve the trace associated with this entry - * - * @return The trace object - */ - public ITmfTrace getTrace() { - return fTrace; - } - - /** - * Set the last rank of the entry - * - * @param rank - * The rank to set - */ - public void setLastRank(long rank) { - fLastRank = rank; - } - - /** - * Retrieve the last rank of the entry - * - * @return The last rank - */ - public long getLastRank() { - return fLastRank; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartAnalysisProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartAnalysisProvider.java deleted file mode 100644 index 48ade80f3a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartAnalysisProvider.java +++ /dev/null @@ -1,108 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.timechart; - -import org.eclipse.linuxtools.tmf.ui.views.colors.ColorSetting; -import org.eclipse.linuxtools.tmf.ui.views.colors.ColorSettingsManager; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.StateItem; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Display; - -/** - * Provider for a time chart analysis view - * - * @version 1.0 - * @author Patrick Tasse - */ -public class TimeChartAnalysisProvider extends TimeGraphPresentationProvider { - - private static final Color BOOKMARK_INNER_COLOR = new Color(Display.getDefault(), 115, 165, 224); - private static final Color BOOKMARK_OUTER_COLOR = new Color(Display.getDefault(), 2, 70, 140); - private static final Color SEARCH_MATCH_COLOR = new Color(Display.getDefault(), 177, 118, 14); - - private int lastX = Integer.MIN_VALUE; - private int currX = Integer.MIN_VALUE; - private int lastPriority; - private int lastBookmarkX = Integer.MIN_VALUE; - - @Override - public StateItem[] getStateTable() { - - ColorSetting[] settings = ColorSettingsManager.getColorSettings(); - StateItem[] stateItems = new StateItem[settings.length]; - for (int i = 0; i < settings.length; i++) { - stateItems[i] = new StateItem(settings[i].getTickColorRGB()); - } - return stateItems; - } - - @Override - public int getStateTableIndex(ITimeEvent event) { - if (! ((TimeChartEvent) event).isVisible()) { - return ITimeGraphPresentationProvider.INVISIBLE; - } - int priority = ((TimeChartEvent) event).getColorSettingPriority(); - if (currX == lastX) { - priority = Math.min(priority, lastPriority); - } - lastPriority = priority; - return priority; - } - - @Override - public void postDrawEvent(ITimeEvent event, Rectangle rect, GC gc) { - if (! ((TimeChartEvent) event).isVisible()) { - return; - } - lastX = currX; - currX = rect.x; - if (lastBookmarkX == rect.x || ((TimeChartEvent) event).isBookmarked()) { - drawBookmark(rect, gc); - lastBookmarkX = rect.x; - } else if (lastBookmarkX == rect.x - 1) { - Rectangle r = new Rectangle(lastBookmarkX, rect.y, rect.width, rect.height); - drawBookmark(r, gc); - } else { - lastBookmarkX = Integer.MIN_VALUE; - } - if (((TimeChartEvent) event).isSearchMatch()) { - drawSearchMatch(rect, gc); - } - } - - private static void drawBookmark(Rectangle r, GC gc) { - gc.setForeground(BOOKMARK_OUTER_COLOR); - gc.drawLine(r.x - 1, r.y - 2, r.x - 1, r.y + 2); - gc.drawLine(r.x + 1, r.y - 2, r.x + 1, r.y + 2); - gc.drawPoint(r.x, r.y - 2); - gc.setForeground(BOOKMARK_INNER_COLOR); - gc.drawLine(r.x, r.y - 1, r.x, r.y + 1); - gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); - gc.drawPoint(r.x - 1, r.y + 3); - gc.drawPoint(r.x, r.y + 2); - gc.drawPoint(r.x + 1, r.y + 3); - } - - private static void drawSearchMatch(Rectangle r, GC gc) { - gc.setForeground(SEARCH_MATCH_COLOR); - gc.drawPoint(r.x, r.y + r.height); - gc.drawLine(r.x - 1, r.y + r.height + 1, r.x + 1, r.y + r.height + 1); - gc.drawLine(r.x - 2, r.y + r.height + 2, r.x + 2, r.y + r.height + 2); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartDecorationProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartDecorationProvider.java deleted file mode 100644 index 7eaeb22b17..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartDecorationProvider.java +++ /dev/null @@ -1,141 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.timechart; - -import java.util.HashSet; -import java.util.Set; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.filter.ITmfFilter; - -/** - * Provider for decorations in the time chart view - * - * @version 1.0 - * @author Patrick Tasse - */ -public class TimeChartDecorationProvider { - - private final IFile fBookmarksFile; - private final Set fBookmarksSet = new HashSet<>(); - private ITmfFilter fFilterFilter; - private ITmfFilter fSearchFilter; - - /** - * Constructor - * - * @param bookmarksFile - * Bookmark file associated with the trace - */ - public TimeChartDecorationProvider(IFile bookmarksFile) { - fBookmarksFile = bookmarksFile; - refreshBookmarks(); - } - - /** - * Retrieve the bookmark file that was assigned to this provider - * - * @return The bookmark file - */ - public IFile getBookmarksFile() { - return fBookmarksFile; - } - - /** - * Verify if the selected rank has a bookmark assigned to it. - * - * @param rank - * The rank to check for - * @return If there is a bookmark there - */ - public boolean isBookmark(long rank) { - return fBookmarksSet.contains(rank); - } - - /** - * Refresh the bookmark display. - */ - public void refreshBookmarks() { - try { - fBookmarksSet.clear(); - if (fBookmarksFile == null) { - return; - } - for (IMarker bookmark : fBookmarksFile.findMarkers( - IMarker.BOOKMARK, false, IResource.DEPTH_ZERO)) { - int location = bookmark.getAttribute(IMarker.LOCATION, -1); - if (location != -1) { - Long rank = (long) location; - fBookmarksSet.add(rank); - } - } - } catch (CoreException e) { - Activator.getDefault().logError("Error refreshing bookmarks", e); //$NON-NLS-1$ - } - } - - /** - * Notify that a filter is now applied on the view. - * - * @param filter - * The filter that was applied - */ - public void filterApplied(ITmfFilter filter) { - fFilterFilter = filter; - } - - /** - * Check if an event is currently visible in the view or not. - * - * @param event - * The event to check for - * @return If the event is visible or not - */ - public boolean isVisible(ITmfEvent event) { - if (fFilterFilter != null) { - return fFilterFilter.matches(event); - } - return true; - } - - /** - * Notify that a search is applied on the view. - * - * @param filter - * The search filter that was applied - */ - public void searchApplied(ITmfFilter filter) { - fSearchFilter = filter; - } - - /** - * Verify if the currently active search filter applies to the given event - * or not. - * - * @param event - * The event to check for - * @return If the event matches - */ - public boolean isSearchMatch(ITmfEvent event) { - if (fSearchFilter != null) { - return fSearchFilter.matches(event); - } - return false; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartEvent.java deleted file mode 100644 index 9f12d2f9d8..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartEvent.java +++ /dev/null @@ -1,375 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.timechart; - -import java.util.ArrayList; -import java.util.Iterator; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.ui.views.colors.ColorSettingsManager; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; - -/** - * Event in the time chart view - * - * @version 1.0 - * @author Patrick Tasse - */ -public class TimeChartEvent implements ITimeEvent { - - private static final byte TIMESTAMP_SCALE = -9; - - private final TimeChartAnalysisEntry fParentEntry; - private long fTime; - private long fDuration; - private long fFirstRank; - private long fLastRank; - private final RankRangeList fRankRangeList; - private long fNbEvents; - private int fColorSettingPriority; - private boolean fIsBookmark; - private boolean fIsVisible; - private boolean fIsSearchMatch; - private TimeChartAnalysisEntry fItemizedEntry; - private boolean fItemizing; - - /** - * Standard constructor - * - * @param parentEntry - * The parent entry - * @param event - * The event from which this time chart event originates - * @param rank - * The rank of the event in the trace - * @param decorationProvider - * The decoration provider to use - */ - public TimeChartEvent(TimeChartAnalysisEntry parentEntry, ITmfEvent event, - long rank, TimeChartDecorationProvider decorationProvider) { - fParentEntry = parentEntry; - fTime = event.getTimestamp().normalize(0, TIMESTAMP_SCALE).getValue(); - fDuration = 0; - fFirstRank = fLastRank = rank; - fRankRangeList = new RankRangeList(rank); - fNbEvents = 1; - fColorSettingPriority = ColorSettingsManager.getColorSettingPriority(event); - fIsBookmark = decorationProvider.isBookmark(rank); - fIsVisible = decorationProvider.isVisible(event); - fIsSearchMatch = decorationProvider.isSearchMatch(event); - } - - @Override - public ITimeGraphEntry getEntry() { - return fParentEntry; - } - - @Override - public long getTime() { - return fTime; - } - - @Override - public long getDuration() { - return fDuration; - } - - /** - * Retrieve the rank of the trace event which started this time event. - * - * @return The rank of the beginning - */ - public long getFirstRank() { - return fFirstRank; - } - - /** - * Retrieve the rank of the trace event which *finished* this time event. - * - * @return The rank of the end - */ - public long getLastRank() { - return fLastRank; - } - - /** - * Get the list of rank ranges corresponding to this time event. - * - * @return The rank range list - */ - public RankRangeList getRankRangeList() { - return fRankRangeList; - } - - /** - * Merge another time event with this one. - * - * @param event - * The other event - */ - public void merge(TimeChartEvent event) { - mergeDecorations(event); - if (fTime == event.getTime() && fDuration == event.getDuration()) { - return; - } - long endTime = Math.max(fTime + fDuration, event.getTime() + event.getDuration()); - fTime = Math.min(fTime, event.getTime()); - fDuration = endTime - fTime; - fFirstRank = Math.min(fFirstRank, event.fFirstRank); - fLastRank = Math.max(fLastRank, event.fLastRank); - fNbEvents += event.fNbEvents; - fItemizedEntry = null; - synchronized (fRankRangeList) { - fRankRangeList.merge(event.getRankRangeList()); - } - } - - /** - * Merge the decorations of another time event with the decorations of this - * one. - * - * @param event - * The other event - */ - public void mergeDecorations(TimeChartEvent event) { - fColorSettingPriority = Math.min(fColorSettingPriority, event.getColorSettingPriority()); - fIsBookmark |= event.fIsBookmark; - fIsVisible |= event.fIsVisible; - fIsSearchMatch |= event.fIsSearchMatch; - } - - /** - * Get the number of time events that have been merged with this one (starts - * counting at 1 if no merge happened). - * - * @return The current number of events in the bath - */ - public long getNbEvents() { - return fNbEvents; - } - - /** - * Retrieve the color setting priority. - * - * @return The priority - */ - public int getColorSettingPriority() { - return fColorSettingPriority; - } - - /** - * Set the color setting priority. - * - * @param priority - * The priority to set - */ - public void setColorSettingPriority(int priority) { - fColorSettingPriority = priority; - } - - /** - * Check if this time event is bookmarked - * - * @return Y/N - */ - public boolean isBookmarked() { - return fIsBookmark; - } - - /** - * Set this time event to be bookmarked or not. - * - * @param isBookmarked - * Should time time event become a bookmark, or not - */ - public void setIsBookmarked(boolean isBookmarked) { - fIsBookmark = isBookmarked; - } - - /** - * Check if this time is currently visible or not. - * - * @return If the event is visible - */ - public boolean isVisible() { - return fIsVisible; - } - - /** - * Set this time event to visible (or to non-visible). - * - * @param isVisible The new status - */ - public void setIsVisible(boolean isVisible) { - fIsVisible = isVisible; - } - - /** - * Check if the time event matches the current search. - * - * @return If it matches, Y/N - */ - public boolean isSearchMatch() { - return fIsSearchMatch; - } - - /** - * Mark this event as matching (or non-matching) the current search. - * - * @param isSearchMatch - * The new matching status - */ - public void setIsSearchMatch(boolean isSearchMatch) { - fIsSearchMatch = isSearchMatch; - } - - /** - * Set this event's itemized entry. - * - * @param timeAnalysisEntry - * The entry to set - */ - public void setItemizedEntry(TimeChartAnalysisEntry timeAnalysisEntry) { - fItemizedEntry = timeAnalysisEntry; - } - - /** - * Retrieve this event's itemized entry. - * - * @return The itemized entry that was previously set - */ - public TimeChartAnalysisEntry getItemizedEntry() { - return fItemizedEntry; - } - - /** - * @return Has this time event been set to itemizing? - */ - public boolean isItemizing() { - return fItemizing; - } - - /** - * Set this event's itemizing flag to true or false. - * - * @param itemizing - * The new value - */ - public void setItemizing(boolean itemizing) { - fItemizing = itemizing; - } - - /** - * Inner class to define a range in terms of ranks in the trace. - * - * @version 1.0 - * @author Patrick Tasse - */ - public class RankRange { - private long firstRank; - private long lastRank; - - /** - * Standard constructor - * - * @param firstRank - * The first (earliest) rank of the range - * @param lastRank - * The last (latest) rank of the range - */ - public RankRange(long firstRank, long lastRank) { - this.firstRank = firstRank; - this.lastRank = lastRank; - } - - /** - * Retrieve the start rank of this range. - * - * @return The first rank - */ - public long getFirstRank() { - return firstRank; - } - - /** - * Retrieve the end rank of this range - * - * @return The end rank - */ - public long getLastRank() { - return lastRank; - } - - /** - * Calculate the minimal distance between two RankRange's - * - * @param range - * The other range - * @return The distance, in "number of events" between the two ranges - */ - public long distanceFrom(RankRange range) { - if (range.lastRank < fFirstRank) { - return fFirstRank - range.lastRank; - } else if (range.firstRank > fLastRank) { - return range.firstRank - fLastRank; - } else { - return 0; - } - } - - @Override - public String toString() { - return "["+firstRank+","+lastRank+"]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - } - - private class RankRangeList extends ArrayList { - - private static final long serialVersionUID = 6060485531208535986L; - - public RankRangeList(long rank) { - super(1); - add(new RankRange(rank, rank)); - } - - public void merge(RankRangeList rankRangeList) { - long threshold = fParentEntry.getTrace().getCacheSize(); - for (RankRange newRange : rankRangeList) { - boolean merged = false; - for (RankRange oldRange : fRankRangeList) { - if (newRange.distanceFrom(oldRange) <= threshold) { - oldRange.firstRank = Math.min(oldRange.firstRank, newRange.firstRank); - oldRange.lastRank = Math.max(oldRange.lastRank, newRange.lastRank); - merged = true; - break; - } - } - if (!merged) { - add(newRange); - } - } - Iterator iterator = fRankRangeList.iterator(); - RankRange previous = null; - while (iterator.hasNext()) { - RankRange range = iterator.next(); - if (previous != null && range.distanceFrom(previous) <= threshold) { - previous.firstRank = Math.min(previous.firstRank, range.firstRank); - previous.lastRank = Math.max(previous.lastRank, range.lastRank); - iterator.remove(); - } - previous = range; - } - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartView.java deleted file mode 100644 index 46a41d8822..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartView.java +++ /dev/null @@ -1,754 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.timechart; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.resources.IMarkerDelta; -import org.eclipse.core.resources.IResourceChangeEvent; -import org.eclipse.core.resources.IResourceChangeListener; -import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.jface.action.IStatusLineManager; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.signal.TmfEventFilterAppliedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfEventSearchAppliedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ui.views.TmfView; -import org.eclipse.linuxtools.tmf.ui.views.colors.ColorSetting; -import org.eclipse.linuxtools.tmf.ui.views.colors.ColorSettingsManager; -import org.eclipse.linuxtools.tmf.ui.views.colors.IColorSettingsListener; -import org.eclipse.linuxtools.tmf.ui.views.timechart.TimeChartEvent.RankRange; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphRangeListener; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphSelectionListener; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphTimeListener; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphSelectionEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphViewer; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; - -/** - * Generic Time Chart view, which is similar to a Gantt chart for trace analysis - * - * @version 1.0 - * @author Patrick Tasse - */ -public class TimeChartView extends TmfView implements ITimeGraphRangeListener, ITimeGraphSelectionListener, ITimeGraphTimeListener, IColorSettingsListener, IResourceChangeListener { - - /** TimeChartView's ID */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.timechart"; //$NON-NLS-1$ - - private static final int TIMESTAMP_SCALE = -9; - - private final int fDisplayWidth; - private TimeGraphViewer fViewer; - private final ArrayList fTimeAnalysisEntries = new ArrayList<>(); - private final Map fDecorationProviders = new HashMap<>(); - private final ArrayList fDecorateThreads = new ArrayList<>(); - private long fStartTime = 0; - private long fStopTime = Long.MAX_VALUE; - private boolean fRefreshBusy = false; - private boolean fRefreshPending = false; - private boolean fRedrawBusy = false; - private boolean fRedrawPending = false; - private final Object fSyncObj = new Object(); - private ITimeGraphPresentationProvider fPresentationProvider; - - /** - * Default constructor - */ - public TimeChartView() { - super("Time Chart"); //$NON-NLS-1$ - fDisplayWidth = Display.getDefault().getBounds().width; - } - - @Override - public void createPartControl(Composite parent) { - fViewer = new TimeGraphViewer(parent, SWT.NONE); - fPresentationProvider = new TimeChartAnalysisProvider(); - fViewer.setTimeGraphProvider(fPresentationProvider); - fViewer.setTimeFormat(TimeFormat.CALENDAR); - fViewer.addTimeListener(this); - fViewer.addRangeListener(this); - fViewer.addSelectionListener(this); - fViewer.setMinimumItemWidth(1); - - IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager(); - fViewer.getTimeGraphControl().setStatusLineManager(statusLineManager); - - for (ITmfTrace trace : TmfTraceManager.getInstance().getOpenedTraces()) { - IFile bookmarksFile = TmfTraceManager.getInstance().getTraceEditorFile(trace); - TimeChartAnalysisEntry timeAnalysisEntry = new TimeChartAnalysisEntry(trace, fDisplayWidth * 2); - fTimeAnalysisEntries.add(timeAnalysisEntry); - fDecorationProviders.put(trace, new TimeChartDecorationProvider(bookmarksFile)); - Thread thread = new ProcessTraceThread(timeAnalysisEntry); - thread.start(); - } - fViewer.setInput(fTimeAnalysisEntries.toArray(new TimeChartAnalysisEntry[0])); - - ColorSettingsManager.addColorSettingsListener(this); - ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE); - } - - @Override - public void dispose() { - ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); - for (DecorateThread thread : fDecorateThreads) { - thread.cancel(); - } - ColorSettingsManager.removeColorSettingsListener(this); - super.dispose(); - } - - @Override - public void setFocus() { - fViewer.setFocus(); - } - - private class ProcessTraceThread extends Thread { - - private final TimeChartAnalysisEntry fTimeAnalysisEntry; - - public ProcessTraceThread(TimeChartAnalysisEntry timeAnalysisEntry) { - super("ProcessTraceJob:" + timeAnalysisEntry.getName()); //$NON-NLS-1$ - fTimeAnalysisEntry = timeAnalysisEntry; - } - - @Override - public void run() { - updateTraceEntry(fTimeAnalysisEntry, Long.MAX_VALUE, 0, Long.MAX_VALUE); - } - } - - private void updateTraceEntry(TimeChartAnalysisEntry timeAnalysisEntry, long stopRank, long startTime, long stopTime) { - ITmfTrace trace = timeAnalysisEntry.getTrace(); - TimeChartDecorationProvider decorationProvider = fDecorationProviders.get(trace); - if (decorationProvider == null) { - return; // the trace has been closed - } - ITmfContext context = null; - // TmfTimestamp lastTimestamp = null; - boolean done = false; - while (!done) { - synchronized (timeAnalysisEntry) { - if (timeAnalysisEntry.getLastRank() >= trace.getNbEvents()) { - done = true; - break; - } - if (context == null || context.getRank() != timeAnalysisEntry.getLastRank()) { - if (context != null) { - context.dispose(); - } - if (timeAnalysisEntry.getLastRank() != -1) { - context = trace.seekEvent(timeAnalysisEntry.getLastRank()); - } else { - // context = trace.seekLocation(null); - context = trace.seekEvent(0); - } - } - while (true) { - long rank = context.getRank(); - ITmfEvent event = trace.getNext(context); - if (event == null) { - done = true; - break; - } - // if (!event.getTimestamp().equals(lastTimestamp)) { - TimeChartEvent timeEvent = new TimeChartEvent(timeAnalysisEntry, event, rank, decorationProvider); - if (timeEvent.getTime() >= startTime && timeEvent.getTime() <= stopTime) { - timeAnalysisEntry.addTraceEvent(timeEvent); - } - // lastTimestamp = event.getTimestamp(); - // } *** commented out so that color setting priority gets - // set even if the event has same time - if (context.getRank() == trace.getNbEvents() || context.getRank() == stopRank) { - done = true; - break; - } - if (context.getRank() % trace.getCacheSize() == 1) { - // break for UI refresh - break; - } - } - // timeAnalysisEntry.setLastRank(Math.min(trace.getNbEvents(), - // stopRank)); - timeAnalysisEntry.setLastRank(context.getRank()); - } - redrawViewer(true); - } - if (context != null) { - context.dispose(); - } - } - - private void refreshViewer() { - synchronized (fSyncObj) { - if (fRefreshBusy) { - fRefreshPending = true; - return; - } - fRefreshBusy = true; - } - // Perform the refresh on the UI thread - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - if (fViewer.getControl().isDisposed()) { - return; - } - fViewer.setInput(fTimeAnalysisEntries.toArray(new TimeChartAnalysisEntry[0])); - fViewer.resetStartFinishTime(); - synchronized (fSyncObj) { - fRefreshBusy = false; - if (fRefreshPending) { - fRefreshPending = false; - refreshViewer(); - } - } - } - }); - } - - private void redrawViewer(boolean resetTimeIntervals) { - synchronized (fSyncObj) { - if (fRedrawBusy) { - fRedrawPending = true; - return; - } - fRedrawBusy = true; - } - final boolean reset = resetTimeIntervals; - // Perform the refresh on the UI thread - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - if (fViewer.getControl().isDisposed()) { - return; - } - if (reset) { - fViewer.setTimeRange(fTimeAnalysisEntries.toArray(new TimeChartAnalysisEntry[0])); - fViewer.setTimeBounds(); - } - fViewer.getControl().redraw(); - fViewer.getControl().update(); - synchronized (fSyncObj) { - fRedrawBusy = false; - if (fRedrawPending) { - fRedrawPending = false; - redrawViewer(reset); - } - } - } - }); - } - - private void itemize(long startTime, long stopTime) { - for (int i = 0; i < fTimeAnalysisEntries.size(); i++) { - Thread thread = new ItemizeThread(fTimeAnalysisEntries.get(i), startTime, stopTime); - thread.start(); - } - } - - private class ItemizeThread extends Thread { - - private final TimeChartAnalysisEntry fTimeAnalysisEntry; - private final long startTime; - private final long stopTime; - private final long fMaxDuration; - - private ItemizeThread(TimeChartAnalysisEntry timeAnalysisEntry, long startTime, long stopTime) { - super("Itemize Thread:" + timeAnalysisEntry.getName()); //$NON-NLS-1$ - fTimeAnalysisEntry = timeAnalysisEntry; - this.startTime = startTime; - this.stopTime = stopTime; - fMaxDuration = 3 * (stopTime - startTime) / fDisplayWidth; - } - - @Override - public void run() { - itemizeTraceEntry(fTimeAnalysisEntry); - } - - public void itemizeTraceEntry(TimeChartAnalysisEntry timeAnalysisEntry) { - Iterator iterator = timeAnalysisEntry.getTimeEventsIterator(); - TimeChartEvent event = null; - boolean hasNext = true; - while (hasNext) { - synchronized (timeAnalysisEntry) { - while ((hasNext = iterator.hasNext()) == true) { - event = (TimeChartEvent) iterator.next(); - if (event.getTime() + event.getDuration() > startTime && event.getTime() < stopTime && event.getDuration() > fMaxDuration - && event.getNbEvents() > 1) { - break; - } - } - } - if (hasNext && event != null) { - if (event.getItemizedEntry() == null) { - itemizeEvent(event); - } else { - itemizeTraceEntry(event.getItemizedEntry()); - } - } - } - } - - public void itemizeEvent(TimeChartEvent event) { - synchronized (event) { - if (event.isItemizing()) { - return; - } - event.setItemizing(true); - } - TimeChartAnalysisEntry timeAnalysisEntry = new TimeChartAnalysisEntry(fTimeAnalysisEntry.getTrace(), (int) Math.min( - event.getNbEvents() + 1, fDisplayWidth * 2)); - synchronized (event.getRankRangeList()) { - for (RankRange range : event.getRankRangeList()) { - timeAnalysisEntry.setLastRank(range.getFirstRank()); - updateTraceEntry(timeAnalysisEntry, range.getLastRank() + 1, event.getTime(), event.getTime() + event.getDuration()); - } - } - event.setItemizedEntry(timeAnalysisEntry); - redrawViewer(false); - itemizeTraceEntry(timeAnalysisEntry); - synchronized (event) { - event.setItemizing(false); - } - } - } - - private void redecorate() { - synchronized (fDecorateThreads) { - for (DecorateThread thread : fDecorateThreads) { - thread.cancel(); - } - fDecorateThreads.clear(); - for (int i = 0; i < fTimeAnalysisEntries.size(); i++) { - DecorateThread thread = new DecorateThread(fTimeAnalysisEntries.get(i)); - thread.start(); - fDecorateThreads.add(thread); - } - } - } - - private class DecorateThread extends Thread { - private volatile boolean interrupted = false; - private final TimeChartAnalysisEntry fTimeAnalysisEntry; - private final TimeChartDecorationProvider fDecorationProvider; - private ITmfContext fContext; - private int fCount = 0; - - private DecorateThread(TimeChartAnalysisEntry timeAnalysisEntry) { - super("Decorate Thread:" + timeAnalysisEntry.getName()); //$NON-NLS-1$ - fTimeAnalysisEntry = timeAnalysisEntry; - fDecorationProvider = fDecorationProviders.get(timeAnalysisEntry.getTrace()); - } - - @Override - public void run() { - resetTraceEntry(fTimeAnalysisEntry); - redrawViewer(false); - decorateTraceEntry(fTimeAnalysisEntry, null); - redrawViewer(false); - synchronized (fDecorateThreads) { - fDecorateThreads.remove(this); - } - if (fContext != null) { - fContext.dispose(); - } - } - - public void resetTraceEntry(TimeChartAnalysisEntry timeAnalysisEntry) { - Iterator iterator = timeAnalysisEntry.getTimeEventsIterator(); - TimeChartEvent event = null; - boolean hasNext = true; - while (!interrupted && hasNext) { - synchronized (timeAnalysisEntry) { - while ((hasNext = iterator.hasNext()) == true) { - event = (TimeChartEvent) iterator.next(); - break; - } - } - if (hasNext && event != null) { - // TODO possible concurrency problem here with ItemizeJob - event.setColorSettingPriority(ColorSettingsManager.PRIORITY_NONE); - if (event.getItemizedEntry() != null) { - resetTraceEntry(event.getItemizedEntry()); - } - } - } - } - - public void decorateTraceEntry(TimeChartAnalysisEntry timeAnalysisEntry, TimeChartEvent parentEvent) { - // Set max duration high to ensure iterator does not consider - // itemized events - Iterator iterator = timeAnalysisEntry.getTimeEventsIterator(0, Long.MAX_VALUE, Long.MAX_VALUE); - TimeChartEvent event = null; - int entryPriority = ColorSettingsManager.PRIORITY_NONE; - boolean entryIsBookmarked = false; - boolean entryIsVisible = false; - boolean entryIsSearchMatch = false; - boolean hasNext = true; - while (!interrupted && hasNext) { - synchronized (timeAnalysisEntry) { - while ((hasNext = iterator.hasNext()) == true) { - event = (TimeChartEvent) iterator.next(); - break; - } - } - if (hasNext && event != null) { - // TODO possible concurrency problem here with ItemizeJob - if (event.getItemizedEntry() == null) { - decorateEvent(event); - } else { - decorateTraceEntry(event.getItemizedEntry(), event); - } - entryPriority = Math.min(entryPriority, event.getColorSettingPriority()); - entryIsBookmarked |= event.isBookmarked(); - entryIsVisible |= event.isVisible(); - entryIsSearchMatch |= event.isSearchMatch(); - if (++fCount % timeAnalysisEntry.getTrace().getCacheSize() == 0) { - redrawViewer(false); - } - } - } - if (parentEvent != null) { - parentEvent.setColorSettingPriority(entryPriority); - parentEvent.setIsBookmarked(entryIsBookmarked); - parentEvent.setIsVisible(entryIsVisible); - parentEvent.setIsSearchMatch(entryIsSearchMatch); - } - } - - public void decorateEvent(TimeChartEvent timeChartEvent) { - // TODO possible concurrency problem here with ItemizeJob - TimeChartAnalysisEntry timeAnalysisEntry = (TimeChartAnalysisEntry) timeChartEvent.getEntry(); - ITmfTrace trace = timeAnalysisEntry.getTrace(); - int priority = ColorSettingsManager.PRIORITY_NONE; - boolean isBookmarked = false; - boolean isVisible = false; - boolean isSearchMatch = false; - synchronized (timeChartEvent.getRankRangeList()) { - for (RankRange range : timeChartEvent.getRankRangeList()) { - if (interrupted) { - return; - } - if (fContext == null || fContext.getRank() != range.getFirstRank()) { - if (fContext != null) { - fContext.dispose(); - } - fContext = trace.seekEvent(range.getFirstRank()); - fContext.setRank(range.getFirstRank()); - } - while (true) { - if (interrupted) { - return; - } - long rank = fContext.getRank(); - ITmfEvent event = trace.getNext(fContext); - if (event == null) { - break; - } - long eventTime = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - if (eventTime >= timeChartEvent.getTime() && eventTime <= timeChartEvent.getTime() + timeChartEvent.getDuration()) { - priority = Math.min(priority, ColorSettingsManager.getColorSettingPriority(event)); - } - isBookmarked |= fDecorationProvider.isBookmark(rank); - isVisible |= fDecorationProvider.isVisible(event); - isSearchMatch |= fDecorationProvider.isSearchMatch(event); - if (fContext.getRank() > range.getLastRank()) { - break; - } - } - } - } - timeChartEvent.setColorSettingPriority(priority); - timeChartEvent.setIsBookmarked(isBookmarked); - timeChartEvent.setIsVisible(isVisible); - timeChartEvent.setIsSearchMatch(isSearchMatch); - } - - public void cancel() { - interrupted = true; - } - } - - // ------------------------------------------------------------------------ - // Listeners - // ------------------------------------------------------------------------ - - @Override - public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) { - fStartTime = event.getStartTime(); - fStopTime = event.getEndTime(); - itemize(fStartTime, fStopTime); - final ITmfTimestamp startTimestamp = new TmfTimestamp(event.getStartTime(), ITmfTimestamp.NANOSECOND_SCALE); - final ITmfTimestamp endTimestamp = new TmfTimestamp(event.getEndTime(), ITmfTimestamp.NANOSECOND_SCALE); - TmfTimeRange range = new TmfTimeRange(startTimestamp, endTimestamp); - broadcast(new TmfRangeSynchSignal(this, range)); - } - - @Override - public void selectionChanged(TimeGraphSelectionEvent event) { - ITimeGraphEntry timeAnalysisEntry = null; - if (event.getSelection() instanceof TimeChartAnalysisEntry) { - timeAnalysisEntry = event.getSelection(); - } else if (event.getSelection() instanceof TimeChartEvent) { - timeAnalysisEntry = ((TimeChartEvent) event.getSelection()).getEntry(); - } - if (timeAnalysisEntry instanceof TimeChartAnalysisEntry) { - broadcast(new TmfTraceSelectedSignal(this, ((TimeChartAnalysisEntry) timeAnalysisEntry).getTrace())); - } - } - - @Override - public void timeSelected(TimeGraphTimeEvent event) { - broadcast(new TmfTimeSynchSignal(this, new TmfTimestamp(event.getBeginTime(), TIMESTAMP_SCALE), new TmfTimestamp(event.getEndTime(), TIMESTAMP_SCALE))); - } - - @Override - public void colorSettingsChanged(ColorSetting[] colorSettings) { - // Set presentation provider again to trigger re-creation of new color settings which are stored - // in the TimeGraphControl class - fViewer.setTimeGraphProvider(fPresentationProvider); - redecorate(); - } - - @Override - public void resourceChanged(IResourceChangeEvent event) { - for (IMarkerDelta delta : event.findMarkerDeltas(IMarker.BOOKMARK, false)) { - for (TimeChartDecorationProvider provider : fDecorationProviders.values()) { - if (delta.getResource().equals(provider.getBookmarksFile())) { - if (delta.getKind() == IResourceDelta.CHANGED && delta.getMarker().getAttribute(IMarker.LOCATION, -1) != -1) { - provider.refreshBookmarks(); - } else if (delta.getKind() == IResourceDelta.REMOVED) { - provider.refreshBookmarks(); - } - } - } - } - redecorate(); - } - - // ------------------------------------------------------------------------ - // Signal handlers - // ------------------------------------------------------------------------ - - /** - * Handler for the Trace Opened signal - * - * @param signal - * The incoming signal - * @since 2.0 - */ - @TmfSignalHandler - public void traceOpened(TmfTraceOpenedSignal signal) { - final ITmfTrace trace = signal.getTrace(); - final IFile bookmarksFile = signal.getEditorFile(); - TimeChartAnalysisEntry timeAnalysisEntry = null; - for (int i = 0; i < fTimeAnalysisEntries.size(); i++) { - if (fTimeAnalysisEntries.get(i).getTrace().equals(trace)) { - timeAnalysisEntry = fTimeAnalysisEntries.get(i); - break; - } - } - if (timeAnalysisEntry == null) { - timeAnalysisEntry = new TimeChartAnalysisEntry(trace, fDisplayWidth * 2); - fTimeAnalysisEntries.add(timeAnalysisEntry); - fDecorationProviders.put(trace, new TimeChartDecorationProvider(bookmarksFile)); - Thread thread = new ProcessTraceThread(timeAnalysisEntry); - thread.start(); - } - refreshViewer(); - } - - /** - * Handler for the Trace Closed signal - * - * @param signal - * The incoming signal - * @since 2.0 - */ - @TmfSignalHandler - public void traceClosed(TmfTraceClosedSignal signal) { - final ITmfTrace trace = signal.getTrace(); - for (int i = 0; i < fTimeAnalysisEntries.size(); i++) { - if (fTimeAnalysisEntries.get(i).getTrace().equals(trace)) { - fTimeAnalysisEntries.remove(i); - fDecorationProviders.remove(trace); - synchronized (fDecorateThreads) { - for (DecorateThread thread : fDecorateThreads) { - if (thread.fTimeAnalysisEntry.getTrace() == trace) { - thread.cancel(); - fDecorateThreads.remove(thread); - break; - } - } - } - refreshViewer(); - break; - } - } - } - - /** - * Handler for the Trace Selected signal - * - * @param signal - * The incoming signal - */ - @TmfSignalHandler - public void traceSelected(TmfTraceSelectedSignal signal) { - if (signal.getSource() != this) { - ITmfTrace trace = signal.getTrace(); - for (int i = 0; i < fTimeAnalysisEntries.size(); i++) { - if (fTimeAnalysisEntries.get(i).getTrace().equals(trace)) { - fViewer.setSelection(fTimeAnalysisEntries.get(i)); - break; - } - } - long beginTime = fTraceManager.getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - long endTime = fTraceManager.getSelectionEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - fViewer.setSelectionRange(beginTime, endTime); - } - } - - /** - * Handler for the Trace Updated signal - * - * @param signal - * The incoming signal - */ - @TmfSignalHandler - public void traceUpdated(TmfTraceUpdatedSignal signal) { - final ITmfTrace trace = signal.getTrace(); - for (int i = 0; i < fTimeAnalysisEntries.size(); i++) { - TimeChartAnalysisEntry timeAnalysisEntry = fTimeAnalysisEntries.get(i); - if (timeAnalysisEntry.getTrace().equals(trace)) { - updateTraceEntry(timeAnalysisEntry, Long.MAX_VALUE, 0, Long.MAX_VALUE); - break; - } - } - } - - /** - * Handler for the Time Synch signal - * - * @param signal - * The incoming signal - */ - @TmfSignalHandler - public void currentTimeUpdated(TmfTimeSynchSignal signal) { - final long beginTime = signal.getBeginTime().normalize(0, TIMESTAMP_SCALE).getValue(); - final long endTime = signal.getEndTime().normalize(0, TIMESTAMP_SCALE).getValue(); - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - if (beginTime == endTime) { - fViewer.setSelectedTime(beginTime, true); - if (fStartTime != fViewer.getTime0() || fStopTime != fViewer.getTime1()) { - fStartTime = fViewer.getTime0(); - fStopTime = fViewer.getTime1(); - itemize(fStartTime, fStopTime); - } - } else { - fViewer.setSelectionRange(beginTime, endTime); - } - } - }); - } - - /** - * Handler for the Time Range Synch signal - * - * @param signal - * The incoming signal - * @since 2.0 - */ - @TmfSignalHandler - public void synchToRange(final TmfRangeSynchSignal signal) { - if (signal.getSource() == this) { - return; - } - final long startTime = signal.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - final long endTime = signal.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - fStartTime = startTime; - fStopTime = endTime; - itemize(fStartTime, fStopTime); - fViewer.setStartFinishTime(startTime, endTime); - } - }); - } - - /** - * Handler for the Event Filter Applied signal - * - * @param signal - * The incoming signal - * @since 2.0 - */ - @TmfSignalHandler - public void filterApplied(TmfEventFilterAppliedSignal signal) { - TimeChartDecorationProvider decorationProvider = fDecorationProviders.get(signal.getTrace()); - if (decorationProvider == null) { - return; - } - decorationProvider.filterApplied(signal.getEventFilter()); - redecorate(); - } - - /** - * Handler for the Event Search Applied signal - * - * @param signal - * The incoming signal - * @since 2.0 - */ - @TmfSignalHandler - public void searchApplied(TmfEventSearchAppliedSignal signal) { - TimeChartDecorationProvider decorationProvider = fDecorationProviders.get(signal.getTrace()); - if (decorationProvider == null) { - return; - } - decorationProvider.searchApplied(signal.getSearchFilter()); - redecorate(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/AbstractTimeGraphView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/AbstractTimeGraphView.java deleted file mode 100644 index 18db3cc48e..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/AbstractTimeGraphView.java +++ /dev/null @@ -1,1271 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Bernd Hufmann - Updated signal handling - * Geneviève Bastien - Move code to provide base classes for time graph view - * Marc-Andre Laperle - Add time zone preference - * Geneviève Bastien - Add event links between entries - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.timegraph; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CopyOnWriteArrayList; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IStatusLineManager; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.viewers.ILabelProvider; -import org.eclipse.jface.viewers.ILabelProviderListener; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.ITableLabelProvider; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimestampFormatUpdateSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.ui.TmfUiRefreshHandler; -import org.eclipse.linuxtools.tmf.ui.views.TmfView; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphContentProvider; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider2; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphRangeListener; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphSelectionListener; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphTimeListener; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphCombo; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphViewer; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.TreeColumn; -import org.eclipse.ui.IActionBars; - -/** - * An abstract view all time graph views can inherit - * - * This view contains either a time graph viewer, or a time graph combo which is - * divided between a tree viewer on the left and a time graph viewer on the right. - * - * @since 2.1 - */ -public abstract class AbstractTimeGraphView extends TmfView { - - /** - * Redraw state enum - */ - private enum State { - IDLE, BUSY, PENDING - } - - // ------------------------------------------------------------------------ - // Fields - // ------------------------------------------------------------------------ - - /** The timegraph wrapper */ - private ITimeGraphWrapper fTimeGraphWrapper; - - /** The selected trace */ - private ITmfTrace fTrace; - - /** The timegraph entry list */ - private List fEntryList; - - /** The trace to entry list hash map */ - private final Map> fEntryListMap = new HashMap<>(); - - /** The trace to build thread hash map */ - private final Map fBuildThreadMap = new HashMap<>(); - - /** The start time */ - private long fStartTime; - - /** The end time */ - private long fEndTime; - - /** The display width */ - private final int fDisplayWidth; - - /** The zoom thread */ - private ZoomThread fZoomThread; - - /** The next resource action */ - private Action fNextResourceAction; - - /** The previous resource action */ - private Action fPreviousResourceAction; - - /** A comparator class */ - private Comparator fEntryComparator = null; - - /** The redraw state used to prevent unnecessary queuing of display runnables */ - private State fRedrawState = State.IDLE; - - /** The redraw synchronization object */ - private final Object fSyncObj = new Object(); - - /** The presentation provider for this view */ - private final TimeGraphPresentationProvider fPresentation; - - /** The tree column label array, or null if combo is not used */ - private String[] fColumns; - - /** The tree label provider, or null if combo is not used */ - private TreeLabelProvider fLabelProvider = null; - - /** The relative weight of the sash, ignored if combo is not used */ - private int[] fWeight = { 1, 1 }; - - /** The filter column label array, or null if filter is not used */ - private String[] fFilterColumns; - - /** The pack done flag */ - private boolean fPackDone = false; - - /** The filter label provider, or null if filter is not used */ - private TreeLabelProvider fFilterLabelProvider; - - // ------------------------------------------------------------------------ - // Classes - // ------------------------------------------------------------------------ - - private interface ITimeGraphWrapper { - - void setTimeGraphProvider(TimeGraphPresentationProvider fPresentation); - - TimeGraphViewer getTimeGraphViewer(); - - void addSelectionListener(ITimeGraphSelectionListener iTimeGraphSelectionListener); - - ISelectionProvider getSelectionProvider(); - - void setFocus(); - - boolean isDisposed(); - - void refresh(); - - void setInput(Object input); - - Object getInput(); - - void redraw(); - - void update(); - - } - - private class TimeGraphViewerWrapper implements ITimeGraphWrapper { - private TimeGraphViewer viewer; - - private TimeGraphViewerWrapper(Composite parent, int style) { - viewer = new TimeGraphViewer(parent, style); - } - - @Override - public void setTimeGraphProvider(TimeGraphPresentationProvider timeGraphProvider) { - viewer.setTimeGraphProvider(timeGraphProvider); - } - - @Override - public TimeGraphViewer getTimeGraphViewer() { - return viewer; - } - - @Override - public void addSelectionListener(ITimeGraphSelectionListener listener) { - viewer.addSelectionListener(listener); - } - - @Override - public ISelectionProvider getSelectionProvider() { - return viewer.getSelectionProvider(); - } - - @Override - public void setFocus() { - viewer.setFocus(); - } - - @Override - public boolean isDisposed() { - return viewer.getControl().isDisposed(); - } - - @Override - public void setInput(Object input) { - viewer.setInput(input); - } - - @Override - public Object getInput() { - return viewer.getInput(); - } - - @Override - public void refresh() { - viewer.refresh(); - } - - @Override - public void redraw() { - viewer.getControl().redraw(); - } - - @Override - public void update() { - viewer.getControl().update(); - } - } - - private class TimeGraphComboWrapper implements ITimeGraphWrapper { - private TimeGraphCombo combo; - - private TimeGraphComboWrapper(Composite parent, int style) { - combo = new TimeGraphCombo(parent, style, fWeight); - } - - @Override - public void setTimeGraphProvider(TimeGraphPresentationProvider timeGraphProvider) { - combo.setTimeGraphProvider(timeGraphProvider); - } - - @Override - public TimeGraphViewer getTimeGraphViewer() { - return combo.getTimeGraphViewer(); - } - - @Override - public void addSelectionListener(ITimeGraphSelectionListener listener) { - combo.addSelectionListener(listener); - } - - @Override - public ISelectionProvider getSelectionProvider() { - return combo.getTreeViewer(); - } - - @Override - public void setFocus() { - combo.setFocus(); - } - - @Override - public boolean isDisposed() { - return combo.isDisposed(); - } - - @Override - public void setInput(Object input) { - combo.setInput(input); - } - - @Override - public Object getInput() { - return combo.getInput(); - } - - @Override - public void refresh() { - combo.refresh(); - } - - @Override - public void redraw() { - combo.redraw(); - } - - @Override - public void update() { - combo.update(); - } - - TimeGraphCombo getTimeGraphCombo() { - return combo; - } - - TreeViewer getTreeViewer() { - return combo.getTreeViewer(); - } - - IAction getShowFilterAction() { - return combo.getShowFilterAction(); - } - } - - private class TreeContentProvider implements ITreeContentProvider { - - @Override - public void dispose() { - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - @Override - public ITimeGraphEntry[] getElements(Object inputElement) { - if (inputElement != null) { - try { - return ((List) inputElement).toArray(new ITimeGraphEntry[0]); - } catch (ClassCastException e) { - } - } - return new ITimeGraphEntry[0]; - } - - @Override - public Object[] getChildren(Object parentElement) { - ITimeGraphEntry entry = (ITimeGraphEntry) parentElement; - List children = entry.getChildren(); - return children.toArray(new ITimeGraphEntry[children.size()]); - } - - @Override - public Object getParent(Object element) { - ITimeGraphEntry entry = (ITimeGraphEntry) element; - return entry.getParent(); - } - - @Override - public boolean hasChildren(Object element) { - ITimeGraphEntry entry = (ITimeGraphEntry) element; - return entry.hasChildren(); - } - - } - - private class TimeGraphContentProvider implements ITimeGraphContentProvider { - - @Override - public ITimeGraphEntry[] getElements(Object inputElement) { - if (inputElement != null) { - try { - return ((List) inputElement).toArray(new ITimeGraphEntry[0]); - } catch (ClassCastException e) { - } - } - return new ITimeGraphEntry[0]; - } - - } - - /** - * Base class to provide the labels for the tree viewer. Views extending - * this class typically need to override the getColumnText method if they - * have more than one column to display - */ - protected static class TreeLabelProvider implements ITableLabelProvider, ILabelProvider { - - @Override - public void addListener(ILabelProviderListener listener) { - } - - @Override - public void dispose() { - } - - @Override - public boolean isLabelProperty(Object element, String property) { - return false; - } - - @Override - public void removeListener(ILabelProviderListener listener) { - } - - @Override - public Image getColumnImage(Object element, int columnIndex) { - return null; - } - - @Override - public String getColumnText(Object element, int columnIndex) { - TimeGraphEntry entry = (TimeGraphEntry) element; - if (columnIndex == 0) { - return entry.getName(); - } - return new String(); - } - - /** - * @since 3.2 - */ - @Override - public Image getImage(Object element) { - return null; - } - - /** - * @since 3.2 - */ - @Override - public String getText(Object element) { - TimeGraphEntry entry = (TimeGraphEntry) element; - return entry.getName(); - } - - } - - private class BuildThread extends Thread { - private final ITmfTrace fBuildTrace; - private final ITmfTrace fParentTrace; - private final IProgressMonitor fMonitor; - - public BuildThread(final ITmfTrace trace, final ITmfTrace parentTrace, final String name) { - super(name + " build"); //$NON-NLS-1$ - fBuildTrace = trace; - fParentTrace = parentTrace; - fMonitor = new NullProgressMonitor(); - } - - @Override - public void run() { - buildEventList(fBuildTrace, fParentTrace, fMonitor); - synchronized (fBuildThreadMap) { - fBuildThreadMap.remove(fBuildTrace); - } - } - - public void cancel() { - fMonitor.setCanceled(true); - } - } - - private class ZoomThread extends Thread { - private final List fZoomEntryList; - private final long fZoomStartTime; - private final long fZoomEndTime; - private final long fResolution; - private final IProgressMonitor fMonitor; - - public ZoomThread(List entryList, long startTime, long endTime, String name) { - super(name + " zoom"); //$NON-NLS-1$ - fZoomEntryList = entryList; - fZoomStartTime = startTime; - fZoomEndTime = endTime; - fResolution = Math.max(1, (fZoomEndTime - fZoomStartTime) / fDisplayWidth); - fMonitor = new NullProgressMonitor(); - } - - @Override - public void run() { - if (fZoomEntryList == null) { - return; - } - for (TimeGraphEntry entry : fZoomEntryList) { - if (fMonitor.isCanceled()) { - return; - } - zoom(entry, fMonitor); - } - /* Refresh the arrows when zooming */ - List events = getLinkList(fZoomStartTime, fZoomEndTime, fResolution, fMonitor); - if (events != null) { - fTimeGraphWrapper.getTimeGraphViewer().setLinks(events); - redraw(); - } - } - - private void zoom(TimeGraphEntry entry, IProgressMonitor monitor) { - if (fZoomStartTime <= fStartTime && fZoomEndTime >= fEndTime) { - entry.setZoomedEventList(null); - } else { - List zoomedEventList = getEventList(entry, fZoomStartTime, fZoomEndTime, fResolution, monitor); - if (zoomedEventList != null) { - entry.setZoomedEventList(zoomedEventList); - } - } - redraw(); - for (ITimeGraphEntry child : entry.getChildren()) { - if (fMonitor.isCanceled()) { - return; - } - if (child instanceof TimeGraphEntry) { - zoom((TimeGraphEntry) child, monitor); - } - } - } - - public void cancel() { - fMonitor.setCanceled(true); - } - } - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructs a time graph view that contains either a time graph viewer or - * a time graph combo. - * - * By default, the view uses a time graph viewer. To use a time graph combo, - * the subclass constructor must call {@link #setTreeColumns(String[])} and - * {@link #setTreeLabelProvider(TreeLabelProvider)}. - * - * @param id - * The id of the view - * @param pres - * The presentation provider - */ - public AbstractTimeGraphView(String id, TimeGraphPresentationProvider pres) { - super(id); - fPresentation = pres; - fDisplayWidth = Display.getDefault().getBounds().width; - } - - // ------------------------------------------------------------------------ - // Getters and setters - // ------------------------------------------------------------------------ - - /** - * Getter for the time graph combo - * - * @return The time graph combo, or null if combo is not used - */ - protected TimeGraphCombo getTimeGraphCombo() { - if (fTimeGraphWrapper instanceof TimeGraphComboWrapper) { - return ((TimeGraphComboWrapper) fTimeGraphWrapper).getTimeGraphCombo(); - } - return null; - } - - /** - * Getter for the time graph viewer - * - * @return The time graph viewer - */ - protected TimeGraphViewer getTimeGraphViewer() { - return fTimeGraphWrapper.getTimeGraphViewer(); - } - - /** - * Getter for the presentation provider - * - * @return The time graph presentation provider - * @since 3.0 - */ - protected ITimeGraphPresentationProvider2 getPresentationProvider() { - return fPresentation; - } - - /** - * Sets the tree column labels. - * This should be called from the constructor. - * - * @param columns - * The array of tree column labels - */ - protected void setTreeColumns(final String[] columns) { - fColumns = columns; - } - - /** - * Sets the tree label provider. - * This should be called from the constructor. - * - * @param tlp - * The tree label provider - */ - protected void setTreeLabelProvider(final TreeLabelProvider tlp) { - fLabelProvider = tlp; - } - - /** - * Sets the relative weight of each part of the time graph combo. - * This should be called from the constructor. - * - * @param weights - * The array (length 2) of relative weights of each part of the combo - */ - protected void setWeight(final int[] weights) { - fWeight = weights; - } - - /** - * Sets the filter column labels. - * This should be called from the constructor. - * - * @param filterColumns - * The array of filter column labels - */ - protected void setFilterColumns(final String[] filterColumns) { - fFilterColumns = filterColumns; - } - - /** - * Sets the filter label provider. - * This should be called from the constructor. - * - * @param labelProvider - * The filter label provider - * - * @since 3.0 - */ - protected void setFilterLabelProvider(final TreeLabelProvider labelProvider) { - fFilterLabelProvider = labelProvider; - } - - /** - * Gets the display width - * - * @return the display width - */ - protected int getDisplayWidth() { - return fDisplayWidth; - } - - /** - * Gets the comparator for the entries - * - * @return The entry comparator - */ - protected Comparator getEntryComparator() { - return fEntryComparator; - } - - /** - * Sets the comparator class for the entries - * - * @param comparator - * A comparator object - */ - protected void setEntryComparator(final Comparator comparator) { - fEntryComparator = comparator; - } - - /** - * Gets the trace displayed in the view - * - * @return The trace - */ - protected ITmfTrace getTrace() { - return fTrace; - } - - /** - * Gets the start time - * - * @return The start time - */ - protected long getStartTime() { - return fStartTime; - } - - /** - * Sets the start time - * - * @param time - * The start time - */ - protected void setStartTime(long time) { - fStartTime = time; - } - - /** - * Gets the end time - * - * @return The end time - */ - protected long getEndTime() { - return fEndTime; - } - - /** - * Sets the end time - * - * @param time - * The end time - */ - protected void setEndTime(long time) { - fEndTime = time; - } - - /** - * Gets the entry list for a trace - * - * @param trace - * the trace - * - * @return the entry list map - * @since 3.0 - */ - protected List getEntryList(ITmfTrace trace) { - synchronized (fEntryListMap) { - return fEntryListMap.get(trace); - } - } - - /** - * Adds a trace entry list to the entry list map - * - * @param trace - * the trace to add - * @param list - * the list of time graph entries - */ - protected void putEntryList(ITmfTrace trace, List list) { - synchronized (fEntryListMap) { - fEntryListMap.put(trace, new CopyOnWriteArrayList<>(list)); - } - } - - /** - * Adds a list of entries to a trace's entry list - * - * @param trace - * the trace - * @param list - * the list of time graph entries to add - * @since 3.0 - */ - protected void addToEntryList(ITmfTrace trace, List list) { - synchronized (fEntryListMap) { - List entryList = fEntryListMap.get(trace); - if (entryList == null) { - fEntryListMap.put(trace, new CopyOnWriteArrayList<>(list)); - } else { - entryList.addAll(list); - } - } - } - - /** - * Removes a list of entries from a trace's entry list - * - * @param trace - * the trace - * @param list - * the list of time graph entries to remove - * @since 3.0 - */ - protected void removeFromEntryList(ITmfTrace trace, List list) { - synchronized (fEntryListMap) { - List entryList = fEntryListMap.get(trace); - if (entryList != null) { - entryList.removeAll(list); - } - } - } - - /** - * Text for the "next" button - * - * @return The "next" button text - */ - protected String getNextText() { - return Messages.AbstractTimeGraphtView_NextText; - } - - /** - * Tooltip for the "next" button - * - * @return Tooltip for the "next" button - */ - protected String getNextTooltip() { - return Messages.AbstractTimeGraphView_NextTooltip; - } - - /** - * Text for the "Previous" button - * - * @return The "Previous" button text - */ - protected String getPrevText() { - return Messages.AbstractTimeGraphView_PreviousText; - } - - /** - * Tooltip for the "previous" button - * - * @return Tooltip for the "previous" button - */ - protected String getPrevTooltip() { - return Messages.AbstractTimeGraphView_PreviousTooltip; - } - - // ------------------------------------------------------------------------ - // ViewPart - // ------------------------------------------------------------------------ - - @Override - public void createPartControl(Composite parent) { - if (fColumns == null || fLabelProvider == null) { - fTimeGraphWrapper = new TimeGraphViewerWrapper(parent, SWT.NONE); - TimeGraphViewer viewer = fTimeGraphWrapper.getTimeGraphViewer(); - viewer.setTimeGraphContentProvider(new TimeGraphContentProvider()); - } else { - TimeGraphComboWrapper wrapper = new TimeGraphComboWrapper(parent, SWT.NONE); - fTimeGraphWrapper = wrapper; - TimeGraphCombo combo = wrapper.getTimeGraphCombo(); - combo.setTreeContentProvider(new TreeContentProvider()); - combo.setTreeLabelProvider(fLabelProvider); - combo.setTreeColumns(fColumns); - combo.setFilterContentProvider(new TreeContentProvider()); - combo.setFilterLabelProvider(fFilterLabelProvider); - combo.setFilterColumns(fFilterColumns); - combo.setTimeGraphContentProvider(new TimeGraphContentProvider()); - } - - fTimeGraphWrapper.setTimeGraphProvider(fPresentation); - - fTimeGraphWrapper.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() { - @Override - public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) { - final long startTime = event.getStartTime(); - final long endTime = event.getEndTime(); - TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime)); - broadcast(new TmfRangeSynchSignal(AbstractTimeGraphView.this, range)); - if (fZoomThread != null) { - fZoomThread.cancel(); - } - startZoomThread(startTime, endTime); - } - }); - - fTimeGraphWrapper.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() { - @Override - public void timeSelected(TimeGraphTimeEvent event) { - TmfNanoTimestamp startTime = new TmfNanoTimestamp(event.getBeginTime()); - TmfNanoTimestamp endTime = new TmfNanoTimestamp(event.getEndTime()); - broadcast(new TmfTimeSynchSignal(AbstractTimeGraphView.this, startTime, endTime)); - } - }); - - fTimeGraphWrapper.getTimeGraphViewer().setTimeFormat(TimeFormat.CALENDAR); - - IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager(); - fTimeGraphWrapper.getTimeGraphViewer().getTimeGraphControl().setStatusLineManager(statusLineManager); - - // View Action Handling - makeActions(); - contributeToActionBars(); - - ITmfTrace trace = getActiveTrace(); - if (trace != null) { - traceSelected(new TmfTraceSelectedSignal(this, trace)); - } - - // make selection available to other views - getSite().setSelectionProvider(fTimeGraphWrapper.getSelectionProvider()); - } - - @Override - public void setFocus() { - fTimeGraphWrapper.setFocus(); - } - - // ------------------------------------------------------------------------ - // Signal handlers - // ------------------------------------------------------------------------ - - /** - * Handler for the trace opened signal. - * - * @param signal - * The incoming signal - * @since 2.0 - */ - @TmfSignalHandler - public void traceOpened(TmfTraceOpenedSignal signal) { - fTrace = signal.getTrace(); - loadTrace(); - } - - /** - * Handler for the trace selected signal - * - * @param signal - * The incoming signal - */ - @TmfSignalHandler - public void traceSelected(final TmfTraceSelectedSignal signal) { - if (signal.getTrace() == fTrace) { - return; - } - fTrace = signal.getTrace(); - - loadTrace(); - } - - /** - * Trace is closed: clear the data structures and the view - * - * @param signal - * the signal received - */ - @TmfSignalHandler - public void traceClosed(final TmfTraceClosedSignal signal) { - synchronized (fBuildThreadMap) { - for (ITmfTrace trace : getTracesToBuild(signal.getTrace())) { - BuildThread buildThread = fBuildThreadMap.remove(trace); - if (buildThread != null) { - buildThread.cancel(); - } - } - } - synchronized (fEntryListMap) { - fEntryListMap.remove(signal.getTrace()); - } - if (signal.getTrace() == fTrace) { - fTrace = null; - fStartTime = 0; - fEndTime = 0; - if (fZoomThread != null) { - fZoomThread.cancel(); - } - refresh(); - } - } - - /** - * Handler for the time synch signal - * - * @param signal - * The signal that's received - */ - @TmfSignalHandler - public void synchToTime(final TmfTimeSynchSignal signal) { - if (signal.getSource() == this || fTrace == null) { - return; - } - final long beginTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - final long endTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - if (fTimeGraphWrapper.isDisposed()) { - return; - } - if (beginTime == endTime) { - fTimeGraphWrapper.getTimeGraphViewer().setSelectedTime(beginTime, true); - } else { - fTimeGraphWrapper.getTimeGraphViewer().setSelectionRange(beginTime, endTime); - } - startZoomThread(fTimeGraphWrapper.getTimeGraphViewer().getTime0(), fTimeGraphWrapper.getTimeGraphViewer().getTime1()); - - synchingToTime(beginTime); - } - }); - } - - /** - * Handler for the range synch signal - * - * @param signal - * The signal that's received - */ - @TmfSignalHandler - public void synchToRange(final TmfRangeSynchSignal signal) { - if (signal.getSource() == this || fTrace == null) { - return; - } - if (signal.getCurrentRange().getIntersection(fTrace.getTimeRange()) == null) { - return; - } - final long startTime = signal.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - final long endTime = signal.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - if (fTimeGraphWrapper.isDisposed()) { - return; - } - fTimeGraphWrapper.getTimeGraphViewer().setStartFinishTime(startTime, endTime); - startZoomThread(startTime, endTime); - } - }); - } - - /** - * @param signal the format of the timestamps was updated. - * @since 2.1 - */ - @TmfSignalHandler - public void updateTimeFormat( final TmfTimestampFormatUpdateSignal signal){ - fTimeGraphWrapper.refresh(); - } - - // ------------------------------------------------------------------------ - // Internal - // ------------------------------------------------------------------------ - - private void loadTrace() { - synchronized (fEntryListMap) { - fEntryList = fEntryListMap.get(fTrace); - if (fEntryList == null) { - rebuild(); - } else { - fStartTime = fTrace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - fEndTime = fTrace.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - refresh(); - } - } - } - - /** - * Forces a rebuild of the entries list, even if entries already exist for this trace - * @since 3.0 - */ - protected void rebuild() { - setStartTime(Long.MAX_VALUE); - setEndTime(Long.MIN_VALUE); - synchronized (fBuildThreadMap) { - for (ITmfTrace trace : getTracesToBuild(fTrace)) { - BuildThread buildThread = new BuildThread(trace, fTrace, getName()); - fBuildThreadMap.put(trace, buildThread); - buildThread.start(); - } - } - } - - /** - * Method called when synching to a given timestamp. Inheriting classes can - * perform actions here to update the view at the given timestamp. - * - * @param time - * The currently selected time - */ - protected void synchingToTime(long time) { - - } - - /** - * Return the list of traces whose data or analysis results will be used to - * populate the view. By default, if the trace is an experiment, the traces - * under it will be returned, otherwise, the trace itself is returned. - * - * A build thread will be started for each trace returned by this method, - * some of which may receive events in live streaming mode. - * - * @param trace - * The trace associated with this view - * @return List of traces with data to display - * @since 3.0 - */ - protected Iterable getTracesToBuild(ITmfTrace trace) { - return Arrays.asList(TmfTraceManager.getTraceSet(trace)); - } - - /** - * Build the entries list to show in this time graph - * - * Called from the BuildThread - * - * @param trace - * The trace being built - * @param parentTrace - * The parent of the trace set, or the trace itself - * @param monitor - * The progress monitor object - * @since 3.0 - */ - protected abstract void buildEventList(ITmfTrace trace, ITmfTrace parentTrace, IProgressMonitor monitor); - - /** - * Gets the list of event for an entry in a given timerange - * - * @param entry - * The entry to get events for - * @param startTime - * Start of the time range - * @param endTime - * End of the time range - * @param resolution - * The resolution - * @param monitor - * The progress monitor object - * @return The list of events for the entry - */ - protected abstract @Nullable List getEventList(TimeGraphEntry entry, - long startTime, long endTime, long resolution, - IProgressMonitor monitor); - - /** - * Gets the list of links (displayed as arrows) for a trace in a given - * timerange. Default implementation returns an empty list. - * - * @param startTime - * Start of the time range - * @param endTime - * End of the time range - * @param resolution - * The resolution - * @param monitor - * The progress monitor object - * @return The list of link events - * @since 2.1 - */ - protected List getLinkList(long startTime, long endTime, - long resolution, IProgressMonitor monitor) { - return new ArrayList<>(); - } - - - /** - * Refresh the display - */ - protected void refresh() { - TmfUiRefreshHandler.getInstance().queueUpdate(this, new Runnable() { - @Override - public void run() { - if (fTimeGraphWrapper.isDisposed()) { - return; - } - boolean hasEntries = false; - synchronized (fEntryListMap) { - fEntryList = fEntryListMap.get(fTrace); - if (fEntryList == null) { - fEntryList = new CopyOnWriteArrayList<>(); - } else if (fEntryComparator != null) { - List list = new ArrayList<>(fEntryList); - Collections.sort(list, fEntryComparator); - fEntryList.clear(); - fEntryList.addAll(list); - } - hasEntries = fEntryList.size() != 0; - } - if (fEntryList != fTimeGraphWrapper.getInput()) { - fTimeGraphWrapper.setInput(fEntryList); - } else { - fTimeGraphWrapper.refresh(); - } - fTimeGraphWrapper.getTimeGraphViewer().setTimeBounds(fStartTime, fEndTime); - - long selectionBeginTime = fTrace == null ? 0 : fTraceManager.getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - long selectionEndTime = fTrace == null ? 0 : fTraceManager.getSelectionEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - long startTime = fTrace == null ? 0 : fTraceManager.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - long endTime = fTrace == null ? 0 : fTraceManager.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); - startTime = Math.max(startTime, fStartTime); - endTime = Math.min(endTime, fEndTime); - fTimeGraphWrapper.getTimeGraphViewer().setSelectionRange(selectionBeginTime, selectionEndTime); - fTimeGraphWrapper.getTimeGraphViewer().setStartFinishTime(startTime, endTime); - - if (fTimeGraphWrapper instanceof TimeGraphComboWrapper && !fPackDone) { - for (TreeColumn column : ((TimeGraphComboWrapper) fTimeGraphWrapper).getTreeViewer().getTree().getColumns()) { - column.pack(); - } - if (hasEntries) { - fPackDone = true; - } - } - - startZoomThread(startTime, endTime); - } - }); - } - - /** - * Redraw the canvas - */ - protected void redraw() { - synchronized (fSyncObj) { - if (fRedrawState == State.IDLE) { - fRedrawState = State.BUSY; - } else { - fRedrawState = State.PENDING; - return; - } - } - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - if (fTimeGraphWrapper.isDisposed()) { - return; - } - fTimeGraphWrapper.redraw(); - fTimeGraphWrapper.update(); - synchronized (fSyncObj) { - if (fRedrawState == State.PENDING) { - fRedrawState = State.IDLE; - redraw(); - } else { - fRedrawState = State.IDLE; - } - } - } - }); - } - - private void startZoomThread(long startTime, long endTime) { - if (fZoomThread != null) { - fZoomThread.cancel(); - } - fZoomThread = new ZoomThread(fEntryList, startTime, endTime, getName()); - fZoomThread.start(); - } - - private void makeActions() { - fPreviousResourceAction = fTimeGraphWrapper.getTimeGraphViewer().getPreviousItemAction(); - fPreviousResourceAction.setText(getPrevText()); - fPreviousResourceAction.setToolTipText(getPrevTooltip()); - fNextResourceAction = fTimeGraphWrapper.getTimeGraphViewer().getNextItemAction(); - fNextResourceAction.setText(getNextText()); - fNextResourceAction.setToolTipText(getNextTooltip()); - } - - private void contributeToActionBars() { - IActionBars bars = getViewSite().getActionBars(); - fillLocalToolBar(bars.getToolBarManager()); - } - - /** - * Add actions to local tool bar manager - * - * @param manager the tool bar manager - */ - protected void fillLocalToolBar(IToolBarManager manager) { - if (fTimeGraphWrapper instanceof TimeGraphComboWrapper) { - if (fFilterColumns != null && fFilterLabelProvider != null && fFilterColumns.length > 0) { - manager.add(((TimeGraphComboWrapper) fTimeGraphWrapper).getShowFilterAction()); - } - } - manager.add(fTimeGraphWrapper.getTimeGraphViewer().getShowLegendAction()); - manager.add(new Separator()); - manager.add(fTimeGraphWrapper.getTimeGraphViewer().getResetScaleAction()); - manager.add(fTimeGraphWrapper.getTimeGraphViewer().getPreviousEventAction()); - manager.add(fTimeGraphWrapper.getTimeGraphViewer().getNextEventAction()); - manager.add(fPreviousResourceAction); - manager.add(fNextResourceAction); - manager.add(fTimeGraphWrapper.getTimeGraphViewer().getZoomInAction()); - manager.add(fTimeGraphWrapper.getTimeGraphViewer().getZoomOutAction()); - manager.add(new Separator()); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/Messages.java deleted file mode 100644 index 1d0ff0c871..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/Messages.java +++ /dev/null @@ -1,38 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.timegraph; - -import org.eclipse.osgi.util.NLS; - -/** - * Generic messages for the bar charts - * - * @since 2.1 - */ -@SuppressWarnings("javadoc") -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.ui.views.timegraph.messages"; //$NON-NLS-1$ - - public static String AbstractTimeGraphtView_NextText; - public static String AbstractTimeGraphView_NextTooltip; - public static String AbstractTimeGraphView_PreviousText; - public static String AbstractTimeGraphView_PreviousTooltip; - public static String TimeGraphPresentationProvider_multipleStates; - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/messages.properties deleted file mode 100644 index 52adaa617b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/messages.properties +++ /dev/null @@ -1,16 +0,0 @@ -############################################################################### -# Copyright (c) 2014 Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Ericsson - Initial API and implementation -############################################################################### -AbstractTimeGraphtView_NextText=Next -AbstractTimeGraphView_NextTooltip=Next element -AbstractTimeGraphView_PreviousText=Previous -AbstractTimeGraphView_PreviousTooltip=Previous element -TimeGraphPresentationProvider_multipleStates=multiple states diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/DiagramToolTip.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/DiagramToolTip.java deleted file mode 100755 index 08accdd9f4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/DiagramToolTip.java +++ /dev/null @@ -1,131 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.FontMetrics; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -/** - *

- * This class is used to reproduce the same tooltip behavior on Windows and Linux when the mouse hovers over the - * sequence diagram - *

- * - * @version 1.0 - * @author sveyrier - */ -public class DiagramToolTip { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - private static final int CHARACTERS_PER_COLUMN = 100; - private static final int DEFAULT_CURSOR_HEIGHT = 32; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The parent control where the tooltip must be drawn. - */ - private Control fParent = null; - /** - * The tooltip shell. - */ - private Shell fToolTipShell = null; - /** - * The text box. - */ - private Text fTextBox = null; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Create a new tooltip for the given parent control - * - * @param parent the parent control. - */ - public DiagramToolTip(Control parent) { - fParent = parent; - fToolTipShell = new Shell(fParent.getShell(), SWT.MULTI); - fToolTipShell.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); - fTextBox = new Text(fToolTipShell, SWT.WRAP | SWT.MULTI); - fTextBox.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - /** - * Display the tooltip using the given text The tooltip will stay on screen until it is told otherwise - * - * @param value the text to display - */ - public void showToolTip(String value) { - if ((value == null) || (value.equalsIgnoreCase(""))) { //$NON-NLS-1$ - fToolTipShell.setVisible(false); - return; - } - - int w = fToolTipShell.getBounds().width; - Point hr = Display.getDefault().getCursorLocation(); - int cursorH = DEFAULT_CURSOR_HEIGHT; - for (int i = 0; i < Display.getDefault().getCursorSizes().length; i++) { - if (Display.getDefault().getCursorSizes()[i].y < cursorH) { - cursorH = Display.getDefault().getCursorSizes()[i].y; - } - } - if (hr.x + w > Display.getDefault().getBounds().width) { - int tempX = (hr.x + w) - Display.getDefault().getBounds().width; - if (tempX > Display.getDefault().getBounds().width) { - hr.x = 0; - } - hr.x = hr.x - tempX; - } - fTextBox.setText(value); - GC gc = new GC(fTextBox); - FontMetrics fm = gc.getFontMetrics(); - gc.dispose(); - int width = CHARACTERS_PER_COLUMN * fm.getAverageCharWidth(); - fTextBox.setSize(fTextBox.computeSize(width, fTextBox.getLineCount() * fTextBox.getLineHeight())); - fToolTipShell.setLocation(hr.x, hr.y + cursorH); - fToolTipShell.setSize(fTextBox.getSize()); - fTextBox.setVisible(true); - fToolTipShell.setVisible(true); - } - - /** - * Hide the tooltip - */ - public void hideToolTip() { - fToolTipShell.setVisible(false); - } - - /** - * @return parent control - * @since 2.0 - */ - protected Control getParent() { - return fParent; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/DrawableToolTip.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/DrawableToolTip.java deleted file mode 100755 index 89d1a5a377..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/DrawableToolTip.java +++ /dev/null @@ -1,305 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - *

- * This class is used to reproduce the same tooltip behavior on Windows and Linux when the mouse move hover the time - * compression bar used to display elapsed time using a tooltip. The tooltip is composed of 2 parts, the text value and - * below, a scale to visually locate the value in a time range (usually the minimum an maximum elapsed time in the whole - * diagram) - *

- * - * @version 1.0 - * @author sveyrier - */ -public class DrawableToolTip implements PaintListener { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - private static final int HORIZONTAL_MARGIN = 10; - private static final int VERTICAL_MARGIN = 10; - private static final int TEXT_SCALE_MARGIN = 20; - private static final int SCALE_LENGTH = 100; - private static final int SHELL_WIDTH = 200; - private static final int SHELL_HEIGHT = 50; - private static final int NUMBER_STEPS = 10; - private static final int BASE_RED_VALUE = 255; - private static final int BASE_GREEN_BLUE_VALUE = 225; - private static final int COLOR_STEP = 25; - private static final int BOUNDS_Y_OFFSET = 26; - private static final int RECTANGLE_HEIGHT = 11; - private static final int DEFAULT_LINE_WIDTH = 10; - private static final int BORDER_LINE_WIDTH = 14; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The tooltip shell - */ - private Shell fToolTipShell = null; - /** - * The Time range data. - */ - private TmfTimeRange fMinMaxRange; - /** - * The current time. - */ - private ITmfTimestamp fCurrentValue; - /** - * The horizontal margin used for drawing. - */ - private static int fHorMargin = HORIZONTAL_MARGIN; - /** - * The vertical margin used for drawing. - */ - private static int fVertMargin = VERTICAL_MARGIN; - /** - * The minimum text scale margin. - */ - private static int fTextScaleMargin = TEXT_SCALE_MARGIN; - /** - * The length of the text scale. - */ - private static int fScaleLength = SCALE_LENGTH; - /** - * The text to display - */ - private String fMessage; - /** - * The color array used to represent the 10 time range slices - */ - private Color[] fColors; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Creates a drawable tool tip instance. - * - * @param parent The parent composite. - */ - public DrawableToolTip(Composite parent) { - fToolTipShell = new Shell(parent.getShell(), SWT.ON_TOP); - fToolTipShell.setLayout(new RowLayout()); - fToolTipShell.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); - fToolTipShell.addPaintListener(this); - fToolTipShell.setSize(SHELL_WIDTH, SHELL_HEIGHT); - - fColors = new Color[NUMBER_STEPS]; - int greenBlue = BASE_GREEN_BLUE_VALUE; - final int step = COLOR_STEP; - for (int i = 0; i < fColors.length; i++) { - fColors[i] = new Color(Display.getDefault(), BASE_RED_VALUE, greenBlue, greenBlue); - greenBlue -= step; - } - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - /** - * Returns the message to display. - * - * @return the message to display. - */ - public String getText() { - return fMessage; - } - - /** - * Returns teh current time to display. - * - * @return the current time to display - */ - public String getAccessibleText() { - return fCurrentValue.toString(); - } - - /** - * Returns the horizontal margin. - * - * @return the horizontal margin. - */ - protected static int getHorizontalMargin() { - return fHorMargin; - } - - /** - * Sets the horizontal margin. - * - * @param margin The margin to set. - */ - protected static void setHorizontalMargin(int margin) { - fHorMargin = margin; - } - - /** - * Returns the vertical margin. - * - * @return the vertical margin. - */ - protected static int getVerticalMargin() { - return fVertMargin; - } - - /** - * Sets the vertical margin. - * - * @param margin The margin to set. - */ - protected static void setVerticalMargin(int margin) { - fVertMargin = margin; - } - - /** - * Returns the text scale margin. - * - * @return the text scale margin. - */ - protected static int getTextScaleMargin() { - return fTextScaleMargin; - } - - /** - * Sets the text scale margin. - * @param textScaleMargin The margin to set. - */ - protected static void setTestScaleMargin(int textScaleMargin) { - fTextScaleMargin = textScaleMargin; - } - - /** - * Returns the scale length. - * - * @return the scale length. - */ - protected static int getScaleLength() { - return fScaleLength; - } - - /** - * Sets the scale length. - * - * @param scaleLength The scale length to set. - */ - protected static void setScaleLength(int scaleLength) { - fScaleLength = scaleLength; - } - - /** - * Display the tooltip using the given time range(min,max) the current value and the time unit The tooltip will stay - * on screen until it is told otherwise - * - * @param value the current in the scale - * @param min the scale min - * @param max the scale max - * @since 2.0 - */ - public void showToolTip(ITmfTimestamp value, ITmfTimestamp min, ITmfTimestamp max) { - fMinMaxRange = new TmfTimeRange(min, max); - fCurrentValue = value; - - int w = fToolTipShell.getBounds().width; - int h = fToolTipShell.getBounds().height; - Point hr = Display.getDefault().getCursorLocation(); - fToolTipShell.setBounds(hr.x, hr.y + BOUNDS_Y_OFFSET, w, h); - fToolTipShell.setVisible(true); - } - - /** - * Hide the tooltip. - */ - public void hideToolTip() { - fToolTipShell.setVisible(false); - } - - /** - * Disposes the system resource used by this kind of toolTips (a colors array essentially) - */ - public void dispose() { - for (int i = 0; i < fColors.length; i++) { - fColors[i].dispose(); - } - } - - @Override - public void paintControl(PaintEvent event) { - fMessage = Messages.SequenceDiagram_Delta + " " + fCurrentValue.toString(); //$NON-NLS-1$ - Point size = event.gc.textExtent(fMessage); - if (size.x < fScaleLength) { - size.x = fScaleLength; - } - event.gc.drawText(fMessage, fHorMargin, fVertMargin, true); - event.gc.drawLine(fHorMargin, fVertMargin + fTextScaleMargin + size.y, fHorMargin + fScaleLength, fVertMargin + fTextScaleMargin + size.y); - - int step = fScaleLength / NUMBER_STEPS; - - ITmfTimestamp minMaxdelta = fMinMaxRange.getEndTime().getDelta(fMinMaxRange.getStartTime()); - double gr = (minMaxdelta.getValue()) / (double) NUMBER_STEPS; - - ITmfTimestamp delta = fCurrentValue.getDelta(fMinMaxRange.getStartTime()); - long absDelta = Math.abs(delta.getValue()); - - int colIndex = 0; - if (gr != 0) { - colIndex = Math.round((float) (absDelta / gr)); - if (colIndex > fColors.length) { - colIndex = fColors.length; - } else if (colIndex <= 1) { - colIndex = 1; - } - } else { - colIndex = 1; - } - - for (int i = 0; i <= NUMBER_STEPS; i++) { - if (i < NUMBER_STEPS) { - event.gc.setBackground(fColors[i]); - } - if ((i < colIndex) && (i < NUMBER_STEPS)) { - event.gc.fillRectangle(fHorMargin + i * step, fVertMargin + fTextScaleMargin + size.y - 5, step, RECTANGLE_HEIGHT); - } - if (i == 0) { - event.gc.drawText(Messages.SequenceDiagram_Min, fHorMargin, size.y + 2 * fVertMargin + fTextScaleMargin, true); - } - if (i == 0) { - int len = event.gc.textExtent(Messages.SequenceDiagram_Max).x; - event.gc.drawText(Messages.SequenceDiagram_Max, fHorMargin + fScaleLength - len + 1, size.y + 2 * fVertMargin + fTextScaleMargin, true); - } - int lineWidth = DEFAULT_LINE_WIDTH; - if ((i == 0) || (i == NUMBER_STEPS)) { - lineWidth = BORDER_LINE_WIDTH; - } - event.gc.drawLine(fHorMargin + i * step, fVertMargin + fTextScaleMargin + size.y - lineWidth / 2, fHorMargin + i * step, fVertMargin + fTextScaleMargin + size.y + lineWidth / 2); - } - fToolTipShell.setSize(size.x + 2 * fHorMargin + 2, 2 * size.y + 3 * fVertMargin + fTextScaleMargin); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/ITimeCompressionListener.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/ITimeCompressionListener.java deleted file mode 100755 index e00b9ea500..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/ITimeCompressionListener.java +++ /dev/null @@ -1,42 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor; - -/** - *

- * Listener interface for the time compression bar to notify about dela selection. - *

- * - * @author sveyrier - * @version 1.0 - */ -public interface ITimeCompressionListener { - - /** - * Notifies listeners about a selected delta. - * - * @param lifeline - * The current lifeline. - * @param startEvent - * The start event selected. - * @param nbEvent - * A number of events. - * @param color - * The current color to use. - */ - void deltaSelected(Lifeline lifeline, int startEvent, int nbEvent, IColor color); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/NGC.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/NGC.java deleted file mode 100755 index e1642a3ff9..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/NGC.java +++ /dev/null @@ -1,988 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IFont; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IImage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.impl.ColorImpl; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Display; - -/** - *

- * This class implements the graphical context for the sequence diagram widgets. - *

- * - * @version 1.0 - * @author sveyrier - */ -public class NGC implements IGC { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The graphical context. - */ - private GC fContext; - /** - * The reference to the sequence diagram view. - */ - private SDWidget fView; - /** - * A reference to the last used font. - */ - private Font fTempFont = null; - /** - * The color of the gradient. - */ - private IColor fGradientColor = null; - /** - * The color of the background. - */ - private IColor fBackground = null; - /** - * The color of the foreground. - */ - private IColor fForeground = null; - /** - * The current visible y screen bounds - */ - private int fVisibleY; - /** - * The current visible x screen bound. - */ - private int fVisibleX; - /** - * The current yx value (view visible height - visible screen bounds) - */ - private int yx; - /** - * The current xx value (view visible width - visible screen bounds) - */ - private int xx; - /** - * true to draw with focus else false. - */ - private boolean fDrawWithFocus = false; - - /** - * The static visible screen bounds. - */ - private static int fVisibleScreenBounds = 0; - - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor. - * - * @param scrollView A sequence diagram view reference. - * @param gc A graphical context. - */ - public NGC(SDWidget scrollView, GC gc) { - fContext = gc; - fView = scrollView; - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public void setLineStyle(int style) { - fContext.setLineStyle(style); - } - - @Override - public int getLineStyle() { - return fContext.getLineStyle(); - } - - @Override - public int getContentsX() { - return Math.round(fView.getContentsX() / fView.getZoomValue()); - } - - @Override - public int getContentsY() { - return Math.round(fView.getContentsY() / fView.getZoomValue()); - } - - @Override - public int getVisibleWidth() { - return Math.round(fView.getVisibleWidth() / fView.getZoomValue()); - } - - @Override - public int getVisibleHeight() { - return Math.round(fView.getVisibleHeight() / fView.getZoomValue()); - } - - /** - * Returns the current visible y screen bounds. - * - * @return the current visible y screen bounds - * @since 2.0 - */ - protected int getVisibleY() { - return fVisibleY; - } - - /** - * Sets the current visible y screen bounds. - * - * @param visibleY - * the current visible y screen bounds - * @since 2.0 - */ - protected void setVisibleY(int visibleY) { - fVisibleY = visibleY; - } - - /** - * Returns the current visible x screen bound. - * - * @return the current visible x screen bound. - * @since 2.0 - * - */ - protected int getfVisibleX() { - return fVisibleX; - } - - /** - * Sets the current visible x screen bound. - * - * @param visibleX - * the current visible x screen bound. - * @since 2.0 - * - */ - protected void setVisibleX(int visibleX) { - fVisibleX = visibleX; - } - - /** - * Returns current yx value (view visible height - visible screen bounds). - * - * @return current yx value - * @since 2.0 - */ - protected int getYx() { - return yx; - } - - /** - * Sets current yx value (view visible height - visible screen bounds). - * - * @param yx - * current yx value - * @since 2.0 - */ - protected void setYx(int yx) { - this.yx = yx; - } - - /** - * Returns the current xx value (view visible width - visible screen bounds) - * - * @return the current xx value - * @since 2.0 - */ - protected int getXx() { - return xx; - } - - /** - * Sets the current xx value (view visible width - visible screen bounds) - * - * @param xx - * the current xx value - * @since 2.0 - */ - protected void setXx(int xx) { - this.xx = xx; - } - - @Override - public int contentsToViewX(int x) { - return fView.contentsToViewX(x); - } - - @Override - public int contentsToViewY(int y) { - return fView.contentsToViewY(y); - } - - /** - * Get code for drawings at given x and y position. - * - * @param x The x position - * @param y The y position. - * @return A code for top, bottom, right and left - */ - protected byte code(int x, int y) { - byte c = 0; - fVisibleY = fVisibleScreenBounds; - fVisibleX = fVisibleScreenBounds; - yx = fView.getVisibleHeight() + fVisibleScreenBounds; - xx = fView.getVisibleWidth() + fVisibleScreenBounds; - if (y > yx) { - c |= 0x01; // top - } else if (y < fVisibleY) { - c |= 0x02; // bottom - } - - if (x > xx) { - c |= 0x04; // right - } else if (x < fVisibleX) { - c |= 0x08; // left - } - return c; - } - - @Override - public void drawLine(int x1, int y1, int x2, int y2) { - int localX1 = x1; - int localY1 = y1; - int localX2 = x2; - int localY2 = y2; - - localX1 = Math.round(localX1 * fView.getZoomValue()); - localY1 = Math.round(localY1 * fView.getZoomValue()); - localX2 = Math.round(localX2 * fView.getZoomValue()); - localY2 = Math.round(localY2 * fView.getZoomValue()); - localX1 = fView.contentsToViewX(localX1); - localY1 = fView.contentsToViewY(localY1); - localX2 = fView.contentsToViewX(localX2); - localY2 = fView.contentsToViewY(localY2); - - byte code1 = code(localX1, localY1); - byte code2 = code(localX2, localY2); - byte codex; - boolean draw = false; - boolean end = false; - int x = 0, y = 0; - - do { - if (code1 == 0 && code2 == 0) { - draw = true; - end = true; - } else if ((code1 & code2) != 0) { - end = true; - } else { - codex = (code1 != 0) ? code1 : code2; - if ((codex & 0x01) != 0) { // top - x = localX1 + ((localX2 - localX1) * (yx - localY1)) / (localY2 - localY1); - y = yx; - } else if ((codex & 0x02) != 0) { // bottom - x = localX1 + ((localX2 - localX1) * (fVisibleY - localY1)) / (localY2 - localY1); - y = fVisibleY; - } else if ((codex & 0x04) != 0) { // right - y = localY1 + ((localY2 - localY1) * (xx - localX1)) / (localX2 - localX1); - x = xx; - } else if ((codex & 0x08) != 0) { // left - y = localY1 + ((localY2 - localY1) * (fVisibleX - localX1)) / (localX2 - localX1); - x = fVisibleX; - } - - if (codex == code1) { - localX1 = x; - localY1 = y; - code1 = code(localX1, localY1); - } else { - localX2 = x; - localY2 = y; - code2 = code(localX2, localY2); - } - } - } while (!end); - - if (draw) { - fContext.drawLine(localX1, localY1, localX2, localY2); - } - } - - @Override - public void drawRectangle(int x, int y, int width, int height) { - int localX = x; - int localY = y; - int localWidth = width; - int localHeight = height; - - localX = Math.round(localX * fView.getZoomValue()); - // Workaround to avoid problems for some special cases (not very nice) - if (localY != getContentsY()) { - localY = Math.round(localY * fView.getZoomValue()); - localY = fView.contentsToViewY(localY); - } else { - localY = 0; - } - localWidth = Math.round(localWidth * fView.getZoomValue()); - localHeight = Math.round(localHeight * fView.getZoomValue()); - localX = fView.contentsToViewX(localX); - - if (localX < -fVisibleScreenBounds) { - localWidth = localWidth + localX + fVisibleScreenBounds; - localX = -fVisibleScreenBounds; - } - if (localY < -fVisibleScreenBounds) { - localHeight = localHeight + localY + fVisibleScreenBounds; - localY = -fVisibleScreenBounds; - } - if ((localWidth < -fVisibleScreenBounds) && (localX + localWidth < -fVisibleScreenBounds)) { - localWidth = -fVisibleScreenBounds; - } else if (localWidth + localX > fView.getVisibleWidth() + fVisibleScreenBounds) { - localWidth = fView.getVisibleWidth() + fVisibleScreenBounds - localX; - } - if ((localHeight < -fVisibleScreenBounds) && (localY + localHeight < -fVisibleScreenBounds)) { - localHeight = -fVisibleScreenBounds; - } else if (localHeight + localY > fView.getVisibleHeight() + fVisibleScreenBounds) { - localHeight = fView.getVisibleHeight() + fVisibleScreenBounds - localY; - } - fContext.drawRectangle(localX, localY, localWidth, localHeight); - } - - @Override - public void drawFocus(int x, int y, int width, int height) { - int localX = x; - int localY = y; - int localWidth = width; - int localHeight = height; - - IColor bC = getBackground(); - IColor fC = getForeground(); - - if (localWidth < 0) { - localX = localX + localWidth; - localWidth = -localWidth; - } - - if (localHeight < 0) { - localY = localY + localHeight; - localHeight = -localHeight; - } - - localX = Math.round(localX * fView.getZoomValue()); - localY = Math.round(localY * fView.getZoomValue()); - localWidth = Math.round(localWidth * fView.getZoomValue()); - localHeight = Math.round(localHeight * fView.getZoomValue()); - - setForeground(SDViewPref.getInstance().getForeGroundColorSelection()); - setBackground(SDViewPref.getInstance().getBackGroundColorSelection()); - - fContext.drawFocus(fView.contentsToViewX(localX - 1), fView.contentsToViewY(localY - 1), localWidth + 3, localHeight + 3); - - setBackground(bC); - setForeground(fC); - } - - @Override - public void fillPolygon(int[] points) { - int len = (points.length / 2) * 2; - int[] localPoint = new int[len]; - for (int i = 0; i < len; i++) { - localPoint[i] = fView.contentsToViewX(Math.round(points[i] * fView.getZoomValue())); - i++; - localPoint[i] = fView.contentsToViewY(Math.round(points[i] * fView.getZoomValue())); - } - - if (validatePolygonHeight(localPoint) <= 0) { - return; - } - - fContext.fillPolygon(localPoint); - } - - @Override - public void drawPolygon(int[] points) { - int len = (points.length / 2) * 2; - int[] localPoint = new int[len]; - for (int i = 0; i < len; i++) { - localPoint[i] = fView.contentsToViewX(Math.round(points[i] * fView.getZoomValue())); - i++; - localPoint[i] = fView.contentsToViewY(Math.round(points[i] * fView.getZoomValue())); - } - - if (validatePolygonHeight(localPoint) <= 0) { - return; - } - - fContext.drawPolygon(localPoint); - } - - @Override - public void fillRectangle(int x, int y, int width, int height) { - int localX = x; - int localY = y; - int localWidth = width; - int localHeight = height; - - localX = Math.round(localX * fView.getZoomValue()); - // Workaround to avoid problems for some special cases (not very nice) - if (localY != getContentsY()) { - localY = Math.round(localY * fView.getZoomValue()); - localY = fView.contentsToViewY(localY) + 1; - } else { - localY = 1; - } - localWidth = Math.round(localWidth * fView.getZoomValue()) - 1; - localHeight = Math.round(localHeight * fView.getZoomValue()) - 1; - localX = fView.contentsToViewX(localX) + 1; - if (localX < -fVisibleScreenBounds) { - localWidth = localWidth + localX + fVisibleScreenBounds; - localX = -fVisibleScreenBounds; - } - if (localY < -fVisibleScreenBounds) { - localHeight = localHeight + localY + fVisibleScreenBounds; - localY = -fVisibleScreenBounds; - } - if ((localWidth < -fVisibleScreenBounds) && (localX + localWidth < -fVisibleScreenBounds)) { - localWidth = -fVisibleScreenBounds; - } else if (localWidth + localX > fView.getVisibleWidth() + fVisibleScreenBounds) { - localWidth = fView.getVisibleWidth() + fVisibleScreenBounds - localX; - } - if ((localHeight < -fVisibleScreenBounds) && (localY + localHeight < -fVisibleScreenBounds)) { - localHeight = -fVisibleScreenBounds; - } else if (localHeight + localY > fView.getVisibleHeight() + fVisibleScreenBounds) { - localHeight = fView.getVisibleHeight() + fVisibleScreenBounds - localY; - } - fContext.fillRectangle(localX, localY, localWidth, localHeight); - } - - @Override - public void fillGradientRectangle(int x, int y, int width, int height, boolean isVertical) { - int localX = x; - int localY = y; - int localWidth = width; - int localHeight = height; - - localX = Math.round(localX * fView.getZoomValue()); - localY = Math.round(localY * fView.getZoomValue()); - localWidth = Math.round(localWidth * fView.getZoomValue()); - localHeight = Math.round(localHeight * fView.getZoomValue()); - IColor tempColor = fForeground; - setForeground(fGradientColor); - localX = fView.contentsToViewX(localX); - localY = fView.contentsToViewY(localY); - - if (localX < -fVisibleScreenBounds) { - localWidth = localWidth + localX + fVisibleScreenBounds; - localX = -fVisibleScreenBounds; - } - if (localY < -fVisibleScreenBounds) { - localHeight = localHeight + localY + fVisibleScreenBounds; - localY = -fVisibleScreenBounds; - } - - if ((localWidth < -fVisibleScreenBounds) && (localX + localWidth < -fVisibleScreenBounds)) { - localWidth = -fVisibleScreenBounds; - } else if (localWidth + localX > fView.getVisibleWidth() + fVisibleScreenBounds) { - localWidth = fView.getVisibleWidth() + fVisibleScreenBounds - localX; - } - if ((localHeight < -fVisibleScreenBounds) && (localY + localHeight < -fVisibleScreenBounds)) { - localHeight = -fVisibleScreenBounds; - } else if (localHeight + localY > fView.getVisibleHeight() + fVisibleScreenBounds) { - localHeight = fView.getVisibleHeight() + fVisibleScreenBounds - localY; - } - if (isVertical) { - fContext.fillGradientRectangle(localX, localY, localWidth, localHeight, isVertical); - } - else { - fContext.fillGradientRectangle(localX + localWidth, localY, -localWidth, localHeight + 1, isVertical); - } - setForeground(tempColor); - } - - @Override - public int textExtent(String name) { - return fContext.textExtent(name).x; - } - - @Override - public void drawText(String string, int x, int y, boolean isTrans) { - int localX = x; - int localY = y; - - localX = Math.round(localX * fView.getZoomValue()); - localY = Math.round(localY * fView.getZoomValue()); - fContext.drawText(string, fView.contentsToViewX(localX), fView.contentsToViewY(localY), isTrans); - if (fDrawWithFocus) { - Point r = fContext.textExtent(string); - fContext.drawFocus(localX - 1, localY - 1, r.x + 2, r.y + 2); - } - } - - @Override - public void drawText(String string, int x, int y) { - int localX = x; - int localY = y; - - localX = Math.round(localX * fView.getZoomValue()); - localY = Math.round(localY * fView.getZoomValue()); - fContext.drawText(string, fView.contentsToViewX(localX), fView.contentsToViewY(localY), true); - if (fDrawWithFocus) { - Point r = fContext.textExtent(string); - fContext.drawFocus(localX - 1, localY - 1, r.x + 2, r.y + 2); - } - } - - @Override - public void fillOval(int x, int y, int width, int height) { - int localX = x; - int localY = y; - int localWidth = width; - int localHeight = height; - - localX = Math.round(localX * fView.getZoomValue()); - localY = Math.round(localY * fView.getZoomValue()); - localWidth = Math.round(localWidth * fView.getZoomValue()); - localHeight = Math.round(localHeight * fView.getZoomValue()); - fContext.fillOval(fView.contentsToViewX(localX), fView.contentsToViewY(localY), localWidth, localHeight); - } - - @Override - public IColor getBackground() { - if ((fBackground != null) && (fBackground.getColor() instanceof Color) && (!((Color) (fBackground.getColor())).isDisposed())) { - return fBackground; - } - return ColorImpl.getSystemColor(SWT.COLOR_WHITE); - } - - @Override - public IColor getForeground() { - if ((fForeground != null) && (fForeground.getColor() instanceof Color) && (!((Color) (fForeground.getColor())).isDisposed())) { - return fForeground; - } - return ColorImpl.getSystemColor(SWT.COLOR_WHITE); - } - - @Override - public void setBackground(IColor color) { - if (color == null) { - return; - } - if (color.getColor() instanceof Color) { - fContext.setBackground((Color) color.getColor()); - fBackground = color; - } - } - - @Override - public void setForeground(IColor color) { - if (color == null) { - return; - } - if (color.getColor() instanceof Color) { - Color c = (Color) color.getColor(); - if (!c.isDisposed()) { - fContext.setForeground(c); - fForeground = color; - } - } - } - - @Override - public void setGradientColor(IColor color) { - if (color == null) { - return; - } - if (color.getColor() instanceof Color) { - fGradientColor = color; - } - } - - @Override - public void setLineWidth(int width) { - if (fView.isPrinting()) { - fContext.setLineWidth(width * 2); - } - else { - fContext.setLineWidth(width); - } - } - - @Override - public int getLineWidth() { - return fContext.getLineWidth(); - } - - /** - * Method to draw a text in rectangle. (Linux GTK Workaround) - * - * @param string The text to draw. - * @param x The x position. - * @param y The y position. - * @param isTransparent true for transparent else false - */ - protected void localDrawText(String string, int x, int y, boolean isTransparent) { - Point r = fContext.textExtent(string); - if (!isTransparent) { - fContext.fillRectangle(x, y, r.x, r.y); - } - fContext.drawText(string, x, y, isTransparent); - if ((fDrawWithFocus) && (string.length() > 1)) { - fContext.drawFocus(x - 1, y - 1, r.x + 2, r.y + 2); - } - } - - @Override - public void drawTextTruncatedCentred(String name, int xValue, int yValue, int width, int height, boolean trans) { - int localX = xValue; - int localY = yValue; - int localWidth = width; - int localHeight = height; - - Point tx = fContext.textExtent(name); - localX = Math.round(localX * fView.getZoomValue()); - int y = 0; - // Workaround to avoid round problems for some special cases (not very nice) - if (localY != getContentsY()) { - localY = Math.round(localY * fView.getZoomValue()); - y = fView.contentsToViewY(localY); - } - localWidth = Math.round(localWidth * fView.getZoomValue()); - localHeight = Math.round(localHeight * fView.getZoomValue()); - int x = fView.contentsToViewX(localX); - if (tx.y > localHeight) { - return; - } - - // Adjust height and y - if (y < -fVisibleScreenBounds) { - localHeight = localHeight + y + fVisibleScreenBounds; - y = -fVisibleScreenBounds; - } - if ((localHeight < -fVisibleScreenBounds) && (y + localHeight < -fVisibleScreenBounds)) { - localHeight = -fVisibleScreenBounds; - } else if (localHeight + y > fView.getVisibleHeight() + fVisibleScreenBounds) { - localHeight = fView.getVisibleHeight() + fVisibleScreenBounds - y; - } - - if (tx.x <= localWidth) { - localDrawText(name, x + 1 + (localWidth - tx.x) / 2, y + 1 + (localHeight - tx.y) / 2, trans); - } else { - String nameToDisplay = name; - for (int i = name.length() - 1; i >= 0 && fContext.textExtent(nameToDisplay).x >= localWidth; i--) { - nameToDisplay = name.substring(0, i); - } - int dotCount = 0; - for (int i = 1; i <= 3 && nameToDisplay.length() - i > 0; i++) { - dotCount++; - } - nameToDisplay = nameToDisplay.substring(0, nameToDisplay.length() - dotCount); - StringBuffer buf = new StringBuffer(nameToDisplay); - for (int i = 0; i < dotCount; i++) { - buf.append("."); //$NON-NLS-1$ - } - nameToDisplay = buf.toString(); - localDrawText(nameToDisplay, x + 1 + (localWidth - fContext.textExtent(nameToDisplay).x) / 2, y + 1 + (localHeight - fContext.textExtent(nameToDisplay).y) / 2, trans); - } - } - - @Override - public void drawTextTruncated(String name, int xValue, int yValue, int width, int height, boolean trans) { - int localX = xValue; - int localY = yValue; - int localWidth = width; - int localHeight = height; - - localX = Math.round(localX * fView.getZoomValue()); - localY = Math.round(localY * fView.getZoomValue()); - localWidth = Math.round(localWidth * fView.getZoomValue()); - localHeight = Math.round(localHeight * fView.getZoomValue()); - int x = fView.contentsToViewX(localX); - int y = fView.contentsToViewY(localY); - if (fContext.textExtent(name).x <= localWidth) { - localDrawText(name, x + 1, y + 1 + localHeight, trans); - } else { - String nameToDisplay = name; - for (int i = name.length() - 1; i >= 0 && fContext.textExtent(nameToDisplay).x >= localWidth; i--) { - nameToDisplay = name.substring(0, i); - } - int dotCount = 0; - for (int i = 1; i <= 3 && nameToDisplay.length() - i > 0; i++) { - dotCount++; - } - nameToDisplay = nameToDisplay.substring(0, nameToDisplay.length() - dotCount); - - StringBuffer buf = new StringBuffer(nameToDisplay); - - for (int i = 0; i < dotCount; i++) { - buf.append("."); //$NON-NLS-1$ - } - nameToDisplay = buf.toString(); - localDrawText(nameToDisplay, x + 1, y + 1 + localHeight, trans); - } - } - - @Override - public void drawImage(IImage image, int xValue, int yValue, int maxWith, int maxHeight) { - int localX = xValue; - int localY = yValue; - - Image img = null; - if (image != null && image.getImage() instanceof Image) { - img = (Image) image.getImage(); - } else { - localX = Math.round(localX * fView.getZoomValue()); - localY = Math.round(localY * fView.getZoomValue()); - int x = fView.contentsToViewX(localX); - int y = fView.contentsToViewY(localY); - float tempZoom = fView.getZoomValue(); - int width = Math.round(maxWith * tempZoom); - int height = Math.round(maxHeight * tempZoom); - fContext.setBackground(fView.getDisplay().getSystemColor(SWT.COLOR_RED)); - fContext.fillRectangle(x, y, width, height); - return; - } - localX = Math.round(localX * fView.getZoomValue()); - localY = Math.round(localY * fView.getZoomValue()); - int x = fView.contentsToViewX(localX); - int y = fView.contentsToViewY(localY); - Rectangle b = ((Image) image.getImage()).getBounds(); - int width = b.width; - int height = b.height; - if (width > maxWith) { - width = maxWith; - } - if (height > maxHeight) { - height = maxHeight; - } - float tempZoom = fView.getZoomValue(); - width = Math.round(width * tempZoom); - height = Math.round(height * tempZoom); - - if (fView.isPrinting() && width > 0 && height > 0) { - Image dbuffer = new Image(fView.getDisplay(), width, height); - GC tempgc = new GC(dbuffer); - tempgc.drawImage(img, 0, 0, b.width, b.height, 0, 0, width, height); - Image dbuffer2 = new Image(fView.getDisplay(), dbuffer.getImageData()); - fContext.drawImage(dbuffer2, x, y); - tempgc.dispose(); - dbuffer.dispose(); - dbuffer2.dispose(); - } else { - fContext.drawImage(img, 0, 0, b.width, b.height, x, y, width, height); - } - } - - @Override - public void drawArc(int x, int y, int width, int height, int startAngle, int endAngle) { - int localX = x; - int localY = y; - int localWidth = width; - int localHeight = height; - - localX = Math.round(localX * fView.getZoomValue()); - localY = Math.round(localY * fView.getZoomValue()); - localWidth = Math.round(localWidth * fView.getZoomValue()); - localHeight = Math.round(localHeight * fView.getZoomValue()); - if (localWidth == 0 || localHeight == 0 || endAngle == 0) { - return; - } - fContext.drawArc(fView.contentsToViewX(localX), fView.contentsToViewY(localY), localWidth, localHeight, startAngle, endAngle); - } - - @Override - public void setFont(IFont font) { - if (font.getFont() != null && ((Font) font.getFont()).getFontData().length > 0) { - FontData fontData = ((Font) font.getFont()).getFontData()[0]; - if (SDViewPref.getInstance().fontLinked() || fView.isPrinting()) { - int h = Math.round(fontData.getHeight() * fView.getZoomValue()); - if (h > 0) { - fontData.setHeight(h); - } - } - if (fTempFont != null) { - fTempFont.dispose(); - } - fTempFont = new Font(Display.getCurrent(), fontData); - fContext.setFont(fTempFont); - } - } - - @Override - public int getFontHeight(IFont font) { - if (font.getFont() != null && (font.getFont() instanceof Font) && ((Font) font.getFont()).getFontData().length > 0) { - Font toRestore = fContext.getFont(); - fContext.setFont((Font) font.getFont()); - int height = fContext.textExtent("lp").y;//$NON-NLS-1$ - fContext.setFont(toRestore); - return height; - } - return 0; - } - - /** - * Returns the current font height. - * - * @return the current font height. - */ - protected int getCurrentFontHeight() { - return fContext.textExtent("lp").y; //$NON-NLS-1$ - } - - @Override - public int getFontWidth(IFont font) { - if ((font.getFont() != null) && (font.getFont() instanceof Font)) { - Font toRestore = fContext.getFont(); - fContext.setFont((Font) font.getFont()); - int width = fContext.getFontMetrics().getAverageCharWidth(); - fContext.setFont(toRestore); - return width; - } - return 0; - } - - /** - * Disposes all created resources. - */ - public void dispose() { - if (fTempFont != null) { - fTempFont.dispose(); - } - fTempFont = null; - if (fContext != null) { - fContext.dispose(); - } - fContext = null; - } - - @Override - public float getZoom() { - if (fView != null) { - return fView.getZoomValue(); - } - return 1; - } - - @Override - public int getLineDotStyle() { - return SWT.LINE_DOT; - } - - @Override - public int getLineDashStyle() { - return SWT.LINE_DASH; - } - - @Override - public int getLineSolidStyle() { - return SWT.LINE_SOLID; - } - - @Override - public IColor createColor(int r, int g, int b) { - return new ColorImpl(Display.getDefault(), r, g, b); - } - - @Override - public void setDrawTextWithFocusStyle(boolean focus) { - fDrawWithFocus = focus; - } - - /** - * Returns the screen bounds. - * - * @return the screen bounds. - */ - protected static int getVscreenBounds() { - return fVisibleScreenBounds; - } - - /** - * Sets the visible screen bounds. - * - * @param vBounds the screen bounds. - */ - protected static void setVscreenBounds(int vBounds) { - fVisibleScreenBounds = vBounds; - } - - /** - * Returns the graphical context. - * - * @return the graphical context - * @since 2.0 - */ - protected GC getGc() { - return fContext; - } - - /** - * Returns the SD widget. - * - * @return the SD widget - * @since 2.0 - */ - protected SDWidget getSDWidget() { - return fView; - } - - /** - * Returns the gradient color. - * - * @return the gradient color - * @since 2.0 - */ - protected IColor setGradientColor() { - return fGradientColor; - } - - // ------------------------------------------------------------------------ - // Helper methods - // ------------------------------------------------------------------------ - - /** - * Validates the polygon height - * - * @param localPoint array of points - * @return height - */ - private int validatePolygonHeight(int[] localPoint) { - int i = 1; - int max = 0; - int min = Integer.MAX_VALUE; - while (i < localPoint.length) { - max = Math.abs(localPoint[i]) > Math.abs(max) ? localPoint[i] : max; - min = Math.abs(localPoint[i]) < Math.abs(min) ? localPoint[i] : min; - i+=2; - } - int height = max - min; - if (min < -fVisibleScreenBounds) { - height = height + min + fVisibleScreenBounds; - min = -fVisibleScreenBounds; - } - if ((height < -fVisibleScreenBounds) && (min + height < -fVisibleScreenBounds)) { - height = -fVisibleScreenBounds; - } else if (height + min > fView.getVisibleHeight() + fVisibleScreenBounds) { - height = fView.getVisibleHeight() + fVisibleScreenBounds - min; - } - return height; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/SDView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/SDView.java deleted file mode 100644 index cdd804c943..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/SDView.java +++ /dev/null @@ -1,1181 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2014 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd; - -import java.util.Iterator; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.ActionContributionItem; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IContributionItem; -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.BaseMessage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Frame; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SyncMessage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SyncMessageReturn; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ConfigureMinMax; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.FirstPage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.KeyBindingsManager; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.LastPage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.MoveToMessage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.NextPage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.OpenSDFiltersDialog; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.OpenSDFindDialog; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.OpenSDPagesDialog; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.PrevPage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.Print; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ShowNodeEnd; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ShowNodeStart; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.Zoom; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.Zoom.ZoomType; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.IExtendedFilterProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.IExtendedFindProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDAdvancedPagingProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDCollapseProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDExtendedActionBarProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDFilterProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDFindProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDPagingProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDPropertiesProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.load.IUml2SDLoader; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.load.LoadersManager; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.ui.IActionBars; -import org.eclipse.ui.IViewReference; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.actions.ActionFactory; -import org.eclipse.ui.part.ViewPart; -import org.eclipse.ui.views.properties.IPropertySheetPage; - -/** - *

- * This class is a generic sequence diagram view implementation. - *

- - * @version 1.0 - * @author sveyrier - */ -public class SDView extends ViewPart { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * Name of menu separator for view modes - * @since 2.0 - */ - public static final String UML2SD_VIEW_MODES_SEPARATOR = "UML2SD_VIEW_MODES"; //$NON-NLS-1$ - /** - * Name of menu separator for working set - * @since 2.0 - */ - public static final String UML2SD_WORKING_SET_SEPARATOR = "UML2SD_WORKING_SET"; //$NON-NLS-1$ - /** - * Name of menu separator for sorting - * @since 2.0 - */ - public static final String UML2SD_SORTING_SEPARATOR = "UML2SD_SORTING"; //$NON-NLS-1$ - /** - * Name of menu separator for filtering - * @since 2.0 - */ - public static final String UML2SD_FILTERING_SEPARATOR = "UML2SD_FILTERING"; //$NON-NLS-1$ - /** - * Name of menu separator for view layout - * @since 2.0 - */ - public static final String UML2SD_VIEW_LAYOUT_SEPARATOR = "UML2SD_VIEW_LAYOUT"; //$NON-NLS-1$ - /** - * Name of menu separator for link editor - * @since 2.0 - */ - public static final String UML2SD_LINK_EDITOR_SEPARATOR = "UML2SD_LINK_EDITOR"; //$NON-NLS-1$ - /** - * Name of menu separator for other commands - * @since 2.0 - */ - public static final String UML2SD_OTHER_COMMANDS_SEPARATOR = "UML2SD_OTHER_COMMANDS"; //$NON-NLS-1$ - /** - * Name of menu separator for other plug-in commands - * @since 2.0 - */ - public static final String UML2SD_OTHER_PLUGINS_COMMANDS_SEPARATOR = "UML2SD_OTHER_PLUGINS_COMMANDS"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The sequence diagram widget. - */ - private SDWidget fSdWidget = null; - /** - * The time compression bar. - */ - private TimeCompressionBar fTimeCompressionBar = null; - /** - * The sequence diagram find provider implementation. - */ - private ISDFindProvider fSdFindProvider = null; - /** - * The sequence diagram paging provider implementation. - */ - private ISDPagingProvider fSdPagingProvider = null; - /** - * The sequence diagram filter provider implementation. - */ - private ISDFilterProvider fSdFilterProvider = null; - /** - * The extended sequence diagram filter provider implementation. - */ - private IExtendedFilterProvider fSdExFilterProvider = null; - /** - * The extended sequence diagram find provider implementation. - */ - private IExtendedFindProvider fSdExFindProvider = null; - /** - * The extended sequence diagram action bar provider implementation. - */ - private ISDExtendedActionBarProvider fSdExtendedActionBarProvider = null; - /** - * The sequence diagram property provider implementation. - */ - private ISDPropertiesProvider fSdPropertiesProvider = null; - /** - * Button for executing the next page action. - */ - private NextPage fNextPageButton = null; - /** - * Button for executing the previous page action. - */ - private PrevPage fPrevPageButton = null; - /** - * Button for executing the first page page action. - */ - private FirstPage fFirstPageButton = null; - /** - * Button for executing the last page action. - */ - private LastPage fLastPageButton = null; - /** - * The menu manager reference. - */ - private MenuManager fMenuMgr = null; - /** - * Flag to indicate whether view needs initialization or not. - */ - private boolean fNeedInit = true; - /** - * WaitCursor is the cursor to be displayed when long tasks are running - */ - private Cursor fWaitCursor; - - private Zoom fResetZoomAction; - private Zoom fNoZoomAction; - private Zoom fZoomInAction; - private Zoom fZoomOutAction; - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public void createPartControl(Composite c) { - Composite parent = new Composite(c, SWT.NONE); - GridLayout parentLayout = new GridLayout(); - parentLayout.numColumns = 2; - parentLayout.marginWidth = 0; - parentLayout.marginHeight = 0; - parent.setLayout(parentLayout); - - GridData timeLayoutdata = new GridData(GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL); - timeLayoutdata.widthHint = 10; - GridData seqDiagLayoutData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL); - fTimeCompressionBar = new TimeCompressionBar(parent, SWT.NONE); - fTimeCompressionBar.setLayoutData(timeLayoutdata); - fSdWidget = new SDWidget(parent, SWT.NONE); - fSdWidget.setLayoutData(seqDiagLayoutData); - fSdWidget.setSite(this); - fSdWidget.setTimeBar(fTimeCompressionBar); - - // Add this view to the key bindings manager - KeyBindingsManager.getInstance().add(this.getSite().getId()); - - createCoolbarContent(); - - hookContextMenu(); - - fTimeCompressionBar.setVisible(false); - parent.layout(true); - - Print print = new Print(this); - getViewSite().getActionBars().setGlobalActionHandler(ActionFactory.PRINT.getId(), print); - - fNeedInit = restoreLoader(); - } - - /** - * Load a blank page that is supposed to explain that a kind of interaction must be chosen. - */ - protected void loadBlank() { - IUml2SDLoader loader = new BlankUml2SdLoader(); - loader.setViewer(this); - setContentDescription(loader.getTitleString()); - } - - @Override - public void setFocus() { - if (fSdWidget != null) { - // update actions for key bindings - KeyBindingsManager.getInstance().setSdView(this); - fSdWidget.setFocus(); - } - if (isViewReady() && fNeedInit) { - fNeedInit = restoreLoader(); - } - } - - @Override - public void dispose() { - KeyBindingsManager.getInstance().remove(this.getSite().getId()); - disposeZoomActions(); - super.dispose(); - } - - private void disposeZoomActions() { - if (fResetZoomAction != null) { - fResetZoomAction.dispose(); - } - if (fNoZoomAction != null) { - fNoZoomAction.dispose(); - } - if (fZoomInAction != null) { - fZoomInAction.dispose(); - } - if (fZoomOutAction != null) { - fZoomOutAction.dispose(); - } - } - - /** - * Returns the SD widget. - * - * @return The SD widget. - */ - public SDWidget getSDWidget() { - return fSdWidget; - } - - /** - * Set the find provider for the opened sequence diagram viewer
- * If the provider is not set, the find menu item will not be available in the viewer
- * A find provider is called back when the user perform a find action
- * The find provider is responsible to move the sequence diagram to the GraphNode which match the - * find criteria as well as to highlight the GraphNode - * - * @param provider the search provider - */ - public void setSDFindProvider(ISDFindProvider provider) { - fSdFindProvider = provider; - fSdExFindProvider = null; - createCoolbarContent(); - if (provider != null) { - KeyBindingsManager.getInstance().setFindEnabled(true); - } - else { - KeyBindingsManager.getInstance().setFindEnabled(false); - } - } - - /** - * Set the find provider for the opened sequence diagram viewer
- * If the provider is not set, the find menu item will not be available in - * the viewer
- * A find provider is called back when the user perform a find action
- * If the extended find provider is set, it replaces the regular find - * provider (sdFindProvider).
- * - * @param provider - * The provider to set - */ - public void setExtendedFindProvider(IExtendedFindProvider provider) { - fSdExFindProvider = provider; - fSdFindProvider = null; - createCoolbarContent(); - if (provider != null) { - KeyBindingsManager.getInstance().setFindEnabled(true); - } - else { - KeyBindingsManager.getInstance().setFindEnabled(false); - } - } - - /** - * Returns the extended find provider - * - * @return extended find provider. - */ - public IExtendedFindProvider getExtendedFindProvider() { - return fSdExFindProvider; - } - - /** - * Resets all providers. - */ - public void resetProviders() { - KeyBindingsManager.getInstance().setFindEnabled(false); - fSdFindProvider = null; - fSdExFindProvider = null; - fSdFilterProvider = null; - fSdExFilterProvider = null; - fSdPagingProvider = null; - fSdExtendedActionBarProvider = null; - fSdPropertiesProvider = null; - if ((fSdWidget != null) && (!fSdWidget.isDisposed())) { - fSdWidget.setCollapseProvider(null); - } - } - - /** - * Set the filter provider for the opened sequence diagram viewer
- * If the provider is not set, the filter menu item will not be available in the viewer
- * A filter provider is called back when the user perform a filter action
- * - * @param provider the filter provider - */ - public void setSDFilterProvider(ISDFilterProvider provider) { - fSdFilterProvider = provider; - // Both systems can be used now, commenting out next statement - createCoolbarContent(); - } - - /** - * Sets the extended filter provider for the opened sequence diagram viewer. - * - * @param provider - * The provider to set - */ - public void setExtendedFilterProvider(IExtendedFilterProvider provider) { - fSdExFilterProvider = provider; - // Both systems can be used now, commenting out next statement - createCoolbarContent(); - } - - /** - * Returns the extended find provider. - * - * @return The extended find provider. - */ - public IExtendedFilterProvider getExtendedFilterProvider() { - return fSdExFilterProvider; - } - - /** - * Register the given provider to support Drag and Drop collapsing. This provider is - * responsible of updating the Frame. - * - * @param provider - the provider to register - */ - public void setCollapsingProvider(ISDCollapseProvider provider) { - if ((fSdWidget != null) && (!fSdWidget.isDisposed())) { - fSdWidget.setCollapseProvider(provider); - } - } - - /** - * Set the page provider for the opened sequence diagram viewer
- * If the sequence diagram provided (see setFrame) need to be split in many parts, a paging provider must be - * provided in order to handle page change requested by the user
- * Set a page provider will create the next and previous page buttons in the viewer coolBar - * - * @param provider the paging provider - */ - public void setSDPagingProvider(ISDPagingProvider provider) { - fSdPagingProvider = provider; - createCoolbarContent(); - } - - /** - * Returns the current page provider for the view - * - * @return the paging provider - */ - public ISDPagingProvider getSDPagingProvider() { - return fSdPagingProvider; - } - - /** - * Returns the current find provider for the view - * - * @return the find provider - */ - public ISDFindProvider getSDFindProvider() { - return fSdFindProvider; - } - - /** - * Returns the current filter provider for the view - * - * @return the filter provider - */ - public ISDFilterProvider getSDFilterProvider() { - return fSdFilterProvider; - } - - /** - * Set the extended action bar provider for the opened sequence diagram viewer
- * This allow to add programmatically actions in the coolbar and/or in the drop-down menu - * - * @param provider the search provider - */ - public void setSDExtendedActionBarProvider(ISDExtendedActionBarProvider provider) { - fSdExtendedActionBarProvider = provider; - createCoolbarContent(); - } - - /** - * Returns the current extended action bar provider for the view - * - * @return the extended action bar provider - */ - public ISDExtendedActionBarProvider getSDExtendedActionBarProvider() { - return fSdExtendedActionBarProvider; - } - - /** - * Set the properties view provider for the opened sequence diagram viewer - * - * @param provider the properties provider - */ - public void setSDPropertiesProvider(ISDPropertiesProvider provider) { - fSdPropertiesProvider = provider; - } - - /** - * Returns the current extended action bar provider for the view. - * - * @return the extended action bar provider - */ - public ISDPropertiesProvider getSDPropertiesProvider() { - return fSdPropertiesProvider; - } - - /** - * Sets the sdWidget. - * - * @param sdWidget - * A sdWidget to set - * @since 2.0 - */ - protected void setSDWidget(SDWidget sdWidget) { - fSdWidget = sdWidget; - } - - /** - * Sets the time compression bar. - * - * @param timeCompressionbar - * A sdWidget to set - * @since 2.0 - */ - protected void setTimeBar(TimeCompressionBar timeCompressionbar) { - fTimeCompressionBar = timeCompressionbar; - } - - /** - * Sets the initialization flag. - * - * @param needInit - * flag value to set - * @since 2.0 - */ - protected void setNeedInit(boolean needInit) { - fNeedInit = needInit; - } - - /** - * Creates the basic sequence diagram menu - */ - protected void hookContextMenu() { - fMenuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$ - fMenuMgr.setRemoveAllWhenShown(true); - fMenuMgr.addMenuListener(new IMenuListener() { - @Override - public void menuAboutToShow(IMenuManager manager) { - fillContextMenu(manager); - } - }); - Menu menu = fMenuMgr.createContextMenu(fSdWidget.getViewControl()); - fSdWidget.getViewControl().setMenu(menu); - getSite().registerContextMenu(fMenuMgr, fSdWidget.getSelectionProvider()); - } - - /** - * Returns the context menu manager - * - * @return the menu manager - */ - public MenuManager getMenuManager() { - return fMenuMgr; - } - - /** - * Fills the basic sequence diagram menu and define the dynamic menu item insertion point - * - * @param manager the menu manager - */ - protected void fillContextMenu(IMenuManager manager) { - manager.add(new Separator("Additions")); //$NON-NLS-1$ - if (getSDWidget() != null && getSDWidget().getCurrentGraphNode() != null) { - ISelectionProvider selProvider = fSdWidget.getSelectionProvider(); - ISelection sel = selProvider.getSelection(); - int nbMessage = 0; - Iterator it = ((StructuredSelection) sel).iterator(); - while (it.hasNext()) { - Object node = it.next(); - if (node instanceof BaseMessage) { - nbMessage++; - } - } - if (nbMessage != 1) { - return; - } - GraphNode node = getSDWidget().getCurrentGraphNode(); - if ((node instanceof SyncMessageReturn) && (((SyncMessageReturn) node).getMessage() != null)) { - Action goToMessage = new MoveToMessage(this); - goToMessage.setText(Messages.SequenceDiagram_GoToMessage); - manager.add(goToMessage); - } - if ((node instanceof SyncMessage) && (((SyncMessage) node).getMessageReturn() != null)) { - Action goToMessage = new MoveToMessage(this); - goToMessage.setText(Messages.SequenceDiagram_GoToMessageReturn); - manager.add(goToMessage); - } - } - manager.add(new Separator("MultiSelectAdditions")); //$NON-NLS-1$ - } - - /** - * Enables/Disables an action with given name. - * - * @param actionName The action name - * @param state true or false - */ - public void setEnableAction(String actionName, boolean state) { - IActionBars bar = getViewSite().getActionBars(); - if (bar != null) { - IContributionItem item = bar.getMenuManager().find(actionName); - if ((item != null) && (item instanceof ActionContributionItem)) { - IAction action = ((ActionContributionItem) item).getAction(); - if (action != null) { - action.setEnabled(state); - } - item.setVisible(state); - bar.updateActionBars(); - } - } - } - - /** - * Creates the coolBar icon depending on the actions supported by the Sequence Diagram provider
- * - Navigation buttons are displayed if ISDPovider.HasPaging return true
- * - Navigation buttons are enabled depending on the value return by ISDPovider.HasNext and HasPrev
- * - * @see ISDGraphNodeSupporter Action support definition - * @see SDView#setSDFilterProvider(ISDFilterProvider) - * @see SDView#setSDFindProvider(ISDFindProvider) - * @see SDView#setSDPagingProvider(ISDPagingProvider) - */ - protected void createCoolbarContent() { - IActionBars bar = getViewSite().getActionBars(); - - bar.getMenuManager().removeAll(); - bar.getToolBarManager().removeAll(); - disposeZoomActions(); - - createMenuGroup(); - - fResetZoomAction = new Zoom(this, ZoomType.ZOOM_RESET); - bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fResetZoomAction); - bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fResetZoomAction); - - fNoZoomAction = new Zoom(this, ZoomType.ZOOM_NONE); - fNoZoomAction.setChecked(true); - bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fNoZoomAction); - bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fNoZoomAction); - - fZoomInAction = new Zoom(this, ZoomType.ZOOM_IN); - bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fZoomInAction); - bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fZoomInAction); - - fZoomOutAction = new Zoom(this, ZoomType.ZOOM_OUT); - bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fZoomOutAction); - bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fZoomOutAction); - - MenuManager navigation = new MenuManager(Messages.SequenceDiagram_Navigation); - - ShowNodeStart showNodeStart = new ShowNodeStart(this); - showNodeStart.setText(Messages.SequenceDiagram_ShowNodeStart); - - showNodeStart.setId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ShowNodeStart");//$NON-NLS-1$ - showNodeStart.setActionDefinitionId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ShowNodeStart");//$NON-NLS-1$ - navigation.add(showNodeStart); - - ShowNodeEnd showNodeEnd = new ShowNodeEnd(this); - showNodeEnd.setText(Messages.SequenceDiagram_ShowNodeEnd); - - showNodeEnd.setId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ShowNodeEnd");//$NON-NLS-1$ - showNodeEnd.setActionDefinitionId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ShowNodeEnd");//$NON-NLS-1$ - navigation.add(showNodeEnd); - - bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, navigation); - - ConfigureMinMax minMax = new ConfigureMinMax(this); - minMax.setText(Messages.SequenceDiagram_ConfigureMinMax); - minMax.setId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ConfigureMinMax");//$NON-NLS-1$ - bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, minMax); - - if ((fSdWidget.getFrame() != null) && (fSdWidget.getFrame().hasTimeInfo())) { - minMax.setEnabled(true); - } else { - minMax.setEnabled(false); - } - - // Do we need to display a paging item - if (fSdPagingProvider != null) { - fNextPageButton = new NextPage(this); - bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fNextPageButton); - fNextPageButton.setEnabled(fSdPagingProvider.hasNextPage()); - bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fNextPageButton); - - fPrevPageButton = new PrevPage(this); - bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fPrevPageButton); - fPrevPageButton.setEnabled(fSdPagingProvider.hasPrevPage()); - bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fPrevPageButton); - - fFirstPageButton = new FirstPage(this); - bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fFirstPageButton); - fFirstPageButton.setEnabled(fSdPagingProvider.hasPrevPage()); - bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fFirstPageButton); - - fLastPageButton = new LastPage(this); - bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fLastPageButton); - fLastPageButton.setEnabled(fSdPagingProvider.hasNextPage()); - bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fLastPageButton); - } - - if (fSdExFilterProvider != null) { - Action action = fSdExFilterProvider.getFilterAction(); - if (action != null) { - if (action.getId() == null) - { - action.setId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.extendedFilter"); //$NON-NLS-1$ - } - if (action.getImageDescriptor() == null) { - action.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FILTERS)); - } - if (action.getText() == null || action.getText().length() == 0) { - action.setText(Messages.SequenceDiagram_EditFilters); - } - bar.getMenuManager().prependToGroup(UML2SD_FILTERING_SEPARATOR, action); - bar.getToolBarManager().prependToGroup(UML2SD_FILTERING_SEPARATOR, action); - } - } - // Both systems can be used now: commenting out else keyword - if (fSdFilterProvider != null) { - bar.getMenuManager().appendToGroup(UML2SD_FILTERING_SEPARATOR, new OpenSDFiltersDialog(this, fSdFilterProvider)); - } - if (fSdPagingProvider instanceof ISDAdvancedPagingProvider) { - IContributionItem sdPaging = bar.getMenuManager().find(OpenSDPagesDialog.ID); - if (sdPaging != null) { - bar.getMenuManager().remove(sdPaging); - sdPaging = null; - } - bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, new OpenSDPagesDialog(this, (ISDAdvancedPagingProvider) fSdPagingProvider)); - updatePagesMenuItem(bar); - } - - if (fSdExFindProvider != null) { - Action action = fSdExFindProvider.getFindAction(); - if (action != null) { - if (action.getId() == null) { - action.setId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.extendedFind"); //$NON-NLS-1$ - } - if (action.getImageDescriptor() == null) { - action.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SEARCH_SEQ)); - } - if (action.getText() == null) { - action.setText(Messages.SequenceDiagram_Find + "..."); //$NON-NLS-1$ - } - bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, action); - bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, action); - } - } else if (fSdFindProvider != null) { - bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, new OpenSDFindDialog(this)); - bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, new OpenSDFindDialog(this)); - } - - if (fSdExtendedActionBarProvider != null) { - fSdExtendedActionBarProvider.supplementCoolbarContent(bar); - } - - bar.updateActionBars(); - } - - /** - * Updates the view coolbar buttons state according to the value return by: - - * ISDExtendedActionBarProvider.hasNextPage()
- * - ISDExtendedActionBarProvider.hasPrevPage()
- * - */ - public void updateCoolBar() { - if (fSdPagingProvider != null) { - IActionBars bar = getViewSite().getActionBars(); - if (bar == null) { - return; - } - IToolBarManager barManager = bar.getToolBarManager(); - if (barManager == null) { - return; - } - IContributionItem nextPage = barManager.find(NextPage.ID); - if (nextPage instanceof ActionContributionItem) { - IAction nextPageAction = ((ActionContributionItem) nextPage).getAction(); - if (nextPageAction instanceof NextPage) { - ((NextPage) nextPageAction).setEnabled(fSdPagingProvider.hasNextPage()); - } - } - - IContributionItem prevPage = barManager.find(PrevPage.ID); - if (prevPage instanceof ActionContributionItem) { - IAction prevPageAction = ((ActionContributionItem) prevPage).getAction(); - if (prevPageAction instanceof PrevPage) { - ((PrevPage) prevPageAction).setEnabled(fSdPagingProvider.hasPrevPage()); - } - } - - IContributionItem firstPage = barManager.find(FirstPage.ID); - if (firstPage instanceof ActionContributionItem) { - IAction firstPageAction = ((ActionContributionItem) firstPage).getAction(); - if (firstPageAction instanceof FirstPage) { - ((FirstPage) firstPageAction).setEnabled(fSdPagingProvider.hasPrevPage()); - } - } - - IContributionItem lastPage = barManager.find(LastPage.ID); - if (lastPage instanceof ActionContributionItem) { - IAction lastPageAction = ((ActionContributionItem) lastPage).getAction(); - if (lastPageAction instanceof LastPage) { - ((LastPage) lastPageAction).setEnabled(fSdPagingProvider.hasNextPage()); - } - } - - updatePagesMenuItem(bar); - } - } - - /** - * Enables or disables the Pages... menu item, depending on the number of pages - * - * @param bar the bar containing the action - */ - protected void updatePagesMenuItem(IActionBars bar) { - if (fSdPagingProvider instanceof ISDAdvancedPagingProvider) { - IMenuManager menuManager = bar.getMenuManager(); - ActionContributionItem contributionItem = (ActionContributionItem) menuManager.find(OpenSDPagesDialog.ID); - IAction openSDPagesDialog = null; - if (contributionItem != null) { - openSDPagesDialog = contributionItem.getAction(); - } - - if (openSDPagesDialog instanceof OpenSDPagesDialog) { - openSDPagesDialog.setEnabled(((ISDAdvancedPagingProvider) fSdPagingProvider).pagesCount() > 1); - } - } - } - - /** - * The frame to render (the sequence diagram) - * - * @param frame the frame to display - */ - public void setFrame(Frame frame) { - setFrame(frame, true); - } - - /** - * The frame to render (the sequence diagram) - * - * @param frame the frame to display - * @param resetPosition boolean Flag whether to reset the position or not. - */ - protected void setFrame(Frame frame, boolean resetPosition) { - if (getSDWidget() == null) { - return; - } - - if (frame == null) { - loadBlank(); - return; - } - - IUml2SDLoader loader = LoadersManager.getInstance().getCurrentLoader(getViewSite().getId(), this); - if (loader == null) { - return; - } - - if (loader.getTitleString() != null) { - setContentDescription(loader.getTitleString()); - } - - getSDWidget().setFrame(frame, resetPosition); - - if (fTimeCompressionBar != null) { - fTimeCompressionBar.setFrame(frame); - } - updateCoolBar(); - if (fTimeCompressionBar != null) { - if (!frame.hasTimeInfo()) { - Composite parent = fTimeCompressionBar.getParent(); - fTimeCompressionBar.setVisible(false); - parent.layout(true); - } else { - Composite parent = fTimeCompressionBar.getParent(); - fTimeCompressionBar.setVisible(true); - parent.layout(true); - } - } - IContributionItem shortKeysMenu = getViewSite().getActionBars().getMenuManager().find("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers");//$NON-NLS-1$ - MenuManager shortKeys = (MenuManager) shortKeysMenu; - if (shortKeys != null) { - IContributionItem[] items = shortKeys.getItems(); - for (int i = 0; i < items.length; i++) { - if (items[i] instanceof ActionContributionItem) { - IAction action = ((ActionContributionItem) items[i]).getAction(); - if (action != null) { - action.setEnabled(true); - } - } - } - } - createCoolbarContent(); - } - - /** - * Activate or deactivate the short key command given in parameter (see plugin.xml) - * - * @param id the command id defined in the plugin.xml - * @param value the state value - */ - public void setEnableCommand(String id, boolean value) { - IContributionItem shortKeysMenu = getViewSite().getActionBars().getMenuManager().find("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers");//$NON-NLS-1$ - MenuManager shortKeys = (MenuManager) shortKeysMenu; - if (shortKeys == null) { - return; - } - IContributionItem item = shortKeys.find(id); - if ((item != null) && (item instanceof ActionContributionItem)) { - IAction action = ((ActionContributionItem) item).getAction(); - if (action != null) { - action.setEnabled(value); - } - } - } - - /** - * Set the frame from an other thread than the one executing the main loop - * - * @param frame The frame to set (and display) - */ - public void setFrameSync(final Frame frame) { - if (getSDWidget() == null || getSDWidget().isDisposed()) { - return; - } - getSDWidget().getDisplay().syncExec(new Runnable() { - @Override - public void run() { - if (getSDWidget() == null || getSDWidget().isDisposed() || - ((fTimeCompressionBar != null) && fTimeCompressionBar.isDisposed())) { - return; - } - setFrame(frame); - } - }); - - } - - /** - * Ensure an object is visible from an other thread than the one executing the main loop - * - * @param sm The node to make visible in view - */ - public void ensureVisibleSync(final GraphNode sm) { - getSDWidget().getDisplay().syncExec(new Runnable() { - @Override - public void run() { - if (getSDWidget() == null || getSDWidget().isDisposed()) { - return; - } - getSDWidget().ensureVisible(sm); - } - }); - } - - /** - * Set the frame and ensure an object is visible from an other thread than the one executing the main loop - * - * @param sm The node to make visible in view - * @param frame Frame The frame to set - */ - public void setFrameAndEnsureVisibleSync(final Frame frame, final GraphNode sm) { - if (getSDWidget() == null || getSDWidget().isDisposed()) { - return; - } - getSDWidget().getDisplay().syncExec(new Runnable() { - @Override - public void run() { - if (getSDWidget() == null || getSDWidget().isDisposed()) { - return; - } - setFrameAndEnsureVisible(frame, sm); - } - }); - } - - /** - * Set the frame and ensure an object is visible - * - * @param sm The node to make visible in view - * @param frame Frame The frame to set - */ - public void setFrameAndEnsureVisible(Frame frame, GraphNode sm) { - getSDWidget().clearSelection(); - setFrame(frame, false); - getSDWidget().ensureVisible(sm); - } - - /** - * Set the frame and ensure an object is visible from an other thread than the one executing the main loop - * - * @param frame The frame to set. - * @param x The x coordinate to make visible. - * @param y The y coordinate to make visible. - */ - public void setFrameAndEnsureVisibleSync(final Frame frame, final int x, final int y) { - if (getSDWidget() == null || getSDWidget().isDisposed()) { - return; - } - - getSDWidget().getDisplay().syncExec(new Runnable() { - @Override - public void run() { - setFrameAndEnsureVisible(frame, x, y); - } - }); - } - - /** - * Set the frame and ensure an object is visible - * - * @param frame The frame to set. - * @param x The x coordinate to make visible. - * @param y The y coordinate to make visible. - */ - public void setFrameAndEnsureVisible(Frame frame, int x, int y) { - getSDWidget().clearSelection(); - setFrame(frame, false); - getSDWidget().ensureVisible(x, y); - getSDWidget().redraw(); - } - - /** - * Toggle between default and wait cursors from an other thread than the one executing the main loop - * - * @param wait true for wait cursor else false for default cursor. - */ - public void toggleWaitCursorAsync(final boolean wait) { - if (getSDWidget() == null || getSDWidget().isDisposed()) { - return; - } - - getSDWidget().getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - if (getSDWidget() == null || getSDWidget().isDisposed()) { - return; - } - if (wait) { - if (fWaitCursor != null && !fWaitCursor.isDisposed()) { - fWaitCursor.dispose(); - } - fWaitCursor = new Cursor(getSDWidget().getDisplay(), SWT.CURSOR_WAIT); - getSDWidget().setCursor(fWaitCursor); - getSDWidget().getDisplay().update(); - } else { - if (fWaitCursor != null && !fWaitCursor.isDisposed()) { - fWaitCursor.dispose(); - } - fWaitCursor = null; - getSDWidget().setCursor(null); - getSDWidget().getDisplay().update(); - } - } - }); - } - - /** - * Return the time compression bar widget - * - * @return the time compression bar - */ - public TimeCompressionBar getTimeCompressionBar() { - return fTimeCompressionBar; - } - - /** - * Returns the current Frame (the sequence diagram container) - * - * @return the current frame - */ - public Frame getFrame() { - if (getSDWidget() != null) { - return getSDWidget().getFrame(); - } - return null; - } - - /** - * Gets the initialization flag. - * @return the value of the initialization flag. - * @since 2.0 - */ - protected boolean isNeedInit() { - return fNeedInit; - } - - /** - * Restores the loader for the view based on the view ID. - * - * @return boolean true if initialization is needed else false. - */ - protected boolean restoreLoader() { - String id = getViewSite().getId(); - if (id == null) { - return true; - } - IUml2SDLoader loader = LoadersManager.getInstance().getCurrentLoader(id, this); - if ((loader != null)) { - loader.setViewer(this); - return false; - } - loadBlank(); - return true; - } - - /** - * Checks if current view is ready to be used. - * - * @return boolean true if view is ready else false. - */ - protected boolean isViewReady() { - IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - if (page == null) { - return false; - } - - IViewReference[] ref = page.getViewReferences(); - for (int i = 0; i < ref.length; i++) { - if (ref[i].getView(false) == this) { - return true; - } - } - return false; - } - - /** - * Creates the menu group. - */ - protected void createMenuGroup() { - IActionBars bar = getViewSite().getActionBars(); - if (bar == null) { - return; - } - bar.getToolBarManager().add(new Separator(UML2SD_VIEW_MODES_SEPARATOR)); - bar.getToolBarManager().add(new Separator(UML2SD_WORKING_SET_SEPARATOR)); - bar.getToolBarManager().add(new Separator(UML2SD_SORTING_SEPARATOR)); - bar.getToolBarManager().add(new Separator(UML2SD_FILTERING_SEPARATOR)); - bar.getToolBarManager().add(new Separator(UML2SD_VIEW_LAYOUT_SEPARATOR)); - bar.getToolBarManager().add(new Separator(UML2SD_LINK_EDITOR_SEPARATOR)); - bar.getToolBarManager().add(new Separator(UML2SD_OTHER_COMMANDS_SEPARATOR)); - bar.getToolBarManager().add(new Separator(UML2SD_OTHER_PLUGINS_COMMANDS_SEPARATOR)); - bar.getMenuManager().add(new Separator(UML2SD_VIEW_MODES_SEPARATOR)); - bar.getMenuManager().add(new Separator(UML2SD_WORKING_SET_SEPARATOR)); - bar.getMenuManager().add(new Separator(UML2SD_SORTING_SEPARATOR)); - bar.getMenuManager().add(new Separator(UML2SD_FILTERING_SEPARATOR)); - bar.getMenuManager().add(new Separator(UML2SD_VIEW_LAYOUT_SEPARATOR)); - bar.getMenuManager().add(new Separator(UML2SD_LINK_EDITOR_SEPARATOR)); - bar.getMenuManager().add(new Separator(UML2SD_OTHER_COMMANDS_SEPARATOR)); - bar.getMenuManager().add(new Separator(UML2SD_OTHER_PLUGINS_COMMANDS_SEPARATOR)); - } - - @Override - public Object getAdapter(Class adapter) { - Object obj = super.getAdapter(adapter); - if (fSdPropertiesProvider != null && adapter.equals(IPropertySheetPage.class)) { - return fSdPropertiesProvider.getPropertySheetEntry(); - } - - return obj; - } - - /** - * Loader for a blank sequence diagram. - * - * @version 1.0 - */ - public static class BlankUml2SdLoader implements IUml2SDLoader { - @Override - public void setViewer(SDView viewer) { - // Nothing to do - Frame f = new Frame(); - f.setName(""); //$NON-NLS-1$ - viewer.setFrame(f); - } - - @Override - public String getTitleString() { - return ""; //$NON-NLS-1$ - } - - @Override - public void dispose() { - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/SDWidget.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/SDWidget.java deleted file mode 100755 index b41887bf18..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/SDWidget.java +++ /dev/null @@ -1,2066 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd; - -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; - -import org.eclipse.jface.contexts.IContextIds; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.BaseMessage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.BasicExecutionOccurrence; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Frame; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.ITimeRange; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Metrics; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.SDPrintDialog; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.SDPrintDialogUI; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDCollapseProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.load.LoadersManager; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.ISDPreferences; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; -import org.eclipse.swt.SWT; -import org.eclipse.swt.accessibility.ACC; -import org.eclipse.swt.accessibility.Accessible; -import org.eclipse.swt.accessibility.AccessibleAdapter; -import org.eclipse.swt.accessibility.AccessibleControlAdapter; -import org.eclipse.swt.accessibility.AccessibleControlEvent; -import org.eclipse.swt.accessibility.AccessibleEvent; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.events.TraverseEvent; -import org.eclipse.swt.events.TraverseListener; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.printing.Printer; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Caret; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.MenuItem; -import org.eclipse.ui.contexts.IContextService; -import org.eclipse.ui.part.ViewPart; - -/** - *

- * This class implements sequence diagram widget used in the sequence diagram view. - *

- * - * @version 1.0 - * @author sveyrier - */ -public class SDWidget extends ScrollView implements SelectionListener, - IPropertyChangeListener, DisposeListener, ITimeCompressionListener { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The frame to display in the sequence diagram widget. - */ - private Frame fFrame; - /** - * The overview image to display. - */ - private Image fOverView = null; - /** - * The zoom in menu item. - */ - private MenuItem fZoomIn = null; - /** - * The zoom out menu item. - */ - private MenuItem fZoomOut = null; - /** - * The sequence diagram selection provider. - */ - private SDWidgetSelectionProvider fSelProvider = null; - /** - * The current zoom value. - */ - private float fZoomValue = 1; - /** - * The current zoomInMode (true for zoom in). - */ - private boolean fZoomInMode = false; - /** - * The current zoomOutMode (true for zoom out). - */ - private boolean fZoomOutMode = false; - /** - * The current list of selected graph nodes. - */ - private List fSelectedNodeList = null; - /** - * Flag whether ctrl button is selected or not. - */ - private boolean fCtrlSelection = false; - /** - * A reference to the view site. - */ - private ViewPart fSite = null; - /** - * The current graph node (the last selected one). - */ - private GraphNode fCurrentGraphNode = null; - /** - * The first graph node in list (multiple selection). - */ - private GraphNode fListStart = null; - /** - * The previous graph node (multiple selection). - */ - private List fPrevList = null; - /** - * The time compression bar. - */ - private TimeCompressionBar fTimeBar = null; - /** - * The current diagram tool tip. - */ - private DiagramToolTip fToolTip = null; - /** - * The accessible object reference of view control. - */ - private Accessible fAccessible = null; - /** - * The current node for the tooltip to display. - */ - private GraphNode fToolTipNode; - /** - * The life line to drag and drop. - */ - private Lifeline fDragAndDrop = null; - /** - * The number of focused widgets. - */ - private int fFocusedWidget = -1; - /** - * The printer zoom. - */ - private float fPrinterZoom = 0; - /** - * Y coordinate for printer. - */ - private int fPrinterY = 0; - /** - * X coordinate for printer. - */ - private int fPrinterX = 0; - /** - * Flag whether drag and drop is enabled or not. - */ - private boolean fIsDragAndDrop = false; - /** - * The x coordinate for drag. - */ - private int fDragX = 0; - /** - * The y coordinate for drag. - */ - private int fDragY = 0; - /** - * The reorder mode. - */ - private boolean fReorderMode = false; - /** - * The collapse caret image. - */ - private Image fCollapaseCaretImg = null; - /** - * The arrow up caret image. - */ - private Image fArrowUpCaretImg = null; - /** - * The current caret image. - */ - private Image fCurrentCaretImage = null; - /** - * A sequence diagramm collapse provider (for collapsing graph nodes) - */ - private ISDCollapseProvider fCollapseProvider = null; - /** - * The insertion caret. - */ - private Caret fInsertionCartet = null; - /** - * The reorder list when in reorder mode. - */ - private List fReorderList = null; - /** - * Flag to specify whether in printing mode or not. - */ - private boolean fIsPrinting = false; - /** - * A printer reference. - */ - private Printer fPrinter = null; - /** - * Flag whether shift was selected or not. - */ - private boolean fShiftSelection = false; - /** - * The scroll tooltip. - */ - private DiagramToolTip fScrollToolTip = null; - /** - * Timer for auto_scroll feature - */ - private AutoScroll fLocalAutoScroll = null; - /** - * TimerTask for auto_scroll feature !=null when auto scroll is running - */ - private Timer fLocalAutoScrollTimer = null; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - /** - * Constructor for SDWidget. - * @param c The parent composite - * @param s The style - */ - public SDWidget(Composite c, int s) { - super(c, s | SWT.NO_BACKGROUND, true); - setOverviewEnabled(true); - fSelectedNodeList = new ArrayList<>(); - fSelProvider = new SDWidgetSelectionProvider(); - SDViewPref.getInstance().addPropertyChangeListener(this); - fToolTip = new DiagramToolTip(getViewControl()); - super.addDisposeListener(this); - - fScrollToolTip = new DiagramToolTip(c); - getVerticalBar().addListener(SWT.MouseUp, new Listener() { - - @Override - public void handleEvent(Event event) { - fScrollToolTip.hideToolTip(); - } - - }); - fAccessible = getViewControl().getAccessible(); - - fAccessible.addAccessibleListener(new AccessibleAdapter() { - @Override - public void getName(AccessibleEvent e) { - // Case toolTip - if (e.childID == 0) { - if (fToolTipNode != null) { - if (fToolTipNode instanceof Lifeline) { - Lifeline lifeline = (Lifeline) fToolTipNode; - e.result = lifeline.getToolTipText(); - } else { - e.result = fToolTipNode.getName() + getPostfixForTooltip(true); - } - } - } else { - if (getFocusNode() != null) { - if (getFocusNode() instanceof Lifeline) { - e.result = MessageFormat.format(Messages.SequenceDiagram_LifelineNode, new Object[] { String.valueOf(getFocusNode().getName()) }); - } - if (getFocusNode() instanceof BaseMessage) { - BaseMessage mes = (BaseMessage) getFocusNode(); - if ((mes.getStartLifeline() != null) && (mes.getEndLifeline() != null)) { - e.result = MessageFormat.format( - Messages.SequenceDiagram_MessageNode, - new Object[] { String.valueOf(mes.getName()), String.valueOf(mes.getStartLifeline().getName()), Integer.valueOf(mes.getStartOccurrence()), String.valueOf(mes.getEndLifeline().getName()), - Integer.valueOf(mes.getEndOccurrence()) }); - } else if ((mes.getStartLifeline() == null) && (mes.getEndLifeline() != null)) { - e.result = MessageFormat.format(Messages.SequenceDiagram_FoundMessageNode, new Object[] { String.valueOf(mes.getName()), String.valueOf(mes.getEndLifeline().getName()), Integer.valueOf(mes.getEndOccurrence()) }); - } else if ((mes.getStartLifeline() != null) && (mes.getEndLifeline() == null)) { - e.result = MessageFormat.format(Messages.SequenceDiagram_LostMessageNode, new Object[] { String.valueOf(mes.getName()), String.valueOf(mes.getStartLifeline().getName()), Integer.valueOf(mes.getStartOccurrence()) }); - } - } else if (getFocusNode() instanceof BasicExecutionOccurrence) { - BasicExecutionOccurrence exec = (BasicExecutionOccurrence) getFocusNode(); - e.result = MessageFormat.format(Messages.SequenceDiagram_ExecutionOccurrenceWithParams, - new Object[] { String.valueOf(exec.getName()), String.valueOf(exec.getLifeline().getName()), Integer.valueOf(exec.getStartOccurrence()), Integer.valueOf(exec.getEndOccurrence()) }); - } - - } - } - } - }); - - fAccessible.addAccessibleControlListener(new AccessibleControlAdapter() { - @Override - public void getFocus(AccessibleControlEvent e) { - if (fFocusedWidget == -1) { - e.childID = ACC.CHILDID_SELF; - } else { - e.childID = fFocusedWidget; - } - } - - @Override - public void getRole(AccessibleControlEvent e) { - switch (e.childID) { - case ACC.CHILDID_SELF: - e.detail = ACC.ROLE_CLIENT_AREA; - break; - case 0: - e.detail = ACC.ROLE_TOOLTIP; - break; - case 1: - e.detail = ACC.ROLE_LABEL; - break; - default: - break; - } - } - - @Override - public void getState(AccessibleControlEvent e) { - e.detail = ACC.STATE_FOCUSABLE; - if (e.childID == ACC.CHILDID_SELF) { - e.detail |= ACC.STATE_FOCUSED; - } else { - e.detail |= ACC.STATE_SELECTABLE; - if (e.childID == fFocusedWidget) { - e.detail |= ACC.STATE_FOCUSED | ACC.STATE_SELECTED | ACC.STATE_CHECKED; - } - } - } - }); - - fInsertionCartet = new Caret((Canvas) getViewControl(), SWT.NONE); - fInsertionCartet.setVisible(false); - - fCollapaseCaretImg = Activator.getDefault().getImageFromPath(ITmfImageConstants.IMG_UI_ARROW_COLLAPSE_OBJ); - fArrowUpCaretImg = Activator.getDefault().getImageFromPath(ITmfImageConstants.IMG_UI_ARROW_UP_OBJ); - - fReorderList = new ArrayList<>(); - getViewControl().addTraverseListener(new LocalTraverseListener()); - - addTraverseListener(new LocalTraverseListener()); - - getViewControl().addFocusListener(new FocusListener() { - - @Override - public void focusGained(FocusEvent e) { - SDViewPref.getInstance().setNoFocusSelection(false); - fCtrlSelection = false; - fShiftSelection = false; - redraw(); - } - - @Override - public void focusLost(FocusEvent e) { - SDViewPref.getInstance().setNoFocusSelection(true); - redraw(); - } - }); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Sets the time compression bar. - * - * @param bar The time compression bar to set - */ - public void setTimeBar(TimeCompressionBar bar) { - if (bar != null) { - fTimeBar = bar; - fTimeBar.addTimeCompressionListener(this); - } - } - - /** - * Resize the contents to insure the frame fit into the view - * - * @param frame the frame which will be drawn in the view - */ - public void resizeContents(Frame frame) { - int width = Math.round((frame.getWidth() + 2 * Metrics.FRAME_H_MARGIN) * fZoomValue); - int height = Math.round((frame.getHeight() + 2 * Metrics.FRAME_V_MARGIN) * fZoomValue); - resizeContents(width, height); - } - - /** - * The frame to render (the sequence diagram) - * - * @param theFrame the frame to display - * @param resetPosition boolean - */ - public void setFrame(Frame theFrame, boolean resetPosition) { - fReorderList.clear(); - fSelectedNodeList.clear(); - fSelProvider.setSelection(new StructuredSelection()); - fFrame = theFrame; - if (resetPosition) { - setContentsPos(0, 0); - resizeContents(fFrame); - redraw(); - } - // prepare the old overview to be reused - if (fOverView != null) { - fOverView.dispose(); - } - fOverView = null; - resizeContents(fFrame); - } - - /** - * Returns the current Frame (the sequence diagram container) - * - * @return the frame - */ - public Frame getFrame() { - return fFrame; - } - - /** - * Returns the selection provider for the current sequence diagram - * - * @return the selection provider - */ - public ISelectionProvider getSelectionProvider() { - return fSelProvider; - } - - /** - * Returns a list of selected graph nodes. - * - * @return a list of selected graph nodes. - */ - public List getSelection() { - return fSelectedNodeList; - } - - /** - * Adds a graph node to the selected nodes list. - * - * @param node A graph node - */ - public void addSelection(GraphNode node) { - if (node == null) { - return; - } - fSelectedNodeList.add(node); - node.setSelected(true); - fCurrentGraphNode = node; - StructuredSelection selection = new StructuredSelection(fSelectedNodeList); - fSelProvider.setSelection(selection); - } - - /** - * Adds a list of node to the selected nodes list. - * - * @param list of graph nodes - */ - public void addSelection(List list) { - for (int i = 0; i < list.size(); i++) { - if (!fSelectedNodeList.contains(list.get(i))) { - fSelectedNodeList.add(list.get(i)); - list.get(i).setSelected(true); - } - } - StructuredSelection selection = new StructuredSelection(fSelectedNodeList); - fSelProvider.setSelection(selection); - } - - /** - * Removes a node from the selected nodes list. - * - * @param node to remove - */ - public void removeSelection(GraphNode node) { - fSelectedNodeList.remove(node); - node.setSelected(false); - node.setFocused(false); - StructuredSelection selection = new StructuredSelection(fSelectedNodeList); - fSelProvider.setSelection(selection); - } - - /** - * Removes a list of graph nodes from the selected nodes list. - * - * @param list of nodes to remove. - */ - public void removeSelection(List list) { - fSelectedNodeList.removeAll(list); - for (int i = 0; i < list.size(); i++) { - list.get(i).setSelected(false); - list.get(i).setFocused(false); - } - StructuredSelection selection = new StructuredSelection(fSelectedNodeList); - fSelProvider.setSelection(selection); - } - - /** - * Clear the list of GraphNodes which must be drawn selected. - */ - public void clearSelection() { - for (int i = 0; i < fSelectedNodeList.size(); i++) { - fSelectedNodeList.get(i).setSelected(false); - fSelectedNodeList.get(i).setFocused(false); - } - fCurrentGraphNode = null; - fSelectedNodeList.clear(); - fSelProvider.setSelection(new StructuredSelection()); - } - - /** - * Sets view part. - * - * @param viewSite The view part to set - */ - public void setSite(ViewPart viewSite) { - fSite = viewSite; - fSite.getSite().setSelectionProvider(fSelProvider); - IContextService service = (IContextService) fSite.getSite().getWorkbenchWindow().getService(IContextService.class); - service.activateContext("org.eclipse.linuxtools.tmf.ui.view.uml2sd.context"); //$NON-NLS-1$ - service.activateContext(IContextIds.CONTEXT_ID_WINDOW); - } - - /** - * Returns the GraphNode overView the mouse if any - * - * @return the current graph node - * */ - public GraphNode getMouseOverNode() { - return fCurrentGraphNode; - } - - /** - * Sets the zoom in mode. - * - * @param value - * The mode value to set. - */ - public void setZoomInMode(boolean value) { - if (value) { - setZoomOutMode(false); - } - fZoomInMode = value; - } - - /** - * Sets the zoom out mode. - * - * @param value - * The mode value to set. - */ - public void setZoomOutMode(boolean value) { - if (value) { - setZoomInMode(false); - } - fZoomOutMode = value; - } - - /** - * Sets the current zoom value. - * - * @param zoomValue - * The current zoom value - * @since 2.0 - */ - public void setZoomValue(float zoomValue) { - fZoomValue = zoomValue; - } - - /** - * Moves the Sequence diagram to ensure the given node is visible and draw it selected - * - * @param node the GraphNode to move to - */ - public void moveTo(GraphNode node) { - if (node == null) { - return; - } - clearSelection(); - addSelection(node); - ensureVisible(node); - } - - /** - * Moves the Sequence diagram to ensure the given node is visible - * - * @param node the GraphNode to move to - */ - public void ensureVisible(GraphNode node) { - if (node == null) { - return; - } - int x = Math.round(node.getX() * fZoomValue); - int y = Math.round(node.getY() * fZoomValue); - int width = Math.round(node.getWidth() * fZoomValue); - int height = Math.round(node.getHeight() * fZoomValue); - if ((node instanceof BaseMessage) && (height == 0)) { - int header = Metrics.LIFELINE_HEARDER_TEXT_V_MARGIN * 2 + Metrics.getLifelineHeaderFontHeigth(); - height = -Math.round((Metrics.getMessagesSpacing() + header) * fZoomValue); - y = y + Math.round(Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT * fZoomValue); - } - if (node instanceof BasicExecutionOccurrence) { - width = 1; - height = 1; - } - if (node instanceof Lifeline) { - y = getContentsY(); - height = getVisibleHeight(); - } - ensureVisible(x, y, width, height, SWT.CENTER, true); - redraw(); - } - - /** - * Returns the current zoom factor. - * @return the current zoom factor. - */ - public float getZoomFactor() { - return fZoomValue; - } - - /** - * Returns teh printer reference. - * - * @return the printer reference - */ - public Printer getPrinter() { - return fPrinter; - } - - /** - * Returns whether the widget is used for printing or not. - * - * @return whether the widget is used for printing or not - */ - public boolean isPrinting() { - return fIsPrinting; - } - - /** - * Returns the current graph node. - * - * @return the current graph node - * @since 2.0 - */ - public GraphNode getCurrentGraphNode() { - return fCurrentGraphNode; - } - - /** - * Returns the current zoom value. - * - * @return the current zoom value - * @since 2.0 - */ - public float getZoomValue() { - return fZoomValue; - } - - /** - * Gets the zoom in mode. - * - * @return the mode value to set. - * @since 2.0 - */ - public boolean getZoomInMode() { - return fZoomInMode; - } - - - /** - * Gets the zoom out mode. - * - * @return the mode value to set. - * @since 2.0 - */ - public boolean getZoomOutMode() { - return fZoomOutMode; - } - - /** - * Returns if ctrl selection - * @return true if ctrl selection else false - * @since 2.0 - */ - public boolean isCtrlSelection() { - return fCtrlSelection; - } - - /** - * Returns if shift selection - * @return true if shift Selection else false - * @since 2.0 - */ - public boolean isShiftSelection() { - return fCtrlSelection; - } - - /** - * Gets the overview image. - * - * @param rect Rectangle to include overview. - * @return the overview image - */ - public Image getOverview(Rectangle rect) { - float oldzoom = fZoomValue; - if ((fOverView != null) && ((rect.width != fOverView.getBounds().width) || (rect.height != fOverView.getBounds().height))) { - fOverView.dispose(); - fOverView = null; - } - if (fOverView == null) { - int backX = getContentsX(); - int backY = getContentsY(); - setContentsPos(0, 0); - fOverView = new Image(getDisplay(), rect.width, rect.height); - GC gcim = new GC(fOverView); - NGC context = new NGC(this, gcim); - context.setBackground(SDViewPref.getInstance().getBackGroundColor(ISDPreferences.PREF_FRAME)); - fFrame.draw(context); - setContentsPos(backX, backY); - gcim.dispose(); - context.dispose(); - } - fZoomValue = oldzoom; - return fOverView; - } - - /** - * Resets the zoom factor. - */ - public void resetZoomFactor() { - int currentX = Math.round(getContentsX() / fZoomValue); - int currentY = Math.round(getContentsY() / fZoomValue); - fZoomValue = 1; - if (fTimeBar != null && !fTimeBar.isDisposed()) { - fTimeBar.setZoom(fZoomValue); - } - redraw(); - update(); - setContentsPos(currentX, currentY); - } - - /** - * Enable or disable the lifeline reodering using Drag and Drop - * - * @param mode - true to enable false otherwise - */ - public void setReorderMode(boolean mode) { - fReorderMode = mode; - } - - /** - * Return the lifelines reorder sequence (using Drag and Drop) if the the reorder mode is turn on. Each ArryList - * element is of type Lifeline[2] with Lifeline[0] inserted before Lifeline[1] in the diagram - * - * @return - the re-odered sequence - */ - public List getLifelineReoderList() { - return fReorderList; - } - - /** - * Sets the focus on given graph node (current node). - * - * @param node - * The graph node to focus on. - */ - public void setFocus(GraphNode node) { - if (node == null) { - return; - } - if (fCurrentGraphNode != null) { - fCurrentGraphNode.setFocused(false); - } - fCurrentGraphNode = node; - node.setFocused(true); - ensureVisible(node); - setFocus(0); - } - - /** - * Returns the graph node focused on. - * - * @return the current graph node - */ - public GraphNode getFocusNode() { - return fCurrentGraphNode; - } - - /** - * Method to traverse right. - */ - public void traverseRight() { - Object selectedNode = getFocusNode(); - if (selectedNode == null) { - traverseLeft(); - } - GraphNode node = null; - if ((selectedNode instanceof BaseMessage) && (((BaseMessage) selectedNode).getEndLifeline() != null)) { - node = fFrame.getCalledMessage((BaseMessage) selectedNode); - } - if (selectedNode instanceof BasicExecutionOccurrence) { - selectedNode = ((BasicExecutionOccurrence) selectedNode).getLifeline(); - } - if ((node == null) && (selectedNode instanceof Lifeline)) { - for (int i = 0; i < fFrame.lifeLinesCount(); i++) { - if ((selectedNode == fFrame.getLifeline(i)) && (i < fFrame.lifeLinesCount() - 1)) { - node = fFrame.getLifeline(i + 1); - break; - } - } - } - if (node != null) { - setFocus(node); - redraw(); - } - } - - /** - * Method to traverse left. - */ - public void traverseLeft() { - Object selectedNode = getFocusNode(); - GraphNode node = null; - if ((selectedNode instanceof BaseMessage) && (((BaseMessage) selectedNode).getStartLifeline() != null)) { - node = fFrame.getCallerMessage((BaseMessage) selectedNode); - } - if (selectedNode instanceof BasicExecutionOccurrence) { - selectedNode = ((BasicExecutionOccurrence) selectedNode).getLifeline(); - } - if (node == null) { - if ((selectedNode instanceof BaseMessage) && (((BaseMessage) selectedNode).getEndLifeline() != null)) { - selectedNode = ((BaseMessage) selectedNode).getEndLifeline(); - } - for (int i = 0; i < fFrame.lifeLinesCount(); i++) { - if ((selectedNode == fFrame.getLifeline(i)) && (i > 0)) { - node = fFrame.getLifeline(i - 1); - break; - } - } - if ((fFrame.lifeLinesCount() > 0) && (node == null)) { - node = fFrame.getLifeline(0); - } - } - if (node != null) { - setFocus(node); - redraw(); - } - } - - /** - * Method to traverse up. - */ - public void traverseUp() { - Object selectedNode = getFocusNode(); - if (selectedNode == null) { - traverseLeft(); - } - GraphNode node = null; - if (selectedNode instanceof BaseMessage) { - node = fFrame.getPrevLifelineMessage(((BaseMessage) selectedNode).getStartLifeline(), (BaseMessage) selectedNode); - } else if (selectedNode instanceof Lifeline) { - node = fFrame.getPrevLifelineMessage((Lifeline) selectedNode, null); - if (!(node instanceof Lifeline)) { - node = null; - } - } else if (selectedNode instanceof BasicExecutionOccurrence) { - node = fFrame.getPrevExecOccurrence((BasicExecutionOccurrence) selectedNode); - if (node == null) { - node = ((BasicExecutionOccurrence) selectedNode).getLifeline(); - } - } - if ((node == null) && (selectedNode instanceof BaseMessage) && (((BaseMessage) selectedNode).getStartLifeline() != null)) { - node = ((BaseMessage) selectedNode).getStartLifeline(); - } - - if (node != null) { - setFocus(node); - redraw(); - } - } - - /** - * Method to traverse down. - */ - public void traverseDown() { - Object selectedNode = getFocusNode(); - if (selectedNode == null) { - traverseLeft(); - } - GraphNode node; - if (selectedNode instanceof BaseMessage) { - node = fFrame.getNextLifelineMessage(((BaseMessage) selectedNode).getStartLifeline(), (BaseMessage) selectedNode); - } else if (selectedNode instanceof Lifeline) { - node = fFrame.getFirstExecution((Lifeline) selectedNode); - } else if (selectedNode instanceof BasicExecutionOccurrence) { - node = fFrame.getNextExecOccurrence((BasicExecutionOccurrence) selectedNode); - } else { - return; - } - - if (node != null) { - setFocus(node); - redraw(); - } - } - - /** - * Method to traverse home. - */ - public void traverseHome() { - Object selectedNode = getFocusNode(); - if (selectedNode == null) { - traverseLeft(); - } - GraphNode node = null; - - if (selectedNode instanceof BaseMessage) { - if (((BaseMessage) selectedNode).getStartLifeline() != null) { - node = fFrame.getNextLifelineMessage(((BaseMessage) selectedNode).getStartLifeline(), null); - } else { - node = fFrame.getNextLifelineMessage(((BaseMessage) selectedNode).getEndLifeline(), null); - } - } else if (selectedNode instanceof Lifeline) { - node = fFrame.getNextLifelineMessage((Lifeline) selectedNode, null); - } else if (selectedNode instanceof BasicExecutionOccurrence) { - node = fFrame.getFirstExecution(((BasicExecutionOccurrence) selectedNode).getLifeline()); - } else { - if (fFrame.lifeLinesCount() > 0) { - Lifeline lifeline = fFrame.getLifeline(0); - node = fFrame.getNextLifelineMessage(lifeline, null); - } - } - - if (node != null) { - setFocus(node); - redraw(); - } - } - - /** - * Method to traverse to the end. - */ - public void traverseEnd() { - Object selectedNode = getFocusNode(); - if (selectedNode == null) { - traverseLeft(); - } - GraphNode node; - if (selectedNode instanceof BaseMessage) { - node = fFrame.getPrevLifelineMessage(((BaseMessage) selectedNode).getStartLifeline(), null); - } else if (selectedNode instanceof Lifeline) { - node = fFrame.getPrevLifelineMessage((Lifeline) selectedNode, null); - } else if (selectedNode instanceof BasicExecutionOccurrence) { - node = fFrame.getLastExecOccurrence(((BasicExecutionOccurrence) selectedNode).getLifeline()); - } else { - if (fFrame.lifeLinesCount() > 0) { - Lifeline lifeline = fFrame.getLifeline(0); - node = fFrame.getPrevLifelineMessage(lifeline, null); - } else { - return; - } - } - - if (node != null) { - setFocus(node); - redraw(); - } - } - - /** - * Method to print UI. - * - * @param sdPrintDialog the sequence diagram printer dialog. - */ - public void printUI(SDPrintDialogUI sdPrintDialog) { - PrinterData data = sdPrintDialog.getPrinterData(); - - if ((data == null) || (fFrame == null)) { - return; - } - - fPrinter = new Printer(data); - - String jobName = MessageFormat.format(Messages.SequenceDiagram_plus, new Object[] { String.valueOf(fSite.getContentDescription()), String.valueOf(fFrame.getName()) }); - fPrinter.startJob(jobName); - - GC gc = new GC(fPrinter); - - float lastZoom = fZoomValue; - - Rectangle area = getClientArea(); - GC gcim = null; - - gcim = gc; - NGC context = new NGC(this, gcim); - - // Set the metrics to use for lifeline text and message text - // using the Graphical Context - Metrics.setLifelineFontHeight(context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE))); - Metrics.setLifelineFontWidth(context.getFontWidth(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE))); - Metrics.setLifelineWidth(SDViewPref.getInstance().getLifelineWidth()); - Metrics.setFrameFontHeight(context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_FRAME_NAME))); - Metrics.setLifelineHeaderFontHeight(context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE_HEADER))); - - int syncMessFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_SYNC_MESS)); - int syncMessRetFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_SYNC_MESS_RET)); - int asyncMessFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_ASYNC_MESS)); - int asyncMessRetFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_ASYNC_MESS_RET)); - - int messageFontHeight = 0; - if (syncMessFontH > syncMessRetFontH) { - messageFontHeight = syncMessFontH; - } else { - messageFontHeight = syncMessRetFontH; - } - if (messageFontHeight < asyncMessFontH) { - messageFontHeight = asyncMessFontH; - } - if (messageFontHeight < asyncMessRetFontH) { - messageFontHeight = asyncMessRetFontH; - } - Metrics.setMessageFontHeight(messageFontHeight); - context.setFont(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE)); - - int width = Math.round((fFrame.getWidth() + 2 * Metrics.FRAME_H_MARGIN) * fZoomValue); - int height = Math.round((fFrame.getHeight() + 2 * Metrics.FRAME_V_MARGIN) * fZoomValue); - if (width < area.width) { - width = area.width; - } - if (height < area.height) { - height = area.height; - } - resizeContents(width, height); - - context.setBackground(SDViewPref.getInstance().getBackGroundColor(ISDPreferences.PREF_FRAME)); - context.fillRectangle(0, 0, getContentsWidth(), Metrics.FRAME_V_MARGIN); - context.fillRectangle(0, 0, fFrame.getX(), getContentsHeight()); - context.fillRectangle(fFrame.getX() + fFrame.getWidth() + 1, 0, getContentsWidth() - (fFrame.getX() + fFrame.getWidth() + 1), getContentsHeight()); - context.fillRectangle(0, fFrame.getY() + fFrame.getHeight() + 1, getContentsWidth(), getContentsHeight() - (fFrame.getY() + fFrame.getHeight() + 1)); - gcim.setLineWidth(1); - - fPrinter.startPage(); - fZoomValue = lastZoom; - - int restoreX = getContentsX(); - int restoreY = getContentsY(); - - float zh = sdPrintDialog.getStepY() * sdPrintDialog.getZoomFactor(); - float zw = sdPrintDialog.getStepX() * sdPrintDialog.getZoomFactor(); - - float zoomValueH = fPrinter.getClientArea().height / zh; - float zoomValueW = fPrinter.getClientArea().width / zw; - if (zoomValueH > zoomValueW) { - fPrinterZoom = zoomValueH; - } else { - fPrinterZoom = zoomValueW; - } - - if (sdPrintDialog.printSelection()) { - int[] pagesList = sdPrintDialog.getPageList(); - - for (int pageIndex = 0; pageIndex < pagesList.length; pageIndex++) { - printPage(pagesList[pageIndex], sdPrintDialog, context); - } - } else if (sdPrintDialog.printAll()) { - for (int pageIndex = 1; pageIndex <= sdPrintDialog.maxNumOfPages(); pageIndex++) { - printPage(pageIndex, sdPrintDialog, context); - } - } else if (sdPrintDialog.printCurrent()) { - printPage(getContentsX(), getContentsY(), sdPrintDialog, context, 1); - } else if (sdPrintDialog.printRange()) { - for (int pageIndex = sdPrintDialog.getFrom(); pageIndex <= sdPrintDialog.maxNumOfPages() && pageIndex <= sdPrintDialog.getTo(); pageIndex++) { - printPage(pageIndex, sdPrintDialog, context); - } - } - - fPrinter.endJob(); - fIsPrinting = false; - - gc.dispose(); - context.dispose(); - - fZoomValue = lastZoom; - fPrinter.dispose(); - setContentsPos(restoreX, restoreY); - } - - /** - * Method to print. - */ - public void print() { - SDPrintDialog sdPrinter = new SDPrintDialog(this.getShell(), this); - try { - if (sdPrinter.open() != 0) { - return; - } - } catch (Exception e) { - Activator.getDefault().logError("Error creating image", e); //$NON-NLS-1$ - return; - } - printUI(sdPrinter.getDialogUI()); - } - - /** - * Method to print a page. - * - * @param pageNum The page number - * @param pd The sequence diagram print dialog - * @param context The graphical context - */ - public void printPage(int pageNum, SDPrintDialogUI pd, NGC context) { - int j = pageNum / pd.getNbRow(); - int i = pageNum % pd.getNbRow(); - if (i != 0) { - j++; - } else { - i = pd.getNbRow(); - } - - i--; - j--; - - i = (int) (i * pd.getStepX()); - j = (int) (j * pd.getStepY()); - - printPage(i, j, pd, context, pageNum); - - fPrinter.endPage(); - } - - /** - * Method to print page ranges. - * - * @param i - * The start page - * @param j - * The end page - * @param pd - * The sequence diagram print dialog - * @param context - * The graphical context - * @param pageNum - * The current page - */ - public void printPage(int i, int j, SDPrintDialogUI pd, NGC context, int pageNum) { - fIsPrinting = false; - int pageNumFontZoom = fPrinter.getClientArea().height / getVisibleHeight(); - fPrinterX = i; - fPrinterY = j; - setContentsPos(i, j); - update(); - fIsPrinting = true; - float lastZoom = fZoomValue; - fZoomValue = fPrinterZoom * lastZoom; - - fFrame.draw(context); - - fZoomValue = pageNumFontZoom; - context.setFont(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE)); - String currentPageNum = String.valueOf(pageNum); - int ii = context.textExtent(currentPageNum); - int jj = context.getCurrentFontHeight(); - fZoomValue = fPrinterZoom * lastZoom; - context.drawText(currentPageNum, Math.round(fPrinterX + getVisibleWidth() / fPrinterZoom - ii / fPrinterZoom), Math.round(fPrinterY + getVisibleHeight() / fPrinterZoom - jj / fPrinterZoom), false); - fIsPrinting = false; - fZoomValue = lastZoom; - } - - /** - * Sets the collapse provider. - * - * @param provider The collapse provider to set - */ - protected void setCollapseProvider(ISDCollapseProvider provider) { - fCollapseProvider = provider; - } - - - /** - * Checks for focus of children. - * - * @param children Control to check - * @return true if child is on focus else false - */ - protected boolean checkFocusOnChilds(Control children) { - if (children instanceof Composite) { - Control[] child = ((Composite) children).getChildren(); - for (int i = 0; i < child.length; i++) { - if (child[i].isFocusControl()) { - return true; - } - checkFocusOnChilds(child[i]); - } - } - return false; - } - - /** - * A post action for a tooltip (before displaying). - * - * @param accessible true if accessible else false - * @return the tooltip text. - */ - protected String getPostfixForTooltip(boolean accessible) { - StringBuffer postfix = new StringBuffer(); - // Determine if the tooltip must show the time difference between the current mouse position and - // the last selected graphNode - if ((fCurrentGraphNode != null) && - (fCurrentGraphNode instanceof ITimeRange) && - (fToolTipNode instanceof ITimeRange) && - (fCurrentGraphNode != fToolTipNode) && - ((ITimeRange) fToolTipNode).hasTimeInfo() && - ((ITimeRange) fCurrentGraphNode).hasTimeInfo()) { - postfix.append(" -> "); //$NON-NLS-1$ - postfix.append(fCurrentGraphNode.getName()); - postfix.append("\n"); //$NON-NLS-1$ - postfix.append(Messages.SequenceDiagram_Delta); - postfix.append(" "); //$NON-NLS-1$ - - //double delta = ((ITimeRange)toolTipNode).getLastTime()-((ITimeRange)currentGraphNode).getLastTime(); - ITmfTimestamp firstTime = ((ITimeRange) fCurrentGraphNode).getEndTime(); - ITmfTimestamp lastTime = ((ITimeRange) fToolTipNode).getEndTime(); - ITmfTimestamp delta = lastTime.getDelta(firstTime); - postfix.append(delta.toString()); - - } else { - if ((fToolTipNode instanceof ITimeRange) && ((ITimeRange) fToolTipNode).hasTimeInfo()) { - postfix.append("\n"); //$NON-NLS-1$ - ITmfTimestamp firstTime = ((ITimeRange) fToolTipNode).getStartTime(); - ITmfTimestamp lastTime = ((ITimeRange) fToolTipNode).getEndTime(); - - if (firstTime != null) { - if (lastTime != null && firstTime.compareTo(lastTime, true) != 0) { - postfix.append("start: "); //$NON-NLS-1$ - postfix.append(firstTime.toString()); - postfix.append("\n"); //$NON-NLS-1$ - postfix.append("end: "); //$NON-NLS-1$ - postfix.append(lastTime.toString()); - postfix.append("\n"); //$NON-NLS-1$ - } else { - postfix.append(firstTime.toString()); - } - } - else if (lastTime != null) { - postfix.append(lastTime.toString()); - } - } - } - return postfix.toString(); - } - - /** - * Sets a new focused widget. - * - * @param newFocusShape A new focus shape. - */ - protected void setFocus(int newFocusShape) { - fFocusedWidget = newFocusShape; - if (fFocusedWidget == -1) { - getViewControl().getAccessible().setFocus(ACC.CHILDID_SELF); - } else { - getViewControl().getAccessible().setFocus(fFocusedWidget); - } - } - - /** - * Highlight the given GraphNode
- * The GraphNode is then displayed using the system default selection color - * - * @param node the GraphNode to highlight - */ - protected void performSelection(GraphNode node) { - if ((fCtrlSelection) || (fShiftSelection)) { - if (node != null) { - if (fSelectedNodeList.contains(node)) { - removeSelection(node); - } else { - addSelection(node); - } - } else { - return; - } - } else { - clearSelection(); - if (node != null) { - addSelection(node); - } - } - } - - /** - * Returns a draw buffer image. - * - * @return a Image containing the draw buffer. - */ - protected Image getDrawBuffer() { - - update(); - Rectangle area = getClientArea(); - Image dbuffer = new Image(getDisplay(), area.width, area.height); - GC gcim = new GC(dbuffer); - NGC context = new NGC(this, gcim); - - // Set the metrics to use for lifeline text and message text - // using the Graphical Context - Metrics.setLifelineFontHeight(context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE))); - Metrics.setLifelineFontWidth(context.getFontWidth(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE))); - Metrics.setLifelineWidth(SDViewPref.getInstance().getLifelineWidth()); - Metrics.setFrameFontHeight(context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_FRAME_NAME))); - Metrics.setLifelineHeaderFontHeight(context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE_HEADER))); - - int syncMessFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_SYNC_MESS)); - int syncMessRetFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_SYNC_MESS_RET)); - int asyncMessFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_ASYNC_MESS)); - int asyncMessRetFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_ASYNC_MESS_RET)); - - int messageFontHeight = 0; - if (syncMessFontH > syncMessRetFontH) { - messageFontHeight = syncMessFontH; - } else { - messageFontHeight = syncMessRetFontH; - } - if (messageFontHeight < asyncMessFontH) { - messageFontHeight = asyncMessFontH; - } - if (messageFontHeight < asyncMessRetFontH) { - messageFontHeight = asyncMessRetFontH; - } - Metrics.setMessageFontHeight(messageFontHeight); - context.setFont(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE)); - - int width = (int) ((fFrame.getWidth() + 2 * Metrics.FRAME_H_MARGIN) * fZoomValue); - int height = (int) ((fFrame.getHeight() + 2 * Metrics.FRAME_V_MARGIN) * fZoomValue); - - resizeContents(width, height); - - context.setBackground(SDViewPref.getInstance().getBackGroundColor(ISDPreferences.PREF_FRAME)); - context.fillRectangle(0, 0, getContentsWidth(), Metrics.FRAME_V_MARGIN); - context.fillRectangle(0, 0, fFrame.getX(), getContentsHeight()); - context.fillRectangle(fFrame.getX() + fFrame.getWidth() + 1, 0, getContentsWidth() - (fFrame.getX() + fFrame.getWidth() + 1), getContentsHeight()); - context.fillRectangle(0, fFrame.getY() + fFrame.getHeight() + 1, getContentsWidth(), getContentsHeight() - (fFrame.getY() + fFrame.getHeight() + 1)); - gcim.setLineWidth(1); - - fFrame.draw(context); - if (fDragAndDrop != null) { - Lifeline node = fDragAndDrop; - boolean isSelected = fDragAndDrop.isSelected(); - boolean hasFocus = fDragAndDrop.hasFocus(); - node.setSelected(false); - node.setFocused(false); - node.draw(context, fDragX, fDragY); - node.setSelected(isSelected); - node.setFocused(hasFocus); - } - gcim.dispose(); - context.dispose(); - return dbuffer; - } - - @Override - protected void keyPressedEvent(KeyEvent event) { - if (!(isFocusControl() || getViewControl().isFocusControl())) { - Control[] child = getParent().getChildren(); - for (int i = 0; i < child.length; i++) { - if ((child[i].isFocusControl())&& (!(child[i] instanceof ScrollView))) { - getViewControl().setFocus(); - break; - } - } - } - setFocus(-1); - - if (event.keyCode == SWT.CTRL) { - fCtrlSelection = true; - } - if (event.keyCode == SWT.SHIFT) { - fShiftSelection = true; - fPrevList = new ArrayList<>(); - fPrevList.addAll(getSelection()); - } - - GraphNode prevNode = getFocusNode(); - - if (event.keyCode == SWT.ARROW_RIGHT) { - traverseRight(); - } - - if (event.keyCode == SWT.ARROW_LEFT) { - traverseLeft(); - } - - if (event.keyCode == SWT.ARROW_DOWN) { - traverseDown(); - } - - if (event.keyCode == SWT.ARROW_UP) { - traverseUp(); - } - - if (event.keyCode == SWT.HOME) { - traverseHome(); - } - - if (event.keyCode == SWT.END) { - traverseEnd(); - } - - if ((!fShiftSelection) && (!fCtrlSelection)) { - fListStart = fCurrentGraphNode; - } - - if (event.character == ' ') { - performSelection(fCurrentGraphNode); - if (!fShiftSelection) { - fListStart = fCurrentGraphNode; - } - } - - if ((fShiftSelection) && (prevNode != getFocusNode())) { - clearSelection(); - addSelection(fPrevList); - addSelection(fFrame.getNodeList(fListStart, getFocusNode())); - if (getFocusNode() instanceof Lifeline) { - ensureVisible(getFocusNode().getX(), getFocusNode().getY(), getFocusNode().getWidth(), getFocusNode().getHeight(), SWT.CENTER | SWT.VERTICAL, true); - } else { - ensureVisible(getFocusNode()); - } - } else if ((!fCtrlSelection) && (!fShiftSelection)) { - - clearSelection(); - if (getFocusNode() != null) { - addSelection(getFocusNode()); - - if (getFocusNode() instanceof Lifeline) { - ensureVisible(getFocusNode().getX(), getFocusNode().getY(), getFocusNode().getWidth(), getFocusNode().getHeight(), SWT.CENTER | SWT.VERTICAL, true); - } else { - ensureVisible(getFocusNode()); - } - } - } - - if (fCurrentGraphNode != null) { - fCurrentGraphNode.setFocused(true); - } - redraw(); - - if ((event.character == ' ') && ((fZoomInMode) || (fZoomOutMode))) { - int cx = Math.round((getContentsX() + getVisibleWidth() / 2) / fZoomValue); - int cy = Math.round((getContentsY() + getVisibleHeight() / 2) / fZoomValue); - if (fZoomInMode) { - if (fZoomValue < 64) { - fZoomValue = fZoomValue * (float) 1.25; - } - } else { - fZoomValue = fZoomValue / (float) 1.25; - } - int x = Math.round(cx * fZoomValue - getVisibleWidth() / (float) 2); - int y = Math.round(cy * fZoomValue - getVisibleHeight() / (float) 2); - setContentsPos(x, y); - if (fTimeBar != null) { - fTimeBar.setZoom(fZoomValue); - } - // redraw also resize the scrollView content - redraw(); - } - } - - @Override - protected void keyReleasedEvent(KeyEvent event) { - setFocus(-1); - if (event.keyCode == SWT.CTRL) { - fCtrlSelection = false; - } - if (event.keyCode == SWT.SHIFT) { - fShiftSelection = false; - } - super.keyReleasedEvent(event); - setFocus(1); - } - - @Override - public boolean isFocusControl() { - Control[] child = getChildren(); - for (int i = 0; i < child.length; i++) { - if (child[i].isFocusControl()) { - return true; - } - checkFocusOnChilds(child[i]); - } - return false; - } - - @Override - public boolean setContentsPos(int x, int y) { - int localX = x; - int localY = y; - - if (localX < 0) { - localX = 0; - } - if (localY < 0) { - localY = 0; - } - if (fFrame == null) { - return false; - } - if (localX + getVisibleWidth() > getContentsWidth()) { - localX = getContentsWidth() - getVisibleWidth(); - } - if (localY + getVisibleHeight() > getContentsHeight()) { - localY = getContentsHeight() - getVisibleHeight(); - } - int x1 = Math.round(localX / fZoomValue); - int y2 = Math.round(localY / fZoomValue); - int width = Math.round(getVisibleWidth() / fZoomValue); - int height = Math.round(getVisibleHeight() / fZoomValue); - fFrame.updateIndex(x1, y2, width, height); - - if (fInsertionCartet != null && fInsertionCartet.isVisible()) { - fInsertionCartet.setVisible(false); - } - - return super.setContentsPos(localX, localY); - } - - @Override - protected void contentsMouseHover(MouseEvent event) { - GraphNode graphNode = null; - if (fFrame != null) { - int x = Math.round(event.x / fZoomValue); - int y = Math.round(event.y / fZoomValue); - graphNode = fFrame.getNodeAt(x, y); - if ((graphNode != null) && (SDViewPref.getInstance().tooltipEnabled())) { - fToolTipNode = graphNode; - String postfix = getPostfixForTooltip(true); - if (graphNode instanceof Lifeline) { - Lifeline lifeline = (Lifeline) graphNode; - fToolTip.showToolTip(lifeline.getToolTipText() + postfix); - setFocus(0); - } else { - fToolTip.showToolTip(graphNode.getName() + postfix); - setFocus(0); - } - } else { - fToolTip.hideToolTip(); - } - } - } - - @Override - protected void contentsMouseMoveEvent(MouseEvent e) { - fScrollToolTip.hideToolTip(); - fToolTip.hideToolTip(); - if (!(isFocusControl() || getViewControl().isFocusControl())) { - Control[] child = getParent().getChildren(); - for (int i = 0; i < child.length; i++) { - if ((child[i].isFocusControl()) && (!(child[i] instanceof ScrollView))) { - getViewControl().setFocus(); - break; - } - } - } - setFocus(-1); - - if (((e.stateMask & SWT.BUTTON_MASK) != 0) && ((fDragAndDrop != null) || fIsDragAndDrop) && (fReorderMode || fCollapseProvider != null)) { - fIsDragAndDrop = false; - if (fCurrentGraphNode instanceof Lifeline) { - fDragAndDrop = (Lifeline) fCurrentGraphNode; - } - if (fDragAndDrop != null) { - int dx = 0; - int dy = 0; - if (e.x > getContentsX() + getVisibleWidth()) { - dx = e.x - (getContentsX() + getVisibleWidth()); - } else if (e.x < getContentsX()) { - dx = -getContentsX() + e.x; - } - if (e.y > getContentsY() + getVisibleHeight()) { - dy = e.y - (getContentsY() + getVisibleHeight()); - } else if (e.y < getContentsY()) { - dy = -getContentsY() + e.y; - } - fDragX = e.x; - fDragY = e.y; - if (dx != 0 || dy != 0) { - if (fLocalAutoScroll == null) { - if (fLocalAutoScrollTimer == null) { - fLocalAutoScrollTimer = new Timer(true); - } - fLocalAutoScroll = new AutoScroll(this, dx, dy); - fLocalAutoScrollTimer.schedule(fLocalAutoScroll, 0, 75); - } else { - fLocalAutoScroll.fDeltaX = dx; - fLocalAutoScroll.fDeltaY = dy; - } - } else if (fLocalAutoScroll != null) { - fLocalAutoScroll.cancel(); - fLocalAutoScroll = null; - } - fDragX = Math.round(e.x / fZoomValue); - fDragY = Math.round(e.y / fZoomValue); - redraw(); - Lifeline node = fFrame.getCloserLifeline(fDragX); - if ((node != null) && (node != fDragAndDrop)) { - int y = 0; - int y1 = 0; - int height = Metrics.getLifelineHeaderFontHeigth() + 2 * Metrics.LIFELINE_HEARDER_TEXT_V_MARGIN; - int hMargin = Metrics.LIFELINE_VT_MAGIN / 4; - int x = node.getX(); - int width = node.getWidth(); - if (fFrame.getVisibleAreaY() < node.getY() + node.getHeight() - height - hMargin) { - y = contentsToViewY(Math.round((node.getY() + node.getHeight()) * fZoomValue)); - } else { - y = Math.round(height * fZoomValue); - } - - if (fFrame.getVisibleAreaY() < contentsToViewY(node.getY() - hMargin)) { - y1 = contentsToViewY(Math.round((node.getY() - hMargin) * fZoomValue)); - } else { - y1 = Math.round(height * fZoomValue); - } - - int rx = Math.round(x * fZoomValue); - - fInsertionCartet.setVisible(true); - if ((fInsertionCartet.getImage() != null) && (!fInsertionCartet.getImage().isDisposed())) { - fInsertionCartet.getImage().dispose(); - } - if (rx <= e.x && Math.round(rx + (width * fZoomValue)) >= e.x) { - if (fCollapseProvider != null) { - ImageData data = fCollapaseCaretImg.getImageData(); - data = data.scaledTo(Math.round(fCollapaseCaretImg.getBounds().width * fZoomValue), Math.round(fCollapaseCaretImg.getBounds().height * fZoomValue)); - fCurrentCaretImage = new Image(Display.getCurrent(), data); - fInsertionCartet.setImage(fCurrentCaretImage); - fInsertionCartet.setLocation(contentsToViewX(rx + Math.round((width / (float) 2) * fZoomValue)) - fCurrentCaretImage.getBounds().width / 2, y); - } - } else if (fReorderMode) { - if (rx > e.x) { - if (node.getIndex() > 1 && fFrame.getLifeline(node.getIndex() - 2) == fDragAndDrop) { - return; - } - ImageData data = fArrowUpCaretImg.getImageData(); - data = data.scaledTo(Math.round(fArrowUpCaretImg.getBounds().width * fZoomValue), Math.round(fArrowUpCaretImg.getBounds().height * fZoomValue)); - fCurrentCaretImage = new Image(Display.getCurrent(), data); - fInsertionCartet.setImage(fCurrentCaretImage); - fInsertionCartet.setLocation(contentsToViewX(Math.round((x - Metrics.LIFELINE_SPACING / 2) * fZoomValue)) - fCurrentCaretImage.getBounds().width / 2, y1); - } else { - if (node.getIndex() < fFrame.lifeLinesCount() && fFrame.getLifeline(node.getIndex()) == fDragAndDrop) { - return; - } - ImageData data = fArrowUpCaretImg.getImageData(); - data = data.scaledTo(Math.round(fArrowUpCaretImg.getBounds().width * fZoomValue), Math.round(fArrowUpCaretImg.getBounds().height * fZoomValue)); - fCurrentCaretImage = new Image(Display.getCurrent(), data); - fInsertionCartet.setImage(fCurrentCaretImage); - fInsertionCartet.setLocation(contentsToViewX(Math.round((x + width + Metrics.LIFELINE_SPACING / 2) * fZoomValue)) - fCurrentCaretImage.getBounds().width / 2 + 1, y1); - } - } - } else { - fInsertionCartet.setVisible(false); - } - } - } else { - super.contentsMouseMoveEvent(e); - } - } - - @Override - protected void contentsMouseUpEvent(MouseEvent event) { - // Just in case the diagram highlight a time compression region - // this region need to be released when clicking everywhere - fInsertionCartet.setVisible(false); - if (fDragAndDrop != null) { - if ((fOverView != null) && (!fOverView.isDisposed())) { - fOverView.dispose(); - } - fOverView = null; - Lifeline node = fFrame.getCloserLifeline(fDragX); - if (node != null) { - int rx = Math.round(node.getX() * fZoomValue); - if (rx <= event.x && Math.round(rx + (node.getWidth() * fZoomValue)) >= event.x) { - if ((fCollapseProvider != null) && (fDragAndDrop != node)) { - fCollapseProvider.collapseTwoLifelines(fDragAndDrop, node); - } - } else if (rx < event.x) { - fFrame.insertLifelineAfter(fDragAndDrop, node); - if (node.getIndex() < fFrame.lifeLinesCount()) { - Lifeline temp[] = { fDragAndDrop, fFrame.getLifeline(node.getIndex()) }; - fReorderList.add(temp); - } else { - Lifeline temp[] = { fDragAndDrop, null }; - fReorderList.add(temp); - } - } else { - fFrame.insertLifelineBefore(fDragAndDrop, node); - Lifeline temp[] = { fDragAndDrop, node }; - fReorderList.add(temp); - } - } - } - fDragAndDrop = null; - redraw(); - if (fFrame == null) { - return; - } - fFrame.resetTimeCompression(); - - // reset auto scroll if it's engaged - if (fLocalAutoScroll != null) { - fLocalAutoScroll.cancel(); - fLocalAutoScroll = null; - } - super.contentsMouseUpEvent(event); - } - - @Override - protected void contentsMouseDownEvent(MouseEvent event) { - if (fCurrentGraphNode != null) { - fCurrentGraphNode.setFocused(false); - } - - // Just in case the diagram highlight a time compression region - // this region need to be released when clicking everywhere - if (fFrame == null) { - return; - } - - fFrame.resetTimeCompression(); - - if ((event.stateMask & SWT.CTRL) != 0) { - fCtrlSelection = true; - } else { - fCtrlSelection = false; - } - - if (((fZoomInMode) || (fZoomOutMode)) && (event.button == 1)) { - int cx = Math.round(event.x / fZoomValue); - int cy = Math.round(event.y / fZoomValue); - if (fZoomInMode) { - if (fZoomValue < 64) { - fZoomValue = fZoomValue * (float) 1.25; - } - } else { - fZoomValue = fZoomValue / (float) 1.25; - } - int x = Math.round(cx * fZoomValue - getVisibleWidth() / (float) 2); - int y = Math.round(cy * fZoomValue - getVisibleHeight() / (float) 2); - setContentsPos(x, y); - if (fTimeBar != null) { - fTimeBar.setZoom(fZoomValue); - } - // redraw also resize the scrollView content - redraw(); - } else { - GraphNode node = null; - int x = Math.round(event.x / fZoomValue); - int y = Math.round(event.y / fZoomValue); - node = fFrame.getNodeAt(x, y); - - if ((event.button == 1) || ((node != null) && !node.isSelected())) { - if (!fShiftSelection) { - fListStart = node; - } - if (fShiftSelection) { - clearSelection(); - addSelection(fFrame.getNodeList(fListStart, node)); - } else { - performSelection(node); - } - fCurrentGraphNode = node; - if (node != null) { - node.setFocused(true); - } - } - redraw(); - } - if (fDragAndDrop == null) { - super.contentsMouseDownEvent(event); - } - fIsDragAndDrop = (event.button == 1); - - } - - /** - * TimerTask for auto scroll feature. - */ - protected static class AutoScroll extends TimerTask { - /** - * Field delta x. - */ - public int fDeltaX; - /** - * Field delta y. - */ - public int fDeltaY; - /** - * Field sequence diagram reference. - */ - public SDWidget fSdWidget; - - /** - * Constructor for AutoScroll. - * @param sv sequence diagram widget reference - * @param dx delta x - * @param dy delta y - */ - public AutoScroll(SDWidget sv, int dx, int dy) { - fSdWidget = sv; - fDeltaX = dx; - fDeltaY = dy; - } - - @Override - public void run() { - Display display = Display.getDefault(); - if ((display == null) || (display.isDisposed())) { - return; - } - display.asyncExec(new Runnable() { - @Override - public void run() { - if (fSdWidget.isDisposed()) { - return; - } - fSdWidget.fDragX += fDeltaX; - fSdWidget.fDragY += fDeltaY; - fSdWidget.scrollBy(fDeltaX, fDeltaY); - } - }); - } - } - - @Override - protected void drawContents(GC gc, int clipx, int clipy, int clipw, int cliph) { - if (fFrame == null) { - gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); - gc.fillRectangle(0, 0, getVisibleWidth(), getVisibleHeight()); - gc.dispose(); - return; - } - SDViewPref.getInstance(); - - Rectangle area = getClientArea(); - Image dbuffer = getDrawBuffer(); - int height = Math.round((fFrame.getHeight() + 2 * Metrics.FRAME_V_MARGIN) * fZoomValue); - - try { - gc.drawImage(dbuffer, 0, 0, area.width, area.height, 0, 0, area.width, area.height); - } catch (Exception e) { - Activator.getDefault().logError("Error drawin content", e); //$NON-NLS-1$ - } - dbuffer.dispose(); - setHScrollBarIncrement(Math.round(SDViewPref.getInstance().getLifelineWidth() / (float) 2 * fZoomValue)); - setVScrollBarIncrement(Math.round(Metrics.getMessagesSpacing() * fZoomValue)); - if ((fTimeBar != null) && (fFrame.hasTimeInfo())) { - fTimeBar.resizeContents(9, height + getHorizontalBarHeight()); - fTimeBar.setContentsPos(getContentsX(), getContentsY()); - fTimeBar.redraw(); - fTimeBar.update(); - } - float xRatio = getContentsWidth() / (float) getVisibleWidth(); - float yRatio = getContentsHeight() / (float) getVisibleHeight(); - if (yRatio > xRatio) { - setOverviewSize((int) (getVisibleHeight() * 0.75)); - } else { - setOverviewSize((int) (getVisibleWidth() * 0.75)); - } - } - - @Override - public void widgetDefaultSelected(SelectionEvent event) { - } - - @Override - public void widgetSelected(SelectionEvent event) { - if (event.widget == fZoomIn) { - fZoomValue = fZoomValue * 2; - } else if (event.widget == fZoomOut) { - fZoomValue = fZoomValue / 2; - } - redraw(); - } - - /** - * Called when property changed occurs in the preference page. "PREFOK" is - * fired when the user press the ok or apply button - */ - @Override - public void propertyChange(PropertyChangeEvent e) { - if (fFrame != null && !isDisposed()) { - fFrame.resetTimeCompression(); - } - if (e.getProperty().equals("PREFOK")) //$NON-NLS-1$ - { - // Prepare the overview to be reused for the new - // settings (especially the colors) - if (fOverView != null) { - fOverView.dispose(); - } - fOverView = null; - redraw(); - } - } - - @Override - public void widgetDisposed(DisposeEvent e) { - if (fOverView != null) { - fOverView.dispose(); - } - super.removeDisposeListener(this); - if ((fCurrentCaretImage != null) && (!fCurrentCaretImage.isDisposed())) { - fCurrentCaretImage.dispose(); - } - if ((fArrowUpCaretImg != null) && (!fArrowUpCaretImg.isDisposed())) { - fArrowUpCaretImg.dispose(); - } - if ((fCollapaseCaretImg != null) && (!fCollapaseCaretImg.isDisposed())) { - fCollapaseCaretImg.dispose(); - } - SDViewPref.getInstance().removePropertyChangeListener(this); - LoadersManager lm = LoadersManager.getInstance(); - if (fSite instanceof SDView) { - ((SDView) fSite).resetProviders(); - if (lm != null) { - lm.resetLoader(((SDView) fSite).getViewSite().getId()); - } - } - } - - @Override - protected void drawOverview(GC gc, Rectangle r) { - float oldzoom = fZoomValue; - if (getContentsWidth() > getContentsHeight()) { - fZoomValue = (float) r.width / (float) getContentsWidth() * oldzoom; - } else { - fZoomValue = (float) r.height / (float) getContentsHeight() * oldzoom; - } - if ((fOverView != null) && ((r.width != fOverView.getBounds().width) || (r.height != fOverView.getBounds().height))) { - fOverView.dispose(); - fOverView = null; - } - if (fOverView == null) { - int backX = getContentsX(); - int backY = getContentsY(); - setContentsPos(0, 0); - fOverView = new Image(getDisplay(), r.width, r.height); - GC gcim = new GC(fOverView); - NGC context = new NGC(this, gcim); - context.setBackground(SDViewPref.getInstance().getBackGroundColor(ISDPreferences.PREF_FRAME)); - fFrame.draw(context); - setContentsPos(backX, backY); - gcim.dispose(); - context.dispose(); - } - if ((fOverView != null) && (r.width == fOverView.getBounds().width) && (r.height == fOverView.getBounds().height)) { - gc.drawImage(fOverView, 0, 0, r.width, r.height, 0, 0, r.width, r.height); - } - - fZoomValue = oldzoom; - - super.drawOverview(gc, r); - } - - @Override - public void deltaSelected(Lifeline lifeline, int startEvent, int nbEvent, IColor color) { - fFrame.highlightTimeCompression(lifeline, startEvent, nbEvent, color); - ensureVisible(lifeline); - int y1 = lifeline.getY() + lifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * startEvent; - int y2 = lifeline.getY() + lifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * (startEvent + nbEvent); - ensureVisible(lifeline.getX(), y1 - (Metrics.getLifelineHeaderFontHeigth() + +2 * Metrics.LIFELINE_HEARDER_TEXT_V_MARGIN), lifeline.getWidth(), y2 - y1 + 3, SWT.CENTER | SWT.VERTICAL, true); - redraw(); - update(); - } - - @Override - public int getVisibleWidth() { - if (fIsPrinting) { - return fPrinter.getClientArea().width; - } - return super.getVisibleWidth(); - } - - @Override - public int getVisibleHeight() { - if (fIsPrinting) { - return fPrinter.getClientArea().height; - } - return super.getVisibleHeight(); - } - - @Override - public int contentsToViewX(int x) { - if (fIsPrinting) { - int v = Math.round(fPrinterX * fPrinterZoom); - return x - v; - } - return x - getContentsX(); - } - - @Override - public int contentsToViewY(int y) { - if (fIsPrinting) { - int v = Math.round(fPrinterY * fPrinterZoom); - return y - v; - } - return y - getContentsY(); - } - - @Override - public int getContentsX() { - if (fIsPrinting) { - return Math.round(fPrinterX * fPrinterZoom); - } - return super.getContentsX(); - } - - @Override - public int getContentsY() { - if (fIsPrinting) { - return Math.round(fPrinterY * fPrinterZoom); - } - return super.getContentsY(); - } - - /** - * Traverse Listener implementation. - */ - protected static class LocalTraverseListener implements TraverseListener { - @Override - public void keyTraversed(TraverseEvent e) { - if ((e.detail == SWT.TRAVERSE_TAB_NEXT) || (e.detail == SWT.TRAVERSE_TAB_PREVIOUS)) { - e.doit = true; - } - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/SDWidgetSelectionProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/SDWidgetSelectionProvider.java deleted file mode 100755 index adc1181c97..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/SDWidgetSelectionProvider.java +++ /dev/null @@ -1,88 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; - -/** - *

- * Informs all registered listeners of graph node selection change in the Frame. - *

- * - * @version 1.0 - * @author sveyrier - */ -public class SDWidgetSelectionProvider implements ISelectionProvider { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The listener list - */ - private List fListenerList = null; - - /** - * The current selection - */ - private ISelection fCurrentSelection = null; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Standard constructor - */ - protected SDWidgetSelectionProvider() { - fListenerList = new ArrayList<>(); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public void addSelectionChangedListener(ISelectionChangedListener listener) { - if (!fListenerList.contains(listener)) { - fListenerList.add(listener); - } - } - - @Override - public void removeSelectionChangedListener(ISelectionChangedListener listener) { - fListenerList.remove(listener); - } - - @Override - public void setSelection(ISelection selection) { - fCurrentSelection = selection; - for (int i = 0; i < fListenerList.size(); i++) { - ISelectionChangedListener list = fListenerList.get(i); - list.selectionChanged(new SelectionChangedEvent(this, fCurrentSelection)); - } - } - - @Override - public ISelection getSelection() { - return fCurrentSelection; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/ScrollView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/ScrollView.java deleted file mode 100755 index 5b4cc295fd..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/ScrollView.java +++ /dev/null @@ -1,2067 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd; - -import java.util.Timer; -import java.util.TimerTask; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ControlListener; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.events.MouseTrackListener; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.events.TypedEvent; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.PaletteData; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Layout; -import org.eclipse.swt.widgets.ScrollBar; -import org.eclipse.swt.widgets.Scrollable; -import org.eclipse.swt.widgets.Shell; - -/** - * ScrollView widget provides a scrolling area with on-demand scroll bars. - * Overview scrollable panel can be used (@see setOverviewEnabled()). - * - * @author Eric Miravete - * @version 1.0 - */ -public class ScrollView extends Composite { - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * Scroll bar mode AUTO - */ - public static final int AUTO = 0; - /** - * Scroll bar mode ALWAYS_ON - */ - public static final int ALWAYS_ON = 1; - /** - * Scroll bar mode ALWAYS_OFF - */ - public static final int ALWAYS_OFF = 2; - /** - * Bit mask for visible vertical scroll bar - */ - public static final int VBAR = 0x01; - /** - * Bit mask for visible horizontal scroll bar - */ - public static final int HBAR = 0x02; - - private static final int DEFAULT_H_SCROLL_INCREMENT = 10; - private static final int DEFAULT_V_SCROLL_INCREMENT = 10; - private static final int DEFAULT_AUTO_SCROLL_PERIOD = 75; - private static final int DEFAULT_OVERVIEW_SIZE = 100; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * Value of the contents height property. - */ - private int fContentsHeight = 0; - /** - * Value of the contents width property. - */ - private int fContentsWidth = 0; - /** - * Value of the contents x coordinate property - */ - private int fContentsX = 0; - /** - * Value of the contents y coordinate property - */ - private int fContentsY = 0; - /** - * Scroll bar mode of horizontal scroll bar. - */ - private int fHorScrollbarMode = AUTO; - /** - * Scroll bar mode of vertical scroll bar. - */ - private int fVertScrollbarMode = AUTO; - /** - * Increment for the horizontal scroll bar. - */ - private int fHorScrollbarIncrement = DEFAULT_H_SCROLL_INCREMENT; - /** - * Increment for the vertical scroll bar. - */ - private int fVertScrollbarIncrement = DEFAULT_V_SCROLL_INCREMENT; - /** - * Flag whether auto scroll is enabled or not. - */ - private boolean fAutoScrollEnabled = true; - /** - * Value of the auto scroll period. - */ - private int fAutoScrollPeriod = DEFAULT_AUTO_SCROLL_PERIOD; - /** - * The local paint listener reference. - */ - private PaintListener fLocalPaintListener = null; - /** - * The local mouse move listener reference. - */ - private MouseMoveListener fLocalMouseMoveListener = null; - /** - * The local mouse listener reference. - */ - private MouseListener fLocalMouseListener = null; - /** - * The local control listener reference. - */ - private ControlListener fLocalControlListener = null; - /** - * The local key listener reference. - */ - private KeyListener fLocalKeyListener = null; - // Canvas for vertical/horizontal Scroll Bar only ... because new ScrollBar() does works. - /** - * Canvas for horizontal scroll bar. - */ - private Canvas fHorScrollBar; - /** - * Canvas for vertical scroll bar. - */ - private Canvas fVertScrollBar; - /** - * Canvas for the view control. - */ - private Canvas fViewControl; - /** - * Control used in the bottom right corner @see setCornerControl() and @see setOverviewEnabled(true) - */ - private Control fCornerControl; - /** - * Size of overview widget. - */ - private int fOverviewSize = DEFAULT_OVERVIEW_SIZE; // default size for overview - /** - * Timer for auto_scroll feature - */ - private AutoScroll fAutoScroll = null; - /** - * TimerTask for auto_scroll feature !=null when auto scroll is running - */ - private Timer fAutoScrollTimer = null; - /** - * where mouse down appear on contents area (x coordinate) - */ - private int fMouseDownX = -1; - /** - * where mouse down appear on contents area (y coordinate) - */ - private int fMousDownY = -1; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Create a ScrollView, child of composite c. Both scroll bar have the mode AUTO. Auto scroll feature is enabled - * using a delay of 250ms. Overview feature is not enabled by default (use setOverviewEnabled()). - * - * @param c The parent composite - * @param style The SWT style bits @see SWT - */ - public ScrollView(Composite c, int style) { - this(c, style, true); - } - - /** - * Create a ScrollView, child of composite c. Both scroll bar have the mode AUTO. Auto scroll feature is enabled - * using a delay of 250ms. Overview feature is not enabled by default (use setOverviewEnabled()). - * - * @param c The parent composite. - * @param style The SWT style bits @see SWT - * @param mouseWheel Flag to force scrollView to handles mouse wheel - */ - public ScrollView(Composite c, int style, boolean mouseWheel) { - super(c, SWT.NONE); - - fHorScrollBar = new Canvas(this, SWT.H_SCROLL); - if (mouseWheel) { - // force scroll bar to get mouse wheel, those scrollbar will be hidden - fViewControl = new Canvas(this, style | SWT.H_SCROLL | SWT.V_SCROLL); - } else { - fViewControl = new Canvas(this, style); - } - fViewControl.setBackground(getBackground()); - // hide scroll bar as their are replaced by fHorScrollBar and fVertScrollBar. - if (mouseWheel) { - fViewControl.getVerticalBar().setVisible(false); - fViewControl.getHorizontalBar().setVisible(false); - } - fVertScrollBar = new Canvas(this, SWT.V_SCROLL); - - setLayout(new SVLayout()); - - fLocalPaintListener = new PaintListener() { - @Override - public void paintControl(PaintEvent event) { - // use clipping, to reduce cost of paint. - Rectangle r = event.gc.getClipping(); - int cx = viewToContentsX(r.x); - int cy = viewToContentsY(r.y); - drawContents(event.gc, cx, cy, r.width, r.height); - } - }; - fViewControl.addPaintListener(fLocalPaintListener); - - fLocalMouseMoveListener = new MouseMoveListener() { - @Override - public void mouseMove(MouseEvent e) { - int ox = e.x, oy = e.y; - e.x = viewToContentsX(e.x); - e.y = viewToContentsY(e.y); - contentsMouseMoveEvent(e); - e.x = ox; - e.y = oy; - } - }; - - fViewControl.addMouseMoveListener(fLocalMouseMoveListener); - - MouseTrackListener localMouseTrackListener = new MouseTrackListener() { - @Override - public void mouseEnter(MouseEvent e) { - int ox = e.x, oy = e.y; - e.x = viewToContentsX(e.x); - e.y = viewToContentsY(e.y); - contentsMouseEnter(e); - e.x = ox; - e.y = oy; - } - - @Override - public void mouseHover(MouseEvent e) { - int ox = e.x, oy = e.y; - e.x = viewToContentsX(e.x); - e.y = viewToContentsY(e.y); - contentsMouseHover(e); - e.x = ox; - e.y = oy; - } - - @Override - public void mouseExit(MouseEvent e) { - int ox = e.x, oy = e.y; - e.x = viewToContentsX(e.x); - e.y = viewToContentsY(e.y); - contentsMouseExit(e); - e.x = ox; - e.y = oy; - } - - }; - - fViewControl.addMouseTrackListener(localMouseTrackListener); - - fLocalMouseListener = new MouseListener() { - @Override - public void mouseDoubleClick(MouseEvent e) { - int ox = e.x, oy = e.y; - e.x = viewToContentsX(e.x); - e.y = viewToContentsY(e.y); - contentsMouseDoubleClickEvent(e); - e.x = ox; - e.y = oy; - } - - @Override - public void mouseDown(MouseEvent e) { - int ox = e.x, oy = e.y; - e.x = viewToContentsX(e.x); - fMouseDownX = e.x; - e.y = viewToContentsY(e.y); - fMousDownY = e.y; - contentsMouseDownEvent(e); - e.x = ox; - e.y = oy; - } - - @Override - public void mouseUp(MouseEvent e) { - int ox = e.x, oy = e.y; - e.x = viewToContentsX(e.x); - e.y = viewToContentsY(e.y); - contentsMouseUpEvent(e); - e.x = ox; - e.y = oy; - // here because class extending me can catch mouse Up and want to scroll... - fMouseDownX = -1; - fMousDownY = -1; - } - }; - fViewControl.addMouseListener(fLocalMouseListener); - - fLocalKeyListener = new KeyListener() { - @Override - public void keyPressed(KeyEvent e) { - keyPressedEvent(e); - } - - @Override - public void keyReleased(KeyEvent e) { - keyReleasedEvent(e); - } - }; - - fViewControl.addKeyListener(fLocalKeyListener); - - getVerticalBar().addSelectionListener(new SelectionListener() { - @Override - public void widgetSelected(SelectionEvent e) { - setContentsPos(fContentsX, getVerticalBar().getSelection()); - // need to change "hidden" vertical bar value ? - // force focus on fViewControl so we got future mouse wheel's scroll events - if (!fViewControl.isFocusControl()) { - fViewControl.setFocus(); - } - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - }); - - if (fViewControl.getVerticalBar() != null) { - // add fViewControl hidden scrollbar listener to get mouse wheel ... - fViewControl.getVerticalBar().addSelectionListener(new SelectionListener() { - @Override - public void widgetSelected(SelectionEvent e) { - ScrollBar b = fViewControl.getVerticalBar(); - setContentsPos(fContentsX, b.getSelection()); - // change "real" vertical bar selection too - getVerticalBar().setSelection(b.getSelection()); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - }); - } - getHorizontalBar().addSelectionListener(new SelectionListener() { - @Override - public void widgetSelected(SelectionEvent e) { - setContentsPos(getHorizontalBar().getSelection(), fContentsY); - // need to change "real" horizontal bar too ? - // force focus on fViewControl so we got future mouse wheel's scroll events - if (!fViewControl.isFocusControl()) { - fViewControl.setFocus(); - } - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - }); - if (fViewControl.getHorizontalBar() != null) { - fViewControl.getHorizontalBar().addSelectionListener(new SelectionListener() { - @Override - public void widgetSelected(SelectionEvent e) { - ScrollBar b = fViewControl.getHorizontalBar(); - setContentsPos(b.getSelection(), fContentsY); - // change "real" vertical bar selection too - getHorizontalBar().setSelection(b.getSelection()); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - }); - } - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public boolean setFocus() { - return fViewControl.forceFocus(); - } - - @Override - public void setCursor(Cursor cursor) { - fViewControl.setCursor(cursor); - } - - @Override - public void dispose() { - if (fAutoScroll != null) { - fAutoScroll.cancel(); - fAutoScroll = null; - } - if (fViewControl != null) { - fViewControl.dispose(); - } - fViewControl = null; - if (fVertScrollBar != null) { - fVertScrollBar.dispose(); - } - fVertScrollBar = null; - if (fHorScrollBar != null) { - fHorScrollBar.dispose(); - } - fHorScrollBar = null; - if (fCornerControl != null) { - Object data = fCornerControl.getData(); - if (data instanceof Overview) { - ((Overview) data).dispose(); - } - fCornerControl.dispose(); - fCornerControl = null; - } - super.dispose(); - } - - @Override - public Rectangle getClientArea() { - Rectangle area = fViewControl.getClientArea(); - /* Clamp the size of the returned area to 1x1 minimum */ - area.width = Math.max(area.width, 1); - area.height = Math.max(area.height, 1); - return area; - } - - @Override - public void setBackground(Color c) { - super.setBackground(c); - fViewControl.setBackground(c); - } - - @Override - public void setToolTipText(String text) { - fViewControl.setToolTipText(text); - } - - /** - * Draw overview area, @see setOverviewEnabled. By default draw a rectangle corresponding to the visible area of - * scroll view. You can redefine this method to draw the contents as drawContents does... ...in an other magnify - * factor. - * - * @param gc GC to used to draw. - * @param r Rectangle corresponding to the client area of overview. - */ - protected void drawOverview(GC gc, Rectangle r) { - int x = (int) (r.width * fContentsX / (float) fContentsWidth); - int y = (int) (r.height * fContentsY / (float) fContentsHeight); - int vw = getVisibleWidth(); - int vh = getVisibleHeight(); - int w = r.width - 1; - if (fContentsWidth > vw) { - w = (int) (r.width * vw / (float) fContentsWidth); - } - int h = r.height - 1; - if (fContentsHeight > vh) { - h = (int) (r.height * vh / (float) fContentsHeight); - } - - gc.setForeground(getForeground()); - // too small rectangle ? - if (w < 5 || h < 5) { - // use a cross ... - gc.drawLine(x, 0, x, r.height); - gc.drawLine(0, y, r.width, y); - } else { - gc.drawRectangle(x, y, w, h); - } - } - - /** - * Remove the local Listener and add the new listener. - * - * @param nlistener the new listener - */ - public void replaceControlListener(ControlListener nlistener) { - if (fLocalControlListener != null) { - removeControlListener(fLocalControlListener); - fLocalControlListener = null; - } - addControlListener(nlistener); - } - - /** - * Remove the local Listener and add the new listener. - * - * @param nlistener the new listener - */ - public void replaceKeyListener(KeyListener nlistener) { - if (fLocalKeyListener != null) { - removeKeyListener(fLocalKeyListener); - fLocalKeyListener = null; - } - addKeyListener(nlistener); - } - - /** - * Remove the local Listener and add the new listener. - * - * @param nlistener the new listener - */ - public void replaceMouseListener(MouseListener nlistener) { - if (fLocalMouseListener != null) { - removeMouseListener(fLocalMouseListener); - fLocalMouseListener = null; - } - fViewControl.addMouseListener(nlistener); - } - - /** - * Remove the local Listener and add the new listener. - * - * @param nlistener the new listener - */ - public void replaceMouseMoveListener(MouseMoveListener nlistener) { - if (fLocalMouseMoveListener != null) { - removeMouseMoveListener(fLocalMouseMoveListener); - fLocalMouseMoveListener = null; - } - fViewControl.addMouseMoveListener(nlistener); - } - - /** - * Remove the local Listener and add the new listener. - * - * @param nlistener the new listener - */ - public void replacePaintListener(PaintListener nlistener) { - if (fLocalPaintListener != null) { - removePaintListener(fLocalPaintListener); - fLocalPaintListener = null; - } - fViewControl.addPaintListener(nlistener); - } - - /** - * Access method for the contentsHeight property. - * - * @return the current value of the contentsHeight property - */ - public int getContentsHeight() { - return fContentsHeight; - } - - /** - * Access method for the contentsWidth property. - * - * @return the current value of the contentsWidth property - */ - public int getContentsWidth() { - return fContentsWidth; - } - - /** - * Access method for the contentsX property. - * - * @return the current value of the contentsX property - */ - public int getContentsX() { - return fContentsX; - } - - /** - * Access method for the contentsY property. - * - * @return the current value of the contentsY property - */ - public int getContentsY() { - return fContentsY; - } - - /** - * Determines if the dragAutoScroll property is true. - * - * @return true if the dragAutoScroll property is true - */ - public boolean isDragAutoScroll() { - return fAutoScrollEnabled; - } - - /** - * Sets the value of the dragAutoScroll property. - * - * @param aDragAutoScroll the new value of the dragAutoScroll property - */ - public void setDragAutoScroll(boolean aDragAutoScroll) { - fAutoScrollEnabled = aDragAutoScroll; - if (!fAutoScrollEnabled && (fAutoScroll != null)) { - fAutoScroll.cancel(); - fAutoScroll = null; - } - } - - /** - * Change delay (in millisec) used for auto scroll feature. - * - * @param period new period between to auto scroll - */ - public void setDragAutoScrollPeriod(int period) { - fAutoScrollPeriod = Math.max(0, period); - } - - /** - * Return auto scroll period. - * - * @return The period - */ - public int getDragAutoScrollPeriod() { - return fAutoScrollPeriod; - } - - /** - * Access method for the hScrollBarMode property. - * - * @return the current value of the hScrollBarMode property - */ - public int getHScrollBarMode() { - return fHorScrollbarMode; - } - - /** - * Sets the value of the hScrollBarMode property. - * - * @param aHScrollBarMode the new value of the hScrollBarMode property - */ - public void setHScrollBarMode(int aHScrollBarMode) { - fHorScrollbarMode = aHScrollBarMode; - } - - /** - * Access method for the vScrollBarMode property. - * - * @return the current value of the vScrollBarMode property - */ - public int getVScrollBarMode() { - return fVertScrollbarMode; - } - - /** - * Sets the value of the vScrollBarMode property. - * - * @param aVScrollBarMode the new value of the vScrollBarMode property - */ - public void setVScrollBarMode(int aVScrollBarMode) { - fVertScrollbarMode = aVScrollBarMode; - } - - /** - * Return horizontal scroll bar increment, default:1 - * - * @return The increment - */ - public int getHScrollBarIncrement() { - return fHorScrollbarIncrement; - } - - /** - * Return vertical scroll bar increment, default:1 - * - * @return The increment - */ - public int getVScrollBarIncrement() { - return fVertScrollbarIncrement; - } - - /** - * Change horizontal scroll bar increment, minimum:1. Page increment is - * always set to visible width. - * - * @param inc - * Increment value to set - */ - public void setHScrollBarIncrement(int inc) { - fHorScrollbarIncrement = Math.max(1, inc); - } - - /** - * Change vertical scroll bar increment, minimum:1. Page increment is always - * set to visible height. - * - * @param inc - * Increment value to set - */ - public void setVScrollBarIncrement(int inc) { - fVertScrollbarIncrement = Math.max(1, inc); - } - - /** - * Enable or disable overview feature. Enabling overview, dispose and replace existing corner control by a button. - * Clicking in it open overview, move mouse cursor holding button to move scroll view and release button to hide - * overview. Tip: hold control and/or shift key while moving mouse when overview is open made fine scroll. - * - * @param value true to engage overview feature - */ - public void setOverviewEnabled(boolean value) { - if (isOverviewEnabled() == value) { - return; - } - - Control cc = null; - if (value) { - Button b = new Button(this, SWT.NONE); - b.setText("+"); //$NON-NLS-1$ - Overview ovr = new Overview(); - ovr.useControl(b); - b.setData(ovr); - cc = b; - b.setToolTipText(Messages.SequenceDiagram_OpenOverviewTooltip); - } - setCornerControl(cc); - } - - /** - * Change overview size (at ratio 1:1), default is 100 - * - * @param size - * The new size - */ - public void setOverviewSize(int size) { - fOverviewSize = Math.abs(size); - } - - /** - * Returns whether the overview is enabled or not. - * - * @return true is overview feature is enabled - */ - public boolean isOverviewEnabled() { - if (fCornerControl instanceof Button) { - Object data = ((Button) fCornerControl).getData(); - // overview alreay - if (data instanceof Overview) { - return true; - } - } - return false; - } - - /** - * Returns the overview size at ratio 1:1. - * - * @return current overview size at ratio 1:1 - */ - public int getOverviewSize() { - return fOverviewSize; - } - - /** - * Returns control used to display view (might not be this object). Use this control to add/remove listener on the - * draw area. - * - * @return control used to display view (might not be this object). - */ - public Control getViewControl() { - return fViewControl; - } - - /** - * Called when the mouse enter the ScrollView area - * - * @param e - * Mouse event - */ - protected void contentsMouseExit(MouseEvent e) { - } - - /** - * Called when the mouse enter the ScrollView area after and system defined - * time - * - * @param e - * Mouse event - */ - protected void contentsMouseHover(MouseEvent e) { - } - - /** - * Called when the mouse enter the ScrollView area - * - * @param e - * Mouse event - */ - protected void contentsMouseEnter(MouseEvent e) { - } - - /** - * Called when user double on contents area. - * - * @param e - * Mouse event - */ - protected void contentsMouseDoubleClickEvent(MouseEvent e) { - } - - /** - * Called when mouse is on contents area and button is pressed. - * - * @param e - * Mouse event - */ - protected void contentsMouseDownEvent(MouseEvent e) { - fMouseDownX = e.x; - fMousDownY = e.y; - } - - /** - * TimerTask for auto scroll feature. - */ - protected static class AutoScroll extends TimerTask { - - /** X delta */ - private int deltaX; - - /** Y delta */ - private int deltaY; - - /** ScrollView object */ - private ScrollView scrollView; - - /** - * Constructor. - * - * @param sv - * ScrollView object to use - * @param dx - * X delta - * @param dy - * Y delta - */ - public AutoScroll(ScrollView sv, int dx, int dy) { - scrollView = sv; - deltaX = dx; - deltaY = dy; - } - - @Override - public void run() { - final Display display = Display.getDefault(); - if ((display == null) || display.isDisposed()) { - return; - } - display.asyncExec(new Runnable() { - @Override - public void run() { - if (!scrollView.isDisposed()) { - scrollView.scrollBy(deltaX, deltaY); - } - } - }); - } - } - - /** - * Called when mouse is on contents area and mode. - * - * @param event - * Mouse event - */ - protected void contentsMouseMoveEvent(MouseEvent event) { - if ((event.stateMask & SWT.BUTTON_MASK) != 0) { - if (!fAutoScrollEnabled) { - scrollBy(-(event.x - fMouseDownX), -(event.y - fMousDownY)); - return; - } - - int sx = 0, sy = 0; - - int vRight = getContentsX() + getVisibleWidth(); - int vBottom = getContentsY() + getVisibleHeight(); - - // auto scroll... ? - if (event.x < getContentsX()) { - sx = (getContentsX() - event.x); - fMouseDownX = getContentsX(); - } else if (event.x > vRight) { - sx = -event.x + vRight; - fMouseDownX = vRight; - } - if (event.y < getContentsY()) { - sy = (getContentsY() - event.y); - fMousDownY = getContentsY(); - } else if (event.y > vBottom) { - sy = -event.y + vBottom; - fMousDownY = vBottom; - } - - if (sx != 0 || sy != 0) { - // start auto scroll... - if (fAutoScroll == null) { - if (fAutoScrollTimer == null) { - fAutoScrollTimer = new Timer(true); - } - fAutoScroll = new AutoScroll(this, sx, sy); - fAutoScrollTimer.schedule(fAutoScroll, 0, fAutoScrollPeriod); - } else { - fAutoScroll.deltaX = sx; - fAutoScroll.deltaY = sy; - } - } else { - if (fAutoScroll != null) { - fAutoScroll.cancel(); - fAutoScroll = null; - } - - scrollBy(-(event.x - fMouseDownX), -(event.y - fMousDownY)); - } - } - } - - /** - * Called when mouse is on contents area and button is released - * - * @param event - * Mouse event - */ - protected void contentsMouseUpEvent(MouseEvent event) { - // reset auto scroll if it's engaged - if (fAutoScroll != null) { - fAutoScroll.cancel(); - fAutoScroll = null; - } - } - - /** - * Responsible to draw contents area. At least rectangle clipX must be - * redrawn. This rectangle is given in contents coordinates. By default, no - * paint is produced. - * - * @param gc - * Graphics context - * @param clipx - * X clip - * @param clipy - * Y clip - * @param clipw - * W clip - * @param cliph - * H clip - */ - protected void drawContents(GC gc, int clipx, int clipy, int clipw, int cliph) { - } - - /** - * Change the size of the contents area. - * - * @param width new width of the area. - * @param height new height of the area. - */ - public void resizeContents(int width, int height) { - int localWidth = width; - int localHeight = height; - - if (localWidth < 0) { - localWidth = 0; - } - if (localHeight < 0) { - localHeight = 0; - } - - int oldW = fContentsWidth; - int oldH = fContentsHeight; - - if (localWidth == oldW && localHeight == oldH) { - return; - } - - fContentsWidth = localWidth; - fContentsHeight = localHeight; - - if (oldW > localWidth) { - int s = localWidth; - localWidth = oldW; - oldW = s; - } - - int visWidth = getVisibleWidth(); - int visHeight = getVisibleHeight(); - if (oldW < visWidth) { - if (localWidth > visWidth) { - localWidth = visWidth; - } - fViewControl.redraw(getContentsX() + oldW, 0, localWidth - oldW, visHeight, true); - } - - if (oldH > localHeight) { - int s = localHeight; - localHeight = oldH; - oldH = s; - } - - if (oldH < visHeight) { - if (localHeight > visHeight) { - localHeight = visHeight; - } - fViewControl.redraw(0, getContentsY() + oldH, visWidth, localHeight - oldH, true); - } - if (updateScrollBarVisiblity()) { - layout(); - } else { - updateScrollBarsValues(); - } - } - - // redefined for internal use .. - @Override - public void redraw() { - super.redraw(); - // ..need to redraw this already: - fViewControl.redraw(); - } - - /** - * @param delataX The delta in X - * @param deltaY the delta in Y - */ - public void scrollBy(int delataX, int deltaY) { - setContentsPos(getContentsX() + delataX, getContentsY() + deltaY); - } - - /** - * Scroll to ensure point(in contents coordinates) is visible. - * - * @param px Point's x position - * @param py Point's y position - */ - public void ensureVisible(int px, int py) { - int cx = getContentsX(), cy = getContentsY(); - int right = getContentsX() + getVisibleWidth(); - int bottom = getContentsY() + getVisibleHeight(); - if (px < getContentsX()) { - cx = px; - } else if (px > right) { - cx = px - getVisibleWidth(); - } - if (py < getContentsY()) { - cy = py; - } else if (py > bottom) { - cy = py - getVisibleHeight(); - } - setContentsPos(cx, cy); - } - - /** - * Make rectangle (x,y,w,h, in contents coordinates) visible. if rectangle cannot be completely visible, use - * align flags. - * - * @param xValue x contents coordinates of rectangle. - * @param yValue y contents coordinates of rectangle. - * @param width width of rectangle. - * @param height height of rectangle. - * @param align bit or'ed SWT flag like SWT.LEFT,RIGHT,CENTER,TOP,BOTTOM,VERTICAL used only for bigger rectangle - * than visible area. By default CENTER/VERTICAL - */ - public void ensureVisible(int xValue, int yValue, int width, int height, int align) { - ensureVisible(xValue, yValue, width, height, align, false); - } - - /** - * Make rectangle (xValue,yValue,width,height, in contents coordinates) visible. if rectangle cannot be completely visible, use - * align flags. - * - * @param xValue x contents coordinates of rectangle. - * @param yValue y contents coordinates of rectangle. - * @param width width of rectangle. - * @param height height of rectangle. - * @param align bit or'ed SWT flag like SWT.LEFT,RIGHT,CENTER,TOP,BOTTOM,VERTICAL used only for bigger rectangle - * than visible area. By default CENTER/VERTICAL - * @param forceAlign force alignment for rectangle smaller than the visible area - */ - protected void ensureVisible(int xValue, int yValue, int width, int height, int align, boolean forceAlign) { - - int localX = xValue; - int localY = yValue; - int localWidth = width; - int localHeight = height; - - if (localWidth < 0) { - localX = localX + localWidth; - localWidth = -localWidth; - } - if (localHeight < 0) { - localY = localY + localHeight; - localHeight = -localHeight; - } - int hbar = getHorizontalBarHeight(); - int vbar = getVerticalBarWidth(); - int cx = getContentsX(); - int cy = getContentsY(); - int right = getContentsX() + getVisibleWidth() - vbar; - int bottom = getContentsY() + getVisibleHeight() - hbar; - boolean alignH = false, alignV = false; - - if (localX < getContentsX()) { - cx = localX; - } else if (localX + localWidth > right) { - cx = localX - localWidth; - } - if (localY < getContentsY()) { - cy = localY; - } else if (localY + localHeight > bottom) { - cy = localY - localHeight; - } - - if (localWidth > getVisibleWidth()) { - alignH = true; - } - if (localHeight > getVisibleHeight()) { - alignV = true; - } - // compute alignment on visible area horizontally - if (alignH || (forceAlign && localX + localWidth > right)) { - // use align flags - if ((align & SWT.LEFT) != 0) { - cx = localX; - } else if ((align & SWT.RIGHT) != 0) { - cx = right - localWidth; - } else { // center - cx = localX + (localWidth - getVisibleWidth()) / 2; - } - } - // compute alignment on visible area vertically - if (alignV || (forceAlign && localY + localHeight > bottom)) { - // use align flags - if ((align & SWT.TOP) != 0) { - cy = localY; - } else if ((align & SWT.BOTTOM) != 0) { - cy = bottom - localHeight; - } else { // center - cy = localY + (localHeight - getVisibleHeight()) / 2; - } - } - setContentsPos(cx, cy); - } - - /** - * Returns true if point is visible (expressed in contents coordinates). - * - * @param px Point's x position - * @param py Point's y position - * @return true if point is visible (expressed in contents coordinates) - */ - public boolean isVisible(int px, int py) { - if (px < getContentsX()) { - return false; - } - if (py < getContentsY()) { - return false; - } - if (px > (getContentsX() + getVisibleWidth())) { - return false; - } - if (py > (getContentsY() + getVisibleHeight())) { - return false; - } - return true; - } - - /** - * Returns true if rectangle if partially visible. - * - * @param xValue x contents coordinates of rectangle. - * @param yValue y contents coordinates of rectangle. - * @param width width of rectangle. - * @param height height of rectangle. - * @return true if rectangle if partially visible. - */ - public boolean isVisible(int xValue, int yValue, int width, int height) { - if (xValue + width < getContentsX()) { - return false; - } - if (yValue + height < getContentsY()) { - return false; - } - int vr = getContentsX() + getVisibleWidth(); - int vb = getContentsY() + getVisibleHeight(); - if (xValue > vr) { - return false; - } - if (yValue > vb) { - return false; - } - return true; - } - - /** - * Returns visible part of rectangle, or null if rectangle is not visible. - * Rectangle is expressed in contents coordinates. - * - * @param xValue - * x contents coordinates of rectangle. - * @param yValue - * y contents coordinates of rectangle. - * @param width - * width of rectangle. - * @param height - * height of rectangle. - * @return visible part of rectangle, or null if rectangle is not visible. - */ - public Rectangle getVisiblePart(int xValue, int yValue, int width, int height) { - if (xValue + width < getContentsX()) { - return null; - } - if (yValue + height < getContentsY()) { - return null; - } - int vr = getContentsX() + getVisibleWidth(); - int vb = getContentsY() + getVisibleHeight(); - if (xValue > vr) { - return null; - } - if (yValue > vb) { - return null; - } - int rr = xValue + width, rb = yValue + height; - int nl = Math.max(xValue, getContentsX()), nt = Math.max(yValue, getContentsY()), nr = Math.min(rr, vr), nb = Math.min(rb, vb); - return new Rectangle(nl, nt, nr - nl, nb - nt); - } - - /** - * Returns the visible part for given rectangle. - * - * @param rect A rectangle - * - * @return gets visible part of rectangle (or null) - */ - public final Rectangle getVisiblePart(Rectangle rect) { - if (rect == null) { - return null; - } - return getVisiblePart(rect.x, rect.y, rect.width, rect.height); - } - - /** - * Change top left position of visible area. Check if the given point is inside contents area. - * - * @param xValue x contents coordinates of visible area. - * @param yValue y contents coordinates of visible area. - * @return true if view really moves - */ - public boolean setContentsPos(int xValue, int yValue) { - int nx = xValue, ny = yValue; - if (getVisibleWidth() >= getContentsWidth()) { - nx = 0; - } else { - if (xValue < 0) { - nx = 0; - } else if (xValue + getVisibleWidth() > getContentsWidth()) { - nx = getContentsWidth() - getVisibleWidth(); - } - } - if (getVisibleHeight() >= getContentsHeight()) { - ny = 0; - } else { - if (yValue <= 0) { - ny = 0; - } else if (yValue + getVisibleHeight() > getContentsHeight()) { - ny = getContentsHeight() - getVisibleHeight(); - } - } - // no move - if (nx == fContentsX && ny == fContentsY) { - return false; - } - fContentsX = nx; - fContentsY = ny; - updateScrollBarsValues(); - // ? find smallest area to redraw only them ? - fViewControl.redraw(); - return true; - } - - @Override - public ScrollBar getVerticalBar() { - return fVertScrollBar.getVerticalBar(); - } - - @Override - public ScrollBar getHorizontalBar() { - return fHorScrollBar.getHorizontalBar(); - } - - /** - * Compute visibility of vertical/horizontal bar using given width/height and current visibility (i.e. is bar size are already in - * for_xxx) - * @param forWidth width of foreground - * @param forHeight height of foreground - * @param currHorVis The current visibility state of horizontal scroll bar - * @param currVertvis The current visibility state of vertical scroll bar - * @return true if visibility changed else false - */ - public int computeBarVisibility(int forWidth, int forHeight, boolean currHorVis, boolean currVertvis) { - - int localForWidth = forWidth; - int vis = 0x00; - switch (fVertScrollbarMode) { - case ALWAYS_OFF: - break; - case ALWAYS_ON: - vis |= VBAR; - break; - case AUTO: - if (getContentsHeight() > forHeight) { - vis = VBAR; - // v bar size is already in for_width. - if (!currVertvis) {// (curr_vis&0x01)==0) - localForWidth -= getVerticalBarWidth(); - } - } - break; - default: - break; - } - - switch (fHorScrollbarMode) { - case ALWAYS_OFF: - break; - case ALWAYS_ON: - vis |= HBAR; - break; - case AUTO: - if (getContentsWidth() > localForWidth) { - vis |= HBAR; - // h bar is not in for_height - if ((!currHorVis) && (getContentsHeight() > (forHeight - getHorizontalBarHeight()))) {// (curr_vis&0x02)==0 ) - vis |= VBAR; - } - } - break; - default: - break; - } - return vis; - } - - /** - * Setup scroll bars visibility. - * - * @return True if one of visibility changed. - */ - protected boolean updateScrollBarVisiblity() { - boolean change = false; - - boolean currVertVis = fVertScrollBar.getVisible(); - boolean currHorVis = fHorScrollBar.getVisible(); - int barNewVis = computeBarVisibility(getVisibleWidth(), getVisibleHeight(), currHorVis, currVertVis); - boolean newVertVis = (barNewVis & VBAR) != 0; - boolean newHorVis = (barNewVis & HBAR) != 0; - if (currVertVis ^ newVertVis) { // vertsb_.getVisible() ) - fVertScrollBar.setVisible(newVertVis); - change = true; - } - if (currHorVis ^ newHorVis) { - fHorScrollBar.setVisible(newHorVis); - change = true; - } - - // update corner control visibility: - if (fCornerControl != null && change) { - boolean vis = newVertVis || newHorVis; - if (vis ^ fCornerControl.getVisible()) { - fCornerControl.setVisible(vis); - change = true; // but must be already the case - } - } - return change; - } - - /** - * Setup scroll bar using contents, visible and scroll bar mode properties. - */ - protected void updateScrollBarsValues() { - /* update vertical scrollbar */ - ScrollBar b = getVerticalBar(); - if (b != null) { - b.setMinimum(0); - b.setMaximum(getContentsHeight()); - b.setThumb(getVisibleHeight()); - b.setPageIncrement(getVisibleHeight()); - b.setIncrement(fVertScrollbarIncrement); - b.setSelection(getContentsY()); - } - - // update "hidden" vertical bar too - b = fViewControl.getVerticalBar(); - if (b != null) { - b.setMinimum(0); - b.setMaximum(getContentsHeight()); - b.setThumb(getVisibleHeight()); - b.setPageIncrement(getVisibleHeight()); - b.setIncrement(fVertScrollbarIncrement); - b.setSelection(getContentsY()); - } - - /* update horizontal scrollbar */ - b = getHorizontalBar(); - if (b != null) { - b.setMinimum(0); - b.setMaximum(getContentsWidth()); - b.setThumb(getVisibleWidth()); - b.setSelection(getContentsX()); - b.setPageIncrement(getVisibleWidth()); - b.setIncrement(fHorScrollbarIncrement); - } - // update "hidden" horizontal bar too - b = fViewControl.getHorizontalBar(); - if (b != null) { - b.setMinimum(0); - b.setMaximum(getContentsWidth()); - b.setThumb(getVisibleWidth()); - b.setSelection(getContentsX()); - b.setPageIncrement(getVisibleWidth()); - b.setIncrement(fHorScrollbarIncrement); - } - } - - /** - * Change the control used in the bottom right corner (between two scrollbar), if control is null reset previous - * corner control. This control is visible only if at least one scrollbar is visible. Given control will be disposed - * by ScrollView, at dispose() time, at next setCornetControl() call or when calling setOverviewEnabled(). Pay - * attention calling this reset overview feature until setOverviewEnabled(true) if called. - * @param control The control for the overview - */ - public void setCornerControl(Control control) { - if (fCornerControl != null) { - fCornerControl.dispose(); - } - fCornerControl = control; - if (fCornerControl != null) { - ScrollBar vb = getVerticalBar(); - ScrollBar hb = getHorizontalBar(); - boolean vis = vb.getVisible() || hb.getVisible(); - fCornerControl.setVisible(vis); - } - } - - /** - * Transform (x,y) point in widget coordinates to contents coordinates. - * - * @param x The x widget coordinate. - * @param y The y widget coordinate. - * @return org.eclipse.swt.graphics.Point with content coordinates. - */ - public final Point viewToContents(int x, int y) { - return new Point(viewToContentsX(x), viewToContentsY(y)); - } - - /** - * Transform x in widget coordinates to contents coordinates - * - * @param x The y widget coordinate. - * @return the x content coordinate. - */ - public int viewToContentsX(int x) { - return fContentsX + x; - } - - /** - * Transform y in widget coordinates to contents coordinates - * - * @param y The y widget coordinate. - * @return the y content coordinate. - */ - public int viewToContentsY(int y) { - return fContentsY + y; - } - - /** - * Transform (x,y) point from contents coordinates, to widget coordinates. - * - * @param x The x content coordinate. - * @param y The y content coordinate. - * @return coordinates widget area as. - */ - public final Point contentsToView(int x, int y) { - return new Point(contentsToViewX(x), contentsToViewY(y)); - } - - /** - * Transform X axis coordinates from contents to widgets. - * - * @param x contents coordinate to transform. - * @return x coordinate in widget area - */ - public int contentsToViewX(int x) { - return x - fContentsX; - } - - /** - * Transform Y axis coordinates from contents to widgets. - * - * @param y contents coordinate to transform - * @return y coordinate in widget area - */ - public int contentsToViewY(int y) { - return y - fContentsY; - } - - /** - * Return the visible height of scroll view, might be > contentsHeight - * - * @return the visible height of scroll view, might be > contentsHeight() - */ - public int getVisibleHeight() { - return fViewControl.getClientArea().height; - } - - /** - * Return int the visible width of scroll view, might be > contentsWidth(). - * - * @return int the visible width of scroll view, might be > contentsWidth() - */ - public int getVisibleWidth() { - return fViewControl.getClientArea().width; - } - - /** - * Add support for arrow key, scroll the ... scroll view. But you can - * redefine this method for your convenience. - * - * @param event - * Keyboard event - */ - protected void keyPressedEvent(KeyEvent event) { - switch (event.keyCode) { - case SWT.ARROW_UP: - scrollBy(0, -getVisibleHeight()); - break; - case SWT.ARROW_DOWN: - scrollBy(0, +getVisibleHeight()); - break; - case SWT.ARROW_LEFT: - scrollBy(-getVisibleWidth(), 0); - break; - case SWT.ARROW_RIGHT: - scrollBy(+getVisibleWidth(), 0); - break; - default: - break; - } - } - - /** - * Redefine this method at your convenience - * - * @param event The key event. - */ - protected void keyReleasedEvent(KeyEvent event) { - } - - /** - * Returns vertical bar width, even if bar isn't visible. - * - * @return vertical bar width, even if bar isn't visible - */ - public int getVerticalBarWidth() { - // include vertical bar width and trimming of scrollable used - int bw = fVertScrollBar.computeTrim(0, 0, 0, 0).width; - return bw + 1; - } - - /** - * Returns horizontal bar height even if bar isn't visible. - * - * @return horizontal bar height even if bar isn't visible - */ - public int getHorizontalBarHeight() { - // include horiz. bar height and trimming of scrollable used - int bh = fHorScrollBar.computeTrim(0, 0, 0, 0).height; - // +1 because win32 H.bar need 1 pixel canvas size to appear ! (strange no ?) - return bh + 1; - } - - @Override - public Rectangle computeTrim(int x, int y, int w, int h) { - Rectangle r = new Rectangle(x, y, w, h); - int barVis = computeBarVisibility(w, h, false, false); - if ((barVis & VBAR) != 0) { - r.width += getVerticalBarWidth(); - } - if ((barVis & HBAR) != 0) { - r.height += getHorizontalBarHeight(); - } - return r; - } - - /** - * Internal layout for ScrollView, handle scrollbars, drawzone and corner control - */ - protected class SVLayout extends Layout { - - private static final int DEFAULT_X = 250; - private static final int DEFAULT_Y = 250; - private static final int MAX_SEEK = 10; - private static final int MIN_SEEK = 0; - - /** - * The seek value - */ - private int seek = 0; - /** - * The do-it-not flag - */ - private boolean dontLayout = false; - - @Override - protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { - Point p = new Point(DEFAULT_X, DEFAULT_Y); - if (fContentsWidth < p.x) { - p.x = fContentsWidth; - } - if (fContentsHeight < p.y) { - p.y = fContentsHeight; - } - return p; - } - - @Override - protected void layout(Composite composite, boolean flushCache) { - if (dontLayout) { - return; - } - seek++; - if (seek > MAX_SEEK) { - dontLayout = true; - } - - Point cs = composite.getSize(); - int barVis = computeBarVisibility(cs.x, cs.y, false, false); - boolean vbVis = (barVis & VBAR) != 0; - boolean hbVis = (barVis & HBAR) != 0; - fVertScrollBar.setVisible(vbVis); - fHorScrollBar.setVisible(hbVis); - int vbw = getVerticalBarWidth(); - int hbh = getHorizontalBarHeight(); - int wb = vbVis ? vbw : 0; - int hb = hbVis ? hbh : 0; - int cww = 0, cwh = 0; - - if (fCornerControl != null && (vbVis || hbVis)) { // corner_control_.getVisible()) - fCornerControl.setVisible(true); - cww = vbw; - cwh = hbh; - if (wb == 0) { - wb = vbw; - } - if (hb == 0) { - hb = hbh; - } - } else if (vbVis && hbVis) { - if (fCornerControl != null) { - fCornerControl.setVisible(false); - } - cww = vbw; - cwh = hbh; - } - if (vbVis || hbVis) { - updateScrollBarsValues(); - } - - int vw = cs.x - (vbVis ? vbw : 0); - int vh = cs.y - (hbVis ? hbh : 0); - int vbx = cs.x - wb; - int hby = cs.y - hb; - - fViewControl.setBounds(0, 0, vw, vh); - - if (vbVis) { - fVertScrollBar.setBounds(vbx, 0, wb, cs.y - cwh); - } - if (hbVis) { - fHorScrollBar.setBounds(0, hby, cs.x - cww, hb); - } - if (fCornerControl != null && fCornerControl.getVisible()) { - fCornerControl.setBounds(vbx, hby, vbw, hbh); - } - updateScrollBarsValues(); - - seek--; - if (seek == MIN_SEEK) { - dontLayout = false; - } - } - - boolean isDontLayout() { - return dontLayout; - } - - void setSontLayout(boolean dontLayout) { - this.dontLayout = dontLayout; - } - } - - // static must take place here... cursor is created once. - private volatile static Cursor fOverviewCursor; - - /** Support for click-and-see overview shell on this ScrollView */ - protected class Overview { - - private static final int REFRESH_FREQ = 4; - - /** - * factor for X from real and overview sizes, for mouse move speed. - */ - private float fOverviewFactorX; - - /** - * factor for Y from real and overview sizes, for mouse move speed. - */ - private float fOverviewFactorY; - /** - * shell use to show overview - */ - private Shell fOverview; - /** - * save mouse X cursor location for disappear(); - */ - private int fSaveCursorX; - /** - * save mouse Y cursor location for disappear(); - */ - private int fSaveCursorY; - - /** - * Apply overview support on a control. Replace existing corner_widget - * - * @param control - * The control to use - */ - public void useControl(Control control) { - final Point pos = control.getLocation(); - control.addMouseListener(new MouseListener() { - @Override - public void mouseDoubleClick(MouseEvent e) { - } - - @Override - public void mouseDown(MouseEvent e) { - overviewAppear(e.x, e.y); - } - - @Override - public void mouseUp(MouseEvent e) { - overviewDisappear(); - } - }); - - control.addFocusListener(new FocusListener() { - - @Override - public void focusGained(FocusEvent e) { - } - - @Override - public void focusLost(FocusEvent e) { - if (overviewing()) { - overviewDisappear(false); - } - } - - }); - control.addKeyListener(new KeyListener() { - - @Override - public void keyPressed(KeyEvent event) { - if (event.keyCode == 32 && !overviewing()) { - overviewAppear(pos.x, pos.y); - } else if (event.keyCode == 32) { - overviewDisappear(); - } - if (event.keyCode == SWT.ARROW_DOWN) { - overviewMove(0, 1, event); - } - - if (event.keyCode == SWT.ARROW_UP) { - overviewMove(0, -1, event); - } - - if (event.keyCode == SWT.ARROW_RIGHT) { - overviewMove(1, 0, event); - } - - if (event.keyCode == SWT.ARROW_LEFT) { - overviewMove(-1, 0, event); - } - } - - @Override - public void keyReleased(KeyEvent e) { - } - }); - control.addMouseMoveListener(new MouseMoveListener() { - private int refReshCount = 0; - @Override - public void mouseMove(MouseEvent event) { - if (overviewing()) { - // Slow down the refresh - if (refReshCount % REFRESH_FREQ == 0) { - overviewMove(event); - } - refReshCount++; - } - } - }); - } - - /** - * Dispose controls of overview - */ - public void dispose() { - if (fOverview != null) { - fOverview.dispose(); - } - } - - /** - * @return true if overview is currently on screen - */ - protected boolean overviewing() { - return (fOverview != null && fOverview.isVisible()); - } - - /** - * Process overview appear - * - * @param mx - * X coordinate - * @param my - * Y coordinate - */ - protected void overviewAppear(int mx, int my) { - if (fOverview == null) { - fOverview = new Shell(getShell(), SWT.ON_TOP | SWT.NO_BACKGROUND); - fOverview.addPaintListener(new PaintListener() { - @Override - public void paintControl(PaintEvent e) { - drawOverview(e.gc, fOverview.getClientArea()); - } - }); - } - // always the same.. - fOverview.setForeground(fViewControl.getForeground()); - - // get location of shell (in screeen coordinates) - Point p = toGlobalCoordinates(fCornerControl, 0, 0); - int x = p.x; - int y = p.y; - int w, h; - h = fOverviewSize; - w = h; - Rectangle scr = getDisplay().getBounds(); - Point ccs = fCornerControl.getSize(); - try { - if (fContentsWidth > fContentsHeight) { - float ratio = fContentsHeight / (float) fContentsWidth; - h = (int) (w * ratio); - if (h < ccs.y) { - h = ccs.y; - } else if (h >= scr.height / 2) { - h = scr.height / 2; - } - } else { - float ratio = fContentsWidth / (float) fContentsHeight; - w = (int) (h * ratio); - if (w < ccs.x) { - w = ccs.x; - } else if (w >= scr.width / 2) { - w = scr.width / 2; - } - } - fOverviewFactorX = fContentsWidth / (float) w; - fOverviewFactorY = fContentsHeight / (float) h; - } - // no contents size set ? - catch (java.lang.ArithmeticException e) { - } - - // try pop-up on button, extending to bottom right, - if (x <= 0) { - x = 1; - } - if (y <= 0) { - y = 1; - } - x = x - w + ccs.x; - y = y - h + ccs.y; - fOverview.setBounds(x, y, w, h); - fOverview.setVisible(true); - fOverview.redraw(); - // mouse cursor disappear, so set invisible mouse cursor ... - if (fOverviewCursor == null) { - RGB rgb[] = { new RGB(0, 0, 0), new RGB(255, 0, 0) }; - PaletteData palette = new PaletteData(rgb); - int s = 1; - byte src[] = new byte[s * s]; - byte msk[] = new byte[s * s]; - for (int i = 0; i < s * s; ++i) { - src[i] = (byte) 0xFF; - } - ImageData i_src = new ImageData(s, s, 1, palette, 1, src); - ImageData i_msk = new ImageData(s, s, 1, palette, 1, msk); - fOverviewCursor = new Cursor(null, i_src, i_msk, 0, 0); - } - fCornerControl.setCursor(fOverviewCursor); - // convert to global coordinates - p = toGlobalCoordinates(fCornerControl, mx, my); - fSaveCursorX = p.x; - fSaveCursorY = p.y; - - Rectangle r = fOverview.getClientArea(); - int cx = (int) (r.width * fContentsX / (float) fContentsWidth); - int cy = (int) (r.height * fContentsY / (float) fContentsHeight); - - // cx,cy to display's global coordinates - p = toGlobalCoordinates(fOverview.getParent(), cx, cy); - } - - /** - * Process disappear of overview - */ - protected void overviewDisappear() { - overviewDisappear(true); - } - - /** - * Process disappear of overview - * @param restoreCursorLoc A flag to restore cursor location - */ - protected void overviewDisappear(boolean restoreCursorLoc) { - if (fOverview == null) { - return; - } - fOverview.setVisible(false); - fCornerControl.setCursor(null); - if (restoreCursorLoc) { - getDisplay().setCursorLocation(fSaveCursorX, fSaveCursorY); - } - fOverview.dispose(); - fOverview = null; - } - - /** - * Process mouse move in overview - * @param event The mouse event - */ - protected void overviewMove(MouseEvent event) { - Point p = toGlobalCoordinates(fCornerControl, event.x, event.y); - int dx = p.x - fSaveCursorX; - int dy = p.y - fSaveCursorY; - overviewMove(dx, dy, event); - } - - /** - * Process mouse move event when overviewing - * - * @param dx The x coordinates delta - * @param dy The y coordinates delta - * @param event The typed event - */ - protected void overviewMove(int dx, int dy, TypedEvent event) { - boolean ctrl = false; - boolean shift = false; - - if (event instanceof MouseEvent) { - MouseEvent e = (MouseEvent) event; - getDisplay().setCursorLocation(fSaveCursorX, fSaveCursorY); - ctrl = (e.stateMask & SWT.CONTROL) != 0; - shift = (e.stateMask & SWT.SHIFT) != 0; - } else if (event instanceof KeyEvent) { - KeyEvent e = (KeyEvent) event; - ctrl = (e.stateMask & SWT.CONTROL) != 0; - shift = (e.stateMask & SWT.SHIFT) != 0; - } - - int cx = fContentsX; - int cy = fContentsY; - float fx = fOverviewFactorX; - float fy = fOverviewFactorY; - - if (ctrl && shift) { - if ((fx * 0.25f > 1) && (fy * 0.25 > 1)) { - fx = fy = 1.0f; - } else { - fx *= 0.1f; - fy *= 0.1f; - } - } else if (ctrl) { - fx *= 0.5f; - fy *= 0.5f; - } else if (shift) { - fx *= 0.5f; - fy *= 0.5f; - } - scrollBy((int) (fx * dx), (int) (fy * dy)); - if (cx != fContentsX || cy != fContentsY) { - fOverview.redraw(); - fOverview.update(); // draw now ! - } - } - - /** - * Convert overview coordinates to global coordinates. - * - * @param loc - * the control reference - * @param x - * The x coordinate to convert - * @param y - * The y coordinate to convert - * @return The new converted Point - */ - protected Point toGlobalCoordinates(Control loc, int x, int y) { - Point p = new Point(x, y); - for (Control c = loc; c != null; c = c.getParent()) { - // control might have client area with 'decorations' - int trimX = 0, trimY = 0; - // other kind of widget with trimming ?? - if (c instanceof Scrollable) { - Scrollable s = (Scrollable) c; - Rectangle rr = s.getClientArea(); - Rectangle tr = s.computeTrim(rr.x, rr.y, rr.width, rr.height); - trimX = rr.x - tr.x; - trimY = rr.y - tr.y; - } - p.x += c.getLocation().x + trimX; - p.y += c.getLocation().y + trimY; - } - return p; - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/TimeCompressionBar.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/TimeCompressionBar.java deleted file mode 100755 index 8a073ccb26..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/TimeCompressionBar.java +++ /dev/null @@ -1,1028 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.AsyncMessage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.AsyncMessageReturn; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.BaseMessage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.ExecutionOccurrence; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Frame; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.ITimeRange; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Metrics; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SDTimeEvent; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SyncMessage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.impl.ColorImpl; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.TimeEventComparator; -import org.eclipse.swt.SWT; -import org.eclipse.swt.accessibility.ACC; -import org.eclipse.swt.accessibility.Accessible; -import org.eclipse.swt.accessibility.AccessibleAdapter; -import org.eclipse.swt.accessibility.AccessibleControlAdapter; -import org.eclipse.swt.accessibility.AccessibleControlEvent; -import org.eclipse.swt.accessibility.AccessibleEvent; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.TraverseEvent; -import org.eclipse.swt.events.TraverseListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; - -/** - *

- * The time compression bar implementation. - *

- * - * @version 1.0 - * @author sveyrier - */ -public class TimeCompressionBar extends ScrollView implements DisposeListener { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - private static final int BASE_RED_VALUE = 255; - private static final int BASE_GREEN_BLUE_VALUE = 225; - private static final int COLOR_STEP = 25; - private static final int NUMBER_STEPS = 10; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The listener list - */ - private List fListenerList = null; - /** - * The current frame displayed. - */ - private Frame fFrame = null; - /** - * List of time events. - */ - private List fNodeList = null; - /** - * The minimum time delta. - */ - private ITmfTimestamp fMinTime = new TmfTimestamp(); - /** - * The maximum time delta. - */ - private ITmfTimestamp fMaxTime = new TmfTimestamp(); - /** - * The current zoom value. - */ - private float fZoomValue = 1; - /** - * The tooltip to display. - */ - private DrawableToolTip fTooltip = null; - /** - * Array of colors for displaying wight of time deltas. - */ - private ColorImpl[] fColors; - /** - * The accessible object reference. - */ - private Accessible fAccessible = null; - /** - * The focused widget reference. - */ - private int fFocusedWidget = -1; - /** - * The current lifeline. - */ - private Lifeline fLifeline = null; - /** - * The current start event value. - */ - private int fLifelineStart = 0; - /** - * The current number of events. - */ - private int fLifelineNumEvents = 0; - /** - * The Current color of range to display. - */ - private IColor fLifelineColor = null; - /** - * The next graph node y coordinate. - */ - private int fNextNodeY = 0; - /** - * The previous graph node y coordinate. - */ - private int fPrevNodeY = 0; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Standard constructor - * - * @param parent The parent composite - * @param s The style bits - */ - public TimeCompressionBar(Composite parent, int s) { - super(parent, s | SWT.NO_BACKGROUND, false); - setVScrollBarMode(ScrollView.ALWAYS_OFF); - setHScrollBarMode(ScrollView.ALWAYS_OFF); - fListenerList = new ArrayList<>(); - fColors = new ColorImpl[NUMBER_STEPS]; - int greenBlue = BASE_GREEN_BLUE_VALUE; - final int step = COLOR_STEP; - for (int i = 0; i < fColors.length; i++) { - fColors[i] = new ColorImpl(Display.getDefault(), BASE_RED_VALUE, greenBlue, greenBlue); - greenBlue -= step; - } - super.addDisposeListener(this); - - fAccessible = getViewControl().getAccessible(); - - fAccessible.addAccessibleListener(new AccessibleAdapter() { - @Override - public void getName(AccessibleEvent e) { - // Case toolTip - if (e.childID == 0) { - if (fTooltip != null) { - e.result = fTooltip.getAccessibleText(); - } - } else if (e.childID == 1) { - createFakeTooltip(); - e.result = fTooltip.getAccessibleText(); - } - } - }); - - fAccessible.addAccessibleControlListener(new AccessibleControlAdapter() { - @Override - public void getFocus(AccessibleControlEvent e) { - if (fFocusedWidget == -1) { - e.childID = ACC.CHILDID_SELF; - } - else { - e.childID = fFocusedWidget; - } - } - - @Override - public void getRole(AccessibleControlEvent e) { - switch (e.childID) { - case ACC.CHILDID_SELF: - e.detail = ACC.ROLE_CLIENT_AREA; - break; - case 0: - e.detail = ACC.ROLE_TOOLTIP; - break; - case 1: - e.detail = ACC.ROLE_LABEL; - break; - default: - break; - } - } - - @Override - public void getState(AccessibleControlEvent e) { - e.detail = ACC.STATE_FOCUSABLE; - if (e.childID == ACC.CHILDID_SELF) { - e.detail |= ACC.STATE_FOCUSED; - } else { - e.detail |= ACC.STATE_SELECTABLE; - if (e.childID == fFocusedWidget) { - e.detail |= ACC.STATE_FOCUSED | ACC.STATE_SELECTED | ACC.STATE_CHECKED; - } - } - } - }); - - getViewControl().addTraverseListener(new LocalTraverseListener()); - - addTraverseListener(new LocalTraverseListener()); - - getViewControl().addFocusListener(new FocusListener() { - @Override - public void focusGained(FocusEvent e) { - redraw(); - } - - @Override - public void focusLost(FocusEvent e) { - redraw(); - } - }); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - /** - * Sets the focus widget - * - * @param newFocusShape widget reference to set - */ - void setFocus(int newFocusShape) { - fFocusedWidget = newFocusShape; - if (fFocusedWidget == -1) { - getViewControl().getAccessible().setFocus(ACC.CHILDID_SELF); - } else { - getViewControl().getAccessible().setFocus(fFocusedWidget); - } - } - - /** - * Sets the current frame. - * - * @param theFrame The frame to set - */ - public void setFrame(Frame theFrame) { - fFrame = theFrame; - fMinTime = fFrame.getMinTime(); - fMaxTime = fFrame.getMaxTime(); - } - - @Override - protected void drawContents(GC gc, int clipx, int clipy, int clipw, int cliph) { - if (fFrame == null) { - return; - } - fNodeList = new ArrayList<>(); - int messageArraysStep = 1; - - if ((Metrics.getMessageFontHeigth() + Metrics.MESSAGES_NAME_SPACING * 2) * fZoomValue < Metrics.MESSAGE_SIGNIFICANT_VSPACING + 1) { - messageArraysStep = Math.round(Metrics.MESSAGE_SIGNIFICANT_VSPACING + 1 / ((Metrics.getMessageFontHeigth() + Metrics.MESSAGES_NAME_SPACING * 2) * fZoomValue)); - } - - int firstVisible = fFrame.getFirstVisibleSyncMessage(); - if (firstVisible > 0) { - firstVisible = firstVisible - 1; - } - for (int i = firstVisible; i < fFrame.syncMessageCount(); i = i + messageArraysStep) { - SyncMessage m = fFrame.getSyncMessage(i); - if (m.hasTimeInfo()) { - SDTimeEvent t = new SDTimeEvent(m.getStartTime(), m.getEventOccurrence(), m); - fNodeList.add(t); - if (m.getY() * fZoomValue > getContentsY() + getVisibleHeight()) { - break; - } - } - } - - firstVisible = fFrame.getFirstVisibleSyncMessageReturn(); - if (firstVisible > 0) { - firstVisible = firstVisible - 1; - } - for (int i = firstVisible; i < fFrame.syncMessageReturnCount(); i = i + messageArraysStep) { - SyncMessage m = fFrame.getSyncMessageReturn(i); - if (m.hasTimeInfo()) { - SDTimeEvent t = new SDTimeEvent(m.getStartTime(), m.getEventOccurrence(), m); - fNodeList.add(t); - if (m.getY() * fZoomValue > getContentsY() + getVisibleHeight()) { - break; - } - } - } - - firstVisible = fFrame.getFirstVisibleAsyncMessage(); - if (firstVisible > 0) { - firstVisible = firstVisible - 1; - } - for (int i = firstVisible; i < fFrame.asyncMessageCount(); i = i + messageArraysStep) { - AsyncMessage m = fFrame.getAsyncMessage(i); - if (m.hasTimeInfo()) { - SDTimeEvent t = new SDTimeEvent(m.getStartTime(), m.getStartOccurrence(), m); - fNodeList.add(t); - t = new SDTimeEvent(m.getEndTime(), m.getEndOccurrence(), m); - fNodeList.add(t); - if (m.getY() * fZoomValue > getContentsY() + getVisibleHeight()) { - break; - } - } - } - - firstVisible = fFrame.getFirstVisibleAsyncMessageReturn(); - if (firstVisible > 0) { - firstVisible = firstVisible - 1; - } - for (int i = firstVisible; i < fFrame.asyncMessageReturnCount(); i = i + messageArraysStep) { - AsyncMessageReturn m = fFrame.getAsyncMessageReturn(i); - if (m.hasTimeInfo()) { - SDTimeEvent t = new SDTimeEvent(m.getStartTime(), m.getStartOccurrence(), m); - fNodeList.add(t); - t = new SDTimeEvent(m.getEndTime(), m.getEndOccurrence(), m); - fNodeList.add(t); - if (m.getY() * fZoomValue > getContentsY() + getVisibleHeight()) { - break; - } - } - } - - List executionOccurrencesWithTime = fFrame.getExecutionOccurrencesWithTime(); - if (executionOccurrencesWithTime != null) { - fNodeList.addAll(executionOccurrencesWithTime); - } - - SDTimeEvent[] temp = fNodeList.toArray(new SDTimeEvent[fNodeList.size()]); - Arrays.sort(temp, new TimeEventComparator()); - fNodeList = Arrays.asList(temp); - - Image dbuffer = new Image(getDisplay(), getClientArea().width, getClientArea().height); - GC gcim = new GC(dbuffer); - - for (int i = 0; i < fNodeList.size() - 1; i++) { - SDTimeEvent m1 = fNodeList.get(i); - SDTimeEvent m2 = fNodeList.get(i + 1); - - if ((SDViewPref.getInstance().excludeExternalTime()) && ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage))) { - BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); - BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); - if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) { - continue; - } - } - - fMinTime = fFrame.getMinTime(); - fMaxTime = fFrame.getMaxTime(); - ITmfTimestamp minMaxdelta = fMaxTime.getDelta(fMinTime); - double gr = (minMaxdelta.getValue()) / (double) NUMBER_STEPS; - - ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime()).getDelta(fMinTime); - long absDelta = Math.abs(delta.getValue()); - - ColorImpl color; - if (gr != 0) { - int colIndex = Math.round((float) (absDelta / gr)); - if (colIndex < fColors.length && colIndex > 0) { - color = fColors[colIndex - 1]; - } else if (colIndex <= 0) { - color = fColors[0]; - } else { - color = fColors[fColors.length - 1]; - } - } else { - color = fColors[0]; - } - - if (color.getColor() instanceof Color) { - gcim.setBackground((Color) color.getColor()); - } - int y1 = ((GraphNode) m1.getGraphNode()).getY(); - int y2 = ((GraphNode) m2.getGraphNode()).getY(); - if (m1.getGraphNode() instanceof AsyncMessage) { - AsyncMessage as = (AsyncMessage) m1.getGraphNode(); - if (as.getEndTime() == m1.getTime()) { - y1 += as.getHeight(); - } - } - if (m2.getGraphNode() instanceof AsyncMessage) { - AsyncMessage as = (AsyncMessage) m2.getGraphNode(); - if (as.getEndTime() == m2.getTime()) { - y2 += as.getHeight(); - } - } - if (m1.getGraphNode() instanceof ExecutionOccurrence) { - - ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); - if (m1.getEvent() == eo.getEndOccurrence()) { - y1 += eo.getHeight(); - } - - if (m2.getGraphNode() instanceof ExecutionOccurrence) { - - ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); - if (m2.getEvent() == eo2.getEndOccurrence()) { - y2 += eo2.getHeight(); - } - - } - } - gcim.fillRectangle(contentsToViewX(0), contentsToViewY(Math.round(y1 * fZoomValue)), 10, Math.round((y2 - y1) * fZoomValue) + 1); - if (messageArraysStep == 1) { - Color backupColor = gcim.getForeground(); - gcim.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); - gcim.drawRectangle(contentsToViewX(0), contentsToViewY(Math.round(y1 * fZoomValue)), 9, Math.round((y2 - y1) * fZoomValue)); - gcim.setForeground(backupColor); - } - } - if (getViewControl().isFocusControl() || isFocusControl()) { - gcim.drawFocus(contentsToViewX(0), contentsToViewY(Math.round(fPrevNodeY * fZoomValue)), contentsToViewX(10), Math.round((fNextNodeY - fPrevNodeY) * fZoomValue)); - } - try { - gc.drawImage(dbuffer, 0, 0, getClientArea().width, getClientArea().height, 0, 0, getClientArea().width, getClientArea().height); - } catch (Exception e) { - Activator.getDefault().logError("Error drawing image", e); //$NON-NLS-1$ - } - gcim.dispose(); - dbuffer.dispose(); - gc.dispose(); - } - - /** - * Checks for focus of children. - * - * @param children - * Control to check - * @return true if child is on focus else false - */ - protected boolean checkFocusOnChilds(Control children) { - if (children instanceof Composite) { - Control[] child = ((Composite) children).getChildren(); - for (int i = 0; i < child.length; i++) { - if (child[i].isFocusControl()) { - return true; - } - checkFocusOnChilds(child[i]); - } - } - return false; - } - - @Override - public boolean isFocusControl() { - Control[] child = getChildren(); - for (int i = 0; i < child.length; i++) { - if (child[i].isFocusControl()) { - return true; - } - checkFocusOnChilds(child[i]); - } - return false; - } - - @Override - protected void contentsMouseMoveEvent(MouseEvent event) { - if (fTooltip != null) { - fTooltip.hideToolTip(); - } - super.contentsMouseMoveEvent(event); - if (!isFocusControl() || getViewControl().isFocusControl()) { - Control[] child = getParent().getChildren(); - for (int i = 0; i < child.length; i++) { - if (child[i].isFocusControl()) { - break; - } - } - } - setFocus(-1); - } - - @Override - protected void contentsMouseHover(MouseEvent e) { - if (fTooltip == null) { - fTooltip = new DrawableToolTip(this); - } - if (fFrame != null) { - setFocus(0); - for (int i = 0; i < fNodeList.size() - 1; i++) { - SDTimeEvent m1 = fNodeList.get(i); - SDTimeEvent m2 = fNodeList.get(i + 1); - - if ((SDViewPref.getInstance().excludeExternalTime()) && ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage))) { - BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); - BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); - if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) { - continue; - } - } - - int y1 = ((GraphNode) m1.getGraphNode()).getY(); - int y2 = ((GraphNode) m2.getGraphNode()).getY(); - - if (m1.getGraphNode() instanceof AsyncMessage) { - AsyncMessage as = (AsyncMessage) m1.getGraphNode(); - if (as.getEndTime() == m1.getTime()) { - y1 += as.getHeight(); - } - } - if (m2.getGraphNode() instanceof AsyncMessage) { - AsyncMessage as = (AsyncMessage) m2.getGraphNode(); - if (as.getEndTime() == m2.getTime()) { - y2 += as.getHeight(); - } - } - if (m1.getGraphNode() instanceof ExecutionOccurrence) { - ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); - if (m1.getEvent() == eo.getEndOccurrence()) { - y1 += eo.getHeight(); - } - - if (m2.getGraphNode() instanceof ExecutionOccurrence) { - - ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); - if (m2.getEvent() == eo2.getEndOccurrence()) { - y2 += eo2.getHeight(); - } - } - } - int m1Y = Math.round(y1 * fZoomValue); - int m2Y = Math.round(y2 * fZoomValue); - if ((m1Y < e.y) && (m2Y >= e.y)) { - ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime()); - fTooltip.showToolTip(delta, fMinTime, fMaxTime); - } - } - } - setFocus(0); - } - - @Override - protected void contentsMouseExit(MouseEvent e) { - if (fTooltip != null) { - fTooltip.hideToolTip(); - } - } - - @Override - protected void contentsMouseUpEvent(MouseEvent event) { - selectTimeDelta(event.y, 0); - setFocus(); - super.contentsMouseUpEvent(event); - } - - /** - * Force the time compression bar to highlight the event occurrences between - * the two given messages. The event occurrences are highlighted on the - * first message's end lifeline - * - * @param mes1 - * the first message - * @param mes2 - * the second message - */ - public void highlightRegion(BaseMessage mes1, BaseMessage mes2) { - BaseMessage localMes1 = mes1; - BaseMessage localMes2 = mes2; - - if (fFrame == null) { - return; - } - if (!(localMes1 instanceof ITimeRange)) { - return; - } - if (!(localMes2 instanceof ITimeRange)) { - return; - } - ITimeRange t1 = (ITimeRange) localMes1; - ITimeRange t2 = (ITimeRange) localMes2; - - ITmfTimestamp time1 = t1.getStartTime(); - ITmfTimestamp time2 = t2.getStartTime(); - int event1 = localMes1.getEventOccurrence(); - int event2 = localMes2.getEventOccurrence(); - - if (localMes1 instanceof AsyncMessage) { - AsyncMessage as = (AsyncMessage) localMes1; - time1 = as.getEndTime(); - event1 = as.getEndOccurrence(); - } - if (localMes2 instanceof AsyncMessage) { - AsyncMessage as = (AsyncMessage) localMes2; - if (as.getEndOccurrence() > as.getStartOccurrence()) { - time1 = as.getEndTime(); - event1 = as.getEndOccurrence(); - } else { - time1 = as.getStartTime(); - event1 = as.getStartOccurrence(); - } - } - - if (event1 > event2) { - BaseMessage tempMes = localMes2; - localMes2 = localMes1; - localMes1 = tempMes; - - t1 = (ITimeRange) localMes1; - t2 = (ITimeRange) localMes2; - - time1 = t1.getStartTime(); - time2 = t2.getStartTime(); - event1 = localMes1.getEventOccurrence(); - event2 = localMes2.getEventOccurrence(); - - if (localMes1 instanceof AsyncMessage) { - AsyncMessage as = (AsyncMessage) localMes1; - time1 = as.getEndTime(); - event1 = as.getEndOccurrence(); - } - if (localMes2 instanceof AsyncMessage) { - AsyncMessage as = (AsyncMessage) localMes2; - if (as.getEndOccurrence() > as.getStartOccurrence()) { - time1 = as.getEndTime(); - event1 = as.getEndOccurrence(); - } else { - time1 = as.getStartTime(); - event1 = as.getStartOccurrence(); - } - } - } - - ITmfTimestamp minMaxdelta = fMaxTime.getDelta(fMinTime); - double gr = (minMaxdelta.getValue()) / (double) NUMBER_STEPS; - - ITmfTimestamp delta = time2.getDelta(time1).getDelta(fMinTime); - long absDelta = Math.abs(delta.getValue()); - - int colIndex = 0; - if (gr != 0) { - colIndex = Math.round((float) (absDelta / gr)); - if (colIndex >= fColors.length) { - colIndex = fColors.length - 1; - } else if (colIndex < 0) { - colIndex = 0; - } - } else { - colIndex = 0; - } - for (int j = 0; j < fListenerList.size(); j++) { - ITimeCompressionListener list = fListenerList.get(j); - if (localMes1.getEndLifeline() != null) { - list.deltaSelected(localMes1.getEndLifeline(), event1, event2 - event1, fColors[colIndex]); - } else if (localMes2.getStartLifeline() != null) { - list.deltaSelected(localMes2.getStartLifeline(), event1, event2 - event1, fColors[colIndex]); - } else { - list.deltaSelected(localMes1.getStartLifeline(), event1, event2 - event1, fColors[colIndex]); - } - } - } - - /** - * Force the time compression bar to highlight the event occurrences between the two given messages. The event - * occurrences are highlighted on the first message's end lifeline - * - * @param mes1 the first message - * @param mes2 the second message - */ - public void highlightRegionSync(final BaseMessage mes1, final BaseMessage mes2) { - getDisplay().syncExec(new Runnable() { - @Override - public void run() { - highlightRegion(mes1, mes2); - } - }); - } - - @Override - public void scrollBy(int x, int y) { - } - - /** - * Sets the zoom value. - * - * @param value The zoom value to set. - */ - public void setZoom(float value) { - fZoomValue = value; - redraw(); - } - - /** - * Adds a listener to the time compression listener list to be notified about selected deltas. - * - * @param listener The listener to add - */ - public void addTimeCompressionListener(ITimeCompressionListener listener) { - if (!fListenerList.contains(listener)) { - fListenerList.add(listener); - } - } - - /** - * Removes a time compression listener. - * - * @param listener The listener to remove. - */ - public void removeSelectionChangedListener(ITimeCompressionListener listener) { - fListenerList.remove(listener); - } - - @Override - public void widgetDisposed(DisposeEvent e) { - if (fTooltip != null) { - fTooltip.dispose(); - } - super.removeDisposeListener(this); - for (int i = 0; i < fColors.length; i++) { - fColors[i].dispose(); - } - } - - @Override - protected void keyPressedEvent(KeyEvent event) { - if (fTooltip != null) { - fTooltip.hideToolTip(); - } - if (!isFocusControl() || getViewControl().isFocusControl()) { - Control[] child = getParent().getChildren(); - for (int i = 0; i < child.length; i++) { - if (child[i].isFocusControl()) { - break; - } - } - } - setFocus(-1); - - boolean top = false; - if (fNextNodeY == 0) { - top = true; - } - if ((fFrame != null) && (fNextNodeY == 0)) { - for (int i = 0; i < fNodeList.size() - 1 && i < 1; i++) { - SDTimeEvent m1 = fNodeList.get(i); - SDTimeEvent m2 = fNodeList.get(i + 1); - if ((SDViewPref.getInstance().excludeExternalTime()) && ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage))) { - BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); - BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); - if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) { - continue; - } - } - - int y1 = ((GraphNode) m1.getGraphNode()).getY(); - int y2 = ((GraphNode) m2.getGraphNode()).getY(); - if (m1.getGraphNode() instanceof AsyncMessage) { - AsyncMessage as = (AsyncMessage) m1.getGraphNode(); - if (as.getEndTime() == m1.getTime()) { - y1 += as.getHeight(); - } - } - if (m2.getGraphNode() instanceof AsyncMessage) { - AsyncMessage as = (AsyncMessage) m2.getGraphNode(); - if (as.getEndTime() == m2.getTime()) { - y2 += as.getHeight(); - } - } - if (m1.getGraphNode() instanceof ExecutionOccurrence) { - ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); - if (m1.getEvent() == eo.getEndOccurrence()) { - y1 += eo.getHeight(); - } - - if (m2.getGraphNode() instanceof ExecutionOccurrence) { - - ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); - if (m2.getEvent() == eo2.getEndOccurrence()) { - y2 += eo2.getHeight(); - } - } - } - fPrevNodeY = Math.round(y1 * fZoomValue); - fNextNodeY = Math.round(y2 * fZoomValue); - } - } - - if (fLifeline != null) { - for (int j = 0; j < fListenerList.size(); j++) { - ITimeCompressionListener list = fListenerList.get(j); - list.deltaSelected(fLifeline, fLifelineStart, fLifelineNumEvents, fLifelineColor); - } - } - - if (event.keyCode == SWT.ARROW_DOWN) { - if (!top) { - selectTimeDelta(fNextNodeY + 1, 1); - } else { - selectTimeDelta(fPrevNodeY + 1, 1); - } - setFocus(1); - } else if (event.keyCode == SWT.ARROW_UP) { - selectTimeDelta(fPrevNodeY - 1, 2); - setFocus(1); - } else if (event.keyCode == SWT.ARROW_RIGHT) { - selectTimeDelta(fPrevNodeY, 1); - setFocus(1); - } - super.keyPressedEvent(event); - } - - /** - * Selects the time delta for given delta y coordinate and direction. - * - * @param dy The delta in y coordinate. - * @param direction 0 no direction, 1 = down, 2 = up - */ - protected void selectTimeDelta(int dy, int direction) { - SDTimeEvent lastM1 = null; - SDTimeEvent lastM2 = null; - int lastY1 = 0; - int lastY2 = 0; - boolean done = false; - if (fFrame != null) { - for (int i = 0; i < fNodeList.size() - 1; i++) { - SDTimeEvent m1 = fNodeList.get(i); - SDTimeEvent m2 = fNodeList.get(i + 1); - if ((SDViewPref.getInstance().excludeExternalTime()) && ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage))) { - BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); - BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); - if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) { - continue; - } - } - - int y1 = ((GraphNode) m1.getGraphNode()).getY(); - int y2 = ((GraphNode) m2.getGraphNode()).getY(); - if (m1.getGraphNode() instanceof AsyncMessage) { - AsyncMessage as = (AsyncMessage) m1.getGraphNode(); - if (as.getEndTime() == m1.getTime()) { - y1 += as.getHeight(); - } - } - if (m2.getGraphNode() instanceof AsyncMessage) { - AsyncMessage as = (AsyncMessage) m2.getGraphNode(); - if (as.getEndTime() == m2.getTime()) { - y2 += as.getHeight(); - } - } - if (m1.getGraphNode() instanceof ExecutionOccurrence) { - ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); - if (m1.getEvent() == eo.getEndOccurrence()) { - y1 += eo.getHeight(); - } - - if (m2.getGraphNode() instanceof ExecutionOccurrence) { - ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); - if (m2.getEvent() == eo2.getEndOccurrence()) { - y2 += eo2.getHeight(); - } - } - } - int m1Y = Math.round(y1 * fZoomValue); - int m2Y = Math.round(y2 * fZoomValue); - - if ((m1Y < dy) && (m2Y > dy) || (!done && m2Y > dy && direction == 1 && lastM1 != null) || (!done && m1Y > dy && direction == 2 && lastM1 != null)) { - if (m1Y > dy && direction == 2) { - m1 = lastM1; - m2 = lastM2; - m1Y = lastY1; - m2Y = lastY2; - } - done = true; - fPrevNodeY = m1Y; - fNextNodeY = m2Y; - ITmfTimestamp minMaxdelta = fMaxTime.getDelta(fMinTime); - double gr = (minMaxdelta.getValue()) / (double) NUMBER_STEPS; - - ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime()).getDelta(fMinTime); - long absDelta = Math.abs(delta.getValue()); - - int colIndex = 0; - if (gr != 0) { - colIndex = Math.round((float) (absDelta / gr)); - if (colIndex >= fColors.length) { - colIndex = fColors.length - 1; - } else if (colIndex < 0) { - colIndex = 0; - } - } else { - colIndex = 0; - } - if (m1.getGraphNode() instanceof BaseMessage) { - BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); - if (mes1.getEndLifeline() != null) { - fLifeline = mes1.getEndLifeline(); - fLifelineStart = m1.getEvent(); - fLifelineNumEvents = m2.getEvent() - m1.getEvent(); - fLifelineColor = fColors[colIndex]; - } else if (m2.getGraphNode() instanceof BaseMessage && ((BaseMessage) m2.getGraphNode()).getStartLifeline() != null) { - fLifeline = ((BaseMessage) m2.getGraphNode()).getStartLifeline(); - fLifelineStart = m1.getEvent(); - fLifelineNumEvents = m2.getEvent() - m1.getEvent(); - fLifelineColor = fColors[colIndex]; - } else { - fLifeline = mes1.getStartLifeline(); - fLifelineStart = m1.getEvent(); - fLifelineNumEvents = m2.getEvent() - m1.getEvent(); - fLifelineColor = fColors[colIndex]; - } - } else if (m1.getGraphNode() instanceof ExecutionOccurrence) { - if (m2.getGraphNode() instanceof ExecutionOccurrence) { - ExecutionOccurrence eo = (ExecutionOccurrence) m2.getGraphNode(); - fLifeline = eo.getLifeline(); - fLifelineStart = m1.getEvent(); - fLifelineNumEvents = m2.getEvent() - m1.getEvent(); - fLifelineColor = fColors[colIndex]; - } else { - ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); - fLifeline = eo.getLifeline(); - fLifelineStart = m1.getEvent(); - fLifelineNumEvents = m2.getEvent() - m1.getEvent(); - fLifelineColor = fColors[colIndex]; - } - } - for (int j = 0; j < fListenerList.size(); j++) { - ITimeCompressionListener list = fListenerList.get(j); - list.deltaSelected(fLifeline, fLifelineStart, fLifelineNumEvents, fLifelineColor); - } - break; - } - lastM1 = m1; - lastM2 = m2; - lastY1 = m1Y; - lastY2 = m2Y; - } - } - } - - /** - * Creates a fake tool tip. - */ - protected void createFakeTooltip() { - if (fTooltip == null) { - fTooltip = new DrawableToolTip(this); - } - - if (fFrame != null) { - setFocus(0); - for (int i = 0; i < fNodeList.size() - 1; i++) { - SDTimeEvent m1 = fNodeList.get(i); - SDTimeEvent m2 = fNodeList.get(i + 1); - - if ((SDViewPref.getInstance().excludeExternalTime()) && ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage))) { - BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); - BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); - if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) { - continue; - } - } - - int y1 = ((GraphNode) m1.getGraphNode()).getY(); - int y2 = ((GraphNode) m2.getGraphNode()).getY(); - - if (m1.getGraphNode() instanceof AsyncMessage) { - AsyncMessage as = (AsyncMessage) m1.getGraphNode(); - if (as.getEndTime() == m1.getTime()) { - y1 += as.getHeight(); - } - } - if (m2.getGraphNode() instanceof AsyncMessage) { - AsyncMessage as = (AsyncMessage) m2.getGraphNode(); - if (as.getEndTime() == m2.getTime()) { - y2 += as.getHeight(); - } - } - if (m1.getGraphNode() instanceof ExecutionOccurrence) { - ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); - if (m1.getEvent() == eo.getEndOccurrence()) { - y1 += eo.getHeight(); - } - - if (m2.getGraphNode() instanceof ExecutionOccurrence) { - - ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); - if (m2.getEvent() == eo2.getEndOccurrence()) { - y2 += eo2.getHeight(); - } - } - } - int m1Y = Math.round(y1 * fZoomValue); - int m2Y = Math.round(y2 * fZoomValue); - if ((m1Y < fPrevNodeY + 1) && (m2Y >= fPrevNodeY + 1)) { - ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime()); - fTooltip.showToolTip(delta, fMinTime, fMaxTime); - fTooltip.hideToolTip(); - } - } - } - } - - /** - * Traverse Listener implementation. - */ - protected static class LocalTraverseListener implements TraverseListener { - @Override - public void keyTraversed(TraverseEvent e) { - if ((e.detail == SWT.TRAVERSE_TAB_NEXT) || (e.detail == SWT.TRAVERSE_TAB_PREVIOUS)) { - e.doit = true; - } - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/AsyncMessage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/AsyncMessage.java deleted file mode 100755 index 31867f8be4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/AsyncMessage.java +++ /dev/null @@ -1,469 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; - -import java.util.Comparator; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.ISDPreferences; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.SortAsyncForBackward; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.SortAsyncMessageComparator; - -/** - * A AsyncMessage is a asynchronous message which appear at two different event occurrences on each lifeline ends (sender - * and receiver).
- *
- *
- * Usage example: - * - *
- * Frame frame;
- * Lifeline lifeLine1;
- * Lifeline lifeLine2;
- *
- * AsyncMessage message = new AsyncMessage();
- * // Create a new event occurrence on each lifeline
- * lifeline1.getNewOccurrenceIndex();
- * lifeline2.getNewOccurrenceIndex();
- * // Set the message sender and receiver
- * message.setStartLifeline(lifeLine1);
- * message.setEndLifline(lifeline2);
- * message.setName("Message label");
- * // add the message to the frame
- * frame.addMessage(message);
- * 
- * - * @see Lifeline Lifeline for more event occurence details - * @version 1.0 - * @author sveyrier - * @since 2.0 - */ -public class AsyncMessage extends BaseMessage implements ITimeRange { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The grahNode ID constant - */ - public static final String ASYNC_MESS_TAG = "AsyncMessage"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * Flag whether message has time information or not. - */ - private boolean fHasTime = false; - /** - * The time when the message begin - */ - private ITmfTimestamp fEndTime = new TmfTimestamp(); - /** - * The time when the message end - */ - private ITmfTimestamp fStartTime = new TmfTimestamp(); - /** - * The associated message. - */ - protected AsyncMessageReturn fMessageReturn = null; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor - */ - public AsyncMessage() { - setColorPrefId(ISDPreferences.PREF_ASYNC_MESS); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public int getX() { - int x = super.getX(true); - int activationWidth = Metrics.EXECUTION_OCCURRENCE_WIDTH / 2; - if ((getStartLifeline() != null) && (getEndLifeline() != null) && (getStartLifeline().getX() > getEndLifeline().getX())) { - activationWidth = -activationWidth; - } - - if (isMessageStartInActivation(getStartOccurrence())) { - x = x + activationWidth; - } - return x; - } - - @Override - public int getY() { - if ((getStartLifeline() != null) && (getEndLifeline() != null)) { - return getEndLifeline().getY() + getEndLifeline().getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * getStartOccurrence(); - } - return super.getY(); - } - - @Override - public int getWidth() { - int width = super.getWidth(true); - int activationWidth = Metrics.EXECUTION_OCCURRENCE_WIDTH / 2; - if ((getStartLifeline() != null) && (getEndLifeline() != null) && (getStartLifeline().getX() > getEndLifeline().getX())) { - activationWidth = -activationWidth; - } - - if (isMessageStartInActivation(getStartOccurrence())) { - width = width - activationWidth; - } - - if (isMessageEndInActivation(getEndOccurrence())) { - width = width - activationWidth; - } - - return width; - } - - @Override - public int getHeight() { - if ((getStartLifeline() != null) && (getEndLifeline() != null)) { - return (getEndLifeline().getY() + getEndLifeline().getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * getEndOccurrence()) - getY(); - } - return super.getHeight(); - } - - /** - * Set the message return associated with this message. - * - * @param message the message return to associate - */ - protected void setMessageReturn(AsyncMessageReturn message) { - fMessageReturn = message; - } - - /** - * Set the event occurrence attached to this message for its end lifeline - * - * @param occurrence the event occurrence to set - */ - @Override - public void setEndOccurrence(int occurrence) { - super.setEndOccurrence(occurrence); - if (getStartLifeline() == null) { - setStartOccurrence(occurrence); - } - informFrame(getEndLifeline(), occurrence); - } - - /** - * Informs the given lifeline about the maximum occurrence if applicable. - * - * @param lifeLine - * Concerned lifeline - * @param occurrence - * Occurrence number - */ - protected void informFrame(Lifeline lifeLine, int occurrence) { - if ((lifeLine != null) && (lifeLine.getFrame() != null) && (lifeLine.getFrame().getMaxEventOccurrence() < occurrence)) { - lifeLine.getFrame().setMaxEventOccurrence(occurrence); - } - } - - /** - * Set the event occurrence attached to this message for its start lifeline - * - * @param occurrence the event occurrence to set - */ - @Override - public void setStartOccurrence(int occurrence) { - super.setStartOccurrence(occurrence); - if (getEndLifeline() == null) { - setEndOccurrence(getStartOccurrence()); - } - informFrame(getStartLifeline(), occurrence); - } - - /** - * Set the lifeLine which has sent the message.
- * A new EventOccurence will be create on this lifeLine.
- * - * @param lifeline the message sender - */ - public void autoSetStartLifeline(Lifeline lifeline) { - lifeline.getNewEventOccurrence(); - setStartLifeline(lifeline); - } - - /** - * Set the lifeLine which has received the message.
- * A new EventOccurence will be create on this lifeLine.
- * - * @param lifeline the message receiver - */ - public void autoSetEndLifeline(Lifeline lifeline) { - lifeline.getNewEventOccurrence(); - setEndLifeline(lifeline); - } - - @Override - public void setStartLifeline(Lifeline lifeline) { - super.setStartLifeline(lifeline); - setStartOccurrence(getStartLifeline().getEventOccurrence()); - if (getEndLifeline() == null) { - setEndOccurrence(getStartOccurrence()); - } - } - - @Override - public void setEndLifeline(Lifeline lifeline) { - super.setEndLifeline(lifeline); - setEventOccurrence(getEndLifeline().getEventOccurrence()); - } - - /** - * Returns true if the point C is on the segment defined with the point A and B - * - * @param xA point A x coordinate - * @param yA point A y coordinate - * @param xB point B x coordinate - * @param yB point B y coordinate - * @param xC point C x coordinate - * @param yC point C y coordinate - * @return Return true if the point C is on the segment defined with the point A and B, else otherwise - */ - protected boolean isNearSegment(int xA, int yA, int xB, int yB, int xC, int yC) { - if ((xA > xB) && (xC > xA)) { - return false; - } - if ((xA < xB) && (xC > xB)) { - return false; - } - if ((xA < xB) && (xC < xA)) { - return false; - } - if ((xA > xB) && (xC < xB)) { - return false; - } - double distAB = Math.sqrt((xB - xA) * (xB - xA) + (yB - yA) * (yB - yA)); - double scalar = ((xB - xA) * (xC - xA) + (yB - yA) * (yC - yA)) / distAB; - double distAC = Math.sqrt((xC - xA) * (xC - xA) + (yC - yA) * (yC - yA)); - double distToSegment = Math.sqrt(Math.abs(distAC * distAC - scalar * scalar)); - if (distToSegment <= Metrics.MESSAGE_SELECTION_TOLERANCE) { - return true; - } - return false; - } - - @Override - public boolean contains(int x, int y) { - // Is it a self message? - if (getStartLifeline() == getEndLifeline()) { - return super.contains(x, y); - } - if (isNearSegment(getX(), getY(), getX() + getWidth(), getY() + getHeight(), x, y)) { - return true; - } - int messageMaxWidth = Metrics.swimmingLaneWidth() - Metrics.EXECUTION_OCCURRENCE_WIDTH; - int nameWidth = getName().length() * Metrics.getAverageCharWidth(); - if (getName().length() * Metrics.getAverageCharWidth() > messageMaxWidth) { - if (GraphNode.contains(getX(), getY() - Metrics.MESSAGES_NAME_SPACING - Metrics.getMessageFontHeigth(), messageMaxWidth, Metrics.getMessageFontHeigth(), x, y)) { - return true; - } - } else { - if (GraphNode.contains(getX() + (messageMaxWidth - nameWidth) / 2, getY() + getHeight() / 2 - Metrics.MESSAGES_NAME_SPACING - Metrics.getMessageFontHeigth(), nameWidth, Metrics.getMessageFontHeigth(), x, y)) { - return true; - } - } - return false; - } - - /** - * Draws the asynchronous message using giving graphical context. - * - * @param context A graphical context to draw in. - */ - protected void drawAsyncMessage(IGC context) { - if (getStartLifeline() != null && getEndLifeline() != null && getStartLifeline() == getEndLifeline() && (getStartOccurrence() != getEndOccurrence())) { - int x = getX(); - int y = getY(); - int height = getHeight(); - int tempx = 0; - boolean startInActivation = isMessageStartInActivation(getStartOccurrence()); - boolean endInActivation = isMessageEndInActivation(getEndOccurrence()); - - if (endInActivation && !startInActivation) { - tempx = Metrics.EXECUTION_OCCURRENCE_WIDTH / 2; - } - if (startInActivation && !endInActivation) { - tempx = -Metrics.EXECUTION_OCCURRENCE_WIDTH / 2; - } - - int tempy = Metrics.INTERNAL_MESSAGE_WIDTH / 2; - if (getHeight() <= Metrics.INTERNAL_MESSAGE_WIDTH) { - tempy = getHeight() / 2; - } - - context.drawLine(x, y, x + Metrics.INTERNAL_MESSAGE_WIDTH / 2, y); - context.drawLine(x + Metrics.INTERNAL_MESSAGE_WIDTH, y + tempy, x + Metrics.INTERNAL_MESSAGE_WIDTH, y + height - tempy); - context.drawLine(x + tempx, y + height, x + Metrics.INTERNAL_MESSAGE_WIDTH / 2, y + height); - - Double xt = Double.valueOf(Math.cos(0.75) * 7); - Double yt = Double.valueOf(Math.sin(0.75) * 7); - - context.drawLine(x + xt.intValue() + tempx, y + height + yt.intValue(), x + tempx, y + height); - context.drawArc(x, y, Metrics.INTERNAL_MESSAGE_WIDTH, 2 * tempy, 0, 90); - context.drawArc(x, y + height, Metrics.INTERNAL_MESSAGE_WIDTH, -2 * tempy, 0, -90); - context.drawLine(x + xt.intValue() + tempx, y + height - yt.intValue(), x + tempx, y + height); - - context.drawTextTruncated(getName(), x + Metrics.INTERNAL_MESSAGE_WIDTH + Metrics.INTERNAL_MESSAGE_V_MARGIN, y, Metrics.swimmingLaneWidth() - Metrics.EXECUTION_OCCURRENCE_WIDTH + -Metrics.INTERNAL_MESSAGE_WIDTH, - +Metrics.MESSAGES_NAME_SPACING - Metrics.getMessageFontHeigth(), !isSelected()); - } else { - super.draw(context); - } - } - - @Override - public void draw(IGC context) { - if (!isVisible()) { - return; - } - - ISDPreferences pref = SDViewPref.getInstance(); - - // Draw it selected? - if (isSelected() && (getStartLifeline() != null && getEndLifeline() != null && getStartLifeline() == getEndLifeline() && (getStartOccurrence() != getEndOccurrence()))) { - /* - * Draw it twice First time, bigger inverting selection colors Second time, regular drawing using selection - * colors This create the highlight effect - */ - context.setForeground(pref.getBackGroundColorSelection()); - context.setLineWidth(Metrics.SELECTION_LINE_WIDTH); - drawAsyncMessage(context); - context.setBackground(pref.getBackGroundColorSelection()); - context.setForeground(pref.getForeGroundColorSelection()); - // Second drawing is done after the else - } else { - context.setBackground(pref.getBackGroundColor(getColorPrefId())); - context.setForeground(pref.getForeGroundColor(getColorPrefId())); - } - if (hasFocus()) { - context.setDrawTextWithFocusStyle(true); - } - context.setLineWidth(Metrics.NORMAL_LINE_WIDTH); - drawAsyncMessage(context); - if (hasFocus()) { - context.setDrawTextWithFocusStyle(false); - } - } - - /** - * Set the time when the message end - * - * @param time the time when the message end - * @since 2.0 - */ - public void setEndTime(ITmfTimestamp time) { - fEndTime = time; - fHasTime = true; - if (getStartLifeline() != null && getStartLifeline().getFrame() != null) { - getStartLifeline().getFrame().setHasTimeInfo(true); - } else if (getEndLifeline() != null && getEndLifeline().getFrame() != null) { - getEndLifeline().getFrame().setHasTimeInfo(true); - } - } - - /** - * Set the time when the message start - * - * @param time the time when the message start - * @since 2.0 - */ - public void setStartTime(ITmfTimestamp time) { - fStartTime = time; - fHasTime = true; - if (getStartLifeline() != null && getStartLifeline().getFrame() != null) { - getStartLifeline().getFrame().setHasTimeInfo(true); - } else if (getEndLifeline() != null && getEndLifeline().getFrame() != null) { - getEndLifeline().getFrame().setHasTimeInfo(true); - } - } - - /** - * @since 2.0 - */ - @Override - public ITmfTimestamp getEndTime() { - return fEndTime; - } - - /** - * @since 2.0 - */ - @Override - public ITmfTimestamp getStartTime() { - return fStartTime; - } - - @Override - public boolean hasTimeInfo() { - return fHasTime; - } - - /** - * @return message return instance or null - * @since 2.0 - */ - public AsyncMessageReturn getMessageReturn() { - return fMessageReturn; - } - - @Override - public boolean isVisible(int x, int y, int width, int height) { - int toDrawY = getY(); - int toDrawHeight = getHeight(); - if ((toDrawY > y + height + Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth()) && (toDrawY + toDrawHeight > y + height + Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth())) { - return false; - } - if (toDrawY < y && (toDrawY + toDrawHeight < y)) { - return false; - } - return super.isVisible(x, y, width, height); - } - - @Override - public Comparator getComparator() { - return new SortAsyncMessageComparator(); - } - - @Override - public String getArrayId() { - return ASYNC_MESS_TAG; - } - - @Override - public Comparator getBackComparator() { - return new SortAsyncForBackward(); - } - - @Override - public boolean positiveDistanceToPoint(int x, int y) { - int mY = getY(); - int mH = getHeight(); - if ((mY > y) || (mY + mH > y)) { - return true; - } - return false; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/AsyncMessageReturn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/AsyncMessageReturn.java deleted file mode 100755 index e1589b9275..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/AsyncMessageReturn.java +++ /dev/null @@ -1,112 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.ISDPreferences; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; - -/** - * The message return graph node implementation.
- * This class differs on the AsynMessage class only on the drawing line style (dashed instead of plain line).
- * Message return are generally associated to a message. This means, they are connected to the same lifelines than the - * associated message but in the opposite direction and for a different event occurrence.
- *
- * WARNING: The association validity is not checked, it is not necessary to provide a valid association, not even needed - * to set an association to drawn a message with a message return style.
- * - * - * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.AsyncMessage AsyncMessage for usage example - * @version 1.0 - * @author sveyrier - * - */ -public class AsyncMessageReturn extends AsyncMessage { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The grahNode ID constant - */ - public static final String ASYNC_MESS_RET_TAG = "AsyncMessageRet"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The corresponding asynchronous message. - */ - protected AsyncMessage fMessage; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor. - */ - public AsyncMessageReturn() { - setColorPrefId(ISDPreferences.PREF_ASYNC_MESS_RET); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - /** - * Set the associated message (the message it is the return).
- * Setting the association will activate the navigation in the default sequence diagram implementation to the - * message when the user right click on this message return.
- * - * @param parentMessage the message to associate - */ - public void setMessage(AsyncMessage parentMessage) { - fMessage = parentMessage; - } - - /** - * Returns the associated message (the message it is the return).
- * - * @return parentMessage the message to associate - * @since 2.0 - */ - public AsyncMessage getMessage() { - return fMessage; - } - - @Override - public void draw(IGC context) { - if (!isVisible()) { - return; - } - - ISDPreferences pref = SDViewPref.getInstance(); - - setColorPrefId(ISDPreferences.PREF_ASYNC_MESS_RET); - int oldStyle = context.getLineStyle(); - // Message return are dashed - context.setLineStyle(context.getLineDotStyle()); - if (!isSelected()) { - context.setBackground(pref.getBackGroundColor(getColorPrefId())); - context.setForeground(pref.getForeGroundColor(getColorPrefId())); - } - super.draw(context); - // restore the context - context.setLineStyle(oldStyle); - } - - @Override - public String getArrayId() { - return ASYNC_MESS_RET_TAG; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/BaseMessage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/BaseMessage.java deleted file mode 100755 index b35340b6ce..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/BaseMessage.java +++ /dev/null @@ -1,724 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.ISDPreferences; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; - -/** - * The base UML2 syncMessages implementation.
- * This abstract class only define one event occurrence to attach to the message.
- * Usually a message has two event occurrences attached, one for both ends. But some syncMessages(like synchronous - * syncMessages) only need one event occurrence to represent the time when they appear. Others kind of message - * representations (like asynchronous syncMessages) will be responsible to define the missing second eventOccurrence - * property.
- *
- * - * @see Lifeline Lifeline for more event occurence details - * @version 1.0 - * @author sveyrier - */ -public abstract class BaseMessage extends GraphNode { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The lifeline which send the message - */ - private Lifeline fStartLifeline = null; - /** - * The lifeline which receive the message - */ - private Lifeline fEndLifeline = null; - /** - * The visiblitiy flag. - */ - private boolean fVisible = true; - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public int getX() { - // returns the exact x coordinate - return getX(false); - } - - @Override - public int getY() { - /* - * Note: lifeline.getY() return the y coordinate of the top left corner of the rectangle which contain the - * lifeline name getHeight return the height of this rectangle The message y coordinate is then relative to this - * position depending of its eventOccurrence Space between syncMessages is constant - */ - if ((fStartLifeline != null) && (fEndLifeline != null)) { - /* - * Regular message, both ends are attached to a lifeline - */ - return fEndLifeline.getY() + fEndLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * getEndOccurrence(); - - } - /* - * UML2 lost message kind - */ - if (fStartLifeline != null) { - return fStartLifeline.getY() + fStartLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * getEndOccurrence(); - } - - /* - * UML2 found message kind - */ - if (fEndLifeline != null) { - return fEndLifeline.getY() + fEndLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * getEndOccurrence(); - } - // return 0 by default - return 0; - } - - @Override - public int getWidth() { - // Returns the exact width - return getWidth(false); - } - - @Override - public int getHeight() { - return 0; - } - - /** - * Returns the graph node x coordinate.
- * Depending on the quick parameter a approximative or exact value is return.
- * The approximative value does not take into account if both message ends are connected to a Lifeline Execution - * Occurrence.
- * Execution occurrence on a lifeline increase the vertical line width which represent the lifeline, this directly - * affect the message x coordinate and width.
- *
- * This method is typically used to faster execute none graphical operation like tooltip lookup.
- *
- * - * @param quick true to get an approximative value
- * false to get the exact x value
- * @return the graph node x coordinate - */ - protected int getX(boolean quick) { - int x = 0; - int activationWidth = Metrics.EXECUTION_OCCURRENCE_WIDTH / 2; - if ((fStartLifeline != null) && (fEndLifeline != null)) { - x = fStartLifeline.getX() + Metrics.getLifelineWidth() / 2; - } else { - if (fStartLifeline != null) { - x = fStartLifeline.getX() + Metrics.getLifelineWidth() / 2; - } - - if (fEndLifeline != null) { - x = fEndLifeline.getX() - Metrics.LIFELINE_SPACING / 2; - } - } - - if (quick) { - return x; - } - - if ((fStartLifeline != null) && (fEndLifeline != null) && (fStartLifeline.getX() > fEndLifeline.getX())) { - activationWidth = -activationWidth; - } - - if (isMessageStartInActivation(getEndOccurrence())) { - x = x + activationWidth; - } - - return x; - } - - /** - * Returns the graph node width.
- * Depending on the quick parameter a approximative or exact value is returned.
- * The approximative value does not take into account if both message ends are connected to a Lifeline Execution - * Occurrence.
- * Execution occurrence on a lifeline increase the vertical line width which represent the lifeline, this directly - * affect the message x coordinate and width.
- *
- * This method is typically used to faster execute none graphical operation like tooltip lookup.
- *
- * - * @param quick true to get an approximative value
- * false to get the exact x value - * @return the graph node width - */ - protected int getWidth(boolean quick) { - int width = 0; - int activationWidth = Metrics.EXECUTION_OCCURRENCE_WIDTH / 2; - if ((fStartLifeline != null) && (fEndLifeline != null)) { - if (fStartLifeline == fEndLifeline) { - width = Metrics.INTERNAL_MESSAGE_WIDTH + Metrics.EXECUTION_OCCURRENCE_WIDTH; - } else { - width = fEndLifeline.getX() + Metrics.getLifelineWidth() / 2 - getX(true); - } - } else { - if (fStartLifeline != null) { - width = Metrics.swimmingLaneWidth() / 2; - } - if (fEndLifeline != null) { - width = Metrics.swimmingLaneWidth() / 2; - } - } - - if (quick) { - return width; - } - - if ((fStartLifeline != null) && (fEndLifeline != null) && (fStartLifeline.getX() > fEndLifeline.getX())) { - activationWidth = -activationWidth; - } - - if (isMessageStartInActivation(getEndOccurrence())) { - width = width - activationWidth; - } - - if (isMessageEndInActivation(getEndOccurrence())) { - width = width - activationWidth; - } - - return width; - } - - @Override - public boolean isVisible(int x, int y, int width, int height) { - // ***Common*** syncMessages visibility - // draw the message only if at least one end is visible - if (fEndLifeline != null && (fEndLifeline.isVisible(x, y, width, height)) || (fStartLifeline != null && fStartLifeline.isVisible(x, y, width, height))) { - return true; - } - // In this case it can be a message which cross the whole visible area - else if (fEndLifeline != null && (!fEndLifeline.isVisible(x, y, width, height)) && (fStartLifeline != null && !fStartLifeline.isVisible(x, y, width, height))) { - if (fEndLifeline.getX() > x + width && fStartLifeline.getX() < x) { - return true; - } else if (fStartLifeline.getX() > x + width && fEndLifeline.getX() < x) { - return true; - } - } - return false; - } - - /** - * Sets the visibility value. - * - * @param value The visibility to set. - */ - public void setVisible(boolean value) { - fVisible = value; - } - - /** - * @return the visibility value. - */ - public boolean isVisible() { - return fVisible; - } - - /** - * Set the lifeline from which this message has been sent. - * - * @param lifeline - the message sender - */ - public void setStartLifeline(Lifeline lifeline) { - fStartLifeline = lifeline; - } - - /** - * Returns the lifeline from which this message has been sent. - * - * @return the message sender - */ - public Lifeline getStartLifeline() { - return fStartLifeline; - } - - /** - * Returns the lifeline which has received this message. - * - * @return the message receiver - */ - public Lifeline getEndLifeline() { - return fEndLifeline; - } - - /** - * Set the lifeline which has receive this message. - * - * @param lifeline the message receiver - */ - public void setEndLifeline(Lifeline lifeline) { - fEndLifeline = lifeline; - } - - /** - * Set the event occurrence when this message occurs.
- * - * @param occurrence the event occurrence to assign to this message.
- * @see Lifeline Lifeline for more event occurence details - */ - protected void setEventOccurrence(int occurrence) { - setEndOccurrence(occurrence); - } - - /** - * Returns the event occurence when is message occurs.
- * - * @return the event occurrence assigned to this message.
- * @see Lifeline Lifeline for more event occurence details - */ - public int getEventOccurrence() { - return getEndOccurrence(); - } - - /** - * Determines if the given eventOccurence occurs on a executionOccurence owned by the sending lifeline.
- * WARNING: this method will return a valid result only for execution occurrences which are visible in the View.
- * As consequence this method is only used for drawing purpose, especially to determine the exact message x - * coordinate and width.
- * - * @see BaseMessage#getX(boolean) - * @param event the event occurrence to test - * @return true if occurs on a execution occurrence owned by the sending lifeine, false otherwise - */ - protected boolean isMessageStartInActivation(int event) { - boolean inActivation = false; - if ((fStartLifeline != null) && (fStartLifeline.getExecutions() != null)) { - // int acIndex=startLifeline.getExecOccurrenceDrawIndex(); - // acIndex = first visible execution occurrence - // for drawing speed reason with only search on the visivle subset - int thisY = getY(); - for (int i = 0; i < fStartLifeline.getExecutions().size(); i++) { - BasicExecutionOccurrence toDraw = (BasicExecutionOccurrence) fStartLifeline.getExecutions().get(i); - if ((event >= toDraw.getStartOccurrence()) && (event <= toDraw.getEndOccurrence())) { - inActivation = true; - } - // if we are outside the visible area we stop right now - // This works because execution occurrences are ordered along the Y axis - if (toDraw.getY() > thisY) { - break; - } - } - } - return inActivation; - } - - /** - * Determines if the given event occurrence occurs on a execution occurrence owned by the receiving lifeline.
- * WARNING: this method will return a valid result only for execution occurrences which are visible in the View.
- * As consequence this method is only used for drawing purpose, especially to determine the exact message x - * coordinate and width.
- * - * @see BaseMessage#getX(boolean) - * @param event the event occurrence to test - * @return true if occurs on a execution occurrence owned by the receiving lifeline, false otherwise - */ - protected boolean isMessageEndInActivation(int event) { - boolean inActivation = false; - if ((fEndLifeline != null) && (fEndLifeline.getExecutions() != null)) { - // acIndex = first visible execution occurrence - // for drawing speed reason with only search on the visivle subset - for (int i = 0; i < fEndLifeline.getExecutions().size(); i++) { - BasicExecutionOccurrence toDraw = (BasicExecutionOccurrence) fEndLifeline.getExecutions().get(i); - if ((event >= toDraw.getStartOccurrence()) && (event <= toDraw.getEndOccurrence())) { - inActivation = true; - } - // if we are outside the visible area we stop right now - // This works because execution occurrences are ordered along the Y axis - if (toDraw.getY() > getY()) { - break; - } - } - } - return inActivation; - } - - @Override - public boolean contains(int xValue, int yValue) { - int x = getX(); - int y = getY(); - int width = getWidth(); - int height = getHeight(); - - // Used to create a rectangle which contains the message label to allow selection when clicking the label - int tempHeight = Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth(); - - // Is it a self message? - if (fStartLifeline == fEndLifeline) { - /* - * Rectangle.contains(x,y, width, height) does not works with negative height or width We check here if the - * rectangle width is negative. - */ - if (getName().length() * Metrics.getAverageCharWidth() > Metrics.swimmingLaneWidth() - Metrics.EXECUTION_OCCURRENCE_WIDTH / 2 + -Metrics.INTERNAL_MESSAGE_WIDTH) { - if (GraphNode.contains(x + Metrics.INTERNAL_MESSAGE_WIDTH + 10, y, Metrics.swimmingLaneWidth() - Metrics.EXECUTION_OCCURRENCE_WIDTH / 2 + -Metrics.INTERNAL_MESSAGE_WIDTH, Metrics.getMessageFontHeigth(), xValue, yValue)) { - return true; - } - } else { - if (GraphNode.contains(x + Metrics.INTERNAL_MESSAGE_WIDTH + 10, y, getName().length() * Metrics.getAverageCharWidth(), Metrics.getMessageFontHeigth(), xValue, yValue)) { - return true; - } - } - - // Test if the point is in part 1 of the self message - // see: "private void drawMessage (NGC context)" method for self message drawing schema - if (GraphNode.contains(x, y - Metrics.MESSAGE_SELECTION_TOLERANCE / 2, Metrics.INTERNAL_MESSAGE_WIDTH / 2, Metrics.MESSAGE_SELECTION_TOLERANCE, xValue, yValue)) { - return true; - } - - // Test if the point is in part 3 of the self message - if (GraphNode.contains(x + Metrics.INTERNAL_MESSAGE_WIDTH - Metrics.MESSAGE_SELECTION_TOLERANCE / 2, y, Metrics.MESSAGE_SELECTION_TOLERANCE, height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT, xValue, yValue)) { - return true; - } - - // Test if the point is in part 5 of the self message - if (GraphNode.contains(x, y + height - Metrics.MESSAGE_SELECTION_TOLERANCE / 2 + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT, Metrics.INTERNAL_MESSAGE_WIDTH / 2, Metrics.MESSAGE_SELECTION_TOLERANCE, xValue, yValue)) { - return true; - } - - // false otherwise - return false; - } - if (GraphNode.contains(x, y - tempHeight, width, tempHeight, xValue, yValue)) { - return true; - } - // false otherwise - return false; - } - - /** - * Method to draw the message using the graphical context. - * - * @param context A graphical context to draw in. - */ - protected void drawMessage(IGC context) { - int fX = 0; - int fY = 0; - int fW = 0; - int fH = 0; - - // temporary store the coordinates to avoid more methods calls - int x = getX(); - int y = getY(); - int width = getWidth(); - int height = getHeight(); - - ISDPreferences pref = SDViewPref.getInstance(); - - // UML2 found message (always drawn from left to right) - // or UML2 lost message (always drawn from left to right) - if ((fStartLifeline == null || fEndLifeline == null) && fStartLifeline != fEndLifeline) { - // Draw the message label above the message and centered - // The label is truncated if it cannot fit between the two message end - // 2*Metrics.MESSAGES_NAME_SPACING = space above the label + space below the label - IColor temp = context.getForeground(); - context.setForeground(pref.getFontColor(getColorPrefId())); - context.drawTextTruncatedCentred(getName(), x, y - Metrics.getMessageFontHeigth() - 2 * Metrics.MESSAGES_NAME_SPACING, width, 2 * Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth(), !isSelected()); - context.setForeground(temp); - int margin = 0; - if (fEndLifeline == null) { - margin = Metrics.MESSAGE_CIRCLE_RAY; - } - - // Draw the message main line - context.drawLine(x, y, x + width, y + height); - // Draw the two little lines which make a arrow part of the message - Double xt = Double.valueOf(Math.cos(0.75) * 7); - Double yt = Double.valueOf(Math.sin(0.75) * 7); - if (context.getLineStyle() == context.getLineSolidStyle()) { - IColor backcolor = context.getBackground(); - context.setBackground(context.getForeground()); - int[] points = { x + width - margin, y + height, x + width - xt.intValue() - margin, y + height - yt.intValue(), x + width - xt.intValue() - margin, y + height + yt.intValue(), x + width - margin, y + height }; - context.fillPolygon(points); - context.drawPolygon(points); - context.setBackground(backcolor); - } else { - int currentStyle = context.getLineStyle(); - int currentWidth = context.getLineWidth(); - context.setLineWidth(currentWidth + 2); - context.setLineStyle(context.getLineSolidStyle()); - context.drawLine(x + width - xt.intValue() - margin, y + height - yt.intValue(), x + width - margin, y + height); - context.drawLine(x + width - xt.intValue() - margin, y + height + yt.intValue(), x + width - margin, y + height); - context.setLineStyle(currentStyle); - context.setLineWidth(currentWidth); - } - IColor storedColor = context.getBackground(); - context.setBackground(context.getForeground()); - - // Draw a circle at the message end (endLifeline side) - int ray = Metrics.MESSAGE_CIRCLE_RAY; - if (context.getLineWidth() != Metrics.NORMAL_LINE_WIDTH) { - ray = ray + Metrics.SELECTION_LINE_WIDTH - Metrics.NORMAL_LINE_WIDTH; - } - if (fStartLifeline == null) { - context.fillOval(x - ray, y - ray, ray * 2, ray * 2); - } else { - context.fillOval(x + width - ray, y + height - ray, ray * 2, ray * 2); - } - context.setBackground(storedColor); - context.setForeground(pref.getFontColor(getColorPrefId())); - fX = x; - fY = y - yt.intValue(); - fW = width; - fH = height + 2 * yt.intValue(); - } - // it is self message (always drawn at the left side of the owning lifeLifeline) - else if (fStartLifeline != null && fEndLifeline != null && fStartLifeline == fEndLifeline) { - /* - * Self syncMessages are drawn in 5 parts 1 -----------+ + 2 + | | | 3 | + 5 + 4 -----------+ - */ - int tempy = Metrics.INTERNAL_MESSAGE_WIDTH / 2; - if (Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT <= Metrics.INTERNAL_MESSAGE_WIDTH) { - tempy = Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT / 2; - } - - // Part 1 - context.drawLine(x, y, x + Metrics.INTERNAL_MESSAGE_WIDTH / 2, y); - // Part 3 - context.drawLine(x + Metrics.INTERNAL_MESSAGE_WIDTH, y + tempy, x + Metrics.INTERNAL_MESSAGE_WIDTH, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT - tempy); - // Part 5 - context.drawLine(x, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT, x + Metrics.INTERNAL_MESSAGE_WIDTH / 2, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT); - - Double xt = Double.valueOf(Math.cos(0.75) * 7); - Double yt = Double.valueOf(Math.sin(0.75) * 7); - - fX = x; - fY = y; - fW = Metrics.INTERNAL_MESSAGE_WIDTH; - fH = height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT; - - // Draw the two little lines which make a arrow part of the message - if (context.getLineStyle() == context.getLineSolidStyle()) { - IColor backcolor = context.getBackground(); - context.setBackground(context.getForeground()); - int[] points = { x, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT, x + xt.intValue(), y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT + yt.intValue(), x + xt.intValue(), - y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT - yt.intValue(), x, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT }; - context.fillPolygon(points); - context.drawPolygon(points); - context.setBackground(backcolor); - } else { - int currentStyle = context.getLineStyle(); - int currentWidth = context.getLineWidth(); - context.setLineWidth(currentWidth + 2); - context.setLineStyle(context.getLineSolidStyle()); - context.drawLine(x + xt.intValue(), y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT + yt.intValue(), x, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT); - context.drawLine(x + xt.intValue(), y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT - yt.intValue(), x, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT); - context.setLineStyle(currentStyle); - context.setLineWidth(currentWidth); - } - - // Part 2 - context.drawArc(x, y, Metrics.INTERNAL_MESSAGE_WIDTH, 2 * tempy, 0, 90); - // Part 4 - context.drawArc(x, y + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT, Metrics.INTERNAL_MESSAGE_WIDTH, -2 * tempy, 0, -90); - - // Draw the message label above the message and centered - // The label is truncated if it cannot fit between the two message end - // 2*Metrics.MESSAGES_NAME_SPACING = space above the label + space below the label - - // the space available for the text is sorter if are drawing internal message on the last lifeline - context.setForeground(pref.getFontColor(getColorPrefId())); - if (fStartLifeline.getIndex() == fStartLifeline.getFrame().getHorizontalIndex()) { - context.drawTextTruncated(getName(), x + width + Metrics.INTERNAL_MESSAGE_V_MARGIN / 2, y, Metrics.swimmingLaneWidth() / 2 - Metrics.EXECUTION_OCCURRENCE_WIDTH + -Metrics.INTERNAL_MESSAGE_WIDTH, +Metrics.MESSAGES_NAME_SPACING - - Metrics.getMessageFontHeigth(), !isSelected()); - } else { - context.drawTextTruncated(getName(), x + width + Metrics.INTERNAL_MESSAGE_V_MARGIN / 2, y, Metrics.swimmingLaneWidth() - Metrics.EXECUTION_OCCURRENCE_WIDTH + -Metrics.INTERNAL_MESSAGE_WIDTH, - +Metrics.MESSAGES_NAME_SPACING - Metrics.getMessageFontHeigth(), !isSelected()); - } - } - // it is regular message - else if (fStartLifeline != null && fEndLifeline != null) { - // Draw the message main line - context.drawLine(x, y, x + width, y + height); - - int spaceBTWStartEnd = fEndLifeline.getX() - fStartLifeline.getX(); - - double a = height; - double b = width; - double angle = Math.atan(a / b); - // Compute the coordinates of the two little lines which make the arrow part of the message - int sign = 1; - if (spaceBTWStartEnd < 0) { - sign = -1; - } - Double x1 = Double.valueOf(sign * Math.cos(angle - 0.75) * 7); - Double y1 = Double.valueOf(sign * Math.sin(angle - 0.75) * 7); - Double x2 = Double.valueOf(sign * Math.cos(angle + 0.75) * 7); - Double y2 = Double.valueOf(sign * Math.sin(angle + 0.75) * 7); - - fX = getX(); - fY = y + height - y2.intValue(); - fW = getWidth(); - fH = y2.intValue() - y1.intValue() + 1; - if (fW < 0) { - fW = -fW; - fX = fX - fW; - } - - if (fH < 0) { - fH = -fH; - fY = fY - fH; - } - - // Draw the two little lines which make a arrow part of the message - if (context.getLineStyle() == context.getLineSolidStyle()) { - IColor backcolor = context.getBackground(); - context.setBackground(context.getForeground()); - int[] points = { x + width - x1.intValue(), y + height - y1.intValue(), x + width, y + height, x + width - x2.intValue(), y + height - y2.intValue(), x + width - x1.intValue(), y + height - y1.intValue() }; - context.fillPolygon(points); - context.drawPolygon(points); - context.setBackground(backcolor); - } else { - int currentStyle = context.getLineStyle(); - int currentWidth = context.getLineWidth(); - context.setLineWidth(currentWidth + 2); - context.setLineStyle(context.getLineSolidStyle()); - context.drawLine(x + width - x1.intValue(), y + height - y1.intValue(), x + width, y + height); - context.drawLine(x + width - x2.intValue(), y + height - y2.intValue(), x + width, y + height); - context.setLineStyle(currentStyle); - context.setLineWidth(currentWidth); - } - - // Draw the message label above the message and centered - // The label is truncated if it cannot fit between the two message end - // 2*Metrics.MESSAGES_NAME_SPACING = space above the label + space below the label - context.setForeground(pref.getFontColor(getColorPrefId())); - if (spaceBTWStartEnd > 0) { - context.drawTextTruncatedCentred(getName(), x, y + height / 2 - (2 * Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth()), width, 2 * Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth(), !isSelected()); - } else { - context.drawTextTruncatedCentred(getName(), x + width, y + height / 2 - (2 * Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth()), -width, 2 * Metrics.MESSAGES_NAME_SPACING + +Metrics.getMessageFontHeigth(), !isSelected()); - } - } - } - - @Override - public void draw(IGC context) { - if (!isVisible()) { - return; - } - - // Draw it selected?*/ - if (isSelected()) { - ISDPreferences pref = SDViewPref.getInstance(); - /* - * Draw it twice First time, bigger inverting selection colors Second time, regular drawing using selection - * colors This create the highlight effect - */ - context.setForeground(pref.getBackGroundColorSelection()); - context.setLineWidth(Metrics.SELECTION_LINE_WIDTH); - drawMessage(context); - context.setBackground(pref.getBackGroundColorSelection()); - context.setForeground(pref.getForeGroundColorSelection()); - // Second drawing is done after - } - context.setLineWidth(Metrics.NORMAL_LINE_WIDTH); - if (hasFocus()) { - context.setDrawTextWithFocusStyle(true); - } - drawMessage(context); - int oldStyle = context.getLineStyle(); - if (hasFocus()) { - context.setDrawTextWithFocusStyle(false); - drawFocus(context); - } - // restore the context - context.setLineStyle(oldStyle); - } - - /** - * Determine if two messages are identical. This default implementation considers that overlapping messages with - * same coordinates are identical. - * - * @param message - the message to compare with - * @return true if identical false otherwise - * - * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#isSameAs(org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode) - */ - @Override - public boolean isSameAs(GraphNode message) { - if (message == null) { - return false; - } - if (!(message instanceof BaseMessage)) { - return super.isSameAs(message); - } - return ((getX() == message.getX()) && (getY() == message.getY()) && (getWidth() == message.getWidth()) && (getHeight() == message.getHeight())); - } - - /** - * Method drawRot. - * - * @param x A x coordinate - * @param y A y coordinate - * @param w A width - * @param h A height - * @param context A graphical context - */ - public void drawRot(int x, int y, int w, int h, IGC context) { - double angleA = Math.atan2(getHeight(), getWidth()); - double cosA = Math.cos(angleA); - double sinA = Math.sin(angleA); - - int gx = getX(); - int gy = getY(); - - int localHeight = h; - localHeight = localHeight / 2; - - double cw = Math.sqrt(w * w + getHeight() * getHeight()); - - int x1 = Math.round((float) ((x - gx) * cosA - (y - gy) * sinA)); - int y1 = Math.round((float) ((x - gx) * sinA + (y - gy) * cosA)); - - int x2 = Math.round((float) (cw * cosA - (y - gy) * sinA)); - int y2 = Math.round((float) (cw * sinA + (y - gy) * cosA)); - - int x3 = Math.round((float) (cw * cosA - (localHeight) * sinA)); - int y3 = Math.round((float) (cw * sinA + (localHeight) * cosA)); - - int x4 = Math.round((float) ((x - gx) * cosA - (localHeight) * sinA)); - int y4 = Math.round((float) ((x - gx) * sinA + (localHeight) * cosA)); - - int[] points = { x1 + getX(), y1 + getY(), x2 + getX(), y2 + getY(), x3 + getX(), y3 + getY(), x4 + getX(), y4 + getY() }; - context.drawPolygon(points); - } - - @Override - public void drawFocus(IGC context) { - - ISDPreferences pref = SDViewPref.getInstance(); - - if ((fStartLifeline != fEndLifeline) && (getStartOccurrence() == getEndOccurrence())) { - context.setLineStyle(context.getLineDotStyle()); - context.setLineWidth(Metrics.NORMAL_LINE_WIDTH); - context.setBackground(pref.getBackGroundColorSelection()); - context.setForeground(pref.getForeGroundColorSelection()); - context.drawFocus(getX(), getY() - 3, getWidth(), getHeight() + 6); - } else if ((fStartLifeline == fEndLifeline) && (getStartOccurrence() == getEndOccurrence())) { - context.drawFocus(getX(), getY() - 3, getWidth(), Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT + 6); - } else if ((fStartLifeline != fEndLifeline) && (getStartOccurrence() != getEndOccurrence())) { - context.setLineStyle(context.getLineDotStyle()); - context.setLineWidth(Metrics.NORMAL_LINE_WIDTH); - context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_LIFELINE_HEADER)); - context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_LIFELINE_HEADER)); - drawRot(getX(), getY() - 5, getWidth(), 10, context); - } else { - super.drawFocus(context); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/BasicExecutionOccurrence.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/BasicExecutionOccurrence.java deleted file mode 100755 index 9e0349715e..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/BasicExecutionOccurrence.java +++ /dev/null @@ -1,275 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.ISDPreferences; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; - -/** - * BasicExecutionOccurrence is the UML2 execution occurrence graphical representation. It is attached to one Lifeline, - * the event occurrence "duration" along the lifeline is defined by two event occurrences - * - * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline Lifeline for more event occurence details - * @version 1.0 - * @author sveyrier - * - */ -public class BasicExecutionOccurrence extends GraphNode { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The grahNode ID constant - */ - public static final String EXEC_OCC_TAG = "Execution_Occ"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The corresponding lifeline. - */ - private Lifeline fLifeline = null; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructore - */ - public BasicExecutionOccurrence() { - setColorPrefId(ISDPreferences.PREF_EXEC); - } - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - @Override - public int getX() { - if (fLifeline == null) { - return 0; - } - return fLifeline.getX() + Metrics.getLifelineWidth() / 2 - Metrics.EXECUTION_OCCURRENCE_WIDTH / 2; - } - - @Override - public int getY() { - if (fLifeline == null) { - return 0; - } - return fLifeline.getY() + fLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * getStartOccurrence(); - } - - @Override - public int getWidth() { - if (fLifeline == null) { - return 0; - } - return Metrics.EXECUTION_OCCURRENCE_WIDTH; - } - - @Override - public int getHeight() { - if (fLifeline == null) { - return 0; - } - return ((Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing())) * (getEndOccurrence() - getStartOccurrence()); - } - - @Override - public boolean contains(int xValue, int yValue) { - int x = getX(); - int y = getY(); - int width = getWidth(); - int height = getHeight(); - - if (GraphNode.contains(x, y, width, height, xValue, yValue)) { - return true; - } - - if (getNodeAt(xValue, yValue) != null) { - return true; - } - return false; - } - - @Override - public String getName() { - if (super.getName() == null || super.getName().equals("")) { //$NON-NLS-1$ - return fLifeline.getToolTipText(); - } - return super.getName(); - } - - /** - * Set the lifeline on which the execution occurrence appears. - * - * @param theLifeline - the parent lifeline - */ - public void setLifeline(Lifeline theLifeline) { - fLifeline = theLifeline; - } - - /** - * Get the lifeline on which the execution occurrence appears. - * - * @return - the parent lifeline - */ - public Lifeline getLifeline() { - return fLifeline; - } - - /** - * Get the execution start event occurrence - * - * @return the start event occurrence to set - */ - @Override - public int getStartOccurrence() { - return super.getStartOccurrence(); - } - - /** - * Set the execution end event occurrence - * - * @return the end event occurrence to set - */ - @Override - public int getEndOccurrence() { - return super.getEndOccurrence(); - } - - /** - * Set the execution start event occurrence - * - * @param occurrence the start event occurrence to set - */ - @Override - public void setStartOccurrence(int occurrence) { - super.setStartOccurrence(occurrence); - } - - /** - * Set the execution end event occurrence - * - * @param occurrence the end event occurrence to set - */ - @Override - public void setEndOccurrence(int occurrence) { - super.setEndOccurrence(occurrence); - } - - @Override - public void draw(IGC context) { - int x = getX(); - int y = getY(); - int width = getWidth(); - int height = getHeight(); - IColor tempFillColor = null; - IColor tempStrokeColor = null; - - ISDPreferences pref = SDViewPref.getInstance(); - - // The execution occurrence is selected - // if the owning lifeline is selected - if (fLifeline.isSelected() || isSelected()) { - context.setBackground(pref.getBackGroundColorSelection()); - context.setForeground(pref.getForeGroundColorSelection()); - } else { - tempFillColor = setUnselectedFillColor(context); - } - if (pref.useGradienColor()) { - context.fillGradientRectangle(x, y, width, height, false); - } else { - context.fillRectangle(x, y, width, height); - } - tempStrokeColor = setUnselectedStrokeColor(context); - context.drawRectangle(x, y, width, height); - if (tempFillColor != null) { - tempFillColor.dispose(); - } - if (tempStrokeColor != null) { - tempStrokeColor.dispose(); - } - if (hasFocus()) { - drawFocus(context); - } - super.drawChildenNodes(context); - } - - /** - * Rewrite this method in your extension in order to support customized fill colors - * - * @param context Graphics context - * @return IColor - */ - protected IColor setUnselectedFillColor(IGC context) { - - ISDPreferences pref = SDViewPref.getInstance(); - - if (pref.useGradienColor()) { - context.setGradientColor(pref.getBackGroundColor(ISDPreferences.PREF_EXEC)); - context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_FRAME)); - } else { - context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_EXEC)); - } - return null; - } - - /** - * Rewrite this method in your extension in order to support customized stroke colors - * - * @param context Graphics context - * @return IColor - */ - protected IColor setUnselectedStrokeColor(IGC context) { - context.setForeground(SDViewPref.getInstance().getForeGroundColor(ISDPreferences.PREF_EXEC)); - return null; - } - - @Override - public String getArrayId() { - return EXEC_OCC_TAG; - } - - @Override - public boolean positiveDistanceToPoint(int x, int y) { - if (getY() + getHeight() > y) { - return true; - } - return false; - } - - @Override - public boolean isVisible(int x, int y, int width, int height) { - if ((getLifeline() != null) && (getLifeline().isVisible(x, y, width, height))) { - int ly = getY(); - int lh = getHeight(); - if (ly >= y && ly < y + height) { - return true; - } - if (ly + lh > y && ly + lh <= y + height) { - return true; - } - if ((ly < y) && (ly + lh > y + height)) { - return true; - } - } - return false; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/BasicFrame.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/BasicFrame.java deleted file mode 100755 index c5b1acd170..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/BasicFrame.java +++ /dev/null @@ -1,633 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.ISDPreferences; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; - -/** - * The Frame class is the base sequence diagram graph nodes container.
- * For instance, only one frame can be drawn in the View.
- * Lifelines, Messages and Stop which are supposed to represent a Sequence diagram are drawn in a Frame.
- * Only the graph node added to their representing list will be drawn. - * - * The lifelines are appended along the X axsis when added in a frame.
- * The syncMessages are ordered along the Y axsis depending on the event occurrence they are attached to.
- * - * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline Lifeline for more event occurence details - * @author sveyrier - * @version 1.0 - */ -public class BasicFrame extends GraphNode { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * Contains the max elapsed time between two consecutive messages in the whole frame - */ - private ITmfTimestamp fMaxTime = new TmfTimestamp(0); - /** - * Contains the min elapsed time between two consecutive messages in the whole frame - */ - private ITmfTimestamp fMinTime = new TmfTimestamp(0); - /** - * Indicate if the min and max elapsed time between two consecutive messages in the whole frame need to be computed - */ - private boolean fComputeMinMax = true; - /** - * Store the preference set by the user regarding the external time. This flag is used determine if the min and max - * need to be recomputed in case this preference is changed. - */ - private boolean fLastExternalTimePref = SDViewPref.getInstance().excludeExternalTime(); - /** - * The greater event occurrence created on graph nodes drawn in this Frame This directly impact the Frame height - */ - private int fVerticalIndex = 0; - /** - * The index along the x axis where the next lifeline will is drawn This directly impact the Frame width - */ - private int fHorizontalIndex = 0; - /** - * The time information flag. - */ - private boolean fHasTimeInfo = false; - /** - * The current Frame visible area - x coordinates - */ - private int fVisibleAreaX; - /** - * The current Frame visible area - y coordinates - */ - private int fVisibleAreaY; - /** - * The current Frame visible area - width - */ - private int fVisibleAreaWidth; - /** - * The current Frame visible area - height - */ - private int fVisibleAreaHeight; - /** - * The event occurrence spacing (-1 for none) - */ - private int fForceEventOccurrenceSpacing = -1; - /** - * Flag to indicate customized minumum and maximum. - */ - private boolean fCustomMinMax = false; - /** - * The minimum time between messages of the sequence diagram frame. - */ - private ITmfTimestamp fMinSDTime = new TmfTimestamp(); - /** - * The maximum time between messages of the sequence diagram frame. - */ - private ITmfTimestamp fMaxSDTime = new TmfTimestamp(); - /** - * Flag to indicate that initial minimum has to be computed. - */ - private boolean fInitSDMin = true; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Creates an empty frame. - */ - public BasicFrame() { - Metrics.setForcedEventSpacing(fForceEventOccurrenceSpacing); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - /** - * - * Returns the greater event occurence known by the Frame - * - * @return the greater event occurrence - */ - protected int getMaxEventOccurrence() { - return fVerticalIndex; - } - - /** - * Set the greater event occurrence created in GraphNodes included in the frame - * - * @param eventOccurrence the new greater event occurrence - */ - protected void setMaxEventOccurrence(int eventOccurrence) { - fVerticalIndex = eventOccurrence; - } - - /** - * This method increase the lifeline place holder The return value is usually assign to a lifeline. This can be used - * to set the lifelines drawing order. Also, calling this method two times and assigning only the last given index - * to a lifeline will increase this lifeline draw spacing (2 times the default spacing) from the last added - * lifeline. - * - * @return a new lifeline index - */ - protected int getNewHorizontalIndex() { - return ++fHorizontalIndex; - } - - /** - * Returns the current horizontal index - * - * @return the current horizontal index - * @see Frame#getNewHorizontalIndex() for horizontal index description - */ - protected int getHorizontalIndex() { - return fHorizontalIndex; - } - - @Override - public void addNode(GraphNode nodeToAdd) { - setComputeMinMax(true); - super.addNode(nodeToAdd); - } - - @Override - public int getX() { - return Metrics.FRAME_H_MARGIN; - } - - @Override - public int getY() { - return Metrics.FRAME_V_MARGIN; - } - - @Override - public int getWidth() { - if (fHorizontalIndex == 0) { - return 3 * Metrics.swimmingLaneWidth() + Metrics.LIFELINE_H_MAGIN * 2 - Metrics.FRAME_H_MARGIN - Metrics.LIFELINE_SPACING / 2; - } - return fHorizontalIndex * Metrics.swimmingLaneWidth() + Metrics.LIFELINE_H_MAGIN * 2 + 1 - Metrics.LIFELINE_SPACING; - } - - @Override - public int getHeight() { - // The Frame height depends on the maximum number of messages added to a lifeline - if (fVerticalIndex == 0) { - return 5 * (Metrics.getMessagesSpacing() + Metrics.getMessageFontHeigth()) + Metrics.LIFELINE_NAME_H_MARGIN + Metrics.FRAME_NAME_H_MARGIN + Metrics.getFrameFontHeigth() + Metrics.LIFELINE_VT_MAGIN + Metrics.LIFELINE_VB_MAGIN - + Metrics.LIFELINE_NAME_H_MARGIN + Metrics.FRAME_NAME_H_MARGIN + Metrics.getLifelineFontHeigth() * 2; - } - if (fForceEventOccurrenceSpacing >= 0) { - Metrics.setForcedEventSpacing(fForceEventOccurrenceSpacing); - } - return fVerticalIndex * (Metrics.getMessagesSpacing() + Metrics.getMessageFontHeigth()) + Metrics.LIFELINE_NAME_H_MARGIN + Metrics.FRAME_NAME_H_MARGIN + Metrics.getFrameFontHeigth() + Metrics.LIFELINE_VT_MAGIN + Metrics.LIFELINE_VB_MAGIN - + Metrics.LIFELINE_NAME_H_MARGIN + Metrics.FRAME_NAME_H_MARGIN + Metrics.getLifelineFontHeigth() * 2; - } - - /** - * @return true if mininum and maximum time needs to be calculated else false - * @since 2.0 - */ - protected boolean isComputeMinMax() { - return fComputeMinMax; - } - - /** - * @return true if mininum and maximum time needs to be calculated else false - * @since 2.0 - */ - protected boolean isCustomMinMax() { - return fCustomMinMax; - } - - /** - * gets the initialization flag for SD minimum. - * - * @return the initialization flag for SD minimum - * @since 2.0 - */ - protected boolean getInitSDMin() { - return fInitSDMin; - } - - /** - * Returns the graph node which contains the point given in parameter for the given graph node list and starting the - * iteration at the given index
- * WARNING: Only graph nodes with smaller coordinates than the current visible area can be returned.
- * - * @param x the x coordinate of the point to test - * @param y the y coordinate of the point to test - * @param list the list to search in - * @param fromIndex list browsing starting point - * @return the graph node containing the point given in parameter, null otherwise - * - * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#getNodeFromListAt(int, int, java.util.List, int) - */ - @Override - protected GraphNode getNodeFromListAt(int x, int y, List list, int fromIndex) { - if (list == null) { - return null; - } - for (int i = fromIndex; i < list.size(); i++) { - GraphNode node = list.get(i); - // only lifeline list is x ordered - // Stop browsing the list if the node is outside the visible area - // all others nodes will be not visible - if ((node instanceof Lifeline) && (node.getX() > fVisibleAreaX + fVisibleAreaWidth)) { - break; - } - if (node.getHeight() < 0) { - if (node.getY() + node.getHeight() > fVisibleAreaY + fVisibleAreaHeight) { - break; - } - } else { - if (node.getY() > fVisibleAreaY + fVisibleAreaHeight) { - break; - } - } - if (node.contains(x, y)) { - return node; - } - } - return null; - } - - /** - * Draw the Frame rectangle - * - * @param context the context to draw to - */ - protected void drawFrame(IGC context) { - - ISDPreferences pref = SDViewPref.getInstance(); - - context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_FRAME)); - context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_FRAME)); - - int x = getX(); - int y = getY(); - int w = getWidth(); - int h = getHeight(); - - // Draw the frame main rectangle - context.fillRectangle(x, y, w, h); - context.drawRectangle(x, y, w, h); - - context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_FRAME_NAME)); - context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_FRAME_NAME)); - context.setFont(pref.getFont(ISDPreferences.PREF_FRAME_NAME)); - - int nameWidth = context.textExtent(getName()) + 2 * Metrics.FRAME_NAME_V_MARGIN; - int nameHeight = Metrics.getFrameFontHeigth() + +Metrics.FRAME_NAME_H_MARGIN * 2; - - // Draw the frame name area - if (nameWidth > w) { - nameWidth = w; - } - - int[] points = { x, y, x + nameWidth, y, x + nameWidth, y - 11 + nameHeight, x - 11 + nameWidth, y + nameHeight, x, y + nameHeight, x, y + nameHeight }; - context.fillPolygon(points); - context.drawPolygon(points); - context.drawLine(x, y, x, y + nameHeight); - - context.setForeground(pref.getFontColor(ISDPreferences.PREF_FRAME_NAME)); - context.drawTextTruncatedCentred(getName(), x, y, nameWidth - 11, nameHeight, false); - - context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_FRAME)); - context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_FRAME)); - } - - @Override - public void draw(IGC context) { - draw(context, true); - } - - /** - * Draws the Frame on the given context.
- * This method start width GraphNodes ordering if needed.
- * After, depending on the visible area, only visible GraphNodes are drawn.
- * - * @param context the context to draw to - * @param drawFrame indicate if the frame rectangle need to be redrawn - * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#draw(IGC) - */ - protected void draw(IGC context, boolean drawFrame) { - fVisibleAreaHeight = context.getVisibleHeight(); - fVisibleAreaWidth = context.getVisibleWidth(); - fVisibleAreaX = context.getContentsX(); - fVisibleAreaY = context.getContentsY(); - - if (fForceEventOccurrenceSpacing >= 0) { - Metrics.setForcedEventSpacing(fForceEventOccurrenceSpacing); - } else { - Metrics.setForcedEventSpacing(-1); - } - - super.drawChildenNodes(context); - } - - /** - * Sets the event occurrence spacing (-1 for none) - * - * @param space A spacing to set. - */ - public void forceEventOccurrenceSpacing(int space) { - fForceEventOccurrenceSpacing = space; - } - - /** - * Return the X coordinates of the frame visible area - * - * @return the X coordinates of the frame visible area - */ - public int getVisibleAreaX() { - return fVisibleAreaX; - } - - /** - * Return the frame visible area width - * - * @return the frame visible area width - */ - public int getVisibleAreaWidth() { - return fVisibleAreaWidth; - } - - /** - * Return the frame visible area height - * - * @return the frame visible area height - */ - public int getVisibleAreaHeight() { - return fVisibleAreaHeight; - } - - /** - * Return the X coordinates of the frame visible area - * - * @return the X coordinates of the frame visible area - */ - public int getVisibleAreaY() { - return fVisibleAreaY; - } - - /** - * Return the minimum time stored in the frame taking all GraphNodes into account - * - * @return the minimum GraphNode time - * @since 2.0 - */ - public ITmfTimestamp getMinTime() { - if (fLastExternalTimePref != SDViewPref.getInstance().excludeExternalTime()) { - fLastExternalTimePref = SDViewPref.getInstance().excludeExternalTime(); - setComputeMinMax(true); - } - if ((fComputeMinMax) && (!fCustomMinMax)) { - computeMinMax(); - setComputeMinMax(false); - } - return fMinTime; - } - - /** - * Set the minimum timestamp of the frame. - * - * @param min - * The minimum timestamp - * @since 2.0 - */ - public void setMin(ITmfTimestamp min) { - fMinTime = min; - fCustomMinMax = true; - } - - /** - * Set the maximum timestamp of the frame. - * - * @param max - * The maximum timestamp - * @since 2.0 - */ - public void setMax(ITmfTimestamp max) { - fMaxTime = max; - fCustomMinMax = true; - } - - /** - * Reset min/max timestamp values to the default ones. - */ - public void resetCustomMinMax() { - fCustomMinMax = false; - setComputeMinMax(true); - } - - /** - * Return the maximum time stored in the frame taking all GraphNodes into account - * - * @return the maximum GraphNode time - * @since 2.0 - */ - public ITmfTimestamp getMaxTime() { - if (fLastExternalTimePref != SDViewPref.getInstance().excludeExternalTime()) { - fLastExternalTimePref = SDViewPref.getInstance().excludeExternalTime(); - setComputeMinMax(true); - } - if (fComputeMinMax) { - computeMinMax(); - setComputeMinMax(false); - } - return fMaxTime; - } - - /** - * Computes the minimum and maximum time between consecutive messages within the frame. - */ - protected void computeMaxMinTime() { - if (!fInitSDMin) { - return; - } - - List timeArray = buildTimeArray(); - - if ((timeArray == null) || timeArray.isEmpty()) { - return; - } - for (int i = 0; i < timeArray.size(); i++) { - SDTimeEvent m = timeArray.get(i); - - if (m.getTime().compareTo(fMaxSDTime, true) > 0) { - fMaxSDTime = m.getTime(); - } - - if ((m.getTime().compareTo(fMinSDTime, true) < 0) || fInitSDMin) { - fMinSDTime = m.getTime(); - fInitSDMin = false; - } - } - } - - /** - * Returns the minimum time between consecutive messages. - * - * @return the minimum time between consecutive messages - * @since 2.0 - */ - public ITmfTimestamp getSDMinTime() { - computeMaxMinTime(); - return fMinSDTime; - } - - /** - * Returns the maximum time between consecutive messages. - * - * @return the maximum time between consecutive messages - * @since 2.0 - */ - public ITmfTimestamp getSDMaxTime() { - computeMaxMinTime(); - return fMaxSDTime; - } - - /** - * Browse all the GraphNode to compute the min and max times store in the Frame - */ - protected void computeMinMax() { - List timeArray = buildTimeArray(); - - if ((timeArray == null) || timeArray.isEmpty()) { - return; - } - for (int i = 0; i < timeArray.size() - 1; i++) { - SDTimeEvent m1 = timeArray.get(i); - SDTimeEvent m2 = timeArray.get(i + 1); - - updateMinMax(m1, m2); - } - } - - /** - * Updates the minimum and maximum time between consecutive message within the frame based on the given values. - * - * @param m1 A first SD time event. - * @param m2 A second SD time event. - */ - protected void updateMinMax(SDTimeEvent m1, SDTimeEvent m2) { - ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime()); - if (fComputeMinMax) { - fMinTime = delta; - if (fMinTime.compareTo(TmfTimestamp.ZERO, false) < 0) { - fMinTime = new TmfTimestamp(0, m1.getTime().getScale(), m1.getTime().getPrecision()); - } - fMaxTime = fMinTime; - setComputeMinMax(false); - } - - if ((delta.compareTo(fMinTime, true) < 0) && (delta.compareTo(TmfTimestamp.ZERO, false) > 0)) { - fMinTime = delta; - } - - if ((delta.compareTo(fMaxTime, true) > 0) && (delta.compareTo(TmfTimestamp.ZERO, false) > 0)) { - fMaxTime = delta; - } - } - - /** - * Builds the time array based on the list of graph nodes. - * - * @return the time array else empty list. - */ - protected List buildTimeArray() { - if (!hasChildren()) { - return new ArrayList<>(); - } - - Iterator it = getForwardSortMap().keySet().iterator(); - List timeArray = new ArrayList<>(); - while (it.hasNext()) { - String nodeType = it.next(); - List list = getNodeMap().get(nodeType); - for (int i = 0; i < list.size(); i++) { - Object timedNode = list.get(i); - if ((timedNode instanceof ITimeRange) && ((ITimeRange) timedNode).hasTimeInfo()) { - int event = list.get(i).getStartOccurrence(); - ITmfTimestamp time = ((ITimeRange) list.get(i)).getStartTime(); - SDTimeEvent f = new SDTimeEvent(time, event, (ITimeRange) list.get(i)); - timeArray.add(f); - if (event != list.get(i).getEndOccurrence()) { - event = (list.get(i)).getEndOccurrence(); - time = ((ITimeRange) list.get(i)).getEndTime(); - f = new SDTimeEvent(time, event, (ITimeRange) list.get(i)); - timeArray.add(f); - } - } - } - } - return timeArray; - } - - @Override - public String getArrayId() { - return null; - } - - @Override - public boolean contains(int x, int y) { - return false; - } - - /** - * @return true if frame has time info else false - * @since 2.0 - */ - public boolean hasTimeInfo() { - return fHasTimeInfo; - } - - /** - * Sets the flag whether the frame has time info or not - * @since 2.0 - * @param hasTimeInfo - * true if frame has time info else false - */ - public void setHasTimeInfo(boolean hasTimeInfo) { - fHasTimeInfo = hasTimeInfo; - } - - /** - * Sets the flag for minimum and maximum computation. - * @param computeMinMax - * true if mininum and maximum time needs to be calculated else false - * @since 2.0 - */ - public void setComputeMinMax(boolean computeMinMax) { - fComputeMinMax = computeMinMax; - } - - /** - * Sets the initialization flag for SD minimum. - * - * @param initSDMin - * the flag to set - * @since 2.0 - */ - public void setInitSDMin(boolean initSDMin) { - fInitSDMin = initSDMin; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/EllipsisMessage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/EllipsisMessage.java deleted file mode 100755 index 21990c88d1..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/EllipsisMessage.java +++ /dev/null @@ -1,141 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.ISDPreferences; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; - -/** - * Class to draw Ellipsis Message. - * - * @version 1.0 - * @author sveyrier - * - */ -public class EllipsisMessage extends AsyncMessage { - - @Override - public int getX() { - if (getStartLifeline() == null) { - return super.getX() + super.getWidth() - 16; - } - return super.getX(); - } - - @Override - public int getY() { - return super.getY() + 3; - } - - @Override - public int getWidth() { - return 16; - } - - @Override - protected void drawMessage(IGC context) { - // temporary store the coordinates to avoid more methods calls - int x = super.getX(); - int y = getY(); - int width = super.getWidth(); - int height = getHeight(); - - // UML2 found message (always drawn from left to right) - if (getStartLifeline() == null && getEndLifeline() != null) { - // Draw the message label above the message and centered - // The label is truncated if it cannot fit between the two message end - // 2*Metrics.MESSAGES_NAME_SPACING = space above the label + space below the label - context.drawTextTruncatedCentred(getName(), x, y - Metrics.getMessageFontHeigth() - 2 * Metrics.MESSAGES_NAME_SPACING, width, 2 * Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth(), !isSelected()); - - int currentStyle = context.getLineStyle(); - context.setLineStyle(context.getLineSolidStyle()); - // Draw the message main line - context.drawRectangle(x + width - 5, y, x + width - 6, y + height); - context.drawRectangle(x + width - 10, y, x + width - 11, y + height); - context.drawRectangle(x + width - 15, y, x + width - 16, y + height); - context.setLineStyle(currentStyle); - - IColor storedColor = context.getBackground(); - context.setBackground(context.getForeground()); - context.fillRectangle(x + width - 5, y, x + width - 6, y + height); - context.fillRectangle(x + width - 10, y, x + width - 11, y + height); - context.fillRectangle(x + width - 15, y, x + width - 16, y + height); - context.setBackground(storedColor); - } - // UML2 lost message (always drawn from left to right) - else if (getEndLifeline() == null && getStartLifeline() != null) { - // Draw the message label above the message and centered - // The label is truncated if it cannot fit between the two message end - // 2*Metrics.MESSAGES_NAME_SPACING = space above the label + space below the label - context.drawTextTruncatedCentred(getName(), x, y - Metrics.getMessageFontHeigth() - 2 * Metrics.MESSAGES_NAME_SPACING, width, 2 * Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth(), !isSelected()); - - int currentStyle = context.getLineStyle(); - context.setLineStyle(context.getLineSolidStyle()); - // Draw the message main line - context.drawRectangle(x + 5, y, 1, 1); - context.drawRectangle(x + 10, y, 1, 1); - context.drawRectangle(x + 15, y, 1, 1); - - context.setLineStyle(currentStyle); - - IColor storedColor = context.getBackground(); - context.setBackground(context.getForeground()); - context.fillRectangle(x + 5, y, 1, 1); - context.fillRectangle(x + 10, y, 1, 1); - context.fillRectangle(x + 15, y, 1, 1); - - context.setBackground(storedColor); - - } else { - super.draw(context); - } - } - - @Override - public void draw(IGC context) { - if (!isVisible()) { - return; - } - - ISDPreferences pref = SDViewPref.getInstance(); - - // Draw it selected?*/ - if (isSelected()) { - - /* - * Draw it twice First time, bigger inverting selection colors Second time, regular drawing using selection - * colors This create the highlight effect - */ - context.setForeground(pref.getBackGroundColorSelection()); - context.setLineWidth(Metrics.SELECTION_LINE_WIDTH); - drawMessage(context); - context.setBackground(pref.getBackGroundColorSelection()); - context.setForeground(pref.getForeGroundColorSelection()); - // Second drawing is done after the else - } else { - context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_ASYNC_MESS)); - context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_ASYNC_MESS)); - } - if (hasFocus()) { - context.setDrawTextWithFocusStyle(true); - } - context.setLineWidth(Metrics.NORMAL_LINE_WIDTH); - drawMessage(context); - context.setLineWidth(Metrics.NORMAL_LINE_WIDTH); - if (hasFocus()) { - context.setDrawTextWithFocusStyle(false); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/ExecutionOccurrence.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/ExecutionOccurrence.java deleted file mode 100755 index 7d0667ab5f..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/ExecutionOccurrence.java +++ /dev/null @@ -1,267 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; - -import java.util.Arrays; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IImage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.ISDPreferences; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; - -/** - * ExecutionOccurrence is the UML2 execution occurrence graphical representation. It is a BasicExecutionOccurrence on - * which you can customize fill and/or. - * - * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline Lifeline for more event occurence details - * @version 1.0 - * @author sveyrier - * - */ -public class ExecutionOccurrence extends BasicExecutionOccurrence implements ITimeRange { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * Set the red, green and blue value of the optional color to be used for filling the execution occurrence. - */ - private int[] fFillRGB; - /** - * Set the red, green and blue value of the optional color to be used for drawing the execution occurrence - */ - private int[] fStrokeRGB; - /** - * The occurrence image. - */ - private IImage fImage; - /** - * The top ellipses image. - */ - private IImage fEllipsesImage; - /** - * The start time stamp. - */ - private ITmfTimestamp fStartTime; - /** - * The end time stamp; - */ - private ITmfTimestamp fEndTime; - /** - * Flag to indicate whether time information is available or not. - */ - private boolean fHasTimeInfo; - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public void setLifeline(Lifeline theLifeline) { - super.setLifeline(theLifeline); - if (getLifeline() != null && fHasTimeInfo) { - getLifeline().setTimeInfo(true); - if (getLifeline().getFrame() != null) { - getLifeline().getFrame().setHasTimeInfo(true); - } - } - } - - /** - * Set the red, green and blue value of the optional color to be used for filling the execution occurrence. - * - * @param red A value for red. - * @param green A green value for green. - * @param blue A value blue. - */ - public void setFillColor(int red, int green, int blue) { - fFillRGB = new int[3]; - fFillRGB[0] = red; - fFillRGB[1] = green; - fFillRGB[2] = blue; - } - - /** - * Set the red, green and blue value of the optional color to be used for drawing the execution occurrence - * - * @param red A value for red. - * @param green A green value for green. - * @param blue A value blue. - */ - public void setStrokeColor(int red, int green, int blue) { - fStrokeRGB = new int[3]; - fStrokeRGB[0] = red; - fStrokeRGB[1] = green; - fStrokeRGB[2] = blue; - } - - /** - * Set the corresponding image. - * - * @param image A image to set. - */ - public void setImage(IImage image) { - fImage = image; - } - - /** - * Set the top ellipses image. - * - * @param image A image to set. - */ - public void setTopEllipsesImage(IImage image) { - fEllipsesImage = image; - } - - /** - * Set the time when the execution occurrence starts. - * - * @param time the time when the execution occurrence starts - * @since 2.0 - */ - public void setStartTime(ITmfTimestamp time) { - fStartTime = time; - fHasTimeInfo = true; - if (getLifeline() != null) { - getLifeline().setTimeInfo(true); - } - } - - /** - * Set the time when the execution occurrence ends. - * - * @param time the time when the execution occurrence ends - * @since 2.0 - */ - public void setEndTime(ITmfTimestamp time) { - fEndTime = time; - fHasTimeInfo = true; - if (getLifeline() != null) { - getLifeline().setTimeInfo(true); - } - } - - /** - * @since 2.0 - */ - @Override - public ITmfTimestamp getStartTime() { - return fStartTime; - } - - /** - * @since 2.0 - */ - @Override - public ITmfTimestamp getEndTime() { - return fEndTime; - } - - @Override - public boolean hasTimeInfo() { - return fHasTimeInfo; - } - - /** - * @return the RGB of the occurrence filler. - * @since 2.0 - */ - public int[] getFillRGB() { - if (fFillRGB == null) { - return null; - } - return Arrays.copyOf(fFillRGB, fFillRGB.length); - } - - /** - * @return the RGB of the occurrence filler. - * @since 2.0 - */ - public int[] getStrokeRGB() { - if (fStrokeRGB == null) { - return null; - } - return Arrays.copyOf(fStrokeRGB, fStrokeRGB.length); - } - - /** - * @return the image. - * @since 2.0 - */ - protected IImage getImage() { - return fImage; - } - - /** - * @return the image. - * @since 2.0 - */ - protected IImage getEllipsesImage() { - return fEllipsesImage; - } - - @Override - public void draw(IGC context) { - super.draw(context); - int x = getX(); - int y = getY(); - int width = getWidth(); - int height = getHeight(); - if (fImage != null) { - context.drawImage(fImage, x + width - 4, y + height - 11, 8, 11); - } - if (fEllipsesImage != null) { - context.drawImage(fEllipsesImage, x + width, y, 40, 10); - } - } - - @Override - protected IColor setUnselectedFillColor(IGC context) { - ISDPreferences pref = SDViewPref.getInstance(); - if (fFillRGB != null) { - IColor tempFillColor = context.createColor(fFillRGB[0], fFillRGB[1], fFillRGB[2]); - if (pref.useGradienColor()) { - context.setGradientColor(tempFillColor); - context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_EXEC)); - context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_FRAME)); - } else { - context.setBackground(tempFillColor); - } - return tempFillColor; - } - return super.setUnselectedFillColor(context); - } - - @Override - protected IColor setUnselectedStrokeColor(IGC context) { - if (fStrokeRGB != null) { - IColor tempStrokeColor = context.createColor(fStrokeRGB[0], fStrokeRGB[1], fStrokeRGB[2]); - context.setForeground(tempStrokeColor); - return tempStrokeColor; - } - return super.setUnselectedStrokeColor(context); - } - - /** - * Sets the flag whether the frame has time info or not - * @since 2.0 - * @param hasTimeInfo - * true if frame has time info else false - */ - public void setHasTimeInfo(boolean hasTimeInfo) { - fHasTimeInfo = hasTimeInfo; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/Frame.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/Frame.java deleted file mode 100755 index 0c653a5ca7..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/Frame.java +++ /dev/null @@ -1,1215 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.TimeEventComparator; - -/** - * The Frame class is the base sequence diagram graph nodes container.
- * For instance, only one frame can be drawn in the View.
- * Lifelines, Messages and Stop which are supposed to represent a Sequence diagram are drawn in a Frame.
- * Only the graph node added to their representing list will be drawn. - * - * The lifelines are appended along the X axsis when added in a frame.
- * The syncMessages are ordered along the Y axsis depending on the event occurrence they are attached to.
- * - * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline Lifeline for more event occurence details - * @author sveyrier - * @version 1.0 - */ -public class Frame extends BasicFrame { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The lifeline that is current highlighted. - */ - private Lifeline fHighlightLifeline = null; - /** - * The value of the start event. - */ - private int fStartEvent = 0; - /** - * The number of events in the frame. - */ - private int fNbEvent = 0; - /** - * The color for highlighting. - */ - private IColor fHighlightColor = null; - /** - * The list of time events of the corresponding execution occurrences. - */ - private List fExecutionOccurrencesWithTime; - /** - * The Array of lifeline categories. - */ - private LifelineCategories[] fLifelineCategories = null; - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - /** - * Returns a list of all lifelines known by this frame. Known lifelines are the only one which can be displayed on - * screen. - * - * @return the lifelines list - */ - protected List getLifelines() { - if (!hasChildren()) { - return null; - } - return getNodeMap().get(Lifeline.LIFELINE_TAG); - } - - /** - * Returns the number of lifelines stored in the frame - * - * @return the number of lifelines - */ - public int lifeLinesCount() { - List lifelines = getLifelines(); - if (lifelines != null) { - return lifelines.size(); - } - return 0; - } - - /** - * Returns the lifeline at the given index in the lifelines array - * - * @param index the position in the lifeline array - * @return the lifeline or null - */ - public Lifeline getLifeline(int index) { - if ((getLifelines() != null) && (index >= 0) && (index < lifeLinesCount())) { - return (Lifeline) getLifelines().get(index); - } - return null; - } - - /** - * Returns a list of syncMessages known by this frame. Known syncMessages are the only on which can be displayed on - * screen - * - * @return the syncMessages list - */ - protected List getSyncMessages() { - if (!hasChildren()) { - return null; - } - return getNodeMap().get(SyncMessage.SYNC_MESS_TAG); - } - - /** - * Returns the number of syncMessages stored in the frame - * - * @return the number of syncMessage - */ - public int syncMessageCount() { - if (getSyncMessages() != null) { - return getSyncMessages().size(); - } - return 0; - } - - /** - * Returns the syncMessage at the given index in the syncMessages array - * - * @param index the position in the syncMessages array - * @return the syncMessage or null - */ - public SyncMessage getSyncMessage(int index) { - if ((getSyncMessages() != null) && (index >= 0) && (index < getSyncMessages().size())) { - return (SyncMessage) getSyncMessages().get(index); - } - return null; - } - - /** - * Returns a list of asyncMessages known by this frame. Known asyncMessages are the only on which can be displayed - * on screen - * - * @return the asyncMessages list or null - */ - protected List getAsyncMessages() { - if (!hasChildren()) { - return null; - } - return getNodeMap().get(AsyncMessage.ASYNC_MESS_TAG); - } - - /** - * Returns the number of asyncMessage stored in the frame - * - * @return the number of asyncMessage - */ - public int asyncMessageCount() { - if (getAsyncMessages() != null) { - return getAsyncMessages().size(); - } - return 0; - } - - /** - * Returns the asyncMessage at the given index in the asyncMessage array - * - * @param index the position in the asyncMessage array - * @return the asyncMessage or null - */ - public AsyncMessage getAsyncMessage(int index) { - if ((getAsyncMessages() != null) && (index >= 0) && (index < getAsyncMessages().size())) { - return (AsyncMessage) getAsyncMessages().get(index); - } - return null; - } - - /** - * Returns a list of syncMessages return known by this frame. Known syncMessages return are the only on which can be - * displayed on screen - * - * @return the syncMessages return list or null - */ - protected List getSyncMessagesReturn() { - if (!hasChildren()) { - return null; - } - return getNodeMap().get(SyncMessageReturn.SYNC_MESS_RET_TAG); - } - - /** - * Returns the number of syncMessageReturn stored in the frame - * - * @return the number of syncMessageReturn - */ - public int syncMessageReturnCount() { - if (getSyncMessagesReturn() != null) { - return getSyncMessagesReturn().size(); - } - return 0; - } - - /** - * Returns the syncMessageReturn at the given index in the syncMessageReturn array - * - * @param index the position in the syncMessageReturn array - * @return the syncMessageReturn or null - */ - public SyncMessageReturn getSyncMessageReturn(int index) { - if ((getSyncMessagesReturn() != null) && (index >= 0) && (index < getSyncMessagesReturn().size())) { - return (SyncMessageReturn) getSyncMessagesReturn().get(index); - } - return null; - } - - /** - * Returns a list of asyncMessageRetun known by this frame. Known asyncMessageRetun are the only on which can be - * displayed on screen - * - * @return the asyncMessageRetun list or null - */ - protected List getAsyncMessagesReturn() { - if (!hasChildren()) { - return null; - } - return getNodeMap().get(AsyncMessageReturn.ASYNC_MESS_RET_TAG); - } - - /** - * Returns the number of asyncMessageReturn stored in the frame - * - * @return the number of asyncMessageReturn - */ - public int asyncMessageReturnCount() { - if (getAsyncMessagesReturn() != null) { - return getAsyncMessagesReturn().size(); - } - return 0; - } - - /** - * Returns the asyncMessageReturn at the given index in the asyncMessageReturn array - * - * @param index the position in the asyncMessageReturn array - * @return the asyncMessageReturn or null - */ - public AsyncMessageReturn getAsyncMessageReturn(int index) { - if ((getAsyncMessagesReturn() != null) && (index >= 0) && (index < getAsyncMessagesReturn().size())) { - return (AsyncMessageReturn) getAsyncMessagesReturn().get(index); - } - return null; - } - - /** - * Adds a lifeline to the frame lifelines list. The lifeline X drawing order depends on the lifeline addition order - * into the frame lifelines list. - * - * @param lifeline the lifeline to add - */ - public void addLifeLine(Lifeline lifeline) { - setComputeMinMax(true); - if (lifeline == null) { - return; - } - // set the lifeline parent frame - lifeline.setFrame(this); - // Increate the frame lifeline counter - // and set the lifeline drawing order - lifeline.setIndex(getNewHorizontalIndex()); - if (lifeline.hasTimeInfo()) { - setHasTimeInfo(true); - } - // add the lifeline to the lifelines list - addNode(lifeline); - } - - /** - * Returns the first visible lifeline drawn in the view - * - * @return the first visible lifeline index - */ - public int getFirstVisibleLifeline() { - if (!hasChildren()) { - return 0; - } else if (getIndexes().get(Lifeline.LIFELINE_TAG) != null) { - return getIndexes().get(Lifeline.LIFELINE_TAG).intValue(); - } - return 0; - } - - /** - * Returns the first visible synchronous message drawn in the view - * - * @return the first visible synchronous message index - */ - public int getFirstVisibleSyncMessage() { - if (!hasChildren()) { - return 0; - } else if (getIndexes().get(SyncMessage.SYNC_MESS_TAG) != null) { - return getIndexes().get(SyncMessage.SYNC_MESS_TAG).intValue(); - } - return 0; - } - - /** - * Returns the first visible synchronous message return drawn in the view - * - * @return the first visible synchronous message return index - */ - public int getFirstVisibleSyncMessageReturn() { - if (!hasChildren()) { - return 0; - } else if (getIndexes().get(SyncMessageReturn.SYNC_MESS_RET_TAG) != null) { - return getIndexes().get(SyncMessageReturn.SYNC_MESS_RET_TAG).intValue(); - } - return 0; - } - - /** - * Returns the first visible synchronous message drawn in the view - * - * @return the first visible synchronous message index - */ - public int getFirstVisibleAsyncMessage() { - if (!hasChildren()) { - return 0; - } else if (getIndexes().get(AsyncMessage.ASYNC_MESS_TAG) != null) { - return getIndexes().get(AsyncMessage.ASYNC_MESS_TAG).intValue(); - } - return 0; - } - - /** - * Returns the first visible synchronous message return drawn in the view - * - * @return the first visible synchronous message return index - */ - public int getFirstVisibleAsyncMessageReturn() { - if (!hasChildren()) { - return 0; - } else if (getIndexes().get(AsyncMessageReturn.ASYNC_MESS_RET_TAG) != null) { - return getIndexes().get(AsyncMessageReturn.ASYNC_MESS_RET_TAG).intValue(); - } - return 0; - } - - /** - * Returns the list of execution occurrences. - * - * @return the list of execution occurrences - */ - public List getExecutionOccurrencesWithTime() { - return fExecutionOccurrencesWithTime; - } - - /** - * Inserts a lifeline after a given lifeline. - * - * @param toInsert A lifeline to insert - * @param after A lifelife the toInsert-lifeline will be inserted after. - */ - public void insertLifelineAfter(Lifeline toInsert, Lifeline after) { - if ((toInsert == null)) { - return; - } - if (toInsert == after) { - return; - } - int insertPoint = 0; - if (after != null) { - insertPoint = after.getIndex(); - } - int removePoint = toInsert.getIndex() - 1; - if (removePoint >= insertPoint) { - getLifelines().remove(removePoint); - } - getLifelines().add(insertPoint, toInsert); - if (removePoint < insertPoint) { - getLifelines().remove(removePoint); - } - - if (removePoint >= insertPoint) { - toInsert.setIndex(insertPoint + 1); - } else { - toInsert.setIndex(insertPoint - 1); - } - - insertPoint++; - if (removePoint >= insertPoint) { - for (int i = insertPoint; i < getLifelines().size(); i++) { - getLifeline(i).setIndex(i + 1); - } - } else { - for (int i = 0; i < insertPoint && i < getLifelines().size(); i++) { - getLifeline(i).setIndex(i + 1); - } - } - } - - /** - * Inserts a lifeline before a given lifeline. - * - * @param toInsert - * A lifeline to insert - * @param before - * A lifeline the toInsert-lifeline will be inserted before. - */ - public void insertLifelineBefore(Lifeline toInsert, Lifeline before) { - if ((toInsert == null)) { - return; - } - if (toInsert == before) { - return; - } - int insertPoint = 0; - if (before != null) { - insertPoint = before.getIndex() - 1; - } - int removePoint = toInsert.getIndex() - 1; - if (removePoint >= insertPoint) { - getLifelines().remove(removePoint); - } - getLifelines().add(insertPoint, toInsert); - if (removePoint < insertPoint) { - getLifelines().remove(removePoint); - } - - if (removePoint >= insertPoint) { - toInsert.setIndex(insertPoint + 1); - } else { - toInsert.setIndex(insertPoint - 1); - } - - insertPoint++; - if (removePoint >= insertPoint) { - for (int i = insertPoint; i < getLifelines().size(); i++) { - getLifeline(i).setIndex(i + 1); - } - } else { - for (int i = 0; i < insertPoint && i < getLifelines().size(); i++) { - getLifeline(i).setIndex(i + 1); - } - } - } - - /** - * Gets the closer life line to the given x-coordinate. - * - * @param x A x coordinate - * @return the closer lifeline - */ - public Lifeline getCloserLifeline(int x) { - int index = (x - Metrics.FRAME_H_MARGIN + Metrics.LIFELINE_H_MAGIN) / Metrics.swimmingLaneWidth() - 1; - if (index < 0) { - index = 0; - } - if (index >= getLifelines().size()) { - index = getLifelines().size() - 1; - } - Lifeline node1, node2, node3; - int dist1, dist2, dist3; - node1 = node2 = node3 = getLifeline(index); - dist1 = dist2 = dist3 = Math.abs(node1.getX() + node1.getWidth() / 2 - x); - if (index > 0) { - node2 = getLifeline(index - 1); - dist2 = Math.abs(node2.getX() + node2.getWidth() / 2 - x); - } - if (index < getLifelines().size() - 1) { - node3 = getLifeline(index + 1); - dist3 = Math.abs(node3.getX() + node3.getWidth() / 2 - x); - } - if (dist1 <= dist2 && dist1 <= dist3) { - return node1; - } else if (dist2 <= dist1 && dist2 <= dist3) { - return node2; - } - return node3; - } - - /** - * Re-orders the given list of lifelines. - * - * @param list A list of lifelines to reorder. - */ - public void reorder(List list) { - for (int i = 0; i < list.size(); i++) { - if (list.get(i) instanceof Lifeline[]) { - Lifeline temp[] = (Lifeline[]) list.get(i); - if (temp.length == 2) { - if (temp[1] == null) { - insertLifelineAfter(temp[0], getLifeline(lifeLinesCount() - 1)); - } else { - insertLifelineBefore(temp[0], temp[1]); - } - } - } - } - } - - /** - * Resets the time compression information. - */ - public void resetTimeCompression() { - fHighlightLifeline = null; - this.fStartEvent = 0; - this.fNbEvent = 0; - fHighlightColor = null; - } - - @Override - protected void computeMinMax() { - List timeArray = buildTimeArray(); - if ((timeArray == null) || timeArray.isEmpty()) { - return; - } - for (int i = 0; i < timeArray.size() - 1; i++) { - SDTimeEvent m1 = timeArray.get(i); - SDTimeEvent m2 = timeArray.get(i + 1); - if (SDViewPref.getInstance().excludeExternalTime() && ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage))) { - BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); - BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); - if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) { - continue; - } - } - - updateMinMax(m1, m2); - } - } - - /** - * Find the two graph nodes that are closest to this date, one just earlier, second just later. If date is before - * any graph node, bounds[0] is null and bounds[1] is the earliest. If date is after any graph node, bounds[1] is - * null and bounds[0] is the latest. - * - * @param dateToFind date to be found - * @param bounds a two items array that will receive bounds if found - * @return true if both bounds not null - * @since 2.0 - */ - public boolean findDateBounds(ITmfTimestamp dateToFind, ITimeRange bounds[]) { - if (hasTimeInfo()) { - List timeArray = buildTimeArray(); - - if ((timeArray == null) || timeArray.isEmpty()) { - return false; - } - - bounds[0] = null; - bounds[1] = null; - for (int i = 0; i < timeArray.size(); i++) { - SDTimeEvent m = timeArray.get(i); - if (m.getTime().compareTo(dateToFind, true) > 0) { - bounds[1] = m.getGraphNode(); - if (i > 0) { - bounds[0] = timeArray.get(i - 1).getGraphNode(); - return true; - } - return false; - } - } - bounds[0] = timeArray.get(timeArray.size() - 1).getGraphNode(); - } - return false; - } - - /** - * Highlights the time compression. - * - * @param lifeline A lifeline to highlight - * @param startEvent A start event number - * @param nbEvent A number of events - * @param color A color for highlighting - */ - public void highlightTimeCompression(Lifeline lifeline, int startEvent, int nbEvent, IColor color) { - fHighlightLifeline = lifeline; - this.fStartEvent = startEvent; - this.fNbEvent = nbEvent; - fHighlightColor = color; - } - - /** - * Set the lifeline categories which will be use during the lifelines creation - * - * @see Lifeline#setCategory(int) - * @param categories the lifeline categories array - */ - public void setLifelineCategories(LifelineCategories[] categories) { - fLifelineCategories = Arrays.copyOf(categories, categories.length); - } - - /** - * Returns the lifeline categories array set for the this frame - * - * @return the lifeline categories array or null if not set - */ - public LifelineCategories[] getLifelineCategories() { - return Arrays.copyOf(fLifelineCategories, fLifelineCategories.length); - } - - /** - * Adds a message to the Frame message list. Four kinds of syncMessages can be added:
- * - synchronous syncMessages
- * - synchronous syncMessages return
- * - asynchronous syncMessages
- * - asynchronous syncMessages return
- * For drawing performance reason, it is recommended to add synchronous syncMessages in the same order they should - * appear along the Y axis in the Frame. - * - * @param message the message to add - */ - public void addMessage(BaseMessage message) { - addNode(message); - } - - @Override - public void draw(IGC context) { - drawFrame(context); - if (!hasChildren()) { - return; - } - - if (fHighlightLifeline != null) { - IColor backupColor = context.getBackground(); - context.setBackground(SDViewPref.getInstance().getTimeCompressionSelectionColor()); - int gy = fHighlightLifeline.getY() + fHighlightLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * fStartEvent; - context.fillRectangle(Metrics.FRAME_H_MARGIN + 1, gy, fHighlightLifeline.getX() + Metrics.getLifelineWidth() / 2 - Metrics.FRAME_H_MARGIN, (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * fNbEvent); - context.setBackground(backupColor); - } - super.draw(context, false); - int lifelineArryStep = 1; - if (Metrics.swimmingLaneWidth() * context.getZoom() < Metrics.LIFELINE_SIGNIFICANT_HSPACING) { - lifelineArryStep = Math.round(Metrics.LIFELINE_SIGNIFICANT_HSPACING / (Metrics.swimmingLaneWidth() * context.getZoom())); - } - if (getIndexes().size() == 0) { - return; - } - int lifeLineDrawIndex = getIndexes().get(Lifeline.LIFELINE_TAG).intValue(); - for (int i = lifeLineDrawIndex; i < getNodeMap().get(Lifeline.LIFELINE_TAG).size(); i = i + lifelineArryStep) { - Lifeline toDraw = (Lifeline) getNodeMap().get(Lifeline.LIFELINE_TAG).get(i); - if (toDraw.getX() - Metrics.LIFELINE_SPACING / 2 > context.getContentsX() + context.getVisibleWidth()) { - break; - } - toDraw.drawName(context); - - if (fHighlightLifeline != null) { - if (toDraw == fHighlightLifeline) { - toDraw.highlightExecOccurrenceRegion(context, fStartEvent, fNbEvent, fHighlightColor); - } else if ((toDraw.getIndex() < fHighlightLifeline.getIndex()) || ((toDraw.getIndex() < fHighlightLifeline.getIndex()))) { - - int acIndex = toDraw.getExecOccurrenceDrawIndex(); - // acIndex = first visible execution occurrence - // for drawing speed reason with only search on the visible subset - if (toDraw.getExecutions() != null) { - for (int index = acIndex; index < toDraw.getExecutions().size(); index++) { - BasicExecutionOccurrence exec = (BasicExecutionOccurrence) toDraw.getExecutions().get(index); - int tempEvent = fStartEvent; - for (int j = 0; j < fNbEvent; j++) { - if (((tempEvent >= exec.getStartOccurrence()) && (tempEvent <= exec.getEndOccurrence()) && (tempEvent + 1 >= exec.getStartOccurrence()) && (tempEvent + 1 <= exec.getEndOccurrence()))) { - toDraw.highlightExecOccurrenceRegion(context, tempEvent, 1, SDViewPref.getInstance().getTimeCompressionSelectionColor()); - } - tempEvent = tempEvent + 1; - } - // if we are outside the visible area we stop right now - // This works because execution occurrences are ordered along the Y axis - if (exec.getY() > getY()) { - break; - } - } - } - } - } - } - } - - @Override - protected List buildTimeArray() { - - if (!hasChildren()) { - return new ArrayList<>(); - } - - List timeArray = super.buildTimeArray(); - fExecutionOccurrencesWithTime = null; - if (getLifelines() != null) { - for (int i = 0; i < getNodeMap().get(Lifeline.LIFELINE_TAG).size(); i++) { - Lifeline lifeline = (Lifeline) getNodeMap().get(Lifeline.LIFELINE_TAG).get(i); - if (lifeline.hasTimeInfo() && lifeline.getExecutions() != null) { - for (Iterator j = lifeline.getExecutions().iterator(); j.hasNext();) { - GraphNode o = j.next(); - if (o instanceof ExecutionOccurrence) { - ExecutionOccurrence eo = (ExecutionOccurrence) o; - if (eo.hasTimeInfo()) { - int event = eo.getStartOccurrence(); - ITmfTimestamp time = eo.getStartTime(); - SDTimeEvent f = new SDTimeEvent(time, event, eo); - timeArray.add(f); - if (fExecutionOccurrencesWithTime == null) { - fExecutionOccurrencesWithTime = new ArrayList<>(); - } - fExecutionOccurrencesWithTime.add(f); - event = eo.getEndOccurrence(); - time = eo.getEndTime(); - f = new SDTimeEvent(time, event, eo); - timeArray.add(f); - fExecutionOccurrencesWithTime.add(f); - } - } - } - } - } - } - - if (fExecutionOccurrencesWithTime != null) { - SDTimeEvent[] temp = fExecutionOccurrencesWithTime.toArray(new SDTimeEvent[fExecutionOccurrencesWithTime.size()]); - Arrays.sort(temp, new TimeEventComparator()); - fExecutionOccurrencesWithTime = Arrays.asList(temp); - } - SDTimeEvent[] temp = timeArray.toArray(new SDTimeEvent[timeArray.size()]); - Arrays.sort(temp, new TimeEventComparator()); - timeArray = Arrays.asList(temp); - return timeArray; - } - - /** - * Get the closer leaving message. - * - * @param lifeline A lifeline reference - * @param message A message reference - * @param list A list of graph nodes - * @param smallerEvent A smaller event flag - * @return the closer leaving message. - */ - protected GraphNode getCloserLeavingMessage(Lifeline lifeline, BaseMessage message, List list, boolean smallerEvent) { - if (list == null) { - return null; - } - - if (!smallerEvent) { - int event = 0; - if (message != null) { - event = message.getEventOccurrence(); - } - for (int i = 0; i < list.size(); i++) { - GraphNode node = list.get(i); - if (node instanceof SyncMessage) { - SyncMessage syncNode = (SyncMessage) node; - if ((syncNode.getEventOccurrence() > event) && (syncNode.getStartLifeline() == lifeline) && !syncNode.isSameAs(message)) { - return node; - } - } else if (node instanceof AsyncMessage) { - AsyncMessage asyncNode = (AsyncMessage) node; - if ((asyncNode.getStartOccurrence() > event) && (asyncNode.getStartLifeline() == lifeline) && !asyncNode.isSameAs(message)) { - return node; - } - } - } - } else { - int event = getMaxEventOccurrence(); - if (message != null) { - if (message instanceof AsyncMessage) { - event = ((AsyncMessage) message).getStartOccurrence(); - } else { - event = message.getEventOccurrence(); - } - } - for (int i = list.size() - 1; i >= 0; i--) { - GraphNode node = list.get(i); - if (node instanceof SyncMessage) { - SyncMessage syncNode = (SyncMessage) node; - if ((syncNode.getEventOccurrence() < event) && (syncNode.getStartLifeline() == lifeline) && !syncNode.isSameAs(message)) { - return node; - } - } else if (node instanceof AsyncMessage) { - AsyncMessage asyncNode = (AsyncMessage) node; - if ((asyncNode.getStartOccurrence() < event) && (asyncNode.getStartLifeline() == lifeline) && !asyncNode.isSameAs(message)) { - return node; - } - } - } - } - return null; - } - - - /** - * Get the closer entering message. - * - * @param lifeline A lifeline reference - * @param message A message reference - * @param list A list of graph nodes - * @param smallerEvent A smaller event flag - * @return the closer entering message. - */ - protected GraphNode getCloserEnteringMessage(Lifeline lifeline, BaseMessage message, List list, boolean smallerEvent) { - if (list == null) { - return null; - } - if (!smallerEvent) { - int event = 0; - if (message != null) { - event = message.getEventOccurrence(); - } - for (int i = 0; i < list.size(); i++) { - GraphNode node = list.get(i); - if (node instanceof SyncMessage) { - SyncMessage syncNode = (SyncMessage) node; - if ((syncNode.getEventOccurrence() > event) && (syncNode.getEndLifeline() == lifeline) && !syncNode.isSameAs(message)) { - return node; - } - } else if (node instanceof AsyncMessage) { - AsyncMessage asyncNode = (AsyncMessage) node; - if ((asyncNode.getStartOccurrence() > event) && (asyncNode.getEndLifeline() == lifeline) && !asyncNode.isSameAs(message)) { - return node; - } - } - } - } else { - int event = getMaxEventOccurrence(); - if (message != null) { - if (message instanceof AsyncMessage) { - event = ((AsyncMessage) message).getStartOccurrence(); - } else { - event = message.getEventOccurrence(); - } - } - for (int i = list.size() - 1; i >= 0; i--) { - GraphNode node = list.get(i); - if (node instanceof SyncMessage) { - SyncMessage syncNode = (SyncMessage) node; - if ((syncNode.getEventOccurrence() < event) && (syncNode.getEndLifeline() == lifeline) && !syncNode.isSameAs(message)) { - return node; - } - } else if (node instanceof AsyncMessage) { - AsyncMessage asyncNode = (AsyncMessage) node; - if ((asyncNode.getStartOccurrence() < event) && (asyncNode.getEndLifeline() == lifeline) && !asyncNode.isSameAs(message)) { - return node; - } - } - } - } - return null; - } - - /** - * Get distance of given event from given graph node. - * - * @param node A graph node reference. - * @param event A event number to check. - * @return distance of event from graph node. - */ - protected int distanceFromEvent(GraphNode node, int event) { - int distance = 0; - if (node instanceof SyncMessage) { - distance = ((SyncMessage) node).getEventOccurrence() - event; - } else if (node instanceof AsyncMessage) { - int start = ((AsyncMessage) node).getStartOccurrence(); - int end = ((AsyncMessage) node).getEndOccurrence(); - if ((start - event) < (end - event)) { - distance = start - event; - } else { - distance = end - event; - } - } - return Math.abs(distance); - } - - /** - * Get node from 2 given nodes that is close to event. - * - * @param node1 A first graph node - * @param node2 A second graph node - * @param event A event to check. - * @return graph node that is closer or null - */ - protected GraphNode getCloserToEvent(GraphNode node1, GraphNode node2, int event) { - if ((node1 != null) && (node2 != null)) { - if (distanceFromEvent(node1, event) < distanceFromEvent(node2, event)) { - return node1; - } - return node2; - } else if (node1 != null) { - return node1; - } else if (node2 != null) { - return node2; - } - return null; - } - - /** - * Get called message based on given start message. - * - * @param startMessage A start message to check. - * @return called message (graph node) or null - */ - public GraphNode getCalledMessage(BaseMessage startMessage) { - int event = 0; - GraphNode result = null; - Lifeline lifeline = null; - if (startMessage != null) { - event = startMessage.getEventOccurrence(); - lifeline = startMessage.getEndLifeline(); - if (lifeline == null) { - lifeline = startMessage.getStartLifeline(); - } - } - if (lifeline == null) { - return null; - } - GraphNode message = getCloserLeavingMessage(lifeline, startMessage, getSyncMessages(), false); - GraphNode messageReturn = getCloserLeavingMessage(lifeline, startMessage, getSyncMessagesReturn(), false); - result = getCloserToEvent(message, messageReturn, event); - message = getCloserLeavingMessage(lifeline, startMessage, getAsyncMessages(), false); - result = getCloserToEvent(result, message, event); - messageReturn = getCloserLeavingMessage(lifeline, startMessage, getAsyncMessagesReturn(), false); - result = getCloserToEvent(result, messageReturn, event); - return result; - } - - /** - * Get caller message based on given start message. - * - * @param startMessage A start message to check. - * @return called message (graph node) or null - */ - public GraphNode getCallerMessage(BaseMessage startMessage) { - int event = getMaxEventOccurrence(); - GraphNode result = null; - Lifeline lifeline = null; - if (startMessage != null) { - event = startMessage.getEventOccurrence(); - lifeline = startMessage.getStartLifeline(); - if (lifeline == null) { - lifeline = startMessage.getEndLifeline(); - } - } - if (lifeline == null) { - return null; - } - GraphNode message = getCloserEnteringMessage(lifeline, startMessage, getSyncMessages(), true); - GraphNode messageReturn = getCloserEnteringMessage(lifeline, startMessage, getSyncMessagesReturn(), true); - result = getCloserToEvent(message, messageReturn, event); - message = getCloserEnteringMessage(lifeline, startMessage, getAsyncMessages(), true); - result = getCloserToEvent(result, message, event); - messageReturn = getCloserEnteringMessage(lifeline, startMessage, getAsyncMessagesReturn(), true); - result = getCloserToEvent(result, messageReturn, event); - return result; - } - - /** - * Get next lifeline based on given message. - * - * @param lifeline A lifeline reference - * @param startMessage A start message to check - * @return next lifeline or null - */ - public GraphNode getNextLifelineMessage(Lifeline lifeline, BaseMessage startMessage) { - int event = 0; - if (startMessage != null) { - event = startMessage.getEventOccurrence(); - } - if (lifeline == null) { - return null; - } - GraphNode message = getCloserLeavingMessage(lifeline, startMessage, getSyncMessages(), false); - GraphNode messageReturn = getCloserLeavingMessage(lifeline, startMessage, getSyncMessagesReturn(), false); - GraphNode result = getCloserToEvent(message, messageReturn, event); - message = getCloserLeavingMessage(lifeline, startMessage, getAsyncMessages(), false); - result = getCloserToEvent(result, message, event); - messageReturn = getCloserLeavingMessage(lifeline, startMessage, getAsyncMessagesReturn(), false); - result = getCloserToEvent(result, messageReturn, event); - return result; - } - - /** - * Get previous lifeline based on given message. - * - * @param lifeline A lifeline reference - * @param startMessage A start message to check. - * @return previous lifeline or null - */ - public GraphNode getPrevLifelineMessage(Lifeline lifeline, BaseMessage startMessage) { - int event = getMaxEventOccurrence(); - if (startMessage != null) { - if (startMessage instanceof AsyncMessage) { - event = ((AsyncMessage) startMessage).getStartOccurrence(); - } else { - event = startMessage.getEventOccurrence(); - } - } - if (lifeline == null) { - return null; - } - GraphNode message = getCloserLeavingMessage(lifeline, startMessage, getSyncMessages(), true); - GraphNode messageReturn = getCloserLeavingMessage(lifeline, startMessage, getSyncMessagesReturn(), true); - GraphNode result = getCloserToEvent(message, messageReturn, event); - message = getCloserLeavingMessage(lifeline, startMessage, getAsyncMessages(), true); - result = getCloserToEvent(result, message, event); - messageReturn = getCloserLeavingMessage(lifeline, startMessage, getAsyncMessagesReturn(), true); - result = getCloserToEvent(result, messageReturn, event); - return result; - } - - /** - * Get the first execution occurrence. - * - * @param lifeline A lifeline reference - * @return the first execution occurrence of lifeline or null. - */ - public BasicExecutionOccurrence getFirstExecution(Lifeline lifeline) { - if (lifeline == null) { - return null; - } - List list = lifeline.getExecutions(); - - if ((list == null) || (list.isEmpty())) { - return null; - } - - BasicExecutionOccurrence result = (BasicExecutionOccurrence) list.get(0); - for (int i = 0; i < list.size(); i++) { - BasicExecutionOccurrence e = (BasicExecutionOccurrence) list.get(i); - if ((e.getStartOccurrence() < result.getEndOccurrence())) { - result = e; - } - } - return result; - } - - /** - * Get the previous execution occurrence relative to a given execution occurrence. - * - * @param exec A execution occurrence reference. - * @return the previous execution occurrence of lifeline or null. - */ - public BasicExecutionOccurrence getPrevExecOccurrence(BasicExecutionOccurrence exec) { - if (exec == null) { - return null; - } - Lifeline lifeline = exec.getLifeline(); - if (lifeline == null) { - return null; - } - List list = lifeline.getExecutions(); - if (list == null) { - return null; - } - BasicExecutionOccurrence result = null; - for (int i = 0; i < list.size(); i++) { - BasicExecutionOccurrence e = (BasicExecutionOccurrence) list.get(i); - if ((e.getStartOccurrence() < exec.getStartOccurrence()) && (result == null)) { - result = e; - } - if ((e.getStartOccurrence() < exec.getStartOccurrence()) && (result != null) && (e.getStartOccurrence() >= result.getEndOccurrence())) { - result = e; - } - } - return result; - } - - /** - * Get the next execution occurrence relative to a given execution occurrence. - * - * @param exec A execution occurrence reference. - * @return the next execution occurrence of lifeline or null. - */ - public BasicExecutionOccurrence getNextExecOccurrence(BasicExecutionOccurrence exec) { - if (exec == null) { - return null; - } - Lifeline lifeline = exec.getLifeline(); - if (lifeline == null) { - return null; - } - List list = lifeline.getExecutions(); - if (list == null) { - return null; - } - BasicExecutionOccurrence result = null; - for (int i = 0; i < list.size(); i++) { - BasicExecutionOccurrence e = (BasicExecutionOccurrence) list.get(i); - if ((e.getStartOccurrence() > exec.getStartOccurrence()) && (result == null)) { - result = e; - } - if ((e.getStartOccurrence() > exec.getStartOccurrence()) && (result != null) && (e.getStartOccurrence() <= result.getEndOccurrence())) { - result = e; - } - } - return result; - } - - /** - * Get the last execution occurrence. - * - * @param lifeline A lifeline reference. - * @return the last execution occurrence of lifeline or null. - */ - public BasicExecutionOccurrence getLastExecOccurrence(Lifeline lifeline) { - if (lifeline == null) { - return null; - } - List list = lifeline.getExecutions(); - if (list == null) { - return null; - } - BasicExecutionOccurrence result = null; - for (int i = 0; i < list.size(); i++) { - BasicExecutionOccurrence e = (BasicExecutionOccurrence) list.get(i); - if (result == null) { - result = e; - } - if (e.getStartOccurrence() > result.getEndOccurrence()) { - result = e; - } - } - return result; - } - - /** - * @return highlighted life line if set else null. - * @since 2.0 - */ - protected Lifeline getHighlightLifeline() { - return fHighlightLifeline; - } - - /** - * @return the start event value. - * @since 2.0 - */ - protected int getStartEvent() { - return fStartEvent; - } - - /** - * Returns the number of events - * - * @return the number of events - * @since 2.0 - */ - protected int getNumberOfEvents() { - return fNbEvent; - } - - /** - * Returns the highlight color. - * @return the highlight color - * @since 2.0 - */ - protected IColor getHighlightColor() { - return fHighlightColor; - } - - /** - * Set the highlighted life line. - * @param lifeline - * The highlighted life line if set else null - * @since 2.0 - */ - protected void setHighlightLifeline(Lifeline lifeline) { - fHighlightLifeline = lifeline; - } - - /** - * Sets the start event value - * @param startEvent - * the start event value. - * @since 2.0 - */ - protected void setStartEvent(int startEvent) { - fStartEvent = startEvent; - } - - /** - * Sets the number of events - * - * @param nbEvents - * The number of events - * @since 2.0 - */ - protected void setNumberOfEvents(int nbEvents) { - fNbEvent = nbEvents; - } - - /** - * Sets the highlight color. - * @param color - * the highlight color - * @since 2.0 - */ - protected void setHighlightColor(IColor color) { - fHighlightColor = color; - } - - /** - * sets the list of execution occurrences. - * - * @param occurences - * the list of execution occurrences - * @since 2.0 - */ - protected void setExecutionOccurrencesWithTime(List occurences) { - fExecutionOccurrencesWithTime = occurences; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/GraphNode.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/GraphNode.java deleted file mode 100755 index 0f24282739..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/GraphNode.java +++ /dev/null @@ -1,906 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.eclipse.linuxtools.internal.tmf.ui.TmfUiTracer; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.ISDPreferences; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; - -/** - * The base class used for all UML2 graph nodes displayed in the Sequence Diagram SDWidget. - * - * @author sveyrier - * @version 1.0 - */ -public abstract class GraphNode { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The start event occurrence. - */ - private int fStartEventOccurrence = 0; - /** - * The event event occurrence. - */ - private int fEndEventOccurrence = 0; - /** - * Preference ColorId to use to draw font - */ - private String fPrefId = ISDPreferences.PREF_SYNC_MESS; - /** - * The selection state of the graph node. - */ - private boolean fSelected = false; - /** - * The focus state of the graph node. - */ - private boolean fFocused = false; - /** - * Flag to indicate whether node has children or not. - */ - private boolean fHasChilden = false; - /** - * The graph node name used to label the graph node in the View. - */ - private String fName = ""; //$NON-NLS-1$ - /** - * A map from node name to graph node. - */ - private Map> fNodes; - /** - * A map from node name to graph node for forward sorting - */ - private Map> fForwardNodes; - /** - * A map from node name to graph node for backwards sorting. - */ - private Map> fBackwardNodes; - /** - * A map from node name to index. - */ - private Map fIndexes; - /** - * A map from node name to flag for forwards sorting. - */ - private Map fForwardSort; - /** - * A map from node name to flag for backwards sorting. - */ - private Map fBackwardSort; - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - /** - * Reset the internal index of the first visible GraphNode for each ordered GraphNode lists - */ - public void resetIndex() { - if (!fHasChilden) { - return; - } - - Iterator it = fIndexes.keySet().iterator(); - while (it.hasNext()) { - String nodeType = it.next(); - fIndexes.put(nodeType, Integer.valueOf(0)); - } - } - - /** - * Add a GraphNode into the receiver - * - * @param nodeToAdd the node to add - */ - public void addNode(GraphNode nodeToAdd) { - if (!fHasChilden) { - fNodes = new HashMap<>(2); - fForwardNodes = new HashMap<>(2); - fBackwardNodes = new HashMap<>(2); - fIndexes = new HashMap<>(2); - fBackwardSort = new HashMap<>(2); - fForwardSort = new HashMap<>(2); - fHasChilden = true; - } - - // Nothing to add - if (nodeToAdd == null) { - return; - } - - if (fNodes.get(nodeToAdd.getArrayId()) == null) { - fNodes.put(nodeToAdd.getArrayId(), new ArrayList(1)); - fIndexes.put(nodeToAdd.getArrayId(), Integer.valueOf(0)); - fForwardNodes.put(nodeToAdd.getArrayId(), new ArrayList(1)); - fForwardSort.put(nodeToAdd.getArrayId(), Boolean.FALSE); - if (nodeToAdd.getBackComparator() != null) { - fBackwardNodes.put(nodeToAdd.getArrayId(), new ArrayList(1)); - fBackwardSort.put(nodeToAdd.getArrayId(), Boolean.FALSE); - } - } - - List fNodeList = fForwardNodes.get(nodeToAdd.getArrayId()); - List bNodeList = null; - if (fBackwardNodes != null) { - bNodeList = fBackwardNodes.get(nodeToAdd.getArrayId()); - } - if (fNodeList != null && fNodeList.size() > 0) { - // check if the nodes are added y ordered - // if not, tag the list to sort it later (during draw) - GraphNode node = fNodeList.get(fNodeList.size() - 1); - Comparator fcomp = nodeToAdd.getComparator(); - Comparator bcomp = nodeToAdd.getBackComparator(); - if ((fcomp != null) && (fcomp.compare(node, nodeToAdd) > 0)) { - fForwardSort.put(nodeToAdd.getArrayId(), Boolean.TRUE); - } - if ((bcomp != null) && (bcomp.compare(node, nodeToAdd) > 0)) { - fBackwardSort.put(nodeToAdd.getArrayId(), Boolean.TRUE); - } - } - - if (fNodeList == null) { - fNodeList = new ArrayList<>(); - } - - fNodeList.add(nodeToAdd); - fNodes.put(nodeToAdd.getArrayId(), fNodeList); - fForwardNodes.put(nodeToAdd.getArrayId(), fNodeList); - if ((bNodeList != null) && (nodeToAdd.getBackComparator() != null)) { - bNodeList.add(nodeToAdd); - fBackwardNodes.put(nodeToAdd.getArrayId(), bNodeList); - } - } - - /** - * Set the graph node name.
- * It is the name display in the view to label the graph node. - * - * @param nodeName the name to set - */ - public void setName(String nodeName) { - fName = nodeName; - } - - /** - * Returns the graph node name.
- * It is the name display in the view to label the graph node. - * - * @return the graph node name - */ - public String getName() { - return fName; - } - - /** - * Tags the the graph node has selected.
- * WARNING: This method is only used to draw the graph node using the system selection colors.
- * To use the complete SDViewer selection mechanism (selection management, notification, etc..) see SDWidget class - * - * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#addSelection(GraphNode) - * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#removeSelection(GraphNode) - * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#clearSelection() - * @param selection - true to set selected, false to set unselected - */ - public void setSelected(boolean selection) { - fSelected = selection; - } - - /** - * Tags the the graph node as focused.
- * WARNING: This method is only used to draw the graph node using the system focus style.
- * To use the complete SDViewer focus mechanism see SDWidget class - * - * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#addSelection(GraphNode) - * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#removeSelection(GraphNode) - * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#clearSelection() - * @param focus - true to set focued, false otherwise - */ - public void setFocused(boolean focus) { - fFocused = focus; - } - - /** - * Returns true if the graph node is selected, false otherwise.
- * The returned value is used to highlight the graph node in the View. - * - * @return true if selected, false otherwise - */ - public boolean isSelected() { - return fSelected; - } - - /** - * Returns true if the graph node is focused, false otherwise.
- * The returned value is used to highlight the graph node in the View. - * - * @return true if focused, false otherwise - */ - public boolean hasFocus() { - return fFocused; - } - - /** - * Returns true if the graph node contains the point given in parameter, - * return false otherwise. - * - * @param x - * the x coordinate of the point to test containment - * @param y - * the y coordinate of the point to test containment - * @return true if contained, false otherwise - */ - abstract public boolean contains(int x, int y); - - /** - * Returns the x coordinate of the graph node - * - * @return the x coordinate - */ - abstract public int getX(); - - /** - * Returns the y coordinate of the graph node - * - * @return the y coordinate - */ - abstract public int getY(); - - /** - * Returns the graph node height - * - * @return the graph node height - */ - abstract public int getHeight(); - - /** - * Returns the graph node width - * - * @return the graph node width - */ - abstract public int getWidth(); - - /** - * Draws the graph node in the given context - * - * @param context the graphical context to draw in - */ - abstract protected void draw(IGC context); - - /** - * Returns the GraphNode visibility for the given visible area. Wrong - * visibility calculation, may strongly impact drawing performance - * - * @param x - * The X coordinate - * @param y - * The Y coordinate - * @param width - * The width of the area - * @param height - * The height of the area - * @return true if visible, false otherwise - */ - public boolean isVisible(int x, int y, int width, int height) { - return true; - } - - /** - * Return a comparator to sort the GraphNode of the same type This - * comparator is used to order the GraphNode array of the given node type. - * (see getArrayId). - * - * @return the comparator - */ - public Comparator getComparator() { - return null; - } - - /** - * If needed, return a different comparator to backward scan the GraphNode - * array - * - * @return the backward comparator or null if not needed - */ - public Comparator getBackComparator() { - return null; - } - - /** - * Compare two graphNodes - * - * @param node - * the node to compare to - * @return true if equal false otherwise - */ - public boolean isSameAs(GraphNode node) { - return false; - } - - /** - * Return the node type for all class instances. This id is used to store the same nodes kind in the same ordered - * array. - * - * @return the node type identifier - */ - abstract public String getArrayId(); - - /** - * Return true if the distance from the GraphNode to the given point is positive - * - * @param x the point x coordinate - * @param y the point y coordinate - * @return true if positive false otherwise - */ - public boolean positiveDistanceToPoint(int x, int y) { - return false; - } - - /** - * Returns the graph node which contains the point given in parameter WARNING: Only graph nodes in the current - * visible area can be returned - * - * @param x the x coordinate of the point to test - * @param y the y coordinate of the point to test - * @return the graph node containing the point given in parameter, null otherwise - */ - public GraphNode getNodeAt(int x, int y) { - GraphNode toReturn = null; - - if (!fHasChilden) { - return null; - } - - Iterator it = fNodes.keySet().iterator(); - GraphNode node = null; - while (it.hasNext()) { - Object nodeType = it.next(); - List list = fNodes.get(nodeType); - int index = fIndexes.get(nodeType).intValue(); - node = getNodeFromListAt(x, y, list, index); - if (toReturn == null) { - toReturn = node; - } - if (node != null) { - GraphNode internalNode = node.getNodeAt(x, y); - if (internalNode != null) { - return internalNode; - } else if (Math.abs(node.getWidth()) < Math.abs(toReturn.getWidth()) || Math.abs(node.getHeight()) < Math.abs(toReturn.getHeight())) { - toReturn = node; - } - } - } - return toReturn; - } - - /** - * Gets node list from node A to node B - - * @param from A from node - * @param to A to node - * @return the list of nodes - */ - public List getNodeList(GraphNode from, GraphNode to) { - List result = new ArrayList<>(); - - if (from != null) { - result.add(from); - } else if (to != null) { - result.add(to); - } - - if ((from == null) || (to == null)) { - return result; - } - - if (from == to) { - return result; - } - - int startX = Math.min(from.getX(), Math.min(to.getX(), Math.min(from.getX() + from.getWidth(), to.getX() + to.getWidth()))); - int endX = Math.max(from.getX(), Math.max(to.getX(), Math.max(from.getX() + from.getWidth(), to.getX() + to.getWidth()))); - int startY = Math.min(from.getY(), Math.min(to.getY(), Math.min(from.getY() + from.getHeight(), to.getY() + to.getHeight()))); - int endY = Math.max(from.getY(), Math.max(to.getY(), Math.max(from.getY() + from.getHeight(), to.getY() + to.getHeight()))); - - if (!fHasChilden) { - return result; - } - - Iterator it = fNodes.keySet().iterator(); - while (it.hasNext()) { - Object nodeType = it.next(); - List nodesList = fNodes.get(nodeType); - if (nodesList == null || nodesList.isEmpty()) { - return null; - } - for (int i = 0; i < nodesList.size(); i++) { - GraphNode node = nodesList.get(i); - int nw = node.getWidth(); - int nh = node.getHeight(); - int nx = node.getX(); - int ny = node.getY(); - if (contains(startX, startY, endX - startX, endY - startY, nx + 1, ny + 1) && contains(startX, startY, endX - startX, endY - startY, nx + nw - 2, ny + nh - 2)) { - result.add(node); - } - result.addAll(node.getNodeList(from, to)); - } - } - - if (!result.contains(to)) { - result.add(to); - } - return result; - } - - /** - * Returns the graph node which contains the point given in parameter for the given graph node list and starting the - * iteration at the given index
- * WARNING: Only graph nodes with smaller coordinates than the current visible area can be returned.
- * - * @param x the x coordinate of the point to test - * @param y the y coordinate of the point to test - * @param list the list to search in - * @param fromIndex list browsing starting point - * @return the graph node containing the point given in parameter, null otherwise - */ - protected GraphNode getNodeFromListAt(int x, int y, List list, int fromIndex) { - if (list == null) { - return null; - } - for (int i = fromIndex; i < list.size(); i++) { - GraphNode node = list.get(i); - if (node.contains(x, y)) { - return node; - } - } - return null; - } - - /** - * Returns the start event occurrence attached to this graphNode. - * - * @return the start event occurrence attached to the graphNode - */ - public int getStartOccurrence() { - return fStartEventOccurrence; - } - - /** - * Returns the end event occurrence attached to this graphNode - * - * @return the start event occurrence attached to the graphNode - */ - public int getEndOccurrence() { - return fEndEventOccurrence; - } - - /** - * Computes the index of the first visible GraphNode for each ordered graph node lists depending on the visible area - * given in parameter - * - * @param x visible area top left corner x coordinate - * @param y visible area top left corner y coordinate - * @param width visible area width - * @param height visible area height - */ - public void updateIndex(int x, int y, int width, int height) { - if (!fHasChilden) { - return; - } - if(TmfUiTracer.isIndexTraced()) { - TmfUiTracer.traceIndex("*****************************\n"); //$NON-NLS-1$ - TmfUiTracer.traceIndex("Visible area position in virtual screen (x,y)= " + x + " " + y + "\n\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - - Iterator it = fNodes.keySet().iterator(); - while (it.hasNext()) { - String nodeType = it.next(); - int direction = 1; - int drawIndex = fIndexes.get(nodeType).intValue(); - /* - * if (x==0) { drawIndex = 0; indexes.put(nodeType,new Integer(drawIndex)); } - */ - if ((fNodes.get(nodeType) != null) && (fNodes.get(nodeType).size() > 1)) { - if (fNodes.get(nodeType).get(drawIndex).positiveDistanceToPoint(x, y)) { - direction = -1; - } - - if (drawIndex == 0) { - direction = 1; - } - - if ((direction == -1) && (fBackwardNodes.get(nodeType) != null)) { - GraphNode currentNode = fNodes.get(nodeType).get(drawIndex); - drawIndex = Arrays.binarySearch(fBackwardNodes.get(nodeType).toArray(new GraphNode[fBackwardNodes.get(nodeType).size()]), - fNodes.get(nodeType).get(drawIndex), currentNode.getBackComparator()); - fNodes.put(nodeType, fBackwardNodes.get(nodeType)); - if (drawIndex < 0) { - drawIndex = 0; - direction = 1; - } else { - fNodes.put(nodeType, fBackwardNodes.get(nodeType)); - } - } - GraphNode prev = null; - - for (int i = drawIndex; i < fNodes.get(nodeType).size() && i >= 0; i = i + direction) { - drawIndex = i; - fIndexes.put(nodeType, Integer.valueOf(i)); - - GraphNode currentNode = fNodes.get(nodeType).get(i); - - if (prev == null) { - prev = currentNode; - } - - Comparator comp = currentNode.getComparator(); - Map sort = fForwardSort; - - if ((direction == -1) && (currentNode.getBackComparator() != null)) { - comp = currentNode.getBackComparator(); - sort = fBackwardSort; - } - - if (i < fNodes.get(nodeType).size() - 1) { - GraphNode next = fNodes.get(nodeType).get(i + 1); - - if ((comp != null) && (comp.compare(currentNode, next) > 0)) { - sort.put(nodeType, Boolean.TRUE); - } - } - if (direction == 1) { - if (fNodes.get(nodeType).get(i).positiveDistanceToPoint(x, y)) { - break; - } - } else { - if (currentNode.getBackComparator() == null) { - if // (currentNode.isVisible(x,y,width,height) - (!currentNode.positiveDistanceToPoint(x, y)) { - break; - } - } else { - if (currentNode.isVisible(x, y, width, height) && !currentNode.positiveDistanceToPoint(x, y)) { - if ((comp != null) && (comp.compare(currentNode, prev) <= 0)) { - break; - } - } else if ((comp != null) && (comp.compare(currentNode, prev) <= 0)) { - prev = currentNode; - } - } - } - } - - fNodes.put(nodeType, fForwardNodes.get(nodeType)); - if ((fBackwardNodes.get(nodeType) != null) && (direction == -1)) { - // nodes.put(nodeType,fnodes.get(nodeType)); - int index = fIndexes.get(nodeType).intValue(); - List list = fNodes.get(nodeType); - List backList = fBackwardNodes.get(nodeType); - GraphNode currentNode = (backList.get(index)); - if (index > 0) { - index = Arrays.binarySearch(list.toArray(new GraphNode[list.size()]), backList.get(index), currentNode.getComparator()); - if (index < 0) { - index = 0; - } - fIndexes.put(nodeType, Integer.valueOf(index)); - } - } - - for (int i = drawIndex; i < fNodes.get(nodeType).size() && i >= 0; i++) { - GraphNode toDraw = fNodes.get(nodeType).get(i); - toDraw.updateIndex(x, y, width, height); - if (!toDraw.isVisible(x, y, width, height)) { - break; - } - } - } - if (TmfUiTracer.isIndexTraced()) { - TmfUiTracer.traceIndex("First drawn " + nodeType + " index = " + drawIndex + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - TmfUiTracer.traceIndex(nodeType + " found in " + 0 + " iterations\n"); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - if (TmfUiTracer.isIndexTraced()) { - TmfUiTracer.traceIndex("*****************************\n"); //$NON-NLS-1$ - } - } - - /** - * Draws the children nodes on the given context.
- * This method start width GraphNodes ordering if needed.
- * After, depending on the visible area, only visible GraphNodes are drawn.
- * - * @param context the context to draw to - * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#draw(IGC) - */ - protected void drawChildenNodes(IGC context) { - - if (!fHasChilden) { - return; - } - // If the nodes have not been added ordered, the array is ordered - Iterator it = fForwardSort.keySet().iterator(); - while (it.hasNext()) { - String nodeType = it.next(); - boolean sort = fForwardSort.get(nodeType).booleanValue(); - if (sort) { - GraphNode[] temp = fForwardNodes.get(nodeType).toArray(new GraphNode[fForwardNodes.get(nodeType).size()]); - GraphNode node = fNodes.get(nodeType).get(0); - Arrays.sort(temp, node.getComparator()); - fForwardSort.put(nodeType, Boolean.FALSE); - fNodes.put(nodeType, Arrays.asList(temp)); - fForwardNodes.put(nodeType, Arrays.asList(temp)); - if (TmfUiTracer.isSortingTraced()) { - TmfUiTracer.traceSorting(nodeType + " array sorted\n"); //$NON-NLS-1$ - } - } - } - - Iterator it2 = fBackwardSort.keySet().iterator(); - while (it2.hasNext()) { - String nodeType = it2.next(); - boolean sort = fBackwardSort.get(nodeType).booleanValue(); - if (sort) { - GraphNode[] temp = fBackwardNodes.get(nodeType).toArray(new GraphNode[fBackwardNodes.get(nodeType).size()]); - GraphNode node = fNodes.get(nodeType).get(0); - Arrays.sort(temp, node.getBackComparator()); - fBackwardSort.put(nodeType, Boolean.FALSE); - fBackwardNodes.put(nodeType, Arrays.asList(temp)); - if (TmfUiTracer.isSortingTraced()) { - TmfUiTracer.traceSorting(nodeType + " back array sorted\n"); //$NON-NLS-1$ - } - } - } - - if (TmfUiTracer.isDisplayTraced()) { - TmfUiTracer.traceDisplay("*****************************\n"); //$NON-NLS-1$ - } - - int arrayStep = 1; - if ((Metrics.getMessageFontHeigth() + Metrics.MESSAGES_NAME_SPACING * 2) * context.getZoom() < Metrics.MESSAGE_SIGNIFICANT_VSPACING) { - arrayStep = Math.round(Metrics.MESSAGE_SIGNIFICANT_VSPACING / ((Metrics.getMessageFontHeigth() + Metrics.MESSAGES_NAME_SPACING * 2) * context.getZoom())); - } - - int count = 0; - Iterator it3 = fForwardSort.keySet().iterator(); - while (it3.hasNext()) { - count = 0; - Object nodeType = it3.next(); - GraphNode node = fNodes.get(nodeType).get(0); - context.setFont(SDViewPref.getInstance().getFont(node.fPrefId)); - int index = fIndexes.get(nodeType).intValue(); - count = drawNodes(context, fNodes.get(nodeType), index, arrayStep); - if (TmfUiTracer.isDisplayTraced()) { - TmfUiTracer.traceDisplay(count + " " + nodeType + " drawn, starting from index " + index + "\r\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - } - if (TmfUiTracer.isDisplayTraced()) { - TmfUiTracer.traceDisplay("*****************************\n"); //$NON-NLS-1$ - } - - } - - /** - * Draw the GraphNode stored in the given list, starting at index startIndex with the given step - * - * @param context the context to draw to - * @param list the GraphNodes list - * @param startIndex the start index - * @param step the step to browse the list - * @return the number of GraphNodes drawn - */ - protected int drawNodes(IGC context, List list, int startIndex, int step) { - if (!fHasChilden) { - return 0; - } - - GraphNode last = null; - int nodesCount = 0; - if (list.size() < 0) { - return 0; - } - - GraphNode node = list.get(0); - context.setFont(SDViewPref.getInstance().getFont(node.fPrefId)); - Comparator comparator = node.getComparator(); - for (int i = startIndex; i < list.size(); i = i + step) { - GraphNode toDraw = list.get(i); - if (i < list.size() - 1) { - GraphNode next = list.get(i + 1); - if ((comparator != null) && (comparator.compare(toDraw, next) > 0)) { - fForwardSort.put(next.getArrayId(), Boolean.TRUE); - } - } - int cx = context.getContentsX(); - int cy = context.getContentsY(); - int cw = context.getVisibleWidth(); - int ch = context.getVisibleHeight(); - // The arrays should be ordered, no needs to continue for this one - if (!toDraw.isVisible(cx, cy, cw, ch) && toDraw.positiveDistanceToPoint(cx + cw, cy + ch)) { - break; - } - // ***Common*** nodes visibility - if ((!toDraw.isSameAs(last) || toDraw.isSelected()) && (toDraw.isVisible(context.getContentsX(), context.getContentsY(), context.getVisibleWidth(), context.getVisibleHeight()))) { - nodesCount++; - - toDraw.draw(context); - if (hasFocus()) { - toDraw.drawFocus(context); - } - } - last = toDraw; - } - return nodesCount; - } - - /** - * Draws the focus within the graphical context. - * - * @param context - * The context - */ - public void drawFocus(IGC context) { - context.drawFocus(getX(), getY(), getWidth(), getHeight()); - } - - /** - * Determine if the given point (px,py) is contained in the rectangle (x,y,width,height) - * - * @param x the rectangle x coordinate - * @param y the rectangle y coordinate - * @param width the rectangle width - * @param height the rectangle height - * @param px the x coordinate of the point to test - * @param py the y coordinate of the point to test - * @return true if contained false otherwise - */ - public static boolean contains(int x, int y, int width, int height, int px, int py) { - int locX = x; - int locY = y; - int locWidth = width; - int locHeight = height; - - if (width < 0) { - locX = locX + width; - locWidth = -locWidth; - } - - if (height < 0) { - locY = locY + height; - locHeight = -locHeight; - } - return (px >= locX) && (py >= locY) && ((px - locX) <= locWidth) && ((py - locY) <= locHeight); - } - - /** - * Sets the start event occurrence attached to this graphNode. - * - * @param occurence - * the start event occurrence attached to the graphNode - * @since 2.0 - */ - protected void setStartOccurrence(int occurence) { - fStartEventOccurrence = occurence; - } - - /** - * Sets the end event occurrence attached to this graphNode - * - * @param occurence - * the start event occurrence attached to the graphNode - * @since 2.0 - */ - protected void setEndOccurrence(int occurence) { - fEndEventOccurrence = occurence; - } - - /** - * Sets the color preference id - * @param id - * The color preference id - * @since 2.0 - */ - protected void setColorPrefId(String id) { - fPrefId = id; - } - - /** - * Gets the color preference id - * @return the color preference id - * @since 2.0 - */ - protected String getColorPrefId() { - return fPrefId; - } - - /** - * @return if node has children or not - * @since 2.0 - */ - protected boolean hasChildren() { - return fHasChilden; - } - - /** - * Sets the flag indicating where the node has children or not. - * @param hasChildren - * if node has children or not - * @since 2.0 - */ - protected void hasChildren(boolean hasChildren) { - fHasChilden = hasChildren; - } - /** - * Returns a map from node name to graph node. - * - * @return map with children graph bodes - * @since 2.0 - */ - protected Map> getNodeMap() { - return fNodes; - } - /** - * Returns a map from node name to graph node for forward sorting - * - * @return forward sorting map - * @since 2.0 - */ - protected Map> getForwardNodes() { - return fForwardNodes; - } - /** - * Returns a map from node name to graph node for backwards sorting. - * - * @return backwards sorting map - * @since 2.0 - */ - protected Map> getBackwardNodes() { - return fBackwardNodes; - } - /** - * Returns a map from node name to index. - * - * @return map with node name to index - * @since 2.0 - */ - protected Map getIndexes() { - return fIndexes; - } - - /** - * Returns a map from node name to sort flag for forwards sorting. - * @return a map from node name to sort flag - * @since 2.0 - */ - protected Map getForwardSortMap() { - return fForwardSort; - } - /** - * Returns a map from node name to flag for backwards sorting. - * @return map from node name to flag for backwards sorting. - * @since 2.0 - */ - protected Map getBackwardSortMap() { - return fBackwardSort; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/HotSpot.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/HotSpot.java deleted file mode 100755 index 1424462203..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/HotSpot.java +++ /dev/null @@ -1,193 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IImage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.ISDPreferences; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; - -/** - * Class to add a hot spot marker. - * - * @version 1.0 - * @author sveyrier - */ -public class HotSpot extends GraphNode { - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The grahNode ID constant - */ - public static final String GLYPH = "Glyph"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The execution occurrence the hot spot marker is for. - */ - private BasicExecutionOccurrence fExecOcc = null; - /** - * The occurrence number. - */ - private int fOccurrence = 0; - /** - * The marker image to display. - */ - private IImage fImage = null; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - public HotSpot() { - setColorPrefId(ISDPreferences.PREF_EXEC); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - /** - * Set the marker image. - * - * @param img A image to set - */ - public void setImage(IImage img) { - fImage = img; - } - - /** - * Returns the marker image. - * - * @return the image - * @since 2.0 - */ - protected IImage getImage() { - return fImage; - } - - @Override - public int getX() { - if (fExecOcc != null) { - return fExecOcc.getX() - 3; - } - return 0; - } - - @Override - public int getY() { - if (fExecOcc != null){ - return fExecOcc.getY(); - } - return 0; - } - - @Override - public int getWidth() { - if (fExecOcc != null) { - return fExecOcc.getWidth() + 7; - } - return 0; - } - - @Override - public int getHeight() { - if (fExecOcc != null) { - return fExecOcc.getWidth() + 10; - } - return 0; - } - - /** - * Set the lifeline on which the execution occurrence appears. - * - * @param occ the parent lifeline - */ - public void setExecution(BasicExecutionOccurrence occ) { - fExecOcc = occ; - fExecOcc.addNode(this); - } - - /** - * Get the lifeline on which the execution occurrence appears. - * - * @return - the parent lifeline - */ - public BasicExecutionOccurrence getExecOcc() { - return fExecOcc; - } - - /** - * Returns the occurrence number. - * - * @return the occurrence number. - */ - public int getOccurrence() { - return fOccurrence; - } - - /** - * Set the occurrence number. - * - * @param occ A number to set. - */ - public void setOccurrence(int occ) { - fOccurrence = occ; - } - - @Override - public void draw(IGC context) { - - ISDPreferences pref = SDViewPref.getInstance(); - - // The execution occurrence is selected - // if the owning lifeline is selected - if (isSelected() || (fExecOcc != null && fExecOcc.isSelected()) || (fExecOcc != null && fExecOcc.getLifeline() != null && fExecOcc.getLifeline().isSelected())) { - context.setBackground(pref.getBackGroundColorSelection()); - context.setForeground(pref.getForeGroundColorSelection()); - } else { - context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_EXEC)); - context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_EXEC)); - } - context.drawImage(fImage, getX(), getY(), getWidth(), getHeight()); - } - - @Override - public String getArrayId() { - return GLYPH; - } - - @Override - public boolean isVisible(int x, int y, int width, int height) { - return true; - } - - @Override - public boolean contains(int xValue, int yValue) { - int x = getX(); - int y = getY(); - int width = getWidth(); - int height = getHeight(); - - if (GraphNode.contains(x, y, width, height, xValue, yValue)) { - return true; - } - return false; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/ITimeRange.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/ITimeRange.java deleted file mode 100755 index 8164fe6b7b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/ITimeRange.java +++ /dev/null @@ -1,46 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; - -/** - * A interface for handling time ranges. - * - * @version 1.0 - * @author sveyrier - */ -public interface ITimeRange { - - /** - * Returns the time when the message began. - * @return the time when the message began - * @since 2.0 - */ - ITmfTimestamp getStartTime(); - - /** - * Returns the time when the message ended. - * - * @return the time when the message ended - * @since 2.0 - */ - ITmfTimestamp getEndTime(); - - /** - * Returns flag to indicate whether time information is available or not. - * - * @return flag to indicate whether time information is available or not - */ - boolean hasTimeInfo(); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/Lifeline.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/Lifeline.java deleted file mode 100755 index ff77a30ec7..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/Lifeline.java +++ /dev/null @@ -1,534 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IImage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.ISDPreferences; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; - -/** - * Lifeline is the UML2 lifeline graphical representation.
- * Each lifeline owns a set of event occurrences. An event occurrence is the base element in UML2 to set an event in a - * sequence diagram.
- * Event occurrence define the drawing order of graph node along a lifeline. In this lifeline implementation, event - * occurrences are just integer index. The event occurrences with the same value on different lifelines will correspond - * the same y coordinate value. - * - * @version 1.0 - * @author sveyrier - * - */ -public class Lifeline extends GraphNode { - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The life line tag. - */ - public static final String LIFELINE_TAG = "Lifeline"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attribute - // ------------------------------------------------------------------------ - /** - * The lifeline position in the containing frame - */ - private int fIndexInFrame = 0; - /** - * The frame where the lifeline is drawn - */ - private Frame fFrame = null; - /** - * The current event occurrence created in the lifeline - */ - private int fEventOccurrence = 0; - /** - * The lifeline category. - */ - private int fCategory = -1; - /** - * Flag whether lifeline has time information available or not - */ - private boolean fHasTimeInfo = false; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor - */ - public Lifeline() { - setColorPrefId(ISDPreferences.PREF_LIFELINE); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public int getX() { - return Metrics.FRAME_H_MARGIN + Metrics.LIFELINE_H_MAGIN + (fIndexInFrame - 1) * Metrics.swimmingLaneWidth(); - } - - @Override - public int getY() { - return 2 * Metrics.FRAME_NAME_H_MARGIN + Metrics.LIFELINE_VT_MAGIN / 2 + Metrics.getFrameFontHeigth() + Metrics.getLifelineHeaderFontHeigth() + Metrics.FRAME_V_MARGIN + 2 * Metrics.LIFELINE_HEARDER_TEXT_V_MARGIN; - } - - @Override - public int getWidth() { - return Metrics.getLifelineWidth(); - } - - @Override - public int getHeight() { - // Set room for two text lines - return Metrics.getLifelineFontHeigth()/** 2 */ - + 2 * Metrics.LIFELINE_NAME_H_MARGIN; - } - - /** - * Set the lifeline category for this lifeline. - * - * @param arrayIndex the index of the category to use - * @see Frame#setLifelineCategories(LifelineCategories[]) - */ - public void setCategory(int arrayIndex) { - fCategory = arrayIndex; - } - - /** - * Gets the lifeline category for this lifeline. - * - * @return arrayIndex the index of the category to use - * @since 2.0 - */ - public int getCategory() { - return fCategory; - } - - /** - * Returns the tooltip text for the lifeline. It is the combination between the category name(if any) and the - * lifeline name - * - * @return the tooltip text - */ - public String getToolTipText() { - if (fCategory >= 0) { - LifelineCategories[] categories = fFrame.getLifelineCategories(); - if (fCategory < categories.length) { - return categories[fCategory].getName() + " " + getName(); //$NON-NLS-1$ - } - } - return ""; //$NON-NLS-1$ - } - - /** - * Returns the index of the first visible Execution Occurrence in the execution occurrence array.
- * Execution Occurrences are Y ordered in this array - * - * @return the first visible Execution Occurrence - */ - public int getExecOccurrenceDrawIndex() { - if (!hasChildren()) { - return 0; - } - if (getIndexes().get(BasicExecutionOccurrence.EXEC_OCC_TAG) != null) { - return getIndexes().get(BasicExecutionOccurrence.EXEC_OCC_TAG).intValue(); - } - return 0; - } - - /** - * Set the frame on which this lifeline must be drawn - * - * @param parentFrame - * Parent frame - */ - protected void setFrame(Frame parentFrame) { - fFrame = parentFrame; - if (fHasTimeInfo) { - fFrame.setHasTimeInfo(true); - } - if (fFrame.getMaxEventOccurrence() < getEventOccurrence() + 1) { - fFrame.setMaxEventOccurrence(getEventOccurrence() + 1); - } - } - - /** - * Returns the frame which this lifeline is drawn - * - * @return the Frame - */ - protected Frame getFrame() { - return fFrame; - } - - /** - * Set the lifeline position index in the containing frame - * - * @param index the lifeline X position - */ - protected void setIndex(int index) { - fIndexInFrame = index; - } - - /** - * Returns the lifeline position in de the containing frame - * - * @return the X position - */ - public int getIndex() { - return fIndexInFrame; - } - - /** - * Set the lifeline event occurrence to the value given in parameter This only change the current event occurrence, - * greater event created on this lifeline are still valid and usable. This also need to inform the frame of the - * operation mostly to store in the frame the greater event found in the diagram (used to determine the frame - * height) - * - * @param eventOcc the new current event occurrence - */ - public void setCurrentEventOccurrence(int eventOcc) { - if ((fFrame != null) && (fFrame.getMaxEventOccurrence() < eventOcc)) { - fFrame.setMaxEventOccurrence(eventOcc); - } - fEventOccurrence = eventOcc; - } - - /** - * Returns the last created event occurrence along the lifeline. - * - * @return the current event occurrence - */ - public int getEventOccurrence() { - return fEventOccurrence; - } - - /** - * Creates a new event occurrence along the lifeline. - * - * @return the new created event occurrence - */ - public int getNewEventOccurrence() { - setCurrentEventOccurrence(fEventOccurrence + 1); - return fEventOccurrence; - } - - /** - * Adds the execution occurrence given in parameter to the lifeline.
- * A Execution occurrence is never drawn in the frame instead it is added to a lifeline - * - * @param exec the execution occurrence to add - */ - public void addExecution(BasicExecutionOccurrence exec) { - exec.setLifeline(this); - addNode(exec); - if ((fFrame != null) && (fFrame.getMaxEventOccurrence() < exec.getEndOccurrence())) { - fFrame.setMaxEventOccurrence(exec.getEndOccurrence()); - } - } - - /** - * Set whether lifeline has time information available or not. - * @param value The value to set - */ - protected void setTimeInfo(boolean value) { - fHasTimeInfo = value; - if ((fFrame != null) && value) { - fFrame.setHasTimeInfo(value); - } - } - - /** - * Returns true if at least one execution occurrence has time info. - * - * @return true if at least one execution occurrence has time info - */ - public boolean hasTimeInfo() { - return fHasTimeInfo; - } - - /** - * Returns the list of execution occurrence on this lifeline. - * - * @return the execution occurrence list - */ - public List getExecutions() { - if (hasChildren()) { - return getNodeMap().get(BasicExecutionOccurrence.EXEC_OCC_TAG); - } - return new ArrayList<>(); - } - - @Override - public boolean contains(int xValue, int yValue) { - int x = getX(); - int y = getY(); - int width = getWidth(); - int height = getHeight(); - - if (fFrame == null) { - return false; - } - if (GraphNode.contains(x, y, width, height, xValue, yValue)) { - return true; - } - if (GraphNode.contains(x + Metrics.getLifelineWidth() / 2 - Metrics.EXECUTION_OCCURRENCE_WIDTH / 2, y + height, Metrics.EXECUTION_OCCURRENCE_WIDTH, (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * fFrame.getMaxEventOccurrence() - + Metrics.LIFELINE_VB_MAGIN - 4, xValue, yValue)) { - return true; - } - - height = Metrics.getLifelineFontHeigth() + 2 * Metrics.LIFELINE_HEARDER_TEXT_V_MARGIN; - int hMargin = (Metrics.LIFELINE_VT_MAGIN - height) / 2; - - if (hMargin >= 2) { - if (fFrame.getVisibleAreaY() < y - height - hMargin) { - if (GraphNode.contains(x - Metrics.LIFELINE_SPACING / 2 + 1, y - height - hMargin, Metrics.swimmingLaneWidth() - 2, height + 1, xValue, yValue)) { - return true; - } - } else { - if (GraphNode.contains(x - Metrics.LIFELINE_SPACING / 2 + 1, fFrame.getVisibleAreaY(), Metrics.swimmingLaneWidth() - 2, height, xValue, yValue)) { - return true; - } - } - } - if (getNodeAt(xValue, yValue) != null) { - return true; - } - return false; - } - - /** - * Returns the lifeline visibility for the given visible area - * - * @param vx The x coordinate of the visible area - * @param vy The y coordinate of the visible area - * @param vwidth The width of the visible area - * @param vheight The height of the visible area - * @return true if visible false otherwise - */ - @Override - public boolean isVisible(int vx, int vy, int vwidth, int vheight) { - int x = getX(); - int width = getWidth(); - if (((x >= vx) && (x <= vx + vwidth)) || ((x + width >= vx) && (x <= vx))) { - return true; - } - return false; - } - - /** - * Draws the name within the graphical context. - * - * @param context The graphical context. - */ - protected void drawName(IGC context) { - ISDPreferences pref = SDViewPref.getInstance(); - - int x = getX(); - int y = getY(); - int height = Metrics.getLifelineHeaderFontHeigth() + 2 * Metrics.LIFELINE_HEARDER_TEXT_V_MARGIN; - int hMargin = Metrics.LIFELINE_VT_MAGIN / 4;// (Metrics.LIFELINE_NAME_H_MARGIN)/2; - - context.setLineStyle(context.getLineSolidStyle()); - context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_LIFELINE_HEADER)); - context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_LIFELINE_HEADER)); - context.setFont(pref.getFont(ISDPreferences.PREF_LIFELINE_HEADER)); - if (hMargin >= 0) { - if (fFrame.getVisibleAreaY() < y - height - hMargin) { - context.fillRectangle(x - Metrics.LIFELINE_SPACING / 2 + 1, y - height - hMargin, Metrics.swimmingLaneWidth() - 2, height); - context.drawRectangle(x - Metrics.LIFELINE_SPACING / 2 + 1, y - height - hMargin, Metrics.swimmingLaneWidth() - 2, height); - context.setForeground(pref.getFontColor(ISDPreferences.PREF_LIFELINE_HEADER)); - context.drawTextTruncatedCentred(getName(), x + Metrics.LIFELINE_NAME_V_MARGIN - Metrics.LIFELINE_SPACING / 2 + 1, y - height - hMargin, Metrics.swimmingLaneWidth() - 2 * Metrics.LIFELINE_NAME_V_MARGIN - 2, height, true); - } else { - context.fillRectangle(x - Metrics.LIFELINE_SPACING / 2 + 1, fFrame.getVisibleAreaY(), Metrics.swimmingLaneWidth() - 2, height); - context.drawRectangle(x - Metrics.LIFELINE_SPACING / 2 + 1, fFrame.getVisibleAreaY(), Metrics.swimmingLaneWidth() - 2, height); - context.setForeground(pref.getFontColor(ISDPreferences.PREF_LIFELINE_HEADER)); - context.drawTextTruncatedCentred(getName(), x - Metrics.LIFELINE_SPACING / 2 + Metrics.LIFELINE_NAME_V_MARGIN + 1, fFrame.getVisibleAreaY(), Metrics.swimmingLaneWidth() - 2 * Metrics.LIFELINE_NAME_V_MARGIN - 2, height, true); - } - } - } - - /** - * Force the lifeline to be drawn at the given coordinate - * - * @param context - the context to draw into - * @param x - the x coordinate - * @param y - the y coordinate - */ - public void draw(IGC context, int x, int y) { - - ISDPreferences pref = SDViewPref.getInstance(); - - // Set the draw color depending if the lifeline must be selected or not - context.setLineWidth(Metrics.NORMAL_LINE_WIDTH); - if (isSelected()) { - if (pref.useGradienColor()) { - context.setGradientColor(pref.getBackGroundColor(ISDPreferences.PREF_LIFELINE)); - } - context.setBackground(pref.getBackGroundColorSelection()); - context.setForeground(pref.getForeGroundColorSelection()); - } else { - if (pref.useGradienColor()) { - context.setGradientColor(pref.getBackGroundColor(ISDPreferences.PREF_LIFELINE)); - context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_FRAME)); - } else { - context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_LIFELINE)); - } - context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_LIFELINE)); - } - // Store the lifeline coordinates to save some calls - int width = getWidth(); - int height = getHeight(); - - // Draw the rectangle which contain the lifeline name - if (pref.useGradienColor()) { - context.fillGradientRectangle(x, y, width, height / 2 - 7, true); - context.fillRectangle(x, y + height / 2 - 8, width, +height / 2 - 5); - context.fillGradientRectangle(x, y + height, width, -height / 2 + 6, true); - } else { - context.fillRectangle(x, y, width, height); - } - context.drawRectangle(x, y, width, height); - - if (fCategory >= 0) { - LifelineCategories[] categories = fFrame.getLifelineCategories(); - if (fCategory < categories.length) { - IImage image = categories[fCategory].getImage(); - if (image != null) { - context.drawImage(image, x, y, width, height); - } - } - } - - // Draw the lifeline label into the rectangle - // The label is truncated if it cannot fit - IColor temp = context.getForeground(); - context.setFont(pref.getFont(ISDPreferences.PREF_LIFELINE)); - context.setForeground(pref.getFontColor(ISDPreferences.PREF_LIFELINE)); - context.drawTextTruncatedCentred(getName(), x + Metrics.LIFELINE_NAME_V_MARGIN, y, Metrics.getLifelineWidth() - 2 * Metrics.LIFELINE_NAME_V_MARGIN, height, true); - - context.setLineStyle(context.getLineDashStyle()); - context.setForeground(temp); - int oldStyle = context.getLineStyle(); - - // Now draw the lifeline vertical line - // this line height depends on a stop assignment - // if there is no stop the line is drawn to the bottom of the frame - - // by default set the height to reach the frame bottom - int dashedLineEnd = y + height + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * fFrame.getMaxEventOccurrence() + Metrics.LIFELINE_VB_MAGIN; - /* - * if (stop != null) { dashedLineEnd = stop.getY(); } - */ - - if (isSelected()) { - context.setForeground(pref.getBackGroundColorSelection()); - context.setLineWidth(5); - context.drawLine(x + Metrics.getLifelineWidth() / 2, y + height, x + Metrics.getLifelineWidth() / 2, dashedLineEnd - 4); - context.setForeground(pref.getForeGroundColorSelection()); - } - - context.setLineWidth(Metrics.NORMAL_LINE_WIDTH); - context.drawLine(x + Metrics.getLifelineWidth() / 2, y + height, x + Metrics.getLifelineWidth() / 2, dashedLineEnd - 4); - context.drawLine(x + Metrics.getLifelineWidth() / 2, y + height, x + Metrics.getLifelineWidth() / 2, dashedLineEnd - 4); - context.setLineStyle(oldStyle); - - context.setLineStyle(context.getLineSolidStyle()); - - if (hasFocus()) { - drawFocus(context); - } - - super.drawChildenNodes(context); - } - - /** - * Draws the select execution occurrence region using the given color - * - * @param context the graphical context - * @param startEvent the region start - * @param nbEvent the region height - * @param color the color to use - */ - public void highlightExecOccurrenceRegion(IGC context, int startEvent, int nbEvent, IColor color) { - IColor backupColor = context.getBackground(); - context.setBackground(color); - int x = getX() + Metrics.getLifelineWidth() / 2 - Metrics.EXECUTION_OCCURRENCE_WIDTH / 2; - int y = getY() + getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * startEvent; - int width = Metrics.EXECUTION_OCCURRENCE_WIDTH; - int height = ((Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing())) * nbEvent; - context.fillRectangle(x, y, width, height); - context.setBackground(backupColor); - } - - @Override - public void draw(IGC context) { - draw(context, getX(), getY()); - } - - @Override - public String getArrayId() { - return LIFELINE_TAG; - } - - @Override - public boolean positiveDistanceToPoint(int x, int y) { - if (getX() > x - Metrics.swimmingLaneWidth()) { - return true; - } - return false; - } - - @Override - public GraphNode getNodeAt(int x, int y) { - int vy = 0; - int vh = 0; - if (getFrame() != null) { - vy = getFrame().getVisibleAreaY(); - vh = getFrame().getVisibleAreaHeight(); - } else { - return null; - } - if (getExecutions() == null) { - return null; - } - for (int i = getExecOccurrenceDrawIndex(); i < getExecutions().size(); i++) { - GraphNode node = getExecutions().get(i); - if (node.getHeight() < 0) { - if (node.getY() + node.getHeight() > vy + vh) { - break; - } - } else { - if (node.getY() > vy + vh) { - break; - } - } - if (node.contains(x, y)) { - GraphNode internal = node.getNodeAt(x, y); - if (internal != null) { - return internal; - } - return node; - } - } - return null; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/LifelineCategories.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/LifelineCategories.java deleted file mode 100755 index 7fd02a0625..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/LifelineCategories.java +++ /dev/null @@ -1,81 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IImage; - -/** - *

- * LifelineCategories is used to assign additional description for - * lifelines of the same type. This consists in providing a type name and an icon. - * The icon will be displayed in the rectangle which contains the lifeline name. - * The category name is only display in the lifeline tooltip. - *

- * - * @version 1.0 - * @author sveyrier - */ -public class LifelineCategories { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The category name - */ - private String fName = null; - /** - * The category image - */ - private IImage fCategoryImage = null; - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - /** - * Returns the category name. - * - * @return the category name - */ - public String getName() { - return fName; - } - - /** - * Sets the category name. - * - * @param string the name - */ - public void setName(String string) { - fName = string; - } - - /** - * Returns the category icon. - * - * @return the category icon - */ - public IImage getImage() { - return fCategoryImage; - } - - /** - * Sets the category icon. - * - * @param image the icon - */ - public void setImage(IImage image) { - fCategoryImage = image; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/Metrics.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/Metrics.java deleted file mode 100755 index a4d3d4d833..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/Metrics.java +++ /dev/null @@ -1,332 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2012 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; - -/** - * This class contains the metrics used to layout a sequence diagram on a view The class method are mostly used in - * combination with the preferences - * - * @version 1.0 - * @author sveyrier - * - */ -public class Metrics { - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * Space between the Frame and the top of the View This also represent the space between the frame and the bottom of - * the View - */ - public static final int FRAME_H_MARGIN = 10; - /** - * Space between the Frame and the left of the View This also represent the space between the Frame and the right of - * the View - */ - public static final int FRAME_V_MARGIN = 10; - /** - * Space between the Lifelines and the right of the Frame - */ - public static final int LIFELINE_H_MAGIN = 23; - /** - * Space between the Lifelines and the bottom of the Frame - */ - public static final int LIFELINE_VB_MAGIN = 20; - /** - * Space between the Lifelines and the top of the Frame - */ - public static final int LIFELINE_VT_MAGIN = 30;// 18 - /** - * Vertical space between the lifeline name and the rectangle which contains that name This is only for the - * "always visible" lifeline name rectangle - */ - public static final int LIFELINE_HEARDER_TEXT_V_MARGIN = 4; - /** - * Vertical spacing between messages - */ - public static final int MESSAGES_SPACING = 30; - /** - * Vertical spacing between the message and its name - */ - public static final int MESSAGES_NAME_SPACING = 10; - /** - * Horizontal spacing between the Frame name and its containing rectangle - */ - public static final int FRAME_NAME_H_MARGIN = 4; - /** - * Vertical spacing between the Frame name and its containing rectangle - */ - public static final int FRAME_NAME_V_MARGIN = 8; - /** - * Horizontal spacing between the lifeline name and its containing rectangle - */ - public static final int LIFELINE_NAME_H_MARGIN = 14; - /** - * Vertical spacing between the lifeline name and its containing rectangle - */ - public static final int LIFELINE_NAME_V_MARGIN = 20; - /** - * Space between the rectangles which contain the Lifelines name - */ - public static final int LIFELINE_SPACING = 45; - /** - * The circle ray used to draw the circle which compose Found and Lost messages - */ - public static final int MESSAGE_CIRCLE_RAY = 5; - /** - * Execution occurrence vertical width - */ - public static final int EXECUTION_OCCURRENCE_WIDTH = 8; - /** - * The square width which contains the Stop representation (a cross) - */ - public static final int STOP_WIDTH = 20; - /** - * The internal message width. - */ - public static final int INTERNAL_MESSAGE_WIDTH = 20; - /** - * The internal sychrounous message height. - */ - public static final int SYNC_INTERNAL_MESSAGE_HEIGHT = 10; - /** - * Line width used when drawing selected GraphNode - */ - public static final int SELECTION_LINE_WIDTH = 5; - /** - * Line width used when drawing non selected GraphNode - */ - public static final int NORMAL_LINE_WIDTH = 1; - /** - * The internal vertical message margin - */ - public static final int INTERNAL_MESSAGE_V_MARGIN = 10; - - /** - * Used to sample the diagram. When the lifeline spacing is smaller than this constant when zooming out then less - * lifelines are displayed to avoid lifelines overlapping and mainly saving some execution time - */ - public static final int LIFELINE_SIGNIFICANT_HSPACING = 10; - /** - * Used to sample the diagram. When the message spacing is smaller than this constant when zooming out then less - * message are displayed to avoid message overlapping and mainly saving some execution time - */ - public static final int MESSAGE_SIGNIFICANT_VSPACING = 1; - /** - * Message selection tolerance. Used for internal syncMessages only - */ - public static final int MESSAGE_SELECTION_TOLERANCE = 30; - /** - * The focus drawing margin. - */ - public static final int FOCUS_DRAWING_MARGIN = 10; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The lifeline font height - */ - private static int fLifelineFontHeight = 0; - /** - * The message font height - */ - private static int fMessageFontHeight = 0; - /** - * The frame font height - */ - private static int fFrameFontHeight = 0; - /** - * The lifeline header font height - */ - private static int fLifelineHeaderFontHeight = 0; - /** - * The lifeline font widht - */ - private static int fLifelineFontWidth = 0; - /** - * The lifeline width - */ - private static int fLifeLineWidth = 119; - /** - * The (forced) event spacing - */ - private static int fForcedEventSpacing = -1; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - /** - * Constructor - * - * Hide private constructor - */ - private Metrics() { - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - /** - * Set the character height used to draw the lifeline name - * - * @param height the character height - */ - static public void setLifelineFontHeight(int height) { - fLifelineFontHeight = height; - } - - /** - * Set the character width used to draw the lifeline name - * - * @param width the character width - */ - static public void setLifelineFontWidth(int width) { - fLifelineFontWidth = width; - } - - /** - * Set the character height used to draw the message name - * - * @param fontHeight the character height - */ - static public void setMessageFontHeight(int fontHeight) { - fMessageFontHeight = fontHeight; - } - - /** - * Returns the character height used to draw the lifeline name - * - * @return the character height - */ - static public int getFrameFontHeigth() { - return fFrameFontHeight; - } - - /** - * Set the character height used to draw the message name - * - * @param fontHeight the character height - */ - static public void setFrameFontHeight(int fontHeight) { - fFrameFontHeight = fontHeight; - } - - /** - * Returns the character height used to draw the lifeline name - * - * @return the character height - */ - static public int getLifelineHeaderFontHeigth() { - return fLifelineHeaderFontHeight; - } - - /** - * Set the character height used to draw the message name - * - * @param fontHeight the character height - */ - static public void setLifelineHeaderFontHeight(int fontHeight) { - fLifelineHeaderFontHeight = fontHeight; - } - - /** - * Returns the character height used to draw the lifeline name - * - * @return the character height - */ - static public int getLifelineFontHeigth() { - return fLifelineFontHeight; - } - - /** - * Returns the character height used to draw the message name - * - * @return the character height - */ - static public int getMessageFontHeigth() { - if (fForcedEventSpacing >= 0) { - return 0; - } - return fMessageFontHeight; - } - - /** - * This is the vertical space used by a Lifeline (mostly the rectangle which contain its name) - * - * @return the vertical space used by a Lifeline - */ - static public int getLifelineWidth() { - return fLifeLineWidth; - } - - /** - * Set the vertical space used by a Lifeline (mostly the rectangle which contain its name) - * - * @param value the vertical space - */ - static public void setLifelineWidth(int value) { - fLifeLineWidth = value; - } - - /** - * Returns the swimming lane width - * - * @return the swimming lane width - */ - static public int swimmingLaneWidth() { - return getLifelineWidth() + LIFELINE_SPACING; - } - - /** - * Returns the character width used to draw the Lifelines name - * - * @return the average character width - */ - static public int getAverageCharWidth() { - return fLifelineFontWidth; - } - - /** - * Returns the message spacing. - * - * @return the message spacing - */ - static public int getMessagesSpacing() { - if (fForcedEventSpacing >= 0) { - return fForcedEventSpacing; - } - return MESSAGES_SPACING; - } - - /** - * Sets the forced event spacing value . - * - * @param eventSpacing - * The spacing value - */ - static public void setForcedEventSpacing(int eventSpacing) { - fForcedEventSpacing = eventSpacing; - } - - /** - * Gets the forced event spacing value. - * - * @return forcedEventSpacing - */ - static public int getForcedEventSpacing() { - return fForcedEventSpacing; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/SDTimeEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/SDTimeEvent.java deleted file mode 100755 index 54e6f4de11..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/SDTimeEvent.java +++ /dev/null @@ -1,91 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; - -/** - * Class implementation of a sequence diagram time event. - * - * @version 1.0 - * @author sveyrier - * - */ -public class SDTimeEvent { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The time stamp of the event - */ - private final ITmfTimestamp fTimestamp; - /** - * The event index. - */ - private final int fEvent; - /** - * The time range implementing node. - */ - private final ITimeRange fNode; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * The default constructor. - * - * @param time The time stamp of the event. - * @param event The event index. - * @param node The time range implementing node. - * @since 2.0 - */ - public SDTimeEvent(ITmfTimestamp time, int event, ITimeRange node) { - fTimestamp = time; - fEvent = event; - fNode = node; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - /** - * Returns the timestamp of the event. - * - * @return the timestamp of the event. - * @since 2.0 - */ - public ITmfTimestamp getTime() { - return fTimestamp; - } - - /** - * Returns the event index. - * - * @return the event index. - */ - public int getEvent() { - return fEvent; - } - - /** - * Returns the time range implementing node. - * - * @return the time range implementing node. - */ - public ITimeRange getGraphNode() { - return fNode; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/Stop.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/Stop.java deleted file mode 100755 index 0c7858beb2..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/Stop.java +++ /dev/null @@ -1,167 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.ISDPreferences; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; - -/** - *

- * It is the UML2 stop graphical representation in the sequence diagram viewer. - * This draw a cross on the lifeline. The stop y coordinate depend on the event occurrence when it appears. - * A stop is never drawn it is assigned to a lifeline. - *

- * - * @version 1.0 - * @author sveyrier - */ -public class Stop extends GraphNode { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The graphNode ID - */ - public static final String STOP = "STOP"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The owning lifeline on which the stop appears - */ - private Lifeline fLifeline = null; - /** - * This basically represents the time when the stop occurs on the owning Lifeline - * - * @see Lifeline Lifeline for more event occurence details - */ - private int fEventOccurrence = 0; - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public int getX() { - if (fLifeline == null) { - return 0; - } - return fLifeline.getX() + Metrics.getLifelineWidth() / 2 - Metrics.STOP_WIDTH / 2; - } - - @Override - public int getY() { - if (fLifeline == null) { - return 0; - } - return fLifeline.getY() + fLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * fEventOccurrence - Metrics.STOP_WIDTH / 2; - } - - @Override - public int getWidth() { - if (fLifeline == null) { - return 0; - } - return Metrics.STOP_WIDTH; - } - - @Override - public int getHeight() { - if (fLifeline == null) { - return 0; - } - return Metrics.STOP_WIDTH; - } - - /** - * Set the lifeline on which the stop must be draw - * - * @param theLifeline The the stop owing lifeline - */ - public void setLifeline(Lifeline theLifeline) { - fLifeline = theLifeline; - } - - /** - * Get the lifeline on which the stop must be draw - * - * @return the the stop owing lifeline - * @since 2.0 - */ - public Lifeline getLifeline() { - return fLifeline; - } - - /** - * Get the event occurrence when this stop appears - * - * @return the eventOccurence to assign to the stop - * @since 2.0 - */ - public int getEventOccurrence() { - return fEventOccurrence; - } - - /** - * Set the event occurrence when this stop appears - * - * @param occurrence the eventOccurence to assign to the stop - */ - public void setEventOccurrence(int occurrence) { - fEventOccurrence = occurrence; - } - - @Override - public void draw(IGC context) { - - ISDPreferences pref = SDViewPref.getInstance(); - - // Set the appropriate color depending if the graph node if selected or not - if (fLifeline.isSelected()) { - context.setForeground(pref.getBackGroundColorSelection()); - context.setLineWidth(Metrics.SELECTION_LINE_WIDTH); - int lastWidth = context.getLineWidth(); - context.setLineWidth(9); - // Draw a cross on the lifeline - context.drawLine(getX(), getY(), getX() + getWidth(), getY() + getHeight()); - context.drawLine(getX() + getWidth(), getY(), getX(), getY() + getHeight()); - // restore the context - context.setLineWidth(lastWidth); - context.setBackground(pref.getBackGroundColorSelection()); - context.setForeground(pref.getForeGroundColorSelection()); - } else { - context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_LIFELINE)); - context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_LIFELINE)); - } - int lastWidth = context.getLineWidth(); - context.setLineWidth(3); - // Draw a cross on the lifeline - context.drawLine(getX(), getY(), getX() + getWidth(), getY() + getHeight()); - context.drawLine(getX() + getWidth(), getY(), getX(), getY() + getHeight()); - // restore the context - context.setLineWidth(lastWidth); - } - - @Override - public String getArrayId() { - return STOP; - } - - @Override - public boolean contains(int x, int y) { - return false; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/SyncMessage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/SyncMessage.java deleted file mode 100755 index aece1f32f7..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/SyncMessage.java +++ /dev/null @@ -1,296 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; - -import java.util.Comparator; - -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.ISDPreferences; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.SortSyncMessageComparator; - -/** - * A SyncMessage is a synchronous message which appear at the same event occurrence on both lifeline ends (sender and - * receiver).
- * A Sync message is usually drawn horizontally.
- *
- *
- * Usage example: - * - *
- * Frame frame;
- * Lifeline lifeLine1;
- * Lifeline lifeLine2;
- *
- * SyncMessage message = new SyncMessage();
- * // Create a new event occurrence on each lifeline
- * lifeline1.getNewOccurrenceIndex();
- * lifeline2.getNewOccurrenceIndex();
- * // Set the message sender and receiver
- * message.setStartLifeline(lifeLine1);
- * message.setEndLifline(lifeline2);
- * message.setName("Message label");
- * // add the message to the frame
- * frame.addMessage(message);
- * 
- * - * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline Lifeline for more event occurence details - * @version 1.0 - * @author sveyrier - * - */ -public class SyncMessage extends BaseMessage implements ITimeRange { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The graphNode ID - */ - public static final String SYNC_MESS_TAG = "SyncMessage"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The associated message return - */ - private SyncMessageReturn fMessageReturn; - /** - * The time when the message occurs - */ - private ITmfTimestamp fEventTime = new TmfTimestamp(); - /** - * Flag whether the message has time information available or not - */ - private boolean fHasTimeInfo = false; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - public SyncMessage() { - setColorPrefId(ISDPreferences.PREF_SYNC_MESS); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - /** - * Ensure both lifelines have the same event occurrence (the greater found on each lifeline) - */ - protected void syncLifelinesEventOccurrence() { - if ((getStartLifeline() != null) && (getEndLifeline() != null)) { - int newIndex = 0; - if (getStartLifeline().getEventOccurrence() > getEndLifeline().getEventOccurrence()) { - newIndex = getStartLifeline().getEventOccurrence(); - } else { - newIndex = getEndLifeline().getEventOccurrence(); - } - getStartLifeline().setCurrentEventOccurrence(newIndex); - getEndLifeline().setCurrentEventOccurrence(newIndex); - setEventOccurrence(getStartLifeline().getEventOccurrence()); - } - } - - /** - * Set the lifeLine from which the message has been sent.
- * A new event occurrence will be created on this lifeLine.
- * SyncMessage must occur at the same event occurrence on both lifeline, this method is responsible to synchronize the - * event occurrence on each lifeline (the greater value will be used).
- * This synchronization is only done if the end lifeline has already been set. - * - * @param lifeline the message sender - */ - public void autoSetStartLifeline(Lifeline lifeline) { - lifeline.getNewEventOccurrence(); - setStartLifeline(lifeline); - } - - /** - * Set the lifeLine which has receiver the message.
- * A new EventOccurence will be create on this lifeLine.
- * SyncMessage must occur at the same event occurrence on both lifeline, this method is responsible to synchronize the - * event occurrence on each lifeline (the greater value will be used).
- * This synchronization is only done if the start lifeline has already been set. - * - * @param lifeline the message receiver - */ - public void autoSetEndLifeline(Lifeline lifeline) { - lifeline.getNewEventOccurrence(); - setEndLifeline(lifeline); - } - - /** - * Set the lifeLine which has receiver the message.
- * SyncMessage must occur at the same event occurrence on both lifeline, this method is responsible to synchronize the - * event occurrence on each lifeline (the greater value will be used).
- * This synchronization is only done if the start lifeline has already been set. - * - * @param lifeline the message receiver - */ - @Override - public void setStartLifeline(Lifeline lifeline) { - super.setStartLifeline(lifeline); - if ((getEndLifeline() == null)) { - setEventOccurrence(getStartLifeline().getEventOccurrence()); - } else { - syncLifelinesEventOccurrence(); - } - } - - /** - * Set the lifeLine which has receiver the message.
- * SyncMessage must occur at the same event occurrence on both lifelines, this method is responsible to synchronize the - * event occurrence on each lifeline (the greater value will be used).
- * This synchronization is only done if the start lifeline has already been set. - * - * @param lifeline the message receiver - */ - @Override - public void setEndLifeline(Lifeline lifeline) { - super.setEndLifeline(lifeline); - if ((getStartLifeline() == null)) { - setEventOccurrence(getEndLifeline().getEventOccurrence()); - } else { - syncLifelinesEventOccurrence(); - } - } - - /** - * Set the event occurrence when this message occurs.
- * - * @param occurrence the event occurrence to assign to this message.
- * @see Lifeline Lifeline for more event occurence details - */ - @Override - protected void setEventOccurrence(int occurrence) { - setStartOccurrence(occurrence); - setEndOccurrence(occurrence); - } - - /** - * Set the message return associated with this message. - * - * @param message the message return to associate - */ - protected void setMessageReturn(SyncMessageReturn message) { - fMessageReturn = message; - } - - /** - * Returns the syncMessageReturn associated to this syncMessage - * - * @return the message return - */ - public SyncMessageReturn getMessageReturn() { - return fMessageReturn; - } - - /** - * Set the time when the message occurs - * - * @param time the time when the message occurs - * @since 2.0 - */ - public void setTime(ITmfTimestamp time) { - fEventTime = time; - fHasTimeInfo = true; - if (getStartLifeline() != null && getStartLifeline().getFrame() != null) { - getStartLifeline().getFrame().setHasTimeInfo(true); - } else if (getEndLifeline() != null && getEndLifeline().getFrame() != null) { - getEndLifeline().getFrame().setHasTimeInfo(true); - } - } - - /** - * @since 2.0 - */ - @Override - public ITmfTimestamp getEndTime() { - return fEventTime; - } - - /** - * @since 2.0 - */ - @Override - public ITmfTimestamp getStartTime() { - return fEventTime; - } - - @Override - public boolean hasTimeInfo() { - return fHasTimeInfo; - } - - @Override - public void draw(IGC context) { - if (!isVisible()) { - return; - } - - ISDPreferences pref = SDViewPref.getInstance(); - - // Draw it selected? - if (!isSelected()) { - context.setBackground(pref.getBackGroundColor(getColorPrefId())); - context.setForeground(pref.getForeGroundColor(getColorPrefId())); - } - super.draw(context); - } - - @Override - public boolean isVisible(int x, int y, int width, int height) { - if (getY() > y + height + - // take into account the message name drawn above the arrow - Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth()) { - return false; - } - - // UML2 lost/found message visibility special case - // Others visibility cases are perform in the ***common*** case - if ((getEndLifeline() == null && getStartLifeline() != null) || (getEndLifeline() != null && getStartLifeline() == null)) { - if (x + width > getX() + getWidth() && x < getX() + getWidth()) { - return true; - } - } - // ***Common*** syncMessages visibility - return super.isVisible(x, y, width, height); - } - - @Override - public Comparator getComparator() { - return new SortSyncMessageComparator(); - } - - @Override - public String getArrayId() { - return SYNC_MESS_TAG; - } - - @Override - public boolean positiveDistanceToPoint(int x, int y) { - if (getY() > y) { - return true; - } - return false; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/SyncMessageReturn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/SyncMessageReturn.java deleted file mode 100755 index a0b665b9ad..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/core/SyncMessageReturn.java +++ /dev/null @@ -1,112 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.ISDPreferences; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; - -/** - * The message return graph node implementation.
- * This class differs on the SynMessage class only on the drawing line style (dashed instead of plain line).
- * Message return are generally associated to a message. This means, they are connected to the same lifelines than the - * associated message but in the opposite direction and for a different event occurrence.
- *
- * WARNING: The association validity is not checked, it is not necessary to provide a valid association, not even needed - * to set an association to drawn a message with a message return style.
- * - * - * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SyncMessage SyncMessage for usage example - * @version 1.0 - * @author sveyrier - * - */ -public class SyncMessageReturn extends SyncMessage { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The graphNode ID - */ - public static final String SYNC_MESS_RET_TAG = "SyncMessageRet"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The associated message(the message it is the return). - */ - private SyncMessage fMessage = null; - - // ------------------------------------------------------------------------ - // Constractors - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - public SyncMessageReturn() { - setColorPrefId(ISDPreferences.PREF_SYNC_MESS_RET); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - /** - * Set the associated message (the message it is the return).
- * Setting the association will activate the navigation in the default sequence diagram implementation to the - * message when the user right click on this message return.
- * - * @param parentMessage the message to associate - */ - public void setMessage(SyncMessage parentMessage) { - fMessage = parentMessage; - fMessage.setMessageReturn(this); - } - - /** - * Returns the syncMessage associated to this SyncMessageReturn - * - * @return the associated message - */ - public SyncMessage getMessage() { - return fMessage; - } - - @Override - public void draw(IGC context) { - if (!isVisible()) { - return; - } - - ISDPreferences pref = SDViewPref.getInstance(); - - int oldStyle = context.getLineStyle(); - // Message return are dashed - context.setLineStyle(context.getLineDotStyle()); - // Draw it selected? - if (!isSelected()) { - context.setBackground(pref.getBackGroundColor(getColorPrefId())); - context.setForeground(pref.getForeGroundColor(getColorPrefId())); - } - super.draw(context); - // restore the context - context.setLineStyle(oldStyle); - } - - @Override - public String getArrayId() { - return SYNC_MESS_RET_TAG; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/Criteria.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/Criteria.java deleted file mode 100755 index e3d30885d5..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/Criteria.java +++ /dev/null @@ -1,415 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -import org.eclipse.jface.dialogs.DialogSettings; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDFilterProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; - -/** - * This class describes the find or filter criteria selected by the user in the find or filter dialog box - * - * @version 1.0 - * @author sveyrier - * @author Bernd Hufmann - */ -public class Criteria { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * Flag whether lifeline is selected or not. - */ - private boolean fLifeLineSelected = false; - /** - * Flag whether synchronous message is selected or not. - */ - private boolean fSyncMessageSelected = false; - /** - * Flag whether synchronous message return is selected or not. - */ - private boolean fSyncMessageReturnSelected = false; - /** - * Flag whether asynchronous message is selected or not. - */ - private boolean fAsyncMessageSelected = false; - /** - * Flag whether asynchronous message return is selected or not. - */ - private boolean fAsyncMessageReturnSelected = false; - /** - * Flag whether case sensitive find is required or not. - */ - private boolean fCaseSenstiveSelected = false; - /** - * Flag whether stop graph node is selected or not. - */ - private boolean fStopSelected = false; - /** - * The find expression. - */ - private String fExpression = null; - /** - * The find pattern as regular expression. - */ - private Pattern pattern = null; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - public Criteria () { - } - - /** - * Copy constructor - * - * @param other Criteria to create new criteria - */ - public Criteria (Criteria other) { - this.fLifeLineSelected = other.fLifeLineSelected; - this.fSyncMessageSelected = other.fSyncMessageSelected; - this.fSyncMessageReturnSelected = other.fSyncMessageReturnSelected; - this.fAsyncMessageSelected = other.fAsyncMessageSelected; - this.fAsyncMessageReturnSelected = other.fAsyncMessageReturnSelected; - this.fCaseSenstiveSelected = other.fCaseSenstiveSelected; - this.fStopSelected = other.fStopSelected; - fExpression = other.fExpression; - updatePattern(); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - /** - * Returns true if the AsyncMessageReturn is selected, false otherwise. - * - * @return true if the AsyncMessageReturn is selected, false otherwise - */ - public boolean isAsyncMessageReturnSelected() { - return fAsyncMessageReturnSelected; - } - - /** - * Returns true if the AsyncMessage is selected, false otherwise. - * - * @return true if the AsyncMessage is selected, false otherwise - */ - public boolean isAsyncMessageSelected() { - return fAsyncMessageSelected; - } - - /** - * Returns the text enter by the user. - * - * @return the expression text - */ - public String getExpression() { - return fExpression; - } - - /** - * Returns the regular expression pattern. - * - * @return the regular expression pattern - */ - public Pattern getPattern() { - return pattern; - } - - /** - * Sets the regular expression pattern. - * - * @param pattern - * The pattern to set - */ - public void setPattern(Pattern pattern) { - this.pattern = pattern; - } - - /** - * Returns true if the LifeLine is selected, false otherwise. - * - * @return true if the LifeLine is selected, false otherwise - */ - public boolean isLifeLineSelected() { - return fLifeLineSelected; - } - - /** - * Returns true if the Stop is selected, false otherwise. - * - * @return true if the Stop is selected, false otherwise - */ - public boolean isStopSelected() { - return fStopSelected; - } - - /** - * Returns true if the SyncMessageReturn is selected, false otherwise. - * - * @return true if the SyncMessageReturn is selected, false otherwise - */ - public boolean isSyncMessageReturnSelected() { - return fSyncMessageReturnSelected; - } - - /** - * Returns true if the SyncMessage is selected, false otherwise. - * - * @return true if the SyncMessage is selected, false otherwise - */ - public boolean isSyncMessageSelected() { - return fSyncMessageSelected; - } - - /** - * Sets the AsyncMessageReturn selection state. - * - * @param b true if selected, false otherwise - */ - public void setAsyncMessageReturnSelected(boolean b) { - fAsyncMessageReturnSelected = b; - } - - /** - * Sets the AsyncMessage selection state. - * - * @param b true if selected, false otherwise - */ - public void setAsyncMessageSelected(boolean b) { - fAsyncMessageSelected = b; - } - - /** - * Sets the text entered by the user and compiles the regular expression. - * - * @param string the text - */ - public void setExpression(String string) { - fExpression = string; - updatePattern(); - } - - /** - * Sets the Stop selection state. - * - * @param b true if selected, false otherwise - */ - public void setLifeLineSelected(boolean b) { - fLifeLineSelected = b; - } - - /** - * Set Stop selection state. - * - * @param b true if selected, false otherwise - */ - public void setStopSelected(boolean b) { - fStopSelected = b; - } - - /** - * Sets the SyncMessageReturn selection state. - * - * @param b true if selected, false otherwise - */ - public void setSyncMessageReturnSelected(boolean b) { - fSyncMessageReturnSelected = b; - } - - /** - * Sets the SyncMessage selection state. - * - * @param b true if selected, false otherwise - */ - public void setSyncMessageSelected(boolean b) { - fSyncMessageSelected = b; - } - - /** - * Returns true if the case sensitive is selected, false otherwise. - * - * @return true if the case sensitive is selected, false otherwise - */ - public boolean isCaseSenstiveSelected() { - return fCaseSenstiveSelected; - } - - /** - * Set case sensitive selection state. - * - * @param b true if selected, false otherwise - */ - public void setCaseSenstiveSelected(boolean b) { - fCaseSenstiveSelected = b; - // Make sure that pattern is set - setExpression(fExpression); - } - - /** - * Compares this criteria with a given criteria. - * - * @param to The criteria to compare - * @return usual comparison result (< 0, 0, > 0) - */ - public boolean compareTo(Criteria to) { - boolean retVal = true; - if (getExpression() != null) { - retVal = getExpression().equals(to.getExpression()); - } else if (to.getExpression() != null) { - retVal = to.getExpression().equals(getExpression()); - } - return retVal && isCaseSenstiveSelected() == to.isCaseSenstiveSelected() && isAsyncMessageReturnSelected() == to.isAsyncMessageReturnSelected() && isAsyncMessageSelected() == to.isAsyncMessageSelected() - && isLifeLineSelected() == to.isLifeLineSelected() && isStopSelected() == to.isStopSelected() && isSyncMessageReturnSelected() == to.isSyncMessageReturnSelected() && isSyncMessageSelected() == to.isSyncMessageSelected(); - } - - /** - * Saves current criteria attributes in the dialog settings. - * - * @param settings The dialog settings - */ - public void save(DialogSettings settings) { - settings.put("expression", getExpression()); //$NON-NLS-1$ - settings.put("isCaseSenstiveSelected", isCaseSenstiveSelected()); //$NON-NLS-1$ - settings.put("isAsyncMessageReturnSelected", isAsyncMessageReturnSelected()); //$NON-NLS-1$ - settings.put("isAsyncMessageSelected", isAsyncMessageSelected()); //$NON-NLS-1$ - settings.put("isLifeLineSelected", isLifeLineSelected()); //$NON-NLS-1$ - settings.put("isStopSelected", isStopSelected()); //$NON-NLS-1$ - settings.put("isSyncMessageReturnSelected", isSyncMessageReturnSelected()); //$NON-NLS-1$ - settings.put("isSyncMessageSelected", isSyncMessageSelected()); //$NON-NLS-1$ - } - - /** - * Loads the criteria with values of the dialog settings. - * - * @param settings The dialog settings - */ - public void load(DialogSettings settings) { - setExpression(settings.get("expression")); //$NON-NLS-1$ - setCaseSenstiveSelected(settings.getBoolean("isCaseSenstiveSelected")); //$NON-NLS-1$ - setAsyncMessageReturnSelected(settings.getBoolean("isAsyncMessageReturnSelected")); //$NON-NLS-1$ - setAsyncMessageSelected(settings.getBoolean("isAsyncMessageSelected")); //$NON-NLS-1$ - setLifeLineSelected(settings.getBoolean("isLifeLineSelected")); //$NON-NLS-1$ - setStopSelected(settings.getBoolean("isStopSelected")); //$NON-NLS-1$ - setSyncMessageReturnSelected(settings.getBoolean("isSyncMessageReturnSelected")); //$NON-NLS-1$ - setSyncMessageSelected(settings.getBoolean("isSyncMessageSelected")); //$NON-NLS-1$ - } - - /** - * Gets the summary of supported graph nodes. - * - * @param provider A filter provider - * @param loaderClassName A class loader - * @return graph node summary - */ - public String getGraphNodeSummary(ISDFilterProvider provider, String loaderClassName) { - ArrayList list = new ArrayList<>(); - - if (provider != null) { - if (isLifeLineSelected()) { - list.add(provider.getNodeName(ISDGraphNodeSupporter.LIFELINE, loaderClassName)); - } - if (isSyncMessageSelected()) { - list.add(provider.getNodeName(ISDGraphNodeSupporter.SYNCMESSAGE, loaderClassName)); - } - if (isSyncMessageReturnSelected()) { - list.add(provider.getNodeName(ISDGraphNodeSupporter.SYNCMESSAGERETURN, loaderClassName)); - } - if (isAsyncMessageSelected()) { - list.add(provider.getNodeName(ISDGraphNodeSupporter.ASYNCMESSAGE, loaderClassName)); - } - if (isAsyncMessageReturnSelected()) { - list.add(provider.getNodeName(ISDGraphNodeSupporter.ASYNCMESSAGERETURN, loaderClassName)); - } - if (isStopSelected()) { - list.add(provider.getNodeName(ISDGraphNodeSupporter.STOP, loaderClassName)); - } - } else { - if (isLifeLineSelected()) { - list.add(Messages.SequenceDiagram_Lifeline); - } - if (isSyncMessageSelected()) { - list.add(Messages.SequenceDiagram_SynchronousMessage); - } - if (isSyncMessageReturnSelected()) { - list.add(Messages.SequenceDiagram_SynchronousMessageReturn); - } - if (isAsyncMessageSelected()) { - list.add(Messages.SequenceDiagram_AsynchronousMessage); - } - if (isAsyncMessageReturnSelected()) { - list.add(Messages.SequenceDiagram_AsynchronousMessageReturn); - } - if (isStopSelected()) { - list.add(Messages.SequenceDiagram_Stop); - } - } - StringBuffer ret = new StringBuffer(); - String prefix = "["; //$NON-NLS-1$ - for (Iterator i = list.iterator(); i.hasNext();) { - String s = i.next(); - ret.append(prefix); - ret.append(s); - prefix = " " + Messages.SequenceDiagram_or + " "; //$NON-NLS-1$ //$NON-NLS-2$ - } - ret.append("]"); //$NON-NLS-1$ - return ret.toString(); - } - - /** - * Matches given string using compiled pattern based on user expression. - * - * @param stringToMatch A string to match - * @return true if string matches expression - */ - public boolean matches(String stringToMatch) { - if (pattern == null) { - return false; - } - return pattern.matcher(stringToMatch).matches(); - } - - /** - * Updates the regular expression pattern based on the expression. - */ - private void updatePattern() { - if (fExpression != null) { - try { - if (fCaseSenstiveSelected) { - pattern = Pattern.compile(fExpression); - } - else { - pattern = Pattern.compile(fExpression, Pattern.CASE_INSENSITIVE); - } - } catch (PatternSyntaxException e) { - pattern = null; - } - } - else { - pattern = null; - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/FilterCriteria.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/FilterCriteria.java deleted file mode 100755 index d67a88e4a9..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/FilterCriteria.java +++ /dev/null @@ -1,273 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs; - -import java.util.Iterator; -import java.util.List; - -import org.eclipse.jface.dialogs.DialogSettings; - -/** - * A filter criteria is a criteria that can be activated or not, positive or not. - * - * @version 1.0 - * @author sveyrier - * - */ -public class FilterCriteria { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The filter state value for 'active'. - */ - protected static final String ACTIVE = "active"; //$NON-NLS-1$ - /** - * The property value for positive filter. - */ - protected static final String POSITIVE = "positive"; //$NON-NLS-1$ - /** - * The filter loader class name property. - */ - protected static final String LOADERCLASSNAME = "loaderClassName"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The criteria reference. - */ - private Criteria fCriteria; - /** - * Flag whether this criteria is active or not - */ - private boolean fIsActive; - /** - * Flag whether this criteria is for positive filter or not - */ - private boolean fIsPositive; - /** - * The loader class name. - */ - private String fLoaderClassName; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - /** - * Standard constructor - * - * @param criteria A criteria reference - * @param isActive true if filter criteria is active else false - * @param isPositive true for positive filter else false - */ - public FilterCriteria(Criteria criteria, boolean isActive, boolean isPositive) { - this(criteria, isActive, isPositive, null); - } - - /** - * Constructor - * - * @param criteria A criteria reference - * @param isActive true if filter criteria is active else false - * @param isPositive true for positive filter else false - * @param loaderClassName A loader class name - */ - public FilterCriteria(Criteria criteria, boolean isActive, boolean isPositive, String loaderClassName) { - fCriteria = criteria; - fIsActive = isActive; - fIsPositive = isPositive; - fLoaderClassName = loaderClassName; - } - - /** - * Copy Constructor - * @param other FilterCriteria - */ - public FilterCriteria (FilterCriteria other) { - fCriteria = new Criteria(other.fCriteria); - fIsActive = other.fIsActive; - fIsPositive = other.fIsPositive; - fLoaderClassName = other.fLoaderClassName; - } - - /** - * Default constructor - */ - protected FilterCriteria() { - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(super.toString()); - sb.append(':'); - if (fCriteria != null) { - sb.append(" expression=");sb.append(fCriteria.getExpression()); //$NON-NLS-1$ - sb.append(" active=");sb.append(fIsActive); //$NON-NLS-1$ - sb.append(" positive=");sb.append(fIsPositive); //$NON-NLS-1$ - } else { - sb.append("empty criteria"); //$NON-NLS-1$ - } - return sb.toString(); - } - - /** - * Sets a criteria reference. - * @param criteria A criteria reference - */ - public void setCriteria(Criteria criteria) { - fCriteria = criteria; - } - - /** - * Returns the criteria reference. - * - * @return the criteria reference - */ - public Criteria getCriteria() { - return fCriteria; - } - - /** - * Sets the active flag. - * - * @param isActive A active value. - */ - public void setActive(boolean isActive) { - fIsActive = isActive; - } - - /** - * Returns whether filter criteria is active or not. - * - * @return whether filter criteria is active or not. - */ - public boolean isActive() { - return fIsActive; - } - - /** - * Sets filter is for positive filtering or not. - * - * @param isPositive The value to set. - */ - public void setPositive(boolean isPositive) { - fIsPositive = isPositive; - } - - /** - * Returns whether the filter si for positive filtering or not. - * - * @return Returns the positive. - */ - public boolean isPositive() { - return fIsPositive; - } - - /** - * Sets the loader class name for this filter. - * - * @param loaderClassName The loader class name to set - */ - public void setLoaderClassName(String loaderClassName) { - fLoaderClassName = loaderClassName; - } - - /** - * Returns the class loader name. - * - * @return the class loader name. - */ - public String getLoaderClassName() { - return fLoaderClassName; - } - - /** - * Finds a filter criteria within a list of criteria. - * - * @param what The filter to find - * @param list A list of filter criteria - * @return The found filter criteria or null - */ - public static FilterCriteria find(FilterCriteria what, List list) { - if (what != null && list != null) { - try { - for (Iterator i = list.iterator(); i.hasNext();) { - FilterCriteria fc = i.next(); - if (what.compareTo(fc)) { - return fc; - } - } - } catch (Exception e) { - // Silence - } - } - return null; - } - - /** - * Compares this filter criteria with a given criteria. - * - * @param to The filter criteria to compare. - * @return usual comparison result (< 0, 0, > 0) - */ - public boolean compareTo(FilterCriteria to) { - if (isPositive() == to.isPositive() && getCriteria().compareTo(to.getCriteria())) { - if (getLoaderClassName() == null && to.getLoaderClassName() == null) { - return true; - } - if ((getLoaderClassName() != null && to.getLoaderClassName() != null) && getLoaderClassName().equals(to.getLoaderClassName())) { - return true; - } - } - return false; - } - - /** - * Saves current criteria attributes in the dialog settings. - * - * @param settings The dialog settings - */ - public void save(DialogSettings settings) { - settings.put(ACTIVE, isActive()); - settings.put(POSITIVE, isPositive()); - if (getLoaderClassName() != null) { - settings.put(LOADERCLASSNAME, getLoaderClassName()); - } else { - settings.put(LOADERCLASSNAME, ""); //$NON-NLS-1$ - } - if (fCriteria != null) { - fCriteria.save(settings); - } - } - - /** - * Loads the criteria with values of the dialog settings. - * - * @param settings The dialog settings - */ - public void load(DialogSettings settings) { - setActive(settings.getBoolean(ACTIVE)); - setPositive(settings.getBoolean(POSITIVE)); - String loaderClassName = settings.get(LOADERCLASSNAME); - setLoaderClassName(loaderClassName != null && loaderClassName.length() > 0 ? loaderClassName : null); - if (fCriteria != null) { - fCriteria.load(settings); - } - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/FilterListDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/FilterListDialog.java deleted file mode 100755 index a5963e140b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/FilterListDialog.java +++ /dev/null @@ -1,518 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.DialogSettings; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDFilterProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.RowData; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableItem; -import org.eclipse.ui.IViewPart; - -/** - * This is the filters list dialog.
- * It is associated to an SDView and to a ISDFilterProvider.
- * - * @version 1.0 - * @author sveyrier - */ -public class FilterListDialog extends Dialog { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * Filter list criteria property name - */ - protected static final String FILTERS_LIST_CRITERIA = "filtersListsCriteria"; //$NON-NLS-1$ - /** - * Filter list size property name - */ - protected static final String FILTERS_LIST_SIZE = "filtersListSize"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The viewer and provided are kept here as attributes - */ - private final IViewPart fViewer; - /** - * The filter provider implementation - */ - private final ISDFilterProvider fProvider; - /** - * The filters are the result of editing this list - */ - private List fFilters; - /** - * The add button. - */ - private Button fAdd; - /** - * The remove button. - */ - private Button fRemove; - /** - * The edit button. - */ - private Button fEdit; - /** - * The table with list of filters. - */ - private Table fTable; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Standard constructor - * - * @param view The view reference - * @param loader The filter provider implementation - */ - public FilterListDialog(IViewPart view, ISDFilterProvider loader) { - super(view.getSite().getShell()); - fViewer = view; - fProvider = loader; - fFilters = null; - setShellStyle(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - /** - * Adds a criteria to the table - * - * @param criteria A criteria to add - * @param checked A flag whether criteria is checked (selected) or not - * @param positive A flag whether criteria is for positive filter or not - * @param loaderClassName A loader class name for the filters - */ - protected void addCriteria(Criteria criteria, boolean checked, boolean positive, String loaderClassName) { - CriteriaTableItem cti = new CriteriaTableItem(fTable, checked, positive, loaderClassName); - cti.setCriteria(criteria); - } - - /** - * Replaces a selected criteria with a new criteria. - * - * @param newCriteria A new criteria. - */ - protected void replaceSelectedCriteria(Criteria newCriteria) { - CriteriaTableItem cti = (CriteriaTableItem) fTable.getSelection()[0].getData(); - cti.setCriteria(newCriteria); - } - - /** - * Handles table selection count. - */ - protected void handleTableSelectionCount() { - int count = fTable.getSelectionCount(); - fEdit.setEnabled(count == 1); - fRemove.setEnabled(count > 0); - } - - @Override - public Control createDialogArea(Composite parent) { - - Group ret = new Group(parent, SWT.NONE); - ret.setText(Messages.SequenceDiagram_ListOfHideDisplayPatterns); - RowLayout rowLayout = new RowLayout(); - rowLayout.wrap = false; - rowLayout.pack = true; - rowLayout.justify = false; - rowLayout.type = SWT.HORIZONTAL; - rowLayout.marginLeft = 4; - rowLayout.marginTop = 4; - rowLayout.marginRight = 4; - rowLayout.marginBottom = 4; - rowLayout.spacing = 8; - ret.setLayout(rowLayout); - - fTable = new Table(ret, SWT.MULTI | SWT.CHECK); - fTable.setLayoutData(new RowData(220, 84)); - fTable.setHeaderVisible(false); - fTable.addSelectionListener(new SelectionListener() { - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - int count = fTable.getSelectionCount(); - if (count == 1) { - Criteria criteria = openFilterDialog(((CriteriaTableItem) fTable.getSelection()[0].getData()).getCriteria(), Messages.SequenceDiagram_Update); - if (criteria != null) { - replaceSelectedCriteria(criteria); - } - } - } - - @Override - public void widgetSelected(SelectionEvent e) { - handleTableSelectionCount(); - } - }); - if (fFilters != null) { - for (Iterator i = fFilters.iterator(); i.hasNext();) { - FilterCriteria filterCriteria = i.next(); - addCriteria(filterCriteria.getCriteria(), filterCriteria.isActive(), filterCriteria.isPositive(), filterCriteria.getLoaderClassName()); - } - } - - Composite commands = new Composite(ret, SWT.NONE); - RowLayout rowLayoutCommands = new RowLayout(); - rowLayoutCommands.wrap = false; - rowLayoutCommands.pack = false; - rowLayoutCommands.justify = true; - rowLayoutCommands.type = SWT.VERTICAL; - rowLayoutCommands.marginLeft = 0; - rowLayoutCommands.marginTop = 4; - rowLayoutCommands.marginRight = 0; - rowLayoutCommands.marginBottom = 4; - rowLayoutCommands.spacing = 8; - commands.setLayout(rowLayoutCommands); - fAdd = new Button(commands, SWT.NONE); - fAdd.setText(Messages.SequenceDiagram_Add); - fAdd.addSelectionListener(new SelectionListener() { - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - // Nothing to do - } - - @Override - public void widgetSelected(SelectionEvent e) { - Criteria init = new Criteria(); - Criteria c = openFilterDialog(init, Messages.SequenceDiagram_Create); - if (c != null) { - addCriteria(c, true, false, null); - } - } - }); - - fEdit = new Button(commands, SWT.NONE); - fEdit.setText(Messages.SequenceDiagram_EditIt); - fEdit.addSelectionListener(new SelectionListener() { - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - // Nothing to do - } - - @Override - public void widgetSelected(SelectionEvent e) { - Criteria c = openFilterDialog(((CriteriaTableItem) fTable.getSelection()[0].getData()).getCriteria(), Messages.SequenceDiagram_Update); - if (c != null) { - replaceSelectedCriteria(c); - } - } - }); - fEdit.setEnabled(false); - - fRemove = new Button(commands, SWT.NONE); - fRemove.setText(Messages.SequenceDiagram_Remove); - fRemove.addSelectionListener(new SelectionListener() { - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - // Nothing to do - } - - @Override - public void widgetSelected(SelectionEvent e) { - fTable.remove(fTable.getSelectionIndices()); - handleTableSelectionCount(); - } - }); - fRemove.setEnabled(false); - - getShell().setText(Messages.SequenceDiagram_SequenceDiagramHidePatterns); - /* - * for (int i=0;i 0) { - fFilters = new ArrayList<>(); - } else { - fFilters = null; - } - for (int i = 0; i < fTable.getItemCount(); i++) { - TableItem item = fTable.getItem(i); - CriteriaTableItem cti = (CriteriaTableItem) item.getData(); - FilterCriteria fc = new FilterCriteria(cti.getCriteria(), item.getChecked(), cti.isPositive(), cti.getLoaderClassName()); - FilterCriteria efc = FilterCriteria.find(fc, fFilters); - if (efc == null) { - fFilters.add(fc); - } else { - efc.setActive(efc.isActive() || fc.isActive()); - } - } - super.close(); - fProvider.filter(fFilters); - saveFiltersCriteria(fFilters); - } - - /** - * Sets the list of filters. - * - * @param filters The list of filters to set. - */ - public void setFilters(List filters) { - fFilters = filters; - } - - /** - * Returns the filters list after editing. - * - * @return the filters list after editing - */ - public List getFilters() { - return fFilters; - } - - /** - * Loads the filter criteria from global filters which are saved in the dialog settings. - */ - protected void loadFiltersCriteria() { - List globalFilters = getGlobalFilters(); - for (Iterator i = globalFilters.iterator(); i.hasNext();) { - FilterCriteria filterCriteria = i.next(); - addCriteria(filterCriteria.getCriteria(), filterCriteria.isActive(), filterCriteria.isPositive(), filterCriteria.getLoaderClassName()); - } - } - - /** - * Returns the global filters which are saved in the dialog settings.. - * - * @return the saved global filters - */ - - public static List getGlobalFilters() { - DialogSettings settings = (DialogSettings) Activator.getDefault().getDialogSettings().getSection(FILTERS_LIST_CRITERIA); - int i = 0; - DialogSettings section = null; - int size = 0; - List globalFilters = new ArrayList<>(); - if (settings != null) { - try { - size = settings.getInt(FILTERS_LIST_SIZE); - } catch (NumberFormatException e) { - // This is not a problem - size = 0; - } - section = (DialogSettings) settings.getSection(FILTERS_LIST_CRITERIA + i); - - while ((section != null) && (i < size)) { - FilterCriteria criteria = new FilterCriteria(); - criteria.setCriteria(new Criteria()); - criteria.load(section); - globalFilters.add(criteria); - section = (DialogSettings) settings.getSection(FILTERS_LIST_CRITERIA + (++i)); - } - } - - return globalFilters; - } - - /** - * Saves the filter criteria in the dialog settings. - * - * @param globalFilters A list of filters to save. - */ - public static void saveFiltersCriteria(List globalFilters) { - DialogSettings settings = (DialogSettings) Activator.getDefault().getDialogSettings(); - DialogSettings section = (DialogSettings) settings.getSection(FILTERS_LIST_CRITERIA); - if (section == null) { - section = (DialogSettings) settings.addNewSection(FILTERS_LIST_CRITERIA); - } - - if (globalFilters == null) { - section.put(FILTERS_LIST_SIZE, 0); - return; - } - - section.put(FILTERS_LIST_SIZE, globalFilters.size()); - - FilterCriteria criteria; - - for (int j = 0; j < globalFilters.size(); j++) { - if (globalFilters.get(j) == null) { - return; - } - - criteria = globalFilters.get(j); - DialogSettings subSection = (DialogSettings) section.getSection(FILTERS_LIST_CRITERIA + j); - - if (subSection == null) { - subSection = (DialogSettings) section.addNewSection(FILTERS_LIST_CRITERIA + j); - } - criteria.save(subSection); - } - } - - /** - * Deactivates the saved global filters. - */ - public static void deactivateSavedGlobalFilters() { - // Deactivate all filters - List filters = getGlobalFilters(); - for(FilterCriteria criteria : filters) { - criteria.setActive(false); - } - // Save settings - FilterListDialog.saveFiltersCriteria(filters); - } - - // ------------------------------------------------------------------------ - // Helper classes - // ------------------------------------------------------------------------ - /** - * A class to map TableItems that can be toggled active or inactive and Criteria - */ - protected class CriteriaTableItem { - - /** - * The criteria reference - */ - protected Criteria fCriteria; - /** - * The "positive" value. - */ - protected boolean fIsPositive; - /** - * The loader class name - */ - protected String fLoaderClassName; - /** - * The actual table item. - */ - protected TableItem fTableItem; - - /** - * Constructor - * - * @param parent The parent table - * @param isActive true if filter criteria is active else false - * @param isPositive true for positive filter else false - * @param loaderClassName The loader class name - */ - public CriteriaTableItem(Table parent, boolean isActive, boolean isPositive, String loaderClassName) { - fTableItem = new TableItem(parent, SWT.NONE); - fTableItem.setData(this); - fTableItem.setChecked(isActive); - fIsPositive = isPositive; - fLoaderClassName = loaderClassName; - } - - /** - * Constructor - * - * @param parent The parent table - * @param isActive true if filter criteria is active else false - * @param isPositive true for positive filter else false - * @param loaderClassName The loader class name - * @param index The table item index - */ - public CriteriaTableItem(Table parent, boolean isActive, boolean isPositive, String loaderClassName, int index) { - fTableItem = new TableItem(parent, SWT.NONE, index); - fTableItem.setChecked(isActive); - fIsPositive = isPositive; - fLoaderClassName = loaderClassName; - } - - /** - * Sets the criteria. - * - * @param criteria The criteria to set - */ - public void setCriteria(Criteria criteria) { - fCriteria = criteria; - fTableItem.setText((fIsPositive ? Messages.SequenceDiagram_display : Messages.SequenceDiagram_hide) + " " + fCriteria.getExpression() + " " + fCriteria.getGraphNodeSummary(fProvider, fLoaderClassName)); //$NON-NLS-1$ //$NON-NLS-2$ - } - - /** - * Returns the criteria. - * @return the criteria - */ - public Criteria getCriteria() { - return fCriteria; - } - - /** - * Returns whether positive filtering is active or not. - * - * @return true for positive filter else false - */ - public boolean isPositive() { - return fIsPositive; - } - - /** - * Returns the loader class name. - * - * @return the loader class name - */ - public String getLoaderClassName() { - return fLoaderClassName; - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/MinMaxDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/MinMaxDialog.java deleted file mode 100755 index e7d0f12008..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/MinMaxDialog.java +++ /dev/null @@ -1,190 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -/** - * Dialog box for entering minimum and maximum time range for time compression bar. - * - * @version 1.0 - * @author sveyrier - * @author Bernd Hufmann - * - */ -public class MinMaxDialog extends Dialog { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * Text field for minimum. - */ - private Text fMinText; - /** - * Text field for maximum. - */ - private Text fMaxText; - /** - * Text field for scale. - */ - private Text fScaleText; - /** - * Text field for precision. - */ - private Text fPrecisionText; - /** - * The sequence diagram widget reference. - */ - private SDWidget fSdWidget; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - /** - * Standard constructor. - * @param shell The shell - * @param viewer The sequence diagram widget reference. - */ - public MinMaxDialog(Shell shell, SDWidget viewer) { - super(shell); - fSdWidget = viewer; - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - /** - * Method to create a grid data base on horizontal span. - * @param span The horizontal span - * @return a grid data object - */ - protected GridData newGridData(int span) { - GridData data = new GridData(GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL); - data.horizontalSpan = span; - return data; - } - - @Override - protected Control createDialogArea(Composite p) { - p.getShell().setText(Messages.SequenceDiagram_TimeCompressionBarConfig); - Composite parent = (Composite) super.createDialogArea(p); - - GridLayout parentLayout = new GridLayout(); - parentLayout.numColumns = 6; - parent.setLayout(parentLayout); - - Group g1 = new Group(parent, SWT.SHADOW_NONE); - g1.setLayoutData(newGridData(3)); - GridLayout g1layout = new GridLayout(); - g1layout.numColumns = 3; - g1.setLayout(g1layout); - - Label minLabel = new Label(g1, SWT.RADIO); - minLabel.setText(Messages.SequenceDiagram_MinTime); - minLabel.setLayoutData(newGridData(1)); - - fMinText = new Text(g1, SWT.SINGLE | SWT.BORDER); - fMinText.setLayoutData(newGridData(2)); - fMinText.setText(String.valueOf(fSdWidget.getFrame().getMinTime().getValue())); - - Label maxLabel = new Label(g1, SWT.RADIO); - maxLabel.setText(Messages.SequenceDiagram_MaxTime); - maxLabel.setLayoutData(newGridData(1)); - - fMaxText = new Text(g1, SWT.SINGLE | SWT.BORDER); - fMaxText.setLayoutData(newGridData(2)); - fMaxText.setText(String.valueOf(fSdWidget.getFrame().getMaxTime().getValue())); - - Label scaleLabel = new Label(g1, SWT.RADIO); - scaleLabel.setText(Messages.SequenceDiagram_Scale); - scaleLabel.setLayoutData(newGridData(1)); - - fScaleText = new Text(g1, SWT.SINGLE | SWT.BORDER); - fScaleText.setLayoutData(newGridData(2)); - fScaleText.setText(String.valueOf(fSdWidget.getFrame().getMinTime().getScale())); - - - Label precisionLabel = new Label(g1, SWT.RADIO); - precisionLabel.setText(Messages.SequenceDiagram_Precision); - precisionLabel.setLayoutData(newGridData(1)); - - fPrecisionText = new Text(g1, SWT.SINGLE | SWT.BORDER); - fPrecisionText.setLayoutData(newGridData(2)); - fPrecisionText.setText(String.valueOf(fSdWidget.getFrame().getMinTime().getPrecision())); - - return parent; - } - - @Override - protected void okPressed() { - long min = 0; - long max = 0; - int scale = 0; - int precision = 0; - try { - min = Long.parseLong(fMinText.getText()); - max = Long.parseLong(fMaxText.getText()); - scale = Integer.parseInt(fScaleText.getText()); - precision = Integer.parseInt(fPrecisionText.getText()); - - fSdWidget.getFrame().setMax(new TmfTimestamp(max, scale, precision)); - fSdWidget.getFrame().setMin(new TmfTimestamp(min, scale, precision)); - - fSdWidget.redraw(); - - super.okPressed(); - } catch (Exception e) { - MessageDialog.openError(getShell(), Messages.SequenceDiagram_Error, Messages.SequenceDiagram_InvalidRange); - } - } - - @Override - protected void createButtonsForButtonBar(Composite parent) { - super.createButtonsForButtonBar(parent); - createButton(parent, IDialogConstants.CLIENT_ID, Messages.SequenceDiagram_Default, false); - getButton(IDialogConstants.CLIENT_ID).addSelectionListener(new SelectionListener() { - - @Override - public void widgetSelected(SelectionEvent e) { - fSdWidget.getFrame().resetCustomMinMax(); - fMinText.setText(String.valueOf(fSdWidget.getFrame().getMinTime().getValue())); - fMaxText.setText(String.valueOf(fSdWidget.getFrame().getMaxTime().getValue())); - fScaleText.setText(String.valueOf(fSdWidget.getFrame().getMinTime().getScale())); - fPrecisionText.setText(String.valueOf(fSdWidget.getFrame().getMinTime().getPrecision())); - fMaxText.getParent().layout(true); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - // nothing to do - } - }); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/PagesDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/PagesDialog.java deleted file mode 100755 index 6243b7469d..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/PagesDialog.java +++ /dev/null @@ -1,204 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs; - -import java.text.MessageFormat; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDAdvancedPagingProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.IViewPart; - -/** - * Class implementation of the pages dialog.
- * - * It is associated to an SDView and to a ISDAdvancedPagingProvider.
- * - * @version 1.0 - * @author sveyrier - */ -public class PagesDialog extends Dialog { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * viewer and provided are kept here as attributes - */ - private ISDAdvancedPagingProvider fProvider = null; - - /** Current page */ - private TextArea fCurrentPage; - - /** Comment label */ - private Label fTotalPageComment; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Standard constructor - * - * @param view The sequence diagram view reference - * @param provider The paging provider reference - */ - public PagesDialog(IViewPart view, ISDAdvancedPagingProvider provider) { - super(view.getSite().getShell()); - fProvider = provider; - setShellStyle(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public Control createDialogArea(Composite parent) { - - Group ret = new Group(parent, SWT.NONE); - GridData data = new GridData(); - data.grabExcessHorizontalSpace = true; - data.horizontalAlignment = GridData.FILL; - ret.setLayoutData(data); - ret.setText(Messages.SequenceDiagram_PageNavigation); - - FillLayout fillLayout = new FillLayout(SWT.VERTICAL); - ret.setLayout(fillLayout); - - Label label = new Label(ret, SWT.NONE); - label.setText(Messages.SequenceDiagram_CurrentPage); - - fCurrentPage = new TextArea(ret); - fCurrentPage.setBounds(1, fProvider.pagesCount()); - fCurrentPage.setValue(fProvider.currentPage() + 1); - - fTotalPageComment = new Label(ret, SWT.NONE); - fTotalPageComment.setAlignment(SWT.RIGHT); - - updateComments(); - - getShell().setText(Messages.SequenceDiagram_SequenceDiagramPages); - return ret; - } - - @Override - public void okPressed() { - int currentPageValue = fCurrentPage.getValue() - 1; - super.close(); - fProvider.pageNumberChanged(currentPageValue); - } - - /** - * Updates the comments texts. - */ - private void updateComments() { - int pages = Math.max(0, fProvider.pagesCount()); - StringBuffer totalPageCommentText = new StringBuffer(); - totalPageCommentText.append(Messages.SequenceDiagram_Total); - totalPageCommentText.append(pages); - totalPageCommentText.append(" "); //$NON-NLS-1$ - if (pages == 0) { - totalPageCommentText.append(Messages.SequenceDiagram_pages); - } else if (pages == 1) { - totalPageCommentText.append(Messages.SequenceDiagram_page); - } else { - totalPageCommentText.append(Messages.SequenceDiagram_pages); - } - fTotalPageComment.setText(totalPageCommentText.toString()); - } - - - // ------------------------------------------------------------------------ - // Helper classes - // ------------------------------------------------------------------------ - - /** - * This is a Text Control that accepts only digits and ensures that bounds are respected - */ - protected static class TextArea { - /** - * The text field. - */ - private Text fText; - /** - * The minimum page value - */ - private int fMin; - /** - * The maximum page value - */ - private int fMax; - - /** - * Constructor - * - * @param parent The paren composite - */ - public TextArea(Composite parent) { - fText = new Text(parent, SWT.SINGLE | SWT.BORDER | SWT.RIGHT); - fText.setTextLimit(10); - } - - /** - * Sets the page value. - * - * @param page The page value - */ - public void setValue(int page) { - int value = Math.max(fMin, Math.min(fMax, page)); - fText.setText(Integer.toString(value)); - } - - /** - * Returns the page value. - * - * @return the page value - */ - public int getValue() { - int res; - try { - res = Integer.parseInt(fText.getText()); - } catch (Exception e) { - // ignored - res = 0; - } - return Math.max(fMin, Math.min(fMax, res)); - } - - /** - * Sets the minimum and maximum page values. - * - * @param min A minimum page value - * @param max A maximum page value - */ - public void setBounds(int min, int max) { - fMin = Math.max(0, min); - fMax = Math.max(fMin, max); - Integer tab[] = new Integer[2]; - tab[0] = Integer.valueOf(fMin); - tab[1] = Integer.valueOf(fMax); - fText.setToolTipText(MessageFormat.format(Messages.SequenceDiagram_IsInBetween, (Object[]) tab)); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/SDPrintDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/SDPrintDialog.java deleted file mode 100755 index 6898a6d643..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/SDPrintDialog.java +++ /dev/null @@ -1,174 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -/** - * This class implements a dialog box for collecting printing information. - * - * @version 1.0 - * @author sveyrier - */ -public class SDPrintDialog extends Dialog { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The sequence dialog widget reference. - */ - private SDWidget fSdView; - /** - * Sequence dialog print dialog UI - */ - private SDPrintDialogUI fDialogUI; - /** - * Error message to display. - */ - private String fErrorMessage = null; - /** - * A message label. - */ - private Label fMessageLabel = null; - /** - * Flag whether the page is complete or not - */ - private boolean fIsPageComplete = true; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Standard constructor - * - * @param shell Shell reference - * @param viewer Sequence diagram widget reference - */ - public SDPrintDialog(Shell shell, SDWidget viewer) { - super(shell); - fSdView = viewer; - - fDialogUI = new SDPrintDialogUI(shell, fSdView); - fDialogUI.setParentDialog(this); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - protected Control createDialogArea(Composite p) { - p.getShell().setText(Messages.SequenceDiagram_Print); - Composite parent = (Composite) super.createDialogArea(p); - - fDialogUI.createDialogArea(parent); - - fMessageLabel = new Label(parent, SWT.NONE); - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); - gridData.horizontalSpan = 6; - fMessageLabel.setLayoutData(gridData); - setErrorMessage(fErrorMessage); - - return parent; - } - - @Override - protected void okPressed() { - - if (fDialogUI.okPressed()) { - super.okPressed(); - } - } - - @Override - protected void createButtonsForButtonBar(Composite parent) { - - super.createButtonsForButtonBar(parent); - createButton(parent, IDialogConstants.CLIENT_ID, Messages.SequenceDiagram_Printer, false); - - getButton(IDialogConstants.CLIENT_ID).addSelectionListener(new SelectionListener() { - @Override - public void widgetSelected(SelectionEvent e) { - fDialogUI.printButtonSelected(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - }); - - updateButtons(); - } - - /** - * @return the dialog UI - */ - public SDPrintDialogUI getDialogUI() { - return fDialogUI; - } - - /** - * Sets the error message. - * - * @param message error message to set - */ - public void setErrorMessage(String message) { - fErrorMessage = message; - if (fMessageLabel != null) { - if (fErrorMessage == null) { - fMessageLabel.setText(""); //$NON-NLS-1$ - } else { - fMessageLabel.setText(fErrorMessage); - } - } - } - - /** - * Sets the page complete flag. - * @param complete whether page is complete or not - */ - public void setPageComplete(boolean complete) { - fIsPageComplete = complete; - updateButtons(); - } - - /** - * Udates the button enable state. - */ - public void updateButtons() { - Button okButton = getButton(IDialogConstants.OK_ID); - if (fIsPageComplete) { - if (okButton != null) { - okButton.setEnabled(true); - } - } else { - if (okButton != null) { - okButton.setEnabled(false); - } - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/SDPrintDialogUI.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/SDPrintDialogUI.java deleted file mode 100755 index f93a0fc738..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/SDPrintDialogUI.java +++ /dev/null @@ -1,1424 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs; - -import java.text.MessageFormat; -import java.util.Arrays; - -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.DiagramToolTip; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.NGC; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseTrackListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.events.TraverseEvent; -import org.eclipse.swt.events.TraverseListener; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.printing.PrintDialog; -import org.eclipse.swt.printing.Printer; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -/** - * The class implements the actual print dialog UI for collecting printing data. - * - * @version 1.0 - * @author sveyrier - */ -public class SDPrintDialogUI { - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The set horizontal pages number. - */ - private Button fSetHPagesNumber; - /** - * The set vertical pages number. - */ - private Button fSetVPagesNumber; - /** - * Flag whether to use current zoom or not. - */ - private Button fUseCurrentZoom; - /** - * Flag whether to print all pages or not - */ - private Button fAllPages; - /** - * Flag whether to print current page only - */ - private Button fCurrentPage; - /** - * Button to select a page list. - */ - private Button fPageList; - /** - * Button to select a page range. - */ - private Button fPageRange; - /** - * Text field to enter from page. - */ - private Text fFromPage; - /** - * Text field to enter to page. - */ - private Text fToPage; - /** - * The sequence diagram widget reference. - */ - private SDWidget fSdView; - /** - * Text field for number of horizontal pages - */ - private Text fHorPagesNum; - /** - * Text field for number of vertical pages - */ - private Text fVertPagesNum; - /** - * Text field for toal number of pages - */ - private Text fTotalPages; - /** - * A modify listener implementation to handle modifications. - */ - private ModifyListener fModifyListener; - /** - * A selection listener implementation to handle selections. - */ - private SelectionListener fSelectionListener; - /** - * Local canvas displaying sequence diagram overview. - */ - private LocalSD fOverviewCanvas; - /** - * Number of pages - */ - private int fNbPages = 0; - /** - * Number of selected pages. - */ - private int fPageNum = -1; - /** - * Number of first page. - */ - private int fFirstPage = -1; - /** - * List of pages to print. - */ - private int fPagesList[]; - - /** - * Value for dividing the sequence diagram into pages - */ - private float fStepX; - - /** - * Value for dividing the sequence diagram into pages - */ - private float fStepY; - - /** - * Value for dividing the sequence diagram into pages - */ - private float sTX; - - /** - * Value for dividing the sequence diagram into pages - */ - private float sTY; - - /** - * Page which to print from. - */ - private int fFrom; - /** - * Page which to print to. - */ - private int fTo; - /** - * Flag for enabling multi-selection. - */ - private boolean fMultiSelection = false; - /** - * Flag for enabling area selection. - */ - private boolean fAreaSelection = false; - /** - * Flag for printing all. - */ - private boolean fPrintAll; - /** - * Flag for printing current page only. - */ - private boolean fPrintCurrent; - /** - * Flag for printing a selection of pages. - */ - private boolean fPrintSelection; - /** - * Flag for printing a range of pages. - */ - private boolean fPrintRange; - /** - * Number of selected rows - */ - private int fNbRows; - /** - * Number of selected lines - */ - private int fNbLines; - /** - * The zoom factor. - */ - private float fZoomFactor; - /** - * The printer data reference. - */ - private PrinterData fPrinterData; - /** - * The diagram tooltip to show if necessary. - */ - private DiagramToolTip fToolTip = null; - /** - * Label for current selection. - */ - private Label fCurrentSelection; - /** - * The shell reference. - */ - private Shell fShell; - /** - * Button to open printer dialog from OS. - */ - private Button fPrinterDialog; - /** - * Flag for showing print button. - */ - private boolean fShowPrintButton; - /** - * Test value - */ - private int fTest = 3; - /** - * Parent wizard page if used as wizard - */ - private WizardPage fParentWizardPage = null; - /** - * Reference to parent print dialog. - */ - private SDPrintDialog fParentDialog = null; - - // ------------------------------------------------------------------------ - // Helper Class - // ------------------------------------------------------------------------ - /** - * Local sequence diagram widget used to display overview of sequence diagram to print. - * @version 1.0 - */ - private class LocalSD extends SDWidget { - - /** - * Constructor - * @param c Parent composite - * @param s Style bits - */ - public LocalSD(Composite c, int s) { - super(c, s); - } - - @Override - public int getContentsHeight() { - if (fSdView.getContentsHeight() > fSdView.getContentsHeight()) { - return (int) (fSdView.getVisibleHeight() / (float) fTest / fSdView.getZoomValue()); - } - return super.getContentsHeight(); - } - - @Override - public int getContentsWidth() { - if (fSdView.getVisibleWidth() > fSdView.getContentsWidth()) { - return (int) (fSdView.getVisibleWidth() / (float) fTest / fSdView.getZoomValue()); - } - return super.getContentsWidth(); - } - - @Override - protected void contentsMouseHover(MouseEvent event) { - } - - /** - * Creates page selection images. - * - * @param img - Overview image - * @param width -The width value - * @param stepX - Step X - * @param height - Height value - * @param stepY - Step Y - * @return new image - */ - protected Image createPagesSelectionImages(Image img, int width, float stepX, int height, float stepY) { - - Image over = new Image(super.getShell().getDisplay(), img.getImageData()); - - for (int pageIndex = 0; pageIndex < fPagesList.length; pageIndex++) { - - int pageNum = fPagesList[pageIndex]; - - if (getPagesForSelection() > 0 && pageNum > 0) { - int line = pageNum / getNbRow(); - int row = pageNum % getNbRow(); - if (row != 0) { - line++; - } else { - row = getNbRow(); - } - - line--; - row--; - - Image toDel = over; - if (fOverviewCanvas.isFocusControl()) { - over = new Image(super.getShell().getDisplay(), drawRegionSelected(toDel, new Rectangle(contentsToViewX((int) (row * stepX * fOverviewCanvas.getZoomValue())), contentsToViewY((int) (line * stepY * fOverviewCanvas.getZoomValue())), - ((int) (stepX * fOverviewCanvas.getZoomValue())), ((int) (stepY * fOverviewCanvas.getZoomValue()))), new RGB(0, 0, 128))); - } else { - over = new Image(super.getShell().getDisplay(), drawRegionSelected(toDel, new Rectangle(contentsToViewX((int) (row * stepX * fOverviewCanvas.getZoomValue())), contentsToViewY((int) (line * stepY * fOverviewCanvas.getZoomValue())), - ((int) (stepX * fOverviewCanvas.getZoomValue())), ((int) (stepY * fOverviewCanvas.getZoomValue()))), new RGB(221, 208, 200))); - } - toDel.dispose(); - } - } - - Arrays.sort(fPagesList); - int pos = Arrays.binarySearch(fPagesList, fPageNum); - if ((pos < 0) && (getPagesForSelection() > 0 && fPageNum > 0)) { - int line = fPageNum / getNbRow(); - int row = fPageNum % getNbRow(); - if (row != 0) { - line++; - } else { - row = getNbRow(); - } - - line--; - row--; - - Image toDel = over; - over = new Image(super.getShell().getDisplay(), drawRegionSelected(toDel, new Rectangle(contentsToViewX((int) (row * stepX * fOverviewCanvas.getZoomValue())), contentsToViewY((int) (line * stepY * fOverviewCanvas.getZoomValue())), - ((int) (stepX * fOverviewCanvas.getZoomValue())), ((int) (stepY * fOverviewCanvas.getZoomValue()))), new RGB(221, 208, 200))); - toDel.dispose(); - } - - GC imGC2 = new GC(over); - imGC2.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); - NGC imGC = new NGC(fOverviewCanvas, imGC2); - for (int i = 0, x = 0; x <= width && stepX > 0; i++, x = (int) (i * stepX)) { - imGC.drawLine(x, 0, x, height); - } - - for (int j = 0, y = 0; y <= height && stepY > 0; j++, y = (int) (j * stepY)) { - imGC.drawLine(0, y, width, y); - } - - imGC2.dispose(); - imGC.dispose(); - return over; - } - - @Override - protected void drawContents(GC gc, int clipx, int clipy, int clipw, int cliph) { - - Image dbuffer = getDrawBuffer(); - computeStepXY(); - Image d; - - int lw = (int) (getContentsWidth() / getZoomValue()); - if (getContentsWidth() < getVisibleWidth()) { - lw = (int) (getVisibleWidth() / getZoomValue()); - } - - int lh = (int) (getContentsHeight() / getZoomValue()); - if (getContentsHeight() < getVisibleHeight()) { - lh = (int) (getVisibleHeight() / getZoomValue()); - } - d = createPagesSelectionImages(dbuffer, lw, fStepX, lh, fStepY); - - if (!isEnabled()) { - Image toDel = d; - d = new Image(super.getShell().getDisplay(), drawRegionSelected(d, new Rectangle(0, 0, lw, lh), new RGB(221, 208, 200))); - toDel.dispose(); - } - - Rectangle area = getClientArea(); - int w = d.getBounds().width; - int h = d.getBounds().height; - gc.drawImage(d, 0, 0, w, h, 0, 0, area.width, area.height); - - fTotalPages.setText(Integer.valueOf(maxNumOfPages()).toString()); - displayPageNum(); - dbuffer.dispose(); - d.dispose(); - gc.dispose(); - } - - @Override - protected void keyPressedEvent(KeyEvent e) { - if (e.keyCode == SWT.CTRL) { - fMultiSelection = true; - } - if (e.keyCode == SWT.SHIFT) { - fAreaSelection = true; - } - if (e.keyCode == SWT.ARROW_DOWN) { - if (fPageNum + getNbRow() <= maxNumOfPages()) { - fPageNum += getNbRow(); - } - int line = fPageNum / getNbRow(); - int row = fPageNum % getNbRow(); - if (row == 0) { - line--; - } - if ((line + 1) * fStepY > (fOverviewCanvas.getContentsY() + fOverviewCanvas.getVisibleHeight()) / fOverviewCanvas.getZoomValue()) { - fOverviewCanvas.scrollBy(0, (int) (fStepY * fOverviewCanvas.getZoomValue())); - } - } - if (e.keyCode == SWT.ARROW_UP) { - if (fPageNum - getNbRow() > 0) { - fPageNum -= getNbRow(); - } - int line = fPageNum / getNbRow(); - int row = fPageNum % getNbRow(); - if (row == 0) { - line--; - } - if ((line) * fStepY <= fOverviewCanvas.getContentsY() / fOverviewCanvas.getZoomValue()) { - fOverviewCanvas.scrollBy(0, -(int) (fStepY * fOverviewCanvas.getZoomValue())); - } - } - if (e.keyCode == SWT.ARROW_LEFT) { - if ((fPageNum - 2) / getNbRow() == (fPageNum - 1) / getNbRow() && fPageNum > 1) { - fPageNum--; - } - int row = fPageNum % getNbRow(); - if ((row - 1) * fStepX < (fOverviewCanvas.getContentsX()) / fOverviewCanvas.getZoomValue()) { - fOverviewCanvas.scrollBy(-(int) (fStepX * fOverviewCanvas.getZoomValue()), 0); - } - } - if (e.keyCode == SWT.ARROW_RIGHT) { - if ((fPageNum - 1) / getNbRow() == fPageNum / getNbRow()) { - fPageNum++; - } - int row = fPageNum % getNbRow(); - if (row == 0) { - row = getNbRow(); - } - if ((row) * fStepX > (fOverviewCanvas.getContentsX() + fOverviewCanvas.getVisibleWidth()) / fOverviewCanvas.getZoomValue()) { - fOverviewCanvas.scrollBy((int) (fStepX * fOverviewCanvas.getZoomValue()), 0); - } - } - - if (e.keyCode == 32 && fPageNum > -1) { - Arrays.sort(fPagesList); - int pos = Arrays.binarySearch(fPagesList, fPageNum); - if (pos < 0) { - addToPagesList(fPageNum); - } else { - removeFromPagesList(fPageNum); - } - } - - if (!fAreaSelection && !fMultiSelection) { - fFirstPage = fPageNum; - fPagesList = new int[1]; - fPagesList[0] = fPageNum; - } else if ((fPageNum != -1) && (fAreaSelection) && (fFirstPage != -1)) { - fPagesList = new int[0]; - int line1 = fFirstPage / getNbRow(); - int row1 = fFirstPage % getNbRow(); - if (row1 != 0) { - line1++; - } else { - row1 = getNbRow(); - } - - int line2 = fPageNum / getNbRow(); - int row2 = fPageNum % getNbRow(); - if (row2 != 0) { - line2++; - } else { - row2 = getNbRow(); - } - - int temp; - if (line1 > line2) { - temp = line2; - line2 = line1; - line1 = temp; - } - - if (row1 > row2) { - temp = row2; - row2 = row1; - row1 = temp; - } - - for (int i = row1 - 1; i < row2; i++) { - for (int j = line1 - 1; j < line2; j++) { - addToPagesList(i + j * getNbRow() + 1); - } - } - } - displayPageNum(); - fOverviewCanvas.redraw(); - } - - @Override - protected void keyReleasedEvent(KeyEvent e) { - if (e.keyCode == SWT.CTRL) { - fMultiSelection = false; - } - if (e.keyCode == SWT.SHIFT) { - fAreaSelection = false; - } - } - - @Override - protected void contentsMouseDownEvent(MouseEvent event) { - - computeStepXY(); - int x1 = (int) ((event.x / fOverviewCanvas.getZoomValue()) / fStepX); - int x2 = (int) ((event.y / fOverviewCanvas.getZoomValue()) / fStepY); - - int oldPage = fPageNum; - - fPageNum = x1 + x2 * getNbRow() + 1; - - if (fPageNum > maxNumOfPages()) { - fPageNum = oldPage; - return; - } - - if (!fAreaSelection) { - fFirstPage = fPageNum; - } - - if ((fPageNum != -1) && (fMultiSelection)) { - Arrays.sort(fPagesList); - int pos = Arrays.binarySearch(fPagesList, fPageNum); - if (pos < 0) { - addToPagesList(fPageNum); - } else { - removeFromPagesList(fPageNum); - } - } else if ((fPageNum != -1) && (fAreaSelection) && (fFirstPage != -1)) { - - fPagesList = new int[0]; - - int line1 = fFirstPage / getNbRow(); - int row1 = fFirstPage % getNbRow(); - if (row1 != 0) { - line1++; - } else { - row1 = getNbRow(); - } - - int line2 = fPageNum / getNbRow(); - int row2 = fPageNum % getNbRow(); - if (row2 != 0) { - line2++; - } else { - row2 = getNbRow(); - } - - int temp; - if (line1 > line2) { - temp = line2; - line2 = line1; - line1 = temp; - } - - if (row1 > row2) { - temp = row2; - row2 = row1; - row1 = temp; - } - - for (int i = row1 - 1; i < row2; i++) { - for (int j = line1 - 1; j < line2; j++) { - addToPagesList(i + j * getNbRow() + 1); - } - } - } else { - fPagesList = new int[1]; - fPagesList[0] = fPageNum; - } - if ((event.stateMask & SWT.CTRL) != 0) { - fMultiSelection = true; - } - displayPageNum(); - redraw(); - } - - @Override - protected void contentsMouseMoveEvent(MouseEvent e) { - fToolTip.hideToolTip(); - } - - @Override - public void resizeContents(int w, int h) { - super.resizeContents(w, h); - } - - } - - /** - * A traverse listener implementation. - */ - protected static class LocalTraverseListener implements TraverseListener { - @Override - public void keyTraversed(TraverseEvent e) { - if ((e.detail == SWT.TRAVERSE_TAB_NEXT) || (e.detail == SWT.TRAVERSE_TAB_PREVIOUS)) { - e.doit = true; - } - } - } - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Constructor - * - * @param shell - * The shell reference - * @param sdWidget - * The sequence diagram widget reference - */ - public SDPrintDialogUI(Shell shell, SDWidget sdWidget) { - this(shell, sdWidget, false); - } - - /** - * Constructor - * - * @param shell - * The shell reference - * @param sdWidget - * The sequence diagram widget reference - * @param showPrintBtn - * Flag for showing print buttons - */ - public SDPrintDialogUI(Shell shell, SDWidget sdWidget, boolean showPrintBtn) { - fShell = shell; - fSdView = sdWidget; - fShowPrintButton = showPrintBtn; - - fPrinterData = Printer.getDefaultPrinterData(); - if (fPrinterData != null) { - fPrinterData.scope = PrinterData.SELECTION; - } - - fPagesList = new int[0]; - - fSelectionListener = new SelectionListener() { - - @Override - public void widgetSelected(SelectionEvent e) { - if (fUseCurrentZoom.getSelection()) { - fHorPagesNum.setEnabled(false); - fVertPagesNum.setEnabled(false); - } - if (fSetHPagesNumber.getSelection()) { - fHorPagesNum.setEnabled(true); - fVertPagesNum.setEnabled(false); - if (fCurrentPage.getSelection()) { - fCurrentPage.setSelection(false); - fAllPages.setSelection(true); - } - if ("".equals(fHorPagesNum.getText())) { //$NON-NLS-1$ - fHorPagesNum.setText("1"); //$NON-NLS-1$ - } - } - if (fSetVPagesNumber.getSelection()) { - fHorPagesNum.setEnabled(false); - fVertPagesNum.setEnabled(true); - if (fCurrentPage.getSelection()) { - fCurrentPage.setSelection(false); - fAllPages.setSelection(true); - } - if ("".equals(fVertPagesNum.getText())) { //$NON-NLS-1$ - fVertPagesNum.setText("1"); //$NON-NLS-1$ - } - } - if (fCurrentPage.getSelection() || fAllPages.getSelection() || fPageList.getSelection()) { - fFromPage.setEnabled(false); - fToPage.setEnabled(false); - } else { - fFromPage.setEnabled(true); - fToPage.setEnabled(true); - } - - fCurrentPage.setEnabled(fUseCurrentZoom.getSelection()); - fOverviewCanvas.setEnabled(fPageList.getSelection()); - if (fOverviewCanvas.isEnabled() && (e.widget == fUseCurrentZoom || e.widget == fSetHPagesNumber || e.widget == fSetVPagesNumber)) { - fPagesList = new int[1]; - fPagesList[0] = 1; - fPageNum = 1; - fFirstPage = 1; - } else if ((fOverviewCanvas.isEnabled() && (e.widget == fPageList)) && - (fPagesList == null || fPagesList.length <= 0)) { - - fPagesList = new int[1]; - fPagesList[0] = 1; - fPageNum = 1; - fFirstPage = 1; - } - computeStepXY(); - fTotalPages.setText(Integer.valueOf(maxNumOfPages()).toString()); - fOverviewCanvas.redraw(); - fOverviewCanvas.update(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - fPagesList = new int[0]; - computeStepXY(); - fOverviewCanvas.redraw(); - } - - }; - - fModifyListener = new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - fPagesList = new int[0]; - computeStepXY(); - fTotalPages.setText(Integer.valueOf(maxNumOfPages()).toString()); - fOverviewCanvas.redraw(); - } - - }; - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - /** - * Creates new grid data object. - * - * @param span horizontal span. - * @return grid data - */ - protected GridData newGridData(int span) { - GridData data = new GridData(GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL); - data.horizontalSpan = span; - return data; - } - - /** - * Creates the dialog area. - * - * @param parent The parent composite - * @return dialog control - */ - public Control createDialogArea(Composite parent) { - - GridLayout parentLayout = new GridLayout(); - parentLayout.numColumns = 6; - parent.setLayout(parentLayout); - - Group g1 = new Group(parent, SWT.SHADOW_NONE); - g1.setText(Messages.SequenceDiagram_ZoomOption); - g1.setLayoutData(newGridData(3)); - GridLayout g1layout = new GridLayout(); - g1layout.numColumns = 2; - g1.setLayout(g1layout); - - fUseCurrentZoom = new Button(g1, SWT.RADIO); - fUseCurrentZoom.setText(Messages.SequenceDiagram_UseCurrentZoom); - fUseCurrentZoom.setLayoutData(newGridData(2)); - fUseCurrentZoom.addSelectionListener(fSelectionListener); - - fSetHPagesNumber = new Button(g1, SWT.RADIO); - fSetHPagesNumber.setText(Messages.SequenceDiagram_NumberOfHorizontalPages); - fSetHPagesNumber.setLayoutData(newGridData(1)); - fSetHPagesNumber.addSelectionListener(fSelectionListener); - - fHorPagesNum = new Text(g1, SWT.SINGLE | SWT.BORDER); - fHorPagesNum.addModifyListener(fModifyListener); - - fSetVPagesNumber = new Button(g1, SWT.RADIO); - fSetVPagesNumber.setText(Messages.SequenceDiagram_NumberOfVerticalPages); - fSetVPagesNumber.setLayoutData(newGridData(1)); - fSetVPagesNumber.addSelectionListener(fSelectionListener); - - fVertPagesNum = new Text(g1, SWT.SINGLE | SWT.BORDER); - fVertPagesNum.addModifyListener(fModifyListener); - - Label nbTotal = new Label(g1, SWT.SHADOW_NONE | SWT.RIGHT); - nbTotal.setText(Messages.TotalNumberOfPages); - // nbTotal.setLayoutData(newGridData(1)); - - fTotalPages = new Text(g1, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY); - // nbHV.addModifyListener(modifListener); - - Group g2 = new Group(parent, SWT.SHADOW_NONE); - g2.setText(Messages.SequenceDiagram_Preview); - GridData data = new GridData(GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL); - data.horizontalSpan = 3; - data.verticalSpan = 2; - g2.setLayoutData(data); - GridLayout g2layout = new GridLayout(); - // g2layout. - g2layout.numColumns = 1; - // SVLayout g2layout = new SVLayout(); - g2.setLayout(g2layout); - - GridData data2 = new GridData(GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL); - data2.horizontalSpan = 1; - data2.verticalSpan = 1; - - fOverviewCanvas = new LocalSD(g2, SWT.NO_BACKGROUND); - GridData seqDiagLayoutData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL); - fOverviewCanvas.setLayoutData(seqDiagLayoutData); - // overviewCanvas.resizeContents(100,100); - if (fSdView.getContentsWidth() < fSdView.getVisibleWidth() && fSdView.getContentsHeight() < fSdView.getVisibleHeight()) { - fTest = 3; - } else { - fTest = 10; - } - fOverviewCanvas.setFrame(fSdView.getFrame(), true); - fOverviewCanvas.setZoomValue((float) 1 / fTest); - fOverviewCanvas.setCornerControl(null); - seqDiagLayoutData.widthHint = fOverviewCanvas.getContentsWidth() / fTest; - seqDiagLayoutData.widthHint = fOverviewCanvas.getFrame().getWidth() / fTest + 15; - - if (fSdView.getVisibleWidth() < fSdView.getContentsWidth()) { - seqDiagLayoutData.widthHint = fOverviewCanvas.getContentsWidth() / fTest; - if (seqDiagLayoutData.widthHint > Display.getDefault().getClientArea().width / 4) { - seqDiagLayoutData.widthHint = Display.getDefault().getClientArea().width / 4; - } - } else { - seqDiagLayoutData.widthHint = fOverviewCanvas.getFrame().getWidth() / fTest + 15; - } - - if (fSdView.getVisibleHeight() < fSdView.getContentsHeight()) { - seqDiagLayoutData.heightHint = fOverviewCanvas.getContentsHeight() / fTest; - if (seqDiagLayoutData.heightHint > Display.getDefault().getClientArea().width / 4) { - seqDiagLayoutData.heightHint = Display.getDefault().getClientArea().width / 4; - } - } else { - seqDiagLayoutData.heightHint = fOverviewCanvas.getFrame().getHeight() / fTest; - } - - fOverviewCanvas.setEnabled(false); - - fCurrentSelection = new Label(g2, SWT.SHADOW_NONE | SWT.LEFT); - fCurrentSelection.setLayoutData(newGridData(1)); - - Group g3 = new Group(parent, SWT.SHADOW_NONE); - g3.setText(Messages.SequenceDiagram_PrintRange); - g3.setLayoutData(newGridData(3)); - GridLayout g3layout = new GridLayout(); - g3layout.numColumns = 4; - g3.setLayout(g3layout); - - fAllPages = new Button(g3, SWT.RADIO); - fAllPages.setText(Messages.SequenceDiagram_AllPages); - fAllPages.setLayoutData(newGridData(4)); - fAllPages.addSelectionListener(fSelectionListener); - - fCurrentPage = new Button(g3, SWT.RADIO); - fCurrentPage.setText(Messages.SequenceDiagram_CurrentView); - fCurrentPage.setLayoutData(newGridData(4)); - fCurrentPage.setEnabled(true); - fCurrentPage.setSelection(true); - fCurrentPage.addSelectionListener(fSelectionListener); - - fPageList = new Button(g3, SWT.RADIO); - fPageList.setText(Messages.SequenceDiagram_SelectedPages); - fPageList.setLayoutData(newGridData(4)); - fPageList.addSelectionListener(fSelectionListener); - - fPageRange = new Button(g3, SWT.RADIO); - fPageRange.setText(Messages.SequenceDiagram_FromPage); - fPageRange.setLayoutData(newGridData(1)); - fPageRange.addSelectionListener(fSelectionListener); - - fFromPage = new Text(g3, SWT.SINGLE | SWT.BORDER); - - Label labelTo = new Label(g3, SWT.CENTER); - labelTo.setText(Messages.SequenceDiagram_to); - - fToPage = new Text(g3, SWT.SINGLE | SWT.BORDER); - - fToolTip = new DiagramToolTip(fOverviewCanvas); - - fOverviewCanvas.getViewControl().addMouseTrackListener(new MouseTrackListener() { - @Override - public void mouseEnter(MouseEvent e) { - fToolTip.hideToolTip(); - } - - @Override - public void mouseExit(MouseEvent e) { - fToolTip.hideToolTip(); - } - - @Override - public void mouseHover(MouseEvent e) { - int x1 = (int) (fOverviewCanvas.viewToContentsX(e.x) / fOverviewCanvas.getZoomValue() / fStepX); - int x2 = (int) (fOverviewCanvas.viewToContentsY(e.y) / fOverviewCanvas.getZoomValue() / fStepY); - int num = x1 + x2 * getNbRow() + 1; - if (num > maxNumOfPages()) { - return; - } - if (num > 0) { - fToolTip.showToolTip(String.valueOf(num)); - displayPageNum(); - } else { - fCurrentSelection.setText("");//$NON-NLS-1$ - fToolTip.hideToolTip(); - } - } - - }); - - fOverviewCanvas.addTraverseListener(new LocalTraverseListener()); - - fOverviewCanvas.addFocusListener(new FocusListener() { - @Override - public void focusGained(FocusEvent e) { - fOverviewCanvas.redraw(); - } - - @Override - public void focusLost(FocusEvent e) { - fOverviewCanvas.redraw(); - } - }); - - if (fShowPrintButton) { - Composite printerDlg = new Composite(parent, SWT.NONE); - data = new GridData(SWT.FILL, SWT.DEFAULT, true, false); - data.horizontalSpan = 6; - parentLayout = new GridLayout(); - parentLayout.numColumns = 2; - printerDlg.setLayout(parentLayout); - printerDlg.setLayoutData(data); - - Label label = new Label(printerDlg, SWT.NONE); - label.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false)); - fPrinterDialog = new Button(printerDlg, SWT.PUSH); - fPrinterDialog.setText(Messages.SequenceDiagram_Printer); - - fPrinterDialog.addSelectionListener(new SelectionListener() { - @Override - public void widgetSelected(SelectionEvent e) { - printButtonSelected(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - - }); - } - - updatePrinterStatus(); - - return parent; - } - - /** - * Get number of pages for selection. - * @return number of pages for selection. - */ - public int getPagesForSelection() { - return fNbPages; - } - - /** - * Handler for when the OK button is pressed - * - * @return True if the operation was successful, false if there was an error - */ - public boolean okPressed() { - fPrintAll = fAllPages.getSelection(); - fPrintCurrent = fCurrentPage.getSelection(); - fPrintSelection = fPageList.getSelection(); - fPrintRange = fPageRange.getSelection(); - try { - if (fPrintRange) { - fFrom = Integer.valueOf(fFromPage.getText()).intValue(); - fTo = Integer.valueOf(fToPage.getText()).intValue(); - if (fFrom > maxNumOfPages() || fTo > maxNumOfPages() || fFrom <= 0 || fTo <= 0) { - MessageDialog.openError(getShell(), Messages.SequenceDiagram_Error, Messages.SequenceDiagram_InvalidRange); - return false; - } - } else if (fSetHPagesNumber.getSelection() && fNbPages <= 0) { - MessageDialog.openError(getShell(), Messages.SequenceDiagram_Error, Messages.SequenceDiagram_InvalidNbHorizontal); - return false; - } else if (fSetVPagesNumber.getSelection() && fNbPages <= 0) { - MessageDialog.openError(getShell(), Messages.SequenceDiagram_Error, Messages.SequenceDiagram_InvalidNbVertical); - return false; - } else if (fPrintSelection && getPageList().length <= 0) { - MessageDialog.openError(getShell(), Messages.SequenceDiagram_Error, Messages.SequenceDiagram_NoPageSelected); - return false; - } - - } catch (Exception e) { - MessageDialog.openError(getShell(), Messages.SequenceDiagram_Error, Messages.SequenceDiagram_InvalidRange); - fFrom = 0; - fTo = 0; - return false; - } - - return true; - } - - /** - * Draws region that was selected - * @param img The corresponding image - * @param r The selected rectangle. - * @param color The color to use for selection - * @return image data reference - */ - public ImageData drawRegionSelected(Image img, Rectangle r, RGB color) { - ImageData id = img.getImageData(); - for (int a = 0; a < r.width && r.x + a < id.width; a++) { - for (int b = 0; b < r.height && r.y + b < id.height; b++) { - int index = id.getPixel(r.x + a, r.y + b); - RGB rgb = id.palette.getRGB(index); - rgb = combine(color, rgb); - id.setPixel(r.x + a, r.y + b, id.palette.getPixel(rgb)); - } - } - return id; - } - - /** - * Combines two RGB colors. - * @param front The front color - * @param back The back color - * @return new RGB color - */ - public static RGB combine(RGB front, RGB back) { - int _af = 128; - int _ab = 200; - - double af = (_af) / 255.0; - double rf = front.red; - double gf = front.green; - double bf = front.blue; - - double ab = (_ab) / 255.0; - double rb = back.red; - double gb = back.green; - double bb = back.blue; - - double k = (1.0 - af) * ab; - int r = (int) ((af * rf + k * rb)); - int g = (int) ((af * gf + k * gb)); - int b = (int) ((af * bf + k * bb)); - - return new RGB(r, g, b); - } - - /** - * Computes value for X coordinates step and Y coordinates step. - */ - protected void computeStepXY() { - float cw = fOverviewCanvas.getContentsWidth() / fOverviewCanvas.getZoomValue(); - float ch = fOverviewCanvas.getContentsHeight() / fOverviewCanvas.getZoomValue(); - try { - if (fPrinterData == null) { - fStepX = 0; - fStepY = 0; - fNbPages = 0; - fZoomFactor = 0; - } else { - Printer printer = new Printer(fPrinterData); - if (fSetHPagesNumber.getSelection()) { - fNbPages = Integer.valueOf(fHorPagesNum.getText()).intValue(); - float z1 = fSdView.getContentsWidth() / cw; - float z2 = printer.getClientArea().width / ((float) fSdView.getContentsWidth() / fNbPages); - - fStepY = printer.getClientArea().height / z1 / z2; - fStepX = cw / fNbPages; - } else if (fSetVPagesNumber.getSelection()) { - fNbPages = Integer.valueOf(fVertPagesNum.getText()).intValue(); - float z1 = fSdView.getContentsHeight() / ch; - float z2 = printer.getClientArea().height / ((float) fSdView.getContentsHeight() / fNbPages); - fStepX = printer.getClientArea().width / z1 / z2; - fStepY = ch / fNbPages; - } else { - float z1 = fSdView.getContentsWidth() / (cw); - fStepX = fSdView.getVisibleWidth() / z1; - fNbPages = Math.round(cw / fStepX); - if (fNbPages == 0) { - fNbPages = 1; - } - int pw = printer.getClientArea().width; - int ph = printer.getClientArea().height; - float z2 = pw / ((float) fSdView.getContentsWidth() / fNbPages); - fStepY = ph / z1 / z2; - } - } - } catch (NumberFormatException e) { - fStepX = fStepY = fNbPages = 0; - fZoomFactor = 0; - } - sTX = fStepX * (fSdView.getContentsWidth() / cw); - sTY = fStepY * (fSdView.getContentsHeight() / ch); - float rat = 1; - if ((fSdView.getVisibleWidth() > fSdView.getContentsWidth()) && (fSetVPagesNumber.getSelection() || fSetHPagesNumber.getSelection())) { - rat = (float) fSdView.getVisibleWidth() / (float) fSdView.getContentsWidth(); - } - fZoomFactor = (fOverviewCanvas.getContentsWidth() / cw) / fOverviewCanvas.getZoomFactor() * rat; - } - - /** - * Returns the pages list. - * - * @return the pages list. - */ - public int[] getPageList() { - return Arrays.copyOf(fPagesList, fPagesList.length); - } - - /** - * Adds a page to pages list. - * - * @param num - * The number of the the new page - */ - public void addToPagesList(int num) { - int temp[] = new int[fPagesList.length + 1]; - System.arraycopy(fPagesList, 0, temp, 0, fPagesList.length); - temp[temp.length - 1] = num; - fPagesList = new int[temp.length]; - System.arraycopy(temp, 0, fPagesList, 0, temp.length); - } - - /** - * Removes a page from the pages list. - * - * @param num - * The number of the page to remove - */ - public void removeFromPagesList(int num) { - int pos = Arrays.binarySearch(fPagesList, num); - int temp[] = new int[fPagesList.length - 1]; - System.arraycopy(fPagesList, 0, temp, 0, pos); - System.arraycopy(fPagesList, pos + 1, temp, pos, fPagesList.length - pos - 1); - fPagesList = new int[temp.length]; - System.arraycopy(temp, 0, fPagesList, 0, temp.length); - } - - /** - * Returns the maximum number of pages. - * - * @return maximum number of pages. - */ - public int maxNumOfPages() { - return (getNbRow() * getNbLines()); - } - - /** - * Returns the number of rows. - * - * @return number of rows. - */ - public int getNbRow() { - if (!fSetHPagesNumber.isDisposed()) { - int cw = (int) (fOverviewCanvas.getContentsWidth() / fOverviewCanvas.getZoomValue()); - int row = 1; - if (fStepX != 0) { - row = (int) (cw / fStepX); - if (fSetHPagesNumber.getSelection()) { - row = Math.round(cw / fStepX); - } else if ((cw % fStepX != 0)) { - row++; - } - } - fNbRows = row; - } - return fNbRows; - } - - /** - * Returns the number of lines. - * - * @return number of lines - */ - public int getNbLines() { - if (!fSetVPagesNumber.isDisposed()) { - int ch = (int) (fOverviewCanvas.getContentsHeight() / fOverviewCanvas.getZoomValue()); - int line = 1; - if (fStepY != 0) { - line = (int) (ch / fStepY); - if (fSetVPagesNumber.getSelection()) { - line = Math.round(ch / fStepY); - } else if (ch % fStepY != 0) { - line++; - } - } - fNbLines = line; - } - return fNbLines; - } - - /** - * Returns whether to print all pages or not. - * - * @return true for all pages else false. - */ - public boolean printAll() { - return fPrintAll; - } - - /** - * Returns whether to print only current page - * - * @return true for current page only else false.. - */ - public boolean printCurrent() { - return fPrintCurrent; - } - - /** - * Returns whether to print selected pages. - * - * @return true for selected pages only else false. - */ - public boolean printSelection() { - return fPrintSelection; - } - - /** - * Returns whether to print range of pages. - * - * @return true for range of pages only else false. - */ - public boolean printRange() { - return fPrintRange; - } - - /** - * Returns the step in X direction. - * - * @return step in X direction - */ - public float getStepX() { - return sTX; - } - - /** - * Returns the step in Y direction. - * - * @return step in Y direction - */ - public float getStepY() { - return sTY; - } - - /** - * Returns the zoom factor - * - * @return zoom factor - */ - public float getZoomFactor() { - return fZoomFactor; - } - - /** - * Returns the printer data reference. - * - * @return printer data reference - */ - public PrinterData getPrinterData() { - return fPrinterData; - } - - /** - * Returns the page number to start printing from. - * - * @return page number to start printing from - */ - public int getFrom() { - return fFrom; - } - - /** - * Returns the page number to print to. - * - * @return page number to print to - */ - public int getTo() { - return fTo; - } - - /** - * Displays current number of pages - */ - protected void displayPageNum() { - if (fPageNum > 0) { - String message = MessageFormat.format(Messages.SequenceDiagram_Page, new Object[] { Integer.valueOf(fPageNum) }); - fCurrentSelection.setText(message); - fCurrentSelection.getParent().layout(); - } - } - - /** - * Returns the shell reference. - * - * @return the shell reference. - */ - public Shell getShell() { - return fShell; - } - - /** - * Sets the shell. - * - * @param shell The shell reference. - */ - public void setShell(Shell shell) { - fShell = shell; - } - - /** - * Handle selection of print button. - */ - public void printButtonSelected() { - PrintDialog printer = new PrintDialog(getShell()); - if (fAllPages.getSelection()) { - printer.setScope(PrinterData.ALL_PAGES); - } - if (fCurrentPage.getSelection()) { - printer.setScope(PrinterData.SELECTION); - } - if (fPageList.getSelection()) { - printer.setScope(PrinterData.SELECTION); - } - if (fPageRange.getSelection()) { - printer.setScope(PrinterData.PAGE_RANGE); - fFrom = Integer.valueOf(fFromPage.getText()).intValue(); - fTo = Integer.valueOf(fToPage.getText()).intValue(); - printer.setStartPage(fFrom); - printer.setEndPage(fTo); - } - - PrinterData newPrinterData = printer.open(); - if (newPrinterData != null) { - fPrinterData = newPrinterData; - } - updatePrinterStatus(); - - if (printer.getScope() == PrinterData.ALL_PAGES) { - fAllPages.setSelection(true); - fCurrentPage.setSelection(false); - fPageList.setSelection(false); - fPageRange.setSelection(false); - fHorPagesNum.setEnabled(false); - fVertPagesNum.setEnabled(false); - } - if (printer.getScope() == PrinterData.PAGE_RANGE) { - fAllPages.setSelection(false); - fCurrentPage.setSelection(false); - fPageList.setSelection(false); - fPageRange.setSelection(true); - fFromPage.setEnabled(true); - fToPage.setEnabled(true); - fFromPage.setText((Integer.valueOf(printer.getStartPage())).toString()); - fToPage.setText((Integer.valueOf(printer.getEndPage())).toString()); - } - computeStepXY(); - fOverviewCanvas.redraw(); - } - - /** - * Sets parent wizard page - * - * @param parent The parent wizard page - */ - public void setParentWizardPage(WizardPage parent) { - fParentWizardPage = parent; - } - - /** - * Sets the parent dialog box. - * - * @param parent The parent dialog box. - */ - public void setParentDialog(SDPrintDialog parent) { - fParentDialog = parent; - } - - /** - * Updates the printer status - */ - protected void updatePrinterStatus() { - if (fParentWizardPage != null) { - // used in the wizard dialog - if (fPrinterData == null) { - // show error message and disable Finish button - fParentWizardPage.setErrorMessage(Messages.SequenceDiagram_NoPrinterSelected); - fParentWizardPage.setPageComplete(false); - } else { - // clear error message and enable Finish button - fParentWizardPage.setErrorMessage(null); - fParentWizardPage.setPageComplete(true); - } - } else if (fParentDialog != null) { - // used in the print dialog - if (fPrinterData == null) { - // show error message and disable OK button - fParentDialog.setErrorMessage(Messages.SequenceDiagram_NoPrinterSelected); - fParentDialog.setPageComplete(false); - } else { - // clear error message and enable OK button - fParentDialog.setErrorMessage(null); - fParentDialog.setPageComplete(true); - } - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/SearchFilterDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/SearchFilterDialog.java deleted file mode 100755 index 49bb51690a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/SearchFilterDialog.java +++ /dev/null @@ -1,451 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.DialogSettings; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.AsyncMessage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.AsyncMessageReturn; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Stop; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SyncMessage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SyncMessageReturn; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDFindProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.TabFolder; - -/** - * This is the common dialog to define Find and/or Filter Criteria(s) - * - * @version 1.0 - * @author Bernd Hufmann - */ -public class SearchFilterDialog extends Dialog { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The find criteria property name - */ - protected static final String FIND_CRITERIA = "findCriteria"; //$NON-NLS-1$ - /** - * The find expression list property name - */ - protected static final String FIND_EXPRESSION_LIST = "findExpressionList"; //$NON-NLS-1$ - /** - * The filter criteria poperty name - */ - protected static final String FILTER_CRITERIA = "filterCriteria"; //$NON-NLS-1$ - /** - * The filter expression list property name - */ - protected static final String FILTER_EXPRESSION_LIST = "filterExpressionList"; //$NON-NLS-1$ - /** - * The maximum number of expressions stored. - */ - protected static final int MAX_EXPRESSION_LIST = 7; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The sequence diagram view reference. - */ - private final SDView fSdView; - - /** - * The tab with the controls for a Criteria - */ - private final TabFolder fTabFolder = null; - - /** - * The Criteria updated by this dialog - */ - private Criteria fCriteria = null; - - /** - * The find/filter provider telling which graph nodes are supported - */ - private final ISDGraphNodeSupporter fProvider; - - /** - * The okText is the text for the Ok button and title is the title of the - * dialog.
- * Both depend (okText and title (below)) on the usage that is done of this - * dialog (find or filter). - */ - private String fOkText; - - /** - * The title is the title of the dialog.
- * Both depend (okText and title) on the usage that is done of this dialog - * (find or filter). - */ - private String fTitle; - - /** - * List of string expressions that have been searched already - */ - private String[] fExpressionList; - - /** - * find is true if the dialog is for the find feature and false for filter - * feature - */ - private boolean fIsFind; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Standard constructor - * - * @param view - * A sequence diagram view reference - * @param provider - * A graph node supporter provider - * @param filter - * A flag to indicate filtering (true) or finding (false) - * @param style - * Style bits - */ - public SearchFilterDialog(SDView view, ISDGraphNodeSupporter provider, boolean filter, int style) { - super(view.getSDWidget().getShell()); - setShellStyle(SWT.DIALOG_TRIM | style); - fProvider = provider; - fSdView = view; - fIsFind = !filter; - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public Control createDialogArea(Composite arg0) { - if (fIsFind) { - fExpressionList = Activator.getDefault().getDialogSettings().getArray(FIND_EXPRESSION_LIST); - } else { - fExpressionList = Activator.getDefault().getDialogSettings().getArray(FILTER_EXPRESSION_LIST); - } - if (fExpressionList == null) { - fExpressionList = new String[0]; - } - return new TabContents(arg0, fProvider, getButton(IDialogConstants.OK_ID), fExpressionList); - } - - /** - * Open the dialog box - */ - @Override - public int open() { - create(); - - if (fCriteria == null) { - loadCriteria(); - } - - if (fCriteria == null) { - fCriteria = new Criteria(); - fCriteria.setLifeLineSelected(fProvider.isNodeSupported(ISDGraphNodeSupporter.LIFELINE)); - fCriteria.setSyncMessageSelected(fProvider.isNodeSupported(ISDGraphNodeSupporter.SYNCMESSAGE)); - fCriteria.setSyncMessageReturnSelected(fProvider.isNodeSupported(ISDGraphNodeSupporter.SYNCMESSAGERETURN)); - fCriteria.setAsyncMessageSelected(fProvider.isNodeSupported(ISDGraphNodeSupporter.ASYNCMESSAGE)); - fCriteria.setAsyncMessageReturnSelected(fProvider.isNodeSupported(ISDGraphNodeSupporter.ASYNCMESSAGERETURN)); - fCriteria.setStopSelected(fProvider.isNodeSupported(ISDGraphNodeSupporter.STOP)); - } - copyFromCriteria(fCriteria); - - if (fOkText != null) { - getButton(IDialogConstants.OK_ID).setText(fOkText); - } else { - getButton(IDialogConstants.OK_ID).setText(Messages.SequenceDiagram_Find); - } - - if (fIsFind) { - getButton(IDialogConstants.CANCEL_ID).setText(Messages.SequenceDiagram_Close); - } - - Button okButton = getButton(IDialogConstants.OK_ID); - ((TabContents) getDialogArea()).setOkButton(okButton); - if (fCriteria == null || !((fCriteria.getExpression() != null && !fCriteria.getExpression().equals("")) && //$NON-NLS-1$ - (fCriteria.isAsyncMessageReturnSelected() || fCriteria.isAsyncMessageSelected() || fCriteria.isLifeLineSelected() || fCriteria.isStopSelected() || fCriteria.isSyncMessageReturnSelected() || fCriteria.isSyncMessageSelected()))) { - okButton.setEnabled(false); - } - - if (fTitle != null) { - getShell().setText(fTitle); - } else { - getShell().setText(Messages.SequenceDiagram_SequenceDiagramFind); - } - - getShell().pack(); - getShell().setLocation(getShell().getDisplay().getCursorLocation()); - - fCriteria = null; - return super.open(); - } - - /** - * Loads criteria from the dialog settings which are saved in the workspace. - */ - protected void loadCriteria() { - - String CRITERIA = FIND_CRITERIA; - if (!fIsFind) { - CRITERIA = FILTER_CRITERIA; - } - - DialogSettings section = (DialogSettings) Activator.getDefault().getDialogSettings().getSection(CRITERIA); - List selection = fSdView.getSDWidget().getSelection(); - if ((selection == null || selection.size() != 1) || (!fIsFind)) { - if (section != null) { - fCriteria = new Criteria(); - fCriteria.load(section); - } - } else { - GraphNode gn = selection.get(0); - fCriteria = new Criteria(); - fCriteria.setExpression(gn.getName()); - fCriteria.setCaseSenstiveSelected(true); - if (gn instanceof Lifeline && fProvider.isNodeSupported(ISDGraphNodeSupporter.LIFELINE)) { - fCriteria.setLifeLineSelected(true); - } else if (gn instanceof SyncMessageReturn && fProvider.isNodeSupported(ISDGraphNodeSupporter.SYNCMESSAGERETURN)) { - fCriteria.setSyncMessageReturnSelected(true); - } else if ((gn instanceof SyncMessageReturn || gn instanceof SyncMessage) && fProvider.isNodeSupported(ISDGraphNodeSupporter.SYNCMESSAGE)) { - fCriteria.setSyncMessageSelected(true); - } else if (gn instanceof AsyncMessageReturn && fProvider.isNodeSupported(ISDGraphNodeSupporter.ASYNCMESSAGERETURN)) { - fCriteria.setAsyncMessageReturnSelected(true); - } else if ((gn instanceof AsyncMessageReturn || gn instanceof AsyncMessage) && fProvider.isNodeSupported(ISDGraphNodeSupporter.ASYNCMESSAGE)) { - fCriteria.setAsyncMessageSelected(true); - } else if (gn instanceof Stop && fProvider.isNodeSupported(ISDGraphNodeSupporter.STOP)) { - fCriteria.setStopSelected(true); - } - } - } - - /** - * Called when the dialog box ok button is pressed and calls back the - * appropriate action provider (ISDFilterProvider or ISDFindProvider). - */ - @Override - public void okPressed() { - copyToCriteria(); - if (!fIsFind) { - saveCriteria(); - super.close(); // Filter is modal - } - if ((fProvider != null) && (fProvider instanceof ISDFindProvider) && fIsFind) { - boolean result = ((ISDFindProvider) fProvider).find(fCriteria); - TabContents content = getTabContents(); - content.setResult(result); - } - } - - @Override - public void cancelPressed() { - if (fIsFind) { - copyToCriteria(); - if (fProvider instanceof ISDFindProvider) { - ((ISDFindProvider) fProvider).cancel(); - } - saveCriteria(); - } - super.cancelPressed(); - } - - /** - * Saves the criteria to the dialog settings within the workspace. - */ - public void saveCriteria() { - String CRITERIA = FIND_CRITERIA; - String EXPRESSION_LIST = FIND_EXPRESSION_LIST; - if (!fIsFind) { - CRITERIA = FILTER_CRITERIA; - EXPRESSION_LIST = FILTER_EXPRESSION_LIST; - } - DialogSettings settings = (DialogSettings) Activator.getDefault().getDialogSettings(); - DialogSettings section = (DialogSettings) settings.getSection(CRITERIA); - if (section == null) { - section = (DialogSettings) settings.addNewSection(CRITERIA); - } - fCriteria.save(section); - - if (fCriteria.getExpression().length() > 0) { - ArrayList list = new ArrayList<>(); - for (int i = 0; i < fExpressionList.length; i++) { - list.add(fExpressionList[i]); - } - // Remove the used expression if one from the dropdown list - list.remove(fCriteria.getExpression()); - // Put the new expression at the beginning - list.add(0, fCriteria.getExpression()); - // Fill in the expressionList, truncating to MAX_EXPRESSION_LIST - int size = Math.min(list.size(), MAX_EXPRESSION_LIST); - String[] temp = new String[size]; - for (int i = 0; i < size; i++) { - temp[i] = list.get(i); - } - fExpressionList = temp; - settings.put(EXPRESSION_LIST, fExpressionList); - } - } - - /** - * Returns the criteria - * - * @return the criteria - */ - public Criteria getCriteria() { - return fCriteria; - } - - /** - * Sets the criteria. - * - * @param criteria - * the criteria to set. - */ - public void setCriteria(Criteria criteria) { - fCriteria = criteria; - } - - /** - * Get the current end-user settings from the dialog to a Criteria - */ - public void copyToCriteria() { - fCriteria = new Criteria(); - TabContents content = getTabContents(); - fCriteria.setLifeLineSelected(content.isLifelineButtonSelected()); - fCriteria.setSyncMessageSelected(content.isSynMessageButtonSelected()); - fCriteria.setSyncMessageReturnSelected(content.isSynMessageReturnButtonSelected()); - fCriteria.setAsyncMessageSelected(content.isAsynMessageButtonSelected()); - fCriteria.setAsyncMessageReturnSelected(content.isAsynMessageReturnButtonSelected()); - fCriteria.setStopSelected(content.isStopButtonSelected()); - fCriteria.setCaseSenstiveSelected(content.isCaseSensitiveSelected()); - fCriteria.setExpression(content.getSearchText()); - } - - /** - * Returns the tab content reference. - * - * @return the tab content - */ - protected TabContents getTabContents() { - TabContents content = null; - if (fTabFolder == null) { - content = (TabContents) getDialogArea(); - } else { - content = (TabContents) fTabFolder.getSelection()[0].getControl(); - } - return content; - } - - /** - * Initialize the dialog with the settings of an existing Criteria
- * Criteria must not be null and the TabContents must have been created - * - * @param from - * the criteria to copy from - */ - public void copyFromCriteria(Criteria from) { - TabContents content = getTabContents(); - content.setLifelineButtonSelection(from.isLifeLineSelected()); - content.setSynMessageButtonSelection(from.isSyncMessageSelected()); - content.setSynMessageReturnButtonSelection(from.isSyncMessageReturnSelected()); - content.setAsynMessageButtonSelection(from.isAsyncMessageSelected()); - content.setAsynMessageReturnButtonSelection(from.isSyncMessageReturnSelected()); - content.setStopButtonSelection(from.isStopSelected()); - content.setCaseSensitiveSelection(from.isCaseSenstiveSelected()); - if (from.getExpression() != null) { - content.setSearchText(from.getExpression()); - } - } - - /** - * Sets the text to be used for the ok button - * - * @param okText - * text to set - */ - public void setOkText(String okText) { - fOkText = okText; - } - - /** - * Sets the title to be used for the dialog box. - * - * @param title - * The title to set - */ - public void setTitle(String title) { - fTitle = title; - } - - /** - * Gets the text to be used for the ok button - * - * @return the text to be used for the ok button - * @since 2.0 - */ - public String getOkText() { - return fOkText; - } - - /** - * Sets the IsFind flag (true for find, else for filter) - * - * @param flag value to set - * @since 2.0 - */ - protected void setIsFind(boolean flag) { - fIsFind = flag; - } - - /** - * Gets the title to be used for the dialog box. - * - * @return the title to be used for the dialog box. - * @since 2.0 - */ - public String getTitle() { - return fTitle; - } - - /** - * Gets the IsFind flag (true for find, else for filter) - * - * @return true for find, else for filter - * @since 2.0 - */ - protected boolean isFind() { - return fIsFind; - } - - - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/TabContents.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/TabContents.java deleted file mode 100755 index eb453783ee..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/dialogs/TabContents.java +++ /dev/null @@ -1,476 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; - -/** - * Class implementation contains the controls that allows to create or update a find or filter Criteria. - * - * @version 1.0 - * @author sveyrier - */ -public class TabContents extends Composite { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The button for lifelines. - */ - private Button fLifelineButton; - /** - * The button for stops. - */ - private Button fStopButton = null; - /** - * The button for synchronous messages - */ - private Button fSynMessageButton = null; - /** - * The button for synchronous return messages - */ - private Button fSynMessageReturnButton = null; - /** - * The button for asynchronous messages - */ - private Button fAsynMessageButton = null; - /** - * The button for asynchronous return messages - */ - private Button fAsynMessageReturnButton = null; - /** - * The search text combo box. - */ - private Combo fSearchText = null; - /** - * The button for case sensitive expressions. - */ - private Button fCaseSensitive = null; - /** - * The label for the result string. - */ - private Label fResult = null; - /** - * The button for notifying parent about valid data. - */ - private Button fParentOkButton = null; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Creates the dialog contents - * - * @param parent the parent widget - * @param provider the provider which handle the action - * @param okButton of the dialog (to be enabled/disabled) - * @param expressionList list of strings already searched for - */ - public TabContents(Composite parent, ISDGraphNodeSupporter provider, Button okButton, String[] expressionList) { - super(parent, SWT.NONE); - fParentOkButton = okButton; - setLayout(new GridLayout()); - - GraphNodeTypeListener graphNodeTypeListener = new GraphNodeTypeListener(); - ExpressionListener expressionListener = new ExpressionListener(); - - // Inform the user how to fill the string to search - Label searchTitle = new Label(this, SWT.LEFT); - searchTitle.setText(Messages.SequenceDiagram_MatchingString); - Composite searchPart = new Composite(this, SWT.NONE); - GridData searchPartData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL); - GridLayout searchPartLayout = new GridLayout(); - searchPartLayout.numColumns = 2; - searchPart.setLayout(searchPartLayout); - searchPart.setLayoutData(searchPartData); - - // Create the user string input area - fSearchText = new Combo(searchPart, SWT.DROP_DOWN); - GridData comboData = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL); - /* - * GridData tabLayoutData2 = new GridData(GridData.HORIZONTAL_ALIGN_FILL| GridData.VERTICAL_ALIGN_FILL); - */ - fSearchText.setLayoutData(comboData); - if (expressionList != null) { - for (int i = 0; i < expressionList.length; i++) { - fSearchText.add(expressionList[i]); - } - } - fSearchText.addModifyListener(expressionListener); - - // Create the case sensitive check button - fCaseSensitive = new Button(searchPart, SWT.CHECK); - fCaseSensitive.setText(Messages.SequenceDiagram_CaseSensitive); - - // Create the group for searched graph node kind selection - Group kindSelection = new Group(this, SWT.SHADOW_NONE); - kindSelection.setText(Messages.SequenceDiagram_SearchFor); - // kindSelection.setLayoutData(tabLayoutData2); - GridLayout kindSelectionLayout = new GridLayout(); - kindSelectionLayout.numColumns = 1; - kindSelection.setLayout(kindSelectionLayout); - GridData kindSelectionData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL); - kindSelection.setLayoutData(kindSelectionData); - - // Create the lifeline check button - if (provider != null && provider.isNodeSupported(ISDGraphNodeSupporter.LIFELINE)) { - fLifelineButton = new Button(kindSelection, SWT.CHECK); - String nodeName = provider.getNodeName(ISDGraphNodeSupporter.LIFELINE, null); - if (nodeName != null) { - fLifelineButton.setText(nodeName); - } else { - fLifelineButton.setText(Messages.SequenceDiagram_Lifeline); - } - fLifelineButton.setEnabled(true); - fLifelineButton.addSelectionListener(graphNodeTypeListener); - } - - if (provider != null && provider.isNodeSupported(ISDGraphNodeSupporter.STOP)) { - // Create the stop check button - fStopButton = new Button(kindSelection, SWT.CHECK); - String nodeName = provider.getNodeName(ISDGraphNodeSupporter.STOP, null); - if (nodeName != null) { - fStopButton.setText(nodeName); - } else { - fStopButton.setText(Messages.SequenceDiagram_Stop); - } - - fStopButton.setEnabled(true); - fStopButton.addSelectionListener(graphNodeTypeListener); - } - - if (provider != null && provider.isNodeSupported(ISDGraphNodeSupporter.SYNCMESSAGE)) { - // Create the synchronous message check button - fSynMessageButton = new Button(kindSelection, SWT.CHECK); - String nodeName = provider.getNodeName(ISDGraphNodeSupporter.SYNCMESSAGE, null); - if (nodeName != null) { - fSynMessageButton.setText(nodeName); - } else { - fSynMessageButton.setText(Messages.SequenceDiagram_SynchronousMessage); - } - fSynMessageButton.setEnabled(true); - fSynMessageButton.addSelectionListener(graphNodeTypeListener); - } - - if (provider != null && provider.isNodeSupported(ISDGraphNodeSupporter.SYNCMESSAGERETURN)) { - // Create the synchronous message return check button - fSynMessageReturnButton = new Button(kindSelection, SWT.CHECK); - String nodeName = provider.getNodeName(ISDGraphNodeSupporter.SYNCMESSAGERETURN, null); - if (nodeName != null) { - fSynMessageReturnButton.setText(nodeName); - } else { - fSynMessageReturnButton.setText(Messages.SequenceDiagram_SynchronousMessageReturn); - } - fSynMessageReturnButton.setEnabled(true); - fSynMessageReturnButton.addSelectionListener(graphNodeTypeListener); - } - - if (provider != null && provider.isNodeSupported(ISDGraphNodeSupporter.ASYNCMESSAGE)) { - // Create the asynchronous message check button - fAsynMessageButton = new Button(kindSelection, SWT.CHECK); - String nodeName = provider.getNodeName(ISDGraphNodeSupporter.ASYNCMESSAGE, null); - if (nodeName != null) { - fAsynMessageButton.setText(nodeName); - } else { - fAsynMessageButton.setText(Messages.SequenceDiagram_AsynchronousMessage); - } - fAsynMessageButton.setEnabled(true); - fAsynMessageButton.addSelectionListener(graphNodeTypeListener); - } - - if (provider != null && provider.isNodeSupported(ISDGraphNodeSupporter.ASYNCMESSAGERETURN)) { - // Create the asynchronous message return check button - fAsynMessageReturnButton = new Button(kindSelection, SWT.CHECK); - String nodeName = provider.getNodeName(ISDGraphNodeSupporter.ASYNCMESSAGERETURN, null); - if (nodeName != null) { - fAsynMessageReturnButton.setText(nodeName); - } else { - fAsynMessageReturnButton.setText(Messages.SequenceDiagram_AsynchronousMessageReturn); - } - fAsynMessageReturnButton.setEnabled(true); - fAsynMessageReturnButton.addSelectionListener(graphNodeTypeListener); - } - - fResult = new Label(this, SWT.LEFT); - fResult.setText(Messages.SequenceDiagram_StringNotFound); - fResult.setVisible(false); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - /** - * Set result text visibility - * @param found true for found (enable visibility) else false - */ - public void setResult(boolean found) { - fResult.setVisible(!found); - } - - /** - * Updates parent OK button based on input data. - */ - public void updateOkButton() { - if (fParentOkButton == null) { - return; - } - boolean enabled = (fSearchText.getText() != null && !fSearchText.getText().equals("")) && //$NON-NLS-1$ - (isLifelineButtonSelected() || isStopButtonSelected() || isSynMessageButtonSelected() || isSynMessageReturnButtonSelected() || isAsynMessageButtonSelected() || isAsynMessageReturnButtonSelected()); - fParentOkButton.setEnabled(enabled); - } - - /** - * Sets the parent OK button reference. - * - * @param okButton The parent OK button - */ - public void setOkButton(Button okButton) { - fParentOkButton = okButton; - } - - /** - * Returns the asynchronous message check button state - * - * @return true if check, false otherwise - */ - public boolean isAsynMessageButtonSelected() { - if (fAsynMessageButton != null) { - return fAsynMessageButton.getSelection(); - } - return false; - } - - /** - * Returns the asynchronous message return check button state - * - * @return true if check, false otherwise - */ - public boolean isAsynMessageReturnButtonSelected() { - if (fAsynMessageReturnButton != null) { - return fAsynMessageReturnButton.getSelection(); - } - return false; - } - - /** - * Returns the case sensitive check button state - * - * @return true if check, false otherwise - */ - public boolean isCaseSensitiveSelected() { - if (fCaseSensitive != null) { - return fCaseSensitive.getSelection(); - } - return false; - } - - /** - * Returns the lifeline check button state - * - * @return true if check, false otherwise - */ - public boolean isLifelineButtonSelected() { - if (fLifelineButton != null) { - return fLifelineButton.getSelection(); - } - return false; - } - - /** - * Returns the user input string - * - * @return the string to search for - */ - public String getSearchText() { - return fSearchText.getText(); - } - - /** - * Returns the stop check button state - * - * @return true if check, false otherwise - */ - public boolean isStopButtonSelected() { - if (fStopButton != null) { - return fStopButton.getSelection(); - } - return false; - } - - /** - * Returns the synchronous message check button state - * - * @return true if check, false otherwise - */ - public boolean isSynMessageButtonSelected() { - if (fSynMessageButton != null) { - return fSynMessageButton.getSelection(); - } - return false; - } - - /** - * Returns the synchronous message return check button state - * - * @return true if check, false otherwise - */ - public boolean isSynMessageReturnButtonSelected() { - if (fSynMessageReturnButton != null) { - return fSynMessageReturnButton.getSelection(); - } - return false; - } - - /** - * Set the asynchronous message check button state - * - * @param state - * The new state to set - */ - public void setAsynMessageButtonSelection(boolean state) { - if (fAsynMessageButton != null) { - fAsynMessageButton.setSelection(state); - } - } - - /** - * Set the asynchronous message return check button state - * - * @param state - * The new state to set - */ - public void setAsynMessageReturnButtonSelection(boolean state) { - if (fAsynMessageReturnButton != null) { - fAsynMessageReturnButton.setSelection(state); - } - } - - /** - * Set the case sensitive check button state - * - * @param state - * The new state to set - */ - public void setCaseSensitiveSelection(boolean state) { - if (fCaseSensitive != null) { - fCaseSensitive.setSelection(state); - } - } - - /** - * Set the lifeline check button state - * - * @param state - * The new state to set - */ - public void setLifelineButtonSelection(boolean state) { - if (fLifelineButton != null) { - fLifelineButton.setSelection(state); - } - } - - /** - * Set the user input string - * - * @param text - * The search text - */ - public void setSearchText(String text) { - fSearchText.setText(text); - } - - /** - * Set the stop check button state - * - * @param state - * The new state to set - */ - public void setStopButtonSelection(boolean state) { - if (fStopButton != null) { - fStopButton.setSelection(state); - } - } - - /** - * Set the synchronous message check button state - * - * @param state - * The new state to set - */ - public void setSynMessageButtonSelection(boolean state) { - if (fSynMessageButton != null) { - fSynMessageButton.setSelection(state); - } - } - - /** - * Set the synchronous message return check button state - * - * @param state - * The new state to set - */ - public void setSynMessageReturnButtonSelection(boolean state) { - if (fSynMessageReturnButton != null) { - fSynMessageReturnButton.setSelection(state); - } - } - - // ------------------------------------------------------------------------ - // Helper classes - // ------------------------------------------------------------------------ - - /** - * Selection listener implementation for graph node types. - * @version 1.0 - */ - protected class GraphNodeTypeListener implements SelectionListener { - @Override - public void widgetDefaultSelected(SelectionEvent e) { - // Nothing to do - } - - @Override - public void widgetSelected(SelectionEvent e) { - updateOkButton(); - } - } - - /** - * Modify listener implementation for the expression field. - * - * @version 1.0 - */ - protected class ExpressionListener implements ModifyListener { - @Override - public void modifyText(ModifyEvent e) { - updateOkButton(); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/IColor.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/IColor.java deleted file mode 100755 index 7dd2575ef4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/IColor.java +++ /dev/null @@ -1,36 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings; - -/** - * Interface for handling a color resource. - * - * @version 1.0 - * @author sveyrier - */ -public interface IColor { - - /** - * Returns the contained color. Returned object must be an instance of org.eclipse.swt.graphics.Color if used with - * the org.eclipse.linuxtools.tmf.ui.views.uml2sd.NGC graphical context - * - * @return the color - */ - Object getColor(); - - /** - * Disposes the color - */ - void dispose(); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/IFont.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/IFont.java deleted file mode 100755 index b11d1e261b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/IFont.java +++ /dev/null @@ -1,36 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings; - -/** - * Interface for handling a font resource. - * - * @version 1.0 - * @author sveyrier - */ -public interface IFont { - - /** - * Returns the contained font. Returned object must be an instance of org.eclipse.swt.graphics.Font if used with the - * org.eclipse.linuxtools.tmf.ui.views.uml2sd.NGC graphical context - * - * @return the font - */ - Object getFont(); - - /** - * Disposes the font - */ - void dispose(); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/IGC.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/IGC.java deleted file mode 100755 index fba8aa7c14..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/IGC.java +++ /dev/null @@ -1,375 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings; - -/** - * Interface for a graphical context. - * - * @version 1.0 - * @author sveyrier - * - */ -public interface IGC { - - /** - * Set the current line style - * - * @param style the new line style - */ - void setLineStyle(int style); - - /** - * Returns current the line style used in the graphical context - * - * @return the current line style - */ - int getLineStyle(); - - /** - * Returns the contents x coordinate that is at the upper left corner of the view - * - * @return the contents x coordinate - */ - int getContentsX(); - - /** - * Returns the contents y coordinate that is at the upper left corner of the view - * - * @return the contents y coordinate - */ - int getContentsY(); - - /** - * Returns the contents visible width - * - * @return the contents width - */ - int getVisibleWidth(); - - /** - * Returns the contents visible height - * - * @return the contents height - */ - int getVisibleHeight(); - - /** - * Translates the given contents x coordinate into view x coordinate - * - * @param x the x coordinate to translate - * @return the corresponding view x coordinate - */ - int contentsToViewX(int x); - - /** - * Translates the given contents y coordinate into view y coordinate - * - * @param y the y coordinate to translate - * @return the corresponding view y coordinate - */ - int contentsToViewY(int y); - - /** - * Draws a line, using the foreground color, between the points (x1, y1) and (x2, y2). - * - * @param x1 the first point's x coordinate - * @param y1 the first point's y coordinate - * @param x2 the second point's x coordinate - * @param y2 the second point's y coordinate - */ - void drawLine(int x1, int y1, int x2, int y2); - - /** - * Draws the outline of the rectangle specified by the arguments, using the receiver's foreground color. The left - * and right edges of the rectangle are at x and x + width. The top and bottom edges are at y and y + height. - * - * @param x the x coordinate of the rectangle to be drawn - * @param y the y coordinate of the rectangle to be drawn - * @param width the width of the rectangle to be drawn - * @param height the height of the rectangle to be drawn - */ - void drawRectangle(int x, int y, int width, int height); - - /** - * Draws a rectangle, based on the specified arguments, which has the appearance of the platform's focus rectangle - * if the platform supports such a notion, and otherwise draws a simple rectangle in the receiver's foreground - * color. - * - * @param x the x coordinate of the rectangle - * @param y the y coordinate of the rectangle - * @param width the width of the rectangle - * @param height the height of the rectangle - */ - void drawFocus(int x, int y, int width, int height); - - /** - * Fills the interior of the closed polygon which is defined by the specified array of integer coordinates, using - * the receiver's background color. The array contains alternating x and y values which are considered to represent - * points which are the vertices of the polygon. Lines are drawn between each consecutive pair, and between the - * first pair and last pair in the array. - * - * @param points an array of alternating x and y values which are the vertices of the polygon - */ - void fillPolygon(int[] points); - - /** - * Draws the closed polygon which is defined by the specified array of integer coordinates, using the receiver's - * foreground color. The array contains alternating x and y values which are considered to represent points which - * are the vertices of the polygon. Lines are drawn between each consecutive pair, and between the first pair and - * last pair in the array. - * - * @param points an array of alternating x and y values which are the vertices of the polygon - */ - void drawPolygon(int[] points); - - /** - * Fills the interior of the rectangle specified by the arguments, using the receiver's background color. - * - * @param x the x coordinate of the rectangle to be filled - * @param y the y coordinate of the rectangle to be filled - * @param width the width of the rectangle to be filled - * @param height the height of the rectangle to be filled - */ - void fillRectangle(int x, int y, int width, int height); - - /** - * Fills the interior of the specified rectangle with a gradient sweeping from left to right or top to bottom - * progressing from the graphical context gradient color to its background color. - * - * @param x the x coordinate of the rectangle to be filled - * @param y the y coordinate of the rectangle to be filled - * @param width the width of the rectangle to be filled, may be negative (inverts direction of gradient if - * horizontal) - * @param height the height of the rectangle to be filled, may be negative (inverts direction of gradient if - * horizontal) - * @param vertical if true sweeps from top to bottom, else sweeps from left to right - */ - void fillGradientRectangle(int x, int y, int width, int height, boolean vertical); - - /** - * Returns the given string width in pixels - * - * @param name the string - * @return the string width - */ - int textExtent(String name); - - /** - * Draws the given string, using the receiver's current font and foreground color. Tab expansion and carriage return - * processing are performed. If trans is true, then the background of the rectangular area where the text is being - * drawn will not be modified, otherwise it will be filled with the receiver's background color. - * - * @param string the string to be drawn - * @param x the x coordinate of the top left corner of the rectangular area where the text is to be drawn - * @param y the y coordinate of the top left corner of the rectangular area where the text is to be drawn - * @param trans if true the background will be transparent, otherwise it will be opaque - */ - void drawText(String string, int x, int y, boolean trans); - - /** - * Draws the given string, using the receiver's current font and foreground color. Tab expansion and carriage return - * processing are performed. The background of the rectangular area where the text is being drawn will be filled - * with the receiver's background color. - * - * @param string the string to be drawn - * @param x the x coordinate of the top left corner of the rectangular area where the text is to be drawn - * @param y the y coordinate of the top left corner of the rectangular area where the text is to be drawn - */ - void drawText(String string, int x, int y); - - /** - * Fills the interior of an oval, within the specified rectangular area, with the receiver's background color. - * - * @param x the x coordinate of the upper left corner of the oval to be filled - * @param y the y coordinate of the upper left corner of the oval to be filled - * @param width the width of the oval to be filled - * @param height the width of the oval to be filled - */ - void fillOval(int x, int y, int width, int height); - - /** - * Returns current the background color used in the graphical context - * - * @return the background color - */ - IColor getBackground(); - - /** - * Returns current the background color used in the graphical context - * - * @return the background color - */ - IColor getForeground(); - - /** - * Set the graphical context foreground color - * - * @param color the foreground color - */ - void setBackground(IColor color); - - /** - * Set the graphical context background color - * - * @param color the background color - */ - void setForeground(IColor color); - - /** - * Set the color to use when filling regions using gradient. The color will progess from the given color to the - * current background color - * - * @param color the gardiient color to use - */ - void setGradientColor(IColor color); - - /** - * Set the line width to use for drawing - * - * @param width the line width - */ - void setLineWidth(int width); - - /** - * Returns the current graphical context line width used for drawing - * - * @return the line width - */ - int getLineWidth(); - - /** - * Returns the LineDotD style constant - * - * @return the constant value - */ - int getLineDotStyle(); - - /** - * Returns the LineDash style constant - * - * @return the constant - */ - int getLineDashStyle(); - - /** - * Returns the LineSolid style constant - * - * @return the constant - */ - int getLineSolidStyle(); - - /** - * Draws the given string centered into the given rectangle. If the string cannot fit in the rectangle area, the - * string is truncated. If trans is true, then the background of the rectangular area where the text is being drawn - * will not be modified, otherwise it will be filled with the receiver's background color. - * - * @param name the string to draw - * @param x the x coordinate of the rectangle to draw the string - * @param y the y coordinate of the rectangle to draw the string - * @param width the width of the rectangle to draw the string - * @param height the height of the rectangle to draw the string - * @param trans if true the background will be transparent, otherwise it will be opaque - */ - void drawTextTruncatedCentred(String name, int x, int y, int width, int height, boolean trans); - - /** - * Draws the given string into the given rectangle (left justify) If the string cannot fit in the rectangle area, - * the string is truncated. If trans is true, then the background of the rectangular area where the text is being - * drawn will not be modified, otherwise it will be filled with the receiver's background color. - * - * @param name The text to put in the rectangle - * @param x the x coordinate of the rectangle to draw the string - * @param y the y coordinate of the rectangle to draw the string - * @param width the width of the rectangle to draw the string - * @param height the height of the rectangle to draw the string - * @param trans if true the background will be transparent, otherwise it will be opaque - */ - void drawTextTruncated(String name, int x, int y, int width, int height, boolean trans); - - /** - * Copies a the source image into a (potentially different sized) rectangular area in the graphical context. If the - * source image has smaller sizes, then the source area will be stretched to fit the destination area as it is - * copied. - * - * @param image the image to draw - * @param x the x coordinate in the destination to copy to - * @param y the y coordinate in the destination to copy to - * @param maxWith the width in pixels of the destination rectangle - * @param maxHeight the height in pixels of the destination rectangle - */ - void drawImage(IImage image, int x, int y, int maxWith, int maxHeight); - - /** - * Draws the outline of a circular or elliptical arc within the specified rectangular area. The resulting arc begins - * at startAngle and extends for arcAngle degrees, using the current color. Angles are interpreted such that 0 - * degrees is at the 3 o'clock position. A positive value indicates a counter-clockwise rotation while a negative - * value indicates a clockwise rotation. The center of the arc is the center of the rectangle whose origin is (x, y) - * and whose size is specified by the width and height arguments. The resulting arc covers an area width + 1 pixels - * wide by height + 1 pixels tall. - * - * @param x the x coordinate of the upper-left corner of the arc to be drawn - * @param y the y coordinate of the upper-left corner of the arc to be drawn - * @param width the width of the arc to be drawn - * @param height the height of the arc to be drawn - * @param startAngle the beginning angle - * @param endAngle the ending angle - */ - void drawArc(int x, int y, int width, int height, int startAngle, int endAngle); - - /** - * Set the current font used in the graphical context - * - * @param font the font to use - */ - void setFont(IFont font); - - /** - * Returns the font height given font - * - * @param font The font to check for - * @return the the font height - */ - int getFontHeight(IFont font); - - /** - * Returns the average character width for the given font - * - * @param font The font to check for - * @return the average width - */ - int getFontWidth(IFont font); - - /** - * Creates a color with the given RGB values - * - * @param r the red component - * @param g the green component - * @param b the blue component - * @return the color - */ - IColor createColor(int r, int g, int b); - - /** - * Returns the zoom factor applied in both x and y directions when drawing - * - * @return the zoom factor - */ - float getZoom(); - - /** - * Draws text with focus style. - * - * @param focus true if item has focus else false - */ - void setDrawTextWithFocusStyle(boolean focus); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/IImage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/IImage.java deleted file mode 100755 index ec5db3fe10..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/IImage.java +++ /dev/null @@ -1,37 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings; - -/** - * Interface for handling a image resource. - * - * @version 1.0 - * @author sveyrier - * - */ -public interface IImage { - - /** - * Returns the contained image. Returned object must be an instance of org.eclipse.swt.graphics.Image if used with - * the org.eclipse.linuxtools.tmf.ui.views.uml2sd.NGC graphical context - * - * @return the color - */ - Object getImage(); - - /** - * Disposes the image - */ - void dispose(); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/impl/ColorImpl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/impl/ColorImpl.java deleted file mode 100755 index 940565050a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/impl/ColorImpl.java +++ /dev/null @@ -1,92 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.impl; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.widgets.Display; - -/** - * Default implementation of the IColor interface. - * - * @version 1.0 - * @author sveyrier - * - */ -public class ColorImpl implements IColor { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The color object. - */ - private final Color fColor; - /** - * Flag to indicate that this object is managing the resource. - */ - private boolean fManageColor = true; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Constructor - * - * @param display The display to use - * @param r A value for red - * @param g A value for green - * @param b A value for blue - */ - public ColorImpl(Display display, int r, int g, int b) { - fColor = new Color(display, r, g, b); - } - - /** - * Copy constructor - * - * @param color - * A color to copy - */ - protected ColorImpl(Color color) { - fColor = color; - fManageColor = false; - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - /** - * Returns a system color. - * - * @param color The color ID - * @return a system color - */ - public static ColorImpl getSystemColor(int color) { - return new ColorImpl(Display.getDefault().getSystemColor(color)); - } - - @Override - public Object getColor() { - return fColor; - } - - @Override - public void dispose() { - if ((fColor != null) && (fManageColor)) { - fColor.dispose(); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/impl/FontImpl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/impl/FontImpl.java deleted file mode 100755 index 6c7b2a95da..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/impl/FontImpl.java +++ /dev/null @@ -1,89 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.impl; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IFont; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.widgets.Display; - -/** - * Default implementation of the IFont interface. - * - * @version 1.0 - * @author sveyrier - * - */ -public class FontImpl implements IFont { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The font object - */ - private final Font fFont; - /** - * Flag to indicate that this object is managing the resource. - */ - protected boolean fManageFont = true; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor. - * - * @param display The display to use - * @param data A font data - */ - public FontImpl(Display display, FontData data) { - fFont = new Font(display, data); - } - - /** - * Copy constructor - * - * @param value A font to copy. - */ - protected FontImpl(Font value) { - fFont = value; - fManageFont = false; - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - /** - * Returns a font implementation based system font. - * - * @return a font implementation based system font. - */ - public static FontImpl getSystemFont() { - return new FontImpl(Display.getDefault().getSystemFont()); - } - - @Override - public Object getFont() { - return fFont; - } - - @Override - public void dispose() { - if (fFont != null) { - fFont.dispose(); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/impl/ImageImpl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/impl/ImageImpl.java deleted file mode 100755 index 9935315c6f..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/drawings/impl/ImageImpl.java +++ /dev/null @@ -1,105 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.impl; - -import java.net.MalformedURLException; -import java.net.URL; - -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IImage; -import org.eclipse.swt.graphics.Image; - -/** - * Default implementation of the IImage interface. - * - * @version 1.0 - * @author sveyrier - * - */ -public class ImageImpl implements IImage { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The image reference - */ - private final Image fImage; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor. - * - * @param file A file name of image file. - */ - public ImageImpl(String file) { - fImage = createResourceImage(file); - } - - /** - * Copy constructor - * - * @param image THe image to copy - */ - public ImageImpl(Image image) { - fImage = image; - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - /** - * Returns Image object from file name. - * - * @param name File name of image file - * @return image object or null - */ - public Image getResourceImage(String name) { - return createResourceImage(name); - } - - @Override - public Object getImage() { - return fImage; - } - - @Override - public void dispose() { - if (fImage != null) { - fImage.dispose(); - } - } - - /** - * Returns Image object from file name. - * - * @param name File name of image file - * @return image object or null - */ - private static Image createResourceImage(String name) { - try { - URL BASIC_URL = new URL("platform", "localhost", "plugin");//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - URL url = new URL(BASIC_URL, "plugin/org.eclipse.linuxtools.tmf.ui/icons/" + name);//$NON-NLS-1$ - ImageDescriptor img = ImageDescriptor.createFromURL(url); - return img.createImage(); - } catch (MalformedURLException e) { - Activator.getDefault().logError("Error opening image file", e); //$NON-NLS-1$ - } - return null; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/BaseSDAction.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/BaseSDAction.java deleted file mode 100644 index d32b0298fe..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/BaseSDAction.java +++ /dev/null @@ -1,89 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013 Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import org.eclipse.jface.action.Action; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; - -/** - * Base class for sequence diagram actions. - * - * @author Bernd Hufmann - * @since 2.0 - */ -public class BaseSDAction extends Action { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The sequence diagram view reference. - */ - private SDView fView = null; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor - */ - public BaseSDAction() { - this(null); - } - - /** - * Constructor - * - * @param view - * a sequence diagram view reference - */ - public BaseSDAction(SDView view) { - super(); - fView = view; - } - - /** - * Constructor - * @param view - * a sequence diagram view reference - * @param text - * The action text - * @param style - * The style - */ - protected BaseSDAction(SDView view, String text, int style) { - super(text, style); - fView = view; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Sets the active SD view. - * - * @param view The SD view. - */ - public void setView(SDView view) { - fView = view; - } - - /** - * Gets the active SD view. - * - * @return view The SD view. - * @since 2.0 - */ - public SDView getView() { - return fView; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/ConfigureMinMax.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/ConfigureMinMax.java deleted file mode 100755 index a9e62c3af6..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/ConfigureMinMax.java +++ /dev/null @@ -1,46 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.MinMaxDialog; - -/** - * Action class implementation to configure minimum and maximum time range values. - * - * @version 1.0 - * @author sveyrier - * - */ -public class ConfigureMinMax extends BaseSDAction { - - /** - * Constructor - * @param view - * the sequence diagram view reference - * @since 2.0 - */ - public ConfigureMinMax(SDView view) { - super(view); - } - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - @Override - public void run() { - if ((getView() != null) && (getView().getSDWidget() != null)) { - MinMaxDialog minMax = new MinMaxDialog(getView().getSite().getShell(), getView().getSDWidget()); - minMax.open(); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/FirstPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/FirstPage.java deleted file mode 100644 index dadf31b11f..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/FirstPage.java +++ /dev/null @@ -1,68 +0,0 @@ -/********************************************************************** - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; - -/** - * Action class implementation to move the focus to the first page of the whole sequence diagram. - * - * @version 1.0 - * @author Bernd Hufmann - */ -public class FirstPage extends BaseSDAction { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The action ID. - */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.firstpage"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor - * - * @param view the view reference - */ - public FirstPage(SDView view) { - super(view); - setText(Messages.SequenceDiagram_FirstPage); - setToolTipText(Messages.SequenceDiagram_GoToFirstPage); - setId(ID); - setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FIRST_PAGE)); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public void run() { - if ((getView() == null) || (getView().getSDWidget()) == null) { - return; - } - if (getView().getSDPagingProvider() != null) { - getView().getSDPagingProvider().firstPage(); - } - getView().updateCoolBar(); - getView().getSDWidget().redraw(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/KeyBindingsManager.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/KeyBindingsManager.java deleted file mode 100644 index 66b8b054f8..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/KeyBindingsManager.java +++ /dev/null @@ -1,302 +0,0 @@ -/********************************************************************** - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.handlers.IHandlerActivation; -import org.eclipse.ui.handlers.IHandlerService; - -/** - *

- * Singleton class that manages key-bindings for certain commands across multiple sequence - * diagram view instances. - *

- * - * @version 1.0 - * @author Bernd Hufmann - * - */ -public class KeyBindingsManager { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The singleton instance. - */ - private static KeyBindingsManager fInstance = null; - /** - * The list of view names. - */ - private Set fViews = new HashSet<>(); - /** - * The list of activations Activations to store - */ - private List fHandlerActivations = new ArrayList<>(); - /** - * The action reference for moving to a message in view. - */ - private MoveToMessage fGoToMessageForKeyBinding; - /** - * The action reference for opening the find dialog. - */ - private OpenSDFindDialog fFindForKeyBinding; - /** - * The action reference for moving up in view. - */ - private MoveSDUp fMoveUpForKeyBinding; - /** - * The action reference for moving down in view. - */ - private MoveSDDown fMoveDownForKeyBinding; - /** - * The action reference for moving left in view. - */ - private MoveSDLeft fMoveLeftForKeyBinding; - /** - * The action reference for moving right in view. - */ - private MoveSDRight fMoveRightForKeyBinding; - /** - * The action reference for showing node start. - */ - private ShowNodeStart fShowNodeStartForKeyBinding; - /** - * The action reference for showing node end. - */ - private ShowNodeEnd fShowNodeEndForKeyBinding; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructor - */ - protected KeyBindingsManager() { - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - /** - * Returns the KeyBindingsManager singleton instance. - * - * @return the KeyBindingsManager singleton instance - */ - public static synchronized KeyBindingsManager getInstance() { - if (fInstance == null) { - fInstance = new KeyBindingsManager(); - } - return fInstance; - } - - /** - * Adds a view list of managed view list. - * - * @param viewId Id of SD view to add and to manage - */ - public void add(String viewId) { - - if (fViews.isEmpty()) { - initialize(); - } - - if(!fViews.contains(viewId)) { - fViews.add(viewId); - } - } - - /** - * Removes a view from managed view list - * - * @param viewId Id of SD view to remove - */ - public void remove(String viewId) { - if (fViews.contains(viewId)) { - fViews.remove(viewId); - } - if (fViews.isEmpty()) { - dispose(); - } - } - - /* - * Initialized the KeyBindingsManager. - */ - private void initialize() { - fGoToMessageForKeyBinding = new MoveToMessage(); - IHandlerService service = (IHandlerService) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getService(IHandlerService.class); - AbstractHandler handler = new AbstractHandler() { - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - fGoToMessageForKeyBinding.run(); - return null; - } - }; - IHandlerActivation activation = service.activateHandler(fGoToMessageForKeyBinding.getActionDefinitionId(), handler); - fHandlerActivations.add(activation); - - fMoveUpForKeyBinding = new MoveSDUp(); - handler = new AbstractHandler() { - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - fMoveUpForKeyBinding.run(); - return null; - } - }; - activation = service.activateHandler(fMoveUpForKeyBinding.getActionDefinitionId(), handler); - fHandlerActivations.add(activation); - - fMoveDownForKeyBinding = new MoveSDDown(); - handler = new AbstractHandler() { - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - fMoveDownForKeyBinding.run(); - return null; - } - }; - activation = service.activateHandler(fMoveDownForKeyBinding.getActionDefinitionId(), handler); - fHandlerActivations.add(activation); - - fMoveLeftForKeyBinding = new MoveSDLeft(); - handler = new AbstractHandler() { - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - fMoveLeftForKeyBinding.run(); - return null; - } - }; - activation = service.activateHandler(fMoveLeftForKeyBinding.getActionDefinitionId(), handler); - fHandlerActivations.add(activation); - - fMoveRightForKeyBinding = new MoveSDRight(); - handler = new AbstractHandler() { - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - fMoveRightForKeyBinding.run(); - return null; - } - }; - activation = service.activateHandler(fMoveRightForKeyBinding.getActionDefinitionId(), handler); - fHandlerActivations.add(activation); - - fFindForKeyBinding = new OpenSDFindDialog(); - handler = new AbstractHandler() { - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - fFindForKeyBinding.run(); - return null; - } - }; - activation = service.activateHandler(fFindForKeyBinding.getActionDefinitionId(), handler); - fFindForKeyBinding.setEnabled(false); - fHandlerActivations.add(activation); - - fShowNodeStartForKeyBinding = new ShowNodeStart(); - fShowNodeStartForKeyBinding.setText(Messages.SequenceDiagram_ShowNodeStart); - - fShowNodeStartForKeyBinding.setId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ShowNodeStart");//$NON-NLS-1$ - fShowNodeStartForKeyBinding.setActionDefinitionId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ShowNodeStart");//$NON-NLS-1$ - - handler = new AbstractHandler() { - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - fShowNodeStartForKeyBinding.run(); - return null; - } - }; - activation = service.activateHandler(fShowNodeStartForKeyBinding.getActionDefinitionId(), handler); - fHandlerActivations.add(activation); - - fShowNodeEndForKeyBinding = new ShowNodeEnd(); - fShowNodeEndForKeyBinding.setText(Messages.SequenceDiagram_ShowNodeEnd); - fShowNodeEndForKeyBinding.setId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ShowNodeEnd");//$NON-NLS-1$ - fShowNodeEndForKeyBinding.setActionDefinitionId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ShowNodeEnd");//$NON-NLS-1$ - - handler = new AbstractHandler() { - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - fShowNodeEndForKeyBinding.run(); - return null; - } - }; - activation = service.activateHandler(fShowNodeEndForKeyBinding.getActionDefinitionId(), handler); - fHandlerActivations.add(activation); - - } - - /* - * Disposes the KeyBindingsManager - */ - private void dispose() { - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window == null) { - //During Eclipse shutdown the active workbench window is null - return; - } - IHandlerService service = (IHandlerService) window.getService(IHandlerService.class); - for(IHandlerActivation activation : fHandlerActivations) { - service.deactivateHandler(activation); - } - - fGoToMessageForKeyBinding = null; - fFindForKeyBinding = null; - fMoveUpForKeyBinding = null; - fMoveDownForKeyBinding = null; - fMoveLeftForKeyBinding = null; - fMoveRightForKeyBinding = null; - fShowNodeStartForKeyBinding = null; - fShowNodeEndForKeyBinding = null; - } - - /** - * Set the view in all supported actions - * - * @param view to set in global actions - */ - public void setSdView(SDView view) { - if (!fViews.isEmpty()) { - fGoToMessageForKeyBinding.setView(view); - fFindForKeyBinding.setView(view); - fMoveUpForKeyBinding.setView(view); - fMoveDownForKeyBinding.setView(view); - fMoveLeftForKeyBinding.setView(view); - fMoveRightForKeyBinding.setView(view); - fShowNodeStartForKeyBinding.setView(view); - fShowNodeEndForKeyBinding.setView(view); - } - } - - /** - * Enable / disable find action - * - * @param enabled true for enabling else false - */ - public void setFindEnabled(boolean enabled) { - if (fFindForKeyBinding != null) { - fFindForKeyBinding.setEnabled(enabled); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/LastPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/LastPage.java deleted file mode 100644 index 30f02c8fa3..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/LastPage.java +++ /dev/null @@ -1,68 +0,0 @@ -/********************************************************************** - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; - -/** - * Action class implementation to move the focus to the last page of the whole sequence diagram. - * - * @version 1.0 - * @author Bernd Hufmann - */ -public class LastPage extends BaseSDAction { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The action ID. - */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.lastpage"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Standard constructor - * - * @param view the view reference - */ - public LastPage(SDView view) { - super(view); - setText(Messages.SequenceDiagram_LastPage); - setToolTipText(Messages.SequenceDiagram_GoToLastPage); - setId(ID); - setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_LAST_PAGE)); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public void run() { - if ((getView() == null) || (getView().getSDWidget()) == null) { - return; - } - if (getView().getSDPagingProvider() != null) { - getView().getSDPagingProvider().lastPage(); - } - getView().updateCoolBar(); - getView().getSDWidget().redraw(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveSDDown.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveSDDown.java deleted file mode 100755 index d2726cb1c8..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveSDDown.java +++ /dev/null @@ -1,70 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget; - -/** - * Action class implementation to move down in the sequence diagram view within a page. - * - * @version 1.0 - * @author sveyrier - * - */ -public class MoveSDDown extends BaseSDAction { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The action ID. - */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.MoveSDDown"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor - */ - public MoveSDDown() { - this(null); - } - - /** - * Constructor - * - * @param view a sequence diagram view reference - */ - public MoveSDDown(SDView view) { - super(view); - setId(ID); - setActionDefinitionId(ID); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - @Override - public void run() { - if (getView() == null) { - return; - } - - SDWidget viewer = getView().getSDWidget(); - if (viewer != null) { - viewer.scrollBy(0, +viewer.getVisibleHeight()); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveSDLeft.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveSDLeft.java deleted file mode 100755 index 70c4b95cd2..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveSDLeft.java +++ /dev/null @@ -1,72 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget; - -/** - * Action class implementation to move left in the sequence diagram view within a page. - * - * @version 1.0 - * @author sveyrier - * - */ -public class MoveSDLeft extends BaseSDAction { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The action ID. - */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.MoveSDLeft"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor - */ - public MoveSDLeft(){ - this(null); - } - - /** - * Constructor - * - * @param view a sequence diagram view reference - */ - public MoveSDLeft(SDView view) { - super(view); - setId(ID); - setActionDefinitionId(ID); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Override - public void run() { - - if (getView() == null) { - return; - } - - SDWidget viewer = getView().getSDWidget(); - if (viewer != null) { - viewer.scrollBy(-viewer.getVisibleWidth(), 0); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveSDRight.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveSDRight.java deleted file mode 100755 index 6a20130f90..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveSDRight.java +++ /dev/null @@ -1,73 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget; - -/** - * Action class implementation to move right in the sequence diagram view within a page. - * - * @version 1.0 - * @author sveyrier - * - */ - -public class MoveSDRight extends BaseSDAction { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The action ID. - */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.MoveSDRight"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor - */ - public MoveSDRight() { - this(null); - } - - /** - * Constructor - * - * @param view a sequence diagram view reference - */ - public MoveSDRight(SDView view) { - super(view); - setId(ID); - setActionDefinitionId(ID); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public void run() { - - if (getView() == null) { - return; - } - - SDWidget viewer = getView().getSDWidget(); - if (viewer != null) { - viewer.scrollBy(+viewer.getVisibleWidth(), 0); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveSDUp.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveSDUp.java deleted file mode 100755 index caf8ec5311..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveSDUp.java +++ /dev/null @@ -1,71 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget; - -/** - * Action class implementation to move up in the sequence diagram view within a - * page. - * - * @version 1.0 - * @author sveyrier - */ -public class MoveSDUp extends BaseSDAction { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The action ID. - */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.MoveSDUp"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor - */ - public MoveSDUp() { - this(null); - } - - /** - * Constructor - * - * @param view a sequence diagram view reference - */ - public MoveSDUp(SDView view) { - super(view); - setId(ID); - setActionDefinitionId(ID); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public void run() { - if (getView() == null) { - return; - } - SDWidget viewer = getView().getSDWidget(); - - if (viewer != null) { - viewer.scrollBy(0, -viewer.getVisibleHeight()); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveToMessage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveToMessage.java deleted file mode 100755 index 4b966b195f..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/MoveToMessage.java +++ /dev/null @@ -1,113 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import java.util.Iterator; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.BaseMessage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SyncMessage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SyncMessageReturn; - -/** - * Action Class implementation to move to selected message - * - * @version 1.0 - * @author sveyrier - * - */ -public class MoveToMessage extends BaseSDAction { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The action ID. - */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.GoToMessage"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default Constructor - */ - public MoveToMessage() { - this(null); - } - - /** - * Constructor - * - * @param view a sequence diagram view reference - */ - public MoveToMessage(SDView view) { - super(view); - setId(ID); - setActionDefinitionId(ID); - setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SEARCH_MATCH)); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public void run() { - if (getView() == null) { - return; - } - - SDWidget sdWidget = getView().getSDWidget(); - - if (sdWidget == null) { - return; - } - - ISelectionProvider selProvider = sdWidget.getSelectionProvider(); - ISelection sel = selProvider.getSelection(); - Object selectedNode = null; - Iterator it = ((StructuredSelection) sel).iterator(); - while (it.hasNext()) { - Object node = it.next(); - if (node instanceof BaseMessage) { - selectedNode = node; - } - } - - if (selectedNode == null) { - return; - } - - if (selectedNode instanceof SyncMessageReturn) { - GraphNode node = ((SyncMessageReturn) selectedNode).getMessage(); - sdWidget.clearSelection(); - sdWidget.addSelection(node); - sdWidget.ensureVisible(node); - sdWidget.redraw(); - } else if (selectedNode instanceof SyncMessage) { - GraphNode node = ((SyncMessage) selectedNode).getMessageReturn(); - sdWidget.clearSelection(); - sdWidget.addSelection(node); - sdWidget.ensureVisible(node); - sdWidget.redraw(); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/NextPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/NextPage.java deleted file mode 100755 index 3e533f0c3c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/NextPage.java +++ /dev/null @@ -1,68 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; - -/** - * Action class implementation to move the focus to the next page of the whole sequence diagram. - * - * @version 1.0 - * @author sveyrier - * - */ -public class NextPage extends BaseSDAction { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The action ID. - */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.nextpage"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor - * - * @param view the view reference - */ - public NextPage(SDView view) { - super(view); - setText(Messages.SequenceDiagram_NextPage); - setToolTipText(Messages.SequenceDiagram_GoToNextPage); - setId(ID); - setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_PAGE)); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Override - public void run() { - if ((getView() == null) || (getView().getSDWidget()) == null) { - return; - } - if (getView().getSDPagingProvider() != null) { - getView().getSDPagingProvider().nextPage(); - } - getView().updateCoolBar(); - getView().getSDWidget().redraw(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/OpenSDFiltersDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/OpenSDFiltersDialog.java deleted file mode 100755 index 27fd1f25b4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/OpenSDFiltersDialog.java +++ /dev/null @@ -1,75 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.FilterListDialog; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDFilterProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; - -/** - * Action class implementation for 'Filtering' of messages/lifelines. - * - * @version 1.0 - * @author sveyrier - */ -public class OpenSDFiltersDialog extends BaseSDAction { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The action ID. - */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.sdFilters"; //$NON-NLS-1$ - - /** - * The filter provider reference - */ - private final ISDFilterProvider fProvider; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Constructor - * - * @param view - * The view reference - * @param provider - * The provider - */ - public OpenSDFiltersDialog(SDView view, ISDFilterProvider provider) { - super(view); - setText(Messages.SequenceDiagram_HidePatterns); - setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FILTERS)); - setId(ID); - setToolTipText(Messages.SequenceDiagram_HidePatterns); - fProvider = provider; - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public void run() { - if (getView() == null) { - return; - } - FilterListDialog dialog = new FilterListDialog(getView(), fProvider); - dialog.open(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/OpenSDFindDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/OpenSDFindDialog.java deleted file mode 100755 index 92cffd8713..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/OpenSDFindDialog.java +++ /dev/null @@ -1,93 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.SearchFilterDialog; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; -import org.eclipse.swt.SWT; - -/** - * Action class implementation for 'Finding' of messages/lifelines. - * - * @version 1.0 - * @author sveyrier - * - */ -public class OpenSDFindDialog extends BaseSDAction { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The action ID. - */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.sdFind"; //$NON-NLS-1$ - - /** - * The action definition ID. - */ - public static final String ACTION_DEFINITION_ID = "org.eclipse.ui.edit.findReplace"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor - */ - public OpenSDFindDialog() { - this(null); - } - - /** - * Constructor - * - * @param view The view reference - */ - public OpenSDFindDialog(SDView view) { - super(view); - setText(Messages.SequenceDiagram_Find + "..."); //$NON-NLS-1$ - setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SEARCH_SEQ)); - setId(ID); - setActionDefinitionId(ACTION_DEFINITION_ID); - setToolTipText(Messages.SequenceDiagram_Find + "..."); //$NON-NLS-1$ - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public void run() { - if (getView() == null) { - return; - } - - // Disable action while search is ongoing - this.setEnabled(false); - - try { - if ((getView().getExtendedFindProvider() != null) && (getView().getExtendedFindProvider().getFindAction() != null)) { - getView().getExtendedFindProvider().getFindAction().run(); - } else if (getView().getSDFindProvider() != null) { - SearchFilterDialog dialog = new SearchFilterDialog(getView(), getView().getSDFindProvider(), false, SWT.NORMAL); - dialog.open(); - } - } finally { - // Enable action after finishing the search - this.setEnabled(true); - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/OpenSDPagesDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/OpenSDPagesDialog.java deleted file mode 100755 index 160a73aad7..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/OpenSDPagesDialog.java +++ /dev/null @@ -1,80 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.PagesDialog; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDAdvancedPagingProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; - -/** - * Action class implementation for paging. - * - * @version 1.0 - * @author Bernd Hufmann - */ -public class OpenSDPagesDialog extends BaseSDAction { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The action ID. - */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.sdPaging"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The advanced paging provider reference. - */ - private final ISDAdvancedPagingProvider fProvider; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructor - * - * @param view - * The view reference - * @param provider - * The provider - */ - public OpenSDPagesDialog(SDView view, ISDAdvancedPagingProvider provider) { - super(view); - setText(Messages.SequenceDiagram_Pages); - setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_GOTO_PAGE)); - setId(ID); - fProvider = provider; - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Override - public void run() { - if (getView() == null) { - return; - } - PagesDialog dialog = new PagesDialog(getView(), fProvider); - dialog.open(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/PrevPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/PrevPage.java deleted file mode 100755 index 19c7779e78..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/PrevPage.java +++ /dev/null @@ -1,70 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; - -/** - * Action class implementation to move the focus to the previous page of the whole sequence diagram. - * - * @version 1.0 - * @author sveyrier - * - */ -public class PrevPage extends BaseSDAction { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The action ID. - */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.prevpage"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor - * - * @param view the view reference - */ - public PrevPage(SDView view) { - super(view); - setText(Messages.SequenceDiagram_PreviousPage); - setToolTipText(Messages.SequenceDiagram_GoToPreviousPage); - setId(ID); - setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_PAGE)); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public void run() { - if ((getView() == null) || (getView().getSDWidget()) == null) { - return; - } - if (getView().getSDPagingProvider() != null) { - getView().getSDPagingProvider().prevPage(); - } - getView().updateCoolBar(); - getView().getSDWidget().redraw(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/Print.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/Print.java deleted file mode 100755 index 9d638e90cb..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/Print.java +++ /dev/null @@ -1,60 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; - -/** - * Action class implementation for 'Printing'. - * - * @version 1.0 - * @author sveyrier - */ -public class Print extends BaseSDAction { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * The action ID. - */ - public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.print"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructor - * - * @param view The view reference - */ - public Print(SDView view) { - super(view); - setId(ID); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public void run() { - if ((getView() == null) || getView().getSDWidget() == null){ - return; - } - - getView().getSDWidget().print(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/ShowNodeEnd.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/ShowNodeEnd.java deleted file mode 100755 index 2d17ab4f1b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/ShowNodeEnd.java +++ /dev/null @@ -1,89 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import java.util.Iterator; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode; - -/** - * Action class implementation to show end of a graph node. - * - * @version 1.0 - * @author sveyrier - */ -public class ShowNodeEnd extends BaseSDAction { - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor - */ - public ShowNodeEnd() { - this(null); - } - - /** - * Constructor - * - * @param view The sequence diagram view reference - * @since 2.0 - */ - public ShowNodeEnd(SDView view) { - super(view); - setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NODE_END)); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - @Override - public void run() { - if (getView() == null) { - return; - } - - SDWidget sdWidget = getView().getSDWidget(); - - if (sdWidget == null) { - return; - } - - ISelectionProvider selProvider = sdWidget.getSelectionProvider(); - ISelection sel = selProvider.getSelection(); - Object selectedNode = null; - - Iterator it = ((StructuredSelection) sel).iterator(); - while (it.hasNext()) { - selectedNode = it.next(); - } - - if (selectedNode != null) { - GraphNode node = (GraphNode) selectedNode; - if ((node.getX() + node.getWidth()) * sdWidget.getZoomFactor() < sdWidget.getContentsX() + sdWidget.getVisibleWidth() / 2) { - sdWidget.ensureVisible(Math.round((node.getX() + node.getWidth()) * sdWidget.getZoomFactor()) - sdWidget.getVisibleWidth() / 2, Math.round((node.getY() + node.getHeight()) * sdWidget.getZoomFactor())); - } else { - sdWidget.ensureVisible(Math.round((node.getX() + node.getWidth()) * sdWidget.getZoomFactor() + sdWidget.getVisibleWidth() / (float) 2), Math.round((node.getY() + node.getHeight()) * sdWidget.getZoomFactor())); - } - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/ShowNodeStart.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/ShowNodeStart.java deleted file mode 100755 index 84767c0da8..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/ShowNodeStart.java +++ /dev/null @@ -1,89 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import java.util.Iterator; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode; - -/** - * Action class implementation to show end of a graph node. - * - * @version 1.0 - * @author sveyrier - */ -public class ShowNodeStart extends BaseSDAction { - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Default constructor - */ - public ShowNodeStart() { - this(null); - } - - /** - * Constructor - * - * @param view - * The sequence diagram view reference - * @since 2.0 - */ - public ShowNodeStart(SDView view) { - super(view); - setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NODE_START)); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public void run() { - if (getView() == null) { - return; - } - - SDWidget sdWidget = getView().getSDWidget(); - - if (sdWidget == null) { - return; - } - - ISelectionProvider selProvider = sdWidget.getSelectionProvider(); - ISelection sel = selProvider.getSelection(); - Object selectedNode = null; - Iterator it = ((StructuredSelection) sel).iterator(); - while (it.hasNext()) { - selectedNode = it.next(); - } - if (selectedNode != null) { - GraphNode node = (GraphNode) selectedNode; - if (node.getX() * sdWidget.getZoomFactor() < sdWidget.getContentsX() + sdWidget.getVisibleWidth() / 2) { - sdWidget.ensureVisible(Math.round(node.getX() * sdWidget.getZoomFactor() - sdWidget.getVisibleWidth() / (float) 2), Math.round(node.getY() * sdWidget.getZoomFactor())); - } else { - sdWidget.ensureVisible(Math.round(node.getX() * sdWidget.getZoomFactor() + sdWidget.getVisibleWidth() / (float) 2), Math.round(node.getY() * sdWidget.getZoomFactor())); - } - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/Zoom.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/Zoom.java deleted file mode 100755 index 1b12a8c63a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/Zoom.java +++ /dev/null @@ -1,239 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2014 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers; - -import org.eclipse.jface.action.ActionContributionItem; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IContributionItem; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IActionBars; - -/** - * Action class implementation for zooming in, out or reset of zoom. - * - * @version 1.0 - * @author sveyrier - * - */ -public class Zoom extends BaseSDAction { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The Action ID for zooming in. - */ - public static final String ZOOM_IN_ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ZoomInCoolBar"; //$NON-NLS-1$ - /** - * The Action ID for zooming out. - */ - public static final String ZOOM_OUT_ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ZoomOutCoolBar"; //$NON-NLS-1$ - /** - * The Action ID for reset zooming. - */ - public static final String RESET_ZOOM_ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ResetZoom"; //$NON-NLS-1$ - /** - * The Action ID for no zoominf. - */ - public static final String NO_ZOOM_ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.NoZoom"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * Flag to indicate last zoom in. - */ - private boolean fLastZoomIn = false; - /** - * Flag to indicate last zoom out. - */ - private boolean fLastZoomOut = false; - /** - * The cursor used when zooming in. - */ - private final Cursor fZoomInCursor; - /** - * The cursor used when zooming out. - */ - private final Cursor fZoomOutCursor; - - /** - * The different zoom actions - */ - public static enum ZoomType { - /** No zoom information */ - ZOOM_NONE, - /** Zoom in */ - ZOOM_IN, - /** Zoom out */ - ZOOM_OUT, - /** Reset to the default zoom level */ - ZOOM_RESET - } - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructor - * @param view The view reference - * @param type The type of zoom. - */ - public Zoom(SDView view, ZoomType type) { - super(view, "", AS_RADIO_BUTTON); //$NON-NLS-1$ - - // Pre-create zooming cursors - fZoomInCursor = new Cursor(Display.getCurrent(), - Activator.getDefault().getImageFromImageRegistry(ITmfImageConstants.IMG_UI_ZOOM_IN).getImageData(), - Activator.getDefault().getImageFromImageRegistry(ITmfImageConstants.IMG_UI_ZOOM).getImageData(), 0, 0); - - fZoomOutCursor = new Cursor(Display.getCurrent(), - Activator.getDefault().getImageFromImageRegistry(ITmfImageConstants.IMG_UI_ZOOM_OUT).getImageData(), - Activator.getDefault().getImageFromImageRegistry(ITmfImageConstants.IMG_UI_ZOOM).getImageData(), 0, 0); - - switch (type) { - case ZOOM_IN: - setText(Messages.SequenceDiagram_ZoomIn); - setToolTipText(Messages.SequenceDiagram_ZoomInTheDiagram); - setId(ZOOM_IN_ID); - setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ZOOM_IN_MENU)); - break; - - case ZOOM_OUT: - setText(Messages.SequenceDiagram_ZoomOut); - setToolTipText(Messages.SequenceDiagram_ZoomOutTheDiagram); - setId(ZOOM_OUT_ID); - setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ZOOM_OUT_MENU)); - break; - - case ZOOM_RESET: - setText(Messages.SequenceDiagram_ResetZoomFactor); - setToolTipText(Messages.SequenceDiagram_ResetZoomFactor); - setId(RESET_ZOOM_ID); - setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_HOME_MENU)); - break; - - case ZOOM_NONE: - default: - setText(Messages.SequenceDiagram_Select); - setToolTipText(Messages.SequenceDiagram_Select); - setId(NO_ZOOM_ID); - setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SELECT_MENU)); - break; - } - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public void run() { - - if ((getView() == null) || (getView().getSDWidget() == null)) { - return; - } - - SDWidget viewer = getView().getSDWidget(); - - if (getId().equals(ZOOM_OUT_ID)) { - // Eclipse 3.0 M7 workaround - if (fLastZoomOut == isChecked()) { - setChecked(!isChecked()); - } - - viewer.setZoomOutMode(isChecked()); - fLastZoomOut = isChecked(); - if (isChecked()) { - viewer.setCursor(fZoomOutCursor); - setActionChecked(NO_ZOOM_ID, false); - } else { - viewer.setCursor(new Cursor(Display.getDefault(), SWT.CURSOR_ARROW)); - setActionChecked(NO_ZOOM_ID, true); - } - } else if (getId().equals(ZOOM_IN_ID)) { - // Eclipse 3.0 M7 workaround - if (fLastZoomIn == isChecked()) { - setChecked(!isChecked()); - } - - viewer.setZoomInMode(isChecked()); - fLastZoomIn = isChecked(); - if (isChecked()) { - viewer.setCursor(fZoomInCursor); - setActionChecked(NO_ZOOM_ID, false); - } else { - viewer.setCursor(new Cursor(Display.getDefault(), SWT.CURSOR_ARROW)); - setActionChecked(NO_ZOOM_ID, true); - } - } else if (getId().equals(RESET_ZOOM_ID)) { - viewer.resetZoomFactor(); - - // The reset action is a radio button only to uncheck the zoom in and out button - // when it is clicked. This avoid adding code to do it manually - // We only have to force it to false every time - setChecked(false); - setActionChecked(NO_ZOOM_ID, true); - } else if (getId().equals(NO_ZOOM_ID)) { - setChecked(true); - viewer.setZoomInMode(false); - viewer.setZoomInMode(false); - viewer.setCursor(new Cursor(Display.getDefault(), SWT.CURSOR_ARROW)); - } - } - - /** - * Set action check state of a view action for a given action ID. - * - * @param id The action ID - * @param checked true to check the action, false to uncheck the action - */ - protected void setActionChecked(String id, boolean checked) { - if (getView() != null) { - IActionBars bar = getView().getViewSite().getActionBars(); - if (bar == null) { - return; - } - IToolBarManager barManager = bar.getToolBarManager(); - if (barManager == null) { - return; - } - IContributionItem nextPage = barManager.find(id); - if (nextPage instanceof ActionContributionItem) { - IAction action = ((ActionContributionItem) nextPage).getAction(); - if (action != null) { - action.setChecked(checked); - } - } - } - } - - /** - * Dispose the action and its resources - * - * @since 3.2 - */ - public void dispose() { - fZoomInCursor.dispose(); - fZoomOutCursor.dispose(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/IExtendedFilterProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/IExtendedFilterProvider.java deleted file mode 100755 index fb0ca6c650..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/IExtendedFilterProvider.java +++ /dev/null @@ -1,37 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider; - -import org.eclipse.jface.action.Action; - -/** - * Interface for providing an extended filter provider. - * - * Sequence Diagram loaders which implement this interface provide the action for filtering the sequence diagram.
- * - * Action provider are associated to a Sequence Diagram view by calling SDView.setExtendedFilterProvider
- * - * @version 1.0 - * @author sveyrier - * - */ -public interface IExtendedFilterProvider { - - /** - * Returns a filter action implementation. - * - * @return a filter action implementation - */ - Action getFilterAction(); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/IExtendedFindProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/IExtendedFindProvider.java deleted file mode 100755 index 8f91e419ff..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/IExtendedFindProvider.java +++ /dev/null @@ -1,38 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider; - -import org.eclipse.jface.action.Action; - -/** - * Interface for providing an extended find provider. - * - * Sequence Diagram loaders which implement this interface provide an action for finding in the sequence diagram. - * - * Action provider are associated to a Sequence Diagram view by calling SDView.setExtendedFindProvider().
- * - * Note that either provider implementing ISDFindProvider or IExtendedFindProvider can be active in the SDView.
- * - * @version 1.0 - * @author sveyrier - * - */ -public interface IExtendedFindProvider { - - /** - * Returns an extended find action. - * - * @return an extended find action - */ - Action getFindAction(); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDAdvancedPagingProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDAdvancedPagingProvider.java deleted file mode 100755 index 8fe4031c32..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDAdvancedPagingProvider.java +++ /dev/null @@ -1,51 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider; - -/** - * Interface for providing an extended find provider. - * - * An advanced paging provider is able to compute number of pages, and to display the number of items it treats on each - * page and for total counts.
- * An item can be a message, a node or anything meaningful from loader standpoint.
- * Items are only here for information to the user. - * - * @version 1.0 - * @author sveyrier - */ -public interface ISDAdvancedPagingProvider extends ISDPagingProvider { - - /** - * Returns the current page. - * - * @return the current page the loader is dealing with. Note that first page has the 0 index (indexes are from - * 0 to pagesCount()-1). - */ - int currentPage(); - - /** - * Returns the number of pages. - * - * @return number of pages the loader is dealing with - */ - int pagesCount(); - - /** - * Instructs a load of the <pageNumber_>th page.
- * Note that first page has the index 0 (indexes are from 0 to pagesCount()-1). - * - * @param pageNumber index of the page to load - */ - void pageNumberChanged(int pageNumber); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDCollapseProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDCollapseProvider.java deleted file mode 100755 index b0e9f56a90..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDCollapseProvider.java +++ /dev/null @@ -1,36 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline; - -/** - * Interface for providing a collapse provider. - * - * Sequence diagram loaders which want to support Drag and Drop collapsing in the sequence diagram must implement this - * interface and register this implementation using SDView.setCollapsingProvider(); - * - * @version 1.0 - * @author sveyrier - */ -public interface ISDCollapseProvider { - - /** - * Called back when the sequence diagram is requesting 2 lifelines collapsing - * - * @param lifeline1 - One of the lifeline to collapse - * @param lifeline2 - The other lifeline to collapse with - */ - void collapseTwoLifelines(Lifeline lifeline1, Lifeline lifeline2); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDExtendedActionBarProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDExtendedActionBarProvider.java deleted file mode 100755 index 3db07d2370..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDExtendedActionBarProvider.java +++ /dev/null @@ -1,37 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2012 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider; - -import org.eclipse.ui.IActionBars; - -/** - * Interface for providing an extended action bar provider. - * - * Sequence Diagram loaders which implement this interface provide their own action to the action bar. - * - * Action provider are associated to a Sequence Diagram SDWidget calling SDViewer.setExtendedActionBarProvider() - * - * @version 1.0 - * @author sveyrier - */ -public interface ISDExtendedActionBarProvider { - - /** - * The caller is supposed to add its own actions in the cool bar and the drop-down menu.
- * See examples in SDView.createCoolbarContent(). - * - * @param bar the bar - */ - void supplementCoolbarContent(IActionBars bar); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDFilterProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDFilterProvider.java deleted file mode 100755 index eb97dd01b4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDFilterProvider.java +++ /dev/null @@ -1,43 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider; - -import java.util.List; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.FilterCriteria; - -/** - * Interface for providing a filter provider. - * - * Sequence Diagram loaders which implement this class provide the actions filtering the sequence diagram.
- * This interface also allow the implementor to set which graph nodes are supporting filtering (thanks to - * ISDGraphNodeSupporter extension).
- * - * Action provider are associated to a Sequence Diagram view by calling SDView.setSDFilterProvider
- * - * Filters to be applied to be managed by the loader in an ArrayList of FilterCriteria.
- * - * @version 1.0 - * @author sveyrier - */ -public interface ISDFilterProvider extends ISDGraphNodeSupporter { - - /** - * Called when the Filter dialog box OK button is pressed - * - * @param filters user selection made in the dialog box - * @return true if the filter applied - */ - boolean filter(List filters); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDFindProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDFindProvider.java deleted file mode 100755 index 047a11bc92..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDFindProvider.java +++ /dev/null @@ -1,46 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.Criteria; - -/** - * Interface for providing a find provider. - * - * Sequence Diagram loaders which implement this class provide the actions for finding the sequence diagram. This - * interface also allow the implementor to set which action/feature are supported.
- * - * Action provider are associated to a Sequence Diagram view by calling SDView.setSDFindProvider().
- * - * Note that either provider implementing ISDFindProvider or IExtendedFindProvider can be active in the SDView.
- * - * @version 1.0 - * @author sveyrier - * - */ -public interface ISDFindProvider extends ISDGraphNodeSupporter { - - /** - * Called when the Find dialog box OK button is pressed - * - * @param toApply user selection made in the dialog box - * @return true if the find got a non empty result - */ - boolean find(Criteria toApply); - - /** - * Called when dialog is closed - */ - void cancel(); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDGraphNodeSupporter.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDGraphNodeSupporter.java deleted file mode 100755 index 0ec0a90032..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDGraphNodeSupporter.java +++ /dev/null @@ -1,83 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider; - -/** - * Interface for providing a graph node supporter. - * - * Sequence Diagram loaders which implement this class provide the actions for finding or filtering the sequence - * diagram. This interface also allow the implementor to set which action/feature are supported - * - * Action provider are associated to a Sequence Diagram SDWidget calling SDViewer.setSDFindProvider() or - * SDViewer.setSDFilterProvider(). - * - * @version 1.0 - * @author sveyrier - * - */ -public interface ISDGraphNodeSupporter { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * Lifeline support ID - */ - static int LIFELINE = 0; - /** - * Synchronous message support ID - */ - static int SYNCMESSAGE = 1; - /** - * Synchronous message return support ID - */ - static int SYNCMESSAGERETURN = 2; - /** - * Asynchronous message support ID - */ - static int ASYNCMESSAGE = 3; - /** - * Asynchronous message return support ID - */ - static int ASYNCMESSAGERETURN = 4; - /** - * Stop support ID - */ - static int STOP = 5; - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - /** - * Return true to enable this options, false otherwise - * - * @param nodeType - * The integer value matching the type of the node - * @return true to enable this options, false otherwise - */ - boolean isNodeSupported(int nodeType); - - /** - * Return the name to use in dialogs Not called if isNodeSupported return - * false - * - * @param nodeType - * The integer value matching the type of the node - * @param loaderClassName - * The name of the loader class - * @return the name to use in dialogs - */ - String getNodeName(int nodeType, String loaderClassName); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDPagingProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDPagingProvider.java deleted file mode 100755 index a0c77c287b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDPagingProvider.java +++ /dev/null @@ -1,61 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider; - -/** - * Paging provider interface. - * - * Sequence Diagram loaders which implement this class provide the actions for sequence diagram page navigation.
- * - * Action provider are associated to a Sequence Diagram view by calling SDView.setSDPagingProvider().
- * - * @version 1.0 - * @author sveyrier - * - */ -public interface ISDPagingProvider { - - /** - * Return true to enable the next page button in the coolBar, false otherwise - * - * @return true if a next page exists false otherwise - */ - boolean hasNextPage(); - - /** - * Return true to enable the previous page button in the coolBar, false otherwise - * - * @return true if a previous page exists false otherwise - */ - boolean hasPrevPage(); - - /** - * Called back when next page button is pressed in the coolBar - */ - void nextPage(); - - /** - * Called back when previous page button is pressed in the coolBar - */ - void prevPage(); - - /** - * Called back when first page button is pressed in the coolBar - */ - void firstPage(); - - /** - * Called back when last page button is pressed in the coolBar - */ - void lastPage(); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDPropertiesProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDPropertiesProvider.java deleted file mode 100755 index d2465488bb..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/handlers/provider/ISDPropertiesProvider.java +++ /dev/null @@ -1,35 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider; - -import org.eclipse.ui.views.properties.IPropertySheetPage; - -/** - * Interface for providing sequence diagram property. - * - * Contract for loaders that want to provide information in the properties view. - * - * @version 1.0 - * @author sveyrier - - */ -public interface ISDPropertiesProvider { - - /** - * Returns the IPropertySheetEntry that will fill in the properties view - * - * @return the property sheet entry - */ - IPropertySheetPage getPropertySheetEntry(); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/load/IUml2SDLoader.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/load/IUml2SDLoader.java deleted file mode 100755 index c1df537e0d..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/load/IUml2SDLoader.java +++ /dev/null @@ -1,46 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.load; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; - -/** - * The interface all UML2SD loaders must implement. - * - * @version 1.0 - * @author sveyrier - */ -public interface IUml2SDLoader { - - /** - * Set the viewer object to the loader that has been reloaded at the beginning - * of a new workbench session - * - * @param viewer The sequence diagram view - */ - void setViewer(SDView viewer); - - /** - * Returns title string for the UML2SD View when this loader is the one - * - * @return the string convenient for this loader - */ - String getTitleString(); - - /** - * When another loader becomes the one the previous one is replaced It's time clean-up - * if needed (listeners to be removed for example) - */ - void dispose(); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/load/LoadersManager.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/load/LoadersManager.java deleted file mode 100644 index 6afa54238f..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/load/LoadersManager.java +++ /dev/null @@ -1,397 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.load; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtension; -import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.Platform; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.ui.IViewReference; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -/** - * Manager class for the UML2SD extension point. - * - * @version 1.0 - * @author sveyrier - * @author Bernd Hufmann - */ -public class LoadersManager { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * The loader tag for the extension point. - */ - public static final String LOADER_TAG = "uml2SDLoader"; //$NON-NLS-1$ - /** - * The loader prefix. - */ - public static final String LOADER_PREFIX = LOADER_TAG + "."; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The LoadersManager singleton instance. - */ - private static LoadersManager fLoadersManager; - - /** - * Map for caching information (view ID to loader class) - */ - private Map fViewLoaderMap = new HashMap<>(); - /** - * Map for caching information (view ID to list of configuration elements) - */ - private Map> fViewLoadersList = new HashMap<>(); - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - /** - * This should not be used by the clients - */ - protected LoadersManager() { - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - /** - * A static method to get the manager instance. - * - * @return the manager instance - */ - public static synchronized LoadersManager getInstance() { - if (fLoadersManager == null) { - fLoadersManager = new LoadersManager(); - } - return fLoadersManager; - } - - /** - * Creates a loader instance and associate it to the view. It requires - * that the loader-view-association was created by an eclipse extension. - * - * @param className The name of the class to create an instance from - * @param view The UML2 Sequence Diagram view instance - * @return The created loader - */ - public IUml2SDLoader createLoader(String className, SDView view) { - - // Safety check - if (view == null) { - return null; - } - - String viewId = view.getViewSite().getId(); - - // Get loaders from all extensions for given view - List loaderElements = getLoaderConfigurationElements(viewId); - IConfigurationElement ce = getLoaderConfigurationElement(className, loaderElements); - - if (ce != null) { - // Assign a loader instance to this view - createLoaderForView(viewId, ce); - IUml2SDLoader loader = fViewLoaderMap.get(viewId); - if (loader != null) { - loader.setViewer(view); - return loader; - } - } - return null; - } - - /** - * Sets the loader to null for this view, a kind of clean-up while disposing. - * - * @param viewId the id of the view - */ - public void resetLoader(String viewId) { - IUml2SDLoader loader = fViewLoaderMap.get(viewId); - if (loader != null) { - loader.dispose(); - } - fViewLoaderMap.put(viewId, null); - } - - /** - * Returns the loader in use in given Sequence Diagram View - * - * @param viewId The Sequence Diagram viewId. - * @return the current loader if any - null otherwise - */ - public IUml2SDLoader getCurrentLoader(String viewId) { - return getCurrentLoader(viewId, null); - } - - /** - * Returns the loader in use in this Sequence Diagram View - * - * @param viewId The Sequence Diagram viewId - * @param view The Sequence Diagram view (if known). Use null to reference the primary SD View. - * @return the current loader if any - null otherwise - */ - public IUml2SDLoader getCurrentLoader(String viewId, SDView view) { - if (viewId == null) { - return null; - } - - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - // During Eclipse shutdown the active workbench window is null - if (window == null) { - return null; - } - - IWorkbenchPage persp = window.getActivePage(); - - SDView sdView = view; - - try { - // Search the view corresponding to the viewId - if (sdView == null) { - IViewReference viewref = persp.findViewReference(viewId); - if (viewref != null) { - sdView = (SDView) viewref.getView(false); - } - - if (sdView == null) { - // no corresponding view exists -> return null for the loader - return null; - } - } - - // Return the loader corresponding to that view (if any) - IUml2SDLoader loader = fViewLoaderMap.get(viewId); - if (loader == null) { - createLastLoaderIfAny(viewId); - loader = fViewLoaderMap.get(viewId); - } - - return loader; - } catch (Exception e) { - Activator.getDefault().logError("Error getting loader class", e); //$NON-NLS-1$ - } - return null; - } - - /** - * Returns the loader class name that have been saved last time. - * - * @param viewId The view this loader belongs to - * @return the class name of the saved loader - */ - public String getSavedLoader(String viewId) { - IPreferenceStore p = Activator.getDefault().getPreferenceStore(); - return p.getString(LOADER_PREFIX + viewId); - } - - /** - * Saves the last loader in order to reload it on next session. - * - * @param id - * Standalone ID of the loader - * @param id2 - * Suffix ID of the loader - */ - public void saveLastLoader(String id, String id2) { - IPreferenceStore p = Activator.getDefault().getPreferenceStore(); - p.setValue(LOADER_PREFIX + id2, id); - } - - /** - * Changes the current unique loader to the given secondary viewId. - * - * @param loader The current loader - * @param id the view secondary id or null - */ - private void setCurrentLoader(IUml2SDLoader loader, String id) { - if (id == null) { - return; - } - - // Get the loader in use - IUml2SDLoader currentLoader = fViewLoaderMap.get(id); - - if ((currentLoader != null) && (currentLoader != loader)) { - if (loader != null) { - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - // During Eclipse shutdown the active workbench window is null - if (window == null) { - return; - } - IWorkbenchPage persp = window.getActivePage(); - try { - // Search view corresponding to the viewId - SDView sdview = null; - IViewReference viewref = persp.findViewReference(id); - if (viewref != null) { - sdview = (SDView) viewref.getView(false); - } - - // Make everything clean for the new loader - if (sdview != null) { - sdview.resetProviders(); - } - - } catch (Exception e) { - Activator.getDefault().logError("Error setting current loader class", e); //$NON-NLS-1$ - } - } - // The old loader is going to be kicked - currentLoader.dispose(); - } - - // Replace the current loader by the new one in the map - fViewLoaderMap.put(id, loader); - - // Store this loader in the preferences to be able to restore it when the workbench will be re-launched - if (loader != null) { - saveLastLoader(loader.getClass().getName(), id); - } - } - - /** - * Creates the last loader and saves it. If not last is not available, it creates - * and saves the default loader, else no loader is created. - * - * @param viewId The view ID. - */ - private void createLastLoaderIfAny(String viewId) { - // Get saved loader from preferences - String loaderName = getSavedLoader(viewId); - - // Get loaders from all extensions for given view - List loaderElements = getLoaderConfigurationElements(viewId); - IConfigurationElement ce = getLoaderConfigurationElement(loaderName, loaderElements); - - if (ce == null) { - ce = getDefaultLoader(loaderElements); - } - - if (ce != null) { - createLoaderForView(viewId, ce); - } - } - - /** - * Gets a list of loader configuration elements from the extension point registry for a given view. - * @param viewId The view ID - * @return List of extension point configuration elements. - */ - private List getLoaderConfigurationElements(String viewId) { - List list = fViewLoadersList.get(viewId); - if (list != null) { - return list; - } - - ArrayList ret = new ArrayList<>(); - IExtensionPoint iep = Platform.getExtensionRegistry().getExtensionPoint(Activator.PLUGIN_ID, LOADER_TAG); - if (iep == null) { - return ret; - } - - IExtension[] ie = iep.getExtensions(); - if (ie == null) { - return ret; - } - - for (int i = 0; i < ie.length; i++) { - IConfigurationElement c[] = ie[i].getConfigurationElements(); - for (int j = 0; j < c.length; j++) { - if (viewId.equals(c[j].getAttribute("view"))) { //$NON-NLS-1$ - ret.add(c[j]); - } - } - } - fViewLoadersList.put(viewId, ret); - return ret; - } - - /** - * Returns the loader configuration element for given loader class name and for the given - * list of configuration elements, if available else null. - * - * @param loaderClassName The loader class name. - * @param loaderElements The list of loader configuration elements - * @return Extension point configuration element - */ - private static IConfigurationElement getLoaderConfigurationElement( - String loaderClassName, List loaderElements) { - if (loaderClassName != null && loaderClassName.length() > 0) { - // Find configuration element corresponding to the saved loader - for (Iterator i = loaderElements.iterator(); i.hasNext();) { - IConfigurationElement ce = i.next(); - if (ce.getAttribute("class").equals(loaderClassName)) { //$NON-NLS-1$ - return ce; - } - } - } - return null; - } - - /** - * Returns the loader configuration element for the given list of configuration elements, if available else null. - * Note that if multiple default loaders are defined it selects the first one - - * @param loaderElements The list of loader configuration elements - * @return The default extension point configuration element. - */ - private static IConfigurationElement getDefaultLoader( - List loaderElements) { - // Look for a default loader - for (Iterator i = loaderElements.iterator(); i.hasNext();) { - IConfigurationElement ce = i.next(); - if (Boolean.valueOf(ce.getAttribute("default")).booleanValue()) { //$NON-NLS-1$ - return ce; - } - } - return null; - } - - /** - * Creates an instance of the loader class for a given extension point configuration element and - * also sets it as current loader for the given view. - * - * @param viewId The view ID. - * @param ce The extension point configuration element - */ - private void createLoaderForView(String viewId, IConfigurationElement ce) { - try { - Object obj = ce.createExecutableExtension("class"); //$NON-NLS-1$ - IUml2SDLoader l = (IUml2SDLoader) obj; - if (viewId != null) { - setCurrentLoader(l, viewId); - } - } catch (CoreException e4) { - Activator.getDefault().logError("Error 'uml2SDLoader' Extension point", e4); //$NON-NLS-1$ - } catch (Exception e5) { - Activator.getDefault().logError("Error 'uml2SDLoader' Extension point", e5); //$NON-NLS-1$ - } - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/Messages.java deleted file mode 100644 index 0bf8fc5302..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/Messages.java +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Ericsson. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.loader; - -import org.eclipse.osgi.util.NLS; - -/** - * Messages related to the sequence diagram loader - * - * @version 1.0 - * @author Bernd Hufmann - */ -@SuppressWarnings("javadoc") -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.loader.messages"; //$NON-NLS-1$ - public static String TmfUml2SDSyncLoader_ViewName; - public static String TmfUml2SDSyncLoader_CategoryLifeline; - public static String TmfUml2SDSyncLoader_CategoryMessage; - public static String TmfUml2SDSyncLoader_FrameName; - public static String TmfUml2SDSyncLoader_SearchJobDescrition; - public static String TmfUml2SDSyncLoader_SearchNotFound; - - /** @since 2.0 */ - public static String TmfUml2SDSyncLoader_EventTypeSend; - /** @since 2.0 */ - public static String TmfUml2SDSyncLoader_EventTypeReceive; - /** @since 2.0 */ - public static String TmfUml2SDSyncLoader_FieldSender; - /** @since 2.0 */ - public static String TmfUml2SDSyncLoader_FieldReceiver; - /** @since 2.0 */ - public static String TmfUml2SDSyncLoader_FieldSignal; - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/TmfAsyncMessage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/TmfAsyncMessage.java deleted file mode 100644 index d9c9e50db4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/TmfAsyncMessage.java +++ /dev/null @@ -1,68 +0,0 @@ -/********************************************************************** - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.loader; - -import org.eclipse.linuxtools.tmf.core.uml2sd.ITmfAsyncSequenceDiagramEvent; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.AsyncMessage; - -/** - *

- * Extends AsyncMessage class to provide additional information about the trace event. - *

- * - * @version 1.0 - * @author Bernd Hufmann - */ -public class TmfAsyncMessage extends AsyncMessage implements ITmfAsyncSequenceDiagramEvent { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * A asynchronous sequence diagram event implementation - */ - private ITmfAsyncSequenceDiagramEvent fSdEvent; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Standard constructor - * - * @param sdEvent The asynchronous sequence diagram event implementation - * @param eventOccurrence The event index - */ - public TmfAsyncMessage(ITmfAsyncSequenceDiagramEvent sdEvent, int eventOccurrence) { - this.fSdEvent = sdEvent; - setEventOccurrence(eventOccurrence); - setName(sdEvent.getName()); - setStartTime(sdEvent.getStartTime()); - setEndTime(sdEvent.getEndTime()); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public String getSender() { - return fSdEvent.getSender(); - } - - @Override - public String getReceiver() { - return fSdEvent.getReceiver(); - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/TmfSyncMessage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/TmfSyncMessage.java deleted file mode 100644 index 890901b3b3..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/TmfSyncMessage.java +++ /dev/null @@ -1,68 +0,0 @@ -/********************************************************************** - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.loader; - -import org.eclipse.linuxtools.tmf.core.uml2sd.ITmfSyncSequenceDiagramEvent; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SyncMessage; - - -/** - *

- * Extends SyncMessage class to provide additional information about the trace event. - *

- * - * @version 1.0 - * @author Bernd Hufmann - */ -public class TmfSyncMessage extends SyncMessage implements ITmfSyncSequenceDiagramEvent { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * A synchronous sequence diagram event implementation - */ - private ITmfSyncSequenceDiagramEvent fSdEvent; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Standard constructor - * - * @param sdEvent The synchronous sequence diagram event implementation - * @param eventOccurrence The event index - */ - public TmfSyncMessage(ITmfSyncSequenceDiagramEvent sdEvent, int eventOccurrence) { - this.fSdEvent = sdEvent; - setEventOccurrence(eventOccurrence); - setName(sdEvent.getName()); - setTime(sdEvent.getStartTime()); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public String getSender() { - return fSdEvent.getSender(); - } - - @Override - public String getReceiver() { - return fSdEvent.getReceiver(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/TmfUml2SDSyncLoader.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/TmfUml2SDSyncLoader.java deleted file mode 100644 index 9ab09ac8b7..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/TmfUml2SDSyncLoader.java +++ /dev/null @@ -1,1485 +0,0 @@ -/********************************************************************** - * Copyright (c) 2011, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.loader; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.locks.ReentrantLock; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.component.TmfComponent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; -import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.eclipse.linuxtools.tmf.core.uml2sd.ITmfSyncSequenceDiagramEvent; -import org.eclipse.linuxtools.tmf.core.uml2sd.TmfSyncSequenceDiagramEvent; -import org.eclipse.linuxtools.tmf.ui.editors.ITmfTraceEditor; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Frame; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.Criteria; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.FilterCriteria; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.FilterListDialog; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDAdvancedPagingProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDFilterProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDFindProvider; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.load.IUml2SDLoader; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.ISelectionListener; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.progress.IProgressConstants; - -/** - *

- * This class is a reference implementation of the - * org.eclipse.linuxtools.tmf.ui.Uml2SDLoader extension point. It - * provides a Sequence Diagram loader for a user space trace with specific trace - * content for sending and receiving signals between components. I also includes - * a default implementation for the ITmfEvent parsing. - *

- * - * The class TmfUml2SDSyncLoader analyzes events from type - * ITmfEvent and creates events type - * ITmfSyncSequenceDiagramEvent if the ITmfEvent - * contains all relevant information. The analysis checks that the event type - * strings contains either string SEND or RECEIVE. If event type matches these - * key words, the analyzer will look for strings sender, receiver and signal in - * the event fields of type ITmfEventField. If all the data is - * found a sequence diagram event from can be created. Note that Sync Messages - * are assumed, which means start and end time are the same.
- *
- * The parsing of the ITmfEvent is done in the method - * getSequnceDiagramEvent() of class - * TmfUml2SDSyncLoader. By extending the class - * TmfUml2SDSyncLoader and overwriting - * getSequnceDiagramEvent() a customized parsing algorithm can be - * implemented.
- *
- * Note that combined traces of multiple components, that contain the trace - * information about the same interactions are not supported in the class - * TmfUml2SDSyncLoader. - * - * @version 1.0 - * @author Bernd Hufmann - */ -public class TmfUml2SDSyncLoader extends TmfComponent implements IUml2SDLoader, ISDFindProvider, ISDFilterProvider, ISDAdvancedPagingProvider, ISelectionListener { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * Default title name. - */ - protected static final String TITLE = Messages.TmfUml2SDSyncLoader_ViewName; - - /** - * Maximum number of messages per page. - */ - protected static final int MAX_NUM_OF_MSG = 10000; - - private static final int INDEXING_THREAD_SLEEP_VALUE = 100; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - // Experiment attributes - /** - * The TMF trace reference. - * @since 2.0 - */ - protected ITmfTrace fTrace = null; - /** - * The current indexing event request. - */ - protected ITmfEventRequest fIndexRequest = null; - /** - * The current request to fill a page. - */ - protected ITmfEventRequest fPageRequest = null; - /** - * Flag whether the time range signal was sent by this loader class or not - */ - protected volatile boolean fIsSignalSent = false; - - // The view and event attributes - /** - * The sequence diagram view reference. - */ - protected SDView fView = null; - /** - * The current sequence diagram frame reference. - */ - protected Frame fFrame = null; - /** - * The list of sequence diagram events of current page. - */ - protected List fEvents = new ArrayList<>(); - - // Checkpoint and page attributes - /** - * The checkpoints of the whole sequence diagram trace (i.e. start time stamp of each page) - */ - protected List fCheckPoints = new ArrayList<>(MAX_NUM_OF_MSG); - /** - * The current page displayed. - */ - protected volatile int fCurrentPage = 0; - /** - * The current time selected. - */ - protected ITmfTimestamp fCurrentTime = null; - /** - * Flag to specify that selection of message is done by selection or by signal. - */ - protected volatile boolean fIsSelect = false; - - // Search attributes - /** - * The job for searching across pages. - */ - protected SearchJob fFindJob = null; - /** - * List of found nodes within a page. - */ - protected List fFindResults = new ArrayList<>(); - /** - * The current find criteria reference - */ - protected Criteria fFindCriteria = null; - /** - * The current find index within the list of found nodes (fFindeResults within a page. - */ - protected volatile int fCurrentFindIndex = 0; - - // Filter attributes - /** - * The list of active filters. - */ - protected List fFilterCriteria = null; - - // Thread synchronization - /** - * The synchronization lock. - */ - protected ReentrantLock fLock = new ReentrantLock(); - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor - */ - public TmfUml2SDSyncLoader() { - super(TITLE); - } - - /** - * Constructor - * - * @param name Name of loader - */ - public TmfUml2SDSyncLoader(String name) { - super(name); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Returns the current time if available else null. - * - * @return the current time if available else null - * @since 2.0 - */ - public ITmfTimestamp getCurrentTime() { - fLock.lock(); - try { - if (fCurrentTime != null) { - return fCurrentTime; - } - return null; - } finally { - fLock.unlock(); - } - } - - /** - * Waits for the page request to be completed - */ - public void waitForCompletion() { - fLock.lock(); - ITmfEventRequest request = fPageRequest; - fLock.unlock(); - if (request != null) { - try { - request.waitForCompletion(); - } catch (InterruptedException e) { - // ignore - } - } - } - - /** - * Handler for the trace opened signal. - * @param signal The trace opened signal - * @since 2.0 - */ - @TmfSignalHandler - public void traceOpened(TmfTraceOpenedSignal signal) { - fTrace = signal.getTrace(); - loadTrace(); - } - - - /** - * Signal handler for the trace selected signal. - * - * Spawns a request to index the trace (checkpoints creation) as well as it fills - * the first page. - * - * @param signal The trace selected signal - * @since 2.0 - */ - @TmfSignalHandler - public void traceSelected(TmfTraceSelectedSignal signal) { - // Update the trace reference - ITmfTrace trace = signal.getTrace(); - if (!trace.equals(fTrace)) { - fTrace = trace; - } - loadTrace(); - } - - /** - * Method for loading the current selected trace into the view. - * Sub-class need to override this method to add the view specific implementation. - * @since 2.0 - */ - protected void loadTrace() { - ITmfEventRequest indexRequest = null; - fLock.lock(); - - try { - final Job job = new IndexingJob("Indexing " + getName() + "..."); //$NON-NLS-1$ //$NON-NLS-2$ - job.setUser(false); - job.schedule(); - - indexRequest = fIndexRequest; - - cancelOngoingRequests(); - - TmfTimeRange window = TmfTimeRange.ETERNITY; - - fIndexRequest = new TmfEventRequest(ITmfEvent.class, window, 0, - ITmfEventRequest.ALL_DATA, ITmfEventRequest.ExecutionType.BACKGROUND) { - - private ITmfTimestamp fFirstTime = null; - private ITmfTimestamp fLastTime = null; - private int fNbSeqEvents = 0; - private final List fSdEvents = new ArrayList<>(MAX_NUM_OF_MSG); - - @Override - public void handleData(ITmfEvent event) { - super.handleData(event); - - ITmfSyncSequenceDiagramEvent sdEvent = getSequenceDiagramEvent(event); - - if (sdEvent != null) { - ++fNbSeqEvents; - - if (fFirstTime == null) { - fFirstTime = event.getTimestamp(); - } - - fLastTime = event.getTimestamp(); - - if ((fNbSeqEvents % MAX_NUM_OF_MSG) == 0) { - fLock.lock(); - try { - fCheckPoints.add(new TmfTimeRange(fFirstTime, fLastTime)); - if (fView != null) { - fView.updateCoolBar(); - } - } finally { - fLock.unlock(); - } - fFirstTime = null; - - } - - if (fNbSeqEvents > MAX_NUM_OF_MSG) { - // page is full - return; - } - - fSdEvents.add(sdEvent); - - if (fNbSeqEvents == MAX_NUM_OF_MSG) { - fillCurrentPage(fSdEvents); - } - } - } - - @Override - public void handleSuccess() { - if ((fFirstTime != null) && (fLastTime != null)) { - - fLock.lock(); - try { - fCheckPoints.add(new TmfTimeRange(fFirstTime, fLastTime)); - if (fView != null) { - fView.updateCoolBar(); - } - } finally { - fLock.unlock(); - } - } - - if (fNbSeqEvents <= MAX_NUM_OF_MSG) { - fillCurrentPage(fSdEvents); - } - - super.handleSuccess(); - } - - @Override - public void handleCompleted() { - if (fEvents.isEmpty()) { - fFrame = new Frame(); - // make sure that view is not null when setting frame - SDView sdView; - fLock.lock(); - try { - sdView = fView; - } finally { - fLock.unlock(); - } - if (sdView != null) { - sdView.setFrameSync(fFrame); - } - } - super.handleCompleted(); - job.cancel(); - } - }; - - } finally { - fLock.unlock(); - } - if (indexRequest != null && !indexRequest.isCompleted()) { - indexRequest.cancel(); - } - resetLoader(); - fTrace.sendRequest(fIndexRequest); - } - - /** - * Signal handler for the trace closed signal. - * - * @param signal The trace closed signal - * @since 2.0 - */ - @TmfSignalHandler - public void traceClosed(TmfTraceClosedSignal signal) { - if (signal.getTrace() != fTrace) { - return; - } - ITmfEventRequest indexRequest = null; - fLock.lock(); - try { - indexRequest = fIndexRequest; - fIndexRequest = null; - - cancelOngoingRequests(); - - if (fFilterCriteria != null) { - fFilterCriteria.clear(); - } - - FilterListDialog.deactivateSavedGlobalFilters(); - } finally { - fTrace = null; - fLock.unlock(); - } - if (indexRequest != null && !indexRequest.isCompleted()) { - indexRequest.cancel(); - } - - resetLoader(); - } - - /** - * Moves to the page that contains the time provided by the signal. The messages will be selected - * if the provided time is the time of a message. - * - * @param signal The Time synch signal. - */ - @TmfSignalHandler - public void synchToTime(TmfTimeSynchSignal signal) { - fLock.lock(); - try { - if ((signal.getSource() != this) && (fFrame != null) && (fCheckPoints.size() > 0)) { - fCurrentTime = signal.getBeginTime(); - fIsSelect = true; - moveToMessage(); - } - } finally { - fLock.unlock(); - } - } - - /** - * Moves to the page that contains the current time provided by signal. - * No message will be selected however the focus will be set to the message - * if the provided time is the time of a message. - * - * @param signal The time range sync signal - */ - @TmfSignalHandler - public void synchToTimeRange(TmfRangeSynchSignal signal) { - fLock.lock(); - try { - if ((signal.getSource() != this) && (fFrame != null) && !fIsSignalSent && (fCheckPoints.size() > 0)) { - TmfTimeRange newTimeRange = signal.getCurrentRange(); - - fIsSelect = false; - fCurrentTime = newTimeRange.getStartTime(); - - moveToMessage(); - } - } finally { - fLock.unlock(); - } - - } - - @Override - public void setViewer(SDView viewer) { - - fLock.lock(); - try { - fView = viewer; - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().addPostSelectionListener(this); - fView.setSDFindProvider(this); - fView.setSDPagingProvider(this); - fView.setSDFilterProvider(this); - - resetLoader(); - IEditorPart editor = fView.getSite().getPage().getActiveEditor(); - if (editor instanceof ITmfTraceEditor) { - ITmfTrace trace = ((ITmfTraceEditor) editor).getTrace(); - if (trace != null) { - traceSelected(new TmfTraceSelectedSignal(this, trace)); - } - } - } finally { - fLock.unlock(); - } - } - - @Override - public String getTitleString() { - return getName(); - } - - @Override - public void dispose() { - super.dispose(); - ITmfEventRequest indexRequest = null; - fLock.lock(); - try { - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - // During Eclipse shutdown the active workbench window is null - if (window != null) { - window.getSelectionService().removePostSelectionListener(this); - } - - indexRequest = fIndexRequest; - fIndexRequest = null; - cancelOngoingRequests(); - - fView.setSDFindProvider(null); - fView.setSDPagingProvider(null); - fView.setSDFilterProvider(null); - fView = null; - } finally { - fLock.unlock(); - } - if (indexRequest != null && !indexRequest.isCompleted()) { - indexRequest.cancel(); - } - } - - @Override - public boolean isNodeSupported(int nodeType) { - switch (nodeType) { - case ISDGraphNodeSupporter.LIFELINE: - case ISDGraphNodeSupporter.SYNCMESSAGE: - return true; - - default: - break; - } - return false; - } - - @Override - public String getNodeName(int nodeType, String loaderClassName) { - switch (nodeType) { - case ISDGraphNodeSupporter.LIFELINE: - return Messages.TmfUml2SDSyncLoader_CategoryLifeline; - case ISDGraphNodeSupporter.SYNCMESSAGE: - return Messages.TmfUml2SDSyncLoader_CategoryMessage; - default: - break; - } - return ""; //$NON-NLS-1$ - } - - @Override - public void selectionChanged(IWorkbenchPart part, ISelection selection) { - ISelection sel = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().getSelection(); - if ((sel != null) && (sel instanceof StructuredSelection)) { - StructuredSelection stSel = (StructuredSelection) sel; - if (stSel.getFirstElement() instanceof TmfSyncMessage) { - TmfSyncMessage syncMsg = ((TmfSyncMessage) stSel.getFirstElement()); - broadcast(new TmfTimeSynchSignal(this, syncMsg.getStartTime())); - } - } - } - - @Override - public boolean find(Criteria toSearch) { - fLock.lock(); - try { - if (fFrame == null) { - return false; - } - - if ((fFindResults == null) || (fFindCriteria == null) || !fFindCriteria.compareTo(toSearch)) { - fFindResults = new CopyOnWriteArrayList<>(); - fFindCriteria = toSearch; - if (fFindCriteria.isLifeLineSelected()) { - for (int i = 0; i < fFrame.lifeLinesCount(); i++) { - if (fFindCriteria.matches(fFrame.getLifeline(i).getName())) { - fFindResults.add(fFrame.getLifeline(i)); - } - } - } - - ArrayList msgs = new ArrayList<>(); - if (fFindCriteria.isSyncMessageSelected()) { - for (int i = 0; i < fFrame.syncMessageCount(); i++) { - if (fFindCriteria.matches(fFrame.getSyncMessage(i).getName())) { - msgs.add(fFrame.getSyncMessage(i)); - } - } - } - - if (!msgs.isEmpty()) { - fFindResults.addAll(msgs); - } - - List selection = fView.getSDWidget().getSelection(); - if ((selection != null) && (selection.size() == 1)) { - fCurrentFindIndex = fFindResults.indexOf(selection.get(0)) + 1; - } else { - fCurrentFindIndex = 0; - } - } else { - fCurrentFindIndex++; - } - - if (fFindResults.size() > fCurrentFindIndex) { - GraphNode current = fFindResults.get(fCurrentFindIndex); - fView.getSDWidget().moveTo(current); - return true; - } - fFindResults = null; - fCurrentFindIndex =0; - return findInNextPages(fFindCriteria); // search in other page - } finally { - fLock.unlock(); - } - } - - @Override - public void cancel() { - cancelOngoingRequests(); - } - - @Override - public boolean filter(List filters) { - fLock.lock(); - try { - cancelOngoingRequests(); - - if (filters == null) { - fFilterCriteria = new ArrayList<>(); - } else { - List list = filters; - fFilterCriteria = new ArrayList<>(list); - } - - fillCurrentPage(fEvents); - - } finally { - fLock.unlock(); - } - return true; - } - - @Override - public boolean hasNextPage() { - fLock.lock(); - try { - int size = fCheckPoints.size(); - if (size > 0) { - return fCurrentPage < (size - 1); - } - } finally { - fLock.unlock(); - } - return false; - } - - @Override - public boolean hasPrevPage() { - fLock.lock(); - try { - return fCurrentPage > 0; - } finally { - fLock.unlock(); - } - } - - @Override - public void nextPage() { - fLock.lock(); - try { - // Safety check - if (fCurrentPage >= (fCheckPoints.size() - 1)) { - return; - } - - cancelOngoingRequests(); - fCurrentTime = null; - fCurrentPage++; - moveToPage(); - } finally { - fLock.unlock(); - } - } - - @Override - public void prevPage() { - fLock.lock(); - try { - // Safety check - if (fCurrentPage <= 0) { - return; - } - - cancelOngoingRequests(); - fCurrentTime = null; - fCurrentPage--; - moveToPage(); - } finally { - fLock.unlock(); - } - } - - @Override - public void firstPage() { - fLock.lock(); - try { - - cancelOngoingRequests(); - fCurrentTime = null; - fCurrentPage = 0; - moveToPage(); - } finally { - fLock.unlock(); - } - } - - @Override - public void lastPage() { - fLock.lock(); - try { - cancelOngoingRequests(); - fCurrentTime = null; - fCurrentPage = fCheckPoints.size() - 1; - moveToPage(); - } finally { - fLock.unlock(); - } - } - - @Override - public int currentPage() { - fLock.lock(); - try { - return fCurrentPage; - } finally { - fLock.unlock(); - } - } - - @Override - public int pagesCount() { - fLock.lock(); - try { - return fCheckPoints.size(); - } finally { - fLock.unlock(); - } - } - - @Override - public void pageNumberChanged(int pagenNumber) { - int localPageNumber = pagenNumber; - - fLock.lock(); - try { - cancelOngoingRequests(); - - if (localPageNumber < 0) { - localPageNumber = 0; - } - int size = fCheckPoints.size(); - if (localPageNumber > (size - 1)) { - localPageNumber = size - 1; - } - fCurrentPage = localPageNumber; - moveToPage(); - } finally { - fLock.unlock(); - } - } - - @Override - public void broadcast(TmfSignal signal) { - fIsSignalSent = true; - super.broadcast(signal); - fIsSignalSent = false; - } - - /** - * Cancels any ongoing find operation - */ - protected void cancelOngoingRequests() { - fLock.lock(); - ITmfEventRequest pageRequest = null; - try { - // Cancel the search thread - if (fFindJob != null) { - fFindJob.cancel(); - } - - fFindResults = null; - fFindCriteria = null; - fCurrentFindIndex = 0; - - pageRequest = fPageRequest; - fPageRequest = null; - } finally { - fLock.unlock(); - } - if (pageRequest != null && !pageRequest.isCompleted()) { - pageRequest.cancel(); - } - } - - /** - * Resets loader attributes - */ - protected void resetLoader() { - fLock.lock(); - try { - fCurrentTime = null; - fEvents.clear(); - fCheckPoints.clear(); - fCurrentPage = 0; - fCurrentFindIndex = 0; - fFindCriteria = null; - fFindResults = null; - fView.setFrameSync(new Frame()); - fFrame = null; - } - finally { - fLock.unlock(); - } - - } - - /** - * Fills current page with sequence diagram content. - * - * @param events sequence diagram events - */ - protected void fillCurrentPage(List events) { - - fLock.lock(); - try { - fEvents = new ArrayList<>(events); - if (fView != null && !events.isEmpty()) { - fView.toggleWaitCursorAsync(true); - } - } finally { - fLock.unlock(); - } - - final Frame frame = new Frame(); - - if (!events.isEmpty()) { - Map nodeToLifelineMap = new HashMap<>(); - - frame.setName(Messages.TmfUml2SDSyncLoader_FrameName); - - for (int i = 0; i < events.size(); i++) { - - ITmfSyncSequenceDiagramEvent sdEvent = events.get(i); - - if ((nodeToLifelineMap.get(sdEvent.getSender()) == null) && (!filterLifeLine(sdEvent.getSender()))) { - Lifeline lifeline = new Lifeline(); - lifeline.setName(sdEvent.getSender()); - nodeToLifelineMap.put(sdEvent.getSender(), lifeline); - frame.addLifeLine(lifeline); - } - - if ((nodeToLifelineMap.get(sdEvent.getReceiver()) == null) && (!filterLifeLine(sdEvent.getReceiver()))) { - Lifeline lifeline = new Lifeline(); - lifeline.setName(sdEvent.getReceiver()); - nodeToLifelineMap.put(sdEvent.getReceiver(), lifeline); - frame.addLifeLine(lifeline); - } - } - - int eventOccurence = 1; - - for (int i = 0; i < events.size(); i++) { - ITmfSyncSequenceDiagramEvent sdEvent = events.get(i); - - // Check message filter - if (filterMessage(sdEvent)) { - continue; - } - - // Set the message sender and receiver - Lifeline startLifeline = nodeToLifelineMap.get(sdEvent.getSender()); - Lifeline endLifeline = nodeToLifelineMap.get(sdEvent.getReceiver()); - - // Check if any of the lifelines were filtered - if ((startLifeline == null) || (endLifeline == null)) { - continue; - } - - int tmp = Math.max(startLifeline.getEventOccurrence(), endLifeline.getEventOccurrence()); - eventOccurence = Math.max(eventOccurence, tmp); - - startLifeline.setCurrentEventOccurrence(eventOccurence); - endLifeline.setCurrentEventOccurrence(eventOccurence); - - TmfSyncMessage message = new TmfSyncMessage(sdEvent, eventOccurence++); - - message.setStartLifeline(startLifeline); - message.setEndLifeline(endLifeline); - - message.setTime(sdEvent.getStartTime()); - - // add the message to the frame - frame.addMessage(message); - - } - fLock.lock(); - try { - if (!fView.getSDWidget().isDisposed()) { - fView.getSDWidget().getDisplay().asyncExec(new Runnable() { - - @Override - public void run() { - - fLock.lock(); - try { - // check if view was disposed in the meanwhile - if ((fView != null) && (!fView.getSDWidget().isDisposed())) { - fFrame = frame; - fView.setFrame(fFrame); - - if (fCurrentTime != null) { - moveToMessageInPage(); - } - - if (fFindCriteria != null) { - find(fFindCriteria); - } - - fView.toggleWaitCursorAsync(false); - } - } finally { - fLock.unlock(); - } - - } - }); - } - } - finally { - fLock.unlock(); - } - } - } - - /** - * Moves to a certain message defined by timestamp (across pages) - */ - protected void moveToMessage() { - int page = 0; - - fLock.lock(); - try { - page = getPage(fCurrentTime); - - if (page == fCurrentPage) { - moveToMessageInPage(); - return; - } - fCurrentPage = page; - moveToPage(false); - } finally { - fLock.unlock(); - } - } - - /** - * Moves to a certain message defined by timestamp in current page - */ - protected void moveToMessageInPage() { - fLock.lock(); - try { - if (!fView.getSDWidget().isDisposed()) { - // Check for GUI thread - if(Display.getCurrent() != null) { - // Already in GUI thread - execute directly - TmfSyncMessage prevMessage = null; - TmfSyncMessage syncMessage = null; - boolean isExactTime = false; - for (int i = 0; i < fFrame.syncMessageCount(); i++) { - if (fFrame.getSyncMessage(i) instanceof TmfSyncMessage) { - syncMessage = (TmfSyncMessage) fFrame.getSyncMessage(i); - if (syncMessage.getStartTime().compareTo(fCurrentTime, false) == 0) { - isExactTime = true; - break; - } else if ((syncMessage.getStartTime().compareTo(fCurrentTime, false) > 0) && (prevMessage != null)) { - syncMessage = prevMessage; - break; - } - prevMessage = syncMessage; - } - } - if (fIsSelect && isExactTime) { - fView.getSDWidget().moveTo(syncMessage); - } - else { - fView.getSDWidget().ensureVisible(syncMessage); - fView.getSDWidget().clearSelection(); - fView.getSDWidget().redraw(); - } - } - else { - // Not in GUI thread - queue action in GUI thread. - fView.getSDWidget().getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - moveToMessageInPage(); - } - }); - } - } - } - finally { - fLock.unlock(); - } - } - - /** - * Moves to a certain message defined by timestamp (across pages) - */ - protected void moveToPage() { - moveToPage(true); - } - - /** - * Moves to a certain page. - * - * @param notifyAll true to broadcast time range signal to other signal handlers else false - */ - protected void moveToPage(boolean notifyAll) { - - TmfTimeRange window = null; - - fLock.lock(); - try { - // Safety check - if (fCurrentPage > fCheckPoints.size()) { - return; - } - window = fCheckPoints.get(fCurrentPage); - } finally { - fLock.unlock(); - } - - if (window == null) { - window = TmfTimeRange.ETERNITY; - } - - fPageRequest = new TmfEventRequest(ITmfEvent.class, window, 0, - ITmfEventRequest.ALL_DATA, ITmfEventRequest.ExecutionType.FOREGROUND) { - private final List fSdEvent = new ArrayList<>(); - - @Override - public void handleData(ITmfEvent event) { - super.handleData(event); - - ITmfSyncSequenceDiagramEvent sdEvent = getSequenceDiagramEvent(event); - - if (sdEvent != null) { - fSdEvent.add(sdEvent); - } - } - - @Override - public void handleSuccess() { - fillCurrentPage(fSdEvent); - super.handleSuccess(); - } - - }; - - fTrace.sendRequest(fPageRequest); - - if (notifyAll) { - TmfTimeRange timeRange = getSignalTimeRange(window.getStartTime()); - broadcast(new TmfRangeSynchSignal(this, timeRange)); - } - } - - /** - * Gets page that contains timestamp - * - * @param time The timestamp - * @return page that contains the time - * @since 2.0 - */ - protected int getPage(ITmfTimestamp time) { - int page; - int size; - fLock.lock(); - try { - size = fCheckPoints.size(); - for (page = 0; page < size; page++) { - TmfTimeRange timeRange = fCheckPoints.get(page); - if (timeRange.getEndTime().compareTo(time, false) >= 0) { - break; - } - } - if (page >= size) { - page = size - 1; - } - return page; - } finally { - fLock.unlock(); - } - } - - /** - * Background search in trace for expression in criteria. - * - * @param findCriteria The find criteria - * @return true if background request was started else false - */ - protected boolean findInNextPages(Criteria findCriteria) { - fLock.lock(); - try { - if (fFindJob != null) { - return true; - } - - int nextPage = fCurrentPage + 1; - - if ((nextPage) >= fCheckPoints.size()) { - // we are at the end - return false; - } - - TmfTimeRange window = new TmfTimeRange(fCheckPoints.get(nextPage).getStartTime(), fCheckPoints.get(fCheckPoints.size()-1).getEndTime()); - fFindJob = new SearchJob(findCriteria, window); - fFindJob.schedule(); - fView.toggleWaitCursorAsync(true); - } finally { - fLock.unlock(); - } - return true; - } - - /** - * Gets time range for time range signal. - * - * @param startTime The start time of time range. - * @return the time range - * @since 2.0 - */ - protected TmfTimeRange getSignalTimeRange(ITmfTimestamp startTime) { - fLock.lock(); - try { - TmfTimeRange currentRange = TmfTraceManager.getInstance().getCurrentRange(); - long offset = fTrace == null ? 0 : currentRange.getEndTime().getDelta(currentRange.getStartTime()).normalize(0, startTime.getScale()).getValue(); - TmfTimestamp initialEndOfWindow = new TmfTimestamp(startTime.getValue() + offset, startTime.getScale(), startTime.getPrecision()); - return new TmfTimeRange(startTime, initialEndOfWindow); - } - finally { - fLock.unlock(); - } - } - - /** - * Checks if filter criteria matches the message name in given SD event. - * - * @param sdEvent The SD event to check - * @return true if match else false. - */ - protected boolean filterMessage(ITmfSyncSequenceDiagramEvent sdEvent) { - fLock.lock(); - try { - if (fFilterCriteria != null) { - for(FilterCriteria criteria : fFilterCriteria) { - if (criteria.isActive() && criteria.getCriteria().isSyncMessageSelected() && criteria.getCriteria().matches(sdEvent.getName())) { - return true; - } - } - } - } finally { - fLock.unlock(); - } - return false; - } - - /** - * Checks if filter criteria matches a lifeline name (sender or receiver) in given SD event. - * - * @param lifeline the message receiver - * @return true if match else false. - */ - protected boolean filterLifeLine(String lifeline) { - fLock.lock(); - try { - if (fFilterCriteria != null) { - for(FilterCriteria criteria : fFilterCriteria) { - if (criteria.isActive() && criteria.getCriteria().isLifeLineSelected() && criteria.getCriteria().matches(lifeline)) { - return true; - } - } - } - } finally { - fLock.unlock(); - } - return false; - } - - /** - * Job to search in trace for given time range. - */ - protected class SearchJob extends Job { - - /** - * The search event request. - */ - protected final SearchEventRequest fSearchRequest; - - /** - * Constructor - * - * @param findCriteria The search criteria - * @param window Time range to search in - * @since 2.0 - */ - public SearchJob(Criteria findCriteria, TmfTimeRange window) { - super(Messages.TmfUml2SDSyncLoader_SearchJobDescrition); - fSearchRequest = new SearchEventRequest(window, ITmfEventRequest.ALL_DATA, - ITmfEventRequest.ExecutionType.FOREGROUND, findCriteria); - } - - @Override - protected IStatus run(IProgressMonitor monitor) { - fSearchRequest.setMonitor(monitor); - - fTrace.sendRequest(fSearchRequest); - - try { - fSearchRequest.waitForCompletion(); - } catch (InterruptedException e) { - Activator.getDefault().logError("Search request interrupted!", e); //$NON-NLS-1$ - } - - IStatus status = Status.OK_STATUS; - if (fSearchRequest.isFound() && (fSearchRequest.getFoundTime() != null)) { - fCurrentTime = fSearchRequest.getFoundTime(); - - // Avoid double-selection. Selection will be done when calling find(criteria) - // after moving to relevant page - fIsSelect = false; - if (!fView.getSDWidget().isDisposed()) { - fView.getSDWidget().getDisplay().asyncExec(new Runnable() { - - @Override - public void run() { - moveToMessage(); - } - }); - } - } - else { - if (monitor.isCanceled()) { - status = Status.CANCEL_STATUS; - } - else { - // String was not found - status = new Status(IStatus.WARNING, Activator.PLUGIN_ID, Messages.TmfUml2SDSyncLoader_SearchNotFound); - } - setProperty(IProgressConstants.KEEP_PROPERTY, Boolean.TRUE); - } - monitor.done(); - - fLock.lock(); - try { - fView.toggleWaitCursorAsync(false); - fFindJob = null; - } finally { - fLock.unlock(); - } - - return status; - } - - @Override - protected void canceling() { - fSearchRequest.cancel(); - fLock.lock(); - try { - fFindJob = null; - } finally { - fLock.unlock(); - } - } - } - - /** - * TMF event request for searching within trace. - */ - protected class SearchEventRequest extends TmfEventRequest { - - /** - * The find criteria. - */ - private final Criteria fCriteria; - /** - * A progress monitor - */ - private IProgressMonitor fMonitor; - /** - * Flag to indicate that node was found according the criteria . - */ - private boolean fIsFound = false; - /** - * Time stamp of found item. - */ - private ITmfTimestamp fFoundTime = null; - - /** - * Constructor - * @param range @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...) - * @param nbRequested @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#handleData(...) - * @param execType @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#handleData(...) - * @param criteria The search criteria - */ - public SearchEventRequest(TmfTimeRange range, int nbRequested, ExecutionType execType, Criteria criteria) { - this(range, nbRequested, execType, criteria, null); - } - - /** - * Constructor - * @param range @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...) - * @param nbRequested @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...) - * @param execType @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...) - * @param criteria The search criteria - * @param monitor progress monitor - */ - public SearchEventRequest(TmfTimeRange range, int nbRequested, ExecutionType execType, Criteria criteria, IProgressMonitor monitor) { - super(ITmfEvent.class, range, 0, nbRequested, execType); - fCriteria = new Criteria(criteria); - fMonitor = monitor; - } - - @Override - public void handleData(ITmfEvent event) { - super.handleData(event); - - if ((fMonitor!= null) && fMonitor.isCanceled()) { - super.cancel(); - return; - } - - ITmfSyncSequenceDiagramEvent sdEvent = getSequenceDiagramEvent(event); - - if (sdEvent != null) { - - if (fCriteria.isLifeLineSelected()) { - if (fCriteria.matches(sdEvent.getSender())) { - fFoundTime = event.getTimestamp(); - fIsFound = true; - super.cancel(); - } - - if (fCriteria.matches(sdEvent.getReceiver())) { - fFoundTime = event.getTimestamp(); - fIsFound = true; - super.cancel(); - } - } - - if (fCriteria.isSyncMessageSelected() && fCriteria.matches(sdEvent.getName())) { - fFoundTime = event.getTimestamp(); - fIsFound = true; - super.cancel(); - } - } - } - - /** - * Set progress monitor. - * - * @param monitor The monitor to assign - */ - public void setMonitor(IProgressMonitor monitor) { - fMonitor = monitor; - } - - /** - * Check if find criteria was met. - * - * @return true if find criteria was met. - */ - public boolean isFound() { - return fIsFound; - } - - /** - * Returns timestamp of found time. - * - * @return timestamp of found time. - * @since 2.0 - */ - public ITmfTimestamp getFoundTime() { - return fFoundTime; - } - } - - /** - * Job class to provide progress monitor feedback. - * - * @version 1.0 - * @author Bernd Hufmann - * - */ - protected static class IndexingJob extends Job { - - /** - * @param name The job name - */ - public IndexingJob(String name) { - super(name); - } - - @Override - protected IStatus run(IProgressMonitor monitor) { - while (!monitor.isCanceled()) { - try { - Thread.sleep(INDEXING_THREAD_SLEEP_VALUE); - } catch (InterruptedException e) { - return Status.OK_STATUS; - } - } - monitor.done(); - return Status.OK_STATUS; - } - } - - - /** - * Returns sequence diagram event if details in given event are available else null. - * - * @param tmfEvent Event to parse for sequence diagram event details - * @return sequence diagram event if details are available else null - * @since 2.0 - */ - protected ITmfSyncSequenceDiagramEvent getSequenceDiagramEvent(ITmfEvent tmfEvent){ - //type = .*RECEIVE.* or .*SEND.* - //content = sender::receiver:,signal: - String eventType = tmfEvent.getType().toString(); - if (eventType.contains(Messages.TmfUml2SDSyncLoader_EventTypeSend) || eventType.contains(Messages.TmfUml2SDSyncLoader_EventTypeReceive)) { - Object sender = tmfEvent.getContent().getField(Messages.TmfUml2SDSyncLoader_FieldSender); - Object receiver = tmfEvent.getContent().getField(Messages.TmfUml2SDSyncLoader_FieldReceiver); - Object name = tmfEvent.getContent().getField(Messages.TmfUml2SDSyncLoader_FieldSignal); - if ((sender instanceof ITmfEventField) && (receiver instanceof ITmfEventField) && (name instanceof ITmfEventField)) { - ITmfSyncSequenceDiagramEvent sdEvent = new TmfSyncSequenceDiagramEvent(tmfEvent, - ((ITmfEventField) sender).getValue().toString(), - ((ITmfEventField) receiver).getValue().toString(), - ((ITmfEventField) name).getValue().toString()); - - return sdEvent; - } - } - return null; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/messages.properties deleted file mode 100644 index 359c257e24..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/loader/messages.properties +++ /dev/null @@ -1,22 +0,0 @@ -############################################################################### -# Copyright (c) 2011, 2013 Ericsson -# -# All rights reserved. This program and the accompanying materials are -# made available under the terms of the Eclipse Public License v1.0 which -# accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Bernd Hufmann - Initial API and implementation -############################################################################### -TmfUml2SDSyncLoader_ViewName=Component Interactions -TmfUml2SDSyncLoader_CategoryLifeline=Lifeline -TmfUml2SDSyncLoader_CategoryMessage=Interaction -TmfUml2SDSyncLoader_FrameName=Sequence Diagram -TmfUml2SDSyncLoader_SearchJobDescrition=Searching in sequence diagram ... -TmfUml2SDSyncLoader_EventTypeSend=SEND -TmfUml2SDSyncLoader_EventTypeReceive=RECEIVE -TmfUml2SDSyncLoader_FieldSender=sender -TmfUml2SDSyncLoader_FieldReceiver=receiver -TmfUml2SDSyncLoader_FieldSignal=signal -TmfUml2SDSyncLoader_SearchNotFound=String not found! diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/preferences/ISDPreferences.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/preferences/ISDPreferences.java deleted file mode 100755 index 0b184d59be..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/preferences/ISDPreferences.java +++ /dev/null @@ -1,147 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IFont; - -/** - * Interface for accessing sequence diagram preferences. - * - * @version 1.0 - * @author sveyrier - */ -public interface ISDPreferences { - - /** - * The link font with zoom preference name - */ - static final String PREF_LINK_FONT = "PREF_LINK_FONT"; //$NON-NLS-1$ - /** - * The exclude preference time preference name - */ - static final String PREF_EXCLUDE_EXTERNAL_TIME = "PREF_EXCLUDE_EXTERNAL_TIME"; //$NON-NLS-1$ - /** - * The use gradient color preferences name - */ - static final String PREF_USE_GRADIENT = "PREF_USE_GRADIENT"; //$NON-NLS-1$ - /** - * The lifeline spacing width preference name - */ - static final String PREF_LIFELINE_WIDTH = "PREF_LIFELINE_WIDTH"; //$NON-NLS-1$ - /** - * The time compression bar font preference name - */ - static final String PREF_TIME_COMP = "PREF_TIME_COMP"; //$NON-NLS-1$ - /** - * The lifeline font preference name - */ - static final String PREF_LIFELINE = "PREF_LIFELINE"; //$NON-NLS-1$ - /** - * The frame font preference name - */ - static final String PREF_FRAME = "PREF_FRAME"; //$NON-NLS-1$ - /** - * The frame name font preference name - */ - static final String PREF_FRAME_NAME = "PREF_FRAME_NAME"; //$NON-NLS-1$ - /** - * The execution occurrence font preference name - */ - static final String PREF_EXEC = "PREF_EXEC"; //$NON-NLS-1$ - /** - * The synchronous message font preference name - */ - static final String PREF_SYNC_MESS = "PREF_SYNC_MESS"; //$NON-NLS-1$ - /** - * The synchronous message return font preference name - */ - static final String PREF_SYNC_MESS_RET = "PREF_SYNC_MESS_RET"; //$NON-NLS-1$ - /** - * The asynchronous message font preference name - */ - static final String PREF_ASYNC_MESS = "PREF_ASYNC_MESS"; //$NON-NLS-1$ - /** - * The asynchronous message return font preference name - */ - static final String PREF_ASYNC_MESS_RET = "PREF_ASYNC_MESS_RET"; //$NON-NLS-1$ - /** - * The lifeline header font (header = the always visible part of a lifeline) - */ - static final String PREF_LIFELINE_HEADER = "PREF_LIFELINE_HEADER"; //$NON-NLS-1$ - /** - * The enable tooltip preference name - */ - static final String PREF_TOOLTIP = "PREF_TOOLTIP"; //$NON-NLS-1$ - - /** - * Returns the background color for the given preference name (font preference name) - * - * @param prefId The preference name - * @return the color - */ - IColor getBackGroundColor(String prefId); - - /** - * Returns the foreground color for the given preference name (font preference name) - * - * @param prefId A preference name - * @return the color - */ - IColor getForeGroundColor(String prefId); - - /** - * Returns the font color for the given preference name (font preference name) - * - * @param prefId A preference name - * @return the color - */ - IColor getFontColor(String prefId); - - /** - * Returns the font for the given preference name - * - * @param prefId the preference name - * @return the font - */ - IFont getFont(String prefId); - - /** - * Returns the time compression bar selection color - * - * @return the time compression bar selection color - */ - IColor getTimeCompressionSelectionColor(); - - /** - * Returns the background color used to draw selection - * - * @return the background color - */ - IColor getBackGroundColorSelection(); - - /** - * Returns the foreground color used to draw selection - * - * @return the foreground color - */ - IColor getForeGroundColorSelection(); - - /** - * Returns whether to use gradient color or not - * - * @return whether to use gradient color or not - */ - boolean useGradienColor(); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/preferences/SDViewPref.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/preferences/SDViewPref.java deleted file mode 100755 index bc720fba29..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/preferences/SDViewPref.java +++ /dev/null @@ -1,527 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Hashtable; -import java.util.Map; - -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.preference.PreferenceConverter; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IFont; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.impl.ColorImpl; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.impl.FontImpl; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.widgets.Display; - -/** - * This is the Sequence Diagram preference handler. This class is responsible for accessing the current user preferences - * selection This class also provider getters for each modifiable preferences. - * - * @version 1.0 - * @author sveyrier - */ -public class SDViewPref implements ISDPreferences, IPropertyChangeListener { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * Postfix string for background color property - */ - public static final String BACK_COLOR_POSTFIX = "_BACK_COLOR";//$NON-NLS-1$ - /** - * Postfix string for foreground color property - */ - public static final String FORE_COLOR_POSTFIX = "_FORE_COLOR";//$NON-NLS-1$ - /** - * Postfix string for text color property - */ - public static final String TEXT_COLOR_POSTFIX = "_TEXT_COLOR";//$NON-NLS-1$ - /** - * Array of preference names - */ - private static final String[] FONT_LIST = { PREF_LIFELINE, PREF_EXEC, PREF_SYNC_MESS, PREF_SYNC_MESS_RET, PREF_ASYNC_MESS, PREF_ASYNC_MESS_RET, PREF_FRAME, PREF_LIFELINE_HEADER, PREF_FRAME_NAME }; - /** - * A 2nd array of preference names - */ - private static final String[] FONT_LIST2 = { Messages.SequenceDiagram_Lifeline, Messages.SequenceDiagram_ExecutionOccurrence, Messages.SequenceDiagram_SyncMessage, Messages.SequenceDiagram_SyncMessageReturn, Messages.SequenceDiagram_AsyncMessage, Messages.SequenceDiagram_AsyncMessageReturn, Messages.SequenceDiagram_Frame, Messages.SequenceDiagram_LifelineHeader, Messages.SequenceDiagram_FrameTitle }; - /** - * Array of background color preference names - */ - private static final String[] PREF_BACK_COLOR_LIST = { PREF_LIFELINE, PREF_EXEC, PREF_FRAME, PREF_LIFELINE_HEADER, PREF_FRAME_NAME }; - /** - * Array of foreground color preference names - */ - private static final String[] PREF_FORE_COLOR_LIST = { PREF_LIFELINE, PREF_EXEC, PREF_SYNC_MESS, PREF_SYNC_MESS_RET, PREF_ASYNC_MESS, PREF_ASYNC_MESS_RET, PREF_FRAME, PREF_LIFELINE_HEADER, PREF_FRAME_NAME }; - /** - * Array of text color preference names - */ - private static final String[] PREF_TEXT_COLOR_LIST = { PREF_LIFELINE, PREF_SYNC_MESS, PREF_SYNC_MESS_RET, PREF_ASYNC_MESS, PREF_ASYNC_MESS_RET, PREF_LIFELINE_HEADER, PREF_FRAME_NAME }; - /** - * Temporary tag - * @since 2.0 - */ - public static final String TEMP_TAG = "_TEMP";//$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - /** - * The sequence diagram preferences singleton instance - */ - private static SDViewPref fHandle = null; - /** - * Hashtable for font preferences - */ - private Map fFontPref; - - /** - * Hashtable for foreground color preferences - */ - private Map fForeColorPref; - /** - * Hashtable for background color preferences - */ - private Map fBackColorPref; - /** - * Hashtable for text color preferences - */ - private Map fTextColorPref; - /** - * The reference to the preference store. - */ - private IPreferenceStore fPrefStore = null; - /** - * Color for the time compression selection - */ - private IColor fTimeCompressionSelectionColor = null; - /** - * Flag whether no focus selection or not. - */ - private boolean fNoFocusSelection = false; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Builds the Sequence Diagram preference handler: - Define the preference default values. - Load the currently used - * preferences setting - */ - protected SDViewPref() { - fPrefStore = Activator.getDefault().getPreferenceStore(); - - fPrefStore.setDefault(PREF_LINK_FONT, true); - fPrefStore.setDefault(PREF_EXCLUDE_EXTERNAL_TIME, true); - fPrefStore.setDefault(PREF_LIFELINE_WIDTH, 200); - fPrefStore.setDefault(PREF_USE_GRADIENT, true); - fPrefStore.setDefault(PREF_TOOLTIP, true); - - fFontPref = new Hashtable<>(); - fForeColorPref = new Hashtable<>(); - fBackColorPref = new Hashtable<>(); - fTextColorPref = new Hashtable<>(); - - for (int i = 0; i < FONT_LIST.length; i++) { - if (FONT_LIST[i].equals(PREF_FRAME_NAME)) { - FontData[] data = Display.getDefault().getSystemFont().getFontData(); - data[0].setStyle(SWT.BOLD); - PreferenceConverter.setDefault(fPrefStore, FONT_LIST[i], data[0]); - PreferenceConverter.setDefault(fPrefStore, FONT_LIST[i] + TEMP_TAG, data[0]); - } else { - PreferenceConverter.setDefault(fPrefStore, FONT_LIST[i], Display.getDefault().getSystemFont().getFontData()); - PreferenceConverter.setDefault(fPrefStore, FONT_LIST[i] + TEMP_TAG, Display.getDefault().getSystemFont().getFontData()); - } - } - - for (int i = 0; i < PREF_BACK_COLOR_LIST.length; i++) { - IColor color; - if ((PREF_BACK_COLOR_LIST[i].equals(PREF_EXEC)) || PREF_BACK_COLOR_LIST[i].equals(PREF_FRAME_NAME)) { - color = new ColorImpl(Display.getDefault(), 201, 222, 233); - } else if (PREF_BACK_COLOR_LIST[i].equals(PREF_LIFELINE)) { - color = new ColorImpl(Display.getDefault(), 220, 220, 220); - } else if (PREF_BACK_COLOR_LIST[i].equals(PREF_LIFELINE_HEADER)) { - color = new ColorImpl(Display.getDefault(), 245, 244, 244); - } else { - color = new ColorImpl(Display.getDefault(), 255, 255, 255); - } - PreferenceConverter.setDefault(fPrefStore, PREF_BACK_COLOR_LIST[i] + BACK_COLOR_POSTFIX, ((Color) color.getColor()).getRGB()); - PreferenceConverter.setDefault(fPrefStore, PREF_BACK_COLOR_LIST[i] + BACK_COLOR_POSTFIX + TEMP_TAG, ((Color) color.getColor()).getRGB()); - color.dispose(); - } - - for (int i = 0; i < PREF_FORE_COLOR_LIST.length; i++) { - IColor color; - if (PREF_FORE_COLOR_LIST[i].equals(PREF_LIFELINE)) { - color = new ColorImpl(Display.getDefault(), 129, 129, 129); - } else if (PREF_FORE_COLOR_LIST[i].equals(PREF_FRAME_NAME)) { - color = new ColorImpl(Display.getDefault(), 81, 153, 200); - } else if (PREF_FORE_COLOR_LIST[i].equals(PREF_LIFELINE_HEADER)) { - color = new ColorImpl(Display.getDefault(), 129, 127, 137); - } else { - color = new ColorImpl(Display.getDefault(), 134, 176, 212); - } - PreferenceConverter.setDefault(fPrefStore, PREF_FORE_COLOR_LIST[i] + FORE_COLOR_POSTFIX, ((Color) color.getColor()).getRGB()); - PreferenceConverter.setDefault(fPrefStore, PREF_FORE_COLOR_LIST[i] + FORE_COLOR_POSTFIX + TEMP_TAG, ((Color) color.getColor()).getRGB()); - color.dispose(); - } - - for (int i = 0; i < PREF_TEXT_COLOR_LIST.length; i++) { - IColor color; - if (PREF_TEXT_COLOR_LIST[i].equals(PREF_LIFELINE)) { - color = new ColorImpl(Display.getDefault(), 129, 129, 129); - } else if (PREF_TEXT_COLOR_LIST[i].equals(PREF_FRAME_NAME)) { - color = new ColorImpl(Display.getDefault(), 0, 0, 0); - } else if (PREF_TEXT_COLOR_LIST[i].equals(PREF_LIFELINE_HEADER)) { - color = new ColorImpl(Display.getDefault(), 129, 127, 137); - } else { - color = new ColorImpl(Display.getDefault(), 134, 176, 212); - } - PreferenceConverter.setDefault(fPrefStore, PREF_TEXT_COLOR_LIST[i] + TEXT_COLOR_POSTFIX, ((Color) color.getColor()).getRGB()); - PreferenceConverter.setDefault(fPrefStore, PREF_TEXT_COLOR_LIST[i] + TEXT_COLOR_POSTFIX + TEMP_TAG, ((Color) color.getColor()).getRGB()); - color.dispose(); - } - - IColor color = new ColorImpl(Display.getDefault(), 218, 232, 238); - PreferenceConverter.setDefault(fPrefStore, PREF_TIME_COMP, ((Color) color.getColor()).getRGB()); - color.dispose(); - - buildFontsAndColors(); - - fPrefStore.addPropertyChangeListener(this); - } - - /** - * Returns the PreferenceStore - * - * @return the PreferenceStore - */ - public IPreferenceStore getPreferenceStore() { - return fPrefStore; - } - - /** - * Apply the preferences in the preferences handler - */ - public void apply() { - buildFontsAndColors(); - fPrefStore.firePropertyChangeEvent("PREFOK", null, null); //$NON-NLS-1$ - } - - /** - * Returns an unique instance of the Sequence Diagram preference handler - * - * @return the preference handler instance - */ - public static synchronized SDViewPref getInstance() { - if (fHandle == null) { - fHandle = new SDViewPref(); - } - return fHandle; - } - - @Override - public IColor getForeGroundColor(String prefName) { - if ((fForeColorPref.get(prefName + FORE_COLOR_POSTFIX) != null) && (fForeColorPref.get(prefName + FORE_COLOR_POSTFIX) instanceof ColorImpl)) { - return fForeColorPref.get(prefName + FORE_COLOR_POSTFIX); - } - return ColorImpl.getSystemColor(SWT.COLOR_BLACK); - } - - @Override - public IColor getBackGroundColor(String prefName) { - if ((fBackColorPref.get(prefName + BACK_COLOR_POSTFIX) != null) && (fBackColorPref.get(prefName + BACK_COLOR_POSTFIX) instanceof ColorImpl)) { - return fBackColorPref.get(prefName + BACK_COLOR_POSTFIX); - } - return ColorImpl.getSystemColor(SWT.COLOR_WHITE); - } - - @Override - public IColor getFontColor(String prefName) { - if ((fTextColorPref.get(prefName + TEXT_COLOR_POSTFIX) != null) && (fTextColorPref.get(prefName + TEXT_COLOR_POSTFIX) instanceof ColorImpl)) { - return fTextColorPref.get(prefName + TEXT_COLOR_POSTFIX); - } - return ColorImpl.getSystemColor(SWT.COLOR_BLACK); - } - - @Override - public IColor getForeGroundColorSelection() { - if (fNoFocusSelection) { - return ColorImpl.getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND); - } - return ColorImpl.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT); - } - - @Override - public IColor getBackGroundColorSelection() { - if (fNoFocusSelection) { - return ColorImpl.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); - } - return ColorImpl.getSystemColor(SWT.COLOR_LIST_SELECTION); - } - - @Override - public IFont getFont(String prefName) { - if (fFontPref.get(prefName) != null) { - return fFontPref.get(prefName); - } - return FontImpl.getSystemFont(); - } - - /** - * Returns the SwimLane width chosen - * - * @return the SwimLane width - */ - public int getLifelineWidth() { - return fPrefStore.getInt(PREF_LIFELINE_WIDTH); - } - - /** - * Returns if font linkage with zoom has been chosen - * - * @return true if checked false otherwise - */ - public boolean fontLinked() { - return fPrefStore.getBoolean(PREF_LINK_FONT); - } - - /** - * Returns the tooltip enablement - * - * @return true if checked false otherwise - */ - public boolean tooltipEnabled() { - return fPrefStore.getBoolean(PREF_TOOLTIP); - } - - /** - * Return true if the user do not want to take external time (basically found and lost messages with time) into - * account in the min max computation - * - * @return true if checked false otherwise - */ - public boolean excludeExternalTime() { - return fPrefStore.getBoolean(PREF_EXCLUDE_EXTERNAL_TIME); - } - - @Override - public boolean useGradienColor() { - return fPrefStore.getBoolean(PREF_USE_GRADIENT); - } - - @Override - public IColor getTimeCompressionSelectionColor() { - return fTimeCompressionSelectionColor; - } - - /** - * Builds the new colors and fonts according the current user selection when the OK or Apply button is clicked - */ - private void buildFontsAndColors() { - - Display display = Display.getDefault(); - - for (int i = 0; i < FONT_LIST.length; i++) { - FontData fontData = PreferenceConverter.getFontData(fPrefStore, FONT_LIST[i]); - if (fFontPref.get(FONT_LIST[i]) != null) { - fFontPref.get(FONT_LIST[i]).dispose(); - } - fFontPref.put(FONT_LIST[i], new FontImpl(display, fontData)); - } - - for (int i = 0; i < PREF_BACK_COLOR_LIST.length; i++) { - RGB rgb = PreferenceConverter.getColor(fPrefStore, PREF_BACK_COLOR_LIST[i] + BACK_COLOR_POSTFIX); - if (fBackColorPref.get(PREF_BACK_COLOR_LIST[i] + BACK_COLOR_POSTFIX) != null) { - fBackColorPref.get(PREF_BACK_COLOR_LIST[i] + BACK_COLOR_POSTFIX).dispose(); - } - fBackColorPref.put(PREF_BACK_COLOR_LIST[i] + BACK_COLOR_POSTFIX, new ColorImpl(display, rgb.red, rgb.green, rgb.blue)); - } - - for (int i = 0; i < PREF_FORE_COLOR_LIST.length; i++) { - RGB rgb = PreferenceConverter.getColor(fPrefStore, PREF_FORE_COLOR_LIST[i] + FORE_COLOR_POSTFIX); - if (fForeColorPref.get(PREF_FORE_COLOR_LIST[i] + FORE_COLOR_POSTFIX) != null) { - fForeColorPref.get(PREF_FORE_COLOR_LIST[i] + FORE_COLOR_POSTFIX).dispose(); - } - fForeColorPref.put(PREF_FORE_COLOR_LIST[i] + FORE_COLOR_POSTFIX, new ColorImpl(display, rgb.red, rgb.green, rgb.blue)); - } - - for (int i = 0; i < PREF_TEXT_COLOR_LIST.length; i++) { - RGB rgb = PreferenceConverter.getColor(fPrefStore, PREF_TEXT_COLOR_LIST[i] + TEXT_COLOR_POSTFIX); - if (fTextColorPref.get(PREF_TEXT_COLOR_LIST[i] + TEXT_COLOR_POSTFIX) != null) { - fTextColorPref.get(PREF_TEXT_COLOR_LIST[i] + TEXT_COLOR_POSTFIX).dispose(); - } - fTextColorPref.put(PREF_TEXT_COLOR_LIST[i] + TEXT_COLOR_POSTFIX, new ColorImpl(display, rgb.red, rgb.green, rgb.blue)); - } - - RGB rgb = PreferenceConverter.getColor(fPrefStore, PREF_TIME_COMP); - if (fTimeCompressionSelectionColor != null) { - fTimeCompressionSelectionColor.dispose(); - } - fTimeCompressionSelectionColor = new ColorImpl(display, rgb.red, rgb.green, rgb.blue); - } - - /** - * Add a property-change listener - * - * @param listener - * The listener to add - */ - public void addPropertyChangeListener(IPropertyChangeListener listener) { - fPrefStore.addPropertyChangeListener(listener); - } - - /** - * Remove a property-change listener - * - * @param listener - * The listerner to remove - */ - public void removePropertyChangeListener(IPropertyChangeListener listener) { - fPrefStore.removePropertyChangeListener(listener); - } - - @Override - public void propertyChange(PropertyChangeEvent event) { - if (!event.getProperty().equals("PREFOK")) { //$NON-NLS-1$ - buildFontsAndColors(); - fPrefStore.firePropertyChangeEvent("PREFOK", null, null); //$NON-NLS-1$ - } - } - - /** - * Set the "no focus selection" preference - * - * @param v - * New value to use - */ - public void setNoFocusSelection(boolean v) { - fNoFocusSelection = v; - } - - /** - * Returns a unmodifiable map with font preferences. - * - * @return map with font preferences - * @since 2.0 - */ - protected Map getFontPref() { - return Collections.unmodifiableMap(fFontPref); - } - - /** - * Returns a unmodifiable map with foreground color preferences - * - * @return map with foreground color preferences - * @since 2.0 - */ - public Map getForeColorPref() { - return Collections.unmodifiableMap(fForeColorPref); - } - - /** - * Returns a unmodifiable map with background color preferences - * - * @return map with background color preferences - * @since 2.0 - */ - public Map getBackColorPref() { - return Collections.unmodifiableMap(fBackColorPref); - } - - /** - * Returns a unmodifiable map with text color preferences - * - * @return map with text color preferences - * @since 2.0 - */ - public Map getTextColorPref() { - return Collections.unmodifiableMap(fTextColorPref); - } - - /** - * Returns the preference store. - * - * @return the preference store - * @since 2.0 - */ - public IPreferenceStore getPrefStore() { - return fPrefStore; - } - - /** - * Returns flag about focus selection - * - * @return flag about focus selection - * @since 2.0 - */ - public boolean isNoFocusSelection() { - return fNoFocusSelection; - } - - /** - * Returns the static font list. - * - * @return static font list - */ - public static String[] getFontList() { - return Arrays.copyOf(FONT_LIST, FONT_LIST.length); - } - - /** - * Returns the 2nd static font list. - * - * @return 2nd static font list - */ - public static String[] getFontList2() { - return Arrays.copyOf(FONT_LIST2, FONT_LIST2.length); - } - - /** - * Returns the preference background color list. - * - * @return preference background color list - */ - public static String[] getPrefBackColorList() { - return Arrays.copyOf(PREF_BACK_COLOR_LIST, PREF_BACK_COLOR_LIST.length); - } - - /** - * Returns the preference foreground color list. - * - * @return preference foreground color list - */ - public static String[] getPrefForeColorList() { - return Arrays.copyOf(PREF_FORE_COLOR_LIST, PREF_FORE_COLOR_LIST.length); - } - - /** - * Returns the preference text color list color list. - * - * @return preference text color list color list - */ - public static String[] getPrefTextColorList() { - return Arrays.copyOf(PREF_TEXT_COLOR_LIST, PREF_TEXT_COLOR_LIST.length); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/preferences/SDViewerPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/preferences/SDViewerPage.java deleted file mode 100755 index 43d922daf8..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/preferences/SDViewerPage.java +++ /dev/null @@ -1,431 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2014 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences; - -import java.util.Iterator; -import java.util.Set; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.preference.BooleanFieldEditor; -import org.eclipse.jface.preference.ColorFieldEditor; -import org.eclipse.jface.preference.FontFieldEditor; -import org.eclipse.jface.preference.IntegerFieldEditor; -import org.eclipse.jface.preference.PreferencePage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.List; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPreferencePage; - -/** - * The Sequence Diagram preferences page implementation. - * - * @version 1.0 - * @author sveyrier - */ -public class SDViewerPage extends PreferencePage implements IWorkbenchPreferencePage, SelectionListener { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * Temporary preferences tag - */ - private static final String TEMP_TAG = SDViewPref.TEMP_TAG; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The preference handler used to access the PreferenceStore - */ - private SDViewPref fPreferences = null; - /** - * BackGround color selector - */ - private ColorFieldEditor fLineColor = null; - /** - * Foreground color selector - */ - private ColorFieldEditor fBackGroundColor = null; - /** - * Font color selector - */ - private ColorFieldEditor fTextColor = null; - /** - * List which display all modifiable sequence Diagram font - */ - private List fClassItemList = null; - /** - * Font selector (The same is used for each modifiable font) - */ - private FontFieldEditor fFont = null; - /** - * Link font when zooming selector - */ - private BooleanFieldEditor fLink = null; - /** - * Enable tooltip selector - */ - private BooleanFieldEditor fTooltip = null; - /** - * Do not take external time into account in the min max computation - */ - private BooleanFieldEditor fNoExternalTime = null; - /** - * Use gradient color selector - */ - private BooleanFieldEditor fUseGrad = null; - /** - * A button area. - */ - private Composite fButtonArea; - /** - * SwimLane width selector - */ - private IntegerFieldEditor fLifelineWidth = null; - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - protected Control createContents(Composite parent) { - GridLayout gl = new GridLayout(); - gl.marginHeight = 0; - gl.marginWidth = 0; - parent.setLayout(gl); - Composite page = new Composite(parent, SWT.NONE); - GridLayout pageLayout = new GridLayout(); - pageLayout.numColumns = 2; - GridData pageLayoutdata = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL); - page.setLayoutData(pageLayoutdata); - page.setLayout(pageLayout); - - fTooltip = new BooleanFieldEditor(ISDPreferences.PREF_TOOLTIP, Messages.SequenceDiagram_ShowTooltips, page); - fTooltip.setPreferenceStore(fPreferences.getPreferenceStore()); - fTooltip.load(); - - // link font with zoom pref - fLink = new BooleanFieldEditor(ISDPreferences.PREF_LINK_FONT, Messages.SequenceDiagram_IncreaseFontSizeWhenZooming, page); - fLink.setPreferenceStore(fPreferences.getPreferenceStore()); - fLink.load(); - - fNoExternalTime = new BooleanFieldEditor(ISDPreferences.PREF_EXCLUDE_EXTERNAL_TIME, Messages.SequenceDiagram_ExcludeExternalTime, page); - fNoExternalTime.setPreferenceStore(fPreferences.getPreferenceStore()); - fNoExternalTime.load(); - - // use gradient color pref - fUseGrad = new BooleanFieldEditor(ISDPreferences.PREF_USE_GRADIENT, Messages.SequenceDiagram_UseGradientColor, page); - fUseGrad.setPreferenceStore(fPreferences.getPreferenceStore()); - fUseGrad.load(); - - Label separator = new Label(page, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.SHADOW_NONE); - GridData sepData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL); - separator.setLayoutData(sepData); - - Composite prefPage = new Composite(page, SWT.NONE); - GridLayout prefPageLayout = new GridLayout(); - prefPage.setLayoutData(pageLayoutdata); - prefPageLayout.numColumns = 1; - prefPage.setLayout(prefPageLayout); - - // swimLane width pref - fLifelineWidth = new IntegerFieldEditor(ISDPreferences.PREF_LIFELINE_WIDTH, Messages.SequenceDiagram_LifelineWidth, prefPage); - fLifelineWidth.setPreferenceStore(fPreferences.getPreferenceStore()); - fLifelineWidth.setValidRange(119, 500); - fLifelineWidth.load(); - - // not very nice - new Label(prefPage, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.SHADOW_NONE); - new Label(prefPage, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.SHADOW_NONE); - - // Font list pref - fClassItemList = new List(prefPage, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); - GridData tabItemLayoutdata = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL); - fClassItemList.setLayoutData(tabItemLayoutdata); - - String[] fontList2 = SDViewPref.getFontList2(); - for (int i = 0; i < fontList2.length; i++) { - fClassItemList.add(fontList2[i]); - } - fClassItemList.setSelection(0); - fClassItemList.addSelectionListener(this); - fButtonArea = new Composite(prefPage, SWT.NONE); - GridData tabItemLayoutdata2 = new GridData(GridData.HORIZONTAL_ALIGN_FILL/* |GridData.GRAB_HORIZONTAL */| GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL); - fButtonArea.setLayoutData(tabItemLayoutdata2); - GridLayout buttonAreaLayout = new GridLayout(); - buttonAreaLayout.numColumns = 1; - fButtonArea.setLayout(buttonAreaLayout); - - // font selector initialise for the lifeline font pref - String[] fontList = SDViewPref.getFontList(); - fFont = new FontFieldEditor(fontList[0], "",//$NON-NLS-1$ - Messages.SequenceDiagram_AaBbYyZz, fButtonArea); - fFont.getPreviewControl().setSize(500, 500); - fFont.setPreferenceStore(fPreferences.getPreferenceStore()); - fFont.load(); - - fBackGroundColor = new ColorFieldEditor(fontList[0] + SDViewPref.BACK_COLOR_POSTFIX, Messages.SequenceDiagram_Background, fButtonArea); - fBackGroundColor.setPreferenceStore(fPreferences.getPreferenceStore()); - fBackGroundColor.load(); - - fLineColor = new ColorFieldEditor(fontList[0] + SDViewPref.FORE_COLOR_POSTFIX, Messages.SequenceDiagram_Lines, fButtonArea); - fLineColor.setPreferenceStore(fPreferences.getPreferenceStore()); - fLineColor.load(); - - fTextColor = new ColorFieldEditor(fontList[0] + SDViewPref.TEXT_COLOR_POSTFIX, Messages.SequenceDiagram_Text, fButtonArea); - fTextColor.setPreferenceStore(fPreferences.getPreferenceStore()); - fTextColor.load(); - swapPref(true); - Dialog.applyDialogFont(page); - - return page; - } - - @Override - public void init(IWorkbench workbench) { - fPreferences = SDViewPref.getInstance(); - } - - @Override - protected void performApply() { - // Store the prefrences in the PreferenceStore - if (!fLifelineWidth.isValid()) { - fLifelineWidth.showErrorMessage(); - return; - } - fFont.store(); - fBackGroundColor.store(); - fLineColor.store(); - fLink.store(); - fTooltip.store(); - fNoExternalTime.store(); - fTextColor.store(); - fUseGrad.store(); - fLifelineWidth.store(); - swapPref(false); - // then save them in the preference file - fPreferences.apply(); - swapPref(true); - } - - @Override - public boolean performOk() { - performApply(); - return true; - } - - @Override - protected void performDefaults() { - fLink.loadDefault(); - fTooltip.loadDefault(); - fNoExternalTime.loadDefault(); - fUseGrad.loadDefault(); - fLifelineWidth.loadDefault(); - - // and all the fonts and colors - // fonts and colors are stored for each time because - // we are using only one FontFieldEditor - Set keySet = SDViewPref.getInstance().getFontPref().keySet(); - Iterator it = keySet.iterator(); - while (it.hasNext()) { - Object prefName = it.next(); - if (prefName instanceof String) { - fFont.setPreferenceName((String) prefName); - fFont.loadDefault(); - fFont.setPreferenceName((String) prefName + TEMP_TAG); - fFont.store(); - } - } - - keySet = SDViewPref.getInstance().getBackColorPref().keySet(); - it = keySet.iterator(); - while (it.hasNext()) { - Object prefName = it.next(); - if (prefName instanceof String) { - fBackGroundColor.setPreferenceName((String) prefName); - fBackGroundColor.loadDefault(); - fBackGroundColor.setPreferenceName((String) prefName + TEMP_TAG); - fBackGroundColor.store(); - } - - } - - String[] fontList = SDViewPref.getFontList(); - fBackGroundColor.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + SDViewPref.BACK_COLOR_POSTFIX + TEMP_TAG); - fBackGroundColor.load(); - - keySet = SDViewPref.getInstance().getForeColorPref().keySet(); - it = keySet.iterator(); - while (it.hasNext()) { - Object prefName = it.next(); - if (prefName instanceof String) { - fLineColor.setPreferenceName((String) prefName); - fLineColor.loadDefault(); - fLineColor.setPreferenceName((String) prefName + TEMP_TAG); - fLineColor.store(); - } - } - - fLineColor.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + SDViewPref.FORE_COLOR_POSTFIX + TEMP_TAG); - fLineColor.load(); - - keySet = SDViewPref.getInstance().getTextColorPref().keySet(); - it = keySet.iterator(); - while (it.hasNext()) { - Object prefName = it.next(); - if (prefName instanceof String) { - fTextColor.setPreferenceName((String) prefName); - fTextColor.loadDefault(); - fTextColor.setPreferenceName((String) prefName + TEMP_TAG); - fTextColor.store(); - } - } - fTextColor.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + SDViewPref.TEXT_COLOR_POSTFIX + TEMP_TAG); - fTextColor.load(); - } - - @Override - public void widgetSelected(SelectionEvent e) { - // Store the past set font preference or else the - // FontFieldEditor reassignment will make us loose the current modification - fFont.store(); - fLineColor.store(); - fBackGroundColor.store(); - fTextColor.store(); - - String[] fontList = SDViewPref.getFontList(); - - // set the FontFieldEditor for the new selected graphNode font - fFont.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + TEMP_TAG); - fFont.load(); - - fBackGroundColor.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + SDViewPref.BACK_COLOR_POSTFIX + TEMP_TAG); - fBackGroundColor.load(); - - fLineColor.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + SDViewPref.FORE_COLOR_POSTFIX + TEMP_TAG); - fLineColor.load(); - - fTextColor.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + SDViewPref.TEXT_COLOR_POSTFIX + TEMP_TAG); - fTextColor.load(); - - // No Background for message graphNodes - if ((fontList[fClassItemList.getSelectionIndex()].equals(ISDPreferences.PREF_SYNC_MESS)) || (fontList[fClassItemList.getSelectionIndex()].equals(ISDPreferences.PREF_SYNC_MESS_RET)) - || (fontList[fClassItemList.getSelectionIndex()].equals(ISDPreferences.PREF_ASYNC_MESS)) || (fontList[fClassItemList.getSelectionIndex()].equals(ISDPreferences.PREF_ASYNC_MESS_RET))) { - fBackGroundColor.setEnabled(false, fButtonArea); - } else { - fBackGroundColor.setEnabled(true, fButtonArea); - } - - // No font used for execution occurrence and global frame - if ((fontList[fClassItemList.getSelectionIndex()].equals(ISDPreferences.PREF_EXEC)) || (fontList[fClassItemList.getSelectionIndex()].equals(ISDPreferences.PREF_FRAME))) { - fTextColor.setEnabled(false, fButtonArea); - } else { - fTextColor.setEnabled(true, fButtonArea); - } - - if (fontList[fClassItemList.getSelectionIndex()].equals(ISDPreferences.PREF_FRAME)) { - fFont.setEnabled(false, fButtonArea); - } else { - fFont.setEnabled(true, fButtonArea); - } - } - - /** - * Swap viewer preferences. - * - * @param toTemp Switch to the temporary preferences - */ - protected void swapPref(boolean toTemp) { - String tag1 = "";//$NON-NLS-1$ - String tag2 = TEMP_TAG; - if (!toTemp) { - tag1 = TEMP_TAG; - tag2 = "";//$NON-NLS-1$ - } - Set keySet = SDViewPref.getInstance().getFontPref().keySet(); - Iterator it = keySet.iterator(); - while (it.hasNext()) { - Object prefName = it.next(); - if (prefName instanceof String) { - fFont.setPreferenceName((String) prefName + tag1); - fFont.load(); - fFont.setPreferenceName((String) prefName + tag2); - fFont.store(); - } - } - - keySet = SDViewPref.getInstance().getBackColorPref().keySet(); - it = keySet.iterator(); - while (it.hasNext()) { - Object prefName = it.next(); - if (prefName instanceof String) { - fBackGroundColor.setPreferenceName((String) prefName + tag1); - fBackGroundColor.load(); - fBackGroundColor.setPreferenceName((String) prefName + tag2); - fBackGroundColor.store(); - } - } - - keySet = SDViewPref.getInstance().getForeColorPref().keySet(); - it = keySet.iterator(); - while (it.hasNext()) { - Object prefName = it.next(); - if (prefName instanceof String) { - fLineColor.setPreferenceName((String) prefName + tag1); - fLineColor.load(); - fLineColor.setPreferenceName((String) prefName + tag2); - fLineColor.store(); - } - } - - keySet = SDViewPref.getInstance().getTextColorPref().keySet(); - it = keySet.iterator(); - while (it.hasNext()) { - Object prefName = it.next(); - if (prefName instanceof String) { - fTextColor.setPreferenceName((String) prefName + tag1); - fTextColor.load(); - fTextColor.setPreferenceName((String) prefName + tag2); - fTextColor.store(); - } - } - String[] fontList = SDViewPref.getFontList(); - if (toTemp) { - // set the FontFieldEditor for the new selected graphNode font - fFont.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + TEMP_TAG); - fFont.load(); - - fBackGroundColor.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + SDViewPref.BACK_COLOR_POSTFIX + TEMP_TAG); - fBackGroundColor.load(); - - fLineColor.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + SDViewPref.FORE_COLOR_POSTFIX + TEMP_TAG); - fLineColor.load(); - - fTextColor.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + SDViewPref.TEXT_COLOR_POSTFIX + TEMP_TAG); - fTextColor.load(); - } - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/Messages.java deleted file mode 100755 index 9a57092897..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/Messages.java +++ /dev/null @@ -1,157 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - * Bernd Hufmann - Updated for TMF - * Alexandre Montplaisir - Renamed variables - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.util; - -import org.eclipse.osgi.util.NLS; - -/** - * Messages related to the sequence diagram - * - * @version 1.0 - * @author Bernd Hufmann - * @since 2.0 - */ -@SuppressWarnings("javadoc") -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.messages"; //$NON-NLS-1$ - - private Messages() { - // Do not instantiate - } - - public static String SequenceDiagram_LifelineNode; - public static String SequenceDiagram_MessageNode; - public static String SequenceDiagram_LostMessageNode; - public static String SequenceDiagram_FoundMessageNode; - public static String SequenceDiagram_ExecutionOccurrenceWithParams; - - public static String SequenceDiagram_Find; - public static String SequenceDiagram_Close; - public static String SequenceDiagram_StringNotFound; - public static String SequenceDiagram_SequenceDiagramFind; - public static String SequenceDiagram_SearchFor; - public static String SequenceDiagram_MatchingString; - public static String SequenceDiagram_CaseSensitive; - public static String SequenceDiagram_Lifeline; - public static String SequenceDiagram_Stop; - public static String SequenceDiagram_SynchronousMessage; - public static String SequenceDiagram_SynchronousMessageReturn; - public static String SequenceDiagram_AsynchronousMessage; - public static String SequenceDiagram_AsynchronousMessageReturn; - public static String SequenceDiagram_or; - public static String SequenceDiagram_PreviousPage; - public static String SequenceDiagram_NextPage; - public static String SequenceDiagram_GoToPreviousPage; - public static String SequenceDiagram_GoToNextPage; - public static String SequenceDiagram_GoToMessage; - public static String SequenceDiagram_GoToMessageReturn; - public static String SequenceDiagram_EditFilters; - public static String SequenceDiagram_HidePatterns; - public static String SequenceDiagram_Pages; - - public static String SequenceDiagram_ZoomIn; - public static String SequenceDiagram_ZoomInTheDiagram; - public static String SequenceDiagram_ResetZoomFactor; - public static String SequenceDiagram_ZoomOut; - public static String SequenceDiagram_ZoomOutTheDiagram; - public static String SequenceDiagram_Select; - public static String SequenceDiagram_Max; - public static String SequenceDiagram_Min; - public static String SequenceDiagram_ListOfHideDisplayPatterns; - public static String SequenceDiagram_hide; - public static String SequenceDiagram_display; - public static String SequenceDiagram_EditIt; - public static String SequenceDiagram_Add; - public static String SequenceDiagram_Create; - public static String SequenceDiagram_Update; - public static String SequenceDiagram_Remove; - public static String SequenceDiagram_SequenceDiagramHidePatterns; - public static String SequenceDiagram_DefinitionOfHidePattern; - public static String SequenceDiagram_PageNavigation; - public static String SequenceDiagram_SequenceDiagramPages; - public static String SequenceDiagram_IsInBetween; - public static String SequenceDiagram_Total; - public static String SequenceDiagram_pages; - public static String SequenceDiagram_page; - - public static String SequenceDiagram_CurrentPage; - - public static String SequenceDiagram_Navigation; - public static String SequenceDiagram_OpenOverviewTooltip; - - public static String SequenceDiagram_LifelineWidth; - public static String SequenceDiagram_AaBbYyZz; - public static String SequenceDiagram_IncreaseFontSizeWhenZooming; - public static String SequenceDiagram_ExcludeExternalTime; - public static String SequenceDiagram_UseGradientColor; - public static String SequenceDiagram_Background; - public static String SequenceDiagram_Lines; - public static String SequenceDiagram_Text; - - public static String SequenceDiagram_ExecutionOccurrence; - public static String SequenceDiagram_SyncMessage; - public static String SequenceDiagram_SyncMessageReturn; - public static String SequenceDiagram_AsyncMessage; - public static String SequenceDiagram_AsyncMessageReturn; - public static String SequenceDiagram_Frame; - public static String SequenceDiagram_LifelineHeader; - public static String SequenceDiagram_FrameTitle; - public static String SequenceDiagram_ShowTooltips; - public static String SequenceDiagram_Error; - public static String SequenceDiagram_InvalidRange; - public static String SequenceDiagram_InvalidNbVertical; - public static String SequenceDiagram_InvalidNbHorizontal; - public static String SequenceDiagram_NoPageSelected; - public static String SequenceDiagram_FromPage; - - public static String SequenceDiagram_to; - public static String SequenceDiagram_SelectedPages; - public static String SequenceDiagram_CurrentView; - public static String SequenceDiagram_AllPages; - public static String TotalNumberOfPages; - public static String SequenceDiagram_NumberOfHorizontalPages; - public static String SequenceDiagram_NumberOfVerticalPages; - public static String SequenceDiagram_UseCurrentZoom; - public static String SequenceDiagram_ZoomOption; - public static String SequenceDiagram_Print; - public static String SequenceDiagram_Printer; - public static String SequenceDiagram_plus; - public static String SequenceDiagram_Page; - public static String SequenceDiagram_PrintRange; - public static String SequenceDiagram_Preview; - - public static String SequenceDiagram_TimeCompressionBarConfig; - public static String SequenceDiagram_MinTime; - public static String SequenceDiagram_MaxTime; - public static String SequenceDiagram_Default; - - public static String SequenceDiagram_NoPrinterSelected; - public static String SequenceDiagram_Scale; - public static String SequenceDiagram_Precision; - public static String SequenceDiagram_Delta; - - public static String SequenceDiagram_FirstPage; - public static String SequenceDiagram_GoToFirstPage; - public static String SequenceDiagram_LastPage; - public static String SequenceDiagram_GoToLastPage; - - public static String SequenceDiagram_ShowNodeEnd; - public static String SequenceDiagram_ShowNodeStart; - public static String SequenceDiagram_ConfigureMinMax; - - static { - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/SortAsyncForBackward.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/SortAsyncForBackward.java deleted file mode 100755 index bbbd5df758..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/SortAsyncForBackward.java +++ /dev/null @@ -1,96 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.util; - -import java.io.Serializable; -import java.util.Comparator; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.AsyncMessage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode; - -/** - * Asynchronous message comparator. - * - * Compares two asyncMessages only taking into account the event occurrence when their - * appear.
- * - * Used to order the AsyncMessage list insuring that the previous node has both of his ends smaller than the current node - * - * @version 1.0 - * @author sveyrier - * - */ -public class SortAsyncForBackward implements Comparator, Serializable { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * Serial version UID - */ - private static final long serialVersionUID = 603959931263853359L; - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public int compare(GraphNode arg0, GraphNode arg1) { - if (arg0 instanceof AsyncMessage && arg1 instanceof AsyncMessage) { - AsyncMessage m1 = (AsyncMessage) arg0; - AsyncMessage m2 = (AsyncMessage) arg1; - int m1Max, m2Max; - // AsyncMessage has two ends which may have different event occurrences - // Search for the greater event occurrence for each messages - if (m1.getStartOccurrence() > m1.getEndOccurrence()) { - m1Max = m1.getStartOccurrence(); - } else { - m1Max = m1.getEndOccurrence(); - } - if (m2.getStartOccurrence() > m2.getEndOccurrence()) { - m2Max = m2.getStartOccurrence(); - } else { - m2Max = m2.getEndOccurrence(); - } - - int m1Min, m2Min; - // Search for the smaller event occurrence for each messages - if (m1.getStartOccurrence() > m1.getEndOccurrence()) { - m1Min = m1.getEndOccurrence(); - } else { - m1Min = m1.getStartOccurrence(); - } - if (m2.getStartOccurrence() > m2.getEndOccurrence()) { - m2Min = m2.getEndOccurrence(); - } else { - m2Min = m2.getStartOccurrence(); - } - - if (m1Max > m2Max) { - return 1; - } else if (m1Max == m2Max) { - if (m1Min == m2Min) { - return 0; - } else if (m1Min > m2Min) { - return -1; - } else { - return 1; - } - } else { - return -1; - } - } - return 0; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/SortAsyncMessageComparator.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/SortAsyncMessageComparator.java deleted file mode 100755 index ab04760b69..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/SortAsyncMessageComparator.java +++ /dev/null @@ -1,94 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.util; - -import java.io.Serializable; -import java.util.Comparator; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.AsyncMessage; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode; - -/** - * Asynchronous message comparator Compare two AsyncMessages only taking into account the event occurrence when their - * appear.
- * - * Used to order the AsyncMessage list insuring that next node has one of his ends greater than the current node - * - * @version 1.0 - * @author sveyrier - * - */ -public class SortAsyncMessageComparator implements Comparator, Serializable { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * Serial version UID - */ - private static final long serialVersionUID = 1L; - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public int compare(GraphNode arg0, GraphNode arg1) { - if (arg0 instanceof AsyncMessage && arg1 instanceof AsyncMessage) { - AsyncMessage m1 = (AsyncMessage) arg0; - AsyncMessage m2 = (AsyncMessage) arg1; - int m1Min, m2Min; - // AsyncMessage has two ends which may have different event occurrences - // Search for the smaller event occurrence for each messages - if (m1.getStartOccurrence() > m1.getEndOccurrence()) { - m1Min = m1.getEndOccurrence(); - } else { - m1Min = m1.getStartOccurrence(); - } - if (m2.getStartOccurrence() > m2.getEndOccurrence()) { - m2Min = m2.getEndOccurrence(); - } else { - m2Min = m2.getStartOccurrence(); - } - - int m1Max, m2Max; - // Search for the greater event occurrence for each messages - if (m1.getStartOccurrence() > m1.getEndOccurrence()) { - m1Max = m1.getStartOccurrence(); - } else { - m1Max = m1.getEndOccurrence(); - } - if (m2.getStartOccurrence() > m2.getEndOccurrence()) { - m2Max = m2.getStartOccurrence(); - } else { - m2Max = m2.getEndOccurrence(); - } - - if (m1Min > m2Min) { - return 1; - } else if ((m1Min == m2Min)) { - if (m1Max == m2Max) { - return 0; - } else if (m1Max > m2Max) { - return -1; - } else { - return 1; - } - } else { - return -1; - } - } - return 0; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/SortSyncMessageComparator.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/SortSyncMessageComparator.java deleted file mode 100755 index 24d5106f20..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/SortSyncMessageComparator.java +++ /dev/null @@ -1,61 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.util; - -import java.io.Serializable; -import java.util.Comparator; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode; -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SyncMessage; - -/** - * Synchronous message comparator Compare two syncMessages only taking into account the event occurrence when their - * appear.
- * - * The message with the greater event occurrence is considered to be the greater.
- * - * @version 1.0 - * @author sveyrier - * - */ -public class SortSyncMessageComparator implements Comparator, Serializable { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * Serial version UID - */ - private static final long serialVersionUID = 4781250984753283718L; - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public int compare(GraphNode arg0, GraphNode arg1) { - if (arg0 instanceof SyncMessage && arg1 instanceof SyncMessage) { - SyncMessage m1 = (SyncMessage) arg0; - SyncMessage m2 = (SyncMessage) arg1; - if (m1.getEventOccurrence() > m2.getEventOccurrence()) { - return 1; - } else if (m1.getEventOccurrence() == m2.getEventOccurrence()) { - return 0; - } else { - return -1; - } - } - return 0; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/TimeEventComparator.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/TimeEventComparator.java deleted file mode 100755 index f06aa783bb..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/TimeEventComparator.java +++ /dev/null @@ -1,53 +0,0 @@ -/********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * Bernd Hufmann - Updated for TMF - **********************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.views.uml2sd.util; - -import java.io.Serializable; -import java.util.Comparator; - -import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SDTimeEvent; - -/** - * Time event comparator - * - * @version 1.0 - * @author sveyrier - */ -public class TimeEventComparator implements Comparator, Serializable { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** - * Serial version UID - */ - private static final long serialVersionUID = 5885497718872575669L; - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public int compare(SDTimeEvent arg0, SDTimeEvent arg1) { - SDTimeEvent t1 = arg0; - SDTimeEvent t2 = arg1; - if (t1.getEvent() > t2.getEvent()) { - return 1; - } - else if (t1.getEvent() == t2.getEvent()) { - return 0; - } - return -1; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/messages.properties deleted file mode 100755 index f8ef1c7c63..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/uml2sd/util/messages.properties +++ /dev/null @@ -1,132 +0,0 @@ -############################################################################### -# Copyright (c) 2005, 2013 IBM Corporation, Ericsson -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# IBM Corporation - initial API and implementation -# Bernd Hufmann - Updated for TMF -# Alexandre Montplaisir - Renamed variables -############################################################################### - -# NLS_MESSAGEFORMAT_VAR -# NLS_ENCODING=UTF-8 - -##SD -SequenceDiagram_LifelineNode=Lifeline node {0} -SequenceDiagram_MessageNode=Message node {0} from Lifeline {1} at event occurrence {2} to Lifeline {3} at event occurrence {4} -SequenceDiagram_LostMessageNode=Lost Message node {0} from Lifeline {1} at event occurrence {2} -SequenceDiagram_FoundMessageNode=Found Message node {0} to Lifeline {1} at event occurrence {2} -SequenceDiagram_ExecutionOccurrenceWithParams=Execution occurrence {0} on Lifeline {1} from event occurrence {2} to {3} - -SequenceDiagram_Find=Find -SequenceDiagram_Close=Close -SequenceDiagram_StringNotFound=String not found -SequenceDiagram_SequenceDiagramFind=Sequence Diagram Find -SequenceDiagram_SearchFor=Search for -SequenceDiagram_MatchingString=Matching string (regular expression): -SequenceDiagram_CaseSensitive=Case sensitive -SequenceDiagram_Lifeline=Lifeline -SequenceDiagram_Stop=Stop -SequenceDiagram_SynchronousMessage=Synchronous message -SequenceDiagram_SynchronousMessageReturn=Synchronous message return -SequenceDiagram_AsynchronousMessage=Asynchronous message -SequenceDiagram_AsynchronousMessageReturn=Asynchronous message return -SequenceDiagram_or=or -SequenceDiagram_PreviousPage=Previous page -SequenceDiagram_NextPage=Next page -SequenceDiagram_GoToPreviousPage=Go to previous page -SequenceDiagram_GoToNextPage=Go to next page -SequenceDiagram_GoToMessage=Go to message -SequenceDiagram_GoToMessageReturn=Go to message return -SequenceDiagram_EditFilters=Edit filters... -SequenceDiagram_HidePatterns=Hide Patterns... -SequenceDiagram_Pages=Pages... -SequenceDiagram_ZoomIn=Zoom in -SequenceDiagram_ZoomInTheDiagram=Zoom in the diagram -SequenceDiagram_ResetZoomFactor=Reset zoom factor -SequenceDiagram_ZoomOut=Zoom out -SequenceDiagram_ZoomOutTheDiagram=Zoom out the diagram -SequenceDiagram_Select=Select -SequenceDiagram_Max=Max -SequenceDiagram_Min=Min -SequenceDiagram_ListOfHideDisplayPatterns=List of hide/display patterns -SequenceDiagram_hide=hide -SequenceDiagram_display=display -SequenceDiagram_EditIt=Edit it -SequenceDiagram_Add=Add... -SequenceDiagram_Create=Create -SequenceDiagram_Update=Update -SequenceDiagram_Remove=Remove -SequenceDiagram_SequenceDiagramHidePatterns=Sequence Diagram Hide Patterns -SequenceDiagram_DefinitionOfHidePattern=Definition of Hide Pattern -SequenceDiagram_PageNavigation=Page navigation -SequenceDiagram_SequenceDiagramPages=Sequence Diagram Pages -SequenceDiagram_IsInBetween={0,number} <= value <= {1,number} -SequenceDiagram_Total=Total: -SequenceDiagram_pages=pages -SequenceDiagram_page=page -SequenceDiagram_CurrentPage=Current page: -SequenceDiagram_Navigation=Navigation -SequenceDiagram_OpenOverviewTooltip=Click to open Overview\nDrag mouse to scroll\nUse Shift+Drag, Ctrl+Drag to scroll slower\nUse Shift+Ctrl+Drag to scroll very fine -SequenceDiagram_LifelineWidth=&Lifeline Width (in pixels) -SequenceDiagram_AaBbYyZz=AaBbYyZz -SequenceDiagram_IncreaseFontSizeWhenZooming=&Increase font size when zooming -SequenceDiagram_ExcludeExternalTime=&Exclude external time -SequenceDiagram_UseGradientColor=&Use gradient color -SequenceDiagram_Background=Background -SequenceDiagram_Lines=Lines -SequenceDiagram_Text=Text -SequenceDiagram_ExecutionOccurrence=Execution Occurrence -SequenceDiagram_SyncMessage=Sync Message -SequenceDiagram_SyncMessageReturn=Sync Message Return -SequenceDiagram_AsyncMessage=Async Message -SequenceDiagram_AsyncMessageReturn=Async Message Return -SequenceDiagram_Frame=Frame -SequenceDiagram_LifelineHeader=Lifeline Header -SequenceDiagram_FrameTitle=Frame Title -SequenceDiagram_ShowTooltips=&Show tooltips -SequenceDiagram_Error=Error -SequenceDiagram_InvalidRange=Invalid range -SequenceDiagram_InvalidNbVertical=Number of vertical pages is invalid -SequenceDiagram_InvalidNbHorizontal=Number of horizontal pages is invalid -SequenceDiagram_NoPageSelected=There is no page selected -SequenceDiagram_FromPage=F&rom page -SequenceDiagram_to=&to -SequenceDiagram_SelectedPages=Selected pages -SequenceDiagram_CurrentView=Current view -SequenceDiagram_AllPages=&All pages -TotalNumberOfPages=Total number of pages: -SequenceDiagram_NumberOfHorizontalPages=Number of horizontal pages: -SequenceDiagram_NumberOfVerticalPages=Number of vertical pages: -SequenceDiagram_UseCurrentZoom=Use current zoom -SequenceDiagram_ZoomOption=Zoom options -SequenceDiagram_Print=Print -SequenceDiagram_Printer=Printer... -SequenceDiagram_plus={0} + {1} -SequenceDiagram_Page=Page {0} -SequenceDiagram_PrintRange=Print range -SequenceDiagram_Preview=Preview - -SequenceDiagram_TimeCompressionBarConfig=TimeCompression bar configuration -SequenceDiagram_MinTime=Min time -SequenceDiagram_MaxTime=Max time -SequenceDiagram_Default=Default - -SequenceDiagram_NoPrinterSelected=No default printer is selected. Click Printer button first and select a printer. - -SequenceDiagram_Scale=Scale -SequenceDiagram_Precision=Precision -SequenceDiagram_Delta=Delta - -SequenceDiagram_FirstPage=First page -SequenceDiagram_GoToFirstPage=Go to first page -SequenceDiagram_LastPage=Last page -SequenceDiagram_GoToLastPage=Go to last page - -SequenceDiagram_ShowNodeEnd=Show the node end -SequenceDiagram_ShowNodeStart=Show the node start -SequenceDiagram_ConfigureMinMax=Configure Min Max... diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/rawviewer/TmfRawEventViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/rawviewer/TmfRawEventViewer.java deleted file mode 100644 index 9845fa09b7..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/rawviewer/TmfRawEventViewer.java +++ /dev/null @@ -1,1060 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.rawviewer; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.CaretEvent; -import org.eclipse.swt.custom.CaretListener; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.ControlListener; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.events.MouseTrackListener; -import org.eclipse.swt.events.MouseWheelListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Slider; - -/** - * TmfRawEventViewer allows for the display of the raw data for an arbitrarily - * large number of TMF events. - * - * It is essentially a Composite of a StyledText area and a Slider, where the number - * of visible lines in the StyledText control is set to fill the viewer display area. - * An underlying data model is used to store a cache of event raw text line data. - * The slider is ratio-based. - * - * @version 1.0 - * @author Patrick Tasse - */ -public class TmfRawEventViewer extends Composite implements ControlListener, SelectionListener, - KeyListener, CaretListener, MouseMoveListener, MouseTrackListener, MouseWheelListener { - - private static final Color COLOR_BACKGROUND_ODD = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE); - private static final Color COLOR_BACKGROUND_EVEN = new Color(Display.getDefault(), 242, 242, 242); - private static final Color COLOR_BACKGROUND_SELECTED = new Color(Display.getDefault(), 231, 246, 254); - private static final Color COLOR_BACKGROUND_HIGHLIGHTED = new Color(Display.getDefault(), 246, 252, 255); - private static final int MAX_LINE_DATA_SIZE = 1000; - private static final int SLIDER_MAX = 1000000; - - private ITmfTrace fTrace; - private ITmfContext fBottomContext; - - private ScrolledComposite fScrolledComposite; - private Composite fTextArea; - private StyledText fStyledText; - private Font fFixedFont; - private Slider fSlider; - - private final List fLines = new ArrayList<>(); - private boolean fActualRanks = false; - private int fTopLineIndex; - private int fLastTopLineIndex; - private final CaretPosition[] fStoredCaretPosition = new CaretPosition[] - { new CaretPosition(0, 0), new CaretPosition(0,0)}; - private int fNumVisibleLines; - private ITmfLocation fSelectedLocation = null; - private long fHighlightedRank = Long.MIN_VALUE; - private int fCursorYCoordinate = -1; - private int fHoldSelection = 0; - - private static class LineData { - long rank; - ITmfLocation location; - String string; - public LineData(long rank, ITmfLocation location, String string) { - this.rank = rank; - this.location = location; - if (string.length() == 0) { - this.string = " "; // workaround for setLineBackground has no effect on empty line //$NON-NLS-1$ - } else { - this.string = string; - } - } - @Override - public String toString() { - return rank + " [" + location + "]: " + string; //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - private static class CaretPosition { - int time; - int caretOffset; - public CaretPosition(int time, int caretOffset) { - this.time = time; - this.caretOffset = caretOffset; - } - } - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructor - * @param parent The parent composite - * @param style The style bits - */ - public TmfRawEventViewer(Composite parent, int style) { - super(parent, style & (~SWT.H_SCROLL) & (~SWT.V_SCROLL)); - - // Set the layout - GridLayout gridLayout = new GridLayout(); - gridLayout.numColumns = 2; - gridLayout.horizontalSpacing = 0; - gridLayout.verticalSpacing = 0; - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - setLayout(gridLayout); - - // Create the controls - createTextArea(style & SWT.H_SCROLL); - createSlider(style & SWT.V_SCROLL); - - // Prevent the slider from being traversed - setTabList(new Control[] { fScrolledComposite }); - } - - @Override - public void dispose() { - if (fFixedFont != null) { - fFixedFont.dispose(); - fFixedFont = null; - } - super.dispose(); - } - - // ------------------------------------------------------------------------ - // Text area handling - // ------------------------------------------------------------------------ - - /** - * Create the text area and add listeners - */ - private void createTextArea(int style) { - fScrolledComposite = new ScrolledComposite(this, style); - fScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - fTextArea = new Composite(fScrolledComposite, SWT.NONE); - fTextArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - fScrolledComposite.setContent(fTextArea); - fScrolledComposite.setExpandHorizontal(true); - fScrolledComposite.setExpandVertical(true); - fScrolledComposite.setAlwaysShowScrollBars(true); - fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT)); - fScrolledComposite.addControlListener(this); - - GridLayout textAreaGridLayout = new GridLayout(); - textAreaGridLayout.marginHeight = 0; - textAreaGridLayout.marginWidth = 0; - fTextArea.setLayout(textAreaGridLayout); - - if (fFixedFont == null) { - if (System.getProperty("os.name").contains("Windows")) { //$NON-NLS-1$ //$NON-NLS-2$ - fFixedFont = new Font(Display.getCurrent(), new FontData("Courier New", 10, SWT.NORMAL)); //$NON-NLS-1$ - } else { - fFixedFont = new Font(Display.getCurrent(), new FontData("Monospace", 10, SWT.NORMAL)); //$NON-NLS-1$ - } - } - - fStyledText = new StyledText(fTextArea, SWT.READ_ONLY); - fStyledText.setFont(fFixedFont); - fStyledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - - fStyledText.addCaretListener(this); - fStyledText.addMouseMoveListener(this); - fStyledText.addMouseTrackListener(this); - fStyledText.addMouseWheelListener(this); - fStyledText.addListener(SWT.MouseWheel, new Listener() { // disable mouse scroll of horizontal scroll bar - @Override - public void handleEvent(Event event) { event.doit = false; }}); - fStyledText.addKeyListener(this); - - fTextArea.setBackground(fStyledText.getBackground()); - fTextArea.addMouseListener(new MouseAdapter() { - @Override - public void mouseDown(MouseEvent e) { - fTextArea.setFocus(); - }}); - } - - // ------------------------------------------------------------------------ - // Slider handling - // ------------------------------------------------------------------------ - - private void createSlider(int style) { - fSlider = new Slider(this, SWT.VERTICAL); - fSlider.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true)); - fSlider.setValues(0, 0, SLIDER_MAX, SLIDER_MAX, 1, 1); - fSlider.addSelectionListener(this); - if ((style & SWT.V_SCROLL) == 0) { - fSlider.setVisible(false); - } - } - - // ------------------------------------------------------------------------ - // Controls interactions - // ------------------------------------------------------------------------ - - @Override - public boolean setFocus() { - boolean isVisible = isVisible(); - if (isVisible) { - fTextArea.setFocus(); - } - return isVisible; - } - - @Override - public void setMenu(Menu menu) { - fStyledText.setMenu(menu); - } - - /** - * Sets the trace and updates the content - * @param trace The trace to set - */ - public void setTrace(ITmfTrace trace) { - fTrace = trace; - fTopLineIndex = 0; - fLines.clear(); - refreshEventCount(); - } - - /** - * Refreshes the event count, updates the slider thumb and loads display - */ - public void refreshEventCount() { - if (fTrace != null) { - if (fTrace.getNbEvents() > 0) { - fSlider.setThumb((int) Math.max(SLIDER_MAX / fTrace.getNbEvents(), 1)); - } else { - fSlider.setThumb(SLIDER_MAX); - } - - if (!isVisible()) { - return; - } - - if (fLines.size() == 0) { - setTopRank(0); - } else if (fLines.size() < fNumVisibleLines) { - fBottomContext = null; - loadLineData(); - fillTextArea(); - //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents()))); - fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location))); - } - } else { - fBottomContext = null; - fillTextArea(); - fSlider.setThumb(SLIDER_MAX); - fSlider.setSelection(0); - } - } - - /** - * Selects the event of given rank and makes it visible. - * @param rank The rank of event - */ - public void selectAndReveal(long rank) { - if (fTrace == null || !isVisible()) { - return; - } - if (fActualRanks && fTopLineIndex < fLines.size() && rank >= fLines.get(fTopLineIndex).rank) { - int lastVisibleIndex = Math.min(fTopLineIndex + fNumVisibleLines, fLines.size()) - 1; - if (rank <= fLines.get(lastVisibleIndex).rank) { - for (int i = fTopLineIndex; i < fLines.size(); i++) { - if (fLines.get(i).rank == rank) { - fSelectedLocation = fLines.get(i).location; - break; - } - } - refreshLineBackgrounds(); - return; - } - } - setTopRank(rank); - if (fLines.size() > 0 && fHoldSelection == 0) { - fSelectedLocation = fLines.get(0).location; - refreshLineBackgrounds(); - } - } - - /** - * Add a selection listener - * @param listener A listener to add - */ - public void addSelectionListener(Listener listener) { - checkWidget(); - if (listener == null) { - SWT.error (SWT.ERROR_NULL_ARGUMENT); - } - addListener (SWT.Selection, listener); - } - - /** - * Remove selection listener - * @param listener A listener to remove - */ - public void removeSelectionListener(Listener listener) { - checkWidget(); - if (listener == null) { - SWT.error (SWT.ERROR_NULL_ARGUMENT); - } - removeListener(SWT.Selection, listener); - } - - private void sendSelectionEvent(LineData lineData) { - Event event = new Event(); - if (fActualRanks) { - event.data = Long.valueOf(lineData.rank); - } else { - event.data = lineData.location; - } - notifyListeners(SWT.Selection, event); - } - - private void setTopRank(long rank) { - fBottomContext = fTrace.seekEvent(rank); - if (fBottomContext == null) { - return; - } - fLines.clear(); - fActualRanks = true; - fTopLineIndex = 0; - loadLineData(); - refreshTextArea(); - if (fLines.size() == 0) { - fSlider.setSelection(0); - } else { - //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents()))); - fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location))); - } - } - - private void setTopPosition(double ratio) { - fBottomContext = fTrace.seekEvent(ratio); - if (fBottomContext == null) { - return; - } - fBottomContext.setRank(0); - fLines.clear(); - fActualRanks = false; - fTopLineIndex = 0; - loadLineData(); - refreshTextArea(); - } - - private void loadLineData() { - if (fTopLineIndex < 0) { - //if (fLines.size() > 0 && fLines.get(0).rank > 0) { - //long endRank = fLines.get(0).rank; - //long startRank = Math.max(0, endRank - fNumVisibleLines); - //TmfContext context = fTrace.seekEvent(startRank); - //int index = 0; - //while (context.getRank() < endRank) { - //long rank = context.getRank(); - //ITmfLocation location = context.getLocation(); - //TmfEvent event = fTrace.getNextEvent(context); - //String[] lines = event.getRawText().split("\r?\n"); - //for (int i = 0; i < lines.length; i++) { - //String line = lines[i]; - //LineData lineData = new LineData(rank, location, line); - //fLines.add(index++, lineData); - //fTopLineIndex++; - //fLastTopLineIndex++; - //} - //} - //} - if (fLines.size() > 0 && fTrace.getLocationRatio(fLines.get(0).location) > 0) { - double lastRatio = fTrace.getLocationRatio(fLines.get(fLines.size() - 1).location); - double firstRatio = fTrace.getLocationRatio(fLines.get(0).location); - double delta; - boolean singleEvent = false; - if (firstRatio != lastRatio) { - // approximate ratio of at least 20 items - delta = Math.max(20, fNumVisibleLines) * (lastRatio - firstRatio) / (fLines.size() - 1); - } else { - delta = Math.pow(10, -15); - singleEvent = true; - } - while (fTopLineIndex < 0) { - ITmfLocation endLocation = fLines.get(0).location; - firstRatio = Math.max(0, firstRatio - delta); - ITmfContext context = fTrace.seekEvent(firstRatio); - ITmfLocation location; - int index = 0; - long rank = 0; - while (!context.getLocation().equals(endLocation)) { - location = context.getLocation(); - ITmfEvent event = fTrace.getNext(context); - if (event == null) { - break; - } - if (event.getContent() != null && event.getContent().getValue() != null) { - String[] lines = event.getContent().getValue().toString().split("\r?\n"); //$NON-NLS-1$ - for (int i = 0; i < lines.length; i++) { - String line = lines[i]; - LineData lineData = new LineData(rank, location, line); - fLines.add(index++, lineData); - fTopLineIndex++; - fLastTopLineIndex++; - } - } else { - LineData lineData = new LineData(rank, location, ""); //$NON-NLS-1$ - fLines.add(index++, lineData); - fTopLineIndex++; - fLastTopLineIndex++; - } - rank++; - } - long rankOffset = fLines.get(index).rank - rank; - for (int i = 0; i < index; i++) { - fLines.get(i).rank += rankOffset; - } - if (firstRatio == 0) { - break; - } - if (singleEvent) { - delta = Math.min(delta * 10, 0.1); - } - } - } - if (fTopLineIndex < 0) { - fTopLineIndex = 0; - } - } - - while (fLines.size() - fTopLineIndex < fNumVisibleLines) { - if (fBottomContext == null) { - if (fLines.size() == 0) { - fBottomContext = fTrace.seekEvent(0); - } else { - //fBottomContext = fTrace.seekEvent(fLines.get(fLines.size() - 1).rank + 1); - fBottomContext = fTrace.seekEvent(fLines.get(fLines.size() - 1).location); - fTrace.getNext(fBottomContext); - } - if (fBottomContext == null) { - break; - } - } - long rank = fBottomContext.getRank(); - ITmfLocation location = fBottomContext.getLocation() != null ? fBottomContext.getLocation() : null; - ITmfEvent event = fTrace.getNext(fBottomContext); - if (event == null) { - break; - } - if (event.getContent() != null && event.getContent().getValue() != null) { - for (String line : event.getContent().getValue().toString().split("\r?\n")) { //$NON-NLS-1$ - int crPos; - if ((crPos = line.indexOf('\r')) != -1) { - line = line.substring(0, crPos); - } - LineData lineData = new LineData(rank, location, line); - fLines.add(lineData); - } - } else { - LineData lineData = new LineData(rank, location, ""); //$NON-NLS-1$ - fLines.add(lineData); - } - } - fTopLineIndex = Math.max(0, Math.min(fTopLineIndex, fLines.size() - 1)); - - if (fLines.size() > MAX_LINE_DATA_SIZE) { - if (fTopLineIndex < MAX_LINE_DATA_SIZE / 2) { - long rank = fLines.get(MAX_LINE_DATA_SIZE - 1).rank; - for (int i = MAX_LINE_DATA_SIZE; i < fLines.size(); i++) { - if (fLines.get(i).rank > rank) { - fLines.subList(i, fLines.size()).clear(); - fBottomContext = null; - break; - } - } - } else { - long rank = fLines.get(fLines.size() - MAX_LINE_DATA_SIZE).rank; - for (int i = fLines.size() - MAX_LINE_DATA_SIZE - 1; i >= 0; i--) { - if (fLines.get(i).rank < rank) { - fLines.subList(0, i + 1).clear(); - fTopLineIndex -= (i + 1); - fLastTopLineIndex -= (i + 1); - break; - } - } - } - } - } - - private void refreshTextArea() { - fStyledText.setText(""); //$NON-NLS-1$ - for (int i = 0; i < fLines.size() - fTopLineIndex && i < fNumVisibleLines; i++) { - if (i > 0) - { - fStyledText.append("\n"); //$NON-NLS-1$ - } - LineData lineData = fLines.get(fTopLineIndex + i); - fStyledText.append(lineData.string); - setLineBackground(i, lineData); - } - fTextArea.layout(); - fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT)); - fLastTopLineIndex = fTopLineIndex; - } - - private void fillTextArea() { - int nextLine = fStyledText.getCharCount() == 0 ? 0 : fStyledText.getLineCount(); - for (int i = nextLine; i < fLines.size() - fTopLineIndex && i < fNumVisibleLines; i++) { - if (i > 0) - { - fStyledText.append("\n"); //$NON-NLS-1$ - } - LineData lineData = fLines.get(fTopLineIndex + i); - fStyledText.append(lineData.string); - setLineBackground(i, lineData); - } - int endLine = Math.min(fNumVisibleLines, fLines.size()); - if (endLine < fStyledText.getLineCount()) { - int endOffset = fStyledText.getOffsetAtLine(endLine) - 1; - if (endOffset > fStyledText.getCharCount()) { - fHoldSelection++; - fStyledText.replaceTextRange(endOffset, fStyledText.getCharCount() - endOffset, ""); //$NON-NLS-1$ - fHoldSelection--; - } - } - fTextArea.layout(); - fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT)); - } - - private void updateTextArea() { - if (fTopLineIndex < fLastTopLineIndex) { - StringBuffer insertedText = new StringBuffer(); - for (int i = fTopLineIndex; i < fLastTopLineIndex; i++) { - insertedText.append(fLines.get(i).string + "\n"); //$NON-NLS-1$ - } - fStyledText.replaceTextRange(0, 0, insertedText.toString()); - for (int i = 0; i < fLastTopLineIndex - fTopLineIndex; i++) { - LineData lineData = fLines.get(fTopLineIndex + i); - setLineBackground(i, lineData); - } - fLastTopLineIndex = fTopLineIndex; - } else if (fTopLineIndex > fLastTopLineIndex) { - int length = 0; - for (int i = 0; i < fTopLineIndex - fLastTopLineIndex && i < fNumVisibleLines; i++) { - length += fLines.get(i + fLastTopLineIndex).string.length(); - if (i < fStyledText.getLineCount()) { - length += 1; - } - } - fStyledText.replaceTextRange(0, length, ""); //$NON-NLS-1$ - fLastTopLineIndex = fTopLineIndex; - fillTextArea(); - } - int endLine = Math.min(fNumVisibleLines, fLines.size()); - if (endLine < fStyledText.getLineCount()) { - int endOffset = fStyledText.getOffsetAtLine(endLine) - 1; - if (endOffset > fStyledText.getCharCount()) { - fStyledText.replaceTextRange(endOffset, fStyledText.getCharCount() - endOffset, ""); //$NON-NLS-1$ - } - } - fTextArea.layout(); - fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT)); - } - - private void refreshLineBackgrounds() { - for (int i = 0; (i < fStyledText.getLineCount()) && (i < fNumVisibleLines) && (i < fLines.size() - fTopLineIndex); i++) { - LineData lineData = fLines.get(fTopLineIndex + i); - setLineBackground(i, lineData); - } - } - - private void setLineBackground(int index, LineData lineData) { - if (lineData.location.equals(fSelectedLocation)) { - fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_SELECTED); - } else if (lineData.rank == fHighlightedRank) { - fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_HIGHLIGHTED); - } else if (lineData.rank % 2 == 0) { - fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_EVEN); - } else { - fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_ODD); - } - } - - private void storeCaretPosition(int time, int caretOffset) { - if (fStoredCaretPosition[0].time == time) { - fStoredCaretPosition[0].caretOffset = caretOffset; - } else { - fStoredCaretPosition[1] = fStoredCaretPosition[0]; - fStoredCaretPosition[0] = new CaretPosition(time, caretOffset); - } - } - - private int getPreviousCaretOffset(int time) { - if (fStoredCaretPosition[0].time == time) { - return fStoredCaretPosition[1].caretOffset; - } - return fStoredCaretPosition[0].caretOffset; - } - - private void updateHighlightedRank() { - if (fCursorYCoordinate < 0 || fCursorYCoordinate > fStyledText.getSize().y) { - if (fHighlightedRank != Long.MIN_VALUE) { - fHighlightedRank = Long.MIN_VALUE; - refreshLineBackgrounds(); - } - return; - } - int offset = fStyledText.getOffsetAtLocation(new Point(0, fCursorYCoordinate)); - int line = fStyledText.getLineAtOffset(offset); - if (line < fLines.size() - fTopLineIndex) { - LineData lineData = fLines.get(fTopLineIndex + line); - if (fHighlightedRank != lineData.rank) { - fHighlightedRank = lineData.rank; - refreshLineBackgrounds(); - } - } else { - if (fHighlightedRank != Long.MIN_VALUE) { - fHighlightedRank = Long.MIN_VALUE; - refreshLineBackgrounds(); - } - } - } - - // ------------------------------------------------------------------------ - // ControlListener (ScrolledComposite) - // ------------------------------------------------------------------------ - - @Override - public void controlResized(ControlEvent event) { - int areaHeight = fScrolledComposite.getSize().y; - if (fScrolledComposite.getHorizontalBar() != null) { - areaHeight -= fScrolledComposite.getHorizontalBar().getSize().y; - } - int lineHeight = fStyledText.getLineHeight(); - fNumVisibleLines = Math.max((areaHeight + lineHeight - 1) / lineHeight, 1); - - if (fBottomContext != null) { - loadLineData(); - fillTextArea(); - } - } - - @Override - public void controlMoved(ControlEvent e) { - } - - // ------------------------------------------------------------------------ - // SelectionListener (Slider) - // ------------------------------------------------------------------------ - - @Override - public void widgetSelected(SelectionEvent e) { - fTextArea.setFocus(); - if (fLines.size() == 0) { - return; - } - if (e.detail == SWT.DRAG) { - return; - } - fHoldSelection++; - switch (e.detail) { - case SWT.NONE: { - //long rank = (long) (fTrace.getNbEvents() * ((double) fSlider.getSelection() / SLIDER_MAX)); - //setTopRank(rank); - if (fSlider.getSelection() == 0 || fSlider.getThumb() == SLIDER_MAX) { - fLines.clear(); - setTopPosition(0.0); - break; - } - double ratio = (double) fSlider.getSelection() / (SLIDER_MAX - fSlider.getThumb()); - double delta = Math.pow(10, -15); - fLines.clear(); - while (fLines.size() == 0) { - setTopPosition(ratio); - if (ratio == 0.0) { - break; - } - delta = Math.min(delta * 10, 0.1); - ratio = Math.max(ratio - delta, 0.0); - } - break; - } - case SWT.ARROW_DOWN: { - if (fTopLineIndex >= fLines.size()) { - break; - } - fTopLineIndex++; - loadLineData(); - updateTextArea(); - break; - } - case SWT.PAGE_DOWN: { - fTopLineIndex += Math.max(fNumVisibleLines - 1, 1); - loadLineData(); - updateTextArea(); - break; - } - case SWT.ARROW_UP: { - //if (fLines.size() == 0 || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) { - if (fLines.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) { - break; - } - fTopLineIndex--; - loadLineData(); - updateTextArea(); - break; - } - case SWT.PAGE_UP: { - fTopLineIndex -= Math.max(fNumVisibleLines - 1, 1); - loadLineData(); - updateTextArea(); - break; - } - case SWT.HOME: { - //selectAndReveal(0); - setTopPosition(0.0); - break; - } - case SWT.END: { - //if (fTrace.getNbEvents() > 0) { - //selectAndReveal(fTrace.getNbEvents() - 1); - //} - double ratio = 1.0; - double delta = Math.pow(10, -15); - fLines.clear(); - while (fLines.size() == 0) { - setTopPosition(ratio); - if (ratio == 0.0) { - break; - } - delta = Math.min(delta * 10, 0.1); - ratio = Math.max(ratio - delta, 0.0); - } - break; - } - default: - break; - } - //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents()))); - if (e.detail != SWT.NONE) { - fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location))); - } - - fHoldSelection = 0; - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - - // ------------------------------------------------------------------------ - // KeyListener (StyledText) - // ------------------------------------------------------------------------ - - @Override - public void keyPressed(KeyEvent e) { - if (fLines.size() == 0) { - return; - } - int caretOffset = fStyledText.getCaretOffset(); - int previousCaretOffset = getPreviousCaretOffset(e.time); - int previousLineAtCaretPosition = fStyledText.getLineAtOffset(previousCaretOffset); - int previousColumnAtCaretPosition = getPreviousCaretOffset(e.time) - fStyledText.getOffsetAtLine(previousLineAtCaretPosition); - switch (e.keyCode) { - case SWT.ARROW_DOWN: { - if (previousLineAtCaretPosition < (fNumVisibleLines - 2)) { - break; - } - fHoldSelection++; - fTopLineIndex++; - loadLineData(); - updateTextArea(); - fHoldSelection--; - LineData lineData = fLines.get(fTopLineIndex + fStyledText.getLineAtOffset(fStyledText.getCaretOffset())); - if (!lineData.location.equals(fSelectedLocation)) { - fSelectedLocation = lineData.location; - refreshLineBackgrounds(); - sendSelectionEvent(lineData); - } - break; - } - case SWT.PAGE_DOWN: { - if (previousLineAtCaretPosition >= (fNumVisibleLines - 1)) { - fHoldSelection++; - if (fLines.get(fTopLineIndex + previousLineAtCaretPosition).rank % 2 == 0) { - fStyledText.setLineBackground(previousLineAtCaretPosition, 1, COLOR_BACKGROUND_EVEN); - } else { - fStyledText.setLineBackground(previousLineAtCaretPosition, 1, COLOR_BACKGROUND_ODD); - } - fSelectedLocation = null; - fTopLineIndex += Math.max(fNumVisibleLines - 1, 1); - loadLineData(); - updateTextArea(); - fHoldSelection--; - } - int line = Math.min(fNumVisibleLines - 1, fStyledText.getLineCount() - 1); - int offset = fStyledText.getOffsetAtLine(line); - fStyledText.setSelection(offset + Math.min(previousColumnAtCaretPosition, fLines.get(fTopLineIndex + line).string.length())); - break; - } - case SWT.ARROW_RIGHT: { - if (previousCaretOffset < fStyledText.getCharCount() || previousLineAtCaretPosition < (fNumVisibleLines - 2)) { - break; - } - fHoldSelection++; - fTopLineIndex++; - loadLineData(); - updateTextArea(); - fHoldSelection--; - fStyledText.setSelection(fStyledText.getCaretOffset() + 1); - break; - } - case SWT.ARROW_UP: { - if (previousLineAtCaretPosition > 0) { - break; - } - if (fLines.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) { - break; - } - fHoldSelection++; - fTopLineIndex--; - loadLineData(); - updateTextArea(); - fHoldSelection--; - LineData lineData = fLines.get(fTopLineIndex); - if (!lineData.location.equals(fSelectedLocation)) { - fSelectedLocation = lineData.location; - refreshLineBackgrounds(); - sendSelectionEvent(lineData); - } - fStyledText.setSelection(caretOffset); - break; - } - case SWT.PAGE_UP: { - if (previousLineAtCaretPosition > 0) { - break; - } - fHoldSelection++; - fTopLineIndex -= Math.max(fNumVisibleLines - 1, 1); - loadLineData(); - updateTextArea(); - fHoldSelection--; - LineData lineData = fLines.get(fTopLineIndex); - if (!lineData.location.equals(fSelectedLocation)) { - fSelectedLocation = lineData.location; - refreshLineBackgrounds(); - sendSelectionEvent(lineData); - } - fStyledText.setSelection(caretOffset); - break; - } - case SWT.ARROW_LEFT: { - if (previousCaretOffset > 0) { - break; - } - if (fLines.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) { - break; - } - long topRank = fLines.get(fTopLineIndex).rank; - fHoldSelection++; - fTopLineIndex--; - loadLineData(); - updateTextArea(); - fHoldSelection--; - LineData lineData = fLines.get(fTopLineIndex); - if (!lineData.location.equals(fSelectedLocation)) { - fSelectedLocation = lineData.location; - refreshLineBackgrounds(); - sendSelectionEvent(lineData); - } - if (topRank != fLines.get(fTopLineIndex).rank) { - fStyledText.setSelection(fLines.get(fTopLineIndex).string.length()); - } - break; - } - case SWT.HOME: { - if ((e.stateMask & SWT.CTRL) == 0) { - break; - } - //selectAndReveal(0); - setTopPosition(0.0); - LineData lineData = fLines.get(fTopLineIndex); - if (!lineData.location.equals(fSelectedLocation)) { - fSelectedLocation = lineData.location; - refreshLineBackgrounds(); - sendSelectionEvent(lineData); - } - break; - } - case SWT.END: { - if ((e.stateMask & SWT.CTRL) == 0) { - break; - } - //if (fTrace.getNbEvents() > 0) { - //selectAndReveal(fTrace.getNbEvents() - 1); - //} - double ratio = 1.0; - double delta = Math.pow(10, -15); - fLines.clear(); - while (fLines.size() == 0) { - setTopPosition(ratio); - if (ratio == 0.0) { - break; - } - delta = Math.min(delta * 10, 0.1); - ratio = Math.max(ratio - delta, 0.0); - } - LineData lineData = fLines.get(fTopLineIndex); - if (!lineData.location.equals(fSelectedLocation)) { - fSelectedLocation = lineData.location; - refreshLineBackgrounds(); - sendSelectionEvent(lineData); - } - break; - } - default: - break; - } - //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents()))); - updateHighlightedRank(); - fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location))); - } - - @Override - public void keyReleased(KeyEvent e) { - } - - // ------------------------------------------------------------------------ - // CaretListener (StyledText) - // ------------------------------------------------------------------------ - - @Override - public void caretMoved(CaretEvent event) { - if (fHoldSelection == 0) { - int line = fStyledText.getLineAtOffset(event.caretOffset); - if (fTopLineIndex + line < fLines.size()) { - LineData lineData = fLines.get(fTopLineIndex + line); - if (!lineData.location.equals(fSelectedLocation)) { - fSelectedLocation = lineData.location; - refreshLineBackgrounds(); - sendSelectionEvent(lineData); - } - } - } - storeCaretPosition(event.time, event.caretOffset); - if (fHoldSelection == 0) { - Point caret = fStyledText.getLocationAtOffset(fStyledText.getCaretOffset()); - Point origin = fScrolledComposite.getOrigin(); - if (origin.x > caret.x) { - origin.x = caret.x; - } else if (caret.x - origin.x > fScrolledComposite.getSize().x) { - origin.x = caret.x - fScrolledComposite.getSize().x + 1; - } - fScrolledComposite.setOrigin(origin); - } - } - - // ------------------------------------------------------------------------ - // MouseMoveListener (StyledText) - // ------------------------------------------------------------------------ - - @Override - public void mouseMove(MouseEvent e) { - fCursorYCoordinate = e.y; - if (e.y < 0 || e.y > fStyledText.getSize().y) { - if (fHighlightedRank != Long.MIN_VALUE) { - fHighlightedRank = Long.MIN_VALUE; - refreshLineBackgrounds(); - } - return; - } - int offset = fStyledText.getOffsetAtLocation(new Point(0, e.y)); - int line = fStyledText.getLineAtOffset(offset); - if (line < fLines.size() - fTopLineIndex) { - LineData lineData = fLines.get(fTopLineIndex + line); - if (fHighlightedRank != lineData.rank) { - fHighlightedRank = lineData.rank; - refreshLineBackgrounds(); - } - } else { - if (fHighlightedRank != Long.MIN_VALUE) { - fHighlightedRank = Long.MIN_VALUE; - refreshLineBackgrounds(); - } - } - } - - // ------------------------------------------------------------------------ - // MouseTrackListener (StyledText) - // ------------------------------------------------------------------------ - - @Override - public void mouseExit(MouseEvent e) { - fCursorYCoordinate = -1; - if (fHighlightedRank != Long.MIN_VALUE) { - fHighlightedRank = Long.MIN_VALUE; - refreshLineBackgrounds(); - } - } - - @Override - public void mouseEnter(MouseEvent e) { - fCursorYCoordinate = e.y; - } - - @Override - public void mouseHover(MouseEvent e) { - } - - // ------------------------------------------------------------------------ - // MouseWheelListener (StyledText) - // ------------------------------------------------------------------------ - - @Override - public void mouseScrolled(MouseEvent e) { - if (fLines.size() == 0) { - return; - } - fHoldSelection++; - fTopLineIndex -= e.count; - loadLineData(); - updateTextArea(); - fHoldSelection = 0; - //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents()))); - updateHighlightedRank(); - fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location))); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/tabsview/TmfViewerFolder.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/tabsview/TmfViewerFolder.java deleted file mode 100644 index 753d783dd5..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/tabsview/TmfViewerFolder.java +++ /dev/null @@ -1,193 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathieu Denis - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.tabsview; - -import java.util.Collection; -import java.util.HashMap; - -import org.eclipse.linuxtools.tmf.ui.viewers.ITmfViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.custom.CTabItem; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Composite; - -/** - * Allows the user to create multiple tabs which makes it look like folders. It - * simplifies the management of the viewer contained in each tab. - * - * The indexing of the viewers is based on their name. - * - * @author Mathieu Denis - * @version 2.0 - * @since 2.0 - */ -public class TmfViewerFolder extends Composite { - - /** - * The list of viewers in the folder - */ - private final HashMap fViewers; - - /** - * The parent folder that contains all viewers - */ - private CTabFolder fFolder; - - /** - * Constructor with empty style - * - * @param parent - * The parent composite - */ - public TmfViewerFolder(Composite parent) { - this(parent, SWT.NONE); - } - - /** - * Constructor - * - * @param parent - * The parent composite - * @param style - * The style of the view that will be created - */ - public TmfViewerFolder(Composite parent, int style) { - super(parent, style); - setLayout(new FillLayout()); - - fViewers = new HashMap<>(); - initFolder(); - } - - @Override - public void dispose() { - super.dispose(); - for (ITmfViewer viewer : fViewers.values()) { - viewer.dispose(); - } - if (fFolder != null) { - fFolder.dispose(); - } - } - - /** - * Disposes of all the viewers contained in the folder and restart to a - * clean state. - */ - public void clear() { - for (ITmfViewer viewer : fViewers.values()) { - viewer.dispose(); - } - fViewers.clear(); - fFolder.dispose(); - initFolder(); - } - - /** - * Create a new tab that will hold the viewer content. The viewer name will - * be used as the name for the tab. The viewer ID must be unique and can be - * used to retrieve the viewer from the folder. - * - * The parent of the viewer control must be the folder returned by - * {@link #getParentFolder()} - * - * @param viewer - * The viewer to put in the new tab - * @param viewerID - * The ID that will be assigned to this viewer for easy - * retrieving - * @param style - * The style of the widget to build - * @return true on success, false otherwise - */ - public boolean addTab(ITmfViewer viewer, String viewerID, int style) { - if (fFolder == null - || viewer.getControl().getParent() != fFolder - || fViewers.containsKey(viewerID)) { - return false; - } - CTabItem item = new CTabItem(fFolder, style); - item.setText(viewer.getName()); - item.setControl(viewer.getControl()); - // Register the viewer in the map to dispose it at closing time - fViewers.put(viewerID, viewer); - return true; - } - - /** - * Gets the folder that will be use as the parent of tabs that will hold the - * viewer. - * - * In order to be able to add new tabs in this view, the parent of the - * viewer control has to be this composite. - * - * @return the folder composite to use as the parent for the viewer control - * to create. - */ - public Composite getParentFolder() { - return fFolder; - } - - /** - * Gets a viewer based on his name. - * - * @param viewerName - * The name of the viewer to find in the folder - * @return The viewer which name is viewerName, or null if there is no such - * viewer - */ - public ITmfViewer getViewer(String viewerName) { - return fViewers.get(viewerName); - } - - /** - * Gets the viewers list contained in the folder view. The list can return - * the viewers in any order. It is not to be assumed that the viewers are - * returned in the same order as they were inserted. - * - * @return a collection of viewers contained in this view. - */ - public Collection getViewers() { - return fViewers.values(); - } - - /** - * Selects the tab at the specified index from the insertion order - * - * @param index - * The index of the tab to be selected - * @throws SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setSelection(int index) throws SWTException { - fFolder.setSelection(index); - } - - /** - * Initializes the folder or put it a back to a clean state. - */ - private void initFolder() { - if (fFolder != null) { - fFolder.dispose(); - } - fFolder = new CTabFolder(this, SWT.LEFT | SWT.BORDER); - fFolder.setSimple(false); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphColorListener.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphColorListener.java deleted file mode 100644 index 4983569e0e..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphColorListener.java +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; - -/** - * A time graph state color change listener - * - * @author Geneviève Bastien - * @since 3.0 - */ -public interface ITimeGraphColorListener { - - /** - * Notify the listener that the presentation provider's color may have - * changed and they need to be reloaded - * - * @param stateItems - * The new state table - */ - void colorSettingsChanged(StateItem[] stateItems); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphContentProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphContentProvider.java deleted file mode 100644 index fda2a07ff0..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphContentProvider.java +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; - -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; - - -/** - * A content provider mediates between the viewer's model - * and the viewer itself. - * - * @since 3.0 - */ -public interface ITimeGraphContentProvider { - /** - * Returns the time graph entries to display in the viewer when its input is - * set to the given element. - * - * @param inputElement - * the input element - * @return the array of time graph entries to display in the viewer - */ - public ITimeGraphEntry[] getElements(Object inputElement); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider.java deleted file mode 100644 index c93c218351..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider.java +++ /dev/null @@ -1,177 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; - -import java.util.Map; - -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Rectangle; - -/** - * Interface for the time graph widget provider - * - * @version 1.0 - * @author Patrick Tasse - */ -public interface ITimeGraphPresentationProvider { - - /** State table index for an invisible event - * @since 2.0 - */ - final int INVISIBLE = -1; - - /** State table index for a transparent event (only borders drawn) - * @since 2.0 - */ - final int TRANSPARENT = -2; - - /** - * Returns the name of state types. - * - * @return the name of state types - */ - String getStateTypeName(); - - /** - * Returns the name of state type depending on the given entry. - * Note that this overwrites the name which is return by getStateTypeName(). - * - * @param entry - * the entry - * @return the name of state type depending on the given entry or null. - * @since 2.0 - */ - String getStateTypeName(ITimeGraphEntry entry); - - /** - * Returns table of states with state name to state color relationship. - * - * @return table of states with color and name - * - * @see #getStateTableIndex - */ - StateItem[] getStateTable(); - - /** - * Returns the index in the state table corresponding to this time event. - * The index should correspond to a state in the state table, - * otherwise the color SWT.COLOR_BLACK will be used. - * If the index returned is TRANSPARENT, only the event borders will be drawn. - * If the index returned is INVISIBLE or another negative, the event will not be drawn. - * - * @param event the time event - * @return the corresponding state table index - * - * @see #getStateTable - * @see #TRANSPARENT - * @see #INVISIBLE - */ - int getStateTableIndex(ITimeEvent event); - - /** - * Called after drawing the control - * - * @param bounds - * The drawing rectangle - * @param gc - * The graphics context - */ - void postDrawControl(Rectangle bounds, GC gc); - - /** - * Called after drawing an entry - * - * @param entry - * the entry that was drawn - * @param bounds - * the drawing rectangle - * @param gc - * the graphics context - */ - void postDrawEntry(ITimeGraphEntry entry, Rectangle bounds, GC gc); - - /** - * Called after drawing an event - * - * @param event - * the event that was drawn - * @param bounds - * the drawing rectangle - * @param gc - * the graphics context - */ - void postDrawEvent(ITimeEvent event, Rectangle bounds, GC gc); - - /** - * Returns the height of this item. This value is ignored if the time graph has a fixed item height. - * - * @param entry the entry - * @return the item height - * - * @see TimeGraphViewer#setItemHeight - */ - int getItemHeight(ITimeGraphEntry entry); - - /** - * Provides the image icon for a given entry. - * - * @param entry the entry - * @return the image icon - */ - Image getItemImage(ITimeGraphEntry entry); - - /** - * Returns the name of this event. - * - * @param event - * The event - * @return The event name - */ - String getEventName(ITimeEvent event); - - /** - * Returns a map of name and value providing additional information - * to display in the tool tip for this event. - * - * @param event the time event - * @return a map of tool tip information - */ - Map getEventHoverToolTipInfo(ITimeEvent event); - - /** - * Returns a map of name and value providing additional information - * to display in the tool tip for this event. - * - * @param event the time event - * @param hoverTime the time corresponding to the mouse hover position - * @return a map of tool tip information - * - * @since 2.0 - */ - Map getEventHoverToolTipInfo(ITimeEvent event, long hoverTime); - - /** - * Check whether time and duration should be displayed in tooltip (after items from - * {@link #getEventHoverToolTipInfo(ITimeEvent)}). - * - * @return true if times and duration should be displayed on tooltip, false otherwise. - * - * @since 3.0 - */ - public boolean displayTimesInTooltip(); - - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider2.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider2.java deleted file mode 100644 index 0a33c9dc73..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider2.java +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Add drawing helper methods - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; - -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.ITmfTimeGraphDrawingHelper; - -/** - * Extension of the ITimeGraphPresentationProvider interface to avoid API breakage - * - * @author Geneviève Bastien - * @since 2.1 - * TODO: Add me to ITimeGraphPresentationProvider before the 3.0 release - */ -public interface ITimeGraphPresentationProvider2 extends ITimeGraphPresentationProvider { - - /** - * Returns the drawing helper for this presentation provider. - * - * @return The drawing helper - */ - ITmfTimeGraphDrawingHelper getDrawingHelper(); - - /** - * Sets this presentation provider's drawing helper. - * This helper be needed to know where to draw items, get its coordinates - * given a time, etc. - * - * @param helper - * The drawing helper - */ - void setDrawingHelper(ITmfTimeGraphDrawingHelper helper); - - /** - * Adds a color settings listener, to be notified when the presentation - * provider's state colors change. - * - * @param listener - * The new listener for color settings changes - * @since 3.0 - */ - public void addColorListener(ITimeGraphColorListener listener); - - /** - * Removes a color settings listener. - * - * @param listener - * The color settings listener to remove - * @since 3.0 - */ - public void removeColorListener(ITimeGraphColorListener listener); - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphRangeListener.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphRangeListener.java deleted file mode 100644 index e7794645d7..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphRangeListener.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; - -import java.util.EventListener; - -/** - * A listener which is notified when a timegraph changes its visible time range. - * - * @version 1.0 - * @author Patrick Tasse - */ -public interface ITimeGraphRangeListener extends EventListener { - - /** - * Notifies that the timegraph range has changed. - * - * @param event event object describing details - */ - void timeRangeUpdated(TimeGraphRangeUpdateEvent event); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphSelectionListener.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphSelectionListener.java deleted file mode 100644 index 9481bc6fc7..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphSelectionListener.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; - -import java.util.EventListener; - -/** - * A listener which is notified when a timegraph changes its selected time. - * - * @version 1.0 - * @author Patrick Tasse - */ -public interface ITimeGraphSelectionListener extends EventListener { - - /** - * Notifies that the timegraph selected entry has changed. - * - * @param event event object describing details - */ - void selectionChanged(TimeGraphSelectionEvent event); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphTimeListener.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphTimeListener.java deleted file mode 100644 index e52a0ee6b6..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphTimeListener.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; - -import java.util.EventListener; - -/** - * A listener which is notified when a timegraph changes its selected time. - * - * @version 1.0 - * @author Patrick Tasse - */ -public interface ITimeGraphTimeListener extends EventListener { - - /** - * Notifies that the timegraph selected time has changed. - * - * @param event event object describing details - */ - void timeSelected(TimeGraphTimeEvent event); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphTreeListener.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphTreeListener.java deleted file mode 100644 index 1b3f288e2d..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphTreeListener.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; - -/** - * A listener which is notified when a timegraph expands or collapses an entry. - * - * @version 1.0 - * @author Patrick Tasse - */ -public interface ITimeGraphTreeListener { - - /** - * Notifies that an entry in the timegraph has been collapsed. - * - * @param event event object describing details - */ - void treeCollapsed(TimeGraphTreeExpansionEvent event); - - /** - * Notifies that an entry in the timegraph has been expanded. - * - * @param event event object describing details - */ - void treeExpanded(TimeGraphTreeExpansionEvent event); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/StateItem.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/StateItem.java deleted file mode 100644 index aa04677e48..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/StateItem.java +++ /dev/null @@ -1,107 +0,0 @@ -/********************************************************************** - * Copyright (c) 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Bernd Hufmann - Initial API and implementation - **********************************************************************/ -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; - -import org.eclipse.swt.graphics.RGB; - -/** - * Class that contains the color of a state and the corresponding state string - * to display. - * - * @version 1.0 - * @author Bernd Hufmann - */ -public class StateItem { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - /** - * Name of state if not known - */ - public static final String UNDEFINED_STATE_NAME = "Undefined"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - /** - * The State color - */ - private RGB fStateColor; - /** - * The State string. - */ - private String fStateString; - - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Creates a state item with given color and unspecified name. - * - * @param stateColor A state color - */ - public StateItem(RGB stateColor) { - this(stateColor, UNDEFINED_STATE_NAME); - } - - /** - * Creates a state color - state string pair. - * - * @param stateColor A state color - * @param stateString A state string - */ - public StateItem(RGB stateColor, String stateString) { - fStateColor = stateColor; - fStateString = stateString; - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - /** - * Returns the state color. - * - * @return Returns the state color. - */ - public RGB getStateColor() { - return fStateColor; - } - - /** - * Sets the state color. - * - * @param stateColor A state color to set - */ - public void setStateColor(RGB stateColor) { - fStateColor = stateColor; - } - - /** - * Returns the state string. - * - * @return the state string. - */ - public String getStateString() { - return fStateString; - } - - /** - * Sets the state string - * @param stateString A state string to set - */ - public void setStateString(String stateString) { - fStateString = stateString; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphCombo.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphCombo.java deleted file mode 100644 index 3b772fd33f..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphCombo.java +++ /dev/null @@ -1,1134 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson, others - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * François Rajotte - Filter implementation - * Geneviève Bastien - Add event links between entries - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; - -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.Set; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.viewers.AbstractTreeViewer; -import org.eclipse.jface.viewers.ILabelProviderListener; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.ITableLabelProvider; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.ITreeViewerListener; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.TreeExpansionEvent; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerFilter; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.dialogs.TimeGraphFilterDialog; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.SashForm; -import org.eclipse.swt.events.ControlAdapter; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseTrackAdapter; -import org.eclipse.swt.events.MouseWheelListener; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Slider; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.TreeColumn; -import org.eclipse.swt.widgets.TreeItem; - -/** - * Time graph "combo" view (with the list/tree on the left and the gantt chart - * on the right) - * - * @version 1.0 - * @author Patrick Tasse - */ -public class TimeGraphCombo extends Composite { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /** Constant indicating that all levels of the time graph should be expanded - * @since 3.1 */ - public static final int ALL_LEVELS = AbstractTreeViewer.ALL_LEVELS; - - private static final Object FILLER = new Object(); - - private static final String ITEM_HEIGHT = "$height$"; //$NON-NLS-1$ - - // ------------------------------------------------------------------------ - // Fields - // ------------------------------------------------------------------------ - - /** The tree viewer */ - private TreeViewer fTreeViewer; - - /** The time viewer */ - private TimeGraphViewer fTimeGraphViewer; - - /** The selection listener map */ - private final Map fSelectionListenerMap = new HashMap<>(); - - /** The map of viewer filters */ - private final Map fViewerFilterMap = new HashMap<>(); - - /** - * Flag to block the tree selection changed listener when triggered by the - * time graph combo - */ - private boolean fInhibitTreeSelection = false; - - /** Number of filler rows used by the tree content provider */ - private int fNumFillerRows; - - /** Calculated item height for Linux workaround */ - private int fLinuxItemHeight = 0; - - /** The button that opens the filter dialog */ - private Action showFilterAction; - - /** The filter dialog */ - private TimeGraphFilterDialog fFilterDialog; - - /** The filter generated from the filter dialog */ - private RawViewerFilter fFilter; - - /** Default weight of each part of the sash */ - private static final int[] DEFAULT_WEIGHTS = { 1, 1 }; - - /** List of all expanded items whose parents are also expanded */ - private List fVisibleExpandedItems = null; - - // ------------------------------------------------------------------------ - // Classes - // ------------------------------------------------------------------------ - - /** - * The TreeContentProviderWrapper is used to insert filler items after - * the elements of the tree's real content provider. - */ - private class TreeContentProviderWrapper implements ITreeContentProvider { - private final ITreeContentProvider contentProvider; - - public TreeContentProviderWrapper(ITreeContentProvider contentProvider) { - this.contentProvider = contentProvider; - } - - @Override - public void dispose() { - contentProvider.dispose(); - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - contentProvider.inputChanged(viewer, oldInput, newInput); - } - - @Override - public Object[] getElements(Object inputElement) { - Object[] elements = contentProvider.getElements(inputElement); - // add filler elements to ensure alignment with time analysis viewer - Object[] oElements = Arrays.copyOf(elements, elements.length + fNumFillerRows, Object[].class); - for (int i = 0; i < fNumFillerRows; i++) { - oElements[elements.length + i] = FILLER; - } - return oElements; - } - - @Override - public Object[] getChildren(Object parentElement) { - if (parentElement instanceof ITimeGraphEntry) { - return contentProvider.getChildren(parentElement); - } - return new Object[0]; - } - - @Override - public Object getParent(Object element) { - if (element instanceof ITimeGraphEntry) { - return contentProvider.getParent(element); - } - return null; - } - - @Override - public boolean hasChildren(Object element) { - if (element instanceof ITimeGraphEntry) { - return contentProvider.hasChildren(element); - } - return false; - } - } - - /** - * The TreeLabelProviderWrapper is used to intercept the filler items - * from the calls to the tree's real label provider. - */ - private class TreeLabelProviderWrapper implements ITableLabelProvider { - private final ITableLabelProvider labelProvider; - - public TreeLabelProviderWrapper(ITableLabelProvider labelProvider) { - this.labelProvider = labelProvider; - } - - @Override - public void addListener(ILabelProviderListener listener) { - labelProvider.addListener(listener); - } - - @Override - public void dispose() { - labelProvider.dispose(); - } - - @Override - public boolean isLabelProperty(Object element, String property) { - if (element instanceof ITimeGraphEntry) { - return labelProvider.isLabelProperty(element, property); - } - return false; - } - - @Override - public void removeListener(ILabelProviderListener listener) { - labelProvider.removeListener(listener); - } - - @Override - public Image getColumnImage(Object element, int columnIndex) { - if (element instanceof ITimeGraphEntry) { - return labelProvider.getColumnImage(element, columnIndex); - } - return null; - } - - @Override - public String getColumnText(Object element, int columnIndex) { - if (element instanceof ITimeGraphEntry) { - return labelProvider.getColumnText(element, columnIndex); - } - return null; - } - - } - - /** - * The SelectionListenerWrapper is used to intercept the filler items from - * the time graph combo's real selection listener, and to prevent double - * notifications from being sent when selection changes in both tree and - * time graph at the same time. - */ - private class SelectionListenerWrapper implements ISelectionChangedListener, ITimeGraphSelectionListener { - private final ITimeGraphSelectionListener listener; - private ITimeGraphEntry selection = null; - - public SelectionListenerWrapper(ITimeGraphSelectionListener listener) { - this.listener = listener; - } - - @Override - public void selectionChanged(SelectionChangedEvent event) { - if (fInhibitTreeSelection) { - return; - } - Object element = ((IStructuredSelection) event.getSelection()).getFirstElement(); - if (element instanceof ITimeGraphEntry) { - ITimeGraphEntry entry = (ITimeGraphEntry) element; - if (entry != selection) { - selection = entry; - listener.selectionChanged(new TimeGraphSelectionEvent(event.getSource(), selection)); - } - } - } - - @Override - public void selectionChanged(TimeGraphSelectionEvent event) { - ITimeGraphEntry entry = event.getSelection(); - if (entry != selection) { - selection = entry; - listener.selectionChanged(new TimeGraphSelectionEvent(event.getSource(), selection)); - } - } - } - - /** - * The ViewerFilterWrapper is used to intercept the filler items from - * the time graph combo's real ViewerFilters. These filler items should - * always be visible. - */ - private class ViewerFilterWrapper extends ViewerFilter { - - private ViewerFilter fWrappedFilter; - - ViewerFilterWrapper(ViewerFilter filter) { - super(); - this.fWrappedFilter = filter; - } - - @Override - public boolean select(Viewer viewer, Object parentElement, Object element) { - if (element instanceof ITimeGraphEntry) { - return fWrappedFilter.select(viewer, parentElement, element); - } - return true; - } - - } - - /** - * This filter simply keeps a list of elements that should be filtered out. - * All the other elements will be shown. - * By default and when the list is set to null, all elements are shown. - */ - private class RawViewerFilter extends ViewerFilter { - - private List fFiltered = null; - - public void setFiltered(List objects) { - fFiltered = objects; - } - - public List getFiltered() { - return fFiltered; - } - - @Override - public boolean select(Viewer viewer, Object parentElement, Object element) { - if (fFiltered == null) { - return true; - } - return !fFiltered.contains(element); - } - } - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructs a new instance of this class given its parent - * and a style value describing its behavior and appearance. - * - * @param parent a widget which will be the parent of the new instance (cannot be null) - * @param style the style of widget to construct - */ - public TimeGraphCombo(Composite parent, int style) { - this(parent, style, DEFAULT_WEIGHTS); - } - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of widget to construct - * @param weights - * The relative weights of each side of the sash form - * @since 2.1 - */ - public TimeGraphCombo(Composite parent, int style, int[] weights) { - super(parent, style); - setLayout(new FillLayout()); - - final SashForm sash = new SashForm(this, SWT.NONE); - - fTreeViewer = new TreeViewer(sash, SWT.FULL_SELECTION | SWT.H_SCROLL); - fTreeViewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS); - final Tree tree = fTreeViewer.getTree(); - tree.setHeaderVisible(true); - tree.setLinesVisible(true); - - fTimeGraphViewer = new TimeGraphViewer(sash, SWT.NONE); - fTimeGraphViewer.setItemHeight(getItemHeight(tree)); - fTimeGraphViewer.setHeaderHeight(tree.getHeaderHeight()); - fTimeGraphViewer.setBorderWidth(tree.getBorderWidth()); - fTimeGraphViewer.setNameWidthPref(0); - - fFilter = new RawViewerFilter(); - addFilter(fFilter); - - fFilterDialog = new TimeGraphFilterDialog(getShell()); - - // Feature in Windows. The tree vertical bar reappears when - // the control is resized so we need to hide it again. - // Bug in Linux. The tree header height is 0 in constructor, - // so we need to reset it later when the control is resized. - tree.addControlListener(new ControlAdapter() { - private int depth = 0; - @Override - public void controlResized(ControlEvent e) { - if (depth == 0) { - depth++; - tree.getVerticalBar().setEnabled(false); - // this can trigger controlResized recursively - tree.getVerticalBar().setVisible(false); - depth--; - } - fTimeGraphViewer.setHeaderHeight(tree.getHeaderHeight()); - } - }); - - // ensure synchronization of expanded items between tree and time graph - fTreeViewer.addTreeListener(new ITreeViewerListener() { - @Override - public void treeCollapsed(TreeExpansionEvent event) { - fTimeGraphViewer.setExpandedState((ITimeGraphEntry) event.getElement(), false); - // queue the alignment update because the tree items may only be - // actually collapsed after the listeners have been notified - fVisibleExpandedItems = null; // invalidate the cache - getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - alignTreeItems(true); - }}); - } - - @Override - public void treeExpanded(TreeExpansionEvent event) { - ITimeGraphEntry entry = (ITimeGraphEntry) event.getElement(); - fTimeGraphViewer.setExpandedState(entry, true); - Set expandedElements = new HashSet<>(Arrays.asList(fTreeViewer.getExpandedElements())); - for (ITimeGraphEntry child : entry.getChildren()) { - if (child.hasChildren()) { - boolean expanded = expandedElements.contains(child); - fTimeGraphViewer.setExpandedState(child, expanded); - } - } - // queue the alignment update because the tree items may only be - // actually expanded after the listeners have been notified - fVisibleExpandedItems = null; // invalidate the cache - getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - alignTreeItems(true); - }}); - } - }); - - // ensure synchronization of expanded items between tree and time graph - fTimeGraphViewer.addTreeListener(new ITimeGraphTreeListener() { - @Override - public void treeCollapsed(TimeGraphTreeExpansionEvent event) { - fTreeViewer.setExpandedState(event.getEntry(), false); - alignTreeItems(true); - } - - @Override - public void treeExpanded(TimeGraphTreeExpansionEvent event) { - ITimeGraphEntry entry = event.getEntry(); - fTreeViewer.setExpandedState(entry, true); - Set expandedElements = new HashSet<>(Arrays.asList(fTreeViewer.getExpandedElements())); - for (ITimeGraphEntry child : entry.getChildren()) { - if (child.hasChildren()) { - boolean expanded = expandedElements.contains(child); - fTimeGraphViewer.setExpandedState(child, expanded); - } - } - alignTreeItems(true); - } - }); - - // prevent mouse button from selecting a filler tree item - tree.addListener(SWT.MouseDown, new Listener() { - @Override - public void handleEvent(Event event) { - TreeItem treeItem = tree.getItem(new Point(event.x, event.y)); - if (treeItem == null || treeItem.getData() == FILLER) { - event.doit = false; - List treeItems = getVisibleExpandedItems(tree, false); - if (treeItems.size() == 0) { - fTreeViewer.setSelection(new StructuredSelection()); - fTimeGraphViewer.setSelection(null); - return; - } - // this prevents from scrolling up when selecting - // the partially visible tree item at the bottom - tree.select(treeItems.get(treeItems.size() - 1)); - fTreeViewer.setSelection(new StructuredSelection()); - fTimeGraphViewer.setSelection(null); - } - } - }); - - // prevent mouse wheel from scrolling down into filler tree items - tree.addListener(SWT.MouseWheel, new Listener() { - @Override - public void handleEvent(Event event) { - event.doit = false; - Slider scrollBar = fTimeGraphViewer.getVerticalBar(); - fTimeGraphViewer.setTopIndex(scrollBar.getSelection() - event.count); - alignTreeItems(false); - } - }); - - // prevent key stroke from selecting a filler tree item - tree.addListener(SWT.KeyDown, new Listener() { - @Override - public void handleEvent(Event event) { - List treeItems = getVisibleExpandedItems(tree, false); - if (treeItems.size() == 0) { - fTreeViewer.setSelection(new StructuredSelection()); - event.doit = false; - return; - } - if (event.keyCode == SWT.ARROW_DOWN) { - int index = Math.min(fTimeGraphViewer.getSelectionIndex() + 1, treeItems.size() - 1); - fTimeGraphViewer.setSelection((ITimeGraphEntry) treeItems.get(index).getData()); - event.doit = false; - } else if (event.keyCode == SWT.PAGE_DOWN) { - int height = tree.getSize().y - tree.getHeaderHeight() - tree.getHorizontalBar().getSize().y; - int countPerPage = height / getItemHeight(tree); - int index = Math.min(fTimeGraphViewer.getSelectionIndex() + countPerPage - 1, treeItems.size() - 1); - fTimeGraphViewer.setSelection((ITimeGraphEntry) treeItems.get(index).getData()); - event.doit = false; - } else if (event.keyCode == SWT.END) { - fTimeGraphViewer.setSelection((ITimeGraphEntry) treeItems.get(treeItems.size() - 1).getData()); - event.doit = false; - } - if (fTimeGraphViewer.getSelectionIndex() >= 0) { - fTreeViewer.setSelection(new StructuredSelection(fTimeGraphViewer.getSelection())); - } else { - fTreeViewer.setSelection(new StructuredSelection()); - } - alignTreeItems(false); - } - }); - - // ensure alignment of top item between tree and time graph - fTimeGraphViewer.getTimeGraphControl().addControlListener(new ControlAdapter() { - @Override - public void controlResized(ControlEvent e) { - alignTreeItems(false); - } - }); - - // ensure synchronization of selected item between tree and time graph - fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() { - @Override - public void selectionChanged(SelectionChangedEvent event) { - if (fInhibitTreeSelection) { - return; - } - if (event.getSelection() instanceof IStructuredSelection) { - Object selection = ((IStructuredSelection) event.getSelection()).getFirstElement(); - if (selection instanceof ITimeGraphEntry) { - fTimeGraphViewer.setSelection((ITimeGraphEntry) selection); - } - alignTreeItems(false); - } - } - }); - - // ensure synchronization of selected item between tree and time graph - fTimeGraphViewer.addSelectionListener(new ITimeGraphSelectionListener() { - @Override - public void selectionChanged(TimeGraphSelectionEvent event) { - ITimeGraphEntry entry = fTimeGraphViewer.getSelection(); - fInhibitTreeSelection = true; // block the tree selection changed listener - if (entry != null) { - StructuredSelection selection = new StructuredSelection(entry); - fTreeViewer.setSelection(selection); - } else { - fTreeViewer.setSelection(new StructuredSelection()); - } - fInhibitTreeSelection = false; - alignTreeItems(false); - } - }); - - // ensure alignment of top item between tree and time graph - fTimeGraphViewer.getVerticalBar().addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - alignTreeItems(false); - } - }); - - // ensure alignment of top item between tree and time graph - fTimeGraphViewer.getTimeGraphControl().addMouseWheelListener(new MouseWheelListener() { - @Override - public void mouseScrolled(MouseEvent e) { - alignTreeItems(false); - } - }); - - // ensure the tree has focus control when mouse is over it if the time graph had control - fTreeViewer.getControl().addMouseTrackListener(new MouseTrackAdapter() { - @Override - public void mouseEnter(MouseEvent e) { - if (fTimeGraphViewer.getTimeGraphControl().isFocusControl()) { - fTreeViewer.getControl().setFocus(); - } - } - }); - - // ensure the time graph has focus control when mouse is over it if the tree had control - fTimeGraphViewer.getTimeGraphControl().addMouseTrackListener(new MouseTrackAdapter() { - @Override - public void mouseEnter(MouseEvent e) { - if (fTreeViewer.getControl().isFocusControl()) { - fTimeGraphViewer.getTimeGraphControl().setFocus(); - } - } - }); - fTimeGraphViewer.getTimeGraphScale().addMouseTrackListener(new MouseTrackAdapter() { - @Override - public void mouseEnter(MouseEvent e) { - if (fTreeViewer.getControl().isFocusControl()) { - fTimeGraphViewer.getTimeGraphControl().setFocus(); - } - } - }); - - // The filler rows are required to ensure alignment when the tree does not have a - // visible horizontal scroll bar. The tree does not allow its top item to be set - // to a value that would cause blank space to be drawn at the bottom of the tree. - fNumFillerRows = Display.getDefault().getBounds().height / getItemHeight(tree); - - sash.setWeights(weights); - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Returns this time graph combo's tree viewer. - * - * @return the tree viewer - */ - public TreeViewer getTreeViewer() { - return fTreeViewer; - } - - /** - * Returns this time graph combo's time graph viewer. - * - * @return the time graph viewer - */ - public TimeGraphViewer getTimeGraphViewer() { - return fTimeGraphViewer; - } - - /** - * Callback for the show filter action - * - * @since 2.0 - */ - public void showFilterDialog() { - ITimeGraphEntry[] topInput = fTimeGraphViewer.getTimeGraphContentProvider().getElements(fTimeGraphViewer.getInput()); - if (topInput != null) { - List allElements = listAllInputs(Arrays.asList(topInput)); - fFilterDialog.setInput(fTimeGraphViewer.getInput()); - fFilterDialog.setTitle(Messages.TmfTimeFilterDialog_WINDOW_TITLE); - fFilterDialog.setMessage(Messages.TmfTimeFilterDialog_MESSAGE); - fFilterDialog.setExpandedElements(allElements.toArray()); - if (fFilter.getFiltered() != null) { - ArrayList nonFilteredElements = new ArrayList<>(allElements); - nonFilteredElements.removeAll(fFilter.getFiltered()); - fFilterDialog.setInitialElementSelections(nonFilteredElements); - } else { - fFilterDialog.setInitialElementSelections(allElements); - } - fFilterDialog.create(); - fFilterDialog.open(); - // Process selected elements - if (fFilterDialog.getResult() != null) { - fInhibitTreeSelection = true; - if (fFilterDialog.getResult().length != allElements.size()) { - ArrayList filteredElements = new ArrayList(allElements); - filteredElements.removeAll(Arrays.asList(fFilterDialog.getResult())); - fFilter.setFiltered(filteredElements); - } else { - fFilter.setFiltered(null); - } - fTreeViewer.refresh(); - fTreeViewer.expandAll(); - fTimeGraphViewer.refresh(); - fInhibitTreeSelection = false; - alignTreeItems(true); - // Reset selection - if (fFilterDialog.getResult().length > 0) { - setSelection(null); - } - } - } - } - - /** - * Get the show filter action. - * - * @return The Action object - * @since 2.0 - */ - public Action getShowFilterAction() { - if (showFilterAction == null) { - // showFilter - showFilterAction = new Action() { - @Override - public void run() { - showFilterDialog(); - } - }; - showFilterAction.setText(Messages.TmfTimeGraphCombo_FilterActionNameText); - showFilterAction.setToolTipText(Messages.TmfTimeGraphCombo_FilterActionToolTipText); - // TODO find a nice, distinctive icon - showFilterAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FILTERS)); - } - - return showFilterAction; - } - - // ------------------------------------------------------------------------ - // Control - // ------------------------------------------------------------------------ - - @Override - public void redraw() { - fTimeGraphViewer.getControl().redraw(); - super.redraw(); - } - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Sets the tree content provider used by this time graph combo. - * - * @param contentProvider the tree content provider - */ - public void setTreeContentProvider(ITreeContentProvider contentProvider) { - fTreeViewer.setContentProvider(new TreeContentProviderWrapper(contentProvider)); - } - - /** - * Sets the tree label provider used by this time graph combo. - * - * @param labelProvider the tree label provider - */ - public void setTreeLabelProvider(ITableLabelProvider labelProvider) { - fTreeViewer.setLabelProvider(new TreeLabelProviderWrapper(labelProvider)); - } - - /** - * Sets the tree content provider used by the filter dialog - * - * @param contentProvider the tree content provider - * @since 2.0 - */ - public void setFilterContentProvider(ITreeContentProvider contentProvider) { - fFilterDialog.setContentProvider(contentProvider); - } - - /** - * Sets the tree label provider used by the filter dialog - * - * @param labelProvider the tree label provider - * @since 2.0 - */ - public void setFilterLabelProvider(ITableLabelProvider labelProvider) { - fFilterDialog.setLabelProvider(labelProvider); - } - - /** - * Sets the tree columns for this time graph combo. - * - * @param columnNames the tree column names - */ - public void setTreeColumns(String[] columnNames) { - final Tree tree = fTreeViewer.getTree(); - for (String columnName : columnNames) { - TreeColumn column = new TreeColumn(tree, SWT.LEFT); - column.setText(columnName); - column.pack(); - } - } - - /** - * Sets the tree columns for this time graph combo's filter dialog. - * - * @param columnNames the tree column names - * @since 2.0 - */ - public void setFilterColumns(String[] columnNames) { - fFilterDialog.setColumnNames(columnNames); - } - - /** - * Sets the time graph content provider used by this time graph combo. - * - * @param timeGraphContentProvider - * the time graph content provider - * - * @since 3.0 - */ - public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider) { - fTimeGraphViewer.setTimeGraphContentProvider(timeGraphContentProvider); - } - - /** - * Sets the time graph presentation provider used by this time graph combo. - * - * @param timeGraphProvider the time graph provider - */ - public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider) { - fTimeGraphViewer.setTimeGraphProvider(timeGraphProvider); - } - - /** - * Sets or clears the input for this time graph combo. - * - * @param input the input of this time graph combo, or null if none - * - * @since 3.0 - */ - public void setInput(Object input) { - fFilter.setFiltered(null); - fInhibitTreeSelection = true; - fTreeViewer.setInput(input); - for (SelectionListenerWrapper listenerWrapper : fSelectionListenerMap.values()) { - listenerWrapper.selection = null; - } - fInhibitTreeSelection = false; - fTreeViewer.getTree().getVerticalBar().setEnabled(false); - fTreeViewer.getTree().getVerticalBar().setVisible(false); - fTimeGraphViewer.setItemHeight(getItemHeight(fTreeViewer.getTree())); - fTimeGraphViewer.setInput(input); - // queue the alignment update because in Linux the item bounds are not - // set properly until the tree has been painted at least once - fVisibleExpandedItems = null; // invalidate the cache - getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - alignTreeItems(true); - }}); - } - - /** - * Gets the input for this time graph combo. - * - * @return The input of this time graph combo, or null if none - * - * @since 3.0 - */ - public Object getInput() { - return fTreeViewer.getInput(); - } - - /** - * Sets or clears the list of links to display on this combo - * - * @param links the links to display in this time graph combo - * @since 2.1 - */ - public void setLinks(List links) { - fTimeGraphViewer.setLinks(links); - } - - /** - * @param filter The filter object to be attached to the view - * @since 2.0 - */ - public void addFilter(ViewerFilter filter) { - ViewerFilter wrapper = new ViewerFilterWrapper(filter); - fTreeViewer.addFilter(wrapper); - fTimeGraphViewer.addFilter(wrapper); - fViewerFilterMap.put(filter, wrapper); - alignTreeItems(true); - } - - /** - * @param filter The filter object to be removed from the view - * @since 2.0 - */ - public void removeFilter(ViewerFilter filter) { - ViewerFilter wrapper = fViewerFilterMap.get(filter); - fTreeViewer.removeFilter(wrapper); - fTimeGraphViewer.removeFilter(wrapper); - fViewerFilterMap.remove(filter); - alignTreeItems(true); - } - - /** - * Refreshes this time graph completely with information freshly obtained from its model. - */ - public void refresh() { - fInhibitTreeSelection = true; - Tree tree = fTreeViewer.getTree(); - tree.setRedraw(false); - fTreeViewer.refresh(); - fTreeViewer.expandAll(); - tree.setRedraw(true); - fTimeGraphViewer.refresh(); - alignTreeItems(true); - fInhibitTreeSelection = false; - } - - /** - * Adds a listener for selection changes in this time graph combo. - * - * @param listener a selection listener - */ - public void addSelectionListener(ITimeGraphSelectionListener listener) { - SelectionListenerWrapper listenerWrapper = new SelectionListenerWrapper(listener); - fTreeViewer.addSelectionChangedListener(listenerWrapper); - fSelectionListenerMap.put(listener, listenerWrapper); - fTimeGraphViewer.addSelectionListener(listenerWrapper); - } - - /** - * Removes the given selection listener from this time graph combo. - * - * @param listener a selection changed listener - */ - public void removeSelectionListener(ITimeGraphSelectionListener listener) { - SelectionListenerWrapper listenerWrapper = fSelectionListenerMap.remove(listener); - fTreeViewer.removeSelectionChangedListener(listenerWrapper); - fTimeGraphViewer.removeSelectionListener(listenerWrapper); - } - - /** - * Sets the current selection for this time graph combo. - * - * @param selection the new selection - */ - public void setSelection(ITimeGraphEntry selection) { - fTimeGraphViewer.setSelection(selection); - fInhibitTreeSelection = true; // block the tree selection changed listener - if (selection != null) { - StructuredSelection structuredSelection = new StructuredSelection(selection); - fTreeViewer.setSelection(structuredSelection); - } else { - fTreeViewer.setSelection(new StructuredSelection()); - } - fInhibitTreeSelection = false; - alignTreeItems(false); - } - - /** - * Sets the auto-expand level to be used when the input of the viewer is set - * using {@link #setInput(Object)}. The value 0 means that there is no - * auto-expand; 1 means that top-level elements are expanded, but not their - * children; 2 means that top-level elements are expanded, and their - * children, but not grand-children; and so on. - *

- * The value {@link #ALL_LEVELS} means that all subtrees should be expanded. - *

- * @param level - * non-negative level, or ALL_LEVELS to expand all - * levels of the tree - * @since 3.1 - */ - public void setAutoExpandLevel(int level) { - fTimeGraphViewer.setAutoExpandLevel(level); - if (level <= 0) { - fTreeViewer.setAutoExpandLevel(level); - } else { - fTreeViewer.setAutoExpandLevel(level + 1); - } - } - - /** - * Returns the auto-expand level. - * - * @return non-negative level, or ALL_LEVELS if all levels of - * the tree are expanded automatically - * @see #setAutoExpandLevel - * @since 3.1 - */ - public int getAutoExpandLevel() { - return fTimeGraphViewer.getAutoExpandLevel(); - } - - /** - * Set the expanded state of an entry - * - * @param entry - * The entry to expand/collapse - * @param expanded - * True for expanded, false for collapsed - * - * @since 2.0 - */ - public void setExpandedState(ITimeGraphEntry entry, boolean expanded) { - fTimeGraphViewer.setExpandedState(entry, expanded); - fTreeViewer.setExpandedState(entry, expanded); - alignTreeItems(true); - } - - /** - * Collapses all nodes of the viewer's tree, starting with the root. - * - * @since 2.0 - */ - public void collapseAll() { - fTimeGraphViewer.collapseAll(); - fTreeViewer.collapseAll(); - alignTreeItems(true); - } - - /** - * Expands all nodes of the viewer's tree, starting with the root. - * - * @since 2.0 - */ - public void expandAll() { - fTimeGraphViewer.expandAll(); - fTreeViewer.expandAll(); - alignTreeItems(true); - } - - // ------------------------------------------------------------------------ - // Internal - // ------------------------------------------------------------------------ - - private List getVisibleExpandedItems(Tree tree, boolean refresh) { - if (fVisibleExpandedItems == null || refresh) { - ArrayList items = new ArrayList<>(); - for (TreeItem item : tree.getItems()) { - if (item.getData() == FILLER) { - break; - } - items.add(item); - if (item.getExpanded()) { - addVisibleExpandedItems(items, item); - } - } - fVisibleExpandedItems = items; - } - return fVisibleExpandedItems; - } - - private void addVisibleExpandedItems(List items, TreeItem treeItem) { - for (TreeItem item : treeItem.getItems()) { - items.add(item); - if (item.getExpanded()) { - addVisibleExpandedItems(items, item); - } - } - } - - /** - * Explores the list of top-level inputs and returns all the inputs - * - * @param inputs The top-level inputs - * @return All the inputs - */ - private List listAllInputs(List inputs) { - ArrayList items = new ArrayList<>(); - for (ITimeGraphEntry entry : inputs) { - items.add(entry); - if (entry.hasChildren()) { - items.addAll(listAllInputs(entry.getChildren())); - } - } - return items; - } - - private int getItemHeight(final Tree tree) { - /* - * Bug in Linux. The method getItemHeight doesn't always return the correct value. - */ - if (fLinuxItemHeight >= 0 && System.getProperty("os.name").contains("Linux")) { //$NON-NLS-1$ //$NON-NLS-2$ - if (fLinuxItemHeight != 0) { - return fLinuxItemHeight; - } - List treeItems = getVisibleExpandedItems(tree, true); - if (treeItems.size() > 1) { - final TreeItem treeItem0 = treeItems.get(0); - final TreeItem treeItem1 = treeItems.get(1); - PaintListener paintListener = new PaintListener() { - @Override - public void paintControl(PaintEvent e) { - tree.removePaintListener(this); - int y0 = treeItem0.getBounds().y; - int y1 = treeItem1.getBounds().y; - int itemHeight = y1 - y0; - if (itemHeight > 0) { - fLinuxItemHeight = itemHeight; - fTimeGraphViewer.setItemHeight(itemHeight); - } - } - }; - tree.addPaintListener(paintListener); - } - } else { - fLinuxItemHeight = -1; // Not Linux, don't perform os.name check anymore - } - return tree.getItemHeight(); - } - - private void alignTreeItems(boolean refreshExpandedItems) { - // align the tree top item with the time graph top item - Tree tree = fTreeViewer.getTree(); - List treeItems = getVisibleExpandedItems(tree, refreshExpandedItems); - int topIndex = fTimeGraphViewer.getTopIndex(); - if (topIndex >= treeItems.size()) { - return; - } - TreeItem item = treeItems.get(topIndex); - tree.setTopItem(item); - - // ensure the time graph item heights are equal to the tree item heights - int treeHeight = fTreeViewer.getTree().getBounds().height; - int index = topIndex; - Rectangle bounds = item.getBounds(); - while (index < treeItems.size() - 1) { - if (bounds.y > treeHeight) { - break; - } - /* - * Bug in Linux. The method getBounds doesn't always return the correct height. - * Use the difference of y position between items to calculate the height. - */ - TreeItem nextItem = treeItems.get(index + 1); - Rectangle nextBounds = nextItem.getBounds(); - Integer itemHeight = nextBounds.y - bounds.y; - if (itemHeight > 0 && !itemHeight.equals(item.getData(ITEM_HEIGHT))) { - ITimeGraphEntry entry = (ITimeGraphEntry) item.getData(); - if (fTimeGraphViewer.getTimeGraphControl().setItemHeight(entry, itemHeight)) { - item.setData(ITEM_HEIGHT, itemHeight); - } - } - index++; - item = nextItem; - bounds = nextBounds; - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphPresentationProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphPresentationProvider.java deleted file mode 100644 index 05d11bbb46..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphPresentationProvider.java +++ /dev/null @@ -1,189 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alvaro Sanchez-Leon - Initial API and implementation - * Patrick Tasse - Refactoring - * Geneviève Bastien - Add drawing helper methods - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.ITmfTimeGraphDrawingHelper; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Rectangle; - -/** - * Provider class for the time graph provider - * - * @version 1.0 - * @author Patrick Tasse - * - */ -public class TimeGraphPresentationProvider implements ITimeGraphPresentationProvider2 { - - private ITmfTimeGraphDrawingHelper fDrawingHelper; - private final String fStateTypeName; - - // The list of listeners for graph color changes - private final List fListeners = new ArrayList<>(); - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - private static final int DEFAULT_ITEM_HEIGHT = 19; - - // ------------------------------------------------------------------------ - // Operations - // ------------------------------------------------------------------------ - - /** - * Constructor - * @param stateTypeName The state type name - * @since 2.1 - */ - public TimeGraphPresentationProvider(String stateTypeName) { - fStateTypeName = stateTypeName; - } - - /** - * Constructor - * @since 2.1 - */ - public TimeGraphPresentationProvider() { - this(Messages.TmfTimeLegend_TRACE_STATES); - } - - @Override - public String getStateTypeName() { - return fStateTypeName; - } - - /** - * @see org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider#getStateTypeName(org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry) - * @since 2.0 - */ - @Override - public String getStateTypeName(ITimeGraphEntry entry) { - return null; - } - - @Override - public StateItem[] getStateTable() { - return null; - } - - @Override - public int getStateTableIndex(ITimeEvent event) { - return 0; - } - - /** - * @since 2.1 - */ - @Override - public ITmfTimeGraphDrawingHelper getDrawingHelper() { - return fDrawingHelper; - } - - /** - * @since 2.1 - */ - @Override - public void setDrawingHelper(ITmfTimeGraphDrawingHelper helper) { - fDrawingHelper = helper; - } - - @Override - public void postDrawControl(Rectangle bounds, GC gc) { - // Override to add own drawing code - } - - @Override - public void postDrawEntry(ITimeGraphEntry entry, Rectangle bounds, GC gc) { - // Override to add own drawing code - } - - @Override - public void postDrawEvent(ITimeEvent event, Rectangle bounds, GC gc) { - // Override to add own drawing code - } - - @Override - public int getItemHeight(ITimeGraphEntry entry) { - return DEFAULT_ITEM_HEIGHT; - } - - @Override - public Image getItemImage(ITimeGraphEntry entry) { - return null; - } - - @Override - public String getEventName(ITimeEvent event) { - return null; - } - - @Override - public Map getEventHoverToolTipInfo(ITimeEvent event) { - return null; - } - - /** - * @since 2.0 - */ - @Override - public Map getEventHoverToolTipInfo(ITimeEvent event, long hoverTime) { - return getEventHoverToolTipInfo(event); - } - - /** - * @since 3.0 - */ - @Override - public boolean displayTimesInTooltip() { - return true; - } - - /** - * @since 3.0 - */ - @Override - public void addColorListener(ITimeGraphColorListener listener) { - if (!fListeners.contains(listener)) { - fListeners.add(listener); - } - } - - /** - * @since 3.0 - */ - @Override - public void removeColorListener(ITimeGraphColorListener listener) { - fListeners.remove(listener); - } - - /** - * Notifies listeners of the state table change - * @since 3.0 - */ - protected void fireColorSettingsChanged() { - for (ITimeGraphColorListener listener : fListeners) { - listener.colorSettingsChanged(getStateTable()); - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphRangeUpdateEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphRangeUpdateEvent.java deleted file mode 100644 index 1d59f51e3a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphRangeUpdateEvent.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; - -import java.util.EventObject; - -/** - * Notifier for the time graph that the time range has been updated. - * - * @version 1.0 - * @author Patrick Tasse - */ -public class TimeGraphRangeUpdateEvent extends EventObject { - - /** - * Default serial version UID for this class. - * @since 1.0 - */ - private static final long serialVersionUID = 1L; - - /** - * The start time. - */ - private final long fStartTime; - - /** - * The end time. - */ - private final long fEndTime; - - /** - * Standard constructor - * - * @param source - * The source of this event - * @param startTime - * The start time - * @param endTime - * The end time - */ - public TimeGraphRangeUpdateEvent(Object source, long startTime, long endTime) { - super(source); - fStartTime = startTime; - fEndTime = endTime; - } - - /** - * @return the start time - */ - public long getStartTime() { - return fStartTime; - } - - /** - * @return the end time - */ - public long getEndTime() { - return fEndTime; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphSelectionEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphSelectionEvent.java deleted file mode 100644 index eac0ded656..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphSelectionEvent.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; - -import java.util.EventObject; - -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; - -/** - * Notifier for the time graph that an object in the views has been selected. - * - * @version 1.0 - * @author Patrick Tasse - */ -public class TimeGraphSelectionEvent extends EventObject { - - /** - * Default serial version UID for this class. - * @since 1.0 - */ - private static final long serialVersionUID = 1L; - - /** - * The selected entry. - */ - private final ITimeGraphEntry fSelection; - - /** - * Standard constructor - * - * @param source - * The source of this event - * @param selection - * The entry that was selected - */ - public TimeGraphSelectionEvent(Object source, ITimeGraphEntry selection) { - super(source); - fSelection = selection; - } - - /** - * @return the selected entry or null if the selection is empty. - */ - public ITimeGraphEntry getSelection() { - return fSelection; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphTimeEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphTimeEvent.java deleted file mode 100644 index 9d2cfeda3e..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphTimeEvent.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; - -import java.util.EventObject; - -/** - * Time selection event - * - * @version 1.0 - * @author Patrick Tasse - */ -public class TimeGraphTimeEvent extends EventObject { - - /** - * Default serial version UID for this class. - * @since 1.0 - */ - private static final long serialVersionUID = 1L; - - /** - * The selection begin time. - */ - private final long fBeginTime; - - /** - * The selection end time. - */ - private final long fEndTime; - - /** - * Standard constructor - * - * @param source - * The source of this event - * @param beginTime - * The selection begin time - * @param endTime - * The selection end time - * @since 2.1 - */ - public TimeGraphTimeEvent(Object source, long beginTime, long endTime) { - super(source); - fBeginTime = beginTime; - fEndTime = endTime; - } - - /** - * @return the selection begin time - * @since 2.1 - */ - public long getBeginTime() { - return fBeginTime; - } - - /** - * @return the selection end time - * @since 2.1 - */ - public long getEndTime() { - return fEndTime; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphTreeExpansionEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphTreeExpansionEvent.java deleted file mode 100644 index 9cf37a8373..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphTreeExpansionEvent.java +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; - -import java.util.EventObject; - -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; - -/** - * Notifier for the time graph view that a tree has been expanded. - * - * @version 1.0 - * @author Patrick Tasse - */ -public class TimeGraphTreeExpansionEvent extends EventObject { - - /** - * Default serial version UID for this class. - * @since 1.0 - */ - private static final long serialVersionUID = 1L; - - /** - * The entry that was expanded or collapsed. - */ - private final ITimeGraphEntry fEntry; - - /** - * Creates a new event for the given source and entry. - * - * @param source the tree viewer - * @param entry the entry - */ - public TimeGraphTreeExpansionEvent(Object source, ITimeGraphEntry entry) { - super(source); - fEntry = entry; - } - - /** - * Returns the entry that got expanded or collapsed. - * - * @return the entry - */ - public ITimeGraphEntry getEntry() { - return fEntry; - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphViewer.java deleted file mode 100644 index e3dc486bc4..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphViewer.java +++ /dev/null @@ -1,1760 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2007, 2014 Intel Corporation, Ericsson, others - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Intel Corporation - Initial API and implementation - * Ruslan A. Scherbakov, Intel - Initial API and implementation - * Alexander N. Alexeev, Intel - Add monitors statistics support - * Alvaro Sanchez-Leon - Adapted for TMF - * Patrick Tasse - Refactoring - * Geneviève Bastien - Add event links between entries - *****************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.viewers.AbstractTreeViewer; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.ViewerFilter; -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.dialogs.TimeGraphLegend; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.ITimeDataProvider; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeDataProviderCyclesConverter; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphColorScheme; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphControl; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphScale; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphTooltipHandler; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ControlAdapter; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.KeyAdapter; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.MenuDetectListener; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseWheelListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.ScrollBar; -import org.eclipse.swt.widgets.Slider; - -/** - * Generic time graph viewer implementation - * - * @version 1.0 - * @author Patrick Tasse, and others - */ -public class TimeGraphViewer implements ITimeDataProvider, SelectionListener { - - /** Constant indicating that all levels of the time graph should be expanded - * @since 3.1 */ - public static final int ALL_LEVELS = AbstractTreeViewer.ALL_LEVELS; - - private static final int DEFAULT_NAME_WIDTH = 200; - private static final int MIN_NAME_WIDTH = 6; - private static final int MAX_NAME_WIDTH = 1000; - private static final int DEFAULT_HEIGHT = 22; - private static final long RECENTERING_MARGIN_FACTOR = 50; - private static final String HIDE_ARROWS_KEY = "hide.arrows"; //$NON-NLS-1$ - private static final long DEFAULT_FREQUENCY = 1000000000L; - - private long fMinTimeInterval; - private ITimeGraphEntry fSelectedEntry; - private long fBeginTime; - private long fEndTime; - private long fTime0; - private long fTime1; - private long fSelectionBegin = 0; - private long fSelectionEnd = 0; - private long fTime0Bound; - private long fTime1Bound; - private long fTime0ExtSynch = 0; - private long fTime1ExtSynch = 0; - private boolean fTimeRangeFixed; - private int fNameWidthPref = DEFAULT_NAME_WIDTH; - private int fMinNameWidth = MIN_NAME_WIDTH; - private int fNameWidth; - private Composite fDataViewer; - - private TimeGraphControl fTimeGraphCtrl; - private TimeGraphScale fTimeScaleCtrl; - private Slider fVerticalScrollBar; - private TimeGraphColorScheme fColorScheme; - private Object fInputElement; - private ITimeGraphContentProvider fTimeGraphContentProvider; - private ITimeGraphPresentationProvider fTimeGraphProvider; - private ITimeDataProvider fTimeDataProvider = this; - private TimeGraphTooltipHandler fToolTipHandler; - - private List fSelectionListeners = new ArrayList<>(); - private List fTimeListeners = new ArrayList<>(); - private List fRangeListeners = new ArrayList<>(); - - // Time format, using Epoch reference, Relative time format(default), - // Number, or Cycles - private TimeFormat fTimeFormat = TimeFormat.RELATIVE; - // Clock frequency to use for Cycles time format - private long fClockFrequency = DEFAULT_FREQUENCY; - private int fBorderWidth = 0; - private int fTimeScaleHeight = DEFAULT_HEIGHT; - - private Action fResetScaleAction; - private Action fShowLegendAction; - private Action fNextEventAction; - private Action fPrevEventAction; - private Action fNextItemAction; - private Action fPreviousItemAction; - private Action fZoomInAction; - private Action fZoomOutAction; - private Action fHideArrowsAction; - private Action fFollowArrowFwdAction; - private Action fFollowArrowBwdAction; - - /** - * Standard constructor. - *

- * The default timegraph content provider accepts an ITimeGraphEntry[] as input element. - * - * @param parent - * The parent UI composite object - * @param style - * The style to use - */ - public TimeGraphViewer(Composite parent, int style) { - createDataViewer(parent, style); - fTimeGraphContentProvider = new ITimeGraphContentProvider() { - @Override - public ITimeGraphEntry[] getElements(Object inputElement) { - if (inputElement instanceof ITimeGraphEntry[]) { - return (ITimeGraphEntry[]) inputElement; - } - return new ITimeGraphEntry[0]; - } - }; - } - - /** - * Sets the timegraph content provider used by this timegraph viewer. - * - * @param timeGraphContentProvider - * the timegraph content provider - * - * @since 3.0 - */ - public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider) { - fTimeGraphContentProvider = timeGraphContentProvider; - } - - /** - * Gets the timegraph content provider used by this timegraph viewer. - * - * @return the timegraph content provider - * - * @since 3.0 - */ - public ITimeGraphContentProvider getTimeGraphContentProvider() { - return fTimeGraphContentProvider; - } - - /** - * Sets the timegraph presentation provider used by this timegraph viewer. - * - * @param timeGraphProvider - * the timegraph provider - */ - public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider) { - fTimeGraphProvider = timeGraphProvider; - fTimeGraphCtrl.setTimeGraphProvider(timeGraphProvider); - fToolTipHandler = new TimeGraphTooltipHandler(fTimeGraphProvider, fTimeDataProvider); - fToolTipHandler.activateHoverHelp(fTimeGraphCtrl); - } - - /** - * Sets or clears the input for this time graph viewer. - * - * @param inputElement - * The input of this time graph viewer, or null if - * none - * - * @since 3.0 - */ - public void setInput(Object inputElement) { - fInputElement = inputElement; - ITimeGraphEntry[] input = fTimeGraphContentProvider.getElements(inputElement); - - if (fTimeGraphCtrl != null) { - setTimeRange(input); - fVerticalScrollBar.setEnabled(true); - setTopIndex(0); - fSelectionBegin = 0; - fSelectionEnd = 0; - fSelectedEntry = null; - refreshAllData(input); - } - } - - /** - * Gets the input for this time graph viewer. - * - * @return The input of this time graph viewer, or null if none - * - * @since 3.0 - */ - public Object getInput() { - return fInputElement; - } - - /** - * Sets (or clears if null) the list of links to display on this combo - * - * @param links - * the links to display in this time graph combo - * @since 2.1 - */ - public void setLinks(List links) { - if (fTimeGraphCtrl != null) { - fTimeGraphCtrl.refreshArrows(links); - } - } - - /** - * Refresh the view - */ - public void refresh() { - ITimeGraphEntry[] input = fTimeGraphContentProvider.getElements(fInputElement); - setTimeRange(input); - fVerticalScrollBar.setEnabled(true); - refreshAllData(input); - } - - /** - * Callback for when the control is moved - * - * @param e - * The caller event - */ - public void controlMoved(ControlEvent e) { - } - - /** - * Callback for when the control is resized - * - * @param e - * The caller event - */ - public void controlResized(ControlEvent e) { - resizeControls(); - } - - /** - * Handler for when the model is updated. Called from the display order in - * the API - * - * @param traces - * The traces in the model - * @param start - * The start time - * @param end - * The end time - * @param updateTimeBounds - * Should we updated the time bounds too - */ - public void modelUpdate(ITimeGraphEntry[] traces, long start, - long end, boolean updateTimeBounds) { - if (null != fTimeGraphCtrl) { - updateInternalData(traces, start, end); - if (updateTimeBounds) { - fTimeRangeFixed = true; - // set window to match limits - setStartFinishTime(fTime0Bound, fTime1Bound); - } else { - fTimeGraphCtrl.redraw(); - fTimeScaleCtrl.redraw(); - } - } - } - - /** - * @return The string representing the view type - */ - protected String getViewTypeStr() { - return "viewoption.threads"; //$NON-NLS-1$ - } - - int getMarginWidth() { - return 0; - } - - int getMarginHeight() { - return 0; - } - - void loadOptions() { - fMinTimeInterval = 1; - fSelectionBegin = -1; - fSelectionEnd = -1; - fNameWidth = Utils.loadIntOption(getPreferenceString("namewidth"), //$NON-NLS-1$ - fNameWidthPref, fMinNameWidth, MAX_NAME_WIDTH); - } - - void saveOptions() { - Utils.saveIntOption(getPreferenceString("namewidth"), fNameWidth); //$NON-NLS-1$ - } - - /** - * Create a data viewer. - * - * @param parent - * Parent composite - * @param style - * Style to use - * @return The new data viewer - */ - protected Control createDataViewer(Composite parent, int style) { - loadOptions(); - fColorScheme = new TimeGraphColorScheme(); - fDataViewer = new Composite(parent, style) { - @Override - public void redraw() { - fTimeScaleCtrl.redraw(); - fTimeGraphCtrl.redraw(); - super.redraw(); - } - }; - GridLayout gl = new GridLayout(2, false); - gl.marginHeight = fBorderWidth; - gl.marginWidth = 0; - gl.verticalSpacing = 0; - gl.horizontalSpacing = 0; - fDataViewer.setLayout(gl); - - fTimeScaleCtrl = new TimeGraphScale(fDataViewer, fColorScheme); - fTimeScaleCtrl.setTimeProvider(fTimeDataProvider); - fTimeScaleCtrl.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false)); - fTimeScaleCtrl.setHeight(fTimeScaleHeight); - - fVerticalScrollBar = new Slider(fDataViewer, SWT.VERTICAL | SWT.NO_FOCUS); - fVerticalScrollBar.setLayoutData(new GridData(SWT.DEFAULT, SWT.FILL, false, true, 1, 2)); - fVerticalScrollBar.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - setTopIndex(fVerticalScrollBar.getSelection()); - } - }); - fVerticalScrollBar.setEnabled(false); - - fTimeGraphCtrl = createTimeGraphControl(fDataViewer, fColorScheme); - - fTimeGraphCtrl.setTimeProvider(this); - fTimeGraphCtrl.setTimeGraphScale(fTimeScaleCtrl); - fTimeGraphCtrl.addSelectionListener(this); - fTimeGraphCtrl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 2)); - fTimeGraphCtrl.addMouseWheelListener(new MouseWheelListener() { - @Override - public void mouseScrolled(MouseEvent e) { - adjustVerticalScrollBar(); - } - }); - fTimeGraphCtrl.addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(KeyEvent e) { - if (e.character == '+') { - zoomIn(); - } else if (e.character == '-') { - zoomOut(); - } - adjustVerticalScrollBar(); - } - }); - - Composite filler = new Composite(fDataViewer, SWT.NONE); - GridData gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false); - gd.heightHint = fTimeGraphCtrl.getHorizontalBar().getSize().y; - filler.setLayoutData(gd); - filler.setLayout(new FillLayout()); - - fTimeGraphCtrl.addControlListener(new ControlAdapter() { - @Override - public void controlResized(ControlEvent event) { - resizeControls(); - } - }); - resizeControls(); - fDataViewer.update(); - adjustVerticalScrollBar(); - return fDataViewer; - } - - /** - * Dispose the view. - */ - public void dispose() { - saveOptions(); - fTimeGraphCtrl.dispose(); - fDataViewer.dispose(); - fColorScheme.dispose(); - } - - /** - * Create a new time graph control. - * - * @param parent - * The parent composite - * @param colors - * The color scheme - * @return The new TimeGraphControl - * @since 2.0 - */ - protected TimeGraphControl createTimeGraphControl(Composite parent, - TimeGraphColorScheme colors) { - return new TimeGraphControl(parent, colors); - } - - /** - * Resize the controls - */ - public void resizeControls() { - Rectangle r = fDataViewer.getClientArea(); - if (r.isEmpty()) { - return; - } - - int width = r.width; - if (fNameWidth > width - fMinNameWidth) { - fNameWidth = width - fMinNameWidth; - } - if (fNameWidth < fMinNameWidth) { - fNameWidth = fMinNameWidth; - } - adjustVerticalScrollBar(); - } - - /** - * Try to set most convenient time range for display. - * - * @param traces - * The traces in the model - */ - public void setTimeRange(ITimeGraphEntry traces[]) { - fEndTime = 0; - fBeginTime = -1; - for (int i = 0; i < traces.length; i++) { - ITimeGraphEntry entry = traces[i]; - if (entry.getEndTime() >= entry.getStartTime() && entry.getEndTime() > 0) { - if (fBeginTime < 0 || entry.getStartTime() < fBeginTime) { - fBeginTime = entry.getStartTime(); - } - if (entry.getEndTime() > fEndTime) { - fEndTime = entry.getEndTime(); - } - } - } - - if (fBeginTime < 0) { - fBeginTime = 0; - } - } - - /** - * Recalculate the time bounds - */ - public void setTimeBounds() { - fTime0Bound = fBeginTime; - if (fTime0Bound < 0) { - fTime0Bound = 0; - } - fTime1Bound = fEndTime; - if (!fTimeRangeFixed) { - fTime0 = fTime0Bound; - fTime1 = fTime1Bound; - } - fTime0 = Math.max(fTime0Bound, Math.min(fTime0, fTime1Bound)); - fTime1 = Math.max(fTime0Bound, Math.min(fTime1, fTime1Bound)); - if (fTime1 - fTime0 < fMinTimeInterval) { - fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval); - } - } - - /** - * @param traces - * @param start - * @param end - */ - void updateInternalData(ITimeGraphEntry[] traces, long start, long end) { - ITimeGraphEntry[] realTraces = traces; - - if (null == realTraces) { - realTraces = new ITimeGraphEntry[0]; - } - if ((start == 0 && end == 0) || start < 0 || end < 0) { - // Start and end time are unspecified and need to be determined from - // individual processes - setTimeRange(realTraces); - } else { - fBeginTime = start; - fEndTime = end; - } - - refreshAllData(realTraces); - } - - /** - * @param traces - */ - private void refreshAllData(ITimeGraphEntry[] traces) { - setTimeBounds(); - if (fSelectionBegin < fBeginTime) { - fSelectionBegin = fBeginTime; - } else if (fSelectionBegin > fEndTime) { - fSelectionBegin = fEndTime; - } - if (fSelectionEnd < fBeginTime) { - fSelectionEnd = fBeginTime; - } else if (fSelectionEnd > fEndTime) { - fSelectionEnd = fEndTime; - } - fTimeGraphCtrl.refreshData(traces); - fTimeScaleCtrl.redraw(); - adjustVerticalScrollBar(); - } - - /** - * Callback for when this view is focused - */ - public void setFocus() { - if (null != fTimeGraphCtrl) { - fTimeGraphCtrl.setFocus(); - } - } - - /** - * Get the current focus status of this view. - * - * @return If the view is currently focused, or not - */ - public boolean isInFocus() { - return fTimeGraphCtrl.isInFocus(); - } - - /** - * Get the view's current selection - * - * @return The entry that is selected - */ - public ITimeGraphEntry getSelection() { - return fTimeGraphCtrl.getSelectedTrace(); - } - - /** - * Get the index of the current selection - * - * @return The index - */ - public int getSelectionIndex() { - return fTimeGraphCtrl.getSelectedIndex(); - } - - @Override - public long getTime0() { - return fTime0; - } - - @Override - public long getTime1() { - return fTime1; - } - - @Override - public long getMinTimeInterval() { - return fMinTimeInterval; - } - - @Override - public int getNameSpace() { - return fNameWidth; - } - - @Override - public void setNameSpace(int width) { - fNameWidth = width; - int w = fTimeGraphCtrl.getClientArea().width; - if (fNameWidth > w - MIN_NAME_WIDTH) { - fNameWidth = w - MIN_NAME_WIDTH; - } - if (fNameWidth < MIN_NAME_WIDTH) { - fNameWidth = MIN_NAME_WIDTH; - } - fTimeGraphCtrl.adjustScrolls(); - fTimeGraphCtrl.redraw(); - fTimeScaleCtrl.redraw(); - } - - @Override - public int getTimeSpace() { - int w = fTimeGraphCtrl.getClientArea().width; - return w - fNameWidth; - } - - @Override - public long getBeginTime() { - return fBeginTime; - } - - @Override - public long getEndTime() { - return fEndTime; - } - - @Override - public long getMaxTime() { - return fTime1Bound; - } - - @Override - public long getMinTime() { - return fTime0Bound; - } - - /** - * @since 2.1 - */ - @Override - public long getSelectionBegin() { - return fSelectionBegin; - } - - /** - * @since 2.1 - */ - @Override - public long getSelectionEnd() { - return fSelectionEnd; - } - - @Override - public void setStartFinishTimeNotify(long time0, long time1) { - setStartFinishTime(time0, time1); - notifyRangeListeners(fTime0, fTime1); - } - - @Override - public void notifyStartFinishTime() { - notifyRangeListeners(fTime0, fTime1); - } - - @Override - public void setStartFinishTime(long time0, long time1) { - fTime0 = time0; - if (fTime0 < fTime0Bound) { - fTime0 = fTime0Bound; - } - if (fTime0 > fTime1Bound) { - fTime0 = fTime1Bound; - } - fTime1 = time1; - if (fTime1 < fTime0Bound) { - fTime1 = fTime0Bound; - } - if (fTime1 > fTime1Bound) { - fTime1 = fTime1Bound; - } - if (fTime1 - fTime0 < fMinTimeInterval) { - fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval); - } - fTimeRangeFixed = true; - fTimeGraphCtrl.adjustScrolls(); - fTimeGraphCtrl.redraw(); - fTimeScaleCtrl.redraw(); - } - - /** - * Set the time bounds to the provided values - * - * @param beginTime - * The start time of the window - * @param endTime - * The end time - */ - public void setTimeBounds(long beginTime, long endTime) { - if (endTime >= beginTime) { - fBeginTime = beginTime; - fEndTime = endTime; - fTime0Bound = beginTime; - fTime1Bound = endTime; - } else { - fBeginTime = 0; - fEndTime = 0; - fTime0Bound = 0; - fTime1Bound = 0; - } - fTimeGraphCtrl.adjustScrolls(); - } - - @Override - public void resetStartFinishTime() { - setStartFinishTime(fTime0Bound, fTime1Bound); - fTimeRangeFixed = false; - } - - @Override - public void setSelectedTimeNotify(long time, boolean ensureVisible) { - setSelectedTimeInt(time, ensureVisible, true); - } - - @Override - public void setSelectedTime(long time, boolean ensureVisible) { - setSelectedTimeInt(time, ensureVisible, false); - } - - /** - * @since 2.1 - */ - @Override - public void setSelectionRangeNotify(long beginTime, long endTime) { - boolean changed = (beginTime != fSelectionBegin || endTime != fSelectionEnd); - fSelectionBegin = Math.max(fTime0Bound, Math.min(fTime1Bound, beginTime)); - fSelectionEnd = Math.max(fTime0Bound, Math.min(fTime1Bound, endTime)); - fTimeGraphCtrl.redraw(); - fTimeScaleCtrl.redraw(); - if (changed) { - notifyTimeListeners(fSelectionBegin, fSelectionEnd); - } - } - - /** - * @since 2.1 - */ - @Override - public void setSelectionRange(long beginTime, long endTime) { - fSelectionBegin = Math.max(fTime0Bound, Math.min(fTime1Bound, beginTime)); - fSelectionEnd = Math.max(fTime0Bound, Math.min(fTime1Bound, endTime)); - fTimeGraphCtrl.redraw(); - fTimeScaleCtrl.redraw(); - } - - private void setSelectedTimeInt(long time, boolean ensureVisible, boolean doNotify) { - long time0 = fTime0; - long time1 = fTime1; - if (ensureVisible) { - long timeSpace = (fTime1 - fTime0) / RECENTERING_MARGIN_FACTOR; - long timeMid = (fTime1 - fTime0) / 2; - if (time < fTime0 + timeSpace) { - long dt = fTime0 - time + timeMid; - fTime0 -= dt; - fTime1 -= dt; - } else if (time > fTime1 - timeSpace) { - long dt = time - fTime1 + timeMid; - fTime0 += dt; - fTime1 += dt; - } - if (fTime0 < fTime0Bound) { - fTime1 = Math.min(fTime1Bound, fTime1 + (fTime0Bound - fTime0)); - fTime0 = fTime0Bound; - } else if (fTime1 > fTime1Bound) { - fTime0 = Math.max(fTime0Bound, fTime0 - (fTime1 - fTime1Bound)); - fTime1 = fTime1Bound; - } - } - if (fTime1 - fTime0 < fMinTimeInterval) { - fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval); - } - fTimeGraphCtrl.adjustScrolls(); - fTimeGraphCtrl.redraw(); - fTimeScaleCtrl.redraw(); - - boolean notifySelectedTime = (time != fSelectionBegin || time != fSelectionEnd); - fSelectionBegin = time; - fSelectionEnd = time; - - if (doNotify && ((time0 != fTime0) || (time1 != fTime1))) { - notifyRangeListeners(fTime0, fTime1); - } - - if (doNotify && notifySelectedTime) { - notifyTimeListeners(fSelectionBegin, fSelectionEnd); - } - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - if (fSelectedEntry != getSelection()) { - fSelectedEntry = getSelection(); - notifySelectionListeners(fSelectedEntry); - } - } - - @Override - public void widgetSelected(SelectionEvent e) { - if (fSelectedEntry != getSelection()) { - fSelectedEntry = getSelection(); - notifySelectionListeners(fSelectedEntry); - } - } - - /** - * Callback for when the next event is selected - */ - public void selectNextEvent() { - fTimeGraphCtrl.selectNextEvent(); - adjustVerticalScrollBar(); - } - - /** - * Callback for when the previous event is selected - */ - public void selectPrevEvent() { - fTimeGraphCtrl.selectPrevEvent(); - adjustVerticalScrollBar(); - } - - /** - * Callback for when the next item is selected - */ - public void selectNextItem() { - fTimeGraphCtrl.selectNextTrace(); - adjustVerticalScrollBar(); - } - - /** - * Callback for when the previous item is selected - */ - public void selectPrevItem() { - fTimeGraphCtrl.selectPrevTrace(); - adjustVerticalScrollBar(); - } - - /** - * Callback for the show legend action - */ - public void showLegend() { - if (fDataViewer == null || fDataViewer.isDisposed()) { - return; - } - - TimeGraphLegend.open(fDataViewer.getShell(), fTimeGraphProvider); - } - - /** - * Callback for the Zoom In action - */ - public void zoomIn() { - fTimeGraphCtrl.zoomIn(); - } - - /** - * Callback for the Zoom Out action - */ - public void zoomOut() { - fTimeGraphCtrl.zoomOut(); - } - - private String getPreferenceString(String string) { - return getViewTypeStr() + "." + string; //$NON-NLS-1$ - } - - /** - * Add a selection listener - * - * @param listener - * The listener to add - */ - public void addSelectionListener(ITimeGraphSelectionListener listener) { - fSelectionListeners.add(listener); - } - - /** - * Remove a selection listener - * - * @param listener - * The listener to remove - */ - public void removeSelectionListener(ITimeGraphSelectionListener listener) { - fSelectionListeners.remove(listener); - } - - private void notifySelectionListeners(ITimeGraphEntry selection) { - TimeGraphSelectionEvent event = new TimeGraphSelectionEvent(this, selection); - - for (ITimeGraphSelectionListener listener : fSelectionListeners) { - listener.selectionChanged(event); - } - } - - /** - * Add a time listener - * - * @param listener - * The listener to add - */ - public void addTimeListener(ITimeGraphTimeListener listener) { - fTimeListeners.add(listener); - } - - /** - * Remove a time listener - * - * @param listener - * The listener to remove - */ - public void removeTimeListener(ITimeGraphTimeListener listener) { - fTimeListeners.remove(listener); - } - - private void notifyTimeListeners(long startTime, long endTime) { - TimeGraphTimeEvent event = new TimeGraphTimeEvent(this, startTime, endTime); - - for (ITimeGraphTimeListener listener : fTimeListeners) { - listener.timeSelected(event); - } - } - - /** - * Add a range listener - * - * @param listener - * The listener to add - */ - public void addRangeListener(ITimeGraphRangeListener listener) { - fRangeListeners.add(listener); - } - - /** - * Remove a range listener - * - * @param listener - * The listener to remove - */ - public void removeRangeListener(ITimeGraphRangeListener listener) { - fRangeListeners.remove(listener); - } - - private void notifyRangeListeners(long startTime, long endTime) { - // Check if the time has actually changed from last notification - if (startTime != fTime0ExtSynch || endTime != fTime1ExtSynch) { - // Notify Time Scale Selection Listeners - TimeGraphRangeUpdateEvent event = new TimeGraphRangeUpdateEvent(this, startTime, endTime); - - for (ITimeGraphRangeListener listener : fRangeListeners) { - listener.timeRangeUpdated(event); - } - - // update external synch timers - updateExtSynchTimers(); - } - } - - /** - * Callback to set a selected event in the view - * - * @param event - * The event that was selected - * @param source - * The source of this selection event - */ - public void setSelectedEvent(ITimeEvent event, Object source) { - if (event == null || source == this) { - return; - } - fSelectedEntry = event.getEntry(); - fTimeGraphCtrl.selectItem(fSelectedEntry, false); - - setSelectedTimeInt(event.getTime(), true, true); - adjustVerticalScrollBar(); - } - - /** - * Set the seeked time of a trace - * - * @param trace - * The trace that was seeked - * @param time - * The target time - * @param source - * The source of this seek event - */ - public void setSelectedTraceTime(ITimeGraphEntry trace, long time, Object source) { - if (trace == null || source == this) { - return; - } - fSelectedEntry = trace; - fTimeGraphCtrl.selectItem(trace, false); - - setSelectedTimeInt(time, true, true); - } - - /** - * Callback for a trace selection - * - * @param trace - * The trace that was selected - */ - public void setSelection(ITimeGraphEntry trace) { - fSelectedEntry = trace; - fTimeGraphCtrl.selectItem(trace, false); - adjustVerticalScrollBar(); - } - - /** - * Callback for a time window selection - * - * @param time0 - * Start time of the range - * @param time1 - * End time of the range - * @param source - * Source of the event - */ - public void setSelectVisTimeWindow(long time0, long time1, Object source) { - if (source == this) { - return; - } - - setStartFinishTime(time0, time1); - - // update notification time values since we are now in synch with the - // external application - updateExtSynchTimers(); - } - - /** - * update the cache timers used to identify the need to send a time window - * update to external registered listeners - */ - private void updateExtSynchTimers() { - // last time notification cache - fTime0ExtSynch = fTime0; - fTime1ExtSynch = fTime1; - } - - /** - * @since 2.0 - */ - @Override - public TimeFormat getTimeFormat() { - return fTimeFormat; - } - - /** - * @param tf - * the {@link TimeFormat} used to display timestamps - * @since 2.0 - */ - public void setTimeFormat(TimeFormat tf) { - this.fTimeFormat = tf; - if (tf == TimeFormat.CYCLES) { - fTimeDataProvider = new TimeDataProviderCyclesConverter(this, fClockFrequency); - } else { - fTimeDataProvider = this; - } - fTimeScaleCtrl.setTimeProvider(fTimeDataProvider); - if (fToolTipHandler != null) { - fToolTipHandler.setTimeProvider(fTimeDataProvider); - } - } - - /** - * Sets the clock frequency. Used when the time format is set to CYCLES. - * - * @param clockFrequency - * the clock frequency in Hz - * @since 3.2 - */ - public void setClockFrequency(long clockFrequency) { - fClockFrequency = clockFrequency; - if (fTimeFormat == TimeFormat.CYCLES) { - fTimeDataProvider = new TimeDataProviderCyclesConverter(this, fClockFrequency); - fTimeScaleCtrl.setTimeProvider(fTimeDataProvider); - if (fToolTipHandler != null) { - fToolTipHandler.setTimeProvider(fTimeDataProvider); - } - } - } - - /** - * Retrieve the border width - * - * @return The width - */ - public int getBorderWidth() { - return fBorderWidth; - } - - /** - * Set the border width - * - * @param borderWidth - * The width - */ - public void setBorderWidth(int borderWidth) { - if (borderWidth > -1) { - this.fBorderWidth = borderWidth; - GridLayout gl = (GridLayout) fDataViewer.getLayout(); - gl.marginHeight = borderWidth; - } - } - - /** - * Retrieve the height of the header - * - * @return The height - */ - public int getHeaderHeight() { - return fTimeScaleHeight; - } - - /** - * Set the height of the header - * - * @param headerHeight - * The height to set - */ - public void setHeaderHeight(int headerHeight) { - if (headerHeight > -1) { - this.fTimeScaleHeight = headerHeight; - fTimeScaleCtrl.setHeight(headerHeight); - } - } - - /** - * Retrieve the height of an item row - * - * @return The height - */ - public int getItemHeight() { - if (fTimeGraphCtrl != null) { - return fTimeGraphCtrl.getItemHeight(); - } - return 0; - } - - /** - * Set the height of an item row - * - * @param rowHeight - * The height to set - */ - public void setItemHeight(int rowHeight) { - if (fTimeGraphCtrl != null) { - fTimeGraphCtrl.setItemHeight(rowHeight); - } - } - - /** - * Set the minimum item width - * - * @param width - * The min width - */ - public void setMinimumItemWidth(int width) { - if (fTimeGraphCtrl != null) { - fTimeGraphCtrl.setMinimumItemWidth(width); - } - } - - /** - * Set the width for the name column - * - * @param width - * The width - */ - public void setNameWidthPref(int width) { - fNameWidthPref = width; - if (width == 0) { - fMinNameWidth = 0; - fNameWidth = 0; - } - } - - /** - * Retrieve the configure width for the name column - * - * @param width - * Unused? - * @return The width - */ - public int getNameWidthPref(int width) { - return fNameWidthPref; - } - - /** - * Returns the primary control associated with this viewer. - * - * @return the SWT control which displays this viewer's content - */ - public Control getControl() { - return fDataViewer; - } - - /** - * Returns the time graph control associated with this viewer. - * - * @return the time graph control - * @since 2.0 - */ - public TimeGraphControl getTimeGraphControl() { - return fTimeGraphCtrl; - } - - /** - * Returns the time graph scale associated with this viewer. - * - * @return the time graph scale - * @since 2.0 - */ - public TimeGraphScale getTimeGraphScale() { - return fTimeScaleCtrl; - } - - /** - * Return the x coordinate corresponding to a time - * - * @param time - * the time - * @return the x coordinate corresponding to the time - * - * @since 2.0 - */ - public int getXForTime(long time) { - return fTimeGraphCtrl.getXForTime(time); - } - - /** - * Return the time corresponding to an x coordinate - * - * @param x - * the x coordinate - * @return the time corresponding to the x coordinate - * - * @since 2.0 - */ - public long getTimeAtX(int x) { - return fTimeGraphCtrl.getTimeAtX(x); - } - - /** - * Get the selection provider - * - * @return the selection provider - */ - public ISelectionProvider getSelectionProvider() { - return fTimeGraphCtrl; - } - - /** - * Wait for the cursor - * - * @param waitInd - * Wait indefinitely? - */ - public void waitCursor(boolean waitInd) { - fTimeGraphCtrl.waitCursor(waitInd); - } - - /** - * Get the horizontal scroll bar object - * - * @return The scroll bar - */ - public ScrollBar getHorizontalBar() { - return fTimeGraphCtrl.getHorizontalBar(); - } - - /** - * Get the vertical scroll bar object - * - * @return The scroll bar - */ - public Slider getVerticalBar() { - return fVerticalScrollBar; - } - - /** - * Set the given index as the top one - * - * @param index - * The index that will go to the top - */ - public void setTopIndex(int index) { - fTimeGraphCtrl.setTopIndex(index); - adjustVerticalScrollBar(); - } - - /** - * Retrieve the current top index - * - * @return The top index - */ - public int getTopIndex() { - return fTimeGraphCtrl.getTopIndex(); - } - - /** - * Sets the auto-expand level to be used when the input of the viewer is set - * using {@link #setInput(Object)}. The value 0 means that there is no - * auto-expand; 1 means that top-level elements are expanded, but not their - * children; 2 means that top-level elements are expanded, and their - * children, but not grand-children; and so on. - *

- * The value {@link #ALL_LEVELS} means that all subtrees should be expanded. - *

- * @param level - * non-negative level, or ALL_LEVELS to expand all - * levels of the tree - * @since 3.1 - */ - public void setAutoExpandLevel(int level) { - fTimeGraphCtrl.setAutoExpandLevel(level); - } - - /** - * Returns the auto-expand level. - * - * @return non-negative level, or ALL_LEVELS if all levels of - * the tree are expanded automatically - * @see #setAutoExpandLevel - * @since 3.1 - */ - public int getAutoExpandLevel() { - return fTimeGraphCtrl.getAutoExpandLevel(); - } - - /** - * Set the expanded state of an entry - * - * @param entry - * The entry to expand/collapse - * @param expanded - * True for expanded, false for collapsed - */ - public void setExpandedState(ITimeGraphEntry entry, boolean expanded) { - fTimeGraphCtrl.setExpandedState(entry, expanded); - adjustVerticalScrollBar(); - } - - /** - * Collapses all nodes of the viewer's tree, starting with the root. - * - * @since 2.0 - */ - public void collapseAll() { - fTimeGraphCtrl.collapseAll(); - adjustVerticalScrollBar(); - } - - /** - * Expands all nodes of the viewer's tree, starting with the root. - * - * @since 2.0 - */ - public void expandAll() { - fTimeGraphCtrl.expandAll(); - adjustVerticalScrollBar(); - } - - /** - * Get the number of sub-elements when expanded - * - * @return The element count - */ - public int getExpandedElementCount() { - return fTimeGraphCtrl.getExpandedElementCount(); - } - - /** - * Get the sub-elements - * - * @return The array of entries that are below this one - */ - public ITimeGraphEntry[] getExpandedElements() { - return fTimeGraphCtrl.getExpandedElements(); - } - - /** - * Add a tree listener - * - * @param listener - * The listener to add - */ - public void addTreeListener(ITimeGraphTreeListener listener) { - fTimeGraphCtrl.addTreeListener(listener); - } - - /** - * Remove a tree listener - * - * @param listener - * The listener to remove - */ - public void removeTreeListener(ITimeGraphTreeListener listener) { - fTimeGraphCtrl.removeTreeListener(listener); - } - - /** - * Get the reset scale action. - * - * @return The Action object - */ - public Action getResetScaleAction() { - if (fResetScaleAction == null) { - // resetScale - fResetScaleAction = new Action() { - @Override - public void run() { - resetStartFinishTime(); - notifyStartFinishTime(); - } - }; - fResetScaleAction.setText(Messages.TmfTimeGraphViewer_ResetScaleActionNameText); - fResetScaleAction.setToolTipText(Messages.TmfTimeGraphViewer_ResetScaleActionToolTipText); - fResetScaleAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_HOME_MENU)); - } - return fResetScaleAction; - } - - /** - * Get the show legend action. - * - * @return The Action object - */ - public Action getShowLegendAction() { - if (fShowLegendAction == null) { - // showLegend - fShowLegendAction = new Action() { - @Override - public void run() { - showLegend(); - } - }; - fShowLegendAction.setText(Messages.TmfTimeGraphViewer_LegendActionNameText); - fShowLegendAction.setToolTipText(Messages.TmfTimeGraphViewer_LegendActionToolTipText); - fShowLegendAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_LEGEND)); - } - - return fShowLegendAction; - } - - /** - * Get the the next event action. - * - * @return The action object - */ - public Action getNextEventAction() { - if (fNextEventAction == null) { - fNextEventAction = new Action() { - @Override - public void run() { - selectNextEvent(); - } - }; - - fNextEventAction.setText(Messages.TmfTimeGraphViewer_NextEventActionNameText); - fNextEventAction.setToolTipText(Messages.TmfTimeGraphViewer_NextEventActionToolTipText); - fNextEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_EVENT)); - } - - return fNextEventAction; - } - - /** - * Get the previous event action. - * - * @return The Action object - */ - public Action getPreviousEventAction() { - if (fPrevEventAction == null) { - fPrevEventAction = new Action() { - @Override - public void run() { - selectPrevEvent(); - } - }; - - fPrevEventAction.setText(Messages.TmfTimeGraphViewer_PreviousEventActionNameText); - fPrevEventAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousEventActionToolTipText); - fPrevEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_EVENT)); - } - - return fPrevEventAction; - } - - /** - * Get the next item action. - * - * @return The Action object - */ - public Action getNextItemAction() { - if (fNextItemAction == null) { - - fNextItemAction = new Action() { - @Override - public void run() { - selectNextItem(); - } - }; - fNextItemAction.setText(Messages.TmfTimeGraphViewer_NextItemActionNameText); - fNextItemAction.setToolTipText(Messages.TmfTimeGraphViewer_NextItemActionToolTipText); - fNextItemAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_ITEM)); - } - return fNextItemAction; - } - - /** - * Get the previous item action. - * - * @return The Action object - */ - public Action getPreviousItemAction() { - if (fPreviousItemAction == null) { - - fPreviousItemAction = new Action() { - @Override - public void run() { - selectPrevItem(); - } - }; - fPreviousItemAction.setText(Messages.TmfTimeGraphViewer_PreviousItemActionNameText); - fPreviousItemAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousItemActionToolTipText); - fPreviousItemAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_ITEM)); - } - return fPreviousItemAction; - } - - /** - * Get the zoom in action - * - * @return The Action object - */ - public Action getZoomInAction() { - if (fZoomInAction == null) { - fZoomInAction = new Action() { - @Override - public void run() { - zoomIn(); - } - }; - fZoomInAction.setText(Messages.TmfTimeGraphViewer_ZoomInActionNameText); - fZoomInAction.setToolTipText(Messages.TmfTimeGraphViewer_ZoomInActionToolTipText); - fZoomInAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ZOOM_IN_MENU)); - } - return fZoomInAction; - } - - /** - * Get the zoom out action - * - * @return The Action object - */ - public Action getZoomOutAction() { - if (fZoomOutAction == null) { - fZoomOutAction = new Action() { - @Override - public void run() { - zoomOut(); - } - }; - fZoomOutAction.setText(Messages.TmfTimeGraphViewer_ZoomOutActionNameText); - fZoomOutAction.setToolTipText(Messages.TmfTimeGraphViewer_ZoomOutActionToolTipText); - fZoomOutAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ZOOM_OUT_MENU)); - } - return fZoomOutAction; - } - - /** - * Get the hide arrows action - * - * @param dialogSettings - * The dialog settings section where the state should be stored, - * or null - * - * @return The Action object - * - * @since 2.1 - */ - public Action getHideArrowsAction(final IDialogSettings dialogSettings) { - if (fHideArrowsAction == null) { - fHideArrowsAction = new Action(Messages.TmfTimeGraphViewer_HideArrowsActionNameText, IAction.AS_CHECK_BOX) { - @Override - public void run() { - boolean hideArrows = fHideArrowsAction.isChecked(); - fTimeGraphCtrl.hideArrows(hideArrows); - refresh(); - if (dialogSettings != null) { - dialogSettings.put(HIDE_ARROWS_KEY, hideArrows); - } - if (fFollowArrowFwdAction != null) { - fFollowArrowFwdAction.setEnabled(!hideArrows); - } - if (fFollowArrowBwdAction != null) { - fFollowArrowBwdAction.setEnabled(!hideArrows); - } - } - }; - fHideArrowsAction.setToolTipText(Messages.TmfTimeGraphViewer_HideArrowsActionToolTipText); - fHideArrowsAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_HIDE_ARROWS)); - if (dialogSettings != null) { - boolean hideArrows = dialogSettings.getBoolean(HIDE_ARROWS_KEY); - fTimeGraphCtrl.hideArrows(hideArrows); - fHideArrowsAction.setChecked(hideArrows); - if (fFollowArrowFwdAction != null) { - fFollowArrowFwdAction.setEnabled(!hideArrows); - } - if (fFollowArrowBwdAction != null) { - fFollowArrowBwdAction.setEnabled(!hideArrows); - } - } - } - return fHideArrowsAction; - } - - /** - * Get the follow arrow forward action. - * - * @return The Action object - * - * @since 2.1 - */ - public Action getFollowArrowFwdAction() { - if (fFollowArrowFwdAction == null) { - fFollowArrowFwdAction = new Action() { - @Override - public void run() { - fTimeGraphCtrl.followArrowFwd(); - adjustVerticalScrollBar(); - } - }; - fFollowArrowFwdAction.setText(Messages.TmfTimeGraphViewer_FollowArrowForwardActionNameText); - fFollowArrowFwdAction.setToolTipText(Messages.TmfTimeGraphViewer_FollowArrowForwardActionToolTipText); - fFollowArrowFwdAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FOLLOW_ARROW_FORWARD)); - if (fHideArrowsAction != null) { - fFollowArrowFwdAction.setEnabled(!fHideArrowsAction.isChecked()); - } - } - return fFollowArrowFwdAction; - } - - /** - * Get the follow arrow backward action. - * - * @return The Action object - * - * @since 2.1 - */ - public Action getFollowArrowBwdAction() { - if (fFollowArrowBwdAction == null) { - fFollowArrowBwdAction = new Action() { - @Override - public void run() { - fTimeGraphCtrl.followArrowBwd(); - adjustVerticalScrollBar(); - } - }; - fFollowArrowBwdAction.setText(Messages.TmfTimeGraphViewer_FollowArrowBackwardActionNameText); - fFollowArrowBwdAction.setToolTipText(Messages.TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText); - fFollowArrowBwdAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FOLLOW_ARROW_BACKWARD)); - if (fHideArrowsAction != null) { - fFollowArrowBwdAction.setEnabled(!fHideArrowsAction.isChecked()); - } - } - return fFollowArrowBwdAction; - } - - private void adjustVerticalScrollBar() { - int topIndex = fTimeGraphCtrl.getTopIndex(); - int countPerPage = fTimeGraphCtrl.countPerPage(); - int expandedElementCount = fTimeGraphCtrl.getExpandedElementCount(); - if (topIndex + countPerPage > expandedElementCount) { - fTimeGraphCtrl.setTopIndex(Math.max(0, expandedElementCount - countPerPage)); - } - - int selection = fTimeGraphCtrl.getTopIndex(); - int min = 0; - int max = Math.max(1, expandedElementCount - 1); - int thumb = Math.min(max, Math.max(1, countPerPage - 1)); - int increment = 1; - int pageIncrement = Math.max(1, countPerPage); - fVerticalScrollBar.setValues(selection, min, max, thumb, increment, pageIncrement); - } - - /** - * @param listener - * a {@link MenuDetectListener} - * @see org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener) - * @since 1.2 - */ - public void addTimeGraphEntryMenuListener(MenuDetectListener listener) { - fTimeGraphCtrl.addTimeGraphEntryMenuListener(listener); - } - - /** - * @param listener - * a {@link MenuDetectListener} - * @see org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener) - * @since 1.2 - */ - public void removeTimeGraphEntryMenuListener(MenuDetectListener listener) { - fTimeGraphCtrl.removeTimeGraphEntryMenuListener(listener); - } - - /** - * @param listener - * a {@link MenuDetectListener} - * @see org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener) - * @since 1.2 - */ - public void addTimeEventMenuListener(MenuDetectListener listener) { - fTimeGraphCtrl.addTimeEventMenuListener(listener); - } - - /** - * @param listener - * a {@link MenuDetectListener} - * @see org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener) - * @since 1.2 - */ - public void removeTimeEventMenuListener(MenuDetectListener listener) { - fTimeGraphCtrl.removeTimeEventMenuListener(listener); - } - - /** - * @param filter - * The filter object to be attached to the view - * @since 2.0 - */ - public void addFilter(ViewerFilter filter) { - fTimeGraphCtrl.addFilter(filter); - refresh(); - } - - /** - * @param filter - * The filter object to be attached to the view - * @since 2.0 - */ - public void removeFilter(ViewerFilter filter) { - fTimeGraphCtrl.removeFilter(filter); - refresh(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/dialogs/FilteredCheckboxTree.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/dialogs/FilteredCheckboxTree.java deleted file mode 100644 index 415c46603c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/dialogs/FilteredCheckboxTree.java +++ /dev/null @@ -1,193 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Inria - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Generoso Pagano, Inria - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.dialogs; - -import java.util.HashSet; -import java.util.Set; - -import org.eclipse.core.runtime.jobs.IJobChangeEvent; -import org.eclipse.core.runtime.jobs.JobChangeAdapter; -import org.eclipse.jface.viewers.CheckStateChangedEvent; -import org.eclipse.jface.viewers.CheckboxTreeViewer; -import org.eclipse.jface.viewers.ICheckStateListener; -import org.eclipse.jface.viewers.ICheckable; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.dialogs.FilteredTree; -import org.eclipse.ui.dialogs.PatternFilter; -import org.eclipse.ui.progress.WorkbenchJob; - -/** - * A FilteredTree wrapping a CheckboxTreeViewer. - * - * This tree keeps the check state of the nodes in sync, regardless of the fact - * that a node is filtered or not. This way, even if an node is filtered (not - * visible), the caller can get and set the check state. - * - * Note that all the "uncheck" operations act only on what is not filtered and - * what is child of something not filtered (even if such a child is filtered). - * On the contrary, all the "check" operations act only on what is not filtered. - * - * @author "Generoso Pagano " - * @since 3.2 - */ -public class FilteredCheckboxTree extends FilteredTree implements ICheckable { - - /** - * Set containing only the tree items that are checked - */ - private Set fObjects = new HashSet<>(); - - /** - * Handle to the tree viewer - */ - private CheckboxTreeViewer fCheckboxTreeViewer; - - /** - * Create a new instance of the receiver. - * - * @param parent - * the parent Composite - * @param treeStyle - * the style bits for the Tree - * @param filter - * the filter to be used - * @param useNewLook - * true if the new FilteredTree look - * should be used - */ - public FilteredCheckboxTree(Composite parent, int treeStyle, PatternFilter filter, - boolean useNewLook) { - super(parent, treeStyle, filter, useNewLook); - } - - @Override - protected TreeViewer doCreateTreeViewer(Composite parentComposite, int style) { - fCheckboxTreeViewer = new CheckboxTreeViewer(parentComposite, style); - fCheckboxTreeViewer.addCheckStateListener(new ICheckStateListener() { - @Override - public void checkStateChanged(CheckStateChangedEvent event) { - if (event.getChecked()) { - fObjects.add(event.getElement()); - } else { - fObjects.remove(event.getElement()); - } - } - }); - return fCheckboxTreeViewer; - } - - @Override - protected WorkbenchJob doCreateRefreshJob() { - WorkbenchJob job = super.doCreateRefreshJob(); - job.addJobChangeListener(new JobChangeAdapter() { - @Override - public void done(IJobChangeEvent event) { - fCheckboxTreeViewer.expandAll(); - fCheckboxTreeViewer.setCheckedElements(getCheckedElements()); - } - }); - return job; - } - - @Override - public boolean getChecked(Object element) { - return fObjects.contains(element); - } - - @Override - public boolean setChecked(Object element, boolean state) { - boolean checkable = fCheckboxTreeViewer.setChecked(element, state); - if (!state) { - fObjects.remove(element); - } else if (checkable) { - fObjects.add(element); - } - return checkable; - } - - @Override - public void addCheckStateListener(ICheckStateListener listener) { - fCheckboxTreeViewer.addCheckStateListener(listener); - } - - @Override - public void removeCheckStateListener(ICheckStateListener listener) { - fCheckboxTreeViewer.addCheckStateListener(listener); - } - - /** - * Returns all the checked elements of this tree, either visible or not. - * - * @return an array containing all the checked elements - */ - public Object[] getCheckedElements() { - return fObjects.toArray(); - } - - /** - * Checks all the passed elements and unchecks all the other. - * - * @param elements - * the elements to check - */ - public void setCheckedElements(Object[] elements) { - fObjects = new HashSet<>(); - for (Object element : elements) { - fObjects.add(element); - } - fCheckboxTreeViewer.setCheckedElements(elements); - } - - /** - * Sets the check state for the given element and its children in this - * viewer. The unchecked state is always set, while the checked state is set - * only on visible elements. - * - * @param element - * the element - * @param state - * the check state to set - * @return true if the check state could be set, and - * false otherwise - */ - public boolean setSubtreeChecked(Object element, boolean state) { - checkSubtree(element, state); - return fCheckboxTreeViewer.setSubtreeChecked(element, state); - } - - /** - * Recursively sets the check state on an element and its children, using - * the politic specified in {@link #setSubtreeChecked(Object, boolean)} - * documentation. - * - * @param element - * the element - * @param state - * the check state to set - */ - private void checkSubtree(Object element, boolean state) { - if (!state || (fCheckboxTreeViewer.testFindItem(element) != null)) { - if (state) { - fObjects.add(element); - } else { - fObjects.remove(element); - } - for (Object o : ((ITreeContentProvider) fCheckboxTreeViewer.getContentProvider()).getChildren(element)) { - checkSubtree(o, state); - } - } - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/dialogs/TimeGraphFilterDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/dialogs/TimeGraphFilterDialog.java deleted file mode 100644 index 76465cd071..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/dialogs/TimeGraphFilterDialog.java +++ /dev/null @@ -1,569 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2013 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - * Sebastian Davids - Fix for bug 19346 - Dialog font should be - * activated and used by other components. - * Lubomir Marinov - Fix for bug 182122 -[Dialogs] - * CheckedTreeSelectionDialog#createSelectionButtons(Composite) fails to - * align the selection buttons to the right - * François Rajotte - Support for multiple columns + selection control - * Patrick Tasse - Fix Sonar warnings - * Generoso Pagano - Add tree filter - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.dialogs; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.viewers.CheckStateChangedEvent; -import org.eclipse.jface.viewers.CheckboxTreeViewer; -import org.eclipse.jface.viewers.IBaseLabelProvider; -import org.eclipse.jface.viewers.ICheckStateListener; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.jface.viewers.ViewerComparator; -import org.eclipse.jface.viewers.ViewerFilter; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.BusyIndicator; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.TreeColumn; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.dialogs.ISelectionStatusValidator; -import org.eclipse.ui.dialogs.PatternFilter; -import org.eclipse.ui.dialogs.SelectionStatusDialog; - -/** - * Filter dialog for the time graphs This class is derived from the - * CheckedTreeSelectionDialog It was necessary to develop this similar dialog to - * allow multiple columns - * - * @version 1.0 - * @since 2.0 - * @author François Rajotte - */ -public class TimeGraphFilterDialog extends SelectionStatusDialog { - private static final int BUTTON_CHECK_SELECTED_ID = IDialogConstants.CLIENT_ID; - private static final int BUTTON_UNCHECK_SELECTED_ID = IDialogConstants.CLIENT_ID + 1; - private static final int BUTTON_CHECK_SUBTREE_ID = IDialogConstants.CLIENT_ID + 2; - private static final int BUTTON_UNCHECK_SUBTREE_ID = IDialogConstants.CLIENT_ID + 3; - - private static final int DEFAULT_WIDTH = 60; - private static final int DEFAULT_HEIGHT = 18; - - private FilteredCheckboxTree fTree; - - private IBaseLabelProvider fLabelProvider; - - private ITreeContentProvider fContentProvider; - - private String[] fColumnNames; - - private ISelectionStatusValidator fValidator = null; - - private ViewerComparator fComparator; - - private String fEmptyListMessage = ""; //$NON-NLS-1$ - - private IStatus fCurrStatus = new Status(IStatus.OK, PlatformUI.PLUGIN_ID, - 0, "", null); //$NON-NLS-1$ - - private List fFilters; - - private Object fInput; - - private boolean fIsEmpty; - - private int fWidth = DEFAULT_WIDTH; - - private int fHeight = DEFAULT_HEIGHT; - - private Object[] fExpandedElements; - - /** - * Constructs an instance of ElementTreeSelectionDialog. - * - * @param parent - * The shell to parent from. - */ - public TimeGraphFilterDialog(Shell parent) { - super(parent); - setResult(new ArrayList<>(0)); - setStatusLineAboveButtons(true); - setHelpAvailable(false); - fExpandedElements = null; - } - - /** - * Sets the initial selection. Convenience method. - * - * @param selection - * the initial selection. - */ - public void setInitialSelection(Object selection) { - setInitialSelections(new Object[] { selection }); - } - - /** - * Sets the message to be displayed if the list is empty. - * - * @param message - * the message to be displayed. - */ - public void setEmptyListMessage(String message) { - fEmptyListMessage = message; - } - - /** - * Sets the comparator used by the tree viewer. - * - * @param comparator - * The comparator - */ - public void setComparator(ViewerComparator comparator) { - fComparator = comparator; - } - - /** - * Adds a filter to the tree viewer. - * - * @param filter - * a filter. - */ - public void addFilter(ViewerFilter filter) { - if (fFilters == null) { - fFilters = new ArrayList<>(); - } - fFilters.add(filter); - } - - /** - * Sets an optional validator to check if the selection is valid. The - * validator is invoked whenever the selection changes. - * - * @param validator - * the validator to validate the selection. - */ - public void setValidator(ISelectionStatusValidator validator) { - fValidator = validator; - } - - /** - * Sets the tree input. - * - * @param input - * the tree input. - */ - public void setInput(Object input) { - fInput = input; - } - - /** - * Expands elements in the tree. - * - * @param elements - * The elements that will be expanded. - */ - public void setExpandedElements(Object[] elements) { - if (elements != null) { - fExpandedElements = Arrays.copyOf(elements, elements.length); - } else { - fExpandedElements = null; - } - } - - /** - * Sets the size of the tree in unit of characters. - * - * @param width - * the width of the tree. - * @param height - * the height of the tree. - */ - public void setSize(int width, int height) { - fWidth = width; - fHeight = height; - } - - /** - * @param contentProvider - * The content provider for the table - */ - public void setContentProvider(ITreeContentProvider contentProvider) { - fContentProvider = contentProvider; - } - - /** - * @param labelProvider - * The label provider for the table - */ - public void setLabelProvider(IBaseLabelProvider labelProvider) { - fLabelProvider = labelProvider; - } - - /** - * @param columnNames - * An array of column names to display - */ - public void setColumnNames(String[] columnNames) { - if (columnNames != null) { - fColumnNames = Arrays.copyOf(columnNames, columnNames.length); - } else { - fColumnNames = null; - } - } - - /** - * Validate the receiver and update the status with the result. - * - */ - protected void updateOKStatus() { - if (!fIsEmpty) { - if (fValidator != null) { - fCurrStatus = fValidator.validate(fTree.getCheckedElements()); - updateStatus(fCurrStatus); - } else if (!fCurrStatus.isOK()) { - fCurrStatus = new Status(IStatus.OK, PlatformUI.PLUGIN_ID, - IStatus.OK, "", //$NON-NLS-1$ - null); - } - } else { - fCurrStatus = new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, - IStatus.OK, fEmptyListMessage, null); - } - updateStatus(fCurrStatus); - } - - @Override - public int open() { - fIsEmpty = evaluateIfTreeEmpty(fInput); - super.open(); - return getReturnCode(); - } - - @Override - protected void cancelPressed() { - setResult(null); - super.cancelPressed(); - } - - @Override - protected void computeResult() { - setResult(Arrays.asList(fTree.getCheckedElements())); - } - - @Override - public void create() { - BusyIndicator.showWhile(null, new Runnable() { - @Override - public void run() { - TimeGraphFilterDialog.super.create(); - fTree.setCheckedElements(getInitialElementSelections() - .toArray()); - if (fExpandedElements != null) { - fTree.getViewer().setExpandedElements(fExpandedElements); - } - updateOKStatus(); - } - }); - } - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - Label messageLabel = createMessageArea(composite); - CheckboxTreeViewer treeViewer = createTreeViewer(composite); - Control buttonComposite = createSelectionButtons(composite); - GridData data = new GridData(GridData.FILL_BOTH); - data.widthHint = convertWidthInCharsToPixels(fWidth); - data.heightHint = convertHeightInCharsToPixels(fHeight); - Tree treeWidget = treeViewer.getTree(); - treeWidget.setLayoutData(data); - treeWidget.setFont(parent.getFont()); - if (fIsEmpty) { - messageLabel.setEnabled(false); - treeWidget.setEnabled(false); - buttonComposite.setEnabled(false); - } - return composite; - } - - /** - * Creates the tree viewer. - * - * @param parent - * the parent composite - * @return the tree viewer - */ - protected CheckboxTreeViewer createTreeViewer(Composite parent) { - PatternFilter filter = new TreePatternFilter(); - filter.setIncludeLeadingWildcard(true); - fTree = new FilteredCheckboxTree(parent, SWT.BORDER | SWT.MULTI, filter, true); - - Tree tree = fTree.getViewer().getTree(); - tree.setHeaderVisible(true); - for (String columnName : fColumnNames) { - TreeColumn column = new TreeColumn(tree, SWT.LEFT); - column.setText(columnName); - column.pack(); - } - - fTree.getViewer().setContentProvider(fContentProvider); - fTree.getViewer().setLabelProvider(fLabelProvider); - fTree.addCheckStateListener(new CheckStateListener()); - fTree.getViewer().setComparator(fComparator); - if (fFilters != null) { - for (int i = 0; i != fFilters.size(); i++) { - fTree.getViewer().addFilter(fFilters.get(i)); - } - } - fTree.getViewer().setInput(fInput); - - // pack the columns again for a nice view... - for (TreeColumn column : tree.getColumns()) { - column.pack(); - } - return (CheckboxTreeViewer) fTree.getViewer(); - } - - /** - * Returns the tree viewer. - * - * @return the tree viewer - */ - protected CheckboxTreeViewer getTreeViewer() { - return (CheckboxTreeViewer) fTree.getViewer(); - } - - /** - * Adds the selection and deselection buttons to the dialog. - * - * @param composite - * the parent composite - * @return Composite the composite the buttons were created in. - */ - protected Composite createSelectionButtons(Composite composite) { - Composite buttonComposite = new Composite(composite, SWT.RIGHT); - GridLayout layout = new GridLayout(); - layout.marginWidth = 0; - layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); - buttonComposite.setLayout(layout); - buttonComposite.setFont(composite.getFont()); - GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END - | GridData.GRAB_HORIZONTAL); - data.grabExcessHorizontalSpace = true; - buttonComposite.setLayoutData(data); - - /* Create the buttons in the good order to place them as we want */ - Button checkSelectedButton = createButton(buttonComposite, - BUTTON_CHECK_SELECTED_ID, Messages.TmfTimeFilterDialog_CHECK_SELECTED, - false); - Button checkSubtreeButton = createButton(buttonComposite, - BUTTON_CHECK_SUBTREE_ID, Messages.TmfTimeFilterDialog_CHECK_SUBTREE, - false); - Button checkAllButton = createButton(buttonComposite, - IDialogConstants.SELECT_ALL_ID, Messages.TmfTimeFilterDialog_CHECK_ALL, - false); - - Button uncheckSelectedButton = createButton(buttonComposite, - BUTTON_UNCHECK_SELECTED_ID, Messages.TmfTimeFilterDialog_UNCHECK_SELECTED, - false); - Button uncheckSubtreeButton = createButton(buttonComposite, - BUTTON_UNCHECK_SUBTREE_ID, Messages.TmfTimeFilterDialog_UNCHECK_SUBTREE, - false); - Button uncheckAllButton = createButton(buttonComposite, - IDialogConstants.DESELECT_ALL_ID, Messages.TmfTimeFilterDialog_UNCHECK_ALL, - false); - - /* - * Apply the layout again after creating the buttons to override - * createButton messing with the columns - */ - layout.numColumns = 3; - buttonComposite.setLayout(layout); - - /* Add a listener to each button */ - checkSelectedButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - TreeSelection selection = (TreeSelection) fTree.getViewer().getSelection(); - - for (Object element : selection.toArray()) { - checkElement(element); - } - - updateOKStatus(); - } - }); - - checkSubtreeButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - TreeSelection selection = (TreeSelection) fTree.getViewer().getSelection(); - - for (Object element : selection.toArray()) { - checkElementAndSubtree(element); - } - } - }); - - checkAllButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - Object[] viewerElements = fContentProvider.getElements(fInput); - - for (int i = 0; i < viewerElements.length; i++) { - fTree.setSubtreeChecked(viewerElements[i], true); - } - - updateOKStatus(); - } - }); - - uncheckSelectedButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - TreeSelection selection = (TreeSelection) fTree.getViewer().getSelection(); - - for (Object element : selection.toArray()) { - uncheckElement(element); - } - - updateOKStatus(); - } - }); - - uncheckSubtreeButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - TreeSelection selection = (TreeSelection) fTree.getViewer().getSelection(); - - for (Object element : selection.toArray()) { - uncheckElement(element); - } - - updateOKStatus(); - } - }); - - uncheckAllButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - Object[] viewerElements = fContentProvider.getElements(fInput); - for (Object element : viewerElements) { - if (fTree.getViewer().testFindItem(element) != null) { - // uncheck only visible roots and their children - uncheckElement(element); - } - } - updateOKStatus(); - } - }); - - return buttonComposite; - } - - /** - * Check an element and all its parents. - * - * @param element - * The element to check. - */ - private void checkElement(Object element) { - fTree.setChecked(element, true); - - Object parent = fContentProvider.getParent(element); - - if (parent != null && !fTree.getChecked(parent)) { - checkElement(parent); - } - } - - /** - * Check an element, all its parents and all its children. - * - * @param element - * The element to check. - */ - private void checkElementAndSubtree(Object element) { - checkElement(element); - - for (Object child : fContentProvider.getChildren(element)) { - checkElementAndSubtree(child); - } - } - - /** - * Uncheck an element and all its children. - * - * @param element - * The element to uncheck. - */ - private void uncheckElement(Object element) { - fTree.setChecked(element, false); - - for (Object child : fContentProvider.getChildren(element)) { - uncheckElement(child); - } - } - - private boolean evaluateIfTreeEmpty(Object input) { - Object[] elements = fContentProvider.getElements(input); - if (elements.length > 0 && fFilters != null) { - for (int i = 0; i < fFilters.size(); i++) { - ViewerFilter curr = fFilters.get(i); - elements = curr.filter(fTree.getViewer(), input, elements); - } - } - return elements.length == 0; - } - - /** - * Private classes - */ - - private class CheckStateListener implements ICheckStateListener { - - CheckStateListener() { - } - - @Override - public void checkStateChanged(CheckStateChangedEvent event) { - try { - ITimeGraphEntry entry = (ITimeGraphEntry) event.getElement(); - boolean checked = event.getChecked(); - if (checked) { - checkElement(entry); - } else { - uncheckElement(entry); - } - } catch (ClassCastException e) { - return; - } finally { - updateOKStatus(); - } - } - - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/dialogs/TimeGraphLegend.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/dialogs/TimeGraphLegend.java deleted file mode 100644 index 5e2b084e85..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/dialogs/TimeGraphLegend.java +++ /dev/null @@ -1,191 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson. - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alvaro Sanchez-Leon - Initial API and implementation - * Patrick Tasse - Refactoring - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.dialogs; - -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.TitleAreaDialog; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.StateItem; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; - -/** - * Legend for the colors used in the time graph view - * - * @version 1.0 - * @author Alvaro Sanchez-Leon - * @author Patrick Tasse - */ -public class TimeGraphLegend extends TitleAreaDialog { - - private final ITimeGraphPresentationProvider provider; - private final LocalResourceManager fResourceManager = new LocalResourceManager(JFaceResources.getResources()); - - /** - * Open the time graph legend window - * - * @param parent - * The parent shell - * @param provider - * The presentation provider - */ - public static void open(Shell parent, ITimeGraphPresentationProvider provider) { - (new TimeGraphLegend(parent, provider)).open(); - } - - /** - * Standard constructor - * - * @param parent - * The parent shell - * @param provider - * The presentation provider - */ - public TimeGraphLegend(Shell parent, ITimeGraphPresentationProvider provider) { - super(parent); - this.provider = provider; - this.setShellStyle(getShellStyle() | SWT.RESIZE); - } - - @Override - protected Control createDialogArea(Composite parent) { - Composite dlgArea = (Composite) super.createDialogArea(parent); - Composite composite = new Composite(dlgArea, SWT.NONE); - - GridLayout layout = new GridLayout(); - composite.setLayout(layout); - GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); - composite.setLayoutData(gd); - - createStatesGroup(composite); - - setTitle(Messages.TmfTimeLegend_LEGEND); - setDialogHelpAvailable(false); - setHelpAvailable(false); - - return composite; - } - - private void createStatesGroup(Composite composite) { - ScrolledComposite sc = new ScrolledComposite(composite, SWT.V_SCROLL|SWT.H_SCROLL); - sc.setExpandHorizontal(true); - sc.setExpandVertical(true); - Group gs = new Group(sc, SWT.H_SCROLL); - sc.setContent(gs); - GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); - sc.setLayoutData(gd); - - String stateTypeName = provider.getStateTypeName(); - StringBuffer buffer = new StringBuffer(); - if (!stateTypeName.isEmpty()) { - buffer.append(stateTypeName); - buffer.append(" "); //$NON-NLS-1$ - } - buffer.append(Messages.TmfTimeLegend_StateTypeName); - gs.setText(buffer.toString()); - - GridLayout layout = new GridLayout(); - layout.numColumns = 2; - layout.marginWidth = 20; - layout.marginBottom = 10; - gs.setLayout(layout); - - // Go through all the defined pairs of state color and state name and display them. - StateItem[] stateItems = provider.getStateTable(); - for (int i = 0; i < stateItems.length; i++) { - //Get the color related to the index - RGB rgb = stateItems[i].getStateColor(); - - //Get the given name, provided by the interface to the application - String stateName = stateItems[i].getStateString(); - - // draw color with name - Bar bar = new Bar(gs, rgb); - gd = new GridData(); - gd.widthHint = 40; - gd.heightHint = 20; - gd.verticalIndent = 8; - bar.setLayoutData(gd); - Label name = new Label(gs, SWT.NONE); - name.setText(stateName); - gd = new GridData(); - gd.horizontalIndent = 10; - gd.verticalIndent = 8; - name.setLayoutData(gd); - } - sc.setMinSize(gs.computeSize(SWT.DEFAULT, SWT.DEFAULT)); - } - - @Override - protected void configureShell(Shell shell) { - super.configureShell(shell); - shell.setText(Messages.TmfTimeLegend_TRACE_STATES_TITLE); - } - - @Override - protected void createButtonsForButtonBar(Composite parent) { - createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, - true); - } - - class Bar extends Canvas { - private final Color color; - - public Bar(Composite parent, RGB rgb) { - super(parent, SWT.NONE); - - color = fResourceManager.createColor(rgb); - addListener(SWT.Paint, new Listener() { - @Override - public void handleEvent(Event event) { - draw(event.gc); - } - }); - } - - private void draw(GC gc) { - Rectangle r = getClientArea(); - gc.setBackground(color); - gc.fillRectangle(r); - gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); - gc.drawRectangle(0, 0, r.width - 1, r.height - 1); - } - - @Override - public void dispose() { - super.dispose(); - color.dispose(); - } - - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/dialogs/TreePatternFilter.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/dialogs/TreePatternFilter.java deleted file mode 100644 index 85cae2a267..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/dialogs/TreePatternFilter.java +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Inria - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Generoso Pagano, Inria - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.dialogs; - -import org.eclipse.jface.viewers.AbstractTreeViewer; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.ui.dialogs.PatternFilter; - -/** - * A filter extending the org.eclipse.ui.dialogs.PatternFilter. - * - * It redefines the {@link #isElementVisible(Viewer, Object)}} method in order - * to have a match on a node if: the node matches or one of the children matches - * or one of the parents matches. - * - * @author "Generoso Pagano " - * @since 3.2 - */ -public class TreePatternFilter extends PatternFilter { - - @Override - public boolean isElementVisible(Viewer viewer, Object element) { - return super.isElementVisible(viewer, element) || isChildMatch(viewer, element); - } - - /** - * Check if at least one of the parents of this element is a match with the - * filter text. - * - * @param viewer - * the viewer that contains the element - * @param element - * the tree element to check - * @return true if the given element has a parent that matches the filter - * text - */ - private boolean isChildMatch(Viewer viewer, Object element) { - Object parent = ((ITreeContentProvider) ((AbstractTreeViewer) viewer).getContentProvider()) - .getParent(element); - while (parent != null) { - if (isLeafMatch(viewer, parent)) { - return true; - } - parent = ((ITreeContentProvider) ((AbstractTreeViewer) viewer).getContentProvider()) - .getParent(parent); - } - return false; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/EventIterator.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/EventIterator.java deleted file mode 100644 index 9b386f1176..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/EventIterator.java +++ /dev/null @@ -1,157 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model; - -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; - - -/** - * An iterator for time events. Events from the zoomed event list override any - * events from the underlying event list. - * @since 2.0 - */ -public class EventIterator implements Iterator { - - private final long fStartTime; - private final long fEndTime; - private List fEventList; - private List fZoomedEventList; - private long fZoomedStartTime; - private long fZoomedEndTime; - private int fIndex = 0; - private int fZoomedIndex= 0; - private ITimeEvent fNext = null; - private ITimeEvent fSplitNext = null; - private ITimeEvent fZoomedNext = null; - - /** - * Basic constructor, with start time and end times equal to the lowest and - * highest values possible, respectively. - * - * @param eventList - * The list on which this iterator will iterate - * @param zoomedEventList - * The "zoomed" list - */ - public EventIterator(List eventList, List zoomedEventList) { - this(eventList, zoomedEventList, Long.MIN_VALUE, Long.MAX_VALUE); - } - - /** - * Complete constructor, where we specify start and end times. - * - * @param eventList - * The list on which this iterator will iterate - * @param zoomedEventList - * The "zoomed" list - * @param startTime - * The start time - * @param endTime - * The end time - */ - public EventIterator(List eventList, - List zoomedEventList, long startTime, long endTime) { - fEventList = eventList; - fZoomedEventList = zoomedEventList; - if (zoomedEventList != null && zoomedEventList.size() > 0) { - fZoomedStartTime = zoomedEventList.get(0).getTime(); - ITimeEvent lastEvent = zoomedEventList.get(zoomedEventList.size() - 1); - fZoomedEndTime = lastEvent.getTime() + lastEvent.getDuration(); - } else { - fZoomedStartTime = Long.MAX_VALUE; - fZoomedEndTime = Long.MIN_VALUE; - } - fStartTime = startTime; - fEndTime = endTime; - } - - @Override - public boolean hasNext() { - if (fNext == null && fEventList != null) { - while (fIndex < fEventList.size()) { - ITimeEvent event = fEventList.get(fIndex++); - if (event.getTime() + event.getDuration() >= fStartTime && event.getTime() <= fEndTime && - (event.getTime() < fZoomedStartTime || event.getTime() + event.getDuration() > fZoomedEndTime)) { - // the event is visible and is not completely hidden by the zoomed events - fNext = event; - if (event.getTime() < fZoomedEndTime && event.getTime() + event.getDuration() > fZoomedStartTime) { - // the event is partially hidden by the zoomed events and must be split - fNext = null; - if (event.getTime() + event.getDuration() > fZoomedEndTime && fZoomedEndTime < fEndTime) { - // the end of the event is partially hidden by the zoomed events and is visible - if (event instanceof ITimeEvent2) { - fNext = ((ITimeEvent2) event).split(fZoomedEndTime).getSecond(); - } else { - fNext = new TimeEvent(event.getEntry(), fZoomedEndTime, event.getTime() + event.getDuration() - fZoomedEndTime); - } - } - if (event.getTime() < fZoomedStartTime && fZoomedStartTime > fStartTime) { - // the start of the event is partially hidden by the zoomed events and is visible - fSplitNext = fNext; - if (event instanceof ITimeEvent2) { - fNext = ((ITimeEvent2) event).split(fZoomedStartTime).getFirst(); - } else { - fNext = new TimeEvent(event.getEntry(), event.getTime(), fZoomedStartTime - event.getTime()); - } - } - } - if (fNext != null) { - break; - } - } - } - if (fNext == null) { - fEventList = null; - } - } - - if (fZoomedNext == null && fZoomedEventList != null) { - while (fZoomedIndex < fZoomedEventList.size()) { - ITimeEvent event = fZoomedEventList.get(fZoomedIndex++); - if (event.getTime() + event.getDuration() >= fStartTime && event.getTime() <= fEndTime) { - // the zoomed event is visible - fZoomedNext = event; - break; - } - } - if (fZoomedNext == null) { - fZoomedEventList = null; - } - } - - return fNext != null || fZoomedNext != null; - } - - @Override - public ITimeEvent next() { - if (hasNext()) { - if (fZoomedNext != null && (fNext == null || fZoomedNext.getTime() <= fNext.getTime())) { - ITimeEvent event = fZoomedNext; - fZoomedNext = null; - return event; - } - ITimeEvent event = fNext; - fNext = fSplitNext; - fSplitNext = null; - return event; - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ILinkEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ILinkEvent.java deleted file mode 100644 index cdb9461514..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ILinkEvent.java +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model; - -/** - * Interface for time event that allows to specify the destination entry of the - * event - * - * @since 2.1 - */ -public interface ILinkEvent extends ITimeEvent { - - /** - * Get this event's destination entry - * - * @return The destination entry - */ - ITimeGraphEntry getDestinationEntry(); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ITimeEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ITimeEvent.java deleted file mode 100644 index c78245cd56..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ITimeEvent.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alvaro Sanchez-Leon - Initial API and implementation - * Patrick Tasse - Refactoring - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model; - -/** - * Interface for time events, for use in the timegraph view - * - * @version 1.0 - * @author Alvaro Sanchez-Leon - * @author Patrick Tasse - */ -public interface ITimeEvent { - - /** - * Get the entry matching this time event. - * - * @return The time graph entry - */ - ITimeGraphEntry getEntry(); - - /** - * Get the timestamp of this event. - * - * @return The event's time - */ - long getTime(); - - /** - * @return - * - *
  • -1: Considers duration to be from current event till the next
  • - *
  • 0: Duration is not relevant e.g. a Burst / no state associated
  • - *
  • >0: Valid duration value specified
  • - *
    - *

    - */ - long getDuration(); - -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ITimeEvent2.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ITimeEvent2.java deleted file mode 100644 index 39b4aa3902..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ITimeEvent2.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model; - -import org.eclipse.linuxtools.tmf.core.util.Pair; - -/** - * Extend ITimeEvent interface - * - * @author Patrick Tasse - * @since 2.1 - */ -public interface ITimeEvent2 extends ITimeEvent { - - /** - * Split an event in two at the specified time. If the time is smaller or - * equal to the event's start, the first split event is null. If the time is - * greater or equal to the event's end, the second split event is null. - * - * @param time - * the time at which the event is to be split - * @return a pair of time events - */ - Pair split(long time); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ITimeGraphEntry.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ITimeGraphEntry.java deleted file mode 100644 index 579d1526b5..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ITimeGraphEntry.java +++ /dev/null @@ -1,102 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alvaro Sanchez-Leon - Initial API and implementation - * Patrick Tasse - Refactoring - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model; - -import java.util.Iterator; -import java.util.List; - -/** - * Interface for an entry (row) in the time graph view - * - * @version 1.0 - * @author Alvaro Sanchez-Leon - * @author Patrick Tasse - */ -public interface ITimeGraphEntry { - - /** - * Returns the parent of this entry, or null if it has none. - * - * @return the parent element, or null if it has none - */ - ITimeGraphEntry getParent(); - - /** - * Returns whether this entry has children. - * - * @return true if the given element has children, - * and false if it has no children - */ - boolean hasChildren(); - - /** - * Returns the child elements of this entry. - * - * @return an array of child elements - * @since 2.0 - */ - List getChildren(); - - /** - * Returns the name of this entry. - * - * @return the entry name - */ - String getName(); - - /** - * Returns the start time of this entry in nanoseconds. - * - * @return the start time - */ - long getStartTime(); - - /** - * Returns the end time of this entry in nanoseconds. - * - * @return the end time - */ - long getEndTime(); - - /** - * Returns whether this entry has time events. - * If true, the time events iterator should not be null. - * - * @return true if the entry has time events - * - * @see #getTimeEventsIterator - * @see #getTimeEventsIterator(long, long, long) - */ - boolean hasTimeEvents(); - - /** - * Get an iterator which returns all time events. - * - * @return the iterator - */ - Iterator getTimeEventsIterator(); - - /** - * Get an iterator which only returns events that fall within the start time and the stop time. - * The visible duration is the event duration below which further detail is not discernible. - * If no such iterator is implemented, provide a basic iterator which returns all events. - * - * @param startTime start time in nanoseconds - * @param stopTime stop time in nanoseconds - * @param visibleDuration duration of one pixel in nanoseconds - * - * @return the iterator - */ - Iterator getTimeEventsIterator(long startTime, long stopTime, long visibleDuration); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/NullTimeEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/NullTimeEvent.java deleted file mode 100644 index a4b7f4ed7b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/NullTimeEvent.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model; - -/** - * A null time event. Used to represent an event that should not be drawn, - * for example as a zoomed event that overshadows an underlying event. - * - * @since 2.0 - */ -public class NullTimeEvent extends TimeEvent { - - /** - * Standard constructor - * - * @param entry - * The entry matching this event - * @param time - * The timestamp of this event - * @param duration - * The duration of the event - */ - public NullTimeEvent(ITimeGraphEntry entry, long time, long duration) { - super(entry, time, duration); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeEvent.java deleted file mode 100644 index 7dc8ba571d..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeEvent.java +++ /dev/null @@ -1,138 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Geneviève Bastien - Added the fValue parameter to avoid subclassing - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model; - -import org.eclipse.linuxtools.tmf.core.util.Pair; - -/** - * Generic TimeEvent implementation - * - * @version 1.0 - * @author Patrick Tasse - */ -public class TimeEvent implements ITimeEvent2 { - - /** TimeGraphEntry matching this time event */ - protected ITimeGraphEntry fEntry; - - /** Beginning timestamp of this time event */ - protected long fTime; - - /** Duration of this time event */ - protected long fDuration; - - private final int fValue; - - /** - * Default value when no other value present - */ - private static final int NOVALUE = Integer.MIN_VALUE; - - /** - * Standard constructor - * - * @param entry - * The entry matching this event - * @param time - * The timestamp of this event - * @param duration - * The duration of the event - */ - public TimeEvent(ITimeGraphEntry entry, long time, long duration) { - this(entry, time, duration, NOVALUE); - - } - - /** - * Constructor - * - * @param entry - * The entry to which this time event is assigned - * @param time - * The timestamp of this event - * @param duration - * The duration of this event - * @param value - * The status assigned to the event - * @since 2.1 - */ - public TimeEvent(ITimeGraphEntry entry, long time, long duration, - int value) { - fEntry = entry; - fTime = time; - fDuration = duration; - fValue = value; - } - - /** - * Get this event's status - * - * @return The integer matching this status - * @since 2.1 - */ - public int getValue() { - return fValue; - } - - /** - * Return whether an event has a value - * - * @return true if the event has a value - * @since 2.1 - */ - public boolean hasValue() { - return (fValue != NOVALUE); - } - - @Override - public ITimeGraphEntry getEntry() { - return fEntry; - } - - @Override - public long getTime() { - return fTime; - } - - @Override - public long getDuration() { - return fDuration; - } - - /** - * Split an event in two at the specified time. If the time is smaller or - * equal to the event's start, the first split event is null. If the time is - * greater or equal to the event's end, the second split event is null. - *

    - * Subclasses should re-implement this method - * - * @since 2.1 - */ - @Override - public Pair split(long time) { - Pair pair = new Pair<>(); - if (time > fTime) { - pair.setFirst(new TimeEvent(fEntry, fTime, Math.min(fDuration, time - fTime), fValue)); - } - if (time < fTime + fDuration) { - pair.setSecond(new TimeEvent(fEntry, Math.max(fTime, time), fDuration - Math.max(0, time - fTime), fValue)); - } - return pair; - } - - @Override - public String toString() { - return getClass().getSimpleName() + " start=" + fTime + " end=" + (fTime + fDuration) + " duration=" + fDuration + (hasValue() ? (" value=" + fValue) : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java deleted file mode 100644 index 8518c577aa..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java +++ /dev/null @@ -1,304 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson, École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - * Geneviève Bastien - Move code to provide base classes for time graph view - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -/** - * An entry for use in the time graph views - * - * @since 2.1 - */ -public class TimeGraphEntry implements ITimeGraphEntry { - - /** Entry's parent */ - private ITimeGraphEntry fParent = null; - - /** List of child entries */ - private final List fChildren = new CopyOnWriteArrayList<>(); - - /** Name of this entry (text to show) */ - private String fName; - private long fStartTime = -1; - private long fEndTime = -1; - private List fEventList = new ArrayList<>(); - private List fZoomedEventList = new ArrayList<>(); - private Comparator fComparator; - - /** - * Constructor - * - * @param name - * The name of this entry - * @param startTime - * The start time of this entry - * @param endTime - * The end time of this entry - */ - public TimeGraphEntry(String name, long startTime, long endTime) { - fName = name; - fStartTime = startTime; - fEndTime = endTime; - } - - // --------------------------------------------- - // Getters and setters - // --------------------------------------------- - - @Override - public ITimeGraphEntry getParent() { - return fParent; - } - - /** - * Sets the entry's parent - * - * @param entry The new parent entry - */ - /* - * TODO: This method can be removed in the next major API version. - */ - protected void setParent(TimeGraphEntry entry) { - fParent = entry; - } - - /** - * Sets the entry's parent - * - * @param entry The new parent entry - * @since 3.1 - */ - /* - * TODO: This method should be added to the interface in the next major API version. - */ - protected void setParent(ITimeGraphEntry entry) { - fParent = entry; - } - - @Override - public synchronized boolean hasChildren() { - return fChildren.size() > 0; - } - - @Override - public synchronized List getChildren() { - return fChildren; - } - - @Override - public String getName() { - return fName; - } - - /** - * Update the entry name - * - * @param name - * the updated entry name - */ - public void setName(String name) { - fName = name; - } - - @Override - public long getStartTime() { - return fStartTime; - } - - @Override - public long getEndTime() { - return fEndTime; - } - - /** - * Updates the end time - * - * @param endTime - * the end time - * - * @since 3.0 - */ - public void updateEndTime(long endTime) { - fEndTime = Math.max(endTime, fEndTime); - } - - @Override - public boolean hasTimeEvents() { - return true; - } - - @Override - public Iterator getTimeEventsIterator() { - if (hasTimeEvents()) { - return new EventIterator(fEventList, fZoomedEventList); - } - return null; - } - - @Override - public Iterator getTimeEventsIterator(long startTime, long stopTime, long visibleDuration) { - if (!hasTimeEvents()) { - return null; - } - return new EventIterator(fEventList, fZoomedEventList, startTime, stopTime); - } - - /** - * Add an event to this entry's event list. If necessary, update the start - * and end time of the entry. If the event list's last event starts at the - * same time as the event to add, it is replaced by the new event. - * - * @param event - * The time event to add - */ - public void addEvent(ITimeEvent event) { - long start = event.getTime(); - long end = start + event.getDuration(); - synchronized (fEventList) { - int lastIndex = fEventList.size() - 1; - if (lastIndex >= 0 && fEventList.get(lastIndex).getTime() == event.getTime()) { - fEventList.set(lastIndex, event); - } else { - fEventList.add(event); - } - if (fStartTime == -1 || start < fStartTime) { - fStartTime = start; - } - if (fEndTime == -1 || end > fEndTime) { - fEndTime = end; - } - } - } - - /** - * Set the general event list of this entry. - * - * @param eventList - * The list of time events - */ - public void setEventList(List eventList) { - if (eventList != null) { - fEventList = new ArrayList<>(eventList); - } else { - fEventList = new ArrayList<>(); - } - } - - /** - * Set the zoomed event list of this entry. - * - * @param eventList - * The list of time events - */ - public void setZoomedEventList(List eventList) { - if (eventList != null) { - fZoomedEventList = new ArrayList<>(eventList); - } else { - fZoomedEventList = new ArrayList<>(); - } - } - - /** - * Add a child entry to this one - * - * @param child - * The child entry - */ - /* - * TODO: This method can be removed in the next major API version. - */ - public synchronized void addChild(TimeGraphEntry child) { - addChild((ITimeGraphEntry) child); - } - - /** - * Add a child entry to this one. If a comparator was previously set with - * {@link #sortChildren(Comparator)}, the entry will be inserted in its - * sort-order position. Otherwise it will be added to the end of the list. - * - * @param child - * The child entry - * @since 3.1 - */ - public synchronized void addChild(ITimeGraphEntry child) { - /* - * TODO: Use setParent() once it is added to the interface. - */ - if (child instanceof TimeGraphEntry) { - ((TimeGraphEntry) child).fParent = this; - } - if (fComparator == null) { - fChildren.add(child); - } else { - int i; - for (i = 0; i < fChildren.size(); i++) { - ITimeGraphEntry entry = fChildren.get(i); - if (fComparator.compare(child, entry) < 0) { - break; - } - } - fChildren.add(i, child); - } - } - - /** - * Add a child entry to this one at the specified position - * - * @param index - * Index at which the specified entry is to be inserted - * @param child - * The child entry - * @since 3.1 - */ - public synchronized void addChild(int index, ITimeGraphEntry child) { - /* - * TODO: Use setParent() once it is added to the interface. - */ - if (child instanceof TimeGraphEntry) { - ((TimeGraphEntry) child).fParent = this; - } - fChildren.add(index, child); - } - - /** - * Sort the children of this entry using the provided comparator. Subsequent - * calls to {@link #addChild(ITimeGraphEntry)} will use this comparator to - * maintain the sort order. - * - * @param comparator - * The entry comparator - * @since 3.1 - */ - public synchronized void sortChildren(Comparator comparator) { - fComparator = comparator; - if (comparator == null) { - return; - } - ITimeGraphEntry[] array = fChildren.toArray(new ITimeGraphEntry[0]); - Arrays.sort(array, comparator); - fChildren.clear(); - fChildren.addAll(Arrays.asList(array)); - } - - @Override - public String toString() { - return getClass().getSimpleName() + '(' + fName + ')'; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeLinkEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeLinkEvent.java deleted file mode 100644 index 0f2cb97bf9..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeLinkEvent.java +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model; - -/** - * TimeEvent implementation for events that do not involve only one entry, they - * have a source entry and destination entry - * - * @since 2.1 - */ -public class TimeLinkEvent extends TimeEvent implements ILinkEvent { - - /** TimeGraphEntry matching the destination this time event */ - private ITimeGraphEntry fDestEntry; - - /** - * Standard constructor - * - * @param src - * The source entry of this event - * @param dst - * The destination entry of this event - * @param time - * The timestamp of this event - * @param duration - * The duration of the event - */ - public TimeLinkEvent(ITimeGraphEntry src, ITimeGraphEntry dst, long time, long duration) { - super(src, time, duration); - fDestEntry = dst; - } - - /** - * Constructor - * - * @param src - * The source entry of this event - * @param dst - * The destination entry of this event - * @param time - * The timestamp of this event - * @param duration - * The duration of this event - * @param value - * The status assigned to the event - */ - public TimeLinkEvent(ITimeGraphEntry src, ITimeGraphEntry dst, long time, long duration, - int value) { - super(src, time, duration, value); - fDestEntry = dst; - } - - @Override - public ITimeGraphEntry getDestinationEntry() { - return fDestEntry; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/ITimeDataProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/ITimeDataProvider.java deleted file mode 100644 index 9921308367..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/ITimeDataProvider.java +++ /dev/null @@ -1,175 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2007, 2014 Intel Corporation, Ericsson - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Intel Corporation - Initial API and implementation - * Ruslan A. Scherbakov, Intel - Initial API and implementation - * Alvaro Sanchez-Leon - Updated for TMF - * Geneviève Bastien - Added methods to save a time range selection - * Patrick Tasse - Refactoring, support for range selection - *****************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets; - -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; - -/** - * Time data provider interface, for use in the timegraph widget. - * - * @version 1.0 - * @author Alvaro Sanchez-Leon - * @author Patrick Tasse - * @author Xavier Raynaud - */ -public interface ITimeDataProvider { - - /** - * Updates the selection begin and end time and notifies any registered - * listeners about the new time range (if necessary) - * - * @param beginTime the selection begin time - * @param endTime the selection end time - * @since 3.0 - */ - void setSelectionRangeNotify(long beginTime, long endTime); - - /** - * Updates the selection begin and end time - * - * @param beginTime the selection begin time - * @param endTime the selection end time - * @since 3.0 - */ - void setSelectionRange(long beginTime, long endTime); - - /** - * @return The begin time of the current selection - * @since 3.0 - */ - long getSelectionBegin(); - - /** - * @return The end time of the current selection - * @since 3.0 - */ - long getSelectionEnd(); - - /** - * @return The beginning time - */ - long getBeginTime(); - - /** - * @return The end time - */ - long getEndTime(); - - /** - * @return The minimum time - */ - long getMinTime(); - - /** - * @return The maximum time - */ - long getMaxTime(); - - /** - * @return The start time of the current selection window - */ - long getTime0(); - - /** - * @return The end time of the current selection window - */ - long getTime1(); - - /** - * @return The minimal time interval - */ - long getMinTimeInterval(); - - /** - * Updates the time range and notify registered listeners - * - * @param time0 - * @param time1 - */ - void setStartFinishTimeNotify(long time0, long time1); - - /** - * Update the time range but do not trigger event notification - * - * @param time0 - * @param time1 - */ - void setStartFinishTime(long time0, long time1); - - /** - * Notify registered listeners without updating the time range - */ - void notifyStartFinishTime(); - - /** - * Updates the selected time, adjusts the time range if necessary and - * notifies any registered listeners about the new selected time and new - * range (if necessary) - * - * @param time - * A Time to set - * @param ensureVisible - * Ensure visibility of new time (will adjust time range if - * necessary) - */ - void setSelectedTimeNotify(long time, boolean ensureVisible); - - /** - * Updates the selected time and adjusts the time range if necessary without - * notifying registered listeners. - * - * @param time - * A Time to set - * @param ensureVisible - * Ensure visibility of new time (will adjust time range if - * necessary) - */ - void setSelectedTime(long time, boolean ensureVisible); - - /** - * Reset the start and end times - */ - void resetStartFinishTime(); - - /** - * @return The names' width - */ - int getNameSpace(); - - /** - * Set the names' width - * - * @param width - */ - void setNameSpace(int width); - - /** - * @return The width for timestamps - */ - int getTimeSpace(); - - /** - * @return the time format, one of: - *

      - *
    • {@link TimeFormat#CALENDAR} absolute time, displayed as year/month/day/hours/minutes/seconds/ms/us/ns - *
    • {@link TimeFormat#RELATIVE} relative time, displayed as seconds/ms/us/ns - *
    • {@link TimeFormat#NUMBER} number, displayed as long values. - *
    - * @since 2.0 - */ - TimeFormat getTimeFormat(); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/ITimeDataProviderConverter.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/ITimeDataProviderConverter.java deleted file mode 100644 index 94ffa4fd5f..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/ITimeDataProviderConverter.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets; - -/** - * Time data provider that converts between time data units used internally and - * time in display units used by the caller. - * - * @since 3.2 - */ -public interface ITimeDataProviderConverter extends ITimeDataProvider { - - /** - * Convert a time in time data provider units to a time in display units. - * - * @param time the time in time data provider units - * - * @return the time in display units - */ - long convertTime(long time); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/ITmfTimeGraphDrawingHelper.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/ITmfTimeGraphDrawingHelper.java deleted file mode 100644 index 26dbd21089..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/ITmfTimeGraphDrawingHelper.java +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Geneviève Bastien - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets; - -/** - * This interface provides functions to convert a model element to a drawing - * element and vice versa. - * - * Views who implement this interface allow access to some model-to-canvas and - * vice-versa functions without having to expose their full functionnalities. - * - * @author gbastien - * @since 2.1 - */ -public interface ITmfTimeGraphDrawingHelper { - - /** - * Return the x coordinate corresponding to a time - * - * @param time - * the time - * @return the x coordinate corresponding to the time - */ - int getXForTime(long time); - - /** - * Return the time corresponding to an x coordinate - * - * @param x - * the x coordinate - * @return the time corresponding to the x coordinate - */ - long getTimeAtX(int x); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeDataProviderCyclesConverter.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeDataProviderCyclesConverter.java deleted file mode 100644 index aa16610779..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeDataProviderCyclesConverter.java +++ /dev/null @@ -1,178 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Patrick Tasse - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; - -/** - * Time Data Provider wrapper that converts nanoseconds to cycles. - * - * The user of the wrapper uses cycles, the wrapped provider uses nanoseconds. - * @since 3.2 - * - */ -public class TimeDataProviderCyclesConverter implements ITimeDataProviderConverter { - - private static final long GIGAHERTZ = 1000000000L; - - private final @NonNull ITimeDataProvider fProvider; - private final long fFreq; - - /** - * Constructor - * - * @param provider - * the original time data provider - * @param clockFrequency - * the clock frequency in Hz - */ - public TimeDataProviderCyclesConverter(@NonNull ITimeDataProvider provider, long clockFrequency) { - fProvider = provider; - fFreq = clockFrequency; - } - - /** - * Convert nanoseconds to cycles - * - * @param nanos - * time in nanoseconds - * @return time in cycles - */ - public long toCycles(long nanos) { - return Math.round(nanos * ((double) fFreq / GIGAHERTZ)); - } - - /** - * Convert cycles to nanoseconds - * - * @param cycles - * time in cycles - * @return time in nanoseconds - */ - public long toNanos(long cycles) { - return Math.round(cycles * ((double) GIGAHERTZ / fFreq)); - } - - @Override - public long convertTime(long time) { - return toCycles(time); - } - - @Override - public void setSelectionRangeNotify(long beginTime, long endTime) { - fProvider.setSelectionRangeNotify(toNanos(beginTime), toNanos(endTime)); - } - - @Override - public void setSelectionRange(long beginTime, long endTime) { - fProvider.setSelectionRange(toNanos(beginTime), toNanos(endTime)); - } - - @Override - public long getSelectionBegin() { - return toCycles(fProvider.getSelectionBegin()); - } - - @Override - public long getSelectionEnd() { - return toCycles(fProvider.getSelectionEnd()); - } - - @Override - public long getBeginTime() { - return toCycles(fProvider.getBeginTime()); - } - - @Override - public long getEndTime() { - return toCycles(fProvider.getEndTime()); - } - - @Override - public long getMinTime() { - return toCycles(fProvider.getMinTime()); - } - - @Override - public long getMaxTime() { - return toCycles(fProvider.getMaxTime()); - } - - @Override - public long getTime0() { - return toCycles(fProvider.getTime0()); - } - - @Override - public long getTime1() { - return toCycles(fProvider.getTime1()); - } - - @Override - public long getMinTimeInterval() { - // do not convert: this is in integer units - return fProvider.getMinTimeInterval(); - } - - @Override - public void setStartFinishTimeNotify(long time0, long time1) { - fProvider.setStartFinishTimeNotify(toNanos(time0), toNanos(time1)); - } - - @Override - public void setStartFinishTime(long time0, long time1) { - fProvider.setStartFinishTime(toNanos(time0), toNanos(time1)); - } - - @Override - public void notifyStartFinishTime() { - fProvider.notifyStartFinishTime(); - } - - @Override - public void setSelectedTimeNotify(long time, boolean ensureVisible) { - fProvider.setSelectedTimeNotify(toNanos(time), ensureVisible); - } - - @Override - public void setSelectedTime(long time, boolean ensureVisible) { - fProvider.setSelectedTime(toNanos(time), ensureVisible); - } - - @Override - public void resetStartFinishTime() { - fProvider.resetStartFinishTime(); - } - - @Override - public int getNameSpace() { - return fProvider.getNameSpace(); - } - - @Override - public void setNameSpace(int width) { - fProvider.setNameSpace(width); - } - - @Override - public int getTimeSpace() { - return fProvider.getTimeSpace(); - } - - @Override - public TimeFormat getTimeFormat() { - return fProvider.getTimeFormat(); - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphBaseControl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphBaseControl.java deleted file mode 100644 index 9fd891838a..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphBaseControl.java +++ /dev/null @@ -1,115 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2007, 2013 Intel Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Intel Corporation - Initial API and implementation - * Ruslan A. Scherbakov, Intel - Initial API and implementation - * Alvaro Sanchez-Leon - Updated for TMF - * Patrick Tasse - Refactoring - *****************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Composite; - -/** - * Base control abstract class for the time graph widget - * - * @version 1.0 - * @author Alvaro Sanchez-Leon - * @author Patrick Tasse - */ -public abstract class TimeGraphBaseControl extends Canvas implements PaintListener { - - /** Default left margin size */ - public static final int MARGIN = 4; - - /** Default expanded size */ - public static final int EXPAND_SIZE = 9; // the [+] or [-] control size - - /** Default size of the right margin */ - public static final int RIGHT_MARGIN = 1; // 1 pixels less to make sure end time is visible - - /** Default size for small icons */ - public static final int SMALL_ICON_SIZE = 16; - - /** Color scheme */ - private TimeGraphColorScheme fColorScheme; - - /** Font size */ - private int fFontHeight = 0; - - /** - * Basic constructor. Uses a default style value - * - * @param parent - * The parent composite object - * @param colors - * The color scheme to use - */ - public TimeGraphBaseControl(Composite parent, TimeGraphColorScheme colors) { - this(parent, colors, SWT.NO_BACKGROUND | SWT.NO_FOCUS); - } - - /** - * Standard constructor - * - * @param parent - * The parent composite object - * @param colorScheme - * The color scheme to use - * @param style - * The index of the style to use - */ - public TimeGraphBaseControl(Composite parent, TimeGraphColorScheme colorScheme, int style) { - super(parent, style); - fColorScheme = colorScheme; - addPaintListener(this); - } - - @Override - public void paintControl(PaintEvent e) { - if (e.widget != this) { - return; - } - fFontHeight = e.gc.getFontMetrics().getHeight(); - Rectangle bound = getClientArea(); - if (!bound.isEmpty()) { - Color colBackup = e.gc.getBackground(); - paint(bound, e); - e.gc.setBackground(colBackup); - } - } - - /** - * Retrieve the color scheme - * - * @return The color scheme - * - * @since 2.0 - */ - public TimeGraphColorScheme getColorScheme() { - return fColorScheme; - } - - /** - * Retrieve the current font's height - * - * @return The height - */ - public int getFontHeight() { - return fFontHeight; - } - - abstract void paint(Rectangle bound, PaintEvent e); -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphColorScheme.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphColorScheme.java deleted file mode 100644 index b040dba5af..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphColorScheme.java +++ /dev/null @@ -1,428 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2008, 2013 Intel Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Intel Corporation - Initial API and implementation - * Ruslan A. Scherbakov, Intel - Initial API and implementation - * Alvaro Sanchez-Leon - Updated for TMF - * Patrick Tasse - Refactoring - *****************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; - -/** - * Color theme used by the timegraph view - * - * @version 1.0 - * @author Patrick Tasse - */ -@SuppressWarnings("javadoc") -public class TimeGraphColorScheme { - - // elements color indices - public static final int BLACK_STATE = 0; - public static final int GREEN_STATE = 1; - public static final int DARK_BLUE_STATE = 2; - public static final int ORANGE_STATE = 3; - public static final int GOLD_STATE = 4; - public static final int RED_STATE = 5; - public static final int GRAY_STATE = 6; - public static final int DARK_GREEN_STATE = 7; - public static final int DARK_YELLOW_STATE = 8; - public static final int MAGENTA3_STATE = 9; - public static final int PURPLE1_STATE = 10; - public static final int PINK1_STATE = 11; - public static final int AQUAMARINE_STATE = 12; - public static final int LIGHT_BLUE_STATE = 13; - public static final int CADET_BLUE_STATE = 14; - public static final int OLIVE_STATE = 15; - - public static final int STATES0 = 0; - public static final int STATES1 = 15; - - // selected state elements color indices - public static final int BLACK_STATE_SEL = 16; - public static final int GREEN_STATE_SEL = 17; - public static final int DARK_BLUE_STATE_SEL = 18; - public static final int ORANGE_STATE_SEL = 19; - public static final int GOLD_STATE_SEL = 20; - public static final int RED_STATE_SEL = 21; - public static final int GRAY_STATE_SEL = 22; - public static final int DARK_GREEN_STATE_SEL = 23; - public static final int DARK_YELLOW_STATE_SEL = 24; - public static final int MAGENTA3_STATE_SEL = 25; - public static final int PURPLE1_STATE_SEL = 26; - public static final int PINK1_STATE_SEL = 27; - public static final int AQUAMARINE_STATE_SEL = 28; - public static final int LIGHT_BLUE_STATE_SEL = 29; - public static final int CADET_BLUE_STATE_SEL = 30; - public static final int OLIVE_STATE_SEL = 31; - - public static final int STATES_SEL0 = 16; - public static final int STATES_SEL1 = 31; - - // colors indices for viewer controls - public static final int BACKGROUND = 32; - public static final int FOREGROUND = 33; - public static final int BACKGROUND_SEL = 34; - public static final int FOREGROUND_SEL = 35; - public static final int BACKGROUND_SEL_NOFOCUS = 36; - public static final int FOREGROUND_SEL_NOFOCUS = 37; - public static final int TOOL_BACKGROUND = 38; - public static final int TOOL_FOREGROUND = 39; - - // misc colors - public static final int FIX_COLOR = 40; - public static final int WHITE = 41; - public static final int GRAY = 42; - public static final int BLACK = 43; - public static final int DARK_GRAY = 44; - - // selected border color indices - public static final int BLACK_BORDER = 45; - public static final int GREEN_BORDER = 46; - public static final int DARK_BLUE_BORDER = 47; - public static final int ORANGE_BORDER = 48; - public static final int GOLD_BORDER = 49; - public static final int RED_BORDER = 50; - public static final int GRAY_BORDER = 51; - public static final int DARK_GREEN_BORDER1 = 52; - public static final int DARK_YELLOW_BORDER1 = 53; - public static final int MAGENTA3_BORDER1 = 54; - public static final int PURPLE1_BORDER1 = 55; - public static final int PINK1_BORDER1 = 56; - public static final int AQUAMARINE_BORDER1 = 57; - public static final int LIGHT_BLUE_BORDER1 = 58; - public static final int CADET_BLUE_STATE_BORDER = 59; - public static final int OLIVE_BORDER2 = 60; - - public static final int STATES_BORDER0 = 45; - public static final int STATES_BORDER1 = 60; - - public static final int MID_LINE = 61; - public static final int RED = 62; - public static final int GREEN = 63; - public static final int BLUE = 64; - public static final int YELLOW = 65; - public static final int CYAN = 66; - public static final int MAGENTA = 67; - - public static final int SELECTED_TIME = 68; - public static final int LEGEND_BACKGROUND = 69; - public static final int LEGEND_FOREGROUND = 70; - - // group items' colors - public static final int GR_BACKGROUND = 71; - public static final int GR_FOREGROUND = 72; - public static final int GR_BACKGROUND_SEL = 73; - public static final int GR_FOREGROUND_SEL = 74; - public static final int GR_BACKGROUND_SEL_NOFOCUS = 75; - public static final int GR_FOREGROUND_SEL_NOFOCUS = 76; - - public static final int LIGHT_LINE = 77; - public static final int BACKGROUND_NAME = 78; - public static final int BACKGROUND_NAME_SEL = 79; - public static final int BACKGROUND_NAME_SEL_NOFOCUS = 80; - - // Interraction's colors - public static final int TI_START_THREAD = BLACK; - public static final int TI_HANDOFF_LOCK = BLUE; - public static final int TI_NOTIFY_ALL = GREEN; - public static final int TI_NOTIFY = GREEN; - public static final int TI_NOTIFY_JOINED = DARK_GRAY; - public static final int TI_INTERRUPT = RED; - public static final int TI_WAIT_EXCEEDED = BLUE; - - interface IColorProvider { - Color get(); - } - - static class SysCol implements IColorProvider { - private int syscol; - - SysCol(int syscol) { - this.syscol = syscol; - } - - @Override - public Color get() { - return Utils.getSysColor(syscol); - } - } - - static class RGB implements IColorProvider { - private int r; - private int g; - private int b; - - RGB(int r, int g, int b) { - this.r = r; - this.g = g; - this.b = b; - } - - @Override - public Color get() { - return new Color(null, r, g, b); - } - } - - static class Mix implements IColorProvider { - private IColorProvider cp1; - private IColorProvider cp2; - private int w1; - private int w2; - - Mix(IColorProvider cp1, IColorProvider cp2, int w1, int w2) { - this.cp1 = cp1; - this.cp2 = cp2; - this.w1 = w1; - this.w2 = w2; - } - - Mix(IColorProvider cp1, IColorProvider cp2) { - this.cp1 = cp1; - this.cp2 = cp2; - this.w1 = 1; - this.w2 = 1; - } - - @Override - public Color get() { - Color col1 = cp1.get(); - Color col2 = cp2.get(); - return Utils.mixColors(col1, col2, w1, w2); - } - } - - private static final IColorProvider PROVIDERS_MAP[] = { - // - new RGB(100, 100, 100), // UNKNOWN - new RGB(174, 200, 124), // RUNNING - new Mix(new SysCol(SWT.COLOR_BLUE), new SysCol(SWT.COLOR_GRAY), 1, 3), // SLEEPING - new RGB(210, 150, 60), // WAITING - new RGB(242, 225, 168), // BLOCKED - new Mix(new SysCol(SWT.COLOR_RED), new SysCol(SWT.COLOR_GRAY), 1, 3), // DEADLOCK - new RGB(200, 200, 200), // STOPPED - new RGB(35, 107, 42), // STEEL BLUE - new RGB(205,205,0), // DARK YELLOW - new RGB(205, 0, 205), // MAGENTA - new RGB(171, 130, 255), // PURPLE - new RGB(255, 181, 197), // PINK - new RGB(112, 219, 147), // AQUAMARINE - new RGB(198, 226, 255), // SLATEGRAY - new RGB(95, 158, 160), // CADET BLUE - new RGB(107, 142, 35), // OLIVE - - - //TODO: Does not seem to be used, check during clean-up - new SysCol(SWT.COLOR_WHITE), // UNKNOWN_SEL - new SysCol(SWT.COLOR_GREEN), // RUNNING_SEL - new SysCol(SWT.COLOR_BLUE), // SLEEPING_SEL - new SysCol(SWT.COLOR_CYAN), // WAITING_SEL - new SysCol(SWT.COLOR_YELLOW), // BLOCKED_SEL - new SysCol(SWT.COLOR_RED), // DEADLOCK_SEL - new SysCol(SWT.COLOR_DARK_GRAY), // STOPPED_SEL - new SysCol(SWT.COLOR_WHITE), - new SysCol(SWT.COLOR_GREEN), - new SysCol(SWT.COLOR_BLUE), - new SysCol(SWT.COLOR_CYAN), - new SysCol(SWT.COLOR_YELLOW), - new SysCol(SWT.COLOR_RED), - new SysCol(SWT.COLOR_DARK_GRAY), - new SysCol(SWT.COLOR_WHITE), - new SysCol(SWT.COLOR_GREEN), - - - new SysCol(SWT.COLOR_LIST_BACKGROUND), // BACKGROUND - new SysCol(SWT.COLOR_LIST_FOREGROUND), // FOREGROUND - new RGB(232, 242, 254), // BACKGROUND_SEL - new SysCol(SWT.COLOR_LIST_FOREGROUND), // FOREGROUND_SEL - new SysCol(SWT.COLOR_WIDGET_BACKGROUND), // BACKGROUND_SEL_NOFOCUS - new SysCol(SWT.COLOR_WIDGET_FOREGROUND), // FOREGROUND_SEL_NOFOCUS - new SysCol(SWT.COLOR_WIDGET_BACKGROUND), // TOOL_BACKGROUND - new SysCol(SWT.COLOR_WIDGET_DARK_SHADOW), // TOOL_FOREGROUND - - new SysCol(SWT.COLOR_GRAY), // FIX_COLOR - new SysCol(SWT.COLOR_WHITE), // WHITE - new SysCol(SWT.COLOR_GRAY), // GRAY - new SysCol(SWT.COLOR_BLACK), // BLACK - new SysCol(SWT.COLOR_DARK_GRAY), // DARK_GRAY - - new SysCol(SWT.COLOR_DARK_GRAY), // BLACK_BORDER - new RGB(75, 115, 120), // GREEN_BORDER - new SysCol(SWT.COLOR_DARK_BLUE), // DARK_BLUE_BORDER - new RGB(242, 225, 168), // ORANGE_BORDER - new RGB(210, 150, 60), // GOLD_BORDER - new SysCol(SWT.COLOR_DARK_RED), // RED_BORDER - new SysCol(SWT.COLOR_BLACK), // GRAY_BORDER - new SysCol(SWT.COLOR_DARK_GRAY), // DARK_GREEN_BORDER - new RGB(75, 115, 120), // DARK_YELLOW_BORDER - new SysCol(SWT.COLOR_DARK_BLUE), // MAGENTA3_BORDER - new RGB(242, 225, 168), // PURPLE1_BORDER - new RGB(210, 150, 60), // PINK1_BORDER - new SysCol(SWT.COLOR_DARK_RED), // AQUAMARINE_BORDER - new SysCol(SWT.COLOR_BLACK), // LIGHT_BLUE_BORDER - new SysCol(SWT.COLOR_DARK_GRAY), // BLUE_BORDER - new RGB(75, 115, 120), // OLIVE_BORDER - - - new SysCol(SWT.COLOR_GRAY), // MID_LINE - new SysCol(SWT.COLOR_RED), // RED - new SysCol(SWT.COLOR_GREEN), // GREEN - new SysCol(SWT.COLOR_BLUE), // BLUE - new SysCol(SWT.COLOR_YELLOW), // YELLOW - new SysCol(SWT.COLOR_CYAN), // CYAN - new SysCol(SWT.COLOR_MAGENTA), // MAGENTA - - new SysCol(SWT.COLOR_BLUE), // SELECTED_TIME - new SysCol(SWT.COLOR_WIDGET_BACKGROUND), // LEGEND_BACKGROUND - new SysCol(SWT.COLOR_WIDGET_DARK_SHADOW), // LEGEND_FOREGROUND - - new Mix(new RGB(150, 200, 240), new SysCol(SWT.COLOR_LIST_BACKGROUND)), // GR_BACKGROUND - new RGB(0, 0, 50), // GR_FOREGROUND - new Mix(new RGB(150, 200, 240), new SysCol(SWT.COLOR_WHITE), 6, 1), // GR_BACKGROUND_SEL - new RGB(0, 0, 50), // GR_FOREGROUND_SEL - new Mix(new RGB(150, 200, 240), new SysCol(SWT.COLOR_WHITE), 6, 1), // GR_BACKGROUND_SEL_NOFOCUS - new RGB(0, 0, 50), // GR_FOREGROUND_SEL_NOFOCUS - - new Mix(new SysCol(SWT.COLOR_GRAY), new SysCol(SWT.COLOR_LIST_BACKGROUND), 1, 3), // LIGHT_LINE - - new Mix(new SysCol(SWT.COLOR_GRAY), new SysCol(SWT.COLOR_LIST_BACKGROUND), 1, 6), // BACKGROUND_NAME - new Mix(new SysCol(SWT.COLOR_GRAY), new RGB(232, 242, 254), 1, 6), // BACKGROUND_NAME_SEL - new Mix(new SysCol(SWT.COLOR_GRAY), new SysCol(SWT.COLOR_WIDGET_BACKGROUND), 1, 6), // BACKGROUND_NAME_SEL_NOFOCUS - }; - - private final Color fColors[]; - - /** - * Default constructor - */ - public TimeGraphColorScheme() { - fColors = new Color[PROVIDERS_MAP.length]; - } - - /** - * Dispose this color scheme - */ - public void dispose() { - for (int i = 0; i < fColors.length; i++) { - Utils.dispose(fColors[i]); - fColors[i] = null; - } - } - - /** - * Get the color matching the given index - * - * @param idx - * The index - * @return The matching color - */ - public Color getColor(int idx) { - if (null == fColors[idx]) { - if (idx >= STATES_SEL0 && idx <= STATES_SEL1) { - Color col1 = getColor(idx - STATES_SEL0); - Color col2 = getColor(BACKGROUND_SEL); - fColors[idx] = Utils.mixColors(col1, col2, 3, 1); - } else { - fColors[idx] = PROVIDERS_MAP[idx].get(); - } - } - return fColors[idx]; - } - - /** - * Get an entry's background color based on its status. - * - * @param selected - * If the entry is selected - * @param focused - * If the entry is focused - * @param name - * Get the color of the name column (false for other columns) - * @return The matching color - */ - public Color getBkColor(boolean selected, boolean focused, boolean name) { - if (name) { - if (selected && focused) { - return getColor(BACKGROUND_NAME_SEL); - } - if (selected) { - return getColor(BACKGROUND_NAME_SEL_NOFOCUS); - } - return getColor(BACKGROUND_NAME); - } - if (selected && focused) { - return getColor(BACKGROUND_SEL); - } - if (selected) { - return getColor(BACKGROUND_SEL_NOFOCUS); - } - return getColor(BACKGROUND); - } - - /** - * Get the correct foreground color - * - * @param selected - * Is the entry selected - * @param focused - * Is the entry focused - * @return The matching color - */ - public Color getFgColor(boolean selected, boolean focused) { - if (selected && focused) { - return getColor(FOREGROUND_SEL); - } - if (selected) { - return getColor(FOREGROUND_SEL_NOFOCUS); - } - return getColor(FOREGROUND); - } - - /** - * Get the correct background color group - * - * @param selected - * Is the entry selected - * @param focused - * Is the entry focused - * @return The matching color - */ - public Color getBkColorGroup(boolean selected, boolean focused) { - if (selected && focused) { - return getColor(GR_BACKGROUND_SEL); - } - if (selected) { - return getColor(GR_BACKGROUND_SEL_NOFOCUS); - } - return getColor(GR_BACKGROUND); - } - - /** - * Get the correct foreground color group - * - * @param selected - * Is the entry selected - * @param focused - * Is the entry focused - * @return The matching color - */ - public Color getFgColorGroup(boolean selected, boolean focused) { - if (selected && focused) { - return getColor(GR_FOREGROUND_SEL); - } - if (selected) { - return getColor(GR_FOREGROUND_SEL_NOFOCUS); - } - return getColor(GR_FOREGROUND); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java deleted file mode 100644 index 74aff55b58..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java +++ /dev/null @@ -1,2799 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2007, 2014 Intel Corporation and others - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Intel Corporation - Initial API and implementation - * Ruslan A. Scherbakov, Intel - Initial API and implementation - * Alvaro Sanchez-Leon, Ericsson - Updated for TMF - * Patrick Tasse, Ericsson - Refactoring - * Geneviève Bastien, École Polytechnique de Montréal - Move code to - * provide base classes for time graph view - * Add display of links between items - * Xavier Raynaud, Kalray - Code optimization - * Generoso Pagano, Inria - Support for drag selection listeners - *****************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.jface.action.IStatusLineManager; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.viewers.AbstractTreeViewer; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.ViewerFilter; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphColorListener; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider2; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphTimeListener; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphTreeListener; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.StateItem; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTreeExpansionEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.Resolution; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.ControlListener; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.MenuDetectEvent; -import org.eclipse.swt.events.MenuDetectListener; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.events.MouseTrackListener; -import org.eclipse.swt.events.MouseWheelListener; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.events.TraverseEvent; -import org.eclipse.swt.events.TraverseListener; -import org.eclipse.swt.events.TypedEvent; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.ScrollBar; - -/** - * Time graph control implementation - * - * @version 1.0 - * @author Alvaro Sanchez-Leon - * @author Patrick Tasse - */ -public class TimeGraphControl extends TimeGraphBaseControl - implements FocusListener, KeyListener, MouseMoveListener, MouseListener, MouseWheelListener, - ControlListener, SelectionListener, MouseTrackListener, TraverseListener, ISelectionProvider, - MenuDetectListener, ITmfTimeGraphDrawingHelper, ITimeGraphColorListener { - - /** Max scrollbar size */ - public static final int H_SCROLLBAR_MAX = Integer.MAX_VALUE - 1; - - /** Constant indicating that all levels of the time graph should be expanded - * @since 3.1 */ - public static final int ALL_LEVELS = AbstractTreeViewer.ALL_LEVELS; - - private static final int DRAG_NONE = 0; - private static final int DRAG_TRACE_ITEM = 1; - private static final int DRAG_SPLIT_LINE = 2; - private static final int DRAG_ZOOM = 3; - private static final int DRAG_SELECTION = 4; - - private static final int CUSTOM_ITEM_HEIGHT = -1; // get item height from provider - - private static final double ZOOM_FACTOR = 1.5; - private static final double ZOOM_IN_FACTOR = 0.8; - private static final double ZOOM_OUT_FACTOR = 1.25; - - private static final int SNAP_WIDTH = 2; - private static final int ARROW_HOVER_MAX_DIST = 5; - - private static final int NO_STATUS = -1; - - /** Resource manager */ - private LocalResourceManager fResourceManager = new LocalResourceManager(JFaceResources.getResources()); - - /** Color map for event types */ - private Color[] fEventColorMap = null; - - private ITimeDataProvider fTimeProvider; - private IStatusLineManager fStatusLineManager = null; - private TimeGraphScale fTimeGraphScale = null; - - private boolean fIsInFocus = false; - private boolean fMouseOverSplitLine = false; - private int fGlobalItemHeight = CUSTOM_ITEM_HEIGHT; - private int fMinimumItemWidth = 0; - private int fTopIndex = 0; - private int fDragState = DRAG_NONE; - private int fDragButton; - private int fDragX0 = 0; - private int fDragX = 0; - private long fDragTime0 = 0; // used to preserve accuracy of modified selection - private int fIdealNameSpace = 0; - private long fTime0bak; - private long fTime1bak; - private ITimeGraphPresentationProvider fTimeGraphProvider = null; - private ItemData fItemData = null; - private List fSelectionListeners; - private List fDragSelectionListeners; - private final List fSelectionChangedListeners = new ArrayList<>(); - private final List fTreeListeners = new ArrayList<>(); - private final List fTimeGraphEntryMenuListeners = new ArrayList<>(); - private final List fTimeEventMenuListeners = new ArrayList<>(); - private final Cursor fDragCursor = Display.getDefault().getSystemCursor(SWT.CURSOR_HAND); - private final Cursor fResizeCursor = Display.getDefault().getSystemCursor(SWT.CURSOR_IBEAM); - private final Cursor fWaitCursor = Display.getDefault().getSystemCursor(SWT.CURSOR_WAIT); - private final Cursor fZoomCursor = Display.getDefault().getSystemCursor(SWT.CURSOR_SIZEWE); - private final List fFilters = new ArrayList<>(); - private MenuDetectEvent fPendingMenuDetectEvent = null; - private boolean fHideArrows = false; - private int fAutoExpandLevel = ALL_LEVELS; - - private int fBorderWidth = 0; - private int fHeaderHeight = 0; - - private Listener fMouseScrollFilterListener; - - private MouseScrollNotifier fMouseScrollNotifier; - private final Object fMouseScrollNotifierLock = new Object(); - - private class MouseScrollNotifier extends Thread { - private static final long DELAY = 400L; - private static final long POLLING_INTERVAL = 10L; - private long fLastScrollTime = Long.MAX_VALUE; - - @Override - public void run() { - while ((System.currentTimeMillis() - fLastScrollTime) < DELAY) { - try { - Thread.sleep(POLLING_INTERVAL); - } catch (Exception e) { - return; - } - } - if (!isInterrupted()) { - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - if (isDisposed()) { - return; - } - fTimeProvider.notifyStartFinishTime(); - } - }); - } - synchronized (fMouseScrollNotifierLock) { - fMouseScrollNotifier = null; - } - } - - public void mouseScrolled() { - fLastScrollTime = System.currentTimeMillis(); - } - } - - /** - * Standard constructor - * - * @param parent - * The parent composite object - * @param colors - * The color scheme to use - */ - public TimeGraphControl(Composite parent, TimeGraphColorScheme colors) { - - super(parent, colors, SWT.NO_BACKGROUND | SWT.H_SCROLL | SWT.DOUBLE_BUFFERED); - - fItemData = new ItemData(); - - addFocusListener(this); - addMouseListener(this); - addMouseMoveListener(this); - addMouseTrackListener(this); - addMouseWheelListener(this); - addTraverseListener(this); - addKeyListener(this); - addControlListener(this); - addMenuDetectListener(this); - ScrollBar scrollHor = getHorizontalBar(); - - if (scrollHor != null) { - scrollHor.addSelectionListener(this); - } - } - - @Override - public void dispose() { - super.dispose(); - fResourceManager.dispose(); - } - - /** - * Sets the timegraph provider used by this timegraph viewer. - * - * @param timeGraphProvider the timegraph provider - */ - public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider) { - fTimeGraphProvider = timeGraphProvider; - - if (timeGraphProvider instanceof ITimeGraphPresentationProvider2) { - ((ITimeGraphPresentationProvider2) timeGraphProvider).setDrawingHelper(this); - ((ITimeGraphPresentationProvider2) timeGraphProvider).addColorListener(this); - } - - StateItem[] stateItems = fTimeGraphProvider.getStateTable(); - colorSettingsChanged(stateItems); - } - - /** - * Gets the timegraph provider used by this timegraph viewer. - * - * @return the timegraph provider, or null if not set. - * @since 3.0 - */ - public ITimeGraphPresentationProvider getTimeGraphProvider() { - return fTimeGraphProvider; - } - - /** - * Gets the color map used by this timegraph viewer. - * - * @return a color map, or null if not set. - * @since 3.0 - */ - public Color[] getEventColorMap() { - return fEventColorMap; - } - - /** - * Assign the given time provider - * - * @param timeProvider - * The time provider - */ - public void setTimeProvider(ITimeDataProvider timeProvider) { - fTimeProvider = timeProvider; - adjustScrolls(); - redraw(); - } - - /** - * Assign the status line manager - * - * @param statusLineManager - * The status line manager, or null to disable status line messages - * @since 2.1 - */ - public void setStatusLineManager(IStatusLineManager statusLineManager) { - if (fStatusLineManager != null && statusLineManager == null) { - fStatusLineManager.setMessage(""); //$NON-NLS-1$ - } - fStatusLineManager = statusLineManager; - } - - /** - * Assign the time graph scale - * - * @param timeGraphScale - * The time graph scale - * @since 2.1 - */ - public void setTimeGraphScale(TimeGraphScale timeGraphScale) { - fTimeGraphScale = timeGraphScale; - } - - /** - * Add a selection listener - * - * @param listener - * The listener to add - */ - public void addSelectionListener(SelectionListener listener) { - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (null == fSelectionListeners) { - fSelectionListeners = new ArrayList<>(); - } - fSelectionListeners.add(listener); - } - - /** - * Remove a selection listener - * - * @param listener - * The listener to remove - */ - public void removeSelectionListener(SelectionListener listener) { - if (null != fSelectionListeners) { - fSelectionListeners.remove(listener); - } - } - - /** - * Selection changed callback - */ - public void fireSelectionChanged() { - if (null != fSelectionListeners) { - Iterator it = fSelectionListeners.iterator(); - while (it.hasNext()) { - SelectionListener listener = it.next(); - listener.widgetSelected(null); - } - } - } - - /** - * Default selection callback - */ - public void fireDefaultSelection() { - if (null != fSelectionListeners) { - Iterator it = fSelectionListeners.iterator(); - while (it.hasNext()) { - SelectionListener listener = it.next(); - listener.widgetDefaultSelected(null); - } - } - } - - /** - * Add a drag selection listener - * - * @param listener - * The listener to add - * @since 3.1 - */ - public void addDragSelectionListener(ITimeGraphTimeListener listener) { - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (null == fDragSelectionListeners) { - fDragSelectionListeners = new ArrayList<>(); - } - fDragSelectionListeners.add(listener); - } - - /** - * Remove a drag selection listener - * - * @param listener - * The listener to remove - * @since 3.1 - */ - public void removeDragSelectionListener(ITimeGraphTimeListener listener) { - if (null != fDragSelectionListeners) { - fDragSelectionListeners.remove(listener); - } - } - - /** - * Drag Selection changed callback - * - * @param start - * Time interval start - * @param end - * Time interval end - * @since 3.1 - */ - public void fireDragSelectionChanged(long start, long end) { - // check for backward intervals - long beginTime, endTime; - if (start > end) { - beginTime = end; - endTime = start; - } else { - beginTime = start; - endTime = end; - } - // call the listeners - if (null != fDragSelectionListeners) { - Iterator it = fDragSelectionListeners.iterator(); - while (it.hasNext()) { - ITimeGraphTimeListener listener = it.next(); - listener.timeSelected(new TimeGraphTimeEvent(this, beginTime, endTime)); - } - } - } - - /** - * Get the traces in the model - * - * @return The array of traces - */ - public ITimeGraphEntry[] getTraces() { - return fItemData.getEntries(); - } - - /** - * Get the on/off trace filters - * - * @return The array of filters - */ - public boolean[] getTraceFilter() { - return fItemData.getEntryFilter(); - } - - /** - * Refresh the data for the thing - */ - public void refreshData() { - fItemData.refreshData(); - adjustScrolls(); - redraw(); - } - - /** - * Refresh data for the given traces - * - * @param traces - * The traces to refresh - */ - public void refreshData(ITimeGraphEntry[] traces) { - fItemData.refreshData(traces); - adjustScrolls(); - redraw(); - } - - /** - * Refresh the links (arrows) of this widget - * - * @param events The link events to refresh - * @since 2.1 - */ - public void refreshArrows(List events) { - fItemData.refreshArrows(events); - } - - /** - * Adjust the scoll bars - */ - public void adjustScrolls() { - if (null == fTimeProvider) { - getHorizontalBar().setValues(0, 1, 1, 1, 1, 1); - return; - } - - // HORIZONTAL BAR - // Visible window - long time0 = fTimeProvider.getTime0(); - long time1 = fTimeProvider.getTime1(); - // Time boundaries - long timeMin = fTimeProvider.getMinTime(); - long timeMax = fTimeProvider.getMaxTime(); - - long delta = timeMax - timeMin; - - int timePos = 0; - int thumb = H_SCROLLBAR_MAX; - - if (delta != 0) { - // Thumb size (page size) - thumb = Math.max(1, (int) (H_SCROLLBAR_MAX * ((double) (time1 - time0) / delta))); - // At the beginning of visible window - timePos = (int) (H_SCROLLBAR_MAX * ((double) (time0 - timeMin) / delta)); - } - - // position, minimum, maximum, thumb size, increment (half page)t, page - // increment size (full page) - getHorizontalBar().setValues(timePos, 0, H_SCROLLBAR_MAX, thumb, Math.max(1, thumb / 2), Math.max(2, thumb)); - } - - boolean ensureVisibleItem(int idx, boolean redraw) { - boolean changed = false; - int index = idx; - if (index < 0) { - for (index = 0; index < fItemData.fExpandedItems.length; index++) { - if (fItemData.fExpandedItems[index].fSelected) { - break; - } - } - } - if (index >= fItemData.fExpandedItems.length) { - return changed; - } - if (index < fTopIndex) { - setTopIndex(index); - if (redraw) { - redraw(); - } - changed = true; - } else { - int page = countPerPage(); - if (index >= fTopIndex + page) { - setTopIndex(index - page + 1); - if (redraw) { - redraw(); - } - changed = true; - } - } - return changed; - } - - /** - * Assign the given index as the top one - * - * @param idx - * The index - */ - public void setTopIndex(int idx) { - int index = Math.min(idx, fItemData.fExpandedItems.length - countPerPage()); - index = Math.max(0, index); - fTopIndex = index; - redraw(); - } - - /** - * Sets the auto-expand level to be used when the entries are refreshed - * using {@link #refreshData()} or {@link #refreshData(ITimeGraphEntry[])}. - * The value 0 means that there is no auto-expand; 1 means that top-level - * entries are expanded, but not their children; 2 means that top-level - * entries are expanded, and their children, but not grand-children; and so - * on. - *

    - * The value {@link #ALL_LEVELS} means that all subtrees should be expanded. - *

    - * @param level - * non-negative level, or ALL_LEVELS to expand all - * levels of the tree - * @since 3.1 - */ - public void setAutoExpandLevel(int level) { - fAutoExpandLevel = level; - } - - /** - * Returns the auto-expand level. - * - * @return non-negative level, or ALL_LEVELS if all levels of - * the tree are expanded automatically - * @see #setAutoExpandLevel - * @since 3.1 - */ - public int getAutoExpandLevel() { - return fAutoExpandLevel; - } - - /** - * Set the expanded state of a given entry - * - * @param entry - * The entry - * @param expanded - * True if expanded, false if collapsed - */ - public void setExpandedState(ITimeGraphEntry entry, boolean expanded) { - Item item = fItemData.findItem(entry); - if (item != null && item.fExpanded != expanded) { - item.fExpanded = expanded; - fItemData.updateExpandedItems(); - redraw(); - } - } - - /** - * Collapses all nodes of the viewer's tree, starting with the root. - * - * @since 2.0 - */ - public void collapseAll() { - for (Item item : fItemData.fItems) { - item.fExpanded = false; - } - fItemData.updateExpandedItems(); - redraw(); - } - - /** - * Expands all nodes of the viewer's tree, starting with the root. - * - * @since 2.0 - */ - public void expandAll() { - for (Item item : fItemData.fItems) { - item.fExpanded = true; - } - fItemData.updateExpandedItems(); - redraw(); - } - - /** - * Add a tree listener - * - * @param listener - * The listener to add - */ - public void addTreeListener(ITimeGraphTreeListener listener) { - if (!fTreeListeners.contains(listener)) { - fTreeListeners.add(listener); - } - } - - /** - * Remove a tree listener - * - * @param listener - * The listener to remove - */ - public void removeTreeListener(ITimeGraphTreeListener listener) { - if (fTreeListeners.contains(listener)) { - fTreeListeners.remove(listener); - } - } - - /** - * Tree event callback - * - * @param entry - * The affected entry - * @param expanded - * The expanded state (true for expanded, false for collapsed) - */ - public void fireTreeEvent(ITimeGraphEntry entry, boolean expanded) { - TimeGraphTreeExpansionEvent event = new TimeGraphTreeExpansionEvent(this, entry); - for (ITimeGraphTreeListener listener : fTreeListeners) { - if (expanded) { - listener.treeExpanded(event); - } else { - listener.treeCollapsed(event); - } - } - } - - /** - * Add a menu listener on {@link ITimeGraphEntry}s - * @param listener - * The listener to add - * @since 1.2 - */ - public void addTimeGraphEntryMenuListener(MenuDetectListener listener) { - if (!fTimeGraphEntryMenuListeners.contains(listener)) { - fTimeGraphEntryMenuListeners.add(listener); - } - } - - /** - * Remove a menu listener on {@link ITimeGraphEntry}s - * - * @param listener - * The listener to remove - * @since 1.2 - */ - public void removeTimeGraphEntryMenuListener(MenuDetectListener listener) { - if (fTimeGraphEntryMenuListeners.contains(listener)) { - fTimeGraphEntryMenuListeners.remove(listener); - } - } - - /** - * Menu event callback on {@link ITimeGraphEntry}s - * - * @param event - * The MenuDetectEvent, with field {@link TypedEvent#data} set to the selected {@link ITimeGraphEntry} - */ - private void fireMenuEventOnTimeGraphEntry(MenuDetectEvent event) { - for (MenuDetectListener listener : fTimeGraphEntryMenuListeners) { - listener.menuDetected(event); - } - } - - /** - * Add a menu listener on {@link ITimeEvent}s - * - * @param listener - * The listener to add - * @since 1.2 - */ - public void addTimeEventMenuListener(MenuDetectListener listener) { - if (!fTimeEventMenuListeners.contains(listener)) { - fTimeEventMenuListeners.add(listener); - } - } - - /** - * Remove a menu listener on {@link ITimeEvent}s - * - * @param listener - * The listener to remove - * @since 1.2 - */ - public void removeTimeEventMenuListener(MenuDetectListener listener) { - if (fTimeEventMenuListeners.contains(listener)) { - fTimeEventMenuListeners.remove(listener); - } - } - - /** - * Menu event callback on {@link ITimeEvent}s - * - * @param event - * The MenuDetectEvent, with field {@link TypedEvent#data} set to the selected {@link ITimeEvent} - */ - private void fireMenuEventOnTimeEvent(MenuDetectEvent event) { - for (MenuDetectListener listener : fTimeEventMenuListeners) { - listener.menuDetected(event); - } - } - - @Override - public ISelection getSelection() { - TimeGraphSelection sel = new TimeGraphSelection(); - ITimeGraphEntry trace = getSelectedTrace(); - if (null != trace && null != fTimeProvider) { - long selectedTime = fTimeProvider.getSelectionBegin(); - ITimeEvent event = Utils.findEvent(trace, selectedTime, 0); - if (event != null) { - sel.add(event); - } else { - sel.add(trace); - } - } - return sel; - } - - /** - * Get the selection object - * - * @return The selection - */ - public ISelection getSelectionTrace() { - TimeGraphSelection sel = new TimeGraphSelection(); - ITimeGraphEntry trace = getSelectedTrace(); - if (null != trace) { - sel.add(trace); - } - return sel; - } - - /** - * Enable/disable one of the traces in the model - * - * @param n - * 1 to enable it, -1 to disable. The method returns immediately - * if another value is used. - */ - public void selectTrace(int n) { - if ((n != 1) && (n != -1)) { - return; - } - - boolean changed = false; - int lastSelection = -1; - for (int i = 0; i < fItemData.fExpandedItems.length; i++) { - Item item = fItemData.fExpandedItems[i]; - if (item.fSelected) { - lastSelection = i; - if ((1 == n) && (i < fItemData.fExpandedItems.length - 1)) { - item.fSelected = false; - item = fItemData.fExpandedItems[i + 1]; - item.fSelected = true; - changed = true; - } else if ((-1 == n) && (i > 0)) { - item.fSelected = false; - item = fItemData.fExpandedItems[i - 1]; - item.fSelected = true; - changed = true; - } - break; - } - } - - if (lastSelection < 0 && fItemData.fExpandedItems.length > 0) { - Item item = fItemData.fExpandedItems[0]; - item.fSelected = true; - changed = true; - } - - if (changed) { - ensureVisibleItem(-1, false); - redraw(); - fireSelectionChanged(); - } - } - - /** - * Select an event - * - * @param n - * 1 for next event, -1 for previous event - */ - public void selectEvent(int n) { - if (null == fTimeProvider) { - return; - } - ITimeGraphEntry trace = getSelectedTrace(); - if (trace == null) { - return; - } - long selectedTime = fTimeProvider.getSelectionBegin(); - long endTime = fTimeProvider.getEndTime(); - ITimeEvent nextEvent; - if (-1 == n && selectedTime > endTime) { - nextEvent = Utils.findEvent(trace, selectedTime, 0); - } else { - nextEvent = Utils.findEvent(trace, selectedTime, n); - } - if (null == nextEvent && -1 == n) { - nextEvent = Utils.getFirstEvent(trace); - } - if (null != nextEvent) { - long nextTime = nextEvent.getTime(); - // If last event detected e.g. going back or not moving to a next - // event - if (nextTime <= selectedTime && n == 1) { - // Select to the end of this last event - nextTime = nextEvent.getTime() + nextEvent.getDuration(); - // but not beyond the end of the trace - if (nextTime > endTime) { - nextTime = endTime; - } - } else if (n == -1 && nextEvent.getTime() + nextEvent.getDuration() < selectedTime) { - // for previous event go to its end time unless we were already there - nextTime = nextEvent.getTime() + nextEvent.getDuration(); - } - fTimeProvider.setSelectedTimeNotify(nextTime, true); - fireSelectionChanged(); - } else if (1 == n) { - fTimeProvider.setSelectedTimeNotify(endTime, true); - fireSelectionChanged(); - } - } - - /** - * Select the next event - */ - public void selectNextEvent() { - selectEvent(1); - // Notify if visible time window has been adjusted - fTimeProvider.setStartFinishTimeNotify(fTimeProvider.getTime0(), fTimeProvider.getTime1()); - } - - /** - * Select the previous event - */ - public void selectPrevEvent() { - selectEvent(-1); - // Notify if visible time window has been adjusted - fTimeProvider.setStartFinishTimeNotify(fTimeProvider.getTime0(), fTimeProvider.getTime1()); - } - - /** - * Select the next trace - */ - public void selectNextTrace() { - selectTrace(1); - } - - /** - * Select the previous trace - */ - public void selectPrevTrace() { - selectTrace(-1); - } - - /** - * Zoom based on mouse cursor location with mouse scrolling - * - * @param zoomIn true to zoom in, false to zoom out - */ - public void zoom(boolean zoomIn) { - int globalX = getDisplay().getCursorLocation().x; - Point p = toControl(globalX, 0); - int nameSpace = fTimeProvider.getNameSpace(); - int timeSpace = fTimeProvider.getTimeSpace(); - int xPos = Math.max(nameSpace, Math.min(nameSpace + timeSpace, p.x)); - long time0 = fTimeProvider.getTime0(); - long time1 = fTimeProvider.getTime1(); - long interval = time1 - time0; - if (interval == 0) { - interval = 1; - } // to allow getting out of single point interval - long newInterval; - if (zoomIn) { - newInterval = Math.max(Math.round(interval * ZOOM_IN_FACTOR), fTimeProvider.getMinTimeInterval()); - } else { - newInterval = (long) Math.ceil(interval * ZOOM_OUT_FACTOR); - } - long center = time0 + Math.round(((double) (xPos - nameSpace) / timeSpace * interval)); - long newTime0 = center - Math.round((double) newInterval * (center - time0) / interval); - long newTime1 = newTime0 + newInterval; - fTimeProvider.setStartFinishTime(newTime0, newTime1); - synchronized (fMouseScrollNotifierLock) { - if (fMouseScrollNotifier == null) { - fMouseScrollNotifier = new MouseScrollNotifier(); - fMouseScrollNotifier.start(); - } - fMouseScrollNotifier.mouseScrolled(); - } - } - - /** - * zoom in using single click - */ - public void zoomIn() { - long prevTime0 = fTimeProvider.getTime0(); - long prevTime1 = fTimeProvider.getTime1(); - long prevRange = prevTime1 - prevTime0; - if (prevRange == 0) { - return; - } - ITimeDataProvider provider = fTimeProvider; - long selTime = (provider.getSelectionEnd() + provider.getSelectionBegin()) / 2; - if (selTime <= prevTime0 || selTime >= prevTime1) { - selTime = (prevTime0 + prevTime1) / 2; - } - long time0 = selTime - (long) ((selTime - prevTime0) / ZOOM_FACTOR); - long time1 = selTime + (long) ((prevTime1 - selTime) / ZOOM_FACTOR); - - long inaccuracy = (fTimeProvider.getMaxTime() - fTimeProvider.getMinTime()) - (time1 - time0); - - if (inaccuracy > 0 && inaccuracy < 100) { - fTimeProvider.setStartFinishTimeNotify(fTimeProvider.getMinTime(), fTimeProvider.getMaxTime()); - return; - } - - long min = fTimeProvider.getMinTimeInterval(); - if ((time1 - time0) < min) { - time0 = selTime - (selTime - prevTime0) * min / prevRange; - time1 = time0 + min; - } - - fTimeProvider.setStartFinishTimeNotify(time0, time1); - } - - /** - * zoom out using single click - */ - public void zoomOut() { - long prevTime0 = fTimeProvider.getTime0(); - long prevTime1 = fTimeProvider.getTime1(); - ITimeDataProvider provider = fTimeProvider; - long selTime = (provider.getSelectionEnd() + provider.getSelectionBegin()) / 2; - if (selTime <= prevTime0 || selTime >= prevTime1) { - selTime = (prevTime0 + prevTime1) / 2; - } - long time0 = (long) (selTime - (selTime - prevTime0) * ZOOM_FACTOR); - long time1 = (long) (selTime + (prevTime1 - selTime) * ZOOM_FACTOR); - - long inaccuracy = (fTimeProvider.getMaxTime() - fTimeProvider.getMinTime()) - (time1 - time0); - if (inaccuracy > 0 && inaccuracy < 100) { - fTimeProvider.setStartFinishTimeNotify(fTimeProvider.getMinTime(), fTimeProvider.getMaxTime()); - return; - } - - fTimeProvider.setStartFinishTimeNotify(time0, time1); - } - - /** - * Hide arrows - * - * @param hideArrows true to hide arrows - * - * @since 2.1 - */ - public void hideArrows(boolean hideArrows) { - fHideArrows = hideArrows; - } - - /** - * Follow the arrow forward - * - * @since 2.1 - */ - public void followArrowFwd() { - ITimeGraphEntry trace = getSelectedTrace(); - if (trace == null) { - return; - } - long selectedTime = fTimeProvider.getSelectionBegin(); - for (ILinkEvent link : fItemData.fLinks) { - if (link.getEntry() == trace && link.getTime() == selectedTime) { - selectItem(link.getDestinationEntry(), false); - if (link.getDuration() != 0) { - fTimeProvider.setSelectedTimeNotify(link.getTime() + link.getDuration(), true); - // Notify if visible time window has been adjusted - fTimeProvider.setStartFinishTimeNotify(fTimeProvider.getTime0(), fTimeProvider.getTime1()); - } - fireSelectionChanged(); - return; - } - } - selectNextEvent(); - } - - /** - * Follow the arrow backward - * - * @since 2.1 - */ - public void followArrowBwd() { - ITimeGraphEntry trace = getSelectedTrace(); - if (trace == null) { - return; - } - long selectedTime = fTimeProvider.getSelectionBegin(); - for (ILinkEvent link : fItemData.fLinks) { - if (link.getDestinationEntry() == trace && link.getTime() + link.getDuration() == selectedTime) { - selectItem(link.getEntry(), false); - if (link.getDuration() != 0) { - fTimeProvider.setSelectedTimeNotify(link.getTime(), true); - // Notify if visible time window has been adjusted - fTimeProvider.setStartFinishTimeNotify(fTimeProvider.getTime0(), fTimeProvider.getTime1()); - } - fireSelectionChanged(); - return; - } - } - selectPrevEvent(); - } - - /** - * Return the currently selected trace - * - * @return The entry matching the trace - */ - public ITimeGraphEntry getSelectedTrace() { - ITimeGraphEntry trace = null; - int idx = getSelectedIndex(); - if (idx >= 0) { - trace = fItemData.fExpandedItems[idx].fEntry; - } - return trace; - } - - /** - * Retrieve the index of the currently selected item - * - * @return The index - */ - public int getSelectedIndex() { - int idx = -1; - for (int i = 0; i < fItemData.fExpandedItems.length; i++) { - Item item = fItemData.fExpandedItems[i]; - if (item.fSelected) { - idx = i; - break; - } - } - return idx; - } - - boolean toggle(int idx) { - boolean toggled = false; - if (idx >= 0 && idx < fItemData.fExpandedItems.length) { - Item item = fItemData.fExpandedItems[idx]; - if (item.fHasChildren) { - item.fExpanded = !item.fExpanded; - fItemData.updateExpandedItems(); - adjustScrolls(); - redraw(); - toggled = true; - fireTreeEvent(item.fEntry, item.fExpanded); - } - } - return toggled; - } - - /** - * Gets the index of the item at the given location. - * - * @param y - * the y coordinate - * @return the index of the item at the given location, of -1 if none. - * @since 3.0 - */ - protected int getItemIndexAtY(int y) { - if (y < 0) { - return -1; - } - int ySum = 0; - for (int idx = fTopIndex; idx < fItemData.fExpandedItems.length; idx++) { - ySum += fItemData.fExpandedItems[idx].fItemHeight; - if (y < ySum) { - return idx; - } - } - return -1; - } - - boolean isOverSplitLine(int x) { - if (x < 0 || null == fTimeProvider) { - return false; - } - int nameWidth = fTimeProvider.getNameSpace(); - return Math.abs(x - nameWidth) < SNAP_WIDTH; - } - - /** - * Gets the {@link ITimeGraphEntry} at the given location. - * - * @param pt - * a point in the widget - * @return the {@link ITimeGraphEntry} at this point, or null - * if none. - * @since 3.0 - */ - protected ITimeGraphEntry getEntry(Point pt) { - int idx = getItemIndexAtY(pt.y); - return idx >= 0 ? fItemData.fExpandedItems[idx].fEntry : null; - } - - /** - * Return the arrow event closest to the given point that is no further than - * a maximum distance. - * - * @param pt - * a point in the widget - * @return The closest arrow event, or null if there is none close enough. - * @since 3.2 - */ - protected ILinkEvent getArrow(Point pt) { - if (fHideArrows) { - return null; - } - ILinkEvent linkEvent = null; - double minDistance = Double.MAX_VALUE; - for (ILinkEvent event : fItemData.fLinks) { - Rectangle rect = getArrowRectangle(new Rectangle(0, 0, 0, 0), event); - if (rect != null) { - int x1 = rect.x; - int y1 = rect.y; - int x2 = x1 + rect.width; - int y2 = y1 + rect.height; - double d = Utils.distance(pt.x, pt.y, x1, y1, x2, y2); - if (minDistance > d) { - minDistance = d; - linkEvent = event; - } - } - } - if (minDistance <= ARROW_HOVER_MAX_DIST) { - return linkEvent; - } - return null; - } - - /** - * @since 2.0 - */ - @Override - public int getXForTime(long time) { - if (null == fTimeProvider) { - return -1; - } - long time0 = fTimeProvider.getTime0(); - long time1 = fTimeProvider.getTime1(); - int width = getCtrlSize().x; - int nameSpace = fTimeProvider.getNameSpace(); - double pixelsPerNanoSec = (width - nameSpace <= RIGHT_MARGIN) ? 0 : (double) (width - nameSpace - RIGHT_MARGIN) / (time1 - time0); - int x = getBounds().x + nameSpace + (int) ((time - time0) * pixelsPerNanoSec); - return x; - } - - /** - * @since 2.0 - */ - @Override - public long getTimeAtX(int coord) { - if (null == fTimeProvider) { - return -1; - } - long hitTime = -1; - Point size = getCtrlSize(); - long time0 = fTimeProvider.getTime0(); - long time1 = fTimeProvider.getTime1(); - int nameWidth = fTimeProvider.getNameSpace(); - final int x = coord - nameWidth; - int timeWidth = size.x - nameWidth - RIGHT_MARGIN; - if (x >= 0 && size.x >= nameWidth) { - if (time1 - time0 > timeWidth) { - // nanosecond smaller than one pixel: use the first integer nanosecond of this pixel's time range - hitTime = time0 + (long) Math.ceil((time1 - time0) * ((double) x / timeWidth)); - } else { - // nanosecond greater than one pixel: use the nanosecond that covers this pixel start position - hitTime = time0 + (long) Math.floor((time1 - time0) * ((double) x / timeWidth)); - } - } - return hitTime; - } - - void selectItem(int idx, boolean addSelection) { - boolean changed = false; - if (addSelection) { - if (idx >= 0 && idx < fItemData.fExpandedItems.length) { - Item item = fItemData.fExpandedItems[idx]; - changed = !item.fSelected; - item.fSelected = true; - } - } else { - for (int i = 0; i < fItemData.fExpandedItems.length; i++) { - Item item = fItemData.fExpandedItems[i]; - if ((i == idx && !item.fSelected) || (idx == -1 && item.fSelected)) { - changed = true; - } - item.fSelected = i == idx; - } - } - changed |= ensureVisibleItem(idx, true); - if (changed) { - redraw(); - } - } - - /** - * Callback for item selection - * - * @param trace - * The entry matching the trace - * @param addSelection - * If the selection is added or removed - */ - public void selectItem(ITimeGraphEntry trace, boolean addSelection) { - int idx = fItemData.findItemIndex(trace); - selectItem(idx, addSelection); - } - - /** - * Retrieve the number of entries shown per page. - * - * @return The count - */ - public int countPerPage() { - int height = getCtrlSize().y; - int count = 0; - int ySum = 0; - for (int idx = fTopIndex; idx < fItemData.fExpandedItems.length; idx++) { - ySum += fItemData.fExpandedItems[idx].fItemHeight; - if (ySum >= height) { - return count; - } - count++; - } - for (int idx = fTopIndex - 1; idx >= 0; idx--) { - ySum += fItemData.fExpandedItems[idx].fItemHeight; - if (ySum >= height) { - return count; - } - count++; - } - return count; - } - - /** - * Get the index of the top element - * - * @return The index - */ - public int getTopIndex() { - return fTopIndex; - } - - /** - * Get the number of expanded items - * - * @return The count of expanded items - */ - public int getExpandedElementCount() { - return fItemData.fExpandedItems.length; - } - - /** - * Get an array of all expanded elements - * - * @return The expanded elements - */ - public ITimeGraphEntry[] getExpandedElements() { - ArrayList elements = new ArrayList<>(); - for (Item item : fItemData.fExpandedItems) { - elements.add(item.fEntry); - } - return elements.toArray(new ITimeGraphEntry[0]); - } - - Point getCtrlSize() { - Point size = getSize(); - if (getHorizontalBar().isVisible()) { - size.y -= getHorizontalBar().getSize().y; - } - return size; - } - - Rectangle getNameRect(Rectangle bound, int idx, int nameWidth) { - Rectangle rect = getStatesRect(bound, idx, nameWidth); - rect.x = bound.x; - rect.width = nameWidth; - return rect; - } - - Rectangle getStatesRect(Rectangle bound, int idx, int nameWidth) { - int x = bound.x + nameWidth; - int width = bound.width - x; - int ySum = 0; - if (idx >= fTopIndex) { - for (int i = fTopIndex; i < idx; i++) { - ySum += fItemData.fExpandedItems[i].fItemHeight; - } - } else { - for (int i = fTopIndex - 1; i >= idx; i--) { - ySum -= fItemData.fExpandedItems[i].fItemHeight; - } - } - int y = bound.y + ySum; - int height = fItemData.fExpandedItems[idx].fItemHeight; - return new Rectangle(x, y, width, height); - } - - @Override - void paint(Rectangle bounds, PaintEvent e) { - GC gc = e.gc; - gc.setBackground(getColorScheme().getColor(TimeGraphColorScheme.BACKGROUND)); - drawBackground(gc, bounds.x, bounds.y, bounds.width, bounds.height); - - if (bounds.width < 2 || bounds.height < 2 || null == fTimeProvider) { - return; - } - - fIdealNameSpace = 0; - int nameSpace = fTimeProvider.getNameSpace(); - - // draw empty name space background - gc.setBackground(getColorScheme().getBkColor(false, false, true)); - drawBackground(gc, bounds.x, bounds.y, nameSpace, bounds.height); - - // draw items - drawItems(bounds, fTimeProvider, fItemData.fExpandedItems, fTopIndex, nameSpace, gc); - drawLinks(bounds, fTimeProvider, fItemData.fLinks, nameSpace, gc); - fTimeGraphProvider.postDrawControl(bounds, gc); - - int alpha = gc.getAlpha(); - gc.setAlpha(100); - - long time0 = fTimeProvider.getTime0(); - long time1 = fTimeProvider.getTime1(); - long selectionBegin = fTimeProvider.getSelectionBegin(); - long selectionEnd = fTimeProvider.getSelectionEnd(); - double pixelsPerNanoSec = (bounds.width - nameSpace <= RIGHT_MARGIN) ? 0 : (double) (bounds.width - nameSpace - RIGHT_MARGIN) / (time1 - time0); - int x0 = bounds.x + nameSpace + (int) ((selectionBegin - time0) * pixelsPerNanoSec); - int x1 = bounds.x + nameSpace + (int) ((selectionEnd - time0) * pixelsPerNanoSec); - - // draw selection lines - if (fDragState != DRAG_SELECTION) { - gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.SELECTED_TIME)); - if (x0 >= nameSpace && x0 < bounds.x + bounds.width) { - gc.drawLine(x0, bounds.y, x0, bounds.y + bounds.height); - } - if (x1 != x0) { - if (x1 >= nameSpace && x1 < bounds.x + bounds.width) { - gc.drawLine(x1, bounds.y, x1, bounds.y + bounds.height); - } - } - } - - // draw selection background - if (selectionBegin != 0 && selectionEnd != 0 && fDragState != DRAG_SELECTION) { - x0 = Math.max(nameSpace, Math.min(bounds.x + bounds.width, x0)); - x1 = Math.max(nameSpace, Math.min(bounds.x + bounds.width, x1)); - gc.setBackground(getColorScheme().getBkColor(false, false, true)); - if (x1 - x0 > 1) { - gc.fillRectangle(new Rectangle(x0 + 1, bounds.y, x1 - x0 - 1, bounds.height)); - } else if (x0 - x1 > 1) { - gc.fillRectangle(new Rectangle(x1 + 1, bounds.y, x0 - x1 - 1, bounds.height)); - } - } - - // draw drag selection background - if (fDragState == DRAG_ZOOM || fDragState == DRAG_SELECTION) { - gc.setBackground(getColorScheme().getBkColor(false, false, true)); - if (fDragX0 < fDragX) { - gc.fillRectangle(new Rectangle(fDragX0, bounds.y, fDragX - fDragX0, bounds.height)); - } else if (fDragX0 > fDragX) { - gc.fillRectangle(new Rectangle(fDragX, bounds.y, fDragX0 - fDragX, bounds.height)); - } - } - - // draw drag line - if (DRAG_SPLIT_LINE == fDragState) { - gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.BLACK)); - gc.drawLine(bounds.x + nameSpace, bounds.y, bounds.x + nameSpace, bounds.y + bounds.height - 1); - } else if (DRAG_ZOOM == fDragState && Math.max(fDragX, fDragX0) > nameSpace) { - gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.TOOL_FOREGROUND)); - gc.drawLine(fDragX0, bounds.y, fDragX0, bounds.y + bounds.height - 1); - if (fDragX != fDragX0) { - gc.drawLine(fDragX, bounds.y, fDragX, bounds.y + bounds.height - 1); - } - } else if (DRAG_SELECTION == fDragState && Math.max(fDragX, fDragX0) > nameSpace) { - gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.SELECTED_TIME)); - gc.drawLine(fDragX0, bounds.y, fDragX0, bounds.y + bounds.height - 1); - if (fDragX != fDragX0) { - gc.drawLine(fDragX, bounds.y, fDragX, bounds.y + bounds.height - 1); - } - } else if (DRAG_NONE == fDragState && fMouseOverSplitLine && fTimeProvider.getNameSpace() > 0) { - gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.RED)); - gc.drawLine(bounds.x + nameSpace, bounds.y, bounds.x + nameSpace, bounds.y + bounds.height - 1); - } - - gc.setAlpha(alpha); - } - - /** - * Draw many items at once - * - * @param bounds - * The rectangle of the area - * @param timeProvider - * The time provider - * @param items - * The array items to draw - * @param topIndex - * The index of the first element to draw - * @param nameSpace - * The width reserved for the names - * @param gc - * Reference to the SWT GC object - */ - public void drawItems(Rectangle bounds, ITimeDataProvider timeProvider, - Item[] items, int topIndex, int nameSpace, GC gc) { - for (int i = topIndex; i < items.length; i++) { - Item item = items[i]; - drawItem(item, bounds, timeProvider, i, nameSpace, gc); - } - } - - /** - * Draws the item - * - * @param item the item to draw - * @param bounds the container rectangle - * @param timeProvider Time provider - * @param i the item index - * @param nameSpace the name space - * @param gc Graphics context - */ - protected void drawItem(Item item, Rectangle bounds, ITimeDataProvider timeProvider, int i, int nameSpace, GC gc) { - ITimeGraphEntry entry = item.fEntry; - long time0 = timeProvider.getTime0(); - long time1 = timeProvider.getTime1(); - long selectedTime = fTimeProvider.getSelectionBegin(); - - Rectangle nameRect = getNameRect(bounds, i, nameSpace); - if (nameRect.y >= bounds.y + bounds.height) { - return; - } - - if (! item.fEntry.hasTimeEvents()) { - Rectangle statesRect = getStatesRect(bounds, i, nameSpace); - nameRect.width += statesRect.width; - drawName(item, nameRect, gc); - } else { - drawName(item, nameRect, gc); - } - Rectangle rect = getStatesRect(bounds, i, nameSpace); - if (rect.isEmpty()) { - fTimeGraphProvider.postDrawEntry(entry, rect, gc); - return; - } - if (time1 <= time0) { - gc.setBackground(getColorScheme().getBkColor(false, false, false)); - gc.fillRectangle(rect); - fTimeGraphProvider.postDrawEntry(entry, rect, gc); - return; - } - - // Initialize _rect1 to same values as enclosing rectangle rect - Rectangle stateRect = Utils.clone(rect); - boolean selected = item.fSelected; - // K pixels per second - double pixelsPerNanoSec = (rect.width <= RIGHT_MARGIN) ? 0 : (double) (rect.width - RIGHT_MARGIN) / (time1 - time0); - - if (item.fEntry.hasTimeEvents()) { - gc.setClipping(new Rectangle(nameSpace, 0, bounds.width - nameSpace, bounds.height)); - fillSpace(rect, gc, selected); - // Drawing rectangle is smaller than reserved space - stateRect.y += 3; - stateRect.height -= 6; - - long maxDuration = (timeProvider.getTimeSpace() == 0) ? Long.MAX_VALUE : 1 * (time1 - time0) / timeProvider.getTimeSpace(); - Iterator iterator = entry.getTimeEventsIterator(time0, time1, maxDuration); - - int lastX = -1; - while (iterator.hasNext()) { - ITimeEvent event = iterator.next(); - int x = rect.x + (int) ((event.getTime() - time0) * pixelsPerNanoSec); - int xEnd = rect.x + (int) ((event.getTime() + event.getDuration() - time0) * pixelsPerNanoSec); - if (x >= rect.x + rect.width || xEnd < rect.x) { - // event is out of bounds - continue; - } - xEnd = Math.min(rect.x + rect.width, xEnd); - stateRect.x = Math.max(rect.x, x); - stateRect.width = Math.max(0, xEnd - stateRect.x + 1); - if (stateRect.x == lastX) { - stateRect.width -= 1; - if (stateRect.width > 0) { - gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); - gc.drawPoint(stateRect.x, stateRect.y - 2); - stateRect.x += 1; - } - } - boolean timeSelected = selectedTime >= event.getTime() && selectedTime < event.getTime() + event.getDuration(); - if (drawState(getColorScheme(), event, stateRect, gc, selected, timeSelected)) { - lastX = x; - } - } - gc.setClipping((Rectangle) null); - } - fTimeGraphProvider.postDrawEntry(entry, rect, gc); - } - - /** - * Draw the links - * - * @param bounds - * The rectangle of the area - * @param timeProvider - * The time provider - * @param links - * The array items to draw - * @param nameSpace - * The width reserved for the names - * @param gc - * Reference to the SWT GC object - * @since 2.1 - */ - public void drawLinks(Rectangle bounds, ITimeDataProvider timeProvider, - List links, int nameSpace, GC gc) { - if (fHideArrows) { - return; - } - gc.setClipping(new Rectangle(nameSpace, 0, bounds.width - nameSpace, bounds.height)); - for (ILinkEvent event : links) { - drawLink(event, bounds, timeProvider, nameSpace, gc); - } - gc.setClipping((Rectangle) null); - } - - /** - * Draws the link type events of this item - * - * @param event - * the item to draw - * @param bounds - * the container rectangle - * @param timeProvider - * Time provider - * @param nameSpace - * the name space - * @param gc - * Graphics context - * @since 2.1 - */ - protected void drawLink(ILinkEvent event, Rectangle bounds, ITimeDataProvider timeProvider, int nameSpace, GC gc) { - drawArrow(getColorScheme(), event, getArrowRectangle(bounds, event), gc); - } - - private Rectangle getArrowRectangle(Rectangle bounds, ILinkEvent event) { - int srcIndex = fItemData.findItemIndex(event.getEntry()); - int destIndex = fItemData.findItemIndex(event.getDestinationEntry()); - - if ((srcIndex == -1) || (destIndex == -1)) { - return null; - } - - Rectangle src = getStatesRect(bounds, srcIndex, fTimeProvider.getNameSpace()); - Rectangle dst = getStatesRect(bounds, destIndex, fTimeProvider.getNameSpace()); - - int x0 = getXForTime(event.getTime()); - int x1 = getXForTime(event.getTime() + event.getDuration()); - - // limit the x-coordinates to prevent integer overflow in calculations - // and also GC.drawLine doesn't draw properly with large coordinates - final int limit = Integer.MAX_VALUE / 1024; - x0 = Math.max(-limit, Math.min(x0, limit)); - x1 = Math.max(-limit, Math.min(x1, limit)); - - int y0 = src.y + src.height / 2; - int y1 = dst.y + dst.height / 2; - return new Rectangle(x0, y0, x1 - x0, y1 - y0); - } - - /** - * Draw the state (color fill) - * - * @param colors - * Color scheme - * @param event - * Time event for which we're drawing the state - * @param rect - * Where to draw - * @param gc - * Graphics context - * @return true if the state was drawn - * @since 2.1 - */ - protected boolean drawArrow(TimeGraphColorScheme colors, ITimeEvent event, - Rectangle rect, GC gc) { - - if (rect == null) { - return false; - } - int colorIdx = fTimeGraphProvider.getStateTableIndex(event); - if (colorIdx < 0) { - return false; - } - boolean visible = ((rect.height == 0) && (rect.width == 0)) ? false : true; - - if (visible) { - Color stateColor = null; - if (colorIdx < fEventColorMap.length) { - stateColor = fEventColorMap[colorIdx]; - } else { - stateColor = Display.getDefault().getSystemColor(SWT.COLOR_BLACK); - } - - gc.setForeground(stateColor); - gc.setBackground(stateColor); - - /* Draw the arrow */ - gc.drawLine(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height); - drawArrowHead(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height, gc); - - } - fTimeGraphProvider.postDrawEvent(event, rect, gc); - return visible; - } - - /* - * @author Francis Giraldeau - * - * Inspiration: - * http://stackoverflow.com/questions/3010803/draw-arrow-on-line-algorithm - * - * The algorithm was taken from this site, not the code itself - */ - private static void drawArrowHead(int x0, int y0, int x1, int y1, GC gc) - { - int factor = 10; - double cos = 0.9510; - double sin = 0.3090; - long lenx = x1 - x0; - long leny = y1 - y0; - double len = Math.sqrt(lenx * lenx + leny * leny); - - double dx = factor * lenx / len; - double dy = factor * leny / len; - int end1X = (int) Math.round((x1 - (dx * cos + dy * -sin))); - int end1Y = (int) Math.round((y1 - (dx * sin + dy * cos))); - int end2X = (int) Math.round((x1 - (dx * cos + dy * sin))); - int end2Y = (int) Math.round((y1 - (dx * -sin + dy * cos))); - int[] arrow = new int[] { x1, y1, end1X, end1Y, end2X, end2Y, x1, y1 }; - gc.fillPolygon(arrow); - } - - /** - * Draw the name of an item. - * - * @param item - * Item object - * @param bounds - * Where to draw the name - * @param gc - * Graphics context - */ - protected void drawName(Item item, Rectangle bounds, GC gc) { - boolean hasTimeEvents = item.fEntry.hasTimeEvents(); - if (! hasTimeEvents) { - gc.setBackground(getColorScheme().getBkColorGroup(item.fSelected, fIsInFocus)); - gc.fillRectangle(bounds); - if (item.fSelected && fIsInFocus) { - gc.setForeground(getColorScheme().getBkColor(item.fSelected, fIsInFocus, false)); - gc.drawRectangle(bounds.x, bounds.y, bounds.width - 1, bounds.height - 1); - } - } else { - gc.setBackground(getColorScheme().getBkColor(item.fSelected, fIsInFocus, true)); - gc.setForeground(getColorScheme().getFgColor(item.fSelected, fIsInFocus)); - gc.fillRectangle(bounds); - } - - // No name to be drawn - if (fTimeProvider.getNameSpace() == 0) { - return; - } - - int leftMargin = MARGIN + item.fLevel * EXPAND_SIZE; - if (item.fHasChildren) { - gc.setForeground(getColorScheme().getFgColorGroup(false, false)); - gc.setBackground(getColorScheme().getBkColor(false, false, false)); - Rectangle rect = Utils.clone(bounds); - rect.x += leftMargin; - rect.y += (bounds.height - EXPAND_SIZE) / 2; - rect.width = EXPAND_SIZE; - rect.height = EXPAND_SIZE; - gc.fillRectangle(rect); - gc.drawRectangle(rect.x, rect.y, rect.width - 1, rect.height - 1); - int midy = rect.y + rect.height / 2; - gc.drawLine(rect.x + 2, midy, rect.x + rect.width - 3, midy); - if (!item.fExpanded) { - int midx = rect.x + rect.width / 2; - gc.drawLine(midx, rect.y + 2, midx, rect.y + rect.height - 3); - } - } - leftMargin += EXPAND_SIZE + MARGIN; - - Image img = fTimeGraphProvider.getItemImage(item.fEntry); - if (img != null) { - // draw icon - int imgHeight = img.getImageData().height; - int imgWidth = img.getImageData().width; - int x = leftMargin; - int y = bounds.y + (bounds.height - imgHeight) / 2; - gc.drawImage(img, x, y); - leftMargin += imgWidth + MARGIN; - } - String name = item.fName; - Point size = gc.stringExtent(name); - if (fIdealNameSpace < leftMargin + size.x + MARGIN) { - fIdealNameSpace = leftMargin + size.x + MARGIN; - } - if (hasTimeEvents) { - // cut long string with "..." - int width = bounds.width - leftMargin; - int cuts = 0; - while (size.x > width && name.length() > 1) { - cuts++; - name = name.substring(0, name.length() - 1); - size = gc.stringExtent(name + "..."); //$NON-NLS-1$ - } - if (cuts > 0) { - name += "..."; //$NON-NLS-1$ - } - } - Rectangle rect = Utils.clone(bounds); - rect.x += leftMargin; - rect.width -= leftMargin; - // draw text - if (rect.width > 0) { - rect.y += (bounds.height - gc.stringExtent(name).y) / 2; - gc.setForeground(getColorScheme().getFgColor(item.fSelected, fIsInFocus)); - int textWidth = Utils.drawText(gc, name, rect, true); - leftMargin += textWidth + MARGIN; - rect.y -= 2; - - if (hasTimeEvents) { - // draw middle line - int x = bounds.x + leftMargin; - int width = bounds.width - x; - int midy = bounds.y + bounds.height / 2; - gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.MID_LINE)); - gc.drawLine(x, midy, x + width, midy); - } - } - } - - /** - * Draw the state (color fill) - * - * @param colors - * Color scheme - * @param event - * Time event for which we're drawing the state - * @param rect - * Where to draw - * @param gc - * Graphics context - * @param selected - * Is this time event currently selected (so it appears - * highlighted) - * @param timeSelected - * Is the timestamp currently selected - * @return true if the state was drawn - * @since 2.0 - */ - protected boolean drawState(TimeGraphColorScheme colors, ITimeEvent event, - Rectangle rect, GC gc, boolean selected, boolean timeSelected) { - - int colorIdx = fTimeGraphProvider.getStateTableIndex(event); - if (colorIdx < 0 && colorIdx != ITimeGraphPresentationProvider.TRANSPARENT) { - return false; - } - boolean visible = rect.width == 0 ? false : true; - Color black = Display.getDefault().getSystemColor(SWT.COLOR_BLACK); - gc.setForeground(black); - - if (visible) { - if (colorIdx == ITimeGraphPresentationProvider.TRANSPARENT) { - // Only draw the top and bottom borders - gc.drawLine(rect.x, rect.y, rect.x + rect.width - 1, rect.y); - gc.drawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width - 1, rect.y + rect.height - 1); - if (rect.width == 1) { - gc.drawPoint(rect.x, rect.y - 2); - } - return false; - } - Color stateColor = null; - if (colorIdx < fEventColorMap.length) { - stateColor = fEventColorMap[colorIdx]; - } else { - stateColor = black; - } - - boolean reallySelected = timeSelected && selected; - // fill all rect area - gc.setBackground(stateColor); - gc.fillRectangle(rect); - - if (reallySelected) { - gc.drawLine(rect.x, rect.y - 1, rect.x + rect.width - 1, rect.y - 1); - gc.drawLine(rect.x, rect.y + rect.height, rect.x + rect.width - 1, rect.y + rect.height); - } - } else { - gc.drawPoint(rect.x, rect.y - 2); - } - fTimeGraphProvider.postDrawEvent(event, rect, gc); - return visible; - } - - /** - * Fill the space between two contiguous time events - * - * @param rect - * Rectangle to fill - * @param gc - * Graphics context - * @param selected - * Is this time event selected or not - */ - protected void fillSpace(Rectangle rect, GC gc, boolean selected) { - gc.setBackground(getColorScheme().getBkColor(selected, fIsInFocus, false)); - gc.fillRectangle(rect); - if (fDragState == DRAG_ZOOM) { - gc.setBackground(getColorScheme().getBkColor(selected, fIsInFocus, true)); - if (fDragX0 < fDragX) { - gc.fillRectangle(new Rectangle(fDragX0, rect.y, fDragX - fDragX0, rect.height)); - } else if (fDragX0 > fDragX) { - gc.fillRectangle(new Rectangle(fDragX, rect.y, fDragX0 - fDragX, rect.height)); - } - } - // draw middle line - gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.MID_LINE)); - int midy = rect.y + rect.height / 2; - gc.drawLine(rect.x, midy, rect.x + rect.width, midy); - } - - @Override - public void keyTraversed(TraverseEvent e) { - if ((e.detail == SWT.TRAVERSE_TAB_NEXT) || (e.detail == SWT.TRAVERSE_TAB_PREVIOUS)) { - e.doit = true; - } - } - - @Override - public void keyPressed(KeyEvent e) { - int idx = -1; - if (fItemData.fExpandedItems.length == 0) { - return; - } - if (SWT.HOME == e.keyCode) { - idx = 0; - } else if (SWT.END == e.keyCode) { - idx = fItemData.fExpandedItems.length - 1; - } else if (SWT.ARROW_DOWN == e.keyCode) { - idx = getSelectedIndex(); - if (idx < 0) { - idx = 0; - } else if (idx < fItemData.fExpandedItems.length - 1) { - idx++; - } - } else if (SWT.ARROW_UP == e.keyCode) { - idx = getSelectedIndex(); - if (idx < 0) { - idx = 0; - } else if (idx > 0) { - idx--; - } - } else if (SWT.ARROW_LEFT == e.keyCode) { - selectPrevEvent(); - } else if (SWT.ARROW_RIGHT == e.keyCode) { - selectNextEvent(); - } else if (SWT.PAGE_DOWN == e.keyCode) { - int page = countPerPage(); - idx = getSelectedIndex(); - if (idx < 0) { - idx = 0; - } - idx += page; - if (idx >= fItemData.fExpandedItems.length) { - idx = fItemData.fExpandedItems.length - 1; - } - } else if (SWT.PAGE_UP == e.keyCode) { - int page = countPerPage(); - idx = getSelectedIndex(); - if (idx < 0) { - idx = 0; - } - idx -= page; - if (idx < 0) { - idx = 0; - } - } else if (SWT.CR == e.keyCode) { - idx = getSelectedIndex(); - if (idx >= 0) { - if (fItemData.fExpandedItems[idx].fHasChildren) { - toggle(idx); - } else { - fireDefaultSelection(); - } - } - idx = -1; - } - if (idx >= 0) { - selectItem(idx, false); - fireSelectionChanged(); - } - int x = toControl(e.display.getCursorLocation()).x; - updateCursor(x, e.stateMask | e.keyCode); - } - - @Override - public void keyReleased(KeyEvent e) { - int x = toControl(e.display.getCursorLocation()).x; - updateCursor(x, e.stateMask & ~e.keyCode); - } - - @Override - public void focusGained(FocusEvent e) { - fIsInFocus = true; - if (fMouseScrollFilterListener == null) { - fMouseScrollFilterListener = new Listener() { - // This filter is used to prevent horizontal scrolling of the view - // when the mouse wheel is used to zoom - @Override - public void handleEvent(Event event) { - event.doit = false; - } - }; - getDisplay().addFilter(SWT.MouseWheel, fMouseScrollFilterListener); - } - redraw(); - updateStatusLine(NO_STATUS); - } - - @Override - public void focusLost(FocusEvent e) { - fIsInFocus = false; - if (fMouseScrollFilterListener != null) { - getDisplay().removeFilter(SWT.MouseWheel, fMouseScrollFilterListener); - fMouseScrollFilterListener = null; - } - if (DRAG_NONE != fDragState) { - setCapture(false); - fDragState = DRAG_NONE; - } - redraw(); - updateStatusLine(NO_STATUS); - } - - /** - * @return If the current view is focused - */ - public boolean isInFocus() { - return fIsInFocus; - } - - /** - * Provide the possibility to control the wait cursor externally e.g. data - * requests in progress - * - * @param waitInd Should we wait indefinitely? - */ - public void waitCursor(boolean waitInd) { - // Update cursor as indicated - if (waitInd) { - setCursor(fWaitCursor); - } else { - setCursor(null); - } - } - - private void updateCursor(int x, int stateMask) { - // if Wait cursor not active, check for the need to change the cursor - if (getCursor() == fWaitCursor) { - return; - } - Cursor cursor = null; - if (fDragState == DRAG_SPLIT_LINE) { - } else if (fDragState == DRAG_SELECTION) { - cursor = fResizeCursor; - } else if (fDragState == DRAG_TRACE_ITEM) { - cursor = fDragCursor; - } else if (fDragState == DRAG_ZOOM) { - cursor = fZoomCursor; - } else if ((stateMask & SWT.MODIFIER_MASK) == SWT.CTRL) { - cursor = fDragCursor; - } else if ((stateMask & SWT.MODIFIER_MASK) == SWT.SHIFT) { - cursor = fResizeCursor; - } else if (!isOverSplitLine(x)) { - long selectionBegin = fTimeProvider.getSelectionBegin(); - long selectionEnd = fTimeProvider.getSelectionEnd(); - int xBegin = getXForTime(selectionBegin); - int xEnd = getXForTime(selectionEnd); - if (Math.abs(x - xBegin) < SNAP_WIDTH || Math.abs(x - xEnd) < SNAP_WIDTH) { - cursor = fResizeCursor; - } - } - if (getCursor() != cursor) { - setCursor(cursor); - } - } - - private void updateStatusLine(int x) { - // use the time provider of the time graph scale for the status line - ITimeDataProvider tdp = fTimeGraphScale.getTimeProvider(); - if (fStatusLineManager == null || null == tdp || - tdp.getTime0() == tdp.getTime1()) { - return; - } - TimeFormat tf = tdp.getTimeFormat(); - Resolution res = Resolution.NANOSEC; - StringBuilder message = new StringBuilder(); - if (x >= 0 && fDragState == DRAG_NONE) { - long time = getTimeAtX(x); - if (time >= 0) { - if (tdp instanceof ITimeDataProviderConverter) { - time = ((ITimeDataProviderConverter) tdp).convertTime(time); - } - long selectionBegin = tdp.getSelectionBegin(); - long selectionEnd = tdp.getSelectionEnd(); - message.append(NLS.bind("T: {0}{1} T1: {2}{3}", //$NON-NLS-1$ - new Object[] { - tf == TimeFormat.CALENDAR ? Utils.formatDate(time) + ' ' : "", //$NON-NLS-1$ - Utils.formatTime(time, tf, res), - tf == TimeFormat.CALENDAR ? Utils.formatDate(Math.min(selectionBegin, selectionEnd)) + ' ' : "", //$NON-NLS-1$ - Utils.formatTime(Math.min(selectionBegin, selectionEnd), tf, res) - })); - if (selectionBegin != selectionEnd) { - message.append(NLS.bind(" T2: {0}{1} \u0394: {2}", //$NON-NLS-1$ - new Object[] { - tf == TimeFormat.CALENDAR ? Utils.formatDate(Math.max(selectionBegin, selectionEnd)) + ' ' : "", //$NON-NLS-1$ - Utils.formatTime(Math.max(selectionBegin, selectionEnd), tf, res), - Utils.formatDelta(Math.abs(selectionBegin - selectionEnd), tf, res) - })); - } - } - } else if (fDragState == DRAG_SELECTION || fDragState == DRAG_ZOOM) { - long time0 = fDragTime0; - long time = getTimeAtX(fDragX); - if (tdp instanceof ITimeDataProviderConverter) { - time0 = ((ITimeDataProviderConverter) tdp).convertTime(time0); - time = ((ITimeDataProviderConverter) tdp).convertTime(time); - } - message.append(NLS.bind("T1: {0}{1} T2: {2}{3} \u0394: {4}", //$NON-NLS-1$ - new Object[] { - tf == TimeFormat.CALENDAR ? Utils.formatDate(Math.min(time, time0)) + ' ' : "", //$NON-NLS-1$ - Utils.formatTime(Math.min(time, time0), tf, res), - tf == TimeFormat.CALENDAR ? Utils.formatDate(Math.max(time, time0)) + ' ' : "", //$NON-NLS-1$ - Utils.formatTime(Math.max(time, time0), tf, res), - Utils.formatDelta(Math.abs(time - time0), tf, res) - })); - } - fStatusLineManager.setMessage(message.toString()); - } - - @Override - public void mouseMove(MouseEvent e) { - if (null == fTimeProvider) { - return; - } - Point size = getCtrlSize(); - if (DRAG_TRACE_ITEM == fDragState) { - int nameWidth = fTimeProvider.getNameSpace(); - if (e.x > nameWidth && size.x > nameWidth && fDragX != e.x) { - fDragX = e.x; - double pixelsPerNanoSec = (size.x - nameWidth <= RIGHT_MARGIN) ? 0 : (double) (size.x - nameWidth - RIGHT_MARGIN) / (fTime1bak - fTime0bak); - long timeDelta = (long) ((pixelsPerNanoSec == 0) ? 0 : ((fDragX - fDragX0) / pixelsPerNanoSec)); - long time1 = fTime1bak - timeDelta; - long maxTime = fTimeProvider.getMaxTime(); - if (time1 > maxTime) { - time1 = maxTime; - } - long time0 = time1 - (fTime1bak - fTime0bak); - if (time0 < fTimeProvider.getMinTime()) { - time0 = fTimeProvider.getMinTime(); - time1 = time0 + (fTime1bak - fTime0bak); - } - fTimeProvider.setStartFinishTime(time0, time1); - } - } else if (DRAG_SPLIT_LINE == fDragState) { - fDragX = e.x; - fTimeProvider.setNameSpace(e.x); - } else if (DRAG_SELECTION == fDragState) { - fDragX = Math.min(Math.max(e.x, fTimeProvider.getNameSpace()), size.x - RIGHT_MARGIN); - redraw(); - fTimeGraphScale.setDragRange(fDragX0, fDragX); - fireDragSelectionChanged(getTimeAtX(fDragX0), getTimeAtX(fDragX)); - } else if (DRAG_ZOOM == fDragState) { - fDragX = Math.min(Math.max(e.x, fTimeProvider.getNameSpace()), size.x - RIGHT_MARGIN); - redraw(); - fTimeGraphScale.setDragRange(fDragX0, fDragX); - } else if (DRAG_NONE == fDragState) { - boolean mouseOverSplitLine = isOverSplitLine(e.x); - if (fMouseOverSplitLine != mouseOverSplitLine) { - redraw(); - } - fMouseOverSplitLine = mouseOverSplitLine; - } - updateCursor(e.x, e.stateMask); - updateStatusLine(e.x); - } - - @Override - public void mouseDoubleClick(MouseEvent e) { - if (null == fTimeProvider) { - return; - } - if (1 == e.button && (e.stateMask & SWT.BUTTON_MASK) == 0) { - if (isOverSplitLine(e.x) && fTimeProvider.getNameSpace() != 0) { - fTimeProvider.setNameSpace(fIdealNameSpace); - boolean mouseOverSplitLine = isOverSplitLine(e.x); - if (fMouseOverSplitLine != mouseOverSplitLine) { - redraw(); - } - fMouseOverSplitLine = mouseOverSplitLine; - return; - } - int idx = getItemIndexAtY(e.y); - if (idx >= 0) { - selectItem(idx, false); - fireDefaultSelection(); - } - } - } - - @Override - public void mouseDown(MouseEvent e) { - if (fDragState != DRAG_NONE || null == fTimeProvider || - fTimeProvider.getTime0() == fTimeProvider.getTime1() || - getCtrlSize().x - fTimeProvider.getNameSpace() <= 0) { - return; - } - int idx; - if (1 == e.button && (e.stateMask & SWT.MODIFIER_MASK) == 0) { - int nameSpace = fTimeProvider.getNameSpace(); - if (nameSpace != 0 && isOverSplitLine(e.x)) { - fDragState = DRAG_SPLIT_LINE; - fDragButton = e.button; - fDragX = e.x; - fDragX0 = fDragX; - fTime0bak = fTimeProvider.getTime0(); - fTime1bak = fTimeProvider.getTime1(); - redraw(); - updateCursor(e.x, e.stateMask); - return; - } - } - if (1 == e.button && ((e.stateMask & SWT.MODIFIER_MASK) == 0 || (e.stateMask & SWT.MODIFIER_MASK) == SWT.SHIFT)) { - int nameSpace = fTimeProvider.getNameSpace(); - idx = getItemIndexAtY(e.y); - if (idx >= 0) { - Item item = fItemData.fExpandedItems[idx]; - if (item.fHasChildren && e.x < nameSpace && e.x < MARGIN + (item.fLevel + 1) * EXPAND_SIZE) { - toggle(idx); - return; - } - selectItem(idx, false); - fireSelectionChanged(); - } else { - selectItem(idx, false); // clear selection - fireSelectionChanged(); - } - long hitTime = getTimeAtX(e.x); - if (hitTime >= 0) { - setCapture(true); - - fDragState = DRAG_SELECTION; - fDragButton = e.button; - fDragX = e.x; - fDragX0 = fDragX; - fDragTime0 = getTimeAtX(fDragX0); - long selectionBegin = fTimeProvider.getSelectionBegin(); - long selectionEnd = fTimeProvider.getSelectionEnd(); - int xBegin = getXForTime(selectionBegin); - int xEnd = getXForTime(selectionEnd); - if ((e.stateMask & SWT.MODIFIER_MASK) == SWT.SHIFT) { - long time = getTimeAtX(e.x); - if (Math.abs(time - selectionBegin) < Math.abs(time - selectionEnd)) { - fDragX0 = xEnd; - fDragTime0 = selectionEnd; - } else { - fDragX0 = xBegin; - fDragTime0 = selectionBegin; - } - } else { - long time = getTimeAtX(e.x); - if (Math.abs(e.x - xBegin) < SNAP_WIDTH && Math.abs(time - selectionBegin) <= Math.abs(time - selectionEnd)) { - fDragX0 = xEnd; - fDragTime0 = selectionEnd; - } else if (Math.abs(e.x - xEnd) < SNAP_WIDTH && Math.abs(time - selectionEnd) <= Math.abs(time - selectionBegin)) { - fDragX0 = xBegin; - fDragTime0 = selectionBegin; - } - } - fTime0bak = fTimeProvider.getTime0(); - fTime1bak = fTimeProvider.getTime1(); - redraw(); - updateCursor(e.x, e.stateMask); - fTimeGraphScale.setDragRange(fDragX0, fDragX); - } - } else if (2 == e.button || (1 == e.button && (e.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL)) { - long hitTime = getTimeAtX(e.x); - if (hitTime > 0) { - setCapture(true); - fDragState = DRAG_TRACE_ITEM; - fDragButton = e.button; - fDragX = e.x; - fDragX0 = fDragX; - fTime0bak = fTimeProvider.getTime0(); - fTime1bak = fTimeProvider.getTime1(); - updateCursor(e.x, e.stateMask); - } - } else if (3 == e.button) { - setCapture(true); - fDragX = Math.min(Math.max(e.x, fTimeProvider.getNameSpace()), getCtrlSize().x - RIGHT_MARGIN); - fDragX0 = fDragX; - fDragTime0 = getTimeAtX(fDragX0); - fDragState = DRAG_ZOOM; - fDragButton = e.button; - redraw(); - updateCursor(e.x, e.stateMask); - fTimeGraphScale.setDragRange(fDragX0, fDragX); - } - } - - @Override - public void mouseUp(MouseEvent e) { - if (fPendingMenuDetectEvent != null && e.button == 3) { - menuDetected(fPendingMenuDetectEvent); - } - if (DRAG_NONE != fDragState) { - setCapture(false); - if (e.button == fDragButton && DRAG_TRACE_ITEM == fDragState) { - if (fDragX != fDragX0) { - fTimeProvider.notifyStartFinishTime(); - } - fDragState = DRAG_NONE; - } else if (e.button == fDragButton && DRAG_SPLIT_LINE == fDragState) { - fDragState = DRAG_NONE; - redraw(); - } else if (e.button == fDragButton && DRAG_SELECTION == fDragState) { - if (fDragX == fDragX0) { // click without selecting anything - long time = getTimeAtX(e.x); - fTimeProvider.setSelectedTimeNotify(time, false); - } else { - long time0 = fDragTime0; - long time1 = getTimeAtX(fDragX); - if (time0 <= time1) { - fTimeProvider.setSelectionRangeNotify(time0, time1); - } else { - fTimeProvider.setSelectionRangeNotify(time1, time0); - } - } - fDragState = DRAG_NONE; - redraw(); - fTimeGraphScale.setDragRange(-1, -1); - } else if (e.button == fDragButton && DRAG_ZOOM == fDragState) { - int nameWidth = fTimeProvider.getNameSpace(); - if (Math.max(fDragX, fDragX0) > nameWidth && fDragX != fDragX0) { - long time0 = getTimeAtX(fDragX0); - long time1 = getTimeAtX(fDragX); - if (time0 < time1) { - fTimeProvider.setStartFinishTimeNotify(time0, time1); - } else { - fTimeProvider.setStartFinishTimeNotify(time1, time0); - } - } else { - redraw(); - } - fDragState = DRAG_NONE; - fTimeGraphScale.setDragRange(-1, -1); - } - } - updateCursor(e.x, e.stateMask); - updateStatusLine(e.x); - } - - @Override - public void mouseEnter(MouseEvent e) { - } - - @Override - public void mouseExit(MouseEvent e) { - if (fMouseOverSplitLine) { - fMouseOverSplitLine = false; - redraw(); - } - updateStatusLine(NO_STATUS); - } - - @Override - public void mouseHover(MouseEvent e) { - } - - @Override - public void mouseScrolled(MouseEvent e) { - if ((fMouseScrollFilterListener == null) || fDragState != DRAG_NONE) { - return; - } - boolean zoomScroll = false; - Point p = getParent().toControl(getDisplay().getCursorLocation()); - Point parentSize = getParent().getSize(); - if (p.x >= 0 && p.x < parentSize.x && p.y >= 0 && p.y < parentSize.y) { - // over the parent control - if (e.x > getCtrlSize().x) { - // over the vertical scroll bar - zoomScroll = false; - } else if (e.y < 0 || e.y >= getCtrlSize().y) { - // over the time scale or horizontal scroll bar - zoomScroll = true; - } else { - if (e.x < fTimeProvider.getNameSpace()) { - // over the name space - zoomScroll = false; - } else { - // over the state area - if ((e.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL) { - // over the state area, CTRL pressed - zoomScroll = true; - } else { - // over the state area, CTRL not pressed - zoomScroll = false; - } - } - } - } - if (zoomScroll && fTimeProvider.getTime0() != fTimeProvider.getTime1()) { - if (e.count > 0) { - zoom(true); - } else if (e.count < 0) { - zoom(false); - } - } else { - setTopIndex(getTopIndex() - e.count); - } - } - - @Override - public void controlMoved(ControlEvent e) { - } - - @Override - public void controlResized(ControlEvent e) { - adjustScrolls(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - - @Override - public void widgetSelected(SelectionEvent e) { - if (e.widget == getVerticalBar()) { - setTopIndex(getVerticalBar().getSelection()); - } else if (e.widget == getHorizontalBar() && null != fTimeProvider) { - int start = getHorizontalBar().getSelection(); - long time0 = fTimeProvider.getTime0(); - long time1 = fTimeProvider.getTime1(); - long timeMin = fTimeProvider.getMinTime(); - long timeMax = fTimeProvider.getMaxTime(); - long delta = timeMax - timeMin; - - long range = time1 - time0; - time0 = timeMin + Math.round(delta * ((double) start / H_SCROLLBAR_MAX)); - time1 = time0 + range; - - // TODO: Follow-up with Bug 310310 - // In Linux SWT.DRAG is the only value received - // https://bugs.eclipse.org/bugs/show_bug.cgi?id=310310 - if (e.detail == SWT.DRAG) { - fTimeProvider.setStartFinishTime(time0, time1); - } else { - fTimeProvider.setStartFinishTimeNotify(time0, time1); - } - } - } - - @Override - public int getBorderWidth() { - return fBorderWidth; - } - - /** - * Set the border width - * - * @param borderWidth - * The width - */ - public void setBorderWidth(int borderWidth) { - this.fBorderWidth = borderWidth; - } - - /** - * @return The current height of the header row - */ - public int getHeaderHeight() { - return fHeaderHeight; - } - - /** - * Set the height of the header row - * - * @param headerHeight - * The height - */ - public void setHeaderHeight(int headerHeight) { - this.fHeaderHeight = headerHeight; - } - - /** - * @return The default height of regular item rows - */ - public int getItemHeight() { - return fGlobalItemHeight; - } - - /** - * Set the default height of regular item rows. - * - * @param rowHeight - * The height - */ - public void setItemHeight(int rowHeight) { - this.fGlobalItemHeight = rowHeight; - } - - /** - * Set the height of a specific item. Overrides the default item height. - * - * @param entry - * A time graph entry - * @param rowHeight - * The height - * @return true if the height is successfully stored, false otherwise - * - * @since 2.1 - */ - public boolean setItemHeight(ITimeGraphEntry entry, int rowHeight) { - Item item = fItemData.findItem(entry); - if (item != null) { - item.fItemHeight = rowHeight; - return true; - } - return false; - } - - /** - * Set the minimum item width - * - * @param width The minimum width - */ - public void setMinimumItemWidth(int width) { - this.fMinimumItemWidth = width; - } - - /** - * @return The minimum item width - */ - public int getMinimumItemWidth() { - return fMinimumItemWidth; - } - - /** - * @return The entries that are currently filtered out - * - * @since 2.0 - */ - public List getFilteredOut() { - return fItemData.getFilteredOut(); - } - - @Override - public void addSelectionChangedListener(ISelectionChangedListener listener) { - if (listener != null && !fSelectionChangedListeners.contains(listener)) { - fSelectionChangedListeners.add(listener); - } - } - - @Override - public void removeSelectionChangedListener(ISelectionChangedListener listener) { - if (listener != null) { - fSelectionChangedListeners.remove(listener); - } - } - - @Override - public void setSelection(ISelection selection) { - if (selection instanceof TimeGraphSelection) { - TimeGraphSelection sel = (TimeGraphSelection) selection; - Object ob = sel.getFirstElement(); - if (ob instanceof ITimeGraphEntry) { - ITimeGraphEntry trace = (ITimeGraphEntry) ob; - selectItem(trace, false); - } - } - - } - - /** - * @param filter The filter object to be attached to the view - * @since 2.0 - */ - public void addFilter(ViewerFilter filter) { - if (!fFilters.contains(filter)) { - fFilters.add(filter); - } - } - - /** - * @param filter The filter object to be attached to the view - * @since 2.0 - */ - public void removeFilter(ViewerFilter filter) { - fFilters.remove(filter); - } - - /** - * @since 3.0 - */ - @Override - public void colorSettingsChanged(StateItem[] stateItems) { - /* Destroy previous colors from the resource manager */ - if (fEventColorMap != null) { - for (Color color : fEventColorMap) { - fResourceManager.destroyColor(color.getRGB()); - } - } - if (stateItems != null) { - fEventColorMap = new Color[stateItems.length]; - for (int i = 0; i < stateItems.length; i++) { - fEventColorMap[i] = fResourceManager.createColor(stateItems[i].getStateColor()); - } - } else { - fEventColorMap = new Color[] { }; - } - redraw(); - } - - private class ItemData { - private final Map fItemMap = new LinkedHashMap<>(); - private Item[] fExpandedItems = new Item[0]; - private Item[] fItems = new Item[0]; - private ITimeGraphEntry fRootEntries[] = new ITimeGraphEntry[0]; - private List fLinks = new ArrayList<>(); - private boolean fEntryFilter[] = new boolean[0]; - private final ArrayList fFilteredOut = new ArrayList<>(); - - public ItemData() { - } - - public Item findItem(ITimeGraphEntry entry) { - return fItemMap.get(entry); - } - - public int findItemIndex(ITimeGraphEntry entry) { - Item item = fItemMap.get(entry); - if (item == null) { - return -1; - } - return item.fExpandedIndex; - } - - public void refreshData() { - fItemMap.clear(); - fFilteredOut.clear(); - ITimeGraphEntry selection = getSelectedTrace(); - for (int i = 0; i < fRootEntries.length; i++) { - ITimeGraphEntry entry = fRootEntries[i]; - refreshData(fItemMap, null, 0, entry); - } - fItems = fItemMap.values().toArray(new Item[0]); - updateExpandedItems(); - if (selection != null) { - for (Item item : fExpandedItems) { - if (item.fEntry == selection) { - item.fSelected = true; - break; - } - } - } - } - - private void refreshData(Map itemMap, Item parent, int level, ITimeGraphEntry entry) { - Item item = new Item(entry, entry.getName(), level); - if (parent != null) { - parent.fChildren.add(item); - } - if (fGlobalItemHeight == CUSTOM_ITEM_HEIGHT) { - item.fItemHeight = fTimeGraphProvider.getItemHeight(entry); - } else { - item.fItemHeight = fGlobalItemHeight; - } - itemMap.put(entry, item); - if (entry.hasChildren()) { - item.fExpanded = fAutoExpandLevel == ALL_LEVELS || level < fAutoExpandLevel; - item.fHasChildren = true; - for (ITimeGraphEntry child : entry.getChildren()) { - refreshData(itemMap, item, level + 1, child); - } - } - } - - public void updateExpandedItems() { - for (Item item : fItems) { - item.fExpandedIndex = -1; - } - List expandedItemList = new ArrayList<>(); - for (int i = 0; i < fRootEntries.length; i++) { - ITimeGraphEntry entry = fRootEntries[i]; - Item item = findItem(entry); - refreshExpanded(expandedItemList, item); - } - fExpandedItems = expandedItemList.toArray(new Item[0]); - fTopIndex = Math.min(fTopIndex, Math.max(0, fExpandedItems.length - 1)); - } - - private void refreshExpanded(List expandedItemList, Item item) { - // Check for filters - boolean display = true; - for (ViewerFilter filter : fFilters) { - if (!filter.select(null, item.fEntry.getParent(), item.fEntry)) { - display = false; - break; - } - } - if (display) { - item.fExpandedIndex = expandedItemList.size(); - expandedItemList.add(item); - if (item.fHasChildren && item.fExpanded) { - for (Item child : item.fChildren) { - refreshExpanded(expandedItemList, child); - } - } - } - } - - public void refreshData(ITimeGraphEntry[] entries) { - if (entries == null) { - fEntryFilter = null; - fRootEntries = null; - } else { - if (entries.length == 0) { - fEntryFilter = null; - } else if (fEntryFilter == null || entries.length != fEntryFilter.length) { - fEntryFilter = new boolean[entries.length]; - java.util.Arrays.fill(fEntryFilter, true); - } - fRootEntries = Arrays.copyOf(entries, entries.length); - } - - refreshData(); - } - - public void refreshArrows(List events) { - /* If links are null, reset the list */ - if (events != null) { - fLinks = events; - } else { - fLinks = new ArrayList<>(); - } - } - - public ITimeGraphEntry[] getEntries() { - return fRootEntries; - } - - public boolean[] getEntryFilter() { - return fEntryFilter; - } - - public List getFilteredOut() { - return fFilteredOut; - } - } - - private class Item { - private boolean fExpanded; - private int fExpandedIndex; - private boolean fSelected; - private boolean fHasChildren; - private int fItemHeight; - private final int fLevel; - private final List fChildren; - private final String fName; - private final ITimeGraphEntry fEntry; - - public Item(ITimeGraphEntry entry, String name, int level) { - this.fEntry = entry; - this.fName = name; - this.fLevel = level; - this.fChildren = new ArrayList<>(); - } - - @Override - public String toString() { - return fName; - } - } - - /** - * @since 1.2 - */ - @Override - public void menuDetected(MenuDetectEvent e) { - if (null == fTimeProvider) { - return; - } - if (e.detail == SWT.MENU_MOUSE) { - if (fPendingMenuDetectEvent == null) { - /* Feature in Linux. The MenuDetectEvent is received before mouseDown. - * Store the event and trigger it later just before handling mouseUp. - * This allows for the method to detect if mouse is used to drag zoom. - */ - fPendingMenuDetectEvent = e; - return; - } - fPendingMenuDetectEvent = null; - if (fDragState != DRAG_ZOOM || fDragX != fDragX0) { - return; - } - } else { - if (fDragState != DRAG_NONE) { - return; - } - } - Point p = toControl(e.x, e.y); - int idx = getItemIndexAtY(p.y); - if (idx >= 0 && idx < fItemData.fExpandedItems.length) { - Item item = fItemData.fExpandedItems[idx]; - ITimeGraphEntry entry = item.fEntry; - if (entry.hasTimeEvents()) { - ITimeEvent event = Utils.findEvent(entry, getTimeAtX(p.x), 2); - if (event != null) { - e.data = event; - fireMenuEventOnTimeEvent(e); - return; - } - } - e.data = entry; - fireMenuEventOnTimeGraphEntry(e); - } - } - -} - - diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphScale.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphScale.java deleted file mode 100644 index 28642b55d6..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphScale.java +++ /dev/null @@ -1,859 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2007, 2014 Intel Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Intel Corporation - Initial API and implementation - * Ruslan A. Scherbakov, Intel - Initial API and implementation - * Alvaro Sanchez-Leon - Updated for TMF - * Patrick Tasse - Refactoring - * Marc-Andre Laperle - Add time zone preference - *****************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets; - -import java.text.NumberFormat; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.TimeZone; - -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfTimestampFormatUpdateSignal; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimePreferences; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.Resolution; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Composite; - -/** - * Implementation of the scale for the time graph view. - * - * This goes above the "gantt chart" area. - * - * @version 1.0 - * @author Alvaro Sanchez-Leon - * @author Patrick Tasse - */ -public class TimeGraphScale extends TimeGraphBaseControl implements - MouseListener, MouseMoveListener { - - private static final long MICROSEC_IN_NS = 1000; - private static final long MILLISEC_IN_NS = 1000000; - private static final long SEC_IN_NS = 1000000000; - private static final long MIN_IN_NS = 60 * SEC_IN_NS; - private static final long HOUR_IN_NS = 60 * MIN_IN_NS; - private static final long DAY_IN_NS = 24 * HOUR_IN_NS; - private static final long MONTH_IN_NS = 31 * DAY_IN_NS; // upper limit - private static final long YEAR_IN_NS = 366 * DAY_IN_NS; // upper limit - - private static final double LOG10_1 = Math.log10(1); - private static final double LOG10_2 = Math.log10(2); - private static final double LOG10_3 = Math.log10(3); - private static final double LOG10_5 = Math.log10(5); - - private static final Calendar GREGORIAN_CALENDAR = Calendar.getInstance(); - - private static final TimeDraw TIMEDRAW_NANOSEC = new TimeDrawNanosec(); - private static final TimeDraw TIMEDRAW_MICROSEC = new TimeDrawMicrosec(); - private static final TimeDraw TIMEDRAW_MILLISEC = new TimeDrawMillisec(); - private static final TimeDraw TIMEDRAW_SEC = new TimeDrawSec(); - private static final TimeDraw TIMEDRAW_ABS_NANOSEC = new TimeDrawAbsNanoSec(); - private static final TimeDraw TIMEDRAW_ABS_MICROSEC = new TimeDrawAbsMicroSec(); - private static final TimeDraw TIMEDRAW_ABS_MILLISEC = new TimeDrawAbsMillisec(); - private static final TimeDraw TIMEDRAW_ABS_SEC = new TimeDrawAbsSec(); - private static final TimeDraw TIMEDRAW_ABS_MIN = new TimeDrawAbsMin(); - private static final TimeDraw TIMEDRAW_ABS_HRS = new TimeDrawAbsHrs(); - private static final TimeDraw TIMEDRAW_ABS_DAY = new TimeDrawAbsDay(); - private static final TimeDraw TIMEDRAW_ABS_MONTH = new TimeDrawAbsMonth(); - private static final TimeDraw TIMEDRAW_ABS_YEAR = new TimeDrawAbsYear(); - private static final TimeDraw TIMEDRAW_NUMBER = new TimeDrawNumber(); - private static final TimeDraw TIMEDRAW_CYCLES = new TimeDrawCycles(); - - private static final int DRAG_EXTERNAL = -1; - private static final int NO_BUTTON = 0; - private static final int LEFT_BUTTON = 1; - - private ITimeDataProvider fTimeProvider; - private int fDragState = NO_BUTTON; - private int fDragX0 = 0; - private int fDragX = 0; - private long fTime0bak; - private long fTime1bak; - private boolean fIsInUpdate; - private int fHeight; - - /** - * Standard constructor - * - * @param parent - * The parent composite object - * @param colors - * The color scheme to use - */ - public TimeGraphScale(Composite parent, TimeGraphColorScheme colors) { - super(parent, colors, SWT.NO_BACKGROUND | SWT.NO_FOCUS | SWT.DOUBLE_BUFFERED); - TmfSignalManager.register(this); - addMouseListener(this); - addMouseMoveListener(this); - TimeDraw.updateTimeZone(); - } - - @Override - public void dispose() { - TmfSignalManager.deregister(this); - super.dispose(); - } - - /** - * Assign the time provider for this scale - * - * @param timeProvider - * The provider to use - */ - public void setTimeProvider(ITimeDataProvider timeProvider) { - fTimeProvider = timeProvider; - } - - /** - * Get the time provider used by this scale - * - * @return The time provider - * @since 3.2 - */ - public ITimeDataProvider getTimeProvider() { - return fTimeProvider; - } - - @Override - public Point computeSize(int wHint, int hHint, boolean changed) { - return super.computeSize(wHint, fHeight, changed); - } - - /** - * Set the height of the scale - * - * @param height - * The height to use - */ - public void setHeight(int height) { - this.fHeight = height; - } - - /** - * Set the drag range to paint decorators - * - * @param begin - * The begin x-coordinate - * @param end - * The end x-coordinate - * @since 2.1 - */ - public void setDragRange(int begin, int end) { - if (NO_BUTTON == fDragState || DRAG_EXTERNAL == fDragState) { - fDragX0 = begin - fTimeProvider.getNameSpace(); - fDragX = end - fTimeProvider.getNameSpace(); - if (begin >= 0 || end >= 0) { - fDragState = DRAG_EXTERNAL; - } else { - fDragState = NO_BUTTON; - } - } - redraw(); - } - - private long calcTimeDelta(int width, double pixelsPerNanoSec) { - long timeDelta; - double minDelta = (pixelsPerNanoSec == 0) ? YEAR_IN_NS : width / pixelsPerNanoSec; - long unit = 1; - if (fTimeProvider != null && fTimeProvider.getTimeFormat() == TimeFormat.CALENDAR) { - if (minDelta > 6 * MONTH_IN_NS) { - unit = YEAR_IN_NS; - } else if (minDelta > 3 * MONTH_IN_NS) { - unit = 6 * MONTH_IN_NS; - } else if (minDelta > 10 * DAY_IN_NS) { - unit = MONTH_IN_NS; - } else if (minDelta > 12 * HOUR_IN_NS) { - unit = DAY_IN_NS; - } else if (minDelta > 3 * HOUR_IN_NS) { - unit = 6 * HOUR_IN_NS; - } else if (minDelta > 30 * MIN_IN_NS) { - unit = HOUR_IN_NS; - } else if (minDelta > 10 * MIN_IN_NS) { - unit = 15 * MIN_IN_NS; - } else if (minDelta > 30 * SEC_IN_NS) { - unit = MIN_IN_NS; - } else if (minDelta > 20 * SEC_IN_NS) { - unit = 30 * SEC_IN_NS; - } else if (minDelta <= 1) { - timeDelta = 1; - return timeDelta; - } - } - double log = Math.log10(minDelta / unit); - long pow10 = (long) log; - double remainder = log - pow10; - if (remainder < LOG10_1) { - timeDelta = (long) Math.pow(10, pow10) * unit; - } else if (remainder < LOG10_2) { - timeDelta = 2 * (long) Math.pow(10, pow10) * unit; - } else if (remainder < LOG10_3 && unit >= HOUR_IN_NS && unit < YEAR_IN_NS) { - timeDelta = 3 * (long) Math.pow(10, pow10) * unit; - } else if (remainder < LOG10_5) { - timeDelta = 5 * (long) Math.pow(10, pow10) * unit; - } else { - timeDelta = 10 * (long) Math.pow(10, pow10) * unit; - } - if (timeDelta <= 0) { - timeDelta = 1; - } - return timeDelta; - } - - TimeDraw getTimeDraw(long timeDelta) { - TimeDraw timeDraw; - if (fTimeProvider != null) { - switch (fTimeProvider.getTimeFormat()) { - case CALENDAR: - if (timeDelta >= YEAR_IN_NS) { - timeDraw = TIMEDRAW_ABS_YEAR; - } else if (timeDelta >= MONTH_IN_NS) { - timeDraw = TIMEDRAW_ABS_MONTH; - } else if (timeDelta >= DAY_IN_NS) { - timeDraw = TIMEDRAW_ABS_DAY; - } else if (timeDelta >= HOUR_IN_NS) { - timeDraw = TIMEDRAW_ABS_HRS; - } else if (timeDelta >= MIN_IN_NS) { - timeDraw = TIMEDRAW_ABS_MIN; - } else if (timeDelta >= SEC_IN_NS) { - timeDraw = TIMEDRAW_ABS_SEC; - } else if (timeDelta >= MILLISEC_IN_NS) { - timeDraw = TIMEDRAW_ABS_MILLISEC; - } else if (timeDelta >= MICROSEC_IN_NS) { - timeDraw = TIMEDRAW_ABS_MICROSEC; - } else { - timeDraw = TIMEDRAW_ABS_NANOSEC; - } - return timeDraw; - case NUMBER: - return TIMEDRAW_NUMBER; - case CYCLES: - return TIMEDRAW_CYCLES; - case RELATIVE: - default: - } - - } - if (timeDelta >= SEC_IN_NS) { - timeDraw = TIMEDRAW_SEC; - } else if (timeDelta >= MILLISEC_IN_NS) { - timeDraw = TIMEDRAW_MILLISEC; - } else if (timeDelta >= MICROSEC_IN_NS) { - timeDraw = TIMEDRAW_MICROSEC; - } else { - timeDraw = TIMEDRAW_NANOSEC; - } - return timeDraw; - } - - @Override - void paint(Rectangle rect, PaintEvent e) { - - if (fIsInUpdate || null == fTimeProvider) { - return; - } - - GC gc = e.gc; - gc.fillRectangle(rect); - - long time0 = fTimeProvider.getTime0(); - long time1 = fTimeProvider.getTime1(); - int leftSpace = fTimeProvider.getNameSpace(); - int timeSpace = fTimeProvider.getTimeSpace(); - - gc.setBackground(getColorScheme().getColor(TimeGraphColorScheme.TOOL_BACKGROUND)); - gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.TOOL_FOREGROUND)); - Rectangle rect0 = new Rectangle(0, 0, 0, 0); - Utils.init(rect0, rect); - - // draw top left area - rect0.width = leftSpace; - rect0.x += 4; - rect0.width -= 4; - Rectangle absHeaderRect = new Rectangle(rect0.x, rect0.y, rect0.width, rect0.height); - rect0.x -= 4; - rect0.width += 4; - - // prepare and draw right rect of the timescale - rect0.x += leftSpace; - rect0.width = rect.width - leftSpace; - - // draw bottom border and erase all other area - gc.drawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width - 1, - rect.y + rect.height - 1); - rect0.height--; - gc.fillRectangle(rect0); - - if (time1 <= time0 || timeSpace < 2) { - return; - } - - int numDigits = calculateDigits(time0, time1); - - int labelWidth = gc.getCharWidth('0') * numDigits; - double pixelsPerNanoSec = (timeSpace <= RIGHT_MARGIN) ? 0 : - (double) (timeSpace - RIGHT_MARGIN) / (time1 - time0); - long timeDelta = calcTimeDelta(labelWidth, pixelsPerNanoSec); - - TimeDraw timeDraw = getTimeDraw(timeDelta); - - // draw range decorators - if (DRAG_EXTERNAL == fDragState) { - int x1 = leftSpace + Math.min(fDragX0, fDragX); - int x2 = leftSpace + Math.max(fDragX0, fDragX); - drawRangeDecorators(rect0, gc, x1, x2); - } else { - int x1; - int x2; - long selectionBegin = fTimeProvider.getSelectionBegin(); - long selectionEnd = fTimeProvider.getSelectionEnd(); - x1 = leftSpace + (int) ((selectionBegin - time0) * pixelsPerNanoSec); - x2 = leftSpace + (int) ((selectionEnd - time0) * pixelsPerNanoSec); - drawRangeDecorators(rect0, gc, x1, x2); - } - - if (rect0.isEmpty()) { - return; - } - - // draw time scale ticks - rect0.y = rect.y; - rect0.height = rect.height - 4; - rect0.width = labelWidth; - - long time; - if (fTimeProvider != null && fTimeProvider.getTimeFormat() == TimeFormat.CALENDAR) { - time = floorToCalendar(time0, timeDelta); - } else { - time = (time0 / timeDelta) * timeDelta; - if (time != time0) { - time += timeDelta; - } - } - - int y = rect0.y + rect0.height; - - if (fTimeProvider != null && fTimeProvider.getTimeFormat() == TimeFormat.CALENDAR) { - timeDraw.drawAbsHeader(gc, time, absHeaderRect); - } - - while (true) { - int x = rect.x + leftSpace + (int) (Math.floor((time - time0) * pixelsPerNanoSec)); - if (x >= rect.x + leftSpace + rect.width - rect0.width) { - break; - } - if (x >= rect.x + leftSpace) { - gc.drawLine(x, y, x, y + 4); - rect0.x = x; - if (x + rect0.width <= rect.x + rect.width) { - timeDraw.draw(gc, time, rect0); - } - } - if (pixelsPerNanoSec == 0 || time > Long.MAX_VALUE - timeDelta || timeDelta == 0) { - break; - } - if (fTimeProvider != null && fTimeProvider.getTimeFormat() == TimeFormat.CALENDAR) { - if (timeDelta >= YEAR_IN_NS) { - long millis = time / MILLISEC_IN_NS; - GREGORIAN_CALENDAR.setTime(new Date(millis)); - GREGORIAN_CALENDAR.add(Calendar.YEAR, (int) (timeDelta / YEAR_IN_NS)); - millis = GREGORIAN_CALENDAR.getTimeInMillis(); - time = millis * MILLISEC_IN_NS; - } else if (timeDelta >= MONTH_IN_NS) { - long millis = time / MILLISEC_IN_NS; - GREGORIAN_CALENDAR.setTime(new Date(millis)); - GREGORIAN_CALENDAR.add(Calendar.MONTH, (int) (timeDelta / MONTH_IN_NS)); - millis = GREGORIAN_CALENDAR.getTimeInMillis(); - time = millis * MILLISEC_IN_NS; - } else if (timeDelta >= DAY_IN_NS) { - long millis = time / MILLISEC_IN_NS; - GREGORIAN_CALENDAR.setTime(new Date(millis)); - GREGORIAN_CALENDAR.add(Calendar.DAY_OF_MONTH, (int) (timeDelta / DAY_IN_NS)); - millis = GREGORIAN_CALENDAR.getTimeInMillis(); - time = millis * MILLISEC_IN_NS; - } else { - time += timeDelta; - } - } else { - time += timeDelta; - } - } - } - - private static void drawRangeDecorators(Rectangle rect, GC gc, int x1, int x2) { - int y1 = rect.y + rect.height - 9; - int y2 = rect.y + rect.height - 5; - int ym = (y1 + y2) / 2; - if (x1 >= rect.x) { - // T1 - gc.drawLine(x1 - 3, y1, x1 - 3, y2); - gc.drawLine(x1 - 4, y1, x1 - 2, y1); - gc.drawLine(x1, y1, x1, y2); - } - if (x2 >= rect.x && x2 - x1 > 3) { - // T2 - gc.drawLine(x2 - 2, y1, x2 - 2, y2); - gc.drawLine(x2 - 3, y1, x2 - 1, y1); - } - if (x2 >= rect.x && x2 - x1 > 0) { - gc.drawLine(x2 + 1, y1, x2 + 3, y1); - gc.drawLine(x2 + 3, y1, x2 + 3, ym); - gc.drawLine(x2 + 1, ym, x2 + 3, ym); - gc.drawLine(x2 + 1, ym, x2 + 1, y2); - gc.drawLine(x2 + 1, y2, x2 + 3, y2); - } - } - - private static long floorToCalendar(long time, long timeDelta) { - long ret = time; - - if (timeDelta >= YEAR_IN_NS) { - GREGORIAN_CALENDAR.setTime(new Date(ret / MILLISEC_IN_NS)); - int year = GREGORIAN_CALENDAR.get(Calendar.YEAR); - int yearDelta = (int) (timeDelta / YEAR_IN_NS); - year = (year / yearDelta) * yearDelta; - GREGORIAN_CALENDAR.set(Calendar.YEAR, year); - GREGORIAN_CALENDAR.set(Calendar.MONTH, 0); // January 1st of year - GREGORIAN_CALENDAR.set(Calendar.DAY_OF_MONTH, 1); - GREGORIAN_CALENDAR.set(Calendar.HOUR_OF_DAY, 0); - GREGORIAN_CALENDAR.set(Calendar.MINUTE, 0); - GREGORIAN_CALENDAR.set(Calendar.SECOND, 0); - GREGORIAN_CALENDAR.set(Calendar.MILLISECOND, 0); - ret = GREGORIAN_CALENDAR.getTimeInMillis() * MILLISEC_IN_NS; - } else if (timeDelta >= MONTH_IN_NS) { - GREGORIAN_CALENDAR.setTime(new Date(ret / MILLISEC_IN_NS)); - int month = GREGORIAN_CALENDAR.get(Calendar.MONTH); - int monthDelta = (int) (timeDelta / MONTH_IN_NS); - month = (month / monthDelta) * monthDelta; - GREGORIAN_CALENDAR.set(Calendar.MONTH, month); - GREGORIAN_CALENDAR.set(Calendar.DAY_OF_MONTH, 1); // 1st of month - GREGORIAN_CALENDAR.set(Calendar.HOUR_OF_DAY, 0); - GREGORIAN_CALENDAR.set(Calendar.MINUTE, 0); - GREGORIAN_CALENDAR.set(Calendar.SECOND, 0); - GREGORIAN_CALENDAR.set(Calendar.MILLISECOND, 0); - ret = GREGORIAN_CALENDAR.getTimeInMillis() * MILLISEC_IN_NS; - } else { - long offset = GREGORIAN_CALENDAR.getTimeZone().getOffset(ret / MILLISEC_IN_NS) * MILLISEC_IN_NS; - ret += offset; - ret = (ret / timeDelta) * timeDelta; - ret -= offset; - } - return ret; - } - - private int calculateDigits(long time0, long time1) { - int numDigits = 5; - long timeRange = time1 - time0; - - if (fTimeProvider.getTimeFormat() == TimeFormat.CALENDAR) { - // Calculate the number of digits to represent the minutes provided - // 11:222 - // HH:mm:ss - numDigits += 8; - if (timeRange < 10000) { - // HH:11:222:333:444__ - numDigits += 10; - } else if (timeRange < 10000000) { - // HH:11:222:333__ - numDigits += 6; - } - } else { - long sec = time1 / SEC_IN_NS; - numDigits = Long.toString(sec).length(); - int thousandGroups = (numDigits - 1) / 3; - numDigits += thousandGroups; - numDigits += 12; // .000 000 000 - if (fTimeProvider.getTimeFormat() == TimeFormat.CYCLES) { - numDigits += Messages.Utils_ClockCyclesUnit.length(); - } - } - - return numDigits; - } - - @Override - public void mouseDown(MouseEvent e) { - getParent().setFocus(); - if (fDragState == NO_BUTTON && null != fTimeProvider) { - int x = e.x - fTimeProvider.getNameSpace(); - if (LEFT_BUTTON == e.button && x > 0) { - setCapture(true); - fDragState = LEFT_BUTTON; - } - if (x < 0) { - x = 0; - } else if (x > getSize().x - fTimeProvider.getNameSpace()) { - x = getSize().x - fTimeProvider.getNameSpace(); - } - fDragX = x; - fDragX0 = x; - fTime0bak = fTimeProvider.getTime0(); - fTime1bak = fTimeProvider.getTime1(); - } - } - - @Override - public void mouseUp(MouseEvent e) { - if (e.button == LEFT_BUTTON && fDragState == LEFT_BUTTON) { - setCapture(false); - fDragState = NO_BUTTON; - - // Notify time provider to check the need for listener notification - if (fDragX != fDragX0 && fTimeProvider.getTime0() != fTimeProvider.getTime1()) { - fTimeProvider.setStartFinishTimeNotify(fTimeProvider.getTime0(), fTimeProvider.getTime1()); - } - } - } - - @Override - public void mouseMove(MouseEvent e) { - if (fDragX0 < 0 || fDragState == NO_BUTTON || fTimeProvider == null) { - return; - } - Point size = getSize(); - int leftSpace = fTimeProvider.getNameSpace(); - int x = e.x - leftSpace; - if (LEFT_BUTTON == fDragState) { - if (x > 0 && size.x > leftSpace && fDragX != x) { - fDragX = x; - if (fTimeProvider.getTime0() == fTimeProvider.getTime1()) { - return; - } - long interval = (long) ((fTime1bak - fTime0bak) * ((double) fDragX0 / fDragX)); - if (interval == Long.MAX_VALUE) { - fTimeProvider.setStartFinishTime(fTime0bak, Long.MAX_VALUE); - } else { - long time1 = fTime0bak + (long) ((fTime1bak - fTime0bak) * ((double) fDragX0 / fDragX)); - fTimeProvider.setStartFinishTime(fTime0bak, time1); - } - } - } - } - - @Override - public void mouseDoubleClick(MouseEvent e) { - if (e.button == 1 && null != fTimeProvider && fTimeProvider.getTime0() != fTimeProvider.getTime1() && (e.stateMask & SWT.BUTTON_MASK) == 0) { - fTimeProvider.resetStartFinishTime(); - fTimeProvider.notifyStartFinishTime(); - fTime0bak = fTimeProvider.getTime0(); - fTime1bak = fTimeProvider.getTime1(); - } - } - - /** - * Update the display to use the updated timestamp format - * - * @param signal the incoming signal - * @since 2.1 - */ - @TmfSignalHandler - public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) { - TimeDraw.updateTimeZone(); - Utils.updateTimeZone(); - redraw(); - } -} - -abstract class TimeDraw { - protected static final long MICROSEC_IN_NS = 1000; - protected static final long MILLISEC_IN_NS = 1000000; - protected static final long MILLISEC_IN_US = 1000; - protected static final long SEC_IN_NS = 1000000000; - protected static final long SEC_IN_MS = 1000; - private static final String S = "" ; //$NON-NLS-1$ - private static final String S0 = "0" ; //$NON-NLS-1$ - private static final String S00 = "00"; //$NON-NLS-1$ - protected static final long PAD_1000 = 1000; - protected static final SimpleDateFormat SEC_FORMAT_HEADER = new SimpleDateFormat("yyyy MMM dd"); //$NON-NLS-1$ - protected static final SimpleDateFormat SEC_FORMAT = new SimpleDateFormat("HH:mm:ss"); //$NON-NLS-1$ - protected static final SimpleDateFormat MIN_FORMAT_HEADER = new SimpleDateFormat("yyyy MMM dd"); //$NON-NLS-1$ - protected static final SimpleDateFormat MIN_FORMAT = new SimpleDateFormat("HH:mm"); //$NON-NLS-1$ - protected static final SimpleDateFormat HOURS_FORMAT_HEADER = new SimpleDateFormat("yyyy"); //$NON-NLS-1$ - protected static final SimpleDateFormat HOURS_FORMAT = new SimpleDateFormat("MMM dd HH:mm"); //$NON-NLS-1$ - protected static final SimpleDateFormat DAY_FORMAT_HEADER = new SimpleDateFormat("yyyy"); //$NON-NLS-1$ - protected static final SimpleDateFormat DAY_FORMAT = new SimpleDateFormat("MMM dd"); //$NON-NLS-1$ - protected static final SimpleDateFormat MONTH_FORMAT = new SimpleDateFormat("yyyy MMM"); //$NON-NLS-1$ - protected static final SimpleDateFormat YEAR_FORMAT = new SimpleDateFormat("yyyy"); //$NON-NLS-1$ - - protected static final SimpleDateFormat formatArray[] = { - SEC_FORMAT, SEC_FORMAT_HEADER, MIN_FORMAT, MIN_FORMAT_HEADER, - HOURS_FORMAT, HOURS_FORMAT_HEADER, DAY_FORMAT, DAY_FORMAT_HEADER, MONTH_FORMAT, YEAR_FORMAT - }; - - /** - * Updates the timezone using the preferences. - */ - public static void updateTimeZone() { - final TimeZone timeZone = TmfTimePreferences.getInstance().getTimeZone(); - for (SimpleDateFormat sdf : formatArray) { - sdf.setTimeZone(timeZone); - } - } - - static String sep(long n) { - StringBuilder retVal = new StringBuilder(); - String s = Long.toString(n); - for (int i = 0; i < s.length(); i++) { - int pos = s.length() - i - 1; - retVal.append(s.charAt(i)); - if (pos % 3 == 0 && pos != 0) { - retVal.append(' '); - } - } - return retVal.toString(); - } - - static String pad(long n) { - String s; - if (n < 10) { - s = S00; - } else if (n < 100) { - s = S0; - } else { - s = S; - } - return s + n; - } - - public abstract int draw(GC gc, long time, Rectangle rect); - - /** - * Override to draw absolute time header. This is for the time information - * not shown in the draw of each tick - * - * @param gc - * Graphics context - * @param nanosec - * time in nanosec - * @param absHeaderRect - * Header rectangle - */ - public void drawAbsHeader(GC gc, long nanosec, Rectangle absHeaderRect) { - } -} - -class TimeDrawSec extends TimeDraw { - @Override - public int draw(GC gc, long nanosec, Rectangle rect) { - long sec = nanosec / SEC_IN_NS; - return Utils.drawText(gc, sep(sec), rect, true); - } -} - -class TimeDrawMillisec extends TimeDraw { - @Override - public int draw(GC gc, long nanosec, Rectangle rect) { - long millisec = nanosec / MILLISEC_IN_NS; - long ms = millisec % PAD_1000; - long sec = millisec / SEC_IN_MS; - return Utils.drawText(gc, sep(sec) + "." + pad(ms), rect, true); //$NON-NLS-1$ - } -} - -class TimeDrawMicrosec extends TimeDraw { - @Override - public int draw(GC gc, long nanosec, Rectangle rect) { - long microsec = nanosec / MICROSEC_IN_NS; - long us = microsec % PAD_1000; - long millisec = microsec / MILLISEC_IN_US; - long ms = millisec % PAD_1000; - long sec = millisec / SEC_IN_MS; - return Utils.drawText(gc, sep(sec) + "." + pad(ms) + " " + pad(us), rect, true); //$NON-NLS-1$ //$NON-NLS-2$ - } -} - -class TimeDrawNanosec extends TimeDraw { - @Override - public int draw(GC gc, long nanosec, Rectangle rect) { - long ns = nanosec % PAD_1000; - long microsec = nanosec / MICROSEC_IN_NS; - long us = microsec % PAD_1000; - long millisec = microsec / MILLISEC_IN_US; - long ms = millisec % PAD_1000; - long sec = millisec / SEC_IN_MS; - return Utils.drawText(gc, sep(sec) + "." + pad(ms) + " " + pad(us) + " " + pad(ns), rect, true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } -} - -class TimeDrawAbsYear extends TimeDraw { - @Override - public int draw(GC gc, long nanosec, Rectangle rect) { - String stime = YEAR_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); - return Utils.drawText(gc, stime, rect, true); - } -} - -class TimeDrawAbsMonth extends TimeDraw { - @Override - public int draw(GC gc, long nanosec, Rectangle rect) { - String stime = MONTH_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); - return Utils.drawText(gc, stime, rect, true); - } -} - -class TimeDrawAbsDay extends TimeDraw { - @Override - public int draw(GC gc, long nanosec, Rectangle rect) { - String stime = DAY_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); - return Utils.drawText(gc, stime, rect, true); - } - - @Override - public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) { - String header = DAY_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS)); - int headerwidth = gc.stringExtent(header).x + 4; - if (headerwidth <= rect.width) { - rect.x += (rect.width - headerwidth); - Utils.drawText(gc, header, rect, true); - } - } -} - -class TimeDrawAbsHrs extends TimeDraw { - @Override - public int draw(GC gc, long nanosec, Rectangle rect) { - String stime = HOURS_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); - return Utils.drawText(gc, stime, rect, true); - } - - @Override - public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) { - String header = HOURS_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS)); - int headerwidth = gc.stringExtent(header).x + 4; - if (headerwidth <= rect.width) { - rect.x += (rect.width - headerwidth); - Utils.drawText(gc, header, rect, true); - } - } -} - -class TimeDrawAbsMin extends TimeDraw { - @Override - public int draw(GC gc, long nanosec, Rectangle rect) { - String stime = MIN_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); - return Utils.drawText(gc, stime, rect, true); - } - - @Override - public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) { - String header = MIN_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS)); - int headerwidth = gc.stringExtent(header).x + 4; - if (headerwidth <= rect.width) { - rect.x += (rect.width - headerwidth); - Utils.drawText(gc, header, rect, true); - } - } -} - -class TimeDrawAbsSec extends TimeDraw { - @Override - public int draw(GC gc, long nanosec, Rectangle rect) { - String stime = SEC_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); - return Utils.drawText(gc, stime, rect, true); - } - - @Override - public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) { - String header = SEC_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS)); - int headerwidth = gc.stringExtent(header).x + 4; - if (headerwidth <= rect.width) { - rect.x += (rect.width - headerwidth); - Utils.drawText(gc, header, rect, true); - } - } -} - -class TimeDrawAbsMillisec extends TimeDraw { - @Override - public int draw(GC gc, long nanosec, Rectangle rect) { - String stime = SEC_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); - String ns = Utils.formatNs(nanosec, Resolution.MILLISEC); - return Utils.drawText(gc, stime + "." + ns, rect, true); //$NON-NLS-1$ - } - - @Override - public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) { - String header = SEC_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS)); - int headerwidth = gc.stringExtent(header).x + 4; - if (headerwidth <= rect.width) { - rect.x += (rect.width - headerwidth); - Utils.drawText(gc, header, rect, true); - } - } -} - -class TimeDrawAbsMicroSec extends TimeDraw { - @Override - public int draw(GC gc, long nanosec, Rectangle rect) { - String stime = SEC_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); - String micr = Utils.formatNs(nanosec, Resolution.MICROSEC); - return Utils.drawText(gc, stime + "." + micr, rect, true); //$NON-NLS-1$ - } - - @Override - public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) { - String header = SEC_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS)); - int headerwidth = gc.stringExtent(header).x + 4; - if (headerwidth <= rect.width) { - rect.x += (rect.width - headerwidth); - Utils.drawText(gc, header, rect, true); - } - } -} - -class TimeDrawAbsNanoSec extends TimeDraw { - @Override - public int draw(GC gc, long nanosec, Rectangle rect) { - String stime = SEC_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); - String ns = Utils.formatNs(nanosec, Resolution.NANOSEC); - return Utils.drawText(gc, stime + "." + ns, rect, true); //$NON-NLS-1$ - } - - @Override - public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) { - String header = SEC_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS)); - int headerwidth = gc.stringExtent(header).x + 4; - if (headerwidth <= rect.width) { - rect.x += (rect.width - headerwidth); - Utils.drawText(gc, header, rect, true); - } - } -} - -class TimeDrawNumber extends TimeDraw { - @Override - public int draw(GC gc, long time, Rectangle rect) { - String stime = NumberFormat.getInstance().format(time); - return Utils.drawText(gc, stime, rect, true); - } -} - -class TimeDrawCycles extends TimeDraw { - @Override - public int draw(GC gc, long time, Rectangle rect) { - String stime = Utils.formatTime(time, TimeFormat.CYCLES, Resolution.SECONDS); - return Utils.drawText(gc, stime, rect, true); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphSelection.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphSelection.java deleted file mode 100644 index 355f0e1afe..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphSelection.java +++ /dev/null @@ -1,97 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2007, 2013 Intel Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Intel Corporation - Initial API and implementation - * Ruslan A. Scherbakov, Intel - Initial API and implementation - * Alvaro Sanchez-Leon - Updated for TMF - * Patrick Tasse - Refactoring - *****************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.jface.viewers.IStructuredSelection; - -/** - * Selection object for the time graph scale - * - * @version 1.0 - * @author Alvaro Sanchez-Leon - * @author Patrick Tasse - */ -public class TimeGraphSelection implements IStructuredSelection { - - private List list = new ArrayList<>(); - - /** - * Default constructor - */ - public TimeGraphSelection() { - } - - /** - * "Wrapper" constructor. Instantiate a new selection object with only one - * existing selection. - * - * @param sel - * The initial selection to add to this one - */ - public TimeGraphSelection(Object sel) { - if (sel != null) { - list.add(sel); - } - } - - /** - * Add a selection to this one. - * - * @param sel - * The selection to add - */ - public void add(Object sel) { - if (null != sel && !list.contains(sel)) { - list.add(sel); - } - } - - @Override - public Object getFirstElement() { - if (!list.isEmpty()) { - return list.get(0); - } - return null; - } - - @Override - public Iterator iterator() { - return list.iterator(); - } - - @Override - public int size() { - return list.size(); - } - - @Override - public Object[] toArray() { - return list.toArray(); - } - - @Override - public List toList() { - return list; - } - - @Override - public boolean isEmpty() { - return list.isEmpty(); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphTooltipHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphTooltipHandler.java deleted file mode 100644 index d3e885ea5b..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphTooltipHandler.java +++ /dev/null @@ -1,380 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2007, 2014 Intel Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Intel Corporation - Initial API and implementation - * Vitaly A. Provodin, Intel - Initial API and implementation - * Alvaro Sanchez-Leon - Updated for TMF - * Patrick Tasse - Refactoring - *****************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets; - -import java.util.Iterator; -import java.util.Map; - -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.NullTimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.Resolution; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.events.MouseTrackAdapter; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -/** - * Handler for the tool tips in the generic time graph view. - * - * @version 1.0 - * @author Alvaro Sanchez-Leon - * @author Patrick Tasse - */ -public class TimeGraphTooltipHandler { - - private static final int OFFSET = 16; - - private Shell fTipShell; - private Composite fTipComposite; - private ITimeDataProvider fTimeDataProvider; - private ITimeGraphPresentationProvider fTimeGraphProvider = null; - - /** - * Standard constructor - * - * @param graphProv - * The presentation provider - * @param timeProv - * The time provider - * - * @since 2.0 - */ - public TimeGraphTooltipHandler(ITimeGraphPresentationProvider graphProv, - ITimeDataProvider timeProv) { - - this.fTimeGraphProvider = graphProv; - this.fTimeDataProvider = timeProv; - } - - /** - * Set the time data provider - * - * @param timeDataProvider - * The time data provider - * - * @since 3.2 - */ - public void setTimeProvider(ITimeDataProvider timeDataProvider) { - fTimeDataProvider = timeDataProvider; - } - - private void createTooltipShell(Shell parent) { - final Display display = parent.getDisplay(); - if (fTipShell != null && ! fTipShell.isDisposed()) { - fTipShell.dispose(); - } - fTipShell = new Shell(parent, SWT.ON_TOP | SWT.TOOL); - GridLayout gridLayout = new GridLayout(); - gridLayout.numColumns = 2; - gridLayout.marginWidth = 2; - gridLayout.marginHeight = 2; - fTipShell.setLayout(gridLayout); - fTipShell.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); - - fTipComposite = new Composite(fTipShell, SWT.NONE); - fTipComposite.setLayout(new GridLayout(3, false)); - setupControl(fTipComposite); - - } - - /** - * Callback for the mouse-over tooltip - * - * @param control - * The control object to use - */ - public void activateHoverHelp(final Control control) { - control.addMouseListener(new MouseAdapter() { - @Override - public void mouseDown(MouseEvent e) { - if (fTipShell != null && ! fTipShell.isDisposed()) { - fTipShell.dispose(); - } - } - }); - - control.addMouseMoveListener(new MouseMoveListener() { - @Override - public void mouseMove(MouseEvent e) { - if (fTipShell != null && ! fTipShell.isDisposed()) { - fTipShell.dispose(); - } - } - }); - - control.addMouseTrackListener(new MouseTrackAdapter() { - @Override - public void mouseExit(MouseEvent e) { - if (fTipShell != null && ! fTipShell.isDisposed()) { - Point pt = control.toDisplay(e.x, e.y); - if (! fTipShell.getBounds().contains(pt)) { - fTipShell.dispose(); - } - } - } - - private void addItem(String name, String value) { - Label nameLabel = new Label(fTipComposite, SWT.NO_FOCUS); - nameLabel.setText(name); - setupControl(nameLabel); - Label separator = new Label(fTipComposite, SWT.NO_FOCUS | SWT.SEPARATOR | SWT.VERTICAL); - GridData gd = new GridData(SWT.CENTER, SWT.CENTER, false, false); - gd.heightHint = nameLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).y; - separator.setLayoutData(gd); - setupControl(separator); - Label valueLabel = new Label(fTipComposite, SWT.NO_FOCUS); - valueLabel.setText(value); - setupControl(valueLabel); - } - - private void fillValues(Point pt, TimeGraphControl timeGraphControl, ITimeGraphEntry entry) { - if (entry == null) { - return; - } - if (entry.hasTimeEvents()) { - long currPixelTime = timeGraphControl.getTimeAtX(pt.x); - long nextPixelTime = timeGraphControl.getTimeAtX(pt.x + 1); - if (nextPixelTime == currPixelTime) { - nextPixelTime++; - } - ITimeEvent currEvent = Utils.findEvent(entry, currPixelTime, 0); - ITimeEvent nextEvent = Utils.findEvent(entry, currPixelTime, 1); - - // if there is no current event at the start of the current pixel range, - // or if the current event starts before the current pixel range, - // use the next event as long as it starts within the current pixel range - if ((currEvent == null || currEvent.getTime() < currPixelTime) && - (nextEvent != null && nextEvent.getTime() < nextPixelTime)) { - currEvent = nextEvent; - currPixelTime = nextEvent.getTime(); - } - - // state name - String stateTypeName = fTimeGraphProvider.getStateTypeName(entry); - String entryName = entry.getName(); - if (stateTypeName == null) { - stateTypeName = fTimeGraphProvider.getStateTypeName(); - } - - if (!entryName.isEmpty()) { - addItem(stateTypeName, entry.getName()); - } - - if (currEvent == null || currEvent instanceof NullTimeEvent) { - return; - } - - // state - String state = fTimeGraphProvider.getEventName(currEvent); - if (state != null) { - addItem(Messages.TmfTimeTipHandler_TRACE_STATE, state); - } - - // This block receives a list of values to be added to the tip table - Map eventAddOns = fTimeGraphProvider.getEventHoverToolTipInfo(currEvent, currPixelTime); - if (eventAddOns != null) { - for (Iterator iter = eventAddOns.keySet().iterator(); iter.hasNext();) { - String message = iter.next(); - addItem(message, eventAddOns.get(message)); - } - } - if (fTimeGraphProvider.displayTimesInTooltip()) { - long eventStartTime = -1; - long eventDuration = -1; - long eventEndTime = -1; - - eventStartTime = currEvent.getTime(); - eventDuration = currEvent.getDuration(); - if (eventDuration < 0 && nextEvent != null) { - eventEndTime = nextEvent.getTime(); - eventDuration = eventEndTime - eventStartTime; - } else { - eventEndTime = eventStartTime + eventDuration; - } - - Resolution res = Resolution.NANOSEC; - TimeFormat tf = fTimeDataProvider.getTimeFormat(); - String startTime = "?"; //$NON-NLS-1$ - String duration = "?"; //$NON-NLS-1$ - String endTime = "?"; //$NON-NLS-1$ - if (fTimeDataProvider instanceof ITimeDataProviderConverter) { - ITimeDataProviderConverter tdp = (ITimeDataProviderConverter) fTimeDataProvider; - if (eventStartTime > -1) { - eventStartTime = tdp.convertTime(eventStartTime); - startTime = Utils.formatTime(eventStartTime, tf, res); - } - if (eventEndTime > -1) { - eventEndTime = tdp.convertTime(eventEndTime); - endTime = Utils.formatTime(eventEndTime, tf, res); - } - if (eventDuration > -1) { - duration = Utils.formatDelta(eventEndTime - eventStartTime, tf, res); - } - } else { - if (eventStartTime > -1) { - startTime = Utils.formatTime(eventStartTime, tf, res); - } - if (eventEndTime > -1) { - endTime = Utils.formatTime(eventEndTime, tf, res); - } - if (eventDuration > -1) { - duration = Utils.formatDelta(eventDuration, tf, res); - } - } - if (tf == TimeFormat.CALENDAR) { - addItem(Messages.TmfTimeTipHandler_TRACE_DATE, - eventStartTime > -1 ? Utils.formatDate(eventStartTime) : "?"); //$NON-NLS-1$ - } - if (eventDuration > 0) { - addItem(Messages.TmfTimeTipHandler_TRACE_START_TIME, startTime); - addItem(Messages.TmfTimeTipHandler_TRACE_STOP_TIME, endTime); - } else { - addItem(Messages.TmfTimeTipHandler_TRACE_EVENT_TIME, startTime); - } - - if (eventDuration > 0) { - addItem(Messages.TmfTimeTipHandler_DURATION, duration); - } - } - } - } - - private void fillValues(ILinkEvent linkEvent) { - addItem(Messages.TmfTimeTipHandler_LINK_SOURCE, linkEvent.getEntry().getName()); - addItem(Messages.TmfTimeTipHandler_LINK_TARGET, linkEvent.getDestinationEntry().getName()); - - // This block receives a list of values to be added to the tip table - Map eventAddOns = fTimeGraphProvider.getEventHoverToolTipInfo(linkEvent); - if (eventAddOns != null) { - for (Iterator iter = eventAddOns.keySet().iterator(); iter.hasNext();) { - String message = iter.next(); - addItem(message, eventAddOns.get(message)); - } - } - if (fTimeGraphProvider.displayTimesInTooltip()) { - long sourceTime = linkEvent.getTime(); - long duration = linkEvent.getDuration(); - long targetTime = sourceTime + duration; - if (fTimeDataProvider instanceof ITimeDataProviderConverter) { - ITimeDataProviderConverter tdp = (ITimeDataProviderConverter) fTimeDataProvider; - sourceTime = tdp.convertTime(sourceTime); - targetTime = tdp.convertTime(targetTime); - duration = targetTime - sourceTime; - } - Resolution res = Resolution.NANOSEC; - TimeFormat tf = fTimeDataProvider.getTimeFormat(); - if (tf == TimeFormat.CALENDAR) { - addItem(Messages.TmfTimeTipHandler_TRACE_DATE, Utils.formatDate(sourceTime)); - } - if (duration > 0) { - addItem(Messages.TmfTimeTipHandler_LINK_SOURCE_TIME, Utils.formatTime(sourceTime, tf, res)); - addItem(Messages.TmfTimeTipHandler_LINK_TARGET_TIME, Utils.formatTime(targetTime, tf, res)); - addItem(Messages.TmfTimeTipHandler_DURATION, Utils.formatDelta(duration, tf, res)); - } else { - addItem(Messages.TmfTimeTipHandler_LINK_TIME, Utils.formatTime(sourceTime, tf, res)); - } - } - } - - @Override - public void mouseHover(MouseEvent event) { - if ((event.stateMask & SWT.BUTTON_MASK) != 0) { - return; - } - Point pt = new Point(event.x, event.y); - TimeGraphControl timeGraphControl = (TimeGraphControl) event.widget; - createTooltipShell(timeGraphControl.getShell()); - for (Control child : fTipComposite.getChildren()) { - child.dispose(); - } - if ((event.stateMask & SWT.MODIFIER_MASK) != SWT.SHIFT) { - ILinkEvent linkEvent = timeGraphControl.getArrow(pt); - if (linkEvent != null) { - fillValues(linkEvent); - } - } - if (fTipComposite.getChildren().length == 0) { - ITimeGraphEntry entry = timeGraphControl.getEntry(pt); - fillValues(pt, timeGraphControl, entry); - } - if (fTipComposite.getChildren().length == 0) { - return; - } - fTipShell.pack(); - Point tipPosition = control.toDisplay(pt); - fTipShell.pack(); - setHoverLocation(fTipShell, tipPosition); - fTipShell.setVisible(true); - } - }); - } - - private static void setHoverLocation(Shell shell, Point position) { - Rectangle displayBounds = shell.getDisplay().getBounds(); - Rectangle shellBounds = shell.getBounds(); - if (position.x + shellBounds.width + OFFSET > displayBounds.width && position.x - shellBounds.width - OFFSET >= 0) { - shellBounds.x = position.x - shellBounds.width - OFFSET; - } else { - shellBounds.x = Math.max(Math.min(position.x + OFFSET, displayBounds.width - shellBounds.width), 0); - } - if (position.y + shellBounds.height + OFFSET > displayBounds.height && position.y - shellBounds.height - OFFSET >= 0) { - shellBounds.y = position.y - shellBounds.height - OFFSET; - } else { - shellBounds.y = Math.max(Math.min(position.y + OFFSET, displayBounds.height - shellBounds.height), 0); - } - shell.setBounds(shellBounds); - } - - private void setupControl(Control control) { - control.setForeground(fTipShell.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND)); - control.setBackground(fTipShell.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); - - control.addMouseListener(new MouseAdapter() { - @Override - public void mouseDown(MouseEvent e) { - fTipShell.dispose(); - } - }); - - control.addMouseTrackListener(new MouseTrackAdapter() { - @Override - public void mouseExit(MouseEvent e) { - fTipShell.dispose(); - } - }); - - control.addMouseMoveListener(new MouseMoveListener() { - @Override - public void mouseMove(MouseEvent e) { - fTipShell.dispose(); - } - }); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/Utils.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/Utils.java deleted file mode 100644 index 06131b22cd..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/Utils.java +++ /dev/null @@ -1,826 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2007, 2014 Intel Corporation, Ericsson - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Intel Corporation - Initial API and implementation - * Ruslan A. Scherbakov, Intel - Initial API and implementation - * Alvaro Sanchez-Leon - Udpated for TMF - * Patrick Tasse - Refactoring - * Marc-Andre Laperle - Add time zone preference - *****************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets; - -import java.text.NumberFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Iterator; -import java.util.TimeZone; -import java.util.concurrent.TimeUnit; - -import org.eclipse.linuxtools.internal.tmf.ui.Messages; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimePreferences; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; -import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Display; - -/** - * General utilities and definitions used by the time graph widget - * - * @version 1.0 - * @author Alvaro Sanchez-Leon - * @author Patrick Tasse - */ -public class Utils { - - private Utils() { - } - - /** Time format for dates and timestamp */ - public enum TimeFormat { - /** Relative to the start of the trace */ - RELATIVE, - - /** - * Absolute timestamp (ie, relative to the Unix epoch) - * @since 2.0 - */ - CALENDAR, - - /** - * Timestamp displayed as a simple number - * @since 2.0 - */ - NUMBER, - - /** - * Timestamp displayed as cycles - * @since 3.2 - */ - CYCLES - } - - /** - * Timestamp resolution - */ - public static enum Resolution { - /** seconds */ - SECONDS, - - /** milliseconds */ - MILLISEC, - - /** microseconds */ - MICROSEC, - - /** nanoseconds */ - NANOSEC - } - - private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss"); //$NON-NLS-1$ - private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); //$NON-NLS-1$ - private static final long HOURS_PER_DAY = 24; - private static final long MIN_PER_HOUR = 60; - private static final long SEC_PER_MIN = 60; - private static final long SEC_IN_NS = 1000000000; - private static final long MILLISEC_IN_NS = 1000000; - - /** - * Update the time and date formats to use the current time zone - * - * @since 2.1 - */ - public static void updateTimeZone() { - TimeZone timeZone = TmfTimePreferences.getInstance().getTimeZone(); - TIME_FORMAT.setTimeZone(timeZone); - DATE_FORMAT.setTimeZone(timeZone); - } - - static Rectangle clone(Rectangle source) { - return new Rectangle(source.x, source.y, source.width, source.height); - } - - /** - * Initialize a Rectangle object to default values (all equal to 0) - * - * @param rect - * The Rectangle to initialize - */ - public static void init(Rectangle rect) { - rect.x = 0; - rect.y = 0; - rect.width = 0; - rect.height = 0; - } - - /** - * Initialize a Rectangle object with all the given values - * - * @param rect - * The Rectangle object to initialize - * @param x - * The X coordinate - * @param y - * The Y coordinate - * @param width - * The width of the rectangle - * @param height - * The height of the rectangle - */ - public static void init(Rectangle rect, int x, int y, int width, int height) { - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - } - - /** - * Initialize a Rectangle object to another existing Rectangle's values. - * - * @param rect - * The Rectangle to initialize - * @param source - * The reference Rectangle to copy - */ - public static void init(Rectangle rect, Rectangle source) { - rect.x = source.x; - rect.y = source.y; - rect.width = source.width; - rect.height = source.height; - } - - /** - * Reduce the size of a given rectangle by the given amounts. - * - * @param rect - * The rectangle to modify - * @param x - * The reduction in width - * @param y - * The reduction in height - */ - public static void deflate(Rectangle rect, int x, int y) { - rect.x += x; - rect.y += y; - rect.width -= x + x; - rect.height -= y + y; - } - - /** - * Increase the size of a given rectangle by the given amounts. - * - * @param rect - * The rectangle to modify - * @param x - * The augmentation in width - * @param y - * The augmentation in height - */ - public static void inflate(Rectangle rect, int x, int y) { - rect.x -= x; - rect.y -= y; - rect.width += x + x; - rect.height += y + y; - } - - static void dispose(Color col) { - if (null != col) { - col.dispose(); - } - } - - /** - * Get the resulting color from a mix of two existing ones for a given - * display. - * - * @param display - * The display device (which might affect the color conversion) - * @param c1 - * The first color - * @param c2 - * The second color - * @param w1 - * The gamma level for color 1 - * @param w2 - * The gamma level for color 2 - * @return The resulting color - */ - public static Color mixColors(Device display, Color c1, Color c2, int w1, - int w2) { - return new Color(display, (w1 * c1.getRed() + w2 * c2.getRed()) - / (w1 + w2), (w1 * c1.getGreen() + w2 * c2.getGreen()) - / (w1 + w2), (w1 * c1.getBlue() + w2 * c2.getBlue()) - / (w1 + w2)); - } - - /** - * Get the system color with the given ID. - * - * @param id - * The color ID - * @return The resulting color - */ - public static Color getSysColor(int id) { - Color col = Display.getCurrent().getSystemColor(id); - return new Color(col.getDevice(), col.getRGB()); - } - - /** - * Get the resulting color from a mix of two existing ones for the current - * display. - * - * @param col1 - * The first color - * @param col2 - * The second color - * @param w1 - * The gamma level for color 1 - * @param w2 - * The gamma level for color 2 - * @return The resulting color - */ - public static Color mixColors(Color col1, Color col2, int w1, int w2) { - return mixColors(Display.getCurrent(), col1, col2, w1, w2); - } - - /** - * Draw text in a rectangle. - * - * @param gc - * The SWT GC object - * @param text - * The text to draw - * @param rect - * The rectangle object which is being drawn - * @param transp - * If true the background will be transparent - * @return The width of the written text - */ - public static int drawText(GC gc, String text, Rectangle rect, boolean transp) { - Point size = gc.stringExtent(text); - gc.drawText(text, rect.x, rect.y, transp); - return size.x; - } - - /** - * Draw text at a given location. - * - * @param gc - * The SWT GC object - * @param text - * The text to draw - * @param x - * The X coordinate of the starting point - * @param y - * the Y coordinate of the starting point - * @param transp - * If true the background will be transparent - * @return The width of the written text - */ - public static int drawText(GC gc, String text, int x, int y, boolean transp) { - Point size = gc.stringExtent(text); - gc.drawText(text, x, y, transp); - return size.x; - } - - /** - * Draw text in a rectangle, trimming the text to prevent exceeding the specified width. - * - * @param gc - * The SWT GC object - * @param text - * The string to be drawn - * @param x - * The x coordinate of the top left corner of the rectangular area where the text is to be drawn - * @param y - * The y coordinate of the top left corner of the rectangular area where the text is to be drawn - * @param width - * The width of the area to be drawn - * @param isCentered - * If true the text will be centered in the available width if space permits - * @param isTransparent - * If true the background will be transparent, otherwise it will be opaque - * @return The number of characters written - * - * @since 2.0 - */ - public static int drawText(GC gc, String text, int x, int y, int width, boolean isCentered, boolean isTransparent) { - if (width < 1) { - return 0; - } - - int len = text.length(); - int textWidth = 0; - boolean isReallyCentered = isCentered; - int realX = x; - - while (len > 0) { - textWidth = gc.stringExtent(text.substring(0, len)).x; - if (textWidth <= width) { - break; - } - isReallyCentered = false; - len--; - } - if (len > 0) { - if (isReallyCentered) { - realX += (width - textWidth) / 2; - } - gc.drawText(text.substring(0, len), realX, y, isTransparent); - } - return len; - } - - /** - * Formats time in format: MM:SS:NNN - * - * @param time time - * @param format 0: MMMM:ss:nnnnnnnnn, 1: HH:MM:ss MMM.mmmm.nnn - * @param resolution the resolution - * @return the formatted time - */ - public static String formatTime(long time, TimeFormat format, Resolution resolution) { - switch (format) { - case CALENDAR: - return formatTimeAbs(time, resolution); - case NUMBER: - return NumberFormat.getInstance().format(time); - case CYCLES: - return NumberFormat.getInstance().format(time) + Messages.Utils_ClockCyclesUnit; - case RELATIVE: - default: - } - - StringBuffer str = new StringBuffer(); - long t = time; - boolean neg = t < 0; - if (neg) { - t = -t; - str.append('-'); - } - - long sec = t / SEC_IN_NS; - str.append(sec); - String ns = formatNs(t, resolution); - if (!ns.equals("")) { //$NON-NLS-1$ - str.append('.'); - str.append(ns); - } - - return str.toString(); - } - - /** - * From input time in nanoseconds, convert to Date format YYYY-MM-dd - * - * @param absTime - * The source time, in ns - * @return the formatted date - */ - public static String formatDate(long absTime) { - String sdate = DATE_FORMAT.format(new Date(absTime / MILLISEC_IN_NS)); - return sdate; - } - - /** - * Formats time in ns to Calendar format: HH:MM:SS MMM.mmm.nnn - * - * @param time - * The source time, in ns - * @param res - * The resolution to use - * @return the formatted time - */ - public static String formatTimeAbs(long time, Resolution res) { - StringBuffer str = new StringBuffer(); - - // format time from nanoseconds to calendar time HH:MM:SS - String stime = TIME_FORMAT.format(new Date(time / MILLISEC_IN_NS)); - str.append(stime); - str.append('.'); - // append the Milliseconds, MicroSeconds and NanoSeconds as specified in - // the Resolution - str.append(formatNs(time, res)); - return str.toString(); - } - - /** - * Formats time delta - * - * @param delta - * The time delta, in ns - * @param format - * The time format to use - * @param resolution - * The resolution to use - * @since 3.2 - * @return the formatted time delta - */ - public static String formatDelta(long delta, TimeFormat format, Resolution resolution) { - if (format == TimeFormat.CALENDAR) { - return formatDeltaAbs(delta, resolution); - } - return formatTime(delta, format, resolution); - } - - /** - * Formats time delta in ns to Calendar format, only formatting the years, - * days, hours or minutes if necessary. - * - * @param delta - * The time delta, in ns - * @param resolution - * The resolution to use - * @return the formatted time delta - * @since 3.2 - */ - public static String formatDeltaAbs(long delta, Resolution resolution) { - StringBuffer str = new StringBuffer(); - if (delta < 0) { - str.append('-'); - } - long ns = Math.abs(delta); - long seconds = TimeUnit.NANOSECONDS.toSeconds(ns); - long minutes = TimeUnit.NANOSECONDS.toMinutes(ns); - long hours = TimeUnit.NANOSECONDS.toHours(ns); - long days = TimeUnit.NANOSECONDS.toDays(ns); - if (days > 0) { - str.append(days); - str.append("d "); //$NON-NLS-1$ - } - if (hours > 0) { - str.append(hours % HOURS_PER_DAY); - str.append("h "); //$NON-NLS-1$ - } - if (minutes > 0) { - str.append(minutes % MIN_PER_HOUR); - str.append("m "); //$NON-NLS-1$ - } - str.append(seconds % SEC_PER_MIN); - str.append('.'); - // append the ms, us and ns as specified in the resolution - str.append(formatNs(delta, resolution)); - str.append("s"); //$NON-NLS-1$ - return str.toString(); - } - - /** - * Obtains the remainder fraction on unit Seconds of the entered value in - * nanoseconds. e.g. input: 1241207054171080214 ns The number of fraction - * seconds can be obtained by removing the last 9 digits: 1241207054 the - * fractional portion of seconds, expressed in ns is: 171080214 - * - * @param srcTime - * The source time in ns - * @param res - * The Resolution to use - * @return the formatted nanosec - */ - public static String formatNs(long srcTime, Resolution res) { - StringBuffer str = new StringBuffer(); - long ns = Math.abs(srcTime % SEC_IN_NS); - String nanos = Long.toString(ns); - str.append("000000000".substring(nanos.length())); //$NON-NLS-1$ - str.append(nanos); - - if (res == Resolution.MILLISEC) { - return str.substring(0, 3); - } else if (res == Resolution.MICROSEC) { - return str.substring(0, 6); - } else if (res == Resolution.NANOSEC) { - return str.substring(0, 9); - } - return ""; //$NON-NLS-1$ - } - - /** - * FIXME Currently does nothing. - * - * @param opt - * The option name - * @param def - * The option value - * @param min - * The minimal accepted value - * @param max - * The maximal accepted value - * @return The value that was read - */ - public static int loadIntOption(String opt, int def, int min, int max) { - return def; - } - - /** - * FIXME currently does nothing - * - * @param opt - * The option name - * @param val - * The option value - */ - public static void saveIntOption(String opt, int val) { - } - - static ITimeEvent getFirstEvent(ITimeGraphEntry entry) { - if (null == entry || ! entry.hasTimeEvents()) { - return null; - } - Iterator iterator = entry.getTimeEventsIterator(); - if (iterator != null && iterator.hasNext()) { - return iterator.next(); - } - return null; - } - - /** - * Gets the {@link ITimeEvent} at the given time from the given - * {@link ITimeGraphEntry}. - * - * @param entry - * a {@link ITimeGraphEntry} - * @param time - * a timestamp - * @param n - * this parameter means:
  • -1: Previous Event
  • - * 0: Current Event
  • - * 1: Next Event
  • 2: Previous Event when located in a non - * Event Area - * @return a {@link ITimeEvent}, or null. - * @since 3.0 - */ - public static ITimeEvent findEvent(ITimeGraphEntry entry, long time, int n) { - if (null == entry || ! entry.hasTimeEvents()) { - return null; - } - Iterator iterator = entry.getTimeEventsIterator(); - if (iterator == null) { - return null; - } - ITimeEvent nextEvent = null; - ITimeEvent currEvent = null; - ITimeEvent prevEvent = null; - - while (iterator.hasNext()) { - nextEvent = iterator.next(); - long nextStartTime = nextEvent.getTime(); - - if (nextStartTime > time) { - break; - } - - if (currEvent == null || currEvent.getTime() != nextStartTime || - (nextStartTime != time && currEvent.getDuration() != nextEvent.getDuration())) { - prevEvent = currEvent; - currEvent = nextEvent; - } - } - - if (n == -1) { //previous - if (currEvent != null && currEvent.getTime() + currEvent.getDuration() >= time) { - return prevEvent; - } - return currEvent; - } else if (n == 0) { //current - if (currEvent != null && currEvent.getTime() + currEvent.getDuration() >= time) { - return currEvent; - } - return null; - } else if (n == 1) { //next - if (nextEvent != null && nextEvent.getTime() > time) { - return nextEvent; - } - return null; - } else if (n == 2) { //current or previous when in empty space - return currEvent; - } - - return null; - } - - /** - * Pretty-print a method signature. - * - * @param origSig - * The original signature - * @return The pretty signature - */ - public static String fixMethodSignature(String origSig) { - String sig = origSig; - int pos = sig.indexOf('('); - if (pos >= 0) { - String ret = sig.substring(0, pos); - sig = sig.substring(pos); - sig = sig + " " + ret; //$NON-NLS-1$ - } - return sig; - } - - /** - * Restore an original method signature from a pretty-printed one. - * - * @param ppSig - * The pretty-printed signature - * @return The original method signature - */ - public static String restoreMethodSignature(String ppSig) { - String ret = ""; //$NON-NLS-1$ - String sig = ppSig; - - int pos = sig.indexOf('('); - if (pos >= 0) { - ret = sig.substring(0, pos); - sig = sig.substring(pos + 1); - } - pos = sig.indexOf(')'); - if (pos >= 0) { - sig = sig.substring(0, pos); - } - String args[] = sig.split(","); //$NON-NLS-1$ - StringBuffer result = new StringBuffer("("); //$NON-NLS-1$ - for (int i = 0; i < args.length; i++) { - String arg = args[i].trim(); - if (arg.length() == 0 && args.length == 1) { - break; - } - result.append(getTypeSignature(arg)); - } - result.append(")").append(getTypeSignature(ret)); //$NON-NLS-1$ - return result.toString(); - } - - /** - * Get the mangled type information from an array of types. - * - * @param typeStr - * The types to convert. See method implementation for what it - * expects. - * @return The mangled string of types - */ - public static String getTypeSignature(String typeStr) { - int dim = 0; - String type = typeStr; - for (int j = 0; j < type.length(); j++) { - if (type.charAt(j) == '[') { - dim++; - } - } - int pos = type.indexOf('['); - if (pos >= 0) { - type = type.substring(0, pos); - } - StringBuffer sig = new StringBuffer(""); //$NON-NLS-1$ - for (int j = 0; j < dim; j++) - { - sig.append("["); //$NON-NLS-1$ - } - if (type.equals("boolean")) { //$NON-NLS-1$ - sig.append('Z'); - } else if (type.equals("byte")) { //$NON-NLS-1$ - sig.append('B'); - } else if (type.equals("char")) { //$NON-NLS-1$ - sig.append('C'); - } else if (type.equals("short")) { //$NON-NLS-1$ - sig.append('S'); - } else if (type.equals("int")) { //$NON-NLS-1$ - sig.append('I'); - } else if (type.equals("long")) { //$NON-NLS-1$ - sig.append('J'); - } else if (type.equals("float")) { //$NON-NLS-1$ - sig.append('F'); - } else if (type.equals("double")) { //$NON-NLS-1$ - sig.append('D'); - } else if (type.equals("void")) { //$NON-NLS-1$ - sig.append('V'); - } - else { - sig.append('L').append(type.replace('.', '/')).append(';'); - } - return sig.toString(); - } - - /** - * Compare two doubles together. - * - * @param d1 - * First double - * @param d2 - * Second double - * @return 1 if they are different, and 0 if they are *exactly* the same. - * Because of the way doubles are stored, it's possible for the - * same number obtained in two different ways to actually look - * different. - */ - public static int compare(double d1, double d2) { - if (d1 > d2) { - return 1; - } - if (d1 < d2) { - return 1; - } - return 0; - } - - /** - * Compare two character strings alphabetically. This is simply a wrapper - * around String.compareToIgnoreCase but that will handle cases where - * strings can be null - * - * @param s1 - * The first string - * @param s2 - * The second string - * @return A number below, equal, or greater than zero if the first string - * is smaller, equal, or bigger (alphabetically) than the second - * one. - */ - public static int compare(String s1, String s2) { - if (s1 != null && s2 != null) { - return s1.compareToIgnoreCase(s2); - } - if (s1 != null) { - return 1; - } - if (s2 != null) { - return -1; - } - return 0; - } - - /** - * Calculates the square of the distance between two points. - * - * @param x1 - * x-coordinate of point 1 - * @param y1 - * y-coordinate of point 1 - * @param x2 - * x-coordinate of point 2 - * @param y2 - * y-coordinate of point 2 - * - * @return the square of the distance in pixels^2 - * @since 3.2 - */ - public static double distance2(int x1, int y1, int x2, int y2) { - int dx = x2 - x1; - int dy = y2 - y1; - int d2 = dx * dx + dy * dy; - return d2; - } - - /** - * Calculates the distance between a point and a line segment. If the point - * is in the perpendicular region between the segment points, return the - * distance from the point to its projection on the segment. Otherwise - * return the distance from the point to its closest segment point. - * - * @param px - * x-coordinate of the point - * @param py - * y-coordinate of the point - * @param x1 - * x-coordinate of segment point 1 - * @param y1 - * y-coordinate of segment point 1 - * @param x2 - * x-coordinate of segment point 2 - * @param y2 - * y-coordinate of segment point 2 - * - * @return the distance in pixels - * @since 3.2 - */ - public static double distance(int px, int py, int x1, int y1, int x2, int y2) { - double length2 = distance2(x1, y1, x2, y2); - if (length2 == 0) { - return Math.sqrt(distance2(px, py, x1, y1)); - } - // 'r' is the ratio of the position, between segment point 1 and segment - // point 2, of the projection of the point on the segment - double r = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / length2; - if (r <= 0.0) { - // the projection is before segment point 1, return distance from - // the point to segment point 1 - return Math.sqrt(distance2(px, py, x1, y1)); - } - if (r >= 1.0) { - // the projection is after segment point 2, return distance from - // the point to segment point 2 - return Math.sqrt(distance2(px, py, x2, y2)); - } - // the projection is between the segment points, return distance from - // the point to its projection on the segment - int x = (int) (x1 + r * (x2 - x1)); - int y = (int) (y1 + r * (y2 - y1)); - return Math.sqrt(distance2(px, py, x, y)); - } -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/virtualtable/ColumnData.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/virtualtable/ColumnData.java deleted file mode 100644 index bf18d4c1df..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/virtualtable/ColumnData.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2012 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Extracted from TmfEventsView - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.virtualtable; - -/** - * ColumnData - * - * @author Matthew Khouzam - * @deprecated Use {@link org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn} instead. - */ -@Deprecated -public class ColumnData { - /** - * The title of the column - */ - public final String header; - /** - * the width of the column in pixels - */ - public final int width; - /** - * the alignment of the column - */ - public final int alignment; - - /** - * Constructor - * @param h header (title) - * @param w width - * @param a alignment - */ - public ColumnData(String h, int w, int a) { - header = h; - width = w; - alignment = a; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/virtualtable/IDoubleClickListener.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/virtualtable/IDoubleClickListener.java deleted file mode 100644 index a11152dd31..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/virtualtable/IDoubleClickListener.java +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Kalray, Ericsson. - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xavier Raynaud - Initial API and implementation - ******************************************************************************/ -package org.eclipse.linuxtools.tmf.ui.widgets.virtualtable; - -import org.eclipse.swt.widgets.TableItem; -/** - * Double click listener interface - * @author Xavier Raynaud - * @version 1.0 - */ -public interface IDoubleClickListener { - - /** - * Handle a double click event - * @param table the table that was double clicked - * @param item the item that was double clicked in the table - * @param column the column that was double clicked in the item in the table. - */ - void handleDoubleClick(TmfVirtualTable table, TableItem item, int column); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/virtualtable/TmfVirtualTable.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/virtualtable/TmfVirtualTable.java deleted file mode 100644 index 7dd7dec169..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/virtualtable/TmfVirtualTable.java +++ /dev/null @@ -1,1130 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010, 2013 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Khouzam - Initial API and implementation - * Francois Chouinard - Refactoring, slider support, bug fixing - * Patrick Tasse - Improvements and bug fixing - * Xavier Raynaud - Improvements - ******************************************************************************/ - -package org.eclipse.linuxtools.tmf.ui.widgets.virtualtable; - -import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.custom.TableEditor; -import org.eclipse.swt.events.ControlAdapter; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.KeyAdapter; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.MouseWheelListener; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Slider; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.TableItem; -import org.eclipse.ui.PlatformUI; - -/** - * TmfVirtualTable - *

    - * TmfVirtualTable allows for the tabular display of arbitrarily large data sets - * (well, up to Integer.MAX_VALUE or ~2G rows). - * - * It is essentially a Composite of Table and Slider, where the number of rows - * in the table is set to fill the table display area. The slider is rank-based. - * - * It differs from Table with the VIRTUAL style flag where an empty entry is - * created for each virtual row. This does not scale well for very large data sets. - * - * Styles: - * H_SCROLL, V_SCROLL, SINGLE, MULTI, CHECK, FULL_SELECTION, HIDE_SELECTION, NO_SCROLL - * @author Matthew Khouzam, Francois Chouinard, Patrick Tasse, Xavier Raynaud - * @version $Revision: 1.0 - */ -public class TmfVirtualTable extends Composite { - - // The table - private Table fTable; - private int fTableRows = 0; // Number of table rows - private int fFullyVisibleRows = 0; // Number of fully visible table rows - private int fFrozenRowCount = 0; // Number of frozen table rows at top of table - - private int fTableTopEventRank = 0; // Global rank of the first entry displayed - private int fSelectedEventRank = -1; // Global rank of the selected event - private int fSelectedBeginRank = -1; // Global rank of the selected begin event - private boolean fPendingSelection = false; // Pending selection update - - private int fTableItemCount = 0; - - // The slider - private Slider fSlider; - - private int fLinuxItemHeight = 0; // Calculated item height for Linux workaround - private TooltipProvider tooltipProvider = null; - private IDoubleClickListener doubleClickListener = null; - - private boolean fResetTopIndex = false; // Flag to trigger reset of top index - private ControlAdapter fResizeListener; // Resize listener to update visible rows - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Standard constructor - * - * @param parent - * The parent composite object - * @param style - * The style to use - */ - public TmfVirtualTable(Composite parent, int style) { - super(parent, style & (~SWT.H_SCROLL) & (~SWT.V_SCROLL) & (~SWT.SINGLE) & (~SWT.MULTI) & (~SWT.FULL_SELECTION) & (~SWT.HIDE_SELECTION) & (~SWT.CHECK)); - - // Create the controls - createTable(style & (SWT.H_SCROLL | SWT.SINGLE | SWT.MULTI | SWT.FULL_SELECTION | SWT.HIDE_SELECTION | SWT.CHECK)); - createSlider(style & SWT.V_SCROLL); - - // Prevent the slider from being traversed - setTabList(new Control[] { fTable }); - - // Set the layout - GridLayout gridLayout = new GridLayout(); - gridLayout.numColumns = 2; - gridLayout.horizontalSpacing = 0; - gridLayout.verticalSpacing = 0; - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - setLayout(gridLayout); - - GridData tableGridData = new GridData(SWT.FILL, SWT.FILL, true, true); - fTable.setLayoutData(tableGridData); - - GridData sliderGridData = new GridData(SWT.FILL, SWT.FILL, false, true); - fSlider.setLayoutData(sliderGridData); - - // Add the listeners - fTable.addMouseWheelListener(new MouseWheelListener() { - @Override - public void mouseScrolled(MouseEvent event) { - if (fTableItemCount <= fFullyVisibleRows) { - return; - } - fTableTopEventRank -= event.count; - if (fTableTopEventRank < 0) { - fTableTopEventRank = 0; - } - int latestFirstRowOffset = fTableItemCount - fFullyVisibleRows; - if (fTableTopEventRank > latestFirstRowOffset) { - fTableTopEventRank = latestFirstRowOffset; - } - - fSlider.setSelection(fTableTopEventRank); - refreshTable(); - } - }); - - fTable.addListener(SWT.MouseWheel, new Listener() { - // disable mouse scroll of horizontal scroll bar - @Override - public void handleEvent(Event event) { - event.doit = false; - } - }); - - fResizeListener = new ControlAdapter() { - @Override - public void controlResized(ControlEvent event) { - int tableHeight = Math.max(0, fTable.getClientArea().height - fTable.getHeaderHeight()); - fFullyVisibleRows = tableHeight / getItemHeight(); - if (fTableItemCount > 0) { - fSlider.setThumb(Math.max(1, Math.min(fTableRows, fFullyVisibleRows))); - } - } - }; - fTable.addControlListener(fResizeListener); - - // Implement a "fake" tooltip - final String TOOLTIP_DATA_KEY = "_TABLEITEM"; //$NON-NLS-1$ - final Listener labelListener = new Listener() { - @Override - public void handleEvent (Event event) { - Label label = (Label) event.widget; - Shell shell = label.getShell(); - switch (event.type) { - case SWT.MouseDown: - Event e = new Event(); - e.item = (TableItem) label.getData(TOOLTIP_DATA_KEY); - // Assuming table is single select, set the selection as if - // the mouse down event went through to the table - fTable.setSelection(new TableItem [] {(TableItem) e.item}); - fTable.notifyListeners(SWT.Selection, e); - shell.dispose(); - fTable.setFocus(); - break; - case SWT.MouseExit: - case SWT.MouseWheel: - shell.dispose(); - break; - default: - break; - } - } - }; - - Listener tableListener = new Listener() { - Shell tip = null; - Label label = null; - @Override - public void handleEvent(Event event) { - switch (event.type) { - case SWT.Dispose: - case SWT.KeyDown: - case SWT.MouseMove: { - if (tip == null) { - break; - } - tip.dispose(); - tip = null; - label = null; - break; - } - case SWT.MouseHover: { - TableItem item = fTable.getItem(new Point(event.x, event.y)); - if (item != null) { - for (int i = 0; i < fTable.getColumnCount(); i++) { - Rectangle bounds = item.getBounds(i); - if (bounds.contains(event.x, event.y)) { - if (tip != null && !tip.isDisposed()) { - tip.dispose(); - } - if (tooltipProvider == null) { - return; - } - String tooltipText = tooltipProvider.getTooltip(i, item.getData()); - if (tooltipText == null) { - return; - } - tip = new Shell(fTable.getShell(), SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL); - tip.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); - FillLayout layout = new FillLayout(); - layout.marginWidth = 2; - tip.setLayout(layout); - label = new Label(tip, SWT.WRAP); - label.setForeground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND)); - label.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); - label.setData(TOOLTIP_DATA_KEY, item); - label.setText(tooltipText); - - label.addListener(SWT.MouseExit, labelListener); - label.addListener(SWT.MouseDown, labelListener); - label.addListener(SWT.MouseWheel, labelListener); - Point size = tip.computeSize(SWT.DEFAULT, SWT.DEFAULT); - Point pt = fTable.toDisplay(bounds.x, bounds.y); - tip.setBounds(pt.x, pt.y, size.x, size.y); - tip.setVisible(true); - - // Item found, leave loop. - break; - } - } - } - break; - } - default: - break; - } - } - }; - fTable.addListener(SWT.Dispose, tableListener); - fTable.addListener(SWT.KeyDown, tableListener); - fTable.addListener(SWT.MouseMove, tableListener); - fTable.addListener(SWT.MouseHover, tableListener); - addControlListener(new ControlAdapter() { - @Override - public void controlResized(ControlEvent event) { - resize(); - if (fTableItemCount > 0) { - fSlider.setThumb(Math.max(1, Math.min(fTableRows, fFullyVisibleRows))); - } - } - }); - - // And display - refresh(); - } - - // ------------------------------------------------------------------------ - // Table handling - // ------------------------------------------------------------------------ - - /** - * Create the table and add listeners - * @param style int can be H_SCROLL, SINGLE, MULTI, FULL_SELECTION, HIDE_SELECTION, CHECK - */ - private void createTable(int style) { - fTable = new Table(this, style | SWT.NO_SCROLL); - - fTable.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent event) { - if (event.item == null) { - // Override table selection from Select All action - refreshSelection(); - } - } - }); - - fTable.addMouseListener(new MouseAdapter() { - @Override - public void mouseDown(MouseEvent e) { - handleTableMouseEvent(e); - } - }); - - fTable.addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(KeyEvent event) { - handleTableKeyEvent(event); - } - }); - - fTable.addListener( - SWT.MouseDoubleClick, new Listener() { - @Override - public void handleEvent(Event event) { - if (doubleClickListener != null) { - TableItem item = fTable.getItem(new Point (event.x, event.y)); - if (item != null) { - for (int i = 0; i < fTable.getColumnCount(); i++){ - Rectangle bounds = item.getBounds(i); - if (bounds.contains(event.x, event.y)){ - doubleClickListener.handleDoubleClick(TmfVirtualTable.this, item, i); - break; - } - } - } - } - } - } - ); - - /* - * Feature in Windows. When a partially visible table item is selected, - * after ~500 ms the top index is changed to ensure the selected item is - * fully visible. This leaves a blank space at the bottom of the virtual - * table. The workaround is to reset the top index to 0 if it is not 0. - * Also reset the top index to 0 if indicated by the flag that was set - * at table selection of a partially visible table item. - */ - fTable.addPaintListener(new PaintListener() { - @Override - public void paintControl(PaintEvent e) { - if (fTable.getTopIndex() != 0 || fResetTopIndex) { - fTable.setTopIndex(0); - } - fResetTopIndex = false; - } - }); - } - - /** - * Handle mouse-based selection in table. - * - * @param event the mouse event - */ - private void handleTableMouseEvent(MouseEvent event) { - TableItem item = fTable.getItem(new Point(event.x, event.y)); - if (item == null) { - return; - } - int selectedRow = indexOf(item); - if (event.button == 1 || (event.button == 3 && - (selectedRow < Math.min(fSelectedBeginRank, fSelectedEventRank) || - selectedRow > Math.max(fSelectedBeginRank, fSelectedEventRank)))) { - if (selectedRow >= 0) { - fSelectedEventRank = selectedRow; - } else { - fSelectedEventRank = -1; - } - if ((event.stateMask & SWT.SHIFT) == 0 || (fTable.getStyle() & SWT.MULTI) == 0 || fSelectedBeginRank == -1) { - fSelectedBeginRank = fSelectedEventRank; - } - } - refreshSelection(); - - /* - * Feature in Linux. When a partially visible table item is selected, - * the origin is changed to ensure the selected item is fully visible. - * This makes the first row partially visible. The solution is to force - * reset the origin by setting the top index to 0. This should happen - * only once at the next redraw by the paint listener. - */ - if (selectedRow >= fFullyVisibleRows) { - fResetTopIndex = true; - } - } - - /** - * Handle key-based navigation in table. - * - * @param event the key event - */ - private void handleTableKeyEvent(KeyEvent event) { - - int lastEventRank = fTableItemCount - 1; - int lastPageTopEntryRank = Math.max(0, fTableItemCount - fFullyVisibleRows); - - int previousSelectedEventRank = fSelectedEventRank; - int previousSelectedBeginRank = fSelectedBeginRank; - boolean needsRefresh = false; - - // In all case, perform the following steps: - // - Update the selected entry rank (within valid range) - // - Update the selected row - // - Update the page's top entry if necessary (which also adjusts the selected row) - // - If the top displayed entry was changed, table refresh is needed - switch (event.keyCode) { - - case SWT.ARROW_DOWN: { - event.doit = false; - if (fSelectedEventRank < lastEventRank) { - fSelectedEventRank++; - int selectedRow = fSelectedEventRank - fTableTopEventRank; - if (selectedRow == fFullyVisibleRows) { - fTableTopEventRank++; - needsRefresh = true; - } else if (selectedRow < fFrozenRowCount || selectedRow > fFullyVisibleRows) { - fTableTopEventRank = Math.max(0, Math.min(fSelectedEventRank - fFrozenRowCount, lastPageTopEntryRank)); - needsRefresh = true; - } - } - break; - } - - case SWT.ARROW_UP: { - event.doit = false; - if (fSelectedEventRank > 0) { - fSelectedEventRank--; - int selectedRow = fSelectedEventRank - fTableTopEventRank; - if (selectedRow == fFrozenRowCount - 1 && fTableTopEventRank > 0) { - fTableTopEventRank--; - needsRefresh = true; - } else if (selectedRow < fFrozenRowCount || selectedRow > fFullyVisibleRows) { - fTableTopEventRank = Math.max(0, Math.min(fSelectedEventRank - fFrozenRowCount, lastPageTopEntryRank)); - needsRefresh = true; - } - } - break; - } - - case SWT.END: { - event.doit = false; - fTableTopEventRank = lastPageTopEntryRank; - fSelectedEventRank = lastEventRank; - needsRefresh = true; - break; - } - - case SWT.HOME: { - event.doit = false; - fSelectedEventRank = fFrozenRowCount; - fTableTopEventRank = 0; - needsRefresh = true; - break; - } - - case SWT.PAGE_DOWN: { - event.doit = false; - if (fSelectedEventRank < lastEventRank) { - fSelectedEventRank += fFullyVisibleRows; - if (fSelectedEventRank > lastEventRank) { - fSelectedEventRank = lastEventRank; - } - int selectedRow = fSelectedEventRank - fTableTopEventRank; - if (selectedRow > fFullyVisibleRows + fFrozenRowCount - 1 && selectedRow < 2 * fFullyVisibleRows) { - fTableTopEventRank += fFullyVisibleRows; - if (fTableTopEventRank > lastPageTopEntryRank) { - fTableTopEventRank = lastPageTopEntryRank; - } - needsRefresh = true; - } else if (selectedRow < fFrozenRowCount || selectedRow >= 2 * fFullyVisibleRows) { - fTableTopEventRank = Math.max(0, Math.min(fSelectedEventRank - fFrozenRowCount, lastPageTopEntryRank)); - needsRefresh = true; - } - } - break; - } - - case SWT.PAGE_UP: { - event.doit = false; - if (fSelectedEventRank > 0) { - fSelectedEventRank -= fFullyVisibleRows; - if (fSelectedEventRank < fFrozenRowCount) { - fSelectedEventRank = fFrozenRowCount; - } - int selectedRow = fSelectedEventRank - fTableTopEventRank; - if (selectedRow < fFrozenRowCount && selectedRow > -fFullyVisibleRows) { - fTableTopEventRank -= fFullyVisibleRows; - if (fTableTopEventRank < 0) { - fTableTopEventRank = 0; - } - needsRefresh = true; - } else if (selectedRow <= -fFullyVisibleRows || selectedRow >= fFullyVisibleRows) { - fTableTopEventRank = Math.max(0, Math.min(fSelectedEventRank - fFrozenRowCount, lastPageTopEntryRank)); - needsRefresh = true; - } - } - break; - } - default: { - return; - } - } - - if ((event.stateMask & SWT.SHIFT) == 0 || (fTable.getStyle() & SWT.MULTI) == 0 || fSelectedBeginRank == -1) { - fSelectedBeginRank = fSelectedEventRank; - } - - boolean done = true; - if (needsRefresh) { - done = refreshTable(); // false if table items not updated yet in this thread - } else { - refreshSelection(); - } - - if (fFullyVisibleRows < fTableItemCount) { - fSlider.setSelection(fTableTopEventRank); - } - - if (fSelectedEventRank != previousSelectedEventRank || fSelectedBeginRank != previousSelectedBeginRank) { - if (done) { - Event e = new Event(); - e.item = fTable.getItem(fSelectedEventRank - fTableTopEventRank); - fTable.notifyListeners(SWT.Selection, e); - } else { - fPendingSelection = true; - } - } - } - - /** - * Method setDataItem. - * @param index int - * @param item TableItem - * @return boolean - */ - private boolean setDataItem(int index, TableItem item) { - if (index != -1) { - Event event = new Event(); - event.item = item; - if (index < fFrozenRowCount) { - event.index = index; - } else { - event.index = index + fTableTopEventRank; - } - event.doit = true; - fTable.notifyListeners(SWT.SetData, event); - return event.doit; // false if table item not updated yet in this thread - } - return true; - } - - // ------------------------------------------------------------------------ - // Slider handling - // ------------------------------------------------------------------------ - - /** - * Method createSlider. - * @param style int - */ - private void createSlider(int style) { - fSlider = new Slider(this, SWT.VERTICAL | SWT.NO_FOCUS); - fSlider.setMinimum(0); - fSlider.setMaximum(0); - if ((style & SWT.V_SCROLL) == 0) { - fSlider.setVisible(false); - } - - fSlider.addListener(SWT.Selection, new Listener() { - @Override - public void handleEvent(Event event) { - switch (event.detail) { - case SWT.ARROW_DOWN: - case SWT.ARROW_UP: - case SWT.END: - case SWT.HOME: - case SWT.PAGE_DOWN: - case SWT.PAGE_UP: { - fTableTopEventRank = fSlider.getSelection(); - refreshTable(); - break; - } - // Not handled because of bug on Linux described below. - case SWT.NONE: - default: - break; - } - } - }); - - /* - * In Linux, the selection event above has event.detail set to SWT.NONE - * instead of SWT.DRAG during dragging of the thumb. To prevent refresh - * overflow, only update the table when the mouse button is released. - */ - fSlider.addMouseListener(new MouseAdapter() { - @Override - public void mouseUp(MouseEvent e) { - fTableTopEventRank = fSlider.getSelection(); - refreshTable(); - } - }); - - } - - // ------------------------------------------------------------------------ - // Simulated Table API - // ------------------------------------------------------------------------ - - /** - * Constructs a new TableColumn instance given a style value describing its - * alignment behavior. The column is added to the end of the columns - * maintained by the table. - * - * @param style - * the alignment style - * @return the new TableColumn - * - * @see SWT#LEFT - * @see SWT#RIGHT - * @see SWT#CENTER - * - * @since 3.1 - */ - public TableColumn newTableColumn(int style) { - TableColumn column = new TableColumn(fTable, style); - - /* - * In Linux the table does not receive a control resized event when - * a table column resize causes the horizontal scroll bar to become - * visible or invisible, so a resize listener must be added to every - * table column to properly update the number of fully visible rows. - */ - column.addControlListener(fResizeListener); - - return column; - } - - /** - * Method setHeaderVisible. - * @param b boolean - */ - public void setHeaderVisible(boolean b) { - fTable.setHeaderVisible(b); - } - - /** - * Method setLinesVisible. - * @param b boolean - */ - public void setLinesVisible(boolean b) { - fTable.setLinesVisible(b); - } - - /** - * Returns an array of TableItems that are currently selected - * in the receiver. The order of the items is unspecified. An empty array - * indicates that no items are selected. - *

    - * Note: This array only contains the visible selected items in the virtual - * table. To get information about the full selection range, use - * {@link #getSelectionIndices()}. - *

    - * - * @return an array representing the selection - * - * @exception SWTException
      - *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • - *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • - *
    - */ - public TableItem[] getSelection() { - return fTable.getSelection(); - } - - /** - * Method addListener. - * @param eventType int - * @param listener Listener - */ - @Override - public void addListener(int eventType, Listener listener) { - fTable.addListener(eventType, listener); - } - - /** - * Method addKeyListener. - * @param listener KeyListener - */ - @Override - public void addKeyListener(KeyListener listener) { - fTable.addKeyListener(listener); - } - - /** - * Method addMouseListener. - * @param listener MouseListener - */ - @Override - public void addMouseListener(MouseListener listener) { - fTable.addMouseListener(listener); - } - - /** - * Method addSelectionListener. - * @param listener SelectionListener - */ - public void addSelectionListener(SelectionListener listener) { - fTable.addSelectionListener(listener); - } - - /** - * Method setMenu sets the menu - * @param menu Menu the menu - */ - @Override - public void setMenu(Menu menu) { - fTable.setMenu(menu); - } - - /** - * Gets the menu of this table - * @return a Menu - */ - @Override - public Menu getMenu() { - return fTable.getMenu(); - } - - /** - * Method clearAll empties a table. - */ - public void clearAll() { - setItemCount(0); - } - - /** - * Method setItemCount - * @param nbItems int the number of items in the table - * - */ - public void setItemCount(int nbItems) { - final int nb = Math.max(0, nbItems); - - if (nb != fTableItemCount) { - fTableItemCount = nb; - fTable.remove(fTableItemCount, fTable.getItemCount() - 1); - fSlider.setMaximum(nb); - resize(); - int tableHeight = Math.max(0, fTable.getClientArea().height - fTable.getHeaderHeight()); - fFullyVisibleRows = tableHeight / getItemHeight(); - if (fTableItemCount > 0) { - fSlider.setThumb(Math.max(1, Math.min(fTableRows, fFullyVisibleRows))); - } - } - } - - /** - * Method getItemCount. - * @return int the number of items in the table - */ - public int getItemCount() { - return fTableItemCount; - } - - /** - * Method getItemHeight. - * @return int the height of a table item in pixels. (may vary from one os to another) - */ - public int getItemHeight() { - /* - * Bug in Linux. The method getItemHeight doesn't always return the correct value. - */ - if (fLinuxItemHeight >= 0 && System.getProperty("os.name").contains("Linux")) { //$NON-NLS-1$ //$NON-NLS-2$ - if (fLinuxItemHeight != 0) { - return fLinuxItemHeight; - } - if (fTable.getItemCount() > 1) { - int itemHeight = fTable.getItem(1).getBounds().y - fTable.getItem(0).getBounds().y; - if (itemHeight > 0) { - fLinuxItemHeight = itemHeight; - return fLinuxItemHeight; - } - } - } else { - fLinuxItemHeight = -1; // Not Linux, don't perform os.name check anymore - } - return fTable.getItemHeight(); - } - - /** - * Method getHeaderHeight. - * @return int get the height of the header in pixels. - */ - public int getHeaderHeight() { - return fTable.getHeaderHeight(); - } - - /** - * Method getTopIndex. - * @return int get the first data item index, if you have a header it is offset. - */ - public int getTopIndex() { - return fTableTopEventRank + fFrozenRowCount; - } - - /** - * Method setTopIndex. - * @param index int suggested top index for the table. - */ - public void setTopIndex(int index) { - if (fTableItemCount > 0) { - int i = Math.min(index, fTableItemCount - 1); - i = Math.max(i, fFrozenRowCount); - - fTableTopEventRank = i - fFrozenRowCount; - if (fFullyVisibleRows < fTableItemCount) { - fSlider.setSelection(fTableTopEventRank); - } - - refreshTable(); - } - } - - /** - * Method indexOf. Return the index of a table item - * @param ti TableItem the table item to search for in the table - * @return int the index of the first match. (there should only be one match) - */ - public int indexOf(TableItem ti) { - int index = fTable.indexOf(ti); - if (index < fFrozenRowCount) { - return index; - } - return (index - fFrozenRowCount) + getTopIndex(); - } - - /** - * Method getColumns. - * @return TableColumn[] the table columns - */ - public TableColumn[] getColumns() { - return fTable.getColumns(); - } - - /** - * Method getItem. - * @param point Point the coordinates in the table - * @return TableItem the corresponding table item - */ - public TableItem getItem(Point point) { - return fTable.getItem(point); - } - - /** - * Method resize. - */ - private void resize() { - // Compute the numbers of rows that fit the new area - int tableHeight = Math.max(0, getSize().y - fTable.getHeaderHeight()); - int itemHeight = getItemHeight(); - fTableRows = Math.min((tableHeight + itemHeight - 1) / itemHeight, fTableItemCount); - - if (fTableTopEventRank + fFullyVisibleRows > fTableItemCount) { - // If we are at the end, get elements before to populate - fTableTopEventRank = Math.max(0, fTableItemCount - fFullyVisibleRows); - refreshTable(); - } else if (fTableRows > fTable.getItemCount() || fTableItemCount < fTable.getItemCount()) { - // Only refresh if new table items are needed or if table items need to be deleted - refreshTable(); - } - - } - - // ------------------------------------------------------------------------ - // Controls interactions - // ------------------------------------------------------------------------ - - /** - * Method setFocus. - * @return boolean is this visible? - */ - @Override - public boolean setFocus() { - boolean isVisible = isVisible(); - if (isVisible) { - fTable.setFocus(); - } - return isVisible; - } - - /** - * Method refresh. - */ - public void refresh() { - boolean done = refreshTable(); - if (!done) { - return; - } - if (fPendingSelection) { - fPendingSelection = false; - TableItem item = null; - if (fSelectedEventRank >= 0 && fSelectedEventRank < fFrozenRowCount) { - item = fTable.getItem(fSelectedEventRank); - } else if (fSelectedEventRank >= fTableTopEventRank + fFrozenRowCount && fSelectedEventRank - fTableTopEventRank < fTable.getItemCount()) { - item = fTable.getItem(fSelectedEventRank - fTableTopEventRank); - } - if (item != null) { - Event e = new Event(); - e.item = item; - fTable.notifyListeners(SWT.Selection, e); - } - } - } - - /** - * Method setColumnHeaders. - * - * @param columnData - * ColumnData[] the columndata array. - */ - @Deprecated - public void setColumnHeaders(ColumnData columnData[]) { - /* No-op */ - } - - /** - * Method removeAll. - * @return int 0 the number of elements in the table - */ - public int removeAll() { - setItemCount(0); - fSlider.setMaximum(0); - fTable.removeAll(); - fSelectedEventRank = -1; - fSelectedBeginRank = fSelectedEventRank; - return 0; - } - - /** - * Method refreshTable. - * @return true if all table items have been refreshed, false otherwise - */ - private boolean refreshTable() { - boolean done = true; - for (int i = 0; i < fTableRows; i++) { - if (i + fTableTopEventRank < fTableItemCount) { - TableItem tableItem; - if (i < fTable.getItemCount()) { - tableItem = fTable.getItem(i); - } else { - tableItem = new TableItem(fTable, SWT.NONE); - } - done &= setDataItem(i, tableItem); // false if table item not updated yet in this thread - } else { - if (fTable.getItemCount() > fTableItemCount - fTableTopEventRank) { - fTable.remove(fTableItemCount - fTableTopEventRank); - } - } - } - if (done) { - refreshSelection(); - } else { - fTable.deselectAll(); - } - return done; - } - - private void refreshSelection() { - int lastRowOffset = fTableTopEventRank + fTableRows - 1; - int startRank = Math.min(fSelectedBeginRank, fSelectedEventRank); - int endRank = Math.max(fSelectedBeginRank, fSelectedEventRank); - int start = Integer.MAX_VALUE; - int end = Integer.MIN_VALUE; - if (startRank < fFrozenRowCount) { - start = startRank; - } else if (startRank < fTableTopEventRank + fFrozenRowCount) { - start = fFrozenRowCount; - } else if (startRank <= lastRowOffset) { - start = startRank - fTableTopEventRank; - } - if (endRank < fFrozenRowCount) { - end = endRank; - } else if (endRank < fTableTopEventRank + fFrozenRowCount) { - end = fFrozenRowCount - 1; - } else if (endRank <= lastRowOffset) { - end = endRank - fTableTopEventRank; - } else { - end = fTableRows - 1; - } - if (start <= end) { - fTable.setSelection(start, end); - if (startRank == fSelectedEventRank) { - fTable.select(start); - } else { - fTable.select(end); - } - } else { - fTable.deselectAll(); - } - } - - /** - * Selects the item at the given zero-relative index in the receiver. - * The current selection is first cleared, then the new item is selected, - * and if necessary the receiver is scrolled to make the new selection visible. - * - * @param index the index of the item to select - * - * @exception SWTException
      - *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • - *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • - *
    - */ - public void setSelection(int index) { - if (fTableItemCount > 0) { - int i = Math.min(index, fTableItemCount - 1); - i = Math.max(i, 0); - - fSelectedEventRank = i; - fSelectedBeginRank = fSelectedEventRank; - if ((i < fTableTopEventRank + fFrozenRowCount && i >= fFrozenRowCount) || - (i >= fTableTopEventRank + fFullyVisibleRows)) { - int lastPageTopEntryRank = Math.max(0, fTableItemCount - fFullyVisibleRows); - fTableTopEventRank = Math.max(0, Math.min(lastPageTopEntryRank, i - fFrozenRowCount - fFullyVisibleRows / 2)); - } - if (fFullyVisibleRows < fTableItemCount) { - fSlider.setSelection(fTableTopEventRank); - } - - refreshTable(); - } - } - - /** - * Returns the zero-relative index of the item which is currently - * selected in the receiver, or -1 if no item is selected. - * - * @return the index of the selected item - */ - public int getSelectionIndex() { - return fSelectedEventRank; - } - - /** - * Returns an index array representing the selection range. If there is a - * single item selected the array holds one index. If there is a selected - * range the first item in the array is the start index of the selection and - * the second item is the end index of the selection, which is the item most - * recently selected. The array is empty if no items are selected. - *

    - * @return the array of indices of the selected items - * @since 2.1 - */ - public int[] getSelectionIndices() { - if (fSelectedEventRank < 0 || fSelectedBeginRank < 0) { - return new int[] {}; - } else if (fSelectedEventRank == fSelectedBeginRank) { - return new int[] { fSelectedEventRank }; - } - return new int[] { fSelectedBeginRank, fSelectedEventRank }; - } - - /** - * Method setFrozenRowCount. - * @param count int the number of rows to freeze from the top row - */ - public void setFrozenRowCount(int count) { - fFrozenRowCount = count; - refreshTable(); - } - - /** - * Method createTableEditor. - * @return a TableEditor of the table - */ - public TableEditor createTableEditor() { - return new TableEditor(fTable); - } - - /** - * Method createTableEditorControl. - * @param control Class - * @return Control - */ - public Control createTableEditorControl(Class control) { - try { - return control.getConstructor(Composite.class, int.class).newInstance(new Object[] {fTable, SWT.NONE}); - } catch (Exception e) { - Activator.getDefault().logError("Error creating table editor control", e); //$NON-NLS-1$ - } - return null; - } - - /** - * @return the tooltipProvider - */ - public TooltipProvider getTooltipProvider() { - return tooltipProvider; - } - - /** - * @param tooltipProvider the tooltipProvider to set - */ - public void setTooltipProvider(TooltipProvider tooltipProvider) { - this.tooltipProvider = tooltipProvider; - } - - /** - * @return the doubleClickListener - */ - public IDoubleClickListener getDoubleClickListener() { - return doubleClickListener; - } - - /** - * @param doubleClickListener the doubleClickListener to set - */ - public void setDoubleClickListener(IDoubleClickListener doubleClickListener) { - this.doubleClickListener = doubleClickListener; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/virtualtable/TooltipProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/virtualtable/TooltipProvider.java deleted file mode 100644 index 5ccfc9be81..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/virtualtable/TooltipProvider.java +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2013 Kalray, Ericsson. - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xavier Raynaud - Initial API and implementation - ******************************************************************************/ -package org.eclipse.linuxtools.tmf.ui.widgets.virtualtable; - -/** - * An interface to get tooltips. - * @author Xavier Raynaud - * @version 1.0 - */ -public interface TooltipProvider { - - /** - * get a Tooltip for a given column in a table row. (a cell if you will) - * @param column the column - * @param data the object being selected. (quite often a "TableItem") - * @return the string of text to display in the tooltip. - */ - String getTooltip(int column, Object data); - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/Activator.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/Activator.java new file mode 100644 index 0000000000..826a1c2d79 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/Activator.java @@ -0,0 +1,245 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.graphics.Image; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.ui.TmfUiRefreshHandler; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.viewers.events.TmfEventAdapterFactory; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.eclipse.ui.preferences.ScopedPreferenceStore; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle. + */ +public class Activator extends AbstractUIPlugin { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The plug-in ID + */ + public static final String PLUGIN_ID = "org.eclipse.tracecompass.tmf.ui"; //$NON-NLS-1$ + /** + * The core plug-in ID + */ + public static final String PLUGIN_CORE_ID = "org.eclipse.tracecompass.tmf.core"; //$NON-NLS-1$ + + /** + * The shared instance + */ + private static Activator plugin; + + private TmfEventAdapterFactory fTmfEventAdapterFactory; + private IPreferenceStore fCorePreferenceStore; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructor + */ + public Activator() { + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * Returns the TMF UI plug-in instance. + * + * @return the TMF UI plug-in instance. + */ + public static Activator getDefault() { + return plugin; + } + + // ------------------------------------------------------------------------ + // AbstractUIPlugin + // ------------------------------------------------------------------------ + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + TmfUiRefreshHandler.getInstance(); // to classload/initialize it + TmfUiTracer.init(); + TmfTraceElement.init(); + TmfExperimentElement.init(); + + fTmfEventAdapterFactory = new TmfEventAdapterFactory(); + Platform.getAdapterManager().registerAdapters(fTmfEventAdapterFactory, ITmfEvent.class); + } + + @Override + public void stop(BundleContext context) throws Exception { + TmfUiTracer.stop(); + TmfUiRefreshHandler.getInstance().dispose(); + plugin = null; + + Platform.getAdapterManager().unregisterAdapters(fTmfEventAdapterFactory); + super.stop(context); + } + + /** + * Returns a preference store for org.eclipse.linux.tmf.core preferences + * @return the preference store + */ + public IPreferenceStore getCorePreferenceStore() { + if (fCorePreferenceStore == null) { + fCorePreferenceStore= new ScopedPreferenceStore(InstanceScope.INSTANCE, PLUGIN_CORE_ID); + } + return fCorePreferenceStore; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Gets an image object using given path within plug-in. + * + * @param path + * path to image file + * + * @return image object + */ + public Image getImageFromPath(String path) { + return getImageDescripterFromPath(path).createImage(); + } + + /** + * Gets an image descriptor using given path within plug-in. + * + * @param path + * path to image file + * + * @return image descriptor object + */ + public ImageDescriptor getImageDescripterFromPath(String path) { + return AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, path); + } + + /** + * Gets a image object from the image registry based on the given path. If + * the image is not in the registry it will be registered. + * + * @param path + * to the image file + * @return image object + */ + public Image getImageFromImageRegistry(String path) { + Image icon = getImageRegistry().get(path); + if (icon == null) { + icon = getImageDescripterFromPath(path).createImage(); + plugin.getImageRegistry().put(path, icon); + } + return icon; + } + + @Override + protected void initializeImageRegistry(ImageRegistry reg) { + reg.put(ITmfImageConstants.IMG_UI_ZOOM, getImageFromPath(ITmfImageConstants.IMG_UI_ZOOM)); + reg.put(ITmfImageConstants.IMG_UI_ZOOM_IN, getImageFromPath(ITmfImageConstants.IMG_UI_ZOOM_IN)); + reg.put(ITmfImageConstants.IMG_UI_ZOOM_OUT, getImageFromPath(ITmfImageConstants.IMG_UI_ZOOM_OUT)); + reg.put(ITmfImageConstants.IMG_UI_SEQ_DIAGRAM_OBJ, getImageFromPath(ITmfImageConstants.IMG_UI_SEQ_DIAGRAM_OBJ)); + reg.put(ITmfImageConstants.IMG_UI_ARROW_COLLAPSE_OBJ, getImageFromPath(ITmfImageConstants.IMG_UI_ARROW_COLLAPSE_OBJ)); + reg.put(ITmfImageConstants.IMG_UI_ARROW_UP_OBJ, getImageFromPath(ITmfImageConstants.IMG_UI_ARROW_UP_OBJ)); + reg.put(ITmfImageConstants.IMG_UI_CONFLICT, getImageFromPath(ITmfImageConstants.IMG_UI_CONFLICT)); + } + + /** + * Logs a message with severity INFO in the runtime log of the plug-in. + * + * @param message + * A message to log + */ + public void logInfo(String message) { + getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity INFO in the runtime log of the + * plug-in. + * + * @param message + * A message to log + * @param exception + * A exception to log + */ + public void logInfo(String message, Throwable exception) { + getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message, exception)); + } + + /** + * Logs a message and exception with severity WARNING in the runtime log of + * the plug-in. + * + * @param message + * A message to log + */ + public void logWarning(String message) { + getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity WARNING in the runtime log of + * the plug-in. + * + * @param message + * A message to log + * @param exception + * A exception to log + */ + public void logWarning(String message, Throwable exception) { + getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message, exception)); + } + + /** + * Logs a message and exception with severity ERROR in the runtime log of + * the plug-in. + * + * @param message + * A message to log + */ + public void logError(String message) { + getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message)); + } + + /** + * Logs a message and exception with severity ERROR in the runtime log of + * the plug-in. + * + * @param message + * A message to log + * @param exception + * A exception to log + */ + public void logError(String message, Throwable exception) { + getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, exception)); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/ITmfImageConstants.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/ITmfImageConstants.java new file mode 100755 index 0000000000..9462b5f713 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/ITmfImageConstants.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - initial API and implementation + * Patrick Tasse - added icons + *******************************************************************************/ +package org.eclipse.tracecompass.internal.tmf.ui; + +/** + * Names for generic icons and buttons used in TMF + */ +@SuppressWarnings({"nls", "javadoc"}) +public interface ITmfImageConstants { + + public static final String ICONS_PATH = "icons/"; //$NON-NLS-1$ + + /* elcl16 */ + public static final String IMG_UI_HOME_MENU = ICONS_PATH + "elcl16/home_nav.gif"; + public static final String IMG_UI_SELECT_MENU = ICONS_PATH + "elcl16/select_menu.gif"; + public static final String IMG_UI_ZOOM_IN_MENU = ICONS_PATH + "elcl16/zoomin_nav.gif"; + public static final String IMG_UI_ZOOM_OUT_MENU = ICONS_PATH + "elcl16/zoomout_nav.gif"; + public static final String IMG_UI_FILTERS = ICONS_PATH + "elcl16/filter_items.gif"; + public static final String IMG_UI_SEARCH_SEQ = ICONS_PATH + "elcl16/search_seqdiag_menu.gif"; + public static final String IMG_UI_NEXT_PAGE = ICONS_PATH + "elcl16/next_menu.gif"; + public static final String IMG_UI_PREV_PAGE = ICONS_PATH + "elcl16/prev_menu.gif"; + public static final String IMG_UI_GOTO_PAGE = ICONS_PATH + "elcl16/gotopage_menu.gif"; + public static final String IMG_UI_NODE_START = ICONS_PATH + "elcl16/node_end.gif"; + public static final String IMG_UI_NODE_END = ICONS_PATH + "elcl16/node_start.gif"; + public static final String IMG_UI_SEARCH_MATCH = ICONS_PATH + "elcl16/search_match.gif"; + public static final String IMG_UI_FIRST_PAGE = ICONS_PATH + "elcl16/backward_nav.gif"; + public static final String IMG_UI_LAST_PAGE = ICONS_PATH + "elcl16/forward_nav.gif"; + public static final String IMG_UI_SHOW_LEGEND = ICONS_PATH + "elcl16/show_legend.gif"; + public static final String IMG_UI_NEXT_EVENT = ICONS_PATH + "elcl16/next_event.gif"; + public static final String IMG_UI_PREV_EVENT = ICONS_PATH + "elcl16/prev_event.gif"; +// public static final String IMG_UI_NEXT_ITEM = ICONS_PATH + "elcl16/next_item.gif"; +// public static final String IMG_UI_PREV_ITEM = ICONS_PATH + "elcl16/prev_item.gif"; + public static final String IMG_UI_NEXT_ITEM = IMG_UI_NEXT_PAGE; + public static final String IMG_UI_PREV_ITEM = IMG_UI_PREV_PAGE; + public static final String IMG_UI_PIN_VIEW = ICONS_PATH + "elcl16/pin_view.gif"; + public static final String IMG_UI_HIDE_ARROWS = ICONS_PATH + "elcl16/hide_arrows.gif"; + public static final String IMG_UI_FOLLOW_ARROW_FORWARD = ICONS_PATH + "elcl16/follow_arrow_fwd.gif"; + public static final String IMG_UI_FOLLOW_ARROW_BACKWARD = ICONS_PATH + "elcl16/follow_arrow_bwd.gif"; + public static final String IMG_UI_SHOW_LOST_EVENTS = ICONS_PATH + "elcl16/hide_lost_events.gif"; + public static final String IMG_UI_SHOW_HIST_TRACES = ICONS_PATH + "elcl16/show_hist_traces.gif"; + + /* eview16 */ + public static final String IMG_UI_SEQ_DIAGRAM_OBJ = ICONS_PATH + "eview16/sequencediagram_view.gif"; + + /* obj16 */ + public static final String IMG_UI_ZOOM = ICONS_PATH + "obj16/zoom_mask.bmp"; + public static final String IMG_UI_ZOOM_IN = ICONS_PATH + "obj16/zoomin_obj.bmp"; + public static final String IMG_UI_ZOOM_OUT = ICONS_PATH + "obj16/zoomout_obj.bmp"; + public static final String IMG_UI_ARROW_COLLAPSE_OBJ = ICONS_PATH + "obj16/arrow_colapse.bmp"; + public static final String IMG_UI_ARROW_UP_OBJ = ICONS_PATH + "obj16/arrow_up.bmp"; + + /* wizban */ + public static final String IMG_UI_CONFLICT = ICONS_PATH + "wizban/conflict_stat.gif"; +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/Messages.java new file mode 100644 index 0000000000..5799f652c9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/Messages.java @@ -0,0 +1,306 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui; + +import org.eclipse.osgi.util.NLS; + +/** + * TMF message bundle + */ +@SuppressWarnings("javadoc") +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.tmf.ui.messages"; //$NON-NLS-1$ + + public static String ManageCustomParsersDialog_ConflictMessage; + public static String ManageCustomParsersDialog_ConflictRenameButtonLabel; + public static String ManageCustomParsersDialog_ConflictSkipButtonLabel; + public static String ManageCustomParsersDialog_DeleteButtonLabel; + public static String ManageCustomParsersDialog_DeleteConfirmation; + public static String ManageCustomParsersDialog_DeleteParserDialogHeader; + public static String ManageCustomParsersDialog_DialogHeader; + public static String ManageCustomParsersDialog_EditButtonLabel; + public static String ManageCustomParsersDialog_ExportButtonLabel; + public static String ManageCustomParsersDialog_ExportParserSelection; + public static String ManageCustomParsersDialog_ImportButtonLabel; + public static String ManageCustomParsersDialog_ImportParserSelection; + public static String ManageCustomParsersDialog_NewButtonLabel; + public static String ManageCustomParsersDialog_TextButtonLabel; + + public static String TmfEventsTable_AddBookmarkActionText; + public static String TmfEventsTable_AddBookmarkDialogMessage; + public static String TmfEventsTable_AddBookmarkDialogTitle; + public static String TmfEventsTable_ApplyPresetFilterMenuName; + public static String TmfEventsTable_ClearFiltersActionText; + public static String TmfEventsTable_CollapseFilterMenuName; + public static String TmfEventsTable_ContentColumnHeader; + public static String TmfEventsTable_Export_to_text; + public static String TmfEventsTable_FilterHint; + public static String TmfEventsTable_HideRawActionText; + public static String TmfEventsTable_HideTableActionText; + public static String TmfEventsTable_MultipleBookmarksToolTip; + public static String TmfEventsTable_OpenSourceCodeActionText; + public static String TmfEventsTable_OpenSourceCodeNotFound; + public static String TmfEventsTable_OpenSourceCodeSelectFileDialogTitle; + public static String TmfEventsTable_OpenModelActionText; + public static String TmfEventsTable_OpenModelUnsupportedURI; + public static String TmfEventsTable_ReferenceColumnHeader; + public static String TmfEventsTable_RemoveBookmarkActionText; + public static String TmfEventsTable_SearchHint; + public static String TmfEventsTable_SearchingJobName; + public static String TmfEventsTable_ShowFilterBarActionText; + public static String TmfEventsTable_ShowRawActionText; + public static String TmfEventsTable_ShowSearchBarActionText; + public static String TmfEventsTable_ShowTableActionText; + public static String TmfEventsTable_SourceColumnHeader; + public static String TmfEventsTable_TimestampColumnHeader; + public static String TmfEventsTable_TypeColumnHeader; + + public static String TmfTimeFilterDialog_EDIT_PROFILING_OPTIONS; + public static String TmfTimeFilterDialog_TRACE_FILTER; + public static String TmfTimeFilterDialog_TRACE_FILTER_DESC; + public static String TmfTimeFilterDialog_TRACE_ID; + public static String TmfTimeFilterDialog_TRACE_NAME; + public static String TmfTimeLegend_LEGEND; + public static String TmfTimeLegend_TRACE_STATES; + public static String TmfTimeLegend_TRACE_STATES_TITLE; + public static String TmfTimeLegend_WINDOW_TITLE; + public static String TmfTimeLegend_StateTypeName; + public static String TmfTimeFilterDialog_WINDOW_TITLE; + public static String TmfTimeFilterDialog_MESSAGE; + public static String TmfTimeFilterDialog_CHECK_ALL; + public static String TmfTimeFilterDialog_UNCHECK_ALL; + public static String TmfTimeFilterDialog_CHECK_SELECTED; + public static String TmfTimeFilterDialog_UNCHECK_SELECTED; + public static String TmfTimeFilterDialog_CHECK_SUBTREE; + public static String TmfTimeFilterDialog_UNCHECK_SUBTREE; + + public static String TmfTimeTipHandler_DURATION; + public static String TmfTimeTipHandler_LINK_SOURCE; + public static String TmfTimeTipHandler_LINK_SOURCE_TIME; + public static String TmfTimeTipHandler_LINK_TARGET; + public static String TmfTimeTipHandler_LINK_TARGET_TIME; + public static String TmfTimeTipHandler_LINK_TIME; + public static String TmfTimeTipHandler_TRACE_DATE; + public static String TmfTimeTipHandler_TRACE_EVENT_TIME; + public static String TmfTimeTipHandler_TRACE_START_TIME; + public static String TmfTimeTipHandler_TRACE_STATE; + public static String TmfTimeTipHandler_TRACE_STOP_TIME; + + public static String TmfTimeGraphCombo_FilterActionNameText; + public static String TmfTimeGraphCombo_FilterActionToolTipText; + + public static String TmfTimeGraphViewer_ResetScaleActionNameText; + public static String TmfTimeGraphViewer_ResetScaleActionToolTipText; + public static String TmfTimeGraphViewer_LegendActionNameText; + public static String TmfTimeGraphViewer_LegendActionToolTipText; + public static String TmfTimeGraphViewer_NextEventActionNameText; + public static String TmfTimeGraphViewer_NextEventActionToolTipText; + public static String TmfTimeGraphViewer_PreviousEventActionNameText; + public static String TmfTimeGraphViewer_PreviousEventActionToolTipText; + public static String TmfTimeGraphViewer_NextItemActionNameText; + public static String TmfTimeGraphViewer_NextItemActionToolTipText; + public static String TmfTimeGraphViewer_PreviousItemActionNameText; + public static String TmfTimeGraphViewer_PreviousItemActionToolTipText; + public static String TmfTimeGraphViewer_ZoomInActionNameText; + public static String TmfTimeGraphViewer_ZoomInActionToolTipText; + public static String TmfTimeGraphViewer_ZoomOutActionNameText; + public static String TmfTimeGraphViewer_ZoomOutActionToolTipText; + public static String TmfTimeGraphViewer_HideArrowsActionNameText; + public static String TmfTimeGraphViewer_HideArrowsActionToolTipText; + public static String TmfTimeGraphViewer_FollowArrowForwardActionNameText; + public static String TmfTimeGraphViewer_FollowArrowForwardActionToolTipText; + public static String TmfTimeGraphViewer_FollowArrowBackwardActionNameText; + public static String TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText; + + public static String Utils_ClockCyclesUnit; + + public static String ColorsView_AddActionToolTipText; + public static String ColorsView_BackgroundButtonText; + public static String ColorsView_BackgroundDialogText; + public static String ColorsView_DeleteActionToolTipText; + public static String ColorsView_ExportActionToolTipText; + public static String ColorsView_FilterButtonText; + public static String ColorsView_ForegroundButtonText; + public static String ColorsView_ForegroundDialogText; + public static String ColorsView_ImportActionToolTipText; + public static String ColorsView_ImportOverwriteDialogMessage1; + public static String ColorsView_ImportOverwriteDialogMessage2; + public static String ColorsView_ImportOverwriteDialogTitle; + public static String ColorsView_MoveDownActionToolTipText; + public static String ColorsView_MoveUpActionToolTipText; + public static String ColorsView_TickButtonText; + public static String TickColorDialog_TickColorDialogTitle; + + public static String CustomTxtParserInputWizardPage_addChildLine; + public static String CustomTxtParserInputWizardPage_addGroup; + public static String CustomTxtParserInputWizardPage_addNextLine; + public static String CustomTxtParserInputWizardPage_append; + public static String CustomTxtParserInputWizardPage_appendWith; + public static String CustomTxtParserInputWizardPage_capturedGroup; + public static String CustomTxtParserInputWizardPage_cardinality; + public static String CustomTxtParserInputWizardPage_category; + public static String CustomTxtParserInputWizardPage_desccriptionEdit; + public static String CustomTxtParserInputWizardPage_descriptionNew; + public static String CustomTxtParserInputWizardPage_format; + public static String CustomTxtParserInputWizardPage_group; + public static String CustomTxtParserInputWizardPage_highlightAll; + public static String CustomTxtParserInputWizardPage_logType; + public static String CustomTxtParserInputWizardPage_matchingOtherLine; + public static String CustomTxtParserInputWizardPage_matchingRootLine; + public static String CustomTxtParserInputWizardPage_max; + public static String CustomTxtParserInputWizardPage_min; + public static String CustomTxtParserInputWizardPage_moveDown; + public static String CustomTxtParserInputWizardPage_moveUp; + public static String CustomTxtParserInputWizardPage_name; + public static String CustomTxtParserInputWizardPage_newGroup; + public static String CustomTxtParserInputWizardPage_noMatch; + public static String CustomTxtParserInputWizardPage_noMatchingGroup; + public static String CustomTxtParserInputWizardPage_noMatchingLine; + public static String CustomTxtParserInputWizardPage_noMatchingTimestamp; + public static String CustomTxtParserInputWizardPage_noMathcingLine; + public static String CustomTxtParserInputWizardPage_nonMatchingLine; + public static String CustomTxtParserInputWizardPage_noTimestampGroup; + public static String CustomTxtParserInputWizardPage_preview; + public static String CustomTxtParserInputWizardPage_previewInput; + public static String CustomTxtParserInputWizardPage_previewLegend; + public static String CustomTxtParserInputWizardPage_regularExpression; + public static String CustomTxtParserInputWizardPage_regularExpressionHelp; + public static String CustomTxtParserInputWizardPage_removeGroup; + public static String CustomTxtParserInputWizardPage_removeLine; + public static String CustomTxtParserInputWizardPage_set; + public static String CustomTxtParserInputWizardPage_timestampFormat; + public static String CustomTxtParserInputWizardPage_timestampFormatHelp; + public static String CustomTxtParserInputWizardPage_uncapturedText; + public static String CustomTxtParserInputWizardPage_unidentifiedCaptureGroup; + public static String CustomTxtParserInputWizardPage_windowTitleEdit; + public static String CustomTxtParserInputWizardPage_windowTitleNew; + public static String CustomTxtParserOutputWizardPage_description; + public static String CustomTxtParserOutputWizardPage_moveAfter; + public static String CustomTxtParserOutputWizardPage_moveBefore; + public static String CustomTxtParserOutputWizardPage_visible; + public static String CustomXmlParserInputWizardPage_emptyCategoryError; + public static String CustomXmlParserInputWizardPage_emptyLogTypeError; + public static String CustomXmlParserInputWizardPage_invalidCategoryError; + public static String CustomXmlParserInputWizardPage_invalidLogTypeError; + public static String CustomXmlParserInputWizardPage_duplicatelogTypeError; + public static String CustomXmlParserInputWizardPage_noDocumentError; + public static String CustomXmlParserInputWizardPage_missingLogEntryError; + public static String CustomXmlParserInputWizardPage_missingTimestampFmtError; + public static String CustomXmlParserInputWizardPage_missingDocumentElementError; + public static String CustomXmlParserInputWizardPage_noTimestampElementOrAttribute; + public static String CustomXmlParserInputWizardPage_elementMissingNameError; + public static String CustomXmlParserInputWizardPage_elementMissingInputNameError; + public static String CustomXmlParserInputWizardPage_elementMissingTimestampFmtError; + public static String CustomXmlParserInputWizardPage_elementInvalidTimestampFmtError; + public static String CustomXmlParserInputWizardPage_elementDuplicateNameError; + public static String CustomXmlParserInputWizardPage_attributeMissingNameError; + public static String CustomXmlParserInputWizardPage_attributeMissingInputNameError; + public static String CustomXmlParserInputWizardPage_attributeMissingTimestampFmtError; + public static String CustomXmlParserInputWizardPage_attributeInvalidTimestampFmtError; + public static String CustomXmlParserInputWizardPage_attributeDuplicateNameError; + public static String CustomXmlParserInputWizardPage_addAttribute; + public static String CustomXmlParserInputWizardPage_addChildElement; + public static String CustomXmlParserInputWizardPage_addDocumentEleemnt; + public static String CustomXmlParserInputWizardPage_addDocumentElement; + public static String CustomXmlParserInputWizardPage_addNextElement; + public static String CustomXmlParserInputWizardPage_append; + public static String CustomXmlParserInputWizardPage_appendWith; + public static String CustomXmlParserInputWizardPage_attibute; + public static String CustomXmlParserInputWizardPage_category; + public static String CustomXmlParserInputWizardPage_descriptionEdit; + public static String CustomXmlParserInputWizardPage_descriptionNew; + public static String CustomXmlParserInputWizardPage_elementName; + public static String CustomXmlParserInputWizardPage_feelingLucky; + public static String CustomXmlParserInputWizardPage_format; + public static String CustomXmlParserInputWizardPage_logEntry; + public static String CustomXmlParserInputWizardPage_logType; + public static String CustomXmlParserInputWizardPage_moveDown; + public static String CustomXmlParserInputWizardPage_moveUp; + public static String CustomXmlParserInputWizardPage_name; + public static String CustomXmlParserInputWizardPage_newAttibute; + public static String CustomXmlParserInputWizardPage_noMatchingAttribute; + public static String CustomXmlParserInputWizardPage_noMatch; + public static String CustomXmlParserInputWizardPage_noMatchingElement; + public static String CustomXmlParserInputWizardPage_preview; + public static String CustomXmlParserInputWizardPage_previewInput; + public static String CustomXmlParserInputWizardPage_removeAttribute; + public static String CustomXmlParserInputWizardPage_removeElement; + public static String CustomXmlParserInputWizardPage_set; + public static String CustomXmlParserInputWizardPage_tagName; + public static String CustomXmlParserInputWizardPage_timestampFormat; + public static String CustomXmlParserInputWizardPage_timestampFormatHelp; + public static String CustomXmlParserInputWizardPage_titleEdit; + public static String CustomXmlParserInputWizardPage_titleNew; + public static String CustomXmlParserOutputWizardPage_description; + public static String CustomXmlParserOutputWizardPage_moveAfter; + public static String CustomXmlParserOutputWizardPage_moveBefore; + public static String CustomXmlParserOutputWizardPage_visible; + + public static String FilterDialog_FilterDialogTitle; + public static String FilterView_AddActionToolTipText; + public static String FilterView_DeleteActionToolTipText; + public static String FilterView_ExportActionToolTipText; + public static String FilterView_FileDialogFilterName; + public static String FilterView_ImportActionToolTipText; + public static String FilterView_SaveActionToolTipText; + public static String FilterViewer_EmptyTreeHintText; + public static String FilterViewer_CommonCategory; + public static String FilterViewer_AlphaButtonText; + public static String FilterViewer_FieldLabel; + public static String FilterViewer_FilterNameHint; + public static String FilterViewer_IgnoreCaseButtonText; + public static String FilterViewer_NameLabel; + public static String FilterViewer_NewPrefix; + public static String FilterViewer_NotLabel; + public static String FilterViewer_NumButtonText; + public static String FilterViewer_RegexHint; + public static String FilterViewer_RegexLabel; + public static String FilterViewer_ResultLabel; + public static String FilterViewer_Subfilter_ToolTip; + public static String FilterViewer_TimestampButtonText; + public static String FilterViewer_TypeLabel; + public static String FilterViewer_ValueHint; + public static String FilterViewer_ValueLabel; + + public static String TmfView_PinActionNameText; + public static String TmfView_PinActionToolTipText; + + public static String CallStackPresentationProvider_Thread; + public static String CallStackView_FunctionColumn; + public static String CallStackView_DepthColumn; + public static String CallStackView_EntryTimeColumn; + public static String CallStackView_ExitTimeColumn; + public static String CallStackView_DurationColumn; + public static String CallStackView_StackInfoNotAvailable; + public static String CallStackView_SortByThreadName; + public static String CallStackView_SortByThreadId; + public static String CallStackView_SortByThreadTime; + public static String CallStackView_ImportMappingButtonText; + public static String CallStackView_ImportMappingButtonTooltip; + public static String CallStackView_ImportMappingDialogTitle; + public static String CallStackView_ImportMappingJobName; + + public static String CallStackView_ImportBinaryFileButtonText; + public static String CallStackView_ImportBinaryFileButtonTooltip; + public static String CallStackView_ImportBinaryFileDialogTitle; + + public static String ExportToTextJob_Export_to; + public static String ExportToTextJob_Export_trace_to; + public static String ExportToTextJob_Unable_to_export_trace; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/TmfUiTracer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/TmfUiTracer.java new file mode 100644 index 0000000000..ee62ba94a3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/TmfUiTracer.java @@ -0,0 +1,245 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; + +import org.eclipse.core.runtime.Platform; + +/** + * Tracer class for the tmf.ui plugin + */ +@SuppressWarnings("nls") +public class TmfUiTracer { + + private static String pluginID = Activator.PLUGIN_ID; + + static boolean ERROR = false; + static boolean WARNING = false; + static boolean INFO = false; + + static boolean INDEX = false; + static boolean DISPLAY = false; + static boolean SORTING = false; + + private static String LOGNAME = "traceUI.log"; + private static BufferedWriter fTraceLog = null; + + private static BufferedWriter openLogFile(String filename) { + BufferedWriter outfile = null; + try { + outfile = new BufferedWriter(new FileWriter(filename)); + } catch (IOException e) { + Activator.getDefault().logError("Error creating log file " + LOGNAME, e); //$NON-NLS-1$ + } + return outfile; + } + + /** + * Initialize tracing + */ + public static void init() { + + String traceKey; + boolean isTracing = false; + + traceKey = Platform.getDebugOption(pluginID + "/error"); + if (traceKey != null) { + ERROR = (Boolean.valueOf(traceKey)).booleanValue(); + isTracing |= ERROR; + } + + traceKey = Platform.getDebugOption(pluginID + "/warning"); + if (traceKey != null) { + WARNING = (Boolean.valueOf(traceKey)).booleanValue(); + isTracing |= WARNING; + } + + traceKey = Platform.getDebugOption(pluginID + "/info"); + if (traceKey != null) { + INFO = (Boolean.valueOf(traceKey)).booleanValue(); + isTracing |= INFO; + } + + traceKey = Platform.getDebugOption(pluginID + "/updateindex"); + if (traceKey != null) { + INDEX = (Boolean.valueOf(traceKey)).booleanValue(); + isTracing |= INDEX; + } + + traceKey = Platform.getDebugOption(pluginID + "/display"); + if (traceKey != null) { + DISPLAY = (Boolean.valueOf(traceKey)).booleanValue(); + isTracing |= DISPLAY; + } + + traceKey = Platform.getDebugOption(pluginID + "/sorting"); + if (traceKey != null) { + SORTING = (Boolean.valueOf(traceKey)).booleanValue(); + isTracing |= SORTING; + } + + // Create trace log file if needed + if (isTracing) { + fTraceLog = openLogFile(LOGNAME); + } + } + + /** + * Stop tracing + */ + public static void stop() { + if (fTraceLog == null) { + return; + } + + try { + fTraceLog.close(); + fTraceLog = null; + } catch (IOException e) { + Activator.getDefault().logError("Error closing log file " + LOGNAME, e); //$NON-NLS-1$ + } + } + + // ------------------------------------------------------------------------ + // Predicates + // ------------------------------------------------------------------------ + + /** + * @return If ERROR messages are traced + */ + public static boolean isErrorTraced() { + return ERROR; + } + + /** + * @return If INDEX messages are traced + */ + public static boolean isIndexTraced() { + return INDEX; + } + + /** + * @return If DISPLAY messages are traced + */ + public static boolean isDisplayTraced() { + return DISPLAY; + } + + /** + * @return If SORTING messages are traced + */ + public static boolean isSortingTraced() { + return SORTING; + } + + + // ------------------------------------------------------------------------ + // Tracing methods + // ------------------------------------------------------------------------ + + /** + * Trace a generic event + * + * @param msg + * The event's message + */ + public static void trace(String msg) { + // Leave when there is no place to write the message. + if (fTraceLog == null) { + return; + } + + long currentTime = System.currentTimeMillis(); + StringBuilder message = new StringBuilder("["); + message.append(currentTime / 1000); + message.append("."); + message.append(String.format("%1$03d", currentTime % 1000)); + message.append("] "); + message.append(msg); + + try { + fTraceLog.write(message.toString()); + fTraceLog.newLine(); + fTraceLog.flush(); + } catch (IOException e) { + Activator.getDefault().logError("Error writing to log file " + LOGNAME, e); //$NON-NLS-1$ + } + } + + /** + * Trace an INDEX event + * + * @param msg + * The event's message + */ + public static void traceIndex(String msg) { + String message = ("[INDEX] " + msg); + trace(message); + } + + /** + * Trace a DISPLAY event + * + * @param msg + * The event's message + */ + public static void traceDisplay(String msg) { + String message = ("[DISPLAY]" + msg); + trace(message); + } + + /** + * Trace a SORTING event + * + * @param msg + * The event's message + */ + public static void traceSorting(String msg) { + String message = ("[SORT] " + msg); + trace(message); + } + + /** + * Trace an ERROR event + * + * @param msg + * The event's message + */ + public static void traceError(String msg) { + String message = ("[ERR] Thread=" + Thread.currentThread().getId() + " " + msg); + trace(message); + } + + /** + * Trace a WARNING event + * + * @param msg + * The event's message + */ + public static void traceWarning(String msg) { + String message = ("[WARN] Thread=" + Thread.currentThread().getId() + " " + msg); + trace(message); + } + + /** + * Trace an INFO event + * + * @param msg + * The event's message + */ + public static void traceInfo(String msg) { + String message = ("[INF] Thread=" + Thread.currentThread().getId() + " " + msg); + trace(message); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/ExportToTextCommandHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/ExportToTextCommandHandler.java new file mode 100644 index 0000000000..c1203884a9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/ExportToTextCommandHandler.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Kalray, Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xavier Raynaud - Initial API and implementation + * Bernd Hufmann - Adapted to new events table column API + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.commands; + +import java.util.List; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.expressions.IEvaluationContext; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.tracecompass.tmf.core.filter.ITmfFilter; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; +import org.eclipse.ui.PlatformUI; + +/** + * This handler exports traces to text files. + * @author Xavier Raynaud + */ +public class ExportToTextCommandHandler extends AbstractHandler { + + /** Id of the export-to-text command */ + public static final String COMMAND_ID = "org.eclipse.linuxtools.tmf.ui.exportToText"; //$NON-NLS-1$ + /** + * Id used to retrieve the header (as a String) of the trace to export. + * This header is from the application context of this handler. + */ + public static final String TMF_EVENT_TABLE_COLUMNS_ID = "org.eclipse.linuxtools.tmf.ui.exportToText.columns"; //$NON-NLS-1$ + + /** + * Constructor + */ + public ExportToTextCommandHandler() { + } + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + List columns = getColumns(event.getApplicationContext()); + ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace(); + ITmfFilter filter = TmfTraceManager.getInstance().getCurrentFilter(); + if (trace != null) { + FileDialog fd = new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.SAVE); + fd.setFilterExtensions(new String[] { "*.csv", "*.*", "*" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + fd.setOverwrite(true); + final String s = fd.open(); + if (s != null) { + Job j = new ExportToTextJob(trace, filter, columns, s); + j.setUser(true); + j.schedule(); + } + } + return null; + } + + @SuppressWarnings("unchecked") + private static List getColumns(Object evaluationContext) { + if (evaluationContext instanceof IEvaluationContext) { + Object s = ((IEvaluationContext) evaluationContext).getVariable(TMF_EVENT_TABLE_COLUMNS_ID); + if (s instanceof List) { + return (List) s; + } + } + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/ExportToTextJob.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/ExportToTextJob.java new file mode 100644 index 0000000000..a0ccbe9ca4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/ExportToTextJob.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Kalray, Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xavier Raynaud - Initial API and implementation + * Bernd Hufmann - Adapted to new events table column API + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.commands; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.text.MessageFormat; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.osgi.util.NLS; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.core.filter.ITmfFilter; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; + +/** + * This job exports traces to text files. + * @author Xavier Raynaud + */ +public class ExportToTextJob extends Job { + + private static final int TOTAL_WORK = 100; + private static final int SLEEPING_INTERVAL = 100; + + /** the ExportToCSV job family */ + public static final Object ExportToCSVJobFamily = new Object(); + + private final ITmfTrace fTrace; + private final ITmfFilter fFilter; + private final List fColumns; + private final String destination; + + /** + * Job constructor. + * + * @param trace + * the trace to export + * @param filter + * the filter to apply when exporting the trace. may be null. + * @param columns + * the header to put at top of the exported file (may be null) + * @param destination + * the path of the file where the data is exported. + */ + public ExportToTextJob(ITmfTrace trace, ITmfFilter filter, List columns, String destination) { + super(MessageFormat.format(Messages.ExportToTextJob_Export_to, destination)); + this.fTrace = trace; + this.fFilter = filter; + this.fColumns = columns; + this.destination = destination; + } + + @Override + public IStatus run(IProgressMonitor monitor) { + monitor.beginTask(NLS.bind(Messages.ExportToTextJob_Export_trace_to, destination), TOTAL_WORK); + IStatus ret = saveImpl(monitor); + monitor.done(); + return ret; + } + + private IStatus saveImpl(IProgressMonitor monitor) { + try (final BufferedWriter bw = new BufferedWriter(new FileWriter(destination));) { + if (fColumns != null) { + boolean needTab = false; + for (TmfEventTableColumn column : fColumns) { + if (needTab) { + bw.write('\t'); + } + bw.write(column.getHeaderName()); + needTab = true; + } + bw.append('\n'); + } + return saveImpl(bw, monitor); + } catch (IOException ex) { + Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, + MessageFormat.format(Messages.ExportToTextJob_Unable_to_export_trace, destination), + ex); + return status; + } + } + + private IStatus saveImpl(Writer bw, IProgressMonitor monitor) { + ExportToTextRequest request = new ExportToTextRequest(bw, fFilter, fColumns); + fTrace.sendRequest(request); + int currentIndex = 0; + while (!request.isCompleted()) { + if (monitor.isCanceled()) { + request.cancel(); + return Status.CANCEL_STATUS; + } + int index = (int) (request.getNbRead() * TOTAL_WORK / fTrace.getNbEvents()); + if (index > currentIndex) { + int progress = index - currentIndex; + monitor.worked(progress); + currentIndex = index; + } + try { + Thread.sleep(SLEEPING_INTERVAL); + } catch (InterruptedException e) { + } + } + if (request.isFailed()) { + Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, + MessageFormat.format(Messages.ExportToTextJob_Unable_to_export_trace, destination), + request.getIOException()); + return status; + } + return Status.OK_STATUS; + } + + @Override + public boolean belongsTo(Object family) { + return ExportToCSVJobFamily.equals(family); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/ExportToTextRequest.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/ExportToTextRequest.java new file mode 100644 index 0000000000..4a1c6afce0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/ExportToTextRequest.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Kalray, Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xavier Raynaud - Initial API and implementation + * Bernd Hufmann - Adapted to new events table column API + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.commands; + +import java.io.IOException; +import java.io.Writer; +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.filter.ITmfFilter; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; + +/** + * This TMF Requests exports traces to text files. + * @author Xavier Raynaud + */ +public class ExportToTextRequest extends TmfEventRequest { + + private final Writer fWriter; + private final ITmfFilter fFilter; + private final List fColumns; + private IOException fIOException; + + /** + * Constructor + * @param w + * a Writer, typically a FileWriter. + * @param filter + * a TmfFilter, if we want to filter some events. May be null. + * @param columns + * the {@link TmfEventTableColumn} requesting the export (may be null) + */ + public ExportToTextRequest(Writer w, ITmfFilter filter, List columns) { + super(ITmfEvent.class, TmfTimeRange.ETERNITY, 0, ITmfEventRequest.ALL_DATA, ExecutionType.FOREGROUND); + this.fWriter = w; + this.fFilter = filter; + this.fColumns = columns; + } + + /** + * Gets the IOException thrown by this export request, if any. + * @return the fIoException + */ + public IOException getIOException() { + return fIOException; + } + + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + if (isCancelled()) { + return; + } + try { + if (fFilter == null || fFilter.matches(event)) { + if (fColumns != null) { + boolean needTab = false; + for (TmfEventTableColumn column : fColumns) { + if (needTab) { + fWriter.write('\t'); + } + fWriter.write(column.getItemString(event)); + needTab = true; + } + } else { // fallback to default formatting + fWriter.write(event.getTimestamp().toString()); + fWriter.write('\t'); + fWriter.write(event.getSource()); + fWriter.write('\t'); + fWriter.write(event.getType().getName()); + fWriter.write('\t'); + fWriter.write(event.getReference()); + fWriter.write('\t'); + ITmfEventField content = event.getContent(); + Object value = content.getValue(); + if (value != null) { + fWriter.write(value.toString()); + } + } + fWriter.write('\n'); + } + } catch (IOException ex) { + fIOException = ex; + fail(); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/ManageCustomParsersCommandHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/ManageCustomParsersCommandHandler.java new file mode 100644 index 0000000000..63d1765c56 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/ManageCustomParsersCommandHandler.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.commands; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.ui.dialogs.ManageCustomParsersDialog; + +/** + * Command handler for custom text parsers. + * + * @author Patrick Tassé + */ +public class ManageCustomParsersCommandHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ManageCustomParsersDialog dialog = new ManageCustomParsersDialog(Display.getDefault().getActiveShell()); + dialog.open(); + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/Messages.java new file mode 100644 index 0000000000..34c450030e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/Messages.java @@ -0,0 +1,37 @@ +/********************************************************************** + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + **********************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.commands; + +import org.eclipse.osgi.util.NLS; + +/** + * Messages for commands + * + * @author Marc-Andre Laperle + */ +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.tmf.ui.commands.messages"; //$NON-NLS-1$ + + /** Select trace directory */ + public static String OpenDirHandler_SelectTraceDirectory; + /** Select trace file */ + public static String OpenFileHandler_SelectTraceFile; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/OpenFileHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/OpenFileHandler.java new file mode 100644 index 0000000000..ee1d56893b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/OpenFileHandler.java @@ -0,0 +1,79 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Patrick Tasse - Add support for folder elements + **********************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.commands; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfOpenTraceHelper; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Open file handler, used to open files (not directories) + * + * @author Matthew Khouzam + */ +public class OpenFileHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) { + + ISelection currentSelection = HandlerUtil.getCurrentSelection(event); + // Menu Selection is not null for context-sensitive menu + ISelection menuSelection = HandlerUtil.getActiveMenuSelection(event); + + // Get trace path + final Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); + FileDialog fd = new FileDialog(shell); + fd.setText(Messages.OpenFileHandler_SelectTraceFile); + String filePath = fd.open(); + if (filePath == null) { + return null; + } + + try { + + TmfTraceFolder destinationFolder; + + if ((menuSelection != null) && (currentSelection instanceof IStructuredSelection)) { + // If handler is called from the context sensitive menu of a tracing project import to + // the traces folder from this project + destinationFolder = TmfHandlerUtil.getTraceFolderFromSelection(currentSelection); + } else { + // If handler is called from file menu import into default tracing project + IProject project = TmfProjectRegistry.createProject( + TmfCommonConstants.DEFAULT_TRACE_PROJECT_NAME, null, new NullProgressMonitor()); + TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true); + destinationFolder = projectElement.getTracesFolder(); + } + + TmfOpenTraceHelper.openTraceFromPath(destinationFolder, filePath, shell); + } catch (CoreException e) { + Activator.getDefault().logError(e.getMessage(), e); + } + return null; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/TmfHandlerUtil.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/TmfHandlerUtil.java new file mode 100644 index 0000000000..4d556dbbfc --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/TmfHandlerUtil.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + * Patrick Tasse - Add support for folder elements + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.commands; + +import org.eclipse.core.resources.IProject; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.tracecompass.tmf.ui.project.model.ITmfProjectModelElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; + +/** + * Utility methods for handlers + * + * @author Marc-Andre Laperle + */ +public class TmfHandlerUtil { + + /** + * Get the enclosing project from the selection + * + * @param selection + * the selection + * + * @return the enclosing project or null if selection is no enclosed by a + * project + */ + public static IProject getProjectFromSelection(ISelection selection) { + if (selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection) selection; + Object firstElement = structuredSelection.getFirstElement(); + if (firstElement instanceof ITmfProjectModelElement) { + ITmfProjectModelElement tmfProjectElement = (ITmfProjectModelElement) firstElement; + return tmfProjectElement.getProject().getResource(); + } + } + + return null; + } + + /** + * Get the trace folder from the selection + * + * @param selection + * the selection + * + * @return the enclosing project or null if selection is no enclosed by a + * project + */ + public static TmfTraceFolder getTraceFolderFromSelection(ISelection selection) { + if (selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection) selection; + Object firstElement = structuredSelection.getFirstElement(); + if (firstElement instanceof ITmfProjectModelElement) { + ITmfProjectModelElement element = (ITmfProjectModelElement) firstElement; + while (element != null) { + if (element instanceof TmfTraceFolder) { + return (TmfTraceFolder) element; + } + element = element.getParent(); + } + } + } + return null; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/messages.properties new file mode 100644 index 0000000000..911dd9d6eb --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/commands/messages.properties @@ -0,0 +1,14 @@ +############################################################################### +# Copyright (c) 2013 Ericsson. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Marc-Andre Laperle - initial API and implementation +############################################################################### + +OpenDirHandler_SelectTraceDirectory=Open trace directory +OpenFileHandler_SelectTraceFile=Open trace file \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/dialogs/ManageCustomParsersDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/dialogs/ManageCustomParsersDialog.java new file mode 100644 index 0000000000..29472e6e5d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/dialogs/ManageCustomParsersDialog.java @@ -0,0 +1,367 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.dialogs; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.window.Window; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.List; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.internal.tmf.ui.parsers.wizards.CustomTxtParserWizard; +import org.eclipse.tracecompass.internal.tmf.ui.parsers.wizards.CustomXmlParserWizard; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; + +/** + * Dialog for custom text parsers. + * + * @author Patrick Tassé + */ +public class ManageCustomParsersDialog extends Dialog { + + private static final String SEP = " : "; //$NON-NLS-1$ + private static final int SEP_LEN = SEP.length(); + + private static final Image image = Activator.getDefault().getImageFromPath("/icons/etool16/customparser_wizard.gif"); //$NON-NLS-1$ + + Button txtButton; + Button xmlButton; + List parserList; + Button newButton; + Button editButton; + Button deleteButton; + Button importButton; + Button exportButton; + + /** + * Constructor + * + * @param parent + * Parent shell of this dialog + */ + public ManageCustomParsersDialog(Shell parent) { + super(parent); + setShellStyle(SWT.RESIZE | SWT.MAX | getShellStyle()); + } + + @Override + protected Control createDialogArea(Composite parent) { + getShell().setText(Messages.ManageCustomParsersDialog_DialogHeader); + getShell().setImage(image); + + Composite composite = (Composite) super.createDialogArea(parent); + composite.setLayout(new GridLayout(2, false)); + + Composite listContainer = new Composite(composite, SWT.NONE); + listContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + GridLayout lcgl = new GridLayout(); + lcgl.marginHeight = 0; + lcgl.marginWidth = 0; + listContainer.setLayout(lcgl); + + Composite radioContainer = new Composite(listContainer, SWT.NONE); + GridLayout rcgl = new GridLayout(2, true); + rcgl.marginHeight = 0; + rcgl.marginWidth = 0; + radioContainer.setLayout(rcgl); + + txtButton = new Button(radioContainer, SWT.RADIO); + txtButton.setText(Messages.ManageCustomParsersDialog_TextButtonLabel); + txtButton.setSelection(true); + txtButton.addSelectionListener(new SelectionListener() { + @Override + public void widgetDefaultSelected(SelectionEvent e) {} + + @Override + public void widgetSelected(SelectionEvent e) { + fillParserList(); + } + }); + + xmlButton = new Button(radioContainer, SWT.RADIO); + xmlButton.setText("XML"); //$NON-NLS-1$ + xmlButton.addSelectionListener(new SelectionListener() { + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + + @Override + public void widgetSelected(SelectionEvent e) { + fillParserList(); + } + }); + + parserList = new List(listContainer, SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); + parserList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + parserList.addSelectionListener(new SelectionListener() { + @Override + public void widgetDefaultSelected(SelectionEvent e) {} + + @Override + public void widgetSelected(SelectionEvent e) { + if (parserList.getSelectionCount() == 0) { + editButton.setEnabled(false); + deleteButton.setEnabled(false); + exportButton.setEnabled(false); + } else { + editButton.setEnabled(true); + deleteButton.setEnabled(true); + exportButton.setEnabled(true); + } + } + }); + + Composite buttonContainer = new Composite(composite, SWT.NULL); + buttonContainer.setLayout(new GridLayout()); + buttonContainer.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, false, false)); + + newButton = new Button(buttonContainer, SWT.PUSH); + newButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + newButton.setText(Messages.ManageCustomParsersDialog_NewButtonLabel); + newButton.addSelectionListener(new SelectionListener() { + @Override + public void widgetDefaultSelected(SelectionEvent e) {} + + @Override + public void widgetSelected(SelectionEvent e) { + WizardDialog dialog = null; + if (txtButton.getSelection()) { + dialog = new WizardDialog(getShell(), new CustomTxtParserWizard()); + } else if (xmlButton.getSelection()) { + dialog = new WizardDialog(getShell(), new CustomXmlParserWizard()); + } + if (dialog != null) { + dialog.open(); + if (dialog.getReturnCode() == Window.OK) { + fillParserList(); + } + } + } + }); + + editButton = new Button(buttonContainer, SWT.PUSH); + editButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + editButton.setText(Messages.ManageCustomParsersDialog_EditButtonLabel); + editButton.setEnabled(false); + editButton.addSelectionListener(new SelectionListener() { + @Override + public void widgetDefaultSelected(SelectionEvent e) {} + + @Override + public void widgetSelected(SelectionEvent e) { + WizardDialog dialog = null; + String selection = parserList.getSelection()[0]; + String category = selection.substring(0, selection.indexOf(SEP)); + String name = selection.substring(selection.indexOf(SEP) + SEP_LEN); + if (txtButton.getSelection()) { + dialog = new WizardDialog(getShell(), + new CustomTxtParserWizard(CustomTxtTraceDefinition.load(category, name))); + } else if (xmlButton.getSelection()) { + dialog = new WizardDialog(getShell(), + new CustomXmlParserWizard(CustomXmlTraceDefinition.load(category, name))); + } + if (dialog != null) { + dialog.open(); + if (dialog.getReturnCode() == Window.OK) { + fillParserList(); + } + } + } + }); + + deleteButton = new Button(buttonContainer, SWT.PUSH); + deleteButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + deleteButton.setText(Messages.ManageCustomParsersDialog_DeleteButtonLabel); + deleteButton.setEnabled(false); + deleteButton.addSelectionListener(new SelectionListener() { + @Override + public void widgetDefaultSelected(SelectionEvent e) {} + + @Override + public void widgetSelected(SelectionEvent e) { + boolean confirm = MessageDialog.openQuestion( + getShell(), + Messages.ManageCustomParsersDialog_DeleteParserDialogHeader, + NLS.bind(Messages.ManageCustomParsersDialog_DeleteConfirmation, parserList.getSelection()[0])); + if (confirm) { + String selection = parserList.getSelection()[0]; + String category = selection.substring(0, selection.indexOf(SEP)); + String name = selection.substring(selection.indexOf(SEP) + SEP_LEN); + if (txtButton.getSelection()) { + CustomTxtTraceDefinition.delete(category, name); + } else if (xmlButton.getSelection()) { + CustomXmlTraceDefinition.delete(category, name); + } + fillParserList(); + } + } + }); + + new Label(buttonContainer, SWT.NONE); // filler + + importButton = new Button(buttonContainer, SWT.PUSH); + importButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + importButton.setText(Messages.ManageCustomParsersDialog_ImportButtonLabel); + importButton.addSelectionListener(new SelectionListener() { + @Override + public void widgetDefaultSelected(SelectionEvent e) {} + + @Override + public void widgetSelected(SelectionEvent e) { + FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(), SWT.OPEN); + dialog.setText(Messages.ManageCustomParsersDialog_ImportParserSelection); + dialog.setFilterExtensions(new String[] { "*.xml", "*" }); //$NON-NLS-1$ //$NON-NLS-2$ + String path = dialog.open(); + if (path != null) { + CustomTraceDefinition[] defs = null; + if (txtButton.getSelection()) { + defs = CustomTxtTraceDefinition.loadAll(path); + } else if (xmlButton.getSelection()) { + defs = CustomXmlTraceDefinition.loadAll(path); + } + if (defs != null && defs.length > 0) { + for (CustomTraceDefinition def : defs) { + boolean ok = checkNameConflict(def); + if (ok) { + def.save(); + } + } + fillParserList(); + } + } + } + }); + + exportButton = new Button(buttonContainer, SWT.PUSH); + exportButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + exportButton.setText(Messages.ManageCustomParsersDialog_ExportButtonLabel); + exportButton.setEnabled(false); + exportButton.addSelectionListener(new SelectionListener() { + @Override + public void widgetDefaultSelected(SelectionEvent e) {} + + @Override + public void widgetSelected(SelectionEvent e) { + FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(), SWT.SAVE); + dialog.setText(NLS.bind(Messages.ManageCustomParsersDialog_ExportParserSelection, parserList.getSelection()[0])); + dialog.setFilterExtensions(new String[] { "*.xml", "*" }); //$NON-NLS-1$ //$NON-NLS-2$ + String path = dialog.open(); + if (path != null) { + String selection = parserList.getSelection()[0]; + String category = selection.substring(0, selection.indexOf(SEP)); + String name = selection.substring(selection.indexOf(SEP) + SEP_LEN); + CustomTraceDefinition def = null; + if (txtButton.getSelection()) { + def = CustomTxtTraceDefinition.load(category, name); + } else if (xmlButton.getSelection()) { + def = CustomXmlTraceDefinition.load(category, name); + } + if (def != null) { + def.save(path); + } + } + } + }); + + fillParserList(); + + getShell().setMinimumSize(300, 275); + return composite; + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.OK_ID, IDialogConstants.CLOSE_LABEL, false); + } + + private void fillParserList() { + parserList.removeAll(); + if (txtButton.getSelection()) { + for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll(false)) { + parserList.add(def.categoryName + SEP + def.definitionName); + } + } else if (xmlButton.getSelection()) { + for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll(false)) { + parserList.add(def.categoryName + SEP + def.definitionName); + } + } + editButton.setEnabled(false); + deleteButton.setEnabled(false); + exportButton.setEnabled(false); + } + + private boolean checkNameConflict(CustomTraceDefinition def) { + for (TraceTypeHelper helper : TmfTraceType.getTraceTypeHelpers()) { + if (def.categoryName.equals(helper.getCategoryName()) && + def.definitionName.equals(helper.getName())) { + String newName = findAvailableName(def); + MessageDialog dialog = new MessageDialog( + getShell(), + null, + null, + NLS.bind(Messages.ManageCustomParsersDialog_ConflictMessage, + new Object[] { def.categoryName, def.definitionName, newName}), + MessageDialog.QUESTION, + new String[] { Messages.ManageCustomParsersDialog_ConflictRenameButtonLabel, + Messages.ManageCustomParsersDialog_ConflictSkipButtonLabel }, + 0); + int result = dialog.open(); + if (result == 0) { + def.definitionName = newName; + return true; + } + return false; + } + } + return true; + } + + private static String findAvailableName(CustomTraceDefinition def) { + int i = 2; + Iterable helpers = TmfTraceType.getTraceTypeHelpers(); + while (true) { + String newName = def.definitionName + '(' + Integer.toString(i++) + ')'; + boolean available = true; + for (TraceTypeHelper helper : helpers) { + if (def.categoryName.equals(helper.getCategoryName()) && + newName.equals(helper.getName())) { + available = false; + break; + } + } + if (available) { + return newName; + } + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/dialogs/MultiLineInputDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/dialogs/MultiLineInputDialog.java new file mode 100644 index 0000000000..d8748ee74c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/dialogs/MultiLineInputDialog.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.dialogs; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.IInputValidator; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * A simple input dialog for soliciting an input string from the user. + * + * Overrides InputDialog to support multiple line text input. + * + * @author Patrick Tassé + */ +public class MultiLineInputDialog extends InputDialog { + + private final String dialogMessage; + + /* flag to indicate if CR can be used to submit the dialog */ + private boolean submitOnCR = true; + + /** + * Creates a multi line input dialog. + * + * @param parentShell + * the parent shell, or null to create a top-level shell + * @param dialogTitle + * the dialog title, or null if none + * @param dialogMessage + * the dialog message, or null if none + * @param initialValue + * the initial input value, or null if none (equivalent to the empty string) + * @param validator + * an input validator, or null if none + */ + public MultiLineInputDialog(Shell parentShell, String dialogTitle, + String dialogMessage, String initialValue, IInputValidator validator) { + super(parentShell, dialogTitle, null, initialValue, validator); + this.dialogMessage = dialogMessage; + } + + /** + * Creates a multi line input dialog with a not-empty text validator. + * + * @param parentShell + * the parent shell, or null to create a top-level shell + * @param dialogTitle + * the dialog title, or null if none + * @param dialogMessage + * the dialog message, or null if none + * @param initialValue + * the initial input value, or null if none (equivalent to the empty string) + */ + public MultiLineInputDialog(Shell parentShell, String dialogTitle, + String dialogMessage, String initialValue) { + super(parentShell, dialogTitle, null, initialValue, new NotEmptyValidator()); + this.dialogMessage = dialogMessage; + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + final Text text = getText(); + + /* create dialog message label here instead because default implementation uses GRAB_VERTICAL */ + if (dialogMessage != null) { + Label label = new Label(composite, SWT.WRAP); + label.setText(dialogMessage); + GridData data = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL + | GridData.VERTICAL_ALIGN_CENTER); + data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH); + label.setLayoutData(data); + label.setFont(parent.getFont()); + label.moveAbove(text); + } + + /* modify text layout data here because default implementation doesn't fill vertically */ + GridData gridData = new GridData(GridData.FILL_BOTH); + gridData.widthHint = convertHorizontalDLUsToPixels(250); + gridData.heightHint = convertHeightInCharsToPixels(3); + text.setLayoutData(gridData); + + text.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.character == SWT.CR) { + if (submitOnCR) { + /* submit the dialog */ + e.doit = false; + okPressed(); + return; + } + } else if (e.character == SWT.TAB) { + /* don't insert a tab character in the text */ + e.doit = false; + text.traverse(SWT.TRAVERSE_TAB_NEXT); + } + /* don't allow CR to submit anymore */ + submitOnCR = false; + } + }); + + text.addMouseListener(new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { + /* don't allow CR to submit anymore */ + submitOnCR = false; + } + }); + + return composite; + } + + @Override + protected Control createContents(Composite parent) { + Control control = super.createContents(parent); + + /* set the shell minimum size */ + Point clientArea = control.computeSize(SWT.DEFAULT, SWT.DEFAULT); + Rectangle trim = getShell().computeTrim(0, 0, clientArea.x, clientArea.y); + getShell().setMinimumSize(trim.width, trim.height); + + return control; + } + + @Override + protected int getInputTextStyle() { + return SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | SWT.BORDER; + } + + @Override + protected boolean isResizable() { + return true; + } + + private static class NotEmptyValidator implements IInputValidator { + @Override + public String isValid(String newText) { + return (newText == null || newText.trim().length() == 0) ? " " : null; //$NON-NLS-1$ + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/editors/handlers/AddBookmarkHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/editors/handlers/AddBookmarkHandler.java new file mode 100644 index 0000000000..fe6682f040 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/editors/handlers/AddBookmarkHandler.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.editors.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; + +/** + * Handler to add bookmarks. + * + * @author Patrick Tasse + */ +public class AddBookmarkHandler extends AbstractHandler { + + @Override + public boolean isEnabled() { + return true; + } + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbench wb = PlatformUI.getWorkbench(); + IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); + IEditorPart activeEditor = activePage.getActiveEditor(); + if (activeEditor instanceof TmfEventsEditor) { + TmfEventsEditor editor = (TmfEventsEditor) activeEditor; + editor.addBookmark(); + } + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/messages.properties new file mode 100644 index 0000000000..a466259bdf --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/messages.properties @@ -0,0 +1,297 @@ +############################################################################### +# Copyright (c) 2013, 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### + +# org.eclipse.linuxtools.tmf.ui.dialogs +ManageCustomParsersDialog_ConflictMessage=Trace type ''{0} : {1}'' already exists.\nDo you want to rename to ''{2}'' or skip? +ManageCustomParsersDialog_ConflictRenameButtonLabel=Rename +ManageCustomParsersDialog_ConflictSkipButtonLabel=Skip +ManageCustomParsersDialog_DeleteButtonLabel=Delete +ManageCustomParsersDialog_DeleteConfirmation=Are you sure you want to delete {0}? +ManageCustomParsersDialog_DeleteParserDialogHeader=Delete Custom Parser +ManageCustomParsersDialog_DialogHeader=Manage Custom Parsers +ManageCustomParsersDialog_EditButtonLabel=Edit... +ManageCustomParsersDialog_ExportButtonLabel=Export... +ManageCustomParsersDialog_ExportParserSelection=Select file to export {0} +ManageCustomParsersDialog_ImportButtonLabel=Import... +ManageCustomParsersDialog_ImportParserSelection=Select custom parser file to import +ManageCustomParsersDialog_NewButtonLabel=New... +ManageCustomParsersDialog_TextButtonLabel=Text + +# org.eclipse.linuxtools.tmf.ui.viewers.events +TmfEventsTable_AddBookmarkActionText=Add Bookmark... +TmfEventsTable_AddBookmarkDialogMessage=Enter Bookmark Description: +TmfEventsTable_AddBookmarkDialogTitle=Add Bookmark +TmfEventsTable_ApplyPresetFilterMenuName=Apply Preset Filter... +TmfEventsTable_ClearFiltersActionText=Clear Filters +TmfEventsTable_CollapseFilterMenuName=Collapse Events +TmfEventsTable_ContentColumnHeader=Content +TmfEventsTable_Export_to_text=Export To Text... +TmfEventsTable_FilterHint= +TmfEventsTable_HideRawActionText=Hide Raw +TmfEventsTable_HideTableActionText=Hide Table +TmfEventsTable_MultipleBookmarksToolTip=Multiple bookmarks at this location +TmfEventsTable_OpenSourceCodeActionText=Open Source Code +TmfEventsTable_OpenSourceCodeNotFound=can not be found in the workspace. +TmfEventsTable_OpenSourceCodeSelectFileDialogTitle=Select source file for the call site +TmfEventsTable_OpenModelActionText=Open Model Element +TmfEventsTable_OpenModelUnsupportedURI=is not a supported model URI format. +TmfEventsTable_ReferenceColumnHeader=File +TmfEventsTable_RemoveBookmarkActionText=Remove Bookmark +TmfEventsTable_SearchHint= +TmfEventsTable_SearchingJobName=Searching... +TmfEventsTable_ShowFilterBarActionText=Show Filter Bar +TmfEventsTable_ShowRawActionText=Show Raw +TmfEventsTable_ShowSearchBarActionText=Show Search Bar +TmfEventsTable_ShowTableActionText=Show Table +TmfEventsTable_SourceColumnHeader=Source +TmfEventsTable_TimestampColumnHeader=Timestamp +TmfEventsTable_TypeColumnHeader=Type + +# org.eclipse.linuxtools.tmf.ui.viewers.timegraph.dialogs +TmfTimeFilterDialog_EDIT_PROFILING_OPTIONS=Edit Profiling Options +TmfTimeFilterDialog_TRACE_FILTER=Trace Filter +TmfTimeFilterDialog_TRACE_FILTER_DESC=Define the filter set +TmfTimeFilterDialog_TRACE_ID=Trace Id +TmfTimeFilterDialog_TRACE_NAME=Trace Name +TmfTimeLegend_LEGEND=Legend +TmfTimeLegend_TRACE_STATES=Trace +TmfTimeLegend_TRACE_STATES_TITLE=States Transition Visualizer +TmfTimeLegend_WINDOW_TITLE=Trace Visualizer's Legend +TmfTimeLegend_StateTypeName=States +TmfTimeFilterDialog_WINDOW_TITLE=Filter +TmfTimeFilterDialog_MESSAGE=Check the entries to show +TmfTimeFilterDialog_CHECK_ALL=Check all +TmfTimeFilterDialog_UNCHECK_ALL=Uncheck all +TmfTimeFilterDialog_CHECK_SELECTED=Check selected +TmfTimeFilterDialog_UNCHECK_SELECTED=Uncheck selected +TmfTimeFilterDialog_CHECK_SUBTREE=Check subtree +TmfTimeFilterDialog_UNCHECK_SUBTREE=Uncheck subtree + +# org.eclipse.linuxtools.tmf.ui.viewers.timegraph.widgets +TmfTimeTipHandler_DURATION=Duration +TmfTimeTipHandler_LINK_SOURCE=Source +TmfTimeTipHandler_LINK_SOURCE_TIME=Source Time +TmfTimeTipHandler_LINK_TARGET=Target +TmfTimeTipHandler_LINK_TARGET_TIME=Target Time +TmfTimeTipHandler_LINK_TIME=Time +TmfTimeTipHandler_TRACE_DATE=Date +TmfTimeTipHandler_TRACE_EVENT_TIME=Event Time +TmfTimeTipHandler_TRACE_START_TIME=Start Time +TmfTimeTipHandler_TRACE_STATE=State +TmfTimeTipHandler_TRACE_STOP_TIME=Stop Time + +TmfTimeGraphCombo_FilterActionNameText=Filter +TmfTimeGraphCombo_FilterActionToolTipText=Show View Filters + + +TmfTimeGraphViewer_ResetScaleActionNameText=Reset +TmfTimeGraphViewer_ResetScaleActionToolTipText=Reset the Time Scale to Default +TmfTimeGraphViewer_LegendActionNameText=Legend +TmfTimeGraphViewer_LegendActionToolTipText=Show Legend +TmfTimeGraphViewer_NextEventActionNameText=Next Event +TmfTimeGraphViewer_NextEventActionToolTipText=Select Next Event +TmfTimeGraphViewer_PreviousEventActionNameText=Previous Event +TmfTimeGraphViewer_PreviousEventActionToolTipText=Select Previous Event +TmfTimeGraphViewer_NextItemActionNameText=Next Item +TmfTimeGraphViewer_NextItemActionToolTipText=Select Next Item +TmfTimeGraphViewer_PreviousItemActionNameText=Previous Item +TmfTimeGraphViewer_PreviousItemActionToolTipText=Select Previous Item +TmfTimeGraphViewer_ZoomInActionNameText=Zoom In +TmfTimeGraphViewer_ZoomInActionToolTipText=Zoom In +TmfTimeGraphViewer_ZoomOutActionNameText=Zoom Out +TmfTimeGraphViewer_ZoomOutActionToolTipText=Zoom Out +TmfTimeGraphViewer_HideArrowsActionNameText=Hide Arrows +TmfTimeGraphViewer_HideArrowsActionToolTipText=Hide Arrows +TmfTimeGraphViewer_FollowArrowForwardActionNameText=Follow Arrow Forward +TmfTimeGraphViewer_FollowArrowForwardActionToolTipText=Follow Arrow Forward +TmfTimeGraphViewer_FollowArrowBackwardActionNameText=Follow Arrow Backward +TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText=Follow Arrow Backward + +Utils_ClockCyclesUnit=\u0020cc + +# org.eclipse.linuxtools.tmf.ui.views.colors +ColorsView_AddActionToolTipText=Insert new color setting +ColorsView_BackgroundButtonText=BG +ColorsView_BackgroundDialogText=Set background color +ColorsView_DeleteActionToolTipText=Delete color setting +ColorsView_ExportActionToolTipText=Export color settings +ColorsView_FilterButtonText=Filter... +ColorsView_ForegroundButtonText=FG +ColorsView_ForegroundDialogText=Set foreground color +ColorsView_ImportActionToolTipText=Import color settings +ColorsView_ImportOverwriteDialogMessage1=Do you want to overwrite the current color settings?\n +ColorsView_ImportOverwriteDialogMessage2=Answering No will insert the imported settings above the current selection. +ColorsView_ImportOverwriteDialogTitle=Overwrite current settings +ColorsView_MoveDownActionToolTipText=Decrease priority +ColorsView_MoveUpActionToolTipText=Increase priority +ColorsView_TickButtonText=Tick +TickColorDialog_TickColorDialogTitle=Choose tick color + +# org.eclipse.linuxtools.tmf.ui.wizards +CustomTxtParserInputWizardPage_addChildLine=Add child line +CustomTxtParserInputWizardPage_addGroup=Add group +CustomTxtParserInputWizardPage_addNextLine=Add next line +CustomTxtParserInputWizardPage_append=Append +CustomTxtParserInputWizardPage_appendWith=Append with | +CustomTxtParserInputWizardPage_capturedGroup=Captured group +CustomTxtParserInputWizardPage_cardinality=Cardinality: +CustomTxtParserInputWizardPage_category=Category: +CustomTxtParserInputWizardPage_desccriptionEdit=Edit an existing custom parser for text trace files +CustomTxtParserInputWizardPage_descriptionNew=Create a new custom parser for text trace files +CustomTxtParserInputWizardPage_format=format: +CustomTxtParserInputWizardPage_group=Group {0}: +CustomTxtParserInputWizardPage_highlightAll=Highlight All +CustomTxtParserInputWizardPage_logType=Trace type: +CustomTxtParserInputWizardPage_matchingOtherLine=Matching other line: +CustomTxtParserInputWizardPage_matchingRootLine=Matching root line : +CustomTxtParserInputWizardPage_max=max: +CustomTxtParserInputWizardPage_min=min: +CustomTxtParserInputWizardPage_moveDown=Move down +CustomTxtParserInputWizardPage_moveUp=Move up +CustomTxtParserInputWizardPage_name=name: +CustomTxtParserInputWizardPage_newGroup=New group +CustomTxtParserInputWizardPage_noMatch=*no match* +CustomTxtParserInputWizardPage_noMatchingGroup=*no matching group* +CustomTxtParserInputWizardPage_noMatchingLine=*no matching line* +CustomTxtParserInputWizardPage_noMatchingTimestamp=*no matching timestamp* +CustomTxtParserInputWizardPage_noMathcingLine=*no matching line* +CustomTxtParserInputWizardPage_nonMatchingLine=Non-matching line\n +CustomTxtParserInputWizardPage_noTimestampGroup=*no timestamp group* +CustomTxtParserInputWizardPage_preview=Preview: +CustomTxtParserInputWizardPage_previewInput=Preview input +CustomTxtParserInputWizardPage_previewLegend=Preview Legend +CustomTxtParserInputWizardPage_regularExpression=Regular expression: +CustomTxtParserInputWizardPage_regularExpressionHelp=Regular Expression Help +CustomTxtParserInputWizardPage_removeGroup=Remove group +CustomTxtParserInputWizardPage_removeLine=Remove line +CustomTxtParserInputWizardPage_set=Set +CustomTxtParserInputWizardPage_timestampFormat=Time Stamp format: +CustomTxtParserInputWizardPage_timestampFormatHelp=Time Stamp Format Help +CustomTxtParserInputWizardPage_uncapturedText=Uncaptured text +CustomTxtParserInputWizardPage_unidentifiedCaptureGroup=Unidentified captured group +CustomTxtParserInputWizardPage_windowTitleEdit=Edit Custom Text Parser +CustomTxtParserInputWizardPage_windowTitleNew=New Custom Text Parser +CustomTxtParserOutputWizardPage_description=Customize the output of the parser +CustomTxtParserOutputWizardPage_moveAfter=Move After +CustomTxtParserOutputWizardPage_moveBefore=Move Before +CustomTxtParserOutputWizardPage_visible=Visible +CustomXmlParserInputWizardPage_emptyCategoryError=Enter a category for the new trace type. +CustomXmlParserInputWizardPage_emptyLogTypeError=Enter a name for the new trace type. +CustomXmlParserInputWizardPage_invalidCategoryError=Invalid character ':' in category. +CustomXmlParserInputWizardPage_invalidLogTypeError=Invalid character ':' in trace type. +CustomXmlParserInputWizardPage_duplicatelogTypeError=The trace type name already exists. +CustomXmlParserInputWizardPage_noDocumentError=Add a document element. +CustomXmlParserInputWizardPage_missingLogEntryError=Identify a Log Entry element. +CustomXmlParserInputWizardPage_missingTimestampFmtError=Enter the output format for the Time Stamp field. +CustomXmlParserInputWizardPage_missingDocumentElementError=Enter a name for the document element. +CustomXmlParserInputWizardPage_noTimestampElementOrAttribute=*no time stamp element or attribute* +CustomXmlParserInputWizardPage_elementMissingNameError=Enter a name for the element (Element {0}). +CustomXmlParserInputWizardPage_elementMissingInputNameError=Enter a name for the input (Element {0}). +CustomXmlParserInputWizardPage_elementMissingTimestampFmtError=Enter the input format for the Time Stamp (Element {0}). +CustomXmlParserInputWizardPage_elementInvalidTimestampFmtError=Enter a valid output format for the Time Stamp field (Element {0}). +CustomXmlParserInputWizardPage_elementDuplicateNameError=Duplicate element names (Element {0}). +CustomXmlParserInputWizardPage_attributeMissingNameError=Enter a name for the attribute (Attribute {0}: ?). +CustomXmlParserInputWizardPage_attributeMissingInputNameError=Enter a name for the input (Attribute {0}). +CustomXmlParserInputWizardPage_attributeMissingTimestampFmtError=Enter the input format for the Time Stamp (Attribute {0}). +CustomXmlParserInputWizardPage_attributeInvalidTimestampFmtError=Enter a valid input format for the Time Stamp (Attribute {0}). +CustomXmlParserInputWizardPage_attributeDuplicateNameError=Duplicate attribute names (Attribute {0}). +CustomXmlParserInputWizardPage_addAttribute=Add attribute +CustomXmlParserInputWizardPage_addChildElement=Add child element +CustomXmlParserInputWizardPage_addDocumentEleemnt=Add document element +CustomXmlParserInputWizardPage_addDocumentElement=Add document element +CustomXmlParserInputWizardPage_addNextElement=Add next element +CustomXmlParserInputWizardPage_append=Append +CustomXmlParserInputWizardPage_appendWith=Append with | +CustomXmlParserInputWizardPage_attibute=Attribute +CustomXmlParserInputWizardPage_category=Category: +CustomXmlParserInputWizardPage_descriptionEdit=Edit an existing custom parser for XML trace files +CustomXmlParserInputWizardPage_descriptionNew=Create a new custom parser for XML trace files +CustomXmlParserInputWizardPage_elementName=Element name: +CustomXmlParserInputWizardPage_feelingLucky=Feeling lucky +CustomXmlParserInputWizardPage_format=format: +CustomXmlParserInputWizardPage_logEntry=Log Entry +CustomXmlParserInputWizardPage_logType=Trace type: +CustomXmlParserInputWizardPage_moveDown=Move down +CustomXmlParserInputWizardPage_moveUp=Move up +CustomXmlParserInputWizardPage_name=name: +CustomXmlParserInputWizardPage_newAttibute=New attribute +CustomXmlParserInputWizardPage_noMatch=*no match* +CustomXmlParserInputWizardPage_noMatchingAttribute=*no matching attribute* +CustomXmlParserInputWizardPage_noMatchingElement=*no matching element* +CustomXmlParserInputWizardPage_preview=Preview: +CustomXmlParserInputWizardPage_previewInput=Preview input +CustomXmlParserInputWizardPage_removeAttribute=Remove attribute +CustomXmlParserInputWizardPage_removeElement=Remove element +CustomXmlParserInputWizardPage_set=Set +CustomXmlParserInputWizardPage_tagName=tag name: +CustomXmlParserInputWizardPage_timestampFormat=Time Stamp format: +CustomXmlParserInputWizardPage_timestampFormatHelp=Time Stamp Format Help +CustomXmlParserInputWizardPage_titleEdit=Edit Custom XML Parser +CustomXmlParserInputWizardPage_titleNew=New Custom XML Parser +CustomXmlParserOutputWizardPage_description=Customize the output of the parser +CustomXmlParserOutputWizardPage_moveAfter=Move After +CustomXmlParserOutputWizardPage_moveBefore=Move Before +CustomXmlParserOutputWizardPage_visible=Visible + +# org.eclipse.linuxtools.tmf.ui.views.filter +FilterDialog_FilterDialogTitle=Edit filter +FilterView_AddActionToolTipText=Add new filter +FilterView_DeleteActionToolTipText=Delete filter node +FilterView_ExportActionToolTipText=Export filters +FilterView_FileDialogFilterName=TMF Filter files +FilterView_ImportActionToolTipText=Import filters +FilterView_SaveActionToolTipText=Save filters +FilterViewer_EmptyTreeHintText= +FilterViewer_CommonCategory=[common] +FilterViewer_AlphaButtonText=Alpha +FilterViewer_FieldLabel=field: +FilterViewer_FilterNameHint=type filter name +FilterViewer_IgnoreCaseButtonText=ignore case +FilterViewer_NameLabel=name: +FilterViewer_NewPrefix=New +FilterViewer_NotLabel=not: +FilterViewer_NumButtonText=Num +FilterViewer_RegexHint=type regular expression +FilterViewer_RegexLabel=regex: +FilterViewer_ResultLabel=result: +FilterViewer_Subfilter_ToolTip=Prefix with '/' to enter a path where subfields are separated by '/'. For an uninterpreted slash use '\\/'. +FilterViewer_TimestampButtonText=Timestamp +FilterViewer_TypeLabel=type: +FilterViewer_ValueHint=type value +FilterViewer_ValueLabel=value: + +TmfView_PinActionNameText=Pin View +TmfView_PinActionToolTipText=Pin View + +# Call Stack View +CallStackPresentationProvider_Thread=Thread +CallStackView_FunctionColumn=Function +CallStackView_DepthColumn=Depth +CallStackView_EntryTimeColumn=Entry time +CallStackView_ExitTimeColumn=Exit time +CallStackView_DurationColumn=Duration +CallStackView_StackInfoNotAvailable=Stack info not available +CallStackView_SortByThreadName=Sort threads by thread name +CallStackView_SortByThreadId=Sort threads by thread id +CallStackView_SortByThreadTime=Sort threads by start time +CallStackView_ImportMappingButtonText=Import mapping file... +CallStackView_ImportMappingButtonTooltip=Import a text file containing the mapping between addresses and function names +CallStackView_ImportMappingDialogTitle=Select Mapping File +CallStackView_ImportMappingJobName=Updating Call Stack view function mapping + +CallStackView_ImportBinaryFileButtonText=Import binary file... +CallStackView_ImportBinaryFileButtonTooltip=Import a binary file containing debugging symbols +CallStackView_ImportBinaryFileDialogTitle=Select Binary File + +ExportToTextJob_Export_to=Export to {0}... +ExportToTextJob_Export_trace_to=Export trace to {0} +ExportToTextJob_Unable_to_export_trace=Unable to export trace to {0} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/custom/CustomEventTableColumns.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/custom/CustomEventTableColumns.java new file mode 100644 index 0000000000..65320cfb8d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/custom/CustomEventTableColumns.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Alexandre Montplaisir - Update for TmfEventTableColumn + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.parsers.custom; + +import java.util.Collection; +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomEvent; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition.OutputColumn; +import org.eclipse.tracecompass.tmf.ui.viewers.events.TmfEventsTable; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.ITmfEventTableColumns; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; + +import com.google.common.collect.ImmutableList; + +/** + * Event table column definition for Custom {Text|XML} traces. + * + * Since this definition will be different for every single custom trace, this + * does not work the same as with {@link ITmfEventTableColumns}. + * + * Instead, one has to call {@link #generateColumns(CustomTraceDefinition)} with + * the CustomTraceDefinition of the the particular trace to display. Then the + * returned collection can be passed to the constructor + * {@link TmfEventsTable#TmfEventsTable(org.eclipse.swt.widgets.Composite, int, Collection)} + * as usual. + * + * @author Alexandre Montplaisir + */ +public class CustomEventTableColumns { + + /** + * Column for custom events, which uses an integer ID to represent each + * column. + */ + private static final class CustomEventTableColumn extends TmfEventTableColumn { + + private final int fIndex; + + /** + * Constructor + * + * @param name + * The name (title) of this column + * @param idx + * The index of this column, which should be the index of the + * field in the event's content to display. + */ + public CustomEventTableColumn(@NonNull String name, int idx) { + super(name); + fIndex = idx; + } + + @Override + public String getItemString(ITmfEvent event) { + if (event instanceof CustomEvent) { + String ret = ((CustomEvent) event).getEventString(fIndex); + return (ret == null ? EMPTY_STRING : ret); + } + return EMPTY_STRING; + } + + @Override + public String getFilterFieldId() { + return getHeaderName(); + } + } + + /** + * Get the event table columns for a given trace definition + * + * @param definition The {@link CustomTraceDefinition} of the trace for which you want the columns + * @return The set of columns for the given trace. + */ + public static Collection generateColumns(CustomTraceDefinition definition) { + ImmutableList.Builder builder = new ImmutableList.Builder<>(); + List outputs = definition.outputs; + for (int i = 0; i < outputs.size(); i++) { + String name = outputs.get(i).name; + if (name != null) { + builder.add(new CustomEventTableColumn(name, i)); + } + } + return builder.build(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomTxtParserInputWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomTxtParserInputWizardPage.java new file mode 100644 index 0000000000..ffe9e83bfd --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomTxtParserInputWizardPage.java @@ -0,0 +1,1681 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.parsers.wizards; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.browser.Browser; +import org.eclipse.swt.browser.TitleEvent; +import org.eclipse.swt.browser.TitleListener; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.events.VerifyListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition.Cardinality; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition.InputData; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition.InputLine; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; +import org.osgi.framework.Bundle; + +/** + * Input wizard page for custom text parsers. + * + * @author Patrick Tasse + */ +public class CustomTxtParserInputWizardPage extends WizardPage { + + private static final String DEFAULT_REGEX = "\\s*(.*\\S)"; //$NON-NLS-1$ + private static final String DEFAULT_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; //$NON-NLS-1$ + private static final String TIMESTAMP_FORMAT_BUNDLE = "org.eclipse.linuxtools.lttng.help"; //$NON-NLS-1$ + private static final String TIMESTAMP_FORMAT_PATH = "reference/api/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestampFormat.html"; //$NON-NLS-1$ + private static final String PATTERN_URL = "http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#sum"; //$NON-NLS-1$ + private static final Image LINE_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/line_icon.gif"); //$NON-NLS-1$ + private static final Image ADD_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/add_button.gif"); //$NON-NLS-1$ + private static final Image ADD_NEXT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/addnext_button.gif"); //$NON-NLS-1$ + private static final Image ADD_CHILD_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/addchild_button.gif"); //$NON-NLS-1$ + private static final Image DELETE_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/delete_button.gif"); //$NON-NLS-1$ + private static final Image MOVE_UP_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/moveup_button.gif"); //$NON-NLS-1$ + private static final Image MOVE_DOWN_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/movedown_button.gif"); //$NON-NLS-1$ + private static final Image HELP_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/help_button.gif"); //$NON-NLS-1$ + private static final Color COLOR_BLACK = Display.getDefault().getSystemColor(SWT.COLOR_BLACK); + private static final Color COLOR_LIGHT_GREEN = new Color(Display.getDefault(), 192, 255, 192); + private static final Color COLOR_GREEN = Display.getDefault().getSystemColor(SWT.COLOR_GREEN); + private static final Color COLOR_LIGHT_YELLOW = new Color(Display.getDefault(), 255, 255, 192); + private static final Color COLOR_YELLOW = Display.getDefault().getSystemColor(SWT.COLOR_YELLOW); + private static final Color COLOR_LIGHT_MAGENTA = new Color(Display.getDefault(), 255, 192, 255); + private static final Color COLOR_MAGENTA = Display.getDefault().getSystemColor(SWT.COLOR_MAGENTA); + private static final Color COLOR_LIGHT_RED = new Color(Display.getDefault(), 255, 192, 192); + private static final Color COLOR_TEXT_BACKGROUND = Display.getDefault().getSystemColor(SWT.COLOR_WHITE); + private static final Color COLOR_WIDGET_BACKGROUND = Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); + + private final ISelection selection; + private CustomTxtTraceDefinition definition; + private String editCategoryName; + private String editDefinitionName; + private String defaultDescription; + private Line selectedLine; + private Composite container; + private Text categoryText; + private Text logtypeText; + private Text timestampOutputFormatText; + private Text timestampPreviewText; + private ScrolledComposite lineScrolledComposite; + private TreeViewer treeViewer; + private Composite lineContainer; + private StyledText inputText; + private Font fixedFont; + private UpdateListener updateListener; + private Browser helpBrowser; + + // variables used recursively through line traversal + private String timeStampFormat; + private boolean timestampFound; + + /** + * Constructor + * + * @param selection + * The Selection object + * @param definition + * The trace definition + */ + protected CustomTxtParserInputWizardPage(ISelection selection, + CustomTxtTraceDefinition definition) { + super("CustomParserWizardPage"); //$NON-NLS-1$ + if (definition == null) { + setTitle(Messages.CustomTxtParserInputWizardPage_windowTitleNew); + defaultDescription = Messages.CustomTxtParserInputWizardPage_descriptionNew; + } else { + setTitle(Messages.CustomTxtParserInputWizardPage_windowTitleEdit); + defaultDescription = Messages.CustomTxtParserInputWizardPage_desccriptionEdit; + } + setDescription(defaultDescription); + this.selection = selection; + this.definition = definition; + if (definition != null) { + this.editCategoryName = definition.categoryName; + this.editDefinitionName = definition.definitionName; + } + } + + @Override + public void createControl(Composite parent) { + container = new Composite(parent, SWT.NULL); + container.setLayout(new GridLayout()); + + updateListener = new UpdateListener(); + + Composite headerComposite = new Composite(container, SWT.FILL); + GridLayout headerLayout = new GridLayout(5, false); + headerLayout.marginHeight = 0; + headerLayout.marginWidth = 0; + headerComposite.setLayout(headerLayout); + headerComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + Label categoryLabel = new Label(headerComposite, SWT.NULL); + categoryLabel.setText(Messages.CustomTxtParserInputWizardPage_category); + + categoryText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE); + categoryText.setLayoutData(new GridData(120, SWT.DEFAULT)); + + Label timestampFormatLabel = new Label(headerComposite, SWT.NULL); + timestampFormatLabel.setText(Messages.CustomTxtParserInputWizardPage_timestampFormat); + + timestampOutputFormatText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE); + timestampOutputFormatText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + timestampOutputFormatText.setText(DEFAULT_TIMESTAMP_FORMAT); + + Button timeStampFormatHelpButton = new Button(headerComposite, SWT.PUSH); + timeStampFormatHelpButton.setImage(HELP_IMAGE); + timeStampFormatHelpButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_timestampFormatHelp); + timeStampFormatHelpButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + Bundle plugin = Platform.getBundle(TIMESTAMP_FORMAT_BUNDLE); + IPath path = new Path(TIMESTAMP_FORMAT_PATH); + URL fileURL = FileLocator.find(plugin, path, null); + try { + URL pageURL = FileLocator.toFileURL(fileURL); + openHelpShell(pageURL.toString()); + } catch (IOException e1) { + } + } + }); + + Label logtypeLabel = new Label(headerComposite, SWT.NULL); + logtypeLabel.setText(Messages.CustomTxtParserInputWizardPage_logType); + + logtypeText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE); + logtypeText.setLayoutData(new GridData(120, SWT.DEFAULT)); + logtypeText.setFocus(); + + Label timestampPreviewLabel = new Label(headerComposite, SWT.NULL); + timestampPreviewLabel.setText(Messages.CustomTxtParserInputWizardPage_preview); + + timestampPreviewText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); + timestampPreviewText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); + timestampPreviewText.setText(Messages.CustomTxtParserInputWizardPage_noMatchingTimestamp); + + Composite buttonBar = new Composite(container, SWT.NONE); + GridLayout buttonBarLayout = new GridLayout(5, false); + buttonBarLayout.marginHeight = 0; + buttonBarLayout.marginWidth = 0; + buttonBar.setLayout(buttonBarLayout); + + Button removeButton = new Button(buttonBar, SWT.PUSH); + removeButton.setImage(DELETE_IMAGE); + removeButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_removeLine); + removeButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (treeViewer.getSelection().isEmpty() || selectedLine == null) { + return; + } + removeLine(); + InputLine inputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); + if (inputLine.parentInput == null) { + definition.inputs.remove(inputLine); + } else { + inputLine.parentInput.childrenInputs.remove(inputLine); + } + treeViewer.refresh(); + validate(); + updatePreviews(); + } + }); + Button addNextButton = new Button(buttonBar, SWT.PUSH); + addNextButton.setImage(ADD_NEXT_IMAGE); + addNextButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_addNextLine); + addNextButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + InputLine inputLine = new InputLine(Cardinality.ZERO_OR_MORE, "", null); //$NON-NLS-1$ + if (((List) treeViewer.getInput()).size() == 0) { + definition.inputs.add(inputLine); + } else if (treeViewer.getSelection().isEmpty()) { + return; + } else { + InputLine previousInputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); + if (previousInputLine.parentInput == null) { + for (int i = 0; i < definition.inputs.size(); i++) { + if (definition.inputs.get(i).equals(previousInputLine)) { + definition.inputs.add(i + 1, inputLine); + } + } + } else { + previousInputLine.addNext(inputLine); + } + } + treeViewer.refresh(); + treeViewer.setSelection(new StructuredSelection(inputLine), true); + } + }); + Button addChildButton = new Button(buttonBar, SWT.PUSH); + addChildButton.setImage(ADD_CHILD_IMAGE); + addChildButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_addChildLine); + addChildButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + InputLine inputLine = new InputLine(Cardinality.ZERO_OR_MORE, "", null); //$NON-NLS-1$ + if (((List) treeViewer.getInput()).size() == 0) { + definition.inputs.add(inputLine); + } else if (treeViewer.getSelection().isEmpty()) { + return; + } else { + InputLine parentInputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); + parentInputLine.addChild(inputLine); + } + treeViewer.refresh(); + treeViewer.setSelection(new StructuredSelection(inputLine), true); + } + }); + Button moveUpButton = new Button(buttonBar, SWT.PUSH); + moveUpButton.setImage(MOVE_UP_IMAGE); + moveUpButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_moveUp); + moveUpButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (treeViewer.getSelection().isEmpty()) { + return; + } + InputLine inputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); + if (inputLine.parentInput == null) { + for (int i = 1; i < definition.inputs.size(); i++) { + if (definition.inputs.get(i).equals(inputLine)) { + definition.inputs.add(i - 1, definition.inputs.remove(i)); + break; + } + } + } else { + inputLine.moveUp(); + } + treeViewer.refresh(); + validate(); + updatePreviews(); + } + }); + Button moveDownButton = new Button(buttonBar, SWT.PUSH); + moveDownButton.setImage(MOVE_DOWN_IMAGE); + moveDownButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_moveDown); + moveDownButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (treeViewer.getSelection().isEmpty()) { + return; + } + InputLine inputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); + if (inputLine.parentInput == null) { + for (int i = 0; i < definition.inputs.size() - 1; i++) { + if (definition.inputs.get(i).equals(inputLine)) { + definition.inputs.add(i + 1, definition.inputs.remove(i)); + break; + } + } + } else { + inputLine.moveDown(); + } + treeViewer.refresh(); + validate(); + updatePreviews(); + } + }); + + SashForm vSash = new SashForm(container, SWT.VERTICAL); + vSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + vSash.setBackground(vSash.getDisplay().getSystemColor(SWT.COLOR_GRAY)); + + SashForm hSash = new SashForm(vSash, SWT.HORIZONTAL); + hSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + ScrolledComposite treeScrolledComposite = new ScrolledComposite(hSash, SWT.V_SCROLL | SWT.H_SCROLL); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.heightHint = 200; + gd.widthHint = 200; + treeScrolledComposite.setLayoutData(gd); + Composite treeContainer = new Composite(treeScrolledComposite, SWT.NONE); + treeContainer.setLayout(new FillLayout()); + treeScrolledComposite.setContent(treeContainer); + treeScrolledComposite.setExpandHorizontal(true); + treeScrolledComposite.setExpandVertical(true); + + treeViewer = new TreeViewer(treeContainer, SWT.SINGLE | SWT.BORDER); + treeViewer.setContentProvider(new InputLineTreeNodeContentProvider()); + treeViewer.setLabelProvider(new InputLineTreeLabelProvider()); + treeViewer.addSelectionChangedListener(new InputLineTreeSelectionChangedListener()); + treeContainer.layout(); + + treeScrolledComposite.setMinSize(treeContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, treeContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y); + + lineScrolledComposite = new ScrolledComposite(hSash, SWT.V_SCROLL); + lineScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + lineContainer = new Composite(lineScrolledComposite, SWT.NONE); + GridLayout linesLayout = new GridLayout(); + linesLayout.marginHeight = 1; + linesLayout.marginWidth = 0; + lineContainer.setLayout(linesLayout); + lineScrolledComposite.setContent(lineContainer); + lineScrolledComposite.setExpandHorizontal(true); + lineScrolledComposite.setExpandVertical(true); + + if (definition == null) { + definition = new CustomTxtTraceDefinition(); + definition.inputs.add(new InputLine(Cardinality.ZERO_OR_MORE, DEFAULT_REGEX, + Arrays.asList(new InputData(CustomTraceDefinition.TAG_MESSAGE, CustomTraceDefinition.ACTION_SET)))); + } + loadDefinition(definition); + treeViewer.expandAll(); + lineContainer.layout(); + + categoryText.addModifyListener(updateListener); + logtypeText.addModifyListener(updateListener); + timestampOutputFormatText.addModifyListener(updateListener); + + lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); + + hSash.setWeights(new int[] { 1, 2 }); + + Composite sashBottom = new Composite(vSash, SWT.NONE); + GridLayout sashBottomLayout = new GridLayout(3, false); + sashBottomLayout.marginHeight = 0; + sashBottomLayout.marginWidth = 0; + sashBottom.setLayout(sashBottomLayout); + + Label previewLabel = new Label(sashBottom, SWT.NULL); + previewLabel.setText(Messages.CustomTxtParserInputWizardPage_previewInput); + previewLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + Button highlightAllButton = new Button(sashBottom, SWT.PUSH); + highlightAllButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + highlightAllButton.setText(Messages.CustomTxtParserInputWizardPage_highlightAll); + highlightAllButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + updatePreviews(true); + } + }); + + Button legendButton = new Button(sashBottom, SWT.PUSH); + legendButton.setImage(HELP_IMAGE); + legendButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_previewLegend); + legendButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + legendButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + openLegend(); + } + }); + + inputText = new StyledText(sashBottom, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL); + if (fixedFont == null) { + if (System.getProperty("os.name").contains("Windows")) { //$NON-NLS-1$ //$NON-NLS-2$ + fixedFont = new Font(Display.getCurrent(), new FontData("Courier New", 10, SWT.NORMAL)); //$NON-NLS-1$ + } else { + fixedFont = new Font(Display.getCurrent(), new FontData("Monospace", 10, SWT.NORMAL)); //$NON-NLS-1$ + } + } + inputText.setFont(fixedFont); + gd = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1); + gd.heightHint = inputText.computeSize(SWT.DEFAULT, inputText.getLineHeight() * 4).y; + gd.widthHint = 800; + inputText.setLayoutData(gd); + inputText.setText(getSelectionText()); + inputText.addModifyListener(updateListener); + + vSash.setWeights(new int[] { hSash.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, sashBottom.computeSize(SWT.DEFAULT, SWT.DEFAULT).y }); + + setControl(container); + + validate(); + updatePreviews(); + } + + private static class InputLineTreeNodeContentProvider implements ITreeContentProvider { + + @Override + public Object[] getElements(Object inputElement) { + return ((List) inputElement).toArray(); + } + + @Override + public Object[] getChildren(Object parentElement) { + InputLine inputLine = (InputLine) parentElement; + if (inputLine.childrenInputs == null) { + return new InputLine[0]; + } + return inputLine.childrenInputs.toArray(); + } + + @Override + public boolean hasChildren(Object element) { + InputLine inputLine = (InputLine) element; + return (inputLine.childrenInputs != null && inputLine.childrenInputs.size() > 0); + } + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + @Override + public Object getParent(Object element) { + InputLine inputLine = (InputLine) element; + return inputLine.parentInput; + } + } + + private class InputLineTreeLabelProvider extends ColumnLabelProvider { + + @Override + public Image getImage(Object element) { + return LINE_IMAGE; + } + + @Override + public String getText(Object element) { + InputLine inputLine = (InputLine) element; + if (inputLine.parentInput == null) { + return "Root Line " + getName(inputLine) + " " + inputLine.cardinality.toString() + " : " + inputLine.getRegex(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + return "Line " + getName(inputLine) + " " + inputLine.cardinality.toString() + " : " + inputLine.getRegex(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + } + + private class InputLineTreeSelectionChangedListener implements ISelectionChangedListener { + @Override + public void selectionChanged(SelectionChangedEvent event) { + if (selectedLine != null) { + selectedLine.dispose(); + } + if (!(event.getSelection().isEmpty()) && event.getSelection() instanceof IStructuredSelection) { + IStructuredSelection sel = (IStructuredSelection) event.getSelection(); + InputLine inputLine = (InputLine) sel.getFirstElement(); + selectedLine = new Line(lineContainer, getName(inputLine), inputLine); + lineContainer.layout(); + lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); + container.layout(); + validate(); + updatePreviews(); + } + } + } + + @Override + public void dispose() { + if (fixedFont != null) { + fixedFont.dispose(); + fixedFont = null; + } + super.dispose(); + } + + private void loadDefinition(CustomTxtTraceDefinition def) { + categoryText.setText(def.categoryName); + logtypeText.setText(def.definitionName); + timestampOutputFormatText.setText(def.timeStampOutputFormat); + treeViewer.setInput(def.inputs); + if (def.inputs.size() > 0) { + InputLine inputLine = def.inputs.get(0); + treeViewer.setSelection(new StructuredSelection(inputLine)); + } + } + + private String getName(InputLine inputLine) { + if (inputLine.parentInput == null) { + return Integer.toString(definition.inputs.indexOf(inputLine) + 1); + } + return getName(inputLine.parentInput) + "." + Integer.toString(inputLine.parentInput.childrenInputs.indexOf(inputLine) + 1); //$NON-NLS-1$ + } + + /** + * Get the global list of input names. + * + * @return The list of input names + */ + public List getInputNames() { + List inputs = new ArrayList<>(); + for (InputLine inputLine : definition.inputs) { + for (String inputName : getInputNames(inputLine)) { + if (!inputs.contains(inputName)) { + inputs.add(inputName); + } + } + } + return inputs; + } + + /** + * Get the list of input names for the given input line. + * + * @param inputLine + * The input line + * @return The list of input names + */ + public List getInputNames(InputLine inputLine) { + List inputs = new ArrayList<>(); + if (inputLine.columns != null) { + for (InputData inputData : inputLine.columns) { + String inputName = inputData.name; + if (!inputs.contains(inputName)) { + inputs.add(inputName); + } + } + } + if (inputLine.childrenInputs != null) { + for (InputLine childInputLine : inputLine.childrenInputs) { + for (String inputName : getInputNames(childInputLine)) { + if (!inputs.contains(inputName)) { + inputs.add(inputName); + } + } + } + } + return inputs; + } + + private void removeLine() { + selectedLine.dispose(); + selectedLine = null; + lineContainer.layout(); + lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); + container.layout(); + } + + private String getSelectionText() { + if (this.selection instanceof IStructuredSelection) { + Object sel = ((IStructuredSelection) this.selection).getFirstElement(); + if (sel instanceof IFile) { + IFile file = (IFile) sel; + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader(file.getContents())); + StringBuilder sb = new StringBuilder(); + String line = null; + while ((line = reader.readLine()) != null) { + sb.append(line + "\n"); //$NON-NLS-1$ + } + return sb.toString(); + } catch (CoreException e) { + return ""; //$NON-NLS-1$ + } catch (IOException e) { + return ""; //$NON-NLS-1$ + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + } + } + } + } + } + return ""; //$NON-NLS-1$ + } + + private void updatePreviews() { + updatePreviews(false); + } + + private void updatePreviews(boolean updateAll) { + if (inputText == null) { + // early update during construction + return; + } + inputText.setStyleRanges(new StyleRange[] {}); + + try (Scanner scanner = new Scanner(inputText.getText());) { + scanner.useDelimiter("\n"); //$NON-NLS-1$ + + int rawPos = 0; + // skip starting delimiters + String skip = scanner.findWithinHorizon("\\A\n+", 0); //$NON-NLS-1$ + if (skip != null) { + rawPos += skip.length(); + } + + timeStampFormat = null; + if (selectedLine != null) { + for (InputGroup input : selectedLine.inputs) { + input.previewText.setText(Messages.CustomTxtParserInputWizardPage_noMathcingLine); + } + } + + Map data = new HashMap<>(); + int rootLineMatches = 0; + String firstEntryTimeStamp = null; + String firstEntryTimeStampInputFormat = null; + String line = null; + boolean lineIsNull = true; // needed because of JDT bug with continue at label + event: while (scanner.hasNext() || !lineIsNull) { + if (rootLineMatches > 0 && !updateAll) { + break; + } + if (line == null) { + line = scanner.next(); + lineIsNull = false; + } + int length = line.length(); + String log = line.replaceAll("\r", ""); //$NON-NLS-1$ //$NON-NLS-2$ + for (InputLine rootInputLine : definition.inputs) { + Pattern pattern; + try { + pattern = rootInputLine.getPattern(); + } catch (PatternSyntaxException e) { + continue; + } + Matcher matcher = pattern.matcher(log); + if (matcher.matches()) { + rootLineMatches++; + inputText.setStyleRange(new StyleRange(rawPos, length, + COLOR_BLACK, COLOR_YELLOW, SWT.ITALIC)); + data = new HashMap<>(); + timeStampFormat = null; + updatePreviewLine(rootInputLine, matcher, data, rawPos, rootLineMatches); + if (rootLineMatches == 1) { + firstEntryTimeStamp = data.get(CustomTraceDefinition.TAG_TIMESTAMP); + firstEntryTimeStampInputFormat = timeStampFormat; + } + HashMap countMap = new HashMap<>(); + InputLine currentInput = null; + if (rootInputLine.childrenInputs != null && rootInputLine.childrenInputs.size() > 0) { + currentInput = rootInputLine.childrenInputs.get(0); + countMap.put(currentInput, 0); + } + rawPos += length + 1; // +1 for \n + while (scanner.hasNext()) { + line = scanner.next(); + length = line.length(); + log = line.replaceAll("\r", ""); //$NON-NLS-1$ //$NON-NLS-2$ + boolean processed = false; + if (currentInput == null) { + for (InputLine input : definition.inputs) { + try { + matcher = input.getPattern().matcher(log); + } catch (PatternSyntaxException e) { + continue; + } + if (matcher.matches()) { + continue event; + } + } + } else { + if (countMap.get(currentInput) >= currentInput.getMinCount()) { + List nextInputs = currentInput.getNextInputs(countMap); + if (nextInputs.size() == 0 || nextInputs.get(nextInputs.size() - 1).getMinCount() == 0) { + for (InputLine input : definition.inputs) { + try { + matcher = input.getPattern().matcher(log); + } catch (PatternSyntaxException e) { + continue; + } + if (matcher.matches()) { + continue event; + } + } + } + for (InputLine input : nextInputs) { + try { + matcher = input.getPattern().matcher(log); + } catch (PatternSyntaxException e) { + continue; + } + if (matcher.matches()) { + inputText.setStyleRange(new StyleRange(rawPos, length, + COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC)); + currentInput = input; + updatePreviewLine(currentInput, matcher, data, rawPos, rootLineMatches); + if (countMap.get(currentInput) == null) { + countMap.put(currentInput, 1); + } else { + countMap.put(currentInput, countMap.get(currentInput) + 1); + } + Iterator iter = countMap.keySet().iterator(); + while (iter.hasNext()) { + InputLine inputLine = iter.next(); + if (inputLine.level > currentInput.level) { + iter.remove(); + } + } + if (currentInput.childrenInputs != null && currentInput.childrenInputs.size() > 0) { + currentInput = currentInput.childrenInputs.get(0); + countMap.put(currentInput, 0); + } else { + if (countMap.get(currentInput) >= currentInput.getMaxCount()) { + if (currentInput.getNextInputs(countMap).size() > 0) { + currentInput = currentInput.getNextInputs(countMap).get(0); + if (countMap.get(currentInput) == null) { + countMap.put(currentInput, 0); + } + iter = countMap.keySet().iterator(); + while (iter.hasNext()) { + InputLine inputLine = iter.next(); + if (inputLine.level > currentInput.level) { + iter.remove(); + } + } + } else { + currentInput = null; + } + } + } + processed = true; + break; + } + } + } + if (!processed && currentInput != null) { + matcher = null; + try { + matcher = currentInput.getPattern().matcher(log); + } catch (PatternSyntaxException e) { + } + if (matcher != null && matcher.matches()) { + inputText.setStyleRange(new StyleRange(rawPos, length, + COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC)); + updatePreviewLine(currentInput, matcher, data, rawPos, rootLineMatches); + countMap.put(currentInput, countMap.get(currentInput) + 1); + if (currentInput.childrenInputs != null && currentInput.childrenInputs.size() > 0) { + currentInput = currentInput.childrenInputs.get(0); + countMap.put(currentInput, 0); + } else { + if (countMap.get(currentInput) >= currentInput.getMaxCount()) { + if (currentInput.getNextInputs(countMap).size() > 0) { + currentInput = currentInput.getNextInputs(countMap).get(0); + if (countMap.get(currentInput) == null) { + countMap.put(currentInput, 0); + } + Iterator iter = countMap.keySet().iterator(); + while (iter.hasNext()) { + InputLine inputLine = iter.next(); + if (inputLine.level > currentInput.level) { + iter.remove(); + } + } + } else { + currentInput = null; + } + } + } + } + } + } + rawPos += length + 1; // +1 for \n + } + + break; + } + } + rawPos += length + 1; // +1 for \n + line = null; + lineIsNull = true; + } + + if (rootLineMatches == 1) { + firstEntryTimeStamp = data.get(CustomTraceDefinition.TAG_TIMESTAMP); + firstEntryTimeStampInputFormat = timeStampFormat; + } + if (firstEntryTimeStamp == null) { + timestampPreviewText.setText(Messages.CustomTxtParserInputWizardPage_noTimestampGroup); + if (selectedLine != null) { + for (InputGroup group : selectedLine.inputs) { + if (group.tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + timestampPreviewText.setText(Messages.CustomTxtParserInputWizardPage_noMatchingTimestamp); + break; + } + } + } + } else { + try { + TmfTimestampFormat timestampFormat = new TmfTimestampFormat(firstEntryTimeStampInputFormat); + long timestamp = timestampFormat.parseValue(firstEntryTimeStamp); + timestampFormat = new TmfTimestampFormat(timestampOutputFormatText.getText().trim()); + timestampPreviewText.setText(timestampFormat.format(timestamp)); + } catch (ParseException e) { + timestampPreviewText.setText("*parse exception* [" + firstEntryTimeStamp + "] <> [" + firstEntryTimeStampInputFormat + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } catch (IllegalArgumentException e) { + timestampPreviewText.setText("*parse exception* [Illegal Argument: " + e.getMessage() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + } + } + } + + private void updatePreviewLine(InputLine line, Matcher matcher, Map data, int rawPos, int rootLineMatches) { + for (int i = 0; i < line.columns.size(); i++) { + InputData input = line.columns.get(i); + if (i < matcher.groupCount() && matcher.group(i + 1) != null) { + if (line.parentInput == null) { + inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i + 1), matcher.end(i + 1) - matcher.start(i + 1), + COLOR_BLACK, COLOR_GREEN, SWT.BOLD)); + } else { + inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i + 1), matcher.end(i + 1) - matcher.start(i + 1), + COLOR_BLACK, COLOR_LIGHT_GREEN, SWT.BOLD)); + } + String value = matcher.group(i + 1).trim(); + if (selectedLine != null && selectedLine.inputLine.equals(line) && rootLineMatches == 1 && + selectedLine.inputs.get(i).previewText.getText().equals(Messages.CustomTxtParserInputWizardPage_noMatchingLine)) { + selectedLine.inputs.get(i).previewText.setText(value); + } + if (value.length() == 0) { + continue; + } + if (input.action == CustomTraceDefinition.ACTION_SET) { + data.put(input.name, value); + if (input.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + timeStampFormat = input.format; + } + } else if (input.action == CustomTraceDefinition.ACTION_APPEND) { + String s = data.get(input.name); + if (s != null) { + data.put(input.name, s + value); + } else { + data.put(input.name, value); + } + if (input.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + if (timeStampFormat != null) { + timeStampFormat += input.format; + } else { + timeStampFormat = input.format; + } + } + } else if (input.action == CustomTraceDefinition.ACTION_APPEND_WITH_SEPARATOR) { + String s = data.get(input.name); + if (s != null) { + data.put(input.name, s + " | " + value); //$NON-NLS-1$ + } else { + data.put(input.name, value); + } + if (input.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + if (timeStampFormat != null) { + timeStampFormat += " | " + input.format; //$NON-NLS-1$ + } else { + timeStampFormat = input.format; + } + } + } + } else { + if (selectedLine != null && selectedLine.inputLine.equals(line) && rootLineMatches == 1) { + if (selectedLine.inputs.get(i).previewText.getText().equals(Messages.CustomTxtParserInputWizardPage_noMatchingLine)) { + selectedLine.inputs.get(i).previewText.setText(Messages.CustomTxtParserInputWizardPage_noMatchingGroup); + } + } + } + } + // highlight the matching groups that have no corresponponding input + for (int i = line.columns.size(); i < matcher.groupCount(); i++) { + if (matcher.group(i + 1) != null) { + if (line.parentInput == null) { + inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i + 1), matcher.end(i + 1) - matcher.start(i + 1), + COLOR_BLACK, COLOR_MAGENTA)); + } else { + inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i + 1), matcher.end(i + 1) - matcher.start(i + 1), + COLOR_BLACK, COLOR_LIGHT_MAGENTA)); + } + } + } + } + + private void openHelpShell(String url) { + if (helpBrowser != null && !helpBrowser.isDisposed()) { + helpBrowser.getShell().setActive(); + if (!helpBrowser.getUrl().equals(url)) { + helpBrowser.setUrl(url); + } + return; + } + final Shell helpShell = new Shell(getShell(), SWT.SHELL_TRIM); + helpShell.setLayout(new FillLayout()); + helpBrowser = new Browser(helpShell, SWT.NONE); + helpBrowser.addTitleListener(new TitleListener() { + @Override + public void changed(TitleEvent event) { + helpShell.setText(event.title); + } + }); + Rectangle r = container.getBounds(); + Point p = container.toDisplay(r.x, r.y); + Rectangle trim = helpShell.computeTrim(p.x + (r.width - 750) / 2, p.y + (r.height - 400) / 2, 750, 400); + helpShell.setBounds(trim); + helpShell.open(); + helpBrowser.setUrl(url); + } + + private void openLegend() { + final String cg = Messages.CustomTxtParserInputWizardPage_capturedGroup; + final String ucg = Messages.CustomTxtParserInputWizardPage_unidentifiedCaptureGroup; + final String ut = Messages.CustomTxtParserInputWizardPage_uncapturedText; + int line1start = 0; + String line1 = Messages.CustomTxtParserInputWizardPage_nonMatchingLine; + int line2start = line1start + line1.length(); + String line2 = Messages.CustomTxtParserInputWizardPage_matchingRootLine + ' ' + cg + ' ' + ucg + ' ' + ut + " \n"; //$NON-NLS-1$ + int line3start = line2start + line2.length(); + String line3 = Messages.CustomTxtParserInputWizardPage_matchingOtherLine + ' ' + cg + ' ' + ucg + ' ' + ut + " \n"; //$NON-NLS-1$ + int line4start = line3start + line3.length(); + String line4 = Messages.CustomTxtParserInputWizardPage_matchingOtherLine + ' ' + cg + ' ' + ucg + ' ' + ut + " \n"; //$NON-NLS-1$ + int line5start = line4start + line4.length(); + String line5 = Messages.CustomTxtParserInputWizardPage_nonMatchingLine; + int line6start = line5start + line5.length(); + String line6 = Messages.CustomTxtParserInputWizardPage_matchingRootLine + cg + ' ' + ucg + ' ' + ut + " \n"; //$NON-NLS-1$ + + final Shell legendShell = new Shell(getShell(), SWT.DIALOG_TRIM); + legendShell.setLayout(new FillLayout()); + StyledText legendText = new StyledText(legendShell, SWT.MULTI); + legendText.setFont(fixedFont); + legendText.setText(line1 + line2 + line3 + line4 + line5 + line6); + legendText.setStyleRange(new StyleRange(line2start, line2.length(), COLOR_BLACK, COLOR_YELLOW, SWT.ITALIC)); + legendText.setStyleRange(new StyleRange(line3start, line3.length(), COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC)); + legendText.setStyleRange(new StyleRange(line4start, line4.length(), COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC)); + legendText.setStyleRange(new StyleRange(line6start, line6.length(), COLOR_BLACK, COLOR_YELLOW, SWT.ITALIC)); + legendText.setStyleRange(new StyleRange(line2start + line2.indexOf(cg), cg.length(), COLOR_BLACK, COLOR_GREEN, SWT.BOLD)); + legendText.setStyleRange(new StyleRange(line2start + line2.indexOf(ucg), ucg.length(), COLOR_BLACK, COLOR_MAGENTA)); + legendText.setStyleRange(new StyleRange(line3start + line3.indexOf(cg), cg.length(), COLOR_BLACK, COLOR_LIGHT_GREEN, SWT.BOLD)); + legendText.setStyleRange(new StyleRange(line3start + line3.indexOf(ucg), ucg.length(), COLOR_BLACK, COLOR_LIGHT_MAGENTA)); + legendText.setStyleRange(new StyleRange(line4start + line4.indexOf(cg), cg.length(), COLOR_BLACK, COLOR_LIGHT_GREEN, SWT.BOLD)); + legendText.setStyleRange(new StyleRange(line4start + line4.indexOf(ucg), ucg.length(), COLOR_BLACK, COLOR_LIGHT_MAGENTA)); + legendText.setStyleRange(new StyleRange(line6start + line6.indexOf(cg), cg.length(), COLOR_BLACK, COLOR_GREEN, SWT.BOLD)); + legendText.setStyleRange(new StyleRange(line6start + line6.indexOf(ucg), ucg.length(), COLOR_BLACK, COLOR_MAGENTA)); + legendShell.setText(Messages.CustomTxtParserInputWizardPage_previewLegend); + legendShell.pack(); + legendShell.open(); + } + + private class UpdateListener implements ModifyListener, SelectionListener { + + @Override + public void modifyText(ModifyEvent e) { + validate(); + updatePreviews(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + validate(); + updatePreviews(); + } + + @Override + public void widgetSelected(SelectionEvent e) { + validate(); + updatePreviews(); + } + + } + + private class Line { + private static final String INFINITY_STRING = "\u221E"; //$NON-NLS-1$ + private InputLine inputLine; + private Group group; + private Composite labelComposite; + private Text regexText; + private Composite cardinalityContainer; + private Combo cardinalityCombo; + private Label cardinalityMinLabel; + private Text cardinalityMinText; + private Label cardinalityMaxLabel; + private Text cardinalityMaxText; + private Button infiniteButton; + private List inputs = new ArrayList<>(); + private Button addGroupButton; + private Label addGroupLabel; + + public Line(Composite parent, String name, InputLine inputLine) { + this.inputLine = inputLine; + + group = new Group(parent, SWT.NONE); + group.setText(name); + group.setLayout(new GridLayout(2, false)); + group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + labelComposite = new Composite(group, SWT.FILL); + GridLayout labelLayout = new GridLayout(1, false); + labelLayout.marginWidth = 0; + labelLayout.marginHeight = 0; + labelComposite.setLayout(labelLayout); + labelComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + + Label label = new Label(labelComposite, SWT.NULL); + label.setText(Messages.CustomTxtParserInputWizardPage_regularExpression); + + Composite regexContainer = new Composite(group, SWT.NONE); + GridLayout regexLayout = new GridLayout(2, false); + regexLayout.marginHeight = 0; + regexLayout.marginWidth = 0; + regexContainer.setLayout(regexLayout); + regexContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + regexText = new Text(regexContainer, SWT.BORDER | SWT.SINGLE); + GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); + gd.widthHint = 0; + regexText.setLayoutData(gd); + regexText.setText(inputLine.getRegex()); + regexText.addModifyListener(updateListener); + + Button regexHelpButton = new Button(regexContainer, SWT.PUSH); + regexHelpButton.setImage(HELP_IMAGE); + regexHelpButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_regularExpressionHelp); + regexHelpButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + openHelpShell(PATTERN_URL); + } + }); + + label = new Label(group, SWT.NONE); + label.setText(Messages.CustomTxtParserInputWizardPage_cardinality); + label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + + cardinalityContainer = new Composite(group, SWT.NONE); + GridLayout cardinalityLayout = new GridLayout(6, false); + cardinalityLayout.marginHeight = 0; + cardinalityLayout.marginWidth = 0; + cardinalityContainer.setLayout(cardinalityLayout); + cardinalityContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + cardinalityCombo = new Combo(cardinalityContainer, SWT.DROP_DOWN | SWT.READ_ONLY); + cardinalityCombo.setItems(new String[] { + Cardinality.ZERO_OR_MORE.toString(), + Cardinality.ONE_OR_MORE.toString(), + Cardinality.ZERO_OR_ONE.toString(), + Cardinality.ONE.toString(), "(?,?)" }); //$NON-NLS-1$ + cardinalityCombo.addSelectionListener(new SelectionListener() { + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + + @Override + public void widgetSelected(SelectionEvent e) { + switch (cardinalityCombo.getSelectionIndex()) { + case 4: // (?,?) + cardinalityMinLabel.setVisible(true); + cardinalityMinText.setVisible(true); + cardinalityMaxLabel.setVisible(true); + cardinalityMaxText.setVisible(true); + infiniteButton.setVisible(true); + break; + default: + cardinalityMinLabel.setVisible(false); + cardinalityMinText.setVisible(false); + cardinalityMaxLabel.setVisible(false); + cardinalityMaxText.setVisible(false); + infiniteButton.setVisible(false); + break; + } + cardinalityContainer.layout(); + validate(); + updatePreviews(); + } + }); + + cardinalityMinLabel = new Label(cardinalityContainer, SWT.NONE); + cardinalityMinLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + cardinalityMinLabel.setText(Messages.CustomTxtParserInputWizardPage_min); + cardinalityMinLabel.setVisible(false); + + cardinalityMinText = new Text(cardinalityContainer, SWT.BORDER | SWT.SINGLE); + gd = new GridData(SWT.CENTER, SWT.CENTER, false, false); + gd.widthHint = 20; + cardinalityMinText.setLayoutData(gd); + cardinalityMinText.setVisible(false); + + cardinalityMaxLabel = new Label(cardinalityContainer, SWT.NONE); + cardinalityMaxLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + cardinalityMaxLabel.setText(Messages.CustomTxtParserInputWizardPage_max); + cardinalityMaxLabel.setVisible(false); + + cardinalityMaxText = new Text(cardinalityContainer, SWT.BORDER | SWT.SINGLE); + gd = new GridData(SWT.CENTER, SWT.CENTER, false, false); + gd.widthHint = 20; + cardinalityMaxText.setLayoutData(gd); + cardinalityMaxText.setVisible(false); + + infiniteButton = new Button(cardinalityContainer, SWT.PUSH); + infiniteButton.setText(INFINITY_STRING); + infiniteButton.setVisible(false); + infiniteButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + cardinalityMaxText.setText(INFINITY_STRING); + } + }); + + if (inputLine.cardinality.equals(Cardinality.ZERO_OR_MORE)) { + cardinalityCombo.select(0); + } else if (inputLine.cardinality.equals(Cardinality.ONE_OR_MORE)) { + cardinalityCombo.select(1); + } else if (inputLine.cardinality.equals(Cardinality.ZERO_OR_ONE)) { + cardinalityCombo.select(2); + } else if (inputLine.cardinality.equals(Cardinality.ONE)) { + cardinalityCombo.select(3); + } else { + cardinalityCombo.select(4); + cardinalityMinLabel.setVisible(true); + cardinalityMinText.setVisible(true); + if (inputLine.getMinCount() >= 0) { + cardinalityMinText.setText(Integer.toString(inputLine.getMinCount())); + } + cardinalityMaxLabel.setVisible(true); + cardinalityMaxText.setVisible(true); + if (inputLine.getMaxCount() == Cardinality.INF) { + cardinalityMaxText.setText(INFINITY_STRING); + } else if (inputLine.getMaxCount() >= 0) { + cardinalityMaxText.setText(Integer.toString(inputLine.getMaxCount())); + } + infiniteButton.setVisible(true); + } + + VerifyListener digitsListener = new VerifyListener() { + @Override + public void verifyText(VerifyEvent e) { + if (e.text.equals(INFINITY_STRING)) { + e.doit = e.widget == cardinalityMaxText && e.start == 0 && e.end == ((Text) e.widget).getText().length(); + } else { + if (((Text) e.widget).getText().equals(INFINITY_STRING)) { + e.doit = e.start == 0 && e.end == ((Text) e.widget).getText().length(); + } + for (int i = 0; i < e.text.length(); i++) { + if (!Character.isDigit(e.text.charAt(i))) { + e.doit = false; + break; + } + } + } + } + }; + + cardinalityMinText.addModifyListener(updateListener); + cardinalityMaxText.addModifyListener(updateListener); + cardinalityMinText.addVerifyListener(digitsListener); + cardinalityMaxText.addVerifyListener(digitsListener); + + if (inputLine.columns != null) { + for (InputData inputData : inputLine.columns) { + InputGroup inputGroup = new InputGroup(group, this, inputs.size() + 1); + if (inputData.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + inputGroup.tagCombo.select(0); + inputGroup.tagText.setText(inputData.format); + inputGroup.tagLabel.setText(Messages.CustomTxtParserInputWizardPage_format); + inputGroup.tagLabel.setVisible(true); + inputGroup.tagText.setVisible(true); + inputGroup.tagText.addModifyListener(updateListener); + } else if (inputData.name.equals(CustomTraceDefinition.TAG_MESSAGE)) { + inputGroup.tagCombo.select(1); + } else { + inputGroup.tagCombo.select(2); + inputGroup.tagText.setText(inputData.name); + inputGroup.tagLabel.setText(Messages.CustomTxtParserInputWizardPage_name); + inputGroup.tagLabel.setVisible(true); + inputGroup.tagText.setVisible(true); + inputGroup.tagText.addModifyListener(updateListener); + } + inputGroup.actionCombo.select(inputData.action); + inputs.add(inputGroup); + } + } + + createAddGroupButton(); + } + + private void createAddGroupButton() { + addGroupButton = new Button(group, SWT.PUSH); + addGroupButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + addGroupButton.setImage(ADD_IMAGE); + addGroupButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_addGroup); + addGroupButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + removeAddGroupButton(); + inputs.add(new InputGroup(group, Line.this, inputs.size() + 1)); + createAddGroupButton(); + lineContainer.layout(); + lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); + group.getParent().layout(); + validate(); + updatePreviews(); + } + }); + + addGroupLabel = new Label(group, SWT.NULL); + addGroupLabel.setText(Messages.CustomTxtParserInputWizardPage_newGroup); + } + + private void removeAddGroupButton() { + addGroupButton.dispose(); + addGroupLabel.dispose(); + } + + private void removeInput(int inputNumber) { + int nb = inputNumber; + if (--nb < inputs.size()) { + inputs.remove(nb).dispose(); + for (int i = nb; i < inputs.size(); i++) { + inputs.get(i).setInputNumber(i + 1); + } + lineContainer.layout(); + lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); + group.getParent().layout(); + } + } + + private void dispose() { + group.dispose(); + } + + private void extractInputs() { + inputLine.setRegex(selectedLine.regexText.getText()); + switch (cardinalityCombo.getSelectionIndex()) { + case 0: + inputLine.cardinality = Cardinality.ZERO_OR_MORE; + break; + case 1: + inputLine.cardinality = Cardinality.ONE_OR_MORE; + break; + case 2: + inputLine.cardinality = Cardinality.ZERO_OR_ONE; + break; + case 3: + inputLine.cardinality = Cardinality.ONE; + break; + case 4: // (?,?) + int min, + max; + try { + min = Integer.parseInt(cardinalityMinText.getText()); + } catch (NumberFormatException e) { + min = -1; + } + try { + if (cardinalityMaxText.getText().equals(INFINITY_STRING)) { + max = Cardinality.INF; + } else { + max = Integer.parseInt(cardinalityMaxText.getText()); + } + } catch (NumberFormatException e) { + max = -1; + } + inputLine.cardinality = new Cardinality(min, max); + break; + default: + inputLine.cardinality = Cardinality.ZERO_OR_MORE; + break; + } + inputLine.columns = new ArrayList<>(inputs.size()); + for (int i = 0; i < inputs.size(); i++) { + InputGroup grp = inputs.get(i); + InputData inputData = new InputData(); + if (grp.tagCombo.getText().equals(CustomTraceDefinition.TAG_OTHER)) { + inputData.name = grp.tagText.getText().trim(); + } else { + inputData.name = grp.tagCombo.getText(); + if (grp.tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + inputData.format = grp.tagText.getText().trim(); + } + } + inputData.action = grp.actionCombo.getSelectionIndex(); + inputLine.columns.add(inputData); + } + } + } + + private class InputGroup { + private Line line; + private int inputNumber; + + // children of parent (must be disposed) + private Composite labelComposite; + private Composite tagComposite; + private Label previewLabel; + private Text previewText; + + // children of labelComposite + private Label inputLabel; + + // children of tagComposite + private Combo tagCombo; + private Label tagLabel; + private Text tagText; + private Combo actionCombo; + + public InputGroup(Composite parent, Line line, int inputNumber) { + this.line = line; + this.inputNumber = inputNumber; + + labelComposite = new Composite(parent, SWT.FILL); + GridLayout labelLayout = new GridLayout(2, false); + labelLayout.marginWidth = 0; + labelLayout.marginHeight = 0; + labelComposite.setLayout(labelLayout); + labelComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + + Button deleteButton = new Button(labelComposite, SWT.PUSH); + deleteButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + deleteButton.setImage(DELETE_IMAGE); + deleteButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_removeGroup); + deleteButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + InputGroup.this.line.removeInput(InputGroup.this.inputNumber); + validate(); + updatePreviews(); + } + }); + + inputLabel = new Label(labelComposite, SWT.NULL); + inputLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + inputLabel.setText(NLS.bind(Messages.CustomTxtParserInputWizardPage_group, inputNumber)); + + tagComposite = new Composite(parent, SWT.FILL); + GridLayout tagLayout = new GridLayout(4, false); + tagLayout.marginWidth = 0; + tagLayout.marginHeight = 0; + tagComposite.setLayout(tagLayout); + tagComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + tagCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY); + tagCombo.setItems(new String[] { CustomTraceDefinition.TAG_TIMESTAMP, + CustomTraceDefinition.TAG_MESSAGE, + CustomTraceDefinition.TAG_OTHER }); + tagCombo.select(1); + tagCombo.addSelectionListener(new SelectionListener() { + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + + @Override + public void widgetSelected(SelectionEvent e) { + tagText.removeModifyListener(updateListener); + switch (tagCombo.getSelectionIndex()) { + case 0: // Time Stamp + tagLabel.setText(Messages.CustomTxtParserInputWizardPage_format); + tagLabel.setVisible(true); + tagText.setVisible(true); + tagText.addModifyListener(updateListener); + break; + case 1: // Message + tagLabel.setVisible(false); + tagText.setVisible(false); + break; + case 2: // Other + tagLabel.setText(Messages.CustomTxtParserInputWizardPage_name); + tagLabel.setVisible(true); + tagText.setVisible(true); + tagText.addModifyListener(updateListener); + break; + case 3: // Continue + tagLabel.setVisible(false); + tagText.setVisible(false); + break; + default: + break; + } + tagComposite.layout(); + validate(); + updatePreviews(); + } + }); + + tagLabel = new Label(tagComposite, SWT.NULL); + tagLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + tagLabel.setVisible(false); + + tagText = new Text(tagComposite, SWT.BORDER | SWT.SINGLE); + GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); + gd.widthHint = 0; + tagText.setLayoutData(gd); + tagText.setVisible(false); + + actionCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY); + actionCombo.setItems(new String[] { Messages.CustomTxtParserInputWizardPage_set, Messages.CustomTxtParserInputWizardPage_append, Messages.CustomTxtParserInputWizardPage_appendWith }); + actionCombo.select(0); + actionCombo.addSelectionListener(updateListener); + + previewLabel = new Label(parent, SWT.NULL); + previewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + previewLabel.setText(Messages.CustomTxtParserInputWizardPage_preview); + + previewText = new Text(parent, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); + gd = new GridData(SWT.FILL, SWT.CENTER, true, false); + gd.widthHint = 0; + previewText.setLayoutData(gd); + previewText.setText(Messages.CustomTxtParserInputWizardPage_noMatch); + previewText.setBackground(COLOR_WIDGET_BACKGROUND); + } + + private void dispose() { + labelComposite.dispose(); + tagComposite.dispose(); + previewLabel.dispose(); + previewText.dispose(); + } + + private void setInputNumber(int inputNumber) { + this.inputNumber = inputNumber; + inputLabel.setText(NLS.bind(Messages.CustomTxtParserInputWizardPage_group, inputNumber)); + labelComposite.layout(); + } + } + + private void validate() { + + definition.categoryName = categoryText.getText().trim(); + definition.definitionName = logtypeText.getText().trim(); + definition.timeStampOutputFormat = timestampOutputFormatText.getText().trim(); + + if (selectedLine != null) { + selectedLine.extractInputs(); + treeViewer.refresh(); + } + + StringBuffer errors = new StringBuffer(); + + if (definition.categoryName.length() == 0) { + errors.append("Enter a category for the new trace type. "); //$NON-NLS-1$ + categoryText.setBackground(COLOR_LIGHT_RED); + } else if (definition.definitionName.length() == 0) { + errors.append("Enter a name for the new trace type. "); //$NON-NLS-1$ + logtypeText.setBackground(COLOR_LIGHT_RED); + } else { + categoryText.setBackground(COLOR_TEXT_BACKGROUND); + logtypeText.setBackground(COLOR_TEXT_BACKGROUND); + if (definition.categoryName.indexOf(':') != -1) { + errors.append("Invalid character ':' in category. "); //$NON-NLS-1$ + categoryText.setBackground(COLOR_LIGHT_RED); + } + if (definition.definitionName.indexOf(':') != -1) { + errors.append("Invalid character ':' in trace type. "); //$NON-NLS-1$ + logtypeText.setBackground(COLOR_LIGHT_RED); + } + for (TraceTypeHelper helper : TmfTraceType.getTraceTypeHelpers()) { + if (definition.categoryName.equals(helper.getCategoryName()) && + definition.definitionName.equals(helper.getName()) && + (editDefinitionName == null || !editDefinitionName.equals(definition.definitionName)) && + (editCategoryName == null || !editCategoryName.equals(definition.categoryName))) { + errors.append("The trace type name already exists. "); //$NON-NLS-1$ + logtypeText.setBackground(COLOR_LIGHT_RED); + break; + } + } + } + + timestampFound = false; + for (int i = 0; i < definition.inputs.size(); i++) { + + InputLine inputLine = definition.inputs.get(i); + String name = Integer.toString(i + 1); + errors.append(validateLine(inputLine, name)); + } + if (timestampFound) { + if (definition.timeStampOutputFormat.length() == 0) { + errors.append("Enter the output format for the Time Stamp field. "); //$NON-NLS-1$ + timestampOutputFormatText.setBackground(COLOR_LIGHT_RED); + } else { + try { + new TmfTimestampFormat(definition.timeStampOutputFormat); + timestampOutputFormatText.setBackground(COLOR_TEXT_BACKGROUND); + } catch (IllegalArgumentException e) { + errors.append("Enter a valid output format for the Time Stamp field [" + e.getMessage() + "]."); //$NON-NLS-1$ //$NON-NLS-2$ + timestampOutputFormatText.setBackground(COLOR_LIGHT_RED); + } + } + + } else { + timestampOutputFormatText.setBackground(COLOR_TEXT_BACKGROUND); + } + + if (errors.length() == 0) { + setDescription(defaultDescription); + setPageComplete(true); + } else { + setDescription(errors.toString()); + setPageComplete(false); + } + } + + /** + * Validate an input line. + * + * @param inputLine + * The line to clean up + * @param name + * The name of the line + * @return The cleaned up line + */ + public StringBuffer validateLine(InputLine inputLine, String name) { + StringBuffer errors = new StringBuffer(); + Line line = null; + if (selectedLine != null && selectedLine.inputLine.equals(inputLine)) { + line = selectedLine; + } + try { + Pattern.compile(inputLine.getRegex()); + if (line != null) { + line.regexText.setBackground(COLOR_TEXT_BACKGROUND); + } + } catch (PatternSyntaxException e) { + errors.append("Enter a valid regular expression (Line " + name + "). "); //$NON-NLS-1$ //$NON-NLS-2$ + if (line != null) { + line.regexText.setBackground(COLOR_LIGHT_RED); + } + } + if (inputLine.getMinCount() == -1) { + errors.append("Enter a minimum value for cardinality (Line " + name + "). "); //$NON-NLS-1$ //$NON-NLS-2$ + if (line != null) { + line.cardinalityMinText.setBackground(COLOR_LIGHT_RED); + } + } else { + if (line != null) { + line.cardinalityMinText.setBackground(COLOR_TEXT_BACKGROUND); + } + } + if (inputLine.getMaxCount() == -1) { + errors.append("Enter a maximum value for cardinality (Line " + name + "). "); //$NON-NLS-1$ //$NON-NLS-2$ + if (line != null) { + line.cardinalityMaxText.setBackground(COLOR_LIGHT_RED); + } + } else if (inputLine.getMinCount() > inputLine.getMaxCount()) { + errors.append("Enter correct (min <= max) values for cardinality (Line " + name + "). "); //$NON-NLS-1$ //$NON-NLS-2$ + if (line != null) { + line.cardinalityMinText.setBackground(COLOR_LIGHT_RED); + } + if (line != null) { + line.cardinalityMaxText.setBackground(COLOR_LIGHT_RED); + } + } else { + if (line != null) { + line.cardinalityMaxText.setBackground(COLOR_TEXT_BACKGROUND); + } + } + for (int i = 0; inputLine.columns != null && i < inputLine.columns.size(); i++) { + InputData inputData = inputLine.columns.get(i); + InputGroup group = null; + if (line != null) { + group = line.inputs.get(i); + } + if (inputData.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + timestampFound = true; + if (inputData.format.length() == 0) { + errors.append("Enter the input format for the Time Stamp (Line " + name + " Group " + (i + 1) + "). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + if (group != null) { + group.tagText.setBackground(COLOR_LIGHT_RED); + } + } else { + try { + new TmfTimestampFormat(inputData.format); + if (group != null) { + group.tagText.setBackground(COLOR_TEXT_BACKGROUND); + } + } catch (IllegalArgumentException e) { + errors.append("Enter a valid input format for the Time Stamp (Line " + name + " Group " + (i + 1) + ") [" + e.getMessage() + "]. "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + if (group != null) { + group.tagText.setBackground(COLOR_LIGHT_RED); + } + } + } + } else if (inputData.name.length() == 0) { + errors.append("Enter a name for the data group (Line " + name + " Group " + (i + 1) + "). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + if (group != null) { + group.tagText.setBackground(COLOR_LIGHT_RED); + } + } else { + if (group != null) { + group.tagText.setBackground(COLOR_TEXT_BACKGROUND); + } + } + } + for (int i = 0; inputLine.childrenInputs != null && i < inputLine.childrenInputs.size(); i++) { + errors.append(validateLine(inputLine.childrenInputs.get(i), name + "." + (i + 1))); //$NON-NLS-1$ + } + return errors; + } + + /** + * Get the trace definition. + * + * @return The trace definition + */ + public CustomTxtTraceDefinition getDefinition() { + return definition; + } + + /** + * Get the raw text of the input. + * + * @return The raw input text + */ + public char[] getInputText() { + return inputText.getText().toCharArray(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomTxtParserOutputWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomTxtParserOutputWizardPage.java new file mode 100644 index 0000000000..af426e2be8 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomTxtParserOutputWizardPage.java @@ -0,0 +1,340 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.parsers.wizards; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.internal.tmf.ui.parsers.custom.CustomEventTableColumns; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTrace; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition.OutputColumn; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer; +import org.eclipse.tracecompass.tmf.ui.viewers.events.TmfEventsTable; + +/** + * Output wizard page for custom text trace parsers. + * + * @author Patrick Tasse + */ +public class CustomTxtParserOutputWizardPage extends WizardPage { + + private static final Image UP_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/up_button.gif"); //$NON-NLS-1$ + private static final Image DOWN_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/down_button.gif"); //$NON-NLS-1$ + private final CustomTxtParserWizard wizard; + private CustomTxtTraceDefinition definition; + private List outputs = new ArrayList<>(); + private Composite container; + private SashForm sash; + private ScrolledComposite outputsScrolledComposite; + private Composite outputsContainer; + private Composite tableContainer; + private TmfEventsTable previewTable; + private File tmpFile; + + /** + * Constructor + * + * @param wizard + * The wizard to which this page belongs + */ + protected CustomTxtParserOutputWizardPage(final CustomTxtParserWizard wizard) { + super("CustomParserOutputWizardPage"); //$NON-NLS-1$ + setTitle(wizard.inputPage.getTitle()); + setDescription(Messages.CustomTxtParserOutputWizardPage_description); + this.wizard = wizard; + setPageComplete(false); + } + + @Override + public void createControl(final Composite parent) { + container = new Composite(parent, SWT.NULL); + container.setLayout(new GridLayout()); + + sash = new SashForm(container, SWT.VERTICAL); + sash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + sash.setBackground(sash.getDisplay().getSystemColor(SWT.COLOR_GRAY)); + + outputsScrolledComposite = new ScrolledComposite(sash, SWT.V_SCROLL); + outputsScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + outputsContainer = new Composite(outputsScrolledComposite, SWT.NONE); + final GridLayout outputsLayout = new GridLayout(4, false); + outputsLayout.marginHeight = 10; + outputsLayout.marginWidth = 0; + outputsContainer.setLayout(outputsLayout); + outputsScrolledComposite.setContent(outputsContainer); + outputsScrolledComposite.setExpandHorizontal(true); + outputsScrolledComposite.setExpandVertical(true); + + outputsContainer.layout(); + + outputsScrolledComposite.setMinSize(outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-5); + + tableContainer = new Composite(sash, SWT.NONE); + final GridLayout tableLayout = new GridLayout(); + tableLayout.marginHeight = 0; + tableLayout.marginWidth = 0; + tableContainer.setLayout(tableLayout); + previewTable = new TmfEventsTable(tableContainer, 0, CustomEventTableColumns.generateColumns(new CustomTxtTraceDefinition())); + previewTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + if (wizard.definition != null) { + loadDefinition(wizard.definition); + } + setControl(container); + + } + + @Override + public void dispose() { + previewTable.dispose(); + super.dispose(); + } + + private void loadDefinition(final CustomTxtTraceDefinition def) { + for (final OutputColumn outputColumn : def.outputs) { + final Output output = new Output(outputsContainer, outputColumn.name); + outputs.add(output); + } + } + + @Override + public void setVisible(final boolean visible) { + if (visible) { + this.definition = wizard.inputPage.getDefinition(); + final List outputNames = wizard.inputPage.getInputNames(); + + // dispose outputs that have been removed in the input page + final Iterator iter = outputs.iterator(); + while (iter.hasNext()) { + final Output output = iter.next(); + boolean found = false; + for (final String name : outputNames) { + if (output.name.equals(name)) { + found = true; + break; + } + } + if (!found) { + output.dispose(); + iter.remove(); + } + } + + // create outputs that have been added in the input page + for (final String name : outputNames) { + boolean found = false; + for (final Output output : outputs) { + if (output.name.equals(name)) { + found = true; + break; + } + } + if (!found) { + outputs.add(new Output(outputsContainer, name)); + } + } + + outputsContainer.layout(); + outputsScrolledComposite.setMinSize(outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-5); + updatePreviewTable(); + if (sash.getSize().y > outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y + previewTable.getTable().getItemHeight()) { + sash.setWeights(new int[] {outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, sash.getSize().y - outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y}); + } else { + sash.setWeights(new int[] {outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, previewTable.getTable().getItemHeight()}); + } + setPageComplete(true); + } else { + setPageComplete(false); + } + super.setVisible(visible); + } + + private void moveBefore(final Output moved) { + final int i = outputs.indexOf(moved); + if (i > 0) { + final Output previous = outputs.get(i-1); + moved.enabledButton.moveAbove(previous.enabledButton); + moved.nameLabel.moveBelow(moved.enabledButton); + moved.upButton.moveBelow(moved.nameLabel); + moved.downButton.moveBelow(moved.upButton); + outputs.add(i-1, outputs.remove(i)); + outputsContainer.layout(); + outputsScrolledComposite.setMinSize(outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-5); + container.layout(); + updatePreviewTable(); + } + } + + private void moveAfter(final Output moved) { + final int i = outputs.indexOf(moved); + if (i+1 < outputs.size()) { + final Output next = outputs.get(i+1); + moved.enabledButton.moveBelow(next.downButton); + moved.nameLabel.moveBelow(moved.enabledButton); + moved.upButton.moveBelow(moved.nameLabel); + moved.downButton.moveBelow(moved.upButton); + outputs.add(i+1, outputs.remove(i)); + outputsContainer.layout(); + outputsScrolledComposite.setMinSize(outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-5); + container.layout(); + updatePreviewTable(); + } + } + + private void updatePreviewTable() { + final int CACHE_SIZE = 50; + definition.outputs = extractOutputs(); + tmpFile = Activator.getDefault().getStateLocation().addTrailingSeparator().append("customwizard.tmp").toFile(); //$NON-NLS-1$ + + try (final FileWriter writer = new FileWriter(tmpFile);) { + writer.write(wizard.inputPage.getInputText()); + } catch (final IOException e) { + Activator.getDefault().logError("Error creating CustomTxtTrace. File:" + tmpFile.getAbsolutePath(), e); //$NON-NLS-1$ + } + + try { + final CustomTxtTrace trace = new CustomTxtTrace(null, definition, tmpFile.getAbsolutePath(), CACHE_SIZE) { + @Override + protected ITmfTraceIndexer createIndexer(int interval) { + return new TmfCheckpointIndexer(this, interval); + } + }; + trace.getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, false); + previewTable.dispose(); + previewTable = new TmfEventsTable(tableContainer, CACHE_SIZE, CustomEventTableColumns.generateColumns(definition)); + previewTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + previewTable.setTrace(trace, true); + } catch (final TmfTraceException e) { + Activator.getDefault().logError("Error creating CustomTxtTrace. File:" + tmpFile.getAbsolutePath(), e); //$NON-NLS-1$ + } + + tableContainer.layout(); + container.layout(); + } + + /** + * Extract the list of output columns from the page's contents. + * + * @return The output columns + */ + public List extractOutputs() { + int numColumns = 0; + for (int i = 0; i < outputs.size(); i++) { + if (outputs.get(i).enabledButton.getSelection()) { + numColumns++; + } + } + final List outputColumns = new ArrayList<>(numColumns); + numColumns = 0; + for (int i = 0; i < outputs.size(); i++) { + final Output output = outputs.get(i); + if (output.enabledButton.getSelection()) { + final OutputColumn column = new OutputColumn(); + column.name = output.nameLabel.getText(); + outputColumns.add(column); + } + } + return outputColumns; + } + + private class Output { + String name; + Button enabledButton; + Text nameLabel; + Button upButton; + Button downButton; + + public Output(final Composite parent, final String name) { + this.name = name; + + enabledButton = new Button(parent, SWT.CHECK); + enabledButton.setToolTipText(Messages.CustomTxtParserOutputWizardPage_visible); + enabledButton.setSelection(true); + enabledButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + updatePreviewTable(); + } + }); + // if (messageOutput != null) { + // enabledButton.moveAbove(messageOutput.enabledButton); + // } + + nameLabel = new Text(parent, SWT.BORDER | SWT.READ_ONLY | SWT.SINGLE); + nameLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + nameLabel.setText(name); + nameLabel.moveBelow(enabledButton); + + upButton = new Button(parent, SWT.PUSH); + upButton.setImage(UP_IMAGE); + upButton.setToolTipText(Messages.CustomTxtParserOutputWizardPage_moveBefore); + upButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + moveBefore(Output.this); + } + }); + upButton.moveBelow(nameLabel); + + downButton = new Button(parent, SWT.PUSH); + downButton.setImage(DOWN_IMAGE); + downButton.setToolTipText(Messages.CustomTxtParserOutputWizardPage_moveAfter); + downButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + moveAfter(Output.this); + } + }); + downButton.moveBelow(upButton); + } + + private void dispose() { + enabledButton.dispose(); + nameLabel.dispose(); + upButton.dispose(); + downButton.dispose(); + } + } + + /** + * Get the trace definition. + * + * @return The trace definition + */ + public CustomTxtTraceDefinition getDefinition() { + return definition; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomTxtParserWizard.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomTxtParserWizard.java new file mode 100644 index 0000000000..8affbab32f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomTxtParserWizard.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.parsers.wizards; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition; +import org.eclipse.ui.INewWizard; +import org.eclipse.ui.IWorkbench; + +/** + * Wizard for custom text trace parsers. + * + * @author Patrick Tasse + */ +public class CustomTxtParserWizard extends Wizard implements INewWizard { + + CustomTxtParserInputWizardPage inputPage; + CustomTxtParserOutputWizardPage outputPage; + private ISelection selection; + CustomTxtTraceDefinition definition; + String initialCategoryName; + String initialDefinitionName; + + /** + * Default constructor + */ + public CustomTxtParserWizard() { + super(); + } + + /** + * Constructor + * + * @param definition + * The trace definition + */ + public CustomTxtParserWizard(CustomTxtTraceDefinition definition) { + super(); + this.definition = definition; + if (definition != null) { + initialCategoryName = definition.categoryName; + initialDefinitionName = definition.definitionName; + } + } + + @Override + public boolean performFinish() { + CustomTxtTraceDefinition def = outputPage.getDefinition(); + if (definition != null && (!initialCategoryName.equals(def.categoryName) || + !initialDefinitionName.equals(def.definitionName))) { + CustomTxtTraceDefinition.delete(initialCategoryName, initialDefinitionName); + } + def.save(); + return true; + } + + @Override + public void addPages() { + inputPage = new CustomTxtParserInputWizardPage(selection, definition); + addPage(inputPage); + outputPage = new CustomTxtParserOutputWizardPage(this); + addPage(outputPage); + } + + @Override + public void init(IWorkbench workbench, IStructuredSelection sel) { + this.selection = sel; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomXmlParserInputWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomXmlParserInputWizardPage.java new file mode 100644 index 0000000000..d959a7e665 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomXmlParserInputWizardPage.java @@ -0,0 +1,1765 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.parsers.wizards; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.browser.Browser; +import org.eclipse.swt.browser.TitleEvent; +import org.eclipse.swt.browser.TitleListener; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTrace; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition.InputAttribute; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition.InputElement; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; +import org.osgi.framework.Bundle; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.EntityResolver; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import com.google.common.base.Joiner; + +/** + * Input wizard page for custom XML trace parsers. + * + * @author Patrick Tasse + */ +public class CustomXmlParserInputWizardPage extends WizardPage { + + private static final String DEFAULT_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; //$NON-NLS-1$ + private static final String TIMESTAMP_FORMAT_BUNDLE = "org.eclipse.linuxtools.lttng.help"; //$NON-NLS-1$ + private static final String TIMESTAMP_FORMAT_PATH = "reference/api/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestampFormat.html"; //$NON-NLS-1$ + private static final Image ELEMENT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/element_icon.gif"); //$NON-NLS-1$ + private static final Image ADD_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/add_button.gif"); //$NON-NLS-1$ + private static final Image ADD_NEXT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/addnext_button.gif"); //$NON-NLS-1$ + private static final Image ADD_CHILD_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/addchild_button.gif"); //$NON-NLS-1$ + private static final Image ADD_MANY_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/addmany_button.gif"); //$NON-NLS-1$ + private static final Image DELETE_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/delete_button.gif"); //$NON-NLS-1$ + private static final Image MOVE_UP_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/moveup_button.gif"); //$NON-NLS-1$ + private static final Image MOVE_DOWN_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/movedown_button.gif"); //$NON-NLS-1$ + private static final Image HELP_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/help_button.gif"); //$NON-NLS-1$ + private static final Color COLOR_LIGHT_RED = new Color(Display.getDefault(), 255, 192, 192); + private static final Color COLOR_TEXT_BACKGROUND = Display.getDefault().getSystemColor(SWT.COLOR_WHITE); + private static final Color COLOR_WIDGET_BACKGROUND = Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); + + private final ISelection selection; + private CustomXmlTraceDefinition definition; + private String editCategoryName; + private String editDefinitionName; + private String defaultDescription; + private ElementNode selectedElement; + private Composite container; + private Text categoryText; + private Text logtypeText; + private Text timeStampOutputFormatText; + private Text timeStampPreviewText; + private Button removeButton; + private Button addChildButton; + private Button addNextButton; + private Button moveUpButton; + private Button moveDownButton; + private ScrolledComposite elementScrolledComposite; + private TreeViewer treeViewer; + private Composite elementContainer; + private Text errorText; + private StyledText inputText; + private Font fixedFont; + private UpdateListener updateListener; + private Browser helpBrowser; + private Element documentElement; + + // variables used recursively through element traversal + private String timeStampValue; + private String timeStampFormat; + private boolean timeStampFound; + private int logEntriesCount; + private boolean logEntryFound; + + /** + * Constructor + * + * @param selection + * Selection object + * @param definition + * Trace definition + */ + protected CustomXmlParserInputWizardPage(ISelection selection, CustomXmlTraceDefinition definition) { + super("CustomXmlParserWizardPage"); //$NON-NLS-1$ + if (definition == null) { + setTitle(Messages.CustomXmlParserInputWizardPage_titleNew); + defaultDescription = Messages.CustomXmlParserInputWizardPage_descriptionNew; + } else { + setTitle(Messages.CustomXmlParserInputWizardPage_titleEdit); + defaultDescription = Messages.CustomXmlParserInputWizardPage_descriptionEdit; + } + setDescription(defaultDescription); + this.selection = selection; + this.definition = definition; + if (definition != null) { + this.editCategoryName = definition.categoryName; + this.editDefinitionName = definition.definitionName; + } + } + + @Override + public void createControl(Composite parent) { + container = new Composite(parent, SWT.NULL); + container.setLayout(new GridLayout()); + + updateListener = new UpdateListener(); + + Composite headerComposite = new Composite(container, SWT.FILL); + GridLayout headerLayout = new GridLayout(5, false); + headerLayout.marginHeight = 0; + headerLayout.marginWidth = 0; + headerComposite.setLayout(headerLayout); + headerComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + Label categoryLabel = new Label(headerComposite, SWT.NULL); + categoryLabel.setText(Messages.CustomXmlParserInputWizardPage_category); + + categoryText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE); + categoryText.setLayoutData(new GridData(120, SWT.DEFAULT)); + + Label timeStampFormatLabel = new Label(headerComposite, SWT.NULL); + timeStampFormatLabel.setText(Messages.CustomXmlParserInputWizardPage_timestampFormat); + + timeStampOutputFormatText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE); + timeStampOutputFormatText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + timeStampOutputFormatText.setText(DEFAULT_TIMESTAMP_FORMAT); + + Button timeStampFormatHelpButton = new Button(headerComposite, SWT.PUSH); + timeStampFormatHelpButton.setImage(HELP_IMAGE); + timeStampFormatHelpButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_timestampFormatHelp); + timeStampFormatHelpButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + Bundle plugin = Platform.getBundle(TIMESTAMP_FORMAT_BUNDLE); + IPath path = new Path(TIMESTAMP_FORMAT_PATH); + URL fileURL = FileLocator.find(plugin, path, null); + try { + URL pageURL = FileLocator.toFileURL(fileURL); + openHelpShell(pageURL.toString()); + } catch (IOException e1) { + } + } + }); + + Label logtypeLabel = new Label(headerComposite, SWT.NULL); + logtypeLabel.setText(Messages.CustomXmlParserInputWizardPage_logType); + + logtypeText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE); + logtypeText.setLayoutData(new GridData(120, SWT.DEFAULT)); + logtypeText.setFocus(); + + Label timeStampPreviewLabel = new Label(headerComposite, SWT.NULL); + timeStampPreviewLabel.setText(Messages.CustomXmlParserInputWizardPage_preview); + + timeStampPreviewText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); + timeStampPreviewText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); + timeStampPreviewText.setText("*no time stamp element or attribute*"); //$NON-NLS-1$ + + createButtonBar(); + + SashForm vSash = new SashForm(container, SWT.VERTICAL); + vSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + vSash.setBackground(vSash.getDisplay().getSystemColor(SWT.COLOR_GRAY)); + + SashForm hSash = new SashForm(vSash, SWT.HORIZONTAL); + hSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + ScrolledComposite treeScrolledComposite = new ScrolledComposite(hSash, SWT.V_SCROLL | SWT.H_SCROLL); + treeScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + Composite treeContainer = new Composite(treeScrolledComposite, SWT.NONE); + treeContainer.setLayout(new FillLayout()); + treeScrolledComposite.setContent(treeContainer); + treeScrolledComposite.setExpandHorizontal(true); + treeScrolledComposite.setExpandVertical(true); + + treeViewer = new TreeViewer(treeContainer, SWT.SINGLE | SWT.BORDER); + treeViewer.setContentProvider(new InputElementTreeNodeContentProvider()); + treeViewer.setLabelProvider(new InputElementTreeLabelProvider()); + treeViewer.addSelectionChangedListener(new InputElementTreeSelectionChangedListener()); + treeContainer.layout(); + + treeScrolledComposite + .setMinSize(treeContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, treeContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y); + + elementScrolledComposite = new ScrolledComposite(hSash, SWT.V_SCROLL); + elementScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + elementContainer = new Composite(elementScrolledComposite, SWT.NONE); + GridLayout gl = new GridLayout(); + gl.marginHeight = 1; + gl.marginWidth = 0; + elementContainer.setLayout(gl); + elementScrolledComposite.setContent(elementContainer); + elementScrolledComposite.setExpandHorizontal(true); + elementScrolledComposite.setExpandVertical(true); + + if (definition == null) { + definition = new CustomXmlTraceDefinition(); + } + loadDefinition(definition); + treeViewer.expandAll(); + elementContainer.layout(); + + categoryText.addModifyListener(updateListener); + logtypeText.addModifyListener(updateListener); + timeStampOutputFormatText.addModifyListener(updateListener); + + elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, + elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); + + hSash.setWeights(new int[] { 1, 2 }); + + if (definition.rootInputElement == null) { + removeButton.setEnabled(false); + addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addDocumentElement); + addNextButton.setEnabled(false); + moveUpButton.setEnabled(false); + moveDownButton.setEnabled(false); + } else { // root is selected + addNextButton.setEnabled(false); + } + + Composite sashBottom = new Composite(vSash, SWT.NONE); + GridLayout sashBottomLayout = new GridLayout(2, false); + sashBottomLayout.marginHeight = 0; + sashBottomLayout.marginWidth = 0; + sashBottom.setLayout(sashBottomLayout); + + Label previewLabel = new Label(sashBottom, SWT.NULL); + previewLabel.setText(Messages.CustomXmlParserInputWizardPage_previewInput); + + errorText = new Text(sashBottom, SWT.SINGLE | SWT.READ_ONLY); + errorText.setBackground(COLOR_WIDGET_BACKGROUND); + errorText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + errorText.setVisible(false); + + inputText = new StyledText(sashBottom, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL); + if (fixedFont == null) { + if (System.getProperty("os.name").contains("Windows")) { //$NON-NLS-1$ //$NON-NLS-2$ + fixedFont = new Font(Display.getCurrent(), new FontData("Courier New", 10, SWT.NORMAL)); //$NON-NLS-1$ + } else { + fixedFont = new Font(Display.getCurrent(), new FontData("Monospace", 10, SWT.NORMAL)); //$NON-NLS-1$ + } + } + inputText.setFont(fixedFont); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1); + gd.heightHint = inputText.computeSize(SWT.DEFAULT, inputText.getLineHeight() * 4).y; + gd.widthHint = 800; + inputText.setLayoutData(gd); + inputText.setText(getSelectionText()); + inputText.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + parseXmlInput(inputText.getText()); + } + }); + inputText.addModifyListener(updateListener); + + vSash.setWeights(new int[] { hSash.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, sashBottom.computeSize(SWT.DEFAULT, SWT.DEFAULT).y }); + + setControl(container); + } + + private void createButtonBar() { + Composite buttonBar = new Composite(container, SWT.NONE); + GridLayout buttonBarLayout = new GridLayout(6, false); + buttonBarLayout.marginHeight = 0; + buttonBarLayout.marginWidth = 0; + buttonBar.setLayout(buttonBarLayout); + + removeButton = new Button(buttonBar, SWT.PUSH); + removeButton.setImage(DELETE_IMAGE); + removeButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_removeElement); + removeButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (treeViewer.getSelection().isEmpty() || selectedElement == null) { + return; + } + removeElement(); + InputElement inputElement = (InputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); + if (inputElement == definition.rootInputElement) { + definition.rootInputElement = null; + } else { + inputElement.parentElement.childElements.remove(inputElement); + } + treeViewer.refresh(); + validate(); + updatePreviews(); + removeButton.setEnabled(false); + if (definition.rootInputElement == null) { + addChildButton.setEnabled(true); + addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addDocumentEleemnt); + } else { + addChildButton.setEnabled(false); + } + addNextButton.setEnabled(false); + moveUpButton.setEnabled(false); + moveDownButton.setEnabled(false); + } + }); + + addChildButton = new Button(buttonBar, SWT.PUSH); + addChildButton.setImage(ADD_CHILD_IMAGE); + addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addChildElement); + addChildButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + InputElement inputElement = new InputElement("", false, CustomXmlTraceDefinition.TAG_IGNORE, 0, "", null); //$NON-NLS-1$ //$NON-NLS-2$ + if (definition.rootInputElement == null) { + definition.rootInputElement = inputElement; + inputElement.elementName = getChildNameSuggestion(null); + } else if (treeViewer.getSelection().isEmpty()) { + return; + } else { + InputElement parentInputElement = (InputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); + parentInputElement.addChild(inputElement); + inputElement.elementName = getChildNameSuggestion(parentInputElement); + } + treeViewer.refresh(); + treeViewer.setSelection(new StructuredSelection(inputElement), true); + } + }); + + addNextButton = new Button(buttonBar, SWT.PUSH); + addNextButton.setImage(ADD_NEXT_IMAGE); + addNextButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addNextElement); + addNextButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + InputElement inputElement = new InputElement("", false, CustomXmlTraceDefinition.TAG_IGNORE, 0, "", null); //$NON-NLS-1$ //$NON-NLS-2$ + if (definition.rootInputElement == null) { + definition.rootInputElement = inputElement; + inputElement.elementName = getChildNameSuggestion(null); + } else if (treeViewer.getSelection().isEmpty()) { + return; + } else { + InputElement previousInputElement = (InputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); + if (previousInputElement == definition.rootInputElement) { + return; + } + previousInputElement.addNext(inputElement); + inputElement.elementName = getChildNameSuggestion(inputElement.parentElement); + } + treeViewer.refresh(); + treeViewer.setSelection(new StructuredSelection(inputElement), true); + } + }); + + Button feelingLuckyButton = new Button(buttonBar, SWT.PUSH); + feelingLuckyButton.setImage(ADD_MANY_IMAGE); + feelingLuckyButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_feelingLucky); + feelingLuckyButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + InputElement inputElement = null; + if (definition.rootInputElement == null) { + if (getChildNameSuggestion(null).length() != 0) { + inputElement = new InputElement(getChildNameSuggestion(null), false, CustomXmlTraceDefinition.TAG_IGNORE, 0, "", null); //$NON-NLS-1$ + definition.rootInputElement = inputElement; + feelingLucky(inputElement); + } else { + return; + } + } else if (treeViewer.getSelection().isEmpty()) { + return; + } else { + inputElement = (InputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); + feelingLucky(inputElement); + } + treeViewer.refresh(); + treeViewer.setSelection(new StructuredSelection(inputElement), true); + treeViewer.expandToLevel(inputElement, AbstractTreeViewer.ALL_LEVELS); + } + }); + + moveUpButton = new Button(buttonBar, SWT.PUSH); + moveUpButton.setImage(MOVE_UP_IMAGE); + moveUpButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_moveUp); + moveUpButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (treeViewer.getSelection().isEmpty()) { + return; + } + InputElement inputElement = (InputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); + if (inputElement == definition.rootInputElement) { + return; + } + inputElement.moveUp(); + treeViewer.refresh(); + validate(); + updatePreviews(); + } + }); + + moveDownButton = new Button(buttonBar, SWT.PUSH); + moveDownButton.setImage(MOVE_DOWN_IMAGE); + moveDownButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_moveDown); + moveDownButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (treeViewer.getSelection().isEmpty()) { + return; + } + InputElement inputElement = (InputElement) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); + if (inputElement == definition.rootInputElement) { + return; + } + inputElement.moveDown(); + treeViewer.refresh(); + validate(); + updatePreviews(); + } + }); + } + + private void feelingLucky(InputElement inputElement) { + while (true) { + String attributeName = getAttributeNameSuggestion(inputElement); + if (attributeName.length() == 0) { + break; + } + InputAttribute attribute = new InputAttribute(attributeName, attributeName, 0, ""); //$NON-NLS-1$ + inputElement.addAttribute(attribute); + } + while (true) { + String childName = getChildNameSuggestion(inputElement); + if (childName.length() == 0) { + break; + } + InputElement childElement = new InputElement(childName, false, CustomXmlTraceDefinition.TAG_IGNORE, 0, "", null); //$NON-NLS-1$ + inputElement.addChild(childElement); + feelingLucky(childElement); + } + } + + private static class InputElementTreeNodeContentProvider implements ITreeContentProvider { + + @Override + public Object[] getElements(Object inputElement) { + CustomXmlTraceDefinition def = (CustomXmlTraceDefinition) inputElement; + if (def.rootInputElement != null) { + return new Object[] { def.rootInputElement }; + } + return new Object[0]; + } + + @Override + public Object[] getChildren(Object parentElement) { + InputElement inputElement = (InputElement) parentElement; + if (inputElement.childElements == null) { + return new InputElement[0]; + } + return inputElement.childElements.toArray(); + } + + @Override + public boolean hasChildren(Object element) { + InputElement inputElement = (InputElement) element; + return (inputElement.childElements != null && inputElement.childElements.size() > 0); + } + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + @Override + public Object getParent(Object element) { + InputElement inputElement = (InputElement) element; + return inputElement.parentElement; + } + } + + private static class InputElementTreeLabelProvider extends ColumnLabelProvider { + + @Override + public Image getImage(Object element) { + return ELEMENT_IMAGE; + } + + @Override + public String getText(Object element) { + InputElement inputElement = (InputElement) element; + return (inputElement.elementName.trim().length() == 0) ? "?" : inputElement.elementName; //$NON-NLS-1$ + } + } + + private class InputElementTreeSelectionChangedListener implements ISelectionChangedListener { + @Override + public void selectionChanged(SelectionChangedEvent event) { + if (selectedElement != null) { + selectedElement.dispose(); + } + if (!(event.getSelection().isEmpty()) && event.getSelection() instanceof IStructuredSelection) { + IStructuredSelection sel = (IStructuredSelection) event.getSelection(); + InputElement inputElement = (InputElement) sel.getFirstElement(); + selectedElement = new ElementNode(elementContainer, inputElement); + elementContainer.layout(); + elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, + elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); + container.layout(); + validate(); + updatePreviews(); + removeButton.setEnabled(true); + addChildButton.setEnabled(true); + addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addChildElement); + if (definition.rootInputElement == inputElement) { + addNextButton.setEnabled(false); + } else { + addNextButton.setEnabled(true); + } + moveUpButton.setEnabled(true); + moveDownButton.setEnabled(true); + } else { + removeButton.setEnabled(false); + if (definition.rootInputElement == null) { + addChildButton.setEnabled(true); + addChildButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addDocumentElement); + } else { + addChildButton.setEnabled(false); + } + addNextButton.setEnabled(false); + moveUpButton.setEnabled(false); + moveDownButton.setEnabled(false); + } + } + } + + @Override + public void dispose() { + if (fixedFont != null) { + fixedFont.dispose(); + fixedFont = null; + } + super.dispose(); + } + + private void loadDefinition(CustomXmlTraceDefinition def) { + categoryText.setText(def.categoryName); + logtypeText.setText(def.definitionName); + timeStampOutputFormatText.setText(def.timeStampOutputFormat); + treeViewer.setInput(def); + + if (def.rootInputElement != null) { + treeViewer.setSelection(new StructuredSelection(def.rootInputElement)); + } + } + + private String getName(InputElement inputElement) { + String name = (inputElement.elementName.trim().length() == 0) ? "?" : inputElement.elementName.trim(); //$NON-NLS-1$ + if (inputElement.parentElement == null) { + return name; + } + return getName(inputElement.parentElement) + " : " + name; //$NON-NLS-1$ + } + + private String getName(InputAttribute inputAttribute, InputElement inputElement) { + String name = (inputAttribute.attributeName.trim().length() == 0) ? "?" : inputAttribute.attributeName.trim(); //$NON-NLS-1$ + return getName(inputElement) + " : " + name; //$NON-NLS-1$ + } + + @Override + public void setVisible(boolean visible) { + if (visible) { + validate(); + updatePreviews(); + } + super.setVisible(visible); + } + + /** + * Get the global list of input names. + * + * @return The list of input names + */ + public List getInputNames() { + return getInputNames(definition.rootInputElement); + } + + /** + * Get the list of input names for a given element. + * + * @param inputElement + * The element + * @return The input names for this element + */ + public List getInputNames(InputElement inputElement) { + List inputs = new ArrayList<>(); + if (inputElement.inputName != null && !inputElement.inputName.equals(CustomXmlTraceDefinition.TAG_IGNORE)) { + String inputName = inputElement.inputName; + if (!inputs.contains(inputName)) { + inputs.add(inputName); + } + } + if (inputElement.attributes != null) { + for (InputAttribute attribute : inputElement.attributes) { + String inputName = attribute.inputName; + if (!inputs.contains(inputName)) { + inputs.add(inputName); + } + } + } + if (inputElement.childElements != null) { + for (InputElement childInputElement : inputElement.childElements) { + for (String inputName : getInputNames(childInputElement)) { + if (!inputs.contains(inputName)) { + inputs.add(inputName); + } + } + } + } + return inputs; + } + + private void removeElement() { + selectedElement.dispose(); + selectedElement = null; + elementContainer.layout(); + elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, + elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); + container.layout(); + } + + private String getSelectionText() { + InputStream inputStream = null; + if (this.selection instanceof IStructuredSelection) { + Object sel = ((IStructuredSelection) this.selection).getFirstElement(); + if (sel instanceof IFile) { + IFile file = (IFile) sel; + try { + inputStream = file.getContents(); + } catch (CoreException e) { + return ""; //$NON-NLS-1$ + } + } + } + if (inputStream != null) { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));) { + StringBuilder sb = new StringBuilder(); + String line = null; + while ((line = reader.readLine()) != null) { + sb.append(line + "\n"); //$NON-NLS-1$ + } + parseXmlInput(sb.toString()); + return sb.toString(); + } catch (IOException e) { + return ""; //$NON-NLS-1$ + } + } + return ""; //$NON-NLS-1$ + } + + private void parseXmlInput(final String string) { + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + + // The following allows xml parsing without access to the dtd + EntityResolver resolver = new EntityResolver() { + @Override + public InputSource resolveEntity(String publicId, String systemId) { + String empty = ""; //$NON-NLS-1$ + ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); + return new InputSource(bais); + } + }; + db.setEntityResolver(resolver); + + // The following catches xml parsing exceptions + db.setErrorHandler(new ErrorHandler() { + @Override + public void error(SAXParseException saxparseexception) throws SAXException { + } + + @Override + public void warning(SAXParseException saxparseexception) throws SAXException { + } + + @Override + public void fatalError(SAXParseException saxparseexception) throws SAXException { + if (string.trim().length() != 0) { + errorText.setText(saxparseexception.getMessage()); + errorText.setBackground(COLOR_LIGHT_RED); + errorText.setVisible(true); + } + throw saxparseexception; + } + }); + + errorText.setVisible(false); + Document doc = null; + doc = db.parse(new ByteArrayInputStream(string.getBytes())); + documentElement = doc.getDocumentElement(); + } catch (ParserConfigurationException e) { + Activator.getDefault().logError("Error pasing XML input string: " + string, e); //$NON-NLS-1$ + documentElement = null; + } catch (SAXException e) { + documentElement = null; + } catch (IOException e) { + Activator.getDefault().logError("Error pasing XML input string: " + string, e); //$NON-NLS-1$ + documentElement = null; + } + } + + private void initValues() { + timeStampValue = null; + timeStampFormat = null; + logEntriesCount = 0; + logEntryFound = false; + } + + private void updatePreviews() { + if (inputText == null) { + // early update during construction + return; + } + inputText.setStyleRanges(new StyleRange[] {}); + if (selectedElement == null) { + return; + } + + initValues(); + + selectedElement.updatePreview(); + + if (timeStampValue != null && timeStampFormat != null) { + try { + TmfTimestampFormat timestampFormat = new TmfTimestampFormat(timeStampFormat); + long timestamp = timestampFormat.parseValue(timeStampValue); + timestampFormat = new TmfTimestampFormat(timeStampOutputFormatText.getText().trim()); + timeStampPreviewText.setText(timestampFormat.format(timestamp)); + } catch (ParseException e) { + timeStampPreviewText.setText("*parse exception* [" + timeStampValue + "] <> [" + timeStampFormat + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } catch (IllegalArgumentException e) { + timeStampPreviewText.setText("*parse exception* [Illegal Argument]"); //$NON-NLS-1$ + } + } else { + timeStampPreviewText.setText("*no matching time stamp*"); //$NON-NLS-1$ + } + } + + private void openHelpShell(String url) { + if (helpBrowser != null && !helpBrowser.isDisposed()) { + helpBrowser.getShell().setActive(); + if (!helpBrowser.getUrl().equals(url)) { + helpBrowser.setUrl(url); + } + return; + } + final Shell helpShell = new Shell(getShell(), SWT.SHELL_TRIM); + helpShell.setLayout(new FillLayout()); + helpBrowser = new Browser(helpShell, SWT.NONE); + helpBrowser.addTitleListener(new TitleListener() { + @Override + public void changed(TitleEvent event) { + helpShell.setText(event.title); + } + }); + Rectangle r = container.getBounds(); + Point p = container.toDisplay(r.x, r.y); + Rectangle trim = helpShell.computeTrim(p.x + (r.width - 750) / 2, p.y + (r.height - 400) / 2, 750, 400); + helpShell.setBounds(trim); + helpShell.open(); + helpBrowser.setUrl(url); + } + + private class UpdateListener implements ModifyListener, SelectionListener { + + @Override + public void modifyText(ModifyEvent e) { + validate(); + updatePreviews(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + validate(); + updatePreviews(); + } + + @Override + public void widgetSelected(SelectionEvent e) { + validate(); + updatePreviews(); + } + + } + + private class ElementNode { + private final InputElement inputElement; + private final Group group; + private List attributes = new ArrayList<>(); + private List childElements = new ArrayList<>(); + private Text elementNameText; + private Composite tagComposite; + private Combo tagCombo; + private Label tagLabel; + private Text tagText; + private Combo actionCombo; + private Label previewLabel; + private Text previewText; + private Button logEntryButton; + private Label fillerLabel; + private Composite addAttributeComposite; + private Button addAttributeButton; + private Label addAttributeLabel; + + public ElementNode(Composite parent, InputElement inputElement) { + this.inputElement = inputElement; + + group = new Group(parent, SWT.NONE); + GridLayout gl = new GridLayout(2, false); + gl.marginHeight = 0; + group.setLayout(gl); + group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + group.setText(getName(inputElement)); + + Label label = new Label(group, SWT.NULL); + label.setText(Messages.CustomXmlParserInputWizardPage_elementName); + label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + + elementNameText = new Text(group, SWT.BORDER | SWT.SINGLE); + GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); + gd.widthHint = 0; + elementNameText.setLayoutData(gd); + elementNameText.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + ElementNode.this.inputElement.elementName = elementNameText.getText().trim(); + group.setText(getName(ElementNode.this.inputElement)); + } + }); + elementNameText.setText(inputElement.elementName); + elementNameText.addModifyListener(updateListener); + + if (inputElement.parentElement != null) { + previewLabel = new Label(group, SWT.NULL); + previewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + previewLabel.setText(Messages.CustomXmlParserInputWizardPage_preview); + + previewText = new Text(group, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); + gd = new GridData(SWT.FILL, SWT.CENTER, true, false); + gd.widthHint = 0; + previewText.setLayoutData(gd); + previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatchingElement); + previewText.setBackground(COLOR_WIDGET_BACKGROUND); + + logEntryButton = new Button(group, SWT.CHECK); + logEntryButton.setText(Messages.CustomXmlParserInputWizardPage_logEntry); + logEntryButton.setSelection(inputElement.logEntry); + logEntryButton.addSelectionListener(new SelectionListener() { + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + + @Override + public void widgetSelected(SelectionEvent e) { + InputElement parentElem = ElementNode.this.inputElement.parentElement; + while (parentElem != null) { + parentElem.logEntry = false; + parentElem = parentElem.parentElement; + } + } + }); + logEntryButton.addSelectionListener(updateListener); + + tagComposite = new Composite(group, SWT.FILL); + GridLayout tagLayout = new GridLayout(4, false); + tagLayout.marginWidth = 0; + tagLayout.marginHeight = 0; + tagComposite.setLayout(tagLayout); + tagComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + tagCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY); + tagCombo.setItems(new String[] { CustomXmlTraceDefinition.TAG_IGNORE, CustomTraceDefinition.TAG_TIMESTAMP, + CustomTraceDefinition.TAG_MESSAGE, CustomTraceDefinition.TAG_OTHER }); + tagCombo.setVisibleItemCount(tagCombo.getItemCount()); + tagCombo.addSelectionListener(new SelectionListener() { + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + + @Override + public void widgetSelected(SelectionEvent e) { + tagText.removeModifyListener(updateListener); + switch (tagCombo.getSelectionIndex()) { + case 0: // Ignore + tagLabel.setVisible(false); + tagText.setVisible(false); + actionCombo.setVisible(false); + break; + case 1: // Time Stamp + tagLabel.setText(Messages.CustomXmlParserInputWizardPage_format); + tagLabel.setVisible(true); + tagText.setVisible(true); + tagText.addModifyListener(updateListener); + actionCombo.setVisible(true); + break; + case 2: // Message + tagLabel.setVisible(false); + tagText.setVisible(false); + actionCombo.setVisible(true); + break; + case 3: // Other + tagLabel.setText(Messages.CustomXmlParserInputWizardPage_tagName); + tagLabel.setVisible(true); + if (tagText.getText().trim().length() == 0) { + tagText.setText(elementNameText.getText().trim()); + } + tagText.setVisible(true); + tagText.addModifyListener(updateListener); + actionCombo.setVisible(true); + break; + default: + break; + } + tagComposite.layout(); + validate(); + updatePreviews(); + } + }); + + tagLabel = new Label(tagComposite, SWT.NULL); + tagLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + + tagText = new Text(tagComposite, SWT.BORDER | SWT.SINGLE); + gd = new GridData(SWT.FILL, SWT.CENTER, true, false); + gd.widthHint = 0; + tagText.setLayoutData(gd); + + actionCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY); + actionCombo.setItems(new String[] { Messages.CustomXmlParserInputWizardPage_set, Messages.CustomXmlParserInputWizardPage_append, + Messages.CustomXmlParserInputWizardPage_appendWith }); + actionCombo.select(inputElement.inputAction); + actionCombo.addSelectionListener(updateListener); + + if (inputElement.inputName.equals(CustomXmlTraceDefinition.TAG_IGNORE)) { + tagCombo.select(0); + tagLabel.setVisible(false); + tagText.setVisible(false); + actionCombo.setVisible(false); + } else if (inputElement.inputName.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + tagCombo.select(1); + tagLabel.setText(Messages.CustomXmlParserInputWizardPage_format); + tagText.setText(inputElement.inputFormat); + tagText.addModifyListener(updateListener); + } else if (inputElement.inputName.equals(CustomTraceDefinition.TAG_MESSAGE)) { + tagCombo.select(2); + tagLabel.setVisible(false); + tagText.setVisible(false); + } else { + tagCombo.select(3); + tagLabel.setText(Messages.CustomXmlParserInputWizardPage_tagName); + tagText.setText(inputElement.inputName); + tagText.addModifyListener(updateListener); + } + } + + if (inputElement.attributes != null) { + for (InputAttribute inputAttribute : inputElement.attributes) { + Attribute attribute = new Attribute(group, this, inputAttribute, attributes.size() + 1); + attributes.add(attribute); + } + } + + createAddButton(); + } + + private void updatePreview() { + Element element = getPreviewElement(inputElement); + if (inputElement.parentElement != null) { // no preview text for + // document element + previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatchingElement); + if (element != null) { + previewText.setText(CustomXmlTrace.parseElement(element, new StringBuffer()).toString()); + if (logEntryButton.getSelection()) { + if (!logEntryFound) { + logEntryFound = true; + logEntriesCount++; + } else { + logEntryButton.setSelection(false); // remove nested + // log entry + } + } + if (tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP) && logEntriesCount <= 1) { + String value = previewText.getText().trim(); + if (value.length() != 0) { + if (actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_SET) { + timeStampValue = value; + timeStampFormat = tagText.getText().trim(); + } else if (actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_APPEND) { + if (timeStampValue != null) { + timeStampValue += value; + timeStampFormat += tagText.getText().trim(); + } else { + timeStampValue = value; + timeStampFormat = tagText.getText().trim(); + } + } else if (actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_APPEND_WITH_SEPARATOR) { + if (timeStampValue != null) { + timeStampValue += " | " + value; //$NON-NLS-1$ + timeStampFormat += " | " + tagText.getText().trim(); //$NON-NLS-1$ + } else { + timeStampValue = value; + timeStampFormat = tagText.getText().trim(); + } + } + } + } + } + } + for (Attribute attribute : attributes) { + if (element != null) { + String value = element.getAttribute(attribute.attributeNameText.getText().trim()); + if (value.length() != 0) { + attribute.previewText.setText(value); + if (attribute.tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP) && logEntriesCount <= 1) { + if (attribute.actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_SET) { + timeStampValue = value; + timeStampFormat = attribute.tagText.getText().trim(); + } else if (attribute.actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_APPEND) { + if (timeStampValue != null) { + timeStampValue += value; + timeStampFormat += attribute.tagText.getText().trim(); + } else { + timeStampValue = value; + timeStampFormat = attribute.tagText.getText().trim(); + } + } else if (attribute.actionCombo.getSelectionIndex() == CustomTraceDefinition.ACTION_APPEND_WITH_SEPARATOR) { + if (timeStampValue != null) { + timeStampValue += " | " + value; //$NON-NLS-1$ + timeStampFormat += " | " + attribute.tagText.getText().trim(); //$NON-NLS-1$ + } else { + timeStampValue = value; + timeStampFormat = attribute.tagText.getText().trim(); + } + } + } + } else { + attribute.previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatchingAttribute); + } + } else { + attribute.previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatchingElement); + } + } + for (ElementNode child : childElements) { + child.updatePreview(); + } + if (logEntryButton != null && logEntryButton.getSelection()) { + logEntryFound = false; + } + } + + private void createAddButton() { + fillerLabel = new Label(group, SWT.NONE); + + addAttributeComposite = new Composite(group, SWT.NONE); + addAttributeComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + GridLayout addAttributeLayout = new GridLayout(2, false); + addAttributeLayout.marginHeight = 0; + addAttributeLayout.marginWidth = 0; + addAttributeComposite.setLayout(addAttributeLayout); + + addAttributeButton = new Button(addAttributeComposite, SWT.PUSH); + addAttributeButton.setImage(ADD_IMAGE); + addAttributeButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_addAttribute); + addAttributeButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + removeAddButton(); + String attributeName = getAttributeNameSuggestion(inputElement); + InputAttribute inputAttribute = new InputAttribute(attributeName, attributeName, 0, ""); //$NON-NLS-1$ + attributes.add(new Attribute(group, ElementNode.this, inputAttribute, attributes.size() + 1)); + createAddButton(); + elementContainer.layout(); + elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, + elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); + group.getParent().layout(); + validate(); + updatePreviews(); + } + }); + + addAttributeLabel = new Label(addAttributeComposite, SWT.NULL); + addAttributeLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + addAttributeLabel.setText(Messages.CustomXmlParserInputWizardPage_newAttibute); + } + + private void removeAddButton() { + fillerLabel.dispose(); + addAttributeComposite.dispose(); + } + + private void removeAttribute(int attributeNumber) { + int nb = attributeNumber; + if (--nb < attributes.size()) { + attributes.remove(nb).dispose(); + for (int i = nb; i < attributes.size(); i++) { + attributes.get(i).setAttributeNumber(i + 1); + } + elementContainer.layout(); + elementScrolledComposite.setMinSize(elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, + elementContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y - 1); + group.getParent().layout(); + } + } + + private void dispose() { + group.dispose(); + } + + private void extractInputs() { + inputElement.elementName = elementNameText.getText().trim(); + if (inputElement.parentElement != null) { + inputElement.logEntry = logEntryButton.getSelection(); + if (tagCombo.getText().equals(CustomTraceDefinition.TAG_OTHER)) { + inputElement.inputName = tagText.getText().trim(); + } else { + inputElement.inputName = tagCombo.getText(); + if (tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + inputElement.inputFormat = tagText.getText().trim(); + } + } + inputElement.inputAction = actionCombo.getSelectionIndex(); + } + inputElement.attributes = new ArrayList<>(attributes.size()); + for (int i = 0; i < attributes.size(); i++) { + Attribute attribute = attributes.get(i); + InputAttribute inputAttribute = new InputAttribute(); + inputAttribute.attributeName = attribute.attributeNameText.getText().trim(); + if (attribute.tagCombo.getText().equals(CustomTraceDefinition.TAG_OTHER)) { + inputAttribute.inputName = attribute.tagText.getText().trim(); + } else { + inputAttribute.inputName = attribute.tagCombo.getText(); + if (attribute.tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + inputAttribute.inputFormat = attribute.tagText.getText().trim(); + } + } + inputAttribute.inputAction = attribute.actionCombo.getSelectionIndex(); + inputElement.addAttribute(inputAttribute); + } + } + } + + private class Attribute { + private ElementNode element; + private int attributeNumber; + + // children of parent (must be disposed) + private Composite labelComposite; + private Composite attributeComposite; + private Label filler; + private Composite tagComposite; + + // children of labelComposite + private Label attributeLabel; + + // children of attributeComposite + private Text attributeNameText; + private Text previewText; + + // children of tagComposite + private Combo tagCombo; + private Label tagLabel; + private Text tagText; + private Combo actionCombo; + + public Attribute(Composite parent, ElementNode element, InputAttribute inputAttribute, int attributeNumber) { + this.element = element; + this.attributeNumber = attributeNumber; + + labelComposite = new Composite(parent, SWT.FILL); + GridLayout labelLayout = new GridLayout(2, false); + labelLayout.marginWidth = 0; + labelLayout.marginHeight = 0; + labelComposite.setLayout(labelLayout); + labelComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + + Button deleteButton = new Button(labelComposite, SWT.PUSH); + deleteButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + deleteButton.setImage(DELETE_IMAGE); + deleteButton.setToolTipText(Messages.CustomXmlParserInputWizardPage_removeAttribute); + deleteButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + Attribute.this.element.removeAttribute(Attribute.this.attributeNumber); + validate(); + updatePreviews(); + } + }); + + attributeLabel = new Label(labelComposite, SWT.NULL); + attributeLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + attributeLabel.setText(Messages.CustomXmlParserInputWizardPage_attibute); + + attributeComposite = new Composite(parent, SWT.FILL); + GridLayout attributeLayout = new GridLayout(4, false); + attributeLayout.marginWidth = 0; + attributeLayout.marginHeight = 0; + attributeComposite.setLayout(attributeLayout); + attributeComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + Label nameLabel = new Label(attributeComposite, SWT.NONE); + nameLabel.setText(Messages.CustomXmlParserInputWizardPage_name); + + attributeNameText = new Text(attributeComposite, SWT.BORDER | SWT.SINGLE); + attributeNameText.setLayoutData(new GridData(120, SWT.DEFAULT)); + attributeNameText.setText(inputAttribute.attributeName); + attributeNameText.addModifyListener(updateListener); + + Label previewLabel = new Label(attributeComposite, SWT.NONE); + previewLabel.setText(Messages.CustomXmlParserInputWizardPage_preview); + + previewText = new Text(attributeComposite, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); + GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); + gd.widthHint = 0; + previewText.setLayoutData(gd); + previewText.setText(Messages.CustomXmlParserInputWizardPage_noMatch); + previewText.setBackground(COLOR_WIDGET_BACKGROUND); + + filler = new Label(parent, SWT.NULL); + + tagComposite = new Composite(parent, SWT.FILL); + GridLayout tagLayout = new GridLayout(4, false); + tagLayout.marginWidth = 0; + tagLayout.marginHeight = 0; + tagComposite.setLayout(tagLayout); + tagComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + tagCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY); + tagCombo.setItems(new String[] { CustomTraceDefinition.TAG_TIMESTAMP, CustomTraceDefinition.TAG_MESSAGE, + CustomTraceDefinition.TAG_OTHER }); + tagCombo.select(2); // Other + tagCombo.addSelectionListener(new SelectionListener() { + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + + @Override + public void widgetSelected(SelectionEvent e) { + tagText.removeModifyListener(updateListener); + switch (tagCombo.getSelectionIndex()) { + case 0: // Time Stamp + tagLabel.setText(Messages.CustomXmlParserInputWizardPage_format); + tagLabel.setVisible(true); + tagText.setVisible(true); + tagText.addModifyListener(updateListener); + break; + case 1: // Message + tagLabel.setVisible(false); + tagText.setVisible(false); + break; + case 2: // Other + tagLabel.setText(Messages.CustomXmlParserInputWizardPage_tagName); + tagLabel.setVisible(true); + if (tagText.getText().trim().length() == 0) { + tagText.setText(attributeNameText.getText().trim()); + } + tagText.setVisible(true); + tagText.addModifyListener(updateListener); + break; + default: + break; + } + tagComposite.layout(); + validate(); + updatePreviews(); + } + }); + + tagLabel = new Label(tagComposite, SWT.NULL); + tagLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + + tagText = new Text(tagComposite, SWT.BORDER | SWT.SINGLE); + gd = new GridData(SWT.FILL, SWT.CENTER, true, false); + gd.widthHint = 0; + tagText.setLayoutData(gd); + tagText.setText(attributeNameText.getText()); + + actionCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY); + actionCombo.setItems(new String[] { Messages.CustomXmlParserInputWizardPage_set, Messages.CustomXmlParserInputWizardPage_append, + Messages.CustomXmlParserInputWizardPage_appendWith }); + actionCombo.select(inputAttribute.inputAction); + actionCombo.addSelectionListener(updateListener); + + if (inputAttribute.inputName.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + tagCombo.select(0); + tagLabel.setText(Messages.CustomXmlParserInputWizardPage_format); + tagText.setText(inputAttribute.inputFormat); + tagText.addModifyListener(updateListener); + } else if (inputAttribute.inputName.equals(CustomTraceDefinition.TAG_MESSAGE)) { + tagCombo.select(1); + tagLabel.setVisible(false); + tagText.setVisible(false); + } else { + tagCombo.select(2); + tagLabel.setText(Messages.CustomXmlParserInputWizardPage_tagName); + tagText.setText(inputAttribute.inputName); + tagText.addModifyListener(updateListener); + } + } + + private void dispose() { + labelComposite.dispose(); + attributeComposite.dispose(); + filler.dispose(); + tagComposite.dispose(); + } + + private void setAttributeNumber(int attributeNumber) { + this.attributeNumber = attributeNumber; + labelComposite.layout(); + } + } + + private Element getPreviewElement(InputElement inputElement) { + InputElement currentElement = inputElement; + Element element = documentElement; + if (element != null) { + if (!documentElement.getNodeName().equals(definition.rootInputElement.elementName)) { + return null; + } + ArrayList elementNames = new ArrayList<>(); + while (currentElement != null) { + elementNames.add(currentElement.elementName); + currentElement = currentElement.parentElement; + } + for (int i = elementNames.size() - 1; --i >= 0;) { + NodeList childList = element.getChildNodes(); + element = null; + for (int j = 0; j < childList.getLength(); j++) { + Node child = childList.item(j); + if (child instanceof Element && child.getNodeName().equals(elementNames.get(i))) { + element = (Element) child; + break; + } + } + if (element == null) { + break; + } + } + if (element != null) { + return element; + } + } + return null; + } + + private String getChildNameSuggestion(InputElement inputElement) { + if (inputElement == null) { + if (documentElement != null) { + return documentElement.getNodeName(); + } + } else { + Element element = getPreviewElement(inputElement); + if (element != null) { + NodeList childNodes = element.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node node = childNodes.item(i); + if (node instanceof Element) { + boolean unused = true; + if (inputElement.childElements != null) { + for (InputElement child : inputElement.childElements) { + if (child.elementName.equals(node.getNodeName())) { + unused = false; + break; + } + } + } + if (unused) { + return node.getNodeName(); + } + } + } + } + } + return ""; //$NON-NLS-1$ + } + + private String getAttributeNameSuggestion(InputElement inputElement) { + Element element = getPreviewElement(inputElement); + if (element != null) { + NamedNodeMap attributeMap = element.getAttributes(); + for (int i = 0; i < attributeMap.getLength(); i++) { + Node node = attributeMap.item(i); + boolean unused = true; + if (inputElement.attributes != null) { + for (InputAttribute attribute : inputElement.attributes) { + if (attribute.attributeName.equals(node.getNodeName())) { + unused = false; + break; + } + } + } + if (unused) { + return node.getNodeName(); + } + } + } + return ""; //$NON-NLS-1$ + } + + private void validate() { + definition.categoryName = categoryText.getText().trim(); + definition.definitionName = logtypeText.getText().trim(); + definition.timeStampOutputFormat = timeStampOutputFormatText.getText().trim(); + + if (selectedElement != null) { + selectedElement.extractInputs(); + treeViewer.refresh(); + } + + List errors = new ArrayList<>(); + + if (definition.categoryName.length() == 0) { + errors.add(Messages.CustomXmlParserInputWizardPage_emptyCategoryError); + categoryText.setBackground(COLOR_LIGHT_RED); + } else if (definition.definitionName.length() == 0) { + errors.add(Messages.CustomXmlParserInputWizardPage_emptyLogTypeError); + logtypeText.setBackground(COLOR_LIGHT_RED); + } else { + categoryText.setBackground(COLOR_TEXT_BACKGROUND); + logtypeText.setBackground(COLOR_TEXT_BACKGROUND); + if (definition.categoryName.indexOf(':') != -1) { + errors.add(Messages.CustomXmlParserInputWizardPage_invalidCategoryError); + categoryText.setBackground(COLOR_LIGHT_RED); + } + if (definition.definitionName.indexOf(':') != -1) { + errors.add(Messages.CustomXmlParserInputWizardPage_invalidLogTypeError); + logtypeText.setBackground(COLOR_LIGHT_RED); + } + for (TraceTypeHelper helper : TmfTraceType.getTraceTypeHelpers()) { + if (definition.categoryName.equals(helper.getCategoryName()) && + definition.definitionName.equals(helper.getName()) && + (editDefinitionName == null || !editDefinitionName.equals(definition.definitionName)) && + (editCategoryName == null || !editCategoryName.equals(definition.categoryName))) { + errors.add(Messages.CustomXmlParserInputWizardPage_duplicatelogTypeError); + logtypeText.setBackground(COLOR_LIGHT_RED); + break; + } + } + } + + if (definition.rootInputElement == null) { + errors.add(Messages.CustomXmlParserInputWizardPage_noDocumentError); + } + + if (definition.rootInputElement != null) { + logEntryFound = false; + timeStampFound = false; + + errors.addAll(validateElement(definition.rootInputElement)); + + if ((definition.rootInputElement.attributes != null && definition.rootInputElement.attributes.size() != 0) + || (definition.rootInputElement.childElements != null && definition.rootInputElement.childElements.size() != 0) + || errors.size() == 0) { + if (!logEntryFound) { + errors.add(Messages.CustomXmlParserInputWizardPage_missingLogEntryError); + } + + if (timeStampFound) { + if (timeStampOutputFormatText.getText().trim().length() == 0) { + errors.add(Messages.CustomXmlParserInputWizardPage_missingTimestampFmtError); + timeStampOutputFormatText.setBackground(COLOR_LIGHT_RED); + } else { + try { + new TmfTimestampFormat(timeStampOutputFormatText.getText().trim()); + timeStampOutputFormatText.setBackground(COLOR_TEXT_BACKGROUND); + } catch (IllegalArgumentException e) { + errors.add(Messages.CustomXmlParserInputWizardPage_elementInvalidTimestampFmtError); + timeStampOutputFormatText.setBackground(COLOR_LIGHT_RED); + } + } + } else { + timeStampPreviewText.setText(Messages.CustomXmlParserInputWizardPage_noTimestampElementOrAttribute); + } + } + } else { + timeStampPreviewText.setText(Messages.CustomXmlParserInputWizardPage_noTimestampElementOrAttribute); + } + + if (errors.size() == 0) { + setDescription(defaultDescription); + setPageComplete(true); + } else { + setDescription(Joiner.on(' ').join(errors)); + setPageComplete(false); + } + } + + /** + * Clean up the specified XML element. + * + * @param inputElement + * The element to clean up + * @return The validated element + */ + public List validateElement(InputElement inputElement) { + List errors = new ArrayList<>(); + ElementNode elementNode = null; + if (selectedElement != null && selectedElement.inputElement.equals(inputElement)) { + elementNode = selectedElement; + } + if (inputElement == definition.rootInputElement) { + if (inputElement.elementName.length() == 0) { + errors.add(Messages.CustomXmlParserInputWizardPage_missingDocumentElementError); + if (elementNode != null) { + elementNode.elementNameText.setBackground(COLOR_LIGHT_RED); + } + } else { + if (elementNode != null) { + elementNode.elementNameText.setBackground(COLOR_TEXT_BACKGROUND); + } + } + } + if (inputElement != definition.rootInputElement) { + if (inputElement.logEntry) { + logEntryFound = true; + } + if (inputElement.inputName.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + timeStampFound = true; + if (inputElement.inputFormat.length() == 0) { + errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_elementMissingTimestampFmtError, getName(inputElement))); + if (elementNode != null) { + elementNode.tagText.setBackground(COLOR_LIGHT_RED); + } + } else { + try { + new TmfTimestampFormat(inputElement.inputFormat); + if (elementNode != null) { + elementNode.tagText.setBackground(COLOR_TEXT_BACKGROUND); + } + } catch (IllegalArgumentException e) { + errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_elementInvalidTimestampFmtError, getName(inputElement))); + if (elementNode != null) { + elementNode.tagText.setBackground(COLOR_LIGHT_RED); + } + } + } + } else if (inputElement.inputName.length() == 0) { + errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_elementMissingInputNameError, getName(inputElement))); + if (elementNode != null) { + elementNode.tagText.setBackground(COLOR_LIGHT_RED); + } + } else { + if (elementNode != null) { + elementNode.tagText.setBackground(COLOR_TEXT_BACKGROUND); + } + } + } + if (inputElement.attributes != null) { + if (elementNode != null) { + for (Attribute attribute : elementNode.attributes) { + attribute.attributeNameText.setBackground(COLOR_TEXT_BACKGROUND); + } + } + for (int i = 0; i < inputElement.attributes.size(); i++) { + InputAttribute attribute = inputElement.attributes.get(i); + boolean duplicate = false; + for (int j = i + 1; j < inputElement.attributes.size(); j++) { + InputAttribute otherAttribute = inputElement.attributes.get(j); + if (otherAttribute.attributeName.equals(attribute.attributeName)) { + duplicate = true; + if (elementNode != null) { + elementNode.attributes.get(j).attributeNameText.setBackground(COLOR_LIGHT_RED); + } + } + } + if (attribute.attributeName.length() == 0) { + errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_attributeMissingNameError, getName(inputElement))); + if (elementNode != null) { + elementNode.attributes.get(i).attributeNameText.setBackground(COLOR_LIGHT_RED); + } + } else if (duplicate) { + errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_attributeDuplicateNameError, getName(attribute, inputElement))); + if (elementNode != null) { + elementNode.attributes.get(i).attributeNameText.setBackground(COLOR_LIGHT_RED); + } + } + if (attribute.inputName.equals(CustomTraceDefinition.TAG_TIMESTAMP)) { + timeStampFound = true; + if (attribute.inputFormat.length() == 0) { + errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_attributeMissingTimestampFmtError, getName(attribute, inputElement))); + if (elementNode != null) { + elementNode.attributes.get(i).tagText.setBackground(COLOR_LIGHT_RED); + } + } else { + try { + new TmfTimestampFormat(attribute.inputFormat); + if (elementNode != null) { + elementNode.attributes.get(i).tagText.setBackground(COLOR_TEXT_BACKGROUND); + } + } catch (IllegalArgumentException e) { + errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_attributeInvalidTimestampFmtError, getName(attribute, inputElement))); + if (elementNode != null) { + elementNode.attributes.get(i).tagText.setBackground(COLOR_LIGHT_RED); + } + } + } + } else if (attribute.inputName.length() == 0) { + errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_attributeMissingInputNameError, getName(attribute, inputElement))); + if (elementNode != null) { + elementNode.attributes.get(i).tagText.setBackground(COLOR_LIGHT_RED); + } + } else { + if (elementNode != null) { + elementNode.attributes.get(i).tagText.setBackground(COLOR_TEXT_BACKGROUND); + } + } + } + } + if (inputElement.childElements != null) { + for (InputElement child : inputElement.childElements) { + ElementNode childElementNode = null; + if (selectedElement != null && selectedElement.inputElement.equals(child)) { + childElementNode = selectedElement; + } + if (childElementNode != null) { + childElementNode.elementNameText.setBackground(COLOR_TEXT_BACKGROUND); + } + } + for (int i = 0; i < inputElement.childElements.size(); i++) { + InputElement child = inputElement.childElements.get(i); + ElementNode childElementNode = null; + if (selectedElement != null && selectedElement.inputElement.equals(child)) { + childElementNode = selectedElement; + } + if (child.elementName.length() == 0) { + errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_elementMissingNameError, getName(child))); + if (childElementNode != null) { + childElementNode.elementNameText.setBackground(COLOR_LIGHT_RED); + } + } else { + boolean duplicate = false; + for (int j = i + 1; j < inputElement.childElements.size(); j++) { + InputElement otherChild = inputElement.childElements.get(j); + if (otherChild.elementName.equals(child.elementName)) { + duplicate = true; + ElementNode otherChildElementNode = null; + if (selectedElement != null && selectedElement.inputElement.equals(otherChild)) { + otherChildElementNode = selectedElement; + } + if (otherChildElementNode != null) { + otherChildElementNode.elementNameText.setBackground(COLOR_LIGHT_RED); + } + } + } + if (duplicate) { + errors.add(NLS.bind(Messages.CustomXmlParserInputWizardPage_elementDuplicateNameError, getName(child))); + if (childElementNode != null) { + childElementNode.elementNameText.setBackground(COLOR_LIGHT_RED); + } + } + } + + errors.addAll(validateElement(child)); + } + } + return errors; + } + + /** + * Get the trace definition. + * + * @return The trace definition + */ + public CustomXmlTraceDefinition getDefinition() { + return definition; + } + + /** + * Get the raw text input. + * + * @return The raw text input. + */ + public char[] getInputText() { + return inputText.getText().toCharArray(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomXmlParserOutputWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomXmlParserOutputWizardPage.java new file mode 100644 index 0000000000..653f904517 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomXmlParserOutputWizardPage.java @@ -0,0 +1,341 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.parsers.wizards; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.internal.tmf.ui.parsers.custom.CustomEventTableColumns; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTrace; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition.OutputColumn; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer; +import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer; +import org.eclipse.tracecompass.tmf.ui.viewers.events.TmfEventsTable; + +/** + * Output wizard page for custom XML trace parsers. + * + * @author Patrick Tasse + */ +public class CustomXmlParserOutputWizardPage extends WizardPage { + + private static final Image UP_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/up_button.gif"); //$NON-NLS-1$ + private static final Image DOWN_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/down_button.gif"); //$NON-NLS-1$ + private final CustomXmlParserWizard wizard; + private CustomXmlTraceDefinition definition; + private List outputs = new ArrayList<>(); + private Composite container; + private SashForm sash; + private ScrolledComposite outputsScrolledComposite; + private Composite outputsContainer; + private Composite tableContainer; + private TmfEventsTable previewTable; + private File tmpFile; + + /** + * Constructor + * + * @param wizard + * The wizard to which this page belongs + */ + protected CustomXmlParserOutputWizardPage(final CustomXmlParserWizard wizard) { + super("CustomParserOutputWizardPage"); //$NON-NLS-1$ + setTitle(wizard.inputPage.getTitle()); + setDescription(Messages.CustomXmlParserOutputWizardPage_description); + this.wizard = wizard; + setPageComplete(false); + } + + @Override + public void createControl(final Composite parent) { + container = new Composite(parent, SWT.NULL); + container.setLayout(new GridLayout()); + + sash = new SashForm(container, SWT.VERTICAL); + sash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + sash.setBackground(sash.getDisplay().getSystemColor(SWT.COLOR_GRAY)); + + outputsScrolledComposite = new ScrolledComposite(sash, SWT.V_SCROLL); + outputsScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + outputsContainer = new Composite(outputsScrolledComposite, SWT.NONE); + final GridLayout outputsLayout = new GridLayout(4, false); + outputsLayout.marginHeight = 10; + outputsLayout.marginWidth = 0; + outputsContainer.setLayout(outputsLayout); + outputsScrolledComposite.setContent(outputsContainer); + outputsScrolledComposite.setExpandHorizontal(true); + outputsScrolledComposite.setExpandVertical(true); + + outputsContainer.layout(); + + outputsScrolledComposite.setMinSize(outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-5); + + tableContainer = new Composite(sash, SWT.NONE); + final GridLayout tableLayout = new GridLayout(); + tableLayout.marginHeight = 0; + tableLayout.marginWidth = 0; + tableContainer.setLayout(tableLayout); + previewTable = new TmfEventsTable(tableContainer, 0, CustomEventTableColumns.generateColumns(new CustomXmlTraceDefinition())); + previewTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + if (wizard.definition != null) { + loadDefinition(wizard.definition); + } + setControl(container); + + } + + @Override + public void dispose() { + previewTable.dispose(); + super.dispose(); + } + + private void loadDefinition(final CustomTraceDefinition def) { + for (final OutputColumn outputColumn : def.outputs) { + final Output output = new Output(outputsContainer, outputColumn.name); + outputs.add(output); + } + } + + @Override + public void setVisible(final boolean visible) { + if (visible) { + this.definition = wizard.inputPage.getDefinition(); + final List outputNames = wizard.inputPage.getInputNames(); + + // dispose outputs that have been removed in the input page + final Iterator iter = outputs.iterator(); + while (iter.hasNext()) { + final Output output = iter.next(); + boolean found = false; + for (final String name : outputNames) { + if (output.name.equals(name)) { + found = true; + break; + } + } + if (!found) { + output.dispose(); + iter.remove(); + } + } + + // create outputs that have been added in the input page + for (final String name : outputNames) { + boolean found = false; + for (final Output output : outputs) { + if (output.name.equals(name)) { + found = true; + break; + } + } + if (!found) { + outputs.add(new Output(outputsContainer, name)); + } + } + + outputsContainer.layout(); + outputsScrolledComposite.setMinSize(outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-5); + updatePreviewTable(); + if (sash.getSize().y > outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y + previewTable.getTable().getItemHeight()) { + sash.setWeights(new int[] {outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, sash.getSize().y - outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y}); + } else { + sash.setWeights(new int[] {outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, previewTable.getTable().getItemHeight()}); + } + setPageComplete(true); + } else { + setPageComplete(false); + } + super.setVisible(visible); + } + + private void moveBefore(final Output moved) { + final int i = outputs.indexOf(moved); + if (i > 0) { + final Output previous = outputs.get(i-1); + moved.enabledButton.moveAbove(previous.enabledButton); + moved.nameLabel.moveBelow(moved.enabledButton); + moved.upButton.moveBelow(moved.nameLabel); + moved.downButton.moveBelow(moved.upButton); + outputs.add(i-1, outputs.remove(i)); + outputsContainer.layout(); + outputsScrolledComposite.setMinSize(outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-5); + container.layout(); + updatePreviewTable(); + } + } + + private void moveAfter(final Output moved) { + final int i = outputs.indexOf(moved); + if (i+1 < outputs.size()) { + final Output next = outputs.get(i+1); + moved.enabledButton.moveBelow(next.downButton); + moved.nameLabel.moveBelow(moved.enabledButton); + moved.upButton.moveBelow(moved.nameLabel); + moved.downButton.moveBelow(moved.upButton); + outputs.add(i+1, outputs.remove(i)); + outputsContainer.layout(); + outputsScrolledComposite.setMinSize(outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, outputsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-5); + container.layout(); + updatePreviewTable(); + } + } + + private void updatePreviewTable() { + final int CACHE_SIZE = 50; + definition.outputs = extractOutputs(); + tmpFile = Activator.getDefault().getStateLocation().addTrailingSeparator().append("customwizard.tmp").toFile(); //$NON-NLS-1$ + + try (final FileWriter writer = new FileWriter(tmpFile);) { + writer.write(wizard.inputPage.getInputText()); + } catch (final IOException e) { + Activator.getDefault().logError("Error creating CustomXmlTrace. File:" + tmpFile.getAbsolutePath(), e); //$NON-NLS-1$ + } + + try { + final CustomXmlTrace trace = new CustomXmlTrace(null, definition, tmpFile.getAbsolutePath(), CACHE_SIZE) { + @Override + protected ITmfTraceIndexer createIndexer(int interval) { + return new TmfCheckpointIndexer(this, interval); + } + }; + trace.getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, false); + previewTable.dispose(); + previewTable = new TmfEventsTable(tableContainer, CACHE_SIZE, CustomEventTableColumns.generateColumns(definition)); + previewTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + previewTable.setTrace(trace, true); + } catch (final TmfTraceException e) { + Activator.getDefault().logError("Error creating CustomXmlTrace. File:" + tmpFile.getAbsolutePath(), e); //$NON-NLS-1$ + } + + tableContainer.layout(); + container.layout(); + } + + /** + * Extract the output columns from the page's current contents. + * + * @return The list of output columns + */ + public List extractOutputs() { + int numColumns = 0; + for (int i = 0; i < outputs.size(); i++) { + if (outputs.get(i).enabledButton.getSelection()) { + numColumns++; + } + } + final List outputColumns = new ArrayList<>(numColumns); + numColumns = 0; + for (int i = 0; i < outputs.size(); i++) { + final Output output = outputs.get(i); + if (output.enabledButton.getSelection()) { + final OutputColumn column = new OutputColumn(); + column.name = output.nameLabel.getText(); + outputColumns.add(column); + } + } + return outputColumns; + } + + private class Output { + String name; + Button enabledButton; + Text nameLabel; + Button upButton; + Button downButton; + + public Output(final Composite parent, final String name) { + this.name = name; + + enabledButton = new Button(parent, SWT.CHECK); + enabledButton.setToolTipText(Messages.CustomXmlParserOutputWizardPage_visible); + enabledButton.setSelection(true); + enabledButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + updatePreviewTable(); + } + }); + // if (messageOutput != null) { + // enabledButton.moveAbove(messageOutput.enabledButton); + // } + + nameLabel = new Text(parent, SWT.BORDER | SWT.READ_ONLY | SWT.SINGLE); + nameLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + nameLabel.setText(name); + nameLabel.moveBelow(enabledButton); + + upButton = new Button(parent, SWT.PUSH); + upButton.setImage(UP_IMAGE); + upButton.setToolTipText(Messages.CustomXmlParserOutputWizardPage_moveBefore); + upButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + moveBefore(Output.this); + } + }); + upButton.moveBelow(nameLabel); + + downButton = new Button(parent, SWT.PUSH); + downButton.setImage(DOWN_IMAGE); + downButton.setToolTipText(Messages.CustomXmlParserOutputWizardPage_moveAfter); + downButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + moveAfter(Output.this); + } + }); + downButton.moveBelow(upButton); + } + + private void dispose() { + enabledButton.dispose(); + nameLabel.dispose(); + upButton.dispose(); + downButton.dispose(); + } + } + + /** + * Get the trace definition. + * + * @return The trace definition + */ + public CustomXmlTraceDefinition getDefinition() { + return definition; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomXmlParserWizard.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomXmlParserWizard.java new file mode 100644 index 0000000000..8edbc95396 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/wizards/CustomXmlParserWizard.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.parsers.wizards; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition; +import org.eclipse.ui.INewWizard; +import org.eclipse.ui.IWorkbench; + +/** + * Wizard for custom XML trace parsers. + * + * @author Patrick Tasse + */ +public class CustomXmlParserWizard extends Wizard implements INewWizard { + + CustomXmlParserInputWizardPage inputPage; + CustomXmlParserOutputWizardPage outputPage; + private ISelection selection; + CustomXmlTraceDefinition definition; + String initialCategoryName; + String initialDefinitionName; + + /** + * Default constructor + */ + public CustomXmlParserWizard() { + super(); + } + + /** + * Constructor + * + * @param definition + * The trace definition + */ + public CustomXmlParserWizard(CustomXmlTraceDefinition definition) { + super(); + this.definition = definition; + if (definition != null) { + initialCategoryName = definition.categoryName; + initialDefinitionName = definition.definitionName; + } + } + + @Override + public boolean performFinish() { + CustomXmlTraceDefinition def = outputPage.getDefinition(); + if (definition != null && (!initialCategoryName.equals(def.categoryName) || + !initialDefinitionName.equals(def.definitionName))) { + CustomXmlTraceDefinition.delete(initialCategoryName, initialDefinitionName); + } + def.save(); + return true; + } + + /** + * Adding the page to the wizard. + */ + + @Override + public void addPages() { + inputPage = new CustomXmlParserInputWizardPage(selection, definition); + addPage(inputPage); + outputPage = new CustomXmlParserOutputWizardPage(this); + addPage(outputPage); + } + + @Override + public void init(IWorkbench workbench, IStructuredSelection sel) { + this.selection = sel; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/preferences/TmfTracingPreferencePage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/preferences/TmfTracingPreferencePage.java new file mode 100644 index 0000000000..3e927d8b54 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/preferences/TmfTracingPreferencePage.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + ******************************************************************************/ +package org.eclipse.tracecompass.internal.tmf.ui.preferences; + +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +/** + * Top Level Preference Page for Tracing. + * + * @version 1.0 + * @author Bernd Hufmann + */ +public class TmfTracingPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Override + protected Control createContents(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + // No content yet! + return composite; + } + + @Override + public void init(IWorkbench workbench) { + // Nothing to do yet! + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/Messages.java new file mode 100644 index 0000000000..0c4a9641bd --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/Messages.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Marc-Andre Laperle - Add select/deselect all + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.dialogs; + +import org.eclipse.osgi.util.NLS; + +/** + * Message bundle for dialog messages. + */ +@SuppressWarnings("javadoc") +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.tmf.ui.project.dialogs.messages"; //$NON-NLS-1$ + + public static String SelectSpplementaryResources_DialogTitle; + public static String SelectSpplementaryResources_ResourcesGroupTitle; + public static String Dialog_SelectAll; + public static String Dialog_DeselectAll; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/SelectSupplementaryResourcesDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/SelectSupplementaryResourcesDialog.java new file mode 100644 index 0000000000..f63145aeaa --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/SelectSupplementaryResourcesDialog.java @@ -0,0 +1,324 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Copied and adapted from NewFolderDialog + * Marc-Andre Laperle - Add select/deselect all + * Patrick Tasse - Add support for folder elements + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.dialogs; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map.Entry; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTreeViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfCommonProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +import com.google.common.collect.Multimap; + +/** + * SelectSupplementaryResourcesDialog + */ +public class SelectSupplementaryResourcesDialog extends Dialog { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + private static final Image EXPERIMENT_IMAGE = Activator.getDefault().getImageFromPath("icons/elcl16/experiment.gif"); //$NON-NLS-1$ + private static final Image TRACE_IMAGE = Activator.getDefault().getImageFromPath("icons/elcl16/trace.gif"); //$NON-NLS-1$ + private static final Image RESOURCE_IMAGE = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE); + + // ------------------------------------------------------------------------ + // Members + // ------------------------------------------------------------------------ + private CheckboxTreeViewer fTreeViewer; + private final Multimap fResourceMap; + private IResource[] fReturnedResources; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Constructor. + * + * @param shell + * Parent shell of this dialog + * @param resourceMap + * Map of element to supplementary resources + */ + public SelectSupplementaryResourcesDialog(Shell shell, Multimap resourceMap) { + super(shell); + fResourceMap = resourceMap; + setShellStyle(SWT.RESIZE | getShellStyle()); + } + + // ------------------------------------------------------------------------ + // Getters/Setters + // ------------------------------------------------------------------------ + + /** + * @return A copy of the selected resources + */ + public IResource[] getResources() { + return Arrays.copyOf(fReturnedResources, fReturnedResources.length); + } + + // ------------------------------------------------------------------------ + // Dialog + // ------------------------------------------------------------------------ + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(Messages.SelectSpplementaryResources_DialogTitle); + newShell.setImage(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_ETOOL_DELETE)); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + composite.setLayout(new GridLayout()); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + Group contextGroup = new Group(composite, SWT.SHADOW_NONE); + contextGroup.setText(Messages.SelectSpplementaryResources_ResourcesGroupTitle); + contextGroup.setLayout(new GridLayout(2, false)); + contextGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); + + fTreeViewer = new CheckboxTreeViewer(contextGroup, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + GridData data = new GridData(GridData.FILL_BOTH); + Tree tree = fTreeViewer.getTree(); + tree.setLayoutData(data); + fTreeViewer.setContentProvider(new ITreeContentProvider() { + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + @Override + public void dispose() { + } + + @Override + public boolean hasChildren(Object element) { + return element instanceof TmfCommonProjectElement; + } + + @Override + public Object getParent(Object element) { + if (element instanceof IResource) { + getParentElement((IResource) element); + } + return null; + } + + @Override + public Object[] getElements(Object inputElement) { + if (inputElement instanceof Object[]) { + return (Object[]) inputElement; + } + return null; + } + + @Override + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof TmfCommonProjectElement) { + return fResourceMap.get((TmfCommonProjectElement) parentElement).toArray(); + } + return null; + } + }); + + fTreeViewer.setLabelProvider(new LabelProvider() { + @Override + public String getText(Object element) { + if (element instanceof IResource) { + IResource resource = (IResource) element; + TmfCommonProjectElement projectElement = getParentElement(resource); + // remove .tracing/ segments + IPath suppFolderPath = projectElement.getTraceSupplementaryFolder(projectElement.getElementPath()).getFullPath(); + return resource.getFullPath().removeFirstSegments(suppFolderPath.segmentCount()).toString(); + } else if (element instanceof TmfCommonProjectElement) { + TmfCommonProjectElement projectElement = (TmfCommonProjectElement) element; + return projectElement.getElementPath(); + } + return super.getText(element); + } + + @Override + public Image getImage(Object element) { + if (element instanceof IResource) { + return RESOURCE_IMAGE; + } else if (element instanceof TmfTraceElement) { + return TRACE_IMAGE; + } else if (element instanceof TmfExperimentElement) { + return EXPERIMENT_IMAGE; + } + return null; + } + + }); + + fTreeViewer.setInput(fResourceMap.keySet().toArray()); + + fTreeViewer.expandAll(); + setAllChecked(true); + + fTreeViewer.addCheckStateListener(new ICheckStateListener() { + @Override + public void checkStateChanged(CheckStateChangedEvent event) { + if (event.getElement() instanceof TmfCommonProjectElement) { + fTreeViewer.setSubtreeChecked(event.getElement(), event.getChecked()); + fTreeViewer.setGrayed(event.getElement(), false); + } else if (event.getElement() instanceof IResource) { + TmfCommonProjectElement projectElement = getParentElement((IResource) event.getElement()); + int checkedCount = 0; + Collection resources = fResourceMap.get(projectElement); + for (IResource resource : resources) { + if (fTreeViewer.getChecked(resource)) { + checkedCount++; + } + } + if (checkedCount == resources.size()) { + fTreeViewer.setChecked(projectElement, true); + fTreeViewer.setGrayed(projectElement, false); + } else if (checkedCount > 0) { + fTreeViewer.setGrayChecked(projectElement, true); + } else { + fTreeViewer.setGrayChecked(projectElement, false); + } + } + } + }); + + fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + updateOKButtonEnablement(); + } + }); + + Composite btComp = new Composite(contextGroup, SWT.NONE); + FillLayout layout = new FillLayout(SWT.VERTICAL); + layout.spacing = 4; + btComp.setLayout(layout); + + GridData gd = new GridData(); + gd.verticalAlignment = SWT.CENTER; + btComp.setLayoutData(gd); + + final Button selectAll = new Button(btComp, SWT.PUSH); + selectAll.setText(Messages.Dialog_SelectAll); + selectAll.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + setAllChecked(true); + + updateOKButtonEnablement(); + } + }); + + final Button deselectAll = new Button(btComp, SWT.PUSH); + deselectAll.setText(Messages.Dialog_DeselectAll); + deselectAll.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + setAllChecked(false); + + updateOKButtonEnablement(); + } + }); + + getShell().setMinimumSize(new Point(300, 150)); + + return composite; + } + + private TmfCommonProjectElement getParentElement(IResource resource) { + for (Entry entry : fResourceMap.entries()) { + if (entry.getValue().equals(resource)) { + return entry.getKey(); + } + } + return null; + } + + private void setAllChecked(boolean state) { + for (Object element : fResourceMap.keySet()) { + fTreeViewer.setSubtreeChecked(element, state); + fTreeViewer.setGrayed(element, false); + } + } + + private void updateOKButtonEnablement() { + Object[] checked = fTreeViewer.getCheckedElements(); + getButton(IDialogConstants.OK_ID).setEnabled(checked.length > 0); + } + + @Override + protected Control createButtonBar(Composite parent) { + Control control = super.createButtonBar(parent); + updateOKButtonEnablement(); + return control; + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, true); + createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); + } + + @Override + protected void okPressed() { + Object[] checkedElements = fTreeViewer.getCheckedElements(); + List checkedResources = new ArrayList<>(checkedElements.length); + for (Object checked : checkedElements) { + if (checked instanceof IResource) { + checkedResources.add((IResource) checked); + } + } + fReturnedResources = checkedResources.toArray(new IResource[0]); + super.okPressed(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/messages.properties new file mode 100644 index 0000000000..476306e1fd --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/messages.properties @@ -0,0 +1,16 @@ +############################################################################### +# Copyright (c) 2012, 2013 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Bernd Hufmann - initial API and implementation +# Marc-Andre Laperle - Add select/deselect all +############################################################################### +SelectSpplementaryResources_DialogTitle=Delete Resources +SelectSpplementaryResources_ResourcesGroupTitle=Select resources to delete +Dialog_SelectAll=Select All +Dialog_DeselectAll=Deselect All \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/offset/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/offset/Messages.java new file mode 100644 index 0000000000..b4a5524e1d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/offset/Messages.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.dialogs.offset; + +import org.eclipse.osgi.util.NLS; + +/** + * Messages for the offset dialog + */ +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.tmf.ui.project.dialogs.offset.messages"; //$NON-NLS-1$ + + /** + * Advanced mode button + */ + public static String OffsetDialog_AdvancedButton; + /** + * Advanced mode dialog message + */ + public static String OffsetDialog_AdvancedMessage; + /** + * Basic mode button + */ + public static String OffsetDialog_BasicButton; + /** + * Basic mode dialog message + */ + public static String OffsetDialog_BasicMessage; + /** + * Offset time + */ + public static String OffsetDialog_OffsetTime; + /** + * Reference time + */ + public static String OffsetDialog_ReferenceTime; + /** + * Target time + */ + public static String OffsetDialog_TargetTime; + /** + * Dialog title + */ + public static String OffsetDialog_Title; + /** + * Trace name + */ + public static String OffsetDialog_TraceName; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/offset/OffsetDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/offset/OffsetDialog.java new file mode 100644 index 0000000000..78564a2ded --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/offset/OffsetDialog.java @@ -0,0 +1,578 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.dialogs.offset; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ColumnViewer; +import org.eclipse.jface.viewers.ColumnViewerEditor; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.jface.viewers.TreeViewerEditor; +import org.eclipse.jface.viewers.TreeViewerFocusCellManager; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.TreeEditor; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.tracecompass.tmf.core.signal.TmfEventSelectedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfOpenTraceHelper; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.viewers.ArrayTreeContentProvider; +import org.eclipse.ui.dialogs.FilteredTree; +import org.eclipse.ui.dialogs.PatternFilter; + +/** + * Offset wizard dialog + * + * @author Matthew Khouzam + * + */ +public class OffsetDialog extends Dialog { + + private static final int TREE_EDITOR_MIN_WIDTH = 50; + private static final String EDITOR_KEY = "$editor$"; //$NON-NLS-1$ + private static final String WIDTH_KEY = "$width$"; //$NON-NLS-1$ + + private static final TmfTimestampFormat TIME_FORMAT = new TmfTimestampFormat("yyyy-MM-dd HH:mm:ss.SSS SSS SSS"); //$NON-NLS-1$ + private static final TmfTimestampFormat OFFSET_FORMAT = new TmfTimestampFormat("T.SSS SSS SSS"); //$NON-NLS-1$ + + private final Map fOffsetMap; + private final Map fRefTimeMap; + private final Map fTargetTimeMap; + + private Label fBasicMessageLabel; + private Group fButtonGroup; + private Label fAdvancedMessageLabel; + private FilteredTree fViewer; + + private boolean fAdvancedMode = true; + private TreeColumn fRefTimeColumn; + private TreeViewerColumn fButtonViewerColumn; + private TreeColumn fTargetTimeColumn; + + private abstract class ColumnEditingSupport extends EditingSupport { + private final TextCellEditor textCellEditor; + + private ColumnEditingSupport(ColumnViewer viewer, TextCellEditor textCellEditor) { + super(viewer); + this.textCellEditor = textCellEditor; + } + + @Override + protected CellEditor getCellEditor(Object element) { + return textCellEditor; + } + + @Override + protected boolean canEdit(Object element) { + return true; + } + } + + private class TimeEditingSupport extends ColumnEditingSupport { + private Map map; + + private TimeEditingSupport(ColumnViewer viewer, TextCellEditor textCellEditor, Map map) { + super(viewer, textCellEditor); + this.map = map; + } + + @Override + protected void setValue(Object element, Object value) { + if (value instanceof String) { + String string = (String) value; + if (string.trim().isEmpty()) { + map.remove(element); + } else { + try { + ITmfTimestamp refTime = map.get(element); + long ref = refTime == null ? 0 : refTime.normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + Long newVal = TIME_FORMAT.parseValue(string, ref); + map.put((TmfTraceElement) element, new TmfNanoTimestamp(newVal)); + } catch (ParseException e) { + /* Ignore and reload previous value */ + } + } + fViewer.getViewer().update(element, null); + } + } + + @Override + protected Object getValue(Object element) { + if (map.get(element) == null) { + return ""; //$NON-NLS-1$ + } + return TIME_FORMAT.format(map.get(element).normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue()); + } + } + + private class RefTimeEditingSupport extends TimeEditingSupport { + private RefTimeEditingSupport(ColumnViewer viewer, TextCellEditor textCellEditor) { + super(viewer, textCellEditor, fRefTimeMap); + } + } + + private class TargetTimeEditingSupport extends TimeEditingSupport { + private TargetTimeEditingSupport(ColumnViewer viewer, TextCellEditor textCellEditor) { + super(viewer, textCellEditor, fTargetTimeMap); + } + } + + private class OffsetEditingSupport extends ColumnEditingSupport { + private OffsetEditingSupport(ColumnViewer viewer, TextCellEditor textCellEditor) { + super(viewer, textCellEditor); + } + + @Override + protected void setValue(Object element, Object value) { + if (value instanceof String) { + String string = (String) value; + if (string.trim().isEmpty()) { + fOffsetMap.put((TmfTraceElement) element, 0L); + } else { + try { + Long newVal = OFFSET_FORMAT.parseValue(string); + fOffsetMap.put((TmfTraceElement) element, newVal); + } catch (ParseException e) { + /* Ignore and reload previous value */ + } + } + fViewer.getViewer().update(element, null); + } + } + + @Override + protected Object getValue(Object element) { + if (fOffsetMap.get(element) == 0) { + return ""; //$NON-NLS-1$ + } + return OFFSET_FORMAT.format((long) fOffsetMap.get(element)); + } + } + + /** + * Constructor + * + * @param parent + * parent shell + * @param results + * results to put the data into + */ + public OffsetDialog(Shell parent, Map results) { + super(parent); + setShellStyle(getShellStyle() & ~SWT.APPLICATION_MODAL); + fOffsetMap = results; + fRefTimeMap = new HashMap<>(); + fTargetTimeMap = new HashMap<>(); + } + + @Override + protected boolean isResizable() { + return true; + } + + @Override + protected Control createDialogArea(Composite parent) { + getShell().setText(Messages.OffsetDialog_Title); + Composite area = (Composite) super.createDialogArea(parent); + Composite composite = new Composite(area, SWT.NONE); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + GridLayout gl = new GridLayout(); + gl.marginHeight = 0; + gl.marginWidth = 0; + composite.setLayout(new GridLayout()); + createBasicMessage(composite); + createButtonGroup(composite); + createAdvancedMessage(composite); + createViewer(composite); + + /* set label width hint equal to tree width */ + int widthHint = fViewer.getViewer().getTree().computeSize(SWT.DEFAULT, SWT.DEFAULT).x; + GridData gd = (GridData) fBasicMessageLabel.getLayoutData(); + gd.widthHint = widthHint; + gd = (GridData) fAdvancedMessageLabel.getLayoutData(); + gd.widthHint = widthHint; + gd = (GridData) composite.getLayoutData(); + gd.heightHint = composite.computeSize(widthHint, SWT.DEFAULT).y; + setBasicMode(); + + TmfSignalManager.register(this); + composite.addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent e) { + TmfSignalManager.deregister(this); + } + }); + return area; + } + + private void createBasicMessage(final Composite parent) { + fBasicMessageLabel = new Label(parent, SWT.WRAP); + fBasicMessageLabel.setText(Messages.OffsetDialog_BasicMessage); + GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); + gd.widthHint = 0; + gd.heightHint = SWT.DEFAULT; + fBasicMessageLabel.setLayoutData(gd); + } + + private void createButtonGroup(final Composite parent) { + fButtonGroup = new Group(parent, SWT.SHADOW_NONE); + fButtonGroup.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + fButtonGroup.setLayout(new RowLayout(SWT.HORIZONTAL)); + + final Button basicButton = new Button(fButtonGroup, SWT.RADIO); + basicButton.setText(Messages.OffsetDialog_BasicButton); + basicButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (!basicButton.getSelection() || !fAdvancedMode) { + return; + } + setBasicMode(); + parent.layout(); + } + }); + basicButton.setSelection(true); + + final Button advancedButton = new Button(fButtonGroup, SWT.RADIO); + advancedButton.setText(Messages.OffsetDialog_AdvancedButton); + advancedButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (!advancedButton.getSelection() || fAdvancedMode) { + return; + } + setAdvancedMode(); + parent.layout(); + } + }); + } + + private void createAdvancedMessage(final Composite parent) { + fAdvancedMessageLabel = new Label(parent, SWT.WRAP); + fAdvancedMessageLabel.setText(Messages.OffsetDialog_AdvancedMessage); + GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); + gd.widthHint = 0; + gd.heightHint = SWT.DEFAULT; + fAdvancedMessageLabel.setLayoutData(gd); + } + + private void createViewer(Composite parent) { + + // Define the TableViewer + fViewer = new FilteredTree(parent, SWT.MULTI | SWT.H_SCROLL + | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER, new PatternFilter() { + @Override + protected boolean isLeafMatch(Viewer viewer, Object element) { + return wordMatches(((TmfTraceElement) element).getElementPath()); + } + }, true); + + // Make lines and make header visible + final Tree tree = fViewer.getViewer().getTree(); + tree.setHeaderVisible(true); + tree.setLinesVisible(true); + + TreeViewerFocusCellManager focusCellManager = new TreeViewerFocusCellManager(fViewer.getViewer(), new FocusCellOwnerDrawHighlighter(fViewer.getViewer())); + ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(fViewer.getViewer()); + TreeViewerEditor.create(fViewer.getViewer(), focusCellManager, actSupport, ColumnViewerEditor.TABBING_HORIZONTAL + | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR + | ColumnViewerEditor.TABBING_VERTICAL | ColumnViewerEditor.KEYBOARD_ACTIVATION); + + final TextCellEditor textCellEditor = new TextCellEditor(fViewer.getViewer().getTree(), SWT.RIGHT); + + fViewer.getViewer().setColumnProperties(new String[] { Messages.OffsetDialog_TraceName, Messages.OffsetDialog_ReferenceTime, Messages.OffsetDialog_OffsetTime }); + + TreeViewerColumn column = createTreeViewerColumn(Messages.OffsetDialog_TraceName, SWT.NONE); + column.setLabelProvider(new ColumnLabelProvider() { + @Override + public String getText(Object element) { + return ((TmfTraceElement) element).getElementPath(); + } + }); + + column = createTreeViewerColumn(Messages.OffsetDialog_ReferenceTime, SWT.RIGHT); + column.setLabelProvider(new ColumnLabelProvider() { + @Override + public String getText(Object element) { + return super.getText(fRefTimeMap.get(element)); + } + }); + column.setEditingSupport(new RefTimeEditingSupport(fViewer.getViewer(), textCellEditor)); + fRefTimeColumn = column.getColumn(); + + column = createTreeViewerColumn(Messages.OffsetDialog_OffsetTime, SWT.RIGHT); + column.setLabelProvider(new ColumnLabelProvider() { + @Override + public String getText(Object element) { + if (fOffsetMap.get(element) != 0) { + return super.getText(OFFSET_FORMAT.format((long) fOffsetMap.get(element))); + } + return ""; //$NON-NLS-1$ + } + }); + column.setEditingSupport(new OffsetEditingSupport(fViewer.getViewer(), textCellEditor)); + + column = createTreeViewerColumn("", SWT.NONE); //$NON-NLS-1$ + column.setLabelProvider(new ColumnLabelProvider() { + @Override + public String getText(Object element) { + return ""; //$NON-NLS-1$ + } + }); + column.getColumn().setWidth(TREE_EDITOR_MIN_WIDTH); + column.getColumn().setResizable(false); + fButtonViewerColumn = column; + + column = createTreeViewerColumn(Messages.OffsetDialog_TargetTime, SWT.RIGHT); + column.setLabelProvider(new ColumnLabelProvider() { + @Override + public String getText(Object element) { + return super.getText(fTargetTimeMap.get(element)); + } + }); + column.setEditingSupport(new TargetTimeEditingSupport(fViewer.getViewer(), textCellEditor)); + fTargetTimeColumn = column.getColumn(); + + List traces = new ArrayList<>(fOffsetMap.keySet()); + Collections.sort(traces, new Comparator() { + @Override + public int compare(TmfTraceElement o1, TmfTraceElement o2) { + IPath folder1 = new Path(o1.getElementPath()).removeLastSegments(1); + IPath folder2 = new Path(o2.getElementPath()).removeLastSegments(1); + if (folder1.equals(folder2)) { + return o1.getName().compareToIgnoreCase(o2.getName()); + } + if (folder1.isPrefixOf(folder2)) { + return 1; + } else if (folder2.isPrefixOf(folder1)) { + return -1; + } + return folder1.toString().compareToIgnoreCase(folder2.toString()); + } + }); + + fViewer.getViewer().setContentProvider(new ArrayTreeContentProvider()); + fViewer.getViewer().setInput(traces); + + /* add button as tree editors to fourth column of every item */ + for (TreeItem treeItem : tree.getItems()) { + TreeEditor treeEditor = new TreeEditor(tree); + Button applyButton = new Button(tree, SWT.PUSH); + applyButton.setText("<<"); //$NON-NLS-1$ + applyButton.setData(treeItem.getData()); + applyButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + TmfTraceElement traceElement = (TmfTraceElement) e.widget.getData(); + ITmfTimestamp targetTime = fTargetTimeMap.get(traceElement); + ITmfTimestamp refTime = fRefTimeMap.get(traceElement); + if (targetTime != null && refTime != null) { + long offset = new TmfNanoTimestamp(targetTime).getValue() - + new TmfNanoTimestamp(refTime).getValue(); + fOffsetMap.put(traceElement, offset); + fViewer.getViewer().update(traceElement, null); + } + } + }); + treeEditor.grabHorizontal = true; + treeEditor.minimumWidth = TREE_EDITOR_MIN_WIDTH; + treeEditor.setEditor(applyButton, treeItem, 3); + treeItem.setData(EDITOR_KEY, applyButton); + } + + /* put temporary values in maps to pack according to time formats */ + fRefTimeMap.put(traces.get(0), new TmfNanoTimestamp()); + fTargetTimeMap.put(traces.get(0), new TmfNanoTimestamp()); + fViewer.getViewer().update(traces.get(0), null); + for (final TreeColumn treeColumn : tree.getColumns()) { + if (treeColumn.getResizable()) { + treeColumn.pack(); + } + } + fRefTimeMap.clear(); + fTargetTimeMap.clear(); + fViewer.getViewer().update(traces.get(0), null); + + for (TmfTraceElement traceElement : fOffsetMap.keySet()) { + for (ITmfTrace parentTrace : TmfTraceManager.getInstance().getOpenedTraces()) { + for (ITmfTrace trace : TmfTraceManager.getTraceSet(parentTrace)) { + if (traceElement.getResource().equals(trace.getResource())) { + fRefTimeMap.put(traceElement, trace.getStartTime()); + fViewer.getViewer().update(traceElement, null); + break; + } + } + if (fRefTimeMap.get(traceElement) != null) { + break; + } + } + } + + /* open trace when double-clicking a tree item */ + tree.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetDefaultSelected(SelectionEvent e) { + TmfTraceElement traceElement = (TmfTraceElement) e.item.getData(); + TmfOpenTraceHelper.openTraceFromElement(traceElement); + } + }); + + tree.setFocus(); + } + + private TreeViewerColumn createTreeViewerColumn(String title, int style) { + final TreeViewerColumn viewerColumn = new TreeViewerColumn(fViewer.getViewer(), style); + final TreeColumn column = viewerColumn.getColumn(); + column.setText(title); + column.setResizable(true); + return viewerColumn; + } + + private void setBasicMode() { + fAdvancedMode = false; + fRefTimeColumn.setData(WIDTH_KEY, fRefTimeColumn.getWidth()); + fTargetTimeColumn.setData(WIDTH_KEY, fTargetTimeColumn.getWidth()); + for (TreeItem treeItem : fViewer.getViewer().getTree().getItems()) { + Control editor = (Control) treeItem.getData(EDITOR_KEY); + editor.setVisible(false); + } + fRefTimeColumn.setWidth(0); + fRefTimeColumn.setResizable(false); + fButtonViewerColumn.getColumn().setWidth(0); + fTargetTimeColumn.setWidth(0); + fTargetTimeColumn.setResizable(false); + fAdvancedMessageLabel.setText(""); //$NON-NLS-1$ + } + + private void setAdvancedMode() { + fAdvancedMode = true; + fRefTimeColumn.setWidth((Integer) fRefTimeColumn.getData(WIDTH_KEY)); + fRefTimeColumn.setResizable(true); + fButtonViewerColumn.getColumn().setWidth(TREE_EDITOR_MIN_WIDTH); + fTargetTimeColumn.setWidth((Integer) fTargetTimeColumn.getData(WIDTH_KEY)); + fTargetTimeColumn.setResizable(true); + for (TreeItem treeItem : fViewer.getViewer().getTree().getItems()) { + Control editor = (Control) treeItem.getData(EDITOR_KEY); + editor.setVisible(true); + } + fAdvancedMessageLabel.setText(Messages.OffsetDialog_AdvancedMessage); + } + + /** + * Handler for the event selected signal + * + * @param signal + * the event selected signal + */ + @TmfSignalHandler + public void eventSelected(final TmfEventSelectedSignal signal) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + for (TmfTraceElement traceElement : fOffsetMap.keySet()) { + if (traceElement.getResource().equals(signal.getEvent().getTrace().getResource())) { + fRefTimeMap.put(traceElement, signal.getEvent().getTimestamp()); + fViewer.getViewer().update(traceElement, null); + break; + } + } + } + }); + } + + /** + * Handler for the time selected signal + * + * @param signal + * the event selected signal + */ + @TmfSignalHandler + public void timeSelected(final TmfTimeSynchSignal signal) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + for (TmfTraceElement traceElement : fOffsetMap.keySet()) { + fTargetTimeMap.put(traceElement, signal.getBeginTime()); + fViewer.getViewer().update(traceElement, null); + } + } + }); + } + + /** + * Handler for the trace opened signal + * + * @param signal + * the trace opened signal + */ + @TmfSignalHandler + public void traceOpened(final TmfTraceOpenedSignal signal) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + for (ITmfTrace trace : TmfTraceManager.getTraceSet(signal.getTrace())) { + for (TmfTraceElement traceElement : fOffsetMap.keySet()) { + if (traceElement.getResource().equals(trace.getResource())) { + if (fRefTimeMap.get(traceElement) == null) { + fRefTimeMap.put(traceElement, trace.getStartTime()); + fViewer.getViewer().update(traceElement, null); + } + break; + } + } + } + } + }); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/offset/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/offset/messages.properties new file mode 100644 index 0000000000..af1de0d719 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/dialogs/offset/messages.properties @@ -0,0 +1,24 @@ +############################################################################### +# Copyright (c) 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Matthew Khouzam - Initial API and implementation +# Patrick Tasse - Initial API and implementation +############################################################################### + +OffsetDialog_AdvancedButton=Advanced +OffsetDialog_AdvancedMessage=Double-click a trace to open it, and select an event to set a reference time. \ +If the reference time and target time are set, press the button to compute their offset automatically. \ +The reference time and target time can be entered in format 'yyyy-mm-dd hh:mm:ss.sss sss sss'. +OffsetDialog_BasicButton=Basic +OffsetDialog_BasicMessage=Set the time offset to apply to each trace. +OffsetDialog_OffsetTime=Offset in seconds +OffsetDialog_ReferenceTime=Reference Time +OffsetDialog_TargetTime=Target Time +OffsetDialog_Title=Apply time offset +OffsetDialog_TraceName=Trace name diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/BatchImportTraceHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/BatchImportTraceHandler.java new file mode 100644 index 0000000000..6bc29810a7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/BatchImportTraceHandler.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Bernd Hufmann - Simplify selection logic + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace.BatchImportTraceWizard; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Batch import handler, spawn a wizard + * + * @author Matthew Khouzam + * @since 2.0 + */ +public class BatchImportTraceHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + BatchImportTraceWizard w = new BatchImportTraceWizard(); + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + + if (window == null) { + return false; + } + + ISelection currentSelection = HandlerUtil.getCurrentSelection(event); + + IStructuredSelection sec = StructuredSelection.EMPTY; + if (currentSelection instanceof IStructuredSelection) { + sec = (IStructuredSelection) currentSelection; + } + + w.init(PlatformUI.getWorkbench(), sec); + WizardDialog dialog = new WizardDialog(window.getShell(), w); + dialog.open(); + + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/ClearTraceOffsetHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/ClearTraceOffsetHandler.java new file mode 100644 index 0000000000..a72dc1858e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/ClearTraceOffsetHandler.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import java.lang.reflect.InvocationTargetException; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.internal.tmf.ui.project.operations.TmfWorkspaceModifyOperation; +import org.eclipse.tracecompass.tmf.core.synchronization.TimestampTransformFactory; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Clear Trace Offset Handler + * + * @author Patrick Tasse + */ +public class ClearTraceOffsetHandler extends AbstractHandler { + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + @Override + public Object execute(final ExecutionEvent event) throws ExecutionException { + + ISelection selection = HandlerUtil.getCurrentSelection(event); + + // Get the set of selected trace elements + final Set traceElements = new HashSet<>(); + if (selection instanceof StructuredSelection) { + Iterator iterator = ((StructuredSelection) selection).iterator(); + while (iterator.hasNext()) { + Object element = iterator.next(); + if (element instanceof TmfTraceElement) { + TmfTraceElement trace = (TmfTraceElement) element; + traceElements.add(trace.getElementUnderTraceFolder()); + } else if (element instanceof TmfExperimentElement) { + TmfExperimentElement exp = (TmfExperimentElement) element; + for (TmfTraceElement trace : exp.getTraces()) { + traceElements.add(trace.getElementUnderTraceFolder()); + } + } else if (element instanceof TmfTraceFolder) { + TmfTraceFolder folder = (TmfTraceFolder) element; + traceElements.addAll(folder.getTraces()); + } + } + } + + Shell shell = HandlerUtil.getActiveShellChecked(event); + MessageBox mb = new MessageBox(shell, SWT.ICON_QUESTION | SWT.CANCEL | SWT.OK); + mb.setText(Messages.ClearTraceOffsetHandler_Title); + mb.setMessage(Messages.ClearTraceOffsetHandler_ConfirmMessage); + if (mb.open() != SWT.OK) { + return null; + } + + TmfWorkspaceModifyOperation operation = new TmfWorkspaceModifyOperation() { + @Override + public void execute(IProgressMonitor monitor) throws CoreException { + for (final TmfTraceElement trace : traceElements) { + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + if (!TimestampTransformFactory.getTimestampTransform(trace.getResource()).equals(TimestampTransformFactory.getDefaultTransform())) { + Display.getDefault().syncExec(new Runnable() { + @Override + public void run() { + trace.closeEditors(); + } + }); + trace.deleteSupplementaryResources(); + TimestampTransformFactory.setTimestampTransform(trace.getResource(), null); + trace.refreshSupplementaryFolder(); + } + } + } + }; + try { + PlatformUI.getWorkbench().getProgressService().run(true, true, operation); + } catch (InterruptedException e) { + return null; + } catch (InvocationTargetException e) { + MessageDialog.openError(shell, e.toString(), e.getTargetException().toString()); + return null; + } + + return null; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/CopyExperimentHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/CopyExperimentHandler.java new file mode 100644 index 0000000000..f8d3bc93d1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/CopyExperimentHandler.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Remove enable check + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.wizards.CopyExperimentDialog; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * CopyExperimentHandler + *

    + */ +public class CopyExperimentHandler extends AbstractHandler { + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + // Get selection already validated by handler in plugin.xml + ISelection selection = HandlerUtil.getCurrentSelectionChecked(event); + if (!(selection instanceof IStructuredSelection)) { + return null; + } + TmfExperimentElement experiment = (TmfExperimentElement) ((IStructuredSelection) selection).getFirstElement(); + + // Fire the Copy Experiment dialog + Shell shell = HandlerUtil.getActiveShellChecked(event); + CopyExperimentDialog dialog = new CopyExperimentDialog(shell, experiment); + dialog.open(); + + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/CopyTraceHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/CopyTraceHandler.java new file mode 100644 index 0000000000..f3c2bc7996 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/CopyTraceHandler.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Remove enable check + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.wizards.CopyTraceDialog; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * CopyTraceHandler + *

    + */ +public class CopyTraceHandler extends AbstractHandler { + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + // Get selection already validated by handler in plugin.xml + ISelection selection = HandlerUtil.getCurrentSelectionChecked(event); + if (!(selection instanceof IStructuredSelection)) { + return null; + } + TmfTraceElement trace = (TmfTraceElement) ((IStructuredSelection) selection).getFirstElement(); + + // Fire the Copy Trace dialog + Shell shell = HandlerUtil.getActiveShellChecked(event); + CopyTraceDialog dialog = new CopyTraceDialog(shell, trace); + dialog.open(); + + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/DeleteExperimentHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/DeleteExperimentHandler.java new file mode 100644 index 0000000000..a679e0e91b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/DeleteExperimentHandler.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Close editors to release resources + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import java.util.Iterator; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * DeleteExperimentHandler + *

    + */ +public class DeleteExperimentHandler extends AbstractHandler { + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + + // Confirm the operation + Shell shell = window.getShell(); + MessageBox confirmOperation = new MessageBox(shell, SWT.ICON_QUESTION | SWT.CANCEL | SWT.OK); + confirmOperation.setText(Messages.DeleteDialog_Title); + confirmOperation.setMessage(Messages.DeleteExperimentHandler_Message); + if (confirmOperation.open() != SWT.OK) { + return null; + } + + // Get the selection + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + IWorkbenchPart part = page.getActivePart(); + if (part == null) { + return Boolean.FALSE; + } + ISelection selection = part.getSite().getSelectionProvider().getSelection(); + + if (selection instanceof TreeSelection) { + TreeSelection sel = (TreeSelection) selection; + Iterator iterator = sel.iterator(); + while (iterator.hasNext()) { + Object element = iterator.next(); + if (element instanceof TmfExperimentElement) { + final TmfExperimentElement experiment = (TmfExperimentElement) element; + IResource resource = experiment.getResource(); + + try { + // Close the experiment if open + experiment.closeEditors(); + + IPath path = resource.getLocation(); + if (path != null) { + // Delete supplementary files + experiment.deleteSupplementaryFolder(); + } + + // Finally, delete the experiment + resource.delete(true, null); + + } catch (final CoreException e) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + final MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()); + mb.setText(Messages.DeleteTraceHandler_Error + ' ' + experiment.getName()); + mb.setMessage(e.getMessage()); + mb.open(); + } + }); + Activator.getDefault().logError("Error deleting experiment: " + experiment.getName(), e); //$NON-NLS-1$ + } + } + } + } + + return null; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/DeleteTraceFolderElementHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/DeleteTraceFolderElementHandler.java new file mode 100644 index 0000000000..22a5211b1e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/DeleteTraceFolderElementHandler.java @@ -0,0 +1,349 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Close editors to release resources + * Geneviève Bastien - Moved the delete code to element model's classes + * Marc-Andre Laperle - Merged DeleteTraceHandler and DeleteFolderHandler + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import java.lang.reflect.InvocationTargetException; +import java.util.Iterator; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceVisitor; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.project.operations.TmfWorkspaceModifyOperation; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTracesFolder; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * An handler for deletion of both traces and trace folders. It allows mixing + * both types of elements. + */ +public class DeleteTraceFolderElementHandler extends AbstractHandler { + + private TreeSelection fSelection = null; + + private enum DeleteType { + /** + * Only trace folders are selected. + */ + DELETE_TRACE_FOLDERS, + /** + * Only traces are selected. + */ + DELETE_TRACES, + /** + * A mix of different elements are selected. + */ + DELETE_GENERIC, + /** + * Only Traces (top trace folders) are selected. + */ + CLEAR_TRACES_FOLDER, + /** + * Only Traces under experiments are selected. + */ + REMOVE_TRACES_FROM_EXPERIMENT + } + + // ------------------------------------------------------------------------ + // Validation + // ------------------------------------------------------------------------ + + @Override + public boolean isEnabled() { + + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return false; + } + + // Get the selection + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + IWorkbenchPart part = page.getActivePart(); + if (part == null) { + return false; + } + ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); + if (selectionProvider == null) { + return false; + } + ISelection selection = selectionProvider.getSelection(); + + // Make sure selection contains only traces and trace folders + fSelection = null; + if (selection instanceof TreeSelection) { + fSelection = (TreeSelection) selection; + Iterator iterator = fSelection.iterator(); + while (iterator.hasNext()) { + Object element = iterator.next(); + if (!(element instanceof TmfTraceElement) && !(element instanceof TmfTraceFolder)) { + return false; + } + } + } + + // If we get here, either nothing is selected or everything is a trace or folder + return !selection.isEmpty(); + } + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + private static DeleteType getDeleteType(ISelection selection) { + int numTracesFolder = 0; + int numTraceFolder = 0; + int numTraces = 0; + int numTracesUnderExperiment = 0; + + @SuppressWarnings("rawtypes") + Iterator iterator = ((IStructuredSelection) selection).iterator(); + while (iterator.hasNext()) { + Object next = iterator.next(); + if ((next instanceof TmfTracesFolder)) { + numTracesFolder++; + } else if (next instanceof TmfTraceFolder) { + numTraceFolder++; + } else if (next instanceof TmfTraceElement) { + TmfTraceElement traceElement = (TmfTraceElement) next; + if (traceElement.getParent() instanceof TmfExperimentElement) { + numTracesUnderExperiment++; + } else { + numTraces++; + } + } + } + + int total = numTraceFolder + numTracesFolder + numTracesUnderExperiment + numTraces; + + if (numTracesFolder == total) { + return DeleteType.CLEAR_TRACES_FOLDER; + } + + if (numTraceFolder == total) { + return DeleteType.DELETE_TRACE_FOLDERS; + } + + if (numTraces == total) { + return DeleteType.DELETE_TRACES; + } + + if (numTracesUnderExperiment == total) { + return DeleteType.REMOVE_TRACES_FROM_EXPERIMENT; + } + + return DeleteType.DELETE_GENERIC; + } + + private static String getTitle(final DeleteType deleteType) { + switch (deleteType) + { + case DELETE_GENERIC: + case DELETE_TRACES: + case DELETE_TRACE_FOLDERS: + return Messages.DeleteDialog_Title; + case CLEAR_TRACES_FOLDER: + return Messages.ClearDialog_Title; + case REMOVE_TRACES_FROM_EXPERIMENT: + return Messages.RemoveDialog_Title; + default: + throw new IllegalArgumentException(); + } + } + + private static String getMessage(DeleteType deleteType) { + switch (deleteType) + { + case DELETE_GENERIC: + return Messages.DeleteTraceHandlerGeneric_Message; + case DELETE_TRACES: + return Messages.DeleteTraceHandler_Message; + case CLEAR_TRACES_FOLDER: + return Messages.DeleteFolderHandlerClear_Message; + case DELETE_TRACE_FOLDERS: + return Messages.DeleteFolderHandler_Message; + case REMOVE_TRACES_FROM_EXPERIMENT: + return Messages.RemoveTraceFromExperimentHandler_Message; + default: + throw new IllegalArgumentException(); + } + } + + private static String getTraceErrorMessage(DeleteType deleteType) { + return deleteType == DeleteType.REMOVE_TRACES_FROM_EXPERIMENT ? Messages.RemoveTraceFromExperimentHandler_Error : Messages.DeleteFolderHandler_Error; + } + + private static String getFolderErrorMessage(DeleteType deleteType) { + return deleteType == DeleteType.CLEAR_TRACES_FOLDER ? Messages.DeleteFolderHandlerClear_Error : Messages.DeleteFolderHandler_Error; + } + + private static String getTraceTaskName(DeleteType deleteType) { + return deleteType == DeleteType.REMOVE_TRACES_FROM_EXPERIMENT ? Messages.RemoveTraceFromExperimentHandler_TaskName : Messages.DeleteFolderHandler_TaskName; + } + + private static String getTraceFolderTaskName(DeleteType deleteType) { + return deleteType == DeleteType.CLEAR_TRACES_FOLDER ? Messages.DeleteFolderHandlerClear_TaskName : Messages.DeleteFolderHandler_TaskName; + } + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + + // Get the selection + ISelection selection = HandlerUtil.getCurrentSelection(event); + if (!(selection instanceof IStructuredSelection)) { + return null; + } + final DeleteType deleteType = getDeleteType(selection); + + // Confirm the operation + Shell shell = window.getShell(); + MessageBox confirmOperation = new MessageBox(shell, SWT.ICON_QUESTION | SWT.CANCEL | SWT.OK); + confirmOperation.setText(getTitle(deleteType)); + confirmOperation.setMessage(getMessage(deleteType)); + if (confirmOperation.open() != SWT.OK) { + return null; + } + + final Iterator iterator = fSelection.iterator(); + final int nbElements = fSelection.size(); + + TmfWorkspaceModifyOperation operation = new TmfWorkspaceModifyOperation() { + @Override + public void execute(IProgressMonitor monitor) throws CoreException { + SubMonitor subMonitor = SubMonitor.convert(monitor, nbElements); + + while (iterator.hasNext()) { + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + Object element = iterator.next(); + SubProgressMonitor elementSubMonitor = new SubProgressMonitor(subMonitor, 1); + if (element instanceof TmfTraceElement) { + final TmfTraceElement trace = (TmfTraceElement) element; + if (!trace.getResource().exists()) { + continue; + } + subMonitor.setTaskName(getTraceTaskName(deleteType) + " " + trace.getElementPath()); //$NON-NLS-1$ + try { + SubMonitor deleteSubMonitor = SubMonitor.convert(elementSubMonitor, 1); + trace.delete(deleteSubMonitor); + } catch (final CoreException e) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + final MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()); + mb.setText(getTraceErrorMessage(deleteType) + ' ' + trace.getName()); + mb.setMessage(e.getMessage()); + mb.open(); + } + }); + Activator.getDefault().logError(getTraceErrorMessage(deleteType) + trace.getName(), e); + } + } else if (element instanceof TmfTraceFolder) { + final TmfTraceFolder folder = (TmfTraceFolder) element; + final IResource resource = folder.getResource(); + if (!resource.exists()) { + continue; + } + + subMonitor.setTaskName(getTraceFolderTaskName(deleteType) + " " + folder.getPath()); //$NON-NLS-1$ + + try { + // delete all traces under this folder + SubMonitor childrenSubMonitor = SubMonitor.convert(elementSubMonitor, folder.getTraces().size() + 1); + for (TmfTraceElement traceElement : folder.getTraces()) { + SubProgressMonitor deleteSubMonitor = new SubProgressMonitor(childrenSubMonitor, 1); + traceElement.delete(deleteSubMonitor); + } + + // Finally, delete the folder. For the Traces + // folder, we only delete the children since the + // folder should always be there. + final SubProgressMonitor deleteSubMonitor = new SubProgressMonitor(subMonitor, 1); + if (folder instanceof TmfTracesFolder) { + resource.accept(new IResourceVisitor() { + @Override + public boolean visit(IResource visitedResource) throws CoreException { + if (visitedResource != resource) { + visitedResource.delete(true, deleteSubMonitor); + } + return true; + } + }, IResource.DEPTH_ONE, 0); + } else { + resource.delete(true, deleteSubMonitor); + } + childrenSubMonitor.done(); + } catch (final CoreException e) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + final MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()); + mb.setText(getFolderErrorMessage(deleteType) + ' ' + folder.getName()); + mb.setMessage(e.getMessage()); + mb.open(); + } + }); + Activator.getDefault().logError(getFolderErrorMessage(deleteType) + folder.getName(), e); + } + } + subMonitor.setTaskName(""); //$NON-NLS-1$ + elementSubMonitor.done(); + } + } + }; + + try { + PlatformUI.getWorkbench().getProgressService().run(true, true, operation); + } catch (InterruptedException e) { + return null; + } catch (InvocationTargetException e) { + MessageDialog.openError(window.getShell(), e.toString(), e.getTargetException().toString()); + return null; + } + return null; + } + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/DeleteTraceSupplementaryFilesHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/DeleteTraceSupplementaryFilesHandler.java new file mode 100644 index 0000000000..982849a2e8 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/DeleteTraceSupplementaryFilesHandler.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Patrick Tasse - Close editors to release resources + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.window.Window; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.project.dialogs.SelectSupplementaryResourcesDialog; +import org.eclipse.tracecompass.internal.tmf.ui.project.operations.TmfWorkspaceModifyOperation; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfCommonProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; + +import com.google.common.collect.Multimap; +import com.google.common.collect.TreeMultimap; + +/** + * Handler for Delete Supplementary Files command on trace + */ +public class DeleteTraceSupplementaryFilesHandler extends AbstractHandler { + + // ------------------------------------------------------------------------ + // Inner classes + // ------------------------------------------------------------------------ + + private class ElementComparator implements Comparator { + @Override + public int compare(TmfCommonProjectElement e1, TmfCommonProjectElement e2) { + return e1.getPath().toString().compareTo(e2.getPath().toString()); + } + } + + private class ResourceComparator implements Comparator { + @Override + public int compare(IResource r1, IResource r2) { + return r1.getFullPath().toString().compareTo(r2.getFullPath().toString()); + } + } + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + + // Get the selection + ISelection selection = HandlerUtil.getCurrentSelection(event); + if (!(selection instanceof IStructuredSelection)) { + return null; + } + final Multimap resourceMap = + TreeMultimap.create(new ElementComparator(), new ResourceComparator()); + final Iterator iterator = ((IStructuredSelection) selection).iterator(); + + while (iterator.hasNext()) { + Object element = iterator.next(); + if (element instanceof TmfTraceElement) { + TmfTraceElement trace = (TmfTraceElement) element; + // If trace is under an experiment, use the original trace from the traces folder + trace = trace.getElementUnderTraceFolder(); + for (IResource resource : trace.getSupplementaryResources()) { + resourceMap.put(trace, resource); + } + + } else if (element instanceof TmfExperimentElement) { + TmfExperimentElement experiment = (TmfExperimentElement) element; + for (IResource resource : experiment.getSupplementaryResources()) { + resourceMap.put(experiment, resource); + } + for (TmfTraceElement trace : experiment.getTraces()) { + // If trace is under an experiment, use the original trace from the traces folder + trace = trace.getElementUnderTraceFolder(); + for (IResource resource : trace.getSupplementaryResources()) { + resourceMap.put(trace, resource); + } + } + } + } + + final SelectSupplementaryResourcesDialog dialog = + new SelectSupplementaryResourcesDialog(window.getShell(), resourceMap); + if (dialog.open() != Window.OK) { + return null; + } + + TmfWorkspaceModifyOperation operation = new TmfWorkspaceModifyOperation() { + @Override + public void execute(IProgressMonitor monitor) throws CoreException { + + Set projectsToRefresh = new HashSet<>(); + + // Delete the resources that were selected + List allResourcesToDelete = Arrays.asList(dialog.getResources()); + + SubMonitor subMonitor = SubMonitor.convert(monitor, allResourcesToDelete.size()); + + for (final TmfCommonProjectElement element : resourceMap.keySet()) { + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + List traceResourcesToDelete = new ArrayList<>(resourceMap.get(element)); + traceResourcesToDelete.retainAll(allResourcesToDelete); + if (!traceResourcesToDelete.isEmpty()) { + subMonitor.setTaskName(NLS.bind(Messages.DeleteSupplementaryFiles_DeletionTask, element.getElementPath())); + // Delete the selected resources + Display.getDefault().syncExec(new Runnable() { + @Override + public void run() { + element.closeEditors(); + } + }); + element.deleteSupplementaryResources(traceResourcesToDelete.toArray(new IResource[0])); + projectsToRefresh.add(element.getProject().getResource()); + } + subMonitor.worked(traceResourcesToDelete.size()); + } + + subMonitor = SubMonitor.convert(monitor, projectsToRefresh.size()); + + // Refresh projects + Iterator projectIterator = projectsToRefresh.iterator(); + while (projectIterator.hasNext()) { + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + IProject project = projectIterator.next(); + subMonitor.setTaskName(NLS.bind(Messages.DeleteSupplementaryFiles_ProjectRefreshTask, project.getName())); + try { + project.refreshLocal(IResource.DEPTH_INFINITE, null); + } catch (CoreException e) { + Activator.getDefault().logError("Error refreshing project " + project, e); //$NON-NLS-1$ + } + subMonitor.worked(1); + } + } + }; + + try { + PlatformUI.getWorkbench().getProgressService().run(true, true, operation); + } catch (InterruptedException e) { + return null; + } catch (InvocationTargetException e) { + MessageDialog.openError(window.getShell(), e.toString(), e.getTargetException().toString()); + return null; + } + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/DropAdapterAssistant.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/DropAdapterAssistant.java new file mode 100644 index 0000000000..a8d4c6ee23 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/DropAdapterAssistant.java @@ -0,0 +1,669 @@ +/******************************************************************************* +* Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Patrick Tasse - Add support for DROP_LINK and rename prompt on name clash + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.FileTransfer; +import org.eclipse.swt.dnd.TransferData; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceImportException; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; +import org.eclipse.tracecompass.tmf.core.trace.TmfTrace; +import org.eclipse.tracecompass.tmf.ui.project.model.ITmfProjectModelElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceTypeUIUtils; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.WorkspaceModifyDelegatingOperation; +import org.eclipse.ui.dialogs.IOverwriteQuery; +import org.eclipse.ui.navigator.CommonDropAdapter; +import org.eclipse.ui.navigator.CommonDropAdapterAssistant; +import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider; +import org.eclipse.ui.wizards.datatransfer.ImportOperation; + +/** + * Drop adapter assistant for project explorer + */ +public class DropAdapterAssistant extends CommonDropAdapterAssistant { + + /** + * Default constructor + */ + public DropAdapterAssistant() { + } + + @Override + public boolean isSupportedType(TransferData aTransferType) { + return super.isSupportedType(aTransferType) || FileTransfer.getInstance().isSupportedType(aTransferType); + } + + @Override + public IStatus validateDrop(Object target, int operation, TransferData transferType) { + if (target instanceof TmfTraceFolder) { + return Status.OK_STATUS; + } + if (target instanceof TmfExperimentElement) { + return Status.OK_STATUS; + } + if (target instanceof TmfTraceElement) { + ITmfProjectModelElement parent = ((TmfTraceElement) target).getParent(); + if (parent instanceof TmfTraceFolder) { + return Status.OK_STATUS; + } + if (parent instanceof TmfExperimentElement) { + return Status.OK_STATUS; + } + } + if (target instanceof IProject) { + return Status.OK_STATUS; + } + return Status.CANCEL_STATUS; + } + + @Override + public IStatus handleDrop(CommonDropAdapter aDropAdapter, DropTargetEvent aDropTargetEvent, Object aTarget) { + boolean ok = false; + + // Use local variable to avoid parameter assignment + Object targetToUse = aTarget; + + int operation = aDropTargetEvent.detail; + if (operation != DND.DROP_LINK) { + operation = DND.DROP_COPY; + } + + // If target is a trace, use its parent (either trace folder or experiment) + if (targetToUse instanceof TmfTraceElement) { + targetToUse = ((TmfTraceElement) targetToUse).getParent(); + } + + // If target is a project, use its trace folder + if (targetToUse instanceof IProject) { + TmfProjectElement projectElement = TmfProjectRegistry.getProject((IProject) targetToUse, true); + if (projectElement != null) { + targetToUse = projectElement.getTracesFolder(); + } + } + + if (aDropTargetEvent.data instanceof IStructuredSelection) { + IStructuredSelection selection = (IStructuredSelection) aDropTargetEvent.data; + for (Object source : selection.toArray()) { + if (source instanceof IResource) { + // If source resource is a trace, use the trace element + IResource sourceResource = (IResource) source; + TmfProjectElement projectElement = TmfProjectRegistry.getProject(sourceResource.getProject()); + if (projectElement != null && projectElement.getTracesFolder() != null) { + for (TmfTraceElement trace : projectElement.getTracesFolder().getTraces()) { + if (trace.getResource().equals(sourceResource)) { + source = trace; + break; + } + } + } + } + if (source instanceof TmfTraceElement) { + TmfTraceElement sourceTrace = (TmfTraceElement) source; + // If source trace is under an experiment, use the original trace from the traces folder + sourceTrace = sourceTrace.getElementUnderTraceFolder(); + if (targetToUse instanceof TmfExperimentElement) { + TmfExperimentElement targetExperiment = (TmfExperimentElement) targetToUse; + ok |= drop(sourceTrace, targetExperiment, operation); + } else if (targetToUse instanceof TmfTraceFolder) { + TmfTraceFolder traceFolder = (TmfTraceFolder) targetToUse; + ok |= drop(sourceTrace, traceFolder, operation); + } + } else if (source instanceof IResource) { + IResource sourceResource = (IResource) source; + if (sourceResource.getType() != IResource.FILE && sourceResource.getType() != IResource.FOLDER) { + continue; + } + if (targetToUse instanceof TmfExperimentElement) { + TmfExperimentElement targetExperiment = (TmfExperimentElement) targetToUse; + ok |= (drop(sourceResource, targetExperiment, operation) != null); + } else if (targetToUse instanceof TmfTraceFolder) { + TmfTraceFolder traceFolder = (TmfTraceFolder) targetToUse; + ok |= (drop(sourceResource, traceFolder, operation) != null); + } + } + } + } else if (aDropTargetEvent.data instanceof String[]) { + String[] sources = (String[]) aDropTargetEvent.data; + for (String source : sources) { + Path path = new Path(source); + if (targetToUse instanceof TmfExperimentElement) { + TmfExperimentElement targetExperiment = (TmfExperimentElement) targetToUse; + ok |= drop(path, targetExperiment, operation); + } else if (targetToUse instanceof TmfTraceFolder) { + TmfTraceFolder traceFolder = (TmfTraceFolder) targetToUse; + ok |= drop(path, traceFolder, operation); + } + } + } + return (ok ? Status.OK_STATUS : Status.CANCEL_STATUS); + } + + + /** + * Drop a trace by copying/linking a trace element in a target experiment + * + * @param sourceTrace the source trace element to copy + * @param targetExperiment the target experiment + * @param operation the drop operation (DND.DROP_COPY | DND.DROP_LINK) + * @return true if successful + */ + private static boolean drop(TmfTraceElement sourceTrace, + TmfExperimentElement targetExperiment, + int operation) { + + IResource sourceResource = sourceTrace.getResource(); + IResource targetResource = drop(sourceResource, targetExperiment, operation); + + if (targetResource != null) { + if (! sourceTrace.getProject().equals(targetExperiment.getProject())) { + IFolder destinationSupplementaryFolder = targetExperiment.getTraceSupplementaryFolder(targetResource.getName()); + sourceTrace.copySupplementaryFolder(destinationSupplementaryFolder); + } + return true; + } + return false; + } + + /** + * Drop a trace by copying/linking a resource in a target experiment + * + * @param sourceResource the source resource + * @param targetExperiment the target experiment + * @param operation the drop operation (DND.DROP_COPY | DND.DROP_LINK) + * @return the target resource or null if unsuccessful + */ + private static IResource drop(IResource sourceResource, + TmfExperimentElement targetExperiment, + int operation) { + + IResource traceResource = sourceResource; + + IPath tracesFolderPath = targetExperiment.getProject().getTracesFolder().getPath(); + if (tracesFolderPath.isPrefixOf(sourceResource.getFullPath())) { + String elementPath = sourceResource.getFullPath().makeRelativeTo(tracesFolderPath).toString(); + for (TmfTraceElement trace : targetExperiment.getTraces()) { + if (trace.getElementPath().equals(elementPath)) { + return null; + } + } + } else { + String targetName = sourceResource.getName(); + for (ITmfProjectModelElement element : targetExperiment.getProject().getTracesFolder().getChildren()) { + if (element.getName().equals(targetName)) { + targetName = promptRename(element); + if (targetName == null) { + return null; + } + break; + } + } + try { + if (operation == DND.DROP_COPY && !sourceResource.isLinked()) { + IPath destination = targetExperiment.getProject().getTracesFolder().getResource().getFullPath().addTrailingSeparator().append(targetName); + sourceResource.copy(destination, false, null); + cleanupBookmarks(destination); + } else { + createLink(targetExperiment.getProject().getTracesFolder().getResource(), sourceResource, targetName); + } + // use the copied resource for the experiment + if (sourceResource.getType() == IResource.FILE) { + traceResource = targetExperiment.getProject().getTracesFolder().getResource().getFile(targetName); + } else if (sourceResource.getType() == IResource.FOLDER) { + traceResource = targetExperiment.getProject().getTracesFolder().getResource().getFolder(targetName); + } + String sourceLocation = sourceResource.getPersistentProperty(TmfCommonConstants.SOURCE_LOCATION); + if (sourceLocation == null) { + sourceLocation = URIUtil.toUnencodedString(new File(sourceResource.getLocationURI()).toURI()); + } + traceResource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation); + } catch (CoreException e) { + displayException(e); + return null; + } + } + if (traceResource != null && traceResource.exists()) { + setTraceType(traceResource); + for (TmfTraceElement trace : targetExperiment.getProject().getTracesFolder().getTraces()) { + if (trace.getResource().equals(traceResource)) { + targetExperiment.addTrace(trace); + targetExperiment.closeEditors(); + targetExperiment.deleteSupplementaryResources(); + break; + } + } + return traceResource; + } + return null; + } + + /** + * Drop a trace by copying/linking a trace element in a trace folder + * + * @param sourceTrace the source trace + * @param traceFolder the target trace folder + * @param operation the drop operation (DND.DROP_COPY | DND.DROP_LINK) + * @return true if successful + */ + private static boolean drop(TmfTraceElement sourceTrace, + TmfTraceFolder traceFolder, + int operation) { + + IResource sourceResource = sourceTrace.getResource(); + IResource targetResource = drop(sourceResource, traceFolder, operation); + + if (targetResource != null) { + String elementPath = targetResource.getFullPath().makeRelativeTo(traceFolder.getProject().getTracesFolder().getPath()).toString(); + IFolder destinationSupplementaryFolder = traceFolder.getTraceSupplementaryFolder(elementPath); + sourceTrace.copySupplementaryFolder(destinationSupplementaryFolder); + return true; + } + return false; + } + + /** + * Drop a trace by copying/linking a resource in a trace folder + * + * @param sourceResource the source resource + * @param traceFolder the target trace folder + * @param operation the drop operation (DND.DROP_COPY | DND.DROP_LINK) + * @return the target resource or null if unsuccessful + */ + private static IResource drop(IResource sourceResource, + TmfTraceFolder traceFolder, + int operation) { + + if (sourceResource.getParent().equals(traceFolder.getResource())) { + return null; + } + String targetName = sourceResource.getName(); + for (ITmfProjectModelElement element : traceFolder.getChildren()) { + if (element.getName().equals(targetName)) { + targetName = promptRename(element); + if (targetName == null) { + return null; + } + break; + } + } + try { + if (operation == DND.DROP_COPY && !sourceResource.isLinked()) { + IPath destination = traceFolder.getResource().getFullPath().addTrailingSeparator().append(targetName); + sourceResource.copy(destination, false, null); + cleanupBookmarks(destination); + } else { + createLink(traceFolder.getResource(), sourceResource, targetName); + } + IResource traceResource = traceFolder.getResource().findMember(targetName); + if (traceResource != null && traceResource.exists()) { + String sourceLocation = sourceResource.getPersistentProperty(TmfCommonConstants.SOURCE_LOCATION); + if (sourceLocation == null) { + sourceLocation = URIUtil.toUnencodedString(new File(sourceResource.getLocationURI()).toURI()); + } + traceResource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation); + setTraceType(traceResource); + } + return traceResource; + } catch (CoreException e) { + displayException(e); + } + return null; + } + + /** + * Drop a trace by importing/linking a path in a target experiment + * + * @param path the source path + * @param targetExperiment the target experiment + * @param operation the drop operation (DND.DROP_COPY | DND.DROP_LINK) + * @return true if successful + */ + private static boolean drop(Path path, + TmfExperimentElement targetExperiment, + int operation) { + + IPath tracesFolderPath = targetExperiment.getProject().getTracesFolder().getResource().getLocation(); + IResource traceResource = null; + if (tracesFolderPath.isPrefixOf(path)) { + String elementPath = path.makeRelativeTo(tracesFolderPath).toString(); + for (TmfTraceElement trace : targetExperiment.getTraces()) { + if (trace.getElementPath().equals(elementPath)) { + return false; + } + } + traceResource = targetExperiment.getProject().getTracesFolder().getResource().findMember(elementPath); + } else { + String targetName = path.lastSegment(); + for (ITmfProjectModelElement element : targetExperiment.getProject().getTracesFolder().getChildren()) { + if (element.getName().equals(targetName)) { + targetName = promptRename(element); + if (targetName == null) { + return false; + } + break; + } + } + if (operation == DND.DROP_COPY) { + importTrace(targetExperiment.getProject().getTracesFolder().getResource(), path, targetName); + } else { + createLink(targetExperiment.getProject().getTracesFolder().getResource(), path, targetName); + } + // use the copied resource for the experiment + File file = new File(path.toString()); + if (file.exists() && file.isFile()) { + traceResource = targetExperiment.getProject().getTracesFolder().getResource().getFile(targetName); + } else if (file.exists() && file.isDirectory()) { + traceResource = targetExperiment.getProject().getTracesFolder().getResource().getFolder(targetName); + } + } + if (traceResource != null && traceResource.exists()) { + try { + String sourceLocation = URIUtil.toUnencodedString(path.toFile().toURI()); + traceResource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation); + } catch (CoreException e) { + displayException(e); + } + setTraceType(traceResource); + for (TmfTraceElement trace : targetExperiment.getProject().getTracesFolder().getTraces()) { + if (trace.getResource().equals(traceResource)) { + targetExperiment.addTrace(trace); + targetExperiment.closeEditors(); + targetExperiment.deleteSupplementaryResources(); + break; + } + } + return true; + } + return false; + } + + /** + * Drop a trace by importing/linking a path in a trace folder + * + * @param path the source path + * @param traceFolder the target trace folder + * @param operation the drop operation (DND.DROP_COPY | DND.DROP_LINK) + * @return true if successful + */ + private static boolean drop(Path path, + TmfTraceFolder traceFolder, + int operation) { + + String targetName = path.lastSegment(); + for (ITmfProjectModelElement element : traceFolder.getChildren()) { + if (element.getName().equals(targetName)) { + targetName = promptRename(element); + if (targetName == null) { + return false; + } + break; + } + } + if (operation == DND.DROP_COPY) { + importTrace(traceFolder.getResource(), path, targetName); + } else { + createLink(traceFolder.getResource(), path, targetName); + } + IResource traceResource = traceFolder.getResource().findMember(targetName); + if (traceResource != null && traceResource.exists()) { + try { + String sourceLocation = URIUtil.toUnencodedString(path.toFile().toURI()); + traceResource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation); + } catch (CoreException e) { + displayException(e); + } + setTraceType(traceResource); + } + return true; + } + + /** + * Import a trace to the trace folder + * + * @param folder the trace folder resource + * @param path the path to the trace to import + * @param targetName the target name + */ + private static void importTrace(final IFolder folder, final Path path, final String targetName) { + final File source = new File(path.toString()); + if (source.isDirectory()) { + IPath containerPath = folder.getFullPath().addTrailingSeparator().append(targetName); + IOverwriteQuery overwriteImplementor = new IOverwriteQuery() { + @Override + public String queryOverwrite(String pathString) { + return IOverwriteQuery.NO_ALL; + } + }; + List filesToImport = Arrays.asList(source.listFiles()); + ImportOperation operation = new ImportOperation( + containerPath, + source, + FileSystemStructureProvider.INSTANCE, + overwriteImplementor, + filesToImport); + operation.setCreateContainerStructure(false); + try { + operation.run(new NullProgressMonitor()); + } catch (InvocationTargetException e) { + displayException(e); + } catch (InterruptedException e) { + displayException(e); + } + } else { + IRunnableWithProgress runnable = new IRunnableWithProgress() { + @Override + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + try (InputStream inputStream = new FileInputStream(source);) { + IFile targetFile = folder.getFile(targetName); + targetFile.create(inputStream, IResource.NONE, monitor); + } catch (CoreException | IOException e) { + displayException(e); + } + } + }; + WorkspaceModifyDelegatingOperation operation = new WorkspaceModifyDelegatingOperation(runnable); + try { + operation.run(new NullProgressMonitor()); + } catch (InvocationTargetException e) { + displayException(e); + } catch (InterruptedException e) { + displayException(e); + } + } + } + + /** + * Create a link to the actual trace and set the trace type + * + * @param parentFolder the parent folder + * @param resource the resource + * @param targetName the target name + */ + private static void createLink(IFolder parentFolder, IResource resource, String targetName) { + IPath location = resource.getLocation(); + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + try { + String traceType = TmfTraceType.getTraceTypeId(resource); + TraceTypeHelper traceTypeHelper = TmfTraceType.getTraceType(traceType); + + if (resource instanceof IFolder) { + IFolder folder = parentFolder.getFolder(targetName); + IStatus result = workspace.validateLinkLocation(folder, location); + if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) { + folder.createLink(location, IResource.REPLACE, null); + if (traceTypeHelper != null) { + TmfTraceTypeUIUtils.setTraceType(folder, traceTypeHelper); + } + } else { + Activator.getDefault().logError("Invalid Trace Location"); //$NON-NLS-1$ + } + } else { + IFile file = parentFolder.getFile(targetName); + IStatus result = workspace.validateLinkLocation(file, location); + if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) { + file.createLink(location, IResource.REPLACE, null); + if (traceTypeHelper != null) { + TmfTraceTypeUIUtils.setTraceType(file, traceTypeHelper); + } + } else { + Activator.getDefault().logError("Invalid Trace Location"); //$NON-NLS-1$ + } + } + } catch (CoreException e) { + displayException(e); + } + } + + /** + * Create a link to a file or folder + * + * @param parentFolder the parent folder + * @param source the file or folder + * @param targetName the target name + */ + private static void createLink(IFolder parentFolder, IPath location, String targetName) { + File source = new File(location.toString()); + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + try { + + if (source.isDirectory()) { + IFolder folder = parentFolder.getFolder(targetName); + IStatus result = workspace.validateLinkLocation(folder, location); + if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) { + folder.createLink(location, IResource.REPLACE, null); + } else { + Activator.getDefault().logError("Invalid Trace Location"); //$NON-NLS-1$ + } + } else { + IFile file = parentFolder.getFile(targetName); + IStatus result = workspace.validateLinkLocation(file, location); + if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) { + file.createLink(location, IResource.REPLACE, null); + } else { + Activator.getDefault().logError("Invalid Trace Location"); //$NON-NLS-1$ + } + } + } catch (CoreException e) { + displayException(e); + } + } + + /** + * Prompts the user to rename a trace + * + * @param element the conflicting element + * @return the new name to use or null if rename is canceled + */ + private static String promptRename(ITmfProjectModelElement element) { + MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.ICON_QUESTION | SWT.CANCEL | SWT.OK); + mb.setText(Messages.DropAdapterAssistant_RenameTraceTitle); + mb.setMessage(NLS.bind(Messages.DropAdapterAssistant_RenameTraceMessage, element.getName())); + if (mb.open() != SWT.OK) { + return null; + } + IContainer folder = element.getResource().getParent(); + int i = 2; + while (true) { + String name = element.getName() + '(' + Integer.toString(i++) + ')'; + IResource resource = folder.findMember(name); + if (resource == null) { + return name; + } + } + } + + /** + * Cleanup bookmarks file in copied trace + */ + private static void cleanupBookmarks(IPath path) { + IFolder folder = ResourcesPlugin.getWorkspace().getRoot().getFolder(path); + if (folder.exists()) { + try { + for (IResource member : folder.members()) { + if (TmfTrace.class.getCanonicalName().equals(TmfTraceType.getTraceTypeId(member))) { + member.delete(true, null); + } + } + } catch (CoreException e) { + displayException(e); + } + } + } + + private static void setTraceType(IResource traceResource) { + try { + String traceType = TmfTraceType.getTraceTypeId(traceResource); + TraceTypeHelper traceTypeHelper = TmfTraceType.getTraceType(traceType); + if (traceTypeHelper == null) { + traceTypeHelper = TmfTraceTypeUIUtils.selectTraceType(traceResource.getLocation().toOSString(), null, null); + } + if (traceTypeHelper != null) { + TmfTraceTypeUIUtils.setTraceType(traceResource, traceTypeHelper); + } + } catch (TmfTraceImportException e) { + } catch (CoreException e) { + displayException(e); + } + } + + /** + * Display an exception in a message box + * + * @param e the exception + */ + private static void displayException(Exception e) { + MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()); + mb.setText(e.getClass().getName()); + mb.setMessage(e.getMessage()); + mb.open(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/ImportTraceHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/ImportTraceHandler.java new file mode 100644 index 0000000000..ead339d9b3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/ImportTraceHandler.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Update selection handling + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace.ImportTraceWizard; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * ImportTraceHandler + *

    + * Starts an ImportTraceWizard that will handle the lowly details. + */ +public class ImportTraceHandler extends AbstractHandler { + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ImportTraceWizard w = new ImportTraceWizard(); + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + + if (window == null) { + return false; + } + + ISelection currentSelection = HandlerUtil.getCurrentSelection(event); + // Menu Selection is only not null for context-sensitive menu + ISelection menuSelection = HandlerUtil.getActiveMenuSelection(event); + + IStructuredSelection sec = StructuredSelection.EMPTY; + + // Only use the selection if handler is called from context-sensitive menu + if ((menuSelection != null) && (currentSelection instanceof IStructuredSelection)) { + sec = (IStructuredSelection) currentSelection; + } + + w.init(PlatformUI.getWorkbench(), sec); + WizardDialog dialog = new WizardDialog(window.getShell(), w); + dialog.open(); + return null; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/Messages.java new file mode 100644 index 0000000000..0314b68990 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/Messages.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Added drag and drop messages + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import org.eclipse.osgi.util.NLS; + +/** + * Messages file + * + * @author Francois Chouinard + * @version 1.0 + */ +@SuppressWarnings("javadoc") +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.tmf.ui.project.handlers.messages"; //$NON-NLS-1$ + + public static String DeleteDialog_Title; + public static String DeleteTraceHandler_Message; + public static String DeleteTraceHandler_Error; + public static String DeleteTraceHandler_TaskName; + public static String DeleteTraceHandlerGeneric_Message; + public static String DeleteTraceHandlerGeneric_Error; + public static String DeleteExperimentHandler_Message; + public static String DeleteExperimentHandler_Error; + public static String DeleteFolderHandler_Message; + public static String DeleteFolderHandler_Error; + public static String DeleteFolderHandler_TaskName; + + public static String RemoveDialog_Title; + public static String RemoveTraceFromExperimentHandler_Message; + public static String RemoveTraceFromExperimentHandler_TaskName; + public static String RemoveTraceFromExperimentHandler_Error; + public static String ClearDialog_Title; + public static String DeleteFolderHandlerClear_Message; + public static String DeleteFolderHandlerClear_Error; + public static String DeleteFolderHandlerClear_TaskName; + + public static String SelectTraceTypeHandler_ErrorSelectingTrace; + public static String SelectTraceTypeHandler_Title; + public static String SelectTraceTypeHandler_TraceFailedValidation; + public static String SelectTraceTypeHandler_TracesFailedValidation; + public static String SelectTraceTypeHandler_InvalidTraceType; + + public static String DropAdapterAssistant_RenameTraceTitle; + public static String DropAdapterAssistant_RenameTraceMessage; + + public static String SynchronizeTracesHandler_InitError; + public static String SynchronizeTracesHandler_CopyProblem; + public static String SynchronizeTracesHandler_WrongType; + public static String SynchronizeTracesHandler_WrongTraceNumber; + public static String SynchronizeTracesHandler_Title; + public static String SynchronizeTracesHandler_Error; + public static String SynchronizeTracesHandler_ErrorSynchingExperiment; + public static String SynchronizeTracesHandler_ErrorSynchingForTrace; + + public static String ClearTraceOffsetHandler_Title; + public static String ClearTraceOffsetHandler_ConfirmMessage; + + public static String DeleteSupplementaryFiles_DeletionTask; + public static String DeleteSupplementaryFiles_ProjectRefreshTask; + + public static String AnalysisModule_Help; + + public static String TmfActionProvider_OpenWith; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/NewExperimentHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/NewExperimentHandler.java new file mode 100644 index 0000000000..0548db66bc --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/NewExperimentHandler.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder; +import org.eclipse.tracecompass.tmf.ui.project.wizards.NewExperimentDialog; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * NewExperimentHandler + *

    + */ +public class NewExperimentHandler extends AbstractHandler { + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + + // Get the selection + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + IWorkbenchPart part = page.getActivePart(); + if (part == null) { + return Boolean.FALSE; + } + ISelection selection = part.getSite().getSelectionProvider().getSelection(); + TmfExperimentFolder experimentFolder = null; + if (selection instanceof TreeSelection) { + TreeSelection sel = (TreeSelection) selection; + Object element = sel.getFirstElement(); + if (element instanceof TmfExperimentFolder) { + experimentFolder = (TmfExperimentFolder) element; + } + } + if (experimentFolder == null) { + return null; + } + + // Fire the New Experiment dialog + Shell shell = window.getShell(); + NewExperimentDialog dialog = new NewExperimentDialog(shell, experimentFolder); + dialog.open(); + + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/NewFolderHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/NewFolderHandler.java new file mode 100644 index 0000000000..c189f11b4e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/NewFolderHandler.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.tracecompass.tmf.ui.project.wizards.NewFolderDialog; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Handler for the New Folder command. + */ +public class NewFolderHandler extends AbstractHandler { + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + + ISelection selection = HandlerUtil.getCurrentSelection(event); + if (!(selection instanceof IStructuredSelection)) { + return null; + } + final Object element = ((IStructuredSelection) selection).getFirstElement(); + if (!(element instanceof TmfTraceFolder)) { + return null; + } + TmfTraceFolder parent = (TmfTraceFolder) element; + + // Fire the New Folder dialog + Shell shell = window.getShell(); + NewFolderDialog dialog = new NewFolderDialog(shell, parent); + dialog.open(); + + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OffsetTraceHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OffsetTraceHandler.java new file mode 100644 index 0000000000..30bc078466 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OffsetTraceHandler.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import java.lang.reflect.InvocationTargetException; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.internal.tmf.ui.project.dialogs.offset.OffsetDialog; +import org.eclipse.tracecompass.internal.tmf.ui.project.operations.TmfWorkspaceModifyOperation; +import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform; +import org.eclipse.tracecompass.tmf.core.synchronization.TimestampTransformFactory; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Offset Handler + * + * @author Matthew Khouzam + */ +public class OffsetTraceHandler extends AbstractHandler { + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + @Override + public Object execute(final ExecutionEvent event) throws ExecutionException { + + ISelection selection = HandlerUtil.getCurrentSelection(event); + + // Get the set of selected trace elements + final Set traceElements = new HashSet<>(); + if (selection instanceof StructuredSelection) { + Iterator iterator = ((StructuredSelection) selection).iterator(); + while (iterator.hasNext()) { + Object element = iterator.next(); + if (element instanceof TmfTraceElement) { + TmfTraceElement trace = (TmfTraceElement) element; + traceElements.add(trace.getElementUnderTraceFolder()); + } else if (element instanceof TmfExperimentElement) { + TmfExperimentElement exp = (TmfExperimentElement) element; + for (TmfTraceElement trace : exp.getTraces()) { + traceElements.add(trace.getElementUnderTraceFolder()); + } + } else if (element instanceof TmfTraceFolder) { + TmfTraceFolder folder = (TmfTraceFolder) element; + traceElements.addAll(folder.getTraces()); + } + } + } + + final Map offsets = new LinkedHashMap<>(traceElements.size()); + for (TmfTraceElement trace : traceElements) { + offsets.put(trace, 0L); + } + + Shell shell = HandlerUtil.getActiveShellChecked(event); + OffsetDialog dialog = new OffsetDialog(shell, offsets); + dialog.open(); + + if (dialog.getReturnCode() != Window.OK) { + return null; + } + + TmfWorkspaceModifyOperation operation = new TmfWorkspaceModifyOperation() { + @Override + public void execute(IProgressMonitor monitor) throws CoreException { + for (final TmfTraceElement trace : offsets.keySet()) { + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + Long offset = offsets.get(trace); + if (offset != 0 && trace.getResource().exists()) { + Display.getDefault().syncExec(new Runnable() { + @Override + public void run() { + trace.closeEditors(); + } + }); + long previousOffset = TimestampTransformFactory.getTimestampTransform(trace.getResource()).transform(0); + ITmfTimestampTransform transform = TimestampTransformFactory.createWithOffset(previousOffset + offset); + trace.deleteSupplementaryResources(); + // make sure the supplementary folder exists + trace.refreshSupplementaryFolder(); + TimestampTransformFactory.setTimestampTransform(trace.getResource(), transform); + trace.refreshSupplementaryFolder(); + } + } + } + }; + try { + PlatformUI.getWorkbench().getProgressService().run(true, true, operation); + } catch (InterruptedException e) { + return null; + } catch (InvocationTargetException e) { + MessageDialog.openError(shell, e.toString(), e.getTargetException().toString()); + return null; + } + + return null; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenAction.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenAction.java new file mode 100644 index 0000000000..8df2de5c67 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenAction.java @@ -0,0 +1,94 @@ +/******************************************************************************* +* Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.NotEnabledException; +import org.eclipse.core.commands.NotHandledException; +import org.eclipse.core.commands.common.NotDefinedException; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfAnalysisOutputElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectModelElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.handlers.IHandlerService; + +/** + * OpenAction + */ +public class OpenAction extends Action { + + private static final String OPEN_COMMAND_ID = "org.eclipse.ui.navigate.openResource"; //$NON-NLS-1$ + + private final IWorkbenchPage page; + private final ISelectionProvider selectionProvider; + private TmfProjectModelElement element; + + /** + * Default constructor + * @param page the workbench page + * @param selectionProvider the selection provider + */ + public OpenAction(IWorkbenchPage page, ISelectionProvider selectionProvider) { + this.page = page; + this.selectionProvider = selectionProvider; + } + + @Override + public boolean isEnabled() { + ISelection selection = selectionProvider.getSelection(); + if (!selection.isEmpty()) { + IStructuredSelection sSelection = (IStructuredSelection) selection; + if (sSelection.size() == 1) { + if (sSelection.getFirstElement() instanceof TmfTraceElement || + sSelection.getFirstElement() instanceof TmfExperimentElement || + sSelection.getFirstElement() instanceof TmfAnalysisOutputElement) { + element = (TmfProjectModelElement) sSelection.getFirstElement(); + return true; + } + } + } + return false; + } + + @Override + public void run() { + try { + IHandlerService handlerService = (IHandlerService) page.getActivePart().getSite().getService(IHandlerService.class); + boolean executeCommand = ((element instanceof TmfTraceElement) || (element instanceof TmfAnalysisOutputElement)); + + if (!executeCommand && element instanceof TmfExperimentElement) { + TmfExperimentElement experiment = (TmfExperimentElement) element; + executeCommand = (experiment.getTraces().size() > 0); + } + + if (executeCommand) { + handlerService.executeCommand(OPEN_COMMAND_ID, null); + } + } catch (ExecutionException e) { + Activator.getDefault().logError("Error opening resource " + element.getName(), e); //$NON-NLS-1$ + } catch (NotDefinedException e) { + Activator.getDefault().logError("Error opening resource " + element.getName(), e); //$NON-NLS-1$ + } catch (NotEnabledException e) { + Activator.getDefault().logError("Error opening resource " + element.getName(), e); //$NON-NLS-1$ + } catch (NotHandledException e) { + Activator.getDefault().logError("Error opening resource " + element.getName(), e); //$NON-NLS-1$ + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenAnalysisHelpHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenAnalysisHelpHandler.java new file mode 100644 index 0000000000..f5445cbead --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenAnalysisHelpHandler.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfAnalysisElement; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * Handler for when user wants to open the analysis help text + * + * @author Geneviève Bastien + */ +public class OpenAnalysisHelpHandler extends AbstractHandler { + + private TmfAnalysisElement fAnalysis; + + @Override + public boolean isEnabled() { + // Check if we are closing down + final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return false; + } + + // Get the selection + final IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + final IWorkbenchPart part = page.getActivePart(); + if (part == null) { + return false; + } + final ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); + if (selectionProvider == null) { + return false; + } + final ISelection selection = selectionProvider.getSelection(); + + // Make sure there is only one selection and that it is a trace + fAnalysis = null; + if (selection instanceof TreeSelection) { + final TreeSelection sel = (TreeSelection) selection; + // There should be only one item selected as per the plugin.xml + final Object element = sel.getFirstElement(); + if (element instanceof TmfAnalysisElement) { + fAnalysis = (TmfAnalysisElement) element; + } + } + + return (fAnalysis != null); + } + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + // Check if we are closing down + final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + + // Check that the trace is valid + if (fAnalysis == null) { + return null; + } + + Thread thread = new Thread() { + @Override + public void run() { + displayHelpMsg(fAnalysis.getHelpMessage()); + } + }; + + thread.start(); + + return null; + } + + private static void displayHelpMsg(final String errorMsg) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + /* + * TODO: A message box is not the best place to show help. + * Something should be done with the Eclipse help + */ + final MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()); + mb.setText(Messages.AnalysisModule_Help); + mb.setMessage(errorMsg); + mb.open(); + } + }); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenAnalysisOutputHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenAnalysisOutputHandler.java new file mode 100644 index 0000000000..8362be7968 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenAnalysisOutputHandler.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfAnalysisOutputElement; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * Handler to programatically open a view + * + * @author Geneviève Bastien + */ +public class OpenAnalysisOutputHandler extends AbstractHandler { + + private TmfAnalysisOutputElement fOutputElement; + + @Override + public boolean isEnabled() { + /* Check if we are closing down */ + final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return false; + } + + /* Get the selection */ + final IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + final IWorkbenchPart part = page.getActivePart(); + if (part == null) { + return false; + } + final ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); + if (selectionProvider == null) { + return false; + } + final ISelection selection = selectionProvider.getSelection(); + + /* Make sure there is only one selection and that it is an analysis output */ + fOutputElement = null; + if (selection instanceof TreeSelection) { + final TreeSelection sel = (TreeSelection) selection; + // There should be only one item selected as per the plugin.xml + final Object element = sel.getFirstElement(); + if (element instanceof TmfAnalysisOutputElement) { + fOutputElement = (TmfAnalysisOutputElement) element; + } + } + + return (fOutputElement != null); + } + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + /* Check if we are closing down */ + final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + + /* Check that the view is valid */ + if (fOutputElement == null) { + return null; + } + + fOutputElement.outputAnalysis(); + + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenExperimentHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenExperimentHandler.java new file mode 100644 index 0000000000..ba782e15a3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenExperimentHandler.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Geneviève Bastien - Experiment instantiates with an experiment type + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfOpenTraceHelper; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * OpenExperimentHandler + *

    + */ +public class OpenExperimentHandler extends AbstractHandler { + + private TmfExperimentElement fExperiment = null; + + // ------------------------------------------------------------------------ + // Validation + // ------------------------------------------------------------------------ + + @Override + public boolean isEnabled() { + + // Check if we are closing down + final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return false; + } + + // Get the selection + final IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + final IWorkbenchPart part = page.getActivePart(); + if (part == null) { + return false; + } + final ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); + if (selectionProvider == null) { + return false; + } + final ISelection selection = selectionProvider.getSelection(); + + // Make sure there is only one selection and that it is an experiment + fExperiment = null; + if (selection instanceof TreeSelection) { + final TreeSelection sel = (TreeSelection) selection; + // There should be only one item selected as per the plugin.xml + final Object element = sel.getFirstElement(); + if (element instanceof TmfExperimentElement) { + fExperiment = (TmfExperimentElement) element; + } + } + + // We only enable opening from the Traces folder for now + return ((fExperiment != null) && (fExperiment.getTraces().size() > 0)); + } + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + @Override + public Object execute(final ExecutionEvent event) throws ExecutionException { + + // Check if we are closing down + final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + + // Check that the experiment is valid + if (fExperiment == null) { + return null; + } + + TmfOpenTraceHelper.openTraceFromElement(fExperiment); + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenTraceHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenTraceHandler.java new file mode 100644 index 0000000000..5365993e12 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/OpenTraceHandler.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfOpenTraceHelper; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * OpenTraceHandler + *

    + * TODO: Add support for multiple trace selection + */ +public class OpenTraceHandler extends AbstractHandler { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private TmfTraceElement fTrace = null; + + // ------------------------------------------------------------------------ + // Validation + // ------------------------------------------------------------------------ + + @Override + public boolean isEnabled() { + + // Check if we are closing down + final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return false; + } + + // Get the selection + final IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + final IWorkbenchPart part = page.getActivePart(); + if (part == null) { + return false; + } + final ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); + if (selectionProvider == null) { + return false; + } + final ISelection selection = selectionProvider.getSelection(); + + // Make sure there is only one selection and that it is a trace + fTrace = null; + if (selection instanceof TreeSelection) { + final TreeSelection sel = (TreeSelection) selection; + // There should be only one item selected as per the plugin.xml + final Object element = sel.getFirstElement(); + if (element instanceof TmfTraceElement) { + fTrace = (TmfTraceElement) element; + } + } + + // We only enable opening from the Traces folder for now + return (fTrace != null); + } + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + @Override + public Object execute(final ExecutionEvent event) throws ExecutionException { + + // Check if we are closing down + final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + + // Check that the trace is valid + if (fTrace == null) { + return null; + } + + // If trace is under an experiment, use the original trace from the traces folder + TmfOpenTraceHelper.openTraceFromElement(fTrace.getElementUnderTraceFolder()); + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/RefreshHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/RefreshHandler.java new file mode 100644 index 0000000000..c32b0bf435 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/RefreshHandler.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * RefreshHandler + *

    + * TODO: Handle multiple selections + */ +public class RefreshHandler extends AbstractHandler { + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + + // Get the selection + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + IWorkbenchPart part = page.getActivePart(); + if (part == null) { + return false; + } + ISelection selection = part.getSite().getSelectionProvider().getSelection(); + if (selection instanceof TreeSelection) { + TreeSelection treeSelection = (TreeSelection) selection; + Object element = treeSelection.getFirstElement(); + IResource resource = null; + if (element instanceof TmfTraceFolder) { + TmfTraceFolder folder = (TmfTraceFolder) element; + resource = folder.getResource(); + } + else if (element instanceof TmfExperimentFolder) { + TmfExperimentFolder folder = (TmfExperimentFolder) element; + resource = folder.getResource(); + } + else if (element instanceof TmfExperimentElement) { + TmfExperimentElement folder = (TmfExperimentElement) element; + resource = folder.getResource(); + } + try { + if (resource != null) { + resource.refreshLocal(IResource.DEPTH_INFINITE, null); + } + } catch (CoreException e) { + Activator.getDefault().logError("Error refreshing projects", e); //$NON-NLS-1$ + } + } + + + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/RenameExperimentHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/RenameExperimentHandler.java new file mode 100644 index 0000000000..c97255ae59 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/RenameExperimentHandler.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.wizards.RenameExperimentDialog; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * RenameExperimentHandler + *

    + */ +public class RenameExperimentHandler extends AbstractHandler { + + private TmfExperimentElement fExperiment = null; + + // ------------------------------------------------------------------------ + // isEnabled + // ------------------------------------------------------------------------ + + @Override + public boolean isEnabled() { + + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return false; + } + + // Get the selection + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + IWorkbenchPart part = page.getActivePart(); + if (part == null) { + return false; + } + ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); + if (selectionProvider == null) { + return false; + } + ISelection selection = selectionProvider.getSelection(); + + // Make sure there is only selection and that it is an experiment + fExperiment = null; + if (selection instanceof TreeSelection) { + TreeSelection sel = (TreeSelection) selection; + Object element = sel.getFirstElement(); + if (element instanceof TmfExperimentElement) { + fExperiment = (TmfExperimentElement) element; + } + } + + return (fExperiment != null); + } + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + + // Fire the Rename Experiment dialog + Shell shell = window.getShell(); + RenameExperimentDialog dialog = new RenameExperimentDialog(shell, fExperiment); + dialog.open(); + + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/RenameFolderHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/RenameFolderHandler.java new file mode 100644 index 0000000000..5d41a01da6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/RenameFolderHandler.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.window.Window; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.tracecompass.tmf.ui.project.wizards.RenameFolderDialog; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.WorkspaceModifyOperation; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Handler for the Rename Folder command. + */ +public class RenameFolderHandler extends AbstractHandler { + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + + ISelection selection = HandlerUtil.getCurrentSelection(event); + TmfTraceFolder selectedFolder = null; + if (selection instanceof IStructuredSelection) { + Object element = ((IStructuredSelection) selection).getFirstElement(); + if (element instanceof TmfTraceFolder) { + selectedFolder = (TmfTraceFolder) element; + } + } + if (selectedFolder == null) { + return null; + } + final TmfTraceFolder oldFolder = selectedFolder; + + // Fire the Rename Folder dialog + RenameFolderDialog dialog = new RenameFolderDialog(window.getShell(), oldFolder); + dialog.open(); + + if (dialog.getReturnCode() != Window.OK) { + return null; + } + + final String newName = (String) dialog.getFirstResult(); + + IContainer parentFolder = oldFolder.getResource().getParent(); + final TmfTraceFolder tracesFolder = oldFolder.getProject().getTracesFolder(); + final IPath newFolderPath = parentFolder.getFullPath().append(newName); + + WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { + @Override + public void execute(IProgressMonitor monitor) throws CoreException { + try { + monitor.beginTask("", 1000); //$NON-NLS-1$ + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + + for (TmfTraceElement traceElement : oldFolder.getTraces()) { + traceElement.closeEditors(); + + IPath relativePath = traceElement.getPath().makeRelativeTo(oldFolder.getPath()); + String newElementPath = newFolderPath.makeRelativeTo(tracesFolder.getPath()).append(relativePath).toString(); + traceElement.renameSupplementaryFolder(newElementPath); + } + + oldFolder.getResource().move(newFolderPath, IResource.FORCE | IResource.SHALLOW, monitor); + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + } finally { + monitor.done(); + } + } + }; + + try { + PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); + } catch (InterruptedException e) { + return null; + } catch (InvocationTargetException e) { + MessageDialog.openError(window.getShell(), e.toString(), e.getTargetException().toString()); + return null; + } + + /* We need to split the WorkspaceModifyOperation so that the new model + * elements get created by the resource changed event */ + operation = new WorkspaceModifyOperation() { + @Override + protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException { + + IPath oldFolderElementPath = oldFolder.getPath().makeRelativeTo(tracesFolder.getPath()); + IPath newFolderElementPath = oldFolderElementPath.removeLastSegments(1).append(newName); + for (TmfExperimentElement experiment : oldFolder.getProject().getExperimentsFolder().getExperiments()) { + for (TmfTraceElement oldTrace : experiment.getTraces()) { + if (oldTrace.getElementPath().startsWith(oldFolderElementPath.toString())) { + experiment.removeTrace(oldTrace); + String relativePath = oldTrace.getElementPath().substring(oldFolderElementPath.toString().length() + 1); + String newTraceElementPath = newFolderElementPath.append(relativePath).toString(); + for (TmfTraceElement newTrace : tracesFolder.getTraces()) { + if (newTrace.getElementPath().equals(newTraceElementPath)) { + experiment.addTrace(newTrace); + break; + } + } + } + } + } + } + }; + + try { + PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); + } catch (InterruptedException e) { + return null; + } catch (InvocationTargetException e) { + MessageDialog.openError(window.getShell(), e.toString(), e.getTargetException().toString()); + return null; + } + + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/RenameTraceHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/RenameTraceHandler.java new file mode 100644 index 0000000000..5bca31a41a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/RenameTraceHandler.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Add support for folder elements + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.window.Window; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.tracecompass.tmf.ui.project.wizards.RenameTraceDialog; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.WorkspaceModifyOperation; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Handler for the Rename Trace command. + */ +public class RenameTraceHandler extends AbstractHandler { + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + + ISelection selection = HandlerUtil.getCurrentSelection(event); + TmfTraceElement selectedTrace = null; + if (selection instanceof IStructuredSelection) { + Object element = ((IStructuredSelection) selection).getFirstElement(); + if (element instanceof TmfTraceElement) { + selectedTrace = (TmfTraceElement) element; + } + } + if (selectedTrace == null) { + return null; + } + + // If trace is under an experiment, use the original trace from the traces folder + final TmfTraceElement oldTrace = selectedTrace.getElementUnderTraceFolder(); + + RenameTraceDialog dialog = new RenameTraceDialog(window.getShell(), oldTrace); + if (dialog.open() != Window.OK) { + return null; + } + + final TmfTraceFolder traceFolder = (TmfTraceFolder) oldTrace.getParent(); + final String newName = (String) dialog.getFirstResult(); + + IFolder parentFolder = (IFolder) oldTrace.getParent().getResource(); + final TmfTraceFolder tracesFolder = oldTrace.getProject().getTracesFolder(); + final IPath newPath = parentFolder.getFullPath().append(newName); + + WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { + @Override + public void execute(IProgressMonitor monitor) throws CoreException { + try { + monitor.beginTask("", 1000); //$NON-NLS-1$ + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + // Close the trace if open + oldTrace.closeEditors(); + + if (oldTrace.getResource() instanceof IFolder) { + IFolder folder = (IFolder) oldTrace.getResource(); + IFile bookmarksFile = oldTrace.getBookmarksFile(); + if (bookmarksFile.exists()) { + IFile newBookmarksFile = folder.getFile(bookmarksFile.getName().replace(oldTrace.getName(), newName)); + if (!newBookmarksFile.exists()) { + IPath newBookmarksPath = newBookmarksFile.getFullPath(); + bookmarksFile.move(newBookmarksPath, IResource.FORCE | IResource.SHALLOW, monitor); + } + } + } + + String newElementPath = newPath.makeRelativeTo(tracesFolder.getPath()).toString(); + oldTrace.renameSupplementaryFolder(newElementPath); + oldTrace.getResource().move(newPath, IResource.FORCE | IResource.SHALLOW, monitor); + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + } finally { + monitor.done(); + } + } + }; + + try { + PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); + } catch (InterruptedException e) { + return null; + } catch (InvocationTargetException e) { + MessageDialog.openError(window.getShell(), e.toString(), e.getTargetException().toString()); + return null; + } + + /* We need to split the WorkspaceModifyOperation so that the new model + * elements get created by the resource changed event */ + operation = new WorkspaceModifyOperation() { + @Override + protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException { + + // Locate the new trace object + TmfTraceElement newTrace = null; + String newElementPath = oldTrace.getParent().getPath().append(newName).makeRelativeTo(tracesFolder.getPath()).toString(); + for (TmfTraceElement element : traceFolder.getTraces()) { + if (element.getElementPath().equals(newElementPath)) { + newTrace = element; + break; + } + } + if (newTrace == null) { + return; + } + + TmfExperimentFolder experimentFolder = newTrace.getProject().getExperimentsFolder(); + for (final TmfExperimentElement experiment : experimentFolder.getExperiments()) { + for (final TmfTraceElement expTrace : experiment.getTraces()) { + if (expTrace.getElementPath().equals(oldTrace.getElementPath())) { + experiment.removeTrace(expTrace); + experiment.addTrace(newTrace); + } + } + } + } + }; + + try { + PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); + } catch (InterruptedException e) { + } catch (InvocationTargetException e) { + MessageDialog.openError(window.getShell(), e.toString(), e.getTargetException().toString()); + } + + return null; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/SelectElementTypeContributionItem.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/SelectElementTypeContributionItem.java new file mode 100644 index 0000000000..06959fa6fd --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/SelectElementTypeContributionItem.java @@ -0,0 +1,269 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Geneviève Bastien - Moved SelectTraceTypeContributionItem to this class + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTrace; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTrace; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType.TraceElementType; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceTypeUIUtils; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.CompoundContributionItem; +import org.eclipse.ui.menus.CommandContributionItem; +import org.eclipse.ui.menus.CommandContributionItemParameter; + +/** + * ContributionItem for the element type selection. + * + * @author Patrick Tassé + */ +public class SelectElementTypeContributionItem extends CompoundContributionItem { + + private static final ImageDescriptor SELECTED_ICON = Activator.getDefault().getImageDescripterFromPath("icons/elcl16/bullet.gif"); //$NON-NLS-1$ + private static final String BUNDLE_PARAMETER = "org.eclipse.linuxtools.tmf.ui.commandparameter.select_trace_type.bundle"; //$NON-NLS-1$ + private static final String TYPE_PARAMETER = "org.eclipse.linuxtools.tmf.ui.commandparameter.select_trace_type.type"; //$NON-NLS-1$ + private static final String ICON_PARAMETER = "org.eclipse.linuxtools.tmf.ui.commandparameter.select_trace_type.icon"; //$NON-NLS-1$ + private static final String SELECT_TRACE_TYPE_COMMAND_ID = "org.eclipse.linuxtools.tmf.ui.command.select_trace_type"; //$NON-NLS-1$ + private static final String DEFAULT_TRACE_ICON_PATH = "icons/elcl16/trace.gif"; //$NON-NLS-1$ + + @Override + protected IContributionItem[] getContributionItems() { + + /* + * Fill the selected trace types and verify if selection applies only to + * either traces or experiments + */ + Set selectedTraceTypes = new HashSet<>(); + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + IWorkbenchPage page = window.getActivePage(); + ISelection selection = page.getSelection(); + boolean forTraces = false, forExperiments = false; + if (selection instanceof StructuredSelection) { + for (Object element : ((StructuredSelection) selection).toList()) { + if (element instanceof TmfTraceElement) { + TmfTraceElement trace = (TmfTraceElement) element; + selectedTraceTypes.add(trace.getTraceType()); + forTraces = true; + } else if (element instanceof TmfExperimentElement) { + TmfExperimentElement exp = (TmfExperimentElement) element; + selectedTraceTypes.add(exp.getTraceType()); + forExperiments = true; + } + } + } + + if (forTraces && forExperiments) { + /* This should never happen anyways */ + throw new RuntimeException("You must select only experiments or only traces to set the element type"); //$NON-NLS-1$ + } + + return getContributionItems(selectedTraceTypes, forExperiments); + } + + /** + * Get the contribution items for traces + * + * @param selectedTraceTypes + * The set of selected trace types + * @param forExperiments + * true if the contribution items are requested for + * experiments, false for traces + * + * @return The list of contribution items + */ + protected IContributionItem[] getContributionItems(Set selectedTraceTypes, boolean forExperiments) { + + String ceType = forExperiments ? TmfTraceType.EXPERIMENT_ELEM : TmfTraceType.TYPE_ELEM; + TraceElementType elementType = forExperiments ? TraceElementType.EXPERIMENT : TraceElementType.TRACE; + + List list = new LinkedList<>(); + + Map categoriesMap = new HashMap<>(); + IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor( + TmfTraceType.TMF_TRACE_TYPE_ID); + for (IConfigurationElement ce : config) { + if (ce.getName().equals(TmfTraceType.CATEGORY_ELEM)) { + String categoryId = ce.getAttribute(TmfTraceType.ID_ATTR); + ImageDescriptor icon = isSelectedCategory(categoryId, config, selectedTraceTypes) ? SELECTED_ICON : null; + MenuManager subMenu = new MenuManager(ce.getAttribute(TmfTraceType.NAME_ATTR), icon, null); + categoriesMap.put(categoryId, subMenu); + list.add(subMenu); + } + } + + for (IConfigurationElement ce : config) { + if (ce.getName().equals(ceType)) { + String traceBundle = ce.getContributor().getName(); + String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR); + String label = ce.getAttribute(TmfTraceType.NAME_ATTR).replaceAll("&", "&&"); //$NON-NLS-1$ //$NON-NLS-2$ + boolean selected = selectedTraceTypes.contains(traceTypeId); + MenuManager subMenu = categoriesMap.get(ce.getAttribute(TmfTraceType.CATEGORY_ATTR)); + + /* Get the icon from the tmftracetypeui extension, if it exists */ + String traceIcon = null; + IConfigurationElement uiCE = TmfTraceTypeUIUtils.getTraceUIAttributes(traceTypeId, elementType); + if (uiCE != null) { + traceIcon = uiCE.getAttribute(TmfTraceTypeUIUtils.ICON_ATTR); + } + + addContributionItem(list, traceBundle, traceTypeId, traceIcon, label, selected, subMenu); + } + } + + Comparator comparator = new Comparator() { + @Override + public int compare(IContributionItem o1, IContributionItem o2) { + if (o1 instanceof MenuManager) { + if (o2 instanceof MenuManager) { + MenuManager m1 = (MenuManager) o1; + MenuManager m2 = (MenuManager) o2; + return m1.getMenuText().compareTo(m2.getMenuText()); + } + return -1; + } + if (o2 instanceof MenuManager) { + return 1; + } + CommandContributionItem c1 = (CommandContributionItem) o1; + CommandContributionItem c2 = (CommandContributionItem) o2; + return c1.getData().label.compareTo(c2.getData().label); + } + }; + + if (forExperiments) { + Collections.sort(list, comparator); + return list.toArray(new IContributionItem[list.size()]); + } + + /* + * Add the custom txt and xml trace type to the contribution items for + * traces + */ + for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) { + String traceBundle = Activator.getDefault().getBundle().getSymbolicName(); + String traceTypeId = CustomTxtTrace.class.getCanonicalName() + ':' + def.categoryName + ':' + def.definitionName; + String traceIcon = DEFAULT_TRACE_ICON_PATH; + String label = def.definitionName; + boolean selected = selectedTraceTypes.contains(traceTypeId); + MenuManager subMenu = getCategorySubMenu(list, categoriesMap, def.categoryName, selected); + + addContributionItem(list, traceBundle, traceTypeId, traceIcon, label, selected, subMenu); + } + for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { + String traceBundle = Activator.getDefault().getBundle().getSymbolicName(); + String traceTypeId = CustomXmlTrace.class.getCanonicalName() + ':' + def.categoryName + ':' + def.definitionName; + String traceIcon = DEFAULT_TRACE_ICON_PATH; + String label = def.definitionName; + boolean selected = selectedTraceTypes.contains(traceTypeId); + MenuManager subMenu = getCategorySubMenu(list, categoriesMap, def.categoryName, selected); + + addContributionItem(list, traceBundle, traceTypeId, traceIcon, label, selected, subMenu); + } + + Collections.sort(list, comparator); + return list.toArray(new IContributionItem[list.size()]); + } + + private static MenuManager getCategorySubMenu(List list, + Map categoriesMap, String categoryName, boolean selected) { + for (Entry entry : categoriesMap.entrySet()) { + MenuManager subMenu = entry.getValue(); + if (subMenu.getMenuText().equals(categoryName)) { + if (selected) { + subMenu.setImageDescriptor(SELECTED_ICON); + } + return subMenu; + } + } + ImageDescriptor icon = selected ? SELECTED_ICON : null; + MenuManager subMenu = new MenuManager(categoryName, icon, null); + categoriesMap.put(categoryName, subMenu); + list.add(subMenu); + return subMenu; + } + + private static void addContributionItem(List list, + String traceBundle, String traceTypeId, String traceIcon, + String label, boolean selected, + MenuManager subMenu) { + Map params; + + params = new HashMap<>(); + params.put(BUNDLE_PARAMETER, traceBundle); + params.put(TYPE_PARAMETER, traceTypeId); + params.put(ICON_PARAMETER, traceIcon); + + ImageDescriptor icon = null; + if (selected) { + icon = SELECTED_ICON; + } + + CommandContributionItemParameter param = new CommandContributionItemParameter( + PlatformUI.getWorkbench().getActiveWorkbenchWindow(), // serviceLocator + "my.parameterid", // id //$NON-NLS-1$ + SELECT_TRACE_TYPE_COMMAND_ID, // commandId + CommandContributionItem.STYLE_PUSH // style + ); + param.parameters = params; + param.icon = icon; + param.disabledIcon = icon; + param.hoverIcon = icon; + param.label = label; + param.visibleEnabled = true; + + if (subMenu != null) { + subMenu.add(new CommandContributionItem(param)); + } else { + list.add(new CommandContributionItem(param)); + } + } + + private static boolean isSelectedCategory(String categoryId, IConfigurationElement[] config, Set selectedTraceTypes) { + for (IConfigurationElement ce : config) { + if (ce.getName().equals(TmfTraceType.TYPE_ELEM)) { + String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR); + if (selectedTraceTypes.contains(traceTypeId)) { + if (categoryId.equals(ce.getAttribute(TmfTraceType.CATEGORY_ATTR))) { + return true; + } + } + } + } + return false; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/SelectTraceTypeHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/SelectTraceTypeHandler.java new file mode 100644 index 0000000000..ad5b264199 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/SelectTraceTypeHandler.java @@ -0,0 +1,203 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Fix propagation to experiment traces + * Geneviève Bastien - Add support of experiment types + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfCommonProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceTypeUIUtils; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * SetTraceTypeHandler + *

    + */ +public class SelectTraceTypeHandler extends AbstractHandler { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + private static final String TYPE_PARAMETER = "org.eclipse.linuxtools.tmf.ui.commandparameter.select_trace_type.type"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private TreeSelection fSelection = null; + + // ------------------------------------------------------------------------ + // Validation + // ------------------------------------------------------------------------ + + @Override + public boolean isEnabled() { + + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return false; + } + + // Get the selection + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + IWorkbenchPart part = page.getActivePart(); + if (part == null) { + return false; + } + ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); + if (selectionProvider == null) { + return false; + } + ISelection selection = selectionProvider.getSelection(); + + // Make sure selection contains only traces + fSelection = null; + if (selection instanceof TreeSelection) { + fSelection = (TreeSelection) selection; + Iterator iterator = fSelection.iterator(); + while (iterator.hasNext()) { + Object element = iterator.next(); + if (!(element instanceof TmfCommonProjectElement)) { + return false; + } + } + } + + // If we get here, either nothing is selected or everything is a trace + return !selection.isEmpty(); + } + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + List statuses = new ArrayList<>(); + Set projects = new HashSet<>(); + boolean ok = true; + for (Object element : fSelection.toList()) { + TmfCommonProjectElement trace = (TmfCommonProjectElement) element; + if (trace instanceof TmfTraceElement) { + trace = ((TmfTraceElement) trace).getElementUnderTraceFolder(); + } + IResource resource = trace.getResource(); + if (resource != null) { + try { + // Set the trace type for this resource + String traceType = event.getParameter(TYPE_PARAMETER); + String previousTraceType = trace.getTraceType(); + IStatus status = propagateProperties(trace, traceType); + ok &= status.isOK(); + + if (status.isOK()) { + if ((previousTraceType != null) && (!traceType.equals(previousTraceType))) { + // Close the trace if open + trace.closeEditors(); + // Delete all supplementary resources + trace.deleteSupplementaryResources(); + } + } else { + statuses.add(status); + } + projects.add(trace.getProject()); + } catch (CoreException e) { + Activator.getDefault().logError(Messages.SelectTraceTypeHandler_ErrorSelectingTrace + trace.getName(), e); + } + } + trace.getProject(); + } + for (TmfProjectElement project : projects) { + project.refresh(); + } + + if (!ok) { + final Shell shell = window.getShell(); + MultiStatus info = new MultiStatus(Activator.PLUGIN_ID, 1, Messages.SelectTraceTypeHandler_TraceFailedValidation, null); + if (statuses.size() > 1) + { + info = new MultiStatus(Activator.PLUGIN_ID, 1, Messages.SelectTraceTypeHandler_TracesFailedValidation, null); + } + for (IStatus status : statuses) { + info.add(status); + } + ErrorDialog.openError(shell, Messages.SelectTraceTypeHandler_Title, Messages.SelectTraceTypeHandler_InvalidTraceType, info); + } + return null; + } + + private static IStatus propagateProperties(TmfCommonProjectElement element, String traceType) + throws CoreException { + + TraceTypeHelper traceTypeHelper = TmfTraceType.getTraceType(traceType); + if (traceTypeHelper == null) { + return Status.CANCEL_STATUS; + } + final IStatus validateTraceType = traceTypeHelper.validate(element.getResource().getLocation().toOSString()); + if (!validateTraceType.isOK()) { + return validateTraceType; + } + + IResource resource = element.getResource(); + TmfTraceTypeUIUtils.setTraceType(resource, traceTypeHelper); + + TmfExperimentFolder experimentFolder = element.getProject().getExperimentsFolder(); + for (final TmfExperimentElement experiment : experimentFolder.getExperiments()) { + for (final TmfTraceElement child : experiment.getTraces()) { + if (child.getName().equals(element.getName())) { + TmfTraceTypeUIUtils.setTraceType(child.getResource(), traceTypeHelper); + break; + } + } + } + + return Status.OK_STATUS; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/SelectTracesHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/SelectTracesHandler.java new file mode 100644 index 0000000000..58556c06b2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/SelectTracesHandler.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.wizards.SelectTracesWizard; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * SelectTracesHandler + *

    + */ +public class SelectTracesHandler extends AbstractHandler { + + private TmfExperimentElement fExperiment = null; + + // ------------------------------------------------------------------------ + // Validation + // ------------------------------------------------------------------------ + + @Override + public boolean isEnabled() { + + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return false; + } + + // Get the selection + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + IWorkbenchPart part = page.getActivePart(); + if (part == null) { + return false; + } + ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); + if (selectionProvider == null) { + return false; + } + ISelection selection = selectionProvider.getSelection(); + + // Make sure there is only one selection and that it is an experiment + fExperiment = null; + if (selection instanceof TreeSelection) { + TreeSelection sel = (TreeSelection) selection; + // There should be only one item selected as per the plugin.xml + Object element = sel.getFirstElement(); + if (element instanceof TmfExperimentElement) { + fExperiment = (TmfExperimentElement) element; + } + } + + return (fExperiment != null); + } + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + + // Fire the Select Traces Wizard + IWorkbench workbench = PlatformUI.getWorkbench(); + Shell shell = workbench.getActiveWorkbenchWindow().getShell(); + + TmfExperimentFolder experiments = (TmfExperimentFolder) fExperiment.getParent(); + TmfProjectElement project = (TmfProjectElement) experiments.getParent(); + SelectTracesWizard wizard = new SelectTracesWizard(project, fExperiment); + wizard.init(PlatformUI.getWorkbench(), null); + WizardDialog dialog = new WizardDialog(shell, wizard); + dialog.open(); + + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/SynchronizeTracesHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/SynchronizeTracesHandler.java new file mode 100644 index 0000000000..ca5651c54b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/SynchronizeTracesHandler.java @@ -0,0 +1,279 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.synchronization.SynchronizationAlgorithm; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TraceUtils; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * Handles the synchronization of an experiment, when the user selects this + * option in the menu + */ +public class SynchronizeTracesHandler extends AbstractHandler { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private TreeSelection fSelection = null; + private static final String CR = System.getProperty("line.separator"); //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Validation + // ------------------------------------------------------------------------ + + @Override + public boolean isEnabled() { + return true; + } + + // ------------------------------------------------------------------------ + // Execution + // ------------------------------------------------------------------------ + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + + // Get the selection + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + IWorkbenchPart part = page.getActivePart(); + if (part == null) { + return Boolean.FALSE; + } + ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); + if (selectionProvider == null) { + return Boolean.FALSE; + } + ISelection selection = selectionProvider.getSelection(); + + // Make sure selection contains only traces + fSelection = null; + final ArrayList tl = new ArrayList<>(); + final ArrayList uiexperiment = new ArrayList<>(); + if (selection instanceof TreeSelection) { + fSelection = (TreeSelection) selection; + Iterator iterator = fSelection.iterator(); + while (iterator.hasNext()) { + Object element = iterator.next(); + if (element instanceof TmfTraceElement) { + tl.add((TmfTraceElement) element); + } else if (element instanceof TmfExperimentElement) { + TmfExperimentElement exp = (TmfExperimentElement) element; + uiexperiment.add(exp); + for (TmfTraceElement trace : exp.getTraces()) { + tl.add(trace); + } + } + } + } + + if ((uiexperiment.size() != 1) || (tl.size() < 2)) { + TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, Messages.SynchronizeTracesHandler_WrongTraceNumber); + return null; + } + + Thread thread = new Thread() { + @Override + public void run() { + + final ITmfTrace[] traces = new ITmfTrace[tl.size()]; + final TmfExperimentElement exp = uiexperiment.get(0); + + for (int i = 0; i < tl.size(); i++) { + ITmfTrace trace = tl.get(i).instantiateTrace(); + ITmfEvent traceEvent = tl.get(i).instantiateEvent(); + if (trace == null) { + TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, Messages.SynchronizeTracesHandler_WrongType + tl.get(i).getName()); + for (int j = 0; j < i; j++) { + traces[j].dispose(); + } + return; + } + try { + trace.initTrace(tl.get(i).getResource(), tl.get(i).getResource().getLocation().toOSString(), traceEvent.getClass()); + TmfTraceManager.refreshSupplementaryFiles(trace); + } catch (TmfTraceException e) { + TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, Messages.SynchronizeTracesHandler_InitError + CR + CR + e); + trace.dispose(); + for (int j = 0; j < i; j++) { + traces[j].dispose(); + } + return; + } + traces[i] = trace; + } + + /* + * FIXME Unlike traces, there is no instanceExperiment, so + * we call this function here alone. Maybe it would be + * better to do this on experiment's element constructor? + */ + exp.refreshSupplementaryFolder(); + final TmfExperiment experiment = new TmfExperiment(ITmfEvent.class, exp.getName(), traces, exp.getResource()); + + final SynchronizationAlgorithm syncAlgo = experiment.synchronizeTraces(true); + TmfTraceManager.refreshSupplementaryFiles(experiment); + + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + List tracesToAdd = new ArrayList<>(); + List tracesToRemove = new ArrayList<>(); + /* + * For each trace in the experiment, if there is + * a transform equation, copy the original + * trace, so that a new state system will be + * generated with sync time. + */ + for (TmfTraceElement traceel : tl) { + /* + * Find the trace corresponding to this + * element in the experiment + */ + ITmfTrace expTrace = null; + for (ITmfTrace t : experiment.getTraces()) { + if (t.getResource().equals(traceel.getResource())) { + expTrace = t; + break; + } + } + if ((expTrace != null) && syncAlgo.isTraceSynced(expTrace.getHostId())) { + + /* Find the original trace */ + TmfTraceElement origtrace = traceel.getElementUnderTraceFolder(); + + /* + * Make sure a trace with the + * new name does not exist + */ + String newname = traceel.getName(); + IContainer parentFolder = origtrace.getResource().getParent(); + boolean traceexists; + do { + traceexists = false; + newname += "_"; //$NON-NLS-1$ + if (parentFolder.findMember(newname) != null) { + traceexists = true; + } + } while (traceexists); + + /* Copy the original trace */ + TmfTraceElement newtrace = origtrace.copy(newname); + if (newtrace == null) { + TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, + Messages.SynchronizeTracesHandler_Error + CR + CR + String.format(Messages.SynchronizeTracesHandler_CopyProblem, origtrace.getName())); + continue; + } + + /* + * Instantiate the new trace + * and set its sync formula + */ + ITmfTrace trace = newtrace.instantiateTrace(); + ITmfEvent traceEvent = newtrace.instantiateEvent(); + + try { + trace.initTrace(newtrace.getResource(), newtrace.getResource().getLocation().toOSString(), traceEvent.getClass()); + } catch (TmfTraceException e) { + Activator.getDefault().logError(String.format(Messages.SynchronizeTracesHandler_ErrorSynchingForTrace, exp.getName(), traceel.getName()), e); + TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, Messages.SynchronizeTracesHandler_Error + CR + CR + e.getMessage()); + } + trace.setTimestampTransform(syncAlgo.getTimestampTransform(trace)); + TmfTraceManager.refreshSupplementaryFiles(trace); + trace.dispose(); + + tracesToAdd.add(newtrace); + tracesToRemove.add(traceel); + } + } + experiment.dispose(); + + // Move synchronization file temporarily so that + // it doesn't get deleted by the experiment change + IFolder tmpFolder = exp.getTraceSupplementaryFolder(exp.getName() + '.' + experiment.getSynchronizationFolder(false)); + IResource syncFile = null; + for (IResource resource : exp.getSupplementaryResources()) { + if (resource.getName().equals(experiment.getSynchronizationFolder(false))) { + try { + resource.move(tmpFolder.getFullPath(), false, null); + syncFile = resource; + break; + } catch (CoreException e) { + Activator.getDefault().logError(String.format(Messages.SynchronizeTracesHandler_ErrorSynchingExperiment, exp.getName()), e); + } + } + } + + for (TmfTraceElement trace : tracesToRemove) { + try { + exp.removeTrace(trace); + } catch (CoreException e) { + Activator.getDefault().logError(String.format(Messages.SynchronizeTracesHandler_ErrorSynchingForTrace, exp.getName(), trace.getName()), e); + TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, Messages.SynchronizeTracesHandler_Error + CR + CR + e.getMessage()); + } + } + for (TmfTraceElement trace : tracesToAdd) { + exp.addTrace(trace); + } + + // Move synchronization file back + if (tmpFolder.exists() && syncFile != null) { + try { + tmpFolder.move(syncFile.getFullPath(), false, null); + } catch (CoreException e) { + Activator.getDefault().logError(String.format(Messages.SynchronizeTracesHandler_ErrorSynchingExperiment, exp.getName()), e); + } + } + } + }); + } + }; + thread.start(); + + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/TmfActionProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/TmfActionProvider.java new file mode 100644 index 0000000000..0ddd7eb8ae --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/TmfActionProvider.java @@ -0,0 +1,81 @@ +/******************************************************************************* +* Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import org.eclipse.core.resources.IFile; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.actions.OpenWithMenu; +import org.eclipse.ui.navigator.CommonActionProvider; +import org.eclipse.ui.navigator.ICommonActionConstants; +import org.eclipse.ui.navigator.ICommonActionExtensionSite; +import org.eclipse.ui.navigator.ICommonMenuConstants; +import org.eclipse.ui.navigator.ICommonViewerSite; +import org.eclipse.ui.navigator.ICommonViewerWorkbenchSite; + +/** + * Base action provider. + * + * @author Patrick Tassé + */ +public class TmfActionProvider extends CommonActionProvider { + + private OpenAction openAction; + + private IWorkbenchPage page; + + /** + * Default constructor + */ + public TmfActionProvider() { + } + + @Override + public void init(ICommonActionExtensionSite aSite) { + ICommonViewerSite viewSite = aSite.getViewSite(); + if (viewSite instanceof ICommonViewerWorkbenchSite) { + ICommonViewerWorkbenchSite workbenchSite = (ICommonViewerWorkbenchSite) viewSite; + page = workbenchSite.getPage(); + openAction = new OpenAction(page, workbenchSite.getSelectionProvider()); + } + } + + @Override + public void fillContextMenu(IMenuManager menu) { + ISelection selection = getContext().getSelection(); + if (selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection) selection; + if (structuredSelection.size() == 1 && structuredSelection.getFirstElement() instanceof TmfTraceElement) { + TmfTraceElement traceElement = (TmfTraceElement) structuredSelection.getFirstElement(); + if (traceElement.getResource() instanceof IFile) { + MenuManager openWithMenu = new MenuManager(Messages.TmfActionProvider_OpenWith); + openWithMenu.add(new OpenWithMenu(page, traceElement.getResource())); + menu.insertAfter(ICommonMenuConstants.GROUP_OPEN_WITH, openWithMenu); + } + } + } + } + + @Override + public void fillActionBars(IActionBars actionBars) { + if (openAction.isEnabled()) { + actionBars.setGlobalActionHandler(ICommonActionConstants.OPEN, openAction); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/TracePropertyTester.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/TracePropertyTester.java new file mode 100644 index 0000000000..51fb8dfb15 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/TracePropertyTester.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; + +import java.util.Iterator; + +import org.eclipse.core.expressions.PropertyTester; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; + +/** + * TracePropertyTester + *

    + */ +public class TracePropertyTester extends PropertyTester { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + private final static String IS_IN_TRACE_FOLDER = "isInTraceFolder"; //$NON-NLS-1$ + private final static String IS_EXPERIMENT_TRACE = "isExperimentTrace"; //$NON-NLS-1$ + private final static String HAS_SUPPLEMENTARY_FILES = "hasSupplementaryFiles"; //$NON-NLS-1$ + private final static String TRACE_TYPE = "traceType"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + public TracePropertyTester() { + } + + // ------------------------------------------------------------------------ + // IPropertyTester + // ------------------------------------------------------------------------ + + @Override + public boolean test(Object receiver, String property, Object[] args, Object expectedValue) { + + // Check if the selected elements are in the trace folder + if (IS_IN_TRACE_FOLDER.equals(property)) { + if (receiver != null && receiver instanceof IStructuredSelection) { + Iterator iter = ((IStructuredSelection) receiver).iterator(); + while (iter.hasNext()) { + Object item = iter.next(); + if (item instanceof TmfTraceElement) { + TmfTraceElement trace = (TmfTraceElement) item; + if (!(trace.getParent() instanceof TmfTraceFolder)) { + return false; + } + } else { + return false; + } + } + return true; + } + } + + // Check if the parent of a trace element is an experiment + if (IS_EXPERIMENT_TRACE.equals(property)) { + if (receiver != null && receiver instanceof TmfTraceElement) { + TmfTraceElement trace = (TmfTraceElement) receiver; + return trace.getParent() instanceof TmfExperimentElement; + } + return false; + } + + // Check if traces has supplementary files + if (HAS_SUPPLEMENTARY_FILES.equals(property)) { + if (receiver == null) { + return false; + } + + if (receiver instanceof TmfTraceElement) { + TmfTraceElement trace = (TmfTraceElement) receiver; + return trace.hasSupplementaryResources(); + } else if (receiver instanceof TmfExperimentElement) { + TmfExperimentElement trace = (TmfExperimentElement) receiver; + boolean hasHistory = false; + for (TmfTraceElement aTrace : trace.getTraces()) { + hasHistory |= aTrace.hasSupplementaryResources(); + } + hasHistory |= trace.hasSupplementaryResources(); + return hasHistory; + } + return false; + } + + // Check if the trace element is of a specific trace type + if (TRACE_TYPE.equals(property)) { + if (receiver != null && receiver instanceof TmfTraceElement) { + TmfTraceElement trace = (TmfTraceElement) receiver; + if (expectedValue instanceof String && expectedValue.equals(trace.getTraceType())) { + return true; + } + } + return false; + } + + return false; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/messages.properties new file mode 100644 index 0000000000..95ab3da1f3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/handlers/messages.properties @@ -0,0 +1,70 @@ +############################################################################### +# Copyright (c) 2013, 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### + +# Delete message +DeleteDialog_Title = Confirm Delete +DeleteTraceHandler_Message = Are you sure you want to delete the selected trace(s)? +DeleteTraceHandler_Error = Error deleting trace +DeleteTraceHandler_TaskName = Deleting trace +RemoveDialog_Title = Confirm Remove +RemoveTraceFromExperimentHandler_Message = Are you sure you want to remove the selected trace(s)? +RemoveTraceFromExperimentHandler_TaskName = Removing trace +RemoveTraceFromExperimentHandler_Error = Error removing trace +DeleteExperimentHandler_Message = Are you sure you want to delete this experiment? +DeleteExperimentHandler_Error = Error deleting experiment +DeleteFolderHandler_Message = Are you sure you want to delete the selected folder(s)? +DeleteFolderHandler_Error = Error deleting folder +DeleteFolderHandler_TaskName = Deleting folder +DeleteTraceHandlerGeneric_Message = Are you sure you want to delete the selected elements? +DeleteTraceHandlerGeneric_Error= Error deleting elements + +# Clear message +ClearDialog_Title = Confirm Clear +DeleteFolderHandlerClear_TaskName = Clearing folder +DeleteFolderHandlerClear_Message = Are you sure you want to clear the selected folder(s)? +DeleteFolderHandlerClear_Error = Error clearing folder + +# Set Trace Type +SelectTraceTypeHandler_ErrorSelectingTrace=Error selecting trace type for trace +SelectTraceTypeHandler_Title = Validation Error +SelectTraceTypeHandler_TraceFailedValidation=A trace has failed validation +SelectTraceTypeHandler_TracesFailedValidation=Several trace files failed validation +SelectTraceTypeHandler_InvalidTraceType = Type could not be set for one or more traces + +# Drag and drop +DropAdapterAssistant_RenameTraceTitle=Confirm rename trace +DropAdapterAssistant_RenameTraceMessage=An element with the name ''{0}'' already exists in the target folder.\nRename the dropped trace? + +# Trace synchronization +SynchronizeTracesHandler_InitError=Error initializing trace +SynchronizeTracesHandler_CopyProblem=Couldn't copy the original trace %s +SynchronizeTracesHandler_WrongTraceNumber=Experiment must have more than one trace +SynchronizeTracesHandler_Title=Synchronize traces +SynchronizeTracesHandler_WrongType=Trace is not a kernel trace:\n +SynchronizeTracesHandler_Error=Error synchronizing experiment + +SynchronizeTracesHandler_ErrorSynchingExperiment=Error synchronizing experiment %s +SynchronizeTracesHandler_ErrorSynchingForTrace=Error synchronizing experiment %s for trace %s + +ClearTraceOffsetHandler_Title=Clear time offset +ClearTraceOffsetHandler_ConfirmMessage=Are you sure you want to clear the time offset for the selected trace(s)? + +# Delete Supplementary Files messages +DeleteSupplementaryFiles_DeletionTask=Deleting supplementary files for {0} +DeleteSupplementaryFiles_ProjectRefreshTask=Refreshing project {0} + + +# Analysis modules +AnalysisModule_Help=Help + +# TMF Action Provider +TmfActionProvider_OpenWith=Open With diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/model/TmfEditorLinkHelper.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/model/TmfEditorLinkHelper.java new file mode 100644 index 0000000000..94a517403c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/model/TmfEditorLinkHelper.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.internal.tmf.ui.project.model; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; +import org.eclipse.tracecompass.tmf.core.trace.TmfTrace; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.ide.ResourceUtil; +import org.eclipse.ui.navigator.ILinkHelper; +import org.eclipse.ui.part.FileEditorInput; + +/** + * Implementation of ILinkHelper interface for linking with editor extension for traces and + * experiments. + * + * @author Bernd Hufmann + */ +public class TmfEditorLinkHelper implements ILinkHelper { + + @Override + public IStructuredSelection findSelection(IEditorInput anInput) { + IFile file = ResourceUtil.getFile(anInput); + if (file != null) { + + try { + // Get the trace type ID + String traceTypeId = file.getPersistentProperty(TmfCommonConstants.TRACETYPE); + if (traceTypeId == null) { + return StructuredSelection.EMPTY; + } + + final TmfProjectElement project = TmfProjectRegistry.getProject(file.getProject(), true); + + // Check for experiments, traces which are folders or traces which are files + if (traceTypeId.equals(TmfExperiment.class.getCanonicalName())) { + // Case 1: Experiment + for (final TmfExperimentElement experimentElement : project.getExperimentsFolder().getExperiments()) { + if (experimentElement.getResource().equals(file.getParent())) { + return new StructuredSelection(experimentElement); + } + } + } else if (traceTypeId.equals(TmfTrace.class.getCanonicalName())) { + // Case 2: Trace that is a folder + for (final TmfTraceElement traceElement : project.getTracesFolder().getTraces()) { + if (traceElement.getResource().equals(file.getParent())) { + return new StructuredSelection(traceElement); + } + } + } else { + // Case 3: Trace that is a file + for (final TmfTraceElement traceElement : project.getTracesFolder().getTraces()) { + if (traceElement.getResource().equals(file)) { + return new StructuredSelection(traceElement); + } + } + } + } catch (CoreException e) { + return StructuredSelection.EMPTY; + } + } + return StructuredSelection.EMPTY; + } + + @Override + public void activateEditor(IWorkbenchPage aPage, IStructuredSelection aSelection) { + if (aSelection == null || aSelection.isEmpty()) { + return; + } + + IFile file = null; + + if ((aSelection.getFirstElement() instanceof TmfTraceElement)) { + TmfTraceElement traceElement = ((TmfTraceElement)aSelection.getFirstElement()); + + // If trace is under an experiment, use the original trace from the traces folder + traceElement = traceElement.getElementUnderTraceFolder(); + file = traceElement.getBookmarksFile(); + } else if ((aSelection.getFirstElement() instanceof TmfExperimentElement)) { + TmfExperimentElement experimentElement = (TmfExperimentElement) aSelection.getFirstElement(); + file = experimentElement.getBookmarksFile(); + } + + if (file != null) { + IEditorInput tmpInput = new FileEditorInput(file); + IEditorPart localEditor = aPage.findEditor(tmpInput); + if (localEditor != null) { + // Editor found. + aPage.bringToTop(localEditor); + } else { + // Search in references for corresponding editor + IEditorReference[] refs = aPage.getEditorReferences(); + for (IEditorReference editorReference : refs) { + try { + if (editorReference.getEditorInput().equals(tmpInput)) { + localEditor = editorReference.getEditor(true); + if (localEditor != null) { + aPage.bringToTop(localEditor); + } + } + } catch (PartInitException e) { + // Ignore + } + } + } + } + } +} + diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/model/TmfImportHelper.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/model/TmfImportHelper.java new file mode 100644 index 0000000000..24ea161dc1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/model/TmfImportHelper.java @@ -0,0 +1,76 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + **********************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.model; + +import java.io.File; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; + +/** + * Import helper used to import traces + * + * It has two purposes: - import files and directories into projects - set the + * resource types + * + * @author Matthew Khouzam + */ +public class TmfImportHelper { + + /** + * Create a link and replace what was already there. + * + * @param parentFolder + * the resource to import to, does not contain the element name + * @param location + * where the resource (file/directory) is located + * @param targetName + * the name to display + * @return the resource created. Should not be null + * @throws CoreException + * an exception made by createLink. + */ + public static IResource createLink(IFolder parentFolder, IPath location, String targetName) throws CoreException { + File source = new File(location.toString()); + IResource res = null; + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + if (source.isDirectory()) { + IFolder folder = parentFolder.getFolder(targetName); + IStatus result = workspace.validateLinkLocation(folder, location); + if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) { + folder.createLink(location, IResource.REPLACE, new NullProgressMonitor()); + } else { + Activator.getDefault().logError(result.getMessage()); + } + } else { + IFile file = parentFolder.getFile(targetName); + IStatus result = workspace.validateLinkLocation(file, location); + if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) { + file.createLink(location, IResource.REPLACE, + new NullProgressMonitor()); + } else { + Activator.getDefault().logError(result.getMessage()); + } + } + res = parentFolder.findMember(targetName); + return res; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/operations/TmfWorkspaceModifyOperation.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/operations/TmfWorkspaceModifyOperation.java new file mode 100644 index 0000000000..9f45de0e29 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/operations/TmfWorkspaceModifyOperation.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.internal.tmf.ui.project.operations; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.ui.actions.WorkspaceModifyOperation; + +/** + * Operation to modify the workspace that refreshes workspace at the end of the operation. + * + * For refreshing periodically use {@link WorkspaceModifyOperation} instead. + * + * @author Bernd Hufmann + * + */ +public abstract class TmfWorkspaceModifyOperation implements IRunnableWithProgress { + + private ISchedulingRule rule; + + /** + * Creates a new operation. + */ + protected TmfWorkspaceModifyOperation() { + this(ResourcesPlugin.getWorkspace().getRoot()); + } + + /** + * Creates a new operation that will run using the provided scheduling rule. + * + * @param rule + * The ISchedulingRule to use or null. + */ + protected TmfWorkspaceModifyOperation(ISchedulingRule rule) { + this.rule = rule; + } + + @Override + public synchronized final void run(IProgressMonitor monitor) + throws InvocationTargetException, InterruptedException { + final InvocationTargetException[] iteHolder = new InvocationTargetException[1]; + try { + IWorkspaceRunnable workspaceRunnable = new IWorkspaceRunnable() { + @Override + public void run(IProgressMonitor pm) throws CoreException { + try { + execute(pm); + } catch (InvocationTargetException e) { + // Pass it outside the workspace runnable + iteHolder[0] = e; + } catch (InterruptedException e) { + // Re-throw as OperationCanceledException, which will be + // caught and re-thrown as InterruptedException below. + throw new OperationCanceledException(e.getMessage()); + } + // CoreException and OperationCanceledException are propagated + } + }; + + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + workspace.run(workspaceRunnable, rule, IWorkspace.AVOID_UPDATE, monitor); + } catch (CoreException e) { + throw new InvocationTargetException(e); + } catch (OperationCanceledException e) { + throw new InterruptedException(e.getMessage()); + } + // Re-throw the InvocationTargetException, if any occurred + if (iteHolder[0] != null) { + throw iteHolder[0]; + } + } + + /** + * Performs the steps that are to be treated as a single logical workspace + * change. + *

    + * Subclasses must implement this method. + *

    + * + * @param monitor + * the progress monitor to use to display progress and field user + * requests to cancel + * @exception CoreException + * if the operation fails due to a CoreException + * @exception InvocationTargetException + * if the operation fails due to an exception other than + * CoreException + * @exception InterruptedException + * if the operation detects a request to cancel, using + * IProgressMonitor.isCanceled(), it should exit + * by throwing InterruptedException. It is also + * possible to throw OperationCanceledException, + * which gets mapped to InterruptedException by + * the run method. + */ + protected abstract void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException; +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/AbstractImportTraceWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/AbstractImportTraceWizardPage.java new file mode 100644 index 0000000000..4b6d68d2f8 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/AbstractImportTraceWizardPage.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.tracecompass.tmf.core.TmfProjectNature; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTracesFolder; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.dialogs.WizardResourceImportPage; + +/** + * The abstract import trace wizard page, the base for the import trace wizard + * pages. + * + * @author Matthew Khouzam + * @since 2.0 + */ +abstract class AbstractImportTraceWizardPage extends WizardResourceImportPage { + + /** + * Import String + */ + protected static final String BATCH_IMPORT_WIZARD_PAGE = "BatchImportWizardPage"; //$NON-NLS-1$ + + /** + * The trace folder, something like "//Traces/" + */ + protected IFolder fTargetFolder; + + /** + * The project "/" + */ + protected IProject fProject; + + /** + * The batch import trace wizard (parent) + */ + private BatchImportTraceWizard fBatchImportTraceWizard; + + /** + * @param name + * the name of the page + * @param selection + * The current selection + */ + protected AbstractImportTraceWizardPage(String name, IStructuredSelection selection) { + super(name, selection); + } + + /** + * Constructor + * + * @param workbench + * The workbench reference. + * @param selection + * The current selection + */ + public AbstractImportTraceWizardPage(IWorkbench workbench, IStructuredSelection selection) { + this(BATCH_IMPORT_WIZARD_PAGE, selection); + setTitle(null); + setDescription(null); + + // Locate the target trace folder + IFolder traceFolder = null; + Object element = selection.getFirstElement(); + + if (element instanceof TmfTraceFolder) { + TmfTraceFolder tmfTraceFolder = (TmfTraceFolder) element; + fProject = (tmfTraceFolder.getProject().getResource()); + traceFolder = tmfTraceFolder.getResource(); + } else if (element instanceof IProject) { + IProject project = (IProject) element; + try { + if (project.hasNature(TmfProjectNature.ID)) { + traceFolder = (IFolder) project.findMember(TmfTracesFolder.TRACES_FOLDER_NAME); + } + } catch (CoreException e) { + } + } + + // Set the target trace folder + if (traceFolder != null) { + fTargetFolder = (traceFolder); + String path = traceFolder.getFullPath().toOSString(); + setContainerFieldValue(path); + } + + } + + /** + * The Batch Import Wizard + * + * @return the Batch Import Wizard + */ + public BatchImportTraceWizard getBatchWizard() { + return fBatchImportTraceWizard; + } + + @Override + public void createControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NULL); + composite.setLayout(new GridLayout()); + composite.setFont(parent.getFont()); + // arbitrary size + final GridData layoutData = new GridData(); + parent.getShell().setLayoutData(layoutData); + parent.getShell().redraw(); + this.setControl(composite); + + // arbitrary sizes + parent.getShell().setMinimumSize(new Point(525, 400)); + fBatchImportTraceWizard = (BatchImportTraceWizard) getWizard(); + } + + // the following methods are stubbed out on purpose. + + @Override + protected void createSourceGroup(Composite parent) { + // do nothing + } + + @Override + protected ITreeContentProvider getFileProvider() { + // do nothing + return null; + } + + @Override + protected ITreeContentProvider getFolderProvider() { + // do nothing + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/BatchImportTraceWizard.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/BatchImportTraceWizard.java new file mode 100644 index 0000000000..88a8bc0875 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/BatchImportTraceWizard.java @@ -0,0 +1,699 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Marc-Andre Laperle - Log some exceptions + * Patrick Tasse - Add support for source location + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace; + +import java.io.File; +import java.io.FileInputStream; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import java.util.concurrent.BlockingQueue; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.project.model.TmfImportHelper; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; +import org.eclipse.tracecompass.tmf.core.project.model.TraceValidationHelper; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceTypeUIUtils; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.dialogs.IOverwriteQuery; +import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider; +import org.eclipse.ui.wizards.datatransfer.ImportOperation; + +/** + * Batch Import trace wizard. + * + * @author Matthew Khouzam + * @since 2.0 + */ +public class BatchImportTraceWizard extends ImportTraceWizard { + + private static final int WIN_HEIGHT = 400; + private static final int WIN_WIDTH = 800; + private static final Status CANCEL_STATUS = new Status(IStatus.CANCEL, Activator.PLUGIN_ID, ""); //$NON-NLS-1$ + private static final int TOTALWORK = 65536; + // ----------------- + // Constants + // ----------------- + + private static final int MAX_FILES = TOTALWORK - 1; + private static final String BATCH_IMPORT_WIZARD = "BatchImportTraceWizard"; //$NON-NLS-1$ + + // ------------------ + // Fields + // ------------------ + + private IWizardPage fSelectDirectoriesPage; + private ImportTraceWizardScanPage fScanPage; + private IWizardPage fSelectTypePage; + private IWizardPage fOptions; + + private final List fTraceTypesToScan = new ArrayList<>(); + private final Set fParentFilesToScan = new HashSet<>(); + + private ImportTraceContentProvider fScannedTraces = new ImportTraceContentProvider(fTraceTypesToScan, fParentFilesToScan); + + private final Map fResults = new HashMap<>(); + private boolean fOverwrite = true; + private boolean fLinked = true; + + private BlockingQueue fTracesToScan; + private final Set fTraces = new TreeSet<>(); + + private Map> fParentFiles = new HashMap<>(); + + // Target import directory (trace folder) + private IFolder fTargetFolder; + + /** + * Returns the ScannedTraces model + * + * @return the ScannedTraces model + */ + public ImportTraceContentProvider getScannedTraces() { + return fScannedTraces; + } + + /** + * Constructor + */ + public BatchImportTraceWizard() { + IDialogSettings workbenchSettings = Activator.getDefault().getDialogSettings(); + IDialogSettings section = workbenchSettings.getSection(BATCH_IMPORT_WIZARD); + if (section == null) { + section = workbenchSettings.addNewSection(BATCH_IMPORT_WIZARD); + } + setDialogSettings(section); + setNeedsProgressMonitor(true); + } + + @Override + public void init(IWorkbench workbench, IStructuredSelection selection) { + + fSelectDirectoriesPage = new ImportTraceWizardSelectDirectoriesPage(workbench, selection); + fScanPage = new ImportTraceWizardScanPage(workbench, selection); + fSelectTypePage = new ImportTraceWizardSelectTraceTypePage(workbench, selection); + fOptions = new ImportTraceWizardPageOptions(workbench, selection); + // keep in case it's called later + Iterator iter = selection.iterator(); + while (iter.hasNext()) { + Object selected = iter.next(); + if (selected instanceof TmfTraceFolder) { + fTargetFolder = ((TmfTraceFolder) selected).getResource(); + break; + } + } + fResults.clear(); + } + + @Override + public void addPages() { + addPage(fSelectTypePage); + addPage(fSelectDirectoriesPage); + addPage(fScanPage); + addPage(fOptions); + final WizardDialog container = (WizardDialog) getContainer(); + if (container != null) { + container.setPageSize(WIN_WIDTH, WIN_HEIGHT); + } + } + + /** + * Add a file to scan + * + * @param fileName + * the file to scan + */ + public void addFileToScan(final String fileName) { + String absolutePath = new File(fileName).getAbsolutePath(); + if (!fParentFiles.containsKey(absolutePath)) { + fParentFiles.put(absolutePath, new HashSet()); + startUpdateTask(Messages.BatchImportTraceWizardAdd + ' ' + absolutePath, absolutePath); + + } + + } + + /** + * Remove files from selection + * + * @param fileName + * the name of the file to remove + */ + public void removeFile(final String fileName) { + fParentFiles.remove(fileName); + fParentFilesToScan.remove(fileName); + startUpdateTask(Messages.BatchImportTraceWizardRemove + ' ' + fileName, null); + } + + private void startUpdateTask(final String taskName, final String fileAbsolutePath) { + try { + this.getContainer().run(true, true, new IRunnableWithProgress() { + + @Override + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + synchronized (BatchImportTraceWizard.this) { // this should + // only run one + // at a time + SubMonitor sm; + sm = SubMonitor.convert(monitor); + sm.setTaskName(taskName); + sm.setWorkRemaining(TOTALWORK); + updateFiles(sm, fileAbsolutePath); + sm.done(); + } + } + }); + } catch (InvocationTargetException e) { + Activator.getDefault().logError(Messages.ImportTraceWizardImportProblem, e); + } catch (InterruptedException e) { + } + } + + /** + * The set of names of the selected files + * + * @return the set of names of the selected files + */ + public Set getFileNames() { + return fParentFilesToScan; + } + + /** + * Reset the trace list to import + */ + public void clearTraces() { + fTraces.clear(); + } + + @Override + public boolean performFinish() { + if (fTraces.isEmpty()) { + return false; + } + // if this turns out to be too slow, put in a progress monitor. Does not + // appear to be slow for the moment. + boolean success = importTraces(); + return success; + } + + private boolean importTraces() { + boolean success = false; + IOverwriteQuery overwriteQuery = new IOverwriteQuery() { + @Override + public String queryOverwrite(String file) { + return fOverwrite ? IOverwriteQuery.ALL : IOverwriteQuery.NO_ALL; + } + }; + FileSystemStructureProvider fileSystemStructureProvider = FileSystemStructureProvider.INSTANCE; + + for (FileAndName traceToImport : fTraces) { + try { + if (fLinked) { + if (TmfImportHelper.createLink(fTargetFolder, Path.fromOSString(traceToImport.getFile().getAbsolutePath()), traceToImport.getName()) == null) { + success = false; + } + else { + success = setTraceTypeAndSourceLocation(traceToImport).isOK(); + } + } + else { + List subList = new ArrayList<>(); + IPath path = fTargetFolder.getFullPath(); + File parentFile = traceToImport.getFile(); + final boolean isFile = parentFile.isFile(); + if (isFile) { + IFile resource = ResourcesPlugin.getWorkspace().getRoot().getFile(path.append(traceToImport.getName())); + if (fOverwrite || !resource.exists()) { + subList.add(parentFile); + parentFile = parentFile.getParentFile(); + try (final FileInputStream source = new FileInputStream(traceToImport.getFile());) { + if (resource.exists()) { + resource.delete(IResource.FORCE, new NullProgressMonitor()); + } + resource.create(source, true, new NullProgressMonitor()); + } + setTraceTypeAndSourceLocation(traceToImport); + success = true; + } + } else { + path = path.addTrailingSeparator().append(traceToImport.getName()); + // Add all files in trace directory + File[] fileList = traceToImport.getFile().listFiles(); + for (File child : fileList) { + subList.add(child); + } + + Collections.sort(subList, new Comparator() { + @Override + public int compare(File o1, File o2) { + return o1.getAbsolutePath().compareTo(o2.getAbsolutePath()); + } + }); + ImportOperation operation = new ImportOperation( + path, + parentFile, + fileSystemStructureProvider, + overwriteQuery, + subList); + operation.setContext(getShell()); + operation.setCreateContainerStructure(false); + if (executeImportOperation(operation)) { + setTraceTypeAndSourceLocation(traceToImport); + success = true; + } + } + + } + } catch (Exception e) { + } + } + return success; + } + + private IStatus setTraceTypeAndSourceLocation(FileAndName traceToImport) { + IStatus status = Status.OK_STATUS; + IResource resource = fTargetFolder.findMember(traceToImport.getName()); + if (resource != null) { + try { + // Set the trace type for this resource + String traceTypeId = traceToImport.getTraceTypeId(); + TraceTypeHelper traceType = TmfTraceType.getTraceType(traceTypeId); + if (traceType != null) { + status = TmfTraceTypeUIUtils.setTraceType(resource, traceType); + } + + // Set the source location for this resource + File file = traceToImport.getFile(); + String sourceLocation = null; + IResource sourceResource; + if (file.isDirectory()) { + sourceResource = ResourcesPlugin.getWorkspace().getRoot().getContainerForLocation(Path.fromOSString(file.getAbsolutePath())); + } else { + sourceResource = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(Path.fromOSString(file.getAbsolutePath())); + } + if (sourceResource != null && sourceResource.exists()) { + sourceLocation = sourceResource.getPersistentProperty(TmfCommonConstants.SOURCE_LOCATION); + } + if (sourceLocation == null) { + sourceLocation = URIUtil.toUnencodedString(file.toURI()); + } + resource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation); + } catch (CoreException e) { + Activator.getDefault().logError(Messages.BatchImportTraceWizardErrorImportingTraceResource + + ' ' + resource.getName(), e); + } + } + return status; + } + + @Override + public boolean canFinish() { + return super.canFinish() && hasTracesToImport() && !hasConflicts() && (fTargetFolder != null); + } + + /** + * Returns if a trace to import is selected + * + * @return if there are traces to import + */ + public boolean hasTracesToImport() { + return fTraces.size() > 0; + } + + /** + * Reset the files to scan + */ + public void clearFilesToScan() { + fTracesToScan.clear(); + } + + /** + * Set the trace types to scan + * + * @param tracesToScan + * a list of trace types to scan for + */ + public void setTraceTypesToScan(List tracesToScan) { + // intersection to know if there's a diff. + // if there's a diff, we need to re-enque everything + List added = new ArrayList<>(); + for (String traceLoc : tracesToScan) { + if (!fTraceTypesToScan.contains(traceLoc)) { + added.add(traceLoc); + } + } + fTraceTypesToScan.clear(); + fTraceTypesToScan.addAll(tracesToScan); + updateTracesToScan(added); + } + + /** + * Get the trace types to scan + * + * @return a list of traces to Scan for + */ + public List getTraceTypesToScan() { + return fTraceTypesToScan; + } + + /** + * Add files to Import + * + * @param element + * add the file and tracetype to import + */ + public void addFileToImport(FileAndName element) { + fTraces.add(element); + updateConflicts(); + } + + /** + * Remove the file to scan + * + * @param element + * the element to remove + */ + public void removeFileToImport(FileAndName element) { + fTraces.remove(element); + element.setConflictingName(false); + updateConflicts(); + } + + /** + * Updates the trace to see if there are conflicts. + */ + public void updateConflicts() { + final FileAndName[] fChildren = fTraces.toArray(new FileAndName[0]); + for (int i = 0; i < fChildren.length; i++) { + fChildren[i].setConflictingName(false); + } + for (int i = 1; i < fChildren.length; i++) { + for (int j = 0; j < i; j++) { + if (fChildren[i].getName().equals(fChildren[j].getName())) { + fChildren[i].setConflictingName(true); + fChildren[j].setConflictingName(true); + } + } + } + getContainer().updateButtons(); + } + + /** + * Is there a name conflict + */ + boolean hasConflicts() { + boolean conflict = false; + for (FileAndName child : fTraces) { + conflict |= child.isConflictingName(); + } + return conflict; + } + + private boolean executeImportOperation(ImportOperation op) { + initializeOperation(op); + + try { + getContainer().run(true, true, op); + } catch (InterruptedException e) { + return false; + } catch (InvocationTargetException e) { + Activator.getDefault().logError(Messages.ImportTraceWizardImportProblem, e); + return false; + } + + IStatus status = op.getStatus(); + if (!status.isOK()) { + ErrorDialog.openError(getContainer().getShell(), Messages.ImportTraceWizardImportProblem, null, status); + return false; + } + + return true; + } + + private static void initializeOperation(ImportOperation op) { + op.setCreateContainerStructure(false); + op.setOverwriteResources(false); + op.setVirtualFolders(false); + } + + /** + * Override existing resources + * + * @param selection + * true or false + */ + public void setOverwrite(boolean selection) { + fOverwrite = selection; + } + + /** + * Is the trace linked? + * + * @param isLink + * true or false + */ + public void setLinked(boolean isLink) { + fLinked = isLink; + } + + /** + * @param tracesToScan + * sets the common traces to scan + */ + public void setTracesToScan(BlockingQueue tracesToScan) { + fTracesToScan = tracesToScan; + } + + /** + * @param traceToScan + * The trace to scan + * @return if the trace has been scanned yet or not + * @since 3.0 + */ + public boolean hasScanned(TraceValidationHelper traceToScan) { + return fResults.containsKey(traceToScan); + } + + /** + * Add a result to a cache + * + * @param traceToScan + * The trace that has been scanned + * @param validate + * if the trace is valid + * @since 3.0 + */ + public void addResult(TraceValidationHelper traceToScan, boolean validate) { + fResults.put(traceToScan, validate); + } + + /** + * Gets if the trace has been scanned or not + * + * @param traceToScan + * the scanned trace + * @return whether it passes or not + * @since 3.0 + */ + public boolean getResult(TraceValidationHelper traceToScan) { + return fResults.get(traceToScan); + } + + /** + * Returns the amount of files scanned + * + * @return the amount of files scanned + */ + public int getNumberOfResults() { + return fResults.size(); + } + + private void updateTracesToScan(final List added) { + // Treeset is used instead of a hashset since the traces should be read + // in the order they were added. + final Set filesToScan = new TreeSet<>(); + for (String name : fParentFiles.keySet()) { + filesToScan.addAll(fParentFiles.get(name)); + } + IProgressMonitor pm = new NullProgressMonitor(); + try { + updateScanQueue(pm, filesToScan, added); + } catch (InterruptedException e) { + } + + } + + /* + * I am a job. Make me work + */ + private synchronized IStatus updateFiles(IProgressMonitor monitor, String traceToScanAbsPath) { + final Set filesToScan = new TreeSet<>(); + + int workToDo = 1; + for (String name : fParentFiles.keySet()) { + + final File file = new File(name); + final File[] listFiles = file.listFiles(); + if (listFiles != null) { + workToDo += listFiles.length; + } + } + int step = TOTALWORK / workToDo; + try { + for (String name : fParentFiles.keySet()) { + final File fileToAdd = new File(name); + final Set parentFilesToScan = fParentFiles.get(fileToAdd.getAbsolutePath()); + recurse(parentFilesToScan, fileToAdd, monitor, step); + if (monitor.isCanceled()) { + fParentFilesToScan.remove(traceToScanAbsPath); + fParentFiles.remove(traceToScanAbsPath); + return CANCEL_STATUS; + } + } + filesToScan.clear(); + for (String name : fParentFiles.keySet()) { + filesToScan.addAll(fParentFiles.get(name)); + fParentFilesToScan.add(name); + } + IStatus cancelled = updateScanQueue(monitor, filesToScan, fTraceTypesToScan); + if (cancelled.matches(IStatus.CANCEL)) { + fParentFilesToScan.remove(traceToScanAbsPath); + fParentFiles.remove(traceToScanAbsPath); + } + } catch (InterruptedException e) { + monitor.done(); + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e); + } + + monitor.done(); + return Status.OK_STATUS; + } + + private IStatus updateScanQueue(IProgressMonitor monitor, final Set filesToScan, final List traceTypes) throws InterruptedException { + for (String fileToScan : filesToScan) { + for (String traceCat : traceTypes) { + TraceValidationHelper tv = new TraceValidationHelper(fileToScan, traceCat); + // for thread safety, keep checks in this order. + if (!fResults.containsKey(tv)) { + if (!fTracesToScan.contains(tv)) { + fTracesToScan.put(tv); + monitor.subTask(tv.getTraceToScan()); + if (monitor.isCanceled()) { + fScanPage.refresh(); + return CANCEL_STATUS; + } + } + } + } + } + fScanPage.refresh(); + return Status.OK_STATUS; + } + + private IStatus recurse(Set filesToScan, File fileToAdd, IProgressMonitor monitor, int step) { + final String absolutePath = fileToAdd.getAbsolutePath(); + if (!filesToScan.contains(absolutePath) && (filesToScan.size() < MAX_FILES)) { + filesToScan.add(absolutePath); + final File[] listFiles = fileToAdd.listFiles(); + if (null != listFiles) { + for (File child : listFiles) { + monitor.subTask(child.getName()); + if (monitor.isCanceled()) { + return CANCEL_STATUS; + } + IStatus retVal = recurse(filesToScan, child, monitor); + if (retVal.matches(IStatus.CANCEL)) { + return retVal; + } + monitor.worked(step); + } + } + } + return Status.OK_STATUS; + } + + private IStatus recurse(Set filesToScan, File fileToAdd, IProgressMonitor monitor) { + final String absolutePath = fileToAdd.getAbsolutePath(); + if (!filesToScan.contains(absolutePath) && (filesToScan.size() < MAX_FILES)) { + filesToScan.add(absolutePath); + final File[] listFiles = fileToAdd.listFiles(); + if (null != listFiles) { + for (File child : listFiles) { + if (monitor.isCanceled()) { + return CANCEL_STATUS; + } + IStatus retVal = recurse(filesToScan, child, monitor); + if (retVal.matches(IStatus.CANCEL)) { + return retVal; + } + } + } + } + return Status.OK_STATUS; + } + + /** + * Gets the folder in the resource (project) + * + * @param targetFolder + * the folder to import to + */ + public void setTraceFolder(IFolder targetFolder) { + fTargetFolder = targetFolder; + if (this.getContainer() != null && this.getContainer().getCurrentPage() != null) { + this.getContainer().updateButtons(); + } + } + + /** + * Gets the target folder + * + * @return the target folder + */ + public IFolder getTargetFolder() { + return fTargetFolder; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/FileAndName.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/FileAndName.java new file mode 100644 index 0000000000..fc2f02723c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/FileAndName.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace; + +import java.io.File; + +/** + * File and name internal helper class
    + * it has the file, a name to display, whether the name is conflicting and a + * reference to the configuration element defining its trace type. + * + * @author Matthew Khouzam + * @since 2.0 + */ +class FileAndName implements Comparable { + + final private File fFile; + private String fTraceTypeId; + private String fName; + private boolean fConflict; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * A file and name + * + * @param f + * the file, can only be set here + * @param n + * the name, can be renamed + * + */ + public FileAndName(File f, String n) { + fFile = f; + fName = n; + fTraceTypeId = null; + } + + // ------------------------------------------------------------------------ + // Getter / Setter + // ------------------------------------------------------------------------ + + /** + * Get the name + * + * @return the name + */ + public String getName() { + return fName; + } + + /** + * Set the name + * + * @param name + * the name to set + */ + public void setName(String name) { + this.fName = name; + } + + /** + * Sets the configuration element of the + * + * @param elem + * the element + */ + public void setTraceTypeId(String elem) { + fTraceTypeId = elem; + } + + /** + * Gets the configuration element canonical name + * + * @return gets the configuration element canonical name + */ + public String getTraceTypeId() { + return fTraceTypeId; + } + + /** + * Get the file + * + * @return the file + */ + public File getFile() { + return fFile; + } + + /** + * Set that the name is conflicting or not + * + * @param conflict + * if the name is conflicting or not + */ + public void setConflictingName(boolean conflict) { + fConflict = conflict; + } + + /** + * Is the name conflicting? + * + * @return is the name conflicting? + */ + public boolean isConflictingName() { + return fConflict; + } + + /** + * Is the fileAndName renamed + * + * @return true if the name does not match the filename + */ + public boolean isRenamed() { + return !fName.equals(fFile.getName()); + } + + // ------------------------------------------------------------------------ + // Comparator & Equals + // ------------------------------------------------------------------------ + + @Override + public int compareTo(FileAndName o) { + int retVal = getFile().compareTo(o.getFile()); + if (retVal == 0) { + if (getTraceTypeId() != null) { + if (getTraceTypeId() != null) { + if (o.getTraceTypeId() != null) { + retVal = getTraceTypeId().compareTo(o.getTraceTypeId()); + } + } + } + } + return retVal; + } + + @Override + public int hashCode() { + // do not take "name" into account since it can change on the fly. + final int prime = 31; + int result = 1; + result = prime * result + ((fTraceTypeId == null) ? 0 : fTraceTypeId.hashCode()); + result = prime * result + ((fFile == null) ? 0 : fFile.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + // do not take "name" into account since it can change on the fly. + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof FileAndName)) { + return false; + } + FileAndName other = (FileAndName) obj; + if (fTraceTypeId == null) { + if (other.fTraceTypeId != null) { + return false; + } + } else if (!fTraceTypeId.equals(other.fTraceTypeId)) { + return false; + } + if (fFile == null) { + if (other.fFile != null) { + return false; + } + } else if (!fFile.equals(other.fFile)) { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceContentProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceContentProvider.java new file mode 100644 index 0000000000..30c76113ec --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceContentProvider.java @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeSet; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; + +/** + * A helper class to show the trace types and files and names. it contains the + * model which can be defined as follows : {tracetype -> { file1, file2, ... } + * }+ + * + * @author Matthew Khouzam + * @since 2.0 + */ +class ImportTraceContentProvider implements ITreeContentProvider { + + private final Map fTraceTypes = new HashMap<>(); + private final Map> fTraceFiles = new HashMap<>(); + private final List fTraceTypesToScan; + private final Set fParentFilesToScan; + + public ImportTraceContentProvider(List traceTypesToScan, Set parentFilesToScan) { + fTraceTypesToScan = traceTypesToScan; + fParentFilesToScan = parentFilesToScan; + } + + /** + * Add a trace candidate to display + * + * @param traceTypeId + * the trace type id of the trace + * @param traceToOpen + * the trace file. + */ + public synchronized void addCandidate(String traceTypeId, File traceToOpen) { + TraceTypeHelper traceTypeHelper = TmfTraceType.getTraceType(traceTypeId); + if (traceTypeHelper == null) { + return; + } + fTraceTypes.put(traceTypeHelper.getName(), traceTypeId); + if (!fTraceFiles.containsKey(traceTypeId)) { + fTraceFiles.put(traceTypeId, new TreeSet()); + } + final FileAndName traceFile = new FileAndName(traceToOpen, traceToOpen.getName()); + traceFile.setTraceTypeId(traceTypeId); + final Set categorySet = fTraceFiles.get(traceTypeId); + categorySet.add(traceFile); + } + + /** + * Reset all the candidates + */ + public synchronized void clearCandidates() { + fTraceTypes.clear(); + fTraceFiles.clear(); + } + + @Override + public void dispose() { + fTraceFiles.clear(); + fTraceTypes.clear(); + + } + + @Override + public synchronized void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + if (oldInput != newInput && newInput != null) { + ImportTraceContentProvider input = (ImportTraceContentProvider) newInput; + clearCandidates(); + fTraceTypes.putAll(input.fTraceTypes); + fTraceFiles.putAll(fTraceFiles); + } + } + + @Override + public synchronized Object[] getElements(Object inputElement) { + List candidates = new ArrayList<>(); + + for (String candidate : fTraceTypesToScan) { + for (Entry entry : fTraceTypes.entrySet()) { + if (entry.getValue().equals(candidate)) { + candidates.add(entry.getKey()); + break; + } + } + + } + return candidates.toArray(new String[candidates.size()]); + } + + @Override + public synchronized Object[] getChildren(Object parentElement) { + if (parentElement instanceof String) { + final Set children = fTraceFiles.get(fTraceTypes.get(parentElement)); + if (children != null) { + Set candidates = new TreeSet<>(); + for (FileAndName child : children) { + for (String parent : fParentFilesToScan) { + // this is going to be slow, but less slow than UI + // display and should not be done for more than 10k + // elements. + if (child.getFile().getAbsolutePath().startsWith(parent)) { + candidates.add(child); + } + } + } + return candidates.toArray(new FileAndName[0]); + } + } + return null; + } + + /** + * Gets the brothers and systems of a file element + * + * @param element + * the child leaf + * @return the siblings of an element, including itself. Should never be + * null + */ + public synchronized FileAndName[] getSiblings(FileAndName element) { + String key = (String) getParent(element); + return (FileAndName[]) getChildren(key); + + } + + @Override + public synchronized Object getParent(Object element) { + if (element instanceof FileAndName) { + for (String key : fTraceFiles.keySet()) { + Set fanSet = fTraceFiles.get(key); + if (fanSet.contains(element)) { + return key; + } + } + } + return null; + } + + @Override + public synchronized boolean hasChildren(Object element) { + if (element instanceof String) { + String key = (String) element; + return fTraceFiles.containsKey(fTraceTypes.get(key)); + } + return false; + } + + /** + * Gets the number of traces to import + * + * @return the number of traces to import + */ + public synchronized int getSize() { + int tot = 0; + for (String s : fTraceFiles.keySet()) { + tot += fTraceFiles.get(s).size(); + } + return tot; + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceLabelProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceLabelProvider.java new file mode 100644 index 0000000000..cb3c80bb26 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceLabelProvider.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace; + +import java.io.File; + +import org.eclipse.jface.viewers.LabelProvider; + +/** + * Trace label provider for the candidate tree + * + * @author Matthew Khouzam + * @since 2.0 + */ +class ImportTraceLabelProvider extends LabelProvider { + + @Override + public String getText(Object element) { + if (element instanceof String) { + return (String) element; + } + if (element instanceof FileAndName) { + final File file = ((FileAndName) element).getFile(); + if (file != null) { // should never not happen since file is final + // and always set automatically + return file.getName(); + } + } + return null; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizard.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizard.java new file mode 100644 index 0000000000..bf807ee113 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizard.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace; + +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.ui.IImportWizard; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +/** + * The import trace wizard implementation. + *

    + * @version 1.0 + * @author Francois Chouinard + * @since 2.0 + */ +public class ImportTraceWizard extends Wizard implements IImportWizard { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + static private final String PLUGIN_ID = Activator.PLUGIN_ID; + static private final String IMPORT_WIZARD = "ImportTraceWizard"; //$NON-NLS-1$ + static private final String ICON_PATH = "icons/wizban/trace_import_wiz.png"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private IStructuredSelection fSelection; + private ImportTraceWizardPage fTraceImportWizardPage; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + /** + * Default constructor + */ + public ImportTraceWizard() { + IDialogSettings workbenchSettings = Activator.getDefault().getDialogSettings(); + IDialogSettings section = workbenchSettings.getSection(IMPORT_WIZARD); + if (section == null) { + section = workbenchSettings.addNewSection(IMPORT_WIZARD); + } + setDialogSettings(section); + } + + // ------------------------------------------------------------------------ + // Wizard + // ------------------------------------------------------------------------ + + @Override + public void init(IWorkbench workbench, IStructuredSelection selection) { + fSelection = selection; + + setWindowTitle(Messages.ImportTraceWizard_DialogTitle); + setDefaultPageImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, ICON_PATH)); + setNeedsProgressMonitor(true); + } + + @Override + public void addPages() { + super.addPages(); + fTraceImportWizardPage = new ImportTraceWizardPage(fSelection); + addPage(fTraceImportWizardPage); + } + + @Override + public boolean performFinish() { + return fTraceImportWizardPage.finish(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardPage.java new file mode 100644 index 0000000000..d05b511722 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardPage.java @@ -0,0 +1,2234 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson and others. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Got rid of dependency on internal platform class + * Francois Chouinard - Complete re-design + * Anna Dushistova(Montavista) - [383047] NPE while importing a CFT trace + * Matthew Khouzam - Moved out some common functions + * Patrick Tasse - Add sorting of file system elements + * Bernd Hufmann - Re-design of trace selection and trace validation + * Marc-Andre Laperle - Preserve folder structure on import + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipException; +import java.util.zip.ZipFile; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.layout.PixelConverter; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.operation.ModalContext; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.swt.events.FocusAdapter; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.TraverseEvent; +import org.eclipse.swt.events.TraverseListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.DirectoryDialog; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.TmfProjectNature; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceImportException; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceTypeUIUtils; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTracesFolder; +import org.eclipse.ui.dialogs.FileSystemElement; +import org.eclipse.ui.dialogs.IOverwriteQuery; +import org.eclipse.ui.dialogs.WizardResourceImportPage; +import org.eclipse.ui.internal.ide.DialogUtil; +import org.eclipse.ui.internal.ide.dialogs.IElementFilter; +import org.eclipse.ui.internal.wizards.datatransfer.ArchiveFileManipulations; +import org.eclipse.ui.internal.wizards.datatransfer.ILeveledImportStructureProvider; +import org.eclipse.ui.internal.wizards.datatransfer.TarEntry; +import org.eclipse.ui.internal.wizards.datatransfer.TarException; +import org.eclipse.ui.internal.wizards.datatransfer.TarFile; +import org.eclipse.ui.internal.wizards.datatransfer.TarLeveledStructureProvider; +import org.eclipse.ui.internal.wizards.datatransfer.ZipLeveledStructureProvider; +import org.eclipse.ui.model.AdaptableList; +import org.eclipse.ui.model.WorkbenchContentProvider; +import org.eclipse.ui.model.WorkbenchLabelProvider; +import org.eclipse.ui.model.WorkbenchViewerComparator; +import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider; +import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider; +import org.eclipse.ui.wizards.datatransfer.ImportOperation; + +/** + * A variant of the standard resource import wizard for importing traces to + * given tracing project. If no project or tracing project was selected the + * wizard imports it to the default tracing project which is created if + * necessary. + * + * In our case traces could be files or a directory structure. This wizard + * supports both cases. It imports traces for a selected trace type or, if no + * trace type is selected, it tries to detect the trace type automatically. + * However, the automatic detection is a best-effort and cannot guarantee that + * the detection is successful. The reason for this is that there might be + * multiple trace types that can be assigned to a single trace. + * + * + * @author Francois Chouinard + * @since 2.0 + */ +@SuppressWarnings("restriction") +public class ImportTraceWizardPage extends WizardResourceImportPage { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + private static final String IMPORT_WIZARD_PAGE_NAME = "ImportTraceWizardPage"; //$NON-NLS-1$ + private static final String IMPORT_WIZARD_ROOT_DIRECTORY_ID = ".import_root_directory_id"; //$NON-NLS-1$; + private static final String IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID = ".import_archive_file_name_id"; //$NON-NLS-1$ + private static final String IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID = ".import_unrecognized_traces_id"; //$NON-NLS-1$ + private static final String IMPORT_WIZARD_PRESERVE_FOLDERS_ID = ".import_preserve_folders_id"; //$NON-NLS-1$ + private static final String IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID = ".import_from_directory"; //$NON-NLS-1$ + private static final String SEPARATOR = ":"; //$NON-NLS-1$ + + // constant from WizardArchiveFileResourceImportPage1 + private static final String[] FILE_IMPORT_MASK = { "*.jar;*.zip;*.tar;*.tar.gz;*.tgz", "*.*" }; //$NON-NLS-1$ //$NON-NLS-2$ + private static final String TRACE_IMPORT_TEMP_FOLDER = ".traceImport"; //$NON-NLS-1$ + + /** + * A special trace type value to communicate that automatic trace type + * detection will occur instead of setting a specific trace type when + * importing the traces. + */ + public static final String TRACE_TYPE_AUTO_DETECT = Messages.ImportTraceWizard_AutoDetection; + + /** + * Preserve the folder structure of the import traces. + */ + public static final int OPTION_PRESERVE_FOLDER_STRUCTURE = 1 << 1; + /** + * Create links to the trace files instead of copies. + */ + public static final int OPTION_CREATE_LINKS_IN_WORKSPACE = 1 << 2; + /** + * Import files that were not recognized as the selected trace type. + */ + public static final int OPTION_IMPORT_UNRECOGNIZED_TRACES = 1 << 3; + /** + * Overwrite existing resources without prompting. + */ + public static final int OPTION_OVERWRITE_EXISTING_RESOURCES = 1 << 4; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // Target import directory ('Traces' folder) + private IFolder fTargetFolder; + // Target Trace folder element + private TmfTraceFolder fTraceFolderElement; + // Flag to handle destination folder change event + private Boolean fIsDestinationChanged = false; + // Combo box containing trace types + private Combo fTraceTypes; + // Button to ignore unrecognized traces or not + private Button fImportUnrecognizedButton; + // Button to overwrite existing resources or not + private Button fOverwriteExistingResourcesCheckbox; + // Button to link or copy traces to workspace + private Button fCreateLinksInWorkspaceButton; + // Button to preserve folder structure + private Button fPreserveFolderStructureButton; + private boolean entryChanged = false; + // The import from directory radio button + private Button fImportFromDirectoryRadio; + // The import from archive radio button + private Button fImportFromArchiveRadio; + // Flag to remember the "create links" checkbox when it gets disabled by + // the import from archive radio button + private Boolean fPreviousCreateLinksValue = true; + + /** The archive name field */ + protected Combo fArchiveNameField; + /** The archive browse button. */ + protected Button fArchiveBrowseButton; + /** The directory name field */ + protected Combo directoryNameField; + /** The directory browse button. */ + protected Button directoryBrowseButton; + + /** + * ResourceTreeAndListGroup was internal in Kepler and we referenced it. It + * is now removed in Luna. To keep our builds compatible with Kepler, we + * need to have our own version of this class. Once we stop supporting + * Kepler, we can delete this class and use the public one from the + * platform. + */ + private ResourceTreeAndListGroup fSelectionGroup; + + // Keep trace of the selection root so that we can dispose its related + // resources + private TraceFileSystemElement fSelectionGroupRoot; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructor. Creates the trace wizard page. + * + * @param name + * The name of the page. + * @param selection + * The current selection + */ + protected ImportTraceWizardPage(String name, IStructuredSelection selection) { + super(name, selection); + setTitle(Messages.ImportTraceWizard_FileSystemTitle); + setDescription(Messages.ImportTraceWizard_ImportTrace); + + // Locate the target trace folder + IFolder traceFolder = null; + Object element = selection.getFirstElement(); + + if (element instanceof TmfTraceFolder) { + fTraceFolderElement = (TmfTraceFolder) element; + traceFolder = fTraceFolderElement.getResource(); + } else if (element instanceof IProject) { + IProject project = (IProject) element; + try { + if (project.hasNature(TmfProjectNature.ID)) { + TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true); + fTraceFolderElement = projectElement.getTracesFolder(); + traceFolder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME); + } + } catch (CoreException e) { + } + } + + // If no tracing project was selected or trace folder doesn't exist use + // default tracing project + if (traceFolder == null) { + IProject project = TmfProjectRegistry.createProject( + TmfCommonConstants.DEFAULT_TRACE_PROJECT_NAME, null, new NullProgressMonitor()); + TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true); + fTraceFolderElement = projectElement.getTracesFolder(); + traceFolder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME); + } + + // Set the target trace folder + if (traceFolder != null) { + fTargetFolder = traceFolder; + String path = traceFolder.getFullPath().toString(); + setContainerFieldValue(path); + } + } + + /** + * Constructor + * + * @param selection + * The current selection + */ + public ImportTraceWizardPage(IStructuredSelection selection) { + this(IMPORT_WIZARD_PAGE_NAME, selection); + } + + /** + * Create the import source selection widget. (Copied from + * WizardResourceImportPage but instead always uses the internal + * ResourceTreeAndListGroup to keep compatibility with Kepler) + */ + @Override + protected void createFileSelectionGroup(Composite parent) { + + // Just create with a dummy root. + fSelectionGroup = new ResourceTreeAndListGroup(parent, + new FileSystemElement("Dummy", null, true),//$NON-NLS-1$ + getFolderProvider(), new WorkbenchLabelProvider(), + getFileProvider(), new WorkbenchLabelProvider(), SWT.NONE, + DialogUtil.inRegularFontMode(parent)); + + ICheckStateListener listener = new ICheckStateListener() { + @Override + public void checkStateChanged(CheckStateChangedEvent event) { + updateWidgetEnablements(); + } + }; + + WorkbenchViewerComparator comparator = new WorkbenchViewerComparator(); + fSelectionGroup.setTreeComparator(comparator); + fSelectionGroup.setListComparator(comparator); + fSelectionGroup.addCheckStateListener(listener); + + } + + // ------------------------------------------------------------------------ + // WizardResourceImportPage + // ------------------------------------------------------------------------ + + @Override + protected void createSourceGroup(Composite parent) { + createSourceSelectionGroup(parent); + createFileSelectionGroup(parent); + createTraceTypeGroup(parent); + validateSourceGroup(); + } + + @Override + protected ITreeContentProvider getFileProvider() { + return new WorkbenchContentProvider() { + @Override + public Object[] getChildren(Object object) { + if (object instanceof TraceFileSystemElement) { + TraceFileSystemElement element = (TraceFileSystemElement) object; + return element.getFiles().getChildren(element); + } + return new Object[0]; + } + }; + } + + @Override + protected ITreeContentProvider getFolderProvider() { + return new WorkbenchContentProvider() { + @Override + public Object[] getChildren(Object o) { + if (o instanceof TraceFileSystemElement) { + TraceFileSystemElement element = (TraceFileSystemElement) o; + return element.getFolders().getChildren(); + } + return new Object[0]; + } + + @Override + public boolean hasChildren(Object o) { + if (o instanceof TraceFileSystemElement) { + TraceFileSystemElement element = (TraceFileSystemElement) o; + if (element.isPopulated()) { + return getChildren(element).length > 0; + } + // If we have not populated then wait until asked + return true; + } + return false; + } + }; + } + + // ------------------------------------------------------------------------ + // Directory Selection Group (forked WizardFileSystemResourceImportPage1) + // ------------------------------------------------------------------------ + + /** + * creates the source selection group. + * + * @param parent + * the parent composite + */ + protected void createSourceSelectionGroup(Composite parent) { + + Composite sourceGroup = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 3; + layout.makeColumnsEqualWidth = false; + layout.marginWidth = 0; + sourceGroup.setLayout(layout); + sourceGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // import from directory radio button + fImportFromDirectoryRadio = new Button(sourceGroup, SWT.RADIO); + fImportFromDirectoryRadio + .setText(Messages.ImportTraceWizard_DirectoryLocation); + + // import location entry combo + directoryNameField = createPathSelectionCombo(sourceGroup); + createDirectoryBrowseButton(sourceGroup); + + // import from archive radio button + fImportFromArchiveRadio = new Button(sourceGroup, SWT.RADIO); + fImportFromArchiveRadio + .setText(Messages.ImportTraceWizard_ArchiveLocation); + + // import location entry combo + fArchiveNameField = createPathSelectionCombo(sourceGroup); + createArchiveBrowseButton(sourceGroup); + + fImportFromDirectoryRadio.setSelection(true); + fArchiveNameField.setEnabled(false); + fArchiveBrowseButton.setEnabled(false); + + fImportFromDirectoryRadio.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + directoryRadioSelected(); + } + }); + + fImportFromArchiveRadio.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + archiveRadioSelected(); + } + }); + } + + /** + * Select or deselect all files in the file selection group + * + * @param checked + * whether or not the files should be checked + */ + protected void setFileSelectionGroupChecked(boolean checked) { + if (fSelectionGroup != null) { + fSelectionGroup.setAllSelections(checked); + } + } + + /** + * Create a combo that will be used to select a path to specify the source + * of the import. The parent is assumed to have a GridLayout. + * + * @param parent + * the parent composite + * @return the created path selection combo + */ + protected Combo createPathSelectionCombo(Composite parent) { + Combo pathSelectionCombo = new Combo(parent, SWT.BORDER); + + GridData layoutData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL); + layoutData.widthHint = new PixelConverter(pathSelectionCombo).convertWidthInCharsToPixels(25); + pathSelectionCombo.setLayoutData(layoutData); + + TraverseListener traverseListener = new TraverseListener() { + @Override + public void keyTraversed(TraverseEvent e) { + if (e.detail == SWT.TRAVERSE_RETURN) { + e.doit = false; + entryChanged = false; + updateFromSourceField(); + } + } + }; + + FocusAdapter focusAdapter = new FocusAdapter() { + @Override + public void focusLost(FocusEvent e) { + // Clear the flag to prevent constant update + if (entryChanged) { + entryChanged = false; + updateFromSourceField(); + } + } + }; + + SelectionAdapter selectionAdapter = new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + entryChanged = false; + updateFromSourceField(); + } + }; + + ModifyListener modifyListner = new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + entryChanged = true; + } + }; + + pathSelectionCombo.addModifyListener(modifyListner); + pathSelectionCombo.addTraverseListener(traverseListener); + pathSelectionCombo.addFocusListener(focusAdapter); + pathSelectionCombo.addSelectionListener(selectionAdapter); + + return pathSelectionCombo; + } + + /** + * Create the directory browse button. + * + * @param parent + * the parent composite + */ + protected void createDirectoryBrowseButton(Composite parent) { + directoryBrowseButton = createPathSelectionBrowseButton(parent); + directoryBrowseButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + handleSourceDirectoryBrowseButtonPressed(); + } + }); + } + + /** + * Create the archive browse button. + * + * @param parent + * the parent composite + */ + protected void createArchiveBrowseButton(Composite parent) { + fArchiveBrowseButton = createPathSelectionBrowseButton(parent); + fArchiveBrowseButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + handleArchiveBrowseButtonPressed(FILE_IMPORT_MASK); + } + }); + } + + /** + * Create a browse button that will be used to browse for a path to specify + * the source of the import. The parent is assumed to have a GridLayout. + * + * @param parent + * the parent composite + * @return the created path selection combo + */ + protected Button createPathSelectionBrowseButton(Composite parent) { + Button pathSelectionBrowseButton = new Button(parent, SWT.PUSH); + pathSelectionBrowseButton.setText(Messages.ImportTraceWizard_BrowseButton); + setButtonLayoutData(pathSelectionBrowseButton); + + return pathSelectionBrowseButton; + } + + private void archiveRadioSelected() { + if (!isImportFromDirectory()) { + directoryNameField.setEnabled(false); + directoryBrowseButton.setEnabled(false); + fArchiveNameField.setEnabled(true); + fArchiveBrowseButton.setEnabled(true); + updateFromSourceField(); + fArchiveNameField.setFocus(); + if (fCreateLinksInWorkspaceButton != null) { + fPreviousCreateLinksValue = fCreateLinksInWorkspaceButton.getSelection(); + fCreateLinksInWorkspaceButton.setSelection(false); + fCreateLinksInWorkspaceButton.setEnabled(false); + } + } + } + + private void directoryRadioSelected() { + if (isImportFromDirectory()) { + directoryNameField.setEnabled(true); + directoryBrowseButton.setEnabled(true); + fArchiveNameField.setEnabled(false); + fArchiveBrowseButton.setEnabled(false); + updateFromSourceField(); + directoryNameField.setFocus(); + if (fCreateLinksInWorkspaceButton != null) { + fCreateLinksInWorkspaceButton.setSelection(fPreviousCreateLinksValue); + fCreateLinksInWorkspaceButton.setEnabled(true); + } + } + } + + // ------------------------------------------------------------------------ + // Browse for the source directory + // ------------------------------------------------------------------------ + + @Override + public void handleEvent(Event event) { + if (event.widget == directoryBrowseButton) { + handleSourceDirectoryBrowseButtonPressed(); + } + + // Avoid overwriting destination path without repeatedly trigger + // call of handleEvent(); + synchronized (fIsDestinationChanged) { + if (fIsDestinationChanged == false) { + event.display.asyncExec(new Runnable() { + @Override + public void run() { + synchronized (fIsDestinationChanged) { + fIsDestinationChanged = true; + String path = fTargetFolder.getFullPath().toString(); + setContainerFieldValue(path); + } + } + }); + } else { + fIsDestinationChanged = false; + } + } + super.handleEvent(event); + } + + @Override + protected void handleContainerBrowseButtonPressed() { + // Do nothing so that destination directory cannot be changed. + } + + /** + * Handle the button pressed event + */ + protected void handleSourceDirectoryBrowseButtonPressed() { + String currentSource = directoryNameField.getText(); + DirectoryDialog dialog = new DirectoryDialog(directoryNameField.getShell(), SWT.SAVE | SWT.SHEET); + dialog.setText(Messages.ImportTraceWizard_SelectTraceDirectoryTitle); + dialog.setMessage(Messages.ImportTraceWizard_SelectTraceDirectoryMessage); + dialog.setFilterPath(getSourceDirectoryName(currentSource)); + + String selectedDirectory = dialog.open(); + if (selectedDirectory != null) { + // Just quit if the directory is not valid + if ((getSourceDirectory(selectedDirectory) == null) || selectedDirectory.equals(currentSource)) { + return; + } + // If it is valid then proceed to populate + setErrorMessage(null); + setSourcePath(selectedDirectory); + } + } + + /** + * Handle the button pressed event + * + * @param extensions + * file extensions used to filter files shown to the user + */ + protected void handleArchiveBrowseButtonPressed(String[] extensions) { + FileDialog dialog = new FileDialog(fArchiveNameField.getShell(), SWT.SHEET); + dialog.setFilterExtensions(extensions); + dialog.setText(Messages.ImportTraceWizard_SelectTraceArchiveTitle); + String fileName = fArchiveNameField.getText().trim(); + if (!fileName.isEmpty()) { + File path = new File(fileName).getParentFile(); + if (path != null && path.exists()) { + dialog.setFilterPath(path.toString()); + } + } + + String selectedArchive = dialog.open(); + if (selectedArchive != null) { + setErrorMessage(null); + setSourcePath(selectedArchive); + updateWidgetEnablements(); + } + } + + private File getSourceDirectory() { + if (directoryNameField == null) { + return null; + } + return getSourceDirectory(directoryNameField.getText()); + } + + private File getSourceArchiveFile() { + if (fArchiveNameField == null) { + return null; + } + + return getSourceArchiveFile(fArchiveNameField.getText()); + } + + private String getSourceContainerPath() { + if (isImportFromDirectory()) { + File sourceDirectory = getSourceDirectory(); + if (sourceDirectory != null) { + return sourceDirectory.getAbsolutePath(); + } + } + File sourceArchiveFile = getSourceArchiveFile(); + if (sourceArchiveFile != null) { + return sourceArchiveFile.getParent(); + } + return null; + } + + private static File getSourceDirectory(String path) { + File sourceDirectory = new File(getSourceDirectoryName(path)); + if (!sourceDirectory.exists() || !sourceDirectory.isDirectory()) { + return null; + } + + return sourceDirectory; + } + + private static File getSourceArchiveFile(String path) { + File sourceArchiveFile = new File(path); + if (!sourceArchiveFile.exists() || sourceArchiveFile.isDirectory()) { + return null; + } + + return sourceArchiveFile; + } + + private static String getSourceDirectoryName(String sourceName) { + IPath result = new Path(sourceName.trim()); + if (result.getDevice() != null && result.segmentCount() == 0) { + result = result.addTrailingSeparator(); + } else { + result = result.removeTrailingSeparator(); + } + return result.toOSString(); + } + + private void updateFromSourceField() { + setSourcePath(getSourceField().getText()); + updateWidgetEnablements(); + } + + private Combo getSourceField() { + if (directoryNameField == null) { + return fArchiveNameField; + } + + return directoryNameField.isEnabled() ? directoryNameField : fArchiveNameField; + } + + /** + * Set the source path that was selected by the user by various input + * methods (Browse button, typing, etc). + * + * Clients can also call this to set the path programmatically (hard-coded + * initial path) and this can also be overridden to be notified when the + * source path changes. + * + * @param path + * the source path + */ + protected void setSourcePath(String path) { + Combo sourceField = getSourceField(); + if (sourceField == null) { + return; + } + + if (path.length() > 0) { + String[] currentItems = sourceField.getItems(); + int selectionIndex = -1; + for (int i = 0; i < currentItems.length; i++) { + if (currentItems[i].equals(path)) { + selectionIndex = i; + } + } + if (selectionIndex < 0) { + int oldLength = currentItems.length; + String[] newItems = new String[oldLength + 1]; + System.arraycopy(currentItems, 0, newItems, 0, oldLength); + newItems[oldLength] = path; + sourceField.setItems(newItems); + selectionIndex = oldLength; + } + sourceField.select(selectionIndex); + } + resetSelection(); + } + + // ------------------------------------------------------------------------ + // File Selection Group (forked WizardFileSystemResourceImportPage1) + // ------------------------------------------------------------------------ + private void resetSelection() { + if (fSelectionGroupRoot != null) { + disposeSelectionGroupRoot(); + } + fSelectionGroupRoot = getFileSystemTree(); + fSelectionGroup.setRoot(fSelectionGroupRoot); + } + + private void disposeSelectionGroupRoot() { + if (fSelectionGroupRoot != null && fSelectionGroupRoot.getProvider() != null) { + FileSystemObjectImportStructureProvider provider = fSelectionGroupRoot.getProvider(); + provider.dispose(); + fSelectionGroupRoot = null; + } + } + + private TraceFileSystemElement getFileSystemTree() { + IFileSystemObject rootElement = null; + FileSystemObjectImportStructureProvider importStructureProvider = null; + + // Import from directory + if (isImportFromDirectory()) { + importStructureProvider = new FileSystemObjectImportStructureProvider(FileSystemStructureProvider.INSTANCE, null); + File sourceDirectory = getSourceDirectory(); + if (sourceDirectory == null) { + return null; + } + rootElement = importStructureProvider.getIFileSystemObject(sourceDirectory); + } else { + // Import from archive + FileSystemObjectLeveledImportStructureProvider leveledImportStructureProvider = null; + String archivePath = getSourceArchiveFile() != null ? getSourceArchiveFile().getAbsolutePath() : ""; //$NON-NLS-1$ + if (ArchiveFileManipulations.isTarFile(archivePath)) { + if (ensureTarSourceIsValid(archivePath)) { + // We close the file when we dispose the import provider, + // see disposeSelectionGroupRoot + TarFile tarFile = getSpecifiedTarSourceFile(archivePath); + leveledImportStructureProvider = new FileSystemObjectLeveledImportStructureProvider(new TarLeveledStructureProvider(tarFile), archivePath); + } + } else if (ensureZipSourceIsValid(archivePath)) { + // We close the file when we dispose the import provider, see + // disposeSelectionGroupRoot + @SuppressWarnings("resource") + ZipFile zipFile = getSpecifiedZipSourceFile(archivePath); + leveledImportStructureProvider = new FileSystemObjectLeveledImportStructureProvider(new ZipLeveledStructureProvider(zipFile), archivePath); + } + if (leveledImportStructureProvider == null) { + return null; + } + rootElement = leveledImportStructureProvider.getRoot(); + importStructureProvider = leveledImportStructureProvider; + } + + if (rootElement == null) { + return null; + } + + return selectFiles(rootElement, importStructureProvider); + } + + /** + * An import provider that makes use of the IFileSystemObject abstraction + * instead of using plain file system objects (File, TarEntry, ZipEntry) + */ + private static class FileSystemObjectImportStructureProvider implements IImportStructureProvider { + + private IImportStructureProvider fImportProvider; + private String fArchivePath; + + private FileSystemObjectImportStructureProvider(IImportStructureProvider importStructureProvider, String archivePath) { + fImportProvider = importStructureProvider; + fArchivePath = archivePath; + } + + @Override + public List getChildren(Object element) { + @SuppressWarnings("rawtypes") + List children = fImportProvider.getChildren(((IFileSystemObject) element).getRawFileSystemObject()); + List adapted = new ArrayList<>(children.size()); + for (Object o : children) { + adapted.add(getIFileSystemObject(o)); + } + return adapted; + } + + public IFileSystemObject getIFileSystemObject(Object o) { + if (o == null) { + return null; + } + + if (o instanceof File) { + return new FileFileSystemObject((File) o); + } else if (o instanceof TarEntry) { + return new TarFileSystemObject((TarEntry) o, fArchivePath); + } else if (o instanceof ZipEntry) { + return new ZipFileSystemObject((ZipEntry) o, fArchivePath); + } + + throw new IllegalArgumentException("Object type not handled"); //$NON-NLS-1$ + } + + @Override + public InputStream getContents(Object element) { + return fImportProvider.getContents(((IFileSystemObject) element).getRawFileSystemObject()); + } + + @Override + public String getFullPath(Object element) { + return fImportProvider.getFullPath(((IFileSystemObject) element).getRawFileSystemObject()); + } + + @Override + public String getLabel(Object element) { + return fImportProvider.getLabel(((IFileSystemObject) element).getRawFileSystemObject()); + } + + @Override + public boolean isFolder(Object element) { + return fImportProvider.isFolder(((IFileSystemObject) element).getRawFileSystemObject()); + } + + /** + * Disposes of the resources associated with the provider. + */ + public void dispose() { + } + } + + /** + * An import provider that both supports using IFileSystemObject and adds + * "archive functionality" by delegating to a leveled import provider + * (TarLeveledStructureProvider, ZipLeveledStructureProvider) + */ + private static class FileSystemObjectLeveledImportStructureProvider extends FileSystemObjectImportStructureProvider implements ILeveledImportStructureProvider { + + private ILeveledImportStructureProvider fLeveledImportProvider; + + private FileSystemObjectLeveledImportStructureProvider(ILeveledImportStructureProvider importStructureProvider, String archivePath) { + super(importStructureProvider, archivePath); + fLeveledImportProvider = importStructureProvider; + } + + @Override + public IFileSystemObject getRoot() { + return getIFileSystemObject(fLeveledImportProvider.getRoot()); + } + + @Override + public void setStrip(int level) { + fLeveledImportProvider.setStrip(level); + } + + @Override + public int getStrip() { + return fLeveledImportProvider.getStrip(); + } + + @Override + public boolean closeArchive() { + return fLeveledImportProvider.closeArchive(); + } + } + + @SuppressWarnings("resource") + private boolean ensureZipSourceIsValid(String archivePath) { + ZipFile specifiedFile = getSpecifiedZipSourceFile(archivePath); + if (specifiedFile == null) { + return false; + } + return ArchiveFileManipulations.closeZipFile(specifiedFile, getShell()); + } + + private boolean ensureTarSourceIsValid(String archivePath) { + TarFile specifiedFile = getSpecifiedTarSourceFile(archivePath); + if (specifiedFile == null) { + return false; + } + return ArchiveFileManipulations.closeTarFile(specifiedFile, getShell()); + } + + private static ZipFile getSpecifiedZipSourceFile(String fileName) { + if (fileName.length() == 0) { + return null; + } + + try { + return new ZipFile(fileName); + } catch (ZipException e) { + // ignore + } catch (IOException e) { + // ignore + } + + return null; + } + + private static TarFile getSpecifiedTarSourceFile(String fileName) { + if (fileName.length() == 0) { + return null; + } + + try { + return new TarFile(fileName); + } catch (TarException e) { + // ignore + } catch (IOException e) { + // ignore + } + + return null; + } + + private TraceFileSystemElement selectFiles(final IFileSystemObject rootFileSystemObject, + final FileSystemObjectImportStructureProvider structureProvider) { + final TraceFileSystemElement[] results = new TraceFileSystemElement[1]; + BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() { + @Override + public void run() { + // Create the root element from the supplied file system object + results[0] = createRootElement(rootFileSystemObject, structureProvider); + } + }); + return results[0]; + } + + private static TraceFileSystemElement createRootElement(IFileSystemObject element, + FileSystemObjectImportStructureProvider provider) { + boolean isContainer = provider.isFolder(element); + String elementLabel = provider.getLabel(element); + + // Use an empty label so that display of the element's full name + // doesn't include a confusing label + TraceFileSystemElement dummyParent = new TraceFileSystemElement("", null, true, provider);//$NON-NLS-1$ + Object dummyParentFileSystemObject = element; + Object rawFileSystemObject = element.getRawFileSystemObject(); + if (rawFileSystemObject instanceof File) { + dummyParentFileSystemObject = provider.getIFileSystemObject(((File) rawFileSystemObject).getParentFile()); + } + dummyParent.setFileSystemObject(dummyParentFileSystemObject); + dummyParent.setPopulated(); + TraceFileSystemElement result = new TraceFileSystemElement( + elementLabel, dummyParent, isContainer, provider); + result.setFileSystemObject(element); + + // Get the files for the element so as to build the first level + result.getFiles(); + + return dummyParent; + } + + // ------------------------------------------------------------------------ + // Trace Type Group + // ------------------------------------------------------------------------ + private final void createTraceTypeGroup(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 3; + layout.makeColumnsEqualWidth = false; + composite.setLayout(layout); + composite.setFont(parent.getFont()); + GridData buttonData = new GridData(SWT.FILL, SWT.FILL, true, false); + composite.setLayoutData(buttonData); + + // Trace type label ("Trace Type:") + Label typeLabel = new Label(composite, SWT.NONE); + typeLabel.setText(Messages.ImportTraceWizard_TraceType); + typeLabel.setFont(parent.getFont()); + + // Trace type combo + fTraceTypes = new Combo(composite, SWT.BORDER | SWT.READ_ONLY); + GridData data = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1); + fTraceTypes.setLayoutData(data); + fTraceTypes.setFont(parent.getFont()); + + String[] availableTraceTypes = TmfTraceType.getAvailableTraceTypes(); + String[] traceTypeList = new String[availableTraceTypes.length + 1]; + traceTypeList[0] = TRACE_TYPE_AUTO_DETECT; + for (int i = 0; i < availableTraceTypes.length; i++) { + traceTypeList[i + 1] = availableTraceTypes[i]; + } + fTraceTypes.setItems(traceTypeList); + fTraceTypes.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + updateWidgetEnablements(); + boolean enabled = fTraceTypes.getText().equals(TRACE_TYPE_AUTO_DETECT); + fImportUnrecognizedButton.setEnabled(enabled); + } + }); + fTraceTypes.select(0); + + // Unrecognized checkbox + fImportUnrecognizedButton = new Button(composite, SWT.CHECK); + fImportUnrecognizedButton.setSelection(true); + fImportUnrecognizedButton.setText(Messages.ImportTraceWizard_ImportUnrecognized); + } + + // ------------------------------------------------------------------------ + // Options + // ------------------------------------------------------------------------ + + @Override + protected void createOptionsGroupButtons(Group optionsGroup) { + + // Overwrite checkbox + fOverwriteExistingResourcesCheckbox = new Button(optionsGroup, SWT.CHECK); + fOverwriteExistingResourcesCheckbox.setFont(optionsGroup.getFont()); + fOverwriteExistingResourcesCheckbox.setText(Messages.ImportTraceWizard_OverwriteExistingTrace); + fOverwriteExistingResourcesCheckbox.setSelection(false); + + // Create links checkbox + fCreateLinksInWorkspaceButton = new Button(optionsGroup, SWT.CHECK); + fCreateLinksInWorkspaceButton.setFont(optionsGroup.getFont()); + fCreateLinksInWorkspaceButton.setText(Messages.ImportTraceWizard_CreateLinksInWorkspace); + fCreateLinksInWorkspaceButton.setSelection(true); + + fCreateLinksInWorkspaceButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + updateWidgetEnablements(); + } + }); + + fPreserveFolderStructureButton = new Button(optionsGroup, SWT.CHECK); + fPreserveFolderStructureButton.setFont(optionsGroup.getFont()); + fPreserveFolderStructureButton.setText(Messages.ImportTraceWizard_PreserveFolderStructure); + fPreserveFolderStructureButton.setSelection(true); + + updateWidgetEnablements(); + } + + // ------------------------------------------------------------------------ + // Determine if the finish button can be enabled + // ------------------------------------------------------------------------ + @Override + public boolean validateSourceGroup() { + + File source = isImportFromDirectory() ? getSourceDirectory() : getSourceArchiveFile(); + if (source == null) { + setMessage(Messages.ImportTraceWizard_SelectTraceSourceEmpty); + setErrorMessage(null); + return false; + } + + if (sourceConflictsWithDestination(new Path(source.getPath()))) { + setMessage(null); + setErrorMessage(getSourceConflictMessage()); + return false; + } + + if (!isImportFromDirectory()) { + if (!ensureTarSourceIsValid(source.getAbsolutePath()) && !ensureZipSourceIsValid(source.getAbsolutePath())) { + setMessage(null); + setErrorMessage(Messages.ImportTraceWizard_BadArchiveFormat); + return false; + } + } + + if (fSelectionGroup.getCheckedElementCount() == 0) { + setMessage(null); + setErrorMessage(Messages.ImportTraceWizard_SelectTraceNoneSelected); + return false; + } + + IContainer container = getSpecifiedContainer(); + if (container != null && container.isVirtual()) { + if (Platform.getPreferencesService().getBoolean(Activator.PLUGIN_ID, ResourcesPlugin.PREF_DISABLE_LINKING, false, null)) { + setMessage(null); + setErrorMessage(Messages.ImportTraceWizard_CannotImportFilesUnderAVirtualFolder); + return false; + } + if (fCreateLinksInWorkspaceButton == null || !fCreateLinksInWorkspaceButton.getSelection()) { + setMessage(null); + setErrorMessage(Messages.ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder); + return false; + } + } + + setErrorMessage(null); + return true; + } + + private boolean isImportFromDirectory() { + return fImportFromDirectoryRadio != null && fImportFromDirectoryRadio.getSelection(); + } + + @Override + protected void restoreWidgetValues() { + super.restoreWidgetValues(); + + IDialogSettings settings = getDialogSettings(); + boolean value; + if (fImportUnrecognizedButton != null) { + if (settings.get(getPageStoreKey(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID)) == null) { + value = true; + } else { + value = settings.getBoolean(getPageStoreKey(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID)); + } + fImportUnrecognizedButton.setSelection(value); + } + + if (fPreserveFolderStructureButton != null) { + if (settings.get(getPageStoreKey(IMPORT_WIZARD_PRESERVE_FOLDERS_ID)) == null) { + value = true; + } else { + value = settings.getBoolean(getPageStoreKey(IMPORT_WIZARD_PRESERVE_FOLDERS_ID)); + } + fPreserveFolderStructureButton.setSelection(value); + } + + if (settings.get(getPageStoreKey(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID)) == null) { + value = true; + } else { + value = settings.getBoolean(getPageStoreKey(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID)); + } + + if (directoryNameField != null) { + restoreComboValues(directoryNameField, settings, getPageStoreKey(IMPORT_WIZARD_ROOT_DIRECTORY_ID)); + } + if (fArchiveNameField != null) { + restoreComboValues(fArchiveNameField, settings, getPageStoreKey(IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID)); + } + + if (fImportFromDirectoryRadio != null) { + fImportFromDirectoryRadio.setSelection(value); + if (value) { + directoryRadioSelected(); + } + } + if (fImportFromArchiveRadio != null) { + fImportFromArchiveRadio.setSelection(!value); + if (!value) { + archiveRadioSelected(); + } + } + } + + @Override + protected void saveWidgetValues() { + // Persist dialog settings + IDialogSettings settings = getDialogSettings(); + if (fImportUnrecognizedButton != null) { + settings.put(getPageStoreKey(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID), fImportUnrecognizedButton.getSelection()); + } + if (fPreserveFolderStructureButton != null) { + settings.put(getPageStoreKey(IMPORT_WIZARD_PRESERVE_FOLDERS_ID), fPreserveFolderStructureButton.getSelection()); + } + settings.put(getPageStoreKey(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID), isImportFromDirectory()); + + if (directoryNameField != null) { + saveComboValues(directoryNameField, settings, getPageStoreKey(IMPORT_WIZARD_ROOT_DIRECTORY_ID)); + } + if (fArchiveNameField != null) { + saveComboValues(fArchiveNameField, settings, getPageStoreKey(IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID)); + } + } + + private String getPageStoreKey(String key) { + return getName() + key; + } + + private static void restoreComboValues(Combo combo, IDialogSettings settings, String key) { + String[] directoryNames = settings.getArray(key); + if ((directoryNames != null) && (directoryNames.length != 0)) { + for (int i = 0; i < directoryNames.length; i++) { + combo.add(directoryNames[i]); + } + } + } + + private void saveComboValues(Combo combo, IDialogSettings settings, String key) { + // update names history + String[] directoryNames = settings.getArray(key); + if (directoryNames == null) { + directoryNames = new String[0]; + } + + String items[] = combo.getItems(); + for (int i = 0; i < items.length; i++) { + directoryNames = addToHistory(directoryNames, items[i]); + } + settings.put(key, directoryNames); + } + + // ------------------------------------------------------------------------ + // Import the trace(s) + // ------------------------------------------------------------------------ + + /** + * Finish the import. + * + * @return true if successful else false + */ + public boolean finish() { + String traceTypeName = getImportTraceTypeId(); + String traceId = null; + if (!TRACE_TYPE_AUTO_DETECT.equals(traceTypeName)) { + String tokens[] = traceTypeName.split(SEPARATOR, 2); + if (tokens.length < 2) { + return false; + } + traceId = TmfTraceType.getTraceTypeId(tokens[0], tokens[1]); + } + + // Save dialog settings + saveWidgetValues(); + + IPath baseSourceContainerPath = new Path(getSourceContainerPath()); + boolean importFromArchive = getSourceArchiveFile() != null; + int importOptionFlags = getImportOptionFlags(); + + final TraceValidateAndImportOperation operation = new TraceValidateAndImportOperation(traceId, baseSourceContainerPath, getContainerFullPath(), importFromArchive, + importOptionFlags); + + IStatus status = Status.OK_STATUS; + try { + getContainer().run(true, true, new IRunnableWithProgress() { + @Override + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + operation.run(monitor); + monitor.done(); + } + }); + + status = operation.getStatus(); + } catch (InvocationTargetException e) { + status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.ImportTraceWizard_ImportProblem, e); + } catch (InterruptedException e) { + status = Status.CANCEL_STATUS; + } + if (!status.isOK()) { + if (status.getSeverity() == IStatus.CANCEL) { + setMessage(Messages.ImportTraceWizard_ImportOperationCancelled); + setErrorMessage(null); + } else { + if (status.getException() != null) { + displayErrorDialog(status.getMessage() + ": " + status.getException()); //$NON-NLS-1$ + } + setMessage(null); + setErrorMessage(Messages.ImportTraceWizard_ImportProblem); + } + return false; + } + setErrorMessage(null); + return true; + } + + /** + * Get the trace type id to import as. This can also return + * {@link #TRACE_TYPE_AUTO_DETECT} to communicate that automatic trace type + * detection will occur instead of setting a specific trace type when + * importing the traces. + * + * @return the trace type id or {@link #TRACE_TYPE_AUTO_DETECT} + */ + protected String getImportTraceTypeId() { + return fTraceTypes.getText(); + } + + /** + * Get import options in the form of flags (bits). + * + * @return the import flags. + * @see #OPTION_CREATE_LINKS_IN_WORKSPACE + * @see #OPTION_IMPORT_UNRECOGNIZED_TRACES + * @see #OPTION_OVERWRITE_EXISTING_RESOURCES + * @see #OPTION_PRESERVE_FOLDER_STRUCTURE + */ + protected int getImportOptionFlags() { + int flags = 0; + if (fCreateLinksInWorkspaceButton != null && fCreateLinksInWorkspaceButton.getSelection()) { + flags |= OPTION_CREATE_LINKS_IN_WORKSPACE; + } + if (fImportUnrecognizedButton != null && fImportUnrecognizedButton.getSelection()) { + flags |= OPTION_IMPORT_UNRECOGNIZED_TRACES; + } + if (fOverwriteExistingResourcesCheckbox != null && fOverwriteExistingResourcesCheckbox.getSelection()) { + flags |= OPTION_OVERWRITE_EXISTING_RESOURCES; + } + if (fPreserveFolderStructureButton != null && fPreserveFolderStructureButton.getSelection()) { + flags |= OPTION_PRESERVE_FOLDER_STRUCTURE; + } + return flags; + } + + @Override + public void dispose() { + super.dispose(); + disposeSelectionGroupRoot(); + } + + // ------------------------------------------------------------------------ + // Classes + // ------------------------------------------------------------------------ + + private class TraceValidateAndImportOperation { + private IStatus fStatus; + private String fTraceType; + private IPath fDestinationContainerPath; + private IPath fBaseSourceContainerPath; + private boolean fImportFromArchive; + private int fImportOptionFlags; + private ImportConfirmation fConfirmationMode = ImportConfirmation.SKIP; + + private TraceValidateAndImportOperation(String traceId, IPath baseSourceContainerPath, IPath destinationContainerPath, boolean importFromArchive, int importOptionFlags) { + fTraceType = traceId; + fBaseSourceContainerPath = baseSourceContainerPath; + fDestinationContainerPath = destinationContainerPath; + fImportOptionFlags = importOptionFlags; + fImportFromArchive = importFromArchive; + + boolean overwriteExistingResources = (importOptionFlags & OPTION_OVERWRITE_EXISTING_RESOURCES) != 0; + if (overwriteExistingResources) { + fConfirmationMode = ImportConfirmation.OVERWRITE_ALL; + } + } + + public void run(IProgressMonitor progressMonitor) { + String currentPath = null; + final Map folderElements = new HashMap<>(); + try { + + final ArrayList fileSystemElements = new ArrayList<>(); + IElementFilter passThroughFilter = new IElementFilter() { + + @Override + public void filterElements(Collection elements, IProgressMonitor monitor) { + fileSystemElements.addAll(elements); + } + + @Override + public void filterElements(Object[] elements, IProgressMonitor monitor) { + for (int i = 0; i < elements.length; i++) { + fileSystemElements.add((TraceFileSystemElement) elements[i]); + } + } + }; + + // List fileSystemElements will be filled using the + // passThroughFilter + SubMonitor subMonitor = SubMonitor.convert(progressMonitor, 1); + fSelectionGroup.getAllCheckedListItems(passThroughFilter, subMonitor); + + // Check if operation was cancelled. + ModalContext.checkCanceled(subMonitor); + + Iterator fileSystemElementsIter = fileSystemElements.iterator(); + IFolder destTempFolder = null; + subMonitor = SubMonitor.convert(progressMonitor, fileSystemElements.size()); + if (fImportFromArchive) { + // When importing from archive, we first extract the + // *selected* files to a temporary folder then create a new + // Iterator that points to the + // extracted files. This way, the import operator can + // continue as it normally would. + + subMonitor = SubMonitor.convert(progressMonitor, fileSystemElements.size() * 2); + destTempFolder = fTargetFolder.getProject().getFolder(TRACE_IMPORT_TEMP_FOLDER); + if (destTempFolder.exists()) { + SubProgressMonitor monitor = new SubProgressMonitor(subMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK); + destTempFolder.delete(true, monitor); + } + SubProgressMonitor monitor = new SubProgressMonitor(subMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK); + destTempFolder.create(IResource.HIDDEN, true, monitor); + + fileSystemElementsIter = extractSelectedFiles(fileSystemElementsIter, destTempFolder, subMonitor); + // We need to update the source container path because the + // "preserve folder structure" option would create the + // wrong folders otherwise. + fBaseSourceContainerPath = destTempFolder.getLocation(); + } + + while (fileSystemElementsIter.hasNext()) { + ModalContext.checkCanceled(progressMonitor); + currentPath = null; + TraceFileSystemElement element = fileSystemElementsIter.next(); + IFileSystemObject fileSystemObject = element.getFileSystemObject(); + String resourcePath = element.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString()); + element.setDestinationContainerPath(computeDestinationContainerPath(new Path(resourcePath))); + + currentPath = resourcePath; + SubMonitor sub = subMonitor.newChild(1); + if (element.isDirectory()) { + if (!folderElements.containsKey(resourcePath)) { + if (isDirectoryTrace(element)) { + folderElements.put(resourcePath, element); + validateAndImportTrace(element, sub); + } + } + } else { + TraceFileSystemElement parentElement = (TraceFileSystemElement) element.getParent(); + String parentPath = parentElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString()); + parentElement.setDestinationContainerPath(computeDestinationContainerPath(new Path(parentPath))); + currentPath = parentPath; + if (!folderElements.containsKey(parentPath)) { + if (isDirectoryTrace(parentElement)) { + folderElements.put(parentPath, parentElement); + validateAndImportTrace(parentElement, sub); + } else { + if (fileSystemObject.exists()) { + validateAndImportTrace(element, sub); + } + } + } + } + } + + if (destTempFolder != null && destTempFolder.exists()) { + destTempFolder.delete(true, progressMonitor); + } + + setStatus(Status.OK_STATUS); + } catch (InterruptedException e) { + setStatus(Status.CANCEL_STATUS); + } catch (Exception e) { + String errorMessage = Messages.ImportTraceWizard_ImportProblem + ": " + //$NON-NLS-1$ + (currentPath != null ? currentPath : ""); //$NON-NLS-1$ + Activator.getDefault().logError(errorMessage, e); + setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, errorMessage, e)); + } + } + + private Iterator extractSelectedFiles(Iterator fileSystemElementsIter, IFolder tempFolder, IProgressMonitor progressMonitor) throws InterruptedException, + InvocationTargetException { + List subList = new ArrayList<>(); + Map sourceLocationMap = new HashMap<>(); + // Collect all the elements + while (fileSystemElementsIter.hasNext()) { + ModalContext.checkCanceled(progressMonitor); + TraceFileSystemElement element = fileSystemElementsIter.next(); + sourceLocationMap.put(new Path(element.getFileSystemObject().getName()).removeTrailingSeparator(), element.getSourceLocation()); + TraceFileSystemElement parentElement = (TraceFileSystemElement) element.getParent(); + sourceLocationMap.put(new Path(parentElement.getFileSystemObject().getName()).removeTrailingSeparator(), parentElement.getSourceLocation()); + if (element.isDirectory()) { + Object[] array = element.getFiles().getChildren(); + for (int i = 0; i < array.length; i++) { + subList.add((TraceFileSystemElement) array[i]); + } + } + subList.add(element); + } + + // Find a sensible root element + TraceFileSystemElement root = subList.get(0); + while (root.getParent() != null) { + root = (TraceFileSystemElement) root.getParent(); + } + + ImportProvider fileSystemStructureProvider = new ImportProvider(); + + IOverwriteQuery myQueryImpl = new IOverwriteQuery() { + @Override + public String queryOverwrite(String file) { + return IOverwriteQuery.NO_ALL; + } + }; + + progressMonitor.setTaskName(Messages.ImportTraceWizard_ExtractImportOperationTaskName); + IPath containerPath = tempFolder.getFullPath(); + ImportOperation operation = new ImportOperation(containerPath, root, fileSystemStructureProvider, myQueryImpl, subList); + operation.setContext(getShell()); + + operation.setCreateContainerStructure(true); + operation.setOverwriteResources(false); + operation.setVirtualFolders(false); + + operation.run(new SubProgressMonitor(progressMonitor, subList.size(), SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); + + // Create the new import provider and root element based on the + // extracted temp folder + FileSystemObjectImportStructureProvider importStructureProvider = new FileSystemObjectImportStructureProvider(FileSystemStructureProvider.INSTANCE, null); + IFileSystemObject rootElement = importStructureProvider.getIFileSystemObject(new File(tempFolder.getLocation().toOSString())); + TraceFileSystemElement createRootElement = createRootElement(rootElement, importStructureProvider); + List list = new ArrayList<>(); + getAllChildren(list, createRootElement); + Iterator extractedElementsIter = list.iterator(); + IPath tempPath = new Path(tempFolder.getLocation().toOSString()); + for (TraceFileSystemElement element : list) { + IPath path = new Path(((File) element.getFileSystemObject().getRawFileSystemObject()).getAbsolutePath()).makeRelativeTo(tempPath); + element.setSourceLocation(sourceLocationMap.get(path)); + TraceFileSystemElement parentElement = (TraceFileSystemElement) element.getParent(); + IPath parentPath = new Path(((File) parentElement.getFileSystemObject().getRawFileSystemObject()).getAbsolutePath()).makeRelativeTo(tempPath); + parentElement.setSourceLocation(sourceLocationMap.get(parentPath)); + } + return extractedElementsIter; + } + + /** + * Get all the TraceFileSystemElements recursively. + * + * @param result + * the list accumulating the result + * @param rootElement + * the root element of the file system to be imported + */ + private void getAllChildren(List result, TraceFileSystemElement rootElement) { + AdaptableList files = rootElement.getFiles(); + for (Object file : files.getChildren()) { + result.add((TraceFileSystemElement) file); + } + + AdaptableList folders = rootElement.getFolders(); + for (Object folder : folders.getChildren()) { + getAllChildren(result, (TraceFileSystemElement) folder); + } + } + + private IPath computeDestinationContainerPath(Path resourcePath) { + IPath destinationContainerPath = fDestinationContainerPath; + + // We need to figure out the new destination path relative to the + // selected "base" source directory. + // Here for example, the selected source directory is /home/user + if ((fImportOptionFlags & OPTION_PRESERVE_FOLDER_STRUCTURE) != 0) { + // /home/user/bar/foo/trace -> /home/user/bar/foo + IPath sourceContainerPath = resourcePath.removeLastSegments(1); + if (fBaseSourceContainerPath.equals(resourcePath)) { + // Use resourcePath directory if fBaseSourceContainerPath + // points to a directory trace + sourceContainerPath = resourcePath; + } + // /home/user/bar/foo, /home/user -> bar/foo + IPath relativeContainerPath = sourceContainerPath.makeRelativeTo(fBaseSourceContainerPath); + // project/Traces + bar/foo -> project/Traces/bar/foo + destinationContainerPath = fDestinationContainerPath.append(relativeContainerPath); + } + return destinationContainerPath; + } + + private void validateAndImportTrace(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor) + throws TmfTraceImportException, CoreException, InvocationTargetException, InterruptedException { + String parentContainerPath = fBaseSourceContainerPath.toOSString(); + String path = fileSystemElement.getFileSystemObject().getAbsolutePath(parentContainerPath); + TraceTypeHelper traceTypeHelper = null; + + if (fTraceType == null) { + // Auto Detection + try { + traceTypeHelper = TmfTraceTypeUIUtils.selectTraceType(path, null, null); + } catch (TmfTraceImportException e) { + // the trace did not match any trace type + } + if (traceTypeHelper == null) { + if ((fImportOptionFlags & OPTION_IMPORT_UNRECOGNIZED_TRACES) != 0) { + importResource(fileSystemElement, monitor); + } + return; + } + } else { + boolean isDirectoryTraceType = TmfTraceType.isDirectoryTraceType(fTraceType); + if (fileSystemElement.isDirectory() != isDirectoryTraceType) { + return; + } + traceTypeHelper = TmfTraceType.getTraceType(fTraceType); + + if (traceTypeHelper == null) { + // Trace type not found + throw new TmfTraceImportException(Messages.ImportTraceWizard_TraceTypeNotFound); + } + + if (!traceTypeHelper.validate(path).isOK()) { + // Trace type exist but doesn't validate for given trace. + return; + } + } + + // Finally import trace + IResource importedResource = importResource(fileSystemElement, monitor); + if (importedResource != null) { + TmfTraceTypeUIUtils.setTraceType(importedResource, traceTypeHelper); + } + + } + + /** + * Imports a trace resource to project. In case of name collision the + * user will be asked to confirm overwriting the existing trace, + * overwriting or skipping the trace to be imported. + * + * @param fileSystemElement + * trace file system object to import + * @param monitor + * a progress monitor + * @return the imported resource or null if no resource was imported + * + * @throws InvocationTargetException + * if problems during import operation + * @throws InterruptedException + * if cancelled + * @throws CoreException + * if problems with workspace + */ + private IResource importResource(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor) + throws InvocationTargetException, InterruptedException, CoreException { + + ImportConfirmation mode = checkForNameClashes(fileSystemElement); + switch (mode) { + case RENAME: + case RENAME_ALL: + rename(fileSystemElement); + break; + case OVERWRITE: + case OVERWRITE_ALL: + delete(fileSystemElement, monitor); + break; + case CONTINUE: + break; + case SKIP: + case SKIP_ALL: + default: + return null; + } + + List subList = new ArrayList<>(); + + FileSystemElement parentFolder = fileSystemElement.getParent(); + + IPath containerPath = fileSystemElement.getDestinationContainerPath(); + IPath tracePath = containerPath.addTrailingSeparator().append(fileSystemElement.getLabel()); + boolean createLinksInWorkspace = (fImportOptionFlags & OPTION_CREATE_LINKS_IN_WORKSPACE) != 0; + if (fileSystemElement.isDirectory() && !createLinksInWorkspace) { + containerPath = tracePath; + + Object[] array = fileSystemElement.getFiles().getChildren(); + for (int i = 0; i < array.length; i++) { + subList.add((TraceFileSystemElement) array[i]); + } + parentFolder = fileSystemElement; + + } else { + subList.add(fileSystemElement); + } + + ImportProvider fileSystemStructureProvider = new ImportProvider(); + + IOverwriteQuery myQueryImpl = new IOverwriteQuery() { + @Override + public String queryOverwrite(String file) { + return IOverwriteQuery.NO_ALL; + } + }; + + monitor.setTaskName(Messages.ImportTraceWizard_ImportOperationTaskName + " " + fileSystemElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString())); //$NON-NLS-1$ + ImportOperation operation = new ImportOperation(containerPath, parentFolder, fileSystemStructureProvider, myQueryImpl, subList); + operation.setContext(getShell()); + + operation.setCreateContainerStructure(false); + operation.setOverwriteResources(false); + operation.setCreateLinks(createLinksInWorkspace); + operation.setVirtualFolders(false); + + operation.run(new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); + String sourceLocation = fileSystemElement.getSourceLocation(); + IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(tracePath); + if (sourceLocation != null) { + resource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation); + } + + return resource; + } + + private boolean isDirectoryTrace(TraceFileSystemElement fileSystemElement) { + String path = fileSystemElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString()); + if (TmfTraceType.isDirectoryTrace(path)) { + return true; + } + return false; + } + + private ImportConfirmation checkForNameClashes(TraceFileSystemElement fileSystemElement) throws InterruptedException { + IPath tracePath = getInitialDestinationPath(fileSystemElement); + + // handle rename + if (getExistingTrace(tracePath) != null) { + if ((fConfirmationMode == ImportConfirmation.RENAME_ALL) || + (fConfirmationMode == ImportConfirmation.OVERWRITE_ALL) || + (fConfirmationMode == ImportConfirmation.SKIP_ALL)) { + return fConfirmationMode; + } + + int returnCode = promptForOverwrite(tracePath); + if (returnCode < 0) { + // Cancel + throw new InterruptedException(); + } + fConfirmationMode = ImportConfirmation.values()[returnCode]; + return fConfirmationMode; + } + return ImportConfirmation.CONTINUE; + } + + private int promptForOverwrite(IPath tracePath) { + final MessageDialog dialog = new MessageDialog(getContainer() + .getShell(), null, null, NLS.bind(Messages.ImportTraceWizard_TraceAlreadyExists, tracePath.makeRelativeTo(fTraceFolderElement.getProject().getPath())), + MessageDialog.QUESTION, new String[] { + ImportConfirmation.RENAME.getInName(), + ImportConfirmation.RENAME_ALL.getInName(), + ImportConfirmation.OVERWRITE.getInName(), + ImportConfirmation.OVERWRITE_ALL.getInName(), + ImportConfirmation.SKIP.getInName(), + ImportConfirmation.SKIP_ALL.getInName(), + }, 4) { + @Override + protected int getShellStyle() { + return super.getShellStyle() | SWT.SHEET; + } + }; + + final int[] returnValue = new int[1]; + getShell().getDisplay().syncExec(new Runnable() { + + @Override + public void run() { + returnValue[0] = dialog.open(); + } + }); + return returnValue[0]; + } + + /** + * @return the initial destination path, before rename, if any + */ + private IPath getInitialDestinationPath(TraceFileSystemElement fileSystemElement) { + IPath traceFolderPath = fileSystemElement.getDestinationContainerPath(); + return traceFolderPath.append(fileSystemElement.getFileSystemObject().getLabel()); + } + + private void rename(TraceFileSystemElement fileSystemElement) { + IPath tracePath = getInitialDestinationPath(fileSystemElement); + TmfTraceElement trace = getExistingTrace(tracePath); + if (trace == null) { + return; + } + + // Not using IFolder on purpose to leave the door open to import + // directly into an IProject + IContainer folder = (IContainer) trace.getParent().getResource(); + int i = 2; + while (true) { + String name = trace.getName() + '(' + Integer.toString(i++) + ')'; + IResource resource = folder.findMember(name); + if (resource == null) { + fileSystemElement.setLabel(name); + return; + } + } + } + + private void delete(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor) throws CoreException { + IPath tracePath = getInitialDestinationPath(fileSystemElement); + TmfTraceElement trace = getExistingTrace(tracePath); + if (trace == null) { + return; + } + + trace.delete(monitor); + } + + private TmfTraceElement getExistingTrace(IPath tracePath) { + List traces = fTraceFolderElement.getTraces(); + for (TmfTraceElement t : traces) { + if (t.getPath().equals(tracePath)) { + return t; + } + } + return null; + } + + /** + * Set the status for this operation + * + * @param status + * the status + */ + protected void setStatus(IStatus status) { + fStatus = status; + } + + public IStatus getStatus() { + return fStatus; + } + } + + /** + * The TraceFileSystemElement is a + * FileSystemElement that knows if it has been populated or + * not. + */ + private static class TraceFileSystemElement extends FileSystemElement { + + private boolean fIsPopulated = false; + private String fLabel = null; + private IPath fDestinationContainerPath; + private FileSystemObjectImportStructureProvider fProvider; + private String fSourceLocation; + + public TraceFileSystemElement(String name, FileSystemElement parent, boolean isDirectory, FileSystemObjectImportStructureProvider provider) { + super(name, parent, isDirectory); + fProvider = provider; + } + + public void setDestinationContainerPath(IPath destinationContainerPath) { + fDestinationContainerPath = destinationContainerPath; + } + + public void setPopulated() { + fIsPopulated = true; + } + + public boolean isPopulated() { + return fIsPopulated; + } + + @Override + public AdaptableList getFiles() { + if (!fIsPopulated) { + populateElementChildren(); + } + return super.getFiles(); + } + + @Override + public AdaptableList getFolders() { + if (!fIsPopulated) { + populateElementChildren(); + } + return super.getFolders(); + } + + /** + * Sets the label for the trace to be used when importing at trace. + * + * @param name + * the label for the trace + */ + public void setLabel(String name) { + fLabel = name; + } + + /** + * Returns the label for the trace to be used when importing at trace. + * + * @return the label of trace resource + */ + public String getLabel() { + if (fLabel == null) { + return getFileSystemObject().getLabel(); + } + return fLabel; + } + + /** + * The full path to the container that will contain the trace + * + * @return the destination container path + */ + public IPath getDestinationContainerPath() { + return fDestinationContainerPath; + } + + /** + * Populates the children of the specified parent + * FileSystemElement + */ + private void populateElementChildren() { + List allchildren = fProvider.getChildren(this.getFileSystemObject()); + Object child = null; + TraceFileSystemElement newelement = null; + Iterator iter = allchildren.iterator(); + while (iter.hasNext()) { + child = iter.next(); + newelement = new TraceFileSystemElement(fProvider.getLabel(child), this, fProvider.isFolder(child), fProvider); + newelement.setFileSystemObject(child); + } + setPopulated(); + } + + public FileSystemObjectImportStructureProvider getProvider() { + return fProvider; + } + + @Override + public IFileSystemObject getFileSystemObject() { + Object fileSystemObject = super.getFileSystemObject(); + return (IFileSystemObject) fileSystemObject; + } + + public String getSourceLocation() { + if (fSourceLocation == null) { + fSourceLocation = getFileSystemObject().getSourceLocation(); + } + return fSourceLocation; + } + + public void setSourceLocation(String sourceLocation) { + fSourceLocation = sourceLocation; + } + } + + /** + * This interface abstracts the differences between different kinds of + * FileSystemObjects such as File, TarEntry and ZipEntry. This allows + * clients (TraceFileSystemElement, TraceValidateAndImportOperation) to + * handle all the types transparently. + */ + private interface IFileSystemObject { + String getLabel(); + + String getName(); + + String getAbsolutePath(String parentContainerPath); + + String getSourceLocation(); + + Object getRawFileSystemObject(); + + boolean exists(); + } + + /** + * The "File" implementation of an IFileSystemObject + */ + private static class FileFileSystemObject implements IFileSystemObject { + + private File fFileSystemObject; + + private FileFileSystemObject(File fileSystemObject) { + fFileSystemObject = fileSystemObject; + } + + @Override + public String getLabel() { + String name = fFileSystemObject.getName(); + if (name.length() == 0) { + return fFileSystemObject.getPath(); + } + return name; + } + + @Override + public String getName() { + return fFileSystemObject.getName(); + } + + @Override + public String getAbsolutePath(String parentContainerPath) { + return fFileSystemObject.getAbsolutePath(); + } + + @Override + public boolean exists() { + return fFileSystemObject.exists(); + } + + @Override + public String getSourceLocation() { + IResource sourceResource; + String sourceLocation = null; + if (fFileSystemObject.isDirectory()) { + sourceResource = ResourcesPlugin.getWorkspace().getRoot().getContainerForLocation(Path.fromOSString(fFileSystemObject.getAbsolutePath())); + } else { + sourceResource = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(Path.fromOSString(fFileSystemObject.getAbsolutePath())); + } + if (sourceResource != null && sourceResource.exists()) { + try { + sourceLocation = sourceResource.getPersistentProperty(TmfCommonConstants.SOURCE_LOCATION); + } catch (CoreException e) { + // Something went wrong with the already existing resource. + // This is not a problem, we'll assign a new location below. + } + } + if (sourceLocation == null) { + sourceLocation = URIUtil.toUnencodedString(fFileSystemObject.toURI()); + } + return sourceLocation; + } + + @Override + public Object getRawFileSystemObject() { + return fFileSystemObject; + } + } + + /** + * The "Tar" implementation of an IFileSystemObject + */ + private static class TarFileSystemObject implements IFileSystemObject { + + private TarEntry fFileSystemObject; + private String fArchivePath; + + private TarFileSystemObject(TarEntry fileSystemObject, String archivePath) { + fFileSystemObject = fileSystemObject; + fArchivePath = archivePath; + } + + @Override + public String getLabel() { + return new Path(fFileSystemObject.getName()).lastSegment(); + } + + @Override + public String getName() { + return fFileSystemObject.getName(); + } + + @Override + public String getAbsolutePath(String parentContainerPath) { + return new Path(parentContainerPath).append(fFileSystemObject.getName()).toOSString(); + } + + @Override + public boolean exists() { + return true; + } + + @Override + public String getSourceLocation() { + URI uri = new File(fArchivePath).toURI(); + IPath entryPath = new Path(fFileSystemObject.getName()); + return URIUtil.toUnencodedString(URIUtil.toJarURI(uri, entryPath)); + } + + @Override + public Object getRawFileSystemObject() { + return fFileSystemObject; + } + } + + /** + * The "Zip" implementation of an IFileSystemObject + */ + private static class ZipFileSystemObject implements IFileSystemObject { + + private ZipEntry fFileSystemObject; + private String fArchivePath; + + private ZipFileSystemObject(ZipEntry fileSystemObject, String archivePath) { + fFileSystemObject = fileSystemObject; + fArchivePath = archivePath; + } + + @Override + public String getLabel() { + return new Path(fFileSystemObject.getName()).lastSegment(); + } + + @Override + public String getName() { + return fFileSystemObject.getName(); + } + + @Override + public String getAbsolutePath(String parentContainerPath) { + return new Path(parentContainerPath).append(fFileSystemObject.getName()).toOSString(); + } + + @Override + public boolean exists() { + return true; + } + + @Override + public String getSourceLocation() { + URI uri = new File(fArchivePath).toURI(); + IPath entryPath = new Path(fFileSystemObject.getName()); + return URIUtil.toUnencodedString(URIUtil.toJarURI(uri, entryPath)); + } + + @Override + public Object getRawFileSystemObject() { + return fFileSystemObject; + } + } + + private class ImportProvider implements IImportStructureProvider { + + ImportProvider() { + } + + @Override + public String getLabel(Object element) { + TraceFileSystemElement resource = (TraceFileSystemElement) element; + return resource.getLabel(); + } + + @Override + public List getChildren(Object element) { + TraceFileSystemElement resource = (TraceFileSystemElement) element; + Object[] array = resource.getFiles().getChildren(); + List list = new ArrayList<>(); + for (int i = 0; i < array.length; i++) { + list.add(array[i]); + } + return list; + } + + @Override + public InputStream getContents(Object element) { + TraceFileSystemElement resource = (TraceFileSystemElement) element; + return resource.getProvider().getContents(resource.getFileSystemObject()); + } + + @Override + public String getFullPath(Object element) { + TraceFileSystemElement resource = (TraceFileSystemElement) element; + return resource.getProvider().getFullPath(resource.getFileSystemObject()); + } + + @Override + public boolean isFolder(Object element) { + TraceFileSystemElement resource = (TraceFileSystemElement) element; + return resource.isDirectory(); + } + } + + private enum ImportConfirmation { + // ------------------------------------------------------------------------ + // Enum definition + // ------------------------------------------------------------------------ + RENAME(Messages.ImportTraceWizard_ImportConfigurationRename), + RENAME_ALL(Messages.ImportTraceWizard_ImportConfigurationRenameAll), + OVERWRITE(Messages.ImportTraceWizard_ImportConfigurationOverwrite), + OVERWRITE_ALL(Messages.ImportTraceWizard_ImportConfigurationOverwriteAll), + SKIP(Messages.ImportTraceWizard_ImportConfigurationSkip), + SKIP_ALL(Messages.ImportTraceWizard_ImportConfigurationSkipAll), + CONTINUE("CONTINUE"); //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * Name of enum + */ + private final String fInName; + + // ------------------------------------------------------------------------ + // Constuctors + // ------------------------------------------------------------------------ + + /** + * Private constructor + * + * @param name + * the name of state + */ + private ImportConfirmation(String name) { + fInName = name; + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + /** + * @return state name + */ + public String getInName() { + return fInName; + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardPageOptions.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardPageOptions.java new file mode 100644 index 0000000000..937721edf6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardPageOptions.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Marc-Andre Laperle - Use common method to get opened tmf projects + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.List; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTracesFolder; +import org.eclipse.tracecompass.tmf.ui.project.model.TraceUtils; +import org.eclipse.ui.IWorkbench; + +/** + * This page selects the project to import to. + * + * @author Matthew Khouzam + * @since 2.0 + */ +public class ImportTraceWizardPageOptions extends AbstractImportTraceWizardPage { + + private List fProjects; + private final Map fProjectsMap = new LinkedHashMap<>(); + + /** + * Import page that tells where the trace will go + * + * @param workbench + * The workbench reference. + * @param selection + * The current selection + */ + public ImportTraceWizardPageOptions(IWorkbench workbench, IStructuredSelection selection) { + super(workbench, selection); + } + + @Override + public void createControl(Composite parent) { + super.createControl(parent); + IFolder originalFolder = getBatchWizard().getTargetFolder(); + IProject proj = null; + if (originalFolder != null) { + proj = originalFolder.getProject(); + } + + Composite optionPane = (Composite) this.getControl(); + optionPane.setLayout(new GridLayout()); + optionPane.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true)); + + fProjects = new List(optionPane, SWT.V_SCROLL); + fProjects.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + for (IProject project : TraceUtils.getOpenedTmfProjects()) { + final String name = project.getName(); + fProjectsMap.put(name, project); + fProjects.add(name); + } + + fProjects.getSelection(); + fProjects.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + updateWithSelection(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + updateWithSelection(); + } + }); + if (proj != null) { + fProjects.setSelection(fProjects.indexOf(proj.getName())); + } else if (fProjects.getItemCount() > 0) { + fProjects.setSelection(0); + updateWithSelection(); + } + setMessage(Messages.SharedSelectProject); + this.setTitle(Messages.ImportTraceWizardPageOptionsTitle); + } + + private void updateWithSelection() { + String[] selection = fProjects.getSelection(); + if (selection.length > 0) { + final String listItem = selection[0]; + IFolder folder = fProjectsMap.get(listItem).getFolder(TmfTracesFolder.TRACES_FOLDER_NAME); + getBatchWizard().setTraceFolder(folder); + ImportTraceWizardPageOptions.this.setErrorMessage(null); + } else { + ImportTraceWizardPageOptions.this.setErrorMessage(Messages.SharedSelectProject); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardScanPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardScanPage.java new file mode 100644 index 0000000000..aef3e36bc6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardScanPage.java @@ -0,0 +1,566 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace; + +import java.io.File; +import java.text.DecimalFormat; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTreeViewer; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ColumnViewer; +import org.eclipse.jface.viewers.ColumnViewerEditor; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.jface.viewers.TreeViewerEditor; +import org.eclipse.jface.viewers.TreeViewerFocusCellManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TraceValidationHelper; +import org.eclipse.ui.IWorkbench; + +/** + * Import page that scans files, can be cancelled this page is the third + * of three pages shown. This one selects the traces to be imported that are to + * be scanned. + * + * @author Matthew Khouzam + * @since 2.0 + */ +public class ImportTraceWizardScanPage extends AbstractImportTraceWizardPage { + + private static final int COL_WIDTH = 200; + private static final int MAX_TRACES = 65536; + private CheckboxTreeViewer traceTypeViewer; + + final ScanRunnable fRunnable = new ScanRunnable("Scan job"); //$NON-NLS-1$ + final private BlockingQueue fTracesToScan = new ArrayBlockingQueue<>(MAX_TRACES); + private volatile boolean fCanRun = true; + + // -------------------------------------------------------------------------------- + // Constructor and destructor + // -------------------------------------------------------------------------------- + + /** + * Import page that scans files, can be cancelled. + * + * @param name + * The name of the page. + * @param selection + * The current selection + */ + protected ImportTraceWizardScanPage(String name, IStructuredSelection selection) { + super(name, selection); + } + + /** + * Import page that scans files, can be cancelled + * + * @param workbench + * The workbench reference. + * @param selection + * The current selection + */ + public ImportTraceWizardScanPage(IWorkbench workbench, IStructuredSelection selection) { + super(workbench, selection); + } + + @Override + public void dispose() { + fCanRun = false; + fRunnable.done(Status.OK_STATUS); + super.dispose(); + } + + /* + * Init + */ + + @Override + public void createControl(Composite parent) { + super.createControl(parent); + final Composite control = (Composite) this.getControl(); + setTitle(Messages.ImportTraceWizardScanPageTitle); + traceTypeViewer = new CheckboxTreeViewer(control, SWT.CHECK); + traceTypeViewer.setContentProvider(getBatchWizard().getScannedTraces()); + traceTypeViewer.getTree().setHeaderVisible(true); + traceTypeViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + traceTypeViewer.setInput(getBatchWizard().getScannedTraces()); + traceTypeViewer.addCheckStateListener(new ImportTraceCheckStateListener()); + + TreeViewerFocusCellManager focusCellManager = new TreeViewerFocusCellManager(traceTypeViewer, new FocusCellOwnerDrawHighlighter(traceTypeViewer)); + ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(traceTypeViewer) { + }; + TreeViewerEditor.create(traceTypeViewer, focusCellManager, actSupport, ColumnViewerEditor.TABBING_HORIZONTAL + | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR + | ColumnViewerEditor.TABBING_VERTICAL | ColumnViewerEditor.KEYBOARD_ACTIVATION); + + final TextCellEditor textCellEditor = new TextCellEditor(traceTypeViewer.getTree()); + // -------------------- + // Column 1 + // -------------------- + TreeViewerColumn column = new TreeViewerColumn(traceTypeViewer, SWT.NONE); + column.getColumn().setWidth(COL_WIDTH); + column.getColumn().setText(Messages.ImportTraceWizardTraceDisplayName); + column.setLabelProvider(new FirstColumnLabelProvider()); + column.setEditingSupport(new ColumnEditorSupport(traceTypeViewer, textCellEditor)); + + // -------------------- + // Column 2 + // -------------------- + + column = new TreeViewerColumn(traceTypeViewer, SWT.NONE); + column.getColumn().setWidth(500); + column.getColumn().setText(Messages.ImportTraceWizardImportCaption); + column.setLabelProvider(new ColumnLabelProvider() { + @Override + public String getText(Object element) { + if (element instanceof FileAndName) { + FileAndName elem = (FileAndName) element; + return elem.getFile().getPath(); + } + return null; + } + }); + // -------------------- + // Column 3 + // -------------------- + + column = new TreeViewerColumn(traceTypeViewer, SWT.NONE); + + column.getColumn().setWidth(80); + column.getColumn().setText(Messages.ImportTraceWizardScanPageSize); + column.getColumn().setAlignment(SWT.RIGHT); + column.setLabelProvider(new ColumnLabelProvider() { + + @Override + public String getText(Object element) { + if (element instanceof FileAndName) { + + FileAndName elem = (FileAndName) element; + long len = recurseSize(elem.getFile()); + if (len > 0) { + double sizeb10 = Math.log10(len); + DecimalFormat df = new DecimalFormat(); + df.setMaximumFractionDigits(2); + df.setMinimumFractionDigits(0); + if (sizeb10 > 12) { + final double tbSize = len / 1024.0 / 1024 / 1024 / 1024; + return df.format(tbSize) + Messages.ImportTraceWizardScanPageTerabyte; + } + if (sizeb10 > 9) { + final double gbSize = len / 1024.0 / 1024 / 1024; + return df.format(gbSize) + Messages.ImportTraceWizardScanPageGigabyte; + } + if (sizeb10 > 6) { + final double mbSize = len / 1024.0 / 1024; + return df.format(mbSize) + Messages.ImportTraceWizardScanPageMegabyte; + } + if (sizeb10 > 3) { + final double kbSize = len / 1024.0; + return df.format(kbSize) + Messages.ImportTraceWizardScanPageKilobyte; + } + } + return Long.toString(len) + Messages.ImportTraceWizardScanPagebyte; + + } + return null; + } + + private long recurseSize(File file) { + if (file.isFile() && file.canRead()) { + return file.length(); + } + long size = 0; + if (file.exists() && file.isDirectory() && file.canRead()) { + final File[] listFiles = file.listFiles(); + if (listFiles != null) { + for (File child : listFiles) { + if (child.isFile() && child.canRead()) { + size += child.length(); + } else if (child.isDirectory()) { + size += recurseSize(child); + } else { + Activator.getDefault().logError("Unknown \"file\" type for " + child + ' ' + child.toString()); //$NON-NLS-1$ + } + } + } + } + return size; + } + }); + + init(); + getBatchWizard().setTracesToScan(fTracesToScan); + getBatchWizard().setTraceFolder(fTargetFolder); + + fRunnable.schedule(); + setErrorMessage(Messages.ImportTraceWizardScanPageSelectAtleastOne); + } + + private void init() { + Composite optionPane = (Composite) this.getControl(); + + optionPane.setLayout(new GridLayout()); + optionPane.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true)); + + final Button fLink = new Button(optionPane, SWT.RADIO); + fLink.setText(Messages.ImportTraceWizardLinkTraces); + fLink.setSelection(true); + fLink.setLayoutData(new GridData()); + + final Button fCopy = new Button(optionPane, SWT.RADIO); + fCopy.setText(Messages.ImportTraceWizardCopyTraces); + fCopy.setLayoutData(new GridData()); + + final SelectionListener linkedListener = new RadioChooser(fLink); + + fLink.addSelectionListener(linkedListener); + fCopy.addSelectionListener(linkedListener); + + Button fOverwrite = new Button(optionPane, SWT.CHECK); + fOverwrite.setText(Messages.ImportTraceWizardOverwriteTraces); + fOverwrite.setLayoutData(new GridData()); + fOverwrite.setSelection(true); + fOverwrite.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + getBatchWizard().setOverwrite(((Button) e.widget).getSelection()); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + } + + /* + * Helper classes + */ + + private final class RadioChooser implements SelectionListener { + final private Button isLinked; + + public RadioChooser(Button desiredButton) { + isLinked = desiredButton; + } + + @Override + public void widgetSelected(SelectionEvent e) { + + final Button widget = (Button) e.widget; + getBatchWizard().setLinked(widget.equals(isLinked)); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + + } + } + + private final class ColumnEditorSupport extends EditingSupport { + private final TextCellEditor textCellEditor; + + private ColumnEditorSupport(ColumnViewer viewer, TextCellEditor textCellEditor) { + super(viewer); + this.textCellEditor = textCellEditor; + } + + @Override + protected boolean canEdit(Object element) { + return element instanceof FileAndName; + } + + @Override + protected CellEditor getCellEditor(Object element) { + return textCellEditor; + } + + @Override + protected Object getValue(Object element) { + if (element instanceof FileAndName) { + return ((FileAndName) element).getName(); + } + return null; + } + + @Override + protected void setValue(Object element, Object value) { + FileAndName fan = (FileAndName) element; + fan.setName((String) value); + getBatchWizard().updateConflicts(); + traceTypeViewer.update(element, null); + traceTypeViewer.refresh(); + } + } + + private final class FirstColumnLabelProvider extends ColumnLabelProvider { + Image fConflict; + + @Override + public Image getImage(Object element) { + if (element instanceof FileAndName) { + final FileAndName fan = (FileAndName) element; + if (fan.isConflictingName()) { + if (fConflict == null) { + fConflict = Activator.getDefault().getImageFromImageRegistry(ITmfImageConstants.IMG_UI_CONFLICT); + } + return fConflict; + } + } + return null; + } + + @Override + public String getText(Object element) { + if (element instanceof FileAndName) { + FileAndName elem = (FileAndName) element; + return elem.getName(); + } + if (element instanceof String) { + return (String) element; + } + return null; + } + } + + private final class ImportTraceCheckStateListener implements ICheckStateListener { + @Override + public void checkStateChanged(CheckStateChangedEvent event) { + final CheckboxTreeViewer tv = (CheckboxTreeViewer) + event.getSource(); + if (event.getElement() instanceof FileAndName) { + final FileAndName element = (FileAndName) event.getElement(); + if (event.getChecked()) { + getBatchWizard().addFileToImport(element); + traceTypeViewer.update(element, null); + } + else { + getBatchWizard().removeFileToImport(element); + traceTypeViewer.update(element, null); + } + maintainCheckIntegrity(tv, element); + } + if (event.getElement() instanceof String) { + + tv.setSubtreeChecked(event.getElement(), event.getChecked()); + final Object[] children = + getBatchWizard().getScannedTraces().getChildren(event.getElement()); + if (event.getChecked()) { + for (int i = 0; i < children.length; i++) { + final FileAndName element = (FileAndName) children[i]; + getBatchWizard().addFileToImport(element); + traceTypeViewer.update(children[i], null); + } + } + else { + for (int i = 0; i < children.length; i++) { + getBatchWizard().removeFileToImport((FileAndName) children[i]); + + } + } + + } + getBatchWizard().updateConflicts(); + if (getBatchWizard().hasConflicts()) { + setErrorMessage(Messages.ImportTraceWizardScanPageRenameError); + } else if (!getBatchWizard().hasTracesToImport()) { + setErrorMessage(Messages.ImportTraceWizardScanPageSelectAtleastOne); + } else { + setErrorMessage(null); + } + getWizard().getContainer().updateButtons(); + traceTypeViewer.update(event.getElement(), null); + } + + private void maintainCheckIntegrity(final CheckboxTreeViewer viewer, final FileAndName element) { + final ImportTraceContentProvider scannedTraces = getBatchWizard().getScannedTraces(); + String parentElement = (String) scannedTraces.getParent(element); + boolean allChecked = true; + final FileAndName[] siblings = scannedTraces.getSiblings(element); + if (siblings != null) { + for (FileAndName child : siblings) { + allChecked &= viewer.getChecked(child); + } + } + viewer.setChecked(parentElement, allChecked); + } + } + + private final class ScanRunnable extends Job { + + // monitor is stored here, starts as the main monitor but becomes a + // submonitor + private IProgressMonitor fMonitor; + + public ScanRunnable(String name) { + super(name); + this.setSystem(true); + } + + private synchronized IProgressMonitor getMonitor() { + return fMonitor; + } + + @Override + public IStatus run(IProgressMonitor monitor) { + /* + * Set up phase, it is synchronous + */ + fMonitor = monitor; + final Control control = traceTypeViewer.getControl(); + // please note the sync exec here is to allow us to set + control.getDisplay().syncExec(new Runnable() { + @Override + public void run() { + // monitor gets overwritten here so it's necessary to save + // it in a field. + fMonitor = SubMonitor.convert(getMonitor()); + getMonitor().setTaskName(Messages.ImportTraceWizardPageScanScanning + ' '); + ((SubMonitor) getMonitor()).setWorkRemaining(IProgressMonitor.UNKNOWN); + } + }); + /* + * At this point we start calling async execs and updating the view. + * This is a good candidate to parallelise. + */ + while (fCanRun == true) { + boolean updated = false; + boolean validCombo; + if (fTracesToScan.isEmpty() && !control.isDisposed()) { + control.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if (!control.isDisposed()) { + getMonitor().setTaskName(Messages.ImportTraceWizardPageScanScanning + ' '); + getMonitor().subTask(Messages.ImportTraceWizardPageScanDone); + ImportTraceWizardScanPage.this.setMessage(Messages.ImportTraceWizardPageScanScanning + ' ' + Messages.ImportTraceWizardPageScanDone); + } + } + }); + } + try { + final TraceValidationHelper traceToScan = fTracesToScan.take(); + + if (!getBatchWizard().hasScanned(traceToScan)) { + getBatchWizard().addResult(traceToScan, TmfTraceType.validate(traceToScan)); + } + + /* + * The following is to update the UI + */ + validCombo = getBatchWizard().getResult(traceToScan); + if (validCombo) { + // Synched on it's parent + + getBatchWizard().getScannedTraces().addCandidate(traceToScan.getTraceType(), new File(traceToScan.getTraceToScan())); + updated = true; + } + final int scanned = getBatchWizard().getNumberOfResults(); + final int total = scanned + fTracesToScan.size(); + final int prevVal = (int) ((scanned - 1) * 100.0 / total); + final int curVal = (int) ((scanned) * 100.0 / total); + if (curVal != prevVal) { + updated = true; + } + /* + * update the progress + */ + if (updated) { + if (!control.isDisposed()) { + control.getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + if (!control.isDisposed()) { + getMonitor().setTaskName(Messages.ImportTraceWizardPageScanScanning + ' '); + getMonitor().subTask(traceToScan.getTraceToScan()); + getMonitor().worked(1); + ImportTraceWizardScanPage.this.setMessage(Messages.ImportTraceWizardPageScanScanning + ' ' + + Integer.toString(curVal) + + '%'); + } + } + } + ); + } + } + + /* + * here we update the table + */ + final boolean editing = traceTypeViewer.isCellEditorActive(); + if (updated && !editing) { + if (!control.isDisposed()) { + control.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if (!control.isDisposed()) { + if (!traceTypeViewer.isCellEditorActive()) { + traceTypeViewer.refresh(); + } + } + } + }); + } + } + } catch (InterruptedException e) { + return new Status(IStatus.CANCEL, Activator.PLUGIN_ID, new String()); + } + } + return Status.OK_STATUS; + } + } + + /** + * Refresh the view and the corresponding model. + */ + public void refresh() { + final Control control = traceTypeViewer.getControl(); + if (!control.isDisposed()) { + control.getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + if (!control.isDisposed()) { + traceTypeViewer.refresh(); + } + } + }); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardSelectDirectoriesPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardSelectDirectoriesPage.java new file mode 100644 index 0000000000..edcd30447a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardSelectDirectoriesPage.java @@ -0,0 +1,261 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Marc-Andre Laperle - Remember last selected directory + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace; + +import java.io.File; + +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.DirectoryDialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.ui.IWorkbench; + +/** + * Select the directories to scan for traces this page is the second of + * three pages shown. This one selects the files to be scanned. + * + * @author Matthew Khouzam + * @since 2.0 + */ +public class ImportTraceWizardSelectDirectoriesPage extends AbstractImportTraceWizardPage { + + /** + * ID + */ + public static String ID = "org.eclipse.linuxtools.tmf.ui.project.wizards.importtrace.ImportTraceWizardPagePopulate"; //$NON-NLS-1$ + + private static final String STORE_DIRECTORY_ID = ID + ".STORE_DIRECTORY_ID"; //$NON-NLS-1$ + + /** + * Constructor. Creates the trace wizard page. + * + * @param name + * The name of the page. + * @param selection + * The current selection + */ + protected ImportTraceWizardSelectDirectoriesPage(String name, IStructuredSelection selection) { + super(name, selection); + } + + /** + * Constructor + * + * @param workbench + * The workbench reference. + * @param selection + * The current selection + */ + public ImportTraceWizardSelectDirectoriesPage(IWorkbench workbench, IStructuredSelection selection) { + super(workbench, selection); + } + + @Override + public void createControl(Composite parent) { + super.createControl(parent); + final Composite control = (Composite) this.getControl(); + control.setLayout(new GridLayout(2, false)); + control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + final Table selectedFiles = new Table(control, SWT.H_SCROLL | SWT.V_SCROLL); + selectedFiles.clearAll(); + selectedFiles.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + selectedFiles.setLinesVisible(true); + + Composite buttonArea = new Composite(control, SWT.None); + buttonArea.setLayout(new GridLayout()); + buttonArea.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false)); + + Button addFile = new Button(buttonArea, SWT.PUSH); + addFile.setText(Messages.ImportTraceWizardAddFile); + addFile.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + addFile.addSelectionListener(new AddFileHandler()); + addFile.setAlignment(SWT.CENTER); + + Button addDirectory = new Button(buttonArea, SWT.PUSH); + addDirectory.setText(Messages.ImportTraceWizardAddDirectory); + addDirectory.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + addDirectory.addSelectionListener(new AddDirectoryHandler()); + addDirectory.setAlignment(SWT.CENTER); + + Button removeFile = new Button(buttonArea, SWT.PUSH); + removeFile.setText(Messages.ImportTraceWizardRemove); + removeFile.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + removeFile.addSelectionListener(new RemoveFileHandler(selectedFiles)); + removeFile.setAlignment(SWT.CENTER); + +// int maxSize = Math.max(addFile.getSize().x, Math.max(addDirectory.getSize().x, removeFile.getSize().x)); +// int maxHeight = Math.max(addFile.getSize().y, Math.max(addDirectory.getSize().y, removeFile.getSize().y)); +// addFile.setSize(maxSize, maxHeight); +// addDirectory.setSize(maxSize, maxHeight); +// removeFile.setSize(maxSize, maxHeight); + + this.setTitle(Messages.ImportTraceWizardDirectoryTitle); + } + + private void updateButtons() { + BatchImportTraceWizard wiz = getBatchWizard(); + updateTable(); + wiz.getContainer().updateButtons(); + } + + private void updateTable() { + final Table selectedFiles = (Table) ((Composite) getControl()).getChildren()[0]; + selectedFiles.clearAll(); + selectedFiles.setItemCount(0); + for (String s : ((BatchImportTraceWizard) getWizard()).getFileNames()) { + TableItem ti = new TableItem(selectedFiles, SWT.None); + ti.setText(s); + } + } + + @Override + public boolean canFlipToNextPage() { + final Table selectedFiles = (Table) ((Composite) getControl()).getChildren()[0]; + boolean canLoad = selectedFiles.getItemCount() > 0; + if (canLoad) { + setErrorMessage(null); + } else { + setErrorMessage(Messages.ImportTraceWizardDirectoryHint); + } + return canLoad; + } + + private final class AddFileHandler implements SelectionListener { + @Override + public void widgetSelected(SelectionEvent e) { + + FileDialog dialog = new + FileDialog(Display.getCurrent().getActiveShell(), SWT.NONE); + + String lastDirectory = getLastSelectedDirectory(); + if (lastDirectory != null) { + dialog.setFilterPath(lastDirectory); + } + + String fn = dialog.open(); + if (null != fn) { + File f = new File(fn); + if (f.exists()) { + getBatchWizard().addFileToScan(fn); + saveSelectedDirectory(f.getParentFile()); + } + } + updateButtons(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + } + + private final class AddDirectoryHandler implements SelectionListener { + @Override + public void widgetSelected(SelectionEvent e) { + + // BUG BUG BUG BUG BUG IN SWT. Cannot read multiple files in a + // fake directory. + +// FileDialog dialog = new +// FileDialog(Display.getCurrent().getActiveShell(), SWT.OPEN | +// SWT.MULTI); +// dialog.setFilterPath("."); +// if (null != dialog.open()) { +// for (String fn : dialog.getFileNames()) { +// final String pathname = dialog.getFilterPath() + +// File.separator + fn; +// File f = new File(pathname); +// if (f.exists()) { +// ((BatchImportTraceWizard) getWizard()).addFile(fn, f); +// } +// } +// } + + DirectoryDialog dialog = new + DirectoryDialog(Display.getCurrent().getActiveShell(), SWT.NONE); + String lastDirectory = getLastSelectedDirectory(); + if (lastDirectory != null) { + dialog.setFilterPath(lastDirectory); + } + + String fn = dialog.open(); + if (null != fn) { + File f = new File(fn); + if (f.exists()) { + getBatchWizard().addFileToScan(fn); + saveSelectedDirectory(f); + } + } + updateButtons(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + } + + private String getLastSelectedDirectory() { + final IDialogSettings settings = getDialogSettings(); + if (settings != null) { + final String directory = settings.get(STORE_DIRECTORY_ID); + if (directory != null && !directory.isEmpty()) { + final File file = new File(directory); + if (file.exists()) { + return directory.toString(); + } + } + } + + return null; + } + + private void saveSelectedDirectory(File directory) { + final IDialogSettings settings = getDialogSettings(); + if (settings != null && directory != null && directory.exists()) { + settings.put(STORE_DIRECTORY_ID, directory.toString()); + } + } + + private final class RemoveFileHandler implements SelectionListener { + private final Table selectedFiles; + + private RemoveFileHandler(Table selectedFiles) { + this.selectedFiles = selectedFiles; + } + + @Override + public void widgetSelected(SelectionEvent e) { + TableItem selectedToRemove[] = selectedFiles.getSelection(); + for (TableItem victim : selectedToRemove) { + String victimName = victim.getText(); + ((BatchImportTraceWizard) getWizard()).removeFile(victimName); + } + updateButtons(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardSelectTraceTypePage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardSelectTraceTypePage.java new file mode 100644 index 0000000000..8cf8415883 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardSelectTraceTypePage.java @@ -0,0 +1,184 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTreeViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; +import org.eclipse.ui.IWorkbench; + +/** + * Select trace types to import, this page is the first of three pages + * shown. This one selects the type of traces that are to be scanned. + * + * @author Matthew Khouzam + * @since 2.0 + */ +public class ImportTraceWizardSelectTraceTypePage extends AbstractImportTraceWizardPage { + + private CheckboxTreeViewer fTreeView; + private final TraceTypeContentProvider fProvider = new TraceTypeContentProvider(); + + /** + * Select trace types to import + * + * @param name + * The name of the page. + * @param selection + * The current selection + */ + protected ImportTraceWizardSelectTraceTypePage(String name, IStructuredSelection selection) { + super(name, selection); + } + + /** + * Select trace types to import + * + * @param workbench + * The workbench reference. + * @param selection + * The current selection + */ + public ImportTraceWizardSelectTraceTypePage(IWorkbench workbench, IStructuredSelection selection) { + super(workbench, selection); + } + + @Override + public void createControl(Composite parent) { + super.createControl(parent); + Composite control = (Composite) this.getControl(); + + final ICheckStateListener listener = new TraceTypeCheckListener(); + + setTitle(Messages.ImportTraceWizardSelectTraceTypePageTitle); + + fTreeView = new CheckboxTreeViewer(control, SWT.BORDER); + fTreeView.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + fTreeView.setContentProvider(fProvider); + fTreeView.setInput(fProvider); + fTreeView.setLabelProvider(new LabelProvider() { + @Override + public String getText(Object element) { + return element.toString(); + } + }); + fTreeView.addCheckStateListener(listener); + + // populateTree(treeView); + + Composite buttonArea = new Composite(control, SWT.NONE); + buttonArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + buttonArea.setLayout(new GridLayout(2, false)); + + Button selectAll = new Button(buttonArea, SWT.NONE); + selectAll.setText(Messages.ImportTraceWizardSelectAll); + selectAll.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false)); + selectAll.addListener(SWT.Selection, new Listener() { + @Override + public void handleEvent(Event event) { + String elements[] = (String[]) ((ITreeContentProvider) fTreeView.getContentProvider()).getElements(null); + for (String key : elements) { + fTreeView.setSubtreeChecked(key, true); + } + getWizard().getContainer().updateButtons(); + } + }); + + Button selectNone = new Button(buttonArea, SWT.NONE); + selectNone.setText(Messages.ImportTraceWizardPageSelectNone); + selectNone.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); + selectNone.addListener(SWT.Selection, new Listener() { + @Override + public void handleEvent(Event event) { + String elements[] = (String[]) ((ITreeContentProvider) fTreeView.getContentProvider()).getElements(null); + for (String key : elements) { + fTreeView.setSubtreeChecked(key, false); + } + getWizard().getContainer().updateButtons(); + } + }); + fTreeView.expandAll(); + } + + @Override + public boolean canFlipToNextPage() { + List tracesToScan = new ArrayList<>(); + String elements[] = (String[]) fProvider.getElements(null); + for (String traceFamily : elements) { + final TraceTypeHelper[] children = (TraceTypeHelper[]) fProvider.getChildren(traceFamily); + if (children != null) { + for (TraceTypeHelper traceType : children) { + if (fTreeView.getChecked(traceType)) { + tracesToScan.add(traceType.getCanonicalName()); + } + } + } + } + ((BatchImportTraceWizard) getWizard()).setTraceTypesToScan(tracesToScan); + if (tracesToScan.isEmpty()) { + setErrorMessage(Messages.ImportTraceWizardPageSelectHint); + } else { + setErrorMessage(null); + } + return super.canFlipToNextPage() && !tracesToScan.isEmpty(); + } + + private final class TraceTypeCheckListener implements ICheckStateListener { + @Override + public void checkStateChanged(CheckStateChangedEvent event) { + + boolean checkStatus = event.getChecked(); + Object element = event.getElement(); + + fTreeView.setGrayed(element, false); + fTreeView.setSubtreeChecked(element, checkStatus); + ITreeContentProvider tcp = (ITreeContentProvider) fTreeView.getContentProvider(); + String parentElement = (String) tcp.getParent(element); + if (parentElement != null) { + TraceTypeHelper[] siblings = (TraceTypeHelper[]) tcp.getChildren(parentElement); + final TraceTypeHelper first = siblings[0]; + final boolean isFirstChecked = fTreeView.getChecked(first); + boolean allSame = true; + for (TraceTypeHelper peer : siblings) { + final boolean peerChecked = fTreeView.getChecked(peer); + if (peerChecked != isFirstChecked) { + allSame = false; + } + } + if (allSame) { + fTreeView.setGrayed(parentElement, false); + fTreeView.setChecked(parentElement, checkStatus); + } else { + fTreeView.setChecked(parentElement, false); + fTreeView.setGrayed(parentElement, true); + } + } + getWizard().getContainer().updateButtons(); + + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/Messages.java new file mode 100644 index 0000000000..10be69c6e3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/Messages.java @@ -0,0 +1,237 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Bernd Hufmann - Add ImportTraceWizard messages + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace; + +import org.eclipse.osgi.util.NLS; + +/** + * The messages for import trace wizards. + * @author Matthew Khouzam + */ +@SuppressWarnings("javadoc") +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace.messages"; //$NON-NLS-1$ + + // Import Trace Wizard + /** + * The dialog title of the import trace wizard + */ + public static String ImportTraceWizard_DialogTitle; + /** + * The title of the file system within the import trace wizard + */ + public static String ImportTraceWizard_FileSystemTitle; + /** + * The title of the the import trace wizard page. + */ + public static String ImportTraceWizard_ImportTrace; + /** + * The label of the directory location (import trace wizard) + */ + public static String ImportTraceWizard_DirectoryLocation; + /** + * The label of the archive location (import trace wizard) + */ + public static String ImportTraceWizard_ArchiveLocation; + /** + * The title of the select trace directory dialog (import trace wizard) + */ + public static String ImportTraceWizard_SelectTraceDirectoryTitle; + /** + * The title of the select trace archive dialog (import trace wizard) + */ + public static String ImportTraceWizard_SelectTraceArchiveTitle; + /** + * The message of the select trace directory dialog (import trace wizard) + */ + public static String ImportTraceWizard_SelectTraceDirectoryMessage; + /** + * The title of the trace type label (import trace wizard) + */ + public static String ImportTraceWizard_TraceType; + /** + * The label of the overwrite checkbox (import trace wizard) + */ + public static String ImportTraceWizard_OverwriteExistingTrace; + /** + * The label of the checkbox to create a link to the trace in workspace (import trace wizard) + */ + public static String ImportTraceWizard_CreateLinksInWorkspace; + /** + * The label of the checkbox to preserve the folder structure of selected the traces in workspace (import trace wizard) + */ + public static String ImportTraceWizard_PreserveFolderStructure; + /** + * The error message for invalid trace directory (import trace wizard) + */ + public static String ImportTraceWizard_InvalidTraceDirectory; + /** + * The error message when a trace validation failed (import trace wizard). + */ + public static String ImportTraceWizard_TraceValidationFailed; + /** + * The error message when a trace already exists in project (import trace wizard). + */ + public static String ImportTraceWizard_TraceAlreadyExists; + /** + * The title of rename button for import configuration dialog. + */ + public static String ImportTraceWizard_ImportConfigurationRename; + /** + * The title of rename all button for import configuration dialog. + */ + public static String ImportTraceWizard_ImportConfigurationRenameAll; + /** + * The title of overwrite button for import configuration dialog. + */ + public static String ImportTraceWizard_ImportConfigurationOverwrite; + /** + * The title of overwrite all button for import configuration dialog. + */ + public static String ImportTraceWizard_ImportConfigurationOverwriteAll; + /** + * The title of skip button for import configuration dialog. + */ + public static String ImportTraceWizard_ImportConfigurationSkip; + /** + * The title of skip all button for import configuration dialog. + */ + public static String ImportTraceWizard_ImportConfigurationSkipAll; + /** + * The error message when trace source is empty (import trace wizard). + */ + public static String ImportTraceWizard_SelectTraceSourceEmpty; + /** + * The error message when the specified archive file is not valid. + */ + public static String ImportTraceWizard_BadArchiveFormat; + /** + * The error message when no trace is selected (import trace wizard). + */ + public static String ImportTraceWizard_SelectTraceNoneSelected; + /** + * The error message when an error occurred during import operation. + */ + public static String ImportTraceWizard_ImportProblem; + /** + * The error message if destination directory is a virtual folder. + */ + public static String ImportTraceWizard_CannotImportFilesUnderAVirtualFolder; + /** + * The error message if destination directory is a virtual folder (for a link). + */ + public static String ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder; + /** + * The label string of the browse button. + */ + public static String ImportTraceWizard_BrowseButton; + /** + * The information label string. + */ + public static String ImportTraceWizard_Information; + /** + * The label of the checkbox to import unrecognized trace files + */ + public static String ImportTraceWizard_ImportUnrecognized; + /** + * The message when the import operation was cancelled. + */ + public static String ImportTraceWizard_ImportOperationCancelled; + /** + * The message when the trace type is not found. + */ + public static String ImportTraceWizard_TraceTypeNotFound; + /** + * The import operation task name. + */ + public static String ImportTraceWizard_ImportOperationTaskName; + /** + * The extract import operation task name + */ + public static String ImportTraceWizard_ExtractImportOperationTaskName; + /** + * The label to indicate that trace type auto detection shall be used. + */ + public static String ImportTraceWizard_AutoDetection; + + + // Batch Import Wizard + public static String ImportTraceWizardImportProblem ; + public static String ImportTraceWizardImportCaption; + public static String ImportTraceWizardTraceDisplayName; + public static String ImportTraceWizardLinkTraces; + public static String ImportTraceWizardCopyTraces; + public static String ImportTraceWizardOverwriteTraces; + public static String ImportTraceWizardAddFile; + public static String ImportTraceWizardAddDirectory; + public static String ImportTraceWizardRemove; + public static String ImportTraceWizardDirectoryTitle; + public static String ImportTraceWizardDirectoryHint; + /** + * @since 2.2 + */ + public static String ImportTraceWizardScanPagebyte; + + /** + * @since 2.2 + */ + public static String ImportTraceWizardScanPageGigabyte; + + /** + * @since 2.2 + */ + public static String ImportTraceWizardScanPageKilobyte; + + /** + * @since 2.2 + */ + public static String ImportTraceWizardScanPageMegabyte; + + public static String ImportTraceWizardScanPageRenameError; + /** + * @since 2.2 + */ + public static String ImportTraceWizardScanPageSelectAtleastOne; + + /** + * @since 2.2 + */ + public static String ImportTraceWizardScanPageSize; + public static String ImportTraceWizardSelectAll; + /** + * @since 2.2 + */ + public static String ImportTraceWizardScanPageTerabyte; + + public static String ImportTraceWizardScanPageTitle; + public static String ImportTraceWizardSelectTraceTypePageTitle; + public static String ImportTraceWizardPageOptionsTitle; + public static String ImportTraceWizardPageScanDone; + public static String ImportTraceWizardPageScanScanning; + public static String ImportTraceWizardPageSelectNone; + public static String ImportTraceWizardPageSelectHint; + public static String BatchImportTraceWizardRemove; + public static String BatchImportTraceWizardAdd; + public static String BatchImportTraceWizardErrorImportingTraceResource; + + public static String SharedSelectProject; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ResourceTreeAndListGroup.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ResourceTreeAndListGroup.java new file mode 100644 index 0000000000..e4a4278005 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/ResourceTreeAndListGroup.java @@ -0,0 +1,1203 @@ +/******************************************************************************* + * Copyright (c) 2000, 2014 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Marc-Andre Laperle - Copied from platform (org.eclipse.ui.internal.ide.dialogs) + *******************************************************************************/ +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.commands.common.EventManager; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.CheckboxTreeViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.ITreeViewerListener; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeExpansionEvent; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.internal.ide.dialogs.IElementFilter; + +/** + * Workbench-level composite that combines a CheckboxTreeViewer and CheckboxListViewer. + * All viewer selection-driven interactions are handled within this object + */ +@SuppressWarnings({"restriction", "rawtypes", "javadoc", "unchecked"}) +class ResourceTreeAndListGroup extends EventManager implements + ICheckStateListener, ISelectionChangedListener, ITreeViewerListener { + private Object root; + + private Object currentTreeSelection; + + private Collection expandedTreeNodes = new HashSet(); + + private Map checkedStateStore = new HashMap(9); + + private HashSet whiteCheckedTreeItems = new HashSet(); + + private ITreeContentProvider treeContentProvider; + + private IStructuredContentProvider listContentProvider; + + private ILabelProvider treeLabelProvider; + + private ILabelProvider listLabelProvider; + + // widgets + private CheckboxTreeViewer treeViewer; + + private CheckboxTableViewer listViewer; + + //height hint for viewers + private static int PREFERRED_HEIGHT = 150; + + /** + * Create an instance of this class. Use this constructor if you wish to specify + * the width and/or height of the combined widget (to only hardcode one of the + * sizing dimensions, specify the other dimension's value as -1) + * + * @param parent + * @param rootObject + * @param treeContentProvider + * @param treeLabelProvider + * @param listContentProvider + * @param listLabelProvider + * @param style + * @param useHeightHint If true then use the height hint + * to make this group big enough + * + */ + public ResourceTreeAndListGroup(Composite parent, Object rootObject, + ITreeContentProvider treeContentProvider, + ILabelProvider treeLabelProvider, + IStructuredContentProvider listContentProvider, + ILabelProvider listLabelProvider, int style, boolean useHeightHint) { + + root = rootObject; + this.treeContentProvider = treeContentProvider; + this.listContentProvider = listContentProvider; + this.treeLabelProvider = treeLabelProvider; + this.listLabelProvider = listLabelProvider; + createContents(parent, style, useHeightHint); + } + + /** + * This method must be called just before this window becomes visible. + */ + public void aboutToOpen() { + determineWhiteCheckedDescendents(root); + checkNewTreeElements(treeContentProvider.getElements(root)); + currentTreeSelection = null; + + //select the first element in the list + Object[] elements = treeContentProvider.getElements(root); + Object primary = elements.length > 0 ? elements[0] : null; + if (primary != null) { + treeViewer.setSelection(new StructuredSelection(primary)); + } + treeViewer.getControl().setFocus(); + } + + /** + * Add the passed listener to self's collection of clients + * that listen for changes to element checked states + * + * @param listener ICheckStateListener + */ + public void addCheckStateListener(ICheckStateListener listener) { + addListenerObject(listener); + } + + /** + * Return a boolean indicating whether all children of the passed tree element + * are currently white-checked + * + * @return boolean + * @param treeElement java.lang.Object + */ + protected boolean areAllChildrenWhiteChecked(Object treeElement) { + Object[] children = treeContentProvider.getChildren(treeElement); + for (int i = 0; i < children.length; ++i) { + if (!whiteCheckedTreeItems.contains(children[i])) { + return false; + } + } + + return true; + } + + /** + * Return a boolean indicating whether all list elements associated with + * the passed tree element are currently checked + * + * @return boolean + * @param treeElement java.lang.Object + */ + protected boolean areAllElementsChecked(Object treeElement) { + List checkedElements = (List) checkedStateStore.get(treeElement); + if (checkedElements == null) { + return false; + } + + return getListItemsSize(treeElement) == checkedElements.size(); + } + + /** + * Iterate through the passed elements which are being realized for the first + * time and check each one in the tree viewer as appropriate + */ + protected void checkNewTreeElements(Object[] elements) { + for (int i = 0; i < elements.length; ++i) { + Object currentElement = elements[i]; + boolean checked = checkedStateStore.containsKey(currentElement); + treeViewer.setChecked(currentElement, checked); + treeViewer.setGrayed(currentElement, checked + && !whiteCheckedTreeItems.contains(currentElement)); + } + } + + /** + * An item was checked in one of self's two views. Determine which + * view this occurred in and delegate appropriately + * + * @param event CheckStateChangedEvent + */ + @Override + public void checkStateChanged(final CheckStateChangedEvent event) { + + //Potentially long operation - show a busy cursor + BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), + new Runnable() { + @Override + public void run() { + if (event.getCheckable().equals(treeViewer)) { + treeItemChecked(event.getElement(), event + .getChecked()); + } else { + listItemChecked(event.getElement(), event + .getChecked(), true); + } + + notifyCheckStateChangeListeners(event); + } + }); + } + + /** + * Lay out and initialize self's visual components. + * + * @param parent org.eclipse.swt.widgets.Composite + * @param style the style flags for the new Composite + * @param useHeightHint If true yse the preferredHeight. + */ + protected void createContents(Composite parent, int style, + boolean useHeightHint) { + // group pane + Composite composite = new Composite(parent, style); + composite.setFont(parent.getFont()); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + layout.makeColumnsEqualWidth = true; + layout.marginHeight = 0; + layout.marginWidth = 0; + composite.setLayout(layout); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + createTreeViewer(composite, useHeightHint); + createListViewer(composite, useHeightHint); + + initialize(); + } + + /** + * Create this group's list viewer. + */ + protected void createListViewer(Composite parent, boolean useHeightHint) { + listViewer = CheckboxTableViewer.newCheckList(parent, SWT.BORDER); + GridData data = new GridData(GridData.FILL_BOTH); + if (useHeightHint) { + data.heightHint = PREFERRED_HEIGHT; + } + listViewer.getTable().setLayoutData(data); + listViewer.getTable().setFont(parent.getFont()); + listViewer.setContentProvider(listContentProvider); + listViewer.setLabelProvider(listLabelProvider); + listViewer.addCheckStateListener(this); + } + + /** + * Create this group's tree viewer. + */ + protected void createTreeViewer(Composite parent, boolean useHeightHint) { + Tree tree = new Tree(parent, SWT.CHECK | SWT.BORDER); + GridData data = new GridData(GridData.FILL_BOTH); + if (useHeightHint) { + data.heightHint = PREFERRED_HEIGHT; + } + tree.setLayoutData(data); + tree.setFont(parent.getFont()); + + treeViewer = new CheckboxTreeViewer(tree); + treeViewer.setContentProvider(treeContentProvider); + treeViewer.setLabelProvider(treeLabelProvider); + treeViewer.addTreeListener(this); + treeViewer.addCheckStateListener(this); + treeViewer.addSelectionChangedListener(this); + } + + /** + * Returns a boolean indicating whether the passed tree element should be + * at LEAST gray-checked. Note that this method does not consider whether + * it should be white-checked, so a specified tree item which should be + * white-checked will result in a true answer from this method. + * To determine whether a tree item should be white-checked use method + * #determineShouldBeWhiteChecked(Object). + * + * @param treeElement java.lang.Object + * @return boolean + * @see #determineShouldBeWhiteChecked(Object) + */ + protected boolean determineShouldBeAtLeastGrayChecked(Object treeElement) { + // if any list items associated with treeElement are checked then it + // retains its gray-checked status regardless of its children + List checked = (List) checkedStateStore.get(treeElement); + if (checked != null && (!checked.isEmpty())) { + return true; + } + + // if any children of treeElement are still gray-checked then treeElement + // must remain gray-checked as well. Only ask expanded nodes + if (expandedTreeNodes.contains(treeElement)) { + Object[] children = treeContentProvider.getChildren(treeElement); + for (int i = 0; i < children.length; ++i) { + if (checkedStateStore.containsKey(children[i])) { + return true; + } + } + } + + return false; + } + + /** + * Returns a boolean indicating whether the passed tree item should be + * white-checked. + * + * @return boolean + * @param treeElement java.lang.Object + */ + protected boolean determineShouldBeWhiteChecked(Object treeElement) { + return areAllChildrenWhiteChecked(treeElement) + && areAllElementsChecked(treeElement); + } + + /** + * Recursively add appropriate tree elements to the collection of + * known white-checked tree elements. + * + * @param treeElement java.lang.Object + */ + protected void determineWhiteCheckedDescendents(Object treeElement) { + // always go through all children first since their white-checked + // statuses will be needed to determine the white-checked status for + // this tree element + Object[] children = treeContentProvider.getElements(treeElement); + for (int i = 0; i < children.length; ++i) { + determineWhiteCheckedDescendents(children[i]); + } + + // now determine the white-checked status for this tree element + if (determineShouldBeWhiteChecked(treeElement)) { + setWhiteChecked(treeElement, true); + } + } + + /** + * Cause the tree viewer to expand all its items + */ + public void expandAll() { + treeViewer.expandAll(); + } + + /** + * Expand an element in a tree viewer + */ + private void expandTreeElement(final Object item) { + BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), + new Runnable() { + @Override + public void run() { + + // First see if the children need to be given their checked state at all. If they've + // already been realized then this won't be necessary + if (expandedTreeNodes.contains(item)) { + checkNewTreeElements(treeContentProvider + .getChildren(item)); + } else { + + expandedTreeNodes.add(item); + if (whiteCheckedTreeItems.contains(item)) { + //If this is the first expansion and this is a white checked node then check the children + Object[] children = treeContentProvider + .getChildren(item); + for (int i = 0; i < children.length; ++i) { + if (!whiteCheckedTreeItems + .contains(children[i])) { + Object child = children[i]; + setWhiteChecked(child, true); + treeViewer.setChecked(child, true); + checkedStateStore.put(child, + new ArrayList()); + } + } + + //Now be sure to select the list of items too + setListForWhiteSelection(item); + } + } + + } + }); + } + + /** + * Add all of the selected children of nextEntry to result recursively. + * This does not set any values in the checked state. + * @param treeElement The tree elements being queried + * @param addAll a boolean to indicate if the checked state store needs to be queried + * @param filter IElementFilter - the filter being used on the data + * @param monitor IProgressMonitor or null that the cancel is polled for + */ + private void findAllSelectedListElements(Object treeElement, + String parentLabel, boolean addAll, IElementFilter filter, + IProgressMonitor monitor) throws InterruptedException { + + String fullLabel = null; + if (monitor != null && monitor.isCanceled()) { + return; + } + if (monitor != null) { + fullLabel = getFullLabel(treeElement, parentLabel); + monitor.subTask(fullLabel); + } + + if (addAll) { + filter.filterElements(listContentProvider.getElements(treeElement), + monitor); + } else { //Add what we have stored + if (checkedStateStore.containsKey(treeElement)) { + filter.filterElements((Collection) checkedStateStore + .get(treeElement), monitor); + } + } + + Object[] treeChildren = treeContentProvider.getChildren(treeElement); + for (int i = 0; i < treeChildren.length; i++) { + Object child = treeChildren[i]; + if (addAll) { + findAllSelectedListElements(child, fullLabel, true, filter, + monitor); + } else { //Only continue for those with checked state + if (checkedStateStore.containsKey(child)) { + findAllSelectedListElements(child, fullLabel, + whiteCheckedTreeItems.contains(child), filter, + monitor); + } + } + + } + } + + /** + * Find all of the white checked children of the treeElement and add them to the collection. + * If the element itself is white select add it. If not then add any selected list elements + * and recurse down to the children. + * @param treeElement java.lang.Object + * @param result java.util.Collection + */ + private void findAllWhiteCheckedItems(Object treeElement, Collection result) { + + if (whiteCheckedTreeItems.contains(treeElement)) { + result.add(treeElement); + } else { + Collection listChildren = (Collection) checkedStateStore + .get(treeElement); + //if it is not in the store then it and it's children are not interesting + if (listChildren == null) { + return; + } + result.addAll(listChildren); + Object[] children = treeContentProvider.getChildren(treeElement); + for (int i = 0; i < children.length; ++i) { + findAllWhiteCheckedItems(children[i], result); + } + } + } + + /** + * Returns a flat list of all of the leaf elements which are checked. Filter + * then based on the supplied ElementFilter. If monitor is cancelled then + * return null + * + * @param filter - + * the filter for the data + * @param monitor + * IProgressMonitor or null + * @throws InterruptedException + * If the find is interrupted. + */ + public void getAllCheckedListItems(IElementFilter filter, + IProgressMonitor monitor) throws InterruptedException { + + //Iterate through the children of the root as the root is not in the store + Object[] children = treeContentProvider.getChildren(root); + for (int i = 0; i < children.length; ++i) { + findAllSelectedListElements(children[i], null, + whiteCheckedTreeItems.contains(children[i]), filter, + monitor); + } + } + + /** Returns whether all items in the list are checked. + * This method is required, because this widget will keep items grey + * checked even though all children are selected (see grayUpdateHierarchy()). + * @return true if all items in the list are checked - false if not + */ + public boolean isEveryItemChecked() { + //Iterate through the children of the root as the root is not in the store + Object[] children = treeContentProvider.getChildren(root); + for (int i = 0; i < children.length; ++i) { + if (!whiteCheckedTreeItems.contains(children[i])) { + if (!treeViewer.getGrayed(children[i])) { + return false; + } + if (!isEveryChildrenChecked(children[i])) { + return false; + } + } + } + return true; + } + + /**Verifies of all list items of the tree element are checked, and + * if all children are white checked. If not, verify their children + * so that if an element is not white checked, but all its children + * are while checked, then, all items are considered checked. + * @param treeElement the treeElement which status to verify + * @return true if all items are checked, false otherwise. + */ + private boolean isEveryChildrenChecked(Object treeElement) { + List checked = (List) checkedStateStore.get(treeElement); + if (checked != null && (!checked.isEmpty())) { + Object[] listItems = listContentProvider.getElements(treeElement); + if (listItems.length != checked.size()) { + return false; + } + } + Object[] children = treeContentProvider.getChildren(treeElement); + for (int i = 0; i < children.length; ++i) { + if (!whiteCheckedTreeItems.contains(children[i])) { + if (!treeViewer.getGrayed(children[i])) { + return false; + } + if (!isEveryChildrenChecked(children[i])) { + return false; + } + } + } + return true; + } + + /** + * Returns a flat list of all of the leaf elements which are checked. + * + * @return all of the leaf elements which are checked. This API does not + * return null in order to keep backwards compatibility. + */ + public List getAllCheckedListItems() { + + final ArrayList returnValue = new ArrayList(); + + IElementFilter passThroughFilter = new IElementFilter() { + + @Override + public void filterElements(Collection elements, + IProgressMonitor monitor) { + returnValue.addAll(elements); + } + + @Override + public void filterElements(Object[] elements, + IProgressMonitor monitor) { + for (int i = 0; i < elements.length; i++) { + returnValue.add(elements[i]); + } + } + }; + + try { + getAllCheckedListItems(passThroughFilter, null); + } catch (InterruptedException exception) { + return new ArrayList(); + } + return returnValue; + + } + + /** + * Returns a flat list of all of the leaf elements. + * + * @return all of the leaf elements. + */ + public List getAllListItems() { + + final ArrayList returnValue = new ArrayList(); + + IElementFilter passThroughFilter = new IElementFilter() { + + @Override + public void filterElements(Collection elements, + IProgressMonitor monitor) { + returnValue.addAll(elements); + } + + @Override + public void filterElements(Object[] elements, + IProgressMonitor monitor) { + for (int i = 0; i < elements.length; i++) { + returnValue.add(elements[i]); + } + } + }; + + try { + Object[] children = treeContentProvider.getChildren(root); + for (int i = 0; i < children.length; ++i) { + findAllSelectedListElements(children[i], null, true, passThroughFilter, + null); + } + } catch (InterruptedException exception) { + return new ArrayList(); + } + return returnValue; + + } + + /** + * Returns a list of all of the items that are white checked. + * Any folders that are white checked are added and then any files + * from white checked folders are added. + * + * @return the list of all of the items that are white checked + */ + public List getAllWhiteCheckedItems() { + + List result = new ArrayList(); + + //Iterate through the children of the root as the root is not in the store + Object[] children = treeContentProvider.getChildren(root); + for (int i = 0; i < children.length; ++i) { + findAllWhiteCheckedItems(children[i], result); + } + + return result; + } + + /** + * Answer the number of elements that have been checked by the + * user. + * + * @return int + */ + public int getCheckedElementCount() { + return checkedStateStore.size(); + } + + /** + * Get the full label of the treeElement (its name and its parent's name). + * @param treeElement - the element being exported + * @param parentLabel - the label of the parent, can be null + * @return String + */ + protected String getFullLabel(Object treeElement, String parentLabel) { + String label = parentLabel; + if (parentLabel == null){ + label = ""; //$NON-NLS-1$ + } + IPath parentName = new Path(label); + + String elementText = treeLabelProvider.getText(treeElement); + if(elementText == null) { + return parentName.toString(); + } + return parentName.append(elementText).toString(); + } + + /** + * Return a count of the number of list items associated with a + * given tree item. + * + * @return int + * @param treeElement java.lang.Object + */ + protected int getListItemsSize(Object treeElement) { + Object[] elements = listContentProvider.getElements(treeElement); + return elements.length; + } + + /** + * Get the table the list viewer uses. + * @return org.eclipse.swt.widgets.Table + */ + public Table getListTable() { + return this.listViewer.getTable(); + } + + /** + * Logically gray-check all ancestors of treeItem by ensuring that they + * appear in the checked table + */ + protected void grayCheckHierarchy(Object treeElement) { + + //expand the element first to make sure we have populated for it + expandTreeElement(treeElement); + + // if this tree element is already gray then its ancestors all are as well + if (checkedStateStore.containsKey(treeElement)) { + return; // no need to proceed upwards from here + } + + checkedStateStore.put(treeElement, new ArrayList()); + Object parent = treeContentProvider.getParent(treeElement); + if (parent != null) { + grayCheckHierarchy(parent); + } + } + + /** + * Set the checked state of self and all ancestors appropriately. Do not white check anyone - this is + * only done down a hierarchy. + */ + private void grayUpdateHierarchy(Object treeElement) { + + boolean shouldBeAtLeastGray = determineShouldBeAtLeastGrayChecked(treeElement); + + treeViewer.setGrayChecked(treeElement, shouldBeAtLeastGray); + + if (whiteCheckedTreeItems.contains(treeElement)) { + whiteCheckedTreeItems.remove(treeElement); + } + + // proceed up the tree element hierarchy + Object parent = treeContentProvider.getParent(treeElement); + if (parent != null) { + grayUpdateHierarchy(parent); + } + } + + /** + * Set the initial checked state of the passed list element to true. + * @param element + */ + public void initialCheckListItem(Object element) { + Object parent = treeContentProvider.getParent(element); + selectAndReveal(parent); + //Check the element in the viewer as if it had been manually checked + listViewer.setChecked(element, true); + //As this is not done from the UI then set the box for updating from the selection to false + listItemChecked(element, true, false); + grayUpdateHierarchy(parent); + } + + /** + * Set the initial checked state of the passed element to true, + * as well as to all of its children and associated list elements + * @param element + */ + public void initialCheckTreeItem(Object element) { + treeItemChecked(element, true); + selectAndReveal(element); + } + + private void selectAndReveal(Object treeElement) { + treeViewer.reveal(treeElement); + IStructuredSelection selection = new StructuredSelection(treeElement); + treeViewer.setSelection(selection); + } + + /** + * Initialize this group's viewers after they have been laid out. + */ + protected void initialize() { + treeViewer.setInput(root); + this.expandedTreeNodes = new ArrayList(); + this.expandedTreeNodes.add(root); + + } + + /** + * Callback that's invoked when the checked status of an item in the list + * is changed by the user. Do not try and update the hierarchy if we are building the + * initial list. + */ + protected void listItemChecked(Object listElement, boolean state, + boolean updatingFromSelection) { + List checkedListItems = (List) checkedStateStore + .get(currentTreeSelection); + //If it has not been expanded do so as the selection of list items will affect gray state + if (!expandedTreeNodes.contains(currentTreeSelection)) { + expandTreeElement(currentTreeSelection); + } + + if (state) { + if (checkedListItems == null) { + // since the associated tree item has gone from 0 -> 1 checked + // list items, tree checking may need to be updated + grayCheckHierarchy(currentTreeSelection); + checkedListItems = (List) checkedStateStore + .get(currentTreeSelection); + } + checkedListItems.add(listElement); + } else { + checkedListItems.remove(listElement); + if (checkedListItems.isEmpty()) { + // since the associated tree item has gone from 1 -> 0 checked + // list items, tree checking may need to be updated + ungrayCheckHierarchy(currentTreeSelection); + } + } + + //Update the list with the selections if there are any + if (checkedListItems.size() > 0) { + checkedStateStore.put(currentTreeSelection, checkedListItems); + } + if (updatingFromSelection) { + grayUpdateHierarchy(currentTreeSelection); + } + } + + /** + * Notify all checked state listeners that the passed element has had + * its checked state changed to the passed state + */ + protected void notifyCheckStateChangeListeners( + final CheckStateChangedEvent event) { + Object[] array = getListeners(); + for (int i = 0; i < array.length; i++) { + final ICheckStateListener l = (ICheckStateListener) array[i]; + SafeRunner.run(new SafeRunnable() { + @Override + public void run() { + l.checkStateChanged(event); + } + }); + } + } + + /** + *Set the contents of the list viewer based upon the specified selected + *tree element. This also includes checking the appropriate list items. + * + *@param treeElement java.lang.Object + */ + protected void populateListViewer(final Object treeElement) { + listViewer.setInput(treeElement); + + //If the element is white checked but not expanded we have not set up all of the children yet + if (!(expandedTreeNodes.contains(treeElement)) + && whiteCheckedTreeItems.contains(treeElement)) { + + //Potentially long operation - show a busy cursor + BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), + new Runnable() { + @Override + public void run() { + setListForWhiteSelection(treeElement); + listViewer.setAllChecked(true); + } + }); + + } else { + List listItemsToCheck = (List) checkedStateStore.get(treeElement); + + if (listItemsToCheck != null) { + Iterator listItemsEnum = listItemsToCheck.iterator(); + while (listItemsEnum.hasNext()) { + listViewer.setChecked(listItemsEnum.next(), true); + } + } + } + } + + /** + * Logically gray-check all ancestors of treeItem by ensuring that they + * appear in the checked table. Add any elements to the selectedNodes + * so we can track that has been done. + */ + private void primeHierarchyForSelection(Object item, Set selectedNodes) { + + //Only prime it if we haven't visited yet + if (selectedNodes.contains(item)) { + return; + } + + checkedStateStore.put(item, new ArrayList()); + + //mark as expanded as we are going to populate it after this + expandedTreeNodes.add(item); + selectedNodes.add(item); + + Object parent = treeContentProvider.getParent(item); + if (parent != null) { + primeHierarchyForSelection(parent, selectedNodes); + } + } + + /** + * Remove the passed listener from self's collection of clients + * that listen for changes to element checked states + * + * @param listener ICheckStateListener + */ + public void removeCheckStateListener(ICheckStateListener listener) { + removeListenerObject(listener); + } + + /** + * Handle the selection of an item in the tree viewer + * + * @param event SelectionChangedEvent + */ + @Override + public void selectionChanged(SelectionChangedEvent event) { + IStructuredSelection selection = (IStructuredSelection) event + .getSelection(); + Object selectedElement = selection.getFirstElement(); + if (selectedElement == null) { + currentTreeSelection = null; + listViewer.setInput(currentTreeSelection); + return; + } + + // ie.- if not an item deselection + if (selectedElement != currentTreeSelection) { + populateListViewer(selectedElement); + } + + currentTreeSelection = selectedElement; + } + + /** + * Select or deselect all of the elements in the tree depending on the value of the selection + * boolean. Be sure to update the displayed files as well. + * @param selection + */ + public void setAllSelections(final boolean selection) { + + //If there is no root there is nothing to select + if (root == null) { + return; + } + + //Potentially long operation - show a busy cursor + BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), + new Runnable() { + @Override + public void run() { + setTreeChecked(root, selection); + listViewer.setAllChecked(selection); + } + }); + } + + /** + * The treeElement has been white selected. Get the list for the element and + * set it in the checked state store. + * @param treeElement the element being updated + */ + private void setListForWhiteSelection(Object treeElement) { + + Object[] listItems = listContentProvider.getElements(treeElement); + List listItemsChecked = new ArrayList(); + for (int i = 0; i < listItems.length; ++i) { + listItemsChecked.add(listItems[i]); + } + + checkedStateStore.put(treeElement, listItemsChecked); + } + + /** + * Set the list viewer's providers to those passed + * + * @param contentProvider ITreeContentProvider + * @param labelProvider ILabelProvider + */ + public void setListProviders(IStructuredContentProvider contentProvider, + ILabelProvider labelProvider) { + listViewer.setContentProvider(contentProvider); + listViewer.setLabelProvider(labelProvider); + } + + /** + * Set the comparator that is to be applied to self's list viewer + * + * @param comparator the sorter for the list + */ + public void setListComparator(ViewerComparator comparator) { + listViewer.setComparator(comparator); + } + + /** + * Set the root of the widget to be new Root. Regenerate all of the tables and lists from this + * value. + * @param newRoot + */ + public void setRoot(Object newRoot) { + this.root = newRoot; + initialize(); + } + + /** + * Set the checked state of the passed tree element appropriately, and + * do so recursively to all of its child tree elements as well + */ + protected void setTreeChecked(Object treeElement, boolean state) { + + if (treeElement.equals(currentTreeSelection)) { + listViewer.setAllChecked(state); + } + + if (state) { + setListForWhiteSelection(treeElement); + } else { + checkedStateStore.remove(treeElement); + } + + setWhiteChecked(treeElement, state); + treeViewer.setChecked(treeElement, state); + treeViewer.setGrayed(treeElement, false); + + // now logically check/uncheck all children as well if it has been expanded + if (expandedTreeNodes.contains(treeElement)) { + Object[] children = treeContentProvider.getChildren(treeElement); + for (int i = 0; i < children.length; ++i) { + setTreeChecked(children[i], state); + } + } + } + + /** + * Set the tree viewer's providers to those passed + * + * @param contentProvider ITreeContentProvider + * @param labelProvider ILabelProvider + */ + public void setTreeProviders(ITreeContentProvider contentProvider, + ILabelProvider labelProvider) { + treeViewer.setContentProvider(contentProvider); + treeViewer.setLabelProvider(labelProvider); + } + + /** + * Set the comparator that is to be applied to self's tree viewer + * + * @param comparator the comparator for the tree + */ + public void setTreeComparator(ViewerComparator comparator) { + treeViewer.setComparator(comparator); + } + + /** + * Adjust the collection of references to white-checked tree elements appropriately. + * + * @param treeElement java.lang.Object + * @param isWhiteChecked boolean + */ + protected void setWhiteChecked(Object treeElement, boolean isWhiteChecked) { + if (isWhiteChecked) { + if (!whiteCheckedTreeItems.contains(treeElement)) { + whiteCheckedTreeItems.add(treeElement); + } + } else { + whiteCheckedTreeItems.remove(treeElement); + } + } + + /** + * Handle the collapsing of an element in a tree viewer + */ + @Override + public void treeCollapsed(TreeExpansionEvent event) { + // We don't need to do anything with this + } + + /** + * Handle the expansionsion of an element in a tree viewer + */ + @Override + public void treeExpanded(TreeExpansionEvent event) { + expandTreeElement(event.getElement()); + } + + /** + * Callback that's invoked when the checked status of an item in the tree + * is changed by the user. + */ + protected void treeItemChecked(Object treeElement, boolean state) { + + // recursively adjust all child tree elements appropriately + setTreeChecked(treeElement, state); + + Object parent = treeContentProvider.getParent(treeElement); + + // workspace root is not shown in the tree, so ignore it + if (parent == null || parent instanceof IWorkspaceRoot) { + return; + } + + // now update upwards in the tree hierarchy + if (state) { + grayCheckHierarchy(parent); + } else { + ungrayCheckHierarchy(parent); + } + + //Update the hierarchy but do not white select the parent + grayUpdateHierarchy(parent); + } + + /** + * Logically un-gray-check all ancestors of treeItem iff appropriate. + */ + protected void ungrayCheckHierarchy(Object treeElement) { + if (!determineShouldBeAtLeastGrayChecked(treeElement)) { + checkedStateStore.remove(treeElement); + } + + Object parent = treeContentProvider.getParent(treeElement); + if (parent != null) { + ungrayCheckHierarchy(parent); + } + } + + /** + * Set the checked state of self and all ancestors appropriately + */ + protected void updateHierarchy(Object treeElement) { + + boolean whiteChecked = determineShouldBeWhiteChecked(treeElement); + boolean shouldBeAtLeastGray = determineShouldBeAtLeastGrayChecked(treeElement); + + treeViewer.setChecked(treeElement, shouldBeAtLeastGray); + setWhiteChecked(treeElement, whiteChecked); + if (whiteChecked) { + treeViewer.setGrayed(treeElement, false); + } else { + treeViewer.setGrayed(treeElement, shouldBeAtLeastGray); + } + + // proceed up the tree element hierarchy but gray select all of them + Object parent = treeContentProvider.getParent(treeElement); + if (parent != null) { + grayUpdateHierarchy(parent); + } + } + + /** + * Update the selections of the tree elements in items to reflect the new + * selections provided. + * @param items Map with keys of Object (the tree element) and values of List (the selected + * list elements). + * NOTE: This method does not special case keys with no values (i.e., + * a tree element with an empty list). If a tree element does not have any selected + * items, do not include the element in the Map. + */ + public void updateSelections(Map items) { + // We are replacing all selected items with the given selected items, + // so reinitialize everything. + this.listViewer.setAllChecked(false); + this.treeViewer.setCheckedElements(new Object[0]); + this.whiteCheckedTreeItems = new HashSet(); + Set selectedNodes = new HashSet(); + checkedStateStore = new HashMap(); + + //Update the store before the hierarchy to prevent updating parents before all of the children are done + Iterator keyIterator = items.keySet().iterator(); + while (keyIterator.hasNext()) { + Object key = keyIterator.next(); + List selections = (List) items.get(key); + //Replace the items in the checked state store with those from the supplied items + checkedStateStore.put(key, selections); + selectedNodes.add(key); + // proceed up the tree element hierarchy + Object parent = treeContentProvider.getParent(key); + if (parent != null) { + // proceed up the tree element hierarchy and make sure everything is in the table + primeHierarchyForSelection(parent, selectedNodes); + } + } + + // Update the checked tree items. Since each tree item has a selected + // item, all the tree items will be gray checked. + treeViewer.setCheckedElements(checkedStateStore.keySet().toArray()); + treeViewer.setGrayedElements(checkedStateStore.keySet().toArray()); + + // Update the listView of the currently selected tree item. + if (currentTreeSelection != null) { + Object displayItems = items.get(currentTreeSelection); + if (displayItems != null) { + listViewer.setCheckedElements(((List) displayItems).toArray()); + } + } + } + + /** + * Set the focus on to the list widget. + */ + public void setFocus() { + + treeViewer.getTree().setFocus(); + if(treeViewer.getSelection().isEmpty()) { + Object[] elements = treeContentProvider.getElements(root); + if(elements.length > 0) { + StructuredSelection selection = new StructuredSelection(elements[0]); + treeViewer.setSelection(selection); + } + } + + } + +} + diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/TraceTypeContentProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/TraceTypeContentProvider.java new file mode 100644 index 0000000000..7a1d35c61e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/TraceTypeContentProvider.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; + +/** + * Trace type content provider, a helper for showing trace types + * + * @author Matthew Khouzam + * @since 2.0 + */ +public class TraceTypeContentProvider implements ITreeContentProvider { + + private final List fTraceCategory = new ArrayList<>(); + private final Map> fTraceType = new HashMap<>(); + + /** + * Default Constructor + */ + public TraceTypeContentProvider() { + fTraceType.clear(); + fTraceCategory.clear(); + + for (String category : TmfTraceType.getTraceCategories()) { + List value = TmfTraceType.getTraceTypes(category); + if (!value.isEmpty()) { + fTraceCategory.add(category); + fTraceType.put(category, value); + } + } + } + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + // Do nothing + } + + @Override + public Object[] getElements(Object inputElement) { + return fTraceCategory.toArray(new String[0]); + } + + @Override + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof String) { + final List children = fTraceType.get(parentElement); + if (children != null) { + return children.toArray(new TraceTypeHelper[0]); + } + } + return null; + } + + @Override + public Object getParent(Object element) { + if (element instanceof TraceTypeHelper) { + for (String key : fTraceCategory) { + List traceSet = fTraceType.get(key); + if (traceSet != null) { + if (traceSet.contains(element)) { + return key; + } + } + } + } + return null; + } + + @Override + public boolean hasChildren(Object element) { + if (element instanceof String) { + String key = (String) element; + return fTraceType.containsKey(key); + } + return false; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/messages.properties new file mode 100644 index 0000000000..f3fdaf8e0c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/messages.properties @@ -0,0 +1,81 @@ +############################################################################### +# Copyright (c) 2013, 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### + +# ImportTraceWizard +ImportTraceWizard_DialogTitle=Trace Import +ImportTraceWizard_FileSystemTitle=File system +ImportTraceWizard_ImportTrace=Import a trace from the local file system +ImportTraceWizard_DirectoryLocation=Select roo&t directory: +ImportTraceWizard_ArchiveLocation=Select &archive file: +ImportTraceWizard_BrowseButton=B&rowse... +ImportTraceWizard_TraceType=Trace Type: +ImportTraceWizard_SelectTraceDirectoryTitle=Select trace directory +ImportTraceWizard_SelectTraceArchiveTitle=Select trace archive file +ImportTraceWizard_SelectTraceDirectoryMessage=Select directory to import trace from +ImportTraceWizard_OverwriteExistingTrace=Overwrite existing trace without warning +ImportTraceWizard_CreateLinksInWorkspace=Create lin&ks in workspace +ImportTraceWizard_PreserveFolderStructure=Preserve &folder structure +ImportTraceWizard_TraceValidationFailed=Validation failed for trace resource {0} +ImportTraceWizard_TraceAlreadyExists=Trace with name "{0}" already exists in project. Do you want to rename, overwrite or skip? +ImportTraceWizard_ImportConfigurationRename=Rename +ImportTraceWizard_ImportConfigurationRenameAll=Rename All +ImportTraceWizard_ImportConfigurationOverwrite=Overwrite +ImportTraceWizard_ImportConfigurationOverwriteAll=Overwrite All +ImportTraceWizard_ImportConfigurationSkip=Skip +ImportTraceWizard_ImportConfigurationSkipAll=Skip All +ImportTraceWizard_InvalidTraceDirectory=Invalid trace directory +ImportTraceWizard_SelectTraceSourceEmpty=Source must not be empty +ImportTraceWizard_BadArchiveFormat=Source file is not a valid tar or zip file. +ImportTraceWizard_SelectTraceNoneSelected=No trace selected +ImportTraceWizard_ImportProblem=Import problem +ImportTraceWizard_CannotImportFilesUnderAVirtualFolder=Can not import trace under a virtual folder +ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder=Have to create link under a virtual folder +ImportTraceWizard_Information=Information +ImportTraceWizard_ImportUnrecognized=Import unrecognized traces +ImportTraceWizard_ImportOperationCancelled=Import operation cancelled +ImportTraceWizard_TraceTypeNotFound=No trace type helper found +ImportTraceWizard_ImportOperationTaskName=Importing +ImportTraceWizard_ExtractImportOperationTaskName=Extracting files +ImportTraceWizard_AutoDetection= + +# BatchImportTraceWizard +ImportTraceWizardImportCaption=Trace to import +ImportTraceWizardTraceDisplayName=Trace display name +ImportTraceWizardLinkTraces=Link traces (Recommended) +ImportTraceWizardCopyTraces=Copy traces +ImportTraceWizardOverwriteTraces=Overwrite existing traces (recommended) +ImportTraceWizardAddFile=Add File... +ImportTraceWizardAddDirectory=Add Directory... +ImportTraceWizardRemove=Remove +ImportTraceWizardDirectoryTitle=Pick directories and files to scan +ImportTraceWizardDirectoryHint=Select at least one file or directory to scan +ImportTraceWizardScanPagebyte=\ B +ImportTraceWizardScanPageGigabyte=\ GB +ImportTraceWizardScanPageKilobyte=\ KB +ImportTraceWizardScanPageMegabyte=\ MB +ImportTraceWizardScanPageRenameError=Each selected trace must have a unique name, please rename. +ImportTraceWizardScanPageSelectAtleastOne=Select at least one trace to import +ImportTraceWizardScanPageSize=Size +ImportTraceWizardSelectAll=Select All +ImportTraceWizardScanPageTerabyte=\ TB +ImportTraceWizardScanPageTitle=Valid traces +ImportTraceWizardSelectTraceTypePageTitle=Available trace types +ImportTraceWizardPageOptionsTitle=Select Target Project +ImportTraceWizardPageScanDone=Done\! +ImportTraceWizardPageScanScanning=Scanning: +ImportTraceWizardPageSelectNone=Deselect All +ImportTraceWizardPageSelectHint=Select at least one trace type +BatchImportTraceWizardRemove=Removing +BatchImportTraceWizardAdd=Adding +BatchImportTraceWizardErrorImportingTraceResource=Error importing trace resource +ImportTraceWizardImportProblem=Error +SharedSelectProject=Select a project to import to diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/AbstractTracePackageOperation.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/AbstractTracePackageOperation.java new file mode 100644 index 0000000000..52faffa8f9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/AbstractTracePackageOperation.java @@ -0,0 +1,369 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; +import java.util.Vector; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.ui.internal.wizards.datatransfer.TarEntry; +import org.eclipse.ui.internal.wizards.datatransfer.TarException; +import org.eclipse.ui.internal.wizards.datatransfer.TarFile; + +/** + * An abstract operation containing common code useful for other trace package + * operations + * + * @author Marc-Andre Laperle + */ +@SuppressWarnings("restriction") +abstract public class AbstractTracePackageOperation { + private IStatus fStatus; + // Result of this operation, if any + private TracePackageElement[] fResultElements; + + private final String fFileName; + + /** + * Constructs a new trace package operation + * + * @param fileName + * the output file name + */ + public AbstractTracePackageOperation(String fileName) { + fFileName = fileName; + } + + /** + * Run the operation. The status (result) of the operation can be obtained + * with {@link #getStatus} + * + * @param progressMonitor + * the progress monitor to use to display progress and receive + * requests for cancellation + */ + public abstract void run(IProgressMonitor progressMonitor); + + /** + * Returns the status of the operation (result) + * + * @return the status of the operation + */ + public IStatus getStatus() { + return fStatus; + } + + /** + * Get the resulting elements for this operation, if any + * + * @return the resulting elements or null if no result is produced by this + * operation + */ + public TracePackageElement[] getResultElements() { + return fResultElements; + } + + /** + * Set the resulting elements for this operation, if any + * + * @param elements + * the resulting elements produced by this operation, can be set + * to null + */ + public void setResultElements(TracePackageElement[] elements) { + fResultElements = elements; + } + + /** + * Set the status for this operation + * + * @param status + * the status + */ + protected void setStatus(IStatus status) { + fStatus = status; + } + + /** + * Get the file name of the package + * + * @return the file name + */ + protected String getFileName() { + return fFileName; + } + + /** + * Answer a handle to the archive file currently specified as being the + * source. Return null if this file does not exist or is not of valid + * format. + * + * @return the archive file + */ + public ArchiveFile getSpecifiedArchiveFile() { + if (fFileName.length() == 0) { + return null; + } + + try { + return new ZipArchiveFile(new ZipFile(fFileName)); + } catch (IOException e) { + // ignore + } + + try { + return new TarArchiveFile(new TarFile(fFileName)); + } catch (TarException | IOException e) { + // ignore + } + + return null; + } + + /** + * Get the number of checked elements in the array and the children + * + * @param elements + * the elements to check for checked + * @return the number of checked elements + */ + protected int getNbCheckedElements(TracePackageElement[] elements) { + int totalWork = 0; + for (TracePackageElement tracePackageElement : elements) { + TracePackageElement[] children = tracePackageElement.getChildren(); + if (children != null && children.length > 0) { + totalWork += getNbCheckedElements(children); + } else if (tracePackageElement.isChecked()) { + ++totalWork; + } + } + + return totalWork; + } + + /** + * Returns whether or not the Files element is checked under the given trace + * package element + * + * @param tracePackageElement + * the trace package element + * @return whether or not the Files element is checked under the given trace + * package element + */ + public static boolean isFilesChecked(TracePackageElement tracePackageElement) { + for (TracePackageElement element : tracePackageElement.getChildren()) { + if (element instanceof TracePackageFilesElement) { + return element.isChecked(); + } + } + + return false; + } + + /** + * Common interface between ZipEntry and TarEntry + */ + protected interface ArchiveEntry { + /** + * The name of the entry + * + * @return The name of the entry + */ + String getName(); + } + + /** + * Common interface between ZipFile and TarFile + */ + protected interface ArchiveFile { + /** + * Returns an enumeration cataloging the archive. + * + * @return enumeration of all files in the archive + */ + Enumeration entries(); + + /** + * Close the file input stream. + * + * @throws IOException + */ + void close() throws IOException; + + /** + * Returns a new InputStream for the given file in the archive. + * + * @param entry + * the given file + * @return an input stream for the given file + * @throws TarException + * @throws IOException + */ + InputStream getInputStream(ArchiveEntry entry) throws TarException, IOException; + } + + /** + * Adapter for TarFile to ArchiveFile + */ + protected class TarArchiveFile implements ArchiveFile { + + private TarFile fTarFile; + + /** + * Constructs a TarAchiveFile for a TarFile + * + * @param tarFile + * the TarFile + */ + public TarArchiveFile(TarFile tarFile) { + this.fTarFile = tarFile; + } + + @Override + public Enumeration entries() { + Vector v = new Vector<>(); + for (Enumeration e = fTarFile.entries(); e.hasMoreElements();) { + v.add(new TarArchiveEntry((TarEntry) e.nextElement())); + } + + return v.elements(); + } + + @Override + public void close() throws IOException { + fTarFile.close(); + } + + @Override + public InputStream getInputStream(ArchiveEntry entry) throws TarException, IOException { + return fTarFile.getInputStream(((TarArchiveEntry) entry).getTarEntry()); + } + } + + /** + * Adapter for TarEntry to ArchiveEntry + */ + protected class TarArchiveEntry implements ArchiveEntry { + private TarEntry fTarEntry; + + /** + * Constructs a TarArchiveEntry for a TarEntry + * + * @param tarEntry + * the TarEntry + */ + public TarArchiveEntry(TarEntry tarEntry) { + this.fTarEntry = tarEntry; + } + + @Override + public String getName() { + return fTarEntry.getName(); + } + + /** + * Get the corresponding TarEntry + * + * @return the corresponding TarEntry + */ + public TarEntry getTarEntry() { + return fTarEntry; + } + + @Override + public String toString() { + return getName(); + } + } + + /** + * Adapter for ArchiveEntry to ArchiveEntry + */ + protected class ZipAchiveEntry implements ArchiveEntry { + + private ZipEntry fZipEntry; + + /** + * Constructs a ZipAchiveEntry for a ZipEntry + * + * @param zipEntry + * the ZipEntry + */ + public ZipAchiveEntry(ZipEntry zipEntry) { + this.fZipEntry = zipEntry; + } + + @Override + public String getName() { + return fZipEntry.getName(); + } + + /** + * Get the corresponding ZipEntry + * + * @return the corresponding ZipEntry + */ + public ZipEntry getZipEntry() { + return fZipEntry; + } + + @Override + public String toString() { + return getName(); + } + } + + /** + * Adapter for ZipFile to ArchiveFile + */ + protected class ZipArchiveFile implements ArchiveFile { + + private ZipFile fZipFile; + + /** + * Constructs a ZipArchiveFile for a ZipFile + * + * @param zipFile + * the ZipFile + */ + public ZipArchiveFile(ZipFile zipFile) { + this.fZipFile = zipFile; + } + + @Override + public Enumeration entries() { + Vector v = new Vector<>(); + for (Enumeration e = fZipFile.entries(); e.hasMoreElements();) { + v.add(new ZipAchiveEntry((ZipEntry) e.nextElement())); + } + + return v.elements(); + } + + @Override + public void close() throws IOException { + fZipFile.close(); + } + + @Override + public InputStream getInputStream(ArchiveEntry entry) throws TarException, IOException { + return fZipFile.getInputStream(((ZipAchiveEntry) entry).getZipEntry()); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/AbstractTracePackageWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/AbstractTracePackageWizardPage.java new file mode 100644 index 0000000000..9ee7497be3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/AbstractTracePackageWizardPage.java @@ -0,0 +1,565 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTreeViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; + +/** + * An abstract wizard page containing common code useful for both import and + * export trace package wizard pages + * + * @author Marc-Andre Laperle + */ +abstract public class AbstractTracePackageWizardPage extends WizardPage { + + private static final int COMBO_HISTORY_LENGTH = 5; + private static final String STORE_FILE_PATHS_ID = ".STORE_FILEPATHS_ID"; //$NON-NLS-1$ + + private final String fStoreFilePathId; + private final IStructuredSelection fSelection; + + private CheckboxTreeViewer fElementViewer; + private Button fSelectAllButton; + private Button fDeselectAllButton; + private Combo fFilePathCombo; + private Button fBrowseButton; + + /** + * Create the trace package wizard page + * + * @param pageName + * the name of the page + * @param title + * the title for this wizard page, or null if none + * @param titleImage + * the image descriptor for the title of this wizard page, or + * null if none + * @param selection + * the current object selection + */ + protected AbstractTracePackageWizardPage(String pageName, String title, ImageDescriptor titleImage, IStructuredSelection selection) { + super(pageName, title, titleImage); + fStoreFilePathId = getName() + STORE_FILE_PATHS_ID; + fSelection = selection; + } + + /** + * Create the element viewer + * + * @param compositeParent + * the parent composite + */ + protected void createElementViewer(Composite compositeParent) { + fElementViewer = new CheckboxTreeViewer(compositeParent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.CHECK); + + fElementViewer.addCheckStateListener(new ICheckStateListener() { + @Override + public void checkStateChanged(CheckStateChangedEvent event) { + TracePackageElement element = (TracePackageElement) event.getElement(); + if (!element.isEnabled()) { + fElementViewer.setChecked(element, element.isChecked()); + } else { + setSubtreeChecked(fElementViewer, element, true, event.getChecked()); + } + maintainCheckIntegrity(element); + + if (element.getParent() != null) { + // Uncheck everything in this trace if Trace files are unchecked + if (element instanceof TracePackageFilesElement) { + if (!element.isChecked()) { + setSubtreeChecked(fElementViewer, element.getParent(), false, false); + } + // Check Trace files if anything else is selected + } else if (element.isChecked()) { + TracePackageElement parent = element.getParent(); + while (parent != null) { + for (TracePackageElement e : parent.getChildren()) { + if (e instanceof TracePackageFilesElement) { + setSubtreeChecked(fElementViewer, e, false, true); + break; + } + } + parent = parent.getParent(); + } + } + } + + + updateApproximateSelectedSize(); + updatePageCompletion(); + } + + private void maintainCheckIntegrity(final TracePackageElement element) { + TracePackageElement parentElement = element.getParent(); + boolean allChecked = true; + boolean oneChecked = false; + if (parentElement != null) { + if (parentElement.getChildren() != null) { + for (TracePackageElement child : parentElement.getChildren()) { + boolean checked = fElementViewer.getChecked(child) && !fElementViewer.getGrayed(child); + oneChecked |= checked; + allChecked &= checked; + } + } + if (oneChecked && !allChecked) { + fElementViewer.setGrayChecked(parentElement, true); + } else { + fElementViewer.setGrayed(parentElement, false); + fElementViewer.setChecked(parentElement, allChecked); + } + maintainCheckIntegrity(parentElement); + } + } + }); + GridData layoutData = new GridData(GridData.FILL_BOTH); + fElementViewer.getTree().setLayoutData(layoutData); + fElementViewer.setContentProvider(new TracePackageContentProvider()); + fElementViewer.setLabelProvider(new TracePackageLabelProvider()); + } + + /** + * Create the input for the element viewer + * + * @return the input for the element viewer + */ + protected abstract Object createElementViewerInput(); + + /** + * Create the file path group that allows the user to type or browse for a + * file path + * + * @param parent + * the parent composite + * @param label + * the label to describe the file path (i.e. import/export) + * @param fileDialogStyle + * SWT.OPEN or SWT.SAVE + */ + protected void createFilePathGroup(Composite parent, String label, final int fileDialogStyle) { + + Composite filePathSelectionGroup = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 3; + filePathSelectionGroup.setLayout(layout); + filePathSelectionGroup.setLayoutData(new GridData( + GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL)); + + Label destinationLabel = new Label(filePathSelectionGroup, SWT.NONE); + destinationLabel.setText(label); + + fFilePathCombo = new Combo(filePathSelectionGroup, SWT.SINGLE + | SWT.BORDER); + GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL + | GridData.GRAB_HORIZONTAL); + data.grabExcessHorizontalSpace = true; + fFilePathCombo.setLayoutData(data); + + fBrowseButton = new Button(filePathSelectionGroup, + SWT.PUSH); + fBrowseButton.setText(org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_Browse); + fBrowseButton.addListener(SWT.Selection, new Listener() { + @Override + public void handleEvent(Event event) { + handleFilePathBrowseButtonPressed(fileDialogStyle); + } + }); + setButtonLayoutData(fBrowseButton); + } + + /** + * Update the page with the file path the current file path selection + */ + abstract protected void updateWithFilePathSelection(); + + /** + * Creates the buttons for selecting all or none of the elements. + * + * @param parent + * the parent control + * @return the button group + */ + protected Composite createButtonsGroup(Composite parent) { + + // top level group + Composite buttonComposite = new Composite(parent, SWT.NONE); + + GridLayout layout = new GridLayout(); + layout.numColumns = 3; + buttonComposite.setLayout(layout); + buttonComposite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL + | GridData.HORIZONTAL_ALIGN_FILL)); + + fSelectAllButton = new Button(buttonComposite, SWT.PUSH); + fSelectAllButton.setText(org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_SelectAll); + + SelectionListener listener = new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + setAllChecked(fElementViewer, true, true); + updateApproximateSelectedSize(); + updatePageCompletion(); + } + }; + fSelectAllButton.addSelectionListener(listener); + + fDeselectAllButton = new Button(buttonComposite, SWT.PUSH); + fDeselectAllButton.setText(org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_DeselectAll); + + listener = new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + setAllChecked(fElementViewer, true, false); + updateApproximateSelectedSize(); + updatePageCompletion(); + } + }; + fDeselectAllButton.addSelectionListener(listener); + + return buttonComposite; + } + + /** + * Restore widget values to the values that they held last time this wizard + * was used to completion. + */ + protected void restoreWidgetValues() { + IDialogSettings settings = getDialogSettings(); + if (settings != null) { + String[] directoryNames = settings.getArray(fStoreFilePathId); + if (directoryNames == null || directoryNames.length == 0) { + return; + } + + for (int i = 0; i < directoryNames.length; i++) { + fFilePathCombo.add(directoryNames[i]); + } + } + } + + /** + * Save widget values to Dialog settings + */ + protected void saveWidgetValues() { + IDialogSettings settings = getDialogSettings(); + if (settings != null) { + // update directory names history + String[] directoryNames = settings.getArray(fStoreFilePathId); + if (directoryNames == null) { + directoryNames = new String[0]; + } + + directoryNames = addToHistory(directoryNames, getFilePathValue()); + settings.put(fStoreFilePathId, directoryNames); + } + } + + /** + * Determine if the page is complete and update the page appropriately. + */ + protected void updatePageCompletion() { + boolean pageComplete = determinePageCompletion(); + setPageComplete(pageComplete); + if (pageComplete) { + setErrorMessage(null); + } + } + + /** + * Determine if the page is completed or not + * + * @return true if the page is completed, false otherwise + */ + protected boolean determinePageCompletion() { + return fElementViewer.getCheckedElements().length > 0 && !getFilePathValue().isEmpty(); + } + + /** + * Handle error status + * + * @param status + * the error status + */ + protected void handleErrorStatus(IStatus status) { + + Throwable exception = status.getException(); + String message = status.getMessage().length() > 0 ? status.getMessage() : org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation; + + if (!status.isMultiStatus()) { + handleError(message, exception); + return; + } + + // Build a string with all the children status messages, exception + // messages and stack traces + StringBuilder sb = new StringBuilder(); + for (IStatus childStatus : status.getChildren()) { + StringBuilder childSb = new StringBuilder(); + if (!childStatus.getMessage().isEmpty()) { + childSb.append(childStatus.getMessage() + '\n'); + } + + Throwable childException = childStatus.getException(); + if (childException != null) { + String reason = childException.getMessage(); + // Some system exceptions have no message + if (reason == null) { + reason = childException.toString(); + } + + String stackMessage = getExceptionStackMessage(childException); + if (stackMessage == null) { + stackMessage = reason; + } + + childSb.append(stackMessage); + } + + if (childSb.length() > 0) { + childSb.insert(0, '\n'); + sb.append(childSb.toString()); + } + } + + // ErrorDialog only prints the call stack for a CoreException + exception = new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, sb.toString(), null)); + final Status statusWithException = new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorMultipleProblems, exception); + + Activator.getDefault().logError(message, exception); + ErrorDialog.openError(getContainer().getShell(), org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_InternalErrorTitle, message, statusWithException); + } + + /** + * Handle errors occurring in the wizard operations + * + * @param message + * the error message + * @param exception + * the exception attached to the message + */ + protected void handleError(String message, Throwable exception) { + Activator.getDefault().logError(message, exception); + displayErrorDialog(message, exception); + } + + private static String getExceptionStackMessage(Throwable exception) { + String stackMessage = null; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(baos); + exception.printStackTrace(ps); + ps.flush(); + try { + baos.flush(); + stackMessage = baos.toString(); + } catch (IOException e) { + } + + return stackMessage; + } + + private void displayErrorDialog(String message, Throwable exception) { + if (exception == null) { + final Status s = new Status(IStatus.ERROR, Activator.PLUGIN_ID, message); + ErrorDialog.openError(getContainer().getShell(), org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_InternalErrorTitle, null, s); + return; + } + + String reason = exception.getMessage(); + // Some system exceptions have no message + if (reason == null) { + reason = exception.toString(); + } + + String stackMessage = getExceptionStackMessage(exception); + if (stackMessage == null || stackMessage.isEmpty()) { + stackMessage = reason; + } + + // ErrorDialog only prints the call stack for a CoreException + CoreException coreException = new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, stackMessage, exception)); + final Status s = new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, reason, coreException); + ErrorDialog.openError(getContainer().getShell(), org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_InternalErrorTitle, message, s); + } + + /** + * A version of setSubtreeChecked that is aware of isEnabled + * + * @param viewer + * the viewer + * @param element + * the element + * @param enabledOnly + * if only enabled elements should be considered + * @param checked + * true if the item should be checked, and false if it should be + * unchecked + */ + protected static void setSubtreeChecked(CheckboxTreeViewer viewer, TracePackageElement element, boolean enabledOnly, boolean checked) { + if (!enabledOnly || element.isEnabled()) { + viewer.setChecked(element, checked); + if (checked) { + viewer.setGrayed(element, false); + } + element.setChecked(checked); + if (element.getChildren() != null) { + for (TracePackageElement child : element.getChildren()) { + setSubtreeChecked(viewer, child, enabledOnly, checked); + } + } + } + } + + /** + * Sets all items in the element viewer to be checked or unchecked + * + * @param viewer + * the viewer + * @param enabledOnly + * if only enabled elements should be considered + * @param checked + * whether or not items should be checked + */ + protected static void setAllChecked(CheckboxTreeViewer viewer, boolean enabledOnly, boolean checked) { + TreeItem[] items = viewer.getTree().getItems(); + for (int i = 0; i < items.length; i++) { + Object element = items[i].getData(); + setSubtreeChecked(viewer, (TracePackageElement) element, enabledOnly, checked); + } + } + + private static void addToHistory(List history, String newEntry) { + history.remove(newEntry); + history.add(0, newEntry); + + // since only one new item was added, we can be over the limit + // by at most one item + if (history.size() > COMBO_HISTORY_LENGTH) { + history.remove(COMBO_HISTORY_LENGTH); + } + } + + private static String[] addToHistory(String[] history, String newEntry) { + ArrayList l = new ArrayList<>(Arrays.asList(history)); + addToHistory(l, newEntry); + String[] r = new String[l.size()]; + l.toArray(r); + return r; + } + + /** + * Open an appropriate file dialog so that the user can specify a file to + * import/export + * @param fileDialogStyle + */ + private void handleFilePathBrowseButtonPressed(int fileDialogStyle) { + FileDialog dialog = new FileDialog(getContainer().getShell(), fileDialogStyle | SWT.SHEET); + dialog.setFilterExtensions(new String[] { "*.zip;*.tar.gz;*.tar;*.tgz", "*.*" }); //$NON-NLS-1$ //$NON-NLS-2$ + dialog.setText(Messages.TracePackage_FileDialogTitle); + String currentSourceString = getFilePathValue(); + int lastSeparatorIndex = currentSourceString.lastIndexOf(File.separator); + if (lastSeparatorIndex != -1) { + dialog.setFilterPath(currentSourceString.substring(0, lastSeparatorIndex)); + } + String selectedFileName = dialog.open(); + + if (selectedFileName != null) { + setFilePathValue(selectedFileName); + updateWithFilePathSelection(); + } + } + + /** + * Get the current file path value + * + * @return the current file path value + */ + protected String getFilePathValue() { + return fFilePathCombo.getText().trim(); + } + + /** + * Set the file path value + * + * @param value + * file path value + */ + protected void setFilePathValue(String value) { + fFilePathCombo.setText(value); + updatePageCompletion(); + } + + /** + * Update the approximate size of the selected elements + */ + protected void updateApproximateSelectedSize() { + } + + /** + * Get the element tree viewer + * + * @return the element tree viewer + */ + protected CheckboxTreeViewer getElementViewer() { + return fElementViewer; + } + + /** + * Get the file path combo box + * + * @return the file path combo box + */ + protected Combo getFilePathCombo() { + return fFilePathCombo; + } + + /** + * Get the object selection when the wizard was created + * + * @return the object selection + */ + protected IStructuredSelection getSelection() { + return fSelection; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/ITracePackageConstants.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/ITracePackageConstants.java new file mode 100644 index 0000000000..ba267d6af7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/ITracePackageConstants.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg; + +/** + * Constants used in the trace package (XML attribute and element names, etc). + * + * @author Marc-Andre Laperle + */ +public interface ITracePackageConstants { + + /** + * The file name for the package manifest file + */ + public static final String MANIFEST_FILENAME = "export-manifest.xml"; //$NON-NLS-1$ + + /** + * The root element of an export + */ + public static final String TMF_EXPORT_ELEMENT = "tmf-export"; //$NON-NLS-1$ + + /** + * Element representing a single trace + */ + public static final String TRACE_ELEMENT = "trace"; //$NON-NLS-1$ + + /** + * Attribute for the name of a trace + */ + public static final String TRACE_NAME_ATTRIB = "name"; //$NON-NLS-1$ + + /** + * Attribute for the type of a trace + */ + public static final String TRACE_TYPE_ATTRIB = "type"; //$NON-NLS-1$ + + /** + * Element representing a single supplementary file + */ + public static final String SUPPLEMENTARY_FILE_ELEMENT = "supplementary-file"; //$NON-NLS-1$ + + /** + * Attribute for the name of a supplementary file + */ + public static final String SUPPLEMENTARY_FILE_NAME_ATTRIB = "name"; //$NON-NLS-1$ + + /** + * Element representing a trace file or folder + */ + public static final String TRACE_FILE_ELEMENT = "file"; //$NON-NLS-1$ + + /** + * Attribute for the name of the file + */ + public static final String TRACE_FILE_NAME_ATTRIB = "name"; //$NON-NLS-1$ + + /** + * Element representing the bookmarks of a trace + */ + public static final String BOOKMARKS_ELEMENT = "bookmarks"; //$NON-NLS-1$ + + /** + * Element representing a single bookmark of a trace + */ + public static final String BOOKMARK_ELEMENT = "bookmark"; //$NON-NLS-1$ +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/Messages.java new file mode 100644 index 0000000000..3cf2e3f49e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/Messages.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg; + +import org.eclipse.osgi.util.NLS; + +/** + * Messages common to trace package operations + * + * @author Marc-Andre Laperle + */ +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.messages"; //$NON-NLS-1$ + + /** + * Text for supplementary files in the element viewer + */ + public static String TracePackage_SupplementaryFiles; + + /** + * Text for trace in the element viewer + */ + public static String TracePackage_TraceElement; + + /** + * Text for bookmarks in the element viewer + */ + public static String TracePackage_Bookmarks; + + /** + * Text for browse button in the wizard pages + */ + public static String TracePackage_Browse; + + /** + * Title for the file dialog + */ + public static String TracePackage_FileDialogTitle; + + /** + * Text for browse select all button in the wizard pages + */ + public static String TracePackage_SelectAll; + + /** + * Text for browse deselect all button in the wizard pages + */ + public static String TracePackage_DeselectAll; + + /** + * Generic error message for wizard operations + */ + public static String TracePackage_ErrorOperation; + + /** + * Generic error when multiple problems occur (MultiStatus) + */ + public static String TracePackage_ErrorMultipleProblems; + + /** + * Generic dialog message for error in wizard operations + */ + public static String TracePackage_InternalErrorTitle; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageBookmarkElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageBookmarkElement.java new file mode 100644 index 0000000000..db9410b6fe --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageBookmarkElement.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg; + +import java.util.List; +import java.util.Map; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; + +/** + * A trace package element representing the bookmarks of a trace + * + * @author Marc-Andre Laperle + */ +public class TracePackageBookmarkElement extends TracePackageElement { + private static final String BOOKMARK_IMAGE_PATH = "icons/elcl16/bookmark_obj.gif"; //$NON-NLS-1$ + private final List> bookmarkAttribs; + + /** + * Construct a bookmark element containing all the bookmarks + * + * @param parent + * the parent node + * @param bookmarkAttribs + * the bookmarks for the trace + */ + public TracePackageBookmarkElement(TracePackageElement parent, List> bookmarkAttribs) { + super(parent); + this.bookmarkAttribs = bookmarkAttribs; + } + + @Override + public long getSize(boolean checkedOnly) { + return 0; + } + + @Override + public String getText() { + return Messages.TracePackage_Bookmarks; + } + + @Override + public Image getImage() { + return Activator.getDefault().getImageFromImageRegistry(BOOKMARK_IMAGE_PATH); + } + + /** + * Get all the bookmarks + * + * @return the bookmarks + */ + public List> getBookmarks() { + return bookmarkAttribs; + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageContentProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageContentProvider.java new file mode 100644 index 0000000000..278b29b854 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageContentProvider.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +/** + * A content provider to display the content of a trace package in a tree + * + * @author Marc-Andre Laperle + */ +public class TracePackageContentProvider implements ITreeContentProvider { + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + @Override + public Object[] getElements(Object inputElement) { + if (inputElement instanceof TracePackageElement[]) { + return (TracePackageElement[]) inputElement; + } + return null; + } + + @Override + public Object[] getChildren(Object parentElement) { + return ((TracePackageElement) parentElement).getVisibleChildren(); + } + + @Override + public Object getParent(Object element) { + return ((TracePackageElement) element).getParent(); + } + + @Override + public boolean hasChildren(Object element) { + TracePackageElement traceTransferElement = (TracePackageElement) element; + TracePackageElement[] visibleChildren = traceTransferElement.getVisibleChildren(); + return visibleChildren != null && visibleChildren.length > 0; + } + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageElement.java new file mode 100644 index 0000000000..1f6810ce1d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageElement.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.model.WorkbenchAdapter; + +/** + * An ExportTraceElement represents an item in the ExportTraceWizard tree. + * + * @author Marc-Andre Laperle + */ +public abstract class TracePackageElement extends WorkbenchAdapter { + private TracePackageElement[] fChildren; + private final TracePackageElement fParent; + private boolean fEnabled; + private boolean fChecked; + private boolean fVisible; + + /** + * + * @param parent + * the parent of this element, can be set to null + */ + public TracePackageElement(TracePackageElement parent) { + fParent = parent; + fEnabled = true; + fVisible = true; + fChildren = new TracePackageElement[0]; + } + + /** + * @return the parent of this element or null if there is no parent + */ + public TracePackageElement getParent() { + return fParent; + } + + /** + * Get the text representation of this element to be displayed in the tree. + * + * @return the text representation + */ + abstract public String getText(); + + /** + * Get the children of this element + * + * @return the children of this element + */ + public TracePackageElement[] getChildren() { + return fChildren; + } + + /** + * Get the visible children of this element + * + * @return the visible children of this element + */ + public TracePackageElement[] getVisibleChildren() { + List visibleChildren = new ArrayList<>(); + for (TracePackageElement child : fChildren) { + if (child.isVisible()) { + visibleChildren.add(child); + } + } + return visibleChildren.toArray(new TracePackageElement[0]); + } + + /** + * Set the children of this element + * + * @param children + * the children of this element + */ + public void setChildren(TracePackageElement[] children) { + this.fChildren = children; + } + + /** + * Get the total size of the element including its children + * + * @param checkedOnly + * only count checked elements + * + * @return the total size of the element + */ + public long getSize(boolean checkedOnly) { + long size = 0; + if (fChildren != null) { + for (TracePackageElement child : fChildren) { + size += child.getSize(checkedOnly); + } + } + + return size; + } + + /** + * Get the image representation of this element to be displayed in the tree. + * + * @return the image representation + */ + public Image getImage() { + return null; + } + + /** + * Returns whether or not the element is enabled (grayed and not + * modifiable). + * + * @return whether or not the element is enabled + */ + public boolean isEnabled() { + return fEnabled; + } + + /** + * Returns whether or not the element is checked. + * + * @return whether or not the element is checked + */ + public boolean isChecked() { + return fChecked; + } + + /** + * Returns whether or not the element is visible. + * + * @return whether or not the element is visible + */ + public boolean isVisible() { + return fVisible; + } + + /** + * Sets whether or not the element should be enabled (grayed and not + * modifiable). + * + * @param enabled + * if the element should be enabled + */ + public void setEnabled(boolean enabled) { + fEnabled = enabled; + } + + /** + * Sets whether or not the element should be checked. + * + * @param checked + * if the element should be checked + */ + public void setChecked(boolean checked) { + fChecked = checked; + } + + /** + * Sets whether or not the element is visible. + * + * @param visible + * if the element should be visible + */ + public void setVisible(boolean visible) { + fVisible = visible; + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageFilesElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageFilesElement.java new file mode 100644 index 0000000000..7863f0ba6a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageFilesElement.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg; + +import java.io.File; + +import org.eclipse.core.resources.IResource; +import org.eclipse.swt.graphics.Image; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; + +/** + * An ExportTraceElement representing the trace files of a trace. + * + * @author Marc-Andre Laperle + */ +public class TracePackageFilesElement extends TracePackageElement { + + private static final String TRACE_ICON_PATH = "icons/elcl16/trace.gif"; //$NON-NLS-1$ + private final String fFileName; + private final IResource fResource; + private long fSize = -1; + + /** + * Constructs an instance of ExportTraceFilesElement when exporting + * + * @param parent + * the parent of this element, can be set to null + * @param resource + * the resource representing the trace file or folder in the + * workspace + */ + public TracePackageFilesElement(TracePackageElement parent, IResource resource) { + super(parent); + fFileName = null; + fResource = resource; + } + + /** + * Constructs an instance of ExportTraceFilesElement when importing + * + * @param parent + * the parent of this element, can be set to null + * @param fileName + * the name of the file to be imported + */ + public TracePackageFilesElement(TracePackageElement parent, String fileName) { + super(parent); + fFileName = fileName; + fResource = null; + } + + private long getSize(File file) { + if (file.isDirectory()) { + long size = 0; + for (File f : file.listFiles()) { + size += getSize(f); + } + return size; + } + + return file.length(); + } + + @Override + public long getSize(boolean checkedOnly) { + if (checkedOnly && !isChecked()) { + return 0; + } + + if (fSize == -1 && fResource.exists()) { + File file = fResource.getLocation().toFile(); + fSize = getSize(file); + } + + return fSize; + } + + @Override + public String getText() { + return Messages.TracePackage_TraceElement; + } + + @Override + public Image getImage() { + return Activator.getDefault().getImageFromImageRegistry(TRACE_ICON_PATH); + } + + /** + * Get the file name for this trace file or folder + * + * @return the file name for this trace file or folder + */ + public String getFileName() { + return fFileName; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageLabelProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageLabelProvider.java new file mode 100644 index 0000000000..66bfd71467 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageLabelProvider.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg; + +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +/** + * A label provider for the export trace tree. + * + * @author Marc-Andre Laperle + */ +public class TracePackageLabelProvider extends ColumnLabelProvider { + + @Override + public void addListener(ILabelProviderListener listener) { + } + + @Override + public void dispose() { + } + + @Override + public boolean isLabelProperty(Object element, String property) { + return false; + } + + @Override + public void removeListener(ILabelProviderListener listener) { + } + + @Override + public Image getImage(Object element) { + return ((TracePackageElement) element).getImage(); + } + + @Override + public String getText(Object element) { + return ((TracePackageElement) element).getText(); + } + + @Override + public Color getForeground(Object element) { + if (!((TracePackageElement) element).isEnabled()) { + return Display.getDefault().getSystemColor(SWT.COLOR_GRAY); + } + return null; + } + + @Override + public Color getBackground(Object element) { + return null; + } + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageSupplFileElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageSupplFileElement.java new file mode 100644 index 0000000000..ddb2393b20 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageSupplFileElement.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg; + +import org.eclipse.core.resources.IResource; +import org.eclipse.swt.graphics.Image; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; + +/** + * A trace package element representing a single supplementary file + * + * @author Marc-Andre Laperle + */ +public class TracePackageSupplFileElement extends TracePackageElement { + + private static final String SUPPL_FILE_ICON_PATH = "icons/obj16/thread_obj.gif"; //$NON-NLS-1$ + + private final IResource fResource; + private final String fSuppFileName; + + /** + * Constructor used when exporting + * + * @param resource + * the resource representing this supplementary file in the + * workspace + * @param parent + * the parent element + */ + public TracePackageSupplFileElement(IResource resource, TracePackageElement parent) { + super(parent); + fResource = resource; + fSuppFileName = null; + } + + /** + * Constructor used when importing + * + * @param suppFileName + * the name to be used for the supplementary file in the + * workspace + * @param parent + * the parent element + */ + public TracePackageSupplFileElement(String suppFileName, TracePackageElement parent) { + super(parent); + this.fSuppFileName = suppFileName; + fResource = null; + } + + /** + * Get the resource corresponding to this supplementary file + * + * @return the resource corresponding to this supplementary file + */ + public IResource getResource() { + return fResource; + } + + @Override + public String getText() { + return fResource != null ? fResource.getName() : fSuppFileName; + } + + @Override + public long getSize(boolean checkedOnly) { + if (checkedOnly && !isChecked()) { + return 0; + } + + return fResource.getLocation().toFile().length(); + } + + @Override + public Image getImage() { + return Activator.getDefault().getImageFromImageRegistry(SUPPL_FILE_ICON_PATH); + } + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageSupplFilesElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageSupplFilesElement.java new file mode 100644 index 0000000000..ec6c3616e7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageSupplFilesElement.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; + +/** + * A trace package element used for grouping supplementary file under a single + * subtree + * + * @author Marc-Andre Laperle + */ +public class TracePackageSupplFilesElement extends TracePackageElement { + + private static final String SUPPL_FILE_ICON_PATH = "icons/obj16/thread_obj.gif"; //$NON-NLS-1$ + + /** + * Construct a new TracePackageSupplFilesElement instance + * + * @param parent + * the parent of this element, can be set to null + */ + public TracePackageSupplFilesElement(TracePackageElement parent) { + super(parent); + } + + @Override + public String getText() { + return Messages.TracePackage_SupplementaryFiles; + } + + @Override + public Image getImage() { + return Activator.getDefault().getImageFromImageRegistry(SUPPL_FILE_ICON_PATH); + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageTraceElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageTraceElement.java new file mode 100644 index 0000000000..2b20c08dad --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/TracePackageTraceElement.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.swt.graphics.Image; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfCommonProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfNavigatorLabelProvider; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; + +/** + * An ExportTraceElement associated to a TmfTraceElement. This will be the + * parent of other elements (events, supplementary files, bookmarks, etc). + * + * @author Marc-Andre Laperle + */ +public class TracePackageTraceElement extends TracePackageElement { + + private final TmfTraceElement fTraceElement; + private final String fImportName; + private final String fTraceType; + + /** + * Construct an instance associated to a TmfTraceElement. For exporting. + * + * @param parent + * the parent of this element, can be set to null + * @param traceElement + * the associated TmfTraceElement + */ + public TracePackageTraceElement(TracePackageElement parent, TmfTraceElement traceElement) { + super(parent); + fTraceElement = traceElement; + fImportName = null; + fTraceType = null; + } + + /** + * Construct an instance associated to a TmfTraceElement. For importing. + * + * @param parent + * the parent of this element, can be set to null + * @param importName + * the name to use to identify this trace + * @param traceType + * the trace type to set for this trace + */ + public TracePackageTraceElement(TracePackageElement parent, String importName, String traceType) { + super(parent); + fImportName = importName; + fTraceElement = null; + fTraceType = traceType; + } + + @Override + public String getText() { + return fTraceElement != null ? fTraceElement.getElementPath() : getDestinationElementPath(); + } + + /** + * Return the target TmfCommonProjectElement element path for a given trace + * package element. {@link TmfCommonProjectElement#getElementPath()} + * + * @return the element path + */ + public String getDestinationElementPath() { + String traceName = getImportName(); + for (TracePackageElement element : getChildren()) { + if (element instanceof TracePackageFilesElement) { + TracePackageFilesElement tracePackageFilesElement = (TracePackageFilesElement) element; + String fileName = tracePackageFilesElement.getFileName(); + String parentDir = removeLastSegment(fileName); + return append(parentDir, traceName); + } + } + + return traceName; + } + + /** + * We do this outside of the Path class because we don't want it to convert + * \ to / on Windows in the presence of regular expressions + */ + private static String removeLastSegment(String str) { + String ret = removeAllTrailing(str, IPath.SEPARATOR); + int lastIndexOf = ret.lastIndexOf(IPath.SEPARATOR); + if (lastIndexOf != -1) { + ret = ret.substring(0, lastIndexOf); + ret = removeAllTrailing(ret, IPath.SEPARATOR); + } else { + ret = ""; //$NON-NLS-1$ + } + + return ret; + } + + private static String removeAllTrailing(String str, char toRemove) { + String ret = str; + while (ret.endsWith(Character.toString(toRemove))) { + ret = ret.substring(0, ret.length() - 1); + } + return ret; + } + + private static String append(String path, String str) { + if (!path.isEmpty()) { + return path + IPath.SEPARATOR + str; + } + + return str; + } + + /** + * @return the associated TmfTraceElement + */ + public TmfTraceElement getTraceElement() { + return fTraceElement; + } + + /** + * @return the import name + */ + public String getImportName() { + return fImportName; + } + + /** + * @return the trace type of this trace + */ + public String getTraceType() { + return fTraceType; + } + + @Override + public Image getImage() { + TmfNavigatorLabelProvider tmfNavigatorLabelProvider = new TmfNavigatorLabelProvider(); + return tmfNavigatorLabelProvider.getImage(fTraceElement); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageHandler.java new file mode 100644 index 0000000000..4d800f19d2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageHandler.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.ui.ISources; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Handler for exporting a trace package + * + * @author Marc-Andre Laperle + */ +public class ExportTracePackageHandler extends AbstractHandler { + + private boolean fEnabled = false; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return Boolean.FALSE; + } + + ISelection currentSelection = HandlerUtil.getCurrentSelection(event); + IStructuredSelection sec = StructuredSelection.EMPTY; + List selectedTraces = new ArrayList<>(); + if (currentSelection instanceof IStructuredSelection) { + sec = (IStructuredSelection) currentSelection; + Object[] selectedElements = sec.toArray(); + for (Object selectedElement : selectedElements) { + if (selectedElement instanceof TmfTraceElement) { + TmfTraceElement tmfTraceElement = (TmfTraceElement) selectedElement; + selectedTraces.add(tmfTraceElement.getElementUnderTraceFolder()); + } else if (selectedElement instanceof TmfTraceFolder) { + TmfTraceFolder tmfTraceFolder = (TmfTraceFolder) selectedElement; + selectedTraces = tmfTraceFolder.getTraces(); + } + } + } + + ExportTracePackageWizard w = new ExportTracePackageWizard(selectedTraces); + + w.init(PlatformUI.getWorkbench(), sec); + WizardDialog dialog = new WizardDialog(window.getShell(), w); + dialog.open(); + return null; + } + + @Override + public boolean isEnabled() { + return super.isEnabled() && fEnabled; + } + + @Override + public void setEnabled(Object evaluationContext) { + super.setEnabled(evaluationContext); + + fEnabled = true; + + Object s = HandlerUtil.getVariable(evaluationContext, ISources.ACTIVE_MENU_SELECTION_NAME); + if (s instanceof IStructuredSelection) { + IStructuredSelection selection = (IStructuredSelection) s; + // If we have traces selected, make sure they are all from the same + // project, disable handler otherwise + Object[] selectedElements = selection.toArray(); + TmfProjectElement firstProject = null; + for (Object selectedElement : selectedElements) { + if (selectedElement instanceof TmfTraceElement) { + TmfTraceElement tmfTraceElement = (TmfTraceElement) selectedElement; + TmfProjectElement project = tmfTraceElement.getProject(); + if (firstProject != null && !project.equals(firstProject)) { + fEnabled = false; + } + + firstProject = project; + } + } + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageSelectTraceWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageSelectTraceWizardPage.java new file mode 100644 index 0000000000..5d6b77d091 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageSelectTraceWizardPage.java @@ -0,0 +1,218 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.resources.IProject; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfNavigatorContentProvider; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfNavigatorLabelProvider; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.tracecompass.tmf.ui.project.model.TraceUtils; +import org.eclipse.ui.model.WorkbenchLabelProvider; + +/** + * A wizard page for selecting the trace to export when no trace was previously + * selected. + * + * @author Marc-Andre Laperle + */ +public class ExportTracePackageSelectTraceWizardPage extends WizardPage { + + private static final String PAGE_NAME = "ExportTracePackageSelectTraceWizardPage"; //$NON-NLS-1$ + + /** + * Construct the select trace page + */ + public ExportTracePackageSelectTraceWizardPage() { + super(PAGE_NAME); + } + + private IProject fSelectedProject; + private Table fTraceTable; + + @Override + public void createControl(Composite parent) { + Composite projectSelectionGroup = new Composite(parent, SWT.NONE); + projectSelectionGroup.setLayout(new GridLayout(2, true)); + projectSelectionGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); + projectSelectionGroup.setFont(parent.getFont()); + + Label projectLabel = new Label(projectSelectionGroup, SWT.NONE); + projectLabel.setText(Messages.ExportTracePackageSelectTraceWizardPage_ProjectSelection); + projectLabel.setLayoutData(new GridData()); + + Label configLabel = new Label(projectSelectionGroup, SWT.NONE); + configLabel.setText(Messages.ExportTracePackageSelectTraceWizardPage_TraceSelection); + configLabel.setLayoutData(new GridData()); + + final Table projectTable = new Table(projectSelectionGroup, SWT.SINGLE | SWT.BORDER); + projectTable.setLayoutData(new GridData(GridData.FILL_BOTH)); + + TableViewer projectViewer = new TableViewer(projectTable); + projectViewer.setContentProvider(new TmfNavigatorContentProvider() { + + @Override + public Object[] getElements(Object inputElement) { + return (IProject[]) inputElement; + } + }); + projectViewer.setLabelProvider(new WorkbenchLabelProvider()); + projectViewer.setInput(TraceUtils.getOpenedTmfProjects().toArray(new IProject[] {})); + + fTraceTable = new Table(projectSelectionGroup, SWT.BORDER | SWT.CHECK); + fTraceTable.setLayoutData(new GridData(GridData.FILL_BOTH)); + + final TableViewer traceViewer = new TableViewer(fTraceTable); + traceViewer.setContentProvider(new IStructuredContentProvider() { + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + @Override + public void dispose() { + } + + @Override + public Object[] getElements(Object inputElement) { + if (inputElement instanceof TmfTraceElement[]) { + return (TmfTraceElement[]) inputElement; + } + return null; + } + }); + traceViewer.setLabelProvider(new ExportLabelProvider()); + fTraceTable.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + getWizard().getContainer().updateButtons(); + updateNextPageData(); + } + }); + + projectTable.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + TableItem[] items = projectTable.getSelection(); + fSelectedProject = (IProject) items[0].getData(); + + TmfProjectElement project = TmfProjectRegistry.getProject(fSelectedProject, true); + + TmfTraceFolder tracesFolder = project.getTracesFolder(); + List traces = tracesFolder.getTraces(); + TmfTraceElement[] array = traces.toArray(new TmfTraceElement[] {}); + traceViewer.setInput(array); + traceViewer.refresh(); + fTraceTable.select(0); + fTraceTable.notifyListeners(SWT.Selection, new Event()); + getWizard().getContainer().updateButtons(); + } + }); + + Composite btComp = new Composite(projectSelectionGroup, SWT.NONE); + btComp.setLayout(new GridLayout(2, true)); + GridData gd = new GridData(); + gd.horizontalSpan = 2; + gd.horizontalAlignment = SWT.RIGHT; + btComp.setLayoutData(gd); + + final Button selectAll = new Button(btComp, SWT.PUSH); + selectAll.setText(org.eclipse.tracecompass.internal.tmf.ui.project.dialogs.Messages.Dialog_SelectAll); + selectAll.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + TableItem[] items = fTraceTable.getItems(); + for (TableItem item : items) { + item.setChecked(true); + } + + getWizard().getContainer().updateButtons(); + updateNextPageData(); + } + }); + + final Button deselectAll = new Button(btComp, SWT.PUSH); + deselectAll.setText(org.eclipse.tracecompass.internal.tmf.ui.project.dialogs.Messages.Dialog_DeselectAll); + deselectAll.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + TableItem[] items = fTraceTable.getItems(); + for (TableItem item : items) { + item.setChecked(false); + } + + getWizard().getContainer().updateButtons(); + updateNextPageData(); + } + }); + + setControl(projectSelectionGroup); + setTitle(Messages.ExportTracePackageWizardPage_Title); + setMessage(Messages.ExportTracePackageSelectTraceWizardPage_ChooseTrace); + } + + private ArrayList getCheckedTraces() { + TableItem[] items = fTraceTable.getItems(); + ArrayList traces = new ArrayList<>(); + for (TableItem item : items) { + if (item.getChecked()) { + TmfTraceElement trace = (TmfTraceElement) item.getData(); + traces.add(trace); + } + } + return traces; + } + + private void updateNextPageData() { + ExportTracePackageWizardPage page = (ExportTracePackageWizardPage) getWizard().getPage(ExportTracePackageWizardPage.PAGE_NAME); + page.setSelectedTraces(getCheckedTraces()); + } + + @Override + public boolean canFlipToNextPage() { + return getCheckedTraces().size() > 0; + } + + private class ExportLabelProvider extends TmfNavigatorLabelProvider { + @Override + public String getText(Object element) { + + if (element instanceof TmfTraceElement) { + TmfTraceElement folder = (TmfTraceElement) element; + return folder.getElementPath(); + } + return super.getText(element); + } + } + + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageWizard.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageWizard.java new file mode 100644 index 0000000000..4c2bb01381 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageWizard.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.ui.IExportWizard; +import org.eclipse.ui.IWorkbench; + +/** + * Wizard for exporting a trace package + * + * @author Marc-Andre Laperle + */ +public class ExportTracePackageWizard extends Wizard implements IExportWizard { + + private static final String STORE_EXPORT_TRACE_WIZARD = "ExportTraceWizard"; //$NON-NLS-1$ + private IStructuredSelection fSelection; + private List fSelectedTraces; + private ExportTracePackageWizardPage fPage; + + /** + * Constructor for the export trace wizard + */ + public ExportTracePackageWizard() { + IDialogSettings workbenchSettings = Activator.getDefault().getDialogSettings(); + IDialogSettings section = workbenchSettings + .getSection(STORE_EXPORT_TRACE_WIZARD); + if (section == null) { + section = workbenchSettings.addNewSection(STORE_EXPORT_TRACE_WIZARD); + } + setDialogSettings(section); + fSelectedTraces = new ArrayList<>(); + } + + /** + * Constructor for the export trace wizard with known selected traces + * + * @param selectedTraces + * the selected traces + */ + public ExportTracePackageWizard(List selectedTraces) { + this(); + fSelectedTraces = selectedTraces; + } + + @Override + public void init(IWorkbench workbench, IStructuredSelection selection) { + fSelection = selection; + + setNeedsProgressMonitor(true); + } + + @Override + public boolean performFinish() { + return fPage.finish(); + } + + @Override + public void addPages() { + super.addPages(); + fPage = new ExportTracePackageWizardPage(fSelection, fSelectedTraces); + if (fSelectedTraces.isEmpty()) { + addPage(new ExportTracePackageSelectTraceWizardPage()); + } + addPage(fPage); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageWizardPage.java new file mode 100644 index 0000000000..40663cc160 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ExportTracePackageWizardPage.java @@ -0,0 +1,453 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.CheckboxTreeViewer; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageWizardPage; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageBookmarkElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageLabelProvider; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFileElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFilesElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; + +/** + * Wizard page for the export trace package wizard + * + * @author Marc-Andre Laperle + */ +public class ExportTracePackageWizardPage extends AbstractTracePackageWizardPage { + + private static final int CONTENT_COL_WIDTH = 300; + private static final int SIZE_COL_WIDTH = 100; + + private static final String ZIP_EXTENSION = ".zip"; //$NON-NLS-1$ + private static final String TAR_EXTENSION = ".tar"; //$NON-NLS-1$ + private static final String TAR_GZ_EXTENSION = ".tar.gz"; //$NON-NLS-1$ + private static final String TGZ_EXTENSION = ".tgz"; //$NON-NLS-1$ + + private static final String ICON_PATH = "icons/wizban/export_wiz.png"; //$NON-NLS-1$ + + /** + * The page name, can be referenced from other pages + */ + public static final String PAGE_NAME = "ExportTracePackageWizardPage"; //$NON-NLS-1$ + // dialog store id constants + private static final String STORE_COMPRESS_CONTENTS_ID = PAGE_NAME + ".STORE_COMPRESS_CONTENTS_ID"; //$NON-NLS-1$ + private static final String STORE_FORMAT_ID = PAGE_NAME + ".STORE_FORMAT_ID"; //$NON-NLS-1$ + + private Button fCompressContentsCheckbox; + private Button fZipFormatButton; + private Button fTargzFormatButton; + private Label fApproximateSizeLabel; + private List fSelectedTraces; + + /** + * Constructor for the export trace package wizard page + * + * @param selection + * the current object selection + * @param selectedTraces + * the selected traces from the selection + */ + public ExportTracePackageWizardPage(IStructuredSelection selection, List selectedTraces) { + super(PAGE_NAME, Messages.ExportTracePackageWizardPage_Title, Activator.getDefault().getImageDescripterFromPath(ICON_PATH), selection); + fSelectedTraces = selectedTraces; + } + + /** + * Set the selected trace from the previous page to be displayed in the + * element viewer + * + * @param selectedTraces + * the selected trace + */ + public void setSelectedTraces(List selectedTraces) { + if (!fSelectedTraces.containsAll(selectedTraces) || !selectedTraces.containsAll(fSelectedTraces)) { + fSelectedTraces = selectedTraces; + CheckboxTreeViewer elementViewer = getElementViewer(); + elementViewer.setInput(createElementViewerInput()); + elementViewer.expandToLevel(2); + setAllChecked(elementViewer, false, true); + updateApproximateSelectedSize(); + } + } + + @Override + public void createControl(Composite parent) { + + initializeDialogUnits(parent); + + Composite composite = new Composite(parent, SWT.NULL); + composite.setLayout(new GridLayout()); + composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL)); + + createElementViewer(composite); + createButtonsGroup(composite); + createFilePathGroup(composite, Messages.ExportTracePackageWizardPage_ToArchive, SWT.SAVE); + createOptionsGroup(composite); + + restoreWidgetValues(); + setMessage(Messages.ExportTracePackageWizardPage_ChooseContent); + + updateApproximateSelectedSize(); + updatePageCompletion(); + + setControl(composite); + } + + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + if (visible) { + updatePageCompletion(); + } else { + setPageComplete(false); + } + } + + /** + * Restore widget values to the values that they held last time this wizard + * was used to completion. + */ + @Override + protected void restoreWidgetValues() { + super.restoreWidgetValues(); + + IDialogSettings settings = getDialogSettings(); + if (settings != null) { + if (getFilePathCombo().getItemCount() > 0) { + String item = getFilePathCombo().getItem(0); + setFilePathValue(item); + } + fCompressContentsCheckbox.setSelection(settings.getBoolean(STORE_COMPRESS_CONTENTS_ID)); + fZipFormatButton.setSelection(settings.getBoolean(STORE_FORMAT_ID)); + fTargzFormatButton.setSelection(!settings.getBoolean(STORE_FORMAT_ID)); + updateWithFilePathSelection(); + } + } + + @Override + protected void createFilePathGroup(Composite parent, String label, int fileDialogStyle) { + super.createFilePathGroup(parent, label, fileDialogStyle); + + getFilePathCombo().addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + updatePageCompletion(); + } + }); + } + + private void createOptionsGroup(Composite parent) { + Group optionsGroup = new Group(parent, SWT.NONE); + optionsGroup.setLayout(new RowLayout(SWT.VERTICAL)); + optionsGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL + | GridData.GRAB_HORIZONTAL)); + optionsGroup.setText(Messages.ExportTracePackageWizardPage_Options); + + SelectionAdapter listener = new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + updateWithFilePathSelection(); + } + }; + + fZipFormatButton = new Button(optionsGroup, SWT.RADIO | SWT.LEFT); + fZipFormatButton.setText(Messages.ExportTracePackageWizardPage_SaveInZipFormat); + fZipFormatButton.setSelection(true); + fZipFormatButton.addSelectionListener(listener); + + fTargzFormatButton = new Button(optionsGroup, SWT.RADIO | SWT.LEFT); + fTargzFormatButton.setText(Messages.ExportTracePackageWizardPage_SaveInTarFormat); + fTargzFormatButton.setSelection(false); + fTargzFormatButton.addSelectionListener(listener); + + fCompressContentsCheckbox = new Button(optionsGroup, SWT.CHECK | SWT.LEFT); + fCompressContentsCheckbox.setText(Messages.ExportTracePackageWizardPage_CompressContents); + fCompressContentsCheckbox.setSelection(true); + fCompressContentsCheckbox.addSelectionListener(listener); + } + + @Override + protected void createElementViewer(Composite parent) { + super.createElementViewer(parent); + + CheckboxTreeViewer elementViewer = getElementViewer(); + elementViewer.getTree().setHeaderVisible(true); + // Content column + TreeViewerColumn column = new TreeViewerColumn(elementViewer, SWT.NONE); + column.getColumn().setWidth(CONTENT_COL_WIDTH); + column.getColumn().setText(Messages.ExportTracePackageWizardPage_ContentColumnName); + column.setLabelProvider(new TracePackageLabelProvider()); + + // Size column + column = new TreeViewerColumn(elementViewer, SWT.NONE); + column.getColumn().setWidth(SIZE_COL_WIDTH); + column.getColumn().setText(Messages.ExportTracePackageWizardPage_SizeColumnName); + column.setLabelProvider(new ColumnLabelProvider() { + @Override + public String getText(Object element) { + TracePackageElement tracePackageElement = (TracePackageElement) element; + long size = tracePackageElement.getSize(false); + if (size == 0) { + return null; + } + int level = 0; + TracePackageElement curElement = tracePackageElement.getParent(); + while (curElement != null) { + curElement = curElement.getParent(); + ++level; + } + + return indent(getHumanReadable(size), level); + } + + private String indent(String humanReadable, int level) { + StringBuilder s = new StringBuilder(humanReadable); + for (int i = 0; i < level; ++i) { + final String indentStr = " "; //$NON-NLS-1$ + s.insert(0, indentStr); + } + return s.toString(); + } + }); + + elementViewer.setInput(createElementViewerInput()); + elementViewer.expandToLevel(2); + setAllChecked(elementViewer, false, true); + } + + @Override + protected void updateApproximateSelectedSize() { + long checkedSize = 0; + TracePackageElement[] tracePackageElements = (TracePackageElement[]) getElementViewer().getInput(); + for (TracePackageElement element : tracePackageElements) { + checkedSize += element.getSize(true); + } + checkedSize = Math.max(0, checkedSize); + fApproximateSizeLabel.setText(MessageFormat.format(Messages.ExportTracePackageWizardPage_ApproximateSizeLbl, getHumanReadable(checkedSize))); + } + + /** + * Get the human readable string for a size in bytes. (KB, MB, etc). + * + * @param size + * the size to print in human readable, + * @return the human readable string + */ + private static String getHumanReadable(long size) { + String humanSuffix[] = { Messages.ExportTracePackageWizardPage_SizeByte, Messages.ExportTracePackageWizardPage_SizeKilobyte, + Messages.ExportTracePackageWizardPage_SizeMegabyte, Messages.ExportTracePackageWizardPage_SizeGigabyte, + Messages.ExportTracePackageWizardPage_SizeTerabyte }; + long curSize = size; + + int suffixIndex = 0; + while (curSize >= 1024) { + curSize /= 1024; + ++suffixIndex; + } + + return Long.toString(curSize) + " " + humanSuffix[suffixIndex]; //$NON-NLS-1$ + } + + @Override + protected Object createElementViewerInput() { + List traceElements = new ArrayList<>(); + for (TmfTraceElement tmfTraceElement : fSelectedTraces) { + TracePackageTraceElement traceElement = new TracePackageTraceElement(null, tmfTraceElement); + + // Trace files + List children = new ArrayList<>(); + TracePackageFilesElement filesElement = new TracePackageFilesElement(traceElement, tmfTraceElement.getResource()); + filesElement.setChecked(true); + children.add(filesElement); + + // Supplementary files + IResource[] supplementaryResources = tmfTraceElement.getSupplementaryResources(); + List suppFilesChildren = new ArrayList<>(); + TracePackageSupplFilesElement suppFilesElement = new TracePackageSupplFilesElement(traceElement); + children.add(suppFilesElement); + for (IResource res : supplementaryResources) { + suppFilesChildren.add(new TracePackageSupplFileElement(res, suppFilesElement)); + } + suppFilesElement.setChildren(suppFilesChildren.toArray(new TracePackageElement[] {})); + + // Bookmarks + IFile bookmarksFile = tmfTraceElement.getBookmarksFile(); + if (bookmarksFile != null && bookmarksFile.exists()) { + IMarker[] findMarkers; + try { + findMarkers = bookmarksFile.findMarkers(IMarker.BOOKMARK, false, IResource.DEPTH_ZERO); + if (findMarkers.length > 0) { + children.add(new TracePackageBookmarkElement(traceElement, null)); + } + } catch (CoreException e) { + // Should not happen since we just checked bookmarksFile.exists() but log it just in case + Activator.getDefault().logError("Error finding bookmarks", e); //$NON-NLS-1$ + } + } + + traceElement.setChildren(children.toArray(new TracePackageElement[] {})); + + traceElements.add(traceElement); + + } + + return traceElements.toArray(new TracePackageTraceElement[] {}); + } + + @Override + protected final Composite createButtonsGroup(Composite parent) { + Composite buttonGroup = super.createButtonsGroup(parent); + + // Add the label on the same row of the select/deselect all buttons + fApproximateSizeLabel = new Label(buttonGroup, SWT.RIGHT); + GridData layoutData = new GridData(GridData.FILL_HORIZONTAL); + layoutData.grabExcessHorizontalSpace = true; + fApproximateSizeLabel.setLayoutData(layoutData); + + return buttonGroup; + } + + /** + * Save widget values to Dialog settings + */ + @Override + protected void saveWidgetValues() { + super.saveWidgetValues(); + + IDialogSettings settings = getDialogSettings(); + if (settings != null) { + settings.put(STORE_COMPRESS_CONTENTS_ID, fCompressContentsCheckbox.getSelection()); + settings.put(STORE_FORMAT_ID, fZipFormatButton.getSelection()); + } + } + + private String getOutputExtension() { + if (fZipFormatButton.getSelection()) { + return ZIP_EXTENSION; + } else if (fCompressContentsCheckbox.getSelection()) { + return TAR_GZ_EXTENSION; + } else { + return TAR_EXTENSION; + } + } + + @Override + protected void updateWithFilePathSelection() { + String filePathValue = getFilePathValue(); + if (filePathValue.isEmpty()) { + return; + } + + filePathValue = stripKnownExtension(filePathValue); + filePathValue = filePathValue.concat(getOutputExtension()); + + setFilePathValue(filePathValue); + } + + private static String stripKnownExtension(String str) { + String ret = str; + if (str.endsWith(TAR_GZ_EXTENSION)) { + ret = ret.substring(0, ret.lastIndexOf(".")); //$NON-NLS-1$ + } + + if (ret.endsWith(ZIP_EXTENSION) | ret.endsWith(TAR_EXTENSION) | ret.endsWith(TGZ_EXTENSION)) { + ret = ret.substring(0, ret.lastIndexOf(".")); //$NON-NLS-1$ + } + + return ret; + } + + /** + * Finish the wizard page + * + * @return true on success + */ + public boolean finish() { + if (!checkForOverwrite()) { + return false; + } + + saveWidgetValues(); + + TracePackageTraceElement[] traceExportElements = (TracePackageTraceElement[]) getElementViewer().getInput(); + boolean useCompression = fCompressContentsCheckbox.getSelection(); + boolean useTar = fTargzFormatButton.getSelection(); + String fileName = getFilePathValue(); + final TracePackageExportOperation exporter = new TracePackageExportOperation(traceExportElements, useCompression, useTar, fileName); + + try { + getContainer().run(true, true, new IRunnableWithProgress() { + + @Override + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + exporter.run(monitor); + } + }); + + IStatus status = exporter.getStatus(); + if (status.getSeverity() == IStatus.ERROR) { + handleErrorStatus(status); + } + + } catch (InvocationTargetException e) { + handleError(org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, e); + } catch (InterruptedException e) { + } + + return exporter.getStatus().getSeverity() == IStatus.OK; + } + + private boolean checkForOverwrite() { + File file = new File(getFilePathValue()); + if (file.exists()) { + return MessageDialog.openQuestion(getContainer().getShell(), null, Messages.ExportTracePackageWizardPage_AlreadyExitst); + } + return true; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageHandler.java new file mode 100644 index 0000000000..e8c96ed3f4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageHandler.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Handler for importing a trace package + * + * @author Marc-Andre Laperle + */ +public class ImportTracePackageHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ImportTracePackageWizard w = new ImportTracePackageWizard(); + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + + if (window == null) { + return Boolean.FALSE; + } + + ISelection currentSelection = HandlerUtil.getCurrentSelection(event); + IStructuredSelection sec = StructuredSelection.EMPTY; + if (currentSelection instanceof IStructuredSelection) { + sec = (IStructuredSelection) currentSelection; + } + + w.init(PlatformUI.getWorkbench(), sec); + WizardDialog dialog = new WizardDialog(window.getShell(), w); + dialog.open(); + return null; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageWizard.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageWizard.java new file mode 100644 index 0000000000..3dd5afe2d8 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageWizard.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport; + +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.ui.IImportWizard; +import org.eclipse.ui.IWorkbench; + +/** + * Wizard for importing a trace package + * + * @author Marc-Andre Laperle + */ +public class ImportTracePackageWizard extends Wizard implements IImportWizard { + + private static final String STORE_IMPORT_TRACE_PKG_WIZARD = "ImportTracePackageWizard"; //$NON-NLS-1$ + private IStructuredSelection fSelection; + private ImportTracePackageWizardPage fPage; + + /** + * Constructs the import trace package wizard + */ + public ImportTracePackageWizard() { + IDialogSettings workbenchSettings = Activator.getDefault().getDialogSettings(); + IDialogSettings section = workbenchSettings + .getSection(STORE_IMPORT_TRACE_PKG_WIZARD); + if (section == null) { + section = workbenchSettings.addNewSection(STORE_IMPORT_TRACE_PKG_WIZARD); + } + setDialogSettings(section); + } + + @Override + public void init(IWorkbench workbench, IStructuredSelection selection) { + fSelection = selection; + setNeedsProgressMonitor(true); + } + + @Override + public boolean performFinish() { + return fPage.finish(); + } + + @Override + public void addPages() { + super.addPages(); + fPage = new ImportTracePackageWizardPage(fSelection); + addPage(fPage); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageWizardPage.java new file mode 100644 index 0000000000..561ea43ce2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ImportTracePackageWizardPage.java @@ -0,0 +1,417 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.CheckboxTreeViewer; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.TraverseEvent; +import org.eclipse.swt.events.TraverseListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageOperation; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageWizardPage; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.tracecompass.tmf.ui.project.model.TraceUtils; +import org.eclipse.ui.dialogs.ElementListSelectionDialog; +import org.eclipse.ui.model.WorkbenchLabelProvider; + +/** + * Wizard page for the import trace package wizard + * + * @author Marc-Andre Laperle + */ +public class ImportTracePackageWizardPage extends AbstractTracePackageWizardPage { + + private static final String ICON_PATH = "icons/wizban/trace_import_wiz.png"; //$NON-NLS-1$ + private static final String PAGE_NAME = "ImportTracePackagePage"; //$NON-NLS-1$ + private static final String STORE_PROJECT_NAME_ID = PAGE_NAME + ".STORE_PROJECT_NAME_ID"; //$NON-NLS-1$ + + private String fValidatedFilePath; + private TmfTraceFolder fTmfTraceFolder; + private Text fProjectText; + private List fOpenedTmfProjects; + + /** + * Constructor for the import trace package wizard page + * + * @param selection + * the current object selection + */ + public ImportTracePackageWizardPage(IStructuredSelection selection) { + super(PAGE_NAME, Messages.ImportTracePackageWizardPage_Title, Activator.getDefault().getImageDescripterFromPath(ICON_PATH), selection); + + if (getSelection().getFirstElement() instanceof TmfTraceFolder) { + fTmfTraceFolder = (TmfTraceFolder) getSelection().getFirstElement(); + } + } + + @Override + public void createControl(Composite parent) { + initializeDialogUnits(parent); + + Composite composite = new Composite(parent, SWT.NULL); + composite.setLayout(new GridLayout()); + composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL + | GridData.HORIZONTAL_ALIGN_FILL)); + composite.setFont(parent.getFont()); + + createFilePathGroup(composite, Messages.ImportTracePackageWizardPage_FromArchive, SWT.OPEN); + createElementViewer(composite); + createButtonsGroup(composite); + if (fTmfTraceFolder == null) { + createProjectSelectionGroup(composite); + } + + restoreWidgetValues(); + setMessage(Messages.ImportTracePackageWizardPage_Message); + updatePageCompletion(); + + setControl(composite); + } + + private void createProjectSelectionGroup(Composite parent) { + + Composite projectSelectionGroup = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 3; + projectSelectionGroup.setLayout(layout); + projectSelectionGroup.setLayoutData(new GridData( + GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL)); + + Label projectLabel = new Label(projectSelectionGroup, SWT.NONE); + projectLabel.setText(Messages.ImportTracePackageWizardPage_Project); + + fProjectText = new Text(projectSelectionGroup, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); + GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL + | GridData.GRAB_HORIZONTAL); + data.grabExcessHorizontalSpace = true; + fProjectText.setLayoutData(data); + + fOpenedTmfProjects = TraceUtils.getOpenedTmfProjects(); + + // No project to import to, create a default project if it doesn't exist + if (fOpenedTmfProjects.isEmpty()) { + IProject defaultProject = ResourcesPlugin.getWorkspace().getRoot().getProject(TmfCommonConstants.DEFAULT_TRACE_PROJECT_NAME); + if (!defaultProject.exists()) { + IProject project = TmfProjectRegistry.createProject(TmfCommonConstants.DEFAULT_TRACE_PROJECT_NAME, null, null); + fOpenedTmfProjects.add(project); + } + } + + if (!fOpenedTmfProjects.isEmpty()) { + selectProject(fOpenedTmfProjects.get(0)); + } + + Button button = new Button(projectSelectionGroup, + SWT.PUSH); + button.setText(Messages.ImportTracePackageWizardPage_SelectProjectButton); + button.addListener(SWT.Selection, new Listener() { + @Override + public void handleEvent(Event event) { + ElementListSelectionDialog d = new ElementListSelectionDialog(getContainer().getShell(), new WorkbenchLabelProvider()); + + d.setBlockOnOpen(true); + d.setTitle(Messages.ImportTracePackageWizardPage_SelectProjectDialogTitle); + + d.setElements(fOpenedTmfProjects.toArray(new IProject[] {})); + + d.open(); + if (d.getFirstResult() != null) { + IProject project = (IProject) d.getFirstResult(); + selectProject(project); + } + } + }); + setButtonLayoutData(button); + } + + @Override + protected void restoreWidgetValues() { + super.restoreWidgetValues(); + IDialogSettings settings = getDialogSettings(); + if (settings != null && fProjectText != null) { + + // Restore last selected project + String projectName = settings.get(STORE_PROJECT_NAME_ID); + if (projectName != null && !projectName.isEmpty()) { + for (IProject project : fOpenedTmfProjects) { + if (project.getName().equals(projectName)) { + selectProject(project); + break; + } + } + } + } + } + + @Override + protected void saveWidgetValues() { + super.saveWidgetValues(); + + IDialogSettings settings = getDialogSettings(); + if (settings != null) { + settings.put(STORE_PROJECT_NAME_ID, fTmfTraceFolder.getProject().getResource().getName()); + } + } + + private void selectProject(IProject project) { + fProjectText.setText(project.getName()); + fTmfTraceFolder = TmfProjectRegistry.getProject(project, true).getTracesFolder(); + updatePageCompletion(); + } + + @Override + protected boolean determinePageCompletion() { + return super.determinePageCompletion() && fTmfTraceFolder != null; + } + + /** + * Create the operation that will be responsible of creating the manifest + * based on the file name. + * + * @param fileName the file name to generate the manifest from + * + * @return the operation that will extract the manifest + */ + protected AbstractTracePackageOperation createExtractManifestOperation(String fileName) { + return new TracePackageExtractManifestOperation(fileName); + } + + @Override + protected Object createElementViewerInput() { + + final AbstractTracePackageOperation op = createExtractManifestOperation(getFilePathValue()); + + try { + getContainer().run(true, true, new IRunnableWithProgress() { + + @Override + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + monitor.beginTask(Messages.ImportTracePackageWizardPage_ReadingPackage, 10); + op.run(monitor); + monitor.done(); + } + + }); + + IStatus status = op.getStatus(); + if (status.getSeverity() == IStatus.ERROR) { + handleErrorStatus(status); + } + } catch (InvocationTargetException e1) { + handleError(Messages.TracePackageExtractManifestOperation_ErrorReadingManifest, e1); + } catch (InterruptedException e1) { + // Canceled + } + + TracePackageElement[] resultElements = op.getResultElements(); + if (resultElements == null || resultElements.length == 0) { + return null; + } + + return resultElements; + } + + @Override + protected void createFilePathGroup(Composite parent, String label, int fileDialogStyle) { + super.createFilePathGroup(parent, label, fileDialogStyle); + + Combo filePathCombo = getFilePathCombo(); + filePathCombo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + updateWithFilePathSelection(); + } + }); + + // User can type-in path and press return to validate + filePathCombo.addTraverseListener(new TraverseListener() { + @Override + public void keyTraversed(TraverseEvent e) { + if (e.detail == SWT.TRAVERSE_RETURN) { + e.doit = false; + updateWithFilePathSelection(); + } + } + }); + } + + @Override + protected void updateWithFilePathSelection() { + if (!isFilePathValid()) { + setErrorMessage(Messages.ImportTracePackageWizardPage_ErrorFileNotFound); + getElementViewer().setInput(null); + return; + } + setErrorMessage(null); + + getContainer().getShell().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + CheckboxTreeViewer elementViewer = getElementViewer(); + Object elementViewerInput = createElementViewerInput(); + elementViewer.setInput(elementViewerInput); + if (elementViewerInput != null) { + elementViewer.expandToLevel(2); + setAllChecked(elementViewer, false, true); + fValidatedFilePath = getFilePathValue(); + } + + updatePageCompletion(); + } + }); + } + + private boolean isFilePathValid() { + return new File(getFilePathValue()).exists(); + } + + /** + * Finish the wizard page + * + * @return true on success + */ + public boolean finish() { + if (!checkForOverwrite()) { + return false; + } + + saveWidgetValues(); + + Object input = getElementViewer().getInput(); + TracePackageElement[] traceElements = (TracePackageElement[]) input; + final TracePackageImportOperation importOperation = new TracePackageImportOperation(fValidatedFilePath, traceElements, fTmfTraceFolder); + + try { + getContainer().run(true, true, new IRunnableWithProgress() { + @Override + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + importOperation.run(monitor); + } + }); + + IStatus status = importOperation.getStatus(); + if (status.getSeverity() == IStatus.ERROR) { + handleErrorStatus(status); + } + + } catch (InvocationTargetException e) { + handleError(Messages.ImportTracePackageWizardPage_ErrorOperation, e); + } catch (InterruptedException e) { + } + + return importOperation.getStatus().getSeverity() == IStatus.OK; + } + + private boolean checkForOverwrite() { + TracePackageElement[] traceElements = (TracePackageElement[]) getElementViewer().getInput(); + List noImportTraces = new ArrayList<>(); + boolean noToAll = false; + for (TracePackageElement packageElement : traceElements) { + TracePackageTraceElement traceElement = (TracePackageTraceElement) packageElement; + if (!AbstractTracePackageOperation.isFilesChecked(traceElement)) { + continue; + } + + if (noToAll) { + noImportTraces.add(traceElement); + continue; + } + + if (traceExists(traceElement)) { + int returnCode = promptForOverwrite(traceElement.getDestinationElementPath()); + // The return code is an index to a button in the dialog but the + // 'X' button in the window corner is not considered a button + // therefore it returns -1 and unfortunately, there is no + // constant for that. + if (returnCode < 0) { + return false; + } + + final String[] response = new String[] { IDialogConstants.NO_TO_ALL_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.YES_TO_ALL_LABEL, IDialogConstants.YES_LABEL }; + if (response[returnCode].equals(IDialogConstants.YES_TO_ALL_LABEL)) { + break; + } else if (response[returnCode].equals(IDialogConstants.NO_TO_ALL_LABEL)) { + noToAll = true; + noImportTraces.add(traceElement); + } else if (response[returnCode].equals(IDialogConstants.NO_LABEL)) { + noImportTraces.add(traceElement); + } + } + } + + // Unselect the traces that the user decided not to import + for (TracePackageTraceElement t : noImportTraces) { + for (TracePackageElement e : t.getChildren()) { + if (e instanceof TracePackageFilesElement) { + ((TracePackageFilesElement) e).setChecked(false); + } + } + } + + return true; + } + + private boolean traceExists(TracePackageTraceElement traceElement) { + IResource traceRes = fTmfTraceFolder.getResource().findMember(traceElement.getDestinationElementPath()); + return traceRes != null; + } + + private int promptForOverwrite(String traceName) { + final MessageDialog dialog = new MessageDialog(getContainer() + .getShell(), null, null, MessageFormat.format(Messages.ImportTracePackageWizardPage_AlreadyExists, traceName), + MessageDialog.QUESTION, new String[] { + IDialogConstants.NO_TO_ALL_LABEL, + IDialogConstants.NO_LABEL, + IDialogConstants.YES_TO_ALL_LABEL, + IDialogConstants.YES_LABEL, + }, 3) { + @Override + protected int getShellStyle() { + return super.getShellStyle() | SWT.SHEET; + } + }; + return dialog.open(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ManifestReader.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ManifestReader.java new file mode 100644 index 0000000000..fe83c41c05 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/ManifestReader.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.ITracePackageConstants; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageBookmarkElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFileElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFilesElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +/** + * Reads a manifest from an input stream + * + * @author Marc-Andre Laperle + */ +public class ManifestReader { + + private static final String SCHEMA_FOLDER_NAME = "schema"; //$NON-NLS-1$ + private static final String EXPORT_MANIFEST_SCHEMA_FILE_NAME = "export-manifest.xsd"; //$NON-NLS-1$ + private static final TracePackageElement [] EMPTY_ARRAY = new TracePackageElement[0]; + + /** + * Validate the content of a manifest from an input stream + * + * @param input the input stream to validate from + * @throws IOException on error + */ + public static void validateManifest(InputStream input) throws IOException + { + URL schemaFileUrl = FileLocator.find(Activator.getDefault().getBundle(), new Path(SCHEMA_FOLDER_NAME).append(EXPORT_MANIFEST_SCHEMA_FILE_NAME), null); + if (schemaFileUrl == null) { + throw new IOException(MessageFormat.format(Messages.TracePackageExtractManifestOperation_SchemaFileNotFound, EXPORT_MANIFEST_SCHEMA_FILE_NAME)); + } + + try { + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = factory.newSchema(new StreamSource(schemaFileUrl.openStream())); + Validator validator = schema.newValidator(); + validator.validate(new StreamSource(input)); + } catch (SAXException e) { + throw new IOException(Messages.TracePackageExtractManifestOperation_ErrorManifestNotValid, e); + } catch (IOException e) { + throw new IOException(Messages.TracePackageExtractManifestOperation_ErrorManifestNotValid, e); + } + } + + /** + * Load package elements from a manifest (input stream) + * + * The manifest looks like this: + * + * + * + * + * + * + * + * + * + * + * + * See schema/export-manifest.xsd for details. + * + * @param inputStream + * the input stream that contains the manifest + * @return the loaded elements + * @throws IOException + * when an error occurs when parsing + * @throws SAXException + * when an error occurs when parsing + * @throws ParserConfigurationException + * when an error occurs when parsing + */ + public static TracePackageElement[] loadElementsFromManifest(InputStream inputStream) throws IOException, SAXException, ParserConfigurationException { + + List packageElements = new ArrayList<>(); + TracePackageElement element = null; + Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + + NodeList traceElements = doc.getDocumentElement().getElementsByTagName(ITracePackageConstants.TRACE_ELEMENT); + for (int i = 0; i < traceElements.getLength(); i++) { + Node traceNode = traceElements.item(i); + if (traceNode.getNodeType() == Node.ELEMENT_NODE) { + Element traceElement = (Element) traceNode; + String traceName = traceElement.getAttribute(ITracePackageConstants.TRACE_NAME_ATTRIB); + String traceType = traceElement.getAttribute(ITracePackageConstants.TRACE_TYPE_ATTRIB); + element = new TracePackageTraceElement(null, traceName, traceType); + + List children = new ArrayList<>(); + NodeList fileElements = traceElement.getElementsByTagName(ITracePackageConstants.TRACE_FILE_ELEMENT); + for (int j = 0; j < fileElements.getLength(); j++) { + Node fileNode = fileElements.item(j); + if (fileNode.getNodeType() == Node.ELEMENT_NODE) { + Element fileElement = (Element) fileNode; + String fileName = fileElement.getAttribute(ITracePackageConstants.TRACE_FILE_NAME_ATTRIB); + children.add(new TracePackageFilesElement(element, fileName)); + } + } + + TracePackageSupplFilesElement supplFilesElement = new TracePackageSupplFilesElement(element); + + // Supplementary files + List suppFiles = new ArrayList<>(); + NodeList suppFilesElements = traceElement.getElementsByTagName(ITracePackageConstants.SUPPLEMENTARY_FILE_ELEMENT); + for (int j = 0; j < suppFilesElements.getLength(); j++) { + Node suppFileNode = suppFilesElements.item(j); + if (suppFileNode.getNodeType() == Node.ELEMENT_NODE) { + Element suppFileElement = (Element) suppFileNode; + String fileName = suppFileElement.getAttribute(ITracePackageConstants.SUPPLEMENTARY_FILE_NAME_ATTRIB); + TracePackageSupplFileElement supplFile = new TracePackageSupplFileElement(fileName, supplFilesElement); + suppFiles.add(supplFile); + } + } + + if (!suppFiles.isEmpty()) { + supplFilesElement.setChildren(suppFiles.toArray(EMPTY_ARRAY)); + children.add(supplFilesElement); + } + + // bookmarks + List> bookmarkAttribs = new ArrayList<>(); + NodeList bookmarksElements = traceElement.getElementsByTagName(ITracePackageConstants.BOOKMARKS_ELEMENT); + for (int j = 0; j < bookmarksElements.getLength(); j++) { + Node bookmarksNode = bookmarksElements.item(j); + if (bookmarksNode.getNodeType() == Node.ELEMENT_NODE) { + NodeList bookmarkElements = traceElement.getElementsByTagName(ITracePackageConstants.BOOKMARK_ELEMENT); + for (int k = 0; k < bookmarkElements.getLength(); k++) { + Node bookmarkNode = bookmarkElements.item(k); + if (bookmarkNode.getNodeType() == Node.ELEMENT_NODE) { + Element bookmarkElement = (Element) bookmarkNode; + NamedNodeMap attributesMap = bookmarkElement.getAttributes(); + Map attribs = new HashMap<>(); + for (int l = 0; l < attributesMap.getLength(); l++) { + Node item = attributesMap.item(l); + attribs.put(item.getNodeName(), item.getNodeValue()); + } + bookmarkAttribs.add(attribs); + } + } + } + } + if (!bookmarkAttribs.isEmpty()) { + children.add(new TracePackageBookmarkElement(element, bookmarkAttribs)); + } + + element.setChildren(children.toArray(EMPTY_ARRAY)); + packageElements.add(element); + } + } + return packageElements.toArray(EMPTY_ARRAY); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/Messages.java new file mode 100644 index 0000000000..d4466c072e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/Messages.java @@ -0,0 +1,239 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport; + +import org.eclipse.osgi.util.NLS; + +/** + * Messages for the trace package export wizard + * + * @author Marc-Andre Laperle + */ +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport.messages"; //$NON-NLS-1$ + + /** + * The message under the select trace wizard page title + */ + public static String ExportTracePackageSelectTraceWizardPage_ChooseTrace; + + /** + * The description of the project selection list + */ + public static String ExportTracePackageSelectTraceWizardPage_ProjectSelection; + + /** + * The description of the trace selection list + */ + public static String ExportTracePackageSelectTraceWizardPage_TraceSelection; + + /** + * Dialog text when target file already exists + */ + public static String ExportTracePackageWizardPage_AlreadyExitst; + + /** + * The approximate size label + */ + public static String ExportTracePackageWizardPage_ApproximateSizeLbl; + + /** + * The message under the wizard page title + */ + public static String ExportTracePackageWizardPage_ChooseContent; + + /** + * Text for the compress contents checkbox + */ + public static String ExportTracePackageWizardPage_CompressContents; + + /** + * Text for the first column (content) + */ + public static String ExportTracePackageWizardPage_ContentColumnName; + + /** + * Text for the options group + */ + public static String ExportTracePackageWizardPage_Options; + + /** + * Text for the tar format option + */ + public static String ExportTracePackageWizardPage_SaveInTarFormat; + + /** + * Text for the zip format option + */ + public static String ExportTracePackageWizardPage_SaveInZipFormat; + + /** + * Byte units + */ + public static String ExportTracePackageWizardPage_SizeByte; + + /** + * Text for the second column (size) + */ + public static String ExportTracePackageWizardPage_SizeColumnName; + + /** + * Gigabyte units + */ + public static String ExportTracePackageWizardPage_SizeGigabyte; + + /** + * Kilobyte units + */ + public static String ExportTracePackageWizardPage_SizeKilobyte; + + /** + * Megabyte units + */ + public static String ExportTracePackageWizardPage_SizeMegabyte; + + /** + * Terabyte units + */ + public static String ExportTracePackageWizardPage_SizeTerabyte; + + /** + * Title for the wizard page + */ + public static String ExportTracePackageWizardPage_Title; + + /** + * Label for the file path + */ + public static String ExportTracePackageWizardPage_ToArchive; + + /** + * Dialog text when a trace with the same name already exists + */ + public static String ImportTracePackageWizardPage_AlreadyExists; + + /** + * Title for the import page + */ + public static String ImportTracePackageWizardPage_Title; + + /** + * Text for the source archive label + */ + public static String ImportTracePackageWizardPage_FromArchive; + + /** + * Text for the reading package job + */ + public static String ImportTracePackageWizardPage_ReadingPackage; + + /** + * Message when file is not found + */ + public static String ImportTracePackageWizardPage_ErrorFileNotFound; + + /** + * Message when trace type could not be set + */ + public static String ImportTracePackageWizardPage_ErrorSettingTraceType; + + /** + * Message when the trace could not be found after importing the files + */ + public static String ImportTracePackageWizardPage_ErrorFindingImportedTrace; + + /** + * The message displayed under the title + */ + public static String ImportTracePackageWizardPage_Message; + + /** + * Generic error message for the import operation + */ + public static String ImportTracePackageWizardPage_ErrorOperation; + + /** + * Project text label + */ + public static String ImportTracePackageWizardPage_Project; + + /** + * The select project button text + */ + public static String ImportTracePackageWizardPage_SelectProjectButton; + + /** + * The select project dialog title + */ + public static String ImportTracePackageWizardPage_SelectProjectDialogTitle; + + /** + * Text for the generating package job + */ + public static String TracePackageExportOperation_GeneratingPackage; + + /** + * Text when error occurs creating a bookmark + */ + public static String TracePackageImportOperation_ErrorCreatingBookmark; + + /** + * Text for the detecting trace type job + */ + public static String TracePackageImportOperation_DetectingTraceType; + + /** + * Text when error occurs creating a bookmark file + */ + public static String TracePackageImportOperation_ErrorCreatingBookmarkFile; + + /** + * Text for the importing package job + */ + public static String TracePackageImportOperation_ImportingPackage; + + /** + * Text when error occurs when the manifest is not found in the archive + */ + public static String TracePackageExtractManifestOperation_ErrorManifestNotFound; + + /** + * Text when error occurs when the manifest is not valid + */ + public static String TracePackageExtractManifestOperation_ErrorManifestNotValid; + + /** + * Generic error message when reading the manifest + */ + public static String TracePackageExtractManifestOperation_ErrorReadingManifest; + + /** + * Error message when the file is an invalid format + */ + public static String TracePackageExtractManifestOperation_InvalidFormat; + + /** + * Error when the schema file cannot be found to validate the export + * manifest + */ + public static String TracePackageExtractManifestOperation_SchemaFileNotFound; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageExportOperation.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageExportOperation.java new file mode 100644 index 0000000000..d3d54ad764 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageExportOperation.java @@ -0,0 +1,304 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport; + +import java.io.ByteArrayInputStream; +import java.io.StringWriter; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.jface.operation.ModalContext; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageOperation; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.ITracePackageConstants; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageBookmarkElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFileElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFilesElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TraceUtils; +import org.eclipse.ui.internal.wizards.datatransfer.ArchiveFileExportOperation; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * An operation that exports a trace package to an archive + * + * @author Marc-Andre Laperle + */ +@SuppressWarnings("restriction") +public class TracePackageExportOperation extends AbstractTracePackageOperation { + + private static final String TRACE_EXPORT_TEMP_FOLDER = ".traceExport"; //$NON-NLS-1$ + + private final TracePackageTraceElement[] fTraceExportElements; + private final boolean fUseCompression; + private final boolean fUseTar; + private final Set fResources; + private IFolder fExportFolder; + + /** + * Constructs a new export operation + * + * @param traceExportElements + * the trace elements to be exported + * @param useCompression + * whether or not to use compression + * @param useTar + * use tar format or zip + * @param fileName + * the output file name + */ + public TracePackageExportOperation(TracePackageTraceElement[] traceExportElements, boolean useCompression, boolean useTar, String fileName) { + super(fileName); + fTraceExportElements = traceExportElements; + fUseCompression = useCompression; + fUseTar = useTar; + fResources = new HashSet<>(); + } + + /** + * Run the operation. The status (result) of the operation can be obtained + * with {@link #getStatus} + * + * @param progressMonitor + * the progress monitor to use to display progress and receive + * requests for cancellation + */ + @Override + public void run(IProgressMonitor progressMonitor) { + + try { + int totalWork = getNbCheckedElements(fTraceExportElements) * 2; + progressMonitor.beginTask(Messages.TracePackageExportOperation_GeneratingPackage, totalWork); + + fExportFolder = createExportFolder(progressMonitor); + + Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + Element createElement = doc.createElement(ITracePackageConstants.TMF_EXPORT_ELEMENT); + Node tmfNode = doc.appendChild(createElement); + + for (TracePackageTraceElement tracePackageElement : fTraceExportElements) { + if (!isFilesChecked(tracePackageElement)) { + continue; + } + + exportTrace(progressMonitor, tmfNode, tracePackageElement); + } + + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); //$NON-NLS-1$ //$NON-NLS-2$ + DOMSource source = new DOMSource(doc); + StringWriter buffer = new StringWriter(); + StreamResult result = new StreamResult(buffer); + transformer.transform(source, result); + String content = buffer.getBuffer().toString(); + + ModalContext.checkCanceled(progressMonitor); + + exportManifest(content); + + setStatus(exportToArchive(progressMonitor, totalWork)); + + fExportFolder.delete(true, new SubProgressMonitor(progressMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); + + progressMonitor.done(); + + } catch (Exception e) { + if (e instanceof InterruptedException) { + setStatus(Status.CANCEL_STATUS); + } else { + setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, e)); + } + } + } + + private IFolder createExportFolder(IProgressMonitor monitor) throws CoreException { + IFolder folder = fTraceExportElements[0].getTraceElement().getProject().getResource().getFolder(TRACE_EXPORT_TEMP_FOLDER); + if (folder.exists()) { + folder.delete(true, null); + } + folder.create(IResource.FORCE | IResource.HIDDEN, true, new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); + return folder; + } + + private void exportTrace(IProgressMonitor monitor, Node tmfNode, TracePackageTraceElement tracePackageElement) throws InterruptedException, CoreException { + TmfTraceElement traceElement = tracePackageElement.getTraceElement(); + Element traceXmlElement = tmfNode.getOwnerDocument().createElement(ITracePackageConstants.TRACE_ELEMENT); + traceXmlElement.setAttribute(ITracePackageConstants.TRACE_NAME_ATTRIB, traceElement.getResource().getName()); + traceXmlElement.setAttribute(ITracePackageConstants.TRACE_TYPE_ATTRIB, traceElement.getTraceType()); + Node traceNode = tmfNode.appendChild(traceXmlElement); + + for (TracePackageElement element : tracePackageElement.getChildren()) { + ModalContext.checkCanceled(monitor); + if (!element.isChecked()) { + continue; + } + + if (element instanceof TracePackageSupplFilesElement) { + exportSupplementaryFiles(monitor, traceNode, traceElement, (TracePackageSupplFilesElement) element); + } else if (element instanceof TracePackageBookmarkElement) { + exportBookmarks(monitor, traceNode, (TracePackageBookmarkElement) element); + } else if (element instanceof TracePackageFilesElement) { + exportTraceFiles(monitor, traceNode, (TracePackageFilesElement) element); + } + + monitor.worked(1); + } + } + + private void exportSupplementaryFiles(IProgressMonitor monitor, Node traceNode, TmfTraceElement traceElement, TracePackageSupplFilesElement element) throws InterruptedException, CoreException { + Document doc = traceNode.getOwnerDocument(); + if (element.getChildren().length > 0) { + + IPath projectPath = traceElement.getProject().getPath(); + + for (TracePackageElement child : element.getChildren()) { + TracePackageSupplFileElement supplFile = (TracePackageSupplFileElement) child; + ModalContext.checkCanceled(monitor); + IResource res = supplFile.getResource(); + // project/.tracing/A/B/statistics.ht -> .tracing/A/B/statistics.ht + IPath relativeToExportFolder = res.getFullPath().makeRelativeTo(projectPath); + + // project/.traceExport/.tracing/A/B + IFolder folder = fExportFolder.getFolder(relativeToExportFolder.removeLastSegments(1)); + TraceUtils.createFolder(folder, new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); + + res.refreshLocal(0, new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); + createExportResource(folder, res); + Element suppFileElement = doc.createElement(ITracePackageConstants.SUPPLEMENTARY_FILE_ELEMENT); + + suppFileElement.setAttribute(ITracePackageConstants.SUPPLEMENTARY_FILE_NAME_ATTRIB, relativeToExportFolder.toString()); + traceNode.appendChild(suppFileElement); + } + + IFolder suppFilesFolder = fExportFolder.getFolder(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER_NAME); + fResources.add(suppFilesFolder); + } + } + + private void exportTraceFiles(IProgressMonitor monitor, Node traceNode, TracePackageFilesElement element) throws CoreException { + Document doc = traceNode.getOwnerDocument(); + TmfTraceElement traceElement = ((TracePackageTraceElement) element.getParent()).getTraceElement(); + IResource resource = traceElement.getResource(); + IPath traceFolderPath = traceElement.getProject().getTracesFolder().getPath(); + + // project/Traces/A/B/Kernel -> A/B/Kernel + IPath relativeToExportFolder = resource.getFullPath().makeRelativeTo(traceFolderPath); + + // project/.traceExport/A/B + IFolder folder = fExportFolder.getFolder(relativeToExportFolder.removeLastSegments(1)); + TraceUtils.createFolder(folder, new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); + + createExportResource(folder, resource); + Element fileElement = doc.createElement(ITracePackageConstants.TRACE_FILE_ELEMENT); + + fileElement.setAttribute(ITracePackageConstants.TRACE_FILE_NAME_ATTRIB, relativeToExportFolder.toString()); + traceNode.appendChild(fileElement); + + // Always export the top-most folder containing the trace or the trace itself + IResource exportedResource = fExportFolder.findMember(relativeToExportFolder.segment(0)); + fResources.add(exportedResource); + } + + /** + * Creates a linked resource in the specified folder + * + * @param exportFolder the folder that will contain the linked resource + * @param res the resource to export + * @throws CoreException when createLink fails + * @return the created linked resource + */ + private static IResource createExportResource(IFolder exportFolder, IResource res) throws CoreException { + IResource ret = null; + // Note: The resources cannot be HIDDEN or else they are ignored by ArchiveFileExportOperation + if (res instanceof IFolder) { + IFolder folder = exportFolder.getFolder(res.getName()); + folder.createLink(res.getLocationURI(), IResource.NONE, null); + ret = folder; + } else if (res instanceof IFile) { + IFile file = exportFolder.getFile(res.getName()); + file.createLink(res.getLocationURI(), IResource.NONE, null); + ret = file; + } + return ret; + } + + private static void exportBookmarks(IProgressMonitor monitor, Node traceNode, TracePackageBookmarkElement element) throws CoreException, InterruptedException { + Document doc = traceNode.getOwnerDocument(); + IFile bookmarksFile = ((TracePackageTraceElement) element.getParent()).getTraceElement().getBookmarksFile(); + if (bookmarksFile != null && bookmarksFile.exists()) { + IMarker[] findMarkers = bookmarksFile.findMarkers(IMarker.BOOKMARK, false, IResource.DEPTH_ZERO); + if (findMarkers.length > 0) { + Element bookmarksXmlElement = doc.createElement(ITracePackageConstants.BOOKMARKS_ELEMENT); + Node bookmarksNode = traceNode.appendChild(bookmarksXmlElement); + + for (IMarker marker : findMarkers) { + ModalContext.checkCanceled(monitor); + + Element singleBookmarkXmlElement = doc.createElement(ITracePackageConstants.BOOKMARK_ELEMENT); + for (String key : marker.getAttributes().keySet()) { + singleBookmarkXmlElement.setAttribute(key, marker.getAttribute(key).toString()); + } + + bookmarksNode.appendChild(singleBookmarkXmlElement); + } + } + } + } + + private void exportManifest(String content) throws CoreException { + IFile file = fExportFolder.getFile(ITracePackageConstants.MANIFEST_FILENAME); + ByteArrayInputStream inputStream = new ByteArrayInputStream(content.getBytes()); + if (file.exists()) { + file.setContents(inputStream, IResource.FORCE, null); + } else { + file.create(inputStream, IResource.FORCE | IResource.HIDDEN, null); + } + fResources.add(file); + } + + private IStatus exportToArchive(IProgressMonitor monitor, int totalWork) throws InvocationTargetException, InterruptedException { + ArchiveFileExportOperation op = new ArchiveFileExportOperation(new ArrayList<>(fResources), getFileName()); + op.setCreateLeadupStructure(false); + op.setUseCompression(fUseCompression); + op.setUseTarFormat(fUseTar); + op.run(new SubProgressMonitor(monitor, totalWork / 2, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); + + return op.getStatus(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageExtractManifestOperation.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageExtractManifestOperation.java new file mode 100644 index 0000000000..47e9700cf5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageExtractManifestOperation.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport; + +import java.io.InputStream; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.operation.ModalContext; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageOperation; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.ITracePackageConstants; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement; + +/** + * An operation that extracts information from the manifest located in an + * archive + * + * @author Marc-Andre Laperle + */ +public class TracePackageExtractManifestOperation extends AbstractTracePackageOperation { + + /** + * Constructs a new import operation for reading the manifest + * + * @param fileName + * the output file name + */ + public TracePackageExtractManifestOperation(String fileName) { + super(fileName); + } + + /** + * Run extract the manifest operation. The status (result) of the operation + * can be obtained with {@link #getStatus} + * + * @param progressMonitor + * the progress monitor to use to display progress and receive + * requests for cancellation + */ + @Override + public void run(IProgressMonitor progressMonitor) { + TracePackageElement[] elements = null; + try { + progressMonitor.worked(1); + ArchiveFile archiveFile = getSpecifiedArchiveFile(); + progressMonitor.worked(1); + if (archiveFile == null) { + setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.TracePackageExtractManifestOperation_InvalidFormat)); + return; + } + + Enumeration entries = archiveFile.entries(); + + boolean found = false; + while (entries.hasMoreElements()) { + ModalContext.checkCanceled(progressMonitor); + + ArchiveEntry entry = (ArchiveEntry) entries.nextElement(); + IPath p = new Path(entry.getName()); + //Remove project name + p = p.removeFirstSegments(1); + + if (entry.getName().endsWith(ITracePackageConstants.MANIFEST_FILENAME)) { + found = true; + InputStream inputStream = archiveFile.getInputStream(entry); + ManifestReader.validateManifest(inputStream); + + inputStream = archiveFile.getInputStream(entry); + elements = ManifestReader.loadElementsFromManifest(inputStream); + break; + } + + progressMonitor.worked(1); + } + + if (found) { + setStatus(Status.OK_STATUS); + } + else { + elements = generateElementsFromArchive(); + if (elements.length > 0) { + setStatus(Status.OK_STATUS); + } else { + setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, MessageFormat.format(Messages.TracePackageExtractManifestOperation_ErrorManifestNotFound, ITracePackageConstants.MANIFEST_FILENAME))); + } + } + + setResultElements(elements); + + } catch (InterruptedException e) { + setStatus(Status.CANCEL_STATUS); + } catch (Exception e) { + setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.TracePackageExtractManifestOperation_ErrorReadingManifest, e)); + } + } + + private TracePackageElement[] generateElementsFromArchive() { + ArchiveFile archiveFile = getSpecifiedArchiveFile(); + Enumeration entries = archiveFile.entries(); + Set traceFileNames = new HashSet<>(); + while (entries.hasMoreElements()) { + ArchiveEntry entry = (ArchiveEntry) entries.nextElement(); + String entryName = entry.getName(); + IPath fullArchivePath = new Path(entryName); + if (!fullArchivePath.hasTrailingSeparator() && fullArchivePath.segmentCount() > 0) { + traceFileNames.add(fullArchivePath.segment(0)); + } + } + + List packageElements = new ArrayList<>(); + for (String traceFileName : traceFileNames) { + TracePackageTraceElement traceElement = new TracePackageTraceElement(null, traceFileName, null); + traceElement.setChildren(new TracePackageElement[] { new TracePackageFilesElement(traceElement, traceFileName) }); + packageElements.add(traceElement); + } + + return packageElements.toArray(new TracePackageElement[] {}); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageImportOperation.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageImportOperation.java new file mode 100644 index 0000000000..f28693b1f1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/TracePackageImportOperation.java @@ -0,0 +1,487 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + * Patrick Tasse - Add support for source location + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.jface.operation.ModalContext; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageOperation; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageBookmarkElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFileElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFilesElement; +import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceImportException; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; +import org.eclipse.tracecompass.tmf.core.util.Pair; +import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceTypeUIUtils; +import org.eclipse.ui.dialogs.IOverwriteQuery; +import org.eclipse.ui.ide.IDE; +import org.eclipse.ui.internal.wizards.datatransfer.TarException; +import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider; +import org.eclipse.ui.wizards.datatransfer.ImportOperation; + +/** + * An operation that imports a trace package from an archive + * + * @author Marc-Andre Laperle + */ +@SuppressWarnings("restriction") +public class TracePackageImportOperation extends AbstractTracePackageOperation implements IOverwriteQuery { + + private final TracePackageElement[] fImportTraceElements; + private final TmfTraceFolder fTmfTraceFolder; + + /** + * Constructs a new import operation + * + * @param importTraceElements + * the trace element to be imported + * @param fileName + * the output file name + * @param tmfTraceFolder + * the destination folder + */ + public TracePackageImportOperation(String fileName, TracePackageElement[] importTraceElements, TmfTraceFolder tmfTraceFolder) { + super(fileName); + fImportTraceElements = importTraceElements; + fTmfTraceFolder = tmfTraceFolder; + } + + private class ImportProvider implements IImportStructureProvider { + + private Exception fException; + + @Override + public List getChildren(Object element) { + return null; + } + + @Override + public InputStream getContents(Object element) { + InputStream inputStream = null; + // We can add throws + try { + inputStream = ((ArchiveProviderElement) element).getContents(); + } catch (IOException e) { + fException = e; + } catch (TarException e) { + fException = e; + } + return inputStream; + } + + @Override + public String getFullPath(Object element) { + return ((ArchiveProviderElement) element).getFullPath(); + } + + @Override + public String getLabel(Object element) { + return ((ArchiveProviderElement) element).getLabel(); + } + + @Override + public boolean isFolder(Object element) { + return ((ArchiveProviderElement) element).isFolder(); + } + + public Exception getException() { + return fException; + } + } + + private class ArchiveProviderElement { + + private final String fPath; + private final String fLabel; + + private ArchiveFile fArchiveFile; + private ArchiveEntry fEntry; + + public ArchiveProviderElement(String destinationPath, String label, ArchiveFile archiveFile, ArchiveEntry entry) { + fPath = destinationPath; + fLabel = label; + this.fArchiveFile = archiveFile; + this.fEntry = entry; + } + + public InputStream getContents() throws TarException, IOException { + return fArchiveFile.getInputStream(fEntry); + } + + public String getFullPath() { + return fPath; + } + + public String getLabel() { + return fLabel; + } + + public boolean isFolder() { + return false; + } + } + + /** + * Run the operation. The status (result) of the operation can be obtained + * with {@link #getStatus} + * + * @param progressMonitor + * the progress monitor to use to display progress and receive + * requests for cancellation + */ + @Override + public void run(IProgressMonitor progressMonitor) { + int totalWork = getNbCheckedElements(fImportTraceElements) * 2; + progressMonitor.beginTask(Messages.TracePackageImportOperation_ImportingPackage, totalWork); + doRun(progressMonitor); + progressMonitor.done(); + } + + private void doRun(IProgressMonitor progressMonitor) { + try { + setStatus(deleteExistingTraces(progressMonitor)); + if (getStatus().getSeverity() != IStatus.OK) { + return; + } + + TracePackageFilesElement traceFilesElement = null; + for (TracePackageElement packageElement : fImportTraceElements) { + TracePackageTraceElement traceElement = (TracePackageTraceElement) packageElement; + if (!isFilesChecked(packageElement)) { + continue; + } + + TracePackageElement[] children = traceElement.getChildren(); + for (TracePackageElement element : children) { + ModalContext.checkCanceled(progressMonitor); + + if (element instanceof TracePackageFilesElement) { + traceFilesElement = (TracePackageFilesElement) element; + setStatus(importTraceFiles(traceFilesElement, traceElement, progressMonitor)); + + } else if (element instanceof TracePackageSupplFilesElement) { + TracePackageSupplFilesElement suppFilesElement = (TracePackageSupplFilesElement) element; + setStatus(importSupplFiles(suppFilesElement, traceElement, progressMonitor)); + } + + if (getStatus().getSeverity() != IStatus.OK) { + return; + } + } + } + + } catch (InterruptedException e) { + setStatus(Status.CANCEL_STATUS); + } + } + + /** + * Returns whether or not the Files element is checked under the given trace + * package element + * + * @param tracePackageElement + * the trace package element + * @return whether or not the Files element is checked under the given trace + * package element + */ + public static boolean isFilesChecked(TracePackageElement tracePackageElement) { + for (TracePackageElement element : tracePackageElement.getChildren()) { + if (element instanceof TracePackageFilesElement) { + return element.isChecked(); + } + } + + return false; + } + + /** + * Return the matching TmfTraceElement for a given trace element. + */ + private TmfTraceElement getMatchingTraceElement(TracePackageTraceElement tracePackageElement) { + IPath tracePath = fTmfTraceFolder.getPath().append(tracePackageElement.getDestinationElementPath()); + List traces = fTmfTraceFolder.getTraces(); + for (TmfTraceElement t : traces) { + if (t.getPath().equals(tracePath)) { + return t; + } + } + + return null; + } + + private IStatus deleteExistingTraces(IProgressMonitor progressMonitor) { + for (TracePackageElement packageElement : fImportTraceElements) { + TracePackageTraceElement traceElement = (TracePackageTraceElement) packageElement; + if (!isFilesChecked(traceElement)) { + continue; + } + + TmfTraceElement existingTrace = getMatchingTraceElement(traceElement); + if (existingTrace != null) { + try { + existingTrace.delete(new SubProgressMonitor(progressMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); + } catch (CoreException e) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, e); + } + } + } + + return Status.OK_STATUS; + } + + private void importBookmarks(IResource traceRes, TracePackageTraceElement traceElement, IProgressMonitor monitor) { + for (TracePackageElement o : traceElement.getChildren()) { + if (o instanceof TracePackageBookmarkElement && o.isChecked()) { + + // Get element + IFile bookmarksFile = null; + TmfTraceElement tmfTraceElement = getMatchingTraceElement(traceElement); + if (tmfTraceElement != null) { + try { + bookmarksFile = tmfTraceElement.createBookmarksFile(); + + // Make sure that if a bookmark is double-clicked first + // before opening the trace, it opens the right editor + + // Get the editor id from the extension point + String traceEditorId = tmfTraceElement.getEditorId(); + final String editorId = (traceEditorId != null) ? traceEditorId : TmfEventsEditor.ID; + IDE.setDefaultEditor(bookmarksFile, editorId); + + } catch (CoreException e) { + Activator.getDefault().logError(MessageFormat.format(Messages.TracePackageImportOperation_ErrorCreatingBookmarkFile, traceRes.getName()), e); + } + } + + if (bookmarksFile == null) { + break; + } + + TracePackageBookmarkElement bookmarkElement = (TracePackageBookmarkElement) o; + + List> bookmarks = bookmarkElement.getBookmarks(); + for (Map attrs : bookmarks) { + IMarker createMarker = null; + try { + createMarker = bookmarksFile.createMarker(IMarker.BOOKMARK); + } catch (CoreException e) { + Activator.getDefault().logError(MessageFormat.format(Messages.TracePackageImportOperation_ErrorCreatingBookmark, traceRes.getName()), e); + } + if (createMarker != null && createMarker.exists()) { + try { + for (String key : attrs.keySet()) { + String value = attrs.get(key); + if (key.equals(IMarker.LOCATION)) { + createMarker.setAttribute(IMarker.LOCATION, Integer.valueOf(value).intValue()); + } else { + createMarker.setAttribute(key, value); + } + } + } catch (CoreException e) { + Activator.getDefault().logError(MessageFormat.format(Messages.TracePackageImportOperation_ErrorCreatingBookmark, traceRes.getName()), e); + } + } + } + } + } + + monitor.worked(1); + } + + private IStatus importTraceFiles(TracePackageFilesElement traceFilesElement, TracePackageTraceElement traceElement, IProgressMonitor monitor) { + List> fileNameAndLabelPairs = new ArrayList<>(); + + String sourceName = traceFilesElement.getFileName(); + String destinationName = traceElement.getImportName(); + + fileNameAndLabelPairs.add(new Pair<>(sourceName, destinationName)); + + IPath containerPath = fTmfTraceFolder.getPath(); + IStatus status = importFiles(getSpecifiedArchiveFile(), fileNameAndLabelPairs, containerPath, Path.EMPTY, monitor); + if (getStatus().getSeverity() != IStatus.OK) { + return status; + } + + // We need to set the trace type before importing the supplementary files so we do it here + IResource traceRes = fTmfTraceFolder.getResource().findMember(traceElement.getDestinationElementPath()); + if (traceRes == null || !traceRes.exists()) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, MessageFormat.format(Messages.ImportTracePackageWizardPage_ErrorFindingImportedTrace, destinationName)); + } + + TraceTypeHelper traceType = null; + String traceTypeStr = traceElement.getTraceType(); + if (traceTypeStr != null) { + traceType = TmfTraceType.getTraceType(traceTypeStr); + if (traceType == null) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, MessageFormat.format(Messages.ImportTracePackageWizardPage_ErrorSettingTraceType, traceElement.getTraceType(), destinationName)); + } + } else { + try { + monitor.subTask(MessageFormat.format(Messages.TracePackageImportOperation_DetectingTraceType, destinationName)); + traceType = TmfTraceTypeUIUtils.selectTraceType(traceRes.getLocation().toOSString(), null, null); + } catch (TmfTraceImportException e) { + // Could not figure out the type + } + } + + if (traceType != null) { + try { + TmfTraceTypeUIUtils.setTraceType(traceRes, traceType); + } catch (CoreException e) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, MessageFormat.format(Messages.ImportTracePackageWizardPage_ErrorSettingTraceType, traceElement.getTraceType(), destinationName), e); + } + } + + importBookmarks(traceRes, traceElement, monitor); + + try { + URI uri = new File(getFileName()).toURI(); + IPath entryPath = new Path(traceFilesElement.getFileName()); + if (traceRes instanceof IFolder) { + entryPath = entryPath.addTrailingSeparator(); + } + String sourceLocation = URIUtil.toUnencodedString(URIUtil.toJarURI(uri, entryPath)); + traceRes.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation); + } catch (CoreException e) { + } + + return status; + } + + private IStatus importSupplFiles(TracePackageSupplFilesElement suppFilesElement, TracePackageTraceElement traceElement, IProgressMonitor monitor) { + List> fileNameAndLabelPairs = new ArrayList<>(); + for (TracePackageElement child : suppFilesElement.getChildren()) { + TracePackageSupplFileElement supplFile = (TracePackageSupplFileElement) child; + fileNameAndLabelPairs.add(new Pair<>(supplFile.getText(), new Path(supplFile.getText()).lastSegment())); + } + + if (!fileNameAndLabelPairs.isEmpty()) { + TmfTraceElement existingTrace = getMatchingTraceElement(traceElement); + if (existingTrace != null) { + ArchiveFile archiveFile = getSpecifiedArchiveFile(); + existingTrace.refreshSupplementaryFolder(); + // Project/Traces/A/B -> A/B + IPath traceFolderRelativePath = fTmfTraceFolder.getPath().makeRelativeTo(fTmfTraceFolder.getProject().getTracesFolder().getPath()); + // Project/.tracing/A/B/ + IFolder traceSupplementaryFolder = fTmfTraceFolder.getTraceSupplementaryFolder(traceFolderRelativePath.toString()); + IPath destinationContainerPath = traceSupplementaryFolder.getFullPath(); + // Remove the .tracing segment at the beginnin so that a file in folder .tracing/A/B/ imports destinationContainerPath/A/B/ + Path baseSourcePath = new Path(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER_NAME); + return importFiles(archiveFile, fileNameAndLabelPairs, destinationContainerPath, baseSourcePath, monitor); + } + } + + return Status.OK_STATUS; + } + + private IStatus importFiles(ArchiveFile archiveFile, List> fileNameAndLabelPairs, IPath destinationContainerPath, IPath baseSourcePath, IProgressMonitor monitor) { + List objects = new ArrayList<>(); + Enumeration entries = archiveFile.entries(); + while (entries.hasMoreElements()) { + ArchiveEntry entry = (ArchiveEntry) entries.nextElement(); + String entryName = entry.getName(); + IPath fullArchivePath = new Path(entryName); + if (fullArchivePath.hasTrailingSeparator()) { + // We only care about file entries as the folders will get created by the ImportOperation + continue; + } + + for (Pair fileNameAndLabel : fileNameAndLabelPairs) { + + // Examples: Traces/aaa/kernel/ .tracing/aaa/testtexttrace.txt/statistics.ht + IPath searchedArchivePath = new Path(fileNameAndLabel.getFirst()); + + // Check if this archive entry matches the searched file name at this archive location + boolean fileMatch = entryName.equalsIgnoreCase(searchedArchivePath.toString()); + // For example Traces/aaa/kernel/metadata matches Traces/aaa/kernel/ + boolean folderMatch = entryName.startsWith(searchedArchivePath + "/"); //$NON-NLS-1$ + + if (fileMatch || folderMatch) { + // .tracing/aaa/testtexttrace.txt/statistics.ht -> aaa/testtexttrace.txt/statistics.ht + IPath destinationPath = fullArchivePath.makeRelativeTo(baseSourcePath); + + // metadata statistics.ht + // We don't use the label when the entry is a folder match because the labels for individual files + // under the folder are not specified in the manifest so just use the last segment. + String resourceLabel = folderMatch ? fullArchivePath.lastSegment() : fileNameAndLabel.getSecond(); + + ArchiveProviderElement pe = new ArchiveProviderElement(destinationPath.toString(), resourceLabel, archiveFile, entry); + objects.add(pe); + break; + } + } + } + + ImportProvider provider = new ImportProvider(); + + ImportOperation operation = new ImportOperation(destinationContainerPath, + null, provider, this, + objects); + operation.setCreateContainerStructure(true); + operation.setOverwriteResources(true); + + try { + operation.run(new SubProgressMonitor(monitor, fileNameAndLabelPairs.size(), SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); + archiveFile.close(); + } catch (InvocationTargetException e) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, e); + } catch (InterruptedException e) { + return Status.CANCEL_STATUS; + } catch (IOException e) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, e); + } + + if (provider.getException() != null) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, provider.getException()); + } + + return operation.getStatus(); + } + + @Override + public String queryOverwrite(String pathString) { + // We always overwrite once we reach this point + return null; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/messages.properties new file mode 100644 index 0000000000..a5fc3ed167 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/importexport/messages.properties @@ -0,0 +1,53 @@ +############################################################################### +# Copyright (c) 2013 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Marc-Andre Laperle - Initial API and implementation +############################################################################### + +ExportTracePackageSelectTraceWizardPage_ChooseTrace=Choose traces to export +ExportTracePackageSelectTraceWizardPage_ProjectSelection=Project +ExportTracePackageSelectTraceWizardPage_TraceSelection=Traces +ExportTracePackageWizardPage_AlreadyExitst = Target file already exists. Would you like to overwrite it? +ExportTracePackageWizardPage_ApproximateSizeLbl=Approximate uncompressed size: {0} +ExportTracePackageWizardPage_ChooseContent=Choose the content to export +ExportTracePackageWizardPage_CompressContents=Co&mpress the contents of the file +ExportTracePackageWizardPage_ContentColumnName=Content +ExportTracePackageWizardPage_Options=Options +ExportTracePackageWizardPage_SaveInTarFormat=Sa&ve in tar format +ExportTracePackageWizardPage_SaveInZipFormat=Save in &zip format +ExportTracePackageWizardPage_SizeByte=B +ExportTracePackageWizardPage_SizeColumnName=Size +ExportTracePackageWizardPage_SizeGigabyte=GB +ExportTracePackageWizardPage_SizeKilobyte=KB +ExportTracePackageWizardPage_SizeMegabyte=MB +ExportTracePackageWizardPage_SizeTerabyte=TB +ExportTracePackageWizardPage_Title=Export trace package +ExportTracePackageWizardPage_ToArchive=To &archive file: +ImportTracePackageWizardPage_AlreadyExists=A trace with the name ''{0}'' already exists. Would you like to overwrite it? +ImportTracePackageWizardPage_ErrorFileNotFound=File does not exist +ImportTracePackageWizardPage_ErrorOperation=Error occurred during import trace operation +ImportTracePackageWizardPage_ErrorSettingTraceType=Error setting the type {0} for the trace {1} +ImportTracePackageWizardPage_ErrorFindingImportedTrace=Could not find the imported trace {0} in the workspace +ImportTracePackageWizardPage_FromArchive=From &archive file: +ImportTracePackageWizardPage_Message=Choose the content to import +ImportTracePackageWizardPage_Project=Into project: +ImportTracePackageWizardPage_ReadingPackage=Reading package +ImportTracePackageWizardPage_SelectProjectButton=Select +ImportTracePackageWizardPage_SelectProjectDialogTitle=Select project +ImportTracePackageWizardPage_Title=Import trace package +TracePackageExportOperation_GeneratingPackage=Generating package +TracePackageExtractManifestOperation_ErrorManifestNotFound=The required manifest file {0} could not be found. +TracePackageExtractManifestOperation_ErrorManifestNotValid=The manifest file is not valid. +TracePackageExtractManifestOperation_ErrorReadingManifest=An error occurred when reading the manifest +TracePackageExtractManifestOperation_InvalidFormat=The selected file is not a supported file format +TracePackageExtractManifestOperation_SchemaFileNotFound=The schema file {0} could not be found. +TracePackageImportOperation_ErrorCreatingBookmark=Error creating bookmark for the trace {0} +TracePackageImportOperation_ErrorCreatingBookmarkFile=Error creating bookmark file for the trace {0} +TracePackageImportOperation_ImportingPackage=Importing package +TracePackageImportOperation_DetectingTraceType=Detecting trace type for ''{0}'' diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/messages.properties new file mode 100644 index 0000000000..47ea91587e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/tracepkg/messages.properties @@ -0,0 +1,22 @@ +############################################################################### +# Copyright (c) 2013 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Marc-Andre Laperle - Initial API and implementation +############################################################################### + +TracePackage_Bookmarks=Bookmarks +TracePackage_Browse=B&rowse... +TracePackage_DeselectAll=Deselect All +TracePackage_ErrorOperation=Error occurred during trace package operation +TracePackage_ErrorMultipleProblems=Multiple problems. Click Details for more information. +TracePackage_FileDialogTitle=Choose Archive File +TracePackage_InternalErrorTitle=Internal error +TracePackage_SelectAll=Select All +TracePackage_SupplementaryFiles=Supplementary files +TracePackage_TraceElement=Trace \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfContentsColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfContentsColumn.java new file mode 100644 index 0000000000..a9c45971cc --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfContentsColumn.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.viewers.events.columns; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; + +/** + * Column for the event contents (fields) + * + * @author Alexandre Montplaisir + */ +public final class TmfContentsColumn extends TmfEventTableColumn { + + @SuppressWarnings("null") + private static final @NonNull String HEADER = Messages.TmfEventsTable_ContentColumnHeader; + + /** + * Constructor + */ + public TmfContentsColumn() { + super(HEADER); + } + + @Override + public String getItemString(ITmfEvent event) { + String ret = event.getContent().toString(); + return (ret == null ? EMPTY_STRING : ret); + } + + @Override + public String getFilterFieldId() { + return ITmfEvent.EVENT_FIELD_CONTENT; + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfReferenceColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfReferenceColumn.java new file mode 100644 index 0000000000..2b0d20f1f0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfReferenceColumn.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.viewers.events.columns; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; + +/** + * Column for the event reference + * + * TODO Remove me, replace with trace-type-specific columns + */ +public final class TmfReferenceColumn extends TmfEventTableColumn { + + @SuppressWarnings("null") + private static final @NonNull String HEADER = Messages.TmfEventsTable_ReferenceColumnHeader; + + /** + * Constructor + */ + public TmfReferenceColumn() { + super(HEADER); + } + + @Override + public String getItemString(ITmfEvent event) { + String ref = event.getReference(); + return (ref == null ? EMPTY_STRING : ref); + } + + @Override + public String getFilterFieldId() { + return ITmfEvent.EVENT_FIELD_REFERENCE; + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfSourceColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfSourceColumn.java new file mode 100644 index 0000000000..85d3cde65f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfSourceColumn.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.viewers.events.columns; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; + +/** + * Column for the event source + * + * TODO Remove me, replace with trace-type-specific columns + */ +public final class TmfSourceColumn extends TmfEventTableColumn { + + @SuppressWarnings("null") + private static final @NonNull String HEADER = Messages.TmfEventsTable_SourceColumnHeader; + + /** + * Constructor + */ + public TmfSourceColumn() { + super(HEADER); + } + + @Override + public String getItemString(ITmfEvent event) { + String source = event.getSource(); + return (source == null ? EMPTY_STRING : source); + } + + @Override + public String getFilterFieldId() { + return ITmfEvent.EVENT_FIELD_SOURCE; + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfTimestampColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfTimestampColumn.java new file mode 100644 index 0000000000..49c03fa247 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfTimestampColumn.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.viewers.events.columns; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; + +/** + * Column for the timestamps + */ +public final class TmfTimestampColumn extends TmfEventTableColumn { + + @SuppressWarnings("null") + private static final @NonNull String HEADER = Messages.TmfEventsTable_TimestampColumnHeader; + + /** + * Constructor + */ + public TmfTimestampColumn() { + super(HEADER); + } + + @Override + public String getItemString(ITmfEvent event) { + String ret = event.getTimestamp().toString(); + return (ret == null ? EMPTY_STRING : ret); + } + + @Override + public String getFilterFieldId() { + return ITmfEvent.EVENT_FIELD_TIMESTAMP; + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfTypeColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfTypeColumn.java new file mode 100644 index 0000000000..07810caf45 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfTypeColumn.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.viewers.events.columns; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; + +/** + * Column for the event type + */ +public final class TmfTypeColumn extends TmfEventTableColumn { + + @SuppressWarnings("null") + private static final @NonNull String HEADER = Messages.TmfEventsTable_TypeColumnHeader; + + /** + * Constructor + */ + public TmfTypeColumn() { + super(HEADER); + } + + @Override + public String getItemString(ITmfEvent event) { + ITmfEventType type = event.getType(); + if (type == null) { + return EMPTY_STRING; + } + String typeName = type.getName(); + return (typeName == null ? EMPTY_STRING : typeName); + } + + @Override + public String getFilterFieldId() { + return ITmfEvent.EVENT_FIELD_TYPE; + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/TmfUiRefreshHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/TmfUiRefreshHandler.java new file mode 100644 index 0000000000..53c5bf6022 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/TmfUiRefreshHandler.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + * Patrick Tasse - Update queue handling + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.eclipse.swt.widgets.Display; + +/** + * This handler offers "coalescing" of UI updates. + * + * When displaying live experiments containing a high number of traces, every + * trace will want to regularly update views with their new available data. This + * can cause a high number of threads calling {@link Display#asyncExec} + * repeatedly, which can really impede UI responsiveness. + *

    + * Instead of calling {@link Display#asyncExec} directly, threads that want to + * queue updates to the UI can instead call + * {@link TmfUiRefreshHandler#queueUpdate}. If the handler is not currently + * executing another update it will be scheduled immediately. Otherwise the + * update will be queued. + *

    + * The handler will only execute one update at a time. While it is busy, new + * requests received from a source that is already in the queue will replace the + * previous one (as we assume the latest UI update request is the most + * up-to-date and interesting one), preserving the previous request order. New + * requests received from other sources will be added to the end of the queue + * (keeping only the latest request from each source). + *

    + * Once the current update is completed, the oldest request in the queue will be + * sent to the UI thread via one single call to {@link Display#syncExec}. + * + * @author Alexandre Montplaisir + * @since 3.1 + */ +public class TmfUiRefreshHandler { + + /** Singleton instance */ + private static TmfUiRefreshHandler fInstance = null; + + private final Map fUpdates = new LinkedHashMap<>(); + private Thread fCurrentTask; + + + /** + * Internal constructor + */ + private TmfUiRefreshHandler() { + fCurrentTask = null; + } + + /** + * Get the handler's instance + * + * @return The singleton instance + */ + public static synchronized TmfUiRefreshHandler getInstance() { + if (fInstance == null) { + fInstance = new TmfUiRefreshHandler(); + } + return fInstance; + } + + /** + * Cancel all current requests and dispose the handler. + */ + public synchronized void dispose() { + fUpdates.clear(); + fCurrentTask = null; + } + + /** + * Queue a UI update. Threads that want to benefit from "UI coalescing" + * should send their {@link Runnable} to this method, instead of + * {@link Display#asyncExec(Runnable)}. + * + * @param source + * The source sending the request. Typically callers should use + * "this". When multiple requests are queued before being + * executed, only the latest request per source is actually sent. + * @param task + * The {@link Runnable} to execute in the UI thread. + */ + public synchronized void queueUpdate(Object source, Runnable task) { + fUpdates.put(source, task); + if (fCurrentTask == null) { + fCurrentTask = new RunAllUpdates(); + fCurrentTask.start(); + } + } + + /** + * Task to empty the update queue, and send each task to the UI thread. + */ + private class RunAllUpdates extends Thread { + @Override + public void run() { + while (true) { + Runnable nextTask = null; + synchronized (TmfUiRefreshHandler.this) { + if (!fUpdates.isEmpty()) { + Object firstKey = fUpdates.keySet().iterator().next(); + nextTask = fUpdates.get(firstKey); + fUpdates.remove(firstKey); + } + if (nextTask == null) { + /* + * No updates remaining in the queue, put fCurrentTask + * back to null so that a new task can be scheduled. + */ + fCurrentTask = null; + break; + } + } + Display.getDefault().syncExec(nextTask); + } + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/analysis/TmfAnalysisViewOutput.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/analysis/TmfAnalysisViewOutput.java new file mode 100644 index 0000000000..6127eeaefe --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/analysis/TmfAnalysisViewOutput.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.analysis; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExecutableExtension; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisOutput; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisModuleOutputs; +import org.eclipse.tracecompass.tmf.ui.project.model.Messages; +import org.eclipse.tracecompass.tmf.ui.project.model.TraceUtils; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.WorkbenchPart; +import org.eclipse.ui.views.IViewDescriptor; + +/** + * Class that implements analysis output as a view. This just opens the view. + * The view itself needs to manage how and when it will execute the analysis and + * display which output. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfAnalysisViewOutput implements IAnalysisOutput, IExecutableExtension { + + private String fViewId; + private final Map fProperties = new HashMap<>(); + + /** + * Default constructor + */ + public TmfAnalysisViewOutput() { + + } + + /** + * Constructor + * + * @param viewid + * id of the view to display as output + */ + public TmfAnalysisViewOutput(String viewid) { + fViewId = viewid; + } + + /** + * Returns the view id of the corresponding view + * + * @return The view id + */ + public String getViewId() { + return fViewId; + } + + @Override + public String getName() { + IViewDescriptor descr = PlatformUI.getWorkbench().getViewRegistry().find(fViewId); + String viewName = (descr != null) ? descr.getLabel() : fViewId + Messages.TmfAnalysisViewOutput_ViewUnavailable; + return viewName; + } + + @Override + public void requestOutput() { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + + try { + final IWorkbench wb = PlatformUI.getWorkbench(); + final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); + + IViewPart view = activePage.showView(fViewId); + if (!(fProperties.isEmpty()) && (view instanceof WorkbenchPart)) { + WorkbenchPart wbPart = (WorkbenchPart) view; + for (String key : fProperties.keySet()) { + wbPart.setPartProperty(key, fProperties.get(key)); + } + } + + } catch (final PartInitException e) { + TraceUtils.displayErrorMsg(Messages.TmfAnalysisViewOutput_Title, "Error opening view " + getName() + e.getMessage()); //$NON-NLS-1$ + Activator.getDefault().logError("Error opening view " + getName(), e); //$NON-NLS-1$ + } + } + }); + } + + @Override + public void setOutputProperty(@NonNull String key, String value, boolean immediate) { + if (value == null) { + fProperties.remove(key); + } else { + fProperties.put(key, value); + /* + * If the property is immediate, we forward it to the view if the + * view is active + */ + if (immediate) { + final IWorkbench wb = PlatformUI.getWorkbench(); + final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); + IViewPart view = activePage.findView(fViewId); + if (view instanceof WorkbenchPart) { + ((WorkbenchPart) view).setPartProperty(key, value); + } + } + } + } + + @Override + public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException { + fViewId = config.getAttribute(TmfAnalysisModuleOutputs.ID_ATTR); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/ITmfTraceEditor.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/ITmfTraceEditor.java new file mode 100644 index 0000000000..2d2ef1a9bd --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/ITmfTraceEditor.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.editors; + +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * The trace editor interface + * + * @version 1.0 + * @author Patrick Tasse + */ +public interface ITmfTraceEditor { + + /** + * Get the trace to which this editor is assigned + * + * @return The trace + */ + ITmfTrace getTrace(); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/TmfEditor.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/TmfEditor.java new file mode 100644 index 0000000000..1751d9650f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/TmfEditor.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Bernd Hufmann - Add interface for broadcasting signals asynchronously + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.editors; + +import org.eclipse.tracecompass.tmf.core.component.ITmfComponent; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.ui.part.EditorPart; + +/** + * The main editor abstract class for use in TMF. + * + * @version 1.0 + * @author Patrick Tasse + */ +public abstract class TmfEditor extends EditorPart implements ITmfComponent { + + private final String fName; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + public TmfEditor() { + super(); + fName = "TmfEditor"; //$NON-NLS-1$ + TmfSignalManager.register(this); + } + + @Override + public void dispose() { + TmfSignalManager.deregister(this); + super.dispose(); + } + + // ------------------------------------------------------------------------ + // ITmfComponent + // ------------------------------------------------------------------------ + + @Override + public String getName() { + return fName; + } + + @Override + public void broadcast(TmfSignal signal) { + TmfSignalManager.dispatchSignal(signal); + } + + /** + * @since 3.0 + */ + @Override + public void broadcastAsync(TmfSignal signal) { + TmfSignalManager.dispatchSignalAsync(signal); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/TmfEditorInput.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/TmfEditorInput.java new file mode 100644 index 0000000000..fb78360a5c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/TmfEditorInput.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.editors; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.content.IContentType; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.ide.IDE; + +/** + * The input interface for TMF editors. + * + * @version 1.0 + * @author Patrick Tasse + */ +public class TmfEditorInput implements IEditorInput { + + private final IFile fFile; + private final ITmfTrace fTrace; + + /** + * Standard constructor + * + * @param file The IFile pointer + * @param trace Reference to the trace + */ + public TmfEditorInput(IFile file, ITmfTrace trace) { + fFile = file; + fTrace = trace; + } + + @Override + public Object getAdapter(Class adapter) { + return null; + } + + @Override + public boolean exists() { + /* prevent this input from appearing in "Files Most Recently Used" list, + * as this causes lingering reference to ITmfTrace in the platform */ + return false; + } + + @Override + public ImageDescriptor getImageDescriptor() { + IContentType contentType = IDE.getContentType(fFile); + return PlatformUI.getWorkbench().getEditorRegistry() + .getImageDescriptor(fFile.getName(), contentType); + } + + @Override + public String getName() { + return fTrace.getName(); + } + + @Override + public IPersistableElement getPersistable() { + return null; + } + + @Override + public String getToolTipText() { + return fFile.getFullPath().makeRelative().toString(); + } + + /** + * Get this editor input's file object + * + * @return The IFile + */ + public IFile getFile() { + return fFile; + } + + /** + * Get this editor input's trace + * + * @return The trace + */ + public ITmfTrace getTrace() { + return fTrace; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((fFile == null) ? 0 : fFile.getLocation().hashCode()); + result = prime * result + ((fTrace == null) ? 0 : fTrace.getName().hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TmfEditorInput other = (TmfEditorInput) obj; + if (fFile == null) { + if (other.fFile != null) { + return false; + } + } else if (!fFile.getLocation().equals(other.fFile.getLocation())) { + return false; + } + if (fTrace == null) { + if (other.fTrace != null) { + return false; + } + } else if (!fTrace.getName().equals(other.fTrace.getName())) { + return false; + } + return true; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/TmfEventsEditor.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/TmfEventsEditor.java new file mode 100644 index 0000000000..75300b2576 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/TmfEventsEditor.java @@ -0,0 +1,649 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Geneviève Bastien - Experiment instantiated with experiment type + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.editors; + +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IMarkerDelta; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.InvalidRegistryObjectException; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; +import org.eclipse.tracecompass.tmf.core.trace.TmfTrace; +import org.eclipse.tracecompass.tmf.ui.project.model.Messages; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfOpenTraceHelper; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceTypeUIUtils; +import org.eclipse.tracecompass.tmf.ui.viewers.events.TmfEventsTable; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IPropertyListener; +import org.eclipse.ui.IReusableEditor; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.ide.IGotoMarker; +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.views.properties.IPropertySheetPage; + +/** + * Editor for TMF events + * + * @version 1.0 + * @author Patrick Tasse + * @since 2.0 + */ +public class TmfEventsEditor extends TmfEditor implements ITmfTraceEditor, IReusableEditor, IPropertyListener, IResourceChangeListener, ISelectionProvider, ISelectionChangedListener, IPartListener, IGotoMarker { + + /** ID for this class */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.editors.events"; //$NON-NLS-1$ + + private TmfEventsTable fEventsTable; + private IFile fFile; + private ITmfTrace fTrace; + private Composite fParent; + private ListenerList fSelectionChangedListeners = new ListenerList(); + private boolean fTraceSelected; + private IMarker fPendingGotoMarker; + + @Override + public void doSave(final IProgressMonitor monitor) { + } + + @Override + public void doSaveAs() { + } + + @Override + public void init(final IEditorSite site, IEditorInput input) throws PartInitException { + IFileEditorInput fileEditorInput; + if (input instanceof TmfEditorInput) { + fFile = ((TmfEditorInput) input).getFile(); + fTrace = ((TmfEditorInput) input).getTrace(); + /* change the input to a FileEditorInput to allow open handlers to find this editor */ + fileEditorInput = new FileEditorInput(fFile); + } else if (input instanceof IFileEditorInput) { + fileEditorInput = (IFileEditorInput) input; + fFile = fileEditorInput.getFile(); + if (fFile == null) { + throw new PartInitException("Invalid IFileEditorInput: " + fileEditorInput); //$NON-NLS-1$ + } + try { + final String traceTypeId = fFile.getPersistentProperty(TmfCommonConstants.TRACETYPE); + if (traceTypeId == null) { + throw new PartInitException(Messages.TmfOpenTraceHelper_NoTraceType); + } + if (traceTypeId.equals(TmfExperiment.class.getCanonicalName())) { + // Special case: experiment bookmark resource + final TmfProjectElement project = TmfProjectRegistry.getProject(fFile.getProject(), true); + if (project == null) { + throw new PartInitException(Messages.TmfOpenTraceHelper_NoTraceType); + } + for (final TmfExperimentElement experimentElement : project.getExperimentsFolder().getExperiments()) { + if (experimentElement.getResource().equals(fFile.getParent())) { + setPartName(experimentElement.getName()); + super.setSite(site); + super.setInput(fileEditorInput); + TmfOpenTraceHelper.reopenTraceFromElement(experimentElement, this); + return; + } + } + } else if (traceTypeId.equals(TmfTrace.class.getCanonicalName())) { + // Special case: trace bookmark resource + final TmfProjectElement project = TmfProjectRegistry.getProject(fFile.getProject(), true); + for (final TmfTraceElement traceElement : project.getTracesFolder().getTraces()) { + if (traceElement.getResource().equals(fFile.getParent())) { + setPartName(traceElement.getName()); + super.setSite(site); + super.setInput(fileEditorInput); + TmfOpenTraceHelper.reopenTraceFromElement(traceElement, this); + return; + } + } + } else { + final TmfProjectElement project = TmfProjectRegistry.getProject(fFile.getProject(), true); + for (final TmfTraceElement traceElement : project.getTracesFolder().getTraces()) { + if (traceElement.getResource().equals(fFile)) { + setPartName(traceElement.getName()); + super.setSite(site); + super.setInput(fileEditorInput); + TmfOpenTraceHelper.reopenTraceFromElement(traceElement, this); + return; + } + } + } + } catch (final PartInitException e) { + throw e; + } catch (final InvalidRegistryObjectException e) { + Activator.getDefault().logError("Error initializing TmfEventsEditor", e); //$NON-NLS-1$ + } catch (final CoreException e) { + Activator.getDefault().logError("Error initializing TmfEventsEditor", e); //$NON-NLS-1$ + } + } else { + throw new PartInitException("Invalid IEditorInput: " + input.getClass()); //$NON-NLS-1$ + } + if (fTrace == null) { + throw new PartInitException("Invalid IEditorInput: " + fFile.getName()); //$NON-NLS-1$ + } + super.setSite(site); + super.setInput(fileEditorInput); + } + + @Override + public boolean isDirty() { + return false; + } + + @Override + public boolean isSaveAsAllowed() { + return false; + } + + @Override + public void setInput(final IEditorInput input) { + super.setInput(input); + firePropertyChange(IEditorPart.PROP_INPUT); + } + + @Override + public void propertyChanged(final Object source, final int propId) { + if (propId == IEditorPart.PROP_INPUT && getEditorInput() instanceof TmfEditorInput) { + if (fTrace != null) { + broadcast(new TmfTraceClosedSignal(this, fTrace)); + } + fTraceSelected = false; + fFile = ((TmfEditorInput) getEditorInput()).getFile(); + fTrace = ((TmfEditorInput) getEditorInput()).getTrace(); + /* change the input to a FileEditorInput to allow open handlers to find this editor */ + super.setInput(new FileEditorInput(fFile)); + fEventsTable.dispose(); + if (fTrace != null) { + setPartName(fTrace.getName()); + fEventsTable = createEventsTable(fParent, fTrace.getCacheSize()); + fEventsTable.addSelectionChangedListener(this); + fEventsTable.setTrace(fTrace, true); + fEventsTable.refreshBookmarks(fFile); + if (fPendingGotoMarker != null) { + fEventsTable.gotoMarker(fPendingGotoMarker); + fPendingGotoMarker = null; + } + + /* ensure start time is set */ + final ITmfContext context = fTrace.seekEvent(0); + fTrace.getNext(context); + context.dispose(); + + broadcast(new TmfTraceOpenedSignal(this, fTrace, fFile)); + } else { + setPartName(getEditorInput().getName()); + fEventsTable = new TmfEventsTable(fParent, 0); + fEventsTable.addSelectionChangedListener(this); + } + fParent.layout(); + } + } + + @Override + public void createPartControl(final Composite parent) { + fParent = parent; + if (fTrace != null) { + setPartName(fTrace.getName()); + fEventsTable = createEventsTable(parent, fTrace.getCacheSize()); + fEventsTable.addSelectionChangedListener(this); + fEventsTable.setTrace(fTrace, true); + fEventsTable.refreshBookmarks(fFile); + + /* ensure start time is set */ + final ITmfContext context = fTrace.seekEvent(0); + fTrace.getNext(context); + context.dispose(); + + broadcast(new TmfTraceOpenedSignal(this, fTrace, fFile)); + } else { + fEventsTable = new TmfEventsTable(parent, 0); + fEventsTable.addSelectionChangedListener(this); + } + IStatusLineManager statusLineManager = getEditorSite().getActionBars().getStatusLineManager(); + fEventsTable.setStatusLineManager(statusLineManager); + addPropertyListener(this); + ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE); + // we need to wrap the ISelectionProvider interface in the editor because + // the events table can be replaced later while the selection changed listener + // is only added once by the platform to the selection provider set here + getSite().setSelectionProvider(this); + getSite().getPage().addPartListener(this); + } + + @Override + public void dispose() { + if (getSite() != null) { + getSite().getPage().removePartListener(this); + } + ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); + removePropertyListener(this); + if (fTrace != null) { + broadcast(new TmfTraceClosedSignal(this, fTrace)); + } + if (fEventsTable != null) { + fEventsTable.dispose(); + } + super.dispose(); + } + + /** + * Create the event table + * + * @param parent + * The parent composite + * @param cacheSize + * The cache size + * @return The event table instance + */ + protected @NonNull TmfEventsTable createEventsTable(final Composite parent, final int cacheSize) { + return getEventTable(fTrace, parent, cacheSize); + } + + /** + * Get the event table for the given trace. It will be of the type defined + * by the extension point if applicable, else it will be a default table + * with the extension-point-defined columns (if any). + * + * @param trace + * The event table is for this trace + * @param parent + * The parent composite of the table + * @param cacheSize + * The cache size to use + * @return The event table for the trace + */ + private static @NonNull TmfEventsTable getEventTable(ITmfTrace trace, + final Composite parent, final int cacheSize) { + if (trace instanceof TmfExperiment) { + return getExperimentEventTable((TmfExperiment) trace, parent, cacheSize); + } + + TmfEventsTable table = TmfTraceTypeUIUtils.getEventTable(trace, parent, cacheSize); + if (table != null) { + /* + * The trace type specified an event table type, we will give it to + * them. + */ + return table; + } + + /* + * The trace type did not specify an event table, we will use a default + * table with the columns it asked for (if any). + */ + Collection columns = TmfTraceTypeUIUtils.getEventTableColumns(trace); + if (columns != null) { + return new TmfEventsTable(parent, cacheSize, columns); + } + + /* + * No columns were defined either, use a default table with the default + * columns. + */ + return new TmfEventsTable(parent, cacheSize); + + } + + /** + * Get the events table for an experiment. If all traces in the experiment + * are of the same type, use the same behavior as if it was one trace of + * that type. + * + * @param experiment + * the experiment + * @param parent + * the parent Composite + * @param cacheSize + * the event table cache size + * @return An event table of the appropriate type + */ + private static @NonNull TmfEventsTable getExperimentEventTable( + final TmfExperiment experiment, final Composite parent, + final int cacheSize) { + + String commonTraceType = getCommonTraceType(experiment); + if (commonTraceType != null) { + /* + * All the traces in this experiment are of the same type, let's + * just use the normal table for that type. + */ + return getEventTable(experiment.getTraces()[0], parent, cacheSize); + } + + /* + * There are different trace types in the experiment, so we are + * definitely using a TmfEventsTable. Aggregate the columns from all + * trace types. + */ + ITmfTrace[] traces = experiment.getTraces(); + Set cols = new LinkedHashSet<>(); + + for (ITmfTrace trace : traces) { + Collection traceCols = + TmfTraceTypeUIUtils.getEventTableColumns(trace); + if (traceCols == null) { + cols.addAll(TmfEventsTable.DEFAULT_COLUMNS); + } else { + cols.addAll(traceCols); + } + } + + return new TmfEventsTable(parent, cacheSize, cols); + } + + /** + * Check if an experiment contains traces of all the same type. If so, + * returns this type as a String. If not, returns null. + * + * @param experiment + * The experiment + * @return The common trace type if there is one, or 'null' if there are + * different types. + */ + private static @Nullable String getCommonTraceType(TmfExperiment experiment) { + String commonTraceType = null; + try { + for (final ITmfTrace trace : experiment.getTraces()) { + final IResource resource = trace.getResource(); + if (resource == null) { + return null; + } + + final String traceType = resource.getPersistentProperty(TmfCommonConstants.TRACETYPE); + if ((commonTraceType != null) && !commonTraceType.equals(traceType)) { + return null; + } + commonTraceType = traceType; + } + } catch (CoreException e) { + /* + * One of the traces didn't advertise its type, we can't infer + * anything. + */ + return null; + } + return commonTraceType; + } + + @Override + public ITmfTrace getTrace() { + return fTrace; + } + + @Override + public void setFocus() { + fEventsTable.setFocus(); + } + + @Override + public Object getAdapter(final Class adapter) { + if (IGotoMarker.class.equals(adapter)) { + if (fTrace == null || fEventsTable == null) { + return this; + } + return fEventsTable; + } else if (IPropertySheetPage.class.equals(adapter)) { + return new UnsortedPropertySheetPage(); + } + return super.getAdapter(adapter); + } + + /** + * @since 2.1 + */ + @Override + public void gotoMarker(IMarker marker) { + if (fTrace == null || fEventsTable == null) { + fPendingGotoMarker = marker; + } else { + fEventsTable.gotoMarker(marker); + } + } + + @Override + public void resourceChanged(final IResourceChangeEvent event) { + for (final IMarkerDelta delta : event.findMarkerDeltas(IMarker.BOOKMARK, false)) { + if (delta.getResource().equals(fFile)) { + if (delta.getKind() == IResourceDelta.REMOVED) { + final IMarker bookmark = delta.getMarker(); + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + fEventsTable.removeBookmark(bookmark); + } + }); + } else if (delta.getKind() == IResourceDelta.CHANGED) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + fEventsTable.getTable().refresh(); + } + }); + } + } + } + } + + // ------------------------------------------------------------------------ + // ISelectionProvider + // ------------------------------------------------------------------------ + + /** + * @since 2.0 + */ + @Override + public void addSelectionChangedListener(ISelectionChangedListener listener) { + fSelectionChangedListeners.add(listener); + } + + /** + * @since 2.0 + */ + @Override + public ISelection getSelection() { + if (fEventsTable == null) { + return StructuredSelection.EMPTY; + } + return fEventsTable.getSelection(); + } + + /** + * @since 2.0 + */ + @Override + public void removeSelectionChangedListener(ISelectionChangedListener listener) { + fSelectionChangedListeners.remove(listener); + } + + /** + * @since 2.0 + */ + @Override + public void setSelection(ISelection selection) { + // not implemented + } + + /** + * Notifies any selection changed listeners that the viewer's selection has changed. + * Only listeners registered at the time this method is called are notified. + * + * @param event a selection changed event + * + * @see ISelectionChangedListener#selectionChanged + * @since 2.0 + */ + protected void fireSelectionChanged(final SelectionChangedEvent event) { + Object[] listeners = fSelectionChangedListeners.getListeners(); + for (int i = 0; i < listeners.length; ++i) { + final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i]; + SafeRunnable.run(new SafeRunnable() { + @Override + public void run() { + l.selectionChanged(event); + } + }); + } + } + + // ------------------------------------------------------------------------ + // ISelectionChangedListener + // ------------------------------------------------------------------------ + + /** + * @since 2.0 + */ + @Override + public void selectionChanged(SelectionChangedEvent event) { + fireSelectionChanged(event); + } + + // ------------------------------------------------------------------------ + // IPartListener + // ------------------------------------------------------------------------ + + /** + * @since 2.0 + */ + @Override + public void partActivated(IWorkbenchPart part) { + if (part == this && fTrace != null) { + if (fTraceSelected) { + return; + } + fTraceSelected = true; + broadcast(new TmfTraceSelectedSignal(this, fTrace)); + } + } + + /** + * @since 2.0 + */ + @Override + public void partBroughtToTop(IWorkbenchPart part) { + if (part == this && fTrace != null) { + if (fTraceSelected) { + return; + } + fTraceSelected = true; + broadcast(new TmfTraceSelectedSignal(this, fTrace)); + } + } + + /** + * @since 2.0 + */ + @Override + public void partClosed(IWorkbenchPart part) { + } + + /** + * @since 2.0 + */ + @Override + public void partDeactivated(IWorkbenchPart part) { + } + + /** + * @since 2.0 + */ + @Override + public void partOpened(IWorkbenchPart part) { + } + + // ------------------------------------------------------------------------ + // Global commands + // ------------------------------------------------------------------------ + + /** + * Add a bookmark + */ + public void addBookmark() { + fEventsTable.addBookmark(fFile); + } + + + // ------------------------------------------------------------------------ + // Signal handlers + // ------------------------------------------------------------------------ + + /** + * Handler for the Trace Selected signal + * + * @param signal The incoming signal + */ + @TmfSignalHandler + public void traceSelected(final TmfTraceSelectedSignal signal) { + if ((signal.getSource() != this)) { + if (signal.getTrace().equals(fTrace)) { + getSite().getPage().bringToTop(this); + } else { + fTraceSelected = false; + } + } + } + + /** + * Update the display to use the updated timestamp format + * + * @param signal the incoming signal + * @since 2.0 + */ + @TmfSignalHandler + public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) { + if (fEventsTable != null) { + fEventsTable.refresh(); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/TmfMultiPageEditorPart.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/TmfMultiPageEditorPart.java new file mode 100644 index 0000000000..57f17191ee --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/TmfMultiPageEditorPart.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.editors; + +import org.eclipse.tracecompass.tmf.core.component.ITmfComponent; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.ui.part.MultiPageEditorPart; + +/** + * Multi-page editor part abstract class for use in TMF. + * + * @version 1.0 + * @author Patrick Tasse + */ +public abstract class TmfMultiPageEditorPart extends MultiPageEditorPart implements ITmfComponent { + + private final String fName; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + public TmfMultiPageEditorPart() { + super(); + fName = "TmfMultiPageEditorPart"; //$NON-NLS-1$ + TmfSignalManager.register(this); + } + + @Override + public void dispose() { + TmfSignalManager.deregister(this); + super.dispose(); + } + + // ------------------------------------------------------------------------ + // ITmfComponent + // ------------------------------------------------------------------------ + + @Override + public String getName() { + return fName; + } + + @Override + public void broadcast(TmfSignal signal) { + TmfSignalManager.dispatchSignal(signal); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/UnsortedPropertySheetPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/UnsortedPropertySheetPage.java new file mode 100644 index 0000000000..9a1d81b075 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/editors/UnsortedPropertySheetPage.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.editors; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.views.properties.IPropertySheetEntry; +import org.eclipse.ui.views.properties.PropertySheetPage; +import org.eclipse.ui.views.properties.PropertySheetSorter; + +/** + * Property sheet page with empty sorter + * + * @version 1.0 + * @author Patrick Tasse + * @since 2.0 + */ +public class UnsortedPropertySheetPage extends PropertySheetPage { + + @Override + public void createControl(Composite parent) { + super.createControl(parent); + // Override for unsorted property sheet page + // See bug 1883 comment 43 and bug 109617 + setSorter(new PropertySheetSorter() { + @Override + public void sort(IPropertySheetEntry[] entries) { + } + }); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/ITmfProjectModelElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/ITmfProjectModelElement.java new file mode 100644 index 0000000000..7de90b6d37 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/ITmfProjectModelElement.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import java.net.URI; +import java.util.List; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; + +/** + * The TMF project model interface. + * + * The TMF tracing project is integrated in the Common Navigator framework. + * Each tracing tree element has to implement this interface to be visible in the + * Project Explorer. + * + * @version 1.0 + * @author Francois Chouinard + */ +public interface ITmfProjectModelElement { + + /** + * Returns the name of the project model element. + * @return the name of the project element. + */ + String getName(); + /** + * Returns the resource associated with the project model element. + * @return the model resource. + */ + IResource getResource(); + /** + * Returns the path of the project model resource. + * @return the resource path. + */ + IPath getPath(); + /** + * Returns the URI (location) of the resource. + * @return the resource URI. + */ + URI getLocation(); + /** + * Returns the project model element. + * @return the project model element. + */ + TmfProjectElement getProject(); + /** + * Returns the parent of this model element. + * @return the parent of this model element. + */ + ITmfProjectModelElement getParent(); + /** + * Returns whether this model element has children or not. + * @return true if this model has children else false + */ + boolean hasChildren(); + /** + * Returns a list of children model elements. + * @return a list of children model elements. + */ + List getChildren(); + /** + * Method to add a child to the model element. + * @param child A child element to add. + */ + void addChild(ITmfProjectModelElement child); + /** + * Method to remove a child from the model element. + * @param child A child element to remove + */ + void removeChild(ITmfProjectModelElement child); + /** + * Method to request to refresh the project. + */ + void refresh(); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/ITmfStyledProjectModelElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/ITmfStyledProjectModelElement.java new file mode 100644 index 0000000000..1c74bf3638 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/ITmfStyledProjectModelElement.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jface.viewers.StyledString.Styler; + +/** + * This interface can be implemented by elements to a style to their text. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public interface ITmfStyledProjectModelElement { + + /** + * Return the styler who will apply its style to the text string. + * + * @return The style object, or 'null' for no special style + */ + @Nullable + Styler getStyler(); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/Messages.java new file mode 100644 index 0000000000..f8aa3aa0d1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/Messages.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jean-Christian Kouamé - Initial API and implementation + * Patrick Tasse - Add support for source location + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import org.eclipse.osgi.util.NLS; + +/** + * Message strings for TMF model handling. + * + * @author Jean-Christian Kouamé + * @since 2.1 + */ +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.ui.project.model.messages"; //$NON-NLS-1$ + + /** Instantiate analysis message box title + * @since 3.0*/ + public static String TmfAnalysisElement_InstantiateAnalysis; + + /** The message when analysis view is not available + * @since 3.0*/ + public static String TmfAnalysisViewOutput_ViewUnavailable; + /** Analysis view title + * @since 3.0 */ + public static String TmfAnalysisViewOutput_Title; + + /** Error message when closing editor + * @since 3.0 */ + public static String TmfCommonProjectElement_ErrorClosingEditor; + + /** Error message when refreshing persistent property + * @since 3.0 */ + public static String TmfCommonProjectElement_ErrorRefreshingProperty; + + /** Error message when instantiating trace + * @since 3.0 */ + public static String TmfExperimentElement_ErrorInstantiatingTrace; + /** Experiment text + * @since 3.0*/ + public static String TmfExperimentElement_TypeName; + + /** The category of the resource properties */ + public static String TmfTraceElement_ResourceProperties; + + /** The category of the trace properties */ + public static String TmfTraceElement_TraceProperties; + + /** The descriptor for the name property */ + public static String TmfTraceElement_Name; + + /** The descriptor for the path property */ + public static String TmfTraceElement_Path; + + /** The descriptor for the location properties */ + public static String TmfTraceElement_Location; + + /** The descriptor for the event type property */ + public static String TmfTraceElement_EventType; + + /** The descriptor for the linked property */ + public static String TmfTraceElement_IsLinked; + + /** The descriptor for the source location property + * @since 3.0*/ + public static String TmfTraceElement_SourceLocation; + + /** The descriptor for the time offset property + * @since 3.2*/ + public static String TmfTraceElement_TimeOffset; + + /** The descriptor for the last modified property + * @since 3.2 */ + public static String TmfTraceElement_LastModified; + + /** The descriptor for the size property + * @since 3.2 */ + public static String TmfTraceElement_Size; + + /** The format string for the size property of a file + * @since 3.2 */ + public static String TmfTraceElement_FileSizeString; + + /** The format string for the size property of a folder + * @since 3.2 */ + public static String TmfTraceElement_FolderSizeString; + + /** The format string for the size property of a folder with too many members + * @since 3.2 */ + public static String TmfTraceElement_FolderSizeOverflowString; + + /** Trace text + * @since 3.0*/ + public static String TmfTraceElement_TypeName; + /** + * The title for the select trace type dialog + * @since 2.2 + * */ + public static String TmfTraceType_SelectTraceType; + + /** Error opening a trace or experiment + * @since 3.0*/ + public static String TmfOpenTraceHelper_ErrorOpeningElement; + /** Could not link trace */ + public static String TmfOpenTraceHelper_LinkFailed; + /** No trace type match */ + public static String TmfOpenTraceHelper_NoTraceTypeMatch; + /** Open trace or experiment + * @since 3.0*/ + public static String TmfOpenTraceHelper_OpenElement; + /** Reduce was too efficient, no candidates found! */ + public static String TmfOpenTraceHelper_ReduceError; + /** No trace or experiment type + * @since 3.0*/ + public static String TmfOpenTraceHelper_NoTraceOrExperimentType; + /** No trace type */ + public static String TmfOpenTraceHelper_NoTraceType; + /** Error opening trace or experiment + * @since 3.0*/ + public static String TmfOpenTraceHelper_ErrorElement; + /** Init error */ + public static String TmfOpenTraceHelper_InitError; + /** Trace not found + * @since 3.0*/ + public static String TmfOpenTraceHelper_TraceNotFound; + + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfAnalysisElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfAnalysisElement.java new file mode 100644 index 0000000000..16c2dccc77 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfAnalysisElement.java @@ -0,0 +1,254 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + * Patrick Tasse - Add support for folder elements + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.viewers.StyledString.Styler; +import org.eclipse.swt.graphics.TextStyle; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisOutput; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.osgi.framework.Bundle; + +/** + * Class for project elements of type analysis modules + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfAnalysisElement extends TmfProjectModelElement implements ITmfStyledProjectModelElement { + + private static final Styler ANALYSIS_CANT_EXECUTE_STYLER = new Styler() { + @Override + public void applyStyles(TextStyle textStyle) { + textStyle.strikeout = true; + } + }; + + private final String fAnalysisId; + private boolean fCanExecute = true; + + /** + * Constructor + * + * @param name + * Name of the analysis + * @param resource + * The resource + * @param parent + * Parent of the analysis + * @param id + * The analysis module id + */ + protected TmfAnalysisElement(String name, IResource resource, ITmfProjectModelElement parent, String id) { + super(name, resource, parent); + fAnalysisId = id; + parent.addChild(this); + } + + // ------------------------------------------------------------------------ + // TmfProjectModelElement + // ------------------------------------------------------------------------ + + @Override + void refreshChildren() { + fCanExecute = true; + + /* Refresh the outputs of this analysis */ + Map childrenMap = new HashMap<>(); + for (TmfAnalysisOutputElement output : getAvailableOutputs()) { + childrenMap.put(output.getName(), output); + } + + IAnalysisModuleHelper helper = TmfAnalysisManager.getAnalysisModule(fAnalysisId); + if (helper == null) { + deleteOutputs(); + return; + } + + /** Get base path for resource */ + IPath path = getProject().getTracesFolder().getPath(); + if (fResource instanceof IFolder) { + path = ((IFolder) fResource).getFullPath(); + } + + /* + * We can get a list of available outputs once the analysis is + * instantiated when the trace is opened + */ + ITmfProjectModelElement parent = getParent(); + if (parent instanceof TmfCommonProjectElement) { + ITmfTrace trace = ((TmfCommonProjectElement) parent).getTrace(); + if (trace == null) { + deleteOutputs(); + return; + } + + IAnalysisModule module = trace.getAnalysisModule(fAnalysisId); + if (module == null) { + deleteOutputs(); + /* + * Trace is opened, but the analysis is null, so it does not + * apply + */ + fCanExecute = false; + return; + } + + for (IAnalysisOutput output : module.getOutputs()) { + TmfAnalysisOutputElement outputElement = childrenMap.remove(output.getName()); + if (outputElement == null) { + IFolder newresource = ResourcesPlugin.getWorkspace().getRoot().getFolder(path.append(output.getName())); + outputElement = new TmfAnalysisOutputElement(output.getName(), newresource, this, output); + } + outputElement.refreshChildren(); + } + + } + /* Remove outputs that are not children of this analysis anymore */ + for (TmfAnalysisOutputElement output : childrenMap.values()) { + removeChild(output); + } + } + + // ------------------------------------------------------------------------ + // TmfProjectModelElement + // ------------------------------------------------------------------------ + + @Override + public Styler getStyler() { + if (!fCanExecute) { + return ANALYSIS_CANT_EXECUTE_STYLER; + } + return null; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Get the list of analysis output model elements under this analysis + * + * @return Array of analysis output elements + */ + public List getAvailableOutputs() { + List children = getChildren(); + List outputs = new ArrayList<>(); + for (ITmfProjectModelElement child : children) { + if (child instanceof TmfAnalysisOutputElement) { + outputs.add((TmfAnalysisOutputElement) child); + } + } + return outputs; + } + + /** + * Gets the analysis id of this module + * + * @return The analysis id + */ + public String getAnalysisId() { + return fAnalysisId; + } + + /** + * Gets the help message for this analysis + * + * @return The help message + */ + public String getHelpMessage() { + ITmfProjectModelElement parent = getParent(); + + ITmfTrace trace = null; + if (parent instanceof TmfTraceElement) { + TmfTraceElement traceElement = (TmfTraceElement) parent; + trace = traceElement.getTrace(); + if (trace != null) { + IAnalysisModule module = trace.getAnalysisModule(fAnalysisId); + if (module != null) { + return module.getHelpText(trace); + } + } + } + + IAnalysisModuleHelper helper = TmfAnalysisManager.getAnalysisModule(fAnalysisId); + if (helper == null) { + return new String(); + } + + if (trace != null) { + return helper.getHelpText(trace); + } + + return helper.getHelpText(); + } + + /** + * Gets the icon file name for the analysis + * + * @return The analysis icon file name + */ + public String getIconFile() { + IAnalysisModuleHelper helper = TmfAnalysisManager.getAnalysisModule(fAnalysisId); + if (helper == null) { + return null; + } + return helper.getIcon(); + } + + /** + * Gets the bundle this analysis is from + * + * @return The analysis bundle + */ + public Bundle getBundle() { + IAnalysisModuleHelper helper = TmfAnalysisManager.getAnalysisModule(fAnalysisId); + if (helper == null) { + return null; + } + return helper.getBundle(); + } + + /** Delete all outputs under this analysis element */ + private void deleteOutputs() { + for (TmfAnalysisOutputElement output : getAvailableOutputs()) { + removeChild(output); + } + } + + /** + * Make sure the trace this analysis is associated to is the currently + * selected one + */ + public void activateParent() { + ITmfProjectModelElement parent = getParent(); + + if (parent instanceof TmfTraceElement) { + TmfTraceElement traceElement = (TmfTraceElement) parent; + TmfOpenTraceHelper.openTraceFromElement(traceElement); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfAnalysisOutputElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfAnalysisOutputElement.java new file mode 100644 index 0000000000..ae5e1e9a94 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfAnalysisOutputElement.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + * Patrick Tasse - Add support for folder elements + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import org.eclipse.core.resources.IResource; +import org.eclipse.swt.graphics.Image; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisOutput; +import org.eclipse.tracecompass.tmf.ui.analysis.TmfAnalysisViewOutput; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.views.IViewDescriptor; + +/** + * Class for project elements of type analysis output + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfAnalysisOutputElement extends TmfProjectModelElement { + + private final IAnalysisOutput fOutput; + + /** + * Constructor + * + * @param name + * Name of the view + * @param resource + * Resource for the view + * @param parent + * Parent analysis of the view + * @param output + * The output object + */ + protected TmfAnalysisOutputElement(String name, IResource resource, ITmfProjectModelElement parent, IAnalysisOutput output) { + super(name, resource, parent); + fOutput = output; + parent.addChild(this); + } + + /** + * Gets the icon of the view, if applicable + * + * @return The view icon or null if output is not a view + */ + public Image getIcon() { + if (fOutput instanceof TmfAnalysisViewOutput) { + IViewDescriptor descr = PlatformUI.getWorkbench().getViewRegistry().find( + ((TmfAnalysisViewOutput) fOutput).getViewId()); + if (descr != null) { + Activator bundle = Activator.getDefault(); + String key = descr.getId(); + Image icon = bundle.getImageRegistry().get(key); + if (icon == null) { + icon = descr.getImageDescriptor().createImage(); + bundle.getImageRegistry().put(key, icon); + } + return icon; + } + } + return null; + } + + /** + * Outputs the analysis + */ + public void outputAnalysis() { + ITmfProjectModelElement parent = getParent(); + if (parent instanceof TmfAnalysisElement) { + ((TmfAnalysisElement) parent).activateParent(); + fOutput.requestOutput(); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfCommonProjectElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfCommonProjectElement.java new file mode 100644 index 0000000000..d13039780f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfCommonProjectElement.java @@ -0,0 +1,573 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Added supplementary files handling (in class TmfTraceElement) + * Geneviève Bastien - Copied supplementary files handling from TmfTracElement + * Moved to this class code to copy a model element + * Renamed from TmfWithFolderElement to TmfCommonProjectElement + * Patrick Tasse - Add support for folder elements + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.osgi.util.NLS; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper; +import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; +import org.eclipse.tracecompass.tmf.core.trace.TmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.FileEditorInput; + +/** + * Base class for tracing project elements: it implements the common behavior of + * all project elements: supplementary files, analysis, types, etc. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public abstract class TmfCommonProjectElement extends TmfProjectModelElement { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // This trace type ID as defined in plugin.xml + private String fTraceTypeId = null; + + private static final String BOOKMARKS_HIDDEN_FILE = ".bookmarks"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructor. Creates model element. + * + * @param name + * The name of the element + * @param resource + * The resource. + * @param parent + * The parent element + */ + public TmfCommonProjectElement(String name, IResource resource, TmfProjectModelElement parent) { + super(name, resource, parent); + parent.addChild(this); + refreshTraceType(); + TmfSignalManager.register(this); + } + + // ------------------------------------------------------------------------ + // TmfProjectModelElement + // ------------------------------------------------------------------------ + + @Override + void refreshChildren() { + + /* Refreshes the analysis under this trace */ + Map childrenMap = new HashMap<>(); + for (TmfAnalysisElement analysis : getAvailableAnalysis()) { + childrenMap.put(analysis.getAnalysisId(), analysis); + } + + TraceTypeHelper helper = TmfTraceType.getTraceType(getTraceType()); + + Class traceClass = null; + + if (helper != null) { + traceClass = helper.getTraceClass(); + } + + /* Remove all analysis and return */ + if (traceClass == null) { + for (TmfAnalysisElement analysis : childrenMap.values()) { + removeChild(analysis); + } + return; + } + + /** Get the base path to put the resource to */ + IPath path = fResource.getFullPath(); + + /* Add all new analysis modules or refresh outputs of existing ones */ + for (IAnalysisModuleHelper module : TmfAnalysisManager.getAnalysisModules(traceClass).values()) { + + /* If the analysis is not a child of the trace, create it */ + TmfAnalysisElement analysis = childrenMap.remove(module.getId()); + if (analysis == null) { + /** + * No need for the resource to exist, nothing will be done with + * it + */ + IFolder newresource = ResourcesPlugin.getWorkspace().getRoot().getFolder(path.append(module.getId())); + analysis = new TmfAnalysisElement(module.getName(), newresource, this, module.getId()); + } + analysis.refreshChildren(); + } + + /* Remove analysis that are not children of this trace anymore */ + for (TmfAnalysisElement analysis : childrenMap.values()) { + removeChild(analysis); + } + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Returns the trace type ID. + * + * @return trace type ID. + */ + public String getTraceType() { + return fTraceTypeId; + } + + /** + * Refreshes the trace type field by reading the trace type persistent + * property of the resource. + */ + public void refreshTraceType() { + try { + fTraceTypeId = TmfTraceType.getTraceTypeId(getResource()); + } catch (CoreException e) { + Activator.getDefault().logError(NLS.bind(Messages.TmfCommonProjectElement_ErrorRefreshingProperty, getName()), e); + } + } + + /** + * Instantiate a ITmfTrace object based on the trace type and + * the corresponding extension. + * + * @return the ITmfTrace or null for an error + */ + public abstract ITmfTrace instantiateTrace(); + + /** + * Return the supplementary folder path for this element. The returned path + * is relative to the project's supplementary folder. + * + * @return The supplementary folder path for this element + */ + protected String getSupplementaryFolderPath() { + return getElementPath() + getSuffix(); + } + + /** + * Return the element path relative to its common element (traces folder, + * experiments folder or experiment element). + * + * @return The element path + */ + public String getElementPath() { + ITmfProjectModelElement parent = getParent(); + while (!(parent instanceof TmfTracesFolder || parent instanceof TmfExperimentElement || parent instanceof TmfExperimentFolder)) { + parent = parent.getParent(); + } + IPath path = fResource.getFullPath().makeRelativeTo(parent.getPath()); + return path.toString(); + } + + /** + * @return The suffix for the supplementary folder + */ + protected String getSuffix() { + return ""; //$NON-NLS-1$ + } + + /** + * Returns a list of TmfTraceElements contained in project element. + * + * @return a list of TmfTraceElements, empty list if none + */ + public List getTraces() { + return new ArrayList<>(); + } + + /** + * Get the instantiated trace associated with this element. + * + * @return The instantiated trace or null if trace is not (yet) available + */ + public ITmfTrace getTrace() { + for (ITmfTrace trace : TmfTraceManager.getInstance().getOpenedTraces()) { + if (trace.getResource().equals(getResource())) { + return trace; + } + } + return null; + } + + /** + * Returns the file resource used to store bookmarks after creating it if + * necessary. If the trace resource is a file, it is returned directly. If + * the trace resource is a folder, a linked file is returned. The file will + * be created if it does not exist. + * + * @return the bookmarks file + * @throws CoreException + * if the bookmarks file cannot be created + */ + public abstract IFile createBookmarksFile() throws CoreException; + + /** + * Actually returns the bookmark file or creates it in the project element's + * folder + * + * @param bookmarksFolder + * Folder where to put the bookmark file + * @param traceType + * The canonical name to set as tracetype + * @return The bookmark file + * @throws CoreException + * if the bookmarks file cannot be created + */ + protected IFile createBookmarksFile(IFolder bookmarksFolder, String traceType) throws CoreException { + IFile file = getBookmarksFile(); + if (!file.exists()) { + final IFile bookmarksFile = bookmarksFolder.getFile(BOOKMARKS_HIDDEN_FILE); + if (!bookmarksFile.exists()) { + final InputStream source = new ByteArrayInputStream(new byte[0]); + bookmarksFile.create(source, true, null); + } + bookmarksFile.setHidden(true); + file.createLink(bookmarksFile.getLocation(), IResource.REPLACE, null); + file.setHidden(true); + file.setPersistentProperty(TmfCommonConstants.TRACETYPE, traceType); + } + return file; + } + + /** + * Returns the optional editor ID from the trace type extension. + * + * @return the editor ID or null if not defined. + */ + public abstract String getEditorId(); + + /** + * Returns the file resource used to store bookmarks. The file may not + * exist. + * + * @return the bookmarks file + */ + public IFile getBookmarksFile() { + final IFolder folder = (IFolder) fResource; + IFile file = folder.getFile(getName() + '_'); + return file; + } + + /** + * Close open editors associated with this experiment. + */ + public void closeEditors() { + IFile file = getBookmarksFile(); + FileEditorInput input = new FileEditorInput(file); + IWorkbench wb = PlatformUI.getWorkbench(); + for (IWorkbenchWindow wbWindow : wb.getWorkbenchWindows()) { + for (IWorkbenchPage wbPage : wbWindow.getPages()) { + for (IEditorReference editorReference : wbPage.getEditorReferences()) { + try { + if (editorReference.getEditorInput().equals(input)) { + wbPage.closeEditor(editorReference.getEditor(false), false); + } + } catch (PartInitException e) { + Activator.getDefault().logError(NLS.bind(Messages.TmfCommonProjectElement_ErrorClosingEditor, getName()), e); + } + } + } + } + } + + /** + * Get a friendly name for the type of element this common project element + * is, to be displayed in UI messages. + * + * @return A string for the type of project element this object is, for + * example "trace" or "experiment" + */ + public abstract String getTypeName(); + + /** + * Copy this model element + * + * @param newName + * The name of the new element + * @param copySuppFiles + * Whether to copy supplementary files or not + * @return the new Resource object + */ + public IResource copy(final String newName, final boolean copySuppFiles) { + + final IPath newPath = getParent().getResource().getFullPath().addTrailingSeparator().append(newName); + + /* Copy supplementary files first, only if needed */ + if (copySuppFiles) { + String newElementPath = new Path(getElementPath()).removeLastSegments(1).append(newName).toString(); + copySupplementaryFolder(newElementPath); + } + /* Copy the trace */ + try { + getResource().copy(newPath, IResource.FORCE | IResource.SHALLOW, null); + IResource trace = ((IFolder) getParent().getResource()).findMember(newName); + + /* Delete any bookmarks file found in copied trace folder */ + if (trace instanceof IFolder) { + IFolder folderTrace = (IFolder) trace; + for (IResource member : folderTrace.members()) { + String traceTypeId = TmfTraceType.getTraceTypeId(member); + if (TmfTrace.class.getCanonicalName().equals(traceTypeId)) { + member.delete(true, null); + } else if (TmfExperiment.class.getCanonicalName().equals(traceTypeId)) { + member.delete(true, null); + } + } + } + return trace; + } catch (CoreException e) { + + } + return null; + } + + /** + * Get the list of analysis elements + * + * @return Array of analysis elements + */ + public List getAvailableAnalysis() { + List children = getChildren(); + List analysis = new ArrayList<>(); + for (ITmfProjectModelElement child : children) { + if (child instanceof TmfAnalysisElement) { + analysis.add((TmfAnalysisElement) child); + } + } + return analysis; + } + + // ------------------------------------------------------------------------ + // Supplementary files operations + // ------------------------------------------------------------------------ + + /** + * Deletes this element specific supplementary folder. + */ + public void deleteSupplementaryFolder() { + IFolder supplFolder = getTraceSupplementaryFolder(getSupplementaryFolderPath()); + try { + deleteFolder(supplFolder); + } catch (CoreException e) { + Activator.getDefault().logError("Error deleting supplementary folder " + supplFolder, e); //$NON-NLS-1$ + } + } + + private static void deleteFolder(IFolder folder) throws CoreException { + if (folder.exists()) { + folder.delete(true, new NullProgressMonitor()); + } + IContainer parent = folder.getParent(); + // delete empty folders up to the parent project + if (parent instanceof IFolder && (!parent.exists() || parent.members().length == 0)) { + deleteFolder((IFolder) parent); + } + } + + /** + * Renames the element specific supplementary folder according to the new + * element name or path. + * + * @param newElementPath + * The new element name or path + */ + public void renameSupplementaryFolder(String newElementPath) { + IFolder oldSupplFolder = getTraceSupplementaryFolder(getSupplementaryFolderPath()); + + // Rename supplementary folder + try { + if (oldSupplFolder.exists()) { + IFolder newSupplFolder = prepareTraceSupplementaryFolder(newElementPath + getSuffix(), false); + oldSupplFolder.move(newSupplFolder.getFullPath(), true, new NullProgressMonitor()); + } + deleteFolder(oldSupplFolder); + } catch (CoreException e) { + Activator.getDefault().logError("Error renaming supplementary folder " + oldSupplFolder, e); //$NON-NLS-1$ + } + } + + /** + * Copies the element specific supplementary folder to the new element name + * or path. + * + * @param newElementPath + * The new element name or path + */ + public void copySupplementaryFolder(String newElementPath) { + IFolder oldSupplFolder = getTraceSupplementaryFolder(getSupplementaryFolderPath()); + + // copy supplementary folder + if (oldSupplFolder.exists()) { + try { + IFolder newSupplFolder = prepareTraceSupplementaryFolder(newElementPath + getSuffix(), false); + oldSupplFolder.copy(newSupplFolder.getFullPath(), true, new NullProgressMonitor()); + } catch (CoreException e) { + Activator.getDefault().logError("Error renaming supplementary folder " + oldSupplFolder, e); //$NON-NLS-1$ + } + } + } + + /** + * Copies the element specific supplementary folder a new folder. + * + * @param destination + * The destination folder to copy to. + */ + public void copySupplementaryFolder(IFolder destination) { + IFolder oldSupplFolder = getTraceSupplementaryFolder(getSupplementaryFolderPath()); + + // copy supplementary folder + if (oldSupplFolder.exists()) { + try { + TraceUtils.createFolder((IFolder) destination.getParent(), new NullProgressMonitor()); + oldSupplFolder.copy(destination.getFullPath(), true, new NullProgressMonitor()); + } catch (CoreException e) { + Activator.getDefault().logError("Error copying supplementary folder " + oldSupplFolder, e); //$NON-NLS-1$ + } + } + } + + /** + * Refreshes the element specific supplementary folder information. It + * creates the folder if not exists. It sets the persistence property of the + * trace resource + */ + public void refreshSupplementaryFolder() { + IFolder supplFolder = createSupplementaryFolder(); + try { + supplFolder.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); + } catch (CoreException e) { + Activator.getDefault().logError("Error refreshing supplementary folder " + supplFolder, e); //$NON-NLS-1$ + } + } + + /** + * Checks if supplementary resource exist or not. + * + * @return true if one or more files are under the element + * supplementary folder + */ + public boolean hasSupplementaryResources() { + IResource[] resources = getSupplementaryResources(); + return (resources.length > 0); + } + + /** + * Returns the supplementary resources under the trace supplementary folder. + * + * @return array of resources under the trace supplementary folder. + */ + public IResource[] getSupplementaryResources() { + IFolder supplFolder = getTraceSupplementaryFolder(getSupplementaryFolderPath()); + if (supplFolder.exists()) { + try { + return supplFolder.members(); + } catch (CoreException e) { + Activator.getDefault().logError("Error deleting supplementary folder " + supplFolder, e); //$NON-NLS-1$ + } + } + return new IResource[0]; + } + + /** + * Deletes the given resources. + * + * @param resources + * array of resources to delete. + */ + public void deleteSupplementaryResources(IResource[] resources) { + + for (int i = 0; i < resources.length; i++) { + try { + resources[i].delete(true, new NullProgressMonitor()); + } catch (CoreException e) { + Activator.getDefault().logError("Error deleting supplementary resource " + resources[i], e); //$NON-NLS-1$ + } + } + } + + /** + * Deletes all supplementary resources in the supplementary directory + */ + public void deleteSupplementaryResources() { + deleteSupplementaryResources(getSupplementaryResources()); + } + + private IFolder createSupplementaryFolder() { + IFolder supplFolder = prepareTraceSupplementaryFolder(getSupplementaryFolderPath(), true); + + try { + fResource.setPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER, supplFolder.getLocationURI().getPath()); + } catch (CoreException e) { + Activator.getDefault().logError("Error setting persistant property " + TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER, e); //$NON-NLS-1$ + } + return supplFolder; + } + + // ------------------------------------------------------- + // Signal handlers + // ------------------------------------------------------- + + /** + * Handler for the Trace Opened signal + * + * @param signal + * The incoming signal + */ + @TmfSignalHandler + public void traceOpened(TmfTraceOpenedSignal signal) { + IResource resource = signal.getTrace().getResource(); + if ((resource == null) || !resource.equals(getResource())) { + return; + } + + getParent().refresh(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfExperimentElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfExperimentElement.java new file mode 100644 index 0000000000..4944a8040e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfExperimentElement.java @@ -0,0 +1,478 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Geneviève Bastien - Copied code to add/remove traces in this class + * Patrick Tasse - Close editors to release resources + * Geneviève Bastien - Experiment instantiated with trace type + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceProxy; +import org.eclipse.core.resources.IResourceProxyVisitor; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.InvalidRegistryObjectException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Platform; +import org.eclipse.osgi.util.NLS; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; +import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor; +import org.eclipse.tracecompass.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; +import org.eclipse.ui.views.properties.IPropertyDescriptor; +import org.eclipse.ui.views.properties.IPropertySource2; + +/** + * Implementation of TMF Experiment Model Element. + *

    + * @version 1.0 + * @author Francois Chouinard + * + */ +public class TmfExperimentElement extends TmfCommonProjectElement implements IPropertySource2 { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + // Property View stuff + private static final String sfInfoCategory = "Info"; //$NON-NLS-1$ + private static final String sfName = "name"; //$NON-NLS-1$ + private static final String sfPath = "path"; //$NON-NLS-1$ + private static final String sfLocation = "location"; //$NON-NLS-1$ + private static final String sfFolderSuffix = "_exp"; //$NON-NLS-1$ + private static final String sfExperimentType = "type"; //$NON-NLS-1$ + + private static final ReadOnlyTextPropertyDescriptor sfNameDescriptor = new ReadOnlyTextPropertyDescriptor(sfName, sfName); + private static final ReadOnlyTextPropertyDescriptor sfPathDescriptor = new ReadOnlyTextPropertyDescriptor(sfPath, sfPath); + private static final ReadOnlyTextPropertyDescriptor sfLocationDescriptor = new ReadOnlyTextPropertyDescriptor(sfLocation, + sfLocation); + private static final ReadOnlyTextPropertyDescriptor sfTypeDescriptor = new ReadOnlyTextPropertyDescriptor(sfExperimentType, sfExperimentType); + + private static final IPropertyDescriptor[] sfDescriptors = { sfNameDescriptor, sfPathDescriptor, + sfLocationDescriptor, sfTypeDescriptor }; + + static { + sfNameDescriptor.setCategory(sfInfoCategory); + sfPathDescriptor.setCategory(sfInfoCategory); + sfLocationDescriptor.setCategory(sfInfoCategory); + sfTypeDescriptor.setCategory(sfInfoCategory); + } + + // The mapping of available trace type IDs to their corresponding + // configuration element + private static final Map sfTraceTypeAttributes = new HashMap<>(); + private static final Map sfTraceTypeUIAttributes = new HashMap<>(); + private static final Map sfTraceCategories = new HashMap<>(); + + // ------------------------------------------------------------------------ + // Static initialization + // ------------------------------------------------------------------------ + + /** + * Initialize statically at startup by getting extensions from the platform + * extension registry. + * @since 3.0 + */ + public static void init() { + IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType.TMF_TRACE_TYPE_ID); + for (IConfigurationElement ce : config) { + String elementName = ce.getName(); + if (elementName.equals(TmfTraceType.EXPERIMENT_ELEM)) { + String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR); + sfTraceTypeAttributes.put(traceTypeId, ce); + } else if (elementName.equals(TmfTraceType.CATEGORY_ELEM)) { + String categoryId = ce.getAttribute(TmfTraceType.ID_ATTR); + sfTraceCategories.put(categoryId, ce); + } + } + + /* + * Read the corresponding tmf.ui "tracetypeui" extension point for this + * trace type, if it exists. + */ + config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceTypeUIUtils.TMF_TRACE_TYPE_UI_ID); + for (IConfigurationElement ce : config) { + String elemName = ce.getName(); + if (TmfTraceTypeUIUtils.EXPERIMENT_ELEM.equals(elemName)) { + String traceType = ce.getAttribute(TmfTraceTypeUIUtils.TRACETYPE_ATTR); + sfTraceTypeUIAttributes.put(traceType, ce); + } + } + } + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Constructor + * @param name The name of the experiment + * @param folder The folder reference + * @param parent The experiment folder reference. + */ + public TmfExperimentElement(String name, IFolder folder, TmfExperimentFolder parent) { + super(name, folder, parent); + } + + // ------------------------------------------------------------------------ + // TmfProjectModelElement + // ------------------------------------------------------------------------ + + @Override + public IFolder getResource() { + return (IFolder) fResource; + } + + @Override + void refreshChildren() { + IFolder folder = getResource(); + + /* Update the trace children of this experiment */ + // Get the children from the model + Map childrenMap = new HashMap<>(); + for (TmfTraceElement trace : getTraces()) { + childrenMap.put(trace.getElementPath(), trace); + } + + List members = getTraceResources(); + for (IResource resource : members) { + String name = resource.getName(); + String elementPath = resource.getFullPath().makeRelativeTo(folder.getFullPath()).toString(); + ITmfProjectModelElement element = childrenMap.get(elementPath); + if (element instanceof TmfTraceElement) { + childrenMap.remove(elementPath); + } else { + element = new TmfTraceElement(name, resource, this); + } + } + + // Cleanup dangling children from the model + for (ITmfProjectModelElement danglingChild : childrenMap.values()) { + removeChild(danglingChild); + } + + /* Update the analysis under this experiment */ + super.refreshChildren(); + } + + private List getTraceResources() { + IFolder folder = getResource(); + final List list = new ArrayList<>(); + try { + folder.accept(new IResourceProxyVisitor() { + @Override + public boolean visit(IResourceProxy resource) throws CoreException { + if (resource.isLinked()) { + list.add(resource.requestResource()); + } + return true; + } + }, IResource.NONE); + } catch (CoreException e) { + } + return list; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Refreshes the trace type filed by reading the trace type persistent + * property of the resource reference. + * + * If trace type is null after refresh, set it to the generic trace type + * (for seamless upgrade) + */ + @Override + public void refreshTraceType() { + super.refreshTraceType(); + if (getTraceType() == null) { + IConfigurationElement ce = TmfTraceType.getTraceAttributes(TmfTraceType.DEFAULT_EXPERIMENT_TYPE); + if (ce != null) { + try { + IFolder experimentFolder = getResource(); + experimentFolder.setPersistentProperty(TmfCommonConstants.TRACETYPE, ce.getAttribute(TmfTraceType.ID_ATTR)); + super.refreshTraceType(); + } catch (InvalidRegistryObjectException | CoreException e) { + } + } + } + } + + /** + * Returns a list of TmfTraceElements contained in this experiment. + * @return a list of TmfTraceElements + */ + @Override + public List getTraces() { + List children = getChildren(); + List traces = new ArrayList<>(); + for (ITmfProjectModelElement child : children) { + if (child instanceof TmfTraceElement) { + traces.add((TmfTraceElement) child); + } + } + return traces; + } + + /** + * Adds a trace to the experiment + * + * @param trace The trace element to add + * @since 2.0 + */ + public void addTrace(TmfTraceElement trace) { + addTrace(trace, true); + } + + /** + * Adds a trace to the experiment + * + * @param trace The trace element to add + * @param refresh Flag for refreshing the project + * + * @since 3.1 + */ + public void addTrace(TmfTraceElement trace, boolean refresh) { + /** + * Create a link to the actual trace and set the trace type + */ + IFolder experiment = getResource(); + IResource resource = trace.getResource(); + IPath location = resource.getLocation(); + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + try { + String traceTypeId = TmfTraceType.getTraceTypeId(trace.getResource()); + TraceTypeHelper traceType = TmfTraceType.getTraceType(traceTypeId); + + if (resource instanceof IFolder) { + IFolder folder = experiment.getFolder(trace.getElementPath()); + TraceUtils.createFolder((IFolder) folder.getParent(), new NullProgressMonitor()); + IStatus result = workspace.validateLinkLocation(folder, location); + if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) { + folder.createLink(location, IResource.REPLACE, null); + if (traceType != null) { + TmfTraceTypeUIUtils.setTraceType(folder, traceType, refresh); + } + + } else { + Activator.getDefault().logError("Error creating link. Invalid trace location " + location); //$NON-NLS-1$ + } + } else { + IFile file = experiment.getFile(trace.getElementPath()); + TraceUtils.createFolder((IFolder) file.getParent(), new NullProgressMonitor()); + IStatus result = workspace.validateLinkLocation(file, location); + if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) { + file.createLink(location, IResource.REPLACE, null); + if (traceType != null) { + TmfTraceTypeUIUtils.setTraceType(file, traceType, refresh); + } + } else { + Activator.getDefault().logError("Error creating link. Invalid trace location " + location); //$NON-NLS-1$ + } + } + } catch (CoreException e) { + Activator.getDefault().logError("Error creating link to location " + location, e); //$NON-NLS-1$ + } + + } + + /** + * Removes a trace from an experiment + * + * @param trace The trace to remove + * @throws CoreException exception + * @since 2.0 + */ + public void removeTrace(TmfTraceElement trace) throws CoreException { + + // Close the experiment if open + closeEditors(); + + /* Finally, remove the trace from experiment*/ + removeChild(trace); + deleteTraceResource(trace.getResource()); + deleteSupplementaryResources(); + } + + private void deleteTraceResource(IResource resource) throws CoreException { + resource.delete(true, null); + IContainer parent = resource.getParent(); + // delete empty folders up to the parent experiment folder + if (!parent.equals(getResource()) && parent.members().length == 0) { + deleteTraceResource(parent); + } + } + + @Override + public IFile createBookmarksFile() throws CoreException { + return createBookmarksFile(getProject().getExperimentsFolder().getResource(), TmfExperiment.class.getCanonicalName()); + } + + @Override + public String getEditorId() { + /* See if a default editor was set for this experiment type */ + if (getTraceType() != null) { + IConfigurationElement ce = sfTraceTypeUIAttributes.get(getTraceType()); + if (ce != null) { + IConfigurationElement[] defaultEditorCE = ce.getChildren(TmfTraceTypeUIUtils.DEFAULT_EDITOR_ELEM); + if (defaultEditorCE.length == 1) { + return defaultEditorCE[0].getAttribute(TmfTraceType.ID_ATTR); + } + } + } + + /* No default editor, try to find a common editor for all traces */ + final List traceEntries = getTraces(); + String commonEditorId = null; + + for (TmfTraceElement element : traceEntries) { + // If all traces use the same editorId, use it, otherwise use the + // default + final String editorId = element.getEditorId(); + if (commonEditorId == null) { + commonEditorId = (editorId != null) ? editorId : TmfEventsEditor.ID; + } else if (!commonEditorId.equals(editorId)) { + commonEditorId = TmfEventsEditor.ID; + } + } + return null; + } + + /** + * Instantiate a {@link TmfExperiment} object based on the experiment type + * and the corresponding extension. + * + * @return the {@link TmfExperiment} or null for an error + * @since 3.0 + */ + @Override + public TmfExperiment instantiateTrace() { + try { + + // make sure that supplementary folder exists + refreshSupplementaryFolder(); + + if (getTraceType() != null) { + + IConfigurationElement ce = sfTraceTypeAttributes.get(getTraceType()); + if (ce == null) { + return null; + } + TmfExperiment experiment = (TmfExperiment) ce.createExecutableExtension(TmfTraceType.EXPERIMENT_TYPE_ATTR); + return experiment; + } + } catch (CoreException e) { + Activator.getDefault().logError(NLS.bind(Messages.TmfExperimentElement_ErrorInstantiatingTrace, getName()), e); + } + return null; + } + + @Override + public String getTypeName() { + return Messages.TmfExperimentElement_TypeName; + } + + // ------------------------------------------------------------------------ + // IPropertySource2 + // ------------------------------------------------------------------------ + + @Override + public Object getEditableValue() { + return null; + } + + @Override + public IPropertyDescriptor[] getPropertyDescriptors() { + return Arrays.copyOf(sfDescriptors, sfDescriptors.length); + } + + @Override + public Object getPropertyValue(Object id) { + + if (sfName.equals(id)) { + return getName(); + } + + if (sfPath.equals(id)) { + return getPath().toString(); + } + + if (sfLocation.equals(id)) { + return getLocation().toString(); + } + + if (sfExperimentType.equals(id)) { + if (getTraceType() != null) { + IConfigurationElement ce = sfTraceTypeAttributes.get(getTraceType()); + if (ce == null) { + return ""; //$NON-NLS-1$ + } + String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR); + if (categoryId != null) { + IConfigurationElement category = sfTraceCategories.get(categoryId); + if (category != null) { + return category.getAttribute(TmfTraceType.NAME_ATTR) + ':' + ce.getAttribute(TmfTraceType.NAME_ATTR); + } + } + return ce.getAttribute(TmfTraceType.NAME_ATTR); + } + } + + return null; + } + + @Override + public void resetPropertyValue(Object id) { + } + + @Override + public void setPropertyValue(Object id, Object value) { + } + + @Override + public boolean isPropertyResettable(Object id) { + return false; + } + + @Override + public boolean isPropertySet(Object id) { + return false; + } + + /** + * Return the suffix for resource names + * @return The folder suffix + */ + @Override + public String getSuffix() { + return sfFolderSuffix; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfExperimentFolder.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfExperimentFolder.java new file mode 100644 index 0000000000..5e0486441c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfExperimentFolder.java @@ -0,0 +1,196 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Add support for folder elements + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.tracecompass.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; +import org.eclipse.ui.views.properties.IPropertyDescriptor; +import org.eclipse.ui.views.properties.IPropertySource2; + +/** + * Implementation of model element representing the unique "Experiments" folder + * in the project. + *

    + * + * @version 1.0 + * @author Francois Chouinard + * + */ +public class TmfExperimentFolder extends TmfProjectModelElement implements IPropertySource2 { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The name of the experiment folder. + */ + public static final String EXPER_FOLDER_NAME = "Experiments"; //$NON-NLS-1$ + + // Property View stuff + private static final String sfInfoCategory = "Info"; //$NON-NLS-1$ + private static final String sfName = "name"; //$NON-NLS-1$ + private static final String sfPath = "path"; //$NON-NLS-1$ + private static final String sfLocation = "location"; //$NON-NLS-1$ + + private static final ReadOnlyTextPropertyDescriptor sfNameDescriptor = new ReadOnlyTextPropertyDescriptor(sfName, sfName); + private static final ReadOnlyTextPropertyDescriptor sfPathDescriptor = new ReadOnlyTextPropertyDescriptor(sfPath, sfPath); + private static final ReadOnlyTextPropertyDescriptor sfLocationDescriptor = new ReadOnlyTextPropertyDescriptor(sfLocation, sfLocation); + + private static final IPropertyDescriptor[] sfDescriptors = { sfNameDescriptor, sfPathDescriptor, sfLocationDescriptor }; + + static { + sfNameDescriptor.setCategory(sfInfoCategory); + sfPathDescriptor.setCategory(sfInfoCategory); + sfLocationDescriptor.setCategory(sfInfoCategory); + } + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructor. + * Creates a TmfExperimentFolder model element. + * @param name The name of the folder + * @param folder The folder reference + * @param parent The parent (project element) + */ + public TmfExperimentFolder(String name, IFolder folder, TmfProjectElement parent) { + super(name, folder, parent); + parent.addChild(this); + } + + // ------------------------------------------------------------------------ + // TmfProjectModelElement + // ------------------------------------------------------------------------ + + @Override + public IFolder getResource() { + return (IFolder) fResource; + } + + @Override + void refreshChildren() { + IFolder folder = getResource(); + + // Get the children from the model + Map childrenMap = new HashMap<>(); + for (ITmfProjectModelElement element : getChildren()) { + childrenMap.put(element.getResource().getName(), element); + } + + try { + IResource[] members = folder.members(); + for (IResource resource : members) { + if (resource instanceof IFolder) { + IFolder expFolder = (IFolder) resource; + String name = resource.getName(); + ITmfProjectModelElement element = childrenMap.get(name); + if (element instanceof TmfExperimentElement) { + childrenMap.remove(name); + } else { + element = new TmfExperimentElement(name, expFolder, this); + } + ((TmfExperimentElement) element).refreshChildren(); + } + } + } catch (CoreException e) { + } + + // Cleanup dangling children from the model + for (ITmfProjectModelElement danglingChild : childrenMap.values()) { + removeChild(danglingChild); + } + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Returns a list of experiment model elements under the experiments folder. + * @return list of experiment model elements + * @since 3.0 + */ + public List getExperiments() { + List children = getChildren(); + List traces = new ArrayList<>(); + for (ITmfProjectModelElement child : children) { + if (child instanceof TmfExperimentElement) { + traces.add((TmfExperimentElement) child); + } + } + return traces; + } + + // ------------------------------------------------------------------------ + // IPropertySource2 + // ------------------------------------------------------------------------ + + @Override + public Object getEditableValue() { + return null; + } + + @Override + public IPropertyDescriptor[] getPropertyDescriptors() { + return Arrays.copyOf(sfDescriptors, sfDescriptors.length); + } + + @Override + public Object getPropertyValue(Object id) { + + if (sfName.equals(id)) { + return getName(); + } + + if (sfPath.equals(id)) { + return getPath().toString(); + } + + if (sfLocation.equals(id)) { + return getLocation().toString(); + } + + return null; + } + + @Override + public void resetPropertyValue(Object id) { + } + + @Override + public void setPropertyValue(Object id, Object value) { + } + + @Override + public boolean isPropertyResettable(Object id) { + return false; + } + + @Override + public boolean isPropertySet(Object id) { + return false; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfNavigatorContentProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfNavigatorContentProvider.java new file mode 100644 index 0000000000..e4b1b71d75 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfNavigatorContentProvider.java @@ -0,0 +1,193 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Implement getParent() + * Patrick Tasse - Add support for folder elements + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import java.util.Set; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.navigator.ICommonContentExtensionSite; +import org.eclipse.ui.navigator.IPipelinedTreeContentProvider; +import org.eclipse.ui.navigator.PipelinedShapeModification; +import org.eclipse.ui.navigator.PipelinedViewerUpdate; + +/** + * The TMF project content provider for the tree viewer in the project explorer view. + *

    + * @version 1.0 + * @author Francois Chouinard + */ +public class TmfNavigatorContentProvider implements IPipelinedTreeContentProvider { + + // ------------------------------------------------------------------------ + // ICommonContentProvider + // ------------------------------------------------------------------------ + + @Override + public Object[] getElements(Object inputElement) { + return null; + } + + @Override + public Object getParent(Object element) { + if (element instanceof IProject) { + IProject project = (IProject) element; + return project.getParent(); + } + + if (element instanceof TmfTracesFolder) { + TmfTracesFolder folder = (TmfTracesFolder) element; + // Return the corresponding IProject as parent because from CNF point of view the IProject is the parent. + // The IProject is needed e.g. for link with Editor to work correctly. + return folder.getParent().getResource(); + } + + if (element instanceof TmfExperimentFolder) { + TmfExperimentFolder folder = (TmfExperimentFolder) element; + // Return the corresponding IProject as parent because from CNF point of view the IProject is the parent. + // The IProject is needed e.g. for link with Editor to work correctly. + return folder.getParent().getResource(); + } + + if (element instanceof ITmfProjectModelElement) { + ITmfProjectModelElement modelElement = (ITmfProjectModelElement) element; + return modelElement.getParent(); + } + + return null; + } + + @Override + public boolean hasChildren(Object element) { + if (element instanceof IProject) { + IProject project = (IProject) element; + return project.isAccessible(); + } + if (element instanceof ITmfProjectModelElement) { + ITmfProjectModelElement modelElement = (ITmfProjectModelElement) element; + return modelElement.hasChildren(); + } + return false; + } + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + @Override + public void restoreState(IMemento aMemento) { + } + + @Override + public void saveState(IMemento aMemento) { + } + + @Override + public void init(ICommonContentExtensionSite aConfig) { + } + + // ------------------------------------------------------------------------ + // ICommonContentProvider - getChildren() + // ------------------------------------------------------------------------ + + @Override + public synchronized Object[] getChildren(Object parentElement) { + + // Tracing project level + if (parentElement instanceof IProject) { + TmfProjectElement element = TmfProjectRegistry.getProject((IProject) parentElement, true); + return element.getChildren().toArray(); + } + + // Other project model elements + if (parentElement instanceof ITmfProjectModelElement) { + return ((ITmfProjectModelElement) parentElement).getChildren().toArray(); + } + + return new Object[0]; + } + + // ------------------------------------------------------------------------ + // IPipelinedTreeContentProvider + // ------------------------------------------------------------------------ + + @Override + public void getPipelinedChildren(Object parent, Set currentChildren) { + customizeTmfElements(getChildren(parent), currentChildren); + } + + @Override + public void getPipelinedElements(Object input, Set currentElements) { + customizeTmfElements(getElements(input), currentElements); + } + + /** + * Add/replace the ITmfProjectElement to the list of children + * + * @param elements + * the list returned by getChildren() + * @param children + * the current children + */ + private static void customizeTmfElements(Object[] elements, + Set children) { + if (elements != null && children != null) { + for (Object element : elements) { + if (element instanceof ITmfProjectModelElement) { + ITmfProjectModelElement tmfElement = (ITmfProjectModelElement) element; + IResource resource = tmfElement.getResource(); + if (resource != null) { + children.remove(resource); + } + children.add(element); + } + else if (element != null) { + children.add(element); + } + } + } + } + + @Override + public Object getPipelinedParent(Object anObject, Object aSuggestedParent) { + return aSuggestedParent; + } + + @Override + public PipelinedShapeModification interceptAdd(PipelinedShapeModification anAddModification) { + return anAddModification; + } + + @Override + public PipelinedShapeModification interceptRemove(PipelinedShapeModification aRemoveModification) { + return null; + } + + @Override + public boolean interceptRefresh(PipelinedViewerUpdate aRefreshSynchronization) { + return false; + } + + @Override + public boolean interceptUpdate(PipelinedViewerUpdate anUpdateSynchronization) { + return false; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfNavigatorLabelProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfNavigatorLabelProvider.java new file mode 100644 index 0000000000..9e15e38b12 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfNavigatorLabelProvider.java @@ -0,0 +1,267 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Add support for unknown trace type icon + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import java.net.URL; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.StyledString; +import org.eclipse.jface.viewers.StyledString.Styler; +import org.eclipse.swt.graphics.Image; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType.TraceElementType; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.model.WorkbenchLabelProvider; +import org.eclipse.ui.navigator.ICommonContentExtensionSite; +import org.eclipse.ui.navigator.ICommonLabelProvider; +import org.osgi.framework.Bundle; + +/** + * The TMF project label provider for the tree viewer in the project explorer view. + *

    + * @version 1.0 + * @author Francois Chouinard + */ +public class TmfNavigatorLabelProvider implements ICommonLabelProvider, IStyledLabelProvider { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + private static final Image fFolderIcon = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER); + private static final String fTraceIconFile = "icons/elcl16/trace.gif"; //$NON-NLS-1$ + private static final String fExperimentIconFile = "icons/elcl16/experiment.gif"; //$NON-NLS-1$ + private static final String fAnalysisIconFile = "icons/ovr16/experiment_folder_ovr.png"; //$NON-NLS-1$ + private static final String fViewIconFile = "icons/obj16/node_obj.gif"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final Image fTraceFolderIcon = fFolderIcon; + private final Image fExperimentFolderIcon = fFolderIcon; + + private final Image fDefaultTraceIcon; + private final Image fExperimentIcon; + private final Image fDefaultAnalysisIcon; + private final Image fDefaultViewIcon; + + private final WorkbenchLabelProvider fWorkspaceLabelProvider = new WorkbenchLabelProvider(); + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructor. + * + * Creates the TMF navigator content provider. + */ + public TmfNavigatorLabelProvider() { + Bundle bundle = Activator.getDefault().getBundle(); + fDefaultTraceIcon = loadIcon(bundle, fTraceIconFile); + fExperimentIcon = loadIcon(bundle, fExperimentIconFile); + fDefaultAnalysisIcon = loadIcon(bundle, fAnalysisIconFile); + fDefaultViewIcon = loadIcon(bundle, fViewIconFile); + } + + private static Image loadIcon(Bundle bundle, String url) { + Activator plugin = Activator.getDefault(); + String key = bundle.getSymbolicName() + "/" + url; //$NON-NLS-1$ + Image icon = plugin.getImageRegistry().get(key); + if (icon == null) { + URL imageURL = bundle.getResource(url); + ImageDescriptor descriptor = ImageDescriptor.createFromURL(imageURL); + if (descriptor != null) { + icon = descriptor.createImage(); + plugin.getImageRegistry().put(key, icon); + } + } + return icon; + } + + // ------------------------------------------------------------------------ + // ICommonLabelProvider + // ------------------------------------------------------------------------ + + @Override + public Image getImage(Object element) { + + if (element instanceof TmfCommonProjectElement) { + TmfCommonProjectElement trace = (TmfCommonProjectElement) element; + String traceType = trace.getTraceType(); + if (traceType == null || TmfTraceType.getTraceType(traceType) == null) { + // request the label to the Eclipse platform + return fWorkspaceLabelProvider.getImage(((TmfCommonProjectElement) element).getResource()); + } + + IConfigurationElement traceUIAttributes = TmfTraceTypeUIUtils.getTraceUIAttributes(traceType, (element instanceof TmfTraceElement) ? TraceElementType.TRACE : TraceElementType.EXPERIMENT); + if (traceUIAttributes != null) { + String iconAttr = traceUIAttributes.getAttribute(TmfTraceTypeUIUtils.ICON_ATTR); + if (iconAttr != null) { + String name = traceUIAttributes.getContributor().getName(); + if (name != null) { + Bundle bundle = Platform.getBundle(name); + if (bundle != null) { + Image image = loadIcon(bundle, iconAttr); + if (image != null) { + return image; + } + } + } + } + + } + if (element instanceof TmfTraceElement) { + return fDefaultTraceIcon; + } + return fExperimentIcon; + } + + if (element instanceof TmfExperimentFolder) { + return fExperimentFolderIcon; + } + + if (element instanceof TmfTraceFolder) { + return fTraceFolderIcon; + } + + if (element instanceof TmfAnalysisOutputElement) { + TmfAnalysisOutputElement output = (TmfAnalysisOutputElement) element; + Image icon = output.getIcon(); + if (icon == null) { + return fDefaultViewIcon; + } + return icon; + } + + if (element instanceof TmfAnalysisElement) { + TmfAnalysisElement analysis = (TmfAnalysisElement) element; + String iconFile = analysis.getIconFile(); + if (iconFile != null) { + Bundle bundle = analysis.getBundle(); + if (bundle != null) { + Image icon = loadIcon(bundle, iconFile); + return icon; + } + } + return fDefaultAnalysisIcon; + } + + return null; + } + + @Override + public String getText(Object element) { + + if (element instanceof TmfTracesFolder) { + TmfTracesFolder folder = (TmfTracesFolder) element; + return folder.getName() + " [" + folder.getTraces().size() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + if (element instanceof TmfTraceFolder) { + TmfTraceFolder folder = (TmfTraceFolder) element; + int nbTraces = folder.getTraces().size(); + if (nbTraces > 0) { + return folder.getName() + " [" + folder.getTraces().size() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + } + return folder.getName(); + } + + if (element instanceof TmfTraceElement) { + TmfTraceElement trace = (TmfTraceElement) element; + if (trace.getParent() instanceof TmfExperimentElement) { + return trace.getElementPath(); + } + return trace.getName(); + } + + if (element instanceof TmfExperimentElement) { + TmfExperimentElement folder = (TmfExperimentElement) element; + return folder.getName() + " [" + folder.getTraces().size() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + if (element instanceof TmfExperimentFolder) { + TmfExperimentFolder folder = (TmfExperimentFolder) element; + return folder.getName() + " [" + folder.getChildren().size() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + // Catch all + if (element instanceof ITmfProjectModelElement) { + return ((ITmfProjectModelElement) element).getName(); + } + + return null; + } + + @Override + public void addListener(ILabelProviderListener listener) { + } + + @Override + public void dispose() { + } + + @Override + public boolean isLabelProperty(Object element, String property) { + return false; + } + + @Override + public void removeListener(ILabelProviderListener listener) { + } + + @Override + public void restoreState(IMemento aMemento) { + } + + @Override + public void saveState(IMemento aMemento) { + } + + @Override + public String getDescription(Object anElement) { + return getText(anElement); + } + + @Override + public void init(ICommonContentExtensionSite aConfig) { + } + + /** + * @since 3.0 + */ + @Override + public StyledString getStyledText(Object element) { + String text = getText(element); + if (text != null) { + if (element instanceof ITmfStyledProjectModelElement) { + Styler styler = ((ITmfStyledProjectModelElement) element).getStyler(); + if (styler != null) { + return new StyledString(text, styler); + } + } + return new StyledString(text); + } + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfOpenTraceHelper.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfOpenTraceHelper.java new file mode 100644 index 0000000000..1e78fab27d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfOpenTraceHelper.java @@ -0,0 +1,464 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Patrick Tasse - Update open trace and add open experiment + * Geneviève Bastien - Merge methods to open trace and experiments + * Bernd Hufmann - Updated handling of directory traces + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import java.io.File; +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.jface.util.OpenStrategy; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.project.model.TmfImportHelper; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceImportException; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; +import org.eclipse.tracecompass.tmf.ui.editors.TmfEditorInput; +import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IReusableEditor; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.ide.IDE; +import org.eclipse.ui.part.FileEditorInput; + +/** + * Open trace helper + * + * Helper class for opening trace resources and loading them to a tracing + * project. + * + * @author Matthew Khouzam + * @since 2.1 + */ +public class TmfOpenTraceHelper { + + private TmfOpenTraceHelper() { + } + + private static final String ENDL = System.getProperty("line.separator"); //$NON-NLS-1$ + + /** + * Opens a trace from a path while importing it to the destination folder. + * The trace is linked as a resource. + * + * @param destinationFolder + * The destination trace folder + * @param path + * the file to import + * @param shell + * the shell to use for dialogs + * @return IStatus OK if successful + * @throws CoreException + * core exceptions if something is not well set up in the back + * end + * @since 3.0 + */ + public static IStatus openTraceFromPath(TmfTraceFolder destinationFolder, String path, Shell shell) throws CoreException { + return openTraceFromPath(destinationFolder, path, shell, null); + } + + /** + * Opens a trace from a path while importing it to the destination folder. + * The trace is linked as a resource. + * + * @param destinationFolder + * The destination trace folder + * @param path + * the file to import + * @param shell + * the shell to use for dialogs + * @param tracetypeHint + * The trace type id, can be null + * @return IStatus OK if successful + * @throws CoreException + * core exceptions if something is not well set up in the back + * end + * + * @since 3.0 + */ + public static IStatus openTraceFromPath(TmfTraceFolder destinationFolder, String path, Shell shell, String tracetypeHint) throws CoreException { + final String pathToUse = checkTracePath(path); + TraceTypeHelper traceTypeToSet = null; + try { + traceTypeToSet = TmfTraceTypeUIUtils.selectTraceType(pathToUse, null, tracetypeHint); + } catch (TmfTraceImportException e) { + MessageBox mb = new MessageBox(shell); + mb.setMessage(e.getMessage()); + mb.open(); + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage()); + } + + IFolder folder = destinationFolder.getResource(); + String traceName = getTraceName(pathToUse, folder); + if (traceExists(pathToUse, folder)) { + return openTraceFromFolder(destinationFolder, traceName); + } + final IPath pathString = Path.fromOSString(pathToUse); + IResource linkedTrace = TmfImportHelper.createLink(folder, pathString, traceName); + + if (linkedTrace == null || !linkedTrace.exists()) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, + Messages.TmfOpenTraceHelper_LinkFailed); + } + + String sourceLocation = URIUtil.toUnencodedString(pathString.toFile().toURI()); + linkedTrace.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation); + + // No trace type was determined. + if (traceTypeToSet == null) { + return Status.OK_STATUS; + } + + IStatus ret = TmfTraceTypeUIUtils.setTraceType(linkedTrace, traceTypeToSet); + if (ret.isOK()) { + ret = openTraceFromFolder(destinationFolder, traceName); + } + return ret; + } + + /** + * Checks whether the parent or grandparent of given path to a file is a + * valid directory trace. If it is a directory trace then return the parent + * or grandparent path. + * + * @param path + * the path to check + * @return path to use for trace type validation. + */ + private static String checkTracePath(String path) { + File file = new File(path); + if (file.exists() && !file.isDirectory()) { + // First check parent + File parent = file.getParentFile(); + String pathToUse = parent.getAbsolutePath(); + if (TmfTraceType.isDirectoryTrace(pathToUse)) { + return pathToUse; + } + // Second check grandparent + File grandParent = parent.getParentFile(); + if (grandParent != null) { + pathToUse = grandParent.getAbsolutePath(); + if (TmfTraceType.isDirectoryTrace(pathToUse)) { + return pathToUse; + } + } + } + return path; + } + + private static boolean traceExists(String path, IFolder folder) { + String val = getTraceName(path, folder); + return (folder.findMember(val) != null); + } + + private static boolean isWrongMember(IFolder folder, String name, final File traceFile) { + final IResource candidate = folder.findMember(name); + if (candidate != null) { + final IPath rawLocation = candidate.getRawLocation(); + final File file = rawLocation.toFile(); + return !file.equals(traceFile); + } + return false; + } + + /** + * Gets the display name, either "filename" or "filename(n)" if there is + * already a filename existing where n is the next unused integer starting + * from 2 + * + * @param path + * the file path + * @param folder + * the folder to import to + * @return the filename + */ + private static String getTraceName(String path, IFolder folder) { + String name; + final File traceFile = new File(path); + name = traceFile.getName(); + for (int i = 2; isWrongMember(folder, name, traceFile); i++) { + name = traceFile.getName() + '(' + i + ')'; + } + return name; + } + + /** + * Open a trace from a trace folder + * + * @param destinationFolder + * The destination trace folder + * @param traceName + * the trace name + * @return success or error + * @since 3.0 + */ + private static IStatus openTraceFromFolder(TmfTraceFolder destinationFolder, String traceName) { + final List elements = destinationFolder.getChildren(); + TmfTraceElement traceElement = null; + for (ITmfProjectModelElement element : elements) { + if (element instanceof TmfTraceElement && element.getName().equals(traceName)) { + traceElement = (TmfTraceElement) element; + } + } + if (traceElement == null) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(Messages.TmfOpenTraceHelper_TraceNotFound, traceName)); + } + openTraceFromElement(traceElement); + return Status.OK_STATUS; + } + + private static ITmfTrace openTraceElement(final TmfTraceElement traceElement) { + final ITmfTrace trace = traceElement.instantiateTrace(); + final ITmfEvent traceEvent = traceElement.instantiateEvent(); + if ((trace == null) || (traceEvent == null)) { + TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, traceElement.getTypeName()), + Messages.TmfOpenTraceHelper_NoTraceType); + if (trace != null) { + trace.dispose(); + } + return null; + } + + try { + trace.initTrace(traceElement.getResource(), traceElement.getResource().getLocation().toOSString(), traceEvent.getClass(), traceElement.getElementPath()); + } catch (final TmfTraceException e) { + TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, traceElement.getTypeName()), + Messages.TmfOpenTraceHelper_InitError + ENDL + ENDL + e); + trace.dispose(); + return null; + } + return trace; + } + + private static ITmfTrace openExperimentElement(final TmfExperimentElement experimentElement) { + /* Experiment element now has an experiment type associated with it */ + final TmfExperiment experiment = experimentElement.instantiateTrace(); + if (experiment == null) { + TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, experimentElement.getTypeName()), + NLS.bind(Messages.TmfOpenTraceHelper_NoTraceOrExperimentType, experimentElement.getTypeName())); + return null; + } + + // Instantiate the experiment's traces + final List traceEntries = experimentElement.getTraces(); + int cacheSize = Integer.MAX_VALUE; + final ITmfTrace[] traces = new ITmfTrace[traceEntries.size()]; + for (int i = 0; i < traceEntries.size(); i++) { + TmfTraceElement element = traceEntries.get(i); + + // Since trace is under an experiment, use the original trace from + // the traces folder + element = element.getElementUnderTraceFolder(); + + ITmfTrace trace = openTraceElement(element); + + if (trace == null) { + for (int j = 0; j < i; j++) { + traces[j].dispose(); + } + return null; + } + cacheSize = Math.min(cacheSize, trace.getCacheSize()); + + traces[i] = trace; + } + + // Create the experiment + experiment.initExperiment(ITmfEvent.class, experimentElement.getName(), traces, cacheSize, experimentElement.getResource()); + + return experiment; + } + + private static ITmfTrace openProjectElement(final TmfCommonProjectElement element) { + ITmfTrace trace = null; + if (element instanceof TmfTraceElement) { + trace = openTraceElement((TmfTraceElement) element); + } else if (element instanceof TmfExperimentElement) { + trace = openExperimentElement((TmfExperimentElement) element); + } + return trace; + } + + /** + * Open a trace (or experiment) from a project element. If the trace is already opened, its + * editor is activated and brought to top. + * + * @param traceElement + * the {@link TmfTraceElement} to open + * @since 3.0 + */ + public static void openTraceFromElement(final TmfCommonProjectElement traceElement) { + + final IFile file; + try { + file = traceElement.createBookmarksFile(); + } catch (final CoreException e) { + Activator.getDefault().logError(NLS.bind(Messages.TmfOpenTraceHelper_ErrorOpeningElement, traceElement.getTypeName()) + ' ' + traceElement.getName()); + TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, traceElement.getTypeName()), + NLS.bind(Messages.TmfOpenTraceHelper_ErrorElement, traceElement.getTypeName()) + ENDL + ENDL + e.getMessage()); + return; + } + + final IWorkbench wb = PlatformUI.getWorkbench(); + final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); + final IEditorPart editor = findEditor(new FileEditorInput(file), true); + if (editor != null) { + activePage.activate(editor); + return; + } + + // If a trace type is not set then delegate it to the eclipse platform + if ((traceElement instanceof TmfTraceElement) && (traceElement.getResource() instanceof IFile) && (traceElement.getTraceType() == null)) { + try { + boolean activate = OpenStrategy.activateOnOpen(); + // only local open is supported + IDE.openEditor(activePage, file, activate); + } catch (PartInitException e) { + TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, traceElement.getTypeName()), + NLS.bind(Messages.TmfOpenTraceHelper_ErrorOpeningElement, traceElement.getElementPath()) + ENDL + ENDL + e.getMessage()); + } + return; + } + + Thread thread = new Thread() { + @Override + public void run() { + final ITmfTrace trace = openProjectElement(traceElement); + + if (trace == null) { + return; + } + + // Get the editor id from the extension point + String traceEditorId = traceElement.getEditorId(); + final String editorId = (traceEditorId != null) ? traceEditorId : TmfEventsEditor.ID; + final IEditorInput editorInput = new TmfEditorInput(file, trace); + + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + try { + activePage.openEditor(editorInput, editorId); + IDE.setDefaultEditor(file, editorId); + // editor should dispose the trace on close + } catch (final PartInitException e) { + TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, traceElement.getTypeName()), + NLS.bind(Messages.TmfOpenTraceHelper_ErrorOpeningElement, traceElement.getTypeName()) + ENDL + ENDL + e.getMessage()); + Activator.getDefault().logError(NLS.bind(Messages.TmfOpenTraceHelper_ErrorOpeningElement, traceElement.getTypeName()) + ' ' + traceElement.getName()); + trace.dispose(); + } + } + }); + } + }; + thread.start(); + } + + /** + * Returns the editor with the specified input. Returns null if there is no + * opened editor with that input. If restore is requested, the method finds + * and returns the editor even if it is not restored yet after a restart. + * + * @param input + * the editor input + * @param restore + * true if the editor should be restored + * @return an editor with input equals to input + */ + private static IEditorPart findEditor(IEditorInput input, boolean restore) { + final IWorkbench wb = PlatformUI.getWorkbench(); + final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); + for (IEditorReference editorReference : activePage.getEditorReferences()) { + try { + IEditorInput editorInput = editorReference.getEditorInput(); + if (editorInput.equals(input)) { + return editorReference.getEditor(restore); + } + } catch (PartInitException e) { + } + } + return null; + } + + /** + * Reopen a trace or experiment from a project element in the provided + * editor + * + * @param traceElement + * the {@link TmfTraceElement} to open + * @param editor + * the reusable editor + * @since 3.0 + */ + public static void reopenTraceFromElement(final TmfCommonProjectElement traceElement, final IReusableEditor editor) { + + final IFile file; + try { + file = traceElement.createBookmarksFile(); + } catch (final CoreException e) { + Activator.getDefault().logError(NLS.bind(Messages.TmfOpenTraceHelper_ErrorOpeningElement, traceElement.getTypeName()) + ' ' + traceElement.getName()); + TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, traceElement.getTypeName()), + NLS.bind(Messages.TmfOpenTraceHelper_ErrorElement, traceElement.getTypeName()) + ENDL + ENDL + e.getMessage()); + return; + } + + Thread thread = new Thread() { + @Override + public void run() { + + final ITmfTrace trace = openProjectElement(traceElement); + if (trace == null) { + return; + } + + final IEditorInput editorInput = new TmfEditorInput(file, trace); + + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + final IWorkbench wb = PlatformUI.getWorkbench(); + final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); + activePage.reuseEditor(editor, editorInput); + activePage.activate(editor); + } + }); + } + }; + thread.start(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfProjectElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfProjectElement.java new file mode 100644 index 0000000000..45cfcb4aea --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfProjectElement.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Refactor resource change listener + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; + +/** + * The implementation of TMF project model element. + * + * @version 1.0 + * @author Francois Chouinard + */ +public class TmfProjectElement extends TmfProjectModelElement { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private TmfTraceFolder fTraceFolder = null; + private TmfExperimentFolder fExperimentFolder = null; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + /** + * Constructor. + * + * Creates the TMF project model element. + * @param name The name of the project. + * @param project The project reference. + * @param parent The parent element + */ + public TmfProjectElement(String name, IProject project, ITmfProjectModelElement parent) { + super(name, project, parent); + } + + // ------------------------------------------------------------------------ + // TmfProjectModelElement + // ------------------------------------------------------------------------ + + @Override + public IProject getResource() { + return (IProject) fResource; + } + + @Override + public void addChild(ITmfProjectModelElement child) { + super.addChild(child); + if (child instanceof TmfTraceFolder) { + fTraceFolder = (TmfTraceFolder) child; + return; + } + if (child instanceof TmfExperimentFolder) { + fExperimentFolder = (TmfExperimentFolder) child; + return; + } + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * Returns the containing trace folder element. + * @return the TMF trace folder element. + */ + public TmfTraceFolder getTracesFolder() { + return fTraceFolder; + } + + /** + * Returns the containing experiment folder element. + * @return the TMF experiment folder element. + */ + public TmfExperimentFolder getExperimentsFolder() { + return fExperimentFolder; + } + + // ------------------------------------------------------------------------ + // TmfProjectModelElement + // ------------------------------------------------------------------------ + + @Override + void refreshChildren() { + IProject project = getResource(); + + // Get the children from the model + Map childrenMap = new HashMap<>(); + for (ITmfProjectModelElement element : getChildren()) { + childrenMap.put(element.getResource().getName(), element); + } + + // Add the model folder if the corresponding resource exists and is not + // accounted for + IFolder folder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME); + if (folder != null && folder.exists()) { + String name = folder.getName(); + ITmfProjectModelElement element = childrenMap.get(name); + if (element instanceof TmfTracesFolder) { + childrenMap.remove(name); + } else { + element = new TmfTracesFolder(TmfTracesFolder.TRACES_FOLDER_NAME, folder, this); + } + ((TmfTracesFolder) element).refreshChildren(); + } + + // Add the model folder if the corresponding resource exists and is not + // accounted for + folder = project.getFolder(TmfExperimentFolder.EXPER_FOLDER_NAME); + if (folder != null && folder.exists()) { + String name = folder.getName(); + ITmfProjectModelElement element = childrenMap.get(name); + if (element instanceof TmfExperimentFolder) { + childrenMap.remove(name); + } else { + element = new TmfExperimentFolder(TmfExperimentFolder.EXPER_FOLDER_NAME, folder, this); + } + ((TmfExperimentFolder) element).refreshChildren(); + } + + // Cleanup dangling children from the model + for (ITmfProjectModelElement danglingChild : childrenMap.values()) { + removeChild(danglingChild); + } + } + + @Override + public TmfProjectElement getProject() { + return this; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfProjectModelElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfProjectModelElement.java new file mode 100644 index 0000000000..c0a699fbe6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfProjectModelElement.java @@ -0,0 +1,271 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Added supplementary files/folder handling + * Patrick Tasse - Refactor resource change listener + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import java.io.File; +import java.net.URI; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.navigator.CommonNavigator; +import org.eclipse.ui.navigator.CommonViewer; + +/** + * The implementation of the base TMF project model element. It provides default implementation + * of the ITmfProjectModelElement interface. + *

    + * @version 1.0 + * @author Francois Chouinard + */ +public abstract class TmfProjectModelElement implements ITmfProjectModelElement { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final String fName; + /** + * The project model element resource. + */ + protected final IResource fResource; + /** + * The project model resource location (URI) + */ + protected final URI fLocation; + /** + * The project model path of a resource. + */ + protected final IPath fPath; + private final ITmfProjectModelElement fParent; + /** + * The list of children elements. + */ + protected final List fChildren; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + /** + * Constructor. + * + * Creates a base project model element. + * @param name The name of the element. + * @param resource The element resource. + * @param parent The parent model element. + */ + protected TmfProjectModelElement(String name, IResource resource, ITmfProjectModelElement parent) { + fName = name; + fResource = resource; + fPath = resource.getFullPath(); + fLocation = new File(resource.getLocationURI()).toURI(); + fParent = parent; + fChildren = new CopyOnWriteArrayList<>(); + } + + // ------------------------------------------------------------------------ + // ITmfProjectModelElement + // ------------------------------------------------------------------------ + + @Override + public String getName() { + return fName; + } + + @Override + public IResource getResource() { + return fResource; + } + + @Override + public IPath getPath() { + return fPath; + } + + @Override + public URI getLocation() { + return fLocation; + } + + /** + * @since 3.0 + */ + @Override + public TmfProjectElement getProject() { + return fParent.getProject(); + } + + @Override + public ITmfProjectModelElement getParent() { + return fParent; + } + + @Override + public boolean hasChildren() { + return fChildren.size() > 0; + } + + @Override + public List getChildren() { + return fChildren; + } + + @Override + public void addChild(ITmfProjectModelElement child) { + fChildren.add(child); + } + + @Override + public void removeChild(ITmfProjectModelElement child) { + fChildren.remove(child); + } + + @Override + public void refresh() { + // make sure the model is updated in the current thread + refreshChildren(); + + Display.getDefault().asyncExec(new Runnable(){ + @Override + public void run() { + IWorkbench wb = PlatformUI.getWorkbench(); + IWorkbenchWindow wbWindow = wb.getActiveWorkbenchWindow(); + if (wbWindow == null) { + return; + } + IWorkbenchPage activePage = wbWindow.getActivePage(); + if (activePage == null) { + return; + } + + for (IViewReference viewReference : activePage.getViewReferences()) { + IViewPart viewPart = viewReference.getView(false); + if (viewPart instanceof CommonNavigator) { + CommonViewer commonViewer = ((CommonNavigator) viewPart).getCommonViewer(); + Object element = TmfProjectModelElement.this; + if (element instanceof TmfProjectElement) { + // for the project element the viewer uses the IProject resource + element = getResource(); + } + commonViewer.refresh(element); + } + } + }}); + } + + // ------------------------------------------------------------------------ + // Object + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((fPath == null) ? 0 : fPath.hashCode()); + return result; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (other == null) { + return false; + } + if (!(other instanceof TmfProjectModelElement)) { + return false; + } + TmfProjectModelElement element = (TmfProjectModelElement) other; + return element.fPath.equals(fPath); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Refresh the children of this model element, adding new children and + * removing dangling children as necessary. The remaining children should + * also refresh their own children sub-tree. + */ + void refreshChildren() { + // Sub-classes may override this method as needed + } + + /** + * Returns the trace specific supplementary folder under the project's + * supplementary folder. The returned folder and its parent folders may not + * exist. + * + * @param supplFolderPath + * folder path relative to the project's supplementary folder + * @return the trace specific supplementary folder + */ + public IFolder getTraceSupplementaryFolder(String supplFolderPath) { + TmfProjectElement project = getProject(); + IProject projectResource = project.getResource(); + IFolder supplFolderParent = projectResource.getFolder(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER_NAME); + IFolder folder = supplFolderParent.getFolder(supplFolderPath); + return folder; + } + + /** + * Returns the trace specific supplementary folder under the project's + * supplementary folder. Its parent folders will be created if they don't + * exist. If createFolder is true, the returned folder will be created, + * otherwise it may not exist. + * + * @param supplFolderPath + * folder path relative to the project's supplementary folder + * @param createFolder + * if true, the returned folder will be created + * @return the trace specific supplementary folder + * @since 3.0 + */ + public IFolder prepareTraceSupplementaryFolder(String supplFolderPath, boolean createFolder) { + IFolder folder = getTraceSupplementaryFolder(supplFolderPath); + try { + if (createFolder) { + TraceUtils.createFolder(folder, new NullProgressMonitor()); + } else { + TraceUtils.createFolder((IFolder) folder.getParent(), new NullProgressMonitor()); + } + } catch (CoreException e) { + Activator.getDefault().logError("Error creating supplementary folder " + folder.getFullPath(), e); //$NON-NLS-1$ + } + return folder; + } + + @Override + public String toString() { + return getClass().getSimpleName() + '(' + getPath() + ')'; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfProjectRegistry.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfProjectRegistry.java new file mode 100644 index 0000000000..ce7453743e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfProjectRegistry.java @@ -0,0 +1,205 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Added project creation utility + * Patrick Tasse - Refactor resource change listener + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.TmfProjectNature; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.WorkspaceModifyOperation; + +/** + * Factory class storing TMF tracing projects and creating TMF project model elements. + *

    + * @version 1.0 + * @author Francois Chouinard + */ +public class TmfProjectRegistry implements IResourceChangeListener { + + // Create the singleton instance + static { + new TmfProjectRegistry(); + } + + // The map of project resource to project model elements + private static Map registry = new HashMap<>(); + + private TmfProjectRegistry() { + ResourcesPlugin.getWorkspace().addResourceChangeListener(this); + } + + /** + * Get the project model element for a project resource + * @param project the project resource + * @return the project model element or null if it does not exist + */ + public static synchronized TmfProjectElement getProject(IProject project) { + return getProject(project, false); + } + + /** + * Get the project model element for a project resource + * @param project the project resource + * @param force a flag controlling whether a new project should be created if it doesn't exist + * @return the project model element + */ + public static synchronized TmfProjectElement getProject(IProject project, boolean force) { + TmfProjectElement element = registry.get(project); + if (element == null && force) { + registry.put(project, new TmfProjectElement(project.getName(), project, null)); + element = registry.get(project); + // force the model to be populated + element.refreshChildren(); + } + return element; + } + + /** + * Utility method to create a tracing project. + * + * @param projectName + * - A project name + * @param projectLocation + * - A project location URI. Use null for default location (which is workspace). + * @param monitor + * - A progress monitor + * @return the IProject object or null + * @since 2.0 + */ + public static IProject createProject(String projectName, final URI projectLocation, IProgressMonitor monitor) { + + final IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IWorkspaceRoot root = workspace.getRoot(); + final IProject project = root.getProject(projectName); + WorkspaceModifyOperation action = new WorkspaceModifyOperation() { + @Override + protected void execute(IProgressMonitor progressMonitor) throws CoreException, InvocationTargetException, InterruptedException { + if (!project.exists()) { + IProjectDescription description = workspace.newProjectDescription(project.getName()); + if (projectLocation != null) { + description.setLocationURI(projectLocation); + } + project.create(description, progressMonitor); + } + + if (!project.isOpen()) { + project.open(progressMonitor); + } + + IProjectDescription description = project.getDescription(); + description.setNatureIds(new String[] { TmfProjectNature.ID }); + project.setDescription(description, null); + + IFolder folder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME); + if (!folder.exists()) { + folder.create(true, true, null); + } + + folder = project.getFolder(TmfExperimentFolder.EXPER_FOLDER_NAME); + if (!folder.exists()) { + folder.create(true, true, null); + } + + // create folder for supplementary tracing files + folder = project.getFolder(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER_NAME); + + if (!folder.exists()) { + folder.create(true, true, null); + } + } + }; + try { + PlatformUI.getWorkbench().getProgressService().run(false, false, action); + } catch (InvocationTargetException e) { + Activator.getDefault().logError("Error creating TMF project " + project.getName(), e); //$NON-NLS-1$ + } catch (InterruptedException e) { + } + return project; + } + + // ------------------------------------------------------------------------ + // IResourceChangeListener + // ------------------------------------------------------------------------ + + /** + * @since 3.0 + */ + @Override + public void resourceChanged(IResourceChangeEvent event) { + if (event.getType() == IResourceChangeEvent.PRE_DELETE || event.getType() == IResourceChangeEvent.PRE_CLOSE) { + if (event.getResource() instanceof IProject) { + IProject project = (IProject) event.getResource(); + try { + if (project.isAccessible() && project.hasNature(TmfProjectNature.ID)) { + TmfProjectElement tmfProjectElement = registry.get(project); + if (tmfProjectElement == null) { + return; + } + final List traces = tmfProjectElement.getTracesFolder().getTraces(); + if (!traces.isEmpty()) { + // Close editors in UI Thread + Display.getDefault().syncExec(new Runnable() { + @Override + public void run() { + for (TmfTraceElement traceElement : traces) { + traceElement.closeEditors(); + } + } + }); + } + } + } catch (CoreException e) { + Activator.getDefault().logError("Error handling resource change event for " + project.getName(), e); //$NON-NLS-1$ + } + } + } else if (event.getType() == IResourceChangeEvent.POST_CHANGE) { + for (IResourceDelta delta : event.getDelta().getAffectedChildren()) { + if (delta.getResource() instanceof IProject) { + IProject project = (IProject) delta.getResource(); + try { + if (delta.getKind() == IResourceDelta.CHANGED && + project.isOpen() && project.hasNature(TmfProjectNature.ID)) { + TmfProjectElement projectElement = getProject(project, true); + projectElement.refresh(); + } else if (delta.getKind() == IResourceDelta.REMOVED) { + registry.remove(project); + } + } catch (CoreException e) { + Activator.getDefault().logError("Error handling resource change event for " + project.getName(), e); //$NON-NLS-1$ + } + } + } + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfTraceElement.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfTraceElement.java new file mode 100644 index 0000000000..00180c9fe9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfTraceElement.java @@ -0,0 +1,700 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Added supplementary files handling + * Geneviève Bastien - Moved supplementary files handling to parent class, + * added code to copy trace + * Patrick Tasse - Close editors to release resources + * Jean-Christian Kouame - added trace properties to be shown into + * the properties view + * Geneviève Bastien - Moved trace type related methods to parent class + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.filesystem.EFS; +import org.eclipse.core.filesystem.IFileInfo; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtEvent; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTrace; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlEvent; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTrace; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; +import org.eclipse.tracecompass.tmf.core.synchronization.TimestampTransformFactory; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceProperties; +import org.eclipse.tracecompass.tmf.core.trace.TmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor; +import org.eclipse.tracecompass.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; +import org.eclipse.ui.IActionFilter; +import org.eclipse.ui.views.properties.IPropertyDescriptor; +import org.eclipse.ui.views.properties.IPropertySource2; + +import com.ibm.icu.text.DateFormat; +import com.ibm.icu.text.NumberFormat; + +/** + * Implementation of trace model element representing a trace. It provides + * methods to instantiate ITmfTrace and ITmfEvent as + * well as editor ID from the trace type extension definition. + * + * @version 1.0 + * @author Francois Chouinard + */ +public class TmfTraceElement extends TmfCommonProjectElement implements IActionFilter, IPropertySource2 { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + // Other attributes + /** + * Bundle attribute name + */ + public static final String BUNDLE = "bundle"; //$NON-NLS-1$ + /** + * IsLinked attribute name. + */ + public static final String IS_LINKED = "isLinked"; //$NON-NLS-1$ + + // Property View stuff + private static final String sfResourcePropertiesCategory = Messages.TmfTraceElement_ResourceProperties; + private static final String sfName = Messages.TmfTraceElement_Name; + private static final String sfPath = Messages.TmfTraceElement_Path; + private static final String sfLocation = Messages.TmfTraceElement_Location; + private static final String sfTraceType = Messages.TmfTraceElement_EventType; + private static final String sfIsLinked = Messages.TmfTraceElement_IsLinked; + private static final String sfSourceLocation = Messages.TmfTraceElement_SourceLocation; + private static final String sfTimeOffset = Messages.TmfTraceElement_TimeOffset; + private static final String sfLastModified = Messages.TmfTraceElement_LastModified; + private static final String sfSize = Messages.TmfTraceElement_Size; + private static final String sfTracePropertiesCategory = Messages.TmfTraceElement_TraceProperties; + + private static final ReadOnlyTextPropertyDescriptor sfNameDescriptor = new ReadOnlyTextPropertyDescriptor(sfName, sfName); + private static final ReadOnlyTextPropertyDescriptor sfPathDescriptor = new ReadOnlyTextPropertyDescriptor(sfPath, sfPath); + private static final ReadOnlyTextPropertyDescriptor sfLocationDescriptor = new ReadOnlyTextPropertyDescriptor(sfLocation, sfLocation); + private static final ReadOnlyTextPropertyDescriptor sfTypeDescriptor = new ReadOnlyTextPropertyDescriptor(sfTraceType, sfTraceType); + private static final ReadOnlyTextPropertyDescriptor sfIsLinkedDescriptor = new ReadOnlyTextPropertyDescriptor(sfIsLinked, sfIsLinked); + private static final ReadOnlyTextPropertyDescriptor sfSourceLocationDescriptor = new ReadOnlyTextPropertyDescriptor(sfSourceLocation, sfSourceLocation); + private static final ReadOnlyTextPropertyDescriptor sfTimeOffsetDescriptor = new ReadOnlyTextPropertyDescriptor(sfTimeOffset, sfTimeOffset); + private static final ReadOnlyTextPropertyDescriptor sfLastModifiedDescriptor = new ReadOnlyTextPropertyDescriptor(sfLastModified, sfLastModified); + private static final ReadOnlyTextPropertyDescriptor sfSizeDescriptor = new ReadOnlyTextPropertyDescriptor(sfSize, sfSize); + + private static final IPropertyDescriptor[] sfDescriptors = { sfNameDescriptor, sfPathDescriptor, sfLocationDescriptor, + sfTypeDescriptor, sfIsLinkedDescriptor, sfSourceLocationDescriptor, + sfTimeOffsetDescriptor, sfLastModifiedDescriptor, sfSizeDescriptor }; + + static { + sfNameDescriptor.setCategory(sfResourcePropertiesCategory); + sfPathDescriptor.setCategory(sfResourcePropertiesCategory); + sfLocationDescriptor.setCategory(sfResourcePropertiesCategory); + sfTypeDescriptor.setCategory(sfResourcePropertiesCategory); + sfIsLinkedDescriptor.setCategory(sfResourcePropertiesCategory); + sfSourceLocationDescriptor.setCategory(sfResourcePropertiesCategory); + sfTimeOffsetDescriptor.setCategory(sfResourcePropertiesCategory); + sfLastModifiedDescriptor.setCategory(sfResourcePropertiesCategory); + sfSizeDescriptor.setCategory(sfResourcePropertiesCategory); + } + + private static final TmfTimestampFormat OFFSET_FORMAT = new TmfTimestampFormat("T.SSS SSS SSS s"); //$NON-NLS-1$ + + private static final int FOLDER_MAX_COUNT = 1024; + + // ------------------------------------------------------------------------ + // Static initialization + // ------------------------------------------------------------------------ + + // The mapping of available trace type IDs to their corresponding + // configuration element + private static final Map sfTraceTypeAttributes = new HashMap<>(); + private static final Map sfTraceTypeUIAttributes = new HashMap<>(); + private static final Map sfTraceCategories = new HashMap<>(); + + /** + * Initialize statically at startup by getting extensions from the platform + * extension registry. + */ + public static void init() { + /* Read the tmf.core "tracetype" extension point */ + IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType.TMF_TRACE_TYPE_ID); + for (IConfigurationElement ce : config) { + switch (ce.getName()) { + case TmfTraceType.TYPE_ELEM: + String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR); + sfTraceTypeAttributes.put(traceTypeId, ce); + break; + case TmfTraceType.CATEGORY_ELEM: + String categoryId = ce.getAttribute(TmfTraceType.ID_ATTR); + sfTraceCategories.put(categoryId, ce); + break; + default: + } + } + + /* + * Read the corresponding tmf.ui "tracetypeui" extension point for this + * trace type, if it exists. + */ + config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceTypeUIUtils.TMF_TRACE_TYPE_UI_ID); + for (IConfigurationElement ce : config) { + String elemName = ce.getName(); + if (TmfTraceTypeUIUtils.TYPE_ELEM.equals(elemName)) { + String traceType = ce.getAttribute(TmfTraceTypeUIUtils.TRACETYPE_ATTR); + sfTraceTypeUIAttributes.put(traceType, ce); + } + } + } + + // ------------------------------------------------------------------------ + // Classes + // ------------------------------------------------------------------------ + + private class FileInfo { + long lastModified; + long size; + int count; + } + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private FileInfo fFileInfo; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Constructor. Creates trace model element under the trace folder. + * + * @param name + * The name of trace + * @param trace + * The trace resource. + * @param parent + * The parent element (trace folder) + */ + public TmfTraceElement(String name, IResource trace, TmfTraceFolder parent) { + super(name, trace, parent); + } + + /** + * Constructor. Creates trace model element under the experiment folder. + * + * @param name + * The name of trace + * @param trace + * The trace resource. + * @param parent + * The parent element (experiment folder) + */ + public TmfTraceElement(String name, IResource trace, TmfExperimentElement parent) { + super(name, trace, parent); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Instantiate a ITmfTrace object based on the trace type and + * the corresponding extension. + * + * @return the ITmfTrace or null for an error + */ + @Override + public ITmfTrace instantiateTrace() { + try { + + // make sure that supplementary folder exists + refreshSupplementaryFolder(); + + if (getTraceType() != null) { + if (getTraceType().startsWith(CustomTxtTrace.class.getCanonicalName())) { + for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) { + if (getTraceType().equals(CustomTxtTrace.class.getCanonicalName() + ':' + def.categoryName+ ':' + def.definitionName)) { + return new CustomTxtTrace(def); + } + } + } + if (getTraceType().startsWith(CustomXmlTrace.class.getCanonicalName())) { + for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { + if (getTraceType().equals(CustomXmlTrace.class.getCanonicalName() + ':' + def.categoryName+ ':' + def.definitionName)) { + return new CustomXmlTrace(def); + } + } + } + IConfigurationElement ce = sfTraceTypeAttributes.get(getTraceType()); + if (ce == null) { + return null; + } + ITmfTrace trace = (ITmfTrace) ce.createExecutableExtension(TmfTraceType.TRACE_TYPE_ATTR); + return trace; + } + } catch (CoreException e) { + Activator.getDefault().logError("Error instantiating ITmfTrace object for trace " + getName(), e); //$NON-NLS-1$ + } + return null; + } + + /** + * Instantiate a ITmfEvent object based on the trace type and + * the corresponding extension. + * + * @return the ITmfEvent or null for an error + */ + public ITmfEvent instantiateEvent() { + try { + if (getTraceType() != null) { + if (getTraceType().startsWith(CustomTxtTrace.class.getCanonicalName())) { + for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) { + if (getTraceType().equals(CustomTxtTrace.class.getCanonicalName() + ':' + def.categoryName+ ':' + def.definitionName)) { + return new CustomTxtEvent(def); + } + } + } + if (getTraceType().startsWith(CustomXmlTrace.class.getCanonicalName())) { + for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { + if (getTraceType().equals(CustomXmlTrace.class.getCanonicalName() + ':' + def.categoryName+ ':' + def.definitionName)) { + return new CustomXmlEvent(def); + } + } + } + IConfigurationElement ce = sfTraceTypeAttributes.get(getTraceType()); + if (ce == null) { + return null; + } + ITmfEvent event = (ITmfEvent) ce.createExecutableExtension(TmfTraceType.EVENT_TYPE_ATTR); + return event; + } + } catch (CoreException e) { + Activator.getDefault().logError("Error instantiating ITmfEvent object for trace " + getName(), e); //$NON-NLS-1$ + } + return null; + } + + @Override + public String getEditorId() { + if (getTraceType() != null) { + if (getTraceType().startsWith(CustomTxtTrace.class.getCanonicalName())) { + return TmfEventsEditor.ID; + } + if (getTraceType().startsWith(CustomXmlTrace.class.getCanonicalName())) { + return TmfEventsEditor.ID; + } + IConfigurationElement ce = sfTraceTypeUIAttributes.get(getTraceType()); + if (ce == null) { + /* This trace type does not define UI attributes */ + return null; + } + IConfigurationElement[] defaultEditorCE = ce.getChildren(TmfTraceTypeUIUtils.DEFAULT_EDITOR_ELEM); + if (defaultEditorCE.length == 1) { + return defaultEditorCE[0].getAttribute(TmfTraceType.ID_ATTR); + } + } + return null; + } + + /** + * Returns the file resource used to store bookmarks after creating it if + * necessary. If the trace resource is a file, it is returned directly. If + * the trace resource is a folder, a linked file is returned. The file will + * be created if it does not exist. + * + * @return the bookmarks file + * @throws CoreException + * if the bookmarks file cannot be created + * @since 2.0 + */ + @Override + public IFile createBookmarksFile() throws CoreException { + IFile file = getBookmarksFile(); + if (fResource instanceof IFolder) { + return createBookmarksFile(getProject().getTracesFolder().getResource(), TmfTrace.class.getCanonicalName()); + } + return file; + } + + /** + * Returns the file resource used to store bookmarks. The file may not + * exist. + * + * @return the bookmarks file + * @since 2.0 + */ + @Override + public IFile getBookmarksFile() { + IFile file = null; + if (fResource instanceof IFile) { + file = (IFile) fResource; + } else if (fResource instanceof IFolder) { + final IFolder folder = (IFolder) fResource; + file = folder.getFile(getName() + '_'); + } + return file; + } + + /** + * Returns the TmfTraceElement located under the + * TmfTracesFolder. + * + * @return this if this element is under the + * TmfTracesFolder else the corresponding + * TmfTraceElement if this element is under + * TmfExperimentElement. + */ + public TmfTraceElement getElementUnderTraceFolder() { + + // If trace is under an experiment, return original trace from the + // traces folder + if (getParent() instanceof TmfExperimentElement) { + for (TmfTraceElement aTrace : getProject().getTracesFolder().getTraces()) { + if (aTrace.getElementPath().equals(getElementPath())) { + return aTrace; + } + } + } + return this; + } + + @Override + public String getTypeName() { + return Messages.TmfTraceElement_TypeName; + } + + // ------------------------------------------------------------------------ + // IActionFilter + // ------------------------------------------------------------------------ + + @Override + public boolean testAttribute(Object target, String name, String value) { + if (name.equals(IS_LINKED)) { + boolean isLinked = getResource().isLinked(); + return Boolean.toString(isLinked).equals(value); + } + return false; + } + + // ------------------------------------------------------------------------ + // IPropertySource2 + // ------------------------------------------------------------------------ + + @Override + public Object getEditableValue() { + return null; + } + + /** + * Get the trace properties of this traceElement if the corresponding trace + * is opened in an editor + * + * @return a map with the names and values of the trace properties + * respectively as keys and values + */ + private Map getTraceProperties() { + for (ITmfTrace openedTrace : TmfTraceManager.getInstance().getOpenedTraces()) { + for (ITmfTrace singleTrace : TmfTraceManager.getTraceSet(openedTrace)) { + if (getElementUnderTraceFolder().getResource().equals(singleTrace.getResource())) { + if (singleTrace instanceof ITmfTraceProperties) { + ITmfTraceProperties traceProperties = (ITmfTraceProperties) singleTrace; + return traceProperties.getTraceProperties(); + } + } + } + } + return new HashMap<>(); + } + + @Override + public IPropertyDescriptor[] getPropertyDescriptors() { + Map traceProperties = getTraceProperties(); + if (!traceProperties.isEmpty()) { + IPropertyDescriptor[] propertyDescriptorArray = new IPropertyDescriptor[traceProperties.size() + sfDescriptors.length]; + int index = 0; + for (Map.Entry varName : traceProperties.entrySet()) { + ReadOnlyTextPropertyDescriptor descriptor = new ReadOnlyTextPropertyDescriptor(this.getName() + "_" + varName.getKey(), varName.getKey()); //$NON-NLS-1$ + descriptor.setCategory(sfTracePropertiesCategory); + propertyDescriptorArray[index] = descriptor; + index++; + } + for (int i = 0; i < sfDescriptors.length; i++) { + propertyDescriptorArray[index] = sfDescriptors[i]; + index++; + } + return propertyDescriptorArray; + } + return Arrays.copyOf(sfDescriptors, sfDescriptors.length); + } + + @Override + public Object getPropertyValue(Object id) { + + if (sfName.equals(id)) { + return getName(); + } + + if (sfPath.equals(id)) { + return getPath().toString(); + } + + if (sfLocation.equals(id)) { + return URIUtil.toUnencodedString(getLocation()); + } + + if (sfIsLinked.equals(id)) { + return Boolean.valueOf(getResource().isLinked()).toString(); + } + + if (sfSourceLocation.equals(id)) { + try { + String sourceLocation = getElementUnderTraceFolder().getResource().getPersistentProperty(TmfCommonConstants.SOURCE_LOCATION); + if (sourceLocation != null) { + return sourceLocation; + } + } catch (CoreException e) { + } + return ""; //$NON-NLS-1$ + } + + if (sfLastModified.equals(id)) { + FileInfo fileInfo = getFileInfo(); + if (fileInfo == null) { + return ""; //$NON-NLS-1$ + } + long date = fileInfo.lastModified; + DateFormat format = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.MEDIUM); + return format.format(new Date(date)); + } + + if (sfSize.equals(id)) { + FileInfo fileInfo = getFileInfo(); + if (fileInfo == null) { + return ""; //$NON-NLS-1$ + } + if (getResource() instanceof IFolder) { + if (fileInfo.count <= FOLDER_MAX_COUNT) { + return NLS.bind(Messages.TmfTraceElement_FolderSizeString, + NumberFormat.getInstance().format(fileInfo.size), fileInfo.count); + } + return NLS.bind(Messages.TmfTraceElement_FolderSizeOverflowString, + NumberFormat.getInstance().format(fileInfo.size), FOLDER_MAX_COUNT); + } + return NLS.bind(Messages.TmfTraceElement_FileSizeString, NumberFormat.getInstance().format(fileInfo.size)); + } + + if (sfTraceType.equals(id)) { + if (getTraceType() != null) { + TraceTypeHelper helper = TmfTraceType.getTraceType(getTraceType()); + if (helper != null) { + return helper.getCategoryName() + " : " + helper.getName(); //$NON-NLS-1$ + } + } + return ""; //$NON-NLS-1$ + } + + if (sfTimeOffset.equals(id)) { + long offset = TimestampTransformFactory.getTimestampTransform(getElementUnderTraceFolder().getResource()).transform(0); + if (offset != 0) { + return OFFSET_FORMAT.format(offset); + } + return ""; //$NON-NLS-1$ + } + + Map traceProperties = getTraceProperties(); + if (id != null && !traceProperties.isEmpty()) { + String key = (String) id; + key = key.substring(this.getName().length() + 1); // remove name_ + String value = traceProperties.get(key); + return value; + } + + return null; + } + + private FileInfo getFileInfo() { + /* FileInfo is needed for both 'last modified' and 'size' properties. + * It is freshly computed for one, and reused for the other, then + * cleared so that the information can be refreshed the next time. + */ + FileInfo fileInfo; + if (fFileInfo == null) { + try { + fileInfo = computeFileInfo(new FileInfo(), getResource()); + } catch (CoreException e) { + return null; + } + fFileInfo = fileInfo; + } else { + fileInfo = fFileInfo; + fFileInfo = null; + } + return fileInfo; + } + + private FileInfo computeFileInfo(FileInfo fileInfo, IResource resource) throws CoreException { + if (fileInfo == null || fileInfo.count > FOLDER_MAX_COUNT) { + return fileInfo; + } + if (resource instanceof IFolder) { + IFolder folder = (IFolder) resource; + for (IResource member : folder.members()) { + computeFileInfo(fileInfo, member); + } + return fileInfo; + } + IFileInfo info = EFS.getStore(resource.getLocationURI()).fetchInfo(); + fileInfo.lastModified = Math.max(fileInfo.lastModified, info.getLastModified()); + fileInfo.size += info.getLength(); + fileInfo.count++; + return fileInfo; + } + + @Override + public void resetPropertyValue(Object id) { + } + + @Override + public void setPropertyValue(Object id, Object value) { + } + + @Override + public boolean isPropertyResettable(Object id) { + return false; + } + + @Override + public boolean isPropertySet(Object id) { + return false; + } + + /** + * Copy this trace in the trace folder. No other parameters are mentioned so + * the trace is copied in this element's project trace folder + * + * @param newName + * The new trace name + * @return the new Resource object + * @since 2.0 + */ + public TmfTraceElement copy(String newName) { + TmfTraceFolder folder = (TmfTraceFolder) getParent(); + IResource res = super.copy(newName, false); + for (TmfTraceElement trace : folder.getTraces()) { + if (trace.getResource().equals(res)) { + return trace; + } + } + return null; + } + + /** + * Close opened editors associated with this trace. + * + * @since 2.0 + */ + @Override + public void closeEditors() { + super.closeEditors(); + + // Close experiments that contain the trace if open + if (getParent() instanceof TmfTraceFolder) { + TmfExperimentFolder experimentsFolder = getProject().getExperimentsFolder(); + for (TmfExperimentElement experiment : experimentsFolder.getExperiments()) { + for (TmfTraceElement trace : experiment.getTraces()) { + if (trace.getElementPath().equals(getElementPath())) { + experiment.closeEditors(); + break; + } + } + } + } else if (getParent() instanceof TmfExperimentElement) { + TmfExperimentElement experiment = (TmfExperimentElement) getParent(); + experiment.closeEditors(); + } + } + + /** + * Delete the trace resource, remove it from experiments and delete its + * supplementary files + * + * @param progressMonitor + * a progress monitor, or null if progress reporting is not + * desired + * + * @throws CoreException + * thrown when IResource.delete fails + * @since 2.2 + */ + public void delete(IProgressMonitor progressMonitor) throws CoreException { + // Close editors in UI Thread + Display.getDefault().syncExec(new Runnable() { + @Override + public void run() { + closeEditors(); + } + }); + + IPath path = fResource.getLocation(); + if (path != null) { + if (getParent() instanceof TmfTraceFolder) { + TmfExperimentFolder experimentFolder = getProject().getExperimentsFolder(); + + // Propagate the removal to traces + for (TmfExperimentElement experiment : experimentFolder.getExperiments()) { + List toRemove = new LinkedList<>(); + for (TmfTraceElement trace : experiment.getTraces()) { + if (trace.getElementPath().equals(getElementPath())) { + toRemove.add(trace); + } + } + for (TmfTraceElement child : toRemove) { + experiment.removeTrace(child); + } + } + + // Delete supplementary files + deleteSupplementaryFolder(); + + } else if (getParent() instanceof TmfExperimentElement) { + TmfExperimentElement experimentElement = (TmfExperimentElement) getParent(); + experimentElement.removeTrace(this); + } + } + + // Finally, delete the trace + fResource.delete(true, progressMonitor); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfTraceFolder.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfTraceFolder.java new file mode 100644 index 0000000000..c5c14f67ab --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfTraceFolder.java @@ -0,0 +1,209 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Add support for folder elements + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; +import org.eclipse.ui.views.properties.IPropertyDescriptor; +import org.eclipse.ui.views.properties.IPropertySource2; + +/** + * Implementation of trace folder model element representing a trace folder in + * the project. + *

    + * @version 1.0 + * @author Francois Chouinard + */ +public class TmfTraceFolder extends TmfProjectModelElement implements IPropertySource2 { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + private static final String sfInfoCategory = "Info"; //$NON-NLS-1$ + private static final String sfName = "name"; //$NON-NLS-1$ + private static final String sfPath = "path"; //$NON-NLS-1$ + private static final String sfLocation = "location"; //$NON-NLS-1$ + + private static final ReadOnlyTextPropertyDescriptor sfNameDescriptor = new ReadOnlyTextPropertyDescriptor(sfName, sfName); + private static final ReadOnlyTextPropertyDescriptor sfPathDescriptor = new ReadOnlyTextPropertyDescriptor(sfPath, sfPath); + private static final ReadOnlyTextPropertyDescriptor sfLocationDescriptor = new ReadOnlyTextPropertyDescriptor(sfLocation, sfLocation); + + private static final IPropertyDescriptor[] sfDescriptors = { sfNameDescriptor, sfPathDescriptor, + sfLocationDescriptor }; + + static { + sfNameDescriptor.setCategory(sfInfoCategory); + sfPathDescriptor.setCategory(sfInfoCategory); + sfLocationDescriptor.setCategory(sfInfoCategory); + } + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Constructor. + * Creates folder model element under the project. + * @param name The name of trace folder. + * @param resource The folder resource. + * @param parent The parent element (project). + */ + public TmfTraceFolder(String name, IFolder resource, TmfProjectElement parent) { + super(name, resource, parent); + parent.addChild(this); + } + + /** + * Constructor. + * Creates folder model element under another folder. + * @param name The name of trace folder. + * @param resource The folder resource. + * @param parent The parent element (folder). + * @since 3.0 + */ + public TmfTraceFolder(String name, IFolder resource, TmfTraceFolder parent) { + super(name, resource, parent); + parent.addChild(this); + } + + // ------------------------------------------------------------------------ + // TmfProjectModelElement + // ------------------------------------------------------------------------ + + @Override + public IFolder getResource() { + return (IFolder) fResource; + } + + @Override + void refreshChildren() { + IFolder folder = getResource(); + + // Get the children from the model + Map childrenMap = new HashMap<>(); + for (ITmfProjectModelElement element : getChildren()) { + childrenMap.put(element.getResource().getName(), element); + } + + try { + IResource[] members = folder.members(); + for (IResource resource : members) { + String name = resource.getName(); + boolean isFolder = resource instanceof IFolder && + (TmfTraceType.getTraceTypeId(resource) == null); + ITmfProjectModelElement element = childrenMap.get(name); + if (isFolder && !(element instanceof TmfTraceFolder) && !(element instanceof TmfTraceElement)) { + if (TmfTraceType.isDirectoryTrace(resource.getLocationURI().getPath())) { + element = new TmfTraceElement(name, resource, this); + } else { + element = new TmfTraceFolder(name, (IFolder) resource, this); + } + } else if (!isFolder && !(element instanceof TmfTraceElement)) { + element = new TmfTraceElement(name, resource, this); + } else { + childrenMap.remove(name); + } + ((TmfProjectModelElement) element).refreshChildren(); + } + } catch (CoreException e) { + } + + // Cleanup dangling children from the model + for (ITmfProjectModelElement danglingChild : childrenMap.values()) { + removeChild(danglingChild); + } + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Returns a list of trace elements under the folder element, recursively. + * @return list of trace model elements + */ + public List getTraces() { + List children = getChildren(); + List traces = new ArrayList<>(); + for (ITmfProjectModelElement child : children) { + if (child instanceof TmfTraceElement) { + traces.add((TmfTraceElement) child); + } else if (child instanceof TmfTraceFolder) { + traces.addAll(((TmfTraceFolder) child).getTraces()); + } + } + return traces; + } + + // ------------------------------------------------------------------------ + // IPropertySource2 + // ------------------------------------------------------------------------ + + @Override + public Object getEditableValue() { + return null; + } + + @Override + public IPropertyDescriptor[] getPropertyDescriptors() { + return Arrays.copyOf(sfDescriptors, sfDescriptors.length); + } + + @Override + public Object getPropertyValue(Object id) { + + if (sfName.equals(id)) { + return getName(); + } + + if (sfPath.equals(id)) { + return getPath().toString(); + } + + if (sfLocation.equals(id)) { + return getLocation().toString(); + } + + return null; + } + + @Override + public void resetPropertyValue(Object id) { + } + + @Override + public void setPropertyValue(Object id, Object value) { + } + + @Override + public boolean isPropertyResettable(Object id) { + return false; + } + + @Override + public boolean isPropertySet(Object id) { + return false; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfTraceTypeUIUtils.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfTraceTypeUIUtils.java new file mode 100644 index 0000000000..b5ce373193 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfTraceTypeUIUtils.java @@ -0,0 +1,494 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + * Patrick Tasse - Add support for folder elements + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.TreeSet; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.internal.tmf.ui.parsers.custom.CustomEventTableColumns; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTrace; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTrace; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceImportException; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType.TraceElementType; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.util.Pair; +import org.eclipse.tracecompass.tmf.ui.viewers.events.TmfEventsTable; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.ITmfEventTableColumns; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; +import org.osgi.framework.Bundle; + +/** + * Utils class for the UI-specific parts of @link {@link TmfTraceType}. + * + * @author Alexandre Montplaisir + * @since 3.0 + */ +public final class TmfTraceTypeUIUtils { + + /** Extension point ID */ + public static final String TMF_TRACE_TYPE_UI_ID = "org.eclipse.linuxtools.tmf.ui.tracetypeui"; //$NON-NLS-1$ + + /** Extension point element 'type' (should match the type in TmfTraceType) */ + public static final String TYPE_ELEM = "type"; //$NON-NLS-1$ + + /** + * Extension point element 'experiment' (should match the type in + * TmfTraceType) + */ + public static final String EXPERIMENT_ELEM = "experiment"; //$NON-NLS-1$ + + /** Extension point element 'Default editor' */ + public static final String DEFAULT_EDITOR_ELEM = "defaultEditor"; //$NON-NLS-1$ + + /** Extension point element 'Events table type' */ + public static final String EVENTS_TABLE_TYPE_ELEM = "eventsTableType"; //$NON-NLS-1$ + + /** Extension point element 'Event Table Columns' + * @since 3.2*/ + public static final String EVENT_TABLE_COLUMNS = "eventTableColumns"; //$NON-NLS-1$ + + /** Extension point attribute 'tracetype' */ + public static final String TRACETYPE_ATTR = "tracetype"; //$NON-NLS-1$ + + /** Extension point attribute 'icon' */ + public static final String ICON_ATTR = "icon"; //$NON-NLS-1$ + + /** Extension point attribute 'class' (attribute of other elements) */ + public static final String CLASS_ATTR = "class"; //$NON-NLS-1$ + + private TmfTraceTypeUIUtils() { + } + + private static List> reduce(List> candidates) { + List> retVal = new ArrayList<>(); + + // get all the tracetypes that are unique in that stage + for (Pair candidatePair : candidates) { + TraceTypeHelper candidate = candidatePair.getSecond(); + if (isUnique(candidate, candidates)) { + retVal.add(candidatePair); + } + } + return retVal; + } + + /* + * Only return the leaves of the trace types. Ignore custom trace types. + */ + private static boolean isUnique(TraceTypeHelper trace, List> set) { + if (trace.getTraceClass().equals(CustomTxtTrace.class) || + trace.getTraceClass().equals(CustomXmlTrace.class)) { + return true; + } + // check if the trace type is the leaf. we make an instance of the trace + // type and if it is only an instance of itself, it is a leaf + final ITmfTrace tmfTrace = trace.getTrace(); + int count = -1; + for (Pair child : set) { + final ITmfTrace traceCandidate = child.getSecond().getTrace(); + if (tmfTrace.getClass().isInstance(traceCandidate)) { + count++; + } + } + return count == 0; + } + + private static TraceTypeHelper getTraceTypeToSet(List> candidates, Shell shell) { + final Map names = new HashMap<>(); + Shell shellToShow = new Shell(shell); + shellToShow.setText(Messages.TmfTraceType_SelectTraceType); + final String candidatesToSet[] = new String[1]; + for (Pair candidatePair : candidates) { + TraceTypeHelper candidate = candidatePair.getSecond(); + Button b = new Button(shellToShow, SWT.RADIO); + final String displayName = candidate.getCategoryName() + ':' + candidate.getName(); + b.setText(displayName); + names.put(displayName, candidate.getCanonicalName()); + + b.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + final Button source = (Button) e.getSource(); + candidatesToSet[0] = (names.get(source.getText())); + source.getParent().dispose(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + + } + }); + } + shellToShow.setLayout(new RowLayout(SWT.VERTICAL)); + shellToShow.pack(); + shellToShow.open(); + + Display display = shellToShow.getDisplay(); + while (!shellToShow.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + return TmfTraceType.getTraceType(candidatesToSet[0]); + } + + /** + * This member figures out the trace type of a given file. It will prompt + * the user if it needs more information to properly pick the trace type. + * + * @param path + * The path of file to import + * @param shell + * a shell to display the message to. If it is null, it is + * assumed to be cancelled. + * @param traceTypeHint + * the ID of a trace (like "o.e.l.specifictrace" ) + * @return null if the request is cancelled or a TraceTypeHelper if it + * passes. + * @throws TmfTraceImportException + * if the traces don't match or there are errors in the trace + * file + */ + public static TraceTypeHelper selectTraceType(String path, Shell shell, String traceTypeHint) throws TmfTraceImportException { + + Comparator> comparator = new Comparator>() { + @Override + public int compare(Pair o1, Pair o2) { + int res = -o1.getFirst().compareTo(o2.getFirst()); // invert so that highest confidence is first + if (res == 0) { + res = o1.getSecond().getName().compareTo(o2.getSecond().getName()); + } + return res; + } + }; + TreeSet> validCandidates = new TreeSet<>(comparator); + final Iterable traceTypeHelpers = TmfTraceType.getTraceTypeHelpers(); + for (TraceTypeHelper traceTypeHelper : traceTypeHelpers) { + if (traceTypeHelper.isExperimentType()) { + continue; + } + int confidence = traceTypeHelper.validateWithConfidence(path); + if (confidence >= 0) { + // insert in the tree map, ordered by confidence (highest confidence first) then name + Pair element = new Pair<>(confidence, traceTypeHelper); + validCandidates.add(element); + } + } + + TraceTypeHelper traceTypeToSet = null; + if (validCandidates.isEmpty()) { + final String errorMsg = NLS.bind(Messages.TmfOpenTraceHelper_NoTraceTypeMatch, path); + throw new TmfTraceImportException(errorMsg); + } else if (validCandidates.size() != 1) { + List> candidates = new ArrayList<>(validCandidates); + List> reducedCandidates = reduce(candidates); + for (Pair candidatePair : reducedCandidates) { + TraceTypeHelper candidate = candidatePair.getSecond(); + if (candidate.getCanonicalName().equals(traceTypeHint)) { + traceTypeToSet = candidate; + break; + } + } + if (traceTypeToSet == null) { + if (reducedCandidates.size() == 0) { + throw new TmfTraceImportException(Messages.TmfOpenTraceHelper_ReduceError); + } else if (reducedCandidates.size() == 1) { + traceTypeToSet = reducedCandidates.get(0).getSecond(); + } else if (shell == null) { + Pair candidate = reducedCandidates.get(0); + // if the best match has lowest confidence, don't select it + if (candidate.getFirst() > 0) { + traceTypeToSet = candidate.getSecond(); + } + } else { + traceTypeToSet = getTraceTypeToSet(reducedCandidates, shell); + } + } + } else { + traceTypeToSet = validCandidates.first().getSecond(); + } + return traceTypeToSet; + } + + /** + * Set the trace type of a {@link TraceTypeHelper}. Should only be + * used internally by this project. + * + * @param resource + * the resource to set + * @param traceType + * the {@link TraceTypeHelper} to set the trace type to. + * @return Status.OK_Status if successful, error is otherwise. + * @throws CoreException + * An exception caused by accessing eclipse project items. + */ + public static IStatus setTraceType(IResource resource, TraceTypeHelper traceType) throws CoreException { + return setTraceType(resource, traceType, true); + } + /** + * Set the trace type of a {@link TraceTypeHelper}. Should only be + * used internally by this project. + * + * @param resource + * the resource to set + * @param traceType + * the {@link TraceTypeHelper} to set the trace type to. + * @param refresh + * Flag for refreshing the project + * @return Status.OK_Status if successful, error is otherwise. + * @throws CoreException + * An exception caused by accessing eclipse project items. + * @since 3.1 + */ + public static IStatus setTraceType(IResource resource, TraceTypeHelper traceType, boolean refresh) throws CoreException { + String traceTypeId = traceType.getCanonicalName(); + + resource.setPersistentProperty(TmfCommonConstants.TRACETYPE, traceTypeId); + + TmfProjectElement tmfProject = TmfProjectRegistry.getProject(resource.getProject(), true); + if (tmfProject.getTracesFolder().getPath().isPrefixOf(resource.getFullPath())) { + String elementPath = resource.getFullPath().makeRelativeTo(tmfProject.getTracesFolder().getPath()).toString(); + refreshTraceElement(tmfProject.getTracesFolder().getTraces(), elementPath); + } else if (resource.getParent().equals(tmfProject.getExperimentsFolder().getResource())) { + /* The trace type to set is for an experiment */ + for (TmfExperimentElement experimentElement : tmfProject.getExperimentsFolder().getExperiments()) { + if (resource.equals(experimentElement.getResource())) { + experimentElement.refreshTraceType(); + break; + } + } + } else { + for (TmfExperimentElement experimentElement : tmfProject.getExperimentsFolder().getExperiments()) { + if (experimentElement.getPath().isPrefixOf(resource.getFullPath())) { + String elementPath = resource.getFullPath().makeRelativeTo(experimentElement.getPath()).toString(); + refreshTraceElement(experimentElement.getTraces(), elementPath); + break; + } + } + } + if (refresh) { + tmfProject.refresh(); + } + return Status.OK_STATUS; + } + + private static void refreshTraceElement(List traceElements, String elementPath) { + for (TmfTraceElement traceElement : traceElements) { + if (traceElement.getElementPath().equals(elementPath)) { + traceElement.refreshTraceType(); + break; + } + } + } + + /** + * Retrieves all configuration elements from the platform extension registry + * for the trace type UI extension. + * + * @param elType + * The type of trace type requested, either TRACE or EXPERIMENT + * @return An array of trace type configuration elements + */ + public static IConfigurationElement[] getTypeUIElements(TraceElementType elType) { + String elementName = TYPE_ELEM; + if (elType == TraceElementType.EXPERIMENT) { + elementName = EXPERIMENT_ELEM; + } + IConfigurationElement[] elements = + Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_TRACE_TYPE_UI_ID); + List typeElements = new LinkedList<>(); + for (IConfigurationElement element : elements) { + if (element.getName().equals(elementName)) { + typeElements.add(element); + } + } + return typeElements.toArray(new IConfigurationElement[typeElements.size()]); + } + + /** + * Get the UI elements for the given trace type + * + * @param traceType + * The tracetype ID + * @param elType + * The type of trace type requested, either TRACE or EXPERIMENT + * @return The top-level configuration element (access its children with + * .getChildren()). Or null if there is no such element. + */ + @Nullable + public static IConfigurationElement getTraceUIAttributes(String traceType, TraceElementType elType) { + IConfigurationElement[] elements = getTypeUIElements(elType); + for (IConfigurationElement ce : elements) { + if (traceType.equals(ce.getAttribute(TRACETYPE_ATTR))) { + return ce; + } + } + return null; + } + + /** + * Get the Event Table type specified by the trace type's extension point, + * if there is one. + * + * @param trace + * The trace for which we want the events table. + * @param parent + * The parent composite that the event table will have + * @param cacheSize + * The cache size to use with this event table. Should be defined + * by the trace type. + * @return The corresponding Event Table, or 'null' if this trace type did + * not specify any. + * @since 3.2 + */ + public static @Nullable TmfEventsTable getEventTable(ITmfTrace trace, Composite parent, int cacheSize) { + final String traceType = getTraceType(trace); + if (traceType == null) { + return null; + } + + for (final IConfigurationElement ce : TmfTraceTypeUIUtils.getTypeUIElements(TraceElementType.TRACE)) { + if (ce.getAttribute(TmfTraceTypeUIUtils.TRACETYPE_ATTR).equals(traceType)) { + final IConfigurationElement[] eventsTableTypeCE = ce.getChildren(TmfTraceTypeUIUtils.EVENTS_TABLE_TYPE_ELEM); + + if (eventsTableTypeCE.length != 1) { + break; + } + final String eventsTableType = eventsTableTypeCE[0].getAttribute(TmfTraceTypeUIUtils.CLASS_ATTR); + if (eventsTableType.isEmpty()) { + break; + } + try { + final Bundle bundle = Platform.getBundle(ce.getContributor().getName()); + final Class c = bundle.loadClass(eventsTableType); + final Class[] constructorArgs = new Class[] { Composite.class, int.class }; + final Constructor constructor = c.getConstructor(constructorArgs); + final Object[] args = new Object[] { parent, cacheSize }; + return (TmfEventsTable) constructor.newInstance(args); + + } catch (NoSuchMethodException | ClassNotFoundException | InstantiationException | + IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + return null; + } + } + } + return null; + } + + /** + * Get the Event Table columns specified by the trace type's extension + * point, if there are any. + * + * @param trace + * The trace for which we want the columns. + * @return The corresponding event table columns, or 'null' if this trace + * type did not specify any. + * @since 3.2 + */ + public static @Nullable Collection getEventTableColumns(ITmfTrace trace) { + final String traceType = getTraceType(trace); + if (traceType == null) { + return null; + } + + /* + * Custom traces are a special case : the columns are defined by the + * trace definition. + */ + if (traceType.startsWith(CustomTxtTrace.class.getCanonicalName())) { + return CustomEventTableColumns.generateColumns(((CustomTxtTrace) trace).getDefinition()); + } + if (traceType.startsWith(CustomXmlTrace.class.getCanonicalName())) { + return CustomEventTableColumns.generateColumns(((CustomXmlTrace) trace).getDefinition()); + } + + /* For all other trace types, we will go look into the extension point */ + for (final IConfigurationElement ce : TmfTraceTypeUIUtils.getTypeUIElements(TraceElementType.TRACE)) { + if (ce.getAttribute(TmfTraceTypeUIUtils.TRACETYPE_ATTR).equals(traceType)) { + final IConfigurationElement[] eventTableColumnsCE = ce.getChildren(TmfTraceTypeUIUtils.EVENT_TABLE_COLUMNS); + + if (eventTableColumnsCE.length != 1) { + break; + } + final String eventTableColumnsClass = eventTableColumnsCE[0].getAttribute(TmfTraceTypeUIUtils.CLASS_ATTR); + if ((eventTableColumnsClass == null) || (eventTableColumnsClass.isEmpty())) { + break; + } + try { + final Bundle bundle = Platform.getBundle(ce.getContributor().getName()); + final Class c = bundle.loadClass(eventTableColumnsClass); + final Constructor ctor = c.getConstructor(); + ITmfEventTableColumns cols = (ITmfEventTableColumns) ctor.newInstance(); + return cols.getEventTableColumns(); + + } catch (NoSuchMethodException | ClassNotFoundException | InstantiationException | + IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + return null; + } + } + } + return null; + } + + /** + * Get the trace type (as a String) for the given trace + * + * @param trace + * The trace object + * @return The String representing the trace type, or 'null' if this trace + * does not advertise it. + */ + private static @Nullable String getTraceType(ITmfTrace trace) { + IResource res = trace.getResource(); + if (res == null) { + return null; + } + try { + String traceType = res.getPersistentProperty(TmfCommonConstants.TRACETYPE); + /* May be null here too */ + return traceType; + + } catch (CoreException e) { + return null; + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfTracesFolder.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfTracesFolder.java new file mode 100644 index 0000000000..10dbcfc908 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfTracesFolder.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import org.eclipse.core.resources.IFolder; + +/** + * Implementation of model element representing the unique "Traces" folder in + * the project. + * + * @since 3.0 + */ +public class TmfTracesFolder extends TmfTraceFolder { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The name of the traces folder + */ + public static final String TRACES_FOLDER_NAME = "Traces"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Constructor. + * Creates folder model element under the project. + * @param name The name of trace folder. + * @param resource The folder resource. + * @param parent The parent element (project). + */ + public TmfTracesFolder(String name, IFolder resource, TmfProjectElement parent) { + super(name, resource, parent); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfViewerSorter.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfViewerSorter.java new file mode 100644 index 0000000000..5b9e182e68 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfViewerSorter.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import org.eclipse.jface.viewers.ViewerSorter; + +/** + * Viewer sorter for TMF project model elements + * + * @since 3.0 + */ +public class TmfViewerSorter extends ViewerSorter { + + @Override + public int category(Object element) { + if (element instanceof TmfExperimentFolder) { + return 0; + } + if (element instanceof TmfTraceFolder) { + return 0; + } + if (element instanceof TmfExperimentElement) { + return 1; + } + if (element instanceof TmfTraceElement) { + return 1; + } + return 2; + } + + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TraceFolderContentProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TraceFolderContentProvider.java new file mode 100644 index 0000000000..8003a2f213 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TraceFolderContentProvider.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Add support for folder elements + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.Viewer; + +/** + * Content provider implementation for trace folders for tree viewers that display + * the content of a trace folder. + *

    + * + * @version 1.0 + * @author Francois Chouinard + */ +public class TraceFolderContentProvider implements IStructuredContentProvider { + + @Override + public Object[] getElements(Object inputElement) { + if (inputElement instanceof TmfTraceFolder) { + TmfTraceFolder folder = (TmfTraceFolder) inputElement; + List elements = new ArrayList<>(); + for (TmfTraceElement trace : folder.getTraces()) { + if (trace.getTraceType() != null) { + elements.add(trace); + } + } + return elements.toArray(); + } + return null; + } + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TraceFolderLabelProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TraceFolderLabelProvider.java new file mode 100644 index 0000000000..7208d301de --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TraceFolderLabelProvider.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Add support for folder elements + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import org.eclipse.jface.viewers.LabelProvider; + +/** + * Label provider implementation for trace folders for viewers that display + * the content of a trace folder. + *

    + * + * @version 1.0 + * @author Francois Chouinard + */ +public class TraceFolderLabelProvider extends LabelProvider { + + @Override + public String getText(Object element) { + if (element instanceof TmfTraceElement) { + TmfTraceElement entry = (TmfTraceElement) element; + return entry.getElementPath(); + } + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TraceUtils.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TraceUtils.java new file mode 100644 index 0000000000..17c6fac15d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TraceUtils.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal and others + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + * Marc-Andre Laperle - Add method to get opened tmf projects + * Patrick Tasse - Add support for folder elements + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.model; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.TmfProjectNature; +import org.eclipse.ui.PlatformUI; + +/** + * Utility class for common tmf.ui functionalities + * + * @since 2.1 + */ +public class TraceUtils { + + /** + * Displays an error message in a box + * + * @param boxTitle + * The message box title + * @param errorMsg + * The error message to display + */ + public static void displayErrorMsg(final String boxTitle, final String errorMsg) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + final MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()); + mb.setText(boxTitle); + mb.setMessage(errorMsg); + mb.open(); + } + }); + } + + /** + * Get the opened (accessible) projects with Tmf nature + * + * @return the Tmf projects + * @since 2.2 + */ + public static List getOpenedTmfProjects() { + IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); + List tmfProjects = new ArrayList<>(); + for (IProject project : projects) { + try { + if (project.isAccessible() && project.getNature(TmfProjectNature.ID) != null) { + tmfProjects.add(project); + } + } catch (CoreException e) { + Activator.getDefault().logError("Error getting opened tmf projects", e); //$NON-NLS-1$ + } + } + return tmfProjects; + } + + /** + * Create a folder, ensuring all parent folders are also created. + * + * @param folder + * the folder to create + * @param monitor + * the progress monitor + * @throws CoreException + * if the folder cannot be created + * @since 3.0 + */ + public static void createFolder(IFolder folder, IProgressMonitor monitor) throws CoreException { + if (!folder.exists()) { + if (folder.getParent() instanceof IFolder) { + createFolder((IFolder) folder.getParent(), monitor); + } + folder.create(true, true, monitor); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/messages.properties new file mode 100644 index 0000000000..f931a19a6f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/messages.properties @@ -0,0 +1,49 @@ +############################################################################### +# Copyright (c) 2013, 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### + +# Environment properties dialog + +TmfAnalysisElement_InstantiateAnalysis=Instantiate analysis +TmfAnalysisViewOutput_ViewUnavailable=\ (view unavailable) +TmfAnalysisViewOutput_Title=Open analysis output +TmfCommonProjectElement_ErrorClosingEditor=Error closing editor for {0} +TmfCommonProjectElement_ErrorRefreshingProperty=Error refreshing trace type persistent property for trace {0} +TmfExperimentElement_ErrorInstantiatingTrace=Error instantiating ITmfTrace object for trace {0} +TmfExperimentElement_TypeName=Experiment +TmfTraceElement_ResourceProperties = Resource properties +TmfTraceElement_TraceProperties = Trace properties +TmfTraceElement_Name = name +TmfTraceElement_Path = path +TmfTraceElement_Location = location +TmfTraceElement_EventType = type +TmfTraceElement_IsLinked = linked +TmfTraceElement_SourceLocation = source location +TmfTraceElement_TimeOffset = time offset +TmfTraceElement_LastModified = last modified +TmfTraceElement_Size = size +TmfTraceElement_FileSizeString={0} bytes +TmfTraceElement_FolderSizeString={0} bytes in {1} files +TmfTraceElement_FolderSizeOverflowString=At least {0} bytes in more than {1} files +TmfTraceElement_TypeName=Trace +TmfTraceType_SelectTraceType=Select Trace Type + +# Open trace error messages +TmfOpenTraceHelper_ErrorOpeningElement=Error opening {0} +TmfOpenTraceHelper_LinkFailed=Link creation failed +TmfOpenTraceHelper_NoTraceTypeMatch=No trace types found to match location {0} +TmfOpenTraceHelper_OpenElement=Open {0} +TmfOpenTraceHelper_ReduceError=Something went wrong +TmfOpenTraceHelper_NoTraceType = No trace type associated to that trace\nPlease select a valid type +TmfOpenTraceHelper_NoTraceOrExperimentType=No experiment type associated to that {0}\nPlease select a valid type +TmfOpenTraceHelper_ErrorElement=Error opening {0}. +TmfOpenTraceHelper_InitError = Error initializing trace. +TmfOpenTraceHelper_TraceNotFound = Trace {0} not found. diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/CopyExperimentDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/CopyExperimentDialog.java new file mode 100644 index 0000000000..326d8550b8 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/CopyExperimentDialog.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Copied and adapted from NewFolderDialog + * Geneviève Bastien - Moved the actual copy code to model element's class + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.wizards; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.WorkspaceModifyOperation; +import org.eclipse.ui.dialogs.SelectionStatusDialog; + +/** + * Implementation of the copy experiement dialog box. + *

    + * + * @version 1.0 + * @author Francois Chouinard + */ +public class CopyExperimentDialog extends SelectionStatusDialog { + + // ------------------------------------------------------------------------ + // Members + // ------------------------------------------------------------------------ + + private final TmfExperimentElement fExperiment; + private Text fNewExperimentName; + private IFolder fExperimentFolder; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Constructor + * + * @param shell + * The parent shell + * @param experiment + * The TMF experiment model element + */ + public CopyExperimentDialog(Shell shell, TmfExperimentElement experiment) { + super(shell); + fExperiment = experiment; + TmfExperimentFolder folder = (TmfExperimentFolder) experiment.getParent(); + fExperimentFolder = folder.getResource(); + setTitle(Messages.CopyExperimentDialog_DialogTitle); + setStatusLineAboveButtons(true); + } + + // ------------------------------------------------------------------------ + // Dialog + // ------------------------------------------------------------------------ + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + composite.setLayout(new GridLayout()); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + createNewExperimentNameGroup(composite); + return composite; + } + + private void createNewExperimentNameGroup(Composite parent) { + Font font = parent.getFont(); + Composite folderGroup = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + folderGroup.setLayout(layout); + folderGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // Old experiment name label + Label oldExperimentLabel = new Label(folderGroup, SWT.NONE); + oldExperimentLabel.setFont(font); + oldExperimentLabel.setText(Messages.CopyExperimentDialog_ExperimentName); + + // Old experiment name field + Text oldExperimentName = new Text(folderGroup, SWT.BORDER); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; + oldExperimentName.setLayoutData(data); + oldExperimentName.setFont(font); + oldExperimentName.setText(fExperiment.getName()); + oldExperimentName.setEnabled(false); + + // New experiment name label + Label newExperimentLabel = new Label(folderGroup, SWT.NONE); + newExperimentLabel.setFont(font); + newExperimentLabel.setText(Messages.CopyExperimentDialog_ExperimentNewName); + + // New experiment name entry field + fNewExperimentName = new Text(folderGroup, SWT.BORDER); + data = new GridData(GridData.FILL_HORIZONTAL); + data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; + fNewExperimentName.setLayoutData(data); + fNewExperimentName.setFont(font); + fNewExperimentName.addListener(SWT.Modify, new Listener() { + @Override + public void handleEvent(Event event) { + validateNewExperimentName(); + } + }); + } + + private void validateNewExperimentName() { + + String name = fNewExperimentName.getText(); + IWorkspace workspace = fExperimentFolder.getWorkspace(); + IStatus nameStatus = workspace.validateName(name, IResource.FOLDER); + + if ("".equals(name)) { //$NON-NLS-1$ + updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.Dialog_EmptyNameError, null)); + return; + } + + if (!nameStatus.isOK()) { + updateStatus(nameStatus); + return; + } + + IPath path = new Path(name); + if (fExperimentFolder.getFolder(path).exists() || fExperimentFolder.getFile(path).exists()) { + updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.Dialog_ExistingNameError, null)); + return; + } + + updateStatus(new Status(IStatus.OK, Activator.PLUGIN_ID, "")); //$NON-NLS-1$ + } + + // ------------------------------------------------------------------------ + // SelectionStatusDialog + // ------------------------------------------------------------------------ + + @Override + protected void computeResult() { + } + + @Override + public void create() { + super.create(); + getButton(IDialogConstants.OK_ID).setEnabled(false); + } + + @Override + protected void okPressed() { + IFolder folder = copyExperiment(fNewExperimentName.getText()); + if (folder == null) { + return; + } + setSelectionResult(new IFolder[] { folder }); + super.okPressed(); + } + + private IFolder copyExperiment(final String newName) { + + WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { + @Override + public void execute(IProgressMonitor monitor) throws CoreException { + try { + monitor.beginTask("", 1000); //$NON-NLS-1$ + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + + fExperiment.copy(newName, true); + + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + } finally { + monitor.done(); + } + } + }; + try { + PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); + } catch (InterruptedException exception) { + return null; + } catch (InvocationTargetException exception) { + MessageDialog.openError(getShell(), "", NLS.bind("", exception.getTargetException().getMessage())); //$NON-NLS-1$ //$NON-NLS-2$ + return null; + } catch (RuntimeException exception) { + return null; + } + + return fExperiment.getResource(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/CopyTraceDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/CopyTraceDialog.java new file mode 100644 index 0000000000..300ae02eef --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/CopyTraceDialog.java @@ -0,0 +1,223 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Copied and adapted from NewFolderDialog + * Geneviève Bastien - Moved the actual copy code to model element's class + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.wizards; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.WorkspaceModifyOperation; +import org.eclipse.ui.dialogs.SelectionStatusDialog; + +/** + * Implementation of the copy trace dialog box. + *

    + * @version 1.0 + * @author Francois Chouinard + */ +public class CopyTraceDialog extends SelectionStatusDialog { + + // ------------------------------------------------------------------------ + // Members + // ------------------------------------------------------------------------ + + private final TmfTraceElement fTrace; + private Text fNewTraceName; + private final IFolder fTraceFolder; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + /** + * Constructor. + * @param shell The parent shell + * @param trace The trace model element. + */ + public CopyTraceDialog(Shell shell, TmfTraceElement trace) { + super(shell); + fTrace = trace; + TmfTraceFolder folder = (TmfTraceFolder) trace.getParent(); + fTraceFolder = folder.getResource(); + setTitle(Messages.CopyTraceDialog_DialogTitle); + setStatusLineAboveButtons(true); + } + + // ------------------------------------------------------------------------ + // Dialog + // ------------------------------------------------------------------------ + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + composite.setLayout(new GridLayout()); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + createNewTraceNameGroup(composite); + return composite; + } + + private void createNewTraceNameGroup(Composite parent) { + Font font = parent.getFont(); + Composite folderGroup = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + folderGroup.setLayout(layout); + folderGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // Old trace name label + Label oldTraceLabel = new Label(folderGroup, SWT.NONE); + oldTraceLabel.setFont(font); + oldTraceLabel.setText(Messages.CopyTraceDialog_TraceName); + + // Old trace name field + Text oldTraceName = new Text(folderGroup, SWT.BORDER); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; + oldTraceName.setLayoutData(data); + oldTraceName.setFont(font); + oldTraceName.setText(fTrace.getName()); + oldTraceName.setEnabled(false); + + // New trace name label + Label newTraceLabel = new Label(folderGroup, SWT.NONE); + newTraceLabel.setFont(font); + newTraceLabel.setText(Messages.CopyTraceDialog_TraceNewName); + + // New trace name entry field + fNewTraceName = new Text(folderGroup, SWT.BORDER); + data = new GridData(GridData.FILL_HORIZONTAL); + data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; + fNewTraceName.setLayoutData(data); + fNewTraceName.setFont(font); + fNewTraceName.addListener(SWT.Modify, new Listener() { + @Override + public void handleEvent(Event event) { + validateNewTraceName(); + } + }); + } + + private void validateNewTraceName() { + + String name = fNewTraceName.getText(); + IWorkspace workspace = fTraceFolder.getWorkspace(); + IStatus nameStatus = workspace.validateName(name, IResource.FOLDER); + + if ("".equals(name)) { //$NON-NLS-1$ + updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, + Messages.Dialog_EmptyNameError, null)); + return; + } + + if (!nameStatus.isOK()) { + updateStatus(nameStatus); + return; + } + + IPath path = new Path(name); + if (fTraceFolder.getFolder(path).exists() || fTraceFolder.getFile(path).exists()) { + updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, + Messages.Dialog_ExistingNameError, null)); + return; + } + + updateStatus(new Status(IStatus.OK, Activator.PLUGIN_ID, "")); //$NON-NLS-1$ + } + + // ------------------------------------------------------------------------ + // SelectionStatusDialog + // ------------------------------------------------------------------------ + + @Override + protected void computeResult() { + } + + @Override + public void create() { + super.create(); + getButton(IDialogConstants.OK_ID).setEnabled(false); + } + + @Override + protected void okPressed() { + IResource trace = copyTrace(fNewTraceName.getText()); + if (trace == null) { + return; + } + setSelectionResult(new IResource[] { trace }); + super.okPressed(); + } + + private IResource copyTrace(final String newName) { + + WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { + @Override + public void execute(IProgressMonitor monitor) throws CoreException { + try { + monitor.beginTask("", 1000); //$NON-NLS-1$ + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + fTrace.copy(newName, true); + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + } finally { + monitor.done(); + } + } + }; + + try { + PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); + } catch (InterruptedException exception) { + return null; + } catch (InvocationTargetException exception) { + MessageDialog.openError(getShell(), "", NLS.bind("", exception.getTargetException().getMessage())); //$NON-NLS-1$ //$NON-NLS-2$ + return null; + } catch (RuntimeException exception) { + return null; + } + + return fTrace.getResource(); + + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/Messages.java new file mode 100644 index 0000000000..3b3b924821 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/Messages.java @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Patrick Tasse - Add support for folder elements + * Marc-Andre Laperle - Preserve folder structure on import + * Bernd Hufmann - Extract ImportTraceWizard messages + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.wizards; + +import org.eclipse.osgi.util.NLS; + +/** + * Message strings for TMF model handling. + * + * @version 1.0 + * @author Francois Chouinard + */ +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.ui.project.wizards.messages"; //$NON-NLS-1$ + + /** + * The dialog header of the new project wizard + */ + public static String NewProjectWizard_DialogHeader; + /** + * The dialog message of the new project wizard + */ + public static String NewProjectWizard_DialogMessage; + /** + * The title of the select traces wizard. + */ + public static String SelectTracesWizard_WindowTitle; + /** + * The column header for the traces (select traces wizard page). + */ + public static String SelectTracesWizardPage_TraceColumnHeader; + /** + * The title of select traces wizard page. + */ + public static String SelectTracesWizardPage_WindowTitle; + /** + * The description of the select traces wizard page. + */ + public static String SelectTracesWizardPage_Description; + /** + * The error message when selecting of traces for an experiment fails. + * @since 3.1 + */ + public static String SelectTracesWizardPage_SelectionError; + /** + * The task name for selecting of a trace for an experiment. + * @since 3.1 + */ + public static String SelectTracesWizardPage_TraceSelectionTask; + /** + * The task name for removing of a trace for an experiment. + * @since 3.1 + */ + public static String SelectTracesWizardPage_TraceRemovalTask; + /** + * The cancel message for the trace selection operation. + * @since 3.1 + */ + public static String SelectTracesWizardPage_SelectionOperationCancelled; + /** + * The error message title. + * @since 3.1 + */ + public static String SelectTracesWizardPage_InternalErrorTitle; + /** + * The error message when no name was entered in a dialog box (new trace or experiment dialog) + */ + public static String Dialog_EmptyNameError; + /** + * The error message when name of trace or experiment already exists + */ + public static String Dialog_ExistingNameError; + /** + * The title of the new experiment dialog. + */ + public static String NewExperimentDialog_DialogTitle; + /** + * The label of the new experiment name field. + */ + public static String NewExperimentDialog_ExperimentName; + /** + * The title of the rename experiment dialog. + */ + public static String RenameExperimentDialog_DialogTitle; + /** + * The label of the field of the current experiment name. + */ + public static String RenameExperimentDialog_ExperimentName; + /** + * The label of the field for entering the new experiment name. + */ + public static String RenameExperimentDialog_ExperimentNewName; + /** + * The title of the copy experiment dialog. + */ + public static String CopyExperimentDialog_DialogTitle; + /** + * The label of the field of the current experiment name. + */ + public static String CopyExperimentDialog_ExperimentName; + /** + * The label of the field for entering the new experiment name. + */ + public static String CopyExperimentDialog_ExperimentNewName; + /** + * The title of the rename trace dialog. + */ + public static String RenameTraceDialog_DialogTitle; + /** + * The label of the field of the current trace name. + */ + public static String RenameTraceDialog_TraceName; + /** + * The label of the field for entering the new trace name. + */ + public static String RenameTraceDialog_TraceNewName; + /** + * The title of the copy trace dialog. + */ + public static String CopyTraceDialog_DialogTitle; + /** + * The label of the field of the current trace name. + */ + public static String CopyTraceDialog_TraceName; + /** + * The label of the field for entering the new trace name. + */ + public static String CopyTraceDialog_TraceNewName; + /** + * The title of the new folder dialog. + * @since 3.0 + */ + public static String NewFolderDialog_DialogTitle; + /** + * The label of the new folder name field. + * @since 3.0 + */ + public static String NewFolderDialog_FolderName; + /** + * The title of the rename folder dialog. + * @since 3.0 + */ + public static String RenameFolderDialog_DialogTitle; + /** + * The label of the field of the current folder name. + * @since 3.0 + */ + public static String RenameFolderDialog_FolderName; + /** + * The label of the field for entering the new folder name. + * @since 3.0 + */ + public static String RenameFolderDialog_FolderNewName; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/NewExperimentDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/NewExperimentDialog.java new file mode 100644 index 0000000000..3b6088c32a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/NewExperimentDialog.java @@ -0,0 +1,231 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Copied and adapted from NewFolderDialog + * Geneviève Bastien - Add support of experiment types + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.wizards; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.InvalidRegistryObjectException; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.WorkspaceModifyOperation; +import org.eclipse.ui.dialogs.SelectionStatusDialog; + +/** + * Implementation of new experiment dialog that creates the experiment element. + *

    + * + * @version 1.0 + * @author Francois Chouinard + */ +public class NewExperimentDialog extends SelectionStatusDialog { + + // ------------------------------------------------------------------------ + // Members + // ------------------------------------------------------------------------ + + private Text fExperimentName; + private final IContainer fExperimentFolder; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + /** + * Constructor + * + * @param shell + * The parent shell + * @param experimentFolder + * The parent experiment folder element + */ + public NewExperimentDialog(Shell shell, TmfExperimentFolder experimentFolder) { + super(shell); + fExperimentFolder = experimentFolder.getResource(); + setTitle(Messages.NewExperimentDialog_DialogTitle); + setStatusLineAboveButtons(true); + } + + // ------------------------------------------------------------------------ + // Dialog + // ------------------------------------------------------------------------ + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + composite.setLayout(new GridLayout()); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + createExperimentNameGroup(composite); + return composite; + } + + private void createExperimentNameGroup(Composite parent) { + Font font = parent.getFont(); + Composite folderGroup = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + folderGroup.setLayout(layout); + folderGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // New experiment label + Label experimentLabel = new Label(folderGroup, SWT.NONE); + experimentLabel.setFont(font); + experimentLabel.setText(Messages.NewExperimentDialog_ExperimentName); + + // New experiment name entry field + fExperimentName = new Text(folderGroup, SWT.BORDER); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; + fExperimentName.setLayoutData(data); + fExperimentName.setFont(font); + fExperimentName.addListener(SWT.Modify, new Listener() { + @Override + public void handleEvent(Event event) { + validateNewExperimentName(); + } + }); + } + + private void validateNewExperimentName() { + + String name = fExperimentName.getText(); + IWorkspace workspace = fExperimentFolder.getWorkspace(); + IStatus nameStatus = workspace.validateName(name, IResource.FOLDER); + + if ("".equals(name)) { //$NON-NLS-1$ + updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.Dialog_EmptyNameError, null)); + return; + } + + if (!nameStatus.isOK()) { + updateStatus(nameStatus); + return; + } + + IPath path = new Path(name); + if (fExperimentFolder.getFolder(path).exists() || fExperimentFolder.getFile(path).exists()) { + updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.Dialog_ExistingNameError, null)); + return; + } + + updateStatus(new Status(IStatus.OK, Activator.PLUGIN_ID, "")); //$NON-NLS-1$ + } + + // ------------------------------------------------------------------------ + // SelectionStatusDialog + // ------------------------------------------------------------------------ + + @Override + protected void computeResult() { + } + + @Override + public void create() { + super.create(); + getButton(IDialogConstants.OK_ID).setEnabled(false); + } + + @Override + protected void okPressed() { + IFolder folder = createNewExperiment(fExperimentName.getText()); + if (folder == null) { + return; + } + setSelectionResult(new IFolder[] { folder }); + super.okPressed(); + } + + private IFolder createNewExperiment(String experimentName) { + + final IFolder experimentFolder = createExperiment(experimentName); + + WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { + @Override + public void execute(IProgressMonitor monitor) throws CoreException { + try { + monitor.beginTask("", 1000); //$NON-NLS-1$ + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + experimentFolder.create(false, true, monitor); + + /* + * Experiments can be set to the default experiment type. No + * need to force user to select an experiment type + */ + IConfigurationElement ce = TmfTraceType.getTraceAttributes(TmfTraceType.DEFAULT_EXPERIMENT_TYPE); + if (ce != null) { + try { + experimentFolder.setPersistentProperty(TmfCommonConstants.TRACETYPE, ce.getAttribute(TmfTraceType.ID_ATTR)); + } catch (InvalidRegistryObjectException | CoreException e) { + } + } + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + } finally { + monitor.done(); + } + } + }; + try { + PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); + } catch (InterruptedException | RuntimeException exception) { + return null; + } catch (InvocationTargetException exception) { + MessageDialog.openError(getShell(), "", NLS.bind("", exception.getTargetException().getMessage())); //$NON-NLS-1$ //$NON-NLS-2$ + return null; + } + + return experimentFolder; + } + + private IFolder createExperiment(String experimentName) { + IWorkspaceRoot workspaceRoot = fExperimentFolder.getWorkspace().getRoot(); + IPath folderPath = fExperimentFolder.getFullPath().append(experimentName); + IFolder folder = workspaceRoot.getFolder(folderPath); + + return folder; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/NewFolderDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/NewFolderDialog.java new file mode 100644 index 0000000000..0e90069dad --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/NewFolderDialog.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.wizards; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.WorkspaceModifyOperation; +import org.eclipse.ui.dialogs.SelectionStatusDialog; + +/** + * Implementation of new folder dialog that creates the folder element. + * @since 3.0 + */ +public class NewFolderDialog extends SelectionStatusDialog { + + // ------------------------------------------------------------------------ + // Members + // ------------------------------------------------------------------------ + + private Text fFolderName; + private final IFolder fParentFolder; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + /** + * Constructor + * + * @param shell + * The parent shell + * @param parent + * The parent trace folder + */ + public NewFolderDialog(Shell shell, TmfTraceFolder parent) { + super(shell); + fParentFolder = parent.getResource(); + setTitle(Messages.NewFolderDialog_DialogTitle); + setStatusLineAboveButtons(true); + } + + // ------------------------------------------------------------------------ + // Dialog + // ------------------------------------------------------------------------ + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + composite.setLayout(new GridLayout()); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + createFolderNameGroup(composite); + return composite; + } + + private void createFolderNameGroup(Composite parent) { + Font font = parent.getFont(); + Composite folderGroup = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + folderGroup.setLayout(layout); + folderGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // New folder label + Label folderLabel = new Label(folderGroup, SWT.NONE); + folderLabel.setFont(font); + folderLabel.setText(Messages.NewFolderDialog_FolderName); + + // New folder name entry field + fFolderName = new Text(folderGroup, SWT.BORDER); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; + fFolderName.setLayoutData(data); + fFolderName.setFont(font); + fFolderName.addListener(SWT.Modify, new Listener() { + @Override + public void handleEvent(Event event) { + validateNewFolderName(); + } + }); + } + + private void validateNewFolderName() { + + String name = fFolderName.getText(); + IWorkspace workspace = fParentFolder.getWorkspace(); + IStatus nameStatus = workspace.validateName(name, IResource.FOLDER); + + if ("".equals(name)) { //$NON-NLS-1$ + updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.Dialog_EmptyNameError, null)); + return; + } + + if (!nameStatus.isOK()) { + updateStatus(nameStatus); + return; + } + + if (fParentFolder.findMember(name) != null) { + updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.Dialog_ExistingNameError, null)); + return; + } + + updateStatus(new Status(IStatus.OK, Activator.PLUGIN_ID, "")); //$NON-NLS-1$ + } + + // ------------------------------------------------------------------------ + // SelectionStatusDialog + // ------------------------------------------------------------------------ + + @Override + protected void computeResult() { + } + + @Override + public void create() { + super.create(); + getButton(IDialogConstants.OK_ID).setEnabled(false); + } + + @Override + protected void okPressed() { + IFolder folder = createNewFolder(fFolderName.getText()); + if (folder == null) { + return; + } + setSelectionResult(new IFolder[] { folder }); + super.okPressed(); + } + + private IFolder createNewFolder(String folderName) { + + final IFolder folder = fParentFolder.getFolder(new Path(folderName)); + + WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { + @Override + public void execute(IProgressMonitor monitor) throws CoreException { + try { + monitor.beginTask("", 1000); //$NON-NLS-1$ + folder.create(false, true, monitor); + } finally { + monitor.done(); + } + } + }; + try { + PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); + } catch (InterruptedException | RuntimeException exception) { + return null; + } catch (InvocationTargetException exception) { + MessageDialog.openError(getShell(), "", NLS.bind("", exception.getTargetException().getMessage())); //$NON-NLS-1$ //$NON-NLS-2$ + return null; + } + + return folder; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/NewTmfProjectMainWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/NewTmfProjectMainWizardPage.java new file mode 100644 index 0000000000..6180c005c0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/NewTmfProjectMainWizardPage.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2009, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.wizards; + +import org.eclipse.ui.dialogs.WizardNewProjectCreationPage; + +/** + * The wizard page for creation of a new TMF tracing project. + *

    + * @version 1.0 + * @author Francois Chouinard + + */ +public class NewTmfProjectMainWizardPage extends WizardNewProjectCreationPage { + + /** + * Constructor + * + * @param pageName + * The name of this wizard page + */ + public NewTmfProjectMainWizardPage(String pageName) { + super(pageName); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/NewTmfProjectWizard.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/NewTmfProjectWizard.java new file mode 100644 index 0000000000..a2bb635922 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/NewTmfProjectWizard.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Moved project creation utility method to TmfProjectRegistry + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.wizards; + +import java.net.URI; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExecutableExtension; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry; +import org.eclipse.ui.INewWizard; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.wizards.newresource.BasicNewProjectResourceWizard; + +/** + * Wizard implementation for creating a TMF tracing project. + * + * @version 1.0 + * @author Francois Chouinard + */ +public class NewTmfProjectWizard extends Wizard implements INewWizard, IExecutableExtension { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The wizard id + * + * @since 2.0 + */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.ui.wizards.newProject"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final String fTtitle; + private final String fDescription; + + /** + * Wizard main page + */ + protected NewTmfProjectMainWizardPage fMainPage; + + /** + * The Project name + */ + protected String fProjectName; + + /** + * The project location + */ + + protected URI fProjectLocation; + + /** + * The configuration element. + */ + protected IConfigurationElement fConfigElement; + + /** + * The project reference + */ + protected IProject fProject; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + public NewTmfProjectWizard() { + this(Messages.NewProjectWizard_DialogHeader, Messages.NewProjectWizard_DialogMessage); + } + + /** + * Constructor + * @param title The tile string + * @param desc The description string + */ + public NewTmfProjectWizard(String title, String desc) { + super(); + setDialogSettings(Activator.getDefault().getDialogSettings()); + setNeedsProgressMonitor(true); + setForcePreviousAndNextButtons(true); + setWindowTitle(title); + fTtitle = title; + fDescription = desc; + } + + // ------------------------------------------------------------------------ + // Wizard + // ------------------------------------------------------------------------ + + @Override + public void addPages() { + fMainPage = new NewTmfProjectMainWizardPage(Messages.NewProjectWizard_DialogHeader); + fMainPage.setTitle(fTtitle); + fMainPage.setDescription(fDescription); + addPage(fMainPage); + } + + @Override + public boolean performCancel() { + return true; + } + + @Override + public boolean performFinish() { + fProjectName = fMainPage.getProjectName(); + fProjectLocation = fMainPage.useDefaults() ? null : fMainPage.getLocationURI(); + fProject = TmfProjectRegistry.createProject(fProjectName, fProjectLocation, new NullProgressMonitor()); + BasicNewProjectResourceWizard.updatePerspective(fConfigElement); + return true; + } + + // ------------------------------------------------------------------------ + // INewWizard + // ------------------------------------------------------------------------ + + @Override + public void init(IWorkbench iworkbench, IStructuredSelection istructuredselection) { + } + + // ------------------------------------------------------------------------ + // IExecutableExtension + // ------------------------------------------------------------------------ + + @Override + public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException { + fConfigElement = config; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/RenameExperimentDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/RenameExperimentDialog.java new file mode 100644 index 0000000000..ea71ac5179 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/RenameExperimentDialog.java @@ -0,0 +1,242 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Copied and adapted from NewFolderDialog + * Patrick Tasse - Close editors to release resources + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.wizards; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.WorkspaceModifyOperation; +import org.eclipse.ui.dialogs.SelectionStatusDialog; + +/** + * Implementation of a dialog box to rename an experiment. + *

    + * + * @version 1.0 + * @author Francois Chouinard + */ +public class RenameExperimentDialog extends SelectionStatusDialog { + + // ------------------------------------------------------------------------ + // Members + // ------------------------------------------------------------------------ + + private final TmfExperimentElement fExperiment; + private Text fNewExperimentName; + private final IContainer fExperimentFolder; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Constructor + * + * @param shell + * The parent shell + * @param experiment + * The experiment element rename + */ + public RenameExperimentDialog(Shell shell, TmfExperimentElement experiment) { + super(shell); + fExperiment = experiment; + TmfExperimentFolder folder = (TmfExperimentFolder) experiment.getParent(); + fExperimentFolder = folder.getResource(); + setTitle(Messages.RenameExperimentDialog_DialogTitle); + setStatusLineAboveButtons(true); + } + + // ------------------------------------------------------------------------ + // Dialog + // ------------------------------------------------------------------------ + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + composite.setLayout(new GridLayout()); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + createNewExperimentNameGroup(composite); + return composite; + } + + private void createNewExperimentNameGroup(Composite parent) { + Font font = parent.getFont(); + Composite folderGroup = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + folderGroup.setLayout(layout); + folderGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // Old experiment name label + Label oldExperimentLabel = new Label(folderGroup, SWT.NONE); + oldExperimentLabel.setFont(font); + oldExperimentLabel.setText(Messages.RenameExperimentDialog_ExperimentName); + + // Old experiment name field + Text oldExperimentName = new Text(folderGroup, SWT.BORDER); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; + oldExperimentName.setLayoutData(data); + oldExperimentName.setFont(font); + oldExperimentName.setText(fExperiment.getName()); + oldExperimentName.setEnabled(false); + + // New experiment name label + Label newExperimentLabel = new Label(folderGroup, SWT.NONE); + newExperimentLabel.setFont(font); + newExperimentLabel.setText(Messages.RenameExperimentDialog_ExperimentNewName); + + // New experiment name entry field + fNewExperimentName = new Text(folderGroup, SWT.BORDER); + data = new GridData(GridData.FILL_HORIZONTAL); + data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; + fNewExperimentName.setLayoutData(data); + fNewExperimentName.setFont(font); + fNewExperimentName.addListener(SWT.Modify, new Listener() { + @Override + public void handleEvent(Event event) { + validateNewExperimentName(); + } + }); + } + + private void validateNewExperimentName() { + + String name = fNewExperimentName.getText(); + IWorkspace workspace = fExperimentFolder.getWorkspace(); + IStatus nameStatus = workspace.validateName(name, IResource.FOLDER); + + if ("".equals(name)) { //$NON-NLS-1$ + updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.Dialog_EmptyNameError, null)); + return; + } + + if (!nameStatus.isOK()) { + updateStatus(nameStatus); + return; + } + + IPath path = new Path(name); + if (fExperimentFolder.getFolder(path).exists() || fExperimentFolder.getFile(path).exists()) { + updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.Dialog_ExistingNameError, null)); + return; + } + + updateStatus(new Status(IStatus.OK, Activator.PLUGIN_ID, "")); //$NON-NLS-1$ + } + + // ------------------------------------------------------------------------ + // SelectionStatusDialog + // ------------------------------------------------------------------------ + + @Override + protected void computeResult() { + } + + @Override + public void create() { + super.create(); + getButton(IDialogConstants.OK_ID).setEnabled(false); + } + + @Override + protected void okPressed() { + IFolder folder = renameExperiment(fNewExperimentName.getText()); + if (folder == null) { + return; + } + setSelectionResult(new IFolder[] { folder }); + super.okPressed(); + } + + private IFolder renameExperiment(final String newName) { + + IPath oldPath = fExperiment.getResource().getFullPath(); + final IPath newPath = oldPath.append("../" + newName); //$NON-NLS-1$ + + WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { + @Override + public void execute(IProgressMonitor monitor) throws CoreException { + try { + monitor.beginTask("", 1000); //$NON-NLS-1$ + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + // Close the experiment if open + fExperiment.closeEditors(); + + IFolder folder = fExperiment.getResource(); + IFile bookmarksFile = fExperiment.getBookmarksFile(); + IFile newBookmarksFile = folder.getFile(bookmarksFile.getName().replace(fExperiment.getName(), newName)); + if (bookmarksFile.exists()) { + if (!newBookmarksFile.exists()) { + IPath newBookmarksPath = newBookmarksFile.getFullPath(); + bookmarksFile.move(newBookmarksPath, IResource.FORCE | IResource.SHALLOW, null); + } + } + + fExperiment.renameSupplementaryFolder(newName); + fExperiment.getResource().move(newPath, IResource.FORCE | IResource.SHALLOW, null); + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + } finally { + monitor.done(); + } + } + }; + try { + PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation); + } catch (InterruptedException exception) { + return null; + } catch (InvocationTargetException exception) { + MessageDialog.openError(getShell(), "", exception.getTargetException().getMessage()); //$NON-NLS-1$ + return null; + } catch (RuntimeException exception) { + return null; + } + + return fExperiment.getResource(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/RenameFolderDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/RenameFolderDialog.java new file mode 100644 index 0000000000..3c5bb9582e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/RenameFolderDialog.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.wizards; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.ui.dialogs.SelectionStatusDialog; + +/** + * Implementation of a dialog box to rename a folder. + * @since 3.0 + */ +public class RenameFolderDialog extends SelectionStatusDialog { + + // ------------------------------------------------------------------------ + // Members + // ------------------------------------------------------------------------ + + private final TmfTraceFolder fFolder; + private Text fNewFolderNameText; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Constructor + * @param shell The parent shell + * @param folder The trace element to rename + */ + public RenameFolderDialog(Shell shell, TmfTraceFolder folder) { + super(shell); + fFolder = folder; + setTitle(Messages.RenameFolderDialog_DialogTitle); + setStatusLineAboveButtons(true); + } + + // ------------------------------------------------------------------------ + // Dialog + // ------------------------------------------------------------------------ + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + composite.setLayout(new GridLayout()); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + createNewTraceNameGroup(composite); + return composite; + } + + private void createNewTraceNameGroup(Composite parent) { + Font font = parent.getFont(); + Composite folderGroup = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + folderGroup.setLayout(layout); + folderGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // Old trace name label + Label oldTraceLabel = new Label(folderGroup, SWT.NONE); + oldTraceLabel.setFont(font); + oldTraceLabel.setText(Messages.RenameFolderDialog_FolderName); + + // Old trace name field + Text oldTraceName = new Text(folderGroup, SWT.BORDER); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; + oldTraceName.setLayoutData(data); + oldTraceName.setFont(font); + oldTraceName.setText(fFolder.getName()); + oldTraceName.setEnabled(false); + + // New trace name label + Label newTaceLabel = new Label(folderGroup, SWT.NONE); + newTaceLabel.setFont(font); + newTaceLabel.setText(Messages.RenameFolderDialog_FolderNewName); + + // New trace name entry field + fNewFolderNameText = new Text(folderGroup, SWT.BORDER); + data = new GridData(GridData.FILL_HORIZONTAL); + data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; + fNewFolderNameText.setLayoutData(data); + fNewFolderNameText.setFont(font); + fNewFolderNameText.addListener(SWT.Modify, new Listener() { + @Override + public void handleEvent(Event event) { + validateNewFolderName(); + } + }); + } + + private void validateNewFolderName() { + + String newFolderName = fNewFolderNameText.getText(); + IWorkspace workspace = fFolder.getResource().getWorkspace(); + IStatus nameStatus = workspace.validateName(newFolderName, IResource.FOLDER); + + if ("".equals(newFolderName)) { //$NON-NLS-1$ + updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, + Messages.Dialog_EmptyNameError, null)); + return; + } + + if (!nameStatus.isOK()) { + updateStatus(nameStatus); + return; + } + + IContainer parentFolder = fFolder.getResource().getParent(); + if (parentFolder.findMember(newFolderName) != null) { + updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, + Messages.Dialog_ExistingNameError, null)); + return; + } + + updateStatus(new Status(IStatus.OK, Activator.PLUGIN_ID, "")); //$NON-NLS-1$ + } + + // ------------------------------------------------------------------------ + // SelectionStatusDialog + // ------------------------------------------------------------------------ + + @Override + protected void computeResult() { + } + + @Override + public void create() { + super.create(); + getButton(IDialogConstants.OK_ID).setEnabled(false); + } + + @Override + protected void okPressed() { + setSelectionResult(new String[] { fNewFolderNameText.getText() }); + super.okPressed(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/RenameTraceDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/RenameTraceDialog.java new file mode 100644 index 0000000000..e6138ee9f6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/RenameTraceDialog.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Copied and adapted from NewFolderDialog + * Patrick Tasse - Close editors to release resources + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.wizards; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.ui.dialogs.SelectionStatusDialog; + +/** + * Implementation of a dialog box to rename a trace. + *

    + * @version 1.0 + * @author Francois Chouinard + */ +public class RenameTraceDialog extends SelectionStatusDialog { + + // ------------------------------------------------------------------------ + // Members + // ------------------------------------------------------------------------ + + private final TmfTraceElement fTrace; + private Text fNewTraceNameText; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + /** + * Constructor + * @param shell The parent shell + * @param trace The trace element to rename + */ + public RenameTraceDialog(Shell shell, TmfTraceElement trace) { + super(shell); + fTrace = trace; + setTitle(Messages.RenameTraceDialog_DialogTitle); + setStatusLineAboveButtons(true); + } + + // ------------------------------------------------------------------------ + // Dialog + // ------------------------------------------------------------------------ + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + composite.setLayout(new GridLayout()); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + createNewTraceNameGroup(composite); + return composite; + } + + private void createNewTraceNameGroup(Composite parent) { + Font font = parent.getFont(); + Composite folderGroup = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + folderGroup.setLayout(layout); + folderGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // Old trace name label + Label oldTraceLabel = new Label(folderGroup, SWT.NONE); + oldTraceLabel.setFont(font); + oldTraceLabel.setText(Messages.RenameTraceDialog_TraceName); + + // Old trace name field + Text oldTraceName = new Text(folderGroup, SWT.BORDER); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; + oldTraceName.setLayoutData(data); + oldTraceName.setFont(font); + oldTraceName.setText(fTrace.getName()); + oldTraceName.setEnabled(false); + + // New trace name label + Label newTaceLabel = new Label(folderGroup, SWT.NONE); + newTaceLabel.setFont(font); + newTaceLabel.setText(Messages.RenameTraceDialog_TraceNewName); + + // New trace name entry field + fNewTraceNameText = new Text(folderGroup, SWT.BORDER); + data = new GridData(GridData.FILL_HORIZONTAL); + data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; + fNewTraceNameText.setLayoutData(data); + fNewTraceNameText.setFont(font); + fNewTraceNameText.addListener(SWT.Modify, new Listener() { + @Override + public void handleEvent(Event event) { + validateNewTraceName(); + } + }); + } + + private void validateNewTraceName() { + + String newTraceName = fNewTraceNameText.getText(); + IWorkspace workspace = fTrace.getResource().getWorkspace(); + IStatus nameStatus = workspace.validateName(newTraceName, IResource.FOLDER); + + if ("".equals(newTraceName)) { //$NON-NLS-1$ + updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, + Messages.Dialog_EmptyNameError, null)); + return; + } + + if (!nameStatus.isOK()) { + updateStatus(nameStatus); + return; + } + + IContainer parentFolder = fTrace.getResource().getParent(); + if (parentFolder.findMember(newTraceName) != null) { + updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, + Messages.Dialog_ExistingNameError, null)); + return; + } + + updateStatus(new Status(IStatus.OK, Activator.PLUGIN_ID, "")); //$NON-NLS-1$ + } + + // ------------------------------------------------------------------------ + // SelectionStatusDialog + // ------------------------------------------------------------------------ + + @Override + protected void computeResult() { + } + + @Override + public void create() { + super.create(); + getButton(IDialogConstants.OK_ID).setEnabled(false); + } + + @Override + protected void okPressed() { + setSelectionResult(new String[] { fNewTraceNameText.getText() }); + super.okPressed(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectTracesWizard.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectTracesWizard.java new file mode 100644 index 0000000000..4638c869c2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectTracesWizard.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.wizards; + +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; +import org.eclipse.ui.IImportWizard; +import org.eclipse.ui.IWorkbench; + +/** + * Wizard implementation to select traces for an experiment. + *

    + * @version 1.0 + * @author Francois Chouinard + */ +public class SelectTracesWizard extends Wizard implements IImportWizard { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final TmfProjectElement fProject; + private final TmfExperimentElement fExperiment; + private SelectTracesWizardPage fSelectTraceWizardPage; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Constructor + * @param project The project model element + * @param experiment The experiemnt model element + */ + public SelectTracesWizard(TmfProjectElement project, TmfExperimentElement experiment) { + fProject = project; + fExperiment = experiment; + } + + // ------------------------------------------------------------------------ + // Wizard + // ------------------------------------------------------------------------ + + @Override + public void init(IWorkbench workbench, IStructuredSelection selection) { + setWindowTitle(Messages.SelectTracesWizard_WindowTitle); + setNeedsProgressMonitor(true); + } + + @Override + public void addPages() { + super.addPages(); + fSelectTraceWizardPage = new SelectTracesWizardPage(fProject, fExperiment); + addPage(fSelectTraceWizardPage); + } + + @Override + public boolean performFinish() { + return fSelectTraceWizardPage.performFinish(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectTracesWizardPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectTracesWizardPage.java new file mode 100644 index 0000000000..b8aaa926f2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/SelectTracesWizardPage.java @@ -0,0 +1,477 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Geneviève Bastien - Moved the add and remove code to the experiment class + * Patrick Tasse - Add support for folder elements + * Marc-Andre Laperle - Convert to tree structure and add select/deselect all + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.project.wizards; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Vector; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.operation.ModalContext; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTreeViewer; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; +import org.eclipse.tracecompass.tmf.ui.project.model.ITmfProjectModelElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfNavigatorContentProvider; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfNavigatorLabelProvider; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; +import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; +import org.eclipse.ui.dialogs.FilteredTree; +import org.eclipse.ui.dialogs.PatternFilter; + +/** + * Implementation of a wizard page for selecting trace for an experiment. + *

    + * + * @version 1.0 + * @author Francois Chouinard + */ +public class SelectTracesWizardPage extends WizardPage { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final TmfProjectElement fProject; + private final TmfExperimentElement fExperiment; + private Map fPreviousTraces; + private CheckboxTreeViewer fCheckboxTreeViewer; + private TmfNavigatorContentProvider fContentProvider; + private TmfNavigatorLabelProvider fLabelProvider; + + private static final int COLUMN_WIDTH = 200; + private static final int BUTTON_SPACING = 4; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + /** + * Constructor + * + * @param project + * The project model element. + * @param experiment + * The experiment model experiment. + */ + protected SelectTracesWizardPage(TmfProjectElement project, TmfExperimentElement experiment) { + super(""); //$NON-NLS-1$ + setTitle(Messages.SelectTracesWizardPage_WindowTitle); + setDescription(Messages.SelectTracesWizardPage_Description); + fProject = project; + fExperiment = experiment; + } + + // ------------------------------------------------------------------------ + // Dialog + // ------------------------------------------------------------------------ + + @Override + public void createControl(Composite parent) { + Composite container = new Composite(parent, SWT.NULL); + container.setLayout(new GridLayout(2, false)); + setControl(container); + + new FilteredTree(container, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, new PatternFilter(), true) { + @Override + protected TreeViewer doCreateTreeViewer(Composite aparent, int style) { + return SelectTracesWizardPage.this.doCreateTreeViewer(aparent); + } + }; + + Composite buttonComposite = new Composite(container, SWT.NONE); + FillLayout layout = new FillLayout(SWT.VERTICAL); + layout.spacing = BUTTON_SPACING; + buttonComposite.setLayout(layout); + GridData gd = new GridData(); + gd.verticalAlignment = SWT.CENTER; + buttonComposite.setLayoutData(gd); + + Button selectAllButton = new Button(buttonComposite, SWT.PUSH); + selectAllButton.setText(org.eclipse.tracecompass.internal.tmf.ui.project.dialogs.Messages.Dialog_SelectAll); + selectAllButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + setAllChecked(true); + } + }); + + Button deselectAllButton = new Button(buttonComposite, SWT.PUSH); + deselectAllButton.setText(org.eclipse.tracecompass.internal.tmf.ui.project.dialogs.Messages.Dialog_DeselectAll); + deselectAllButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + setAllChecked(false); + } + }); + } + + private TreeViewer doCreateTreeViewer(Composite parent) { + fCheckboxTreeViewer = new CheckboxTreeViewer(parent, SWT.BORDER); + fContentProvider = new TmfNavigatorContentProvider() { + + @Override + public Object[] getElements(Object inputElement) { + return getChildren(inputElement); + } + + @Override + public synchronized Object[] getChildren(Object parentElement) { + // We only care about the content of trace folders + if (parentElement instanceof TmfTraceFolder) { + Object[] children = super.getChildren(parentElement); + List filteredChildren = new ArrayList<>(); + for (Object child : children) { + if (child instanceof TmfTraceElement) { + TmfTraceElement traceElement = (TmfTraceElement) child; + String traceType = traceElement.getTraceType(); + if (traceType != null && TmfTraceType.getTraceType(traceType) != null) { + filteredChildren.add(traceElement); + } + } else if (child instanceof TmfTraceFolder) { + filteredChildren.add((TmfTraceFolder) child); + } + } + return filteredChildren.toArray(); + } + return null; + } + + @Override + public boolean hasChildren(Object element) { + Object[] children = getChildren(element); + return children != null && children.length > 0; + } + }; + fCheckboxTreeViewer.setContentProvider(fContentProvider); + fLabelProvider = new TmfNavigatorLabelProvider(); + fCheckboxTreeViewer.setLabelProvider(fLabelProvider); + fCheckboxTreeViewer.setSorter(new ViewerSorter()); + + final Tree tree = fCheckboxTreeViewer.getTree(); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + tree.setLayoutData(gd); + tree.setHeaderVisible(true); + + final TreeViewerColumn column = new TreeViewerColumn(fCheckboxTreeViewer, SWT.NONE); + column.getColumn().setWidth(COLUMN_WIDTH); + column.getColumn().setText(Messages.SelectTracesWizardPage_TraceColumnHeader); + column.setLabelProvider(new ColumnLabelProvider() { + @Override + public String getText(Object element) { + return fLabelProvider.getText(element); + } + + @Override + public Image getImage(Object element) { + return fLabelProvider.getImage(element); + } + }); + + // Get the list of traces already part of the experiment + fPreviousTraces = new HashMap<>(); + for (ITmfProjectModelElement child : fExperiment.getChildren()) { + if (child instanceof TmfTraceElement) { + TmfTraceElement trace = (TmfTraceElement) child; + String name = trace.getElementPath(); + fPreviousTraces.put(name, trace); + } + } + + // Populate the list of traces to choose from + Set keys = fPreviousTraces.keySet(); + TmfTraceFolder traceFolder = fProject.getTracesFolder(); + fCheckboxTreeViewer.setInput(traceFolder); + + // Set the checkbox for the traces already included + setCheckedAlreadyIncludedTraces(keys, fContentProvider.getElements(fCheckboxTreeViewer.getInput())); + + fCheckboxTreeViewer.addCheckStateListener(new ICheckStateListener() { + @Override + public void checkStateChanged(CheckStateChangedEvent event) { + Object element = event.getElement(); + setSubtreeChecked(element, event.getChecked()); + maintainCheckIntegrity(element); + } + }); + + return fCheckboxTreeViewer; + } + + private void maintainCheckIntegrity(final Object element) { + Object parentElement = fContentProvider.getParent(element); + boolean allChecked = true; + boolean oneChecked = false; + boolean oneGrayed = false; + if (parentElement != null) { + if (fContentProvider.getChildren(parentElement) != null) { + for (Object child : fContentProvider.getChildren(parentElement)) { + boolean checked = fCheckboxTreeViewer.getChecked(child); + oneChecked |= checked; + allChecked &= checked; + oneGrayed |= fCheckboxTreeViewer.getGrayed(child); + } + } + if (oneGrayed || oneChecked && !allChecked) { + fCheckboxTreeViewer.setGrayChecked(parentElement, true); + } else { + fCheckboxTreeViewer.setGrayed(parentElement, false); + fCheckboxTreeViewer.setChecked(parentElement, allChecked); + } + maintainCheckIntegrity(parentElement); + } + } + + private void setCheckedAlreadyIncludedTraces(Set alreadyIncludedTraces, Object[] elements) { + for (Object element : elements) { + if (element instanceof TmfTraceElement) { + TmfTraceElement trace = (TmfTraceElement) element; + String elementPath = trace.getElementPath(); + if (alreadyIncludedTraces.contains(elementPath)) { + fCheckboxTreeViewer.setChecked(element, true); + maintainCheckIntegrity(element); + } + } + Object[] children = fContentProvider.getChildren(element); + if (children != null) { + setCheckedAlreadyIncludedTraces(alreadyIncludedTraces, children); + } + } + } + + /** + * Sets all items in the element viewer to be checked or unchecked + * + * @param checked + * whether or not items should be checked + */ + private void setAllChecked(boolean checked) { + for (Object element : fContentProvider.getChildren(fCheckboxTreeViewer.getInput())) { + setSubtreeChecked(element, checked); + } + } + + /** + * A version of setSubtreeChecked that also handles the grayed state + * + * @param element + * the element + * @param checked + * true if the item should be checked, and false if it should be + * unchecked + */ + private void setSubtreeChecked(Object element, boolean checked) { + fCheckboxTreeViewer.setChecked(element, checked); + if (checked) { + fCheckboxTreeViewer.setGrayed(element, false); + } + Object[] children = fContentProvider.getChildren(element); + if (children != null) { + for (Object child : children) { + setSubtreeChecked(child, checked); + } + } + } + + /** + * Method to finalize the select operation. + * + * @return true if successful else false + */ + public boolean performFinish() { + + IFolder experiment = fExperiment.getResource(); + + final SelectTracesOperation operation = new SelectTracesOperation(experiment, getSelection()); + + IStatus status = Status.OK_STATUS; + try { + getContainer().run(true, true, new IRunnableWithProgress() { + @Override + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + // Wrapper to have only one resource changed event at the + // end of the operation. + IWorkspaceRunnable workspaceRunnable = new IWorkspaceRunnable() { + @Override + public void run(IProgressMonitor pm) throws CoreException { + operation.run(pm); + } + }; + + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + try { + workspace.run(workspaceRunnable, workspace.getRoot(), IWorkspace.AVOID_UPDATE, monitor); + } catch (CoreException e) { + throw new InvocationTargetException(e); + } finally { + monitor.done(); + } + } + }); + + status = operation.getStatus(); + } catch (InvocationTargetException e) { + status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.SelectTracesWizardPage_SelectionError, e); + } catch (InterruptedException e) { + status = Status.CANCEL_STATUS; + } + if (!status.isOK()) { + if (status.getSeverity() == IStatus.CANCEL) { + setMessage(Messages.SelectTracesWizardPage_SelectionOperationCancelled); + setErrorMessage(null); + } else { + if (status.getException() != null) { + MessageDialog.open(MessageDialog.ERROR, getContainer().getShell(), + Messages.SelectTracesWizardPage_InternalErrorTitle, status.getMessage() + ": " + status.getException(), SWT.SHEET); //$NON-NLS-1$ + } + setMessage(null); + setErrorMessage(Messages.SelectTracesWizardPage_SelectionError); + } + return false; + } + setErrorMessage(null); + + return true; + } + + private class SelectTracesOperation { + + IFolder experiment = null; + TmfTraceElement[] traces; + private IStatus fStatus; + + public SelectTracesOperation(IFolder experiment, TmfTraceElement[] traces) { + this.experiment = experiment; + this.traces = traces; + } + + public void run(IProgressMonitor progressMonitor) { + + // Check if operation was cancelled. + boolean changed = false; + + // Add the selected traces to the experiment + Set keys = fPreviousTraces.keySet(); + SubMonitor subMonitor = SubMonitor.convert(progressMonitor, traces.length + keys.size()); + try { + for (TmfTraceElement trace : traces) { + ModalContext.checkCanceled(progressMonitor); + String name = trace.getElementPath(); + if (keys.contains(name)) { + subMonitor.setTaskName(Messages.SelectTracesWizardPage_TraceRemovalTask + " " + trace.getElementPath()); //$NON-NLS-1$ + fPreviousTraces.remove(name); + } else { + subMonitor.setTaskName(Messages.SelectTracesWizardPage_TraceSelectionTask + " " + trace.getElementPath()); //$NON-NLS-1$ + fExperiment.addTrace(trace, false); + changed = true; + } + subMonitor.worked(1); + } + + // Remove traces that were unchecked (thus left in + // fPreviousTraces) + keys = fPreviousTraces.keySet(); + for (String key : keys) { + ModalContext.checkCanceled(progressMonitor); + TmfTraceElement trace = fPreviousTraces.get(key); + subMonitor.setTaskName(Messages.SelectTracesWizardPage_TraceRemovalTask + " " + trace.getElementPath()); //$NON-NLS-1$ + + try { + fExperiment.removeTrace(trace); + } catch (CoreException e) { + Activator.getDefault().logError(Messages.SelectTracesWizardPage_SelectionError + " " + experiment.getName(), e); //$NON-NLS-1$ + } + changed = true; + subMonitor.worked(1); + } + if (changed) { + fExperiment.closeEditors(); + fExperiment.deleteSupplementaryResources(); + } + setStatus(Status.OK_STATUS); + } catch (InterruptedException e) { + setStatus(Status.CANCEL_STATUS); + } catch (Exception e) { + Activator.getDefault().logError(Messages.SelectTracesWizardPage_SelectionError, e); + setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.SelectTracesWizardPage_SelectionError, e)); + } + } + + /** + * Set the status for this operation + * + * @param status + * the status + */ + protected void setStatus(IStatus status) { + fStatus = status; + } + + public IStatus getStatus() { + return fStatus; + } + + } + + /** + * Get the list of selected traces + */ + private TmfTraceElement[] getSelection() { + Vector traces = new Vector<>(); + Object[] selection = fCheckboxTreeViewer.getCheckedElements(); + for (Object sel : selection) { + if (sel instanceof TmfTraceElement) { + traces.add((TmfTraceElement) sel); + } + } + TmfTraceElement[] result = new TmfTraceElement[traces.size()]; + traces.toArray(result); + return result; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/messages.properties new file mode 100644 index 0000000000..6993dcdd98 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/wizards/messages.properties @@ -0,0 +1,64 @@ +############################################################################### +# Copyright (c) 2013, 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +# Marc-Andre Laperle - Preserve folder structure on import +############################################################################### + +# NewProjectWizard +NewProjectWizard_DialogHeader = Tracing Project +NewProjectWizard_DialogMessage = Create a Tracing Project + +# SelectTracesWizard +SelectTracesWizard_WindowTitle=Select Traces +SelectTracesWizardPage_TraceColumnHeader=Trace +SelectTracesWizardPage_WindowTitle=Select Traces +SelectTracesWizardPage_Description=Select the traces to add to the experiment +SelectTracesWizardPage_SelectionError=Error selecting traces for experiment +SelectTracesWizardPage_TraceSelectionTask=Selecting trace +SelectTracesWizardPage_TraceRemovalTask=Removing trace +SelectTracesWizardPage_SelectionOperationCancelled=Selection operation cancelled +SelectTracesWizardPage_InternalErrorTitle=Internal Error + +# Common Experiment/Trace dialog errors +Dialog_EmptyNameError = No name specified +Dialog_ExistingNameError = Name already used + +# NewExperiment dialog +NewExperimentDialog_DialogTitle = New Experiment +NewExperimentDialog_ExperimentName = Experiment name: + +# RenameExperiment dialog +RenameExperimentDialog_DialogTitle = Rename Experiment +RenameExperimentDialog_ExperimentName = Old Experiment name: +RenameExperimentDialog_ExperimentNewName = New Experiment name: + +# CopyExperiment dialog +CopyExperimentDialog_DialogTitle = Copy Experiment +CopyExperimentDialog_ExperimentName = Source Experiment name: +CopyExperimentDialog_ExperimentNewName = New Experiment name: + +# RenameTrace dialog +RenameTraceDialog_DialogTitle = Rename Trace +RenameTraceDialog_TraceName = Old Trace name: +RenameTraceDialog_TraceNewName = New Trace name: + +# CopyTrace dialog +CopyTraceDialog_DialogTitle = Copy Trace +CopyTraceDialog_TraceName = Source Trace name: +CopyTraceDialog_TraceNewName = New Trace name: + +# NewFolder dialog +NewFolderDialog_DialogTitle = New Folder +NewFolderDialog_FolderName = Folder name: + +# RenameFolder dialog +RenameFolderDialog_DialogTitle = Rename Folder +RenameFolderDialog_FolderName = Old Folder name: +RenameFolderDialog_FolderNewName = New Folder name: diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/properties/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/properties/Messages.java new file mode 100644 index 0000000000..b43099ecd2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/properties/Messages.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ui.properties; + +import org.eclipse.osgi.util.NLS; + +/** + * @since 2.1 + */ +@SuppressWarnings("javadoc") +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.ui.properties.messages"; //$NON-NLS-1$ + + public static String TmfTimestampFormatPage_LocalTime; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/properties/ReadOnlyTextPropertyDescriptor.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/properties/ReadOnlyTextPropertyDescriptor.java new file mode 100644 index 0000000000..bcdf5ebf4e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/properties/ReadOnlyTextPropertyDescriptor.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.properties; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.views.properties.PropertyDescriptor; +import org.eclipse.ui.views.properties.TextPropertyDescriptor; + +/** + * A uneditable version of a {@link TextPropertyDescriptor}. + * + * @author Alexandre Montplaisir + * @since 2.0 + */ +public class ReadOnlyTextPropertyDescriptor extends PropertyDescriptor { + + /** + * Creates an property descriptor with the given id and display name. + * + * @param id + * The id of the property + * @param displayName + * The name to display for the property + */ + public ReadOnlyTextPropertyDescriptor(Object id, String displayName) { + super(id, displayName); + } + + @Override + public CellEditor createPropertyEditor(Composite parent) { + CellEditor editor = new TextCellEditor(parent, SWT.READ_ONLY); + if (getValidator() != null) { + editor.setValidator(getValidator()); + } + return editor; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/properties/TmfTimestampFormatPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/properties/TmfTimestampFormatPage.java new file mode 100644 index 0000000000..bc0dfa5c0c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/properties/TmfTimestampFormatPage.java @@ -0,0 +1,391 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Marc-Andre Laperle - Add time zone preference + * Patrick Tasse - Updated for fraction of seconds + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.properties; + +import java.util.Map; +import java.util.TimeZone; + +import org.eclipse.jface.preference.ComboFieldEditor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.preference.RadioGroupFieldEditor; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimePreferencesConstants; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimePreferences; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +/** + * The TMF timestamp format configuration page. This page is used to select the + * global timestamp and interval time formats (for display and parsing). The + * user can either pick a pre-defined format or enter his/her own. + * + * @version 1.0 + * @author Francois Chouinard + * @since 2.0 + */ +public class TmfTimestampFormatPage extends PreferencePage implements IWorkbenchPreferencePage, SelectionListener, IPropertyChangeListener { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + // Date and Time formats + private static final String[][] fDateTimeFormats = new String[][] { + { ITmfTimePreferencesConstants.DATE_YEAR_FMT, ITmfTimePreferencesConstants.DATE_YEAR_FMT }, + { ITmfTimePreferencesConstants.DATE_YEAR2_FMT, ITmfTimePreferencesConstants.DATE_YEAR2_FMT }, + { ITmfTimePreferencesConstants.DATE_MONTH_FMT, ITmfTimePreferencesConstants.DATE_MONTH_FMT }, + { ITmfTimePreferencesConstants.DATE_DAY_FMT, ITmfTimePreferencesConstants.DATE_DAY_FMT }, + { ITmfTimePreferencesConstants.DATE_JDAY_FMT, ITmfTimePreferencesConstants.DATE_JDAY_FMT }, + { ITmfTimePreferencesConstants.TIME_HOUR_FMT, ITmfTimePreferencesConstants.TIME_HOUR_FMT }, + { ITmfTimePreferencesConstants.TIME_MINUTE_FMT, ITmfTimePreferencesConstants.TIME_MINUTE_FMT }, + { ITmfTimePreferencesConstants.TIME_SECOND_FMT, ITmfTimePreferencesConstants.TIME_SECOND_FMT }, + { ITmfTimePreferencesConstants.TIME_ELAPSED_FMT + " (secs in epoch)", ITmfTimePreferencesConstants.TIME_ELAPSED_FMT }, //$NON-NLS-1$ + { "(none)", ITmfTimePreferencesConstants.TIME_NO_FMT }, //$NON-NLS-1$ + }; + + // Sub-second formats + private static final String[][] fSubSecondFormats = new String[][] { + { ITmfTimePreferencesConstants.SUBSEC_MILLI_FMT + " (ms)", ITmfTimePreferencesConstants.SUBSEC_MILLI_FMT }, //$NON-NLS-1$ + { ITmfTimePreferencesConstants.SUBSEC_MICRO_FMT + " (µs)", ITmfTimePreferencesConstants.SUBSEC_MICRO_FMT }, //$NON-NLS-1$ + { ITmfTimePreferencesConstants.SUBSEC_NANO_FMT + " (ns)", ITmfTimePreferencesConstants.SUBSEC_NANO_FMT }, //$NON-NLS-1$ + }; + + // Date and Time delimiters + private static final String[][] fDateTimeDelimiters = new String[][] { + { "(none)", ITmfTimePreferencesConstants.DELIMITER_NONE }, //$NON-NLS-1$ + { " (space)", ITmfTimePreferencesConstants.DELIMITER_SPACE }, //$NON-NLS-1$ + { ", (comma)", ITmfTimePreferencesConstants.DELIMITER_COMMA }, //$NON-NLS-1$ + { "- (dash)", ITmfTimePreferencesConstants.DELIMITER_DASH }, //$NON-NLS-1$ + { "_ (underline)", ITmfTimePreferencesConstants.DELIMITER_UNDERLINE }, //$NON-NLS-1$ + { ": (colon)", ITmfTimePreferencesConstants.DELIMITER_COLON }, //$NON-NLS-1$ + { "; (semicolon)", ITmfTimePreferencesConstants.DELIMITER_SEMICOLON }, //$NON-NLS-1$ + { "/ (slash)", ITmfTimePreferencesConstants.DELIMITER_SLASH }, //$NON-NLS-1$ + { "' (quote)", ITmfTimePreferencesConstants.DELIMITER_QUOTE }, //$NON-NLS-1$ + { "\" (dbl-quote)", ITmfTimePreferencesConstants.DELIMITER_DQUOT }, //$NON-NLS-1$ + }; + + // Sub-Second delimiters + private static final String[][] fSubSecondDelimiters = new String[][] { + { "(none)", ITmfTimePreferencesConstants.DELIMITER_NONE }, //$NON-NLS-1$ + { " (space)", ITmfTimePreferencesConstants.DELIMITER_SPACE }, //$NON-NLS-1$ + { ", (comma)", ITmfTimePreferencesConstants.DELIMITER_COMMA }, //$NON-NLS-1$ + { "- (dash)", ITmfTimePreferencesConstants.DELIMITER_DASH }, //$NON-NLS-1$ + { "_ (underline)", ITmfTimePreferencesConstants.DELIMITER_UNDERLINE }, //$NON-NLS-1$ + { ": (colon)", ITmfTimePreferencesConstants.DELIMITER_COLON }, //$NON-NLS-1$ + { "; (semicolon)", ITmfTimePreferencesConstants.DELIMITER_SEMICOLON }, //$NON-NLS-1$ + { "/ (slash)", ITmfTimePreferencesConstants.DELIMITER_SLASH }, //$NON-NLS-1$ + { "' (quote)", ITmfTimePreferencesConstants.DELIMITER_QUOTE }, //$NON-NLS-1$ + { "\" (dbl-quote)", ITmfTimePreferencesConstants.DELIMITER_DQUOT }, //$NON-NLS-1$ + { ". (period)", ITmfTimePreferencesConstants.DELIMITER_PERIOD }, //$NON-NLS-1$ + }; + + // Time zones + @SuppressWarnings("nls") + private static final String[] timeZones = new String[] { + Messages.TmfTimestampFormatPage_LocalTime, + "GMT-12", + "GMT-11", + "GMT-10", + "GMT-9:30", + "GMT-9", + "GMT-7", + "GMT-6", + "GMT-5", + "GMT-4", + "GMT-3:30", + "GMT-3", + "GMT-2", + "GMT-1", + "GMT", + "GMT+1", + "GMT+2", + "GMT+3", + "GMT+3:30", + "GMT+4", + "GMT+4:30", + "GMT+5", + "GMT+5:30", + "GMT+6", + "GMT+7", + "GMT+8", + "GMT+9", + "GMT+9:30", + "GMT+10", + "GMT+10:30", + "GMT+11", + "GMT+11:30", + "GMT+12", + "GMT+13:00", + "GMT+14:00" + }; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // General stuff + private Composite fPage; + private IPreferenceStore fPreferenceStore; + private TmfTimePreferences fTimePreference; + + // Example section + private Composite fExampleSection; + private Text fPatternDisplay; + private Text fExampleDisplay; + + // Timezone section + private ComboFieldEditor fCombo; + + // Date/Time format section + private RadioGroupFieldEditor fDateTimeFields; + private RadioGroupFieldEditor fSSecFields; + + // Delimiters section + private RadioGroupFieldEditor fDateFieldDelim; + private RadioGroupFieldEditor fTimeFieldDelim; + private RadioGroupFieldEditor fSSecFieldDelim; + + // IPropertyChangeListener data + private String fProperty; + private String fChangedProperty; + + private Map fPreferenceMap; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * The default constructor + */ + public TmfTimestampFormatPage() { + fPreferenceStore = getPreferenceStore(); + fTimePreference = TmfTimePreferences.getInstance(); + fPreferenceMap = fTimePreference.getPreferenceMap(); + } + + // ------------------------------------------------------------------------ + // IWorkbenchPreferencePage + // ------------------------------------------------------------------------ + + @Override + protected IPreferenceStore doGetPreferenceStore() { + return Activator.getDefault().getCorePreferenceStore(); + } + + @Override + public void init(IWorkbench workbench) { + } + + // ------------------------------------------------------------------------ + // PreferencePage + // ------------------------------------------------------------------------ + + @Override + protected Control createContents(Composite parent) { + + // Overall preference page layout + GridLayout gl = new GridLayout(); + gl.marginHeight = 0; + gl.marginWidth = 0; + parent.setLayout(gl); + fPage = new Composite(parent, SWT.NONE); + fPage.setLayout(new GridLayout()); + fPage.setLayoutData(new GridData( + GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL)); + + // Example section + fExampleSection = new Composite(fPage, SWT.NONE); + fExampleSection.setLayout(new GridLayout(2, false)); + fExampleSection.setLayoutData(new GridData(GridData.FILL_BOTH)); + + Label patternLabel = new Label(fExampleSection, SWT.HORIZONTAL); + patternLabel.setText("Current Format: "); //$NON-NLS-1$ + fPatternDisplay = new Text(fExampleSection, SWT.BORDER | SWT.READ_ONLY); + fPatternDisplay.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Label exampleLabel = new Label(fExampleSection, SWT.NONE); + exampleLabel.setText("Sample Display: "); //$NON-NLS-1$ + fExampleDisplay = new Text(fExampleSection, SWT.BORDER | SWT.READ_ONLY); + fExampleDisplay.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Label separator = new Label(fPage, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.SHADOW_NONE); + separator.setLayoutData( + new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL)); + + // Time Zones + String[][] timeZoneIntervals = new String[timeZones.length][2]; + timeZoneIntervals[0][0] = timeZones[0]; + timeZoneIntervals[0][1] = fPreferenceStore.getDefaultString(ITmfTimePreferencesConstants.TIME_ZONE); + for (int i = 1; i < timeZones.length; i++) { + TimeZone tz = null; + try { + tz = TimeZone.getTimeZone(timeZones[i]); + timeZoneIntervals[i][0] = tz.getDisplayName(); + timeZoneIntervals[i][1] = tz.getID(); + } catch (NullPointerException e) { + System.out.println("TimeZone " + timeZones[i] + " does not exist."); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + fCombo = new ComboFieldEditor(ITmfTimePreferencesConstants.TIME_ZONE, "Time Zone", timeZoneIntervals, fPage); //$NON-NLS-1$ + fCombo.setPreferenceStore(fPreferenceStore); + fCombo.load(); + fCombo.setPropertyChangeListener(this); + + // Date and Time section + fDateTimeFields = new RadioGroupFieldEditor( + ITmfTimePreferencesConstants.DATIME, "Date and Time format", 3, fDateTimeFormats, fPage, true); //$NON-NLS-1$ + fDateTimeFields.setPreferenceStore(fPreferenceStore); + fDateTimeFields.load(); + fDateTimeFields.setPropertyChangeListener(this); + + // Sub-second section + fSSecFields = new RadioGroupFieldEditor( + ITmfTimePreferencesConstants.SUBSEC, "Sub-second format", 3, fSubSecondFormats, fPage, true); //$NON-NLS-1$ + fSSecFields.setPreferenceStore(fPreferenceStore); + fSSecFields.load(); + fSSecFields.setPropertyChangeListener(this); + + // Separators section + fDateFieldDelim = new RadioGroupFieldEditor( + ITmfTimePreferencesConstants.DATE_DELIMITER, "Date delimiter", 5, fDateTimeDelimiters, fPage, true); //$NON-NLS-1$ + fDateFieldDelim.setPreferenceStore(fPreferenceStore); + fDateFieldDelim.load(); + fDateFieldDelim.setPropertyChangeListener(this); + + fTimeFieldDelim = new RadioGroupFieldEditor( + ITmfTimePreferencesConstants.TIME_DELIMITER, "Time delimiter", 5, fDateTimeDelimiters, fPage, true); //$NON-NLS-1$ + fTimeFieldDelim.setPreferenceStore(fPreferenceStore); + fTimeFieldDelim.load(); + fTimeFieldDelim.setPropertyChangeListener(this); + + fSSecFieldDelim = new RadioGroupFieldEditor( + ITmfTimePreferencesConstants.SSEC_DELIMITER, "Sub-Second Delimiter", 5, fSubSecondDelimiters, fPage, true); //$NON-NLS-1$ + fSSecFieldDelim.setPreferenceStore(fPreferenceStore); + fSSecFieldDelim.load(); + fSSecFieldDelim.setPropertyChangeListener(this); + + refresh(); + return fPage; + } + + @Override + protected void performDefaults() { + fDateTimeFields.loadDefault(); + fSSecFields.loadDefault(); + fDateFieldDelim.loadDefault(); + fTimeFieldDelim.loadDefault(); + fSSecFieldDelim.loadDefault(); + fCombo.loadDefault(); + + fPreferenceMap = TmfTimePreferences.getInstance().getDefaultPreferenceMap(); + displayExample(); + } + + @Override + protected void performApply() { + fDateTimeFields.store(); + fSSecFields.store(); + fDateFieldDelim.store(); + fTimeFieldDelim.store(); + fSSecFieldDelim.store(); + fCombo.store(); + + TmfTimestampFormat.updateDefaultFormats(); + TmfSignalManager.dispatchSignal(new TmfTimestampFormatUpdateSignal(null)); + displayExample(); + } + + @Override + public boolean performOk() { + performApply(); + return super.performOk(); + } + + // ------------------------------------------------------------------------ + // SelectionListener + // ------------------------------------------------------------------------ + + @Override + public void widgetSelected(SelectionEvent e) { + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + + // ------------------------------------------------------------------------ + // IPropertyChangeListener + // ------------------------------------------------------------------------ + + @Override + public void propertyChange(PropertyChangeEvent event) { + Object source = event.getSource(); + Object value = event.getNewValue(); + if (source instanceof RadioGroupFieldEditor && value instanceof String && + !(value.equals(fChangedProperty) && source == fProperty)) + { + fProperty = ((RadioGroupFieldEditor) source).getPreferenceName(); + fChangedProperty = (String) value; + refresh(); + } + } + + // ------------------------------------------------------------------------ + // Helper functions + // ------------------------------------------------------------------------ + + private void refresh() { + updatePatterns(); + displayExample(); + } + + void updatePatterns() { + if (ITmfTimePreferencesConstants.DATIME.equals(fProperty) || + ITmfTimePreferencesConstants.SUBSEC.equals(fProperty) || + ITmfTimePreferencesConstants.DATE_DELIMITER.equals(fProperty) || + ITmfTimePreferencesConstants.TIME_DELIMITER.equals(fProperty) || + ITmfTimePreferencesConstants.SSEC_DELIMITER.equals(fProperty)) { + fPreferenceMap.put(fProperty, fChangedProperty); + } + } + + private void displayExample() { + long ts = 1332170682500677380L; + String timePattern = fTimePreference.computeTimePattern(fPreferenceMap); + fPatternDisplay.setText(timePattern); + fPatternDisplay.redraw(); + + fExampleDisplay.setText(new TmfTimestampFormat(timePattern).format(ts)); + fExampleDisplay.redraw(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/properties/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/properties/messages.properties new file mode 100644 index 0000000000..446e99854a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/properties/messages.properties @@ -0,0 +1,13 @@ +############################################################################### +# Copyright (c) 2013 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Marc-Andre Laperle - Initial API and implementation +############################################################################### + +TmfTimestampFormatPage_LocalTime=Local time diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/ArrayTreeContentProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/ArrayTreeContentProvider.java new file mode 100644 index 0000000000..d8bc199383 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/ArrayTreeContentProvider.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers; + +import java.util.Collection; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +/** + * This implementation of ITreeContentProvider handles the case + * where the viewer input is an unchanging array or collection of elements. + * The elements do not have children. + * + * @author Patrick Tasse + * @since 3.2 + */ +public class ArrayTreeContentProvider implements ITreeContentProvider { + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + @Override + public Object[] getChildren(Object parentElement) { + return null; + } + + @Override + public Object getParent(Object element) { + return null; + } + + @Override + public boolean hasChildren(Object element) { + return false; + } + + @Override + public Object[] getElements(Object inputElement) { + if (inputElement instanceof Object[]) { + return (Object[]) inputElement; + } + if (inputElement instanceof Collection) { + return ((Collection) inputElement).toArray(); + } + return new Object[0]; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/ITmfTimeProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/ITmfTimeProvider.java new file mode 100644 index 0000000000..56e546c930 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/ITmfTimeProvider.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation in ITmfChartTimeProvider + * Geneviève Bastien - Moved methods from ITmfChartTimeProvider to this interface + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers; + +/** + * Interface for providing and updating time information. This is typically + * implemented by a viewer that is displaying trace data over time. + * + * @author Bernd Hufmann + * @author Geneviève Bastien + * @since 3.0 + */ +public interface ITmfTimeProvider extends ITmfViewer { + + /** + * Gets the start time of trace + * + * @return start time of trace + */ + long getStartTime(); + + /** + * Gets the end time of trace + * + * @return End time of trace + */ + long getEndTime(); + + /** + * Gets the start time of current time range displayed + * + * @return start time of current time range + */ + long getWindowStartTime(); + + /** + * Gets the end time of current time range displayed + * + * @return End time of current time range + */ + long getWindowEndTime(); + + /** + * Gets the duration of the current time range displayed + * + * @return duration of current time range + */ + long getWindowDuration(); + + /** + * Gets the begin time of the selected range + * + * @return the begin time of the selected range + */ + long getSelectionBeginTime(); + + /** + * Gets the end time of the selected range + * + * @return end time of the selected range + */ + long getSelectionEndTime(); + + /** + * Method to notify about a change of the current selected time. + * + * @param currentBeginTime + * The current selection begin time + * @param currentEndTime + * The current selection end time + */ + void updateSelectionRange(long currentBeginTime, long currentEndTime); + + /** + * Updates the current time range window. + * + * @param windowStartTime + * The window start time + * @param windowEndTime + * The window end time. + */ + void updateWindow(long windowStartTime, long windowEndTime); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/ITmfViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/ITmfViewer.java new file mode 100644 index 0000000000..011a1c9b6d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/ITmfViewer.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers; + +import org.eclipse.swt.widgets.Control; +import org.eclipse.tracecompass.tmf.core.component.ITmfComponent; + +/** + * Interface to viewers. + * + * Viewers are to be put into views which need to know how to refresh the + * viewer's contents. + * + * @author Mathieu Denis + * @version 2.0 + * @since 2.0 + */ +public interface ITmfViewer extends ITmfComponent { + + /** + * Returns the primary control associated with this viewer. + * + * @return the SWT control which displays this viewer's contents + */ + Control getControl(); + + /** + * Tells the viewer to refresh its contents. + */ + void refresh(); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/TmfTimeViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/TmfTimeViewer.java new file mode 100644 index 0000000000..bed6ceda2d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/TmfTimeViewer.java @@ -0,0 +1,442 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation in TmfXYChartViewer + * Geneviève Bastien - Moved methods from TmfXYChartViewer to this interface + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.tracecompass.tmf.core.signal.TmfRangeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalThrottler; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceRangeUpdatedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceUpdatedSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; + +/** + * Abstract class that extends {@link TmfViewer} that adds methods to + * synchronize with a trace's time information. + * + * This class will be extended by viewers who require time information to update + * their content. + * + *

    + * It provides three times of data:
    + *   - start and end time of the trace (available)
    + *   - start, end and duration of the current time window, ie the visible time range
    + *   - start and end of the time range selected
    + * 
    + * + * @author Bernd Hufmann + * @author Geneviève Bastien + * @since 3.0 + */ +public abstract class TmfTimeViewer extends TmfViewer implements ITmfTimeProvider { + + /** Start time of trace */ + private long fStartTime; + /** End time of trace */ + private long fEndTime; + /** Start time of current time range */ + private long fWindowStartTime; + /** End time of current time range */ + private long fWindowEndTime; + /** Duration of current time range */ + private long fWindowDuration; + /** Current begin time of selection range */ + private long fSelectionBeginTime; + /** Current end of selection range */ + private long fSelectionEndTime; + /** The trace that is displayed by this viewer */ + private ITmfTrace fTrace; + /** A signal throttler for range updates */ + private final TmfSignalThrottler fTimeRangeSyncThrottle = new TmfSignalThrottler(this, 200); + + /** + * Default constructor. + */ + public TmfTimeViewer() { + super(); + } + + /** + * Constructor that initializes the parent of the viewer + * + * @param parent + * The parent composite that holds this viewer + */ + public TmfTimeViewer(Composite parent) { + this(parent, ""); //$NON-NLS-1$ + } + + /** + * Constructor that initializes the parent of the viewer and that sets the + * name of the viewer + * + * @param parent + * The parent composite that holds this viewer + * @param name + * The name of the viewer + */ + public TmfTimeViewer(Composite parent, String name) { + init(parent, name); + } + + // ------------------------------------------------------------------------ + // Getter/Setters + // ------------------------------------------------------------------------ + + /** + * Sets the start time of the trace + * + * @param startTime + * The start time to set + */ + protected void setStartTime(long startTime) { + fStartTime = startTime; + } + + /** + * Sets the end time of the trace + * + * @param endTime + * The start time to set + */ + protected void setEndTime(long endTime) { + fEndTime = endTime; + } + + /** + * Sets the start time of the current time range window (visible range) + * + * @param windowStartTime + * The start time to set + */ + protected void setWindowStartTime(long windowStartTime) { + fWindowStartTime = windowStartTime; + } + + /** + * Sets the end time of the current time range window (visible range) + * + * @param windowEndTime + * The start time to set + */ + protected void setWindowEndTime(long windowEndTime) { + fWindowEndTime = windowEndTime; + } + + /** + * Sets the duration of the current time range window (visible range) + * + * @param windowDuration + * The window duration + */ + protected void setWindowDuration(long windowDuration) { + fWindowDuration = windowDuration; + } + + /** + * Sets the begin time of the selected range. + * + * @param selectionBeginTime + * The begin time to set + */ + protected void setSelectionBeginTime(long selectionBeginTime) { + fSelectionBeginTime = selectionBeginTime; + } + + /** + * Sets the end time of the selected range. + * + * @param selectionEndTime + * The end time to set + */ + protected void setSelectionEndTime(long selectionEndTime) { + fSelectionEndTime = selectionEndTime; + } + + /** + * Sets the trace that is displayed by this viewer. + * + * @param trace + * The trace to set + */ + protected void setTrace(ITmfTrace trace) { + fTrace = trace; + } + + /** + * Gets the trace that is displayed by this viewer. + * + * @return the trace + */ + protected ITmfTrace getTrace() { + return fTrace; + } + + // ------------------------------------------------------------------------ + // ITmfTimeProvider + // ------------------------------------------------------------------------ + + @Override + public long getStartTime() { + return fStartTime; + } + + @Override + public long getEndTime() { + return fEndTime; + } + + @Override + public long getWindowStartTime() { + return fWindowStartTime; + } + + @Override + public long getWindowEndTime() { + return fWindowEndTime; + } + + @Override + public long getWindowDuration() { + return fWindowDuration; + } + + @Override + public long getSelectionBeginTime() { + return fSelectionBeginTime; + } + + @Override + public long getSelectionEndTime() { + return fSelectionEndTime; + } + + @Override + public void updateSelectionRange(final long currentBeginTime, final long currentEndTime) { + if (fTrace != null) { + setSelectionBeginTime(currentBeginTime); + setSelectionEndTime(currentEndTime); + + final ITmfTimestamp startTimestamp = new TmfTimestamp(getSelectionBeginTime(), ITmfTimestamp.NANOSECOND_SCALE); + final ITmfTimestamp endTimestamp = new TmfTimestamp(getSelectionEndTime(), ITmfTimestamp.NANOSECOND_SCALE); + + TmfTimeSynchSignal signal = new TmfTimeSynchSignal(this, startTimestamp, endTimestamp); + broadcast(signal); + } + } + + @Override + public void updateWindow(long windowStartTime, long windowEndTime) { + + setWindowStartTime(windowStartTime); + setWindowEndTime(windowEndTime); + setWindowDuration(windowEndTime - windowStartTime); + + // Build the new time range; keep the current time + TmfTimeRange timeRange = new TmfTimeRange( + new TmfTimestamp(getWindowStartTime(), ITmfTimestamp.NANOSECOND_SCALE), + new TmfTimestamp(getWindowEndTime(), ITmfTimestamp.NANOSECOND_SCALE)); + + // Send the signal + TmfRangeSynchSignal signal = new TmfRangeSynchSignal(this, timeRange); + fTimeRangeSyncThrottle.queue(signal); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + /** + * A Method to load a trace into the viewer. + * + * @param trace + * A trace to apply in the viewer + */ + public void loadTrace(ITmfTrace trace) { + fTrace = trace; + + long timestamp = TmfTraceManager.getInstance().getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + TmfTimeRange currentRange = TmfTraceManager.getInstance().getCurrentRange(); + long windowStartTime = currentRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long windowEndTime = currentRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long windowDuration = windowEndTime - windowStartTime; + long startTime = fTrace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long endTime = fTrace.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + + setSelectionBeginTime(timestamp); + setSelectionEndTime(timestamp); + setStartTime(startTime); + setWindowStartTime(windowStartTime); + setWindowEndTime(windowEndTime); + setWindowDuration(windowDuration); + setEndTime(endTime); + } + + /** + * Resets the content of the viewer + */ + public void reset() { + // Reset the internal data + setSelectionBeginTime(0); + setSelectionEndTime(0); + setStartTime(0); + setWindowStartTime(0); + setWindowDuration(0); + setEndTime(0); + setWindowEndTime(0); + setTrace(null); + } + + // ------------------------------------------------------------------------ + // Signal Handler + // ------------------------------------------------------------------------ + + /** + * Signal handler for handling of the trace opened signal. + * + * @param signal + * The trace opened signal {@link TmfTraceOpenedSignal} + */ + @TmfSignalHandler + public void traceOpened(TmfTraceOpenedSignal signal) { + fTrace = signal.getTrace(); + loadTrace(getTrace()); + } + + /** + * Signal handler for handling of the trace selected signal. + * + * @param signal + * The trace selected signal {@link TmfTraceSelectedSignal} + */ + @TmfSignalHandler + public void traceSelected(TmfTraceSelectedSignal signal) { + if (fTrace != signal.getTrace()) { + fTrace = signal.getTrace(); + loadTrace(getTrace()); + } + } + + /** + * Signal handler for handling of the trace closed signal. + * + * @param signal + * The trace closed signal {@link TmfTraceClosedSignal} + */ + @TmfSignalHandler + public void traceClosed(TmfTraceClosedSignal signal) { + + if (signal.getTrace() != fTrace) { + return; + } + + // Reset the internal data + fTrace = null; + reset(); + } + + /** + * Signal handler for handling of the time synch signal, ie the selected range. + * + * @param signal + * The time synch signal {@link TmfTimeSynchSignal} + */ + @TmfSignalHandler + public void selectionRangeUpdated(TmfTimeSynchSignal signal) { + if ((signal.getSource() != this) && (fTrace != null)) { + ITmfTimestamp selectedTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE); + ITmfTimestamp selectedEndTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE); + setSelectionBeginTime(selectedTime.getValue()); + setSelectionEndTime(selectedEndTime.getValue()); + } + } + + /** + * Signal handler for handling of the time range synch signal, ie the visible range. + * + * @param signal + * The time range synch signal {@link TmfRangeSynchSignal} + */ + @TmfSignalHandler + public void timeRangeUpdated(TmfRangeSynchSignal signal) { + + if (fTrace != null) { + // Validate the time range + TmfTimeRange range = signal.getCurrentRange().getIntersection(fTrace.getTimeRange()); + if (range == null) { + return; + } + + if (signal.getSource() != this) { + // Update the time range + long windowStartTime = range.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long windowEndTime = range.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long windowDuration = windowEndTime - windowStartTime; + + setWindowStartTime(windowStartTime); + setWindowEndTime(windowEndTime); + setWindowDuration(windowDuration); + } + } + } + + /** + * Signal handler for handling of the trace range updated signal. + * + * @param signal + * The trace range signal {@link TmfTraceRangeUpdatedSignal} + */ + @TmfSignalHandler + public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal) { + + if (signal.getTrace() != fTrace) { + return; + } + + TmfTimeRange fullRange = signal.getRange(); + + long traceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long traceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + + setStartTime(traceStartTime); + setEndTime(traceEndTime); + } + + /** + * Signal handler for handling of the trace updated signal. + * + * @param signal + * The trace updated signal {@link TmfTraceUpdatedSignal} + */ + @TmfSignalHandler + public void traceUpdated(TmfTraceUpdatedSignal signal) { + if (signal.getTrace() != fTrace) { + return; + } + TmfTimeRange fullRange = signal.getTrace().getTimeRange(); + long traceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long traceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + + setStartTime(traceStartTime); + setEndTime(traceEndTime); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/TmfViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/TmfViewer.java new file mode 100644 index 0000000000..e69a1be73a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/TmfViewer.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.tracecompass.tmf.core.component.TmfComponent; + +/** + * Abstract class that extends {@link TmfComponent} to be specific to viewers. + * + * It allows the access to the control and the parent of a viewer. + * + * @author Mathieu Denis + * @version 2.0 + * @since 2.0 + */ +public abstract class TmfViewer extends TmfComponent implements ITmfViewer { + + /** + * The parent composite that holds the viewer + */ + protected Composite fParent; + + /** + * Default constructor. The viewer have to be initialize through the + * {@link TmfViewer#init(Composite, String)} function later on. + */ + public TmfViewer() { + super(); + } + + /** + * Constructor that initializes the parent of the viewer + * + * @param parent + * The parent composite that holds this viewer + * + * @see TmfComponent#TmfComponent(String) + */ + public TmfViewer(Composite parent) { + this(parent, ""); //$NON-NLS-1$ + } + + /** + * Constructor that initializes the parent of the viewer and that sets the + * name of the viewer + * + * @param parent + * The parent composite that holds this viewer + * @param name + * The name of the viewer + */ + public TmfViewer(Composite parent, String name) { + init(parent, name); + } + + /** + * Performs initialization of the viewer. It initializes the component. Need + * to be called when the default constructor is used. + * + * @param parent + * The parent composite of the viewer + * @param name + * The name to give to this viewer + * @see TmfComponent#init(String) + */ + public void init(Composite parent, String name) { + super.init(name); + fParent = parent; + } + + /** + * @return the parent of this viewer + */ + public Composite getParent() { + return fParent; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventAdapterFactory.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventAdapterFactory.java new file mode 100644 index 0000000000..8cf00086c3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventAdapterFactory.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc-Andre Laperle - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ui.viewers.events; + +import org.eclipse.core.runtime.IAdapterFactory; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.ui.views.properties.IPropertySource; + +/** + * Implements basic UI support for TMF events. + * + * @since 2.0 + */ +public class TmfEventAdapterFactory implements IAdapterFactory { + + private static Class[] PROPERTIES = new Class[] { + IPropertySource.class + }; + + @Override + public Class[] getAdapterList() { + return PROPERTIES; + } + + @Override + public Object getAdapter(Object element, Class key) { + ITmfEvent tmfEvent = (ITmfEvent) element; + if (IPropertySource.class.equals(key)) { + return new TmfEventPropertySource(tmfEvent); + } + return null; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventPropertySource.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventPropertySource.java new file mode 100644 index 0000000000..75816b39a2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventPropertySource.java @@ -0,0 +1,355 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Bernd Hufmann - Added call site and model URI properties + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.events; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.event.ITmfCustomAttributes; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfModelLookup; +import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfSourceLookup; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.ui.properties.ReadOnlyTextPropertyDescriptor; +import org.eclipse.ui.views.properties.IPropertyDescriptor; +import org.eclipse.ui.views.properties.IPropertySource; + +/** + * Property source for events + * + * @since 2.0 + */ +public class TmfEventPropertySource implements IPropertySource { + + private static final String ID_TIMESTAMP = "event_timestamp"; //$NON-NLS-1$ + private static final String ID_SOURCE = "event_source"; //$NON-NLS-1$ + private static final String ID_TYPE = "event_type"; //$NON-NLS-1$ + private static final String ID_REFERENCE = "event_reference"; //$NON-NLS-1$ + private static final String ID_TRACE = "trace_attribute"; //$NON-NLS-1$ + private static final String ID_CONTENT = "event_content"; //$NON-NLS-1$ + private static final String ID_SOURCE_LOOKUP = "event_lookup"; //$NON-NLS-1$ + private static final String ID_MODEL_URI = "model_uri"; //$NON-NLS-1$ + private static final String ID_CUSTOM_ATTRIBUTE = "custom_attribute"; //$NON-NLS-1$ + + private static final String NAME_TIMESTAMP = "Timestamp"; //$NON-NLS-1$ + private static final String NAME_SOURCE = "Source"; //$NON-NLS-1$ + private static final String NAME_TYPE = "Type"; //$NON-NLS-1$ + private static final String NAME_REFERENCE = "Reference"; //$NON-NLS-1$ + private static final String NAME_TRACE = "Trace"; //$NON-NLS-1$ + private static final String NAME_CONTENT = "Content"; //$NON-NLS-1$ + private static final String NAME_SOURCE_LOOKUP = "Source Lookup"; //$NON-NLS-1$ + private static final String NAME_MODEL_URI = "Model URI"; //$NON-NLS-1$ + private static final String NAME_CUSTOM_ATTRIBUTES = "Custom Attributes"; //$NON-NLS-1$ + + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + + private ITmfEvent fEvent; + + private class TimestampPropertySource implements IPropertySource { + private static final String ID_TIMESTAMP_VALUE = "timestamp_value"; //$NON-NLS-1$ + private static final String ID_TIMESTAMP_SCALE = "timestamp_scale"; //$NON-NLS-1$ + private static final String ID_TIMESTAMP_PRECISION = "timestamp_precision"; //$NON-NLS-1$ + private static final String NAME_TIMESTAMP_VALUE = "value"; //$NON-NLS-1$ + private static final String NAME_TIMESTAMP_SCALE = "scale"; //$NON-NLS-1$ + private static final String NAME_TIMESTAMP_PRECISION = "precision"; //$NON-NLS-1$ + + private ITmfTimestamp fTimestamp; + + public TimestampPropertySource(ITmfTimestamp timestamp) { + fTimestamp = timestamp; + } + + @Override + public Object getEditableValue() { + return fTimestamp.toString(); + } + + @Override + public IPropertyDescriptor[] getPropertyDescriptors() { + IPropertyDescriptor[] descriptors = new IPropertyDescriptor[3]; + descriptors[0] = new ReadOnlyTextPropertyDescriptor(ID_TIMESTAMP_VALUE, NAME_TIMESTAMP_VALUE); + descriptors[1] = new ReadOnlyTextPropertyDescriptor(ID_TIMESTAMP_SCALE, NAME_TIMESTAMP_SCALE); + descriptors[2] = new ReadOnlyTextPropertyDescriptor(ID_TIMESTAMP_PRECISION, NAME_TIMESTAMP_PRECISION); + return descriptors; + } + + @Override + public Object getPropertyValue(Object id) { + if (id.equals(ID_TIMESTAMP_VALUE)) { + return Long.toString(fTimestamp.getValue()); + } else if (id.equals(ID_TIMESTAMP_SCALE)) { + return Integer.toString(fTimestamp.getScale()); + } else if (id.equals(ID_TIMESTAMP_PRECISION)) { + return Integer.toString(fTimestamp.getPrecision()); + } + return null; + } + + @Override + public boolean isPropertySet(Object id) { + return false; + } + + @Override + public void resetPropertyValue(Object id) { + } + + @Override + public void setPropertyValue(Object id, Object value) { + } + } + + private class ContentPropertySource implements IPropertySource { + private ITmfEventField fContent; + + public ContentPropertySource(ITmfEventField content) { + fContent = content; + } + + @Override + public Object getEditableValue() { + return fContent.toString(); + } + + @Override + public IPropertyDescriptor[] getPropertyDescriptors() { + List descriptors = new ArrayList<>(fContent.getFields().size()); + for (ITmfEventField field : fContent.getFields()) { + if (field != null) { + descriptors.add(new ReadOnlyTextPropertyDescriptor(field, field.getName())); + } + } + return descriptors.toArray(new IPropertyDescriptor[0]); + } + + @Override + public Object getPropertyValue(Object id) { + ITmfEventField field = (ITmfEventField) id; + if (field.getFields() != null && field.getFields().size() > 0) { + return new ContentPropertySource(field); + } + return field.getFormattedValue(); + } + + @Override + public boolean isPropertySet(Object id) { + return false; + } + + @Override + public void resetPropertyValue(Object id) { + } + + @Override + public void setPropertyValue(Object id, Object value) { + } + } + + private class SourceLookupPropertySource implements IPropertySource { + + private static final String ID_FILE_NAME = "callsite_file"; //$NON-NLS-1$ + private static final String ID_FUNCTION_NAME = "callsite_function"; //$NON-NLS-1$ + private static final String ID_LINE_NUMBER = "callsite_line"; //$NON-NLS-1$ + + private static final String NAME_FILE_NAME = "File"; //$NON-NLS-1$ + private static final String NAME_FUNCTION_NAME = "Function"; //$NON-NLS-1$ + private static final String NAME_LINE_NUMBER = "Line"; //$NON-NLS-1$ + + final private ITmfSourceLookup fSourceLookup; + + public SourceLookupPropertySource(ITmfSourceLookup lookup) { + fSourceLookup = lookup; + } + + @Override + public Object getEditableValue() { + if (fSourceLookup.getCallsite() != null) { + return fSourceLookup.getCallsite().toString(); + } + return null; + } + + @Override + public IPropertyDescriptor[] getPropertyDescriptors() { + List descriptors= new ArrayList<>(); + if (fSourceLookup.getCallsite() != null) { + descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_FILE_NAME, NAME_FILE_NAME)); + descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_LINE_NUMBER, NAME_LINE_NUMBER)); + // only display function if available + if (fSourceLookup.getCallsite().getFunctionName() != null) { + descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_FUNCTION_NAME, NAME_FUNCTION_NAME)); + } + } + return descriptors.toArray(new IPropertyDescriptor[0]); + } + + @Override + public Object getPropertyValue(Object id) { + if (id.equals(ID_FILE_NAME)) { + return fSourceLookup.getCallsite().getFileName(); + } else if (id.equals(ID_FUNCTION_NAME)) { + return fSourceLookup.getCallsite().getFunctionName(); + } else if (id.equals(ID_LINE_NUMBER)) { + return Long.valueOf(fSourceLookup.getCallsite().getLineNumber()); + } + return null; + } + + @Override + public boolean isPropertySet(Object id) { + return false; + } + + @Override + public void resetPropertyValue(Object id) { + + } + + @Override + public void setPropertyValue(Object id, Object value) { + } + } + + private class CustomAttributePropertySource implements IPropertySource { + + private final ITmfCustomAttributes event; + + public CustomAttributePropertySource(ITmfCustomAttributes event) { + this.event = event; + } + + @Override + public Object getEditableValue() { + return EMPTY_STRING; + } + + @Override + public IPropertyDescriptor[] getPropertyDescriptors() { + List descriptors = new ArrayList<>(); + + for (String customAttribute : event.listCustomAttributes()) { + descriptors.add(new ReadOnlyTextPropertyDescriptor(customAttribute, customAttribute)); + } + + return descriptors.toArray(new IPropertyDescriptor[0]); + } + + @Override + public Object getPropertyValue(Object id) { + return event.getCustomAttribute((String) id); + } + + @Override + public boolean isPropertySet(Object id) { + return false; + } + + @Override + public void resetPropertyValue(Object id) { + } + + @Override + public void setPropertyValue(Object id, Object value) { + } + } + + /** + * Default constructor + * + * @param event the event + */ + public TmfEventPropertySource(ITmfEvent event) { + super(); + this.fEvent = event; + } + + @Override + public Object getEditableValue() { + return null; + } + + @Override + public IPropertyDescriptor[] getPropertyDescriptors() { + List descriptors= new ArrayList<>(); + + /* Display basic event information */ + descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_TIMESTAMP, NAME_TIMESTAMP)); + descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_SOURCE, NAME_SOURCE)); + descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_TYPE, NAME_TYPE)); + descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_REFERENCE, NAME_REFERENCE)); + descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_TRACE, NAME_TRACE)); + + /* Display event fields */ + descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_CONTENT, NAME_CONTENT)); + + /* Display source lookup information, if the event supplies it */ + if ((fEvent instanceof ITmfSourceLookup) && (((ITmfSourceLookup)fEvent).getCallsite() != null)) { + descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_SOURCE_LOOKUP, NAME_SOURCE_LOOKUP)); + } + + /* Display Model URI information, if the event supplies it */ + if ((fEvent instanceof ITmfModelLookup) && (((ITmfModelLookup) fEvent).getModelUri() != null)) { + descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_MODEL_URI, NAME_MODEL_URI)); + } + + /* Display custom attributes, if available */ + if (fEvent instanceof ITmfCustomAttributes) { + ITmfCustomAttributes event = (ITmfCustomAttributes) fEvent; + if (event.listCustomAttributes() != null && !event.listCustomAttributes().isEmpty()) { + descriptors.add(new ReadOnlyTextPropertyDescriptor(ID_CUSTOM_ATTRIBUTE, NAME_CUSTOM_ATTRIBUTES)); + } + } + + return descriptors.toArray(new IPropertyDescriptor[0]); + } + + @Override + public Object getPropertyValue(Object id) { + if (id.equals(ID_TIMESTAMP) && fEvent.getTimestamp() != null) { + return new TimestampPropertySource(fEvent.getTimestamp()); + } else if (id.equals(ID_SOURCE) && fEvent.getSource() != null) { + return fEvent.getSource().toString(); + } else if (id.equals(ID_TYPE) && fEvent.getType() != null) { + return fEvent.getType().toString(); + } else if (id.equals(ID_REFERENCE) && fEvent.getReference() != null) { + return fEvent.getReference().toString(); + } else if (id.equals(ID_TRACE) && fEvent.getTrace() != null) { + return fEvent.getTrace().getName(); + } else if (id.equals(ID_MODEL_URI)) { + return ((ITmfModelLookup)fEvent).getModelUri(); + } else if (id.equals(ID_SOURCE_LOOKUP)) { + return new SourceLookupPropertySource(((ITmfSourceLookup)fEvent)); + } else if (id.equals(ID_CONTENT) && fEvent.getContent() != null) { + return new ContentPropertySource(fEvent.getContent()); + } else if (id.equals(ID_CUSTOM_ATTRIBUTE)) { + return new CustomAttributePropertySource((ITmfCustomAttributes) fEvent); + } + return null; + } + + @Override + public boolean isPropertySet(Object id) { + return false; + } + + @Override + public void resetPropertyValue(Object id) { + } + + @Override + public void setPropertyValue(Object id, Object value) { + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventsCache.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventsCache.java new file mode 100644 index 0000000000..1ef789b368 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventsCache.java @@ -0,0 +1,489 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Bernd Hufmann - Add support for event collapsing + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.events; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.tracecompass.internal.tmf.core.filter.TmfCollapseFilter; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.component.ITmfEventProvider; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.core.filter.ITmfFilter; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * The generic TMF Events table events cache + * + * This can help avoid re-reading the trace when the user scrolls a window, + * for example. + * + * @author Patrick Tasse + */ +public class TmfEventsCache { + + /** + * The generic TMF Events table cached event. + * + * @author Patrick Tasse + */ + public static class CachedEvent implements ITmfEvent { + /** + * Event reference. + * + * When {@link TmfCollapseFilter} is active then it's event reference + * of the first event of repeated events. + */ + ITmfEvent event; + /** + * Events rank. + * + * When {@link TmfCollapseFilter} is active then it's event rank of the + * first event of repeated events. + */ + long rank; + /** + * Number times event is repeated. Updated by using {@link TmfCollapseFilter} + */ + long repeatCount; + + /** + * Constructor for new cached events. + * + * @param iTmfEvent + * The original trace event + * @param rank + * The rank of this event in the trace + */ + public CachedEvent (ITmfEvent iTmfEvent, long rank) { + this.event = iTmfEvent; + this.rank = rank; + } + /** + * @since 3.2 + */ + @Override + public Object getAdapter(Class adapter) { + return event.getAdapter(adapter); + } + /** + * @since 3.2 + */ + @Override + public ITmfTrace getTrace() { + return event.getTrace(); + } + /** + * @since 3.2 + */ + @Override + public long getRank() { + return event.getRank(); + } + /** + * @since 3.2 + */ + @Override + public ITmfTimestamp getTimestamp() { + return event.getTimestamp(); + } + /** + * @since 3.2 + */ + @Override + public String getSource() { + return event.getSource(); + } + /** + * @since 3.2 + */ + @Override + public ITmfEventType getType() { + return event.getType(); + } + /** + * @since 3.2 + */ + @Override + public ITmfEventField getContent() { + return event.getContent(); + } + /** + * @since 3.2 + */ + @Override + public String getReference() { + return event.getReference(); + } + } + + private final CachedEvent[] fCache; + private final int fCacheSize; + private int fCacheStartIndex = 0; + private int fCacheEndIndex = 0; + + private ITmfTrace fTrace; + private final TmfEventsTable fTable; + private ITmfFilter fFilter; + private final List fFilterIndex = new ArrayList<>(); // contains the event rank at each 'cache size' filtered events + + /** + * Constructor for the event cache + * + * @param cacheSize + * The size of the cache, in number of events + * @param table + * The Events table this cache will cover + */ + public TmfEventsCache(int cacheSize, TmfEventsTable table) { + fCacheSize = cacheSize; + fCache = new CachedEvent[cacheSize * 2]; // the cache holds two blocks of cache size + fTable = table; + } + + /** + * Assign a new trace to this events cache. This clears the current + * contents. + * + * @param trace + * The trace to assign. + */ + public void setTrace(ITmfTrace trace) { + fTrace = trace; + clear(); + } + + /** + * Clear the current contents of this cache. + */ + public synchronized void clear() { + if (job != null && job.getState() != Job.NONE) { + job.cancel(); + } + Arrays.fill(fCache, null); + fCacheStartIndex = 0; + fCacheEndIndex = 0; + fFilterIndex.clear(); + } + + /** + * Apply a filter on this event cache. This clears the current cache + * contents. + * + * @param filter + * The ITmfFilter to apply. + */ + public void applyFilter(ITmfFilter filter) { + fFilter = filter; + clear(); + } + + /** + * Clear the current filter on this cache. This also clears the current + * cache contents. + */ + public void clearFilter() { + fFilter = null; + clear(); + } + + /** + * Get an event from the cache. If the cache does not contain the event, + * a cache population request is triggered. + * + * @param index + * The index of this event in the cache + * @return The cached event, or 'null' if the event is not in the cache + */ + public synchronized CachedEvent getEvent(int index) { + if ((index >= fCacheStartIndex) && (index < fCacheEndIndex)) { + int i = index - fCacheStartIndex; + return fCache[i]; + } + populateCache(index); + return null; + } + + /** + * Peek an event in the cache. Does not trigger cache population. + * + * @param index + * Index of the event to peek + * @return The cached event, or 'null' if the event is not in the cache + */ + public synchronized CachedEvent peekEvent(int index) { + if ((index >= fCacheStartIndex) && (index < fCacheEndIndex)) { + int i = index - fCacheStartIndex; + return fCache[i]; + } + return null; + } + + /** + * Add a trace event to the cache. + * + * @param event + * The original trace event to be cached + * @param rank + * The rank of this event in the trace + * @param index + * The index this event will occupy in the cache + */ + public synchronized void storeEvent(ITmfEvent event, long rank, int index) { + if (index == fCacheEndIndex) { + int i = index - fCacheStartIndex; + if (i < fCache.length) { + fCache[i] = new CachedEvent(event, rank); + fCacheEndIndex++; + } + } + if ((fFilter != null) && ((index % fCacheSize) == 0)) { + int i = index / fCacheSize; + fFilterIndex.add(i, Integer.valueOf((int) rank)); + } + } + + /** + * Update event repeat count at index + * + * @param index + * The index this event occupies in the cache + * + * @since 3.2 + */ + public synchronized void updateCollapsedEvent(int index) { + int i = index - fCacheStartIndex; + if (i < fCache.length) { + fCache[i].repeatCount++; + } + } + + /** + * Get the cache index of an event from his rank in the trace. This will + * take in consideration any filter that might be applied. + * + * @param rank + * The rank of the event in the trace + * @return The position (index) this event should use once cached + */ + public int getFilteredEventIndex(final long rank) { + int current; + int startRank; + TmfEventRequest request; + final ITmfFilter filter = fFilter; + synchronized (this) { + int start = 0; + int end = fFilterIndex.size(); + + if ((fCacheEndIndex - fCacheStartIndex) > 1) { + if (rank < fCache[0].rank) { + end = (fCacheStartIndex / fCacheSize) + 1; + } else if (rank > fCache[fCacheEndIndex - fCacheStartIndex - 1].rank) { + start = fCacheEndIndex / fCacheSize; + } else { + for (int i = 0; i < (fCacheEndIndex - fCacheStartIndex); i++) { + if (fCache[i].rank >= rank) { + return fCacheStartIndex + i; + } + } + return fCacheEndIndex; + } + } + + current = (start + end) / 2; + while (current != start) { + if (rank < fFilterIndex.get(current)) { + end = current; + current = (start + end) / 2; + } else { + start = current; + current = (start + end) / 2; + } + } + startRank = fFilterIndex.size() > 0 ? fFilterIndex.get(current) : 0; + } + + final int index = current * fCacheSize; + + class DataRequest extends TmfEventRequest { + ITmfFilter requestFilter; + int requestRank; + int requestIndex; + + DataRequest(Class dataType, ITmfFilter reqFilter, int start, int nbRequested) { + super(dataType, TmfTimeRange.ETERNITY, start, nbRequested, + TmfEventRequest.ExecutionType.FOREGROUND); + requestFilter = reqFilter; + requestRank = start; + requestIndex = index; + } + + @Override + public void handleData(ITmfEvent event) { + super.handleData(event); + if (isCancelled()) { + return; + } + if (requestRank >= rank) { + cancel(); + return; + } + requestRank++; + if (requestFilter.matches(event)) { + requestIndex++; + } + } + + public int getFilteredIndex() { + return requestIndex; + } + } + + request = new DataRequest(ITmfEvent.class, filter, startRank, ITmfEventRequest.ALL_DATA); + ((ITmfEventProvider) fTrace).sendRequest(request); + try { + request.waitForCompletion(); + return ((DataRequest) request).getFilteredIndex(); + } catch (InterruptedException e) { + Activator.getDefault().logError("Filter request interrupted!", e); //$NON-NLS-1$ + } + return 0; + } + + // ------------------------------------------------------------------------ + // Event cache population + // ------------------------------------------------------------------------ + + // The event fetching job + private Job job; + private synchronized void populateCache(final int index) { + + /* Check if the current job will fetch the requested event: + * 1. The job must exist + * 2. It must be running (i.e. not completed) + * 3. The requested index must be within the cache range + * + * If the job meets these conditions, we simply exit. + * Otherwise, we create a new job but we might have to cancel + * an existing job for an obsolete range. + */ + if (job != null) { + if (job.getState() != Job.NONE) { + if ((index >= fCacheStartIndex) && (index < (fCacheStartIndex + fCache.length))) { + return; + } + // The new index is out of the requested range + // Kill the job and start a new one + job.cancel(); + } + } + + // Populate the cache starting at the index that is one block less + // of cache size than the requested index. The cache will hold two + // consecutive blocks of cache size, centered on the requested index. + fCacheStartIndex = Math.max(0, index - fCacheSize); + fCacheEndIndex = fCacheStartIndex; + + job = new Job("Fetching Events") { //$NON-NLS-1$ + private int startIndex = fCacheStartIndex; + private int skipCount = 0; + @Override + protected IStatus run(final IProgressMonitor monitor) { + + int nbRequested; + if (fFilter == null) { + nbRequested = fCache.length; + } else { + nbRequested = ITmfEventRequest.ALL_DATA; + int i = startIndex / fCacheSize; + if (i < fFilterIndex.size()) { + skipCount = startIndex - (i * fCacheSize); + startIndex = fFilterIndex.get(i); + } + } + + TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, + TmfTimeRange.ETERNITY, + startIndex, + nbRequested, + TmfEventRequest.ExecutionType.FOREGROUND) { + private int count = 0; + private long rank = startIndex; + @Override + public void handleData(ITmfEvent event) { + // If the job is canceled, cancel the request so waitForCompletion() will unlock + if (monitor.isCanceled()) { + cancel(); + return; + } + super.handleData(event); + if (((fFilter == null) || fFilter.matches(event)) && (skipCount-- <= 0)) { + synchronized (TmfEventsCache.this) { + if (monitor.isCanceled()) { + return; + } + fCache[count] = new CachedEvent(event, rank); + count++; + fCacheEndIndex++; + } + if (fFilter != null) { + fTable.cacheUpdated(false); + } + } else if (((fFilter != null) && !fFilter.matches(event)) && (skipCount <= 0)) { // TODO fix duplicated call to matches() + if ((count > 0) && (fFilter instanceof TmfCollapseFilter)) { + fCache[count - 1].repeatCount++; + } + } + if (count >= fCache.length) { + cancel(); + } else if ((fFilter != null) && (count >= (fTable.getTable().getItemCount() - 3))) { // -1 for header row, -2 for top and bottom filter status rows + cancel(); + } + rank++; + } + }; + + ((ITmfEventProvider) fTrace).sendRequest(request); + try { + request.waitForCompletion(); + } catch (InterruptedException e) { + Activator.getDefault().logError("Wait for completion interrupted for populateCache ", e); //$NON-NLS-1$ + } + + fTable.cacheUpdated(true); + + // Flag the UI thread that the cache is ready + if (monitor.isCanceled()) { + return Status.CANCEL_STATUS; + } + return Status.OK_STATUS; + } + }; + //job.setSystem(true); + job.setPriority(Job.SHORT); + job.schedule(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventsTable.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventsTable.java new file mode 100644 index 0000000000..2f7783f16b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventsTable.java @@ -0,0 +1,2539 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation, replaced Table by TmfVirtualTable + * Patrick Tasse - Factored out from events view, + * Filter implementation (inspired by www.eclipse.org/mat) + * Ansgar Radermacher - Support navigation to model URIs (Bug 396956) + * Bernd Hufmann - Updated call site and model URI implementation + * Alexandre Montplaisir - Update to new column API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.events; + +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map.Entry; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.NotEnabledException; +import org.eclipse.core.commands.NotHandledException; +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.core.commands.common.NotDefinedException; +import org.eclipse.core.expressions.IEvaluationContext; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceVisitor; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EValidator; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.util.OpenStrategy; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.custom.TableEditor; +import org.eclipse.swt.events.FocusAdapter; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.internal.tmf.core.filter.TmfCollapseFilter; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.internal.tmf.ui.commands.ExportToTextCommandHandler; +import org.eclipse.tracecompass.internal.tmf.ui.dialogs.MultiLineInputDialog; +import org.eclipse.tracecompass.tmf.core.component.ITmfEventProvider; +import org.eclipse.tracecompass.tmf.core.component.TmfComponent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.collapse.ITmfCollapsibleEvent; +import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfCallsite; +import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfModelLookup; +import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfSourceLookup; +import org.eclipse.tracecompass.tmf.core.filter.ITmfFilter; +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterAndNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterMatchesNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterNode; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.signal.TmfEventFilterAppliedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfEventSearchAppliedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfEventSelectedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceUpdatedSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; +import org.eclipse.tracecompass.tmf.ui.viewers.events.TmfEventsCache.CachedEvent; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; +import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableFieldColumn; +import org.eclipse.tracecompass.tmf.ui.views.colors.ColorSetting; +import org.eclipse.tracecompass.tmf.ui.views.colors.ColorSettingsManager; +import org.eclipse.tracecompass.tmf.ui.views.colors.IColorSettingsListener; +import org.eclipse.tracecompass.tmf.ui.views.filter.FilterManager; +import org.eclipse.tracecompass.tmf.ui.widgets.rawviewer.TmfRawEventViewer; +import org.eclipse.tracecompass.tmf.ui.widgets.virtualtable.TmfVirtualTable; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.dialogs.ListDialog; +import org.eclipse.ui.handlers.IHandlerService; +import org.eclipse.ui.ide.IDE; +import org.eclipse.ui.ide.IGotoMarker; +import org.eclipse.ui.themes.ColorUtil; + +import com.google.common.base.Joiner; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Multimap; + +/** + * The generic TMF Events table + * + * This is a view that will list events that are read from a trace. + * + * @author Francois Chouinard + * @author Patrick Tasse + * @since 2.0 + */ +public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorSettingsListener, ISelectionProvider { + + /** + * Empty string array, used by {@link #getItemStrings}. + * @since 3.0 + */ + protected static final @NonNull String[] EMPTY_STRING_ARRAY = new String[0]; + + /** + * Empty string + * @since 3.1 + */ + protected static final @NonNull String EMPTY_STRING = ""; //$NON-NLS-1$ + + private static final boolean IS_LINUX = System.getProperty("os.name").contains("Linux") ? true : false; //$NON-NLS-1$ //$NON-NLS-2$ + + private static final Image BOOKMARK_IMAGE = Activator.getDefault().getImageFromPath( + "icons/elcl16/bookmark_obj.gif"); //$NON-NLS-1$ + private static final Image SEARCH_IMAGE = Activator.getDefault().getImageFromPath("icons/elcl16/search.gif"); //$NON-NLS-1$ + private static final Image SEARCH_MATCH_IMAGE = Activator.getDefault().getImageFromPath( + "icons/elcl16/search_match.gif"); //$NON-NLS-1$ + private static final Image SEARCH_MATCH_BOOKMARK_IMAGE = Activator.getDefault().getImageFromPath( + "icons/elcl16/search_match_bookmark.gif"); //$NON-NLS-1$ + private static final Image FILTER_IMAGE = Activator.getDefault() + .getImageFromPath("icons/elcl16/filter_items.gif"); //$NON-NLS-1$ + private static final Image STOP_IMAGE = Activator.getDefault().getImageFromPath("icons/elcl16/stop.gif"); //$NON-NLS-1$ + private static final String SEARCH_HINT = Messages.TmfEventsTable_SearchHint; + private static final String FILTER_HINT = Messages.TmfEventsTable_FilterHint; + private static final int MAX_CACHE_SIZE = 1000; + + private static final int MARGIN_COLUMN_INDEX = 0; + private static final int FILTER_SUMMARY_INDEX = 1; + private static final int EVENT_COLUMNS_START_INDEX = MARGIN_COLUMN_INDEX + 1; + + /** + * Default set of columns to use for trace types that do not specify + * anything + * @since 3.2 + */ + public static final Collection DEFAULT_COLUMNS = ImmutableList.of( + TmfEventTableColumn.BaseColumns.TIMESTAMP, + TmfEventTableColumn.BaseColumns.SOURCE, + TmfEventTableColumn.BaseColumns.EVENT_TYPE, + TmfEventTableColumn.BaseColumns.REFERENCE, + TmfEventTableColumn.BaseColumns.CONTENTS + ); + + /** + * The events table search/filter keys + * + * @version 1.0 + * @author Patrick Tasse + */ + public interface Key { + /** Search text */ + String SEARCH_TXT = "$srch_txt"; //$NON-NLS-1$ + + /** Search object */ + String SEARCH_OBJ = "$srch_obj"; //$NON-NLS-1$ + + /** Filter text */ + String FILTER_TXT = "$fltr_txt"; //$NON-NLS-1$ + + /** Filter object */ + String FILTER_OBJ = "$fltr_obj"; //$NON-NLS-1$ + + /** Timestamp */ + String TIMESTAMP = "$time"; //$NON-NLS-1$ + + /** Rank */ + String RANK = "$rank"; //$NON-NLS-1$ + + /** Field ID */ + String FIELD_ID = "$field_id"; //$NON-NLS-1$ + + /** Bookmark indicator */ + String BOOKMARK = "$bookmark"; //$NON-NLS-1$ + } + + /** + * The events table search/filter state + * + * @version 1.0 + * @author Patrick Tasse + */ + public static enum HeaderState { + /** A search is being run */ + SEARCH, + + /** A filter is applied */ + FILTER + } + + interface Direction { + int FORWARD = +1; + int BACKWARD = -1; + } + + // ------------------------------------------------------------------------ + // Table data + // ------------------------------------------------------------------------ + + /** The virtual event table */ + protected TmfVirtualTable fTable; + + private Composite fComposite; + private SashForm fSashForm; + private TmfRawEventViewer fRawViewer; + private ITmfTrace fTrace; + volatile private boolean fPackDone = false; + private HeaderState fHeaderState = HeaderState.SEARCH; + private long fSelectedRank = 0; + private ITmfTimestamp fSelectedBeginTimestamp = null; + private IStatusLineManager fStatusLineManager = null; + + // Filter data + private long fFilterMatchCount; + private long fFilterCheckCount; + private FilterThread fFilterThread; + private boolean fFilterThreadResume = false; + private final Object fFilterSyncObj = new Object(); + private SearchThread fSearchThread; + private final Object fSearchSyncObj = new Object(); + + /** + * List of selection change listeners (element type: ISelectionChangedListener). + * + * @see #fireSelectionChanged + */ + private ListenerList selectionChangedListeners = new ListenerList(); + + // Bookmark map + private Multimap fBookmarksMap = HashMultimap.create(); + private IFile fBookmarksFile; + private long fPendingGotoRank = -1; + + // SWT resources + private LocalResourceManager fResourceManager = new LocalResourceManager(JFaceResources.getResources()); + private Color fGrayColor; + private Color fGreenColor; + private Font fBoldFont; + + private final List fColumns = new LinkedList<>(); + + // Event cache + private final TmfEventsCache fCache; + private boolean fCacheUpdateBusy = false; + private boolean fCacheUpdatePending = false; + private boolean fCacheUpdateCompleted = false; + private final Object fCacheUpdateSyncObj = new Object(); + + private boolean fDisposeOnClose; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Basic constructor, using the default set of columns + * + * @param parent + * The parent composite UI object + * @param cacheSize + * The size of the event table cache + */ + public TmfEventsTable(final Composite parent, final int cacheSize) { + this(parent, cacheSize, DEFAULT_COLUMNS); + } + + /** + * Legacy constructor, using ColumnData to define columns + * + * @param parent + * The parent composite UI object + * @param cacheSize + * The size of the event table cache + * @param columnData + * Unused + * @deprecated Deprecated constructor, use + * {@link #TmfEventsTable(Composite, int, Collection)} + */ + @Deprecated + public TmfEventsTable(final Composite parent, int cacheSize, + final org.eclipse.tracecompass.tmf.ui.widgets.virtualtable.ColumnData[] columnData) { + /* + * We'll do a "best-effort" to keep trace types still using this API to + * keep working, by defining a TmfEventTableFieldColumn for each + * ColumnData they passed. + */ + this(parent, cacheSize, convertFromColumnData(columnData)); + } + + @Deprecated + private static Collection convertFromColumnData( + org.eclipse.tracecompass.tmf.ui.widgets.virtualtable.ColumnData[] columnData) { + + ImmutableList.Builder builder = new ImmutableList.Builder<>(); + for (org.eclipse.tracecompass.tmf.ui.widgets.virtualtable.ColumnData col : columnData) { + String header = col.header; + if (header != null) { + builder.add(new TmfEventTableFieldColumn(header)); + } + } + return builder.build(); + } + + /** + * Standard constructor, where we define which columns to use. + * + * @param parent + * The parent composite UI object + * @param cacheSize + * The size of the event table cache + * @param columns + * The columns to use in this table. + *

    + * The iteration order of this collection will correspond to the + * initial ordering of this series of columns in the table. + *

    + * @since 3.1 + */ + public TmfEventsTable(final Composite parent, int cacheSize, + Collection columns) { + super("TmfEventsTable"); //$NON-NLS-1$ + + fComposite = new Composite(parent, SWT.NONE); + final GridLayout gl = new GridLayout(1, false); + gl.marginHeight = 0; + gl.marginWidth = 0; + gl.verticalSpacing = 0; + fComposite.setLayout(gl); + + fSashForm = new SashForm(fComposite, SWT.HORIZONTAL); + fSashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + // Create a virtual table + final int style = SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION; + fTable = new TmfVirtualTable(fSashForm, style); + + // Set the table layout + final GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + fTable.setLayoutData(layoutData); + + // Some cosmetic enhancements + fTable.setHeaderVisible(true); + fTable.setLinesVisible(true); + + // Setup the columns + if (columns != null) { + fColumns.addAll(columns); + } + + TmfMarginColumn collapseCol = new TmfMarginColumn(); + fColumns.add(MARGIN_COLUMN_INDEX, collapseCol); + + // Create the UI columns in the table + for (TmfEventTableColumn col : fColumns) { + TableColumn column = fTable.newTableColumn(SWT.LEFT); + column.setText(col.getHeaderName()); + column.setToolTipText(col.getHeaderTooltip()); + column.setData(Key.FIELD_ID, col.getFilterFieldId()); + column.pack(); + if (col instanceof TmfMarginColumn) { + column.setResizable(false); + } + } + + // Set the frozen row for header row + fTable.setFrozenRowCount(1); + + // Create the header row cell editor + createHeaderEditor(); + + // Handle the table item selection + fTable.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + if (e.item == null) { + return; + } + updateStatusLine(null); + if (fTable.getSelectionIndices().length > 0) { + if (e.item.getData(Key.RANK) instanceof Long) { + fSelectedRank = (Long) e.item.getData(Key.RANK); + fRawViewer.selectAndReveal((Long) e.item.getData(Key.RANK)); + } + if (e.item.getData(Key.TIMESTAMP) instanceof ITmfTimestamp) { + final ITmfTimestamp ts = (ITmfTimestamp) e.item.getData(Key.TIMESTAMP); + if (fTable.getSelectionIndices().length == 1) { + fSelectedBeginTimestamp = ts; + } + if (fSelectedBeginTimestamp != null) { + if (fSelectedBeginTimestamp.compareTo(ts) <= 0) { + broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, fSelectedBeginTimestamp, ts)); + if (fTable.getSelectionIndices().length == 2) { + updateStatusLine(ts.getDelta(fSelectedBeginTimestamp)); + } + } else { + broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, ts, fSelectedBeginTimestamp)); + updateStatusLine(fSelectedBeginTimestamp.getDelta(ts)); + } + } + } else { + if (fTable.getSelectionIndices().length == 1) { + fSelectedBeginTimestamp = null; + } + } + } + if (e.item.getData() instanceof ITmfEvent) { + broadcast(new TmfEventSelectedSignal(TmfEventsTable.this, (ITmfEvent) e.item.getData())); + fireSelectionChanged(new SelectionChangedEvent(TmfEventsTable.this, new StructuredSelection(e.item.getData()))); + } else { + fireSelectionChanged(new SelectionChangedEvent(TmfEventsTable.this, StructuredSelection.EMPTY)); + } + } + }); + + int realCacheSize = Math.max(cacheSize, Display.getDefault().getBounds().height / fTable.getItemHeight()); + realCacheSize = Math.min(realCacheSize, MAX_CACHE_SIZE); + fCache = new TmfEventsCache(realCacheSize, this); + + // Handle the table item requests + fTable.addListener(SWT.SetData, new Listener() { + + @Override + public void handleEvent(final Event event) { + + final TableItem item = (TableItem) event.item; + int index = event.index - 1; // -1 for the header row + + if (event.index == 0) { + setHeaderRowItemData(item); + return; + } + + if (fTable.getData(Key.FILTER_OBJ) != null) { + if ((event.index == 1) || (event.index == (fTable.getItemCount() - 1))) { + setFilterStatusRowItemData(item); + return; + } + index = index - 1; // -1 for top filter status row + } + + final CachedEvent cachedEvent = fCache.getEvent(index); + if (cachedEvent != null) { + setItemData(item, cachedEvent, cachedEvent.rank); + return; + } + + // Else, fill the cache asynchronously (and off the UI thread) + event.doit = false; + } + }); + + fTable.addMouseListener(new MouseAdapter() { + @Override + public void mouseDoubleClick(final MouseEvent event) { + if (event.button != 1) { + return; + } + // Identify the selected row + final Point point = new Point(event.x, event.y); + final TableItem item = fTable.getItem(point); + if (item != null) { + final Rectangle imageBounds = item.getImageBounds(0); + imageBounds.width = BOOKMARK_IMAGE.getBounds().width; + if (imageBounds.contains(point)) { + final Long rank = (Long) item.getData(Key.RANK); + if (rank != null) { + toggleBookmark(rank); + } + } + } + } + }); + + final Listener tooltipListener = new Listener () { + Shell tooltipShell = null; + @Override + public void handleEvent(final Event event) { + switch (event.type) { + case SWT.MouseHover: + final TableItem item = fTable.getItem(new Point(event.x, event.y)); + if (item == null) { + return; + } + final Long rank = (Long) item.getData(Key.RANK); + if (rank == null) { + return; + } + final String tooltipText = (String) item.getData(Key.BOOKMARK); + final Rectangle bounds = item.getImageBounds(0); + bounds.width = BOOKMARK_IMAGE.getBounds().width; + if (!bounds.contains(event.x,event.y)) { + return; + } + if ((tooltipShell != null) && !tooltipShell.isDisposed()) { + tooltipShell.dispose(); + } + tooltipShell = new Shell(fTable.getShell(), SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL); + tooltipShell.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + final FillLayout layout = new FillLayout(); + layout.marginWidth = 2; + tooltipShell.setLayout(layout); + final Label label = new Label(tooltipShell, SWT.WRAP); + String text = rank.toString() + (tooltipText != null ? ": " + tooltipText : EMPTY_STRING); //$NON-NLS-1$ + label.setForeground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND)); + label.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + label.setText(text); + label.addListener(SWT.MouseExit, this); + label.addListener(SWT.MouseDown, this); + label.addListener(SWT.MouseWheel, this); + final Point size = tooltipShell.computeSize(SWT.DEFAULT, SWT.DEFAULT); + /* + * Bug in Linux. The coordinates of the event have an origin that excludes the table header but + * the method toDisplay() expects coordinates relative to an origin that includes the table header. + */ + int y = event.y; + if (IS_LINUX) { + y += fTable.getHeaderHeight(); + } + Point pt = fTable.toDisplay(event.x, y); + pt.x += BOOKMARK_IMAGE.getBounds().width; + pt.y += item.getBounds().height; + tooltipShell.setBounds(pt.x, pt.y, size.x, size.y); + tooltipShell.setVisible(true); + break; + case SWT.Dispose: + case SWT.KeyDown: + case SWT.MouseMove: + case SWT.MouseExit: + case SWT.MouseDown: + case SWT.MouseWheel: + if (tooltipShell != null) { + tooltipShell.dispose(); + tooltipShell = null; + } + break; + default: + break; + } + } + }; + + fTable.addListener(SWT.MouseHover, tooltipListener); + fTable.addListener(SWT.Dispose, tooltipListener); + fTable.addListener(SWT.KeyDown, tooltipListener); + fTable.addListener(SWT.MouseMove, tooltipListener); + fTable.addListener(SWT.MouseExit, tooltipListener); + fTable.addListener(SWT.MouseDown, tooltipListener); + fTable.addListener(SWT.MouseWheel, tooltipListener); + + // Create resources + createResources(); + + ColorSettingsManager.addColorSettingsListener(this); + + fTable.setItemCount(1); // +1 for header row + + fRawViewer = new TmfRawEventViewer(fSashForm, SWT.H_SCROLL | SWT.V_SCROLL); + + fRawViewer.addSelectionListener(new Listener() { + @Override + public void handleEvent(final Event e) { + if (e.data instanceof Long) { + final long rank = (Long) e.data; + int index = (int) rank; + if (fTable.getData(Key.FILTER_OBJ) != null) { + index = fCache.getFilteredEventIndex(rank) + 1; // +1 for top filter status row + } + fTable.setSelection(index + 1); // +1 for header row + fSelectedRank = rank; + updateStatusLine(null); + } else if (e.data instanceof ITmfLocation) { + // DOES NOT WORK: rank undefined in context from seekLocation() + // ITmfLocation location = (ITmfLocation) e.data; + // TmfContext context = fTrace.seekLocation(location); + // fTable.setSelection((int) context.getRank()); + return; + } else { + return; + } + final TableItem[] selection = fTable.getSelection(); + if ((selection != null) && (selection.length > 0)) { + final TmfTimestamp ts = (TmfTimestamp) fTable.getSelection()[0].getData(Key.TIMESTAMP); + if (ts != null) { + broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, ts)); + } + } + } + }); + + fSashForm.setWeights(new int[] { 1, 1 }); + fRawViewer.setVisible(false); + + createPopupMenu(); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Create a pop-up menu. + */ + protected void createPopupMenu() { + final IAction showTableAction = new Action(Messages.TmfEventsTable_ShowTableActionText) { + @Override + public void run() { + fTable.setVisible(true); + fSashForm.layout(); + } + }; + + final IAction hideTableAction = new Action(Messages.TmfEventsTable_HideTableActionText) { + @Override + public void run() { + fTable.setVisible(false); + fSashForm.layout(); + } + }; + + final IAction showRawAction = new Action(Messages.TmfEventsTable_ShowRawActionText) { + @Override + public void run() { + fRawViewer.setVisible(true); + fSashForm.layout(); + final int index = fTable.getSelectionIndex(); + if (index >= 1) { + fRawViewer.selectAndReveal(index - 1); + } + } + }; + + final IAction hideRawAction = new Action(Messages.TmfEventsTable_HideRawActionText) { + @Override + public void run() { + fRawViewer.setVisible(false); + fSashForm.layout(); + } + }; + + final IAction openCallsiteAction = new Action(Messages.TmfEventsTable_OpenSourceCodeActionText) { + @Override + public void run() { + final TableItem items[] = fTable.getSelection(); + if (items.length != 1) { + return; + } + final TableItem item = items[0]; + + final Object data = item.getData(); + if (data instanceof ITmfSourceLookup) { + ITmfSourceLookup event = (ITmfSourceLookup) data; + ITmfCallsite cs = event.getCallsite(); + if (cs == null || cs.getFileName() == null) { + return; + } + IMarker marker = null; + try { + String fileName = cs.getFileName(); + final String trimmedPath = fileName.replaceAll("\\.\\./", EMPTY_STRING); //$NON-NLS-1$ + final ArrayList files = new ArrayList<>(); + ResourcesPlugin.getWorkspace().getRoot().accept(new IResourceVisitor() { + @Override + public boolean visit(IResource resource) throws CoreException { + if (resource instanceof IFile && resource.getFullPath().toString().endsWith(trimmedPath)) { + files.add((IFile) resource); + } + return true; + } + }); + IFile file = null; + if (files.size() > 1) { + ListDialog dialog = new ListDialog(getTable().getShell()); + dialog.setContentProvider(ArrayContentProvider.getInstance()); + dialog.setLabelProvider(new LabelProvider() { + @Override + public String getText(Object element) { + return ((IFile) element).getFullPath().toString(); + } + }); + dialog.setInput(files); + dialog.setTitle(Messages.TmfEventsTable_OpenSourceCodeSelectFileDialogTitle); + dialog.setMessage(Messages.TmfEventsTable_OpenSourceCodeSelectFileDialogTitle + '\n' + cs.toString()); + dialog.open(); + Object[] result = dialog.getResult(); + if (result != null && result.length > 0) { + file = (IFile) result[0]; + } + } else if (files.size() == 1) { + file = files.get(0); + } + if (file != null) { + marker = file.createMarker(IMarker.MARKER); + marker.setAttribute(IMarker.LINE_NUMBER, Long.valueOf(cs.getLineNumber()).intValue()); + IDE.openEditor(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(), marker); + marker.delete(); + } else if (files.size() == 0){ + displayException(new FileNotFoundException('\'' + cs.toString() + '\'' + '\n' + Messages.TmfEventsTable_OpenSourceCodeNotFound)); + } + } catch (CoreException e) { + displayException(e); + } + } + } + }; + + final IAction openModelAction = new Action(Messages.TmfEventsTable_OpenModelActionText) { + @Override + public void run() { + + final TableItem items[] = fTable.getSelection(); + if (items.length != 1) { + return; + } + final TableItem item = items[0]; + + final Object eventData = item.getData(); + if (eventData instanceof ITmfModelLookup) { + String modelURI = ((ITmfModelLookup) eventData).getModelUri(); + + if (modelURI != null) { + IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + + IFile file = null; + final URI uri = URI.createURI(modelURI); + if (uri.isPlatformResource()) { + IPath path = new Path(uri.toPlatformString(true)); + file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); + } else if (uri.isFile() && !uri.isRelative()) { + file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation( + new Path(uri.toFileString())); + } + + if (file != null) { + try { + /* + * create a temporary validation marker on the + * model file, remove it afterwards thus, + * navigation works with all model editors + * supporting the navigation to a marker + */ + IMarker marker = file.createMarker(EValidator.MARKER); + marker.setAttribute(EValidator.URI_ATTRIBUTE, modelURI); + marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO); + + IDE.openEditor(activePage, marker, OpenStrategy.activateOnOpen()); + marker.delete(); + } + catch (CoreException e) { + displayException(e); + } + } else { + displayException(new FileNotFoundException('\'' + modelURI + '\'' + '\n' + Messages.TmfEventsTable_OpenModelUnsupportedURI)); + } + } + } + } + }; + + final IAction exportToTextAction = new Action(Messages.TmfEventsTable_Export_to_text) { + @Override + public void run() { + IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + IHandlerService handlerService = (IHandlerService) activePage.getActiveEditor().getSite().getService(IHandlerService.class); + ICommandService cmdService = (ICommandService) activePage.getActiveEditor().getSite().getService(ICommandService.class); + try { + HashMap parameters = new HashMap<>(); + Command command = cmdService.getCommand(ExportToTextCommandHandler.COMMAND_ID); + ParameterizedCommand cmd = ParameterizedCommand.generateCommand(command, parameters); + + IEvaluationContext context = handlerService.getCurrentState(); + // Omit the margin column + List exportColumns = fColumns.subList(EVENT_COLUMNS_START_INDEX, fColumns.size()); + context.addVariable(ExportToTextCommandHandler.TMF_EVENT_TABLE_COLUMNS_ID, exportColumns); + + handlerService.executeCommandInContext(cmd, null, context); + } catch (ExecutionException e) { + displayException(e); + } catch (NotDefinedException e) { + displayException(e); + } catch (NotEnabledException e) { + displayException(e); + } catch (NotHandledException e) { + displayException(e); + } + } + }; + + final IAction showSearchBarAction = new Action(Messages.TmfEventsTable_ShowSearchBarActionText) { + @Override + public void run() { + fHeaderState = HeaderState.SEARCH; + fTable.refresh(); + } + }; + + final IAction showFilterBarAction = new Action(Messages.TmfEventsTable_ShowFilterBarActionText) { + @Override + public void run() { + fHeaderState = HeaderState.FILTER; + fTable.refresh(); + } + }; + + final IAction clearFiltersAction = new Action(Messages.TmfEventsTable_ClearFiltersActionText) { + @Override + public void run() { + clearFilters(); + } + }; + + final IAction collapseAction = new Action(Messages.TmfEventsTable_CollapseFilterMenuName) { + @Override + public void run() { + applyFilter(new TmfCollapseFilter()); + } + }; + + class ToggleBookmarkAction extends Action { + Long fRank; + + public ToggleBookmarkAction(final String text, final Long rank) { + super(text); + fRank = rank; + } + + @Override + public void run() { + toggleBookmark(fRank); + } + } + + final MenuManager tablePopupMenu = new MenuManager(); + tablePopupMenu.setRemoveAllWhenShown(true); + tablePopupMenu.addMenuListener(new IMenuListener() { + @Override + public void menuAboutToShow(final IMenuManager manager) { + if (fTable.getSelectionIndex() == 0) { + // Right-click on header row + if (fHeaderState == HeaderState.FILTER) { + tablePopupMenu.add(showSearchBarAction); + } else { + tablePopupMenu.add(showFilterBarAction); + } + return; + } + final Point point = fTable.toControl(Display.getDefault().getCursorLocation()); + final TableItem item = fTable.getSelection().length > 0 ? fTable.getSelection()[0] : null; + if (item != null) { + final Rectangle imageBounds = item.getImageBounds(0); + imageBounds.width = BOOKMARK_IMAGE.getBounds().width; + if (point.x <= (imageBounds.x + imageBounds.width)) { + // Right-click on left margin + final Long rank = (Long) item.getData(Key.RANK); + if ((rank != null) && (fBookmarksFile != null)) { + if (fBookmarksMap.containsKey(rank)) { + tablePopupMenu.add(new ToggleBookmarkAction( + Messages.TmfEventsTable_RemoveBookmarkActionText, rank)); + } else { + tablePopupMenu.add(new ToggleBookmarkAction( + Messages.TmfEventsTable_AddBookmarkActionText, rank)); + } + } + return; + } + } + + // Right-click on table + if (fTable.isVisible() && fRawViewer.isVisible()) { + tablePopupMenu.add(hideTableAction); + tablePopupMenu.add(hideRawAction); + } else if (!fTable.isVisible()) { + tablePopupMenu.add(showTableAction); + } else if (!fRawViewer.isVisible()) { + tablePopupMenu.add(showRawAction); + } + tablePopupMenu.add(exportToTextAction); + tablePopupMenu.add(new Separator()); + + if (item != null) { + final Object data = item.getData(); + Separator separator = null; + if (data instanceof ITmfSourceLookup) { + ITmfSourceLookup event = (ITmfSourceLookup) data; + if (event.getCallsite() != null) { + tablePopupMenu.add(openCallsiteAction); + separator = new Separator(); + } + } + + if (data instanceof ITmfModelLookup) { + ITmfModelLookup event = (ITmfModelLookup) data; + if (event.getModelUri() != null) { + tablePopupMenu.add(openModelAction); + separator = new Separator(); + } + + if (separator != null) { + tablePopupMenu.add(separator); + } + } + } + + // only show collapse filter if at least one trace can be collapsed + boolean isCollapsible = false; + if (fTrace != null) { + ITmfTrace traces[] = TmfTraceManager.getTraceSet(fTrace); + for (ITmfTrace trace : traces) { + Class eventClass = trace.getEventType(); + isCollapsible = ITmfCollapsibleEvent.class.isAssignableFrom(eventClass); + if (isCollapsible) { + break; + } + } + } + + if (isCollapsible && !(fTable.getData(Key.FILTER_OBJ) instanceof TmfCollapseFilter)) { + tablePopupMenu.add(collapseAction); + tablePopupMenu.add(new Separator()); + } + + tablePopupMenu.add(clearFiltersAction); + final ITmfFilterTreeNode[] savedFilters = FilterManager.getSavedFilters(); + if (savedFilters.length > 0) { + final MenuManager subMenu = new MenuManager(Messages.TmfEventsTable_ApplyPresetFilterMenuName); + for (final ITmfFilterTreeNode node : savedFilters) { + if (node instanceof TmfFilterNode) { + final TmfFilterNode filter = (TmfFilterNode) node; + subMenu.add(new Action(filter.getFilterName()) { + @Override + public void run() { + applyFilter(filter); + } + }); + } + } + tablePopupMenu.add(subMenu); + } + appendToTablePopupMenu(tablePopupMenu, item); + } + }); + + final MenuManager rawViewerPopupMenu = new MenuManager(); + rawViewerPopupMenu.setRemoveAllWhenShown(true); + rawViewerPopupMenu.addMenuListener(new IMenuListener() { + @Override + public void menuAboutToShow(final IMenuManager manager) { + if (fTable.isVisible() && fRawViewer.isVisible()) { + rawViewerPopupMenu.add(hideTableAction); + rawViewerPopupMenu.add(hideRawAction); + } else if (!fTable.isVisible()) { + rawViewerPopupMenu.add(showTableAction); + } else if (!fRawViewer.isVisible()) { + rawViewerPopupMenu.add(showRawAction); + } + appendToRawPopupMenu(tablePopupMenu); + } + }); + + Menu menu = tablePopupMenu.createContextMenu(fTable); + fTable.setMenu(menu); + + menu = rawViewerPopupMenu.createContextMenu(fRawViewer); + fRawViewer.setMenu(menu); + } + + + /** + * Append an item to the event table's pop-up menu. + * + * @param tablePopupMenu + * The menu manager + * @param selectedItem + * The item to append + */ + protected void appendToTablePopupMenu(final MenuManager tablePopupMenu, final TableItem selectedItem) { + // override to append more actions + } + + /** + * Append an item to the raw viewer's pop-up menu. + * + * @param rawViewerPopupMenu + * The menu manager + */ + protected void appendToRawPopupMenu(final MenuManager rawViewerPopupMenu) { + // override to append more actions + } + + @Override + public void dispose() { + stopSearchThread(); + stopFilterThread(); + ColorSettingsManager.removeColorSettingsListener(this); + fComposite.dispose(); + if ((fTrace != null) && fDisposeOnClose) { + fTrace.dispose(); + } + fResourceManager.dispose(); + fRawViewer.dispose(); + super.dispose(); + } + + /** + * Assign a layout data object to this view. + * + * @param layoutData + * The layout data to assign + */ + public void setLayoutData(final Object layoutData) { + fComposite.setLayoutData(layoutData); + } + + /** + * Get the virtual table contained in this event table. + * + * @return The TMF virtual table + */ + public TmfVirtualTable getTable() { + return fTable; + } + + /** + * @param columnData + * columnData + * @deprecated The column headers are now set at the constructor, this + * shouldn't be called anymore. + */ + @Deprecated + protected void setColumnHeaders(final org.eclipse.tracecompass.tmf.ui.widgets.virtualtable.ColumnData [] columnData) { + /* No-op */ + } + + /** + * Set a table item's data. + * + * @param item + * The item to set + * @param event + * Which trace event to link with this entry + * @param rank + * Which rank this event has in the trace/experiment + */ + protected void setItemData(final TableItem item, final ITmfEvent event, final long rank) { + String[] itemStrings = getItemStrings(fColumns, event); + item.setText(itemStrings); + item.setData(event); + item.setData(Key.TIMESTAMP, new TmfTimestamp(event.getTimestamp())); + item.setData(Key.RANK, rank); + + final Collection markerIds = fBookmarksMap.get(rank); + if (!markerIds.isEmpty()) { + Joiner joiner = Joiner.on("\n -").skipNulls(); //$NON-NLS-1$ + List parts = new ArrayList<>(); + if (markerIds.size() > 1) { + parts.add(Messages.TmfEventsTable_MultipleBookmarksToolTip); + } + try { + for (long markerId : markerIds) { + final IMarker marker = fBookmarksFile.findMarker(markerId); + parts.add(marker.getAttribute(IMarker.MESSAGE)); + } + } catch (CoreException e) { + displayException(e); + } + item.setData(Key.BOOKMARK, joiner.join(parts)); + } else { + item.setData(Key.BOOKMARK, null); + } + + boolean searchMatch = false; + boolean searchNoMatch = false; + final ITmfFilter searchFilter = (ITmfFilter) fTable.getData(Key.SEARCH_OBJ); + if (searchFilter != null) { + if (searchFilter.matches(event)) { + searchMatch = true; + } else { + searchNoMatch = true; + } + } + + final ColorSetting colorSetting = ColorSettingsManager.getColorSetting(event); + if (searchNoMatch) { + item.setForeground(colorSetting.getDimmedForegroundColor()); + item.setBackground(colorSetting.getDimmedBackgroundColor()); + } else { + item.setForeground(colorSetting.getForegroundColor()); + item.setBackground(colorSetting.getBackgroundColor()); + } + + if (searchMatch) { + if (!markerIds.isEmpty()) { + item.setImage(SEARCH_MATCH_BOOKMARK_IMAGE); + } else { + item.setImage(SEARCH_MATCH_IMAGE); + } + } else if (!markerIds.isEmpty()) { + item.setImage(BOOKMARK_IMAGE); + } else { + item.setImage((Image) null); + } + + if ((itemStrings[MARGIN_COLUMN_INDEX] != null) && !itemStrings[MARGIN_COLUMN_INDEX].isEmpty()) { + packMarginColumn(); + } + } + + /** + * Set the item data of the header row. + * + * @param item + * The item to use as table header + */ + protected void setHeaderRowItemData(final TableItem item) { + String txtKey = null; + if (fHeaderState == HeaderState.SEARCH) { + item.setImage(SEARCH_IMAGE); + txtKey = Key.SEARCH_TXT; + } else if (fHeaderState == HeaderState.FILTER) { + item.setImage(FILTER_IMAGE); + txtKey = Key.FILTER_TXT; + } + item.setForeground(fGrayColor); + // Ignore collapse and image column + for (int i = EVENT_COLUMNS_START_INDEX; i < fTable.getColumns().length; i++) { + final TableColumn column = fTable.getColumns()[i]; + final String filter = (String) column.getData(txtKey); + if (filter == null) { + if (fHeaderState == HeaderState.SEARCH) { + item.setText(i, SEARCH_HINT); + } else if (fHeaderState == HeaderState.FILTER) { + item.setText(i, FILTER_HINT); + } + item.setForeground(i, fGrayColor); + item.setFont(i, fTable.getFont()); + } else { + item.setText(i, filter); + item.setForeground(i, fGreenColor); + item.setFont(i, fBoldFont); + } + } + } + + /** + * Set the item data of the "filter status" row. + * + * @param item + * The item to use as filter status row + */ + protected void setFilterStatusRowItemData(final TableItem item) { + for (int i = 0; i < fTable.getColumns().length; i++) { + if (i == MARGIN_COLUMN_INDEX) { + if ((fTrace == null) || (fFilterCheckCount == fTrace.getNbEvents())) { + item.setImage(FILTER_IMAGE); + } else { + item.setImage(STOP_IMAGE); + } + } + + if (i == FILTER_SUMMARY_INDEX) { + item.setText(FILTER_SUMMARY_INDEX, fFilterMatchCount + "/" + fFilterCheckCount); //$NON-NLS-1$ + } else { + item.setText(i, EMPTY_STRING); + } + } + item.setData(null); + item.setData(Key.TIMESTAMP, null); + item.setData(Key.RANK, null); + item.setForeground(null); + item.setBackground(null); + } + + /** + * Create an editor for the header. + */ + protected void createHeaderEditor() { + final TableEditor tableEditor = fTable.createTableEditor(); + tableEditor.horizontalAlignment = SWT.LEFT; + tableEditor.verticalAlignment = SWT.CENTER; + tableEditor.grabHorizontal = true; + tableEditor.minimumWidth = 50; + + // Handle the header row selection + fTable.addMouseListener(new MouseAdapter() { + int columnIndex; + TableColumn column; + TableItem item; + + @Override + public void mouseDown(final MouseEvent event) { + if (event.button != 1) { + return; + } + // Identify the selected row + final Point point = new Point(event.x, event.y); + item = fTable.getItem(point); + + // Header row selected + if ((item != null) && (fTable.indexOf(item) == 0)) { + + // Icon selected + if (item.getImageBounds(0).contains(point)) { + if (fHeaderState == HeaderState.SEARCH) { + fHeaderState = HeaderState.FILTER; + } else if (fHeaderState == HeaderState.FILTER) { + fHeaderState = HeaderState.SEARCH; + } + fTable.setSelection(0); + fTable.refresh(); + return; + } + + // Identify the selected column + columnIndex = -1; + for (int i = 0; i < fTable.getColumns().length; i++) { + final Rectangle rect = item.getBounds(i); + if (rect.contains(point)) { + columnIndex = i; + break; + } + } + + if (columnIndex == -1) { + return; + } + + column = fTable.getColumns()[columnIndex]; + + String txtKey = null; + if (fHeaderState == HeaderState.SEARCH) { + txtKey = Key.SEARCH_TXT; + } else if (fHeaderState == HeaderState.FILTER) { + txtKey = Key.FILTER_TXT; + } + + // The control that will be the editor must be a child of the Table + final Text newEditor = (Text) fTable.createTableEditorControl(Text.class); + final String headerString = (String) column.getData(txtKey); + if (headerString != null) { + newEditor.setText(headerString); + } + newEditor.addFocusListener(new FocusAdapter() { + @Override + public void focusLost(final FocusEvent e) { + final boolean changed = updateHeader(newEditor.getText()); + if (changed) { + applyHeader(); + } + } + }); + newEditor.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(final KeyEvent e) { + if (e.character == SWT.CR) { + updateHeader(newEditor.getText()); + applyHeader(); + + // Set focus on the table so that the next carriage return goes to the next result + TmfEventsTable.this.getTable().setFocus(); + } else if (e.character == SWT.ESC) { + tableEditor.getEditor().dispose(); + } + } + }); + newEditor.selectAll(); + newEditor.setFocus(); + tableEditor.setEditor(newEditor, item, columnIndex); + } + } + + /* + * returns true is value was changed + */ + private boolean updateHeader(final String text) { + String objKey = null; + String txtKey = null; + if (fHeaderState == HeaderState.SEARCH) { + objKey = Key.SEARCH_OBJ; + txtKey = Key.SEARCH_TXT; + } else if (fHeaderState == HeaderState.FILTER) { + objKey = Key.FILTER_OBJ; + txtKey = Key.FILTER_TXT; + } + if (text.trim().length() > 0) { + try { + final String regex = TmfFilterMatchesNode.regexFix(text); + Pattern.compile(regex); + if (regex.equals(column.getData(txtKey))) { + tableEditor.getEditor().dispose(); + return false; + } + final TmfFilterMatchesNode filter = new TmfFilterMatchesNode(null); + String fieldId = (String) column.getData(Key.FIELD_ID); + if (fieldId == null) { + fieldId = column.getText(); + } + filter.setField(fieldId); + filter.setRegex(regex); + column.setData(objKey, filter); + column.setData(txtKey, regex); + } catch (final PatternSyntaxException ex) { + tableEditor.getEditor().dispose(); + MessageDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), + ex.getDescription(), ex.getMessage()); + return false; + } + } else { + if (column.getData(txtKey) == null) { + tableEditor.getEditor().dispose(); + return false; + } + column.setData(objKey, null); + column.setData(txtKey, null); + } + return true; + } + + private void applyHeader() { + if (fHeaderState == HeaderState.SEARCH) { + stopSearchThread(); + final TmfFilterAndNode filter = new TmfFilterAndNode(null); + for (final TableColumn col : fTable.getColumns()) { + final Object filterObj = col.getData(Key.SEARCH_OBJ); + if (filterObj instanceof ITmfFilterTreeNode) { + filter.addChild((ITmfFilterTreeNode) filterObj); + } + } + if (filter.getChildrenCount() > 0) { + fTable.setData(Key.SEARCH_OBJ, filter); + fTable.refresh(); + searchNext(); + fireSearchApplied(filter); + } else { + fTable.setData(Key.SEARCH_OBJ, null); + fTable.refresh(); + fireSearchApplied(null); + } + } else if (fHeaderState == HeaderState.FILTER) { + final TmfFilterAndNode filter = new TmfFilterAndNode(null); + for (final TableColumn col : fTable.getColumns()) { + final Object filterObj = col.getData(Key.FILTER_OBJ); + if (filterObj instanceof ITmfFilterTreeNode) { + filter.addChild((ITmfFilterTreeNode) filterObj); + } + } + if (filter.getChildrenCount() > 0) { + applyFilter(filter); + } else { + clearFilters(); + } + } + + tableEditor.getEditor().dispose(); + } + }); + + fTable.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(final KeyEvent e) { + e.doit = false; + if (e.character == SWT.ESC) { + stopFilterThread(); + stopSearchThread(); + fTable.refresh(); + } else if (e.character == SWT.DEL) { + if (fHeaderState == HeaderState.SEARCH) { + stopSearchThread(); + for (final TableColumn column : fTable.getColumns()) { + column.setData(Key.SEARCH_OBJ, null); + column.setData(Key.SEARCH_TXT, null); + } + fTable.setData(Key.SEARCH_OBJ, null); + fTable.refresh(); + fireSearchApplied(null); + } else if (fHeaderState == HeaderState.FILTER) { + clearFilters(); + } + } else if (e.character == SWT.CR) { + if ((e.stateMask & SWT.SHIFT) == 0) { + searchNext(); + } else { + searchPrevious(); + } + } + } + }); + } + + /** + * Send an event indicating a filter has been applied. + * + * @param filter + * The filter that was just applied + */ + protected void fireFilterApplied(final ITmfFilter filter) { + broadcast(new TmfEventFilterAppliedSignal(this, fTrace, filter)); + } + + /** + * Send an event indicating that a search has been applied. + * + * @param filter + * The search filter that was just applied + */ + protected void fireSearchApplied(final ITmfFilter filter) { + broadcast(new TmfEventSearchAppliedSignal(this, fTrace, filter)); + } + + /** + * Start the filtering thread. + */ + protected void startFilterThread() { + synchronized (fFilterSyncObj) { + final ITmfFilterTreeNode filter = (ITmfFilterTreeNode) fTable.getData(Key.FILTER_OBJ); + if (fFilterThread == null || fFilterThread.filter != filter) { + if (fFilterThread != null) { + fFilterThread.cancel(); + fFilterThreadResume = false; + } + fFilterThread = new FilterThread(filter); + fFilterThread.start(); + } else { + fFilterThreadResume = true; + } + } + } + + /** + * Stop the filtering thread. + */ + protected void stopFilterThread() { + synchronized (fFilterSyncObj) { + if (fFilterThread != null) { + fFilterThread.cancel(); + fFilterThread = null; + fFilterThreadResume = false; + } + } + } + + /** + * Apply a filter. + * + * @param filter + * The filter to apply + * @since 1.1 + */ + protected void applyFilter(ITmfFilter filter) { + stopFilterThread(); + stopSearchThread(); + fFilterMatchCount = 0; + fFilterCheckCount = 0; + fCache.applyFilter(filter); + fTable.clearAll(); + fTable.setData(Key.FILTER_OBJ, filter); + fTable.setItemCount(3); // +1 for header row, +2 for top and bottom filter status rows + startFilterThread(); + fireFilterApplied(filter); + } + + /** + * Clear all currently active filters. + */ + protected void clearFilters() { + if (fTable.getData(Key.FILTER_OBJ) == null) { + return; + } + stopFilterThread(); + stopSearchThread(); + fCache.clearFilter(); + fTable.clearAll(); + for (final TableColumn column : fTable.getColumns()) { + column.setData(Key.FILTER_OBJ, null); + column.setData(Key.FILTER_TXT, null); + } + fTable.setData(Key.FILTER_OBJ, null); + if (fTrace != null) { + fTable.setItemCount((int) fTrace.getNbEvents() + 1); // +1 for header row + } else { + fTable.setItemCount(1); // +1 for header row + } + fFilterMatchCount = 0; + fFilterCheckCount = 0; + if (fSelectedRank >= 0) { + fTable.setSelection((int) fSelectedRank + 1); // +1 for header row + } else { + fTable.setSelection(0); + } + fireFilterApplied(null); + updateStatusLine(null); + + // Set original width + fTable.getColumns()[MARGIN_COLUMN_INDEX].setWidth(0); + packMarginColumn(); + } + + /** + * Wrapper Thread object for the filtering thread. + */ + protected class FilterThread extends Thread { + private final ITmfFilterTreeNode filter; + private TmfEventRequest request; + private boolean refreshBusy = false; + private boolean refreshPending = false; + private final Object syncObj = new Object(); + + /** + * Constructor. + * + * @param filter + * The filter this thread will be processing + */ + public FilterThread(final ITmfFilterTreeNode filter) { + super("Filter Thread"); //$NON-NLS-1$ + this.filter = filter; + } + + @Override + public void run() { + if (fTrace == null) { + return; + } + final int nbRequested = (int) (fTrace.getNbEvents() - fFilterCheckCount); + if (nbRequested <= 0) { + return; + } + request = new TmfEventRequest(ITmfEvent.class, TmfTimeRange.ETERNITY, + (int) fFilterCheckCount, nbRequested, ExecutionType.BACKGROUND) { + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + if (request.isCancelled()) { + return; + } + boolean refresh = false; + if (filter.matches(event)) { + final long rank = fFilterCheckCount; + final int index = (int) fFilterMatchCount; + fFilterMatchCount++; + fCache.storeEvent(event, rank, index); + refresh = true; + } else { + if (filter instanceof TmfCollapseFilter) { + fCache.updateCollapsedEvent((int) fFilterMatchCount - 1); + } + } + + if (refresh || (fFilterCheckCount % 100) == 0) { + refreshTable(); + } + fFilterCheckCount++; + } + }; + ((ITmfEventProvider) fTrace).sendRequest(request); + try { + request.waitForCompletion(); + } catch (final InterruptedException e) { + } + refreshTable(); + synchronized (fFilterSyncObj) { + fFilterThread = null; + if (fFilterThreadResume) { + fFilterThreadResume = false; + fFilterThread = new FilterThread(filter); + fFilterThread.start(); + } + } + } + + /** + * Refresh the filter. + */ + public void refreshTable() { + synchronized (syncObj) { + if (refreshBusy) { + refreshPending = true; + return; + } + refreshBusy = true; + } + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (request.isCancelled()) { + return; + } + if (fTable.isDisposed()) { + return; + } + fTable.setItemCount((int) fFilterMatchCount + 3); // +1 for header row, +2 for top and bottom filter status rows + fTable.refresh(); + synchronized (syncObj) { + refreshBusy = false; + if (refreshPending) { + refreshPending = false; + refreshTable(); + } + } + } + }); + } + + /** + * Cancel this filtering thread. + */ + public void cancel() { + if (request != null) { + request.cancel(); + } + } + } + + /** + * Go to the next item of a search. + */ + protected void searchNext() { + synchronized (fSearchSyncObj) { + if (fSearchThread != null) { + return; + } + final ITmfFilterTreeNode searchFilter = (ITmfFilterTreeNode) fTable.getData(Key.SEARCH_OBJ); + if (searchFilter == null) { + return; + } + final int selectionIndex = fTable.getSelectionIndex(); + int startIndex; + if (selectionIndex > 0) { + startIndex = selectionIndex; // -1 for header row, +1 for next event + } else { + // header row is selected, start at top event + startIndex = Math.max(0, fTable.getTopIndex() - 1); // -1 for header row + } + final ITmfFilterTreeNode eventFilter = (ITmfFilterTreeNode) fTable.getData(Key.FILTER_OBJ); + if (eventFilter != null) { + startIndex = Math.max(0, startIndex - 1); // -1 for top filter status row + } + fSearchThread = new SearchThread(searchFilter, eventFilter, startIndex, fSelectedRank, Direction.FORWARD); + fSearchThread.schedule(); + } + } + + /** + * Go to the previous item of a search. + */ + protected void searchPrevious() { + synchronized (fSearchSyncObj) { + if (fSearchThread != null) { + return; + } + final ITmfFilterTreeNode searchFilter = (ITmfFilterTreeNode) fTable.getData(Key.SEARCH_OBJ); + if (searchFilter == null) { + return; + } + final int selectionIndex = fTable.getSelectionIndex(); + int startIndex; + if (selectionIndex > 0) { + startIndex = selectionIndex - 2; // -1 for header row, -1 for previous event + } else { + // header row is selected, start at precedent of top event + startIndex = fTable.getTopIndex() - 2; // -1 for header row, -1 for previous event + } + final ITmfFilterTreeNode eventFilter = (ITmfFilterTreeNode) fTable.getData(Key.FILTER_OBJ); + if (eventFilter != null) { + startIndex = startIndex - 1; // -1 for top filter status row + } + fSearchThread = new SearchThread(searchFilter, eventFilter, startIndex, fSelectedRank, Direction.BACKWARD); + fSearchThread.schedule(); + } + } + + /** + * Stop the search thread. + */ + protected void stopSearchThread() { + fPendingGotoRank = -1; + synchronized (fSearchSyncObj) { + if (fSearchThread != null) { + fSearchThread.cancel(); + fSearchThread = null; + } + } + } + + /** + * Wrapper for the search thread. + */ + protected class SearchThread extends Job { + + private ITmfFilterTreeNode searchFilter; + private ITmfFilterTreeNode eventFilter; + private int startIndex; + private int direction; + private long rank; + private long foundRank = -1; + private TmfEventRequest request; + private ITmfTimestamp foundTimestamp = null; + + /** + * Constructor. + * + * @param searchFilter + * The search filter + * @param eventFilter + * The event filter + * @param startIndex + * The index at which we should start searching + * @param currentRank + * The current rank + * @param direction + * In which direction should we search, forward or backwards + */ + public SearchThread(final ITmfFilterTreeNode searchFilter, + final ITmfFilterTreeNode eventFilter, final int startIndex, + final long currentRank, final int direction) { + super(Messages.TmfEventsTable_SearchingJobName); + this.searchFilter = searchFilter; + this.eventFilter = eventFilter; + this.startIndex = startIndex; + this.rank = currentRank; + this.direction = direction; + } + + @Override + protected IStatus run(final IProgressMonitor monitor) { + if (fTrace == null) { + return Status.OK_STATUS; + } + final Display display = Display.getDefault(); + if (startIndex < 0) { + rank = (int) fTrace.getNbEvents() - 1; + } else if (startIndex >= (fTable.getItemCount() - (eventFilter == null ? 1 : 3))) { // -1 for header row, -2 for top and bottom filter status rows + rank = 0; + } else { + int idx = startIndex; + while (foundRank == -1) { + final CachedEvent event = fCache.peekEvent(idx); + if (event == null) { + break; + } + rank = event.rank; + if (searchFilter.matches(event.event) && ((eventFilter == null) || eventFilter.matches(event.event))) { + foundRank = event.rank; + foundTimestamp = event.event.getTimestamp(); + break; + } + if (direction == Direction.FORWARD) { + idx++; + } else { + idx--; + } + } + if (foundRank == -1) { + if (direction == Direction.FORWARD) { + rank++; + if (rank > (fTrace.getNbEvents() - 1)) { + rank = 0; + } + } else { + rank--; + if (rank < 0) { + rank = (int) fTrace.getNbEvents() - 1; + } + } + } + } + final int startRank = (int) rank; + boolean wrapped = false; + while (!monitor.isCanceled() && (foundRank == -1) && (fTrace != null)) { + int nbRequested = (direction == Direction.FORWARD ? Integer.MAX_VALUE : Math.min((int) rank + 1, fTrace.getCacheSize())); + if (direction == Direction.BACKWARD) { + rank = Math.max(0, rank - fTrace.getCacheSize() + 1); + } + request = new TmfEventRequest(ITmfEvent.class, TmfTimeRange.ETERNITY, + (int) rank, nbRequested, ExecutionType.BACKGROUND) { + long currentRank = rank; + + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + if (searchFilter.matches(event) && ((eventFilter == null) || eventFilter.matches(event))) { + foundRank = currentRank; + foundTimestamp = event.getTimestamp(); + if (direction == Direction.FORWARD) { + done(); + return; + } + } + currentRank++; + } + }; + ((ITmfEventProvider) fTrace).sendRequest(request); + try { + request.waitForCompletion(); + if (request.isCancelled()) { + return Status.OK_STATUS; + } + } catch (final InterruptedException e) { + synchronized (fSearchSyncObj) { + fSearchThread = null; + } + return Status.OK_STATUS; + } + if (foundRank == -1) { + if (direction == Direction.FORWARD) { + if (rank == 0) { + synchronized (fSearchSyncObj) { + fSearchThread = null; + } + return Status.OK_STATUS; + } + nbRequested = (int) rank; + rank = 0; + wrapped = true; + } else { + rank--; + if (rank < 0) { + rank = (int) fTrace.getNbEvents() - 1; + wrapped = true; + } + if ((rank <= startRank) && wrapped) { + synchronized (fSearchSyncObj) { + fSearchThread = null; + } + return Status.OK_STATUS; + } + } + } + } + int index = (int) foundRank; + if (eventFilter != null) { + index = fCache.getFilteredEventIndex(foundRank); + } + final int selection = index + 1 + (eventFilter != null ? +1 : 0); // +1 for header row, +1 for top filter status row + + display.asyncExec(new Runnable() { + @Override + public void run() { + if (monitor.isCanceled()) { + return; + } + if (fTable.isDisposed()) { + return; + } + fTable.setSelection(selection); + fSelectedRank = foundRank; + fRawViewer.selectAndReveal(fSelectedRank); + if (foundTimestamp != null) { + broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, foundTimestamp)); + } + fireSelectionChanged(new SelectionChangedEvent(TmfEventsTable.this, getSelection())); + synchronized (fSearchSyncObj) { + fSearchThread = null; + } + updateStatusLine(null); + } + }); + return Status.OK_STATUS; + } + + @Override + protected void canceling() { + request.cancel(); + synchronized (fSearchSyncObj) { + fSearchThread = null; + } + } + } + + /** + * Create the resources. + */ + protected void createResources() { + fGrayColor = fResourceManager.createColor(ColorUtil.blend(fTable.getBackground().getRGB(), fTable + .getForeground().getRGB())); + fGreenColor = fTable.getDisplay().getSystemColor(SWT.COLOR_DARK_GREEN); + fBoldFont = fResourceManager.createFont(FontDescriptor.createFrom(fTable.getFont()).setStyle(SWT.BOLD)); + } + + /** + * Pack the columns. + */ + protected void packColumns() { + if (fPackDone) { + return; + } + fTable.setRedraw(false); + try { + TableColumn tableColumns[] = fTable.getColumns(); + for (int i = 0; i < tableColumns.length; i++) { + final TableColumn column = tableColumns[i]; + packSingleColumn(i, column); + } + } finally { + // Make sure that redraw is always enabled. + fTable.setRedraw(true); + } + fPackDone = true; + } + + + private void packMarginColumn() { + TableColumn[] columns = fTable.getColumns(); + if (columns.length > 0) { + packSingleColumn(0, columns[0]); + } + } + + private void packSingleColumn(int i, final TableColumn column) { + final int headerWidth = column.getWidth(); + column.pack(); + // Workaround for Linux which doesn't consider the image width of + // search/filter row in TableColumn.pack() after having executed + // TableItem.setImage((Image)null) for other rows than search/filter row. + boolean isCollapseFilter = fTable.getData(Key.FILTER_OBJ) instanceof TmfCollapseFilter; + if (IS_LINUX && (i == 0) && isCollapseFilter) { + column.setWidth(column.getWidth() + SEARCH_IMAGE.getBounds().width); + } + + if (column.getWidth() < headerWidth) { + column.setWidth(headerWidth); + } + } + + /** + * Get the array of item strings (e.g., what to display in each cell of the + * table row) corresponding to the columns and trace event passed in + * parameter. The order of the Strings in the returned array will correspond + * to the iteration order of 'columns'. + * + *

    + * To ensure consistent results, make sure only call this within a scope + * synchronized on 'columns'! If the order of 'columns' changes right after + * this method is called, the returned value won't be ordered correctly + * anymore. + */ + private static String[] getItemStrings(List columns, ITmfEvent event) { + if (event == null) { + return EMPTY_STRING_ARRAY; + } + synchronized (columns) { + List itemStrings = new ArrayList<>(columns.size()); + for (TmfEventTableColumn column : columns) { + ITmfEvent passedEvent = event; + if (!(column instanceof TmfMarginColumn) && (event instanceof CachedEvent)) { + // Make sure that the event object from the trace is passed + // to all columns but the TmfMarginColumn + passedEvent = ((CachedEvent) event).event; + } + if (passedEvent == null) { + itemStrings.add(EMPTY_STRING); + } else { + itemStrings.add(column.getItemString(passedEvent)); + } + + } + return itemStrings.toArray(new String[0]); + } + } + + /** + * Get the contents of the row in the events table corresponding to an + * event. The order of the elements corresponds to the current order of the + * columns. + * + * @param event + * The event printed in this row + * @return The event row entries + * @since 3.0 + */ + public String[] getItemStrings(ITmfEvent event) { + return getItemStrings(fColumns, event); + } + + /** + * Notify this table that is got the UI focus. + */ + public void setFocus() { + fTable.setFocus(); + } + + /** + * Assign a new trace to this event table. + * + * @param trace + * The trace to assign to this event table + * @param disposeOnClose + * true if the trace should be disposed when the table is + * disposed + */ + public void setTrace(final ITmfTrace trace, final boolean disposeOnClose) { + if ((fTrace != null) && fDisposeOnClose) { + fTrace.dispose(); + } + fTrace = trace; + fPackDone = false; + fSelectedRank = 0; + fDisposeOnClose = disposeOnClose; + + // Perform the updates on the UI thread + fTable.getDisplay().syncExec(new Runnable() { + @Override + public void run() { + fTable.removeAll(); + fCache.setTrace(fTrace); // Clear the cache + if (fTrace != null) { + if (!fTable.isDisposed() && (fTrace != null)) { + if (fTable.getData(Key.FILTER_OBJ) == null) { + fTable.setItemCount((int) fTrace.getNbEvents() + 1); // +1 for header row + } else { + stopFilterThread(); + fFilterMatchCount = 0; + fFilterCheckCount = 0; + fTable.setItemCount(3); // +1 for header row, +2 for top and bottom filter status rows + startFilterThread(); + } + } + } + fRawViewer.setTrace(fTrace); + } + }); + } + + /** + * Assign the status line manager + * + * @param statusLineManager + * The status line manager, or null to disable status line messages + * @since 2.1 + */ + public void setStatusLineManager(IStatusLineManager statusLineManager) { + if (fStatusLineManager != null && statusLineManager == null) { + fStatusLineManager.setMessage(EMPTY_STRING); + } + fStatusLineManager = statusLineManager; + } + + private void updateStatusLine(ITmfTimestamp delta) { + if (fStatusLineManager != null) { + if (delta != null) { + fStatusLineManager.setMessage("\u0394: " + delta); //$NON-NLS-1$ + } else { + fStatusLineManager.setMessage(null); + } + } + } + + // ------------------------------------------------------------------------ + // Event cache + // ------------------------------------------------------------------------ + + /** + * Notify that the event cache has been updated + * + * @param completed + * Also notify if the populating of the cache is complete, or + * not. + */ + public void cacheUpdated(final boolean completed) { + synchronized (fCacheUpdateSyncObj) { + if (fCacheUpdateBusy) { + fCacheUpdatePending = true; + fCacheUpdateCompleted = completed; + return; + } + fCacheUpdateBusy = true; + } + // Event cache is now updated. Perform update on the UI thread + if (!fTable.isDisposed()) { + fTable.getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + if (!fTable.isDisposed()) { + fTable.refresh(); + packColumns(); + } + if (completed) { + populateCompleted(); + } + synchronized (fCacheUpdateSyncObj) { + fCacheUpdateBusy = false; + if (fCacheUpdatePending) { + fCacheUpdatePending = false; + cacheUpdated(fCacheUpdateCompleted); + } + } + } + }); + } + } + + /** + * Callback for when populating the table is complete. + */ + protected void populateCompleted() { + // Nothing by default; + } + + // ------------------------------------------------------------------------ + // ISelectionProvider + // ------------------------------------------------------------------------ + + /** + * @since 2.0 + */ + @Override + public void addSelectionChangedListener(ISelectionChangedListener listener) { + selectionChangedListeners.add(listener); + } + + /** + * @since 2.0 + */ + @Override + public ISelection getSelection() { + if (fTable == null || fTable.isDisposed()) { + return StructuredSelection.EMPTY; + } + List list = new ArrayList<>(fTable.getSelection().length); + for (TableItem item : fTable.getSelection()) { + if (item.getData() != null) { + list.add(item.getData()); + } + } + return new StructuredSelection(list); + } + + /** + * @since 2.0 + */ + @Override + public void removeSelectionChangedListener(ISelectionChangedListener listener) { + selectionChangedListeners.remove(listener); + } + + /** + * @since 2.0 + */ + @Override + public void setSelection(ISelection selection) { + // not implemented + } + + /** + * Notifies any selection changed listeners that the viewer's selection has changed. + * Only listeners registered at the time this method is called are notified. + * + * @param event a selection changed event + * + * @see ISelectionChangedListener#selectionChanged + * @since 2.0 + */ + protected void fireSelectionChanged(final SelectionChangedEvent event) { + Object[] listeners = selectionChangedListeners.getListeners(); + for (int i = 0; i < listeners.length; ++i) { + final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i]; + SafeRunnable.run(new SafeRunnable() { + @Override + public void run() { + l.selectionChanged(event); + } + }); + } + } + + // ------------------------------------------------------------------------ + // Bookmark handling + // ------------------------------------------------------------------------ + + /** + * Add a bookmark to this event table. + * + * @param bookmarksFile + * The file to use for the bookmarks + */ + public void addBookmark(final IFile bookmarksFile) { + fBookmarksFile = bookmarksFile; + final TableItem[] selection = fTable.getSelection(); + if (selection.length > 0) { + final TableItem tableItem = selection[0]; + if (tableItem.getData(Key.RANK) != null) { + final StringBuffer defaultMessage = new StringBuffer(); + for (int i = 0; i < fTable.getColumns().length; i++) { + if (i > 0) { + defaultMessage.append(", "); //$NON-NLS-1$ + } + defaultMessage.append(tableItem.getText(i)); + } + final InputDialog dialog = new MultiLineInputDialog( + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), + Messages.TmfEventsTable_AddBookmarkDialogTitle, + Messages.TmfEventsTable_AddBookmarkDialogMessage, + defaultMessage.toString()); + if (dialog.open() == Window.OK) { + final String message = dialog.getValue(); + try { + final IMarker bookmark = bookmarksFile.createMarker(IMarker.BOOKMARK); + if (bookmark.exists()) { + bookmark.setAttribute(IMarker.MESSAGE, message.toString()); + final Long rank = (Long) tableItem.getData(Key.RANK); + final int location = rank.intValue(); + bookmark.setAttribute(IMarker.LOCATION, Integer.valueOf(location)); + fBookmarksMap.put(rank, bookmark.getId()); + fTable.refresh(); + } + } catch (final CoreException e) { + displayException(e); + } + } + } + } + + } + + /** + * Remove a bookmark from this event table. + * + * @param bookmark + * The bookmark to remove + */ + public void removeBookmark(final IMarker bookmark) { + for (final Entry entry : fBookmarksMap.entries()) { + if (entry.getValue().equals(bookmark.getId())) { + fBookmarksMap.remove(entry.getKey(), entry.getValue()); + fTable.refresh(); + return; + } + } + } + + private void toggleBookmark(final Long rank) { + if (fBookmarksFile == null) { + return; + } + if (fBookmarksMap.containsKey(rank)) { + final Collection markerIds = fBookmarksMap.removeAll(rank); + fTable.refresh(); + try { + for (long markerId : markerIds) { + final IMarker bookmark = fBookmarksFile.findMarker(markerId); + if (bookmark != null) { + bookmark.delete(); + } + } + } catch (final CoreException e) { + displayException(e); + } + } else { + addBookmark(fBookmarksFile); + } + } + + /** + * Refresh the bookmarks assigned to this trace, from the contents of a + * bookmark file. + * + * @param bookmarksFile + * The bookmark file to use + */ + public void refreshBookmarks(final IFile bookmarksFile) { + fBookmarksFile = bookmarksFile; + if (bookmarksFile == null) { + fBookmarksMap.clear(); + fTable.refresh(); + return; + } + try { + fBookmarksMap.clear(); + for (final IMarker bookmark : bookmarksFile.findMarkers(IMarker.BOOKMARK, false, IResource.DEPTH_ZERO)) { + final int location = bookmark.getAttribute(IMarker.LOCATION, -1); + if (location != -1) { + final long rank = location; + fBookmarksMap.put(rank, bookmark.getId()); + } + } + fTable.refresh(); + } catch (final CoreException e) { + displayException(e); + } + } + + @Override + public void gotoMarker(final IMarker marker) { + final int rank = marker.getAttribute(IMarker.LOCATION, -1); + if (rank != -1) { + int index = rank; + if (fTable.getData(Key.FILTER_OBJ) != null) { + index = fCache.getFilteredEventIndex(rank) + 1; // +1 for top filter status row + } else if (rank >= fTable.getItemCount()) { + fPendingGotoRank = rank; + } + fSelectedRank = rank; + fTable.setSelection(index + 1); // +1 for header row + updateStatusLine(null); + } + } + + // ------------------------------------------------------------------------ + // Listeners + // ------------------------------------------------------------------------ + + @Override + public void colorSettingsChanged(final ColorSetting[] colorSettings) { + fTable.refresh(); + } + + // ------------------------------------------------------------------------ + // Signal handlers + // ------------------------------------------------------------------------ + + /** + * Handler for the trace updated signal + * + * @param signal + * The incoming signal + */ + @TmfSignalHandler + public void traceUpdated(final TmfTraceUpdatedSignal signal) { + if ((signal.getTrace() != fTrace) || fTable.isDisposed()) { + return; + } + // Perform the refresh on the UI thread + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (!fTable.isDisposed() && (fTrace != null)) { + if (fTable.getData(Key.FILTER_OBJ) == null) { + fTable.setItemCount((int) fTrace.getNbEvents() + 1); // +1 for header row + if ((fPendingGotoRank != -1) && ((fPendingGotoRank + 1) < fTable.getItemCount())) { // +1 for header row + fTable.setSelection((int) fPendingGotoRank + 1); // +1 for header row + fPendingGotoRank = -1; + updateStatusLine(null); + } + } else { + startFilterThread(); + } + } + if (!fRawViewer.isDisposed() && (fTrace != null)) { + fRawViewer.refreshEventCount(); + } + } + }); + } + + /** + * Handler for the time synch signal. + * + * @param signal + * The incoming signal + */ + @TmfSignalHandler + public void currentTimeUpdated(final TmfTimeSynchSignal signal) { + if ((signal.getSource() != this) && (fTrace != null) && (!fTable.isDisposed())) { + + // Create a request for one event that will be queued after other ongoing requests. When this request is completed + // do the work to select the actual event with the timestamp specified in the signal. This procedure prevents + // the method fTrace.getRank() from interfering and delaying ongoing requests. + final TmfEventRequest subRequest = new TmfEventRequest(ITmfEvent.class, + TmfTimeRange.ETERNITY, 0, 1, ExecutionType.FOREGROUND) { + + TmfTimestamp ts = new TmfTimestamp(signal.getBeginTime()); + + @Override + public void handleData(final ITmfEvent event) { + super.handleData(event); + } + + @Override + public void handleCompleted() { + super.handleCompleted(); + if (fTrace == null) { + return; + } + + // Verify if the event is within the trace range and adjust if necessary + ITmfTimestamp timestamp = ts; + if (timestamp.compareTo(fTrace.getStartTime(), true) == -1) { + timestamp = fTrace.getStartTime(); + } + if (timestamp.compareTo(fTrace.getEndTime(), true) == 1) { + timestamp = fTrace.getEndTime(); + } + + // Get the rank of the selected event in the table + final ITmfContext context = fTrace.seekEvent(timestamp); + final long rank = context.getRank(); + context.dispose(); + fSelectedRank = rank; + + fTable.getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + // Return if table is disposed + if (fTable.isDisposed()) { + return; + } + + int index = (int) rank; + if (fTable.isDisposed()) { + return; + } + if (fTable.getData(Key.FILTER_OBJ) != null) { + index = fCache.getFilteredEventIndex(rank) + 1; // +1 for top filter status row + } + fTable.setSelection(index + 1); // +1 for header row + fRawViewer.selectAndReveal(rank); + updateStatusLine(null); + } + }); + } + }; + + ((ITmfEventProvider) fTrace).sendRequest(subRequest); + } + } + + // ------------------------------------------------------------------------ + // Error handling + // ------------------------------------------------------------------------ + + /** + * Display an exception in a message box + * + * @param e the exception + */ + private static void displayException(final Exception e) { + final MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()); + mb.setText(e.getClass().getSimpleName()); + mb.setMessage(e.getMessage()); + mb.open(); + } + + /** + * @since 2.0 + */ + public void refresh() { + fCache.clear(); + fTable.refresh(); + fTable.redraw(); + } + + /** + * Margin column for images and special text (e.g. collapse count) + */ + private static final class TmfMarginColumn extends TmfEventTableColumn { + + private static final @NonNull String HEADER = EMPTY_STRING; + + /** + * Constructor + */ + public TmfMarginColumn() { + super(HEADER); + } + + @Override + public String getItemString(ITmfEvent event) { + if (!(event instanceof CachedEvent) || ((CachedEvent) event).repeatCount == 0) { + return EMPTY_STRING; + } + return "+" + ((CachedEvent) event).repeatCount; //$NON-NLS-1$ + } + + @Override + public String getFilterFieldId() { + return null; + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/ITmfEventTableColumns.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/ITmfEventTableColumns.java new file mode 100644 index 0000000000..fa1ca42bed --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/ITmfEventTableColumns.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.events.columns; + +import java.util.Collection; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * This class allows a trace type to specify which columns it wants to display + * in the Event Table. The "function" to populate the column for any given event + * is defined in each {@link TmfEventTableColumn}. + * + * @author Alexandre Montplaisir + * @since 3.2 + */ +public interface ITmfEventTableColumns { + + /** + * Return the columns specified by this trace type. + * + * The iteration order of the returned collection will correspond to the + * initial order of these columns in the view (from left to right). + *

    + * Note to implementers: + *

    + * Even if many traces of the same type can be opened at the same time, the + * column objects can (and probably should) be singleton instances. This + * means you do not need to create new column objects every time this method + * is called. + * + * @return The Event Table columns advertised by this trace type + */ + @NonNull Collection getEventTableColumns(); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/TmfEventTableColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/TmfEventTableColumn.java new file mode 100644 index 0000000000..1aaa2fd514 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/TmfEventTableColumn.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.events.columns; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.internal.tmf.ui.viewers.events.columns.TmfContentsColumn; +import org.eclipse.tracecompass.internal.tmf.ui.viewers.events.columns.TmfReferenceColumn; +import org.eclipse.tracecompass.internal.tmf.ui.viewers.events.columns.TmfSourceColumn; +import org.eclipse.tracecompass.internal.tmf.ui.viewers.events.columns.TmfTimestampColumn; +import org.eclipse.tracecompass.internal.tmf.ui.viewers.events.columns.TmfTypeColumn; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * A column in the + * {@link org.eclipse.tracecompass.tmf.ui.viewers.events.TmfEventsTable}. In + * addition to ones provided by default, trace types can extend this class to + * create additional columns specific to their events. + * + * Those additional columns can then be passed to the constructor + * {@link org.eclipse.tracecompass.tmf.ui.viewers.events.TmfEventsTable#TmfEventsTable(org.eclipse.swt.widgets.Composite, int, java.util.Collection)} + * + * @author Alexandre Montplaisir + * @since 3.1 + */ +@NonNullByDefault +public abstract class TmfEventTableColumn { + + // ------------------------------------------------------------------------ + // Class attributes + // ------------------------------------------------------------------------ + + /** + * The base set of columns, which can apply to any trace type. + */ + public static interface BaseColumns { + + /** Column showing the event timestamp */ + TmfEventTableColumn TIMESTAMP = new TmfTimestampColumn(); + + /** Column showing the event's source */ + TmfEventTableColumn SOURCE = new TmfSourceColumn(); + + /** Column showing the event type */ + TmfEventTableColumn EVENT_TYPE = new TmfTypeColumn(); + + /** Column showing the event reference */ + TmfEventTableColumn REFERENCE = new TmfReferenceColumn(); + + /** Column showing the aggregated event contents (fields) */ + TmfEventTableColumn CONTENTS = new TmfContentsColumn(); + } + + /** + * Static definition of an empty string. Return this instead of returning + * 'null'! + */ + protected static final String EMPTY_STRING = ""; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Fields + // ------------------------------------------------------------------------ + + private final String fHeaderName; + private final @Nullable String fHeaderTooltip; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructor with no tooltip. + * + * @param headerName + * The name (title) of this column. Should ideally be short. + */ + public TmfEventTableColumn(String headerName) { + fHeaderName = headerName; + fHeaderTooltip = null; + } + + /** + * Constructor with a tooltip. + * + * @param headerName + * The name (title) of this column. Should ideally be short. + * @param headerTooltip + * The tooltip text for the column header. Use 'null' for no + * tooltip. + */ + public TmfEventTableColumn(String headerName, @Nullable String headerTooltip) { + fHeaderName = headerName; + fHeaderTooltip = headerTooltip; + } + + // ------------------------------------------------------------------------ + // Getters + // ------------------------------------------------------------------------ + + /** + * Get this column's header name, a.k.a. title + * + * @return The column's title + */ + public String getHeaderName() { + return fHeaderName; + } + + /** + * Get the tooltip text for the column header + * + * @return The header's tooltip + */ + public @Nullable String getHeaderTooltip() { + return fHeaderTooltip; + } + + // ------------------------------------------------------------------------ + // Abstract methods + // ------------------------------------------------------------------------ + + /** + * Get the string that should be displayed in this column's cell for a given + * trace event. Basically, this defines "what to print in this column for + * this event". + *

    + * Note to implementers: + *

    + * This method takes an {@link ITmfEvent}, because any type of event could + * potentially be present in the table at the time. Do not assume that you + * will only receive events of your trace type. You'd probably want to + * return an empty string for event that don't match your expected class + * type here. + * + * @param event + * The trace event whose element we want to display + * @return The string to display in the column for this event + */ + public abstract String getItemString(ITmfEvent event); + + /** + * Return the FILTER_ID used by the filters to search this column. + * + * @return The filter ID for this column, or 'null' to not provide a filter + * ID (which will mean this column will probably not be + * searchable/filterable.) + */ + public abstract @Nullable String getFilterFieldId(); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/TmfEventTableFieldColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/TmfEventTableFieldColumn.java new file mode 100644 index 0000000000..7b7eeeaa4c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/TmfEventTableFieldColumn.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.events.columns; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; + +/** + * Event table column that will print the value of a given event field, and + * whose column name is also the same as that field. + * + * @author Alexandre Montplaisir + * @since 3.1 + */ +@NonNullByDefault +public class TmfEventTableFieldColumn extends TmfEventTableColumn { + + private final String fFieldName; + + /** + * Basic constructor, which uses the same name for the field name and the + * column header. + * + * @param headerAndFieldName + * The string that is both the title of the column AND the field + * name to look for. + */ + public TmfEventTableFieldColumn(String headerAndFieldName) { + super(headerAndFieldName); + fFieldName = headerAndFieldName; + } + + /** + * Advanced constructor, which can define different field name and header. + * You can also define a tooltip, optionally. + * + * @param headerName + * The header (title) of the column + * @param fieldName + * The field name to look for in the event content to populate + * this column. + * @param headerTooltip + * The tooltip text for the column header. Use 'null' for no + * tooltip. + */ + public TmfEventTableFieldColumn(String headerName, String fieldName, + @Nullable String headerTooltip) { + super(headerName, headerTooltip); + fFieldName = fieldName; + } + + @Override + public final String getItemString(ITmfEvent event) { + ITmfEventField field = event.getContent().getField(fFieldName); + if (field == null) { + return EMPTY_STRING; + } + String val = field.getFormattedValue(); + return (val == null ? EMPTY_STRING : val); + } + + @Override + public @NonNull String getFilterFieldId() { + return fFieldName; + } + + // ------------------------------------------------------------------------ + // hashCode/equals (so that equivalent columns can be merged together) + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + fFieldName.hashCode(); + result = prime * result + getHeaderName().hashCode(); + return result; + } + + @Override + public boolean equals(@Nullable Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof TmfEventTableFieldColumn)) { + return false; + } + TmfEventTableFieldColumn other = (TmfEventTableFieldColumn) obj; + if (!fFieldName.equals(other.fFieldName)) { + return false; + } + if (!getHeaderName().equals(other.getHeaderName())) { + return false; + } + return true; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/text/TmfTextEventTable.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/text/TmfTextEventTable.java new file mode 100644 index 0000000000..6567141119 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/text/TmfTextEventTable.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.events.text; + +import java.util.List; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.trace.text.TextTraceEvent; +import org.eclipse.tracecompass.tmf.core.trace.text.TextTraceEventContent; +import org.eclipse.tracecompass.tmf.ui.viewers.events.TmfEventsTable; +import org.eclipse.tracecompass.tmf.ui.widgets.virtualtable.ColumnData; + +/** + * Event table for text traces, which has one column for every event field. + * + * @author Alexandre Montplaisir + * @since 3.0 + * @deprecated Users of this class should instead use + * {@link TmfEventsTable#TmfEventsTable(Composite, int, java.util.Collection)} + * , by passing + * {@link org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn} + * or + * {@link org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableFieldColumn} + * . + */ +@Deprecated +public class TmfTextEventTable extends TmfEventsTable { + + /** + * Constructor + * + * @param parent + * The parent composite UI object + * @param cacheSize + * The size of the event table cache + * @param columnData + * The column data to use for this table + */ + public TmfTextEventTable(Composite parent, int cacheSize, ColumnData[] columnData) { + super(parent, cacheSize, columnData); + } + + /** + * @param event + * The event to get the column strings for. It should be an + * instance of {@link TextTraceEvent}. + */ + @Override + public String[] getItemStrings(ITmfEvent event) { + if (event instanceof TextTraceEvent) { + List fields = ((TextTraceEvent) event).getContent().getFields(); + String[] strings = new String[fields.size()]; + for (int i = 0; i < strings.length; i++) { + Object value = fields.get(i).getValue(); + strings[i] = (value == null ? EMPTY_STRING : value.toString()); + } + return strings; + } + return EMPTY_STRING_ARRAY; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/Messages.java new file mode 100644 index 0000000000..e53e5a9376 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/Messages.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial API and Implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.statistics; + +import org.eclipse.osgi.util.NLS; + +/** + * Messages file for statistics view strings. + * + * @author Mathieu Denis + * @since 2.0 + */ +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.ui.viewers.statistics.messages"; //$NON-NLS-1$ + + /** + * String for unknown trace name. + */ + public static String TmfStatisticsView_UnknownTraceName; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/TmfStatisticsViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/TmfStatisticsViewer.java new file mode 100644 index 0000000000..40458973e4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/TmfStatisticsViewer.java @@ -0,0 +1,799 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial API and implementation + * Alexandre Montplaisir - Port to ITmfStatistics provider + * Patrick Tasse - Support selection range + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.statistics; + +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.tracecompass.tmf.core.component.TmfComponent; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceRangeUpdatedSignal; +import org.eclipse.tracecompass.tmf.core.statistics.ITmfStatistics; +import org.eclipse.tracecompass.tmf.core.statistics.TmfStatisticsEventTypesModule; +import org.eclipse.tracecompass.tmf.core.statistics.TmfStatisticsModule; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ui.TmfUiRefreshHandler; +import org.eclipse.tracecompass.tmf.ui.viewers.TmfViewer; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfBaseColumnData; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfBaseColumnDataProvider; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsFormatter; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTree; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTreeManager; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfTreeContentProvider; + +/** + * A basic viewer to display statistics in the statistics view. + * + * It is linked to a single ITmfTrace until its disposal. + * + * @author Mathieu Denis + * @since 2.0 + */ +public class TmfStatisticsViewer extends TmfViewer { + + /** Timestamp scale used for all statistics (nanosecond) */ + private static final byte TIME_SCALE = ITmfTimestamp.NANOSECOND_SCALE; + + /** The delay (in ms) between each update in live-reading mode */ + private static final long LIVE_UPDATE_DELAY = 1000; + + /** The actual tree viewer to display */ + private TreeViewer fTreeViewer; + + /** The statistics tree linked to this viewer */ + private TmfStatisticsTree fStatisticsData; + + /** Update range synchronization object */ + private final Object fStatisticsRangeUpdateSyncObj = new Object(); + + /** The trace that is displayed by this viewer */ + private ITmfTrace fTrace; + + /** Indicates to process all events */ + private boolean fProcessAll; + + /** View instance counter (for multiple statistics views) */ + private static int fCountInstance = 0; + + /** Number of this instance. Used as an instance ID. */ + private int fInstanceNb; + + /** Object to store the cursor while waiting for the trace to load */ + private Cursor fWaitCursor = null; + + /** + * Counts the number of times waitCursor() has been called. It avoids + * removing the waiting cursor, since there may be multiple requests running + * at the same time. + */ + private int fWaitCursorCount = 0; + + /** Tells to send a time range request when the trace gets updated. */ + private boolean fSendRangeRequest = true; + + /** Reference to the trace manager */ + private final TmfTraceManager fTraceManager; + + /** + * Create a basic statistics viewer. To be used in conjunction with + * {@link TmfStatisticsViewer#init(Composite, String, ITmfTrace)} + * + * @param parent + * The parent composite that will hold the viewer + * @param viewerName + * The name that will be assigned to this viewer + * @param trace + * The trace that is displayed by this viewer + * @see TmfComponent + */ + public TmfStatisticsViewer(Composite parent, String viewerName, ITmfTrace trace) { + init(parent, viewerName, trace); + fTraceManager = TmfTraceManager.getInstance(); + } + + /** + * Initialize the statistics viewer. + * + * @param parent + * The parent component of the viewer. + * @param viewerName + * The name to give to the viewer. + * @param trace + * The trace that will be displayed by the viewer. + */ + public void init(Composite parent, String viewerName, ITmfTrace trace) { + super.init(parent, viewerName); + // Increment a counter to make sure the tree ID is unique. + fCountInstance++; + fInstanceNb = fCountInstance; + fTrace = trace; + + // The viewer will process all events if he is assigned to an experiment + fProcessAll = (trace instanceof TmfExperiment); + + initContent(parent); + initInput(); + } + + @Override + public void dispose() { + super.dispose(); + if (fWaitCursor != null) { + fWaitCursor.dispose(); + } + + // Clean the model for this viewer + TmfStatisticsTreeManager.removeStatTreeRoot(getTreeID()); + } + + // ------------------------------------------------------------------------ + // Signal handlers + // ------------------------------------------------------------------------ + + /** + * Handles the signal about new trace range. + * + * @param signal + * The trace range updated signal + */ + @TmfSignalHandler + public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal) { + ITmfTrace trace = signal.getTrace(); + // validate + if (!isListeningTo(trace)) { + return; + } + + synchronized (fStatisticsRangeUpdateSyncObj) { + // Sends the time range request only once from this method. + if (fSendRangeRequest) { + fSendRangeRequest = false; + ITmfTimestamp begin = fTraceManager.getSelectionBeginTime(); + ITmfTimestamp end = fTraceManager.getSelectionEndTime(); + TmfTimeRange timeRange = new TmfTimeRange(begin, end); + requestTimeRangeData(trace, timeRange); + } + } + requestData(trace, signal.getRange()); + } + + /** + * Handles the time synch updated signal. It updates the time range + * statistics. + * + * @param signal + * Contains the information about the new selected time range. + * @since 2.1 + */ + @TmfSignalHandler + public void timeSynchUpdated(TmfTimeSynchSignal signal) { + if (fTrace == null) { + return; + } + ITmfTimestamp begin = signal.getBeginTime(); + ITmfTimestamp end = signal.getEndTime(); + TmfTimeRange timeRange = new TmfTimeRange(begin, end); + requestTimeRangeData(fTrace, timeRange); + } + + // ------------------------------------------------------------------------ + // Class methods + // ------------------------------------------------------------------------ + + /* + * Returns the primary control associated with this viewer. + * + * @return the SWT control which displays this viewer's content + */ + @Override + public Control getControl() { + return fTreeViewer.getControl(); + } + + /** + * Get the input of the viewer. + * + * @return an object representing the input of the statistics viewer. + */ + public Object getInput() { + return fTreeViewer.getInput(); + } + + /** + * This method can be overridden to implement another way of representing + * the statistics data and to retrieve the information for display. + * + * @return a TmfStatisticsData object. + */ + public TmfStatisticsTree getStatisticData() { + if (fStatisticsData == null) { + fStatisticsData = new TmfStatisticsTree(); + } + return fStatisticsData; + } + + /** + * Returns a unique ID based on name to be associated with the statistics + * tree for this viewer. For a same name, it will always return the same ID. + * + * @return a unique statistics tree ID. + */ + public String getTreeID() { + return getName() + fInstanceNb; + } + + @Override + public void refresh() { + final Control viewerControl = getControl(); + // Ignore update if disposed + if (viewerControl.isDisposed()) { + return; + } + + TmfUiRefreshHandler.getInstance().queueUpdate(this, new Runnable() { + @Override + public void run() { + if (!viewerControl.isDisposed()) { + fTreeViewer.refresh(); + } + } + }); + } + + /** + * Will force a request on the partial event count if one is needed. + */ + public void sendPartialRequestOnNextUpdate() { + synchronized (fStatisticsRangeUpdateSyncObj) { + fSendRangeRequest = true; + } + } + + /** + * Focus on the statistics tree of the viewer + */ + public void setFocus() { + fTreeViewer.getTree().setFocus(); + } + + /** + * Cancels the request if it is not already completed + * + * @param request + * The request to be canceled + * @since 3.0 + */ + protected void cancelOngoingRequest(ITmfEventRequest request) { + if (request != null && !request.isCompleted()) { + request.cancel(); + } + } + + /** + * This method can be overridden to change the representation of the data in + * the columns. + * + * @return An object of type {@link TmfBaseColumnDataProvider}. + * @since 3.0 + */ + protected TmfBaseColumnDataProvider getColumnDataProvider() { + return new TmfBaseColumnDataProvider(); + } + + /** + * Initialize the content that will be drawn in this viewer + * + * @param parent + * The parent of the control to create + */ + protected void initContent(Composite parent) { + final List columnDataList = getColumnDataProvider().getColumnData(); + + fTreeViewer = new TreeViewer(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); + fTreeViewer.setContentProvider(new TmfTreeContentProvider()); + fTreeViewer.getTree().setHeaderVisible(true); + fTreeViewer.setUseHashlookup(true); + + // Creates the columns defined by the column data provider + for (final TmfBaseColumnData columnData : columnDataList) { + final TreeViewerColumn treeColumn = new TreeViewerColumn(fTreeViewer, columnData.getAlignment()); + treeColumn.getColumn().setText(columnData.getHeader()); + treeColumn.getColumn().setWidth(columnData.getWidth()); + treeColumn.getColumn().setToolTipText(columnData.getTooltip()); + + // If is dummy column + if (columnData == columnDataList.get(TmfBaseColumnDataProvider.StatsColumn.DUMMY.getIndex())) { + treeColumn.getColumn().setResizable(false); + } + + // A comparator is defined. + if (columnData.getComparator() != null) { + // Adds a listener on the columns header for sorting purpose. + treeColumn.getColumn().addSelectionListener(new SelectionAdapter() { + + private ViewerComparator reverseComparator; + + @Override + public void widgetSelected(SelectionEvent e) { + // Initializes the reverse comparator once. + if (reverseComparator == null) { + reverseComparator = new ViewerComparator() { + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + return -1 * columnData.getComparator().compare(viewer, e1, e2); + } + }; + } + + if (fTreeViewer.getTree().getSortDirection() == SWT.UP + || fTreeViewer.getTree().getSortColumn() != treeColumn.getColumn()) { + /* + * Puts the descendant order if the old order was up + * or if the selected column has changed. + */ + fTreeViewer.setComparator(columnData.getComparator()); + fTreeViewer.getTree().setSortDirection(SWT.DOWN); + } else { + /* + * Puts the ascendant ordering if the selected + * column hasn't changed. + */ + fTreeViewer.setComparator(reverseComparator); + fTreeViewer.getTree().setSortDirection(SWT.UP); + } + fTreeViewer.getTree().setSortColumn(treeColumn.getColumn()); + } + }); + } + treeColumn.setLabelProvider(columnData.getLabelProvider()); + } + + // Handler that will draw the percentages and the bar charts. + fTreeViewer.getTree().addListener(SWT.EraseItem, new Listener() { + @Override + public void handleEvent(Event event) { + if (columnDataList.get(event.index).getPercentageProvider() != null) { + + TmfStatisticsTreeNode node = (TmfStatisticsTreeNode) event.item.getData(); + + // If node is hidden, exit immediately. + if (TmfBaseColumnDataProvider.HIDDEN_FOLDER_LEVELS.contains(node.getName())) { + return; + } + + // Otherwise, get percentage and draw bar and text if applicable. + double percentage = columnDataList.get(event.index).getPercentageProvider().getPercentage(node); + + // The item is selected. + if ((event.detail & SWT.SELECTED) > 0) { + // Draws our own background to avoid overwriting the bar. + event.gc.fillRectangle(event.x, event.y, event.width, event.height); + event.detail &= ~SWT.SELECTED; + } + + // Drawing the percentage text + // if events are present in top node + // and the current node is not the top node + // and if is total or partial events column. + // If not, exit the method. + if (!((event.index == TmfBaseColumnDataProvider.StatsColumn.TOTAL.getIndex() || event.index == TmfBaseColumnDataProvider.StatsColumn.PARTIAL.getIndex()) + && node != node.getTop())) { + return; + } + + long eventValue = event.index == TmfBaseColumnDataProvider.StatsColumn.TOTAL.getIndex() ? + node.getTop().getValues().getTotal() : node.getTop().getValues().getPartial(); + + if (eventValue != 0) { + + int oldAlpha = event.gc.getAlpha(); + Color oldForeground = event.gc.getForeground(); + Color oldBackground = event.gc.getBackground(); + + // Bar to draw + if (percentage != 0) { + /* + * Draws a transparent gradient rectangle from the + * color of foreground and background. + */ + int barWidth = (int) ((fTreeViewer.getTree().getColumn(event.index).getWidth() - 8) * percentage); + event.gc.setAlpha(64); + event.gc.setForeground(event.item.getDisplay().getSystemColor(SWT.COLOR_BLUE)); + event.gc.setBackground(event.item.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + event.gc.fillGradientRectangle(event.x, event.y, barWidth, event.height, true); + event.gc.drawRectangle(event.x, event.y, barWidth, event.height); + + // Restore old values + event.gc.setBackground(oldBackground); + event.gc.setAlpha(oldAlpha); + event.detail &= ~SWT.BACKGROUND; + + } + + String percentageText = TmfStatisticsFormatter.toPercentageText(percentage); + String absoluteNumberText = TmfStatisticsFormatter.toColumnData(node, TmfBaseColumnDataProvider.StatsColumn.getColumn(event.index)); + + if (event.width > event.gc.stringExtent(percentageText).x + event.gc.stringExtent(absoluteNumberText).x) { + int textHeight = event.gc.stringExtent(percentageText).y; + event.gc.setForeground(event.item.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY)); + event.gc.drawText(percentageText, event.x, event.y + (event.height - textHeight) / 2, true); + } + + // Restores old values + event.gc.setForeground(oldForeground); + + } + } + } + + }); + + // Initializes the comparator parameters + fTreeViewer.setComparator(columnDataList.get(0).getComparator()); + fTreeViewer.getTree().setSortColumn(fTreeViewer.getTree().getColumn(0)); + fTreeViewer.getTree().setSortDirection(SWT.DOWN); + } + + /** + * Initializes the input for the tree viewer. + */ + protected void initInput() { + String treeID = getTreeID(); + TmfStatisticsTreeNode statisticsTreeNode; + if (TmfStatisticsTreeManager.containsTreeRoot(treeID)) { + // The statistics root is already present + statisticsTreeNode = TmfStatisticsTreeManager.getStatTreeRoot(treeID); + + // Checks if the trace is already in the statistics tree. + int numNodeTraces = statisticsTreeNode.getNbChildren(); + + ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace); + int numTraces = traces.length; + + if (numTraces == numNodeTraces) { + boolean same = true; + /* + * Checks if the experiment contains the same traces as when + * previously selected. + */ + for (int i = 0; i < numTraces; i++) { + String traceName = traces[i].getName(); + if (!statisticsTreeNode.containsChild(traceName)) { + same = false; + break; + } + } + + if (same) { + // No need to reload data, all traces are already loaded + fTreeViewer.setInput(statisticsTreeNode); + return; + } + // Clears the old content to start over + statisticsTreeNode.reset(); + } + } else { + // Creates a new tree + statisticsTreeNode = TmfStatisticsTreeManager.addStatsTreeRoot(treeID, getStatisticData()); + } + + // Sets the input to a clean data model + fTreeViewer.setInput(statisticsTreeNode); + } + + /** + * Tells if the viewer is listening to a trace. + * + * @param trace + * The trace that the viewer may be listening + * @return true if the viewer is listening to the trace, false otherwise + */ + protected boolean isListeningTo(ITmfTrace trace) { + if (fProcessAll || trace == fTrace) { + return true; + } + return false; + } + + /** + * Called when an trace request has been completed successfully. + * + * @param global + * Tells if the request is a global or time range (partial) + * request. + */ + protected void modelComplete(boolean global) { + refresh(); + waitCursor(false); + } + + /** + * Called when an trace request has failed or has been cancelled. + * + * @param isGlobalRequest + * Tells if the request is a global or time range (partial) + * request. + */ + protected void modelIncomplete(boolean isGlobalRequest) { + if (isGlobalRequest) { // Clean the global statistics + /* + * No need to reset the global number of events, since the index of + * the last requested event is known. + */ + } else { // Clean the partial statistics + resetTimeRangeValue(); + } + refresh(); + waitCursor(false); + } + + /** + * Sends the request to the trace for the whole trace + * + * @param trace + * The trace used to send the request + * @param timeRange + * The range to request to the trace + */ + protected void requestData(final ITmfTrace trace, final TmfTimeRange timeRange) { + buildStatisticsTree(trace, timeRange, true); + } + + /** + * Sends the time range request from the trace + * + * @param trace + * The trace used to send the request + * @param timeRange + * The range to request to the trace + */ + protected void requestTimeRangeData(final ITmfTrace trace, final TmfTimeRange timeRange) { + buildStatisticsTree(trace, timeRange, false); + } + + /** + * Requests all the data of the trace to the state system which contains + * information about the statistics. + * + * Since the viewer may be listening to multiple traces, it may receive an + * experiment rather than a single trace. The filtering is done with the + * method {@link #isListeningTo(String trace)}. + * + * @param trace + * The trace for which a request must be done + * @param timeRange + * The time range that will be requested to the state system + * @param isGlobal + * Tells if the request is for the global event count or the + * partial one. + */ + private void buildStatisticsTree(final ITmfTrace trace, final TmfTimeRange timeRange, final boolean isGlobal) { + final TmfStatisticsTreeNode statTree = TmfStatisticsTreeManager.getStatTreeRoot(getTreeID()); + final TmfStatisticsTree statsData = TmfStatisticsTreeManager.getStatTree(getTreeID()); + if (statsData == null) { + return; + } + + synchronized (statsData) { + if (isGlobal) { + statTree.resetGlobalValue(); + } else { + statTree.resetTimeRangeValue(); + } + + for (final ITmfTrace aTrace : TmfTraceManager.getTraceSet(trace)) { + if (!isListeningTo(aTrace)) { + continue; + } + + /* Retrieve the statistics object */ + final TmfStatisticsModule statsMod = aTrace.getAnalysisModuleOfClass(TmfStatisticsModule.class, TmfStatisticsModule.ID); + if (statsMod == null) { + /* No statistics module available for this trace */ + continue; + } + + /* Run the potentially long queries in a separate thread */ + Thread statsThread = new Thread("Statistics update") { //$NON-NLS-1$ + @Override + public void run() { + /* Wait until the analysis is ready to be queried */ + statsMod.waitForInitialization(); + ITmfStatistics stats = statsMod.getStatistics(); + if (stats == null) { + /* It should have worked, but didn't */ + throw new IllegalStateException(); + } + + /* + * The generic statistics are stored in nanoseconds, so + * we must make sure the time range is scaled correctly. + */ + long start = timeRange.getStartTime().normalize(0, TIME_SCALE).getValue(); + long end = timeRange.getEndTime().normalize(0, TIME_SCALE).getValue(); + + /* + * Wait on the state system object we are going to query. + * + * TODO Eventually this could be exposed through the + * TmfStateSystemAnalysisModule directly. + */ + ITmfStateSystem ss = statsMod.getStateSystem(TmfStatisticsEventTypesModule.ID); + if (ss == null) { + /* + * It should be instantiated after the + * statsMod.waitForInitialization() above. + */ + throw new IllegalStateException(); + } + + /* + * Periodically update the statistics while they are + * being built (or, if the back-end is already + * completely built, it will skip over the while() immediately. + */ + while (!ss.waitUntilBuilt(LIVE_UPDATE_DELAY)) { + Map map = stats.getEventTypesInRange(start, end); + updateStats(aTrace, isGlobal, map); + } + /* Query one last time for the final values */ + Map map = stats.getEventTypesInRange(start, end); + updateStats(aTrace, isGlobal, map); + } + }; + statsThread.start(); + } + } + } + + /* + * Update statistics for a given trace + */ + private void updateStats(ITmfTrace trace, boolean isGlobal, Map eventsPerType) { + + final TmfStatisticsTree statsData = TmfStatisticsTreeManager.getStatTree(getTreeID()); + if (statsData == null) { + /* The stat tree has been disposed, abort mission. */ + return; + } + + Map map = eventsPerType; + String name = trace.getName(); + + + /* + * "Global", "partial", "total", etc., it's all very confusing... + * + * The base view shows the total count for the trace and for + * each even types, organized in columns like this: + * + * | Global | Time range | + * trace name | A | B | + * Event Type | | | + * | C | D | + * | ... | ... | + * ... | | | + * + * Here, we called the cells like this: + * A : GlobalTotal + * B : TimeRangeTotal + * C : GlobalTypeCount(s) + * D : TimeRangeTypeCount(s) + */ + + /* Fill in an the event counts (either cells C or D) */ + for (Map.Entry entry : map.entrySet()) { + statsData.setTypeCount(name, entry.getKey(), isGlobal, entry.getValue()); + } + + /* + * Calculate the totals (cell A or B, depending if isGlobal). We will + * use the results of the previous request instead of sending another + * one. + */ + long globalTotal = 0; + for (long val : map.values()) { + globalTotal += val; + } + statsData.setTotal(name, isGlobal, globalTotal); + + modelComplete(isGlobal); + } + + /** + * Resets the number of events within the time range + */ + protected void resetTimeRangeValue() { + TmfStatisticsTreeNode treeModelRoot = TmfStatisticsTreeManager.getStatTreeRoot(getTreeID()); + if (treeModelRoot != null && treeModelRoot.hasChildren()) { + treeModelRoot.resetTimeRangeValue(); + } + } + + /** + * When the trace is loading the cursor will be different so the user knows + * that the processing is not finished yet. + * + * Calls to this method are stacked. + * + * @param waitRequested + * Indicates if we need to show the waiting cursor, or the + * default one. + */ + protected void waitCursor(final boolean waitRequested) { + if ((fTreeViewer == null) || (fTreeViewer.getTree().isDisposed())) { + return; + } + + boolean needsUpdate = false; + Display display = fTreeViewer.getControl().getDisplay(); + if (waitRequested) { + fWaitCursorCount++; + if (fWaitCursor == null) { // The cursor hasn't been initialized yet + fWaitCursor = new Cursor(display, SWT.CURSOR_WAIT); + } + if (fWaitCursorCount == 1) { // The cursor is not in waiting mode + needsUpdate = true; + } + } else { + if (fWaitCursorCount > 0) { // The cursor is in waiting mode + fWaitCursorCount--; + if (fWaitCursorCount == 0) { // No more reason to wait + // Put back the default cursor + needsUpdate = true; + } + } + } + + if (needsUpdate) { + // Performs the updates on the UI thread + display.asyncExec(new Runnable() { + @Override + public void run() { + if ((fTreeViewer != null) + && (!fTreeViewer.getTree().isDisposed())) { + Cursor cursor = null; // indicates default + if (waitRequested) { + cursor = fWaitCursor; + } + fTreeViewer.getControl().setCursor(cursor); + } + } + }); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/messages.properties new file mode 100644 index 0000000000..c522f0aa1a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/messages.properties @@ -0,0 +1,13 @@ +############################################################################### +# Copyright (c) 2013 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### + +TmfStatisticsView_UnknownTraceName=Unknown_Trace \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/Messages.java new file mode 100755 index 0000000000..24b9cd9548 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/Messages.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial API and Implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.statistics.model; + +import org.eclipse.osgi.util.NLS; + +/** + * Message strings for the statistics framework. + * + * @version 2.0 + * @author Mathieu Denis + * @since 2.0 + */ +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.messages"; //$NON-NLS-1$ + + /** + * CPU statistic name. + */ + public static String TmfStatisticsData_CPUs; + + /** + * Event type statistic name. + */ + public static String TmfStatisticsData_EventTypes; + + /** + * Level column name + */ + public static String TmfStatisticsView_LevelColumn; + + /** + * Level column tool tip. + */ + public static String TmfStatisticsView_LevelColumnTip; + + /** + * Number of events column name. + */ + public static String TmfStatisticsView_NbEventsColumn; + + /** + * Number of events column tool tip. + */ + public static String TmfStatisticsView_NbEventsTip; + + /** + * Partial number of events column. + * @since 2.0 + */ + public static String TmfStatisticsView_NbEventsTimeRangeColumn; + + /** + * Partial number of events column tool tip. + * @since 2.0 + */ + public static String TmfStatisticsView_NbEventsTimeRangeTip; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfBaseColumnData.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfBaseColumnData.java new file mode 100755 index 0000000000..37286a785d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfBaseColumnData.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial Implementation + * Bernd Hufmann - Added Annotations + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.statistics.model; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ViewerComparator; + +/** + * Contains all the information necessary to build a column of the table. + * + * @author Mathieu Denis + * @since 2.0 + */ +public class TmfBaseColumnData { + + /** + * Name of the column. + */ + private final String fHeader; + + /** + * Width of the column. + */ + private final int fWidth; + + /** + * Alignment of the column. + */ + private final int fAlignment; + + /** + * Tooltip of the column. + */ + private final String fTooltip; + + /** + * Adapts a StatisticsTreeNode into the content of it's corresponding cell + * for that column. + */ + private final ColumnLabelProvider fLabelProvider; + + /** + * Used to sort elements of this column. Can be null. + */ + private final @Nullable ViewerComparator fComparator; + + /** + * Used to draw bar charts in this column. Can be null. + */ + private final @Nullable ITmfColumnPercentageProvider fPercentageProvider; + + /** + * Used to draw bar charts in columns. + */ + public interface ITmfColumnPercentageProvider { + + /** + * Percentage provider + * + * @param node + * The statistics tree node + * @return The value as a percentage + */ + public double getPercentage(TmfStatisticsTreeNode node); + } + + /** + * Constructor with parameters + * + * @param h + * header of the column. The name will be shown at the top of the + * column. + * @param w + * width of the column. + * @param a + * alignment of the text + * @param t + * text to shown as a tooltip when the cursor comes over the + * header + * @param l + * provide all the column element + * @param c + * used to compare element between them to be able to classify + * the content of the columns + * @param p + * provide the percentage of a specific element + */ + public TmfBaseColumnData(String h, int w, int a, String t, + ColumnLabelProvider l, ViewerComparator c, + ITmfColumnPercentageProvider p) { + fHeader = h; + fWidth = w; + fAlignment = a; + fTooltip = t; + fLabelProvider = l; + fComparator = c; + fPercentageProvider = p; + } + + /** + * Return the column name. + * + * @return the name of the column. + */ + public String getHeader() { + return fHeader; + } + + /** + * Return the width of the column at the creation. + * + * @return the width of the column. + */ + public int getWidth() { + return fWidth; + } + + /** + * Return the alignment of the column. + * + * @see org.eclipse.swt.SWT + * @return an integer representing the alignment inside the column. + */ + public int getAlignment() { + return fAlignment; + } + + /** + * Provide the text to show in the tooltip when the cursor comes over the + * column header. + * + * @return text to show in the tooltip + */ + public String getTooltip() { + return fTooltip; + } + + /** + * Return the labelProvider which provides the information to put in column + * cells. + * + * @return a ColumnLabelProvider. + */ + public ColumnLabelProvider getLabelProvider() { + return fLabelProvider; + } + + /** + * Return a ViewerComparator used to sort viewer's contents. + * + * @return the comparator. + */ + public ViewerComparator getComparator() { + return fComparator; + } + + /** + * Return the provider of the percentage. Used to draw bar charts in + * columns. + * + * @return the percentageProvider. + */ + public ITmfColumnPercentageProvider getPercentageProvider() { + return fPercentageProvider; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfBaseColumnDataProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfBaseColumnDataProvider.java new file mode 100755 index 0000000000..999d5b5b2b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfBaseColumnDataProvider.java @@ -0,0 +1,289 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Implementation and Initial API + * Vincent Perot - Add percentages to the label provider + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.statistics.model; + +import java.util.List; +import java.util.Set; + +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfBaseColumnData.ITmfColumnPercentageProvider; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; + +/** + * Create a basic list of columns with providers. + * + * @author Mathieu Denis + * @since 3.0 + */ +public class TmfBaseColumnDataProvider { + + // ------------------------------------------------------------------------ + // Localized strings + // ------------------------------------------------------------------------ + + /** Level column names */ + private static final String LEVEL_COLUMN = Messages.TmfStatisticsView_LevelColumn; + + /** Number of events column names */ + private static final String EVENTS_COUNT_COLUMN = Messages.TmfStatisticsView_NbEventsColumn; + + /** Number of events in time range column names */ + private static final String PARTIAL_EVENTS_COUNT_COLUMN = Messages.TmfStatisticsView_NbEventsTimeRangeColumn; + + /** Level column tooltips */ + private static final String LEVEL_COLUMN_TIP = Messages.TmfStatisticsView_LevelColumnTip; + + /** Number of events column tooltips */ + private static final String EVENTS_COUNT_COLUMN_TIP = Messages.TmfStatisticsView_NbEventsTip; + + /** Number of events in time range column tooltips */ + private static final String PARTIAL_COUNT_COLUMN_TIP = Messages.TmfStatisticsView_NbEventsTimeRangeTip; + + // ------------------------------------------------------------------------ + // Class attributes + // ------------------------------------------------------------------------ + + /** + * Level for which statistics should not be displayed. + * + * @since 3.0 + */ + public static final Set HIDDEN_FOLDER_LEVELS = ImmutableSet.of("Event Types"); //$NON-NLS-1$ + + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Column index (Ideally, this should not be hardcoded). + // ------------------------------------------------------------------------ + + /** + * Possible columns in the view + * + * @since 3.0 + */ + public static enum StatsColumn { + /** + * Column index for the event type column. + */ + EVENT(0), + /** + * Column index for the event total count column. + */ + TOTAL(1), + /** + * Column index for the event partial count column. + */ + PARTIAL(2), + /** + * Column index for the dummy column. + */ + DUMMY(3); + + private final int colIndex; + + private StatsColumn(int index) { + colIndex = index; + } + + /** + * Getter method for the column index. + * + * @return the index of the column + */ + public int getIndex() { + return colIndex; + } + + /** + * Method to get the column at a certain index. + * + * @param index the index of the column + * + * @return the column at the specified index + */ + public static StatsColumn getColumn(int index) { + switch(index) { + case 0: + return EVENT; + + case 1: + return TOTAL; + + case 2: + return PARTIAL; + + case 3: + return DUMMY; + + // Other values are illegal. + default: + throw new IllegalArgumentException(); + } + + } + } + + // ------------------------------------------------------------------------ + // Instance fields + // ------------------------------------------------------------------------ + + /** + * Contains the list of the columns + */ + private final List fColumnData; + + /** + * Create basic columns to represent the statistics data + */ + public TmfBaseColumnDataProvider() { + /* List that will be used to create the table. */ + ImmutableList.Builder builder = new ImmutableList.Builder<>(); + /* Column showing the name of the events and its level in the tree */ + builder.add(new TmfBaseColumnData( + LEVEL_COLUMN, + 200, + SWT.LEFT, + LEVEL_COLUMN_TIP, + new ColumnLabelProvider() { + @Override + public String getText(Object element) { + return ((TmfStatisticsTreeNode) element).getName(); + } + + @Override + public Image getImage(Object element) { + TmfStatisticsTreeNode node = (TmfStatisticsTreeNode) element; + if (HIDDEN_FOLDER_LEVELS.contains(node.getName())) { + return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER); + } + return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT); + } + }, + new ViewerComparator() { + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + TmfStatisticsTreeNode n1 = (TmfStatisticsTreeNode) e1; + TmfStatisticsTreeNode n2 = (TmfStatisticsTreeNode) e2; + + return n1.getName().compareTo(n2.getName()); + } + }, + null)); + + /* Column showing the total number of events */ + builder.add(new TmfBaseColumnData( + EVENTS_COUNT_COLUMN, + 140, + SWT.RIGHT, + EVENTS_COUNT_COLUMN_TIP, + new ColumnLabelProvider() { + @Override + public String getText(Object element) { + TmfStatisticsTreeNode node = (TmfStatisticsTreeNode) element; + if (!HIDDEN_FOLDER_LEVELS.contains(node.getName())) { + return TmfStatisticsFormatter.toColumnData(node, StatsColumn.TOTAL); + } + return EMPTY_STRING; + } + }, + new ViewerComparator() { + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + TmfStatisticsTreeNode n1 = (TmfStatisticsTreeNode) e1; + TmfStatisticsTreeNode n2 = (TmfStatisticsTreeNode) e2; + + return (int) (n1.getValues().getTotal() - n2.getValues().getTotal()); + } + }, + new ITmfColumnPercentageProvider() { + @Override + public double getPercentage(TmfStatisticsTreeNode node) { + TmfStatisticsTreeNode top = node.getTop(); + return (top == null || top.getValues().getTotal() == 0) ? + 0 : (double) (node.getValues().getTotal()) / top.getValues().getTotal(); + } + })); + + /* Column showing the number of events within the selected time range */ + builder.add(new TmfBaseColumnData( + PARTIAL_EVENTS_COUNT_COLUMN, + 140, + SWT.RIGHT, + PARTIAL_COUNT_COLUMN_TIP, + new ColumnLabelProvider() { + @Override + public String getText(Object element) { + TmfStatisticsTreeNode node = (TmfStatisticsTreeNode) element; + if (!HIDDEN_FOLDER_LEVELS.contains(node.getName())) { + return TmfStatisticsFormatter.toColumnData(node, StatsColumn.PARTIAL); + } + return EMPTY_STRING; + } + + }, + new ViewerComparator() { + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + TmfStatisticsTreeNode n1 = (TmfStatisticsTreeNode) e1; + TmfStatisticsTreeNode n2 = (TmfStatisticsTreeNode) e2; + + return (int) (n1.getValues().getPartial() - n2.getValues().getPartial()); + } + }, + new ITmfColumnPercentageProvider() { + @Override + public double getPercentage(TmfStatisticsTreeNode node) { + TmfStatisticsTreeNode top = node.getTop(); + return (top == null || top.getValues().getPartial() == 0) ? + 0 : (double) (node.getValues().getPartial()) / top.getValues().getPartial(); + } + })); + + /* Dummy column used to "fix" the display on Linux (using GTK) */ + builder.add(new TmfBaseColumnData(EMPTY_STRING, 1, SWT.RIGHT, EMPTY_STRING, + new ColumnLabelProvider() { + @Override + public String getText(Object element) { + return EMPTY_STRING; + } + }, + new ViewerComparator(), + new ITmfColumnPercentageProvider() { + @Override + public double getPercentage(TmfStatisticsTreeNode node) { + return 0; + } + })); + + fColumnData = builder.build(); + } + + /** + * Return a list of the column created for the view + * + * @return columns list + */ + public List getColumnData() { + return fColumnData; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsFormatter.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsFormatter.java new file mode 100644 index 0000000000..1027f24bc0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsFormatter.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vincent Perot - Add percentages to the label provider + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.statistics.model; + +import java.text.NumberFormat; +import java.util.Locale; + +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfBaseColumnDataProvider.StatsColumn; + +/** + * Class that format data for cells in the statistics view. + * + * @author Vincent Perot + * @since 3.0 + */ +public final class TmfStatisticsFormatter { + + /** + * Formatter for the column data + */ + private static final NumberFormat FORMATTER = NumberFormat.getNumberInstance(Locale.getDefault()); + + TmfStatisticsFormatter() { + // Nothing to construct. + } + + /** + * Generate the string for display in a cell. + * + * @param node + * Current node. + * @param config + * Configuration between total and partial. + * @return The formatted string ready for display. + */ + public static String toColumnData(TmfStatisticsTreeNode node, StatsColumn config) { + + long eventValue = 0; + + switch (config) { + + case TOTAL: + eventValue = node.getValues().getTotal(); + break; + + case PARTIAL: + eventValue = node.getValues().getPartial(); + break; + + // Other values are illegal. + // $CASES-OMITTED$ + default: + throw new IllegalArgumentException(); + } + + return FORMATTER.format(eventValue); + } + + /** + * Format the percentage according to user settings. + * + * @param percentage + * the percentage to format + * @return The formated percentage as a string. + */ + public static String toPercentageText(double percentage) { + + // The cast to long is needed because the formatter cannot truncate the number. + double truncPercentage = ((long) (1000.0 * percentage)) / 10.0; + + String percentageString = String.format("%s%s%s", " ", FORMATTER.format(truncPercentage), " % "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + return percentageString; + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsTree.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsTree.java new file mode 100755 index 0000000000..4cc4f12ee3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsTree.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Implementation and Initial API + * Alexandre Montplaisir - Merge TmfBaseStatisticsTree and AbsStatisticsTree + * Move the tree structure logic into the nodes + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.statistics.model; + + +/** + * Base class for the statistics storage. It allow to implement a tree structure + * while avoiding the need to run through the tree each time you need to add a + * node at a given place. + * + * @author Mathieu Denis + * @version 2.0 + * @since 2.0 + */ +public class TmfStatisticsTree { + + /** Header for the event type categories. */ + public static final String HEADER_EVENT_TYPES = Messages.TmfStatisticsData_EventTypes; + + /** Root node of this tree */ + private final TmfStatisticsTreeNode rootNode; + + /** + * Default constructor. Creates base statistics tree for counting total + * number of events and number of events per event type. + */ + public TmfStatisticsTree() { + rootNode = new TmfStatisticsTreeNode(this, null, new String[0]); + } + + /** + * Retrieve the root node of this tree. + * + * @return The root node + */ + public TmfStatisticsTreeNode getRootNode() { + return rootNode; + } + + /** + * Get a node. + * + * @param path + * Path to the node. + * @return The node, or null if it doesn't current exist in the tree. + */ + public TmfStatisticsTreeNode getNode(String... path) { + TmfStatisticsTreeNode curNode = rootNode; + for (String pathElem : path) { + curNode = curNode.getChild(pathElem); + if (curNode == null) { + /* The requested path doesn't exist, return null */ + break; + } + } + return curNode; + } + + /** + * Get or create a node. + * + * @param path + * Path to the node. + * @return The requested node. Will be created if it didn't exist. + */ + public TmfStatisticsTreeNode getOrCreateNode(String... path) { + TmfStatisticsTreeNode curNode = rootNode; + TmfStatisticsTreeNode nextNode; + for (String pathElem : path) { + nextNode = curNode.getChild(pathElem); + if (nextNode == null) { + nextNode = curNode.addChild(pathElem); + } + curNode = nextNode; + } + return curNode; + } + + /** + * Set the value to display in the "total" cells. This means the row + * indicating the total count of events for a trace. + * + * @param traceName + * The name of the trace (will be used as a sub-tree in the view) + * @param isGlobal + * Is this a for a global or a time range request? Determines if + * this goes in the Global column or the Selected Time Range one. + * @param qty + * The value to display + */ + public void setTotal(String traceName, boolean isGlobal, long qty) { + String[][] paths = getNormalPaths(traceName); + for (String path[] : paths) { + getOrCreateNode(path).getValues().setValue(isGlobal, qty); + } + } + + /** + * Set the value to display in the "Type count" cells. These are the counts + * for each event types. + * + * @param traceName + * The name of the trace (will be used as a sub-tree in the view) + * @param type + * The event type + * @param isGlobal + * Is this a for a global or a time range request? Determines if + * this goes in the Global column or the Selected Time Range one. + * @param qty + * The value to display + */ + public void setTypeCount(String traceName, String type, boolean isGlobal, long qty) { + String[][] paths = getTypePaths(traceName, type); + for (String[] path : paths) { + getOrCreateNode(path).getValues().setValue(isGlobal, qty); + } + } + + /** + * Get the event types paths. + * + * @param traceName + * The name of the trace (will be used as a sub-tree in the view) + * @param type + * The event type + * @return Array of arrays representing the paths + */ + protected String[][] getTypePaths(String traceName, String type) { + String[][] paths = { new String[] {traceName, HEADER_EVENT_TYPES, type } }; + return paths; + } + + /** + * Get the standard paths for an event. + * + * @param traceName + * The name of the trace (will be used as a sub-tree in the view) + * @return Array of arrays representing the paths + */ + protected String[][] getNormalPaths(String traceName) { + String[][] paths = { new String[] { traceName } }; + return paths; + } + + /** + * Function to merge many string more efficiently. + * + * @param strings + * Strings to merge. + * @return A new string containing all the strings. + */ + protected static String mergeString(String... strings) { + StringBuilder builder = new StringBuilder(); + for (String s : strings) { + builder.append(s); + } + return builder.toString(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsTreeManager.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsTreeManager.java new file mode 100755 index 0000000000..a40ea4a523 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsTreeManager.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.statistics.model; + +import java.util.HashMap; +import java.util.Map; + +/** + * Factory class to create and store TMF statistic trees. + * + * Based on a given tree node ID a TMF statistic tree is stored internally. A + * root node is created for each tree. Using the tree node ID the statistics + * tree can be retrieved. + * + * @author Mathieu Denis + * @version 2.0 + * @since 2.0 + */ +public class TmfStatisticsTreeManager { + + /** + * Contains the experiment name as the key and the traces data + */ + private static final Map fTreeInstances = new HashMap<>(); + + /** + * Provide a statisticsTree instance per trace + * + * @param traceUniqueId + * Unique ID for the trace + * @return The root node of the corresponding trace statistics tree + */ + public static TmfStatisticsTreeNode getStatTreeRoot(String traceUniqueId) { + + TmfStatisticsTree tree = getStatTree(traceUniqueId); + if (tree == null) { + return null; + } + return tree.getRootNode(); + } + + /** + * Get the tree that's being used for statistics + * + * @param traceUniqueId + * Unique ID for the trace + * @return the corresponding trace statistics tree + */ + public static TmfStatisticsTree getStatTree(String traceUniqueId) { + if (traceUniqueId == null) { + return null; + } + + TmfStatisticsTree tree = fTreeInstances.get(traceUniqueId); + return tree; + } + + /** + * Add the new trace statistics data in the tree. Can be used later on if + * the same traces is selected back. + * + * @param traceUniqueId + * The name of the trace which will be used as a key to store the + * data. Must be different for each traces, otherwise the traces + * might be overwritten which would trigger a reload of the same + * trace. + * @param statsData + * The information about the trace + * @return The newly created root node of the trace statistics tree, or null if something went wrong + */ + public static TmfStatisticsTreeNode addStatsTreeRoot(String traceUniqueId, TmfStatisticsTree statsData) { + if (traceUniqueId == null || statsData == null) { + return null; + } + fTreeInstances.put(traceUniqueId, statsData); + return statsData.getRootNode(); + } + + /** + * Return if the given trace is currently known by the statistics manager. + * + * @param traceUniqueId + * The unique ID of the trace + * @return true if the trace id is known + */ + public static boolean containsTreeRoot(String traceUniqueId) { + return fTreeInstances.containsKey(traceUniqueId); + } + + /** + * Remove previously registered statistics tree. + * + * @param traceUniqueId + * The unique ID of the trace + */ + public static void removeStatTreeRoot(String traceUniqueId) { + if (traceUniqueId != null && fTreeInstances.containsKey(traceUniqueId)) { + fTreeInstances.remove(traceUniqueId); + } + } + + /** + * Remove all tree and root instances + */ + public static void removeAll() { + fTreeInstances.clear(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsTreeNode.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsTreeNode.java new file mode 100755 index 0000000000..60fc91f714 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsTreeNode.java @@ -0,0 +1,252 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Yann N. Dauphin - Implementation for stats + * Francois Godin - Re-design for new stats structure + * Mathieu Denis - Re-design for new stats structure (2) + * Alexandre Montplaisir - Move the tree structure logic into the nodes + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.statistics.model; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * A tree where nodes can be accessed efficiently using paths. + * + * It works like file systems. Each node is identified by a key. A path is an + * array of String. The elements of the array represent the path from the root + * to this node. + * + * @author Mathieu Denis + * @version 2.0 + * @since 2.0 + */ +public class TmfStatisticsTreeNode { + + /** Tree to which this node belongs */ + private final TmfStatisticsTree fTree; + + /** Path of this node. The last element represents its basename. */ + private final String[] fPath; + + /** Parent node */ + private final TmfStatisticsTreeNode fParent; + + /** Children of this node, indexed by their basename. */ + private final Map fChildren; + + /** Statistics values associated to this node. */ + private final TmfStatisticsValues fValues; + + /** + * Return the node at the top of the branch + */ + private final TmfStatisticsTreeNode fTopNode; + + /** + * Constructor. + * + * @param tree + * Owner tree of this node + * @param parent + * Parent node of this one + * @param path + * Path to the node. + */ + public TmfStatisticsTreeNode(TmfStatisticsTree tree, + TmfStatisticsTreeNode parent, final String... path) { + /* + * The path must not contain any null element, or else we won't be able + * to walk the tree. + */ + for (String elem : path) { + if (elem == null) { + throw new IllegalArgumentException(); + } + } + + fTree = tree; + fPath = path; + fParent = parent; + fChildren = new ConcurrentHashMap<>(); + fValues = new TmfStatisticsValues(); + + /* calculating top node */ + TmfStatisticsTreeNode topNode = this; + while (topNode.getParent() != null && topNode.getParent().getParent() != null) { + topNode = topNode.getParent(); + } + fTopNode = topNode; + } + + /** + * Get the name for this node. It's used as the key in the parent's node. + * + * @return Name of this node. + */ + public String getName() { + if (fPath.length == 0) { + /* This means we are the root node, which has no path itself */ + return "root"; //$NON-NLS-1$ + } + return fPath[fPath.length - 1]; + } + + /** + * Test if a node contain the specified child. + * + * @param childName + * Name of the child. + * @return true: if child with given key is present, false: if no child + * exists with given key name + */ + public boolean containsChild(String childName) { + return fChildren.containsKey(childName); + } + + /** + * Retrieve the given child from this node. + * + * @param childName + * The (base)name of the child you want + * @return The child object, or null if it doesn't exist + */ + public TmfStatisticsTreeNode getChild(String childName) { + return fChildren.get(childName); + } + + /** + * Get the children of this node. + * + * @return Direct children of this node. + */ + public Collection getChildren() { + return fChildren.values(); + } + + /** + * Add a child to this node. + * + * @param childName + * Name of the child to add + * @return The newly-created child + */ + public TmfStatisticsTreeNode addChild(String childName) { + TmfStatisticsTreeNode child; + String[] childPath = new String[fPath.length + 1]; + System.arraycopy(fPath, 0, childPath, 0, fPath.length); + childPath[fPath.length] = childName; + + child = new TmfStatisticsTreeNode(this.fTree, this, childPath); + fChildren.put(childName, child); + return child; + } + + /** + * Get the number of children this node have. + * + * @return Number of direct children of this node. + */ + public int getNbChildren() { + return fChildren.size(); + } + + /** + * Return the parent node. + * + * @return Parent node. + */ + public TmfStatisticsTreeNode getParent() { + return fParent; + } + + /** + * Return the top node. + * + * @return Top node. + * @since 3.0 + */ + public TmfStatisticsTreeNode getTop() { + return fTopNode; + } + + /** + * Get the path of the node. + * + * @return The path of the node. + */ + public String[] getPath() { + return fPath; + } + + /** + * Get the value of this node. + * + * @return Value associated with this node. + */ + public TmfStatisticsValues getValues() { + return fValues; + } + + /** + * Indicate if the node have children. + * + * @return True if the node has children. + */ + public boolean hasChildren() { + return (fChildren.size() > 0); + } + + /** + * Start from creation time i.e. keep key and parent but new statistics and + * no children. + */ + public void reset() { + fValues.resetTotalCount(); + fValues.resetPartialCount(); + fChildren.clear(); + } + + /** + * Resets the global number of events. It doesn't remove any node and + * doesn't modify the partial event count. Works recursively. + * + * @since 2.0 + */ + public void resetGlobalValue() { + for (TmfStatisticsTreeNode child : fChildren.values()) { + child.resetGlobalValue(); + } + fValues.resetTotalCount(); + } + + /** + * Resets the number of events in the time range. It doesn't remove any node + * and doesn't modify the global event count. Works recursively. + * + * @since 2.0 + */ + public void resetTimeRangeValue() { + for (TmfStatisticsTreeNode child : fChildren.values()) { + child.resetTimeRangeValue(); + } + fValues.resetPartialCount(); + } + + @Override + public String toString() { + /* Used for debugging only */ + return "Stats node, path = " + Arrays.toString(fPath) + //$NON-NLS-1$ + ", values = " + fValues.toString(); //$NON-NLS-1$ + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsValues.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsValues.java new file mode 100755 index 0000000000..a9b567107c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfStatisticsValues.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2011, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Intial API and Implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.statistics.model; + +/** + * Primitive container for Statistics values. + * + * Contains information about statistics that can be retrieved with any type of + * traces. + * + * There are two counters : one for the total number of events in the trace, and + * another for the number of events in the selected time range. + * + * @author Mathieu Denis + * @version 2.0 + * @since 2.0 + */ +public class TmfStatisticsValues { + + /** + * Total number of events. + */ + protected long fNbEvents = 0; + + /** + * Number of events within a time range (Partial event count). + */ + protected long fNbEventsInTimeRange = 0; + + /** + * @return the total events count + */ + public long getTotal() { + return fNbEvents; + } + + /** + * @return the partial events count within a time range + */ + public long getPartial() { + return fNbEventsInTimeRange; + } + + /** + * Set either the "global" or the "time range" value. + * + * @param global + * True to set the global value, false for the timerange one. + * @param nb + * The new value to set + */ + public void setValue(boolean global, long nb) { + if (nb > 0) { + if (global) { + fNbEvents = nb; + } else { + fNbEventsInTimeRange = nb; + } + } + } + + /** + * Resets the total number of events. + */ + public void resetTotalCount() { + fNbEvents = 0; + } + + /** + * Resets the number of events within a time range (partial events count). + */ + public void resetPartialCount() { + fNbEventsInTimeRange = 0; + } + + @Override + public String toString() { + return fNbEvents + ", " + fNbEventsInTimeRange; //$NON-NLS-1$ + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfTreeContentProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfTreeContentProvider.java new file mode 100755 index 0000000000..6ece22b83b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/TmfTreeContentProvider.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.statistics.model; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +/** + * Adapter TreeViewers can use to interact with StatisticsTreeNode objects. + * + * @version 2.0 + * @since 2.0 + * @author Mathieu Denis + * @see org.eclipse.jface.viewers.ITreeContentProvider + */ +public class TmfTreeContentProvider implements ITreeContentProvider { + + @Override + public Object[] getChildren(Object parentElement) { + return ((TmfStatisticsTreeNode) parentElement).getChildren().toArray(); + } + + @Override + public Object getParent(Object element) { + return ((TmfStatisticsTreeNode) element).getParent(); + } + + @Override + public boolean hasChildren(Object element) { + return ((TmfStatisticsTreeNode) element).hasChildren(); + } + + @Override + public Object[] getElements(Object inputElement) { + return getChildren(inputElement); + } + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/messages.properties new file mode 100755 index 0000000000..484648adca --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/statistics/model/messages.properties @@ -0,0 +1,20 @@ +############################################################################### +# Copyright (c) 2013 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### + +TmfStatisticsData_CPUs=CPUs +TmfStatisticsData_EventTypes=Event Types +TmfStatisticsView_LevelColumn=Level +TmfStatisticsView_LevelColumnTip=Level at which statistics apply. +TmfStatisticsView_NbEventsColumn=Events total +TmfStatisticsView_NbEventsTip=Total amount of events contained in the trace +TmfStatisticsView_NbEventsTimeRangeColumn=Events in selection +TmfStatisticsView_NbEventsTimeRangeTip=Number of events in the currently selected time range diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/AbstractTmfTreeViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/AbstractTmfTreeViewer.java new file mode 100644 index 0000000000..5b604a77fa --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/AbstractTmfTreeViewer.java @@ -0,0 +1,508 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.tree; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableColorProvider; +import org.eclipse.jface.viewers.ITableFontProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.tracecompass.tmf.core.signal.TmfRangeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.viewers.TmfTimeViewer; + +/** + * Abstract class for viewers who will display data using a TreeViewer. It + * automatically synchronizes with time information of the UI. It also + * implements some common functionalities for all tree viewer, such as managing + * the column data, content initialization and update. The viewer implementing + * this does not have to worry about whether some code runs in the UI thread or + * not. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public abstract class AbstractTmfTreeViewer extends TmfTimeViewer { + + private final TreeViewer fTreeViewer; + + // ------------------------------------------------------------------------ + // Internal classes + // ------------------------------------------------------------------------ + + /* The elements of the tree viewer are of type ITmfTreeViewerEntry */ + private class TreeContentProvider implements ITreeContentProvider { + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + @Override + public Object[] getElements(Object inputElement) { + if (inputElement instanceof ITmfTreeViewerEntry) { + return ((ITmfTreeViewerEntry) inputElement).getChildren().toArray(new ITmfTreeViewerEntry[0]); + } + return new ITmfTreeViewerEntry[0]; + } + + @Override + public Object[] getChildren(Object parentElement) { + ITmfTreeViewerEntry entry = (ITmfTreeViewerEntry) parentElement; + List children = entry.getChildren(); + return children.toArray(new ITmfTreeViewerEntry[children.size()]); + } + + @Override + public Object getParent(Object element) { + ITmfTreeViewerEntry entry = (ITmfTreeViewerEntry) element; + return entry.getParent(); + } + + @Override + public boolean hasChildren(Object element) { + ITmfTreeViewerEntry entry = (ITmfTreeViewerEntry) element; + return entry.hasChildren(); + } + + } + + /** + * Base class to provide the labels for the tree viewer. Views extending + * this class typically need to override the getColumnText method if they + * have more than one column to display. It also allows to change the font + * and colors of the cells. + */ + protected static class TreeLabelProvider implements ITableLabelProvider, ITableFontProvider, ITableColorProvider { + + @Override + public void addListener(ILabelProviderListener listener) { + } + + @Override + public void dispose() { + } + + @Override + public boolean isLabelProperty(Object element, String property) { + return false; + } + + @Override + public void removeListener(ILabelProviderListener listener) { + } + + @Override + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + if ((element instanceof ITmfTreeViewerEntry) && (columnIndex == 0)) { + ITmfTreeViewerEntry entry = (ITmfTreeViewerEntry) element; + return entry.getName(); + } + return new String(); + } + + @Override + public Color getForeground(Object element, int columnIndex) { + return Display.getCurrent().getSystemColor(SWT.COLOR_LIST_FOREGROUND); + } + + @Override + public Color getBackground(Object element, int columnIndex) { + return Display.getCurrent().getSystemColor(SWT.COLOR_LIST_BACKGROUND); + } + + @Override + public Font getFont(Object element, int columnIndex) { + return null; + } + + } + + // ------------------------------------------------------------------------ + // Constructors and initialization methods + // ------------------------------------------------------------------------ + + /** + * Constructor + * + * @param parent + * The parent composite that holds this viewer + * @param allowMultiSelect + * Whether multiple selections are allowed + */ + public AbstractTmfTreeViewer(Composite parent, boolean allowMultiSelect) { + super(parent); + + int flags = SWT.FULL_SELECTION | SWT.H_SCROLL; + if (allowMultiSelect) { + flags |= SWT.MULTI; + } + + /* Build the tree viewer part of the view */ + fTreeViewer = new TreeViewer(parent, flags); + fTreeViewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS); + final Tree tree = fTreeViewer.getTree(); + tree.setHeaderVisible(true); + tree.setLinesVisible(true); + fTreeViewer.setContentProvider(new TreeContentProvider()); + fTreeViewer.setLabelProvider(new TreeLabelProvider()); + List columns = getColumnDataProvider().getColumnData(); + this.setTreeColumns(columns); + } + + /** + * Get the column data provider that will contain the list of columns to be + * part of this viewer. It is called once during the constructor. + * + * @return The tree column data provider for this viewer. + */ + protected abstract ITmfTreeColumnDataProvider getColumnDataProvider(); + + /** + * Sets the tree columns for this tree viewer + * + * @param columns + * The tree column data + */ + public void setTreeColumns(final List columns) { + boolean hasPercentProvider = false; + for (final TmfTreeColumnData columnData : columns) { + columnData.createColumn(fTreeViewer); + hasPercentProvider |= (columnData.getPercentageProvider() != null); + } + + if (hasPercentProvider) { + /* + * Handler that will draw bar charts in the cell using a percentage + * value. + */ + fTreeViewer.getTree().addListener(SWT.EraseItem, new Listener() { + @Override + public void handleEvent(Event event) { + if (columns.get(event.index).getPercentageProvider() != null) { + + double percentage = columns.get(event.index).getPercentageProvider().getPercentage(event.item.getData()); + if (percentage == 0) { // No bar to draw + return; + } + + if ((event.detail & SWT.SELECTED) > 0) { + /* + * The item is selected. Draw our own background to + * avoid overwriting the bar. + */ + event.gc.fillRectangle(event.x, event.y, event.width, event.height); + event.detail &= ~SWT.SELECTED; + } + + int barWidth = (int) ((fTreeViewer.getTree().getColumn(event.index).getWidth() - 8) * percentage); + int oldAlpha = event.gc.getAlpha(); + Color oldForeground = event.gc.getForeground(); + Color oldBackground = event.gc.getBackground(); + /* + * Draws a transparent gradient rectangle from the color + * of foreground and background. + */ + event.gc.setAlpha(64); + event.gc.setForeground(event.item.getDisplay().getSystemColor(SWT.COLOR_BLUE)); + event.gc.setBackground(event.item.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + event.gc.fillGradientRectangle(event.x, event.y, barWidth, event.height, true); + event.gc.drawRectangle(event.x, event.y, barWidth, event.height); + /* Restores old values */ + event.gc.setForeground(oldForeground); + event.gc.setBackground(oldBackground); + event.gc.setAlpha(oldAlpha); + event.detail &= ~SWT.BACKGROUND; + } + } + }); + } + } + + /** + * Set the label provider that will fill the columns of the tree viewer + * + * @param labelProvider + * The label provider to fill the columns + */ + protected void setLabelProvider(IBaseLabelProvider labelProvider) { + fTreeViewer.setLabelProvider(labelProvider); + } + + /** + * Get the tree viewer object + * + * @return The tree viewer object displayed by this viewer + */ + protected TreeViewer getTreeViewer() { + return fTreeViewer; + } + + // ------------------------------------------------------------------------ + // ITmfViewer + // ------------------------------------------------------------------------ + + @Override + public Control getControl() { + return fTreeViewer.getControl(); + } + + @Override + public void refresh() { + Tree tree = fTreeViewer.getTree(); + tree.setRedraw(false); + fTreeViewer.refresh(); + fTreeViewer.expandAll(); + tree.setRedraw(true); + } + + @Override + public void loadTrace(ITmfTrace trace) { + super.loadTrace(trace); + Thread thread = new Thread() { + @Override + public void run() { + initializeDataSource(); + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + clearContent(); + updateContent(getWindowStartTime(), getWindowEndTime(), false); + } + }); + } + }; + thread.start(); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Set the currently selected items in the treeviewer + * + * @param selection + * The list of selected items + * @since 3.1 + */ + public void setSelection(@NonNull List selection) { + IStructuredSelection sel = new StructuredSelection(selection); + fTreeViewer.setSelection(sel, true); + } + + /** + * Add a selection listener to the tree viewer. This will be called when the + * selection changes and contain all the selected items. + * + * The selection change listener can be used like this: + * + *

    +     * getTreeViewer().addSelectionChangeListener(new ISelectionChangedListener() {
    +     *     @Override
    +     *     public void selectionChanged(SelectionChangedEvent event) {
    +     *         if (event.getSelection() instanceof IStructuredSelection) {
    +     *             Object selection = ((IStructuredSelection) event.getSelection()).getFirstElement();
    +     *             if (selection instanceof ITmfTreeViewerEntry) {
    +     *                 // Do something
    +     *             }
    +     *         }
    +     *     }
    +     * });
    +     * 
    + * + * @param listener + * The {@link ISelectionChangedListener} + */ + public void addSelectionChangeListener(ISelectionChangedListener listener) { + fTreeViewer.addSelectionChangedListener(listener); + } + + /** + * Method called when the trace is loaded, to initialize any data once the + * trace has been set, but before the first call to update the content of + * the viewer. + */ + protected void initializeDataSource() { + + } + + /** + * Clears the current content of the viewer. + */ + protected void clearContent() { + fTreeViewer.setInput(null); + } + + /** + * Method called after the content has been updated and the new input has + * been set on the tree. + * + * @param rootEntry + * The new input of this viewer, or null if none + * @since 3.1 + */ + protected void contentChanged(ITmfTreeViewerEntry rootEntry) { + + } + + /** + * Requests an update of the viewer's content in a given time range or + * selection time range. An extra parameter defines whether these times + * correspond to the selection or the visible range, as the viewer may + * update differently in those cases. + * + * @param start + * The start time of the requested content + * @param end + * The end time of the requested content + * @param isSelection + * true if this time range is for a selection, + * false for the visible time range + */ + protected void updateContent(final long start, final long end, final boolean isSelection) { + Thread thread = new Thread() { + @Override + public void run() { + final ITmfTreeViewerEntry rootEntry = updateElements(start, end, isSelection); + /* Set the input in main thread only if it didn't change */ + if (rootEntry != null) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (rootEntry != fTreeViewer.getInput()) { + fTreeViewer.setInput(rootEntry); + contentChanged(rootEntry); + } else { + fTreeViewer.refresh(); + fTreeViewer.expandToLevel(fTreeViewer.getAutoExpandLevel()); + } + // FIXME should add a bit of padding + for (TreeColumn column : fTreeViewer.getTree().getColumns()) { + column.pack(); + } + } + }); + } + } + }; + thread.start(); + } + + /** + * Update the entries to the given start/end time. An extra parameter + * defines whether these times correspond to the selection or the visible + * range, as the viewer may update differently in those cases. This methods + * returns a root node that is not meant to be visible. The children of this + * 'fake' root node are the first level of entries that will appear in the + * tree. If no update is necessary, the method should return + * null. To empty the tree, a root node containing an empty + * list of children should be returned. + * + * This method is not called in the UI thread when using the default viewer + * content update. Resource-intensive calculations here should not block the + * UI. + * + * @param start + * The start time of the requested content + * @param end + * The end time of the requested content + * @param isSelection + * true if this time range is for a selection, + * false for the visible time range + * @return The root entry of the list of entries to display or + * null if no update necessary + */ + protected abstract ITmfTreeViewerEntry updateElements(long start, long end, boolean isSelection); + + /** + * Get the current input displayed by the viewer + * + * @return The input of the tree viewer, the root entry + */ + protected ITmfTreeViewerEntry getInput() { + return (ITmfTreeViewerEntry) fTreeViewer.getInput(); + } + + // ------------------------------------------------------------------------ + // Signal Handler + // ------------------------------------------------------------------------ + + /** + * Signal handler for handling of the time synch signal. The times + * correspond to the selection by the user, not the visible time range. + * + * @param signal + * The time synch signal {@link TmfTimeSynchSignal} + */ + @Override + @TmfSignalHandler + public void selectionRangeUpdated(TmfTimeSynchSignal signal) { + super.selectionRangeUpdated(signal); + if ((signal.getSource() != this) && (getTrace() != null)) { + updateContent(this.getSelectionBeginTime(), this.getSelectionEndTime(), true); + } + } + + /** + * Signal handler for handling of the time range synch signal. This time + * range is the visible zone of the view. + * + * @param signal + * The time range synch signal {@link TmfRangeSynchSignal} + */ + @Override + @TmfSignalHandler + public void timeRangeUpdated(TmfRangeSynchSignal signal) { + super.timeRangeUpdated(signal); + updateContent(this.getWindowStartTime(), this.getWindowEndTime(), false); + } + + @Override + public void reset() { + super.reset(); + clearContent(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/ITmfTreeColumnDataProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/ITmfTreeColumnDataProvider.java new file mode 100755 index 0000000000..e18d2bfa49 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/ITmfTreeColumnDataProvider.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial API and Implementation + * Geneviève Bastien - Moved class and adapted it to abstract tree viewer + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.tree; + +import java.util.List; + +/** + * Basic methods that must be implemented in a column data provider. Tree + * viewers will use class implementing this to populate the columns. + * + * @author Mathieu Denis + * @since 3.0 + */ +public interface ITmfTreeColumnDataProvider { + + /** + * Return a list of the column created for the view + * + * @return columns list + */ + List getColumnData(); +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/ITmfTreeViewerEntry.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/ITmfTreeViewerEntry.java new file mode 100644 index 0000000000..308fd26979 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/ITmfTreeViewerEntry.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.tree; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * Interface for an entry (row) in a TMF tree viewer + * + * @author Geneviève Bastien + * @since 3.0 + */ +public interface ITmfTreeViewerEntry { + + /** + * Returns the parent of this entry, or null if it has none. + * + * @return the parent element, or null if it has none + */ + ITmfTreeViewerEntry getParent(); + + /** + * Returns whether this entry has children. + * + * @return true if the given element has children, + * and false if it has no children + */ + boolean hasChildren(); + + /** + * Returns the child elements of this entry. + * + * @return an array of child elements + */ + @NonNull + List getChildren(); + + /** + * Returns the name of this entry. + * + * @return the entry name + */ + String getName(); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/TmfTreeColumnData.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/TmfTreeColumnData.java new file mode 100644 index 0000000000..5bbd2136a6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/TmfTreeColumnData.java @@ -0,0 +1,266 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial Implementation and API (in TmfBaseColumnData of + * statistics framework) + * Bernd Hufmann - Added Annotations + * Geneviève Bastien - Moved TmfBaseColumnData to this class and adapted + * it for the abstract tree viewer + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.tree; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Tree; + +/** + * Represents a column in an abstract tree viewer. It allows to define the + * column's characteristics: text, width, alignment, tooltip, comparators, + * percent providers, whether the column is movable, etc. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfTreeColumnData { + /** Name of the column. */ + private final String fText; + /** Width of the column. */ + private int fWidth = -1; + /** Alignment of the column. */ + private int fAlignment = SWT.LEAD; + /** Tooltip of the column. */ + private String fTooltip = null; + /** Used to sort elements of this column. If null, column is not sortable. */ + private ViewerComparator fComparator = null; + /** Whether the column is movable */ + private boolean fMovable = false; + /** Used to draw bar charts in this column. Can be null. */ + private ITmfColumnPercentageProvider fPercentageProvider = null; + + /** Used to draw bar charts in columns. */ + public interface ITmfColumnPercentageProvider { + + /** + * Percentage provider. Returns a percentage (between 0 and 100) from + * the given object. The object is usually an entry (a line of the tree + * viewer). + * + * @param data + * The data object corresponding to a line in the tree. + * @return The value as a percentage (between 0 and 100) + */ + public double getPercentage(Object data); + } + + /** + * Constructor with parameters + * + * @param text + * Text of the column. The name will be shown at the top of the + * column. + */ + public TmfTreeColumnData(String text) { + fText = text; + } + + /** + * Get the header text of a column + * + * @return The header text + */ + public String getText() { + return fText; + } + + /** + * Get the width of the column + * + * @return The column width + */ + public int getWidth() { + return fWidth; + } + + /** + * Get the alignment of the column + * + * @return The alignment (for example SWT.LEAD, SWT.RIGHT, etc) + */ + public int getAlignment() { + return fAlignment; + } + + /** + * Get the tooltip text to go with this column + * + * @return The tooltip text + */ + public String getTooltip() { + return fTooltip; + } + + /** + * Get the comparator used to sort columns. If null, then the + * column is not sortable + * + * @return The column comparator + */ + public ViewerComparator getComparator() { + return fComparator; + } + + /** + * Get the percentage provider for this column. This will allow to draw a + * bar chart inside the cells of this columns + * + * @return The percentage provider + */ + public ITmfColumnPercentageProvider getPercentageProvider() { + return fPercentageProvider; + } + + /** + * Return whether the column is movable or not + * + * @return True if column can be moved, false otherwise. + */ + public boolean isMovable() { + return fMovable; + } + + /** + * Set the width of the column. If not set, -1 is used. + * + * @param width + * Width of the column. Use -1 for tree viewer's default + * behavior. + */ + public void setWidth(int width) { + fWidth = width; + } + + /** + * Set the alignment of this column. If not set, default value is SWT.LEAD. + * + * @param alignment + * Alignment of the column. For example, SWT.LEAD, SWT.RIGHT, + * SWT.LEFT + */ + public void setAlignment(int alignment) { + fAlignment = alignment; + } + + /** + * Set the tooltip associated with this column + * + * @param tooltip + * the tooltip text + */ + public void setTooltip(String tooltip) { + fTooltip = tooltip; + } + + /** + * Set the comparator used to sort the column + * + * @param comparator + * The comparator. Use null to not sort the column. + */ + public void setComparator(ViewerComparator comparator) { + fComparator = comparator; + } + + /** + * Set the percentage provider that will provide a percentage value to draw + * a bar chart inside the cells of this column + * + * @param percentProvider + * The percentage provider + */ + public void setPercentageProvider(ITmfColumnPercentageProvider percentProvider) { + fPercentageProvider = percentProvider; + } + + /** + * Set whether the column can be moved in the tree viewer. Default is false. + * + * @param movable + * true if the column can be moved, false otherwise + */ + public void setMovable(boolean movable) { + fMovable = movable; + } + + /** + * Create a TreeColumn with this column's data and adds it to a {@link Tree} + * + * @param treeViewer + * The {@link TreeViewer} object to add the column to + * @return The newly created {@link TreeViewerColumn} + */ + @NonNull + public TreeViewerColumn createColumn(final TreeViewer treeViewer) { + final TreeViewerColumn column = new TreeViewerColumn(treeViewer, getAlignment()); + final TmfTreeColumnData columnData = this; + column.getColumn().setText(getText()); + if (getWidth() != -1) { + column.getColumn().setWidth(getWidth()); + } + if (getTooltip() != null) { + column.getColumn().setToolTipText(getTooltip()); + } + column.getColumn().setMoveable(isMovable()); + + /* Add the comparator to sort the column */ + if (getComparator() != null) { + column.getColumn().addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + + if (treeViewer.getTree().getSortDirection() == SWT.UP || treeViewer.getTree().getSortColumn() != column.getColumn()) { + /* + * Puts the descendant order if the old order was up + * or if the selected column has changed. + */ + treeViewer.setComparator(columnData.getComparator()); + treeViewer.getTree().setSortDirection(SWT.DOWN); + } else { + ViewerComparator reverseComparator; + /* Initializes the reverse comparator. */ + reverseComparator = new ViewerComparator() { + @Override + public int compare(Viewer viewer, Object e1, Object + e2) { + return -1 * columnData.getComparator().compare(viewer, e1, e2); + } + }; + + /* + * Puts the ascendant ordering if the selected + * column hasn't changed. + */ + treeViewer.setComparator(reverseComparator); + treeViewer.getTree().setSortDirection(SWT.UP); + } + treeViewer.getTree().setSortColumn(column.getColumn()); + } + }); + } + + return column; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/TmfTreeViewerEntry.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/TmfTreeViewerEntry.java new file mode 100644 index 0000000000..7d96734078 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/TmfTreeViewerEntry.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.tree; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * Basic implementation of an entry for the TMF tree viewer. A name is all that is needed for this entry. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfTreeViewerEntry implements ITmfTreeViewerEntry { + + /** Entry's parent */ + private ITmfTreeViewerEntry fParent = null; + + /** List of child entries */ + @NonNull + private final List fChildren = new CopyOnWriteArrayList<>(); + + /** Name of this entry (default text to show in first column) */ + private String fName; + + /** + * Constructor + * + * @param name + * The name of this entry + */ + public TmfTreeViewerEntry(String name) { + fName = name; + } + + // --------------------------------------------- + // Getters and setters + // --------------------------------------------- + + @Override + public ITmfTreeViewerEntry getParent() { + return fParent; + } + + /** + * Sets the entry's parent + * + * @param entry The new parent entry + */ + protected void setParent(ITmfTreeViewerEntry entry) { + fParent = entry; + } + + @Override + public boolean hasChildren() { + return fChildren.size() > 0; + } + + @Override + public List getChildren() { + return fChildren; + } + + @Override + public String getName() { + return fName; + } + + /** + * Update the entry name + * + * @param name + * the updated entry name + */ + public void setName(String name) { + fName = name; + } + + /** + * Add a child entry to this one + * + * @param child + * The child entry + */ + public void addChild(TmfTreeViewerEntry child) { + child.fParent = this; + fChildren.add(child); + } + + @Override + public String toString() { + return getClass().getSimpleName() + '[' + fName + ']'; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/ITmfChartTimeProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/ITmfChartTimeProvider.java new file mode 100644 index 0000000000..722b067b80 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/ITmfChartTimeProvider.java @@ -0,0 +1,54 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Geneviève Bastien - Moved some methods to ITmfTimeProvider + **********************************************************************/ +package org.eclipse.tracecompass.tmf.ui.viewers.xycharts; + +import org.eclipse.tracecompass.tmf.ui.viewers.ITmfTimeProvider; + +/** + * Interface adding some methods specific for SWT charts to the base time + * provider interface. Typically, the time will be shown on the x-axis. + * + * @author Bernd Hufmann + * @since 3.0 + */ +public interface ITmfChartTimeProvider extends ITmfTimeProvider { + + /** + * Returns a constant time offset that is used to normalize the time values + * to a range of 0..53 bits to avoid loss of precision when converting long + * <-> double. + * + * Time values are stored in TMF as long values. The SWT chart library uses + * values of type double (on x and y axis). To avoid loss of precision when + * converting long <-> double the values need to fit within 53 bits. + * + * Subtract the offset when using time values provided externally for + * internal usage in SWT chart. Add the offset when using time values + * provided by SWT chart (e.g. for display purposes) and when broadcasting + * them externally (e.g. time synchronization signals). + * + * For example the offset can be calculated as the time of the first time + * value in the current time range to be displayed in the chart. Add +1 to + * avoid 0 when using logarithmic scale. + * + * t0=10000, t2=20000, tn=N -> timeOffset=t0-1 -> t0'=1, t1'=10001, + * tn'=N-timeOffset + * + * where t0 ... tn are times used externally and t0' ... tn' are times used + * internally by the SWT chart. + * + * @return the time offset + */ + long getTimeOffset(); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfBaseProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfBaseProvider.java new file mode 100644 index 0000000000..39a771c188 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfBaseProvider.java @@ -0,0 +1,155 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ +package org.eclipse.tracecompass.tmf.ui.viewers.xycharts; + +import org.swtchart.Chart; +import org.swtchart.IAxis; + +/** + * Base class for any provider such as tool tip, zoom and selection providers. + * + * @author Bernd Hufmann + * @since 3.0 + */ +abstract public class TmfBaseProvider { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** Reference to the chart viewer */ + private final ITmfChartTimeProvider fChartViewer; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Standard constructor. + * + * @param tmfChartViewer + * The parent histogram object + */ + public TmfBaseProvider(ITmfChartTimeProvider tmfChartViewer) { + fChartViewer = tmfChartViewer; + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + /** + * Returns the chart viewer reference. + * @return the chart viewer reference + */ + public ITmfChartTimeProvider getChartViewer() { + return fChartViewer; + } + + /** + * Returns the SWT chart reference + * + * @return SWT chart reference. + */ + protected Chart getChart() { + return (Chart) fChartViewer.getControl(); + } + + /** + * Limits x data coordinate to window start and window end range + * + * @param x + * x to limit + * @return x if x >= begin && x <= end + * begin if x < begin + * end if x > end + */ + protected long limitXDataCoordinate(double x) { + ITmfChartTimeProvider viewer = getChartViewer(); + long windowStartTime = viewer.getWindowStartTime() - viewer.getTimeOffset(); + long windowEndTime = viewer.getWindowEndTime() - viewer.getTimeOffset(); + + if (x < windowStartTime) { + return windowStartTime; + } + + if (x > windowEndTime) { + return windowEndTime; + } + + return (long) x; + } + + /** + * Limits x pixel coordinate to window start and window end range + * + * @param axisIndex + * index of x-axis + * @param x + * x to limit + * @return x if x >= begin && x <= end + * begin if x < begin + * end if x > end + */ + protected int limitXPixelCoordinate(int axisIndex, int x) { + ITmfChartTimeProvider viewer = getChartViewer(); + long windowStartTime = viewer.getWindowStartTime() - viewer.getTimeOffset(); + long windowEndTime = viewer.getWindowEndTime() - viewer.getTimeOffset(); + + IAxis xAxis = getChart().getAxisSet().getXAxis(0); + int startX = xAxis.getPixelCoordinate(windowStartTime); + if (x < startX) { + return startX; + } + + int endX = xAxis.getPixelCoordinate(windowEndTime); + if (x > endX) { + return endX; + } + + return x; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + /** + * Method deregisters provider from chart viewer. Subclasses may override this method + * to dispose any resources. + */ + public void dispose() { + deregister(); + } + + /** + * Method to refresh the viewer. It will redraw the viewer. + */ + public void refresh() { + if (!TmfXYChartViewer.getDisplay().isDisposed()) { + TmfXYChartViewer.getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + getChart().redraw(); + } + }); + } + } + + /** + * Method to register the provider to chart viewer. + */ + protected abstract void register(); + + /** + * Method to deregister the provider from chart viewer. + */ + protected abstract void deregister(); + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfChartTimeStampFormat.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfChartTimeStampFormat.java new file mode 100644 index 0000000000..f8cea6a44f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfChartTimeStampFormat.java @@ -0,0 +1,63 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ +package org.eclipse.tracecompass.tmf.ui.viewers.xycharts; + +import java.text.FieldPosition; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; + +/** + * SimpleDateFormat class for displaying time information in SWT charts + * using the TmfTimestampFormat class. + * + * @author Bernd Hufmann + * @since 3.0 + */ +public class TmfChartTimeStampFormat extends SimpleDateFormat { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + private static final long serialVersionUID = 3719743469686142387L; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + private long fOffset; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Standard Constructor + * + * @param offset + * offset to apply before formatting time (time = time + offset) + */ + public TmfChartTimeStampFormat(long offset) { + fOffset = offset; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + @Override + public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) { + + long time = date.getTime() + fOffset; + toAppendTo.append(TmfTimestampFormat.getDefaulTimeFormat().format(time)); + return toAppendTo; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfMouseDragProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfMouseDragProvider.java new file mode 100644 index 0000000000..1cdc7d5355 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfMouseDragProvider.java @@ -0,0 +1,135 @@ +/********************************************************************** + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ +package org.eclipse.tracecompass.tmf.ui.viewers.xycharts; + +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.swtchart.IAxis; +import org.swtchart.Range; + +/** + * Class for updating time ranges based on middle mouse button drag. + * It also notifies the viewer about a change of range. + * + * @author Bernd Hufmann + * @since 3.0 + */ +public class TmfMouseDragProvider extends TmfBaseProvider implements MouseListener, MouseMoveListener { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** Cached start time */ + private long fStartTime; + /** Cached end time */ + private long fEndTime; + /** Flag indicating that an update is ongoing */ + private boolean fIsUpdate; + /** Cached position when mouse button was pressed */ + private int fStartPosition; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor + * + * @param tmfChartViewer + * the chart viewer reference. + */ + public TmfMouseDragProvider(ITmfChartTimeProvider tmfChartViewer) { + super(tmfChartViewer); + register(); + } + + // ------------------------------------------------------------------------ + // TmfBaseProvider + // ------------------------------------------------------------------------ + @Override + public void register() { + getChart().getPlotArea().addMouseListener(this); + getChart().getPlotArea().addMouseMoveListener(this); + } + + @Override + public void deregister() { + if ((getChartViewer().getControl() != null) && !getChartViewer().getControl().isDisposed()) { + getChart().getPlotArea().removeMouseListener(this); + getChart().getPlotArea().removeMouseMoveListener(this); + } + } + + @Override + public void refresh() { + // nothing to do + } + + // ------------------------------------------------------------------------ + // MouseListener + // ------------------------------------------------------------------------ + @Override + public void mouseDoubleClick(MouseEvent e) { + } + + @Override + public void mouseDown(MouseEvent e) { + if ((getChartViewer().getWindowDuration() != 0) && (e.button == 2)) { + fStartPosition = e.x; + fIsUpdate = true; + } + } + + @Override + public void mouseUp(MouseEvent e) { + if ((fIsUpdate) && (fStartTime != fEndTime)) { + ITmfChartTimeProvider viewer = getChartViewer(); + viewer.updateWindow(fStartTime, fEndTime); + } + fIsUpdate = false; + } + + // ------------------------------------------------------------------------ + // MouseMoveListener + // ------------------------------------------------------------------------ + @Override + public void mouseMove(MouseEvent e) { + if (fIsUpdate) { + IAxis xAxis = getChart().getAxisSet().getXAxis(0); + + ITmfChartTimeProvider viewer = getChartViewer(); + + fStartTime = viewer.getWindowStartTime(); + fEndTime = viewer.getWindowEndTime(); + + long startTime = viewer.getStartTime(); + long endTime = viewer.getEndTime(); + + long delta = 0; + if (fStartPosition > e.x) { + delta = (long) (xAxis.getDataCoordinate(fStartPosition) - xAxis.getDataCoordinate(e.x)); + long max = endTime - fEndTime; + delta = Math.max(0, Math.min(delta, max)); + fStartTime = fStartTime + delta; + fEndTime = fEndTime + delta; + } else if (fStartPosition < e.x) { + delta = (long) (xAxis.getDataCoordinate(e.x) - xAxis.getDataCoordinate(fStartPosition)); + long max = fStartTime - startTime; + delta = Math.max(0, Math.min(delta, max)); + fStartTime = fStartTime - delta; + fEndTime = fEndTime - delta; + } + + xAxis.setRange(new Range(fStartTime - viewer.getTimeOffset(), fEndTime - viewer.getTimeOffset())); + } + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfMouseDragZoomProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfMouseDragZoomProvider.java new file mode 100644 index 0000000000..e0353b6b68 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfMouseDragZoomProvider.java @@ -0,0 +1,152 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ +package org.eclipse.tracecompass.tmf.ui.viewers.xycharts; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.PaintEvent; +import org.swtchart.IAxis; +import org.swtchart.ICustomPaintListener; +import org.swtchart.IPlotArea; + +/** + * Class for providing zooming based on mouse drag with right mouse button. + * It also notifies the viewer about a change of range. + * + * @author Bernd Hufmann + * @since 3.0 + */ +public class TmfMouseDragZoomProvider extends TmfBaseProvider implements MouseListener, MouseMoveListener, ICustomPaintListener { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** Cached start time */ + private long fStartTime; + /** Cached end time */ + private long fEndTime; + /** Flag indicating that an update is ongoing */ + private boolean fIsUpdate; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor + * + * @param tmfChartViewer + * the chart viewer reference. + */ + public TmfMouseDragZoomProvider(ITmfChartTimeProvider tmfChartViewer) { + super(tmfChartViewer); + register(); + } + + // ------------------------------------------------------------------------ + // TmfBaseProvider + // ------------------------------------------------------------------------ + @Override + public void register() { + getChart().getPlotArea().addMouseListener(this); + getChart().getPlotArea().addMouseMoveListener(this); + ((IPlotArea) getChart().getPlotArea()).addCustomPaintListener(this); + } + + @Override + public void deregister() { + if ((getChartViewer().getControl() != null) && !getChartViewer().getControl().isDisposed()) { + getChart().getPlotArea().removeMouseListener(this); + getChart().getPlotArea().removeMouseMoveListener(this); + ((IPlotArea) getChart().getPlotArea()).removeCustomPaintListener(this); + } + } + + @Override + public void refresh() { + // nothing to do + } + + // ------------------------------------------------------------------------ + // MouseListener + // ------------------------------------------------------------------------ + @Override + public void mouseDoubleClick(MouseEvent e) { + } + + @Override + public void mouseDown(MouseEvent e) { + if ((getChartViewer().getWindowDuration() != 0) && (e.button == 3)) { + IAxis xAxis = getChart().getAxisSet().getXAxis(0); + fStartTime = limitXDataCoordinate(xAxis.getDataCoordinate(e.x)); + fEndTime = fStartTime; + fIsUpdate = true; + } + } + + @Override + public void mouseUp(MouseEvent e) { + if ((fIsUpdate) && (fStartTime != fEndTime)) { + if (fStartTime > fEndTime) { + long tmp = fStartTime; + fStartTime = fEndTime; + fEndTime = tmp; + } + ITmfChartTimeProvider viewer = getChartViewer(); + viewer.updateWindow(fStartTime + viewer.getTimeOffset(), fEndTime + viewer.getTimeOffset()); + } + + if (fIsUpdate) { + getChart().redraw(); + } + fIsUpdate = false; + } + + // ------------------------------------------------------------------------ + // MouseMoveListener + // ------------------------------------------------------------------------ + @Override + public void mouseMove(MouseEvent e) { + if (fIsUpdate) { + IAxis xAxis = getChart().getAxisSet().getXAxis(0); + fEndTime = limitXDataCoordinate(xAxis.getDataCoordinate(e.x)); + getChart().redraw(); + } + } + + // ------------------------------------------------------------------------ + // ICustomPaintListener + // ------------------------------------------------------------------------ + @Override + public void paintControl(PaintEvent e) { + if (fIsUpdate && (fStartTime != fEndTime)) { + IAxis xAxis = getChart().getAxisSet().getXAxis(0); + int startX = xAxis.getPixelCoordinate(fStartTime); + int endX = xAxis.getPixelCoordinate(fEndTime); + + e.gc.setBackground(TmfXYChartViewer.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND)); + if (fStartTime < fEndTime) { + e.gc.fillRectangle(startX, 0, endX - startX, e.height); + } else { + e.gc.fillRectangle(endX, 0, startX - endX, e.height); + } + e.gc.drawLine(startX, 0, startX, e.height); + e.gc.drawLine(endX, 0, endX, e.height); + } + } + + @Override + public boolean drawBehindSeries() { + return true; + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfMouseSelectionProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfMouseSelectionProvider.java new file mode 100644 index 0000000000..d63b3a8e82 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfMouseSelectionProvider.java @@ -0,0 +1,164 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ +package org.eclipse.tracecompass.tmf.ui.viewers.xycharts; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.PaintEvent; +import org.swtchart.IAxis; +import org.swtchart.ICustomPaintListener; +import org.swtchart.IPlotArea; + +/** + * Class for providing selection of ranges with the left mouse button. + * It also notifies the viewer about a change of selection. + * + * @author Bernd Hufmann + * @since 3.0 + */ +public class TmfMouseSelectionProvider extends TmfBaseProvider implements MouseListener, MouseMoveListener, ICustomPaintListener { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** Cached start time */ + private long fBeginTime; + /** Cached end time */ + private long fEndTime; + /** Flag indicating that an update is ongoing */ + private boolean fIsInternalUpdate; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor + * + * @param tmfChartViewer + * The chart viewer reference. + */ + public TmfMouseSelectionProvider(ITmfChartTimeProvider tmfChartViewer) { + super(tmfChartViewer); + register(); + } + + // ------------------------------------------------------------------------ + // TmfBaseProvider + // ------------------------------------------------------------------------ + @Override + public void register() { + getChart().getPlotArea().addMouseListener(this); + getChart().getPlotArea().addMouseMoveListener(this); + ((IPlotArea) getChart().getPlotArea()).addCustomPaintListener(this); + } + + @Override + public void deregister() { + if ((getChartViewer().getControl() != null) && !getChartViewer().getControl().isDisposed()) { + getChart().getPlotArea().removeMouseListener(this); + getChart().getPlotArea().removeMouseMoveListener(this); + ((IPlotArea) getChart().getPlotArea()).removeCustomPaintListener(this); + } + } + + // ------------------------------------------------------------------------ + // MouseListener + // ------------------------------------------------------------------------ + @Override + public void mouseDoubleClick(MouseEvent e) { + } + + @Override + public void mouseDown(MouseEvent e) { + if ((getChartViewer().getWindowDuration() != 0) && (e.button == 1)) { + IAxis xAxis = getChart().getAxisSet().getXAxis(0); + fBeginTime = limitXDataCoordinate(xAxis.getDataCoordinate(e.x)); + fEndTime = fBeginTime; + fIsInternalUpdate = true; + } + } + + @Override + public void mouseUp(MouseEvent e) { + if (fIsInternalUpdate) { + if (fBeginTime > fEndTime) { + // Swap time + long tmp = fBeginTime; + fBeginTime = fEndTime; + fEndTime = tmp; + } + ITmfChartTimeProvider viewer = getChartViewer(); + viewer.updateSelectionRange(fBeginTime + viewer.getTimeOffset(), fEndTime + viewer.getTimeOffset()); + fIsInternalUpdate = false; + getChart().redraw(); + } + } + + // ------------------------------------------------------------------------ + // MouseMoveListener + // ------------------------------------------------------------------------ + @Override + public void mouseMove(MouseEvent e) { + if (fIsInternalUpdate) { + IAxis xAxis = getChart().getAxisSet().getXAxis(0); + fEndTime = limitXDataCoordinate(xAxis.getDataCoordinate(e.x)); + getChart().redraw(); + } + } + + // ------------------------------------------------------------------------ + // ICustomPaintListener + // ------------------------------------------------------------------------ + @Override + public void paintControl(PaintEvent e) { + ITmfChartTimeProvider viewer = getChartViewer(); + + if (!fIsInternalUpdate) { + fBeginTime = viewer.getSelectionBeginTime() - viewer.getTimeOffset(); + fEndTime = viewer.getSelectionEndTime() - viewer.getTimeOffset(); + } + long windowStartTime = viewer.getWindowStartTime() - viewer.getTimeOffset(); + long windowEndTime = viewer.getWindowEndTime() - viewer.getTimeOffset(); + + IAxis xAxis = getChart().getAxisSet().getXAxis(0); + e.gc.setBackground(TmfXYChartViewer.getDisplay().getSystemColor(SWT.COLOR_BLUE)); + e.gc.setForeground(TmfXYChartViewer.getDisplay().getSystemColor(SWT.COLOR_BLUE)); + e.gc.setLineStyle(SWT.LINE_SOLID); + if ((fBeginTime >= windowStartTime) && (fBeginTime <= windowEndTime)) { + int beginX = xAxis.getPixelCoordinate(fBeginTime); + e.gc.drawLine(beginX, 0, beginX, e.height); + } + + if ((fEndTime >= windowStartTime) && (fEndTime <= windowEndTime) && (fBeginTime != fEndTime)) { + int endX = xAxis.getPixelCoordinate(fEndTime); + e.gc.drawLine(endX, 0, endX, e.height); + } + e.gc.setAlpha(150); + if (Math.abs(fEndTime - fBeginTime) > 1) { + e.gc.setBackground(TmfXYChartViewer.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + int beginX = xAxis.getPixelCoordinate(fBeginTime); + int endX = xAxis.getPixelCoordinate(fEndTime); + if (fEndTime > fBeginTime) { + e.gc.fillRectangle(beginX + 1, 0, endX - beginX - 1, e.height); + } else { + e.gc.fillRectangle(endX + 1, 0, beginX - endX - 1, e.height); + } + } + } + + @Override + public boolean drawBehindSeries() { + return false; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfMouseWheelZoomProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfMouseWheelZoomProvider.java new file mode 100644 index 0000000000..2ed79fa1c2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfMouseWheelZoomProvider.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.xycharts; + +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseWheelListener; +import org.swtchart.IAxis; + +/** + * Class for providing zooming based on mouse wheel. It centers the zoom on + * mouse position. It also notifies the viewer about a change of range. + * + * @author Bernd Hufmann + * @since 3.0 + */ +public class TmfMouseWheelZoomProvider extends TmfBaseProvider implements MouseWheelListener { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + private final static double ZOOM_FACTOR = 0.8; + private final static long MIN_WINDOW_SIZE = 1; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Standard constructor. + * + * @param tmfChartViewer + * The parent histogram object + */ + public TmfMouseWheelZoomProvider(ITmfChartTimeProvider tmfChartViewer) { + super(tmfChartViewer); + register(); + } + + // ------------------------------------------------------------------------ + // TmfBaseProvider + // ------------------------------------------------------------------------ + @Override + public void register() { + getChart().getPlotArea().addMouseWheelListener(this); + } + + @Override + public void deregister() { + if ((getChartViewer().getControl() != null) && !getChartViewer().getControl().isDisposed()) { + getChart().getPlotArea().removeMouseWheelListener(this); + } + } + + @Override + public void refresh() { + // nothing to do + } + + // ------------------------------------------------------------------------ + // MouseWheelListener + // ------------------------------------------------------------------------ + @Override + public synchronized void mouseScrolled(MouseEvent event) { + ITmfChartTimeProvider viewer = getChartViewer(); + + long oldDuration = viewer.getWindowDuration(); + + if (oldDuration == 0) { + return; + } + + // Compute the new time range + long newDuration = oldDuration; + double ratio = 1.0; + if (event.count > 0) { + ratio = ZOOM_FACTOR; + newDuration = Math.round(ZOOM_FACTOR * oldDuration); + } else { + ratio = 1.0 / ZOOM_FACTOR; + newDuration = (long) Math.ceil(oldDuration * ratio); + } + newDuration = Math.max(MIN_WINDOW_SIZE, newDuration); + + // Center the zoom on mouse position, distribute new duration and adjust for boundaries. + IAxis xAxis = getChart().getAxisSet().getXAxis(0); + long timeAtXPos = limitXDataCoordinate(xAxis.getDataCoordinate(event.x)) + viewer.getTimeOffset(); + // Note: ratio = newDuration/oldDuration + long newWindowStartTime = timeAtXPos - Math.round(ratio * (timeAtXPos - viewer.getWindowStartTime())); + long newWindowEndTime = validateWindowEndTime(newWindowStartTime, newWindowStartTime + newDuration); + newWindowStartTime = validateWindowStartTime(newWindowStartTime); + viewer.updateWindow(newWindowStartTime, newWindowEndTime); + } + + // ------------------------------------------------------------------------ + // Helper methods + // ------------------------------------------------------------------------ + private long validateWindowStartTime(long start) { + ITmfChartTimeProvider viewer = getChartViewer(); + long realStart = start; + + long startTime = viewer.getStartTime(); + long endTime = viewer.getEndTime(); + + if (realStart < startTime) { + realStart = startTime; + } + if (realStart > endTime) { + realStart = endTime; + } + return realStart; + } + + private long validateWindowEndTime(long start, long end) { + ITmfChartTimeProvider viewer = getChartViewer(); + long realEnd = end; + long endTime = viewer.getEndTime(); + + if (realEnd > endTime) { + realEnd = endTime; + } + if (realEnd < start + MIN_WINDOW_SIZE) { + realEnd = start + MIN_WINDOW_SIZE; + } + return realEnd; + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfSimpleTooltipProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfSimpleTooltipProvider.java new file mode 100644 index 0000000000..e51d622e5c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfSimpleTooltipProvider.java @@ -0,0 +1,97 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ +package org.eclipse.tracecompass.tmf.ui.viewers.xycharts; + +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.swtchart.IAxis; + +/** + * Tool tip provider for TMF chart viewer. It displays the x and y + * value of the current mouse position. + * + * @author Bernd Hufmann + * @since 3.0 + */ +public class TmfSimpleTooltipProvider extends TmfBaseProvider implements MouseTrackListener { + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Constructor for a tool tip provider. + * + * @param tmfChartViewer + * The parent chart viewer + */ + public TmfSimpleTooltipProvider(ITmfChartTimeProvider tmfChartViewer) { + super(tmfChartViewer); + register(); + } + + // ------------------------------------------------------------------------ + // TmfBaseProvider + // ------------------------------------------------------------------------ + @Override + public void register() { + getChart().getPlotArea().addMouseTrackListener(this); + } + + @Override + public void deregister() { + if ((getChartViewer().getControl() != null) && !getChartViewer().getControl().isDisposed()) { + getChart().getPlotArea().removeMouseTrackListener(this); + } + } + + @Override + public void refresh() { + // nothing to do + } + + // ------------------------------------------------------------------------ + // MouseTrackListener + // ------------------------------------------------------------------------ + @Override + public void mouseEnter(MouseEvent e) { + } + + @Override + public void mouseExit(MouseEvent e) { + } + + @Override + public void mouseHover(MouseEvent e) { + if (getChartViewer().getWindowDuration() == 0) { + return; + } + + IAxis xAxis = getChart().getAxisSet().getXAxis(0); + IAxis yAxis = getChart().getAxisSet().getYAxis(0); + + double xCoordinate = xAxis.getDataCoordinate(e.x); + double yCoordinate = yAxis.getDataCoordinate(e.y); + + ITmfChartTimeProvider viewer = getChartViewer(); + + /* set tooltip of current data point */ + StringBuffer buffer = new StringBuffer(); + buffer.append("x="); //$NON-NLS-1$ + buffer.append(new TmfTimestamp((long) xCoordinate + viewer.getTimeOffset(), ITmfTimestamp.NANOSECOND_SCALE).toString()); + buffer.append("\n"); //$NON-NLS-1$ + buffer.append("y="); //$NON-NLS-1$ + buffer.append((long) yCoordinate); + getChart().getPlotArea().setToolTipText(buffer.toString()); + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfXYChartViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfXYChartViewer.java new file mode 100644 index 0000000000..4e4580704a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/TmfXYChartViewer.java @@ -0,0 +1,373 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Geneviève Bastien - Moved some methods to TmfTimeViewer + **********************************************************************/ +package org.eclipse.tracecompass.tmf.ui.viewers.xycharts; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.tmf.core.signal.TmfRangeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.viewers.TmfTimeViewer; +import org.swtchart.Chart; +import org.swtchart.IAxis; +import org.swtchart.ISeries; +import org.swtchart.ISeriesSet; + +/** + * Base class for a XY-Chart based on SWT chart. It provides a methods to define + * zoom, selection and tool tip providers. It also provides call backs to be + * notified by any changes caused by selection and zoom. + * + * @author Bernd Hufmann + * @since 3.0 + */ +public abstract class TmfXYChartViewer extends TmfTimeViewer implements ITmfChartTimeProvider { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The offset to apply to any x position. This offset ensures better + * precision when converting long to double and back. + */ + private long fTimeOffset; + /** The SWT Chart reference */ + private Chart fSwtChart; + /** The mouse selection provider */ + private TmfBaseProvider fMouseSelectionProvider; + /** The mouse drag zoom provider */ + private TmfBaseProvider fMouseDragZoomProvider; + /** The mouse wheel zoom provider */ + private TmfBaseProvider fMouseWheelZoomProvider; + /** The tooltip provider */ + private TmfBaseProvider fToolTipProvider; + /** The middle mouse drag provider */ + private TmfBaseProvider fMouseDragProvider; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructs a TmfXYChartViewer. + * + * @param parent + * The parent composite + * @param title + * The title of the viewer + * @param xLabel + * The label of the xAxis + * @param yLabel + * The label of the yAXIS + */ + public TmfXYChartViewer(Composite parent, String title, String xLabel, String yLabel) { + super(parent, title); + fSwtChart = new Chart(parent, SWT.NONE); + + IAxis xAxis = fSwtChart.getAxisSet().getXAxis(0); + IAxis yAxis = fSwtChart.getAxisSet().getYAxis(0); + + /* Set the title/labels, or hide them if they are not provided */ + if (title == null) { + fSwtChart.getTitle().setVisible(false); + } else { + fSwtChart.getTitle().setText(title); + } + if (xLabel == null) { + xAxis.getTitle().setVisible(false); + } else { + xAxis.getTitle().setText(xLabel); + } + if (yLabel == null) { + yAxis.getTitle().setVisible(false); + } else { + yAxis.getTitle().setText(yLabel); + } + + fMouseSelectionProvider = new TmfMouseSelectionProvider(this); + fMouseDragZoomProvider = new TmfMouseDragZoomProvider(this); + fMouseWheelZoomProvider = new TmfMouseWheelZoomProvider(this); + fToolTipProvider = new TmfSimpleTooltipProvider(this); + fMouseDragProvider = new TmfMouseDragProvider(this); + } + + // ------------------------------------------------------------------------ + // Getter/Setters + // ------------------------------------------------------------------------ + /** + * Sets the time offset to apply. + * @see ITmfChartTimeProvider#getTimeOffset() + * + * @param timeOffset + * The time offset to apply + */ + protected void setTimeOffset(long timeOffset) { + fTimeOffset = timeOffset; + } + + /** + * Sets the SWT Chart reference + * + * @param chart + * The SWT chart to set. + */ + protected void setSwtChart(Chart chart) { + fSwtChart = chart; + } + + /** + * Gets the SWT Chart reference + * + * @return the SWT chart to set. + */ + protected Chart getSwtChart() { + return fSwtChart; + } + + /** + * Sets a mouse selection provider. An existing provider will be + * disposed. Use null to disable the mouse selection provider. + * + * @param provider + * The selection provider to set + */ + public void setSelectionProvider(TmfBaseProvider provider) { + if (fMouseSelectionProvider != null) { + fMouseSelectionProvider.dispose(); + } + fMouseSelectionProvider = provider; + } + + /** + * Sets a mouse drag zoom provider. An existing provider will be + * disposed. Use null to disable the mouse drag zoom provider. + * + * @param provider + * The mouse drag zoom provider to set + */ + public void setMouseDragZoomProvider(TmfBaseProvider provider) { + if (fMouseDragZoomProvider != null) { + fMouseDragZoomProvider.dispose(); + } + fMouseDragZoomProvider = provider; + } + + /** + * Sets a mouse wheel zoom provider. An existing provider will be + * disposed. Use null to disable the mouse wheel zoom + * provider. + * + * @param provider + * The mouse wheel zoom provider to set + */ + public void setMouseWheelZoomProvider(TmfBaseProvider provider) { + if (fMouseWheelZoomProvider != null) { + fMouseWheelZoomProvider.dispose(); + } + fMouseWheelZoomProvider = provider; + } + + /** + * Sets a tooltip provider. An existing provider will be + * disposed. Use null to disable the tooltip provider. + * + * @param provider + * The tooltip provider to set + */ + public void setTooltipProvider(TmfBaseProvider provider) { + if (fToolTipProvider != null) { + fToolTipProvider.dispose(); + } + fToolTipProvider = provider; + } + + /** + * Sets a mouse drag provider. An existing provider will be + * disposed. Use null to disable the mouse drag provider. + * + * @param provider + * The mouse drag provider to set + */ + public void setMouseDrageProvider(TmfBaseProvider provider) { + if (fMouseDragProvider != null) { + fMouseDragProvider.dispose(); + } + fMouseDragProvider = provider; + } + + // ------------------------------------------------------------------------ + // ITmfChartTimeProvider + // ------------------------------------------------------------------------ + + @Override + public long getTimeOffset() { + return fTimeOffset; + } + + // ------------------------------------------------------------------------ + // ITmfViewer interface + // ------------------------------------------------------------------------ + @Override + public Control getControl() { + return fSwtChart; + } + + @Override + public void refresh() { + fSwtChart.redraw(); + } + + // ------------------------------------------------------------------------ + // TmfComponent + // ------------------------------------------------------------------------ + @Override + public void dispose() { + super.dispose(); + fSwtChart.dispose(); + + if (fMouseSelectionProvider != null) { + fMouseSelectionProvider.dispose(); + } + + if (fMouseDragZoomProvider != null) { + fMouseDragZoomProvider.dispose(); + } + + if (fMouseWheelZoomProvider != null) { + fMouseWheelZoomProvider.dispose(); + } + + if (fToolTipProvider != null) { + fToolTipProvider.dispose(); + } + + if (fMouseDragProvider != null) { + fMouseDragProvider.dispose(); + } + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + /** + * A Method to load a trace into the viewer. + * + * @param trace + * A trace to apply in the viewer + */ + @Override + public void loadTrace(ITmfTrace trace) { + super.loadTrace(trace); + clearContent(); + updateContent(); + } + + /** + * Resets the content of the viewer + */ + @Override + public void reset() { + super.reset(); + clearContent(); + } + + /** + * Method to implement to update the chart content. + */ + protected abstract void updateContent(); + + // ------------------------------------------------------------------------ + // Signal Handler + // ------------------------------------------------------------------------ + + /** + * Signal handler for handling of the time synch signal. + * + * @param signal + * The time synch signal {@link TmfTimeSynchSignal} + */ + @Override + @TmfSignalHandler + public void selectionRangeUpdated(TmfTimeSynchSignal signal) { + super.selectionRangeUpdated(signal); + if ((signal.getSource() != this) && (getTrace() != null)) { + if (fMouseSelectionProvider != null) { + fMouseSelectionProvider.refresh(); + } + } + } + + /** + * Signal handler for handling of the time range synch signal. + * + * @param signal + * The time range synch signal {@link TmfRangeSynchSignal} + */ + @Override + @TmfSignalHandler + public void timeRangeUpdated(TmfRangeSynchSignal signal) { + super.timeRangeUpdated(signal); + updateContent(); + } + + /** + * Signal handler for handling the signal that notifies about an updated + * timestamp format. + * + * @param signal + * The trace updated signal + * {@link TmfTimestampFormatUpdateSignal} + */ + @TmfSignalHandler + public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) { + fSwtChart.getAxisSet().adjustRange(); + fSwtChart.redraw(); + } + + // ------------------------------------------------------------------------ + // Helper Methods + // ------------------------------------------------------------------------ + + /** + * Clears the view content. + */ + protected void clearContent() { + if (!fSwtChart.isDisposed()) { + ISeriesSet set = fSwtChart.getSeriesSet(); + ISeries[] series = set.getSeries(); + for (int i = 0; i < series.length; i++) { + set.deleteSeries(series[i].getId()); + } + fSwtChart.redraw(); + } + } + + /** + * Returns the current or default display. + * + * @return the current or default display + */ + protected static Display getDisplay() { + Display display = Display.getCurrent(); + // may be null if outside the UI thread + if (display == null) { + display = Display.getDefault(); + } + return display; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/barcharts/TmfBarChartViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/barcharts/TmfBarChartViewer.java new file mode 100644 index 0000000000..574e2a1e09 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/barcharts/TmfBarChartViewer.java @@ -0,0 +1,220 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + * Bernd Hufmann - Updated for TMF base chart viewer + **********************************************************************/ +package org.eclipse.tracecompass.tmf.ui.viewers.xycharts.barcharts; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.TmfChartTimeStampFormat; +import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.TmfXYChartViewer; +import org.swtchart.Chart; +import org.swtchart.IAxisTick; +import org.swtchart.IBarSeries; +import org.swtchart.ISeries; +import org.swtchart.ISeries.SeriesType; + +/** + * Abstract bar chart viewer class implementation. Used for displaying + * histograms. + * + * @author Alexandre Montplaisir + * @author Bernd Hufmann + * @since 3.0 + */ +public abstract class TmfBarChartViewer extends TmfXYChartViewer { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** Width of each histogram bar, in pixels */ + public static final int MINIMUM_BAR_WIDTH = 1; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** List of series */ + private final List seriesNames = new ArrayList<>(); + /** List of colors */ + private final List colors = new ArrayList<>(); + /** the bar width */ + private int fBarWidth = MINIMUM_BAR_WIDTH; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Constructs a TmfXYChartViewer. + * + * @param parent + * The parent composite + * @param title + * The title of the viewer + * @param xLabel + * The label of the xAxis + * @param yLabel + * The label of the yAXIS + * @param barWidth + * The bar width + */ + public TmfBarChartViewer(Composite parent, String title, String xLabel, String yLabel, int barWidth) { + super(parent, title, xLabel, yLabel); + fBarWidth = barWidth; + + setTooltipProvider(new TmfHistogramTooltipProvider(this)); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + @Override + protected void updateContent() { + + getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + Chart swtChart = getSwtChart(); + int numRequests = swtChart.getPlotArea().getBounds().width / fBarWidth; + + for (int i = 0; i < seriesNames.size(); i++) { + ISeries series = swtChart.getSeriesSet().getSeries(seriesNames.get(i)); + if (series == null) { + series = initSeries(seriesNames.get(i), colors.get(i)); + } + readData(series, getWindowStartTime(), getWindowEndTime(), numRequests); + } + } + }); + } + + /** + * Method to add a series to the chart. + * + * @param name + * Name of series + * @param color + * color to use for series + */ + protected void addSeries(String name, RGB color) { + seriesNames.add(name); + colors.add(color); + } + + /** + * Clears all series + */ + protected void clearSeries() { + seriesNames.clear(); + colors.clear(); + } + + /** + * Draw the given series on the chart + * + * @param series + * The series to display + * @param x + * The X values. It can be computed with + * {@link TmfBarChartViewer#getXAxis} + * The values are stored in the internal time representation. + * To get the trace time one has to add the time offset + * {@link #getTimeOffset()}. + * @param y + * The Y values that were computed by the extended class + */ + protected void drawChart(final ISeries series, final double[] x, final double[] y) { + // Run in GUI thread to make sure that chart is ready after restart + final Display display = getDisplay(); + if (display.isDisposed()) { + return; + } + + display.syncExec(new Runnable() { + @Override + public void run() { + if (display.isDisposed()) { + return; + } + Chart swtChart = getSwtChart(); + IAxisTick xTick = swtChart.getAxisSet().getXAxis(0).getTick(); + xTick.setFormat(new TmfChartTimeStampFormat(getTimeOffset())); + series.setXSeries(x); + series.setYSeries(y); + xTick.setTickMarkStepHint(256); + + swtChart.getAxisSet().adjustRange(); + swtChart.redraw(); + } + }); + } + + /** + * Convenience method to compute the X axis values for a given time range. + * + * @param start + * Start of the time range + * @param end + * End of the range + * @param nb + * Number of steps. This will be the size of the returned array. + * @return The time values (converted to double) that match every step + */ + protected final double[] getXAxis(long start, long end, int nb) { + setTimeOffset(start - 1); + double timestamps[] = new double[nb]; + long steps = (end - start); + double step = steps / (double) nb; + + double curTime = 1; + for (int i = 0; i < nb; i++) { + timestamps[i] = curTime; + curTime += step; + } + return timestamps; + } + + /** + * Load the data for the given series. This method should call + * {@link TmfBarChartViewer#drawChart} to return the results when done. + * + * Careful, this method is called by a signal handler which also happens to + * be in the main UI thread. This means any processing will block the UI! In + * most cases it's probably better to start a separate Thread/Job to do the + * processing, and that one can call drawChart() when done to update the + * view. + * + * @param series + * Which series of the chart should the viewer update + * @param start + * The start time (in nanoseconds) of the range to display + * @param end + * The end time of the range to display. + * @param nb + * The number of 'steps' in the bar chart (fewer steps means each + * bar is wider). + */ + protected abstract void readData(ISeries series, long start, long end, int nb); + + // initializes a series + private IBarSeries initSeries(String name, RGB color) { + IBarSeries bs = (IBarSeries) getSwtChart().getSeriesSet().createSeries(SeriesType.BAR, name); + bs.enableStack(true); + bs.setBarColor(new Color(Display.getDefault(), color)); + bs.setBarPadding(0); + return bs; + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/barcharts/TmfHistogramTooltipProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/barcharts/TmfHistogramTooltipProvider.java new file mode 100644 index 0000000000..392df99964 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/barcharts/TmfHistogramTooltipProvider.java @@ -0,0 +1,179 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ +package org.eclipse.tracecompass.tmf.ui.viewers.xycharts.barcharts; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.ITmfChartTimeProvider; +import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.TmfBaseProvider; +import org.swtchart.IAxis; +import org.swtchart.ISeries; + +/** + * Tool tip provider for TMF bar chart viewer. It displays the y value of + * position x as well as it highlights the bar of the x position. + * It only considers the first series of the chart. + * + * @author Bernd Hufmann + * @since 3.0 + */ +public class TmfHistogramTooltipProvider extends TmfBaseProvider implements MouseTrackListener, MouseMoveListener, PaintListener { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** X coordinate for highlighting */ + private int fHighlightX; + /** y coordinate for highlighting */ + private int fHighlightY; + /** Flag to do highlighting or not */ + private boolean fIsHighlight; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Constructor for a tool tip provider. + * + * @param tmfChartViewer + * - the parent chart viewer + */ + public TmfHistogramTooltipProvider(ITmfChartTimeProvider tmfChartViewer) { + super(tmfChartViewer); + register(); + } + + // ------------------------------------------------------------------------ + // TmfBaseProvider + // ------------------------------------------------------------------------ + @Override + public void register() { + getChart().getPlotArea().addMouseTrackListener(this); + getChart().getPlotArea().addMouseMoveListener(this); + getChart().getPlotArea().addPaintListener(this); + } + + @Override + public void deregister() { + if ((getChartViewer().getControl() != null) && !getChartViewer().getControl().isDisposed()) { + getChart().getPlotArea().removeMouseTrackListener(this); + getChart().getPlotArea().removeMouseMoveListener(this); + getChart().getPlotArea().removePaintListener(this); + } + } + + @Override + public void refresh() { + // nothing to do + } + + // ------------------------------------------------------------------------ + // MouseTrackListener + // ------------------------------------------------------------------------ + @Override + public void mouseEnter(MouseEvent e) { + } + + @Override + public void mouseExit(MouseEvent e) { + } + + @Override + public void mouseHover(MouseEvent e) { + if (getChartViewer().getWindowDuration() != 0) { + IAxis xAxis = getChart().getAxisSet().getXAxis(0); + IAxis yAxis = getChart().getAxisSet().getYAxis(0); + + double xCoordinate = xAxis.getDataCoordinate(e.x); + + ISeries[] series = getChart().getSeriesSet().getSeries(); + + if ((xCoordinate < 0) || (series.length == 0)) { + return; + } + + double y = 0.0; + double rangeStart = 0.0; + double rangeEnd = 0.0; + + // Consider first series only + double[] xS = series[0].getXSeries(); + double[] yS = series[0].getYSeries(); + + if ((xS == null) || (yS == null)) { + return; + } + + for (int i = 0; i < xS.length - 1; i++) { + int pixel = xAxis.getPixelCoordinate(xS[i]); + if (pixel <= e.x) { + rangeStart = xS[i]; + rangeEnd = (long) xS[i + 1]; + if (xCoordinate >= rangeStart) { + y = yS[i + 1]; + } else { + y = yS[i]; + } + } + } + + ITmfChartTimeProvider viewer = getChartViewer(); + + /* set tooltip of closest data point */ + StringBuffer buffer = new StringBuffer(); + buffer.append("Range=["); //$NON-NLS-1$ + buffer.append(new TmfTimestamp((long) rangeStart + viewer.getTimeOffset(), ITmfTimestamp.NANOSECOND_SCALE).toString()); + buffer.append(','); + buffer.append(new TmfTimestamp((long) rangeEnd + viewer.getTimeOffset(), ITmfTimestamp.NANOSECOND_SCALE).toString()); + buffer.append("]\n"); //$NON-NLS-1$ + buffer.append("y="); //$NON-NLS-1$ + buffer.append((long) y); + getChart().getPlotArea().setToolTipText(buffer.toString()); + + fHighlightX = e.x; + fHighlightY = yAxis.getPixelCoordinate(y); + fIsHighlight = true; + getChart().redraw(); + } + } + + // ------------------------------------------------------------------------ + // MouseMoveListener + // ------------------------------------------------------------------------ + @Override + public void mouseMove(MouseEvent e) { + fIsHighlight = false; + getChart().redraw(); + } + + // ------------------------------------------------------------------------ + // PaintListener + // ------------------------------------------------------------------------ + @Override + public void paintControl(PaintEvent e) { + if (fIsHighlight) { + e.gc.setBackground(Display.getDefault().getSystemColor( + SWT.COLOR_RED)); + e.gc.setAlpha(128); + + e.gc.fillOval(fHighlightX - 5, fHighlightY - 5, 10, 10); + } + } + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/linecharts/TmfCommonXLineChartTooltipProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/linecharts/TmfCommonXLineChartTooltipProvider.java new file mode 100644 index 0000000000..c303753af1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/linecharts/TmfCommonXLineChartTooltipProvider.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.xycharts.linecharts; + +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.ITmfChartTimeProvider; +import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.TmfBaseProvider; +import org.swtchart.IAxis; +import org.swtchart.ISeries; + +/** + * Displays a tooltip on line charts. For each series, it shows the y value at + * the selected x value. This tooltip assumes that all series share a common set + * of X axis values. If the X series is not common, the tooltip text may not be + * accurate. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfCommonXLineChartTooltipProvider extends TmfBaseProvider implements MouseTrackListener { + + /** + * Constructor for the tooltip provider + * + * @param tmfChartViewer + * The parent chart viewer + */ + public TmfCommonXLineChartTooltipProvider(ITmfChartTimeProvider tmfChartViewer) { + super(tmfChartViewer); + register(); + } + + // ------------------------------------------------------------------------ + // TmfBaseProvider + // ------------------------------------------------------------------------ + + @Override + public void register() { + getChart().getPlotArea().addMouseTrackListener(this); + } + + @Override + public void deregister() { + if ((getChartViewer().getControl() != null) && !getChartViewer().getControl().isDisposed()) { + getChart().getPlotArea().removeMouseTrackListener(this); + } + } + + @Override + public void refresh() { + // nothing to do + } + + // ------------------------------------------------------------------------ + // MouseTrackListener + // ------------------------------------------------------------------------ + + @Override + public void mouseEnter(MouseEvent e) { + } + + @Override + public void mouseExit(MouseEvent e) { + } + + @Override + public void mouseHover(MouseEvent e) { + if (getChartViewer().getWindowDuration() != 0) { + IAxis xAxis = getChart().getAxisSet().getXAxis(0); + + double xCoordinate = xAxis.getDataCoordinate(e.x); + + ISeries[] series = getChart().getSeriesSet().getSeries(); + + if ((xCoordinate < 0) || (series.length == 0)) { + return; + } + + /* Find the index of the value we want */ + double[] xS = series[0].getXSeries(); + if (xS == null) { + return; + } + int index = 0; + for (int i = 0; i < xS.length; i++) { + if (xS[i] > xCoordinate) { + break; + } + index = i; + } + + /* set tooltip of closest data point */ + StringBuffer buffer = new StringBuffer(); + buffer.append("time="); //$NON-NLS-1$ + buffer.append(new TmfTimestamp((long) xCoordinate + getChartViewer().getTimeOffset(), ITmfTimestamp.NANOSECOND_SCALE).toString()); + buffer.append('\n'); + + /* For each series, get the value at the index */ + for (ISeries serie : series) { + double[] yS = serie.getYSeries(); + /* Make sure the series values and the value at index exist */ + if (yS == null || yS.length <= index) { + continue; + } + buffer.append(serie.getId()); + buffer.append('='); + buffer.append(yS[index]); + buffer.append('\n'); + } + + getChart().getPlotArea().setToolTipText(buffer.toString()); + getChart().redraw(); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/linecharts/TmfCommonXLineChartViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/linecharts/TmfCommonXLineChartViewer.java new file mode 100644 index 0000000000..af5bac3396 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/linecharts/TmfCommonXLineChartViewer.java @@ -0,0 +1,374 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.viewers.xycharts.linecharts; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.TmfUiRefreshHandler; +import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.TmfChartTimeStampFormat; +import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.TmfXYChartViewer; +import org.swtchart.IAxisTick; +import org.swtchart.ILineSeries; +import org.swtchart.ILineSeries.PlotSymbolType; +import org.swtchart.ISeries; +import org.swtchart.ISeries.SeriesType; +import org.swtchart.ISeriesSet; +import org.swtchart.LineStyle; +import org.swtchart.Range; + +/** + * Abstract line chart viewer class implementation. All series in this viewer + * use the same X axis values. They are automatically created as values are + * provided for a key. Series by default will be displayed as a line. Each + * series appearance can be overridden when creating it. + * + * @author - Geneviève Bastien + * @since 3.0 + */ +public abstract class TmfCommonXLineChartViewer extends TmfXYChartViewer { + + private static final double DEFAULT_MAXY = Double.MIN_VALUE; + private static final double DEFAULT_MINY = Double.MAX_VALUE; + + /* The desired number of points per pixel */ + private static final double RESOLUTION = 1.0; + + private static final int[] LINE_COLORS = { SWT.COLOR_BLUE, SWT.COLOR_RED, SWT.COLOR_GREEN, + SWT.COLOR_MAGENTA, SWT.COLOR_CYAN, + SWT.COLOR_DARK_BLUE, SWT.COLOR_DARK_RED, SWT.COLOR_DARK_GREEN, + SWT.COLOR_DARK_MAGENTA, SWT.COLOR_DARK_CYAN, SWT.COLOR_DARK_YELLOW, + SWT.COLOR_BLACK, SWT.COLOR_GRAY }; + private static final LineStyle[] LINE_STYLES = { LineStyle.SOLID, LineStyle.DASH, LineStyle.DOT, LineStyle.DASHDOT }; + + private final Map fSeriesValues = new LinkedHashMap<>(); + private double[] fXValues; + private double fResolution; + + private UpdateThread fUpdateThread; + + /** + * Constructor + * + * @param parent + * The parent composite + * @param title + * The title of the viewer + * @param xLabel + * The label of the xAxis + * @param yLabel + * The label of the yAXIS + */ + public TmfCommonXLineChartViewer(Composite parent, String title, String xLabel, String yLabel) { + super(parent, title, xLabel, yLabel); + + setResolution(RESOLUTION); + setTooltipProvider(new TmfCommonXLineChartTooltipProvider(this)); + } + + /** + * Set the number of requests per pixel that should be done on this chart + * + * @param resolution + * The number of points per pixels + */ + protected void setResolution(double resolution) { + fResolution = resolution; + } + + @Override + public void loadTrace(ITmfTrace trace) { + super.loadTrace(trace); + reinitialize(); + } + + /** + * Forces a reinitialization of the data sources, even if it has already + * been initialized for this trace before + * + * @since 3.1 + */ + protected void reinitialize() { + fSeriesValues.clear(); + Thread thread = new Thread() { + @Override + public void run() { + initializeDataSource(); + TmfUiRefreshHandler.getInstance().queueUpdate(TmfCommonXLineChartViewer.this, + new Runnable() { + @Override + public void run() { + if (!getSwtChart().isDisposed()) { + /* Delete the old series */ + clearContent(); + createSeries(); + } + } + }); + } + }; + thread.start(); + } + + /** + * Initialize the source of the data for this viewer. This method is run in + * a separate thread, so this is where for example one can execute an + * analysis module and wait for its completion to initialize the series + */ + protected void initializeDataSource() { + + } + + private class UpdateThread extends Thread { + private final IProgressMonitor fMonitor; + private final int fNumRequests; + + public UpdateThread(int numRequests) { + super("Line chart update"); //$NON-NLS-1$ + fNumRequests = numRequests; + fMonitor = new NullProgressMonitor(); + } + + @Override + public void run() { + updateData(getWindowStartTime(), getWindowEndTime(), fNumRequests, fMonitor); + updateThreadFinished(this); + } + + public void cancel() { + fMonitor.setCanceled(true); + } + } + + private synchronized void newUpdateThread() { + cancelUpdate(); + final int numRequests = (int) (getSwtChart().getPlotArea().getBounds().width * fResolution); + fUpdateThread = new UpdateThread(numRequests); + fUpdateThread.start(); + } + + private synchronized void updateThreadFinished(UpdateThread thread) { + if (thread == fUpdateThread) { + fUpdateThread = null; + } + } + + /** + * Cancels the currently running update thread. It is automatically called + * when the content is updated, but child viewers may want to call it + * manually to do some operations before calling + * {@link TmfCommonXLineChartViewer#updateContent} + */ + protected synchronized void cancelUpdate() { + if (fUpdateThread != null) { + fUpdateThread.cancel(); + } + } + + @Override + protected void updateContent() { + getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + newUpdateThread(); + } + }); + } + + /** + * Convenience method to compute the values of the X axis for a given time + * range. This method will return nb values depending, equally separated + * from start to end. + * + * The returned time values are in internal time, ie to get trace time, the + * time offset needs to be added to those values. + * + * @param start + * The start time of the time range + * @param end + * End time of the range + * @param nb + * The number of steps in the x axis. + * @return The time values (converted to double) to match every step. + */ + protected final double[] getXAxis(long start, long end, int nb) { + setTimeOffset(start - 1); + + double timestamps[] = new double[nb]; + long steps = (end - start); + double step = steps / (double) nb; + + double curTime = 1; + for (int i = 0; i < nb; i++) { + timestamps[i] = curTime; + curTime += step; + } + return timestamps; + } + + /** + * Set the values of the x axis. There is only one array of values for the x + * axis for all series of a line chart so it needs to be set once here. + * + * @param xaxis + * The values for the x axis. The values must be in internal + * time, ie time offset have been subtracted from trace time + * values. + */ + protected final void setXAxis(double[] xaxis) { + fXValues = xaxis; + } + + /** + * Update the series data because the time range has changed. The x axis + * values for this data update can be computed using the + * {@link TmfCommonXLineChartViewer#getXAxis(long, long, int)} method which + * will return a list of uniformely separated time values. + * + * Each series values should be set by calling the + * {@link TmfCommonXLineChartViewer#setSeries(String, double[])}. + * + * This method is responsible for calling the + * {@link TmfCommonXLineChartViewer#updateDisplay()} when needed for the new + * values to be displayed. + * + * @param start + * The start time of the range for which the get the data + * @param end + * The end time of the range + * @param nb + * The number of 'points' in the chart. + * @param monitor + * The progress monitor object + */ + protected abstract void updateData(long start, long end, int nb, IProgressMonitor monitor); + + /** + * Set the data for a given series of the graph. The series does not need to + * be created before calling this, but it needs to have at least as many + * values as the x axis. + * + * If the series does not exist, it will automatically be created at display + * time, with the default values. + * + * @param seriesName + * The name of the series for which to set the values + * @param seriesValues + * The array of values for the series + */ + protected void setSeries(String seriesName, double[] seriesValues) { + if (fXValues.length > seriesValues.length) { + throw new IllegalStateException(); + } + fSeriesValues.put(seriesName, seriesValues); + } + + /** + * Add a new series to the XY line chart. By default, it is a simple solid + * line. + * + * @param seriesName + * The name of the series to create + * @return The series so that the concrete viewer can modify its properties + * if required + */ + protected ILineSeries addSeries(String seriesName) { + ISeriesSet seriesSet = getSwtChart().getSeriesSet(); + int seriesCount = seriesSet.getSeries().length; + ILineSeries series = (ILineSeries) seriesSet.createSeries(SeriesType.LINE, seriesName); + series.setVisible(true); + series.enableArea(false); + series.setLineStyle(LINE_STYLES[(seriesCount / (LINE_COLORS.length)) % LINE_STYLES.length]); + series.setSymbolType(PlotSymbolType.NONE); + series.setLineColor(Display.getDefault().getSystemColor(LINE_COLORS[seriesCount % LINE_COLORS.length])); + return series; + } + + /** + * Delete a series from the chart and its values from the viewer. + * + * @param seriesName + * Name of the series to delete + */ + protected void deleteSeries(String seriesName) { + ISeries series = getSwtChart().getSeriesSet().getSeries(seriesName); + if (series != null) { + getSwtChart().getSeriesSet().deleteSeries(series.getId()); + } + fSeriesValues.remove(seriesName); + } + + /** + * Update the chart's values before refreshing the viewer + */ + protected void updateDisplay() { + Display.getDefault().asyncExec(new Runnable() { + final TmfChartTimeStampFormat tmfChartTimeStampFormat = new TmfChartTimeStampFormat(getTimeOffset()); + + @Override + public void run() { + if (!getSwtChart().isDisposed()) { + double maxy = DEFAULT_MAXY; + double miny = DEFAULT_MINY; + for (Entry entry : fSeriesValues.entrySet()) { + ILineSeries series = (ILineSeries) getSwtChart().getSeriesSet().getSeries(entry.getKey()); + if (series == null) { + series = addSeries(entry.getKey()); + } + series.setXSeries(fXValues); + /* Find the minimal and maximum values in this series */ + for (double value : entry.getValue()) { + maxy = Math.max(maxy, value); + miny = Math.min(miny, value); + } + series.setYSeries(entry.getValue()); + } + if (maxy == DEFAULT_MAXY) { + maxy = 1.0; + } + + IAxisTick xTick = getSwtChart().getAxisSet().getXAxis(0).getTick(); + xTick.setFormat(tmfChartTimeStampFormat); + + final double start = fXValues[0]; + int lastX = fXValues.length - 1; + double end = (start == fXValues[lastX]) ? start + 1 : fXValues[lastX]; + getSwtChart().getAxisSet().getXAxis(0).setRange(new Range(start, end)); + getSwtChart().getAxisSet().getXAxis(0).adjustRange(); + if (maxy > miny) { + getSwtChart().getAxisSet().getYAxis(0).setRange(new Range(miny, maxy)); + } + getSwtChart().redraw(); + } + } + }); + } + + /** + * Create the series once the initialization of the viewer's data source is + * done. Series do not need to be created before setting their values, but + * if their appearance needs to be customized, this method is a good place + * to do so. It is called only once per trace. + */ + protected void createSeries() { + + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/PinTmfViewAction.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/PinTmfViewAction.java new file mode 100644 index 0000000000..4eb11629b7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/PinTmfViewAction.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ui.views; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; + +/** + * + * @version 1.0 + * @author Bernd Hufmann + * @since 2.0 + */ +public class PinTmfViewAction extends Action { + /** + * Creates a new PinPropertySheetAction. + */ + public PinTmfViewAction() { + super(Messages.TmfView_PinActionNameText, IAction.AS_CHECK_BOX); + + setId("org.eclipse.linuxtools.tmf.ui.views.PinTmfViewAction"); //$NON-NLS-1$ + setToolTipText(Messages.TmfView_PinActionToolTipText); + setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PIN_VIEW)); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/TmfChartView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/TmfChartView.java new file mode 100644 index 0000000000..99c692fb87 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/TmfChartView.java @@ -0,0 +1,118 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ +package org.eclipse.tracecompass.tmf.ui.views; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.TmfXYChartViewer; + +/** + * Base class to be used with a chart viewer {@link TmfXYChartViewer}. + * It is responsible to instantiate the viewer class and load the trace + * into the viewer when the view is created. + * + * @author Bernd Hufmann + * @since 3.0 + */ +abstract public class TmfChartView extends TmfView { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** The TMF XY Chart reference */ + private TmfXYChartViewer fChartViewer; + /** The Trace reference */ + private ITmfTrace fTrace; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Standard Constructor + * + * @param viewName + * The view name + */ + public TmfChartView(String viewName) { + super(viewName); + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + /** + * Returns the TMF XY chart viewer implementation. + * + * @return the TMF XY chart viewer {@link TmfXYChartViewer} + */ + protected TmfXYChartViewer getChartViewer() { + return fChartViewer; + } + + /** + * Sets the TMF XY chart viewer implementation. + * + * @param chartViewer + * The TMF XY chart viewer {@link TmfXYChartViewer} + */ + protected void setChartViewer(TmfXYChartViewer chartViewer) { + fChartViewer = chartViewer; + } + + /** + * Returns the ITmfTrace implementation + * + * @return the ITmfTrace implementation {@link ITmfTrace} + */ + protected ITmfTrace getTrace() { + return fTrace; + } + + /** + * Sets the ITmfTrace implementation + * + * @param trace + * The ITmfTrace implementation {@link ITmfTrace} + */ + protected void setTrace(ITmfTrace trace) { + fTrace = trace; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + @Override + public void createPartControl(Composite parent) { + ITmfTrace trace = getActiveTrace(); + if (trace != null) { + setTrace(trace); + loadTrace(); + } + } + + @Override + public void dispose() { + if (fChartViewer != null) { + fChartViewer.dispose(); + } + } + + /** + * Load the trace into view. + */ + protected void loadTrace() { + if (fChartViewer != null) { + fChartViewer.loadTrace(fTrace); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/TmfView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/TmfView.java new file mode 100644 index 0000000000..cc874e32f9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/TmfView.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Added possibility to pin view + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views; + +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.tracecompass.tmf.core.component.ITmfComponent; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ui.editors.ITmfTraceEditor; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.part.ViewPart; + +/** + * Basic abstract TMF view class implementation. + * + * It registers any sub class to the signal manager for receiving and sending + * TMF signals. + * + * @version 1.2 + * @author Francois Chouinard + */ +public abstract class TmfView extends ViewPart implements ITmfComponent { + + private final String fName; + + /** + * Action class for pinning of TmfView. + * @since 2.0 + */ + protected PinTmfViewAction fPinAction; + + /** + * Reference to the trace manager + * @since 2.0 + */ + protected final TmfTraceManager fTraceManager; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Constructor. Creates a TMF view and registers to the signal manager. + * + * @param viewName + * A view name + */ + public TmfView(String viewName) { + super(); + fName = viewName; + fTraceManager = TmfTraceManager.getInstance(); + TmfSignalManager.register(this); + } + + /** + * Disposes this view and de-registers itself from the signal manager + */ + @Override + public void dispose() { + TmfSignalManager.deregister(this); + super.dispose(); + } + + // ------------------------------------------------------------------------ + // ITmfComponent + // ------------------------------------------------------------------------ + + @Override + public String getName() { + return fName; + } + + @Override + public void broadcast(TmfSignal signal) { + TmfSignalManager.dispatchSignal(signal); + } + + /** + * @since 3.0 + */ + @Override + public void broadcastAsync(TmfSignal signal) { + TmfSignalManager.dispatchSignalAsync(signal); + } + + // ------------------------------------------------------------------------ + // View pinning support + // ------------------------------------------------------------------------ + + /** + * Returns whether the pin flag is set. + * For example, this flag can be used to ignore time synchronization signals from other TmfViews. + * + * @return pin flag + * @since 2.0 + */ + public boolean isPinned() { + return ((fPinAction != null) && (fPinAction.isChecked())); + } + + /** + * Method adds a pin action to the TmfView. The pin action allows to toggle the fIsPinned flag. + * For example, this flag can be used to ignore time synchronization signals from other TmfViews. + * + * @since 2.0 + */ + protected void contributePinActionToToolBar() { + if (fPinAction == null) { + fPinAction = new PinTmfViewAction(); + + IToolBarManager toolBarManager = getViewSite().getActionBars() + .getToolBarManager(); + toolBarManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + toolBarManager.add(fPinAction); + } + } + + /** + * Get the currently selected trace, or 'null' if the active editor is not a + * TMF trace. + * + * @return The active trace, or 'null' if not a trace + * @since 2.0 + */ + public ITmfTrace getActiveTrace() { + IEditorPart editor = getSite().getPage().getActiveEditor(); + if (editor instanceof ITmfTraceEditor) { + ITmfTrace trace = ((ITmfTraceEditor) editor).getTrace(); + return trace; + } + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/TracingPerspectiveFactory.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/TracingPerspectiveFactory.java new file mode 100644 index 0000000000..2cc89f70f5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/TracingPerspectiveFactory.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views; + +import org.eclipse.tracecompass.tmf.ui.project.wizards.NewTmfProjectWizard; +import org.eclipse.tracecompass.tmf.ui.views.histogram.HistogramView; +import org.eclipse.tracecompass.tmf.ui.views.statistics.TmfStatisticsView; +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +/** + * The tracing perspective definition. + * + * @version 1.0 + * @author Francois Chouinard + */ +public class TracingPerspectiveFactory implements IPerspectiveFactory { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** The Perspective ID */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.perspective"; //$NON-NLS-1$ + + // Standard TMF views + private static final String HISTOGRAM_VIEW_ID = HistogramView.ID; + + // Standard Eclipse views + private static final String PROJECT_VIEW_ID = IPageLayout.ID_PROJECT_EXPLORER; + private static final String STATISTICS_VIEW_ID = TmfStatisticsView.ID; + private static final String PROPERTIES_VIEW_ID = IPageLayout.ID_PROP_SHEET; + private static final String BOOKMARKS_VIEW_ID = IPageLayout.ID_BOOKMARKS; + + + // ------------------------------------------------------------------------ + // IPerspectiveFactory + // ------------------------------------------------------------------------ + + @Override + public void createInitialLayout(IPageLayout layout) { + + // Editor area + layout.setEditorAreaVisible(true); + + // Create the top left folder + IFolderLayout topLeftFolder = layout.createFolder( + "topLeftFolder", IPageLayout.LEFT, 0.15f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$ + topLeftFolder.addView(PROJECT_VIEW_ID); + + // Create the middle right folder + IFolderLayout middleRightFolder = layout.createFolder( + "middleRightFolder", IPageLayout.BOTTOM, 0.50f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$ + middleRightFolder.addView(STATISTICS_VIEW_ID); + + // Create the bottom right folder + IFolderLayout bottomRightFolder = layout.createFolder( + "bottomRightFolder", IPageLayout.BOTTOM, 0.55f, "middleRightFolder"); //$NON-NLS-1$ //$NON-NLS-2$ + bottomRightFolder.addView(HISTOGRAM_VIEW_ID); + bottomRightFolder.addView(PROPERTIES_VIEW_ID); + bottomRightFolder.addView(BOOKMARKS_VIEW_ID); + + // Populate menus, etc + layout.addPerspectiveShortcut(ID); + layout.addNewWizardShortcut(NewTmfProjectWizard.ID); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/AbstractCallStackAnalysis.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/AbstractCallStackAnalysis.java new file mode 100644 index 0000000000..7ccc51977d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/AbstractCallStackAnalysis.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + * Patrick Tasse - Add methods to get attribute paths + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.callstack; + +import org.eclipse.tracecompass.tmf.core.callstack.CallStackStateProvider; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.ui.analysis.TmfAnalysisViewOutput; + +/** + * The base classes for analyses who want to populate the CallStack View. + * + * @author Alexandre Montplaisir + * @since 3.0 + */ +public abstract class AbstractCallStackAnalysis extends TmfStateSystemAnalysisModule { + + private static final String[] DEFAULT_THREADS_PATTERN = + new String[] { CallStackStateProvider.THREADS, "*" }; //$NON-NLS-1$; + + private static final String[] DEFAULT_CALL_STACK_PATH = + new String[] { CallStackStateProvider.CALL_STACK }; + + /** + * Abstract constructor (should only be called via the sub-classes' + * constructors. + */ + public AbstractCallStackAnalysis() { + super(); + registerOutput(new TmfAnalysisViewOutput(CallStackView.ID)); + } + + /** + * Get the pattern of thread attributes. Override this method if the state + * system attributes do not match the default pattern defined by + * {@link CallStackStateProvider}. + * + * @return the absolute pattern of the thread attributes + * @since 3.1 + */ + public String[] getThreadsPattern() { + return DEFAULT_THREADS_PATTERN; + } + + /** + * Get the call stack attribute path relative to a thread attribute found by + * {@link #getThreadsPattern()}. Override this method if the state system + * attributes do not match the default pattern defined by + * {@link CallStackStateProvider}. + * + * @return the relative path of the call stack attribute + * @since 3.1 + */ + public String[] getCallStackPath() { + return DEFAULT_CALL_STACK_PATH; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackEntry.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackEntry.java new file mode 100644 index 0000000000..31c831527b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackEntry.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.callstack; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry; + +/** + * An entry, or row, in the Call Stack view + * + * @author Patrick Tasse + * @since 2.0 + */ +public class CallStackEntry extends TimeGraphEntry { + + private final int fQuark; + private final int fStackLevel; + private final ITmfTrace fTrace; + private String fFunctionName; + private long fFunctionEntryTime; + private long fFunctionExitTime; + private @NonNull ITmfStateSystem fSS; + + /** + * Standard constructor + * + * @param quark + * The call stack quark + * @param stackLevel + * The stack level + * @param trace + * The trace that this view is talking about + * @deprecated Use {@link #CallStackEntry(String, int, int, ITmfTrace, ITmfStateSystem)} + */ + @Deprecated + public CallStackEntry(int quark, int stackLevel, ITmfTrace trace) { + super(null, 0, 0); + throw new UnsupportedOperationException(); + } + + /** + * Standard constructor + * + * @param name + * The parent thread name + * @param quark + * The call stack quark + * @param stackLevel + * The stack level + * @param trace + * The trace that this view is talking about + * @param ss + * The call stack state system + * @since 3.1 + */ + public CallStackEntry(String name, int quark, int stackLevel, ITmfTrace trace, @NonNull ITmfStateSystem ss) { + super(name, 0, 0); + fQuark = quark; + fStackLevel = stackLevel; + fTrace = trace; + fFunctionName = ""; //$NON-NLS-1$ + fSS = ss; + } + + /** + * Get the function name of the call stack entry + * @return the function name + */ + public String getFunctionName() { + return fFunctionName; + } + + /** + * Set the function name of the call stack entry + * @param functionName the function name + */ + public void setFunctionName(String functionName) { + fFunctionName = functionName; + } + + /** + * Set the start time of the call stack entry + * @param startTime the start time + * @deprecated Use {@link #setFunctionEntryTime(long)} + */ + @Deprecated + public void setStartTime(long startTime) { + throw new UnsupportedOperationException(); + } + + /** + * Set the end time of the call stack entry + * @param endTime the end time + * @deprecated Use {@link #setFunctionExitTime(long)} + */ + @Deprecated + public void setEndTime(long endTime) { + throw new UnsupportedOperationException(); + } + + /** + * Set the selected function entry time + * + * @param entryTime + * the function entry time + * @since 3.1 + */ + public void setFunctionEntryTime(long entryTime) { + fFunctionEntryTime = entryTime; + } + + /** + * Get the selected function entry time + * + * @return the function entry time + * @since 3.1 + */ + public long getFunctionEntryTime() { + return fFunctionEntryTime; + } + + /** + * Set the selected function exit time + * + * @param exitTime + * the function exit time + * @since 3.1 + */ + public void setFunctionExitTime(long exitTime) { + fFunctionExitTime = exitTime; + } + + /** + * Get the selected function exit time + * + * @return the function exit time + * @since 3.1 + */ + public long getFunctionExitTime() { + return fFunctionExitTime; + } + + /** + * Retrieve the attribute quark that's represented by this entry. + * + * @return The integer quark + */ + public int getQuark() { + return fQuark; + } + + /** + * Retrieve the stack level associated with this entry. + * + * @return The stack level or 0 + */ + public int getStackLevel() { + return fStackLevel; + } + + /** + * Retrieve the trace that is associated to this view. + * + * @return The trace + */ + public ITmfTrace getTrace() { + return fTrace; + } + + /** + * Retrieve the call stack state system associated with this entry. + * + * @return The call stack state system + * @since 3.1 + */ + public @NonNull ITmfStateSystem getStateSystem() { + return fSS; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackEvent.java new file mode 100644 index 0000000000..05fc4ae20f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackEvent.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.callstack; + +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent; + +/** + * Time Event implementation specific to the Call Stack View + * + * @author Patrick Tasse + * @since 2.0 + */ +public class CallStackEvent extends TimeEvent { + + /** + * Standard constructor + * + * @param entry + * The entry that this event affects + * @param time + * The start time of the event + * @param duration + * The duration of the event + * @param value + * The event value (1-256) + */ + public CallStackEvent(CallStackEntry entry, long time, long duration, int value) { + super(entry, time, duration, value); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackPresentationProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackPresentationProvider.java new file mode 100644 index 0000000000..e23e399652 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackPresentationProvider.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.callstack; + +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.StateItem; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.NullTimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils; + +/** + * Presentation provider for the Call Stack view, based on the generic TMF + * presentation provider. + * + * @author Patrick Tasse + * @since 2.0 + */ +public class CallStackPresentationProvider extends TimeGraphPresentationProvider { + + /** Number of colors used for call stack events */ + public static final int NUM_COLORS = 360; + + private final CallStackView fView; + + private Integer fAverageCharWidth; + + private enum State { + MULTIPLE (new RGB(100, 100, 100)), + EXEC (new RGB(0, 200, 0)); + + private final RGB rgb; + + private State (RGB rgb) { + this.rgb = rgb; + } + } + + /** + * Constructor + * + * @param view + * The callstack view that will contain the time events + * @since 3.0 + */ + public CallStackPresentationProvider(CallStackView view) { + fView = view; + } + + @Override + public String getStateTypeName(ITimeGraphEntry entry) { + return Messages.CallStackPresentationProvider_Thread; + } + + @Override + public StateItem[] getStateTable() { + final float saturation = 0.6f; + final float brightness = 0.6f; + StateItem[] stateTable = new StateItem[NUM_COLORS + 1]; + stateTable[0] = new StateItem(State.MULTIPLE.rgb, State.MULTIPLE.toString()); + for (int i = 0; i < NUM_COLORS; i++) { + RGB rgb = new RGB(i, saturation, brightness); + stateTable[i + 1] = new StateItem(rgb, State.EXEC.toString()); + } + return stateTable; + } + + @Override + public int getStateTableIndex(ITimeEvent event) { + if (event instanceof CallStackEvent) { + CallStackEvent callStackEvent = (CallStackEvent) event; + return callStackEvent.getValue() + 1; + } else if (event instanceof NullTimeEvent) { + return INVISIBLE; + } + return State.MULTIPLE.ordinal(); + } + + @Override + public String getEventName(ITimeEvent event) { + if (event instanceof CallStackEvent) { + CallStackEntry entry = (CallStackEntry) event.getEntry(); + ITmfStateSystem ss = entry.getStateSystem(); + try { + ITmfStateValue value = ss.querySingleState(event.getTime(), entry.getQuark()).getStateValue(); + if (!value.isNull()) { + String address = value.toString(); + return fView.getFunctionName(address); + } + } catch (AttributeNotFoundException e) { + Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ + } catch (TimeRangeException e) { + Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ + } catch (StateSystemDisposedException e) { + /* Ignored */ + } + return null; + } + return State.MULTIPLE.toString(); + } + + @Override + public void postDrawEvent(ITimeEvent event, Rectangle bounds, GC gc) { + if (fAverageCharWidth == null) { + fAverageCharWidth = gc.getFontMetrics().getAverageCharWidth(); + } + if (bounds.width <= fAverageCharWidth) { + return; + } + if (!(event instanceof CallStackEvent)) { + return; + } + CallStackEntry entry = (CallStackEntry) event.getEntry(); + ITmfStateSystem ss = entry.getStateSystem(); + try { + ITmfStateValue value = ss.querySingleState(event.getTime(), entry.getQuark()).getStateValue(); + if (!value.isNull()) { + String address = value.toString(); + String name = fView.getFunctionName(address); + gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE)); + Utils.drawText(gc, name, bounds.x, bounds.y - 2, bounds.width, true, true); + } + } catch (AttributeNotFoundException e) { + Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ + } catch (TimeRangeException e) { + Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ + } catch (StateSystemDisposedException e) { + /* Ignored */ + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackView.java new file mode 100644 index 0000000000..58be6c2a22 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackView.java @@ -0,0 +1,1569 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Bernd Hufmann - Updated signal handling + * Marc-Andre Laperle - Map from binary file + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.callstack; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.core.signal.TmfRangeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampDelta; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ui.editors.ITmfTraceEditor; +import org.eclipse.tracecompass.tmf.ui.views.TmfView; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphContentProvider; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphRangeListener; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphTimeListener; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphCombo; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphTimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphViewer; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.NullTimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphSelection; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IEditorPart; + +/** + * Main implementation for the Call Stack view + * + * @author Patrick Tasse + * @since 2.0 + */ +public class CallStackView extends TmfView { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** View ID. */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.callstack"; //$NON-NLS-1$ + + /** + * Redraw state enum + */ + private enum State { + IDLE, BUSY, PENDING + } + + private static final String[] COLUMN_TIMES = new String[] { + Messages.CallStackView_FunctionColumn, + Messages.CallStackView_DepthColumn, + Messages.CallStackView_EntryTimeColumn, + Messages.CallStackView_ExitTimeColumn, + Messages.CallStackView_DurationColumn + }; + + private static final int[] COLUMN_WIDTHS = new int[] { + 200, + 50, + 120, + 120, + 120 + }; + + /** Timeout between updates in the build thread in ms */ + private static final long BUILD_UPDATE_TIMEOUT = 500; + + // Fraction of a function duration to be added as spacing + private static final double SPACING_RATIO = 0.01; + + private static final Image THREAD_IMAGE = Activator.getDefault().getImageFromPath("icons/obj16/thread_obj.gif"); //$NON-NLS-1$ + private static final Image STACKFRAME_IMAGE = Activator.getDefault().getImageFromPath("icons/obj16/stckframe_obj.gif"); //$NON-NLS-1$ + + private static final String IMPORT_MAPPING_ICON_PATH = "icons/etool16/import.gif"; //$NON-NLS-1$ + private static final String IMPORT_BINARY_ICON_PATH = "icons/obj16/binaries_obj.gif"; //$NON-NLS-1$ + + private static final ImageDescriptor SORT_BY_NAME_ICON = Activator.getDefault().getImageDescripterFromPath("icons/etool16/sort_alpha.gif"); //$NON-NLS-1$ + private static final ImageDescriptor SORT_BY_NAME_REV_ICON = Activator.getDefault().getImageDescripterFromPath("icons/etool16/sort_alpha_rev.gif"); //$NON-NLS-1$ + private static final ImageDescriptor SORT_BY_ID_ICON = Activator.getDefault().getImageDescripterFromPath("icons/etool16/sort_num.gif"); //$NON-NLS-1$ + private static final ImageDescriptor SORT_BY_ID_REV_ICON = Activator.getDefault().getImageDescripterFromPath("icons/etool16/sort_num_rev.gif"); //$NON-NLS-1$ + private static final ImageDescriptor SORT_BY_TIME_ICON = Activator.getDefault().getImageDescripterFromPath("icons/etool16/sort_time.gif"); //$NON-NLS-1$ + private static final ImageDescriptor SORT_BY_TIME_REV_ICON = Activator.getDefault().getImageDescripterFromPath("icons/etool16/sort_time_rev.gif"); //$NON-NLS-1$ + private static final String SORT_OPTION_KEY = "sort.option"; //$NON-NLS-1$ + + private enum SortOption { + BY_NAME, BY_NAME_REV, BY_ID, BY_ID_REV, BY_TIME, BY_TIME_REV + } + + private SortOption fSortOption; + private Comparator fThreadComparator = null; + private Action fSortByNameAction; + private Action fSortByIdAction; + private Action fSortByTimeAction; + + // ------------------------------------------------------------------------ + // Fields + // ------------------------------------------------------------------------ + + // The time graph combo + private TimeGraphCombo fTimeGraphCombo; + + // The selected trace + private ITmfTrace fTrace; + + // The selected thread map + private final Map fSelectedThreadMap = new HashMap<>(); + + // The time graph entry list + private List fEntryList; + + // The trace to entry list hash map + private final Map> fEntryListMap = new HashMap<>(); + + // The trace to build thread hash map + private final Map fBuildThreadMap = new HashMap<>(); + + /** The map to map function addresses to function names */ + private Map fNameMapping; + + // The start time + private long fStartTime; + + // The end time + private long fEndTime; + + // The display width + private int fDisplayWidth; + + // The next event action + private Action fNextEventAction; + + // The previous event action + private Action fPrevEventAction; + + // The next item action + private Action fNextItemAction; + + // The previous item action + private Action fPreviousItemAction; + + // The action to import a function-name mapping file + private Action fImportMappingAction; + + // The action to import a binary file mapping */ + private Action fImportBinaryFileMappingAction; + + // The zoom thread + private ZoomThread fZoomThread; + + // The redraw state used to prevent unnecessary queuing of display runnables + private State fRedrawState = State.IDLE; + + // The redraw synchronization object + private final Object fSyncObj = new Object(); + + // The saved time sync. signal used when switching off the pinning of a view + private TmfTimeSynchSignal fSavedTimeSyncSignal; + + // The saved time range sync. signal used when switching off the pinning of + // a view + private TmfRangeSynchSignal fSavedRangeSyncSignal; + + // ------------------------------------------------------------------------ + // Classes + // ------------------------------------------------------------------------ + + private class TraceEntry extends TimeGraphEntry { + public TraceEntry(String name, long startTime, long endTime) { + super(name, startTime, endTime); + } + + @Override + public boolean hasTimeEvents() { + return false; + } + } + + private class ThreadEntry extends TimeGraphEntry { + // The call stack quark + private final int fCallStackQuark; + // The state system from which this entry comes + private final ITmfStateSystem fSS; + // The thread id + private final long fThreadId; + + public ThreadEntry(ITmfStateSystem ss, String name, long threadId, int callStackQuark, long startTime, long endTime) { + super(name, startTime, endTime); + fCallStackQuark = callStackQuark; + fThreadId = threadId; + fSS = ss; + } + + @Override + public boolean hasTimeEvents() { + return false; + } + + public int getCallStackQuark() { + return fCallStackQuark; + } + + public long getThreadId() { + return fThreadId; + } + + @Nullable + public ITmfStateSystem getStateSystem() { + return fSS; + } + } + + private class ThreadNameComparator implements Comparator { + private boolean reverse; + + public ThreadNameComparator(boolean reverse) { + this.reverse = reverse; + } + + @Override + public int compare(ITimeGraphEntry o1, ITimeGraphEntry o2) { + return reverse ? o2.getName().compareTo(o1.getName()) : + o1.getName().compareTo(o2.getName()); + } + } + + private class ThreadIdComparator implements Comparator { + private boolean reverse; + + public ThreadIdComparator(boolean reverse) { + this.reverse = reverse; + } + + @Override + public int compare(ITimeGraphEntry o1, ITimeGraphEntry o2) { + ThreadEntry t1 = (ThreadEntry) o1; + ThreadEntry t2 = (ThreadEntry) o2; + return reverse ? Long.compare(t2.getThreadId(), t1.getThreadId()) : + Long.compare(t1.getThreadId(), t2.getThreadId()); + } + } + + private class ThreadTimeComparator implements Comparator { + private boolean reverse; + + public ThreadTimeComparator(boolean reverse) { + this.reverse = reverse; + } + + @Override + public int compare(ITimeGraphEntry o1, ITimeGraphEntry o2) { + return reverse ? Long.compare(o2.getStartTime(), o1.getStartTime()) : + Long.compare(o1.getStartTime(), o2.getStartTime()); + } + } + + private class TreeContentProvider implements ITreeContentProvider { + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + @Override + public Object[] getElements(Object inputElement) { + if (inputElement != null) { + try { + return ((List) inputElement).toArray(new ITimeGraphEntry[0]); + } catch (ClassCastException e) { + } + } + return new ITimeGraphEntry[0]; + } + + @Override + public Object[] getChildren(Object parentElement) { + ITimeGraphEntry entry = (ITimeGraphEntry) parentElement; + return entry.getChildren().toArray(); + } + + @Override + public Object getParent(Object element) { + ITimeGraphEntry entry = (ITimeGraphEntry) element; + return entry.getParent(); + } + + @Override + public boolean hasChildren(Object element) { + ITimeGraphEntry entry = (ITimeGraphEntry) element; + return entry.hasChildren(); + } + + } + + private class TreeLabelProvider implements ITableLabelProvider { + + @Override + public void addListener(ILabelProviderListener listener) { + } + + @Override + public void dispose() { + } + + @Override + public boolean isLabelProperty(Object element, String property) { + return false; + } + + @Override + public void removeListener(ILabelProviderListener listener) { + } + + @Override + public Image getColumnImage(Object element, int columnIndex) { + if (columnIndex == 0) { + if (element instanceof ThreadEntry) { + return THREAD_IMAGE; + } else if (element instanceof CallStackEntry) { + CallStackEntry entry = (CallStackEntry) element; + if (entry.getFunctionName().length() > 0) { + return STACKFRAME_IMAGE; + } + } + } + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + if (element instanceof CallStackEntry) { + CallStackEntry entry = (CallStackEntry) element; + if (columnIndex == 0) { + return entry.getFunctionName(); + } else if (columnIndex == 1 && entry.getFunctionName().length() > 0) { + int depth = entry.getStackLevel(); + return Integer.toString(depth); + } else if (columnIndex == 2 && entry.getFunctionName().length() > 0) { + ITmfTimestamp ts = new TmfTimestamp(entry.getFunctionEntryTime(), ITmfTimestamp.NANOSECOND_SCALE); + return ts.toString(); + } else if (columnIndex == 3 && entry.getFunctionName().length() > 0) { + ITmfTimestamp ts = new TmfTimestamp(entry.getFunctionExitTime(), ITmfTimestamp.NANOSECOND_SCALE); + return ts.toString(); + } else if (columnIndex == 4 && entry.getFunctionName().length() > 0) { + ITmfTimestamp ts = new TmfTimestampDelta(entry.getFunctionExitTime() - entry.getFunctionEntryTime(), ITmfTimestamp.NANOSECOND_SCALE); + return ts.toString(); + } + } else if (element instanceof ITimeGraphEntry) { + if (columnIndex == 0) { + return ((ITimeGraphEntry) element).getName(); + } + } + return ""; //$NON-NLS-1$ + } + + } + + private class TimeGraphContentProvider implements ITimeGraphContentProvider { + + @Override + public ITimeGraphEntry[] getElements(Object inputElement) { + if (inputElement != null) { + try { + return ((List) inputElement).toArray(new ITimeGraphEntry[0]); + } catch (ClassCastException e) { + } + } + return new ITimeGraphEntry[0]; + } + + } + + private class BuildThread extends Thread { + private final ITmfTrace fBuildTrace; + private final ITmfTrace fParentTrace; + private final IProgressMonitor fMonitor; + + public BuildThread(ITmfTrace trace, ITmfTrace parentTrace) { + super("CallStackView build"); //$NON-NLS-1$ + fBuildTrace = trace; + fParentTrace = parentTrace; + fMonitor = new NullProgressMonitor(); + } + + @Override + public void run() { + buildThreadList(fBuildTrace, fParentTrace, fMonitor); + synchronized (fBuildThreadMap) { + fBuildThreadMap.remove(fBuildTrace); + } + } + + public void cancel() { + fMonitor.setCanceled(true); + } + } + + private class ZoomThread extends Thread { + private final List fZoomEntryList; + private final long fZoomStartTime; + private final long fZoomEndTime; + private final IProgressMonitor fMonitor; + + public ZoomThread(List entryList, long startTime, long endTime) { + super("CallStackView zoom"); //$NON-NLS-1$ + fZoomEntryList = entryList; + fZoomStartTime = startTime; + fZoomEndTime = endTime; + fMonitor = new NullProgressMonitor(); + } + + @Override + public void run() { + if (fZoomEntryList == null) { + return; + } + long resolution = Math.max(1, (fZoomEndTime - fZoomStartTime) / fDisplayWidth); + for (TraceEntry traceEntry : fZoomEntryList) { + for (ITimeGraphEntry threadEntry : traceEntry.getChildren()) { + ITmfStateSystem ss = ((ThreadEntry) threadEntry).getStateSystem(); + if (ss == null) { + continue; + } + ss.waitUntilBuilt(); + if (ss.isCancelled()) { + continue; + } + for (ITimeGraphEntry child : threadEntry.getChildren()) { + if (fMonitor.isCanceled()) { + break; + } + CallStackEntry entry = (CallStackEntry) child; + if (fZoomStartTime <= fStartTime && fZoomEndTime >= fEndTime) { + entry.setZoomedEventList(null); + } else { + List zoomedEventList = getEventList(entry, fZoomStartTime, fZoomEndTime, resolution, fMonitor); + if (zoomedEventList != null) { + entry.setZoomedEventList(zoomedEventList); + } + } + redraw(); + } + } + } + } + + public void cancel() { + fMonitor.setCanceled(true); + } + } + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + public CallStackView() { + super(ID); + fDisplayWidth = Display.getDefault().getBounds().width; + } + + // ------------------------------------------------------------------------ + // ViewPart + // ------------------------------------------------------------------------ + + @Override + public void createPartControl(Composite parent) { + fTimeGraphCombo = new TimeGraphCombo(parent, SWT.NONE); + + fTimeGraphCombo.setTreeContentProvider(new TreeContentProvider()); + + fTimeGraphCombo.setTreeLabelProvider(new TreeLabelProvider()); + + fTimeGraphCombo.setTreeColumns(COLUMN_TIMES); + + fTimeGraphCombo.getTreeViewer().getTree().getColumn(0).setWidth(COLUMN_WIDTHS[0]); + fTimeGraphCombo.getTreeViewer().getTree().getColumn(1).setWidth(COLUMN_WIDTHS[1]); + fTimeGraphCombo.getTreeViewer().getTree().getColumn(2).setWidth(COLUMN_WIDTHS[2]); + fTimeGraphCombo.getTreeViewer().getTree().getColumn(3).setWidth(COLUMN_WIDTHS[3]); + fTimeGraphCombo.getTreeViewer().getTree().getColumn(4).setWidth(COLUMN_WIDTHS[4]); + + fTimeGraphCombo.setTimeGraphContentProvider(new TimeGraphContentProvider()); + fTimeGraphCombo.setTimeGraphProvider(new CallStackPresentationProvider(this)); + fTimeGraphCombo.getTimeGraphViewer().setTimeFormat(TimeFormat.CALENDAR); + + fTimeGraphCombo.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() { + @Override + public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) { + long startTime = event.getStartTime(); + long endTime = event.getEndTime(); + TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime)); + broadcast(new TmfRangeSynchSignal(CallStackView.this, range)); + startZoomThread(startTime, endTime); + } + }); + + fTimeGraphCombo.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() { + @Override + public void timeSelected(TimeGraphTimeEvent event) { + long beginTime = event.getBeginTime(); + long endTime = event.getEndTime(); + synchingToTime(beginTime); + broadcast(new TmfTimeSynchSignal(CallStackView.this, new TmfNanoTimestamp(beginTime), new TmfNanoTimestamp(endTime))); + } + }); + + fTimeGraphCombo.getTimeGraphViewer().getControl().addControlListener(new ControlAdapter() { + @Override + public void controlResized(ControlEvent e) { + fDisplayWidth = fTimeGraphCombo.getTimeGraphViewer().getControl().getSize().x; + if (fEntryList != null) { + startZoomThread(fTimeGraphCombo.getTimeGraphViewer().getTime0(), fTimeGraphCombo.getTimeGraphViewer().getTime1()); + } + } + }); + + fTimeGraphCombo.getTreeViewer().addDoubleClickListener(new IDoubleClickListener() { + @Override + public void doubleClick(DoubleClickEvent event) { + Object selection = ((IStructuredSelection) event.getSelection()).getFirstElement(); + if (selection instanceof CallStackEntry) { + CallStackEntry entry = (CallStackEntry) selection; + if (entry.getFunctionName().length() > 0) { + long entryTime = entry.getFunctionEntryTime(); + long exitTime = entry.getFunctionExitTime(); + long spacingTime = (long) ((exitTime - entryTime) * SPACING_RATIO); + entryTime -= spacingTime; + exitTime += spacingTime; + TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(entryTime), new TmfNanoTimestamp(exitTime)); + broadcast(new TmfRangeSynchSignal(CallStackView.this, range)); + fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(entryTime, exitTime); + startZoomThread(entryTime, exitTime); + } + } + } + }); + + fTimeGraphCombo.getTimeGraphViewer().getTimeGraphControl().addMouseListener(new MouseAdapter() { + @Override + public void mouseDoubleClick(MouseEvent e) { + TimeGraphControl timeGraphControl = fTimeGraphCombo.getTimeGraphViewer().getTimeGraphControl(); + ISelection selection = timeGraphControl.getSelection(); + if (selection instanceof TimeGraphSelection) { + Object o = ((TimeGraphSelection) selection).getFirstElement(); + if (o instanceof CallStackEvent) { + CallStackEvent event = (CallStackEvent) o; + long startTime = event.getTime(); + long endTime = startTime + event.getDuration(); + long spacingTime = (long) ((endTime - startTime) * SPACING_RATIO); + startTime -= spacingTime; + endTime += spacingTime; + TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime)); + broadcast(new TmfRangeSynchSignal(CallStackView.this, range)); + fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime); + startZoomThread(startTime, endTime); + } + } + } + }); + + IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager(); + fTimeGraphCombo.getTimeGraphViewer().getTimeGraphControl().setStatusLineManager(statusLineManager); + + // View Action Handling + makeActions(); + contributeToActionBars(); + createContextMenu(); + loadSortOption(); + + IEditorPart editor = getSite().getPage().getActiveEditor(); + if (editor instanceof ITmfTraceEditor) { + ITmfTrace trace = ((ITmfTraceEditor) editor).getTrace(); + if (trace != null) { + traceSelected(new TmfTraceSelectedSignal(this, trace)); + } + } + } + + @Override + public void setFocus() { + fTimeGraphCombo.setFocus(); + } + + // ------------------------------------------------------------------------ + // Signal handlers + // ------------------------------------------------------------------------ + /** + * Handler for the trace opened signal. + * + * @param signal + * The incoming signal + * @since 2.0 + */ + @TmfSignalHandler + public void traceOpened(TmfTraceOpenedSignal signal) { + fTrace = signal.getTrace(); + loadTrace(); + } + + /** + * Handler for the trace selected signal + * + * @param signal + * The incoming signal + */ + @TmfSignalHandler + public void traceSelected(final TmfTraceSelectedSignal signal) { + if (signal.getTrace() == fTrace) { + return; + } + fTrace = signal.getTrace(); + loadTrace(); + } + + /** + * Trace is closed: clear the data structures and the view + * + * @param signal + * the signal received + */ + @TmfSignalHandler + public void traceClosed(final TmfTraceClosedSignal signal) { + synchronized (fBuildThreadMap) { + ITmfTrace[] traces = TmfTraceManager.getTraceSet(signal.getTrace()); + for (ITmfTrace trace : traces) { + BuildThread buildThread = fBuildThreadMap.remove(trace); + if (buildThread != null) { + buildThread.cancel(); + } + } + } + synchronized (fEntryListMap) { + fEntryListMap.remove(signal.getTrace()); + } + fSelectedThreadMap.remove(signal.getTrace()); + if (signal.getTrace() == fTrace) { + fTrace = null; + fStartTime = 0; + fEndTime = 0; + refresh(); + } + } + + /** + * Handler for the TimeSynch signal + * + * @param signal + * The incoming signal + */ + @TmfSignalHandler + public void synchToTime(final TmfTimeSynchSignal signal) { + + fSavedTimeSyncSignal = isPinned() ? new TmfTimeSynchSignal(signal.getSource(), signal.getBeginTime(), signal.getEndTime()) : null; + + if (signal.getSource() == this || fTrace == null || isPinned()) { + return; + } + final long beginTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + final long endTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (fTimeGraphCombo.isDisposed()) { + return; + } + if (beginTime == endTime) { + fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(beginTime, true); + } else { + fTimeGraphCombo.getTimeGraphViewer().setSelectionRange(beginTime, endTime); + } + synchingToTime(beginTime); + startZoomThread(fTimeGraphCombo.getTimeGraphViewer().getTime0(), fTimeGraphCombo.getTimeGraphViewer().getTime1()); + if (fEntryList == null) { + return; + } + TimeGraphViewer viewer = fTimeGraphCombo.getTimeGraphViewer(); + for (TraceEntry traceEntry : fEntryList) { + for (ITimeGraphEntry child : traceEntry.getChildren()) { + ThreadEntry threadEntry = (ThreadEntry) child; + ITmfStateSystem ss = threadEntry.getStateSystem(); + if (ss == null || beginTime < ss.getStartTime() || beginTime > ss.getCurrentEndTime()) { + continue; + } + try { + int quark = threadEntry.getCallStackQuark(); + ITmfStateInterval stackInterval = ss.querySingleState(beginTime, quark); + if (beginTime == stackInterval.getStartTime()) { + int stackLevel = stackInterval.getStateValue().unboxInt(); + ITimeGraphEntry selectedEntry = threadEntry.getChildren().get(Math.max(0, stackLevel - 1)); + fTimeGraphCombo.setSelection(selectedEntry); + viewer.getTimeGraphControl().fireSelectionChanged(); + break; + } + } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException | StateValueTypeException e) { + Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ + } + } + } + } + }); + } + + /** + * Handler for the RangeSynch signal + * + * @param signal + * The incoming signal + */ + @TmfSignalHandler + public void synchToRange(final TmfRangeSynchSignal signal) { + + if (isPinned()) { + fSavedRangeSyncSignal = + new TmfRangeSynchSignal(signal.getSource(), new TmfTimeRange(signal.getCurrentRange().getStartTime(), signal.getCurrentRange().getEndTime())); + + fSavedTimeSyncSignal = null; + } + + if (signal.getSource() == this || fTrace == null || isPinned()) { + return; + } + if (signal.getCurrentRange().getIntersection(fTrace.getTimeRange()) == null) { + return; + } + final long startTime = signal.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + final long endTime = signal.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (fTimeGraphCombo.isDisposed()) { + return; + } + fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime); + startZoomThread(startTime, endTime); + } + }); + } + + // ------------------------------------------------------------------------ + // Internal + // ------------------------------------------------------------------------ + + private void loadTrace() { + synchronized (fEntryListMap) { + fEntryList = fEntryListMap.get(fTrace); + if (fEntryList == null) { + fStartTime = Long.MAX_VALUE; + fEndTime = Long.MIN_VALUE; + synchronized (fBuildThreadMap) { + ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace); + for (ITmfTrace trace : traces) { + BuildThread buildThread = new BuildThread(trace, fTrace); + fBuildThreadMap.put(trace, buildThread); + buildThread.start(); + } + } + } else { + fStartTime = fTrace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + fEndTime = fTrace.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + refresh(); + } + } + } + + private void buildThreadList(final ITmfTrace trace, final ITmfTrace parentTrace, IProgressMonitor monitor) { + if (monitor.isCanceled()) { + return; + } + AbstractCallStackAnalysis module = getCallStackModule(trace); + if (module == null) { + addUnavailableEntry(trace, parentTrace); + return; + } + ITmfStateSystem ss = module.getStateSystem(); + if (ss == null) { + addUnavailableEntry(trace, parentTrace); + return; + } + + Map traceEntryMap = new HashMap<>(); + Map threadEntryMap = new HashMap<>(); + String[] threadPaths = module.getThreadsPattern(); + + long start = ss.getStartTime(); + + boolean complete = false; + while (!complete) { + if (monitor.isCanceled()) { + return; + } + complete = ss.waitUntilBuilt(BUILD_UPDATE_TIMEOUT); + if (ss.isCancelled()) { + return; + } + long end = ss.getCurrentEndTime(); + if (start == end && !complete) { // when complete execute one last time regardless of end time + continue; + } + List threadQuarks = ss.getQuarks(threadPaths); + TraceEntry traceEntry = traceEntryMap.get(trace); + if (traceEntry == null) { + traceEntry = new TraceEntry(trace.getName(), start, end + 1); + traceEntryMap.put(trace, traceEntry); + traceEntry.sortChildren(fThreadComparator); + addToEntryList(parentTrace, Collections.singletonList(traceEntry)); + } else { + traceEntry.updateEndTime(end); + } + for (int i = 0; i < threadQuarks.size(); i++) { + if (monitor.isCanceled()) { + return; + } + int threadQuark = threadQuarks.get(i); + try { + String[] callStackPath = module.getCallStackPath(); + int callStackQuark = ss.getQuarkRelative(threadQuark, callStackPath); + String threadName = ss.getAttributeName(threadQuark); + long threadEnd = end + 1; + ITmfStateInterval endInterval = ss.querySingleState(ss.getCurrentEndTime(), callStackQuark); + if (endInterval.getStateValue().isNull() && endInterval.getStartTime() != ss.getStartTime()) { + threadEnd = endInterval.getStartTime(); + } + ThreadEntry threadEntry = threadEntryMap.get(threadQuark); + if (threadEntry == null) { + long threadId = ss.querySingleState(ss.getCurrentEndTime(), threadQuark).getStateValue().unboxLong(); + long threadStart = start; + ITmfStateInterval startInterval = ss.querySingleState(start, callStackQuark); + if (startInterval.getStateValue().isNull()) { + threadStart = Math.min(startInterval.getEndTime() + 1, end + 1); + } + threadEntry = new ThreadEntry(ss, threadName, threadId, callStackQuark, threadStart, threadEnd); + threadEntryMap.put(threadQuark, threadEntry); + traceEntry.addChild(threadEntry); + } else { + threadEntry.updateEndTime(threadEnd); + } + int level = 1; + for (int stackLevelQuark : ss.getSubAttributes(callStackQuark, false)) { + if (level > threadEntry.getChildren().size()) { + CallStackEntry callStackEntry = new CallStackEntry(threadName, stackLevelQuark, level, trace, ss); + threadEntry.addChild(callStackEntry); + } + level++; + } + } catch (AttributeNotFoundException e) { + Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ + } catch (StateSystemDisposedException e) { + /* Ignored */ + } + } + if (parentTrace == fTrace) { + synchronized (fEntryListMap) { + fStartTime = Math.min(fStartTime, start); + fEndTime = Math.max(fEndTime, end + 1); + } + refresh(); + } + for (ITimeGraphEntry threadEntry : traceEntry.getChildren()) { + for (ITimeGraphEntry callStackEntry : threadEntry.getChildren()) { + if (monitor.isCanceled()) { + return; + } + buildStatusEvents(parentTrace, (CallStackEntry) callStackEntry, monitor, start, end); + } + } + start = end; + } + } + + private void addToEntryList(ITmfTrace trace, List list) { + synchronized (fEntryListMap) { + List entryList = fEntryListMap.get(trace); + if (entryList == null) { + fEntryListMap.put(trace, new CopyOnWriteArrayList<>(list)); + } else { + entryList.addAll(list); + } + } + } + + private void addUnavailableEntry(ITmfTrace trace, ITmfTrace parentTrace) { + String name = Messages.CallStackView_StackInfoNotAvailable + ' ' + '(' + trace.getName() + ')'; + TraceEntry unavailableEntry = new TraceEntry(name, 0, 0); + addToEntryList(parentTrace, Collections.singletonList(unavailableEntry)); + if (parentTrace == fTrace) { + refresh(); + } + } + + private void buildStatusEvents(ITmfTrace trace, CallStackEntry entry, IProgressMonitor monitor, long start, long end) { + ITmfStateSystem ss = entry.getStateSystem(); + long resolution = Math.max(1, (end - ss.getStartTime()) / fDisplayWidth); + List eventList = getEventList(entry, start, end + 1, resolution, monitor); + if (eventList != null) { + for (ITimeEvent event : eventList) { + entry.addEvent(event); + } + } + if (trace == fTrace) { + redraw(); + } + } + + private static List getEventList(CallStackEntry entry, + long startTime, long endTime, long resolution, + IProgressMonitor monitor) { + ITmfStateSystem ss = entry.getStateSystem(); + long start = Math.max(startTime, ss.getStartTime()); + long end = Math.min(endTime, ss.getCurrentEndTime() + 1); + if (end <= start) { + return null; + } + List eventList = null; + try { + List stackIntervals = ss.queryHistoryRange(entry.getQuark(), start, end - 1, resolution, monitor); + eventList = new ArrayList<>(stackIntervals.size()); + long lastEndTime = -1; + boolean lastIsNull = true; + for (ITmfStateInterval statusInterval : stackIntervals) { + if (monitor.isCanceled()) { + return null; + } + long time = statusInterval.getStartTime(); + long duration = statusInterval.getEndTime() - time + 1; + if (!statusInterval.getStateValue().isNull()) { + final int modulo = CallStackPresentationProvider.NUM_COLORS / 2; + int value = statusInterval.getStateValue().toString().hashCode() % modulo + modulo; + eventList.add(new CallStackEvent(entry, time, duration, value)); + lastIsNull = false; + } else { + if (lastEndTime == -1) { + // add null event if it intersects the start time + eventList.add(new NullTimeEvent(entry, time, duration)); + } else { + if (lastEndTime != time && lastIsNull) { + // add unknown event if between two null states + eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime)); + } + if (time + duration >= endTime) { + // add null event if it intersects the end time + eventList.add(new NullTimeEvent(entry, time, duration)); + } + } + lastIsNull = true; + } + lastEndTime = time + duration; + } + } catch (AttributeNotFoundException e) { + Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ + } catch (TimeRangeException e) { + Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ + } catch (StateSystemDisposedException e) { + /* Ignored */ + } + return eventList; + } + + private void synchingToTime(long time) { + if (fEntryList == null) { + return; + } + for (TraceEntry traceEntry : fEntryList) { + for (ITimeGraphEntry threadEntry : traceEntry.getChildren()) { + ITmfStateSystem ss = ((ThreadEntry) threadEntry).getStateSystem(); + if (ss == null) { + continue; + } + if (ss.isCancelled()) { + continue; + } + if (time < ss.getStartTime() || time > ss.getCurrentEndTime()) { + continue; + } + for (ITimeGraphEntry child : threadEntry.getChildren()) { + CallStackEntry callStackEntry = (CallStackEntry) child; + try { + ITmfStateInterval stackLevelInterval = ss.querySingleState(time, callStackEntry.getQuark()); + ITmfStateValue nameValue = stackLevelInterval.getStateValue(); + String name = ""; //$NON-NLS-1$ + try { + if (nameValue.getType() == Type.STRING) { + String address = nameValue.unboxStr(); + name = getFunctionName(address); + } else if (nameValue.getType() == Type.INTEGER) { + name = "0x" + Integer.toHexString(nameValue.unboxInt()); //$NON-NLS-1$ + } else if (nameValue.getType() == Type.LONG) { + name = "0x" + Long.toHexString(nameValue.unboxLong()); //$NON-NLS-1$ + } + } catch (StateValueTypeException e) { + } + callStackEntry.setFunctionName(name); + if (name.length() > 0) { + callStackEntry.setFunctionEntryTime(stackLevelInterval.getStartTime()); + callStackEntry.setFunctionExitTime(stackLevelInterval.getEndTime() + 1); + } + } catch (AttributeNotFoundException e) { + Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ + } catch (StateSystemDisposedException e) { + /* Ignored */ + } + } + } + } + fTimeGraphCombo.refresh(); + } + + private void refresh() { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (fTimeGraphCombo.isDisposed()) { + return; + } + synchronized (fEntryListMap) { + fEntryList = fEntryListMap.get(fTrace); + if (fEntryList == null) { + fEntryList = new ArrayList<>(); + } + for (TraceEntry traceEntry : fEntryList) { + traceEntry.sortChildren(fThreadComparator); + } + } + if (fEntryList != fTimeGraphCombo.getInput()) { + fTimeGraphCombo.setInput(fEntryList); + } else { + fTimeGraphCombo.refresh(); + } + fTimeGraphCombo.getTimeGraphViewer().setTimeBounds(fStartTime, fEndTime); + + long selectionBeginTime = fTrace == null ? 0 : fTraceManager.getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long selectionEndTime = fTrace == null ? 0 : fTraceManager.getSelectionEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long startTime = fTrace == null ? 0 : fTraceManager.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long endTime = fTrace == null ? 0 : fTraceManager.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + startTime = Math.max(startTime, fStartTime); + endTime = Math.min(endTime, fEndTime); + fTimeGraphCombo.getTimeGraphViewer().setSelectionRange(selectionBeginTime, selectionEndTime); + synchingToTime(selectionBeginTime); + fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime); + startZoomThread(startTime, endTime); + } + }); + } + + private void redraw() { + synchronized (fSyncObj) { + if (fRedrawState == State.IDLE) { + fRedrawState = State.BUSY; + } else { + fRedrawState = State.PENDING; + return; + } + } + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (fTimeGraphCombo.isDisposed()) { + return; + } + fTimeGraphCombo.redraw(); + fTimeGraphCombo.update(); + synchronized (fSyncObj) { + if (fRedrawState == State.PENDING) { + fRedrawState = State.IDLE; + redraw(); + } else { + fRedrawState = State.IDLE; + } + } + } + }); + } + + private void startZoomThread(long startTime, long endTime) { + if (fZoomThread != null) { + fZoomThread.cancel(); + } + fZoomThread = new ZoomThread(fEntryList, startTime, endTime); + fZoomThread.start(); + } + + private void makeActions() { + fPreviousItemAction = fTimeGraphCombo.getTimeGraphViewer().getPreviousItemAction(); + fPreviousItemAction.setText(Messages.TmfTimeGraphViewer_PreviousItemActionNameText); + fPreviousItemAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousItemActionToolTipText); + fNextItemAction = fTimeGraphCombo.getTimeGraphViewer().getNextItemAction(); + fNextItemAction.setText(Messages.TmfTimeGraphViewer_NextItemActionNameText); + fNextItemAction.setToolTipText(Messages.TmfTimeGraphViewer_NextItemActionToolTipText); + } + + private void contributeToActionBars() { + IActionBars bars = getViewSite().getActionBars(); + fillLocalToolBar(bars.getToolBarManager()); + + // Create pin action + contributePinActionToToolBar(); + fPinAction.addPropertyChangeListener(new IPropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent event) { + if (IAction.CHECKED.equals(event.getProperty()) && !isPinned()) { + if (fSavedRangeSyncSignal != null) { + synchToRange(fSavedRangeSyncSignal); + fSavedRangeSyncSignal = null; + } + + if (fSavedTimeSyncSignal != null) { + synchToTime(fSavedTimeSyncSignal); + fSavedTimeSyncSignal = null; + } + } + } + }); + } + + private void fillLocalToolBar(IToolBarManager manager) { + manager.add(getImportBinaryAction()); + manager.add(getImportMappingAction()); + manager.add(new Separator()); + manager.add(getSortByNameAction()); + manager.add(getSortByIdAction()); + manager.add(getSortByTimeAction()); + manager.add(new Separator()); + manager.add(fTimeGraphCombo.getTimeGraphViewer().getResetScaleAction()); + manager.add(getPreviousEventAction()); + manager.add(getNextEventAction()); + manager.add(fPreviousItemAction); + manager.add(fNextItemAction); + manager.add(fTimeGraphCombo.getTimeGraphViewer().getZoomInAction()); + manager.add(fTimeGraphCombo.getTimeGraphViewer().getZoomOutAction()); + manager.add(new Separator()); + } + + private void createContextMenu() { + final MenuManager contextMenu = new MenuManager(); + contextMenu.add(getSortByNameAction()); + contextMenu.add(getSortByIdAction()); + contextMenu.add(getSortByTimeAction()); + + Tree tree = fTimeGraphCombo.getTreeViewer().getTree(); + Menu menu = contextMenu.createContextMenu(tree); + tree.setMenu(menu); + } + + /** + * Get the the next event action. + * + * @return The action object + */ + private Action getNextEventAction() { + if (fNextEventAction == null) { + fNextEventAction = new Action() { + @Override + public void run() { + TimeGraphViewer viewer = fTimeGraphCombo.getTimeGraphViewer(); + ITimeGraphEntry entry = viewer.getSelection(); + if (entry instanceof CallStackEntry) { + try { + CallStackEntry callStackEntry = (CallStackEntry) entry; + ITmfStateSystem ss = callStackEntry.getStateSystem(); + long time = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), viewer.getSelectionBegin())); + ThreadEntry threadEntry = (ThreadEntry) callStackEntry.getParent(); + int quark = ss.getParentAttributeQuark(callStackEntry.getQuark()); + ITmfStateInterval stackInterval = ss.querySingleState(time, quark); + long newTime = stackInterval.getEndTime() + 1; + viewer.setSelectedTimeNotify(newTime, true); + stackInterval = ss.querySingleState(Math.min(ss.getCurrentEndTime(), newTime), quark); + int stackLevel = stackInterval.getStateValue().unboxInt(); + ITimeGraphEntry selectedEntry = threadEntry.getChildren().get(Math.max(0, stackLevel - 1)); + fTimeGraphCombo.setSelection(selectedEntry); + viewer.getTimeGraphControl().fireSelectionChanged(); + startZoomThread(viewer.getTime0(), viewer.getTime1()); + + } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException | StateValueTypeException e) { + Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ + } + } + } + }; + + fNextEventAction.setText(Messages.TmfTimeGraphViewer_NextEventActionNameText); + fNextEventAction.setToolTipText(Messages.TmfTimeGraphViewer_NextEventActionToolTipText); + fNextEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_EVENT)); + } + + return fNextEventAction; + } + + /** + * Get the previous event action. + * + * @return The Action object + */ + private Action getPreviousEventAction() { + if (fPrevEventAction == null) { + fPrevEventAction = new Action() { + @Override + public void run() { + TimeGraphViewer viewer = fTimeGraphCombo.getTimeGraphViewer(); + ITimeGraphEntry entry = viewer.getSelection(); + if (entry instanceof CallStackEntry) { + try { + CallStackEntry callStackEntry = (CallStackEntry) entry; + ITmfStateSystem ss = callStackEntry.getStateSystem(); + long time = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), viewer.getSelectionBegin())); + ThreadEntry threadEntry = (ThreadEntry) callStackEntry.getParent(); + int quark = ss.getParentAttributeQuark(callStackEntry.getQuark()); + ITmfStateInterval stackInterval = ss.querySingleState(time, quark); + if (stackInterval.getStartTime() == time && time > ss.getStartTime()) { + stackInterval = ss.querySingleState(time - 1, quark); + } + viewer.setSelectedTimeNotify(stackInterval.getStartTime(), true); + int stackLevel = stackInterval.getStateValue().unboxInt(); + ITimeGraphEntry selectedEntry = threadEntry.getChildren().get(Math.max(0, stackLevel - 1)); + fTimeGraphCombo.setSelection(selectedEntry); + viewer.getTimeGraphControl().fireSelectionChanged(); + startZoomThread(viewer.getTime0(), viewer.getTime1()); + + } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException | StateValueTypeException e) { + Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ + } + } + } + }; + + fPrevEventAction.setText(Messages.TmfTimeGraphViewer_PreviousEventActionNameText); + fPrevEventAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousEventActionToolTipText); + fPrevEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_EVENT)); + } + + return fPrevEventAction; + } + + private static @Nullable AbstractCallStackAnalysis getCallStackModule(ITmfTrace trace) { + /* + * Since we cannot know the exact analysis ID (in separate plugins), we + * will search using the analysis type. + */ + Iterable modules = + trace.getAnalysisModulesOfClass(AbstractCallStackAnalysis.class); + Iterator it = modules.iterator(); + if (!it.hasNext()) { + /* This trace does not provide a call-stack analysis */ + return null; + } + + /* + * We only look at the first module we find. + * + * TODO Handle the advanced case where one trace provides more than one + * call-stack analysis. + */ + AbstractCallStackAnalysis module = it.next(); + /* This analysis is not automatic, we need to schedule it on-demand */ + module.schedule(); + module.waitForInitialization(); + return module; + } + + // ------------------------------------------------------------------------ + // Methods related to function name mapping + // ------------------------------------------------------------------------ + + /** + * Common code for all import file mapping actions + */ + private abstract class AbstractImportFileMappingAction extends Action { + private final String fDialogTitle; + + private AbstractImportFileMappingAction(String dialogTitle) { + fDialogTitle = dialogTitle; + } + + @Override + public void run() { + FileDialog dialog = new FileDialog(getViewSite().getShell()); + dialog.setText(fDialogTitle); + final String filePath = dialog.open(); + if (filePath == null) { + /* No file was selected, don't change anything */ + return; + } + + /* + * Start the mapping import in a separate thread (we do not want to + * UI thread to do this). + */ + Job job = new Job(Messages.CallStackView_ImportMappingJobName) { + @Override + public IStatus run(IProgressMonitor monitor) { + fNameMapping = doMapping(new File(filePath)); + + /* Refresh call stack entries and event labels */ + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + synchingToTime(fTimeGraphCombo.getTimeGraphViewer().getSelectionBegin()); + } + }); + return Status.OK_STATUS; + } + }; + job.schedule(); + } + + abstract Map doMapping(File file); + } + + /** + * Toolbar icon to import the function address-to-name mapping file. + */ + private Action getImportMappingAction() { + if (fImportMappingAction != null) { + return fImportMappingAction; + } + fImportMappingAction = new AbstractImportFileMappingAction(Messages.CallStackView_ImportMappingDialogTitle) { + @Override + Map doMapping(File file) { + return FunctionNameMapper.mapFromNmTextFile(file); + } + }; + + fImportMappingAction.setText(Messages.CallStackView_ImportMappingButtonText); + fImportMappingAction.setToolTipText(Messages.CallStackView_ImportMappingButtonTooltip); + fImportMappingAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(IMPORT_MAPPING_ICON_PATH)); + + return fImportMappingAction; + } + + private Action getSortByNameAction() { + if (fSortByNameAction == null) { + fSortByNameAction = new Action(Messages.CallStackView_SortByThreadName, IAction.AS_CHECK_BOX) { + @Override + public void run() { + if (fSortOption == SortOption.BY_NAME) { + saveSortOption(SortOption.BY_NAME_REV); + } else { + saveSortOption(SortOption.BY_NAME); + } + } + }; + fSortByNameAction.setToolTipText(Messages.CallStackView_SortByThreadName); + fSortByNameAction.setImageDescriptor(SORT_BY_NAME_ICON); + } + return fSortByNameAction; + } + + private Action getSortByIdAction() { + if (fSortByIdAction == null) { + fSortByIdAction = new Action(Messages.CallStackView_SortByThreadId, IAction.AS_CHECK_BOX) { + @Override + public void run() { + if (fSortOption == SortOption.BY_ID) { + saveSortOption(SortOption.BY_ID_REV); + } else { + saveSortOption(SortOption.BY_ID); + } + } + }; + fSortByIdAction.setToolTipText(Messages.CallStackView_SortByThreadId); + fSortByIdAction.setImageDescriptor(SORT_BY_ID_ICON); + } + return fSortByIdAction; + } + + private Action getSortByTimeAction() { + if (fSortByTimeAction == null) { + fSortByTimeAction = new Action(Messages.CallStackView_SortByThreadTime, IAction.AS_CHECK_BOX) { + @Override + public void run() { + if (fSortOption == SortOption.BY_TIME) { + saveSortOption(SortOption.BY_TIME_REV); + } else { + saveSortOption(SortOption.BY_TIME); + } + } + }; + fSortByTimeAction.setToolTipText(Messages.CallStackView_SortByThreadTime); + fSortByTimeAction.setImageDescriptor(SORT_BY_TIME_ICON); + } + return fSortByTimeAction; + } + + private void loadSortOption() { + IDialogSettings settings = Activator.getDefault().getDialogSettings(); + IDialogSettings section = settings.getSection(getClass().getName()); + if (section == null) { + return; + } + String sortOption = section.get(SORT_OPTION_KEY); + if (sortOption == null) { + return; + } + + // reset defaults + getSortByNameAction().setChecked(false); + getSortByNameAction().setImageDescriptor(SORT_BY_NAME_ICON); + getSortByIdAction().setChecked(false); + getSortByIdAction().setImageDescriptor(SORT_BY_ID_ICON); + getSortByTimeAction().setChecked(false); + getSortByTimeAction().setImageDescriptor(SORT_BY_TIME_ICON); + + if (sortOption.equals(SortOption.BY_NAME.name())) { + fSortOption = SortOption.BY_NAME; + fThreadComparator = new ThreadNameComparator(false); + getSortByNameAction().setChecked(true); + } else if (sortOption.equals(SortOption.BY_NAME_REV.name())) { + fSortOption = SortOption.BY_NAME_REV; + fThreadComparator = new ThreadNameComparator(true); + getSortByNameAction().setChecked(true); + getSortByNameAction().setImageDescriptor(SORT_BY_NAME_REV_ICON); + } else if (sortOption.equals(SortOption.BY_ID.name())) { + fSortOption = SortOption.BY_ID; + fThreadComparator = new ThreadIdComparator(false); + getSortByIdAction().setChecked(true); + } else if (sortOption.equals(SortOption.BY_ID_REV.name())) { + fSortOption = SortOption.BY_ID_REV; + fThreadComparator = new ThreadIdComparator(true); + getSortByIdAction().setChecked(true); + getSortByIdAction().setImageDescriptor(SORT_BY_ID_REV_ICON); + } else if (sortOption.equals(SortOption.BY_TIME.name())) { + fSortOption = SortOption.BY_TIME; + fThreadComparator = new ThreadTimeComparator(false); + getSortByTimeAction().setChecked(true); + } else if (sortOption.equals(SortOption.BY_TIME_REV.name())) { + fSortOption = SortOption.BY_TIME_REV; + fThreadComparator = new ThreadTimeComparator(true); + getSortByTimeAction().setChecked(true); + getSortByTimeAction().setImageDescriptor(SORT_BY_TIME_REV_ICON); + } + } + + private void saveSortOption(SortOption sortOption) { + IDialogSettings settings = Activator.getDefault().getDialogSettings(); + IDialogSettings section = settings.getSection(getClass().getName()); + if (section == null) { + section = settings.addNewSection(getClass().getName()); + } + section.put(SORT_OPTION_KEY, sortOption.name()); + loadSortOption(); + if (fEntryList == null) { + return; + } + for (TraceEntry traceEntry : fEntryList) { + traceEntry.sortChildren(fThreadComparator); + } + refresh(); + } + + /** + * Toolbar icon to import the function address-to-name mapping binary file. + */ + private Action getImportBinaryAction() { + if (fImportBinaryFileMappingAction != null) { + return fImportBinaryFileMappingAction; + } + + fImportBinaryFileMappingAction = new AbstractImportFileMappingAction(Messages.CallStackView_ImportBinaryFileDialogTitle) { + @Override + Map doMapping(File file) { + return FunctionNameMapper.mapFromBinaryFile(file); + } + }; + + fImportBinaryFileMappingAction.setText(Messages.CallStackView_ImportBinaryFileButtonText); + fImportBinaryFileMappingAction.setToolTipText(Messages.CallStackView_ImportBinaryFileButtonTooltip); + fImportBinaryFileMappingAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(IMPORT_BINARY_ICON_PATH)); + + return fImportBinaryFileMappingAction; + } + + String getFunctionName(String address) { + if (fNameMapping == null) { + /* No mapping available, just print the addresses */ + return address; + } + String ret = fNameMapping.get(address); + if (ret == null) { + /* + * We didn't find this address in the mapping file, just use the + * address + */ + return address; + } + return ret; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/FunctionNameMapper.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/FunctionNameMapper.java new file mode 100644 index 0000000000..2c421a799b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/FunctionNameMapper.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + * Marc-Andre Laperle - Map from binary file + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.callstack; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; +import org.eclipse.cdt.core.IBinaryParser.ISymbol; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.ISafeRunnable; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; + +/** + * Class containing the different methods to import an address->name mapping. + * + * @author Alexandre Montplaisir + */ +class FunctionNameMapper { + + public static @Nullable Map mapFromNmTextFile(File mappingFile) { + Map map = new HashMap<>(); + + try (FileReader fr = new FileReader(mappingFile); + BufferedReader reader = new BufferedReader(fr);) { + for (String line = reader.readLine(); line != null; line = reader.readLine()) { + String[] elems = line.split(" "); //$NON-NLS-1$ + /* Only lines with 3 elements contain addresses */ + if (elems.length == 3) { + /* Strip the leading zeroes from the address */ + String address = elems[0].replaceFirst("^0+(?!$)", ""); //$NON-NLS-1$ //$NON-NLS-2$; + String name = elems[elems.length - 1]; + map.put(address, name); + } + } + } catch (FileNotFoundException e) { + return null; + } catch (IOException e) { + /* Stop reading the file at this point */ + } + + if (map.isEmpty()) { + return null; + } + return Collections.unmodifiableMap(map); + } + + /** + * Strip the leading zeroes from the address + * */ + private static String stripLeadingZeros(String address) { + return address.replaceFirst("^0+(?!$)", ""); //$NON-NLS-1$ //$NON-NLS-2$; + } + + public static @Nullable Map mapFromBinaryFile(File file) { + Map map = new HashMap<>(); + IBinaryParser.IBinaryObject binaryObject = getBinaryObject(file); + if (binaryObject != null) { + ISymbol[] symbols = binaryObject.getSymbols(); + for (ISymbol symbol : symbols) { + String address = symbol.getAddress().toHexAddressString(); + /* Remove "0x" */ + address = address.substring(2); + /* Strip the leading zeroes from the address */ + address = stripLeadingZeros(address); + map.put(address, symbol.getName()); + } + } + + return map; + } + + private static @Nullable IBinaryParser.IBinaryObject getBinaryObject(File file) { + IPath filePath = new Path(file.toString()); + + /* Get all the available binary parsers */ + final List binaryParsers = new ArrayList<>(); + IConfigurationElement[] elements = Platform.getExtensionRegistry() + .getConfigurationElementsFor(CCorePlugin.BINARY_PARSER_UNIQ_ID); + for (IConfigurationElement element : elements) { + IConfigurationElement[] children = element.getChildren("run"); //$NON-NLS-1$ + for (final IConfigurationElement run : children) { + SafeRunner.run(new ISafeRunnable() { + @Override + public void run() throws Exception { + IBinaryParser binaryParser = (IBinaryParser) run.createExecutableExtension("class"); //$NON-NLS-1$ + binaryParsers.add(binaryParser); + } + + @Override + public void handleException(Throwable exception) { + Activator.getDefault().logError("Error creating binary parser", exception); //$NON-NLS-1$ + } + }); + } + } + + /* Find the maximum "hint" buffer size we'll need from all the parsers */ + int hintBufferSize = 0; + for (IBinaryParser parser : binaryParsers) { + if (parser.getHintBufferSize() > hintBufferSize) { + hintBufferSize = Math.max(hintBufferSize, parser.getHintBufferSize()); + } + } + + /* Read the initial "hint" bytes */ + byte[] hintBuffer = new byte[hintBufferSize]; + if (hintBufferSize > 0) { + try (InputStream is = new FileInputStream(file) ){ + + int count = 0; + // Make sure we read up to 'hints' bytes if we possibly can + while (count < hintBufferSize) { + int bytesRead = is.read(hintBuffer, count, hintBufferSize - count); + if (bytesRead < 0) { + break; + } + count += bytesRead; + } + if (count > 0 && count < hintBuffer.length) { + byte[] array = new byte[count]; + System.arraycopy(hintBuffer, 0, array, 0, count); + hintBuffer = array; + } + } catch (IOException e) { + Activator.getDefault().logError("Error reading initial bytes of binary file", e); //$NON-NLS-1$ + return null; + } + } + + /* For all binary parsers, try to get a binary object */ + for (IBinaryParser parser : binaryParsers) { + if (parser.isBinary(hintBuffer, filePath)) { + IBinaryFile binFile; + try { + binFile = parser.getBinary(hintBuffer, filePath); + if (binFile != null && binFile instanceof IBinaryParser.IBinaryObject) { + return (IBinaryParser.IBinaryObject)binFile; + } + } catch (IOException e) { + Activator.getDefault().logError("Error parsing binary file", e); //$NON-NLS-1$ + } + } + } + + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/ColorSetting.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/ColorSetting.java new file mode 100644 index 0000000000..15c4d7dabc --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/ColorSetting.java @@ -0,0 +1,214 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Bernd Hufmann - Updated to use RGB for the tick color + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.colors; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; +import org.eclipse.ui.themes.ColorUtil; + +/** + * Class for storing color settings of a TMF filter. + * + * Application code must explicitly invoke the ColorSetting.dispose() method to release the operating system + * resources managed by each instance when those instances are no longer required. + * + * @version 1.0 + * @author Patrick Tasse + */ +public class ColorSetting { + + private RGB fForegroundRGB; + private RGB fBackgroundRGB; + private RGB fTickColorRGB; + private Color fForegroundColor; + private Color fBackgroundColor; + private Color fDimmedForegroundColor; + private Color fDimmedBackgroundColor; + private Color fTickColor; + private ITmfFilterTreeNode fFilter; + + /** + * Constructor + * + * You must dispose the color setting when it is no longer required. + * + * @param foreground + * The foreground color + * @param background + * The background color + * @param tickColorRGB + * The color for the checkbox ticks + * @param filter + * The filter tree node + */ + public ColorSetting(RGB foreground, RGB background, RGB tickColorRGB, ITmfFilterTreeNode filter) { + fForegroundRGB = foreground; + fBackgroundRGB = background; + fTickColorRGB = tickColorRGB; + fFilter = filter; + Display display = Display.getDefault(); + fForegroundColor = new Color(display, fForegroundRGB); + fBackgroundColor = new Color(display, fBackgroundRGB); + fDimmedForegroundColor = new Color(display, ColorUtil.blend( + fForegroundRGB, fBackgroundRGB)); + fDimmedBackgroundColor = new Color(display, ColorUtil.blend( + fBackgroundRGB, display.getSystemColor(SWT.COLOR_LIST_BACKGROUND).getRGB())); + fTickColor = new Color(display, fTickColorRGB); + } + + /** + * Dispose the color setting resources + */ + public void dispose() { + fForegroundColor.dispose(); + fBackgroundColor.dispose(); + fDimmedForegroundColor.dispose(); + fDimmedBackgroundColor.dispose(); + fTickColor.dispose(); + } + + /** + * Returns foreground RGB value. + * + * @return the foreground RGB + */ + public RGB getForegroundRGB() { + return fForegroundRGB; + } + + /** + * Sets the foreground RGB value + * + * @param foreground the foreground to set + */ + public void setForegroundRGB(RGB foreground) { + fForegroundRGB = foreground; + fForegroundColor.dispose(); + fDimmedForegroundColor.dispose(); + Display display = Display.getDefault(); + fForegroundColor = new Color(display, fForegroundRGB); + fDimmedForegroundColor = new Color(display, ColorUtil.blend( + fForegroundRGB, fBackgroundRGB)); + } + + /** + * Returns the background RGB value. + * + * @return the background RGB + */ + public RGB getBackgroundRGB() { + return fBackgroundRGB; + } + + /** + * Sets the background RGB value. + * + * @param background the background to set + */ + public void setBackgroundRGB(RGB background) { + fBackgroundRGB = background; + fBackgroundColor.dispose(); + fDimmedBackgroundColor.dispose(); + Display display = Display.getDefault(); + fBackgroundColor = new Color(display, fBackgroundRGB); + fDimmedBackgroundColor = new Color(display, ColorUtil.blend( + fBackgroundRGB, display.getSystemColor(SWT.COLOR_LIST_BACKGROUND).getRGB())); + } + + /** + * Returns the RGB of the tick color + * + * @return the RGB of the tick color + */ + public RGB getTickColorRGB() { + return fTickColorRGB; + } + + /** + * Sets the RGB of the tick color + * + * @param tickColorRGB the tick color TGB + */ + public void setTickColorRGB(RGB tickColorRGB) { + fTickColorRGB = tickColorRGB; + fTickColor.dispose(); + Display display = Display.getDefault(); + fTickColor = new Color(display, fTickColorRGB); + } + + /** + * Returns the filter implementation. + * @return the filter + */ + public ITmfFilterTreeNode getFilter() { + return fFilter; + } + + /** + * Sets the filter implementation. + * + * @param filter the filter to set + */ + public void setFilter(ITmfFilterTreeNode filter) { + fFilter = filter; + } + + /** + * Returns the foreground color. + * + * @return the foreground color + */ + public Color getForegroundColor() { + return fForegroundColor; + } + + /** + * Returns the background color. + * + * @return the background color + */ + public Color getBackgroundColor() { + return fBackgroundColor; + } + + /** + * Returns the dimmed foreground color. + * + * @return the dimmed foreground color + */ + public Color getDimmedForegroundColor() { + return fDimmedForegroundColor; + } + + /** + * Returns the dimmed background color. + * + * @return the dimmed background color + */ + public Color getDimmedBackgroundColor() { + return fDimmedBackgroundColor; + } + + /** + * Returns the tick color. + * + * @return the tick color + */ + public Color getTickColor() { + return fTickColor; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/ColorSettingsManager.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/ColorSettingsManager.java new file mode 100644 index 0000000000..7e6c7ce906 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/ColorSettingsManager.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Bernd Hufmann - Updated to use RGB for the tick color + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.colors; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * Static class for managing color settings. + * + * @version 1.0 + * @author Patrick Tasse + * + */ +public class ColorSettingsManager { + + // The color settings file name + private static final String COLOR_SETTINGS_FILE_NAME = "color_settings.xml"; //$NON-NLS-1$ + + // The path for the color settings file + private static final String COLOR_SETTINGS_PATH_NAME = + Activator.getDefault().getStateLocation().addTrailingSeparator().append(COLOR_SETTINGS_FILE_NAME).toString(); + + // The default color setting + private static final ColorSetting DEFAULT_COLOR_SETTING = new ColorSetting( + Display.getDefault().getSystemColor(SWT.COLOR_LIST_FOREGROUND).getRGB(), + Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND).getRGB(), + Display.getDefault().getSystemColor(SWT.COLOR_LIST_FOREGROUND).getRGB(), + null); + + /** + * Special value for priority if unknown. + */ + public static final int PRIORITY_NONE = Integer.MAX_VALUE; + + // The stored color settings + private static ColorSetting[] fColorSettings = ColorSettingsXML.load(COLOR_SETTINGS_PATH_NAME); + + // The listener list + private static List fListeners = new ArrayList<>(); + + /** + * Returns an array of color settings. + * + * @return an array of color settings. + */ + public static ColorSetting[] getColorSettings() { + return (fColorSettings != null) ? Arrays.copyOf(fColorSettings, fColorSettings.length) : null; + } + + /** + * Sets the array of color settings. + * + * @param colorSettings A array of color settings to set + */ + public static void setColorSettings(ColorSetting[] colorSettings) { + fColorSettings = (colorSettings != null) ? Arrays.copyOf(colorSettings, colorSettings.length) : null; + ColorSettingsXML.save(COLOR_SETTINGS_PATH_NAME, fColorSettings); + fireColorSettingsChanged(); + } + + /** + * Gets the color settings that matches the filter for given event. + * + * @param event + * The event to check + * + * @return color settings defined for filter if found else default color + * settings + */ + public static ColorSetting getColorSetting(ITmfEvent event) { + for (int i = 0; i < fColorSettings.length; i++) { + ColorSetting colorSetting = fColorSettings[i]; + if (colorSetting.getFilter() != null && colorSetting.getFilter().matches(event)) { + return colorSetting; + } + } + return DEFAULT_COLOR_SETTING; + } + + /** + * Gets the color settings priority for the given event. + * + * @param event A event the event to check + * @return the priority defined for the filter else PRIORITY_NONE + */ + public static int getColorSettingPriority(ITmfEvent event) { + for (int i = 0; i < fColorSettings.length; i++) { + ColorSetting colorSetting = fColorSettings[i]; + if (colorSetting.getFilter() != null && colorSetting.getFilter().matches(event)) { + return i; + } + } + return PRIORITY_NONE; + } + + /** + * Returns the color settings based the priority. + * + * @param priority A priority (index) of color settings + * @return the color settings defined for the priority else default color settings + */ + public static ColorSetting getColorSetting(int priority) { + if (priority < fColorSettings.length) { + return fColorSettings[priority]; + } + return DEFAULT_COLOR_SETTING; + } + + /** + * Adds a color settings listener. + * + * @param listener A listener to add. + */ + public static void addColorSettingsListener(IColorSettingsListener listener) { + if (! fListeners.contains(listener)) { + fListeners.add(listener); + } + } + + /** + * Removes a color settings listener. + * + * @param listener A listener to remove. + */ + public static void removeColorSettingsListener(IColorSettingsListener listener) { + fListeners.remove(listener); + } + + // Notify listeners + private static void fireColorSettingsChanged() { + for (IColorSettingsListener listener : fListeners) { + listener.colorSettingsChanged(fColorSettings); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/ColorSettingsXML.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/ColorSettingsXML.java new file mode 100644 index 0000000000..a123b25c6c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/ColorSettingsXML.java @@ -0,0 +1,221 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Bernd Hufmann - Updated to use RGB for the tick color + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.colors; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.eclipse.swt.graphics.RGB; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; +import org.eclipse.tracecompass.tmf.core.filter.xml.TmfFilterContentHandler; +import org.eclipse.tracecompass.tmf.core.filter.xml.TmfFilterXMLWriter; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.DefaultHandler; + +/** + * Class for saving and loading of color settings to/from file. + * + * @version 1.0 + * @author Patrick Tasse + * + */ +public class ColorSettingsXML { + + // XML Tags and attributes + private static final String COLOR_SETTINGS_TAG = "COLOR_SETTINGS"; //$NON-NLS-1$ + private static final String COLOR_SETTING_TAG = "COLOR_SETTING"; //$NON-NLS-1$ + private static final String FG_TAG = "FG"; //$NON-NLS-1$ + private static final String BG_TAG = "BG"; //$NON-NLS-1$ + private static final String R_ATTR = "R"; //$NON-NLS-1$ + private static final String G_ATTR = "G"; //$NON-NLS-1$ + private static final String B_ATTR = "B"; //$NON-NLS-1$ + private static final String TICK_TAG = "TICK"; //$NON-NLS-1$ + private static final String FILTER_TAG = "FILTER"; //$NON-NLS-1$ + + /** + * Saves the given color settings to file. + * + * @param pathName + * A file name with path + * @param colorSettings + * -An array of color settings to save. + */ + public static void save(String pathName, ColorSetting[] colorSettings) { + try { + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + Document document = documentBuilder.newDocument(); + + Element rootElement = document.createElement(COLOR_SETTINGS_TAG); + document.appendChild(rootElement); + + for (ColorSetting colorSetting : colorSettings) { + Element colorSettingElement = document.createElement(COLOR_SETTING_TAG); + rootElement.appendChild(colorSettingElement); + + Element fgElement = document.createElement(FG_TAG); + colorSettingElement.appendChild(fgElement); + RGB foreground = colorSetting.getForegroundRGB(); + fgElement.setAttribute(R_ATTR, Integer.toString(foreground.red)); + fgElement.setAttribute(G_ATTR, Integer.toString(foreground.green)); + fgElement.setAttribute(B_ATTR, Integer.toString(foreground.blue)); + + Element bgElement = document.createElement(BG_TAG); + colorSettingElement.appendChild(bgElement); + RGB background = colorSetting.getBackgroundRGB(); + bgElement.setAttribute(R_ATTR, Integer.toString(background.red)); + bgElement.setAttribute(G_ATTR, Integer.toString(background.green)); + bgElement.setAttribute(B_ATTR, Integer.toString(background.blue)); + + Element tickColorElement = document.createElement(TICK_TAG); + colorSettingElement.appendChild(tickColorElement); + RGB tickColor = colorSetting.getTickColorRGB(); + tickColorElement.setAttribute(R_ATTR, Integer.toString(tickColor.red)); + tickColorElement.setAttribute(G_ATTR, Integer.toString(tickColor.green)); + tickColorElement.setAttribute(B_ATTR, Integer.toString(tickColor.blue)); + + if (colorSetting.getFilter() != null) { + Element filterElement = document.createElement(FILTER_TAG); + colorSettingElement.appendChild(filterElement); + TmfFilterXMLWriter.buildXMLTree(document, colorSetting.getFilter(), filterElement); + } + } + + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + + Transformer transformer = transformerFactory.newTransformer(); + DOMSource source = new DOMSource(document); + StreamResult result = new StreamResult(new File(pathName)); + transformer.transform(source, result); + } catch (ParserConfigurationException e) { + Activator.getDefault().logError("Error saving color xml file: " + pathName, e); //$NON-NLS-1$ + } catch (TransformerConfigurationException e) { + Activator.getDefault().logError("Error saving color xml file: " + pathName, e); //$NON-NLS-1$ + } catch (TransformerException e) { + Activator.getDefault().logError("Error saving color xml file: " + pathName, e); //$NON-NLS-1$ + } + } + + /** + * Loads color settings from file and returns it in an array. + * + * @param pathName + * A file name with path + * + * @return the color settings array loaded from file + */ + public static ColorSetting[] load(String pathName) { + if (!new File(pathName).canRead()) { + return new ColorSetting[0]; + } + SAXParserFactory parserFactory = SAXParserFactory.newInstance(); + parserFactory.setNamespaceAware(true); + + ColorSettingsContentHandler handler = new ColorSettingsContentHandler(); + try { + XMLReader saxReader = parserFactory.newSAXParser().getXMLReader(); + saxReader.setContentHandler(handler); + saxReader.parse(pathName); + return handler.colorSettings.toArray(new ColorSetting[0]); + } catch (ParserConfigurationException e) { + Activator.getDefault().logError("Error loading color xml file: " + pathName, e); //$NON-NLS-1$ + } catch (SAXException e) { + Activator.getDefault().logError("Error loading color xml file: " + pathName, e); //$NON-NLS-1$ + } catch (IOException e) { + Activator.getDefault().logError("Error loading color xml file: " + pathName, e); //$NON-NLS-1$ + } + // In case of error, dispose the partial list of color settings + for (ColorSetting colorSetting : handler.colorSettings) { + colorSetting.dispose(); + } + return new ColorSetting[0]; + } + + // Helper class + private static class ColorSettingsContentHandler extends DefaultHandler { + + private List colorSettings = new ArrayList<>(0); + private RGB fg = new RGB(0, 0, 0); + private RGB bg = new RGB(255, 255, 255); + private RGB tickColor = new RGB(0, 0, 0); + private ITmfFilterTreeNode filter; + private TmfFilterContentHandler filterContentHandler; + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) + throws SAXException { + if (localName.equals(COLOR_SETTINGS_TAG)) { + colorSettings = new ArrayList<>(); + } else if (localName.equals(COLOR_SETTING_TAG)) { + fg = null; + bg = null; + filter = null; + } else if (localName.equals(FG_TAG)) { + int r = Integer.parseInt(attributes.getValue(R_ATTR)); + int g = Integer.parseInt(attributes.getValue(G_ATTR)); + int b = Integer.parseInt(attributes.getValue(B_ATTR)); + fg = new RGB(r, g, b); + } else if (localName.equals(BG_TAG)) { + int r = Integer.parseInt(attributes.getValue(R_ATTR)); + int g = Integer.parseInt(attributes.getValue(G_ATTR)); + int b = Integer.parseInt(attributes.getValue(B_ATTR)); + bg = new RGB(r, g, b); + } else if (localName.equals(TICK_TAG)) { + int r = Integer.parseInt(attributes.getValue(R_ATTR)); + int g = Integer.parseInt(attributes.getValue(G_ATTR)); + int b = Integer.parseInt(attributes.getValue(B_ATTR)); + tickColor = new RGB(r, g, b); + } else if (localName.equals(FILTER_TAG)) { + filterContentHandler = new TmfFilterContentHandler(); + } else if (filterContentHandler != null) { + filterContentHandler.startElement(uri, localName, qName, attributes); + } + } + + @Override + public void endElement(String uri, String localName, String qName) + throws SAXException { + if (localName.equals(COLOR_SETTINGS_TAG)) { + // Nothing to do + } else if (localName.equals(COLOR_SETTING_TAG)) { + ColorSetting colorSetting = new ColorSetting(fg, bg, tickColor, filter); + colorSettings.add(colorSetting); + } else if (localName.equals(FILTER_TAG)) { + filter = filterContentHandler.getTree(); + filterContentHandler = null; + } else if (filterContentHandler != null) { + filterContentHandler.endElement(uri, localName, qName); + } + } + + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/ColorsView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/ColorsView.java new file mode 100644 index 0000000000..a5081a0566 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/ColorsView.java @@ -0,0 +1,588 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Bernd Hufmann - Updated to use RGB for the tick color + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.colors; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.ColorDialog; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.ui.views.TmfView; +import org.eclipse.tracecompass.tmf.ui.views.filter.FilterDialog; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphColorScheme; +import org.eclipse.ui.IActionBars; + +/** + * Color view implementation. This view provides support for managing color settings for filters. + * + * @version 1.0 + * @author Patrick Tasse + * + */ +public class ColorsView extends TmfView { + + /** ID for the color view */ + public static final @NonNull String ID = "org.eclipse.linuxtools.tmf.ui.views.colors"; //$NON-NLS-1$ + + private static final Image ADD_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/add_button.gif"); //$NON-NLS-1$ + private static final Image DELETE_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/delete_button.gif"); //$NON-NLS-1$ + private static final Image MOVE_UP_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/moveup_button.gif"); //$NON-NLS-1$ + private static final Image MOVE_DOWN_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/movedown_button.gif"); //$NON-NLS-1$ + private static final Image IMPORT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/import_button.gif"); //$NON-NLS-1$ + private static final Image EXPORT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/export_button.gif"); //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Main data structures + // ------------------------------------------------------------------------ + + /** + * The composite shell. + */ + protected Shell fShell; + /** + * The main composite (scrolled composite) + */ + protected ScrolledComposite fScrolledComposite; + /** + * The list composite. + */ + protected Composite fListComposite; + /** + * The filler composite. + */ + protected Composite fFillerComposite; + /** + * The selected color settings row + */ + protected ColorSettingRow fSelectedRow = null; + /** + * The color scheme instance for managing colors + */ + protected TimeGraphColorScheme traceColorScheme = new TimeGraphColorScheme(); + /** + * An action to add a color settings row + */ + protected Action fAddAction; + /** + * An action to delete a color settings row + */ + protected Action fDeleteAction; + /** + * An action to move up a color settings row in the list. + */ + protected Action fMoveUpAction; + /** + * An action to move down a color settings row in the list. + */ + protected Action fMoveDownAction; + /** + * An action to import color settings from file. + */ + protected Action fImportAction; + /** + * An action to export color settings from file. + */ + protected Action fExportAction; + /** + * The list of existing color settings + */ + protected List fColorSettings; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Default Constructor + */ + public ColorsView() { + super("Colors"); //$NON-NLS-1$ + } + + @Override + public void createPartControl(Composite parent) { + fShell = parent.getShell(); + + fScrolledComposite = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL); + fScrolledComposite.setExpandHorizontal(true); + fScrolledComposite.setExpandVertical(true); + fListComposite = new Composite(fScrolledComposite, SWT.NONE); + fScrolledComposite.setContent(fListComposite); + + GridLayout gl = new GridLayout(); + gl.marginHeight = 0; + gl.marginWidth = 0; + gl.verticalSpacing = 1; + fListComposite.setLayout(gl); + + fColorSettings = new ArrayList<>(Arrays.asList(ColorSettingsManager.getColorSettings())); + for (ColorSetting colorSetting : fColorSettings) { + new ColorSettingRow(fListComposite, colorSetting); + } + + fFillerComposite = new Composite(fListComposite, SWT.NONE); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.heightHint = 0; + fFillerComposite.setLayoutData(gd); + gl = new GridLayout(); + gl.marginHeight = 1; + gl.marginWidth = 1; + fFillerComposite.setLayout(gl); + Label fillerLabel = new Label(fFillerComposite, SWT.NONE); + fillerLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + fillerLabel.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + + fFillerComposite.addPaintListener(new PaintListener() { + @Override + public void paintControl(PaintEvent e) { + if (fSelectedRow == null) { + Color lineColor = Display.getDefault().getSystemColor(SWT.COLOR_BLACK); + Point p = fFillerComposite.getSize(); + GC gc = e.gc; + gc.setForeground(lineColor); + gc.drawLine(0, 0, p.x - 1, 0); + } + } + }); + + MouseListener mouseListener = new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { + fSelectedRow = null; + refresh(); + } + }; + fillerLabel.addMouseListener(mouseListener); + + fScrolledComposite.setMinSize(fListComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + + fillToolBar(); + } + + @Override + public void setFocus() { + fScrolledComposite.setFocus(); + } + + /** + * Refreshes the view display and updates the view actions enablements. + */ + public void refresh() { + fListComposite.layout(); + fScrolledComposite.setMinSize(fListComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + fListComposite.redraw(0, 0, fListComposite.getBounds().width, fListComposite.getBounds().height, true); + if (fSelectedRow == null) { + fDeleteAction.setEnabled(false); + fMoveUpAction.setEnabled(false); + fMoveDownAction.setEnabled(false); + } else { + fDeleteAction.setEnabled(true); + fMoveUpAction.setEnabled(true); + fMoveDownAction.setEnabled(true); + } + } + + private void fillToolBar() { + + fAddAction = new AddAction(); + fAddAction.setImageDescriptor(ImageDescriptor.createFromImage(ADD_IMAGE)); + fAddAction.setToolTipText(Messages.ColorsView_AddActionToolTipText); + + fDeleteAction = new DeleteAction(); + fDeleteAction.setImageDescriptor(ImageDescriptor.createFromImage(DELETE_IMAGE)); + fDeleteAction.setToolTipText(Messages.ColorsView_DeleteActionToolTipText); + fDeleteAction.setEnabled(false); + + fMoveUpAction = new MoveUpAction(); + fMoveUpAction.setImageDescriptor(ImageDescriptor.createFromImage(MOVE_UP_IMAGE)); + fMoveUpAction.setToolTipText(Messages.ColorsView_MoveUpActionToolTipText); + fMoveUpAction.setEnabled(false); + + fMoveDownAction = new MoveDownAction(); + fMoveDownAction.setImageDescriptor(ImageDescriptor.createFromImage(MOVE_DOWN_IMAGE)); + fMoveDownAction.setToolTipText(Messages.ColorsView_MoveDownActionToolTipText); + fMoveDownAction.setEnabled(false); + + fExportAction = new ExportAction(); + fExportAction.setImageDescriptor(ImageDescriptor.createFromImage(EXPORT_IMAGE)); + fExportAction.setToolTipText(Messages.ColorsView_ExportActionToolTipText); + + fImportAction = new ImportAction(); + fImportAction.setImageDescriptor(ImageDescriptor.createFromImage(IMPORT_IMAGE)); + fImportAction.setToolTipText(Messages.ColorsView_ImportActionToolTipText); + + IActionBars bars = getViewSite().getActionBars(); + IToolBarManager manager = bars.getToolBarManager(); + manager.add(fAddAction); + manager.add(fDeleteAction); + manager.add(fMoveUpAction); + manager.add(fMoveDownAction); + manager.add(new Separator()); + manager.add(fExportAction); + manager.add(fImportAction); + } + + private class AddAction extends Action { + @Override + public void run() { + ColorSetting colorSetting = new ColorSetting( + Display.getDefault().getSystemColor(SWT.COLOR_LIST_FOREGROUND).getRGB(), + Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND).getRGB(), + Display.getDefault().getSystemColor(SWT.COLOR_LIST_FOREGROUND).getRGB(), + null); + ColorSettingRow row = new ColorSettingRow(fListComposite, colorSetting); + if (fSelectedRow == null) { + fColorSettings.add(colorSetting); + row.moveAbove(fFillerComposite); + } else { + fColorSettings.add(fColorSettings.indexOf(fSelectedRow.getColorSetting()), colorSetting); + row.moveAbove(fSelectedRow); + } + fSelectedRow = row; + refresh(); + ColorSettingsManager.setColorSettings(fColorSettings.toArray(new ColorSetting[0])); + } + } + + private class DeleteAction extends Action { + + @Override + public void run() { + if (fSelectedRow != null) { + int index = fColorSettings.indexOf(fSelectedRow.getColorSetting()); + fColorSettings.remove(index); + fSelectedRow.fColorSetting.dispose(); + fSelectedRow.dispose(); + if (index < fColorSettings.size()) { + fSelectedRow = (ColorSettingRow) fListComposite.getChildren()[index]; + } else { + fSelectedRow = null; + } + refresh(); + ColorSettingsManager.setColorSettings(fColorSettings.toArray(new ColorSetting[0])); + } + } + } + + private class MoveUpAction extends Action { + @Override + public void run() { + if (fSelectedRow != null) { + int index = fColorSettings.indexOf(fSelectedRow.getColorSetting()); + if (index > 0) { + fColorSettings.add(index - 1, fColorSettings.remove(index)); + fSelectedRow.moveAbove(fListComposite.getChildren()[index - 1]); + refresh(); + ColorSettingsManager.setColorSettings(fColorSettings.toArray(new ColorSetting[0])); + } + } + } + } + + private class MoveDownAction extends Action { + @Override + public void run() { + if (fSelectedRow != null) { + int index = fColorSettings.indexOf(fSelectedRow.getColorSetting()); + if (index < fColorSettings.size() - 1) { + fColorSettings.add(index + 1, fColorSettings.remove(index)); + + fSelectedRow.moveBelow(fListComposite.getChildren()[index + 1]); + refresh(); + ColorSettingsManager.setColorSettings(fColorSettings.toArray(new ColorSetting[0])); + } + } + } + } + + private class ExportAction extends Action { + @Override + public void run() { + FileDialog fileDialog = new FileDialog(fShell, SWT.SAVE); + fileDialog.setFilterExtensions(new String[] {"*.xml"}); //$NON-NLS-1$ + fileDialog.setOverwrite(true); + String pathName = fileDialog.open(); + if (pathName != null) { + ColorSettingsXML.save(pathName, fColorSettings.toArray(new ColorSetting[0])); + } + } + } + + private class ImportAction extends Action { + @Override + public void run() { + FileDialog fileDialog = new FileDialog(fShell, SWT.OPEN); + fileDialog.setFilterExtensions(new String[] {"*.xml"}); //$NON-NLS-1$ + String pathName = fileDialog.open(); + if (pathName != null) { + ColorSetting[] colorSettings = ColorSettingsXML.load(pathName); + if (colorSettings.length > 0) { + if (fColorSettings.size() > 0) { + boolean overwrite = MessageDialog.openQuestion(fShell, + Messages.ColorsView_ImportOverwriteDialogTitle, + Messages.ColorsView_ImportOverwriteDialogMessage1 + + Messages.ColorsView_ImportOverwriteDialogMessage2); + if (overwrite) { + for (Control control : fListComposite.getChildren()) { + if (control instanceof ColorSettingRow) { + ((ColorSettingRow) control).fColorSetting.dispose(); + control.dispose(); + } + } + fColorSettings = new ArrayList<>(); + fSelectedRow = null; + } + } + for (ColorSetting colorSetting : colorSettings) { + ColorSettingRow row = new ColorSettingRow(fListComposite, colorSetting); + if (fSelectedRow == null) { + fColorSettings.add(colorSetting); + row.moveAbove(fFillerComposite); + } else { + fColorSettings.add(fColorSettings.indexOf(fSelectedRow.getColorSetting()), colorSetting); + row.moveAbove(fSelectedRow); + } + } + refresh(); + ColorSettingsManager.setColorSettings(fColorSettings.toArray(new ColorSetting[0])); + } + } + } + } + + private class ColorSettingRow extends Composite { + + ColorSetting fColorSetting; + + public ColorSettingRow(final Composite parent, final ColorSetting colorSetting) { + super(parent, SWT.NONE); + fColorSetting = colorSetting; + + setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + + setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + GridLayout gl = new GridLayout(7, false); + gl.marginHeight = 1; + gl.marginWidth = 1; + gl.horizontalSpacing = 1; + gl.verticalSpacing = 0; + setLayout(gl); + + final Button fgButton = new Button(this, SWT.PUSH); + fgButton.setText(Messages.ColorsView_ForegroundButtonText); + fgButton.setSize(fgButton.computeSize(SWT.DEFAULT, 19)); + fgButton.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + + final Button bgButton = new Button(this, SWT.PUSH); + bgButton.setText(Messages.ColorsView_BackgroundButtonText); + bgButton.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + + final Composite labelComposite = new Composite(this, SWT.NONE); + labelComposite.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, false, false)); + gl = new GridLayout(); + gl.marginHeight = 0; + gl.marginWidth = 0; + labelComposite.setLayout(gl); + labelComposite.setBackground(colorSetting.getBackgroundColor()); + + final Label label = new Label(labelComposite, SWT.NONE); + label.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, true)); + label.setText(" Text "); //$NON-NLS-1$ + label.setForeground(colorSetting.getForegroundColor()); + label.setBackground(colorSetting.getBackgroundColor()); + + fgButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + fSelectedRow = ColorSettingRow.this; + refresh(); + ColorDialog dialog = new ColorDialog(fShell); + dialog.setRGB(colorSetting.getForegroundRGB()); + dialog.setText(Messages.ColorsView_ForegroundDialogText); + dialog.open(); + RGB rgb = dialog.getRGB(); + if (rgb != null) { + colorSetting.setForegroundRGB(rgb); + ColorSettingsManager.setColorSettings(fColorSettings.toArray(new ColorSetting[0])); + label.setForeground(colorSetting.getForegroundColor()); + } + }}); + + bgButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + fSelectedRow = ColorSettingRow.this; + refresh(); + ColorDialog dialog = new ColorDialog(fShell); + dialog.setRGB(colorSetting.getBackgroundRGB()); + dialog.setText(Messages.ColorsView_BackgroundDialogText); + dialog.open(); + RGB rgb = dialog.getRGB(); + if (rgb != null) { + colorSetting.setBackgroundRGB(rgb); + ColorSettingsManager.setColorSettings(fColorSettings.toArray(new ColorSetting[0])); + labelComposite.setBackground(colorSetting.getBackgroundColor()); + label.setBackground(colorSetting.getBackgroundColor()); + } + }}); + + final Button tickButton = new Button(this, SWT.PUSH); + tickButton.setText(Messages.ColorsView_TickButtonText); + tickButton.setSize(tickButton.computeSize(SWT.DEFAULT, 19)); + tickButton.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + + final Canvas tickCanvas = new Canvas(this, SWT.NONE); + GridData gd = new GridData(SWT.CENTER, SWT.FILL, false, false); + gd.widthHint = 12; + gd.heightHint = bgButton.getSize().y; + tickCanvas.setLayoutData(gd); + tickCanvas.setBackground(traceColorScheme.getBkColor(false, false, false)); + tickCanvas.addPaintListener(new PaintListener() { + @Override + public void paintControl(PaintEvent e) { + Rectangle bounds = tickCanvas.getBounds(); + e.gc.setForeground(traceColorScheme.getColor(TimeGraphColorScheme.MID_LINE)); + int midy = bounds.y + bounds.height / 2 - 1; + //int midy = e.y + e.height / 2; + e.gc.drawLine(e.x, midy, e.x + e.width, midy); + Rectangle rect = new Rectangle(e.x + 1, bounds.y + 2, 0, bounds.height - 6); + for (int i = 1; i <= 3; i++) { + rect.x += i; + rect.width = i; + e.gc.setBackground(fColorSetting.getTickColor()); + e.gc.fillRectangle(rect); + } + }}); + + tickButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + fSelectedRow = ColorSettingRow.this; + ColorDialog dialog = new ColorDialog(fShell); + dialog.setRGB(colorSetting.getTickColorRGB()); + dialog.setText(Messages.TickColorDialog_TickColorDialogTitle); + dialog.open(); + RGB rgb = dialog.getRGB(); + if (rgb != null) { + colorSetting.setTickColorRGB(rgb); + ColorSettingsManager.setColorSettings(fColorSettings.toArray(new ColorSetting[0])); + refresh(); + } + }}); + + final Button filterButton = new Button(this, SWT.PUSH); + filterButton.setText(Messages.ColorsView_FilterButtonText); + filterButton.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + + final Label filterText = new Label(this, SWT.NONE); + if (colorSetting.getFilter() != null) { + filterText.setText(colorSetting.getFilter().toString()); + filterText.setToolTipText(colorSetting.getFilter().toString()); + } + filterText.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + filterText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + filterButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + fSelectedRow = ColorSettingRow.this; + refresh(); + FilterDialog dialog = new FilterDialog(fShell); + dialog.setFilter(colorSetting.getFilter()); + dialog.open(); + if (dialog.getReturnCode() == Window.OK) { + if (dialog.getFilter() != null) { + colorSetting.setFilter(dialog.getFilter()); + filterText.setText(dialog.getFilter().toString()); + filterText.setToolTipText(dialog.getFilter().toString()); + } else { + colorSetting.setFilter(null); + filterText.setText(""); //$NON-NLS-1$ + filterText.setToolTipText(""); //$NON-NLS-1$ + } + ColorSettingsManager.setColorSettings(fColorSettings.toArray(new ColorSetting[0])); + refresh(); + } + }}); + + addPaintListener(new PaintListener() { + @Override + public void paintControl(PaintEvent e) { + if (fSelectedRow == ColorSettingRow.this) { + Color borderColor = Display.getDefault().getSystemColor(SWT.COLOR_BLACK); + Point p = ColorSettingRow.this.getSize(); + Rectangle rect = new Rectangle(0, 0, p.x - 1, p.y - 1); + GC gc = e.gc; + gc.setForeground(borderColor); + gc.drawRectangle(rect); + } + } + }); + + MouseListener mouseListener = new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { + fSelectedRow = ColorSettingRow.this; + refresh(); + } + }; + addMouseListener(mouseListener); + label.addMouseListener(mouseListener); + tickCanvas.addMouseListener(mouseListener); + filterText.addMouseListener(mouseListener); + } + + /** + * @return the ColorSetting + */ + public ColorSetting getColorSetting() { + return fColorSetting; + } + + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/IColorSettingsListener.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/IColorSettingsListener.java new file mode 100644 index 0000000000..629dbf1c79 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/colors/IColorSettingsListener.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.colors; + +/** + * A color change listener + * + * @version 1.0 + * @author Patrick Tasse + */ +public interface IColorSettingsListener { + + /** + * Notify the listener that the color settings have changed. + * + * @param colorSettings + * The new color settings + */ + void colorSettingsChanged(ColorSetting[] colorSettings); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/distribution/model/BaseDistributionData.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/distribution/model/BaseDistributionData.java new file mode 100644 index 0000000000..3d9201ae60 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/distribution/model/BaseDistributionData.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * Copyright (c) 2011, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Francois Chouinard - Moved from LTTng to TMF + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.distribution.model; + +/** + * Class with basic distribution data used for distribution models. + * + * It stores number of events (with timestamp) in buckets with a start time and a + * certain duration. The duration is the same across all buckets. + * Note that Timestamps are stored as long values. + * + * @version 1.0 + * @author Bernd Hufmann + */ +public class BaseDistributionData { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * Constant indication that bucket is not filled. + */ + public final static int OUT_OF_RANGE_BUCKET = -1; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * Number of buckets + */ + protected final int fNbBuckets; + /** + * Duration of each bucket + */ + protected long fBucketDuration; + /** + * Bucket index of last event time + */ + protected int fLastBucket; + /** + * Timestamp of the first bucket. (could be negative when analyzing events with descending time!!!) + */ + protected long fFirstBucketTime; + /** + * Timestamp of the first event + */ + protected long fFirstEventTime; + /** + * Timestamp of the last event + */ + protected long fLastEventTime; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructs a base distribution data object. + * @param nbBuckets A total number of buckets + */ + public BaseDistributionData(int nbBuckets) { + fNbBuckets = nbBuckets; + clear(); + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + /** + * Returns the total number of buckets. + * + * @return the number of buckets. + */ + public int getNbBuckets() { + return fNbBuckets; + } + + /** + * Returns the duration of buckets. + * + * @return bucket duration + */ + public long getBucketDuration() { + return fBucketDuration; + } + + /** + * Set the bucket duration. + * + * @param bucketDuration The duration to set. + */ + public void setBucketDuration(long bucketDuration) { + fBucketDuration = bucketDuration; + } + + /** + * Returns the index of the last used bucket. + * + * @return last bucket index. + */ + public int getLastBucket() { + return fLastBucket; + } + + /** + * Sets the index of the last bucket used. + * + * @param lastBucket The last bucket index to set. + */ + public void setLastBucket(int lastBucket) { + fLastBucket = lastBucket; + } + + /** + * Returns the start time of the first bucket. + * + * @return first bucket time. + */ + public long getFirstBucketTime() { + return fFirstBucketTime; + } + + /** + * Sets the start time of the first bucket. + * + * @param firstBucketTime The bucket time to ser. + */ + public void setFirstBucketTime(long firstBucketTime) { + fFirstBucketTime = firstBucketTime; + } + + /** + * Returns the start time of the last bucket used. + * + * @return the start time of the last bucket. + */ + public long getLastBucketTime() { + return getBucketStartTime(fLastBucket); + } + + /** + * Returns the time of the event with the lowest timestamp. + * + * @return first event time. + */ + public long getFirstEventTime() { + return fFirstEventTime; + } + + /** + * Sets the time of the event with the lowest timestamp. + * + * @param firstEventTime The first event time to set. + */ + public void setFirstEventTime(long firstEventTime) { + fFirstEventTime = firstEventTime; + } + + /** + * Returns the time of the event with the biggest timestamp. + * + * @return the last event time. + */ + public long getLastEventTime() { + return fLastEventTime; + } + + /** + * Sets the time of the event with the biggest timestamp. + * + * @param lastEventTime The last event time to set. + */ + public void setLastEventTime(long lastEventTime) { + fLastEventTime = lastEventTime; + } + + /** + * Returns the bucket start time of a given bucket index. + * + * @param index The bucket index. + * @return the bucket start time of a given bucket index. + */ + public long getBucketStartTime(int index) { + return fFirstBucketTime + index * fBucketDuration; + } + + /** + * Returns the bucket end time of a given bucket index. + * + * @param index The bucket index. + * @return the bucket start time of a given bucket index. + */ + public long getBucketEndTime(int index) { + return getBucketStartTime(index) + fBucketDuration; + } + + /** + * Returns the bucket index of the bucket containing a given time. + * + * @param time The timestamp to check. + * @return the bucket index of the bucket containing the given time. + */ + public int getIndex(long time) { + return (int)((time - fFirstBucketTime) / fBucketDuration); + } + + /** + * Check if an index is valid. + * + * @param index + * The index to check + * @return If it's valid, true or false. + */ + public boolean isIndexValid(int index) { + return ((index >= 0) && (index <= fNbBuckets - 1)); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Clears the data model to default values. + */ + public void clear() { + fFirstBucketTime = 0; + fFirstEventTime = 0; + fLastEventTime = 0; + fLastBucket = 0; + fBucketDuration = 1; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/distribution/model/IBaseDistributionModel.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/distribution/model/IBaseDistributionModel.java new file mode 100644 index 0000000000..34ba642ec6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/distribution/model/IBaseDistributionModel.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Francois Chouinard - Moved from LTTng to TMF + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.distribution.model; + +/** + * Base distribution model interface. + * + * Distribution models such histograms need to implement this interface. + * + * @version 1.0 + * @author Bernd Hufmann + * + */ +public interface IBaseDistributionModel { + /** + * Complete the model (all data received) + */ + void complete(); + + /** + * Clear the model (delete all data). + */ + void clear(); +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/CopyHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/CopyHandler.java new file mode 100644 index 0000000000..9acb2ced8f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/CopyHandler.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2013 Kalray + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xavier Raynaud - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.filter; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.util.LocalSelectionTransfer; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * Handler for copy command in filter view + * @author Xavier Raynaud + * @since 3.0 + */ +public class CopyHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + IWorkbenchPage page = window.getActivePage(); + FilterView part = (FilterView) page.getActivePart(); + ISelection selection = getSelection(part); + + LocalSelectionTransfer.getTransfer().setSelection(selection); + LocalSelectionTransfer.getTransfer().setSelectionSetTime(System.currentTimeMillis()); + return null; + } + + /** + * Retrieve the current selection + * + * @param tcv + * the FilterView + * @return the current selection in the FilterView + */ + protected ISelection getSelection(FilterView tcv) { + return tcv.getViewSite().getSelectionProvider().getSelection(); + } + + @Override + public boolean isEnabled() { + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return false; + } + + // Get the selection + IWorkbenchPage page = window.getActivePage(); + IWorkbenchPart part = page.getActivePart(); + if (part instanceof FilterView) { + FilterView tcv = (FilterView) part; + ISelection selection = tcv.getSite().getSelectionProvider().getSelection(); + if (!selection.isEmpty()) { + return true; + } + } + return false; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/CutHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/CutHandler.java new file mode 100644 index 0000000000..f76396d0cc --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/CutHandler.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2013 Kalray + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xavier Raynaud - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.filter; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; + +/** + * Handler for cut command in filter view + * @author Xavier Raynaud + * @since 3.0 + */ +public class CutHandler extends CopyHandler { + + @Override + protected ISelection getSelection(FilterView tcv) { + ISelection sel = super.getSelection(tcv); + if (sel instanceof IStructuredSelection) { + IStructuredSelection selection = (IStructuredSelection) sel; + Object o = selection.getFirstElement(); + if (o instanceof ITmfFilterTreeNode) { + ITmfFilterTreeNode node = (ITmfFilterTreeNode) o; + node = node.remove(); + tcv.refresh(); + return new StructuredSelection(node); + } + } + return sel; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/DeleteHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/DeleteHandler.java new file mode 100644 index 0000000000..bb01f0eb34 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/DeleteHandler.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2013 Kalray + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xavier Raynaud - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.filter; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * Handler for delete command in filter view + * @author Xavier Raynaud + * @since 3.0 + */ +public class DeleteHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + IWorkbenchPage page = window.getActivePage(); + FilterView part = (FilterView) page.getActivePart(); + ISelection sel = part.getViewSite().getSelectionProvider().getSelection(); + if (sel instanceof IStructuredSelection) { + IStructuredSelection selection = (IStructuredSelection) sel; + Object o = selection.getFirstElement(); + if (o instanceof ITmfFilterTreeNode) { + ITmfFilterTreeNode node = (ITmfFilterTreeNode) o; + node = node.remove(); + part.refresh(); + } + } + return null; + } + + @Override + public boolean isEnabled() { + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return false; + } + + // Get the selection + IWorkbenchPage page = window.getActivePage(); + IWorkbenchPart part = page.getActivePart(); + if (part instanceof FilterView) { + FilterView tcv = (FilterView) part; + ISelection selection = tcv.getSite().getSelectionProvider().getSelection(); + if (!selection.isEmpty()) { + return true; + } + } + return false; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterDialog.java new file mode 100644 index 0000000000..43707c8d98 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterDialog.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.filter; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterNode; + +/** + * The dialog for user-defined filters. + * + * @version 1.0 + * @author Patrick Tasse + */ +public class FilterDialog extends Dialog { + + TmfFilterNode fRoot; + FilterViewer fViewer; + + /** + * Constructor. + * + * @param shell + * The shell to which this dialog is attached + */ + public FilterDialog(Shell shell) { + super(shell); + setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX); + } + + @Override + protected Control createDialogArea(Composite parent) { + getShell().setText(Messages.FilterDialog_FilterDialogTitle); + getShell().setMinimumSize(getShell().computeSize(500, 200)); + Composite composite = (Composite) super.createDialogArea(parent); + + fViewer = new FilterViewer(composite, SWT.BORDER); + fViewer.setInput(fRoot); + return composite; + } + + /** + * @param filter + * the filter to set + */ + public void setFilter(ITmfFilterTreeNode filter) { + fRoot = new TmfFilterNode(null); + if (filter != null) { + fRoot.addChild(filter.clone()); + } + if (fViewer != null) { + fViewer.setInput(fRoot); + } + } + + /** + * @return the filter + */ + public ITmfFilterTreeNode getFilter() { + if (fRoot != null && fRoot.hasChildren()) { + return fRoot.getChild(0).clone(); + } + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterDragSourceAdapter.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterDragSourceAdapter.java new file mode 100644 index 0000000000..ef05bd431f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterDragSourceAdapter.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2013 Kalray + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xavier Raynaud - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.filter; + +import org.eclipse.jface.util.LocalSelectionTransfer; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DragSourceAdapter; +import org.eclipse.swt.dnd.DragSourceEvent; +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; + +/** + * DragSourceListener for filter view + * @author Xavier Raynaud + */ +class FilterDragSourceAdapter extends DragSourceAdapter { + + private FilterViewer fViewer; + + /** + * Constructor + * + * @param viewer + * the content of the FilterView + */ + public FilterDragSourceAdapter(FilterViewer viewer) { + super(); + this.fViewer = viewer; + } + + @Override + public void dragStart(DragSourceEvent event) { + ISelection s = fViewer.getTreeViewer().getSelection(); + LocalSelectionTransfer.getTransfer().setSelection(s); + LocalSelectionTransfer.getTransfer().setSelectionSetTime(event.time & 0xFFFFFFFFL); + } + + @Override + public void dragSetData(DragSourceEvent event) { + event.data = LocalSelectionTransfer.getTransfer().getSelection(); + } + + @Override + public void dragFinished(DragSourceEvent event) { + if (event.detail == DND.DROP_MOVE) { + IStructuredSelection selection = (IStructuredSelection) LocalSelectionTransfer.getTransfer().getSelection(); + for (Object data : selection.toList()) { + if (data instanceof ITmfFilterTreeNode) { + ITmfFilterTreeNode e = (ITmfFilterTreeNode) data; + e.remove(); + fViewer.refresh(); + } + } + } + LocalSelectionTransfer.getTransfer().setSelection(null); + LocalSelectionTransfer.getTransfer().setSelectionSetTime(0); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterDropTargetAdapter.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterDropTargetAdapter.java new file mode 100644 index 0000000000..557f77e670 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterDropTargetAdapter.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright (c) 2013 Kalray + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xavier Raynaud - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.filter; + + +import org.eclipse.jface.util.LocalSelectionTransfer; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DropTargetAdapter; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterNode; + +/** + * DropTargetListener for filter view + * @author Xavier Raynaud + */ +class FilterDropTargetAdapter extends DropTargetAdapter { + + private FilterViewer fViewer; + + /** + * Constructor + * @param viewer the content of the FilterView + */ + public FilterDropTargetAdapter(FilterViewer viewer) { + super(); + this.fViewer = viewer; + } + + /** + * Returns true if droppedNode is an ancestor of node. + * + * @param droppedNode + * the ITmfFilterTreeNode to drop or paste + * @param node + * the ITmfFilterTreeNode receiving a new child + * @return true if droppedNode is and ancestor of node, + * false otherwise. + */ + private static boolean isAncestor(ITmfFilterTreeNode droppedNode, ITmfFilterTreeNode node) { + ITmfFilterTreeNode tmp = node; + + while (tmp != null) { + ITmfFilterTreeNode n = tmp.getParent(); + if (n == droppedNode) { + return true; + } + tmp = n; + } + return false; + } + + @Override + public void dropAccept(DropTargetEvent event) { + ITmfFilterTreeNode treeNodeToDrop = null; + if (LocalSelectionTransfer.getTransfer().isSupportedType(event.currentDataType)) { + treeNodeToDrop = FilterEditUtils.getTransferredTreeNode(); + } + if (treeNodeToDrop == null) { + // should never occur + event.detail = DND.DROP_NONE; + return; + } + if (event.item instanceof TreeItem) { + Object data = event.item.getData(); + if (data instanceof ITmfFilterTreeNode) { + ITmfFilterTreeNode node = (ITmfFilterTreeNode) data; + if (node.getValidChildren().contains(treeNodeToDrop.getNodeName())) { + if (isAncestor(treeNodeToDrop, node) && event.detail != DND.DROP_COPY) { + // do nothing in this case + event.detail = DND.DROP_NONE; + } + return; + } + } + } else { // accept only TmfFilterNode + if (!TmfFilterNode.NODE_NAME.equals(treeNodeToDrop.getNodeName())) { + event.detail = DND.DROP_NONE; + } + return; + } + event.detail = DND.DROP_NONE; + return; + } + + @Override + public void drop(DropTargetEvent event) { + ITmfFilterTreeNode treeNodeToDrop = FilterEditUtils.getTransferredTreeNode(); + if (event.item instanceof TreeItem) { + Object data = event.item.getData(); + if (data instanceof ITmfFilterTreeNode) { + ITmfFilterTreeNode node = (ITmfFilterTreeNode) data; + if (node.getValidChildren().contains(treeNodeToDrop.getNodeName())) { + treeNodeToDrop = treeNodeToDrop.clone(); + node.addChild(treeNodeToDrop); + fViewer.refresh(); + fViewer.setSelection(treeNodeToDrop, true); + return; + } + } + } else { // accept only TmfFilterNode + if (TmfFilterNode.NODE_NAME.equals(treeNodeToDrop.getNodeName())) { + ITmfFilterTreeNode root = fViewer.getInput(); + treeNodeToDrop = treeNodeToDrop.clone(); + root.addChild(treeNodeToDrop); + fViewer.refresh(); + fViewer.setSelection(treeNodeToDrop, true); + return; + } + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterEditUtils.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterEditUtils.java new file mode 100644 index 0000000000..7766d8f63c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterEditUtils.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2013 Kalray + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xavier Raynaud - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.filter; + +import org.eclipse.jface.util.LocalSelectionTransfer; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; + +/** + * Utilities for cut/copy/paste/dnd in filter view + * @author Xavier Raynaud + */ +class FilterEditUtils { + + /** + * Gets the ITmfFilterTreeNode in LocalSelectionTransfer, if any + * @return a ITmfFilterTreeNode or null + */ + public static ITmfFilterTreeNode getTransferredTreeNode() { + ITmfFilterTreeNode treeNodeToDrop = null; + ISelection sel = LocalSelectionTransfer.getTransfer().getSelection(); + if (sel instanceof IStructuredSelection) { + IStructuredSelection selection = (IStructuredSelection) sel; + for (Object data : selection.toList()) { + if (!(data instanceof ITmfFilterTreeNode)) { + return null; + } else if (treeNodeToDrop != null) { + // should never occur, since tree has SWT.SINGLE style + return null; + } else { + treeNodeToDrop = (ITmfFilterTreeNode) data; + } + } + } + return treeNodeToDrop; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterManager.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterManager.java new file mode 100644 index 0000000000..fecd173708 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterManager.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.filter; + +import java.io.FileNotFoundException; +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterRootNode; +import org.eclipse.tracecompass.tmf.core.filter.xml.TmfFilterXMLParser; +import org.eclipse.tracecompass.tmf.core.filter.xml.TmfFilterXMLWriter; +import org.xml.sax.SAXException; + +/** + * Central filter manager + * + * @version 1.0 + * @author Patrick Tasse + */ +public class FilterManager { + + private static final String SAVED_FILTERS_FILE_NAME = "saved_filters.xml"; //$NON-NLS-1$ + private static final String SAVED_FILTERS_PATH_NAME = + Activator.getDefault().getStateLocation().addTrailingSeparator().append(SAVED_FILTERS_FILE_NAME).toString(); + + private static ITmfFilterTreeNode fRoot = new TmfFilterRootNode(); + static { + try { + fRoot = new TmfFilterXMLParser(SAVED_FILTERS_PATH_NAME).getTree(); + } catch (FileNotFoundException e) { + } catch (SAXException e) { + Activator.getDefault().logError("Error parsing saved filter xml file: " + SAVED_FILTERS_PATH_NAME, e); //$NON-NLS-1$ + } catch (IOException e) { + Activator.getDefault().logError("Error parsing saved filter xml file: " + SAVED_FILTERS_PATH_NAME, e); //$NON-NLS-1$ + } + } + + /** + * Retrieve the currently saved filters + * + * @return The array of filters + */ + public static ITmfFilterTreeNode[] getSavedFilters() { + return fRoot.clone().getChildren(); + } + + /** + * Set the passed filters as the currently saved ones. + * + * @param filters + * The filters to save + */ + public static void setSavedFilters(ITmfFilterTreeNode[] filters) { + fRoot = new TmfFilterRootNode(); + for (ITmfFilterTreeNode filter : filters) { + fRoot.addChild(filter.clone()); + } + try { + TmfFilterXMLWriter writerXML = new TmfFilterXMLWriter(fRoot); + writerXML.saveTree(SAVED_FILTERS_PATH_NAME); + } catch (ParserConfigurationException e) { + Activator.getDefault().logError("Error saving filter xml file: " + SAVED_FILTERS_PATH_NAME, e); //$NON-NLS-1$ + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterTreeContentProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterTreeContentProvider.java new file mode 100644 index 0000000000..ec9ec29cb9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterTreeContentProvider.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Yuriy Vashchuk - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.filter; + +import java.util.ArrayList; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; + +/** + * This is the Content Provider of our tree + * + * @version 1.0 + * @author Yuriy Vashchuk + */ +public class FilterTreeContentProvider implements ITreeContentProvider { + + @Override + public void dispose() { + // TODO Auto-generated method stub + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + // TODO Auto-generated method stub + } + + @Override + public Object[] getElements(Object inputElement) { + if (inputElement instanceof ITmfFilterTreeNode) { + ArrayList result = new ArrayList<>(); + for (int i = 0; i < ((ITmfFilterTreeNode) inputElement).getChildrenCount(); i++) { + result.add(((ITmfFilterTreeNode) inputElement).getChild(i)); + } + + return result.toArray(); + } + return null; + } + + @Override + public Object[] getChildren(Object parentElement) { + ArrayList result = new ArrayList<>(); + for (int i = 0; i < ((ITmfFilterTreeNode) parentElement).getChildrenCount(); i++) { + result.add(((ITmfFilterTreeNode) parentElement).getChild(i)); + } + return result.toArray(); + } + + @Override + public Object getParent(Object element) { + return ((ITmfFilterTreeNode) element).getParent(); + } + + @Override + public boolean hasChildren(Object element) { + return ((ITmfFilterTreeNode) element).hasChildren(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterTreeLabelProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterTreeLabelProvider.java new file mode 100644 index 0000000000..53bb2caef1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterTreeLabelProvider.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Yuriy Vashchuk - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.filter; + +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterAndNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterCompareNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterContainsNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterEqualsNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterEventTypeNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterMatchesNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterOrNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterCompareNode.Type; + +/** + * This is the Label Provider for our Filter Tree + * + * @version 1.0 + * @author Yuriy Vashchuk + */ +public class FilterTreeLabelProvider implements ILabelProvider { + + @Override + public void addListener(ILabelProviderListener listener) { + // TODO Auto-generated method stub + } + + @Override + public void dispose() { + // TODO Auto-generated method stub + } + + @Override + public boolean isLabelProperty(Object element, String property) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void removeListener(ILabelProviderListener listener) { + // TODO Auto-generated method stub + } + + @Override + public Image getImage(Object element) { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getText(Object element) { + String label = null; + + if (element instanceof TmfFilterNode) { + + TmfFilterNode node = (TmfFilterNode) element; + label = node.getNodeName() + " " + node.getFilterName(); //$NON-NLS-1$ + + } else if (element instanceof TmfFilterEventTypeNode) { + + TmfFilterEventTypeNode node = (TmfFilterEventTypeNode) element; + label = "WITH " + node.getNodeName() + (node.getName() != null ? " " + node.getName() : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + } else if (element instanceof TmfFilterAndNode) { + + TmfFilterAndNode node = (TmfFilterAndNode) element; + label = (node.isNot() ? "NOT " : "") + node.getNodeName(); //$NON-NLS-1$ //$NON-NLS-2$ + + } else if (element instanceof TmfFilterOrNode) { + + TmfFilterOrNode node = (TmfFilterOrNode) element; + label = (node.isNot() ? "NOT " : "") + node.getNodeName(); //$NON-NLS-1$ //$NON-NLS-2$ + + } else if (element instanceof TmfFilterContainsNode) { + + TmfFilterContainsNode node = (TmfFilterContainsNode) element; + label = (node.isNot() ? "NOT " : "") + //$NON-NLS-1$ //$NON-NLS-2$ + (node.getField() != null ? node.getField() + " " : "") + //$NON-NLS-1$ //$NON-NLS-2$ + node.getNodeName() + + (node.getValue() != null && node.getValue().length() > 0 ? " \"" + node.getValue() + "\"" : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + } else if (element instanceof TmfFilterEqualsNode) { + + TmfFilterEqualsNode node = (TmfFilterEqualsNode) element; + label = (node.isNot() ? "NOT " : "") + //$NON-NLS-1$ //$NON-NLS-2$ + (node.getField() != null ? node.getField() + " " : "") + //$NON-NLS-1$ //$NON-NLS-2$ + node.getNodeName() + + (node.getValue() != null && node.getValue().length() > 0 ? " \"" + node.getValue() + "\"" : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + } else if (element instanceof TmfFilterMatchesNode) { + + TmfFilterMatchesNode node = (TmfFilterMatchesNode) element; + label = (node.isNot() ? "NOT " : "") + //$NON-NLS-1$ //$NON-NLS-2$ + (node.getField() != null ? node.getField() + " " : "") + //$NON-NLS-1$ //$NON-NLS-2$ + node.getNodeName() + + (node.getRegex() != null && node.getRegex().length() > 0 ? " \"" + node.getRegex() + "\"" : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + } else if (element instanceof TmfFilterCompareNode) { + + TmfFilterCompareNode node = (TmfFilterCompareNode) element; + label = (node.isNot() ? "NOT " : "") + //$NON-NLS-1$ //$NON-NLS-2$ + (node.getField() != null ? node.getField() + " " : "") + //$NON-NLS-1$ //$NON-NLS-2$ + (node.getResult() < 0 ? "<" : (node.getResult() > 0 ? ">" : "=")) + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + (node.getValue() != null && node.getValue().length() > 0 ? + (node.getType() == Type.ALPHA ? " \"" + node.getValue() + "\"" : //$NON-NLS-1$ //$NON-NLS-2$ + (node.getType() == Type.TIMESTAMP ? " [" + node.getValue() + "]" : //$NON-NLS-1$ //$NON-NLS-2$ + " " + node.getValue())) : ""); //$NON-NLS-1$//$NON-NLS-2$ + + } + return label; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterView.java new file mode 100644 index 0000000000..d3ee36c7eb --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterView.java @@ -0,0 +1,309 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Yuriy Vashchuk - Initial API and implementation + * Xavier Raynaud - add cut/copy/paste/dnd support + * based on Francois Chouinard ProjectView code. + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.filter; + +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterRootNode; +import org.eclipse.tracecompass.tmf.core.filter.xml.TmfFilterXMLParser; +import org.eclipse.tracecompass.tmf.core.filter.xml.TmfFilterXMLWriter; +import org.eclipse.tracecompass.tmf.ui.views.TmfView; +import org.eclipse.ui.IActionBars; +import org.xml.sax.SAXException; + +/** + * View that contain UI to the TMF filter. + * + * @version 1.0 + * @author Yuriy Vashchuk + */ +public class FilterView extends TmfView { + + /** ID for the Filter view */ + public static final @NonNull String ID = "org.eclipse.linuxtools.tmf.ui.views.filter"; //$NON-NLS-1$ + + private static final Image SAVE_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/save_button.gif"); //$NON-NLS-1$ + private static final Image ADD_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/add_button.gif"); //$NON-NLS-1$ + private static final Image IMPORT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/import_button.gif"); //$NON-NLS-1$ + private static final Image EXPORT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/export_button.gif"); //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Main data structures + // ------------------------------------------------------------------------ + + private FilterViewer fViewer; + private final ITmfFilterTreeNode fRoot; + + private final IWorkspace fWorkspace; + + private SaveAction fSaveAction; + private AddAction fAddAction; + private ExportAction fExportAction; + private ImportAction fImportAction; + + /** + * Getter for the Filter Tree Root + * + * @return The root of builded tree + */ + public ITmfFilterTreeNode getFilterRoot() { + return fRoot; + } + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Default Constructor + */ + public FilterView() { + super("Filter"); //$NON-NLS-1$ + + fWorkspace = ResourcesPlugin.getWorkspace(); + try { + fWorkspace.getRoot().refreshLocal(IResource.DEPTH_INFINITE, null); + } catch (CoreException e) { + Activator.getDefault().logError("Error refreshing workspace", e); //$NON-NLS-1$ + } + + fRoot = new TmfFilterRootNode(); + for (ITmfFilterTreeNode node : FilterManager.getSavedFilters()) { + fRoot.addChild(node); + } + } + + /** + * Add a filter to the FilterView. This does not modify the XML, which must + * be done manually. If the filter is already in the FilterView, this is a + * no-op. + * + * @param filter + * The filter to add. + * @since 3.1 + */ + public void addFilter(ITmfFilterTreeNode filter) { + ITmfFilterTreeNode root = fViewer.getInput(); + for (ITmfFilterTreeNode node : root.getChildren()) { + if (node.equals(filter)) { + return; + } + } + root.addChild(filter); + fViewer.setInput(root); + } + + /** + * Refresh the tree widget + */ + public void refresh() { + fViewer.refresh(); + } + + /** + * Setter for selection + * + * @param node + * The node to select + */ + public void setSelection(ITmfFilterTreeNode node) { + fViewer.setSelection(node, true); + } + + // ------------------------------------------------------------------------ + // ViewPart + // ------------------------------------------------------------------------ + + @Override + public void createPartControl(Composite parent) { + + fViewer = new FilterViewer(parent, SWT.NONE); + fViewer.setInput(fRoot); + + contributeToActionBars(); + + fViewer.addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + if (!(event.getSelection().isEmpty()) && event.getSelection() instanceof IStructuredSelection) { + fExportAction.setEnabled(true); + } else { + fExportAction.setEnabled(false); + } + } + }); + this.getSite().setSelectionProvider(fViewer.getTreeViewer()); + + MenuManager menuManager = fViewer.getMenuManager(); + this.getSite().registerContextMenu(menuManager, fViewer.getTreeViewer()); + } + + /** + * @return the ITmfFilterTreeNode currently selected + */ + ITmfFilterTreeNode getSelection() { + return fViewer.getSelection(); + } + + @Override + public void setFocus() { + fViewer.setFocus(); + } + + @Override + public String toString() { + return "[FilterView]"; //$NON-NLS-1$ + } + + /** + * Builds the menu toolbar + */ + private void contributeToActionBars() { + IActionBars bars = getViewSite().getActionBars(); + // fillLocalPullDown(bars.getMenuManager()); + fillLocalToolBar(bars.getToolBarManager()); + } + + /** + * Build the popup menu + * + * @param manager + * The manager to build + */ + private void fillLocalToolBar(IToolBarManager manager) { + + fSaveAction = new SaveAction(); + fSaveAction.setImageDescriptor(ImageDescriptor.createFromImage(SAVE_IMAGE)); + fSaveAction.setToolTipText(Messages.FilterView_SaveActionToolTipText); + + fAddAction = new AddAction(); + fAddAction.setImageDescriptor(ImageDescriptor.createFromImage(ADD_IMAGE)); + fAddAction.setToolTipText(Messages.FilterView_AddActionToolTipText); + + fExportAction = new ExportAction(); + fExportAction.setImageDescriptor(ImageDescriptor.createFromImage(EXPORT_IMAGE)); + fExportAction.setToolTipText(Messages.FilterView_ExportActionToolTipText); + + fImportAction = new ImportAction(); + fImportAction.setImageDescriptor(ImageDescriptor.createFromImage(IMPORT_IMAGE)); + fImportAction.setToolTipText(Messages.FilterView_ImportActionToolTipText); + + manager.add(fSaveAction); + manager.add(new Separator("add_delete")); //$NON-NLS-1$ + manager.add(fAddAction); + manager.add(new Separator("edit")); //$NON-NLS-1$ + manager.add(new Separator()); + manager.add(fExportAction); + manager.add(fImportAction); + } + + private class SaveAction extends Action { + @Override + public void run() { + FilterManager.setSavedFilters(fRoot.getChildren()); + } + } + + private class AddAction extends Action { + @Override + public void run() { + + TmfFilterNode newNode = new TmfFilterNode(fRoot, ""); //$NON-NLS-1$ + refresh(); + setSelection(newNode); + } + } + + private class ExportAction extends Action { + @Override + public void run() { + try { + FileDialog dlg = new FileDialog(new Shell(), SWT.SAVE); + dlg.setFilterNames(new String[] { Messages.FilterView_FileDialogFilterName + " (*.xml)" }); //$NON-NLS-1$ + dlg.setFilterExtensions(new String[] { "*.xml" }); //$NON-NLS-1$ + + String fn = dlg.open(); + if (fn != null) { + TmfFilterXMLWriter writerXML = new TmfFilterXMLWriter(fRoot); + writerXML.saveTree(fn); + } + + } catch (ParserConfigurationException e) { + Activator.getDefault().logError("Error parsing filter xml file", e); //$NON-NLS-1$ + } + } + } + + private class ImportAction extends Action { + @Override + public void run() { + if (fViewer != null) { + ITmfFilterTreeNode root = null; + try { + FileDialog dlg = new FileDialog(new Shell(), SWT.OPEN); + dlg.setFilterNames(new String[] { Messages.FilterView_FileDialogFilterName + " (*.xml)" }); //$NON-NLS-1$ + dlg.setFilterExtensions(new String[] { "*.xml" }); //$NON-NLS-1$ + + TmfFilterXMLParser parserXML = null; + String fn = dlg.open(); + if (fn != null) { + parserXML = new TmfFilterXMLParser(fn); + root = parserXML.getTree(); + } + + } catch (SAXException e) { + Activator.getDefault().logError("Error importing filter xml file", e); //$NON-NLS-1$ + } catch (IOException e) { + Activator.getDefault().logError("Error importing filter xml file", e); //$NON-NLS-1$ + } + + if (root != null) { + for (ITmfFilterTreeNode node : root.getChildren()) { + if (node instanceof TmfFilterNode) { + fRoot.addChild(node); + refresh(); + fViewer.setSelection(node); + } + } + } + } + } + } + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterViewer.java new file mode 100644 index 0000000000..af432330ae --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/FilterViewer.java @@ -0,0 +1,1124 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Xavier Raynaud - add cut/copy/paste/dnd support + * Vincent Perot - Add subfield filtering + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.filter; + +import java.util.ArrayList; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.util.LocalSelectionTransfer; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DragSource; +import org.eclipse.swt.dnd.DropTarget; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterAndNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterCompareNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterContainsNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterEqualsNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterEventTypeNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterMatchesNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterOrNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterRootNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterTreeNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterCompareNode.Type; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtEvent; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlEvent; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition; +import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition.OutputColumn; +import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; + +class FilterViewer extends Composite { + + private static final String SEP = " : "; //$NON-NLS-1$ + + private TreeViewer fViewer; + + private Composite fComposite; + private MenuManager fMenuManager; + + public FilterViewer(Composite parent, int style) { + super(parent, style); + + setLayout(new FillLayout()); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + setLayoutData(gd); + + final SashForm sash = new SashForm(this, SWT.HORIZONTAL); + + // Create the tree viewer to display the filter tree + fViewer = new TreeViewer(sash, SWT.NONE); + fViewer.setContentProvider(new FilterTreeContentProvider()); + fViewer.setLabelProvider(new FilterTreeLabelProvider()); + fViewer.setInput(new TmfFilterRootNode()); + + // Create the empty filter node properties panel + fComposite = new Composite(sash, SWT.NONE); + GridLayout gl = new GridLayout(); + gl.marginHeight = 0; + gl.marginWidth = 0; + fComposite.setLayout(gl); + + createContextMenu(); + + fViewer.addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + if (!(event.getSelection().isEmpty()) && event.getSelection() instanceof IStructuredSelection) { + // Update the filter node properties panel to the selection + IStructuredSelection selection = (IStructuredSelection) event.getSelection(); + ITmfFilterTreeNode node = (ITmfFilterTreeNode) selection.getFirstElement(); + updateFilterNodeComposite(node); + // Highlight the selection's children + highlightTreeItems(fViewer.getTree().getSelection()[0].getItems()); + } else { + updateFilterNodeComposite(null); + } + } + }); + + fViewer.getTree().addPaintListener(new PaintListener() { + @Override + public void paintControl(PaintEvent e) { + TmfFilterTreeNode root = (TmfFilterTreeNode) fViewer.getInput(); + if (root == null || root.getChildrenCount() == 0) { + e.gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); + e.gc.drawText(Messages.FilterViewer_EmptyTreeHintText, 5, 0); + } + } + }); + + int operations = DND.DROP_MOVE | DND.DROP_COPY; + DragSource dragSource = new org.eclipse.swt.dnd.DragSource(fViewer.getTree(), operations); + dragSource.setTransfer(new Transfer[] { LocalSelectionTransfer.getTransfer() }); + dragSource.addDragListener(new FilterDragSourceAdapter(this)); + DropTarget dropTarget = new DropTarget(fViewer.getTree(), operations); + dropTarget.setTransfer(new Transfer[] { LocalSelectionTransfer.getTransfer() }); + dropTarget.addDropListener(new FilterDropTargetAdapter(this)); + } + + /** + * Create the context menu for the tree viewer + */ + private void createContextMenu() { + // Adds root context menu + fMenuManager = new MenuManager(); + fMenuManager.setRemoveAllWhenShown(true); + fMenuManager.addMenuListener(new IMenuListener() { + @Override + public void menuAboutToShow(IMenuManager manager) { + fillContextMenu(manager); + } + }); + + // Context + Menu contextMenu = fMenuManager.createContextMenu(fViewer.getTree()); + + // Publish it + fViewer.getTree().setMenu(contextMenu); + } + + public MenuManager getMenuManager() { + return fMenuManager; + } + + /** + * Fill the context menu for the tree viewer. + * + * @param manager + * The menu manager + */ + protected void fillContextMenu(IMenuManager manager) { + final ISelection selection = fViewer.getSelection(); + ITmfFilterTreeNode filterTreeNode = null; + if (selection instanceof StructuredSelection) { + Object element = ((StructuredSelection) selection).getFirstElement(); + if (element instanceof ITmfFilterTreeNode) { + filterTreeNode = (ITmfFilterTreeNode) element; + } + } + + if (filterTreeNode != null) { + fillContextMenuForNode(filterTreeNode, manager); + } + manager.add(new Separator("delete")); //$NON-NLS-1$ + manager.add(new Separator("edit")); //$NON-NLS-1$ + + if (fViewer.getInput() instanceof TmfFilterRootNode || filterTreeNode == null) { + manager.add(new Separator()); + ITmfFilterTreeNode root = (ITmfFilterTreeNode) fViewer.getInput(); + fillContextMenuForNode(root, manager); + } + } + + /** + * Fill the context menu with the valid children of the provided node + * + * @param node + * The target node + * @param manager + * The menu manager + */ + protected void fillContextMenuForNode(final ITmfFilterTreeNode node, IMenuManager manager) { + for (final String child : node.getValidChildren()) { + final Action action = new Action() { + @Override + public void run() { + ITmfFilterTreeNode newNode = null; + if (TmfFilterNode.NODE_NAME.equals(child)) { + newNode = new TmfFilterNode(node, ""); //$NON-NLS-1$ + } else if (TmfFilterEventTypeNode.NODE_NAME.equals(child)) { + newNode = new TmfFilterEventTypeNode(node); + } else if (TmfFilterAndNode.NODE_NAME.equals(child)) { + newNode = new TmfFilterAndNode(node); + } else if (TmfFilterOrNode.NODE_NAME.equals(child)) { + newNode = new TmfFilterOrNode(node); + } else if (TmfFilterContainsNode.NODE_NAME.equals(child)) { + newNode = new TmfFilterContainsNode(node); + } else if (TmfFilterEqualsNode.NODE_NAME.equals(child)) { + newNode = new TmfFilterEqualsNode(node); + } else if (TmfFilterMatchesNode.NODE_NAME.equals(child)) { + newNode = new TmfFilterMatchesNode(node); + } else if (TmfFilterCompareNode.NODE_NAME.equals(child)) { + newNode = new TmfFilterCompareNode(node); + } + if (newNode != null) { + fViewer.refresh(); + fViewer.setSelection(new StructuredSelection(newNode), true); + } + } + }; + if (TmfFilterNode.NODE_NAME.equals(child)) { + action.setText(Messages.FilterViewer_NewPrefix + " " + child); //$NON-NLS-1$ + } else { + action.setText(child); + } + manager.add(action); + } + } + + /** + * Create the appropriate filter node properties composite + */ + private void updateFilterNodeComposite(ITmfFilterTreeNode node) { + for (Control control : fComposite.getChildren()) { + control.dispose(); + } + + if (node instanceof TmfFilterNode) { + new FilterNodeComposite(fComposite, (TmfFilterNode) node); + } else if (node instanceof TmfFilterEventTypeNode) { + new FilterEventTypeNodeComposite(fComposite, (TmfFilterEventTypeNode) node); + } else if (node instanceof TmfFilterAndNode) { + new FilterAndNodeComposite(fComposite, (TmfFilterAndNode) node); + } else if (node instanceof TmfFilterOrNode) { + new FilterOrNodeComposite(fComposite, (TmfFilterOrNode) node); + } else if (node instanceof TmfFilterContainsNode) { + new FilterContainsNodeComposite(fComposite, (TmfFilterContainsNode) node); + } else if (node instanceof TmfFilterEqualsNode) { + new FilterEqualsNodeComposite(fComposite, (TmfFilterEqualsNode) node); + } else if (node instanceof TmfFilterMatchesNode) { + new FilterMatchesNodeComposite(fComposite, (TmfFilterMatchesNode) node); + } else if (node instanceof TmfFilterCompareNode) { + new FilterCompareNodeComposite(fComposite, (TmfFilterCompareNode) node); + } else { + new FilterBaseNodeComposite(fComposite); + } + fComposite.layout(); + } + + /** + * Highlight the provided tree items + */ + private void highlightTreeItems(TreeItem[] items) { + resetTreeItems(fViewer.getTree().getItems()); + for (TreeItem item : items) { + item.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLUE)); + } + + } + + /** + * Reset the provided tree items (remove highlight) + */ + private void resetTreeItems(TreeItem[] items) { + for (TreeItem item : items) { + item.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); + resetTreeItems(item.getItems()); + } + } + + public void setInput(ITmfFilterTreeNode root) { + fViewer.setInput(root); + fViewer.expandAll(); + + updateFilterNodeComposite(null); + } + + public ITmfFilterTreeNode getInput() { + return (ITmfFilterTreeNode) fViewer.getInput(); + } + + public void refresh() { + fViewer.refresh(); + } + + public void setSelection(ITmfFilterTreeNode node, boolean reveal) { + fViewer.setSelection(new StructuredSelection(node), reveal); + } + + public void setSelection(ITmfFilterTreeNode node) { + fViewer.setSelection(new StructuredSelection(node)); + } + + public ITmfFilterTreeNode getSelection() { + final ISelection selection = fViewer.getSelection(); + ITmfFilterTreeNode filterTreeNode = null; + if (selection instanceof StructuredSelection) { + Object element = ((StructuredSelection) selection).getFirstElement(); + if (element instanceof ITmfFilterTreeNode) { + filterTreeNode = (ITmfFilterTreeNode) element; + } + } + + final ITmfFilterTreeNode selectedNode = filterTreeNode; + return selectedNode; + } + + public void addSelectionChangedListener(ISelectionChangedListener listener) { + fViewer.addSelectionChangedListener(listener); + } + + public void removeSelectionChangedListener(ISelectionChangedListener listener) { + fViewer.removeSelectionChangedListener(listener); + } + + /** + * Gets the TreeViewer displaying filters + * + * @return a {@link TreeViewer} + */ + TreeViewer getTreeViewer() { + return fViewer; + } + + private class FilterBaseNodeComposite extends Composite { + + FilterBaseNodeComposite(Composite parent) { + super(parent, SWT.NONE); + setLayout(new GridLayout(2, false)); + setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + } + + protected Map getEventsTypeMap() { + Map eventsTypeMap = new TreeMap<>(); + for (IConfigurationElement ce : TmfTraceType.getTypeElements()) { + String categoryPrefix = ""; //$NON-NLS-1$ + String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR); + if (categoryId != null) { + categoryPrefix = TmfTraceType.getCategoryName(categoryId) + SEP; + } + String text = categoryPrefix + ce.getAttribute(TmfTraceType.NAME_ATTR); + eventsTypeMap.put(text, ce); + } + for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) { + String text = def.categoryName + SEP + def.definitionName; + eventsTypeMap.put(text, def); + } + for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { + String text = def.categoryName + SEP + def.definitionName; + eventsTypeMap.put(text, def); + } + return eventsTypeMap; + } + + protected String[] getFieldsList(ITmfFilterTreeNode node) { + ArrayList fieldsList = new ArrayList<>(); + ITmfFilterTreeNode curNode = node; + while (curNode != null) { + if (curNode instanceof TmfFilterEventTypeNode) { + TmfFilterEventTypeNode eventTypeNode = (TmfFilterEventTypeNode) curNode; + for (IConfigurationElement ce : TmfTraceType.getTypeElements()) { + if (ce.getAttribute(TmfTraceType.EVENT_TYPE_ATTR).equals(eventTypeNode.getEventType())) { + try { + ITmfEvent event = (ITmfEvent) ce.createExecutableExtension(TmfTraceType.EVENT_TYPE_ATTR); + ITmfEventType eventType = event.getType(); + if (eventType != null) { + for (String field : eventType.getRootField().getFieldNames()) { + fieldsList.add(field); + } + } + } catch (CoreException e) { + } + if (fieldsList.size() == 0) { + fieldsList.add(ITmfEvent.EVENT_FIELD_TIMESTAMP); + fieldsList.add(ITmfEvent.EVENT_FIELD_SOURCE); + fieldsList.add(ITmfEvent.EVENT_FIELD_TYPE); + fieldsList.add(ITmfEvent.EVENT_FIELD_REFERENCE); + fieldsList.add(ITmfEvent.EVENT_FIELD_CONTENT); + } + return fieldsList.toArray(new String[0]); + } + } + if (eventTypeNode.getEventType() != null && eventTypeNode.getEventType().startsWith(CustomTxtEvent.class.getCanonicalName())) { + for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) { + if (eventTypeNode.getEventType().equals(CustomTxtEvent.class.getCanonicalName() + ':' + def.categoryName + ':' + def.definitionName)) { + for (OutputColumn output : def.outputs) { + fieldsList.add(output.name); + } + return fieldsList.toArray(new String[0]); + } + } + } + if (eventTypeNode.getEventType() != null && eventTypeNode.getEventType().startsWith(CustomXmlEvent.class.getCanonicalName())) { + for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { + if (eventTypeNode.getEventType().equals(CustomXmlEvent.class.getCanonicalName() + ':' + def.categoryName + ':' + def.definitionName)) { + for (OutputColumn output : def.outputs) { + fieldsList.add(output.name); + } + return fieldsList.toArray(new String[0]); + } + } + } + } + curNode = curNode.getParent(); + } + + fieldsList.add(Messages.FilterViewer_CommonCategory); + fieldsList.add(ITmfEvent.EVENT_FIELD_TIMESTAMP); + fieldsList.add(ITmfEvent.EVENT_FIELD_SOURCE); + fieldsList.add(ITmfEvent.EVENT_FIELD_TYPE); + fieldsList.add(ITmfEvent.EVENT_FIELD_REFERENCE); + fieldsList.add(ITmfEvent.EVENT_FIELD_CONTENT); + fieldsList.add(""); //$NON-NLS-1$ + + for (Entry eventTypeEntry : getEventsTypeMap().entrySet()) { + Object value = eventTypeEntry.getValue(); + if (value instanceof IConfigurationElement) { + IConfigurationElement ce = (IConfigurationElement) value; + try { + ITmfEvent event = (ITmfEvent) ce.createExecutableExtension(TmfTraceType.EVENT_TYPE_ATTR); + ITmfEventType eventType = event.getType(); + if (eventType != null && eventType.getFieldNames().size() > 0) { + String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR); + if (categoryId != null) { + fieldsList.add('[' + TmfTraceType.getCategoryName(categoryId) + SEP + + ce.getAttribute(TmfTraceType.NAME_ATTR) + ']'); + } else { + fieldsList.add('[' + ce.getAttribute(TmfTraceType.NAME_ATTR) + ']'); + } + for (String field : eventType.getFieldNames()) { + fieldsList.add(field); + } + fieldsList.add(""); //$NON-NLS-1$ + } + } catch (CoreException e) { + } + } else if (value instanceof CustomTraceDefinition) { + CustomTraceDefinition def = (CustomTraceDefinition) value; + if (def.outputs.size() > 0) { + fieldsList.add('[' + def.categoryName + SEP + def.definitionName + ']'); + for (OutputColumn output : def.outputs) { + fieldsList.add(output.name); + } + fieldsList.add(""); //$NON-NLS-1$ + } + } + } + return fieldsList.toArray(new String[0]); + } + } + + private class FilterNodeComposite extends FilterBaseNodeComposite { + TmfFilterNode fNode; + Text fNameText; + + FilterNodeComposite(Composite parent, TmfFilterNode node) { + super(parent); + fNode = node; + + Label label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + label.setText(Messages.FilterViewer_NameLabel); + + fNameText = new Text(this, SWT.BORDER); + fNameText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + if (node.getFilterName() != null && node.getFilterName().length() > 0) { + fNameText.setText(node.getFilterName()); + } else { + fNameText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); + fNameText.setText(Messages.FilterViewer_FilterNameHint); + } + fNameText.addFocusListener(new FocusListener() { + @Override + public void focusLost(FocusEvent e) { + if (fNode.getFilterName() == null || fNode.getFilterName().length() == 0) { + fNameText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); + fNameText.setText(Messages.FilterViewer_FilterNameHint); + } + } + + @Override + public void focusGained(FocusEvent e) { + if (fNameText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { + fNameText.setText(""); //$NON-NLS-1$ + } + fNameText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); + } + }); + fNameText.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + if (!fNameText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { + fNode.setFilterName(fNameText.getText()); + fViewer.refresh(fNode); + } + } + }); + } + } + + private class FilterEventTypeNodeComposite extends FilterBaseNodeComposite { + TmfFilterEventTypeNode fNode; + Combo fTypeCombo; + Map fEventsTypeMap; + + FilterEventTypeNodeComposite(Composite parent, TmfFilterEventTypeNode node) { + super(parent); + fNode = node; + fEventsTypeMap = getEventsTypeMap(); + + Label label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + label.setText(Messages.FilterViewer_TypeLabel); + + fTypeCombo = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY); + fTypeCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + fTypeCombo.setItems(fEventsTypeMap.keySet().toArray(new String[0])); + if (fNode.getEventType() != null) { + fTypeCombo.setText(fNode.getName()); + } + fTypeCombo.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + for (Entry eventTypeEntry : fEventsTypeMap.entrySet()) { + if (eventTypeEntry.getKey().equals(fTypeCombo.getText())) { + Object value = eventTypeEntry.getValue(); + if (value instanceof IConfigurationElement) { + IConfigurationElement ce = (IConfigurationElement) value; + fNode.setEventType(ce.getAttribute(TmfTraceType.EVENT_TYPE_ATTR)); + String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR); + if (categoryId != null) { + fNode.setName(TmfTraceType.getCategoryName(categoryId) + SEP + + ce.getAttribute(TmfTraceType.NAME_ATTR)); + } else { + fNode.setName(ce.getAttribute(TmfTraceType.NAME_ATTR)); + } + } else if (value instanceof CustomTxtTraceDefinition) { + CustomTxtTraceDefinition def = (CustomTxtTraceDefinition) value; + fNode.setEventType(CustomTxtEvent.class.getCanonicalName() + ':' + def.categoryName + ':' + def.definitionName); + fNode.setName(def.categoryName + SEP + def.definitionName); + } else if (value instanceof CustomXmlTraceDefinition) { + CustomXmlTraceDefinition def = (CustomXmlTraceDefinition) value; + fNode.setEventType(CustomXmlEvent.class.getCanonicalName() + ':' + def.categoryName + ':' + def.definitionName); + fNode.setName(def.categoryName + SEP + def.definitionName); + } + fViewer.refresh(fNode); + break; + } + } + } + }); + } + } + + private class FilterAndNodeComposite extends FilterBaseNodeComposite { + TmfFilterAndNode fNode; + Button fNotButton; + + FilterAndNodeComposite(Composite parent, TmfFilterAndNode node) { + super(parent); + fNode = node; + + Label label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + label.setText(Messages.FilterViewer_NotLabel); + + fNotButton = new Button(this, SWT.CHECK); + fNotButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + fNotButton.setSelection(fNode.isNot()); + fNotButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + fNode.setNot(fNotButton.getSelection()); + fViewer.refresh(fNode); + } + }); + } + } + + private class FilterOrNodeComposite extends FilterBaseNodeComposite { + TmfFilterOrNode fNode; + Button fNotButton; + + FilterOrNodeComposite(Composite parent, TmfFilterOrNode node) { + super(parent); + fNode = node; + + Label label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + label.setText(Messages.FilterViewer_NotLabel); + + fNotButton = new Button(this, SWT.CHECK); + fNotButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + fNotButton.setSelection(fNode.isNot()); + fNotButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + fNode.setNot(fNotButton.getSelection()); + fViewer.refresh(fNode); + } + }); + } + } + + private class FilterContainsNodeComposite extends FilterBaseNodeComposite { + TmfFilterContainsNode fNode; + Button fNotButton; + Combo fFieldCombo; + Text fValueText; + Button fIgnoreCaseButton; + + FilterContainsNodeComposite(Composite parent, TmfFilterContainsNode node) { + super(parent); + fNode = node; + + Label label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + label.setText(Messages.FilterViewer_NotLabel); + + fNotButton = new Button(this, SWT.CHECK); + fNotButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + fNotButton.setSelection(fNode.isNot()); + fNotButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + fNode.setNot(fNotButton.getSelection()); + fViewer.refresh(fNode); + } + }); + + label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + label.setText(Messages.FilterViewer_FieldLabel); + + fFieldCombo = new Combo(this, SWT.DROP_DOWN); + fFieldCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + fFieldCombo.setItems(getFieldsList(fNode)); + fFieldCombo.setToolTipText(Messages.FilterViewer_Subfilter_ToolTip); + if (fNode.getField() != null) { + fFieldCombo.setText(fNode.getField()); + } + fFieldCombo.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + fNode.setField(fFieldCombo.getText()); + fViewer.refresh(fNode); + } + }); + + label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + label.setText(Messages.FilterViewer_ValueLabel); + + fValueText = new Text(this, SWT.BORDER); + fValueText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + if (node.getValue() != null && node.getValue().length() > 0) { + fValueText.setText(node.getValue()); + } else { + fValueText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); + fValueText.setText(Messages.FilterViewer_ValueHint); + } + fValueText.addFocusListener(new FocusListener() { + @Override + public void focusLost(FocusEvent e) { + if (fNode.getValue() == null || fNode.getValue().length() == 0) { + fValueText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); + fValueText.setText(Messages.FilterViewer_ValueHint); + } + } + + @Override + public void focusGained(FocusEvent e) { + if (fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { + fValueText.setText(""); //$NON-NLS-1$ + } + fValueText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); + } + }); + fValueText.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + if (!fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { + fNode.setValue(fValueText.getText()); + fViewer.refresh(fNode); + } + } + }); + + label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + + fIgnoreCaseButton = new Button(this, SWT.CHECK); + fIgnoreCaseButton.setSelection(fNode.isIgnoreCase()); + fIgnoreCaseButton.setText(Messages.FilterViewer_IgnoreCaseButtonText); + fIgnoreCaseButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + fIgnoreCaseButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + fNode.setIgnoreCase(fIgnoreCaseButton.getSelection()); + fViewer.refresh(fNode); + } + }); + } + } + + private class FilterEqualsNodeComposite extends FilterBaseNodeComposite { + TmfFilterEqualsNode fNode; + Button fNotButton; + Combo fFieldCombo; + Text fValueText; + Button fIgnoreCaseButton; + + FilterEqualsNodeComposite(Composite parent, TmfFilterEqualsNode node) { + super(parent); + fNode = node; + + Label label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + label.setText(Messages.FilterViewer_NotLabel); + + fNotButton = new Button(this, SWT.CHECK); + fNotButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + fNotButton.setSelection(fNode.isNot()); + fNotButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + fNode.setNot(fNotButton.getSelection()); + fViewer.refresh(fNode); + } + }); + + label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + label.setText(Messages.FilterViewer_FieldLabel); + + fFieldCombo = new Combo(this, SWT.DROP_DOWN); + fFieldCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + fFieldCombo.setItems(getFieldsList(fNode)); + fFieldCombo.setToolTipText(Messages.FilterViewer_Subfilter_ToolTip); + if (fNode.getField() != null) { + fFieldCombo.setText(fNode.getField()); + } + fFieldCombo.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + fNode.setField(fFieldCombo.getText()); + fViewer.refresh(fNode); + } + }); + + label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + label.setText(Messages.FilterViewer_ValueLabel); + + fValueText = new Text(this, SWT.BORDER); + fValueText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + if (node.getValue() != null && node.getValue().length() > 0) { + fValueText.setText(node.getValue()); + } else { + fValueText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); + fValueText.setText(Messages.FilterViewer_ValueHint); + } + fValueText.addFocusListener(new FocusListener() { + @Override + public void focusLost(FocusEvent e) { + if (fNode.getValue() == null || fNode.getValue().length() == 0) { + fValueText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); + fValueText.setText(Messages.FilterViewer_ValueHint); + } + } + + @Override + public void focusGained(FocusEvent e) { + if (fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { + fValueText.setText(""); //$NON-NLS-1$ + } + fValueText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); + } + }); + fValueText.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + if (!fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { + fNode.setValue(fValueText.getText()); + fViewer.refresh(fNode); + } + } + }); + + label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + + fIgnoreCaseButton = new Button(this, SWT.CHECK); + fIgnoreCaseButton.setSelection(fNode.isIgnoreCase()); + fIgnoreCaseButton.setText(Messages.FilterViewer_IgnoreCaseButtonText); + fIgnoreCaseButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + fIgnoreCaseButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + fNode.setIgnoreCase(fIgnoreCaseButton.getSelection()); + fViewer.refresh(fNode); + } + }); + } + } + + private class FilterMatchesNodeComposite extends FilterBaseNodeComposite { + TmfFilterMatchesNode fNode; + Button fNotButton; + Combo fFieldCombo; + Text fRegexText; + + FilterMatchesNodeComposite(Composite parent, TmfFilterMatchesNode node) { + super(parent); + fNode = node; + + Label label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + label.setText(Messages.FilterViewer_NotLabel); + + fNotButton = new Button(this, SWT.CHECK); + fNotButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + fNotButton.setSelection(fNode.isNot()); + fNotButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + fNode.setNot(fNotButton.getSelection()); + fViewer.refresh(fNode); + } + }); + + label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + label.setText(Messages.FilterViewer_FieldLabel); + + fFieldCombo = new Combo(this, SWT.DROP_DOWN); + fFieldCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + fFieldCombo.setItems(getFieldsList(fNode)); + fFieldCombo.setToolTipText(Messages.FilterViewer_Subfilter_ToolTip); + if (fNode.getField() != null) { + fFieldCombo.setText(fNode.getField()); + } + fFieldCombo.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + fNode.setField(fFieldCombo.getText()); + fViewer.refresh(fNode); + } + }); + + label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + label.setText(Messages.FilterViewer_RegexLabel); + + fRegexText = new Text(this, SWT.BORDER); + fRegexText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + if (node.getRegex() != null && node.getRegex().length() > 0) { + fRegexText.setText(node.getRegex()); + } else { + fRegexText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); + fRegexText.setText(Messages.FilterViewer_RegexHint); + } + fRegexText.addFocusListener(new FocusListener() { + @Override + public void focusLost(FocusEvent e) { + if (fNode.getRegex() == null || fNode.getRegex().length() == 0) { + fRegexText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); + fRegexText.setText(Messages.FilterViewer_RegexHint); + } + } + + @Override + public void focusGained(FocusEvent e) { + if (fRegexText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { + fRegexText.setText(""); //$NON-NLS-1$ + } + fRegexText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); + } + }); + fRegexText.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + if (!fRegexText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { + fNode.setRegex(fRegexText.getText()); + fViewer.refresh(fNode); + } + } + }); + } + } + + private class FilterCompareNodeComposite extends FilterBaseNodeComposite { + TmfFilterCompareNode fNode; + Button fNotButton; + Combo fFieldCombo; + Text fValueText; + Button fLTButton; + Button fEQButton; + Button fGTButton; + Button fNumButton; + Button fAlphaButton; + Button fTimestampButton; + + FilterCompareNodeComposite(Composite parent, TmfFilterCompareNode node) { + super(parent); + fNode = node; + + Label label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + label.setText(Messages.FilterViewer_NotLabel); + + fNotButton = new Button(this, SWT.CHECK); + fNotButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + fNotButton.setSelection(fNode.isNot()); + fNotButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + fNode.setNot(fNotButton.getSelection()); + fViewer.refresh(fNode); + } + }); + + label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + label.setText(Messages.FilterViewer_FieldLabel); + + fFieldCombo = new Combo(this, SWT.DROP_DOWN); + fFieldCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + fFieldCombo.setItems(getFieldsList(fNode)); + fFieldCombo.setToolTipText(Messages.FilterViewer_Subfilter_ToolTip); + if (fNode.getField() != null) { + fFieldCombo.setText(fNode.getField()); + } + fFieldCombo.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + fNode.setField(fFieldCombo.getText()); + fViewer.refresh(fNode); + } + }); + + label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + label.setText(Messages.FilterViewer_ResultLabel); + + Composite resultGroup = new Composite(this, SWT.NONE); + GridLayout rggl = new GridLayout(3, true); + rggl.marginHeight = 0; + rggl.marginWidth = 0; + resultGroup.setLayout(rggl); + resultGroup.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + + fLTButton = new Button(resultGroup, SWT.RADIO); + fLTButton.setSelection(fNode.getResult() < 0); + fLTButton.setText("<"); //$NON-NLS-1$ + fLTButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + fLTButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (fLTButton.getSelection()) { + fNode.setResult(-1); + } + fViewer.refresh(fNode); + } + }); + + fEQButton = new Button(resultGroup, SWT.RADIO); + fEQButton.setSelection(fNode.getResult() == 0); + fEQButton.setText("="); //$NON-NLS-1$ + fEQButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + fEQButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (fEQButton.getSelection()) { + fNode.setResult(0); + } + fViewer.refresh(fNode); + } + }); + + fGTButton = new Button(resultGroup, SWT.RADIO); + fGTButton.setSelection(fNode.getResult() > 0); + fGTButton.setText(">"); //$NON-NLS-1$ + fGTButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + fGTButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (fGTButton.getSelection()) { + fNode.setResult(1); + } + fViewer.refresh(fNode); + } + }); + + label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + label.setText(Messages.FilterViewer_TypeLabel); + + Composite typeGroup = new Composite(this, SWT.NONE); + GridLayout tggl = new GridLayout(3, false); + tggl.marginHeight = 0; + tggl.marginWidth = 0; + typeGroup.setLayout(tggl); + typeGroup.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + + fNumButton = new Button(typeGroup, SWT.RADIO); + fNumButton.setSelection(fNode.getType() == Type.NUM); + fNumButton.setText(Messages.FilterViewer_NumButtonText); + fNumButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + fNumButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (fNumButton.getSelection()) { + fNode.setType(Type.NUM); + } + fViewer.refresh(fNode); + } + }); + + fAlphaButton = new Button(typeGroup, SWT.RADIO); + fAlphaButton.setSelection(fNode.getType() == Type.ALPHA); + fAlphaButton.setText(Messages.FilterViewer_AlphaButtonText); + fAlphaButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + fAlphaButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (fAlphaButton.getSelection()) { + fNode.setType(Type.ALPHA); + } + fViewer.refresh(fNode); + } + }); + + fTimestampButton = new Button(typeGroup, SWT.RADIO); + fTimestampButton.setSelection(fNode.getType() == Type.TIMESTAMP); + fTimestampButton.setText(Messages.FilterViewer_TimestampButtonText); + fTimestampButton.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + fTimestampButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (fTimestampButton.getSelection()) { + fNode.setType(Type.TIMESTAMP); + } + fViewer.refresh(fNode); + } + }); + + label = new Label(this, SWT.NONE); + label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + label.setText(Messages.FilterViewer_ValueLabel); + + fValueText = new Text(this, SWT.BORDER); + fValueText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + if (node.getValue() != null && node.getValue().length() > 0) { + fValueText.setText(node.getValue()); + } else { + fValueText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); + fValueText.setText(Messages.FilterViewer_ValueHint); + } + fValueText.addFocusListener(new FocusListener() { + @Override + public void focusLost(FocusEvent e) { + if (fNode.getValue() == null || fNode.getValue().length() == 0) { + fValueText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); + fValueText.setText(Messages.FilterViewer_ValueHint); + } + } + + @Override + public void focusGained(FocusEvent e) { + if (fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { + fValueText.setText(""); //$NON-NLS-1$ + } + fValueText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); + } + }); + fValueText.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + if (!fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) { + fNode.setValue(fValueText.getText()); + fViewer.refresh(fNode); + } + } + }); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/PasteHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/PasteHandler.java new file mode 100644 index 0000000000..f34a986659 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/filter/PasteHandler.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2013 Kalray + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xavier Raynaud - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.filter; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode; +import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterNode; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * Handler for paste command in filter view + * @author Xavier Raynaud + * @since 3.0 + */ +public class PasteHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return null; + } + + // Get the selection + IWorkbenchPage page = window.getActivePage(); + IWorkbenchPart part = page.getActivePart(); + if (!(part instanceof FilterView)) { + return null; + } + FilterView v = (FilterView) part; + + ITmfFilterTreeNode objectToPaste = FilterEditUtils.getTransferredTreeNode(); + objectToPaste = objectToPaste.clone(); + ITmfFilterTreeNode sel = v.getSelection(); + if (sel == null || TmfFilterNode.NODE_NAME.equals(objectToPaste.getNodeName())) { + sel = v.getFilterRoot(); + } + + sel.addChild(objectToPaste); + v.refresh(); + v.setSelection(objectToPaste); + return null; + } + + @Override + public boolean isEnabled() { + // Check if we are closing down + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + return false; + } + + // Get the selection + IWorkbenchPage page = window.getActivePage(); + IWorkbenchPart part = page.getActivePart(); + if (!(part instanceof FilterView)) { + return false; + } + FilterView v = (FilterView) part; + ITmfFilterTreeNode sel = v.getSelection(); + if (sel == null) { + sel = v.getFilterRoot(); + } + ITmfFilterTreeNode objectToPaste = FilterEditUtils.getTransferredTreeNode(); + if (objectToPaste != null && + (sel.getValidChildren().contains(objectToPaste.getNodeName()) + || TmfFilterNode.NODE_NAME.equals(objectToPaste.getNodeName()))) { + return true; + } + return false; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/FullTraceHistogram.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/FullTraceHistogram.java new file mode 100644 index 0000000000..0d75887f7a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/FullTraceHistogram.java @@ -0,0 +1,224 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Changed to updated histogram data model + * Patrick Tasse - Update for mouse wheel zoom + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.histogram; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; + +/** + * A histogram widget that displays the event distribution of a whole trace. + *

    + * It also features a selected range window that can be dragged and zoomed. + * + * @version 1.1 + * @author Francois Chouinard + */ +public class FullTraceHistogram extends Histogram { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final HistogramZoom fZoom; + + private long fRangeStartTime = 0L; + private long fRangeDuration; + + // ------------------------------------------------------------------------ + // Construction + // ------------------------------------------------------------------------ + + /** + * Full Constructor + * + * @param view A reference to the parent histogram view + * @param parent A reference to the parent composite + */ + public FullTraceHistogram(HistogramView view, Composite parent) { + super(view, parent); + fZoom = new HistogramZoom(this, getStartTime(), getTimeLimit()); + } + + @Override + public void dispose() { + super.dispose(); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Override + public void clear() { + fRangeStartTime = 0L; + fRangeDuration = 0L; + if (fZoom != null) { + fZoom.setFullRange(0L, 0L); + fZoom.setNewRange(0L, 0L); + } + super.clear(); + } + + /** + * Sets the time range of the full histogram. + * + * @param startTime A start time + * @param endTime A end time + */ + public void setFullRange(long startTime, long endTime) { + fZoom.setFullRange(startTime, endTime); + fZoom.setNewRange(fRangeStartTime, fRangeDuration); + } + + /** + * Sets the selected time range. + * + * @param startTime The histogram start time + * @param duration The histogram duration + */ + public void setTimeRange(long startTime, long duration) { + fRangeStartTime = startTime; + fRangeDuration = duration; + fZoom.setNewRange(fRangeStartTime, fRangeDuration); + fDataModel.complete(); + } + + // ------------------------------------------------------------------------ + // MouseListener + // ------------------------------------------------------------------------ + + private int fStartDelta; + private boolean fMouseMoved; + + @Override + public void mouseDown(MouseEvent event) { + if (fScaledData != null && fDragState == DRAG_NONE && fDataModel.getStartTime() < fDataModel.getEndTime()) { + if (event.button == 2 || (event.button == 1 && (event.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL)) { + fDragState = DRAG_RANGE; + fDragButton = event.button; + int center = (int) (((fRangeStartTime + fRangeDuration / 2) - fScaledData.fFirstBucketTime) / fScaledData.fBucketDuration); + fStartDelta = center - event.x; + fMouseMoved = false; + return; + } else if (event.button == 3) { + fDragState = DRAG_ZOOM; + fDragButton = event.button; + long time = Math.min(getTimestamp(event.x), getEndTime()); + if ((event.stateMask & SWT.MODIFIER_MASK) == SWT.SHIFT) { + if (time < fRangeStartTime + fRangeDuration / 2) { + fRangeStartTime = fRangeStartTime + fRangeDuration; + } + } else { + fRangeStartTime = time; + } + fRangeDuration = time - fRangeStartTime; + fCanvas.redraw(); + return; + } + } + super.mouseDown(event); + } + + @Override + public void mouseUp(MouseEvent event) { + if (fDragState == DRAG_RANGE && event.button == fDragButton) { + fDragState = DRAG_NONE; + fDragButton = 0; + if (!fMouseMoved) { + // if single click without move, center on the click + long startTime = getTimestamp(event.x) - fRangeDuration / 2; + fRangeStartTime = Math.max(getStartTime(), Math.min(getEndTime() - fRangeDuration, startTime)); + } + ((HistogramView) fParentView).updateTimeRange(fRangeStartTime, fRangeStartTime + fRangeDuration); + return; + } else if (fDragState == DRAG_ZOOM && event.button == fDragButton) { + fDragState = DRAG_NONE; + fDragButton = 0; + if (fRangeDuration < 0) { + fRangeStartTime = fRangeStartTime + fRangeDuration; + fRangeDuration = -fRangeDuration; + } + if (fRangeDuration > 0) { + ((HistogramView) fParentView).updateTimeRange(fRangeStartTime, fRangeStartTime + fRangeDuration); + } else { + fRangeStartTime = fZoom.getStartTime(); + fRangeDuration = fZoom.getDuration(); + fCanvas.redraw(); + } + return; + } + super.mouseUp(event); + } + + // ------------------------------------------------------------------------ + // MouseMoveListener + // ------------------------------------------------------------------------ + + @Override + public void mouseMove(MouseEvent event) { + if (fDragState == DRAG_RANGE) { + int center = event.x + fStartDelta; + long newStart = getTimestamp(center) - fRangeDuration / 2; + fRangeStartTime = Math.max(getStartTime(), Math.min(getEndTime() - fRangeDuration, newStart)); + fCanvas.redraw(); + fMouseMoved = true; + return; + } else if (fDragState == DRAG_ZOOM) { + long endTime = Math.max(getStartTime(), Math.min(getEndTime(), getTimestamp(event.x))); + fRangeDuration = endTime - fRangeStartTime; + fCanvas.redraw(); + return; + } + super.mouseMove(event); + } + + // ------------------------------------------------------------------------ + // PaintListener + // ------------------------------------------------------------------------ + + @Override + public void paintControl(PaintEvent event) { + super.paintControl(event); + + Image image = (Image) fCanvas.getData(IMAGE_KEY); + assert image != null; + + Image rangeRectangleImage = new Image(image.getDevice(), image, SWT.IMAGE_COPY); + GC rangeWindowGC = new GC(rangeRectangleImage); + + if ((fScaledData != null) && (fRangeDuration != 0 || fDragState == DRAG_ZOOM)) { + drawTimeRangeWindow(rangeWindowGC, fRangeStartTime, fRangeDuration); + } + + // Draws the buffer image onto the canvas. + event.gc.drawImage(rangeRectangleImage, 0, 0); + + rangeWindowGC.dispose(); + rangeRectangleImage.dispose(); + } + + /** + * Get the histogram zoom + * @return the histogram zoom + * @since 2.0 + */ + public HistogramZoom getZoom() { + return fZoom; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/Histogram.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/Histogram.java new file mode 100644 index 0000000000..25a778d144 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/Histogram.java @@ -0,0 +1,1045 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Changed to updated histogram data model + * Francois Chouinard - Reformat histogram labels on format change + * Patrick Tasse - Support selection range + * Xavier Raynaud - Support multi-trace coloring + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.histogram; + +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.events.MouseWheelListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampDelta; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; +import org.eclipse.tracecompass.tmf.ui.views.TmfView; + +/** + * Re-usable histogram widget. + * + * It has the following features: + *

      + *
    • Y-axis labels displaying min/max count values + *
    • X-axis labels displaying time range + *
    • a histogram displaying the distribution of values over time (note that + * the histogram might not necessarily fill the whole canvas) + *
    + * The widget also has 2 'markers' to identify: + *
      + *
    • a red dashed line over the bar that contains the currently selected event + *
    • a dark red dashed line that delimits the right end of the histogram (if + * it doesn't fill the canvas) + *
    + * Clicking on the histogram will select the current event at the mouse + * location. + *

    + * Once the histogram is selected, there is some limited keyboard support: + *

      + *
    • Home: go to the first histogram bar + *
    • End: go to the last histogram bar + *
    • Left: go to the previous histogram + *
    • Right: go to the next histogram bar + *
    + * Finally, when the mouse hovers over the histogram, a tool tip showing the + * following information about the corresponding histogram bar time range: + *
      + *
    • start of the time range + *
    • end of the time range + *
    • number of events in that time range + *
    + * + * @version 1.1 + * @author Francois Chouinard + */ +public abstract class Histogram implements ControlListener, PaintListener, KeyListener, MouseListener, MouseMoveListener, MouseTrackListener, IHistogramModelListener { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + // Histogram colors + + // System colors, they do not need to be disposed + private final Color fBackgroundColor = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE); + private final Color fSelectionForegroundColor = Display.getCurrent().getSystemColor(SWT.COLOR_BLUE); + private final Color fSelectionBackgroundColor = Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); + private final Color fLastEventColor = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_RED); + + // Application colors, they need to be disposed + private final Color[] fHistoBarColors = new Color[] {new Color(Display.getDefault(), 90, 90, 255), // blue + new Color(Display.getDefault(), 0, 240, 0), // green + new Color(Display.getDefault(), 255, 0, 0), // red + new Color(Display.getDefault(), 0, 255, 255), // cyan + new Color(Display.getDefault(), 255, 80, 255), // magenta + new Color(Display.getDefault(), 200, 200, 0), // yellow + new Color(Display.getDefault(), 200, 150, 0), // brown + new Color(Display.getDefault(), 150, 255, 150), // light green + new Color(Display.getDefault(), 200, 80, 80), // dark red + new Color(Display.getDefault(), 30, 150, 150), // dark cyan + new Color(Display.getDefault(), 200, 200, 255), // light blue + new Color(Display.getDefault(), 0, 120, 0), // dark green + new Color(Display.getDefault(), 255, 150, 150), // lighter red + new Color(Display.getDefault(), 140, 80, 140), // dark magenta + new Color(Display.getDefault(), 150, 100, 50), // brown + new Color(Display.getDefault(), 255, 80, 80), // light red + new Color(Display.getDefault(), 200, 200, 200), // light grey + new Color(Display.getDefault(), 255, 200, 80), // orange + new Color(Display.getDefault(), 255, 255, 80), // pale yellow + new Color(Display.getDefault(), 255, 200, 200), // pale red + new Color(Display.getDefault(), 255, 200, 255), // pale magenta + new Color(Display.getDefault(), 255, 255, 200), // pale pale yellow + new Color(Display.getDefault(), 200, 255, 255), // pale pale blue + }; + private final Color fTimeRangeColor = new Color(Display.getCurrent(), 255, 128, 0); + private final Color fLostEventColor = new Color(Display.getCurrent(), 208, 62, 120); + + // Drag states + /** + * No drag in progress + * @since 2.2 + */ + protected final int DRAG_NONE = 0; + /** + * Drag the selection + * @since 2.2 + */ + protected final int DRAG_SELECTION = 1; + /** + * Drag the time range + * @since 2.2 + */ + protected final int DRAG_RANGE = 2; + /** + * Drag the zoom range + * @since 2.2 + */ + protected final int DRAG_ZOOM = 3; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The parent TMF view. + */ + protected TmfView fParentView; + + private Composite fComposite; + private Font fFont; + + // Histogram text fields + private Label fMaxNbEventsLabel; + private Label fMinNbEventsLabel; + private Label fTimeRangeStartLabel; + private Label fTimeRangeEndLabel; + + /** + * Histogram drawing area + */ + protected Canvas fCanvas; + + /** + * The histogram data model. + */ + protected final HistogramDataModel fDataModel; + + /** + * The histogram data model scaled to current resolution and screen width. + */ + protected HistogramScaledData fScaledData; + + /** + * The current event value + */ + protected long fCurrentEventTime = 0L; + + /** + * The current selection begin time + */ + private long fSelectionBegin = 0L; + + /** + * The current selection end time + */ + private long fSelectionEnd = 0L; + + /** + * The drag state + * @see #DRAG_NONE + * @see #DRAG_SELECTION + * @see #DRAG_RANGE + * @see #DRAG_ZOOM + * @since 2.2 + */ + protected int fDragState = DRAG_NONE; + + /** + * The button that started a mouse drag, or 0 if no drag in progress + * @since 2.2 + */ + protected int fDragButton = 0; + + /** + * The bucket display offset + */ + private int fOffset = 0; + + /** + * show the traces or not + * @since 3.0 + */ + static boolean showTraces = true; + + // ------------------------------------------------------------------------ + // Construction + // ------------------------------------------------------------------------ + + /** + * Full constructor. + * + * @param view A reference to the parent TMF view. + * @param parent A parent composite + */ + public Histogram(final TmfView view, final Composite parent) { + fParentView = view; + + fComposite = createWidget(parent); + fDataModel = new HistogramDataModel(); + fDataModel.addHistogramListener(this); + clear(); + + fCanvas.addControlListener(this); + fCanvas.addPaintListener(this); + fCanvas.addKeyListener(this); + fCanvas.addMouseListener(this); + fCanvas.addMouseTrackListener(this); + fCanvas.addMouseMoveListener(this); + + TmfSignalManager.register(this); + } + + /** + * Dispose resources and unregisters listeners. + */ + public void dispose() { + TmfSignalManager.deregister(this); + fLostEventColor.dispose(); + for (Color c : fHistoBarColors) { + c.dispose(); + } + fTimeRangeColor.dispose(); + fFont.dispose(); + fDataModel.removeHistogramListener(this); + fDataModel.dispose(); + } + + private Composite createWidget(final Composite parent) { + + fFont = adjustFont(parent); + + final int initalWidth = 10; + + // -------------------------------------------------------------------- + // Define the histogram + // -------------------------------------------------------------------- + + final GridLayout gridLayout = new GridLayout(); + gridLayout.numColumns = 3; + gridLayout.marginHeight = 0; + gridLayout.marginWidth = 0; + gridLayout.marginTop = 0; + gridLayout.horizontalSpacing = 0; + gridLayout.verticalSpacing = 0; + gridLayout.marginLeft = 0; + gridLayout.marginRight = 0; + final Composite composite = new Composite(parent, SWT.FILL); + composite.setLayout(gridLayout); + + // Use all the horizontal space + GridData gridData = new GridData(); + gridData.horizontalAlignment = SWT.FILL; + gridData.verticalAlignment = SWT.FILL; + gridData.grabExcessHorizontalSpace = true; + gridData.grabExcessVerticalSpace = true; + composite.setLayoutData(gridData); + + // Y-axis max event + gridData = new GridData(); + gridData.horizontalAlignment = SWT.RIGHT; + gridData.verticalAlignment = SWT.TOP; + fMaxNbEventsLabel = new Label(composite, SWT.RIGHT); + fMaxNbEventsLabel.setFont(fFont); + fMaxNbEventsLabel.setText("0"); //$NON-NLS-1$ + fMaxNbEventsLabel.setLayoutData(gridData); + + // Histogram itself + Composite canvasComposite = new Composite(composite, SWT.BORDER); + gridData = new GridData(); + gridData.horizontalSpan = 2; + gridData.verticalSpan = 2; + gridData.horizontalAlignment = SWT.FILL; + gridData.verticalAlignment = SWT.FILL; + gridData.heightHint = 0; + gridData.widthHint = 0; + gridData.grabExcessHorizontalSpace = true; + gridData.grabExcessVerticalSpace = true; + canvasComposite.setLayoutData(gridData); + canvasComposite.setLayout(new FillLayout()); + fCanvas = new Canvas(canvasComposite, SWT.DOUBLE_BUFFERED); + fCanvas.addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent e) { + Object image = fCanvas.getData(IMAGE_KEY); + if (image instanceof Image) { + ((Image) image).dispose(); + } + } + }); + + // Y-axis min event (always 0...) + gridData = new GridData(); + gridData.horizontalAlignment = SWT.RIGHT; + gridData.verticalAlignment = SWT.BOTTOM; + fMinNbEventsLabel = new Label(composite, SWT.RIGHT); + fMinNbEventsLabel.setFont(fFont); + fMinNbEventsLabel.setText("0"); //$NON-NLS-1$ + fMinNbEventsLabel.setLayoutData(gridData); + + // Dummy cell + gridData = new GridData(initalWidth, SWT.DEFAULT); + gridData.horizontalAlignment = SWT.RIGHT; + gridData.verticalAlignment = SWT.BOTTOM; + final Label dummyLabel = new Label(composite, SWT.NONE); + dummyLabel.setLayoutData(gridData); + + // Window range start time + gridData = new GridData(); + gridData.horizontalAlignment = SWT.LEFT; + gridData.verticalAlignment = SWT.BOTTOM; + fTimeRangeStartLabel = new Label(composite, SWT.NONE); + fTimeRangeStartLabel.setFont(fFont); + fTimeRangeStartLabel.setLayoutData(gridData); + + // Window range end time + gridData = new GridData(); + gridData.horizontalAlignment = SWT.RIGHT; + gridData.verticalAlignment = SWT.BOTTOM; + fTimeRangeEndLabel = new Label(composite, SWT.NONE); + fTimeRangeEndLabel.setFont(fFont); + fTimeRangeEndLabel.setLayoutData(gridData); + + return composite; + } + + private static Font adjustFont(final Composite composite) { + // Reduce font size for a more pleasing rendering + final int fontSizeAdjustment = -2; + final Font font = composite.getFont(); + final FontData fontData = font.getFontData()[0]; + return new Font(font.getDevice(), fontData.getName(), fontData.getHeight() + fontSizeAdjustment, fontData.getStyle()); + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * Returns the start time (equal first bucket time) + * @return the start time. + */ + public long getStartTime() { + return fDataModel.getFirstBucketTime(); + } + + /** + * Returns the end time. + * @return the end time. + */ + public long getEndTime() { + return fDataModel.getEndTime(); + } + + /** + * Returns the time limit (end of last bucket) + * @return the time limit. + */ + public long getTimeLimit() { + return fDataModel.getTimeLimit(); + } + + /** + * Returns a data model reference. + * @return data model. + */ + public HistogramDataModel getDataModel() { + return fDataModel; + } + + /** + * Set the max number events to be displayed + * + * @param maxNbEvents + * the maximum number of events + */ + void setMaxNbEvents(long maxNbEvents) { + fMaxNbEventsLabel.setText(Long.toString(maxNbEvents)); + fMaxNbEventsLabel.getParent().layout(); + fCanvas.redraw(); + } + + /** + * Return true if the traces must be displayed in the histogram, + * false otherwise. + * @return whether the traces should be displayed + * @since 3.0 + */ + public boolean showTraces() { + return showTraces && fDataModel.getNbTraces() < getMaxNbTraces(); + } + + /** + * Returns the maximum number of traces the histogram can display with separate colors. + * If there is more traces, histogram will use only one color to display them. + * @return the maximum number of traces the histogram can display. + * @since 3.0 + */ + public int getMaxNbTraces() { + return fHistoBarColors.length; + } + + /** + * Returns the color used to display the trace at the given index. + * @param traceIndex a trace index + * @return a {@link Color} + * @since 3.0 + */ + public Color getTraceColor(int traceIndex) { + return fHistoBarColors[traceIndex % fHistoBarColors.length]; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + /** + * Updates the time range. + * @param startTime A start time + * @param endTime A end time. + */ + public void updateTimeRange(long startTime, long endTime) { + if (fDragState == DRAG_NONE) { + ((HistogramView) fParentView).updateTimeRange(startTime, endTime); + } + } + + /** + * Clear the histogram and reset the data + */ + public void clear() { + fDataModel.clear(); + if (fDragState == DRAG_SELECTION) { + updateSelectionTime(); + } + fDragState = DRAG_NONE; + fDragButton = 0; + synchronized (fDataModel) { + fScaledData = null; + } + } + + /** + * Sets the current selection time range and refresh the display + * + * @param beginTime The begin time of the current selection + * @param endTime The end time of the current selection + * @since 2.1 + */ + public void setSelection(final long beginTime, final long endTime) { + fSelectionBegin = (beginTime > 0) ? beginTime : 0; + fSelectionEnd = (endTime > 0) ? endTime : 0; + fDataModel.setSelectionNotifyListeners(beginTime, endTime); + } + + /** + * Computes the timestamp of the bucket at [offset] + * + * @param offset offset from the left on the histogram + * @return the start timestamp of the corresponding bucket + */ + public synchronized long getTimestamp(final int offset) { + assert offset > 0 && offset < fScaledData.fWidth; + try { + return fScaledData.fFirstBucketTime + fScaledData.fBucketDuration * offset; + } catch (final Exception e) { + return 0; // TODO: Fix that racing condition (NPE) + } + } + + /** + * Computes the offset of the timestamp in the histogram + * + * @param timestamp the timestamp + * @return the offset of the corresponding bucket (-1 if invalid) + */ + public synchronized int getOffset(final long timestamp) { + if (timestamp < fDataModel.getFirstBucketTime() || timestamp > fDataModel.getEndTime()) { + return -1; + } + return (int) ((timestamp - fDataModel.getFirstBucketTime()) / fScaledData.fBucketDuration); + } + + /** + * Set the bucket display offset + * + * @param offset + * the bucket display offset + * @since 2.2 + */ + protected void setOffset(final int offset) { + fOffset = offset; + } + + /** + * Move the currently selected bar cursor to a non-empty bucket. + * + * @param keyCode the SWT key code + */ + protected void moveCursor(final int keyCode) { + + int index; + switch (keyCode) { + + case SWT.HOME: + index = 0; + while (index < fScaledData.fLastBucket && fScaledData.fData[index].isEmpty()) { + index++; + } + if (index < fScaledData.fLastBucket) { + fScaledData.fSelectionBeginBucket = index; + } + break; + + case SWT.ARROW_RIGHT: + index = Math.max(0, fScaledData.fSelectionBeginBucket + 1); + while (index < fScaledData.fWidth && fScaledData.fData[index].isEmpty()) { + index++; + } + if (index < fScaledData.fLastBucket) { + fScaledData.fSelectionBeginBucket = index; + } + break; + + case SWT.END: + index = fScaledData.fLastBucket; + while (index >= 0 && fScaledData.fData[index].isEmpty()) { + index--; + } + if (index >= 0) { + fScaledData.fSelectionBeginBucket = index; + } + break; + + case SWT.ARROW_LEFT: + index = Math.min(fScaledData.fLastBucket - 1, fScaledData.fSelectionBeginBucket - 1); + while (index >= 0 && fScaledData.fData[index].isEmpty()) { + index--; + } + if (index >= 0) { + fScaledData.fSelectionBeginBucket = index; + } + break; + + default: + return; + } + + fScaledData.fSelectionEndBucket = fScaledData.fSelectionBeginBucket; + fSelectionBegin = getTimestamp(fScaledData.fSelectionBeginBucket); + fSelectionEnd = fSelectionBegin; + updateSelectionTime(); + } + + /** + * Refresh the histogram display + */ + @Override + public void modelUpdated() { + if (!fCanvas.isDisposed() && fCanvas.getDisplay() != null) { + fCanvas.getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + if (!fCanvas.isDisposed()) { + // Retrieve and normalize the data + final int canvasWidth = fCanvas.getBounds().width; + final int canvasHeight = fCanvas.getBounds().height; + if (canvasWidth <= 0 || canvasHeight <= 0) { + return; + } + fDataModel.setSelection(fSelectionBegin, fSelectionEnd); + fScaledData = fDataModel.scaleTo(canvasWidth, canvasHeight, 1); + synchronized (fDataModel) { + if (fScaledData != null) { + fCanvas.redraw(); + // Display histogram and update X-,Y-axis labels + updateRangeTextControls(); + long maxNbEvents = HistogramScaledData.hideLostEvents ? fScaledData.fMaxValue : fScaledData.fMaxCombinedValue; + fMaxNbEventsLabel.setText(Long.toString(maxNbEvents)); + // The Y-axis area might need to be re-sized + GridData gd = (GridData) fMaxNbEventsLabel.getLayoutData(); + gd.widthHint = Math.max(gd.widthHint, fMaxNbEventsLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).x); + fMaxNbEventsLabel.getParent().layout(); + } + } + } + } + }); + } + } + + /** + * Add a mouse wheel listener to the histogram + * @param listener the mouse wheel listener + * @since 2.0 + */ + public void addMouseWheelListener(MouseWheelListener listener) { + fCanvas.addMouseWheelListener(listener); + } + + /** + * Remove a mouse wheel listener from the histogram + * @param listener the mouse wheel listener + * @since 2.0 + */ + public void removeMouseWheelListener(MouseWheelListener listener) { + fCanvas.removeMouseWheelListener(listener); + } + + /** + * Add a key listener to the histogram + * @param listener the key listener + * @since 3.1 + */ + public void addKeyListener(KeyListener listener) { + fCanvas.addKeyListener(listener); + } + + /** + * Remove a key listener from the histogram + * @param listener the key listener + * @since 3.1 + */ + public void removeKeyListener(KeyListener listener) { + fCanvas.removeKeyListener(listener); + } + + // ------------------------------------------------------------------------ + // Helper functions + // ------------------------------------------------------------------------ + + private void updateSelectionTime() { + if (fSelectionBegin > fSelectionEnd) { + long end = fSelectionBegin; + fSelectionBegin = fSelectionEnd; + fSelectionEnd = end; + } + ((HistogramView) fParentView).updateSelectionTime(fSelectionBegin, fSelectionEnd); + } + + /** + * Update the range text controls + */ + private void updateRangeTextControls() { + if (fDataModel.getStartTime() < fDataModel.getEndTime()) { + fTimeRangeStartLabel.setText(TmfTimestampFormat.getDefaulTimeFormat().format(fDataModel.getStartTime())); + fTimeRangeEndLabel.setText(TmfTimestampFormat.getDefaulTimeFormat().format(fDataModel.getEndTime())); + } else { + fTimeRangeStartLabel.setText(""); //$NON-NLS-1$ + fTimeRangeEndLabel.setText(""); //$NON-NLS-1$ + } + } + + // ------------------------------------------------------------------------ + // PaintListener + // ------------------------------------------------------------------------ + /** + * Image key string for the canvas. + */ + protected final String IMAGE_KEY = "double-buffer-image"; //$NON-NLS-1$ + + @Override + public void paintControl(final PaintEvent event) { + + // Get the geometry + final int canvasWidth = fCanvas.getBounds().width; + final int canvasHeight = fCanvas.getBounds().height; + + // Make sure we have something to draw upon + if (canvasWidth <= 0 || canvasHeight <= 0) { + return; + } + + // Retrieve image; re-create only if necessary + Image image = (Image) fCanvas.getData(IMAGE_KEY); + if (image == null || image.getBounds().width != canvasWidth || image.getBounds().height != canvasHeight) { + if (image != null) { + image.dispose(); + } + image = new Image(event.display, canvasWidth, canvasHeight); + fCanvas.setData(IMAGE_KEY, image); + } + + // Draw the histogram on its canvas + final GC imageGC = new GC(image); + formatImage(imageGC, image); + event.gc.drawImage(image, 0, 0); + imageGC.dispose(); + } + + private void formatImage(final GC imageGC, final Image image) { + + if (fScaledData == null) { + return; + } + + final HistogramScaledData scaledData = new HistogramScaledData(fScaledData); + + try { + // Get drawing boundaries + final int width = image.getBounds().width; + final int height = image.getBounds().height; + + // Clear the drawing area + imageGC.setBackground(fBackgroundColor); + imageGC.fillRectangle(0, 0, image.getBounds().width + 1, image.getBounds().height + 1); + + // Draw the histogram bars + final int limit = width < scaledData.fWidth ? width : scaledData.fWidth; + double factor = HistogramScaledData.hideLostEvents ? scaledData.fScalingFactor : scaledData.fScalingFactorCombined; + final boolean showTracesColors = showTraces(); + for (int i = 0; i < limit; i++) { + HistogramBucket hb = scaledData.fData[i]; + int totalNbEvents = hb.getNbEvents(); + int value = (int) Math.ceil(totalNbEvents * factor); + int x = i + fOffset; + + // in Linux, the last pixel in a line is not drawn, + // so draw lost events first, one pixel too far + if (!HistogramScaledData.hideLostEvents) { + imageGC.setForeground(fLostEventColor); + final int lostEventValue = (int) Math.ceil(scaledData.fLostEventsData[i] * factor); + if (lostEventValue != 0) { + // drawing a line is inclusive, so we should remove 1 from y2 + // but we don't because Linux + imageGC.drawLine(x, height - value - lostEventValue, x, height - value); + } + } + + // then draw normal events second, to overwrite that extra pixel + if (!hb.isEmpty()) { + if (showTracesColors) { + for (int traceIndex = 0; traceIndex < hb.getNbTraces(); traceIndex++) { + int nbEventsForTrace = hb.getNbEvent(traceIndex); + if (nbEventsForTrace > 0) { + Color c = fHistoBarColors[traceIndex % fHistoBarColors.length]; + imageGC.setForeground(c); + imageGC.drawLine(x, height - value, x, height); + totalNbEvents -= nbEventsForTrace; + value = (int) Math.ceil(totalNbEvents * scaledData.fScalingFactor); + } + } + } else { + Color c = fHistoBarColors[0]; + imageGC.setForeground(c); + imageGC.drawLine(x, height - value, x, height); + } + } + } + + // Draw the selection bars + int alpha = imageGC.getAlpha(); + imageGC.setAlpha(100); + imageGC.setForeground(fSelectionForegroundColor); + imageGC.setBackground(fSelectionBackgroundColor); + final int beginBucket = scaledData.fSelectionBeginBucket + fOffset; + if (beginBucket >= 0 && beginBucket < limit) { + imageGC.drawLine(beginBucket, 0, beginBucket, height); + } + final int endBucket = scaledData.fSelectionEndBucket + fOffset; + if (endBucket >= 0 && endBucket < limit && endBucket != beginBucket) { + imageGC.drawLine(endBucket, 0, endBucket, height); + } + if (Math.abs(endBucket - beginBucket) > 1) { + if (endBucket > beginBucket) { + imageGC.fillRectangle(beginBucket + 1, 0, endBucket - beginBucket - 1, height); + } else { + imageGC.fillRectangle(endBucket + 1, 0, beginBucket - endBucket - 1, height); + } + } + imageGC.setAlpha(alpha); + + // Add a dashed line as a delimiter + int delimiterIndex = (int) ((getDataModel().getEndTime() - scaledData.getFirstBucketTime()) / scaledData.fBucketDuration) + 1; + drawDelimiter(imageGC, fLastEventColor, height, delimiterIndex); + + // Fill the area to the right of delimiter with background color + imageGC.setBackground(fComposite.getBackground()); + imageGC.fillRectangle(delimiterIndex + 1, 0, width - (delimiterIndex + 1), height); + + } catch (final Exception e) { + // Do nothing + } + } + + private static void drawDelimiter(final GC imageGC, final Color color, + final int height, final int index) { + imageGC.setBackground(color); + final int dash = height / 4; + imageGC.fillRectangle(index, 0 * dash, 1, dash - 1); + imageGC.fillRectangle(index, 1 * dash, 1, dash - 1); + imageGC.fillRectangle(index, 2 * dash, 1, dash - 1); + imageGC.fillRectangle(index, 3 * dash, 1, height - 3 * dash); + } + + /** + * Draw a time range window + * + * @param imageGC + * the GC + * @param rangeStartTime + * the range start time + * @param rangeDuration + * the range duration + * @since 2.2 + */ + protected void drawTimeRangeWindow(GC imageGC, long rangeStartTime, long rangeDuration) { + + if (fScaledData == null) { + return; + } + + // Map times to histogram coordinates + long bucketSpan = Math.max(fScaledData.fBucketDuration, 1); + long startTime = Math.min(rangeStartTime, rangeStartTime + rangeDuration); + int rangeWidth = (int) (Math.abs(rangeDuration) / bucketSpan); + + int left = (int) ((startTime - fDataModel.getFirstBucketTime()) / bucketSpan); + int right = left + rangeWidth; + int center = (left + right) / 2; + int height = fCanvas.getSize().y; + int arc = Math.min(15, rangeWidth); + + // Draw the selection window + imageGC.setForeground(fTimeRangeColor); + imageGC.setLineWidth(1); + imageGC.setLineStyle(SWT.LINE_SOLID); + imageGC.drawRoundRectangle(left, 0, rangeWidth, height - 1, arc, arc); + + // Fill the selection window + imageGC.setBackground(fTimeRangeColor); + imageGC.setAlpha(35); + imageGC.fillRoundRectangle(left + 1, 1, rangeWidth - 1, height - 2, arc, arc); + imageGC.setAlpha(255); + + // Draw the cross hair + imageGC.setForeground(fTimeRangeColor); + imageGC.setLineWidth(1); + imageGC.setLineStyle(SWT.LINE_SOLID); + + int chHalfWidth = ((rangeWidth < 60) ? (rangeWidth * 2) / 3 : 40) / 2; + imageGC.drawLine(center - chHalfWidth, height / 2, center + chHalfWidth, height / 2); + imageGC.drawLine(center, (height / 2) - chHalfWidth, center, (height / 2) + chHalfWidth); + } + + // ------------------------------------------------------------------------ + // KeyListener + // ------------------------------------------------------------------------ + + @Override + public void keyPressed(final KeyEvent event) { + moveCursor(event.keyCode); + } + + @Override + public void keyReleased(final KeyEvent event) { + } + + // ------------------------------------------------------------------------ + // MouseListener + // ------------------------------------------------------------------------ + + @Override + public void mouseDoubleClick(final MouseEvent event) { + } + + @Override + public void mouseDown(final MouseEvent event) { + if (fScaledData != null && event.button == 1 && fDragState == DRAG_NONE && fDataModel.getStartTime() < fDataModel.getEndTime()) { + fDragState = DRAG_SELECTION; + fDragButton = event.button; + if ((event.stateMask & SWT.MODIFIER_MASK) == SWT.SHIFT) { + if (Math.abs(event.x - fScaledData.fSelectionBeginBucket) < Math.abs(event.x - fScaledData.fSelectionEndBucket)) { + fScaledData.fSelectionBeginBucket = fScaledData.fSelectionEndBucket; + fSelectionBegin = fSelectionEnd; + } + fSelectionEnd = Math.min(getTimestamp(event.x), getEndTime()); + fScaledData.fSelectionEndBucket = (int) ((fSelectionEnd - fScaledData.fFirstBucketTime) / fScaledData.fBucketDuration); + } else { + fSelectionBegin = Math.min(getTimestamp(event.x), getEndTime()); + fScaledData.fSelectionBeginBucket = (int) ((fSelectionBegin - fScaledData.fFirstBucketTime) / fScaledData.fBucketDuration); + fSelectionEnd = fSelectionBegin; + fScaledData.fSelectionEndBucket = fScaledData.fSelectionBeginBucket; + } + fCanvas.redraw(); + } + } + + @Override + public void mouseUp(final MouseEvent event) { + if (fDragState == DRAG_SELECTION && event.button == fDragButton) { + fDragState = DRAG_NONE; + fDragButton = 0; + updateSelectionTime(); + } + } + + // ------------------------------------------------------------------------ + // MouseMoveListener + // ------------------------------------------------------------------------ + + /** + * @since 2.2 + */ + @Override + public void mouseMove(MouseEvent event) { + if (fDragState == DRAG_SELECTION && fDataModel.getStartTime() < fDataModel.getEndTime()) { + fSelectionEnd = Math.max(getStartTime(), Math.min(getEndTime(), getTimestamp(event.x))); + fScaledData.fSelectionEndBucket = (int) ((fSelectionEnd - fScaledData.fFirstBucketTime) / fScaledData.fBucketDuration); + fCanvas.redraw(); + } + } + + // ------------------------------------------------------------------------ + // MouseTrackListener + // ------------------------------------------------------------------------ + + @Override + public void mouseEnter(final MouseEvent event) { + } + + @Override + public void mouseExit(final MouseEvent event) { + } + + @Override + public void mouseHover(final MouseEvent event) { + if (fDataModel.getStartTime() < fDataModel.getEndTime() && fScaledData != null) { + int delimiterIndex = (int) ((fDataModel.getEndTime() - fScaledData.getFirstBucketTime()) / fScaledData.fBucketDuration) + 1; + if (event.x < delimiterIndex) { + final String tooltip = formatToolTipLabel(event.x - fOffset); + fCanvas.setToolTipText(tooltip); + return; + } + } + fCanvas.setToolTipText(null); + } + + private String formatToolTipLabel(final int index) { + long startTime = fScaledData.getBucketStartTime(index); + // negative values are possible if time values came into the model in decreasing order + if (startTime < 0) { + startTime = 0; + } + final long endTime = fScaledData.getBucketEndTime(index); + final int nbEvents = (index >= 0) ? fScaledData.fData[index].getNbEvents() : 0; + final String newLine = System.getProperty("line.separator"); //$NON-NLS-1$ + final StringBuffer buffer = new StringBuffer(); + int selectionBeginBucket = Math.min(fScaledData.fSelectionBeginBucket, fScaledData.fSelectionEndBucket); + int selectionEndBucket = Math.max(fScaledData.fSelectionBeginBucket, fScaledData.fSelectionEndBucket); + if (selectionBeginBucket <= index && index <= selectionEndBucket && fSelectionBegin != fSelectionEnd) { + TmfTimestampDelta delta = new TmfTimestampDelta(Math.abs(fSelectionEnd - fSelectionBegin), ITmfTimestamp.NANOSECOND_SCALE); + buffer.append(NLS.bind(Messages.Histogram_selectionSpanToolTip, delta.toString())); + buffer.append(newLine); + } + buffer.append(NLS.bind(Messages.Histogram_bucketRangeToolTip, + new TmfTimestamp(startTime, ITmfTimestamp.NANOSECOND_SCALE).toString(), + new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE).toString())); + buffer.append(newLine); + buffer.append(NLS.bind(Messages.Histogram_eventCountToolTip, nbEvents)); + if (!HistogramScaledData.hideLostEvents) { + final int nbLostEvents = (index >= 0) ? fScaledData.fLostEventsData[index] : 0; + buffer.append(newLine); + buffer.append(NLS.bind(Messages.Histogram_lostEventCountToolTip, nbLostEvents)); + } + return buffer.toString(); + } + + // ------------------------------------------------------------------------ + // ControlListener + // ------------------------------------------------------------------------ + + @Override + public void controlMoved(final ControlEvent event) { + fDataModel.complete(); + } + + @Override + public void controlResized(final ControlEvent event) { + fDataModel.complete(); + } + + // ------------------------------------------------------------------------ + // Signal Handlers + // ------------------------------------------------------------------------ + + /** + * Format the timestamp and update the display + * + * @param signal + * the incoming signal + * @since 2.0 + */ + @TmfSignalHandler + public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) { + updateRangeTextControls(); + + fComposite.layout(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramBucket.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramBucket.java new file mode 100644 index 0000000000..a6ae1625d5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramBucket.java @@ -0,0 +1,175 @@ +/******************************************************************************* + * Copyright (c) 2014 Kalray + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xavier Raynaud - Initial API and implementation + * Patrick Tasse - Fix concurrency issue + *******************************************************************************/ +package org.eclipse.tracecompass.tmf.ui.views.histogram; + +import java.util.Arrays; + +/** + * This class counts events for a particular time range, taking into account origin of the event. + * @author Xavier Raynaud + * @since 3.0 + */ +public class HistogramBucket { + + private int fNbEvents = 0; + private int fEvents[]; + + /** + * Constructor + * @param traceCount number of traces of the experiment. + */ + public HistogramBucket(int traceCount) { + fEvents = new int[traceCount]; + } + + /** + * Constructor + * @param values list of values + */ + public HistogramBucket(int... values) { + fEvents = values; + for (int i : fEvents) { + fNbEvents += i; + } + } + + /** + * Copy Constructor + * @param b a HistogramBucket to copy + */ + public HistogramBucket(HistogramBucket b) { + add(b); + } + + /** + * Merge Constructor + * @param b1 a HistogramBucket + * @param b2 another HistogramBucket + */ + public HistogramBucket(HistogramBucket b1, HistogramBucket b2) { + add(b1); + add(b2); + } + + /** + * @return the number of events in this bucket + */ + public int getNbEvents() { + return fNbEvents; + } + + /** + * Add an event in this bucket + * @param traceIndex a trace index - see {@link HistogramDataModel#setTrace}. + */ + public synchronized void addEvent(int traceIndex) { + ensureCapacity(traceIndex + 1); + fEvents[traceIndex]++; + fNbEvents++; + } + + private void ensureCapacity(int len) { + if (fEvents == null) { + fEvents = new int[len]; + } else if (fEvents.length < len) { + int[] oldArray = fEvents; + fEvents = new int[len]; + System.arraycopy(oldArray, 0, fEvents, 0, oldArray.length); + } + } + + /** + * Gets the number of event in this bucket belonging to given trace + * @param traceIndex a trace index + * @return the number of events in this bucket belonging to the given trace + */ + public int getNbEvent(int traceIndex) { + if (fEvents == null || fEvents.length<= traceIndex) { + return 0; + } + return fEvents[traceIndex]; + } + + /** + * @return the number of traces in this bucket + */ + public int getNbTraces() { + if (fEvents == null) { + return 0; + } + return fEvents.length; + } + + /** + * Merge the given bucket in this one. + * @param histogramBucket a bucket to merge in this one. + */ + public synchronized void add(HistogramBucket histogramBucket) { + if (histogramBucket != null && histogramBucket.fNbEvents != 0) { + int len = histogramBucket.fEvents.length; + ensureCapacity(len); + for (int i = 0; i < len; i++) { + int nbEvents = histogramBucket.fEvents[i]; + fEvents[i] += nbEvents; + fNbEvents += nbEvents; + } + } + } + + /** + * @return true if this bucket contains no event, false otherwise. + */ + public boolean isEmpty() { + return fNbEvents == 0; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(fEvents); + result = prime * result + fNbEvents; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + HistogramBucket other = (HistogramBucket) obj; + if (fNbEvents != other.fNbEvents) { + return false; + } + if (fNbEvents != 0 && !Arrays.equals(fEvents, other.fEvents)) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(fNbEvents); + sb.append(": "); //$NON-NLS-1$ + sb.append(Arrays.toString(fEvents)); + return sb.toString(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramCurrentTimeControl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramCurrentTimeControl.java new file mode 100644 index 0000000000..ed0978ed01 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramCurrentTimeControl.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Moved from LTTng to TMF + * Francois Chouinard - Simplified constructor, handle interval format change + * Patrick Tasse - Update value handling + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.histogram; + +import java.text.ParseException; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +/** + * This control provides a group containing a text control. + * + * @version 1.1 + * @author Francois Chouinard + */ +public class HistogramCurrentTimeControl extends HistogramTextControl { + + // ------------------------------------------------------------------------ + // Construction + // ------------------------------------------------------------------------ + + /** + * Standard constructor + * + * @param parentView A parent histogram view + * @param parent A parent composite to draw in + * @param label A label + * @param value A value + * @since 2.0 + */ + public HistogramCurrentTimeControl(HistogramView parentView, Composite parent, + String label, long value) + { + super(parentView, parent, label, value); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Override + protected void updateValue() { + if (getValue() == Long.MIN_VALUE) { + fTextValue.setText(""); //$NON-NLS-1$ + return; + } + String string = fTextValue.getText(); + long value = getValue(); + try { + value = TmfTimestampFormat.getDefaulTimeFormat().parseValue(string, getValue()); + } catch (ParseException e) { + } + if (getValue() != value) { + // Make sure that the new time is within range + ITmfTrace trace = fParentView.getTrace(); + if (trace != null) { + TmfTimeRange range = trace.getTimeRange(); + long startTime = range.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long endTime = range.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + if (value < startTime) { + value = startTime; + } else if (value > endTime) { + value = endTime; + } + } + + // Set and propagate + setValue(value); + updateSelectionTime(value); + } else { + setValue(value); + } + } + + /** + * Update the selection time + * + * @param time + * the new selected time + * @since 2.2 + */ + protected void updateSelectionTime(long time) { + fParentView.updateSelectionTime(time, time); + } + + @Override + public void setValue(long time) { + if (time != Long.MIN_VALUE) { + super.setValue(time, new TmfTimestamp(time, ITmfTimestamp.NANOSECOND_SCALE).toString()); + } else { + super.setValue(time, ""); //$NON-NLS-1$ + } + } + + // ------------------------------------------------------------------------ + // Signal Handlers + // ------------------------------------------------------------------------ + + /** + * Format the timestamp and update the display. Compute the new text size, + * adjust the text and group widgets and then refresh the view layout. + * + * @param signal the incoming signal + * @since 2.0 + */ + @TmfSignalHandler + public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) { + setValue(getValue()); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramDataModel.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramDataModel.java new file mode 100644 index 0000000000..cc723a7626 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramDataModel.java @@ -0,0 +1,717 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Implementation of new interfaces/listeners and support for + * time stamp in any order + * Francois Chouinard - Moved from LTTng to TMF + * Francois Chouinard - Added support for empty initial buckets + * Patrick Tasse - Support selection range + * Jean-Christian Kouamé, Simon Delisle - Added support to manage lost events + * Xavier Raynaud - Support multi-trace coloring + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.histogram; + +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; + +/** + * Histogram-independent data model. + * + * It has the following characteristics: + *
      + *
    • The basetime is the timestamp of the first event + *
    • There is a fixed number (n) of buckets of uniform duration + * (d) + *
    • The timespan of the model is thus: n * d time units + *
    • Bucket i holds the number of events that occurred in time range: + * [basetime + i * d, basetime + (i + 1) * + * d) + *
    + * Initially, the bucket durations is set to 1ns. As the events are read, they + * are tallied (using countEvent()) in the appropriate bucket (relative + * to the basetime). + *

    + * Eventually, an event will have a timestamp that exceeds the timespan + * high end (determined by n, the number of buckets, and d, the + * bucket duration). At this point, the histogram needs to be compacted. This is + * done by simply merging adjacent buckets by pair, in effect doubling the + * timespan (timespan' = n * d', where d' = + * 2d). This compaction happens as needed as the trace is read. + *

    + * The model allows for timestamps in not increasing order. The timestamps can + * be fed to the model in any order. If an event has a timestamp less than the + * basetime, the buckets will be moved to the right to account for the + * new smaller timestamp. The new basetime is a multiple of the bucket + * duration smaller then the previous basetime. Note that the + * basetime might no longer be the timestamp of an event. If necessary, + * the buckets will be compacted before moving to the right. This might be + * necessary to not lose any event counts at the end of the buckets array. + *

    + * The mapping from the model to the UI is performed by the scaleTo() + * method. By keeping the number of buckets n relatively large with + * respect to to the number of pixels in the actual histogram, we should achieve + * a nice result when visualizing the histogram. + *

    + * + * @version 2.0 + * @author Francois Chouinard + */ +public class HistogramDataModel implements IHistogramDataModel { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The default number of buckets + */ + public static final int DEFAULT_NUMBER_OF_BUCKETS = 16 * 1000; + + /** + * Number of events after which listeners will be notified. + */ + public static final int REFRESH_FREQUENCY = DEFAULT_NUMBER_OF_BUCKETS; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // Trace management + private ITmfTrace fTrace = null; + private final Map fTraceMap = new LinkedHashMap<>(); + + // Bucket management + private final int fNbBuckets; + private final HistogramBucket[] fBuckets; + private final long[] fLostEventsBuckets; + private long fBucketDuration; + private long fNbEvents; + private int fLastBucket; + + // Timestamps + private long fFirstBucketTime; // could be negative when analyzing events with descending order!!! + private long fFirstEventTime; + private long fEndTime; + private long fSelectionBegin; + private long fSelectionEnd; + private long fTimeLimit; + + // Private listener lists + private final ListenerList fModelListeners; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor with default number of buckets. + */ + public HistogramDataModel() { + this(0, DEFAULT_NUMBER_OF_BUCKETS); + } + + /** + * Default constructor with default number of buckets. + * + * @param startTime + * The histogram start time + * @since 2.0 + */ + public HistogramDataModel(long startTime) { + this(startTime, DEFAULT_NUMBER_OF_BUCKETS); + } + + /** + * Constructor with non-default number of buckets. + * + * @param nbBuckets + * A number of buckets. + */ + public HistogramDataModel(int nbBuckets) { + this(0, nbBuckets); + } + + /** + * Constructor with non-default number of buckets. + * + * @param startTime + * the histogram start time + * @param nbBuckets + * A number of buckets. + * @since 2.0 + */ + public HistogramDataModel(long startTime, int nbBuckets) { + fFirstBucketTime = fFirstEventTime = fEndTime = startTime; + fNbBuckets = nbBuckets; + fBuckets = new HistogramBucket[nbBuckets]; + fLostEventsBuckets = new long[nbBuckets]; + fModelListeners = new ListenerList(); + clear(); + } + + /** + * Copy constructor. + * + * @param other + * A model to copy. + */ + public HistogramDataModel(HistogramDataModel other) { + fNbBuckets = other.fNbBuckets; + fBuckets = new HistogramBucket[fNbBuckets]; + for (int i = 0; i < fNbBuckets; i++) { + fBuckets[i] = new HistogramBucket(other.fBuckets[i]); + } + fLostEventsBuckets = Arrays.copyOf(other.fLostEventsBuckets, fNbBuckets); + fBucketDuration = Math.max(other.fBucketDuration, 1); + fNbEvents = other.fNbEvents; + fLastBucket = other.fLastBucket; + fFirstBucketTime = other.fFirstBucketTime; + fFirstEventTime = other.fFirstEventTime; + fEndTime = other.fEndTime; + fSelectionBegin = other.fSelectionBegin; + fSelectionEnd = other.fSelectionEnd; + fTimeLimit = other.fTimeLimit; + fModelListeners = new ListenerList(); + Object[] listeners = other.fModelListeners.getListeners(); + for (Object listener : listeners) { + fModelListeners.add(listener); + } + } + + + /** + * Disposes the data model + * @since 3.0 + */ + public void dispose() { + fTraceMap.clear(); + fTrace = null; + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * Returns the number of events in the data model. + * + * @return number of events. + */ + public long getNbEvents() { + return fNbEvents; + } + + /** + * Returns the number of buckets in the model. + * + * @return number of buckets. + */ + public int getNbBuckets() { + return fNbBuckets; + } + + /** + * Returns the current bucket duration. + * + * @return bucket duration + */ + public long getBucketDuration() { + return fBucketDuration; + } + + /** + * Returns the time value of the first bucket in the model. + * + * @return time of first bucket. + */ + public long getFirstBucketTime() { + return fFirstBucketTime; + } + + /** + * Returns the time of the first event in the model. + * + * @return time of first event. + */ + public long getStartTime() { + return fFirstEventTime; + } + + /** + * Sets the trace of this model. + * @param trace - a {@link ITmfTrace} + * @since 3.0 + */ + public void setTrace(ITmfTrace trace) { + this.fTrace = trace; + fTraceMap.clear(); + ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace); + if (traces != null) { + int i = 0; + for (ITmfTrace tr : traces) { + fTraceMap.put(tr, i); + i++; + } + } + } + + /** + * Gets the trace of this model. + * @return a {@link ITmfTrace} + * @since 3.0 + */ + public ITmfTrace getTrace() { + return this.fTrace; + } + + /** + * Gets the traces names of this model. + * @return an array of trace names + * @since 3.0 + */ + public String[] getTraceNames() { + ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace); + if (traces == null) { + return new String[0]; + } + String[] traceNames = new String[traces.length]; + int i = 0; + for (ITmfTrace tr : traces) { + traceNames[i] = tr.getName(); + i++; + } + return traceNames; + } + + /** + * Gets the number of traces of this model. + * @return the number of traces of this model. + * @since 3.0 + */ + public int getNbTraces() { + ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace); + if (traces == null) { + return 1; // + } + return traces.length; + } + + /** + * Sets the model start time + * + * @param startTime + * the histogram range start time + * @param endTime + * the histogram range end time + * @since 2.0 + */ + public void setTimeRange(long startTime, long endTime) { + fFirstBucketTime = fFirstEventTime = fEndTime = startTime; + fBucketDuration = 1; + updateEndTime(); + while (endTime >= fTimeLimit) { + mergeBuckets(); + } + } + + /** + * Set the end time. Setting this ensures that the corresponding bucket is + * displayed regardless of the event counts. + * + * @param endTime + * the time of the last used bucket + * @since 2.2 + */ + public void setEndTime(long endTime) { + fEndTime = endTime; + fLastBucket = (int) ((endTime - fFirstBucketTime) / fBucketDuration); + } + + /** + * Returns the end time. + * + * @return the time of the last used bucket + */ + public long getEndTime() { + return fEndTime; + } + + /** + * Returns the begin time of the current selection in the model. + * + * @return the begin time of the current selection. + * @since 2.1 + */ + public long getSelectionBegin() { + return fSelectionBegin; + } + + /** + * Returns the end time of the current selection in the model. + * + * @return the end time of the current selection. + * @since 2.1 + */ + public long getSelectionEnd() { + return fSelectionEnd; + } + + /** + * Returns the time limit with is: start time + nbBuckets * bucketDuration + * + * @return the time limit. + */ + public long getTimeLimit() { + return fTimeLimit; + } + + // ------------------------------------------------------------------------ + // Listener handling + // ------------------------------------------------------------------------ + + /** + * Add a listener to the model to be informed about model changes. + * + * @param listener + * A listener to add. + */ + public void addHistogramListener(IHistogramModelListener listener) { + fModelListeners.add(listener); + } + + /** + * Remove a given model listener. + * + * @param listener + * A listener to remove. + */ + public void removeHistogramListener(IHistogramModelListener listener) { + fModelListeners.remove(listener); + } + + // Notify listeners (always) + private void fireModelUpdateNotification() { + fireModelUpdateNotification(0); + } + + // Notify listener on boundary + private void fireModelUpdateNotification(long count) { + if ((count % REFRESH_FREQUENCY) == 0) { + Object[] listeners = fModelListeners.getListeners(); + for (Object listener2 : listeners) { + IHistogramModelListener listener = (IHistogramModelListener) listener2; + listener.modelUpdated(); + } + } + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Override + public void complete() { + fireModelUpdateNotification(); + } + + /** + * Clear the histogram model. + * + * @see org.eclipse.tracecompass.tmf.ui.views.distribution.model.IBaseDistributionModel#clear() + */ + @Override + public void clear() { + Arrays.fill(fBuckets, null); + Arrays.fill(fLostEventsBuckets, 0); + fNbEvents = 0; + fFirstBucketTime = 0; + fEndTime = 0; + fSelectionBegin = 0; + fSelectionEnd = 0; + fLastBucket = 0; + fBucketDuration = 1; + updateEndTime(); + fireModelUpdateNotification(); + } + + /** + * Sets the current selection time range (no notification of listeners) + * + * @param beginTime + * The selection begin time. + * @param endTime + * The selection end time. + * @since 2.1 + */ + public void setSelection(long beginTime, long endTime) { + fSelectionBegin = beginTime; + fSelectionEnd = endTime; + } + + /** + * Sets the current selection time range with notification of listeners + * + * @param beginTime + * The selection begin time. + * @param endTime + * The selection end time. + * @since 2.1 + */ + public void setSelectionNotifyListeners(long beginTime, long endTime) { + fSelectionBegin = beginTime; + fSelectionEnd = endTime; + fireModelUpdateNotification(); + } + + /** + * Add event to the correct bucket, compacting the if needed. + * + * @param eventCount + * The current event Count (for notification purposes) + * @param timestamp + * The timestamp of the event to count + * @param trace + * The event trace + * @since 3.0 + */ + @Override + public void countEvent(long eventCount, long timestamp, ITmfTrace trace) { + + // Validate + if (timestamp < 0) { + return; + } + + // Set the start/end time if not already done + if ((fFirstBucketTime == 0) && (fLastBucket == 0) && (fBuckets[0] == null) && (timestamp > 0)) { + fFirstBucketTime = timestamp; + fFirstEventTime = timestamp; + updateEndTime(); + } + + if (timestamp < fFirstEventTime) { + fFirstEventTime = timestamp; + } + + if (fEndTime < timestamp) { + fEndTime = timestamp; + } + + if (timestamp >= fFirstBucketTime) { + + // Compact as needed + while (timestamp >= fTimeLimit) { + mergeBuckets(); + } + + } else { + + // get offset for adjustment + int offset = getOffset(timestamp); + + // Compact as needed + while ((fLastBucket + offset) >= fNbBuckets) { + mergeBuckets(); + offset = getOffset(timestamp); + } + + moveBuckets(offset); + + fLastBucket = fLastBucket + offset; + + fFirstBucketTime = fFirstBucketTime - (offset * fBucketDuration); + updateEndTime(); + } + + // Increment the right bucket + int index = (int) ((timestamp - fFirstBucketTime) / fBucketDuration); + if (fBuckets[index] == null) { + fBuckets[index] = new HistogramBucket(getNbTraces()); + } + Integer traceIndex = fTraceMap.get(trace); + if (traceIndex == null) { + traceIndex = 0; + } + fBuckets[index].addEvent(traceIndex); + fNbEvents++; + if (fLastBucket < index) { + fLastBucket = index; + } + + fireModelUpdateNotification(eventCount); + } + + /** + * Add lost event to the correct bucket, compacting the if needed. + * + * @param timeRange + * time range of a lost event + * @param nbLostEvents + * the number of lost events + * @param fullRange + * Full range or time range for histogram request + * @since 2.2 + */ + public void countLostEvent(TmfTimeRange timeRange, long nbLostEvents, boolean fullRange) { + + // Validate + if (timeRange.getStartTime().getValue() < 0 || timeRange.getEndTime().getValue() < 0) { + return; + } + + // Compact as needed + if (fullRange) { + while (timeRange.getEndTime().getValue() >= fTimeLimit) { + mergeBuckets(); + } + } + + int indexStart = (int) ((timeRange.getStartTime().getValue() - fFirstBucketTime) / fBucketDuration); + int indexEnd = (int) ((timeRange.getEndTime().getValue() - fFirstBucketTime) / fBucketDuration); + int nbBucketRange = (indexEnd - indexStart) + 1; + + int lostEventPerBucket = (int) Math.ceil((double) nbLostEvents / nbBucketRange); + long lastLostCol = Math.max(1, nbLostEvents - lostEventPerBucket * (nbBucketRange - 1)); + + // Increment the right bucket, bear in mind that ranges make it almost certain that some lost events are out of range + for (int index = indexStart; index <= indexEnd && index < fLostEventsBuckets.length; index++) { + if (index == (indexStart + nbBucketRange - 1)) { + fLostEventsBuckets[index] += lastLostCol; + } else { + fLostEventsBuckets[index] += lostEventPerBucket; + } + } + + fNbEvents++; + + fireModelUpdateNotification(nbLostEvents); + } + + /** + * Scale the model data to the width, height and bar width requested. + * + * @param width + * A width of the histogram canvas + * @param height + * A height of the histogram canvas + * @param barWidth + * A width (in pixel) of a histogram bar + * @return the result array of size [width] and where the highest value + * doesn't exceed [height] + * + * @see org.eclipse.tracecompass.tmf.ui.views.histogram.IHistogramDataModel#scaleTo(int, + * int, int) + */ + @Override + public HistogramScaledData scaleTo(int width, int height, int barWidth) { + // Basic validation + if ((width <= 0) || (height <= 0) || (barWidth <= 0)) + { + throw new AssertionError("Invalid histogram dimensions (" + width + "x" + height + ", barWidth=" + barWidth + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + + // The result structure + HistogramScaledData result = new HistogramScaledData(width, height, barWidth); + + // Scale horizontally + result.fMaxValue = 0; + + int nbBars = width / barWidth; + int bucketsPerBar = (fLastBucket / nbBars) + 1; + result.fBucketDuration = Math.max(bucketsPerBar * fBucketDuration, 1); + for (int i = 0; i < nbBars; i++) { + int count = 0; + int countLostEvent = 0; + result.fData[i] = new HistogramBucket(getNbTraces()); + for (int j = i * bucketsPerBar; j < ((i + 1) * bucketsPerBar); j++) { + if (fNbBuckets <= j) { + break; + } + if (fBuckets[j] != null) { + count += fBuckets[j].getNbEvents(); + result.fData[i].add(fBuckets[j]); + } + countLostEvent += fLostEventsBuckets[j]; + } + result.fLostEventsData[i] = countLostEvent; + result.fLastBucket = i; + if (result.fMaxValue < count) { + result.fMaxValue = count; + } + if (result.fMaxCombinedValue < count + countLostEvent) { + result.fMaxCombinedValue = count + countLostEvent; + } + } + + // Scale vertically + if (result.fMaxValue > 0) { + result.fScalingFactor = (double) height / result.fMaxValue; + } + if (result.fMaxCombinedValue > 0) { + result.fScalingFactorCombined = (double) height / result.fMaxCombinedValue; + } + + fBucketDuration = Math.max(fBucketDuration, 1); + // Set selection begin and end index in the scaled histogram + result.fSelectionBeginBucket = (int) ((fSelectionBegin - fFirstBucketTime) / fBucketDuration) / bucketsPerBar; + result.fSelectionEndBucket = (int) ((fSelectionEnd - fFirstBucketTime) / fBucketDuration) / bucketsPerBar; + + result.fFirstBucketTime = fFirstBucketTime; + result.fFirstEventTime = fFirstEventTime; + return result; + } + + // ------------------------------------------------------------------------ + // Helper functions + // ------------------------------------------------------------------------ + + private void updateEndTime() { + fTimeLimit = fFirstBucketTime + (fNbBuckets * fBucketDuration); + } + + private void mergeBuckets() { + for (int i = 0; i < (fNbBuckets / 2); i++) { + fBuckets[i] = new HistogramBucket(fBuckets[2 * i], fBuckets[(2 * i) + 1]); + fLostEventsBuckets[i] = fLostEventsBuckets[2 * i] + fLostEventsBuckets[(2 * i) + 1]; + } + Arrays.fill(fBuckets, fNbBuckets / 2, fNbBuckets, null); + Arrays.fill(fLostEventsBuckets, fNbBuckets / 2, fNbBuckets, 0); + fBucketDuration *= 2; + updateEndTime(); + fLastBucket = (fNbBuckets / 2) - 1; + } + + private void moveBuckets(int offset) { + for (int i = fNbBuckets - 1; i >= offset; i--) { + fBuckets[i] = new HistogramBucket(fBuckets[i - offset]); + fLostEventsBuckets[i] = fLostEventsBuckets[i - offset]; + } + + for (int i = 0; i < offset; i++) { + fBuckets[i] = null; + fLostEventsBuckets[i] = 0; + } + } + + private int getOffset(long timestamp) { + int offset = (int) ((fFirstBucketTime - timestamp) / fBucketDuration); + if (((fFirstBucketTime - timestamp) % fBucketDuration) != 0) { + offset++; + } + return offset; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramRequest.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramRequest.java new file mode 100644 index 0000000000..b91ca655a0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramRequest.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * William Bourque - Initial API and implementation + * Yuriy Vashchuk - Heritage correction. + * Francois Chouinard - Cleanup and refactoring + * Francois Chouinard - Moved from LTTng to TMF + * Simon Delisle - Added a new parameter to the constructor + * Xavier Raynaud - Support multi-trace coloring + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.histogram; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfLostEvent; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; + +/** + * Class to request events for given time range from a trace to fill a + * HistogramDataModel and HistogramView. + * + * @version 1.0 + * @author Francois Chouinard + *

    + */ +public class HistogramRequest extends TmfEventRequest { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The histogram data model to fill. + */ + protected final HistogramDataModel fHistogram; + + private final boolean fFullRange; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Constructor + * + * @param histogram + * The histogram data model + * @param range + * The time range to request data + * @param rank + * The index of the first event to retrieve + * @param nbEvents + * The number of events requested + * @param blockSize + * The number of events per block + * @param execType + * The requested execution priority + * @param fullRange + * Full range or time range for histogram request + * @since 3.0 + */ + public HistogramRequest(HistogramDataModel histogram, TmfTimeRange range, + int rank, int nbEvents, int blockSize, + ITmfEventRequest.ExecutionType execType, boolean fullRange) { + super(ITmfEvent.class, range, rank, nbEvents, execType); + fHistogram = histogram; + fFullRange = fullRange; + } + + // ------------------------------------------------------------------------ + // TmfEventRequest + // ------------------------------------------------------------------------ + + /** + * Handle the event from the trace by updating the histogram data model. + * + * @param event + * a event from the trace + * @see org.eclipse.tracecompass.tmf.core.request.TmfEventRequest#handleData(org.eclipse.tracecompass.tmf.core.event.ITmfEvent) + */ + @Override + public void handleData(ITmfEvent event) { + super.handleData(event); + if (event instanceof ITmfLostEvent) { + ITmfLostEvent lostEvents = (ITmfLostEvent) event; + /* clear the old data when it is a new request */ + fHistogram.countLostEvent(lostEvents.getTimeRange(), lostEvents.getNbLostEvents(), fFullRange); + + } else { /* handle lost event */ + long timestamp = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + fHistogram.countEvent(getNbRead(), timestamp, event.getTrace()); + } + } + + /** + * Complete the request. It also notifies the histogram model about the + * completion. + * + * @see org.eclipse.tracecompass.tmf.core.request.TmfEventRequest#handleCompleted() + */ + @Override + public void handleCompleted() { + fHistogram.complete(); + super.handleCompleted(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramScaledData.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramScaledData.java new file mode 100644 index 0000000000..389f814e0d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramScaledData.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Added setter and getter and bar width support + * Francois Chouinard - Moved from LTTng to TMF + * Patrick Tasse - Support selection range + * Jean-Christian Kouamé - Support to manage lost events + * Xavier Raynaud - Support multi-trace coloring + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.histogram; + +import java.util.Arrays; + +/** + * Convenience class/struct for scaled histogram data. + * + * @version 1.0 + * @author Francois Chouinard + */ +public class HistogramScaledData { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * Indicator value that bucket is out of range (not filled). + */ + public static final int OUT_OF_RANGE_BUCKET = -1; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * Width of histogram canvas (number of pixels). + */ + public int fWidth; + /** + * Height of histogram canvas (number of pixels). + */ + public int fHeight; + /** + * Width of one histogram bar (number of pixels). + */ + public int fBarWidth; + /** + * Array of scaled values + */ + public HistogramBucket[] fData; + /** + * Array of scaled values combined including the lost events. + * This array contains the number of lost events for each bar in the histogram + * @since 2.2 + */ + public final int[] fLostEventsData; + /** + * The bucket duration of a scaled data bucket. + */ + public long fBucketDuration; + /** + * The maximum number of events of all buckets. + */ + public long fMaxValue; + /** + * the maximum of events of all buckets including the lost events + * @since 2.2 + */ + public long fMaxCombinedValue; + /** + * The index of the selection begin bucket. + * @since 2.1 + */ + public int fSelectionBeginBucket; + /** + * The index of the selection end bucket. + * @since 2.1 + */ + public int fSelectionEndBucket; + /** + * The index of the last bucket. + */ + public int fLastBucket; + /** + * The scaling factor used to fill the scaled data. + */ + public double fScalingFactor; + /** + * The scaling factor used to fill the scaled data including the lost events. + * @since 2.2 + */ + public double fScalingFactorCombined; + /** + * The scaling factor used to fill the combining scaled data including lost events + */ + /** + * Time of first bucket. + */ + public long fFirstBucketTime; + /** + * The time of the first event. + */ + public long fFirstEventTime; + /** + * show the lost events or not + * @since 2.2 + */ + public static volatile boolean hideLostEvents = false; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Constructor. + * @param width the canvas width + * @param height the canvas height + * @param barWidth the required bar width + */ + public HistogramScaledData(int width, int height, int barWidth) { + fWidth = width; + fHeight = height; + fBarWidth = barWidth; + fData = new HistogramBucket[width / fBarWidth]; + fLostEventsData = new int[width / fBarWidth]; + fBucketDuration = 1; + fMaxValue = 0; + fMaxCombinedValue = 0; + fSelectionBeginBucket = 0; + fSelectionEndBucket = 0; + fLastBucket = 0; + fScalingFactor = 1; + fScalingFactorCombined = 1; + fFirstBucketTime = 0; + } + + /** + * Copy constructor + * @param other another scaled data. + */ + public HistogramScaledData(HistogramScaledData other) { + fWidth = other.fWidth; + fHeight = other.fHeight; + fBarWidth = other.fBarWidth; + fData = Arrays.copyOf(other.fData, other.fData.length); + fLostEventsData = Arrays.copyOf(other.fLostEventsData, other.fLostEventsData.length); + fBucketDuration = other.fBucketDuration; + fMaxValue = other.fMaxValue; + fMaxCombinedValue = other.fMaxCombinedValue; + fSelectionBeginBucket = other.fSelectionBeginBucket; + fSelectionEndBucket = other.fSelectionEndBucket; + fLastBucket = other.fLastBucket; + fScalingFactor = other.fScalingFactor; + fScalingFactorCombined = other.fScalingFactorCombined; + fFirstBucketTime = other.fFirstBucketTime; + } + + // ------------------------------------------------------------------------ + // Setter and Getter + // ------------------------------------------------------------------------ + + /** + * Returns the time of the first bucket of the scaled data. + * @return the time of the first bucket. + */ + public long getFirstBucketTime() { + return fFirstBucketTime; + } + + /** + * Set the first event time. + * @param firstEventTime The time to set + */ + public void setFirstBucketTime(long firstEventTime) { + fFirstBucketTime = firstEventTime; + } + + /** + * Returns the time of the last bucket. + * @return last bucket time + */ + public long getLastBucketTime() { + return getBucketStartTime(fLastBucket); + } + + /** + * Returns the time of the bucket start time for given index. + * @param index A bucket index. + * @return the time of the bucket start time + */ + public long getBucketStartTime(int index) { + return fFirstBucketTime + index * fBucketDuration; + } + + /** + * Returns the time of the bucket end time for given index. + * @param index A bucket index. + * @return the time of the bucket end time + */ + public long getBucketEndTime(int index) { + return getBucketStartTime(index) + fBucketDuration; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramSelectionEndControl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramSelectionEndControl.java new file mode 100644 index 0000000000..c87cb403ca --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramSelectionEndControl.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.histogram; + +import org.eclipse.swt.widgets.Composite; + +/** + * Text control for selection end time + * + * @since 2.2 + */ +public class HistogramSelectionEndControl extends HistogramCurrentTimeControl { + + /** + * Standard constructor + * + * @param parentView A parent histogram view + * @param parent A parent composite to draw in + * @param label A label + * @param value A value + */ + public HistogramSelectionEndControl(HistogramView parentView, Composite parent, String label, long value) { + super(parentView, parent, label, value); + } + + @Override + protected void updateSelectionTime(long time) { + long begin = Math.min(fParentView.getSelectionBegin(), time); + long end = Math.max(fParentView.getSelectionBegin(), time); + fParentView.updateSelectionTime(begin, end); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramSelectionStartControl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramSelectionStartControl.java new file mode 100644 index 0000000000..14cc546143 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramSelectionStartControl.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.histogram; + +import org.eclipse.swt.widgets.Composite; + +/** + * Text control for selection start time + * + * @since 2.2 + */ +public class HistogramSelectionStartControl extends HistogramCurrentTimeControl { + + /** + * Standard constructor + * + * @param parentView A parent histogram view + * @param parent A parent composite to draw in + * @param label A label + * @param value A value + */ + public HistogramSelectionStartControl(HistogramView parentView, Composite parent, String label, long value) { + super(parentView, parent, label, value); + } + + @Override + protected void updateSelectionTime(long time) { + if (fParentView.getLinkState()) { + fParentView.updateSelectionTime(time, time); + } else { + long begin = Math.min(time, fParentView.getSelectionEnd()); + long end = Math.max(time, fParentView.getSelectionEnd()); + fParentView.updateSelectionTime(begin, end); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramTextControl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramTextControl.java new file mode 100644 index 0000000000..5e8c588011 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramTextControl.java @@ -0,0 +1,280 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wiliam Bourque - Adapted from SpinnerGroup (in TimeFrameView) + * Francois Chouinard - Cleanup and refactoring + * Francois Chouinard - Moved from LTTng to TMF + * Francois Chouinard - Better handling of control display, support for signals + * Patrick Tasse - Update for mouse wheel zoom + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.histogram; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseWheelListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; + +/** + * This control provides a group containing a text control. + * + * @version 1.1 + * @author Francois Chouinard + */ +public abstract class HistogramTextControl implements FocusListener, KeyListener { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The parent histogram view. + */ + protected final HistogramView fParentView; + + // Controls data + private final Composite fParent; + private Font fFont; + private final Composite fComposite; + private final Label fLabel; + + /** + * The text value field. + */ + protected final Text fTextValue; + + private long fValue; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructor with given group and text values. + * + * @param parentView The parent histogram view. + * @param parent The parent composite + * @param label The text label + * @param value The initial value + * @since 2.0 + */ + public HistogramTextControl(HistogramView parentView, Composite parent, String label, long value) + { + fParentView = parentView; + fParent = parent; + + // -------------------------------------------------------------------- + // Reduce font size for a more pleasing rendering + // -------------------------------------------------------------------- + + final int fontSizeAdjustment = -1; + final Font font = parent.getFont(); + final FontData fontData = font.getFontData()[0]; + fFont = new Font(font.getDevice(), fontData.getName(), fontData.getHeight() + fontSizeAdjustment, fontData.getStyle()); + + // -------------------------------------------------------------------- + // Create the group + // -------------------------------------------------------------------- + + // Re-used layout variables + GridLayout gridLayout; + GridData gridData; + + // Composite + gridLayout = new GridLayout(3, false); + gridLayout.marginHeight = 0; + gridLayout.marginWidth = 0; + fComposite = new Composite(fParent, SWT.NONE); + fComposite.setLayout(gridLayout); + + gridData = new GridData(SWT.FILL, SWT.CENTER, true, false); + Label filler = new Label(fComposite, SWT.NONE); + filler.setLayoutData(gridData); + + // Label + gridData = new GridData(SWT.CENTER, SWT.CENTER, false, false); + fLabel = new Label(fComposite, SWT.NONE); + fLabel.setText(label); + fLabel.setFont(fFont); + + // Text control + gridData = new GridData(SWT.CENTER, SWT.CENTER, false, false); + fTextValue = new Text(fComposite, SWT.BORDER); + fTextValue.setFont(fFont); + fTextValue.setLayoutData(gridData); + + // -------------------------------------------------------------------- + // Add listeners + // -------------------------------------------------------------------- + + fTextValue.addFocusListener(this); + fTextValue.addKeyListener(this); + + TmfSignalManager.register(this); + } + + /** + * Dispose of the widget + * @since 2.0 + */ + public void dispose() { + fFont.dispose(); + TmfSignalManager.deregister(this); + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * Returns if widget isDisposed or not + * @return true if widget is disposed else false + */ + public boolean isDisposed() { + return fComposite.isDisposed(); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Updates the text value. + */ + protected abstract void updateValue(); + + /** + * Set the Grid Layout Data for the group. + * @param layoutData A GridData to set. + */ + public void setLayoutData(GridData layoutData) { + fComposite.setLayoutData(layoutData); + } + + /** + * Enables the receiver if the argument is true, + * and disables it otherwise. A disabled control is typically + * not selectable from the user interface and draws with an + * inactive or "grayed" look. + * + * @param enabled the new enabled state + * @since 2.2 + */ + public void setEnabled(boolean enabled) { + fTextValue.setEnabled(enabled); + } + + /** + * The time value in to set in the text field. + * + * @param time the time to set + * @param displayTime the display value + * @since 2.0 + */ + protected void setValue(final long time, final String displayTime) { + // If this is the UI thread, process now + Display display = Display.getCurrent(); + if (display != null) { + if (!isDisposed()) { + fValue = time; + fTextValue.setText(displayTime); + fComposite.layout(); + fParent.getParent().layout(); + } + return; + } + + // Call self from the UI thread + if (!isDisposed()) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (!isDisposed()) { + setValue(time, displayTime); + } + } + }); + } + } + + /** + * @param time the time value to display + */ + public abstract void setValue(long time); + + /** + * Returns the time value. + * @return time value. + */ + public long getValue() { + return fValue; + } + + /** + * Add a mouse wheel listener to the text control + * @param listener the mouse wheel listener + * @since 2.0 + */ + public void addMouseWheelListener(MouseWheelListener listener) { + fTextValue.addMouseWheelListener(listener); + } + + /** + * Remove a mouse wheel listener from the text control + * @param listener the mouse wheel listener + * @since 2.0 + */ + public void removeMouseWheelListener(MouseWheelListener listener) { + fTextValue.removeMouseWheelListener(listener); + } + + // ------------------------------------------------------------------------ + // FocusListener + // ------------------------------------------------------------------------ + + @Override + public void focusGained(FocusEvent event) { + } + + @Override + public void focusLost(FocusEvent event) { + updateValue(); + } + + // ------------------------------------------------------------------------ + // KeyListener + // ------------------------------------------------------------------------ + + @Override + public void keyPressed(KeyEvent event) { + switch (event.character) { + case SWT.CR: + updateValue(); + break; + default: + break; + } + } + + @Override + public void keyReleased(KeyEvent e) { + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramTimeRangeControl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramTimeRangeControl.java new file mode 100644 index 0000000000..0eaa50fb7a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramTimeRangeControl.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Moved from LTTng to TMF + * Francois Chouinard - Simplified constructor, handle interval format change + * Patrick Tasse - Update value handling + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.histogram; + +import java.text.ParseException; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; + +/** + * This control provides a group containing a text control. + * + * @version 2.0 + * @author Francois Chouinard + */ +public class HistogramTimeRangeControl extends HistogramTextControl { + + // ------------------------------------------------------------------------ + // Construction + // ------------------------------------------------------------------------ + + /** + * Constructor with given group and text values. + * + * @param parentView The parent histogram view. + * @param parent The parent composite + * @param groupLabel A group value + * @param value A text value + * @since 2.0 + */ + public HistogramTimeRangeControl(HistogramView parentView, Composite parent, + String groupLabel, long value) + { + super(parentView, parent, groupLabel, value); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Override + protected void updateValue() { + if (getValue() == Long.MIN_VALUE) { + fTextValue.setText(""); //$NON-NLS-1$ + return; + } + String string = fTextValue.getText(); + long value = getValue(); + try { + value = TmfTimestampFormat.getDefaulIntervalFormat().parseValue(string); + if (value < 1) { + value = getValue(); + } + } catch (ParseException e) { + } + if (getValue() != value) { + fParentView.updateTimeRange(value); + } else { + setValue(value); + } + } + + @Override + public void setValue(long time) { + if (time != Long.MIN_VALUE) { + ITmfTimestamp ts = new TmfTimestamp(time, ITmfTimestamp.NANOSECOND_SCALE); + super.setValue(time, ts.toString(TmfTimestampFormat.getDefaulIntervalFormat())); + } else { + super.setValue(time, ""); //$NON-NLS-1$ + } + } + + // ------------------------------------------------------------------------ + // Signal Handlers + // ------------------------------------------------------------------------ + + /** + * Format the interval and update the display. Compute the new text size, + * adjust the text and group widgets and then refresh the view layout. + * + * @param signal the incoming signal + * @since 2.0 + */ + @TmfSignalHandler + public void intervalFormatUpdated(TmfTimestampFormatUpdateSignal signal) { + setValue(getValue()); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramView.java new file mode 100644 index 0000000000..a575619a58 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramView.java @@ -0,0 +1,887 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * William Bourque - Initial API and implementation + * Yuriy Vashchuk - GUI reorganisation, simplification and some related code improvements. + * Yuriy Vashchuk - Histograms optimisation. + * Yuriy Vashchuk - Histogram Canvas Heritage correction + * Francois Chouinard - Cleanup and refactoring + * Francois Chouinard - Moved from LTTng to TMF + * Patrick Tasse - Update for mouse wheel zoom + * Xavier Raynaud - Support multi-trace coloring + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.histogram; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.Separator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseWheelListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType; +import org.eclipse.tracecompass.tmf.core.signal.TmfRangeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalThrottler; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceRangeUpdatedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceUpdatedSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ui.views.TmfView; +import org.eclipse.ui.IActionBars; + +/** + * The purpose of this view is to provide graphical time distribution statistics about the trace events. + *

    + * The view is composed of two histograms and two controls: + *

      + *
    • an event distribution histogram for the whole trace; + *
    • an event distribution histogram for current time window (window span); + *
    • the timestamp of the currently selected event; + *
    • the window span (size of the time window of the smaller histogram). + *
    + * The histograms x-axis show their respective time range. + * + * @version 2.0 + * @author Francois Chouinard + */ +public class HistogramView extends TmfView { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The view ID as defined in plugin.xml + */ + public static final @NonNull String ID = "org.eclipse.linuxtools.tmf.ui.views.histogram"; //$NON-NLS-1$ + + private static final Image LINK_IMG = Activator.getDefault().getImageFromPath("/icons/etool16/link.gif"); //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // Parent widget + private Composite fParent; + + // The current trace + private ITmfTrace fTrace; + + // Current timestamp/time window - everything in the TIME_SCALE + private long fTraceStartTime; + private long fTraceEndTime; + private long fWindowStartTime; + private long fWindowEndTime; + private long fWindowSpan; + private long fSelectionBeginTime; + private long fSelectionEndTime; + + // Time controls + private HistogramTextControl fSelectionStartControl; + private HistogramTextControl fSelectionEndControl; + private HistogramTextControl fTimeSpanControl; + + // Link + private Label fLinkButton; + private boolean fLinkState; + + // Histogram/request for the full trace range + private static FullTraceHistogram fFullTraceHistogram; + private HistogramRequest fFullTraceRequest; + + // Histogram/request for the selected time range + private static TimeRangeHistogram fTimeRangeHistogram; + private HistogramRequest fTimeRangeRequest; + + // Legend area + private Composite fLegendArea; + private Image[] fLegendImages; + + // Throttlers for the time sync and time-range sync signals + private final TmfSignalThrottler fTimeSyncThrottle; + private final TmfSignalThrottler fTimeRangeSyncThrottle; + + // Action for toggle showing the lost events + private Action hideLostEventsAction; + // Action for toggle showing the traces + private Action showTraceAction; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + public HistogramView() { + super(ID); + fTimeSyncThrottle = new TmfSignalThrottler(this, 200); + fTimeRangeSyncThrottle = new TmfSignalThrottler(this, 200); + } + + @Override + public void dispose() { + if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) { + fTimeRangeRequest.cancel(); + } + if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) { + fFullTraceRequest.cancel(); + } + fFullTraceHistogram.dispose(); + fTimeRangeHistogram.dispose(); + fSelectionStartControl.dispose(); + fSelectionEndControl.dispose(); + fTimeSpanControl.dispose(); + super.dispose(); + } + + // ------------------------------------------------------------------------ + // TmfView + // ------------------------------------------------------------------------ + + @Override + public void createPartControl(Composite parent) { + + fParent = parent; + + // Control labels + final String selectionStartLabel = Messages.HistogramView_selectionStartLabel; + final String selectionEndLabel = Messages.HistogramView_selectionEndLabel; + final String windowSpanLabel = Messages.HistogramView_windowSpanLabel; + + // -------------------------------------------------------------------- + // Set the HistogramView layout + // -------------------------------------------------------------------- + + Composite viewComposite = new Composite(fParent, SWT.FILL); + GridLayout gridLayout = new GridLayout(); + gridLayout.numColumns = 2; + gridLayout.horizontalSpacing = 5; + gridLayout.verticalSpacing = 0; + gridLayout.marginHeight = 0; + gridLayout.marginWidth = 0; + viewComposite.setLayout(gridLayout); + + // -------------------------------------------------------------------- + // Time controls + // -------------------------------------------------------------------- + + Composite controlsComposite = new Composite(viewComposite, SWT.NONE); + gridLayout = new GridLayout(); + gridLayout.numColumns = 2; + gridLayout.marginHeight = 0; + gridLayout.marginWidth = 0; + gridLayout.horizontalSpacing = 5; + gridLayout.verticalSpacing = 1; + gridLayout.makeColumnsEqualWidth = false; + controlsComposite.setLayout(gridLayout); + GridData gridData = new GridData(SWT.FILL, SWT.CENTER, false, false); + controlsComposite.setLayoutData(gridData); + + Composite selectionGroup = new Composite(controlsComposite, SWT.BORDER); + gridLayout = new GridLayout(); + gridLayout.marginHeight = 0; + gridLayout.marginWidth = 0; + gridLayout.horizontalSpacing = 0; + gridLayout.verticalSpacing = 0; + selectionGroup.setLayout(gridLayout); + + // Selection start control + gridData = new GridData(); + gridData.horizontalAlignment = SWT.FILL; + gridData.verticalAlignment = SWT.CENTER; + fSelectionStartControl = new HistogramSelectionStartControl(this, selectionGroup, selectionStartLabel, 0L); + fSelectionStartControl.setLayoutData(gridData); + fSelectionStartControl.setValue(Long.MIN_VALUE); + + // Selection end control + gridData = new GridData(); + gridData.horizontalAlignment = SWT.FILL; + gridData.verticalAlignment = SWT.CENTER; + fSelectionEndControl = new HistogramSelectionEndControl(this, selectionGroup, selectionEndLabel, 0L); + fSelectionEndControl.setLayoutData(gridData); + fSelectionEndControl.setValue(Long.MIN_VALUE); + + // Link button + gridData = new GridData(); + fLinkButton = new Label(controlsComposite, SWT.NONE); + fLinkButton.setImage(LINK_IMG); + fLinkButton.setLayoutData(gridData); + addLinkButtonListeners(); + + // Window span time control + gridData = new GridData(); + gridData.horizontalAlignment = SWT.FILL; + gridData.verticalAlignment = SWT.CENTER; + fTimeSpanControl = new HistogramTimeRangeControl(this, controlsComposite, windowSpanLabel, 0L); + fTimeSpanControl.setLayoutData(gridData); + fTimeSpanControl.setValue(Long.MIN_VALUE); + + // -------------------------------------------------------------------- + // Time range histogram + // -------------------------------------------------------------------- + + Composite timeRangeComposite = new Composite(viewComposite, SWT.NONE); + gridLayout = new GridLayout(); + gridLayout.numColumns = 1; + gridLayout.marginHeight = 0; + gridLayout.marginWidth = 0; + gridLayout.marginTop = 5; + gridLayout.horizontalSpacing = 0; + gridLayout.verticalSpacing = 0; + gridLayout.marginLeft = 5; + gridLayout.marginRight = 5; + timeRangeComposite.setLayout(gridLayout); + + // Use remaining horizontal space + gridData = new GridData(); + gridData.horizontalAlignment = SWT.FILL; + gridData.verticalAlignment = SWT.FILL; + gridData.grabExcessHorizontalSpace = true; + gridData.grabExcessVerticalSpace = true; + timeRangeComposite.setLayoutData(gridData); + + // Histogram + fTimeRangeHistogram = new TimeRangeHistogram(this, timeRangeComposite); + + // -------------------------------------------------------------------- + // Full range histogram + // -------------------------------------------------------------------- + + Composite fullRangeComposite = new Composite(viewComposite, SWT.FILL); + gridLayout = new GridLayout(); + gridLayout.numColumns = 1; + gridLayout.marginHeight = 0; + gridLayout.marginWidth = 0; + gridLayout.marginTop = 5; + gridLayout.horizontalSpacing = 0; + gridLayout.verticalSpacing = 0; + gridLayout.marginLeft = 5; + gridLayout.marginRight = 5; + fullRangeComposite.setLayout(gridLayout); + + // Use remaining horizontal space + gridData = new GridData(); + gridData.horizontalAlignment = SWT.FILL; + gridData.verticalAlignment = SWT.FILL; + gridData.horizontalSpan = 2; + gridData.grabExcessHorizontalSpace = true; + gridData.grabExcessVerticalSpace = true; + fullRangeComposite.setLayoutData(gridData); + + // Histogram + fFullTraceHistogram = new FullTraceHistogram(this, fullRangeComposite); + + fLegendArea = new Composite(viewComposite, SWT.FILL); + fLegendArea.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, true, false, 2, 1)); + fLegendArea.setLayout(new RowLayout()); + + // Add mouse wheel listener to time span control + MouseWheelListener listener = fFullTraceHistogram.getZoom(); + fTimeSpanControl.addMouseWheelListener(listener); + + + // View Action Handling + contributeToActionBars(); + + ITmfTrace trace = getActiveTrace(); + if (trace != null) { + traceSelected(new TmfTraceSelectedSignal(this, trace)); + } + } + + @Override + public void setFocus() { + fFullTraceHistogram.fCanvas.setFocus(); + } + + void refresh() { + fParent.layout(true); + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * Returns the current trace handled by the view + * + * @return the current trace + * @since 2.0 + */ + public ITmfTrace getTrace() { + return fTrace; + } + + /** + * Returns the time range of the current selected window (base on default time scale). + * + * @return the time range of current selected window. + * @since 2.0 + */ + public TmfTimeRange getTimeRange() { + return new TmfTimeRange( + new TmfTimestamp(fWindowStartTime, ITmfTimestamp.NANOSECOND_SCALE), + new TmfTimestamp(fWindowEndTime, ITmfTimestamp.NANOSECOND_SCALE)); + } + + /** + * get the show lost events action + * + * @return The action object + * @since 2.2 + */ + public Action getShowLostEventsAction() { + if (hideLostEventsAction == null) { + /* show lost events */ + hideLostEventsAction = new Action(Messages.HistogramView_hideLostEvents, IAction.AS_CHECK_BOX) { + @Override + public void run() { + HistogramScaledData.hideLostEvents = hideLostEventsAction.isChecked(); + long maxNbEvents = HistogramScaledData.hideLostEvents ? fFullTraceHistogram.fScaledData.fMaxValue : fFullTraceHistogram.fScaledData.fMaxCombinedValue; + fFullTraceHistogram.setMaxNbEvents(maxNbEvents); + maxNbEvents = HistogramScaledData.hideLostEvents ? fTimeRangeHistogram.fScaledData.fMaxValue : fTimeRangeHistogram.fScaledData.fMaxCombinedValue; + fTimeRangeHistogram.setMaxNbEvents(maxNbEvents); + } + }; + hideLostEventsAction.setText(Messages.HistogramView_hideLostEvents); + hideLostEventsAction.setToolTipText(Messages.HistogramView_hideLostEvents); + hideLostEventsAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_LOST_EVENTS)); + } + return hideLostEventsAction; + } + + /** + * get the show trace action + * + * @return The action object + * @since 3.0 + */ + public Action getShowTraceAction() { + if (showTraceAction == null) { + /* show lost events */ + showTraceAction = new Action(Messages.HistogramView_showTraces, IAction.AS_CHECK_BOX) { + @Override + public void run() { + Histogram.showTraces = showTraceAction.isChecked(); + fFullTraceHistogram.fCanvas.redraw(); + fTimeRangeHistogram.fCanvas.redraw(); + updateLegendArea(); + } + }; + showTraceAction.setChecked(true); + showTraceAction.setText(Messages.HistogramView_showTraces); + showTraceAction.setToolTipText(Messages.HistogramView_showTraces); + showTraceAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_HIST_TRACES)); + } + return showTraceAction; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Broadcast TmfSignal about new current selection time range. + * @param beginTime the begin time of current selection. + * @param endTime the end time of current selection. + */ + void updateSelectionTime(long beginTime, long endTime) { + updateDisplayedSelectionTime(beginTime, endTime); + TmfTimestamp beginTs = new TmfTimestamp(beginTime, ITmfTimestamp.NANOSECOND_SCALE); + TmfTimestamp endTs = new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE); + TmfTimeSynchSignal signal = new TmfTimeSynchSignal(this, beginTs, endTs); + fTimeSyncThrottle.queue(signal); + } + + /** + * Get selection begin time + * @return the begin time of current selection + */ + long getSelectionBegin() { + return fSelectionBeginTime; + } + + /** + * Get selection end time + * @return the end time of current selection + */ + long getSelectionEnd() { + return fSelectionEndTime; + } + + /** + * Get the link state + * @return true if begin and end selection time should be linked + */ + boolean getLinkState() { + return fLinkState; + } + + /** + * Broadcast TmfSignal about new selection time range. + * @param startTime the new start time + * @param endTime the new end time + */ + void updateTimeRange(long startTime, long endTime) { + if (fTrace != null) { + // Build the new time range; keep the current time + TmfTimeRange timeRange = new TmfTimeRange( + new TmfTimestamp(startTime, ITmfTimestamp.NANOSECOND_SCALE), + new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE)); + fTimeSpanControl.setValue(endTime - startTime); + + updateDisplayedTimeRange(startTime, endTime); + + // Send the FW signal + TmfRangeSynchSignal signal = new TmfRangeSynchSignal(this, timeRange); + fTimeRangeSyncThrottle.queue(signal); + } + } + + /** + * Broadcast TmfSignal about new selected time range. + * @param newDuration new duration (relative to current start time) + */ + public synchronized void updateTimeRange(long newDuration) { + if (fTrace != null) { + long delta = newDuration - fWindowSpan; + long newStartTime = fWindowStartTime - (delta / 2); + setNewRange(newStartTime, newDuration); + } + } + + private void setNewRange(long startTime, long duration) { + long realStart = startTime; + + if (realStart < fTraceStartTime) { + realStart = fTraceStartTime; + } + + long endTime = realStart + duration; + if (endTime > fTraceEndTime) { + endTime = fTraceEndTime; + if ((endTime - duration) > fTraceStartTime) { + realStart = endTime - duration; + } else { + realStart = fTraceStartTime; + } + } + updateTimeRange(realStart, endTime); + } + + // ------------------------------------------------------------------------ + // Signal handlers + // ------------------------------------------------------------------------ + + /** + * Handles trace opened signal. Loads histogram if new trace time range is not + * equal TmfTimeRange.NULL_RANGE + * @param signal the trace opened signal + * @since 2.0 + */ + @TmfSignalHandler + public void traceOpened(TmfTraceOpenedSignal signal) { + assert (signal != null); + fTrace = signal.getTrace(); + loadTrace(); + } + + /** + * Handles trace selected signal. Loads histogram if new trace time range is not + * equal TmfTimeRange.NULL_RANGE + * @param signal the trace selected signal + * @since 2.0 + */ + @TmfSignalHandler + public void traceSelected(TmfTraceSelectedSignal signal) { + assert (signal != null); + if (fTrace != signal.getTrace()) { + fTrace = signal.getTrace(); + loadTrace(); + } + } + + private void loadTrace() { + initializeHistograms(); + fParent.redraw(); + } + + /** + * Handles trace closed signal. Clears the view and data model and cancels requests. + * @param signal the trace closed signal + * @since 2.0 + */ + @TmfSignalHandler + public void traceClosed(TmfTraceClosedSignal signal) { + + if (signal.getTrace() != fTrace) { + return; + } + + // Kill any running request + if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) { + fTimeRangeRequest.cancel(); + } + if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) { + fFullTraceRequest.cancel(); + } + + // Initialize the internal data + fTrace = null; + fTraceStartTime = 0L; + fTraceEndTime = 0L; + fWindowStartTime = 0L; + fWindowEndTime = 0L; + fWindowSpan = 0L; + fSelectionBeginTime = 0L; + fSelectionEndTime = 0L; + + // Clear the UI widgets + fFullTraceHistogram.clear(); + fTimeRangeHistogram.clear(); + fSelectionStartControl.setValue(Long.MIN_VALUE); + fSelectionEndControl.setValue(Long.MIN_VALUE); + + fTimeSpanControl.setValue(Long.MIN_VALUE); + + for (Control c: fLegendArea.getChildren()) { + c.dispose(); + } + if (fLegendImages != null) { + for (Image i: fLegendImages) { + i.dispose(); + } + } + fLegendImages = null; + fLegendArea.layout(); + fLegendArea.getParent().layout(); + } + + /** + * Handles trace range updated signal. Extends histogram according to the new time range. If a + * HistogramRequest is already ongoing, it will be cancelled and a new request with the new range + * will be issued. + * + * @param signal the trace range updated signal + * @since 2.0 + */ + @TmfSignalHandler + public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal) { + + if (signal.getTrace() != fTrace) { + return; + } + + TmfTimeRange fullRange = signal.getRange(); + + fTraceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + fTraceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + + fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime); + fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime); + + sendFullRangeRequest(fullRange); + } + + /** + * Handles the trace updated signal. Used to update time limits (start and end time) + * @param signal the trace updated signal + * @since 2.0 + */ + @TmfSignalHandler + public void traceUpdated(TmfTraceUpdatedSignal signal) { + if (signal.getTrace() != fTrace) { + return; + } + TmfTimeRange fullRange = signal.getTrace().getTimeRange(); + fTraceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + fTraceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + + fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime); + fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime); + + if ((fFullTraceRequest != null) && fFullTraceRequest.getRange().getEndTime().compareTo(signal.getRange().getEndTime()) < 0) { + sendFullRangeRequest(fullRange); + } +} + + /** + * Handles the current time updated signal. Sets the current time in the time range + * histogram as well as the full histogram. + * + * @param signal the signal to process + */ + @TmfSignalHandler + public void currentTimeUpdated(final TmfTimeSynchSignal signal) { + if (Display.getCurrent() == null) { + // Make sure the signal is handled in the UI thread + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (fParent.isDisposed()) { + return; + } + currentTimeUpdated(signal); + } + }); + return; + } + + // Update the selected time range + ITmfTimestamp beginTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE); + ITmfTimestamp endTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE); + updateDisplayedSelectionTime(beginTime.getValue(), endTime.getValue()); + } + + /** + * Updates the current time range in the time range histogram and full range histogram. + * @param signal the signal to process + */ + @TmfSignalHandler + public void timeRangeUpdated(final TmfRangeSynchSignal signal) { + if (Display.getCurrent() == null) { + // Make sure the signal is handled in the UI thread + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (fParent.isDisposed()) { + return; + } + timeRangeUpdated(signal); + } + }); + return; + } + + if (fTrace != null) { + // Validate the time range + TmfTimeRange range = signal.getCurrentRange().getIntersection(fTrace.getTimeRange()); + if (range == null) { + return; + } + + updateDisplayedTimeRange( + range.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(), + range.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue()); + + // Send the event request to populate the small histogram + sendTimeRangeRequest(fWindowStartTime, fWindowEndTime); + + fTimeSpanControl.setValue(fWindowSpan); + } + } + + // ------------------------------------------------------------------------ + // Helper functions + // ------------------------------------------------------------------------ + + private void initializeHistograms() { + TmfTimeRange fullRange = updateTraceTimeRange(); + long selectionBeginTime = fTraceManager.getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long selectionEndTime = fTraceManager.getSelectionEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long startTime = fTraceManager.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long duration = fTraceManager.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue() - startTime; + + if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) { + fTimeRangeRequest.cancel(); + } + fTimeRangeHistogram.clear(); + fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime); + fTimeRangeHistogram.setTimeRange(startTime, duration); + fTimeRangeHistogram.setSelection(selectionBeginTime, selectionEndTime); + fTimeRangeHistogram.fDataModel.setTrace(fTrace); + + if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) { + fFullTraceRequest.cancel(); + } + fFullTraceHistogram.clear(); + fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime); + fFullTraceHistogram.setTimeRange(startTime, duration); + fFullTraceHistogram.setSelection(selectionBeginTime, selectionEndTime); + fFullTraceHistogram.fDataModel.setTrace(fTrace); + + fWindowStartTime = startTime; + fWindowSpan = duration; + fWindowEndTime = startTime + duration; + + fSelectionBeginTime = selectionBeginTime; + fSelectionEndTime = selectionEndTime; + fSelectionStartControl.setValue(fSelectionBeginTime); + fSelectionEndControl.setValue(fSelectionEndTime); + + fTimeSpanControl.setValue(duration); + + ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace); + if (traces != null) { + this.showTraceAction.setEnabled(traces.length < fFullTraceHistogram.getMaxNbTraces()); + } + updateLegendArea(); + + if (!fullRange.equals(TmfTimeRange.NULL_RANGE)) { + sendTimeRangeRequest(startTime, startTime + duration); + sendFullRangeRequest(fullRange); + } + } + + private void updateLegendArea() { + for (Control c: fLegendArea.getChildren()) { + c.dispose(); + } + if (fLegendImages != null) { + for (Image i: fLegendImages) { + i.dispose(); + } + } + fLegendImages = null; + if (fFullTraceHistogram.showTraces()) { + ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace); + fLegendImages = new Image[traces.length]; + int traceIndex = 0; + for (ITmfTrace trace : traces) { + fLegendImages[traceIndex] = new Image(fLegendArea.getDisplay(), 16, 16); + GC gc = new GC(fLegendImages[traceIndex]); + gc.setBackground(fFullTraceHistogram.getTraceColor(traceIndex)); + gc.fillRectangle(0, 0, 15, 15); + gc.setForeground(fLegendArea.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + gc.drawRectangle(0, 0, 15, 15); + gc.dispose(); + + CLabel label = new CLabel(fLegendArea, SWT.NONE); + label.setText(trace.getName()); + label.setImage(fLegendImages[traceIndex]); + traceIndex++; + } + } + fLegendArea.layout(); + fLegendArea.getParent().layout(); + } + + private void updateDisplayedSelectionTime(long beginTime, long endTime) { + fSelectionBeginTime = beginTime; + fSelectionEndTime = endTime; + + fFullTraceHistogram.setSelection(fSelectionBeginTime, fSelectionEndTime); + fTimeRangeHistogram.setSelection(fSelectionBeginTime, fSelectionEndTime); + fSelectionStartControl.setValue(fSelectionBeginTime); + fSelectionEndControl.setValue(fSelectionEndTime); + } + + private void updateDisplayedTimeRange(long start, long end) { + fWindowStartTime = start; + fWindowEndTime = end; + fWindowSpan = fWindowEndTime - fWindowStartTime; + fFullTraceHistogram.setTimeRange(fWindowStartTime, fWindowSpan); + } + + private TmfTimeRange updateTraceTimeRange() { + fTraceStartTime = 0L; + fTraceEndTime = 0L; + + TmfTimeRange timeRange = fTrace.getTimeRange(); + if (!timeRange.equals(TmfTimeRange.NULL_RANGE)) { + fTraceStartTime = timeRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + fTraceEndTime = timeRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + } + return timeRange; + } + + private void sendTimeRangeRequest(long startTime, long endTime) { + if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) { + fTimeRangeRequest.cancel(); + } + TmfTimestamp startTS = new TmfTimestamp(startTime, ITmfTimestamp.NANOSECOND_SCALE); + TmfTimestamp endTS = new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE); + TmfTimeRange timeRange = new TmfTimeRange(startTS, endTS); + + fTimeRangeHistogram.clear(); + fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime); + fTimeRangeHistogram.setTimeRange(startTime, endTime - startTime); + + int cacheSize = fTrace.getCacheSize(); + fTimeRangeRequest = new HistogramRequest(fTimeRangeHistogram.getDataModel(), + timeRange, 0, ITmfEventRequest.ALL_DATA, cacheSize, ExecutionType.FOREGROUND, false); + fTrace.sendRequest(fTimeRangeRequest); + } + + private void sendFullRangeRequest(TmfTimeRange fullRange) { + if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) { + fFullTraceRequest.cancel(); + } + int cacheSize = fTrace.getCacheSize(); + fFullTraceRequest = new HistogramRequest(fFullTraceHistogram.getDataModel(), + fullRange, + (int) fFullTraceHistogram.fDataModel.getNbEvents(), + ITmfEventRequest.ALL_DATA, + cacheSize, + ExecutionType.BACKGROUND, true); + fTrace.sendRequest(fFullTraceRequest); + } + + private void contributeToActionBars() { + IActionBars bars = getViewSite().getActionBars(); + bars.getToolBarManager().add(getShowLostEventsAction()); + bars.getToolBarManager().add(getShowTraceAction()); + bars.getToolBarManager().add(new Separator()); + } + + private void addLinkButtonListeners() { + fLinkButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { + fSelectionEndControl.setEnabled(fLinkState); + fLinkState = !fLinkState; + fLinkButton.redraw(); + } + }); + + fLinkButton.addPaintListener(new PaintListener() { + @Override + public void paintControl(PaintEvent e) { + if (fLinkState) { + Rectangle r = fLinkButton.getBounds(); + r.x = -1; + r.y = -1; + e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); + e.gc.drawRectangle(r); + r.x = 0; + r.y = 0; + e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_DARK_GRAY)); + e.gc.drawRectangle(r); + } + } + }); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramZoom.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramZoom.java new file mode 100644 index 0000000000..296b2c79fd --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/HistogramZoom.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Francois Chouinard - Moved from LTTng to TMF + * Patrick Tasse - Update for mouse wheel zoom + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.histogram; + +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseWheelListener; + +/** + * Class to handle zooming within histogram windows.. + * + * @version 1.0 + * @author Francois Chouinard + *

    + */ +public class HistogramZoom implements MouseWheelListener, KeyListener { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + private final static double ZOOM_FACTOR = 0.8; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final Histogram fHistogram; + + private long fAbsoluteStartTime; + private long fAbsoluteEndTime; + private final long fMinWindowSize; + + private long fRangeStartTime; + private long fRangeDuration; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Standard constructor. + * + * @param histogram + * The parent histogram object + * @param start + * The start time of the zoom area + * @param end + * The end time of the zoom area + * @since 2.0 + */ + public HistogramZoom(Histogram histogram, long start, long end) { + fHistogram = histogram; + fAbsoluteStartTime = start; + fAbsoluteEndTime = end; + fMinWindowSize = 0; + + fRangeStartTime = fAbsoluteStartTime; + fRangeDuration = fAbsoluteStartTime + fMinWindowSize; + + histogram.addMouseWheelListener(this); + histogram.addKeyListener(this); + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * Get start time of the zoom window. + * @return the start time. + */ + public synchronized long getStartTime() { + return fRangeStartTime; + } + + /** + * Get the end time of the zoom window. + * @return the end time + */ + public synchronized long getEndTime() { + return fRangeStartTime + fRangeDuration; + } + + /** + * Get the duration of the zoom window. + * @return the duration of the zoom window. + */ + public synchronized long getDuration() { + return fRangeDuration; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * The the full time range of the histogram + * + * @param startTime the start time the histogram + * @param endTime the end time of the histogram + */ + public synchronized void setFullRange(long startTime, long endTime) { + fAbsoluteStartTime = startTime; + fAbsoluteEndTime = endTime; + } + + /** + * Sets the new zoom window + * @param startTime the start time + * @param duration the duration + */ + public synchronized void setNewRange(long startTime, long duration) { + long realStart = startTime; + + if (realStart < fAbsoluteStartTime) { + realStart = fAbsoluteStartTime; + } + + long endTime = realStart + duration; + if (endTime > fAbsoluteEndTime) { + endTime = fAbsoluteEndTime; + if (endTime - duration > fAbsoluteStartTime) { + realStart = endTime - duration; + } else { + realStart = fAbsoluteStartTime; + } + } + + fRangeStartTime = realStart; + fRangeDuration = endTime - realStart; + } + + // ------------------------------------------------------------------------ + // MouseWheelListener + // ------------------------------------------------------------------------ + + @Override + public void mouseScrolled(MouseEvent event) { + zoom(event.count); + } + + /** + * @since 3.1 + */ + @Override + public void keyPressed(KeyEvent e) { + if (e.character == '+') { + zoom(1); + } else if (e.character == '-') { + zoom(-1); + } + } + + /** + * @since 3.1 + */ + @Override + public void keyReleased(KeyEvent e) { + } + + private synchronized void zoom(int nbClicks) { + // Compute the new time range + long requestedRange = (nbClicks > 0) ? Math.round(ZOOM_FACTOR * fRangeDuration) : (long) Math.ceil(fRangeDuration * (1.0 / ZOOM_FACTOR)); + + // Distribute delta and adjust for boundaries + long requestedStart = validateStart(fRangeStartTime + (fRangeDuration - requestedRange) / 2); + long requestedEnd = validateEnd(requestedStart, requestedStart + requestedRange); + requestedStart = validateStart(requestedEnd - requestedRange); + + fHistogram.updateTimeRange(requestedStart, requestedEnd); + } + + private long validateStart(long start) { + long realStart = start; + + if (realStart < fAbsoluteStartTime) { + realStart = fAbsoluteStartTime; + } + if (realStart > fAbsoluteEndTime) { + realStart = fAbsoluteEndTime - fMinWindowSize; + } + return realStart; + } + + private long validateEnd(long start, long end) { + long realEnd = end; + + if (realEnd > fAbsoluteEndTime) { + realEnd = fAbsoluteEndTime; + } + if (realEnd < start + fMinWindowSize) { + realEnd = start + fMinWindowSize; + } + return realEnd; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/IHistogramDataModel.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/IHistogramDataModel.java new file mode 100644 index 0000000000..56f1e89747 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/IHistogramDataModel.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Francois Chouinard - Moved from LTTng to TMF + * Xavier Raynaud - Support multi-trace coloring + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.histogram; + +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.views.distribution.model.IBaseDistributionModel; + +/** + * Histogram data model interface. + * + * @version 1.0 + * @author Bernd Hufmann + */ +public interface IHistogramDataModel extends IBaseDistributionModel { + /** + * Add event to the correct bucket, compacting the if needed. + * + * @param eventCount the event to count + * @param timestamp the timestamp of the event to count + * @param trace the trace corresponding to given events + * @since 3.0 + */ + void countEvent(long eventCount, long timestamp, ITmfTrace trace); + + /** + * Scale the model data to the width, height and bar width requested. + * + * @param width A width of the histogram canvas + * @param height A height of the histogram canvas + * @param barWidth A width (in pixel) of a histogram bar + * @return the result array of size [width] and where the highest value doesn't exceed [height] + * while considering the bar width [barWidth] + */ + HistogramScaledData scaleTo(int width, int height, int barWidth); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/IHistogramModelListener.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/IHistogramModelListener.java new file mode 100644 index 0000000000..10c6a07a94 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/IHistogramModelListener.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + * Francois Chouinard - Moved from LTTng to TMF + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.histogram; + +/** + * Listener interface for receiving histogram data model notifications. + * + * @version 1.0 + * @author Bernd Hufmann + */ +public interface IHistogramModelListener { + /** + * Method to implement to receive notification about model updates. + */ + void modelUpdated(); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/Messages.java new file mode 100644 index 0000000000..9141c11fb0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/Messages.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * William Bourque - Initial API and implementation + * Francois Chouinard - Cleanup and refactoring + * Francois Chouinard - Moved from LTTng to TMF + * Patrick Tasse - Update for histogram selection range and tool tip + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.histogram; + +import org.eclipse.osgi.util.NLS; + +/** + * Messages file for the histogram widgets. + *

    + * + * @version 1.0 + * @author Francois Chouinard + */ +public class Messages extends NLS { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.ui.views.histogram.messages"; //$NON-NLS-1$ + + /** + * @since 3.0 + */ + public static String HistogramView_showTraces; + + /** + * @since 2.2 + */ + public static String HistogramView_hideLostEvents; + /** + * The label for the selection start time + * @since 2.2 + */ + public static String HistogramView_selectionStartLabel; + /** + * The label for the selection end time + * @since 2.2 + */ + public static String HistogramView_selectionEndLabel; + /** + * The label for the window span. + */ + public static String HistogramView_windowSpanLabel; + /** + * The tool tip text for the selection span. + * @since 2.2 + */ + public static String Histogram_selectionSpanToolTip; + /** + * The tool tip text for the bucket range. + * @since 2.2 + */ + public static String Histogram_bucketRangeToolTip; + /** + * The tool tip text for the event count. + * @since 2.2 + */ + public static String Histogram_eventCountToolTip; + /** + * The tool tip text for the lost event count. + * @since 2.2 + */ + public static String Histogram_lostEventCountToolTip; + + // ------------------------------------------------------------------------ + // Initializer + // ------------------------------------------------------------------------ + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + private Messages() { + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/TimeRangeHistogram.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/TimeRangeHistogram.java new file mode 100644 index 0000000000..caf56e03b6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/TimeRangeHistogram.java @@ -0,0 +1,217 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Francois Chouinard - Initial API and implementation + * Bernd Hufmann - Changed to updated histogram data model + * Francois Chouinard - Moved from LTTng to TMF + * Patrick Tasse - Update for mouse wheel zoom + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.histogram; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; + +/** + * A basic histogram widget that displays the event distribution of a specific time range of a trace. + * It has the following additional features: + *

      + *
    • zoom in: mouse wheel up (or forward) + *
    • zoom out: mouse wheel down (or backward) + *
    + * + * @version 1.1 + * @author Francois Chouinard + */ +public class TimeRangeHistogram extends Histogram { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private HistogramZoom fZoom = null; + + private long fRangeStartTime = 0L; + private long fRangeDuration; + private long fFullRangeStartTime = 0L; + private long fFullRangeEndTime = 0L; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + /** + * Constructor + * @param view The parent histogram view + * @param parent The parent composite + */ + public TimeRangeHistogram(HistogramView view, Composite parent) { + super(view, parent); + fZoom = new HistogramZoom(this, getStartTime(), getTimeLimit()); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Override + public synchronized void clear() { + fRangeStartTime = 0L; + fRangeDuration = 0L; + fFullRangeStartTime = 0L; + fFullRangeEndTime = 0L; + setOffset(0); + if (fZoom != null) { + fZoom.setFullRange(0L, 0L); + fZoom.setNewRange(0L, 0L); + } + super.clear(); + } + + /** + * Sets the time range of the histogram + * @param startTime The start time + * @param duration The duration of the time range + */ + public synchronized void setTimeRange(long startTime, long duration) { + fRangeStartTime = startTime; + fRangeDuration = duration; + fZoom.setNewRange(startTime, duration); + if (getDataModel().getNbEvents() == 0) { + getDataModel().setTimeRange(startTime, startTime + duration); + getDataModel().setEndTime(startTime + duration); + } + } + + /** + * Sets the full time range of the whole trace. + * @param startTime The start time + * @param endTime The end time + */ + public void setFullRange(long startTime, long endTime) { + fFullRangeStartTime = startTime; + fFullRangeEndTime = endTime; + fZoom.setFullRange(startTime, endTime); + fZoom.setNewRange(fRangeStartTime, fRangeDuration); + } + + // ------------------------------------------------------------------------ + // MouseListener + // ------------------------------------------------------------------------ + + private int fStartPosition; + private int fMinOffset; + private int fMaxOffset; + + @Override + public void mouseDown(MouseEvent event) { + if (fScaledData != null && fDragState == DRAG_NONE && fDataModel.getStartTime() < fDataModel.getEndTime()) { + if (event.button == 2 || (event.button == 1 && (event.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL)) { + fDragState = DRAG_RANGE; + fDragButton = event.button; + fStartPosition = event.x; + long maxOffset = (fRangeStartTime - fFullRangeStartTime) / fScaledData.fBucketDuration; + long minOffset = (fRangeStartTime + fRangeDuration - fFullRangeEndTime) / fScaledData.fBucketDuration; + fMaxOffset = (int) Math.max(Integer.MIN_VALUE, Math.min(Integer.MAX_VALUE, maxOffset)); + fMinOffset = (int) Math.max(Integer.MIN_VALUE, Math.min(Integer.MAX_VALUE, minOffset)); + return; + } else if (event.button == 3) { + fDragState = DRAG_ZOOM; + fDragButton = event.button; + fRangeStartTime = Math.min(getTimestamp(event.x), getEndTime()); + fRangeDuration = 0; + fCanvas.redraw(); + return; + } + } + super.mouseDown(event); + } + + @Override + public void mouseUp(MouseEvent event) { + if (fDragState == DRAG_RANGE && event.button == fDragButton) { + fDragState = DRAG_NONE; + fDragButton = 0; + if (event.x != fStartPosition) { + int nbBuckets = event.x - fStartPosition; + long delta = nbBuckets * fScaledData.fBucketDuration; + long startTime = fRangeStartTime - delta; + fRangeStartTime = Math.max(fFullRangeStartTime, Math.min(fFullRangeEndTime - fRangeDuration, startTime)); + ((HistogramView) fParentView).updateTimeRange(fRangeStartTime, fRangeStartTime + fRangeDuration); + setOffset(0); + } + return; + } else if (fDragState == DRAG_ZOOM && event.button == fDragButton) { + fDragState = DRAG_NONE; + fDragButton = 0; + if (fRangeDuration < 0) { + fRangeStartTime = fRangeStartTime + fRangeDuration; + fRangeDuration = -fRangeDuration; + } + if (fRangeDuration > 0) { + ((HistogramView) fParentView).updateTimeRange(fRangeStartTime, fRangeStartTime + fRangeDuration); + } else { + fRangeStartTime = fZoom.getStartTime(); + fRangeDuration = fZoom.getDuration(); + fCanvas.redraw(); + } + return; + } + super.mouseUp(event); + } + + // ------------------------------------------------------------------------ + // MouseMoveListener + // ------------------------------------------------------------------------ + + @Override + public void mouseMove(MouseEvent event) { + if (fDragState == DRAG_RANGE) { + int offset = Math.max(fMinOffset, Math.min(fMaxOffset, event.x - fStartPosition)); + setOffset(offset); + fCanvas.redraw(); + return; + } else if (fDragState == DRAG_ZOOM) { + long endTime = Math.max(getStartTime(), Math.min(getEndTime(), getTimestamp(event.x))); + fRangeDuration = endTime - fRangeStartTime; + fCanvas.redraw(); + return; + } + super.mouseMove(event); + } + + // ------------------------------------------------------------------------ + // PaintListener + // ------------------------------------------------------------------------ + + @Override + public void paintControl(PaintEvent event) { + super.paintControl(event); + + if (fDragState == DRAG_ZOOM) { + Image image = (Image) fCanvas.getData(IMAGE_KEY); + assert image != null; + + Image rangeRectangleImage = new Image(image.getDevice(), image, SWT.IMAGE_COPY); + GC rangeWindowGC = new GC(rangeRectangleImage); + + drawTimeRangeWindow(rangeWindowGC, fRangeStartTime, fRangeDuration); + + // Draws the buffer image onto the canvas. + event.gc.drawImage(rangeRectangleImage, 0, 0); + + rangeWindowGC.dispose(); + rangeRectangleImage.dispose(); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/messages.properties new file mode 100644 index 0000000000..116ec9acc3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/histogram/messages.properties @@ -0,0 +1,21 @@ +############################################################################### +# Copyright (c) 2013, 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### + +HistogramView_hideLostEvents=Hide Lost Events +HistogramView_showTraces=Activate Trace Coloring +HistogramView_selectionStartLabel=Selection Start +HistogramView_selectionEndLabel=Selection End +HistogramView_windowSpanLabel=Window Span +Histogram_selectionSpanToolTip=Selection Span = {0} +Histogram_bucketRangeToolTip=Bucket Range = [{0},{1}) +Histogram_eventCountToolTip=Event count = {0} +Histogram_lostEventCountToolTip=Lost event count = {0} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statesystem/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statesystem/Messages.java new file mode 100644 index 0000000000..10da8eef3a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statesystem/Messages.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.statesystem; + +import org.eclipse.osgi.util.NLS; + +/** + * Localizable strings in the State System Visualizer. + * + * @author Alexandre Montplaisir + * @since 2.0 + */ +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.ui.views.statesystem.messages"; //$NON-NLS-1$ + + /** + * Initializer + */ + static { + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + /** + * Private constructor (static class) + */ + private Messages() {} + + /** Label for the first column */ + public static String TreeNodeColumnLabel; + + /** Label for the "quark" column" */ + public static String QuarkColumnLabel; + + /** Label for the "value" column */ + public static String ValueColumnLabel; + + /** Label for the "type" column + * @since 2.1*/ + public static String TypeColumnLabel; + + /** Label for the "start time" column */ + public static String StartTimeColumLabel; + + /** Label for the "end time" column */ + public static String EndTimeColumLabel; + + /** Label for the "attribute path" column */ + public static String AttributePathColumnLabel; + + /** + * Printing "out of range" in the value column when the current timestamp is + * outside of the SS's range. + */ + public static String OutOfRangeMsg; + + /** Label for the Filter button + * @since 2.1*/ + public static String FilterButton; + + /** Label for the type Interger + * @since 2.1*/ + public static String TypeInteger; + + /** Label for the type Long + * @since 2.1*/ + public static String TypeLong; + + /** Label for type Double + * @since 3.0*/ + public static String TypeDouble; + + /** Label for the type String + * @since 2.1*/ + public static String TypeString; +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statesystem/TmfStateSystemExplorer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statesystem/TmfStateSystemExplorer.java new file mode 100644 index 0000000000..fb658c2370 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statesystem/TmfStateSystemExplorer.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2013, 2014 École Polytechnique de Montréal, Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Florian Wininger - Initial API and implementation + * Alexandre Montplaisir - Refactoring, performance tweaks + * Bernd Hufmann - Updated signal handling + * Marc-Andre Laperle - Add time zone preference + * Geneviève Bastien - Use a tree viewer instead of a tree + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.statesystem; + +import java.io.File; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.views.TmfView; +import org.eclipse.ui.IActionBars; + +/** + * Displays the State System at a current time. + * + * @author Florian Wininger + * @author Alexandre Montplaisir + * @since 2.0 + */ +public class TmfStateSystemExplorer extends TmfView { + + /** The Environment View's ID */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.ssview"; //$NON-NLS-1$ + + private static final Image FILTER_IMAGE = + Activator.getDefault().getImageFromPath( File.separator + "icons" + File.separator + "elcl16" + File.separator + "filter_items.gif"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + private TmfStateSystemViewer fViewer; + + /** + * Default constructor + */ + public TmfStateSystemExplorer() { + super(ID); + } + + // ------------------------------------------------------------------------ + // ViewPart + // ------------------------------------------------------------------------ + + @Override + public void createPartControl(Composite parent) { + + fViewer = new TmfStateSystemViewer(parent); + + fillToolBar() ; + + ITmfTrace trace = getActiveTrace(); + if (trace != null) { + fViewer.traceSelected(new TmfTraceSelectedSignal(this, trace)); + } + + } + + // ------------------------------------------------------------------------ + // Part For Button Action + // ------------------------------------------------------------------------ + + private void fillToolBar() { + Action fFilterAction = new FilterAction(); + fFilterAction.setImageDescriptor(ImageDescriptor.createFromImage(FILTER_IMAGE)); + fFilterAction.setToolTipText(Messages.FilterButton) ; + fFilterAction.setChecked(false); + + IActionBars bars = getViewSite().getActionBars(); + IToolBarManager manager = bars.getToolBarManager(); + manager.add(fFilterAction); + } + + private class FilterAction extends Action { + @Override + public void run() { + fViewer.changeFilterStatus(); + } + } + + @Override + public void setFocus() { + } + + @Override + public void dispose() { + super.dispose(); + if (fViewer != null) { + fViewer.dispose(); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statesystem/TmfStateSystemViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statesystem/TmfStateSystemViewer.java new file mode 100644 index 0000000000..1c732c1e44 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statesystem/TmfStateSystemViewer.java @@ -0,0 +1,463 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Florian Wininger - Initial API and implementation + * Alexandre Montplaisir - Refactoring, performance tweaks + * Bernd Hufmann - Updated signal handling + * Marc-Andre Laperle - Add time zone preference + * Geneviève Bastien - Moved state system explorer to use the abstract tree viewer + * Patrick Tasse - Refactoring + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.statesystem; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfAnalysisModuleWithStateSystems; +import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ui.viewers.tree.AbstractTmfTreeViewer; +import org.eclipse.tracecompass.tmf.ui.viewers.tree.ITmfTreeColumnDataProvider; +import org.eclipse.tracecompass.tmf.ui.viewers.tree.ITmfTreeViewerEntry; +import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfTreeColumnData; +import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfTreeViewerEntry; + +/** + * Displays the content of the state systems at the current time + * + * @author Florian Wininger + * @author Alexandre Montplaisir + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfStateSystemViewer extends AbstractTmfTreeViewer { + + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + private static final int DEFAULT_AUTOEXPAND = 2; + private boolean fFilterStatus = false; + private long fSelection = 0; + + /* Order of columns */ + private static final int ATTRIBUTE_NAME_COL = 0; + private static final int QUARK_COL = 1; + private static final int VALUE_COL = 2; + private static final int TYPE_COL = 3; + private static final int START_TIME_COL = 4; + private static final int END_TIME_COL = 5; + private static final int ATTRIBUTE_FULLPATH_COL = 6; + + /** + * Base class to provide the labels for the tree viewer. Views extending + * this class typically need to override the getColumnText method if they + * have more than one column to display + */ + protected static class StateSystemTreeLabelProvider extends TreeLabelProvider { + + @Override + public String getColumnText(Object element, int columnIndex) { + if (element instanceof StateEntry) { + StateEntry entry = (StateEntry) element; + switch (columnIndex) { + case ATTRIBUTE_NAME_COL: + return entry.getName(); + case QUARK_COL: + return String.valueOf(entry.getQuark()); + case VALUE_COL: + return entry.getValue(); + case TYPE_COL: + return entry.getType(); + case START_TIME_COL: + return entry.getStartTime(); + case END_TIME_COL: + return entry.getEndTime(); + case ATTRIBUTE_FULLPATH_COL: + return entry.getFullPath(); + default: + return EMPTY_STRING; + } + } + return super.getColumnText(element, columnIndex); + } + + @Override + public Color getBackground(Object element, int columnIndex) { + if (element instanceof StateEntry) { + if (((StateEntry) element).isModified()) { + return Display.getCurrent().getSystemColor(SWT.COLOR_YELLOW); + } + } + return super.getBackground(element, columnIndex); + } + } + + /** + * Constructor + * + * @param parent + * The parent containing this viewer + */ + public TmfStateSystemViewer(Composite parent) { + super(parent, false); + this.setLabelProvider(new StateSystemTreeLabelProvider()); + getTreeViewer().setAutoExpandLevel(DEFAULT_AUTOEXPAND); + } + + @Override + protected ITmfTreeColumnDataProvider getColumnDataProvider() { + return new ITmfTreeColumnDataProvider() { + + @Override + public List getColumnData() { + List columns = new ArrayList<>(); + TmfTreeColumnData column = new TmfTreeColumnData(Messages.TreeNodeColumnLabel); + columns.add(column); + column.setComparator(new ViewerComparator() { + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + TmfTreeViewerEntry n1 = (TmfTreeViewerEntry) e1; + TmfTreeViewerEntry n2 = (TmfTreeViewerEntry) e2; + + return n1.getName().compareTo(n2.getName()); + } + }); + columns.add(new TmfTreeColumnData(Messages.QuarkColumnLabel)); + columns.add(new TmfTreeColumnData(Messages.ValueColumnLabel)); + columns.add(new TmfTreeColumnData(Messages.TypeColumnLabel)); + columns.add(new TmfTreeColumnData(Messages.StartTimeColumLabel)); + columns.add(new TmfTreeColumnData(Messages.EndTimeColumLabel)); + columns.add(new TmfTreeColumnData(Messages.AttributePathColumnLabel)); + return columns; + } + + }; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Override + protected ITmfTreeViewerEntry updateElements(long start, long end, boolean selection) { + + if (selection) { + fSelection = start; + } else { + fSelection = TmfTraceManager.getInstance().getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + } + + if (getTrace() == null) { + return null; + } + + ITmfTreeViewerEntry root = getInput(); + + if (root == null) { + root = createRoot(); + } else if (fFilterStatus) { + clearStateSystemEntries(root); + } + + /* + * Update the values of the elements of the state systems at the + * selection start time + */ + boolean changed = updateStateSystemEntries(root, fSelection); + + return selection || changed ? root : null; + } + + private ITmfTreeViewerEntry createRoot() { + // 'Fake' root node + TmfTreeViewerEntry rootEntry = new TmfTreeViewerEntry("root"); //$NON-NLS-1$ + + for (final ITmfTrace trace : TmfTraceManager.getTraceSetWithExperiment(getTrace())) { + if (trace != null) { + rootEntry.addChild(createTraceEntry(trace)); + } + } + return rootEntry; + } + + private static TmfTreeViewerEntry createTraceEntry(ITmfTrace trace) { + TmfTreeViewerEntry traceEntry = new TmfTreeViewerEntry(trace.getName()); + Iterable modules = trace.getAnalysisModulesOfClass(ITmfAnalysisModuleWithStateSystems.class); + for (ITmfAnalysisModuleWithStateSystems module : modules) { + /* Just schedule the module, the data will be filled when available */ + module.schedule(); + if (module instanceof TmfStateSystemAnalysisModule) { + // TODO: add this method to ITmfAnalysisModuleWithStateSystems + ((TmfStateSystemAnalysisModule) module).waitForInitialization(); + } + for (ITmfStateSystem ss : module.getStateSystems()) { + if (ss != null) { + traceEntry.addChild(new StateSystemEntry(ss)); + } + } + } + return traceEntry; + } + + private static void clearStateSystemEntries(ITmfTreeViewerEntry root) { + for (ITmfTreeViewerEntry traceEntry : root.getChildren()) { + for (ITmfTreeViewerEntry ssEntry : traceEntry.getChildren()) { + ssEntry.getChildren().clear(); + } + } + } + + private boolean updateStateSystemEntries(ITmfTreeViewerEntry root, long timestamp) { + boolean changed = false; + for (ITmfTreeViewerEntry traceEntry : root.getChildren()) { + for (ITmfTreeViewerEntry ssEntry : traceEntry.getChildren()) { + StateSystemEntry stateSystemEntry = (StateSystemEntry) ssEntry; + ITmfStateSystem ss = stateSystemEntry.getSS(); + try { + List fullState = ss.queryFullState(timestamp); + changed |= updateStateEntries(ss, fullState, stateSystemEntry, -1, timestamp); + } catch (TimeRangeException e) { + markOutOfRange(stateSystemEntry); + changed = true; + } catch (StateSystemDisposedException e) { + /* Ignored */ + } + } + } + return changed; + } + + private boolean updateStateEntries(ITmfStateSystem ss, List fullState, TmfTreeViewerEntry parent, int parentQuark, long timestamp) { + boolean changed = false; + try { + for (int quark : ss.getSubAttributes(parentQuark, false)) { + if (quark >= fullState.size()) { + // attribute was created after the full state query + continue; + } + ITmfStateInterval interval = fullState.get(quark); + StateEntry stateEntry = findStateEntry(parent, quark); + if (stateEntry == null) { + boolean modified = fFilterStatus ? + interval.getStartTime() == timestamp : + !interval.getStateValue().isNull(); + stateEntry = new StateEntry(ss.getAttributeName(quark), quark, ss.getFullAttributePath(quark), + interval.getStateValue(), + new TmfTimestamp(interval.getStartTime(), ITmfTimestamp.NANOSECOND_SCALE), + new TmfTimestamp(interval.getEndTime(), ITmfTimestamp.NANOSECOND_SCALE), + modified); + + // update children first to know if parent is really needed + updateStateEntries(ss, fullState, stateEntry, quark, timestamp); + + /* + * Add this entry to parent if filtering is off, or + * if the entry has children to display, or + * if there is a state change at the current timestamp + */ + if (!fFilterStatus || stateEntry.hasChildren() || interval.getStartTime() == timestamp) { + parent.addChild(stateEntry); + changed = true; + } + } else { + stateEntry.update(interval.getStateValue(), + new TmfTimestamp(interval.getStartTime(), ITmfTimestamp.NANOSECOND_SCALE), + new TmfTimestamp(interval.getEndTime(), ITmfTimestamp.NANOSECOND_SCALE)); + + // update children recursively + updateStateEntries(ss, fullState, stateEntry, quark, timestamp); + } + + } + } catch (AttributeNotFoundException e) { + /* Should not happen, we're iterating on known attributes */ + } + return changed; + } + + private static StateEntry findStateEntry(TmfTreeViewerEntry parent, int quark) { + for (ITmfTreeViewerEntry child : parent.getChildren()) { + StateEntry stateEntry = (StateEntry) child; + if (stateEntry.getQuark() == quark) { + return stateEntry; + } + } + return null; + } + /** + * Set the entries as out of range + */ + private static void markOutOfRange(ITmfTreeViewerEntry parent) { + for (ITmfTreeViewerEntry entry : parent.getChildren()) { + if (entry instanceof StateEntry) { + ((StateEntry) entry).setOutOfRange(); + + /* Update this node's children recursively */ + markOutOfRange(entry); + } + } + } + + /** + * Set the filter status of the viewer. By default, all entries of all state + * system are present, and the values that changed since last refresh are + * shown in yellow. When the filter status is true, only the entries with + * values modified at current time are displayed. + */ + public void changeFilterStatus() { + fFilterStatus = !fFilterStatus; + if (fFilterStatus) { + getTreeViewer().setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS); + } else { + getTreeViewer().setAutoExpandLevel(DEFAULT_AUTOEXPAND); + clearContent(); + } + updateContent(getSelectionBeginTime(), getSelectionEndTime(), true); + } + + /** + * Update the display to use the updated timestamp format + * + * @param signal + * the incoming signal + */ + @TmfSignalHandler + public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) { + updateContent(getSelectionBeginTime(), getSelectionEndTime(), true); + } + + private static class StateSystemEntry extends TmfTreeViewerEntry { + private final @NonNull ITmfStateSystem fSS; + + public StateSystemEntry(@NonNull ITmfStateSystem ss) { + super(ss.getSSID()); + fSS = ss; + } + + public @NonNull ITmfStateSystem getSS() { + return fSS; + } + } + + private class StateEntry extends TmfTreeViewerEntry { + + private final int fQuark; + private final String fFullPath; + private @NonNull TmfTimestamp fStart; + private @NonNull TmfTimestamp fEnd; + private ITmfStateValue fValue; + private boolean fModified; + private boolean fOutOfRange = false; + + public StateEntry(String name, int quark, String fullPath, ITmfStateValue value, @NonNull TmfTimestamp start, @NonNull TmfTimestamp end, boolean modified) { + super(name); + fQuark = quark; + fFullPath = fullPath; + fStart = start; + fEnd = end; + fValue = value; + fModified = modified; + } + + public int getQuark() { + return fQuark; + } + + public String getFullPath() { + return fFullPath; + } + + public String getStartTime() { + if (fOutOfRange) { + return EMPTY_STRING; + } + return fStart.toString(); + } + + public String getEndTime() { + if (fOutOfRange) { + return EMPTY_STRING; + } + return fEnd.toString(); + } + + public String getValue() { + if (fOutOfRange) { + return Messages.OutOfRangeMsg; + } + switch (fValue.getType()) { + case INTEGER: + case LONG: + case DOUBLE: + case STRING: + return fValue.toString(); + case NULL: + default: + return EMPTY_STRING; + } + } + + public String getType() { + if (fOutOfRange) { + return EMPTY_STRING; + } + switch (fValue.getType()) { + case INTEGER: + return Messages.TypeInteger; + case LONG: + return Messages.TypeLong; + case DOUBLE: + return Messages.TypeDouble; + case STRING: + return Messages.TypeString; + case NULL: + default: + return EMPTY_STRING; + } + } + + public boolean isModified() { + return fModified; + } + + public void update(ITmfStateValue value, @NonNull TmfTimestamp start, @NonNull TmfTimestamp end) { + fModified = false; + fOutOfRange = false; + if (!start.equals(fStart)) { + fModified = true; + fStart = start; + fEnd = end; + fValue = value; + } + } + + public void setOutOfRange() { + fModified = false; + fOutOfRange = true; + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statesystem/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statesystem/messages.properties new file mode 100644 index 0000000000..33a5a3d741 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statesystem/messages.properties @@ -0,0 +1,28 @@ +############################################################################### +# Copyright (c) 2013 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### + +# Column names +TreeNodeColumnLabel=State System / Attribute +QuarkColumnLabel=Quark +ValueColumnLabel=Value at timestamp +TypeColumnLabel=Type +StartTimeColumLabel=Start time +EndTimeColumLabel=End time +AttributePathColumnLabel=Full attribute path + +# Other messages +OutOfRangeMsg=Out of Range +FilterButton=Only Display Changes at Selected Timestamp +TypeInteger=Int +TypeLong=Long +TypeDouble=Double +TypeString=String diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statistics/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statistics/Messages.java new file mode 100755 index 0000000000..3824dc61f5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statistics/Messages.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial API and Implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.statistics; + +import org.eclipse.osgi.util.NLS; + +/** + * Messages file for statistics view strings. + * + * @version 2.0 + * @author Mathieu Denis + * @since 2.0 + */ +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.ui.views.statistics.messages"; //$NON-NLS-1$ + + /** + * String for the global tab name + * @since 2.0 + */ + public static String TmfStatisticsView_GlobalTabName; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statistics/TmfStatisticsView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statistics/TmfStatisticsView.java new file mode 100755 index 0000000000..01e772e1e0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statistics/TmfStatisticsView.java @@ -0,0 +1,230 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Generalized version based on LTTng + * Bernd Hufmann - Updated to use trace reference in TmfEvent and streaming + * Mathieu Denis - New request added to update the statistics from the selected time range + * Mathieu Denis - Generalization of the view to instantiate a viewer specific to a trace type + * + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.statistics; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceRangeUpdatedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.viewers.ITmfViewer; +import org.eclipse.tracecompass.tmf.ui.viewers.statistics.TmfStatisticsViewer; +import org.eclipse.tracecompass.tmf.ui.views.TmfView; +import org.eclipse.tracecompass.tmf.ui.widgets.tabsview.TmfViewerFolder; + +/** + * The generic Statistics View displays statistics for any kind of traces. + * + * It is implemented according to the MVC pattern. - The model is a + * TmfStatisticsTreeNode built by the State Manager. - The view is built with a + * TreeViewer. - The controller that keeps model and view synchronized is an + * observer of the model. + * + * @version 2.0 + * @author Mathieu Denis + */ +public class TmfStatisticsView extends TmfView { + + /** + * The ID corresponds to the package in which this class is embedded. + */ + public static final @NonNull String ID = "org.eclipse.linuxtools.tmf.ui.views.statistics"; //$NON-NLS-1$ + + /** + * The view name. + */ + public static final String TMF_STATISTICS_VIEW = "StatisticsView"; //$NON-NLS-1$ + + /** + * The viewer that builds the columns to show the statistics. + * + * @since 2.0 + */ + protected final TmfViewerFolder fStatsViewers; + + /** + * Stores a reference to the selected trace. + */ + private ITmfTrace fTrace; + + /** + * Constructor of a statistics view. + * + * @param viewName The name to give to the view. + */ + public TmfStatisticsView(String viewName) { + super(viewName); + /* + * Create a fake parent for initialization purpose, than set the parent + * as soon as createPartControl is called. + */ + Composite temporaryParent = new Shell(); + fStatsViewers = new TmfViewerFolder(temporaryParent); + } + + /** + * Default constructor. + */ + public TmfStatisticsView() { + this(TMF_STATISTICS_VIEW); + } + + @Override + public void createPartControl(Composite parent) { + fStatsViewers.setParent(parent); + createStatisticsViewers(); + + ITmfTrace trace = getActiveTrace(); + if (trace != null) { + traceSelected(new TmfTraceSelectedSignal(this, trace)); + } + } + + @Override + public void dispose() { + super.dispose(); + fStatsViewers.dispose(); + } + + /** + * Handler called when an trace is opened. + * + * @param signal + * Contains the information about the selection. + * @since 2.0 + */ + @TmfSignalHandler + public void traceOpened(TmfTraceOpenedSignal signal) { + /* + * Dispose the current viewer and adapt the new one to the trace + * type of the trace opened + */ + fStatsViewers.clear(); + // Update the current trace + fTrace = signal.getTrace(); + createStatisticsViewers(); + fStatsViewers.layout(); + } + + /** + * Handler called when an trace is selected. Checks if the trace + * has changed and requests the selected trace if it has not yet been + * cached. + * + * @param signal + * Contains the information about the selection. + * @since 2.0 + */ + @TmfSignalHandler + public void traceSelected(TmfTraceSelectedSignal signal) { + // Does not reload the same trace if already opened + if (signal.getTrace() != fTrace) { + /* + * Dispose the current viewer and adapt the new one to the trace + * type of the trace selected + */ + fStatsViewers.clear(); + // Update the current trace + fTrace = signal.getTrace(); + createStatisticsViewers(); + fStatsViewers.layout(); + + TmfTraceRangeUpdatedSignal updateSignal = new TmfTraceRangeUpdatedSignal(this, fTrace, fTrace.getTimeRange()); + + for (ITmfViewer viewer : fStatsViewers.getViewers()) { + TmfStatisticsViewer statsViewer = (TmfStatisticsViewer) viewer; + statsViewer.sendPartialRequestOnNextUpdate(); + statsViewer.traceRangeUpdated(updateSignal); + } + } else { + /* + * If the same trace is reselected, sends a notification to + * the viewers to make sure they reload correctly their partial + * event count. + */ + for (ITmfViewer viewer : fStatsViewers.getViewers()) { + TmfStatisticsViewer statsViewer = (TmfStatisticsViewer) viewer; + // Will update the partial event count if needed. + statsViewer.sendPartialRequestOnNextUpdate(); + } + } + } + + /** + * @param signal the incoming signal + * @since 2.0 + */ + @TmfSignalHandler + public void traceClosed(TmfTraceClosedSignal signal) { + if (signal.getTrace() != fTrace) { + return; + } + + // Clear the internal data + fTrace = null; + + // Clear the UI widgets + fStatsViewers.clear(); // Also cancels ongoing requests + createStatisticsViewers(); + fStatsViewers.layout(); + } + + @Override + public void setFocus() { + fStatsViewers.setFocus(); + } + + /** + * Creates the statistics viewers for all traces in an experiment and + * populates a viewer folder. Each viewer is placed in a different tab and + * the first one is selected automatically. + * + * It uses the extension point that defines the statistics viewer to build + * from the trace type. If no viewer is defined, another tab won't be + * created, since the global viewer already contains all the basic + * statistics. If there is no trace selected, a global statistics viewer will + * still be created. + * + * @since 2.0 + */ + protected void createStatisticsViewers() { + // Default style for the tabs that will be created + int defaultStyle = SWT.NONE; + + // The folder composite that will contain the tabs + Composite folder = fStatsViewers.getParentFolder(); + + // Instantiation of the global viewer + if (fTrace != null) { + // Shows the name of the trace in the global tab + TmfStatisticsViewer globalViewer = new TmfStatisticsViewer(folder, Messages.TmfStatisticsView_GlobalTabName + " - " + fTrace.getName(), fTrace); //$NON-NLS-1$ + fStatsViewers.addTab(globalViewer, Messages.TmfStatisticsView_GlobalTabName, defaultStyle); + + } else { + // There is no trace selected. Shows an empty global tab + TmfStatisticsViewer globalViewer = new TmfStatisticsViewer(folder, Messages.TmfStatisticsView_GlobalTabName, fTrace); + fStatsViewers.addTab(globalViewer, Messages.TmfStatisticsView_GlobalTabName, defaultStyle); + } + // Makes the global viewer visible + fStatsViewers.setSelection(0); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statistics/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statistics/messages.properties new file mode 100755 index 0000000000..1a7d06c1e2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/statistics/messages.properties @@ -0,0 +1,13 @@ +############################################################################### +# Copyright (c) 2013 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### + +TmfStatisticsView_GlobalTabName=Global diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/synchronization/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/synchronization/Messages.java new file mode 100644 index 0000000000..e2e6f03b73 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/synchronization/Messages.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.synchronization; + +import org.eclipse.osgi.util.NLS; + +/** + * Message file for the synchronization view + * @since 3.0 + */ +@SuppressWarnings("javadoc") +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.ui.views.synchronization.messages"; //$NON-NLS-1$ + public static String TmfSynchronizationView_NameColumn; + public static String TmfSynchronizationView_ValueColumn; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/synchronization/TmfSynchronizationView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/synchronization/TmfSynchronizationView.java new file mode 100644 index 0000000000..8021e1dabb --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/synchronization/TmfSynchronizationView.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial implementation and API + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.synchronization; + +import java.util.Map; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSynchronizedSignal; +import org.eclipse.tracecompass.tmf.core.synchronization.SynchronizationAlgorithm; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfExperiment; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ui.views.TmfView; + +/** + * Small view to display statistics about a synchronization + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfSynchronizationView extends TmfView { + + /** + * The ID corresponds to the package in which this class is embedded. + */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.synchronization"; //$NON-NLS-1$ + + /** + * The view name. + */ + public static final String TMF_SYNCHRONIZATION_VIEW = "SynchronizationView"; //$NON-NLS-1$ + + /** + * The synchronization algorithm to display stats for + */ + private SynchronizationAlgorithm fAlgoSync; + + private Tree fTree; + + /** + * Default constructor + */ + public TmfSynchronizationView() { + super(TMF_SYNCHRONIZATION_VIEW); + } + + @Override + public void createPartControl(Composite parent) { + fTree = new Tree(parent, SWT.NONE); + TreeColumn nameCol = new TreeColumn(fTree, SWT.NONE, 0); + TreeColumn valueCol = new TreeColumn(fTree, SWT.NONE, 1); + nameCol.setText(Messages.TmfSynchronizationView_NameColumn); + valueCol.setText(Messages.TmfSynchronizationView_ValueColumn); + + fTree.setItemCount(0); + + fTree.setHeaderVisible(true); + nameCol.pack(); + valueCol.pack(); + + ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace(); + if (trace != null) { + traceSelected(new TmfTraceSelectedSignal(this, trace)); + } + } + + private void updateTable() { + fTree.setItemCount(0); + if (fAlgoSync == null) { + return; + } + + for (Map.Entry> entry : fAlgoSync.getStats().entrySet()) { + TreeItem item = new TreeItem(fTree, SWT.NONE); + item.setText(0, entry.getKey().toString()); + item.setText(1, entry.getValue().toString()); + + for (Map.Entry subentry : entry.getValue().entrySet()) { + TreeItem subitem = new TreeItem(item, SWT.NONE); + subitem.setText(0, subentry.getKey().toString()); + subitem.setText(1, subentry.getValue().toString()); + } + } + + /* Expand the tree items */ + for (int i = 0; i < fTree.getItemCount(); i++) { + fTree.getItem(i).setExpanded(true); + } + + for (TreeColumn column : fTree.getColumns()) { + column.pack(); + } + } + + @Override + public void setFocus() { + fTree.setFocus(); + } + + /** + * Handler called when a trace is selected + * + * @param signal + * Contains information about the selected trace + * @since 3.1 + */ + @TmfSignalHandler + public void traceSelected(TmfTraceSelectedSignal signal) { + fAlgoSync = null; + if (signal.getTrace() instanceof TmfExperiment) { + fAlgoSync = ((TmfExperiment) signal.getTrace()).synchronizeTraces(); + } + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + updateTable(); + } + }); + } + + /** + * Handler called when traces are synchronized + * + * @param signal + * Contains the information about the selection. + */ + @TmfSignalHandler + public void traceSynchronized(TmfTraceSynchronizedSignal signal) { + if (signal.getSyncAlgo() != fAlgoSync) { + fAlgoSync = signal.getSyncAlgo(); + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + updateTable(); + } + }); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/synchronization/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/synchronization/messages.properties new file mode 100644 index 0000000000..86c84fe49e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/synchronization/messages.properties @@ -0,0 +1,13 @@ +############################################################################### +# Copyright (c) 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### +TmfSynchronizationView_NameColumn=Synchronization Information +TmfSynchronizationView_ValueColumn=Value diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartAnalysisEntry.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartAnalysisEntry.java new file mode 100644 index 0000000000..512b0e223f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartAnalysisEntry.java @@ -0,0 +1,277 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.timechart; + +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Vector; + +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; + +/** + * An entry (row) in the time chart analysis view + * + * @version 1.0 + * @author Patrick Tasse + */ +public class TimeChartAnalysisEntry implements ITimeGraphEntry { + + private final ITmfTrace fTrace; + private final Vector fTraceEvents; + private int fPower = 0; // 2^fPower nanoseconds per vector position + private long fReferenceTime = -1; // time corresponding to beginning of index 0 + private long fStartTime = -1; // time of first event + private long fStopTime = -1; // time of last event + private long fLastRank = -1; // rank of last processed trace event + + TimeChartAnalysisEntry(ITmfTrace trace, int modelSize) { + fTrace = trace; + fTraceEvents = new Vector<>(modelSize); + } + + /** + * @since 2.0 + */ + @Override + public List getChildren() { + return null; + } + + @Override + public ITimeGraphEntry getParent() { + return null; + } + + @Override + public boolean hasChildren() { + return false; + } + + @Override + public String getName() { + return fTrace.getName(); + } + + @Override + public long getStartTime() { + return fStartTime; + } + + @Override + public long getEndTime() { + return fStopTime; + } + + @Override + public boolean hasTimeEvents() { + return true; + } + + @Override + public Iterator getTimeEventsIterator() { + return new EntryIterator(0, Long.MAX_VALUE, 0); + } + + @Override + public Iterator getTimeEventsIterator(long startTime, long stopTime, long maxDuration) { + return new EntryIterator(startTime, stopTime, maxDuration); + } + + private class EntryIterator implements Iterator { + private final long fIteratorStartTime; + private final long fIteratorStopTime; + private final long fIteratorMaxDuration; + private long lastTime = -1; + private TimeChartEvent next = null; + private Iterator nestedIterator = null; + + public EntryIterator(long startTime, long stopTime, long maxDuration) { + fIteratorStartTime = startTime; + fIteratorStopTime = stopTime; + fIteratorMaxDuration = maxDuration; + } + + @Override + public boolean hasNext() { + synchronized (fTraceEvents) { + if (next != null) { + return true; + } + if (nestedIterator != null) { + if (nestedIterator.hasNext()) { + return true; + } + nestedIterator = null; + } + long time = (lastTime == -1) ? fStartTime : lastTime; + int index = (fReferenceTime == -1) ? 0 : (int) ((time - fReferenceTime) >> fPower); + while (index < fTraceEvents.size()) { + TimeChartEvent event = fTraceEvents.get(index++); + if (event != null && (lastTime == -1 || event.getTime() > time)) { + if (event.getTime() + event.getDuration() >= fIteratorStartTime && event.getTime() <= fIteratorStopTime) { + if (event.getItemizedEntry() == null || event.getDuration() <= fIteratorMaxDuration) { + lastTime = event.getTime() + event.getDuration(); + next = event; + return true; + } + nestedIterator = event.getItemizedEntry().getTimeEventsIterator(fIteratorStartTime, fIteratorStopTime, fIteratorMaxDuration); + return nestedIterator.hasNext(); + } + } + } + return false; + } + } + + @Override + public TimeChartEvent next() { + synchronized (fTraceEvents) { + if (nestedIterator != null) { + TimeChartEvent event = (TimeChartEvent) nestedIterator.next(); + lastTime = event.getTime() + event.getDuration(); + return event; + } + if (hasNext()) { + TimeChartEvent event = next; + next = null; + return event; + } + throw new NoSuchElementException(); + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + } + + /** + * Add a time event to the time chart entry + * + * @param timeEvent + * The event to add + */ + public void addTraceEvent(ITimeEvent timeEvent) { + long time = timeEvent.getTime(); + synchronized (fTraceEvents) { + long index = (fReferenceTime == -1) ? 0 : (time - fReferenceTime) >> fPower; + if (index < 0) { + if (fTraceEvents.capacity() - fTraceEvents.size() < -index) { + int powershift = (-index + fTraceEvents.size() <= 2 * fTraceEvents.capacity()) ? 1 : + (int) Math.ceil(Math.log((double) (-index + fTraceEvents.size()) / fTraceEvents.capacity()) / Math.log(2)); + merge(powershift); + index = (int) ((time - fReferenceTime) >> fPower); + } + shift((int) -index); + index = 0; + fTraceEvents.set(0, (TimeChartEvent) timeEvent); + } else if (index < fTraceEvents.capacity()) { + if (index >= fTraceEvents.size()) { + fTraceEvents.setSize((int) index + 1); + } + } else { + int powershift = (index < 2 * fTraceEvents.capacity()) ? 1 : + (int) Math.ceil(Math.log((double) (index + 1) / fTraceEvents.capacity()) / Math.log(2)); + merge(powershift); + index = (int) ((time - fReferenceTime) >> fPower); + fTraceEvents.setSize((int) index + 1); + } + TimeChartEvent event = fTraceEvents.get((int) index); + if (event == null) { + fTraceEvents.set((int) index, (TimeChartEvent) timeEvent); + } else { + if (event.getItemizedEntry() == null) { + event.merge((TimeChartEvent) timeEvent); + } else { + event.mergeDecorations((TimeChartEvent) timeEvent); + event.getItemizedEntry().addTraceEvent(timeEvent); + } + } + if (fReferenceTime == -1 || time < fReferenceTime) { + fReferenceTime = (time >> fPower) << fPower; + } + if (fStartTime == -1 || time < fStartTime) { + fStartTime = time; + } + if (fStopTime == -1 || time > fStopTime) { + fStopTime = time; + } + } + } + + private void merge(int powershift) { + fPower += powershift; + fReferenceTime = (fReferenceTime >> fPower) << fPower; + int index = 0; + for (int i = 0; i < fTraceEvents.size(); i++) { + TimeChartEvent event = fTraceEvents.get(i); + if (event != null) { + index = (int) ((event.getTime() - fReferenceTime) >> fPower); + TimeChartEvent mergedEvent = fTraceEvents.get(index); + if (mergedEvent == null) { + fTraceEvents.set(index, event); + } else { + mergedEvent.merge(event); + } + if (i != index) { + fTraceEvents.set(i, null); + } + } + } + fTraceEvents.setSize(index + 1); + } + + private void shift(int indexshift) { + int oldSize = fTraceEvents.size(); + fTraceEvents.setSize(oldSize + indexshift); + for (int i = oldSize - 1; i >= 0; i--) { + fTraceEvents.set(i + indexshift, fTraceEvents.get(i)); + } + for (int i = 0; i < indexshift; i++) { + fTraceEvents.set(i, null); + } + } + + /** + * Retrieve the trace associated with this entry + * + * @return The trace object + */ + public ITmfTrace getTrace() { + return fTrace; + } + + /** + * Set the last rank of the entry + * + * @param rank + * The rank to set + */ + public void setLastRank(long rank) { + fLastRank = rank; + } + + /** + * Retrieve the last rank of the entry + * + * @return The last rank + */ + public long getLastRank() { + return fLastRank; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartAnalysisProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartAnalysisProvider.java new file mode 100644 index 0000000000..ba935bdd87 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartAnalysisProvider.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.timechart; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.tmf.ui.views.colors.ColorSetting; +import org.eclipse.tracecompass.tmf.ui.views.colors.ColorSettingsManager; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.StateItem; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; + +/** + * Provider for a time chart analysis view + * + * @version 1.0 + * @author Patrick Tasse + */ +public class TimeChartAnalysisProvider extends TimeGraphPresentationProvider { + + private static final Color BOOKMARK_INNER_COLOR = new Color(Display.getDefault(), 115, 165, 224); + private static final Color BOOKMARK_OUTER_COLOR = new Color(Display.getDefault(), 2, 70, 140); + private static final Color SEARCH_MATCH_COLOR = new Color(Display.getDefault(), 177, 118, 14); + + private int lastX = Integer.MIN_VALUE; + private int currX = Integer.MIN_VALUE; + private int lastPriority; + private int lastBookmarkX = Integer.MIN_VALUE; + + @Override + public StateItem[] getStateTable() { + + ColorSetting[] settings = ColorSettingsManager.getColorSettings(); + StateItem[] stateItems = new StateItem[settings.length]; + for (int i = 0; i < settings.length; i++) { + stateItems[i] = new StateItem(settings[i].getTickColorRGB()); + } + return stateItems; + } + + @Override + public int getStateTableIndex(ITimeEvent event) { + if (! ((TimeChartEvent) event).isVisible()) { + return ITimeGraphPresentationProvider.INVISIBLE; + } + int priority = ((TimeChartEvent) event).getColorSettingPriority(); + if (currX == lastX) { + priority = Math.min(priority, lastPriority); + } + lastPriority = priority; + return priority; + } + + @Override + public void postDrawEvent(ITimeEvent event, Rectangle rect, GC gc) { + if (! ((TimeChartEvent) event).isVisible()) { + return; + } + lastX = currX; + currX = rect.x; + if (lastBookmarkX == rect.x || ((TimeChartEvent) event).isBookmarked()) { + drawBookmark(rect, gc); + lastBookmarkX = rect.x; + } else if (lastBookmarkX == rect.x - 1) { + Rectangle r = new Rectangle(lastBookmarkX, rect.y, rect.width, rect.height); + drawBookmark(r, gc); + } else { + lastBookmarkX = Integer.MIN_VALUE; + } + if (((TimeChartEvent) event).isSearchMatch()) { + drawSearchMatch(rect, gc); + } + } + + private static void drawBookmark(Rectangle r, GC gc) { + gc.setForeground(BOOKMARK_OUTER_COLOR); + gc.drawLine(r.x - 1, r.y - 2, r.x - 1, r.y + 2); + gc.drawLine(r.x + 1, r.y - 2, r.x + 1, r.y + 2); + gc.drawPoint(r.x, r.y - 2); + gc.setForeground(BOOKMARK_INNER_COLOR); + gc.drawLine(r.x, r.y - 1, r.x, r.y + 1); + gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); + gc.drawPoint(r.x - 1, r.y + 3); + gc.drawPoint(r.x, r.y + 2); + gc.drawPoint(r.x + 1, r.y + 3); + } + + private static void drawSearchMatch(Rectangle r, GC gc) { + gc.setForeground(SEARCH_MATCH_COLOR); + gc.drawPoint(r.x, r.y + r.height); + gc.drawLine(r.x - 1, r.y + r.height + 1, r.x + 1, r.y + r.height + 1); + gc.drawLine(r.x - 2, r.y + r.height + 2, r.x + 2, r.y + r.height + 2); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartDecorationProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartDecorationProvider.java new file mode 100644 index 0000000000..1dbd59dd0f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartDecorationProvider.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.timechart; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.filter.ITmfFilter; + +/** + * Provider for decorations in the time chart view + * + * @version 1.0 + * @author Patrick Tasse + */ +public class TimeChartDecorationProvider { + + private final IFile fBookmarksFile; + private final Set fBookmarksSet = new HashSet<>(); + private ITmfFilter fFilterFilter; + private ITmfFilter fSearchFilter; + + /** + * Constructor + * + * @param bookmarksFile + * Bookmark file associated with the trace + */ + public TimeChartDecorationProvider(IFile bookmarksFile) { + fBookmarksFile = bookmarksFile; + refreshBookmarks(); + } + + /** + * Retrieve the bookmark file that was assigned to this provider + * + * @return The bookmark file + */ + public IFile getBookmarksFile() { + return fBookmarksFile; + } + + /** + * Verify if the selected rank has a bookmark assigned to it. + * + * @param rank + * The rank to check for + * @return If there is a bookmark there + */ + public boolean isBookmark(long rank) { + return fBookmarksSet.contains(rank); + } + + /** + * Refresh the bookmark display. + */ + public void refreshBookmarks() { + try { + fBookmarksSet.clear(); + if (fBookmarksFile == null) { + return; + } + for (IMarker bookmark : fBookmarksFile.findMarkers( + IMarker.BOOKMARK, false, IResource.DEPTH_ZERO)) { + int location = bookmark.getAttribute(IMarker.LOCATION, -1); + if (location != -1) { + Long rank = (long) location; + fBookmarksSet.add(rank); + } + } + } catch (CoreException e) { + Activator.getDefault().logError("Error refreshing bookmarks", e); //$NON-NLS-1$ + } + } + + /** + * Notify that a filter is now applied on the view. + * + * @param filter + * The filter that was applied + */ + public void filterApplied(ITmfFilter filter) { + fFilterFilter = filter; + } + + /** + * Check if an event is currently visible in the view or not. + * + * @param event + * The event to check for + * @return If the event is visible or not + */ + public boolean isVisible(ITmfEvent event) { + if (fFilterFilter != null) { + return fFilterFilter.matches(event); + } + return true; + } + + /** + * Notify that a search is applied on the view. + * + * @param filter + * The search filter that was applied + */ + public void searchApplied(ITmfFilter filter) { + fSearchFilter = filter; + } + + /** + * Verify if the currently active search filter applies to the given event + * or not. + * + * @param event + * The event to check for + * @return If the event matches + */ + public boolean isSearchMatch(ITmfEvent event) { + if (fSearchFilter != null) { + return fSearchFilter.matches(event); + } + return false; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartEvent.java new file mode 100644 index 0000000000..9a5850cebc --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartEvent.java @@ -0,0 +1,375 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.timechart; + +import java.util.ArrayList; +import java.util.Iterator; + +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.ui.views.colors.ColorSettingsManager; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; + +/** + * Event in the time chart view + * + * @version 1.0 + * @author Patrick Tasse + */ +public class TimeChartEvent implements ITimeEvent { + + private static final byte TIMESTAMP_SCALE = -9; + + private final TimeChartAnalysisEntry fParentEntry; + private long fTime; + private long fDuration; + private long fFirstRank; + private long fLastRank; + private final RankRangeList fRankRangeList; + private long fNbEvents; + private int fColorSettingPriority; + private boolean fIsBookmark; + private boolean fIsVisible; + private boolean fIsSearchMatch; + private TimeChartAnalysisEntry fItemizedEntry; + private boolean fItemizing; + + /** + * Standard constructor + * + * @param parentEntry + * The parent entry + * @param event + * The event from which this time chart event originates + * @param rank + * The rank of the event in the trace + * @param decorationProvider + * The decoration provider to use + */ + public TimeChartEvent(TimeChartAnalysisEntry parentEntry, ITmfEvent event, + long rank, TimeChartDecorationProvider decorationProvider) { + fParentEntry = parentEntry; + fTime = event.getTimestamp().normalize(0, TIMESTAMP_SCALE).getValue(); + fDuration = 0; + fFirstRank = fLastRank = rank; + fRankRangeList = new RankRangeList(rank); + fNbEvents = 1; + fColorSettingPriority = ColorSettingsManager.getColorSettingPriority(event); + fIsBookmark = decorationProvider.isBookmark(rank); + fIsVisible = decorationProvider.isVisible(event); + fIsSearchMatch = decorationProvider.isSearchMatch(event); + } + + @Override + public ITimeGraphEntry getEntry() { + return fParentEntry; + } + + @Override + public long getTime() { + return fTime; + } + + @Override + public long getDuration() { + return fDuration; + } + + /** + * Retrieve the rank of the trace event which started this time event. + * + * @return The rank of the beginning + */ + public long getFirstRank() { + return fFirstRank; + } + + /** + * Retrieve the rank of the trace event which *finished* this time event. + * + * @return The rank of the end + */ + public long getLastRank() { + return fLastRank; + } + + /** + * Get the list of rank ranges corresponding to this time event. + * + * @return The rank range list + */ + public RankRangeList getRankRangeList() { + return fRankRangeList; + } + + /** + * Merge another time event with this one. + * + * @param event + * The other event + */ + public void merge(TimeChartEvent event) { + mergeDecorations(event); + if (fTime == event.getTime() && fDuration == event.getDuration()) { + return; + } + long endTime = Math.max(fTime + fDuration, event.getTime() + event.getDuration()); + fTime = Math.min(fTime, event.getTime()); + fDuration = endTime - fTime; + fFirstRank = Math.min(fFirstRank, event.fFirstRank); + fLastRank = Math.max(fLastRank, event.fLastRank); + fNbEvents += event.fNbEvents; + fItemizedEntry = null; + synchronized (fRankRangeList) { + fRankRangeList.merge(event.getRankRangeList()); + } + } + + /** + * Merge the decorations of another time event with the decorations of this + * one. + * + * @param event + * The other event + */ + public void mergeDecorations(TimeChartEvent event) { + fColorSettingPriority = Math.min(fColorSettingPriority, event.getColorSettingPriority()); + fIsBookmark |= event.fIsBookmark; + fIsVisible |= event.fIsVisible; + fIsSearchMatch |= event.fIsSearchMatch; + } + + /** + * Get the number of time events that have been merged with this one (starts + * counting at 1 if no merge happened). + * + * @return The current number of events in the bath + */ + public long getNbEvents() { + return fNbEvents; + } + + /** + * Retrieve the color setting priority. + * + * @return The priority + */ + public int getColorSettingPriority() { + return fColorSettingPriority; + } + + /** + * Set the color setting priority. + * + * @param priority + * The priority to set + */ + public void setColorSettingPriority(int priority) { + fColorSettingPriority = priority; + } + + /** + * Check if this time event is bookmarked + * + * @return Y/N + */ + public boolean isBookmarked() { + return fIsBookmark; + } + + /** + * Set this time event to be bookmarked or not. + * + * @param isBookmarked + * Should time time event become a bookmark, or not + */ + public void setIsBookmarked(boolean isBookmarked) { + fIsBookmark = isBookmarked; + } + + /** + * Check if this time is currently visible or not. + * + * @return If the event is visible + */ + public boolean isVisible() { + return fIsVisible; + } + + /** + * Set this time event to visible (or to non-visible). + * + * @param isVisible The new status + */ + public void setIsVisible(boolean isVisible) { + fIsVisible = isVisible; + } + + /** + * Check if the time event matches the current search. + * + * @return If it matches, Y/N + */ + public boolean isSearchMatch() { + return fIsSearchMatch; + } + + /** + * Mark this event as matching (or non-matching) the current search. + * + * @param isSearchMatch + * The new matching status + */ + public void setIsSearchMatch(boolean isSearchMatch) { + fIsSearchMatch = isSearchMatch; + } + + /** + * Set this event's itemized entry. + * + * @param timeAnalysisEntry + * The entry to set + */ + public void setItemizedEntry(TimeChartAnalysisEntry timeAnalysisEntry) { + fItemizedEntry = timeAnalysisEntry; + } + + /** + * Retrieve this event's itemized entry. + * + * @return The itemized entry that was previously set + */ + public TimeChartAnalysisEntry getItemizedEntry() { + return fItemizedEntry; + } + + /** + * @return Has this time event been set to itemizing? + */ + public boolean isItemizing() { + return fItemizing; + } + + /** + * Set this event's itemizing flag to true or false. + * + * @param itemizing + * The new value + */ + public void setItemizing(boolean itemizing) { + fItemizing = itemizing; + } + + /** + * Inner class to define a range in terms of ranks in the trace. + * + * @version 1.0 + * @author Patrick Tasse + */ + public class RankRange { + private long firstRank; + private long lastRank; + + /** + * Standard constructor + * + * @param firstRank + * The first (earliest) rank of the range + * @param lastRank + * The last (latest) rank of the range + */ + public RankRange(long firstRank, long lastRank) { + this.firstRank = firstRank; + this.lastRank = lastRank; + } + + /** + * Retrieve the start rank of this range. + * + * @return The first rank + */ + public long getFirstRank() { + return firstRank; + } + + /** + * Retrieve the end rank of this range + * + * @return The end rank + */ + public long getLastRank() { + return lastRank; + } + + /** + * Calculate the minimal distance between two RankRange's + * + * @param range + * The other range + * @return The distance, in "number of events" between the two ranges + */ + public long distanceFrom(RankRange range) { + if (range.lastRank < fFirstRank) { + return fFirstRank - range.lastRank; + } else if (range.firstRank > fLastRank) { + return range.firstRank - fLastRank; + } else { + return 0; + } + } + + @Override + public String toString() { + return "["+firstRank+","+lastRank+"]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + } + + private class RankRangeList extends ArrayList { + + private static final long serialVersionUID = 6060485531208535986L; + + public RankRangeList(long rank) { + super(1); + add(new RankRange(rank, rank)); + } + + public void merge(RankRangeList rankRangeList) { + long threshold = fParentEntry.getTrace().getCacheSize(); + for (RankRange newRange : rankRangeList) { + boolean merged = false; + for (RankRange oldRange : fRankRangeList) { + if (newRange.distanceFrom(oldRange) <= threshold) { + oldRange.firstRank = Math.min(oldRange.firstRank, newRange.firstRank); + oldRange.lastRank = Math.max(oldRange.lastRank, newRange.lastRank); + merged = true; + break; + } + } + if (!merged) { + add(newRange); + } + } + Iterator iterator = fRankRangeList.iterator(); + RankRange previous = null; + while (iterator.hasNext()) { + RankRange range = iterator.next(); + if (previous != null && range.distanceFrom(previous) <= threshold) { + previous.firstRank = Math.min(previous.firstRank, range.firstRank); + previous.lastRank = Math.max(previous.lastRank, range.lastRank); + iterator.remove(); + } + previous = range; + } + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartView.java new file mode 100644 index 0000000000..73dd074a18 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timechart/TimeChartView.java @@ -0,0 +1,754 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.timechart; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IMarkerDelta; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.signal.TmfEventFilterAppliedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfEventSearchAppliedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfRangeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceUpdatedSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ui.views.TmfView; +import org.eclipse.tracecompass.tmf.ui.views.colors.ColorSetting; +import org.eclipse.tracecompass.tmf.ui.views.colors.ColorSettingsManager; +import org.eclipse.tracecompass.tmf.ui.views.colors.IColorSettingsListener; +import org.eclipse.tracecompass.tmf.ui.views.timechart.TimeChartEvent.RankRange; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphRangeListener; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphSelectionListener; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphTimeListener; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphSelectionEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphTimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphViewer; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; + +/** + * Generic Time Chart view, which is similar to a Gantt chart for trace analysis + * + * @version 1.0 + * @author Patrick Tasse + */ +public class TimeChartView extends TmfView implements ITimeGraphRangeListener, ITimeGraphSelectionListener, ITimeGraphTimeListener, IColorSettingsListener, IResourceChangeListener { + + /** TimeChartView's ID */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.timechart"; //$NON-NLS-1$ + + private static final int TIMESTAMP_SCALE = -9; + + private final int fDisplayWidth; + private TimeGraphViewer fViewer; + private final ArrayList fTimeAnalysisEntries = new ArrayList<>(); + private final Map fDecorationProviders = new HashMap<>(); + private final ArrayList fDecorateThreads = new ArrayList<>(); + private long fStartTime = 0; + private long fStopTime = Long.MAX_VALUE; + private boolean fRefreshBusy = false; + private boolean fRefreshPending = false; + private boolean fRedrawBusy = false; + private boolean fRedrawPending = false; + private final Object fSyncObj = new Object(); + private ITimeGraphPresentationProvider fPresentationProvider; + + /** + * Default constructor + */ + public TimeChartView() { + super("Time Chart"); //$NON-NLS-1$ + fDisplayWidth = Display.getDefault().getBounds().width; + } + + @Override + public void createPartControl(Composite parent) { + fViewer = new TimeGraphViewer(parent, SWT.NONE); + fPresentationProvider = new TimeChartAnalysisProvider(); + fViewer.setTimeGraphProvider(fPresentationProvider); + fViewer.setTimeFormat(TimeFormat.CALENDAR); + fViewer.addTimeListener(this); + fViewer.addRangeListener(this); + fViewer.addSelectionListener(this); + fViewer.setMinimumItemWidth(1); + + IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager(); + fViewer.getTimeGraphControl().setStatusLineManager(statusLineManager); + + for (ITmfTrace trace : TmfTraceManager.getInstance().getOpenedTraces()) { + IFile bookmarksFile = TmfTraceManager.getInstance().getTraceEditorFile(trace); + TimeChartAnalysisEntry timeAnalysisEntry = new TimeChartAnalysisEntry(trace, fDisplayWidth * 2); + fTimeAnalysisEntries.add(timeAnalysisEntry); + fDecorationProviders.put(trace, new TimeChartDecorationProvider(bookmarksFile)); + Thread thread = new ProcessTraceThread(timeAnalysisEntry); + thread.start(); + } + fViewer.setInput(fTimeAnalysisEntries.toArray(new TimeChartAnalysisEntry[0])); + + ColorSettingsManager.addColorSettingsListener(this); + ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE); + } + + @Override + public void dispose() { + ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); + for (DecorateThread thread : fDecorateThreads) { + thread.cancel(); + } + ColorSettingsManager.removeColorSettingsListener(this); + super.dispose(); + } + + @Override + public void setFocus() { + fViewer.setFocus(); + } + + private class ProcessTraceThread extends Thread { + + private final TimeChartAnalysisEntry fTimeAnalysisEntry; + + public ProcessTraceThread(TimeChartAnalysisEntry timeAnalysisEntry) { + super("ProcessTraceJob:" + timeAnalysisEntry.getName()); //$NON-NLS-1$ + fTimeAnalysisEntry = timeAnalysisEntry; + } + + @Override + public void run() { + updateTraceEntry(fTimeAnalysisEntry, Long.MAX_VALUE, 0, Long.MAX_VALUE); + } + } + + private void updateTraceEntry(TimeChartAnalysisEntry timeAnalysisEntry, long stopRank, long startTime, long stopTime) { + ITmfTrace trace = timeAnalysisEntry.getTrace(); + TimeChartDecorationProvider decorationProvider = fDecorationProviders.get(trace); + if (decorationProvider == null) { + return; // the trace has been closed + } + ITmfContext context = null; + // TmfTimestamp lastTimestamp = null; + boolean done = false; + while (!done) { + synchronized (timeAnalysisEntry) { + if (timeAnalysisEntry.getLastRank() >= trace.getNbEvents()) { + done = true; + break; + } + if (context == null || context.getRank() != timeAnalysisEntry.getLastRank()) { + if (context != null) { + context.dispose(); + } + if (timeAnalysisEntry.getLastRank() != -1) { + context = trace.seekEvent(timeAnalysisEntry.getLastRank()); + } else { + // context = trace.seekLocation(null); + context = trace.seekEvent(0); + } + } + while (true) { + long rank = context.getRank(); + ITmfEvent event = trace.getNext(context); + if (event == null) { + done = true; + break; + } + // if (!event.getTimestamp().equals(lastTimestamp)) { + TimeChartEvent timeEvent = new TimeChartEvent(timeAnalysisEntry, event, rank, decorationProvider); + if (timeEvent.getTime() >= startTime && timeEvent.getTime() <= stopTime) { + timeAnalysisEntry.addTraceEvent(timeEvent); + } + // lastTimestamp = event.getTimestamp(); + // } *** commented out so that color setting priority gets + // set even if the event has same time + if (context.getRank() == trace.getNbEvents() || context.getRank() == stopRank) { + done = true; + break; + } + if (context.getRank() % trace.getCacheSize() == 1) { + // break for UI refresh + break; + } + } + // timeAnalysisEntry.setLastRank(Math.min(trace.getNbEvents(), + // stopRank)); + timeAnalysisEntry.setLastRank(context.getRank()); + } + redrawViewer(true); + } + if (context != null) { + context.dispose(); + } + } + + private void refreshViewer() { + synchronized (fSyncObj) { + if (fRefreshBusy) { + fRefreshPending = true; + return; + } + fRefreshBusy = true; + } + // Perform the refresh on the UI thread + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (fViewer.getControl().isDisposed()) { + return; + } + fViewer.setInput(fTimeAnalysisEntries.toArray(new TimeChartAnalysisEntry[0])); + fViewer.resetStartFinishTime(); + synchronized (fSyncObj) { + fRefreshBusy = false; + if (fRefreshPending) { + fRefreshPending = false; + refreshViewer(); + } + } + } + }); + } + + private void redrawViewer(boolean resetTimeIntervals) { + synchronized (fSyncObj) { + if (fRedrawBusy) { + fRedrawPending = true; + return; + } + fRedrawBusy = true; + } + final boolean reset = resetTimeIntervals; + // Perform the refresh on the UI thread + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (fViewer.getControl().isDisposed()) { + return; + } + if (reset) { + fViewer.setTimeRange(fTimeAnalysisEntries.toArray(new TimeChartAnalysisEntry[0])); + fViewer.setTimeBounds(); + } + fViewer.getControl().redraw(); + fViewer.getControl().update(); + synchronized (fSyncObj) { + fRedrawBusy = false; + if (fRedrawPending) { + fRedrawPending = false; + redrawViewer(reset); + } + } + } + }); + } + + private void itemize(long startTime, long stopTime) { + for (int i = 0; i < fTimeAnalysisEntries.size(); i++) { + Thread thread = new ItemizeThread(fTimeAnalysisEntries.get(i), startTime, stopTime); + thread.start(); + } + } + + private class ItemizeThread extends Thread { + + private final TimeChartAnalysisEntry fTimeAnalysisEntry; + private final long startTime; + private final long stopTime; + private final long fMaxDuration; + + private ItemizeThread(TimeChartAnalysisEntry timeAnalysisEntry, long startTime, long stopTime) { + super("Itemize Thread:" + timeAnalysisEntry.getName()); //$NON-NLS-1$ + fTimeAnalysisEntry = timeAnalysisEntry; + this.startTime = startTime; + this.stopTime = stopTime; + fMaxDuration = 3 * (stopTime - startTime) / fDisplayWidth; + } + + @Override + public void run() { + itemizeTraceEntry(fTimeAnalysisEntry); + } + + public void itemizeTraceEntry(TimeChartAnalysisEntry timeAnalysisEntry) { + Iterator iterator = timeAnalysisEntry.getTimeEventsIterator(); + TimeChartEvent event = null; + boolean hasNext = true; + while (hasNext) { + synchronized (timeAnalysisEntry) { + while ((hasNext = iterator.hasNext()) == true) { + event = (TimeChartEvent) iterator.next(); + if (event.getTime() + event.getDuration() > startTime && event.getTime() < stopTime && event.getDuration() > fMaxDuration + && event.getNbEvents() > 1) { + break; + } + } + } + if (hasNext && event != null) { + if (event.getItemizedEntry() == null) { + itemizeEvent(event); + } else { + itemizeTraceEntry(event.getItemizedEntry()); + } + } + } + } + + public void itemizeEvent(TimeChartEvent event) { + synchronized (event) { + if (event.isItemizing()) { + return; + } + event.setItemizing(true); + } + TimeChartAnalysisEntry timeAnalysisEntry = new TimeChartAnalysisEntry(fTimeAnalysisEntry.getTrace(), (int) Math.min( + event.getNbEvents() + 1, fDisplayWidth * 2)); + synchronized (event.getRankRangeList()) { + for (RankRange range : event.getRankRangeList()) { + timeAnalysisEntry.setLastRank(range.getFirstRank()); + updateTraceEntry(timeAnalysisEntry, range.getLastRank() + 1, event.getTime(), event.getTime() + event.getDuration()); + } + } + event.setItemizedEntry(timeAnalysisEntry); + redrawViewer(false); + itemizeTraceEntry(timeAnalysisEntry); + synchronized (event) { + event.setItemizing(false); + } + } + } + + private void redecorate() { + synchronized (fDecorateThreads) { + for (DecorateThread thread : fDecorateThreads) { + thread.cancel(); + } + fDecorateThreads.clear(); + for (int i = 0; i < fTimeAnalysisEntries.size(); i++) { + DecorateThread thread = new DecorateThread(fTimeAnalysisEntries.get(i)); + thread.start(); + fDecorateThreads.add(thread); + } + } + } + + private class DecorateThread extends Thread { + private volatile boolean interrupted = false; + private final TimeChartAnalysisEntry fTimeAnalysisEntry; + private final TimeChartDecorationProvider fDecorationProvider; + private ITmfContext fContext; + private int fCount = 0; + + private DecorateThread(TimeChartAnalysisEntry timeAnalysisEntry) { + super("Decorate Thread:" + timeAnalysisEntry.getName()); //$NON-NLS-1$ + fTimeAnalysisEntry = timeAnalysisEntry; + fDecorationProvider = fDecorationProviders.get(timeAnalysisEntry.getTrace()); + } + + @Override + public void run() { + resetTraceEntry(fTimeAnalysisEntry); + redrawViewer(false); + decorateTraceEntry(fTimeAnalysisEntry, null); + redrawViewer(false); + synchronized (fDecorateThreads) { + fDecorateThreads.remove(this); + } + if (fContext != null) { + fContext.dispose(); + } + } + + public void resetTraceEntry(TimeChartAnalysisEntry timeAnalysisEntry) { + Iterator iterator = timeAnalysisEntry.getTimeEventsIterator(); + TimeChartEvent event = null; + boolean hasNext = true; + while (!interrupted && hasNext) { + synchronized (timeAnalysisEntry) { + while ((hasNext = iterator.hasNext()) == true) { + event = (TimeChartEvent) iterator.next(); + break; + } + } + if (hasNext && event != null) { + // TODO possible concurrency problem here with ItemizeJob + event.setColorSettingPriority(ColorSettingsManager.PRIORITY_NONE); + if (event.getItemizedEntry() != null) { + resetTraceEntry(event.getItemizedEntry()); + } + } + } + } + + public void decorateTraceEntry(TimeChartAnalysisEntry timeAnalysisEntry, TimeChartEvent parentEvent) { + // Set max duration high to ensure iterator does not consider + // itemized events + Iterator iterator = timeAnalysisEntry.getTimeEventsIterator(0, Long.MAX_VALUE, Long.MAX_VALUE); + TimeChartEvent event = null; + int entryPriority = ColorSettingsManager.PRIORITY_NONE; + boolean entryIsBookmarked = false; + boolean entryIsVisible = false; + boolean entryIsSearchMatch = false; + boolean hasNext = true; + while (!interrupted && hasNext) { + synchronized (timeAnalysisEntry) { + while ((hasNext = iterator.hasNext()) == true) { + event = (TimeChartEvent) iterator.next(); + break; + } + } + if (hasNext && event != null) { + // TODO possible concurrency problem here with ItemizeJob + if (event.getItemizedEntry() == null) { + decorateEvent(event); + } else { + decorateTraceEntry(event.getItemizedEntry(), event); + } + entryPriority = Math.min(entryPriority, event.getColorSettingPriority()); + entryIsBookmarked |= event.isBookmarked(); + entryIsVisible |= event.isVisible(); + entryIsSearchMatch |= event.isSearchMatch(); + if (++fCount % timeAnalysisEntry.getTrace().getCacheSize() == 0) { + redrawViewer(false); + } + } + } + if (parentEvent != null) { + parentEvent.setColorSettingPriority(entryPriority); + parentEvent.setIsBookmarked(entryIsBookmarked); + parentEvent.setIsVisible(entryIsVisible); + parentEvent.setIsSearchMatch(entryIsSearchMatch); + } + } + + public void decorateEvent(TimeChartEvent timeChartEvent) { + // TODO possible concurrency problem here with ItemizeJob + TimeChartAnalysisEntry timeAnalysisEntry = (TimeChartAnalysisEntry) timeChartEvent.getEntry(); + ITmfTrace trace = timeAnalysisEntry.getTrace(); + int priority = ColorSettingsManager.PRIORITY_NONE; + boolean isBookmarked = false; + boolean isVisible = false; + boolean isSearchMatch = false; + synchronized (timeChartEvent.getRankRangeList()) { + for (RankRange range : timeChartEvent.getRankRangeList()) { + if (interrupted) { + return; + } + if (fContext == null || fContext.getRank() != range.getFirstRank()) { + if (fContext != null) { + fContext.dispose(); + } + fContext = trace.seekEvent(range.getFirstRank()); + fContext.setRank(range.getFirstRank()); + } + while (true) { + if (interrupted) { + return; + } + long rank = fContext.getRank(); + ITmfEvent event = trace.getNext(fContext); + if (event == null) { + break; + } + long eventTime = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + if (eventTime >= timeChartEvent.getTime() && eventTime <= timeChartEvent.getTime() + timeChartEvent.getDuration()) { + priority = Math.min(priority, ColorSettingsManager.getColorSettingPriority(event)); + } + isBookmarked |= fDecorationProvider.isBookmark(rank); + isVisible |= fDecorationProvider.isVisible(event); + isSearchMatch |= fDecorationProvider.isSearchMatch(event); + if (fContext.getRank() > range.getLastRank()) { + break; + } + } + } + } + timeChartEvent.setColorSettingPriority(priority); + timeChartEvent.setIsBookmarked(isBookmarked); + timeChartEvent.setIsVisible(isVisible); + timeChartEvent.setIsSearchMatch(isSearchMatch); + } + + public void cancel() { + interrupted = true; + } + } + + // ------------------------------------------------------------------------ + // Listeners + // ------------------------------------------------------------------------ + + @Override + public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) { + fStartTime = event.getStartTime(); + fStopTime = event.getEndTime(); + itemize(fStartTime, fStopTime); + final ITmfTimestamp startTimestamp = new TmfTimestamp(event.getStartTime(), ITmfTimestamp.NANOSECOND_SCALE); + final ITmfTimestamp endTimestamp = new TmfTimestamp(event.getEndTime(), ITmfTimestamp.NANOSECOND_SCALE); + TmfTimeRange range = new TmfTimeRange(startTimestamp, endTimestamp); + broadcast(new TmfRangeSynchSignal(this, range)); + } + + @Override + public void selectionChanged(TimeGraphSelectionEvent event) { + ITimeGraphEntry timeAnalysisEntry = null; + if (event.getSelection() instanceof TimeChartAnalysisEntry) { + timeAnalysisEntry = event.getSelection(); + } else if (event.getSelection() instanceof TimeChartEvent) { + timeAnalysisEntry = ((TimeChartEvent) event.getSelection()).getEntry(); + } + if (timeAnalysisEntry instanceof TimeChartAnalysisEntry) { + broadcast(new TmfTraceSelectedSignal(this, ((TimeChartAnalysisEntry) timeAnalysisEntry).getTrace())); + } + } + + @Override + public void timeSelected(TimeGraphTimeEvent event) { + broadcast(new TmfTimeSynchSignal(this, new TmfTimestamp(event.getBeginTime(), TIMESTAMP_SCALE), new TmfTimestamp(event.getEndTime(), TIMESTAMP_SCALE))); + } + + @Override + public void colorSettingsChanged(ColorSetting[] colorSettings) { + // Set presentation provider again to trigger re-creation of new color settings which are stored + // in the TimeGraphControl class + fViewer.setTimeGraphProvider(fPresentationProvider); + redecorate(); + } + + @Override + public void resourceChanged(IResourceChangeEvent event) { + for (IMarkerDelta delta : event.findMarkerDeltas(IMarker.BOOKMARK, false)) { + for (TimeChartDecorationProvider provider : fDecorationProviders.values()) { + if (delta.getResource().equals(provider.getBookmarksFile())) { + if (delta.getKind() == IResourceDelta.CHANGED && delta.getMarker().getAttribute(IMarker.LOCATION, -1) != -1) { + provider.refreshBookmarks(); + } else if (delta.getKind() == IResourceDelta.REMOVED) { + provider.refreshBookmarks(); + } + } + } + } + redecorate(); + } + + // ------------------------------------------------------------------------ + // Signal handlers + // ------------------------------------------------------------------------ + + /** + * Handler for the Trace Opened signal + * + * @param signal + * The incoming signal + * @since 2.0 + */ + @TmfSignalHandler + public void traceOpened(TmfTraceOpenedSignal signal) { + final ITmfTrace trace = signal.getTrace(); + final IFile bookmarksFile = signal.getEditorFile(); + TimeChartAnalysisEntry timeAnalysisEntry = null; + for (int i = 0; i < fTimeAnalysisEntries.size(); i++) { + if (fTimeAnalysisEntries.get(i).getTrace().equals(trace)) { + timeAnalysisEntry = fTimeAnalysisEntries.get(i); + break; + } + } + if (timeAnalysisEntry == null) { + timeAnalysisEntry = new TimeChartAnalysisEntry(trace, fDisplayWidth * 2); + fTimeAnalysisEntries.add(timeAnalysisEntry); + fDecorationProviders.put(trace, new TimeChartDecorationProvider(bookmarksFile)); + Thread thread = new ProcessTraceThread(timeAnalysisEntry); + thread.start(); + } + refreshViewer(); + } + + /** + * Handler for the Trace Closed signal + * + * @param signal + * The incoming signal + * @since 2.0 + */ + @TmfSignalHandler + public void traceClosed(TmfTraceClosedSignal signal) { + final ITmfTrace trace = signal.getTrace(); + for (int i = 0; i < fTimeAnalysisEntries.size(); i++) { + if (fTimeAnalysisEntries.get(i).getTrace().equals(trace)) { + fTimeAnalysisEntries.remove(i); + fDecorationProviders.remove(trace); + synchronized (fDecorateThreads) { + for (DecorateThread thread : fDecorateThreads) { + if (thread.fTimeAnalysisEntry.getTrace() == trace) { + thread.cancel(); + fDecorateThreads.remove(thread); + break; + } + } + } + refreshViewer(); + break; + } + } + } + + /** + * Handler for the Trace Selected signal + * + * @param signal + * The incoming signal + */ + @TmfSignalHandler + public void traceSelected(TmfTraceSelectedSignal signal) { + if (signal.getSource() != this) { + ITmfTrace trace = signal.getTrace(); + for (int i = 0; i < fTimeAnalysisEntries.size(); i++) { + if (fTimeAnalysisEntries.get(i).getTrace().equals(trace)) { + fViewer.setSelection(fTimeAnalysisEntries.get(i)); + break; + } + } + long beginTime = fTraceManager.getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long endTime = fTraceManager.getSelectionEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + fViewer.setSelectionRange(beginTime, endTime); + } + } + + /** + * Handler for the Trace Updated signal + * + * @param signal + * The incoming signal + */ + @TmfSignalHandler + public void traceUpdated(TmfTraceUpdatedSignal signal) { + final ITmfTrace trace = signal.getTrace(); + for (int i = 0; i < fTimeAnalysisEntries.size(); i++) { + TimeChartAnalysisEntry timeAnalysisEntry = fTimeAnalysisEntries.get(i); + if (timeAnalysisEntry.getTrace().equals(trace)) { + updateTraceEntry(timeAnalysisEntry, Long.MAX_VALUE, 0, Long.MAX_VALUE); + break; + } + } + } + + /** + * Handler for the Time Synch signal + * + * @param signal + * The incoming signal + */ + @TmfSignalHandler + public void currentTimeUpdated(TmfTimeSynchSignal signal) { + final long beginTime = signal.getBeginTime().normalize(0, TIMESTAMP_SCALE).getValue(); + final long endTime = signal.getEndTime().normalize(0, TIMESTAMP_SCALE).getValue(); + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (beginTime == endTime) { + fViewer.setSelectedTime(beginTime, true); + if (fStartTime != fViewer.getTime0() || fStopTime != fViewer.getTime1()) { + fStartTime = fViewer.getTime0(); + fStopTime = fViewer.getTime1(); + itemize(fStartTime, fStopTime); + } + } else { + fViewer.setSelectionRange(beginTime, endTime); + } + } + }); + } + + /** + * Handler for the Time Range Synch signal + * + * @param signal + * The incoming signal + * @since 2.0 + */ + @TmfSignalHandler + public void synchToRange(final TmfRangeSynchSignal signal) { + if (signal.getSource() == this) { + return; + } + final long startTime = signal.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + final long endTime = signal.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + fStartTime = startTime; + fStopTime = endTime; + itemize(fStartTime, fStopTime); + fViewer.setStartFinishTime(startTime, endTime); + } + }); + } + + /** + * Handler for the Event Filter Applied signal + * + * @param signal + * The incoming signal + * @since 2.0 + */ + @TmfSignalHandler + public void filterApplied(TmfEventFilterAppliedSignal signal) { + TimeChartDecorationProvider decorationProvider = fDecorationProviders.get(signal.getTrace()); + if (decorationProvider == null) { + return; + } + decorationProvider.filterApplied(signal.getEventFilter()); + redecorate(); + } + + /** + * Handler for the Event Search Applied signal + * + * @param signal + * The incoming signal + * @since 2.0 + */ + @TmfSignalHandler + public void searchApplied(TmfEventSearchAppliedSignal signal) { + TimeChartDecorationProvider decorationProvider = fDecorationProviders.get(signal.getTrace()); + if (decorationProvider == null) { + return; + } + decorationProvider.searchApplied(signal.getSearchFilter()); + redecorate(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/AbstractTimeGraphView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/AbstractTimeGraphView.java new file mode 100644 index 0000000000..79ca26cac3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/AbstractTimeGraphView.java @@ -0,0 +1,1271 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Bernd Hufmann - Updated signal handling + * Geneviève Bastien - Move code to provide base classes for time graph view + * Marc-Andre Laperle - Add time zone preference + * Geneviève Bastien - Add event links between entries + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.timegraph; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.tracecompass.tmf.core.signal.TmfRangeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ui.TmfUiRefreshHandler; +import org.eclipse.tracecompass.tmf.ui.views.TmfView; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphContentProvider; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider2; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphRangeListener; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphSelectionListener; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphTimeListener; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphCombo; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphTimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphViewer; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; +import org.eclipse.ui.IActionBars; + +/** + * An abstract view all time graph views can inherit + * + * This view contains either a time graph viewer, or a time graph combo which is + * divided between a tree viewer on the left and a time graph viewer on the right. + * + * @since 2.1 + */ +public abstract class AbstractTimeGraphView extends TmfView { + + /** + * Redraw state enum + */ + private enum State { + IDLE, BUSY, PENDING + } + + // ------------------------------------------------------------------------ + // Fields + // ------------------------------------------------------------------------ + + /** The timegraph wrapper */ + private ITimeGraphWrapper fTimeGraphWrapper; + + /** The selected trace */ + private ITmfTrace fTrace; + + /** The timegraph entry list */ + private List fEntryList; + + /** The trace to entry list hash map */ + private final Map> fEntryListMap = new HashMap<>(); + + /** The trace to build thread hash map */ + private final Map fBuildThreadMap = new HashMap<>(); + + /** The start time */ + private long fStartTime; + + /** The end time */ + private long fEndTime; + + /** The display width */ + private final int fDisplayWidth; + + /** The zoom thread */ + private ZoomThread fZoomThread; + + /** The next resource action */ + private Action fNextResourceAction; + + /** The previous resource action */ + private Action fPreviousResourceAction; + + /** A comparator class */ + private Comparator fEntryComparator = null; + + /** The redraw state used to prevent unnecessary queuing of display runnables */ + private State fRedrawState = State.IDLE; + + /** The redraw synchronization object */ + private final Object fSyncObj = new Object(); + + /** The presentation provider for this view */ + private final TimeGraphPresentationProvider fPresentation; + + /** The tree column label array, or null if combo is not used */ + private String[] fColumns; + + /** The tree label provider, or null if combo is not used */ + private TreeLabelProvider fLabelProvider = null; + + /** The relative weight of the sash, ignored if combo is not used */ + private int[] fWeight = { 1, 1 }; + + /** The filter column label array, or null if filter is not used */ + private String[] fFilterColumns; + + /** The pack done flag */ + private boolean fPackDone = false; + + /** The filter label provider, or null if filter is not used */ + private TreeLabelProvider fFilterLabelProvider; + + // ------------------------------------------------------------------------ + // Classes + // ------------------------------------------------------------------------ + + private interface ITimeGraphWrapper { + + void setTimeGraphProvider(TimeGraphPresentationProvider fPresentation); + + TimeGraphViewer getTimeGraphViewer(); + + void addSelectionListener(ITimeGraphSelectionListener iTimeGraphSelectionListener); + + ISelectionProvider getSelectionProvider(); + + void setFocus(); + + boolean isDisposed(); + + void refresh(); + + void setInput(Object input); + + Object getInput(); + + void redraw(); + + void update(); + + } + + private class TimeGraphViewerWrapper implements ITimeGraphWrapper { + private TimeGraphViewer viewer; + + private TimeGraphViewerWrapper(Composite parent, int style) { + viewer = new TimeGraphViewer(parent, style); + } + + @Override + public void setTimeGraphProvider(TimeGraphPresentationProvider timeGraphProvider) { + viewer.setTimeGraphProvider(timeGraphProvider); + } + + @Override + public TimeGraphViewer getTimeGraphViewer() { + return viewer; + } + + @Override + public void addSelectionListener(ITimeGraphSelectionListener listener) { + viewer.addSelectionListener(listener); + } + + @Override + public ISelectionProvider getSelectionProvider() { + return viewer.getSelectionProvider(); + } + + @Override + public void setFocus() { + viewer.setFocus(); + } + + @Override + public boolean isDisposed() { + return viewer.getControl().isDisposed(); + } + + @Override + public void setInput(Object input) { + viewer.setInput(input); + } + + @Override + public Object getInput() { + return viewer.getInput(); + } + + @Override + public void refresh() { + viewer.refresh(); + } + + @Override + public void redraw() { + viewer.getControl().redraw(); + } + + @Override + public void update() { + viewer.getControl().update(); + } + } + + private class TimeGraphComboWrapper implements ITimeGraphWrapper { + private TimeGraphCombo combo; + + private TimeGraphComboWrapper(Composite parent, int style) { + combo = new TimeGraphCombo(parent, style, fWeight); + } + + @Override + public void setTimeGraphProvider(TimeGraphPresentationProvider timeGraphProvider) { + combo.setTimeGraphProvider(timeGraphProvider); + } + + @Override + public TimeGraphViewer getTimeGraphViewer() { + return combo.getTimeGraphViewer(); + } + + @Override + public void addSelectionListener(ITimeGraphSelectionListener listener) { + combo.addSelectionListener(listener); + } + + @Override + public ISelectionProvider getSelectionProvider() { + return combo.getTreeViewer(); + } + + @Override + public void setFocus() { + combo.setFocus(); + } + + @Override + public boolean isDisposed() { + return combo.isDisposed(); + } + + @Override + public void setInput(Object input) { + combo.setInput(input); + } + + @Override + public Object getInput() { + return combo.getInput(); + } + + @Override + public void refresh() { + combo.refresh(); + } + + @Override + public void redraw() { + combo.redraw(); + } + + @Override + public void update() { + combo.update(); + } + + TimeGraphCombo getTimeGraphCombo() { + return combo; + } + + TreeViewer getTreeViewer() { + return combo.getTreeViewer(); + } + + IAction getShowFilterAction() { + return combo.getShowFilterAction(); + } + } + + private class TreeContentProvider implements ITreeContentProvider { + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + @Override + public ITimeGraphEntry[] getElements(Object inputElement) { + if (inputElement != null) { + try { + return ((List) inputElement).toArray(new ITimeGraphEntry[0]); + } catch (ClassCastException e) { + } + } + return new ITimeGraphEntry[0]; + } + + @Override + public Object[] getChildren(Object parentElement) { + ITimeGraphEntry entry = (ITimeGraphEntry) parentElement; + List children = entry.getChildren(); + return children.toArray(new ITimeGraphEntry[children.size()]); + } + + @Override + public Object getParent(Object element) { + ITimeGraphEntry entry = (ITimeGraphEntry) element; + return entry.getParent(); + } + + @Override + public boolean hasChildren(Object element) { + ITimeGraphEntry entry = (ITimeGraphEntry) element; + return entry.hasChildren(); + } + + } + + private class TimeGraphContentProvider implements ITimeGraphContentProvider { + + @Override + public ITimeGraphEntry[] getElements(Object inputElement) { + if (inputElement != null) { + try { + return ((List) inputElement).toArray(new ITimeGraphEntry[0]); + } catch (ClassCastException e) { + } + } + return new ITimeGraphEntry[0]; + } + + } + + /** + * Base class to provide the labels for the tree viewer. Views extending + * this class typically need to override the getColumnText method if they + * have more than one column to display + */ + protected static class TreeLabelProvider implements ITableLabelProvider, ILabelProvider { + + @Override + public void addListener(ILabelProviderListener listener) { + } + + @Override + public void dispose() { + } + + @Override + public boolean isLabelProperty(Object element, String property) { + return false; + } + + @Override + public void removeListener(ILabelProviderListener listener) { + } + + @Override + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + TimeGraphEntry entry = (TimeGraphEntry) element; + if (columnIndex == 0) { + return entry.getName(); + } + return new String(); + } + + /** + * @since 3.2 + */ + @Override + public Image getImage(Object element) { + return null; + } + + /** + * @since 3.2 + */ + @Override + public String getText(Object element) { + TimeGraphEntry entry = (TimeGraphEntry) element; + return entry.getName(); + } + + } + + private class BuildThread extends Thread { + private final ITmfTrace fBuildTrace; + private final ITmfTrace fParentTrace; + private final IProgressMonitor fMonitor; + + public BuildThread(final ITmfTrace trace, final ITmfTrace parentTrace, final String name) { + super(name + " build"); //$NON-NLS-1$ + fBuildTrace = trace; + fParentTrace = parentTrace; + fMonitor = new NullProgressMonitor(); + } + + @Override + public void run() { + buildEventList(fBuildTrace, fParentTrace, fMonitor); + synchronized (fBuildThreadMap) { + fBuildThreadMap.remove(fBuildTrace); + } + } + + public void cancel() { + fMonitor.setCanceled(true); + } + } + + private class ZoomThread extends Thread { + private final List fZoomEntryList; + private final long fZoomStartTime; + private final long fZoomEndTime; + private final long fResolution; + private final IProgressMonitor fMonitor; + + public ZoomThread(List entryList, long startTime, long endTime, String name) { + super(name + " zoom"); //$NON-NLS-1$ + fZoomEntryList = entryList; + fZoomStartTime = startTime; + fZoomEndTime = endTime; + fResolution = Math.max(1, (fZoomEndTime - fZoomStartTime) / fDisplayWidth); + fMonitor = new NullProgressMonitor(); + } + + @Override + public void run() { + if (fZoomEntryList == null) { + return; + } + for (TimeGraphEntry entry : fZoomEntryList) { + if (fMonitor.isCanceled()) { + return; + } + zoom(entry, fMonitor); + } + /* Refresh the arrows when zooming */ + List events = getLinkList(fZoomStartTime, fZoomEndTime, fResolution, fMonitor); + if (events != null) { + fTimeGraphWrapper.getTimeGraphViewer().setLinks(events); + redraw(); + } + } + + private void zoom(TimeGraphEntry entry, IProgressMonitor monitor) { + if (fZoomStartTime <= fStartTime && fZoomEndTime >= fEndTime) { + entry.setZoomedEventList(null); + } else { + List zoomedEventList = getEventList(entry, fZoomStartTime, fZoomEndTime, fResolution, monitor); + if (zoomedEventList != null) { + entry.setZoomedEventList(zoomedEventList); + } + } + redraw(); + for (ITimeGraphEntry child : entry.getChildren()) { + if (fMonitor.isCanceled()) { + return; + } + if (child instanceof TimeGraphEntry) { + zoom((TimeGraphEntry) child, monitor); + } + } + } + + public void cancel() { + fMonitor.setCanceled(true); + } + } + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructs a time graph view that contains either a time graph viewer or + * a time graph combo. + * + * By default, the view uses a time graph viewer. To use a time graph combo, + * the subclass constructor must call {@link #setTreeColumns(String[])} and + * {@link #setTreeLabelProvider(TreeLabelProvider)}. + * + * @param id + * The id of the view + * @param pres + * The presentation provider + */ + public AbstractTimeGraphView(String id, TimeGraphPresentationProvider pres) { + super(id); + fPresentation = pres; + fDisplayWidth = Display.getDefault().getBounds().width; + } + + // ------------------------------------------------------------------------ + // Getters and setters + // ------------------------------------------------------------------------ + + /** + * Getter for the time graph combo + * + * @return The time graph combo, or null if combo is not used + */ + protected TimeGraphCombo getTimeGraphCombo() { + if (fTimeGraphWrapper instanceof TimeGraphComboWrapper) { + return ((TimeGraphComboWrapper) fTimeGraphWrapper).getTimeGraphCombo(); + } + return null; + } + + /** + * Getter for the time graph viewer + * + * @return The time graph viewer + */ + protected TimeGraphViewer getTimeGraphViewer() { + return fTimeGraphWrapper.getTimeGraphViewer(); + } + + /** + * Getter for the presentation provider + * + * @return The time graph presentation provider + * @since 3.0 + */ + protected ITimeGraphPresentationProvider2 getPresentationProvider() { + return fPresentation; + } + + /** + * Sets the tree column labels. + * This should be called from the constructor. + * + * @param columns + * The array of tree column labels + */ + protected void setTreeColumns(final String[] columns) { + fColumns = columns; + } + + /** + * Sets the tree label provider. + * This should be called from the constructor. + * + * @param tlp + * The tree label provider + */ + protected void setTreeLabelProvider(final TreeLabelProvider tlp) { + fLabelProvider = tlp; + } + + /** + * Sets the relative weight of each part of the time graph combo. + * This should be called from the constructor. + * + * @param weights + * The array (length 2) of relative weights of each part of the combo + */ + protected void setWeight(final int[] weights) { + fWeight = weights; + } + + /** + * Sets the filter column labels. + * This should be called from the constructor. + * + * @param filterColumns + * The array of filter column labels + */ + protected void setFilterColumns(final String[] filterColumns) { + fFilterColumns = filterColumns; + } + + /** + * Sets the filter label provider. + * This should be called from the constructor. + * + * @param labelProvider + * The filter label provider + * + * @since 3.0 + */ + protected void setFilterLabelProvider(final TreeLabelProvider labelProvider) { + fFilterLabelProvider = labelProvider; + } + + /** + * Gets the display width + * + * @return the display width + */ + protected int getDisplayWidth() { + return fDisplayWidth; + } + + /** + * Gets the comparator for the entries + * + * @return The entry comparator + */ + protected Comparator getEntryComparator() { + return fEntryComparator; + } + + /** + * Sets the comparator class for the entries + * + * @param comparator + * A comparator object + */ + protected void setEntryComparator(final Comparator comparator) { + fEntryComparator = comparator; + } + + /** + * Gets the trace displayed in the view + * + * @return The trace + */ + protected ITmfTrace getTrace() { + return fTrace; + } + + /** + * Gets the start time + * + * @return The start time + */ + protected long getStartTime() { + return fStartTime; + } + + /** + * Sets the start time + * + * @param time + * The start time + */ + protected void setStartTime(long time) { + fStartTime = time; + } + + /** + * Gets the end time + * + * @return The end time + */ + protected long getEndTime() { + return fEndTime; + } + + /** + * Sets the end time + * + * @param time + * The end time + */ + protected void setEndTime(long time) { + fEndTime = time; + } + + /** + * Gets the entry list for a trace + * + * @param trace + * the trace + * + * @return the entry list map + * @since 3.0 + */ + protected List getEntryList(ITmfTrace trace) { + synchronized (fEntryListMap) { + return fEntryListMap.get(trace); + } + } + + /** + * Adds a trace entry list to the entry list map + * + * @param trace + * the trace to add + * @param list + * the list of time graph entries + */ + protected void putEntryList(ITmfTrace trace, List list) { + synchronized (fEntryListMap) { + fEntryListMap.put(trace, new CopyOnWriteArrayList<>(list)); + } + } + + /** + * Adds a list of entries to a trace's entry list + * + * @param trace + * the trace + * @param list + * the list of time graph entries to add + * @since 3.0 + */ + protected void addToEntryList(ITmfTrace trace, List list) { + synchronized (fEntryListMap) { + List entryList = fEntryListMap.get(trace); + if (entryList == null) { + fEntryListMap.put(trace, new CopyOnWriteArrayList<>(list)); + } else { + entryList.addAll(list); + } + } + } + + /** + * Removes a list of entries from a trace's entry list + * + * @param trace + * the trace + * @param list + * the list of time graph entries to remove + * @since 3.0 + */ + protected void removeFromEntryList(ITmfTrace trace, List list) { + synchronized (fEntryListMap) { + List entryList = fEntryListMap.get(trace); + if (entryList != null) { + entryList.removeAll(list); + } + } + } + + /** + * Text for the "next" button + * + * @return The "next" button text + */ + protected String getNextText() { + return Messages.AbstractTimeGraphtView_NextText; + } + + /** + * Tooltip for the "next" button + * + * @return Tooltip for the "next" button + */ + protected String getNextTooltip() { + return Messages.AbstractTimeGraphView_NextTooltip; + } + + /** + * Text for the "Previous" button + * + * @return The "Previous" button text + */ + protected String getPrevText() { + return Messages.AbstractTimeGraphView_PreviousText; + } + + /** + * Tooltip for the "previous" button + * + * @return Tooltip for the "previous" button + */ + protected String getPrevTooltip() { + return Messages.AbstractTimeGraphView_PreviousTooltip; + } + + // ------------------------------------------------------------------------ + // ViewPart + // ------------------------------------------------------------------------ + + @Override + public void createPartControl(Composite parent) { + if (fColumns == null || fLabelProvider == null) { + fTimeGraphWrapper = new TimeGraphViewerWrapper(parent, SWT.NONE); + TimeGraphViewer viewer = fTimeGraphWrapper.getTimeGraphViewer(); + viewer.setTimeGraphContentProvider(new TimeGraphContentProvider()); + } else { + TimeGraphComboWrapper wrapper = new TimeGraphComboWrapper(parent, SWT.NONE); + fTimeGraphWrapper = wrapper; + TimeGraphCombo combo = wrapper.getTimeGraphCombo(); + combo.setTreeContentProvider(new TreeContentProvider()); + combo.setTreeLabelProvider(fLabelProvider); + combo.setTreeColumns(fColumns); + combo.setFilterContentProvider(new TreeContentProvider()); + combo.setFilterLabelProvider(fFilterLabelProvider); + combo.setFilterColumns(fFilterColumns); + combo.setTimeGraphContentProvider(new TimeGraphContentProvider()); + } + + fTimeGraphWrapper.setTimeGraphProvider(fPresentation); + + fTimeGraphWrapper.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() { + @Override + public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) { + final long startTime = event.getStartTime(); + final long endTime = event.getEndTime(); + TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime)); + broadcast(new TmfRangeSynchSignal(AbstractTimeGraphView.this, range)); + if (fZoomThread != null) { + fZoomThread.cancel(); + } + startZoomThread(startTime, endTime); + } + }); + + fTimeGraphWrapper.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() { + @Override + public void timeSelected(TimeGraphTimeEvent event) { + TmfNanoTimestamp startTime = new TmfNanoTimestamp(event.getBeginTime()); + TmfNanoTimestamp endTime = new TmfNanoTimestamp(event.getEndTime()); + broadcast(new TmfTimeSynchSignal(AbstractTimeGraphView.this, startTime, endTime)); + } + }); + + fTimeGraphWrapper.getTimeGraphViewer().setTimeFormat(TimeFormat.CALENDAR); + + IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager(); + fTimeGraphWrapper.getTimeGraphViewer().getTimeGraphControl().setStatusLineManager(statusLineManager); + + // View Action Handling + makeActions(); + contributeToActionBars(); + + ITmfTrace trace = getActiveTrace(); + if (trace != null) { + traceSelected(new TmfTraceSelectedSignal(this, trace)); + } + + // make selection available to other views + getSite().setSelectionProvider(fTimeGraphWrapper.getSelectionProvider()); + } + + @Override + public void setFocus() { + fTimeGraphWrapper.setFocus(); + } + + // ------------------------------------------------------------------------ + // Signal handlers + // ------------------------------------------------------------------------ + + /** + * Handler for the trace opened signal. + * + * @param signal + * The incoming signal + * @since 2.0 + */ + @TmfSignalHandler + public void traceOpened(TmfTraceOpenedSignal signal) { + fTrace = signal.getTrace(); + loadTrace(); + } + + /** + * Handler for the trace selected signal + * + * @param signal + * The incoming signal + */ + @TmfSignalHandler + public void traceSelected(final TmfTraceSelectedSignal signal) { + if (signal.getTrace() == fTrace) { + return; + } + fTrace = signal.getTrace(); + + loadTrace(); + } + + /** + * Trace is closed: clear the data structures and the view + * + * @param signal + * the signal received + */ + @TmfSignalHandler + public void traceClosed(final TmfTraceClosedSignal signal) { + synchronized (fBuildThreadMap) { + for (ITmfTrace trace : getTracesToBuild(signal.getTrace())) { + BuildThread buildThread = fBuildThreadMap.remove(trace); + if (buildThread != null) { + buildThread.cancel(); + } + } + } + synchronized (fEntryListMap) { + fEntryListMap.remove(signal.getTrace()); + } + if (signal.getTrace() == fTrace) { + fTrace = null; + fStartTime = 0; + fEndTime = 0; + if (fZoomThread != null) { + fZoomThread.cancel(); + } + refresh(); + } + } + + /** + * Handler for the time synch signal + * + * @param signal + * The signal that's received + */ + @TmfSignalHandler + public void synchToTime(final TmfTimeSynchSignal signal) { + if (signal.getSource() == this || fTrace == null) { + return; + } + final long beginTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + final long endTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (fTimeGraphWrapper.isDisposed()) { + return; + } + if (beginTime == endTime) { + fTimeGraphWrapper.getTimeGraphViewer().setSelectedTime(beginTime, true); + } else { + fTimeGraphWrapper.getTimeGraphViewer().setSelectionRange(beginTime, endTime); + } + startZoomThread(fTimeGraphWrapper.getTimeGraphViewer().getTime0(), fTimeGraphWrapper.getTimeGraphViewer().getTime1()); + + synchingToTime(beginTime); + } + }); + } + + /** + * Handler for the range synch signal + * + * @param signal + * The signal that's received + */ + @TmfSignalHandler + public void synchToRange(final TmfRangeSynchSignal signal) { + if (signal.getSource() == this || fTrace == null) { + return; + } + if (signal.getCurrentRange().getIntersection(fTrace.getTimeRange()) == null) { + return; + } + final long startTime = signal.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + final long endTime = signal.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (fTimeGraphWrapper.isDisposed()) { + return; + } + fTimeGraphWrapper.getTimeGraphViewer().setStartFinishTime(startTime, endTime); + startZoomThread(startTime, endTime); + } + }); + } + + /** + * @param signal the format of the timestamps was updated. + * @since 2.1 + */ + @TmfSignalHandler + public void updateTimeFormat( final TmfTimestampFormatUpdateSignal signal){ + fTimeGraphWrapper.refresh(); + } + + // ------------------------------------------------------------------------ + // Internal + // ------------------------------------------------------------------------ + + private void loadTrace() { + synchronized (fEntryListMap) { + fEntryList = fEntryListMap.get(fTrace); + if (fEntryList == null) { + rebuild(); + } else { + fStartTime = fTrace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + fEndTime = fTrace.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + refresh(); + } + } + } + + /** + * Forces a rebuild of the entries list, even if entries already exist for this trace + * @since 3.0 + */ + protected void rebuild() { + setStartTime(Long.MAX_VALUE); + setEndTime(Long.MIN_VALUE); + synchronized (fBuildThreadMap) { + for (ITmfTrace trace : getTracesToBuild(fTrace)) { + BuildThread buildThread = new BuildThread(trace, fTrace, getName()); + fBuildThreadMap.put(trace, buildThread); + buildThread.start(); + } + } + } + + /** + * Method called when synching to a given timestamp. Inheriting classes can + * perform actions here to update the view at the given timestamp. + * + * @param time + * The currently selected time + */ + protected void synchingToTime(long time) { + + } + + /** + * Return the list of traces whose data or analysis results will be used to + * populate the view. By default, if the trace is an experiment, the traces + * under it will be returned, otherwise, the trace itself is returned. + * + * A build thread will be started for each trace returned by this method, + * some of which may receive events in live streaming mode. + * + * @param trace + * The trace associated with this view + * @return List of traces with data to display + * @since 3.0 + */ + protected Iterable getTracesToBuild(ITmfTrace trace) { + return Arrays.asList(TmfTraceManager.getTraceSet(trace)); + } + + /** + * Build the entries list to show in this time graph + * + * Called from the BuildThread + * + * @param trace + * The trace being built + * @param parentTrace + * The parent of the trace set, or the trace itself + * @param monitor + * The progress monitor object + * @since 3.0 + */ + protected abstract void buildEventList(ITmfTrace trace, ITmfTrace parentTrace, IProgressMonitor monitor); + + /** + * Gets the list of event for an entry in a given timerange + * + * @param entry + * The entry to get events for + * @param startTime + * Start of the time range + * @param endTime + * End of the time range + * @param resolution + * The resolution + * @param monitor + * The progress monitor object + * @return The list of events for the entry + */ + protected abstract @Nullable List getEventList(TimeGraphEntry entry, + long startTime, long endTime, long resolution, + IProgressMonitor monitor); + + /** + * Gets the list of links (displayed as arrows) for a trace in a given + * timerange. Default implementation returns an empty list. + * + * @param startTime + * Start of the time range + * @param endTime + * End of the time range + * @param resolution + * The resolution + * @param monitor + * The progress monitor object + * @return The list of link events + * @since 2.1 + */ + protected List getLinkList(long startTime, long endTime, + long resolution, IProgressMonitor monitor) { + return new ArrayList<>(); + } + + + /** + * Refresh the display + */ + protected void refresh() { + TmfUiRefreshHandler.getInstance().queueUpdate(this, new Runnable() { + @Override + public void run() { + if (fTimeGraphWrapper.isDisposed()) { + return; + } + boolean hasEntries = false; + synchronized (fEntryListMap) { + fEntryList = fEntryListMap.get(fTrace); + if (fEntryList == null) { + fEntryList = new CopyOnWriteArrayList<>(); + } else if (fEntryComparator != null) { + List list = new ArrayList<>(fEntryList); + Collections.sort(list, fEntryComparator); + fEntryList.clear(); + fEntryList.addAll(list); + } + hasEntries = fEntryList.size() != 0; + } + if (fEntryList != fTimeGraphWrapper.getInput()) { + fTimeGraphWrapper.setInput(fEntryList); + } else { + fTimeGraphWrapper.refresh(); + } + fTimeGraphWrapper.getTimeGraphViewer().setTimeBounds(fStartTime, fEndTime); + + long selectionBeginTime = fTrace == null ? 0 : fTraceManager.getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long selectionEndTime = fTrace == null ? 0 : fTraceManager.getSelectionEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long startTime = fTrace == null ? 0 : fTraceManager.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long endTime = fTrace == null ? 0 : fTraceManager.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + startTime = Math.max(startTime, fStartTime); + endTime = Math.min(endTime, fEndTime); + fTimeGraphWrapper.getTimeGraphViewer().setSelectionRange(selectionBeginTime, selectionEndTime); + fTimeGraphWrapper.getTimeGraphViewer().setStartFinishTime(startTime, endTime); + + if (fTimeGraphWrapper instanceof TimeGraphComboWrapper && !fPackDone) { + for (TreeColumn column : ((TimeGraphComboWrapper) fTimeGraphWrapper).getTreeViewer().getTree().getColumns()) { + column.pack(); + } + if (hasEntries) { + fPackDone = true; + } + } + + startZoomThread(startTime, endTime); + } + }); + } + + /** + * Redraw the canvas + */ + protected void redraw() { + synchronized (fSyncObj) { + if (fRedrawState == State.IDLE) { + fRedrawState = State.BUSY; + } else { + fRedrawState = State.PENDING; + return; + } + } + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (fTimeGraphWrapper.isDisposed()) { + return; + } + fTimeGraphWrapper.redraw(); + fTimeGraphWrapper.update(); + synchronized (fSyncObj) { + if (fRedrawState == State.PENDING) { + fRedrawState = State.IDLE; + redraw(); + } else { + fRedrawState = State.IDLE; + } + } + } + }); + } + + private void startZoomThread(long startTime, long endTime) { + if (fZoomThread != null) { + fZoomThread.cancel(); + } + fZoomThread = new ZoomThread(fEntryList, startTime, endTime, getName()); + fZoomThread.start(); + } + + private void makeActions() { + fPreviousResourceAction = fTimeGraphWrapper.getTimeGraphViewer().getPreviousItemAction(); + fPreviousResourceAction.setText(getPrevText()); + fPreviousResourceAction.setToolTipText(getPrevTooltip()); + fNextResourceAction = fTimeGraphWrapper.getTimeGraphViewer().getNextItemAction(); + fNextResourceAction.setText(getNextText()); + fNextResourceAction.setToolTipText(getNextTooltip()); + } + + private void contributeToActionBars() { + IActionBars bars = getViewSite().getActionBars(); + fillLocalToolBar(bars.getToolBarManager()); + } + + /** + * Add actions to local tool bar manager + * + * @param manager the tool bar manager + */ + protected void fillLocalToolBar(IToolBarManager manager) { + if (fTimeGraphWrapper instanceof TimeGraphComboWrapper) { + if (fFilterColumns != null && fFilterLabelProvider != null && fFilterColumns.length > 0) { + manager.add(((TimeGraphComboWrapper) fTimeGraphWrapper).getShowFilterAction()); + } + } + manager.add(fTimeGraphWrapper.getTimeGraphViewer().getShowLegendAction()); + manager.add(new Separator()); + manager.add(fTimeGraphWrapper.getTimeGraphViewer().getResetScaleAction()); + manager.add(fTimeGraphWrapper.getTimeGraphViewer().getPreviousEventAction()); + manager.add(fTimeGraphWrapper.getTimeGraphViewer().getNextEventAction()); + manager.add(fPreviousResourceAction); + manager.add(fNextResourceAction); + manager.add(fTimeGraphWrapper.getTimeGraphViewer().getZoomInAction()); + manager.add(fTimeGraphWrapper.getTimeGraphViewer().getZoomOutAction()); + manager.add(new Separator()); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/Messages.java new file mode 100644 index 0000000000..b301d7048f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/Messages.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.timegraph; + +import org.eclipse.osgi.util.NLS; + +/** + * Generic messages for the bar charts + * + * @since 2.1 + */ +@SuppressWarnings("javadoc") +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.ui.views.timegraph.messages"; //$NON-NLS-1$ + + public static String AbstractTimeGraphtView_NextText; + public static String AbstractTimeGraphView_NextTooltip; + public static String AbstractTimeGraphView_PreviousText; + public static String AbstractTimeGraphView_PreviousTooltip; + public static String TimeGraphPresentationProvider_multipleStates; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/messages.properties new file mode 100644 index 0000000000..52adaa617b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/messages.properties @@ -0,0 +1,16 @@ +############################################################################### +# Copyright (c) 2014 Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ericsson - Initial API and implementation +############################################################################### +AbstractTimeGraphtView_NextText=Next +AbstractTimeGraphView_NextTooltip=Next element +AbstractTimeGraphView_PreviousText=Previous +AbstractTimeGraphView_PreviousTooltip=Previous element +TimeGraphPresentationProvider_multipleStates=multiple states diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/DiagramToolTip.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/DiagramToolTip.java new file mode 100755 index 0000000000..1301222e9f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/DiagramToolTip.java @@ -0,0 +1,131 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + *

    + * This class is used to reproduce the same tooltip behavior on Windows and Linux when the mouse hovers over the + * sequence diagram + *

    + * + * @version 1.0 + * @author sveyrier + */ +public class DiagramToolTip { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + private static final int CHARACTERS_PER_COLUMN = 100; + private static final int DEFAULT_CURSOR_HEIGHT = 32; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The parent control where the tooltip must be drawn. + */ + private Control fParent = null; + /** + * The tooltip shell. + */ + private Shell fToolTipShell = null; + /** + * The text box. + */ + private Text fTextBox = null; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Create a new tooltip for the given parent control + * + * @param parent the parent control. + */ + public DiagramToolTip(Control parent) { + fParent = parent; + fToolTipShell = new Shell(fParent.getShell(), SWT.MULTI); + fToolTipShell.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + fTextBox = new Text(fToolTipShell, SWT.WRAP | SWT.MULTI); + fTextBox.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + /** + * Display the tooltip using the given text The tooltip will stay on screen until it is told otherwise + * + * @param value the text to display + */ + public void showToolTip(String value) { + if ((value == null) || (value.equalsIgnoreCase(""))) { //$NON-NLS-1$ + fToolTipShell.setVisible(false); + return; + } + + int w = fToolTipShell.getBounds().width; + Point hr = Display.getDefault().getCursorLocation(); + int cursorH = DEFAULT_CURSOR_HEIGHT; + for (int i = 0; i < Display.getDefault().getCursorSizes().length; i++) { + if (Display.getDefault().getCursorSizes()[i].y < cursorH) { + cursorH = Display.getDefault().getCursorSizes()[i].y; + } + } + if (hr.x + w > Display.getDefault().getBounds().width) { + int tempX = (hr.x + w) - Display.getDefault().getBounds().width; + if (tempX > Display.getDefault().getBounds().width) { + hr.x = 0; + } + hr.x = hr.x - tempX; + } + fTextBox.setText(value); + GC gc = new GC(fTextBox); + FontMetrics fm = gc.getFontMetrics(); + gc.dispose(); + int width = CHARACTERS_PER_COLUMN * fm.getAverageCharWidth(); + fTextBox.setSize(fTextBox.computeSize(width, fTextBox.getLineCount() * fTextBox.getLineHeight())); + fToolTipShell.setLocation(hr.x, hr.y + cursorH); + fToolTipShell.setSize(fTextBox.getSize()); + fTextBox.setVisible(true); + fToolTipShell.setVisible(true); + } + + /** + * Hide the tooltip + */ + public void hideToolTip() { + fToolTipShell.setVisible(false); + } + + /** + * @return parent control + * @since 2.0 + */ + protected Control getParent() { + return fParent; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/DrawableToolTip.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/DrawableToolTip.java new file mode 100755 index 0000000000..d06eb52d69 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/DrawableToolTip.java @@ -0,0 +1,305 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; + +/** + *

    + * This class is used to reproduce the same tooltip behavior on Windows and Linux when the mouse move hover the time + * compression bar used to display elapsed time using a tooltip. The tooltip is composed of 2 parts, the text value and + * below, a scale to visually locate the value in a time range (usually the minimum an maximum elapsed time in the whole + * diagram) + *

    + * + * @version 1.0 + * @author sveyrier + */ +public class DrawableToolTip implements PaintListener { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + private static final int HORIZONTAL_MARGIN = 10; + private static final int VERTICAL_MARGIN = 10; + private static final int TEXT_SCALE_MARGIN = 20; + private static final int SCALE_LENGTH = 100; + private static final int SHELL_WIDTH = 200; + private static final int SHELL_HEIGHT = 50; + private static final int NUMBER_STEPS = 10; + private static final int BASE_RED_VALUE = 255; + private static final int BASE_GREEN_BLUE_VALUE = 225; + private static final int COLOR_STEP = 25; + private static final int BOUNDS_Y_OFFSET = 26; + private static final int RECTANGLE_HEIGHT = 11; + private static final int DEFAULT_LINE_WIDTH = 10; + private static final int BORDER_LINE_WIDTH = 14; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The tooltip shell + */ + private Shell fToolTipShell = null; + /** + * The Time range data. + */ + private TmfTimeRange fMinMaxRange; + /** + * The current time. + */ + private ITmfTimestamp fCurrentValue; + /** + * The horizontal margin used for drawing. + */ + private static int fHorMargin = HORIZONTAL_MARGIN; + /** + * The vertical margin used for drawing. + */ + private static int fVertMargin = VERTICAL_MARGIN; + /** + * The minimum text scale margin. + */ + private static int fTextScaleMargin = TEXT_SCALE_MARGIN; + /** + * The length of the text scale. + */ + private static int fScaleLength = SCALE_LENGTH; + /** + * The text to display + */ + private String fMessage; + /** + * The color array used to represent the 10 time range slices + */ + private Color[] fColors; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Creates a drawable tool tip instance. + * + * @param parent The parent composite. + */ + public DrawableToolTip(Composite parent) { + fToolTipShell = new Shell(parent.getShell(), SWT.ON_TOP); + fToolTipShell.setLayout(new RowLayout()); + fToolTipShell.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + fToolTipShell.addPaintListener(this); + fToolTipShell.setSize(SHELL_WIDTH, SHELL_HEIGHT); + + fColors = new Color[NUMBER_STEPS]; + int greenBlue = BASE_GREEN_BLUE_VALUE; + final int step = COLOR_STEP; + for (int i = 0; i < fColors.length; i++) { + fColors[i] = new Color(Display.getDefault(), BASE_RED_VALUE, greenBlue, greenBlue); + greenBlue -= step; + } + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + /** + * Returns the message to display. + * + * @return the message to display. + */ + public String getText() { + return fMessage; + } + + /** + * Returns teh current time to display. + * + * @return the current time to display + */ + public String getAccessibleText() { + return fCurrentValue.toString(); + } + + /** + * Returns the horizontal margin. + * + * @return the horizontal margin. + */ + protected static int getHorizontalMargin() { + return fHorMargin; + } + + /** + * Sets the horizontal margin. + * + * @param margin The margin to set. + */ + protected static void setHorizontalMargin(int margin) { + fHorMargin = margin; + } + + /** + * Returns the vertical margin. + * + * @return the vertical margin. + */ + protected static int getVerticalMargin() { + return fVertMargin; + } + + /** + * Sets the vertical margin. + * + * @param margin The margin to set. + */ + protected static void setVerticalMargin(int margin) { + fVertMargin = margin; + } + + /** + * Returns the text scale margin. + * + * @return the text scale margin. + */ + protected static int getTextScaleMargin() { + return fTextScaleMargin; + } + + /** + * Sets the text scale margin. + * @param textScaleMargin The margin to set. + */ + protected static void setTestScaleMargin(int textScaleMargin) { + fTextScaleMargin = textScaleMargin; + } + + /** + * Returns the scale length. + * + * @return the scale length. + */ + protected static int getScaleLength() { + return fScaleLength; + } + + /** + * Sets the scale length. + * + * @param scaleLength The scale length to set. + */ + protected static void setScaleLength(int scaleLength) { + fScaleLength = scaleLength; + } + + /** + * Display the tooltip using the given time range(min,max) the current value and the time unit The tooltip will stay + * on screen until it is told otherwise + * + * @param value the current in the scale + * @param min the scale min + * @param max the scale max + * @since 2.0 + */ + public void showToolTip(ITmfTimestamp value, ITmfTimestamp min, ITmfTimestamp max) { + fMinMaxRange = new TmfTimeRange(min, max); + fCurrentValue = value; + + int w = fToolTipShell.getBounds().width; + int h = fToolTipShell.getBounds().height; + Point hr = Display.getDefault().getCursorLocation(); + fToolTipShell.setBounds(hr.x, hr.y + BOUNDS_Y_OFFSET, w, h); + fToolTipShell.setVisible(true); + } + + /** + * Hide the tooltip. + */ + public void hideToolTip() { + fToolTipShell.setVisible(false); + } + + /** + * Disposes the system resource used by this kind of toolTips (a colors array essentially) + */ + public void dispose() { + for (int i = 0; i < fColors.length; i++) { + fColors[i].dispose(); + } + } + + @Override + public void paintControl(PaintEvent event) { + fMessage = Messages.SequenceDiagram_Delta + " " + fCurrentValue.toString(); //$NON-NLS-1$ + Point size = event.gc.textExtent(fMessage); + if (size.x < fScaleLength) { + size.x = fScaleLength; + } + event.gc.drawText(fMessage, fHorMargin, fVertMargin, true); + event.gc.drawLine(fHorMargin, fVertMargin + fTextScaleMargin + size.y, fHorMargin + fScaleLength, fVertMargin + fTextScaleMargin + size.y); + + int step = fScaleLength / NUMBER_STEPS; + + ITmfTimestamp minMaxdelta = fMinMaxRange.getEndTime().getDelta(fMinMaxRange.getStartTime()); + double gr = (minMaxdelta.getValue()) / (double) NUMBER_STEPS; + + ITmfTimestamp delta = fCurrentValue.getDelta(fMinMaxRange.getStartTime()); + long absDelta = Math.abs(delta.getValue()); + + int colIndex = 0; + if (gr != 0) { + colIndex = Math.round((float) (absDelta / gr)); + if (colIndex > fColors.length) { + colIndex = fColors.length; + } else if (colIndex <= 1) { + colIndex = 1; + } + } else { + colIndex = 1; + } + + for (int i = 0; i <= NUMBER_STEPS; i++) { + if (i < NUMBER_STEPS) { + event.gc.setBackground(fColors[i]); + } + if ((i < colIndex) && (i < NUMBER_STEPS)) { + event.gc.fillRectangle(fHorMargin + i * step, fVertMargin + fTextScaleMargin + size.y - 5, step, RECTANGLE_HEIGHT); + } + if (i == 0) { + event.gc.drawText(Messages.SequenceDiagram_Min, fHorMargin, size.y + 2 * fVertMargin + fTextScaleMargin, true); + } + if (i == 0) { + int len = event.gc.textExtent(Messages.SequenceDiagram_Max).x; + event.gc.drawText(Messages.SequenceDiagram_Max, fHorMargin + fScaleLength - len + 1, size.y + 2 * fVertMargin + fTextScaleMargin, true); + } + int lineWidth = DEFAULT_LINE_WIDTH; + if ((i == 0) || (i == NUMBER_STEPS)) { + lineWidth = BORDER_LINE_WIDTH; + } + event.gc.drawLine(fHorMargin + i * step, fVertMargin + fTextScaleMargin + size.y - lineWidth / 2, fHorMargin + i * step, fVertMargin + fTextScaleMargin + size.y + lineWidth / 2); + } + fToolTipShell.setSize(size.x + 2 * fHorMargin + 2, 2 * size.y + 3 * fVertMargin + fTextScaleMargin); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/ITimeCompressionListener.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/ITimeCompressionListener.java new file mode 100755 index 0000000000..e6506c8bdb --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/ITimeCompressionListener.java @@ -0,0 +1,42 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Lifeline; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IColor; + +/** + *

    + * Listener interface for the time compression bar to notify about dela selection. + *

    + * + * @author sveyrier + * @version 1.0 + */ +public interface ITimeCompressionListener { + + /** + * Notifies listeners about a selected delta. + * + * @param lifeline + * The current lifeline. + * @param startEvent + * The start event selected. + * @param nbEvent + * A number of events. + * @param color + * The current color to use. + */ + void deltaSelected(Lifeline lifeline, int startEvent, int nbEvent, IColor color); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/NGC.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/NGC.java new file mode 100755 index 0000000000..a686868929 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/NGC.java @@ -0,0 +1,988 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IColor; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IFont; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IImage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.impl.ColorImpl; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref; + +/** + *

    + * This class implements the graphical context for the sequence diagram widgets. + *

    + * + * @version 1.0 + * @author sveyrier + */ +public class NGC implements IGC { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The graphical context. + */ + private GC fContext; + /** + * The reference to the sequence diagram view. + */ + private SDWidget fView; + /** + * A reference to the last used font. + */ + private Font fTempFont = null; + /** + * The color of the gradient. + */ + private IColor fGradientColor = null; + /** + * The color of the background. + */ + private IColor fBackground = null; + /** + * The color of the foreground. + */ + private IColor fForeground = null; + /** + * The current visible y screen bounds + */ + private int fVisibleY; + /** + * The current visible x screen bound. + */ + private int fVisibleX; + /** + * The current yx value (view visible height - visible screen bounds) + */ + private int yx; + /** + * The current xx value (view visible width - visible screen bounds) + */ + private int xx; + /** + * true to draw with focus else false. + */ + private boolean fDrawWithFocus = false; + + /** + * The static visible screen bounds. + */ + private static int fVisibleScreenBounds = 0; + + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor. + * + * @param scrollView A sequence diagram view reference. + * @param gc A graphical context. + */ + public NGC(SDWidget scrollView, GC gc) { + fContext = gc; + fView = scrollView; + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public void setLineStyle(int style) { + fContext.setLineStyle(style); + } + + @Override + public int getLineStyle() { + return fContext.getLineStyle(); + } + + @Override + public int getContentsX() { + return Math.round(fView.getContentsX() / fView.getZoomValue()); + } + + @Override + public int getContentsY() { + return Math.round(fView.getContentsY() / fView.getZoomValue()); + } + + @Override + public int getVisibleWidth() { + return Math.round(fView.getVisibleWidth() / fView.getZoomValue()); + } + + @Override + public int getVisibleHeight() { + return Math.round(fView.getVisibleHeight() / fView.getZoomValue()); + } + + /** + * Returns the current visible y screen bounds. + * + * @return the current visible y screen bounds + * @since 2.0 + */ + protected int getVisibleY() { + return fVisibleY; + } + + /** + * Sets the current visible y screen bounds. + * + * @param visibleY + * the current visible y screen bounds + * @since 2.0 + */ + protected void setVisibleY(int visibleY) { + fVisibleY = visibleY; + } + + /** + * Returns the current visible x screen bound. + * + * @return the current visible x screen bound. + * @since 2.0 + * + */ + protected int getfVisibleX() { + return fVisibleX; + } + + /** + * Sets the current visible x screen bound. + * + * @param visibleX + * the current visible x screen bound. + * @since 2.0 + * + */ + protected void setVisibleX(int visibleX) { + fVisibleX = visibleX; + } + + /** + * Returns current yx value (view visible height - visible screen bounds). + * + * @return current yx value + * @since 2.0 + */ + protected int getYx() { + return yx; + } + + /** + * Sets current yx value (view visible height - visible screen bounds). + * + * @param yx + * current yx value + * @since 2.0 + */ + protected void setYx(int yx) { + this.yx = yx; + } + + /** + * Returns the current xx value (view visible width - visible screen bounds) + * + * @return the current xx value + * @since 2.0 + */ + protected int getXx() { + return xx; + } + + /** + * Sets the current xx value (view visible width - visible screen bounds) + * + * @param xx + * the current xx value + * @since 2.0 + */ + protected void setXx(int xx) { + this.xx = xx; + } + + @Override + public int contentsToViewX(int x) { + return fView.contentsToViewX(x); + } + + @Override + public int contentsToViewY(int y) { + return fView.contentsToViewY(y); + } + + /** + * Get code for drawings at given x and y position. + * + * @param x The x position + * @param y The y position. + * @return A code for top, bottom, right and left + */ + protected byte code(int x, int y) { + byte c = 0; + fVisibleY = fVisibleScreenBounds; + fVisibleX = fVisibleScreenBounds; + yx = fView.getVisibleHeight() + fVisibleScreenBounds; + xx = fView.getVisibleWidth() + fVisibleScreenBounds; + if (y > yx) { + c |= 0x01; // top + } else if (y < fVisibleY) { + c |= 0x02; // bottom + } + + if (x > xx) { + c |= 0x04; // right + } else if (x < fVisibleX) { + c |= 0x08; // left + } + return c; + } + + @Override + public void drawLine(int x1, int y1, int x2, int y2) { + int localX1 = x1; + int localY1 = y1; + int localX2 = x2; + int localY2 = y2; + + localX1 = Math.round(localX1 * fView.getZoomValue()); + localY1 = Math.round(localY1 * fView.getZoomValue()); + localX2 = Math.round(localX2 * fView.getZoomValue()); + localY2 = Math.round(localY2 * fView.getZoomValue()); + localX1 = fView.contentsToViewX(localX1); + localY1 = fView.contentsToViewY(localY1); + localX2 = fView.contentsToViewX(localX2); + localY2 = fView.contentsToViewY(localY2); + + byte code1 = code(localX1, localY1); + byte code2 = code(localX2, localY2); + byte codex; + boolean draw = false; + boolean end = false; + int x = 0, y = 0; + + do { + if (code1 == 0 && code2 == 0) { + draw = true; + end = true; + } else if ((code1 & code2) != 0) { + end = true; + } else { + codex = (code1 != 0) ? code1 : code2; + if ((codex & 0x01) != 0) { // top + x = localX1 + ((localX2 - localX1) * (yx - localY1)) / (localY2 - localY1); + y = yx; + } else if ((codex & 0x02) != 0) { // bottom + x = localX1 + ((localX2 - localX1) * (fVisibleY - localY1)) / (localY2 - localY1); + y = fVisibleY; + } else if ((codex & 0x04) != 0) { // right + y = localY1 + ((localY2 - localY1) * (xx - localX1)) / (localX2 - localX1); + x = xx; + } else if ((codex & 0x08) != 0) { // left + y = localY1 + ((localY2 - localY1) * (fVisibleX - localX1)) / (localX2 - localX1); + x = fVisibleX; + } + + if (codex == code1) { + localX1 = x; + localY1 = y; + code1 = code(localX1, localY1); + } else { + localX2 = x; + localY2 = y; + code2 = code(localX2, localY2); + } + } + } while (!end); + + if (draw) { + fContext.drawLine(localX1, localY1, localX2, localY2); + } + } + + @Override + public void drawRectangle(int x, int y, int width, int height) { + int localX = x; + int localY = y; + int localWidth = width; + int localHeight = height; + + localX = Math.round(localX * fView.getZoomValue()); + // Workaround to avoid problems for some special cases (not very nice) + if (localY != getContentsY()) { + localY = Math.round(localY * fView.getZoomValue()); + localY = fView.contentsToViewY(localY); + } else { + localY = 0; + } + localWidth = Math.round(localWidth * fView.getZoomValue()); + localHeight = Math.round(localHeight * fView.getZoomValue()); + localX = fView.contentsToViewX(localX); + + if (localX < -fVisibleScreenBounds) { + localWidth = localWidth + localX + fVisibleScreenBounds; + localX = -fVisibleScreenBounds; + } + if (localY < -fVisibleScreenBounds) { + localHeight = localHeight + localY + fVisibleScreenBounds; + localY = -fVisibleScreenBounds; + } + if ((localWidth < -fVisibleScreenBounds) && (localX + localWidth < -fVisibleScreenBounds)) { + localWidth = -fVisibleScreenBounds; + } else if (localWidth + localX > fView.getVisibleWidth() + fVisibleScreenBounds) { + localWidth = fView.getVisibleWidth() + fVisibleScreenBounds - localX; + } + if ((localHeight < -fVisibleScreenBounds) && (localY + localHeight < -fVisibleScreenBounds)) { + localHeight = -fVisibleScreenBounds; + } else if (localHeight + localY > fView.getVisibleHeight() + fVisibleScreenBounds) { + localHeight = fView.getVisibleHeight() + fVisibleScreenBounds - localY; + } + fContext.drawRectangle(localX, localY, localWidth, localHeight); + } + + @Override + public void drawFocus(int x, int y, int width, int height) { + int localX = x; + int localY = y; + int localWidth = width; + int localHeight = height; + + IColor bC = getBackground(); + IColor fC = getForeground(); + + if (localWidth < 0) { + localX = localX + localWidth; + localWidth = -localWidth; + } + + if (localHeight < 0) { + localY = localY + localHeight; + localHeight = -localHeight; + } + + localX = Math.round(localX * fView.getZoomValue()); + localY = Math.round(localY * fView.getZoomValue()); + localWidth = Math.round(localWidth * fView.getZoomValue()); + localHeight = Math.round(localHeight * fView.getZoomValue()); + + setForeground(SDViewPref.getInstance().getForeGroundColorSelection()); + setBackground(SDViewPref.getInstance().getBackGroundColorSelection()); + + fContext.drawFocus(fView.contentsToViewX(localX - 1), fView.contentsToViewY(localY - 1), localWidth + 3, localHeight + 3); + + setBackground(bC); + setForeground(fC); + } + + @Override + public void fillPolygon(int[] points) { + int len = (points.length / 2) * 2; + int[] localPoint = new int[len]; + for (int i = 0; i < len; i++) { + localPoint[i] = fView.contentsToViewX(Math.round(points[i] * fView.getZoomValue())); + i++; + localPoint[i] = fView.contentsToViewY(Math.round(points[i] * fView.getZoomValue())); + } + + if (validatePolygonHeight(localPoint) <= 0) { + return; + } + + fContext.fillPolygon(localPoint); + } + + @Override + public void drawPolygon(int[] points) { + int len = (points.length / 2) * 2; + int[] localPoint = new int[len]; + for (int i = 0; i < len; i++) { + localPoint[i] = fView.contentsToViewX(Math.round(points[i] * fView.getZoomValue())); + i++; + localPoint[i] = fView.contentsToViewY(Math.round(points[i] * fView.getZoomValue())); + } + + if (validatePolygonHeight(localPoint) <= 0) { + return; + } + + fContext.drawPolygon(localPoint); + } + + @Override + public void fillRectangle(int x, int y, int width, int height) { + int localX = x; + int localY = y; + int localWidth = width; + int localHeight = height; + + localX = Math.round(localX * fView.getZoomValue()); + // Workaround to avoid problems for some special cases (not very nice) + if (localY != getContentsY()) { + localY = Math.round(localY * fView.getZoomValue()); + localY = fView.contentsToViewY(localY) + 1; + } else { + localY = 1; + } + localWidth = Math.round(localWidth * fView.getZoomValue()) - 1; + localHeight = Math.round(localHeight * fView.getZoomValue()) - 1; + localX = fView.contentsToViewX(localX) + 1; + if (localX < -fVisibleScreenBounds) { + localWidth = localWidth + localX + fVisibleScreenBounds; + localX = -fVisibleScreenBounds; + } + if (localY < -fVisibleScreenBounds) { + localHeight = localHeight + localY + fVisibleScreenBounds; + localY = -fVisibleScreenBounds; + } + if ((localWidth < -fVisibleScreenBounds) && (localX + localWidth < -fVisibleScreenBounds)) { + localWidth = -fVisibleScreenBounds; + } else if (localWidth + localX > fView.getVisibleWidth() + fVisibleScreenBounds) { + localWidth = fView.getVisibleWidth() + fVisibleScreenBounds - localX; + } + if ((localHeight < -fVisibleScreenBounds) && (localY + localHeight < -fVisibleScreenBounds)) { + localHeight = -fVisibleScreenBounds; + } else if (localHeight + localY > fView.getVisibleHeight() + fVisibleScreenBounds) { + localHeight = fView.getVisibleHeight() + fVisibleScreenBounds - localY; + } + fContext.fillRectangle(localX, localY, localWidth, localHeight); + } + + @Override + public void fillGradientRectangle(int x, int y, int width, int height, boolean isVertical) { + int localX = x; + int localY = y; + int localWidth = width; + int localHeight = height; + + localX = Math.round(localX * fView.getZoomValue()); + localY = Math.round(localY * fView.getZoomValue()); + localWidth = Math.round(localWidth * fView.getZoomValue()); + localHeight = Math.round(localHeight * fView.getZoomValue()); + IColor tempColor = fForeground; + setForeground(fGradientColor); + localX = fView.contentsToViewX(localX); + localY = fView.contentsToViewY(localY); + + if (localX < -fVisibleScreenBounds) { + localWidth = localWidth + localX + fVisibleScreenBounds; + localX = -fVisibleScreenBounds; + } + if (localY < -fVisibleScreenBounds) { + localHeight = localHeight + localY + fVisibleScreenBounds; + localY = -fVisibleScreenBounds; + } + + if ((localWidth < -fVisibleScreenBounds) && (localX + localWidth < -fVisibleScreenBounds)) { + localWidth = -fVisibleScreenBounds; + } else if (localWidth + localX > fView.getVisibleWidth() + fVisibleScreenBounds) { + localWidth = fView.getVisibleWidth() + fVisibleScreenBounds - localX; + } + if ((localHeight < -fVisibleScreenBounds) && (localY + localHeight < -fVisibleScreenBounds)) { + localHeight = -fVisibleScreenBounds; + } else if (localHeight + localY > fView.getVisibleHeight() + fVisibleScreenBounds) { + localHeight = fView.getVisibleHeight() + fVisibleScreenBounds - localY; + } + if (isVertical) { + fContext.fillGradientRectangle(localX, localY, localWidth, localHeight, isVertical); + } + else { + fContext.fillGradientRectangle(localX + localWidth, localY, -localWidth, localHeight + 1, isVertical); + } + setForeground(tempColor); + } + + @Override + public int textExtent(String name) { + return fContext.textExtent(name).x; + } + + @Override + public void drawText(String string, int x, int y, boolean isTrans) { + int localX = x; + int localY = y; + + localX = Math.round(localX * fView.getZoomValue()); + localY = Math.round(localY * fView.getZoomValue()); + fContext.drawText(string, fView.contentsToViewX(localX), fView.contentsToViewY(localY), isTrans); + if (fDrawWithFocus) { + Point r = fContext.textExtent(string); + fContext.drawFocus(localX - 1, localY - 1, r.x + 2, r.y + 2); + } + } + + @Override + public void drawText(String string, int x, int y) { + int localX = x; + int localY = y; + + localX = Math.round(localX * fView.getZoomValue()); + localY = Math.round(localY * fView.getZoomValue()); + fContext.drawText(string, fView.contentsToViewX(localX), fView.contentsToViewY(localY), true); + if (fDrawWithFocus) { + Point r = fContext.textExtent(string); + fContext.drawFocus(localX - 1, localY - 1, r.x + 2, r.y + 2); + } + } + + @Override + public void fillOval(int x, int y, int width, int height) { + int localX = x; + int localY = y; + int localWidth = width; + int localHeight = height; + + localX = Math.round(localX * fView.getZoomValue()); + localY = Math.round(localY * fView.getZoomValue()); + localWidth = Math.round(localWidth * fView.getZoomValue()); + localHeight = Math.round(localHeight * fView.getZoomValue()); + fContext.fillOval(fView.contentsToViewX(localX), fView.contentsToViewY(localY), localWidth, localHeight); + } + + @Override + public IColor getBackground() { + if ((fBackground != null) && (fBackground.getColor() instanceof Color) && (!((Color) (fBackground.getColor())).isDisposed())) { + return fBackground; + } + return ColorImpl.getSystemColor(SWT.COLOR_WHITE); + } + + @Override + public IColor getForeground() { + if ((fForeground != null) && (fForeground.getColor() instanceof Color) && (!((Color) (fForeground.getColor())).isDisposed())) { + return fForeground; + } + return ColorImpl.getSystemColor(SWT.COLOR_WHITE); + } + + @Override + public void setBackground(IColor color) { + if (color == null) { + return; + } + if (color.getColor() instanceof Color) { + fContext.setBackground((Color) color.getColor()); + fBackground = color; + } + } + + @Override + public void setForeground(IColor color) { + if (color == null) { + return; + } + if (color.getColor() instanceof Color) { + Color c = (Color) color.getColor(); + if (!c.isDisposed()) { + fContext.setForeground(c); + fForeground = color; + } + } + } + + @Override + public void setGradientColor(IColor color) { + if (color == null) { + return; + } + if (color.getColor() instanceof Color) { + fGradientColor = color; + } + } + + @Override + public void setLineWidth(int width) { + if (fView.isPrinting()) { + fContext.setLineWidth(width * 2); + } + else { + fContext.setLineWidth(width); + } + } + + @Override + public int getLineWidth() { + return fContext.getLineWidth(); + } + + /** + * Method to draw a text in rectangle. (Linux GTK Workaround) + * + * @param string The text to draw. + * @param x The x position. + * @param y The y position. + * @param isTransparent true for transparent else false + */ + protected void localDrawText(String string, int x, int y, boolean isTransparent) { + Point r = fContext.textExtent(string); + if (!isTransparent) { + fContext.fillRectangle(x, y, r.x, r.y); + } + fContext.drawText(string, x, y, isTransparent); + if ((fDrawWithFocus) && (string.length() > 1)) { + fContext.drawFocus(x - 1, y - 1, r.x + 2, r.y + 2); + } + } + + @Override + public void drawTextTruncatedCentred(String name, int xValue, int yValue, int width, int height, boolean trans) { + int localX = xValue; + int localY = yValue; + int localWidth = width; + int localHeight = height; + + Point tx = fContext.textExtent(name); + localX = Math.round(localX * fView.getZoomValue()); + int y = 0; + // Workaround to avoid round problems for some special cases (not very nice) + if (localY != getContentsY()) { + localY = Math.round(localY * fView.getZoomValue()); + y = fView.contentsToViewY(localY); + } + localWidth = Math.round(localWidth * fView.getZoomValue()); + localHeight = Math.round(localHeight * fView.getZoomValue()); + int x = fView.contentsToViewX(localX); + if (tx.y > localHeight) { + return; + } + + // Adjust height and y + if (y < -fVisibleScreenBounds) { + localHeight = localHeight + y + fVisibleScreenBounds; + y = -fVisibleScreenBounds; + } + if ((localHeight < -fVisibleScreenBounds) && (y + localHeight < -fVisibleScreenBounds)) { + localHeight = -fVisibleScreenBounds; + } else if (localHeight + y > fView.getVisibleHeight() + fVisibleScreenBounds) { + localHeight = fView.getVisibleHeight() + fVisibleScreenBounds - y; + } + + if (tx.x <= localWidth) { + localDrawText(name, x + 1 + (localWidth - tx.x) / 2, y + 1 + (localHeight - tx.y) / 2, trans); + } else { + String nameToDisplay = name; + for (int i = name.length() - 1; i >= 0 && fContext.textExtent(nameToDisplay).x >= localWidth; i--) { + nameToDisplay = name.substring(0, i); + } + int dotCount = 0; + for (int i = 1; i <= 3 && nameToDisplay.length() - i > 0; i++) { + dotCount++; + } + nameToDisplay = nameToDisplay.substring(0, nameToDisplay.length() - dotCount); + StringBuffer buf = new StringBuffer(nameToDisplay); + for (int i = 0; i < dotCount; i++) { + buf.append("."); //$NON-NLS-1$ + } + nameToDisplay = buf.toString(); + localDrawText(nameToDisplay, x + 1 + (localWidth - fContext.textExtent(nameToDisplay).x) / 2, y + 1 + (localHeight - fContext.textExtent(nameToDisplay).y) / 2, trans); + } + } + + @Override + public void drawTextTruncated(String name, int xValue, int yValue, int width, int height, boolean trans) { + int localX = xValue; + int localY = yValue; + int localWidth = width; + int localHeight = height; + + localX = Math.round(localX * fView.getZoomValue()); + localY = Math.round(localY * fView.getZoomValue()); + localWidth = Math.round(localWidth * fView.getZoomValue()); + localHeight = Math.round(localHeight * fView.getZoomValue()); + int x = fView.contentsToViewX(localX); + int y = fView.contentsToViewY(localY); + if (fContext.textExtent(name).x <= localWidth) { + localDrawText(name, x + 1, y + 1 + localHeight, trans); + } else { + String nameToDisplay = name; + for (int i = name.length() - 1; i >= 0 && fContext.textExtent(nameToDisplay).x >= localWidth; i--) { + nameToDisplay = name.substring(0, i); + } + int dotCount = 0; + for (int i = 1; i <= 3 && nameToDisplay.length() - i > 0; i++) { + dotCount++; + } + nameToDisplay = nameToDisplay.substring(0, nameToDisplay.length() - dotCount); + + StringBuffer buf = new StringBuffer(nameToDisplay); + + for (int i = 0; i < dotCount; i++) { + buf.append("."); //$NON-NLS-1$ + } + nameToDisplay = buf.toString(); + localDrawText(nameToDisplay, x + 1, y + 1 + localHeight, trans); + } + } + + @Override + public void drawImage(IImage image, int xValue, int yValue, int maxWith, int maxHeight) { + int localX = xValue; + int localY = yValue; + + Image img = null; + if (image != null && image.getImage() instanceof Image) { + img = (Image) image.getImage(); + } else { + localX = Math.round(localX * fView.getZoomValue()); + localY = Math.round(localY * fView.getZoomValue()); + int x = fView.contentsToViewX(localX); + int y = fView.contentsToViewY(localY); + float tempZoom = fView.getZoomValue(); + int width = Math.round(maxWith * tempZoom); + int height = Math.round(maxHeight * tempZoom); + fContext.setBackground(fView.getDisplay().getSystemColor(SWT.COLOR_RED)); + fContext.fillRectangle(x, y, width, height); + return; + } + localX = Math.round(localX * fView.getZoomValue()); + localY = Math.round(localY * fView.getZoomValue()); + int x = fView.contentsToViewX(localX); + int y = fView.contentsToViewY(localY); + Rectangle b = ((Image) image.getImage()).getBounds(); + int width = b.width; + int height = b.height; + if (width > maxWith) { + width = maxWith; + } + if (height > maxHeight) { + height = maxHeight; + } + float tempZoom = fView.getZoomValue(); + width = Math.round(width * tempZoom); + height = Math.round(height * tempZoom); + + if (fView.isPrinting() && width > 0 && height > 0) { + Image dbuffer = new Image(fView.getDisplay(), width, height); + GC tempgc = new GC(dbuffer); + tempgc.drawImage(img, 0, 0, b.width, b.height, 0, 0, width, height); + Image dbuffer2 = new Image(fView.getDisplay(), dbuffer.getImageData()); + fContext.drawImage(dbuffer2, x, y); + tempgc.dispose(); + dbuffer.dispose(); + dbuffer2.dispose(); + } else { + fContext.drawImage(img, 0, 0, b.width, b.height, x, y, width, height); + } + } + + @Override + public void drawArc(int x, int y, int width, int height, int startAngle, int endAngle) { + int localX = x; + int localY = y; + int localWidth = width; + int localHeight = height; + + localX = Math.round(localX * fView.getZoomValue()); + localY = Math.round(localY * fView.getZoomValue()); + localWidth = Math.round(localWidth * fView.getZoomValue()); + localHeight = Math.round(localHeight * fView.getZoomValue()); + if (localWidth == 0 || localHeight == 0 || endAngle == 0) { + return; + } + fContext.drawArc(fView.contentsToViewX(localX), fView.contentsToViewY(localY), localWidth, localHeight, startAngle, endAngle); + } + + @Override + public void setFont(IFont font) { + if (font.getFont() != null && ((Font) font.getFont()).getFontData().length > 0) { + FontData fontData = ((Font) font.getFont()).getFontData()[0]; + if (SDViewPref.getInstance().fontLinked() || fView.isPrinting()) { + int h = Math.round(fontData.getHeight() * fView.getZoomValue()); + if (h > 0) { + fontData.setHeight(h); + } + } + if (fTempFont != null) { + fTempFont.dispose(); + } + fTempFont = new Font(Display.getCurrent(), fontData); + fContext.setFont(fTempFont); + } + } + + @Override + public int getFontHeight(IFont font) { + if (font.getFont() != null && (font.getFont() instanceof Font) && ((Font) font.getFont()).getFontData().length > 0) { + Font toRestore = fContext.getFont(); + fContext.setFont((Font) font.getFont()); + int height = fContext.textExtent("lp").y;//$NON-NLS-1$ + fContext.setFont(toRestore); + return height; + } + return 0; + } + + /** + * Returns the current font height. + * + * @return the current font height. + */ + protected int getCurrentFontHeight() { + return fContext.textExtent("lp").y; //$NON-NLS-1$ + } + + @Override + public int getFontWidth(IFont font) { + if ((font.getFont() != null) && (font.getFont() instanceof Font)) { + Font toRestore = fContext.getFont(); + fContext.setFont((Font) font.getFont()); + int width = fContext.getFontMetrics().getAverageCharWidth(); + fContext.setFont(toRestore); + return width; + } + return 0; + } + + /** + * Disposes all created resources. + */ + public void dispose() { + if (fTempFont != null) { + fTempFont.dispose(); + } + fTempFont = null; + if (fContext != null) { + fContext.dispose(); + } + fContext = null; + } + + @Override + public float getZoom() { + if (fView != null) { + return fView.getZoomValue(); + } + return 1; + } + + @Override + public int getLineDotStyle() { + return SWT.LINE_DOT; + } + + @Override + public int getLineDashStyle() { + return SWT.LINE_DASH; + } + + @Override + public int getLineSolidStyle() { + return SWT.LINE_SOLID; + } + + @Override + public IColor createColor(int r, int g, int b) { + return new ColorImpl(Display.getDefault(), r, g, b); + } + + @Override + public void setDrawTextWithFocusStyle(boolean focus) { + fDrawWithFocus = focus; + } + + /** + * Returns the screen bounds. + * + * @return the screen bounds. + */ + protected static int getVscreenBounds() { + return fVisibleScreenBounds; + } + + /** + * Sets the visible screen bounds. + * + * @param vBounds the screen bounds. + */ + protected static void setVscreenBounds(int vBounds) { + fVisibleScreenBounds = vBounds; + } + + /** + * Returns the graphical context. + * + * @return the graphical context + * @since 2.0 + */ + protected GC getGc() { + return fContext; + } + + /** + * Returns the SD widget. + * + * @return the SD widget + * @since 2.0 + */ + protected SDWidget getSDWidget() { + return fView; + } + + /** + * Returns the gradient color. + * + * @return the gradient color + * @since 2.0 + */ + protected IColor setGradientColor() { + return fGradientColor; + } + + // ------------------------------------------------------------------------ + // Helper methods + // ------------------------------------------------------------------------ + + /** + * Validates the polygon height + * + * @param localPoint array of points + * @return height + */ + private int validatePolygonHeight(int[] localPoint) { + int i = 1; + int max = 0; + int min = Integer.MAX_VALUE; + while (i < localPoint.length) { + max = Math.abs(localPoint[i]) > Math.abs(max) ? localPoint[i] : max; + min = Math.abs(localPoint[i]) < Math.abs(min) ? localPoint[i] : min; + i+=2; + } + int height = max - min; + if (min < -fVisibleScreenBounds) { + height = height + min + fVisibleScreenBounds; + min = -fVisibleScreenBounds; + } + if ((height < -fVisibleScreenBounds) && (min + height < -fVisibleScreenBounds)) { + height = -fVisibleScreenBounds; + } else if (height + min > fView.getVisibleHeight() + fVisibleScreenBounds) { + height = fView.getVisibleHeight() + fVisibleScreenBounds - min; + } + return height; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/SDView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/SDView.java new file mode 100644 index 0000000000..8bfed0365e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/SDView.java @@ -0,0 +1,1181 @@ +/********************************************************************** + * Copyright (c) 2005, 2014 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd; + +import java.util.Iterator; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.BaseMessage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Frame; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SyncMessage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SyncMessageReturn; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.ConfigureMinMax; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.FirstPage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.KeyBindingsManager; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.LastPage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.MoveToMessage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.NextPage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.OpenSDFiltersDialog; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.OpenSDFindDialog; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.OpenSDPagesDialog; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.PrevPage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.Print; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.ShowNodeEnd; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.ShowNodeStart; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.Zoom; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.Zoom.ZoomType; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.IExtendedFilterProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.IExtendedFindProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDAdvancedPagingProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDCollapseProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDExtendedActionBarProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDFilterProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDFindProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDPagingProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDPropertiesProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.load.IUml2SDLoader; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.load.LoadersManager; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.part.ViewPart; +import org.eclipse.ui.views.properties.IPropertySheetPage; + +/** + *

    + * This class is a generic sequence diagram view implementation. + *

    + + * @version 1.0 + * @author sveyrier + */ +public class SDView extends ViewPart { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * Name of menu separator for view modes + * @since 2.0 + */ + public static final String UML2SD_VIEW_MODES_SEPARATOR = "UML2SD_VIEW_MODES"; //$NON-NLS-1$ + /** + * Name of menu separator for working set + * @since 2.0 + */ + public static final String UML2SD_WORKING_SET_SEPARATOR = "UML2SD_WORKING_SET"; //$NON-NLS-1$ + /** + * Name of menu separator for sorting + * @since 2.0 + */ + public static final String UML2SD_SORTING_SEPARATOR = "UML2SD_SORTING"; //$NON-NLS-1$ + /** + * Name of menu separator for filtering + * @since 2.0 + */ + public static final String UML2SD_FILTERING_SEPARATOR = "UML2SD_FILTERING"; //$NON-NLS-1$ + /** + * Name of menu separator for view layout + * @since 2.0 + */ + public static final String UML2SD_VIEW_LAYOUT_SEPARATOR = "UML2SD_VIEW_LAYOUT"; //$NON-NLS-1$ + /** + * Name of menu separator for link editor + * @since 2.0 + */ + public static final String UML2SD_LINK_EDITOR_SEPARATOR = "UML2SD_LINK_EDITOR"; //$NON-NLS-1$ + /** + * Name of menu separator for other commands + * @since 2.0 + */ + public static final String UML2SD_OTHER_COMMANDS_SEPARATOR = "UML2SD_OTHER_COMMANDS"; //$NON-NLS-1$ + /** + * Name of menu separator for other plug-in commands + * @since 2.0 + */ + public static final String UML2SD_OTHER_PLUGINS_COMMANDS_SEPARATOR = "UML2SD_OTHER_PLUGINS_COMMANDS"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The sequence diagram widget. + */ + private SDWidget fSdWidget = null; + /** + * The time compression bar. + */ + private TimeCompressionBar fTimeCompressionBar = null; + /** + * The sequence diagram find provider implementation. + */ + private ISDFindProvider fSdFindProvider = null; + /** + * The sequence diagram paging provider implementation. + */ + private ISDPagingProvider fSdPagingProvider = null; + /** + * The sequence diagram filter provider implementation. + */ + private ISDFilterProvider fSdFilterProvider = null; + /** + * The extended sequence diagram filter provider implementation. + */ + private IExtendedFilterProvider fSdExFilterProvider = null; + /** + * The extended sequence diagram find provider implementation. + */ + private IExtendedFindProvider fSdExFindProvider = null; + /** + * The extended sequence diagram action bar provider implementation. + */ + private ISDExtendedActionBarProvider fSdExtendedActionBarProvider = null; + /** + * The sequence diagram property provider implementation. + */ + private ISDPropertiesProvider fSdPropertiesProvider = null; + /** + * Button for executing the next page action. + */ + private NextPage fNextPageButton = null; + /** + * Button for executing the previous page action. + */ + private PrevPage fPrevPageButton = null; + /** + * Button for executing the first page page action. + */ + private FirstPage fFirstPageButton = null; + /** + * Button for executing the last page action. + */ + private LastPage fLastPageButton = null; + /** + * The menu manager reference. + */ + private MenuManager fMenuMgr = null; + /** + * Flag to indicate whether view needs initialization or not. + */ + private boolean fNeedInit = true; + /** + * WaitCursor is the cursor to be displayed when long tasks are running + */ + private Cursor fWaitCursor; + + private Zoom fResetZoomAction; + private Zoom fNoZoomAction; + private Zoom fZoomInAction; + private Zoom fZoomOutAction; + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public void createPartControl(Composite c) { + Composite parent = new Composite(c, SWT.NONE); + GridLayout parentLayout = new GridLayout(); + parentLayout.numColumns = 2; + parentLayout.marginWidth = 0; + parentLayout.marginHeight = 0; + parent.setLayout(parentLayout); + + GridData timeLayoutdata = new GridData(GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL); + timeLayoutdata.widthHint = 10; + GridData seqDiagLayoutData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL); + fTimeCompressionBar = new TimeCompressionBar(parent, SWT.NONE); + fTimeCompressionBar.setLayoutData(timeLayoutdata); + fSdWidget = new SDWidget(parent, SWT.NONE); + fSdWidget.setLayoutData(seqDiagLayoutData); + fSdWidget.setSite(this); + fSdWidget.setTimeBar(fTimeCompressionBar); + + // Add this view to the key bindings manager + KeyBindingsManager.getInstance().add(this.getSite().getId()); + + createCoolbarContent(); + + hookContextMenu(); + + fTimeCompressionBar.setVisible(false); + parent.layout(true); + + Print print = new Print(this); + getViewSite().getActionBars().setGlobalActionHandler(ActionFactory.PRINT.getId(), print); + + fNeedInit = restoreLoader(); + } + + /** + * Load a blank page that is supposed to explain that a kind of interaction must be chosen. + */ + protected void loadBlank() { + IUml2SDLoader loader = new BlankUml2SdLoader(); + loader.setViewer(this); + setContentDescription(loader.getTitleString()); + } + + @Override + public void setFocus() { + if (fSdWidget != null) { + // update actions for key bindings + KeyBindingsManager.getInstance().setSdView(this); + fSdWidget.setFocus(); + } + if (isViewReady() && fNeedInit) { + fNeedInit = restoreLoader(); + } + } + + @Override + public void dispose() { + KeyBindingsManager.getInstance().remove(this.getSite().getId()); + disposeZoomActions(); + super.dispose(); + } + + private void disposeZoomActions() { + if (fResetZoomAction != null) { + fResetZoomAction.dispose(); + } + if (fNoZoomAction != null) { + fNoZoomAction.dispose(); + } + if (fZoomInAction != null) { + fZoomInAction.dispose(); + } + if (fZoomOutAction != null) { + fZoomOutAction.dispose(); + } + } + + /** + * Returns the SD widget. + * + * @return The SD widget. + */ + public SDWidget getSDWidget() { + return fSdWidget; + } + + /** + * Set the find provider for the opened sequence diagram viewer
    + * If the provider is not set, the find menu item will not be available in the viewer
    + * A find provider is called back when the user perform a find action
    + * The find provider is responsible to move the sequence diagram to the GraphNode which match the + * find criteria as well as to highlight the GraphNode + * + * @param provider the search provider + */ + public void setSDFindProvider(ISDFindProvider provider) { + fSdFindProvider = provider; + fSdExFindProvider = null; + createCoolbarContent(); + if (provider != null) { + KeyBindingsManager.getInstance().setFindEnabled(true); + } + else { + KeyBindingsManager.getInstance().setFindEnabled(false); + } + } + + /** + * Set the find provider for the opened sequence diagram viewer
    + * If the provider is not set, the find menu item will not be available in + * the viewer
    + * A find provider is called back when the user perform a find action
    + * If the extended find provider is set, it replaces the regular find + * provider (sdFindProvider).
    + * + * @param provider + * The provider to set + */ + public void setExtendedFindProvider(IExtendedFindProvider provider) { + fSdExFindProvider = provider; + fSdFindProvider = null; + createCoolbarContent(); + if (provider != null) { + KeyBindingsManager.getInstance().setFindEnabled(true); + } + else { + KeyBindingsManager.getInstance().setFindEnabled(false); + } + } + + /** + * Returns the extended find provider + * + * @return extended find provider. + */ + public IExtendedFindProvider getExtendedFindProvider() { + return fSdExFindProvider; + } + + /** + * Resets all providers. + */ + public void resetProviders() { + KeyBindingsManager.getInstance().setFindEnabled(false); + fSdFindProvider = null; + fSdExFindProvider = null; + fSdFilterProvider = null; + fSdExFilterProvider = null; + fSdPagingProvider = null; + fSdExtendedActionBarProvider = null; + fSdPropertiesProvider = null; + if ((fSdWidget != null) && (!fSdWidget.isDisposed())) { + fSdWidget.setCollapseProvider(null); + } + } + + /** + * Set the filter provider for the opened sequence diagram viewer
    + * If the provider is not set, the filter menu item will not be available in the viewer
    + * A filter provider is called back when the user perform a filter action
    + * + * @param provider the filter provider + */ + public void setSDFilterProvider(ISDFilterProvider provider) { + fSdFilterProvider = provider; + // Both systems can be used now, commenting out next statement + createCoolbarContent(); + } + + /** + * Sets the extended filter provider for the opened sequence diagram viewer. + * + * @param provider + * The provider to set + */ + public void setExtendedFilterProvider(IExtendedFilterProvider provider) { + fSdExFilterProvider = provider; + // Both systems can be used now, commenting out next statement + createCoolbarContent(); + } + + /** + * Returns the extended find provider. + * + * @return The extended find provider. + */ + public IExtendedFilterProvider getExtendedFilterProvider() { + return fSdExFilterProvider; + } + + /** + * Register the given provider to support Drag and Drop collapsing. This provider is + * responsible of updating the Frame. + * + * @param provider - the provider to register + */ + public void setCollapsingProvider(ISDCollapseProvider provider) { + if ((fSdWidget != null) && (!fSdWidget.isDisposed())) { + fSdWidget.setCollapseProvider(provider); + } + } + + /** + * Set the page provider for the opened sequence diagram viewer
    + * If the sequence diagram provided (see setFrame) need to be split in many parts, a paging provider must be + * provided in order to handle page change requested by the user
    + * Set a page provider will create the next and previous page buttons in the viewer coolBar + * + * @param provider the paging provider + */ + public void setSDPagingProvider(ISDPagingProvider provider) { + fSdPagingProvider = provider; + createCoolbarContent(); + } + + /** + * Returns the current page provider for the view + * + * @return the paging provider + */ + public ISDPagingProvider getSDPagingProvider() { + return fSdPagingProvider; + } + + /** + * Returns the current find provider for the view + * + * @return the find provider + */ + public ISDFindProvider getSDFindProvider() { + return fSdFindProvider; + } + + /** + * Returns the current filter provider for the view + * + * @return the filter provider + */ + public ISDFilterProvider getSDFilterProvider() { + return fSdFilterProvider; + } + + /** + * Set the extended action bar provider for the opened sequence diagram viewer
    + * This allow to add programmatically actions in the coolbar and/or in the drop-down menu + * + * @param provider the search provider + */ + public void setSDExtendedActionBarProvider(ISDExtendedActionBarProvider provider) { + fSdExtendedActionBarProvider = provider; + createCoolbarContent(); + } + + /** + * Returns the current extended action bar provider for the view + * + * @return the extended action bar provider + */ + public ISDExtendedActionBarProvider getSDExtendedActionBarProvider() { + return fSdExtendedActionBarProvider; + } + + /** + * Set the properties view provider for the opened sequence diagram viewer + * + * @param provider the properties provider + */ + public void setSDPropertiesProvider(ISDPropertiesProvider provider) { + fSdPropertiesProvider = provider; + } + + /** + * Returns the current extended action bar provider for the view. + * + * @return the extended action bar provider + */ + public ISDPropertiesProvider getSDPropertiesProvider() { + return fSdPropertiesProvider; + } + + /** + * Sets the sdWidget. + * + * @param sdWidget + * A sdWidget to set + * @since 2.0 + */ + protected void setSDWidget(SDWidget sdWidget) { + fSdWidget = sdWidget; + } + + /** + * Sets the time compression bar. + * + * @param timeCompressionbar + * A sdWidget to set + * @since 2.0 + */ + protected void setTimeBar(TimeCompressionBar timeCompressionbar) { + fTimeCompressionBar = timeCompressionbar; + } + + /** + * Sets the initialization flag. + * + * @param needInit + * flag value to set + * @since 2.0 + */ + protected void setNeedInit(boolean needInit) { + fNeedInit = needInit; + } + + /** + * Creates the basic sequence diagram menu + */ + protected void hookContextMenu() { + fMenuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$ + fMenuMgr.setRemoveAllWhenShown(true); + fMenuMgr.addMenuListener(new IMenuListener() { + @Override + public void menuAboutToShow(IMenuManager manager) { + fillContextMenu(manager); + } + }); + Menu menu = fMenuMgr.createContextMenu(fSdWidget.getViewControl()); + fSdWidget.getViewControl().setMenu(menu); + getSite().registerContextMenu(fMenuMgr, fSdWidget.getSelectionProvider()); + } + + /** + * Returns the context menu manager + * + * @return the menu manager + */ + public MenuManager getMenuManager() { + return fMenuMgr; + } + + /** + * Fills the basic sequence diagram menu and define the dynamic menu item insertion point + * + * @param manager the menu manager + */ + protected void fillContextMenu(IMenuManager manager) { + manager.add(new Separator("Additions")); //$NON-NLS-1$ + if (getSDWidget() != null && getSDWidget().getCurrentGraphNode() != null) { + ISelectionProvider selProvider = fSdWidget.getSelectionProvider(); + ISelection sel = selProvider.getSelection(); + int nbMessage = 0; + Iterator it = ((StructuredSelection) sel).iterator(); + while (it.hasNext()) { + Object node = it.next(); + if (node instanceof BaseMessage) { + nbMessage++; + } + } + if (nbMessage != 1) { + return; + } + GraphNode node = getSDWidget().getCurrentGraphNode(); + if ((node instanceof SyncMessageReturn) && (((SyncMessageReturn) node).getMessage() != null)) { + Action goToMessage = new MoveToMessage(this); + goToMessage.setText(Messages.SequenceDiagram_GoToMessage); + manager.add(goToMessage); + } + if ((node instanceof SyncMessage) && (((SyncMessage) node).getMessageReturn() != null)) { + Action goToMessage = new MoveToMessage(this); + goToMessage.setText(Messages.SequenceDiagram_GoToMessageReturn); + manager.add(goToMessage); + } + } + manager.add(new Separator("MultiSelectAdditions")); //$NON-NLS-1$ + } + + /** + * Enables/Disables an action with given name. + * + * @param actionName The action name + * @param state true or false + */ + public void setEnableAction(String actionName, boolean state) { + IActionBars bar = getViewSite().getActionBars(); + if (bar != null) { + IContributionItem item = bar.getMenuManager().find(actionName); + if ((item != null) && (item instanceof ActionContributionItem)) { + IAction action = ((ActionContributionItem) item).getAction(); + if (action != null) { + action.setEnabled(state); + } + item.setVisible(state); + bar.updateActionBars(); + } + } + } + + /** + * Creates the coolBar icon depending on the actions supported by the Sequence Diagram provider
    + * - Navigation buttons are displayed if ISDPovider.HasPaging return true
    + * - Navigation buttons are enabled depending on the value return by ISDPovider.HasNext and HasPrev
    + * + * @see ISDGraphNodeSupporter Action support definition + * @see SDView#setSDFilterProvider(ISDFilterProvider) + * @see SDView#setSDFindProvider(ISDFindProvider) + * @see SDView#setSDPagingProvider(ISDPagingProvider) + */ + protected void createCoolbarContent() { + IActionBars bar = getViewSite().getActionBars(); + + bar.getMenuManager().removeAll(); + bar.getToolBarManager().removeAll(); + disposeZoomActions(); + + createMenuGroup(); + + fResetZoomAction = new Zoom(this, ZoomType.ZOOM_RESET); + bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fResetZoomAction); + bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fResetZoomAction); + + fNoZoomAction = new Zoom(this, ZoomType.ZOOM_NONE); + fNoZoomAction.setChecked(true); + bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fNoZoomAction); + bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fNoZoomAction); + + fZoomInAction = new Zoom(this, ZoomType.ZOOM_IN); + bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fZoomInAction); + bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fZoomInAction); + + fZoomOutAction = new Zoom(this, ZoomType.ZOOM_OUT); + bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fZoomOutAction); + bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fZoomOutAction); + + MenuManager navigation = new MenuManager(Messages.SequenceDiagram_Navigation); + + ShowNodeStart showNodeStart = new ShowNodeStart(this); + showNodeStart.setText(Messages.SequenceDiagram_ShowNodeStart); + + showNodeStart.setId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ShowNodeStart");//$NON-NLS-1$ + showNodeStart.setActionDefinitionId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ShowNodeStart");//$NON-NLS-1$ + navigation.add(showNodeStart); + + ShowNodeEnd showNodeEnd = new ShowNodeEnd(this); + showNodeEnd.setText(Messages.SequenceDiagram_ShowNodeEnd); + + showNodeEnd.setId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ShowNodeEnd");//$NON-NLS-1$ + showNodeEnd.setActionDefinitionId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ShowNodeEnd");//$NON-NLS-1$ + navigation.add(showNodeEnd); + + bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, navigation); + + ConfigureMinMax minMax = new ConfigureMinMax(this); + minMax.setText(Messages.SequenceDiagram_ConfigureMinMax); + minMax.setId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ConfigureMinMax");//$NON-NLS-1$ + bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, minMax); + + if ((fSdWidget.getFrame() != null) && (fSdWidget.getFrame().hasTimeInfo())) { + minMax.setEnabled(true); + } else { + minMax.setEnabled(false); + } + + // Do we need to display a paging item + if (fSdPagingProvider != null) { + fNextPageButton = new NextPage(this); + bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fNextPageButton); + fNextPageButton.setEnabled(fSdPagingProvider.hasNextPage()); + bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fNextPageButton); + + fPrevPageButton = new PrevPage(this); + bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fPrevPageButton); + fPrevPageButton.setEnabled(fSdPagingProvider.hasPrevPage()); + bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fPrevPageButton); + + fFirstPageButton = new FirstPage(this); + bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fFirstPageButton); + fFirstPageButton.setEnabled(fSdPagingProvider.hasPrevPage()); + bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fFirstPageButton); + + fLastPageButton = new LastPage(this); + bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fLastPageButton); + fLastPageButton.setEnabled(fSdPagingProvider.hasNextPage()); + bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, fLastPageButton); + } + + if (fSdExFilterProvider != null) { + Action action = fSdExFilterProvider.getFilterAction(); + if (action != null) { + if (action.getId() == null) + { + action.setId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.extendedFilter"); //$NON-NLS-1$ + } + if (action.getImageDescriptor() == null) { + action.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FILTERS)); + } + if (action.getText() == null || action.getText().length() == 0) { + action.setText(Messages.SequenceDiagram_EditFilters); + } + bar.getMenuManager().prependToGroup(UML2SD_FILTERING_SEPARATOR, action); + bar.getToolBarManager().prependToGroup(UML2SD_FILTERING_SEPARATOR, action); + } + } + // Both systems can be used now: commenting out else keyword + if (fSdFilterProvider != null) { + bar.getMenuManager().appendToGroup(UML2SD_FILTERING_SEPARATOR, new OpenSDFiltersDialog(this, fSdFilterProvider)); + } + if (fSdPagingProvider instanceof ISDAdvancedPagingProvider) { + IContributionItem sdPaging = bar.getMenuManager().find(OpenSDPagesDialog.ID); + if (sdPaging != null) { + bar.getMenuManager().remove(sdPaging); + sdPaging = null; + } + bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, new OpenSDPagesDialog(this, (ISDAdvancedPagingProvider) fSdPagingProvider)); + updatePagesMenuItem(bar); + } + + if (fSdExFindProvider != null) { + Action action = fSdExFindProvider.getFindAction(); + if (action != null) { + if (action.getId() == null) { + action.setId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.extendedFind"); //$NON-NLS-1$ + } + if (action.getImageDescriptor() == null) { + action.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SEARCH_SEQ)); + } + if (action.getText() == null) { + action.setText(Messages.SequenceDiagram_Find + "..."); //$NON-NLS-1$ + } + bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, action); + bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, action); + } + } else if (fSdFindProvider != null) { + bar.getMenuManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, new OpenSDFindDialog(this)); + bar.getToolBarManager().appendToGroup(UML2SD_OTHER_COMMANDS_SEPARATOR, new OpenSDFindDialog(this)); + } + + if (fSdExtendedActionBarProvider != null) { + fSdExtendedActionBarProvider.supplementCoolbarContent(bar); + } + + bar.updateActionBars(); + } + + /** + * Updates the view coolbar buttons state according to the value return by: - + * ISDExtendedActionBarProvider.hasNextPage()
    + * - ISDExtendedActionBarProvider.hasPrevPage()
    + * + */ + public void updateCoolBar() { + if (fSdPagingProvider != null) { + IActionBars bar = getViewSite().getActionBars(); + if (bar == null) { + return; + } + IToolBarManager barManager = bar.getToolBarManager(); + if (barManager == null) { + return; + } + IContributionItem nextPage = barManager.find(NextPage.ID); + if (nextPage instanceof ActionContributionItem) { + IAction nextPageAction = ((ActionContributionItem) nextPage).getAction(); + if (nextPageAction instanceof NextPage) { + ((NextPage) nextPageAction).setEnabled(fSdPagingProvider.hasNextPage()); + } + } + + IContributionItem prevPage = barManager.find(PrevPage.ID); + if (prevPage instanceof ActionContributionItem) { + IAction prevPageAction = ((ActionContributionItem) prevPage).getAction(); + if (prevPageAction instanceof PrevPage) { + ((PrevPage) prevPageAction).setEnabled(fSdPagingProvider.hasPrevPage()); + } + } + + IContributionItem firstPage = barManager.find(FirstPage.ID); + if (firstPage instanceof ActionContributionItem) { + IAction firstPageAction = ((ActionContributionItem) firstPage).getAction(); + if (firstPageAction instanceof FirstPage) { + ((FirstPage) firstPageAction).setEnabled(fSdPagingProvider.hasPrevPage()); + } + } + + IContributionItem lastPage = barManager.find(LastPage.ID); + if (lastPage instanceof ActionContributionItem) { + IAction lastPageAction = ((ActionContributionItem) lastPage).getAction(); + if (lastPageAction instanceof LastPage) { + ((LastPage) lastPageAction).setEnabled(fSdPagingProvider.hasNextPage()); + } + } + + updatePagesMenuItem(bar); + } + } + + /** + * Enables or disables the Pages... menu item, depending on the number of pages + * + * @param bar the bar containing the action + */ + protected void updatePagesMenuItem(IActionBars bar) { + if (fSdPagingProvider instanceof ISDAdvancedPagingProvider) { + IMenuManager menuManager = bar.getMenuManager(); + ActionContributionItem contributionItem = (ActionContributionItem) menuManager.find(OpenSDPagesDialog.ID); + IAction openSDPagesDialog = null; + if (contributionItem != null) { + openSDPagesDialog = contributionItem.getAction(); + } + + if (openSDPagesDialog instanceof OpenSDPagesDialog) { + openSDPagesDialog.setEnabled(((ISDAdvancedPagingProvider) fSdPagingProvider).pagesCount() > 1); + } + } + } + + /** + * The frame to render (the sequence diagram) + * + * @param frame the frame to display + */ + public void setFrame(Frame frame) { + setFrame(frame, true); + } + + /** + * The frame to render (the sequence diagram) + * + * @param frame the frame to display + * @param resetPosition boolean Flag whether to reset the position or not. + */ + protected void setFrame(Frame frame, boolean resetPosition) { + if (getSDWidget() == null) { + return; + } + + if (frame == null) { + loadBlank(); + return; + } + + IUml2SDLoader loader = LoadersManager.getInstance().getCurrentLoader(getViewSite().getId(), this); + if (loader == null) { + return; + } + + if (loader.getTitleString() != null) { + setContentDescription(loader.getTitleString()); + } + + getSDWidget().setFrame(frame, resetPosition); + + if (fTimeCompressionBar != null) { + fTimeCompressionBar.setFrame(frame); + } + updateCoolBar(); + if (fTimeCompressionBar != null) { + if (!frame.hasTimeInfo()) { + Composite parent = fTimeCompressionBar.getParent(); + fTimeCompressionBar.setVisible(false); + parent.layout(true); + } else { + Composite parent = fTimeCompressionBar.getParent(); + fTimeCompressionBar.setVisible(true); + parent.layout(true); + } + } + IContributionItem shortKeysMenu = getViewSite().getActionBars().getMenuManager().find("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers");//$NON-NLS-1$ + MenuManager shortKeys = (MenuManager) shortKeysMenu; + if (shortKeys != null) { + IContributionItem[] items = shortKeys.getItems(); + for (int i = 0; i < items.length; i++) { + if (items[i] instanceof ActionContributionItem) { + IAction action = ((ActionContributionItem) items[i]).getAction(); + if (action != null) { + action.setEnabled(true); + } + } + } + } + createCoolbarContent(); + } + + /** + * Activate or deactivate the short key command given in parameter (see plugin.xml) + * + * @param id the command id defined in the plugin.xml + * @param value the state value + */ + public void setEnableCommand(String id, boolean value) { + IContributionItem shortKeysMenu = getViewSite().getActionBars().getMenuManager().find("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers");//$NON-NLS-1$ + MenuManager shortKeys = (MenuManager) shortKeysMenu; + if (shortKeys == null) { + return; + } + IContributionItem item = shortKeys.find(id); + if ((item != null) && (item instanceof ActionContributionItem)) { + IAction action = ((ActionContributionItem) item).getAction(); + if (action != null) { + action.setEnabled(value); + } + } + } + + /** + * Set the frame from an other thread than the one executing the main loop + * + * @param frame The frame to set (and display) + */ + public void setFrameSync(final Frame frame) { + if (getSDWidget() == null || getSDWidget().isDisposed()) { + return; + } + getSDWidget().getDisplay().syncExec(new Runnable() { + @Override + public void run() { + if (getSDWidget() == null || getSDWidget().isDisposed() || + ((fTimeCompressionBar != null) && fTimeCompressionBar.isDisposed())) { + return; + } + setFrame(frame); + } + }); + + } + + /** + * Ensure an object is visible from an other thread than the one executing the main loop + * + * @param sm The node to make visible in view + */ + public void ensureVisibleSync(final GraphNode sm) { + getSDWidget().getDisplay().syncExec(new Runnable() { + @Override + public void run() { + if (getSDWidget() == null || getSDWidget().isDisposed()) { + return; + } + getSDWidget().ensureVisible(sm); + } + }); + } + + /** + * Set the frame and ensure an object is visible from an other thread than the one executing the main loop + * + * @param sm The node to make visible in view + * @param frame Frame The frame to set + */ + public void setFrameAndEnsureVisibleSync(final Frame frame, final GraphNode sm) { + if (getSDWidget() == null || getSDWidget().isDisposed()) { + return; + } + getSDWidget().getDisplay().syncExec(new Runnable() { + @Override + public void run() { + if (getSDWidget() == null || getSDWidget().isDisposed()) { + return; + } + setFrameAndEnsureVisible(frame, sm); + } + }); + } + + /** + * Set the frame and ensure an object is visible + * + * @param sm The node to make visible in view + * @param frame Frame The frame to set + */ + public void setFrameAndEnsureVisible(Frame frame, GraphNode sm) { + getSDWidget().clearSelection(); + setFrame(frame, false); + getSDWidget().ensureVisible(sm); + } + + /** + * Set the frame and ensure an object is visible from an other thread than the one executing the main loop + * + * @param frame The frame to set. + * @param x The x coordinate to make visible. + * @param y The y coordinate to make visible. + */ + public void setFrameAndEnsureVisibleSync(final Frame frame, final int x, final int y) { + if (getSDWidget() == null || getSDWidget().isDisposed()) { + return; + } + + getSDWidget().getDisplay().syncExec(new Runnable() { + @Override + public void run() { + setFrameAndEnsureVisible(frame, x, y); + } + }); + } + + /** + * Set the frame and ensure an object is visible + * + * @param frame The frame to set. + * @param x The x coordinate to make visible. + * @param y The y coordinate to make visible. + */ + public void setFrameAndEnsureVisible(Frame frame, int x, int y) { + getSDWidget().clearSelection(); + setFrame(frame, false); + getSDWidget().ensureVisible(x, y); + getSDWidget().redraw(); + } + + /** + * Toggle between default and wait cursors from an other thread than the one executing the main loop + * + * @param wait true for wait cursor else false for default cursor. + */ + public void toggleWaitCursorAsync(final boolean wait) { + if (getSDWidget() == null || getSDWidget().isDisposed()) { + return; + } + + getSDWidget().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + if (getSDWidget() == null || getSDWidget().isDisposed()) { + return; + } + if (wait) { + if (fWaitCursor != null && !fWaitCursor.isDisposed()) { + fWaitCursor.dispose(); + } + fWaitCursor = new Cursor(getSDWidget().getDisplay(), SWT.CURSOR_WAIT); + getSDWidget().setCursor(fWaitCursor); + getSDWidget().getDisplay().update(); + } else { + if (fWaitCursor != null && !fWaitCursor.isDisposed()) { + fWaitCursor.dispose(); + } + fWaitCursor = null; + getSDWidget().setCursor(null); + getSDWidget().getDisplay().update(); + } + } + }); + } + + /** + * Return the time compression bar widget + * + * @return the time compression bar + */ + public TimeCompressionBar getTimeCompressionBar() { + return fTimeCompressionBar; + } + + /** + * Returns the current Frame (the sequence diagram container) + * + * @return the current frame + */ + public Frame getFrame() { + if (getSDWidget() != null) { + return getSDWidget().getFrame(); + } + return null; + } + + /** + * Gets the initialization flag. + * @return the value of the initialization flag. + * @since 2.0 + */ + protected boolean isNeedInit() { + return fNeedInit; + } + + /** + * Restores the loader for the view based on the view ID. + * + * @return boolean true if initialization is needed else false. + */ + protected boolean restoreLoader() { + String id = getViewSite().getId(); + if (id == null) { + return true; + } + IUml2SDLoader loader = LoadersManager.getInstance().getCurrentLoader(id, this); + if ((loader != null)) { + loader.setViewer(this); + return false; + } + loadBlank(); + return true; + } + + /** + * Checks if current view is ready to be used. + * + * @return boolean true if view is ready else false. + */ + protected boolean isViewReady() { + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + if (page == null) { + return false; + } + + IViewReference[] ref = page.getViewReferences(); + for (int i = 0; i < ref.length; i++) { + if (ref[i].getView(false) == this) { + return true; + } + } + return false; + } + + /** + * Creates the menu group. + */ + protected void createMenuGroup() { + IActionBars bar = getViewSite().getActionBars(); + if (bar == null) { + return; + } + bar.getToolBarManager().add(new Separator(UML2SD_VIEW_MODES_SEPARATOR)); + bar.getToolBarManager().add(new Separator(UML2SD_WORKING_SET_SEPARATOR)); + bar.getToolBarManager().add(new Separator(UML2SD_SORTING_SEPARATOR)); + bar.getToolBarManager().add(new Separator(UML2SD_FILTERING_SEPARATOR)); + bar.getToolBarManager().add(new Separator(UML2SD_VIEW_LAYOUT_SEPARATOR)); + bar.getToolBarManager().add(new Separator(UML2SD_LINK_EDITOR_SEPARATOR)); + bar.getToolBarManager().add(new Separator(UML2SD_OTHER_COMMANDS_SEPARATOR)); + bar.getToolBarManager().add(new Separator(UML2SD_OTHER_PLUGINS_COMMANDS_SEPARATOR)); + bar.getMenuManager().add(new Separator(UML2SD_VIEW_MODES_SEPARATOR)); + bar.getMenuManager().add(new Separator(UML2SD_WORKING_SET_SEPARATOR)); + bar.getMenuManager().add(new Separator(UML2SD_SORTING_SEPARATOR)); + bar.getMenuManager().add(new Separator(UML2SD_FILTERING_SEPARATOR)); + bar.getMenuManager().add(new Separator(UML2SD_VIEW_LAYOUT_SEPARATOR)); + bar.getMenuManager().add(new Separator(UML2SD_LINK_EDITOR_SEPARATOR)); + bar.getMenuManager().add(new Separator(UML2SD_OTHER_COMMANDS_SEPARATOR)); + bar.getMenuManager().add(new Separator(UML2SD_OTHER_PLUGINS_COMMANDS_SEPARATOR)); + } + + @Override + public Object getAdapter(Class adapter) { + Object obj = super.getAdapter(adapter); + if (fSdPropertiesProvider != null && adapter.equals(IPropertySheetPage.class)) { + return fSdPropertiesProvider.getPropertySheetEntry(); + } + + return obj; + } + + /** + * Loader for a blank sequence diagram. + * + * @version 1.0 + */ + public static class BlankUml2SdLoader implements IUml2SDLoader { + @Override + public void setViewer(SDView viewer) { + // Nothing to do + Frame f = new Frame(); + f.setName(""); //$NON-NLS-1$ + viewer.setFrame(f); + } + + @Override + public String getTitleString() { + return ""; //$NON-NLS-1$ + } + + @Override + public void dispose() { + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/SDWidget.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/SDWidget.java new file mode 100755 index 0000000000..089ebc0e49 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/SDWidget.java @@ -0,0 +1,2066 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; + +import org.eclipse.jface.contexts.IContextIds; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.accessibility.ACC; +import org.eclipse.swt.accessibility.Accessible; +import org.eclipse.swt.accessibility.AccessibleAdapter; +import org.eclipse.swt.accessibility.AccessibleControlAdapter; +import org.eclipse.swt.accessibility.AccessibleControlEvent; +import org.eclipse.swt.accessibility.AccessibleEvent; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.TraverseEvent; +import org.eclipse.swt.events.TraverseListener; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.printing.Printer; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Caret; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.BaseMessage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.BasicExecutionOccurrence; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Frame; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.ITimeRange; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Lifeline; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Metrics; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.SDPrintDialog; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.SDPrintDialogUI; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IColor; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDCollapseProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.load.LoadersManager; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.ISDPreferences; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; +import org.eclipse.ui.contexts.IContextService; +import org.eclipse.ui.part.ViewPart; + +/** + *

    + * This class implements sequence diagram widget used in the sequence diagram view. + *

    + * + * @version 1.0 + * @author sveyrier + */ +public class SDWidget extends ScrollView implements SelectionListener, + IPropertyChangeListener, DisposeListener, ITimeCompressionListener { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The frame to display in the sequence diagram widget. + */ + private Frame fFrame; + /** + * The overview image to display. + */ + private Image fOverView = null; + /** + * The zoom in menu item. + */ + private MenuItem fZoomIn = null; + /** + * The zoom out menu item. + */ + private MenuItem fZoomOut = null; + /** + * The sequence diagram selection provider. + */ + private SDWidgetSelectionProvider fSelProvider = null; + /** + * The current zoom value. + */ + private float fZoomValue = 1; + /** + * The current zoomInMode (true for zoom in). + */ + private boolean fZoomInMode = false; + /** + * The current zoomOutMode (true for zoom out). + */ + private boolean fZoomOutMode = false; + /** + * The current list of selected graph nodes. + */ + private List fSelectedNodeList = null; + /** + * Flag whether ctrl button is selected or not. + */ + private boolean fCtrlSelection = false; + /** + * A reference to the view site. + */ + private ViewPart fSite = null; + /** + * The current graph node (the last selected one). + */ + private GraphNode fCurrentGraphNode = null; + /** + * The first graph node in list (multiple selection). + */ + private GraphNode fListStart = null; + /** + * The previous graph node (multiple selection). + */ + private List fPrevList = null; + /** + * The time compression bar. + */ + private TimeCompressionBar fTimeBar = null; + /** + * The current diagram tool tip. + */ + private DiagramToolTip fToolTip = null; + /** + * The accessible object reference of view control. + */ + private Accessible fAccessible = null; + /** + * The current node for the tooltip to display. + */ + private GraphNode fToolTipNode; + /** + * The life line to drag and drop. + */ + private Lifeline fDragAndDrop = null; + /** + * The number of focused widgets. + */ + private int fFocusedWidget = -1; + /** + * The printer zoom. + */ + private float fPrinterZoom = 0; + /** + * Y coordinate for printer. + */ + private int fPrinterY = 0; + /** + * X coordinate for printer. + */ + private int fPrinterX = 0; + /** + * Flag whether drag and drop is enabled or not. + */ + private boolean fIsDragAndDrop = false; + /** + * The x coordinate for drag. + */ + private int fDragX = 0; + /** + * The y coordinate for drag. + */ + private int fDragY = 0; + /** + * The reorder mode. + */ + private boolean fReorderMode = false; + /** + * The collapse caret image. + */ + private Image fCollapaseCaretImg = null; + /** + * The arrow up caret image. + */ + private Image fArrowUpCaretImg = null; + /** + * The current caret image. + */ + private Image fCurrentCaretImage = null; + /** + * A sequence diagramm collapse provider (for collapsing graph nodes) + */ + private ISDCollapseProvider fCollapseProvider = null; + /** + * The insertion caret. + */ + private Caret fInsertionCartet = null; + /** + * The reorder list when in reorder mode. + */ + private List fReorderList = null; + /** + * Flag to specify whether in printing mode or not. + */ + private boolean fIsPrinting = false; + /** + * A printer reference. + */ + private Printer fPrinter = null; + /** + * Flag whether shift was selected or not. + */ + private boolean fShiftSelection = false; + /** + * The scroll tooltip. + */ + private DiagramToolTip fScrollToolTip = null; + /** + * Timer for auto_scroll feature + */ + private AutoScroll fLocalAutoScroll = null; + /** + * TimerTask for auto_scroll feature !=null when auto scroll is running + */ + private Timer fLocalAutoScrollTimer = null; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + /** + * Constructor for SDWidget. + * @param c The parent composite + * @param s The style + */ + public SDWidget(Composite c, int s) { + super(c, s | SWT.NO_BACKGROUND, true); + setOverviewEnabled(true); + fSelectedNodeList = new ArrayList<>(); + fSelProvider = new SDWidgetSelectionProvider(); + SDViewPref.getInstance().addPropertyChangeListener(this); + fToolTip = new DiagramToolTip(getViewControl()); + super.addDisposeListener(this); + + fScrollToolTip = new DiagramToolTip(c); + getVerticalBar().addListener(SWT.MouseUp, new Listener() { + + @Override + public void handleEvent(Event event) { + fScrollToolTip.hideToolTip(); + } + + }); + fAccessible = getViewControl().getAccessible(); + + fAccessible.addAccessibleListener(new AccessibleAdapter() { + @Override + public void getName(AccessibleEvent e) { + // Case toolTip + if (e.childID == 0) { + if (fToolTipNode != null) { + if (fToolTipNode instanceof Lifeline) { + Lifeline lifeline = (Lifeline) fToolTipNode; + e.result = lifeline.getToolTipText(); + } else { + e.result = fToolTipNode.getName() + getPostfixForTooltip(true); + } + } + } else { + if (getFocusNode() != null) { + if (getFocusNode() instanceof Lifeline) { + e.result = MessageFormat.format(Messages.SequenceDiagram_LifelineNode, new Object[] { String.valueOf(getFocusNode().getName()) }); + } + if (getFocusNode() instanceof BaseMessage) { + BaseMessage mes = (BaseMessage) getFocusNode(); + if ((mes.getStartLifeline() != null) && (mes.getEndLifeline() != null)) { + e.result = MessageFormat.format( + Messages.SequenceDiagram_MessageNode, + new Object[] { String.valueOf(mes.getName()), String.valueOf(mes.getStartLifeline().getName()), Integer.valueOf(mes.getStartOccurrence()), String.valueOf(mes.getEndLifeline().getName()), + Integer.valueOf(mes.getEndOccurrence()) }); + } else if ((mes.getStartLifeline() == null) && (mes.getEndLifeline() != null)) { + e.result = MessageFormat.format(Messages.SequenceDiagram_FoundMessageNode, new Object[] { String.valueOf(mes.getName()), String.valueOf(mes.getEndLifeline().getName()), Integer.valueOf(mes.getEndOccurrence()) }); + } else if ((mes.getStartLifeline() != null) && (mes.getEndLifeline() == null)) { + e.result = MessageFormat.format(Messages.SequenceDiagram_LostMessageNode, new Object[] { String.valueOf(mes.getName()), String.valueOf(mes.getStartLifeline().getName()), Integer.valueOf(mes.getStartOccurrence()) }); + } + } else if (getFocusNode() instanceof BasicExecutionOccurrence) { + BasicExecutionOccurrence exec = (BasicExecutionOccurrence) getFocusNode(); + e.result = MessageFormat.format(Messages.SequenceDiagram_ExecutionOccurrenceWithParams, + new Object[] { String.valueOf(exec.getName()), String.valueOf(exec.getLifeline().getName()), Integer.valueOf(exec.getStartOccurrence()), Integer.valueOf(exec.getEndOccurrence()) }); + } + + } + } + } + }); + + fAccessible.addAccessibleControlListener(new AccessibleControlAdapter() { + @Override + public void getFocus(AccessibleControlEvent e) { + if (fFocusedWidget == -1) { + e.childID = ACC.CHILDID_SELF; + } else { + e.childID = fFocusedWidget; + } + } + + @Override + public void getRole(AccessibleControlEvent e) { + switch (e.childID) { + case ACC.CHILDID_SELF: + e.detail = ACC.ROLE_CLIENT_AREA; + break; + case 0: + e.detail = ACC.ROLE_TOOLTIP; + break; + case 1: + e.detail = ACC.ROLE_LABEL; + break; + default: + break; + } + } + + @Override + public void getState(AccessibleControlEvent e) { + e.detail = ACC.STATE_FOCUSABLE; + if (e.childID == ACC.CHILDID_SELF) { + e.detail |= ACC.STATE_FOCUSED; + } else { + e.detail |= ACC.STATE_SELECTABLE; + if (e.childID == fFocusedWidget) { + e.detail |= ACC.STATE_FOCUSED | ACC.STATE_SELECTED | ACC.STATE_CHECKED; + } + } + } + }); + + fInsertionCartet = new Caret((Canvas) getViewControl(), SWT.NONE); + fInsertionCartet.setVisible(false); + + fCollapaseCaretImg = Activator.getDefault().getImageFromPath(ITmfImageConstants.IMG_UI_ARROW_COLLAPSE_OBJ); + fArrowUpCaretImg = Activator.getDefault().getImageFromPath(ITmfImageConstants.IMG_UI_ARROW_UP_OBJ); + + fReorderList = new ArrayList<>(); + getViewControl().addTraverseListener(new LocalTraverseListener()); + + addTraverseListener(new LocalTraverseListener()); + + getViewControl().addFocusListener(new FocusListener() { + + @Override + public void focusGained(FocusEvent e) { + SDViewPref.getInstance().setNoFocusSelection(false); + fCtrlSelection = false; + fShiftSelection = false; + redraw(); + } + + @Override + public void focusLost(FocusEvent e) { + SDViewPref.getInstance().setNoFocusSelection(true); + redraw(); + } + }); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Sets the time compression bar. + * + * @param bar The time compression bar to set + */ + public void setTimeBar(TimeCompressionBar bar) { + if (bar != null) { + fTimeBar = bar; + fTimeBar.addTimeCompressionListener(this); + } + } + + /** + * Resize the contents to insure the frame fit into the view + * + * @param frame the frame which will be drawn in the view + */ + public void resizeContents(Frame frame) { + int width = Math.round((frame.getWidth() + 2 * Metrics.FRAME_H_MARGIN) * fZoomValue); + int height = Math.round((frame.getHeight() + 2 * Metrics.FRAME_V_MARGIN) * fZoomValue); + resizeContents(width, height); + } + + /** + * The frame to render (the sequence diagram) + * + * @param theFrame the frame to display + * @param resetPosition boolean + */ + public void setFrame(Frame theFrame, boolean resetPosition) { + fReorderList.clear(); + fSelectedNodeList.clear(); + fSelProvider.setSelection(new StructuredSelection()); + fFrame = theFrame; + if (resetPosition) { + setContentsPos(0, 0); + resizeContents(fFrame); + redraw(); + } + // prepare the old overview to be reused + if (fOverView != null) { + fOverView.dispose(); + } + fOverView = null; + resizeContents(fFrame); + } + + /** + * Returns the current Frame (the sequence diagram container) + * + * @return the frame + */ + public Frame getFrame() { + return fFrame; + } + + /** + * Returns the selection provider for the current sequence diagram + * + * @return the selection provider + */ + public ISelectionProvider getSelectionProvider() { + return fSelProvider; + } + + /** + * Returns a list of selected graph nodes. + * + * @return a list of selected graph nodes. + */ + public List getSelection() { + return fSelectedNodeList; + } + + /** + * Adds a graph node to the selected nodes list. + * + * @param node A graph node + */ + public void addSelection(GraphNode node) { + if (node == null) { + return; + } + fSelectedNodeList.add(node); + node.setSelected(true); + fCurrentGraphNode = node; + StructuredSelection selection = new StructuredSelection(fSelectedNodeList); + fSelProvider.setSelection(selection); + } + + /** + * Adds a list of node to the selected nodes list. + * + * @param list of graph nodes + */ + public void addSelection(List list) { + for (int i = 0; i < list.size(); i++) { + if (!fSelectedNodeList.contains(list.get(i))) { + fSelectedNodeList.add(list.get(i)); + list.get(i).setSelected(true); + } + } + StructuredSelection selection = new StructuredSelection(fSelectedNodeList); + fSelProvider.setSelection(selection); + } + + /** + * Removes a node from the selected nodes list. + * + * @param node to remove + */ + public void removeSelection(GraphNode node) { + fSelectedNodeList.remove(node); + node.setSelected(false); + node.setFocused(false); + StructuredSelection selection = new StructuredSelection(fSelectedNodeList); + fSelProvider.setSelection(selection); + } + + /** + * Removes a list of graph nodes from the selected nodes list. + * + * @param list of nodes to remove. + */ + public void removeSelection(List list) { + fSelectedNodeList.removeAll(list); + for (int i = 0; i < list.size(); i++) { + list.get(i).setSelected(false); + list.get(i).setFocused(false); + } + StructuredSelection selection = new StructuredSelection(fSelectedNodeList); + fSelProvider.setSelection(selection); + } + + /** + * Clear the list of GraphNodes which must be drawn selected. + */ + public void clearSelection() { + for (int i = 0; i < fSelectedNodeList.size(); i++) { + fSelectedNodeList.get(i).setSelected(false); + fSelectedNodeList.get(i).setFocused(false); + } + fCurrentGraphNode = null; + fSelectedNodeList.clear(); + fSelProvider.setSelection(new StructuredSelection()); + } + + /** + * Sets view part. + * + * @param viewSite The view part to set + */ + public void setSite(ViewPart viewSite) { + fSite = viewSite; + fSite.getSite().setSelectionProvider(fSelProvider); + IContextService service = (IContextService) fSite.getSite().getWorkbenchWindow().getService(IContextService.class); + service.activateContext("org.eclipse.linuxtools.tmf.ui.view.uml2sd.context"); //$NON-NLS-1$ + service.activateContext(IContextIds.CONTEXT_ID_WINDOW); + } + + /** + * Returns the GraphNode overView the mouse if any + * + * @return the current graph node + * */ + public GraphNode getMouseOverNode() { + return fCurrentGraphNode; + } + + /** + * Sets the zoom in mode. + * + * @param value + * The mode value to set. + */ + public void setZoomInMode(boolean value) { + if (value) { + setZoomOutMode(false); + } + fZoomInMode = value; + } + + /** + * Sets the zoom out mode. + * + * @param value + * The mode value to set. + */ + public void setZoomOutMode(boolean value) { + if (value) { + setZoomInMode(false); + } + fZoomOutMode = value; + } + + /** + * Sets the current zoom value. + * + * @param zoomValue + * The current zoom value + * @since 2.0 + */ + public void setZoomValue(float zoomValue) { + fZoomValue = zoomValue; + } + + /** + * Moves the Sequence diagram to ensure the given node is visible and draw it selected + * + * @param node the GraphNode to move to + */ + public void moveTo(GraphNode node) { + if (node == null) { + return; + } + clearSelection(); + addSelection(node); + ensureVisible(node); + } + + /** + * Moves the Sequence diagram to ensure the given node is visible + * + * @param node the GraphNode to move to + */ + public void ensureVisible(GraphNode node) { + if (node == null) { + return; + } + int x = Math.round(node.getX() * fZoomValue); + int y = Math.round(node.getY() * fZoomValue); + int width = Math.round(node.getWidth() * fZoomValue); + int height = Math.round(node.getHeight() * fZoomValue); + if ((node instanceof BaseMessage) && (height == 0)) { + int header = Metrics.LIFELINE_HEARDER_TEXT_V_MARGIN * 2 + Metrics.getLifelineHeaderFontHeigth(); + height = -Math.round((Metrics.getMessagesSpacing() + header) * fZoomValue); + y = y + Math.round(Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT * fZoomValue); + } + if (node instanceof BasicExecutionOccurrence) { + width = 1; + height = 1; + } + if (node instanceof Lifeline) { + y = getContentsY(); + height = getVisibleHeight(); + } + ensureVisible(x, y, width, height, SWT.CENTER, true); + redraw(); + } + + /** + * Returns the current zoom factor. + * @return the current zoom factor. + */ + public float getZoomFactor() { + return fZoomValue; + } + + /** + * Returns teh printer reference. + * + * @return the printer reference + */ + public Printer getPrinter() { + return fPrinter; + } + + /** + * Returns whether the widget is used for printing or not. + * + * @return whether the widget is used for printing or not + */ + public boolean isPrinting() { + return fIsPrinting; + } + + /** + * Returns the current graph node. + * + * @return the current graph node + * @since 2.0 + */ + public GraphNode getCurrentGraphNode() { + return fCurrentGraphNode; + } + + /** + * Returns the current zoom value. + * + * @return the current zoom value + * @since 2.0 + */ + public float getZoomValue() { + return fZoomValue; + } + + /** + * Gets the zoom in mode. + * + * @return the mode value to set. + * @since 2.0 + */ + public boolean getZoomInMode() { + return fZoomInMode; + } + + + /** + * Gets the zoom out mode. + * + * @return the mode value to set. + * @since 2.0 + */ + public boolean getZoomOutMode() { + return fZoomOutMode; + } + + /** + * Returns if ctrl selection + * @return true if ctrl selection else false + * @since 2.0 + */ + public boolean isCtrlSelection() { + return fCtrlSelection; + } + + /** + * Returns if shift selection + * @return true if shift Selection else false + * @since 2.0 + */ + public boolean isShiftSelection() { + return fCtrlSelection; + } + + /** + * Gets the overview image. + * + * @param rect Rectangle to include overview. + * @return the overview image + */ + public Image getOverview(Rectangle rect) { + float oldzoom = fZoomValue; + if ((fOverView != null) && ((rect.width != fOverView.getBounds().width) || (rect.height != fOverView.getBounds().height))) { + fOverView.dispose(); + fOverView = null; + } + if (fOverView == null) { + int backX = getContentsX(); + int backY = getContentsY(); + setContentsPos(0, 0); + fOverView = new Image(getDisplay(), rect.width, rect.height); + GC gcim = new GC(fOverView); + NGC context = new NGC(this, gcim); + context.setBackground(SDViewPref.getInstance().getBackGroundColor(ISDPreferences.PREF_FRAME)); + fFrame.draw(context); + setContentsPos(backX, backY); + gcim.dispose(); + context.dispose(); + } + fZoomValue = oldzoom; + return fOverView; + } + + /** + * Resets the zoom factor. + */ + public void resetZoomFactor() { + int currentX = Math.round(getContentsX() / fZoomValue); + int currentY = Math.round(getContentsY() / fZoomValue); + fZoomValue = 1; + if (fTimeBar != null && !fTimeBar.isDisposed()) { + fTimeBar.setZoom(fZoomValue); + } + redraw(); + update(); + setContentsPos(currentX, currentY); + } + + /** + * Enable or disable the lifeline reodering using Drag and Drop + * + * @param mode - true to enable false otherwise + */ + public void setReorderMode(boolean mode) { + fReorderMode = mode; + } + + /** + * Return the lifelines reorder sequence (using Drag and Drop) if the the reorder mode is turn on. Each ArryList + * element is of type Lifeline[2] with Lifeline[0] inserted before Lifeline[1] in the diagram + * + * @return - the re-odered sequence + */ + public List getLifelineReoderList() { + return fReorderList; + } + + /** + * Sets the focus on given graph node (current node). + * + * @param node + * The graph node to focus on. + */ + public void setFocus(GraphNode node) { + if (node == null) { + return; + } + if (fCurrentGraphNode != null) { + fCurrentGraphNode.setFocused(false); + } + fCurrentGraphNode = node; + node.setFocused(true); + ensureVisible(node); + setFocus(0); + } + + /** + * Returns the graph node focused on. + * + * @return the current graph node + */ + public GraphNode getFocusNode() { + return fCurrentGraphNode; + } + + /** + * Method to traverse right. + */ + public void traverseRight() { + Object selectedNode = getFocusNode(); + if (selectedNode == null) { + traverseLeft(); + } + GraphNode node = null; + if ((selectedNode instanceof BaseMessage) && (((BaseMessage) selectedNode).getEndLifeline() != null)) { + node = fFrame.getCalledMessage((BaseMessage) selectedNode); + } + if (selectedNode instanceof BasicExecutionOccurrence) { + selectedNode = ((BasicExecutionOccurrence) selectedNode).getLifeline(); + } + if ((node == null) && (selectedNode instanceof Lifeline)) { + for (int i = 0; i < fFrame.lifeLinesCount(); i++) { + if ((selectedNode == fFrame.getLifeline(i)) && (i < fFrame.lifeLinesCount() - 1)) { + node = fFrame.getLifeline(i + 1); + break; + } + } + } + if (node != null) { + setFocus(node); + redraw(); + } + } + + /** + * Method to traverse left. + */ + public void traverseLeft() { + Object selectedNode = getFocusNode(); + GraphNode node = null; + if ((selectedNode instanceof BaseMessage) && (((BaseMessage) selectedNode).getStartLifeline() != null)) { + node = fFrame.getCallerMessage((BaseMessage) selectedNode); + } + if (selectedNode instanceof BasicExecutionOccurrence) { + selectedNode = ((BasicExecutionOccurrence) selectedNode).getLifeline(); + } + if (node == null) { + if ((selectedNode instanceof BaseMessage) && (((BaseMessage) selectedNode).getEndLifeline() != null)) { + selectedNode = ((BaseMessage) selectedNode).getEndLifeline(); + } + for (int i = 0; i < fFrame.lifeLinesCount(); i++) { + if ((selectedNode == fFrame.getLifeline(i)) && (i > 0)) { + node = fFrame.getLifeline(i - 1); + break; + } + } + if ((fFrame.lifeLinesCount() > 0) && (node == null)) { + node = fFrame.getLifeline(0); + } + } + if (node != null) { + setFocus(node); + redraw(); + } + } + + /** + * Method to traverse up. + */ + public void traverseUp() { + Object selectedNode = getFocusNode(); + if (selectedNode == null) { + traverseLeft(); + } + GraphNode node = null; + if (selectedNode instanceof BaseMessage) { + node = fFrame.getPrevLifelineMessage(((BaseMessage) selectedNode).getStartLifeline(), (BaseMessage) selectedNode); + } else if (selectedNode instanceof Lifeline) { + node = fFrame.getPrevLifelineMessage((Lifeline) selectedNode, null); + if (!(node instanceof Lifeline)) { + node = null; + } + } else if (selectedNode instanceof BasicExecutionOccurrence) { + node = fFrame.getPrevExecOccurrence((BasicExecutionOccurrence) selectedNode); + if (node == null) { + node = ((BasicExecutionOccurrence) selectedNode).getLifeline(); + } + } + if ((node == null) && (selectedNode instanceof BaseMessage) && (((BaseMessage) selectedNode).getStartLifeline() != null)) { + node = ((BaseMessage) selectedNode).getStartLifeline(); + } + + if (node != null) { + setFocus(node); + redraw(); + } + } + + /** + * Method to traverse down. + */ + public void traverseDown() { + Object selectedNode = getFocusNode(); + if (selectedNode == null) { + traverseLeft(); + } + GraphNode node; + if (selectedNode instanceof BaseMessage) { + node = fFrame.getNextLifelineMessage(((BaseMessage) selectedNode).getStartLifeline(), (BaseMessage) selectedNode); + } else if (selectedNode instanceof Lifeline) { + node = fFrame.getFirstExecution((Lifeline) selectedNode); + } else if (selectedNode instanceof BasicExecutionOccurrence) { + node = fFrame.getNextExecOccurrence((BasicExecutionOccurrence) selectedNode); + } else { + return; + } + + if (node != null) { + setFocus(node); + redraw(); + } + } + + /** + * Method to traverse home. + */ + public void traverseHome() { + Object selectedNode = getFocusNode(); + if (selectedNode == null) { + traverseLeft(); + } + GraphNode node = null; + + if (selectedNode instanceof BaseMessage) { + if (((BaseMessage) selectedNode).getStartLifeline() != null) { + node = fFrame.getNextLifelineMessage(((BaseMessage) selectedNode).getStartLifeline(), null); + } else { + node = fFrame.getNextLifelineMessage(((BaseMessage) selectedNode).getEndLifeline(), null); + } + } else if (selectedNode instanceof Lifeline) { + node = fFrame.getNextLifelineMessage((Lifeline) selectedNode, null); + } else if (selectedNode instanceof BasicExecutionOccurrence) { + node = fFrame.getFirstExecution(((BasicExecutionOccurrence) selectedNode).getLifeline()); + } else { + if (fFrame.lifeLinesCount() > 0) { + Lifeline lifeline = fFrame.getLifeline(0); + node = fFrame.getNextLifelineMessage(lifeline, null); + } + } + + if (node != null) { + setFocus(node); + redraw(); + } + } + + /** + * Method to traverse to the end. + */ + public void traverseEnd() { + Object selectedNode = getFocusNode(); + if (selectedNode == null) { + traverseLeft(); + } + GraphNode node; + if (selectedNode instanceof BaseMessage) { + node = fFrame.getPrevLifelineMessage(((BaseMessage) selectedNode).getStartLifeline(), null); + } else if (selectedNode instanceof Lifeline) { + node = fFrame.getPrevLifelineMessage((Lifeline) selectedNode, null); + } else if (selectedNode instanceof BasicExecutionOccurrence) { + node = fFrame.getLastExecOccurrence(((BasicExecutionOccurrence) selectedNode).getLifeline()); + } else { + if (fFrame.lifeLinesCount() > 0) { + Lifeline lifeline = fFrame.getLifeline(0); + node = fFrame.getPrevLifelineMessage(lifeline, null); + } else { + return; + } + } + + if (node != null) { + setFocus(node); + redraw(); + } + } + + /** + * Method to print UI. + * + * @param sdPrintDialog the sequence diagram printer dialog. + */ + public void printUI(SDPrintDialogUI sdPrintDialog) { + PrinterData data = sdPrintDialog.getPrinterData(); + + if ((data == null) || (fFrame == null)) { + return; + } + + fPrinter = new Printer(data); + + String jobName = MessageFormat.format(Messages.SequenceDiagram_plus, new Object[] { String.valueOf(fSite.getContentDescription()), String.valueOf(fFrame.getName()) }); + fPrinter.startJob(jobName); + + GC gc = new GC(fPrinter); + + float lastZoom = fZoomValue; + + Rectangle area = getClientArea(); + GC gcim = null; + + gcim = gc; + NGC context = new NGC(this, gcim); + + // Set the metrics to use for lifeline text and message text + // using the Graphical Context + Metrics.setLifelineFontHeight(context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE))); + Metrics.setLifelineFontWidth(context.getFontWidth(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE))); + Metrics.setLifelineWidth(SDViewPref.getInstance().getLifelineWidth()); + Metrics.setFrameFontHeight(context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_FRAME_NAME))); + Metrics.setLifelineHeaderFontHeight(context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE_HEADER))); + + int syncMessFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_SYNC_MESS)); + int syncMessRetFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_SYNC_MESS_RET)); + int asyncMessFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_ASYNC_MESS)); + int asyncMessRetFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_ASYNC_MESS_RET)); + + int messageFontHeight = 0; + if (syncMessFontH > syncMessRetFontH) { + messageFontHeight = syncMessFontH; + } else { + messageFontHeight = syncMessRetFontH; + } + if (messageFontHeight < asyncMessFontH) { + messageFontHeight = asyncMessFontH; + } + if (messageFontHeight < asyncMessRetFontH) { + messageFontHeight = asyncMessRetFontH; + } + Metrics.setMessageFontHeight(messageFontHeight); + context.setFont(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE)); + + int width = Math.round((fFrame.getWidth() + 2 * Metrics.FRAME_H_MARGIN) * fZoomValue); + int height = Math.round((fFrame.getHeight() + 2 * Metrics.FRAME_V_MARGIN) * fZoomValue); + if (width < area.width) { + width = area.width; + } + if (height < area.height) { + height = area.height; + } + resizeContents(width, height); + + context.setBackground(SDViewPref.getInstance().getBackGroundColor(ISDPreferences.PREF_FRAME)); + context.fillRectangle(0, 0, getContentsWidth(), Metrics.FRAME_V_MARGIN); + context.fillRectangle(0, 0, fFrame.getX(), getContentsHeight()); + context.fillRectangle(fFrame.getX() + fFrame.getWidth() + 1, 0, getContentsWidth() - (fFrame.getX() + fFrame.getWidth() + 1), getContentsHeight()); + context.fillRectangle(0, fFrame.getY() + fFrame.getHeight() + 1, getContentsWidth(), getContentsHeight() - (fFrame.getY() + fFrame.getHeight() + 1)); + gcim.setLineWidth(1); + + fPrinter.startPage(); + fZoomValue = lastZoom; + + int restoreX = getContentsX(); + int restoreY = getContentsY(); + + float zh = sdPrintDialog.getStepY() * sdPrintDialog.getZoomFactor(); + float zw = sdPrintDialog.getStepX() * sdPrintDialog.getZoomFactor(); + + float zoomValueH = fPrinter.getClientArea().height / zh; + float zoomValueW = fPrinter.getClientArea().width / zw; + if (zoomValueH > zoomValueW) { + fPrinterZoom = zoomValueH; + } else { + fPrinterZoom = zoomValueW; + } + + if (sdPrintDialog.printSelection()) { + int[] pagesList = sdPrintDialog.getPageList(); + + for (int pageIndex = 0; pageIndex < pagesList.length; pageIndex++) { + printPage(pagesList[pageIndex], sdPrintDialog, context); + } + } else if (sdPrintDialog.printAll()) { + for (int pageIndex = 1; pageIndex <= sdPrintDialog.maxNumOfPages(); pageIndex++) { + printPage(pageIndex, sdPrintDialog, context); + } + } else if (sdPrintDialog.printCurrent()) { + printPage(getContentsX(), getContentsY(), sdPrintDialog, context, 1); + } else if (sdPrintDialog.printRange()) { + for (int pageIndex = sdPrintDialog.getFrom(); pageIndex <= sdPrintDialog.maxNumOfPages() && pageIndex <= sdPrintDialog.getTo(); pageIndex++) { + printPage(pageIndex, sdPrintDialog, context); + } + } + + fPrinter.endJob(); + fIsPrinting = false; + + gc.dispose(); + context.dispose(); + + fZoomValue = lastZoom; + fPrinter.dispose(); + setContentsPos(restoreX, restoreY); + } + + /** + * Method to print. + */ + public void print() { + SDPrintDialog sdPrinter = new SDPrintDialog(this.getShell(), this); + try { + if (sdPrinter.open() != 0) { + return; + } + } catch (Exception e) { + Activator.getDefault().logError("Error creating image", e); //$NON-NLS-1$ + return; + } + printUI(sdPrinter.getDialogUI()); + } + + /** + * Method to print a page. + * + * @param pageNum The page number + * @param pd The sequence diagram print dialog + * @param context The graphical context + */ + public void printPage(int pageNum, SDPrintDialogUI pd, NGC context) { + int j = pageNum / pd.getNbRow(); + int i = pageNum % pd.getNbRow(); + if (i != 0) { + j++; + } else { + i = pd.getNbRow(); + } + + i--; + j--; + + i = (int) (i * pd.getStepX()); + j = (int) (j * pd.getStepY()); + + printPage(i, j, pd, context, pageNum); + + fPrinter.endPage(); + } + + /** + * Method to print page ranges. + * + * @param i + * The start page + * @param j + * The end page + * @param pd + * The sequence diagram print dialog + * @param context + * The graphical context + * @param pageNum + * The current page + */ + public void printPage(int i, int j, SDPrintDialogUI pd, NGC context, int pageNum) { + fIsPrinting = false; + int pageNumFontZoom = fPrinter.getClientArea().height / getVisibleHeight(); + fPrinterX = i; + fPrinterY = j; + setContentsPos(i, j); + update(); + fIsPrinting = true; + float lastZoom = fZoomValue; + fZoomValue = fPrinterZoom * lastZoom; + + fFrame.draw(context); + + fZoomValue = pageNumFontZoom; + context.setFont(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE)); + String currentPageNum = String.valueOf(pageNum); + int ii = context.textExtent(currentPageNum); + int jj = context.getCurrentFontHeight(); + fZoomValue = fPrinterZoom * lastZoom; + context.drawText(currentPageNum, Math.round(fPrinterX + getVisibleWidth() / fPrinterZoom - ii / fPrinterZoom), Math.round(fPrinterY + getVisibleHeight() / fPrinterZoom - jj / fPrinterZoom), false); + fIsPrinting = false; + fZoomValue = lastZoom; + } + + /** + * Sets the collapse provider. + * + * @param provider The collapse provider to set + */ + protected void setCollapseProvider(ISDCollapseProvider provider) { + fCollapseProvider = provider; + } + + + /** + * Checks for focus of children. + * + * @param children Control to check + * @return true if child is on focus else false + */ + protected boolean checkFocusOnChilds(Control children) { + if (children instanceof Composite) { + Control[] child = ((Composite) children).getChildren(); + for (int i = 0; i < child.length; i++) { + if (child[i].isFocusControl()) { + return true; + } + checkFocusOnChilds(child[i]); + } + } + return false; + } + + /** + * A post action for a tooltip (before displaying). + * + * @param accessible true if accessible else false + * @return the tooltip text. + */ + protected String getPostfixForTooltip(boolean accessible) { + StringBuffer postfix = new StringBuffer(); + // Determine if the tooltip must show the time difference between the current mouse position and + // the last selected graphNode + if ((fCurrentGraphNode != null) && + (fCurrentGraphNode instanceof ITimeRange) && + (fToolTipNode instanceof ITimeRange) && + (fCurrentGraphNode != fToolTipNode) && + ((ITimeRange) fToolTipNode).hasTimeInfo() && + ((ITimeRange) fCurrentGraphNode).hasTimeInfo()) { + postfix.append(" -> "); //$NON-NLS-1$ + postfix.append(fCurrentGraphNode.getName()); + postfix.append("\n"); //$NON-NLS-1$ + postfix.append(Messages.SequenceDiagram_Delta); + postfix.append(" "); //$NON-NLS-1$ + + //double delta = ((ITimeRange)toolTipNode).getLastTime()-((ITimeRange)currentGraphNode).getLastTime(); + ITmfTimestamp firstTime = ((ITimeRange) fCurrentGraphNode).getEndTime(); + ITmfTimestamp lastTime = ((ITimeRange) fToolTipNode).getEndTime(); + ITmfTimestamp delta = lastTime.getDelta(firstTime); + postfix.append(delta.toString()); + + } else { + if ((fToolTipNode instanceof ITimeRange) && ((ITimeRange) fToolTipNode).hasTimeInfo()) { + postfix.append("\n"); //$NON-NLS-1$ + ITmfTimestamp firstTime = ((ITimeRange) fToolTipNode).getStartTime(); + ITmfTimestamp lastTime = ((ITimeRange) fToolTipNode).getEndTime(); + + if (firstTime != null) { + if (lastTime != null && firstTime.compareTo(lastTime, true) != 0) { + postfix.append("start: "); //$NON-NLS-1$ + postfix.append(firstTime.toString()); + postfix.append("\n"); //$NON-NLS-1$ + postfix.append("end: "); //$NON-NLS-1$ + postfix.append(lastTime.toString()); + postfix.append("\n"); //$NON-NLS-1$ + } else { + postfix.append(firstTime.toString()); + } + } + else if (lastTime != null) { + postfix.append(lastTime.toString()); + } + } + } + return postfix.toString(); + } + + /** + * Sets a new focused widget. + * + * @param newFocusShape A new focus shape. + */ + protected void setFocus(int newFocusShape) { + fFocusedWidget = newFocusShape; + if (fFocusedWidget == -1) { + getViewControl().getAccessible().setFocus(ACC.CHILDID_SELF); + } else { + getViewControl().getAccessible().setFocus(fFocusedWidget); + } + } + + /** + * Highlight the given GraphNode
    + * The GraphNode is then displayed using the system default selection color + * + * @param node the GraphNode to highlight + */ + protected void performSelection(GraphNode node) { + if ((fCtrlSelection) || (fShiftSelection)) { + if (node != null) { + if (fSelectedNodeList.contains(node)) { + removeSelection(node); + } else { + addSelection(node); + } + } else { + return; + } + } else { + clearSelection(); + if (node != null) { + addSelection(node); + } + } + } + + /** + * Returns a draw buffer image. + * + * @return a Image containing the draw buffer. + */ + protected Image getDrawBuffer() { + + update(); + Rectangle area = getClientArea(); + Image dbuffer = new Image(getDisplay(), area.width, area.height); + GC gcim = new GC(dbuffer); + NGC context = new NGC(this, gcim); + + // Set the metrics to use for lifeline text and message text + // using the Graphical Context + Metrics.setLifelineFontHeight(context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE))); + Metrics.setLifelineFontWidth(context.getFontWidth(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE))); + Metrics.setLifelineWidth(SDViewPref.getInstance().getLifelineWidth()); + Metrics.setFrameFontHeight(context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_FRAME_NAME))); + Metrics.setLifelineHeaderFontHeight(context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE_HEADER))); + + int syncMessFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_SYNC_MESS)); + int syncMessRetFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_SYNC_MESS_RET)); + int asyncMessFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_ASYNC_MESS)); + int asyncMessRetFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_ASYNC_MESS_RET)); + + int messageFontHeight = 0; + if (syncMessFontH > syncMessRetFontH) { + messageFontHeight = syncMessFontH; + } else { + messageFontHeight = syncMessRetFontH; + } + if (messageFontHeight < asyncMessFontH) { + messageFontHeight = asyncMessFontH; + } + if (messageFontHeight < asyncMessRetFontH) { + messageFontHeight = asyncMessRetFontH; + } + Metrics.setMessageFontHeight(messageFontHeight); + context.setFont(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE)); + + int width = (int) ((fFrame.getWidth() + 2 * Metrics.FRAME_H_MARGIN) * fZoomValue); + int height = (int) ((fFrame.getHeight() + 2 * Metrics.FRAME_V_MARGIN) * fZoomValue); + + resizeContents(width, height); + + context.setBackground(SDViewPref.getInstance().getBackGroundColor(ISDPreferences.PREF_FRAME)); + context.fillRectangle(0, 0, getContentsWidth(), Metrics.FRAME_V_MARGIN); + context.fillRectangle(0, 0, fFrame.getX(), getContentsHeight()); + context.fillRectangle(fFrame.getX() + fFrame.getWidth() + 1, 0, getContentsWidth() - (fFrame.getX() + fFrame.getWidth() + 1), getContentsHeight()); + context.fillRectangle(0, fFrame.getY() + fFrame.getHeight() + 1, getContentsWidth(), getContentsHeight() - (fFrame.getY() + fFrame.getHeight() + 1)); + gcim.setLineWidth(1); + + fFrame.draw(context); + if (fDragAndDrop != null) { + Lifeline node = fDragAndDrop; + boolean isSelected = fDragAndDrop.isSelected(); + boolean hasFocus = fDragAndDrop.hasFocus(); + node.setSelected(false); + node.setFocused(false); + node.draw(context, fDragX, fDragY); + node.setSelected(isSelected); + node.setFocused(hasFocus); + } + gcim.dispose(); + context.dispose(); + return dbuffer; + } + + @Override + protected void keyPressedEvent(KeyEvent event) { + if (!(isFocusControl() || getViewControl().isFocusControl())) { + Control[] child = getParent().getChildren(); + for (int i = 0; i < child.length; i++) { + if ((child[i].isFocusControl())&& (!(child[i] instanceof ScrollView))) { + getViewControl().setFocus(); + break; + } + } + } + setFocus(-1); + + if (event.keyCode == SWT.CTRL) { + fCtrlSelection = true; + } + if (event.keyCode == SWT.SHIFT) { + fShiftSelection = true; + fPrevList = new ArrayList<>(); + fPrevList.addAll(getSelection()); + } + + GraphNode prevNode = getFocusNode(); + + if (event.keyCode == SWT.ARROW_RIGHT) { + traverseRight(); + } + + if (event.keyCode == SWT.ARROW_LEFT) { + traverseLeft(); + } + + if (event.keyCode == SWT.ARROW_DOWN) { + traverseDown(); + } + + if (event.keyCode == SWT.ARROW_UP) { + traverseUp(); + } + + if (event.keyCode == SWT.HOME) { + traverseHome(); + } + + if (event.keyCode == SWT.END) { + traverseEnd(); + } + + if ((!fShiftSelection) && (!fCtrlSelection)) { + fListStart = fCurrentGraphNode; + } + + if (event.character == ' ') { + performSelection(fCurrentGraphNode); + if (!fShiftSelection) { + fListStart = fCurrentGraphNode; + } + } + + if ((fShiftSelection) && (prevNode != getFocusNode())) { + clearSelection(); + addSelection(fPrevList); + addSelection(fFrame.getNodeList(fListStart, getFocusNode())); + if (getFocusNode() instanceof Lifeline) { + ensureVisible(getFocusNode().getX(), getFocusNode().getY(), getFocusNode().getWidth(), getFocusNode().getHeight(), SWT.CENTER | SWT.VERTICAL, true); + } else { + ensureVisible(getFocusNode()); + } + } else if ((!fCtrlSelection) && (!fShiftSelection)) { + + clearSelection(); + if (getFocusNode() != null) { + addSelection(getFocusNode()); + + if (getFocusNode() instanceof Lifeline) { + ensureVisible(getFocusNode().getX(), getFocusNode().getY(), getFocusNode().getWidth(), getFocusNode().getHeight(), SWT.CENTER | SWT.VERTICAL, true); + } else { + ensureVisible(getFocusNode()); + } + } + } + + if (fCurrentGraphNode != null) { + fCurrentGraphNode.setFocused(true); + } + redraw(); + + if ((event.character == ' ') && ((fZoomInMode) || (fZoomOutMode))) { + int cx = Math.round((getContentsX() + getVisibleWidth() / 2) / fZoomValue); + int cy = Math.round((getContentsY() + getVisibleHeight() / 2) / fZoomValue); + if (fZoomInMode) { + if (fZoomValue < 64) { + fZoomValue = fZoomValue * (float) 1.25; + } + } else { + fZoomValue = fZoomValue / (float) 1.25; + } + int x = Math.round(cx * fZoomValue - getVisibleWidth() / (float) 2); + int y = Math.round(cy * fZoomValue - getVisibleHeight() / (float) 2); + setContentsPos(x, y); + if (fTimeBar != null) { + fTimeBar.setZoom(fZoomValue); + } + // redraw also resize the scrollView content + redraw(); + } + } + + @Override + protected void keyReleasedEvent(KeyEvent event) { + setFocus(-1); + if (event.keyCode == SWT.CTRL) { + fCtrlSelection = false; + } + if (event.keyCode == SWT.SHIFT) { + fShiftSelection = false; + } + super.keyReleasedEvent(event); + setFocus(1); + } + + @Override + public boolean isFocusControl() { + Control[] child = getChildren(); + for (int i = 0; i < child.length; i++) { + if (child[i].isFocusControl()) { + return true; + } + checkFocusOnChilds(child[i]); + } + return false; + } + + @Override + public boolean setContentsPos(int x, int y) { + int localX = x; + int localY = y; + + if (localX < 0) { + localX = 0; + } + if (localY < 0) { + localY = 0; + } + if (fFrame == null) { + return false; + } + if (localX + getVisibleWidth() > getContentsWidth()) { + localX = getContentsWidth() - getVisibleWidth(); + } + if (localY + getVisibleHeight() > getContentsHeight()) { + localY = getContentsHeight() - getVisibleHeight(); + } + int x1 = Math.round(localX / fZoomValue); + int y2 = Math.round(localY / fZoomValue); + int width = Math.round(getVisibleWidth() / fZoomValue); + int height = Math.round(getVisibleHeight() / fZoomValue); + fFrame.updateIndex(x1, y2, width, height); + + if (fInsertionCartet != null && fInsertionCartet.isVisible()) { + fInsertionCartet.setVisible(false); + } + + return super.setContentsPos(localX, localY); + } + + @Override + protected void contentsMouseHover(MouseEvent event) { + GraphNode graphNode = null; + if (fFrame != null) { + int x = Math.round(event.x / fZoomValue); + int y = Math.round(event.y / fZoomValue); + graphNode = fFrame.getNodeAt(x, y); + if ((graphNode != null) && (SDViewPref.getInstance().tooltipEnabled())) { + fToolTipNode = graphNode; + String postfix = getPostfixForTooltip(true); + if (graphNode instanceof Lifeline) { + Lifeline lifeline = (Lifeline) graphNode; + fToolTip.showToolTip(lifeline.getToolTipText() + postfix); + setFocus(0); + } else { + fToolTip.showToolTip(graphNode.getName() + postfix); + setFocus(0); + } + } else { + fToolTip.hideToolTip(); + } + } + } + + @Override + protected void contentsMouseMoveEvent(MouseEvent e) { + fScrollToolTip.hideToolTip(); + fToolTip.hideToolTip(); + if (!(isFocusControl() || getViewControl().isFocusControl())) { + Control[] child = getParent().getChildren(); + for (int i = 0; i < child.length; i++) { + if ((child[i].isFocusControl()) && (!(child[i] instanceof ScrollView))) { + getViewControl().setFocus(); + break; + } + } + } + setFocus(-1); + + if (((e.stateMask & SWT.BUTTON_MASK) != 0) && ((fDragAndDrop != null) || fIsDragAndDrop) && (fReorderMode || fCollapseProvider != null)) { + fIsDragAndDrop = false; + if (fCurrentGraphNode instanceof Lifeline) { + fDragAndDrop = (Lifeline) fCurrentGraphNode; + } + if (fDragAndDrop != null) { + int dx = 0; + int dy = 0; + if (e.x > getContentsX() + getVisibleWidth()) { + dx = e.x - (getContentsX() + getVisibleWidth()); + } else if (e.x < getContentsX()) { + dx = -getContentsX() + e.x; + } + if (e.y > getContentsY() + getVisibleHeight()) { + dy = e.y - (getContentsY() + getVisibleHeight()); + } else if (e.y < getContentsY()) { + dy = -getContentsY() + e.y; + } + fDragX = e.x; + fDragY = e.y; + if (dx != 0 || dy != 0) { + if (fLocalAutoScroll == null) { + if (fLocalAutoScrollTimer == null) { + fLocalAutoScrollTimer = new Timer(true); + } + fLocalAutoScroll = new AutoScroll(this, dx, dy); + fLocalAutoScrollTimer.schedule(fLocalAutoScroll, 0, 75); + } else { + fLocalAutoScroll.fDeltaX = dx; + fLocalAutoScroll.fDeltaY = dy; + } + } else if (fLocalAutoScroll != null) { + fLocalAutoScroll.cancel(); + fLocalAutoScroll = null; + } + fDragX = Math.round(e.x / fZoomValue); + fDragY = Math.round(e.y / fZoomValue); + redraw(); + Lifeline node = fFrame.getCloserLifeline(fDragX); + if ((node != null) && (node != fDragAndDrop)) { + int y = 0; + int y1 = 0; + int height = Metrics.getLifelineHeaderFontHeigth() + 2 * Metrics.LIFELINE_HEARDER_TEXT_V_MARGIN; + int hMargin = Metrics.LIFELINE_VT_MAGIN / 4; + int x = node.getX(); + int width = node.getWidth(); + if (fFrame.getVisibleAreaY() < node.getY() + node.getHeight() - height - hMargin) { + y = contentsToViewY(Math.round((node.getY() + node.getHeight()) * fZoomValue)); + } else { + y = Math.round(height * fZoomValue); + } + + if (fFrame.getVisibleAreaY() < contentsToViewY(node.getY() - hMargin)) { + y1 = contentsToViewY(Math.round((node.getY() - hMargin) * fZoomValue)); + } else { + y1 = Math.round(height * fZoomValue); + } + + int rx = Math.round(x * fZoomValue); + + fInsertionCartet.setVisible(true); + if ((fInsertionCartet.getImage() != null) && (!fInsertionCartet.getImage().isDisposed())) { + fInsertionCartet.getImage().dispose(); + } + if (rx <= e.x && Math.round(rx + (width * fZoomValue)) >= e.x) { + if (fCollapseProvider != null) { + ImageData data = fCollapaseCaretImg.getImageData(); + data = data.scaledTo(Math.round(fCollapaseCaretImg.getBounds().width * fZoomValue), Math.round(fCollapaseCaretImg.getBounds().height * fZoomValue)); + fCurrentCaretImage = new Image(Display.getCurrent(), data); + fInsertionCartet.setImage(fCurrentCaretImage); + fInsertionCartet.setLocation(contentsToViewX(rx + Math.round((width / (float) 2) * fZoomValue)) - fCurrentCaretImage.getBounds().width / 2, y); + } + } else if (fReorderMode) { + if (rx > e.x) { + if (node.getIndex() > 1 && fFrame.getLifeline(node.getIndex() - 2) == fDragAndDrop) { + return; + } + ImageData data = fArrowUpCaretImg.getImageData(); + data = data.scaledTo(Math.round(fArrowUpCaretImg.getBounds().width * fZoomValue), Math.round(fArrowUpCaretImg.getBounds().height * fZoomValue)); + fCurrentCaretImage = new Image(Display.getCurrent(), data); + fInsertionCartet.setImage(fCurrentCaretImage); + fInsertionCartet.setLocation(contentsToViewX(Math.round((x - Metrics.LIFELINE_SPACING / 2) * fZoomValue)) - fCurrentCaretImage.getBounds().width / 2, y1); + } else { + if (node.getIndex() < fFrame.lifeLinesCount() && fFrame.getLifeline(node.getIndex()) == fDragAndDrop) { + return; + } + ImageData data = fArrowUpCaretImg.getImageData(); + data = data.scaledTo(Math.round(fArrowUpCaretImg.getBounds().width * fZoomValue), Math.round(fArrowUpCaretImg.getBounds().height * fZoomValue)); + fCurrentCaretImage = new Image(Display.getCurrent(), data); + fInsertionCartet.setImage(fCurrentCaretImage); + fInsertionCartet.setLocation(contentsToViewX(Math.round((x + width + Metrics.LIFELINE_SPACING / 2) * fZoomValue)) - fCurrentCaretImage.getBounds().width / 2 + 1, y1); + } + } + } else { + fInsertionCartet.setVisible(false); + } + } + } else { + super.contentsMouseMoveEvent(e); + } + } + + @Override + protected void contentsMouseUpEvent(MouseEvent event) { + // Just in case the diagram highlight a time compression region + // this region need to be released when clicking everywhere + fInsertionCartet.setVisible(false); + if (fDragAndDrop != null) { + if ((fOverView != null) && (!fOverView.isDisposed())) { + fOverView.dispose(); + } + fOverView = null; + Lifeline node = fFrame.getCloserLifeline(fDragX); + if (node != null) { + int rx = Math.round(node.getX() * fZoomValue); + if (rx <= event.x && Math.round(rx + (node.getWidth() * fZoomValue)) >= event.x) { + if ((fCollapseProvider != null) && (fDragAndDrop != node)) { + fCollapseProvider.collapseTwoLifelines(fDragAndDrop, node); + } + } else if (rx < event.x) { + fFrame.insertLifelineAfter(fDragAndDrop, node); + if (node.getIndex() < fFrame.lifeLinesCount()) { + Lifeline temp[] = { fDragAndDrop, fFrame.getLifeline(node.getIndex()) }; + fReorderList.add(temp); + } else { + Lifeline temp[] = { fDragAndDrop, null }; + fReorderList.add(temp); + } + } else { + fFrame.insertLifelineBefore(fDragAndDrop, node); + Lifeline temp[] = { fDragAndDrop, node }; + fReorderList.add(temp); + } + } + } + fDragAndDrop = null; + redraw(); + if (fFrame == null) { + return; + } + fFrame.resetTimeCompression(); + + // reset auto scroll if it's engaged + if (fLocalAutoScroll != null) { + fLocalAutoScroll.cancel(); + fLocalAutoScroll = null; + } + super.contentsMouseUpEvent(event); + } + + @Override + protected void contentsMouseDownEvent(MouseEvent event) { + if (fCurrentGraphNode != null) { + fCurrentGraphNode.setFocused(false); + } + + // Just in case the diagram highlight a time compression region + // this region need to be released when clicking everywhere + if (fFrame == null) { + return; + } + + fFrame.resetTimeCompression(); + + if ((event.stateMask & SWT.CTRL) != 0) { + fCtrlSelection = true; + } else { + fCtrlSelection = false; + } + + if (((fZoomInMode) || (fZoomOutMode)) && (event.button == 1)) { + int cx = Math.round(event.x / fZoomValue); + int cy = Math.round(event.y / fZoomValue); + if (fZoomInMode) { + if (fZoomValue < 64) { + fZoomValue = fZoomValue * (float) 1.25; + } + } else { + fZoomValue = fZoomValue / (float) 1.25; + } + int x = Math.round(cx * fZoomValue - getVisibleWidth() / (float) 2); + int y = Math.round(cy * fZoomValue - getVisibleHeight() / (float) 2); + setContentsPos(x, y); + if (fTimeBar != null) { + fTimeBar.setZoom(fZoomValue); + } + // redraw also resize the scrollView content + redraw(); + } else { + GraphNode node = null; + int x = Math.round(event.x / fZoomValue); + int y = Math.round(event.y / fZoomValue); + node = fFrame.getNodeAt(x, y); + + if ((event.button == 1) || ((node != null) && !node.isSelected())) { + if (!fShiftSelection) { + fListStart = node; + } + if (fShiftSelection) { + clearSelection(); + addSelection(fFrame.getNodeList(fListStart, node)); + } else { + performSelection(node); + } + fCurrentGraphNode = node; + if (node != null) { + node.setFocused(true); + } + } + redraw(); + } + if (fDragAndDrop == null) { + super.contentsMouseDownEvent(event); + } + fIsDragAndDrop = (event.button == 1); + + } + + /** + * TimerTask for auto scroll feature. + */ + protected static class AutoScroll extends TimerTask { + /** + * Field delta x. + */ + public int fDeltaX; + /** + * Field delta y. + */ + public int fDeltaY; + /** + * Field sequence diagram reference. + */ + public SDWidget fSdWidget; + + /** + * Constructor for AutoScroll. + * @param sv sequence diagram widget reference + * @param dx delta x + * @param dy delta y + */ + public AutoScroll(SDWidget sv, int dx, int dy) { + fSdWidget = sv; + fDeltaX = dx; + fDeltaY = dy; + } + + @Override + public void run() { + Display display = Display.getDefault(); + if ((display == null) || (display.isDisposed())) { + return; + } + display.asyncExec(new Runnable() { + @Override + public void run() { + if (fSdWidget.isDisposed()) { + return; + } + fSdWidget.fDragX += fDeltaX; + fSdWidget.fDragY += fDeltaY; + fSdWidget.scrollBy(fDeltaX, fDeltaY); + } + }); + } + } + + @Override + protected void drawContents(GC gc, int clipx, int clipy, int clipw, int cliph) { + if (fFrame == null) { + gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); + gc.fillRectangle(0, 0, getVisibleWidth(), getVisibleHeight()); + gc.dispose(); + return; + } + SDViewPref.getInstance(); + + Rectangle area = getClientArea(); + Image dbuffer = getDrawBuffer(); + int height = Math.round((fFrame.getHeight() + 2 * Metrics.FRAME_V_MARGIN) * fZoomValue); + + try { + gc.drawImage(dbuffer, 0, 0, area.width, area.height, 0, 0, area.width, area.height); + } catch (Exception e) { + Activator.getDefault().logError("Error drawin content", e); //$NON-NLS-1$ + } + dbuffer.dispose(); + setHScrollBarIncrement(Math.round(SDViewPref.getInstance().getLifelineWidth() / (float) 2 * fZoomValue)); + setVScrollBarIncrement(Math.round(Metrics.getMessagesSpacing() * fZoomValue)); + if ((fTimeBar != null) && (fFrame.hasTimeInfo())) { + fTimeBar.resizeContents(9, height + getHorizontalBarHeight()); + fTimeBar.setContentsPos(getContentsX(), getContentsY()); + fTimeBar.redraw(); + fTimeBar.update(); + } + float xRatio = getContentsWidth() / (float) getVisibleWidth(); + float yRatio = getContentsHeight() / (float) getVisibleHeight(); + if (yRatio > xRatio) { + setOverviewSize((int) (getVisibleHeight() * 0.75)); + } else { + setOverviewSize((int) (getVisibleWidth() * 0.75)); + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent event) { + } + + @Override + public void widgetSelected(SelectionEvent event) { + if (event.widget == fZoomIn) { + fZoomValue = fZoomValue * 2; + } else if (event.widget == fZoomOut) { + fZoomValue = fZoomValue / 2; + } + redraw(); + } + + /** + * Called when property changed occurs in the preference page. "PREFOK" is + * fired when the user press the ok or apply button + */ + @Override + public void propertyChange(PropertyChangeEvent e) { + if (fFrame != null && !isDisposed()) { + fFrame.resetTimeCompression(); + } + if (e.getProperty().equals("PREFOK")) //$NON-NLS-1$ + { + // Prepare the overview to be reused for the new + // settings (especially the colors) + if (fOverView != null) { + fOverView.dispose(); + } + fOverView = null; + redraw(); + } + } + + @Override + public void widgetDisposed(DisposeEvent e) { + if (fOverView != null) { + fOverView.dispose(); + } + super.removeDisposeListener(this); + if ((fCurrentCaretImage != null) && (!fCurrentCaretImage.isDisposed())) { + fCurrentCaretImage.dispose(); + } + if ((fArrowUpCaretImg != null) && (!fArrowUpCaretImg.isDisposed())) { + fArrowUpCaretImg.dispose(); + } + if ((fCollapaseCaretImg != null) && (!fCollapaseCaretImg.isDisposed())) { + fCollapaseCaretImg.dispose(); + } + SDViewPref.getInstance().removePropertyChangeListener(this); + LoadersManager lm = LoadersManager.getInstance(); + if (fSite instanceof SDView) { + ((SDView) fSite).resetProviders(); + if (lm != null) { + lm.resetLoader(((SDView) fSite).getViewSite().getId()); + } + } + } + + @Override + protected void drawOverview(GC gc, Rectangle r) { + float oldzoom = fZoomValue; + if (getContentsWidth() > getContentsHeight()) { + fZoomValue = (float) r.width / (float) getContentsWidth() * oldzoom; + } else { + fZoomValue = (float) r.height / (float) getContentsHeight() * oldzoom; + } + if ((fOverView != null) && ((r.width != fOverView.getBounds().width) || (r.height != fOverView.getBounds().height))) { + fOverView.dispose(); + fOverView = null; + } + if (fOverView == null) { + int backX = getContentsX(); + int backY = getContentsY(); + setContentsPos(0, 0); + fOverView = new Image(getDisplay(), r.width, r.height); + GC gcim = new GC(fOverView); + NGC context = new NGC(this, gcim); + context.setBackground(SDViewPref.getInstance().getBackGroundColor(ISDPreferences.PREF_FRAME)); + fFrame.draw(context); + setContentsPos(backX, backY); + gcim.dispose(); + context.dispose(); + } + if ((fOverView != null) && (r.width == fOverView.getBounds().width) && (r.height == fOverView.getBounds().height)) { + gc.drawImage(fOverView, 0, 0, r.width, r.height, 0, 0, r.width, r.height); + } + + fZoomValue = oldzoom; + + super.drawOverview(gc, r); + } + + @Override + public void deltaSelected(Lifeline lifeline, int startEvent, int nbEvent, IColor color) { + fFrame.highlightTimeCompression(lifeline, startEvent, nbEvent, color); + ensureVisible(lifeline); + int y1 = lifeline.getY() + lifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * startEvent; + int y2 = lifeline.getY() + lifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * (startEvent + nbEvent); + ensureVisible(lifeline.getX(), y1 - (Metrics.getLifelineHeaderFontHeigth() + +2 * Metrics.LIFELINE_HEARDER_TEXT_V_MARGIN), lifeline.getWidth(), y2 - y1 + 3, SWT.CENTER | SWT.VERTICAL, true); + redraw(); + update(); + } + + @Override + public int getVisibleWidth() { + if (fIsPrinting) { + return fPrinter.getClientArea().width; + } + return super.getVisibleWidth(); + } + + @Override + public int getVisibleHeight() { + if (fIsPrinting) { + return fPrinter.getClientArea().height; + } + return super.getVisibleHeight(); + } + + @Override + public int contentsToViewX(int x) { + if (fIsPrinting) { + int v = Math.round(fPrinterX * fPrinterZoom); + return x - v; + } + return x - getContentsX(); + } + + @Override + public int contentsToViewY(int y) { + if (fIsPrinting) { + int v = Math.round(fPrinterY * fPrinterZoom); + return y - v; + } + return y - getContentsY(); + } + + @Override + public int getContentsX() { + if (fIsPrinting) { + return Math.round(fPrinterX * fPrinterZoom); + } + return super.getContentsX(); + } + + @Override + public int getContentsY() { + if (fIsPrinting) { + return Math.round(fPrinterY * fPrinterZoom); + } + return super.getContentsY(); + } + + /** + * Traverse Listener implementation. + */ + protected static class LocalTraverseListener implements TraverseListener { + @Override + public void keyTraversed(TraverseEvent e) { + if ((e.detail == SWT.TRAVERSE_TAB_NEXT) || (e.detail == SWT.TRAVERSE_TAB_PREVIOUS)) { + e.doit = true; + } + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/SDWidgetSelectionProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/SDWidgetSelectionProvider.java new file mode 100755 index 0000000000..4dd0c8d011 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/SDWidgetSelectionProvider.java @@ -0,0 +1,88 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; + +/** + *

    + * Informs all registered listeners of graph node selection change in the Frame. + *

    + * + * @version 1.0 + * @author sveyrier + */ +public class SDWidgetSelectionProvider implements ISelectionProvider { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The listener list + */ + private List fListenerList = null; + + /** + * The current selection + */ + private ISelection fCurrentSelection = null; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Standard constructor + */ + protected SDWidgetSelectionProvider() { + fListenerList = new ArrayList<>(); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public void addSelectionChangedListener(ISelectionChangedListener listener) { + if (!fListenerList.contains(listener)) { + fListenerList.add(listener); + } + } + + @Override + public void removeSelectionChangedListener(ISelectionChangedListener listener) { + fListenerList.remove(listener); + } + + @Override + public void setSelection(ISelection selection) { + fCurrentSelection = selection; + for (int i = 0; i < fListenerList.size(); i++) { + ISelectionChangedListener list = fListenerList.get(i); + list.selectionChanged(new SelectionChangedEvent(this, fCurrentSelection)); + } + } + + @Override + public ISelection getSelection() { + return fCurrentSelection; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/ScrollView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/ScrollView.java new file mode 100755 index 0000000000..bf199965b2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/ScrollView.java @@ -0,0 +1,2067 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd; + +import java.util.Timer; +import java.util.TimerTask; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.TypedEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.PaletteData; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.ScrollBar; +import org.eclipse.swt.widgets.Scrollable; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; + +/** + * ScrollView widget provides a scrolling area with on-demand scroll bars. + * Overview scrollable panel can be used (@see setOverviewEnabled()). + * + * @author Eric Miravete + * @version 1.0 + */ +public class ScrollView extends Composite { + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * Scroll bar mode AUTO + */ + public static final int AUTO = 0; + /** + * Scroll bar mode ALWAYS_ON + */ + public static final int ALWAYS_ON = 1; + /** + * Scroll bar mode ALWAYS_OFF + */ + public static final int ALWAYS_OFF = 2; + /** + * Bit mask for visible vertical scroll bar + */ + public static final int VBAR = 0x01; + /** + * Bit mask for visible horizontal scroll bar + */ + public static final int HBAR = 0x02; + + private static final int DEFAULT_H_SCROLL_INCREMENT = 10; + private static final int DEFAULT_V_SCROLL_INCREMENT = 10; + private static final int DEFAULT_AUTO_SCROLL_PERIOD = 75; + private static final int DEFAULT_OVERVIEW_SIZE = 100; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * Value of the contents height property. + */ + private int fContentsHeight = 0; + /** + * Value of the contents width property. + */ + private int fContentsWidth = 0; + /** + * Value of the contents x coordinate property + */ + private int fContentsX = 0; + /** + * Value of the contents y coordinate property + */ + private int fContentsY = 0; + /** + * Scroll bar mode of horizontal scroll bar. + */ + private int fHorScrollbarMode = AUTO; + /** + * Scroll bar mode of vertical scroll bar. + */ + private int fVertScrollbarMode = AUTO; + /** + * Increment for the horizontal scroll bar. + */ + private int fHorScrollbarIncrement = DEFAULT_H_SCROLL_INCREMENT; + /** + * Increment for the vertical scroll bar. + */ + private int fVertScrollbarIncrement = DEFAULT_V_SCROLL_INCREMENT; + /** + * Flag whether auto scroll is enabled or not. + */ + private boolean fAutoScrollEnabled = true; + /** + * Value of the auto scroll period. + */ + private int fAutoScrollPeriod = DEFAULT_AUTO_SCROLL_PERIOD; + /** + * The local paint listener reference. + */ + private PaintListener fLocalPaintListener = null; + /** + * The local mouse move listener reference. + */ + private MouseMoveListener fLocalMouseMoveListener = null; + /** + * The local mouse listener reference. + */ + private MouseListener fLocalMouseListener = null; + /** + * The local control listener reference. + */ + private ControlListener fLocalControlListener = null; + /** + * The local key listener reference. + */ + private KeyListener fLocalKeyListener = null; + // Canvas for vertical/horizontal Scroll Bar only ... because new ScrollBar() does works. + /** + * Canvas for horizontal scroll bar. + */ + private Canvas fHorScrollBar; + /** + * Canvas for vertical scroll bar. + */ + private Canvas fVertScrollBar; + /** + * Canvas for the view control. + */ + private Canvas fViewControl; + /** + * Control used in the bottom right corner @see setCornerControl() and @see setOverviewEnabled(true) + */ + private Control fCornerControl; + /** + * Size of overview widget. + */ + private int fOverviewSize = DEFAULT_OVERVIEW_SIZE; // default size for overview + /** + * Timer for auto_scroll feature + */ + private AutoScroll fAutoScroll = null; + /** + * TimerTask for auto_scroll feature !=null when auto scroll is running + */ + private Timer fAutoScrollTimer = null; + /** + * where mouse down appear on contents area (x coordinate) + */ + private int fMouseDownX = -1; + /** + * where mouse down appear on contents area (y coordinate) + */ + private int fMousDownY = -1; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Create a ScrollView, child of composite c. Both scroll bar have the mode AUTO. Auto scroll feature is enabled + * using a delay of 250ms. Overview feature is not enabled by default (use setOverviewEnabled()). + * + * @param c The parent composite + * @param style The SWT style bits @see SWT + */ + public ScrollView(Composite c, int style) { + this(c, style, true); + } + + /** + * Create a ScrollView, child of composite c. Both scroll bar have the mode AUTO. Auto scroll feature is enabled + * using a delay of 250ms. Overview feature is not enabled by default (use setOverviewEnabled()). + * + * @param c The parent composite. + * @param style The SWT style bits @see SWT + * @param mouseWheel Flag to force scrollView to handles mouse wheel + */ + public ScrollView(Composite c, int style, boolean mouseWheel) { + super(c, SWT.NONE); + + fHorScrollBar = new Canvas(this, SWT.H_SCROLL); + if (mouseWheel) { + // force scroll bar to get mouse wheel, those scrollbar will be hidden + fViewControl = new Canvas(this, style | SWT.H_SCROLL | SWT.V_SCROLL); + } else { + fViewControl = new Canvas(this, style); + } + fViewControl.setBackground(getBackground()); + // hide scroll bar as their are replaced by fHorScrollBar and fVertScrollBar. + if (mouseWheel) { + fViewControl.getVerticalBar().setVisible(false); + fViewControl.getHorizontalBar().setVisible(false); + } + fVertScrollBar = new Canvas(this, SWT.V_SCROLL); + + setLayout(new SVLayout()); + + fLocalPaintListener = new PaintListener() { + @Override + public void paintControl(PaintEvent event) { + // use clipping, to reduce cost of paint. + Rectangle r = event.gc.getClipping(); + int cx = viewToContentsX(r.x); + int cy = viewToContentsY(r.y); + drawContents(event.gc, cx, cy, r.width, r.height); + } + }; + fViewControl.addPaintListener(fLocalPaintListener); + + fLocalMouseMoveListener = new MouseMoveListener() { + @Override + public void mouseMove(MouseEvent e) { + int ox = e.x, oy = e.y; + e.x = viewToContentsX(e.x); + e.y = viewToContentsY(e.y); + contentsMouseMoveEvent(e); + e.x = ox; + e.y = oy; + } + }; + + fViewControl.addMouseMoveListener(fLocalMouseMoveListener); + + MouseTrackListener localMouseTrackListener = new MouseTrackListener() { + @Override + public void mouseEnter(MouseEvent e) { + int ox = e.x, oy = e.y; + e.x = viewToContentsX(e.x); + e.y = viewToContentsY(e.y); + contentsMouseEnter(e); + e.x = ox; + e.y = oy; + } + + @Override + public void mouseHover(MouseEvent e) { + int ox = e.x, oy = e.y; + e.x = viewToContentsX(e.x); + e.y = viewToContentsY(e.y); + contentsMouseHover(e); + e.x = ox; + e.y = oy; + } + + @Override + public void mouseExit(MouseEvent e) { + int ox = e.x, oy = e.y; + e.x = viewToContentsX(e.x); + e.y = viewToContentsY(e.y); + contentsMouseExit(e); + e.x = ox; + e.y = oy; + } + + }; + + fViewControl.addMouseTrackListener(localMouseTrackListener); + + fLocalMouseListener = new MouseListener() { + @Override + public void mouseDoubleClick(MouseEvent e) { + int ox = e.x, oy = e.y; + e.x = viewToContentsX(e.x); + e.y = viewToContentsY(e.y); + contentsMouseDoubleClickEvent(e); + e.x = ox; + e.y = oy; + } + + @Override + public void mouseDown(MouseEvent e) { + int ox = e.x, oy = e.y; + e.x = viewToContentsX(e.x); + fMouseDownX = e.x; + e.y = viewToContentsY(e.y); + fMousDownY = e.y; + contentsMouseDownEvent(e); + e.x = ox; + e.y = oy; + } + + @Override + public void mouseUp(MouseEvent e) { + int ox = e.x, oy = e.y; + e.x = viewToContentsX(e.x); + e.y = viewToContentsY(e.y); + contentsMouseUpEvent(e); + e.x = ox; + e.y = oy; + // here because class extending me can catch mouse Up and want to scroll... + fMouseDownX = -1; + fMousDownY = -1; + } + }; + fViewControl.addMouseListener(fLocalMouseListener); + + fLocalKeyListener = new KeyListener() { + @Override + public void keyPressed(KeyEvent e) { + keyPressedEvent(e); + } + + @Override + public void keyReleased(KeyEvent e) { + keyReleasedEvent(e); + } + }; + + fViewControl.addKeyListener(fLocalKeyListener); + + getVerticalBar().addSelectionListener(new SelectionListener() { + @Override + public void widgetSelected(SelectionEvent e) { + setContentsPos(fContentsX, getVerticalBar().getSelection()); + // need to change "hidden" vertical bar value ? + // force focus on fViewControl so we got future mouse wheel's scroll events + if (!fViewControl.isFocusControl()) { + fViewControl.setFocus(); + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + + if (fViewControl.getVerticalBar() != null) { + // add fViewControl hidden scrollbar listener to get mouse wheel ... + fViewControl.getVerticalBar().addSelectionListener(new SelectionListener() { + @Override + public void widgetSelected(SelectionEvent e) { + ScrollBar b = fViewControl.getVerticalBar(); + setContentsPos(fContentsX, b.getSelection()); + // change "real" vertical bar selection too + getVerticalBar().setSelection(b.getSelection()); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + } + getHorizontalBar().addSelectionListener(new SelectionListener() { + @Override + public void widgetSelected(SelectionEvent e) { + setContentsPos(getHorizontalBar().getSelection(), fContentsY); + // need to change "real" horizontal bar too ? + // force focus on fViewControl so we got future mouse wheel's scroll events + if (!fViewControl.isFocusControl()) { + fViewControl.setFocus(); + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + if (fViewControl.getHorizontalBar() != null) { + fViewControl.getHorizontalBar().addSelectionListener(new SelectionListener() { + @Override + public void widgetSelected(SelectionEvent e) { + ScrollBar b = fViewControl.getHorizontalBar(); + setContentsPos(b.getSelection(), fContentsY); + // change "real" vertical bar selection too + getHorizontalBar().setSelection(b.getSelection()); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + } + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public boolean setFocus() { + return fViewControl.forceFocus(); + } + + @Override + public void setCursor(Cursor cursor) { + fViewControl.setCursor(cursor); + } + + @Override + public void dispose() { + if (fAutoScroll != null) { + fAutoScroll.cancel(); + fAutoScroll = null; + } + if (fViewControl != null) { + fViewControl.dispose(); + } + fViewControl = null; + if (fVertScrollBar != null) { + fVertScrollBar.dispose(); + } + fVertScrollBar = null; + if (fHorScrollBar != null) { + fHorScrollBar.dispose(); + } + fHorScrollBar = null; + if (fCornerControl != null) { + Object data = fCornerControl.getData(); + if (data instanceof Overview) { + ((Overview) data).dispose(); + } + fCornerControl.dispose(); + fCornerControl = null; + } + super.dispose(); + } + + @Override + public Rectangle getClientArea() { + Rectangle area = fViewControl.getClientArea(); + /* Clamp the size of the returned area to 1x1 minimum */ + area.width = Math.max(area.width, 1); + area.height = Math.max(area.height, 1); + return area; + } + + @Override + public void setBackground(Color c) { + super.setBackground(c); + fViewControl.setBackground(c); + } + + @Override + public void setToolTipText(String text) { + fViewControl.setToolTipText(text); + } + + /** + * Draw overview area, @see setOverviewEnabled. By default draw a rectangle corresponding to the visible area of + * scroll view. You can redefine this method to draw the contents as drawContents does... ...in an other magnify + * factor. + * + * @param gc GC to used to draw. + * @param r Rectangle corresponding to the client area of overview. + */ + protected void drawOverview(GC gc, Rectangle r) { + int x = (int) (r.width * fContentsX / (float) fContentsWidth); + int y = (int) (r.height * fContentsY / (float) fContentsHeight); + int vw = getVisibleWidth(); + int vh = getVisibleHeight(); + int w = r.width - 1; + if (fContentsWidth > vw) { + w = (int) (r.width * vw / (float) fContentsWidth); + } + int h = r.height - 1; + if (fContentsHeight > vh) { + h = (int) (r.height * vh / (float) fContentsHeight); + } + + gc.setForeground(getForeground()); + // too small rectangle ? + if (w < 5 || h < 5) { + // use a cross ... + gc.drawLine(x, 0, x, r.height); + gc.drawLine(0, y, r.width, y); + } else { + gc.drawRectangle(x, y, w, h); + } + } + + /** + * Remove the local Listener and add the new listener. + * + * @param nlistener the new listener + */ + public void replaceControlListener(ControlListener nlistener) { + if (fLocalControlListener != null) { + removeControlListener(fLocalControlListener); + fLocalControlListener = null; + } + addControlListener(nlistener); + } + + /** + * Remove the local Listener and add the new listener. + * + * @param nlistener the new listener + */ + public void replaceKeyListener(KeyListener nlistener) { + if (fLocalKeyListener != null) { + removeKeyListener(fLocalKeyListener); + fLocalKeyListener = null; + } + addKeyListener(nlistener); + } + + /** + * Remove the local Listener and add the new listener. + * + * @param nlistener the new listener + */ + public void replaceMouseListener(MouseListener nlistener) { + if (fLocalMouseListener != null) { + removeMouseListener(fLocalMouseListener); + fLocalMouseListener = null; + } + fViewControl.addMouseListener(nlistener); + } + + /** + * Remove the local Listener and add the new listener. + * + * @param nlistener the new listener + */ + public void replaceMouseMoveListener(MouseMoveListener nlistener) { + if (fLocalMouseMoveListener != null) { + removeMouseMoveListener(fLocalMouseMoveListener); + fLocalMouseMoveListener = null; + } + fViewControl.addMouseMoveListener(nlistener); + } + + /** + * Remove the local Listener and add the new listener. + * + * @param nlistener the new listener + */ + public void replacePaintListener(PaintListener nlistener) { + if (fLocalPaintListener != null) { + removePaintListener(fLocalPaintListener); + fLocalPaintListener = null; + } + fViewControl.addPaintListener(nlistener); + } + + /** + * Access method for the contentsHeight property. + * + * @return the current value of the contentsHeight property + */ + public int getContentsHeight() { + return fContentsHeight; + } + + /** + * Access method for the contentsWidth property. + * + * @return the current value of the contentsWidth property + */ + public int getContentsWidth() { + return fContentsWidth; + } + + /** + * Access method for the contentsX property. + * + * @return the current value of the contentsX property + */ + public int getContentsX() { + return fContentsX; + } + + /** + * Access method for the contentsY property. + * + * @return the current value of the contentsY property + */ + public int getContentsY() { + return fContentsY; + } + + /** + * Determines if the dragAutoScroll property is true. + * + * @return true if the dragAutoScroll property is true + */ + public boolean isDragAutoScroll() { + return fAutoScrollEnabled; + } + + /** + * Sets the value of the dragAutoScroll property. + * + * @param aDragAutoScroll the new value of the dragAutoScroll property + */ + public void setDragAutoScroll(boolean aDragAutoScroll) { + fAutoScrollEnabled = aDragAutoScroll; + if (!fAutoScrollEnabled && (fAutoScroll != null)) { + fAutoScroll.cancel(); + fAutoScroll = null; + } + } + + /** + * Change delay (in millisec) used for auto scroll feature. + * + * @param period new period between to auto scroll + */ + public void setDragAutoScrollPeriod(int period) { + fAutoScrollPeriod = Math.max(0, period); + } + + /** + * Return auto scroll period. + * + * @return The period + */ + public int getDragAutoScrollPeriod() { + return fAutoScrollPeriod; + } + + /** + * Access method for the hScrollBarMode property. + * + * @return the current value of the hScrollBarMode property + */ + public int getHScrollBarMode() { + return fHorScrollbarMode; + } + + /** + * Sets the value of the hScrollBarMode property. + * + * @param aHScrollBarMode the new value of the hScrollBarMode property + */ + public void setHScrollBarMode(int aHScrollBarMode) { + fHorScrollbarMode = aHScrollBarMode; + } + + /** + * Access method for the vScrollBarMode property. + * + * @return the current value of the vScrollBarMode property + */ + public int getVScrollBarMode() { + return fVertScrollbarMode; + } + + /** + * Sets the value of the vScrollBarMode property. + * + * @param aVScrollBarMode the new value of the vScrollBarMode property + */ + public void setVScrollBarMode(int aVScrollBarMode) { + fVertScrollbarMode = aVScrollBarMode; + } + + /** + * Return horizontal scroll bar increment, default:1 + * + * @return The increment + */ + public int getHScrollBarIncrement() { + return fHorScrollbarIncrement; + } + + /** + * Return vertical scroll bar increment, default:1 + * + * @return The increment + */ + public int getVScrollBarIncrement() { + return fVertScrollbarIncrement; + } + + /** + * Change horizontal scroll bar increment, minimum:1. Page increment is + * always set to visible width. + * + * @param inc + * Increment value to set + */ + public void setHScrollBarIncrement(int inc) { + fHorScrollbarIncrement = Math.max(1, inc); + } + + /** + * Change vertical scroll bar increment, minimum:1. Page increment is always + * set to visible height. + * + * @param inc + * Increment value to set + */ + public void setVScrollBarIncrement(int inc) { + fVertScrollbarIncrement = Math.max(1, inc); + } + + /** + * Enable or disable overview feature. Enabling overview, dispose and replace existing corner control by a button. + * Clicking in it open overview, move mouse cursor holding button to move scroll view and release button to hide + * overview. Tip: hold control and/or shift key while moving mouse when overview is open made fine scroll. + * + * @param value true to engage overview feature + */ + public void setOverviewEnabled(boolean value) { + if (isOverviewEnabled() == value) { + return; + } + + Control cc = null; + if (value) { + Button b = new Button(this, SWT.NONE); + b.setText("+"); //$NON-NLS-1$ + Overview ovr = new Overview(); + ovr.useControl(b); + b.setData(ovr); + cc = b; + b.setToolTipText(Messages.SequenceDiagram_OpenOverviewTooltip); + } + setCornerControl(cc); + } + + /** + * Change overview size (at ratio 1:1), default is 100 + * + * @param size + * The new size + */ + public void setOverviewSize(int size) { + fOverviewSize = Math.abs(size); + } + + /** + * Returns whether the overview is enabled or not. + * + * @return true is overview feature is enabled + */ + public boolean isOverviewEnabled() { + if (fCornerControl instanceof Button) { + Object data = ((Button) fCornerControl).getData(); + // overview alreay + if (data instanceof Overview) { + return true; + } + } + return false; + } + + /** + * Returns the overview size at ratio 1:1. + * + * @return current overview size at ratio 1:1 + */ + public int getOverviewSize() { + return fOverviewSize; + } + + /** + * Returns control used to display view (might not be this object). Use this control to add/remove listener on the + * draw area. + * + * @return control used to display view (might not be this object). + */ + public Control getViewControl() { + return fViewControl; + } + + /** + * Called when the mouse enter the ScrollView area + * + * @param e + * Mouse event + */ + protected void contentsMouseExit(MouseEvent e) { + } + + /** + * Called when the mouse enter the ScrollView area after and system defined + * time + * + * @param e + * Mouse event + */ + protected void contentsMouseHover(MouseEvent e) { + } + + /** + * Called when the mouse enter the ScrollView area + * + * @param e + * Mouse event + */ + protected void contentsMouseEnter(MouseEvent e) { + } + + /** + * Called when user double on contents area. + * + * @param e + * Mouse event + */ + protected void contentsMouseDoubleClickEvent(MouseEvent e) { + } + + /** + * Called when mouse is on contents area and button is pressed. + * + * @param e + * Mouse event + */ + protected void contentsMouseDownEvent(MouseEvent e) { + fMouseDownX = e.x; + fMousDownY = e.y; + } + + /** + * TimerTask for auto scroll feature. + */ + protected static class AutoScroll extends TimerTask { + + /** X delta */ + private int deltaX; + + /** Y delta */ + private int deltaY; + + /** ScrollView object */ + private ScrollView scrollView; + + /** + * Constructor. + * + * @param sv + * ScrollView object to use + * @param dx + * X delta + * @param dy + * Y delta + */ + public AutoScroll(ScrollView sv, int dx, int dy) { + scrollView = sv; + deltaX = dx; + deltaY = dy; + } + + @Override + public void run() { + final Display display = Display.getDefault(); + if ((display == null) || display.isDisposed()) { + return; + } + display.asyncExec(new Runnable() { + @Override + public void run() { + if (!scrollView.isDisposed()) { + scrollView.scrollBy(deltaX, deltaY); + } + } + }); + } + } + + /** + * Called when mouse is on contents area and mode. + * + * @param event + * Mouse event + */ + protected void contentsMouseMoveEvent(MouseEvent event) { + if ((event.stateMask & SWT.BUTTON_MASK) != 0) { + if (!fAutoScrollEnabled) { + scrollBy(-(event.x - fMouseDownX), -(event.y - fMousDownY)); + return; + } + + int sx = 0, sy = 0; + + int vRight = getContentsX() + getVisibleWidth(); + int vBottom = getContentsY() + getVisibleHeight(); + + // auto scroll... ? + if (event.x < getContentsX()) { + sx = (getContentsX() - event.x); + fMouseDownX = getContentsX(); + } else if (event.x > vRight) { + sx = -event.x + vRight; + fMouseDownX = vRight; + } + if (event.y < getContentsY()) { + sy = (getContentsY() - event.y); + fMousDownY = getContentsY(); + } else if (event.y > vBottom) { + sy = -event.y + vBottom; + fMousDownY = vBottom; + } + + if (sx != 0 || sy != 0) { + // start auto scroll... + if (fAutoScroll == null) { + if (fAutoScrollTimer == null) { + fAutoScrollTimer = new Timer(true); + } + fAutoScroll = new AutoScroll(this, sx, sy); + fAutoScrollTimer.schedule(fAutoScroll, 0, fAutoScrollPeriod); + } else { + fAutoScroll.deltaX = sx; + fAutoScroll.deltaY = sy; + } + } else { + if (fAutoScroll != null) { + fAutoScroll.cancel(); + fAutoScroll = null; + } + + scrollBy(-(event.x - fMouseDownX), -(event.y - fMousDownY)); + } + } + } + + /** + * Called when mouse is on contents area and button is released + * + * @param event + * Mouse event + */ + protected void contentsMouseUpEvent(MouseEvent event) { + // reset auto scroll if it's engaged + if (fAutoScroll != null) { + fAutoScroll.cancel(); + fAutoScroll = null; + } + } + + /** + * Responsible to draw contents area. At least rectangle clipX must be + * redrawn. This rectangle is given in contents coordinates. By default, no + * paint is produced. + * + * @param gc + * Graphics context + * @param clipx + * X clip + * @param clipy + * Y clip + * @param clipw + * W clip + * @param cliph + * H clip + */ + protected void drawContents(GC gc, int clipx, int clipy, int clipw, int cliph) { + } + + /** + * Change the size of the contents area. + * + * @param width new width of the area. + * @param height new height of the area. + */ + public void resizeContents(int width, int height) { + int localWidth = width; + int localHeight = height; + + if (localWidth < 0) { + localWidth = 0; + } + if (localHeight < 0) { + localHeight = 0; + } + + int oldW = fContentsWidth; + int oldH = fContentsHeight; + + if (localWidth == oldW && localHeight == oldH) { + return; + } + + fContentsWidth = localWidth; + fContentsHeight = localHeight; + + if (oldW > localWidth) { + int s = localWidth; + localWidth = oldW; + oldW = s; + } + + int visWidth = getVisibleWidth(); + int visHeight = getVisibleHeight(); + if (oldW < visWidth) { + if (localWidth > visWidth) { + localWidth = visWidth; + } + fViewControl.redraw(getContentsX() + oldW, 0, localWidth - oldW, visHeight, true); + } + + if (oldH > localHeight) { + int s = localHeight; + localHeight = oldH; + oldH = s; + } + + if (oldH < visHeight) { + if (localHeight > visHeight) { + localHeight = visHeight; + } + fViewControl.redraw(0, getContentsY() + oldH, visWidth, localHeight - oldH, true); + } + if (updateScrollBarVisiblity()) { + layout(); + } else { + updateScrollBarsValues(); + } + } + + // redefined for internal use .. + @Override + public void redraw() { + super.redraw(); + // ..need to redraw this already: + fViewControl.redraw(); + } + + /** + * @param delataX The delta in X + * @param deltaY the delta in Y + */ + public void scrollBy(int delataX, int deltaY) { + setContentsPos(getContentsX() + delataX, getContentsY() + deltaY); + } + + /** + * Scroll to ensure point(in contents coordinates) is visible. + * + * @param px Point's x position + * @param py Point's y position + */ + public void ensureVisible(int px, int py) { + int cx = getContentsX(), cy = getContentsY(); + int right = getContentsX() + getVisibleWidth(); + int bottom = getContentsY() + getVisibleHeight(); + if (px < getContentsX()) { + cx = px; + } else if (px > right) { + cx = px - getVisibleWidth(); + } + if (py < getContentsY()) { + cy = py; + } else if (py > bottom) { + cy = py - getVisibleHeight(); + } + setContentsPos(cx, cy); + } + + /** + * Make rectangle (x,y,w,h, in contents coordinates) visible. if rectangle cannot be completely visible, use + * align flags. + * + * @param xValue x contents coordinates of rectangle. + * @param yValue y contents coordinates of rectangle. + * @param width width of rectangle. + * @param height height of rectangle. + * @param align bit or'ed SWT flag like SWT.LEFT,RIGHT,CENTER,TOP,BOTTOM,VERTICAL used only for bigger rectangle + * than visible area. By default CENTER/VERTICAL + */ + public void ensureVisible(int xValue, int yValue, int width, int height, int align) { + ensureVisible(xValue, yValue, width, height, align, false); + } + + /** + * Make rectangle (xValue,yValue,width,height, in contents coordinates) visible. if rectangle cannot be completely visible, use + * align flags. + * + * @param xValue x contents coordinates of rectangle. + * @param yValue y contents coordinates of rectangle. + * @param width width of rectangle. + * @param height height of rectangle. + * @param align bit or'ed SWT flag like SWT.LEFT,RIGHT,CENTER,TOP,BOTTOM,VERTICAL used only for bigger rectangle + * than visible area. By default CENTER/VERTICAL + * @param forceAlign force alignment for rectangle smaller than the visible area + */ + protected void ensureVisible(int xValue, int yValue, int width, int height, int align, boolean forceAlign) { + + int localX = xValue; + int localY = yValue; + int localWidth = width; + int localHeight = height; + + if (localWidth < 0) { + localX = localX + localWidth; + localWidth = -localWidth; + } + if (localHeight < 0) { + localY = localY + localHeight; + localHeight = -localHeight; + } + int hbar = getHorizontalBarHeight(); + int vbar = getVerticalBarWidth(); + int cx = getContentsX(); + int cy = getContentsY(); + int right = getContentsX() + getVisibleWidth() - vbar; + int bottom = getContentsY() + getVisibleHeight() - hbar; + boolean alignH = false, alignV = false; + + if (localX < getContentsX()) { + cx = localX; + } else if (localX + localWidth > right) { + cx = localX - localWidth; + } + if (localY < getContentsY()) { + cy = localY; + } else if (localY + localHeight > bottom) { + cy = localY - localHeight; + } + + if (localWidth > getVisibleWidth()) { + alignH = true; + } + if (localHeight > getVisibleHeight()) { + alignV = true; + } + // compute alignment on visible area horizontally + if (alignH || (forceAlign && localX + localWidth > right)) { + // use align flags + if ((align & SWT.LEFT) != 0) { + cx = localX; + } else if ((align & SWT.RIGHT) != 0) { + cx = right - localWidth; + } else { // center + cx = localX + (localWidth - getVisibleWidth()) / 2; + } + } + // compute alignment on visible area vertically + if (alignV || (forceAlign && localY + localHeight > bottom)) { + // use align flags + if ((align & SWT.TOP) != 0) { + cy = localY; + } else if ((align & SWT.BOTTOM) != 0) { + cy = bottom - localHeight; + } else { // center + cy = localY + (localHeight - getVisibleHeight()) / 2; + } + } + setContentsPos(cx, cy); + } + + /** + * Returns true if point is visible (expressed in contents coordinates). + * + * @param px Point's x position + * @param py Point's y position + * @return true if point is visible (expressed in contents coordinates) + */ + public boolean isVisible(int px, int py) { + if (px < getContentsX()) { + return false; + } + if (py < getContentsY()) { + return false; + } + if (px > (getContentsX() + getVisibleWidth())) { + return false; + } + if (py > (getContentsY() + getVisibleHeight())) { + return false; + } + return true; + } + + /** + * Returns true if rectangle if partially visible. + * + * @param xValue x contents coordinates of rectangle. + * @param yValue y contents coordinates of rectangle. + * @param width width of rectangle. + * @param height height of rectangle. + * @return true if rectangle if partially visible. + */ + public boolean isVisible(int xValue, int yValue, int width, int height) { + if (xValue + width < getContentsX()) { + return false; + } + if (yValue + height < getContentsY()) { + return false; + } + int vr = getContentsX() + getVisibleWidth(); + int vb = getContentsY() + getVisibleHeight(); + if (xValue > vr) { + return false; + } + if (yValue > vb) { + return false; + } + return true; + } + + /** + * Returns visible part of rectangle, or null if rectangle is not visible. + * Rectangle is expressed in contents coordinates. + * + * @param xValue + * x contents coordinates of rectangle. + * @param yValue + * y contents coordinates of rectangle. + * @param width + * width of rectangle. + * @param height + * height of rectangle. + * @return visible part of rectangle, or null if rectangle is not visible. + */ + public Rectangle getVisiblePart(int xValue, int yValue, int width, int height) { + if (xValue + width < getContentsX()) { + return null; + } + if (yValue + height < getContentsY()) { + return null; + } + int vr = getContentsX() + getVisibleWidth(); + int vb = getContentsY() + getVisibleHeight(); + if (xValue > vr) { + return null; + } + if (yValue > vb) { + return null; + } + int rr = xValue + width, rb = yValue + height; + int nl = Math.max(xValue, getContentsX()), nt = Math.max(yValue, getContentsY()), nr = Math.min(rr, vr), nb = Math.min(rb, vb); + return new Rectangle(nl, nt, nr - nl, nb - nt); + } + + /** + * Returns the visible part for given rectangle. + * + * @param rect A rectangle + * + * @return gets visible part of rectangle (or null) + */ + public final Rectangle getVisiblePart(Rectangle rect) { + if (rect == null) { + return null; + } + return getVisiblePart(rect.x, rect.y, rect.width, rect.height); + } + + /** + * Change top left position of visible area. Check if the given point is inside contents area. + * + * @param xValue x contents coordinates of visible area. + * @param yValue y contents coordinates of visible area. + * @return true if view really moves + */ + public boolean setContentsPos(int xValue, int yValue) { + int nx = xValue, ny = yValue; + if (getVisibleWidth() >= getContentsWidth()) { + nx = 0; + } else { + if (xValue < 0) { + nx = 0; + } else if (xValue + getVisibleWidth() > getContentsWidth()) { + nx = getContentsWidth() - getVisibleWidth(); + } + } + if (getVisibleHeight() >= getContentsHeight()) { + ny = 0; + } else { + if (yValue <= 0) { + ny = 0; + } else if (yValue + getVisibleHeight() > getContentsHeight()) { + ny = getContentsHeight() - getVisibleHeight(); + } + } + // no move + if (nx == fContentsX && ny == fContentsY) { + return false; + } + fContentsX = nx; + fContentsY = ny; + updateScrollBarsValues(); + // ? find smallest area to redraw only them ? + fViewControl.redraw(); + return true; + } + + @Override + public ScrollBar getVerticalBar() { + return fVertScrollBar.getVerticalBar(); + } + + @Override + public ScrollBar getHorizontalBar() { + return fHorScrollBar.getHorizontalBar(); + } + + /** + * Compute visibility of vertical/horizontal bar using given width/height and current visibility (i.e. is bar size are already in + * for_xxx) + * @param forWidth width of foreground + * @param forHeight height of foreground + * @param currHorVis The current visibility state of horizontal scroll bar + * @param currVertvis The current visibility state of vertical scroll bar + * @return true if visibility changed else false + */ + public int computeBarVisibility(int forWidth, int forHeight, boolean currHorVis, boolean currVertvis) { + + int localForWidth = forWidth; + int vis = 0x00; + switch (fVertScrollbarMode) { + case ALWAYS_OFF: + break; + case ALWAYS_ON: + vis |= VBAR; + break; + case AUTO: + if (getContentsHeight() > forHeight) { + vis = VBAR; + // v bar size is already in for_width. + if (!currVertvis) {// (curr_vis&0x01)==0) + localForWidth -= getVerticalBarWidth(); + } + } + break; + default: + break; + } + + switch (fHorScrollbarMode) { + case ALWAYS_OFF: + break; + case ALWAYS_ON: + vis |= HBAR; + break; + case AUTO: + if (getContentsWidth() > localForWidth) { + vis |= HBAR; + // h bar is not in for_height + if ((!currHorVis) && (getContentsHeight() > (forHeight - getHorizontalBarHeight()))) {// (curr_vis&0x02)==0 ) + vis |= VBAR; + } + } + break; + default: + break; + } + return vis; + } + + /** + * Setup scroll bars visibility. + * + * @return True if one of visibility changed. + */ + protected boolean updateScrollBarVisiblity() { + boolean change = false; + + boolean currVertVis = fVertScrollBar.getVisible(); + boolean currHorVis = fHorScrollBar.getVisible(); + int barNewVis = computeBarVisibility(getVisibleWidth(), getVisibleHeight(), currHorVis, currVertVis); + boolean newVertVis = (barNewVis & VBAR) != 0; + boolean newHorVis = (barNewVis & HBAR) != 0; + if (currVertVis ^ newVertVis) { // vertsb_.getVisible() ) + fVertScrollBar.setVisible(newVertVis); + change = true; + } + if (currHorVis ^ newHorVis) { + fHorScrollBar.setVisible(newHorVis); + change = true; + } + + // update corner control visibility: + if (fCornerControl != null && change) { + boolean vis = newVertVis || newHorVis; + if (vis ^ fCornerControl.getVisible()) { + fCornerControl.setVisible(vis); + change = true; // but must be already the case + } + } + return change; + } + + /** + * Setup scroll bar using contents, visible and scroll bar mode properties. + */ + protected void updateScrollBarsValues() { + /* update vertical scrollbar */ + ScrollBar b = getVerticalBar(); + if (b != null) { + b.setMinimum(0); + b.setMaximum(getContentsHeight()); + b.setThumb(getVisibleHeight()); + b.setPageIncrement(getVisibleHeight()); + b.setIncrement(fVertScrollbarIncrement); + b.setSelection(getContentsY()); + } + + // update "hidden" vertical bar too + b = fViewControl.getVerticalBar(); + if (b != null) { + b.setMinimum(0); + b.setMaximum(getContentsHeight()); + b.setThumb(getVisibleHeight()); + b.setPageIncrement(getVisibleHeight()); + b.setIncrement(fVertScrollbarIncrement); + b.setSelection(getContentsY()); + } + + /* update horizontal scrollbar */ + b = getHorizontalBar(); + if (b != null) { + b.setMinimum(0); + b.setMaximum(getContentsWidth()); + b.setThumb(getVisibleWidth()); + b.setSelection(getContentsX()); + b.setPageIncrement(getVisibleWidth()); + b.setIncrement(fHorScrollbarIncrement); + } + // update "hidden" horizontal bar too + b = fViewControl.getHorizontalBar(); + if (b != null) { + b.setMinimum(0); + b.setMaximum(getContentsWidth()); + b.setThumb(getVisibleWidth()); + b.setSelection(getContentsX()); + b.setPageIncrement(getVisibleWidth()); + b.setIncrement(fHorScrollbarIncrement); + } + } + + /** + * Change the control used in the bottom right corner (between two scrollbar), if control is null reset previous + * corner control. This control is visible only if at least one scrollbar is visible. Given control will be disposed + * by ScrollView, at dispose() time, at next setCornetControl() call or when calling setOverviewEnabled(). Pay + * attention calling this reset overview feature until setOverviewEnabled(true) if called. + * @param control The control for the overview + */ + public void setCornerControl(Control control) { + if (fCornerControl != null) { + fCornerControl.dispose(); + } + fCornerControl = control; + if (fCornerControl != null) { + ScrollBar vb = getVerticalBar(); + ScrollBar hb = getHorizontalBar(); + boolean vis = vb.getVisible() || hb.getVisible(); + fCornerControl.setVisible(vis); + } + } + + /** + * Transform (x,y) point in widget coordinates to contents coordinates. + * + * @param x The x widget coordinate. + * @param y The y widget coordinate. + * @return org.eclipse.swt.graphics.Point with content coordinates. + */ + public final Point viewToContents(int x, int y) { + return new Point(viewToContentsX(x), viewToContentsY(y)); + } + + /** + * Transform x in widget coordinates to contents coordinates + * + * @param x The y widget coordinate. + * @return the x content coordinate. + */ + public int viewToContentsX(int x) { + return fContentsX + x; + } + + /** + * Transform y in widget coordinates to contents coordinates + * + * @param y The y widget coordinate. + * @return the y content coordinate. + */ + public int viewToContentsY(int y) { + return fContentsY + y; + } + + /** + * Transform (x,y) point from contents coordinates, to widget coordinates. + * + * @param x The x content coordinate. + * @param y The y content coordinate. + * @return coordinates widget area as. + */ + public final Point contentsToView(int x, int y) { + return new Point(contentsToViewX(x), contentsToViewY(y)); + } + + /** + * Transform X axis coordinates from contents to widgets. + * + * @param x contents coordinate to transform. + * @return x coordinate in widget area + */ + public int contentsToViewX(int x) { + return x - fContentsX; + } + + /** + * Transform Y axis coordinates from contents to widgets. + * + * @param y contents coordinate to transform + * @return y coordinate in widget area + */ + public int contentsToViewY(int y) { + return y - fContentsY; + } + + /** + * Return the visible height of scroll view, might be > contentsHeight + * + * @return the visible height of scroll view, might be > contentsHeight() + */ + public int getVisibleHeight() { + return fViewControl.getClientArea().height; + } + + /** + * Return int the visible width of scroll view, might be > contentsWidth(). + * + * @return int the visible width of scroll view, might be > contentsWidth() + */ + public int getVisibleWidth() { + return fViewControl.getClientArea().width; + } + + /** + * Add support for arrow key, scroll the ... scroll view. But you can + * redefine this method for your convenience. + * + * @param event + * Keyboard event + */ + protected void keyPressedEvent(KeyEvent event) { + switch (event.keyCode) { + case SWT.ARROW_UP: + scrollBy(0, -getVisibleHeight()); + break; + case SWT.ARROW_DOWN: + scrollBy(0, +getVisibleHeight()); + break; + case SWT.ARROW_LEFT: + scrollBy(-getVisibleWidth(), 0); + break; + case SWT.ARROW_RIGHT: + scrollBy(+getVisibleWidth(), 0); + break; + default: + break; + } + } + + /** + * Redefine this method at your convenience + * + * @param event The key event. + */ + protected void keyReleasedEvent(KeyEvent event) { + } + + /** + * Returns vertical bar width, even if bar isn't visible. + * + * @return vertical bar width, even if bar isn't visible + */ + public int getVerticalBarWidth() { + // include vertical bar width and trimming of scrollable used + int bw = fVertScrollBar.computeTrim(0, 0, 0, 0).width; + return bw + 1; + } + + /** + * Returns horizontal bar height even if bar isn't visible. + * + * @return horizontal bar height even if bar isn't visible + */ + public int getHorizontalBarHeight() { + // include horiz. bar height and trimming of scrollable used + int bh = fHorScrollBar.computeTrim(0, 0, 0, 0).height; + // +1 because win32 H.bar need 1 pixel canvas size to appear ! (strange no ?) + return bh + 1; + } + + @Override + public Rectangle computeTrim(int x, int y, int w, int h) { + Rectangle r = new Rectangle(x, y, w, h); + int barVis = computeBarVisibility(w, h, false, false); + if ((barVis & VBAR) != 0) { + r.width += getVerticalBarWidth(); + } + if ((barVis & HBAR) != 0) { + r.height += getHorizontalBarHeight(); + } + return r; + } + + /** + * Internal layout for ScrollView, handle scrollbars, drawzone and corner control + */ + protected class SVLayout extends Layout { + + private static final int DEFAULT_X = 250; + private static final int DEFAULT_Y = 250; + private static final int MAX_SEEK = 10; + private static final int MIN_SEEK = 0; + + /** + * The seek value + */ + private int seek = 0; + /** + * The do-it-not flag + */ + private boolean dontLayout = false; + + @Override + protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { + Point p = new Point(DEFAULT_X, DEFAULT_Y); + if (fContentsWidth < p.x) { + p.x = fContentsWidth; + } + if (fContentsHeight < p.y) { + p.y = fContentsHeight; + } + return p; + } + + @Override + protected void layout(Composite composite, boolean flushCache) { + if (dontLayout) { + return; + } + seek++; + if (seek > MAX_SEEK) { + dontLayout = true; + } + + Point cs = composite.getSize(); + int barVis = computeBarVisibility(cs.x, cs.y, false, false); + boolean vbVis = (barVis & VBAR) != 0; + boolean hbVis = (barVis & HBAR) != 0; + fVertScrollBar.setVisible(vbVis); + fHorScrollBar.setVisible(hbVis); + int vbw = getVerticalBarWidth(); + int hbh = getHorizontalBarHeight(); + int wb = vbVis ? vbw : 0; + int hb = hbVis ? hbh : 0; + int cww = 0, cwh = 0; + + if (fCornerControl != null && (vbVis || hbVis)) { // corner_control_.getVisible()) + fCornerControl.setVisible(true); + cww = vbw; + cwh = hbh; + if (wb == 0) { + wb = vbw; + } + if (hb == 0) { + hb = hbh; + } + } else if (vbVis && hbVis) { + if (fCornerControl != null) { + fCornerControl.setVisible(false); + } + cww = vbw; + cwh = hbh; + } + if (vbVis || hbVis) { + updateScrollBarsValues(); + } + + int vw = cs.x - (vbVis ? vbw : 0); + int vh = cs.y - (hbVis ? hbh : 0); + int vbx = cs.x - wb; + int hby = cs.y - hb; + + fViewControl.setBounds(0, 0, vw, vh); + + if (vbVis) { + fVertScrollBar.setBounds(vbx, 0, wb, cs.y - cwh); + } + if (hbVis) { + fHorScrollBar.setBounds(0, hby, cs.x - cww, hb); + } + if (fCornerControl != null && fCornerControl.getVisible()) { + fCornerControl.setBounds(vbx, hby, vbw, hbh); + } + updateScrollBarsValues(); + + seek--; + if (seek == MIN_SEEK) { + dontLayout = false; + } + } + + boolean isDontLayout() { + return dontLayout; + } + + void setSontLayout(boolean dontLayout) { + this.dontLayout = dontLayout; + } + } + + // static must take place here... cursor is created once. + private volatile static Cursor fOverviewCursor; + + /** Support for click-and-see overview shell on this ScrollView */ + protected class Overview { + + private static final int REFRESH_FREQ = 4; + + /** + * factor for X from real and overview sizes, for mouse move speed. + */ + private float fOverviewFactorX; + + /** + * factor for Y from real and overview sizes, for mouse move speed. + */ + private float fOverviewFactorY; + /** + * shell use to show overview + */ + private Shell fOverview; + /** + * save mouse X cursor location for disappear(); + */ + private int fSaveCursorX; + /** + * save mouse Y cursor location for disappear(); + */ + private int fSaveCursorY; + + /** + * Apply overview support on a control. Replace existing corner_widget + * + * @param control + * The control to use + */ + public void useControl(Control control) { + final Point pos = control.getLocation(); + control.addMouseListener(new MouseListener() { + @Override + public void mouseDoubleClick(MouseEvent e) { + } + + @Override + public void mouseDown(MouseEvent e) { + overviewAppear(e.x, e.y); + } + + @Override + public void mouseUp(MouseEvent e) { + overviewDisappear(); + } + }); + + control.addFocusListener(new FocusListener() { + + @Override + public void focusGained(FocusEvent e) { + } + + @Override + public void focusLost(FocusEvent e) { + if (overviewing()) { + overviewDisappear(false); + } + } + + }); + control.addKeyListener(new KeyListener() { + + @Override + public void keyPressed(KeyEvent event) { + if (event.keyCode == 32 && !overviewing()) { + overviewAppear(pos.x, pos.y); + } else if (event.keyCode == 32) { + overviewDisappear(); + } + if (event.keyCode == SWT.ARROW_DOWN) { + overviewMove(0, 1, event); + } + + if (event.keyCode == SWT.ARROW_UP) { + overviewMove(0, -1, event); + } + + if (event.keyCode == SWT.ARROW_RIGHT) { + overviewMove(1, 0, event); + } + + if (event.keyCode == SWT.ARROW_LEFT) { + overviewMove(-1, 0, event); + } + } + + @Override + public void keyReleased(KeyEvent e) { + } + }); + control.addMouseMoveListener(new MouseMoveListener() { + private int refReshCount = 0; + @Override + public void mouseMove(MouseEvent event) { + if (overviewing()) { + // Slow down the refresh + if (refReshCount % REFRESH_FREQ == 0) { + overviewMove(event); + } + refReshCount++; + } + } + }); + } + + /** + * Dispose controls of overview + */ + public void dispose() { + if (fOverview != null) { + fOverview.dispose(); + } + } + + /** + * @return true if overview is currently on screen + */ + protected boolean overviewing() { + return (fOverview != null && fOverview.isVisible()); + } + + /** + * Process overview appear + * + * @param mx + * X coordinate + * @param my + * Y coordinate + */ + protected void overviewAppear(int mx, int my) { + if (fOverview == null) { + fOverview = new Shell(getShell(), SWT.ON_TOP | SWT.NO_BACKGROUND); + fOverview.addPaintListener(new PaintListener() { + @Override + public void paintControl(PaintEvent e) { + drawOverview(e.gc, fOverview.getClientArea()); + } + }); + } + // always the same.. + fOverview.setForeground(fViewControl.getForeground()); + + // get location of shell (in screeen coordinates) + Point p = toGlobalCoordinates(fCornerControl, 0, 0); + int x = p.x; + int y = p.y; + int w, h; + h = fOverviewSize; + w = h; + Rectangle scr = getDisplay().getBounds(); + Point ccs = fCornerControl.getSize(); + try { + if (fContentsWidth > fContentsHeight) { + float ratio = fContentsHeight / (float) fContentsWidth; + h = (int) (w * ratio); + if (h < ccs.y) { + h = ccs.y; + } else if (h >= scr.height / 2) { + h = scr.height / 2; + } + } else { + float ratio = fContentsWidth / (float) fContentsHeight; + w = (int) (h * ratio); + if (w < ccs.x) { + w = ccs.x; + } else if (w >= scr.width / 2) { + w = scr.width / 2; + } + } + fOverviewFactorX = fContentsWidth / (float) w; + fOverviewFactorY = fContentsHeight / (float) h; + } + // no contents size set ? + catch (java.lang.ArithmeticException e) { + } + + // try pop-up on button, extending to bottom right, + if (x <= 0) { + x = 1; + } + if (y <= 0) { + y = 1; + } + x = x - w + ccs.x; + y = y - h + ccs.y; + fOverview.setBounds(x, y, w, h); + fOverview.setVisible(true); + fOverview.redraw(); + // mouse cursor disappear, so set invisible mouse cursor ... + if (fOverviewCursor == null) { + RGB rgb[] = { new RGB(0, 0, 0), new RGB(255, 0, 0) }; + PaletteData palette = new PaletteData(rgb); + int s = 1; + byte src[] = new byte[s * s]; + byte msk[] = new byte[s * s]; + for (int i = 0; i < s * s; ++i) { + src[i] = (byte) 0xFF; + } + ImageData i_src = new ImageData(s, s, 1, palette, 1, src); + ImageData i_msk = new ImageData(s, s, 1, palette, 1, msk); + fOverviewCursor = new Cursor(null, i_src, i_msk, 0, 0); + } + fCornerControl.setCursor(fOverviewCursor); + // convert to global coordinates + p = toGlobalCoordinates(fCornerControl, mx, my); + fSaveCursorX = p.x; + fSaveCursorY = p.y; + + Rectangle r = fOverview.getClientArea(); + int cx = (int) (r.width * fContentsX / (float) fContentsWidth); + int cy = (int) (r.height * fContentsY / (float) fContentsHeight); + + // cx,cy to display's global coordinates + p = toGlobalCoordinates(fOverview.getParent(), cx, cy); + } + + /** + * Process disappear of overview + */ + protected void overviewDisappear() { + overviewDisappear(true); + } + + /** + * Process disappear of overview + * @param restoreCursorLoc A flag to restore cursor location + */ + protected void overviewDisappear(boolean restoreCursorLoc) { + if (fOverview == null) { + return; + } + fOverview.setVisible(false); + fCornerControl.setCursor(null); + if (restoreCursorLoc) { + getDisplay().setCursorLocation(fSaveCursorX, fSaveCursorY); + } + fOverview.dispose(); + fOverview = null; + } + + /** + * Process mouse move in overview + * @param event The mouse event + */ + protected void overviewMove(MouseEvent event) { + Point p = toGlobalCoordinates(fCornerControl, event.x, event.y); + int dx = p.x - fSaveCursorX; + int dy = p.y - fSaveCursorY; + overviewMove(dx, dy, event); + } + + /** + * Process mouse move event when overviewing + * + * @param dx The x coordinates delta + * @param dy The y coordinates delta + * @param event The typed event + */ + protected void overviewMove(int dx, int dy, TypedEvent event) { + boolean ctrl = false; + boolean shift = false; + + if (event instanceof MouseEvent) { + MouseEvent e = (MouseEvent) event; + getDisplay().setCursorLocation(fSaveCursorX, fSaveCursorY); + ctrl = (e.stateMask & SWT.CONTROL) != 0; + shift = (e.stateMask & SWT.SHIFT) != 0; + } else if (event instanceof KeyEvent) { + KeyEvent e = (KeyEvent) event; + ctrl = (e.stateMask & SWT.CONTROL) != 0; + shift = (e.stateMask & SWT.SHIFT) != 0; + } + + int cx = fContentsX; + int cy = fContentsY; + float fx = fOverviewFactorX; + float fy = fOverviewFactorY; + + if (ctrl && shift) { + if ((fx * 0.25f > 1) && (fy * 0.25 > 1)) { + fx = fy = 1.0f; + } else { + fx *= 0.1f; + fy *= 0.1f; + } + } else if (ctrl) { + fx *= 0.5f; + fy *= 0.5f; + } else if (shift) { + fx *= 0.5f; + fy *= 0.5f; + } + scrollBy((int) (fx * dx), (int) (fy * dy)); + if (cx != fContentsX || cy != fContentsY) { + fOverview.redraw(); + fOverview.update(); // draw now ! + } + } + + /** + * Convert overview coordinates to global coordinates. + * + * @param loc + * the control reference + * @param x + * The x coordinate to convert + * @param y + * The y coordinate to convert + * @return The new converted Point + */ + protected Point toGlobalCoordinates(Control loc, int x, int y) { + Point p = new Point(x, y); + for (Control c = loc; c != null; c = c.getParent()) { + // control might have client area with 'decorations' + int trimX = 0, trimY = 0; + // other kind of widget with trimming ?? + if (c instanceof Scrollable) { + Scrollable s = (Scrollable) c; + Rectangle rr = s.getClientArea(); + Rectangle tr = s.computeTrim(rr.x, rr.y, rr.width, rr.height); + trimX = rr.x - tr.x; + trimY = rr.y - tr.y; + } + p.x += c.getLocation().x + trimX; + p.y += c.getLocation().y + trimY; + } + return p; + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/TimeCompressionBar.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/TimeCompressionBar.java new file mode 100755 index 0000000000..b7e72adecb --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/TimeCompressionBar.java @@ -0,0 +1,1028 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.accessibility.ACC; +import org.eclipse.swt.accessibility.Accessible; +import org.eclipse.swt.accessibility.AccessibleAdapter; +import org.eclipse.swt.accessibility.AccessibleControlAdapter; +import org.eclipse.swt.accessibility.AccessibleControlEvent; +import org.eclipse.swt.accessibility.AccessibleEvent; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.TraverseEvent; +import org.eclipse.swt.events.TraverseListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.AsyncMessage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.AsyncMessageReturn; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.BaseMessage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.ExecutionOccurrence; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Frame; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.ITimeRange; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Lifeline; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Metrics; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SDTimeEvent; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SyncMessage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IColor; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.impl.ColorImpl; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.TimeEventComparator; + +/** + *

    + * The time compression bar implementation. + *

    + * + * @version 1.0 + * @author sveyrier + */ +public class TimeCompressionBar extends ScrollView implements DisposeListener { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + private static final int BASE_RED_VALUE = 255; + private static final int BASE_GREEN_BLUE_VALUE = 225; + private static final int COLOR_STEP = 25; + private static final int NUMBER_STEPS = 10; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The listener list + */ + private List fListenerList = null; + /** + * The current frame displayed. + */ + private Frame fFrame = null; + /** + * List of time events. + */ + private List fNodeList = null; + /** + * The minimum time delta. + */ + private ITmfTimestamp fMinTime = new TmfTimestamp(); + /** + * The maximum time delta. + */ + private ITmfTimestamp fMaxTime = new TmfTimestamp(); + /** + * The current zoom value. + */ + private float fZoomValue = 1; + /** + * The tooltip to display. + */ + private DrawableToolTip fTooltip = null; + /** + * Array of colors for displaying wight of time deltas. + */ + private ColorImpl[] fColors; + /** + * The accessible object reference. + */ + private Accessible fAccessible = null; + /** + * The focused widget reference. + */ + private int fFocusedWidget = -1; + /** + * The current lifeline. + */ + private Lifeline fLifeline = null; + /** + * The current start event value. + */ + private int fLifelineStart = 0; + /** + * The current number of events. + */ + private int fLifelineNumEvents = 0; + /** + * The Current color of range to display. + */ + private IColor fLifelineColor = null; + /** + * The next graph node y coordinate. + */ + private int fNextNodeY = 0; + /** + * The previous graph node y coordinate. + */ + private int fPrevNodeY = 0; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Standard constructor + * + * @param parent The parent composite + * @param s The style bits + */ + public TimeCompressionBar(Composite parent, int s) { + super(parent, s | SWT.NO_BACKGROUND, false); + setVScrollBarMode(ScrollView.ALWAYS_OFF); + setHScrollBarMode(ScrollView.ALWAYS_OFF); + fListenerList = new ArrayList<>(); + fColors = new ColorImpl[NUMBER_STEPS]; + int greenBlue = BASE_GREEN_BLUE_VALUE; + final int step = COLOR_STEP; + for (int i = 0; i < fColors.length; i++) { + fColors[i] = new ColorImpl(Display.getDefault(), BASE_RED_VALUE, greenBlue, greenBlue); + greenBlue -= step; + } + super.addDisposeListener(this); + + fAccessible = getViewControl().getAccessible(); + + fAccessible.addAccessibleListener(new AccessibleAdapter() { + @Override + public void getName(AccessibleEvent e) { + // Case toolTip + if (e.childID == 0) { + if (fTooltip != null) { + e.result = fTooltip.getAccessibleText(); + } + } else if (e.childID == 1) { + createFakeTooltip(); + e.result = fTooltip.getAccessibleText(); + } + } + }); + + fAccessible.addAccessibleControlListener(new AccessibleControlAdapter() { + @Override + public void getFocus(AccessibleControlEvent e) { + if (fFocusedWidget == -1) { + e.childID = ACC.CHILDID_SELF; + } + else { + e.childID = fFocusedWidget; + } + } + + @Override + public void getRole(AccessibleControlEvent e) { + switch (e.childID) { + case ACC.CHILDID_SELF: + e.detail = ACC.ROLE_CLIENT_AREA; + break; + case 0: + e.detail = ACC.ROLE_TOOLTIP; + break; + case 1: + e.detail = ACC.ROLE_LABEL; + break; + default: + break; + } + } + + @Override + public void getState(AccessibleControlEvent e) { + e.detail = ACC.STATE_FOCUSABLE; + if (e.childID == ACC.CHILDID_SELF) { + e.detail |= ACC.STATE_FOCUSED; + } else { + e.detail |= ACC.STATE_SELECTABLE; + if (e.childID == fFocusedWidget) { + e.detail |= ACC.STATE_FOCUSED | ACC.STATE_SELECTED | ACC.STATE_CHECKED; + } + } + } + }); + + getViewControl().addTraverseListener(new LocalTraverseListener()); + + addTraverseListener(new LocalTraverseListener()); + + getViewControl().addFocusListener(new FocusListener() { + @Override + public void focusGained(FocusEvent e) { + redraw(); + } + + @Override + public void focusLost(FocusEvent e) { + redraw(); + } + }); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + /** + * Sets the focus widget + * + * @param newFocusShape widget reference to set + */ + void setFocus(int newFocusShape) { + fFocusedWidget = newFocusShape; + if (fFocusedWidget == -1) { + getViewControl().getAccessible().setFocus(ACC.CHILDID_SELF); + } else { + getViewControl().getAccessible().setFocus(fFocusedWidget); + } + } + + /** + * Sets the current frame. + * + * @param theFrame The frame to set + */ + public void setFrame(Frame theFrame) { + fFrame = theFrame; + fMinTime = fFrame.getMinTime(); + fMaxTime = fFrame.getMaxTime(); + } + + @Override + protected void drawContents(GC gc, int clipx, int clipy, int clipw, int cliph) { + if (fFrame == null) { + return; + } + fNodeList = new ArrayList<>(); + int messageArraysStep = 1; + + if ((Metrics.getMessageFontHeigth() + Metrics.MESSAGES_NAME_SPACING * 2) * fZoomValue < Metrics.MESSAGE_SIGNIFICANT_VSPACING + 1) { + messageArraysStep = Math.round(Metrics.MESSAGE_SIGNIFICANT_VSPACING + 1 / ((Metrics.getMessageFontHeigth() + Metrics.MESSAGES_NAME_SPACING * 2) * fZoomValue)); + } + + int firstVisible = fFrame.getFirstVisibleSyncMessage(); + if (firstVisible > 0) { + firstVisible = firstVisible - 1; + } + for (int i = firstVisible; i < fFrame.syncMessageCount(); i = i + messageArraysStep) { + SyncMessage m = fFrame.getSyncMessage(i); + if (m.hasTimeInfo()) { + SDTimeEvent t = new SDTimeEvent(m.getStartTime(), m.getEventOccurrence(), m); + fNodeList.add(t); + if (m.getY() * fZoomValue > getContentsY() + getVisibleHeight()) { + break; + } + } + } + + firstVisible = fFrame.getFirstVisibleSyncMessageReturn(); + if (firstVisible > 0) { + firstVisible = firstVisible - 1; + } + for (int i = firstVisible; i < fFrame.syncMessageReturnCount(); i = i + messageArraysStep) { + SyncMessage m = fFrame.getSyncMessageReturn(i); + if (m.hasTimeInfo()) { + SDTimeEvent t = new SDTimeEvent(m.getStartTime(), m.getEventOccurrence(), m); + fNodeList.add(t); + if (m.getY() * fZoomValue > getContentsY() + getVisibleHeight()) { + break; + } + } + } + + firstVisible = fFrame.getFirstVisibleAsyncMessage(); + if (firstVisible > 0) { + firstVisible = firstVisible - 1; + } + for (int i = firstVisible; i < fFrame.asyncMessageCount(); i = i + messageArraysStep) { + AsyncMessage m = fFrame.getAsyncMessage(i); + if (m.hasTimeInfo()) { + SDTimeEvent t = new SDTimeEvent(m.getStartTime(), m.getStartOccurrence(), m); + fNodeList.add(t); + t = new SDTimeEvent(m.getEndTime(), m.getEndOccurrence(), m); + fNodeList.add(t); + if (m.getY() * fZoomValue > getContentsY() + getVisibleHeight()) { + break; + } + } + } + + firstVisible = fFrame.getFirstVisibleAsyncMessageReturn(); + if (firstVisible > 0) { + firstVisible = firstVisible - 1; + } + for (int i = firstVisible; i < fFrame.asyncMessageReturnCount(); i = i + messageArraysStep) { + AsyncMessageReturn m = fFrame.getAsyncMessageReturn(i); + if (m.hasTimeInfo()) { + SDTimeEvent t = new SDTimeEvent(m.getStartTime(), m.getStartOccurrence(), m); + fNodeList.add(t); + t = new SDTimeEvent(m.getEndTime(), m.getEndOccurrence(), m); + fNodeList.add(t); + if (m.getY() * fZoomValue > getContentsY() + getVisibleHeight()) { + break; + } + } + } + + List executionOccurrencesWithTime = fFrame.getExecutionOccurrencesWithTime(); + if (executionOccurrencesWithTime != null) { + fNodeList.addAll(executionOccurrencesWithTime); + } + + SDTimeEvent[] temp = fNodeList.toArray(new SDTimeEvent[fNodeList.size()]); + Arrays.sort(temp, new TimeEventComparator()); + fNodeList = Arrays.asList(temp); + + Image dbuffer = new Image(getDisplay(), getClientArea().width, getClientArea().height); + GC gcim = new GC(dbuffer); + + for (int i = 0; i < fNodeList.size() - 1; i++) { + SDTimeEvent m1 = fNodeList.get(i); + SDTimeEvent m2 = fNodeList.get(i + 1); + + if ((SDViewPref.getInstance().excludeExternalTime()) && ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage))) { + BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); + BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); + if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) { + continue; + } + } + + fMinTime = fFrame.getMinTime(); + fMaxTime = fFrame.getMaxTime(); + ITmfTimestamp minMaxdelta = fMaxTime.getDelta(fMinTime); + double gr = (minMaxdelta.getValue()) / (double) NUMBER_STEPS; + + ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime()).getDelta(fMinTime); + long absDelta = Math.abs(delta.getValue()); + + ColorImpl color; + if (gr != 0) { + int colIndex = Math.round((float) (absDelta / gr)); + if (colIndex < fColors.length && colIndex > 0) { + color = fColors[colIndex - 1]; + } else if (colIndex <= 0) { + color = fColors[0]; + } else { + color = fColors[fColors.length - 1]; + } + } else { + color = fColors[0]; + } + + if (color.getColor() instanceof Color) { + gcim.setBackground((Color) color.getColor()); + } + int y1 = ((GraphNode) m1.getGraphNode()).getY(); + int y2 = ((GraphNode) m2.getGraphNode()).getY(); + if (m1.getGraphNode() instanceof AsyncMessage) { + AsyncMessage as = (AsyncMessage) m1.getGraphNode(); + if (as.getEndTime() == m1.getTime()) { + y1 += as.getHeight(); + } + } + if (m2.getGraphNode() instanceof AsyncMessage) { + AsyncMessage as = (AsyncMessage) m2.getGraphNode(); + if (as.getEndTime() == m2.getTime()) { + y2 += as.getHeight(); + } + } + if (m1.getGraphNode() instanceof ExecutionOccurrence) { + + ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); + if (m1.getEvent() == eo.getEndOccurrence()) { + y1 += eo.getHeight(); + } + + if (m2.getGraphNode() instanceof ExecutionOccurrence) { + + ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); + if (m2.getEvent() == eo2.getEndOccurrence()) { + y2 += eo2.getHeight(); + } + + } + } + gcim.fillRectangle(contentsToViewX(0), contentsToViewY(Math.round(y1 * fZoomValue)), 10, Math.round((y2 - y1) * fZoomValue) + 1); + if (messageArraysStep == 1) { + Color backupColor = gcim.getForeground(); + gcim.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); + gcim.drawRectangle(contentsToViewX(0), contentsToViewY(Math.round(y1 * fZoomValue)), 9, Math.round((y2 - y1) * fZoomValue)); + gcim.setForeground(backupColor); + } + } + if (getViewControl().isFocusControl() || isFocusControl()) { + gcim.drawFocus(contentsToViewX(0), contentsToViewY(Math.round(fPrevNodeY * fZoomValue)), contentsToViewX(10), Math.round((fNextNodeY - fPrevNodeY) * fZoomValue)); + } + try { + gc.drawImage(dbuffer, 0, 0, getClientArea().width, getClientArea().height, 0, 0, getClientArea().width, getClientArea().height); + } catch (Exception e) { + Activator.getDefault().logError("Error drawing image", e); //$NON-NLS-1$ + } + gcim.dispose(); + dbuffer.dispose(); + gc.dispose(); + } + + /** + * Checks for focus of children. + * + * @param children + * Control to check + * @return true if child is on focus else false + */ + protected boolean checkFocusOnChilds(Control children) { + if (children instanceof Composite) { + Control[] child = ((Composite) children).getChildren(); + for (int i = 0; i < child.length; i++) { + if (child[i].isFocusControl()) { + return true; + } + checkFocusOnChilds(child[i]); + } + } + return false; + } + + @Override + public boolean isFocusControl() { + Control[] child = getChildren(); + for (int i = 0; i < child.length; i++) { + if (child[i].isFocusControl()) { + return true; + } + checkFocusOnChilds(child[i]); + } + return false; + } + + @Override + protected void contentsMouseMoveEvent(MouseEvent event) { + if (fTooltip != null) { + fTooltip.hideToolTip(); + } + super.contentsMouseMoveEvent(event); + if (!isFocusControl() || getViewControl().isFocusControl()) { + Control[] child = getParent().getChildren(); + for (int i = 0; i < child.length; i++) { + if (child[i].isFocusControl()) { + break; + } + } + } + setFocus(-1); + } + + @Override + protected void contentsMouseHover(MouseEvent e) { + if (fTooltip == null) { + fTooltip = new DrawableToolTip(this); + } + if (fFrame != null) { + setFocus(0); + for (int i = 0; i < fNodeList.size() - 1; i++) { + SDTimeEvent m1 = fNodeList.get(i); + SDTimeEvent m2 = fNodeList.get(i + 1); + + if ((SDViewPref.getInstance().excludeExternalTime()) && ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage))) { + BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); + BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); + if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) { + continue; + } + } + + int y1 = ((GraphNode) m1.getGraphNode()).getY(); + int y2 = ((GraphNode) m2.getGraphNode()).getY(); + + if (m1.getGraphNode() instanceof AsyncMessage) { + AsyncMessage as = (AsyncMessage) m1.getGraphNode(); + if (as.getEndTime() == m1.getTime()) { + y1 += as.getHeight(); + } + } + if (m2.getGraphNode() instanceof AsyncMessage) { + AsyncMessage as = (AsyncMessage) m2.getGraphNode(); + if (as.getEndTime() == m2.getTime()) { + y2 += as.getHeight(); + } + } + if (m1.getGraphNode() instanceof ExecutionOccurrence) { + ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); + if (m1.getEvent() == eo.getEndOccurrence()) { + y1 += eo.getHeight(); + } + + if (m2.getGraphNode() instanceof ExecutionOccurrence) { + + ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); + if (m2.getEvent() == eo2.getEndOccurrence()) { + y2 += eo2.getHeight(); + } + } + } + int m1Y = Math.round(y1 * fZoomValue); + int m2Y = Math.round(y2 * fZoomValue); + if ((m1Y < e.y) && (m2Y >= e.y)) { + ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime()); + fTooltip.showToolTip(delta, fMinTime, fMaxTime); + } + } + } + setFocus(0); + } + + @Override + protected void contentsMouseExit(MouseEvent e) { + if (fTooltip != null) { + fTooltip.hideToolTip(); + } + } + + @Override + protected void contentsMouseUpEvent(MouseEvent event) { + selectTimeDelta(event.y, 0); + setFocus(); + super.contentsMouseUpEvent(event); + } + + /** + * Force the time compression bar to highlight the event occurrences between + * the two given messages. The event occurrences are highlighted on the + * first message's end lifeline + * + * @param mes1 + * the first message + * @param mes2 + * the second message + */ + public void highlightRegion(BaseMessage mes1, BaseMessage mes2) { + BaseMessage localMes1 = mes1; + BaseMessage localMes2 = mes2; + + if (fFrame == null) { + return; + } + if (!(localMes1 instanceof ITimeRange)) { + return; + } + if (!(localMes2 instanceof ITimeRange)) { + return; + } + ITimeRange t1 = (ITimeRange) localMes1; + ITimeRange t2 = (ITimeRange) localMes2; + + ITmfTimestamp time1 = t1.getStartTime(); + ITmfTimestamp time2 = t2.getStartTime(); + int event1 = localMes1.getEventOccurrence(); + int event2 = localMes2.getEventOccurrence(); + + if (localMes1 instanceof AsyncMessage) { + AsyncMessage as = (AsyncMessage) localMes1; + time1 = as.getEndTime(); + event1 = as.getEndOccurrence(); + } + if (localMes2 instanceof AsyncMessage) { + AsyncMessage as = (AsyncMessage) localMes2; + if (as.getEndOccurrence() > as.getStartOccurrence()) { + time1 = as.getEndTime(); + event1 = as.getEndOccurrence(); + } else { + time1 = as.getStartTime(); + event1 = as.getStartOccurrence(); + } + } + + if (event1 > event2) { + BaseMessage tempMes = localMes2; + localMes2 = localMes1; + localMes1 = tempMes; + + t1 = (ITimeRange) localMes1; + t2 = (ITimeRange) localMes2; + + time1 = t1.getStartTime(); + time2 = t2.getStartTime(); + event1 = localMes1.getEventOccurrence(); + event2 = localMes2.getEventOccurrence(); + + if (localMes1 instanceof AsyncMessage) { + AsyncMessage as = (AsyncMessage) localMes1; + time1 = as.getEndTime(); + event1 = as.getEndOccurrence(); + } + if (localMes2 instanceof AsyncMessage) { + AsyncMessage as = (AsyncMessage) localMes2; + if (as.getEndOccurrence() > as.getStartOccurrence()) { + time1 = as.getEndTime(); + event1 = as.getEndOccurrence(); + } else { + time1 = as.getStartTime(); + event1 = as.getStartOccurrence(); + } + } + } + + ITmfTimestamp minMaxdelta = fMaxTime.getDelta(fMinTime); + double gr = (minMaxdelta.getValue()) / (double) NUMBER_STEPS; + + ITmfTimestamp delta = time2.getDelta(time1).getDelta(fMinTime); + long absDelta = Math.abs(delta.getValue()); + + int colIndex = 0; + if (gr != 0) { + colIndex = Math.round((float) (absDelta / gr)); + if (colIndex >= fColors.length) { + colIndex = fColors.length - 1; + } else if (colIndex < 0) { + colIndex = 0; + } + } else { + colIndex = 0; + } + for (int j = 0; j < fListenerList.size(); j++) { + ITimeCompressionListener list = fListenerList.get(j); + if (localMes1.getEndLifeline() != null) { + list.deltaSelected(localMes1.getEndLifeline(), event1, event2 - event1, fColors[colIndex]); + } else if (localMes2.getStartLifeline() != null) { + list.deltaSelected(localMes2.getStartLifeline(), event1, event2 - event1, fColors[colIndex]); + } else { + list.deltaSelected(localMes1.getStartLifeline(), event1, event2 - event1, fColors[colIndex]); + } + } + } + + /** + * Force the time compression bar to highlight the event occurrences between the two given messages. The event + * occurrences are highlighted on the first message's end lifeline + * + * @param mes1 the first message + * @param mes2 the second message + */ + public void highlightRegionSync(final BaseMessage mes1, final BaseMessage mes2) { + getDisplay().syncExec(new Runnable() { + @Override + public void run() { + highlightRegion(mes1, mes2); + } + }); + } + + @Override + public void scrollBy(int x, int y) { + } + + /** + * Sets the zoom value. + * + * @param value The zoom value to set. + */ + public void setZoom(float value) { + fZoomValue = value; + redraw(); + } + + /** + * Adds a listener to the time compression listener list to be notified about selected deltas. + * + * @param listener The listener to add + */ + public void addTimeCompressionListener(ITimeCompressionListener listener) { + if (!fListenerList.contains(listener)) { + fListenerList.add(listener); + } + } + + /** + * Removes a time compression listener. + * + * @param listener The listener to remove. + */ + public void removeSelectionChangedListener(ITimeCompressionListener listener) { + fListenerList.remove(listener); + } + + @Override + public void widgetDisposed(DisposeEvent e) { + if (fTooltip != null) { + fTooltip.dispose(); + } + super.removeDisposeListener(this); + for (int i = 0; i < fColors.length; i++) { + fColors[i].dispose(); + } + } + + @Override + protected void keyPressedEvent(KeyEvent event) { + if (fTooltip != null) { + fTooltip.hideToolTip(); + } + if (!isFocusControl() || getViewControl().isFocusControl()) { + Control[] child = getParent().getChildren(); + for (int i = 0; i < child.length; i++) { + if (child[i].isFocusControl()) { + break; + } + } + } + setFocus(-1); + + boolean top = false; + if (fNextNodeY == 0) { + top = true; + } + if ((fFrame != null) && (fNextNodeY == 0)) { + for (int i = 0; i < fNodeList.size() - 1 && i < 1; i++) { + SDTimeEvent m1 = fNodeList.get(i); + SDTimeEvent m2 = fNodeList.get(i + 1); + if ((SDViewPref.getInstance().excludeExternalTime()) && ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage))) { + BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); + BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); + if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) { + continue; + } + } + + int y1 = ((GraphNode) m1.getGraphNode()).getY(); + int y2 = ((GraphNode) m2.getGraphNode()).getY(); + if (m1.getGraphNode() instanceof AsyncMessage) { + AsyncMessage as = (AsyncMessage) m1.getGraphNode(); + if (as.getEndTime() == m1.getTime()) { + y1 += as.getHeight(); + } + } + if (m2.getGraphNode() instanceof AsyncMessage) { + AsyncMessage as = (AsyncMessage) m2.getGraphNode(); + if (as.getEndTime() == m2.getTime()) { + y2 += as.getHeight(); + } + } + if (m1.getGraphNode() instanceof ExecutionOccurrence) { + ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); + if (m1.getEvent() == eo.getEndOccurrence()) { + y1 += eo.getHeight(); + } + + if (m2.getGraphNode() instanceof ExecutionOccurrence) { + + ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); + if (m2.getEvent() == eo2.getEndOccurrence()) { + y2 += eo2.getHeight(); + } + } + } + fPrevNodeY = Math.round(y1 * fZoomValue); + fNextNodeY = Math.round(y2 * fZoomValue); + } + } + + if (fLifeline != null) { + for (int j = 0; j < fListenerList.size(); j++) { + ITimeCompressionListener list = fListenerList.get(j); + list.deltaSelected(fLifeline, fLifelineStart, fLifelineNumEvents, fLifelineColor); + } + } + + if (event.keyCode == SWT.ARROW_DOWN) { + if (!top) { + selectTimeDelta(fNextNodeY + 1, 1); + } else { + selectTimeDelta(fPrevNodeY + 1, 1); + } + setFocus(1); + } else if (event.keyCode == SWT.ARROW_UP) { + selectTimeDelta(fPrevNodeY - 1, 2); + setFocus(1); + } else if (event.keyCode == SWT.ARROW_RIGHT) { + selectTimeDelta(fPrevNodeY, 1); + setFocus(1); + } + super.keyPressedEvent(event); + } + + /** + * Selects the time delta for given delta y coordinate and direction. + * + * @param dy The delta in y coordinate. + * @param direction 0 no direction, 1 = down, 2 = up + */ + protected void selectTimeDelta(int dy, int direction) { + SDTimeEvent lastM1 = null; + SDTimeEvent lastM2 = null; + int lastY1 = 0; + int lastY2 = 0; + boolean done = false; + if (fFrame != null) { + for (int i = 0; i < fNodeList.size() - 1; i++) { + SDTimeEvent m1 = fNodeList.get(i); + SDTimeEvent m2 = fNodeList.get(i + 1); + if ((SDViewPref.getInstance().excludeExternalTime()) && ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage))) { + BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); + BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); + if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) { + continue; + } + } + + int y1 = ((GraphNode) m1.getGraphNode()).getY(); + int y2 = ((GraphNode) m2.getGraphNode()).getY(); + if (m1.getGraphNode() instanceof AsyncMessage) { + AsyncMessage as = (AsyncMessage) m1.getGraphNode(); + if (as.getEndTime() == m1.getTime()) { + y1 += as.getHeight(); + } + } + if (m2.getGraphNode() instanceof AsyncMessage) { + AsyncMessage as = (AsyncMessage) m2.getGraphNode(); + if (as.getEndTime() == m2.getTime()) { + y2 += as.getHeight(); + } + } + if (m1.getGraphNode() instanceof ExecutionOccurrence) { + ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); + if (m1.getEvent() == eo.getEndOccurrence()) { + y1 += eo.getHeight(); + } + + if (m2.getGraphNode() instanceof ExecutionOccurrence) { + ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); + if (m2.getEvent() == eo2.getEndOccurrence()) { + y2 += eo2.getHeight(); + } + } + } + int m1Y = Math.round(y1 * fZoomValue); + int m2Y = Math.round(y2 * fZoomValue); + + if ((m1Y < dy) && (m2Y > dy) || (!done && m2Y > dy && direction == 1 && lastM1 != null) || (!done && m1Y > dy && direction == 2 && lastM1 != null)) { + if (m1Y > dy && direction == 2) { + m1 = lastM1; + m2 = lastM2; + m1Y = lastY1; + m2Y = lastY2; + } + done = true; + fPrevNodeY = m1Y; + fNextNodeY = m2Y; + ITmfTimestamp minMaxdelta = fMaxTime.getDelta(fMinTime); + double gr = (minMaxdelta.getValue()) / (double) NUMBER_STEPS; + + ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime()).getDelta(fMinTime); + long absDelta = Math.abs(delta.getValue()); + + int colIndex = 0; + if (gr != 0) { + colIndex = Math.round((float) (absDelta / gr)); + if (colIndex >= fColors.length) { + colIndex = fColors.length - 1; + } else if (colIndex < 0) { + colIndex = 0; + } + } else { + colIndex = 0; + } + if (m1.getGraphNode() instanceof BaseMessage) { + BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); + if (mes1.getEndLifeline() != null) { + fLifeline = mes1.getEndLifeline(); + fLifelineStart = m1.getEvent(); + fLifelineNumEvents = m2.getEvent() - m1.getEvent(); + fLifelineColor = fColors[colIndex]; + } else if (m2.getGraphNode() instanceof BaseMessage && ((BaseMessage) m2.getGraphNode()).getStartLifeline() != null) { + fLifeline = ((BaseMessage) m2.getGraphNode()).getStartLifeline(); + fLifelineStart = m1.getEvent(); + fLifelineNumEvents = m2.getEvent() - m1.getEvent(); + fLifelineColor = fColors[colIndex]; + } else { + fLifeline = mes1.getStartLifeline(); + fLifelineStart = m1.getEvent(); + fLifelineNumEvents = m2.getEvent() - m1.getEvent(); + fLifelineColor = fColors[colIndex]; + } + } else if (m1.getGraphNode() instanceof ExecutionOccurrence) { + if (m2.getGraphNode() instanceof ExecutionOccurrence) { + ExecutionOccurrence eo = (ExecutionOccurrence) m2.getGraphNode(); + fLifeline = eo.getLifeline(); + fLifelineStart = m1.getEvent(); + fLifelineNumEvents = m2.getEvent() - m1.getEvent(); + fLifelineColor = fColors[colIndex]; + } else { + ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); + fLifeline = eo.getLifeline(); + fLifelineStart = m1.getEvent(); + fLifelineNumEvents = m2.getEvent() - m1.getEvent(); + fLifelineColor = fColors[colIndex]; + } + } + for (int j = 0; j < fListenerList.size(); j++) { + ITimeCompressionListener list = fListenerList.get(j); + list.deltaSelected(fLifeline, fLifelineStart, fLifelineNumEvents, fLifelineColor); + } + break; + } + lastM1 = m1; + lastM2 = m2; + lastY1 = m1Y; + lastY2 = m2Y; + } + } + } + + /** + * Creates a fake tool tip. + */ + protected void createFakeTooltip() { + if (fTooltip == null) { + fTooltip = new DrawableToolTip(this); + } + + if (fFrame != null) { + setFocus(0); + for (int i = 0; i < fNodeList.size() - 1; i++) { + SDTimeEvent m1 = fNodeList.get(i); + SDTimeEvent m2 = fNodeList.get(i + 1); + + if ((SDViewPref.getInstance().excludeExternalTime()) && ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage))) { + BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); + BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); + if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) { + continue; + } + } + + int y1 = ((GraphNode) m1.getGraphNode()).getY(); + int y2 = ((GraphNode) m2.getGraphNode()).getY(); + + if (m1.getGraphNode() instanceof AsyncMessage) { + AsyncMessage as = (AsyncMessage) m1.getGraphNode(); + if (as.getEndTime() == m1.getTime()) { + y1 += as.getHeight(); + } + } + if (m2.getGraphNode() instanceof AsyncMessage) { + AsyncMessage as = (AsyncMessage) m2.getGraphNode(); + if (as.getEndTime() == m2.getTime()) { + y2 += as.getHeight(); + } + } + if (m1.getGraphNode() instanceof ExecutionOccurrence) { + ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); + if (m1.getEvent() == eo.getEndOccurrence()) { + y1 += eo.getHeight(); + } + + if (m2.getGraphNode() instanceof ExecutionOccurrence) { + + ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); + if (m2.getEvent() == eo2.getEndOccurrence()) { + y2 += eo2.getHeight(); + } + } + } + int m1Y = Math.round(y1 * fZoomValue); + int m2Y = Math.round(y2 * fZoomValue); + if ((m1Y < fPrevNodeY + 1) && (m2Y >= fPrevNodeY + 1)) { + ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime()); + fTooltip.showToolTip(delta, fMinTime, fMaxTime); + fTooltip.hideToolTip(); + } + } + } + } + + /** + * Traverse Listener implementation. + */ + protected static class LocalTraverseListener implements TraverseListener { + @Override + public void keyTraversed(TraverseEvent e) { + if ((e.detail == SWT.TRAVERSE_TAB_NEXT) || (e.detail == SWT.TRAVERSE_TAB_PREVIOUS)) { + e.doit = true; + } + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/AsyncMessage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/AsyncMessage.java new file mode 100755 index 0000000000..2355b482be --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/AsyncMessage.java @@ -0,0 +1,469 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; + +import java.util.Comparator; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.ISDPreferences; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.SortAsyncForBackward; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.SortAsyncMessageComparator; + +/** + * A AsyncMessage is a asynchronous message which appear at two different event occurrences on each lifeline ends (sender + * and receiver).
    + *
    + *
    + * Usage example: + * + *
    + * Frame frame;
    + * Lifeline lifeLine1;
    + * Lifeline lifeLine2;
    + *
    + * AsyncMessage message = new AsyncMessage();
    + * // Create a new event occurrence on each lifeline
    + * lifeline1.getNewOccurrenceIndex();
    + * lifeline2.getNewOccurrenceIndex();
    + * // Set the message sender and receiver
    + * message.setStartLifeline(lifeLine1);
    + * message.setEndLifline(lifeline2);
    + * message.setName("Message label");
    + * // add the message to the frame
    + * frame.addMessage(message);
    + * 
    + * + * @see Lifeline Lifeline for more event occurence details + * @version 1.0 + * @author sveyrier + * @since 2.0 + */ +public class AsyncMessage extends BaseMessage implements ITimeRange { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The grahNode ID constant + */ + public static final String ASYNC_MESS_TAG = "AsyncMessage"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * Flag whether message has time information or not. + */ + private boolean fHasTime = false; + /** + * The time when the message begin + */ + private ITmfTimestamp fEndTime = new TmfTimestamp(); + /** + * The time when the message end + */ + private ITmfTimestamp fStartTime = new TmfTimestamp(); + /** + * The associated message. + */ + protected AsyncMessageReturn fMessageReturn = null; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor + */ + public AsyncMessage() { + setColorPrefId(ISDPreferences.PREF_ASYNC_MESS); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public int getX() { + int x = super.getX(true); + int activationWidth = Metrics.EXECUTION_OCCURRENCE_WIDTH / 2; + if ((getStartLifeline() != null) && (getEndLifeline() != null) && (getStartLifeline().getX() > getEndLifeline().getX())) { + activationWidth = -activationWidth; + } + + if (isMessageStartInActivation(getStartOccurrence())) { + x = x + activationWidth; + } + return x; + } + + @Override + public int getY() { + if ((getStartLifeline() != null) && (getEndLifeline() != null)) { + return getEndLifeline().getY() + getEndLifeline().getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * getStartOccurrence(); + } + return super.getY(); + } + + @Override + public int getWidth() { + int width = super.getWidth(true); + int activationWidth = Metrics.EXECUTION_OCCURRENCE_WIDTH / 2; + if ((getStartLifeline() != null) && (getEndLifeline() != null) && (getStartLifeline().getX() > getEndLifeline().getX())) { + activationWidth = -activationWidth; + } + + if (isMessageStartInActivation(getStartOccurrence())) { + width = width - activationWidth; + } + + if (isMessageEndInActivation(getEndOccurrence())) { + width = width - activationWidth; + } + + return width; + } + + @Override + public int getHeight() { + if ((getStartLifeline() != null) && (getEndLifeline() != null)) { + return (getEndLifeline().getY() + getEndLifeline().getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * getEndOccurrence()) - getY(); + } + return super.getHeight(); + } + + /** + * Set the message return associated with this message. + * + * @param message the message return to associate + */ + protected void setMessageReturn(AsyncMessageReturn message) { + fMessageReturn = message; + } + + /** + * Set the event occurrence attached to this message for its end lifeline + * + * @param occurrence the event occurrence to set + */ + @Override + public void setEndOccurrence(int occurrence) { + super.setEndOccurrence(occurrence); + if (getStartLifeline() == null) { + setStartOccurrence(occurrence); + } + informFrame(getEndLifeline(), occurrence); + } + + /** + * Informs the given lifeline about the maximum occurrence if applicable. + * + * @param lifeLine + * Concerned lifeline + * @param occurrence + * Occurrence number + */ + protected void informFrame(Lifeline lifeLine, int occurrence) { + if ((lifeLine != null) && (lifeLine.getFrame() != null) && (lifeLine.getFrame().getMaxEventOccurrence() < occurrence)) { + lifeLine.getFrame().setMaxEventOccurrence(occurrence); + } + } + + /** + * Set the event occurrence attached to this message for its start lifeline + * + * @param occurrence the event occurrence to set + */ + @Override + public void setStartOccurrence(int occurrence) { + super.setStartOccurrence(occurrence); + if (getEndLifeline() == null) { + setEndOccurrence(getStartOccurrence()); + } + informFrame(getStartLifeline(), occurrence); + } + + /** + * Set the lifeLine which has sent the message.
    + * A new EventOccurence will be create on this lifeLine.
    + * + * @param lifeline the message sender + */ + public void autoSetStartLifeline(Lifeline lifeline) { + lifeline.getNewEventOccurrence(); + setStartLifeline(lifeline); + } + + /** + * Set the lifeLine which has received the message.
    + * A new EventOccurence will be create on this lifeLine.
    + * + * @param lifeline the message receiver + */ + public void autoSetEndLifeline(Lifeline lifeline) { + lifeline.getNewEventOccurrence(); + setEndLifeline(lifeline); + } + + @Override + public void setStartLifeline(Lifeline lifeline) { + super.setStartLifeline(lifeline); + setStartOccurrence(getStartLifeline().getEventOccurrence()); + if (getEndLifeline() == null) { + setEndOccurrence(getStartOccurrence()); + } + } + + @Override + public void setEndLifeline(Lifeline lifeline) { + super.setEndLifeline(lifeline); + setEventOccurrence(getEndLifeline().getEventOccurrence()); + } + + /** + * Returns true if the point C is on the segment defined with the point A and B + * + * @param xA point A x coordinate + * @param yA point A y coordinate + * @param xB point B x coordinate + * @param yB point B y coordinate + * @param xC point C x coordinate + * @param yC point C y coordinate + * @return Return true if the point C is on the segment defined with the point A and B, else otherwise + */ + protected boolean isNearSegment(int xA, int yA, int xB, int yB, int xC, int yC) { + if ((xA > xB) && (xC > xA)) { + return false; + } + if ((xA < xB) && (xC > xB)) { + return false; + } + if ((xA < xB) && (xC < xA)) { + return false; + } + if ((xA > xB) && (xC < xB)) { + return false; + } + double distAB = Math.sqrt((xB - xA) * (xB - xA) + (yB - yA) * (yB - yA)); + double scalar = ((xB - xA) * (xC - xA) + (yB - yA) * (yC - yA)) / distAB; + double distAC = Math.sqrt((xC - xA) * (xC - xA) + (yC - yA) * (yC - yA)); + double distToSegment = Math.sqrt(Math.abs(distAC * distAC - scalar * scalar)); + if (distToSegment <= Metrics.MESSAGE_SELECTION_TOLERANCE) { + return true; + } + return false; + } + + @Override + public boolean contains(int x, int y) { + // Is it a self message? + if (getStartLifeline() == getEndLifeline()) { + return super.contains(x, y); + } + if (isNearSegment(getX(), getY(), getX() + getWidth(), getY() + getHeight(), x, y)) { + return true; + } + int messageMaxWidth = Metrics.swimmingLaneWidth() - Metrics.EXECUTION_OCCURRENCE_WIDTH; + int nameWidth = getName().length() * Metrics.getAverageCharWidth(); + if (getName().length() * Metrics.getAverageCharWidth() > messageMaxWidth) { + if (GraphNode.contains(getX(), getY() - Metrics.MESSAGES_NAME_SPACING - Metrics.getMessageFontHeigth(), messageMaxWidth, Metrics.getMessageFontHeigth(), x, y)) { + return true; + } + } else { + if (GraphNode.contains(getX() + (messageMaxWidth - nameWidth) / 2, getY() + getHeight() / 2 - Metrics.MESSAGES_NAME_SPACING - Metrics.getMessageFontHeigth(), nameWidth, Metrics.getMessageFontHeigth(), x, y)) { + return true; + } + } + return false; + } + + /** + * Draws the asynchronous message using giving graphical context. + * + * @param context A graphical context to draw in. + */ + protected void drawAsyncMessage(IGC context) { + if (getStartLifeline() != null && getEndLifeline() != null && getStartLifeline() == getEndLifeline() && (getStartOccurrence() != getEndOccurrence())) { + int x = getX(); + int y = getY(); + int height = getHeight(); + int tempx = 0; + boolean startInActivation = isMessageStartInActivation(getStartOccurrence()); + boolean endInActivation = isMessageEndInActivation(getEndOccurrence()); + + if (endInActivation && !startInActivation) { + tempx = Metrics.EXECUTION_OCCURRENCE_WIDTH / 2; + } + if (startInActivation && !endInActivation) { + tempx = -Metrics.EXECUTION_OCCURRENCE_WIDTH / 2; + } + + int tempy = Metrics.INTERNAL_MESSAGE_WIDTH / 2; + if (getHeight() <= Metrics.INTERNAL_MESSAGE_WIDTH) { + tempy = getHeight() / 2; + } + + context.drawLine(x, y, x + Metrics.INTERNAL_MESSAGE_WIDTH / 2, y); + context.drawLine(x + Metrics.INTERNAL_MESSAGE_WIDTH, y + tempy, x + Metrics.INTERNAL_MESSAGE_WIDTH, y + height - tempy); + context.drawLine(x + tempx, y + height, x + Metrics.INTERNAL_MESSAGE_WIDTH / 2, y + height); + + Double xt = Double.valueOf(Math.cos(0.75) * 7); + Double yt = Double.valueOf(Math.sin(0.75) * 7); + + context.drawLine(x + xt.intValue() + tempx, y + height + yt.intValue(), x + tempx, y + height); + context.drawArc(x, y, Metrics.INTERNAL_MESSAGE_WIDTH, 2 * tempy, 0, 90); + context.drawArc(x, y + height, Metrics.INTERNAL_MESSAGE_WIDTH, -2 * tempy, 0, -90); + context.drawLine(x + xt.intValue() + tempx, y + height - yt.intValue(), x + tempx, y + height); + + context.drawTextTruncated(getName(), x + Metrics.INTERNAL_MESSAGE_WIDTH + Metrics.INTERNAL_MESSAGE_V_MARGIN, y, Metrics.swimmingLaneWidth() - Metrics.EXECUTION_OCCURRENCE_WIDTH + -Metrics.INTERNAL_MESSAGE_WIDTH, + +Metrics.MESSAGES_NAME_SPACING - Metrics.getMessageFontHeigth(), !isSelected()); + } else { + super.draw(context); + } + } + + @Override + public void draw(IGC context) { + if (!isVisible()) { + return; + } + + ISDPreferences pref = SDViewPref.getInstance(); + + // Draw it selected? + if (isSelected() && (getStartLifeline() != null && getEndLifeline() != null && getStartLifeline() == getEndLifeline() && (getStartOccurrence() != getEndOccurrence()))) { + /* + * Draw it twice First time, bigger inverting selection colors Second time, regular drawing using selection + * colors This create the highlight effect + */ + context.setForeground(pref.getBackGroundColorSelection()); + context.setLineWidth(Metrics.SELECTION_LINE_WIDTH); + drawAsyncMessage(context); + context.setBackground(pref.getBackGroundColorSelection()); + context.setForeground(pref.getForeGroundColorSelection()); + // Second drawing is done after the else + } else { + context.setBackground(pref.getBackGroundColor(getColorPrefId())); + context.setForeground(pref.getForeGroundColor(getColorPrefId())); + } + if (hasFocus()) { + context.setDrawTextWithFocusStyle(true); + } + context.setLineWidth(Metrics.NORMAL_LINE_WIDTH); + drawAsyncMessage(context); + if (hasFocus()) { + context.setDrawTextWithFocusStyle(false); + } + } + + /** + * Set the time when the message end + * + * @param time the time when the message end + * @since 2.0 + */ + public void setEndTime(ITmfTimestamp time) { + fEndTime = time; + fHasTime = true; + if (getStartLifeline() != null && getStartLifeline().getFrame() != null) { + getStartLifeline().getFrame().setHasTimeInfo(true); + } else if (getEndLifeline() != null && getEndLifeline().getFrame() != null) { + getEndLifeline().getFrame().setHasTimeInfo(true); + } + } + + /** + * Set the time when the message start + * + * @param time the time when the message start + * @since 2.0 + */ + public void setStartTime(ITmfTimestamp time) { + fStartTime = time; + fHasTime = true; + if (getStartLifeline() != null && getStartLifeline().getFrame() != null) { + getStartLifeline().getFrame().setHasTimeInfo(true); + } else if (getEndLifeline() != null && getEndLifeline().getFrame() != null) { + getEndLifeline().getFrame().setHasTimeInfo(true); + } + } + + /** + * @since 2.0 + */ + @Override + public ITmfTimestamp getEndTime() { + return fEndTime; + } + + /** + * @since 2.0 + */ + @Override + public ITmfTimestamp getStartTime() { + return fStartTime; + } + + @Override + public boolean hasTimeInfo() { + return fHasTime; + } + + /** + * @return message return instance or null + * @since 2.0 + */ + public AsyncMessageReturn getMessageReturn() { + return fMessageReturn; + } + + @Override + public boolean isVisible(int x, int y, int width, int height) { + int toDrawY = getY(); + int toDrawHeight = getHeight(); + if ((toDrawY > y + height + Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth()) && (toDrawY + toDrawHeight > y + height + Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth())) { + return false; + } + if (toDrawY < y && (toDrawY + toDrawHeight < y)) { + return false; + } + return super.isVisible(x, y, width, height); + } + + @Override + public Comparator getComparator() { + return new SortAsyncMessageComparator(); + } + + @Override + public String getArrayId() { + return ASYNC_MESS_TAG; + } + + @Override + public Comparator getBackComparator() { + return new SortAsyncForBackward(); + } + + @Override + public boolean positiveDistanceToPoint(int x, int y) { + int mY = getY(); + int mH = getHeight(); + if ((mY > y) || (mY + mH > y)) { + return true; + } + return false; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/AsyncMessageReturn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/AsyncMessageReturn.java new file mode 100755 index 0000000000..dbc5160bca --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/AsyncMessageReturn.java @@ -0,0 +1,112 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.ISDPreferences; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref; + +/** + * The message return graph node implementation.
    + * This class differs on the AsynMessage class only on the drawing line style (dashed instead of plain line).
    + * Message return are generally associated to a message. This means, they are connected to the same lifelines than the + * associated message but in the opposite direction and for a different event occurrence.
    + *
    + * WARNING: The association validity is not checked, it is not necessary to provide a valid association, not even needed + * to set an association to drawn a message with a message return style.
    + * + * + * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.AsyncMessage AsyncMessage for usage example + * @version 1.0 + * @author sveyrier + * + */ +public class AsyncMessageReturn extends AsyncMessage { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The grahNode ID constant + */ + public static final String ASYNC_MESS_RET_TAG = "AsyncMessageRet"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The corresponding asynchronous message. + */ + protected AsyncMessage fMessage; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor. + */ + public AsyncMessageReturn() { + setColorPrefId(ISDPreferences.PREF_ASYNC_MESS_RET); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + /** + * Set the associated message (the message it is the return).
    + * Setting the association will activate the navigation in the default sequence diagram implementation to the + * message when the user right click on this message return.
    + * + * @param parentMessage the message to associate + */ + public void setMessage(AsyncMessage parentMessage) { + fMessage = parentMessage; + } + + /** + * Returns the associated message (the message it is the return).
    + * + * @return parentMessage the message to associate + * @since 2.0 + */ + public AsyncMessage getMessage() { + return fMessage; + } + + @Override + public void draw(IGC context) { + if (!isVisible()) { + return; + } + + ISDPreferences pref = SDViewPref.getInstance(); + + setColorPrefId(ISDPreferences.PREF_ASYNC_MESS_RET); + int oldStyle = context.getLineStyle(); + // Message return are dashed + context.setLineStyle(context.getLineDotStyle()); + if (!isSelected()) { + context.setBackground(pref.getBackGroundColor(getColorPrefId())); + context.setForeground(pref.getForeGroundColor(getColorPrefId())); + } + super.draw(context); + // restore the context + context.setLineStyle(oldStyle); + } + + @Override + public String getArrayId() { + return ASYNC_MESS_RET_TAG; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/BaseMessage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/BaseMessage.java new file mode 100755 index 0000000000..532cb51e90 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/BaseMessage.java @@ -0,0 +1,724 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IColor; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.ISDPreferences; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref; + +/** + * The base UML2 syncMessages implementation.
    + * This abstract class only define one event occurrence to attach to the message.
    + * Usually a message has two event occurrences attached, one for both ends. But some syncMessages(like synchronous + * syncMessages) only need one event occurrence to represent the time when they appear. Others kind of message + * representations (like asynchronous syncMessages) will be responsible to define the missing second eventOccurrence + * property.
    + *
    + * + * @see Lifeline Lifeline for more event occurence details + * @version 1.0 + * @author sveyrier + */ +public abstract class BaseMessage extends GraphNode { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The lifeline which send the message + */ + private Lifeline fStartLifeline = null; + /** + * The lifeline which receive the message + */ + private Lifeline fEndLifeline = null; + /** + * The visiblitiy flag. + */ + private boolean fVisible = true; + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public int getX() { + // returns the exact x coordinate + return getX(false); + } + + @Override + public int getY() { + /* + * Note: lifeline.getY() return the y coordinate of the top left corner of the rectangle which contain the + * lifeline name getHeight return the height of this rectangle The message y coordinate is then relative to this + * position depending of its eventOccurrence Space between syncMessages is constant + */ + if ((fStartLifeline != null) && (fEndLifeline != null)) { + /* + * Regular message, both ends are attached to a lifeline + */ + return fEndLifeline.getY() + fEndLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * getEndOccurrence(); + + } + /* + * UML2 lost message kind + */ + if (fStartLifeline != null) { + return fStartLifeline.getY() + fStartLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * getEndOccurrence(); + } + + /* + * UML2 found message kind + */ + if (fEndLifeline != null) { + return fEndLifeline.getY() + fEndLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * getEndOccurrence(); + } + // return 0 by default + return 0; + } + + @Override + public int getWidth() { + // Returns the exact width + return getWidth(false); + } + + @Override + public int getHeight() { + return 0; + } + + /** + * Returns the graph node x coordinate.
    + * Depending on the quick parameter a approximative or exact value is return.
    + * The approximative value does not take into account if both message ends are connected to a Lifeline Execution + * Occurrence.
    + * Execution occurrence on a lifeline increase the vertical line width which represent the lifeline, this directly + * affect the message x coordinate and width.
    + *
    + * This method is typically used to faster execute none graphical operation like tooltip lookup.
    + *
    + * + * @param quick true to get an approximative value
    + * false to get the exact x value
    + * @return the graph node x coordinate + */ + protected int getX(boolean quick) { + int x = 0; + int activationWidth = Metrics.EXECUTION_OCCURRENCE_WIDTH / 2; + if ((fStartLifeline != null) && (fEndLifeline != null)) { + x = fStartLifeline.getX() + Metrics.getLifelineWidth() / 2; + } else { + if (fStartLifeline != null) { + x = fStartLifeline.getX() + Metrics.getLifelineWidth() / 2; + } + + if (fEndLifeline != null) { + x = fEndLifeline.getX() - Metrics.LIFELINE_SPACING / 2; + } + } + + if (quick) { + return x; + } + + if ((fStartLifeline != null) && (fEndLifeline != null) && (fStartLifeline.getX() > fEndLifeline.getX())) { + activationWidth = -activationWidth; + } + + if (isMessageStartInActivation(getEndOccurrence())) { + x = x + activationWidth; + } + + return x; + } + + /** + * Returns the graph node width.
    + * Depending on the quick parameter a approximative or exact value is returned.
    + * The approximative value does not take into account if both message ends are connected to a Lifeline Execution + * Occurrence.
    + * Execution occurrence on a lifeline increase the vertical line width which represent the lifeline, this directly + * affect the message x coordinate and width.
    + *
    + * This method is typically used to faster execute none graphical operation like tooltip lookup.
    + *
    + * + * @param quick true to get an approximative value
    + * false to get the exact x value + * @return the graph node width + */ + protected int getWidth(boolean quick) { + int width = 0; + int activationWidth = Metrics.EXECUTION_OCCURRENCE_WIDTH / 2; + if ((fStartLifeline != null) && (fEndLifeline != null)) { + if (fStartLifeline == fEndLifeline) { + width = Metrics.INTERNAL_MESSAGE_WIDTH + Metrics.EXECUTION_OCCURRENCE_WIDTH; + } else { + width = fEndLifeline.getX() + Metrics.getLifelineWidth() / 2 - getX(true); + } + } else { + if (fStartLifeline != null) { + width = Metrics.swimmingLaneWidth() / 2; + } + if (fEndLifeline != null) { + width = Metrics.swimmingLaneWidth() / 2; + } + } + + if (quick) { + return width; + } + + if ((fStartLifeline != null) && (fEndLifeline != null) && (fStartLifeline.getX() > fEndLifeline.getX())) { + activationWidth = -activationWidth; + } + + if (isMessageStartInActivation(getEndOccurrence())) { + width = width - activationWidth; + } + + if (isMessageEndInActivation(getEndOccurrence())) { + width = width - activationWidth; + } + + return width; + } + + @Override + public boolean isVisible(int x, int y, int width, int height) { + // ***Common*** syncMessages visibility + // draw the message only if at least one end is visible + if (fEndLifeline != null && (fEndLifeline.isVisible(x, y, width, height)) || (fStartLifeline != null && fStartLifeline.isVisible(x, y, width, height))) { + return true; + } + // In this case it can be a message which cross the whole visible area + else if (fEndLifeline != null && (!fEndLifeline.isVisible(x, y, width, height)) && (fStartLifeline != null && !fStartLifeline.isVisible(x, y, width, height))) { + if (fEndLifeline.getX() > x + width && fStartLifeline.getX() < x) { + return true; + } else if (fStartLifeline.getX() > x + width && fEndLifeline.getX() < x) { + return true; + } + } + return false; + } + + /** + * Sets the visibility value. + * + * @param value The visibility to set. + */ + public void setVisible(boolean value) { + fVisible = value; + } + + /** + * @return the visibility value. + */ + public boolean isVisible() { + return fVisible; + } + + /** + * Set the lifeline from which this message has been sent. + * + * @param lifeline - the message sender + */ + public void setStartLifeline(Lifeline lifeline) { + fStartLifeline = lifeline; + } + + /** + * Returns the lifeline from which this message has been sent. + * + * @return the message sender + */ + public Lifeline getStartLifeline() { + return fStartLifeline; + } + + /** + * Returns the lifeline which has received this message. + * + * @return the message receiver + */ + public Lifeline getEndLifeline() { + return fEndLifeline; + } + + /** + * Set the lifeline which has receive this message. + * + * @param lifeline the message receiver + */ + public void setEndLifeline(Lifeline lifeline) { + fEndLifeline = lifeline; + } + + /** + * Set the event occurrence when this message occurs.
    + * + * @param occurrence the event occurrence to assign to this message.
    + * @see Lifeline Lifeline for more event occurence details + */ + protected void setEventOccurrence(int occurrence) { + setEndOccurrence(occurrence); + } + + /** + * Returns the event occurence when is message occurs.
    + * + * @return the event occurrence assigned to this message.
    + * @see Lifeline Lifeline for more event occurence details + */ + public int getEventOccurrence() { + return getEndOccurrence(); + } + + /** + * Determines if the given eventOccurence occurs on a executionOccurence owned by the sending lifeline.
    + * WARNING: this method will return a valid result only for execution occurrences which are visible in the View.
    + * As consequence this method is only used for drawing purpose, especially to determine the exact message x + * coordinate and width.
    + * + * @see BaseMessage#getX(boolean) + * @param event the event occurrence to test + * @return true if occurs on a execution occurrence owned by the sending lifeine, false otherwise + */ + protected boolean isMessageStartInActivation(int event) { + boolean inActivation = false; + if ((fStartLifeline != null) && (fStartLifeline.getExecutions() != null)) { + // int acIndex=startLifeline.getExecOccurrenceDrawIndex(); + // acIndex = first visible execution occurrence + // for drawing speed reason with only search on the visivle subset + int thisY = getY(); + for (int i = 0; i < fStartLifeline.getExecutions().size(); i++) { + BasicExecutionOccurrence toDraw = (BasicExecutionOccurrence) fStartLifeline.getExecutions().get(i); + if ((event >= toDraw.getStartOccurrence()) && (event <= toDraw.getEndOccurrence())) { + inActivation = true; + } + // if we are outside the visible area we stop right now + // This works because execution occurrences are ordered along the Y axis + if (toDraw.getY() > thisY) { + break; + } + } + } + return inActivation; + } + + /** + * Determines if the given event occurrence occurs on a execution occurrence owned by the receiving lifeline.
    + * WARNING: this method will return a valid result only for execution occurrences which are visible in the View.
    + * As consequence this method is only used for drawing purpose, especially to determine the exact message x + * coordinate and width.
    + * + * @see BaseMessage#getX(boolean) + * @param event the event occurrence to test + * @return true if occurs on a execution occurrence owned by the receiving lifeline, false otherwise + */ + protected boolean isMessageEndInActivation(int event) { + boolean inActivation = false; + if ((fEndLifeline != null) && (fEndLifeline.getExecutions() != null)) { + // acIndex = first visible execution occurrence + // for drawing speed reason with only search on the visivle subset + for (int i = 0; i < fEndLifeline.getExecutions().size(); i++) { + BasicExecutionOccurrence toDraw = (BasicExecutionOccurrence) fEndLifeline.getExecutions().get(i); + if ((event >= toDraw.getStartOccurrence()) && (event <= toDraw.getEndOccurrence())) { + inActivation = true; + } + // if we are outside the visible area we stop right now + // This works because execution occurrences are ordered along the Y axis + if (toDraw.getY() > getY()) { + break; + } + } + } + return inActivation; + } + + @Override + public boolean contains(int xValue, int yValue) { + int x = getX(); + int y = getY(); + int width = getWidth(); + int height = getHeight(); + + // Used to create a rectangle which contains the message label to allow selection when clicking the label + int tempHeight = Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth(); + + // Is it a self message? + if (fStartLifeline == fEndLifeline) { + /* + * Rectangle.contains(x,y, width, height) does not works with negative height or width We check here if the + * rectangle width is negative. + */ + if (getName().length() * Metrics.getAverageCharWidth() > Metrics.swimmingLaneWidth() - Metrics.EXECUTION_OCCURRENCE_WIDTH / 2 + -Metrics.INTERNAL_MESSAGE_WIDTH) { + if (GraphNode.contains(x + Metrics.INTERNAL_MESSAGE_WIDTH + 10, y, Metrics.swimmingLaneWidth() - Metrics.EXECUTION_OCCURRENCE_WIDTH / 2 + -Metrics.INTERNAL_MESSAGE_WIDTH, Metrics.getMessageFontHeigth(), xValue, yValue)) { + return true; + } + } else { + if (GraphNode.contains(x + Metrics.INTERNAL_MESSAGE_WIDTH + 10, y, getName().length() * Metrics.getAverageCharWidth(), Metrics.getMessageFontHeigth(), xValue, yValue)) { + return true; + } + } + + // Test if the point is in part 1 of the self message + // see: "private void drawMessage (NGC context)" method for self message drawing schema + if (GraphNode.contains(x, y - Metrics.MESSAGE_SELECTION_TOLERANCE / 2, Metrics.INTERNAL_MESSAGE_WIDTH / 2, Metrics.MESSAGE_SELECTION_TOLERANCE, xValue, yValue)) { + return true; + } + + // Test if the point is in part 3 of the self message + if (GraphNode.contains(x + Metrics.INTERNAL_MESSAGE_WIDTH - Metrics.MESSAGE_SELECTION_TOLERANCE / 2, y, Metrics.MESSAGE_SELECTION_TOLERANCE, height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT, xValue, yValue)) { + return true; + } + + // Test if the point is in part 5 of the self message + if (GraphNode.contains(x, y + height - Metrics.MESSAGE_SELECTION_TOLERANCE / 2 + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT, Metrics.INTERNAL_MESSAGE_WIDTH / 2, Metrics.MESSAGE_SELECTION_TOLERANCE, xValue, yValue)) { + return true; + } + + // false otherwise + return false; + } + if (GraphNode.contains(x, y - tempHeight, width, tempHeight, xValue, yValue)) { + return true; + } + // false otherwise + return false; + } + + /** + * Method to draw the message using the graphical context. + * + * @param context A graphical context to draw in. + */ + protected void drawMessage(IGC context) { + int fX = 0; + int fY = 0; + int fW = 0; + int fH = 0; + + // temporary store the coordinates to avoid more methods calls + int x = getX(); + int y = getY(); + int width = getWidth(); + int height = getHeight(); + + ISDPreferences pref = SDViewPref.getInstance(); + + // UML2 found message (always drawn from left to right) + // or UML2 lost message (always drawn from left to right) + if ((fStartLifeline == null || fEndLifeline == null) && fStartLifeline != fEndLifeline) { + // Draw the message label above the message and centered + // The label is truncated if it cannot fit between the two message end + // 2*Metrics.MESSAGES_NAME_SPACING = space above the label + space below the label + IColor temp = context.getForeground(); + context.setForeground(pref.getFontColor(getColorPrefId())); + context.drawTextTruncatedCentred(getName(), x, y - Metrics.getMessageFontHeigth() - 2 * Metrics.MESSAGES_NAME_SPACING, width, 2 * Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth(), !isSelected()); + context.setForeground(temp); + int margin = 0; + if (fEndLifeline == null) { + margin = Metrics.MESSAGE_CIRCLE_RAY; + } + + // Draw the message main line + context.drawLine(x, y, x + width, y + height); + // Draw the two little lines which make a arrow part of the message + Double xt = Double.valueOf(Math.cos(0.75) * 7); + Double yt = Double.valueOf(Math.sin(0.75) * 7); + if (context.getLineStyle() == context.getLineSolidStyle()) { + IColor backcolor = context.getBackground(); + context.setBackground(context.getForeground()); + int[] points = { x + width - margin, y + height, x + width - xt.intValue() - margin, y + height - yt.intValue(), x + width - xt.intValue() - margin, y + height + yt.intValue(), x + width - margin, y + height }; + context.fillPolygon(points); + context.drawPolygon(points); + context.setBackground(backcolor); + } else { + int currentStyle = context.getLineStyle(); + int currentWidth = context.getLineWidth(); + context.setLineWidth(currentWidth + 2); + context.setLineStyle(context.getLineSolidStyle()); + context.drawLine(x + width - xt.intValue() - margin, y + height - yt.intValue(), x + width - margin, y + height); + context.drawLine(x + width - xt.intValue() - margin, y + height + yt.intValue(), x + width - margin, y + height); + context.setLineStyle(currentStyle); + context.setLineWidth(currentWidth); + } + IColor storedColor = context.getBackground(); + context.setBackground(context.getForeground()); + + // Draw a circle at the message end (endLifeline side) + int ray = Metrics.MESSAGE_CIRCLE_RAY; + if (context.getLineWidth() != Metrics.NORMAL_LINE_WIDTH) { + ray = ray + Metrics.SELECTION_LINE_WIDTH - Metrics.NORMAL_LINE_WIDTH; + } + if (fStartLifeline == null) { + context.fillOval(x - ray, y - ray, ray * 2, ray * 2); + } else { + context.fillOval(x + width - ray, y + height - ray, ray * 2, ray * 2); + } + context.setBackground(storedColor); + context.setForeground(pref.getFontColor(getColorPrefId())); + fX = x; + fY = y - yt.intValue(); + fW = width; + fH = height + 2 * yt.intValue(); + } + // it is self message (always drawn at the left side of the owning lifeLifeline) + else if (fStartLifeline != null && fEndLifeline != null && fStartLifeline == fEndLifeline) { + /* + * Self syncMessages are drawn in 5 parts 1 -----------+ + 2 + | | | 3 | + 5 + 4 -----------+ + */ + int tempy = Metrics.INTERNAL_MESSAGE_WIDTH / 2; + if (Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT <= Metrics.INTERNAL_MESSAGE_WIDTH) { + tempy = Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT / 2; + } + + // Part 1 + context.drawLine(x, y, x + Metrics.INTERNAL_MESSAGE_WIDTH / 2, y); + // Part 3 + context.drawLine(x + Metrics.INTERNAL_MESSAGE_WIDTH, y + tempy, x + Metrics.INTERNAL_MESSAGE_WIDTH, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT - tempy); + // Part 5 + context.drawLine(x, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT, x + Metrics.INTERNAL_MESSAGE_WIDTH / 2, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT); + + Double xt = Double.valueOf(Math.cos(0.75) * 7); + Double yt = Double.valueOf(Math.sin(0.75) * 7); + + fX = x; + fY = y; + fW = Metrics.INTERNAL_MESSAGE_WIDTH; + fH = height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT; + + // Draw the two little lines which make a arrow part of the message + if (context.getLineStyle() == context.getLineSolidStyle()) { + IColor backcolor = context.getBackground(); + context.setBackground(context.getForeground()); + int[] points = { x, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT, x + xt.intValue(), y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT + yt.intValue(), x + xt.intValue(), + y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT - yt.intValue(), x, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT }; + context.fillPolygon(points); + context.drawPolygon(points); + context.setBackground(backcolor); + } else { + int currentStyle = context.getLineStyle(); + int currentWidth = context.getLineWidth(); + context.setLineWidth(currentWidth + 2); + context.setLineStyle(context.getLineSolidStyle()); + context.drawLine(x + xt.intValue(), y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT + yt.intValue(), x, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT); + context.drawLine(x + xt.intValue(), y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT - yt.intValue(), x, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT); + context.setLineStyle(currentStyle); + context.setLineWidth(currentWidth); + } + + // Part 2 + context.drawArc(x, y, Metrics.INTERNAL_MESSAGE_WIDTH, 2 * tempy, 0, 90); + // Part 4 + context.drawArc(x, y + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT, Metrics.INTERNAL_MESSAGE_WIDTH, -2 * tempy, 0, -90); + + // Draw the message label above the message and centered + // The label is truncated if it cannot fit between the two message end + // 2*Metrics.MESSAGES_NAME_SPACING = space above the label + space below the label + + // the space available for the text is sorter if are drawing internal message on the last lifeline + context.setForeground(pref.getFontColor(getColorPrefId())); + if (fStartLifeline.getIndex() == fStartLifeline.getFrame().getHorizontalIndex()) { + context.drawTextTruncated(getName(), x + width + Metrics.INTERNAL_MESSAGE_V_MARGIN / 2, y, Metrics.swimmingLaneWidth() / 2 - Metrics.EXECUTION_OCCURRENCE_WIDTH + -Metrics.INTERNAL_MESSAGE_WIDTH, +Metrics.MESSAGES_NAME_SPACING + - Metrics.getMessageFontHeigth(), !isSelected()); + } else { + context.drawTextTruncated(getName(), x + width + Metrics.INTERNAL_MESSAGE_V_MARGIN / 2, y, Metrics.swimmingLaneWidth() - Metrics.EXECUTION_OCCURRENCE_WIDTH + -Metrics.INTERNAL_MESSAGE_WIDTH, + +Metrics.MESSAGES_NAME_SPACING - Metrics.getMessageFontHeigth(), !isSelected()); + } + } + // it is regular message + else if (fStartLifeline != null && fEndLifeline != null) { + // Draw the message main line + context.drawLine(x, y, x + width, y + height); + + int spaceBTWStartEnd = fEndLifeline.getX() - fStartLifeline.getX(); + + double a = height; + double b = width; + double angle = Math.atan(a / b); + // Compute the coordinates of the two little lines which make the arrow part of the message + int sign = 1; + if (spaceBTWStartEnd < 0) { + sign = -1; + } + Double x1 = Double.valueOf(sign * Math.cos(angle - 0.75) * 7); + Double y1 = Double.valueOf(sign * Math.sin(angle - 0.75) * 7); + Double x2 = Double.valueOf(sign * Math.cos(angle + 0.75) * 7); + Double y2 = Double.valueOf(sign * Math.sin(angle + 0.75) * 7); + + fX = getX(); + fY = y + height - y2.intValue(); + fW = getWidth(); + fH = y2.intValue() - y1.intValue() + 1; + if (fW < 0) { + fW = -fW; + fX = fX - fW; + } + + if (fH < 0) { + fH = -fH; + fY = fY - fH; + } + + // Draw the two little lines which make a arrow part of the message + if (context.getLineStyle() == context.getLineSolidStyle()) { + IColor backcolor = context.getBackground(); + context.setBackground(context.getForeground()); + int[] points = { x + width - x1.intValue(), y + height - y1.intValue(), x + width, y + height, x + width - x2.intValue(), y + height - y2.intValue(), x + width - x1.intValue(), y + height - y1.intValue() }; + context.fillPolygon(points); + context.drawPolygon(points); + context.setBackground(backcolor); + } else { + int currentStyle = context.getLineStyle(); + int currentWidth = context.getLineWidth(); + context.setLineWidth(currentWidth + 2); + context.setLineStyle(context.getLineSolidStyle()); + context.drawLine(x + width - x1.intValue(), y + height - y1.intValue(), x + width, y + height); + context.drawLine(x + width - x2.intValue(), y + height - y2.intValue(), x + width, y + height); + context.setLineStyle(currentStyle); + context.setLineWidth(currentWidth); + } + + // Draw the message label above the message and centered + // The label is truncated if it cannot fit between the two message end + // 2*Metrics.MESSAGES_NAME_SPACING = space above the label + space below the label + context.setForeground(pref.getFontColor(getColorPrefId())); + if (spaceBTWStartEnd > 0) { + context.drawTextTruncatedCentred(getName(), x, y + height / 2 - (2 * Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth()), width, 2 * Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth(), !isSelected()); + } else { + context.drawTextTruncatedCentred(getName(), x + width, y + height / 2 - (2 * Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth()), -width, 2 * Metrics.MESSAGES_NAME_SPACING + +Metrics.getMessageFontHeigth(), !isSelected()); + } + } + } + + @Override + public void draw(IGC context) { + if (!isVisible()) { + return; + } + + // Draw it selected?*/ + if (isSelected()) { + ISDPreferences pref = SDViewPref.getInstance(); + /* + * Draw it twice First time, bigger inverting selection colors Second time, regular drawing using selection + * colors This create the highlight effect + */ + context.setForeground(pref.getBackGroundColorSelection()); + context.setLineWidth(Metrics.SELECTION_LINE_WIDTH); + drawMessage(context); + context.setBackground(pref.getBackGroundColorSelection()); + context.setForeground(pref.getForeGroundColorSelection()); + // Second drawing is done after + } + context.setLineWidth(Metrics.NORMAL_LINE_WIDTH); + if (hasFocus()) { + context.setDrawTextWithFocusStyle(true); + } + drawMessage(context); + int oldStyle = context.getLineStyle(); + if (hasFocus()) { + context.setDrawTextWithFocusStyle(false); + drawFocus(context); + } + // restore the context + context.setLineStyle(oldStyle); + } + + /** + * Determine if two messages are identical. This default implementation considers that overlapping messages with + * same coordinates are identical. + * + * @param message - the message to compare with + * @return true if identical false otherwise + * + * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode#isSameAs(org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode) + */ + @Override + public boolean isSameAs(GraphNode message) { + if (message == null) { + return false; + } + if (!(message instanceof BaseMessage)) { + return super.isSameAs(message); + } + return ((getX() == message.getX()) && (getY() == message.getY()) && (getWidth() == message.getWidth()) && (getHeight() == message.getHeight())); + } + + /** + * Method drawRot. + * + * @param x A x coordinate + * @param y A y coordinate + * @param w A width + * @param h A height + * @param context A graphical context + */ + public void drawRot(int x, int y, int w, int h, IGC context) { + double angleA = Math.atan2(getHeight(), getWidth()); + double cosA = Math.cos(angleA); + double sinA = Math.sin(angleA); + + int gx = getX(); + int gy = getY(); + + int localHeight = h; + localHeight = localHeight / 2; + + double cw = Math.sqrt(w * w + getHeight() * getHeight()); + + int x1 = Math.round((float) ((x - gx) * cosA - (y - gy) * sinA)); + int y1 = Math.round((float) ((x - gx) * sinA + (y - gy) * cosA)); + + int x2 = Math.round((float) (cw * cosA - (y - gy) * sinA)); + int y2 = Math.round((float) (cw * sinA + (y - gy) * cosA)); + + int x3 = Math.round((float) (cw * cosA - (localHeight) * sinA)); + int y3 = Math.round((float) (cw * sinA + (localHeight) * cosA)); + + int x4 = Math.round((float) ((x - gx) * cosA - (localHeight) * sinA)); + int y4 = Math.round((float) ((x - gx) * sinA + (localHeight) * cosA)); + + int[] points = { x1 + getX(), y1 + getY(), x2 + getX(), y2 + getY(), x3 + getX(), y3 + getY(), x4 + getX(), y4 + getY() }; + context.drawPolygon(points); + } + + @Override + public void drawFocus(IGC context) { + + ISDPreferences pref = SDViewPref.getInstance(); + + if ((fStartLifeline != fEndLifeline) && (getStartOccurrence() == getEndOccurrence())) { + context.setLineStyle(context.getLineDotStyle()); + context.setLineWidth(Metrics.NORMAL_LINE_WIDTH); + context.setBackground(pref.getBackGroundColorSelection()); + context.setForeground(pref.getForeGroundColorSelection()); + context.drawFocus(getX(), getY() - 3, getWidth(), getHeight() + 6); + } else if ((fStartLifeline == fEndLifeline) && (getStartOccurrence() == getEndOccurrence())) { + context.drawFocus(getX(), getY() - 3, getWidth(), Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT + 6); + } else if ((fStartLifeline != fEndLifeline) && (getStartOccurrence() != getEndOccurrence())) { + context.setLineStyle(context.getLineDotStyle()); + context.setLineWidth(Metrics.NORMAL_LINE_WIDTH); + context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_LIFELINE_HEADER)); + context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_LIFELINE_HEADER)); + drawRot(getX(), getY() - 5, getWidth(), 10, context); + } else { + super.drawFocus(context); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/BasicExecutionOccurrence.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/BasicExecutionOccurrence.java new file mode 100755 index 0000000000..a1e94c5a8e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/BasicExecutionOccurrence.java @@ -0,0 +1,275 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IColor; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.ISDPreferences; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref; + +/** + * BasicExecutionOccurrence is the UML2 execution occurrence graphical representation. It is attached to one Lifeline, + * the event occurrence "duration" along the lifeline is defined by two event occurrences + * + * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Lifeline Lifeline for more event occurence details + * @version 1.0 + * @author sveyrier + * + */ +public class BasicExecutionOccurrence extends GraphNode { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The grahNode ID constant + */ + public static final String EXEC_OCC_TAG = "Execution_Occ"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The corresponding lifeline. + */ + private Lifeline fLifeline = null; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructore + */ + public BasicExecutionOccurrence() { + setColorPrefId(ISDPreferences.PREF_EXEC); + } + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + @Override + public int getX() { + if (fLifeline == null) { + return 0; + } + return fLifeline.getX() + Metrics.getLifelineWidth() / 2 - Metrics.EXECUTION_OCCURRENCE_WIDTH / 2; + } + + @Override + public int getY() { + if (fLifeline == null) { + return 0; + } + return fLifeline.getY() + fLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * getStartOccurrence(); + } + + @Override + public int getWidth() { + if (fLifeline == null) { + return 0; + } + return Metrics.EXECUTION_OCCURRENCE_WIDTH; + } + + @Override + public int getHeight() { + if (fLifeline == null) { + return 0; + } + return ((Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing())) * (getEndOccurrence() - getStartOccurrence()); + } + + @Override + public boolean contains(int xValue, int yValue) { + int x = getX(); + int y = getY(); + int width = getWidth(); + int height = getHeight(); + + if (GraphNode.contains(x, y, width, height, xValue, yValue)) { + return true; + } + + if (getNodeAt(xValue, yValue) != null) { + return true; + } + return false; + } + + @Override + public String getName() { + if (super.getName() == null || super.getName().equals("")) { //$NON-NLS-1$ + return fLifeline.getToolTipText(); + } + return super.getName(); + } + + /** + * Set the lifeline on which the execution occurrence appears. + * + * @param theLifeline - the parent lifeline + */ + public void setLifeline(Lifeline theLifeline) { + fLifeline = theLifeline; + } + + /** + * Get the lifeline on which the execution occurrence appears. + * + * @return - the parent lifeline + */ + public Lifeline getLifeline() { + return fLifeline; + } + + /** + * Get the execution start event occurrence + * + * @return the start event occurrence to set + */ + @Override + public int getStartOccurrence() { + return super.getStartOccurrence(); + } + + /** + * Set the execution end event occurrence + * + * @return the end event occurrence to set + */ + @Override + public int getEndOccurrence() { + return super.getEndOccurrence(); + } + + /** + * Set the execution start event occurrence + * + * @param occurrence the start event occurrence to set + */ + @Override + public void setStartOccurrence(int occurrence) { + super.setStartOccurrence(occurrence); + } + + /** + * Set the execution end event occurrence + * + * @param occurrence the end event occurrence to set + */ + @Override + public void setEndOccurrence(int occurrence) { + super.setEndOccurrence(occurrence); + } + + @Override + public void draw(IGC context) { + int x = getX(); + int y = getY(); + int width = getWidth(); + int height = getHeight(); + IColor tempFillColor = null; + IColor tempStrokeColor = null; + + ISDPreferences pref = SDViewPref.getInstance(); + + // The execution occurrence is selected + // if the owning lifeline is selected + if (fLifeline.isSelected() || isSelected()) { + context.setBackground(pref.getBackGroundColorSelection()); + context.setForeground(pref.getForeGroundColorSelection()); + } else { + tempFillColor = setUnselectedFillColor(context); + } + if (pref.useGradienColor()) { + context.fillGradientRectangle(x, y, width, height, false); + } else { + context.fillRectangle(x, y, width, height); + } + tempStrokeColor = setUnselectedStrokeColor(context); + context.drawRectangle(x, y, width, height); + if (tempFillColor != null) { + tempFillColor.dispose(); + } + if (tempStrokeColor != null) { + tempStrokeColor.dispose(); + } + if (hasFocus()) { + drawFocus(context); + } + super.drawChildenNodes(context); + } + + /** + * Rewrite this method in your extension in order to support customized fill colors + * + * @param context Graphics context + * @return IColor + */ + protected IColor setUnselectedFillColor(IGC context) { + + ISDPreferences pref = SDViewPref.getInstance(); + + if (pref.useGradienColor()) { + context.setGradientColor(pref.getBackGroundColor(ISDPreferences.PREF_EXEC)); + context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_FRAME)); + } else { + context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_EXEC)); + } + return null; + } + + /** + * Rewrite this method in your extension in order to support customized stroke colors + * + * @param context Graphics context + * @return IColor + */ + protected IColor setUnselectedStrokeColor(IGC context) { + context.setForeground(SDViewPref.getInstance().getForeGroundColor(ISDPreferences.PREF_EXEC)); + return null; + } + + @Override + public String getArrayId() { + return EXEC_OCC_TAG; + } + + @Override + public boolean positiveDistanceToPoint(int x, int y) { + if (getY() + getHeight() > y) { + return true; + } + return false; + } + + @Override + public boolean isVisible(int x, int y, int width, int height) { + if ((getLifeline() != null) && (getLifeline().isVisible(x, y, width, height))) { + int ly = getY(); + int lh = getHeight(); + if (ly >= y && ly < y + height) { + return true; + } + if (ly + lh > y && ly + lh <= y + height) { + return true; + } + if ((ly < y) && (ly + lh > y + height)) { + return true; + } + } + return false; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/BasicFrame.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/BasicFrame.java new file mode 100755 index 0000000000..ecea18c6d2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/BasicFrame.java @@ -0,0 +1,633 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.ISDPreferences; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref; + +/** + * The Frame class is the base sequence diagram graph nodes container.
    + * For instance, only one frame can be drawn in the View.
    + * Lifelines, Messages and Stop which are supposed to represent a Sequence diagram are drawn in a Frame.
    + * Only the graph node added to their representing list will be drawn. + * + * The lifelines are appended along the X axsis when added in a frame.
    + * The syncMessages are ordered along the Y axsis depending on the event occurrence they are attached to.
    + * + * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Lifeline Lifeline for more event occurence details + * @author sveyrier + * @version 1.0 + */ +public class BasicFrame extends GraphNode { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * Contains the max elapsed time between two consecutive messages in the whole frame + */ + private ITmfTimestamp fMaxTime = new TmfTimestamp(0); + /** + * Contains the min elapsed time between two consecutive messages in the whole frame + */ + private ITmfTimestamp fMinTime = new TmfTimestamp(0); + /** + * Indicate if the min and max elapsed time between two consecutive messages in the whole frame need to be computed + */ + private boolean fComputeMinMax = true; + /** + * Store the preference set by the user regarding the external time. This flag is used determine if the min and max + * need to be recomputed in case this preference is changed. + */ + private boolean fLastExternalTimePref = SDViewPref.getInstance().excludeExternalTime(); + /** + * The greater event occurrence created on graph nodes drawn in this Frame This directly impact the Frame height + */ + private int fVerticalIndex = 0; + /** + * The index along the x axis where the next lifeline will is drawn This directly impact the Frame width + */ + private int fHorizontalIndex = 0; + /** + * The time information flag. + */ + private boolean fHasTimeInfo = false; + /** + * The current Frame visible area - x coordinates + */ + private int fVisibleAreaX; + /** + * The current Frame visible area - y coordinates + */ + private int fVisibleAreaY; + /** + * The current Frame visible area - width + */ + private int fVisibleAreaWidth; + /** + * The current Frame visible area - height + */ + private int fVisibleAreaHeight; + /** + * The event occurrence spacing (-1 for none) + */ + private int fForceEventOccurrenceSpacing = -1; + /** + * Flag to indicate customized minumum and maximum. + */ + private boolean fCustomMinMax = false; + /** + * The minimum time between messages of the sequence diagram frame. + */ + private ITmfTimestamp fMinSDTime = new TmfTimestamp(); + /** + * The maximum time between messages of the sequence diagram frame. + */ + private ITmfTimestamp fMaxSDTime = new TmfTimestamp(); + /** + * Flag to indicate that initial minimum has to be computed. + */ + private boolean fInitSDMin = true; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Creates an empty frame. + */ + public BasicFrame() { + Metrics.setForcedEventSpacing(fForceEventOccurrenceSpacing); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + /** + * + * Returns the greater event occurence known by the Frame + * + * @return the greater event occurrence + */ + protected int getMaxEventOccurrence() { + return fVerticalIndex; + } + + /** + * Set the greater event occurrence created in GraphNodes included in the frame + * + * @param eventOccurrence the new greater event occurrence + */ + protected void setMaxEventOccurrence(int eventOccurrence) { + fVerticalIndex = eventOccurrence; + } + + /** + * This method increase the lifeline place holder The return value is usually assign to a lifeline. This can be used + * to set the lifelines drawing order. Also, calling this method two times and assigning only the last given index + * to a lifeline will increase this lifeline draw spacing (2 times the default spacing) from the last added + * lifeline. + * + * @return a new lifeline index + */ + protected int getNewHorizontalIndex() { + return ++fHorizontalIndex; + } + + /** + * Returns the current horizontal index + * + * @return the current horizontal index + * @see Frame#getNewHorizontalIndex() for horizontal index description + */ + protected int getHorizontalIndex() { + return fHorizontalIndex; + } + + @Override + public void addNode(GraphNode nodeToAdd) { + setComputeMinMax(true); + super.addNode(nodeToAdd); + } + + @Override + public int getX() { + return Metrics.FRAME_H_MARGIN; + } + + @Override + public int getY() { + return Metrics.FRAME_V_MARGIN; + } + + @Override + public int getWidth() { + if (fHorizontalIndex == 0) { + return 3 * Metrics.swimmingLaneWidth() + Metrics.LIFELINE_H_MAGIN * 2 - Metrics.FRAME_H_MARGIN - Metrics.LIFELINE_SPACING / 2; + } + return fHorizontalIndex * Metrics.swimmingLaneWidth() + Metrics.LIFELINE_H_MAGIN * 2 + 1 - Metrics.LIFELINE_SPACING; + } + + @Override + public int getHeight() { + // The Frame height depends on the maximum number of messages added to a lifeline + if (fVerticalIndex == 0) { + return 5 * (Metrics.getMessagesSpacing() + Metrics.getMessageFontHeigth()) + Metrics.LIFELINE_NAME_H_MARGIN + Metrics.FRAME_NAME_H_MARGIN + Metrics.getFrameFontHeigth() + Metrics.LIFELINE_VT_MAGIN + Metrics.LIFELINE_VB_MAGIN + + Metrics.LIFELINE_NAME_H_MARGIN + Metrics.FRAME_NAME_H_MARGIN + Metrics.getLifelineFontHeigth() * 2; + } + if (fForceEventOccurrenceSpacing >= 0) { + Metrics.setForcedEventSpacing(fForceEventOccurrenceSpacing); + } + return fVerticalIndex * (Metrics.getMessagesSpacing() + Metrics.getMessageFontHeigth()) + Metrics.LIFELINE_NAME_H_MARGIN + Metrics.FRAME_NAME_H_MARGIN + Metrics.getFrameFontHeigth() + Metrics.LIFELINE_VT_MAGIN + Metrics.LIFELINE_VB_MAGIN + + Metrics.LIFELINE_NAME_H_MARGIN + Metrics.FRAME_NAME_H_MARGIN + Metrics.getLifelineFontHeigth() * 2; + } + + /** + * @return true if mininum and maximum time needs to be calculated else false + * @since 2.0 + */ + protected boolean isComputeMinMax() { + return fComputeMinMax; + } + + /** + * @return true if mininum and maximum time needs to be calculated else false + * @since 2.0 + */ + protected boolean isCustomMinMax() { + return fCustomMinMax; + } + + /** + * gets the initialization flag for SD minimum. + * + * @return the initialization flag for SD minimum + * @since 2.0 + */ + protected boolean getInitSDMin() { + return fInitSDMin; + } + + /** + * Returns the graph node which contains the point given in parameter for the given graph node list and starting the + * iteration at the given index
    + * WARNING: Only graph nodes with smaller coordinates than the current visible area can be returned.
    + * + * @param x the x coordinate of the point to test + * @param y the y coordinate of the point to test + * @param list the list to search in + * @param fromIndex list browsing starting point + * @return the graph node containing the point given in parameter, null otherwise + * + * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode#getNodeFromListAt(int, int, java.util.List, int) + */ + @Override + protected GraphNode getNodeFromListAt(int x, int y, List list, int fromIndex) { + if (list == null) { + return null; + } + for (int i = fromIndex; i < list.size(); i++) { + GraphNode node = list.get(i); + // only lifeline list is x ordered + // Stop browsing the list if the node is outside the visible area + // all others nodes will be not visible + if ((node instanceof Lifeline) && (node.getX() > fVisibleAreaX + fVisibleAreaWidth)) { + break; + } + if (node.getHeight() < 0) { + if (node.getY() + node.getHeight() > fVisibleAreaY + fVisibleAreaHeight) { + break; + } + } else { + if (node.getY() > fVisibleAreaY + fVisibleAreaHeight) { + break; + } + } + if (node.contains(x, y)) { + return node; + } + } + return null; + } + + /** + * Draw the Frame rectangle + * + * @param context the context to draw to + */ + protected void drawFrame(IGC context) { + + ISDPreferences pref = SDViewPref.getInstance(); + + context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_FRAME)); + context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_FRAME)); + + int x = getX(); + int y = getY(); + int w = getWidth(); + int h = getHeight(); + + // Draw the frame main rectangle + context.fillRectangle(x, y, w, h); + context.drawRectangle(x, y, w, h); + + context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_FRAME_NAME)); + context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_FRAME_NAME)); + context.setFont(pref.getFont(ISDPreferences.PREF_FRAME_NAME)); + + int nameWidth = context.textExtent(getName()) + 2 * Metrics.FRAME_NAME_V_MARGIN; + int nameHeight = Metrics.getFrameFontHeigth() + +Metrics.FRAME_NAME_H_MARGIN * 2; + + // Draw the frame name area + if (nameWidth > w) { + nameWidth = w; + } + + int[] points = { x, y, x + nameWidth, y, x + nameWidth, y - 11 + nameHeight, x - 11 + nameWidth, y + nameHeight, x, y + nameHeight, x, y + nameHeight }; + context.fillPolygon(points); + context.drawPolygon(points); + context.drawLine(x, y, x, y + nameHeight); + + context.setForeground(pref.getFontColor(ISDPreferences.PREF_FRAME_NAME)); + context.drawTextTruncatedCentred(getName(), x, y, nameWidth - 11, nameHeight, false); + + context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_FRAME)); + context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_FRAME)); + } + + @Override + public void draw(IGC context) { + draw(context, true); + } + + /** + * Draws the Frame on the given context.
    + * This method start width GraphNodes ordering if needed.
    + * After, depending on the visible area, only visible GraphNodes are drawn.
    + * + * @param context the context to draw to + * @param drawFrame indicate if the frame rectangle need to be redrawn + * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode#draw(IGC) + */ + protected void draw(IGC context, boolean drawFrame) { + fVisibleAreaHeight = context.getVisibleHeight(); + fVisibleAreaWidth = context.getVisibleWidth(); + fVisibleAreaX = context.getContentsX(); + fVisibleAreaY = context.getContentsY(); + + if (fForceEventOccurrenceSpacing >= 0) { + Metrics.setForcedEventSpacing(fForceEventOccurrenceSpacing); + } else { + Metrics.setForcedEventSpacing(-1); + } + + super.drawChildenNodes(context); + } + + /** + * Sets the event occurrence spacing (-1 for none) + * + * @param space A spacing to set. + */ + public void forceEventOccurrenceSpacing(int space) { + fForceEventOccurrenceSpacing = space; + } + + /** + * Return the X coordinates of the frame visible area + * + * @return the X coordinates of the frame visible area + */ + public int getVisibleAreaX() { + return fVisibleAreaX; + } + + /** + * Return the frame visible area width + * + * @return the frame visible area width + */ + public int getVisibleAreaWidth() { + return fVisibleAreaWidth; + } + + /** + * Return the frame visible area height + * + * @return the frame visible area height + */ + public int getVisibleAreaHeight() { + return fVisibleAreaHeight; + } + + /** + * Return the X coordinates of the frame visible area + * + * @return the X coordinates of the frame visible area + */ + public int getVisibleAreaY() { + return fVisibleAreaY; + } + + /** + * Return the minimum time stored in the frame taking all GraphNodes into account + * + * @return the minimum GraphNode time + * @since 2.0 + */ + public ITmfTimestamp getMinTime() { + if (fLastExternalTimePref != SDViewPref.getInstance().excludeExternalTime()) { + fLastExternalTimePref = SDViewPref.getInstance().excludeExternalTime(); + setComputeMinMax(true); + } + if ((fComputeMinMax) && (!fCustomMinMax)) { + computeMinMax(); + setComputeMinMax(false); + } + return fMinTime; + } + + /** + * Set the minimum timestamp of the frame. + * + * @param min + * The minimum timestamp + * @since 2.0 + */ + public void setMin(ITmfTimestamp min) { + fMinTime = min; + fCustomMinMax = true; + } + + /** + * Set the maximum timestamp of the frame. + * + * @param max + * The maximum timestamp + * @since 2.0 + */ + public void setMax(ITmfTimestamp max) { + fMaxTime = max; + fCustomMinMax = true; + } + + /** + * Reset min/max timestamp values to the default ones. + */ + public void resetCustomMinMax() { + fCustomMinMax = false; + setComputeMinMax(true); + } + + /** + * Return the maximum time stored in the frame taking all GraphNodes into account + * + * @return the maximum GraphNode time + * @since 2.0 + */ + public ITmfTimestamp getMaxTime() { + if (fLastExternalTimePref != SDViewPref.getInstance().excludeExternalTime()) { + fLastExternalTimePref = SDViewPref.getInstance().excludeExternalTime(); + setComputeMinMax(true); + } + if (fComputeMinMax) { + computeMinMax(); + setComputeMinMax(false); + } + return fMaxTime; + } + + /** + * Computes the minimum and maximum time between consecutive messages within the frame. + */ + protected void computeMaxMinTime() { + if (!fInitSDMin) { + return; + } + + List timeArray = buildTimeArray(); + + if ((timeArray == null) || timeArray.isEmpty()) { + return; + } + for (int i = 0; i < timeArray.size(); i++) { + SDTimeEvent m = timeArray.get(i); + + if (m.getTime().compareTo(fMaxSDTime, true) > 0) { + fMaxSDTime = m.getTime(); + } + + if ((m.getTime().compareTo(fMinSDTime, true) < 0) || fInitSDMin) { + fMinSDTime = m.getTime(); + fInitSDMin = false; + } + } + } + + /** + * Returns the minimum time between consecutive messages. + * + * @return the minimum time between consecutive messages + * @since 2.0 + */ + public ITmfTimestamp getSDMinTime() { + computeMaxMinTime(); + return fMinSDTime; + } + + /** + * Returns the maximum time between consecutive messages. + * + * @return the maximum time between consecutive messages + * @since 2.0 + */ + public ITmfTimestamp getSDMaxTime() { + computeMaxMinTime(); + return fMaxSDTime; + } + + /** + * Browse all the GraphNode to compute the min and max times store in the Frame + */ + protected void computeMinMax() { + List timeArray = buildTimeArray(); + + if ((timeArray == null) || timeArray.isEmpty()) { + return; + } + for (int i = 0; i < timeArray.size() - 1; i++) { + SDTimeEvent m1 = timeArray.get(i); + SDTimeEvent m2 = timeArray.get(i + 1); + + updateMinMax(m1, m2); + } + } + + /** + * Updates the minimum and maximum time between consecutive message within the frame based on the given values. + * + * @param m1 A first SD time event. + * @param m2 A second SD time event. + */ + protected void updateMinMax(SDTimeEvent m1, SDTimeEvent m2) { + ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime()); + if (fComputeMinMax) { + fMinTime = delta; + if (fMinTime.compareTo(TmfTimestamp.ZERO, false) < 0) { + fMinTime = new TmfTimestamp(0, m1.getTime().getScale(), m1.getTime().getPrecision()); + } + fMaxTime = fMinTime; + setComputeMinMax(false); + } + + if ((delta.compareTo(fMinTime, true) < 0) && (delta.compareTo(TmfTimestamp.ZERO, false) > 0)) { + fMinTime = delta; + } + + if ((delta.compareTo(fMaxTime, true) > 0) && (delta.compareTo(TmfTimestamp.ZERO, false) > 0)) { + fMaxTime = delta; + } + } + + /** + * Builds the time array based on the list of graph nodes. + * + * @return the time array else empty list. + */ + protected List buildTimeArray() { + if (!hasChildren()) { + return new ArrayList<>(); + } + + Iterator it = getForwardSortMap().keySet().iterator(); + List timeArray = new ArrayList<>(); + while (it.hasNext()) { + String nodeType = it.next(); + List list = getNodeMap().get(nodeType); + for (int i = 0; i < list.size(); i++) { + Object timedNode = list.get(i); + if ((timedNode instanceof ITimeRange) && ((ITimeRange) timedNode).hasTimeInfo()) { + int event = list.get(i).getStartOccurrence(); + ITmfTimestamp time = ((ITimeRange) list.get(i)).getStartTime(); + SDTimeEvent f = new SDTimeEvent(time, event, (ITimeRange) list.get(i)); + timeArray.add(f); + if (event != list.get(i).getEndOccurrence()) { + event = (list.get(i)).getEndOccurrence(); + time = ((ITimeRange) list.get(i)).getEndTime(); + f = new SDTimeEvent(time, event, (ITimeRange) list.get(i)); + timeArray.add(f); + } + } + } + } + return timeArray; + } + + @Override + public String getArrayId() { + return null; + } + + @Override + public boolean contains(int x, int y) { + return false; + } + + /** + * @return true if frame has time info else false + * @since 2.0 + */ + public boolean hasTimeInfo() { + return fHasTimeInfo; + } + + /** + * Sets the flag whether the frame has time info or not + * @since 2.0 + * @param hasTimeInfo + * true if frame has time info else false + */ + public void setHasTimeInfo(boolean hasTimeInfo) { + fHasTimeInfo = hasTimeInfo; + } + + /** + * Sets the flag for minimum and maximum computation. + * @param computeMinMax + * true if mininum and maximum time needs to be calculated else false + * @since 2.0 + */ + public void setComputeMinMax(boolean computeMinMax) { + fComputeMinMax = computeMinMax; + } + + /** + * Sets the initialization flag for SD minimum. + * + * @param initSDMin + * the flag to set + * @since 2.0 + */ + public void setInitSDMin(boolean initSDMin) { + fInitSDMin = initSDMin; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/EllipsisMessage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/EllipsisMessage.java new file mode 100755 index 0000000000..4291ddcca0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/EllipsisMessage.java @@ -0,0 +1,141 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IColor; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.ISDPreferences; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref; + +/** + * Class to draw Ellipsis Message. + * + * @version 1.0 + * @author sveyrier + * + */ +public class EllipsisMessage extends AsyncMessage { + + @Override + public int getX() { + if (getStartLifeline() == null) { + return super.getX() + super.getWidth() - 16; + } + return super.getX(); + } + + @Override + public int getY() { + return super.getY() + 3; + } + + @Override + public int getWidth() { + return 16; + } + + @Override + protected void drawMessage(IGC context) { + // temporary store the coordinates to avoid more methods calls + int x = super.getX(); + int y = getY(); + int width = super.getWidth(); + int height = getHeight(); + + // UML2 found message (always drawn from left to right) + if (getStartLifeline() == null && getEndLifeline() != null) { + // Draw the message label above the message and centered + // The label is truncated if it cannot fit between the two message end + // 2*Metrics.MESSAGES_NAME_SPACING = space above the label + space below the label + context.drawTextTruncatedCentred(getName(), x, y - Metrics.getMessageFontHeigth() - 2 * Metrics.MESSAGES_NAME_SPACING, width, 2 * Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth(), !isSelected()); + + int currentStyle = context.getLineStyle(); + context.setLineStyle(context.getLineSolidStyle()); + // Draw the message main line + context.drawRectangle(x + width - 5, y, x + width - 6, y + height); + context.drawRectangle(x + width - 10, y, x + width - 11, y + height); + context.drawRectangle(x + width - 15, y, x + width - 16, y + height); + context.setLineStyle(currentStyle); + + IColor storedColor = context.getBackground(); + context.setBackground(context.getForeground()); + context.fillRectangle(x + width - 5, y, x + width - 6, y + height); + context.fillRectangle(x + width - 10, y, x + width - 11, y + height); + context.fillRectangle(x + width - 15, y, x + width - 16, y + height); + context.setBackground(storedColor); + } + // UML2 lost message (always drawn from left to right) + else if (getEndLifeline() == null && getStartLifeline() != null) { + // Draw the message label above the message and centered + // The label is truncated if it cannot fit between the two message end + // 2*Metrics.MESSAGES_NAME_SPACING = space above the label + space below the label + context.drawTextTruncatedCentred(getName(), x, y - Metrics.getMessageFontHeigth() - 2 * Metrics.MESSAGES_NAME_SPACING, width, 2 * Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth(), !isSelected()); + + int currentStyle = context.getLineStyle(); + context.setLineStyle(context.getLineSolidStyle()); + // Draw the message main line + context.drawRectangle(x + 5, y, 1, 1); + context.drawRectangle(x + 10, y, 1, 1); + context.drawRectangle(x + 15, y, 1, 1); + + context.setLineStyle(currentStyle); + + IColor storedColor = context.getBackground(); + context.setBackground(context.getForeground()); + context.fillRectangle(x + 5, y, 1, 1); + context.fillRectangle(x + 10, y, 1, 1); + context.fillRectangle(x + 15, y, 1, 1); + + context.setBackground(storedColor); + + } else { + super.draw(context); + } + } + + @Override + public void draw(IGC context) { + if (!isVisible()) { + return; + } + + ISDPreferences pref = SDViewPref.getInstance(); + + // Draw it selected?*/ + if (isSelected()) { + + /* + * Draw it twice First time, bigger inverting selection colors Second time, regular drawing using selection + * colors This create the highlight effect + */ + context.setForeground(pref.getBackGroundColorSelection()); + context.setLineWidth(Metrics.SELECTION_LINE_WIDTH); + drawMessage(context); + context.setBackground(pref.getBackGroundColorSelection()); + context.setForeground(pref.getForeGroundColorSelection()); + // Second drawing is done after the else + } else { + context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_ASYNC_MESS)); + context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_ASYNC_MESS)); + } + if (hasFocus()) { + context.setDrawTextWithFocusStyle(true); + } + context.setLineWidth(Metrics.NORMAL_LINE_WIDTH); + drawMessage(context); + context.setLineWidth(Metrics.NORMAL_LINE_WIDTH); + if (hasFocus()) { + context.setDrawTextWithFocusStyle(false); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/ExecutionOccurrence.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/ExecutionOccurrence.java new file mode 100755 index 0000000000..df27ae6b1d --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/ExecutionOccurrence.java @@ -0,0 +1,267 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; + +import java.util.Arrays; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IColor; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IImage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.ISDPreferences; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref; + +/** + * ExecutionOccurrence is the UML2 execution occurrence graphical representation. It is a BasicExecutionOccurrence on + * which you can customize fill and/or. + * + * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Lifeline Lifeline for more event occurence details + * @version 1.0 + * @author sveyrier + * + */ +public class ExecutionOccurrence extends BasicExecutionOccurrence implements ITimeRange { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * Set the red, green and blue value of the optional color to be used for filling the execution occurrence. + */ + private int[] fFillRGB; + /** + * Set the red, green and blue value of the optional color to be used for drawing the execution occurrence + */ + private int[] fStrokeRGB; + /** + * The occurrence image. + */ + private IImage fImage; + /** + * The top ellipses image. + */ + private IImage fEllipsesImage; + /** + * The start time stamp. + */ + private ITmfTimestamp fStartTime; + /** + * The end time stamp; + */ + private ITmfTimestamp fEndTime; + /** + * Flag to indicate whether time information is available or not. + */ + private boolean fHasTimeInfo; + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public void setLifeline(Lifeline theLifeline) { + super.setLifeline(theLifeline); + if (getLifeline() != null && fHasTimeInfo) { + getLifeline().setTimeInfo(true); + if (getLifeline().getFrame() != null) { + getLifeline().getFrame().setHasTimeInfo(true); + } + } + } + + /** + * Set the red, green and blue value of the optional color to be used for filling the execution occurrence. + * + * @param red A value for red. + * @param green A green value for green. + * @param blue A value blue. + */ + public void setFillColor(int red, int green, int blue) { + fFillRGB = new int[3]; + fFillRGB[0] = red; + fFillRGB[1] = green; + fFillRGB[2] = blue; + } + + /** + * Set the red, green and blue value of the optional color to be used for drawing the execution occurrence + * + * @param red A value for red. + * @param green A green value for green. + * @param blue A value blue. + */ + public void setStrokeColor(int red, int green, int blue) { + fStrokeRGB = new int[3]; + fStrokeRGB[0] = red; + fStrokeRGB[1] = green; + fStrokeRGB[2] = blue; + } + + /** + * Set the corresponding image. + * + * @param image A image to set. + */ + public void setImage(IImage image) { + fImage = image; + } + + /** + * Set the top ellipses image. + * + * @param image A image to set. + */ + public void setTopEllipsesImage(IImage image) { + fEllipsesImage = image; + } + + /** + * Set the time when the execution occurrence starts. + * + * @param time the time when the execution occurrence starts + * @since 2.0 + */ + public void setStartTime(ITmfTimestamp time) { + fStartTime = time; + fHasTimeInfo = true; + if (getLifeline() != null) { + getLifeline().setTimeInfo(true); + } + } + + /** + * Set the time when the execution occurrence ends. + * + * @param time the time when the execution occurrence ends + * @since 2.0 + */ + public void setEndTime(ITmfTimestamp time) { + fEndTime = time; + fHasTimeInfo = true; + if (getLifeline() != null) { + getLifeline().setTimeInfo(true); + } + } + + /** + * @since 2.0 + */ + @Override + public ITmfTimestamp getStartTime() { + return fStartTime; + } + + /** + * @since 2.0 + */ + @Override + public ITmfTimestamp getEndTime() { + return fEndTime; + } + + @Override + public boolean hasTimeInfo() { + return fHasTimeInfo; + } + + /** + * @return the RGB of the occurrence filler. + * @since 2.0 + */ + public int[] getFillRGB() { + if (fFillRGB == null) { + return null; + } + return Arrays.copyOf(fFillRGB, fFillRGB.length); + } + + /** + * @return the RGB of the occurrence filler. + * @since 2.0 + */ + public int[] getStrokeRGB() { + if (fStrokeRGB == null) { + return null; + } + return Arrays.copyOf(fStrokeRGB, fStrokeRGB.length); + } + + /** + * @return the image. + * @since 2.0 + */ + protected IImage getImage() { + return fImage; + } + + /** + * @return the image. + * @since 2.0 + */ + protected IImage getEllipsesImage() { + return fEllipsesImage; + } + + @Override + public void draw(IGC context) { + super.draw(context); + int x = getX(); + int y = getY(); + int width = getWidth(); + int height = getHeight(); + if (fImage != null) { + context.drawImage(fImage, x + width - 4, y + height - 11, 8, 11); + } + if (fEllipsesImage != null) { + context.drawImage(fEllipsesImage, x + width, y, 40, 10); + } + } + + @Override + protected IColor setUnselectedFillColor(IGC context) { + ISDPreferences pref = SDViewPref.getInstance(); + if (fFillRGB != null) { + IColor tempFillColor = context.createColor(fFillRGB[0], fFillRGB[1], fFillRGB[2]); + if (pref.useGradienColor()) { + context.setGradientColor(tempFillColor); + context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_EXEC)); + context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_FRAME)); + } else { + context.setBackground(tempFillColor); + } + return tempFillColor; + } + return super.setUnselectedFillColor(context); + } + + @Override + protected IColor setUnselectedStrokeColor(IGC context) { + if (fStrokeRGB != null) { + IColor tempStrokeColor = context.createColor(fStrokeRGB[0], fStrokeRGB[1], fStrokeRGB[2]); + context.setForeground(tempStrokeColor); + return tempStrokeColor; + } + return super.setUnselectedStrokeColor(context); + } + + /** + * Sets the flag whether the frame has time info or not + * @since 2.0 + * @param hasTimeInfo + * true if frame has time info else false + */ + public void setHasTimeInfo(boolean hasTimeInfo) { + fHasTimeInfo = hasTimeInfo; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/Frame.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/Frame.java new file mode 100755 index 0000000000..d5dcf6f3da --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/Frame.java @@ -0,0 +1,1215 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IColor; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.TimeEventComparator; + +/** + * The Frame class is the base sequence diagram graph nodes container.
    + * For instance, only one frame can be drawn in the View.
    + * Lifelines, Messages and Stop which are supposed to represent a Sequence diagram are drawn in a Frame.
    + * Only the graph node added to their representing list will be drawn. + * + * The lifelines are appended along the X axsis when added in a frame.
    + * The syncMessages are ordered along the Y axsis depending on the event occurrence they are attached to.
    + * + * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Lifeline Lifeline for more event occurence details + * @author sveyrier + * @version 1.0 + */ +public class Frame extends BasicFrame { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The lifeline that is current highlighted. + */ + private Lifeline fHighlightLifeline = null; + /** + * The value of the start event. + */ + private int fStartEvent = 0; + /** + * The number of events in the frame. + */ + private int fNbEvent = 0; + /** + * The color for highlighting. + */ + private IColor fHighlightColor = null; + /** + * The list of time events of the corresponding execution occurrences. + */ + private List fExecutionOccurrencesWithTime; + /** + * The Array of lifeline categories. + */ + private LifelineCategories[] fLifelineCategories = null; + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + /** + * Returns a list of all lifelines known by this frame. Known lifelines are the only one which can be displayed on + * screen. + * + * @return the lifelines list + */ + protected List getLifelines() { + if (!hasChildren()) { + return null; + } + return getNodeMap().get(Lifeline.LIFELINE_TAG); + } + + /** + * Returns the number of lifelines stored in the frame + * + * @return the number of lifelines + */ + public int lifeLinesCount() { + List lifelines = getLifelines(); + if (lifelines != null) { + return lifelines.size(); + } + return 0; + } + + /** + * Returns the lifeline at the given index in the lifelines array + * + * @param index the position in the lifeline array + * @return the lifeline or null + */ + public Lifeline getLifeline(int index) { + if ((getLifelines() != null) && (index >= 0) && (index < lifeLinesCount())) { + return (Lifeline) getLifelines().get(index); + } + return null; + } + + /** + * Returns a list of syncMessages known by this frame. Known syncMessages are the only on which can be displayed on + * screen + * + * @return the syncMessages list + */ + protected List getSyncMessages() { + if (!hasChildren()) { + return null; + } + return getNodeMap().get(SyncMessage.SYNC_MESS_TAG); + } + + /** + * Returns the number of syncMessages stored in the frame + * + * @return the number of syncMessage + */ + public int syncMessageCount() { + if (getSyncMessages() != null) { + return getSyncMessages().size(); + } + return 0; + } + + /** + * Returns the syncMessage at the given index in the syncMessages array + * + * @param index the position in the syncMessages array + * @return the syncMessage or null + */ + public SyncMessage getSyncMessage(int index) { + if ((getSyncMessages() != null) && (index >= 0) && (index < getSyncMessages().size())) { + return (SyncMessage) getSyncMessages().get(index); + } + return null; + } + + /** + * Returns a list of asyncMessages known by this frame. Known asyncMessages are the only on which can be displayed + * on screen + * + * @return the asyncMessages list or null + */ + protected List getAsyncMessages() { + if (!hasChildren()) { + return null; + } + return getNodeMap().get(AsyncMessage.ASYNC_MESS_TAG); + } + + /** + * Returns the number of asyncMessage stored in the frame + * + * @return the number of asyncMessage + */ + public int asyncMessageCount() { + if (getAsyncMessages() != null) { + return getAsyncMessages().size(); + } + return 0; + } + + /** + * Returns the asyncMessage at the given index in the asyncMessage array + * + * @param index the position in the asyncMessage array + * @return the asyncMessage or null + */ + public AsyncMessage getAsyncMessage(int index) { + if ((getAsyncMessages() != null) && (index >= 0) && (index < getAsyncMessages().size())) { + return (AsyncMessage) getAsyncMessages().get(index); + } + return null; + } + + /** + * Returns a list of syncMessages return known by this frame. Known syncMessages return are the only on which can be + * displayed on screen + * + * @return the syncMessages return list or null + */ + protected List getSyncMessagesReturn() { + if (!hasChildren()) { + return null; + } + return getNodeMap().get(SyncMessageReturn.SYNC_MESS_RET_TAG); + } + + /** + * Returns the number of syncMessageReturn stored in the frame + * + * @return the number of syncMessageReturn + */ + public int syncMessageReturnCount() { + if (getSyncMessagesReturn() != null) { + return getSyncMessagesReturn().size(); + } + return 0; + } + + /** + * Returns the syncMessageReturn at the given index in the syncMessageReturn array + * + * @param index the position in the syncMessageReturn array + * @return the syncMessageReturn or null + */ + public SyncMessageReturn getSyncMessageReturn(int index) { + if ((getSyncMessagesReturn() != null) && (index >= 0) && (index < getSyncMessagesReturn().size())) { + return (SyncMessageReturn) getSyncMessagesReturn().get(index); + } + return null; + } + + /** + * Returns a list of asyncMessageRetun known by this frame. Known asyncMessageRetun are the only on which can be + * displayed on screen + * + * @return the asyncMessageRetun list or null + */ + protected List getAsyncMessagesReturn() { + if (!hasChildren()) { + return null; + } + return getNodeMap().get(AsyncMessageReturn.ASYNC_MESS_RET_TAG); + } + + /** + * Returns the number of asyncMessageReturn stored in the frame + * + * @return the number of asyncMessageReturn + */ + public int asyncMessageReturnCount() { + if (getAsyncMessagesReturn() != null) { + return getAsyncMessagesReturn().size(); + } + return 0; + } + + /** + * Returns the asyncMessageReturn at the given index in the asyncMessageReturn array + * + * @param index the position in the asyncMessageReturn array + * @return the asyncMessageReturn or null + */ + public AsyncMessageReturn getAsyncMessageReturn(int index) { + if ((getAsyncMessagesReturn() != null) && (index >= 0) && (index < getAsyncMessagesReturn().size())) { + return (AsyncMessageReturn) getAsyncMessagesReturn().get(index); + } + return null; + } + + /** + * Adds a lifeline to the frame lifelines list. The lifeline X drawing order depends on the lifeline addition order + * into the frame lifelines list. + * + * @param lifeline the lifeline to add + */ + public void addLifeLine(Lifeline lifeline) { + setComputeMinMax(true); + if (lifeline == null) { + return; + } + // set the lifeline parent frame + lifeline.setFrame(this); + // Increate the frame lifeline counter + // and set the lifeline drawing order + lifeline.setIndex(getNewHorizontalIndex()); + if (lifeline.hasTimeInfo()) { + setHasTimeInfo(true); + } + // add the lifeline to the lifelines list + addNode(lifeline); + } + + /** + * Returns the first visible lifeline drawn in the view + * + * @return the first visible lifeline index + */ + public int getFirstVisibleLifeline() { + if (!hasChildren()) { + return 0; + } else if (getIndexes().get(Lifeline.LIFELINE_TAG) != null) { + return getIndexes().get(Lifeline.LIFELINE_TAG).intValue(); + } + return 0; + } + + /** + * Returns the first visible synchronous message drawn in the view + * + * @return the first visible synchronous message index + */ + public int getFirstVisibleSyncMessage() { + if (!hasChildren()) { + return 0; + } else if (getIndexes().get(SyncMessage.SYNC_MESS_TAG) != null) { + return getIndexes().get(SyncMessage.SYNC_MESS_TAG).intValue(); + } + return 0; + } + + /** + * Returns the first visible synchronous message return drawn in the view + * + * @return the first visible synchronous message return index + */ + public int getFirstVisibleSyncMessageReturn() { + if (!hasChildren()) { + return 0; + } else if (getIndexes().get(SyncMessageReturn.SYNC_MESS_RET_TAG) != null) { + return getIndexes().get(SyncMessageReturn.SYNC_MESS_RET_TAG).intValue(); + } + return 0; + } + + /** + * Returns the first visible synchronous message drawn in the view + * + * @return the first visible synchronous message index + */ + public int getFirstVisibleAsyncMessage() { + if (!hasChildren()) { + return 0; + } else if (getIndexes().get(AsyncMessage.ASYNC_MESS_TAG) != null) { + return getIndexes().get(AsyncMessage.ASYNC_MESS_TAG).intValue(); + } + return 0; + } + + /** + * Returns the first visible synchronous message return drawn in the view + * + * @return the first visible synchronous message return index + */ + public int getFirstVisibleAsyncMessageReturn() { + if (!hasChildren()) { + return 0; + } else if (getIndexes().get(AsyncMessageReturn.ASYNC_MESS_RET_TAG) != null) { + return getIndexes().get(AsyncMessageReturn.ASYNC_MESS_RET_TAG).intValue(); + } + return 0; + } + + /** + * Returns the list of execution occurrences. + * + * @return the list of execution occurrences + */ + public List getExecutionOccurrencesWithTime() { + return fExecutionOccurrencesWithTime; + } + + /** + * Inserts a lifeline after a given lifeline. + * + * @param toInsert A lifeline to insert + * @param after A lifelife the toInsert-lifeline will be inserted after. + */ + public void insertLifelineAfter(Lifeline toInsert, Lifeline after) { + if ((toInsert == null)) { + return; + } + if (toInsert == after) { + return; + } + int insertPoint = 0; + if (after != null) { + insertPoint = after.getIndex(); + } + int removePoint = toInsert.getIndex() - 1; + if (removePoint >= insertPoint) { + getLifelines().remove(removePoint); + } + getLifelines().add(insertPoint, toInsert); + if (removePoint < insertPoint) { + getLifelines().remove(removePoint); + } + + if (removePoint >= insertPoint) { + toInsert.setIndex(insertPoint + 1); + } else { + toInsert.setIndex(insertPoint - 1); + } + + insertPoint++; + if (removePoint >= insertPoint) { + for (int i = insertPoint; i < getLifelines().size(); i++) { + getLifeline(i).setIndex(i + 1); + } + } else { + for (int i = 0; i < insertPoint && i < getLifelines().size(); i++) { + getLifeline(i).setIndex(i + 1); + } + } + } + + /** + * Inserts a lifeline before a given lifeline. + * + * @param toInsert + * A lifeline to insert + * @param before + * A lifeline the toInsert-lifeline will be inserted before. + */ + public void insertLifelineBefore(Lifeline toInsert, Lifeline before) { + if ((toInsert == null)) { + return; + } + if (toInsert == before) { + return; + } + int insertPoint = 0; + if (before != null) { + insertPoint = before.getIndex() - 1; + } + int removePoint = toInsert.getIndex() - 1; + if (removePoint >= insertPoint) { + getLifelines().remove(removePoint); + } + getLifelines().add(insertPoint, toInsert); + if (removePoint < insertPoint) { + getLifelines().remove(removePoint); + } + + if (removePoint >= insertPoint) { + toInsert.setIndex(insertPoint + 1); + } else { + toInsert.setIndex(insertPoint - 1); + } + + insertPoint++; + if (removePoint >= insertPoint) { + for (int i = insertPoint; i < getLifelines().size(); i++) { + getLifeline(i).setIndex(i + 1); + } + } else { + for (int i = 0; i < insertPoint && i < getLifelines().size(); i++) { + getLifeline(i).setIndex(i + 1); + } + } + } + + /** + * Gets the closer life line to the given x-coordinate. + * + * @param x A x coordinate + * @return the closer lifeline + */ + public Lifeline getCloserLifeline(int x) { + int index = (x - Metrics.FRAME_H_MARGIN + Metrics.LIFELINE_H_MAGIN) / Metrics.swimmingLaneWidth() - 1; + if (index < 0) { + index = 0; + } + if (index >= getLifelines().size()) { + index = getLifelines().size() - 1; + } + Lifeline node1, node2, node3; + int dist1, dist2, dist3; + node1 = node2 = node3 = getLifeline(index); + dist1 = dist2 = dist3 = Math.abs(node1.getX() + node1.getWidth() / 2 - x); + if (index > 0) { + node2 = getLifeline(index - 1); + dist2 = Math.abs(node2.getX() + node2.getWidth() / 2 - x); + } + if (index < getLifelines().size() - 1) { + node3 = getLifeline(index + 1); + dist3 = Math.abs(node3.getX() + node3.getWidth() / 2 - x); + } + if (dist1 <= dist2 && dist1 <= dist3) { + return node1; + } else if (dist2 <= dist1 && dist2 <= dist3) { + return node2; + } + return node3; + } + + /** + * Re-orders the given list of lifelines. + * + * @param list A list of lifelines to reorder. + */ + public void reorder(List list) { + for (int i = 0; i < list.size(); i++) { + if (list.get(i) instanceof Lifeline[]) { + Lifeline temp[] = (Lifeline[]) list.get(i); + if (temp.length == 2) { + if (temp[1] == null) { + insertLifelineAfter(temp[0], getLifeline(lifeLinesCount() - 1)); + } else { + insertLifelineBefore(temp[0], temp[1]); + } + } + } + } + } + + /** + * Resets the time compression information. + */ + public void resetTimeCompression() { + fHighlightLifeline = null; + this.fStartEvent = 0; + this.fNbEvent = 0; + fHighlightColor = null; + } + + @Override + protected void computeMinMax() { + List timeArray = buildTimeArray(); + if ((timeArray == null) || timeArray.isEmpty()) { + return; + } + for (int i = 0; i < timeArray.size() - 1; i++) { + SDTimeEvent m1 = timeArray.get(i); + SDTimeEvent m2 = timeArray.get(i + 1); + if (SDViewPref.getInstance().excludeExternalTime() && ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage))) { + BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); + BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); + if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) { + continue; + } + } + + updateMinMax(m1, m2); + } + } + + /** + * Find the two graph nodes that are closest to this date, one just earlier, second just later. If date is before + * any graph node, bounds[0] is null and bounds[1] is the earliest. If date is after any graph node, bounds[1] is + * null and bounds[0] is the latest. + * + * @param dateToFind date to be found + * @param bounds a two items array that will receive bounds if found + * @return true if both bounds not null + * @since 2.0 + */ + public boolean findDateBounds(ITmfTimestamp dateToFind, ITimeRange bounds[]) { + if (hasTimeInfo()) { + List timeArray = buildTimeArray(); + + if ((timeArray == null) || timeArray.isEmpty()) { + return false; + } + + bounds[0] = null; + bounds[1] = null; + for (int i = 0; i < timeArray.size(); i++) { + SDTimeEvent m = timeArray.get(i); + if (m.getTime().compareTo(dateToFind, true) > 0) { + bounds[1] = m.getGraphNode(); + if (i > 0) { + bounds[0] = timeArray.get(i - 1).getGraphNode(); + return true; + } + return false; + } + } + bounds[0] = timeArray.get(timeArray.size() - 1).getGraphNode(); + } + return false; + } + + /** + * Highlights the time compression. + * + * @param lifeline A lifeline to highlight + * @param startEvent A start event number + * @param nbEvent A number of events + * @param color A color for highlighting + */ + public void highlightTimeCompression(Lifeline lifeline, int startEvent, int nbEvent, IColor color) { + fHighlightLifeline = lifeline; + this.fStartEvent = startEvent; + this.fNbEvent = nbEvent; + fHighlightColor = color; + } + + /** + * Set the lifeline categories which will be use during the lifelines creation + * + * @see Lifeline#setCategory(int) + * @param categories the lifeline categories array + */ + public void setLifelineCategories(LifelineCategories[] categories) { + fLifelineCategories = Arrays.copyOf(categories, categories.length); + } + + /** + * Returns the lifeline categories array set for the this frame + * + * @return the lifeline categories array or null if not set + */ + public LifelineCategories[] getLifelineCategories() { + return Arrays.copyOf(fLifelineCategories, fLifelineCategories.length); + } + + /** + * Adds a message to the Frame message list. Four kinds of syncMessages can be added:
    + * - synchronous syncMessages
    + * - synchronous syncMessages return
    + * - asynchronous syncMessages
    + * - asynchronous syncMessages return
    + * For drawing performance reason, it is recommended to add synchronous syncMessages in the same order they should + * appear along the Y axis in the Frame. + * + * @param message the message to add + */ + public void addMessage(BaseMessage message) { + addNode(message); + } + + @Override + public void draw(IGC context) { + drawFrame(context); + if (!hasChildren()) { + return; + } + + if (fHighlightLifeline != null) { + IColor backupColor = context.getBackground(); + context.setBackground(SDViewPref.getInstance().getTimeCompressionSelectionColor()); + int gy = fHighlightLifeline.getY() + fHighlightLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * fStartEvent; + context.fillRectangle(Metrics.FRAME_H_MARGIN + 1, gy, fHighlightLifeline.getX() + Metrics.getLifelineWidth() / 2 - Metrics.FRAME_H_MARGIN, (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * fNbEvent); + context.setBackground(backupColor); + } + super.draw(context, false); + int lifelineArryStep = 1; + if (Metrics.swimmingLaneWidth() * context.getZoom() < Metrics.LIFELINE_SIGNIFICANT_HSPACING) { + lifelineArryStep = Math.round(Metrics.LIFELINE_SIGNIFICANT_HSPACING / (Metrics.swimmingLaneWidth() * context.getZoom())); + } + if (getIndexes().size() == 0) { + return; + } + int lifeLineDrawIndex = getIndexes().get(Lifeline.LIFELINE_TAG).intValue(); + for (int i = lifeLineDrawIndex; i < getNodeMap().get(Lifeline.LIFELINE_TAG).size(); i = i + lifelineArryStep) { + Lifeline toDraw = (Lifeline) getNodeMap().get(Lifeline.LIFELINE_TAG).get(i); + if (toDraw.getX() - Metrics.LIFELINE_SPACING / 2 > context.getContentsX() + context.getVisibleWidth()) { + break; + } + toDraw.drawName(context); + + if (fHighlightLifeline != null) { + if (toDraw == fHighlightLifeline) { + toDraw.highlightExecOccurrenceRegion(context, fStartEvent, fNbEvent, fHighlightColor); + } else if ((toDraw.getIndex() < fHighlightLifeline.getIndex()) || ((toDraw.getIndex() < fHighlightLifeline.getIndex()))) { + + int acIndex = toDraw.getExecOccurrenceDrawIndex(); + // acIndex = first visible execution occurrence + // for drawing speed reason with only search on the visible subset + if (toDraw.getExecutions() != null) { + for (int index = acIndex; index < toDraw.getExecutions().size(); index++) { + BasicExecutionOccurrence exec = (BasicExecutionOccurrence) toDraw.getExecutions().get(index); + int tempEvent = fStartEvent; + for (int j = 0; j < fNbEvent; j++) { + if (((tempEvent >= exec.getStartOccurrence()) && (tempEvent <= exec.getEndOccurrence()) && (tempEvent + 1 >= exec.getStartOccurrence()) && (tempEvent + 1 <= exec.getEndOccurrence()))) { + toDraw.highlightExecOccurrenceRegion(context, tempEvent, 1, SDViewPref.getInstance().getTimeCompressionSelectionColor()); + } + tempEvent = tempEvent + 1; + } + // if we are outside the visible area we stop right now + // This works because execution occurrences are ordered along the Y axis + if (exec.getY() > getY()) { + break; + } + } + } + } + } + } + } + + @Override + protected List buildTimeArray() { + + if (!hasChildren()) { + return new ArrayList<>(); + } + + List timeArray = super.buildTimeArray(); + fExecutionOccurrencesWithTime = null; + if (getLifelines() != null) { + for (int i = 0; i < getNodeMap().get(Lifeline.LIFELINE_TAG).size(); i++) { + Lifeline lifeline = (Lifeline) getNodeMap().get(Lifeline.LIFELINE_TAG).get(i); + if (lifeline.hasTimeInfo() && lifeline.getExecutions() != null) { + for (Iterator j = lifeline.getExecutions().iterator(); j.hasNext();) { + GraphNode o = j.next(); + if (o instanceof ExecutionOccurrence) { + ExecutionOccurrence eo = (ExecutionOccurrence) o; + if (eo.hasTimeInfo()) { + int event = eo.getStartOccurrence(); + ITmfTimestamp time = eo.getStartTime(); + SDTimeEvent f = new SDTimeEvent(time, event, eo); + timeArray.add(f); + if (fExecutionOccurrencesWithTime == null) { + fExecutionOccurrencesWithTime = new ArrayList<>(); + } + fExecutionOccurrencesWithTime.add(f); + event = eo.getEndOccurrence(); + time = eo.getEndTime(); + f = new SDTimeEvent(time, event, eo); + timeArray.add(f); + fExecutionOccurrencesWithTime.add(f); + } + } + } + } + } + } + + if (fExecutionOccurrencesWithTime != null) { + SDTimeEvent[] temp = fExecutionOccurrencesWithTime.toArray(new SDTimeEvent[fExecutionOccurrencesWithTime.size()]); + Arrays.sort(temp, new TimeEventComparator()); + fExecutionOccurrencesWithTime = Arrays.asList(temp); + } + SDTimeEvent[] temp = timeArray.toArray(new SDTimeEvent[timeArray.size()]); + Arrays.sort(temp, new TimeEventComparator()); + timeArray = Arrays.asList(temp); + return timeArray; + } + + /** + * Get the closer leaving message. + * + * @param lifeline A lifeline reference + * @param message A message reference + * @param list A list of graph nodes + * @param smallerEvent A smaller event flag + * @return the closer leaving message. + */ + protected GraphNode getCloserLeavingMessage(Lifeline lifeline, BaseMessage message, List list, boolean smallerEvent) { + if (list == null) { + return null; + } + + if (!smallerEvent) { + int event = 0; + if (message != null) { + event = message.getEventOccurrence(); + } + for (int i = 0; i < list.size(); i++) { + GraphNode node = list.get(i); + if (node instanceof SyncMessage) { + SyncMessage syncNode = (SyncMessage) node; + if ((syncNode.getEventOccurrence() > event) && (syncNode.getStartLifeline() == lifeline) && !syncNode.isSameAs(message)) { + return node; + } + } else if (node instanceof AsyncMessage) { + AsyncMessage asyncNode = (AsyncMessage) node; + if ((asyncNode.getStartOccurrence() > event) && (asyncNode.getStartLifeline() == lifeline) && !asyncNode.isSameAs(message)) { + return node; + } + } + } + } else { + int event = getMaxEventOccurrence(); + if (message != null) { + if (message instanceof AsyncMessage) { + event = ((AsyncMessage) message).getStartOccurrence(); + } else { + event = message.getEventOccurrence(); + } + } + for (int i = list.size() - 1; i >= 0; i--) { + GraphNode node = list.get(i); + if (node instanceof SyncMessage) { + SyncMessage syncNode = (SyncMessage) node; + if ((syncNode.getEventOccurrence() < event) && (syncNode.getStartLifeline() == lifeline) && !syncNode.isSameAs(message)) { + return node; + } + } else if (node instanceof AsyncMessage) { + AsyncMessage asyncNode = (AsyncMessage) node; + if ((asyncNode.getStartOccurrence() < event) && (asyncNode.getStartLifeline() == lifeline) && !asyncNode.isSameAs(message)) { + return node; + } + } + } + } + return null; + } + + + /** + * Get the closer entering message. + * + * @param lifeline A lifeline reference + * @param message A message reference + * @param list A list of graph nodes + * @param smallerEvent A smaller event flag + * @return the closer entering message. + */ + protected GraphNode getCloserEnteringMessage(Lifeline lifeline, BaseMessage message, List list, boolean smallerEvent) { + if (list == null) { + return null; + } + if (!smallerEvent) { + int event = 0; + if (message != null) { + event = message.getEventOccurrence(); + } + for (int i = 0; i < list.size(); i++) { + GraphNode node = list.get(i); + if (node instanceof SyncMessage) { + SyncMessage syncNode = (SyncMessage) node; + if ((syncNode.getEventOccurrence() > event) && (syncNode.getEndLifeline() == lifeline) && !syncNode.isSameAs(message)) { + return node; + } + } else if (node instanceof AsyncMessage) { + AsyncMessage asyncNode = (AsyncMessage) node; + if ((asyncNode.getStartOccurrence() > event) && (asyncNode.getEndLifeline() == lifeline) && !asyncNode.isSameAs(message)) { + return node; + } + } + } + } else { + int event = getMaxEventOccurrence(); + if (message != null) { + if (message instanceof AsyncMessage) { + event = ((AsyncMessage) message).getStartOccurrence(); + } else { + event = message.getEventOccurrence(); + } + } + for (int i = list.size() - 1; i >= 0; i--) { + GraphNode node = list.get(i); + if (node instanceof SyncMessage) { + SyncMessage syncNode = (SyncMessage) node; + if ((syncNode.getEventOccurrence() < event) && (syncNode.getEndLifeline() == lifeline) && !syncNode.isSameAs(message)) { + return node; + } + } else if (node instanceof AsyncMessage) { + AsyncMessage asyncNode = (AsyncMessage) node; + if ((asyncNode.getStartOccurrence() < event) && (asyncNode.getEndLifeline() == lifeline) && !asyncNode.isSameAs(message)) { + return node; + } + } + } + } + return null; + } + + /** + * Get distance of given event from given graph node. + * + * @param node A graph node reference. + * @param event A event number to check. + * @return distance of event from graph node. + */ + protected int distanceFromEvent(GraphNode node, int event) { + int distance = 0; + if (node instanceof SyncMessage) { + distance = ((SyncMessage) node).getEventOccurrence() - event; + } else if (node instanceof AsyncMessage) { + int start = ((AsyncMessage) node).getStartOccurrence(); + int end = ((AsyncMessage) node).getEndOccurrence(); + if ((start - event) < (end - event)) { + distance = start - event; + } else { + distance = end - event; + } + } + return Math.abs(distance); + } + + /** + * Get node from 2 given nodes that is close to event. + * + * @param node1 A first graph node + * @param node2 A second graph node + * @param event A event to check. + * @return graph node that is closer or null + */ + protected GraphNode getCloserToEvent(GraphNode node1, GraphNode node2, int event) { + if ((node1 != null) && (node2 != null)) { + if (distanceFromEvent(node1, event) < distanceFromEvent(node2, event)) { + return node1; + } + return node2; + } else if (node1 != null) { + return node1; + } else if (node2 != null) { + return node2; + } + return null; + } + + /** + * Get called message based on given start message. + * + * @param startMessage A start message to check. + * @return called message (graph node) or null + */ + public GraphNode getCalledMessage(BaseMessage startMessage) { + int event = 0; + GraphNode result = null; + Lifeline lifeline = null; + if (startMessage != null) { + event = startMessage.getEventOccurrence(); + lifeline = startMessage.getEndLifeline(); + if (lifeline == null) { + lifeline = startMessage.getStartLifeline(); + } + } + if (lifeline == null) { + return null; + } + GraphNode message = getCloserLeavingMessage(lifeline, startMessage, getSyncMessages(), false); + GraphNode messageReturn = getCloserLeavingMessage(lifeline, startMessage, getSyncMessagesReturn(), false); + result = getCloserToEvent(message, messageReturn, event); + message = getCloserLeavingMessage(lifeline, startMessage, getAsyncMessages(), false); + result = getCloserToEvent(result, message, event); + messageReturn = getCloserLeavingMessage(lifeline, startMessage, getAsyncMessagesReturn(), false); + result = getCloserToEvent(result, messageReturn, event); + return result; + } + + /** + * Get caller message based on given start message. + * + * @param startMessage A start message to check. + * @return called message (graph node) or null + */ + public GraphNode getCallerMessage(BaseMessage startMessage) { + int event = getMaxEventOccurrence(); + GraphNode result = null; + Lifeline lifeline = null; + if (startMessage != null) { + event = startMessage.getEventOccurrence(); + lifeline = startMessage.getStartLifeline(); + if (lifeline == null) { + lifeline = startMessage.getEndLifeline(); + } + } + if (lifeline == null) { + return null; + } + GraphNode message = getCloserEnteringMessage(lifeline, startMessage, getSyncMessages(), true); + GraphNode messageReturn = getCloserEnteringMessage(lifeline, startMessage, getSyncMessagesReturn(), true); + result = getCloserToEvent(message, messageReturn, event); + message = getCloserEnteringMessage(lifeline, startMessage, getAsyncMessages(), true); + result = getCloserToEvent(result, message, event); + messageReturn = getCloserEnteringMessage(lifeline, startMessage, getAsyncMessagesReturn(), true); + result = getCloserToEvent(result, messageReturn, event); + return result; + } + + /** + * Get next lifeline based on given message. + * + * @param lifeline A lifeline reference + * @param startMessage A start message to check + * @return next lifeline or null + */ + public GraphNode getNextLifelineMessage(Lifeline lifeline, BaseMessage startMessage) { + int event = 0; + if (startMessage != null) { + event = startMessage.getEventOccurrence(); + } + if (lifeline == null) { + return null; + } + GraphNode message = getCloserLeavingMessage(lifeline, startMessage, getSyncMessages(), false); + GraphNode messageReturn = getCloserLeavingMessage(lifeline, startMessage, getSyncMessagesReturn(), false); + GraphNode result = getCloserToEvent(message, messageReturn, event); + message = getCloserLeavingMessage(lifeline, startMessage, getAsyncMessages(), false); + result = getCloserToEvent(result, message, event); + messageReturn = getCloserLeavingMessage(lifeline, startMessage, getAsyncMessagesReturn(), false); + result = getCloserToEvent(result, messageReturn, event); + return result; + } + + /** + * Get previous lifeline based on given message. + * + * @param lifeline A lifeline reference + * @param startMessage A start message to check. + * @return previous lifeline or null + */ + public GraphNode getPrevLifelineMessage(Lifeline lifeline, BaseMessage startMessage) { + int event = getMaxEventOccurrence(); + if (startMessage != null) { + if (startMessage instanceof AsyncMessage) { + event = ((AsyncMessage) startMessage).getStartOccurrence(); + } else { + event = startMessage.getEventOccurrence(); + } + } + if (lifeline == null) { + return null; + } + GraphNode message = getCloserLeavingMessage(lifeline, startMessage, getSyncMessages(), true); + GraphNode messageReturn = getCloserLeavingMessage(lifeline, startMessage, getSyncMessagesReturn(), true); + GraphNode result = getCloserToEvent(message, messageReturn, event); + message = getCloserLeavingMessage(lifeline, startMessage, getAsyncMessages(), true); + result = getCloserToEvent(result, message, event); + messageReturn = getCloserLeavingMessage(lifeline, startMessage, getAsyncMessagesReturn(), true); + result = getCloserToEvent(result, messageReturn, event); + return result; + } + + /** + * Get the first execution occurrence. + * + * @param lifeline A lifeline reference + * @return the first execution occurrence of lifeline or null. + */ + public BasicExecutionOccurrence getFirstExecution(Lifeline lifeline) { + if (lifeline == null) { + return null; + } + List list = lifeline.getExecutions(); + + if ((list == null) || (list.isEmpty())) { + return null; + } + + BasicExecutionOccurrence result = (BasicExecutionOccurrence) list.get(0); + for (int i = 0; i < list.size(); i++) { + BasicExecutionOccurrence e = (BasicExecutionOccurrence) list.get(i); + if ((e.getStartOccurrence() < result.getEndOccurrence())) { + result = e; + } + } + return result; + } + + /** + * Get the previous execution occurrence relative to a given execution occurrence. + * + * @param exec A execution occurrence reference. + * @return the previous execution occurrence of lifeline or null. + */ + public BasicExecutionOccurrence getPrevExecOccurrence(BasicExecutionOccurrence exec) { + if (exec == null) { + return null; + } + Lifeline lifeline = exec.getLifeline(); + if (lifeline == null) { + return null; + } + List list = lifeline.getExecutions(); + if (list == null) { + return null; + } + BasicExecutionOccurrence result = null; + for (int i = 0; i < list.size(); i++) { + BasicExecutionOccurrence e = (BasicExecutionOccurrence) list.get(i); + if ((e.getStartOccurrence() < exec.getStartOccurrence()) && (result == null)) { + result = e; + } + if ((e.getStartOccurrence() < exec.getStartOccurrence()) && (result != null) && (e.getStartOccurrence() >= result.getEndOccurrence())) { + result = e; + } + } + return result; + } + + /** + * Get the next execution occurrence relative to a given execution occurrence. + * + * @param exec A execution occurrence reference. + * @return the next execution occurrence of lifeline or null. + */ + public BasicExecutionOccurrence getNextExecOccurrence(BasicExecutionOccurrence exec) { + if (exec == null) { + return null; + } + Lifeline lifeline = exec.getLifeline(); + if (lifeline == null) { + return null; + } + List list = lifeline.getExecutions(); + if (list == null) { + return null; + } + BasicExecutionOccurrence result = null; + for (int i = 0; i < list.size(); i++) { + BasicExecutionOccurrence e = (BasicExecutionOccurrence) list.get(i); + if ((e.getStartOccurrence() > exec.getStartOccurrence()) && (result == null)) { + result = e; + } + if ((e.getStartOccurrence() > exec.getStartOccurrence()) && (result != null) && (e.getStartOccurrence() <= result.getEndOccurrence())) { + result = e; + } + } + return result; + } + + /** + * Get the last execution occurrence. + * + * @param lifeline A lifeline reference. + * @return the last execution occurrence of lifeline or null. + */ + public BasicExecutionOccurrence getLastExecOccurrence(Lifeline lifeline) { + if (lifeline == null) { + return null; + } + List list = lifeline.getExecutions(); + if (list == null) { + return null; + } + BasicExecutionOccurrence result = null; + for (int i = 0; i < list.size(); i++) { + BasicExecutionOccurrence e = (BasicExecutionOccurrence) list.get(i); + if (result == null) { + result = e; + } + if (e.getStartOccurrence() > result.getEndOccurrence()) { + result = e; + } + } + return result; + } + + /** + * @return highlighted life line if set else null. + * @since 2.0 + */ + protected Lifeline getHighlightLifeline() { + return fHighlightLifeline; + } + + /** + * @return the start event value. + * @since 2.0 + */ + protected int getStartEvent() { + return fStartEvent; + } + + /** + * Returns the number of events + * + * @return the number of events + * @since 2.0 + */ + protected int getNumberOfEvents() { + return fNbEvent; + } + + /** + * Returns the highlight color. + * @return the highlight color + * @since 2.0 + */ + protected IColor getHighlightColor() { + return fHighlightColor; + } + + /** + * Set the highlighted life line. + * @param lifeline + * The highlighted life line if set else null + * @since 2.0 + */ + protected void setHighlightLifeline(Lifeline lifeline) { + fHighlightLifeline = lifeline; + } + + /** + * Sets the start event value + * @param startEvent + * the start event value. + * @since 2.0 + */ + protected void setStartEvent(int startEvent) { + fStartEvent = startEvent; + } + + /** + * Sets the number of events + * + * @param nbEvents + * The number of events + * @since 2.0 + */ + protected void setNumberOfEvents(int nbEvents) { + fNbEvent = nbEvents; + } + + /** + * Sets the highlight color. + * @param color + * the highlight color + * @since 2.0 + */ + protected void setHighlightColor(IColor color) { + fHighlightColor = color; + } + + /** + * sets the list of execution occurrences. + * + * @param occurences + * the list of execution occurrences + * @since 2.0 + */ + protected void setExecutionOccurrencesWithTime(List occurences) { + fExecutionOccurrencesWithTime = occurences; + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/GraphNode.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/GraphNode.java new file mode 100755 index 0000000000..f0c026a74a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/GraphNode.java @@ -0,0 +1,906 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.tracecompass.internal.tmf.ui.TmfUiTracer; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.ISDPreferences; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref; + +/** + * The base class used for all UML2 graph nodes displayed in the Sequence Diagram SDWidget. + * + * @author sveyrier + * @version 1.0 + */ +public abstract class GraphNode { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The start event occurrence. + */ + private int fStartEventOccurrence = 0; + /** + * The event event occurrence. + */ + private int fEndEventOccurrence = 0; + /** + * Preference ColorId to use to draw font + */ + private String fPrefId = ISDPreferences.PREF_SYNC_MESS; + /** + * The selection state of the graph node. + */ + private boolean fSelected = false; + /** + * The focus state of the graph node. + */ + private boolean fFocused = false; + /** + * Flag to indicate whether node has children or not. + */ + private boolean fHasChilden = false; + /** + * The graph node name used to label the graph node in the View. + */ + private String fName = ""; //$NON-NLS-1$ + /** + * A map from node name to graph node. + */ + private Map> fNodes; + /** + * A map from node name to graph node for forward sorting + */ + private Map> fForwardNodes; + /** + * A map from node name to graph node for backwards sorting. + */ + private Map> fBackwardNodes; + /** + * A map from node name to index. + */ + private Map fIndexes; + /** + * A map from node name to flag for forwards sorting. + */ + private Map fForwardSort; + /** + * A map from node name to flag for backwards sorting. + */ + private Map fBackwardSort; + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + /** + * Reset the internal index of the first visible GraphNode for each ordered GraphNode lists + */ + public void resetIndex() { + if (!fHasChilden) { + return; + } + + Iterator it = fIndexes.keySet().iterator(); + while (it.hasNext()) { + String nodeType = it.next(); + fIndexes.put(nodeType, Integer.valueOf(0)); + } + } + + /** + * Add a GraphNode into the receiver + * + * @param nodeToAdd the node to add + */ + public void addNode(GraphNode nodeToAdd) { + if (!fHasChilden) { + fNodes = new HashMap<>(2); + fForwardNodes = new HashMap<>(2); + fBackwardNodes = new HashMap<>(2); + fIndexes = new HashMap<>(2); + fBackwardSort = new HashMap<>(2); + fForwardSort = new HashMap<>(2); + fHasChilden = true; + } + + // Nothing to add + if (nodeToAdd == null) { + return; + } + + if (fNodes.get(nodeToAdd.getArrayId()) == null) { + fNodes.put(nodeToAdd.getArrayId(), new ArrayList(1)); + fIndexes.put(nodeToAdd.getArrayId(), Integer.valueOf(0)); + fForwardNodes.put(nodeToAdd.getArrayId(), new ArrayList(1)); + fForwardSort.put(nodeToAdd.getArrayId(), Boolean.FALSE); + if (nodeToAdd.getBackComparator() != null) { + fBackwardNodes.put(nodeToAdd.getArrayId(), new ArrayList(1)); + fBackwardSort.put(nodeToAdd.getArrayId(), Boolean.FALSE); + } + } + + List fNodeList = fForwardNodes.get(nodeToAdd.getArrayId()); + List bNodeList = null; + if (fBackwardNodes != null) { + bNodeList = fBackwardNodes.get(nodeToAdd.getArrayId()); + } + if (fNodeList != null && fNodeList.size() > 0) { + // check if the nodes are added y ordered + // if not, tag the list to sort it later (during draw) + GraphNode node = fNodeList.get(fNodeList.size() - 1); + Comparator fcomp = nodeToAdd.getComparator(); + Comparator bcomp = nodeToAdd.getBackComparator(); + if ((fcomp != null) && (fcomp.compare(node, nodeToAdd) > 0)) { + fForwardSort.put(nodeToAdd.getArrayId(), Boolean.TRUE); + } + if ((bcomp != null) && (bcomp.compare(node, nodeToAdd) > 0)) { + fBackwardSort.put(nodeToAdd.getArrayId(), Boolean.TRUE); + } + } + + if (fNodeList == null) { + fNodeList = new ArrayList<>(); + } + + fNodeList.add(nodeToAdd); + fNodes.put(nodeToAdd.getArrayId(), fNodeList); + fForwardNodes.put(nodeToAdd.getArrayId(), fNodeList); + if ((bNodeList != null) && (nodeToAdd.getBackComparator() != null)) { + bNodeList.add(nodeToAdd); + fBackwardNodes.put(nodeToAdd.getArrayId(), bNodeList); + } + } + + /** + * Set the graph node name.
    + * It is the name display in the view to label the graph node. + * + * @param nodeName the name to set + */ + public void setName(String nodeName) { + fName = nodeName; + } + + /** + * Returns the graph node name.
    + * It is the name display in the view to label the graph node. + * + * @return the graph node name + */ + public String getName() { + return fName; + } + + /** + * Tags the the graph node has selected.
    + * WARNING: This method is only used to draw the graph node using the system selection colors.
    + * To use the complete SDViewer selection mechanism (selection management, notification, etc..) see SDWidget class + * + * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget#addSelection(GraphNode) + * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget#removeSelection(GraphNode) + * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget#clearSelection() + * @param selection - true to set selected, false to set unselected + */ + public void setSelected(boolean selection) { + fSelected = selection; + } + + /** + * Tags the the graph node as focused.
    + * WARNING: This method is only used to draw the graph node using the system focus style.
    + * To use the complete SDViewer focus mechanism see SDWidget class + * + * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget#addSelection(GraphNode) + * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget#removeSelection(GraphNode) + * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget#clearSelection() + * @param focus - true to set focued, false otherwise + */ + public void setFocused(boolean focus) { + fFocused = focus; + } + + /** + * Returns true if the graph node is selected, false otherwise.
    + * The returned value is used to highlight the graph node in the View. + * + * @return true if selected, false otherwise + */ + public boolean isSelected() { + return fSelected; + } + + /** + * Returns true if the graph node is focused, false otherwise.
    + * The returned value is used to highlight the graph node in the View. + * + * @return true if focused, false otherwise + */ + public boolean hasFocus() { + return fFocused; + } + + /** + * Returns true if the graph node contains the point given in parameter, + * return false otherwise. + * + * @param x + * the x coordinate of the point to test containment + * @param y + * the y coordinate of the point to test containment + * @return true if contained, false otherwise + */ + abstract public boolean contains(int x, int y); + + /** + * Returns the x coordinate of the graph node + * + * @return the x coordinate + */ + abstract public int getX(); + + /** + * Returns the y coordinate of the graph node + * + * @return the y coordinate + */ + abstract public int getY(); + + /** + * Returns the graph node height + * + * @return the graph node height + */ + abstract public int getHeight(); + + /** + * Returns the graph node width + * + * @return the graph node width + */ + abstract public int getWidth(); + + /** + * Draws the graph node in the given context + * + * @param context the graphical context to draw in + */ + abstract protected void draw(IGC context); + + /** + * Returns the GraphNode visibility for the given visible area. Wrong + * visibility calculation, may strongly impact drawing performance + * + * @param x + * The X coordinate + * @param y + * The Y coordinate + * @param width + * The width of the area + * @param height + * The height of the area + * @return true if visible, false otherwise + */ + public boolean isVisible(int x, int y, int width, int height) { + return true; + } + + /** + * Return a comparator to sort the GraphNode of the same type This + * comparator is used to order the GraphNode array of the given node type. + * (see getArrayId). + * + * @return the comparator + */ + public Comparator getComparator() { + return null; + } + + /** + * If needed, return a different comparator to backward scan the GraphNode + * array + * + * @return the backward comparator or null if not needed + */ + public Comparator getBackComparator() { + return null; + } + + /** + * Compare two graphNodes + * + * @param node + * the node to compare to + * @return true if equal false otherwise + */ + public boolean isSameAs(GraphNode node) { + return false; + } + + /** + * Return the node type for all class instances. This id is used to store the same nodes kind in the same ordered + * array. + * + * @return the node type identifier + */ + abstract public String getArrayId(); + + /** + * Return true if the distance from the GraphNode to the given point is positive + * + * @param x the point x coordinate + * @param y the point y coordinate + * @return true if positive false otherwise + */ + public boolean positiveDistanceToPoint(int x, int y) { + return false; + } + + /** + * Returns the graph node which contains the point given in parameter WARNING: Only graph nodes in the current + * visible area can be returned + * + * @param x the x coordinate of the point to test + * @param y the y coordinate of the point to test + * @return the graph node containing the point given in parameter, null otherwise + */ + public GraphNode getNodeAt(int x, int y) { + GraphNode toReturn = null; + + if (!fHasChilden) { + return null; + } + + Iterator it = fNodes.keySet().iterator(); + GraphNode node = null; + while (it.hasNext()) { + Object nodeType = it.next(); + List list = fNodes.get(nodeType); + int index = fIndexes.get(nodeType).intValue(); + node = getNodeFromListAt(x, y, list, index); + if (toReturn == null) { + toReturn = node; + } + if (node != null) { + GraphNode internalNode = node.getNodeAt(x, y); + if (internalNode != null) { + return internalNode; + } else if (Math.abs(node.getWidth()) < Math.abs(toReturn.getWidth()) || Math.abs(node.getHeight()) < Math.abs(toReturn.getHeight())) { + toReturn = node; + } + } + } + return toReturn; + } + + /** + * Gets node list from node A to node B + + * @param from A from node + * @param to A to node + * @return the list of nodes + */ + public List getNodeList(GraphNode from, GraphNode to) { + List result = new ArrayList<>(); + + if (from != null) { + result.add(from); + } else if (to != null) { + result.add(to); + } + + if ((from == null) || (to == null)) { + return result; + } + + if (from == to) { + return result; + } + + int startX = Math.min(from.getX(), Math.min(to.getX(), Math.min(from.getX() + from.getWidth(), to.getX() + to.getWidth()))); + int endX = Math.max(from.getX(), Math.max(to.getX(), Math.max(from.getX() + from.getWidth(), to.getX() + to.getWidth()))); + int startY = Math.min(from.getY(), Math.min(to.getY(), Math.min(from.getY() + from.getHeight(), to.getY() + to.getHeight()))); + int endY = Math.max(from.getY(), Math.max(to.getY(), Math.max(from.getY() + from.getHeight(), to.getY() + to.getHeight()))); + + if (!fHasChilden) { + return result; + } + + Iterator it = fNodes.keySet().iterator(); + while (it.hasNext()) { + Object nodeType = it.next(); + List nodesList = fNodes.get(nodeType); + if (nodesList == null || nodesList.isEmpty()) { + return null; + } + for (int i = 0; i < nodesList.size(); i++) { + GraphNode node = nodesList.get(i); + int nw = node.getWidth(); + int nh = node.getHeight(); + int nx = node.getX(); + int ny = node.getY(); + if (contains(startX, startY, endX - startX, endY - startY, nx + 1, ny + 1) && contains(startX, startY, endX - startX, endY - startY, nx + nw - 2, ny + nh - 2)) { + result.add(node); + } + result.addAll(node.getNodeList(from, to)); + } + } + + if (!result.contains(to)) { + result.add(to); + } + return result; + } + + /** + * Returns the graph node which contains the point given in parameter for the given graph node list and starting the + * iteration at the given index
    + * WARNING: Only graph nodes with smaller coordinates than the current visible area can be returned.
    + * + * @param x the x coordinate of the point to test + * @param y the y coordinate of the point to test + * @param list the list to search in + * @param fromIndex list browsing starting point + * @return the graph node containing the point given in parameter, null otherwise + */ + protected GraphNode getNodeFromListAt(int x, int y, List list, int fromIndex) { + if (list == null) { + return null; + } + for (int i = fromIndex; i < list.size(); i++) { + GraphNode node = list.get(i); + if (node.contains(x, y)) { + return node; + } + } + return null; + } + + /** + * Returns the start event occurrence attached to this graphNode. + * + * @return the start event occurrence attached to the graphNode + */ + public int getStartOccurrence() { + return fStartEventOccurrence; + } + + /** + * Returns the end event occurrence attached to this graphNode + * + * @return the start event occurrence attached to the graphNode + */ + public int getEndOccurrence() { + return fEndEventOccurrence; + } + + /** + * Computes the index of the first visible GraphNode for each ordered graph node lists depending on the visible area + * given in parameter + * + * @param x visible area top left corner x coordinate + * @param y visible area top left corner y coordinate + * @param width visible area width + * @param height visible area height + */ + public void updateIndex(int x, int y, int width, int height) { + if (!fHasChilden) { + return; + } + if(TmfUiTracer.isIndexTraced()) { + TmfUiTracer.traceIndex("*****************************\n"); //$NON-NLS-1$ + TmfUiTracer.traceIndex("Visible area position in virtual screen (x,y)= " + x + " " + y + "\n\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + Iterator it = fNodes.keySet().iterator(); + while (it.hasNext()) { + String nodeType = it.next(); + int direction = 1; + int drawIndex = fIndexes.get(nodeType).intValue(); + /* + * if (x==0) { drawIndex = 0; indexes.put(nodeType,new Integer(drawIndex)); } + */ + if ((fNodes.get(nodeType) != null) && (fNodes.get(nodeType).size() > 1)) { + if (fNodes.get(nodeType).get(drawIndex).positiveDistanceToPoint(x, y)) { + direction = -1; + } + + if (drawIndex == 0) { + direction = 1; + } + + if ((direction == -1) && (fBackwardNodes.get(nodeType) != null)) { + GraphNode currentNode = fNodes.get(nodeType).get(drawIndex); + drawIndex = Arrays.binarySearch(fBackwardNodes.get(nodeType).toArray(new GraphNode[fBackwardNodes.get(nodeType).size()]), + fNodes.get(nodeType).get(drawIndex), currentNode.getBackComparator()); + fNodes.put(nodeType, fBackwardNodes.get(nodeType)); + if (drawIndex < 0) { + drawIndex = 0; + direction = 1; + } else { + fNodes.put(nodeType, fBackwardNodes.get(nodeType)); + } + } + GraphNode prev = null; + + for (int i = drawIndex; i < fNodes.get(nodeType).size() && i >= 0; i = i + direction) { + drawIndex = i; + fIndexes.put(nodeType, Integer.valueOf(i)); + + GraphNode currentNode = fNodes.get(nodeType).get(i); + + if (prev == null) { + prev = currentNode; + } + + Comparator comp = currentNode.getComparator(); + Map sort = fForwardSort; + + if ((direction == -1) && (currentNode.getBackComparator() != null)) { + comp = currentNode.getBackComparator(); + sort = fBackwardSort; + } + + if (i < fNodes.get(nodeType).size() - 1) { + GraphNode next = fNodes.get(nodeType).get(i + 1); + + if ((comp != null) && (comp.compare(currentNode, next) > 0)) { + sort.put(nodeType, Boolean.TRUE); + } + } + if (direction == 1) { + if (fNodes.get(nodeType).get(i).positiveDistanceToPoint(x, y)) { + break; + } + } else { + if (currentNode.getBackComparator() == null) { + if // (currentNode.isVisible(x,y,width,height) + (!currentNode.positiveDistanceToPoint(x, y)) { + break; + } + } else { + if (currentNode.isVisible(x, y, width, height) && !currentNode.positiveDistanceToPoint(x, y)) { + if ((comp != null) && (comp.compare(currentNode, prev) <= 0)) { + break; + } + } else if ((comp != null) && (comp.compare(currentNode, prev) <= 0)) { + prev = currentNode; + } + } + } + } + + fNodes.put(nodeType, fForwardNodes.get(nodeType)); + if ((fBackwardNodes.get(nodeType) != null) && (direction == -1)) { + // nodes.put(nodeType,fnodes.get(nodeType)); + int index = fIndexes.get(nodeType).intValue(); + List list = fNodes.get(nodeType); + List backList = fBackwardNodes.get(nodeType); + GraphNode currentNode = (backList.get(index)); + if (index > 0) { + index = Arrays.binarySearch(list.toArray(new GraphNode[list.size()]), backList.get(index), currentNode.getComparator()); + if (index < 0) { + index = 0; + } + fIndexes.put(nodeType, Integer.valueOf(index)); + } + } + + for (int i = drawIndex; i < fNodes.get(nodeType).size() && i >= 0; i++) { + GraphNode toDraw = fNodes.get(nodeType).get(i); + toDraw.updateIndex(x, y, width, height); + if (!toDraw.isVisible(x, y, width, height)) { + break; + } + } + } + if (TmfUiTracer.isIndexTraced()) { + TmfUiTracer.traceIndex("First drawn " + nodeType + " index = " + drawIndex + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + TmfUiTracer.traceIndex(nodeType + " found in " + 0 + " iterations\n"); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + if (TmfUiTracer.isIndexTraced()) { + TmfUiTracer.traceIndex("*****************************\n"); //$NON-NLS-1$ + } + } + + /** + * Draws the children nodes on the given context.
    + * This method start width GraphNodes ordering if needed.
    + * After, depending on the visible area, only visible GraphNodes are drawn.
    + * + * @param context the context to draw to + * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode#draw(IGC) + */ + protected void drawChildenNodes(IGC context) { + + if (!fHasChilden) { + return; + } + // If the nodes have not been added ordered, the array is ordered + Iterator it = fForwardSort.keySet().iterator(); + while (it.hasNext()) { + String nodeType = it.next(); + boolean sort = fForwardSort.get(nodeType).booleanValue(); + if (sort) { + GraphNode[] temp = fForwardNodes.get(nodeType).toArray(new GraphNode[fForwardNodes.get(nodeType).size()]); + GraphNode node = fNodes.get(nodeType).get(0); + Arrays.sort(temp, node.getComparator()); + fForwardSort.put(nodeType, Boolean.FALSE); + fNodes.put(nodeType, Arrays.asList(temp)); + fForwardNodes.put(nodeType, Arrays.asList(temp)); + if (TmfUiTracer.isSortingTraced()) { + TmfUiTracer.traceSorting(nodeType + " array sorted\n"); //$NON-NLS-1$ + } + } + } + + Iterator it2 = fBackwardSort.keySet().iterator(); + while (it2.hasNext()) { + String nodeType = it2.next(); + boolean sort = fBackwardSort.get(nodeType).booleanValue(); + if (sort) { + GraphNode[] temp = fBackwardNodes.get(nodeType).toArray(new GraphNode[fBackwardNodes.get(nodeType).size()]); + GraphNode node = fNodes.get(nodeType).get(0); + Arrays.sort(temp, node.getBackComparator()); + fBackwardSort.put(nodeType, Boolean.FALSE); + fBackwardNodes.put(nodeType, Arrays.asList(temp)); + if (TmfUiTracer.isSortingTraced()) { + TmfUiTracer.traceSorting(nodeType + " back array sorted\n"); //$NON-NLS-1$ + } + } + } + + if (TmfUiTracer.isDisplayTraced()) { + TmfUiTracer.traceDisplay("*****************************\n"); //$NON-NLS-1$ + } + + int arrayStep = 1; + if ((Metrics.getMessageFontHeigth() + Metrics.MESSAGES_NAME_SPACING * 2) * context.getZoom() < Metrics.MESSAGE_SIGNIFICANT_VSPACING) { + arrayStep = Math.round(Metrics.MESSAGE_SIGNIFICANT_VSPACING / ((Metrics.getMessageFontHeigth() + Metrics.MESSAGES_NAME_SPACING * 2) * context.getZoom())); + } + + int count = 0; + Iterator it3 = fForwardSort.keySet().iterator(); + while (it3.hasNext()) { + count = 0; + Object nodeType = it3.next(); + GraphNode node = fNodes.get(nodeType).get(0); + context.setFont(SDViewPref.getInstance().getFont(node.fPrefId)); + int index = fIndexes.get(nodeType).intValue(); + count = drawNodes(context, fNodes.get(nodeType), index, arrayStep); + if (TmfUiTracer.isDisplayTraced()) { + TmfUiTracer.traceDisplay(count + " " + nodeType + " drawn, starting from index " + index + "\r\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + } + if (TmfUiTracer.isDisplayTraced()) { + TmfUiTracer.traceDisplay("*****************************\n"); //$NON-NLS-1$ + } + + } + + /** + * Draw the GraphNode stored in the given list, starting at index startIndex with the given step + * + * @param context the context to draw to + * @param list the GraphNodes list + * @param startIndex the start index + * @param step the step to browse the list + * @return the number of GraphNodes drawn + */ + protected int drawNodes(IGC context, List list, int startIndex, int step) { + if (!fHasChilden) { + return 0; + } + + GraphNode last = null; + int nodesCount = 0; + if (list.size() < 0) { + return 0; + } + + GraphNode node = list.get(0); + context.setFont(SDViewPref.getInstance().getFont(node.fPrefId)); + Comparator comparator = node.getComparator(); + for (int i = startIndex; i < list.size(); i = i + step) { + GraphNode toDraw = list.get(i); + if (i < list.size() - 1) { + GraphNode next = list.get(i + 1); + if ((comparator != null) && (comparator.compare(toDraw, next) > 0)) { + fForwardSort.put(next.getArrayId(), Boolean.TRUE); + } + } + int cx = context.getContentsX(); + int cy = context.getContentsY(); + int cw = context.getVisibleWidth(); + int ch = context.getVisibleHeight(); + // The arrays should be ordered, no needs to continue for this one + if (!toDraw.isVisible(cx, cy, cw, ch) && toDraw.positiveDistanceToPoint(cx + cw, cy + ch)) { + break; + } + // ***Common*** nodes visibility + if ((!toDraw.isSameAs(last) || toDraw.isSelected()) && (toDraw.isVisible(context.getContentsX(), context.getContentsY(), context.getVisibleWidth(), context.getVisibleHeight()))) { + nodesCount++; + + toDraw.draw(context); + if (hasFocus()) { + toDraw.drawFocus(context); + } + } + last = toDraw; + } + return nodesCount; + } + + /** + * Draws the focus within the graphical context. + * + * @param context + * The context + */ + public void drawFocus(IGC context) { + context.drawFocus(getX(), getY(), getWidth(), getHeight()); + } + + /** + * Determine if the given point (px,py) is contained in the rectangle (x,y,width,height) + * + * @param x the rectangle x coordinate + * @param y the rectangle y coordinate + * @param width the rectangle width + * @param height the rectangle height + * @param px the x coordinate of the point to test + * @param py the y coordinate of the point to test + * @return true if contained false otherwise + */ + public static boolean contains(int x, int y, int width, int height, int px, int py) { + int locX = x; + int locY = y; + int locWidth = width; + int locHeight = height; + + if (width < 0) { + locX = locX + width; + locWidth = -locWidth; + } + + if (height < 0) { + locY = locY + height; + locHeight = -locHeight; + } + return (px >= locX) && (py >= locY) && ((px - locX) <= locWidth) && ((py - locY) <= locHeight); + } + + /** + * Sets the start event occurrence attached to this graphNode. + * + * @param occurence + * the start event occurrence attached to the graphNode + * @since 2.0 + */ + protected void setStartOccurrence(int occurence) { + fStartEventOccurrence = occurence; + } + + /** + * Sets the end event occurrence attached to this graphNode + * + * @param occurence + * the start event occurrence attached to the graphNode + * @since 2.0 + */ + protected void setEndOccurrence(int occurence) { + fEndEventOccurrence = occurence; + } + + /** + * Sets the color preference id + * @param id + * The color preference id + * @since 2.0 + */ + protected void setColorPrefId(String id) { + fPrefId = id; + } + + /** + * Gets the color preference id + * @return the color preference id + * @since 2.0 + */ + protected String getColorPrefId() { + return fPrefId; + } + + /** + * @return if node has children or not + * @since 2.0 + */ + protected boolean hasChildren() { + return fHasChilden; + } + + /** + * Sets the flag indicating where the node has children or not. + * @param hasChildren + * if node has children or not + * @since 2.0 + */ + protected void hasChildren(boolean hasChildren) { + fHasChilden = hasChildren; + } + /** + * Returns a map from node name to graph node. + * + * @return map with children graph bodes + * @since 2.0 + */ + protected Map> getNodeMap() { + return fNodes; + } + /** + * Returns a map from node name to graph node for forward sorting + * + * @return forward sorting map + * @since 2.0 + */ + protected Map> getForwardNodes() { + return fForwardNodes; + } + /** + * Returns a map from node name to graph node for backwards sorting. + * + * @return backwards sorting map + * @since 2.0 + */ + protected Map> getBackwardNodes() { + return fBackwardNodes; + } + /** + * Returns a map from node name to index. + * + * @return map with node name to index + * @since 2.0 + */ + protected Map getIndexes() { + return fIndexes; + } + + /** + * Returns a map from node name to sort flag for forwards sorting. + * @return a map from node name to sort flag + * @since 2.0 + */ + protected Map getForwardSortMap() { + return fForwardSort; + } + /** + * Returns a map from node name to flag for backwards sorting. + * @return map from node name to flag for backwards sorting. + * @since 2.0 + */ + protected Map getBackwardSortMap() { + return fBackwardSort; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/HotSpot.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/HotSpot.java new file mode 100755 index 0000000000..703db9c1f4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/HotSpot.java @@ -0,0 +1,193 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IImage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.ISDPreferences; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref; + +/** + * Class to add a hot spot marker. + * + * @version 1.0 + * @author sveyrier + */ +public class HotSpot extends GraphNode { + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The grahNode ID constant + */ + public static final String GLYPH = "Glyph"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The execution occurrence the hot spot marker is for. + */ + private BasicExecutionOccurrence fExecOcc = null; + /** + * The occurrence number. + */ + private int fOccurrence = 0; + /** + * The marker image to display. + */ + private IImage fImage = null; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + public HotSpot() { + setColorPrefId(ISDPreferences.PREF_EXEC); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + /** + * Set the marker image. + * + * @param img A image to set + */ + public void setImage(IImage img) { + fImage = img; + } + + /** + * Returns the marker image. + * + * @return the image + * @since 2.0 + */ + protected IImage getImage() { + return fImage; + } + + @Override + public int getX() { + if (fExecOcc != null) { + return fExecOcc.getX() - 3; + } + return 0; + } + + @Override + public int getY() { + if (fExecOcc != null){ + return fExecOcc.getY(); + } + return 0; + } + + @Override + public int getWidth() { + if (fExecOcc != null) { + return fExecOcc.getWidth() + 7; + } + return 0; + } + + @Override + public int getHeight() { + if (fExecOcc != null) { + return fExecOcc.getWidth() + 10; + } + return 0; + } + + /** + * Set the lifeline on which the execution occurrence appears. + * + * @param occ the parent lifeline + */ + public void setExecution(BasicExecutionOccurrence occ) { + fExecOcc = occ; + fExecOcc.addNode(this); + } + + /** + * Get the lifeline on which the execution occurrence appears. + * + * @return - the parent lifeline + */ + public BasicExecutionOccurrence getExecOcc() { + return fExecOcc; + } + + /** + * Returns the occurrence number. + * + * @return the occurrence number. + */ + public int getOccurrence() { + return fOccurrence; + } + + /** + * Set the occurrence number. + * + * @param occ A number to set. + */ + public void setOccurrence(int occ) { + fOccurrence = occ; + } + + @Override + public void draw(IGC context) { + + ISDPreferences pref = SDViewPref.getInstance(); + + // The execution occurrence is selected + // if the owning lifeline is selected + if (isSelected() || (fExecOcc != null && fExecOcc.isSelected()) || (fExecOcc != null && fExecOcc.getLifeline() != null && fExecOcc.getLifeline().isSelected())) { + context.setBackground(pref.getBackGroundColorSelection()); + context.setForeground(pref.getForeGroundColorSelection()); + } else { + context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_EXEC)); + context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_EXEC)); + } + context.drawImage(fImage, getX(), getY(), getWidth(), getHeight()); + } + + @Override + public String getArrayId() { + return GLYPH; + } + + @Override + public boolean isVisible(int x, int y, int width, int height) { + return true; + } + + @Override + public boolean contains(int xValue, int yValue) { + int x = getX(); + int y = getY(); + int width = getWidth(); + int height = getHeight(); + + if (GraphNode.contains(x, y, width, height, xValue, yValue)) { + return true; + } + return false; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/ITimeRange.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/ITimeRange.java new file mode 100755 index 0000000000..9ea37acf4a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/ITimeRange.java @@ -0,0 +1,46 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; + +/** + * A interface for handling time ranges. + * + * @version 1.0 + * @author sveyrier + */ +public interface ITimeRange { + + /** + * Returns the time when the message began. + * @return the time when the message began + * @since 2.0 + */ + ITmfTimestamp getStartTime(); + + /** + * Returns the time when the message ended. + * + * @return the time when the message ended + * @since 2.0 + */ + ITmfTimestamp getEndTime(); + + /** + * Returns flag to indicate whether time information is available or not. + * + * @return flag to indicate whether time information is available or not + */ + boolean hasTimeInfo(); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/Lifeline.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/Lifeline.java new file mode 100755 index 0000000000..3bbabf1238 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/Lifeline.java @@ -0,0 +1,534 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IColor; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IImage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.ISDPreferences; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref; + +/** + * Lifeline is the UML2 lifeline graphical representation.
    + * Each lifeline owns a set of event occurrences. An event occurrence is the base element in UML2 to set an event in a + * sequence diagram.
    + * Event occurrence define the drawing order of graph node along a lifeline. In this lifeline implementation, event + * occurrences are just integer index. The event occurrences with the same value on different lifelines will correspond + * the same y coordinate value. + * + * @version 1.0 + * @author sveyrier + * + */ +public class Lifeline extends GraphNode { + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The life line tag. + */ + public static final String LIFELINE_TAG = "Lifeline"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attribute + // ------------------------------------------------------------------------ + /** + * The lifeline position in the containing frame + */ + private int fIndexInFrame = 0; + /** + * The frame where the lifeline is drawn + */ + private Frame fFrame = null; + /** + * The current event occurrence created in the lifeline + */ + private int fEventOccurrence = 0; + /** + * The lifeline category. + */ + private int fCategory = -1; + /** + * Flag whether lifeline has time information available or not + */ + private boolean fHasTimeInfo = false; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor + */ + public Lifeline() { + setColorPrefId(ISDPreferences.PREF_LIFELINE); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public int getX() { + return Metrics.FRAME_H_MARGIN + Metrics.LIFELINE_H_MAGIN + (fIndexInFrame - 1) * Metrics.swimmingLaneWidth(); + } + + @Override + public int getY() { + return 2 * Metrics.FRAME_NAME_H_MARGIN + Metrics.LIFELINE_VT_MAGIN / 2 + Metrics.getFrameFontHeigth() + Metrics.getLifelineHeaderFontHeigth() + Metrics.FRAME_V_MARGIN + 2 * Metrics.LIFELINE_HEARDER_TEXT_V_MARGIN; + } + + @Override + public int getWidth() { + return Metrics.getLifelineWidth(); + } + + @Override + public int getHeight() { + // Set room for two text lines + return Metrics.getLifelineFontHeigth()/** 2 */ + + 2 * Metrics.LIFELINE_NAME_H_MARGIN; + } + + /** + * Set the lifeline category for this lifeline. + * + * @param arrayIndex the index of the category to use + * @see Frame#setLifelineCategories(LifelineCategories[]) + */ + public void setCategory(int arrayIndex) { + fCategory = arrayIndex; + } + + /** + * Gets the lifeline category for this lifeline. + * + * @return arrayIndex the index of the category to use + * @since 2.0 + */ + public int getCategory() { + return fCategory; + } + + /** + * Returns the tooltip text for the lifeline. It is the combination between the category name(if any) and the + * lifeline name + * + * @return the tooltip text + */ + public String getToolTipText() { + if (fCategory >= 0) { + LifelineCategories[] categories = fFrame.getLifelineCategories(); + if (fCategory < categories.length) { + return categories[fCategory].getName() + " " + getName(); //$NON-NLS-1$ + } + } + return ""; //$NON-NLS-1$ + } + + /** + * Returns the index of the first visible Execution Occurrence in the execution occurrence array.
    + * Execution Occurrences are Y ordered in this array + * + * @return the first visible Execution Occurrence + */ + public int getExecOccurrenceDrawIndex() { + if (!hasChildren()) { + return 0; + } + if (getIndexes().get(BasicExecutionOccurrence.EXEC_OCC_TAG) != null) { + return getIndexes().get(BasicExecutionOccurrence.EXEC_OCC_TAG).intValue(); + } + return 0; + } + + /** + * Set the frame on which this lifeline must be drawn + * + * @param parentFrame + * Parent frame + */ + protected void setFrame(Frame parentFrame) { + fFrame = parentFrame; + if (fHasTimeInfo) { + fFrame.setHasTimeInfo(true); + } + if (fFrame.getMaxEventOccurrence() < getEventOccurrence() + 1) { + fFrame.setMaxEventOccurrence(getEventOccurrence() + 1); + } + } + + /** + * Returns the frame which this lifeline is drawn + * + * @return the Frame + */ + protected Frame getFrame() { + return fFrame; + } + + /** + * Set the lifeline position index in the containing frame + * + * @param index the lifeline X position + */ + protected void setIndex(int index) { + fIndexInFrame = index; + } + + /** + * Returns the lifeline position in de the containing frame + * + * @return the X position + */ + public int getIndex() { + return fIndexInFrame; + } + + /** + * Set the lifeline event occurrence to the value given in parameter This only change the current event occurrence, + * greater event created on this lifeline are still valid and usable. This also need to inform the frame of the + * operation mostly to store in the frame the greater event found in the diagram (used to determine the frame + * height) + * + * @param eventOcc the new current event occurrence + */ + public void setCurrentEventOccurrence(int eventOcc) { + if ((fFrame != null) && (fFrame.getMaxEventOccurrence() < eventOcc)) { + fFrame.setMaxEventOccurrence(eventOcc); + } + fEventOccurrence = eventOcc; + } + + /** + * Returns the last created event occurrence along the lifeline. + * + * @return the current event occurrence + */ + public int getEventOccurrence() { + return fEventOccurrence; + } + + /** + * Creates a new event occurrence along the lifeline. + * + * @return the new created event occurrence + */ + public int getNewEventOccurrence() { + setCurrentEventOccurrence(fEventOccurrence + 1); + return fEventOccurrence; + } + + /** + * Adds the execution occurrence given in parameter to the lifeline.
    + * A Execution occurrence is never drawn in the frame instead it is added to a lifeline + * + * @param exec the execution occurrence to add + */ + public void addExecution(BasicExecutionOccurrence exec) { + exec.setLifeline(this); + addNode(exec); + if ((fFrame != null) && (fFrame.getMaxEventOccurrence() < exec.getEndOccurrence())) { + fFrame.setMaxEventOccurrence(exec.getEndOccurrence()); + } + } + + /** + * Set whether lifeline has time information available or not. + * @param value The value to set + */ + protected void setTimeInfo(boolean value) { + fHasTimeInfo = value; + if ((fFrame != null) && value) { + fFrame.setHasTimeInfo(value); + } + } + + /** + * Returns true if at least one execution occurrence has time info. + * + * @return true if at least one execution occurrence has time info + */ + public boolean hasTimeInfo() { + return fHasTimeInfo; + } + + /** + * Returns the list of execution occurrence on this lifeline. + * + * @return the execution occurrence list + */ + public List getExecutions() { + if (hasChildren()) { + return getNodeMap().get(BasicExecutionOccurrence.EXEC_OCC_TAG); + } + return new ArrayList<>(); + } + + @Override + public boolean contains(int xValue, int yValue) { + int x = getX(); + int y = getY(); + int width = getWidth(); + int height = getHeight(); + + if (fFrame == null) { + return false; + } + if (GraphNode.contains(x, y, width, height, xValue, yValue)) { + return true; + } + if (GraphNode.contains(x + Metrics.getLifelineWidth() / 2 - Metrics.EXECUTION_OCCURRENCE_WIDTH / 2, y + height, Metrics.EXECUTION_OCCURRENCE_WIDTH, (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * fFrame.getMaxEventOccurrence() + + Metrics.LIFELINE_VB_MAGIN - 4, xValue, yValue)) { + return true; + } + + height = Metrics.getLifelineFontHeigth() + 2 * Metrics.LIFELINE_HEARDER_TEXT_V_MARGIN; + int hMargin = (Metrics.LIFELINE_VT_MAGIN - height) / 2; + + if (hMargin >= 2) { + if (fFrame.getVisibleAreaY() < y - height - hMargin) { + if (GraphNode.contains(x - Metrics.LIFELINE_SPACING / 2 + 1, y - height - hMargin, Metrics.swimmingLaneWidth() - 2, height + 1, xValue, yValue)) { + return true; + } + } else { + if (GraphNode.contains(x - Metrics.LIFELINE_SPACING / 2 + 1, fFrame.getVisibleAreaY(), Metrics.swimmingLaneWidth() - 2, height, xValue, yValue)) { + return true; + } + } + } + if (getNodeAt(xValue, yValue) != null) { + return true; + } + return false; + } + + /** + * Returns the lifeline visibility for the given visible area + * + * @param vx The x coordinate of the visible area + * @param vy The y coordinate of the visible area + * @param vwidth The width of the visible area + * @param vheight The height of the visible area + * @return true if visible false otherwise + */ + @Override + public boolean isVisible(int vx, int vy, int vwidth, int vheight) { + int x = getX(); + int width = getWidth(); + if (((x >= vx) && (x <= vx + vwidth)) || ((x + width >= vx) && (x <= vx))) { + return true; + } + return false; + } + + /** + * Draws the name within the graphical context. + * + * @param context The graphical context. + */ + protected void drawName(IGC context) { + ISDPreferences pref = SDViewPref.getInstance(); + + int x = getX(); + int y = getY(); + int height = Metrics.getLifelineHeaderFontHeigth() + 2 * Metrics.LIFELINE_HEARDER_TEXT_V_MARGIN; + int hMargin = Metrics.LIFELINE_VT_MAGIN / 4;// (Metrics.LIFELINE_NAME_H_MARGIN)/2; + + context.setLineStyle(context.getLineSolidStyle()); + context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_LIFELINE_HEADER)); + context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_LIFELINE_HEADER)); + context.setFont(pref.getFont(ISDPreferences.PREF_LIFELINE_HEADER)); + if (hMargin >= 0) { + if (fFrame.getVisibleAreaY() < y - height - hMargin) { + context.fillRectangle(x - Metrics.LIFELINE_SPACING / 2 + 1, y - height - hMargin, Metrics.swimmingLaneWidth() - 2, height); + context.drawRectangle(x - Metrics.LIFELINE_SPACING / 2 + 1, y - height - hMargin, Metrics.swimmingLaneWidth() - 2, height); + context.setForeground(pref.getFontColor(ISDPreferences.PREF_LIFELINE_HEADER)); + context.drawTextTruncatedCentred(getName(), x + Metrics.LIFELINE_NAME_V_MARGIN - Metrics.LIFELINE_SPACING / 2 + 1, y - height - hMargin, Metrics.swimmingLaneWidth() - 2 * Metrics.LIFELINE_NAME_V_MARGIN - 2, height, true); + } else { + context.fillRectangle(x - Metrics.LIFELINE_SPACING / 2 + 1, fFrame.getVisibleAreaY(), Metrics.swimmingLaneWidth() - 2, height); + context.drawRectangle(x - Metrics.LIFELINE_SPACING / 2 + 1, fFrame.getVisibleAreaY(), Metrics.swimmingLaneWidth() - 2, height); + context.setForeground(pref.getFontColor(ISDPreferences.PREF_LIFELINE_HEADER)); + context.drawTextTruncatedCentred(getName(), x - Metrics.LIFELINE_SPACING / 2 + Metrics.LIFELINE_NAME_V_MARGIN + 1, fFrame.getVisibleAreaY(), Metrics.swimmingLaneWidth() - 2 * Metrics.LIFELINE_NAME_V_MARGIN - 2, height, true); + } + } + } + + /** + * Force the lifeline to be drawn at the given coordinate + * + * @param context - the context to draw into + * @param x - the x coordinate + * @param y - the y coordinate + */ + public void draw(IGC context, int x, int y) { + + ISDPreferences pref = SDViewPref.getInstance(); + + // Set the draw color depending if the lifeline must be selected or not + context.setLineWidth(Metrics.NORMAL_LINE_WIDTH); + if (isSelected()) { + if (pref.useGradienColor()) { + context.setGradientColor(pref.getBackGroundColor(ISDPreferences.PREF_LIFELINE)); + } + context.setBackground(pref.getBackGroundColorSelection()); + context.setForeground(pref.getForeGroundColorSelection()); + } else { + if (pref.useGradienColor()) { + context.setGradientColor(pref.getBackGroundColor(ISDPreferences.PREF_LIFELINE)); + context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_FRAME)); + } else { + context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_LIFELINE)); + } + context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_LIFELINE)); + } + // Store the lifeline coordinates to save some calls + int width = getWidth(); + int height = getHeight(); + + // Draw the rectangle which contain the lifeline name + if (pref.useGradienColor()) { + context.fillGradientRectangle(x, y, width, height / 2 - 7, true); + context.fillRectangle(x, y + height / 2 - 8, width, +height / 2 - 5); + context.fillGradientRectangle(x, y + height, width, -height / 2 + 6, true); + } else { + context.fillRectangle(x, y, width, height); + } + context.drawRectangle(x, y, width, height); + + if (fCategory >= 0) { + LifelineCategories[] categories = fFrame.getLifelineCategories(); + if (fCategory < categories.length) { + IImage image = categories[fCategory].getImage(); + if (image != null) { + context.drawImage(image, x, y, width, height); + } + } + } + + // Draw the lifeline label into the rectangle + // The label is truncated if it cannot fit + IColor temp = context.getForeground(); + context.setFont(pref.getFont(ISDPreferences.PREF_LIFELINE)); + context.setForeground(pref.getFontColor(ISDPreferences.PREF_LIFELINE)); + context.drawTextTruncatedCentred(getName(), x + Metrics.LIFELINE_NAME_V_MARGIN, y, Metrics.getLifelineWidth() - 2 * Metrics.LIFELINE_NAME_V_MARGIN, height, true); + + context.setLineStyle(context.getLineDashStyle()); + context.setForeground(temp); + int oldStyle = context.getLineStyle(); + + // Now draw the lifeline vertical line + // this line height depends on a stop assignment + // if there is no stop the line is drawn to the bottom of the frame + + // by default set the height to reach the frame bottom + int dashedLineEnd = y + height + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * fFrame.getMaxEventOccurrence() + Metrics.LIFELINE_VB_MAGIN; + /* + * if (stop != null) { dashedLineEnd = stop.getY(); } + */ + + if (isSelected()) { + context.setForeground(pref.getBackGroundColorSelection()); + context.setLineWidth(5); + context.drawLine(x + Metrics.getLifelineWidth() / 2, y + height, x + Metrics.getLifelineWidth() / 2, dashedLineEnd - 4); + context.setForeground(pref.getForeGroundColorSelection()); + } + + context.setLineWidth(Metrics.NORMAL_LINE_WIDTH); + context.drawLine(x + Metrics.getLifelineWidth() / 2, y + height, x + Metrics.getLifelineWidth() / 2, dashedLineEnd - 4); + context.drawLine(x + Metrics.getLifelineWidth() / 2, y + height, x + Metrics.getLifelineWidth() / 2, dashedLineEnd - 4); + context.setLineStyle(oldStyle); + + context.setLineStyle(context.getLineSolidStyle()); + + if (hasFocus()) { + drawFocus(context); + } + + super.drawChildenNodes(context); + } + + /** + * Draws the select execution occurrence region using the given color + * + * @param context the graphical context + * @param startEvent the region start + * @param nbEvent the region height + * @param color the color to use + */ + public void highlightExecOccurrenceRegion(IGC context, int startEvent, int nbEvent, IColor color) { + IColor backupColor = context.getBackground(); + context.setBackground(color); + int x = getX() + Metrics.getLifelineWidth() / 2 - Metrics.EXECUTION_OCCURRENCE_WIDTH / 2; + int y = getY() + getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * startEvent; + int width = Metrics.EXECUTION_OCCURRENCE_WIDTH; + int height = ((Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing())) * nbEvent; + context.fillRectangle(x, y, width, height); + context.setBackground(backupColor); + } + + @Override + public void draw(IGC context) { + draw(context, getX(), getY()); + } + + @Override + public String getArrayId() { + return LIFELINE_TAG; + } + + @Override + public boolean positiveDistanceToPoint(int x, int y) { + if (getX() > x - Metrics.swimmingLaneWidth()) { + return true; + } + return false; + } + + @Override + public GraphNode getNodeAt(int x, int y) { + int vy = 0; + int vh = 0; + if (getFrame() != null) { + vy = getFrame().getVisibleAreaY(); + vh = getFrame().getVisibleAreaHeight(); + } else { + return null; + } + if (getExecutions() == null) { + return null; + } + for (int i = getExecOccurrenceDrawIndex(); i < getExecutions().size(); i++) { + GraphNode node = getExecutions().get(i); + if (node.getHeight() < 0) { + if (node.getY() + node.getHeight() > vy + vh) { + break; + } + } else { + if (node.getY() > vy + vh) { + break; + } + } + if (node.contains(x, y)) { + GraphNode internal = node.getNodeAt(x, y); + if (internal != null) { + return internal; + } + return node; + } + } + return null; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/LifelineCategories.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/LifelineCategories.java new file mode 100755 index 0000000000..db1449caad --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/LifelineCategories.java @@ -0,0 +1,81 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IImage; + +/** + *

    + * LifelineCategories is used to assign additional description for + * lifelines of the same type. This consists in providing a type name and an icon. + * The icon will be displayed in the rectangle which contains the lifeline name. + * The category name is only display in the lifeline tooltip. + *

    + * + * @version 1.0 + * @author sveyrier + */ +public class LifelineCategories { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The category name + */ + private String fName = null; + /** + * The category image + */ + private IImage fCategoryImage = null; + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + /** + * Returns the category name. + * + * @return the category name + */ + public String getName() { + return fName; + } + + /** + * Sets the category name. + * + * @param string the name + */ + public void setName(String string) { + fName = string; + } + + /** + * Returns the category icon. + * + * @return the category icon + */ + public IImage getImage() { + return fCategoryImage; + } + + /** + * Sets the category icon. + * + * @param image the icon + */ + public void setImage(IImage image) { + fCategoryImage = image; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/Metrics.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/Metrics.java new file mode 100755 index 0000000000..57f6a13193 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/Metrics.java @@ -0,0 +1,332 @@ +/********************************************************************** + * Copyright (c) 2005, 2012 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; + +/** + * This class contains the metrics used to layout a sequence diagram on a view The class method are mostly used in + * combination with the preferences + * + * @version 1.0 + * @author sveyrier + * + */ +public class Metrics { + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * Space between the Frame and the top of the View This also represent the space between the frame and the bottom of + * the View + */ + public static final int FRAME_H_MARGIN = 10; + /** + * Space between the Frame and the left of the View This also represent the space between the Frame and the right of + * the View + */ + public static final int FRAME_V_MARGIN = 10; + /** + * Space between the Lifelines and the right of the Frame + */ + public static final int LIFELINE_H_MAGIN = 23; + /** + * Space between the Lifelines and the bottom of the Frame + */ + public static final int LIFELINE_VB_MAGIN = 20; + /** + * Space between the Lifelines and the top of the Frame + */ + public static final int LIFELINE_VT_MAGIN = 30;// 18 + /** + * Vertical space between the lifeline name and the rectangle which contains that name This is only for the + * "always visible" lifeline name rectangle + */ + public static final int LIFELINE_HEARDER_TEXT_V_MARGIN = 4; + /** + * Vertical spacing between messages + */ + public static final int MESSAGES_SPACING = 30; + /** + * Vertical spacing between the message and its name + */ + public static final int MESSAGES_NAME_SPACING = 10; + /** + * Horizontal spacing between the Frame name and its containing rectangle + */ + public static final int FRAME_NAME_H_MARGIN = 4; + /** + * Vertical spacing between the Frame name and its containing rectangle + */ + public static final int FRAME_NAME_V_MARGIN = 8; + /** + * Horizontal spacing between the lifeline name and its containing rectangle + */ + public static final int LIFELINE_NAME_H_MARGIN = 14; + /** + * Vertical spacing between the lifeline name and its containing rectangle + */ + public static final int LIFELINE_NAME_V_MARGIN = 20; + /** + * Space between the rectangles which contain the Lifelines name + */ + public static final int LIFELINE_SPACING = 45; + /** + * The circle ray used to draw the circle which compose Found and Lost messages + */ + public static final int MESSAGE_CIRCLE_RAY = 5; + /** + * Execution occurrence vertical width + */ + public static final int EXECUTION_OCCURRENCE_WIDTH = 8; + /** + * The square width which contains the Stop representation (a cross) + */ + public static final int STOP_WIDTH = 20; + /** + * The internal message width. + */ + public static final int INTERNAL_MESSAGE_WIDTH = 20; + /** + * The internal sychrounous message height. + */ + public static final int SYNC_INTERNAL_MESSAGE_HEIGHT = 10; + /** + * Line width used when drawing selected GraphNode + */ + public static final int SELECTION_LINE_WIDTH = 5; + /** + * Line width used when drawing non selected GraphNode + */ + public static final int NORMAL_LINE_WIDTH = 1; + /** + * The internal vertical message margin + */ + public static final int INTERNAL_MESSAGE_V_MARGIN = 10; + + /** + * Used to sample the diagram. When the lifeline spacing is smaller than this constant when zooming out then less + * lifelines are displayed to avoid lifelines overlapping and mainly saving some execution time + */ + public static final int LIFELINE_SIGNIFICANT_HSPACING = 10; + /** + * Used to sample the diagram. When the message spacing is smaller than this constant when zooming out then less + * message are displayed to avoid message overlapping and mainly saving some execution time + */ + public static final int MESSAGE_SIGNIFICANT_VSPACING = 1; + /** + * Message selection tolerance. Used for internal syncMessages only + */ + public static final int MESSAGE_SELECTION_TOLERANCE = 30; + /** + * The focus drawing margin. + */ + public static final int FOCUS_DRAWING_MARGIN = 10; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The lifeline font height + */ + private static int fLifelineFontHeight = 0; + /** + * The message font height + */ + private static int fMessageFontHeight = 0; + /** + * The frame font height + */ + private static int fFrameFontHeight = 0; + /** + * The lifeline header font height + */ + private static int fLifelineHeaderFontHeight = 0; + /** + * The lifeline font widht + */ + private static int fLifelineFontWidth = 0; + /** + * The lifeline width + */ + private static int fLifeLineWidth = 119; + /** + * The (forced) event spacing + */ + private static int fForcedEventSpacing = -1; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + /** + * Constructor + * + * Hide private constructor + */ + private Metrics() { + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + /** + * Set the character height used to draw the lifeline name + * + * @param height the character height + */ + static public void setLifelineFontHeight(int height) { + fLifelineFontHeight = height; + } + + /** + * Set the character width used to draw the lifeline name + * + * @param width the character width + */ + static public void setLifelineFontWidth(int width) { + fLifelineFontWidth = width; + } + + /** + * Set the character height used to draw the message name + * + * @param fontHeight the character height + */ + static public void setMessageFontHeight(int fontHeight) { + fMessageFontHeight = fontHeight; + } + + /** + * Returns the character height used to draw the lifeline name + * + * @return the character height + */ + static public int getFrameFontHeigth() { + return fFrameFontHeight; + } + + /** + * Set the character height used to draw the message name + * + * @param fontHeight the character height + */ + static public void setFrameFontHeight(int fontHeight) { + fFrameFontHeight = fontHeight; + } + + /** + * Returns the character height used to draw the lifeline name + * + * @return the character height + */ + static public int getLifelineHeaderFontHeigth() { + return fLifelineHeaderFontHeight; + } + + /** + * Set the character height used to draw the message name + * + * @param fontHeight the character height + */ + static public void setLifelineHeaderFontHeight(int fontHeight) { + fLifelineHeaderFontHeight = fontHeight; + } + + /** + * Returns the character height used to draw the lifeline name + * + * @return the character height + */ + static public int getLifelineFontHeigth() { + return fLifelineFontHeight; + } + + /** + * Returns the character height used to draw the message name + * + * @return the character height + */ + static public int getMessageFontHeigth() { + if (fForcedEventSpacing >= 0) { + return 0; + } + return fMessageFontHeight; + } + + /** + * This is the vertical space used by a Lifeline (mostly the rectangle which contain its name) + * + * @return the vertical space used by a Lifeline + */ + static public int getLifelineWidth() { + return fLifeLineWidth; + } + + /** + * Set the vertical space used by a Lifeline (mostly the rectangle which contain its name) + * + * @param value the vertical space + */ + static public void setLifelineWidth(int value) { + fLifeLineWidth = value; + } + + /** + * Returns the swimming lane width + * + * @return the swimming lane width + */ + static public int swimmingLaneWidth() { + return getLifelineWidth() + LIFELINE_SPACING; + } + + /** + * Returns the character width used to draw the Lifelines name + * + * @return the average character width + */ + static public int getAverageCharWidth() { + return fLifelineFontWidth; + } + + /** + * Returns the message spacing. + * + * @return the message spacing + */ + static public int getMessagesSpacing() { + if (fForcedEventSpacing >= 0) { + return fForcedEventSpacing; + } + return MESSAGES_SPACING; + } + + /** + * Sets the forced event spacing value . + * + * @param eventSpacing + * The spacing value + */ + static public void setForcedEventSpacing(int eventSpacing) { + fForcedEventSpacing = eventSpacing; + } + + /** + * Gets the forced event spacing value. + * + * @return forcedEventSpacing + */ + static public int getForcedEventSpacing() { + return fForcedEventSpacing; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/SDTimeEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/SDTimeEvent.java new file mode 100755 index 0000000000..3b7dbd807f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/SDTimeEvent.java @@ -0,0 +1,91 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; + +/** + * Class implementation of a sequence diagram time event. + * + * @version 1.0 + * @author sveyrier + * + */ +public class SDTimeEvent { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The time stamp of the event + */ + private final ITmfTimestamp fTimestamp; + /** + * The event index. + */ + private final int fEvent; + /** + * The time range implementing node. + */ + private final ITimeRange fNode; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * The default constructor. + * + * @param time The time stamp of the event. + * @param event The event index. + * @param node The time range implementing node. + * @since 2.0 + */ + public SDTimeEvent(ITmfTimestamp time, int event, ITimeRange node) { + fTimestamp = time; + fEvent = event; + fNode = node; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + /** + * Returns the timestamp of the event. + * + * @return the timestamp of the event. + * @since 2.0 + */ + public ITmfTimestamp getTime() { + return fTimestamp; + } + + /** + * Returns the event index. + * + * @return the event index. + */ + public int getEvent() { + return fEvent; + } + + /** + * Returns the time range implementing node. + * + * @return the time range implementing node. + */ + public ITimeRange getGraphNode() { + return fNode; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/Stop.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/Stop.java new file mode 100755 index 0000000000..c795fb87c1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/Stop.java @@ -0,0 +1,167 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.ISDPreferences; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref; + +/** + *

    + * It is the UML2 stop graphical representation in the sequence diagram viewer. + * This draw a cross on the lifeline. The stop y coordinate depend on the event occurrence when it appears. + * A stop is never drawn it is assigned to a lifeline. + *

    + * + * @version 1.0 + * @author sveyrier + */ +public class Stop extends GraphNode { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The graphNode ID + */ + public static final String STOP = "STOP"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The owning lifeline on which the stop appears + */ + private Lifeline fLifeline = null; + /** + * This basically represents the time when the stop occurs on the owning Lifeline + * + * @see Lifeline Lifeline for more event occurence details + */ + private int fEventOccurrence = 0; + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public int getX() { + if (fLifeline == null) { + return 0; + } + return fLifeline.getX() + Metrics.getLifelineWidth() / 2 - Metrics.STOP_WIDTH / 2; + } + + @Override + public int getY() { + if (fLifeline == null) { + return 0; + } + return fLifeline.getY() + fLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * fEventOccurrence - Metrics.STOP_WIDTH / 2; + } + + @Override + public int getWidth() { + if (fLifeline == null) { + return 0; + } + return Metrics.STOP_WIDTH; + } + + @Override + public int getHeight() { + if (fLifeline == null) { + return 0; + } + return Metrics.STOP_WIDTH; + } + + /** + * Set the lifeline on which the stop must be draw + * + * @param theLifeline The the stop owing lifeline + */ + public void setLifeline(Lifeline theLifeline) { + fLifeline = theLifeline; + } + + /** + * Get the lifeline on which the stop must be draw + * + * @return the the stop owing lifeline + * @since 2.0 + */ + public Lifeline getLifeline() { + return fLifeline; + } + + /** + * Get the event occurrence when this stop appears + * + * @return the eventOccurence to assign to the stop + * @since 2.0 + */ + public int getEventOccurrence() { + return fEventOccurrence; + } + + /** + * Set the event occurrence when this stop appears + * + * @param occurrence the eventOccurence to assign to the stop + */ + public void setEventOccurrence(int occurrence) { + fEventOccurrence = occurrence; + } + + @Override + public void draw(IGC context) { + + ISDPreferences pref = SDViewPref.getInstance(); + + // Set the appropriate color depending if the graph node if selected or not + if (fLifeline.isSelected()) { + context.setForeground(pref.getBackGroundColorSelection()); + context.setLineWidth(Metrics.SELECTION_LINE_WIDTH); + int lastWidth = context.getLineWidth(); + context.setLineWidth(9); + // Draw a cross on the lifeline + context.drawLine(getX(), getY(), getX() + getWidth(), getY() + getHeight()); + context.drawLine(getX() + getWidth(), getY(), getX(), getY() + getHeight()); + // restore the context + context.setLineWidth(lastWidth); + context.setBackground(pref.getBackGroundColorSelection()); + context.setForeground(pref.getForeGroundColorSelection()); + } else { + context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_LIFELINE)); + context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_LIFELINE)); + } + int lastWidth = context.getLineWidth(); + context.setLineWidth(3); + // Draw a cross on the lifeline + context.drawLine(getX(), getY(), getX() + getWidth(), getY() + getHeight()); + context.drawLine(getX() + getWidth(), getY(), getX(), getY() + getHeight()); + // restore the context + context.setLineWidth(lastWidth); + } + + @Override + public String getArrayId() { + return STOP; + } + + @Override + public boolean contains(int x, int y) { + return false; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/SyncMessage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/SyncMessage.java new file mode 100755 index 0000000000..04b8394030 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/SyncMessage.java @@ -0,0 +1,296 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; + +import java.util.Comparator; + +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.ISDPreferences; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.SortSyncMessageComparator; + +/** + * A SyncMessage is a synchronous message which appear at the same event occurrence on both lifeline ends (sender and + * receiver).
    + * A Sync message is usually drawn horizontally.
    + *
    + *
    + * Usage example: + * + *
    + * Frame frame;
    + * Lifeline lifeLine1;
    + * Lifeline lifeLine2;
    + *
    + * SyncMessage message = new SyncMessage();
    + * // Create a new event occurrence on each lifeline
    + * lifeline1.getNewOccurrenceIndex();
    + * lifeline2.getNewOccurrenceIndex();
    + * // Set the message sender and receiver
    + * message.setStartLifeline(lifeLine1);
    + * message.setEndLifline(lifeline2);
    + * message.setName("Message label");
    + * // add the message to the frame
    + * frame.addMessage(message);
    + * 
    + * + * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Lifeline Lifeline for more event occurence details + * @version 1.0 + * @author sveyrier + * + */ +public class SyncMessage extends BaseMessage implements ITimeRange { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The graphNode ID + */ + public static final String SYNC_MESS_TAG = "SyncMessage"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The associated message return + */ + private SyncMessageReturn fMessageReturn; + /** + * The time when the message occurs + */ + private ITmfTimestamp fEventTime = new TmfTimestamp(); + /** + * Flag whether the message has time information available or not + */ + private boolean fHasTimeInfo = false; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + public SyncMessage() { + setColorPrefId(ISDPreferences.PREF_SYNC_MESS); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + /** + * Ensure both lifelines have the same event occurrence (the greater found on each lifeline) + */ + protected void syncLifelinesEventOccurrence() { + if ((getStartLifeline() != null) && (getEndLifeline() != null)) { + int newIndex = 0; + if (getStartLifeline().getEventOccurrence() > getEndLifeline().getEventOccurrence()) { + newIndex = getStartLifeline().getEventOccurrence(); + } else { + newIndex = getEndLifeline().getEventOccurrence(); + } + getStartLifeline().setCurrentEventOccurrence(newIndex); + getEndLifeline().setCurrentEventOccurrence(newIndex); + setEventOccurrence(getStartLifeline().getEventOccurrence()); + } + } + + /** + * Set the lifeLine from which the message has been sent.
    + * A new event occurrence will be created on this lifeLine.
    + * SyncMessage must occur at the same event occurrence on both lifeline, this method is responsible to synchronize the + * event occurrence on each lifeline (the greater value will be used).
    + * This synchronization is only done if the end lifeline has already been set. + * + * @param lifeline the message sender + */ + public void autoSetStartLifeline(Lifeline lifeline) { + lifeline.getNewEventOccurrence(); + setStartLifeline(lifeline); + } + + /** + * Set the lifeLine which has receiver the message.
    + * A new EventOccurence will be create on this lifeLine.
    + * SyncMessage must occur at the same event occurrence on both lifeline, this method is responsible to synchronize the + * event occurrence on each lifeline (the greater value will be used).
    + * This synchronization is only done if the start lifeline has already been set. + * + * @param lifeline the message receiver + */ + public void autoSetEndLifeline(Lifeline lifeline) { + lifeline.getNewEventOccurrence(); + setEndLifeline(lifeline); + } + + /** + * Set the lifeLine which has receiver the message.
    + * SyncMessage must occur at the same event occurrence on both lifeline, this method is responsible to synchronize the + * event occurrence on each lifeline (the greater value will be used).
    + * This synchronization is only done if the start lifeline has already been set. + * + * @param lifeline the message receiver + */ + @Override + public void setStartLifeline(Lifeline lifeline) { + super.setStartLifeline(lifeline); + if ((getEndLifeline() == null)) { + setEventOccurrence(getStartLifeline().getEventOccurrence()); + } else { + syncLifelinesEventOccurrence(); + } + } + + /** + * Set the lifeLine which has receiver the message.
    + * SyncMessage must occur at the same event occurrence on both lifelines, this method is responsible to synchronize the + * event occurrence on each lifeline (the greater value will be used).
    + * This synchronization is only done if the start lifeline has already been set. + * + * @param lifeline the message receiver + */ + @Override + public void setEndLifeline(Lifeline lifeline) { + super.setEndLifeline(lifeline); + if ((getStartLifeline() == null)) { + setEventOccurrence(getEndLifeline().getEventOccurrence()); + } else { + syncLifelinesEventOccurrence(); + } + } + + /** + * Set the event occurrence when this message occurs.
    + * + * @param occurrence the event occurrence to assign to this message.
    + * @see Lifeline Lifeline for more event occurence details + */ + @Override + protected void setEventOccurrence(int occurrence) { + setStartOccurrence(occurrence); + setEndOccurrence(occurrence); + } + + /** + * Set the message return associated with this message. + * + * @param message the message return to associate + */ + protected void setMessageReturn(SyncMessageReturn message) { + fMessageReturn = message; + } + + /** + * Returns the syncMessageReturn associated to this syncMessage + * + * @return the message return + */ + public SyncMessageReturn getMessageReturn() { + return fMessageReturn; + } + + /** + * Set the time when the message occurs + * + * @param time the time when the message occurs + * @since 2.0 + */ + public void setTime(ITmfTimestamp time) { + fEventTime = time; + fHasTimeInfo = true; + if (getStartLifeline() != null && getStartLifeline().getFrame() != null) { + getStartLifeline().getFrame().setHasTimeInfo(true); + } else if (getEndLifeline() != null && getEndLifeline().getFrame() != null) { + getEndLifeline().getFrame().setHasTimeInfo(true); + } + } + + /** + * @since 2.0 + */ + @Override + public ITmfTimestamp getEndTime() { + return fEventTime; + } + + /** + * @since 2.0 + */ + @Override + public ITmfTimestamp getStartTime() { + return fEventTime; + } + + @Override + public boolean hasTimeInfo() { + return fHasTimeInfo; + } + + @Override + public void draw(IGC context) { + if (!isVisible()) { + return; + } + + ISDPreferences pref = SDViewPref.getInstance(); + + // Draw it selected? + if (!isSelected()) { + context.setBackground(pref.getBackGroundColor(getColorPrefId())); + context.setForeground(pref.getForeGroundColor(getColorPrefId())); + } + super.draw(context); + } + + @Override + public boolean isVisible(int x, int y, int width, int height) { + if (getY() > y + height + + // take into account the message name drawn above the arrow + Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth()) { + return false; + } + + // UML2 lost/found message visibility special case + // Others visibility cases are perform in the ***common*** case + if ((getEndLifeline() == null && getStartLifeline() != null) || (getEndLifeline() != null && getStartLifeline() == null)) { + if (x + width > getX() + getWidth() && x < getX() + getWidth()) { + return true; + } + } + // ***Common*** syncMessages visibility + return super.isVisible(x, y, width, height); + } + + @Override + public Comparator getComparator() { + return new SortSyncMessageComparator(); + } + + @Override + public String getArrayId() { + return SYNC_MESS_TAG; + } + + @Override + public boolean positiveDistanceToPoint(int x, int y) { + if (getY() > y) { + return true; + } + return false; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/SyncMessageReturn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/SyncMessageReturn.java new file mode 100755 index 0000000000..c3b0f0804c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/core/SyncMessageReturn.java @@ -0,0 +1,112 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.ISDPreferences; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref; + +/** + * The message return graph node implementation.
    + * This class differs on the SynMessage class only on the drawing line style (dashed instead of plain line).
    + * Message return are generally associated to a message. This means, they are connected to the same lifelines than the + * associated message but in the opposite direction and for a different event occurrence.
    + *
    + * WARNING: The association validity is not checked, it is not necessary to provide a valid association, not even needed + * to set an association to drawn a message with a message return style.
    + * + * + * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SyncMessage SyncMessage for usage example + * @version 1.0 + * @author sveyrier + * + */ +public class SyncMessageReturn extends SyncMessage { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The graphNode ID + */ + public static final String SYNC_MESS_RET_TAG = "SyncMessageRet"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The associated message(the message it is the return). + */ + private SyncMessage fMessage = null; + + // ------------------------------------------------------------------------ + // Constractors + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + public SyncMessageReturn() { + setColorPrefId(ISDPreferences.PREF_SYNC_MESS_RET); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + /** + * Set the associated message (the message it is the return).
    + * Setting the association will activate the navigation in the default sequence diagram implementation to the + * message when the user right click on this message return.
    + * + * @param parentMessage the message to associate + */ + public void setMessage(SyncMessage parentMessage) { + fMessage = parentMessage; + fMessage.setMessageReturn(this); + } + + /** + * Returns the syncMessage associated to this SyncMessageReturn + * + * @return the associated message + */ + public SyncMessage getMessage() { + return fMessage; + } + + @Override + public void draw(IGC context) { + if (!isVisible()) { + return; + } + + ISDPreferences pref = SDViewPref.getInstance(); + + int oldStyle = context.getLineStyle(); + // Message return are dashed + context.setLineStyle(context.getLineDotStyle()); + // Draw it selected? + if (!isSelected()) { + context.setBackground(pref.getBackGroundColor(getColorPrefId())); + context.setForeground(pref.getForeGroundColor(getColorPrefId())); + } + super.draw(context); + // restore the context + context.setLineStyle(oldStyle); + } + + @Override + public String getArrayId() { + return SYNC_MESS_RET_TAG; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/Criteria.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/Criteria.java new file mode 100755 index 0000000000..7c2a304f3b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/Criteria.java @@ -0,0 +1,415 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import org.eclipse.jface.dialogs.DialogSettings; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDFilterProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; + +/** + * This class describes the find or filter criteria selected by the user in the find or filter dialog box + * + * @version 1.0 + * @author sveyrier + * @author Bernd Hufmann + */ +public class Criteria { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * Flag whether lifeline is selected or not. + */ + private boolean fLifeLineSelected = false; + /** + * Flag whether synchronous message is selected or not. + */ + private boolean fSyncMessageSelected = false; + /** + * Flag whether synchronous message return is selected or not. + */ + private boolean fSyncMessageReturnSelected = false; + /** + * Flag whether asynchronous message is selected or not. + */ + private boolean fAsyncMessageSelected = false; + /** + * Flag whether asynchronous message return is selected or not. + */ + private boolean fAsyncMessageReturnSelected = false; + /** + * Flag whether case sensitive find is required or not. + */ + private boolean fCaseSenstiveSelected = false; + /** + * Flag whether stop graph node is selected or not. + */ + private boolean fStopSelected = false; + /** + * The find expression. + */ + private String fExpression = null; + /** + * The find pattern as regular expression. + */ + private Pattern pattern = null; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + public Criteria () { + } + + /** + * Copy constructor + * + * @param other Criteria to create new criteria + */ + public Criteria (Criteria other) { + this.fLifeLineSelected = other.fLifeLineSelected; + this.fSyncMessageSelected = other.fSyncMessageSelected; + this.fSyncMessageReturnSelected = other.fSyncMessageReturnSelected; + this.fAsyncMessageSelected = other.fAsyncMessageSelected; + this.fAsyncMessageReturnSelected = other.fAsyncMessageReturnSelected; + this.fCaseSenstiveSelected = other.fCaseSenstiveSelected; + this.fStopSelected = other.fStopSelected; + fExpression = other.fExpression; + updatePattern(); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + /** + * Returns true if the AsyncMessageReturn is selected, false otherwise. + * + * @return true if the AsyncMessageReturn is selected, false otherwise + */ + public boolean isAsyncMessageReturnSelected() { + return fAsyncMessageReturnSelected; + } + + /** + * Returns true if the AsyncMessage is selected, false otherwise. + * + * @return true if the AsyncMessage is selected, false otherwise + */ + public boolean isAsyncMessageSelected() { + return fAsyncMessageSelected; + } + + /** + * Returns the text enter by the user. + * + * @return the expression text + */ + public String getExpression() { + return fExpression; + } + + /** + * Returns the regular expression pattern. + * + * @return the regular expression pattern + */ + public Pattern getPattern() { + return pattern; + } + + /** + * Sets the regular expression pattern. + * + * @param pattern + * The pattern to set + */ + public void setPattern(Pattern pattern) { + this.pattern = pattern; + } + + /** + * Returns true if the LifeLine is selected, false otherwise. + * + * @return true if the LifeLine is selected, false otherwise + */ + public boolean isLifeLineSelected() { + return fLifeLineSelected; + } + + /** + * Returns true if the Stop is selected, false otherwise. + * + * @return true if the Stop is selected, false otherwise + */ + public boolean isStopSelected() { + return fStopSelected; + } + + /** + * Returns true if the SyncMessageReturn is selected, false otherwise. + * + * @return true if the SyncMessageReturn is selected, false otherwise + */ + public boolean isSyncMessageReturnSelected() { + return fSyncMessageReturnSelected; + } + + /** + * Returns true if the SyncMessage is selected, false otherwise. + * + * @return true if the SyncMessage is selected, false otherwise + */ + public boolean isSyncMessageSelected() { + return fSyncMessageSelected; + } + + /** + * Sets the AsyncMessageReturn selection state. + * + * @param b true if selected, false otherwise + */ + public void setAsyncMessageReturnSelected(boolean b) { + fAsyncMessageReturnSelected = b; + } + + /** + * Sets the AsyncMessage selection state. + * + * @param b true if selected, false otherwise + */ + public void setAsyncMessageSelected(boolean b) { + fAsyncMessageSelected = b; + } + + /** + * Sets the text entered by the user and compiles the regular expression. + * + * @param string the text + */ + public void setExpression(String string) { + fExpression = string; + updatePattern(); + } + + /** + * Sets the Stop selection state. + * + * @param b true if selected, false otherwise + */ + public void setLifeLineSelected(boolean b) { + fLifeLineSelected = b; + } + + /** + * Set Stop selection state. + * + * @param b true if selected, false otherwise + */ + public void setStopSelected(boolean b) { + fStopSelected = b; + } + + /** + * Sets the SyncMessageReturn selection state. + * + * @param b true if selected, false otherwise + */ + public void setSyncMessageReturnSelected(boolean b) { + fSyncMessageReturnSelected = b; + } + + /** + * Sets the SyncMessage selection state. + * + * @param b true if selected, false otherwise + */ + public void setSyncMessageSelected(boolean b) { + fSyncMessageSelected = b; + } + + /** + * Returns true if the case sensitive is selected, false otherwise. + * + * @return true if the case sensitive is selected, false otherwise + */ + public boolean isCaseSenstiveSelected() { + return fCaseSenstiveSelected; + } + + /** + * Set case sensitive selection state. + * + * @param b true if selected, false otherwise + */ + public void setCaseSenstiveSelected(boolean b) { + fCaseSenstiveSelected = b; + // Make sure that pattern is set + setExpression(fExpression); + } + + /** + * Compares this criteria with a given criteria. + * + * @param to The criteria to compare + * @return usual comparison result (< 0, 0, > 0) + */ + public boolean compareTo(Criteria to) { + boolean retVal = true; + if (getExpression() != null) { + retVal = getExpression().equals(to.getExpression()); + } else if (to.getExpression() != null) { + retVal = to.getExpression().equals(getExpression()); + } + return retVal && isCaseSenstiveSelected() == to.isCaseSenstiveSelected() && isAsyncMessageReturnSelected() == to.isAsyncMessageReturnSelected() && isAsyncMessageSelected() == to.isAsyncMessageSelected() + && isLifeLineSelected() == to.isLifeLineSelected() && isStopSelected() == to.isStopSelected() && isSyncMessageReturnSelected() == to.isSyncMessageReturnSelected() && isSyncMessageSelected() == to.isSyncMessageSelected(); + } + + /** + * Saves current criteria attributes in the dialog settings. + * + * @param settings The dialog settings + */ + public void save(DialogSettings settings) { + settings.put("expression", getExpression()); //$NON-NLS-1$ + settings.put("isCaseSenstiveSelected", isCaseSenstiveSelected()); //$NON-NLS-1$ + settings.put("isAsyncMessageReturnSelected", isAsyncMessageReturnSelected()); //$NON-NLS-1$ + settings.put("isAsyncMessageSelected", isAsyncMessageSelected()); //$NON-NLS-1$ + settings.put("isLifeLineSelected", isLifeLineSelected()); //$NON-NLS-1$ + settings.put("isStopSelected", isStopSelected()); //$NON-NLS-1$ + settings.put("isSyncMessageReturnSelected", isSyncMessageReturnSelected()); //$NON-NLS-1$ + settings.put("isSyncMessageSelected", isSyncMessageSelected()); //$NON-NLS-1$ + } + + /** + * Loads the criteria with values of the dialog settings. + * + * @param settings The dialog settings + */ + public void load(DialogSettings settings) { + setExpression(settings.get("expression")); //$NON-NLS-1$ + setCaseSenstiveSelected(settings.getBoolean("isCaseSenstiveSelected")); //$NON-NLS-1$ + setAsyncMessageReturnSelected(settings.getBoolean("isAsyncMessageReturnSelected")); //$NON-NLS-1$ + setAsyncMessageSelected(settings.getBoolean("isAsyncMessageSelected")); //$NON-NLS-1$ + setLifeLineSelected(settings.getBoolean("isLifeLineSelected")); //$NON-NLS-1$ + setStopSelected(settings.getBoolean("isStopSelected")); //$NON-NLS-1$ + setSyncMessageReturnSelected(settings.getBoolean("isSyncMessageReturnSelected")); //$NON-NLS-1$ + setSyncMessageSelected(settings.getBoolean("isSyncMessageSelected")); //$NON-NLS-1$ + } + + /** + * Gets the summary of supported graph nodes. + * + * @param provider A filter provider + * @param loaderClassName A class loader + * @return graph node summary + */ + public String getGraphNodeSummary(ISDFilterProvider provider, String loaderClassName) { + ArrayList list = new ArrayList<>(); + + if (provider != null) { + if (isLifeLineSelected()) { + list.add(provider.getNodeName(ISDGraphNodeSupporter.LIFELINE, loaderClassName)); + } + if (isSyncMessageSelected()) { + list.add(provider.getNodeName(ISDGraphNodeSupporter.SYNCMESSAGE, loaderClassName)); + } + if (isSyncMessageReturnSelected()) { + list.add(provider.getNodeName(ISDGraphNodeSupporter.SYNCMESSAGERETURN, loaderClassName)); + } + if (isAsyncMessageSelected()) { + list.add(provider.getNodeName(ISDGraphNodeSupporter.ASYNCMESSAGE, loaderClassName)); + } + if (isAsyncMessageReturnSelected()) { + list.add(provider.getNodeName(ISDGraphNodeSupporter.ASYNCMESSAGERETURN, loaderClassName)); + } + if (isStopSelected()) { + list.add(provider.getNodeName(ISDGraphNodeSupporter.STOP, loaderClassName)); + } + } else { + if (isLifeLineSelected()) { + list.add(Messages.SequenceDiagram_Lifeline); + } + if (isSyncMessageSelected()) { + list.add(Messages.SequenceDiagram_SynchronousMessage); + } + if (isSyncMessageReturnSelected()) { + list.add(Messages.SequenceDiagram_SynchronousMessageReturn); + } + if (isAsyncMessageSelected()) { + list.add(Messages.SequenceDiagram_AsynchronousMessage); + } + if (isAsyncMessageReturnSelected()) { + list.add(Messages.SequenceDiagram_AsynchronousMessageReturn); + } + if (isStopSelected()) { + list.add(Messages.SequenceDiagram_Stop); + } + } + StringBuffer ret = new StringBuffer(); + String prefix = "["; //$NON-NLS-1$ + for (Iterator i = list.iterator(); i.hasNext();) { + String s = i.next(); + ret.append(prefix); + ret.append(s); + prefix = " " + Messages.SequenceDiagram_or + " "; //$NON-NLS-1$ //$NON-NLS-2$ + } + ret.append("]"); //$NON-NLS-1$ + return ret.toString(); + } + + /** + * Matches given string using compiled pattern based on user expression. + * + * @param stringToMatch A string to match + * @return true if string matches expression + */ + public boolean matches(String stringToMatch) { + if (pattern == null) { + return false; + } + return pattern.matcher(stringToMatch).matches(); + } + + /** + * Updates the regular expression pattern based on the expression. + */ + private void updatePattern() { + if (fExpression != null) { + try { + if (fCaseSenstiveSelected) { + pattern = Pattern.compile(fExpression); + } + else { + pattern = Pattern.compile(fExpression, Pattern.CASE_INSENSITIVE); + } + } catch (PatternSyntaxException e) { + pattern = null; + } + } + else { + pattern = null; + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/FilterCriteria.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/FilterCriteria.java new file mode 100755 index 0000000000..91ec6e876c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/FilterCriteria.java @@ -0,0 +1,273 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.jface.dialogs.DialogSettings; + +/** + * A filter criteria is a criteria that can be activated or not, positive or not. + * + * @version 1.0 + * @author sveyrier + * + */ +public class FilterCriteria { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The filter state value for 'active'. + */ + protected static final String ACTIVE = "active"; //$NON-NLS-1$ + /** + * The property value for positive filter. + */ + protected static final String POSITIVE = "positive"; //$NON-NLS-1$ + /** + * The filter loader class name property. + */ + protected static final String LOADERCLASSNAME = "loaderClassName"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The criteria reference. + */ + private Criteria fCriteria; + /** + * Flag whether this criteria is active or not + */ + private boolean fIsActive; + /** + * Flag whether this criteria is for positive filter or not + */ + private boolean fIsPositive; + /** + * The loader class name. + */ + private String fLoaderClassName; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + /** + * Standard constructor + * + * @param criteria A criteria reference + * @param isActive true if filter criteria is active else false + * @param isPositive true for positive filter else false + */ + public FilterCriteria(Criteria criteria, boolean isActive, boolean isPositive) { + this(criteria, isActive, isPositive, null); + } + + /** + * Constructor + * + * @param criteria A criteria reference + * @param isActive true if filter criteria is active else false + * @param isPositive true for positive filter else false + * @param loaderClassName A loader class name + */ + public FilterCriteria(Criteria criteria, boolean isActive, boolean isPositive, String loaderClassName) { + fCriteria = criteria; + fIsActive = isActive; + fIsPositive = isPositive; + fLoaderClassName = loaderClassName; + } + + /** + * Copy Constructor + * @param other FilterCriteria + */ + public FilterCriteria (FilterCriteria other) { + fCriteria = new Criteria(other.fCriteria); + fIsActive = other.fIsActive; + fIsPositive = other.fIsPositive; + fLoaderClassName = other.fLoaderClassName; + } + + /** + * Default constructor + */ + protected FilterCriteria() { + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(super.toString()); + sb.append(':'); + if (fCriteria != null) { + sb.append(" expression=");sb.append(fCriteria.getExpression()); //$NON-NLS-1$ + sb.append(" active=");sb.append(fIsActive); //$NON-NLS-1$ + sb.append(" positive=");sb.append(fIsPositive); //$NON-NLS-1$ + } else { + sb.append("empty criteria"); //$NON-NLS-1$ + } + return sb.toString(); + } + + /** + * Sets a criteria reference. + * @param criteria A criteria reference + */ + public void setCriteria(Criteria criteria) { + fCriteria = criteria; + } + + /** + * Returns the criteria reference. + * + * @return the criteria reference + */ + public Criteria getCriteria() { + return fCriteria; + } + + /** + * Sets the active flag. + * + * @param isActive A active value. + */ + public void setActive(boolean isActive) { + fIsActive = isActive; + } + + /** + * Returns whether filter criteria is active or not. + * + * @return whether filter criteria is active or not. + */ + public boolean isActive() { + return fIsActive; + } + + /** + * Sets filter is for positive filtering or not. + * + * @param isPositive The value to set. + */ + public void setPositive(boolean isPositive) { + fIsPositive = isPositive; + } + + /** + * Returns whether the filter si for positive filtering or not. + * + * @return Returns the positive. + */ + public boolean isPositive() { + return fIsPositive; + } + + /** + * Sets the loader class name for this filter. + * + * @param loaderClassName The loader class name to set + */ + public void setLoaderClassName(String loaderClassName) { + fLoaderClassName = loaderClassName; + } + + /** + * Returns the class loader name. + * + * @return the class loader name. + */ + public String getLoaderClassName() { + return fLoaderClassName; + } + + /** + * Finds a filter criteria within a list of criteria. + * + * @param what The filter to find + * @param list A list of filter criteria + * @return The found filter criteria or null + */ + public static FilterCriteria find(FilterCriteria what, List list) { + if (what != null && list != null) { + try { + for (Iterator i = list.iterator(); i.hasNext();) { + FilterCriteria fc = i.next(); + if (what.compareTo(fc)) { + return fc; + } + } + } catch (Exception e) { + // Silence + } + } + return null; + } + + /** + * Compares this filter criteria with a given criteria. + * + * @param to The filter criteria to compare. + * @return usual comparison result (< 0, 0, > 0) + */ + public boolean compareTo(FilterCriteria to) { + if (isPositive() == to.isPositive() && getCriteria().compareTo(to.getCriteria())) { + if (getLoaderClassName() == null && to.getLoaderClassName() == null) { + return true; + } + if ((getLoaderClassName() != null && to.getLoaderClassName() != null) && getLoaderClassName().equals(to.getLoaderClassName())) { + return true; + } + } + return false; + } + + /** + * Saves current criteria attributes in the dialog settings. + * + * @param settings The dialog settings + */ + public void save(DialogSettings settings) { + settings.put(ACTIVE, isActive()); + settings.put(POSITIVE, isPositive()); + if (getLoaderClassName() != null) { + settings.put(LOADERCLASSNAME, getLoaderClassName()); + } else { + settings.put(LOADERCLASSNAME, ""); //$NON-NLS-1$ + } + if (fCriteria != null) { + fCriteria.save(settings); + } + } + + /** + * Loads the criteria with values of the dialog settings. + * + * @param settings The dialog settings + */ + public void load(DialogSettings settings) { + setActive(settings.getBoolean(ACTIVE)); + setPositive(settings.getBoolean(POSITIVE)); + String loaderClassName = settings.get(LOADERCLASSNAME); + setLoaderClassName(loaderClassName != null && loaderClassName.length() > 0 ? loaderClassName : null); + if (fCriteria != null) { + fCriteria.load(settings); + } + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/FilterListDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/FilterListDialog.java new file mode 100755 index 0000000000..a905c391b6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/FilterListDialog.java @@ -0,0 +1,518 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.DialogSettings; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.RowData; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDFilterProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; +import org.eclipse.ui.IViewPart; + +/** + * This is the filters list dialog.
    + * It is associated to an SDView and to a ISDFilterProvider.
    + * + * @version 1.0 + * @author sveyrier + */ +public class FilterListDialog extends Dialog { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * Filter list criteria property name + */ + protected static final String FILTERS_LIST_CRITERIA = "filtersListsCriteria"; //$NON-NLS-1$ + /** + * Filter list size property name + */ + protected static final String FILTERS_LIST_SIZE = "filtersListSize"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The viewer and provided are kept here as attributes + */ + private final IViewPart fViewer; + /** + * The filter provider implementation + */ + private final ISDFilterProvider fProvider; + /** + * The filters are the result of editing this list + */ + private List fFilters; + /** + * The add button. + */ + private Button fAdd; + /** + * The remove button. + */ + private Button fRemove; + /** + * The edit button. + */ + private Button fEdit; + /** + * The table with list of filters. + */ + private Table fTable; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Standard constructor + * + * @param view The view reference + * @param loader The filter provider implementation + */ + public FilterListDialog(IViewPart view, ISDFilterProvider loader) { + super(view.getSite().getShell()); + fViewer = view; + fProvider = loader; + fFilters = null; + setShellStyle(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + /** + * Adds a criteria to the table + * + * @param criteria A criteria to add + * @param checked A flag whether criteria is checked (selected) or not + * @param positive A flag whether criteria is for positive filter or not + * @param loaderClassName A loader class name for the filters + */ + protected void addCriteria(Criteria criteria, boolean checked, boolean positive, String loaderClassName) { + CriteriaTableItem cti = new CriteriaTableItem(fTable, checked, positive, loaderClassName); + cti.setCriteria(criteria); + } + + /** + * Replaces a selected criteria with a new criteria. + * + * @param newCriteria A new criteria. + */ + protected void replaceSelectedCriteria(Criteria newCriteria) { + CriteriaTableItem cti = (CriteriaTableItem) fTable.getSelection()[0].getData(); + cti.setCriteria(newCriteria); + } + + /** + * Handles table selection count. + */ + protected void handleTableSelectionCount() { + int count = fTable.getSelectionCount(); + fEdit.setEnabled(count == 1); + fRemove.setEnabled(count > 0); + } + + @Override + public Control createDialogArea(Composite parent) { + + Group ret = new Group(parent, SWT.NONE); + ret.setText(Messages.SequenceDiagram_ListOfHideDisplayPatterns); + RowLayout rowLayout = new RowLayout(); + rowLayout.wrap = false; + rowLayout.pack = true; + rowLayout.justify = false; + rowLayout.type = SWT.HORIZONTAL; + rowLayout.marginLeft = 4; + rowLayout.marginTop = 4; + rowLayout.marginRight = 4; + rowLayout.marginBottom = 4; + rowLayout.spacing = 8; + ret.setLayout(rowLayout); + + fTable = new Table(ret, SWT.MULTI | SWT.CHECK); + fTable.setLayoutData(new RowData(220, 84)); + fTable.setHeaderVisible(false); + fTable.addSelectionListener(new SelectionListener() { + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + int count = fTable.getSelectionCount(); + if (count == 1) { + Criteria criteria = openFilterDialog(((CriteriaTableItem) fTable.getSelection()[0].getData()).getCriteria(), Messages.SequenceDiagram_Update); + if (criteria != null) { + replaceSelectedCriteria(criteria); + } + } + } + + @Override + public void widgetSelected(SelectionEvent e) { + handleTableSelectionCount(); + } + }); + if (fFilters != null) { + for (Iterator i = fFilters.iterator(); i.hasNext();) { + FilterCriteria filterCriteria = i.next(); + addCriteria(filterCriteria.getCriteria(), filterCriteria.isActive(), filterCriteria.isPositive(), filterCriteria.getLoaderClassName()); + } + } + + Composite commands = new Composite(ret, SWT.NONE); + RowLayout rowLayoutCommands = new RowLayout(); + rowLayoutCommands.wrap = false; + rowLayoutCommands.pack = false; + rowLayoutCommands.justify = true; + rowLayoutCommands.type = SWT.VERTICAL; + rowLayoutCommands.marginLeft = 0; + rowLayoutCommands.marginTop = 4; + rowLayoutCommands.marginRight = 0; + rowLayoutCommands.marginBottom = 4; + rowLayoutCommands.spacing = 8; + commands.setLayout(rowLayoutCommands); + fAdd = new Button(commands, SWT.NONE); + fAdd.setText(Messages.SequenceDiagram_Add); + fAdd.addSelectionListener(new SelectionListener() { + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + // Nothing to do + } + + @Override + public void widgetSelected(SelectionEvent e) { + Criteria init = new Criteria(); + Criteria c = openFilterDialog(init, Messages.SequenceDiagram_Create); + if (c != null) { + addCriteria(c, true, false, null); + } + } + }); + + fEdit = new Button(commands, SWT.NONE); + fEdit.setText(Messages.SequenceDiagram_EditIt); + fEdit.addSelectionListener(new SelectionListener() { + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + // Nothing to do + } + + @Override + public void widgetSelected(SelectionEvent e) { + Criteria c = openFilterDialog(((CriteriaTableItem) fTable.getSelection()[0].getData()).getCriteria(), Messages.SequenceDiagram_Update); + if (c != null) { + replaceSelectedCriteria(c); + } + } + }); + fEdit.setEnabled(false); + + fRemove = new Button(commands, SWT.NONE); + fRemove.setText(Messages.SequenceDiagram_Remove); + fRemove.addSelectionListener(new SelectionListener() { + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + // Nothing to do + } + + @Override + public void widgetSelected(SelectionEvent e) { + fTable.remove(fTable.getSelectionIndices()); + handleTableSelectionCount(); + } + }); + fRemove.setEnabled(false); + + getShell().setText(Messages.SequenceDiagram_SequenceDiagramHidePatterns); + /* + * for (int i=0;i 0) { + fFilters = new ArrayList<>(); + } else { + fFilters = null; + } + for (int i = 0; i < fTable.getItemCount(); i++) { + TableItem item = fTable.getItem(i); + CriteriaTableItem cti = (CriteriaTableItem) item.getData(); + FilterCriteria fc = new FilterCriteria(cti.getCriteria(), item.getChecked(), cti.isPositive(), cti.getLoaderClassName()); + FilterCriteria efc = FilterCriteria.find(fc, fFilters); + if (efc == null) { + fFilters.add(fc); + } else { + efc.setActive(efc.isActive() || fc.isActive()); + } + } + super.close(); + fProvider.filter(fFilters); + saveFiltersCriteria(fFilters); + } + + /** + * Sets the list of filters. + * + * @param filters The list of filters to set. + */ + public void setFilters(List filters) { + fFilters = filters; + } + + /** + * Returns the filters list after editing. + * + * @return the filters list after editing + */ + public List getFilters() { + return fFilters; + } + + /** + * Loads the filter criteria from global filters which are saved in the dialog settings. + */ + protected void loadFiltersCriteria() { + List globalFilters = getGlobalFilters(); + for (Iterator i = globalFilters.iterator(); i.hasNext();) { + FilterCriteria filterCriteria = i.next(); + addCriteria(filterCriteria.getCriteria(), filterCriteria.isActive(), filterCriteria.isPositive(), filterCriteria.getLoaderClassName()); + } + } + + /** + * Returns the global filters which are saved in the dialog settings.. + * + * @return the saved global filters + */ + + public static List getGlobalFilters() { + DialogSettings settings = (DialogSettings) Activator.getDefault().getDialogSettings().getSection(FILTERS_LIST_CRITERIA); + int i = 0; + DialogSettings section = null; + int size = 0; + List globalFilters = new ArrayList<>(); + if (settings != null) { + try { + size = settings.getInt(FILTERS_LIST_SIZE); + } catch (NumberFormatException e) { + // This is not a problem + size = 0; + } + section = (DialogSettings) settings.getSection(FILTERS_LIST_CRITERIA + i); + + while ((section != null) && (i < size)) { + FilterCriteria criteria = new FilterCriteria(); + criteria.setCriteria(new Criteria()); + criteria.load(section); + globalFilters.add(criteria); + section = (DialogSettings) settings.getSection(FILTERS_LIST_CRITERIA + (++i)); + } + } + + return globalFilters; + } + + /** + * Saves the filter criteria in the dialog settings. + * + * @param globalFilters A list of filters to save. + */ + public static void saveFiltersCriteria(List globalFilters) { + DialogSettings settings = (DialogSettings) Activator.getDefault().getDialogSettings(); + DialogSettings section = (DialogSettings) settings.getSection(FILTERS_LIST_CRITERIA); + if (section == null) { + section = (DialogSettings) settings.addNewSection(FILTERS_LIST_CRITERIA); + } + + if (globalFilters == null) { + section.put(FILTERS_LIST_SIZE, 0); + return; + } + + section.put(FILTERS_LIST_SIZE, globalFilters.size()); + + FilterCriteria criteria; + + for (int j = 0; j < globalFilters.size(); j++) { + if (globalFilters.get(j) == null) { + return; + } + + criteria = globalFilters.get(j); + DialogSettings subSection = (DialogSettings) section.getSection(FILTERS_LIST_CRITERIA + j); + + if (subSection == null) { + subSection = (DialogSettings) section.addNewSection(FILTERS_LIST_CRITERIA + j); + } + criteria.save(subSection); + } + } + + /** + * Deactivates the saved global filters. + */ + public static void deactivateSavedGlobalFilters() { + // Deactivate all filters + List filters = getGlobalFilters(); + for(FilterCriteria criteria : filters) { + criteria.setActive(false); + } + // Save settings + FilterListDialog.saveFiltersCriteria(filters); + } + + // ------------------------------------------------------------------------ + // Helper classes + // ------------------------------------------------------------------------ + /** + * A class to map TableItems that can be toggled active or inactive and Criteria + */ + protected class CriteriaTableItem { + + /** + * The criteria reference + */ + protected Criteria fCriteria; + /** + * The "positive" value. + */ + protected boolean fIsPositive; + /** + * The loader class name + */ + protected String fLoaderClassName; + /** + * The actual table item. + */ + protected TableItem fTableItem; + + /** + * Constructor + * + * @param parent The parent table + * @param isActive true if filter criteria is active else false + * @param isPositive true for positive filter else false + * @param loaderClassName The loader class name + */ + public CriteriaTableItem(Table parent, boolean isActive, boolean isPositive, String loaderClassName) { + fTableItem = new TableItem(parent, SWT.NONE); + fTableItem.setData(this); + fTableItem.setChecked(isActive); + fIsPositive = isPositive; + fLoaderClassName = loaderClassName; + } + + /** + * Constructor + * + * @param parent The parent table + * @param isActive true if filter criteria is active else false + * @param isPositive true for positive filter else false + * @param loaderClassName The loader class name + * @param index The table item index + */ + public CriteriaTableItem(Table parent, boolean isActive, boolean isPositive, String loaderClassName, int index) { + fTableItem = new TableItem(parent, SWT.NONE, index); + fTableItem.setChecked(isActive); + fIsPositive = isPositive; + fLoaderClassName = loaderClassName; + } + + /** + * Sets the criteria. + * + * @param criteria The criteria to set + */ + public void setCriteria(Criteria criteria) { + fCriteria = criteria; + fTableItem.setText((fIsPositive ? Messages.SequenceDiagram_display : Messages.SequenceDiagram_hide) + " " + fCriteria.getExpression() + " " + fCriteria.getGraphNodeSummary(fProvider, fLoaderClassName)); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * Returns the criteria. + * @return the criteria + */ + public Criteria getCriteria() { + return fCriteria; + } + + /** + * Returns whether positive filtering is active or not. + * + * @return true for positive filter else false + */ + public boolean isPositive() { + return fIsPositive; + } + + /** + * Returns the loader class name. + * + * @return the loader class name + */ + public String getLoaderClassName() { + return fLoaderClassName; + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/MinMaxDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/MinMaxDialog.java new file mode 100755 index 0000000000..4847b1d41e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/MinMaxDialog.java @@ -0,0 +1,190 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; + +/** + * Dialog box for entering minimum and maximum time range for time compression bar. + * + * @version 1.0 + * @author sveyrier + * @author Bernd Hufmann + * + */ +public class MinMaxDialog extends Dialog { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * Text field for minimum. + */ + private Text fMinText; + /** + * Text field for maximum. + */ + private Text fMaxText; + /** + * Text field for scale. + */ + private Text fScaleText; + /** + * Text field for precision. + */ + private Text fPrecisionText; + /** + * The sequence diagram widget reference. + */ + private SDWidget fSdWidget; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + /** + * Standard constructor. + * @param shell The shell + * @param viewer The sequence diagram widget reference. + */ + public MinMaxDialog(Shell shell, SDWidget viewer) { + super(shell); + fSdWidget = viewer; + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + /** + * Method to create a grid data base on horizontal span. + * @param span The horizontal span + * @return a grid data object + */ + protected GridData newGridData(int span) { + GridData data = new GridData(GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL); + data.horizontalSpan = span; + return data; + } + + @Override + protected Control createDialogArea(Composite p) { + p.getShell().setText(Messages.SequenceDiagram_TimeCompressionBarConfig); + Composite parent = (Composite) super.createDialogArea(p); + + GridLayout parentLayout = new GridLayout(); + parentLayout.numColumns = 6; + parent.setLayout(parentLayout); + + Group g1 = new Group(parent, SWT.SHADOW_NONE); + g1.setLayoutData(newGridData(3)); + GridLayout g1layout = new GridLayout(); + g1layout.numColumns = 3; + g1.setLayout(g1layout); + + Label minLabel = new Label(g1, SWT.RADIO); + minLabel.setText(Messages.SequenceDiagram_MinTime); + minLabel.setLayoutData(newGridData(1)); + + fMinText = new Text(g1, SWT.SINGLE | SWT.BORDER); + fMinText.setLayoutData(newGridData(2)); + fMinText.setText(String.valueOf(fSdWidget.getFrame().getMinTime().getValue())); + + Label maxLabel = new Label(g1, SWT.RADIO); + maxLabel.setText(Messages.SequenceDiagram_MaxTime); + maxLabel.setLayoutData(newGridData(1)); + + fMaxText = new Text(g1, SWT.SINGLE | SWT.BORDER); + fMaxText.setLayoutData(newGridData(2)); + fMaxText.setText(String.valueOf(fSdWidget.getFrame().getMaxTime().getValue())); + + Label scaleLabel = new Label(g1, SWT.RADIO); + scaleLabel.setText(Messages.SequenceDiagram_Scale); + scaleLabel.setLayoutData(newGridData(1)); + + fScaleText = new Text(g1, SWT.SINGLE | SWT.BORDER); + fScaleText.setLayoutData(newGridData(2)); + fScaleText.setText(String.valueOf(fSdWidget.getFrame().getMinTime().getScale())); + + + Label precisionLabel = new Label(g1, SWT.RADIO); + precisionLabel.setText(Messages.SequenceDiagram_Precision); + precisionLabel.setLayoutData(newGridData(1)); + + fPrecisionText = new Text(g1, SWT.SINGLE | SWT.BORDER); + fPrecisionText.setLayoutData(newGridData(2)); + fPrecisionText.setText(String.valueOf(fSdWidget.getFrame().getMinTime().getPrecision())); + + return parent; + } + + @Override + protected void okPressed() { + long min = 0; + long max = 0; + int scale = 0; + int precision = 0; + try { + min = Long.parseLong(fMinText.getText()); + max = Long.parseLong(fMaxText.getText()); + scale = Integer.parseInt(fScaleText.getText()); + precision = Integer.parseInt(fPrecisionText.getText()); + + fSdWidget.getFrame().setMax(new TmfTimestamp(max, scale, precision)); + fSdWidget.getFrame().setMin(new TmfTimestamp(min, scale, precision)); + + fSdWidget.redraw(); + + super.okPressed(); + } catch (Exception e) { + MessageDialog.openError(getShell(), Messages.SequenceDiagram_Error, Messages.SequenceDiagram_InvalidRange); + } + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + super.createButtonsForButtonBar(parent); + createButton(parent, IDialogConstants.CLIENT_ID, Messages.SequenceDiagram_Default, false); + getButton(IDialogConstants.CLIENT_ID).addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + fSdWidget.getFrame().resetCustomMinMax(); + fMinText.setText(String.valueOf(fSdWidget.getFrame().getMinTime().getValue())); + fMaxText.setText(String.valueOf(fSdWidget.getFrame().getMaxTime().getValue())); + fScaleText.setText(String.valueOf(fSdWidget.getFrame().getMinTime().getScale())); + fPrecisionText.setText(String.valueOf(fSdWidget.getFrame().getMinTime().getPrecision())); + fMaxText.getParent().layout(true); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + // nothing to do + } + }); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/PagesDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/PagesDialog.java new file mode 100755 index 0000000000..29c8b737db --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/PagesDialog.java @@ -0,0 +1,204 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs; + +import java.text.MessageFormat; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDAdvancedPagingProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; +import org.eclipse.ui.IViewPart; + +/** + * Class implementation of the pages dialog.
    + * + * It is associated to an SDView and to a ISDAdvancedPagingProvider.
    + * + * @version 1.0 + * @author sveyrier + */ +public class PagesDialog extends Dialog { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * viewer and provided are kept here as attributes + */ + private ISDAdvancedPagingProvider fProvider = null; + + /** Current page */ + private TextArea fCurrentPage; + + /** Comment label */ + private Label fTotalPageComment; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Standard constructor + * + * @param view The sequence diagram view reference + * @param provider The paging provider reference + */ + public PagesDialog(IViewPart view, ISDAdvancedPagingProvider provider) { + super(view.getSite().getShell()); + fProvider = provider; + setShellStyle(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public Control createDialogArea(Composite parent) { + + Group ret = new Group(parent, SWT.NONE); + GridData data = new GridData(); + data.grabExcessHorizontalSpace = true; + data.horizontalAlignment = GridData.FILL; + ret.setLayoutData(data); + ret.setText(Messages.SequenceDiagram_PageNavigation); + + FillLayout fillLayout = new FillLayout(SWT.VERTICAL); + ret.setLayout(fillLayout); + + Label label = new Label(ret, SWT.NONE); + label.setText(Messages.SequenceDiagram_CurrentPage); + + fCurrentPage = new TextArea(ret); + fCurrentPage.setBounds(1, fProvider.pagesCount()); + fCurrentPage.setValue(fProvider.currentPage() + 1); + + fTotalPageComment = new Label(ret, SWT.NONE); + fTotalPageComment.setAlignment(SWT.RIGHT); + + updateComments(); + + getShell().setText(Messages.SequenceDiagram_SequenceDiagramPages); + return ret; + } + + @Override + public void okPressed() { + int currentPageValue = fCurrentPage.getValue() - 1; + super.close(); + fProvider.pageNumberChanged(currentPageValue); + } + + /** + * Updates the comments texts. + */ + private void updateComments() { + int pages = Math.max(0, fProvider.pagesCount()); + StringBuffer totalPageCommentText = new StringBuffer(); + totalPageCommentText.append(Messages.SequenceDiagram_Total); + totalPageCommentText.append(pages); + totalPageCommentText.append(" "); //$NON-NLS-1$ + if (pages == 0) { + totalPageCommentText.append(Messages.SequenceDiagram_pages); + } else if (pages == 1) { + totalPageCommentText.append(Messages.SequenceDiagram_page); + } else { + totalPageCommentText.append(Messages.SequenceDiagram_pages); + } + fTotalPageComment.setText(totalPageCommentText.toString()); + } + + + // ------------------------------------------------------------------------ + // Helper classes + // ------------------------------------------------------------------------ + + /** + * This is a Text Control that accepts only digits and ensures that bounds are respected + */ + protected static class TextArea { + /** + * The text field. + */ + private Text fText; + /** + * The minimum page value + */ + private int fMin; + /** + * The maximum page value + */ + private int fMax; + + /** + * Constructor + * + * @param parent The paren composite + */ + public TextArea(Composite parent) { + fText = new Text(parent, SWT.SINGLE | SWT.BORDER | SWT.RIGHT); + fText.setTextLimit(10); + } + + /** + * Sets the page value. + * + * @param page The page value + */ + public void setValue(int page) { + int value = Math.max(fMin, Math.min(fMax, page)); + fText.setText(Integer.toString(value)); + } + + /** + * Returns the page value. + * + * @return the page value + */ + public int getValue() { + int res; + try { + res = Integer.parseInt(fText.getText()); + } catch (Exception e) { + // ignored + res = 0; + } + return Math.max(fMin, Math.min(fMax, res)); + } + + /** + * Sets the minimum and maximum page values. + * + * @param min A minimum page value + * @param max A maximum page value + */ + public void setBounds(int min, int max) { + fMin = Math.max(0, min); + fMax = Math.max(fMin, max); + Integer tab[] = new Integer[2]; + tab[0] = Integer.valueOf(fMin); + tab[1] = Integer.valueOf(fMax); + fText.setToolTipText(MessageFormat.format(Messages.SequenceDiagram_IsInBetween, (Object[]) tab)); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/SDPrintDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/SDPrintDialog.java new file mode 100755 index 0000000000..b5378652ee --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/SDPrintDialog.java @@ -0,0 +1,174 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; + +/** + * This class implements a dialog box for collecting printing information. + * + * @version 1.0 + * @author sveyrier + */ +public class SDPrintDialog extends Dialog { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The sequence dialog widget reference. + */ + private SDWidget fSdView; + /** + * Sequence dialog print dialog UI + */ + private SDPrintDialogUI fDialogUI; + /** + * Error message to display. + */ + private String fErrorMessage = null; + /** + * A message label. + */ + private Label fMessageLabel = null; + /** + * Flag whether the page is complete or not + */ + private boolean fIsPageComplete = true; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Standard constructor + * + * @param shell Shell reference + * @param viewer Sequence diagram widget reference + */ + public SDPrintDialog(Shell shell, SDWidget viewer) { + super(shell); + fSdView = viewer; + + fDialogUI = new SDPrintDialogUI(shell, fSdView); + fDialogUI.setParentDialog(this); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + protected Control createDialogArea(Composite p) { + p.getShell().setText(Messages.SequenceDiagram_Print); + Composite parent = (Composite) super.createDialogArea(p); + + fDialogUI.createDialogArea(parent); + + fMessageLabel = new Label(parent, SWT.NONE); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); + gridData.horizontalSpan = 6; + fMessageLabel.setLayoutData(gridData); + setErrorMessage(fErrorMessage); + + return parent; + } + + @Override + protected void okPressed() { + + if (fDialogUI.okPressed()) { + super.okPressed(); + } + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + + super.createButtonsForButtonBar(parent); + createButton(parent, IDialogConstants.CLIENT_ID, Messages.SequenceDiagram_Printer, false); + + getButton(IDialogConstants.CLIENT_ID).addSelectionListener(new SelectionListener() { + @Override + public void widgetSelected(SelectionEvent e) { + fDialogUI.printButtonSelected(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + + updateButtons(); + } + + /** + * @return the dialog UI + */ + public SDPrintDialogUI getDialogUI() { + return fDialogUI; + } + + /** + * Sets the error message. + * + * @param message error message to set + */ + public void setErrorMessage(String message) { + fErrorMessage = message; + if (fMessageLabel != null) { + if (fErrorMessage == null) { + fMessageLabel.setText(""); //$NON-NLS-1$ + } else { + fMessageLabel.setText(fErrorMessage); + } + } + } + + /** + * Sets the page complete flag. + * @param complete whether page is complete or not + */ + public void setPageComplete(boolean complete) { + fIsPageComplete = complete; + updateButtons(); + } + + /** + * Udates the button enable state. + */ + public void updateButtons() { + Button okButton = getButton(IDialogConstants.OK_ID); + if (fIsPageComplete) { + if (okButton != null) { + okButton.setEnabled(true); + } + } else { + if (okButton != null) { + okButton.setEnabled(false); + } + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/SDPrintDialogUI.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/SDPrintDialogUI.java new file mode 100755 index 0000000000..8780c8d243 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/SDPrintDialogUI.java @@ -0,0 +1,1424 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs; + +import java.text.MessageFormat; +import java.util.Arrays; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.TraverseEvent; +import org.eclipse.swt.events.TraverseListener; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.printing.PrintDialog; +import org.eclipse.swt.printing.Printer; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.DiagramToolTip; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.NGC; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; + +/** + * The class implements the actual print dialog UI for collecting printing data. + * + * @version 1.0 + * @author sveyrier + */ +public class SDPrintDialogUI { + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The set horizontal pages number. + */ + private Button fSetHPagesNumber; + /** + * The set vertical pages number. + */ + private Button fSetVPagesNumber; + /** + * Flag whether to use current zoom or not. + */ + private Button fUseCurrentZoom; + /** + * Flag whether to print all pages or not + */ + private Button fAllPages; + /** + * Flag whether to print current page only + */ + private Button fCurrentPage; + /** + * Button to select a page list. + */ + private Button fPageList; + /** + * Button to select a page range. + */ + private Button fPageRange; + /** + * Text field to enter from page. + */ + private Text fFromPage; + /** + * Text field to enter to page. + */ + private Text fToPage; + /** + * The sequence diagram widget reference. + */ + private SDWidget fSdView; + /** + * Text field for number of horizontal pages + */ + private Text fHorPagesNum; + /** + * Text field for number of vertical pages + */ + private Text fVertPagesNum; + /** + * Text field for toal number of pages + */ + private Text fTotalPages; + /** + * A modify listener implementation to handle modifications. + */ + private ModifyListener fModifyListener; + /** + * A selection listener implementation to handle selections. + */ + private SelectionListener fSelectionListener; + /** + * Local canvas displaying sequence diagram overview. + */ + private LocalSD fOverviewCanvas; + /** + * Number of pages + */ + private int fNbPages = 0; + /** + * Number of selected pages. + */ + private int fPageNum = -1; + /** + * Number of first page. + */ + private int fFirstPage = -1; + /** + * List of pages to print. + */ + private int fPagesList[]; + + /** + * Value for dividing the sequence diagram into pages + */ + private float fStepX; + + /** + * Value for dividing the sequence diagram into pages + */ + private float fStepY; + + /** + * Value for dividing the sequence diagram into pages + */ + private float sTX; + + /** + * Value for dividing the sequence diagram into pages + */ + private float sTY; + + /** + * Page which to print from. + */ + private int fFrom; + /** + * Page which to print to. + */ + private int fTo; + /** + * Flag for enabling multi-selection. + */ + private boolean fMultiSelection = false; + /** + * Flag for enabling area selection. + */ + private boolean fAreaSelection = false; + /** + * Flag for printing all. + */ + private boolean fPrintAll; + /** + * Flag for printing current page only. + */ + private boolean fPrintCurrent; + /** + * Flag for printing a selection of pages. + */ + private boolean fPrintSelection; + /** + * Flag for printing a range of pages. + */ + private boolean fPrintRange; + /** + * Number of selected rows + */ + private int fNbRows; + /** + * Number of selected lines + */ + private int fNbLines; + /** + * The zoom factor. + */ + private float fZoomFactor; + /** + * The printer data reference. + */ + private PrinterData fPrinterData; + /** + * The diagram tooltip to show if necessary. + */ + private DiagramToolTip fToolTip = null; + /** + * Label for current selection. + */ + private Label fCurrentSelection; + /** + * The shell reference. + */ + private Shell fShell; + /** + * Button to open printer dialog from OS. + */ + private Button fPrinterDialog; + /** + * Flag for showing print button. + */ + private boolean fShowPrintButton; + /** + * Test value + */ + private int fTest = 3; + /** + * Parent wizard page if used as wizard + */ + private WizardPage fParentWizardPage = null; + /** + * Reference to parent print dialog. + */ + private SDPrintDialog fParentDialog = null; + + // ------------------------------------------------------------------------ + // Helper Class + // ------------------------------------------------------------------------ + /** + * Local sequence diagram widget used to display overview of sequence diagram to print. + * @version 1.0 + */ + private class LocalSD extends SDWidget { + + /** + * Constructor + * @param c Parent composite + * @param s Style bits + */ + public LocalSD(Composite c, int s) { + super(c, s); + } + + @Override + public int getContentsHeight() { + if (fSdView.getContentsHeight() > fSdView.getContentsHeight()) { + return (int) (fSdView.getVisibleHeight() / (float) fTest / fSdView.getZoomValue()); + } + return super.getContentsHeight(); + } + + @Override + public int getContentsWidth() { + if (fSdView.getVisibleWidth() > fSdView.getContentsWidth()) { + return (int) (fSdView.getVisibleWidth() / (float) fTest / fSdView.getZoomValue()); + } + return super.getContentsWidth(); + } + + @Override + protected void contentsMouseHover(MouseEvent event) { + } + + /** + * Creates page selection images. + * + * @param img - Overview image + * @param width -The width value + * @param stepX - Step X + * @param height - Height value + * @param stepY - Step Y + * @return new image + */ + protected Image createPagesSelectionImages(Image img, int width, float stepX, int height, float stepY) { + + Image over = new Image(super.getShell().getDisplay(), img.getImageData()); + + for (int pageIndex = 0; pageIndex < fPagesList.length; pageIndex++) { + + int pageNum = fPagesList[pageIndex]; + + if (getPagesForSelection() > 0 && pageNum > 0) { + int line = pageNum / getNbRow(); + int row = pageNum % getNbRow(); + if (row != 0) { + line++; + } else { + row = getNbRow(); + } + + line--; + row--; + + Image toDel = over; + if (fOverviewCanvas.isFocusControl()) { + over = new Image(super.getShell().getDisplay(), drawRegionSelected(toDel, new Rectangle(contentsToViewX((int) (row * stepX * fOverviewCanvas.getZoomValue())), contentsToViewY((int) (line * stepY * fOverviewCanvas.getZoomValue())), + ((int) (stepX * fOverviewCanvas.getZoomValue())), ((int) (stepY * fOverviewCanvas.getZoomValue()))), new RGB(0, 0, 128))); + } else { + over = new Image(super.getShell().getDisplay(), drawRegionSelected(toDel, new Rectangle(contentsToViewX((int) (row * stepX * fOverviewCanvas.getZoomValue())), contentsToViewY((int) (line * stepY * fOverviewCanvas.getZoomValue())), + ((int) (stepX * fOverviewCanvas.getZoomValue())), ((int) (stepY * fOverviewCanvas.getZoomValue()))), new RGB(221, 208, 200))); + } + toDel.dispose(); + } + } + + Arrays.sort(fPagesList); + int pos = Arrays.binarySearch(fPagesList, fPageNum); + if ((pos < 0) && (getPagesForSelection() > 0 && fPageNum > 0)) { + int line = fPageNum / getNbRow(); + int row = fPageNum % getNbRow(); + if (row != 0) { + line++; + } else { + row = getNbRow(); + } + + line--; + row--; + + Image toDel = over; + over = new Image(super.getShell().getDisplay(), drawRegionSelected(toDel, new Rectangle(contentsToViewX((int) (row * stepX * fOverviewCanvas.getZoomValue())), contentsToViewY((int) (line * stepY * fOverviewCanvas.getZoomValue())), + ((int) (stepX * fOverviewCanvas.getZoomValue())), ((int) (stepY * fOverviewCanvas.getZoomValue()))), new RGB(221, 208, 200))); + toDel.dispose(); + } + + GC imGC2 = new GC(over); + imGC2.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); + NGC imGC = new NGC(fOverviewCanvas, imGC2); + for (int i = 0, x = 0; x <= width && stepX > 0; i++, x = (int) (i * stepX)) { + imGC.drawLine(x, 0, x, height); + } + + for (int j = 0, y = 0; y <= height && stepY > 0; j++, y = (int) (j * stepY)) { + imGC.drawLine(0, y, width, y); + } + + imGC2.dispose(); + imGC.dispose(); + return over; + } + + @Override + protected void drawContents(GC gc, int clipx, int clipy, int clipw, int cliph) { + + Image dbuffer = getDrawBuffer(); + computeStepXY(); + Image d; + + int lw = (int) (getContentsWidth() / getZoomValue()); + if (getContentsWidth() < getVisibleWidth()) { + lw = (int) (getVisibleWidth() / getZoomValue()); + } + + int lh = (int) (getContentsHeight() / getZoomValue()); + if (getContentsHeight() < getVisibleHeight()) { + lh = (int) (getVisibleHeight() / getZoomValue()); + } + d = createPagesSelectionImages(dbuffer, lw, fStepX, lh, fStepY); + + if (!isEnabled()) { + Image toDel = d; + d = new Image(super.getShell().getDisplay(), drawRegionSelected(d, new Rectangle(0, 0, lw, lh), new RGB(221, 208, 200))); + toDel.dispose(); + } + + Rectangle area = getClientArea(); + int w = d.getBounds().width; + int h = d.getBounds().height; + gc.drawImage(d, 0, 0, w, h, 0, 0, area.width, area.height); + + fTotalPages.setText(Integer.valueOf(maxNumOfPages()).toString()); + displayPageNum(); + dbuffer.dispose(); + d.dispose(); + gc.dispose(); + } + + @Override + protected void keyPressedEvent(KeyEvent e) { + if (e.keyCode == SWT.CTRL) { + fMultiSelection = true; + } + if (e.keyCode == SWT.SHIFT) { + fAreaSelection = true; + } + if (e.keyCode == SWT.ARROW_DOWN) { + if (fPageNum + getNbRow() <= maxNumOfPages()) { + fPageNum += getNbRow(); + } + int line = fPageNum / getNbRow(); + int row = fPageNum % getNbRow(); + if (row == 0) { + line--; + } + if ((line + 1) * fStepY > (fOverviewCanvas.getContentsY() + fOverviewCanvas.getVisibleHeight()) / fOverviewCanvas.getZoomValue()) { + fOverviewCanvas.scrollBy(0, (int) (fStepY * fOverviewCanvas.getZoomValue())); + } + } + if (e.keyCode == SWT.ARROW_UP) { + if (fPageNum - getNbRow() > 0) { + fPageNum -= getNbRow(); + } + int line = fPageNum / getNbRow(); + int row = fPageNum % getNbRow(); + if (row == 0) { + line--; + } + if ((line) * fStepY <= fOverviewCanvas.getContentsY() / fOverviewCanvas.getZoomValue()) { + fOverviewCanvas.scrollBy(0, -(int) (fStepY * fOverviewCanvas.getZoomValue())); + } + } + if (e.keyCode == SWT.ARROW_LEFT) { + if ((fPageNum - 2) / getNbRow() == (fPageNum - 1) / getNbRow() && fPageNum > 1) { + fPageNum--; + } + int row = fPageNum % getNbRow(); + if ((row - 1) * fStepX < (fOverviewCanvas.getContentsX()) / fOverviewCanvas.getZoomValue()) { + fOverviewCanvas.scrollBy(-(int) (fStepX * fOverviewCanvas.getZoomValue()), 0); + } + } + if (e.keyCode == SWT.ARROW_RIGHT) { + if ((fPageNum - 1) / getNbRow() == fPageNum / getNbRow()) { + fPageNum++; + } + int row = fPageNum % getNbRow(); + if (row == 0) { + row = getNbRow(); + } + if ((row) * fStepX > (fOverviewCanvas.getContentsX() + fOverviewCanvas.getVisibleWidth()) / fOverviewCanvas.getZoomValue()) { + fOverviewCanvas.scrollBy((int) (fStepX * fOverviewCanvas.getZoomValue()), 0); + } + } + + if (e.keyCode == 32 && fPageNum > -1) { + Arrays.sort(fPagesList); + int pos = Arrays.binarySearch(fPagesList, fPageNum); + if (pos < 0) { + addToPagesList(fPageNum); + } else { + removeFromPagesList(fPageNum); + } + } + + if (!fAreaSelection && !fMultiSelection) { + fFirstPage = fPageNum; + fPagesList = new int[1]; + fPagesList[0] = fPageNum; + } else if ((fPageNum != -1) && (fAreaSelection) && (fFirstPage != -1)) { + fPagesList = new int[0]; + int line1 = fFirstPage / getNbRow(); + int row1 = fFirstPage % getNbRow(); + if (row1 != 0) { + line1++; + } else { + row1 = getNbRow(); + } + + int line2 = fPageNum / getNbRow(); + int row2 = fPageNum % getNbRow(); + if (row2 != 0) { + line2++; + } else { + row2 = getNbRow(); + } + + int temp; + if (line1 > line2) { + temp = line2; + line2 = line1; + line1 = temp; + } + + if (row1 > row2) { + temp = row2; + row2 = row1; + row1 = temp; + } + + for (int i = row1 - 1; i < row2; i++) { + for (int j = line1 - 1; j < line2; j++) { + addToPagesList(i + j * getNbRow() + 1); + } + } + } + displayPageNum(); + fOverviewCanvas.redraw(); + } + + @Override + protected void keyReleasedEvent(KeyEvent e) { + if (e.keyCode == SWT.CTRL) { + fMultiSelection = false; + } + if (e.keyCode == SWT.SHIFT) { + fAreaSelection = false; + } + } + + @Override + protected void contentsMouseDownEvent(MouseEvent event) { + + computeStepXY(); + int x1 = (int) ((event.x / fOverviewCanvas.getZoomValue()) / fStepX); + int x2 = (int) ((event.y / fOverviewCanvas.getZoomValue()) / fStepY); + + int oldPage = fPageNum; + + fPageNum = x1 + x2 * getNbRow() + 1; + + if (fPageNum > maxNumOfPages()) { + fPageNum = oldPage; + return; + } + + if (!fAreaSelection) { + fFirstPage = fPageNum; + } + + if ((fPageNum != -1) && (fMultiSelection)) { + Arrays.sort(fPagesList); + int pos = Arrays.binarySearch(fPagesList, fPageNum); + if (pos < 0) { + addToPagesList(fPageNum); + } else { + removeFromPagesList(fPageNum); + } + } else if ((fPageNum != -1) && (fAreaSelection) && (fFirstPage != -1)) { + + fPagesList = new int[0]; + + int line1 = fFirstPage / getNbRow(); + int row1 = fFirstPage % getNbRow(); + if (row1 != 0) { + line1++; + } else { + row1 = getNbRow(); + } + + int line2 = fPageNum / getNbRow(); + int row2 = fPageNum % getNbRow(); + if (row2 != 0) { + line2++; + } else { + row2 = getNbRow(); + } + + int temp; + if (line1 > line2) { + temp = line2; + line2 = line1; + line1 = temp; + } + + if (row1 > row2) { + temp = row2; + row2 = row1; + row1 = temp; + } + + for (int i = row1 - 1; i < row2; i++) { + for (int j = line1 - 1; j < line2; j++) { + addToPagesList(i + j * getNbRow() + 1); + } + } + } else { + fPagesList = new int[1]; + fPagesList[0] = fPageNum; + } + if ((event.stateMask & SWT.CTRL) != 0) { + fMultiSelection = true; + } + displayPageNum(); + redraw(); + } + + @Override + protected void contentsMouseMoveEvent(MouseEvent e) { + fToolTip.hideToolTip(); + } + + @Override + public void resizeContents(int w, int h) { + super.resizeContents(w, h); + } + + } + + /** + * A traverse listener implementation. + */ + protected static class LocalTraverseListener implements TraverseListener { + @Override + public void keyTraversed(TraverseEvent e) { + if ((e.detail == SWT.TRAVERSE_TAB_NEXT) || (e.detail == SWT.TRAVERSE_TAB_PREVIOUS)) { + e.doit = true; + } + } + } + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Constructor + * + * @param shell + * The shell reference + * @param sdWidget + * The sequence diagram widget reference + */ + public SDPrintDialogUI(Shell shell, SDWidget sdWidget) { + this(shell, sdWidget, false); + } + + /** + * Constructor + * + * @param shell + * The shell reference + * @param sdWidget + * The sequence diagram widget reference + * @param showPrintBtn + * Flag for showing print buttons + */ + public SDPrintDialogUI(Shell shell, SDWidget sdWidget, boolean showPrintBtn) { + fShell = shell; + fSdView = sdWidget; + fShowPrintButton = showPrintBtn; + + fPrinterData = Printer.getDefaultPrinterData(); + if (fPrinterData != null) { + fPrinterData.scope = PrinterData.SELECTION; + } + + fPagesList = new int[0]; + + fSelectionListener = new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + if (fUseCurrentZoom.getSelection()) { + fHorPagesNum.setEnabled(false); + fVertPagesNum.setEnabled(false); + } + if (fSetHPagesNumber.getSelection()) { + fHorPagesNum.setEnabled(true); + fVertPagesNum.setEnabled(false); + if (fCurrentPage.getSelection()) { + fCurrentPage.setSelection(false); + fAllPages.setSelection(true); + } + if ("".equals(fHorPagesNum.getText())) { //$NON-NLS-1$ + fHorPagesNum.setText("1"); //$NON-NLS-1$ + } + } + if (fSetVPagesNumber.getSelection()) { + fHorPagesNum.setEnabled(false); + fVertPagesNum.setEnabled(true); + if (fCurrentPage.getSelection()) { + fCurrentPage.setSelection(false); + fAllPages.setSelection(true); + } + if ("".equals(fVertPagesNum.getText())) { //$NON-NLS-1$ + fVertPagesNum.setText("1"); //$NON-NLS-1$ + } + } + if (fCurrentPage.getSelection() || fAllPages.getSelection() || fPageList.getSelection()) { + fFromPage.setEnabled(false); + fToPage.setEnabled(false); + } else { + fFromPage.setEnabled(true); + fToPage.setEnabled(true); + } + + fCurrentPage.setEnabled(fUseCurrentZoom.getSelection()); + fOverviewCanvas.setEnabled(fPageList.getSelection()); + if (fOverviewCanvas.isEnabled() && (e.widget == fUseCurrentZoom || e.widget == fSetHPagesNumber || e.widget == fSetVPagesNumber)) { + fPagesList = new int[1]; + fPagesList[0] = 1; + fPageNum = 1; + fFirstPage = 1; + } else if ((fOverviewCanvas.isEnabled() && (e.widget == fPageList)) && + (fPagesList == null || fPagesList.length <= 0)) { + + fPagesList = new int[1]; + fPagesList[0] = 1; + fPageNum = 1; + fFirstPage = 1; + } + computeStepXY(); + fTotalPages.setText(Integer.valueOf(maxNumOfPages()).toString()); + fOverviewCanvas.redraw(); + fOverviewCanvas.update(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + fPagesList = new int[0]; + computeStepXY(); + fOverviewCanvas.redraw(); + } + + }; + + fModifyListener = new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + fPagesList = new int[0]; + computeStepXY(); + fTotalPages.setText(Integer.valueOf(maxNumOfPages()).toString()); + fOverviewCanvas.redraw(); + } + + }; + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + /** + * Creates new grid data object. + * + * @param span horizontal span. + * @return grid data + */ + protected GridData newGridData(int span) { + GridData data = new GridData(GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL); + data.horizontalSpan = span; + return data; + } + + /** + * Creates the dialog area. + * + * @param parent The parent composite + * @return dialog control + */ + public Control createDialogArea(Composite parent) { + + GridLayout parentLayout = new GridLayout(); + parentLayout.numColumns = 6; + parent.setLayout(parentLayout); + + Group g1 = new Group(parent, SWT.SHADOW_NONE); + g1.setText(Messages.SequenceDiagram_ZoomOption); + g1.setLayoutData(newGridData(3)); + GridLayout g1layout = new GridLayout(); + g1layout.numColumns = 2; + g1.setLayout(g1layout); + + fUseCurrentZoom = new Button(g1, SWT.RADIO); + fUseCurrentZoom.setText(Messages.SequenceDiagram_UseCurrentZoom); + fUseCurrentZoom.setLayoutData(newGridData(2)); + fUseCurrentZoom.addSelectionListener(fSelectionListener); + + fSetHPagesNumber = new Button(g1, SWT.RADIO); + fSetHPagesNumber.setText(Messages.SequenceDiagram_NumberOfHorizontalPages); + fSetHPagesNumber.setLayoutData(newGridData(1)); + fSetHPagesNumber.addSelectionListener(fSelectionListener); + + fHorPagesNum = new Text(g1, SWT.SINGLE | SWT.BORDER); + fHorPagesNum.addModifyListener(fModifyListener); + + fSetVPagesNumber = new Button(g1, SWT.RADIO); + fSetVPagesNumber.setText(Messages.SequenceDiagram_NumberOfVerticalPages); + fSetVPagesNumber.setLayoutData(newGridData(1)); + fSetVPagesNumber.addSelectionListener(fSelectionListener); + + fVertPagesNum = new Text(g1, SWT.SINGLE | SWT.BORDER); + fVertPagesNum.addModifyListener(fModifyListener); + + Label nbTotal = new Label(g1, SWT.SHADOW_NONE | SWT.RIGHT); + nbTotal.setText(Messages.TotalNumberOfPages); + // nbTotal.setLayoutData(newGridData(1)); + + fTotalPages = new Text(g1, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY); + // nbHV.addModifyListener(modifListener); + + Group g2 = new Group(parent, SWT.SHADOW_NONE); + g2.setText(Messages.SequenceDiagram_Preview); + GridData data = new GridData(GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL); + data.horizontalSpan = 3; + data.verticalSpan = 2; + g2.setLayoutData(data); + GridLayout g2layout = new GridLayout(); + // g2layout. + g2layout.numColumns = 1; + // SVLayout g2layout = new SVLayout(); + g2.setLayout(g2layout); + + GridData data2 = new GridData(GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL); + data2.horizontalSpan = 1; + data2.verticalSpan = 1; + + fOverviewCanvas = new LocalSD(g2, SWT.NO_BACKGROUND); + GridData seqDiagLayoutData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL); + fOverviewCanvas.setLayoutData(seqDiagLayoutData); + // overviewCanvas.resizeContents(100,100); + if (fSdView.getContentsWidth() < fSdView.getVisibleWidth() && fSdView.getContentsHeight() < fSdView.getVisibleHeight()) { + fTest = 3; + } else { + fTest = 10; + } + fOverviewCanvas.setFrame(fSdView.getFrame(), true); + fOverviewCanvas.setZoomValue((float) 1 / fTest); + fOverviewCanvas.setCornerControl(null); + seqDiagLayoutData.widthHint = fOverviewCanvas.getContentsWidth() / fTest; + seqDiagLayoutData.widthHint = fOverviewCanvas.getFrame().getWidth() / fTest + 15; + + if (fSdView.getVisibleWidth() < fSdView.getContentsWidth()) { + seqDiagLayoutData.widthHint = fOverviewCanvas.getContentsWidth() / fTest; + if (seqDiagLayoutData.widthHint > Display.getDefault().getClientArea().width / 4) { + seqDiagLayoutData.widthHint = Display.getDefault().getClientArea().width / 4; + } + } else { + seqDiagLayoutData.widthHint = fOverviewCanvas.getFrame().getWidth() / fTest + 15; + } + + if (fSdView.getVisibleHeight() < fSdView.getContentsHeight()) { + seqDiagLayoutData.heightHint = fOverviewCanvas.getContentsHeight() / fTest; + if (seqDiagLayoutData.heightHint > Display.getDefault().getClientArea().width / 4) { + seqDiagLayoutData.heightHint = Display.getDefault().getClientArea().width / 4; + } + } else { + seqDiagLayoutData.heightHint = fOverviewCanvas.getFrame().getHeight() / fTest; + } + + fOverviewCanvas.setEnabled(false); + + fCurrentSelection = new Label(g2, SWT.SHADOW_NONE | SWT.LEFT); + fCurrentSelection.setLayoutData(newGridData(1)); + + Group g3 = new Group(parent, SWT.SHADOW_NONE); + g3.setText(Messages.SequenceDiagram_PrintRange); + g3.setLayoutData(newGridData(3)); + GridLayout g3layout = new GridLayout(); + g3layout.numColumns = 4; + g3.setLayout(g3layout); + + fAllPages = new Button(g3, SWT.RADIO); + fAllPages.setText(Messages.SequenceDiagram_AllPages); + fAllPages.setLayoutData(newGridData(4)); + fAllPages.addSelectionListener(fSelectionListener); + + fCurrentPage = new Button(g3, SWT.RADIO); + fCurrentPage.setText(Messages.SequenceDiagram_CurrentView); + fCurrentPage.setLayoutData(newGridData(4)); + fCurrentPage.setEnabled(true); + fCurrentPage.setSelection(true); + fCurrentPage.addSelectionListener(fSelectionListener); + + fPageList = new Button(g3, SWT.RADIO); + fPageList.setText(Messages.SequenceDiagram_SelectedPages); + fPageList.setLayoutData(newGridData(4)); + fPageList.addSelectionListener(fSelectionListener); + + fPageRange = new Button(g3, SWT.RADIO); + fPageRange.setText(Messages.SequenceDiagram_FromPage); + fPageRange.setLayoutData(newGridData(1)); + fPageRange.addSelectionListener(fSelectionListener); + + fFromPage = new Text(g3, SWT.SINGLE | SWT.BORDER); + + Label labelTo = new Label(g3, SWT.CENTER); + labelTo.setText(Messages.SequenceDiagram_to); + + fToPage = new Text(g3, SWT.SINGLE | SWT.BORDER); + + fToolTip = new DiagramToolTip(fOverviewCanvas); + + fOverviewCanvas.getViewControl().addMouseTrackListener(new MouseTrackListener() { + @Override + public void mouseEnter(MouseEvent e) { + fToolTip.hideToolTip(); + } + + @Override + public void mouseExit(MouseEvent e) { + fToolTip.hideToolTip(); + } + + @Override + public void mouseHover(MouseEvent e) { + int x1 = (int) (fOverviewCanvas.viewToContentsX(e.x) / fOverviewCanvas.getZoomValue() / fStepX); + int x2 = (int) (fOverviewCanvas.viewToContentsY(e.y) / fOverviewCanvas.getZoomValue() / fStepY); + int num = x1 + x2 * getNbRow() + 1; + if (num > maxNumOfPages()) { + return; + } + if (num > 0) { + fToolTip.showToolTip(String.valueOf(num)); + displayPageNum(); + } else { + fCurrentSelection.setText("");//$NON-NLS-1$ + fToolTip.hideToolTip(); + } + } + + }); + + fOverviewCanvas.addTraverseListener(new LocalTraverseListener()); + + fOverviewCanvas.addFocusListener(new FocusListener() { + @Override + public void focusGained(FocusEvent e) { + fOverviewCanvas.redraw(); + } + + @Override + public void focusLost(FocusEvent e) { + fOverviewCanvas.redraw(); + } + }); + + if (fShowPrintButton) { + Composite printerDlg = new Composite(parent, SWT.NONE); + data = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + data.horizontalSpan = 6; + parentLayout = new GridLayout(); + parentLayout.numColumns = 2; + printerDlg.setLayout(parentLayout); + printerDlg.setLayoutData(data); + + Label label = new Label(printerDlg, SWT.NONE); + label.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false)); + fPrinterDialog = new Button(printerDlg, SWT.PUSH); + fPrinterDialog.setText(Messages.SequenceDiagram_Printer); + + fPrinterDialog.addSelectionListener(new SelectionListener() { + @Override + public void widgetSelected(SelectionEvent e) { + printButtonSelected(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + + }); + } + + updatePrinterStatus(); + + return parent; + } + + /** + * Get number of pages for selection. + * @return number of pages for selection. + */ + public int getPagesForSelection() { + return fNbPages; + } + + /** + * Handler for when the OK button is pressed + * + * @return True if the operation was successful, false if there was an error + */ + public boolean okPressed() { + fPrintAll = fAllPages.getSelection(); + fPrintCurrent = fCurrentPage.getSelection(); + fPrintSelection = fPageList.getSelection(); + fPrintRange = fPageRange.getSelection(); + try { + if (fPrintRange) { + fFrom = Integer.valueOf(fFromPage.getText()).intValue(); + fTo = Integer.valueOf(fToPage.getText()).intValue(); + if (fFrom > maxNumOfPages() || fTo > maxNumOfPages() || fFrom <= 0 || fTo <= 0) { + MessageDialog.openError(getShell(), Messages.SequenceDiagram_Error, Messages.SequenceDiagram_InvalidRange); + return false; + } + } else if (fSetHPagesNumber.getSelection() && fNbPages <= 0) { + MessageDialog.openError(getShell(), Messages.SequenceDiagram_Error, Messages.SequenceDiagram_InvalidNbHorizontal); + return false; + } else if (fSetVPagesNumber.getSelection() && fNbPages <= 0) { + MessageDialog.openError(getShell(), Messages.SequenceDiagram_Error, Messages.SequenceDiagram_InvalidNbVertical); + return false; + } else if (fPrintSelection && getPageList().length <= 0) { + MessageDialog.openError(getShell(), Messages.SequenceDiagram_Error, Messages.SequenceDiagram_NoPageSelected); + return false; + } + + } catch (Exception e) { + MessageDialog.openError(getShell(), Messages.SequenceDiagram_Error, Messages.SequenceDiagram_InvalidRange); + fFrom = 0; + fTo = 0; + return false; + } + + return true; + } + + /** + * Draws region that was selected + * @param img The corresponding image + * @param r The selected rectangle. + * @param color The color to use for selection + * @return image data reference + */ + public ImageData drawRegionSelected(Image img, Rectangle r, RGB color) { + ImageData id = img.getImageData(); + for (int a = 0; a < r.width && r.x + a < id.width; a++) { + for (int b = 0; b < r.height && r.y + b < id.height; b++) { + int index = id.getPixel(r.x + a, r.y + b); + RGB rgb = id.palette.getRGB(index); + rgb = combine(color, rgb); + id.setPixel(r.x + a, r.y + b, id.palette.getPixel(rgb)); + } + } + return id; + } + + /** + * Combines two RGB colors. + * @param front The front color + * @param back The back color + * @return new RGB color + */ + public static RGB combine(RGB front, RGB back) { + int _af = 128; + int _ab = 200; + + double af = (_af) / 255.0; + double rf = front.red; + double gf = front.green; + double bf = front.blue; + + double ab = (_ab) / 255.0; + double rb = back.red; + double gb = back.green; + double bb = back.blue; + + double k = (1.0 - af) * ab; + int r = (int) ((af * rf + k * rb)); + int g = (int) ((af * gf + k * gb)); + int b = (int) ((af * bf + k * bb)); + + return new RGB(r, g, b); + } + + /** + * Computes value for X coordinates step and Y coordinates step. + */ + protected void computeStepXY() { + float cw = fOverviewCanvas.getContentsWidth() / fOverviewCanvas.getZoomValue(); + float ch = fOverviewCanvas.getContentsHeight() / fOverviewCanvas.getZoomValue(); + try { + if (fPrinterData == null) { + fStepX = 0; + fStepY = 0; + fNbPages = 0; + fZoomFactor = 0; + } else { + Printer printer = new Printer(fPrinterData); + if (fSetHPagesNumber.getSelection()) { + fNbPages = Integer.valueOf(fHorPagesNum.getText()).intValue(); + float z1 = fSdView.getContentsWidth() / cw; + float z2 = printer.getClientArea().width / ((float) fSdView.getContentsWidth() / fNbPages); + + fStepY = printer.getClientArea().height / z1 / z2; + fStepX = cw / fNbPages; + } else if (fSetVPagesNumber.getSelection()) { + fNbPages = Integer.valueOf(fVertPagesNum.getText()).intValue(); + float z1 = fSdView.getContentsHeight() / ch; + float z2 = printer.getClientArea().height / ((float) fSdView.getContentsHeight() / fNbPages); + fStepX = printer.getClientArea().width / z1 / z2; + fStepY = ch / fNbPages; + } else { + float z1 = fSdView.getContentsWidth() / (cw); + fStepX = fSdView.getVisibleWidth() / z1; + fNbPages = Math.round(cw / fStepX); + if (fNbPages == 0) { + fNbPages = 1; + } + int pw = printer.getClientArea().width; + int ph = printer.getClientArea().height; + float z2 = pw / ((float) fSdView.getContentsWidth() / fNbPages); + fStepY = ph / z1 / z2; + } + } + } catch (NumberFormatException e) { + fStepX = fStepY = fNbPages = 0; + fZoomFactor = 0; + } + sTX = fStepX * (fSdView.getContentsWidth() / cw); + sTY = fStepY * (fSdView.getContentsHeight() / ch); + float rat = 1; + if ((fSdView.getVisibleWidth() > fSdView.getContentsWidth()) && (fSetVPagesNumber.getSelection() || fSetHPagesNumber.getSelection())) { + rat = (float) fSdView.getVisibleWidth() / (float) fSdView.getContentsWidth(); + } + fZoomFactor = (fOverviewCanvas.getContentsWidth() / cw) / fOverviewCanvas.getZoomFactor() * rat; + } + + /** + * Returns the pages list. + * + * @return the pages list. + */ + public int[] getPageList() { + return Arrays.copyOf(fPagesList, fPagesList.length); + } + + /** + * Adds a page to pages list. + * + * @param num + * The number of the the new page + */ + public void addToPagesList(int num) { + int temp[] = new int[fPagesList.length + 1]; + System.arraycopy(fPagesList, 0, temp, 0, fPagesList.length); + temp[temp.length - 1] = num; + fPagesList = new int[temp.length]; + System.arraycopy(temp, 0, fPagesList, 0, temp.length); + } + + /** + * Removes a page from the pages list. + * + * @param num + * The number of the page to remove + */ + public void removeFromPagesList(int num) { + int pos = Arrays.binarySearch(fPagesList, num); + int temp[] = new int[fPagesList.length - 1]; + System.arraycopy(fPagesList, 0, temp, 0, pos); + System.arraycopy(fPagesList, pos + 1, temp, pos, fPagesList.length - pos - 1); + fPagesList = new int[temp.length]; + System.arraycopy(temp, 0, fPagesList, 0, temp.length); + } + + /** + * Returns the maximum number of pages. + * + * @return maximum number of pages. + */ + public int maxNumOfPages() { + return (getNbRow() * getNbLines()); + } + + /** + * Returns the number of rows. + * + * @return number of rows. + */ + public int getNbRow() { + if (!fSetHPagesNumber.isDisposed()) { + int cw = (int) (fOverviewCanvas.getContentsWidth() / fOverviewCanvas.getZoomValue()); + int row = 1; + if (fStepX != 0) { + row = (int) (cw / fStepX); + if (fSetHPagesNumber.getSelection()) { + row = Math.round(cw / fStepX); + } else if ((cw % fStepX != 0)) { + row++; + } + } + fNbRows = row; + } + return fNbRows; + } + + /** + * Returns the number of lines. + * + * @return number of lines + */ + public int getNbLines() { + if (!fSetVPagesNumber.isDisposed()) { + int ch = (int) (fOverviewCanvas.getContentsHeight() / fOverviewCanvas.getZoomValue()); + int line = 1; + if (fStepY != 0) { + line = (int) (ch / fStepY); + if (fSetVPagesNumber.getSelection()) { + line = Math.round(ch / fStepY); + } else if (ch % fStepY != 0) { + line++; + } + } + fNbLines = line; + } + return fNbLines; + } + + /** + * Returns whether to print all pages or not. + * + * @return true for all pages else false. + */ + public boolean printAll() { + return fPrintAll; + } + + /** + * Returns whether to print only current page + * + * @return true for current page only else false.. + */ + public boolean printCurrent() { + return fPrintCurrent; + } + + /** + * Returns whether to print selected pages. + * + * @return true for selected pages only else false. + */ + public boolean printSelection() { + return fPrintSelection; + } + + /** + * Returns whether to print range of pages. + * + * @return true for range of pages only else false. + */ + public boolean printRange() { + return fPrintRange; + } + + /** + * Returns the step in X direction. + * + * @return step in X direction + */ + public float getStepX() { + return sTX; + } + + /** + * Returns the step in Y direction. + * + * @return step in Y direction + */ + public float getStepY() { + return sTY; + } + + /** + * Returns the zoom factor + * + * @return zoom factor + */ + public float getZoomFactor() { + return fZoomFactor; + } + + /** + * Returns the printer data reference. + * + * @return printer data reference + */ + public PrinterData getPrinterData() { + return fPrinterData; + } + + /** + * Returns the page number to start printing from. + * + * @return page number to start printing from + */ + public int getFrom() { + return fFrom; + } + + /** + * Returns the page number to print to. + * + * @return page number to print to + */ + public int getTo() { + return fTo; + } + + /** + * Displays current number of pages + */ + protected void displayPageNum() { + if (fPageNum > 0) { + String message = MessageFormat.format(Messages.SequenceDiagram_Page, new Object[] { Integer.valueOf(fPageNum) }); + fCurrentSelection.setText(message); + fCurrentSelection.getParent().layout(); + } + } + + /** + * Returns the shell reference. + * + * @return the shell reference. + */ + public Shell getShell() { + return fShell; + } + + /** + * Sets the shell. + * + * @param shell The shell reference. + */ + public void setShell(Shell shell) { + fShell = shell; + } + + /** + * Handle selection of print button. + */ + public void printButtonSelected() { + PrintDialog printer = new PrintDialog(getShell()); + if (fAllPages.getSelection()) { + printer.setScope(PrinterData.ALL_PAGES); + } + if (fCurrentPage.getSelection()) { + printer.setScope(PrinterData.SELECTION); + } + if (fPageList.getSelection()) { + printer.setScope(PrinterData.SELECTION); + } + if (fPageRange.getSelection()) { + printer.setScope(PrinterData.PAGE_RANGE); + fFrom = Integer.valueOf(fFromPage.getText()).intValue(); + fTo = Integer.valueOf(fToPage.getText()).intValue(); + printer.setStartPage(fFrom); + printer.setEndPage(fTo); + } + + PrinterData newPrinterData = printer.open(); + if (newPrinterData != null) { + fPrinterData = newPrinterData; + } + updatePrinterStatus(); + + if (printer.getScope() == PrinterData.ALL_PAGES) { + fAllPages.setSelection(true); + fCurrentPage.setSelection(false); + fPageList.setSelection(false); + fPageRange.setSelection(false); + fHorPagesNum.setEnabled(false); + fVertPagesNum.setEnabled(false); + } + if (printer.getScope() == PrinterData.PAGE_RANGE) { + fAllPages.setSelection(false); + fCurrentPage.setSelection(false); + fPageList.setSelection(false); + fPageRange.setSelection(true); + fFromPage.setEnabled(true); + fToPage.setEnabled(true); + fFromPage.setText((Integer.valueOf(printer.getStartPage())).toString()); + fToPage.setText((Integer.valueOf(printer.getEndPage())).toString()); + } + computeStepXY(); + fOverviewCanvas.redraw(); + } + + /** + * Sets parent wizard page + * + * @param parent The parent wizard page + */ + public void setParentWizardPage(WizardPage parent) { + fParentWizardPage = parent; + } + + /** + * Sets the parent dialog box. + * + * @param parent The parent dialog box. + */ + public void setParentDialog(SDPrintDialog parent) { + fParentDialog = parent; + } + + /** + * Updates the printer status + */ + protected void updatePrinterStatus() { + if (fParentWizardPage != null) { + // used in the wizard dialog + if (fPrinterData == null) { + // show error message and disable Finish button + fParentWizardPage.setErrorMessage(Messages.SequenceDiagram_NoPrinterSelected); + fParentWizardPage.setPageComplete(false); + } else { + // clear error message and enable Finish button + fParentWizardPage.setErrorMessage(null); + fParentWizardPage.setPageComplete(true); + } + } else if (fParentDialog != null) { + // used in the print dialog + if (fPrinterData == null) { + // show error message and disable OK button + fParentDialog.setErrorMessage(Messages.SequenceDiagram_NoPrinterSelected); + fParentDialog.setPageComplete(false); + } else { + // clear error message and enable OK button + fParentDialog.setErrorMessage(null); + fParentDialog.setPageComplete(true); + } + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/SearchFilterDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/SearchFilterDialog.java new file mode 100755 index 0000000000..3a283402e6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/SearchFilterDialog.java @@ -0,0 +1,451 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.DialogSettings; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.AsyncMessage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.AsyncMessageReturn; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Lifeline; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Stop; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SyncMessage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SyncMessageReturn; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDFindProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; + +/** + * This is the common dialog to define Find and/or Filter Criteria(s) + * + * @version 1.0 + * @author Bernd Hufmann + */ +public class SearchFilterDialog extends Dialog { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The find criteria property name + */ + protected static final String FIND_CRITERIA = "findCriteria"; //$NON-NLS-1$ + /** + * The find expression list property name + */ + protected static final String FIND_EXPRESSION_LIST = "findExpressionList"; //$NON-NLS-1$ + /** + * The filter criteria poperty name + */ + protected static final String FILTER_CRITERIA = "filterCriteria"; //$NON-NLS-1$ + /** + * The filter expression list property name + */ + protected static final String FILTER_EXPRESSION_LIST = "filterExpressionList"; //$NON-NLS-1$ + /** + * The maximum number of expressions stored. + */ + protected static final int MAX_EXPRESSION_LIST = 7; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The sequence diagram view reference. + */ + private final SDView fSdView; + + /** + * The tab with the controls for a Criteria + */ + private final TabFolder fTabFolder = null; + + /** + * The Criteria updated by this dialog + */ + private Criteria fCriteria = null; + + /** + * The find/filter provider telling which graph nodes are supported + */ + private final ISDGraphNodeSupporter fProvider; + + /** + * The okText is the text for the Ok button and title is the title of the + * dialog.
    + * Both depend (okText and title (below)) on the usage that is done of this + * dialog (find or filter). + */ + private String fOkText; + + /** + * The title is the title of the dialog.
    + * Both depend (okText and title) on the usage that is done of this dialog + * (find or filter). + */ + private String fTitle; + + /** + * List of string expressions that have been searched already + */ + private String[] fExpressionList; + + /** + * find is true if the dialog is for the find feature and false for filter + * feature + */ + private boolean fIsFind; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Standard constructor + * + * @param view + * A sequence diagram view reference + * @param provider + * A graph node supporter provider + * @param filter + * A flag to indicate filtering (true) or finding (false) + * @param style + * Style bits + */ + public SearchFilterDialog(SDView view, ISDGraphNodeSupporter provider, boolean filter, int style) { + super(view.getSDWidget().getShell()); + setShellStyle(SWT.DIALOG_TRIM | style); + fProvider = provider; + fSdView = view; + fIsFind = !filter; + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public Control createDialogArea(Composite arg0) { + if (fIsFind) { + fExpressionList = Activator.getDefault().getDialogSettings().getArray(FIND_EXPRESSION_LIST); + } else { + fExpressionList = Activator.getDefault().getDialogSettings().getArray(FILTER_EXPRESSION_LIST); + } + if (fExpressionList == null) { + fExpressionList = new String[0]; + } + return new TabContents(arg0, fProvider, getButton(IDialogConstants.OK_ID), fExpressionList); + } + + /** + * Open the dialog box + */ + @Override + public int open() { + create(); + + if (fCriteria == null) { + loadCriteria(); + } + + if (fCriteria == null) { + fCriteria = new Criteria(); + fCriteria.setLifeLineSelected(fProvider.isNodeSupported(ISDGraphNodeSupporter.LIFELINE)); + fCriteria.setSyncMessageSelected(fProvider.isNodeSupported(ISDGraphNodeSupporter.SYNCMESSAGE)); + fCriteria.setSyncMessageReturnSelected(fProvider.isNodeSupported(ISDGraphNodeSupporter.SYNCMESSAGERETURN)); + fCriteria.setAsyncMessageSelected(fProvider.isNodeSupported(ISDGraphNodeSupporter.ASYNCMESSAGE)); + fCriteria.setAsyncMessageReturnSelected(fProvider.isNodeSupported(ISDGraphNodeSupporter.ASYNCMESSAGERETURN)); + fCriteria.setStopSelected(fProvider.isNodeSupported(ISDGraphNodeSupporter.STOP)); + } + copyFromCriteria(fCriteria); + + if (fOkText != null) { + getButton(IDialogConstants.OK_ID).setText(fOkText); + } else { + getButton(IDialogConstants.OK_ID).setText(Messages.SequenceDiagram_Find); + } + + if (fIsFind) { + getButton(IDialogConstants.CANCEL_ID).setText(Messages.SequenceDiagram_Close); + } + + Button okButton = getButton(IDialogConstants.OK_ID); + ((TabContents) getDialogArea()).setOkButton(okButton); + if (fCriteria == null || !((fCriteria.getExpression() != null && !fCriteria.getExpression().equals("")) && //$NON-NLS-1$ + (fCriteria.isAsyncMessageReturnSelected() || fCriteria.isAsyncMessageSelected() || fCriteria.isLifeLineSelected() || fCriteria.isStopSelected() || fCriteria.isSyncMessageReturnSelected() || fCriteria.isSyncMessageSelected()))) { + okButton.setEnabled(false); + } + + if (fTitle != null) { + getShell().setText(fTitle); + } else { + getShell().setText(Messages.SequenceDiagram_SequenceDiagramFind); + } + + getShell().pack(); + getShell().setLocation(getShell().getDisplay().getCursorLocation()); + + fCriteria = null; + return super.open(); + } + + /** + * Loads criteria from the dialog settings which are saved in the workspace. + */ + protected void loadCriteria() { + + String CRITERIA = FIND_CRITERIA; + if (!fIsFind) { + CRITERIA = FILTER_CRITERIA; + } + + DialogSettings section = (DialogSettings) Activator.getDefault().getDialogSettings().getSection(CRITERIA); + List selection = fSdView.getSDWidget().getSelection(); + if ((selection == null || selection.size() != 1) || (!fIsFind)) { + if (section != null) { + fCriteria = new Criteria(); + fCriteria.load(section); + } + } else { + GraphNode gn = selection.get(0); + fCriteria = new Criteria(); + fCriteria.setExpression(gn.getName()); + fCriteria.setCaseSenstiveSelected(true); + if (gn instanceof Lifeline && fProvider.isNodeSupported(ISDGraphNodeSupporter.LIFELINE)) { + fCriteria.setLifeLineSelected(true); + } else if (gn instanceof SyncMessageReturn && fProvider.isNodeSupported(ISDGraphNodeSupporter.SYNCMESSAGERETURN)) { + fCriteria.setSyncMessageReturnSelected(true); + } else if ((gn instanceof SyncMessageReturn || gn instanceof SyncMessage) && fProvider.isNodeSupported(ISDGraphNodeSupporter.SYNCMESSAGE)) { + fCriteria.setSyncMessageSelected(true); + } else if (gn instanceof AsyncMessageReturn && fProvider.isNodeSupported(ISDGraphNodeSupporter.ASYNCMESSAGERETURN)) { + fCriteria.setAsyncMessageReturnSelected(true); + } else if ((gn instanceof AsyncMessageReturn || gn instanceof AsyncMessage) && fProvider.isNodeSupported(ISDGraphNodeSupporter.ASYNCMESSAGE)) { + fCriteria.setAsyncMessageSelected(true); + } else if (gn instanceof Stop && fProvider.isNodeSupported(ISDGraphNodeSupporter.STOP)) { + fCriteria.setStopSelected(true); + } + } + } + + /** + * Called when the dialog box ok button is pressed and calls back the + * appropriate action provider (ISDFilterProvider or ISDFindProvider). + */ + @Override + public void okPressed() { + copyToCriteria(); + if (!fIsFind) { + saveCriteria(); + super.close(); // Filter is modal + } + if ((fProvider != null) && (fProvider instanceof ISDFindProvider) && fIsFind) { + boolean result = ((ISDFindProvider) fProvider).find(fCriteria); + TabContents content = getTabContents(); + content.setResult(result); + } + } + + @Override + public void cancelPressed() { + if (fIsFind) { + copyToCriteria(); + if (fProvider instanceof ISDFindProvider) { + ((ISDFindProvider) fProvider).cancel(); + } + saveCriteria(); + } + super.cancelPressed(); + } + + /** + * Saves the criteria to the dialog settings within the workspace. + */ + public void saveCriteria() { + String CRITERIA = FIND_CRITERIA; + String EXPRESSION_LIST = FIND_EXPRESSION_LIST; + if (!fIsFind) { + CRITERIA = FILTER_CRITERIA; + EXPRESSION_LIST = FILTER_EXPRESSION_LIST; + } + DialogSettings settings = (DialogSettings) Activator.getDefault().getDialogSettings(); + DialogSettings section = (DialogSettings) settings.getSection(CRITERIA); + if (section == null) { + section = (DialogSettings) settings.addNewSection(CRITERIA); + } + fCriteria.save(section); + + if (fCriteria.getExpression().length() > 0) { + ArrayList list = new ArrayList<>(); + for (int i = 0; i < fExpressionList.length; i++) { + list.add(fExpressionList[i]); + } + // Remove the used expression if one from the dropdown list + list.remove(fCriteria.getExpression()); + // Put the new expression at the beginning + list.add(0, fCriteria.getExpression()); + // Fill in the expressionList, truncating to MAX_EXPRESSION_LIST + int size = Math.min(list.size(), MAX_EXPRESSION_LIST); + String[] temp = new String[size]; + for (int i = 0; i < size; i++) { + temp[i] = list.get(i); + } + fExpressionList = temp; + settings.put(EXPRESSION_LIST, fExpressionList); + } + } + + /** + * Returns the criteria + * + * @return the criteria + */ + public Criteria getCriteria() { + return fCriteria; + } + + /** + * Sets the criteria. + * + * @param criteria + * the criteria to set. + */ + public void setCriteria(Criteria criteria) { + fCriteria = criteria; + } + + /** + * Get the current end-user settings from the dialog to a Criteria + */ + public void copyToCriteria() { + fCriteria = new Criteria(); + TabContents content = getTabContents(); + fCriteria.setLifeLineSelected(content.isLifelineButtonSelected()); + fCriteria.setSyncMessageSelected(content.isSynMessageButtonSelected()); + fCriteria.setSyncMessageReturnSelected(content.isSynMessageReturnButtonSelected()); + fCriteria.setAsyncMessageSelected(content.isAsynMessageButtonSelected()); + fCriteria.setAsyncMessageReturnSelected(content.isAsynMessageReturnButtonSelected()); + fCriteria.setStopSelected(content.isStopButtonSelected()); + fCriteria.setCaseSenstiveSelected(content.isCaseSensitiveSelected()); + fCriteria.setExpression(content.getSearchText()); + } + + /** + * Returns the tab content reference. + * + * @return the tab content + */ + protected TabContents getTabContents() { + TabContents content = null; + if (fTabFolder == null) { + content = (TabContents) getDialogArea(); + } else { + content = (TabContents) fTabFolder.getSelection()[0].getControl(); + } + return content; + } + + /** + * Initialize the dialog with the settings of an existing Criteria
    + * Criteria must not be null and the TabContents must have been created + * + * @param from + * the criteria to copy from + */ + public void copyFromCriteria(Criteria from) { + TabContents content = getTabContents(); + content.setLifelineButtonSelection(from.isLifeLineSelected()); + content.setSynMessageButtonSelection(from.isSyncMessageSelected()); + content.setSynMessageReturnButtonSelection(from.isSyncMessageReturnSelected()); + content.setAsynMessageButtonSelection(from.isAsyncMessageSelected()); + content.setAsynMessageReturnButtonSelection(from.isSyncMessageReturnSelected()); + content.setStopButtonSelection(from.isStopSelected()); + content.setCaseSensitiveSelection(from.isCaseSenstiveSelected()); + if (from.getExpression() != null) { + content.setSearchText(from.getExpression()); + } + } + + /** + * Sets the text to be used for the ok button + * + * @param okText + * text to set + */ + public void setOkText(String okText) { + fOkText = okText; + } + + /** + * Sets the title to be used for the dialog box. + * + * @param title + * The title to set + */ + public void setTitle(String title) { + fTitle = title; + } + + /** + * Gets the text to be used for the ok button + * + * @return the text to be used for the ok button + * @since 2.0 + */ + public String getOkText() { + return fOkText; + } + + /** + * Sets the IsFind flag (true for find, else for filter) + * + * @param flag value to set + * @since 2.0 + */ + protected void setIsFind(boolean flag) { + fIsFind = flag; + } + + /** + * Gets the title to be used for the dialog box. + * + * @return the title to be used for the dialog box. + * @since 2.0 + */ + public String getTitle() { + return fTitle; + } + + /** + * Gets the IsFind flag (true for find, else for filter) + * + * @return true for find, else for filter + * @since 2.0 + */ + protected boolean isFind() { + return fIsFind; + } + + + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/TabContents.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/TabContents.java new file mode 100755 index 0000000000..3b5f98b090 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/dialogs/TabContents.java @@ -0,0 +1,476 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; + +/** + * Class implementation contains the controls that allows to create or update a find or filter Criteria. + * + * @version 1.0 + * @author sveyrier + */ +public class TabContents extends Composite { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The button for lifelines. + */ + private Button fLifelineButton; + /** + * The button for stops. + */ + private Button fStopButton = null; + /** + * The button for synchronous messages + */ + private Button fSynMessageButton = null; + /** + * The button for synchronous return messages + */ + private Button fSynMessageReturnButton = null; + /** + * The button for asynchronous messages + */ + private Button fAsynMessageButton = null; + /** + * The button for asynchronous return messages + */ + private Button fAsynMessageReturnButton = null; + /** + * The search text combo box. + */ + private Combo fSearchText = null; + /** + * The button for case sensitive expressions. + */ + private Button fCaseSensitive = null; + /** + * The label for the result string. + */ + private Label fResult = null; + /** + * The button for notifying parent about valid data. + */ + private Button fParentOkButton = null; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Creates the dialog contents + * + * @param parent the parent widget + * @param provider the provider which handle the action + * @param okButton of the dialog (to be enabled/disabled) + * @param expressionList list of strings already searched for + */ + public TabContents(Composite parent, ISDGraphNodeSupporter provider, Button okButton, String[] expressionList) { + super(parent, SWT.NONE); + fParentOkButton = okButton; + setLayout(new GridLayout()); + + GraphNodeTypeListener graphNodeTypeListener = new GraphNodeTypeListener(); + ExpressionListener expressionListener = new ExpressionListener(); + + // Inform the user how to fill the string to search + Label searchTitle = new Label(this, SWT.LEFT); + searchTitle.setText(Messages.SequenceDiagram_MatchingString); + Composite searchPart = new Composite(this, SWT.NONE); + GridData searchPartData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL); + GridLayout searchPartLayout = new GridLayout(); + searchPartLayout.numColumns = 2; + searchPart.setLayout(searchPartLayout); + searchPart.setLayoutData(searchPartData); + + // Create the user string input area + fSearchText = new Combo(searchPart, SWT.DROP_DOWN); + GridData comboData = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL); + /* + * GridData tabLayoutData2 = new GridData(GridData.HORIZONTAL_ALIGN_FILL| GridData.VERTICAL_ALIGN_FILL); + */ + fSearchText.setLayoutData(comboData); + if (expressionList != null) { + for (int i = 0; i < expressionList.length; i++) { + fSearchText.add(expressionList[i]); + } + } + fSearchText.addModifyListener(expressionListener); + + // Create the case sensitive check button + fCaseSensitive = new Button(searchPart, SWT.CHECK); + fCaseSensitive.setText(Messages.SequenceDiagram_CaseSensitive); + + // Create the group for searched graph node kind selection + Group kindSelection = new Group(this, SWT.SHADOW_NONE); + kindSelection.setText(Messages.SequenceDiagram_SearchFor); + // kindSelection.setLayoutData(tabLayoutData2); + GridLayout kindSelectionLayout = new GridLayout(); + kindSelectionLayout.numColumns = 1; + kindSelection.setLayout(kindSelectionLayout); + GridData kindSelectionData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL); + kindSelection.setLayoutData(kindSelectionData); + + // Create the lifeline check button + if (provider != null && provider.isNodeSupported(ISDGraphNodeSupporter.LIFELINE)) { + fLifelineButton = new Button(kindSelection, SWT.CHECK); + String nodeName = provider.getNodeName(ISDGraphNodeSupporter.LIFELINE, null); + if (nodeName != null) { + fLifelineButton.setText(nodeName); + } else { + fLifelineButton.setText(Messages.SequenceDiagram_Lifeline); + } + fLifelineButton.setEnabled(true); + fLifelineButton.addSelectionListener(graphNodeTypeListener); + } + + if (provider != null && provider.isNodeSupported(ISDGraphNodeSupporter.STOP)) { + // Create the stop check button + fStopButton = new Button(kindSelection, SWT.CHECK); + String nodeName = provider.getNodeName(ISDGraphNodeSupporter.STOP, null); + if (nodeName != null) { + fStopButton.setText(nodeName); + } else { + fStopButton.setText(Messages.SequenceDiagram_Stop); + } + + fStopButton.setEnabled(true); + fStopButton.addSelectionListener(graphNodeTypeListener); + } + + if (provider != null && provider.isNodeSupported(ISDGraphNodeSupporter.SYNCMESSAGE)) { + // Create the synchronous message check button + fSynMessageButton = new Button(kindSelection, SWT.CHECK); + String nodeName = provider.getNodeName(ISDGraphNodeSupporter.SYNCMESSAGE, null); + if (nodeName != null) { + fSynMessageButton.setText(nodeName); + } else { + fSynMessageButton.setText(Messages.SequenceDiagram_SynchronousMessage); + } + fSynMessageButton.setEnabled(true); + fSynMessageButton.addSelectionListener(graphNodeTypeListener); + } + + if (provider != null && provider.isNodeSupported(ISDGraphNodeSupporter.SYNCMESSAGERETURN)) { + // Create the synchronous message return check button + fSynMessageReturnButton = new Button(kindSelection, SWT.CHECK); + String nodeName = provider.getNodeName(ISDGraphNodeSupporter.SYNCMESSAGERETURN, null); + if (nodeName != null) { + fSynMessageReturnButton.setText(nodeName); + } else { + fSynMessageReturnButton.setText(Messages.SequenceDiagram_SynchronousMessageReturn); + } + fSynMessageReturnButton.setEnabled(true); + fSynMessageReturnButton.addSelectionListener(graphNodeTypeListener); + } + + if (provider != null && provider.isNodeSupported(ISDGraphNodeSupporter.ASYNCMESSAGE)) { + // Create the asynchronous message check button + fAsynMessageButton = new Button(kindSelection, SWT.CHECK); + String nodeName = provider.getNodeName(ISDGraphNodeSupporter.ASYNCMESSAGE, null); + if (nodeName != null) { + fAsynMessageButton.setText(nodeName); + } else { + fAsynMessageButton.setText(Messages.SequenceDiagram_AsynchronousMessage); + } + fAsynMessageButton.setEnabled(true); + fAsynMessageButton.addSelectionListener(graphNodeTypeListener); + } + + if (provider != null && provider.isNodeSupported(ISDGraphNodeSupporter.ASYNCMESSAGERETURN)) { + // Create the asynchronous message return check button + fAsynMessageReturnButton = new Button(kindSelection, SWT.CHECK); + String nodeName = provider.getNodeName(ISDGraphNodeSupporter.ASYNCMESSAGERETURN, null); + if (nodeName != null) { + fAsynMessageReturnButton.setText(nodeName); + } else { + fAsynMessageReturnButton.setText(Messages.SequenceDiagram_AsynchronousMessageReturn); + } + fAsynMessageReturnButton.setEnabled(true); + fAsynMessageReturnButton.addSelectionListener(graphNodeTypeListener); + } + + fResult = new Label(this, SWT.LEFT); + fResult.setText(Messages.SequenceDiagram_StringNotFound); + fResult.setVisible(false); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + /** + * Set result text visibility + * @param found true for found (enable visibility) else false + */ + public void setResult(boolean found) { + fResult.setVisible(!found); + } + + /** + * Updates parent OK button based on input data. + */ + public void updateOkButton() { + if (fParentOkButton == null) { + return; + } + boolean enabled = (fSearchText.getText() != null && !fSearchText.getText().equals("")) && //$NON-NLS-1$ + (isLifelineButtonSelected() || isStopButtonSelected() || isSynMessageButtonSelected() || isSynMessageReturnButtonSelected() || isAsynMessageButtonSelected() || isAsynMessageReturnButtonSelected()); + fParentOkButton.setEnabled(enabled); + } + + /** + * Sets the parent OK button reference. + * + * @param okButton The parent OK button + */ + public void setOkButton(Button okButton) { + fParentOkButton = okButton; + } + + /** + * Returns the asynchronous message check button state + * + * @return true if check, false otherwise + */ + public boolean isAsynMessageButtonSelected() { + if (fAsynMessageButton != null) { + return fAsynMessageButton.getSelection(); + } + return false; + } + + /** + * Returns the asynchronous message return check button state + * + * @return true if check, false otherwise + */ + public boolean isAsynMessageReturnButtonSelected() { + if (fAsynMessageReturnButton != null) { + return fAsynMessageReturnButton.getSelection(); + } + return false; + } + + /** + * Returns the case sensitive check button state + * + * @return true if check, false otherwise + */ + public boolean isCaseSensitiveSelected() { + if (fCaseSensitive != null) { + return fCaseSensitive.getSelection(); + } + return false; + } + + /** + * Returns the lifeline check button state + * + * @return true if check, false otherwise + */ + public boolean isLifelineButtonSelected() { + if (fLifelineButton != null) { + return fLifelineButton.getSelection(); + } + return false; + } + + /** + * Returns the user input string + * + * @return the string to search for + */ + public String getSearchText() { + return fSearchText.getText(); + } + + /** + * Returns the stop check button state + * + * @return true if check, false otherwise + */ + public boolean isStopButtonSelected() { + if (fStopButton != null) { + return fStopButton.getSelection(); + } + return false; + } + + /** + * Returns the synchronous message check button state + * + * @return true if check, false otherwise + */ + public boolean isSynMessageButtonSelected() { + if (fSynMessageButton != null) { + return fSynMessageButton.getSelection(); + } + return false; + } + + /** + * Returns the synchronous message return check button state + * + * @return true if check, false otherwise + */ + public boolean isSynMessageReturnButtonSelected() { + if (fSynMessageReturnButton != null) { + return fSynMessageReturnButton.getSelection(); + } + return false; + } + + /** + * Set the asynchronous message check button state + * + * @param state + * The new state to set + */ + public void setAsynMessageButtonSelection(boolean state) { + if (fAsynMessageButton != null) { + fAsynMessageButton.setSelection(state); + } + } + + /** + * Set the asynchronous message return check button state + * + * @param state + * The new state to set + */ + public void setAsynMessageReturnButtonSelection(boolean state) { + if (fAsynMessageReturnButton != null) { + fAsynMessageReturnButton.setSelection(state); + } + } + + /** + * Set the case sensitive check button state + * + * @param state + * The new state to set + */ + public void setCaseSensitiveSelection(boolean state) { + if (fCaseSensitive != null) { + fCaseSensitive.setSelection(state); + } + } + + /** + * Set the lifeline check button state + * + * @param state + * The new state to set + */ + public void setLifelineButtonSelection(boolean state) { + if (fLifelineButton != null) { + fLifelineButton.setSelection(state); + } + } + + /** + * Set the user input string + * + * @param text + * The search text + */ + public void setSearchText(String text) { + fSearchText.setText(text); + } + + /** + * Set the stop check button state + * + * @param state + * The new state to set + */ + public void setStopButtonSelection(boolean state) { + if (fStopButton != null) { + fStopButton.setSelection(state); + } + } + + /** + * Set the synchronous message check button state + * + * @param state + * The new state to set + */ + public void setSynMessageButtonSelection(boolean state) { + if (fSynMessageButton != null) { + fSynMessageButton.setSelection(state); + } + } + + /** + * Set the synchronous message return check button state + * + * @param state + * The new state to set + */ + public void setSynMessageReturnButtonSelection(boolean state) { + if (fSynMessageReturnButton != null) { + fSynMessageReturnButton.setSelection(state); + } + } + + // ------------------------------------------------------------------------ + // Helper classes + // ------------------------------------------------------------------------ + + /** + * Selection listener implementation for graph node types. + * @version 1.0 + */ + protected class GraphNodeTypeListener implements SelectionListener { + @Override + public void widgetDefaultSelected(SelectionEvent e) { + // Nothing to do + } + + @Override + public void widgetSelected(SelectionEvent e) { + updateOkButton(); + } + } + + /** + * Modify listener implementation for the expression field. + * + * @version 1.0 + */ + protected class ExpressionListener implements ModifyListener { + @Override + public void modifyText(ModifyEvent e) { + updateOkButton(); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/IColor.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/IColor.java new file mode 100755 index 0000000000..2b5e2e1bf7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/IColor.java @@ -0,0 +1,36 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings; + +/** + * Interface for handling a color resource. + * + * @version 1.0 + * @author sveyrier + */ +public interface IColor { + + /** + * Returns the contained color. Returned object must be an instance of org.eclipse.swt.graphics.Color if used with + * the org.eclipse.linuxtools.tmf.ui.views.uml2sd.NGC graphical context + * + * @return the color + */ + Object getColor(); + + /** + * Disposes the color + */ + void dispose(); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/IFont.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/IFont.java new file mode 100755 index 0000000000..c2196e06af --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/IFont.java @@ -0,0 +1,36 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings; + +/** + * Interface for handling a font resource. + * + * @version 1.0 + * @author sveyrier + */ +public interface IFont { + + /** + * Returns the contained font. Returned object must be an instance of org.eclipse.swt.graphics.Font if used with the + * org.eclipse.linuxtools.tmf.ui.views.uml2sd.NGC graphical context + * + * @return the font + */ + Object getFont(); + + /** + * Disposes the font + */ + void dispose(); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/IGC.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/IGC.java new file mode 100755 index 0000000000..c26bb5ceed --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/IGC.java @@ -0,0 +1,375 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings; + +/** + * Interface for a graphical context. + * + * @version 1.0 + * @author sveyrier + * + */ +public interface IGC { + + /** + * Set the current line style + * + * @param style the new line style + */ + void setLineStyle(int style); + + /** + * Returns current the line style used in the graphical context + * + * @return the current line style + */ + int getLineStyle(); + + /** + * Returns the contents x coordinate that is at the upper left corner of the view + * + * @return the contents x coordinate + */ + int getContentsX(); + + /** + * Returns the contents y coordinate that is at the upper left corner of the view + * + * @return the contents y coordinate + */ + int getContentsY(); + + /** + * Returns the contents visible width + * + * @return the contents width + */ + int getVisibleWidth(); + + /** + * Returns the contents visible height + * + * @return the contents height + */ + int getVisibleHeight(); + + /** + * Translates the given contents x coordinate into view x coordinate + * + * @param x the x coordinate to translate + * @return the corresponding view x coordinate + */ + int contentsToViewX(int x); + + /** + * Translates the given contents y coordinate into view y coordinate + * + * @param y the y coordinate to translate + * @return the corresponding view y coordinate + */ + int contentsToViewY(int y); + + /** + * Draws a line, using the foreground color, between the points (x1, y1) and (x2, y2). + * + * @param x1 the first point's x coordinate + * @param y1 the first point's y coordinate + * @param x2 the second point's x coordinate + * @param y2 the second point's y coordinate + */ + void drawLine(int x1, int y1, int x2, int y2); + + /** + * Draws the outline of the rectangle specified by the arguments, using the receiver's foreground color. The left + * and right edges of the rectangle are at x and x + width. The top and bottom edges are at y and y + height. + * + * @param x the x coordinate of the rectangle to be drawn + * @param y the y coordinate of the rectangle to be drawn + * @param width the width of the rectangle to be drawn + * @param height the height of the rectangle to be drawn + */ + void drawRectangle(int x, int y, int width, int height); + + /** + * Draws a rectangle, based on the specified arguments, which has the appearance of the platform's focus rectangle + * if the platform supports such a notion, and otherwise draws a simple rectangle in the receiver's foreground + * color. + * + * @param x the x coordinate of the rectangle + * @param y the y coordinate of the rectangle + * @param width the width of the rectangle + * @param height the height of the rectangle + */ + void drawFocus(int x, int y, int width, int height); + + /** + * Fills the interior of the closed polygon which is defined by the specified array of integer coordinates, using + * the receiver's background color. The array contains alternating x and y values which are considered to represent + * points which are the vertices of the polygon. Lines are drawn between each consecutive pair, and between the + * first pair and last pair in the array. + * + * @param points an array of alternating x and y values which are the vertices of the polygon + */ + void fillPolygon(int[] points); + + /** + * Draws the closed polygon which is defined by the specified array of integer coordinates, using the receiver's + * foreground color. The array contains alternating x and y values which are considered to represent points which + * are the vertices of the polygon. Lines are drawn between each consecutive pair, and between the first pair and + * last pair in the array. + * + * @param points an array of alternating x and y values which are the vertices of the polygon + */ + void drawPolygon(int[] points); + + /** + * Fills the interior of the rectangle specified by the arguments, using the receiver's background color. + * + * @param x the x coordinate of the rectangle to be filled + * @param y the y coordinate of the rectangle to be filled + * @param width the width of the rectangle to be filled + * @param height the height of the rectangle to be filled + */ + void fillRectangle(int x, int y, int width, int height); + + /** + * Fills the interior of the specified rectangle with a gradient sweeping from left to right or top to bottom + * progressing from the graphical context gradient color to its background color. + * + * @param x the x coordinate of the rectangle to be filled + * @param y the y coordinate of the rectangle to be filled + * @param width the width of the rectangle to be filled, may be negative (inverts direction of gradient if + * horizontal) + * @param height the height of the rectangle to be filled, may be negative (inverts direction of gradient if + * horizontal) + * @param vertical if true sweeps from top to bottom, else sweeps from left to right + */ + void fillGradientRectangle(int x, int y, int width, int height, boolean vertical); + + /** + * Returns the given string width in pixels + * + * @param name the string + * @return the string width + */ + int textExtent(String name); + + /** + * Draws the given string, using the receiver's current font and foreground color. Tab expansion and carriage return + * processing are performed. If trans is true, then the background of the rectangular area where the text is being + * drawn will not be modified, otherwise it will be filled with the receiver's background color. + * + * @param string the string to be drawn + * @param x the x coordinate of the top left corner of the rectangular area where the text is to be drawn + * @param y the y coordinate of the top left corner of the rectangular area where the text is to be drawn + * @param trans if true the background will be transparent, otherwise it will be opaque + */ + void drawText(String string, int x, int y, boolean trans); + + /** + * Draws the given string, using the receiver's current font and foreground color. Tab expansion and carriage return + * processing are performed. The background of the rectangular area where the text is being drawn will be filled + * with the receiver's background color. + * + * @param string the string to be drawn + * @param x the x coordinate of the top left corner of the rectangular area where the text is to be drawn + * @param y the y coordinate of the top left corner of the rectangular area where the text is to be drawn + */ + void drawText(String string, int x, int y); + + /** + * Fills the interior of an oval, within the specified rectangular area, with the receiver's background color. + * + * @param x the x coordinate of the upper left corner of the oval to be filled + * @param y the y coordinate of the upper left corner of the oval to be filled + * @param width the width of the oval to be filled + * @param height the width of the oval to be filled + */ + void fillOval(int x, int y, int width, int height); + + /** + * Returns current the background color used in the graphical context + * + * @return the background color + */ + IColor getBackground(); + + /** + * Returns current the background color used in the graphical context + * + * @return the background color + */ + IColor getForeground(); + + /** + * Set the graphical context foreground color + * + * @param color the foreground color + */ + void setBackground(IColor color); + + /** + * Set the graphical context background color + * + * @param color the background color + */ + void setForeground(IColor color); + + /** + * Set the color to use when filling regions using gradient. The color will progess from the given color to the + * current background color + * + * @param color the gardiient color to use + */ + void setGradientColor(IColor color); + + /** + * Set the line width to use for drawing + * + * @param width the line width + */ + void setLineWidth(int width); + + /** + * Returns the current graphical context line width used for drawing + * + * @return the line width + */ + int getLineWidth(); + + /** + * Returns the LineDotD style constant + * + * @return the constant value + */ + int getLineDotStyle(); + + /** + * Returns the LineDash style constant + * + * @return the constant + */ + int getLineDashStyle(); + + /** + * Returns the LineSolid style constant + * + * @return the constant + */ + int getLineSolidStyle(); + + /** + * Draws the given string centered into the given rectangle. If the string cannot fit in the rectangle area, the + * string is truncated. If trans is true, then the background of the rectangular area where the text is being drawn + * will not be modified, otherwise it will be filled with the receiver's background color. + * + * @param name the string to draw + * @param x the x coordinate of the rectangle to draw the string + * @param y the y coordinate of the rectangle to draw the string + * @param width the width of the rectangle to draw the string + * @param height the height of the rectangle to draw the string + * @param trans if true the background will be transparent, otherwise it will be opaque + */ + void drawTextTruncatedCentred(String name, int x, int y, int width, int height, boolean trans); + + /** + * Draws the given string into the given rectangle (left justify) If the string cannot fit in the rectangle area, + * the string is truncated. If trans is true, then the background of the rectangular area where the text is being + * drawn will not be modified, otherwise it will be filled with the receiver's background color. + * + * @param name The text to put in the rectangle + * @param x the x coordinate of the rectangle to draw the string + * @param y the y coordinate of the rectangle to draw the string + * @param width the width of the rectangle to draw the string + * @param height the height of the rectangle to draw the string + * @param trans if true the background will be transparent, otherwise it will be opaque + */ + void drawTextTruncated(String name, int x, int y, int width, int height, boolean trans); + + /** + * Copies a the source image into a (potentially different sized) rectangular area in the graphical context. If the + * source image has smaller sizes, then the source area will be stretched to fit the destination area as it is + * copied. + * + * @param image the image to draw + * @param x the x coordinate in the destination to copy to + * @param y the y coordinate in the destination to copy to + * @param maxWith the width in pixels of the destination rectangle + * @param maxHeight the height in pixels of the destination rectangle + */ + void drawImage(IImage image, int x, int y, int maxWith, int maxHeight); + + /** + * Draws the outline of a circular or elliptical arc within the specified rectangular area. The resulting arc begins + * at startAngle and extends for arcAngle degrees, using the current color. Angles are interpreted such that 0 + * degrees is at the 3 o'clock position. A positive value indicates a counter-clockwise rotation while a negative + * value indicates a clockwise rotation. The center of the arc is the center of the rectangle whose origin is (x, y) + * and whose size is specified by the width and height arguments. The resulting arc covers an area width + 1 pixels + * wide by height + 1 pixels tall. + * + * @param x the x coordinate of the upper-left corner of the arc to be drawn + * @param y the y coordinate of the upper-left corner of the arc to be drawn + * @param width the width of the arc to be drawn + * @param height the height of the arc to be drawn + * @param startAngle the beginning angle + * @param endAngle the ending angle + */ + void drawArc(int x, int y, int width, int height, int startAngle, int endAngle); + + /** + * Set the current font used in the graphical context + * + * @param font the font to use + */ + void setFont(IFont font); + + /** + * Returns the font height given font + * + * @param font The font to check for + * @return the the font height + */ + int getFontHeight(IFont font); + + /** + * Returns the average character width for the given font + * + * @param font The font to check for + * @return the average width + */ + int getFontWidth(IFont font); + + /** + * Creates a color with the given RGB values + * + * @param r the red component + * @param g the green component + * @param b the blue component + * @return the color + */ + IColor createColor(int r, int g, int b); + + /** + * Returns the zoom factor applied in both x and y directions when drawing + * + * @return the zoom factor + */ + float getZoom(); + + /** + * Draws text with focus style. + * + * @param focus true if item has focus else false + */ + void setDrawTextWithFocusStyle(boolean focus); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/IImage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/IImage.java new file mode 100755 index 0000000000..eac7ee28ff --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/IImage.java @@ -0,0 +1,37 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings; + +/** + * Interface for handling a image resource. + * + * @version 1.0 + * @author sveyrier + * + */ +public interface IImage { + + /** + * Returns the contained image. Returned object must be an instance of org.eclipse.swt.graphics.Image if used with + * the org.eclipse.linuxtools.tmf.ui.views.uml2sd.NGC graphical context + * + * @return the color + */ + Object getImage(); + + /** + * Disposes the image + */ + void dispose(); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/impl/ColorImpl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/impl/ColorImpl.java new file mode 100755 index 0000000000..25b5a689ac --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/impl/ColorImpl.java @@ -0,0 +1,92 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.impl; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IColor; + +/** + * Default implementation of the IColor interface. + * + * @version 1.0 + * @author sveyrier + * + */ +public class ColorImpl implements IColor { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The color object. + */ + private final Color fColor; + /** + * Flag to indicate that this object is managing the resource. + */ + private boolean fManageColor = true; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Constructor + * + * @param display The display to use + * @param r A value for red + * @param g A value for green + * @param b A value for blue + */ + public ColorImpl(Display display, int r, int g, int b) { + fColor = new Color(display, r, g, b); + } + + /** + * Copy constructor + * + * @param color + * A color to copy + */ + protected ColorImpl(Color color) { + fColor = color; + fManageColor = false; + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + /** + * Returns a system color. + * + * @param color The color ID + * @return a system color + */ + public static ColorImpl getSystemColor(int color) { + return new ColorImpl(Display.getDefault().getSystemColor(color)); + } + + @Override + public Object getColor() { + return fColor; + } + + @Override + public void dispose() { + if ((fColor != null) && (fManageColor)) { + fColor.dispose(); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/impl/FontImpl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/impl/FontImpl.java new file mode 100755 index 0000000000..1b1cbcf890 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/impl/FontImpl.java @@ -0,0 +1,89 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.impl; + +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IFont; + +/** + * Default implementation of the IFont interface. + * + * @version 1.0 + * @author sveyrier + * + */ +public class FontImpl implements IFont { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The font object + */ + private final Font fFont; + /** + * Flag to indicate that this object is managing the resource. + */ + protected boolean fManageFont = true; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor. + * + * @param display The display to use + * @param data A font data + */ + public FontImpl(Display display, FontData data) { + fFont = new Font(display, data); + } + + /** + * Copy constructor + * + * @param value A font to copy. + */ + protected FontImpl(Font value) { + fFont = value; + fManageFont = false; + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + /** + * Returns a font implementation based system font. + * + * @return a font implementation based system font. + */ + public static FontImpl getSystemFont() { + return new FontImpl(Display.getDefault().getSystemFont()); + } + + @Override + public Object getFont() { + return fFont; + } + + @Override + public void dispose() { + if (fFont != null) { + fFont.dispose(); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/impl/ImageImpl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/impl/ImageImpl.java new file mode 100755 index 0000000000..5637b88981 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/drawings/impl/ImageImpl.java @@ -0,0 +1,105 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.impl; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Image; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IImage; + +/** + * Default implementation of the IImage interface. + * + * @version 1.0 + * @author sveyrier + * + */ +public class ImageImpl implements IImage { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The image reference + */ + private final Image fImage; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor. + * + * @param file A file name of image file. + */ + public ImageImpl(String file) { + fImage = createResourceImage(file); + } + + /** + * Copy constructor + * + * @param image THe image to copy + */ + public ImageImpl(Image image) { + fImage = image; + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + /** + * Returns Image object from file name. + * + * @param name File name of image file + * @return image object or null + */ + public Image getResourceImage(String name) { + return createResourceImage(name); + } + + @Override + public Object getImage() { + return fImage; + } + + @Override + public void dispose() { + if (fImage != null) { + fImage.dispose(); + } + } + + /** + * Returns Image object from file name. + * + * @param name File name of image file + * @return image object or null + */ + private static Image createResourceImage(String name) { + try { + URL BASIC_URL = new URL("platform", "localhost", "plugin");//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + URL url = new URL(BASIC_URL, "plugin/org.eclipse.linuxtools.tmf.ui/icons/" + name);//$NON-NLS-1$ + ImageDescriptor img = ImageDescriptor.createFromURL(url); + return img.createImage(); + } catch (MalformedURLException e) { + Activator.getDefault().logError("Error opening image file", e); //$NON-NLS-1$ + } + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/BaseSDAction.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/BaseSDAction.java new file mode 100644 index 0000000000..e45fd20d28 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/BaseSDAction.java @@ -0,0 +1,89 @@ +/********************************************************************** + * Copyright (c) 2013 Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import org.eclipse.jface.action.Action; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; + +/** + * Base class for sequence diagram actions. + * + * @author Bernd Hufmann + * @since 2.0 + */ +public class BaseSDAction extends Action { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The sequence diagram view reference. + */ + private SDView fView = null; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor + */ + public BaseSDAction() { + this(null); + } + + /** + * Constructor + * + * @param view + * a sequence diagram view reference + */ + public BaseSDAction(SDView view) { + super(); + fView = view; + } + + /** + * Constructor + * @param view + * a sequence diagram view reference + * @param text + * The action text + * @param style + * The style + */ + protected BaseSDAction(SDView view, String text, int style) { + super(text, style); + fView = view; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Sets the active SD view. + * + * @param view The SD view. + */ + public void setView(SDView view) { + fView = view; + } + + /** + * Gets the active SD view. + * + * @return view The SD view. + * @since 2.0 + */ + public SDView getView() { + return fView; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/ConfigureMinMax.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/ConfigureMinMax.java new file mode 100755 index 0000000000..21ee20f259 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/ConfigureMinMax.java @@ -0,0 +1,46 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.MinMaxDialog; + +/** + * Action class implementation to configure minimum and maximum time range values. + * + * @version 1.0 + * @author sveyrier + * + */ +public class ConfigureMinMax extends BaseSDAction { + + /** + * Constructor + * @param view + * the sequence diagram view reference + * @since 2.0 + */ + public ConfigureMinMax(SDView view) { + super(view); + } + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + @Override + public void run() { + if ((getView() != null) && (getView().getSDWidget() != null)) { + MinMaxDialog minMax = new MinMaxDialog(getView().getSite().getShell(), getView().getSDWidget()); + minMax.open(); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/FirstPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/FirstPage.java new file mode 100644 index 0000000000..33476c7dc0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/FirstPage.java @@ -0,0 +1,68 @@ +/********************************************************************** + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; + +/** + * Action class implementation to move the focus to the first page of the whole sequence diagram. + * + * @version 1.0 + * @author Bernd Hufmann + */ +public class FirstPage extends BaseSDAction { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The action ID. + */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.firstpage"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor + * + * @param view the view reference + */ + public FirstPage(SDView view) { + super(view); + setText(Messages.SequenceDiagram_FirstPage); + setToolTipText(Messages.SequenceDiagram_GoToFirstPage); + setId(ID); + setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FIRST_PAGE)); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public void run() { + if ((getView() == null) || (getView().getSDWidget()) == null) { + return; + } + if (getView().getSDPagingProvider() != null) { + getView().getSDPagingProvider().firstPage(); + } + getView().updateCoolBar(); + getView().getSDWidget().redraw(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/KeyBindingsManager.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/KeyBindingsManager.java new file mode 100644 index 0000000000..c4e9c8d3ae --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/KeyBindingsManager.java @@ -0,0 +1,302 @@ +/********************************************************************** + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.IHandlerActivation; +import org.eclipse.ui.handlers.IHandlerService; + +/** + *

    + * Singleton class that manages key-bindings for certain commands across multiple sequence + * diagram view instances. + *

    + * + * @version 1.0 + * @author Bernd Hufmann + * + */ +public class KeyBindingsManager { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The singleton instance. + */ + private static KeyBindingsManager fInstance = null; + /** + * The list of view names. + */ + private Set fViews = new HashSet<>(); + /** + * The list of activations Activations to store + */ + private List fHandlerActivations = new ArrayList<>(); + /** + * The action reference for moving to a message in view. + */ + private MoveToMessage fGoToMessageForKeyBinding; + /** + * The action reference for opening the find dialog. + */ + private OpenSDFindDialog fFindForKeyBinding; + /** + * The action reference for moving up in view. + */ + private MoveSDUp fMoveUpForKeyBinding; + /** + * The action reference for moving down in view. + */ + private MoveSDDown fMoveDownForKeyBinding; + /** + * The action reference for moving left in view. + */ + private MoveSDLeft fMoveLeftForKeyBinding; + /** + * The action reference for moving right in view. + */ + private MoveSDRight fMoveRightForKeyBinding; + /** + * The action reference for showing node start. + */ + private ShowNodeStart fShowNodeStartForKeyBinding; + /** + * The action reference for showing node end. + */ + private ShowNodeEnd fShowNodeEndForKeyBinding; + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Constructor + */ + protected KeyBindingsManager() { + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + /** + * Returns the KeyBindingsManager singleton instance. + * + * @return the KeyBindingsManager singleton instance + */ + public static synchronized KeyBindingsManager getInstance() { + if (fInstance == null) { + fInstance = new KeyBindingsManager(); + } + return fInstance; + } + + /** + * Adds a view list of managed view list. + * + * @param viewId Id of SD view to add and to manage + */ + public void add(String viewId) { + + if (fViews.isEmpty()) { + initialize(); + } + + if(!fViews.contains(viewId)) { + fViews.add(viewId); + } + } + + /** + * Removes a view from managed view list + * + * @param viewId Id of SD view to remove + */ + public void remove(String viewId) { + if (fViews.contains(viewId)) { + fViews.remove(viewId); + } + if (fViews.isEmpty()) { + dispose(); + } + } + + /* + * Initialized the KeyBindingsManager. + */ + private void initialize() { + fGoToMessageForKeyBinding = new MoveToMessage(); + IHandlerService service = (IHandlerService) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getService(IHandlerService.class); + AbstractHandler handler = new AbstractHandler() { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + fGoToMessageForKeyBinding.run(); + return null; + } + }; + IHandlerActivation activation = service.activateHandler(fGoToMessageForKeyBinding.getActionDefinitionId(), handler); + fHandlerActivations.add(activation); + + fMoveUpForKeyBinding = new MoveSDUp(); + handler = new AbstractHandler() { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + fMoveUpForKeyBinding.run(); + return null; + } + }; + activation = service.activateHandler(fMoveUpForKeyBinding.getActionDefinitionId(), handler); + fHandlerActivations.add(activation); + + fMoveDownForKeyBinding = new MoveSDDown(); + handler = new AbstractHandler() { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + fMoveDownForKeyBinding.run(); + return null; + } + }; + activation = service.activateHandler(fMoveDownForKeyBinding.getActionDefinitionId(), handler); + fHandlerActivations.add(activation); + + fMoveLeftForKeyBinding = new MoveSDLeft(); + handler = new AbstractHandler() { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + fMoveLeftForKeyBinding.run(); + return null; + } + }; + activation = service.activateHandler(fMoveLeftForKeyBinding.getActionDefinitionId(), handler); + fHandlerActivations.add(activation); + + fMoveRightForKeyBinding = new MoveSDRight(); + handler = new AbstractHandler() { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + fMoveRightForKeyBinding.run(); + return null; + } + }; + activation = service.activateHandler(fMoveRightForKeyBinding.getActionDefinitionId(), handler); + fHandlerActivations.add(activation); + + fFindForKeyBinding = new OpenSDFindDialog(); + handler = new AbstractHandler() { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + fFindForKeyBinding.run(); + return null; + } + }; + activation = service.activateHandler(fFindForKeyBinding.getActionDefinitionId(), handler); + fFindForKeyBinding.setEnabled(false); + fHandlerActivations.add(activation); + + fShowNodeStartForKeyBinding = new ShowNodeStart(); + fShowNodeStartForKeyBinding.setText(Messages.SequenceDiagram_ShowNodeStart); + + fShowNodeStartForKeyBinding.setId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ShowNodeStart");//$NON-NLS-1$ + fShowNodeStartForKeyBinding.setActionDefinitionId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ShowNodeStart");//$NON-NLS-1$ + + handler = new AbstractHandler() { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + fShowNodeStartForKeyBinding.run(); + return null; + } + }; + activation = service.activateHandler(fShowNodeStartForKeyBinding.getActionDefinitionId(), handler); + fHandlerActivations.add(activation); + + fShowNodeEndForKeyBinding = new ShowNodeEnd(); + fShowNodeEndForKeyBinding.setText(Messages.SequenceDiagram_ShowNodeEnd); + fShowNodeEndForKeyBinding.setId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ShowNodeEnd");//$NON-NLS-1$ + fShowNodeEndForKeyBinding.setActionDefinitionId("org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ShowNodeEnd");//$NON-NLS-1$ + + handler = new AbstractHandler() { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + fShowNodeEndForKeyBinding.run(); + return null; + } + }; + activation = service.activateHandler(fShowNodeEndForKeyBinding.getActionDefinitionId(), handler); + fHandlerActivations.add(activation); + + } + + /* + * Disposes the KeyBindingsManager + */ + private void dispose() { + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + //During Eclipse shutdown the active workbench window is null + return; + } + IHandlerService service = (IHandlerService) window.getService(IHandlerService.class); + for(IHandlerActivation activation : fHandlerActivations) { + service.deactivateHandler(activation); + } + + fGoToMessageForKeyBinding = null; + fFindForKeyBinding = null; + fMoveUpForKeyBinding = null; + fMoveDownForKeyBinding = null; + fMoveLeftForKeyBinding = null; + fMoveRightForKeyBinding = null; + fShowNodeStartForKeyBinding = null; + fShowNodeEndForKeyBinding = null; + } + + /** + * Set the view in all supported actions + * + * @param view to set in global actions + */ + public void setSdView(SDView view) { + if (!fViews.isEmpty()) { + fGoToMessageForKeyBinding.setView(view); + fFindForKeyBinding.setView(view); + fMoveUpForKeyBinding.setView(view); + fMoveDownForKeyBinding.setView(view); + fMoveLeftForKeyBinding.setView(view); + fMoveRightForKeyBinding.setView(view); + fShowNodeStartForKeyBinding.setView(view); + fShowNodeEndForKeyBinding.setView(view); + } + } + + /** + * Enable / disable find action + * + * @param enabled true for enabling else false + */ + public void setFindEnabled(boolean enabled) { + if (fFindForKeyBinding != null) { + fFindForKeyBinding.setEnabled(enabled); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/LastPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/LastPage.java new file mode 100644 index 0000000000..4dacc9f7ff --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/LastPage.java @@ -0,0 +1,68 @@ +/********************************************************************** + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; + +/** + * Action class implementation to move the focus to the last page of the whole sequence diagram. + * + * @version 1.0 + * @author Bernd Hufmann + */ +public class LastPage extends BaseSDAction { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The action ID. + */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.lastpage"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Standard constructor + * + * @param view the view reference + */ + public LastPage(SDView view) { + super(view); + setText(Messages.SequenceDiagram_LastPage); + setToolTipText(Messages.SequenceDiagram_GoToLastPage); + setId(ID); + setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_LAST_PAGE)); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public void run() { + if ((getView() == null) || (getView().getSDWidget()) == null) { + return; + } + if (getView().getSDPagingProvider() != null) { + getView().getSDPagingProvider().lastPage(); + } + getView().updateCoolBar(); + getView().getSDWidget().redraw(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveSDDown.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveSDDown.java new file mode 100755 index 0000000000..44f965d3ce --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveSDDown.java @@ -0,0 +1,70 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget; + +/** + * Action class implementation to move down in the sequence diagram view within a page. + * + * @version 1.0 + * @author sveyrier + * + */ +public class MoveSDDown extends BaseSDAction { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The action ID. + */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.MoveSDDown"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor + */ + public MoveSDDown() { + this(null); + } + + /** + * Constructor + * + * @param view a sequence diagram view reference + */ + public MoveSDDown(SDView view) { + super(view); + setId(ID); + setActionDefinitionId(ID); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + @Override + public void run() { + if (getView() == null) { + return; + } + + SDWidget viewer = getView().getSDWidget(); + if (viewer != null) { + viewer.scrollBy(0, +viewer.getVisibleHeight()); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveSDLeft.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveSDLeft.java new file mode 100755 index 0000000000..1ce3220436 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveSDLeft.java @@ -0,0 +1,72 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget; + +/** + * Action class implementation to move left in the sequence diagram view within a page. + * + * @version 1.0 + * @author sveyrier + * + */ +public class MoveSDLeft extends BaseSDAction { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The action ID. + */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.MoveSDLeft"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor + */ + public MoveSDLeft(){ + this(null); + } + + /** + * Constructor + * + * @param view a sequence diagram view reference + */ + public MoveSDLeft(SDView view) { + super(view); + setId(ID); + setActionDefinitionId(ID); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Override + public void run() { + + if (getView() == null) { + return; + } + + SDWidget viewer = getView().getSDWidget(); + if (viewer != null) { + viewer.scrollBy(-viewer.getVisibleWidth(), 0); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveSDRight.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveSDRight.java new file mode 100755 index 0000000000..ce2a3cec7f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveSDRight.java @@ -0,0 +1,73 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget; + +/** + * Action class implementation to move right in the sequence diagram view within a page. + * + * @version 1.0 + * @author sveyrier + * + */ + +public class MoveSDRight extends BaseSDAction { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The action ID. + */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.MoveSDRight"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor + */ + public MoveSDRight() { + this(null); + } + + /** + * Constructor + * + * @param view a sequence diagram view reference + */ + public MoveSDRight(SDView view) { + super(view); + setId(ID); + setActionDefinitionId(ID); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public void run() { + + if (getView() == null) { + return; + } + + SDWidget viewer = getView().getSDWidget(); + if (viewer != null) { + viewer.scrollBy(+viewer.getVisibleWidth(), 0); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveSDUp.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveSDUp.java new file mode 100755 index 0000000000..f10c1dd16f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveSDUp.java @@ -0,0 +1,71 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget; + +/** + * Action class implementation to move up in the sequence diagram view within a + * page. + * + * @version 1.0 + * @author sveyrier + */ +public class MoveSDUp extends BaseSDAction { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The action ID. + */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.MoveSDUp"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor + */ + public MoveSDUp() { + this(null); + } + + /** + * Constructor + * + * @param view a sequence diagram view reference + */ + public MoveSDUp(SDView view) { + super(view); + setId(ID); + setActionDefinitionId(ID); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public void run() { + if (getView() == null) { + return; + } + SDWidget viewer = getView().getSDWidget(); + + if (viewer != null) { + viewer.scrollBy(0, -viewer.getVisibleHeight()); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveToMessage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveToMessage.java new file mode 100755 index 0000000000..2b8438eea6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/MoveToMessage.java @@ -0,0 +1,113 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import java.util.Iterator; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.BaseMessage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SyncMessage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SyncMessageReturn; + +/** + * Action Class implementation to move to selected message + * + * @version 1.0 + * @author sveyrier + * + */ +public class MoveToMessage extends BaseSDAction { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The action ID. + */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.GoToMessage"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default Constructor + */ + public MoveToMessage() { + this(null); + } + + /** + * Constructor + * + * @param view a sequence diagram view reference + */ + public MoveToMessage(SDView view) { + super(view); + setId(ID); + setActionDefinitionId(ID); + setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SEARCH_MATCH)); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public void run() { + if (getView() == null) { + return; + } + + SDWidget sdWidget = getView().getSDWidget(); + + if (sdWidget == null) { + return; + } + + ISelectionProvider selProvider = sdWidget.getSelectionProvider(); + ISelection sel = selProvider.getSelection(); + Object selectedNode = null; + Iterator it = ((StructuredSelection) sel).iterator(); + while (it.hasNext()) { + Object node = it.next(); + if (node instanceof BaseMessage) { + selectedNode = node; + } + } + + if (selectedNode == null) { + return; + } + + if (selectedNode instanceof SyncMessageReturn) { + GraphNode node = ((SyncMessageReturn) selectedNode).getMessage(); + sdWidget.clearSelection(); + sdWidget.addSelection(node); + sdWidget.ensureVisible(node); + sdWidget.redraw(); + } else if (selectedNode instanceof SyncMessage) { + GraphNode node = ((SyncMessage) selectedNode).getMessageReturn(); + sdWidget.clearSelection(); + sdWidget.addSelection(node); + sdWidget.ensureVisible(node); + sdWidget.redraw(); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/NextPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/NextPage.java new file mode 100755 index 0000000000..2518ab9e5e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/NextPage.java @@ -0,0 +1,68 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; + +/** + * Action class implementation to move the focus to the next page of the whole sequence diagram. + * + * @version 1.0 + * @author sveyrier + * + */ +public class NextPage extends BaseSDAction { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The action ID. + */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.nextpage"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor + * + * @param view the view reference + */ + public NextPage(SDView view) { + super(view); + setText(Messages.SequenceDiagram_NextPage); + setToolTipText(Messages.SequenceDiagram_GoToNextPage); + setId(ID); + setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_PAGE)); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Override + public void run() { + if ((getView() == null) || (getView().getSDWidget()) == null) { + return; + } + if (getView().getSDPagingProvider() != null) { + getView().getSDPagingProvider().nextPage(); + } + getView().updateCoolBar(); + getView().getSDWidget().redraw(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/OpenSDFiltersDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/OpenSDFiltersDialog.java new file mode 100755 index 0000000000..7afaf6f5cf --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/OpenSDFiltersDialog.java @@ -0,0 +1,75 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.FilterListDialog; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDFilterProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; + +/** + * Action class implementation for 'Filtering' of messages/lifelines. + * + * @version 1.0 + * @author sveyrier + */ +public class OpenSDFiltersDialog extends BaseSDAction { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The action ID. + */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.sdFilters"; //$NON-NLS-1$ + + /** + * The filter provider reference + */ + private final ISDFilterProvider fProvider; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Constructor + * + * @param view + * The view reference + * @param provider + * The provider + */ + public OpenSDFiltersDialog(SDView view, ISDFilterProvider provider) { + super(view); + setText(Messages.SequenceDiagram_HidePatterns); + setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FILTERS)); + setId(ID); + setToolTipText(Messages.SequenceDiagram_HidePatterns); + fProvider = provider; + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public void run() { + if (getView() == null) { + return; + } + FilterListDialog dialog = new FilterListDialog(getView(), fProvider); + dialog.open(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/OpenSDFindDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/OpenSDFindDialog.java new file mode 100755 index 0000000000..0bfce393ca --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/OpenSDFindDialog.java @@ -0,0 +1,93 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import org.eclipse.swt.SWT; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.SearchFilterDialog; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; + +/** + * Action class implementation for 'Finding' of messages/lifelines. + * + * @version 1.0 + * @author sveyrier + * + */ +public class OpenSDFindDialog extends BaseSDAction { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The action ID. + */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.sdFind"; //$NON-NLS-1$ + + /** + * The action definition ID. + */ + public static final String ACTION_DEFINITION_ID = "org.eclipse.ui.edit.findReplace"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor + */ + public OpenSDFindDialog() { + this(null); + } + + /** + * Constructor + * + * @param view The view reference + */ + public OpenSDFindDialog(SDView view) { + super(view); + setText(Messages.SequenceDiagram_Find + "..."); //$NON-NLS-1$ + setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SEARCH_SEQ)); + setId(ID); + setActionDefinitionId(ACTION_DEFINITION_ID); + setToolTipText(Messages.SequenceDiagram_Find + "..."); //$NON-NLS-1$ + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public void run() { + if (getView() == null) { + return; + } + + // Disable action while search is ongoing + this.setEnabled(false); + + try { + if ((getView().getExtendedFindProvider() != null) && (getView().getExtendedFindProvider().getFindAction() != null)) { + getView().getExtendedFindProvider().getFindAction().run(); + } else if (getView().getSDFindProvider() != null) { + SearchFilterDialog dialog = new SearchFilterDialog(getView(), getView().getSDFindProvider(), false, SWT.NORMAL); + dialog.open(); + } + } finally { + // Enable action after finishing the search + this.setEnabled(true); + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/OpenSDPagesDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/OpenSDPagesDialog.java new file mode 100755 index 0000000000..e7145f3252 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/OpenSDPagesDialog.java @@ -0,0 +1,80 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.PagesDialog; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDAdvancedPagingProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; + +/** + * Action class implementation for paging. + * + * @version 1.0 + * @author Bernd Hufmann + */ +public class OpenSDPagesDialog extends BaseSDAction { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The action ID. + */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.sdPaging"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The advanced paging provider reference. + */ + private final ISDAdvancedPagingProvider fProvider; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructor + * + * @param view + * The view reference + * @param provider + * The provider + */ + public OpenSDPagesDialog(SDView view, ISDAdvancedPagingProvider provider) { + super(view); + setText(Messages.SequenceDiagram_Pages); + setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_GOTO_PAGE)); + setId(ID); + fProvider = provider; + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Override + public void run() { + if (getView() == null) { + return; + } + PagesDialog dialog = new PagesDialog(getView(), fProvider); + dialog.open(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/PrevPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/PrevPage.java new file mode 100755 index 0000000000..741d06f329 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/PrevPage.java @@ -0,0 +1,70 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; + +/** + * Action class implementation to move the focus to the previous page of the whole sequence diagram. + * + * @version 1.0 + * @author sveyrier + * + */ +public class PrevPage extends BaseSDAction { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The action ID. + */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.prevpage"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor + * + * @param view the view reference + */ + public PrevPage(SDView view) { + super(view); + setText(Messages.SequenceDiagram_PreviousPage); + setToolTipText(Messages.SequenceDiagram_GoToPreviousPage); + setId(ID); + setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_PAGE)); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public void run() { + if ((getView() == null) || (getView().getSDWidget()) == null) { + return; + } + if (getView().getSDPagingProvider() != null) { + getView().getSDPagingProvider().prevPage(); + } + getView().updateCoolBar(); + getView().getSDWidget().redraw(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/Print.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/Print.java new file mode 100755 index 0000000000..433d4d4e03 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/Print.java @@ -0,0 +1,60 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; + +/** + * Action class implementation for 'Printing'. + * + * @version 1.0 + * @author sveyrier + */ +public class Print extends BaseSDAction { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * The action ID. + */ + public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.print"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructor + * + * @param view The view reference + */ + public Print(SDView view) { + super(view); + setId(ID); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public void run() { + if ((getView() == null) || getView().getSDWidget() == null){ + return; + } + + getView().getSDWidget().print(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/ShowNodeEnd.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/ShowNodeEnd.java new file mode 100755 index 0000000000..901bba59c7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/ShowNodeEnd.java @@ -0,0 +1,89 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import java.util.Iterator; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode; + +/** + * Action class implementation to show end of a graph node. + * + * @version 1.0 + * @author sveyrier + */ +public class ShowNodeEnd extends BaseSDAction { + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor + */ + public ShowNodeEnd() { + this(null); + } + + /** + * Constructor + * + * @param view The sequence diagram view reference + * @since 2.0 + */ + public ShowNodeEnd(SDView view) { + super(view); + setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NODE_END)); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + @Override + public void run() { + if (getView() == null) { + return; + } + + SDWidget sdWidget = getView().getSDWidget(); + + if (sdWidget == null) { + return; + } + + ISelectionProvider selProvider = sdWidget.getSelectionProvider(); + ISelection sel = selProvider.getSelection(); + Object selectedNode = null; + + Iterator it = ((StructuredSelection) sel).iterator(); + while (it.hasNext()) { + selectedNode = it.next(); + } + + if (selectedNode != null) { + GraphNode node = (GraphNode) selectedNode; + if ((node.getX() + node.getWidth()) * sdWidget.getZoomFactor() < sdWidget.getContentsX() + sdWidget.getVisibleWidth() / 2) { + sdWidget.ensureVisible(Math.round((node.getX() + node.getWidth()) * sdWidget.getZoomFactor()) - sdWidget.getVisibleWidth() / 2, Math.round((node.getY() + node.getHeight()) * sdWidget.getZoomFactor())); + } else { + sdWidget.ensureVisible(Math.round((node.getX() + node.getWidth()) * sdWidget.getZoomFactor() + sdWidget.getVisibleWidth() / (float) 2), Math.round((node.getY() + node.getHeight()) * sdWidget.getZoomFactor())); + } + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/ShowNodeStart.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/ShowNodeStart.java new file mode 100755 index 0000000000..7c3ca150b6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/ShowNodeStart.java @@ -0,0 +1,89 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import java.util.Iterator; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode; + +/** + * Action class implementation to show end of a graph node. + * + * @version 1.0 + * @author sveyrier + */ +public class ShowNodeStart extends BaseSDAction { + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Default constructor + */ + public ShowNodeStart() { + this(null); + } + + /** + * Constructor + * + * @param view + * The sequence diagram view reference + * @since 2.0 + */ + public ShowNodeStart(SDView view) { + super(view); + setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NODE_START)); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public void run() { + if (getView() == null) { + return; + } + + SDWidget sdWidget = getView().getSDWidget(); + + if (sdWidget == null) { + return; + } + + ISelectionProvider selProvider = sdWidget.getSelectionProvider(); + ISelection sel = selProvider.getSelection(); + Object selectedNode = null; + Iterator it = ((StructuredSelection) sel).iterator(); + while (it.hasNext()) { + selectedNode = it.next(); + } + if (selectedNode != null) { + GraphNode node = (GraphNode) selectedNode; + if (node.getX() * sdWidget.getZoomFactor() < sdWidget.getContentsX() + sdWidget.getVisibleWidth() / 2) { + sdWidget.ensureVisible(Math.round(node.getX() * sdWidget.getZoomFactor() - sdWidget.getVisibleWidth() / (float) 2), Math.round(node.getY() * sdWidget.getZoomFactor())); + } else { + sdWidget.ensureVisible(Math.round(node.getX() * sdWidget.getZoomFactor() + sdWidget.getVisibleWidth() / (float) 2), Math.round(node.getY() * sdWidget.getZoomFactor())); + } + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/Zoom.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/Zoom.java new file mode 100755 index 0000000000..5a7ee0c668 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/Zoom.java @@ -0,0 +1,239 @@ +/********************************************************************** + * Copyright (c) 2005, 2014 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers; + +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; +import org.eclipse.ui.IActionBars; + +/** + * Action class implementation for zooming in, out or reset of zoom. + * + * @version 1.0 + * @author sveyrier + * + */ +public class Zoom extends BaseSDAction { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The Action ID for zooming in. + */ + public static final String ZOOM_IN_ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ZoomInCoolBar"; //$NON-NLS-1$ + /** + * The Action ID for zooming out. + */ + public static final String ZOOM_OUT_ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ZoomOutCoolBar"; //$NON-NLS-1$ + /** + * The Action ID for reset zooming. + */ + public static final String RESET_ZOOM_ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.ResetZoom"; //$NON-NLS-1$ + /** + * The Action ID for no zoominf. + */ + public static final String NO_ZOOM_ID = "org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.NoZoom"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * Flag to indicate last zoom in. + */ + private boolean fLastZoomIn = false; + /** + * Flag to indicate last zoom out. + */ + private boolean fLastZoomOut = false; + /** + * The cursor used when zooming in. + */ + private final Cursor fZoomInCursor; + /** + * The cursor used when zooming out. + */ + private final Cursor fZoomOutCursor; + + /** + * The different zoom actions + */ + public static enum ZoomType { + /** No zoom information */ + ZOOM_NONE, + /** Zoom in */ + ZOOM_IN, + /** Zoom out */ + ZOOM_OUT, + /** Reset to the default zoom level */ + ZOOM_RESET + } + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructor + * @param view The view reference + * @param type The type of zoom. + */ + public Zoom(SDView view, ZoomType type) { + super(view, "", AS_RADIO_BUTTON); //$NON-NLS-1$ + + // Pre-create zooming cursors + fZoomInCursor = new Cursor(Display.getCurrent(), + Activator.getDefault().getImageFromImageRegistry(ITmfImageConstants.IMG_UI_ZOOM_IN).getImageData(), + Activator.getDefault().getImageFromImageRegistry(ITmfImageConstants.IMG_UI_ZOOM).getImageData(), 0, 0); + + fZoomOutCursor = new Cursor(Display.getCurrent(), + Activator.getDefault().getImageFromImageRegistry(ITmfImageConstants.IMG_UI_ZOOM_OUT).getImageData(), + Activator.getDefault().getImageFromImageRegistry(ITmfImageConstants.IMG_UI_ZOOM).getImageData(), 0, 0); + + switch (type) { + case ZOOM_IN: + setText(Messages.SequenceDiagram_ZoomIn); + setToolTipText(Messages.SequenceDiagram_ZoomInTheDiagram); + setId(ZOOM_IN_ID); + setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ZOOM_IN_MENU)); + break; + + case ZOOM_OUT: + setText(Messages.SequenceDiagram_ZoomOut); + setToolTipText(Messages.SequenceDiagram_ZoomOutTheDiagram); + setId(ZOOM_OUT_ID); + setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ZOOM_OUT_MENU)); + break; + + case ZOOM_RESET: + setText(Messages.SequenceDiagram_ResetZoomFactor); + setToolTipText(Messages.SequenceDiagram_ResetZoomFactor); + setId(RESET_ZOOM_ID); + setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_HOME_MENU)); + break; + + case ZOOM_NONE: + default: + setText(Messages.SequenceDiagram_Select); + setToolTipText(Messages.SequenceDiagram_Select); + setId(NO_ZOOM_ID); + setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SELECT_MENU)); + break; + } + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public void run() { + + if ((getView() == null) || (getView().getSDWidget() == null)) { + return; + } + + SDWidget viewer = getView().getSDWidget(); + + if (getId().equals(ZOOM_OUT_ID)) { + // Eclipse 3.0 M7 workaround + if (fLastZoomOut == isChecked()) { + setChecked(!isChecked()); + } + + viewer.setZoomOutMode(isChecked()); + fLastZoomOut = isChecked(); + if (isChecked()) { + viewer.setCursor(fZoomOutCursor); + setActionChecked(NO_ZOOM_ID, false); + } else { + viewer.setCursor(new Cursor(Display.getDefault(), SWT.CURSOR_ARROW)); + setActionChecked(NO_ZOOM_ID, true); + } + } else if (getId().equals(ZOOM_IN_ID)) { + // Eclipse 3.0 M7 workaround + if (fLastZoomIn == isChecked()) { + setChecked(!isChecked()); + } + + viewer.setZoomInMode(isChecked()); + fLastZoomIn = isChecked(); + if (isChecked()) { + viewer.setCursor(fZoomInCursor); + setActionChecked(NO_ZOOM_ID, false); + } else { + viewer.setCursor(new Cursor(Display.getDefault(), SWT.CURSOR_ARROW)); + setActionChecked(NO_ZOOM_ID, true); + } + } else if (getId().equals(RESET_ZOOM_ID)) { + viewer.resetZoomFactor(); + + // The reset action is a radio button only to uncheck the zoom in and out button + // when it is clicked. This avoid adding code to do it manually + // We only have to force it to false every time + setChecked(false); + setActionChecked(NO_ZOOM_ID, true); + } else if (getId().equals(NO_ZOOM_ID)) { + setChecked(true); + viewer.setZoomInMode(false); + viewer.setZoomInMode(false); + viewer.setCursor(new Cursor(Display.getDefault(), SWT.CURSOR_ARROW)); + } + } + + /** + * Set action check state of a view action for a given action ID. + * + * @param id The action ID + * @param checked true to check the action, false to uncheck the action + */ + protected void setActionChecked(String id, boolean checked) { + if (getView() != null) { + IActionBars bar = getView().getViewSite().getActionBars(); + if (bar == null) { + return; + } + IToolBarManager barManager = bar.getToolBarManager(); + if (barManager == null) { + return; + } + IContributionItem nextPage = barManager.find(id); + if (nextPage instanceof ActionContributionItem) { + IAction action = ((ActionContributionItem) nextPage).getAction(); + if (action != null) { + action.setChecked(checked); + } + } + } + } + + /** + * Dispose the action and its resources + * + * @since 3.2 + */ + public void dispose() { + fZoomInCursor.dispose(); + fZoomOutCursor.dispose(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/IExtendedFilterProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/IExtendedFilterProvider.java new file mode 100755 index 0000000000..3e8ee59fa7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/IExtendedFilterProvider.java @@ -0,0 +1,37 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider; + +import org.eclipse.jface.action.Action; + +/** + * Interface for providing an extended filter provider. + * + * Sequence Diagram loaders which implement this interface provide the action for filtering the sequence diagram.
    + * + * Action provider are associated to a Sequence Diagram view by calling SDView.setExtendedFilterProvider
    + * + * @version 1.0 + * @author sveyrier + * + */ +public interface IExtendedFilterProvider { + + /** + * Returns a filter action implementation. + * + * @return a filter action implementation + */ + Action getFilterAction(); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/IExtendedFindProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/IExtendedFindProvider.java new file mode 100755 index 0000000000..aa471c2fa3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/IExtendedFindProvider.java @@ -0,0 +1,38 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider; + +import org.eclipse.jface.action.Action; + +/** + * Interface for providing an extended find provider. + * + * Sequence Diagram loaders which implement this interface provide an action for finding in the sequence diagram. + * + * Action provider are associated to a Sequence Diagram view by calling SDView.setExtendedFindProvider().
    + * + * Note that either provider implementing ISDFindProvider or IExtendedFindProvider can be active in the SDView.
    + * + * @version 1.0 + * @author sveyrier + * + */ +public interface IExtendedFindProvider { + + /** + * Returns an extended find action. + * + * @return an extended find action + */ + Action getFindAction(); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDAdvancedPagingProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDAdvancedPagingProvider.java new file mode 100755 index 0000000000..45014914cd --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDAdvancedPagingProvider.java @@ -0,0 +1,51 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider; + +/** + * Interface for providing an extended find provider. + * + * An advanced paging provider is able to compute number of pages, and to display the number of items it treats on each + * page and for total counts.
    + * An item can be a message, a node or anything meaningful from loader standpoint.
    + * Items are only here for information to the user. + * + * @version 1.0 + * @author sveyrier + */ +public interface ISDAdvancedPagingProvider extends ISDPagingProvider { + + /** + * Returns the current page. + * + * @return the current page the loader is dealing with. Note that first page has the 0 index (indexes are from + * 0 to pagesCount()-1). + */ + int currentPage(); + + /** + * Returns the number of pages. + * + * @return number of pages the loader is dealing with + */ + int pagesCount(); + + /** + * Instructs a load of the <pageNumber_>th page.
    + * Note that first page has the index 0 (indexes are from 0 to pagesCount()-1). + * + * @param pageNumber index of the page to load + */ + void pageNumberChanged(int pageNumber); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDCollapseProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDCollapseProvider.java new file mode 100755 index 0000000000..29d0fa6c87 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDCollapseProvider.java @@ -0,0 +1,36 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Lifeline; + +/** + * Interface for providing a collapse provider. + * + * Sequence diagram loaders which want to support Drag and Drop collapsing in the sequence diagram must implement this + * interface and register this implementation using SDView.setCollapsingProvider(); + * + * @version 1.0 + * @author sveyrier + */ +public interface ISDCollapseProvider { + + /** + * Called back when the sequence diagram is requesting 2 lifelines collapsing + * + * @param lifeline1 - One of the lifeline to collapse + * @param lifeline2 - The other lifeline to collapse with + */ + void collapseTwoLifelines(Lifeline lifeline1, Lifeline lifeline2); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDExtendedActionBarProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDExtendedActionBarProvider.java new file mode 100755 index 0000000000..1ebd1aecb6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDExtendedActionBarProvider.java @@ -0,0 +1,37 @@ +/********************************************************************** + * Copyright (c) 2005, 2012 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider; + +import org.eclipse.ui.IActionBars; + +/** + * Interface for providing an extended action bar provider. + * + * Sequence Diagram loaders which implement this interface provide their own action to the action bar. + * + * Action provider are associated to a Sequence Diagram SDWidget calling SDViewer.setExtendedActionBarProvider() + * + * @version 1.0 + * @author sveyrier + */ +public interface ISDExtendedActionBarProvider { + + /** + * The caller is supposed to add its own actions in the cool bar and the drop-down menu.
    + * See examples in SDView.createCoolbarContent(). + * + * @param bar the bar + */ + void supplementCoolbarContent(IActionBars bar); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDFilterProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDFilterProvider.java new file mode 100755 index 0000000000..feb721f605 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDFilterProvider.java @@ -0,0 +1,43 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider; + +import java.util.List; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.FilterCriteria; + +/** + * Interface for providing a filter provider. + * + * Sequence Diagram loaders which implement this class provide the actions filtering the sequence diagram.
    + * This interface also allow the implementor to set which graph nodes are supporting filtering (thanks to + * ISDGraphNodeSupporter extension).
    + * + * Action provider are associated to a Sequence Diagram view by calling SDView.setSDFilterProvider
    + * + * Filters to be applied to be managed by the loader in an ArrayList of FilterCriteria.
    + * + * @version 1.0 + * @author sveyrier + */ +public interface ISDFilterProvider extends ISDGraphNodeSupporter { + + /** + * Called when the Filter dialog box OK button is pressed + * + * @param filters user selection made in the dialog box + * @return true if the filter applied + */ + boolean filter(List filters); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDFindProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDFindProvider.java new file mode 100755 index 0000000000..e279d5fc8f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDFindProvider.java @@ -0,0 +1,46 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.Criteria; + +/** + * Interface for providing a find provider. + * + * Sequence Diagram loaders which implement this class provide the actions for finding the sequence diagram. This + * interface also allow the implementor to set which action/feature are supported.
    + * + * Action provider are associated to a Sequence Diagram view by calling SDView.setSDFindProvider().
    + * + * Note that either provider implementing ISDFindProvider or IExtendedFindProvider can be active in the SDView.
    + * + * @version 1.0 + * @author sveyrier + * + */ +public interface ISDFindProvider extends ISDGraphNodeSupporter { + + /** + * Called when the Find dialog box OK button is pressed + * + * @param toApply user selection made in the dialog box + * @return true if the find got a non empty result + */ + boolean find(Criteria toApply); + + /** + * Called when dialog is closed + */ + void cancel(); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDGraphNodeSupporter.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDGraphNodeSupporter.java new file mode 100755 index 0000000000..52e5f61bd5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDGraphNodeSupporter.java @@ -0,0 +1,83 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider; + +/** + * Interface for providing a graph node supporter. + * + * Sequence Diagram loaders which implement this class provide the actions for finding or filtering the sequence + * diagram. This interface also allow the implementor to set which action/feature are supported + * + * Action provider are associated to a Sequence Diagram SDWidget calling SDViewer.setSDFindProvider() or + * SDViewer.setSDFilterProvider(). + * + * @version 1.0 + * @author sveyrier + * + */ +public interface ISDGraphNodeSupporter { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * Lifeline support ID + */ + static int LIFELINE = 0; + /** + * Synchronous message support ID + */ + static int SYNCMESSAGE = 1; + /** + * Synchronous message return support ID + */ + static int SYNCMESSAGERETURN = 2; + /** + * Asynchronous message support ID + */ + static int ASYNCMESSAGE = 3; + /** + * Asynchronous message return support ID + */ + static int ASYNCMESSAGERETURN = 4; + /** + * Stop support ID + */ + static int STOP = 5; + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + /** + * Return true to enable this options, false otherwise + * + * @param nodeType + * The integer value matching the type of the node + * @return true to enable this options, false otherwise + */ + boolean isNodeSupported(int nodeType); + + /** + * Return the name to use in dialogs Not called if isNodeSupported return + * false + * + * @param nodeType + * The integer value matching the type of the node + * @param loaderClassName + * The name of the loader class + * @return the name to use in dialogs + */ + String getNodeName(int nodeType, String loaderClassName); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDPagingProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDPagingProvider.java new file mode 100755 index 0000000000..1c32c0c5f9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDPagingProvider.java @@ -0,0 +1,61 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider; + +/** + * Paging provider interface. + * + * Sequence Diagram loaders which implement this class provide the actions for sequence diagram page navigation.
    + * + * Action provider are associated to a Sequence Diagram view by calling SDView.setSDPagingProvider().
    + * + * @version 1.0 + * @author sveyrier + * + */ +public interface ISDPagingProvider { + + /** + * Return true to enable the next page button in the coolBar, false otherwise + * + * @return true if a next page exists false otherwise + */ + boolean hasNextPage(); + + /** + * Return true to enable the previous page button in the coolBar, false otherwise + * + * @return true if a previous page exists false otherwise + */ + boolean hasPrevPage(); + + /** + * Called back when next page button is pressed in the coolBar + */ + void nextPage(); + + /** + * Called back when previous page button is pressed in the coolBar + */ + void prevPage(); + + /** + * Called back when first page button is pressed in the coolBar + */ + void firstPage(); + + /** + * Called back when last page button is pressed in the coolBar + */ + void lastPage(); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDPropertiesProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDPropertiesProvider.java new file mode 100755 index 0000000000..19f5d728f2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/handlers/provider/ISDPropertiesProvider.java @@ -0,0 +1,35 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider; + +import org.eclipse.ui.views.properties.IPropertySheetPage; + +/** + * Interface for providing sequence diagram property. + * + * Contract for loaders that want to provide information in the properties view. + * + * @version 1.0 + * @author sveyrier + + */ +public interface ISDPropertiesProvider { + + /** + * Returns the IPropertySheetEntry that will fill in the properties view + * + * @return the property sheet entry + */ + IPropertySheetPage getPropertySheetEntry(); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/load/IUml2SDLoader.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/load/IUml2SDLoader.java new file mode 100755 index 0000000000..68a1c7fb09 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/load/IUml2SDLoader.java @@ -0,0 +1,46 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.load; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; + +/** + * The interface all UML2SD loaders must implement. + * + * @version 1.0 + * @author sveyrier + */ +public interface IUml2SDLoader { + + /** + * Set the viewer object to the loader that has been reloaded at the beginning + * of a new workbench session + * + * @param viewer The sequence diagram view + */ + void setViewer(SDView viewer); + + /** + * Returns title string for the UML2SD View when this loader is the one + * + * @return the string convenient for this loader + */ + String getTitleString(); + + /** + * When another loader becomes the one the previous one is replaced It's time clean-up + * if needed (listeners to be removed for example) + */ + void dispose(); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/load/LoadersManager.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/load/LoadersManager.java new file mode 100644 index 0000000000..7c9b6726cd --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/load/LoadersManager.java @@ -0,0 +1,397 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.load; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * Manager class for the UML2SD extension point. + * + * @version 1.0 + * @author sveyrier + * @author Bernd Hufmann + */ +public class LoadersManager { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * The loader tag for the extension point. + */ + public static final String LOADER_TAG = "uml2SDLoader"; //$NON-NLS-1$ + /** + * The loader prefix. + */ + public static final String LOADER_PREFIX = LOADER_TAG + "."; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The LoadersManager singleton instance. + */ + private static LoadersManager fLoadersManager; + + /** + * Map for caching information (view ID to loader class) + */ + private Map fViewLoaderMap = new HashMap<>(); + /** + * Map for caching information (view ID to list of configuration elements) + */ + private Map> fViewLoadersList = new HashMap<>(); + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + /** + * This should not be used by the clients + */ + protected LoadersManager() { + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + /** + * A static method to get the manager instance. + * + * @return the manager instance + */ + public static synchronized LoadersManager getInstance() { + if (fLoadersManager == null) { + fLoadersManager = new LoadersManager(); + } + return fLoadersManager; + } + + /** + * Creates a loader instance and associate it to the view. It requires + * that the loader-view-association was created by an eclipse extension. + * + * @param className The name of the class to create an instance from + * @param view The UML2 Sequence Diagram view instance + * @return The created loader + */ + public IUml2SDLoader createLoader(String className, SDView view) { + + // Safety check + if (view == null) { + return null; + } + + String viewId = view.getViewSite().getId(); + + // Get loaders from all extensions for given view + List loaderElements = getLoaderConfigurationElements(viewId); + IConfigurationElement ce = getLoaderConfigurationElement(className, loaderElements); + + if (ce != null) { + // Assign a loader instance to this view + createLoaderForView(viewId, ce); + IUml2SDLoader loader = fViewLoaderMap.get(viewId); + if (loader != null) { + loader.setViewer(view); + return loader; + } + } + return null; + } + + /** + * Sets the loader to null for this view, a kind of clean-up while disposing. + * + * @param viewId the id of the view + */ + public void resetLoader(String viewId) { + IUml2SDLoader loader = fViewLoaderMap.get(viewId); + if (loader != null) { + loader.dispose(); + } + fViewLoaderMap.put(viewId, null); + } + + /** + * Returns the loader in use in given Sequence Diagram View + * + * @param viewId The Sequence Diagram viewId. + * @return the current loader if any - null otherwise + */ + public IUml2SDLoader getCurrentLoader(String viewId) { + return getCurrentLoader(viewId, null); + } + + /** + * Returns the loader in use in this Sequence Diagram View + * + * @param viewId The Sequence Diagram viewId + * @param view The Sequence Diagram view (if known). Use null to reference the primary SD View. + * @return the current loader if any - null otherwise + */ + public IUml2SDLoader getCurrentLoader(String viewId, SDView view) { + if (viewId == null) { + return null; + } + + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + // During Eclipse shutdown the active workbench window is null + if (window == null) { + return null; + } + + IWorkbenchPage persp = window.getActivePage(); + + SDView sdView = view; + + try { + // Search the view corresponding to the viewId + if (sdView == null) { + IViewReference viewref = persp.findViewReference(viewId); + if (viewref != null) { + sdView = (SDView) viewref.getView(false); + } + + if (sdView == null) { + // no corresponding view exists -> return null for the loader + return null; + } + } + + // Return the loader corresponding to that view (if any) + IUml2SDLoader loader = fViewLoaderMap.get(viewId); + if (loader == null) { + createLastLoaderIfAny(viewId); + loader = fViewLoaderMap.get(viewId); + } + + return loader; + } catch (Exception e) { + Activator.getDefault().logError("Error getting loader class", e); //$NON-NLS-1$ + } + return null; + } + + /** + * Returns the loader class name that have been saved last time. + * + * @param viewId The view this loader belongs to + * @return the class name of the saved loader + */ + public String getSavedLoader(String viewId) { + IPreferenceStore p = Activator.getDefault().getPreferenceStore(); + return p.getString(LOADER_PREFIX + viewId); + } + + /** + * Saves the last loader in order to reload it on next session. + * + * @param id + * Standalone ID of the loader + * @param id2 + * Suffix ID of the loader + */ + public void saveLastLoader(String id, String id2) { + IPreferenceStore p = Activator.getDefault().getPreferenceStore(); + p.setValue(LOADER_PREFIX + id2, id); + } + + /** + * Changes the current unique loader to the given secondary viewId. + * + * @param loader The current loader + * @param id the view secondary id or null + */ + private void setCurrentLoader(IUml2SDLoader loader, String id) { + if (id == null) { + return; + } + + // Get the loader in use + IUml2SDLoader currentLoader = fViewLoaderMap.get(id); + + if ((currentLoader != null) && (currentLoader != loader)) { + if (loader != null) { + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + // During Eclipse shutdown the active workbench window is null + if (window == null) { + return; + } + IWorkbenchPage persp = window.getActivePage(); + try { + // Search view corresponding to the viewId + SDView sdview = null; + IViewReference viewref = persp.findViewReference(id); + if (viewref != null) { + sdview = (SDView) viewref.getView(false); + } + + // Make everything clean for the new loader + if (sdview != null) { + sdview.resetProviders(); + } + + } catch (Exception e) { + Activator.getDefault().logError("Error setting current loader class", e); //$NON-NLS-1$ + } + } + // The old loader is going to be kicked + currentLoader.dispose(); + } + + // Replace the current loader by the new one in the map + fViewLoaderMap.put(id, loader); + + // Store this loader in the preferences to be able to restore it when the workbench will be re-launched + if (loader != null) { + saveLastLoader(loader.getClass().getName(), id); + } + } + + /** + * Creates the last loader and saves it. If not last is not available, it creates + * and saves the default loader, else no loader is created. + * + * @param viewId The view ID. + */ + private void createLastLoaderIfAny(String viewId) { + // Get saved loader from preferences + String loaderName = getSavedLoader(viewId); + + // Get loaders from all extensions for given view + List loaderElements = getLoaderConfigurationElements(viewId); + IConfigurationElement ce = getLoaderConfigurationElement(loaderName, loaderElements); + + if (ce == null) { + ce = getDefaultLoader(loaderElements); + } + + if (ce != null) { + createLoaderForView(viewId, ce); + } + } + + /** + * Gets a list of loader configuration elements from the extension point registry for a given view. + * @param viewId The view ID + * @return List of extension point configuration elements. + */ + private List getLoaderConfigurationElements(String viewId) { + List list = fViewLoadersList.get(viewId); + if (list != null) { + return list; + } + + ArrayList ret = new ArrayList<>(); + IExtensionPoint iep = Platform.getExtensionRegistry().getExtensionPoint(Activator.PLUGIN_ID, LOADER_TAG); + if (iep == null) { + return ret; + } + + IExtension[] ie = iep.getExtensions(); + if (ie == null) { + return ret; + } + + for (int i = 0; i < ie.length; i++) { + IConfigurationElement c[] = ie[i].getConfigurationElements(); + for (int j = 0; j < c.length; j++) { + if (viewId.equals(c[j].getAttribute("view"))) { //$NON-NLS-1$ + ret.add(c[j]); + } + } + } + fViewLoadersList.put(viewId, ret); + return ret; + } + + /** + * Returns the loader configuration element for given loader class name and for the given + * list of configuration elements, if available else null. + * + * @param loaderClassName The loader class name. + * @param loaderElements The list of loader configuration elements + * @return Extension point configuration element + */ + private static IConfigurationElement getLoaderConfigurationElement( + String loaderClassName, List loaderElements) { + if (loaderClassName != null && loaderClassName.length() > 0) { + // Find configuration element corresponding to the saved loader + for (Iterator i = loaderElements.iterator(); i.hasNext();) { + IConfigurationElement ce = i.next(); + if (ce.getAttribute("class").equals(loaderClassName)) { //$NON-NLS-1$ + return ce; + } + } + } + return null; + } + + /** + * Returns the loader configuration element for the given list of configuration elements, if available else null. + * Note that if multiple default loaders are defined it selects the first one + + * @param loaderElements The list of loader configuration elements + * @return The default extension point configuration element. + */ + private static IConfigurationElement getDefaultLoader( + List loaderElements) { + // Look for a default loader + for (Iterator i = loaderElements.iterator(); i.hasNext();) { + IConfigurationElement ce = i.next(); + if (Boolean.valueOf(ce.getAttribute("default")).booleanValue()) { //$NON-NLS-1$ + return ce; + } + } + return null; + } + + /** + * Creates an instance of the loader class for a given extension point configuration element and + * also sets it as current loader for the given view. + * + * @param viewId The view ID. + * @param ce The extension point configuration element + */ + private void createLoaderForView(String viewId, IConfigurationElement ce) { + try { + Object obj = ce.createExecutableExtension("class"); //$NON-NLS-1$ + IUml2SDLoader l = (IUml2SDLoader) obj; + if (viewId != null) { + setCurrentLoader(l, viewId); + } + } catch (CoreException e4) { + Activator.getDefault().logError("Error 'uml2SDLoader' Extension point", e4); //$NON-NLS-1$ + } catch (Exception e5) { + Activator.getDefault().logError("Error 'uml2SDLoader' Extension point", e5); //$NON-NLS-1$ + } + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/Messages.java new file mode 100644 index 0000000000..95a2928483 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/Messages.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Ericsson. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.loader; + +import org.eclipse.osgi.util.NLS; + +/** + * Messages related to the sequence diagram loader + * + * @version 1.0 + * @author Bernd Hufmann + */ +@SuppressWarnings("javadoc") +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.ui.views.uml2sd.loader.messages"; //$NON-NLS-1$ + public static String TmfUml2SDSyncLoader_ViewName; + public static String TmfUml2SDSyncLoader_CategoryLifeline; + public static String TmfUml2SDSyncLoader_CategoryMessage; + public static String TmfUml2SDSyncLoader_FrameName; + public static String TmfUml2SDSyncLoader_SearchJobDescrition; + public static String TmfUml2SDSyncLoader_SearchNotFound; + + /** @since 2.0 */ + public static String TmfUml2SDSyncLoader_EventTypeSend; + /** @since 2.0 */ + public static String TmfUml2SDSyncLoader_EventTypeReceive; + /** @since 2.0 */ + public static String TmfUml2SDSyncLoader_FieldSender; + /** @since 2.0 */ + public static String TmfUml2SDSyncLoader_FieldReceiver; + /** @since 2.0 */ + public static String TmfUml2SDSyncLoader_FieldSignal; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/TmfAsyncMessage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/TmfAsyncMessage.java new file mode 100644 index 0000000000..5c59b96030 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/TmfAsyncMessage.java @@ -0,0 +1,68 @@ +/********************************************************************** + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.loader; + +import org.eclipse.tracecompass.tmf.core.uml2sd.ITmfAsyncSequenceDiagramEvent; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.AsyncMessage; + +/** + *

    + * Extends AsyncMessage class to provide additional information about the trace event. + *

    + * + * @version 1.0 + * @author Bernd Hufmann + */ +public class TmfAsyncMessage extends AsyncMessage implements ITmfAsyncSequenceDiagramEvent { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * A asynchronous sequence diagram event implementation + */ + private ITmfAsyncSequenceDiagramEvent fSdEvent; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Standard constructor + * + * @param sdEvent The asynchronous sequence diagram event implementation + * @param eventOccurrence The event index + */ + public TmfAsyncMessage(ITmfAsyncSequenceDiagramEvent sdEvent, int eventOccurrence) { + this.fSdEvent = sdEvent; + setEventOccurrence(eventOccurrence); + setName(sdEvent.getName()); + setStartTime(sdEvent.getStartTime()); + setEndTime(sdEvent.getEndTime()); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public String getSender() { + return fSdEvent.getSender(); + } + + @Override + public String getReceiver() { + return fSdEvent.getReceiver(); + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/TmfSyncMessage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/TmfSyncMessage.java new file mode 100644 index 0000000000..aec9f5fe4f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/TmfSyncMessage.java @@ -0,0 +1,68 @@ +/********************************************************************** + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.loader; + +import org.eclipse.tracecompass.tmf.core.uml2sd.ITmfSyncSequenceDiagramEvent; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SyncMessage; + + +/** + *

    + * Extends SyncMessage class to provide additional information about the trace event. + *

    + * + * @version 1.0 + * @author Bernd Hufmann + */ +public class TmfSyncMessage extends SyncMessage implements ITmfSyncSequenceDiagramEvent { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * A synchronous sequence diagram event implementation + */ + private ITmfSyncSequenceDiagramEvent fSdEvent; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Standard constructor + * + * @param sdEvent The synchronous sequence diagram event implementation + * @param eventOccurrence The event index + */ + public TmfSyncMessage(ITmfSyncSequenceDiagramEvent sdEvent, int eventOccurrence) { + this.fSdEvent = sdEvent; + setEventOccurrence(eventOccurrence); + setName(sdEvent.getName()); + setTime(sdEvent.getStartTime()); + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public String getSender() { + return fSdEvent.getSender(); + } + + @Override + public String getReceiver() { + return fSdEvent.getReceiver(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/TmfUml2SDSyncLoader.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/TmfUml2SDSyncLoader.java new file mode 100644 index 0000000000..61ab61ebe6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/TmfUml2SDSyncLoader.java @@ -0,0 +1,1485 @@ +/********************************************************************** + * Copyright (c) 2011, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.loader; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.locks.ReentrantLock; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.core.component.TmfComponent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; +import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; +import org.eclipse.tracecompass.tmf.core.signal.TmfRangeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.core.uml2sd.ITmfSyncSequenceDiagramEvent; +import org.eclipse.tracecompass.tmf.core.uml2sd.TmfSyncSequenceDiagramEvent; +import org.eclipse.tracecompass.tmf.ui.editors.ITmfTraceEditor; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Frame; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Lifeline; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.Criteria; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.FilterCriteria; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.dialogs.FilterListDialog; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDAdvancedPagingProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDFilterProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDFindProvider; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.load.IUml2SDLoader; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.progress.IProgressConstants; + +/** + *

    + * This class is a reference implementation of the + * org.eclipse.linuxtools.tmf.ui.Uml2SDLoader extension point. It + * provides a Sequence Diagram loader for a user space trace with specific trace + * content for sending and receiving signals between components. I also includes + * a default implementation for the ITmfEvent parsing. + *

    + * + * The class TmfUml2SDSyncLoader analyzes events from type + * ITmfEvent and creates events type + * ITmfSyncSequenceDiagramEvent if the ITmfEvent + * contains all relevant information. The analysis checks that the event type + * strings contains either string SEND or RECEIVE. If event type matches these + * key words, the analyzer will look for strings sender, receiver and signal in + * the event fields of type ITmfEventField. If all the data is + * found a sequence diagram event from can be created. Note that Sync Messages + * are assumed, which means start and end time are the same.
    + *
    + * The parsing of the ITmfEvent is done in the method + * getSequnceDiagramEvent() of class + * TmfUml2SDSyncLoader. By extending the class + * TmfUml2SDSyncLoader and overwriting + * getSequnceDiagramEvent() a customized parsing algorithm can be + * implemented.
    + *
    + * Note that combined traces of multiple components, that contain the trace + * information about the same interactions are not supported in the class + * TmfUml2SDSyncLoader. + * + * @version 1.0 + * @author Bernd Hufmann + */ +public class TmfUml2SDSyncLoader extends TmfComponent implements IUml2SDLoader, ISDFindProvider, ISDFilterProvider, ISDAdvancedPagingProvider, ISelectionListener { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * Default title name. + */ + protected static final String TITLE = Messages.TmfUml2SDSyncLoader_ViewName; + + /** + * Maximum number of messages per page. + */ + protected static final int MAX_NUM_OF_MSG = 10000; + + private static final int INDEXING_THREAD_SLEEP_VALUE = 100; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + // Experiment attributes + /** + * The TMF trace reference. + * @since 2.0 + */ + protected ITmfTrace fTrace = null; + /** + * The current indexing event request. + */ + protected ITmfEventRequest fIndexRequest = null; + /** + * The current request to fill a page. + */ + protected ITmfEventRequest fPageRequest = null; + /** + * Flag whether the time range signal was sent by this loader class or not + */ + protected volatile boolean fIsSignalSent = false; + + // The view and event attributes + /** + * The sequence diagram view reference. + */ + protected SDView fView = null; + /** + * The current sequence diagram frame reference. + */ + protected Frame fFrame = null; + /** + * The list of sequence diagram events of current page. + */ + protected List fEvents = new ArrayList<>(); + + // Checkpoint and page attributes + /** + * The checkpoints of the whole sequence diagram trace (i.e. start time stamp of each page) + */ + protected List fCheckPoints = new ArrayList<>(MAX_NUM_OF_MSG); + /** + * The current page displayed. + */ + protected volatile int fCurrentPage = 0; + /** + * The current time selected. + */ + protected ITmfTimestamp fCurrentTime = null; + /** + * Flag to specify that selection of message is done by selection or by signal. + */ + protected volatile boolean fIsSelect = false; + + // Search attributes + /** + * The job for searching across pages. + */ + protected SearchJob fFindJob = null; + /** + * List of found nodes within a page. + */ + protected List fFindResults = new ArrayList<>(); + /** + * The current find criteria reference + */ + protected Criteria fFindCriteria = null; + /** + * The current find index within the list of found nodes (fFindeResults within a page. + */ + protected volatile int fCurrentFindIndex = 0; + + // Filter attributes + /** + * The list of active filters. + */ + protected List fFilterCriteria = null; + + // Thread synchronization + /** + * The synchronization lock. + */ + protected ReentrantLock fLock = new ReentrantLock(); + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor + */ + public TmfUml2SDSyncLoader() { + super(TITLE); + } + + /** + * Constructor + * + * @param name Name of loader + */ + public TmfUml2SDSyncLoader(String name) { + super(name); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Returns the current time if available else null. + * + * @return the current time if available else null + * @since 2.0 + */ + public ITmfTimestamp getCurrentTime() { + fLock.lock(); + try { + if (fCurrentTime != null) { + return fCurrentTime; + } + return null; + } finally { + fLock.unlock(); + } + } + + /** + * Waits for the page request to be completed + */ + public void waitForCompletion() { + fLock.lock(); + ITmfEventRequest request = fPageRequest; + fLock.unlock(); + if (request != null) { + try { + request.waitForCompletion(); + } catch (InterruptedException e) { + // ignore + } + } + } + + /** + * Handler for the trace opened signal. + * @param signal The trace opened signal + * @since 2.0 + */ + @TmfSignalHandler + public void traceOpened(TmfTraceOpenedSignal signal) { + fTrace = signal.getTrace(); + loadTrace(); + } + + + /** + * Signal handler for the trace selected signal. + * + * Spawns a request to index the trace (checkpoints creation) as well as it fills + * the first page. + * + * @param signal The trace selected signal + * @since 2.0 + */ + @TmfSignalHandler + public void traceSelected(TmfTraceSelectedSignal signal) { + // Update the trace reference + ITmfTrace trace = signal.getTrace(); + if (!trace.equals(fTrace)) { + fTrace = trace; + } + loadTrace(); + } + + /** + * Method for loading the current selected trace into the view. + * Sub-class need to override this method to add the view specific implementation. + * @since 2.0 + */ + protected void loadTrace() { + ITmfEventRequest indexRequest = null; + fLock.lock(); + + try { + final Job job = new IndexingJob("Indexing " + getName() + "..."); //$NON-NLS-1$ //$NON-NLS-2$ + job.setUser(false); + job.schedule(); + + indexRequest = fIndexRequest; + + cancelOngoingRequests(); + + TmfTimeRange window = TmfTimeRange.ETERNITY; + + fIndexRequest = new TmfEventRequest(ITmfEvent.class, window, 0, + ITmfEventRequest.ALL_DATA, ITmfEventRequest.ExecutionType.BACKGROUND) { + + private ITmfTimestamp fFirstTime = null; + private ITmfTimestamp fLastTime = null; + private int fNbSeqEvents = 0; + private final List fSdEvents = new ArrayList<>(MAX_NUM_OF_MSG); + + @Override + public void handleData(ITmfEvent event) { + super.handleData(event); + + ITmfSyncSequenceDiagramEvent sdEvent = getSequenceDiagramEvent(event); + + if (sdEvent != null) { + ++fNbSeqEvents; + + if (fFirstTime == null) { + fFirstTime = event.getTimestamp(); + } + + fLastTime = event.getTimestamp(); + + if ((fNbSeqEvents % MAX_NUM_OF_MSG) == 0) { + fLock.lock(); + try { + fCheckPoints.add(new TmfTimeRange(fFirstTime, fLastTime)); + if (fView != null) { + fView.updateCoolBar(); + } + } finally { + fLock.unlock(); + } + fFirstTime = null; + + } + + if (fNbSeqEvents > MAX_NUM_OF_MSG) { + // page is full + return; + } + + fSdEvents.add(sdEvent); + + if (fNbSeqEvents == MAX_NUM_OF_MSG) { + fillCurrentPage(fSdEvents); + } + } + } + + @Override + public void handleSuccess() { + if ((fFirstTime != null) && (fLastTime != null)) { + + fLock.lock(); + try { + fCheckPoints.add(new TmfTimeRange(fFirstTime, fLastTime)); + if (fView != null) { + fView.updateCoolBar(); + } + } finally { + fLock.unlock(); + } + } + + if (fNbSeqEvents <= MAX_NUM_OF_MSG) { + fillCurrentPage(fSdEvents); + } + + super.handleSuccess(); + } + + @Override + public void handleCompleted() { + if (fEvents.isEmpty()) { + fFrame = new Frame(); + // make sure that view is not null when setting frame + SDView sdView; + fLock.lock(); + try { + sdView = fView; + } finally { + fLock.unlock(); + } + if (sdView != null) { + sdView.setFrameSync(fFrame); + } + } + super.handleCompleted(); + job.cancel(); + } + }; + + } finally { + fLock.unlock(); + } + if (indexRequest != null && !indexRequest.isCompleted()) { + indexRequest.cancel(); + } + resetLoader(); + fTrace.sendRequest(fIndexRequest); + } + + /** + * Signal handler for the trace closed signal. + * + * @param signal The trace closed signal + * @since 2.0 + */ + @TmfSignalHandler + public void traceClosed(TmfTraceClosedSignal signal) { + if (signal.getTrace() != fTrace) { + return; + } + ITmfEventRequest indexRequest = null; + fLock.lock(); + try { + indexRequest = fIndexRequest; + fIndexRequest = null; + + cancelOngoingRequests(); + + if (fFilterCriteria != null) { + fFilterCriteria.clear(); + } + + FilterListDialog.deactivateSavedGlobalFilters(); + } finally { + fTrace = null; + fLock.unlock(); + } + if (indexRequest != null && !indexRequest.isCompleted()) { + indexRequest.cancel(); + } + + resetLoader(); + } + + /** + * Moves to the page that contains the time provided by the signal. The messages will be selected + * if the provided time is the time of a message. + * + * @param signal The Time synch signal. + */ + @TmfSignalHandler + public void synchToTime(TmfTimeSynchSignal signal) { + fLock.lock(); + try { + if ((signal.getSource() != this) && (fFrame != null) && (fCheckPoints.size() > 0)) { + fCurrentTime = signal.getBeginTime(); + fIsSelect = true; + moveToMessage(); + } + } finally { + fLock.unlock(); + } + } + + /** + * Moves to the page that contains the current time provided by signal. + * No message will be selected however the focus will be set to the message + * if the provided time is the time of a message. + * + * @param signal The time range sync signal + */ + @TmfSignalHandler + public void synchToTimeRange(TmfRangeSynchSignal signal) { + fLock.lock(); + try { + if ((signal.getSource() != this) && (fFrame != null) && !fIsSignalSent && (fCheckPoints.size() > 0)) { + TmfTimeRange newTimeRange = signal.getCurrentRange(); + + fIsSelect = false; + fCurrentTime = newTimeRange.getStartTime(); + + moveToMessage(); + } + } finally { + fLock.unlock(); + } + + } + + @Override + public void setViewer(SDView viewer) { + + fLock.lock(); + try { + fView = viewer; + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().addPostSelectionListener(this); + fView.setSDFindProvider(this); + fView.setSDPagingProvider(this); + fView.setSDFilterProvider(this); + + resetLoader(); + IEditorPart editor = fView.getSite().getPage().getActiveEditor(); + if (editor instanceof ITmfTraceEditor) { + ITmfTrace trace = ((ITmfTraceEditor) editor).getTrace(); + if (trace != null) { + traceSelected(new TmfTraceSelectedSignal(this, trace)); + } + } + } finally { + fLock.unlock(); + } + } + + @Override + public String getTitleString() { + return getName(); + } + + @Override + public void dispose() { + super.dispose(); + ITmfEventRequest indexRequest = null; + fLock.lock(); + try { + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + // During Eclipse shutdown the active workbench window is null + if (window != null) { + window.getSelectionService().removePostSelectionListener(this); + } + + indexRequest = fIndexRequest; + fIndexRequest = null; + cancelOngoingRequests(); + + fView.setSDFindProvider(null); + fView.setSDPagingProvider(null); + fView.setSDFilterProvider(null); + fView = null; + } finally { + fLock.unlock(); + } + if (indexRequest != null && !indexRequest.isCompleted()) { + indexRequest.cancel(); + } + } + + @Override + public boolean isNodeSupported(int nodeType) { + switch (nodeType) { + case ISDGraphNodeSupporter.LIFELINE: + case ISDGraphNodeSupporter.SYNCMESSAGE: + return true; + + default: + break; + } + return false; + } + + @Override + public String getNodeName(int nodeType, String loaderClassName) { + switch (nodeType) { + case ISDGraphNodeSupporter.LIFELINE: + return Messages.TmfUml2SDSyncLoader_CategoryLifeline; + case ISDGraphNodeSupporter.SYNCMESSAGE: + return Messages.TmfUml2SDSyncLoader_CategoryMessage; + default: + break; + } + return ""; //$NON-NLS-1$ + } + + @Override + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + ISelection sel = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().getSelection(); + if ((sel != null) && (sel instanceof StructuredSelection)) { + StructuredSelection stSel = (StructuredSelection) sel; + if (stSel.getFirstElement() instanceof TmfSyncMessage) { + TmfSyncMessage syncMsg = ((TmfSyncMessage) stSel.getFirstElement()); + broadcast(new TmfTimeSynchSignal(this, syncMsg.getStartTime())); + } + } + } + + @Override + public boolean find(Criteria toSearch) { + fLock.lock(); + try { + if (fFrame == null) { + return false; + } + + if ((fFindResults == null) || (fFindCriteria == null) || !fFindCriteria.compareTo(toSearch)) { + fFindResults = new CopyOnWriteArrayList<>(); + fFindCriteria = toSearch; + if (fFindCriteria.isLifeLineSelected()) { + for (int i = 0; i < fFrame.lifeLinesCount(); i++) { + if (fFindCriteria.matches(fFrame.getLifeline(i).getName())) { + fFindResults.add(fFrame.getLifeline(i)); + } + } + } + + ArrayList msgs = new ArrayList<>(); + if (fFindCriteria.isSyncMessageSelected()) { + for (int i = 0; i < fFrame.syncMessageCount(); i++) { + if (fFindCriteria.matches(fFrame.getSyncMessage(i).getName())) { + msgs.add(fFrame.getSyncMessage(i)); + } + } + } + + if (!msgs.isEmpty()) { + fFindResults.addAll(msgs); + } + + List selection = fView.getSDWidget().getSelection(); + if ((selection != null) && (selection.size() == 1)) { + fCurrentFindIndex = fFindResults.indexOf(selection.get(0)) + 1; + } else { + fCurrentFindIndex = 0; + } + } else { + fCurrentFindIndex++; + } + + if (fFindResults.size() > fCurrentFindIndex) { + GraphNode current = fFindResults.get(fCurrentFindIndex); + fView.getSDWidget().moveTo(current); + return true; + } + fFindResults = null; + fCurrentFindIndex =0; + return findInNextPages(fFindCriteria); // search in other page + } finally { + fLock.unlock(); + } + } + + @Override + public void cancel() { + cancelOngoingRequests(); + } + + @Override + public boolean filter(List filters) { + fLock.lock(); + try { + cancelOngoingRequests(); + + if (filters == null) { + fFilterCriteria = new ArrayList<>(); + } else { + List list = filters; + fFilterCriteria = new ArrayList<>(list); + } + + fillCurrentPage(fEvents); + + } finally { + fLock.unlock(); + } + return true; + } + + @Override + public boolean hasNextPage() { + fLock.lock(); + try { + int size = fCheckPoints.size(); + if (size > 0) { + return fCurrentPage < (size - 1); + } + } finally { + fLock.unlock(); + } + return false; + } + + @Override + public boolean hasPrevPage() { + fLock.lock(); + try { + return fCurrentPage > 0; + } finally { + fLock.unlock(); + } + } + + @Override + public void nextPage() { + fLock.lock(); + try { + // Safety check + if (fCurrentPage >= (fCheckPoints.size() - 1)) { + return; + } + + cancelOngoingRequests(); + fCurrentTime = null; + fCurrentPage++; + moveToPage(); + } finally { + fLock.unlock(); + } + } + + @Override + public void prevPage() { + fLock.lock(); + try { + // Safety check + if (fCurrentPage <= 0) { + return; + } + + cancelOngoingRequests(); + fCurrentTime = null; + fCurrentPage--; + moveToPage(); + } finally { + fLock.unlock(); + } + } + + @Override + public void firstPage() { + fLock.lock(); + try { + + cancelOngoingRequests(); + fCurrentTime = null; + fCurrentPage = 0; + moveToPage(); + } finally { + fLock.unlock(); + } + } + + @Override + public void lastPage() { + fLock.lock(); + try { + cancelOngoingRequests(); + fCurrentTime = null; + fCurrentPage = fCheckPoints.size() - 1; + moveToPage(); + } finally { + fLock.unlock(); + } + } + + @Override + public int currentPage() { + fLock.lock(); + try { + return fCurrentPage; + } finally { + fLock.unlock(); + } + } + + @Override + public int pagesCount() { + fLock.lock(); + try { + return fCheckPoints.size(); + } finally { + fLock.unlock(); + } + } + + @Override + public void pageNumberChanged(int pagenNumber) { + int localPageNumber = pagenNumber; + + fLock.lock(); + try { + cancelOngoingRequests(); + + if (localPageNumber < 0) { + localPageNumber = 0; + } + int size = fCheckPoints.size(); + if (localPageNumber > (size - 1)) { + localPageNumber = size - 1; + } + fCurrentPage = localPageNumber; + moveToPage(); + } finally { + fLock.unlock(); + } + } + + @Override + public void broadcast(TmfSignal signal) { + fIsSignalSent = true; + super.broadcast(signal); + fIsSignalSent = false; + } + + /** + * Cancels any ongoing find operation + */ + protected void cancelOngoingRequests() { + fLock.lock(); + ITmfEventRequest pageRequest = null; + try { + // Cancel the search thread + if (fFindJob != null) { + fFindJob.cancel(); + } + + fFindResults = null; + fFindCriteria = null; + fCurrentFindIndex = 0; + + pageRequest = fPageRequest; + fPageRequest = null; + } finally { + fLock.unlock(); + } + if (pageRequest != null && !pageRequest.isCompleted()) { + pageRequest.cancel(); + } + } + + /** + * Resets loader attributes + */ + protected void resetLoader() { + fLock.lock(); + try { + fCurrentTime = null; + fEvents.clear(); + fCheckPoints.clear(); + fCurrentPage = 0; + fCurrentFindIndex = 0; + fFindCriteria = null; + fFindResults = null; + fView.setFrameSync(new Frame()); + fFrame = null; + } + finally { + fLock.unlock(); + } + + } + + /** + * Fills current page with sequence diagram content. + * + * @param events sequence diagram events + */ + protected void fillCurrentPage(List events) { + + fLock.lock(); + try { + fEvents = new ArrayList<>(events); + if (fView != null && !events.isEmpty()) { + fView.toggleWaitCursorAsync(true); + } + } finally { + fLock.unlock(); + } + + final Frame frame = new Frame(); + + if (!events.isEmpty()) { + Map nodeToLifelineMap = new HashMap<>(); + + frame.setName(Messages.TmfUml2SDSyncLoader_FrameName); + + for (int i = 0; i < events.size(); i++) { + + ITmfSyncSequenceDiagramEvent sdEvent = events.get(i); + + if ((nodeToLifelineMap.get(sdEvent.getSender()) == null) && (!filterLifeLine(sdEvent.getSender()))) { + Lifeline lifeline = new Lifeline(); + lifeline.setName(sdEvent.getSender()); + nodeToLifelineMap.put(sdEvent.getSender(), lifeline); + frame.addLifeLine(lifeline); + } + + if ((nodeToLifelineMap.get(sdEvent.getReceiver()) == null) && (!filterLifeLine(sdEvent.getReceiver()))) { + Lifeline lifeline = new Lifeline(); + lifeline.setName(sdEvent.getReceiver()); + nodeToLifelineMap.put(sdEvent.getReceiver(), lifeline); + frame.addLifeLine(lifeline); + } + } + + int eventOccurence = 1; + + for (int i = 0; i < events.size(); i++) { + ITmfSyncSequenceDiagramEvent sdEvent = events.get(i); + + // Check message filter + if (filterMessage(sdEvent)) { + continue; + } + + // Set the message sender and receiver + Lifeline startLifeline = nodeToLifelineMap.get(sdEvent.getSender()); + Lifeline endLifeline = nodeToLifelineMap.get(sdEvent.getReceiver()); + + // Check if any of the lifelines were filtered + if ((startLifeline == null) || (endLifeline == null)) { + continue; + } + + int tmp = Math.max(startLifeline.getEventOccurrence(), endLifeline.getEventOccurrence()); + eventOccurence = Math.max(eventOccurence, tmp); + + startLifeline.setCurrentEventOccurrence(eventOccurence); + endLifeline.setCurrentEventOccurrence(eventOccurence); + + TmfSyncMessage message = new TmfSyncMessage(sdEvent, eventOccurence++); + + message.setStartLifeline(startLifeline); + message.setEndLifeline(endLifeline); + + message.setTime(sdEvent.getStartTime()); + + // add the message to the frame + frame.addMessage(message); + + } + fLock.lock(); + try { + if (!fView.getSDWidget().isDisposed()) { + fView.getSDWidget().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + + fLock.lock(); + try { + // check if view was disposed in the meanwhile + if ((fView != null) && (!fView.getSDWidget().isDisposed())) { + fFrame = frame; + fView.setFrame(fFrame); + + if (fCurrentTime != null) { + moveToMessageInPage(); + } + + if (fFindCriteria != null) { + find(fFindCriteria); + } + + fView.toggleWaitCursorAsync(false); + } + } finally { + fLock.unlock(); + } + + } + }); + } + } + finally { + fLock.unlock(); + } + } + } + + /** + * Moves to a certain message defined by timestamp (across pages) + */ + protected void moveToMessage() { + int page = 0; + + fLock.lock(); + try { + page = getPage(fCurrentTime); + + if (page == fCurrentPage) { + moveToMessageInPage(); + return; + } + fCurrentPage = page; + moveToPage(false); + } finally { + fLock.unlock(); + } + } + + /** + * Moves to a certain message defined by timestamp in current page + */ + protected void moveToMessageInPage() { + fLock.lock(); + try { + if (!fView.getSDWidget().isDisposed()) { + // Check for GUI thread + if(Display.getCurrent() != null) { + // Already in GUI thread - execute directly + TmfSyncMessage prevMessage = null; + TmfSyncMessage syncMessage = null; + boolean isExactTime = false; + for (int i = 0; i < fFrame.syncMessageCount(); i++) { + if (fFrame.getSyncMessage(i) instanceof TmfSyncMessage) { + syncMessage = (TmfSyncMessage) fFrame.getSyncMessage(i); + if (syncMessage.getStartTime().compareTo(fCurrentTime, false) == 0) { + isExactTime = true; + break; + } else if ((syncMessage.getStartTime().compareTo(fCurrentTime, false) > 0) && (prevMessage != null)) { + syncMessage = prevMessage; + break; + } + prevMessage = syncMessage; + } + } + if (fIsSelect && isExactTime) { + fView.getSDWidget().moveTo(syncMessage); + } + else { + fView.getSDWidget().ensureVisible(syncMessage); + fView.getSDWidget().clearSelection(); + fView.getSDWidget().redraw(); + } + } + else { + // Not in GUI thread - queue action in GUI thread. + fView.getSDWidget().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + moveToMessageInPage(); + } + }); + } + } + } + finally { + fLock.unlock(); + } + } + + /** + * Moves to a certain message defined by timestamp (across pages) + */ + protected void moveToPage() { + moveToPage(true); + } + + /** + * Moves to a certain page. + * + * @param notifyAll true to broadcast time range signal to other signal handlers else false + */ + protected void moveToPage(boolean notifyAll) { + + TmfTimeRange window = null; + + fLock.lock(); + try { + // Safety check + if (fCurrentPage > fCheckPoints.size()) { + return; + } + window = fCheckPoints.get(fCurrentPage); + } finally { + fLock.unlock(); + } + + if (window == null) { + window = TmfTimeRange.ETERNITY; + } + + fPageRequest = new TmfEventRequest(ITmfEvent.class, window, 0, + ITmfEventRequest.ALL_DATA, ITmfEventRequest.ExecutionType.FOREGROUND) { + private final List fSdEvent = new ArrayList<>(); + + @Override + public void handleData(ITmfEvent event) { + super.handleData(event); + + ITmfSyncSequenceDiagramEvent sdEvent = getSequenceDiagramEvent(event); + + if (sdEvent != null) { + fSdEvent.add(sdEvent); + } + } + + @Override + public void handleSuccess() { + fillCurrentPage(fSdEvent); + super.handleSuccess(); + } + + }; + + fTrace.sendRequest(fPageRequest); + + if (notifyAll) { + TmfTimeRange timeRange = getSignalTimeRange(window.getStartTime()); + broadcast(new TmfRangeSynchSignal(this, timeRange)); + } + } + + /** + * Gets page that contains timestamp + * + * @param time The timestamp + * @return page that contains the time + * @since 2.0 + */ + protected int getPage(ITmfTimestamp time) { + int page; + int size; + fLock.lock(); + try { + size = fCheckPoints.size(); + for (page = 0; page < size; page++) { + TmfTimeRange timeRange = fCheckPoints.get(page); + if (timeRange.getEndTime().compareTo(time, false) >= 0) { + break; + } + } + if (page >= size) { + page = size - 1; + } + return page; + } finally { + fLock.unlock(); + } + } + + /** + * Background search in trace for expression in criteria. + * + * @param findCriteria The find criteria + * @return true if background request was started else false + */ + protected boolean findInNextPages(Criteria findCriteria) { + fLock.lock(); + try { + if (fFindJob != null) { + return true; + } + + int nextPage = fCurrentPage + 1; + + if ((nextPage) >= fCheckPoints.size()) { + // we are at the end + return false; + } + + TmfTimeRange window = new TmfTimeRange(fCheckPoints.get(nextPage).getStartTime(), fCheckPoints.get(fCheckPoints.size()-1).getEndTime()); + fFindJob = new SearchJob(findCriteria, window); + fFindJob.schedule(); + fView.toggleWaitCursorAsync(true); + } finally { + fLock.unlock(); + } + return true; + } + + /** + * Gets time range for time range signal. + * + * @param startTime The start time of time range. + * @return the time range + * @since 2.0 + */ + protected TmfTimeRange getSignalTimeRange(ITmfTimestamp startTime) { + fLock.lock(); + try { + TmfTimeRange currentRange = TmfTraceManager.getInstance().getCurrentRange(); + long offset = fTrace == null ? 0 : currentRange.getEndTime().getDelta(currentRange.getStartTime()).normalize(0, startTime.getScale()).getValue(); + TmfTimestamp initialEndOfWindow = new TmfTimestamp(startTime.getValue() + offset, startTime.getScale(), startTime.getPrecision()); + return new TmfTimeRange(startTime, initialEndOfWindow); + } + finally { + fLock.unlock(); + } + } + + /** + * Checks if filter criteria matches the message name in given SD event. + * + * @param sdEvent The SD event to check + * @return true if match else false. + */ + protected boolean filterMessage(ITmfSyncSequenceDiagramEvent sdEvent) { + fLock.lock(); + try { + if (fFilterCriteria != null) { + for(FilterCriteria criteria : fFilterCriteria) { + if (criteria.isActive() && criteria.getCriteria().isSyncMessageSelected() && criteria.getCriteria().matches(sdEvent.getName())) { + return true; + } + } + } + } finally { + fLock.unlock(); + } + return false; + } + + /** + * Checks if filter criteria matches a lifeline name (sender or receiver) in given SD event. + * + * @param lifeline the message receiver + * @return true if match else false. + */ + protected boolean filterLifeLine(String lifeline) { + fLock.lock(); + try { + if (fFilterCriteria != null) { + for(FilterCriteria criteria : fFilterCriteria) { + if (criteria.isActive() && criteria.getCriteria().isLifeLineSelected() && criteria.getCriteria().matches(lifeline)) { + return true; + } + } + } + } finally { + fLock.unlock(); + } + return false; + } + + /** + * Job to search in trace for given time range. + */ + protected class SearchJob extends Job { + + /** + * The search event request. + */ + protected final SearchEventRequest fSearchRequest; + + /** + * Constructor + * + * @param findCriteria The search criteria + * @param window Time range to search in + * @since 2.0 + */ + public SearchJob(Criteria findCriteria, TmfTimeRange window) { + super(Messages.TmfUml2SDSyncLoader_SearchJobDescrition); + fSearchRequest = new SearchEventRequest(window, ITmfEventRequest.ALL_DATA, + ITmfEventRequest.ExecutionType.FOREGROUND, findCriteria); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + fSearchRequest.setMonitor(monitor); + + fTrace.sendRequest(fSearchRequest); + + try { + fSearchRequest.waitForCompletion(); + } catch (InterruptedException e) { + Activator.getDefault().logError("Search request interrupted!", e); //$NON-NLS-1$ + } + + IStatus status = Status.OK_STATUS; + if (fSearchRequest.isFound() && (fSearchRequest.getFoundTime() != null)) { + fCurrentTime = fSearchRequest.getFoundTime(); + + // Avoid double-selection. Selection will be done when calling find(criteria) + // after moving to relevant page + fIsSelect = false; + if (!fView.getSDWidget().isDisposed()) { + fView.getSDWidget().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + moveToMessage(); + } + }); + } + } + else { + if (monitor.isCanceled()) { + status = Status.CANCEL_STATUS; + } + else { + // String was not found + status = new Status(IStatus.WARNING, Activator.PLUGIN_ID, Messages.TmfUml2SDSyncLoader_SearchNotFound); + } + setProperty(IProgressConstants.KEEP_PROPERTY, Boolean.TRUE); + } + monitor.done(); + + fLock.lock(); + try { + fView.toggleWaitCursorAsync(false); + fFindJob = null; + } finally { + fLock.unlock(); + } + + return status; + } + + @Override + protected void canceling() { + fSearchRequest.cancel(); + fLock.lock(); + try { + fFindJob = null; + } finally { + fLock.unlock(); + } + } + } + + /** + * TMF event request for searching within trace. + */ + protected class SearchEventRequest extends TmfEventRequest { + + /** + * The find criteria. + */ + private final Criteria fCriteria; + /** + * A progress monitor + */ + private IProgressMonitor fMonitor; + /** + * Flag to indicate that node was found according the criteria . + */ + private boolean fIsFound = false; + /** + * Time stamp of found item. + */ + private ITmfTimestamp fFoundTime = null; + + /** + * Constructor + * @param range @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...) + * @param nbRequested @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#handleData(...) + * @param execType @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#handleData(...) + * @param criteria The search criteria + */ + public SearchEventRequest(TmfTimeRange range, int nbRequested, ExecutionType execType, Criteria criteria) { + this(range, nbRequested, execType, criteria, null); + } + + /** + * Constructor + * @param range @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...) + * @param nbRequested @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...) + * @param execType @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...) + * @param criteria The search criteria + * @param monitor progress monitor + */ + public SearchEventRequest(TmfTimeRange range, int nbRequested, ExecutionType execType, Criteria criteria, IProgressMonitor monitor) { + super(ITmfEvent.class, range, 0, nbRequested, execType); + fCriteria = new Criteria(criteria); + fMonitor = monitor; + } + + @Override + public void handleData(ITmfEvent event) { + super.handleData(event); + + if ((fMonitor!= null) && fMonitor.isCanceled()) { + super.cancel(); + return; + } + + ITmfSyncSequenceDiagramEvent sdEvent = getSequenceDiagramEvent(event); + + if (sdEvent != null) { + + if (fCriteria.isLifeLineSelected()) { + if (fCriteria.matches(sdEvent.getSender())) { + fFoundTime = event.getTimestamp(); + fIsFound = true; + super.cancel(); + } + + if (fCriteria.matches(sdEvent.getReceiver())) { + fFoundTime = event.getTimestamp(); + fIsFound = true; + super.cancel(); + } + } + + if (fCriteria.isSyncMessageSelected() && fCriteria.matches(sdEvent.getName())) { + fFoundTime = event.getTimestamp(); + fIsFound = true; + super.cancel(); + } + } + } + + /** + * Set progress monitor. + * + * @param monitor The monitor to assign + */ + public void setMonitor(IProgressMonitor monitor) { + fMonitor = monitor; + } + + /** + * Check if find criteria was met. + * + * @return true if find criteria was met. + */ + public boolean isFound() { + return fIsFound; + } + + /** + * Returns timestamp of found time. + * + * @return timestamp of found time. + * @since 2.0 + */ + public ITmfTimestamp getFoundTime() { + return fFoundTime; + } + } + + /** + * Job class to provide progress monitor feedback. + * + * @version 1.0 + * @author Bernd Hufmann + * + */ + protected static class IndexingJob extends Job { + + /** + * @param name The job name + */ + public IndexingJob(String name) { + super(name); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + while (!monitor.isCanceled()) { + try { + Thread.sleep(INDEXING_THREAD_SLEEP_VALUE); + } catch (InterruptedException e) { + return Status.OK_STATUS; + } + } + monitor.done(); + return Status.OK_STATUS; + } + } + + + /** + * Returns sequence diagram event if details in given event are available else null. + * + * @param tmfEvent Event to parse for sequence diagram event details + * @return sequence diagram event if details are available else null + * @since 2.0 + */ + protected ITmfSyncSequenceDiagramEvent getSequenceDiagramEvent(ITmfEvent tmfEvent){ + //type = .*RECEIVE.* or .*SEND.* + //content = sender::receiver:,signal: + String eventType = tmfEvent.getType().toString(); + if (eventType.contains(Messages.TmfUml2SDSyncLoader_EventTypeSend) || eventType.contains(Messages.TmfUml2SDSyncLoader_EventTypeReceive)) { + Object sender = tmfEvent.getContent().getField(Messages.TmfUml2SDSyncLoader_FieldSender); + Object receiver = tmfEvent.getContent().getField(Messages.TmfUml2SDSyncLoader_FieldReceiver); + Object name = tmfEvent.getContent().getField(Messages.TmfUml2SDSyncLoader_FieldSignal); + if ((sender instanceof ITmfEventField) && (receiver instanceof ITmfEventField) && (name instanceof ITmfEventField)) { + ITmfSyncSequenceDiagramEvent sdEvent = new TmfSyncSequenceDiagramEvent(tmfEvent, + ((ITmfEventField) sender).getValue().toString(), + ((ITmfEventField) receiver).getValue().toString(), + ((ITmfEventField) name).getValue().toString()); + + return sdEvent; + } + } + return null; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/messages.properties new file mode 100644 index 0000000000..359c257e24 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/loader/messages.properties @@ -0,0 +1,22 @@ +############################################################################### +# Copyright (c) 2011, 2013 Ericsson +# +# All rights reserved. This program and the accompanying materials are +# made available under the terms of the Eclipse Public License v1.0 which +# accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Bernd Hufmann - Initial API and implementation +############################################################################### +TmfUml2SDSyncLoader_ViewName=Component Interactions +TmfUml2SDSyncLoader_CategoryLifeline=Lifeline +TmfUml2SDSyncLoader_CategoryMessage=Interaction +TmfUml2SDSyncLoader_FrameName=Sequence Diagram +TmfUml2SDSyncLoader_SearchJobDescrition=Searching in sequence diagram ... +TmfUml2SDSyncLoader_EventTypeSend=SEND +TmfUml2SDSyncLoader_EventTypeReceive=RECEIVE +TmfUml2SDSyncLoader_FieldSender=sender +TmfUml2SDSyncLoader_FieldReceiver=receiver +TmfUml2SDSyncLoader_FieldSignal=signal +TmfUml2SDSyncLoader_SearchNotFound=String not found! diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/preferences/ISDPreferences.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/preferences/ISDPreferences.java new file mode 100755 index 0000000000..eda1e24a1a --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/preferences/ISDPreferences.java @@ -0,0 +1,147 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IColor; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IFont; + +/** + * Interface for accessing sequence diagram preferences. + * + * @version 1.0 + * @author sveyrier + */ +public interface ISDPreferences { + + /** + * The link font with zoom preference name + */ + static final String PREF_LINK_FONT = "PREF_LINK_FONT"; //$NON-NLS-1$ + /** + * The exclude preference time preference name + */ + static final String PREF_EXCLUDE_EXTERNAL_TIME = "PREF_EXCLUDE_EXTERNAL_TIME"; //$NON-NLS-1$ + /** + * The use gradient color preferences name + */ + static final String PREF_USE_GRADIENT = "PREF_USE_GRADIENT"; //$NON-NLS-1$ + /** + * The lifeline spacing width preference name + */ + static final String PREF_LIFELINE_WIDTH = "PREF_LIFELINE_WIDTH"; //$NON-NLS-1$ + /** + * The time compression bar font preference name + */ + static final String PREF_TIME_COMP = "PREF_TIME_COMP"; //$NON-NLS-1$ + /** + * The lifeline font preference name + */ + static final String PREF_LIFELINE = "PREF_LIFELINE"; //$NON-NLS-1$ + /** + * The frame font preference name + */ + static final String PREF_FRAME = "PREF_FRAME"; //$NON-NLS-1$ + /** + * The frame name font preference name + */ + static final String PREF_FRAME_NAME = "PREF_FRAME_NAME"; //$NON-NLS-1$ + /** + * The execution occurrence font preference name + */ + static final String PREF_EXEC = "PREF_EXEC"; //$NON-NLS-1$ + /** + * The synchronous message font preference name + */ + static final String PREF_SYNC_MESS = "PREF_SYNC_MESS"; //$NON-NLS-1$ + /** + * The synchronous message return font preference name + */ + static final String PREF_SYNC_MESS_RET = "PREF_SYNC_MESS_RET"; //$NON-NLS-1$ + /** + * The asynchronous message font preference name + */ + static final String PREF_ASYNC_MESS = "PREF_ASYNC_MESS"; //$NON-NLS-1$ + /** + * The asynchronous message return font preference name + */ + static final String PREF_ASYNC_MESS_RET = "PREF_ASYNC_MESS_RET"; //$NON-NLS-1$ + /** + * The lifeline header font (header = the always visible part of a lifeline) + */ + static final String PREF_LIFELINE_HEADER = "PREF_LIFELINE_HEADER"; //$NON-NLS-1$ + /** + * The enable tooltip preference name + */ + static final String PREF_TOOLTIP = "PREF_TOOLTIP"; //$NON-NLS-1$ + + /** + * Returns the background color for the given preference name (font preference name) + * + * @param prefId The preference name + * @return the color + */ + IColor getBackGroundColor(String prefId); + + /** + * Returns the foreground color for the given preference name (font preference name) + * + * @param prefId A preference name + * @return the color + */ + IColor getForeGroundColor(String prefId); + + /** + * Returns the font color for the given preference name (font preference name) + * + * @param prefId A preference name + * @return the color + */ + IColor getFontColor(String prefId); + + /** + * Returns the font for the given preference name + * + * @param prefId the preference name + * @return the font + */ + IFont getFont(String prefId); + + /** + * Returns the time compression bar selection color + * + * @return the time compression bar selection color + */ + IColor getTimeCompressionSelectionColor(); + + /** + * Returns the background color used to draw selection + * + * @return the background color + */ + IColor getBackGroundColorSelection(); + + /** + * Returns the foreground color used to draw selection + * + * @return the foreground color + */ + IColor getForeGroundColorSelection(); + + /** + * Returns whether to use gradient color or not + * + * @return whether to use gradient color or not + */ + boolean useGradienColor(); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/preferences/SDViewPref.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/preferences/SDViewPref.java new file mode 100755 index 0000000000..59f4aaf5af --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/preferences/SDViewPref.java @@ -0,0 +1,527 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Hashtable; +import java.util.Map; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IColor; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IFont; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.impl.ColorImpl; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.impl.FontImpl; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; + +/** + * This is the Sequence Diagram preference handler. This class is responsible for accessing the current user preferences + * selection This class also provider getters for each modifiable preferences. + * + * @version 1.0 + * @author sveyrier + */ +public class SDViewPref implements ISDPreferences, IPropertyChangeListener { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * Postfix string for background color property + */ + public static final String BACK_COLOR_POSTFIX = "_BACK_COLOR";//$NON-NLS-1$ + /** + * Postfix string for foreground color property + */ + public static final String FORE_COLOR_POSTFIX = "_FORE_COLOR";//$NON-NLS-1$ + /** + * Postfix string for text color property + */ + public static final String TEXT_COLOR_POSTFIX = "_TEXT_COLOR";//$NON-NLS-1$ + /** + * Array of preference names + */ + private static final String[] FONT_LIST = { PREF_LIFELINE, PREF_EXEC, PREF_SYNC_MESS, PREF_SYNC_MESS_RET, PREF_ASYNC_MESS, PREF_ASYNC_MESS_RET, PREF_FRAME, PREF_LIFELINE_HEADER, PREF_FRAME_NAME }; + /** + * A 2nd array of preference names + */ + private static final String[] FONT_LIST2 = { Messages.SequenceDiagram_Lifeline, Messages.SequenceDiagram_ExecutionOccurrence, Messages.SequenceDiagram_SyncMessage, Messages.SequenceDiagram_SyncMessageReturn, Messages.SequenceDiagram_AsyncMessage, Messages.SequenceDiagram_AsyncMessageReturn, Messages.SequenceDiagram_Frame, Messages.SequenceDiagram_LifelineHeader, Messages.SequenceDiagram_FrameTitle }; + /** + * Array of background color preference names + */ + private static final String[] PREF_BACK_COLOR_LIST = { PREF_LIFELINE, PREF_EXEC, PREF_FRAME, PREF_LIFELINE_HEADER, PREF_FRAME_NAME }; + /** + * Array of foreground color preference names + */ + private static final String[] PREF_FORE_COLOR_LIST = { PREF_LIFELINE, PREF_EXEC, PREF_SYNC_MESS, PREF_SYNC_MESS_RET, PREF_ASYNC_MESS, PREF_ASYNC_MESS_RET, PREF_FRAME, PREF_LIFELINE_HEADER, PREF_FRAME_NAME }; + /** + * Array of text color preference names + */ + private static final String[] PREF_TEXT_COLOR_LIST = { PREF_LIFELINE, PREF_SYNC_MESS, PREF_SYNC_MESS_RET, PREF_ASYNC_MESS, PREF_ASYNC_MESS_RET, PREF_LIFELINE_HEADER, PREF_FRAME_NAME }; + /** + * Temporary tag + * @since 2.0 + */ + public static final String TEMP_TAG = "_TEMP";//$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + /** + * The sequence diagram preferences singleton instance + */ + private static SDViewPref fHandle = null; + /** + * Hashtable for font preferences + */ + private Map fFontPref; + + /** + * Hashtable for foreground color preferences + */ + private Map fForeColorPref; + /** + * Hashtable for background color preferences + */ + private Map fBackColorPref; + /** + * Hashtable for text color preferences + */ + private Map fTextColorPref; + /** + * The reference to the preference store. + */ + private IPreferenceStore fPrefStore = null; + /** + * Color for the time compression selection + */ + private IColor fTimeCompressionSelectionColor = null; + /** + * Flag whether no focus selection or not. + */ + private boolean fNoFocusSelection = false; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Builds the Sequence Diagram preference handler: - Define the preference default values. - Load the currently used + * preferences setting + */ + protected SDViewPref() { + fPrefStore = Activator.getDefault().getPreferenceStore(); + + fPrefStore.setDefault(PREF_LINK_FONT, true); + fPrefStore.setDefault(PREF_EXCLUDE_EXTERNAL_TIME, true); + fPrefStore.setDefault(PREF_LIFELINE_WIDTH, 200); + fPrefStore.setDefault(PREF_USE_GRADIENT, true); + fPrefStore.setDefault(PREF_TOOLTIP, true); + + fFontPref = new Hashtable<>(); + fForeColorPref = new Hashtable<>(); + fBackColorPref = new Hashtable<>(); + fTextColorPref = new Hashtable<>(); + + for (int i = 0; i < FONT_LIST.length; i++) { + if (FONT_LIST[i].equals(PREF_FRAME_NAME)) { + FontData[] data = Display.getDefault().getSystemFont().getFontData(); + data[0].setStyle(SWT.BOLD); + PreferenceConverter.setDefault(fPrefStore, FONT_LIST[i], data[0]); + PreferenceConverter.setDefault(fPrefStore, FONT_LIST[i] + TEMP_TAG, data[0]); + } else { + PreferenceConverter.setDefault(fPrefStore, FONT_LIST[i], Display.getDefault().getSystemFont().getFontData()); + PreferenceConverter.setDefault(fPrefStore, FONT_LIST[i] + TEMP_TAG, Display.getDefault().getSystemFont().getFontData()); + } + } + + for (int i = 0; i < PREF_BACK_COLOR_LIST.length; i++) { + IColor color; + if ((PREF_BACK_COLOR_LIST[i].equals(PREF_EXEC)) || PREF_BACK_COLOR_LIST[i].equals(PREF_FRAME_NAME)) { + color = new ColorImpl(Display.getDefault(), 201, 222, 233); + } else if (PREF_BACK_COLOR_LIST[i].equals(PREF_LIFELINE)) { + color = new ColorImpl(Display.getDefault(), 220, 220, 220); + } else if (PREF_BACK_COLOR_LIST[i].equals(PREF_LIFELINE_HEADER)) { + color = new ColorImpl(Display.getDefault(), 245, 244, 244); + } else { + color = new ColorImpl(Display.getDefault(), 255, 255, 255); + } + PreferenceConverter.setDefault(fPrefStore, PREF_BACK_COLOR_LIST[i] + BACK_COLOR_POSTFIX, ((Color) color.getColor()).getRGB()); + PreferenceConverter.setDefault(fPrefStore, PREF_BACK_COLOR_LIST[i] + BACK_COLOR_POSTFIX + TEMP_TAG, ((Color) color.getColor()).getRGB()); + color.dispose(); + } + + for (int i = 0; i < PREF_FORE_COLOR_LIST.length; i++) { + IColor color; + if (PREF_FORE_COLOR_LIST[i].equals(PREF_LIFELINE)) { + color = new ColorImpl(Display.getDefault(), 129, 129, 129); + } else if (PREF_FORE_COLOR_LIST[i].equals(PREF_FRAME_NAME)) { + color = new ColorImpl(Display.getDefault(), 81, 153, 200); + } else if (PREF_FORE_COLOR_LIST[i].equals(PREF_LIFELINE_HEADER)) { + color = new ColorImpl(Display.getDefault(), 129, 127, 137); + } else { + color = new ColorImpl(Display.getDefault(), 134, 176, 212); + } + PreferenceConverter.setDefault(fPrefStore, PREF_FORE_COLOR_LIST[i] + FORE_COLOR_POSTFIX, ((Color) color.getColor()).getRGB()); + PreferenceConverter.setDefault(fPrefStore, PREF_FORE_COLOR_LIST[i] + FORE_COLOR_POSTFIX + TEMP_TAG, ((Color) color.getColor()).getRGB()); + color.dispose(); + } + + for (int i = 0; i < PREF_TEXT_COLOR_LIST.length; i++) { + IColor color; + if (PREF_TEXT_COLOR_LIST[i].equals(PREF_LIFELINE)) { + color = new ColorImpl(Display.getDefault(), 129, 129, 129); + } else if (PREF_TEXT_COLOR_LIST[i].equals(PREF_FRAME_NAME)) { + color = new ColorImpl(Display.getDefault(), 0, 0, 0); + } else if (PREF_TEXT_COLOR_LIST[i].equals(PREF_LIFELINE_HEADER)) { + color = new ColorImpl(Display.getDefault(), 129, 127, 137); + } else { + color = new ColorImpl(Display.getDefault(), 134, 176, 212); + } + PreferenceConverter.setDefault(fPrefStore, PREF_TEXT_COLOR_LIST[i] + TEXT_COLOR_POSTFIX, ((Color) color.getColor()).getRGB()); + PreferenceConverter.setDefault(fPrefStore, PREF_TEXT_COLOR_LIST[i] + TEXT_COLOR_POSTFIX + TEMP_TAG, ((Color) color.getColor()).getRGB()); + color.dispose(); + } + + IColor color = new ColorImpl(Display.getDefault(), 218, 232, 238); + PreferenceConverter.setDefault(fPrefStore, PREF_TIME_COMP, ((Color) color.getColor()).getRGB()); + color.dispose(); + + buildFontsAndColors(); + + fPrefStore.addPropertyChangeListener(this); + } + + /** + * Returns the PreferenceStore + * + * @return the PreferenceStore + */ + public IPreferenceStore getPreferenceStore() { + return fPrefStore; + } + + /** + * Apply the preferences in the preferences handler + */ + public void apply() { + buildFontsAndColors(); + fPrefStore.firePropertyChangeEvent("PREFOK", null, null); //$NON-NLS-1$ + } + + /** + * Returns an unique instance of the Sequence Diagram preference handler + * + * @return the preference handler instance + */ + public static synchronized SDViewPref getInstance() { + if (fHandle == null) { + fHandle = new SDViewPref(); + } + return fHandle; + } + + @Override + public IColor getForeGroundColor(String prefName) { + if ((fForeColorPref.get(prefName + FORE_COLOR_POSTFIX) != null) && (fForeColorPref.get(prefName + FORE_COLOR_POSTFIX) instanceof ColorImpl)) { + return fForeColorPref.get(prefName + FORE_COLOR_POSTFIX); + } + return ColorImpl.getSystemColor(SWT.COLOR_BLACK); + } + + @Override + public IColor getBackGroundColor(String prefName) { + if ((fBackColorPref.get(prefName + BACK_COLOR_POSTFIX) != null) && (fBackColorPref.get(prefName + BACK_COLOR_POSTFIX) instanceof ColorImpl)) { + return fBackColorPref.get(prefName + BACK_COLOR_POSTFIX); + } + return ColorImpl.getSystemColor(SWT.COLOR_WHITE); + } + + @Override + public IColor getFontColor(String prefName) { + if ((fTextColorPref.get(prefName + TEXT_COLOR_POSTFIX) != null) && (fTextColorPref.get(prefName + TEXT_COLOR_POSTFIX) instanceof ColorImpl)) { + return fTextColorPref.get(prefName + TEXT_COLOR_POSTFIX); + } + return ColorImpl.getSystemColor(SWT.COLOR_BLACK); + } + + @Override + public IColor getForeGroundColorSelection() { + if (fNoFocusSelection) { + return ColorImpl.getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND); + } + return ColorImpl.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT); + } + + @Override + public IColor getBackGroundColorSelection() { + if (fNoFocusSelection) { + return ColorImpl.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); + } + return ColorImpl.getSystemColor(SWT.COLOR_LIST_SELECTION); + } + + @Override + public IFont getFont(String prefName) { + if (fFontPref.get(prefName) != null) { + return fFontPref.get(prefName); + } + return FontImpl.getSystemFont(); + } + + /** + * Returns the SwimLane width chosen + * + * @return the SwimLane width + */ + public int getLifelineWidth() { + return fPrefStore.getInt(PREF_LIFELINE_WIDTH); + } + + /** + * Returns if font linkage with zoom has been chosen + * + * @return true if checked false otherwise + */ + public boolean fontLinked() { + return fPrefStore.getBoolean(PREF_LINK_FONT); + } + + /** + * Returns the tooltip enablement + * + * @return true if checked false otherwise + */ + public boolean tooltipEnabled() { + return fPrefStore.getBoolean(PREF_TOOLTIP); + } + + /** + * Return true if the user do not want to take external time (basically found and lost messages with time) into + * account in the min max computation + * + * @return true if checked false otherwise + */ + public boolean excludeExternalTime() { + return fPrefStore.getBoolean(PREF_EXCLUDE_EXTERNAL_TIME); + } + + @Override + public boolean useGradienColor() { + return fPrefStore.getBoolean(PREF_USE_GRADIENT); + } + + @Override + public IColor getTimeCompressionSelectionColor() { + return fTimeCompressionSelectionColor; + } + + /** + * Builds the new colors and fonts according the current user selection when the OK or Apply button is clicked + */ + private void buildFontsAndColors() { + + Display display = Display.getDefault(); + + for (int i = 0; i < FONT_LIST.length; i++) { + FontData fontData = PreferenceConverter.getFontData(fPrefStore, FONT_LIST[i]); + if (fFontPref.get(FONT_LIST[i]) != null) { + fFontPref.get(FONT_LIST[i]).dispose(); + } + fFontPref.put(FONT_LIST[i], new FontImpl(display, fontData)); + } + + for (int i = 0; i < PREF_BACK_COLOR_LIST.length; i++) { + RGB rgb = PreferenceConverter.getColor(fPrefStore, PREF_BACK_COLOR_LIST[i] + BACK_COLOR_POSTFIX); + if (fBackColorPref.get(PREF_BACK_COLOR_LIST[i] + BACK_COLOR_POSTFIX) != null) { + fBackColorPref.get(PREF_BACK_COLOR_LIST[i] + BACK_COLOR_POSTFIX).dispose(); + } + fBackColorPref.put(PREF_BACK_COLOR_LIST[i] + BACK_COLOR_POSTFIX, new ColorImpl(display, rgb.red, rgb.green, rgb.blue)); + } + + for (int i = 0; i < PREF_FORE_COLOR_LIST.length; i++) { + RGB rgb = PreferenceConverter.getColor(fPrefStore, PREF_FORE_COLOR_LIST[i] + FORE_COLOR_POSTFIX); + if (fForeColorPref.get(PREF_FORE_COLOR_LIST[i] + FORE_COLOR_POSTFIX) != null) { + fForeColorPref.get(PREF_FORE_COLOR_LIST[i] + FORE_COLOR_POSTFIX).dispose(); + } + fForeColorPref.put(PREF_FORE_COLOR_LIST[i] + FORE_COLOR_POSTFIX, new ColorImpl(display, rgb.red, rgb.green, rgb.blue)); + } + + for (int i = 0; i < PREF_TEXT_COLOR_LIST.length; i++) { + RGB rgb = PreferenceConverter.getColor(fPrefStore, PREF_TEXT_COLOR_LIST[i] + TEXT_COLOR_POSTFIX); + if (fTextColorPref.get(PREF_TEXT_COLOR_LIST[i] + TEXT_COLOR_POSTFIX) != null) { + fTextColorPref.get(PREF_TEXT_COLOR_LIST[i] + TEXT_COLOR_POSTFIX).dispose(); + } + fTextColorPref.put(PREF_TEXT_COLOR_LIST[i] + TEXT_COLOR_POSTFIX, new ColorImpl(display, rgb.red, rgb.green, rgb.blue)); + } + + RGB rgb = PreferenceConverter.getColor(fPrefStore, PREF_TIME_COMP); + if (fTimeCompressionSelectionColor != null) { + fTimeCompressionSelectionColor.dispose(); + } + fTimeCompressionSelectionColor = new ColorImpl(display, rgb.red, rgb.green, rgb.blue); + } + + /** + * Add a property-change listener + * + * @param listener + * The listener to add + */ + public void addPropertyChangeListener(IPropertyChangeListener listener) { + fPrefStore.addPropertyChangeListener(listener); + } + + /** + * Remove a property-change listener + * + * @param listener + * The listerner to remove + */ + public void removePropertyChangeListener(IPropertyChangeListener listener) { + fPrefStore.removePropertyChangeListener(listener); + } + + @Override + public void propertyChange(PropertyChangeEvent event) { + if (!event.getProperty().equals("PREFOK")) { //$NON-NLS-1$ + buildFontsAndColors(); + fPrefStore.firePropertyChangeEvent("PREFOK", null, null); //$NON-NLS-1$ + } + } + + /** + * Set the "no focus selection" preference + * + * @param v + * New value to use + */ + public void setNoFocusSelection(boolean v) { + fNoFocusSelection = v; + } + + /** + * Returns a unmodifiable map with font preferences. + * + * @return map with font preferences + * @since 2.0 + */ + protected Map getFontPref() { + return Collections.unmodifiableMap(fFontPref); + } + + /** + * Returns a unmodifiable map with foreground color preferences + * + * @return map with foreground color preferences + * @since 2.0 + */ + public Map getForeColorPref() { + return Collections.unmodifiableMap(fForeColorPref); + } + + /** + * Returns a unmodifiable map with background color preferences + * + * @return map with background color preferences + * @since 2.0 + */ + public Map getBackColorPref() { + return Collections.unmodifiableMap(fBackColorPref); + } + + /** + * Returns a unmodifiable map with text color preferences + * + * @return map with text color preferences + * @since 2.0 + */ + public Map getTextColorPref() { + return Collections.unmodifiableMap(fTextColorPref); + } + + /** + * Returns the preference store. + * + * @return the preference store + * @since 2.0 + */ + public IPreferenceStore getPrefStore() { + return fPrefStore; + } + + /** + * Returns flag about focus selection + * + * @return flag about focus selection + * @since 2.0 + */ + public boolean isNoFocusSelection() { + return fNoFocusSelection; + } + + /** + * Returns the static font list. + * + * @return static font list + */ + public static String[] getFontList() { + return Arrays.copyOf(FONT_LIST, FONT_LIST.length); + } + + /** + * Returns the 2nd static font list. + * + * @return 2nd static font list + */ + public static String[] getFontList2() { + return Arrays.copyOf(FONT_LIST2, FONT_LIST2.length); + } + + /** + * Returns the preference background color list. + * + * @return preference background color list + */ + public static String[] getPrefBackColorList() { + return Arrays.copyOf(PREF_BACK_COLOR_LIST, PREF_BACK_COLOR_LIST.length); + } + + /** + * Returns the preference foreground color list. + * + * @return preference foreground color list + */ + public static String[] getPrefForeColorList() { + return Arrays.copyOf(PREF_FORE_COLOR_LIST, PREF_FORE_COLOR_LIST.length); + } + + /** + * Returns the preference text color list color list. + * + * @return preference text color list color list + */ + public static String[] getPrefTextColorList() { + return Arrays.copyOf(PREF_TEXT_COLOR_LIST, PREF_TEXT_COLOR_LIST.length); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/preferences/SDViewerPage.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/preferences/SDViewerPage.java new file mode 100755 index 0000000000..98ba43fef4 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/preferences/SDViewerPage.java @@ -0,0 +1,431 @@ +/********************************************************************** + * Copyright (c) 2005, 2014 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences; + +import java.util.Iterator; +import java.util.Set; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.ColorFieldEditor; +import org.eclipse.jface.preference.FontFieldEditor; +import org.eclipse.jface.preference.IntegerFieldEditor; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.List; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.Messages; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +/** + * The Sequence Diagram preferences page implementation. + * + * @version 1.0 + * @author sveyrier + */ +public class SDViewerPage extends PreferencePage implements IWorkbenchPreferencePage, SelectionListener { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * Temporary preferences tag + */ + private static final String TEMP_TAG = SDViewPref.TEMP_TAG; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The preference handler used to access the PreferenceStore + */ + private SDViewPref fPreferences = null; + /** + * BackGround color selector + */ + private ColorFieldEditor fLineColor = null; + /** + * Foreground color selector + */ + private ColorFieldEditor fBackGroundColor = null; + /** + * Font color selector + */ + private ColorFieldEditor fTextColor = null; + /** + * List which display all modifiable sequence Diagram font + */ + private List fClassItemList = null; + /** + * Font selector (The same is used for each modifiable font) + */ + private FontFieldEditor fFont = null; + /** + * Link font when zooming selector + */ + private BooleanFieldEditor fLink = null; + /** + * Enable tooltip selector + */ + private BooleanFieldEditor fTooltip = null; + /** + * Do not take external time into account in the min max computation + */ + private BooleanFieldEditor fNoExternalTime = null; + /** + * Use gradient color selector + */ + private BooleanFieldEditor fUseGrad = null; + /** + * A button area. + */ + private Composite fButtonArea; + /** + * SwimLane width selector + */ + private IntegerFieldEditor fLifelineWidth = null; + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + protected Control createContents(Composite parent) { + GridLayout gl = new GridLayout(); + gl.marginHeight = 0; + gl.marginWidth = 0; + parent.setLayout(gl); + Composite page = new Composite(parent, SWT.NONE); + GridLayout pageLayout = new GridLayout(); + pageLayout.numColumns = 2; + GridData pageLayoutdata = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL); + page.setLayoutData(pageLayoutdata); + page.setLayout(pageLayout); + + fTooltip = new BooleanFieldEditor(ISDPreferences.PREF_TOOLTIP, Messages.SequenceDiagram_ShowTooltips, page); + fTooltip.setPreferenceStore(fPreferences.getPreferenceStore()); + fTooltip.load(); + + // link font with zoom pref + fLink = new BooleanFieldEditor(ISDPreferences.PREF_LINK_FONT, Messages.SequenceDiagram_IncreaseFontSizeWhenZooming, page); + fLink.setPreferenceStore(fPreferences.getPreferenceStore()); + fLink.load(); + + fNoExternalTime = new BooleanFieldEditor(ISDPreferences.PREF_EXCLUDE_EXTERNAL_TIME, Messages.SequenceDiagram_ExcludeExternalTime, page); + fNoExternalTime.setPreferenceStore(fPreferences.getPreferenceStore()); + fNoExternalTime.load(); + + // use gradient color pref + fUseGrad = new BooleanFieldEditor(ISDPreferences.PREF_USE_GRADIENT, Messages.SequenceDiagram_UseGradientColor, page); + fUseGrad.setPreferenceStore(fPreferences.getPreferenceStore()); + fUseGrad.load(); + + Label separator = new Label(page, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.SHADOW_NONE); + GridData sepData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL); + separator.setLayoutData(sepData); + + Composite prefPage = new Composite(page, SWT.NONE); + GridLayout prefPageLayout = new GridLayout(); + prefPage.setLayoutData(pageLayoutdata); + prefPageLayout.numColumns = 1; + prefPage.setLayout(prefPageLayout); + + // swimLane width pref + fLifelineWidth = new IntegerFieldEditor(ISDPreferences.PREF_LIFELINE_WIDTH, Messages.SequenceDiagram_LifelineWidth, prefPage); + fLifelineWidth.setPreferenceStore(fPreferences.getPreferenceStore()); + fLifelineWidth.setValidRange(119, 500); + fLifelineWidth.load(); + + // not very nice + new Label(prefPage, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.SHADOW_NONE); + new Label(prefPage, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.SHADOW_NONE); + + // Font list pref + fClassItemList = new List(prefPage, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); + GridData tabItemLayoutdata = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL); + fClassItemList.setLayoutData(tabItemLayoutdata); + + String[] fontList2 = SDViewPref.getFontList2(); + for (int i = 0; i < fontList2.length; i++) { + fClassItemList.add(fontList2[i]); + } + fClassItemList.setSelection(0); + fClassItemList.addSelectionListener(this); + fButtonArea = new Composite(prefPage, SWT.NONE); + GridData tabItemLayoutdata2 = new GridData(GridData.HORIZONTAL_ALIGN_FILL/* |GridData.GRAB_HORIZONTAL */| GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL); + fButtonArea.setLayoutData(tabItemLayoutdata2); + GridLayout buttonAreaLayout = new GridLayout(); + buttonAreaLayout.numColumns = 1; + fButtonArea.setLayout(buttonAreaLayout); + + // font selector initialise for the lifeline font pref + String[] fontList = SDViewPref.getFontList(); + fFont = new FontFieldEditor(fontList[0], "",//$NON-NLS-1$ + Messages.SequenceDiagram_AaBbYyZz, fButtonArea); + fFont.getPreviewControl().setSize(500, 500); + fFont.setPreferenceStore(fPreferences.getPreferenceStore()); + fFont.load(); + + fBackGroundColor = new ColorFieldEditor(fontList[0] + SDViewPref.BACK_COLOR_POSTFIX, Messages.SequenceDiagram_Background, fButtonArea); + fBackGroundColor.setPreferenceStore(fPreferences.getPreferenceStore()); + fBackGroundColor.load(); + + fLineColor = new ColorFieldEditor(fontList[0] + SDViewPref.FORE_COLOR_POSTFIX, Messages.SequenceDiagram_Lines, fButtonArea); + fLineColor.setPreferenceStore(fPreferences.getPreferenceStore()); + fLineColor.load(); + + fTextColor = new ColorFieldEditor(fontList[0] + SDViewPref.TEXT_COLOR_POSTFIX, Messages.SequenceDiagram_Text, fButtonArea); + fTextColor.setPreferenceStore(fPreferences.getPreferenceStore()); + fTextColor.load(); + swapPref(true); + Dialog.applyDialogFont(page); + + return page; + } + + @Override + public void init(IWorkbench workbench) { + fPreferences = SDViewPref.getInstance(); + } + + @Override + protected void performApply() { + // Store the prefrences in the PreferenceStore + if (!fLifelineWidth.isValid()) { + fLifelineWidth.showErrorMessage(); + return; + } + fFont.store(); + fBackGroundColor.store(); + fLineColor.store(); + fLink.store(); + fTooltip.store(); + fNoExternalTime.store(); + fTextColor.store(); + fUseGrad.store(); + fLifelineWidth.store(); + swapPref(false); + // then save them in the preference file + fPreferences.apply(); + swapPref(true); + } + + @Override + public boolean performOk() { + performApply(); + return true; + } + + @Override + protected void performDefaults() { + fLink.loadDefault(); + fTooltip.loadDefault(); + fNoExternalTime.loadDefault(); + fUseGrad.loadDefault(); + fLifelineWidth.loadDefault(); + + // and all the fonts and colors + // fonts and colors are stored for each time because + // we are using only one FontFieldEditor + Set keySet = SDViewPref.getInstance().getFontPref().keySet(); + Iterator it = keySet.iterator(); + while (it.hasNext()) { + Object prefName = it.next(); + if (prefName instanceof String) { + fFont.setPreferenceName((String) prefName); + fFont.loadDefault(); + fFont.setPreferenceName((String) prefName + TEMP_TAG); + fFont.store(); + } + } + + keySet = SDViewPref.getInstance().getBackColorPref().keySet(); + it = keySet.iterator(); + while (it.hasNext()) { + Object prefName = it.next(); + if (prefName instanceof String) { + fBackGroundColor.setPreferenceName((String) prefName); + fBackGroundColor.loadDefault(); + fBackGroundColor.setPreferenceName((String) prefName + TEMP_TAG); + fBackGroundColor.store(); + } + + } + + String[] fontList = SDViewPref.getFontList(); + fBackGroundColor.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + SDViewPref.BACK_COLOR_POSTFIX + TEMP_TAG); + fBackGroundColor.load(); + + keySet = SDViewPref.getInstance().getForeColorPref().keySet(); + it = keySet.iterator(); + while (it.hasNext()) { + Object prefName = it.next(); + if (prefName instanceof String) { + fLineColor.setPreferenceName((String) prefName); + fLineColor.loadDefault(); + fLineColor.setPreferenceName((String) prefName + TEMP_TAG); + fLineColor.store(); + } + } + + fLineColor.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + SDViewPref.FORE_COLOR_POSTFIX + TEMP_TAG); + fLineColor.load(); + + keySet = SDViewPref.getInstance().getTextColorPref().keySet(); + it = keySet.iterator(); + while (it.hasNext()) { + Object prefName = it.next(); + if (prefName instanceof String) { + fTextColor.setPreferenceName((String) prefName); + fTextColor.loadDefault(); + fTextColor.setPreferenceName((String) prefName + TEMP_TAG); + fTextColor.store(); + } + } + fTextColor.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + SDViewPref.TEXT_COLOR_POSTFIX + TEMP_TAG); + fTextColor.load(); + } + + @Override + public void widgetSelected(SelectionEvent e) { + // Store the past set font preference or else the + // FontFieldEditor reassignment will make us loose the current modification + fFont.store(); + fLineColor.store(); + fBackGroundColor.store(); + fTextColor.store(); + + String[] fontList = SDViewPref.getFontList(); + + // set the FontFieldEditor for the new selected graphNode font + fFont.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + TEMP_TAG); + fFont.load(); + + fBackGroundColor.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + SDViewPref.BACK_COLOR_POSTFIX + TEMP_TAG); + fBackGroundColor.load(); + + fLineColor.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + SDViewPref.FORE_COLOR_POSTFIX + TEMP_TAG); + fLineColor.load(); + + fTextColor.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + SDViewPref.TEXT_COLOR_POSTFIX + TEMP_TAG); + fTextColor.load(); + + // No Background for message graphNodes + if ((fontList[fClassItemList.getSelectionIndex()].equals(ISDPreferences.PREF_SYNC_MESS)) || (fontList[fClassItemList.getSelectionIndex()].equals(ISDPreferences.PREF_SYNC_MESS_RET)) + || (fontList[fClassItemList.getSelectionIndex()].equals(ISDPreferences.PREF_ASYNC_MESS)) || (fontList[fClassItemList.getSelectionIndex()].equals(ISDPreferences.PREF_ASYNC_MESS_RET))) { + fBackGroundColor.setEnabled(false, fButtonArea); + } else { + fBackGroundColor.setEnabled(true, fButtonArea); + } + + // No font used for execution occurrence and global frame + if ((fontList[fClassItemList.getSelectionIndex()].equals(ISDPreferences.PREF_EXEC)) || (fontList[fClassItemList.getSelectionIndex()].equals(ISDPreferences.PREF_FRAME))) { + fTextColor.setEnabled(false, fButtonArea); + } else { + fTextColor.setEnabled(true, fButtonArea); + } + + if (fontList[fClassItemList.getSelectionIndex()].equals(ISDPreferences.PREF_FRAME)) { + fFont.setEnabled(false, fButtonArea); + } else { + fFont.setEnabled(true, fButtonArea); + } + } + + /** + * Swap viewer preferences. + * + * @param toTemp Switch to the temporary preferences + */ + protected void swapPref(boolean toTemp) { + String tag1 = "";//$NON-NLS-1$ + String tag2 = TEMP_TAG; + if (!toTemp) { + tag1 = TEMP_TAG; + tag2 = "";//$NON-NLS-1$ + } + Set keySet = SDViewPref.getInstance().getFontPref().keySet(); + Iterator it = keySet.iterator(); + while (it.hasNext()) { + Object prefName = it.next(); + if (prefName instanceof String) { + fFont.setPreferenceName((String) prefName + tag1); + fFont.load(); + fFont.setPreferenceName((String) prefName + tag2); + fFont.store(); + } + } + + keySet = SDViewPref.getInstance().getBackColorPref().keySet(); + it = keySet.iterator(); + while (it.hasNext()) { + Object prefName = it.next(); + if (prefName instanceof String) { + fBackGroundColor.setPreferenceName((String) prefName + tag1); + fBackGroundColor.load(); + fBackGroundColor.setPreferenceName((String) prefName + tag2); + fBackGroundColor.store(); + } + } + + keySet = SDViewPref.getInstance().getForeColorPref().keySet(); + it = keySet.iterator(); + while (it.hasNext()) { + Object prefName = it.next(); + if (prefName instanceof String) { + fLineColor.setPreferenceName((String) prefName + tag1); + fLineColor.load(); + fLineColor.setPreferenceName((String) prefName + tag2); + fLineColor.store(); + } + } + + keySet = SDViewPref.getInstance().getTextColorPref().keySet(); + it = keySet.iterator(); + while (it.hasNext()) { + Object prefName = it.next(); + if (prefName instanceof String) { + fTextColor.setPreferenceName((String) prefName + tag1); + fTextColor.load(); + fTextColor.setPreferenceName((String) prefName + tag2); + fTextColor.store(); + } + } + String[] fontList = SDViewPref.getFontList(); + if (toTemp) { + // set the FontFieldEditor for the new selected graphNode font + fFont.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + TEMP_TAG); + fFont.load(); + + fBackGroundColor.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + SDViewPref.BACK_COLOR_POSTFIX + TEMP_TAG); + fBackGroundColor.load(); + + fLineColor.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + SDViewPref.FORE_COLOR_POSTFIX + TEMP_TAG); + fLineColor.load(); + + fTextColor.setPreferenceName(fontList[fClassItemList.getSelectionIndex()] + SDViewPref.TEXT_COLOR_POSTFIX + TEMP_TAG); + fTextColor.load(); + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/Messages.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/Messages.java new file mode 100755 index 0000000000..0a7f99f150 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/Messages.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * Copyright (c) 2000, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bernd Hufmann - Updated for TMF + * Alexandre Montplaisir - Renamed variables + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.util; + +import org.eclipse.osgi.util.NLS; + +/** + * Messages related to the sequence diagram + * + * @version 1.0 + * @author Bernd Hufmann + * @since 2.0 + */ +@SuppressWarnings("javadoc") +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.messages"; //$NON-NLS-1$ + + private Messages() { + // Do not instantiate + } + + public static String SequenceDiagram_LifelineNode; + public static String SequenceDiagram_MessageNode; + public static String SequenceDiagram_LostMessageNode; + public static String SequenceDiagram_FoundMessageNode; + public static String SequenceDiagram_ExecutionOccurrenceWithParams; + + public static String SequenceDiagram_Find; + public static String SequenceDiagram_Close; + public static String SequenceDiagram_StringNotFound; + public static String SequenceDiagram_SequenceDiagramFind; + public static String SequenceDiagram_SearchFor; + public static String SequenceDiagram_MatchingString; + public static String SequenceDiagram_CaseSensitive; + public static String SequenceDiagram_Lifeline; + public static String SequenceDiagram_Stop; + public static String SequenceDiagram_SynchronousMessage; + public static String SequenceDiagram_SynchronousMessageReturn; + public static String SequenceDiagram_AsynchronousMessage; + public static String SequenceDiagram_AsynchronousMessageReturn; + public static String SequenceDiagram_or; + public static String SequenceDiagram_PreviousPage; + public static String SequenceDiagram_NextPage; + public static String SequenceDiagram_GoToPreviousPage; + public static String SequenceDiagram_GoToNextPage; + public static String SequenceDiagram_GoToMessage; + public static String SequenceDiagram_GoToMessageReturn; + public static String SequenceDiagram_EditFilters; + public static String SequenceDiagram_HidePatterns; + public static String SequenceDiagram_Pages; + + public static String SequenceDiagram_ZoomIn; + public static String SequenceDiagram_ZoomInTheDiagram; + public static String SequenceDiagram_ResetZoomFactor; + public static String SequenceDiagram_ZoomOut; + public static String SequenceDiagram_ZoomOutTheDiagram; + public static String SequenceDiagram_Select; + public static String SequenceDiagram_Max; + public static String SequenceDiagram_Min; + public static String SequenceDiagram_ListOfHideDisplayPatterns; + public static String SequenceDiagram_hide; + public static String SequenceDiagram_display; + public static String SequenceDiagram_EditIt; + public static String SequenceDiagram_Add; + public static String SequenceDiagram_Create; + public static String SequenceDiagram_Update; + public static String SequenceDiagram_Remove; + public static String SequenceDiagram_SequenceDiagramHidePatterns; + public static String SequenceDiagram_DefinitionOfHidePattern; + public static String SequenceDiagram_PageNavigation; + public static String SequenceDiagram_SequenceDiagramPages; + public static String SequenceDiagram_IsInBetween; + public static String SequenceDiagram_Total; + public static String SequenceDiagram_pages; + public static String SequenceDiagram_page; + + public static String SequenceDiagram_CurrentPage; + + public static String SequenceDiagram_Navigation; + public static String SequenceDiagram_OpenOverviewTooltip; + + public static String SequenceDiagram_LifelineWidth; + public static String SequenceDiagram_AaBbYyZz; + public static String SequenceDiagram_IncreaseFontSizeWhenZooming; + public static String SequenceDiagram_ExcludeExternalTime; + public static String SequenceDiagram_UseGradientColor; + public static String SequenceDiagram_Background; + public static String SequenceDiagram_Lines; + public static String SequenceDiagram_Text; + + public static String SequenceDiagram_ExecutionOccurrence; + public static String SequenceDiagram_SyncMessage; + public static String SequenceDiagram_SyncMessageReturn; + public static String SequenceDiagram_AsyncMessage; + public static String SequenceDiagram_AsyncMessageReturn; + public static String SequenceDiagram_Frame; + public static String SequenceDiagram_LifelineHeader; + public static String SequenceDiagram_FrameTitle; + public static String SequenceDiagram_ShowTooltips; + public static String SequenceDiagram_Error; + public static String SequenceDiagram_InvalidRange; + public static String SequenceDiagram_InvalidNbVertical; + public static String SequenceDiagram_InvalidNbHorizontal; + public static String SequenceDiagram_NoPageSelected; + public static String SequenceDiagram_FromPage; + + public static String SequenceDiagram_to; + public static String SequenceDiagram_SelectedPages; + public static String SequenceDiagram_CurrentView; + public static String SequenceDiagram_AllPages; + public static String TotalNumberOfPages; + public static String SequenceDiagram_NumberOfHorizontalPages; + public static String SequenceDiagram_NumberOfVerticalPages; + public static String SequenceDiagram_UseCurrentZoom; + public static String SequenceDiagram_ZoomOption; + public static String SequenceDiagram_Print; + public static String SequenceDiagram_Printer; + public static String SequenceDiagram_plus; + public static String SequenceDiagram_Page; + public static String SequenceDiagram_PrintRange; + public static String SequenceDiagram_Preview; + + public static String SequenceDiagram_TimeCompressionBarConfig; + public static String SequenceDiagram_MinTime; + public static String SequenceDiagram_MaxTime; + public static String SequenceDiagram_Default; + + public static String SequenceDiagram_NoPrinterSelected; + public static String SequenceDiagram_Scale; + public static String SequenceDiagram_Precision; + public static String SequenceDiagram_Delta; + + public static String SequenceDiagram_FirstPage; + public static String SequenceDiagram_GoToFirstPage; + public static String SequenceDiagram_LastPage; + public static String SequenceDiagram_GoToLastPage; + + public static String SequenceDiagram_ShowNodeEnd; + public static String SequenceDiagram_ShowNodeStart; + public static String SequenceDiagram_ConfigureMinMax; + + static { + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/SortAsyncForBackward.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/SortAsyncForBackward.java new file mode 100755 index 0000000000..004c23e8fa --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/SortAsyncForBackward.java @@ -0,0 +1,96 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.util; + +import java.io.Serializable; +import java.util.Comparator; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.AsyncMessage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode; + +/** + * Asynchronous message comparator. + * + * Compares two asyncMessages only taking into account the event occurrence when their + * appear.
    + * + * Used to order the AsyncMessage list insuring that the previous node has both of his ends smaller than the current node + * + * @version 1.0 + * @author sveyrier + * + */ +public class SortAsyncForBackward implements Comparator, Serializable { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * Serial version UID + */ + private static final long serialVersionUID = 603959931263853359L; + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public int compare(GraphNode arg0, GraphNode arg1) { + if (arg0 instanceof AsyncMessage && arg1 instanceof AsyncMessage) { + AsyncMessage m1 = (AsyncMessage) arg0; + AsyncMessage m2 = (AsyncMessage) arg1; + int m1Max, m2Max; + // AsyncMessage has two ends which may have different event occurrences + // Search for the greater event occurrence for each messages + if (m1.getStartOccurrence() > m1.getEndOccurrence()) { + m1Max = m1.getStartOccurrence(); + } else { + m1Max = m1.getEndOccurrence(); + } + if (m2.getStartOccurrence() > m2.getEndOccurrence()) { + m2Max = m2.getStartOccurrence(); + } else { + m2Max = m2.getEndOccurrence(); + } + + int m1Min, m2Min; + // Search for the smaller event occurrence for each messages + if (m1.getStartOccurrence() > m1.getEndOccurrence()) { + m1Min = m1.getEndOccurrence(); + } else { + m1Min = m1.getStartOccurrence(); + } + if (m2.getStartOccurrence() > m2.getEndOccurrence()) { + m2Min = m2.getEndOccurrence(); + } else { + m2Min = m2.getStartOccurrence(); + } + + if (m1Max > m2Max) { + return 1; + } else if (m1Max == m2Max) { + if (m1Min == m2Min) { + return 0; + } else if (m1Min > m2Min) { + return -1; + } else { + return 1; + } + } else { + return -1; + } + } + return 0; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/SortAsyncMessageComparator.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/SortAsyncMessageComparator.java new file mode 100755 index 0000000000..251eb46bbf --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/SortAsyncMessageComparator.java @@ -0,0 +1,94 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.util; + +import java.io.Serializable; +import java.util.Comparator; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.AsyncMessage; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode; + +/** + * Asynchronous message comparator Compare two AsyncMessages only taking into account the event occurrence when their + * appear.
    + * + * Used to order the AsyncMessage list insuring that next node has one of his ends greater than the current node + * + * @version 1.0 + * @author sveyrier + * + */ +public class SortAsyncMessageComparator implements Comparator, Serializable { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * Serial version UID + */ + private static final long serialVersionUID = 1L; + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public int compare(GraphNode arg0, GraphNode arg1) { + if (arg0 instanceof AsyncMessage && arg1 instanceof AsyncMessage) { + AsyncMessage m1 = (AsyncMessage) arg0; + AsyncMessage m2 = (AsyncMessage) arg1; + int m1Min, m2Min; + // AsyncMessage has two ends which may have different event occurrences + // Search for the smaller event occurrence for each messages + if (m1.getStartOccurrence() > m1.getEndOccurrence()) { + m1Min = m1.getEndOccurrence(); + } else { + m1Min = m1.getStartOccurrence(); + } + if (m2.getStartOccurrence() > m2.getEndOccurrence()) { + m2Min = m2.getEndOccurrence(); + } else { + m2Min = m2.getStartOccurrence(); + } + + int m1Max, m2Max; + // Search for the greater event occurrence for each messages + if (m1.getStartOccurrence() > m1.getEndOccurrence()) { + m1Max = m1.getStartOccurrence(); + } else { + m1Max = m1.getEndOccurrence(); + } + if (m2.getStartOccurrence() > m2.getEndOccurrence()) { + m2Max = m2.getStartOccurrence(); + } else { + m2Max = m2.getEndOccurrence(); + } + + if (m1Min > m2Min) { + return 1; + } else if ((m1Min == m2Min)) { + if (m1Max == m2Max) { + return 0; + } else if (m1Max > m2Max) { + return -1; + } else { + return 1; + } + } else { + return -1; + } + } + return 0; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/SortSyncMessageComparator.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/SortSyncMessageComparator.java new file mode 100755 index 0000000000..a19d28b1f1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/SortSyncMessageComparator.java @@ -0,0 +1,61 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.util; + +import java.io.Serializable; +import java.util.Comparator; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode; +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SyncMessage; + +/** + * Synchronous message comparator Compare two syncMessages only taking into account the event occurrence when their + * appear.
    + * + * The message with the greater event occurrence is considered to be the greater.
    + * + * @version 1.0 + * @author sveyrier + * + */ +public class SortSyncMessageComparator implements Comparator, Serializable { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * Serial version UID + */ + private static final long serialVersionUID = 4781250984753283718L; + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public int compare(GraphNode arg0, GraphNode arg1) { + if (arg0 instanceof SyncMessage && arg1 instanceof SyncMessage) { + SyncMessage m1 = (SyncMessage) arg0; + SyncMessage m2 = (SyncMessage) arg1; + if (m1.getEventOccurrence() > m2.getEventOccurrence()) { + return 1; + } else if (m1.getEventOccurrence() == m2.getEventOccurrence()) { + return 0; + } else { + return -1; + } + } + return 0; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/TimeEventComparator.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/TimeEventComparator.java new file mode 100755 index 0000000000..3c97af2df7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/TimeEventComparator.java @@ -0,0 +1,53 @@ +/********************************************************************** + * Copyright (c) 2005, 2013 IBM Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Bernd Hufmann - Updated for TMF + **********************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.views.uml2sd.util; + +import java.io.Serializable; +import java.util.Comparator; + +import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SDTimeEvent; + +/** + * Time event comparator + * + * @version 1.0 + * @author sveyrier + */ +public class TimeEventComparator implements Comparator, Serializable { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** + * Serial version UID + */ + private static final long serialVersionUID = 5885497718872575669L; + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public int compare(SDTimeEvent arg0, SDTimeEvent arg1) { + SDTimeEvent t1 = arg0; + SDTimeEvent t2 = arg1; + if (t1.getEvent() > t2.getEvent()) { + return 1; + } + else if (t1.getEvent() == t2.getEvent()) { + return 0; + } + return -1; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/messages.properties b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/messages.properties new file mode 100755 index 0000000000..f8ef1c7c63 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/uml2sd/util/messages.properties @@ -0,0 +1,132 @@ +############################################################################### +# Copyright (c) 2005, 2013 IBM Corporation, Ericsson +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +# Bernd Hufmann - Updated for TMF +# Alexandre Montplaisir - Renamed variables +############################################################################### + +# NLS_MESSAGEFORMAT_VAR +# NLS_ENCODING=UTF-8 + +##SD +SequenceDiagram_LifelineNode=Lifeline node {0} +SequenceDiagram_MessageNode=Message node {0} from Lifeline {1} at event occurrence {2} to Lifeline {3} at event occurrence {4} +SequenceDiagram_LostMessageNode=Lost Message node {0} from Lifeline {1} at event occurrence {2} +SequenceDiagram_FoundMessageNode=Found Message node {0} to Lifeline {1} at event occurrence {2} +SequenceDiagram_ExecutionOccurrenceWithParams=Execution occurrence {0} on Lifeline {1} from event occurrence {2} to {3} + +SequenceDiagram_Find=Find +SequenceDiagram_Close=Close +SequenceDiagram_StringNotFound=String not found +SequenceDiagram_SequenceDiagramFind=Sequence Diagram Find +SequenceDiagram_SearchFor=Search for +SequenceDiagram_MatchingString=Matching string (regular expression): +SequenceDiagram_CaseSensitive=Case sensitive +SequenceDiagram_Lifeline=Lifeline +SequenceDiagram_Stop=Stop +SequenceDiagram_SynchronousMessage=Synchronous message +SequenceDiagram_SynchronousMessageReturn=Synchronous message return +SequenceDiagram_AsynchronousMessage=Asynchronous message +SequenceDiagram_AsynchronousMessageReturn=Asynchronous message return +SequenceDiagram_or=or +SequenceDiagram_PreviousPage=Previous page +SequenceDiagram_NextPage=Next page +SequenceDiagram_GoToPreviousPage=Go to previous page +SequenceDiagram_GoToNextPage=Go to next page +SequenceDiagram_GoToMessage=Go to message +SequenceDiagram_GoToMessageReturn=Go to message return +SequenceDiagram_EditFilters=Edit filters... +SequenceDiagram_HidePatterns=Hide Patterns... +SequenceDiagram_Pages=Pages... +SequenceDiagram_ZoomIn=Zoom in +SequenceDiagram_ZoomInTheDiagram=Zoom in the diagram +SequenceDiagram_ResetZoomFactor=Reset zoom factor +SequenceDiagram_ZoomOut=Zoom out +SequenceDiagram_ZoomOutTheDiagram=Zoom out the diagram +SequenceDiagram_Select=Select +SequenceDiagram_Max=Max +SequenceDiagram_Min=Min +SequenceDiagram_ListOfHideDisplayPatterns=List of hide/display patterns +SequenceDiagram_hide=hide +SequenceDiagram_display=display +SequenceDiagram_EditIt=Edit it +SequenceDiagram_Add=Add... +SequenceDiagram_Create=Create +SequenceDiagram_Update=Update +SequenceDiagram_Remove=Remove +SequenceDiagram_SequenceDiagramHidePatterns=Sequence Diagram Hide Patterns +SequenceDiagram_DefinitionOfHidePattern=Definition of Hide Pattern +SequenceDiagram_PageNavigation=Page navigation +SequenceDiagram_SequenceDiagramPages=Sequence Diagram Pages +SequenceDiagram_IsInBetween={0,number} <= value <= {1,number} +SequenceDiagram_Total=Total: +SequenceDiagram_pages=pages +SequenceDiagram_page=page +SequenceDiagram_CurrentPage=Current page: +SequenceDiagram_Navigation=Navigation +SequenceDiagram_OpenOverviewTooltip=Click to open Overview\nDrag mouse to scroll\nUse Shift+Drag, Ctrl+Drag to scroll slower\nUse Shift+Ctrl+Drag to scroll very fine +SequenceDiagram_LifelineWidth=&Lifeline Width (in pixels) +SequenceDiagram_AaBbYyZz=AaBbYyZz +SequenceDiagram_IncreaseFontSizeWhenZooming=&Increase font size when zooming +SequenceDiagram_ExcludeExternalTime=&Exclude external time +SequenceDiagram_UseGradientColor=&Use gradient color +SequenceDiagram_Background=Background +SequenceDiagram_Lines=Lines +SequenceDiagram_Text=Text +SequenceDiagram_ExecutionOccurrence=Execution Occurrence +SequenceDiagram_SyncMessage=Sync Message +SequenceDiagram_SyncMessageReturn=Sync Message Return +SequenceDiagram_AsyncMessage=Async Message +SequenceDiagram_AsyncMessageReturn=Async Message Return +SequenceDiagram_Frame=Frame +SequenceDiagram_LifelineHeader=Lifeline Header +SequenceDiagram_FrameTitle=Frame Title +SequenceDiagram_ShowTooltips=&Show tooltips +SequenceDiagram_Error=Error +SequenceDiagram_InvalidRange=Invalid range +SequenceDiagram_InvalidNbVertical=Number of vertical pages is invalid +SequenceDiagram_InvalidNbHorizontal=Number of horizontal pages is invalid +SequenceDiagram_NoPageSelected=There is no page selected +SequenceDiagram_FromPage=F&rom page +SequenceDiagram_to=&to +SequenceDiagram_SelectedPages=Selected pages +SequenceDiagram_CurrentView=Current view +SequenceDiagram_AllPages=&All pages +TotalNumberOfPages=Total number of pages: +SequenceDiagram_NumberOfHorizontalPages=Number of horizontal pages: +SequenceDiagram_NumberOfVerticalPages=Number of vertical pages: +SequenceDiagram_UseCurrentZoom=Use current zoom +SequenceDiagram_ZoomOption=Zoom options +SequenceDiagram_Print=Print +SequenceDiagram_Printer=Printer... +SequenceDiagram_plus={0} + {1} +SequenceDiagram_Page=Page {0} +SequenceDiagram_PrintRange=Print range +SequenceDiagram_Preview=Preview + +SequenceDiagram_TimeCompressionBarConfig=TimeCompression bar configuration +SequenceDiagram_MinTime=Min time +SequenceDiagram_MaxTime=Max time +SequenceDiagram_Default=Default + +SequenceDiagram_NoPrinterSelected=No default printer is selected. Click Printer button first and select a printer. + +SequenceDiagram_Scale=Scale +SequenceDiagram_Precision=Precision +SequenceDiagram_Delta=Delta + +SequenceDiagram_FirstPage=First page +SequenceDiagram_GoToFirstPage=Go to first page +SequenceDiagram_LastPage=Last page +SequenceDiagram_GoToLastPage=Go to last page + +SequenceDiagram_ShowNodeEnd=Show the node end +SequenceDiagram_ShowNodeStart=Show the node start +SequenceDiagram_ConfigureMinMax=Configure Min Max... diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/rawviewer/TmfRawEventViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/rawviewer/TmfRawEventViewer.java new file mode 100644 index 0000000000..956de693eb --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/rawviewer/TmfRawEventViewer.java @@ -0,0 +1,1060 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.rawviewer; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CaretEvent; +import org.eclipse.swt.custom.CaretListener; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.events.MouseWheelListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Slider; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; + +/** + * TmfRawEventViewer allows for the display of the raw data for an arbitrarily + * large number of TMF events. + * + * It is essentially a Composite of a StyledText area and a Slider, where the number + * of visible lines in the StyledText control is set to fill the viewer display area. + * An underlying data model is used to store a cache of event raw text line data. + * The slider is ratio-based. + * + * @version 1.0 + * @author Patrick Tasse + */ +public class TmfRawEventViewer extends Composite implements ControlListener, SelectionListener, + KeyListener, CaretListener, MouseMoveListener, MouseTrackListener, MouseWheelListener { + + private static final Color COLOR_BACKGROUND_ODD = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE); + private static final Color COLOR_BACKGROUND_EVEN = new Color(Display.getDefault(), 242, 242, 242); + private static final Color COLOR_BACKGROUND_SELECTED = new Color(Display.getDefault(), 231, 246, 254); + private static final Color COLOR_BACKGROUND_HIGHLIGHTED = new Color(Display.getDefault(), 246, 252, 255); + private static final int MAX_LINE_DATA_SIZE = 1000; + private static final int SLIDER_MAX = 1000000; + + private ITmfTrace fTrace; + private ITmfContext fBottomContext; + + private ScrolledComposite fScrolledComposite; + private Composite fTextArea; + private StyledText fStyledText; + private Font fFixedFont; + private Slider fSlider; + + private final List fLines = new ArrayList<>(); + private boolean fActualRanks = false; + private int fTopLineIndex; + private int fLastTopLineIndex; + private final CaretPosition[] fStoredCaretPosition = new CaretPosition[] + { new CaretPosition(0, 0), new CaretPosition(0,0)}; + private int fNumVisibleLines; + private ITmfLocation fSelectedLocation = null; + private long fHighlightedRank = Long.MIN_VALUE; + private int fCursorYCoordinate = -1; + private int fHoldSelection = 0; + + private static class LineData { + long rank; + ITmfLocation location; + String string; + public LineData(long rank, ITmfLocation location, String string) { + this.rank = rank; + this.location = location; + if (string.length() == 0) { + this.string = " "; // workaround for setLineBackground has no effect on empty line //$NON-NLS-1$ + } else { + this.string = string; + } + } + @Override + public String toString() { + return rank + " [" + location + "]: " + string; //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + private static class CaretPosition { + int time; + int caretOffset; + public CaretPosition(int time, int caretOffset) { + this.time = time; + this.caretOffset = caretOffset; + } + } + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Constructor + * @param parent The parent composite + * @param style The style bits + */ + public TmfRawEventViewer(Composite parent, int style) { + super(parent, style & (~SWT.H_SCROLL) & (~SWT.V_SCROLL)); + + // Set the layout + GridLayout gridLayout = new GridLayout(); + gridLayout.numColumns = 2; + gridLayout.horizontalSpacing = 0; + gridLayout.verticalSpacing = 0; + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + setLayout(gridLayout); + + // Create the controls + createTextArea(style & SWT.H_SCROLL); + createSlider(style & SWT.V_SCROLL); + + // Prevent the slider from being traversed + setTabList(new Control[] { fScrolledComposite }); + } + + @Override + public void dispose() { + if (fFixedFont != null) { + fFixedFont.dispose(); + fFixedFont = null; + } + super.dispose(); + } + + // ------------------------------------------------------------------------ + // Text area handling + // ------------------------------------------------------------------------ + + /** + * Create the text area and add listeners + */ + private void createTextArea(int style) { + fScrolledComposite = new ScrolledComposite(this, style); + fScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + fTextArea = new Composite(fScrolledComposite, SWT.NONE); + fTextArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + fScrolledComposite.setContent(fTextArea); + fScrolledComposite.setExpandHorizontal(true); + fScrolledComposite.setExpandVertical(true); + fScrolledComposite.setAlwaysShowScrollBars(true); + fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + fScrolledComposite.addControlListener(this); + + GridLayout textAreaGridLayout = new GridLayout(); + textAreaGridLayout.marginHeight = 0; + textAreaGridLayout.marginWidth = 0; + fTextArea.setLayout(textAreaGridLayout); + + if (fFixedFont == null) { + if (System.getProperty("os.name").contains("Windows")) { //$NON-NLS-1$ //$NON-NLS-2$ + fFixedFont = new Font(Display.getCurrent(), new FontData("Courier New", 10, SWT.NORMAL)); //$NON-NLS-1$ + } else { + fFixedFont = new Font(Display.getCurrent(), new FontData("Monospace", 10, SWT.NORMAL)); //$NON-NLS-1$ + } + } + + fStyledText = new StyledText(fTextArea, SWT.READ_ONLY); + fStyledText.setFont(fFixedFont); + fStyledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + + fStyledText.addCaretListener(this); + fStyledText.addMouseMoveListener(this); + fStyledText.addMouseTrackListener(this); + fStyledText.addMouseWheelListener(this); + fStyledText.addListener(SWT.MouseWheel, new Listener() { // disable mouse scroll of horizontal scroll bar + @Override + public void handleEvent(Event event) { event.doit = false; }}); + fStyledText.addKeyListener(this); + + fTextArea.setBackground(fStyledText.getBackground()); + fTextArea.addMouseListener(new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { + fTextArea.setFocus(); + }}); + } + + // ------------------------------------------------------------------------ + // Slider handling + // ------------------------------------------------------------------------ + + private void createSlider(int style) { + fSlider = new Slider(this, SWT.VERTICAL); + fSlider.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true)); + fSlider.setValues(0, 0, SLIDER_MAX, SLIDER_MAX, 1, 1); + fSlider.addSelectionListener(this); + if ((style & SWT.V_SCROLL) == 0) { + fSlider.setVisible(false); + } + } + + // ------------------------------------------------------------------------ + // Controls interactions + // ------------------------------------------------------------------------ + + @Override + public boolean setFocus() { + boolean isVisible = isVisible(); + if (isVisible) { + fTextArea.setFocus(); + } + return isVisible; + } + + @Override + public void setMenu(Menu menu) { + fStyledText.setMenu(menu); + } + + /** + * Sets the trace and updates the content + * @param trace The trace to set + */ + public void setTrace(ITmfTrace trace) { + fTrace = trace; + fTopLineIndex = 0; + fLines.clear(); + refreshEventCount(); + } + + /** + * Refreshes the event count, updates the slider thumb and loads display + */ + public void refreshEventCount() { + if (fTrace != null) { + if (fTrace.getNbEvents() > 0) { + fSlider.setThumb((int) Math.max(SLIDER_MAX / fTrace.getNbEvents(), 1)); + } else { + fSlider.setThumb(SLIDER_MAX); + } + + if (!isVisible()) { + return; + } + + if (fLines.size() == 0) { + setTopRank(0); + } else if (fLines.size() < fNumVisibleLines) { + fBottomContext = null; + loadLineData(); + fillTextArea(); + //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents()))); + fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location))); + } + } else { + fBottomContext = null; + fillTextArea(); + fSlider.setThumb(SLIDER_MAX); + fSlider.setSelection(0); + } + } + + /** + * Selects the event of given rank and makes it visible. + * @param rank The rank of event + */ + public void selectAndReveal(long rank) { + if (fTrace == null || !isVisible()) { + return; + } + if (fActualRanks && fTopLineIndex < fLines.size() && rank >= fLines.get(fTopLineIndex).rank) { + int lastVisibleIndex = Math.min(fTopLineIndex + fNumVisibleLines, fLines.size()) - 1; + if (rank <= fLines.get(lastVisibleIndex).rank) { + for (int i = fTopLineIndex; i < fLines.size(); i++) { + if (fLines.get(i).rank == rank) { + fSelectedLocation = fLines.get(i).location; + break; + } + } + refreshLineBackgrounds(); + return; + } + } + setTopRank(rank); + if (fLines.size() > 0 && fHoldSelection == 0) { + fSelectedLocation = fLines.get(0).location; + refreshLineBackgrounds(); + } + } + + /** + * Add a selection listener + * @param listener A listener to add + */ + public void addSelectionListener(Listener listener) { + checkWidget(); + if (listener == null) { + SWT.error (SWT.ERROR_NULL_ARGUMENT); + } + addListener (SWT.Selection, listener); + } + + /** + * Remove selection listener + * @param listener A listener to remove + */ + public void removeSelectionListener(Listener listener) { + checkWidget(); + if (listener == null) { + SWT.error (SWT.ERROR_NULL_ARGUMENT); + } + removeListener(SWT.Selection, listener); + } + + private void sendSelectionEvent(LineData lineData) { + Event event = new Event(); + if (fActualRanks) { + event.data = Long.valueOf(lineData.rank); + } else { + event.data = lineData.location; + } + notifyListeners(SWT.Selection, event); + } + + private void setTopRank(long rank) { + fBottomContext = fTrace.seekEvent(rank); + if (fBottomContext == null) { + return; + } + fLines.clear(); + fActualRanks = true; + fTopLineIndex = 0; + loadLineData(); + refreshTextArea(); + if (fLines.size() == 0) { + fSlider.setSelection(0); + } else { + //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents()))); + fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location))); + } + } + + private void setTopPosition(double ratio) { + fBottomContext = fTrace.seekEvent(ratio); + if (fBottomContext == null) { + return; + } + fBottomContext.setRank(0); + fLines.clear(); + fActualRanks = false; + fTopLineIndex = 0; + loadLineData(); + refreshTextArea(); + } + + private void loadLineData() { + if (fTopLineIndex < 0) { + //if (fLines.size() > 0 && fLines.get(0).rank > 0) { + //long endRank = fLines.get(0).rank; + //long startRank = Math.max(0, endRank - fNumVisibleLines); + //TmfContext context = fTrace.seekEvent(startRank); + //int index = 0; + //while (context.getRank() < endRank) { + //long rank = context.getRank(); + //ITmfLocation location = context.getLocation(); + //TmfEvent event = fTrace.getNextEvent(context); + //String[] lines = event.getRawText().split("\r?\n"); + //for (int i = 0; i < lines.length; i++) { + //String line = lines[i]; + //LineData lineData = new LineData(rank, location, line); + //fLines.add(index++, lineData); + //fTopLineIndex++; + //fLastTopLineIndex++; + //} + //} + //} + if (fLines.size() > 0 && fTrace.getLocationRatio(fLines.get(0).location) > 0) { + double lastRatio = fTrace.getLocationRatio(fLines.get(fLines.size() - 1).location); + double firstRatio = fTrace.getLocationRatio(fLines.get(0).location); + double delta; + boolean singleEvent = false; + if (firstRatio != lastRatio) { + // approximate ratio of at least 20 items + delta = Math.max(20, fNumVisibleLines) * (lastRatio - firstRatio) / (fLines.size() - 1); + } else { + delta = Math.pow(10, -15); + singleEvent = true; + } + while (fTopLineIndex < 0) { + ITmfLocation endLocation = fLines.get(0).location; + firstRatio = Math.max(0, firstRatio - delta); + ITmfContext context = fTrace.seekEvent(firstRatio); + ITmfLocation location; + int index = 0; + long rank = 0; + while (!context.getLocation().equals(endLocation)) { + location = context.getLocation(); + ITmfEvent event = fTrace.getNext(context); + if (event == null) { + break; + } + if (event.getContent() != null && event.getContent().getValue() != null) { + String[] lines = event.getContent().getValue().toString().split("\r?\n"); //$NON-NLS-1$ + for (int i = 0; i < lines.length; i++) { + String line = lines[i]; + LineData lineData = new LineData(rank, location, line); + fLines.add(index++, lineData); + fTopLineIndex++; + fLastTopLineIndex++; + } + } else { + LineData lineData = new LineData(rank, location, ""); //$NON-NLS-1$ + fLines.add(index++, lineData); + fTopLineIndex++; + fLastTopLineIndex++; + } + rank++; + } + long rankOffset = fLines.get(index).rank - rank; + for (int i = 0; i < index; i++) { + fLines.get(i).rank += rankOffset; + } + if (firstRatio == 0) { + break; + } + if (singleEvent) { + delta = Math.min(delta * 10, 0.1); + } + } + } + if (fTopLineIndex < 0) { + fTopLineIndex = 0; + } + } + + while (fLines.size() - fTopLineIndex < fNumVisibleLines) { + if (fBottomContext == null) { + if (fLines.size() == 0) { + fBottomContext = fTrace.seekEvent(0); + } else { + //fBottomContext = fTrace.seekEvent(fLines.get(fLines.size() - 1).rank + 1); + fBottomContext = fTrace.seekEvent(fLines.get(fLines.size() - 1).location); + fTrace.getNext(fBottomContext); + } + if (fBottomContext == null) { + break; + } + } + long rank = fBottomContext.getRank(); + ITmfLocation location = fBottomContext.getLocation() != null ? fBottomContext.getLocation() : null; + ITmfEvent event = fTrace.getNext(fBottomContext); + if (event == null) { + break; + } + if (event.getContent() != null && event.getContent().getValue() != null) { + for (String line : event.getContent().getValue().toString().split("\r?\n")) { //$NON-NLS-1$ + int crPos; + if ((crPos = line.indexOf('\r')) != -1) { + line = line.substring(0, crPos); + } + LineData lineData = new LineData(rank, location, line); + fLines.add(lineData); + } + } else { + LineData lineData = new LineData(rank, location, ""); //$NON-NLS-1$ + fLines.add(lineData); + } + } + fTopLineIndex = Math.max(0, Math.min(fTopLineIndex, fLines.size() - 1)); + + if (fLines.size() > MAX_LINE_DATA_SIZE) { + if (fTopLineIndex < MAX_LINE_DATA_SIZE / 2) { + long rank = fLines.get(MAX_LINE_DATA_SIZE - 1).rank; + for (int i = MAX_LINE_DATA_SIZE; i < fLines.size(); i++) { + if (fLines.get(i).rank > rank) { + fLines.subList(i, fLines.size()).clear(); + fBottomContext = null; + break; + } + } + } else { + long rank = fLines.get(fLines.size() - MAX_LINE_DATA_SIZE).rank; + for (int i = fLines.size() - MAX_LINE_DATA_SIZE - 1; i >= 0; i--) { + if (fLines.get(i).rank < rank) { + fLines.subList(0, i + 1).clear(); + fTopLineIndex -= (i + 1); + fLastTopLineIndex -= (i + 1); + break; + } + } + } + } + } + + private void refreshTextArea() { + fStyledText.setText(""); //$NON-NLS-1$ + for (int i = 0; i < fLines.size() - fTopLineIndex && i < fNumVisibleLines; i++) { + if (i > 0) + { + fStyledText.append("\n"); //$NON-NLS-1$ + } + LineData lineData = fLines.get(fTopLineIndex + i); + fStyledText.append(lineData.string); + setLineBackground(i, lineData); + } + fTextArea.layout(); + fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + fLastTopLineIndex = fTopLineIndex; + } + + private void fillTextArea() { + int nextLine = fStyledText.getCharCount() == 0 ? 0 : fStyledText.getLineCount(); + for (int i = nextLine; i < fLines.size() - fTopLineIndex && i < fNumVisibleLines; i++) { + if (i > 0) + { + fStyledText.append("\n"); //$NON-NLS-1$ + } + LineData lineData = fLines.get(fTopLineIndex + i); + fStyledText.append(lineData.string); + setLineBackground(i, lineData); + } + int endLine = Math.min(fNumVisibleLines, fLines.size()); + if (endLine < fStyledText.getLineCount()) { + int endOffset = fStyledText.getOffsetAtLine(endLine) - 1; + if (endOffset > fStyledText.getCharCount()) { + fHoldSelection++; + fStyledText.replaceTextRange(endOffset, fStyledText.getCharCount() - endOffset, ""); //$NON-NLS-1$ + fHoldSelection--; + } + } + fTextArea.layout(); + fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + } + + private void updateTextArea() { + if (fTopLineIndex < fLastTopLineIndex) { + StringBuffer insertedText = new StringBuffer(); + for (int i = fTopLineIndex; i < fLastTopLineIndex; i++) { + insertedText.append(fLines.get(i).string + "\n"); //$NON-NLS-1$ + } + fStyledText.replaceTextRange(0, 0, insertedText.toString()); + for (int i = 0; i < fLastTopLineIndex - fTopLineIndex; i++) { + LineData lineData = fLines.get(fTopLineIndex + i); + setLineBackground(i, lineData); + } + fLastTopLineIndex = fTopLineIndex; + } else if (fTopLineIndex > fLastTopLineIndex) { + int length = 0; + for (int i = 0; i < fTopLineIndex - fLastTopLineIndex && i < fNumVisibleLines; i++) { + length += fLines.get(i + fLastTopLineIndex).string.length(); + if (i < fStyledText.getLineCount()) { + length += 1; + } + } + fStyledText.replaceTextRange(0, length, ""); //$NON-NLS-1$ + fLastTopLineIndex = fTopLineIndex; + fillTextArea(); + } + int endLine = Math.min(fNumVisibleLines, fLines.size()); + if (endLine < fStyledText.getLineCount()) { + int endOffset = fStyledText.getOffsetAtLine(endLine) - 1; + if (endOffset > fStyledText.getCharCount()) { + fStyledText.replaceTextRange(endOffset, fStyledText.getCharCount() - endOffset, ""); //$NON-NLS-1$ + } + } + fTextArea.layout(); + fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + } + + private void refreshLineBackgrounds() { + for (int i = 0; (i < fStyledText.getLineCount()) && (i < fNumVisibleLines) && (i < fLines.size() - fTopLineIndex); i++) { + LineData lineData = fLines.get(fTopLineIndex + i); + setLineBackground(i, lineData); + } + } + + private void setLineBackground(int index, LineData lineData) { + if (lineData.location.equals(fSelectedLocation)) { + fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_SELECTED); + } else if (lineData.rank == fHighlightedRank) { + fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_HIGHLIGHTED); + } else if (lineData.rank % 2 == 0) { + fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_EVEN); + } else { + fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_ODD); + } + } + + private void storeCaretPosition(int time, int caretOffset) { + if (fStoredCaretPosition[0].time == time) { + fStoredCaretPosition[0].caretOffset = caretOffset; + } else { + fStoredCaretPosition[1] = fStoredCaretPosition[0]; + fStoredCaretPosition[0] = new CaretPosition(time, caretOffset); + } + } + + private int getPreviousCaretOffset(int time) { + if (fStoredCaretPosition[0].time == time) { + return fStoredCaretPosition[1].caretOffset; + } + return fStoredCaretPosition[0].caretOffset; + } + + private void updateHighlightedRank() { + if (fCursorYCoordinate < 0 || fCursorYCoordinate > fStyledText.getSize().y) { + if (fHighlightedRank != Long.MIN_VALUE) { + fHighlightedRank = Long.MIN_VALUE; + refreshLineBackgrounds(); + } + return; + } + int offset = fStyledText.getOffsetAtLocation(new Point(0, fCursorYCoordinate)); + int line = fStyledText.getLineAtOffset(offset); + if (line < fLines.size() - fTopLineIndex) { + LineData lineData = fLines.get(fTopLineIndex + line); + if (fHighlightedRank != lineData.rank) { + fHighlightedRank = lineData.rank; + refreshLineBackgrounds(); + } + } else { + if (fHighlightedRank != Long.MIN_VALUE) { + fHighlightedRank = Long.MIN_VALUE; + refreshLineBackgrounds(); + } + } + } + + // ------------------------------------------------------------------------ + // ControlListener (ScrolledComposite) + // ------------------------------------------------------------------------ + + @Override + public void controlResized(ControlEvent event) { + int areaHeight = fScrolledComposite.getSize().y; + if (fScrolledComposite.getHorizontalBar() != null) { + areaHeight -= fScrolledComposite.getHorizontalBar().getSize().y; + } + int lineHeight = fStyledText.getLineHeight(); + fNumVisibleLines = Math.max((areaHeight + lineHeight - 1) / lineHeight, 1); + + if (fBottomContext != null) { + loadLineData(); + fillTextArea(); + } + } + + @Override + public void controlMoved(ControlEvent e) { + } + + // ------------------------------------------------------------------------ + // SelectionListener (Slider) + // ------------------------------------------------------------------------ + + @Override + public void widgetSelected(SelectionEvent e) { + fTextArea.setFocus(); + if (fLines.size() == 0) { + return; + } + if (e.detail == SWT.DRAG) { + return; + } + fHoldSelection++; + switch (e.detail) { + case SWT.NONE: { + //long rank = (long) (fTrace.getNbEvents() * ((double) fSlider.getSelection() / SLIDER_MAX)); + //setTopRank(rank); + if (fSlider.getSelection() == 0 || fSlider.getThumb() == SLIDER_MAX) { + fLines.clear(); + setTopPosition(0.0); + break; + } + double ratio = (double) fSlider.getSelection() / (SLIDER_MAX - fSlider.getThumb()); + double delta = Math.pow(10, -15); + fLines.clear(); + while (fLines.size() == 0) { + setTopPosition(ratio); + if (ratio == 0.0) { + break; + } + delta = Math.min(delta * 10, 0.1); + ratio = Math.max(ratio - delta, 0.0); + } + break; + } + case SWT.ARROW_DOWN: { + if (fTopLineIndex >= fLines.size()) { + break; + } + fTopLineIndex++; + loadLineData(); + updateTextArea(); + break; + } + case SWT.PAGE_DOWN: { + fTopLineIndex += Math.max(fNumVisibleLines - 1, 1); + loadLineData(); + updateTextArea(); + break; + } + case SWT.ARROW_UP: { + //if (fLines.size() == 0 || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) { + if (fLines.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) { + break; + } + fTopLineIndex--; + loadLineData(); + updateTextArea(); + break; + } + case SWT.PAGE_UP: { + fTopLineIndex -= Math.max(fNumVisibleLines - 1, 1); + loadLineData(); + updateTextArea(); + break; + } + case SWT.HOME: { + //selectAndReveal(0); + setTopPosition(0.0); + break; + } + case SWT.END: { + //if (fTrace.getNbEvents() > 0) { + //selectAndReveal(fTrace.getNbEvents() - 1); + //} + double ratio = 1.0; + double delta = Math.pow(10, -15); + fLines.clear(); + while (fLines.size() == 0) { + setTopPosition(ratio); + if (ratio == 0.0) { + break; + } + delta = Math.min(delta * 10, 0.1); + ratio = Math.max(ratio - delta, 0.0); + } + break; + } + default: + break; + } + //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents()))); + if (e.detail != SWT.NONE) { + fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location))); + } + + fHoldSelection = 0; + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + + // ------------------------------------------------------------------------ + // KeyListener (StyledText) + // ------------------------------------------------------------------------ + + @Override + public void keyPressed(KeyEvent e) { + if (fLines.size() == 0) { + return; + } + int caretOffset = fStyledText.getCaretOffset(); + int previousCaretOffset = getPreviousCaretOffset(e.time); + int previousLineAtCaretPosition = fStyledText.getLineAtOffset(previousCaretOffset); + int previousColumnAtCaretPosition = getPreviousCaretOffset(e.time) - fStyledText.getOffsetAtLine(previousLineAtCaretPosition); + switch (e.keyCode) { + case SWT.ARROW_DOWN: { + if (previousLineAtCaretPosition < (fNumVisibleLines - 2)) { + break; + } + fHoldSelection++; + fTopLineIndex++; + loadLineData(); + updateTextArea(); + fHoldSelection--; + LineData lineData = fLines.get(fTopLineIndex + fStyledText.getLineAtOffset(fStyledText.getCaretOffset())); + if (!lineData.location.equals(fSelectedLocation)) { + fSelectedLocation = lineData.location; + refreshLineBackgrounds(); + sendSelectionEvent(lineData); + } + break; + } + case SWT.PAGE_DOWN: { + if (previousLineAtCaretPosition >= (fNumVisibleLines - 1)) { + fHoldSelection++; + if (fLines.get(fTopLineIndex + previousLineAtCaretPosition).rank % 2 == 0) { + fStyledText.setLineBackground(previousLineAtCaretPosition, 1, COLOR_BACKGROUND_EVEN); + } else { + fStyledText.setLineBackground(previousLineAtCaretPosition, 1, COLOR_BACKGROUND_ODD); + } + fSelectedLocation = null; + fTopLineIndex += Math.max(fNumVisibleLines - 1, 1); + loadLineData(); + updateTextArea(); + fHoldSelection--; + } + int line = Math.min(fNumVisibleLines - 1, fStyledText.getLineCount() - 1); + int offset = fStyledText.getOffsetAtLine(line); + fStyledText.setSelection(offset + Math.min(previousColumnAtCaretPosition, fLines.get(fTopLineIndex + line).string.length())); + break; + } + case SWT.ARROW_RIGHT: { + if (previousCaretOffset < fStyledText.getCharCount() || previousLineAtCaretPosition < (fNumVisibleLines - 2)) { + break; + } + fHoldSelection++; + fTopLineIndex++; + loadLineData(); + updateTextArea(); + fHoldSelection--; + fStyledText.setSelection(fStyledText.getCaretOffset() + 1); + break; + } + case SWT.ARROW_UP: { + if (previousLineAtCaretPosition > 0) { + break; + } + if (fLines.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) { + break; + } + fHoldSelection++; + fTopLineIndex--; + loadLineData(); + updateTextArea(); + fHoldSelection--; + LineData lineData = fLines.get(fTopLineIndex); + if (!lineData.location.equals(fSelectedLocation)) { + fSelectedLocation = lineData.location; + refreshLineBackgrounds(); + sendSelectionEvent(lineData); + } + fStyledText.setSelection(caretOffset); + break; + } + case SWT.PAGE_UP: { + if (previousLineAtCaretPosition > 0) { + break; + } + fHoldSelection++; + fTopLineIndex -= Math.max(fNumVisibleLines - 1, 1); + loadLineData(); + updateTextArea(); + fHoldSelection--; + LineData lineData = fLines.get(fTopLineIndex); + if (!lineData.location.equals(fSelectedLocation)) { + fSelectedLocation = lineData.location; + refreshLineBackgrounds(); + sendSelectionEvent(lineData); + } + fStyledText.setSelection(caretOffset); + break; + } + case SWT.ARROW_LEFT: { + if (previousCaretOffset > 0) { + break; + } + if (fLines.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) { + break; + } + long topRank = fLines.get(fTopLineIndex).rank; + fHoldSelection++; + fTopLineIndex--; + loadLineData(); + updateTextArea(); + fHoldSelection--; + LineData lineData = fLines.get(fTopLineIndex); + if (!lineData.location.equals(fSelectedLocation)) { + fSelectedLocation = lineData.location; + refreshLineBackgrounds(); + sendSelectionEvent(lineData); + } + if (topRank != fLines.get(fTopLineIndex).rank) { + fStyledText.setSelection(fLines.get(fTopLineIndex).string.length()); + } + break; + } + case SWT.HOME: { + if ((e.stateMask & SWT.CTRL) == 0) { + break; + } + //selectAndReveal(0); + setTopPosition(0.0); + LineData lineData = fLines.get(fTopLineIndex); + if (!lineData.location.equals(fSelectedLocation)) { + fSelectedLocation = lineData.location; + refreshLineBackgrounds(); + sendSelectionEvent(lineData); + } + break; + } + case SWT.END: { + if ((e.stateMask & SWT.CTRL) == 0) { + break; + } + //if (fTrace.getNbEvents() > 0) { + //selectAndReveal(fTrace.getNbEvents() - 1); + //} + double ratio = 1.0; + double delta = Math.pow(10, -15); + fLines.clear(); + while (fLines.size() == 0) { + setTopPosition(ratio); + if (ratio == 0.0) { + break; + } + delta = Math.min(delta * 10, 0.1); + ratio = Math.max(ratio - delta, 0.0); + } + LineData lineData = fLines.get(fTopLineIndex); + if (!lineData.location.equals(fSelectedLocation)) { + fSelectedLocation = lineData.location; + refreshLineBackgrounds(); + sendSelectionEvent(lineData); + } + break; + } + default: + break; + } + //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents()))); + updateHighlightedRank(); + fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location))); + } + + @Override + public void keyReleased(KeyEvent e) { + } + + // ------------------------------------------------------------------------ + // CaretListener (StyledText) + // ------------------------------------------------------------------------ + + @Override + public void caretMoved(CaretEvent event) { + if (fHoldSelection == 0) { + int line = fStyledText.getLineAtOffset(event.caretOffset); + if (fTopLineIndex + line < fLines.size()) { + LineData lineData = fLines.get(fTopLineIndex + line); + if (!lineData.location.equals(fSelectedLocation)) { + fSelectedLocation = lineData.location; + refreshLineBackgrounds(); + sendSelectionEvent(lineData); + } + } + } + storeCaretPosition(event.time, event.caretOffset); + if (fHoldSelection == 0) { + Point caret = fStyledText.getLocationAtOffset(fStyledText.getCaretOffset()); + Point origin = fScrolledComposite.getOrigin(); + if (origin.x > caret.x) { + origin.x = caret.x; + } else if (caret.x - origin.x > fScrolledComposite.getSize().x) { + origin.x = caret.x - fScrolledComposite.getSize().x + 1; + } + fScrolledComposite.setOrigin(origin); + } + } + + // ------------------------------------------------------------------------ + // MouseMoveListener (StyledText) + // ------------------------------------------------------------------------ + + @Override + public void mouseMove(MouseEvent e) { + fCursorYCoordinate = e.y; + if (e.y < 0 || e.y > fStyledText.getSize().y) { + if (fHighlightedRank != Long.MIN_VALUE) { + fHighlightedRank = Long.MIN_VALUE; + refreshLineBackgrounds(); + } + return; + } + int offset = fStyledText.getOffsetAtLocation(new Point(0, e.y)); + int line = fStyledText.getLineAtOffset(offset); + if (line < fLines.size() - fTopLineIndex) { + LineData lineData = fLines.get(fTopLineIndex + line); + if (fHighlightedRank != lineData.rank) { + fHighlightedRank = lineData.rank; + refreshLineBackgrounds(); + } + } else { + if (fHighlightedRank != Long.MIN_VALUE) { + fHighlightedRank = Long.MIN_VALUE; + refreshLineBackgrounds(); + } + } + } + + // ------------------------------------------------------------------------ + // MouseTrackListener (StyledText) + // ------------------------------------------------------------------------ + + @Override + public void mouseExit(MouseEvent e) { + fCursorYCoordinate = -1; + if (fHighlightedRank != Long.MIN_VALUE) { + fHighlightedRank = Long.MIN_VALUE; + refreshLineBackgrounds(); + } + } + + @Override + public void mouseEnter(MouseEvent e) { + fCursorYCoordinate = e.y; + } + + @Override + public void mouseHover(MouseEvent e) { + } + + // ------------------------------------------------------------------------ + // MouseWheelListener (StyledText) + // ------------------------------------------------------------------------ + + @Override + public void mouseScrolled(MouseEvent e) { + if (fLines.size() == 0) { + return; + } + fHoldSelection++; + fTopLineIndex -= e.count; + loadLineData(); + updateTextArea(); + fHoldSelection = 0; + //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents()))); + updateHighlightedRank(); + fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location))); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/tabsview/TmfViewerFolder.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/tabsview/TmfViewerFolder.java new file mode 100644 index 0000000000..1977ed2fab --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/tabsview/TmfViewerFolder.java @@ -0,0 +1,193 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.tabsview; + +import java.util.Collection; +import java.util.HashMap; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.tracecompass.tmf.ui.viewers.ITmfViewer; + +/** + * Allows the user to create multiple tabs which makes it look like folders. It + * simplifies the management of the viewer contained in each tab. + * + * The indexing of the viewers is based on their name. + * + * @author Mathieu Denis + * @version 2.0 + * @since 2.0 + */ +public class TmfViewerFolder extends Composite { + + /** + * The list of viewers in the folder + */ + private final HashMap fViewers; + + /** + * The parent folder that contains all viewers + */ + private CTabFolder fFolder; + + /** + * Constructor with empty style + * + * @param parent + * The parent composite + */ + public TmfViewerFolder(Composite parent) { + this(parent, SWT.NONE); + } + + /** + * Constructor + * + * @param parent + * The parent composite + * @param style + * The style of the view that will be created + */ + public TmfViewerFolder(Composite parent, int style) { + super(parent, style); + setLayout(new FillLayout()); + + fViewers = new HashMap<>(); + initFolder(); + } + + @Override + public void dispose() { + super.dispose(); + for (ITmfViewer viewer : fViewers.values()) { + viewer.dispose(); + } + if (fFolder != null) { + fFolder.dispose(); + } + } + + /** + * Disposes of all the viewers contained in the folder and restart to a + * clean state. + */ + public void clear() { + for (ITmfViewer viewer : fViewers.values()) { + viewer.dispose(); + } + fViewers.clear(); + fFolder.dispose(); + initFolder(); + } + + /** + * Create a new tab that will hold the viewer content. The viewer name will + * be used as the name for the tab. The viewer ID must be unique and can be + * used to retrieve the viewer from the folder. + * + * The parent of the viewer control must be the folder returned by + * {@link #getParentFolder()} + * + * @param viewer + * The viewer to put in the new tab + * @param viewerID + * The ID that will be assigned to this viewer for easy + * retrieving + * @param style + * The style of the widget to build + * @return true on success, false otherwise + */ + public boolean addTab(ITmfViewer viewer, String viewerID, int style) { + if (fFolder == null + || viewer.getControl().getParent() != fFolder + || fViewers.containsKey(viewerID)) { + return false; + } + CTabItem item = new CTabItem(fFolder, style); + item.setText(viewer.getName()); + item.setControl(viewer.getControl()); + // Register the viewer in the map to dispose it at closing time + fViewers.put(viewerID, viewer); + return true; + } + + /** + * Gets the folder that will be use as the parent of tabs that will hold the + * viewer. + * + * In order to be able to add new tabs in this view, the parent of the + * viewer control has to be this composite. + * + * @return the folder composite to use as the parent for the viewer control + * to create. + */ + public Composite getParentFolder() { + return fFolder; + } + + /** + * Gets a viewer based on his name. + * + * @param viewerName + * The name of the viewer to find in the folder + * @return The viewer which name is viewerName, or null if there is no such + * viewer + */ + public ITmfViewer getViewer(String viewerName) { + return fViewers.get(viewerName); + } + + /** + * Gets the viewers list contained in the folder view. The list can return + * the viewers in any order. It is not to be assumed that the viewers are + * returned in the same order as they were inserted. + * + * @return a collection of viewers contained in this view. + */ + public Collection getViewers() { + return fViewers.values(); + } + + /** + * Selects the tab at the specified index from the insertion order + * + * @param index + * The index of the tab to be selected + * @throws SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
    • + *
    + */ + public void setSelection(int index) throws SWTException { + fFolder.setSelection(index); + } + + /** + * Initializes the folder or put it a back to a clean state. + */ + private void initFolder() { + if (fFolder != null) { + fFolder.dispose(); + } + fFolder = new CTabFolder(this, SWT.LEFT | SWT.BORDER); + fFolder.setSimple(false); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphColorListener.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphColorListener.java new file mode 100644 index 0000000000..9fd7dc420c --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphColorListener.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph; + +/** + * A time graph state color change listener + * + * @author Geneviève Bastien + * @since 3.0 + */ +public interface ITimeGraphColorListener { + + /** + * Notify the listener that the presentation provider's color may have + * changed and they need to be reloaded + * + * @param stateItems + * The new state table + */ + void colorSettingsChanged(StateItem[] stateItems); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphContentProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphContentProvider.java new file mode 100644 index 0000000000..9e9737a2b3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphContentProvider.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph; + +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; + + +/** + * A content provider mediates between the viewer's model + * and the viewer itself. + * + * @since 3.0 + */ +public interface ITimeGraphContentProvider { + /** + * Returns the time graph entries to display in the viewer when its input is + * set to the given element. + * + * @param inputElement + * the input element + * @return the array of time graph entries to display in the viewer + */ + public ITimeGraphEntry[] getElements(Object inputElement); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider.java new file mode 100644 index 0000000000..3066244c94 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph; + +import java.util.Map; + +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; + +/** + * Interface for the time graph widget provider + * + * @version 1.0 + * @author Patrick Tasse + */ +public interface ITimeGraphPresentationProvider { + + /** State table index for an invisible event + * @since 2.0 + */ + final int INVISIBLE = -1; + + /** State table index for a transparent event (only borders drawn) + * @since 2.0 + */ + final int TRANSPARENT = -2; + + /** + * Returns the name of state types. + * + * @return the name of state types + */ + String getStateTypeName(); + + /** + * Returns the name of state type depending on the given entry. + * Note that this overwrites the name which is return by getStateTypeName(). + * + * @param entry + * the entry + * @return the name of state type depending on the given entry or null. + * @since 2.0 + */ + String getStateTypeName(ITimeGraphEntry entry); + + /** + * Returns table of states with state name to state color relationship. + * + * @return table of states with color and name + * + * @see #getStateTableIndex + */ + StateItem[] getStateTable(); + + /** + * Returns the index in the state table corresponding to this time event. + * The index should correspond to a state in the state table, + * otherwise the color SWT.COLOR_BLACK will be used. + * If the index returned is TRANSPARENT, only the event borders will be drawn. + * If the index returned is INVISIBLE or another negative, the event will not be drawn. + * + * @param event the time event + * @return the corresponding state table index + * + * @see #getStateTable + * @see #TRANSPARENT + * @see #INVISIBLE + */ + int getStateTableIndex(ITimeEvent event); + + /** + * Called after drawing the control + * + * @param bounds + * The drawing rectangle + * @param gc + * The graphics context + */ + void postDrawControl(Rectangle bounds, GC gc); + + /** + * Called after drawing an entry + * + * @param entry + * the entry that was drawn + * @param bounds + * the drawing rectangle + * @param gc + * the graphics context + */ + void postDrawEntry(ITimeGraphEntry entry, Rectangle bounds, GC gc); + + /** + * Called after drawing an event + * + * @param event + * the event that was drawn + * @param bounds + * the drawing rectangle + * @param gc + * the graphics context + */ + void postDrawEvent(ITimeEvent event, Rectangle bounds, GC gc); + + /** + * Returns the height of this item. This value is ignored if the time graph has a fixed item height. + * + * @param entry the entry + * @return the item height + * + * @see TimeGraphViewer#setItemHeight + */ + int getItemHeight(ITimeGraphEntry entry); + + /** + * Provides the image icon for a given entry. + * + * @param entry the entry + * @return the image icon + */ + Image getItemImage(ITimeGraphEntry entry); + + /** + * Returns the name of this event. + * + * @param event + * The event + * @return The event name + */ + String getEventName(ITimeEvent event); + + /** + * Returns a map of name and value providing additional information + * to display in the tool tip for this event. + * + * @param event the time event + * @return a map of tool tip information + */ + Map getEventHoverToolTipInfo(ITimeEvent event); + + /** + * Returns a map of name and value providing additional information + * to display in the tool tip for this event. + * + * @param event the time event + * @param hoverTime the time corresponding to the mouse hover position + * @return a map of tool tip information + * + * @since 2.0 + */ + Map getEventHoverToolTipInfo(ITimeEvent event, long hoverTime); + + /** + * Check whether time and duration should be displayed in tooltip (after items from + * {@link #getEventHoverToolTipInfo(ITimeEvent)}). + * + * @return true if times and duration should be displayed on tooltip, false otherwise. + * + * @since 3.0 + */ + public boolean displayTimesInTooltip(); + + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider2.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider2.java new file mode 100644 index 0000000000..c644dc5334 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider2.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Add drawing helper methods + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph; + +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.ITmfTimeGraphDrawingHelper; + +/** + * Extension of the ITimeGraphPresentationProvider interface to avoid API breakage + * + * @author Geneviève Bastien + * @since 2.1 + * TODO: Add me to ITimeGraphPresentationProvider before the 3.0 release + */ +public interface ITimeGraphPresentationProvider2 extends ITimeGraphPresentationProvider { + + /** + * Returns the drawing helper for this presentation provider. + * + * @return The drawing helper + */ + ITmfTimeGraphDrawingHelper getDrawingHelper(); + + /** + * Sets this presentation provider's drawing helper. + * This helper be needed to know where to draw items, get its coordinates + * given a time, etc. + * + * @param helper + * The drawing helper + */ + void setDrawingHelper(ITmfTimeGraphDrawingHelper helper); + + /** + * Adds a color settings listener, to be notified when the presentation + * provider's state colors change. + * + * @param listener + * The new listener for color settings changes + * @since 3.0 + */ + public void addColorListener(ITimeGraphColorListener listener); + + /** + * Removes a color settings listener. + * + * @param listener + * The color settings listener to remove + * @since 3.0 + */ + public void removeColorListener(ITimeGraphColorListener listener); + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphRangeListener.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphRangeListener.java new file mode 100644 index 0000000000..1b66f59879 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphRangeListener.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph; + +import java.util.EventListener; + +/** + * A listener which is notified when a timegraph changes its visible time range. + * + * @version 1.0 + * @author Patrick Tasse + */ +public interface ITimeGraphRangeListener extends EventListener { + + /** + * Notifies that the timegraph range has changed. + * + * @param event event object describing details + */ + void timeRangeUpdated(TimeGraphRangeUpdateEvent event); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphSelectionListener.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphSelectionListener.java new file mode 100644 index 0000000000..0159b1c4fb --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphSelectionListener.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph; + +import java.util.EventListener; + +/** + * A listener which is notified when a timegraph changes its selected time. + * + * @version 1.0 + * @author Patrick Tasse + */ +public interface ITimeGraphSelectionListener extends EventListener { + + /** + * Notifies that the timegraph selected entry has changed. + * + * @param event event object describing details + */ + void selectionChanged(TimeGraphSelectionEvent event); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphTimeListener.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphTimeListener.java new file mode 100644 index 0000000000..766544a7e9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphTimeListener.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph; + +import java.util.EventListener; + +/** + * A listener which is notified when a timegraph changes its selected time. + * + * @version 1.0 + * @author Patrick Tasse + */ +public interface ITimeGraphTimeListener extends EventListener { + + /** + * Notifies that the timegraph selected time has changed. + * + * @param event event object describing details + */ + void timeSelected(TimeGraphTimeEvent event); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphTreeListener.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphTreeListener.java new file mode 100644 index 0000000000..3c44eabb20 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphTreeListener.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph; + +/** + * A listener which is notified when a timegraph expands or collapses an entry. + * + * @version 1.0 + * @author Patrick Tasse + */ +public interface ITimeGraphTreeListener { + + /** + * Notifies that an entry in the timegraph has been collapsed. + * + * @param event event object describing details + */ + void treeCollapsed(TimeGraphTreeExpansionEvent event); + + /** + * Notifies that an entry in the timegraph has been expanded. + * + * @param event event object describing details + */ + void treeExpanded(TimeGraphTreeExpansionEvent event); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/StateItem.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/StateItem.java new file mode 100644 index 0000000000..a840b97d3b --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/StateItem.java @@ -0,0 +1,107 @@ +/********************************************************************** + * Copyright (c) 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bernd Hufmann - Initial API and implementation + **********************************************************************/ +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph; + +import org.eclipse.swt.graphics.RGB; + +/** + * Class that contains the color of a state and the corresponding state string + * to display. + * + * @version 1.0 + * @author Bernd Hufmann + */ +public class StateItem { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + /** + * Name of state if not known + */ + public static final String UNDEFINED_STATE_NAME = "Undefined"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + /** + * The State color + */ + private RGB fStateColor; + /** + * The State string. + */ + private String fStateString; + + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Creates a state item with given color and unspecified name. + * + * @param stateColor A state color + */ + public StateItem(RGB stateColor) { + this(stateColor, UNDEFINED_STATE_NAME); + } + + /** + * Creates a state color - state string pair. + * + * @param stateColor A state color + * @param stateString A state string + */ + public StateItem(RGB stateColor, String stateString) { + fStateColor = stateColor; + fStateString = stateString; + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + /** + * Returns the state color. + * + * @return Returns the state color. + */ + public RGB getStateColor() { + return fStateColor; + } + + /** + * Sets the state color. + * + * @param stateColor A state color to set + */ + public void setStateColor(RGB stateColor) { + fStateColor = stateColor; + } + + /** + * Returns the state string. + * + * @return the state string. + */ + public String getStateString() { + return fStateString; + } + + /** + * Sets the state string + * @param stateString A state string to set + */ + public void setStateString(String stateString) { + fStateString = stateString; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphCombo.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphCombo.java new file mode 100644 index 0000000000..d99d282041 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphCombo.java @@ -0,0 +1,1134 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson, others + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * François Rajotte - Filter implementation + * Geneviève Bastien - Add event links between entries + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph; + +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.Set; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.ITreeViewerListener; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeExpansionEvent; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseTrackAdapter; +import org.eclipse.swt.events.MouseWheelListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Slider; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.TimeGraphFilterDialog; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; + +/** + * Time graph "combo" view (with the list/tree on the left and the gantt chart + * on the right) + * + * @version 1.0 + * @author Patrick Tasse + */ +public class TimeGraphCombo extends Composite { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /** Constant indicating that all levels of the time graph should be expanded + * @since 3.1 */ + public static final int ALL_LEVELS = AbstractTreeViewer.ALL_LEVELS; + + private static final Object FILLER = new Object(); + + private static final String ITEM_HEIGHT = "$height$"; //$NON-NLS-1$ + + // ------------------------------------------------------------------------ + // Fields + // ------------------------------------------------------------------------ + + /** The tree viewer */ + private TreeViewer fTreeViewer; + + /** The time viewer */ + private TimeGraphViewer fTimeGraphViewer; + + /** The selection listener map */ + private final Map fSelectionListenerMap = new HashMap<>(); + + /** The map of viewer filters */ + private final Map fViewerFilterMap = new HashMap<>(); + + /** + * Flag to block the tree selection changed listener when triggered by the + * time graph combo + */ + private boolean fInhibitTreeSelection = false; + + /** Number of filler rows used by the tree content provider */ + private int fNumFillerRows; + + /** Calculated item height for Linux workaround */ + private int fLinuxItemHeight = 0; + + /** The button that opens the filter dialog */ + private Action showFilterAction; + + /** The filter dialog */ + private TimeGraphFilterDialog fFilterDialog; + + /** The filter generated from the filter dialog */ + private RawViewerFilter fFilter; + + /** Default weight of each part of the sash */ + private static final int[] DEFAULT_WEIGHTS = { 1, 1 }; + + /** List of all expanded items whose parents are also expanded */ + private List fVisibleExpandedItems = null; + + // ------------------------------------------------------------------------ + // Classes + // ------------------------------------------------------------------------ + + /** + * The TreeContentProviderWrapper is used to insert filler items after + * the elements of the tree's real content provider. + */ + private class TreeContentProviderWrapper implements ITreeContentProvider { + private final ITreeContentProvider contentProvider; + + public TreeContentProviderWrapper(ITreeContentProvider contentProvider) { + this.contentProvider = contentProvider; + } + + @Override + public void dispose() { + contentProvider.dispose(); + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + contentProvider.inputChanged(viewer, oldInput, newInput); + } + + @Override + public Object[] getElements(Object inputElement) { + Object[] elements = contentProvider.getElements(inputElement); + // add filler elements to ensure alignment with time analysis viewer + Object[] oElements = Arrays.copyOf(elements, elements.length + fNumFillerRows, Object[].class); + for (int i = 0; i < fNumFillerRows; i++) { + oElements[elements.length + i] = FILLER; + } + return oElements; + } + + @Override + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof ITimeGraphEntry) { + return contentProvider.getChildren(parentElement); + } + return new Object[0]; + } + + @Override + public Object getParent(Object element) { + if (element instanceof ITimeGraphEntry) { + return contentProvider.getParent(element); + } + return null; + } + + @Override + public boolean hasChildren(Object element) { + if (element instanceof ITimeGraphEntry) { + return contentProvider.hasChildren(element); + } + return false; + } + } + + /** + * The TreeLabelProviderWrapper is used to intercept the filler items + * from the calls to the tree's real label provider. + */ + private class TreeLabelProviderWrapper implements ITableLabelProvider { + private final ITableLabelProvider labelProvider; + + public TreeLabelProviderWrapper(ITableLabelProvider labelProvider) { + this.labelProvider = labelProvider; + } + + @Override + public void addListener(ILabelProviderListener listener) { + labelProvider.addListener(listener); + } + + @Override + public void dispose() { + labelProvider.dispose(); + } + + @Override + public boolean isLabelProperty(Object element, String property) { + if (element instanceof ITimeGraphEntry) { + return labelProvider.isLabelProperty(element, property); + } + return false; + } + + @Override + public void removeListener(ILabelProviderListener listener) { + labelProvider.removeListener(listener); + } + + @Override + public Image getColumnImage(Object element, int columnIndex) { + if (element instanceof ITimeGraphEntry) { + return labelProvider.getColumnImage(element, columnIndex); + } + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + if (element instanceof ITimeGraphEntry) { + return labelProvider.getColumnText(element, columnIndex); + } + return null; + } + + } + + /** + * The SelectionListenerWrapper is used to intercept the filler items from + * the time graph combo's real selection listener, and to prevent double + * notifications from being sent when selection changes in both tree and + * time graph at the same time. + */ + private class SelectionListenerWrapper implements ISelectionChangedListener, ITimeGraphSelectionListener { + private final ITimeGraphSelectionListener listener; + private ITimeGraphEntry selection = null; + + public SelectionListenerWrapper(ITimeGraphSelectionListener listener) { + this.listener = listener; + } + + @Override + public void selectionChanged(SelectionChangedEvent event) { + if (fInhibitTreeSelection) { + return; + } + Object element = ((IStructuredSelection) event.getSelection()).getFirstElement(); + if (element instanceof ITimeGraphEntry) { + ITimeGraphEntry entry = (ITimeGraphEntry) element; + if (entry != selection) { + selection = entry; + listener.selectionChanged(new TimeGraphSelectionEvent(event.getSource(), selection)); + } + } + } + + @Override + public void selectionChanged(TimeGraphSelectionEvent event) { + ITimeGraphEntry entry = event.getSelection(); + if (entry != selection) { + selection = entry; + listener.selectionChanged(new TimeGraphSelectionEvent(event.getSource(), selection)); + } + } + } + + /** + * The ViewerFilterWrapper is used to intercept the filler items from + * the time graph combo's real ViewerFilters. These filler items should + * always be visible. + */ + private class ViewerFilterWrapper extends ViewerFilter { + + private ViewerFilter fWrappedFilter; + + ViewerFilterWrapper(ViewerFilter filter) { + super(); + this.fWrappedFilter = filter; + } + + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + if (element instanceof ITimeGraphEntry) { + return fWrappedFilter.select(viewer, parentElement, element); + } + return true; + } + + } + + /** + * This filter simply keeps a list of elements that should be filtered out. + * All the other elements will be shown. + * By default and when the list is set to null, all elements are shown. + */ + private class RawViewerFilter extends ViewerFilter { + + private List fFiltered = null; + + public void setFiltered(List objects) { + fFiltered = objects; + } + + public List getFiltered() { + return fFiltered; + } + + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + if (fFiltered == null) { + return true; + } + return !fFiltered.contains(element); + } + } + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + + /** + * Constructs a new instance of this class given its parent + * and a style value describing its behavior and appearance. + * + * @param parent a widget which will be the parent of the new instance (cannot be null) + * @param style the style of widget to construct + */ + public TimeGraphCombo(Composite parent, int style) { + this(parent, style, DEFAULT_WEIGHTS); + } + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + * @param weights + * The relative weights of each side of the sash form + * @since 2.1 + */ + public TimeGraphCombo(Composite parent, int style, int[] weights) { + super(parent, style); + setLayout(new FillLayout()); + + final SashForm sash = new SashForm(this, SWT.NONE); + + fTreeViewer = new TreeViewer(sash, SWT.FULL_SELECTION | SWT.H_SCROLL); + fTreeViewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS); + final Tree tree = fTreeViewer.getTree(); + tree.setHeaderVisible(true); + tree.setLinesVisible(true); + + fTimeGraphViewer = new TimeGraphViewer(sash, SWT.NONE); + fTimeGraphViewer.setItemHeight(getItemHeight(tree)); + fTimeGraphViewer.setHeaderHeight(tree.getHeaderHeight()); + fTimeGraphViewer.setBorderWidth(tree.getBorderWidth()); + fTimeGraphViewer.setNameWidthPref(0); + + fFilter = new RawViewerFilter(); + addFilter(fFilter); + + fFilterDialog = new TimeGraphFilterDialog(getShell()); + + // Feature in Windows. The tree vertical bar reappears when + // the control is resized so we need to hide it again. + // Bug in Linux. The tree header height is 0 in constructor, + // so we need to reset it later when the control is resized. + tree.addControlListener(new ControlAdapter() { + private int depth = 0; + @Override + public void controlResized(ControlEvent e) { + if (depth == 0) { + depth++; + tree.getVerticalBar().setEnabled(false); + // this can trigger controlResized recursively + tree.getVerticalBar().setVisible(false); + depth--; + } + fTimeGraphViewer.setHeaderHeight(tree.getHeaderHeight()); + } + }); + + // ensure synchronization of expanded items between tree and time graph + fTreeViewer.addTreeListener(new ITreeViewerListener() { + @Override + public void treeCollapsed(TreeExpansionEvent event) { + fTimeGraphViewer.setExpandedState((ITimeGraphEntry) event.getElement(), false); + // queue the alignment update because the tree items may only be + // actually collapsed after the listeners have been notified + fVisibleExpandedItems = null; // invalidate the cache + getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + alignTreeItems(true); + }}); + } + + @Override + public void treeExpanded(TreeExpansionEvent event) { + ITimeGraphEntry entry = (ITimeGraphEntry) event.getElement(); + fTimeGraphViewer.setExpandedState(entry, true); + Set expandedElements = new HashSet<>(Arrays.asList(fTreeViewer.getExpandedElements())); + for (ITimeGraphEntry child : entry.getChildren()) { + if (child.hasChildren()) { + boolean expanded = expandedElements.contains(child); + fTimeGraphViewer.setExpandedState(child, expanded); + } + } + // queue the alignment update because the tree items may only be + // actually expanded after the listeners have been notified + fVisibleExpandedItems = null; // invalidate the cache + getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + alignTreeItems(true); + }}); + } + }); + + // ensure synchronization of expanded items between tree and time graph + fTimeGraphViewer.addTreeListener(new ITimeGraphTreeListener() { + @Override + public void treeCollapsed(TimeGraphTreeExpansionEvent event) { + fTreeViewer.setExpandedState(event.getEntry(), false); + alignTreeItems(true); + } + + @Override + public void treeExpanded(TimeGraphTreeExpansionEvent event) { + ITimeGraphEntry entry = event.getEntry(); + fTreeViewer.setExpandedState(entry, true); + Set expandedElements = new HashSet<>(Arrays.asList(fTreeViewer.getExpandedElements())); + for (ITimeGraphEntry child : entry.getChildren()) { + if (child.hasChildren()) { + boolean expanded = expandedElements.contains(child); + fTimeGraphViewer.setExpandedState(child, expanded); + } + } + alignTreeItems(true); + } + }); + + // prevent mouse button from selecting a filler tree item + tree.addListener(SWT.MouseDown, new Listener() { + @Override + public void handleEvent(Event event) { + TreeItem treeItem = tree.getItem(new Point(event.x, event.y)); + if (treeItem == null || treeItem.getData() == FILLER) { + event.doit = false; + List treeItems = getVisibleExpandedItems(tree, false); + if (treeItems.size() == 0) { + fTreeViewer.setSelection(new StructuredSelection()); + fTimeGraphViewer.setSelection(null); + return; + } + // this prevents from scrolling up when selecting + // the partially visible tree item at the bottom + tree.select(treeItems.get(treeItems.size() - 1)); + fTreeViewer.setSelection(new StructuredSelection()); + fTimeGraphViewer.setSelection(null); + } + } + }); + + // prevent mouse wheel from scrolling down into filler tree items + tree.addListener(SWT.MouseWheel, new Listener() { + @Override + public void handleEvent(Event event) { + event.doit = false; + Slider scrollBar = fTimeGraphViewer.getVerticalBar(); + fTimeGraphViewer.setTopIndex(scrollBar.getSelection() - event.count); + alignTreeItems(false); + } + }); + + // prevent key stroke from selecting a filler tree item + tree.addListener(SWT.KeyDown, new Listener() { + @Override + public void handleEvent(Event event) { + List treeItems = getVisibleExpandedItems(tree, false); + if (treeItems.size() == 0) { + fTreeViewer.setSelection(new StructuredSelection()); + event.doit = false; + return; + } + if (event.keyCode == SWT.ARROW_DOWN) { + int index = Math.min(fTimeGraphViewer.getSelectionIndex() + 1, treeItems.size() - 1); + fTimeGraphViewer.setSelection((ITimeGraphEntry) treeItems.get(index).getData()); + event.doit = false; + } else if (event.keyCode == SWT.PAGE_DOWN) { + int height = tree.getSize().y - tree.getHeaderHeight() - tree.getHorizontalBar().getSize().y; + int countPerPage = height / getItemHeight(tree); + int index = Math.min(fTimeGraphViewer.getSelectionIndex() + countPerPage - 1, treeItems.size() - 1); + fTimeGraphViewer.setSelection((ITimeGraphEntry) treeItems.get(index).getData()); + event.doit = false; + } else if (event.keyCode == SWT.END) { + fTimeGraphViewer.setSelection((ITimeGraphEntry) treeItems.get(treeItems.size() - 1).getData()); + event.doit = false; + } + if (fTimeGraphViewer.getSelectionIndex() >= 0) { + fTreeViewer.setSelection(new StructuredSelection(fTimeGraphViewer.getSelection())); + } else { + fTreeViewer.setSelection(new StructuredSelection()); + } + alignTreeItems(false); + } + }); + + // ensure alignment of top item between tree and time graph + fTimeGraphViewer.getTimeGraphControl().addControlListener(new ControlAdapter() { + @Override + public void controlResized(ControlEvent e) { + alignTreeItems(false); + } + }); + + // ensure synchronization of selected item between tree and time graph + fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + if (fInhibitTreeSelection) { + return; + } + if (event.getSelection() instanceof IStructuredSelection) { + Object selection = ((IStructuredSelection) event.getSelection()).getFirstElement(); + if (selection instanceof ITimeGraphEntry) { + fTimeGraphViewer.setSelection((ITimeGraphEntry) selection); + } + alignTreeItems(false); + } + } + }); + + // ensure synchronization of selected item between tree and time graph + fTimeGraphViewer.addSelectionListener(new ITimeGraphSelectionListener() { + @Override + public void selectionChanged(TimeGraphSelectionEvent event) { + ITimeGraphEntry entry = fTimeGraphViewer.getSelection(); + fInhibitTreeSelection = true; // block the tree selection changed listener + if (entry != null) { + StructuredSelection selection = new StructuredSelection(entry); + fTreeViewer.setSelection(selection); + } else { + fTreeViewer.setSelection(new StructuredSelection()); + } + fInhibitTreeSelection = false; + alignTreeItems(false); + } + }); + + // ensure alignment of top item between tree and time graph + fTimeGraphViewer.getVerticalBar().addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + alignTreeItems(false); + } + }); + + // ensure alignment of top item between tree and time graph + fTimeGraphViewer.getTimeGraphControl().addMouseWheelListener(new MouseWheelListener() { + @Override + public void mouseScrolled(MouseEvent e) { + alignTreeItems(false); + } + }); + + // ensure the tree has focus control when mouse is over it if the time graph had control + fTreeViewer.getControl().addMouseTrackListener(new MouseTrackAdapter() { + @Override + public void mouseEnter(MouseEvent e) { + if (fTimeGraphViewer.getTimeGraphControl().isFocusControl()) { + fTreeViewer.getControl().setFocus(); + } + } + }); + + // ensure the time graph has focus control when mouse is over it if the tree had control + fTimeGraphViewer.getTimeGraphControl().addMouseTrackListener(new MouseTrackAdapter() { + @Override + public void mouseEnter(MouseEvent e) { + if (fTreeViewer.getControl().isFocusControl()) { + fTimeGraphViewer.getTimeGraphControl().setFocus(); + } + } + }); + fTimeGraphViewer.getTimeGraphScale().addMouseTrackListener(new MouseTrackAdapter() { + @Override + public void mouseEnter(MouseEvent e) { + if (fTreeViewer.getControl().isFocusControl()) { + fTimeGraphViewer.getTimeGraphControl().setFocus(); + } + } + }); + + // The filler rows are required to ensure alignment when the tree does not have a + // visible horizontal scroll bar. The tree does not allow its top item to be set + // to a value that would cause blank space to be drawn at the bottom of the tree. + fNumFillerRows = Display.getDefault().getBounds().height / getItemHeight(tree); + + sash.setWeights(weights); + } + + // ------------------------------------------------------------------------ + // Accessors + // ------------------------------------------------------------------------ + + /** + * Returns this time graph combo's tree viewer. + * + * @return the tree viewer + */ + public TreeViewer getTreeViewer() { + return fTreeViewer; + } + + /** + * Returns this time graph combo's time graph viewer. + * + * @return the time graph viewer + */ + public TimeGraphViewer getTimeGraphViewer() { + return fTimeGraphViewer; + } + + /** + * Callback for the show filter action + * + * @since 2.0 + */ + public void showFilterDialog() { + ITimeGraphEntry[] topInput = fTimeGraphViewer.getTimeGraphContentProvider().getElements(fTimeGraphViewer.getInput()); + if (topInput != null) { + List allElements = listAllInputs(Arrays.asList(topInput)); + fFilterDialog.setInput(fTimeGraphViewer.getInput()); + fFilterDialog.setTitle(Messages.TmfTimeFilterDialog_WINDOW_TITLE); + fFilterDialog.setMessage(Messages.TmfTimeFilterDialog_MESSAGE); + fFilterDialog.setExpandedElements(allElements.toArray()); + if (fFilter.getFiltered() != null) { + ArrayList nonFilteredElements = new ArrayList<>(allElements); + nonFilteredElements.removeAll(fFilter.getFiltered()); + fFilterDialog.setInitialElementSelections(nonFilteredElements); + } else { + fFilterDialog.setInitialElementSelections(allElements); + } + fFilterDialog.create(); + fFilterDialog.open(); + // Process selected elements + if (fFilterDialog.getResult() != null) { + fInhibitTreeSelection = true; + if (fFilterDialog.getResult().length != allElements.size()) { + ArrayList filteredElements = new ArrayList(allElements); + filteredElements.removeAll(Arrays.asList(fFilterDialog.getResult())); + fFilter.setFiltered(filteredElements); + } else { + fFilter.setFiltered(null); + } + fTreeViewer.refresh(); + fTreeViewer.expandAll(); + fTimeGraphViewer.refresh(); + fInhibitTreeSelection = false; + alignTreeItems(true); + // Reset selection + if (fFilterDialog.getResult().length > 0) { + setSelection(null); + } + } + } + } + + /** + * Get the show filter action. + * + * @return The Action object + * @since 2.0 + */ + public Action getShowFilterAction() { + if (showFilterAction == null) { + // showFilter + showFilterAction = new Action() { + @Override + public void run() { + showFilterDialog(); + } + }; + showFilterAction.setText(Messages.TmfTimeGraphCombo_FilterActionNameText); + showFilterAction.setToolTipText(Messages.TmfTimeGraphCombo_FilterActionToolTipText); + // TODO find a nice, distinctive icon + showFilterAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FILTERS)); + } + + return showFilterAction; + } + + // ------------------------------------------------------------------------ + // Control + // ------------------------------------------------------------------------ + + @Override + public void redraw() { + fTimeGraphViewer.getControl().redraw(); + super.redraw(); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Sets the tree content provider used by this time graph combo. + * + * @param contentProvider the tree content provider + */ + public void setTreeContentProvider(ITreeContentProvider contentProvider) { + fTreeViewer.setContentProvider(new TreeContentProviderWrapper(contentProvider)); + } + + /** + * Sets the tree label provider used by this time graph combo. + * + * @param labelProvider the tree label provider + */ + public void setTreeLabelProvider(ITableLabelProvider labelProvider) { + fTreeViewer.setLabelProvider(new TreeLabelProviderWrapper(labelProvider)); + } + + /** + * Sets the tree content provider used by the filter dialog + * + * @param contentProvider the tree content provider + * @since 2.0 + */ + public void setFilterContentProvider(ITreeContentProvider contentProvider) { + fFilterDialog.setContentProvider(contentProvider); + } + + /** + * Sets the tree label provider used by the filter dialog + * + * @param labelProvider the tree label provider + * @since 2.0 + */ + public void setFilterLabelProvider(ITableLabelProvider labelProvider) { + fFilterDialog.setLabelProvider(labelProvider); + } + + /** + * Sets the tree columns for this time graph combo. + * + * @param columnNames the tree column names + */ + public void setTreeColumns(String[] columnNames) { + final Tree tree = fTreeViewer.getTree(); + for (String columnName : columnNames) { + TreeColumn column = new TreeColumn(tree, SWT.LEFT); + column.setText(columnName); + column.pack(); + } + } + + /** + * Sets the tree columns for this time graph combo's filter dialog. + * + * @param columnNames the tree column names + * @since 2.0 + */ + public void setFilterColumns(String[] columnNames) { + fFilterDialog.setColumnNames(columnNames); + } + + /** + * Sets the time graph content provider used by this time graph combo. + * + * @param timeGraphContentProvider + * the time graph content provider + * + * @since 3.0 + */ + public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider) { + fTimeGraphViewer.setTimeGraphContentProvider(timeGraphContentProvider); + } + + /** + * Sets the time graph presentation provider used by this time graph combo. + * + * @param timeGraphProvider the time graph provider + */ + public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider) { + fTimeGraphViewer.setTimeGraphProvider(timeGraphProvider); + } + + /** + * Sets or clears the input for this time graph combo. + * + * @param input the input of this time graph combo, or null if none + * + * @since 3.0 + */ + public void setInput(Object input) { + fFilter.setFiltered(null); + fInhibitTreeSelection = true; + fTreeViewer.setInput(input); + for (SelectionListenerWrapper listenerWrapper : fSelectionListenerMap.values()) { + listenerWrapper.selection = null; + } + fInhibitTreeSelection = false; + fTreeViewer.getTree().getVerticalBar().setEnabled(false); + fTreeViewer.getTree().getVerticalBar().setVisible(false); + fTimeGraphViewer.setItemHeight(getItemHeight(fTreeViewer.getTree())); + fTimeGraphViewer.setInput(input); + // queue the alignment update because in Linux the item bounds are not + // set properly until the tree has been painted at least once + fVisibleExpandedItems = null; // invalidate the cache + getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + alignTreeItems(true); + }}); + } + + /** + * Gets the input for this time graph combo. + * + * @return The input of this time graph combo, or null if none + * + * @since 3.0 + */ + public Object getInput() { + return fTreeViewer.getInput(); + } + + /** + * Sets or clears the list of links to display on this combo + * + * @param links the links to display in this time graph combo + * @since 2.1 + */ + public void setLinks(List links) { + fTimeGraphViewer.setLinks(links); + } + + /** + * @param filter The filter object to be attached to the view + * @since 2.0 + */ + public void addFilter(ViewerFilter filter) { + ViewerFilter wrapper = new ViewerFilterWrapper(filter); + fTreeViewer.addFilter(wrapper); + fTimeGraphViewer.addFilter(wrapper); + fViewerFilterMap.put(filter, wrapper); + alignTreeItems(true); + } + + /** + * @param filter The filter object to be removed from the view + * @since 2.0 + */ + public void removeFilter(ViewerFilter filter) { + ViewerFilter wrapper = fViewerFilterMap.get(filter); + fTreeViewer.removeFilter(wrapper); + fTimeGraphViewer.removeFilter(wrapper); + fViewerFilterMap.remove(filter); + alignTreeItems(true); + } + + /** + * Refreshes this time graph completely with information freshly obtained from its model. + */ + public void refresh() { + fInhibitTreeSelection = true; + Tree tree = fTreeViewer.getTree(); + tree.setRedraw(false); + fTreeViewer.refresh(); + fTreeViewer.expandAll(); + tree.setRedraw(true); + fTimeGraphViewer.refresh(); + alignTreeItems(true); + fInhibitTreeSelection = false; + } + + /** + * Adds a listener for selection changes in this time graph combo. + * + * @param listener a selection listener + */ + public void addSelectionListener(ITimeGraphSelectionListener listener) { + SelectionListenerWrapper listenerWrapper = new SelectionListenerWrapper(listener); + fTreeViewer.addSelectionChangedListener(listenerWrapper); + fSelectionListenerMap.put(listener, listenerWrapper); + fTimeGraphViewer.addSelectionListener(listenerWrapper); + } + + /** + * Removes the given selection listener from this time graph combo. + * + * @param listener a selection changed listener + */ + public void removeSelectionListener(ITimeGraphSelectionListener listener) { + SelectionListenerWrapper listenerWrapper = fSelectionListenerMap.remove(listener); + fTreeViewer.removeSelectionChangedListener(listenerWrapper); + fTimeGraphViewer.removeSelectionListener(listenerWrapper); + } + + /** + * Sets the current selection for this time graph combo. + * + * @param selection the new selection + */ + public void setSelection(ITimeGraphEntry selection) { + fTimeGraphViewer.setSelection(selection); + fInhibitTreeSelection = true; // block the tree selection changed listener + if (selection != null) { + StructuredSelection structuredSelection = new StructuredSelection(selection); + fTreeViewer.setSelection(structuredSelection); + } else { + fTreeViewer.setSelection(new StructuredSelection()); + } + fInhibitTreeSelection = false; + alignTreeItems(false); + } + + /** + * Sets the auto-expand level to be used when the input of the viewer is set + * using {@link #setInput(Object)}. The value 0 means that there is no + * auto-expand; 1 means that top-level elements are expanded, but not their + * children; 2 means that top-level elements are expanded, and their + * children, but not grand-children; and so on. + *

    + * The value {@link #ALL_LEVELS} means that all subtrees should be expanded. + *

    + * @param level + * non-negative level, or ALL_LEVELS to expand all + * levels of the tree + * @since 3.1 + */ + public void setAutoExpandLevel(int level) { + fTimeGraphViewer.setAutoExpandLevel(level); + if (level <= 0) { + fTreeViewer.setAutoExpandLevel(level); + } else { + fTreeViewer.setAutoExpandLevel(level + 1); + } + } + + /** + * Returns the auto-expand level. + * + * @return non-negative level, or ALL_LEVELS if all levels of + * the tree are expanded automatically + * @see #setAutoExpandLevel + * @since 3.1 + */ + public int getAutoExpandLevel() { + return fTimeGraphViewer.getAutoExpandLevel(); + } + + /** + * Set the expanded state of an entry + * + * @param entry + * The entry to expand/collapse + * @param expanded + * True for expanded, false for collapsed + * + * @since 2.0 + */ + public void setExpandedState(ITimeGraphEntry entry, boolean expanded) { + fTimeGraphViewer.setExpandedState(entry, expanded); + fTreeViewer.setExpandedState(entry, expanded); + alignTreeItems(true); + } + + /** + * Collapses all nodes of the viewer's tree, starting with the root. + * + * @since 2.0 + */ + public void collapseAll() { + fTimeGraphViewer.collapseAll(); + fTreeViewer.collapseAll(); + alignTreeItems(true); + } + + /** + * Expands all nodes of the viewer's tree, starting with the root. + * + * @since 2.0 + */ + public void expandAll() { + fTimeGraphViewer.expandAll(); + fTreeViewer.expandAll(); + alignTreeItems(true); + } + + // ------------------------------------------------------------------------ + // Internal + // ------------------------------------------------------------------------ + + private List getVisibleExpandedItems(Tree tree, boolean refresh) { + if (fVisibleExpandedItems == null || refresh) { + ArrayList items = new ArrayList<>(); + for (TreeItem item : tree.getItems()) { + if (item.getData() == FILLER) { + break; + } + items.add(item); + if (item.getExpanded()) { + addVisibleExpandedItems(items, item); + } + } + fVisibleExpandedItems = items; + } + return fVisibleExpandedItems; + } + + private void addVisibleExpandedItems(List items, TreeItem treeItem) { + for (TreeItem item : treeItem.getItems()) { + items.add(item); + if (item.getExpanded()) { + addVisibleExpandedItems(items, item); + } + } + } + + /** + * Explores the list of top-level inputs and returns all the inputs + * + * @param inputs The top-level inputs + * @return All the inputs + */ + private List listAllInputs(List inputs) { + ArrayList items = new ArrayList<>(); + for (ITimeGraphEntry entry : inputs) { + items.add(entry); + if (entry.hasChildren()) { + items.addAll(listAllInputs(entry.getChildren())); + } + } + return items; + } + + private int getItemHeight(final Tree tree) { + /* + * Bug in Linux. The method getItemHeight doesn't always return the correct value. + */ + if (fLinuxItemHeight >= 0 && System.getProperty("os.name").contains("Linux")) { //$NON-NLS-1$ //$NON-NLS-2$ + if (fLinuxItemHeight != 0) { + return fLinuxItemHeight; + } + List treeItems = getVisibleExpandedItems(tree, true); + if (treeItems.size() > 1) { + final TreeItem treeItem0 = treeItems.get(0); + final TreeItem treeItem1 = treeItems.get(1); + PaintListener paintListener = new PaintListener() { + @Override + public void paintControl(PaintEvent e) { + tree.removePaintListener(this); + int y0 = treeItem0.getBounds().y; + int y1 = treeItem1.getBounds().y; + int itemHeight = y1 - y0; + if (itemHeight > 0) { + fLinuxItemHeight = itemHeight; + fTimeGraphViewer.setItemHeight(itemHeight); + } + } + }; + tree.addPaintListener(paintListener); + } + } else { + fLinuxItemHeight = -1; // Not Linux, don't perform os.name check anymore + } + return tree.getItemHeight(); + } + + private void alignTreeItems(boolean refreshExpandedItems) { + // align the tree top item with the time graph top item + Tree tree = fTreeViewer.getTree(); + List treeItems = getVisibleExpandedItems(tree, refreshExpandedItems); + int topIndex = fTimeGraphViewer.getTopIndex(); + if (topIndex >= treeItems.size()) { + return; + } + TreeItem item = treeItems.get(topIndex); + tree.setTopItem(item); + + // ensure the time graph item heights are equal to the tree item heights + int treeHeight = fTreeViewer.getTree().getBounds().height; + int index = topIndex; + Rectangle bounds = item.getBounds(); + while (index < treeItems.size() - 1) { + if (bounds.y > treeHeight) { + break; + } + /* + * Bug in Linux. The method getBounds doesn't always return the correct height. + * Use the difference of y position between items to calculate the height. + */ + TreeItem nextItem = treeItems.get(index + 1); + Rectangle nextBounds = nextItem.getBounds(); + Integer itemHeight = nextBounds.y - bounds.y; + if (itemHeight > 0 && !itemHeight.equals(item.getData(ITEM_HEIGHT))) { + ITimeGraphEntry entry = (ITimeGraphEntry) item.getData(); + if (fTimeGraphViewer.getTimeGraphControl().setItemHeight(entry, itemHeight)) { + item.setData(ITEM_HEIGHT, itemHeight); + } + } + index++; + item = nextItem; + bounds = nextBounds; + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphPresentationProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphPresentationProvider.java new file mode 100644 index 0000000000..011a9f5497 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphPresentationProvider.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alvaro Sanchez-Leon - Initial API and implementation + * Patrick Tasse - Refactoring + * Geneviève Bastien - Add drawing helper methods + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.ITmfTimeGraphDrawingHelper; + +/** + * Provider class for the time graph provider + * + * @version 1.0 + * @author Patrick Tasse + * + */ +public class TimeGraphPresentationProvider implements ITimeGraphPresentationProvider2 { + + private ITmfTimeGraphDrawingHelper fDrawingHelper; + private final String fStateTypeName; + + // The list of listeners for graph color changes + private final List fListeners = new ArrayList<>(); + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + private static final int DEFAULT_ITEM_HEIGHT = 19; + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Constructor + * @param stateTypeName The state type name + * @since 2.1 + */ + public TimeGraphPresentationProvider(String stateTypeName) { + fStateTypeName = stateTypeName; + } + + /** + * Constructor + * @since 2.1 + */ + public TimeGraphPresentationProvider() { + this(Messages.TmfTimeLegend_TRACE_STATES); + } + + @Override + public String getStateTypeName() { + return fStateTypeName; + } + + /** + * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider#getStateTypeName(org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry) + * @since 2.0 + */ + @Override + public String getStateTypeName(ITimeGraphEntry entry) { + return null; + } + + @Override + public StateItem[] getStateTable() { + return null; + } + + @Override + public int getStateTableIndex(ITimeEvent event) { + return 0; + } + + /** + * @since 2.1 + */ + @Override + public ITmfTimeGraphDrawingHelper getDrawingHelper() { + return fDrawingHelper; + } + + /** + * @since 2.1 + */ + @Override + public void setDrawingHelper(ITmfTimeGraphDrawingHelper helper) { + fDrawingHelper = helper; + } + + @Override + public void postDrawControl(Rectangle bounds, GC gc) { + // Override to add own drawing code + } + + @Override + public void postDrawEntry(ITimeGraphEntry entry, Rectangle bounds, GC gc) { + // Override to add own drawing code + } + + @Override + public void postDrawEvent(ITimeEvent event, Rectangle bounds, GC gc) { + // Override to add own drawing code + } + + @Override + public int getItemHeight(ITimeGraphEntry entry) { + return DEFAULT_ITEM_HEIGHT; + } + + @Override + public Image getItemImage(ITimeGraphEntry entry) { + return null; + } + + @Override + public String getEventName(ITimeEvent event) { + return null; + } + + @Override + public Map getEventHoverToolTipInfo(ITimeEvent event) { + return null; + } + + /** + * @since 2.0 + */ + @Override + public Map getEventHoverToolTipInfo(ITimeEvent event, long hoverTime) { + return getEventHoverToolTipInfo(event); + } + + /** + * @since 3.0 + */ + @Override + public boolean displayTimesInTooltip() { + return true; + } + + /** + * @since 3.0 + */ + @Override + public void addColorListener(ITimeGraphColorListener listener) { + if (!fListeners.contains(listener)) { + fListeners.add(listener); + } + } + + /** + * @since 3.0 + */ + @Override + public void removeColorListener(ITimeGraphColorListener listener) { + fListeners.remove(listener); + } + + /** + * Notifies listeners of the state table change + * @since 3.0 + */ + protected void fireColorSettingsChanged() { + for (ITimeGraphColorListener listener : fListeners) { + listener.colorSettingsChanged(getStateTable()); + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphRangeUpdateEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphRangeUpdateEvent.java new file mode 100644 index 0000000000..9e776e42ee --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphRangeUpdateEvent.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph; + +import java.util.EventObject; + +/** + * Notifier for the time graph that the time range has been updated. + * + * @version 1.0 + * @author Patrick Tasse + */ +public class TimeGraphRangeUpdateEvent extends EventObject { + + /** + * Default serial version UID for this class. + * @since 1.0 + */ + private static final long serialVersionUID = 1L; + + /** + * The start time. + */ + private final long fStartTime; + + /** + * The end time. + */ + private final long fEndTime; + + /** + * Standard constructor + * + * @param source + * The source of this event + * @param startTime + * The start time + * @param endTime + * The end time + */ + public TimeGraphRangeUpdateEvent(Object source, long startTime, long endTime) { + super(source); + fStartTime = startTime; + fEndTime = endTime; + } + + /** + * @return the start time + */ + public long getStartTime() { + return fStartTime; + } + + /** + * @return the end time + */ + public long getEndTime() { + return fEndTime; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphSelectionEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphSelectionEvent.java new file mode 100644 index 0000000000..001cbe8ed3 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphSelectionEvent.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph; + +import java.util.EventObject; + +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; + +/** + * Notifier for the time graph that an object in the views has been selected. + * + * @version 1.0 + * @author Patrick Tasse + */ +public class TimeGraphSelectionEvent extends EventObject { + + /** + * Default serial version UID for this class. + * @since 1.0 + */ + private static final long serialVersionUID = 1L; + + /** + * The selected entry. + */ + private final ITimeGraphEntry fSelection; + + /** + * Standard constructor + * + * @param source + * The source of this event + * @param selection + * The entry that was selected + */ + public TimeGraphSelectionEvent(Object source, ITimeGraphEntry selection) { + super(source); + fSelection = selection; + } + + /** + * @return the selected entry or null if the selection is empty. + */ + public ITimeGraphEntry getSelection() { + return fSelection; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphTimeEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphTimeEvent.java new file mode 100644 index 0000000000..a0c217eab2 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphTimeEvent.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph; + +import java.util.EventObject; + +/** + * Time selection event + * + * @version 1.0 + * @author Patrick Tasse + */ +public class TimeGraphTimeEvent extends EventObject { + + /** + * Default serial version UID for this class. + * @since 1.0 + */ + private static final long serialVersionUID = 1L; + + /** + * The selection begin time. + */ + private final long fBeginTime; + + /** + * The selection end time. + */ + private final long fEndTime; + + /** + * Standard constructor + * + * @param source + * The source of this event + * @param beginTime + * The selection begin time + * @param endTime + * The selection end time + * @since 2.1 + */ + public TimeGraphTimeEvent(Object source, long beginTime, long endTime) { + super(source); + fBeginTime = beginTime; + fEndTime = endTime; + } + + /** + * @return the selection begin time + * @since 2.1 + */ + public long getBeginTime() { + return fBeginTime; + } + + /** + * @return the selection end time + * @since 2.1 + */ + public long getEndTime() { + return fEndTime; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphTreeExpansionEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphTreeExpansionEvent.java new file mode 100644 index 0000000000..ef088df349 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphTreeExpansionEvent.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph; + +import java.util.EventObject; + +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; + +/** + * Notifier for the time graph view that a tree has been expanded. + * + * @version 1.0 + * @author Patrick Tasse + */ +public class TimeGraphTreeExpansionEvent extends EventObject { + + /** + * Default serial version UID for this class. + * @since 1.0 + */ + private static final long serialVersionUID = 1L; + + /** + * The entry that was expanded or collapsed. + */ + private final ITimeGraphEntry fEntry; + + /** + * Creates a new event for the given source and entry. + * + * @param source the tree viewer + * @param entry the entry + */ + public TimeGraphTreeExpansionEvent(Object source, ITimeGraphEntry entry) { + super(source); + fEntry = entry; + } + + /** + * Returns the entry that got expanded or collapsed. + * + * @return the entry + */ + public ITimeGraphEntry getEntry() { + return fEntry; + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphViewer.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphViewer.java new file mode 100644 index 0000000000..602b1b12f0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphViewer.java @@ -0,0 +1,1760 @@ +/***************************************************************************** + * Copyright (c) 2007, 2014 Intel Corporation, Ericsson, others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + * Ruslan A. Scherbakov, Intel - Initial API and implementation + * Alexander N. Alexeev, Intel - Add monitors statistics support + * Alvaro Sanchez-Leon - Adapted for TMF + * Patrick Tasse - Refactoring + * Geneviève Bastien - Add event links between entries + *****************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.MenuDetectListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseWheelListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.ScrollBar; +import org.eclipse.swt.widgets.Slider; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.TimeGraphLegend; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.ITimeDataProvider; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeDataProviderCyclesConverter; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphColorScheme; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphScale; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphTooltipHandler; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; + +/** + * Generic time graph viewer implementation + * + * @version 1.0 + * @author Patrick Tasse, and others + */ +public class TimeGraphViewer implements ITimeDataProvider, SelectionListener { + + /** Constant indicating that all levels of the time graph should be expanded + * @since 3.1 */ + public static final int ALL_LEVELS = AbstractTreeViewer.ALL_LEVELS; + + private static final int DEFAULT_NAME_WIDTH = 200; + private static final int MIN_NAME_WIDTH = 6; + private static final int MAX_NAME_WIDTH = 1000; + private static final int DEFAULT_HEIGHT = 22; + private static final long RECENTERING_MARGIN_FACTOR = 50; + private static final String HIDE_ARROWS_KEY = "hide.arrows"; //$NON-NLS-1$ + private static final long DEFAULT_FREQUENCY = 1000000000L; + + private long fMinTimeInterval; + private ITimeGraphEntry fSelectedEntry; + private long fBeginTime; + private long fEndTime; + private long fTime0; + private long fTime1; + private long fSelectionBegin = 0; + private long fSelectionEnd = 0; + private long fTime0Bound; + private long fTime1Bound; + private long fTime0ExtSynch = 0; + private long fTime1ExtSynch = 0; + private boolean fTimeRangeFixed; + private int fNameWidthPref = DEFAULT_NAME_WIDTH; + private int fMinNameWidth = MIN_NAME_WIDTH; + private int fNameWidth; + private Composite fDataViewer; + + private TimeGraphControl fTimeGraphCtrl; + private TimeGraphScale fTimeScaleCtrl; + private Slider fVerticalScrollBar; + private TimeGraphColorScheme fColorScheme; + private Object fInputElement; + private ITimeGraphContentProvider fTimeGraphContentProvider; + private ITimeGraphPresentationProvider fTimeGraphProvider; + private ITimeDataProvider fTimeDataProvider = this; + private TimeGraphTooltipHandler fToolTipHandler; + + private List fSelectionListeners = new ArrayList<>(); + private List fTimeListeners = new ArrayList<>(); + private List fRangeListeners = new ArrayList<>(); + + // Time format, using Epoch reference, Relative time format(default), + // Number, or Cycles + private TimeFormat fTimeFormat = TimeFormat.RELATIVE; + // Clock frequency to use for Cycles time format + private long fClockFrequency = DEFAULT_FREQUENCY; + private int fBorderWidth = 0; + private int fTimeScaleHeight = DEFAULT_HEIGHT; + + private Action fResetScaleAction; + private Action fShowLegendAction; + private Action fNextEventAction; + private Action fPrevEventAction; + private Action fNextItemAction; + private Action fPreviousItemAction; + private Action fZoomInAction; + private Action fZoomOutAction; + private Action fHideArrowsAction; + private Action fFollowArrowFwdAction; + private Action fFollowArrowBwdAction; + + /** + * Standard constructor. + *

    + * The default timegraph content provider accepts an ITimeGraphEntry[] as input element. + * + * @param parent + * The parent UI composite object + * @param style + * The style to use + */ + public TimeGraphViewer(Composite parent, int style) { + createDataViewer(parent, style); + fTimeGraphContentProvider = new ITimeGraphContentProvider() { + @Override + public ITimeGraphEntry[] getElements(Object inputElement) { + if (inputElement instanceof ITimeGraphEntry[]) { + return (ITimeGraphEntry[]) inputElement; + } + return new ITimeGraphEntry[0]; + } + }; + } + + /** + * Sets the timegraph content provider used by this timegraph viewer. + * + * @param timeGraphContentProvider + * the timegraph content provider + * + * @since 3.0 + */ + public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider) { + fTimeGraphContentProvider = timeGraphContentProvider; + } + + /** + * Gets the timegraph content provider used by this timegraph viewer. + * + * @return the timegraph content provider + * + * @since 3.0 + */ + public ITimeGraphContentProvider getTimeGraphContentProvider() { + return fTimeGraphContentProvider; + } + + /** + * Sets the timegraph presentation provider used by this timegraph viewer. + * + * @param timeGraphProvider + * the timegraph provider + */ + public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider) { + fTimeGraphProvider = timeGraphProvider; + fTimeGraphCtrl.setTimeGraphProvider(timeGraphProvider); + fToolTipHandler = new TimeGraphTooltipHandler(fTimeGraphProvider, fTimeDataProvider); + fToolTipHandler.activateHoverHelp(fTimeGraphCtrl); + } + + /** + * Sets or clears the input for this time graph viewer. + * + * @param inputElement + * The input of this time graph viewer, or null if + * none + * + * @since 3.0 + */ + public void setInput(Object inputElement) { + fInputElement = inputElement; + ITimeGraphEntry[] input = fTimeGraphContentProvider.getElements(inputElement); + + if (fTimeGraphCtrl != null) { + setTimeRange(input); + fVerticalScrollBar.setEnabled(true); + setTopIndex(0); + fSelectionBegin = 0; + fSelectionEnd = 0; + fSelectedEntry = null; + refreshAllData(input); + } + } + + /** + * Gets the input for this time graph viewer. + * + * @return The input of this time graph viewer, or null if none + * + * @since 3.0 + */ + public Object getInput() { + return fInputElement; + } + + /** + * Sets (or clears if null) the list of links to display on this combo + * + * @param links + * the links to display in this time graph combo + * @since 2.1 + */ + public void setLinks(List links) { + if (fTimeGraphCtrl != null) { + fTimeGraphCtrl.refreshArrows(links); + } + } + + /** + * Refresh the view + */ + public void refresh() { + ITimeGraphEntry[] input = fTimeGraphContentProvider.getElements(fInputElement); + setTimeRange(input); + fVerticalScrollBar.setEnabled(true); + refreshAllData(input); + } + + /** + * Callback for when the control is moved + * + * @param e + * The caller event + */ + public void controlMoved(ControlEvent e) { + } + + /** + * Callback for when the control is resized + * + * @param e + * The caller event + */ + public void controlResized(ControlEvent e) { + resizeControls(); + } + + /** + * Handler for when the model is updated. Called from the display order in + * the API + * + * @param traces + * The traces in the model + * @param start + * The start time + * @param end + * The end time + * @param updateTimeBounds + * Should we updated the time bounds too + */ + public void modelUpdate(ITimeGraphEntry[] traces, long start, + long end, boolean updateTimeBounds) { + if (null != fTimeGraphCtrl) { + updateInternalData(traces, start, end); + if (updateTimeBounds) { + fTimeRangeFixed = true; + // set window to match limits + setStartFinishTime(fTime0Bound, fTime1Bound); + } else { + fTimeGraphCtrl.redraw(); + fTimeScaleCtrl.redraw(); + } + } + } + + /** + * @return The string representing the view type + */ + protected String getViewTypeStr() { + return "viewoption.threads"; //$NON-NLS-1$ + } + + int getMarginWidth() { + return 0; + } + + int getMarginHeight() { + return 0; + } + + void loadOptions() { + fMinTimeInterval = 1; + fSelectionBegin = -1; + fSelectionEnd = -1; + fNameWidth = Utils.loadIntOption(getPreferenceString("namewidth"), //$NON-NLS-1$ + fNameWidthPref, fMinNameWidth, MAX_NAME_WIDTH); + } + + void saveOptions() { + Utils.saveIntOption(getPreferenceString("namewidth"), fNameWidth); //$NON-NLS-1$ + } + + /** + * Create a data viewer. + * + * @param parent + * Parent composite + * @param style + * Style to use + * @return The new data viewer + */ + protected Control createDataViewer(Composite parent, int style) { + loadOptions(); + fColorScheme = new TimeGraphColorScheme(); + fDataViewer = new Composite(parent, style) { + @Override + public void redraw() { + fTimeScaleCtrl.redraw(); + fTimeGraphCtrl.redraw(); + super.redraw(); + } + }; + GridLayout gl = new GridLayout(2, false); + gl.marginHeight = fBorderWidth; + gl.marginWidth = 0; + gl.verticalSpacing = 0; + gl.horizontalSpacing = 0; + fDataViewer.setLayout(gl); + + fTimeScaleCtrl = new TimeGraphScale(fDataViewer, fColorScheme); + fTimeScaleCtrl.setTimeProvider(fTimeDataProvider); + fTimeScaleCtrl.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false)); + fTimeScaleCtrl.setHeight(fTimeScaleHeight); + + fVerticalScrollBar = new Slider(fDataViewer, SWT.VERTICAL | SWT.NO_FOCUS); + fVerticalScrollBar.setLayoutData(new GridData(SWT.DEFAULT, SWT.FILL, false, true, 1, 2)); + fVerticalScrollBar.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + setTopIndex(fVerticalScrollBar.getSelection()); + } + }); + fVerticalScrollBar.setEnabled(false); + + fTimeGraphCtrl = createTimeGraphControl(fDataViewer, fColorScheme); + + fTimeGraphCtrl.setTimeProvider(this); + fTimeGraphCtrl.setTimeGraphScale(fTimeScaleCtrl); + fTimeGraphCtrl.addSelectionListener(this); + fTimeGraphCtrl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 2)); + fTimeGraphCtrl.addMouseWheelListener(new MouseWheelListener() { + @Override + public void mouseScrolled(MouseEvent e) { + adjustVerticalScrollBar(); + } + }); + fTimeGraphCtrl.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.character == '+') { + zoomIn(); + } else if (e.character == '-') { + zoomOut(); + } + adjustVerticalScrollBar(); + } + }); + + Composite filler = new Composite(fDataViewer, SWT.NONE); + GridData gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false); + gd.heightHint = fTimeGraphCtrl.getHorizontalBar().getSize().y; + filler.setLayoutData(gd); + filler.setLayout(new FillLayout()); + + fTimeGraphCtrl.addControlListener(new ControlAdapter() { + @Override + public void controlResized(ControlEvent event) { + resizeControls(); + } + }); + resizeControls(); + fDataViewer.update(); + adjustVerticalScrollBar(); + return fDataViewer; + } + + /** + * Dispose the view. + */ + public void dispose() { + saveOptions(); + fTimeGraphCtrl.dispose(); + fDataViewer.dispose(); + fColorScheme.dispose(); + } + + /** + * Create a new time graph control. + * + * @param parent + * The parent composite + * @param colors + * The color scheme + * @return The new TimeGraphControl + * @since 2.0 + */ + protected TimeGraphControl createTimeGraphControl(Composite parent, + TimeGraphColorScheme colors) { + return new TimeGraphControl(parent, colors); + } + + /** + * Resize the controls + */ + public void resizeControls() { + Rectangle r = fDataViewer.getClientArea(); + if (r.isEmpty()) { + return; + } + + int width = r.width; + if (fNameWidth > width - fMinNameWidth) { + fNameWidth = width - fMinNameWidth; + } + if (fNameWidth < fMinNameWidth) { + fNameWidth = fMinNameWidth; + } + adjustVerticalScrollBar(); + } + + /** + * Try to set most convenient time range for display. + * + * @param traces + * The traces in the model + */ + public void setTimeRange(ITimeGraphEntry traces[]) { + fEndTime = 0; + fBeginTime = -1; + for (int i = 0; i < traces.length; i++) { + ITimeGraphEntry entry = traces[i]; + if (entry.getEndTime() >= entry.getStartTime() && entry.getEndTime() > 0) { + if (fBeginTime < 0 || entry.getStartTime() < fBeginTime) { + fBeginTime = entry.getStartTime(); + } + if (entry.getEndTime() > fEndTime) { + fEndTime = entry.getEndTime(); + } + } + } + + if (fBeginTime < 0) { + fBeginTime = 0; + } + } + + /** + * Recalculate the time bounds + */ + public void setTimeBounds() { + fTime0Bound = fBeginTime; + if (fTime0Bound < 0) { + fTime0Bound = 0; + } + fTime1Bound = fEndTime; + if (!fTimeRangeFixed) { + fTime0 = fTime0Bound; + fTime1 = fTime1Bound; + } + fTime0 = Math.max(fTime0Bound, Math.min(fTime0, fTime1Bound)); + fTime1 = Math.max(fTime0Bound, Math.min(fTime1, fTime1Bound)); + if (fTime1 - fTime0 < fMinTimeInterval) { + fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval); + } + } + + /** + * @param traces + * @param start + * @param end + */ + void updateInternalData(ITimeGraphEntry[] traces, long start, long end) { + ITimeGraphEntry[] realTraces = traces; + + if (null == realTraces) { + realTraces = new ITimeGraphEntry[0]; + } + if ((start == 0 && end == 0) || start < 0 || end < 0) { + // Start and end time are unspecified and need to be determined from + // individual processes + setTimeRange(realTraces); + } else { + fBeginTime = start; + fEndTime = end; + } + + refreshAllData(realTraces); + } + + /** + * @param traces + */ + private void refreshAllData(ITimeGraphEntry[] traces) { + setTimeBounds(); + if (fSelectionBegin < fBeginTime) { + fSelectionBegin = fBeginTime; + } else if (fSelectionBegin > fEndTime) { + fSelectionBegin = fEndTime; + } + if (fSelectionEnd < fBeginTime) { + fSelectionEnd = fBeginTime; + } else if (fSelectionEnd > fEndTime) { + fSelectionEnd = fEndTime; + } + fTimeGraphCtrl.refreshData(traces); + fTimeScaleCtrl.redraw(); + adjustVerticalScrollBar(); + } + + /** + * Callback for when this view is focused + */ + public void setFocus() { + if (null != fTimeGraphCtrl) { + fTimeGraphCtrl.setFocus(); + } + } + + /** + * Get the current focus status of this view. + * + * @return If the view is currently focused, or not + */ + public boolean isInFocus() { + return fTimeGraphCtrl.isInFocus(); + } + + /** + * Get the view's current selection + * + * @return The entry that is selected + */ + public ITimeGraphEntry getSelection() { + return fTimeGraphCtrl.getSelectedTrace(); + } + + /** + * Get the index of the current selection + * + * @return The index + */ + public int getSelectionIndex() { + return fTimeGraphCtrl.getSelectedIndex(); + } + + @Override + public long getTime0() { + return fTime0; + } + + @Override + public long getTime1() { + return fTime1; + } + + @Override + public long getMinTimeInterval() { + return fMinTimeInterval; + } + + @Override + public int getNameSpace() { + return fNameWidth; + } + + @Override + public void setNameSpace(int width) { + fNameWidth = width; + int w = fTimeGraphCtrl.getClientArea().width; + if (fNameWidth > w - MIN_NAME_WIDTH) { + fNameWidth = w - MIN_NAME_WIDTH; + } + if (fNameWidth < MIN_NAME_WIDTH) { + fNameWidth = MIN_NAME_WIDTH; + } + fTimeGraphCtrl.adjustScrolls(); + fTimeGraphCtrl.redraw(); + fTimeScaleCtrl.redraw(); + } + + @Override + public int getTimeSpace() { + int w = fTimeGraphCtrl.getClientArea().width; + return w - fNameWidth; + } + + @Override + public long getBeginTime() { + return fBeginTime; + } + + @Override + public long getEndTime() { + return fEndTime; + } + + @Override + public long getMaxTime() { + return fTime1Bound; + } + + @Override + public long getMinTime() { + return fTime0Bound; + } + + /** + * @since 2.1 + */ + @Override + public long getSelectionBegin() { + return fSelectionBegin; + } + + /** + * @since 2.1 + */ + @Override + public long getSelectionEnd() { + return fSelectionEnd; + } + + @Override + public void setStartFinishTimeNotify(long time0, long time1) { + setStartFinishTime(time0, time1); + notifyRangeListeners(fTime0, fTime1); + } + + @Override + public void notifyStartFinishTime() { + notifyRangeListeners(fTime0, fTime1); + } + + @Override + public void setStartFinishTime(long time0, long time1) { + fTime0 = time0; + if (fTime0 < fTime0Bound) { + fTime0 = fTime0Bound; + } + if (fTime0 > fTime1Bound) { + fTime0 = fTime1Bound; + } + fTime1 = time1; + if (fTime1 < fTime0Bound) { + fTime1 = fTime0Bound; + } + if (fTime1 > fTime1Bound) { + fTime1 = fTime1Bound; + } + if (fTime1 - fTime0 < fMinTimeInterval) { + fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval); + } + fTimeRangeFixed = true; + fTimeGraphCtrl.adjustScrolls(); + fTimeGraphCtrl.redraw(); + fTimeScaleCtrl.redraw(); + } + + /** + * Set the time bounds to the provided values + * + * @param beginTime + * The start time of the window + * @param endTime + * The end time + */ + public void setTimeBounds(long beginTime, long endTime) { + if (endTime >= beginTime) { + fBeginTime = beginTime; + fEndTime = endTime; + fTime0Bound = beginTime; + fTime1Bound = endTime; + } else { + fBeginTime = 0; + fEndTime = 0; + fTime0Bound = 0; + fTime1Bound = 0; + } + fTimeGraphCtrl.adjustScrolls(); + } + + @Override + public void resetStartFinishTime() { + setStartFinishTime(fTime0Bound, fTime1Bound); + fTimeRangeFixed = false; + } + + @Override + public void setSelectedTimeNotify(long time, boolean ensureVisible) { + setSelectedTimeInt(time, ensureVisible, true); + } + + @Override + public void setSelectedTime(long time, boolean ensureVisible) { + setSelectedTimeInt(time, ensureVisible, false); + } + + /** + * @since 2.1 + */ + @Override + public void setSelectionRangeNotify(long beginTime, long endTime) { + boolean changed = (beginTime != fSelectionBegin || endTime != fSelectionEnd); + fSelectionBegin = Math.max(fTime0Bound, Math.min(fTime1Bound, beginTime)); + fSelectionEnd = Math.max(fTime0Bound, Math.min(fTime1Bound, endTime)); + fTimeGraphCtrl.redraw(); + fTimeScaleCtrl.redraw(); + if (changed) { + notifyTimeListeners(fSelectionBegin, fSelectionEnd); + } + } + + /** + * @since 2.1 + */ + @Override + public void setSelectionRange(long beginTime, long endTime) { + fSelectionBegin = Math.max(fTime0Bound, Math.min(fTime1Bound, beginTime)); + fSelectionEnd = Math.max(fTime0Bound, Math.min(fTime1Bound, endTime)); + fTimeGraphCtrl.redraw(); + fTimeScaleCtrl.redraw(); + } + + private void setSelectedTimeInt(long time, boolean ensureVisible, boolean doNotify) { + long time0 = fTime0; + long time1 = fTime1; + if (ensureVisible) { + long timeSpace = (fTime1 - fTime0) / RECENTERING_MARGIN_FACTOR; + long timeMid = (fTime1 - fTime0) / 2; + if (time < fTime0 + timeSpace) { + long dt = fTime0 - time + timeMid; + fTime0 -= dt; + fTime1 -= dt; + } else if (time > fTime1 - timeSpace) { + long dt = time - fTime1 + timeMid; + fTime0 += dt; + fTime1 += dt; + } + if (fTime0 < fTime0Bound) { + fTime1 = Math.min(fTime1Bound, fTime1 + (fTime0Bound - fTime0)); + fTime0 = fTime0Bound; + } else if (fTime1 > fTime1Bound) { + fTime0 = Math.max(fTime0Bound, fTime0 - (fTime1 - fTime1Bound)); + fTime1 = fTime1Bound; + } + } + if (fTime1 - fTime0 < fMinTimeInterval) { + fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval); + } + fTimeGraphCtrl.adjustScrolls(); + fTimeGraphCtrl.redraw(); + fTimeScaleCtrl.redraw(); + + boolean notifySelectedTime = (time != fSelectionBegin || time != fSelectionEnd); + fSelectionBegin = time; + fSelectionEnd = time; + + if (doNotify && ((time0 != fTime0) || (time1 != fTime1))) { + notifyRangeListeners(fTime0, fTime1); + } + + if (doNotify && notifySelectedTime) { + notifyTimeListeners(fSelectionBegin, fSelectionEnd); + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + if (fSelectedEntry != getSelection()) { + fSelectedEntry = getSelection(); + notifySelectionListeners(fSelectedEntry); + } + } + + @Override + public void widgetSelected(SelectionEvent e) { + if (fSelectedEntry != getSelection()) { + fSelectedEntry = getSelection(); + notifySelectionListeners(fSelectedEntry); + } + } + + /** + * Callback for when the next event is selected + */ + public void selectNextEvent() { + fTimeGraphCtrl.selectNextEvent(); + adjustVerticalScrollBar(); + } + + /** + * Callback for when the previous event is selected + */ + public void selectPrevEvent() { + fTimeGraphCtrl.selectPrevEvent(); + adjustVerticalScrollBar(); + } + + /** + * Callback for when the next item is selected + */ + public void selectNextItem() { + fTimeGraphCtrl.selectNextTrace(); + adjustVerticalScrollBar(); + } + + /** + * Callback for when the previous item is selected + */ + public void selectPrevItem() { + fTimeGraphCtrl.selectPrevTrace(); + adjustVerticalScrollBar(); + } + + /** + * Callback for the show legend action + */ + public void showLegend() { + if (fDataViewer == null || fDataViewer.isDisposed()) { + return; + } + + TimeGraphLegend.open(fDataViewer.getShell(), fTimeGraphProvider); + } + + /** + * Callback for the Zoom In action + */ + public void zoomIn() { + fTimeGraphCtrl.zoomIn(); + } + + /** + * Callback for the Zoom Out action + */ + public void zoomOut() { + fTimeGraphCtrl.zoomOut(); + } + + private String getPreferenceString(String string) { + return getViewTypeStr() + "." + string; //$NON-NLS-1$ + } + + /** + * Add a selection listener + * + * @param listener + * The listener to add + */ + public void addSelectionListener(ITimeGraphSelectionListener listener) { + fSelectionListeners.add(listener); + } + + /** + * Remove a selection listener + * + * @param listener + * The listener to remove + */ + public void removeSelectionListener(ITimeGraphSelectionListener listener) { + fSelectionListeners.remove(listener); + } + + private void notifySelectionListeners(ITimeGraphEntry selection) { + TimeGraphSelectionEvent event = new TimeGraphSelectionEvent(this, selection); + + for (ITimeGraphSelectionListener listener : fSelectionListeners) { + listener.selectionChanged(event); + } + } + + /** + * Add a time listener + * + * @param listener + * The listener to add + */ + public void addTimeListener(ITimeGraphTimeListener listener) { + fTimeListeners.add(listener); + } + + /** + * Remove a time listener + * + * @param listener + * The listener to remove + */ + public void removeTimeListener(ITimeGraphTimeListener listener) { + fTimeListeners.remove(listener); + } + + private void notifyTimeListeners(long startTime, long endTime) { + TimeGraphTimeEvent event = new TimeGraphTimeEvent(this, startTime, endTime); + + for (ITimeGraphTimeListener listener : fTimeListeners) { + listener.timeSelected(event); + } + } + + /** + * Add a range listener + * + * @param listener + * The listener to add + */ + public void addRangeListener(ITimeGraphRangeListener listener) { + fRangeListeners.add(listener); + } + + /** + * Remove a range listener + * + * @param listener + * The listener to remove + */ + public void removeRangeListener(ITimeGraphRangeListener listener) { + fRangeListeners.remove(listener); + } + + private void notifyRangeListeners(long startTime, long endTime) { + // Check if the time has actually changed from last notification + if (startTime != fTime0ExtSynch || endTime != fTime1ExtSynch) { + // Notify Time Scale Selection Listeners + TimeGraphRangeUpdateEvent event = new TimeGraphRangeUpdateEvent(this, startTime, endTime); + + for (ITimeGraphRangeListener listener : fRangeListeners) { + listener.timeRangeUpdated(event); + } + + // update external synch timers + updateExtSynchTimers(); + } + } + + /** + * Callback to set a selected event in the view + * + * @param event + * The event that was selected + * @param source + * The source of this selection event + */ + public void setSelectedEvent(ITimeEvent event, Object source) { + if (event == null || source == this) { + return; + } + fSelectedEntry = event.getEntry(); + fTimeGraphCtrl.selectItem(fSelectedEntry, false); + + setSelectedTimeInt(event.getTime(), true, true); + adjustVerticalScrollBar(); + } + + /** + * Set the seeked time of a trace + * + * @param trace + * The trace that was seeked + * @param time + * The target time + * @param source + * The source of this seek event + */ + public void setSelectedTraceTime(ITimeGraphEntry trace, long time, Object source) { + if (trace == null || source == this) { + return; + } + fSelectedEntry = trace; + fTimeGraphCtrl.selectItem(trace, false); + + setSelectedTimeInt(time, true, true); + } + + /** + * Callback for a trace selection + * + * @param trace + * The trace that was selected + */ + public void setSelection(ITimeGraphEntry trace) { + fSelectedEntry = trace; + fTimeGraphCtrl.selectItem(trace, false); + adjustVerticalScrollBar(); + } + + /** + * Callback for a time window selection + * + * @param time0 + * Start time of the range + * @param time1 + * End time of the range + * @param source + * Source of the event + */ + public void setSelectVisTimeWindow(long time0, long time1, Object source) { + if (source == this) { + return; + } + + setStartFinishTime(time0, time1); + + // update notification time values since we are now in synch with the + // external application + updateExtSynchTimers(); + } + + /** + * update the cache timers used to identify the need to send a time window + * update to external registered listeners + */ + private void updateExtSynchTimers() { + // last time notification cache + fTime0ExtSynch = fTime0; + fTime1ExtSynch = fTime1; + } + + /** + * @since 2.0 + */ + @Override + public TimeFormat getTimeFormat() { + return fTimeFormat; + } + + /** + * @param tf + * the {@link TimeFormat} used to display timestamps + * @since 2.0 + */ + public void setTimeFormat(TimeFormat tf) { + this.fTimeFormat = tf; + if (tf == TimeFormat.CYCLES) { + fTimeDataProvider = new TimeDataProviderCyclesConverter(this, fClockFrequency); + } else { + fTimeDataProvider = this; + } + fTimeScaleCtrl.setTimeProvider(fTimeDataProvider); + if (fToolTipHandler != null) { + fToolTipHandler.setTimeProvider(fTimeDataProvider); + } + } + + /** + * Sets the clock frequency. Used when the time format is set to CYCLES. + * + * @param clockFrequency + * the clock frequency in Hz + * @since 3.2 + */ + public void setClockFrequency(long clockFrequency) { + fClockFrequency = clockFrequency; + if (fTimeFormat == TimeFormat.CYCLES) { + fTimeDataProvider = new TimeDataProviderCyclesConverter(this, fClockFrequency); + fTimeScaleCtrl.setTimeProvider(fTimeDataProvider); + if (fToolTipHandler != null) { + fToolTipHandler.setTimeProvider(fTimeDataProvider); + } + } + } + + /** + * Retrieve the border width + * + * @return The width + */ + public int getBorderWidth() { + return fBorderWidth; + } + + /** + * Set the border width + * + * @param borderWidth + * The width + */ + public void setBorderWidth(int borderWidth) { + if (borderWidth > -1) { + this.fBorderWidth = borderWidth; + GridLayout gl = (GridLayout) fDataViewer.getLayout(); + gl.marginHeight = borderWidth; + } + } + + /** + * Retrieve the height of the header + * + * @return The height + */ + public int getHeaderHeight() { + return fTimeScaleHeight; + } + + /** + * Set the height of the header + * + * @param headerHeight + * The height to set + */ + public void setHeaderHeight(int headerHeight) { + if (headerHeight > -1) { + this.fTimeScaleHeight = headerHeight; + fTimeScaleCtrl.setHeight(headerHeight); + } + } + + /** + * Retrieve the height of an item row + * + * @return The height + */ + public int getItemHeight() { + if (fTimeGraphCtrl != null) { + return fTimeGraphCtrl.getItemHeight(); + } + return 0; + } + + /** + * Set the height of an item row + * + * @param rowHeight + * The height to set + */ + public void setItemHeight(int rowHeight) { + if (fTimeGraphCtrl != null) { + fTimeGraphCtrl.setItemHeight(rowHeight); + } + } + + /** + * Set the minimum item width + * + * @param width + * The min width + */ + public void setMinimumItemWidth(int width) { + if (fTimeGraphCtrl != null) { + fTimeGraphCtrl.setMinimumItemWidth(width); + } + } + + /** + * Set the width for the name column + * + * @param width + * The width + */ + public void setNameWidthPref(int width) { + fNameWidthPref = width; + if (width == 0) { + fMinNameWidth = 0; + fNameWidth = 0; + } + } + + /** + * Retrieve the configure width for the name column + * + * @param width + * Unused? + * @return The width + */ + public int getNameWidthPref(int width) { + return fNameWidthPref; + } + + /** + * Returns the primary control associated with this viewer. + * + * @return the SWT control which displays this viewer's content + */ + public Control getControl() { + return fDataViewer; + } + + /** + * Returns the time graph control associated with this viewer. + * + * @return the time graph control + * @since 2.0 + */ + public TimeGraphControl getTimeGraphControl() { + return fTimeGraphCtrl; + } + + /** + * Returns the time graph scale associated with this viewer. + * + * @return the time graph scale + * @since 2.0 + */ + public TimeGraphScale getTimeGraphScale() { + return fTimeScaleCtrl; + } + + /** + * Return the x coordinate corresponding to a time + * + * @param time + * the time + * @return the x coordinate corresponding to the time + * + * @since 2.0 + */ + public int getXForTime(long time) { + return fTimeGraphCtrl.getXForTime(time); + } + + /** + * Return the time corresponding to an x coordinate + * + * @param x + * the x coordinate + * @return the time corresponding to the x coordinate + * + * @since 2.0 + */ + public long getTimeAtX(int x) { + return fTimeGraphCtrl.getTimeAtX(x); + } + + /** + * Get the selection provider + * + * @return the selection provider + */ + public ISelectionProvider getSelectionProvider() { + return fTimeGraphCtrl; + } + + /** + * Wait for the cursor + * + * @param waitInd + * Wait indefinitely? + */ + public void waitCursor(boolean waitInd) { + fTimeGraphCtrl.waitCursor(waitInd); + } + + /** + * Get the horizontal scroll bar object + * + * @return The scroll bar + */ + public ScrollBar getHorizontalBar() { + return fTimeGraphCtrl.getHorizontalBar(); + } + + /** + * Get the vertical scroll bar object + * + * @return The scroll bar + */ + public Slider getVerticalBar() { + return fVerticalScrollBar; + } + + /** + * Set the given index as the top one + * + * @param index + * The index that will go to the top + */ + public void setTopIndex(int index) { + fTimeGraphCtrl.setTopIndex(index); + adjustVerticalScrollBar(); + } + + /** + * Retrieve the current top index + * + * @return The top index + */ + public int getTopIndex() { + return fTimeGraphCtrl.getTopIndex(); + } + + /** + * Sets the auto-expand level to be used when the input of the viewer is set + * using {@link #setInput(Object)}. The value 0 means that there is no + * auto-expand; 1 means that top-level elements are expanded, but not their + * children; 2 means that top-level elements are expanded, and their + * children, but not grand-children; and so on. + *

    + * The value {@link #ALL_LEVELS} means that all subtrees should be expanded. + *

    + * @param level + * non-negative level, or ALL_LEVELS to expand all + * levels of the tree + * @since 3.1 + */ + public void setAutoExpandLevel(int level) { + fTimeGraphCtrl.setAutoExpandLevel(level); + } + + /** + * Returns the auto-expand level. + * + * @return non-negative level, or ALL_LEVELS if all levels of + * the tree are expanded automatically + * @see #setAutoExpandLevel + * @since 3.1 + */ + public int getAutoExpandLevel() { + return fTimeGraphCtrl.getAutoExpandLevel(); + } + + /** + * Set the expanded state of an entry + * + * @param entry + * The entry to expand/collapse + * @param expanded + * True for expanded, false for collapsed + */ + public void setExpandedState(ITimeGraphEntry entry, boolean expanded) { + fTimeGraphCtrl.setExpandedState(entry, expanded); + adjustVerticalScrollBar(); + } + + /** + * Collapses all nodes of the viewer's tree, starting with the root. + * + * @since 2.0 + */ + public void collapseAll() { + fTimeGraphCtrl.collapseAll(); + adjustVerticalScrollBar(); + } + + /** + * Expands all nodes of the viewer's tree, starting with the root. + * + * @since 2.0 + */ + public void expandAll() { + fTimeGraphCtrl.expandAll(); + adjustVerticalScrollBar(); + } + + /** + * Get the number of sub-elements when expanded + * + * @return The element count + */ + public int getExpandedElementCount() { + return fTimeGraphCtrl.getExpandedElementCount(); + } + + /** + * Get the sub-elements + * + * @return The array of entries that are below this one + */ + public ITimeGraphEntry[] getExpandedElements() { + return fTimeGraphCtrl.getExpandedElements(); + } + + /** + * Add a tree listener + * + * @param listener + * The listener to add + */ + public void addTreeListener(ITimeGraphTreeListener listener) { + fTimeGraphCtrl.addTreeListener(listener); + } + + /** + * Remove a tree listener + * + * @param listener + * The listener to remove + */ + public void removeTreeListener(ITimeGraphTreeListener listener) { + fTimeGraphCtrl.removeTreeListener(listener); + } + + /** + * Get the reset scale action. + * + * @return The Action object + */ + public Action getResetScaleAction() { + if (fResetScaleAction == null) { + // resetScale + fResetScaleAction = new Action() { + @Override + public void run() { + resetStartFinishTime(); + notifyStartFinishTime(); + } + }; + fResetScaleAction.setText(Messages.TmfTimeGraphViewer_ResetScaleActionNameText); + fResetScaleAction.setToolTipText(Messages.TmfTimeGraphViewer_ResetScaleActionToolTipText); + fResetScaleAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_HOME_MENU)); + } + return fResetScaleAction; + } + + /** + * Get the show legend action. + * + * @return The Action object + */ + public Action getShowLegendAction() { + if (fShowLegendAction == null) { + // showLegend + fShowLegendAction = new Action() { + @Override + public void run() { + showLegend(); + } + }; + fShowLegendAction.setText(Messages.TmfTimeGraphViewer_LegendActionNameText); + fShowLegendAction.setToolTipText(Messages.TmfTimeGraphViewer_LegendActionToolTipText); + fShowLegendAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_LEGEND)); + } + + return fShowLegendAction; + } + + /** + * Get the the next event action. + * + * @return The action object + */ + public Action getNextEventAction() { + if (fNextEventAction == null) { + fNextEventAction = new Action() { + @Override + public void run() { + selectNextEvent(); + } + }; + + fNextEventAction.setText(Messages.TmfTimeGraphViewer_NextEventActionNameText); + fNextEventAction.setToolTipText(Messages.TmfTimeGraphViewer_NextEventActionToolTipText); + fNextEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_EVENT)); + } + + return fNextEventAction; + } + + /** + * Get the previous event action. + * + * @return The Action object + */ + public Action getPreviousEventAction() { + if (fPrevEventAction == null) { + fPrevEventAction = new Action() { + @Override + public void run() { + selectPrevEvent(); + } + }; + + fPrevEventAction.setText(Messages.TmfTimeGraphViewer_PreviousEventActionNameText); + fPrevEventAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousEventActionToolTipText); + fPrevEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_EVENT)); + } + + return fPrevEventAction; + } + + /** + * Get the next item action. + * + * @return The Action object + */ + public Action getNextItemAction() { + if (fNextItemAction == null) { + + fNextItemAction = new Action() { + @Override + public void run() { + selectNextItem(); + } + }; + fNextItemAction.setText(Messages.TmfTimeGraphViewer_NextItemActionNameText); + fNextItemAction.setToolTipText(Messages.TmfTimeGraphViewer_NextItemActionToolTipText); + fNextItemAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_ITEM)); + } + return fNextItemAction; + } + + /** + * Get the previous item action. + * + * @return The Action object + */ + public Action getPreviousItemAction() { + if (fPreviousItemAction == null) { + + fPreviousItemAction = new Action() { + @Override + public void run() { + selectPrevItem(); + } + }; + fPreviousItemAction.setText(Messages.TmfTimeGraphViewer_PreviousItemActionNameText); + fPreviousItemAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousItemActionToolTipText); + fPreviousItemAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_ITEM)); + } + return fPreviousItemAction; + } + + /** + * Get the zoom in action + * + * @return The Action object + */ + public Action getZoomInAction() { + if (fZoomInAction == null) { + fZoomInAction = new Action() { + @Override + public void run() { + zoomIn(); + } + }; + fZoomInAction.setText(Messages.TmfTimeGraphViewer_ZoomInActionNameText); + fZoomInAction.setToolTipText(Messages.TmfTimeGraphViewer_ZoomInActionToolTipText); + fZoomInAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ZOOM_IN_MENU)); + } + return fZoomInAction; + } + + /** + * Get the zoom out action + * + * @return The Action object + */ + public Action getZoomOutAction() { + if (fZoomOutAction == null) { + fZoomOutAction = new Action() { + @Override + public void run() { + zoomOut(); + } + }; + fZoomOutAction.setText(Messages.TmfTimeGraphViewer_ZoomOutActionNameText); + fZoomOutAction.setToolTipText(Messages.TmfTimeGraphViewer_ZoomOutActionToolTipText); + fZoomOutAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ZOOM_OUT_MENU)); + } + return fZoomOutAction; + } + + /** + * Get the hide arrows action + * + * @param dialogSettings + * The dialog settings section where the state should be stored, + * or null + * + * @return The Action object + * + * @since 2.1 + */ + public Action getHideArrowsAction(final IDialogSettings dialogSettings) { + if (fHideArrowsAction == null) { + fHideArrowsAction = new Action(Messages.TmfTimeGraphViewer_HideArrowsActionNameText, IAction.AS_CHECK_BOX) { + @Override + public void run() { + boolean hideArrows = fHideArrowsAction.isChecked(); + fTimeGraphCtrl.hideArrows(hideArrows); + refresh(); + if (dialogSettings != null) { + dialogSettings.put(HIDE_ARROWS_KEY, hideArrows); + } + if (fFollowArrowFwdAction != null) { + fFollowArrowFwdAction.setEnabled(!hideArrows); + } + if (fFollowArrowBwdAction != null) { + fFollowArrowBwdAction.setEnabled(!hideArrows); + } + } + }; + fHideArrowsAction.setToolTipText(Messages.TmfTimeGraphViewer_HideArrowsActionToolTipText); + fHideArrowsAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_HIDE_ARROWS)); + if (dialogSettings != null) { + boolean hideArrows = dialogSettings.getBoolean(HIDE_ARROWS_KEY); + fTimeGraphCtrl.hideArrows(hideArrows); + fHideArrowsAction.setChecked(hideArrows); + if (fFollowArrowFwdAction != null) { + fFollowArrowFwdAction.setEnabled(!hideArrows); + } + if (fFollowArrowBwdAction != null) { + fFollowArrowBwdAction.setEnabled(!hideArrows); + } + } + } + return fHideArrowsAction; + } + + /** + * Get the follow arrow forward action. + * + * @return The Action object + * + * @since 2.1 + */ + public Action getFollowArrowFwdAction() { + if (fFollowArrowFwdAction == null) { + fFollowArrowFwdAction = new Action() { + @Override + public void run() { + fTimeGraphCtrl.followArrowFwd(); + adjustVerticalScrollBar(); + } + }; + fFollowArrowFwdAction.setText(Messages.TmfTimeGraphViewer_FollowArrowForwardActionNameText); + fFollowArrowFwdAction.setToolTipText(Messages.TmfTimeGraphViewer_FollowArrowForwardActionToolTipText); + fFollowArrowFwdAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FOLLOW_ARROW_FORWARD)); + if (fHideArrowsAction != null) { + fFollowArrowFwdAction.setEnabled(!fHideArrowsAction.isChecked()); + } + } + return fFollowArrowFwdAction; + } + + /** + * Get the follow arrow backward action. + * + * @return The Action object + * + * @since 2.1 + */ + public Action getFollowArrowBwdAction() { + if (fFollowArrowBwdAction == null) { + fFollowArrowBwdAction = new Action() { + @Override + public void run() { + fTimeGraphCtrl.followArrowBwd(); + adjustVerticalScrollBar(); + } + }; + fFollowArrowBwdAction.setText(Messages.TmfTimeGraphViewer_FollowArrowBackwardActionNameText); + fFollowArrowBwdAction.setToolTipText(Messages.TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText); + fFollowArrowBwdAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FOLLOW_ARROW_BACKWARD)); + if (fHideArrowsAction != null) { + fFollowArrowBwdAction.setEnabled(!fHideArrowsAction.isChecked()); + } + } + return fFollowArrowBwdAction; + } + + private void adjustVerticalScrollBar() { + int topIndex = fTimeGraphCtrl.getTopIndex(); + int countPerPage = fTimeGraphCtrl.countPerPage(); + int expandedElementCount = fTimeGraphCtrl.getExpandedElementCount(); + if (topIndex + countPerPage > expandedElementCount) { + fTimeGraphCtrl.setTopIndex(Math.max(0, expandedElementCount - countPerPage)); + } + + int selection = fTimeGraphCtrl.getTopIndex(); + int min = 0; + int max = Math.max(1, expandedElementCount - 1); + int thumb = Math.min(max, Math.max(1, countPerPage - 1)); + int increment = 1; + int pageIncrement = Math.max(1, countPerPage); + fVerticalScrollBar.setValues(selection, min, max, thumb, increment, pageIncrement); + } + + /** + * @param listener + * a {@link MenuDetectListener} + * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener) + * @since 1.2 + */ + public void addTimeGraphEntryMenuListener(MenuDetectListener listener) { + fTimeGraphCtrl.addTimeGraphEntryMenuListener(listener); + } + + /** + * @param listener + * a {@link MenuDetectListener} + * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener) + * @since 1.2 + */ + public void removeTimeGraphEntryMenuListener(MenuDetectListener listener) { + fTimeGraphCtrl.removeTimeGraphEntryMenuListener(listener); + } + + /** + * @param listener + * a {@link MenuDetectListener} + * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener) + * @since 1.2 + */ + public void addTimeEventMenuListener(MenuDetectListener listener) { + fTimeGraphCtrl.addTimeEventMenuListener(listener); + } + + /** + * @param listener + * a {@link MenuDetectListener} + * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener) + * @since 1.2 + */ + public void removeTimeEventMenuListener(MenuDetectListener listener) { + fTimeGraphCtrl.removeTimeEventMenuListener(listener); + } + + /** + * @param filter + * The filter object to be attached to the view + * @since 2.0 + */ + public void addFilter(ViewerFilter filter) { + fTimeGraphCtrl.addFilter(filter); + refresh(); + } + + /** + * @param filter + * The filter object to be attached to the view + * @since 2.0 + */ + public void removeFilter(ViewerFilter filter) { + fTimeGraphCtrl.removeFilter(filter); + refresh(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/dialogs/FilteredCheckboxTree.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/dialogs/FilteredCheckboxTree.java new file mode 100644 index 0000000000..e7eb954749 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/dialogs/FilteredCheckboxTree.java @@ -0,0 +1,193 @@ +/******************************************************************************* + * Copyright (c) 2014 Inria + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Generoso Pagano, Inria - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTreeViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.ICheckable; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.dialogs.FilteredTree; +import org.eclipse.ui.dialogs.PatternFilter; +import org.eclipse.ui.progress.WorkbenchJob; + +/** + * A FilteredTree wrapping a CheckboxTreeViewer. + * + * This tree keeps the check state of the nodes in sync, regardless of the fact + * that a node is filtered or not. This way, even if an node is filtered (not + * visible), the caller can get and set the check state. + * + * Note that all the "uncheck" operations act only on what is not filtered and + * what is child of something not filtered (even if such a child is filtered). + * On the contrary, all the "check" operations act only on what is not filtered. + * + * @author "Generoso Pagano " + * @since 3.2 + */ +public class FilteredCheckboxTree extends FilteredTree implements ICheckable { + + /** + * Set containing only the tree items that are checked + */ + private Set fObjects = new HashSet<>(); + + /** + * Handle to the tree viewer + */ + private CheckboxTreeViewer fCheckboxTreeViewer; + + /** + * Create a new instance of the receiver. + * + * @param parent + * the parent Composite + * @param treeStyle + * the style bits for the Tree + * @param filter + * the filter to be used + * @param useNewLook + * true if the new FilteredTree look + * should be used + */ + public FilteredCheckboxTree(Composite parent, int treeStyle, PatternFilter filter, + boolean useNewLook) { + super(parent, treeStyle, filter, useNewLook); + } + + @Override + protected TreeViewer doCreateTreeViewer(Composite parentComposite, int style) { + fCheckboxTreeViewer = new CheckboxTreeViewer(parentComposite, style); + fCheckboxTreeViewer.addCheckStateListener(new ICheckStateListener() { + @Override + public void checkStateChanged(CheckStateChangedEvent event) { + if (event.getChecked()) { + fObjects.add(event.getElement()); + } else { + fObjects.remove(event.getElement()); + } + } + }); + return fCheckboxTreeViewer; + } + + @Override + protected WorkbenchJob doCreateRefreshJob() { + WorkbenchJob job = super.doCreateRefreshJob(); + job.addJobChangeListener(new JobChangeAdapter() { + @Override + public void done(IJobChangeEvent event) { + fCheckboxTreeViewer.expandAll(); + fCheckboxTreeViewer.setCheckedElements(getCheckedElements()); + } + }); + return job; + } + + @Override + public boolean getChecked(Object element) { + return fObjects.contains(element); + } + + @Override + public boolean setChecked(Object element, boolean state) { + boolean checkable = fCheckboxTreeViewer.setChecked(element, state); + if (!state) { + fObjects.remove(element); + } else if (checkable) { + fObjects.add(element); + } + return checkable; + } + + @Override + public void addCheckStateListener(ICheckStateListener listener) { + fCheckboxTreeViewer.addCheckStateListener(listener); + } + + @Override + public void removeCheckStateListener(ICheckStateListener listener) { + fCheckboxTreeViewer.addCheckStateListener(listener); + } + + /** + * Returns all the checked elements of this tree, either visible or not. + * + * @return an array containing all the checked elements + */ + public Object[] getCheckedElements() { + return fObjects.toArray(); + } + + /** + * Checks all the passed elements and unchecks all the other. + * + * @param elements + * the elements to check + */ + public void setCheckedElements(Object[] elements) { + fObjects = new HashSet<>(); + for (Object element : elements) { + fObjects.add(element); + } + fCheckboxTreeViewer.setCheckedElements(elements); + } + + /** + * Sets the check state for the given element and its children in this + * viewer. The unchecked state is always set, while the checked state is set + * only on visible elements. + * + * @param element + * the element + * @param state + * the check state to set + * @return true if the check state could be set, and + * false otherwise + */ + public boolean setSubtreeChecked(Object element, boolean state) { + checkSubtree(element, state); + return fCheckboxTreeViewer.setSubtreeChecked(element, state); + } + + /** + * Recursively sets the check state on an element and its children, using + * the politic specified in {@link #setSubtreeChecked(Object, boolean)} + * documentation. + * + * @param element + * the element + * @param state + * the check state to set + */ + private void checkSubtree(Object element, boolean state) { + if (!state || (fCheckboxTreeViewer.testFindItem(element) != null)) { + if (state) { + fObjects.add(element); + } else { + fObjects.remove(element); + } + for (Object o : ((ITreeContentProvider) fCheckboxTreeViewer.getContentProvider()).getChildren(element)) { + checkSubtree(o, state); + } + } + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/dialogs/TimeGraphFilterDialog.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/dialogs/TimeGraphFilterDialog.java new file mode 100644 index 0000000000..e816fdcabf --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/dialogs/TimeGraphFilterDialog.java @@ -0,0 +1,569 @@ +/******************************************************************************* + * Copyright (c) 2000, 2013 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Sebastian Davids - Fix for bug 19346 - Dialog font should be + * activated and used by other components. + * Lubomir Marinov - Fix for bug 182122 -[Dialogs] + * CheckedTreeSelectionDialog#createSelectionButtons(Composite) fails to + * align the selection buttons to the right + * François Rajotte - Support for multiple columns + selection control + * Patrick Tasse - Fix Sonar warnings + * Generoso Pagano - Add tree filter + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTreeViewer; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.dialogs.ISelectionStatusValidator; +import org.eclipse.ui.dialogs.PatternFilter; +import org.eclipse.ui.dialogs.SelectionStatusDialog; + +/** + * Filter dialog for the time graphs This class is derived from the + * CheckedTreeSelectionDialog It was necessary to develop this similar dialog to + * allow multiple columns + * + * @version 1.0 + * @since 2.0 + * @author François Rajotte + */ +public class TimeGraphFilterDialog extends SelectionStatusDialog { + private static final int BUTTON_CHECK_SELECTED_ID = IDialogConstants.CLIENT_ID; + private static final int BUTTON_UNCHECK_SELECTED_ID = IDialogConstants.CLIENT_ID + 1; + private static final int BUTTON_CHECK_SUBTREE_ID = IDialogConstants.CLIENT_ID + 2; + private static final int BUTTON_UNCHECK_SUBTREE_ID = IDialogConstants.CLIENT_ID + 3; + + private static final int DEFAULT_WIDTH = 60; + private static final int DEFAULT_HEIGHT = 18; + + private FilteredCheckboxTree fTree; + + private IBaseLabelProvider fLabelProvider; + + private ITreeContentProvider fContentProvider; + + private String[] fColumnNames; + + private ISelectionStatusValidator fValidator = null; + + private ViewerComparator fComparator; + + private String fEmptyListMessage = ""; //$NON-NLS-1$ + + private IStatus fCurrStatus = new Status(IStatus.OK, PlatformUI.PLUGIN_ID, + 0, "", null); //$NON-NLS-1$ + + private List fFilters; + + private Object fInput; + + private boolean fIsEmpty; + + private int fWidth = DEFAULT_WIDTH; + + private int fHeight = DEFAULT_HEIGHT; + + private Object[] fExpandedElements; + + /** + * Constructs an instance of ElementTreeSelectionDialog. + * + * @param parent + * The shell to parent from. + */ + public TimeGraphFilterDialog(Shell parent) { + super(parent); + setResult(new ArrayList<>(0)); + setStatusLineAboveButtons(true); + setHelpAvailable(false); + fExpandedElements = null; + } + + /** + * Sets the initial selection. Convenience method. + * + * @param selection + * the initial selection. + */ + public void setInitialSelection(Object selection) { + setInitialSelections(new Object[] { selection }); + } + + /** + * Sets the message to be displayed if the list is empty. + * + * @param message + * the message to be displayed. + */ + public void setEmptyListMessage(String message) { + fEmptyListMessage = message; + } + + /** + * Sets the comparator used by the tree viewer. + * + * @param comparator + * The comparator + */ + public void setComparator(ViewerComparator comparator) { + fComparator = comparator; + } + + /** + * Adds a filter to the tree viewer. + * + * @param filter + * a filter. + */ + public void addFilter(ViewerFilter filter) { + if (fFilters == null) { + fFilters = new ArrayList<>(); + } + fFilters.add(filter); + } + + /** + * Sets an optional validator to check if the selection is valid. The + * validator is invoked whenever the selection changes. + * + * @param validator + * the validator to validate the selection. + */ + public void setValidator(ISelectionStatusValidator validator) { + fValidator = validator; + } + + /** + * Sets the tree input. + * + * @param input + * the tree input. + */ + public void setInput(Object input) { + fInput = input; + } + + /** + * Expands elements in the tree. + * + * @param elements + * The elements that will be expanded. + */ + public void setExpandedElements(Object[] elements) { + if (elements != null) { + fExpandedElements = Arrays.copyOf(elements, elements.length); + } else { + fExpandedElements = null; + } + } + + /** + * Sets the size of the tree in unit of characters. + * + * @param width + * the width of the tree. + * @param height + * the height of the tree. + */ + public void setSize(int width, int height) { + fWidth = width; + fHeight = height; + } + + /** + * @param contentProvider + * The content provider for the table + */ + public void setContentProvider(ITreeContentProvider contentProvider) { + fContentProvider = contentProvider; + } + + /** + * @param labelProvider + * The label provider for the table + */ + public void setLabelProvider(IBaseLabelProvider labelProvider) { + fLabelProvider = labelProvider; + } + + /** + * @param columnNames + * An array of column names to display + */ + public void setColumnNames(String[] columnNames) { + if (columnNames != null) { + fColumnNames = Arrays.copyOf(columnNames, columnNames.length); + } else { + fColumnNames = null; + } + } + + /** + * Validate the receiver and update the status with the result. + * + */ + protected void updateOKStatus() { + if (!fIsEmpty) { + if (fValidator != null) { + fCurrStatus = fValidator.validate(fTree.getCheckedElements()); + updateStatus(fCurrStatus); + } else if (!fCurrStatus.isOK()) { + fCurrStatus = new Status(IStatus.OK, PlatformUI.PLUGIN_ID, + IStatus.OK, "", //$NON-NLS-1$ + null); + } + } else { + fCurrStatus = new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, + IStatus.OK, fEmptyListMessage, null); + } + updateStatus(fCurrStatus); + } + + @Override + public int open() { + fIsEmpty = evaluateIfTreeEmpty(fInput); + super.open(); + return getReturnCode(); + } + + @Override + protected void cancelPressed() { + setResult(null); + super.cancelPressed(); + } + + @Override + protected void computeResult() { + setResult(Arrays.asList(fTree.getCheckedElements())); + } + + @Override + public void create() { + BusyIndicator.showWhile(null, new Runnable() { + @Override + public void run() { + TimeGraphFilterDialog.super.create(); + fTree.setCheckedElements(getInitialElementSelections() + .toArray()); + if (fExpandedElements != null) { + fTree.getViewer().setExpandedElements(fExpandedElements); + } + updateOKStatus(); + } + }); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + Label messageLabel = createMessageArea(composite); + CheckboxTreeViewer treeViewer = createTreeViewer(composite); + Control buttonComposite = createSelectionButtons(composite); + GridData data = new GridData(GridData.FILL_BOTH); + data.widthHint = convertWidthInCharsToPixels(fWidth); + data.heightHint = convertHeightInCharsToPixels(fHeight); + Tree treeWidget = treeViewer.getTree(); + treeWidget.setLayoutData(data); + treeWidget.setFont(parent.getFont()); + if (fIsEmpty) { + messageLabel.setEnabled(false); + treeWidget.setEnabled(false); + buttonComposite.setEnabled(false); + } + return composite; + } + + /** + * Creates the tree viewer. + * + * @param parent + * the parent composite + * @return the tree viewer + */ + protected CheckboxTreeViewer createTreeViewer(Composite parent) { + PatternFilter filter = new TreePatternFilter(); + filter.setIncludeLeadingWildcard(true); + fTree = new FilteredCheckboxTree(parent, SWT.BORDER | SWT.MULTI, filter, true); + + Tree tree = fTree.getViewer().getTree(); + tree.setHeaderVisible(true); + for (String columnName : fColumnNames) { + TreeColumn column = new TreeColumn(tree, SWT.LEFT); + column.setText(columnName); + column.pack(); + } + + fTree.getViewer().setContentProvider(fContentProvider); + fTree.getViewer().setLabelProvider(fLabelProvider); + fTree.addCheckStateListener(new CheckStateListener()); + fTree.getViewer().setComparator(fComparator); + if (fFilters != null) { + for (int i = 0; i != fFilters.size(); i++) { + fTree.getViewer().addFilter(fFilters.get(i)); + } + } + fTree.getViewer().setInput(fInput); + + // pack the columns again for a nice view... + for (TreeColumn column : tree.getColumns()) { + column.pack(); + } + return (CheckboxTreeViewer) fTree.getViewer(); + } + + /** + * Returns the tree viewer. + * + * @return the tree viewer + */ + protected CheckboxTreeViewer getTreeViewer() { + return (CheckboxTreeViewer) fTree.getViewer(); + } + + /** + * Adds the selection and deselection buttons to the dialog. + * + * @param composite + * the parent composite + * @return Composite the composite the buttons were created in. + */ + protected Composite createSelectionButtons(Composite composite) { + Composite buttonComposite = new Composite(composite, SWT.RIGHT); + GridLayout layout = new GridLayout(); + layout.marginWidth = 0; + layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); + buttonComposite.setLayout(layout); + buttonComposite.setFont(composite.getFont()); + GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END + | GridData.GRAB_HORIZONTAL); + data.grabExcessHorizontalSpace = true; + buttonComposite.setLayoutData(data); + + /* Create the buttons in the good order to place them as we want */ + Button checkSelectedButton = createButton(buttonComposite, + BUTTON_CHECK_SELECTED_ID, Messages.TmfTimeFilterDialog_CHECK_SELECTED, + false); + Button checkSubtreeButton = createButton(buttonComposite, + BUTTON_CHECK_SUBTREE_ID, Messages.TmfTimeFilterDialog_CHECK_SUBTREE, + false); + Button checkAllButton = createButton(buttonComposite, + IDialogConstants.SELECT_ALL_ID, Messages.TmfTimeFilterDialog_CHECK_ALL, + false); + + Button uncheckSelectedButton = createButton(buttonComposite, + BUTTON_UNCHECK_SELECTED_ID, Messages.TmfTimeFilterDialog_UNCHECK_SELECTED, + false); + Button uncheckSubtreeButton = createButton(buttonComposite, + BUTTON_UNCHECK_SUBTREE_ID, Messages.TmfTimeFilterDialog_UNCHECK_SUBTREE, + false); + Button uncheckAllButton = createButton(buttonComposite, + IDialogConstants.DESELECT_ALL_ID, Messages.TmfTimeFilterDialog_UNCHECK_ALL, + false); + + /* + * Apply the layout again after creating the buttons to override + * createButton messing with the columns + */ + layout.numColumns = 3; + buttonComposite.setLayout(layout); + + /* Add a listener to each button */ + checkSelectedButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + TreeSelection selection = (TreeSelection) fTree.getViewer().getSelection(); + + for (Object element : selection.toArray()) { + checkElement(element); + } + + updateOKStatus(); + } + }); + + checkSubtreeButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + TreeSelection selection = (TreeSelection) fTree.getViewer().getSelection(); + + for (Object element : selection.toArray()) { + checkElementAndSubtree(element); + } + } + }); + + checkAllButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + Object[] viewerElements = fContentProvider.getElements(fInput); + + for (int i = 0; i < viewerElements.length; i++) { + fTree.setSubtreeChecked(viewerElements[i], true); + } + + updateOKStatus(); + } + }); + + uncheckSelectedButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + TreeSelection selection = (TreeSelection) fTree.getViewer().getSelection(); + + for (Object element : selection.toArray()) { + uncheckElement(element); + } + + updateOKStatus(); + } + }); + + uncheckSubtreeButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + TreeSelection selection = (TreeSelection) fTree.getViewer().getSelection(); + + for (Object element : selection.toArray()) { + uncheckElement(element); + } + + updateOKStatus(); + } + }); + + uncheckAllButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + Object[] viewerElements = fContentProvider.getElements(fInput); + for (Object element : viewerElements) { + if (fTree.getViewer().testFindItem(element) != null) { + // uncheck only visible roots and their children + uncheckElement(element); + } + } + updateOKStatus(); + } + }); + + return buttonComposite; + } + + /** + * Check an element and all its parents. + * + * @param element + * The element to check. + */ + private void checkElement(Object element) { + fTree.setChecked(element, true); + + Object parent = fContentProvider.getParent(element); + + if (parent != null && !fTree.getChecked(parent)) { + checkElement(parent); + } + } + + /** + * Check an element, all its parents and all its children. + * + * @param element + * The element to check. + */ + private void checkElementAndSubtree(Object element) { + checkElement(element); + + for (Object child : fContentProvider.getChildren(element)) { + checkElementAndSubtree(child); + } + } + + /** + * Uncheck an element and all its children. + * + * @param element + * The element to uncheck. + */ + private void uncheckElement(Object element) { + fTree.setChecked(element, false); + + for (Object child : fContentProvider.getChildren(element)) { + uncheckElement(child); + } + } + + private boolean evaluateIfTreeEmpty(Object input) { + Object[] elements = fContentProvider.getElements(input); + if (elements.length > 0 && fFilters != null) { + for (int i = 0; i < fFilters.size(); i++) { + ViewerFilter curr = fFilters.get(i); + elements = curr.filter(fTree.getViewer(), input, elements); + } + } + return elements.length == 0; + } + + /** + * Private classes + */ + + private class CheckStateListener implements ICheckStateListener { + + CheckStateListener() { + } + + @Override + public void checkStateChanged(CheckStateChangedEvent event) { + try { + ITimeGraphEntry entry = (ITimeGraphEntry) event.getElement(); + boolean checked = event.getChecked(); + if (checked) { + checkElement(entry); + } else { + uncheckElement(entry); + } + } catch (ClassCastException e) { + return; + } finally { + updateOKStatus(); + } + } + + } +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/dialogs/TimeGraphLegend.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/dialogs/TimeGraphLegend.java new file mode 100644 index 0000000000..4256bc607f --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/dialogs/TimeGraphLegend.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alvaro Sanchez-Leon - Initial API and implementation + * Patrick Tasse - Refactoring + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.StateItem; + +/** + * Legend for the colors used in the time graph view + * + * @version 1.0 + * @author Alvaro Sanchez-Leon + * @author Patrick Tasse + */ +public class TimeGraphLegend extends TitleAreaDialog { + + private final ITimeGraphPresentationProvider provider; + private final LocalResourceManager fResourceManager = new LocalResourceManager(JFaceResources.getResources()); + + /** + * Open the time graph legend window + * + * @param parent + * The parent shell + * @param provider + * The presentation provider + */ + public static void open(Shell parent, ITimeGraphPresentationProvider provider) { + (new TimeGraphLegend(parent, provider)).open(); + } + + /** + * Standard constructor + * + * @param parent + * The parent shell + * @param provider + * The presentation provider + */ + public TimeGraphLegend(Shell parent, ITimeGraphPresentationProvider provider) { + super(parent); + this.provider = provider; + this.setShellStyle(getShellStyle() | SWT.RESIZE); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite dlgArea = (Composite) super.createDialogArea(parent); + Composite composite = new Composite(dlgArea, SWT.NONE); + + GridLayout layout = new GridLayout(); + composite.setLayout(layout); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + composite.setLayoutData(gd); + + createStatesGroup(composite); + + setTitle(Messages.TmfTimeLegend_LEGEND); + setDialogHelpAvailable(false); + setHelpAvailable(false); + + return composite; + } + + private void createStatesGroup(Composite composite) { + ScrolledComposite sc = new ScrolledComposite(composite, SWT.V_SCROLL|SWT.H_SCROLL); + sc.setExpandHorizontal(true); + sc.setExpandVertical(true); + Group gs = new Group(sc, SWT.H_SCROLL); + sc.setContent(gs); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + sc.setLayoutData(gd); + + String stateTypeName = provider.getStateTypeName(); + StringBuffer buffer = new StringBuffer(); + if (!stateTypeName.isEmpty()) { + buffer.append(stateTypeName); + buffer.append(" "); //$NON-NLS-1$ + } + buffer.append(Messages.TmfTimeLegend_StateTypeName); + gs.setText(buffer.toString()); + + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + layout.marginWidth = 20; + layout.marginBottom = 10; + gs.setLayout(layout); + + // Go through all the defined pairs of state color and state name and display them. + StateItem[] stateItems = provider.getStateTable(); + for (int i = 0; i < stateItems.length; i++) { + //Get the color related to the index + RGB rgb = stateItems[i].getStateColor(); + + //Get the given name, provided by the interface to the application + String stateName = stateItems[i].getStateString(); + + // draw color with name + Bar bar = new Bar(gs, rgb); + gd = new GridData(); + gd.widthHint = 40; + gd.heightHint = 20; + gd.verticalIndent = 8; + bar.setLayoutData(gd); + Label name = new Label(gs, SWT.NONE); + name.setText(stateName); + gd = new GridData(); + gd.horizontalIndent = 10; + gd.verticalIndent = 8; + name.setLayoutData(gd); + } + sc.setMinSize(gs.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + } + + @Override + protected void configureShell(Shell shell) { + super.configureShell(shell); + shell.setText(Messages.TmfTimeLegend_TRACE_STATES_TITLE); + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, + true); + } + + class Bar extends Canvas { + private final Color color; + + public Bar(Composite parent, RGB rgb) { + super(parent, SWT.NONE); + + color = fResourceManager.createColor(rgb); + addListener(SWT.Paint, new Listener() { + @Override + public void handleEvent(Event event) { + draw(event.gc); + } + }); + } + + private void draw(GC gc) { + Rectangle r = getClientArea(); + gc.setBackground(color); + gc.fillRectangle(r); + gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); + gc.drawRectangle(0, 0, r.width - 1, r.height - 1); + } + + @Override + public void dispose() { + super.dispose(); + color.dispose(); + } + + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/dialogs/TreePatternFilter.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/dialogs/TreePatternFilter.java new file mode 100644 index 0000000000..ab044d6962 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/dialogs/TreePatternFilter.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2014 Inria + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Generoso Pagano, Inria - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs; + +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.ui.dialogs.PatternFilter; + +/** + * A filter extending the org.eclipse.ui.dialogs.PatternFilter. + * + * It redefines the {@link #isElementVisible(Viewer, Object)}} method in order + * to have a match on a node if: the node matches or one of the children matches + * or one of the parents matches. + * + * @author "Generoso Pagano " + * @since 3.2 + */ +public class TreePatternFilter extends PatternFilter { + + @Override + public boolean isElementVisible(Viewer viewer, Object element) { + return super.isElementVisible(viewer, element) || isChildMatch(viewer, element); + } + + /** + * Check if at least one of the parents of this element is a match with the + * filter text. + * + * @param viewer + * the viewer that contains the element + * @param element + * the tree element to check + * @return true if the given element has a parent that matches the filter + * text + */ + private boolean isChildMatch(Viewer viewer, Object element) { + Object parent = ((ITreeContentProvider) ((AbstractTreeViewer) viewer).getContentProvider()) + .getParent(element); + while (parent != null) { + if (isLeafMatch(viewer, parent)) { + return true; + } + parent = ((ITreeContentProvider) ((AbstractTreeViewer) viewer).getContentProvider()) + .getParent(parent); + } + return false; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/EventIterator.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/EventIterator.java new file mode 100644 index 0000000000..3873afadcf --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/EventIterator.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model; + +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + + +/** + * An iterator for time events. Events from the zoomed event list override any + * events from the underlying event list. + * @since 2.0 + */ +public class EventIterator implements Iterator { + + private final long fStartTime; + private final long fEndTime; + private List fEventList; + private List fZoomedEventList; + private long fZoomedStartTime; + private long fZoomedEndTime; + private int fIndex = 0; + private int fZoomedIndex= 0; + private ITimeEvent fNext = null; + private ITimeEvent fSplitNext = null; + private ITimeEvent fZoomedNext = null; + + /** + * Basic constructor, with start time and end times equal to the lowest and + * highest values possible, respectively. + * + * @param eventList + * The list on which this iterator will iterate + * @param zoomedEventList + * The "zoomed" list + */ + public EventIterator(List eventList, List zoomedEventList) { + this(eventList, zoomedEventList, Long.MIN_VALUE, Long.MAX_VALUE); + } + + /** + * Complete constructor, where we specify start and end times. + * + * @param eventList + * The list on which this iterator will iterate + * @param zoomedEventList + * The "zoomed" list + * @param startTime + * The start time + * @param endTime + * The end time + */ + public EventIterator(List eventList, + List zoomedEventList, long startTime, long endTime) { + fEventList = eventList; + fZoomedEventList = zoomedEventList; + if (zoomedEventList != null && zoomedEventList.size() > 0) { + fZoomedStartTime = zoomedEventList.get(0).getTime(); + ITimeEvent lastEvent = zoomedEventList.get(zoomedEventList.size() - 1); + fZoomedEndTime = lastEvent.getTime() + lastEvent.getDuration(); + } else { + fZoomedStartTime = Long.MAX_VALUE; + fZoomedEndTime = Long.MIN_VALUE; + } + fStartTime = startTime; + fEndTime = endTime; + } + + @Override + public boolean hasNext() { + if (fNext == null && fEventList != null) { + while (fIndex < fEventList.size()) { + ITimeEvent event = fEventList.get(fIndex++); + if (event.getTime() + event.getDuration() >= fStartTime && event.getTime() <= fEndTime && + (event.getTime() < fZoomedStartTime || event.getTime() + event.getDuration() > fZoomedEndTime)) { + // the event is visible and is not completely hidden by the zoomed events + fNext = event; + if (event.getTime() < fZoomedEndTime && event.getTime() + event.getDuration() > fZoomedStartTime) { + // the event is partially hidden by the zoomed events and must be split + fNext = null; + if (event.getTime() + event.getDuration() > fZoomedEndTime && fZoomedEndTime < fEndTime) { + // the end of the event is partially hidden by the zoomed events and is visible + if (event instanceof ITimeEvent2) { + fNext = ((ITimeEvent2) event).split(fZoomedEndTime).getSecond(); + } else { + fNext = new TimeEvent(event.getEntry(), fZoomedEndTime, event.getTime() + event.getDuration() - fZoomedEndTime); + } + } + if (event.getTime() < fZoomedStartTime && fZoomedStartTime > fStartTime) { + // the start of the event is partially hidden by the zoomed events and is visible + fSplitNext = fNext; + if (event instanceof ITimeEvent2) { + fNext = ((ITimeEvent2) event).split(fZoomedStartTime).getFirst(); + } else { + fNext = new TimeEvent(event.getEntry(), event.getTime(), fZoomedStartTime - event.getTime()); + } + } + } + if (fNext != null) { + break; + } + } + } + if (fNext == null) { + fEventList = null; + } + } + + if (fZoomedNext == null && fZoomedEventList != null) { + while (fZoomedIndex < fZoomedEventList.size()) { + ITimeEvent event = fZoomedEventList.get(fZoomedIndex++); + if (event.getTime() + event.getDuration() >= fStartTime && event.getTime() <= fEndTime) { + // the zoomed event is visible + fZoomedNext = event; + break; + } + } + if (fZoomedNext == null) { + fZoomedEventList = null; + } + } + + return fNext != null || fZoomedNext != null; + } + + @Override + public ITimeEvent next() { + if (hasNext()) { + if (fZoomedNext != null && (fNext == null || fZoomedNext.getTime() <= fNext.getTime())) { + ITimeEvent event = fZoomedNext; + fZoomedNext = null; + return event; + } + ITimeEvent event = fNext; + fNext = fSplitNext; + fSplitNext = null; + return event; + } + throw new NoSuchElementException(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/ILinkEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/ILinkEvent.java new file mode 100644 index 0000000000..5806714f18 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/ILinkEvent.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model; + +/** + * Interface for time event that allows to specify the destination entry of the + * event + * + * @since 2.1 + */ +public interface ILinkEvent extends ITimeEvent { + + /** + * Get this event's destination entry + * + * @return The destination entry + */ + ITimeGraphEntry getDestinationEntry(); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/ITimeEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/ITimeEvent.java new file mode 100644 index 0000000000..5bc19eb9e1 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/ITimeEvent.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alvaro Sanchez-Leon - Initial API and implementation + * Patrick Tasse - Refactoring + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model; + +/** + * Interface for time events, for use in the timegraph view + * + * @version 1.0 + * @author Alvaro Sanchez-Leon + * @author Patrick Tasse + */ +public interface ITimeEvent { + + /** + * Get the entry matching this time event. + * + * @return The time graph entry + */ + ITimeGraphEntry getEntry(); + + /** + * Get the timestamp of this event. + * + * @return The event's time + */ + long getTime(); + + /** + * @return + * + *
  • -1: Considers duration to be from current event till the next
  • + *
  • 0: Duration is not relevant e.g. a Burst / no state associated
  • + *
  • >0: Valid duration value specified
  • + *
    + *

    + */ + long getDuration(); + +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/ITimeEvent2.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/ITimeEvent2.java new file mode 100644 index 0000000000..b982e2f616 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/ITimeEvent2.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model; + +import org.eclipse.tracecompass.tmf.core.util.Pair; + +/** + * Extend ITimeEvent interface + * + * @author Patrick Tasse + * @since 2.1 + */ +public interface ITimeEvent2 extends ITimeEvent { + + /** + * Split an event in two at the specified time. If the time is smaller or + * equal to the event's start, the first split event is null. If the time is + * greater or equal to the event's end, the second split event is null. + * + * @param time + * the time at which the event is to be split + * @return a pair of time events + */ + Pair split(long time); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/ITimeGraphEntry.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/ITimeGraphEntry.java new file mode 100644 index 0000000000..8be70b44a9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/ITimeGraphEntry.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alvaro Sanchez-Leon - Initial API and implementation + * Patrick Tasse - Refactoring + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model; + +import java.util.Iterator; +import java.util.List; + +/** + * Interface for an entry (row) in the time graph view + * + * @version 1.0 + * @author Alvaro Sanchez-Leon + * @author Patrick Tasse + */ +public interface ITimeGraphEntry { + + /** + * Returns the parent of this entry, or null if it has none. + * + * @return the parent element, or null if it has none + */ + ITimeGraphEntry getParent(); + + /** + * Returns whether this entry has children. + * + * @return true if the given element has children, + * and false if it has no children + */ + boolean hasChildren(); + + /** + * Returns the child elements of this entry. + * + * @return an array of child elements + * @since 2.0 + */ + List getChildren(); + + /** + * Returns the name of this entry. + * + * @return the entry name + */ + String getName(); + + /** + * Returns the start time of this entry in nanoseconds. + * + * @return the start time + */ + long getStartTime(); + + /** + * Returns the end time of this entry in nanoseconds. + * + * @return the end time + */ + long getEndTime(); + + /** + * Returns whether this entry has time events. + * If true, the time events iterator should not be null. + * + * @return true if the entry has time events + * + * @see #getTimeEventsIterator + * @see #getTimeEventsIterator(long, long, long) + */ + boolean hasTimeEvents(); + + /** + * Get an iterator which returns all time events. + * + * @return the iterator + */ + Iterator getTimeEventsIterator(); + + /** + * Get an iterator which only returns events that fall within the start time and the stop time. + * The visible duration is the event duration below which further detail is not discernible. + * If no such iterator is implemented, provide a basic iterator which returns all events. + * + * @param startTime start time in nanoseconds + * @param stopTime stop time in nanoseconds + * @param visibleDuration duration of one pixel in nanoseconds + * + * @return the iterator + */ + Iterator getTimeEventsIterator(long startTime, long stopTime, long visibleDuration); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/NullTimeEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/NullTimeEvent.java new file mode 100644 index 0000000000..56c5deb688 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/NullTimeEvent.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model; + +/** + * A null time event. Used to represent an event that should not be drawn, + * for example as a zoomed event that overshadows an underlying event. + * + * @since 2.0 + */ +public class NullTimeEvent extends TimeEvent { + + /** + * Standard constructor + * + * @param entry + * The entry matching this event + * @param time + * The timestamp of this event + * @param duration + * The duration of the event + */ + public NullTimeEvent(ITimeGraphEntry entry, long time, long duration) { + super(entry, time, duration); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeEvent.java new file mode 100644 index 0000000000..d899527203 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeEvent.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Geneviève Bastien - Added the fValue parameter to avoid subclassing + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model; + +import org.eclipse.tracecompass.tmf.core.util.Pair; + +/** + * Generic TimeEvent implementation + * + * @version 1.0 + * @author Patrick Tasse + */ +public class TimeEvent implements ITimeEvent2 { + + /** TimeGraphEntry matching this time event */ + protected ITimeGraphEntry fEntry; + + /** Beginning timestamp of this time event */ + protected long fTime; + + /** Duration of this time event */ + protected long fDuration; + + private final int fValue; + + /** + * Default value when no other value present + */ + private static final int NOVALUE = Integer.MIN_VALUE; + + /** + * Standard constructor + * + * @param entry + * The entry matching this event + * @param time + * The timestamp of this event + * @param duration + * The duration of the event + */ + public TimeEvent(ITimeGraphEntry entry, long time, long duration) { + this(entry, time, duration, NOVALUE); + + } + + /** + * Constructor + * + * @param entry + * The entry to which this time event is assigned + * @param time + * The timestamp of this event + * @param duration + * The duration of this event + * @param value + * The status assigned to the event + * @since 2.1 + */ + public TimeEvent(ITimeGraphEntry entry, long time, long duration, + int value) { + fEntry = entry; + fTime = time; + fDuration = duration; + fValue = value; + } + + /** + * Get this event's status + * + * @return The integer matching this status + * @since 2.1 + */ + public int getValue() { + return fValue; + } + + /** + * Return whether an event has a value + * + * @return true if the event has a value + * @since 2.1 + */ + public boolean hasValue() { + return (fValue != NOVALUE); + } + + @Override + public ITimeGraphEntry getEntry() { + return fEntry; + } + + @Override + public long getTime() { + return fTime; + } + + @Override + public long getDuration() { + return fDuration; + } + + /** + * Split an event in two at the specified time. If the time is smaller or + * equal to the event's start, the first split event is null. If the time is + * greater or equal to the event's end, the second split event is null. + *

    + * Subclasses should re-implement this method + * + * @since 2.1 + */ + @Override + public Pair split(long time) { + Pair pair = new Pair<>(); + if (time > fTime) { + pair.setFirst(new TimeEvent(fEntry, fTime, Math.min(fDuration, time - fTime), fValue)); + } + if (time < fTime + fDuration) { + pair.setSecond(new TimeEvent(fEntry, Math.max(fTime, time), fDuration - Math.max(0, time - fTime), fValue)); + } + return pair; + } + + @Override + public String toString() { + return getClass().getSimpleName() + " start=" + fTime + " end=" + (fTime + fDuration) + " duration=" + fDuration + (hasValue() ? (" value=" + fValue) : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java new file mode 100644 index 0000000000..ab66cbd8cd --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java @@ -0,0 +1,304 @@ +/******************************************************************************* + * Copyright (c) 2012, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + * Geneviève Bastien - Move code to provide base classes for time graph view + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * An entry for use in the time graph views + * + * @since 2.1 + */ +public class TimeGraphEntry implements ITimeGraphEntry { + + /** Entry's parent */ + private ITimeGraphEntry fParent = null; + + /** List of child entries */ + private final List fChildren = new CopyOnWriteArrayList<>(); + + /** Name of this entry (text to show) */ + private String fName; + private long fStartTime = -1; + private long fEndTime = -1; + private List fEventList = new ArrayList<>(); + private List fZoomedEventList = new ArrayList<>(); + private Comparator fComparator; + + /** + * Constructor + * + * @param name + * The name of this entry + * @param startTime + * The start time of this entry + * @param endTime + * The end time of this entry + */ + public TimeGraphEntry(String name, long startTime, long endTime) { + fName = name; + fStartTime = startTime; + fEndTime = endTime; + } + + // --------------------------------------------- + // Getters and setters + // --------------------------------------------- + + @Override + public ITimeGraphEntry getParent() { + return fParent; + } + + /** + * Sets the entry's parent + * + * @param entry The new parent entry + */ + /* + * TODO: This method can be removed in the next major API version. + */ + protected void setParent(TimeGraphEntry entry) { + fParent = entry; + } + + /** + * Sets the entry's parent + * + * @param entry The new parent entry + * @since 3.1 + */ + /* + * TODO: This method should be added to the interface in the next major API version. + */ + protected void setParent(ITimeGraphEntry entry) { + fParent = entry; + } + + @Override + public synchronized boolean hasChildren() { + return fChildren.size() > 0; + } + + @Override + public synchronized List getChildren() { + return fChildren; + } + + @Override + public String getName() { + return fName; + } + + /** + * Update the entry name + * + * @param name + * the updated entry name + */ + public void setName(String name) { + fName = name; + } + + @Override + public long getStartTime() { + return fStartTime; + } + + @Override + public long getEndTime() { + return fEndTime; + } + + /** + * Updates the end time + * + * @param endTime + * the end time + * + * @since 3.0 + */ + public void updateEndTime(long endTime) { + fEndTime = Math.max(endTime, fEndTime); + } + + @Override + public boolean hasTimeEvents() { + return true; + } + + @Override + public Iterator getTimeEventsIterator() { + if (hasTimeEvents()) { + return new EventIterator(fEventList, fZoomedEventList); + } + return null; + } + + @Override + public Iterator getTimeEventsIterator(long startTime, long stopTime, long visibleDuration) { + if (!hasTimeEvents()) { + return null; + } + return new EventIterator(fEventList, fZoomedEventList, startTime, stopTime); + } + + /** + * Add an event to this entry's event list. If necessary, update the start + * and end time of the entry. If the event list's last event starts at the + * same time as the event to add, it is replaced by the new event. + * + * @param event + * The time event to add + */ + public void addEvent(ITimeEvent event) { + long start = event.getTime(); + long end = start + event.getDuration(); + synchronized (fEventList) { + int lastIndex = fEventList.size() - 1; + if (lastIndex >= 0 && fEventList.get(lastIndex).getTime() == event.getTime()) { + fEventList.set(lastIndex, event); + } else { + fEventList.add(event); + } + if (fStartTime == -1 || start < fStartTime) { + fStartTime = start; + } + if (fEndTime == -1 || end > fEndTime) { + fEndTime = end; + } + } + } + + /** + * Set the general event list of this entry. + * + * @param eventList + * The list of time events + */ + public void setEventList(List eventList) { + if (eventList != null) { + fEventList = new ArrayList<>(eventList); + } else { + fEventList = new ArrayList<>(); + } + } + + /** + * Set the zoomed event list of this entry. + * + * @param eventList + * The list of time events + */ + public void setZoomedEventList(List eventList) { + if (eventList != null) { + fZoomedEventList = new ArrayList<>(eventList); + } else { + fZoomedEventList = new ArrayList<>(); + } + } + + /** + * Add a child entry to this one + * + * @param child + * The child entry + */ + /* + * TODO: This method can be removed in the next major API version. + */ + public synchronized void addChild(TimeGraphEntry child) { + addChild((ITimeGraphEntry) child); + } + + /** + * Add a child entry to this one. If a comparator was previously set with + * {@link #sortChildren(Comparator)}, the entry will be inserted in its + * sort-order position. Otherwise it will be added to the end of the list. + * + * @param child + * The child entry + * @since 3.1 + */ + public synchronized void addChild(ITimeGraphEntry child) { + /* + * TODO: Use setParent() once it is added to the interface. + */ + if (child instanceof TimeGraphEntry) { + ((TimeGraphEntry) child).fParent = this; + } + if (fComparator == null) { + fChildren.add(child); + } else { + int i; + for (i = 0; i < fChildren.size(); i++) { + ITimeGraphEntry entry = fChildren.get(i); + if (fComparator.compare(child, entry) < 0) { + break; + } + } + fChildren.add(i, child); + } + } + + /** + * Add a child entry to this one at the specified position + * + * @param index + * Index at which the specified entry is to be inserted + * @param child + * The child entry + * @since 3.1 + */ + public synchronized void addChild(int index, ITimeGraphEntry child) { + /* + * TODO: Use setParent() once it is added to the interface. + */ + if (child instanceof TimeGraphEntry) { + ((TimeGraphEntry) child).fParent = this; + } + fChildren.add(index, child); + } + + /** + * Sort the children of this entry using the provided comparator. Subsequent + * calls to {@link #addChild(ITimeGraphEntry)} will use this comparator to + * maintain the sort order. + * + * @param comparator + * The entry comparator + * @since 3.1 + */ + public synchronized void sortChildren(Comparator comparator) { + fComparator = comparator; + if (comparator == null) { + return; + } + ITimeGraphEntry[] array = fChildren.toArray(new ITimeGraphEntry[0]); + Arrays.sort(array, comparator); + fChildren.clear(); + fChildren.addAll(Arrays.asList(array)); + } + + @Override + public String toString() { + return getClass().getSimpleName() + '(' + fName + ')'; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeLinkEvent.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeLinkEvent.java new file mode 100644 index 0000000000..41d173ecc7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeLinkEvent.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model; + +/** + * TimeEvent implementation for events that do not involve only one entry, they + * have a source entry and destination entry + * + * @since 2.1 + */ +public class TimeLinkEvent extends TimeEvent implements ILinkEvent { + + /** TimeGraphEntry matching the destination this time event */ + private ITimeGraphEntry fDestEntry; + + /** + * Standard constructor + * + * @param src + * The source entry of this event + * @param dst + * The destination entry of this event + * @param time + * The timestamp of this event + * @param duration + * The duration of the event + */ + public TimeLinkEvent(ITimeGraphEntry src, ITimeGraphEntry dst, long time, long duration) { + super(src, time, duration); + fDestEntry = dst; + } + + /** + * Constructor + * + * @param src + * The source entry of this event + * @param dst + * The destination entry of this event + * @param time + * The timestamp of this event + * @param duration + * The duration of this event + * @param value + * The status assigned to the event + */ + public TimeLinkEvent(ITimeGraphEntry src, ITimeGraphEntry dst, long time, long duration, + int value) { + super(src, time, duration, value); + fDestEntry = dst; + } + + @Override + public ITimeGraphEntry getDestinationEntry() { + return fDestEntry; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/ITimeDataProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/ITimeDataProvider.java new file mode 100644 index 0000000000..44b63841a9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/ITimeDataProvider.java @@ -0,0 +1,175 @@ +/***************************************************************************** + * Copyright (c) 2007, 2014 Intel Corporation, Ericsson + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + * Ruslan A. Scherbakov, Intel - Initial API and implementation + * Alvaro Sanchez-Leon - Updated for TMF + * Geneviève Bastien - Added methods to save a time range selection + * Patrick Tasse - Refactoring, support for range selection + *****************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets; + +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; + +/** + * Time data provider interface, for use in the timegraph widget. + * + * @version 1.0 + * @author Alvaro Sanchez-Leon + * @author Patrick Tasse + * @author Xavier Raynaud + */ +public interface ITimeDataProvider { + + /** + * Updates the selection begin and end time and notifies any registered + * listeners about the new time range (if necessary) + * + * @param beginTime the selection begin time + * @param endTime the selection end time + * @since 3.0 + */ + void setSelectionRangeNotify(long beginTime, long endTime); + + /** + * Updates the selection begin and end time + * + * @param beginTime the selection begin time + * @param endTime the selection end time + * @since 3.0 + */ + void setSelectionRange(long beginTime, long endTime); + + /** + * @return The begin time of the current selection + * @since 3.0 + */ + long getSelectionBegin(); + + /** + * @return The end time of the current selection + * @since 3.0 + */ + long getSelectionEnd(); + + /** + * @return The beginning time + */ + long getBeginTime(); + + /** + * @return The end time + */ + long getEndTime(); + + /** + * @return The minimum time + */ + long getMinTime(); + + /** + * @return The maximum time + */ + long getMaxTime(); + + /** + * @return The start time of the current selection window + */ + long getTime0(); + + /** + * @return The end time of the current selection window + */ + long getTime1(); + + /** + * @return The minimal time interval + */ + long getMinTimeInterval(); + + /** + * Updates the time range and notify registered listeners + * + * @param time0 + * @param time1 + */ + void setStartFinishTimeNotify(long time0, long time1); + + /** + * Update the time range but do not trigger event notification + * + * @param time0 + * @param time1 + */ + void setStartFinishTime(long time0, long time1); + + /** + * Notify registered listeners without updating the time range + */ + void notifyStartFinishTime(); + + /** + * Updates the selected time, adjusts the time range if necessary and + * notifies any registered listeners about the new selected time and new + * range (if necessary) + * + * @param time + * A Time to set + * @param ensureVisible + * Ensure visibility of new time (will adjust time range if + * necessary) + */ + void setSelectedTimeNotify(long time, boolean ensureVisible); + + /** + * Updates the selected time and adjusts the time range if necessary without + * notifying registered listeners. + * + * @param time + * A Time to set + * @param ensureVisible + * Ensure visibility of new time (will adjust time range if + * necessary) + */ + void setSelectedTime(long time, boolean ensureVisible); + + /** + * Reset the start and end times + */ + void resetStartFinishTime(); + + /** + * @return The names' width + */ + int getNameSpace(); + + /** + * Set the names' width + * + * @param width + */ + void setNameSpace(int width); + + /** + * @return The width for timestamps + */ + int getTimeSpace(); + + /** + * @return the time format, one of: + *

      + *
    • {@link TimeFormat#CALENDAR} absolute time, displayed as year/month/day/hours/minutes/seconds/ms/us/ns + *
    • {@link TimeFormat#RELATIVE} relative time, displayed as seconds/ms/us/ns + *
    • {@link TimeFormat#NUMBER} number, displayed as long values. + *
    + * @since 2.0 + */ + TimeFormat getTimeFormat(); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/ITimeDataProviderConverter.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/ITimeDataProviderConverter.java new file mode 100644 index 0000000000..49eb9eaa08 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/ITimeDataProviderConverter.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets; + +/** + * Time data provider that converts between time data units used internally and + * time in display units used by the caller. + * + * @since 3.2 + */ +public interface ITimeDataProviderConverter extends ITimeDataProvider { + + /** + * Convert a time in time data provider units to a time in display units. + * + * @param time the time in time data provider units + * + * @return the time in display units + */ + long convertTime(long time); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/ITmfTimeGraphDrawingHelper.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/ITmfTimeGraphDrawingHelper.java new file mode 100644 index 0000000000..271e67a529 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/ITmfTimeGraphDrawingHelper.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets; + +/** + * This interface provides functions to convert a model element to a drawing + * element and vice versa. + * + * Views who implement this interface allow access to some model-to-canvas and + * vice-versa functions without having to expose their full functionnalities. + * + * @author gbastien + * @since 2.1 + */ +public interface ITmfTimeGraphDrawingHelper { + + /** + * Return the x coordinate corresponding to a time + * + * @param time + * the time + * @return the x coordinate corresponding to the time + */ + int getXForTime(long time); + + /** + * Return the time corresponding to an x coordinate + * + * @param x + * the x coordinate + * @return the time corresponding to the x coordinate + */ + long getTimeAtX(int x); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeDataProviderCyclesConverter.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeDataProviderCyclesConverter.java new file mode 100644 index 0000000000..a3962ac019 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeDataProviderCyclesConverter.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; + +/** + * Time Data Provider wrapper that converts nanoseconds to cycles. + * + * The user of the wrapper uses cycles, the wrapped provider uses nanoseconds. + * @since 3.2 + * + */ +public class TimeDataProviderCyclesConverter implements ITimeDataProviderConverter { + + private static final long GIGAHERTZ = 1000000000L; + + private final @NonNull ITimeDataProvider fProvider; + private final long fFreq; + + /** + * Constructor + * + * @param provider + * the original time data provider + * @param clockFrequency + * the clock frequency in Hz + */ + public TimeDataProviderCyclesConverter(@NonNull ITimeDataProvider provider, long clockFrequency) { + fProvider = provider; + fFreq = clockFrequency; + } + + /** + * Convert nanoseconds to cycles + * + * @param nanos + * time in nanoseconds + * @return time in cycles + */ + public long toCycles(long nanos) { + return Math.round(nanos * ((double) fFreq / GIGAHERTZ)); + } + + /** + * Convert cycles to nanoseconds + * + * @param cycles + * time in cycles + * @return time in nanoseconds + */ + public long toNanos(long cycles) { + return Math.round(cycles * ((double) GIGAHERTZ / fFreq)); + } + + @Override + public long convertTime(long time) { + return toCycles(time); + } + + @Override + public void setSelectionRangeNotify(long beginTime, long endTime) { + fProvider.setSelectionRangeNotify(toNanos(beginTime), toNanos(endTime)); + } + + @Override + public void setSelectionRange(long beginTime, long endTime) { + fProvider.setSelectionRange(toNanos(beginTime), toNanos(endTime)); + } + + @Override + public long getSelectionBegin() { + return toCycles(fProvider.getSelectionBegin()); + } + + @Override + public long getSelectionEnd() { + return toCycles(fProvider.getSelectionEnd()); + } + + @Override + public long getBeginTime() { + return toCycles(fProvider.getBeginTime()); + } + + @Override + public long getEndTime() { + return toCycles(fProvider.getEndTime()); + } + + @Override + public long getMinTime() { + return toCycles(fProvider.getMinTime()); + } + + @Override + public long getMaxTime() { + return toCycles(fProvider.getMaxTime()); + } + + @Override + public long getTime0() { + return toCycles(fProvider.getTime0()); + } + + @Override + public long getTime1() { + return toCycles(fProvider.getTime1()); + } + + @Override + public long getMinTimeInterval() { + // do not convert: this is in integer units + return fProvider.getMinTimeInterval(); + } + + @Override + public void setStartFinishTimeNotify(long time0, long time1) { + fProvider.setStartFinishTimeNotify(toNanos(time0), toNanos(time1)); + } + + @Override + public void setStartFinishTime(long time0, long time1) { + fProvider.setStartFinishTime(toNanos(time0), toNanos(time1)); + } + + @Override + public void notifyStartFinishTime() { + fProvider.notifyStartFinishTime(); + } + + @Override + public void setSelectedTimeNotify(long time, boolean ensureVisible) { + fProvider.setSelectedTimeNotify(toNanos(time), ensureVisible); + } + + @Override + public void setSelectedTime(long time, boolean ensureVisible) { + fProvider.setSelectedTime(toNanos(time), ensureVisible); + } + + @Override + public void resetStartFinishTime() { + fProvider.resetStartFinishTime(); + } + + @Override + public int getNameSpace() { + return fProvider.getNameSpace(); + } + + @Override + public void setNameSpace(int width) { + fProvider.setNameSpace(width); + } + + @Override + public int getTimeSpace() { + return fProvider.getTimeSpace(); + } + + @Override + public TimeFormat getTimeFormat() { + return fProvider.getTimeFormat(); + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphBaseControl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphBaseControl.java new file mode 100644 index 0000000000..6f08d69e1e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphBaseControl.java @@ -0,0 +1,115 @@ +/***************************************************************************** + * Copyright (c) 2007, 2013 Intel Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + * Ruslan A. Scherbakov, Intel - Initial API and implementation + * Alvaro Sanchez-Leon - Updated for TMF + * Patrick Tasse - Refactoring + *****************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; + +/** + * Base control abstract class for the time graph widget + * + * @version 1.0 + * @author Alvaro Sanchez-Leon + * @author Patrick Tasse + */ +public abstract class TimeGraphBaseControl extends Canvas implements PaintListener { + + /** Default left margin size */ + public static final int MARGIN = 4; + + /** Default expanded size */ + public static final int EXPAND_SIZE = 9; // the [+] or [-] control size + + /** Default size of the right margin */ + public static final int RIGHT_MARGIN = 1; // 1 pixels less to make sure end time is visible + + /** Default size for small icons */ + public static final int SMALL_ICON_SIZE = 16; + + /** Color scheme */ + private TimeGraphColorScheme fColorScheme; + + /** Font size */ + private int fFontHeight = 0; + + /** + * Basic constructor. Uses a default style value + * + * @param parent + * The parent composite object + * @param colors + * The color scheme to use + */ + public TimeGraphBaseControl(Composite parent, TimeGraphColorScheme colors) { + this(parent, colors, SWT.NO_BACKGROUND | SWT.NO_FOCUS); + } + + /** + * Standard constructor + * + * @param parent + * The parent composite object + * @param colorScheme + * The color scheme to use + * @param style + * The index of the style to use + */ + public TimeGraphBaseControl(Composite parent, TimeGraphColorScheme colorScheme, int style) { + super(parent, style); + fColorScheme = colorScheme; + addPaintListener(this); + } + + @Override + public void paintControl(PaintEvent e) { + if (e.widget != this) { + return; + } + fFontHeight = e.gc.getFontMetrics().getHeight(); + Rectangle bound = getClientArea(); + if (!bound.isEmpty()) { + Color colBackup = e.gc.getBackground(); + paint(bound, e); + e.gc.setBackground(colBackup); + } + } + + /** + * Retrieve the color scheme + * + * @return The color scheme + * + * @since 2.0 + */ + public TimeGraphColorScheme getColorScheme() { + return fColorScheme; + } + + /** + * Retrieve the current font's height + * + * @return The height + */ + public int getFontHeight() { + return fFontHeight; + } + + abstract void paint(Rectangle bound, PaintEvent e); +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphColorScheme.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphColorScheme.java new file mode 100644 index 0000000000..95550c596e --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphColorScheme.java @@ -0,0 +1,428 @@ +/***************************************************************************** + * Copyright (c) 2008, 2013 Intel Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + * Ruslan A. Scherbakov, Intel - Initial API and implementation + * Alvaro Sanchez-Leon - Updated for TMF + * Patrick Tasse - Refactoring + *****************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; + +/** + * Color theme used by the timegraph view + * + * @version 1.0 + * @author Patrick Tasse + */ +@SuppressWarnings("javadoc") +public class TimeGraphColorScheme { + + // elements color indices + public static final int BLACK_STATE = 0; + public static final int GREEN_STATE = 1; + public static final int DARK_BLUE_STATE = 2; + public static final int ORANGE_STATE = 3; + public static final int GOLD_STATE = 4; + public static final int RED_STATE = 5; + public static final int GRAY_STATE = 6; + public static final int DARK_GREEN_STATE = 7; + public static final int DARK_YELLOW_STATE = 8; + public static final int MAGENTA3_STATE = 9; + public static final int PURPLE1_STATE = 10; + public static final int PINK1_STATE = 11; + public static final int AQUAMARINE_STATE = 12; + public static final int LIGHT_BLUE_STATE = 13; + public static final int CADET_BLUE_STATE = 14; + public static final int OLIVE_STATE = 15; + + public static final int STATES0 = 0; + public static final int STATES1 = 15; + + // selected state elements color indices + public static final int BLACK_STATE_SEL = 16; + public static final int GREEN_STATE_SEL = 17; + public static final int DARK_BLUE_STATE_SEL = 18; + public static final int ORANGE_STATE_SEL = 19; + public static final int GOLD_STATE_SEL = 20; + public static final int RED_STATE_SEL = 21; + public static final int GRAY_STATE_SEL = 22; + public static final int DARK_GREEN_STATE_SEL = 23; + public static final int DARK_YELLOW_STATE_SEL = 24; + public static final int MAGENTA3_STATE_SEL = 25; + public static final int PURPLE1_STATE_SEL = 26; + public static final int PINK1_STATE_SEL = 27; + public static final int AQUAMARINE_STATE_SEL = 28; + public static final int LIGHT_BLUE_STATE_SEL = 29; + public static final int CADET_BLUE_STATE_SEL = 30; + public static final int OLIVE_STATE_SEL = 31; + + public static final int STATES_SEL0 = 16; + public static final int STATES_SEL1 = 31; + + // colors indices for viewer controls + public static final int BACKGROUND = 32; + public static final int FOREGROUND = 33; + public static final int BACKGROUND_SEL = 34; + public static final int FOREGROUND_SEL = 35; + public static final int BACKGROUND_SEL_NOFOCUS = 36; + public static final int FOREGROUND_SEL_NOFOCUS = 37; + public static final int TOOL_BACKGROUND = 38; + public static final int TOOL_FOREGROUND = 39; + + // misc colors + public static final int FIX_COLOR = 40; + public static final int WHITE = 41; + public static final int GRAY = 42; + public static final int BLACK = 43; + public static final int DARK_GRAY = 44; + + // selected border color indices + public static final int BLACK_BORDER = 45; + public static final int GREEN_BORDER = 46; + public static final int DARK_BLUE_BORDER = 47; + public static final int ORANGE_BORDER = 48; + public static final int GOLD_BORDER = 49; + public static final int RED_BORDER = 50; + public static final int GRAY_BORDER = 51; + public static final int DARK_GREEN_BORDER1 = 52; + public static final int DARK_YELLOW_BORDER1 = 53; + public static final int MAGENTA3_BORDER1 = 54; + public static final int PURPLE1_BORDER1 = 55; + public static final int PINK1_BORDER1 = 56; + public static final int AQUAMARINE_BORDER1 = 57; + public static final int LIGHT_BLUE_BORDER1 = 58; + public static final int CADET_BLUE_STATE_BORDER = 59; + public static final int OLIVE_BORDER2 = 60; + + public static final int STATES_BORDER0 = 45; + public static final int STATES_BORDER1 = 60; + + public static final int MID_LINE = 61; + public static final int RED = 62; + public static final int GREEN = 63; + public static final int BLUE = 64; + public static final int YELLOW = 65; + public static final int CYAN = 66; + public static final int MAGENTA = 67; + + public static final int SELECTED_TIME = 68; + public static final int LEGEND_BACKGROUND = 69; + public static final int LEGEND_FOREGROUND = 70; + + // group items' colors + public static final int GR_BACKGROUND = 71; + public static final int GR_FOREGROUND = 72; + public static final int GR_BACKGROUND_SEL = 73; + public static final int GR_FOREGROUND_SEL = 74; + public static final int GR_BACKGROUND_SEL_NOFOCUS = 75; + public static final int GR_FOREGROUND_SEL_NOFOCUS = 76; + + public static final int LIGHT_LINE = 77; + public static final int BACKGROUND_NAME = 78; + public static final int BACKGROUND_NAME_SEL = 79; + public static final int BACKGROUND_NAME_SEL_NOFOCUS = 80; + + // Interraction's colors + public static final int TI_START_THREAD = BLACK; + public static final int TI_HANDOFF_LOCK = BLUE; + public static final int TI_NOTIFY_ALL = GREEN; + public static final int TI_NOTIFY = GREEN; + public static final int TI_NOTIFY_JOINED = DARK_GRAY; + public static final int TI_INTERRUPT = RED; + public static final int TI_WAIT_EXCEEDED = BLUE; + + interface IColorProvider { + Color get(); + } + + static class SysCol implements IColorProvider { + private int syscol; + + SysCol(int syscol) { + this.syscol = syscol; + } + + @Override + public Color get() { + return Utils.getSysColor(syscol); + } + } + + static class RGB implements IColorProvider { + private int r; + private int g; + private int b; + + RGB(int r, int g, int b) { + this.r = r; + this.g = g; + this.b = b; + } + + @Override + public Color get() { + return new Color(null, r, g, b); + } + } + + static class Mix implements IColorProvider { + private IColorProvider cp1; + private IColorProvider cp2; + private int w1; + private int w2; + + Mix(IColorProvider cp1, IColorProvider cp2, int w1, int w2) { + this.cp1 = cp1; + this.cp2 = cp2; + this.w1 = w1; + this.w2 = w2; + } + + Mix(IColorProvider cp1, IColorProvider cp2) { + this.cp1 = cp1; + this.cp2 = cp2; + this.w1 = 1; + this.w2 = 1; + } + + @Override + public Color get() { + Color col1 = cp1.get(); + Color col2 = cp2.get(); + return Utils.mixColors(col1, col2, w1, w2); + } + } + + private static final IColorProvider PROVIDERS_MAP[] = { + // + new RGB(100, 100, 100), // UNKNOWN + new RGB(174, 200, 124), // RUNNING + new Mix(new SysCol(SWT.COLOR_BLUE), new SysCol(SWT.COLOR_GRAY), 1, 3), // SLEEPING + new RGB(210, 150, 60), // WAITING + new RGB(242, 225, 168), // BLOCKED + new Mix(new SysCol(SWT.COLOR_RED), new SysCol(SWT.COLOR_GRAY), 1, 3), // DEADLOCK + new RGB(200, 200, 200), // STOPPED + new RGB(35, 107, 42), // STEEL BLUE + new RGB(205,205,0), // DARK YELLOW + new RGB(205, 0, 205), // MAGENTA + new RGB(171, 130, 255), // PURPLE + new RGB(255, 181, 197), // PINK + new RGB(112, 219, 147), // AQUAMARINE + new RGB(198, 226, 255), // SLATEGRAY + new RGB(95, 158, 160), // CADET BLUE + new RGB(107, 142, 35), // OLIVE + + + //TODO: Does not seem to be used, check during clean-up + new SysCol(SWT.COLOR_WHITE), // UNKNOWN_SEL + new SysCol(SWT.COLOR_GREEN), // RUNNING_SEL + new SysCol(SWT.COLOR_BLUE), // SLEEPING_SEL + new SysCol(SWT.COLOR_CYAN), // WAITING_SEL + new SysCol(SWT.COLOR_YELLOW), // BLOCKED_SEL + new SysCol(SWT.COLOR_RED), // DEADLOCK_SEL + new SysCol(SWT.COLOR_DARK_GRAY), // STOPPED_SEL + new SysCol(SWT.COLOR_WHITE), + new SysCol(SWT.COLOR_GREEN), + new SysCol(SWT.COLOR_BLUE), + new SysCol(SWT.COLOR_CYAN), + new SysCol(SWT.COLOR_YELLOW), + new SysCol(SWT.COLOR_RED), + new SysCol(SWT.COLOR_DARK_GRAY), + new SysCol(SWT.COLOR_WHITE), + new SysCol(SWT.COLOR_GREEN), + + + new SysCol(SWT.COLOR_LIST_BACKGROUND), // BACKGROUND + new SysCol(SWT.COLOR_LIST_FOREGROUND), // FOREGROUND + new RGB(232, 242, 254), // BACKGROUND_SEL + new SysCol(SWT.COLOR_LIST_FOREGROUND), // FOREGROUND_SEL + new SysCol(SWT.COLOR_WIDGET_BACKGROUND), // BACKGROUND_SEL_NOFOCUS + new SysCol(SWT.COLOR_WIDGET_FOREGROUND), // FOREGROUND_SEL_NOFOCUS + new SysCol(SWT.COLOR_WIDGET_BACKGROUND), // TOOL_BACKGROUND + new SysCol(SWT.COLOR_WIDGET_DARK_SHADOW), // TOOL_FOREGROUND + + new SysCol(SWT.COLOR_GRAY), // FIX_COLOR + new SysCol(SWT.COLOR_WHITE), // WHITE + new SysCol(SWT.COLOR_GRAY), // GRAY + new SysCol(SWT.COLOR_BLACK), // BLACK + new SysCol(SWT.COLOR_DARK_GRAY), // DARK_GRAY + + new SysCol(SWT.COLOR_DARK_GRAY), // BLACK_BORDER + new RGB(75, 115, 120), // GREEN_BORDER + new SysCol(SWT.COLOR_DARK_BLUE), // DARK_BLUE_BORDER + new RGB(242, 225, 168), // ORANGE_BORDER + new RGB(210, 150, 60), // GOLD_BORDER + new SysCol(SWT.COLOR_DARK_RED), // RED_BORDER + new SysCol(SWT.COLOR_BLACK), // GRAY_BORDER + new SysCol(SWT.COLOR_DARK_GRAY), // DARK_GREEN_BORDER + new RGB(75, 115, 120), // DARK_YELLOW_BORDER + new SysCol(SWT.COLOR_DARK_BLUE), // MAGENTA3_BORDER + new RGB(242, 225, 168), // PURPLE1_BORDER + new RGB(210, 150, 60), // PINK1_BORDER + new SysCol(SWT.COLOR_DARK_RED), // AQUAMARINE_BORDER + new SysCol(SWT.COLOR_BLACK), // LIGHT_BLUE_BORDER + new SysCol(SWT.COLOR_DARK_GRAY), // BLUE_BORDER + new RGB(75, 115, 120), // OLIVE_BORDER + + + new SysCol(SWT.COLOR_GRAY), // MID_LINE + new SysCol(SWT.COLOR_RED), // RED + new SysCol(SWT.COLOR_GREEN), // GREEN + new SysCol(SWT.COLOR_BLUE), // BLUE + new SysCol(SWT.COLOR_YELLOW), // YELLOW + new SysCol(SWT.COLOR_CYAN), // CYAN + new SysCol(SWT.COLOR_MAGENTA), // MAGENTA + + new SysCol(SWT.COLOR_BLUE), // SELECTED_TIME + new SysCol(SWT.COLOR_WIDGET_BACKGROUND), // LEGEND_BACKGROUND + new SysCol(SWT.COLOR_WIDGET_DARK_SHADOW), // LEGEND_FOREGROUND + + new Mix(new RGB(150, 200, 240), new SysCol(SWT.COLOR_LIST_BACKGROUND)), // GR_BACKGROUND + new RGB(0, 0, 50), // GR_FOREGROUND + new Mix(new RGB(150, 200, 240), new SysCol(SWT.COLOR_WHITE), 6, 1), // GR_BACKGROUND_SEL + new RGB(0, 0, 50), // GR_FOREGROUND_SEL + new Mix(new RGB(150, 200, 240), new SysCol(SWT.COLOR_WHITE), 6, 1), // GR_BACKGROUND_SEL_NOFOCUS + new RGB(0, 0, 50), // GR_FOREGROUND_SEL_NOFOCUS + + new Mix(new SysCol(SWT.COLOR_GRAY), new SysCol(SWT.COLOR_LIST_BACKGROUND), 1, 3), // LIGHT_LINE + + new Mix(new SysCol(SWT.COLOR_GRAY), new SysCol(SWT.COLOR_LIST_BACKGROUND), 1, 6), // BACKGROUND_NAME + new Mix(new SysCol(SWT.COLOR_GRAY), new RGB(232, 242, 254), 1, 6), // BACKGROUND_NAME_SEL + new Mix(new SysCol(SWT.COLOR_GRAY), new SysCol(SWT.COLOR_WIDGET_BACKGROUND), 1, 6), // BACKGROUND_NAME_SEL_NOFOCUS + }; + + private final Color fColors[]; + + /** + * Default constructor + */ + public TimeGraphColorScheme() { + fColors = new Color[PROVIDERS_MAP.length]; + } + + /** + * Dispose this color scheme + */ + public void dispose() { + for (int i = 0; i < fColors.length; i++) { + Utils.dispose(fColors[i]); + fColors[i] = null; + } + } + + /** + * Get the color matching the given index + * + * @param idx + * The index + * @return The matching color + */ + public Color getColor(int idx) { + if (null == fColors[idx]) { + if (idx >= STATES_SEL0 && idx <= STATES_SEL1) { + Color col1 = getColor(idx - STATES_SEL0); + Color col2 = getColor(BACKGROUND_SEL); + fColors[idx] = Utils.mixColors(col1, col2, 3, 1); + } else { + fColors[idx] = PROVIDERS_MAP[idx].get(); + } + } + return fColors[idx]; + } + + /** + * Get an entry's background color based on its status. + * + * @param selected + * If the entry is selected + * @param focused + * If the entry is focused + * @param name + * Get the color of the name column (false for other columns) + * @return The matching color + */ + public Color getBkColor(boolean selected, boolean focused, boolean name) { + if (name) { + if (selected && focused) { + return getColor(BACKGROUND_NAME_SEL); + } + if (selected) { + return getColor(BACKGROUND_NAME_SEL_NOFOCUS); + } + return getColor(BACKGROUND_NAME); + } + if (selected && focused) { + return getColor(BACKGROUND_SEL); + } + if (selected) { + return getColor(BACKGROUND_SEL_NOFOCUS); + } + return getColor(BACKGROUND); + } + + /** + * Get the correct foreground color + * + * @param selected + * Is the entry selected + * @param focused + * Is the entry focused + * @return The matching color + */ + public Color getFgColor(boolean selected, boolean focused) { + if (selected && focused) { + return getColor(FOREGROUND_SEL); + } + if (selected) { + return getColor(FOREGROUND_SEL_NOFOCUS); + } + return getColor(FOREGROUND); + } + + /** + * Get the correct background color group + * + * @param selected + * Is the entry selected + * @param focused + * Is the entry focused + * @return The matching color + */ + public Color getBkColorGroup(boolean selected, boolean focused) { + if (selected && focused) { + return getColor(GR_BACKGROUND_SEL); + } + if (selected) { + return getColor(GR_BACKGROUND_SEL_NOFOCUS); + } + return getColor(GR_BACKGROUND); + } + + /** + * Get the correct foreground color group + * + * @param selected + * Is the entry selected + * @param focused + * Is the entry focused + * @return The matching color + */ + public Color getFgColorGroup(boolean selected, boolean focused) { + if (selected && focused) { + return getColor(GR_FOREGROUND_SEL); + } + if (selected) { + return getColor(GR_FOREGROUND_SEL_NOFOCUS); + } + return getColor(GR_FOREGROUND); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java new file mode 100644 index 0000000000..fcd300d492 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java @@ -0,0 +1,2799 @@ +/***************************************************************************** + * Copyright (c) 2007, 2014 Intel Corporation and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + * Ruslan A. Scherbakov, Intel - Initial API and implementation + * Alvaro Sanchez-Leon, Ericsson - Updated for TMF + * Patrick Tasse, Ericsson - Refactoring + * Geneviève Bastien, École Polytechnique de Montréal - Move code to + * provide base classes for time graph view + * Add display of links between items + * Xavier Raynaud, Kalray - Code optimization + * Generoso Pagano, Inria - Support for drag selection listeners + *****************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MenuDetectEvent; +import org.eclipse.swt.events.MenuDetectListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.events.MouseWheelListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.TraverseEvent; +import org.eclipse.swt.events.TraverseListener; +import org.eclipse.swt.events.TypedEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.ScrollBar; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphColorListener; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider2; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphTimeListener; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphTreeListener; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.StateItem; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphTimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphTreeExpansionEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.Resolution; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; + +/** + * Time graph control implementation + * + * @version 1.0 + * @author Alvaro Sanchez-Leon + * @author Patrick Tasse + */ +public class TimeGraphControl extends TimeGraphBaseControl + implements FocusListener, KeyListener, MouseMoveListener, MouseListener, MouseWheelListener, + ControlListener, SelectionListener, MouseTrackListener, TraverseListener, ISelectionProvider, + MenuDetectListener, ITmfTimeGraphDrawingHelper, ITimeGraphColorListener { + + /** Max scrollbar size */ + public static final int H_SCROLLBAR_MAX = Integer.MAX_VALUE - 1; + + /** Constant indicating that all levels of the time graph should be expanded + * @since 3.1 */ + public static final int ALL_LEVELS = AbstractTreeViewer.ALL_LEVELS; + + private static final int DRAG_NONE = 0; + private static final int DRAG_TRACE_ITEM = 1; + private static final int DRAG_SPLIT_LINE = 2; + private static final int DRAG_ZOOM = 3; + private static final int DRAG_SELECTION = 4; + + private static final int CUSTOM_ITEM_HEIGHT = -1; // get item height from provider + + private static final double ZOOM_FACTOR = 1.5; + private static final double ZOOM_IN_FACTOR = 0.8; + private static final double ZOOM_OUT_FACTOR = 1.25; + + private static final int SNAP_WIDTH = 2; + private static final int ARROW_HOVER_MAX_DIST = 5; + + private static final int NO_STATUS = -1; + + /** Resource manager */ + private LocalResourceManager fResourceManager = new LocalResourceManager(JFaceResources.getResources()); + + /** Color map for event types */ + private Color[] fEventColorMap = null; + + private ITimeDataProvider fTimeProvider; + private IStatusLineManager fStatusLineManager = null; + private TimeGraphScale fTimeGraphScale = null; + + private boolean fIsInFocus = false; + private boolean fMouseOverSplitLine = false; + private int fGlobalItemHeight = CUSTOM_ITEM_HEIGHT; + private int fMinimumItemWidth = 0; + private int fTopIndex = 0; + private int fDragState = DRAG_NONE; + private int fDragButton; + private int fDragX0 = 0; + private int fDragX = 0; + private long fDragTime0 = 0; // used to preserve accuracy of modified selection + private int fIdealNameSpace = 0; + private long fTime0bak; + private long fTime1bak; + private ITimeGraphPresentationProvider fTimeGraphProvider = null; + private ItemData fItemData = null; + private List fSelectionListeners; + private List fDragSelectionListeners; + private final List fSelectionChangedListeners = new ArrayList<>(); + private final List fTreeListeners = new ArrayList<>(); + private final List fTimeGraphEntryMenuListeners = new ArrayList<>(); + private final List fTimeEventMenuListeners = new ArrayList<>(); + private final Cursor fDragCursor = Display.getDefault().getSystemCursor(SWT.CURSOR_HAND); + private final Cursor fResizeCursor = Display.getDefault().getSystemCursor(SWT.CURSOR_IBEAM); + private final Cursor fWaitCursor = Display.getDefault().getSystemCursor(SWT.CURSOR_WAIT); + private final Cursor fZoomCursor = Display.getDefault().getSystemCursor(SWT.CURSOR_SIZEWE); + private final List fFilters = new ArrayList<>(); + private MenuDetectEvent fPendingMenuDetectEvent = null; + private boolean fHideArrows = false; + private int fAutoExpandLevel = ALL_LEVELS; + + private int fBorderWidth = 0; + private int fHeaderHeight = 0; + + private Listener fMouseScrollFilterListener; + + private MouseScrollNotifier fMouseScrollNotifier; + private final Object fMouseScrollNotifierLock = new Object(); + + private class MouseScrollNotifier extends Thread { + private static final long DELAY = 400L; + private static final long POLLING_INTERVAL = 10L; + private long fLastScrollTime = Long.MAX_VALUE; + + @Override + public void run() { + while ((System.currentTimeMillis() - fLastScrollTime) < DELAY) { + try { + Thread.sleep(POLLING_INTERVAL); + } catch (Exception e) { + return; + } + } + if (!isInterrupted()) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (isDisposed()) { + return; + } + fTimeProvider.notifyStartFinishTime(); + } + }); + } + synchronized (fMouseScrollNotifierLock) { + fMouseScrollNotifier = null; + } + } + + public void mouseScrolled() { + fLastScrollTime = System.currentTimeMillis(); + } + } + + /** + * Standard constructor + * + * @param parent + * The parent composite object + * @param colors + * The color scheme to use + */ + public TimeGraphControl(Composite parent, TimeGraphColorScheme colors) { + + super(parent, colors, SWT.NO_BACKGROUND | SWT.H_SCROLL | SWT.DOUBLE_BUFFERED); + + fItemData = new ItemData(); + + addFocusListener(this); + addMouseListener(this); + addMouseMoveListener(this); + addMouseTrackListener(this); + addMouseWheelListener(this); + addTraverseListener(this); + addKeyListener(this); + addControlListener(this); + addMenuDetectListener(this); + ScrollBar scrollHor = getHorizontalBar(); + + if (scrollHor != null) { + scrollHor.addSelectionListener(this); + } + } + + @Override + public void dispose() { + super.dispose(); + fResourceManager.dispose(); + } + + /** + * Sets the timegraph provider used by this timegraph viewer. + * + * @param timeGraphProvider the timegraph provider + */ + public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider) { + fTimeGraphProvider = timeGraphProvider; + + if (timeGraphProvider instanceof ITimeGraphPresentationProvider2) { + ((ITimeGraphPresentationProvider2) timeGraphProvider).setDrawingHelper(this); + ((ITimeGraphPresentationProvider2) timeGraphProvider).addColorListener(this); + } + + StateItem[] stateItems = fTimeGraphProvider.getStateTable(); + colorSettingsChanged(stateItems); + } + + /** + * Gets the timegraph provider used by this timegraph viewer. + * + * @return the timegraph provider, or null if not set. + * @since 3.0 + */ + public ITimeGraphPresentationProvider getTimeGraphProvider() { + return fTimeGraphProvider; + } + + /** + * Gets the color map used by this timegraph viewer. + * + * @return a color map, or null if not set. + * @since 3.0 + */ + public Color[] getEventColorMap() { + return fEventColorMap; + } + + /** + * Assign the given time provider + * + * @param timeProvider + * The time provider + */ + public void setTimeProvider(ITimeDataProvider timeProvider) { + fTimeProvider = timeProvider; + adjustScrolls(); + redraw(); + } + + /** + * Assign the status line manager + * + * @param statusLineManager + * The status line manager, or null to disable status line messages + * @since 2.1 + */ + public void setStatusLineManager(IStatusLineManager statusLineManager) { + if (fStatusLineManager != null && statusLineManager == null) { + fStatusLineManager.setMessage(""); //$NON-NLS-1$ + } + fStatusLineManager = statusLineManager; + } + + /** + * Assign the time graph scale + * + * @param timeGraphScale + * The time graph scale + * @since 2.1 + */ + public void setTimeGraphScale(TimeGraphScale timeGraphScale) { + fTimeGraphScale = timeGraphScale; + } + + /** + * Add a selection listener + * + * @param listener + * The listener to add + */ + public void addSelectionListener(SelectionListener listener) { + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (null == fSelectionListeners) { + fSelectionListeners = new ArrayList<>(); + } + fSelectionListeners.add(listener); + } + + /** + * Remove a selection listener + * + * @param listener + * The listener to remove + */ + public void removeSelectionListener(SelectionListener listener) { + if (null != fSelectionListeners) { + fSelectionListeners.remove(listener); + } + } + + /** + * Selection changed callback + */ + public void fireSelectionChanged() { + if (null != fSelectionListeners) { + Iterator it = fSelectionListeners.iterator(); + while (it.hasNext()) { + SelectionListener listener = it.next(); + listener.widgetSelected(null); + } + } + } + + /** + * Default selection callback + */ + public void fireDefaultSelection() { + if (null != fSelectionListeners) { + Iterator it = fSelectionListeners.iterator(); + while (it.hasNext()) { + SelectionListener listener = it.next(); + listener.widgetDefaultSelected(null); + } + } + } + + /** + * Add a drag selection listener + * + * @param listener + * The listener to add + * @since 3.1 + */ + public void addDragSelectionListener(ITimeGraphTimeListener listener) { + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (null == fDragSelectionListeners) { + fDragSelectionListeners = new ArrayList<>(); + } + fDragSelectionListeners.add(listener); + } + + /** + * Remove a drag selection listener + * + * @param listener + * The listener to remove + * @since 3.1 + */ + public void removeDragSelectionListener(ITimeGraphTimeListener listener) { + if (null != fDragSelectionListeners) { + fDragSelectionListeners.remove(listener); + } + } + + /** + * Drag Selection changed callback + * + * @param start + * Time interval start + * @param end + * Time interval end + * @since 3.1 + */ + public void fireDragSelectionChanged(long start, long end) { + // check for backward intervals + long beginTime, endTime; + if (start > end) { + beginTime = end; + endTime = start; + } else { + beginTime = start; + endTime = end; + } + // call the listeners + if (null != fDragSelectionListeners) { + Iterator it = fDragSelectionListeners.iterator(); + while (it.hasNext()) { + ITimeGraphTimeListener listener = it.next(); + listener.timeSelected(new TimeGraphTimeEvent(this, beginTime, endTime)); + } + } + } + + /** + * Get the traces in the model + * + * @return The array of traces + */ + public ITimeGraphEntry[] getTraces() { + return fItemData.getEntries(); + } + + /** + * Get the on/off trace filters + * + * @return The array of filters + */ + public boolean[] getTraceFilter() { + return fItemData.getEntryFilter(); + } + + /** + * Refresh the data for the thing + */ + public void refreshData() { + fItemData.refreshData(); + adjustScrolls(); + redraw(); + } + + /** + * Refresh data for the given traces + * + * @param traces + * The traces to refresh + */ + public void refreshData(ITimeGraphEntry[] traces) { + fItemData.refreshData(traces); + adjustScrolls(); + redraw(); + } + + /** + * Refresh the links (arrows) of this widget + * + * @param events The link events to refresh + * @since 2.1 + */ + public void refreshArrows(List events) { + fItemData.refreshArrows(events); + } + + /** + * Adjust the scoll bars + */ + public void adjustScrolls() { + if (null == fTimeProvider) { + getHorizontalBar().setValues(0, 1, 1, 1, 1, 1); + return; + } + + // HORIZONTAL BAR + // Visible window + long time0 = fTimeProvider.getTime0(); + long time1 = fTimeProvider.getTime1(); + // Time boundaries + long timeMin = fTimeProvider.getMinTime(); + long timeMax = fTimeProvider.getMaxTime(); + + long delta = timeMax - timeMin; + + int timePos = 0; + int thumb = H_SCROLLBAR_MAX; + + if (delta != 0) { + // Thumb size (page size) + thumb = Math.max(1, (int) (H_SCROLLBAR_MAX * ((double) (time1 - time0) / delta))); + // At the beginning of visible window + timePos = (int) (H_SCROLLBAR_MAX * ((double) (time0 - timeMin) / delta)); + } + + // position, minimum, maximum, thumb size, increment (half page)t, page + // increment size (full page) + getHorizontalBar().setValues(timePos, 0, H_SCROLLBAR_MAX, thumb, Math.max(1, thumb / 2), Math.max(2, thumb)); + } + + boolean ensureVisibleItem(int idx, boolean redraw) { + boolean changed = false; + int index = idx; + if (index < 0) { + for (index = 0; index < fItemData.fExpandedItems.length; index++) { + if (fItemData.fExpandedItems[index].fSelected) { + break; + } + } + } + if (index >= fItemData.fExpandedItems.length) { + return changed; + } + if (index < fTopIndex) { + setTopIndex(index); + if (redraw) { + redraw(); + } + changed = true; + } else { + int page = countPerPage(); + if (index >= fTopIndex + page) { + setTopIndex(index - page + 1); + if (redraw) { + redraw(); + } + changed = true; + } + } + return changed; + } + + /** + * Assign the given index as the top one + * + * @param idx + * The index + */ + public void setTopIndex(int idx) { + int index = Math.min(idx, fItemData.fExpandedItems.length - countPerPage()); + index = Math.max(0, index); + fTopIndex = index; + redraw(); + } + + /** + * Sets the auto-expand level to be used when the entries are refreshed + * using {@link #refreshData()} or {@link #refreshData(ITimeGraphEntry[])}. + * The value 0 means that there is no auto-expand; 1 means that top-level + * entries are expanded, but not their children; 2 means that top-level + * entries are expanded, and their children, but not grand-children; and so + * on. + *

    + * The value {@link #ALL_LEVELS} means that all subtrees should be expanded. + *

    + * @param level + * non-negative level, or ALL_LEVELS to expand all + * levels of the tree + * @since 3.1 + */ + public void setAutoExpandLevel(int level) { + fAutoExpandLevel = level; + } + + /** + * Returns the auto-expand level. + * + * @return non-negative level, or ALL_LEVELS if all levels of + * the tree are expanded automatically + * @see #setAutoExpandLevel + * @since 3.1 + */ + public int getAutoExpandLevel() { + return fAutoExpandLevel; + } + + /** + * Set the expanded state of a given entry + * + * @param entry + * The entry + * @param expanded + * True if expanded, false if collapsed + */ + public void setExpandedState(ITimeGraphEntry entry, boolean expanded) { + Item item = fItemData.findItem(entry); + if (item != null && item.fExpanded != expanded) { + item.fExpanded = expanded; + fItemData.updateExpandedItems(); + redraw(); + } + } + + /** + * Collapses all nodes of the viewer's tree, starting with the root. + * + * @since 2.0 + */ + public void collapseAll() { + for (Item item : fItemData.fItems) { + item.fExpanded = false; + } + fItemData.updateExpandedItems(); + redraw(); + } + + /** + * Expands all nodes of the viewer's tree, starting with the root. + * + * @since 2.0 + */ + public void expandAll() { + for (Item item : fItemData.fItems) { + item.fExpanded = true; + } + fItemData.updateExpandedItems(); + redraw(); + } + + /** + * Add a tree listener + * + * @param listener + * The listener to add + */ + public void addTreeListener(ITimeGraphTreeListener listener) { + if (!fTreeListeners.contains(listener)) { + fTreeListeners.add(listener); + } + } + + /** + * Remove a tree listener + * + * @param listener + * The listener to remove + */ + public void removeTreeListener(ITimeGraphTreeListener listener) { + if (fTreeListeners.contains(listener)) { + fTreeListeners.remove(listener); + } + } + + /** + * Tree event callback + * + * @param entry + * The affected entry + * @param expanded + * The expanded state (true for expanded, false for collapsed) + */ + public void fireTreeEvent(ITimeGraphEntry entry, boolean expanded) { + TimeGraphTreeExpansionEvent event = new TimeGraphTreeExpansionEvent(this, entry); + for (ITimeGraphTreeListener listener : fTreeListeners) { + if (expanded) { + listener.treeExpanded(event); + } else { + listener.treeCollapsed(event); + } + } + } + + /** + * Add a menu listener on {@link ITimeGraphEntry}s + * @param listener + * The listener to add + * @since 1.2 + */ + public void addTimeGraphEntryMenuListener(MenuDetectListener listener) { + if (!fTimeGraphEntryMenuListeners.contains(listener)) { + fTimeGraphEntryMenuListeners.add(listener); + } + } + + /** + * Remove a menu listener on {@link ITimeGraphEntry}s + * + * @param listener + * The listener to remove + * @since 1.2 + */ + public void removeTimeGraphEntryMenuListener(MenuDetectListener listener) { + if (fTimeGraphEntryMenuListeners.contains(listener)) { + fTimeGraphEntryMenuListeners.remove(listener); + } + } + + /** + * Menu event callback on {@link ITimeGraphEntry}s + * + * @param event + * The MenuDetectEvent, with field {@link TypedEvent#data} set to the selected {@link ITimeGraphEntry} + */ + private void fireMenuEventOnTimeGraphEntry(MenuDetectEvent event) { + for (MenuDetectListener listener : fTimeGraphEntryMenuListeners) { + listener.menuDetected(event); + } + } + + /** + * Add a menu listener on {@link ITimeEvent}s + * + * @param listener + * The listener to add + * @since 1.2 + */ + public void addTimeEventMenuListener(MenuDetectListener listener) { + if (!fTimeEventMenuListeners.contains(listener)) { + fTimeEventMenuListeners.add(listener); + } + } + + /** + * Remove a menu listener on {@link ITimeEvent}s + * + * @param listener + * The listener to remove + * @since 1.2 + */ + public void removeTimeEventMenuListener(MenuDetectListener listener) { + if (fTimeEventMenuListeners.contains(listener)) { + fTimeEventMenuListeners.remove(listener); + } + } + + /** + * Menu event callback on {@link ITimeEvent}s + * + * @param event + * The MenuDetectEvent, with field {@link TypedEvent#data} set to the selected {@link ITimeEvent} + */ + private void fireMenuEventOnTimeEvent(MenuDetectEvent event) { + for (MenuDetectListener listener : fTimeEventMenuListeners) { + listener.menuDetected(event); + } + } + + @Override + public ISelection getSelection() { + TimeGraphSelection sel = new TimeGraphSelection(); + ITimeGraphEntry trace = getSelectedTrace(); + if (null != trace && null != fTimeProvider) { + long selectedTime = fTimeProvider.getSelectionBegin(); + ITimeEvent event = Utils.findEvent(trace, selectedTime, 0); + if (event != null) { + sel.add(event); + } else { + sel.add(trace); + } + } + return sel; + } + + /** + * Get the selection object + * + * @return The selection + */ + public ISelection getSelectionTrace() { + TimeGraphSelection sel = new TimeGraphSelection(); + ITimeGraphEntry trace = getSelectedTrace(); + if (null != trace) { + sel.add(trace); + } + return sel; + } + + /** + * Enable/disable one of the traces in the model + * + * @param n + * 1 to enable it, -1 to disable. The method returns immediately + * if another value is used. + */ + public void selectTrace(int n) { + if ((n != 1) && (n != -1)) { + return; + } + + boolean changed = false; + int lastSelection = -1; + for (int i = 0; i < fItemData.fExpandedItems.length; i++) { + Item item = fItemData.fExpandedItems[i]; + if (item.fSelected) { + lastSelection = i; + if ((1 == n) && (i < fItemData.fExpandedItems.length - 1)) { + item.fSelected = false; + item = fItemData.fExpandedItems[i + 1]; + item.fSelected = true; + changed = true; + } else if ((-1 == n) && (i > 0)) { + item.fSelected = false; + item = fItemData.fExpandedItems[i - 1]; + item.fSelected = true; + changed = true; + } + break; + } + } + + if (lastSelection < 0 && fItemData.fExpandedItems.length > 0) { + Item item = fItemData.fExpandedItems[0]; + item.fSelected = true; + changed = true; + } + + if (changed) { + ensureVisibleItem(-1, false); + redraw(); + fireSelectionChanged(); + } + } + + /** + * Select an event + * + * @param n + * 1 for next event, -1 for previous event + */ + public void selectEvent(int n) { + if (null == fTimeProvider) { + return; + } + ITimeGraphEntry trace = getSelectedTrace(); + if (trace == null) { + return; + } + long selectedTime = fTimeProvider.getSelectionBegin(); + long endTime = fTimeProvider.getEndTime(); + ITimeEvent nextEvent; + if (-1 == n && selectedTime > endTime) { + nextEvent = Utils.findEvent(trace, selectedTime, 0); + } else { + nextEvent = Utils.findEvent(trace, selectedTime, n); + } + if (null == nextEvent && -1 == n) { + nextEvent = Utils.getFirstEvent(trace); + } + if (null != nextEvent) { + long nextTime = nextEvent.getTime(); + // If last event detected e.g. going back or not moving to a next + // event + if (nextTime <= selectedTime && n == 1) { + // Select to the end of this last event + nextTime = nextEvent.getTime() + nextEvent.getDuration(); + // but not beyond the end of the trace + if (nextTime > endTime) { + nextTime = endTime; + } + } else if (n == -1 && nextEvent.getTime() + nextEvent.getDuration() < selectedTime) { + // for previous event go to its end time unless we were already there + nextTime = nextEvent.getTime() + nextEvent.getDuration(); + } + fTimeProvider.setSelectedTimeNotify(nextTime, true); + fireSelectionChanged(); + } else if (1 == n) { + fTimeProvider.setSelectedTimeNotify(endTime, true); + fireSelectionChanged(); + } + } + + /** + * Select the next event + */ + public void selectNextEvent() { + selectEvent(1); + // Notify if visible time window has been adjusted + fTimeProvider.setStartFinishTimeNotify(fTimeProvider.getTime0(), fTimeProvider.getTime1()); + } + + /** + * Select the previous event + */ + public void selectPrevEvent() { + selectEvent(-1); + // Notify if visible time window has been adjusted + fTimeProvider.setStartFinishTimeNotify(fTimeProvider.getTime0(), fTimeProvider.getTime1()); + } + + /** + * Select the next trace + */ + public void selectNextTrace() { + selectTrace(1); + } + + /** + * Select the previous trace + */ + public void selectPrevTrace() { + selectTrace(-1); + } + + /** + * Zoom based on mouse cursor location with mouse scrolling + * + * @param zoomIn true to zoom in, false to zoom out + */ + public void zoom(boolean zoomIn) { + int globalX = getDisplay().getCursorLocation().x; + Point p = toControl(globalX, 0); + int nameSpace = fTimeProvider.getNameSpace(); + int timeSpace = fTimeProvider.getTimeSpace(); + int xPos = Math.max(nameSpace, Math.min(nameSpace + timeSpace, p.x)); + long time0 = fTimeProvider.getTime0(); + long time1 = fTimeProvider.getTime1(); + long interval = time1 - time0; + if (interval == 0) { + interval = 1; + } // to allow getting out of single point interval + long newInterval; + if (zoomIn) { + newInterval = Math.max(Math.round(interval * ZOOM_IN_FACTOR), fTimeProvider.getMinTimeInterval()); + } else { + newInterval = (long) Math.ceil(interval * ZOOM_OUT_FACTOR); + } + long center = time0 + Math.round(((double) (xPos - nameSpace) / timeSpace * interval)); + long newTime0 = center - Math.round((double) newInterval * (center - time0) / interval); + long newTime1 = newTime0 + newInterval; + fTimeProvider.setStartFinishTime(newTime0, newTime1); + synchronized (fMouseScrollNotifierLock) { + if (fMouseScrollNotifier == null) { + fMouseScrollNotifier = new MouseScrollNotifier(); + fMouseScrollNotifier.start(); + } + fMouseScrollNotifier.mouseScrolled(); + } + } + + /** + * zoom in using single click + */ + public void zoomIn() { + long prevTime0 = fTimeProvider.getTime0(); + long prevTime1 = fTimeProvider.getTime1(); + long prevRange = prevTime1 - prevTime0; + if (prevRange == 0) { + return; + } + ITimeDataProvider provider = fTimeProvider; + long selTime = (provider.getSelectionEnd() + provider.getSelectionBegin()) / 2; + if (selTime <= prevTime0 || selTime >= prevTime1) { + selTime = (prevTime0 + prevTime1) / 2; + } + long time0 = selTime - (long) ((selTime - prevTime0) / ZOOM_FACTOR); + long time1 = selTime + (long) ((prevTime1 - selTime) / ZOOM_FACTOR); + + long inaccuracy = (fTimeProvider.getMaxTime() - fTimeProvider.getMinTime()) - (time1 - time0); + + if (inaccuracy > 0 && inaccuracy < 100) { + fTimeProvider.setStartFinishTimeNotify(fTimeProvider.getMinTime(), fTimeProvider.getMaxTime()); + return; + } + + long min = fTimeProvider.getMinTimeInterval(); + if ((time1 - time0) < min) { + time0 = selTime - (selTime - prevTime0) * min / prevRange; + time1 = time0 + min; + } + + fTimeProvider.setStartFinishTimeNotify(time0, time1); + } + + /** + * zoom out using single click + */ + public void zoomOut() { + long prevTime0 = fTimeProvider.getTime0(); + long prevTime1 = fTimeProvider.getTime1(); + ITimeDataProvider provider = fTimeProvider; + long selTime = (provider.getSelectionEnd() + provider.getSelectionBegin()) / 2; + if (selTime <= prevTime0 || selTime >= prevTime1) { + selTime = (prevTime0 + prevTime1) / 2; + } + long time0 = (long) (selTime - (selTime - prevTime0) * ZOOM_FACTOR); + long time1 = (long) (selTime + (prevTime1 - selTime) * ZOOM_FACTOR); + + long inaccuracy = (fTimeProvider.getMaxTime() - fTimeProvider.getMinTime()) - (time1 - time0); + if (inaccuracy > 0 && inaccuracy < 100) { + fTimeProvider.setStartFinishTimeNotify(fTimeProvider.getMinTime(), fTimeProvider.getMaxTime()); + return; + } + + fTimeProvider.setStartFinishTimeNotify(time0, time1); + } + + /** + * Hide arrows + * + * @param hideArrows true to hide arrows + * + * @since 2.1 + */ + public void hideArrows(boolean hideArrows) { + fHideArrows = hideArrows; + } + + /** + * Follow the arrow forward + * + * @since 2.1 + */ + public void followArrowFwd() { + ITimeGraphEntry trace = getSelectedTrace(); + if (trace == null) { + return; + } + long selectedTime = fTimeProvider.getSelectionBegin(); + for (ILinkEvent link : fItemData.fLinks) { + if (link.getEntry() == trace && link.getTime() == selectedTime) { + selectItem(link.getDestinationEntry(), false); + if (link.getDuration() != 0) { + fTimeProvider.setSelectedTimeNotify(link.getTime() + link.getDuration(), true); + // Notify if visible time window has been adjusted + fTimeProvider.setStartFinishTimeNotify(fTimeProvider.getTime0(), fTimeProvider.getTime1()); + } + fireSelectionChanged(); + return; + } + } + selectNextEvent(); + } + + /** + * Follow the arrow backward + * + * @since 2.1 + */ + public void followArrowBwd() { + ITimeGraphEntry trace = getSelectedTrace(); + if (trace == null) { + return; + } + long selectedTime = fTimeProvider.getSelectionBegin(); + for (ILinkEvent link : fItemData.fLinks) { + if (link.getDestinationEntry() == trace && link.getTime() + link.getDuration() == selectedTime) { + selectItem(link.getEntry(), false); + if (link.getDuration() != 0) { + fTimeProvider.setSelectedTimeNotify(link.getTime(), true); + // Notify if visible time window has been adjusted + fTimeProvider.setStartFinishTimeNotify(fTimeProvider.getTime0(), fTimeProvider.getTime1()); + } + fireSelectionChanged(); + return; + } + } + selectPrevEvent(); + } + + /** + * Return the currently selected trace + * + * @return The entry matching the trace + */ + public ITimeGraphEntry getSelectedTrace() { + ITimeGraphEntry trace = null; + int idx = getSelectedIndex(); + if (idx >= 0) { + trace = fItemData.fExpandedItems[idx].fEntry; + } + return trace; + } + + /** + * Retrieve the index of the currently selected item + * + * @return The index + */ + public int getSelectedIndex() { + int idx = -1; + for (int i = 0; i < fItemData.fExpandedItems.length; i++) { + Item item = fItemData.fExpandedItems[i]; + if (item.fSelected) { + idx = i; + break; + } + } + return idx; + } + + boolean toggle(int idx) { + boolean toggled = false; + if (idx >= 0 && idx < fItemData.fExpandedItems.length) { + Item item = fItemData.fExpandedItems[idx]; + if (item.fHasChildren) { + item.fExpanded = !item.fExpanded; + fItemData.updateExpandedItems(); + adjustScrolls(); + redraw(); + toggled = true; + fireTreeEvent(item.fEntry, item.fExpanded); + } + } + return toggled; + } + + /** + * Gets the index of the item at the given location. + * + * @param y + * the y coordinate + * @return the index of the item at the given location, of -1 if none. + * @since 3.0 + */ + protected int getItemIndexAtY(int y) { + if (y < 0) { + return -1; + } + int ySum = 0; + for (int idx = fTopIndex; idx < fItemData.fExpandedItems.length; idx++) { + ySum += fItemData.fExpandedItems[idx].fItemHeight; + if (y < ySum) { + return idx; + } + } + return -1; + } + + boolean isOverSplitLine(int x) { + if (x < 0 || null == fTimeProvider) { + return false; + } + int nameWidth = fTimeProvider.getNameSpace(); + return Math.abs(x - nameWidth) < SNAP_WIDTH; + } + + /** + * Gets the {@link ITimeGraphEntry} at the given location. + * + * @param pt + * a point in the widget + * @return the {@link ITimeGraphEntry} at this point, or null + * if none. + * @since 3.0 + */ + protected ITimeGraphEntry getEntry(Point pt) { + int idx = getItemIndexAtY(pt.y); + return idx >= 0 ? fItemData.fExpandedItems[idx].fEntry : null; + } + + /** + * Return the arrow event closest to the given point that is no further than + * a maximum distance. + * + * @param pt + * a point in the widget + * @return The closest arrow event, or null if there is none close enough. + * @since 3.2 + */ + protected ILinkEvent getArrow(Point pt) { + if (fHideArrows) { + return null; + } + ILinkEvent linkEvent = null; + double minDistance = Double.MAX_VALUE; + for (ILinkEvent event : fItemData.fLinks) { + Rectangle rect = getArrowRectangle(new Rectangle(0, 0, 0, 0), event); + if (rect != null) { + int x1 = rect.x; + int y1 = rect.y; + int x2 = x1 + rect.width; + int y2 = y1 + rect.height; + double d = Utils.distance(pt.x, pt.y, x1, y1, x2, y2); + if (minDistance > d) { + minDistance = d; + linkEvent = event; + } + } + } + if (minDistance <= ARROW_HOVER_MAX_DIST) { + return linkEvent; + } + return null; + } + + /** + * @since 2.0 + */ + @Override + public int getXForTime(long time) { + if (null == fTimeProvider) { + return -1; + } + long time0 = fTimeProvider.getTime0(); + long time1 = fTimeProvider.getTime1(); + int width = getCtrlSize().x; + int nameSpace = fTimeProvider.getNameSpace(); + double pixelsPerNanoSec = (width - nameSpace <= RIGHT_MARGIN) ? 0 : (double) (width - nameSpace - RIGHT_MARGIN) / (time1 - time0); + int x = getBounds().x + nameSpace + (int) ((time - time0) * pixelsPerNanoSec); + return x; + } + + /** + * @since 2.0 + */ + @Override + public long getTimeAtX(int coord) { + if (null == fTimeProvider) { + return -1; + } + long hitTime = -1; + Point size = getCtrlSize(); + long time0 = fTimeProvider.getTime0(); + long time1 = fTimeProvider.getTime1(); + int nameWidth = fTimeProvider.getNameSpace(); + final int x = coord - nameWidth; + int timeWidth = size.x - nameWidth - RIGHT_MARGIN; + if (x >= 0 && size.x >= nameWidth) { + if (time1 - time0 > timeWidth) { + // nanosecond smaller than one pixel: use the first integer nanosecond of this pixel's time range + hitTime = time0 + (long) Math.ceil((time1 - time0) * ((double) x / timeWidth)); + } else { + // nanosecond greater than one pixel: use the nanosecond that covers this pixel start position + hitTime = time0 + (long) Math.floor((time1 - time0) * ((double) x / timeWidth)); + } + } + return hitTime; + } + + void selectItem(int idx, boolean addSelection) { + boolean changed = false; + if (addSelection) { + if (idx >= 0 && idx < fItemData.fExpandedItems.length) { + Item item = fItemData.fExpandedItems[idx]; + changed = !item.fSelected; + item.fSelected = true; + } + } else { + for (int i = 0; i < fItemData.fExpandedItems.length; i++) { + Item item = fItemData.fExpandedItems[i]; + if ((i == idx && !item.fSelected) || (idx == -1 && item.fSelected)) { + changed = true; + } + item.fSelected = i == idx; + } + } + changed |= ensureVisibleItem(idx, true); + if (changed) { + redraw(); + } + } + + /** + * Callback for item selection + * + * @param trace + * The entry matching the trace + * @param addSelection + * If the selection is added or removed + */ + public void selectItem(ITimeGraphEntry trace, boolean addSelection) { + int idx = fItemData.findItemIndex(trace); + selectItem(idx, addSelection); + } + + /** + * Retrieve the number of entries shown per page. + * + * @return The count + */ + public int countPerPage() { + int height = getCtrlSize().y; + int count = 0; + int ySum = 0; + for (int idx = fTopIndex; idx < fItemData.fExpandedItems.length; idx++) { + ySum += fItemData.fExpandedItems[idx].fItemHeight; + if (ySum >= height) { + return count; + } + count++; + } + for (int idx = fTopIndex - 1; idx >= 0; idx--) { + ySum += fItemData.fExpandedItems[idx].fItemHeight; + if (ySum >= height) { + return count; + } + count++; + } + return count; + } + + /** + * Get the index of the top element + * + * @return The index + */ + public int getTopIndex() { + return fTopIndex; + } + + /** + * Get the number of expanded items + * + * @return The count of expanded items + */ + public int getExpandedElementCount() { + return fItemData.fExpandedItems.length; + } + + /** + * Get an array of all expanded elements + * + * @return The expanded elements + */ + public ITimeGraphEntry[] getExpandedElements() { + ArrayList elements = new ArrayList<>(); + for (Item item : fItemData.fExpandedItems) { + elements.add(item.fEntry); + } + return elements.toArray(new ITimeGraphEntry[0]); + } + + Point getCtrlSize() { + Point size = getSize(); + if (getHorizontalBar().isVisible()) { + size.y -= getHorizontalBar().getSize().y; + } + return size; + } + + Rectangle getNameRect(Rectangle bound, int idx, int nameWidth) { + Rectangle rect = getStatesRect(bound, idx, nameWidth); + rect.x = bound.x; + rect.width = nameWidth; + return rect; + } + + Rectangle getStatesRect(Rectangle bound, int idx, int nameWidth) { + int x = bound.x + nameWidth; + int width = bound.width - x; + int ySum = 0; + if (idx >= fTopIndex) { + for (int i = fTopIndex; i < idx; i++) { + ySum += fItemData.fExpandedItems[i].fItemHeight; + } + } else { + for (int i = fTopIndex - 1; i >= idx; i--) { + ySum -= fItemData.fExpandedItems[i].fItemHeight; + } + } + int y = bound.y + ySum; + int height = fItemData.fExpandedItems[idx].fItemHeight; + return new Rectangle(x, y, width, height); + } + + @Override + void paint(Rectangle bounds, PaintEvent e) { + GC gc = e.gc; + gc.setBackground(getColorScheme().getColor(TimeGraphColorScheme.BACKGROUND)); + drawBackground(gc, bounds.x, bounds.y, bounds.width, bounds.height); + + if (bounds.width < 2 || bounds.height < 2 || null == fTimeProvider) { + return; + } + + fIdealNameSpace = 0; + int nameSpace = fTimeProvider.getNameSpace(); + + // draw empty name space background + gc.setBackground(getColorScheme().getBkColor(false, false, true)); + drawBackground(gc, bounds.x, bounds.y, nameSpace, bounds.height); + + // draw items + drawItems(bounds, fTimeProvider, fItemData.fExpandedItems, fTopIndex, nameSpace, gc); + drawLinks(bounds, fTimeProvider, fItemData.fLinks, nameSpace, gc); + fTimeGraphProvider.postDrawControl(bounds, gc); + + int alpha = gc.getAlpha(); + gc.setAlpha(100); + + long time0 = fTimeProvider.getTime0(); + long time1 = fTimeProvider.getTime1(); + long selectionBegin = fTimeProvider.getSelectionBegin(); + long selectionEnd = fTimeProvider.getSelectionEnd(); + double pixelsPerNanoSec = (bounds.width - nameSpace <= RIGHT_MARGIN) ? 0 : (double) (bounds.width - nameSpace - RIGHT_MARGIN) / (time1 - time0); + int x0 = bounds.x + nameSpace + (int) ((selectionBegin - time0) * pixelsPerNanoSec); + int x1 = bounds.x + nameSpace + (int) ((selectionEnd - time0) * pixelsPerNanoSec); + + // draw selection lines + if (fDragState != DRAG_SELECTION) { + gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.SELECTED_TIME)); + if (x0 >= nameSpace && x0 < bounds.x + bounds.width) { + gc.drawLine(x0, bounds.y, x0, bounds.y + bounds.height); + } + if (x1 != x0) { + if (x1 >= nameSpace && x1 < bounds.x + bounds.width) { + gc.drawLine(x1, bounds.y, x1, bounds.y + bounds.height); + } + } + } + + // draw selection background + if (selectionBegin != 0 && selectionEnd != 0 && fDragState != DRAG_SELECTION) { + x0 = Math.max(nameSpace, Math.min(bounds.x + bounds.width, x0)); + x1 = Math.max(nameSpace, Math.min(bounds.x + bounds.width, x1)); + gc.setBackground(getColorScheme().getBkColor(false, false, true)); + if (x1 - x0 > 1) { + gc.fillRectangle(new Rectangle(x0 + 1, bounds.y, x1 - x0 - 1, bounds.height)); + } else if (x0 - x1 > 1) { + gc.fillRectangle(new Rectangle(x1 + 1, bounds.y, x0 - x1 - 1, bounds.height)); + } + } + + // draw drag selection background + if (fDragState == DRAG_ZOOM || fDragState == DRAG_SELECTION) { + gc.setBackground(getColorScheme().getBkColor(false, false, true)); + if (fDragX0 < fDragX) { + gc.fillRectangle(new Rectangle(fDragX0, bounds.y, fDragX - fDragX0, bounds.height)); + } else if (fDragX0 > fDragX) { + gc.fillRectangle(new Rectangle(fDragX, bounds.y, fDragX0 - fDragX, bounds.height)); + } + } + + // draw drag line + if (DRAG_SPLIT_LINE == fDragState) { + gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.BLACK)); + gc.drawLine(bounds.x + nameSpace, bounds.y, bounds.x + nameSpace, bounds.y + bounds.height - 1); + } else if (DRAG_ZOOM == fDragState && Math.max(fDragX, fDragX0) > nameSpace) { + gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.TOOL_FOREGROUND)); + gc.drawLine(fDragX0, bounds.y, fDragX0, bounds.y + bounds.height - 1); + if (fDragX != fDragX0) { + gc.drawLine(fDragX, bounds.y, fDragX, bounds.y + bounds.height - 1); + } + } else if (DRAG_SELECTION == fDragState && Math.max(fDragX, fDragX0) > nameSpace) { + gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.SELECTED_TIME)); + gc.drawLine(fDragX0, bounds.y, fDragX0, bounds.y + bounds.height - 1); + if (fDragX != fDragX0) { + gc.drawLine(fDragX, bounds.y, fDragX, bounds.y + bounds.height - 1); + } + } else if (DRAG_NONE == fDragState && fMouseOverSplitLine && fTimeProvider.getNameSpace() > 0) { + gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.RED)); + gc.drawLine(bounds.x + nameSpace, bounds.y, bounds.x + nameSpace, bounds.y + bounds.height - 1); + } + + gc.setAlpha(alpha); + } + + /** + * Draw many items at once + * + * @param bounds + * The rectangle of the area + * @param timeProvider + * The time provider + * @param items + * The array items to draw + * @param topIndex + * The index of the first element to draw + * @param nameSpace + * The width reserved for the names + * @param gc + * Reference to the SWT GC object + */ + public void drawItems(Rectangle bounds, ITimeDataProvider timeProvider, + Item[] items, int topIndex, int nameSpace, GC gc) { + for (int i = topIndex; i < items.length; i++) { + Item item = items[i]; + drawItem(item, bounds, timeProvider, i, nameSpace, gc); + } + } + + /** + * Draws the item + * + * @param item the item to draw + * @param bounds the container rectangle + * @param timeProvider Time provider + * @param i the item index + * @param nameSpace the name space + * @param gc Graphics context + */ + protected void drawItem(Item item, Rectangle bounds, ITimeDataProvider timeProvider, int i, int nameSpace, GC gc) { + ITimeGraphEntry entry = item.fEntry; + long time0 = timeProvider.getTime0(); + long time1 = timeProvider.getTime1(); + long selectedTime = fTimeProvider.getSelectionBegin(); + + Rectangle nameRect = getNameRect(bounds, i, nameSpace); + if (nameRect.y >= bounds.y + bounds.height) { + return; + } + + if (! item.fEntry.hasTimeEvents()) { + Rectangle statesRect = getStatesRect(bounds, i, nameSpace); + nameRect.width += statesRect.width; + drawName(item, nameRect, gc); + } else { + drawName(item, nameRect, gc); + } + Rectangle rect = getStatesRect(bounds, i, nameSpace); + if (rect.isEmpty()) { + fTimeGraphProvider.postDrawEntry(entry, rect, gc); + return; + } + if (time1 <= time0) { + gc.setBackground(getColorScheme().getBkColor(false, false, false)); + gc.fillRectangle(rect); + fTimeGraphProvider.postDrawEntry(entry, rect, gc); + return; + } + + // Initialize _rect1 to same values as enclosing rectangle rect + Rectangle stateRect = Utils.clone(rect); + boolean selected = item.fSelected; + // K pixels per second + double pixelsPerNanoSec = (rect.width <= RIGHT_MARGIN) ? 0 : (double) (rect.width - RIGHT_MARGIN) / (time1 - time0); + + if (item.fEntry.hasTimeEvents()) { + gc.setClipping(new Rectangle(nameSpace, 0, bounds.width - nameSpace, bounds.height)); + fillSpace(rect, gc, selected); + // Drawing rectangle is smaller than reserved space + stateRect.y += 3; + stateRect.height -= 6; + + long maxDuration = (timeProvider.getTimeSpace() == 0) ? Long.MAX_VALUE : 1 * (time1 - time0) / timeProvider.getTimeSpace(); + Iterator iterator = entry.getTimeEventsIterator(time0, time1, maxDuration); + + int lastX = -1; + while (iterator.hasNext()) { + ITimeEvent event = iterator.next(); + int x = rect.x + (int) ((event.getTime() - time0) * pixelsPerNanoSec); + int xEnd = rect.x + (int) ((event.getTime() + event.getDuration() - time0) * pixelsPerNanoSec); + if (x >= rect.x + rect.width || xEnd < rect.x) { + // event is out of bounds + continue; + } + xEnd = Math.min(rect.x + rect.width, xEnd); + stateRect.x = Math.max(rect.x, x); + stateRect.width = Math.max(0, xEnd - stateRect.x + 1); + if (stateRect.x == lastX) { + stateRect.width -= 1; + if (stateRect.width > 0) { + gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); + gc.drawPoint(stateRect.x, stateRect.y - 2); + stateRect.x += 1; + } + } + boolean timeSelected = selectedTime >= event.getTime() && selectedTime < event.getTime() + event.getDuration(); + if (drawState(getColorScheme(), event, stateRect, gc, selected, timeSelected)) { + lastX = x; + } + } + gc.setClipping((Rectangle) null); + } + fTimeGraphProvider.postDrawEntry(entry, rect, gc); + } + + /** + * Draw the links + * + * @param bounds + * The rectangle of the area + * @param timeProvider + * The time provider + * @param links + * The array items to draw + * @param nameSpace + * The width reserved for the names + * @param gc + * Reference to the SWT GC object + * @since 2.1 + */ + public void drawLinks(Rectangle bounds, ITimeDataProvider timeProvider, + List links, int nameSpace, GC gc) { + if (fHideArrows) { + return; + } + gc.setClipping(new Rectangle(nameSpace, 0, bounds.width - nameSpace, bounds.height)); + for (ILinkEvent event : links) { + drawLink(event, bounds, timeProvider, nameSpace, gc); + } + gc.setClipping((Rectangle) null); + } + + /** + * Draws the link type events of this item + * + * @param event + * the item to draw + * @param bounds + * the container rectangle + * @param timeProvider + * Time provider + * @param nameSpace + * the name space + * @param gc + * Graphics context + * @since 2.1 + */ + protected void drawLink(ILinkEvent event, Rectangle bounds, ITimeDataProvider timeProvider, int nameSpace, GC gc) { + drawArrow(getColorScheme(), event, getArrowRectangle(bounds, event), gc); + } + + private Rectangle getArrowRectangle(Rectangle bounds, ILinkEvent event) { + int srcIndex = fItemData.findItemIndex(event.getEntry()); + int destIndex = fItemData.findItemIndex(event.getDestinationEntry()); + + if ((srcIndex == -1) || (destIndex == -1)) { + return null; + } + + Rectangle src = getStatesRect(bounds, srcIndex, fTimeProvider.getNameSpace()); + Rectangle dst = getStatesRect(bounds, destIndex, fTimeProvider.getNameSpace()); + + int x0 = getXForTime(event.getTime()); + int x1 = getXForTime(event.getTime() + event.getDuration()); + + // limit the x-coordinates to prevent integer overflow in calculations + // and also GC.drawLine doesn't draw properly with large coordinates + final int limit = Integer.MAX_VALUE / 1024; + x0 = Math.max(-limit, Math.min(x0, limit)); + x1 = Math.max(-limit, Math.min(x1, limit)); + + int y0 = src.y + src.height / 2; + int y1 = dst.y + dst.height / 2; + return new Rectangle(x0, y0, x1 - x0, y1 - y0); + } + + /** + * Draw the state (color fill) + * + * @param colors + * Color scheme + * @param event + * Time event for which we're drawing the state + * @param rect + * Where to draw + * @param gc + * Graphics context + * @return true if the state was drawn + * @since 2.1 + */ + protected boolean drawArrow(TimeGraphColorScheme colors, ITimeEvent event, + Rectangle rect, GC gc) { + + if (rect == null) { + return false; + } + int colorIdx = fTimeGraphProvider.getStateTableIndex(event); + if (colorIdx < 0) { + return false; + } + boolean visible = ((rect.height == 0) && (rect.width == 0)) ? false : true; + + if (visible) { + Color stateColor = null; + if (colorIdx < fEventColorMap.length) { + stateColor = fEventColorMap[colorIdx]; + } else { + stateColor = Display.getDefault().getSystemColor(SWT.COLOR_BLACK); + } + + gc.setForeground(stateColor); + gc.setBackground(stateColor); + + /* Draw the arrow */ + gc.drawLine(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height); + drawArrowHead(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height, gc); + + } + fTimeGraphProvider.postDrawEvent(event, rect, gc); + return visible; + } + + /* + * @author Francis Giraldeau + * + * Inspiration: + * http://stackoverflow.com/questions/3010803/draw-arrow-on-line-algorithm + * + * The algorithm was taken from this site, not the code itself + */ + private static void drawArrowHead(int x0, int y0, int x1, int y1, GC gc) + { + int factor = 10; + double cos = 0.9510; + double sin = 0.3090; + long lenx = x1 - x0; + long leny = y1 - y0; + double len = Math.sqrt(lenx * lenx + leny * leny); + + double dx = factor * lenx / len; + double dy = factor * leny / len; + int end1X = (int) Math.round((x1 - (dx * cos + dy * -sin))); + int end1Y = (int) Math.round((y1 - (dx * sin + dy * cos))); + int end2X = (int) Math.round((x1 - (dx * cos + dy * sin))); + int end2Y = (int) Math.round((y1 - (dx * -sin + dy * cos))); + int[] arrow = new int[] { x1, y1, end1X, end1Y, end2X, end2Y, x1, y1 }; + gc.fillPolygon(arrow); + } + + /** + * Draw the name of an item. + * + * @param item + * Item object + * @param bounds + * Where to draw the name + * @param gc + * Graphics context + */ + protected void drawName(Item item, Rectangle bounds, GC gc) { + boolean hasTimeEvents = item.fEntry.hasTimeEvents(); + if (! hasTimeEvents) { + gc.setBackground(getColorScheme().getBkColorGroup(item.fSelected, fIsInFocus)); + gc.fillRectangle(bounds); + if (item.fSelected && fIsInFocus) { + gc.setForeground(getColorScheme().getBkColor(item.fSelected, fIsInFocus, false)); + gc.drawRectangle(bounds.x, bounds.y, bounds.width - 1, bounds.height - 1); + } + } else { + gc.setBackground(getColorScheme().getBkColor(item.fSelected, fIsInFocus, true)); + gc.setForeground(getColorScheme().getFgColor(item.fSelected, fIsInFocus)); + gc.fillRectangle(bounds); + } + + // No name to be drawn + if (fTimeProvider.getNameSpace() == 0) { + return; + } + + int leftMargin = MARGIN + item.fLevel * EXPAND_SIZE; + if (item.fHasChildren) { + gc.setForeground(getColorScheme().getFgColorGroup(false, false)); + gc.setBackground(getColorScheme().getBkColor(false, false, false)); + Rectangle rect = Utils.clone(bounds); + rect.x += leftMargin; + rect.y += (bounds.height - EXPAND_SIZE) / 2; + rect.width = EXPAND_SIZE; + rect.height = EXPAND_SIZE; + gc.fillRectangle(rect); + gc.drawRectangle(rect.x, rect.y, rect.width - 1, rect.height - 1); + int midy = rect.y + rect.height / 2; + gc.drawLine(rect.x + 2, midy, rect.x + rect.width - 3, midy); + if (!item.fExpanded) { + int midx = rect.x + rect.width / 2; + gc.drawLine(midx, rect.y + 2, midx, rect.y + rect.height - 3); + } + } + leftMargin += EXPAND_SIZE + MARGIN; + + Image img = fTimeGraphProvider.getItemImage(item.fEntry); + if (img != null) { + // draw icon + int imgHeight = img.getImageData().height; + int imgWidth = img.getImageData().width; + int x = leftMargin; + int y = bounds.y + (bounds.height - imgHeight) / 2; + gc.drawImage(img, x, y); + leftMargin += imgWidth + MARGIN; + } + String name = item.fName; + Point size = gc.stringExtent(name); + if (fIdealNameSpace < leftMargin + size.x + MARGIN) { + fIdealNameSpace = leftMargin + size.x + MARGIN; + } + if (hasTimeEvents) { + // cut long string with "..." + int width = bounds.width - leftMargin; + int cuts = 0; + while (size.x > width && name.length() > 1) { + cuts++; + name = name.substring(0, name.length() - 1); + size = gc.stringExtent(name + "..."); //$NON-NLS-1$ + } + if (cuts > 0) { + name += "..."; //$NON-NLS-1$ + } + } + Rectangle rect = Utils.clone(bounds); + rect.x += leftMargin; + rect.width -= leftMargin; + // draw text + if (rect.width > 0) { + rect.y += (bounds.height - gc.stringExtent(name).y) / 2; + gc.setForeground(getColorScheme().getFgColor(item.fSelected, fIsInFocus)); + int textWidth = Utils.drawText(gc, name, rect, true); + leftMargin += textWidth + MARGIN; + rect.y -= 2; + + if (hasTimeEvents) { + // draw middle line + int x = bounds.x + leftMargin; + int width = bounds.width - x; + int midy = bounds.y + bounds.height / 2; + gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.MID_LINE)); + gc.drawLine(x, midy, x + width, midy); + } + } + } + + /** + * Draw the state (color fill) + * + * @param colors + * Color scheme + * @param event + * Time event for which we're drawing the state + * @param rect + * Where to draw + * @param gc + * Graphics context + * @param selected + * Is this time event currently selected (so it appears + * highlighted) + * @param timeSelected + * Is the timestamp currently selected + * @return true if the state was drawn + * @since 2.0 + */ + protected boolean drawState(TimeGraphColorScheme colors, ITimeEvent event, + Rectangle rect, GC gc, boolean selected, boolean timeSelected) { + + int colorIdx = fTimeGraphProvider.getStateTableIndex(event); + if (colorIdx < 0 && colorIdx != ITimeGraphPresentationProvider.TRANSPARENT) { + return false; + } + boolean visible = rect.width == 0 ? false : true; + Color black = Display.getDefault().getSystemColor(SWT.COLOR_BLACK); + gc.setForeground(black); + + if (visible) { + if (colorIdx == ITimeGraphPresentationProvider.TRANSPARENT) { + // Only draw the top and bottom borders + gc.drawLine(rect.x, rect.y, rect.x + rect.width - 1, rect.y); + gc.drawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width - 1, rect.y + rect.height - 1); + if (rect.width == 1) { + gc.drawPoint(rect.x, rect.y - 2); + } + return false; + } + Color stateColor = null; + if (colorIdx < fEventColorMap.length) { + stateColor = fEventColorMap[colorIdx]; + } else { + stateColor = black; + } + + boolean reallySelected = timeSelected && selected; + // fill all rect area + gc.setBackground(stateColor); + gc.fillRectangle(rect); + + if (reallySelected) { + gc.drawLine(rect.x, rect.y - 1, rect.x + rect.width - 1, rect.y - 1); + gc.drawLine(rect.x, rect.y + rect.height, rect.x + rect.width - 1, rect.y + rect.height); + } + } else { + gc.drawPoint(rect.x, rect.y - 2); + } + fTimeGraphProvider.postDrawEvent(event, rect, gc); + return visible; + } + + /** + * Fill the space between two contiguous time events + * + * @param rect + * Rectangle to fill + * @param gc + * Graphics context + * @param selected + * Is this time event selected or not + */ + protected void fillSpace(Rectangle rect, GC gc, boolean selected) { + gc.setBackground(getColorScheme().getBkColor(selected, fIsInFocus, false)); + gc.fillRectangle(rect); + if (fDragState == DRAG_ZOOM) { + gc.setBackground(getColorScheme().getBkColor(selected, fIsInFocus, true)); + if (fDragX0 < fDragX) { + gc.fillRectangle(new Rectangle(fDragX0, rect.y, fDragX - fDragX0, rect.height)); + } else if (fDragX0 > fDragX) { + gc.fillRectangle(new Rectangle(fDragX, rect.y, fDragX0 - fDragX, rect.height)); + } + } + // draw middle line + gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.MID_LINE)); + int midy = rect.y + rect.height / 2; + gc.drawLine(rect.x, midy, rect.x + rect.width, midy); + } + + @Override + public void keyTraversed(TraverseEvent e) { + if ((e.detail == SWT.TRAVERSE_TAB_NEXT) || (e.detail == SWT.TRAVERSE_TAB_PREVIOUS)) { + e.doit = true; + } + } + + @Override + public void keyPressed(KeyEvent e) { + int idx = -1; + if (fItemData.fExpandedItems.length == 0) { + return; + } + if (SWT.HOME == e.keyCode) { + idx = 0; + } else if (SWT.END == e.keyCode) { + idx = fItemData.fExpandedItems.length - 1; + } else if (SWT.ARROW_DOWN == e.keyCode) { + idx = getSelectedIndex(); + if (idx < 0) { + idx = 0; + } else if (idx < fItemData.fExpandedItems.length - 1) { + idx++; + } + } else if (SWT.ARROW_UP == e.keyCode) { + idx = getSelectedIndex(); + if (idx < 0) { + idx = 0; + } else if (idx > 0) { + idx--; + } + } else if (SWT.ARROW_LEFT == e.keyCode) { + selectPrevEvent(); + } else if (SWT.ARROW_RIGHT == e.keyCode) { + selectNextEvent(); + } else if (SWT.PAGE_DOWN == e.keyCode) { + int page = countPerPage(); + idx = getSelectedIndex(); + if (idx < 0) { + idx = 0; + } + idx += page; + if (idx >= fItemData.fExpandedItems.length) { + idx = fItemData.fExpandedItems.length - 1; + } + } else if (SWT.PAGE_UP == e.keyCode) { + int page = countPerPage(); + idx = getSelectedIndex(); + if (idx < 0) { + idx = 0; + } + idx -= page; + if (idx < 0) { + idx = 0; + } + } else if (SWT.CR == e.keyCode) { + idx = getSelectedIndex(); + if (idx >= 0) { + if (fItemData.fExpandedItems[idx].fHasChildren) { + toggle(idx); + } else { + fireDefaultSelection(); + } + } + idx = -1; + } + if (idx >= 0) { + selectItem(idx, false); + fireSelectionChanged(); + } + int x = toControl(e.display.getCursorLocation()).x; + updateCursor(x, e.stateMask | e.keyCode); + } + + @Override + public void keyReleased(KeyEvent e) { + int x = toControl(e.display.getCursorLocation()).x; + updateCursor(x, e.stateMask & ~e.keyCode); + } + + @Override + public void focusGained(FocusEvent e) { + fIsInFocus = true; + if (fMouseScrollFilterListener == null) { + fMouseScrollFilterListener = new Listener() { + // This filter is used to prevent horizontal scrolling of the view + // when the mouse wheel is used to zoom + @Override + public void handleEvent(Event event) { + event.doit = false; + } + }; + getDisplay().addFilter(SWT.MouseWheel, fMouseScrollFilterListener); + } + redraw(); + updateStatusLine(NO_STATUS); + } + + @Override + public void focusLost(FocusEvent e) { + fIsInFocus = false; + if (fMouseScrollFilterListener != null) { + getDisplay().removeFilter(SWT.MouseWheel, fMouseScrollFilterListener); + fMouseScrollFilterListener = null; + } + if (DRAG_NONE != fDragState) { + setCapture(false); + fDragState = DRAG_NONE; + } + redraw(); + updateStatusLine(NO_STATUS); + } + + /** + * @return If the current view is focused + */ + public boolean isInFocus() { + return fIsInFocus; + } + + /** + * Provide the possibility to control the wait cursor externally e.g. data + * requests in progress + * + * @param waitInd Should we wait indefinitely? + */ + public void waitCursor(boolean waitInd) { + // Update cursor as indicated + if (waitInd) { + setCursor(fWaitCursor); + } else { + setCursor(null); + } + } + + private void updateCursor(int x, int stateMask) { + // if Wait cursor not active, check for the need to change the cursor + if (getCursor() == fWaitCursor) { + return; + } + Cursor cursor = null; + if (fDragState == DRAG_SPLIT_LINE) { + } else if (fDragState == DRAG_SELECTION) { + cursor = fResizeCursor; + } else if (fDragState == DRAG_TRACE_ITEM) { + cursor = fDragCursor; + } else if (fDragState == DRAG_ZOOM) { + cursor = fZoomCursor; + } else if ((stateMask & SWT.MODIFIER_MASK) == SWT.CTRL) { + cursor = fDragCursor; + } else if ((stateMask & SWT.MODIFIER_MASK) == SWT.SHIFT) { + cursor = fResizeCursor; + } else if (!isOverSplitLine(x)) { + long selectionBegin = fTimeProvider.getSelectionBegin(); + long selectionEnd = fTimeProvider.getSelectionEnd(); + int xBegin = getXForTime(selectionBegin); + int xEnd = getXForTime(selectionEnd); + if (Math.abs(x - xBegin) < SNAP_WIDTH || Math.abs(x - xEnd) < SNAP_WIDTH) { + cursor = fResizeCursor; + } + } + if (getCursor() != cursor) { + setCursor(cursor); + } + } + + private void updateStatusLine(int x) { + // use the time provider of the time graph scale for the status line + ITimeDataProvider tdp = fTimeGraphScale.getTimeProvider(); + if (fStatusLineManager == null || null == tdp || + tdp.getTime0() == tdp.getTime1()) { + return; + } + TimeFormat tf = tdp.getTimeFormat(); + Resolution res = Resolution.NANOSEC; + StringBuilder message = new StringBuilder(); + if (x >= 0 && fDragState == DRAG_NONE) { + long time = getTimeAtX(x); + if (time >= 0) { + if (tdp instanceof ITimeDataProviderConverter) { + time = ((ITimeDataProviderConverter) tdp).convertTime(time); + } + long selectionBegin = tdp.getSelectionBegin(); + long selectionEnd = tdp.getSelectionEnd(); + message.append(NLS.bind("T: {0}{1} T1: {2}{3}", //$NON-NLS-1$ + new Object[] { + tf == TimeFormat.CALENDAR ? Utils.formatDate(time) + ' ' : "", //$NON-NLS-1$ + Utils.formatTime(time, tf, res), + tf == TimeFormat.CALENDAR ? Utils.formatDate(Math.min(selectionBegin, selectionEnd)) + ' ' : "", //$NON-NLS-1$ + Utils.formatTime(Math.min(selectionBegin, selectionEnd), tf, res) + })); + if (selectionBegin != selectionEnd) { + message.append(NLS.bind(" T2: {0}{1} \u0394: {2}", //$NON-NLS-1$ + new Object[] { + tf == TimeFormat.CALENDAR ? Utils.formatDate(Math.max(selectionBegin, selectionEnd)) + ' ' : "", //$NON-NLS-1$ + Utils.formatTime(Math.max(selectionBegin, selectionEnd), tf, res), + Utils.formatDelta(Math.abs(selectionBegin - selectionEnd), tf, res) + })); + } + } + } else if (fDragState == DRAG_SELECTION || fDragState == DRAG_ZOOM) { + long time0 = fDragTime0; + long time = getTimeAtX(fDragX); + if (tdp instanceof ITimeDataProviderConverter) { + time0 = ((ITimeDataProviderConverter) tdp).convertTime(time0); + time = ((ITimeDataProviderConverter) tdp).convertTime(time); + } + message.append(NLS.bind("T1: {0}{1} T2: {2}{3} \u0394: {4}", //$NON-NLS-1$ + new Object[] { + tf == TimeFormat.CALENDAR ? Utils.formatDate(Math.min(time, time0)) + ' ' : "", //$NON-NLS-1$ + Utils.formatTime(Math.min(time, time0), tf, res), + tf == TimeFormat.CALENDAR ? Utils.formatDate(Math.max(time, time0)) + ' ' : "", //$NON-NLS-1$ + Utils.formatTime(Math.max(time, time0), tf, res), + Utils.formatDelta(Math.abs(time - time0), tf, res) + })); + } + fStatusLineManager.setMessage(message.toString()); + } + + @Override + public void mouseMove(MouseEvent e) { + if (null == fTimeProvider) { + return; + } + Point size = getCtrlSize(); + if (DRAG_TRACE_ITEM == fDragState) { + int nameWidth = fTimeProvider.getNameSpace(); + if (e.x > nameWidth && size.x > nameWidth && fDragX != e.x) { + fDragX = e.x; + double pixelsPerNanoSec = (size.x - nameWidth <= RIGHT_MARGIN) ? 0 : (double) (size.x - nameWidth - RIGHT_MARGIN) / (fTime1bak - fTime0bak); + long timeDelta = (long) ((pixelsPerNanoSec == 0) ? 0 : ((fDragX - fDragX0) / pixelsPerNanoSec)); + long time1 = fTime1bak - timeDelta; + long maxTime = fTimeProvider.getMaxTime(); + if (time1 > maxTime) { + time1 = maxTime; + } + long time0 = time1 - (fTime1bak - fTime0bak); + if (time0 < fTimeProvider.getMinTime()) { + time0 = fTimeProvider.getMinTime(); + time1 = time0 + (fTime1bak - fTime0bak); + } + fTimeProvider.setStartFinishTime(time0, time1); + } + } else if (DRAG_SPLIT_LINE == fDragState) { + fDragX = e.x; + fTimeProvider.setNameSpace(e.x); + } else if (DRAG_SELECTION == fDragState) { + fDragX = Math.min(Math.max(e.x, fTimeProvider.getNameSpace()), size.x - RIGHT_MARGIN); + redraw(); + fTimeGraphScale.setDragRange(fDragX0, fDragX); + fireDragSelectionChanged(getTimeAtX(fDragX0), getTimeAtX(fDragX)); + } else if (DRAG_ZOOM == fDragState) { + fDragX = Math.min(Math.max(e.x, fTimeProvider.getNameSpace()), size.x - RIGHT_MARGIN); + redraw(); + fTimeGraphScale.setDragRange(fDragX0, fDragX); + } else if (DRAG_NONE == fDragState) { + boolean mouseOverSplitLine = isOverSplitLine(e.x); + if (fMouseOverSplitLine != mouseOverSplitLine) { + redraw(); + } + fMouseOverSplitLine = mouseOverSplitLine; + } + updateCursor(e.x, e.stateMask); + updateStatusLine(e.x); + } + + @Override + public void mouseDoubleClick(MouseEvent e) { + if (null == fTimeProvider) { + return; + } + if (1 == e.button && (e.stateMask & SWT.BUTTON_MASK) == 0) { + if (isOverSplitLine(e.x) && fTimeProvider.getNameSpace() != 0) { + fTimeProvider.setNameSpace(fIdealNameSpace); + boolean mouseOverSplitLine = isOverSplitLine(e.x); + if (fMouseOverSplitLine != mouseOverSplitLine) { + redraw(); + } + fMouseOverSplitLine = mouseOverSplitLine; + return; + } + int idx = getItemIndexAtY(e.y); + if (idx >= 0) { + selectItem(idx, false); + fireDefaultSelection(); + } + } + } + + @Override + public void mouseDown(MouseEvent e) { + if (fDragState != DRAG_NONE || null == fTimeProvider || + fTimeProvider.getTime0() == fTimeProvider.getTime1() || + getCtrlSize().x - fTimeProvider.getNameSpace() <= 0) { + return; + } + int idx; + if (1 == e.button && (e.stateMask & SWT.MODIFIER_MASK) == 0) { + int nameSpace = fTimeProvider.getNameSpace(); + if (nameSpace != 0 && isOverSplitLine(e.x)) { + fDragState = DRAG_SPLIT_LINE; + fDragButton = e.button; + fDragX = e.x; + fDragX0 = fDragX; + fTime0bak = fTimeProvider.getTime0(); + fTime1bak = fTimeProvider.getTime1(); + redraw(); + updateCursor(e.x, e.stateMask); + return; + } + } + if (1 == e.button && ((e.stateMask & SWT.MODIFIER_MASK) == 0 || (e.stateMask & SWT.MODIFIER_MASK) == SWT.SHIFT)) { + int nameSpace = fTimeProvider.getNameSpace(); + idx = getItemIndexAtY(e.y); + if (idx >= 0) { + Item item = fItemData.fExpandedItems[idx]; + if (item.fHasChildren && e.x < nameSpace && e.x < MARGIN + (item.fLevel + 1) * EXPAND_SIZE) { + toggle(idx); + return; + } + selectItem(idx, false); + fireSelectionChanged(); + } else { + selectItem(idx, false); // clear selection + fireSelectionChanged(); + } + long hitTime = getTimeAtX(e.x); + if (hitTime >= 0) { + setCapture(true); + + fDragState = DRAG_SELECTION; + fDragButton = e.button; + fDragX = e.x; + fDragX0 = fDragX; + fDragTime0 = getTimeAtX(fDragX0); + long selectionBegin = fTimeProvider.getSelectionBegin(); + long selectionEnd = fTimeProvider.getSelectionEnd(); + int xBegin = getXForTime(selectionBegin); + int xEnd = getXForTime(selectionEnd); + if ((e.stateMask & SWT.MODIFIER_MASK) == SWT.SHIFT) { + long time = getTimeAtX(e.x); + if (Math.abs(time - selectionBegin) < Math.abs(time - selectionEnd)) { + fDragX0 = xEnd; + fDragTime0 = selectionEnd; + } else { + fDragX0 = xBegin; + fDragTime0 = selectionBegin; + } + } else { + long time = getTimeAtX(e.x); + if (Math.abs(e.x - xBegin) < SNAP_WIDTH && Math.abs(time - selectionBegin) <= Math.abs(time - selectionEnd)) { + fDragX0 = xEnd; + fDragTime0 = selectionEnd; + } else if (Math.abs(e.x - xEnd) < SNAP_WIDTH && Math.abs(time - selectionEnd) <= Math.abs(time - selectionBegin)) { + fDragX0 = xBegin; + fDragTime0 = selectionBegin; + } + } + fTime0bak = fTimeProvider.getTime0(); + fTime1bak = fTimeProvider.getTime1(); + redraw(); + updateCursor(e.x, e.stateMask); + fTimeGraphScale.setDragRange(fDragX0, fDragX); + } + } else if (2 == e.button || (1 == e.button && (e.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL)) { + long hitTime = getTimeAtX(e.x); + if (hitTime > 0) { + setCapture(true); + fDragState = DRAG_TRACE_ITEM; + fDragButton = e.button; + fDragX = e.x; + fDragX0 = fDragX; + fTime0bak = fTimeProvider.getTime0(); + fTime1bak = fTimeProvider.getTime1(); + updateCursor(e.x, e.stateMask); + } + } else if (3 == e.button) { + setCapture(true); + fDragX = Math.min(Math.max(e.x, fTimeProvider.getNameSpace()), getCtrlSize().x - RIGHT_MARGIN); + fDragX0 = fDragX; + fDragTime0 = getTimeAtX(fDragX0); + fDragState = DRAG_ZOOM; + fDragButton = e.button; + redraw(); + updateCursor(e.x, e.stateMask); + fTimeGraphScale.setDragRange(fDragX0, fDragX); + } + } + + @Override + public void mouseUp(MouseEvent e) { + if (fPendingMenuDetectEvent != null && e.button == 3) { + menuDetected(fPendingMenuDetectEvent); + } + if (DRAG_NONE != fDragState) { + setCapture(false); + if (e.button == fDragButton && DRAG_TRACE_ITEM == fDragState) { + if (fDragX != fDragX0) { + fTimeProvider.notifyStartFinishTime(); + } + fDragState = DRAG_NONE; + } else if (e.button == fDragButton && DRAG_SPLIT_LINE == fDragState) { + fDragState = DRAG_NONE; + redraw(); + } else if (e.button == fDragButton && DRAG_SELECTION == fDragState) { + if (fDragX == fDragX0) { // click without selecting anything + long time = getTimeAtX(e.x); + fTimeProvider.setSelectedTimeNotify(time, false); + } else { + long time0 = fDragTime0; + long time1 = getTimeAtX(fDragX); + if (time0 <= time1) { + fTimeProvider.setSelectionRangeNotify(time0, time1); + } else { + fTimeProvider.setSelectionRangeNotify(time1, time0); + } + } + fDragState = DRAG_NONE; + redraw(); + fTimeGraphScale.setDragRange(-1, -1); + } else if (e.button == fDragButton && DRAG_ZOOM == fDragState) { + int nameWidth = fTimeProvider.getNameSpace(); + if (Math.max(fDragX, fDragX0) > nameWidth && fDragX != fDragX0) { + long time0 = getTimeAtX(fDragX0); + long time1 = getTimeAtX(fDragX); + if (time0 < time1) { + fTimeProvider.setStartFinishTimeNotify(time0, time1); + } else { + fTimeProvider.setStartFinishTimeNotify(time1, time0); + } + } else { + redraw(); + } + fDragState = DRAG_NONE; + fTimeGraphScale.setDragRange(-1, -1); + } + } + updateCursor(e.x, e.stateMask); + updateStatusLine(e.x); + } + + @Override + public void mouseEnter(MouseEvent e) { + } + + @Override + public void mouseExit(MouseEvent e) { + if (fMouseOverSplitLine) { + fMouseOverSplitLine = false; + redraw(); + } + updateStatusLine(NO_STATUS); + } + + @Override + public void mouseHover(MouseEvent e) { + } + + @Override + public void mouseScrolled(MouseEvent e) { + if ((fMouseScrollFilterListener == null) || fDragState != DRAG_NONE) { + return; + } + boolean zoomScroll = false; + Point p = getParent().toControl(getDisplay().getCursorLocation()); + Point parentSize = getParent().getSize(); + if (p.x >= 0 && p.x < parentSize.x && p.y >= 0 && p.y < parentSize.y) { + // over the parent control + if (e.x > getCtrlSize().x) { + // over the vertical scroll bar + zoomScroll = false; + } else if (e.y < 0 || e.y >= getCtrlSize().y) { + // over the time scale or horizontal scroll bar + zoomScroll = true; + } else { + if (e.x < fTimeProvider.getNameSpace()) { + // over the name space + zoomScroll = false; + } else { + // over the state area + if ((e.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL) { + // over the state area, CTRL pressed + zoomScroll = true; + } else { + // over the state area, CTRL not pressed + zoomScroll = false; + } + } + } + } + if (zoomScroll && fTimeProvider.getTime0() != fTimeProvider.getTime1()) { + if (e.count > 0) { + zoom(true); + } else if (e.count < 0) { + zoom(false); + } + } else { + setTopIndex(getTopIndex() - e.count); + } + } + + @Override + public void controlMoved(ControlEvent e) { + } + + @Override + public void controlResized(ControlEvent e) { + adjustScrolls(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + + @Override + public void widgetSelected(SelectionEvent e) { + if (e.widget == getVerticalBar()) { + setTopIndex(getVerticalBar().getSelection()); + } else if (e.widget == getHorizontalBar() && null != fTimeProvider) { + int start = getHorizontalBar().getSelection(); + long time0 = fTimeProvider.getTime0(); + long time1 = fTimeProvider.getTime1(); + long timeMin = fTimeProvider.getMinTime(); + long timeMax = fTimeProvider.getMaxTime(); + long delta = timeMax - timeMin; + + long range = time1 - time0; + time0 = timeMin + Math.round(delta * ((double) start / H_SCROLLBAR_MAX)); + time1 = time0 + range; + + // TODO: Follow-up with Bug 310310 + // In Linux SWT.DRAG is the only value received + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=310310 + if (e.detail == SWT.DRAG) { + fTimeProvider.setStartFinishTime(time0, time1); + } else { + fTimeProvider.setStartFinishTimeNotify(time0, time1); + } + } + } + + @Override + public int getBorderWidth() { + return fBorderWidth; + } + + /** + * Set the border width + * + * @param borderWidth + * The width + */ + public void setBorderWidth(int borderWidth) { + this.fBorderWidth = borderWidth; + } + + /** + * @return The current height of the header row + */ + public int getHeaderHeight() { + return fHeaderHeight; + } + + /** + * Set the height of the header row + * + * @param headerHeight + * The height + */ + public void setHeaderHeight(int headerHeight) { + this.fHeaderHeight = headerHeight; + } + + /** + * @return The default height of regular item rows + */ + public int getItemHeight() { + return fGlobalItemHeight; + } + + /** + * Set the default height of regular item rows. + * + * @param rowHeight + * The height + */ + public void setItemHeight(int rowHeight) { + this.fGlobalItemHeight = rowHeight; + } + + /** + * Set the height of a specific item. Overrides the default item height. + * + * @param entry + * A time graph entry + * @param rowHeight + * The height + * @return true if the height is successfully stored, false otherwise + * + * @since 2.1 + */ + public boolean setItemHeight(ITimeGraphEntry entry, int rowHeight) { + Item item = fItemData.findItem(entry); + if (item != null) { + item.fItemHeight = rowHeight; + return true; + } + return false; + } + + /** + * Set the minimum item width + * + * @param width The minimum width + */ + public void setMinimumItemWidth(int width) { + this.fMinimumItemWidth = width; + } + + /** + * @return The minimum item width + */ + public int getMinimumItemWidth() { + return fMinimumItemWidth; + } + + /** + * @return The entries that are currently filtered out + * + * @since 2.0 + */ + public List getFilteredOut() { + return fItemData.getFilteredOut(); + } + + @Override + public void addSelectionChangedListener(ISelectionChangedListener listener) { + if (listener != null && !fSelectionChangedListeners.contains(listener)) { + fSelectionChangedListeners.add(listener); + } + } + + @Override + public void removeSelectionChangedListener(ISelectionChangedListener listener) { + if (listener != null) { + fSelectionChangedListeners.remove(listener); + } + } + + @Override + public void setSelection(ISelection selection) { + if (selection instanceof TimeGraphSelection) { + TimeGraphSelection sel = (TimeGraphSelection) selection; + Object ob = sel.getFirstElement(); + if (ob instanceof ITimeGraphEntry) { + ITimeGraphEntry trace = (ITimeGraphEntry) ob; + selectItem(trace, false); + } + } + + } + + /** + * @param filter The filter object to be attached to the view + * @since 2.0 + */ + public void addFilter(ViewerFilter filter) { + if (!fFilters.contains(filter)) { + fFilters.add(filter); + } + } + + /** + * @param filter The filter object to be attached to the view + * @since 2.0 + */ + public void removeFilter(ViewerFilter filter) { + fFilters.remove(filter); + } + + /** + * @since 3.0 + */ + @Override + public void colorSettingsChanged(StateItem[] stateItems) { + /* Destroy previous colors from the resource manager */ + if (fEventColorMap != null) { + for (Color color : fEventColorMap) { + fResourceManager.destroyColor(color.getRGB()); + } + } + if (stateItems != null) { + fEventColorMap = new Color[stateItems.length]; + for (int i = 0; i < stateItems.length; i++) { + fEventColorMap[i] = fResourceManager.createColor(stateItems[i].getStateColor()); + } + } else { + fEventColorMap = new Color[] { }; + } + redraw(); + } + + private class ItemData { + private final Map fItemMap = new LinkedHashMap<>(); + private Item[] fExpandedItems = new Item[0]; + private Item[] fItems = new Item[0]; + private ITimeGraphEntry fRootEntries[] = new ITimeGraphEntry[0]; + private List fLinks = new ArrayList<>(); + private boolean fEntryFilter[] = new boolean[0]; + private final ArrayList fFilteredOut = new ArrayList<>(); + + public ItemData() { + } + + public Item findItem(ITimeGraphEntry entry) { + return fItemMap.get(entry); + } + + public int findItemIndex(ITimeGraphEntry entry) { + Item item = fItemMap.get(entry); + if (item == null) { + return -1; + } + return item.fExpandedIndex; + } + + public void refreshData() { + fItemMap.clear(); + fFilteredOut.clear(); + ITimeGraphEntry selection = getSelectedTrace(); + for (int i = 0; i < fRootEntries.length; i++) { + ITimeGraphEntry entry = fRootEntries[i]; + refreshData(fItemMap, null, 0, entry); + } + fItems = fItemMap.values().toArray(new Item[0]); + updateExpandedItems(); + if (selection != null) { + for (Item item : fExpandedItems) { + if (item.fEntry == selection) { + item.fSelected = true; + break; + } + } + } + } + + private void refreshData(Map itemMap, Item parent, int level, ITimeGraphEntry entry) { + Item item = new Item(entry, entry.getName(), level); + if (parent != null) { + parent.fChildren.add(item); + } + if (fGlobalItemHeight == CUSTOM_ITEM_HEIGHT) { + item.fItemHeight = fTimeGraphProvider.getItemHeight(entry); + } else { + item.fItemHeight = fGlobalItemHeight; + } + itemMap.put(entry, item); + if (entry.hasChildren()) { + item.fExpanded = fAutoExpandLevel == ALL_LEVELS || level < fAutoExpandLevel; + item.fHasChildren = true; + for (ITimeGraphEntry child : entry.getChildren()) { + refreshData(itemMap, item, level + 1, child); + } + } + } + + public void updateExpandedItems() { + for (Item item : fItems) { + item.fExpandedIndex = -1; + } + List expandedItemList = new ArrayList<>(); + for (int i = 0; i < fRootEntries.length; i++) { + ITimeGraphEntry entry = fRootEntries[i]; + Item item = findItem(entry); + refreshExpanded(expandedItemList, item); + } + fExpandedItems = expandedItemList.toArray(new Item[0]); + fTopIndex = Math.min(fTopIndex, Math.max(0, fExpandedItems.length - 1)); + } + + private void refreshExpanded(List expandedItemList, Item item) { + // Check for filters + boolean display = true; + for (ViewerFilter filter : fFilters) { + if (!filter.select(null, item.fEntry.getParent(), item.fEntry)) { + display = false; + break; + } + } + if (display) { + item.fExpandedIndex = expandedItemList.size(); + expandedItemList.add(item); + if (item.fHasChildren && item.fExpanded) { + for (Item child : item.fChildren) { + refreshExpanded(expandedItemList, child); + } + } + } + } + + public void refreshData(ITimeGraphEntry[] entries) { + if (entries == null) { + fEntryFilter = null; + fRootEntries = null; + } else { + if (entries.length == 0) { + fEntryFilter = null; + } else if (fEntryFilter == null || entries.length != fEntryFilter.length) { + fEntryFilter = new boolean[entries.length]; + java.util.Arrays.fill(fEntryFilter, true); + } + fRootEntries = Arrays.copyOf(entries, entries.length); + } + + refreshData(); + } + + public void refreshArrows(List events) { + /* If links are null, reset the list */ + if (events != null) { + fLinks = events; + } else { + fLinks = new ArrayList<>(); + } + } + + public ITimeGraphEntry[] getEntries() { + return fRootEntries; + } + + public boolean[] getEntryFilter() { + return fEntryFilter; + } + + public List getFilteredOut() { + return fFilteredOut; + } + } + + private class Item { + private boolean fExpanded; + private int fExpandedIndex; + private boolean fSelected; + private boolean fHasChildren; + private int fItemHeight; + private final int fLevel; + private final List fChildren; + private final String fName; + private final ITimeGraphEntry fEntry; + + public Item(ITimeGraphEntry entry, String name, int level) { + this.fEntry = entry; + this.fName = name; + this.fLevel = level; + this.fChildren = new ArrayList<>(); + } + + @Override + public String toString() { + return fName; + } + } + + /** + * @since 1.2 + */ + @Override + public void menuDetected(MenuDetectEvent e) { + if (null == fTimeProvider) { + return; + } + if (e.detail == SWT.MENU_MOUSE) { + if (fPendingMenuDetectEvent == null) { + /* Feature in Linux. The MenuDetectEvent is received before mouseDown. + * Store the event and trigger it later just before handling mouseUp. + * This allows for the method to detect if mouse is used to drag zoom. + */ + fPendingMenuDetectEvent = e; + return; + } + fPendingMenuDetectEvent = null; + if (fDragState != DRAG_ZOOM || fDragX != fDragX0) { + return; + } + } else { + if (fDragState != DRAG_NONE) { + return; + } + } + Point p = toControl(e.x, e.y); + int idx = getItemIndexAtY(p.y); + if (idx >= 0 && idx < fItemData.fExpandedItems.length) { + Item item = fItemData.fExpandedItems[idx]; + ITimeGraphEntry entry = item.fEntry; + if (entry.hasTimeEvents()) { + ITimeEvent event = Utils.findEvent(entry, getTimeAtX(p.x), 2); + if (event != null) { + e.data = event; + fireMenuEventOnTimeEvent(e); + return; + } + } + e.data = entry; + fireMenuEventOnTimeGraphEntry(e); + } + } + +} + + diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphScale.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphScale.java new file mode 100644 index 0000000000..ce2218dbc0 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphScale.java @@ -0,0 +1,859 @@ +/***************************************************************************** + * Copyright (c) 2007, 2014 Intel Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + * Ruslan A. Scherbakov, Intel - Initial API and implementation + * Alvaro Sanchez-Leon - Updated for TMF + * Patrick Tasse - Refactoring + * Marc-Andre Laperle - Add time zone preference + *****************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets; + +import java.text.NumberFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimePreferences; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.Resolution; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; + +/** + * Implementation of the scale for the time graph view. + * + * This goes above the "gantt chart" area. + * + * @version 1.0 + * @author Alvaro Sanchez-Leon + * @author Patrick Tasse + */ +public class TimeGraphScale extends TimeGraphBaseControl implements + MouseListener, MouseMoveListener { + + private static final long MICROSEC_IN_NS = 1000; + private static final long MILLISEC_IN_NS = 1000000; + private static final long SEC_IN_NS = 1000000000; + private static final long MIN_IN_NS = 60 * SEC_IN_NS; + private static final long HOUR_IN_NS = 60 * MIN_IN_NS; + private static final long DAY_IN_NS = 24 * HOUR_IN_NS; + private static final long MONTH_IN_NS = 31 * DAY_IN_NS; // upper limit + private static final long YEAR_IN_NS = 366 * DAY_IN_NS; // upper limit + + private static final double LOG10_1 = Math.log10(1); + private static final double LOG10_2 = Math.log10(2); + private static final double LOG10_3 = Math.log10(3); + private static final double LOG10_5 = Math.log10(5); + + private static final Calendar GREGORIAN_CALENDAR = Calendar.getInstance(); + + private static final TimeDraw TIMEDRAW_NANOSEC = new TimeDrawNanosec(); + private static final TimeDraw TIMEDRAW_MICROSEC = new TimeDrawMicrosec(); + private static final TimeDraw TIMEDRAW_MILLISEC = new TimeDrawMillisec(); + private static final TimeDraw TIMEDRAW_SEC = new TimeDrawSec(); + private static final TimeDraw TIMEDRAW_ABS_NANOSEC = new TimeDrawAbsNanoSec(); + private static final TimeDraw TIMEDRAW_ABS_MICROSEC = new TimeDrawAbsMicroSec(); + private static final TimeDraw TIMEDRAW_ABS_MILLISEC = new TimeDrawAbsMillisec(); + private static final TimeDraw TIMEDRAW_ABS_SEC = new TimeDrawAbsSec(); + private static final TimeDraw TIMEDRAW_ABS_MIN = new TimeDrawAbsMin(); + private static final TimeDraw TIMEDRAW_ABS_HRS = new TimeDrawAbsHrs(); + private static final TimeDraw TIMEDRAW_ABS_DAY = new TimeDrawAbsDay(); + private static final TimeDraw TIMEDRAW_ABS_MONTH = new TimeDrawAbsMonth(); + private static final TimeDraw TIMEDRAW_ABS_YEAR = new TimeDrawAbsYear(); + private static final TimeDraw TIMEDRAW_NUMBER = new TimeDrawNumber(); + private static final TimeDraw TIMEDRAW_CYCLES = new TimeDrawCycles(); + + private static final int DRAG_EXTERNAL = -1; + private static final int NO_BUTTON = 0; + private static final int LEFT_BUTTON = 1; + + private ITimeDataProvider fTimeProvider; + private int fDragState = NO_BUTTON; + private int fDragX0 = 0; + private int fDragX = 0; + private long fTime0bak; + private long fTime1bak; + private boolean fIsInUpdate; + private int fHeight; + + /** + * Standard constructor + * + * @param parent + * The parent composite object + * @param colors + * The color scheme to use + */ + public TimeGraphScale(Composite parent, TimeGraphColorScheme colors) { + super(parent, colors, SWT.NO_BACKGROUND | SWT.NO_FOCUS | SWT.DOUBLE_BUFFERED); + TmfSignalManager.register(this); + addMouseListener(this); + addMouseMoveListener(this); + TimeDraw.updateTimeZone(); + } + + @Override + public void dispose() { + TmfSignalManager.deregister(this); + super.dispose(); + } + + /** + * Assign the time provider for this scale + * + * @param timeProvider + * The provider to use + */ + public void setTimeProvider(ITimeDataProvider timeProvider) { + fTimeProvider = timeProvider; + } + + /** + * Get the time provider used by this scale + * + * @return The time provider + * @since 3.2 + */ + public ITimeDataProvider getTimeProvider() { + return fTimeProvider; + } + + @Override + public Point computeSize(int wHint, int hHint, boolean changed) { + return super.computeSize(wHint, fHeight, changed); + } + + /** + * Set the height of the scale + * + * @param height + * The height to use + */ + public void setHeight(int height) { + this.fHeight = height; + } + + /** + * Set the drag range to paint decorators + * + * @param begin + * The begin x-coordinate + * @param end + * The end x-coordinate + * @since 2.1 + */ + public void setDragRange(int begin, int end) { + if (NO_BUTTON == fDragState || DRAG_EXTERNAL == fDragState) { + fDragX0 = begin - fTimeProvider.getNameSpace(); + fDragX = end - fTimeProvider.getNameSpace(); + if (begin >= 0 || end >= 0) { + fDragState = DRAG_EXTERNAL; + } else { + fDragState = NO_BUTTON; + } + } + redraw(); + } + + private long calcTimeDelta(int width, double pixelsPerNanoSec) { + long timeDelta; + double minDelta = (pixelsPerNanoSec == 0) ? YEAR_IN_NS : width / pixelsPerNanoSec; + long unit = 1; + if (fTimeProvider != null && fTimeProvider.getTimeFormat() == TimeFormat.CALENDAR) { + if (minDelta > 6 * MONTH_IN_NS) { + unit = YEAR_IN_NS; + } else if (minDelta > 3 * MONTH_IN_NS) { + unit = 6 * MONTH_IN_NS; + } else if (minDelta > 10 * DAY_IN_NS) { + unit = MONTH_IN_NS; + } else if (minDelta > 12 * HOUR_IN_NS) { + unit = DAY_IN_NS; + } else if (minDelta > 3 * HOUR_IN_NS) { + unit = 6 * HOUR_IN_NS; + } else if (minDelta > 30 * MIN_IN_NS) { + unit = HOUR_IN_NS; + } else if (minDelta > 10 * MIN_IN_NS) { + unit = 15 * MIN_IN_NS; + } else if (minDelta > 30 * SEC_IN_NS) { + unit = MIN_IN_NS; + } else if (minDelta > 20 * SEC_IN_NS) { + unit = 30 * SEC_IN_NS; + } else if (minDelta <= 1) { + timeDelta = 1; + return timeDelta; + } + } + double log = Math.log10(minDelta / unit); + long pow10 = (long) log; + double remainder = log - pow10; + if (remainder < LOG10_1) { + timeDelta = (long) Math.pow(10, pow10) * unit; + } else if (remainder < LOG10_2) { + timeDelta = 2 * (long) Math.pow(10, pow10) * unit; + } else if (remainder < LOG10_3 && unit >= HOUR_IN_NS && unit < YEAR_IN_NS) { + timeDelta = 3 * (long) Math.pow(10, pow10) * unit; + } else if (remainder < LOG10_5) { + timeDelta = 5 * (long) Math.pow(10, pow10) * unit; + } else { + timeDelta = 10 * (long) Math.pow(10, pow10) * unit; + } + if (timeDelta <= 0) { + timeDelta = 1; + } + return timeDelta; + } + + TimeDraw getTimeDraw(long timeDelta) { + TimeDraw timeDraw; + if (fTimeProvider != null) { + switch (fTimeProvider.getTimeFormat()) { + case CALENDAR: + if (timeDelta >= YEAR_IN_NS) { + timeDraw = TIMEDRAW_ABS_YEAR; + } else if (timeDelta >= MONTH_IN_NS) { + timeDraw = TIMEDRAW_ABS_MONTH; + } else if (timeDelta >= DAY_IN_NS) { + timeDraw = TIMEDRAW_ABS_DAY; + } else if (timeDelta >= HOUR_IN_NS) { + timeDraw = TIMEDRAW_ABS_HRS; + } else if (timeDelta >= MIN_IN_NS) { + timeDraw = TIMEDRAW_ABS_MIN; + } else if (timeDelta >= SEC_IN_NS) { + timeDraw = TIMEDRAW_ABS_SEC; + } else if (timeDelta >= MILLISEC_IN_NS) { + timeDraw = TIMEDRAW_ABS_MILLISEC; + } else if (timeDelta >= MICROSEC_IN_NS) { + timeDraw = TIMEDRAW_ABS_MICROSEC; + } else { + timeDraw = TIMEDRAW_ABS_NANOSEC; + } + return timeDraw; + case NUMBER: + return TIMEDRAW_NUMBER; + case CYCLES: + return TIMEDRAW_CYCLES; + case RELATIVE: + default: + } + + } + if (timeDelta >= SEC_IN_NS) { + timeDraw = TIMEDRAW_SEC; + } else if (timeDelta >= MILLISEC_IN_NS) { + timeDraw = TIMEDRAW_MILLISEC; + } else if (timeDelta >= MICROSEC_IN_NS) { + timeDraw = TIMEDRAW_MICROSEC; + } else { + timeDraw = TIMEDRAW_NANOSEC; + } + return timeDraw; + } + + @Override + void paint(Rectangle rect, PaintEvent e) { + + if (fIsInUpdate || null == fTimeProvider) { + return; + } + + GC gc = e.gc; + gc.fillRectangle(rect); + + long time0 = fTimeProvider.getTime0(); + long time1 = fTimeProvider.getTime1(); + int leftSpace = fTimeProvider.getNameSpace(); + int timeSpace = fTimeProvider.getTimeSpace(); + + gc.setBackground(getColorScheme().getColor(TimeGraphColorScheme.TOOL_BACKGROUND)); + gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.TOOL_FOREGROUND)); + Rectangle rect0 = new Rectangle(0, 0, 0, 0); + Utils.init(rect0, rect); + + // draw top left area + rect0.width = leftSpace; + rect0.x += 4; + rect0.width -= 4; + Rectangle absHeaderRect = new Rectangle(rect0.x, rect0.y, rect0.width, rect0.height); + rect0.x -= 4; + rect0.width += 4; + + // prepare and draw right rect of the timescale + rect0.x += leftSpace; + rect0.width = rect.width - leftSpace; + + // draw bottom border and erase all other area + gc.drawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width - 1, + rect.y + rect.height - 1); + rect0.height--; + gc.fillRectangle(rect0); + + if (time1 <= time0 || timeSpace < 2) { + return; + } + + int numDigits = calculateDigits(time0, time1); + + int labelWidth = gc.getCharWidth('0') * numDigits; + double pixelsPerNanoSec = (timeSpace <= RIGHT_MARGIN) ? 0 : + (double) (timeSpace - RIGHT_MARGIN) / (time1 - time0); + long timeDelta = calcTimeDelta(labelWidth, pixelsPerNanoSec); + + TimeDraw timeDraw = getTimeDraw(timeDelta); + + // draw range decorators + if (DRAG_EXTERNAL == fDragState) { + int x1 = leftSpace + Math.min(fDragX0, fDragX); + int x2 = leftSpace + Math.max(fDragX0, fDragX); + drawRangeDecorators(rect0, gc, x1, x2); + } else { + int x1; + int x2; + long selectionBegin = fTimeProvider.getSelectionBegin(); + long selectionEnd = fTimeProvider.getSelectionEnd(); + x1 = leftSpace + (int) ((selectionBegin - time0) * pixelsPerNanoSec); + x2 = leftSpace + (int) ((selectionEnd - time0) * pixelsPerNanoSec); + drawRangeDecorators(rect0, gc, x1, x2); + } + + if (rect0.isEmpty()) { + return; + } + + // draw time scale ticks + rect0.y = rect.y; + rect0.height = rect.height - 4; + rect0.width = labelWidth; + + long time; + if (fTimeProvider != null && fTimeProvider.getTimeFormat() == TimeFormat.CALENDAR) { + time = floorToCalendar(time0, timeDelta); + } else { + time = (time0 / timeDelta) * timeDelta; + if (time != time0) { + time += timeDelta; + } + } + + int y = rect0.y + rect0.height; + + if (fTimeProvider != null && fTimeProvider.getTimeFormat() == TimeFormat.CALENDAR) { + timeDraw.drawAbsHeader(gc, time, absHeaderRect); + } + + while (true) { + int x = rect.x + leftSpace + (int) (Math.floor((time - time0) * pixelsPerNanoSec)); + if (x >= rect.x + leftSpace + rect.width - rect0.width) { + break; + } + if (x >= rect.x + leftSpace) { + gc.drawLine(x, y, x, y + 4); + rect0.x = x; + if (x + rect0.width <= rect.x + rect.width) { + timeDraw.draw(gc, time, rect0); + } + } + if (pixelsPerNanoSec == 0 || time > Long.MAX_VALUE - timeDelta || timeDelta == 0) { + break; + } + if (fTimeProvider != null && fTimeProvider.getTimeFormat() == TimeFormat.CALENDAR) { + if (timeDelta >= YEAR_IN_NS) { + long millis = time / MILLISEC_IN_NS; + GREGORIAN_CALENDAR.setTime(new Date(millis)); + GREGORIAN_CALENDAR.add(Calendar.YEAR, (int) (timeDelta / YEAR_IN_NS)); + millis = GREGORIAN_CALENDAR.getTimeInMillis(); + time = millis * MILLISEC_IN_NS; + } else if (timeDelta >= MONTH_IN_NS) { + long millis = time / MILLISEC_IN_NS; + GREGORIAN_CALENDAR.setTime(new Date(millis)); + GREGORIAN_CALENDAR.add(Calendar.MONTH, (int) (timeDelta / MONTH_IN_NS)); + millis = GREGORIAN_CALENDAR.getTimeInMillis(); + time = millis * MILLISEC_IN_NS; + } else if (timeDelta >= DAY_IN_NS) { + long millis = time / MILLISEC_IN_NS; + GREGORIAN_CALENDAR.setTime(new Date(millis)); + GREGORIAN_CALENDAR.add(Calendar.DAY_OF_MONTH, (int) (timeDelta / DAY_IN_NS)); + millis = GREGORIAN_CALENDAR.getTimeInMillis(); + time = millis * MILLISEC_IN_NS; + } else { + time += timeDelta; + } + } else { + time += timeDelta; + } + } + } + + private static void drawRangeDecorators(Rectangle rect, GC gc, int x1, int x2) { + int y1 = rect.y + rect.height - 9; + int y2 = rect.y + rect.height - 5; + int ym = (y1 + y2) / 2; + if (x1 >= rect.x) { + // T1 + gc.drawLine(x1 - 3, y1, x1 - 3, y2); + gc.drawLine(x1 - 4, y1, x1 - 2, y1); + gc.drawLine(x1, y1, x1, y2); + } + if (x2 >= rect.x && x2 - x1 > 3) { + // T2 + gc.drawLine(x2 - 2, y1, x2 - 2, y2); + gc.drawLine(x2 - 3, y1, x2 - 1, y1); + } + if (x2 >= rect.x && x2 - x1 > 0) { + gc.drawLine(x2 + 1, y1, x2 + 3, y1); + gc.drawLine(x2 + 3, y1, x2 + 3, ym); + gc.drawLine(x2 + 1, ym, x2 + 3, ym); + gc.drawLine(x2 + 1, ym, x2 + 1, y2); + gc.drawLine(x2 + 1, y2, x2 + 3, y2); + } + } + + private static long floorToCalendar(long time, long timeDelta) { + long ret = time; + + if (timeDelta >= YEAR_IN_NS) { + GREGORIAN_CALENDAR.setTime(new Date(ret / MILLISEC_IN_NS)); + int year = GREGORIAN_CALENDAR.get(Calendar.YEAR); + int yearDelta = (int) (timeDelta / YEAR_IN_NS); + year = (year / yearDelta) * yearDelta; + GREGORIAN_CALENDAR.set(Calendar.YEAR, year); + GREGORIAN_CALENDAR.set(Calendar.MONTH, 0); // January 1st of year + GREGORIAN_CALENDAR.set(Calendar.DAY_OF_MONTH, 1); + GREGORIAN_CALENDAR.set(Calendar.HOUR_OF_DAY, 0); + GREGORIAN_CALENDAR.set(Calendar.MINUTE, 0); + GREGORIAN_CALENDAR.set(Calendar.SECOND, 0); + GREGORIAN_CALENDAR.set(Calendar.MILLISECOND, 0); + ret = GREGORIAN_CALENDAR.getTimeInMillis() * MILLISEC_IN_NS; + } else if (timeDelta >= MONTH_IN_NS) { + GREGORIAN_CALENDAR.setTime(new Date(ret / MILLISEC_IN_NS)); + int month = GREGORIAN_CALENDAR.get(Calendar.MONTH); + int monthDelta = (int) (timeDelta / MONTH_IN_NS); + month = (month / monthDelta) * monthDelta; + GREGORIAN_CALENDAR.set(Calendar.MONTH, month); + GREGORIAN_CALENDAR.set(Calendar.DAY_OF_MONTH, 1); // 1st of month + GREGORIAN_CALENDAR.set(Calendar.HOUR_OF_DAY, 0); + GREGORIAN_CALENDAR.set(Calendar.MINUTE, 0); + GREGORIAN_CALENDAR.set(Calendar.SECOND, 0); + GREGORIAN_CALENDAR.set(Calendar.MILLISECOND, 0); + ret = GREGORIAN_CALENDAR.getTimeInMillis() * MILLISEC_IN_NS; + } else { + long offset = GREGORIAN_CALENDAR.getTimeZone().getOffset(ret / MILLISEC_IN_NS) * MILLISEC_IN_NS; + ret += offset; + ret = (ret / timeDelta) * timeDelta; + ret -= offset; + } + return ret; + } + + private int calculateDigits(long time0, long time1) { + int numDigits = 5; + long timeRange = time1 - time0; + + if (fTimeProvider.getTimeFormat() == TimeFormat.CALENDAR) { + // Calculate the number of digits to represent the minutes provided + // 11:222 + // HH:mm:ss + numDigits += 8; + if (timeRange < 10000) { + // HH:11:222:333:444__ + numDigits += 10; + } else if (timeRange < 10000000) { + // HH:11:222:333__ + numDigits += 6; + } + } else { + long sec = time1 / SEC_IN_NS; + numDigits = Long.toString(sec).length(); + int thousandGroups = (numDigits - 1) / 3; + numDigits += thousandGroups; + numDigits += 12; // .000 000 000 + if (fTimeProvider.getTimeFormat() == TimeFormat.CYCLES) { + numDigits += Messages.Utils_ClockCyclesUnit.length(); + } + } + + return numDigits; + } + + @Override + public void mouseDown(MouseEvent e) { + getParent().setFocus(); + if (fDragState == NO_BUTTON && null != fTimeProvider) { + int x = e.x - fTimeProvider.getNameSpace(); + if (LEFT_BUTTON == e.button && x > 0) { + setCapture(true); + fDragState = LEFT_BUTTON; + } + if (x < 0) { + x = 0; + } else if (x > getSize().x - fTimeProvider.getNameSpace()) { + x = getSize().x - fTimeProvider.getNameSpace(); + } + fDragX = x; + fDragX0 = x; + fTime0bak = fTimeProvider.getTime0(); + fTime1bak = fTimeProvider.getTime1(); + } + } + + @Override + public void mouseUp(MouseEvent e) { + if (e.button == LEFT_BUTTON && fDragState == LEFT_BUTTON) { + setCapture(false); + fDragState = NO_BUTTON; + + // Notify time provider to check the need for listener notification + if (fDragX != fDragX0 && fTimeProvider.getTime0() != fTimeProvider.getTime1()) { + fTimeProvider.setStartFinishTimeNotify(fTimeProvider.getTime0(), fTimeProvider.getTime1()); + } + } + } + + @Override + public void mouseMove(MouseEvent e) { + if (fDragX0 < 0 || fDragState == NO_BUTTON || fTimeProvider == null) { + return; + } + Point size = getSize(); + int leftSpace = fTimeProvider.getNameSpace(); + int x = e.x - leftSpace; + if (LEFT_BUTTON == fDragState) { + if (x > 0 && size.x > leftSpace && fDragX != x) { + fDragX = x; + if (fTimeProvider.getTime0() == fTimeProvider.getTime1()) { + return; + } + long interval = (long) ((fTime1bak - fTime0bak) * ((double) fDragX0 / fDragX)); + if (interval == Long.MAX_VALUE) { + fTimeProvider.setStartFinishTime(fTime0bak, Long.MAX_VALUE); + } else { + long time1 = fTime0bak + (long) ((fTime1bak - fTime0bak) * ((double) fDragX0 / fDragX)); + fTimeProvider.setStartFinishTime(fTime0bak, time1); + } + } + } + } + + @Override + public void mouseDoubleClick(MouseEvent e) { + if (e.button == 1 && null != fTimeProvider && fTimeProvider.getTime0() != fTimeProvider.getTime1() && (e.stateMask & SWT.BUTTON_MASK) == 0) { + fTimeProvider.resetStartFinishTime(); + fTimeProvider.notifyStartFinishTime(); + fTime0bak = fTimeProvider.getTime0(); + fTime1bak = fTimeProvider.getTime1(); + } + } + + /** + * Update the display to use the updated timestamp format + * + * @param signal the incoming signal + * @since 2.1 + */ + @TmfSignalHandler + public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) { + TimeDraw.updateTimeZone(); + Utils.updateTimeZone(); + redraw(); + } +} + +abstract class TimeDraw { + protected static final long MICROSEC_IN_NS = 1000; + protected static final long MILLISEC_IN_NS = 1000000; + protected static final long MILLISEC_IN_US = 1000; + protected static final long SEC_IN_NS = 1000000000; + protected static final long SEC_IN_MS = 1000; + private static final String S = "" ; //$NON-NLS-1$ + private static final String S0 = "0" ; //$NON-NLS-1$ + private static final String S00 = "00"; //$NON-NLS-1$ + protected static final long PAD_1000 = 1000; + protected static final SimpleDateFormat SEC_FORMAT_HEADER = new SimpleDateFormat("yyyy MMM dd"); //$NON-NLS-1$ + protected static final SimpleDateFormat SEC_FORMAT = new SimpleDateFormat("HH:mm:ss"); //$NON-NLS-1$ + protected static final SimpleDateFormat MIN_FORMAT_HEADER = new SimpleDateFormat("yyyy MMM dd"); //$NON-NLS-1$ + protected static final SimpleDateFormat MIN_FORMAT = new SimpleDateFormat("HH:mm"); //$NON-NLS-1$ + protected static final SimpleDateFormat HOURS_FORMAT_HEADER = new SimpleDateFormat("yyyy"); //$NON-NLS-1$ + protected static final SimpleDateFormat HOURS_FORMAT = new SimpleDateFormat("MMM dd HH:mm"); //$NON-NLS-1$ + protected static final SimpleDateFormat DAY_FORMAT_HEADER = new SimpleDateFormat("yyyy"); //$NON-NLS-1$ + protected static final SimpleDateFormat DAY_FORMAT = new SimpleDateFormat("MMM dd"); //$NON-NLS-1$ + protected static final SimpleDateFormat MONTH_FORMAT = new SimpleDateFormat("yyyy MMM"); //$NON-NLS-1$ + protected static final SimpleDateFormat YEAR_FORMAT = new SimpleDateFormat("yyyy"); //$NON-NLS-1$ + + protected static final SimpleDateFormat formatArray[] = { + SEC_FORMAT, SEC_FORMAT_HEADER, MIN_FORMAT, MIN_FORMAT_HEADER, + HOURS_FORMAT, HOURS_FORMAT_HEADER, DAY_FORMAT, DAY_FORMAT_HEADER, MONTH_FORMAT, YEAR_FORMAT + }; + + /** + * Updates the timezone using the preferences. + */ + public static void updateTimeZone() { + final TimeZone timeZone = TmfTimePreferences.getInstance().getTimeZone(); + for (SimpleDateFormat sdf : formatArray) { + sdf.setTimeZone(timeZone); + } + } + + static String sep(long n) { + StringBuilder retVal = new StringBuilder(); + String s = Long.toString(n); + for (int i = 0; i < s.length(); i++) { + int pos = s.length() - i - 1; + retVal.append(s.charAt(i)); + if (pos % 3 == 0 && pos != 0) { + retVal.append(' '); + } + } + return retVal.toString(); + } + + static String pad(long n) { + String s; + if (n < 10) { + s = S00; + } else if (n < 100) { + s = S0; + } else { + s = S; + } + return s + n; + } + + public abstract int draw(GC gc, long time, Rectangle rect); + + /** + * Override to draw absolute time header. This is for the time information + * not shown in the draw of each tick + * + * @param gc + * Graphics context + * @param nanosec + * time in nanosec + * @param absHeaderRect + * Header rectangle + */ + public void drawAbsHeader(GC gc, long nanosec, Rectangle absHeaderRect) { + } +} + +class TimeDrawSec extends TimeDraw { + @Override + public int draw(GC gc, long nanosec, Rectangle rect) { + long sec = nanosec / SEC_IN_NS; + return Utils.drawText(gc, sep(sec), rect, true); + } +} + +class TimeDrawMillisec extends TimeDraw { + @Override + public int draw(GC gc, long nanosec, Rectangle rect) { + long millisec = nanosec / MILLISEC_IN_NS; + long ms = millisec % PAD_1000; + long sec = millisec / SEC_IN_MS; + return Utils.drawText(gc, sep(sec) + "." + pad(ms), rect, true); //$NON-NLS-1$ + } +} + +class TimeDrawMicrosec extends TimeDraw { + @Override + public int draw(GC gc, long nanosec, Rectangle rect) { + long microsec = nanosec / MICROSEC_IN_NS; + long us = microsec % PAD_1000; + long millisec = microsec / MILLISEC_IN_US; + long ms = millisec % PAD_1000; + long sec = millisec / SEC_IN_MS; + return Utils.drawText(gc, sep(sec) + "." + pad(ms) + " " + pad(us), rect, true); //$NON-NLS-1$ //$NON-NLS-2$ + } +} + +class TimeDrawNanosec extends TimeDraw { + @Override + public int draw(GC gc, long nanosec, Rectangle rect) { + long ns = nanosec % PAD_1000; + long microsec = nanosec / MICROSEC_IN_NS; + long us = microsec % PAD_1000; + long millisec = microsec / MILLISEC_IN_US; + long ms = millisec % PAD_1000; + long sec = millisec / SEC_IN_MS; + return Utils.drawText(gc, sep(sec) + "." + pad(ms) + " " + pad(us) + " " + pad(ns), rect, true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } +} + +class TimeDrawAbsYear extends TimeDraw { + @Override + public int draw(GC gc, long nanosec, Rectangle rect) { + String stime = YEAR_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); + return Utils.drawText(gc, stime, rect, true); + } +} + +class TimeDrawAbsMonth extends TimeDraw { + @Override + public int draw(GC gc, long nanosec, Rectangle rect) { + String stime = MONTH_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); + return Utils.drawText(gc, stime, rect, true); + } +} + +class TimeDrawAbsDay extends TimeDraw { + @Override + public int draw(GC gc, long nanosec, Rectangle rect) { + String stime = DAY_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); + return Utils.drawText(gc, stime, rect, true); + } + + @Override + public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) { + String header = DAY_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS)); + int headerwidth = gc.stringExtent(header).x + 4; + if (headerwidth <= rect.width) { + rect.x += (rect.width - headerwidth); + Utils.drawText(gc, header, rect, true); + } + } +} + +class TimeDrawAbsHrs extends TimeDraw { + @Override + public int draw(GC gc, long nanosec, Rectangle rect) { + String stime = HOURS_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); + return Utils.drawText(gc, stime, rect, true); + } + + @Override + public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) { + String header = HOURS_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS)); + int headerwidth = gc.stringExtent(header).x + 4; + if (headerwidth <= rect.width) { + rect.x += (rect.width - headerwidth); + Utils.drawText(gc, header, rect, true); + } + } +} + +class TimeDrawAbsMin extends TimeDraw { + @Override + public int draw(GC gc, long nanosec, Rectangle rect) { + String stime = MIN_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); + return Utils.drawText(gc, stime, rect, true); + } + + @Override + public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) { + String header = MIN_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS)); + int headerwidth = gc.stringExtent(header).x + 4; + if (headerwidth <= rect.width) { + rect.x += (rect.width - headerwidth); + Utils.drawText(gc, header, rect, true); + } + } +} + +class TimeDrawAbsSec extends TimeDraw { + @Override + public int draw(GC gc, long nanosec, Rectangle rect) { + String stime = SEC_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); + return Utils.drawText(gc, stime, rect, true); + } + + @Override + public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) { + String header = SEC_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS)); + int headerwidth = gc.stringExtent(header).x + 4; + if (headerwidth <= rect.width) { + rect.x += (rect.width - headerwidth); + Utils.drawText(gc, header, rect, true); + } + } +} + +class TimeDrawAbsMillisec extends TimeDraw { + @Override + public int draw(GC gc, long nanosec, Rectangle rect) { + String stime = SEC_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); + String ns = Utils.formatNs(nanosec, Resolution.MILLISEC); + return Utils.drawText(gc, stime + "." + ns, rect, true); //$NON-NLS-1$ + } + + @Override + public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) { + String header = SEC_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS)); + int headerwidth = gc.stringExtent(header).x + 4; + if (headerwidth <= rect.width) { + rect.x += (rect.width - headerwidth); + Utils.drawText(gc, header, rect, true); + } + } +} + +class TimeDrawAbsMicroSec extends TimeDraw { + @Override + public int draw(GC gc, long nanosec, Rectangle rect) { + String stime = SEC_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); + String micr = Utils.formatNs(nanosec, Resolution.MICROSEC); + return Utils.drawText(gc, stime + "." + micr, rect, true); //$NON-NLS-1$ + } + + @Override + public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) { + String header = SEC_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS)); + int headerwidth = gc.stringExtent(header).x + 4; + if (headerwidth <= rect.width) { + rect.x += (rect.width - headerwidth); + Utils.drawText(gc, header, rect, true); + } + } +} + +class TimeDrawAbsNanoSec extends TimeDraw { + @Override + public int draw(GC gc, long nanosec, Rectangle rect) { + String stime = SEC_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); + String ns = Utils.formatNs(nanosec, Resolution.NANOSEC); + return Utils.drawText(gc, stime + "." + ns, rect, true); //$NON-NLS-1$ + } + + @Override + public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) { + String header = SEC_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS)); + int headerwidth = gc.stringExtent(header).x + 4; + if (headerwidth <= rect.width) { + rect.x += (rect.width - headerwidth); + Utils.drawText(gc, header, rect, true); + } + } +} + +class TimeDrawNumber extends TimeDraw { + @Override + public int draw(GC gc, long time, Rectangle rect) { + String stime = NumberFormat.getInstance().format(time); + return Utils.drawText(gc, stime, rect, true); + } +} + +class TimeDrawCycles extends TimeDraw { + @Override + public int draw(GC gc, long time, Rectangle rect) { + String stime = Utils.formatTime(time, TimeFormat.CYCLES, Resolution.SECONDS); + return Utils.drawText(gc, stime, rect, true); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphSelection.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphSelection.java new file mode 100644 index 0000000000..53d02303a6 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphSelection.java @@ -0,0 +1,97 @@ +/***************************************************************************** + * Copyright (c) 2007, 2013 Intel Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + * Ruslan A. Scherbakov, Intel - Initial API and implementation + * Alvaro Sanchez-Leon - Updated for TMF + * Patrick Tasse - Refactoring + *****************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.jface.viewers.IStructuredSelection; + +/** + * Selection object for the time graph scale + * + * @version 1.0 + * @author Alvaro Sanchez-Leon + * @author Patrick Tasse + */ +public class TimeGraphSelection implements IStructuredSelection { + + private List list = new ArrayList<>(); + + /** + * Default constructor + */ + public TimeGraphSelection() { + } + + /** + * "Wrapper" constructor. Instantiate a new selection object with only one + * existing selection. + * + * @param sel + * The initial selection to add to this one + */ + public TimeGraphSelection(Object sel) { + if (sel != null) { + list.add(sel); + } + } + + /** + * Add a selection to this one. + * + * @param sel + * The selection to add + */ + public void add(Object sel) { + if (null != sel && !list.contains(sel)) { + list.add(sel); + } + } + + @Override + public Object getFirstElement() { + if (!list.isEmpty()) { + return list.get(0); + } + return null; + } + + @Override + public Iterator iterator() { + return list.iterator(); + } + + @Override + public int size() { + return list.size(); + } + + @Override + public Object[] toArray() { + return list.toArray(); + } + + @Override + public List toList() { + return list; + } + + @Override + public boolean isEmpty() { + return list.isEmpty(); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphTooltipHandler.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphTooltipHandler.java new file mode 100644 index 0000000000..15031dc5cf --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphTooltipHandler.java @@ -0,0 +1,380 @@ +/***************************************************************************** + * Copyright (c) 2007, 2014 Intel Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + * Vitaly A. Provodin, Intel - Initial API and implementation + * Alvaro Sanchez-Leon - Updated for TMF + * Patrick Tasse - Refactoring + *****************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets; + +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackAdapter; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.NullTimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.Resolution; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; + +/** + * Handler for the tool tips in the generic time graph view. + * + * @version 1.0 + * @author Alvaro Sanchez-Leon + * @author Patrick Tasse + */ +public class TimeGraphTooltipHandler { + + private static final int OFFSET = 16; + + private Shell fTipShell; + private Composite fTipComposite; + private ITimeDataProvider fTimeDataProvider; + private ITimeGraphPresentationProvider fTimeGraphProvider = null; + + /** + * Standard constructor + * + * @param graphProv + * The presentation provider + * @param timeProv + * The time provider + * + * @since 2.0 + */ + public TimeGraphTooltipHandler(ITimeGraphPresentationProvider graphProv, + ITimeDataProvider timeProv) { + + this.fTimeGraphProvider = graphProv; + this.fTimeDataProvider = timeProv; + } + + /** + * Set the time data provider + * + * @param timeDataProvider + * The time data provider + * + * @since 3.2 + */ + public void setTimeProvider(ITimeDataProvider timeDataProvider) { + fTimeDataProvider = timeDataProvider; + } + + private void createTooltipShell(Shell parent) { + final Display display = parent.getDisplay(); + if (fTipShell != null && ! fTipShell.isDisposed()) { + fTipShell.dispose(); + } + fTipShell = new Shell(parent, SWT.ON_TOP | SWT.TOOL); + GridLayout gridLayout = new GridLayout(); + gridLayout.numColumns = 2; + gridLayout.marginWidth = 2; + gridLayout.marginHeight = 2; + fTipShell.setLayout(gridLayout); + fTipShell.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + + fTipComposite = new Composite(fTipShell, SWT.NONE); + fTipComposite.setLayout(new GridLayout(3, false)); + setupControl(fTipComposite); + + } + + /** + * Callback for the mouse-over tooltip + * + * @param control + * The control object to use + */ + public void activateHoverHelp(final Control control) { + control.addMouseListener(new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { + if (fTipShell != null && ! fTipShell.isDisposed()) { + fTipShell.dispose(); + } + } + }); + + control.addMouseMoveListener(new MouseMoveListener() { + @Override + public void mouseMove(MouseEvent e) { + if (fTipShell != null && ! fTipShell.isDisposed()) { + fTipShell.dispose(); + } + } + }); + + control.addMouseTrackListener(new MouseTrackAdapter() { + @Override + public void mouseExit(MouseEvent e) { + if (fTipShell != null && ! fTipShell.isDisposed()) { + Point pt = control.toDisplay(e.x, e.y); + if (! fTipShell.getBounds().contains(pt)) { + fTipShell.dispose(); + } + } + } + + private void addItem(String name, String value) { + Label nameLabel = new Label(fTipComposite, SWT.NO_FOCUS); + nameLabel.setText(name); + setupControl(nameLabel); + Label separator = new Label(fTipComposite, SWT.NO_FOCUS | SWT.SEPARATOR | SWT.VERTICAL); + GridData gd = new GridData(SWT.CENTER, SWT.CENTER, false, false); + gd.heightHint = nameLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).y; + separator.setLayoutData(gd); + setupControl(separator); + Label valueLabel = new Label(fTipComposite, SWT.NO_FOCUS); + valueLabel.setText(value); + setupControl(valueLabel); + } + + private void fillValues(Point pt, TimeGraphControl timeGraphControl, ITimeGraphEntry entry) { + if (entry == null) { + return; + } + if (entry.hasTimeEvents()) { + long currPixelTime = timeGraphControl.getTimeAtX(pt.x); + long nextPixelTime = timeGraphControl.getTimeAtX(pt.x + 1); + if (nextPixelTime == currPixelTime) { + nextPixelTime++; + } + ITimeEvent currEvent = Utils.findEvent(entry, currPixelTime, 0); + ITimeEvent nextEvent = Utils.findEvent(entry, currPixelTime, 1); + + // if there is no current event at the start of the current pixel range, + // or if the current event starts before the current pixel range, + // use the next event as long as it starts within the current pixel range + if ((currEvent == null || currEvent.getTime() < currPixelTime) && + (nextEvent != null && nextEvent.getTime() < nextPixelTime)) { + currEvent = nextEvent; + currPixelTime = nextEvent.getTime(); + } + + // state name + String stateTypeName = fTimeGraphProvider.getStateTypeName(entry); + String entryName = entry.getName(); + if (stateTypeName == null) { + stateTypeName = fTimeGraphProvider.getStateTypeName(); + } + + if (!entryName.isEmpty()) { + addItem(stateTypeName, entry.getName()); + } + + if (currEvent == null || currEvent instanceof NullTimeEvent) { + return; + } + + // state + String state = fTimeGraphProvider.getEventName(currEvent); + if (state != null) { + addItem(Messages.TmfTimeTipHandler_TRACE_STATE, state); + } + + // This block receives a list of values to be added to the tip table + Map eventAddOns = fTimeGraphProvider.getEventHoverToolTipInfo(currEvent, currPixelTime); + if (eventAddOns != null) { + for (Iterator iter = eventAddOns.keySet().iterator(); iter.hasNext();) { + String message = iter.next(); + addItem(message, eventAddOns.get(message)); + } + } + if (fTimeGraphProvider.displayTimesInTooltip()) { + long eventStartTime = -1; + long eventDuration = -1; + long eventEndTime = -1; + + eventStartTime = currEvent.getTime(); + eventDuration = currEvent.getDuration(); + if (eventDuration < 0 && nextEvent != null) { + eventEndTime = nextEvent.getTime(); + eventDuration = eventEndTime - eventStartTime; + } else { + eventEndTime = eventStartTime + eventDuration; + } + + Resolution res = Resolution.NANOSEC; + TimeFormat tf = fTimeDataProvider.getTimeFormat(); + String startTime = "?"; //$NON-NLS-1$ + String duration = "?"; //$NON-NLS-1$ + String endTime = "?"; //$NON-NLS-1$ + if (fTimeDataProvider instanceof ITimeDataProviderConverter) { + ITimeDataProviderConverter tdp = (ITimeDataProviderConverter) fTimeDataProvider; + if (eventStartTime > -1) { + eventStartTime = tdp.convertTime(eventStartTime); + startTime = Utils.formatTime(eventStartTime, tf, res); + } + if (eventEndTime > -1) { + eventEndTime = tdp.convertTime(eventEndTime); + endTime = Utils.formatTime(eventEndTime, tf, res); + } + if (eventDuration > -1) { + duration = Utils.formatDelta(eventEndTime - eventStartTime, tf, res); + } + } else { + if (eventStartTime > -1) { + startTime = Utils.formatTime(eventStartTime, tf, res); + } + if (eventEndTime > -1) { + endTime = Utils.formatTime(eventEndTime, tf, res); + } + if (eventDuration > -1) { + duration = Utils.formatDelta(eventDuration, tf, res); + } + } + if (tf == TimeFormat.CALENDAR) { + addItem(Messages.TmfTimeTipHandler_TRACE_DATE, + eventStartTime > -1 ? Utils.formatDate(eventStartTime) : "?"); //$NON-NLS-1$ + } + if (eventDuration > 0) { + addItem(Messages.TmfTimeTipHandler_TRACE_START_TIME, startTime); + addItem(Messages.TmfTimeTipHandler_TRACE_STOP_TIME, endTime); + } else { + addItem(Messages.TmfTimeTipHandler_TRACE_EVENT_TIME, startTime); + } + + if (eventDuration > 0) { + addItem(Messages.TmfTimeTipHandler_DURATION, duration); + } + } + } + } + + private void fillValues(ILinkEvent linkEvent) { + addItem(Messages.TmfTimeTipHandler_LINK_SOURCE, linkEvent.getEntry().getName()); + addItem(Messages.TmfTimeTipHandler_LINK_TARGET, linkEvent.getDestinationEntry().getName()); + + // This block receives a list of values to be added to the tip table + Map eventAddOns = fTimeGraphProvider.getEventHoverToolTipInfo(linkEvent); + if (eventAddOns != null) { + for (Iterator iter = eventAddOns.keySet().iterator(); iter.hasNext();) { + String message = iter.next(); + addItem(message, eventAddOns.get(message)); + } + } + if (fTimeGraphProvider.displayTimesInTooltip()) { + long sourceTime = linkEvent.getTime(); + long duration = linkEvent.getDuration(); + long targetTime = sourceTime + duration; + if (fTimeDataProvider instanceof ITimeDataProviderConverter) { + ITimeDataProviderConverter tdp = (ITimeDataProviderConverter) fTimeDataProvider; + sourceTime = tdp.convertTime(sourceTime); + targetTime = tdp.convertTime(targetTime); + duration = targetTime - sourceTime; + } + Resolution res = Resolution.NANOSEC; + TimeFormat tf = fTimeDataProvider.getTimeFormat(); + if (tf == TimeFormat.CALENDAR) { + addItem(Messages.TmfTimeTipHandler_TRACE_DATE, Utils.formatDate(sourceTime)); + } + if (duration > 0) { + addItem(Messages.TmfTimeTipHandler_LINK_SOURCE_TIME, Utils.formatTime(sourceTime, tf, res)); + addItem(Messages.TmfTimeTipHandler_LINK_TARGET_TIME, Utils.formatTime(targetTime, tf, res)); + addItem(Messages.TmfTimeTipHandler_DURATION, Utils.formatDelta(duration, tf, res)); + } else { + addItem(Messages.TmfTimeTipHandler_LINK_TIME, Utils.formatTime(sourceTime, tf, res)); + } + } + } + + @Override + public void mouseHover(MouseEvent event) { + if ((event.stateMask & SWT.BUTTON_MASK) != 0) { + return; + } + Point pt = new Point(event.x, event.y); + TimeGraphControl timeGraphControl = (TimeGraphControl) event.widget; + createTooltipShell(timeGraphControl.getShell()); + for (Control child : fTipComposite.getChildren()) { + child.dispose(); + } + if ((event.stateMask & SWT.MODIFIER_MASK) != SWT.SHIFT) { + ILinkEvent linkEvent = timeGraphControl.getArrow(pt); + if (linkEvent != null) { + fillValues(linkEvent); + } + } + if (fTipComposite.getChildren().length == 0) { + ITimeGraphEntry entry = timeGraphControl.getEntry(pt); + fillValues(pt, timeGraphControl, entry); + } + if (fTipComposite.getChildren().length == 0) { + return; + } + fTipShell.pack(); + Point tipPosition = control.toDisplay(pt); + fTipShell.pack(); + setHoverLocation(fTipShell, tipPosition); + fTipShell.setVisible(true); + } + }); + } + + private static void setHoverLocation(Shell shell, Point position) { + Rectangle displayBounds = shell.getDisplay().getBounds(); + Rectangle shellBounds = shell.getBounds(); + if (position.x + shellBounds.width + OFFSET > displayBounds.width && position.x - shellBounds.width - OFFSET >= 0) { + shellBounds.x = position.x - shellBounds.width - OFFSET; + } else { + shellBounds.x = Math.max(Math.min(position.x + OFFSET, displayBounds.width - shellBounds.width), 0); + } + if (position.y + shellBounds.height + OFFSET > displayBounds.height && position.y - shellBounds.height - OFFSET >= 0) { + shellBounds.y = position.y - shellBounds.height - OFFSET; + } else { + shellBounds.y = Math.max(Math.min(position.y + OFFSET, displayBounds.height - shellBounds.height), 0); + } + shell.setBounds(shellBounds); + } + + private void setupControl(Control control) { + control.setForeground(fTipShell.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND)); + control.setBackground(fTipShell.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + + control.addMouseListener(new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { + fTipShell.dispose(); + } + }); + + control.addMouseTrackListener(new MouseTrackAdapter() { + @Override + public void mouseExit(MouseEvent e) { + fTipShell.dispose(); + } + }); + + control.addMouseMoveListener(new MouseMoveListener() { + @Override + public void mouseMove(MouseEvent e) { + fTipShell.dispose(); + } + }); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/Utils.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/Utils.java new file mode 100644 index 0000000000..5f8f8a4652 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/Utils.java @@ -0,0 +1,826 @@ +/***************************************************************************** + * Copyright (c) 2007, 2014 Intel Corporation, Ericsson + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + * Ruslan A. Scherbakov, Intel - Initial API and implementation + * Alvaro Sanchez-Leon - Udpated for TMF + * Patrick Tasse - Refactoring + * Marc-Andre Laperle - Add time zone preference + *****************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets; + +import java.text.NumberFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Iterator; +import java.util.TimeZone; +import java.util.concurrent.TimeUnit; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimePreferences; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; + +/** + * General utilities and definitions used by the time graph widget + * + * @version 1.0 + * @author Alvaro Sanchez-Leon + * @author Patrick Tasse + */ +public class Utils { + + private Utils() { + } + + /** Time format for dates and timestamp */ + public enum TimeFormat { + /** Relative to the start of the trace */ + RELATIVE, + + /** + * Absolute timestamp (ie, relative to the Unix epoch) + * @since 2.0 + */ + CALENDAR, + + /** + * Timestamp displayed as a simple number + * @since 2.0 + */ + NUMBER, + + /** + * Timestamp displayed as cycles + * @since 3.2 + */ + CYCLES + } + + /** + * Timestamp resolution + */ + public static enum Resolution { + /** seconds */ + SECONDS, + + /** milliseconds */ + MILLISEC, + + /** microseconds */ + MICROSEC, + + /** nanoseconds */ + NANOSEC + } + + private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss"); //$NON-NLS-1$ + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); //$NON-NLS-1$ + private static final long HOURS_PER_DAY = 24; + private static final long MIN_PER_HOUR = 60; + private static final long SEC_PER_MIN = 60; + private static final long SEC_IN_NS = 1000000000; + private static final long MILLISEC_IN_NS = 1000000; + + /** + * Update the time and date formats to use the current time zone + * + * @since 2.1 + */ + public static void updateTimeZone() { + TimeZone timeZone = TmfTimePreferences.getInstance().getTimeZone(); + TIME_FORMAT.setTimeZone(timeZone); + DATE_FORMAT.setTimeZone(timeZone); + } + + static Rectangle clone(Rectangle source) { + return new Rectangle(source.x, source.y, source.width, source.height); + } + + /** + * Initialize a Rectangle object to default values (all equal to 0) + * + * @param rect + * The Rectangle to initialize + */ + public static void init(Rectangle rect) { + rect.x = 0; + rect.y = 0; + rect.width = 0; + rect.height = 0; + } + + /** + * Initialize a Rectangle object with all the given values + * + * @param rect + * The Rectangle object to initialize + * @param x + * The X coordinate + * @param y + * The Y coordinate + * @param width + * The width of the rectangle + * @param height + * The height of the rectangle + */ + public static void init(Rectangle rect, int x, int y, int width, int height) { + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + } + + /** + * Initialize a Rectangle object to another existing Rectangle's values. + * + * @param rect + * The Rectangle to initialize + * @param source + * The reference Rectangle to copy + */ + public static void init(Rectangle rect, Rectangle source) { + rect.x = source.x; + rect.y = source.y; + rect.width = source.width; + rect.height = source.height; + } + + /** + * Reduce the size of a given rectangle by the given amounts. + * + * @param rect + * The rectangle to modify + * @param x + * The reduction in width + * @param y + * The reduction in height + */ + public static void deflate(Rectangle rect, int x, int y) { + rect.x += x; + rect.y += y; + rect.width -= x + x; + rect.height -= y + y; + } + + /** + * Increase the size of a given rectangle by the given amounts. + * + * @param rect + * The rectangle to modify + * @param x + * The augmentation in width + * @param y + * The augmentation in height + */ + public static void inflate(Rectangle rect, int x, int y) { + rect.x -= x; + rect.y -= y; + rect.width += x + x; + rect.height += y + y; + } + + static void dispose(Color col) { + if (null != col) { + col.dispose(); + } + } + + /** + * Get the resulting color from a mix of two existing ones for a given + * display. + * + * @param display + * The display device (which might affect the color conversion) + * @param c1 + * The first color + * @param c2 + * The second color + * @param w1 + * The gamma level for color 1 + * @param w2 + * The gamma level for color 2 + * @return The resulting color + */ + public static Color mixColors(Device display, Color c1, Color c2, int w1, + int w2) { + return new Color(display, (w1 * c1.getRed() + w2 * c2.getRed()) + / (w1 + w2), (w1 * c1.getGreen() + w2 * c2.getGreen()) + / (w1 + w2), (w1 * c1.getBlue() + w2 * c2.getBlue()) + / (w1 + w2)); + } + + /** + * Get the system color with the given ID. + * + * @param id + * The color ID + * @return The resulting color + */ + public static Color getSysColor(int id) { + Color col = Display.getCurrent().getSystemColor(id); + return new Color(col.getDevice(), col.getRGB()); + } + + /** + * Get the resulting color from a mix of two existing ones for the current + * display. + * + * @param col1 + * The first color + * @param col2 + * The second color + * @param w1 + * The gamma level for color 1 + * @param w2 + * The gamma level for color 2 + * @return The resulting color + */ + public static Color mixColors(Color col1, Color col2, int w1, int w2) { + return mixColors(Display.getCurrent(), col1, col2, w1, w2); + } + + /** + * Draw text in a rectangle. + * + * @param gc + * The SWT GC object + * @param text + * The text to draw + * @param rect + * The rectangle object which is being drawn + * @param transp + * If true the background will be transparent + * @return The width of the written text + */ + public static int drawText(GC gc, String text, Rectangle rect, boolean transp) { + Point size = gc.stringExtent(text); + gc.drawText(text, rect.x, rect.y, transp); + return size.x; + } + + /** + * Draw text at a given location. + * + * @param gc + * The SWT GC object + * @param text + * The text to draw + * @param x + * The X coordinate of the starting point + * @param y + * the Y coordinate of the starting point + * @param transp + * If true the background will be transparent + * @return The width of the written text + */ + public static int drawText(GC gc, String text, int x, int y, boolean transp) { + Point size = gc.stringExtent(text); + gc.drawText(text, x, y, transp); + return size.x; + } + + /** + * Draw text in a rectangle, trimming the text to prevent exceeding the specified width. + * + * @param gc + * The SWT GC object + * @param text + * The string to be drawn + * @param x + * The x coordinate of the top left corner of the rectangular area where the text is to be drawn + * @param y + * The y coordinate of the top left corner of the rectangular area where the text is to be drawn + * @param width + * The width of the area to be drawn + * @param isCentered + * If true the text will be centered in the available width if space permits + * @param isTransparent + * If true the background will be transparent, otherwise it will be opaque + * @return The number of characters written + * + * @since 2.0 + */ + public static int drawText(GC gc, String text, int x, int y, int width, boolean isCentered, boolean isTransparent) { + if (width < 1) { + return 0; + } + + int len = text.length(); + int textWidth = 0; + boolean isReallyCentered = isCentered; + int realX = x; + + while (len > 0) { + textWidth = gc.stringExtent(text.substring(0, len)).x; + if (textWidth <= width) { + break; + } + isReallyCentered = false; + len--; + } + if (len > 0) { + if (isReallyCentered) { + realX += (width - textWidth) / 2; + } + gc.drawText(text.substring(0, len), realX, y, isTransparent); + } + return len; + } + + /** + * Formats time in format: MM:SS:NNN + * + * @param time time + * @param format 0: MMMM:ss:nnnnnnnnn, 1: HH:MM:ss MMM.mmmm.nnn + * @param resolution the resolution + * @return the formatted time + */ + public static String formatTime(long time, TimeFormat format, Resolution resolution) { + switch (format) { + case CALENDAR: + return formatTimeAbs(time, resolution); + case NUMBER: + return NumberFormat.getInstance().format(time); + case CYCLES: + return NumberFormat.getInstance().format(time) + Messages.Utils_ClockCyclesUnit; + case RELATIVE: + default: + } + + StringBuffer str = new StringBuffer(); + long t = time; + boolean neg = t < 0; + if (neg) { + t = -t; + str.append('-'); + } + + long sec = t / SEC_IN_NS; + str.append(sec); + String ns = formatNs(t, resolution); + if (!ns.equals("")) { //$NON-NLS-1$ + str.append('.'); + str.append(ns); + } + + return str.toString(); + } + + /** + * From input time in nanoseconds, convert to Date format YYYY-MM-dd + * + * @param absTime + * The source time, in ns + * @return the formatted date + */ + public static String formatDate(long absTime) { + String sdate = DATE_FORMAT.format(new Date(absTime / MILLISEC_IN_NS)); + return sdate; + } + + /** + * Formats time in ns to Calendar format: HH:MM:SS MMM.mmm.nnn + * + * @param time + * The source time, in ns + * @param res + * The resolution to use + * @return the formatted time + */ + public static String formatTimeAbs(long time, Resolution res) { + StringBuffer str = new StringBuffer(); + + // format time from nanoseconds to calendar time HH:MM:SS + String stime = TIME_FORMAT.format(new Date(time / MILLISEC_IN_NS)); + str.append(stime); + str.append('.'); + // append the Milliseconds, MicroSeconds and NanoSeconds as specified in + // the Resolution + str.append(formatNs(time, res)); + return str.toString(); + } + + /** + * Formats time delta + * + * @param delta + * The time delta, in ns + * @param format + * The time format to use + * @param resolution + * The resolution to use + * @since 3.2 + * @return the formatted time delta + */ + public static String formatDelta(long delta, TimeFormat format, Resolution resolution) { + if (format == TimeFormat.CALENDAR) { + return formatDeltaAbs(delta, resolution); + } + return formatTime(delta, format, resolution); + } + + /** + * Formats time delta in ns to Calendar format, only formatting the years, + * days, hours or minutes if necessary. + * + * @param delta + * The time delta, in ns + * @param resolution + * The resolution to use + * @return the formatted time delta + * @since 3.2 + */ + public static String formatDeltaAbs(long delta, Resolution resolution) { + StringBuffer str = new StringBuffer(); + if (delta < 0) { + str.append('-'); + } + long ns = Math.abs(delta); + long seconds = TimeUnit.NANOSECONDS.toSeconds(ns); + long minutes = TimeUnit.NANOSECONDS.toMinutes(ns); + long hours = TimeUnit.NANOSECONDS.toHours(ns); + long days = TimeUnit.NANOSECONDS.toDays(ns); + if (days > 0) { + str.append(days); + str.append("d "); //$NON-NLS-1$ + } + if (hours > 0) { + str.append(hours % HOURS_PER_DAY); + str.append("h "); //$NON-NLS-1$ + } + if (minutes > 0) { + str.append(minutes % MIN_PER_HOUR); + str.append("m "); //$NON-NLS-1$ + } + str.append(seconds % SEC_PER_MIN); + str.append('.'); + // append the ms, us and ns as specified in the resolution + str.append(formatNs(delta, resolution)); + str.append("s"); //$NON-NLS-1$ + return str.toString(); + } + + /** + * Obtains the remainder fraction on unit Seconds of the entered value in + * nanoseconds. e.g. input: 1241207054171080214 ns The number of fraction + * seconds can be obtained by removing the last 9 digits: 1241207054 the + * fractional portion of seconds, expressed in ns is: 171080214 + * + * @param srcTime + * The source time in ns + * @param res + * The Resolution to use + * @return the formatted nanosec + */ + public static String formatNs(long srcTime, Resolution res) { + StringBuffer str = new StringBuffer(); + long ns = Math.abs(srcTime % SEC_IN_NS); + String nanos = Long.toString(ns); + str.append("000000000".substring(nanos.length())); //$NON-NLS-1$ + str.append(nanos); + + if (res == Resolution.MILLISEC) { + return str.substring(0, 3); + } else if (res == Resolution.MICROSEC) { + return str.substring(0, 6); + } else if (res == Resolution.NANOSEC) { + return str.substring(0, 9); + } + return ""; //$NON-NLS-1$ + } + + /** + * FIXME Currently does nothing. + * + * @param opt + * The option name + * @param def + * The option value + * @param min + * The minimal accepted value + * @param max + * The maximal accepted value + * @return The value that was read + */ + public static int loadIntOption(String opt, int def, int min, int max) { + return def; + } + + /** + * FIXME currently does nothing + * + * @param opt + * The option name + * @param val + * The option value + */ + public static void saveIntOption(String opt, int val) { + } + + static ITimeEvent getFirstEvent(ITimeGraphEntry entry) { + if (null == entry || ! entry.hasTimeEvents()) { + return null; + } + Iterator iterator = entry.getTimeEventsIterator(); + if (iterator != null && iterator.hasNext()) { + return iterator.next(); + } + return null; + } + + /** + * Gets the {@link ITimeEvent} at the given time from the given + * {@link ITimeGraphEntry}. + * + * @param entry + * a {@link ITimeGraphEntry} + * @param time + * a timestamp + * @param n + * this parameter means:
  • -1: Previous Event
  • + * 0: Current Event
  • + * 1: Next Event
  • 2: Previous Event when located in a non + * Event Area + * @return a {@link ITimeEvent}, or null. + * @since 3.0 + */ + public static ITimeEvent findEvent(ITimeGraphEntry entry, long time, int n) { + if (null == entry || ! entry.hasTimeEvents()) { + return null; + } + Iterator iterator = entry.getTimeEventsIterator(); + if (iterator == null) { + return null; + } + ITimeEvent nextEvent = null; + ITimeEvent currEvent = null; + ITimeEvent prevEvent = null; + + while (iterator.hasNext()) { + nextEvent = iterator.next(); + long nextStartTime = nextEvent.getTime(); + + if (nextStartTime > time) { + break; + } + + if (currEvent == null || currEvent.getTime() != nextStartTime || + (nextStartTime != time && currEvent.getDuration() != nextEvent.getDuration())) { + prevEvent = currEvent; + currEvent = nextEvent; + } + } + + if (n == -1) { //previous + if (currEvent != null && currEvent.getTime() + currEvent.getDuration() >= time) { + return prevEvent; + } + return currEvent; + } else if (n == 0) { //current + if (currEvent != null && currEvent.getTime() + currEvent.getDuration() >= time) { + return currEvent; + } + return null; + } else if (n == 1) { //next + if (nextEvent != null && nextEvent.getTime() > time) { + return nextEvent; + } + return null; + } else if (n == 2) { //current or previous when in empty space + return currEvent; + } + + return null; + } + + /** + * Pretty-print a method signature. + * + * @param origSig + * The original signature + * @return The pretty signature + */ + public static String fixMethodSignature(String origSig) { + String sig = origSig; + int pos = sig.indexOf('('); + if (pos >= 0) { + String ret = sig.substring(0, pos); + sig = sig.substring(pos); + sig = sig + " " + ret; //$NON-NLS-1$ + } + return sig; + } + + /** + * Restore an original method signature from a pretty-printed one. + * + * @param ppSig + * The pretty-printed signature + * @return The original method signature + */ + public static String restoreMethodSignature(String ppSig) { + String ret = ""; //$NON-NLS-1$ + String sig = ppSig; + + int pos = sig.indexOf('('); + if (pos >= 0) { + ret = sig.substring(0, pos); + sig = sig.substring(pos + 1); + } + pos = sig.indexOf(')'); + if (pos >= 0) { + sig = sig.substring(0, pos); + } + String args[] = sig.split(","); //$NON-NLS-1$ + StringBuffer result = new StringBuffer("("); //$NON-NLS-1$ + for (int i = 0; i < args.length; i++) { + String arg = args[i].trim(); + if (arg.length() == 0 && args.length == 1) { + break; + } + result.append(getTypeSignature(arg)); + } + result.append(")").append(getTypeSignature(ret)); //$NON-NLS-1$ + return result.toString(); + } + + /** + * Get the mangled type information from an array of types. + * + * @param typeStr + * The types to convert. See method implementation for what it + * expects. + * @return The mangled string of types + */ + public static String getTypeSignature(String typeStr) { + int dim = 0; + String type = typeStr; + for (int j = 0; j < type.length(); j++) { + if (type.charAt(j) == '[') { + dim++; + } + } + int pos = type.indexOf('['); + if (pos >= 0) { + type = type.substring(0, pos); + } + StringBuffer sig = new StringBuffer(""); //$NON-NLS-1$ + for (int j = 0; j < dim; j++) + { + sig.append("["); //$NON-NLS-1$ + } + if (type.equals("boolean")) { //$NON-NLS-1$ + sig.append('Z'); + } else if (type.equals("byte")) { //$NON-NLS-1$ + sig.append('B'); + } else if (type.equals("char")) { //$NON-NLS-1$ + sig.append('C'); + } else if (type.equals("short")) { //$NON-NLS-1$ + sig.append('S'); + } else if (type.equals("int")) { //$NON-NLS-1$ + sig.append('I'); + } else if (type.equals("long")) { //$NON-NLS-1$ + sig.append('J'); + } else if (type.equals("float")) { //$NON-NLS-1$ + sig.append('F'); + } else if (type.equals("double")) { //$NON-NLS-1$ + sig.append('D'); + } else if (type.equals("void")) { //$NON-NLS-1$ + sig.append('V'); + } + else { + sig.append('L').append(type.replace('.', '/')).append(';'); + } + return sig.toString(); + } + + /** + * Compare two doubles together. + * + * @param d1 + * First double + * @param d2 + * Second double + * @return 1 if they are different, and 0 if they are *exactly* the same. + * Because of the way doubles are stored, it's possible for the + * same number obtained in two different ways to actually look + * different. + */ + public static int compare(double d1, double d2) { + if (d1 > d2) { + return 1; + } + if (d1 < d2) { + return 1; + } + return 0; + } + + /** + * Compare two character strings alphabetically. This is simply a wrapper + * around String.compareToIgnoreCase but that will handle cases where + * strings can be null + * + * @param s1 + * The first string + * @param s2 + * The second string + * @return A number below, equal, or greater than zero if the first string + * is smaller, equal, or bigger (alphabetically) than the second + * one. + */ + public static int compare(String s1, String s2) { + if (s1 != null && s2 != null) { + return s1.compareToIgnoreCase(s2); + } + if (s1 != null) { + return 1; + } + if (s2 != null) { + return -1; + } + return 0; + } + + /** + * Calculates the square of the distance between two points. + * + * @param x1 + * x-coordinate of point 1 + * @param y1 + * y-coordinate of point 1 + * @param x2 + * x-coordinate of point 2 + * @param y2 + * y-coordinate of point 2 + * + * @return the square of the distance in pixels^2 + * @since 3.2 + */ + public static double distance2(int x1, int y1, int x2, int y2) { + int dx = x2 - x1; + int dy = y2 - y1; + int d2 = dx * dx + dy * dy; + return d2; + } + + /** + * Calculates the distance between a point and a line segment. If the point + * is in the perpendicular region between the segment points, return the + * distance from the point to its projection on the segment. Otherwise + * return the distance from the point to its closest segment point. + * + * @param px + * x-coordinate of the point + * @param py + * y-coordinate of the point + * @param x1 + * x-coordinate of segment point 1 + * @param y1 + * y-coordinate of segment point 1 + * @param x2 + * x-coordinate of segment point 2 + * @param y2 + * y-coordinate of segment point 2 + * + * @return the distance in pixels + * @since 3.2 + */ + public static double distance(int px, int py, int x1, int y1, int x2, int y2) { + double length2 = distance2(x1, y1, x2, y2); + if (length2 == 0) { + return Math.sqrt(distance2(px, py, x1, y1)); + } + // 'r' is the ratio of the position, between segment point 1 and segment + // point 2, of the projection of the point on the segment + double r = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / length2; + if (r <= 0.0) { + // the projection is before segment point 1, return distance from + // the point to segment point 1 + return Math.sqrt(distance2(px, py, x1, y1)); + } + if (r >= 1.0) { + // the projection is after segment point 2, return distance from + // the point to segment point 2 + return Math.sqrt(distance2(px, py, x2, y2)); + } + // the projection is between the segment points, return distance from + // the point to its projection on the segment + int x = (int) (x1 + r * (x2 - x1)); + int y = (int) (y1 + r * (y2 - y1)); + return Math.sqrt(distance2(px, py, x, y)); + } +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/virtualtable/ColumnData.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/virtualtable/ColumnData.java new file mode 100644 index 0000000000..acd76744de --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/virtualtable/ColumnData.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Extracted from TmfEventsView + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.virtualtable; + +/** + * ColumnData + * + * @author Matthew Khouzam + * @deprecated Use {@link org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn} instead. + */ +@Deprecated +public class ColumnData { + /** + * The title of the column + */ + public final String header; + /** + * the width of the column in pixels + */ + public final int width; + /** + * the alignment of the column + */ + public final int alignment; + + /** + * Constructor + * @param h header (title) + * @param w width + * @param a alignment + */ + public ColumnData(String h, int w, int a) { + header = h; + width = w; + alignment = a; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/virtualtable/IDoubleClickListener.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/virtualtable/IDoubleClickListener.java new file mode 100644 index 0000000000..0f9359e0c7 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/virtualtable/IDoubleClickListener.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Kalray, Ericsson. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xavier Raynaud - Initial API and implementation + ******************************************************************************/ +package org.eclipse.tracecompass.tmf.ui.widgets.virtualtable; + +import org.eclipse.swt.widgets.TableItem; +/** + * Double click listener interface + * @author Xavier Raynaud + * @version 1.0 + */ +public interface IDoubleClickListener { + + /** + * Handle a double click event + * @param table the table that was double clicked + * @param item the item that was double clicked in the table + * @param column the column that was double clicked in the item in the table. + */ + void handleDoubleClick(TmfVirtualTable table, TableItem item, int column); + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/virtualtable/TmfVirtualTable.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/virtualtable/TmfVirtualTable.java new file mode 100644 index 0000000000..27b656b505 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/virtualtable/TmfVirtualTable.java @@ -0,0 +1,1130 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Khouzam - Initial API and implementation + * Francois Chouinard - Refactoring, slider support, bug fixing + * Patrick Tasse - Improvements and bug fixing + * Xavier Raynaud - Improvements + ******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.widgets.virtualtable; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.custom.TableEditor; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseWheelListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Slider; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.tracecompass.internal.tmf.ui.Activator; +import org.eclipse.ui.PlatformUI; + +/** + * TmfVirtualTable + *

    + * TmfVirtualTable allows for the tabular display of arbitrarily large data sets + * (well, up to Integer.MAX_VALUE or ~2G rows). + * + * It is essentially a Composite of Table and Slider, where the number of rows + * in the table is set to fill the table display area. The slider is rank-based. + * + * It differs from Table with the VIRTUAL style flag where an empty entry is + * created for each virtual row. This does not scale well for very large data sets. + * + * Styles: + * H_SCROLL, V_SCROLL, SINGLE, MULTI, CHECK, FULL_SELECTION, HIDE_SELECTION, NO_SCROLL + * @author Matthew Khouzam, Francois Chouinard, Patrick Tasse, Xavier Raynaud + * @version $Revision: 1.0 + */ +public class TmfVirtualTable extends Composite { + + // The table + private Table fTable; + private int fTableRows = 0; // Number of table rows + private int fFullyVisibleRows = 0; // Number of fully visible table rows + private int fFrozenRowCount = 0; // Number of frozen table rows at top of table + + private int fTableTopEventRank = 0; // Global rank of the first entry displayed + private int fSelectedEventRank = -1; // Global rank of the selected event + private int fSelectedBeginRank = -1; // Global rank of the selected begin event + private boolean fPendingSelection = false; // Pending selection update + + private int fTableItemCount = 0; + + // The slider + private Slider fSlider; + + private int fLinuxItemHeight = 0; // Calculated item height for Linux workaround + private TooltipProvider tooltipProvider = null; + private IDoubleClickListener doubleClickListener = null; + + private boolean fResetTopIndex = false; // Flag to trigger reset of top index + private ControlAdapter fResizeListener; // Resize listener to update visible rows + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** + * Standard constructor + * + * @param parent + * The parent composite object + * @param style + * The style to use + */ + public TmfVirtualTable(Composite parent, int style) { + super(parent, style & (~SWT.H_SCROLL) & (~SWT.V_SCROLL) & (~SWT.SINGLE) & (~SWT.MULTI) & (~SWT.FULL_SELECTION) & (~SWT.HIDE_SELECTION) & (~SWT.CHECK)); + + // Create the controls + createTable(style & (SWT.H_SCROLL | SWT.SINGLE | SWT.MULTI | SWT.FULL_SELECTION | SWT.HIDE_SELECTION | SWT.CHECK)); + createSlider(style & SWT.V_SCROLL); + + // Prevent the slider from being traversed + setTabList(new Control[] { fTable }); + + // Set the layout + GridLayout gridLayout = new GridLayout(); + gridLayout.numColumns = 2; + gridLayout.horizontalSpacing = 0; + gridLayout.verticalSpacing = 0; + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + setLayout(gridLayout); + + GridData tableGridData = new GridData(SWT.FILL, SWT.FILL, true, true); + fTable.setLayoutData(tableGridData); + + GridData sliderGridData = new GridData(SWT.FILL, SWT.FILL, false, true); + fSlider.setLayoutData(sliderGridData); + + // Add the listeners + fTable.addMouseWheelListener(new MouseWheelListener() { + @Override + public void mouseScrolled(MouseEvent event) { + if (fTableItemCount <= fFullyVisibleRows) { + return; + } + fTableTopEventRank -= event.count; + if (fTableTopEventRank < 0) { + fTableTopEventRank = 0; + } + int latestFirstRowOffset = fTableItemCount - fFullyVisibleRows; + if (fTableTopEventRank > latestFirstRowOffset) { + fTableTopEventRank = latestFirstRowOffset; + } + + fSlider.setSelection(fTableTopEventRank); + refreshTable(); + } + }); + + fTable.addListener(SWT.MouseWheel, new Listener() { + // disable mouse scroll of horizontal scroll bar + @Override + public void handleEvent(Event event) { + event.doit = false; + } + }); + + fResizeListener = new ControlAdapter() { + @Override + public void controlResized(ControlEvent event) { + int tableHeight = Math.max(0, fTable.getClientArea().height - fTable.getHeaderHeight()); + fFullyVisibleRows = tableHeight / getItemHeight(); + if (fTableItemCount > 0) { + fSlider.setThumb(Math.max(1, Math.min(fTableRows, fFullyVisibleRows))); + } + } + }; + fTable.addControlListener(fResizeListener); + + // Implement a "fake" tooltip + final String TOOLTIP_DATA_KEY = "_TABLEITEM"; //$NON-NLS-1$ + final Listener labelListener = new Listener() { + @Override + public void handleEvent (Event event) { + Label label = (Label) event.widget; + Shell shell = label.getShell(); + switch (event.type) { + case SWT.MouseDown: + Event e = new Event(); + e.item = (TableItem) label.getData(TOOLTIP_DATA_KEY); + // Assuming table is single select, set the selection as if + // the mouse down event went through to the table + fTable.setSelection(new TableItem [] {(TableItem) e.item}); + fTable.notifyListeners(SWT.Selection, e); + shell.dispose(); + fTable.setFocus(); + break; + case SWT.MouseExit: + case SWT.MouseWheel: + shell.dispose(); + break; + default: + break; + } + } + }; + + Listener tableListener = new Listener() { + Shell tip = null; + Label label = null; + @Override + public void handleEvent(Event event) { + switch (event.type) { + case SWT.Dispose: + case SWT.KeyDown: + case SWT.MouseMove: { + if (tip == null) { + break; + } + tip.dispose(); + tip = null; + label = null; + break; + } + case SWT.MouseHover: { + TableItem item = fTable.getItem(new Point(event.x, event.y)); + if (item != null) { + for (int i = 0; i < fTable.getColumnCount(); i++) { + Rectangle bounds = item.getBounds(i); + if (bounds.contains(event.x, event.y)) { + if (tip != null && !tip.isDisposed()) { + tip.dispose(); + } + if (tooltipProvider == null) { + return; + } + String tooltipText = tooltipProvider.getTooltip(i, item.getData()); + if (tooltipText == null) { + return; + } + tip = new Shell(fTable.getShell(), SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL); + tip.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + FillLayout layout = new FillLayout(); + layout.marginWidth = 2; + tip.setLayout(layout); + label = new Label(tip, SWT.WRAP); + label.setForeground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND)); + label.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + label.setData(TOOLTIP_DATA_KEY, item); + label.setText(tooltipText); + + label.addListener(SWT.MouseExit, labelListener); + label.addListener(SWT.MouseDown, labelListener); + label.addListener(SWT.MouseWheel, labelListener); + Point size = tip.computeSize(SWT.DEFAULT, SWT.DEFAULT); + Point pt = fTable.toDisplay(bounds.x, bounds.y); + tip.setBounds(pt.x, pt.y, size.x, size.y); + tip.setVisible(true); + + // Item found, leave loop. + break; + } + } + } + break; + } + default: + break; + } + } + }; + fTable.addListener(SWT.Dispose, tableListener); + fTable.addListener(SWT.KeyDown, tableListener); + fTable.addListener(SWT.MouseMove, tableListener); + fTable.addListener(SWT.MouseHover, tableListener); + addControlListener(new ControlAdapter() { + @Override + public void controlResized(ControlEvent event) { + resize(); + if (fTableItemCount > 0) { + fSlider.setThumb(Math.max(1, Math.min(fTableRows, fFullyVisibleRows))); + } + } + }); + + // And display + refresh(); + } + + // ------------------------------------------------------------------------ + // Table handling + // ------------------------------------------------------------------------ + + /** + * Create the table and add listeners + * @param style int can be H_SCROLL, SINGLE, MULTI, FULL_SELECTION, HIDE_SELECTION, CHECK + */ + private void createTable(int style) { + fTable = new Table(this, style | SWT.NO_SCROLL); + + fTable.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent event) { + if (event.item == null) { + // Override table selection from Select All action + refreshSelection(); + } + } + }); + + fTable.addMouseListener(new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { + handleTableMouseEvent(e); + } + }); + + fTable.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent event) { + handleTableKeyEvent(event); + } + }); + + fTable.addListener( + SWT.MouseDoubleClick, new Listener() { + @Override + public void handleEvent(Event event) { + if (doubleClickListener != null) { + TableItem item = fTable.getItem(new Point (event.x, event.y)); + if (item != null) { + for (int i = 0; i < fTable.getColumnCount(); i++){ + Rectangle bounds = item.getBounds(i); + if (bounds.contains(event.x, event.y)){ + doubleClickListener.handleDoubleClick(TmfVirtualTable.this, item, i); + break; + } + } + } + } + } + } + ); + + /* + * Feature in Windows. When a partially visible table item is selected, + * after ~500 ms the top index is changed to ensure the selected item is + * fully visible. This leaves a blank space at the bottom of the virtual + * table. The workaround is to reset the top index to 0 if it is not 0. + * Also reset the top index to 0 if indicated by the flag that was set + * at table selection of a partially visible table item. + */ + fTable.addPaintListener(new PaintListener() { + @Override + public void paintControl(PaintEvent e) { + if (fTable.getTopIndex() != 0 || fResetTopIndex) { + fTable.setTopIndex(0); + } + fResetTopIndex = false; + } + }); + } + + /** + * Handle mouse-based selection in table. + * + * @param event the mouse event + */ + private void handleTableMouseEvent(MouseEvent event) { + TableItem item = fTable.getItem(new Point(event.x, event.y)); + if (item == null) { + return; + } + int selectedRow = indexOf(item); + if (event.button == 1 || (event.button == 3 && + (selectedRow < Math.min(fSelectedBeginRank, fSelectedEventRank) || + selectedRow > Math.max(fSelectedBeginRank, fSelectedEventRank)))) { + if (selectedRow >= 0) { + fSelectedEventRank = selectedRow; + } else { + fSelectedEventRank = -1; + } + if ((event.stateMask & SWT.SHIFT) == 0 || (fTable.getStyle() & SWT.MULTI) == 0 || fSelectedBeginRank == -1) { + fSelectedBeginRank = fSelectedEventRank; + } + } + refreshSelection(); + + /* + * Feature in Linux. When a partially visible table item is selected, + * the origin is changed to ensure the selected item is fully visible. + * This makes the first row partially visible. The solution is to force + * reset the origin by setting the top index to 0. This should happen + * only once at the next redraw by the paint listener. + */ + if (selectedRow >= fFullyVisibleRows) { + fResetTopIndex = true; + } + } + + /** + * Handle key-based navigation in table. + * + * @param event the key event + */ + private void handleTableKeyEvent(KeyEvent event) { + + int lastEventRank = fTableItemCount - 1; + int lastPageTopEntryRank = Math.max(0, fTableItemCount - fFullyVisibleRows); + + int previousSelectedEventRank = fSelectedEventRank; + int previousSelectedBeginRank = fSelectedBeginRank; + boolean needsRefresh = false; + + // In all case, perform the following steps: + // - Update the selected entry rank (within valid range) + // - Update the selected row + // - Update the page's top entry if necessary (which also adjusts the selected row) + // - If the top displayed entry was changed, table refresh is needed + switch (event.keyCode) { + + case SWT.ARROW_DOWN: { + event.doit = false; + if (fSelectedEventRank < lastEventRank) { + fSelectedEventRank++; + int selectedRow = fSelectedEventRank - fTableTopEventRank; + if (selectedRow == fFullyVisibleRows) { + fTableTopEventRank++; + needsRefresh = true; + } else if (selectedRow < fFrozenRowCount || selectedRow > fFullyVisibleRows) { + fTableTopEventRank = Math.max(0, Math.min(fSelectedEventRank - fFrozenRowCount, lastPageTopEntryRank)); + needsRefresh = true; + } + } + break; + } + + case SWT.ARROW_UP: { + event.doit = false; + if (fSelectedEventRank > 0) { + fSelectedEventRank--; + int selectedRow = fSelectedEventRank - fTableTopEventRank; + if (selectedRow == fFrozenRowCount - 1 && fTableTopEventRank > 0) { + fTableTopEventRank--; + needsRefresh = true; + } else if (selectedRow < fFrozenRowCount || selectedRow > fFullyVisibleRows) { + fTableTopEventRank = Math.max(0, Math.min(fSelectedEventRank - fFrozenRowCount, lastPageTopEntryRank)); + needsRefresh = true; + } + } + break; + } + + case SWT.END: { + event.doit = false; + fTableTopEventRank = lastPageTopEntryRank; + fSelectedEventRank = lastEventRank; + needsRefresh = true; + break; + } + + case SWT.HOME: { + event.doit = false; + fSelectedEventRank = fFrozenRowCount; + fTableTopEventRank = 0; + needsRefresh = true; + break; + } + + case SWT.PAGE_DOWN: { + event.doit = false; + if (fSelectedEventRank < lastEventRank) { + fSelectedEventRank += fFullyVisibleRows; + if (fSelectedEventRank > lastEventRank) { + fSelectedEventRank = lastEventRank; + } + int selectedRow = fSelectedEventRank - fTableTopEventRank; + if (selectedRow > fFullyVisibleRows + fFrozenRowCount - 1 && selectedRow < 2 * fFullyVisibleRows) { + fTableTopEventRank += fFullyVisibleRows; + if (fTableTopEventRank > lastPageTopEntryRank) { + fTableTopEventRank = lastPageTopEntryRank; + } + needsRefresh = true; + } else if (selectedRow < fFrozenRowCount || selectedRow >= 2 * fFullyVisibleRows) { + fTableTopEventRank = Math.max(0, Math.min(fSelectedEventRank - fFrozenRowCount, lastPageTopEntryRank)); + needsRefresh = true; + } + } + break; + } + + case SWT.PAGE_UP: { + event.doit = false; + if (fSelectedEventRank > 0) { + fSelectedEventRank -= fFullyVisibleRows; + if (fSelectedEventRank < fFrozenRowCount) { + fSelectedEventRank = fFrozenRowCount; + } + int selectedRow = fSelectedEventRank - fTableTopEventRank; + if (selectedRow < fFrozenRowCount && selectedRow > -fFullyVisibleRows) { + fTableTopEventRank -= fFullyVisibleRows; + if (fTableTopEventRank < 0) { + fTableTopEventRank = 0; + } + needsRefresh = true; + } else if (selectedRow <= -fFullyVisibleRows || selectedRow >= fFullyVisibleRows) { + fTableTopEventRank = Math.max(0, Math.min(fSelectedEventRank - fFrozenRowCount, lastPageTopEntryRank)); + needsRefresh = true; + } + } + break; + } + default: { + return; + } + } + + if ((event.stateMask & SWT.SHIFT) == 0 || (fTable.getStyle() & SWT.MULTI) == 0 || fSelectedBeginRank == -1) { + fSelectedBeginRank = fSelectedEventRank; + } + + boolean done = true; + if (needsRefresh) { + done = refreshTable(); // false if table items not updated yet in this thread + } else { + refreshSelection(); + } + + if (fFullyVisibleRows < fTableItemCount) { + fSlider.setSelection(fTableTopEventRank); + } + + if (fSelectedEventRank != previousSelectedEventRank || fSelectedBeginRank != previousSelectedBeginRank) { + if (done) { + Event e = new Event(); + e.item = fTable.getItem(fSelectedEventRank - fTableTopEventRank); + fTable.notifyListeners(SWT.Selection, e); + } else { + fPendingSelection = true; + } + } + } + + /** + * Method setDataItem. + * @param index int + * @param item TableItem + * @return boolean + */ + private boolean setDataItem(int index, TableItem item) { + if (index != -1) { + Event event = new Event(); + event.item = item; + if (index < fFrozenRowCount) { + event.index = index; + } else { + event.index = index + fTableTopEventRank; + } + event.doit = true; + fTable.notifyListeners(SWT.SetData, event); + return event.doit; // false if table item not updated yet in this thread + } + return true; + } + + // ------------------------------------------------------------------------ + // Slider handling + // ------------------------------------------------------------------------ + + /** + * Method createSlider. + * @param style int + */ + private void createSlider(int style) { + fSlider = new Slider(this, SWT.VERTICAL | SWT.NO_FOCUS); + fSlider.setMinimum(0); + fSlider.setMaximum(0); + if ((style & SWT.V_SCROLL) == 0) { + fSlider.setVisible(false); + } + + fSlider.addListener(SWT.Selection, new Listener() { + @Override + public void handleEvent(Event event) { + switch (event.detail) { + case SWT.ARROW_DOWN: + case SWT.ARROW_UP: + case SWT.END: + case SWT.HOME: + case SWT.PAGE_DOWN: + case SWT.PAGE_UP: { + fTableTopEventRank = fSlider.getSelection(); + refreshTable(); + break; + } + // Not handled because of bug on Linux described below. + case SWT.NONE: + default: + break; + } + } + }); + + /* + * In Linux, the selection event above has event.detail set to SWT.NONE + * instead of SWT.DRAG during dragging of the thumb. To prevent refresh + * overflow, only update the table when the mouse button is released. + */ + fSlider.addMouseListener(new MouseAdapter() { + @Override + public void mouseUp(MouseEvent e) { + fTableTopEventRank = fSlider.getSelection(); + refreshTable(); + } + }); + + } + + // ------------------------------------------------------------------------ + // Simulated Table API + // ------------------------------------------------------------------------ + + /** + * Constructs a new TableColumn instance given a style value describing its + * alignment behavior. The column is added to the end of the columns + * maintained by the table. + * + * @param style + * the alignment style + * @return the new TableColumn + * + * @see SWT#LEFT + * @see SWT#RIGHT + * @see SWT#CENTER + * + * @since 3.1 + */ + public TableColumn newTableColumn(int style) { + TableColumn column = new TableColumn(fTable, style); + + /* + * In Linux the table does not receive a control resized event when + * a table column resize causes the horizontal scroll bar to become + * visible or invisible, so a resize listener must be added to every + * table column to properly update the number of fully visible rows. + */ + column.addControlListener(fResizeListener); + + return column; + } + + /** + * Method setHeaderVisible. + * @param b boolean + */ + public void setHeaderVisible(boolean b) { + fTable.setHeaderVisible(b); + } + + /** + * Method setLinesVisible. + * @param b boolean + */ + public void setLinesVisible(boolean b) { + fTable.setLinesVisible(b); + } + + /** + * Returns an array of TableItems that are currently selected + * in the receiver. The order of the items is unspecified. An empty array + * indicates that no items are selected. + *

    + * Note: This array only contains the visible selected items in the virtual + * table. To get information about the full selection range, use + * {@link #getSelectionIndices()}. + *

    + * + * @return an array representing the selection + * + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public TableItem[] getSelection() { + return fTable.getSelection(); + } + + /** + * Method addListener. + * @param eventType int + * @param listener Listener + */ + @Override + public void addListener(int eventType, Listener listener) { + fTable.addListener(eventType, listener); + } + + /** + * Method addKeyListener. + * @param listener KeyListener + */ + @Override + public void addKeyListener(KeyListener listener) { + fTable.addKeyListener(listener); + } + + /** + * Method addMouseListener. + * @param listener MouseListener + */ + @Override + public void addMouseListener(MouseListener listener) { + fTable.addMouseListener(listener); + } + + /** + * Method addSelectionListener. + * @param listener SelectionListener + */ + public void addSelectionListener(SelectionListener listener) { + fTable.addSelectionListener(listener); + } + + /** + * Method setMenu sets the menu + * @param menu Menu the menu + */ + @Override + public void setMenu(Menu menu) { + fTable.setMenu(menu); + } + + /** + * Gets the menu of this table + * @return a Menu + */ + @Override + public Menu getMenu() { + return fTable.getMenu(); + } + + /** + * Method clearAll empties a table. + */ + public void clearAll() { + setItemCount(0); + } + + /** + * Method setItemCount + * @param nbItems int the number of items in the table + * + */ + public void setItemCount(int nbItems) { + final int nb = Math.max(0, nbItems); + + if (nb != fTableItemCount) { + fTableItemCount = nb; + fTable.remove(fTableItemCount, fTable.getItemCount() - 1); + fSlider.setMaximum(nb); + resize(); + int tableHeight = Math.max(0, fTable.getClientArea().height - fTable.getHeaderHeight()); + fFullyVisibleRows = tableHeight / getItemHeight(); + if (fTableItemCount > 0) { + fSlider.setThumb(Math.max(1, Math.min(fTableRows, fFullyVisibleRows))); + } + } + } + + /** + * Method getItemCount. + * @return int the number of items in the table + */ + public int getItemCount() { + return fTableItemCount; + } + + /** + * Method getItemHeight. + * @return int the height of a table item in pixels. (may vary from one os to another) + */ + public int getItemHeight() { + /* + * Bug in Linux. The method getItemHeight doesn't always return the correct value. + */ + if (fLinuxItemHeight >= 0 && System.getProperty("os.name").contains("Linux")) { //$NON-NLS-1$ //$NON-NLS-2$ + if (fLinuxItemHeight != 0) { + return fLinuxItemHeight; + } + if (fTable.getItemCount() > 1) { + int itemHeight = fTable.getItem(1).getBounds().y - fTable.getItem(0).getBounds().y; + if (itemHeight > 0) { + fLinuxItemHeight = itemHeight; + return fLinuxItemHeight; + } + } + } else { + fLinuxItemHeight = -1; // Not Linux, don't perform os.name check anymore + } + return fTable.getItemHeight(); + } + + /** + * Method getHeaderHeight. + * @return int get the height of the header in pixels. + */ + public int getHeaderHeight() { + return fTable.getHeaderHeight(); + } + + /** + * Method getTopIndex. + * @return int get the first data item index, if you have a header it is offset. + */ + public int getTopIndex() { + return fTableTopEventRank + fFrozenRowCount; + } + + /** + * Method setTopIndex. + * @param index int suggested top index for the table. + */ + public void setTopIndex(int index) { + if (fTableItemCount > 0) { + int i = Math.min(index, fTableItemCount - 1); + i = Math.max(i, fFrozenRowCount); + + fTableTopEventRank = i - fFrozenRowCount; + if (fFullyVisibleRows < fTableItemCount) { + fSlider.setSelection(fTableTopEventRank); + } + + refreshTable(); + } + } + + /** + * Method indexOf. Return the index of a table item + * @param ti TableItem the table item to search for in the table + * @return int the index of the first match. (there should only be one match) + */ + public int indexOf(TableItem ti) { + int index = fTable.indexOf(ti); + if (index < fFrozenRowCount) { + return index; + } + return (index - fFrozenRowCount) + getTopIndex(); + } + + /** + * Method getColumns. + * @return TableColumn[] the table columns + */ + public TableColumn[] getColumns() { + return fTable.getColumns(); + } + + /** + * Method getItem. + * @param point Point the coordinates in the table + * @return TableItem the corresponding table item + */ + public TableItem getItem(Point point) { + return fTable.getItem(point); + } + + /** + * Method resize. + */ + private void resize() { + // Compute the numbers of rows that fit the new area + int tableHeight = Math.max(0, getSize().y - fTable.getHeaderHeight()); + int itemHeight = getItemHeight(); + fTableRows = Math.min((tableHeight + itemHeight - 1) / itemHeight, fTableItemCount); + + if (fTableTopEventRank + fFullyVisibleRows > fTableItemCount) { + // If we are at the end, get elements before to populate + fTableTopEventRank = Math.max(0, fTableItemCount - fFullyVisibleRows); + refreshTable(); + } else if (fTableRows > fTable.getItemCount() || fTableItemCount < fTable.getItemCount()) { + // Only refresh if new table items are needed or if table items need to be deleted + refreshTable(); + } + + } + + // ------------------------------------------------------------------------ + // Controls interactions + // ------------------------------------------------------------------------ + + /** + * Method setFocus. + * @return boolean is this visible? + */ + @Override + public boolean setFocus() { + boolean isVisible = isVisible(); + if (isVisible) { + fTable.setFocus(); + } + return isVisible; + } + + /** + * Method refresh. + */ + public void refresh() { + boolean done = refreshTable(); + if (!done) { + return; + } + if (fPendingSelection) { + fPendingSelection = false; + TableItem item = null; + if (fSelectedEventRank >= 0 && fSelectedEventRank < fFrozenRowCount) { + item = fTable.getItem(fSelectedEventRank); + } else if (fSelectedEventRank >= fTableTopEventRank + fFrozenRowCount && fSelectedEventRank - fTableTopEventRank < fTable.getItemCount()) { + item = fTable.getItem(fSelectedEventRank - fTableTopEventRank); + } + if (item != null) { + Event e = new Event(); + e.item = item; + fTable.notifyListeners(SWT.Selection, e); + } + } + } + + /** + * Method setColumnHeaders. + * + * @param columnData + * ColumnData[] the columndata array. + */ + @Deprecated + public void setColumnHeaders(ColumnData columnData[]) { + /* No-op */ + } + + /** + * Method removeAll. + * @return int 0 the number of elements in the table + */ + public int removeAll() { + setItemCount(0); + fSlider.setMaximum(0); + fTable.removeAll(); + fSelectedEventRank = -1; + fSelectedBeginRank = fSelectedEventRank; + return 0; + } + + /** + * Method refreshTable. + * @return true if all table items have been refreshed, false otherwise + */ + private boolean refreshTable() { + boolean done = true; + for (int i = 0; i < fTableRows; i++) { + if (i + fTableTopEventRank < fTableItemCount) { + TableItem tableItem; + if (i < fTable.getItemCount()) { + tableItem = fTable.getItem(i); + } else { + tableItem = new TableItem(fTable, SWT.NONE); + } + done &= setDataItem(i, tableItem); // false if table item not updated yet in this thread + } else { + if (fTable.getItemCount() > fTableItemCount - fTableTopEventRank) { + fTable.remove(fTableItemCount - fTableTopEventRank); + } + } + } + if (done) { + refreshSelection(); + } else { + fTable.deselectAll(); + } + return done; + } + + private void refreshSelection() { + int lastRowOffset = fTableTopEventRank + fTableRows - 1; + int startRank = Math.min(fSelectedBeginRank, fSelectedEventRank); + int endRank = Math.max(fSelectedBeginRank, fSelectedEventRank); + int start = Integer.MAX_VALUE; + int end = Integer.MIN_VALUE; + if (startRank < fFrozenRowCount) { + start = startRank; + } else if (startRank < fTableTopEventRank + fFrozenRowCount) { + start = fFrozenRowCount; + } else if (startRank <= lastRowOffset) { + start = startRank - fTableTopEventRank; + } + if (endRank < fFrozenRowCount) { + end = endRank; + } else if (endRank < fTableTopEventRank + fFrozenRowCount) { + end = fFrozenRowCount - 1; + } else if (endRank <= lastRowOffset) { + end = endRank - fTableTopEventRank; + } else { + end = fTableRows - 1; + } + if (start <= end) { + fTable.setSelection(start, end); + if (startRank == fSelectedEventRank) { + fTable.select(start); + } else { + fTable.select(end); + } + } else { + fTable.deselectAll(); + } + } + + /** + * Selects the item at the given zero-relative index in the receiver. + * The current selection is first cleared, then the new item is selected, + * and if necessary the receiver is scrolled to make the new selection visible. + * + * @param index the index of the item to select + * + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public void setSelection(int index) { + if (fTableItemCount > 0) { + int i = Math.min(index, fTableItemCount - 1); + i = Math.max(i, 0); + + fSelectedEventRank = i; + fSelectedBeginRank = fSelectedEventRank; + if ((i < fTableTopEventRank + fFrozenRowCount && i >= fFrozenRowCount) || + (i >= fTableTopEventRank + fFullyVisibleRows)) { + int lastPageTopEntryRank = Math.max(0, fTableItemCount - fFullyVisibleRows); + fTableTopEventRank = Math.max(0, Math.min(lastPageTopEntryRank, i - fFrozenRowCount - fFullyVisibleRows / 2)); + } + if (fFullyVisibleRows < fTableItemCount) { + fSlider.setSelection(fTableTopEventRank); + } + + refreshTable(); + } + } + + /** + * Returns the zero-relative index of the item which is currently + * selected in the receiver, or -1 if no item is selected. + * + * @return the index of the selected item + */ + public int getSelectionIndex() { + return fSelectedEventRank; + } + + /** + * Returns an index array representing the selection range. If there is a + * single item selected the array holds one index. If there is a selected + * range the first item in the array is the start index of the selection and + * the second item is the end index of the selection, which is the item most + * recently selected. The array is empty if no items are selected. + *

    + * @return the array of indices of the selected items + * @since 2.1 + */ + public int[] getSelectionIndices() { + if (fSelectedEventRank < 0 || fSelectedBeginRank < 0) { + return new int[] {}; + } else if (fSelectedEventRank == fSelectedBeginRank) { + return new int[] { fSelectedEventRank }; + } + return new int[] { fSelectedBeginRank, fSelectedEventRank }; + } + + /** + * Method setFrozenRowCount. + * @param count int the number of rows to freeze from the top row + */ + public void setFrozenRowCount(int count) { + fFrozenRowCount = count; + refreshTable(); + } + + /** + * Method createTableEditor. + * @return a TableEditor of the table + */ + public TableEditor createTableEditor() { + return new TableEditor(fTable); + } + + /** + * Method createTableEditorControl. + * @param control Class + * @return Control + */ + public Control createTableEditorControl(Class control) { + try { + return control.getConstructor(Composite.class, int.class).newInstance(new Object[] {fTable, SWT.NONE}); + } catch (Exception e) { + Activator.getDefault().logError("Error creating table editor control", e); //$NON-NLS-1$ + } + return null; + } + + /** + * @return the tooltipProvider + */ + public TooltipProvider getTooltipProvider() { + return tooltipProvider; + } + + /** + * @param tooltipProvider the tooltipProvider to set + */ + public void setTooltipProvider(TooltipProvider tooltipProvider) { + this.tooltipProvider = tooltipProvider; + } + + /** + * @return the doubleClickListener + */ + public IDoubleClickListener getDoubleClickListener() { + return doubleClickListener; + } + + /** + * @param doubleClickListener the doubleClickListener to set + */ + public void setDoubleClickListener(IDoubleClickListener doubleClickListener) { + this.doubleClickListener = doubleClickListener; + } + +} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/virtualtable/TooltipProvider.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/virtualtable/TooltipProvider.java new file mode 100644 index 0000000000..4e66b1bfff --- /dev/null +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/virtualtable/TooltipProvider.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Kalray, Ericsson. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xavier Raynaud - Initial API and implementation + ******************************************************************************/ +package org.eclipse.tracecompass.tmf.ui.widgets.virtualtable; + +/** + * An interface to get tooltips. + * @author Xavier Raynaud + * @version 1.0 + */ +public interface TooltipProvider { + + /** + * get a Tooltip for a given column in a table row. (a cell if you will) + * @param column the column + * @param data the object being selected. (quite often a "TableItem") + * @return the string of text to display in the tooltip. + */ + String getTooltip(int column, Object data); + +} -- cgit v1.2.3